* device/lib/pic16/**: build pic16 library using autotools for
[fw/sdcc] / device / lib / pic16 / libc / stdio / vfprintf.c
index 6e7bc6255b89e8d8ef453d4a696f696fdc58e248..f413180b7c9ebcab012546884f9695b37c1143c2 100644 (file)
@@ -2,7 +2,7 @@
     vfprintf.c - source file for reduced version of printf
 
     Modified for pic16 port, by Vangelis Rokas, 2005 (vrokas@otenet.gr)
-    
+
     Written By - Sandeep Dutta . sandeep.dutta@usa.net (1999)
 
     This library is free software; you can redistribute it and/or modify it
 
 /* following formats are supported :-
    format     output type       argument-type
+     %%        -                   -
      %u*       unsigned            *
-     %b               binary
+     %b               binary              int
+     %lb       binary              long
+     %hb       binary              char
      %d        decimal             int
      %ld       decimal             long
      %hd       decimal             char
-     %x        hexadecimal         int
-     %lxX      hexadecimal         long
-     %hxX      hexadecimal         char
+     %[xX]     hexadecimal         int
+     %l[xX]    hexadecimal         long
+     %h[xX]    hexadecimal         char
      %o        octal               int
      %lo       octal               long
      %ho       octal               char
@@ -63,106 +66,118 @@ unsigned int vfprintf(FILE *stream, char *fmt, va_list ap)
   unsigned char fchar, nosign;
   unsigned char upcase;
   unsigned int count=0;
-  unsigned char *str, *ch;
-  data char *str1;
+  char *str, *ch;
+  __data char *str1;
   long val;
 //  static char buffer[16];
   char buffer[16];
 
 
 #if _DEBUG
-    io_str( "vfprintf: " );
-    io_long( (unsigned long)stream );
-    io_long( (unsigned long)fmt );
+  io_str( "vfprintf: " );
+  io_long( (unsigned long)stream );
+  io_long( (unsigned long)fmt );
 #endif
 
 //    va_start(ap,fmt);
-    ch = fmt;
-    
-    while( *ch ) {                     //for (; *fmt ; fmt++ )
-        if (*ch == '%') {
-            flong = 0;
-            fstr = 0;
-            fchar = 0;
-            nosign = 0;
-            radix = 0;
-            upcase = 0;
-            ch++;
-
-            if(*ch == 'u') {
-              nosign = 1;
-              ch++;
-            }
-            
-            if(*ch == 'l') {
-              flong = 1;
-              ch++;
-            } else
-            if(*ch == 'h') {
-              fchar = 1;
-              ch++;
-            }
-            
-            if(*ch == 's')fstr = 1;
-            else if(*ch == 'd')radix = 10;
-            else if(*ch == 'x'){ radix = 16; upcase = 0; }
-            else if(*ch == 'X'){ radix = 16; upcase = 1; }
-            else if(*ch == 'c')radix = 0;
-            else if(*ch == 'o')radix = 8;
-            else if(*ch == 'b')radix = 2;
-            
-            if(fstr) {
-                str = va_arg(ap, char *);
-                while(*str) { __stream_putchar(stream, *str); str++; count++; }
-            } else {
-              val = 0;
-              if(flong) {
-                val = va_arg(ap, long);
+  ch = fmt;
+
+  while( *ch ) {      //for (; *fmt ; fmt++ )
+    if (*ch == '%') {
+      flong = 0;
+      fstr = 0;
+      fchar = 0;
+      nosign = 0;
+      radix = 0;
+      upcase = 0;
+      ch++;
+
+      if(*ch == '%') {
+        __stream_putchar(stream, *ch);
+        ++count;
+        ++ch;
+        continue;
+      }
+
+      if(*ch == 'u') {
+        nosign = 1;
+        ch++;
+      }
+
+      if(*ch == 'l') {
+        flong = 1;
+        ch++;
+      } else if(*ch == 'h') {
+        fchar = 1;
+        ch++;
+      }
+
+      if(*ch == 's')fstr = 1;
+      else if(*ch == 'd')radix = 10;
+      else if(*ch == 'x'){ radix = 16; upcase = 0; }
+      else if(*ch == 'X'){ radix = 16; upcase = 1; }
+      else if(*ch == 'c')radix = 0;
+      else if(*ch == 'o')radix = 8;
+      else if(*ch == 'b')radix = 2;
+      else {
+        __stream_putchar(stream, *ch);
+        ++count;
+        ++ch;
+        continue;
+      }
+
+      if(fstr) {
+        str = va_arg(ap, char *);
+        while(*str) { __stream_putchar(stream, *str); str++; count++; }
+      } else {
+        val = 0;
+        if(flong) {
+          val = va_arg(ap, long);
 #if _DEBUG
-                io_long(val);
+          io_long(val);
 #endif
-              }              
-              else
-              if(fchar) {
-                val = va_arg(ap, char);
+        }
+        else if(fchar) {
+          val = (unsigned char)va_arg(ap, int); // FIXME: SDCC passes 1-byte char varargs as 2-byte ints...
+         if (!nosign) val = (char) val; // (FIXME cont'd) sign extend if required
 #if _DEBUG
-                io_long(val);
+          io_long(val);
 #endif
-              }
-              else {
-                  val = va_arg(ap, int);
+        }
+        else {
+          val = va_arg(ap, int);
 #if _DEBUG
-                io_long(val);
+          io_long(val);
 #endif
-              }
-
-              if(radix) {
-                if(nosign)
-                  ultoa(val, buffer, radix);
-                else
-                  ltoa (val, buffer, radix);
-
-                str1 = buffer;
-                while( (*str1) ) {
-                  radix = *str1;
-                  if(upcase)
-                    radix = toupper( radix );
-                  __stream_putchar(stream, (unsigned char)radix);
-                  count++;
-                  str1++;
-                }
-              }        else {
-                __stream_putchar(stream, (unsigned char)val);
-                count++;
-              }
-            }
-          } else {
-            __stream_putchar(stream, *ch);
+        }
+
+        if(radix) {
+          if(nosign)
+            ultoa(val, buffer, radix);
+          else
+            ltoa (val, buffer, radix);
+
+          str1 = buffer;
+          while( (*str1) ) {
+            radix = *str1;
+            if(upcase)
+              radix = toupper( radix );
+            __stream_putchar(stream, (unsigned char)radix);
             count++;
+            str1++;
           }
-
-        ch++;
+        } else {
+          __stream_putchar(stream, (unsigned char)val);
+          count++;
+        }
+      }
+    } else {
+      __stream_putchar(stream, *ch);
+      count++;
     }
-  
+
+    ch++;
+  }
+
   return (count);
 }