tizen 2.3.1 release
[external/curl.git] / lib / mprintf.c
index 536c0c2..23070a7 100644 (file)
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1999 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1999 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * page at http://daniel.haxx.se/trio/
  */
 
-#include "setup.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <ctype.h>
-#include <string.h>
+#include "curl_setup.h"
 
 #if defined(DJGPP) && (DJGPP_MINOR < 4)
 #undef _MPRINTF_REPLACE /* don't use x_was_used() here */
 #endif
 
 /*
+ * Non-ANSI integer extensions
+ */
+
+#if (defined(__BORLANDC__) && (__BORLANDC__ >= 0x520)) || \
+    (defined(__WATCOMC__) && defined(__386__)) || \
+    (defined(__POCC__) && defined(_MSC_VER)) || \
+    (defined(_WIN32_WCE)) || \
+    (defined(__MINGW32__)) || \
+    (defined(_MSC_VER) && (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64))
+#  define MP_HAVE_INT_EXTENSIONS
+#endif
+
+/*
  * Max integer data types that mprintf.c is capable
  */
 
@@ -108,7 +116,7 @@ static const char upper_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
       done++; \
     else \
      return done; /* return immediately on failure */ \
-  } while(0)
+  } WHILE_FALSE
 
 /* Data type to read from the arglist */
 typedef enum  {
@@ -124,7 +132,7 @@ typedef enum  {
   FORMAT_WIDTH /* For internal use */
 } FormatType;
 
-/* convertion and display flags */
+/* conversion and display flags */
 enum {
   FLAGS_NEW        = 0,
   FLAGS_SPACE      = 1<<0,
@@ -194,114 +202,29 @@ static long dprintf_DollarString(char *input, char **end)
   return 0;
 }
 
-static int dprintf_IsQualifierNoDollar(char c)
+static bool dprintf_IsQualifierNoDollar(const char *fmt)
 {
-  switch (c) {
+#if defined(MP_HAVE_INT_EXTENSIONS)
+  if(!strncmp(fmt, "I32", 3) || !strncmp(fmt, "I64", 3)) {
+    return TRUE;
+  }
+#endif
+
+  switch(*fmt) {
   case '-': case '+': case ' ': case '#': case '.':
   case '0': case '1': case '2': case '3': case '4':
   case '5': case '6': case '7': case '8': case '9':
   case 'h': case 'l': case 'L': case 'z': case 'q':
   case '*': case 'O':
-    return 1; /* true */
-  default:
-    return 0; /* false */
-  }
-}
-
-#ifdef DPRINTF_DEBUG2
-static void dprintf_Pass1Report(va_stack_t *vto, int max)
-{
-  int i;
-  char buffer[256];
-  int bit;
-  int flags;
-
-  for(i=0; i<max; i++) {
-    char *type;
-    switch(vto[i].type) {
-    case FORMAT_UNKNOWN:
-      type = "unknown";
-      break;
-    case FORMAT_STRING:
-      type ="string";
-      break;
-    case FORMAT_PTR:
-      type ="pointer";
-      break;
-    case FORMAT_INT:
-      type = "int";
-      break;
-    case FORMAT_INTPTR:
-      type = "intptr";
-      break;
-    case FORMAT_LONG:
-      type = "long";
-      break;
-    case FORMAT_LONGLONG:
-      type = "long long";
-      break;
-    case FORMAT_DOUBLE:
-      type = "double";
-      break;
-    case FORMAT_LONGDOUBLE:
-      type = "long double";
-      break;
-    }
-
-
-    buffer[0]=0;
-
-    for(bit=0; bit<31; bit++) {
-      flags = vto[i].flags & (1<<bit);
-
-      if(flags & FLAGS_SPACE)
-        strcat(buffer, "space ");
-      else if(flags & FLAGS_SHOWSIGN)
-        strcat(buffer, "plus ");
-      else if(flags & FLAGS_LEFT)
-        strcat(buffer, "left ");
-      else if(flags & FLAGS_ALT)
-        strcat(buffer, "alt ");
-      else if(flags & FLAGS_SHORT)
-        strcat(buffer, "short ");
-      else if(flags & FLAGS_LONG)
-        strcat(buffer, "long ");
-      else if(flags & FLAGS_LONGLONG)
-        strcat(buffer, "longlong ");
-      else if(flags & FLAGS_LONGDOUBLE)
-        strcat(buffer, "longdouble ");
-      else if(flags & FLAGS_PAD_NIL)
-        strcat(buffer, "padnil ");
-      else if(flags & FLAGS_UNSIGNED)
-        strcat(buffer, "unsigned ");
-      else if(flags & FLAGS_OCTAL)
-        strcat(buffer, "octal ");
-      else if(flags & FLAGS_HEX)
-        strcat(buffer, "hex ");
-      else if(flags & FLAGS_UPPER)
-        strcat(buffer, "upper ");
-      else if(flags & FLAGS_WIDTH)
-        strcat(buffer, "width ");
-      else if(flags & FLAGS_WIDTHPARAM)
-        strcat(buffer, "widthparam ");
-      else if(flags & FLAGS_PREC)
-        strcat(buffer, "precision ");
-      else if(flags & FLAGS_PRECPARAM)
-        strcat(buffer, "precparam ");
-      else if(flags & FLAGS_CHAR)
-        strcat(buffer, "char ");
-      else if(flags & FLAGS_FLOATE)
-        strcat(buffer, "floate ");
-      else if(flags & FLAGS_FLOATG)
-        strcat(buffer, "floatg ");
-    }
-    printf("REPORT: %d. %s [%s]\n", i, type, buffer);
+#if defined(MP_HAVE_INT_EXTENSIONS)
+  case 'I':
+#endif
+    return TRUE;
 
+  default:
+    return FALSE;
   }
-
-
 }
-#endif
 
 /******************************************************************
  *
@@ -355,8 +278,20 @@ static long dprintf_Pass1(const char *format, va_stack_t *vto, char **endpos,
 
       /* Handle the flags */
 
-      while(dprintf_IsQualifierNoDollar(*fmt)) {
-        switch (*fmt++) {
+      while(dprintf_IsQualifierNoDollar(fmt)) {
+#if defined(MP_HAVE_INT_EXTENSIONS)
+        if(!strncmp(fmt, "I32", 3)) {
+          flags |= FLAGS_LONG;
+          fmt += 3;
+        }
+        else if(!strncmp(fmt, "I64", 3)) {
+          flags |= FLAGS_LONGLONG;
+          fmt += 3;
+        }
+        else
+#endif
+
+        switch(*fmt++) {
         case ' ':
           flags |= FLAGS_SPACE;
           break;
@@ -396,6 +331,15 @@ static long dprintf_Pass1(const char *format, va_stack_t *vto, char **endpos,
         case 'h':
           flags |= FLAGS_SHORT;
           break;
+#if defined(MP_HAVE_INT_EXTENSIONS)
+        case 'I':
+#if (CURL_SIZEOF_CURL_OFF_T > CURL_SIZEOF_LONG)
+          flags |= FLAGS_LONGLONG;
+#else
+          flags |= FLAGS_LONG;
+#endif
+          break;
+#endif
         case 'l':
           if(flags & FLAGS_LONG)
             flags |= FLAGS_LONGLONG;
@@ -480,11 +424,11 @@ static long dprintf_Pass1(const char *format, va_stack_t *vto, char **endpos,
         break;
       case 'x':
         vto[i].type = FORMAT_INT;
-        flags |= FLAGS_HEX;
+        flags |= FLAGS_HEX|FLAGS_UNSIGNED;
         break;
       case 'X':
         vto[i].type = FORMAT_INT;
-        flags |= FLAGS_HEX|FLAGS_UPPER;
+        flags |= FLAGS_HEX|FLAGS_UPPER|FLAGS_UNSIGNED;
         break;
       case 'c':
         vto[i].type = FORMAT_INT;
@@ -542,72 +486,66 @@ static long dprintf_Pass1(const char *format, va_stack_t *vto, char **endpos,
     }
   }
 
-#ifdef DPRINTF_DEBUG2
-  dprintf_Pass1Report(vto, max_param);
-#endif
-
   /* Read the arg list parameters into our data list */
-  for (i=0; i<max_param; i++) {
-    if((i + 1 < max_param) && (vto[i + 1].type == FORMAT_WIDTH))
-      {
-        /* Width/precision arguments must be read before the main argument
-         * they are attached to
-         */
-        vto[i + 1].data.num.as_signed = (mp_intmax_t)va_arg(arglist, int);
-      }
+  for(i=0; i<max_param; i++) {
+    if((i + 1 < max_param) && (vto[i + 1].type == FORMAT_WIDTH)) {
+      /* Width/precision arguments must be read before the main argument
+       * they are attached to
+       */
+      vto[i + 1].data.num.as_signed = (mp_intmax_t)va_arg(arglist, int);
+    }
 
-    switch (vto[i].type)
-      {
-      case FORMAT_STRING:
-        vto[i].data.str = va_arg(arglist, char *);
-        break;
+    switch (vto[i].type) {
+    case FORMAT_STRING:
+      vto[i].data.str = va_arg(arglist, char *);
+      break;
 
-      case FORMAT_INTPTR:
-      case FORMAT_UNKNOWN:
-      case FORMAT_PTR:
-        vto[i].data.ptr = va_arg(arglist, void *);
-        break;
+    case FORMAT_INTPTR:
+    case FORMAT_UNKNOWN:
+    case FORMAT_PTR:
+      vto[i].data.ptr = va_arg(arglist, void *);
+      break;
 
-      case FORMAT_INT:
+    case FORMAT_INT:
 #ifdef HAVE_LONG_LONG_TYPE
-        if((vto[i].flags & FLAGS_LONGLONG) && (vto[i].flags & FLAGS_UNSIGNED))
+      if((vto[i].flags & FLAGS_LONGLONG) && (vto[i].flags & FLAGS_UNSIGNED))
+        vto[i].data.num.as_unsigned =
+          (mp_uintmax_t)va_arg(arglist, mp_uintmax_t);
+      else if(vto[i].flags & FLAGS_LONGLONG)
+        vto[i].data.num.as_signed =
+          (mp_intmax_t)va_arg(arglist, mp_intmax_t);
+      else
+#endif
+      {
+        if((vto[i].flags & FLAGS_LONG) && (vto[i].flags & FLAGS_UNSIGNED))
           vto[i].data.num.as_unsigned =
-            (mp_uintmax_t)va_arg(arglist, mp_uintmax_t);
-        else if(vto[i].flags & FLAGS_LONGLONG)
+            (mp_uintmax_t)va_arg(arglist, unsigned long);
+        else if(vto[i].flags & FLAGS_LONG)
           vto[i].data.num.as_signed =
-            (mp_intmax_t)va_arg(arglist, mp_intmax_t);
+            (mp_intmax_t)va_arg(arglist, long);
+        else if(vto[i].flags & FLAGS_UNSIGNED)
+          vto[i].data.num.as_unsigned =
+            (mp_uintmax_t)va_arg(arglist, unsigned int);
         else
-#endif
-        {
-          if((vto[i].flags & FLAGS_LONG) && (vto[i].flags & FLAGS_UNSIGNED))
-            vto[i].data.num.as_unsigned =
-              (mp_uintmax_t)va_arg(arglist, unsigned long);
-          else if(vto[i].flags & FLAGS_LONG)
-            vto[i].data.num.as_signed =
-              (mp_intmax_t)va_arg(arglist, long);
-          else if(vto[i].flags & FLAGS_UNSIGNED)
-            vto[i].data.num.as_unsigned =
-              (mp_uintmax_t)va_arg(arglist, unsigned int);
-          else
-            vto[i].data.num.as_signed =
-              (mp_intmax_t)va_arg(arglist, int);
-        }
-        break;
+          vto[i].data.num.as_signed =
+            (mp_intmax_t)va_arg(arglist, int);
+      }
+      break;
 
-      case FORMAT_DOUBLE:
-        vto[i].data.dnum = va_arg(arglist, double);
-        break;
+    case FORMAT_DOUBLE:
+      vto[i].data.dnum = va_arg(arglist, double);
+      break;
 
-      case FORMAT_WIDTH:
-        /* Argument has been read. Silently convert it into an integer
-         * for later use
-         */
-        vto[i].type = FORMAT_INT;
-        break;
+    case FORMAT_WIDTH:
+      /* Argument has been read. Silently convert it into an integer
+       * for later use
+       */
+      vto[i].type = FORMAT_INT;
+      break;
 
-      default:
-        break;
-      }
+    default:
+      break;
+    }
   }
 
   return max_param;
@@ -692,7 +630,7 @@ static int dprintf_formatf(
       continue;
     }
 
-    /* If this is a positional parameter, the position must follow imediately
+    /* If this is a positional parameter, the position must follow immediately
        after the %, thus create a %<num>$ sequence */
     param=dprintf_DollarString(f, &f);
 
@@ -739,23 +677,23 @@ static int dprintf_formatf(
             OUTCHAR(' ');
         break;
       }
-      if(p->flags & FLAGS_UNSIGNED) {
-        /* Decimal unsigned integer.  */
-        base = 10;
-        goto unsigned_number;
-      }
       if(p->flags & FLAGS_OCTAL) {
         /* Octal unsigned integer.  */
         base = 8;
         goto unsigned_number;
       }
-      if(p->flags & FLAGS_HEX) {
+      else if(p->flags & FLAGS_HEX) {
         /* Hexadecimal unsigned integer.  */
 
         digits = (p->flags & FLAGS_UPPER)? upper_digits : lower_digits;
         base = 16;
         goto unsigned_number;
       }
+      else if(p->flags & FLAGS_UNSIGNED) {
+        /* Decimal unsigned integer.  */
+        base = 10;
+        goto unsigned_number;
+      }
 
       /* Decimal integer.  */
       base = 10;
@@ -853,7 +791,7 @@ static int dprintf_formatf(
         size_t len;
 
         str = (char *) p->data.str;
-        if( str == NULL) {
+        if(str == NULL) {
           /* Write null[] if there's space.  */
           if(prec == -1 || prec >= (long) sizeof(null) - 1) {
             str = null;
@@ -866,11 +804,11 @@ static int dprintf_formatf(
             len = 0;
           }
         }
+        else if(prec != -1)
+          len = (size_t)prec;
         else
           len = strlen(str);
 
-        if(prec != -1 && (size_t) prec < len)
-          len = (size_t)prec;
         width -= (long)len;
 
         if(p->flags & FLAGS_ALT)
@@ -880,7 +818,7 @@ static int dprintf_formatf(
           while(width-- > 0)
             OUTCHAR(' ');
 
-        while(len-- > 0)
+        while((len-- > 0) && *str)
           OUTCHAR(*str++);
         if(p->flags&FLAGS_LEFT)
           while(width-- > 0)
@@ -914,7 +852,7 @@ static int dprintf_formatf(
           if(p->flags & FLAGS_LEFT)
             while(width-- > 0)
               OUTCHAR(' ');
-          for (point = strnil; *point != '\0'; ++point)
+          for(point = strnil; *point != '\0'; ++point)
             OUTCHAR(*point);
           if(! (p->flags & FLAGS_LEFT))
             while(width-- > 0)
@@ -926,7 +864,7 @@ static int dprintf_formatf(
     case FORMAT_DOUBLE:
       {
         char formatbuf[32]="%";
-        char *fptr;
+        char *fptr = &formatbuf[1];
         size_t left = sizeof(formatbuf)-strlen(formatbuf);
         int len;
 
@@ -943,15 +881,15 @@ static int dprintf_formatf(
           prec = (long)vto[p->precision].data.num.as_signed;
 
         if(p->flags & FLAGS_LEFT)
-          strcat(formatbuf, "-");
+          *fptr++ = '-';
         if(p->flags & FLAGS_SHOWSIGN)
-          strcat(formatbuf, "+");
+          *fptr++ = '+';
         if(p->flags & FLAGS_SPACE)
-          strcat(formatbuf, " ");
+          *fptr++ = ' ';
         if(p->flags & FLAGS_ALT)
-          strcat(formatbuf, "#");
+          *fptr++ = '#';
 
-        fptr=&formatbuf[strlen(formatbuf)];
+        *fptr = 0;
 
         if(width >= 0) {
           /* RECURSIVE USAGE */
@@ -976,8 +914,8 @@ static int dprintf_formatf(
 
         *fptr = 0; /* and a final zero termination */
 
-        /* NOTE NOTE NOTE!! Not all sprintf() implementations returns number
-           of output characters */
+        /* NOTE NOTE NOTE!! Not all sprintf implementations return number of
+           output characters */
         (sprintf)(work, formatbuf, p->data.dnum);
 
         for(fptr=work; *fptr; fptr++)
@@ -1202,45 +1140,3 @@ int curl_mvfprintf(FILE *whereto, const char *format, va_list ap_save)
 {
   return dprintf_formatf(whereto, fputc, format, ap_save);
 }
-
-#ifdef DPRINTF_DEBUG
-int main()
-{
-  char buffer[129];
-  char *ptr;
-#ifdef HAVE_LONG_LONG_TYPE
-  LONG_LONG_TYPE one=99;
-  LONG_LONG_TYPE two=100;
-  LONG_LONG_TYPE test = 0x1000000000LL;
-  curl_mprintf("%lld %lld %lld\n", one, two, test);
-#endif
-
-  curl_mprintf("%3d %5d\n", 10, 1998);
-
-  ptr=curl_maprintf("test this then baby %s%s%s%s%s%s %d %d %d loser baby get a kiss in yer face now!", "", "pretty long string pretty long string pretty long string pretty long string pretty long string", "/", "/", "/", "pretty long string", 1998, 1999, 2001);
-
-  puts(ptr);
-
-  memset(ptr, 55, strlen(ptr)+1);
-
-  free(ptr);
-
-#if 1
-  curl_mprintf(buffer, "%s %s %d", "daniel", "stenberg", 19988);
-  puts(buffer);
-
-  curl_mfprintf(stderr, "%s %#08x\n", "dummy", 65);
-
-  printf("%s %#08x\n", "dummy", 65);
-  {
-    double tryout = 3.14156592;
-    curl_mprintf(buffer, "%.2g %G %f %e %E", tryout, tryout, tryout, tryout, tryout);
-    puts(buffer);
-    printf("%.2g %G %f %e %E\n", tryout, tryout, tryout, tryout, tryout);
-  }
-#endif
-
-  return 0;
-}
-
-#endif