diff options
author | Jim Warner <james.warner@comcast.net> | 2014-06-28 00:00:00 -0500 |
---|---|---|
committer | Craig Small <csmall@enc.com.au> | 2014-07-01 21:30:45 +1000 |
commit | 2199af404a92cac238728564f2f022255c5716ce (patch) | |
tree | 19529bf77a4559056bbac858b2aedc2e7d242eb3 | |
parent | cacba5613ec3333e6536820a0453ae67026eafde (diff) | |
download | procps-ng-2199af404a92cac238728564f2f022255c5716ce.tar.gz |
top: maximize recent locale aware numeric enhancements
When startup argument parsing was recently enhanced to
account for LC_NUMERIC settings, some user input logic
dealing with numbers fails to exploit that capability.
This patch extends such enhancements to a running top.
Reference(s):
commit f7b84f45c7ae99c276de9954fc16cdc4ff7f36f0
http://www.freelists.org/post/procps/topwatch-floating-point-input,2
Signed-off-by: Jim Warner <james.warner@comcast.net>
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | top/top.c | 40 | ||||
-rw-r--r-- | top/top.h | 2 |
3 files changed, 21 insertions, 22 deletions
@@ -11,6 +11,7 @@ procps-ng-3.3.10 * top is now immune to distortions when system time is reset * top standardized the <Esc> key support with prompted input * top missing summary area info added to man document, ubuntu #574624 + * top properly responds to the current locale LC_NUMERIC setting * top provides alternate graph modes for cpu states and memory usage @@ -1259,6 +1259,21 @@ static char *ioline (const char *prompt) { /* + * Make locale aware float (but maybe restrict to whole numbers). */ +static int mkfloat (const char *str, float *num, int whole) { + char *ep; + + if (whole) + *num = (float)strtol(str, &ep, 0); + else + *num = strtof(str, &ep); + if (ep != str && *ep == '\0' && *num < MAXINT) + return 1; + return 0; +} // end: mkfloat + + + /* * This routine provides the i/o in support of files whose size * cannot be determined in advance. Given a stream pointer, he'll * try to slurp in the whole thing and return a dynamically acquired @@ -1302,11 +1317,10 @@ static float get_float (const char *prompt) { if (line[0] == kbd_ESC || Frames_signal) return GET_NUM_ESC; if (!line[0]) return GET_NUM_NOT; // note: we're not allowing negative floats - if (strcspn(line, "+,.0123456789")) { + if (!mkfloat(line, &f, 0) || f < 0) { show_msg(N_txt(BAD_numfloat_txt)); return GET_NUM_BAD; } - sscanf(line, "%f", &f); return f; } // end: get_float @@ -1315,18 +1329,17 @@ static float get_float (const char *prompt) { * Get an integer from the user, returning INT_MIN for error */ static int get_int (const char *prompt) { char *line; - int n; + float f; line = ioline(prompt); if (line[0] == kbd_ESC || Frames_signal) return GET_NUM_ESC; if (!line[0]) return GET_NUM_NOT; // note: we've got to allow negative ints (renice) - if (strcspn(line, "-+0123456789")) { + if (!mkfloat(line, &f, 1)) { show_msg(N_txt(BAD_integers_txt)); return GET_NUM_BAD; } - sscanf(line, "%d", &n); - return n; + return (int)f; } // end: get_int @@ -1350,21 +1363,6 @@ static inline const char *hex_make (KLONG num, int noz) { /* - * Make locale aware float (but maybe restrict to whole numbers). */ -static int mkfloat (const char *str, float *num, int whole) { - char *ep; - - if (whole) - *num = (float)strtol(str, &ep, 0); - else - *num = strtof(str, &ep); - if (ep != str && *ep == '\0' && *num < MAXINT) - return 1; - return 0; -} // end: mkfloat - - - /* * This sructure is hung from a WIN_t when other filtering is active */ struct osel_s { struct osel_s *nxt; // the next criteria or NULL. @@ -677,12 +677,12 @@ typedef struct WIN_t { //atic int ioch (int ech, char *buf, unsigned cnt); //atic int iokey (int action); //atic char *ioline (const char *prompt); +//atic int mkfloat (const char *str, float *num, int whole); //atic int readfile (FILE *fp, char **baddr, size_t *bsize, size_t *bread); /*------ Small Utility routines ----------------------------------------*/ //atic float get_float (const char *prompt); //atic int get_int (const char *prompt); //atic inline const char *hex_make (KLONG num, int noz); -//atic int mkfloat (const char *str, float *num, int whole); //atic void osel_clear (WIN_t *q); //atic inline int osel_matched (const WIN_t *q, FLG_t enu, const char *str); //atic const char *user_certify (WIN_t *q, const char *str, char typ); |