changeset 1652:971df24b458b draft

Promote printf.
author Rob Landley <rob@landley.net>
date Sun, 11 Jan 2015 10:17:58 -0600
parents 114fb916e04e
children 58cb2d7bd461
files toys/pending/printf.c toys/posix/printf.c
diffstat 2 files changed, 143 insertions(+), 143 deletions(-) [+]
line wrap: on
line diff
--- a/toys/pending/printf.c	Sun Jan 11 10:16:38 2015 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,143 +0,0 @@
-/* printf.c - Format and Print the data.
- *
- * Copyright 2014 Sandeep Sharma <sandeep.jack2756@gmail.com>
- * Copyright 2014 Kyungwan Han <asura321@gmail.com>
- *
- * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/printf.html
- *
- * todo: *m$ ala printf("%1$d:%2$.*3$d:%4$.*3$d\n", hour, min, precision, sec);
-
-USE_PRINTF(NEWTOY(printf, "<1", TOYFLAG_USR|TOYFLAG_BIN))
-
-config PRINTF 
-  bool "printf"
-  default n
-  help
-    usage: printf FORMAT [ARGUMENT...]
-    
-    Format and print ARGUMENT(s) according to FORMAT, using C printf syntax
-    (% escapes for cdeEfgGiosuxX, \ escapes for abefnrtv0 or \OCTAL or \xHEX).
-*/
-
-#define FOR_printf
-#include "toys.h"
-
-// Detect matching character (return true/valse) and advance pointer if match.
-static int eat(char **s, char c)
-{
-  int x = (**s == c);
-
-  if (x) ++*s;
-
-  return x;
-}
-
-// Parse escape sequences.
-static int handle_slash(char **esc_val)
-{
-  char *ptr = *esc_val;
-  int len, base = 0;
-  unsigned result = 0, num;
-
-  if (*ptr == 'c') xexit();
-
-  // 0x12 hex escapes have 1-2 digits, \123 octal escapes have 1-3 digits.
-  if (eat(&ptr, 'x')) base = 16;
-  else if (*ptr >= '0' && *ptr <= '8') base = 8;
-  len = (char []){0,3,2}[base/8];
-
-  // Not a hex or octal escape? (This catches trailing \)
-  if (!len) {
-    if (!(result = unescape(*ptr))) result = '\\';
-    else ++*esc_val;
-
-    return result;
-  }
-
-  while (len) {
-    num = tolower(*ptr) - '0';
-    if (num >= 'a'-'0') num += '0'-'a'+10;
-    if (num >= base) {
-      // Don't parse invalid hex value ala "\xvd", print it verbatim
-      if (base == 16 && len == 2) {
-        ptr--;
-        result = '\\';
-      }
-      break;
-    }
-    result = (result*base)+num;
-    ptr++;
-    len--;
-  }
-  *esc_val = ptr;
-
-  return result;
-}
-
-void printf_main(void)
-{
-  char **arg = toys.optargs+1;
-
-  // Repeat format until arguments consumed
-  for (;;) {
-    int seen = 0;
-    char *f = *toys.optargs;
-
-    // Loop through characters in format
-    while (*f) {
-      if (eat(&f, '\\')) putchar(handle_slash(&f));
-      else if (!eat(&f, '%') || *f == '%') putchar(*f++);
-
-      // Handle %escape
-      else {
-        char c, *end = 0, *aa, *to = toybuf;
-        int wp[] = {0,-1}, i;
-
-        // Parse width.precision between % and type indicator.
-        *to++ = '%';
-        while (strchr("-+# '0", *f) && (to-toybuf)<10) *to++ = *f++;
-        for (i=0; i<2; i++) {
-          if (eat(&f, '*')) {
-            if (*arg) wp[i] = atolx(*arg++);
-          } else while (*f >= '0' && *f <= '9') {
-            if (wp[i]<0) wp[i] = 0;
-            wp[i] = (wp[i]*10)+(*f++)-'0';
-          }
-          if (!eat(&f, '.')) break;
-        }
-        c = *f++;
-        seen = sprintf(to, "*.*%c", c);;
-        errno = 0;
-        aa = *arg ? *arg++ : "";
-
-        // Output %esc using parsed format string
-        if (c == 'b') {
-          while (*aa) putchar(eat(&aa, '\\') ? handle_slash(&aa) : *aa++);
-
-          continue;
-        } else if (c == 'c') printf(toybuf, wp[0], wp[1], *aa);
-        else if (c == 's') printf(toybuf, wp[0], wp[1], aa);
-        else if (strchr("diouxX", c)) {
-          long ll;
-
-          if (*aa == '\'' || *aa == '"') ll = aa[1];
-          else ll = strtoll(aa, &end, 0);
-
-          sprintf(to, "*.*ll%c", c);
-          printf(toybuf, wp[0], wp[1], ll);
-        } else if (strchr("feEgG", c)) {
-          long double ld = strtold(aa, &end);
-
-          sprintf(to, "*.*L%c", c);
-          printf(toybuf, wp[0], wp[1], ld);
-        } else error_exit("bad %%%c@%ld", c, f-*toys.optargs);
-
-        if (end && (errno || *end)) perror_msg("bad %%%c %s", c, aa);
-      }
-    }
-
-    // Posix says to keep looping through format until we consume all args.
-    // This only works if the format actually consumed at least one arg.
-    if (!seen || !*arg) break;
-  }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/toys/posix/printf.c	Sun Jan 11 10:17:58 2015 -0600
@@ -0,0 +1,143 @@
+/* printf.c - Format and Print the data.
+ *
+ * Copyright 2014 Sandeep Sharma <sandeep.jack2756@gmail.com>
+ * Copyright 2014 Kyungwan Han <asura321@gmail.com>
+ *
+ * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/printf.html
+ *
+ * todo: *m$ ala printf("%1$d:%2$.*3$d:%4$.*3$d\n", hour, min, precision, sec);
+
+USE_PRINTF(NEWTOY(printf, "<1", TOYFLAG_USR|TOYFLAG_BIN))
+
+config PRINTF 
+  bool "printf"
+  default y
+  help
+    usage: printf FORMAT [ARGUMENT...]
+    
+    Format and print ARGUMENT(s) according to FORMAT, using C printf syntax
+    (% escapes for cdeEfgGiosuxX, \ escapes for abefnrtv0 or \OCTAL or \xHEX).
+*/
+
+#define FOR_printf
+#include "toys.h"
+
+// Detect matching character (return true/valse) and advance pointer if match.
+static int eat(char **s, char c)
+{
+  int x = (**s == c);
+
+  if (x) ++*s;
+
+  return x;
+}
+
+// Parse escape sequences.
+static int handle_slash(char **esc_val)
+{
+  char *ptr = *esc_val;
+  int len, base = 0;
+  unsigned result = 0, num;
+
+  if (*ptr == 'c') xexit();
+
+  // 0x12 hex escapes have 1-2 digits, \123 octal escapes have 1-3 digits.
+  if (eat(&ptr, 'x')) base = 16;
+  else if (*ptr >= '0' && *ptr <= '8') base = 8;
+  len = (char []){0,3,2}[base/8];
+
+  // Not a hex or octal escape? (This catches trailing \)
+  if (!len) {
+    if (!(result = unescape(*ptr))) result = '\\';
+    else ++*esc_val;
+
+    return result;
+  }
+
+  while (len) {
+    num = tolower(*ptr) - '0';
+    if (num >= 'a'-'0') num += '0'-'a'+10;
+    if (num >= base) {
+      // Don't parse invalid hex value ala "\xvd", print it verbatim
+      if (base == 16 && len == 2) {
+        ptr--;
+        result = '\\';
+      }
+      break;
+    }
+    result = (result*base)+num;
+    ptr++;
+    len--;
+  }
+  *esc_val = ptr;
+
+  return result;
+}
+
+void printf_main(void)
+{
+  char **arg = toys.optargs+1;
+
+  // Repeat format until arguments consumed
+  for (;;) {
+    int seen = 0;
+    char *f = *toys.optargs;
+
+    // Loop through characters in format
+    while (*f) {
+      if (eat(&f, '\\')) putchar(handle_slash(&f));
+      else if (!eat(&f, '%') || *f == '%') putchar(*f++);
+
+      // Handle %escape
+      else {
+        char c, *end = 0, *aa, *to = toybuf;
+        int wp[] = {0,-1}, i;
+
+        // Parse width.precision between % and type indicator.
+        *to++ = '%';
+        while (strchr("-+# '0", *f) && (to-toybuf)<10) *to++ = *f++;
+        for (i=0; i<2; i++) {
+          if (eat(&f, '*')) {
+            if (*arg) wp[i] = atolx(*arg++);
+          } else while (*f >= '0' && *f <= '9') {
+            if (wp[i]<0) wp[i] = 0;
+            wp[i] = (wp[i]*10)+(*f++)-'0';
+          }
+          if (!eat(&f, '.')) break;
+        }
+        c = *f++;
+        seen = sprintf(to, "*.*%c", c);;
+        errno = 0;
+        aa = *arg ? *arg++ : "";
+
+        // Output %esc using parsed format string
+        if (c == 'b') {
+          while (*aa) putchar(eat(&aa, '\\') ? handle_slash(&aa) : *aa++);
+
+          continue;
+        } else if (c == 'c') printf(toybuf, wp[0], wp[1], *aa);
+        else if (c == 's') printf(toybuf, wp[0], wp[1], aa);
+        else if (strchr("diouxX", c)) {
+          long ll;
+
+          if (*aa == '\'' || *aa == '"') ll = aa[1];
+          else ll = strtoll(aa, &end, 0);
+
+          sprintf(to, "*.*ll%c", c);
+          printf(toybuf, wp[0], wp[1], ll);
+        } else if (strchr("feEgG", c)) {
+          long double ld = strtold(aa, &end);
+
+          sprintf(to, "*.*L%c", c);
+          printf(toybuf, wp[0], wp[1], ld);
+        } else error_exit("bad %%%c@%ld", c, f-*toys.optargs);
+
+        if (end && (errno || *end)) perror_msg("bad %%%c %s", c, aa);
+      }
+    }
+
+    // Posix says to keep looping through format until we consume all args.
+    // This only works if the format actually consumed at least one arg.
+    if (!seen || !*arg) break;
+  }
+}