source: rtems/cpukit/libcsupport/src/vprintk.c @ 2feeb26

4.104.11
Last change on this file since 2feeb26 was 2feeb26, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on Nov 30, 2009 at 12:47:44 PM

Fixed output of unsigned integers.

Changed type of boolean variables to bool. Use unsigned integer type
for radix and width parameters.

  • Property mode set to 100644
File size: 3.7 KB
Line 
1/*
2 * (C) Copyright 1997 -
3 * - NavIST Group - Real-Time Distributed Systems and Industrial Automation
4 *
5 * http://pandora.ist.utl.pt
6 *
7 * Instituto Superior Tecnico * Lisboa * PORTUGAL
8 *
9 * Disclaimer:
10 *
11 * This file is provided "AS IS" without warranty of any kind, either
12 * expressed or implied.
13 *
14 * This code is based on code by: Jose Rufino - IST
15 *
16 *  $Id$
17 */
18
19#if HAVE_CONFIG_H
20#include "config.h"
21#endif
22
23#include <stdarg.h>
24#include <stdio.h>
25#include <stdbool.h>
26#include <rtems/bspIo.h>
27
28static void printNum(
29  long num,
30  unsigned base,
31  bool sign,
32  unsigned maxwidth,
33  char lead
34);
35
36/*
37 *  vprintk
38 *
39 *  A simplified version of printf intended for use when the
40 *  console is not yet initialized or in ISR's.
41 *
42 * Arguments:
43 *    as in printf: fmt - format string, ... - unnamed arguments.
44 */
45void vprintk(
46  const char *fmt,
47  va_list     ap
48)
49{
50  for (; *fmt != '\0'; fmt++) {
51    unsigned base = 0;
52    unsigned width = 0;
53    bool lflag = false;
54    bool minus = false;
55    bool sign = false;
56    char lead = ' ';
57    char c;
58
59    if (*fmt != '%') {
60      BSP_output_char(*fmt);
61      continue;
62    }
63    fmt++;
64    if (*fmt == '0' ) {
65      lead = '0';
66      fmt++;
67    }
68    if (*fmt == '-' ) {
69      minus = true;
70      fmt++;
71    }
72    while (*fmt >= '0' && *fmt <= '9' ) {
73      width *= 10;
74      width += ((unsigned) *fmt - '0');
75      fmt++;
76    }
77
78    if ((c = *fmt) == 'l') {
79      lflag = true;
80      c = *++fmt;
81    }
82    if ( c == 'c' ) {
83      char chr = va_arg(ap, char);
84      BSP_output_char(chr);
85      continue;
86    }
87    if ( c == 's' ) {
88      unsigned i, len;
89      char *s, *str;
90
91      str = va_arg(ap, char *);
92
93      if ( str == NULL ) {
94        str = "";
95      }
96
97      /* calculate length of string */
98      for ( len=0, s=str ; *s ; len++, s++ )
99        ;
100
101      /* leading spaces */
102      if ( !minus )
103        for ( i=len ; i<width ; i++ )
104          BSP_output_char(' ');
105
106      /* no width option */
107      if (width == 0) {
108          width = len;
109      }
110
111      /* output the string */
112      for ( i=0 ; i<width && *str ; str++ )
113        BSP_output_char(*str);
114
115      /* trailing spaces */
116      if ( minus )
117        for ( i=len ; i<width ; i++ )
118          BSP_output_char(' ');
119
120      continue;
121    }
122
123    /* must be a numeric format or something unsupported */
124    if ( c == 'o' || c == 'O' ) {
125      base = 8; sign = false;
126    } else if ( c == 'i' || c == 'I' ||
127                c == 'd' || c == 'D' ) {
128      base = 10; sign = true;
129    } else if ( c == 'u' || c == 'U' ) {
130      base = 10; sign = false;
131    } else if ( c == 'x' || c == 'X' ) {
132      base = 16; sign = false;
133    } else if ( c == 'p' ) {
134      base = 16; sign = false; lflag = true;
135    } else {
136      BSP_output_char(c);
137      continue;
138    }
139
140    printNum(
141      lflag ? va_arg(ap, long) : (long) va_arg(ap, int),
142      base,
143      sign,
144      width,
145      lead
146    );
147  }
148}
149
150/*
151 * printNum - print number in a given base.
152 * Arguments
153 *    num - number to print
154 *    base - base used to print the number.
155 */
156static void printNum(
157  long num,
158  unsigned base,
159  bool sign,
160  unsigned maxwidth,
161  char lead
162)
163{
164  unsigned long unsigned_num;
165  unsigned long n;
166  unsigned count;
167  char toPrint[20];
168
169  if ( sign && (num <  0) ) {
170    BSP_output_char('-');
171    unsigned_num = (unsigned long) -num;
172    if (maxwidth) maxwidth--;
173  } else {
174    unsigned_num = (unsigned long) num;
175  }
176
177  count = 0;
178  while ((n = unsigned_num / base) > 0) {
179    toPrint[count++] = (char) (unsigned_num - (n * base));
180    unsigned_num = n;
181  }
182  toPrint[count++] = (char) unsigned_num;
183
184  for (n=maxwidth ; n > count; n-- )
185    BSP_output_char(lead);
186
187  for (n = 0; n < count; n++) {
188    BSP_output_char("0123456789ABCDEF"[(int)(toPrint[count-(n+1)])]);
189  }
190}
Note: See TracBrowser for help on using the repository browser.