Subversion Repositories HelenOS-historic

Rev

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