Subversion Repositories HelenOS-historic

Rev

Rev 1616 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1616 Rev 1617
Line 71... Line 71...
71
 
71
 
72
/** Print count chars from buffer without adding newline
72
/** Print count chars from buffer without adding newline
73
 * @param buf Buffer with size at least count bytes - NULL pointer NOT allowed!
73
 * @param buf Buffer with size at least count bytes - NULL pointer NOT allowed!
74
 * @param count
74
 * @param count
75
 * @param ps output method and its data
75
 * @param ps output method and its data
76
 * @return 0 on success, EOF on fail
76
 * @return number of printed characters
77
 */
77
 */
78
static int printf_putnchars(const char * buf, size_t count, struct printf_spec *ps)
78
static int printf_putnchars(const char * buf, size_t count, struct printf_spec *ps)
79
{
79
{
80
    if (ps->write((void *)buf, count, ps->data) == count) {
80
    return ps->write((void *)buf, count, ps->data);
81
        return 0;
-
 
82
    }
-
 
83
   
-
 
84
    return EOF;
-
 
85
}
81
}
86
 
82
 
87
/** Print string without added newline
83
/** Print string without added newline
88
 * @param str string to print
84
 * @param str string to print
89
 * @param ps write function specification and support data
85
 * @param ps write function specification and support data
90
 * @return 0 on success or EOF on fail
86
 * @return number of printed characters
91
 */
87
 */
92
static int printf_putstr(const char * str, struct printf_spec *ps)
88
static int printf_putstr(const char * str, struct printf_spec *ps)
93
{
89
{
94
    size_t count;
90
    size_t count;
95
   
91
   
Line 107... Line 103...
107
}
103
}
108
 
104
 
109
/** Print one character to output
105
/** Print one character to output
110
 * @param c one character
106
 * @param c one character
111
 * @param ps output method
107
 * @param ps output method
112
 * @return printed character or EOF
108
 * @return number of printed characters
113
 */
109
 */
114
static int printf_putchar(int c, struct printf_spec *ps)
110
static int printf_putchar(int c, struct printf_spec *ps)
115
{
111
{
116
    unsigned char ch = c;
112
    unsigned char ch = c;
117
   
113
   
118
    if (ps->write((void *) &ch, 1, ps->data) == 1) {
114
    return ps->write((void *) &ch, 1, ps->data);
119
        return c;
-
 
120
    }
-
 
121
   
-
 
122
    return EOF;
-
 
123
}
115
}
124
 
116
 
125
/** Print one formatted character
117
/** Print one formatted character
126
 * @param c character to print
118
 * @param c character to print
127
 * @param width
119
 * @param width
128
 * @param flags
120
 * @param flags
129
 * @return number of printed characters or EOF
121
 * @return number of printed characters
130
 */
122
 */
131
static int print_char(char c, int width, uint64_t flags, struct printf_spec *ps)
123
static int print_char(char c, int width, uint64_t flags, struct printf_spec *ps)
132
{
124
{
133
    int counter = 0;
125
    int counter = 0;
134
   
126
   
135
    if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
127
    if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
136
        while (--width > 0) {   /* one space is consumed by character itself hence predecrement */
128
        while (--width > 0) {   /* one space is consumed by character itself hence predecrement */
137
            /* FIXME: painful slow */
-
 
138
            printf_putchar(' ', ps);   
129
            if (printf_putchar(' ', ps) > 0)   
139
            ++counter;
130
                ++counter;
140
        }
131
        }
141
    }
132
    }
-
 
133
   
-
 
134
    if (printf_putchar(c, ps) > 0)
-
 
135
        counter++;
142
   
136
   
143
    if (printf_putchar(c, ps) == EOF) {
-
 
144
        return EOF;
-
 
145
    }
-
 
146
 
-
 
147
    while (--width > 0) { /* one space is consumed by character itself hence predecrement */
137
    while (--width > 0) { /* one space is consumed by character itself hence predecrement */
148
        printf_putchar(' ', ps);
138
        if (printf_putchar(' ', ps) > 0)
149
        ++counter;
139
            ++counter;
150
    }
140
    }
