summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Wilgus <me.theuser@yahoo.com>2018-12-09 12:09:40 -0600
committerWilliam Wilgus <me.theuser@yahoo.com>2018-12-09 22:54:55 -0600
commit62a5ed49cc187120793ea50e0eec4e18c8bc0441 (patch)
treea6714de084a80ea4a61f3da6042a743801b19d12
parent74701a16a547ab4a68fc9c5a32d939e7a9c91531 (diff)
downloadrockbox-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.c4
-rw-r--r--apps/lang/english.lang66
-rw-r--r--apps/menus/main_menu.c32
-rw-r--r--apps/misc.c42
-rw-r--r--apps/misc.h10
-rw-r--r--apps/recorder/recording.c2
-rw-r--r--apps/screens.c2
-rw-r--r--apps/talk.c2
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 @@
110const unsigned char * const byte_units[] = 110const 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
118const unsigned char * const * const kbyte_units = &byte_units[1]; 118const 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.*/
125char *output_dyn_value(char *buf, int buf_size, int value, 125char *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
29extern const unsigned char * const byte_units[]; 29extern const unsigned char * const byte_units[];
30extern const unsigned char * const * const kbyte_units; 30extern 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.*/
37char *output_dyn_value(char *buf, int buf_size, int value, 37char *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]