drivers/serial/printk.c File Reference

Go to the source code of this file.

Functions

static int skip_atoi (const char **s)
unsigned short int strnlen (const char *s, unsigned short int count)
static char * number (char *buf, char *end, long long num, int base, int size, int precision, int type)
int vsnprintf (char *buf, size_t size, const char *fmt, va_list args)
int printk (const char *fmt,...)


Function Documentation

static char* number ( char *  buf,
char *  end,
long long  num,
int  base,
int  size,
int  precision,
int  type 
) [static]

Definition at line 42 of file printk.c.

00043 {
00044     char c,sign,tmp[66];
00045     const char *digits;
00046     const char small_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
00047     const char large_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
00048     int i;
00049 
00050     digits = (type & LARGE) ? large_digits : small_digits;
00051     if (type & LEFT)
00052         type &= ~ZEROPAD;
00053     if (base < 2 || base > 36)
00054         return 0;
00055     c = (type & ZEROPAD) ? '0' : ' ';
00056     sign = 0;
00057     if (type & SIGN) {
00058         if (num < 0) {
00059             sign = '-';
00060             num = -num;
00061             size--;
00062         } else if (type & PLUS) {
00063             sign = '+';
00064             size--;
00065         } else if (type & SPACE) {
00066             sign = ' ';
00067             size--;
00068         }
00069     }
00070     if (type & SPECIAL) {
00071         if (base == 16)
00072             size -= 2;
00073         else if (base == 8)
00074             size--;
00075     }
00076     i = 0;
00077     if (num == 0)
00078         tmp[i++]='0';
00079     else while (num != 0)
00080         tmp[i++] = digits[do_div(num,base)];
00081     if (i > precision)
00082         precision = i;
00083     size -= precision;
00084     if (!(type&(ZEROPAD+LEFT))) {
00085         while(size-->0) {
00086             if (buf <= end)
00087                 *buf = ' ';
00088             ++buf;
00089         }
00090     }
00091     if (sign) {
00092         if (buf <= end)
00093             *buf = sign;
00094         ++buf;
00095     }
00096     if (type & SPECIAL) {
00097         if (base==8) {
00098             if (buf <= end)
00099                 *buf = '0';
00100             ++buf;
00101         } else if (base==16) {
00102             if (buf <= end)
00103                 *buf = '0';
00104             ++buf;
00105             if (buf <= end)
00106                 *buf = digits[33];
00107             ++buf;
00108         }
00109     }
00110     if (!(type & LEFT)) {
00111         while (size-- > 0) {
00112             if (buf <= end)
00113                 *buf = c;
00114             ++buf;
00115         }
00116     }
00117     while (i < precision--) {
00118         if (buf <= end)
00119             *buf = '0';
00120         ++buf;
00121     }
00122     while (i-- > 0) {
00123         if (buf <= end)
00124             *buf = tmp[i];
00125         ++buf;
00126     }
00127     while (size-- > 0) {
00128         if (buf <= end)
00129             *buf = ' ';
00130         ++buf;
00131     }
00132     return buf;
00133 }

int printk ( const char *  fmt,
  ... 
)

Definition at line 361 of file printk.c.

00362 {
00363     va_list args;
00364     int printed_len;
00365     //char *p;
00366     static char printk_buf[1024];
00367 
00368     /* Emit the output into the temporary buffer */
00369     va_start(args, fmt);
00370     printed_len = vsnprintf(printk_buf, sizeof(printk_buf), fmt, args);
00371     va_end(args);
00372 
00373     /*
00374      * Copy the output into log_buf.  If the caller didn't provide
00375      * appropriate log level tags, we insert them here
00376      */
00377 
00378         F_Uart0StringTx(printk_buf);
00379         //F_Uart0StringTx("1234.");
00380         /*for (p = printk_buf; *p; p++) {
00381         if (*p == '\n')
00382             putch('\r');
00383         putch(*p);
00384     }*/
00385 
00386     return printed_len;
00387 }

static int skip_atoi ( const char **  s  )  [static]

Definition at line 15 of file printk.c.

00016 {
00017     int i=0;
00018 
00019     while (is_digit(**s))
00020         i = i*10 + *((*s)++) - '0';
00021     return i;
00022 }

unsigned short int strnlen ( const char *  s,
unsigned short int  count 
)

Definition at line 24 of file printk.c.

00025 {
00026     const char *sc;
00027 
00028     for (sc = s; count-- && *sc != '\0'; ++sc)
00029         /* nothing */;
00030     return sc - s; 
00031 }

int vsnprintf ( char *  buf,
size_t  size,
const char *  fmt,
va_list  args 
)

Definition at line 135 of file printk.c.