151
   
141
   
152
    return ++counter;
142
    return ++counter;
153
}
143
}
154
 
144
 
155
/** Print one string
145
/** Print one string
156
 * @param s string
146
 * @param s string
157
 * @param width
147
 * @param width
158
 * @param precision
148
 * @param precision
159
 * @param flags
149
 * @param flags
160
 * @return number of printed characters or EOF
150
 * @return number of printed characters
161
 */
151
 */
162
                       
152
                       
163
static int print_string(char *s, int width, int precision, uint64_t flags, struct printf_spec *ps)
153
static int print_string(char *s, int width, int precision, uint64_t flags, struct printf_spec *ps)
164
{
154
{
165
    int counter = 0;
155
    int counter = 0;
166
    size_t size;
156
    size_t size;
-
 
157
    int retval;
167
 
158
 
168
    if (s == NULL) {
159
    if (s == NULL) {
169
        return printf_putstr("(NULL)", ps);
160
        return printf_putstr("(NULL)", ps);
170
    }
161
    }
171
   
162
   
Line 178... Line 169...
178
 
169
 
179
    width -= precision;
170
    width -= precision;
180
   
171
   
181
    if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
172
    if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
182
        while (width-- > 0) {  
173
        while (width-- > 0) {  
183
            printf_putchar(' ', ps);   
174
            if (printf_putchar(' ', ps) == 1)  
184
            counter++;
175
                counter++;
185
        }
176
        }
186
    }
177
    }
187
 
178
 
188
    while (precision > size) {
179
    while (precision > size) {
189
        precision--;
180
        precision--;
190
        printf_putchar(' ', ps);   
181
        if (printf_putchar(' ', ps) == 1)  
191
        ++counter;
182
            ++counter;
192
    }
183
    }
193
   
184
   
194
    if (printf_putnchars(s, precision, ps) == EOF) {
185
    if ((retval = printf_putnchars(s, precision, ps)) < 0) {
195
        return EOF;
186
        return -counter;
196
    }
187
    }
197
 
188
 
198
    counter += precision;
189
    counter += retval; 
199
 
190
 
200
    while (width-- > 0) {
191
    while (width-- > 0) {
201
        printf_putchar(' ', ps);   
192
        if (printf_putchar(' ', ps) == 1)  
202
        ++counter;
193
            ++counter;
203
    }
194
    }
204
   
195
   
205
    return ++counter;
196
    return counter;
206
}
197
}
207
 
198
 
208
 
199
 
209
/** Print number in given base
200
/** Print number in given base
210
 *
201
 *
Line 215... Line 206...
215
 * @param width
206
 * @param width
216
 * @param precision
207
 * @param precision
217
 * @param base Base to print the number in (should
208
 * @param base Base to print the number in (should
218
 *             be in range 2 .. 16).
209
 *             be in range 2 .. 16).
219
 * @param flags output modifiers
210
 * @param flags output modifiers
220
 * @return number of written characters or EOF
211
 * @return number of printed characters
221
 *
212
 *
222
 */
213
 */
