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 |