]> granicus.if.org Git - procps-ng/commitdiff
top: maximize recent locale aware numeric enhancements
authorJim Warner <james.warner@comcast.net>
Sat, 28 Jun 2014 05:00:00 +0000 (00:00 -0500)
committerCraig Small <csmall@enc.com.au>
Tue, 1 Jul 2014 11:30:45 +0000 (21:30 +1000)
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>
NEWS
top/top.c
top/top.h

diff --git a/NEWS b/NEWS
index 33cb0bd10de433d9e3299761dcf0ea6160baac36..83809e78340ecdbfadb343d566bc46dbb6fabc48 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -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
 
 
index 4e8ea68b89a54d259adab393fd6e925a9ea48115..29875374e3efb6b1e6f4257cdebba9ef34112e35 100644 (file)
--- a/top/top.c
+++ b/top/top.c
@@ -1258,6 +1258,21 @@ static char *ioline (const char *prompt) {
 #endif
 
 
+        /*
+         * 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
@@ -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
 
 
@@ -1349,21 +1362,6 @@ static inline const char *hex_make (KLONG num, int noz) {
 } // end: hex_make
 
 
-        /*
-         * 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 {
index 859840196684bdacfa578b083698979968e9f969..26532f0bb16889d50d72c4520daf49ec56818c7c 100644 (file)
--- a/top/top.h
+++ b/top/top.h
@@ -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);