Changeset e499a30 in mainline
- Timestamp:
- 2006-05-02T11:25:22Z (19 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 6445baf
- Parents:
- 7dd1787
- Files:
-
- 7 added
- 3 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
Makefile
r7dd1787 re499a30 134 134 generic/src/lib/sort.c \ 135 135 generic/src/lib/elf.c \ 136 generic/src/debug/print.c \ 136 generic/src/debug/printf_core.c \ 137 generic/src/debug/printf.c \ 138 generic/src/debug/sprintf.c \ 139 generic/src/debug/snprintf.c \ 140 generic/src/debug/vprintf.c \ 141 generic/src/debug/vsprintf.c \ 142 generic/src/debug/vsnprintf.c \ 137 143 generic/src/debug/symtab.c \ 138 144 generic/src/time/clock.c \ -
generic/include/print.h
r7dd1787 re499a30 32 32 #include <arch/types.h> 33 33 #include <synch/spinlock.h> 34 35 #define INT8 1 36 #define INT16 2 37 #define INT32 4 38 #define INT64 8 39 40 extern int printf(const char *fmt, ...); 34 #include <arch/arg.h> 41 35 42 36 /* We need this address in spinlock to avoid deadlock in deadlock detection */ … … 45 39 #define EOF (-1) 46 40 41 extern int puts(const char * str); 42 43 extern int printf(const char *fmt, ...); 44 extern int sprintf(char *str, const char *fmt, ...); 45 extern int snprintf(char *str, size_t size, const char *fmt, ...); 46 47 extern int vprintf(const char *fmt, va_list ap); 48 extern int vsprintf(char *str, const char *fmt, va_list ap); 49 extern int vsnprintf(char *str, size_t size, const char *fmt, va_list ap); 50 47 51 #endif -
generic/src/debug/printf_core.c
r7dd1787 re499a30 33 33 */ 34 34 35 #include <printf/printf_core.h> 35 36 #include <putchar.h> 36 37 #include <print.h> … … 43 44 SPINLOCK_INITIALIZE(printflock); /**< printf spinlock */ 44 45 45 #define __PRINTF_FLAG_PREFIX 0x00000001 /* show prefixes 0x or 0*/46 #define __PRINTF_FLAG_SIGNED 0x00000002 /* signed / unsigned number */47 #define __PRINTF_FLAG_ZEROPADDED 0x00000004 /* print leading zeroes */48 #define __PRINTF_FLAG_LEFTALIGNED 0x00000010 /* align to left */49 #define __PRINTF_FLAG_SHOWPLUS 0x00000020 /* always show + sign */50 #define __PRINTF_FLAG_SPACESIGN 0x00000040 /* print space instead of plus */51 #define __PRINTF_FLAG_BIGCHARS 0x00000080 /* show big characters */52 #define __PRINTF_FLAG_NEGATIVE 0x00000100 /* number has - sign */53 54 #define PRINT_NUMBER_BUFFER_SIZE (64+5) /* Buffer big enought for 64 bit number46 #define __PRINTF_FLAG_PREFIX 0x00000001 /**< show prefixes 0x or 0*/ 47 #define __PRINTF_FLAG_SIGNED 0x00000002 /**< signed / unsigned number */ 48 #define __PRINTF_FLAG_ZEROPADDED 0x00000004 /**< print leading zeroes */ 49 #define __PRINTF_FLAG_LEFTALIGNED 0x00000010 /**< align to left */ 50 #define __PRINTF_FLAG_SHOWPLUS 0x00000020 /**< always show + sign */ 51 #define __PRINTF_FLAG_SPACESIGN 0x00000040 /**< print space instead of plus */ 52 #define __PRINTF_FLAG_BIGCHARS 0x00000080 /**< show big characters */ 53 #define __PRINTF_FLAG_NEGATIVE 0x00000100 /**< number has - sign */ 54 55 #define PRINT_NUMBER_BUFFER_SIZE (64+5) /**< Buffer big enought for 64 bit number 55 56 * printed in base 2, sign, prefix and 56 57 * 0 to terminate string.. (last one is only for better testing 57 * end of buffer by zero-filling subroutine) 58 */ 58 * end of buffer by zero-filling subroutine)*/ 59 60 /** Enumeration of possible arguments types. 61 */ 59 62 typedef enum { 60 63 PrintfQualifierByte = 0, … … 67 70 } qualifier_t; 68 71 69 static char digits_small[] = "0123456789abcdef"; /* Small hexadecimal characters */ 70 static char digits_big[] = "0123456789ABCDEF"; /* Big hexadecimal characters */ 71 72 static char digits_small[] = "0123456789abcdef"; /**< Small hexadecimal characters */ 73 static char digits_big[] = "0123456789ABCDEF"; /**< Big hexadecimal characters */ 74 75 /** Checks c for a digit. 76 * @param c One character. 77 * @return nonzero if c is from interval '0 to '9'. 78 */ 72 79 static inline int isdigit(int c) 73 80 { … … 75 82 } 76 83 84 /** Compute length of given zero terminated string. 85 * @param str Pointer to valid string. 86 * @return string length without trailing zero. 87 */ 77 88 static __native strlen(const char *str) 78 89 { … … 86 97 } 87 98 88 /** Print one string without appending newline to the end. 89 * 90 * Do not use this function directly - printflock is not locked here. 91 * 92 */ 93 static int putstr(const char *str) 94 { 95 int count; 99 /** Print count chars from buffer without adding newline 100 * @param buf Buffer with size at least count bytes - NULL pointer NOT allowed! 101 * @param count 102 * @param ps output method and its data 103 * @return 0 on success, EOF on fail 104 */ 105 static int printf_putnchars(const char * buf, size_t count, struct printf_spec *ps) 106 { 107 if (ps->write((void *)buf, count, ps->data) == count) { 108 return 0; 109 } 110 111 return EOF; 112 } 113 114 /** Print string without added newline 115 * @param str string to print 116 * @param ps write function specification and support data 117 * @return 0 on success or EOF on fail 118 */ 119 static int printf_putstr(const char * str, struct printf_spec *ps) 120 { 121 size_t count; 122 96 123 if (str == NULL) { 97 str = "(NULL)"; 98 } 99 100 for (count = 0; str[count] != 0; count++) { 101 putchar(str[count]); 102 } 103 return count; 104 } 105 106 /** Print count characters from buffer to output. 107 * 108 * @param buffer Address of the buffer with charaters to be printed. 109 * @param count Number of characters to be printed. 110 * 111 * @return Number of characters printed. 112 */ 113 static int putnchars(const char *buffer, __native count) 114 { 115 int i; 116 if (buffer == NULL) { 117 buffer = "(NULL)"; 118 count = 6; 119 } 120 121 for (i = 0; i < count; i++) { 122 putchar(buffer[i]); 123 } 124 125 return count; 124 return printf_putnchars("(NULL)", 6, ps); 125 } 126 127 count = strlen(str); 128 129 if (ps->write((void *) str, count, ps->data) == count) { 130 return 0; 131 } 132 133 return EOF; 134 } 135 136 /** Print one character to output 137 * @param c one character 138 * @param ps output method 139 * @return printed character or EOF 140 */ 141 static int printf_putchar(int c, struct printf_spec *ps) 142 { 143 unsigned char ch = c; 144 145 if (ps->write((void *) &ch, 1, ps->data) == 1) { 146 return c; 147 } 148 149 return EOF; 126 150 } 127 151 128 152 /** Print one formatted character 129 * 130 * @param c Character to print. 153 * @param c character to print 131 154 * @param width 132 155 * @param flags 133 * @return Number of printed characters or EOF.134 */ 135 static int print_char(char c, int width, __u64 flags )156 * @return number of printed characters or EOF 157 */ 158 static int print_char(char c, int width, __u64 flags, struct printf_spec *ps) 136 159 { 137 160 int counter = 0; 138 161 139 162 if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) { 140 while (--width > 0) { /* one space is consumed by character itself hence thepredecrement */141 /* FIXME: painful lyslow */142 p utchar(' ');163 while (--width > 0) { /* one space is consumed by character itself hence predecrement */ 164 /* FIXME: painful slow */ 165 printf_putchar(' ', ps); 143 166 ++counter; 144 167 } 145 168 } 146 169 147 putchar(c); 148 ++counter; 149 150 while (--width > 0) { /* one space is consumed by character itself hence the predecrement */ 151 putchar(' '); 170 if (printf_putchar(c, ps) == EOF) { 171 return EOF; 172 } 173 174 while (--width > 0) { /* one space is consumed by character itself hence predecrement */ 175 printf_putchar(' ', ps); 152 176 ++counter; 153 177 } 154 178 155 return counter;179 return ++counter; 156 180 } 157 181 … … 163 187 * @return number of printed characters or EOF 164 188 */ 165 static int print_string(char *s, int width, int precision, __u64 flags) 189 190 static int print_string(char *s, int width, int precision, __u64 flags, struct printf_spec *ps) 166 191 { 167 192 int counter = 0; 168 __nativesize;193 size_t size; 169 194 170 195 if (s == NULL) { 171 return p utstr("(NULL)");196 return printf_putstr("(NULL)", ps); 172 197 } 173 198 … … 183 208 if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) { 184 209 while (width-- > 0) { 185 p utchar(' ');210 printf_putchar(' ', ps); 186 211 counter++; 187 212 } … … 190 215 while (precision > size) { 191 216 precision--; 192 p utchar(' ');217 printf_putchar(' ', ps); 193 218 ++counter; 194 219 } 195 220 196 if (p utnchars(s, precision) == EOF) {221 if (printf_putnchars(s, precision, ps) == EOF) { 197 222 return EOF; 198 223 } … … 201 226 202 227 while (width-- > 0) { 203 p utchar(' ');228 printf_putchar(' ', ps); 204 229 ++counter; 205 230 } … … 220 245 * be in range 2 .. 16). 221 246 * @param flags output modifiers 222 * @return number of written characters or EOF. 223 */ 224 static int print_number(__u64 num, int width, int precision, int base , __u64 flags) 247 * @return number of written characters or EOF 248 * 249 */ 250 static int print_number(__u64 num, int width, int precision, int base , __u64 flags, struct printf_spec *ps) 225 251 { 226 252 char *digits = digits_small; 227 253 char d[PRINT_NUMBER_BUFFER_SIZE]; /* this is good enough even for base == 2, prefix and sign */ 228 254 char *ptr = &d[PRINT_NUMBER_BUFFER_SIZE - 1]; 229 int size = 0; 255 int size = 0; /* size of number with all prefixes and signs */ 230 256 int number_size; /* size of plain number */ 231 257 int written = 0; … … 246 272 } while (num /= base); 247 273 } 248 274 249 275 number_size = size; 250 276 251 277 /* Collect sum of all prefixes/signs/... to calculate padding and leading zeroes */ 252 278 if (flags & __PRINTF_FLAG_PREFIX) { … … 297 323 if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) { 298 324 while (width-- > 0) { 299 p utchar(' ');325 printf_putchar(' ', ps); 300 326 written++; 301 327 } … … 304 330 /* print sign */ 305 331 if (sgn) { 306 p utchar(sgn);332 printf_putchar(sgn, ps); 307 333 written++; 308 334 } … … 313 339 switch(base) { 314 340 case 2: /* Binary formating is not standard, but usefull */ 315 p utchar('0');341 printf_putchar('0', ps); 316 342 if (flags & __PRINTF_FLAG_BIGCHARS) { 317 p utchar('B');343 printf_putchar('B', ps); 318 344 } else { 319 p utchar('b');345 printf_putchar('b', ps); 320 346 } 321 347 written += 2; 322 348 break; 323 349 case 8: 324 p utchar('o');350 printf_putchar('o', ps); 325 351 written++; 326 352 break; 327 353 case 16: 328 p utchar('0');354 printf_putchar('0', ps); 329 355 if (flags & __PRINTF_FLAG_BIGCHARS) { 330 p utchar('X');356 printf_putchar('X', ps); 331 357 } else { 332 p utchar('x');358 printf_putchar('x', ps); 333 359 } 334 360 written += 2; … … 340 366 precision -= number_size; 341 367 while (precision-- > 0) { 342 p utchar('0');368 printf_putchar('0', ps); 343 369 written++; 344 370 } … … 347 373 /* print number itself */ 348 374 349 written += p utstr(++ptr);375 written += printf_putstr(++ptr, ps); 350 376 351 377 /* print ending spaces */ 352 378 353 379 while (width-- > 0) { 354 p utchar(' ');380 printf_putchar(' ', ps); 355 381 written++; 356 382 } … … 358 384 return written; 359 385 } 386 360 387 361 388 /** Print formatted string. … … 368 395 * 369 396 * FLAGS:@n 370 * "#"Force to print prefix.397 * - "#" Force to print prefix. 371 398 * For conversion \%o the prefix is 0, for %x and \%X prefixes are 0x and 0X 372 399 * and for conversion \%b the prefix is 0b. 373 400 * 374 * "-" Align to left.375 * 376 * "+" Print positive sign just as negative.377 * 378 * " " If the printed number is positive and "+" flag is not set, print space in401 * - "-" Align to left. 402 * 403 * - "+" Print positive sign just as negative. 404 * 405 * - " " If the printed number is positive and "+" flag is not set, print space in 379 406 * place of sign. 380 407 * 381 * "0" Print 0 as padding instead of spaces. Zeroes are placed between sign and the408 * - "0" Print 0 as padding instead of spaces. Zeroes are placed between sign and the 382 409 * rest of the number. This flag is ignored if "-" flag is specified. 383 410 * 384 411 * WIDTH:@n 385 * Specify minimal width of printed argument. If it is bigger, width is ignored.412 * - Specify minimal width of printed argument. If it is bigger, width is ignored. 386 413 * If width is specified with a "*" character instead of number, width is taken from 387 414 * parameter list. And integer parameter is expected before parameter for processed … … 390 417 * 391 418 * PRECISION:@n 392 * Value precision. For numbers it specifies minimum valid numbers.419 * - Value precision. For numbers it specifies minimum valid numbers. 393 420 * Smaller numbers are printed with leading zeroes. Bigger numbers are not affected. 394 421 * Strings with more than precision characters are cut off. … … 399 426 * 400 427 * TYPE:@n 401 * "hh" Signed or unsigned char.@n402 * "h" Signed or usigned short.@n403 * "" Signed or usigned int (default value).@n404 * "l" Signed or usigned long int.@n405 * "ll" Signed or usigned long long int.@n406 * "z" __native (non-standard extension).@n428 * - "hh" Signed or unsigned char.@n 429 * - "h" Signed or usigned short.@n 430 * - "" Signed or usigned int (default value).@n 431 * - "l" Signed or usigned long int.@n 432 * - "ll" Signed or usigned long long int.@n 433 * - "z" __native (non-standard extension).@n 407 434 * 408 435 * 409 436 * CONVERSION:@n 410 * % Print percentile character itself.411 * 412 * c Print single character.413 * 414 * s Print zero terminated string. If a NULL value is passed as value, "(NULL)" is printed instead.437 * - % Print percentile character itself. 438 * 439 * - c Print single character. 440 * 441 * - s Print zero terminated string. If a NULL value is passed as value, "(NULL)" is printed instead. 415 442 * 416 * P, p Print value of a pointer. Void * value is expected and it is printed in hexadecimal notation with prefix443 * - P, p Print value of a pointer. Void * value is expected and it is printed in hexadecimal notation with prefix 417 444 * (as with \%#X or \%#x for 32bit or \%#X / \%#x for 64bit long pointers). 418 445 * 419 * b Print value as unsigned binary number. Prefix is not printed by default. (Nonstandard extension.)446 * - b Print value as unsigned binary number. Prefix is not printed by default. (Nonstandard extension.) 420 447 * 421 * o Print value as unsigned octal number. Prefix is not printed by default.422 * 423 * d,i Print signed decimal number. There is no difference between d and i conversion.424 * 425 * u Print unsigned decimal number.426 * 427 * X, x Print hexadecimal number with upper- or lower-case. Prefix is not printed by default.448 * - o Print value as unsigned octal number. Prefix is not printed by default. 449 * 450 * - d,i Print signed decimal number. There is no difference between d and i conversion. 451 * 452 * - u Print unsigned decimal number. 453 * 454 * - X, x Print hexadecimal number with upper- or lower-case. Prefix is not printed by default. 428 455 * 429 456 * All other characters from fmt except the formatting directives … … 433 460 * @return Number of printed characters or negative value on failure. 434 461 */ 435 int printf (const char *fmt, ...)462 int printf_core(const char *fmt, struct printf_spec *ps, va_list ap) 436 463 { 437 464 int irqpri; … … 440 467 int counter; /* counter of printed characters */ 441 468 int retval; /* used to store return values from called functions */ 442 va_list ap;443 469 char c; 444 470 qualifier_t qualifier; /* type of argument */ 445 471 int base; /* base in which will be parameter (numbers only) printed */ 446 472 __u64 number; /* argument value */ 447 __nativesize; /* byte size of integer parameter */473 size_t size; /* byte size of integer parameter */ 448 474 int width, precision; 449 475 __u64 flags; … … 451 477 counter = 0; 452 478 453 va_start(ap, fmt);454 455 479 irqpri = interrupts_disable(); 456 480 spinlock_lock(&printflock); 457 481 458 459 482 while ((c = fmt[i])) { 460 483 /* control character */ … … 462 485 /* print common characters if any processed */ 463 486 if (i > j) { 464 if ((retval = p utnchars(&fmt[j], (__native)(i - j))) == EOF) { /* error */487 if ((retval = printf_putnchars(&fmt[j], (size_t)(i - j), ps)) == EOF) { /* error */ 465 488 counter = -counter; 466 489 goto out; … … 559 582 */ 560 583 case 's': 561 if ((retval = print_string(va_arg(ap, char*), width, precision, flags )) == EOF) {584 if ((retval = print_string(va_arg(ap, char*), width, precision, flags, ps)) == EOF) { 562 585 counter = -counter; 563 586 goto out; … … 569 592 case 'c': 570 593 c = va_arg(ap, unsigned int); 571 if ((retval = print_char(c, width, flags 594 if ((retval = print_char(c, width, flags, ps)) == EOF) { 572 595 counter = -counter; 573 596 goto out; … … 654 677 counter = -counter; 655 678 goto out; 656 657 679 } 658 680 … … 671 693 } 672 694 673 if ((retval = print_number(number, width, precision, base, flags )) == EOF ) {695 if ((retval = print_number(number, width, precision, base, flags, ps)) == EOF ) { 674 696 counter = -counter; 675 697 goto out; … … 685 707 686 708 if (i > j) { 687 if ((retval = p utnchars(&fmt[j], (__native)(i - j))) == EOF) { /* error */709 if ((retval = printf_putnchars(&fmt[j], (__native)(i - j), ps)) == EOF) { /* error */ 688 710 counter = -counter; 689 711 goto out; 712 690 713 } 691 714 counter += retval; 692 715 } 716 693 717 out: 694 718 spinlock_unlock(&printflock); 695 719 interrupts_restore(irqpri); 696 720 697 va_end(ap);698 721 return counter; 699 722 } 723 -
test/print/print1/test.c
r7dd1787 re499a30 29 29 #include <test.h> 30 30 31 #define BUFFER_SIZE 32 32 31 33 void test(void) 32 34 { 33 35 __native nat = 0x12345678u; 36 37 unsigned char buffer[BUFFER_SIZE]; 38 34 39 printf(" Printf test \n"); 35 40 … … 47 52 48 53 printf(" Print to NULL '%s'\n",NULL); 54 55 printf("Print short text to %d char long buffer via snprintf.\n", BUFFER_SIZE); 56 snprintf(buffer, BUFFER_SIZE, "Short %s", "text"); 57 printf("Result is: '%s'\n", buffer); 58 59 printf("Print long text to %d char long buffer via snprintf.\n", BUFFER_SIZE); 60 snprintf(buffer, BUFFER_SIZE, "Very long %s. This text`s length is more than %d. We are interested in the result.", "text" , BUFFER_SIZE); 61 printf("Result is: '%s'\n", buffer); 62 49 63 return; 50 64 }
Note:
See TracChangeset
for help on using the changeset viewer.