]> 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 20efbaacc55a66e3223b80afcd23308091dc848a..be39635ab039acdcbebb8f9952fdf4f5c5818e5f 100644 (file)
  *    snprintf(buf,) ->                      vsnprintf(buf,)\r
  *\r
  * IMPLEMENTATION NOTE:\r
- *  If printing more than the limit, e.g. using vsnprintf() then\r
- *  the emit function will only stop printing, but not interrupted\r
- *  (The code will get more complicated that way)\r
+ *  - If printing more than the limit, e.g. using vsnprintf() then\r
+ *    the emit function will only stop printing, but not interrupted\r
+ *    (The code will get more complicated that way)\r
+ *  - 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
+ *\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 <unistd.h>\r
 #include <stdarg.h>\r
 #include <assert.h>\r
 #include <string.h>\r
-\r
-//#define HOST_TEST    1\r
-\r
-#ifdef HOST_TEST\r
-#define _STDOUT        stdout\r
-#define _STDIN         stdin\r
-#define _STDERR        stderr\r
-#else\r
-#define _STDOUT        (FILE *)STDOUT_FILENO\r
-#define _STDINT        STDIN_FILENO\r
-#define _STDERR        (FILE *)STDERR_FILENO\r
+#if defined(USE_NEWLIB) && defined(__GNUC__)\r
+#include "reent.h"\r
 #endif\r
-\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
@@ -98,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
@@ -107,7 +129,7 @@ int vsprintf(char *buffer, const char *format, va_list ap) {
 \r
 int vfprintf(FILE *file, const char *format, va_list ap) {\r
        int rv;\r
-       /* Just print to _STDOUT */\r
+       /* Just print to stdout */\r
        rv = print(file,NULL,~(size_t)0, format,ap);\r
        return rv;\r
 }\r
@@ -146,11 +168,24 @@ static inline int emitChar( FILE *file, char **buf, char c, int *left ) {
        --(*left);\r
        if( buf == NULL ) {\r
 #if HOST_TEST\r
-               putc(c, _STDOUT);\r
-               fflush(_STDOUT);\r
+               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
@@ -212,7 +247,7 @@ extern void xtoa( unsigned long val, char* str, int base, int negative);
 #define FL_ALIGN_LEFT                  (1<<4)\r
 #define FL_TYPE_SIGNED_INT             (1<<5)\r
 #define FL_TYPE_UNSIGNED_INT   (1<<6)\r
-\r
+#define FL_TYPE_POINTER                        (1<<7)\r
 \r
 static void emitString( FILE *file, char **buffer, char *string, int width, int flags, int *left) {\r
        char pad;\r
@@ -310,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
@@ -338,23 +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 's':\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
+                       }\r
+                       else if (ch == 's')\r
+                       {\r
                                str = (char *)va_arg( ap, int );\r
 \r
                                if( str == NULL ) {\r
@@ -362,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
@@ -381,7 +426,7 @@ int print(FILE *file, char **buffer, size_t n, const char *format, va_list ap)
        return 0; // Wrong.. but for now.\r
 }\r
 \r
-#if defined(HOST_TEST)\r
+#if 0\r
 int main(void) {\r
        char *ptr = NULL;\r
        char buff[30];\r
@@ -410,7 +455,7 @@ int main(void) {
 \r
        printf("decimal:  00c000   = %06x \n", 0xc000);\r
 \r
-       fprintf(_STDOUT, "string: %s = foobar \n", "foobar");\r
+       fprintf(stdout, "string: %s = foobar \n", "foobar");\r
        sprintf(buff, "string: %s = foobar \n", "foobar");\r
        printf("%s",buff);\r
 \r