diff options
author | William Wilgus <me.theuser@yahoo.com> | 2018-12-09 12:09:40 -0600 |
---|---|---|
committer | William Wilgus <me.theuser@yahoo.com> | 2018-12-09 22:54:55 -0600 |
commit | 62a5ed49cc187120793ea50e0eec4e18c8bc0441 (patch) | |
tree | a6714de084a80ea4a61f3da6042a743801b19d12 | |
parent | 74701a16a547ab4a68fc9c5a32d939e7a9c91531 (diff) | |
download | rockbox-62a5ed49cc187120793ea50e0eec4e18c8bc0441.tar.gz rockbox-62a5ed49cc187120793ea50e0eec4e18c8bc0441.zip |
Fix possible truncation misc.c->output_dyn_value + use Kibytes
output_dyn_value now requires the count for number of units
Binary scale now shows Kibibytes instead of kilobytes (g#1742)
Fixes output for negative values as well
Change-Id: I8aa896860e97d2453fa35069e2dfe1caac60109f
-rw-r--r-- | apps/debug_menu.c | 4 | ||||
-rw-r--r-- | apps/lang/english.lang | 66 | ||||
-rw-r--r-- | apps/menus/main_menu.c | 32 | ||||
-rw-r--r-- | apps/misc.c | 42 | ||||
-rw-r--r-- | apps/misc.h | 10 | ||||
-rw-r--r-- | apps/recorder/recording.c | 2 | ||||
-rw-r--r-- | apps/screens.c | 2 | ||||
-rw-r--r-- | apps/talk.c | 2 |
8 files changed, 106 insertions, 54 deletions
diff --git a/apps/debug_menu.c b/apps/debug_menu.c index 0dec3cd738..362d3fbf3e 100644 --- a/apps/debug_menu.c +++ b/apps/debug_menu.c | |||
@@ -1326,11 +1326,11 @@ static int disk_callback(int btn, struct gui_synclist *lists) | |||
1326 | simplelist_addline( | 1326 | simplelist_addline( |
1327 | "Blocks: 0x%08lx", card->numblocks); | 1327 | "Blocks: 0x%08lx", card->numblocks); |
1328 | output_dyn_value(pbuf, sizeof pbuf, card->speed / 1000, | 1328 | output_dyn_value(pbuf, sizeof pbuf, card->speed / 1000, |
1329 | kbit_units, false); | 1329 | kbit_units, 3, false); |
1330 | simplelist_addline( | 1330 | simplelist_addline( |
1331 | "Speed: %s", pbuf); | 1331 | "Speed: %s", pbuf); |
1332 | output_dyn_value(pbuf, sizeof pbuf, card->taac, | 1332 | output_dyn_value(pbuf, sizeof pbuf, card->taac, |
1333 | nsec_units, false); | 1333 | nsec_units, 3, false); |
1334 | simplelist_addline( | 1334 | simplelist_addline( |
1335 | "Taac: %s", pbuf); | 1335 | "Taac: %s", pbuf); |
1336 | simplelist_addline( | 1336 | simplelist_addline( |
diff --git a/apps/lang/english.lang b/apps/lang/english.lang index d4e0697667..f4f1b12032 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang | |||
@@ -8441,44 +8441,44 @@ | |||
8441 | </phrase> | 8441 | </phrase> |
8442 | <phrase> | 8442 | <phrase> |
8443 | id: LANG_KILOBYTE | 8443 | id: LANG_KILOBYTE |
8444 | desc: a unit postfix, also voiced | 8444 | desc: deprecated |
8445 | user: core | 8445 | user: core |
8446 | <source> | 8446 | <source> |
8447 | *: "KB" | 8447 | *: "" |
8448 | </source> | 8448 | </source> |
8449 | <dest> | 8449 | <dest> |
8450 | *: "KB" | 8450 | *: "" |
8451 | </dest> | 8451 | </dest> |
8452 | <voice> | 8452 | <voice> |
8453 | *: "kilobyte" | 8453 | *: "" |
8454 | </voice> | 8454 | </voice> |
8455 | </phrase> | 8455 | </phrase> |
8456 | <phrase> | 8456 | <phrase> |
8457 | id: LANG_MEGABYTE | 8457 | id: LANG_MEGABYTE |
8458 | desc: a unit postfix, also voiced | 8458 | desc: deprecated |
8459 | user: core | 8459 | user: core |
8460 | <source> | 8460 | <source> |
8461 | *: "MB" | 8461 | *: "" |
8462 | </source> | 8462 | </source> |
8463 | <dest> | 8463 | <dest> |
8464 | *: "MB" | 8464 | *: "" |
8465 | </dest> | 8465 | </dest> |
8466 | <voice> | 8466 | <voice> |
8467 | *: "megabyte" | 8467 | *: "" |
8468 | </voice> | 8468 | </voice> |
8469 | </phrase> | 8469 | </phrase> |
8470 | <phrase> | 8470 | <phrase> |
8471 | id: LANG_GIGABYTE | 8471 | id: LANG_GIGABYTE |
8472 | desc: a unit postfix, also voiced | 8472 | desc: deprecated |
8473 | user: core | 8473 | user: core |
8474 | <source> | 8474 | <source> |
8475 | *: "GB" | 8475 | *: "" |
8476 | </source> | 8476 | </source> |
8477 | <dest> | 8477 | <dest> |
8478 | *: "GB" | 8478 | *: "" |
8479 | </dest> | 8479 | </dest> |
8480 | <voice> | 8480 | <voice> |
8481 | *: "gigabyte" | 8481 | *: "" |
8482 | </voice> | 8482 | </voice> |
8483 | </phrase> | 8483 | </phrase> |
8484 | <phrase> | 8484 | <phrase> |
@@ -13647,3 +13647,45 @@ | |||
13647 | *: "Disable Touch" | 13647 | *: "Disable Touch" |
13648 | </voice> | 13648 | </voice> |
13649 | </phrase> | 13649 | </phrase> |
13650 | <phrase> | ||
13651 | id: LANG_KIBIBYTE | ||
13652 | desc: a unit postfix, also voiced | ||
13653 | user: core | ||
13654 | <source> | ||
13655 | *: "KiB" | ||
13656 | </source> | ||
13657 | <dest> | ||
13658 | *: "KiB" | ||
13659 | </dest> | ||
13660 | <voice> | ||
13661 | *: "kibibyte" | ||
13662 | </voice> | ||
13663 | </phrase> | ||
13664 | <phrase> | ||
13665 | id: LANG_MEBIBYTE | ||
13666 | desc: a unit postfix, also voiced | ||
13667 | user: core | ||
13668 | <source> | ||
13669 | *: "MiB" | ||
13670 | </source> | ||
13671 | <dest> | ||
13672 | *: "MiB" | ||
13673 | </dest> | ||
13674 | <voice> | ||
13675 | *: "mebibyte" | ||
13676 | </voice> | ||
13677 | </phrase> | ||
13678 | <phrase> | ||
13679 | id: LANG_GIBIBYTE | ||
13680 | desc: a unit postfix, also voiced | ||
13681 | user: core | ||
13682 | <source> | ||
13683 | *: "GiB" | ||
13684 | </source> | ||
13685 | <dest> | ||
13686 | *: "GiB" | ||
13687 | </dest> | ||
13688 | <voice> | ||
13689 | *: "gibibyte" | ||
13690 | </voice> | ||
13691 | </phrase> | ||
diff --git a/apps/menus/main_menu.c b/apps/menus/main_menu.c index 139667cef4..a5196020a0 100644 --- a/apps/menus/main_menu.c +++ b/apps/menus/main_menu.c | |||
@@ -181,8 +181,8 @@ static const char* info_getname(int selected_item, void *data, | |||
181 | 181 | ||
182 | case INFO_BUFFER: /* buffer */ | 182 | case INFO_BUFFER: /* buffer */ |
183 | { | 183 | { |
184 | long kib = audio_buffer_size() / 1024; /* to KiB */ | 184 | long kib = audio_buffer_size() >> 10; /* to KiB */ |
185 | output_dyn_value(s1, sizeof(s1), kib, kbyte_units, true); | 185 | output_dyn_value(s1, sizeof(s1), kib, kibyte_units, 3, true); |
186 | snprintf(buffer, buffer_len, "%s %s", str(LANG_BUFFER_STAT), s1); | 186 | snprintf(buffer, buffer_len, "%s %s", str(LANG_BUFFER_STAT), s1); |
187 | } | 187 | } |
188 | break; | 188 | break; |
@@ -217,12 +217,12 @@ static const char* info_getname(int selected_item, void *data, | |||
217 | break; | 217 | break; |
218 | case INFO_DISK1: /* disk usage 1 */ | 218 | case INFO_DISK1: /* disk usage 1 */ |
219 | #ifdef HAVE_MULTIVOLUME | 219 | #ifdef HAVE_MULTIVOLUME |
220 | output_dyn_value(s1, sizeof s1, info->free, kbyte_units, true); | 220 | output_dyn_value(s1, sizeof s1, info->free, kibyte_units, 3, true); |
221 | output_dyn_value(s2, sizeof s2, info->size, kbyte_units, true); | 221 | output_dyn_value(s2, sizeof s2, info->size, kibyte_units, 3, true); |
222 | snprintf(buffer, buffer_len, "%s %s/%s", str(LANG_DISK_NAME_INTERNAL), | 222 | snprintf(buffer, buffer_len, "%s %s/%s", str(LANG_DISK_NAME_INTERNAL), |
223 | s1, s2); | 223 | s1, s2); |
224 | #else | 224 | #else |
225 | output_dyn_value(s1, sizeof s1, info->free, kbyte_units, true); | 225 | output_dyn_value(s1, sizeof s1, info->free, kibyte_units, 3, true); |
226 | snprintf(buffer, buffer_len, SIZE_FMT, str(LANG_DISK_FREE_INFO), s1); | 226 | snprintf(buffer, buffer_len, SIZE_FMT, str(LANG_DISK_FREE_INFO), s1); |
227 | #endif | 227 | #endif |
228 | break; | 228 | break; |
@@ -230,8 +230,8 @@ static const char* info_getname(int selected_item, void *data, | |||
230 | #ifdef HAVE_MULTIVOLUME | 230 | #ifdef HAVE_MULTIVOLUME |
231 | if (info->size2) | 231 | if (info->size2) |
232 | { | 232 | { |
233 | output_dyn_value(s1, sizeof s1, info->free2, kbyte_units, true); | 233 | output_dyn_value(s1, sizeof s1, info->free2, kibyte_units, 3, true); |
234 | output_dyn_value(s2, sizeof s2, info->size2, kbyte_units, true); | 234 | output_dyn_value(s2, sizeof s2, info->size2, kibyte_units, 3, true); |
235 | snprintf(buffer, buffer_len, "%s %s/%s", str(LANG_DISK_NAME_MMC), | 235 | snprintf(buffer, buffer_len, "%s %s/%s", str(LANG_DISK_NAME_MMC), |
236 | s1, s2); | 236 | s1, s2); |
237 | } | 237 | } |
@@ -241,7 +241,7 @@ static const char* info_getname(int selected_item, void *data, | |||
241 | str(LANG_NOT_PRESENT)); | 241 | str(LANG_NOT_PRESENT)); |
242 | } | 242 | } |
243 | #else | 243 | #else |
244 | output_dyn_value(s1, sizeof s1, info->size, kbyte_units, true); | 244 | output_dyn_value(s1, sizeof s1, info->size, kibyte_units, 3, true); |
245 | snprintf(buffer, buffer_len, SIZE_FMT, str(LANG_DISK_SIZE_INFO), s1); | 245 | snprintf(buffer, buffer_len, SIZE_FMT, str(LANG_DISK_SIZE_INFO), s1); |
246 | #endif | 246 | #endif |
247 | break; | 247 | break; |
@@ -263,8 +263,8 @@ static int info_speak_item(int selected_item, void * data) | |||
263 | case INFO_BUFFER: /* buffer */ | 263 | case INFO_BUFFER: /* buffer */ |
264 | { | 264 | { |
265 | talk_id(LANG_BUFFER_STAT, false); | 265 | talk_id(LANG_BUFFER_STAT, false); |
266 | long kib = audio_buffer_size() / 1024; /* to KiB */ | 266 | long kib = audio_buffer_size() >> 10; /* to KiB */ |
267 | output_dyn_value(NULL, 0, kib, kbyte_units, true); | 267 | output_dyn_value(NULL, 0, kib, kibyte_units, 3, true); |
268 | break; | 268 | break; |
269 | } | 269 | } |
270 | case INFO_BATTERY: /* battery */ | 270 | case INFO_BATTERY: /* battery */ |
@@ -303,12 +303,12 @@ static int info_speak_item(int selected_item, void * data) | |||
303 | case INFO_DISK1: /* disk 1 */ | 303 | case INFO_DISK1: /* disk 1 */ |
304 | #ifdef HAVE_MULTIVOLUME | 304 | #ifdef HAVE_MULTIVOLUME |
305 | talk_ids(false, LANG_DISK_NAME_INTERNAL, LANG_DISK_FREE_INFO); | 305 | talk_ids(false, LANG_DISK_NAME_INTERNAL, LANG_DISK_FREE_INFO); |
306 | output_dyn_value(NULL, 0, info->free, kbyte_units, true); | 306 | output_dyn_value(NULL, 0, info->free, kibyte_units, 3, true); |
307 | talk_id(LANG_DISK_SIZE_INFO, true); | 307 | talk_id(LANG_DISK_SIZE_INFO, true); |
308 | output_dyn_value(NULL, 0, info->size, kbyte_units, true); | 308 | output_dyn_value(NULL, 0, info->size, kibyte_units, 3, true); |
309 | #else | 309 | #else |
310 | talk_id(LANG_DISK_FREE_INFO, false); | 310 | talk_id(LANG_DISK_FREE_INFO, false); |
311 | output_dyn_value(NULL, 0, info->free, kbyte_units, true); | 311 | output_dyn_value(NULL, 0, info->free, kibyte_units, 3, true); |
312 | #endif | 312 | #endif |
313 | break; | 313 | break; |
314 | case INFO_DISK2: /* disk 2 */ | 314 | case INFO_DISK2: /* disk 2 */ |
@@ -317,14 +317,14 @@ static int info_speak_item(int selected_item, void * data) | |||
317 | if (info->size2) | 317 | if (info->size2) |
318 | { | 318 | { |
319 | talk_id(LANG_DISK_FREE_INFO, true); | 319 | talk_id(LANG_DISK_FREE_INFO, true); |
320 | output_dyn_value(NULL, 0, info->free2, kbyte_units, true); | 320 | output_dyn_value(NULL, 0, info->free2, kibyte_units, 3, true); |
321 | talk_id(LANG_DISK_SIZE_INFO, true); | 321 | talk_id(LANG_DISK_SIZE_INFO, true); |
322 | output_dyn_value(NULL, 0, info->size2, kbyte_units, true); | 322 | output_dyn_value(NULL, 0, info->size2, kibyte_units, 3, true); |
323 | } | 323 | } |
324 | else talk_id(LANG_NOT_PRESENT, true); | 324 | else talk_id(LANG_NOT_PRESENT, true); |
325 | #else | 325 | #else |
326 | talk_id(LANG_DISK_SIZE_INFO, false); | 326 | talk_id(LANG_DISK_SIZE_INFO, false); |
327 | output_dyn_value(NULL, 0, info->size, kbyte_units, true); | 327 | output_dyn_value(NULL, 0, info->size, kibyte_units, 3, true); |
328 | #endif | 328 | #endif |
329 | break; | 329 | break; |
330 | 330 | ||
diff --git a/apps/misc.c b/apps/misc.c index 477efc6313..b3ae8e9af5 100644 --- a/apps/misc.c +++ b/apps/misc.c | |||
@@ -110,41 +110,47 @@ | |||
110 | const unsigned char * const byte_units[] = | 110 | const unsigned char * const byte_units[] = |
111 | { | 111 | { |
112 | ID2P(LANG_BYTE), | 112 | ID2P(LANG_BYTE), |
113 | ID2P(LANG_KILOBYTE), | 113 | ID2P(LANG_KIBIBYTE), |
114 | ID2P(LANG_MEGABYTE), | 114 | ID2P(LANG_MEBIBYTE), |
115 | ID2P(LANG_GIGABYTE) | 115 | ID2P(LANG_GIBIBYTE) |
116 | }; | 116 | }; |
117 | 117 | ||
118 | const unsigned char * const * const kbyte_units = &byte_units[1]; | 118 | const unsigned char * const * const kibyte_units = &byte_units[1]; |
119 | 119 | ||
120 | /* Format a large-range value for output, using the appropriate unit so that | 120 | /* Format a large-range value for output, using the appropriate unit so that |
121 | * the displayed value is in the range 1 <= display < 1000 (1024 for "binary" | 121 | * the displayed value is in the range 1 <= display < 1000 (1024 for "binary" |
122 | * units) if possible, and 3 significant digits are shown. If a buffer is | 122 | * units) if possible, and 3 significant digits are shown. If a buffer is |
123 | * given, the result is snprintf()'d into that buffer, otherwise the result is | 123 | * given, the result is snprintf()'d into that buffer, otherwise the result is |
124 | * voiced.*/ | 124 | * voiced.*/ |
125 | char *output_dyn_value(char *buf, int buf_size, int value, | 125 | char *output_dyn_value(char *buf, |
126 | const unsigned char * const *units, bool bin_scale) | 126 | int buf_size, |
127 | int value, | ||
128 | const unsigned char * const *units, | ||
129 | unsigned int unit_count, | ||
130 | bool binary_scale) | ||
127 | { | 131 | { |
128 | int scale = bin_scale ? 1024 : 1000; | 132 | unsigned int scale = binary_scale ? 1024 : 1000; |
129 | int fraction = 0; | 133 | unsigned int fraction = 0; |
130 | int unit_no = 0; | 134 | unsigned int unit_no = 0; |
135 | unsigned int value_abs = (value < 0) ? -value : value; | ||
131 | char tbuf[5]; | 136 | char tbuf[5]; |
132 | 137 | ||
133 | while (value >= scale) | 138 | while (value_abs >= scale && unit_no < (unit_count - 1)) |
134 | { | 139 | { |
135 | fraction = value % scale; | 140 | fraction = value_abs % scale; |
136 | value /= scale; | 141 | value_abs /= scale; |
137 | unit_no++; | 142 | unit_no++; |
138 | } | 143 | } |
139 | if (bin_scale) | 144 | |
140 | fraction = fraction * 1000 / 1024; | 145 | value = (value < 0) ? -value_abs : value_abs; /* preserve sign */ |
146 | fraction = (fraction * 1000 / scale) / 10; | ||
141 | 147 | ||
142 | if (value >= 100 || !unit_no) | 148 | if (value_abs >= 100 || fraction >= 100 || !unit_no) |
143 | tbuf[0] = '\0'; | 149 | tbuf[0] = '\0'; |
144 | else if (value >= 10) | 150 | else if (value_abs >= 10) |
145 | snprintf(tbuf, sizeof(tbuf), "%01d", fraction / 100); | 151 | snprintf(tbuf, sizeof(tbuf), "%01u", fraction / 10); |
146 | else | 152 | else |
147 | snprintf(tbuf, sizeof(tbuf), "%02d", fraction / 10); | 153 | snprintf(tbuf, sizeof(tbuf), "%02u", fraction); |
148 | 154 | ||
149 | if (buf) | 155 | if (buf) |
150 | { | 156 | { |
diff --git a/apps/misc.h b/apps/misc.h index b13c0b15c6..6821c6debf 100644 --- a/apps/misc.h +++ b/apps/misc.h | |||
@@ -27,15 +27,19 @@ | |||
27 | #include "screen_access.h" | 27 | #include "screen_access.h" |
28 | 28 | ||
29 | extern const unsigned char * const byte_units[]; | 29 | extern const unsigned char * const byte_units[]; |
30 | extern const unsigned char * const * const kbyte_units; | 30 | extern const unsigned char * const * const kibyte_units; |
31 | 31 | ||
32 | /* Format a large-range value for output, using the appropriate unit so that | 32 | /* Format a large-range value for output, using the appropriate unit so that |
33 | * the displayed value is in the range 1 <= display < 1000 (1024 for "binary" | 33 | * the displayed value is in the range 1 <= display < 1000 (1024 for "binary" |
34 | * units) if possible, and 3 significant digits are shown. If a buffer is | 34 | * units) if possible, and 3 significant digits are shown. If a buffer is |
35 | * given, the result is snprintf()'d into that buffer, otherwise the result is | 35 | * given, the result is snprintf()'d into that buffer, otherwise the result is |
36 | * voiced.*/ | 36 | * voiced.*/ |
37 | char *output_dyn_value(char *buf, int buf_size, int value, | 37 | char *output_dyn_value(char *buf, |
38 | const unsigned char * const *units, bool bin_scale); | 38 | int buf_size, |
39 | int value, | ||
40 | const unsigned char * const *units, | ||
41 | unsigned int unit_count, | ||
42 | bool binary_scale); | ||
39 | 43 | ||
40 | /* Format time into buf. | 44 | /* Format time into buf. |
41 | * | 45 | * |
diff --git a/apps/recorder/recording.c b/apps/recorder/recording.c index b8f10dc83e..d47773071f 100644 --- a/apps/recorder/recording.c +++ b/apps/recorder/recording.c | |||
@@ -1756,7 +1756,7 @@ bool recording_screen(bool no_source) | |||
1756 | { | 1756 | { |
1757 | output_dyn_value(buf2, sizeof buf2, | 1757 | output_dyn_value(buf2, sizeof buf2, |
1758 | num_recorded_bytes, | 1758 | num_recorded_bytes, |
1759 | byte_units, true); | 1759 | byte_units, 4, true); |
1760 | snprintf(buf, sizeof(buf), "%s %s", | 1760 | snprintf(buf, sizeof(buf), "%s %s", |
1761 | str(LANG_RECORDING_SIZE), buf2); | 1761 | str(LANG_RECORDING_SIZE), buf2); |
1762 | } | 1762 | } |
diff --git a/apps/screens.c b/apps/screens.c index e203b446cf..5fa92f5fbd 100644 --- a/apps/screens.c +++ b/apps/screens.c | |||
@@ -747,7 +747,7 @@ static const char* id3_get_info(int selected_item, void* data, | |||
747 | val=id3->composer; | 747 | val=id3->composer; |
748 | break; | 748 | break; |
749 | case LANG_FILESIZE: /* not LANG_ID3_FILESIZE because the string is shared */ | 749 | case LANG_FILESIZE: /* not LANG_ID3_FILESIZE because the string is shared */ |
750 | output_dyn_value(buffer, buffer_len, id3->filesize, byte_units, true); | 750 | output_dyn_value(buffer, buffer_len, id3->filesize, byte_units, 4, true); |
751 | val=buffer; | 751 | val=buffer; |
752 | break; | 752 | break; |
753 | } | 753 | } |
diff --git a/apps/talk.c b/apps/talk.c index 910f355ff9..aae33283ae 100644 --- a/apps/talk.c +++ b/apps/talk.c | |||
@@ -1330,7 +1330,7 @@ int talk_value_decimal(long n, int unit, int decimals, bool enqueue) | |||
1330 | [UNIT_HERTZ] | 1330 | [UNIT_HERTZ] |
1331 | = VOICE_HERTZ, | 1331 | = VOICE_HERTZ, |
1332 | [UNIT_MB] | 1332 | [UNIT_MB] |
1333 | = LANG_MEGABYTE, | 1333 | = LANG_MEBIBYTE, |
1334 | [UNIT_KBIT] | 1334 | [UNIT_KBIT] |
1335 | = VOICE_KBIT_PER_SEC, | 1335 | = VOICE_KBIT_PER_SEC, |
1336 | [UNIT_PM_TICK] | 1336 | [UNIT_PM_TICK] |