update to the time_clean function by Jean-Edouard Babin
authoroetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa>
Fri, 11 Jun 2010 13:47:24 +0000 (13:47 +0000)
committeroetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa>
Fri, 11 Jun 2010 13:47:24 +0000 (13:47 +0000)
git-svn-id: svn://svn.oetiker.ch/rrdtool/trunk/program@2088 a5681a0c-68f1-0310-ab6d-d61299d08faa

src/rrd_graph.c

index ef51b7c..dcfb3e6 100644 (file)
@@ -5232,44 +5232,119 @@ void grinfo_push(
     }
 }
 
+
 void time_clean(
     char *result,
     char *format)
 {
     int       j, jj;
     
+/*     Handling based on
+       - ANSI C99 Specifications                         http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf
+       - Single UNIX Specification version 2             http://www.opengroup.org/onlinepubs/007908799/xsh/strftime.html 
+       - POSIX:2001/Single UNIX Specification version 3  http://www.opengroup.org/onlinepubs/009695399/functions/strftime.html
+       - POSIX:2008 Specifications                       http://www.opengroup.org/onlinepubs/9699919799/functions/strftime.html
+       Specifications tells 
+       "If a conversion specifier is not one of the above, the behavior is undefined."
+
+      C99 tells
+       "A conversion specifier consists of a % character, possibly followed by an E or O modifier character (described below), followed by a character that determines the behavior of the conversion specifier.
+
+      POSIX:2001 tells
+      "A conversion specification consists of a '%' character, possibly followed by an E or O modifier, and a terminating conversion specifier character that determines the conversion specification's behavior."
+
+      POSIX:2008 introduce more complexe behavior that are not handled here.
+
+      According to this, this code will replace:
+      - % followed by @ by a %@
+      - % followed by   by a %SPACE
+      - % followed by . by a %.
+      - % followed by % by a %
+      - % followed by t by a TAB
+      - % followed by E then anything by '-'
+      - % followed by O then anything by '-'
+      - % followed by anything else by at least one '-'. More characters may be added to better fit expected output length
+*/
+
     jj = 0;
-    for(j = 0; j < FMT_LEG_LEN - 1; j++) { /* we don't need to parse the last char */
+    for(j = 0; (j < FMT_LEG_LEN - 1) && (jj < FMT_LEG_LEN); j++) { /* we don't need to parse the last char */
         if (format[j] == '%') {
-            if ((format[j+1] == 'A') || (format[j+1] == 'a') ||
-                (format[j+1] == 'B') || (format[j+1] == 'b') ||
-                (format[j+1] == 'C') || (format[j+1] == 'c') ||
-                (format[j+1] == 'D') || (format[j+1] == 'd') ||
-                (format[j+1] == 'E') || (format[j+1] == 'e') ||
-                (format[j+1] == 'F') ||
-                (format[j+1] == 'G') || (format[j+1] == 'g') ||
-                (format[j+1] == 'H') || (format[j+1] == 'h') ||
-                (format[j+1] == 'I') ||
-                                        (format[j+1] == 'j') ||
-                                        (format[j+1] == 'k') ||
-                                        (format[j+1] == 'l') ||
-                (format[j+1] == 'M') || (format[j+1] == 'm') ||
-                (format[j+1] == 'O') ||
-                (format[j+1] == 'P') || (format[j+1] == 'p') ||
-                (format[j+1] == 'R') || (format[j+1] == 'r') ||
-                (format[j+1] == 'S') || (format[j+1] == 's') ||
-                (format[j+1] == 'T') ||
-                (format[j+1] == 'U') || (format[j+1] == 'u') ||
-                (format[j+1] == 'V') || (format[j+1] == 'v') ||
-                (format[j+1] == 'W') || (format[j+1] == 'w') ||
-                (format[j+1] == 'X') || (format[j+1] == 'x') ||
-                (format[j+1] == 'Y') || (format[j+1] == 'y') ||
-                (format[j+1] == 'Z') || (format[j+1] == 'z') ||
-                (format[j+1] == '+')) {
+            if ((format[j+1] == 'E') || (format[j+1] == 'O')) {
                 result[jj++] = '-';
+                j+=2; /* We skip next 2 following char */
+            } else if ((format[j+1] == 'C') || (format[j+1] == 'd') ||
+                       (format[j+1] == 'g') || (format[j+1] == 'H') ||
+                       (format[j+1] == 'I') || (format[j+1] == 'm') ||
+                       (format[j+1] == 'M') || (format[j+1] == 'S') ||
+                       (format[j+1] == 'U') || (format[j+1] == 'V') ||
+                       (format[j+1] == 'W') || (format[j+1] == 'y')) {
+                result[jj++] = '-';
+                if (jj < FMT_LEG_LEN) {
+                    result[jj++] = '-';
+                }
                 j++; /* We skip the following char */
-            } else if (format[j+1] == '%') {
-                result[jj++] = '%';
+            } else if (format[j+1] == 'j') {
+                result[jj++] = '-';
+                if (jj < FMT_LEG_LEN - 1) {
+                    result[jj++] = '-';
+                    result[jj++] = '-';
+               }
+                j++; /* We skip the following char */
+            } else if ((format[j+1] == 'G') || (format[j+1] == 'Y')) {
+                /* Assuming Year on 4 digit */
+                result[jj++] = '-';
+                if (jj < FMT_LEG_LEN - 2) {
+                    result[jj++] = '-';
+                    result[jj++] = '-';
+                    result[jj++] = '-';
+                }
+                j++; /* We skip the following char */
+            } else if (format[j+1] == 'R') {
+                result[jj++] = '-';
+                if (jj < FMT_LEG_LEN - 3) {
+                    result[jj++] = '-';
+                    result[jj++] = ':';
+                    result[jj++] = '-';
+                    result[jj++] = '-';
+                }
+                j++; /* We skip the following char */
+            } else if (format[j+1] == 'T') {
+                result[jj++] = '-';
+                if (jj < FMT_LEG_LEN - 6) {
+                    result[jj++] = '-';
+                    result[jj++] = ':';
+                    result[jj++] = '-';
+                    result[jj++] = '-';
+                    result[jj++] = ':';
+                    result[jj++] = '-';
+                    result[jj++] = '-';
+                }
+                j++; /* We skip the following char */
+            } else if (format[j+1] == 'F') {
+                result[jj++] = '-';
+                if (jj < FMT_LEG_LEN - 8) {
+                    result[jj++] = '-';
+                    result[jj++] = '-';
+                    result[jj++] = '-';
+                    result[jj++] = '-';
+                    result[jj++] = '-';
+                    result[jj++] = '-';
+                    result[jj++] = '-';
+                    result[jj++] = '-';
+                    result[jj++] = '-';
+                }
+                j++; /* We skip the following char */
+            } else if (format[j+1] == 'D') {
+                result[jj++] = '-';
+                if (jj < FMT_LEG_LEN - 6) {
+                    result[jj++] = '-';
+                    result[jj++] = '/';
+                    result[jj++] = '-';
+                    result[jj++] = '-';
+                    result[jj++] = '/';
+                    result[jj++] = '-';
+                    result[jj++] = '-';
+                }
                 j++; /* We skip the following char */
             } else if (format[j+1] == 'n') {
                 result[jj++] = '\r';
@@ -5278,11 +5353,33 @@ void time_clean(
             } else if (format[j+1] == 't') {
                 result[jj++] = '\t';
                 j++; /* We skip the following char */
+            } else if (format[j+1] == '%') {
+                result[jj++] = '%';
+                j++; /* We skip the following char */
+            } else if (format[j+1] == ' ') {
+                if (jj < FMT_LEG_LEN - 1) {
+                    result[jj++] = '%';
+                    result[jj++] = ' ';
+                }
+                j++; /* We skip the following char */
+            } else if (format[j+1] == '.') {
+                if (jj < FMT_LEG_LEN - 1) {
+                    result[jj++] = '%';
+                    result[jj++] = '.';
+                }
+                j++; /* We skip the following char */
+            } else if (format[j+1] == '@') {
+                if (jj < FMT_LEG_LEN - 1) {
+                    result[jj++] = '%';
+                    result[jj++] = '@';
+                }
+                j++; /* We skip the following char */
             } else {
-                result[jj++] = format[j];
+                result[jj++] = '-';
+                j++; /* We skip the following char */
             }
         } else {
-            result[jj++] = format[j];
+                result[jj++] = format[j];
         }
     }
     result[jj] = '\0'; /* We must force the end of the string */