tizen 2.4 release
[external/busybox.git] / coreutils / printf.c
index eb53fa4..3dd43a9 100644 (file)
@@ -4,7 +4,7 @@
    Copyright 1999 Dave Cinege
    Portions copyright (C) 1990-1996 Free Software Foundation, Inc.
 
-   Licensed under GPL v2 or later, see file LICENSE in this tarball for details.
+   Licensed under GPLv2 or later, see file LICENSE in this source tree.
 */
 
 /* Usage: printf format [argument...]
    David MacKenzie <djm@gnu.ai.mit.edu>
 */
 
-//   19990508 Busy Boxed! Dave Cinege
+/* 19990508 Busy Boxed! Dave Cinege */
+
+//usage:#define printf_trivial_usage
+//usage:       "FORMAT [ARG]..."
+//usage:#define printf_full_usage "\n\n"
+//usage:       "Format and print ARG(s) according to FORMAT (a-la C printf)"
+//usage:
+//usage:#define printf_example_usage
+//usage:       "$ printf \"Val=%d\\n\" 5\n"
+//usage:       "Val=5\n"
 
 #include "libbb.h"
 
@@ -66,7 +75,7 @@ static int multiconvert(const char *arg, void *result, converter convert)
        errno = 0;
        convert(arg, result);
        if (errno) {
-               bb_error_msg("%s: invalid number", arg);
+               bb_error_msg("invalid number '%s'", arg);
                return 1;
        }
        return 0;
@@ -122,16 +131,29 @@ static double my_xstrtod(const char *arg)
        return result;
 }
 
-static void print_esc_string(char *str)
+/* Handles %b */
+static void print_esc_string(const char *str)
 {
-       while (*str) {
-               if (*str == '\\') {
-                       str++;
-                       bb_putchar(bb_process_escape_sequence((const char **)&str));
-               } else {
-                       bb_putchar(*str);
-                       str++;
+       char c;
+       while ((c = *str) != '\0') {
+               str++;
+               if (c == '\\') {
+                       /* %b also accepts 4-digit octals of the form \0### */
+                       if (*str == '0') {
+                               if ((unsigned char)(str[1] - '0') < 8) {
+                                       /* 2nd char is 0..7: skip leading '0' */
+                                       str++;
+                               }
+                       }
+                       {
+                               /* optimization: don't force arg to be on-stack,
+                                * use another variable for that. */
+                               const char *z = str;
+                               c = bb_process_escape_sequence(&z);
+                               str = z;
+                       }
                }
+               putchar(c);
        }
 }
 
@@ -230,7 +252,7 @@ static int get_width_prec(const char *str)
 {
        int v = bb_strtoi(str, NULL, 10);
        if (errno) {
-               bb_error_msg("%s: invalid number", str);
+               bb_error_msg("invalid number '%s'", str);
                v = 0;
        }
        return v;
@@ -344,7 +366,7 @@ static char **print_formatted(char *f, char **argv, int *conv_err)
                        f--;
                        break;
                default:
-                       bb_putchar(*f);
+                       putchar(*f);
                }
        }