Rev 1198 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1198 | Rev 1204 | ||
---|---|---|---|
Line 33... | Line 33... | ||
33 | #include <arch/arg.h> |
33 | #include <arch/arg.h> |
34 | #include <arch/asm.h> |
34 | #include <arch/asm.h> |
35 | 35 | ||
36 | #include <arch.h> |
36 | #include <arch.h> |
37 | 37 | ||
38 | SPINLOCK_INITIALIZE(printflock); /**< printf spinlock */ |
38 | SPINLOCK_INITIALIZE(printflock); /**< printf spinlock */ |
39 | 39 | ||
40 | #define __PRINTF_FLAG_PREFIX 0x00000001 /* show prefixes 0x or 0*/ |
40 | #define __PRINTF_FLAG_PREFIX 0x00000001 /* show prefixes 0x or 0 */ |
41 | #define __PRINTF_FLAG_SIGNED 0x00000002 /* signed / unsigned number */ |
41 | #define __PRINTF_FLAG_SIGNED 0x00000002 /* signed / unsigned number */ |
42 | #define __PRINTF_FLAG_ZEROPADDED 0x00000004 /* print leading zeroes */ |
42 | #define __PRINTF_FLAG_ZEROPADDED 0x00000004 /* print leading zeroes */ |
43 | #define __PRINTF_FLAG_LEFTALIGNED 0x00000010 /* align to left */ |
43 | #define __PRINTF_FLAG_LEFTALIGNED 0x00000010 /* align to left */ |
44 | #define __PRINTF_FLAG_SHOWPLUS 0x00000020 /* always show + sign */ |
44 | #define __PRINTF_FLAG_SHOWPLUS 0x00000020 /* always show + sign */ |
45 | #define __PRINTF_FLAG_SPACESIGN 0x00000040 /* print space instead of plus */ |
45 | #define __PRINTF_FLAG_SPACESIGN 0x00000040 /* print space instead of plus */ |
Line 60... | Line 60... | ||
60 | PrintfQualifierNative, |
60 | PrintfQualifierNative, |
61 | PrintfQualifierPointer |
61 | PrintfQualifierPointer |
62 | } qualifier_t; |
62 | } qualifier_t; |
63 | 63 | ||
64 | static char digits_small[] = "0123456789abcdef"; /* Small hexadecimal characters */ |
64 | static char digits_small[] = "0123456789abcdef"; /* Small hexadecimal characters */ |
65 | static char digits_big[] = "0123456789ABCDEF"; /* Big hexadecimal characters */ |
65 | static char digits_big[] = "0123456789ABCDEF"; /* Big hexadecimal characters */ |
66 | 66 | ||
67 | static inline int isdigit(int c) |
67 | static inline int isdigit(int c) |
68 | { |
68 | { |
69 | return ((c >= '0' )&&( c <= '9')); |
69 | return ((c >= '0' )&&( c <= '9')); |
70 | } |
70 | } |
Line 78... | Line 78... | ||
78 | } |
78 | } |
79 | 79 | ||
80 | return counter; |
80 | return counter; |
81 | } |
81 | } |
82 | 82 | ||
83 | /** Print one string without adding \n at end |
83 | /** Print one string without appending '\n' to the end |
- | 84 | * |
|
84 | * Dont use this function directly - printflock is not locked here |
85 | * Dont use this function directly - printflock is not locked here |
- | 86 | * |
|
85 | * */ |
87 | */ |
86 | static int putstr(const char *str) |
88 | static int putstr(const char *str) |
87 | { |
89 | { |
88 | int count; |
90 | int count; |
89 | if (str == NULL) { |
91 | if (str == NULL) { |
90 | str = "(NULL)"; |
92 | str = "(NULL)"; |
Line 113... | Line 115... | ||
113 | 115 | ||
114 | return count; |
116 | return count; |
115 | } |
117 | } |
116 | 118 | ||
117 | /** Print one formatted character |
119 | /** Print one formatted character |
- | 120 | * |
|
118 | * @param c character to print |
121 | * @param c character to print |
119 | * @param width |
122 | * @param width |
120 | * @param flags |
123 | * @param flags |
121 | * @return number of printed characters or EOF |
124 | * @return number of printed characters or EOF |
122 | */ |
125 | */ |
123 | static int print_char(char c, int width, __u64 flags) |
126 | static int print_char(char c, int width, __u64 flags) |
124 | { |
127 | { |
125 | int counter = 0; |
128 | int counter = 0; |
126 | 129 | ||
127 | if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) { |
130 | if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) { |
128 | while (--width > 0) { /* one space is consumed by character itself hence predecrement */ |
131 | while (--width > 0) { /* one space is consumed by character itself hence the predecrement */ |
129 | /* FIXME: painful slow */ |
132 | /* FIXME: painfully slow */ |
130 | putchar(' '); |
133 | putchar(' '); |
131 | ++counter; |
134 | ++counter; |
132 | } |
135 | } |
133 | } |
136 | } |
134 | 137 | ||
135 | putchar(c); |
138 | putchar(c); |
136 | ++counter; |
139 | ++counter; |
137 | 140 | ||
138 | while (--width > 0) { /* one space is consumed by character itself hence predecrement */ |
141 | while (--width > 0) { /* one space is consumed by character itself hence the predecrement */ |
139 | putchar(' '); |
142 | putchar(' '); |
140 | ++counter; |
143 | ++counter; |
141 | } |
144 | } |
142 | 145 | ||
143 | return counter; |
146 | return counter; |
Line 148... | Line 151... | ||
148 | * @param width |
151 | * @param width |
149 | * @param precision |
152 | * @param precision |
150 | * @param flags |
153 | * @param flags |
151 | * @return number of printed characters or EOF |
154 | * @return number of printed characters or EOF |
152 | */ |
155 | */ |
153 | - | ||
154 | static int print_string(char *s, int width, int precision, __u64 flags) |
156 | static int print_string(char *s, int width, int precision, __u64 flags) |
155 | { |
157 | { |
156 | int counter = 0; |
158 | int counter = 0; |
157 | __native size; |
159 | __native size; |
158 | 160 | ||
Line 273... | Line 275... | ||
273 | precision = width - size; |
275 | precision = width - size; |
274 | } |
276 | } |
275 | } |
277 | } |
276 | 278 | ||
277 | /* print leading spaces */ |
279 | /* print leading spaces */ |
278 | if (size > precision) /* We must print whole number not only a part */ |
280 | if (size > precision) /* We must print the whole number, not only a part */ |
279 | precision = size; |
281 | precision = size; |
280 | 282 | ||
281 | width -= precision; |
283 | width -= precision; |
282 | 284 | ||
283 | if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) { |
285 | if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) { |
Line 344... | Line 346... | ||
344 | return written; |
346 | return written; |
345 | } |
347 | } |
346 | 348 | ||
347 | /** General formatted text print |
349 | /** General formatted text print |
348 | * |
350 | * |
349 | * Print string formatted according the fmt parameter |
351 | * Print string formatted according to the fmt parameter |
350 | * and variant arguments. Each formatting directive |
352 | * and variadic arguments. Each formatting directive |
351 | * must have the following form: |
353 | * must have the following form: |
352 | * % [ flags ] [ width ] [ .precision ] [ type ] conversion |
354 | * % [ flags ] [ width ] [ .precision ] [ type ] conversion |
353 | * |
355 | * |
354 | * FLAGS: |
356 | * FLAGS: |
- | 357 | * # Force to print prefix. |
|
355 | * # Force to print prefix. For conversion %o is prefix 0, for %x and %X are prefixes 0x and 0X and for conversion %b is prefix 0b. |
358 | * For conversion %o the prefix is 0, for %x and %X prefixes are 0x and 0X and for conversion %b the prefix is 0b. |
356 | * - Align to left. |
359 | * - Align to left. |
357 | * + Print positive sign just as negative. |
360 | * + Print positive sign just as negative. |
358 | * (space) If printed number is positive and '+' flag is not set, print space in place of sign. |
361 | * (space) If printed number is positive and '+' flag is not set, print space in place of sign. |
359 | * 0 Print 0 as padding instead of spaces. Zeroes are placed between sign and the rest of number. This flag is ignored if '-' flag is specified. |
362 | * 0 Print 0 as padding instead of spaces. Zeroes are placed between sign and the rest of number. |
- | 363 | * This flag is ignored if '-' flag is specified. |
|
360 | * |
364 | * |
361 | * WIDTH: |
365 | * WIDTH: |
362 | * Specify minimal width of printed argument. If it is bigger, width is ignored. |
366 | * Specify minimal width of printed argument. If it is bigger, width is ignored. |
363 | * If width is specified with a '*' character instead of number, width is taken from parameter list. |
367 | * If width is specified with a '*' character instead of number, width is taken from parameter list. |
364 | * Int parameter expected before parameter for processed conversion specification. |
368 | * Int parameter expected before parameter for processed conversion specification. |
365 | * If this value is negative it is taken its absolute value and the '-' flag is set. |
369 | * If this value is negative its absolute value is taken and the '-' flag is set. |
366 | * |
370 | * |
367 | * PRECISION: |
371 | * PRECISION: |
368 | * Value precision. For numbers it specifies minimum valid numbers. |
372 | * Value precision. For numbers it specifies minimum valid numbers. |
369 | * Smaller numbers are printed with leading zeroes. Bigger numbers are not affected. |
373 | * Smaller numbers are printed with leading zeroes. Bigger numbers are not affected. |
370 | * Strings with more than precision characters are cutted of. |
374 | * Strings with more than precision characters are cut off. |
371 | * Just as width could be '*' used instead a number. |
375 | * Just as with width, an '*' can be used used instead of a number. |
372 | * A int value is then expected in parameters. When both width and precision are specified using '*', |
376 | * An integer value is then expected in parameters. When both width and precision are specified using '*', |
373 | * first parameter is used for width and second one for precision. |
377 | * first parameter is used for width and second one for precision. |
374 | * |
378 | * |
375 | * TYPE: |
379 | * TYPE: |
376 | * hh signed or unsigned char |
380 | * hh signed or unsigned char |
377 | * h signed or usigned short |
381 | * h signed or usigned short |
Line 671... | Line 675... | ||
671 | interrupts_restore(irqpri); |
675 | interrupts_restore(irqpri); |
672 | 676 | ||
673 | va_end(ap); |
677 | va_end(ap); |
674 | return counter; |
678 | return counter; |
675 | } |
679 | } |
676 | - |