00136 {
00137     int len;
00138     unsigned long long num;
00139     int i, base;
00140     char *str, *end, c;
00141     const char *s;
00142 
00143     int flags;      /* flags to number() */
00144 
00145     int field_width;    /* width of output field */
00146     int precision;      /* min. # of digits for integers; max
00147                    number of chars for from string */
00148     int qualifier;      /* 'h', 'l', or 'L' for integer fields */
00149                 /* 'z' support added 23/7/1999 S.H.    */
00150                 /* 'z' changed to 'Z' --davidm 1/25/99 */
00151 
00152     str = buf;
00153     end = buf + size - 1;
00154 
00155     if (end < buf - 1) {
00156         end = ((void *) -1);
00157         size = end - buf + 1;
00158     }
00159 
00160     for (; *fmt ; ++fmt) {
00161         if (*fmt != '%') {
00162             if (str <= end)
00163                 *str = *fmt;
00164             ++str;
00165             continue;
00166         }
00167 
00168         /* process flags */
00169         flags = 0;
00170         repeat:
00171             ++fmt;      /* this also skips first '%' */
00172             switch (*fmt) {
00173                 case '-': flags |= LEFT; goto repeat;
00174                 case '+': flags |= PLUS; goto repeat;
00175                 case ' ': flags |= SPACE; goto repeat;
00176                 case '#': flags |= SPECIAL; goto repeat;
00177                 case '0': flags |= ZEROPAD; goto repeat;
00178             }
00179 
00180         /* get field width */
00181         field_width = -1;
00182         if (is_digit(*fmt))
00183             field_width = skip_atoi(&fmt);
00184         else if (*fmt == '*') {
00185             ++fmt;
00186             /* it's the next argument */
00187             field_width = va_arg(args, int);
00188             if (field_width < 0) {
00189                 field_width = -field_width;
00190                 flags |= LEFT;
00191             }
00192         }
00193 
00194         /* get the precision */
00195         precision = -1;
00196         if (*fmt == '.') {
00197             ++fmt;  
00198             if (is_digit(*fmt))
00199                 precision = skip_atoi(&fmt);
00200             else if (*fmt == '*') {
00201                 ++fmt;
00202                 /* it's the next argument */
00203                 precision = va_arg(args, int);
00204             }
00205             if (precision < 0)
00206                 precision = 0;
00207         }
00208 
00209         /* get the conversion qualifier */
00210         qualifier = -1;
00211         if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') {
00212             qualifier = *fmt;
00213             ++fmt;
00214             if (qualifier == 'l' && *fmt == 'l') {
00215                 qualifier = 'L';
00216                 ++fmt;
00217             }
00218         }
00219 
00220         /* default base */
00221         base = 10;
00222 
00223         switch (*fmt) {
00224             case 'c':
00225                 if (!(flags & LEFT)) {
00226                     while (--field_width > 0) {
00227                         if (str <= end)
00228                             *str = ' ';
00229                         ++str;
00230                     }
00231                 }
00232                 c = (unsigned char) va_arg(args, int);
00233                 if (str <= end)
00234                     *str = c;
00235                 ++str;
00236                 while (--field_width > 0) {
00237                     if (str <= end)
00238                         *str = ' ';
00239                     ++str;
00240                 }
00241                 continue;
00242 
00243             case 's':
00244                 s = va_arg(args, char *);
00245                 if (!s)
00246                     s = "<NULL>";
00247 
00248                 len = strnlen(s, precision);
00249 
00250                 if (!(flags & LEFT)) {
00251                     while (len < field_width--) {
00252                         if (str <= end)
00253                             *str = ' ';
00254                         ++str;
00255                     }
00256                 }
00257                 for (i = 0; i < len; ++i) {
00258                     if (str <= end)
00259                         *str = *s;
00260                     ++str; ++s;
00261                 }
00262                 while (len < field_width--) {
00263                     if (str <= end)
00264                         *str = ' ';
00265                     ++str;
00266                 }
00267                 continue;
00268 
00269             case 'p':
00270                 if (field_width == -1) {
00271                     field_width = 2*sizeof(void *);
00272                     flags |= ZEROPAD;
00273                 }
00274                 str = number(str, end,
00275                         (unsigned long) va_arg(args, void *),
00276                         16, field_width, precision, flags);
00277                 continue;
00278 
00279 
00280             case 'n':
00281                 /* FIXME:
00282                 * What does C99 say about the overflow case here? */
00283                 if (qualifier == 'l') {
00284                     long * ip = va_arg(args, long *);
00285                     *ip = (str - buf);
00286                 } else if (qualifier == 'Z') {
00287                     size_t * ip = va_arg(args, size_t *);
00288                     *ip = (str - buf);
00289                 } else {
00290                     int * ip = va_arg(args, int *);
00291                     *ip = (str - buf);
00292                 }
00293                 continue;
00294 
00295             case '%':
00296                 if (str <= end)
00297                     *str = '%';
00298                 ++str;
00299                 continue;
00300 
00301                 /* integer number formats - set up the flags and "break" */
00302             case 'o':
00303                 base = 8;
00304                 break;
00305 
00306             case 'X':
00307                 flags |= LARGE;
00308             case 'x':
00309                 base = 16;
00310                 break;
00311 
00312             case 'd':
00313             case 'i':
00314                 flags |= SIGN;
00315             case 'u':
00316                 break;
00317 
00318             default:
00319                 if (str <= end)
00320                     *str = '%';
00321                 ++str;
00322                 if (*fmt) {
00323                     if (str <= end)
00324                         *str = *fmt;
00325                     ++str;
00326                 } else {
00327                     --fmt;
00328                 }
00329                 continue;
00330         }
00331         if (qualifier == 'L')
00332             num = va_arg(args, long long);
00333         else if (qualifier == 'l') {
00334             num = va_arg(args, unsigned long);
00335             if (flags & SIGN)
00336                 num = (signed long) num;
00337         } else if (qualifier == 'Z') {
00338             num = va_arg(args, size_t);
00339         } else if (qualifier == 'h') {
00340             num = (unsigned short) va_arg(args, int);
00341             if (flags & SIGN)
00342                 num = (signed short) num;
00343         } else {
00344             num = va_arg(args, unsigned int);
00345             if (flags & SIGN)
00346                 num = (signed int) num;
00347         }
00348         str = number(str, end, num, base,
00349                 field_width, precision, flags);
00350     }
00351     if (str <= end)
00352         *str = '\0';
00353     else if (size > 0)
00354         /* don't write out a null byte if the buf size is zero */
00355         *end = '\0';
00356     /* the trailing null byte doesn't count towards the total
00357     * ++str;
00358     */
00359     return str-buf;
00360 }


Generated on Tue Sep 2 08:45:41 2008 for A Simple operation System using S3C2410 by  doxygen 1.5.6