]> rtime.felk.cvut.cz Git - arc.git/blobdiff - common/printf.c
Merge branch 'mikulka' of git@rtime.felk.cvut.cz:arc into mikulka
[arc.git] / common / printf.c
index da7d1125cf70acc4d48bb191e77c384a94af20e7..be39635ab039acdcbebb8f9952fdf4f5c5818e5f 100644 (file)
  *  - ANSI-C and POSIX, streams and POSIX filenumbers.\r
  *    POSIX file-numbers exist in unistd.h and are only to be used by the porting\r
  *    newlib interface i.e. newlib_port.c.\r
- *    The filenumber is actually just a cast of the steampointer and save in the member\r
- *    _cookie in FILE.\r
+ *\r
+ *\r
+ * NEWLIB: File handles vs files\r
+ *   This printf() family of functions does not use newlib at all.\r
+ *   At this point the following can have happend:\r
+ *   1. A call to any of the file functions in newlib have been called.\r
+ *      This then calls a number of functions (sbrk, __sinit(_impure_ptr), etc ).\r
+ *      __sinit(_impure_ptr) initializes the standard files, stdin, stdout, stderr.\r
+ *      file->_file is the actual posix file number (stdin=0, stdout=1, stderr=2)\r
+ *   2. No calls is done to newlib file functions. The impure_data is then empty and\r
+ *      all fields are 0.\r
+ *\r
+ *  Code for checking if the newlib have initialized (or we have explicitly called __sinit(_impure_ptr)\r
+ *     if( _impure_ptr->__sdidinit == 1 ) {\r
+ *       // We use the real filenumber\r
+ *       arc_putchar((int)(file->_file), c);\r
+ *     )\r
  *\r
  */\r
 \r
 #include <stdarg.h>\r
 #include <assert.h>\r
 #include <string.h>\r
-\r
+#if defined(USE_NEWLIB) && defined(__GNUC__)\r
+#include "reent.h"\r
+#endif\r
 //#define HOST_TEST    1\r
 \r
 int arc_putchar(int fd, int c);\r
 int print(FILE *file, char **buffer, size_t n, const char *format, va_list ap);\r
+static inline int emitChar( FILE *file, char **buf, char c, int *left );\r
+\r
+int fputs( const char *s, FILE *file ) {\r
+       int left = ~(size_t)0;\r
+       while(*s) {\r
+               emitChar(file,NULL,*s++,&left);\r
+       }\r
+       return 0;\r
+}\r
+\r
 \r
 int printf(const char *format, ...) {\r
        va_list ap;\r
        int rv;\r
 \r
        va_start(ap, format);\r
-       rv = vfprintf(stdout, format, ap);\r
+       rv = vfprintf((FILE *)STDOUT_FILENO, format, ap);\r
        va_end(ap);\r
        return rv;\r
 }\r
@@ -93,7 +120,7 @@ int snprintf(char *buffer, size_t n, const char *format, ...) {
 }\r
 \r
 int vprintf(const char *format, va_list ap) {\r
-       return vfprintf(stdout, format, ap);\r
+       return vfprintf((FILE *)STDOUT_FILENO, format, ap);\r
 }\r
 \r
 int vsprintf(char *buffer, const char *format, va_list ap) {\r
@@ -144,8 +171,21 @@ static inline int emitChar( FILE *file, char **buf, char c, int *left ) {
                putc(c, stdout);\r
                fflush(stdout);\r
 #else\r
-               arc_putchar((int)file, c);\r
+#if 0\r
+#if defined(USE_NEWLIB) && defined(__GNUC__)\r
+               /* We are trying to print with newlib file descriptor.\r
+                * That's wrong since we are using the POSIX file numbers here instead\r
+                * Check stdout */\r
+               assert( file != _impure_ptr->_stdout );\r
+#endif\r
 #endif\r
+               if( (unsigned )file > 10UL ) {\r
+                       arc_putchar((int)(file->_file), c);\r
+               } else {\r
+                       arc_putchar((int)(file), c);\r
+               }\r
+\r
+#endif /* HOST_TEST */\r
        } else {\r
                **buf = c;\r
                (*buf)++;\r
@@ -305,21 +345,23 @@ int print(FILE *file, char **buffer, size_t n, const char *format, va_list ap)
                        }\r
 \r
                        /* Find flags */\r
-                       switch (ch) {\r
-                       case '0':\r
+                       if (ch == '0')\r
+                       {\r
                                flags = FL_ZERO;\r
-                               break;\r
-                       case ' ':\r
+                       }\r
+                       else if (ch == ' ')\r
+                       {\r
                                flags = FL_SPACE;\r
-                               break;\r
-                       case '-':\r
+                       }\r
+                       else if (ch == '-')\r
+                       {\r
                                flags = FL_ALIGN_LEFT;\r
-                               break;\r
-                       default:\r
+                       }\r
+                       else\r
+                       {\r
                                /* Not supported or no flag */\r
                                flags = FL_NONE;\r
                                format--;\r
-                               break;\r
                        }\r
 \r
                        ch = *format++;\r
@@ -333,27 +375,32 @@ int print(FILE *file, char **buffer, size_t n, const char *format, va_list ap)
                        }\r
 \r
                        /* Find type */\r
-                       switch (ch) {\r
-                       case 'c':\r
+                       if (ch =='c')\r
+                       {\r
                                emitChar(file,buffer,(char )va_arg( ap, int ),&left);\r
-                               break;\r
-                       case 'd':\r
+                       }\r
+                       else if (ch == 'd')\r
+                       {\r
                                flags |= FL_TYPE_SIGNED_INT;\r
                                emitInt(file,buffer,va_arg( ap, int ),10,width,flags,&left);\r
-                               break;\r
-                       case 'u':\r
+                       }\r
+                       else if (ch == 'u')\r
+                       {\r
                                flags |= FL_TYPE_UNSIGNED_INT;\r
                                emitInt(file,buffer,va_arg( ap, int ),10,width,flags,&left);\r
-                               break;\r
-                       case 'x':\r
+                       }\r
+                       else if (ch == 'x')\r
+                       {\r
                                flags |= FL_TYPE_UNSIGNED_INT;\r
                                emitInt(file,buffer,va_arg( ap, int ),16,width,flags,&left);\r
-                               break;\r
-                       case 'p':\r
+                       }\r
+                       else if (ch == 'p')\r
+                       {\r
                                flags |= FL_TYPE_POINTER;\r
                                emitInt(file,buffer,va_arg( ap, int ),16,width,flags,&left);\r
-                               break;\r
-                       case 's':\r
+                       }\r
+                       else if (ch == 's')\r
+                       {\r
                                str = (char *)va_arg( ap, int );\r
 \r
                                if( str == NULL ) {\r
@@ -361,12 +408,11 @@ int print(FILE *file, char **buffer, size_t n, const char *format, va_list ap)
                                }\r
 \r
                                emitString(file,buffer,str,width,flags,&left);\r
-                               break;\r
-                       default:\r
+                       }\r
+                       else\r
+                       {\r
                                assert(0); // oops\r
-                               break;\r
                        }\r
-\r
                } else {\r
                        flags = FL_NONE;\r
                        emitChar(file,buffer,ch,&left);\r