223
static int print_number(uint64_t num, int width, int precision, int base , uint64_t flags, struct printf_spec *ps)
214
static int print_number(uint64_t num, int width, int precision, int base , uint64_t flags, struct printf_spec *ps)
224
{
215
{
225
    char *digits = digits_small;
216
    char *digits = digits_small;
226
    char d[PRINT_NUMBER_BUFFER_SIZE];   /* this is good enough even for base == 2, prefix and sign */
217
    char d[PRINT_NUMBER_BUFFER_SIZE];   /* this is good enough even for base == 2, prefix and sign */
227
    char *ptr = &d[PRINT_NUMBER_BUFFER_SIZE - 1];
218
    char *ptr = &d[PRINT_NUMBER_BUFFER_SIZE - 1];
228
    int size = 0; /* size of number with all prefixes and signs */
219
    int size = 0; /* size of number with all prefixes and signs */
229
    int number_size; /* size of plain number */
220
    int number_size; /* size of plain number */
230
    int written = 0;
-
 
231
    char sgn;
221
    char sgn;
-
 
222
    int retval;
-
 
223
    int counter = 0;
232
   
224
   
233
    if (flags & __PRINTF_FLAG_BIGCHARS)
225
    if (flags & __PRINTF_FLAG_BIGCHARS)
234
        digits = digits_big;   
226
        digits = digits_big;   
235
   
227
   
236
    *ptr-- = 0; /* Put zero at end of string */
228
    *ptr-- = 0; /* Put zero at end of string */
Line 293... Line 285...
293
 
285
 
294
    width -= precision + size - number_size;
286
    width -= precision + size - number_size;
295
   
287
   
296
    if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
288
    if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
297
        while (width-- > 0) {  
289
        while (width-- > 0) {  
298
            printf_putchar(' ', ps);   
290
            if (printf_putchar(' ', ps) == 1)  
299
            written++;
291
                counter++;
300
        }
292
        }
301
    }
293
    }
302
   
294
   
303
    /* print sign */
295
    /* print sign */
304
    if (sgn) {
296
    if (sgn) {
305
        printf_putchar(sgn, ps);
297
        if (printf_putchar(sgn, ps) == 1)
306
        written++;
298
            counter++;
307
    }
299
    }
308
   
300
   
309
    /* print prefix */
301
    /* print prefix */
310
   
302
   
311
    if (flags & __PRINTF_FLAG_PREFIX) {
303
    if (flags & __PRINTF_FLAG_PREFIX) {
312
        switch(base) {
304
        switch(base) {
313
            case 2: /* Binary formating is not standard, but usefull */
305
            case 2: /* Binary formating is not standard, but usefull */
314
                printf_putchar('0', ps);
306
                if (printf_putchar('0', ps) == 1)
-
 
307
                    counter++;
315
                if (flags & __PRINTF_FLAG_BIGCHARS) {
308
                if (flags & __PRINTF_FLAG_BIGCHARS) {
316
                    printf_putchar('B', ps);
309
                    if (printf_putchar('B', ps) == 1)
-
 
310
                        counter++;
317
                } else {
311
                } else {
318
                    printf_putchar('b', ps);
312
                    if (printf_putchar('b', ps) == 1)
-
 
313
                        counter++;
319
                }
314
                }
320
                written += 2;
-
 
321
                break;
315
                break;
322
            case 8:
316
            case 8:
323
                printf_putchar('o', ps);
317
                if (printf_putchar('o', ps) == 1)
324
                written++;
318
                    counter++;
325
                break;
319
                break;
326
            case 16:
320
            case 16:
327
                printf_putchar('0', ps);
321
                if (printf_putchar('0', ps) == 1)
-
 
322
                    counter++;
328
                if (flags & __PRINTF_FLAG_BIGCHARS) {
323
                if (flags & __PRINTF_FLAG_BIGCHARS) {
329
                    printf_putchar('X', ps);
324
                    if (printf_putchar('X', ps) == 1)
-
 
325
                        counter++;
330
                } else {
326
                } else {
331
                    printf_putchar('x', ps);
327
                    if (printf_putchar('x', ps) == 1)
-
 
328
                        counter++;
332
                }
329
                }
333
                written += 2;
-
 
334
                break;
330
                break;
335
        }
331
        }
336
    }
332
    }
337
 
333
 
338
    /* print leading zeroes */
334
    /* print leading zeroes */
339
    precision -= number_size;
335
    precision -= number_size;
340
    while (precision-- > 0) {  
336
    while (precision-- > 0) {  
341
        printf_putchar('0', ps);   
337
        if (printf_putchar('0', ps) == 1)
342
        written++;
338
            counter++;
343
    }
339
    }
344
 
340
 
345
   
341
   
346
    /* print number itself */
342
    /* print number itself */
