summaryrefslogtreecommitdiffstats
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.tar.bz2
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)
simplelist_addline(
"Blocks: 0x%08lx", card->numblocks);
output_dyn_value(pbuf, sizeof pbuf, card->speed / 1000,
- kbit_units, false);
+ kbit_units, 3, false);
simplelist_addline(
"Speed: %s", pbuf);
output_dyn_value(pbuf, sizeof pbuf, card->taac,
- nsec_units, false);
+ nsec_units, 3, false);
simplelist_addline(
"Taac: %s", pbuf);
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 @@
</phrase>
<phrase>
id: LANG_KILOBYTE
- desc: a unit postfix, also voiced
+ desc: deprecated
user: core
<source>
- *: "KB"
+ *: ""
</source>
<dest>
- *: "KB"
+ *: ""
</dest>
<voice>
- *: "kilobyte"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_MEGABYTE
- desc: a unit postfix, also voiced
+ desc: deprecated
user: core
<source>
- *: "MB"
+ *: ""
</source>
<dest>
- *: "MB"
+ *: ""
</dest>
<voice>
- *: "megabyte"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_GIGABYTE
- desc: a unit postfix, also voiced
+ desc: deprecated
user: core
<source>
- *: "GB"
+ *: ""
</source>
<dest>
- *: "GB"
+ *: ""
</dest>
<voice>
- *: "gigabyte"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -13647,3 +13647,45 @@
*: "Disable Touch"
</voice>
</phrase>
+<phrase>
+ id: LANG_KIBIBYTE
+ desc: a unit postfix, also voiced
+ user: core
+ <source>
+ *: "KiB"
+ </source>
+ <dest>
+ *: "KiB"
+ </dest>
+ <voice>
+ *: "kibibyte"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_MEBIBYTE
+ desc: a unit postfix, also voiced
+ user: core
+ <source>
+ *: "MiB"
+ </source>
+ <dest>
+ *: "MiB"
+ </dest>
+ <voice>
+ *: "mebibyte"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_GIBIBYTE
+ desc: a unit postfix, also voiced
+ user: core
+ <source>
+ *: "GiB"
+ </source>
+ <dest>
+ *: "GiB"
+ </dest>
+ <voice>
+ *: "gibibyte"
+ </voice>
+</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,
case INFO_BUFFER: /* buffer */
{
- long kib = audio_buffer_size() / 1024; /* to KiB */
- output_dyn_value(s1, sizeof(s1), kib, kbyte_units, true);
+ long kib = audio_buffer_size() >> 10; /* to KiB */
+ output_dyn_value(s1, sizeof(s1), kib, kibyte_units, 3, true);
snprintf(buffer, buffer_len, "%s %s", str(LANG_BUFFER_STAT), s1);
}
break;
@@ -217,12 +217,12 @@ static const char* info_getname(int selected_item, void *data,
break;
case INFO_DISK1: /* disk usage 1 */
#ifdef HAVE_MULTIVOLUME
- output_dyn_value(s1, sizeof s1, info->free, kbyte_units, true);
- output_dyn_value(s2, sizeof s2, info->size, kbyte_units, true);
+ output_dyn_value(s1, sizeof s1, info->free, kibyte_units, 3, true);
+ output_dyn_value(s2, sizeof s2, info->size, kibyte_units, 3, true);
snprintf(buffer, buffer_len, "%s %s/%s", str(LANG_DISK_NAME_INTERNAL),
s1, s2);
#else
- output_dyn_value(s1, sizeof s1, info->free, kbyte_units, true);
+ output_dyn_value(s1, sizeof s1, info->free, kibyte_units, 3, true);
snprintf(buffer, buffer_len, SIZE_FMT, str(LANG_DISK_FREE_INFO), s1);
#endif
break;
@@ -230,8 +230,8 @@ static const char* info_getname(int selected_item, void *data,
#ifdef HAVE_MULTIVOLUME
if (info->size2)
{
- output_dyn_value(s1, sizeof s1, info->free2, kbyte_units, true);
- output_dyn_value(s2, sizeof s2, info->size2, kbyte_units, true);
+ output_dyn_value(s1, sizeof s1, info->free2, kibyte_units, 3, true);
+ output_dyn_value(s2, sizeof s2, info->size2, kibyte_units, 3, true);
snprintf(buffer, buffer_len, "%s %s/%s", str(LANG_DISK_NAME_MMC),
s1, s2);
}
@@ -241,7 +241,7 @@ static const char* info_getname(int selected_item, void *data,
str(LANG_NOT_PRESENT));
}
#else
- output_dyn_value(s1, sizeof s1, info->size, kbyte_units, true);
+ output_dyn_value(s1, sizeof s1, info->size, kibyte_units, 3, true);
snprintf(buffer, buffer_len, SIZE_FMT, str(LANG_DISK_SIZE_INFO), s1);
#endif
break;
@@ -263,8 +263,8 @@ static int info_speak_item(int selected_item, void * data)
case INFO_BUFFER: /* buffer */
{
talk_id(LANG_BUFFER_STAT, false);
- long kib = audio_buffer_size() / 1024; /* to KiB */
- output_dyn_value(NULL, 0, kib, kbyte_units, true);
+ long kib = audio_buffer_size() >> 10; /* to KiB */
+ output_dyn_value(NULL, 0, kib, kibyte_units, 3, true);
break;
}
case INFO_BATTERY: /* battery */
@@ -303,12 +303,12 @@ static int info_speak_item(int selected_item, void * data)
case INFO_DISK1: /* disk 1 */
#ifdef HAVE_MULTIVOLUME
talk_ids(false, LANG_DISK_NAME_INTERNAL, LANG_DISK_FREE_INFO);
- output_dyn_value(NULL, 0, info->free, kbyte_units, true);
+ output_dyn_value(NULL, 0, info->free, kibyte_units, 3, true);
talk_id(LANG_DISK_SIZE_INFO, true);
- output_dyn_value(NULL, 0, info->size, kbyte_units, true);
+ output_dyn_value(NULL, 0, info->size, kibyte_units, 3, true);
#else
talk_id(LANG_DISK_FREE_INFO, false);
- output_dyn_value(NULL, 0, info->free, kbyte_units, true);
+ output_dyn_value(NULL, 0, info->free, kibyte_units, 3, true);
#endif
break;
case INFO_DISK2: /* disk 2 */
@@ -317,14 +317,14 @@ static int info_speak_item(int selected_item, void * data)
if (info->size2)
{
talk_id(LANG_DISK_FREE_INFO, true);
- output_dyn_value(NULL, 0, info->free2, kbyte_units, true);
+ output_dyn_value(NULL, 0, info->free2, kibyte_units, 3, true);
talk_id(LANG_DISK_SIZE_INFO, true);
- output_dyn_value(NULL, 0, info->size2, kbyte_units, true);
+ output_dyn_value(NULL, 0, info->size2, kibyte_units, 3, true);
}
else talk_id(LANG_NOT_PRESENT, true);
#else
talk_id(LANG_DISK_SIZE_INFO, false);
- output_dyn_value(NULL, 0, info->size, kbyte_units, true);
+ output_dyn_value(NULL, 0, info->size, kibyte_units, 3, true);
#endif
break;
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 @@
const unsigned char * const byte_units[] =
{
ID2P(LANG_BYTE),
- ID2P(LANG_KILOBYTE),
- ID2P(LANG_MEGABYTE),
- ID2P(LANG_GIGABYTE)
+ ID2P(LANG_KIBIBYTE),
+ ID2P(LANG_MEBIBYTE),
+ ID2P(LANG_GIBIBYTE)
};
-const unsigned char * const * const kbyte_units = &byte_units[1];
+const unsigned char * const * const kibyte_units = &byte_units[1];
/* Format a large-range value for output, using the appropriate unit so that
* the displayed value is in the range 1 <= display < 1000 (1024 for "binary"
* units) if possible, and 3 significant digits are shown. If a buffer is
* given, the result is snprintf()'d into that buffer, otherwise the result is
* voiced.*/
-char *output_dyn_value(char *buf, int buf_size, int value,
- const unsigned char * const *units, bool bin_scale)
+char *output_dyn_value(char *buf,
+ int buf_size,
+ int value,
+ const unsigned char * const *units,
+ unsigned int unit_count,
+ bool binary_scale)
{
- int scale = bin_scale ? 1024 : 1000;
- int fraction = 0;
- int unit_no = 0;
+ unsigned int scale = binary_scale ? 1024 : 1000;
+ unsigned int fraction = 0;
+ unsigned int unit_no = 0;
+ unsigned int value_abs = (value < 0) ? -value : value;
char tbuf[5];
- while (value >= scale)
+ while (value_abs >= scale && unit_no < (unit_count - 1))
{
- fraction = value % scale;
- value /= scale;
+ fraction = value_abs % scale;
+ value_abs /= scale;
unit_no++;
}
- if (bin_scale)
- fraction = fraction * 1000 / 1024;
+
+ value = (value < 0) ? -value_abs : value_abs; /* preserve sign */
+ fraction = (fraction * 1000 / scale) / 10;
- if (value >= 100 || !unit_no)
+ if (value_abs >= 100 || fraction >= 100 || !unit_no)
tbuf[0] = '\0';
- else if (value >= 10)
- snprintf(tbuf, sizeof(tbuf), "%01d", fraction / 100);
+ else if (value_abs >= 10)
+ snprintf(tbuf, sizeof(tbuf), "%01u", fraction / 10);
else
- snprintf(tbuf, sizeof(tbuf), "%02d", fraction / 10);
+ snprintf(tbuf, sizeof(tbuf), "%02u", fraction);
if (buf)
{
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 @@
#include "screen_access.h"
extern const unsigned char * const byte_units[];
-extern const unsigned char * const * const kbyte_units;
+extern const unsigned char * const * const kibyte_units;
/* Format a large-range value for output, using the appropriate unit so that
* the displayed value is in the range 1 <= display < 1000 (1024 for "binary"
* units) if possible, and 3 significant digits are shown. If a buffer is
* given, the result is snprintf()'d into that buffer, otherwise the result is
* voiced.*/
-char *output_dyn_value(char *buf, int buf_size, int value,
- const unsigned char * const *units, bool bin_scale);
+char *output_dyn_value(char *buf,
+ int buf_size,
+ int value,
+ const unsigned char * const *units,
+ unsigned int unit_count,
+ bool binary_scale);
/* Format time into buf.
*
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)
{
output_dyn_value(buf2, sizeof buf2,
num_recorded_bytes,
- byte_units, true);
+ byte_units, 4, true);
snprintf(buf, sizeof(buf), "%s %s",
str(LANG_RECORDING_SIZE), buf2);
}
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,
val=id3->composer;
break;
case LANG_FILESIZE: /* not LANG_ID3_FILESIZE because the string is shared */
- output_dyn_value(buffer, buffer_len, id3->filesize, byte_units, true);
+ output_dyn_value(buffer, buffer_len, id3->filesize, byte_units, 4, true);
val=buffer;
break;
}
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)
[UNIT_HERTZ]
= VOICE_HERTZ,
[UNIT_MB]
- = LANG_MEGABYTE,
+ = LANG_MEBIBYTE,
[UNIT_KBIT]
= VOICE_KBIT_PER_SEC,
[UNIT_PM_TICK]