Rev 1234 | Rev 1444 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 1234 | Rev 1272 | ||
|---|---|---|---|
| Line 25... | Line 25... | ||
| 25 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| 27 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 28 | */ |
28 | */ |
| 29 | 29 | ||
| - | 30 | /** |
|
| - | 31 | * @file print.c |
|
| - | 32 | * @brief Printing functions. |
|
| - | 33 | */ |
|
| - | 34 | ||
| 30 | #include <unistd.h> |
35 | #include <unistd.h> |
| 31 | #include <stdio.h> |
36 | #include <stdio.h> |
| 32 | #include <io/printf_core.h> |
37 | #include <io/printf_core.h> |
| 33 | #include <ctype.h> |
38 | #include <ctype.h> |
| 34 | #include <string.h> |
39 | #include <string.h> |
| 35 | 40 | ||
| 36 | #define __PRINTF_FLAG_PREFIX 0x00000001 /* show prefixes 0x or 0*/ |
41 | #define __PRINTF_FLAG_PREFIX 0x00000001 /**< show prefixes 0x or 0*/ |
| 37 | #define __PRINTF_FLAG_SIGNED 0x00000002 /* signed / unsigned number */ |
42 | #define __PRINTF_FLAG_SIGNED 0x00000002 /**< signed / unsigned number */ |
| 38 | #define __PRINTF_FLAG_ZEROPADDED 0x00000004 /* print leading zeroes */ |
43 | #define __PRINTF_FLAG_ZEROPADDED 0x00000004 /**< print leading zeroes */ |
| 39 | #define __PRINTF_FLAG_LEFTALIGNED 0x00000010 /* align to left */ |
44 | #define __PRINTF_FLAG_LEFTALIGNED 0x00000010 /**< align to left */ |
| 40 | #define __PRINTF_FLAG_SHOWPLUS 0x00000020 /* always show + sign */ |
45 | #define __PRINTF_FLAG_SHOWPLUS 0x00000020 /**< always show + sign */ |
| 41 | #define __PRINTF_FLAG_SPACESIGN 0x00000040 /* print space instead of plus */ |
46 | #define __PRINTF_FLAG_SPACESIGN 0x00000040 /**< print space instead of plus */ |
| 42 | #define __PRINTF_FLAG_BIGCHARS 0x00000080 /* show big characters */ |
47 | #define __PRINTF_FLAG_BIGCHARS 0x00000080 /**< show big characters */ |
| 43 | #define __PRINTF_FLAG_NEGATIVE 0x00000100 /* number has - sign */ |
48 | #define __PRINTF_FLAG_NEGATIVE 0x00000100 /**< number has - sign */ |
| 44 | 49 | ||
| 45 | #define PRINT_NUMBER_BUFFER_SIZE (64+5) /* Buffer big enought for 64 bit number |
50 | #define PRINT_NUMBER_BUFFER_SIZE (64+5) /**< Buffer big enought for 64 bit number |
| 46 | * printed in base 2, sign, prefix and |
51 | * printed in base 2, sign, prefix and |
| 47 | * 0 to terminate string.. (last one is only for better testing |
52 | * 0 to terminate string.. (last one is only for better testing |
| 48 | * end of buffer by zero-filling subroutine) |
53 | * end of buffer by zero-filling subroutine) |
| 49 | */ |
54 | */ |
| - | 55 | /** Enumeration of possible arguments types. |
|
| - | 56 | */ |
|
| 50 | typedef enum { |
57 | typedef enum { |
| 51 | PrintfQualifierByte = 0, |
58 | PrintfQualifierByte = 0, |
| 52 | PrintfQualifierShort, |
59 | PrintfQualifierShort, |
| 53 | PrintfQualifierInt, |
60 | PrintfQualifierInt, |
| 54 | PrintfQualifierLong, |
61 | PrintfQualifierLong, |
| 55 | PrintfQualifierLongLong, |
62 | PrintfQualifierLongLong, |
| 56 | PrintfQualifierSizeT, |
63 | PrintfQualifierSizeT, |
| 57 | PrintfQualifierPointer |
64 | PrintfQualifierPointer |
| 58 | } qualifier_t; |
65 | } qualifier_t; |
| 59 | 66 | ||
| 60 | static char digits_small[] = "0123456789abcdef"; /* Small hexadecimal characters */ |
67 | static char digits_small[] = "0123456789abcdef"; /**< Small hexadecimal characters */ |
| 61 | static char digits_big[] = "0123456789ABCDEF"; /* Big hexadecimal characters */ |
68 | static char digits_big[] = "0123456789ABCDEF"; /**< Big hexadecimal characters */ |
| 62 | 69 | ||
| 63 | /** Print count chars from buffer without adding newline |
70 | /** Print count chars from buffer without adding newline |
| 64 | * @param buf Buffer with size at least count bytes - NULL pointer NOT allowed! |
71 | * @param buf Buffer with size at least count bytes - NULL pointer NOT allowed! |
| 65 | * @param count |
72 | * @param count |
| 66 | * @param ps output method and its data |
73 | * @param ps output method and its data |
| Line 347... | Line 354... | ||
| 347 | 354 | ||
| 348 | return written; |
355 | return written; |
| 349 | } |
356 | } |
| 350 | 357 | ||
| 351 | 358 | ||
| 352 | /** General formatted text print |
359 | /** Print formatted string. |
| 353 | * |
360 | * |
| 354 | * Print string formatted according the fmt parameter |
361 | * Print string formatted according to the fmt parameter |
| 355 | * and variant arguments. Each formatting directive |
362 | * and variadic arguments. Each formatting directive |
| 356 | * must have the following form: |
363 | * must have the following form: |
| - | 364 | * |
|
| 357 | * % [ flags ] [ width ] [ .precision ] [ type ] conversion |
365 | * \% [ FLAGS ] [ WIDTH ] [ .PRECISION ] [ TYPE ] CONVERSION |
| - | 366 | * |
|
| - | 367 | * FLAGS:@n |
|
| - | 368 | * - "#" Force to print prefix. |
|
| - | 369 | * For conversion \%o the prefix is 0, for %x and \%X prefixes are 0x and 0X |
|
| - | 370 | * and for conversion \%b the prefix is 0b. |
|
| 358 | * |
371 | * |
| 359 | * FLAGS: |
- | |
| 360 | * # 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. |
- | |
| 361 | * - Align to left. |
372 | * - "-" Align to left. |
| - | 373 | * |
|
| 362 | * + Print positive sign just as negative. |
374 | * - "+" Print positive sign just as negative. |
| - | 375 | * |
|
| 363 | * (space) If printed number is positive and '+' flag is not set, print space in place of sign. |
376 | * - " " If the printed number is positive and "+" flag is not set, print space in |
| - | 377 | * place of sign. |
|
| - | 378 | * |
|
| 364 | * 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. |
379 | * - "0" Print 0 as padding instead of spaces. Zeroes are placed between sign and the |
| - | 380 | * rest of the number. This flag is ignored if "-" flag is specified. |
|
| 365 | * |
381 | * |
| 366 | * WIDTH: |
382 | * WIDTH:@n |
| 367 | * Specify minimal width of printed argument. If it is bigger, width is ignored. |
383 | * - Specify minimal width of printed argument. If it is bigger, width is ignored. |
| 368 | * If width is specified with a '*' character instead of number, width is taken from parameter list. |
384 | * If width is specified with a "*" character instead of number, width is taken from |
| 369 | * Int parameter expected before parameter for processed conversion specification. |
385 | * parameter list. And integer parameter is expected before parameter for processed |
| 370 | * If this value is negative it is taken its absolute value and the '-' flag is set. |
386 | * conversion specification. If this value is negative its absolute value is taken |
| - | 387 | * and the "-" flag is set. |
|
| 371 | * |
388 | * |
| 372 | * PRECISION: |
389 | * PRECISION:@n |
| 373 | * Value precision. For numbers it specifies minimum valid numbers. |
390 | * - Value precision. For numbers it specifies minimum valid numbers. |
| 374 | * Smaller numbers are printed with leading zeroes. Bigger numbers are not affected. |
391 | * Smaller numbers are printed with leading zeroes. Bigger numbers are not affected. |
| 375 | * Strings with more than precision characters are cutted of. |
392 | * Strings with more than precision characters are cut off. |
| 376 | * Just as width could be '*' used instead a number. |
393 | * Just as with width, an "*" can be used used instead of a number. |
| 377 | * A int value is then expected in parameters. When both width and precision are specified using '*', |
394 | * An integer value is then expected in parameters. When both width and precision |
| 378 | * first parameter is used for width and second one for precision. |
395 | * are specified using "*", the first parameter is used for width and the second one |
| 379 | * |
- | |
| 380 | * TYPE: |
- | |
| 381 | * hh signed or unsigned char |
- | |
| 382 | * h signed or usigned short |
- | |
| 383 | * signed or usigned int (default value) |
- | |
| 384 | * l signed or usigned long int |
- | |
| 385 | * ll signed or usigned long long int |
- | |
| 386 | * z size_t type |
396 | * for precision. |
| 387 | * |
397 | * |
| - | 398 | * TYPE:@n |
|
| - | 399 | * - "hh" Signed or unsigned char.@n |
|
| - | 400 | * - "h" Signed or usigned short.@n |
|
| - | 401 | * - "" Signed or usigned int (default value).@n |
|
| - | 402 | * - "l" Signed or usigned long int.@n |
|
| - | 403 | * - "ll" Signed or usigned long long int.@n |
|
| - | 404 | * - "z" Type size_t.@n |
|
| 388 | * |
405 | * |
| 389 | * CONVERSIONS: |
- | |
| 390 | * |
406 | * |
| - | 407 | * CONVERSION:@n |
|
| 391 | * % Print percentage character. |
408 | * - % Print percentile character itself. |
| 392 | * |
409 | * |
| 393 | * c Print single character. |
410 | * - c Print single character. |
| 394 | * |
411 | * |
| 395 | * s Print zero terminated string. If a NULL value is passed as value, "(NULL)" is printed instead. |
412 | * - s Print zero terminated string. If a NULL value is passed as value, "(NULL)" is printed instead. |
| 396 | * |
413 | * |
| 397 | * P, p Print value of a pointer. Void * value is expected and it is printed in hexadecimal notation with prefix |
414 | * - P, p Print value of a pointer. Void * value is expected and it is printed in hexadecimal notation with prefix |
| 398 | * ( as with %#X or %#x for 32bit or %#X / %#x for 64bit long pointers) |
415 | * (as with \%#X or \%#x for 32bit or \%#X / \%#x for 64bit long pointers). |
| 399 | * |
416 | * |
| 400 | * b Print value as unsigned binary number. Prefix is not printed by default. (Nonstandard extension.) |
417 | * - b Print value as unsigned binary number. Prefix is not printed by default. (Nonstandard extension.) |
| 401 | * |
418 | * |
| 402 | * o Print value as unsigned octal number. Prefix is not printed by default. |
419 | * - o Print value as unsigned octal number. Prefix is not printed by default. |
| 403 | * |
420 | * |
| 404 | * d,i Print signed decimal number. There is no difference between d and i conversion. |
421 | * - d,i Print signed decimal number. There is no difference between d and i conversion. |
| 405 | * |
422 | * |
| 406 | * u Print unsigned decimal number. |
423 | * - u Print unsigned decimal number. |
| 407 | * |
424 | * |
| 408 | * X, x Print hexadecimal number with upper- or lower-case. Prefix is not printed by default. |
425 | * - X, x Print hexadecimal number with upper- or lower-case. Prefix is not printed by default. |
| 409 | * |
426 | * |
| 410 | * All other characters from fmt except the formatting directives |
427 | * All other characters from fmt except the formatting directives |
| 411 | * are printed in verbatim. |
428 | * are printed in verbatim. |
| 412 | * |
429 | * |
| 413 | * @param fmt Formatting NULL terminated string. |
430 | * @param fmt Formatting NULL terminated string. |
| 414 | * @return count of printed characters or negative value on fail. |
431 | * @return Number of printed characters or negative value on failure. |
| 415 | */ |
432 | */ |
| 416 | int printf_core(const char *fmt, struct printf_spec *ps, va_list ap) |
433 | int printf_core(const char *fmt, struct printf_spec *ps, va_list ap) |
| 417 | { |
434 | { |
| 418 | int i = 0, j = 0; /* i is index of currently processed char from fmt, j is index to the first not printed nonformating character */ |
435 | int i = 0, j = 0; /**< i is index of currently processed char from fmt, j is index to the first not printed nonformating character */ |
| 419 | int end; |
436 | int end; |
| 420 | int counter; /* counter of printed characters */ |
437 | int counter; /**< counter of printed characters */ |
| 421 | int retval; /* used to store return values from called functions */ |
438 | int retval; /**< used to store return values from called functions */ |
| 422 | char c; |
439 | char c; |
| 423 | qualifier_t qualifier; /* type of argument */ |
440 | qualifier_t qualifier; /**< type of argument */ |
| 424 | int base; /* base in which will be parameter (numbers only) printed */ |
441 | int base; /**< base in which will be parameter (numbers only) printed */ |
| 425 | uint64_t number; /* argument value */ |
442 | uint64_t number; /**< argument value */ |
| 426 | size_t size; /* byte size of integer parameter */ |
443 | size_t size; /**< byte size of integer parameter */ |
| 427 | int width, precision; |
444 | int width, precision; |
| 428 | uint64_t flags; |
445 | uint64_t flags; |
| 429 | 446 | ||
| 430 | counter = 0; |
447 | counter = 0; |
| 431 | 448 | ||