347
 
343
 
348
    written += printf_putstr(++ptr, ps);
344
    if ((retval = printf_putstr(++ptr, ps)) > 0) {
-
 
345
        counter += retval;
-
 
346
    }
349
   
347
   
350
    /* print ending spaces */
348
    /* print ending spaces */
351
   
349
   
352
    while (width-- > 0) {  
350
    while (width-- > 0) {  
353
        printf_putchar(' ', ps);   
351
        if (printf_putchar(' ', ps) == 1)  
354
        written++;
352
            counter++;
355
    }
353
    }
356
 
354
 
357
    return written;
355
    return counter;
358
}
356
}
359
 
357
 
360
 
358
 
361
/** Print formatted string.
359
/** Print formatted string.
362
 *
360
 *
Line 454... Line 452...
454
    while ((c = fmt[i])) {
452
    while ((c = fmt[i])) {
455
        /* control character */
453
        /* control character */
456
        if (c == '%' ) {
454
        if (c == '%' ) {
457
            /* print common characters if any processed */ 
455
            /* print common characters if any processed */ 
458
            if (i > j) {
456
            if (i > j) {
459
                if ((retval = printf_putnchars(&fmt[j], (size_t)(i - j), ps)) == EOF) { /* error */
457
                if ((retval = printf_putnchars(&fmt[j], (size_t)(i - j), ps)) < 0) { /* error */
460
                    goto minus_out;
458
                    goto minus_out;
461
                }
459
                }
462
                counter += retval;
460
                counter += retval;
463
            }
461
            }
464
       
462
       
Line 550... Line 548...
550
 
548
 
551
                /*
549
                /*
552
                * String and character conversions.
550
                * String and character conversions.
553
                */
551
                */
554
                case 's':
552
                case 's':
555
                    if ((retval = print_string(va_arg(ap, char*), width, precision, flags, ps)) == EOF) {
553
                    if ((retval = print_string(va_arg(ap, char*), width, precision, flags, ps)) < 0) {
556
                        goto minus_out;
554
                        goto minus_out;
557
                    };
555
                    };
558
                   
556
                   
559
                    counter += retval;
557
                    counter += retval;
560
                    j = i + 1;
558
                    j = i + 1;
561
                    goto next_char;
559
                    goto next_char;
562
                case 'c':
560
                case 'c':
563
                    c = va_arg(ap, unsigned int);
561
                    c = va_arg(ap, unsigned int);
564
                    if ((retval = print_char(c, width, flags, ps)) == EOF) {
562
                    if ((retval = print_char(c, width, flags, ps)) < 0) {
565
                        goto minus_out;
563
                        goto minus_out;
566
                    };
564
                    };
567
                   
565
                   
568
                    counter += retval;
566
                    counter += retval;
569
                    j = i + 1;
567
                    j = i + 1;
Line 659... Line 657...
659
                        number++;
657
                        number++;
660
                    }
658
                    }
661
                }
659
                }
662
            }
660
            }
663
 
661
 
664
            if ((retval = print_number(number, width, precision, base, flags, ps)) == EOF ) {
662
            if ((retval = print_number(number, width, precision, base, flags, ps)) < 0 ) {
665
                goto minus_out;
663
                goto minus_out;
666
            };
664
            };
667
 
665
 
668
            counter += retval;
666
            counter += retval;
669
            j = i + 1;
667
            j = i + 1;
Line 672... Line 670...
672
           
670
           
673
        ++i;
671
        ++i;
674
    }
672
    }
675
   
673
   
676
    if (i > j) {
674
    if (i > j) {
677
        if ((retval = printf_putnchars(&fmt[j], (size_t)(i - j), ps)) == EOF) { /* error */
675
        if ((retval = printf_putnchars(&fmt[j], (size_t)(i - j), ps)) < 0) { /* error */
678
            goto minus_out;
676
            goto minus_out;
679
        }
677
        }
680
        counter += retval;
678
        counter += retval;
681
    }
679
    }
682
   
680