Subversion Repositories HelenOS-historic

Rev

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
 
-