8 #define LARGEST_SIGNED long long int 10 #define LARGEST_UNSIGNED long int 14 #ifndef LARGEST_UNSIGNED 16 #define LARGEST_UNSIGNED unsigned long long int 18 #define LARGEST_UNSIGNED unsigned long int 23 #define POINTER_INT unsigned long 26 typedef unsigned int FormatFlags;
28 #define MAKE_MASK(shift,size) (((1 << size) - 1) << (shift)) 30 #define JUSTIFY_SHIFT 0 31 #define JUSTIFY_SIZE 1 32 #define JUSTIFY_RIGHT 0x0000 33 #define JUSTIFY_LEFT 0x0001 34 #define JUSTIFY_MASK MAKE_MASK(JUSTIFY_SHIFT,JUSTIFY_SIZE) 38 #define POSITIVE_SHIFT (JUSTIFY_SHIFT + JUSTIFY_SIZE) 39 #define POSITIVE_NONE (0x0000 << POSITIVE_SHIFT) 40 #define POSITIVE_SPACE (0x0001 << POSITIVE_SHIFT) 41 #define POSITIVE_PLUS (0x0003 << POSITIVE_SHIFT) 42 #define POSITIVE_MASK MAKE_MASK(POSITIVE_SHIFT, POSITIVE_SIZE) 44 #define POSITIVE_SIZE 2 46 #define ALTERNATE_FORM_SHIFT (POSITIVE_SHIFT + POSITIVE_SIZE) 47 #define ALTERNATE_FORM_SIZE 1 48 #define ALTERNATE_FORM (0x0001 << ALTERNATE_FORM_SHIFT) 51 #define PAD_SHIFT (ALTERNATE_FORM_SHIFT + ALTERNATE_FORM_SIZE) 53 #define PAD_SPACE (0x0000 << PAD_SHIFT) 54 #define PAD_ZERO (0x0001 << PAD_SHIFT) 56 #define SIZE_SHIFT (PAD_SHIFT + PAD_SIZE) 58 #define SIZE_CHAR (0x0001 << SIZE_SHIFT) 59 #define SIZE_SHORT (0x0002 << SIZE_SHIFT) 60 #define SIZE_INT (0x0000 << SIZE_SHIFT) 61 #define SIZE_LONG (0x0003 << SIZE_SHIFT) 62 #define SIZE_LONGLONG (0x0004 << SIZE_SHIFT) 63 #define SIZE_MASK MAKE_MASK(SIZE_SHIFT,SIZE_SIZE) 65 #define CONV_SHIFT (SIZE_SHIFT + SIZE_SIZE) 67 #define CONV_INTEGER (0x0001 << CONV_SHIFT) 68 #define CONV_FLOAT (0x0002 << CONV_SHIFT) 69 #define CONV_POINTER (0x0003 << CONV_SHIFT) 70 #define CONV_STRING (0x0004 << CONV_SHIFT) 71 #define CONV_CHAR (0x0005 << CONV_SHIFT) 72 #define CONV_PERCENT (0x0006 << CONV_SHIFT) 73 #define CONV_WRITTEN (0x0007 << CONV_SHIFT) 74 #define CONV_MASK MAKE_MASK(CONV_SHIFT, CONV_SIZE) 76 #define RADIX_SHIFT (CONV_SHIFT + CONV_SIZE) 78 #define RADIX_DECIMAL (0x0001 << RADIX_SHIFT) 79 #define RADIX_OCTAL (0x0002 << RADIX_SHIFT) 80 #define RADIX_HEX (0x0003 << RADIX_SHIFT) 81 #define RADIX_MASK MAKE_MASK(RADIX_SHIFT,RADIX_SIZE) 83 #define SIGNED_SHIFT (RADIX_SHIFT + RADIX_SIZE) 85 #define SIGNED_NO (0x0000 << SIGNED_SHIFT) 86 #define SIGNED_YES (0x0001 << SIGNED_SHIFT) 87 #define SIGNED_MASK MAKE_MASK(SIGNED_SHIFT,SIGNED_SIZE) 89 #define CAPS_SHIFT (SIGNED_SHIFT + SIGNED_SIZE) 91 #define CAPS_NO (0x0000 << CAPS_SHIFT) 92 #define CAPS_YES (0x0001 << CAPS_SHIFT) 93 #define CAPS_MASK MAKE_MASK(CAPS_SHIFT,CAPS_SIZE) 95 #define FLOAT_SHIFT (CAPS_SHIFT + CAPS_SIZE) 97 #define FLOAT_NORMAL (0x0000 << FLOAT_SHIFT) 98 #define FLOAT_EXPONENT (0x0001 << FLOAT_SHIFT) 99 #define FLOAT_DEPENDANT (0x0002 << FLOAT_SHIFT) 100 #define FLOAT_HEX (0x0003 << FLOAT_SHIFT) 101 #define FLOAT_MASK MAKE_MASK(FLOAT_SHIFT, FLOAT_SIZE) 104 parse_flags(
const char **posp)
106 FormatFlags flags = 0;
107 const char *pos = *posp;
111 flags |= JUSTIFY_LEFT;
114 flags |= POSITIVE_PLUS;
117 flags |= POSITIVE_SPACE;
120 flags |= ALTERNATE_FORM;
131 #ifdef ECLIPSE_STUB_CODE_ANALYSE 138 parse_uint(
const char **posp)
141 const char *pos = *posp;
143 while((ch = *pos) >=
'0' && ch <=
'9') {
144 v = v * 10 + (ch -
'0');
151 #define MAXCHARS_HEX ((sizeof(LARGEST_UNSIGNED) * 8) / 4 ) 155 #define MAXCHARS ((sizeof(LARGEST_UNSIGNED) * 8 + 2) / 3 ) 158 output_uint_decimal(
char **posp, LARGEST_UNSIGNED v)
163 *--pos = (v % 10) +
'0';
172 output_uint_hex(
char **posp, LARGEST_UNSIGNED v,
unsigned int flags)
175 const char *hex = (flags & CAPS_YES) ?
"0123456789ABCDEF":
"0123456789abcdef";
178 *--pos = hex[(v % 16)];
187 output_uint_octal(
char **posp, LARGEST_UNSIGNED v)
192 *--pos = (v % 8) +
'0';
200 static StrFormatResult
201 fill_space(
const StrFormatContext *ctxt,
unsigned int len)
204 static const char buffer[16] =
" ";
206 res = ctxt->write_str(ctxt->user_data, buffer, 16);
207 if (res != STRFORMAT_OK)
return res;
210 if (len == 0)
return STRFORMAT_OK;
211 return ctxt->write_str(ctxt->user_data, buffer, len);
214 static StrFormatResult
215 fill_zero(
const StrFormatContext *ctxt,
unsigned int len)
218 static const char buffer[16] =
"0000000000000000";
220 res = ctxt->write_str(ctxt->user_data, buffer, 16);
221 if (res != STRFORMAT_OK)
return res;
224 if (len == 0)
return STRFORMAT_OK;
225 return ctxt->write_str(ctxt->user_data, buffer, len);
228 #define CHECKCB(res) {if ((res) != STRFORMAT_OK) {va_end(ap); return -1;}} 231 format_str(
const StrFormatContext *ctxt,
const char *format, ...)
235 va_start(ap, format);
236 ret = format_str_v(ctxt, format, ap);
242 format_str_v(
const StrFormatContext *ctxt,
const char *format, va_list ap)
244 unsigned int written = 0;
245 const char *pos = format;
246 while(*pos !=
'\0') {
248 unsigned int minwidth = 0;
251 const char *start = pos;
252 while( (ch = *pos) !=
'\0' && ch !=
'%') pos++;
254 CHECKCB(ctxt->write_str(ctxt->user_data, start, pos - start));
255 written += pos - start;
266 flags = parse_flags(&pos);
269 if (*pos >=
'1' && *pos <=
'9') {
270 minwidth = parse_uint(&pos);
271 }
else if (*pos ==
'*') {
272 int w = va_arg(ap,
int);
274 flags |= JUSTIFY_LEFT;
285 if (*pos >=
'0' && *pos <=
'9') {
286 precision = parse_uint(&pos);
287 }
else if (*pos ==
'*') {
289 precision = va_arg(ap,
int);
295 flags |= SIZE_LONGLONG;
300 }
else if (*pos ==
'h') {
314 flags |= CONV_INTEGER | RADIX_DECIMAL | SIGNED_YES;
317 flags |= CONV_INTEGER | RADIX_DECIMAL | SIGNED_NO;
320 flags |= CONV_INTEGER | RADIX_OCTAL | SIGNED_NO;
323 flags |= CONV_INTEGER | RADIX_HEX | SIGNED_NO;
326 flags |= CONV_INTEGER | RADIX_HEX | SIGNED_NO | CAPS_YES;
330 flags |= CONV_FLOAT | FLOAT_NORMAL;
333 flags |= CONV_FLOAT | FLOAT_NORMAL | CAPS_YES;
336 flags |= CONV_FLOAT | FLOAT_EXPONENT;
339 flags |= CONV_FLOAT | FLOAT_EXPONENT | CAPS_YES;
342 flags |= CONV_FLOAT | FLOAT_DEPENDANT;
345 flags |= CONV_FLOAT | FLOAT_DEPENDANT | CAPS_YES;
348 flags |= CONV_FLOAT | FLOAT_HEX;
351 flags |= CONV_FLOAT | FLOAT_HEX | CAPS_YES;
358 flags |= CONV_STRING;
361 flags |= CONV_POINTER;
364 flags |= CONV_WRITTEN;
367 flags |= CONV_PERCENT;
374 switch(flags & CONV_MASK) {
376 CHECKCB(ctxt->write_str(ctxt->user_data,
"%", 1));
383 unsigned int prefix_len = 0;
384 char buffer[MAXCHARS];
385 char *conv_pos = buffer + MAXCHARS;
386 unsigned int conv_len = 0;
387 unsigned int width = 0;
388 unsigned int precision_fill;
389 unsigned int field_fill;
390 LARGEST_UNSIGNED uvalue = 0;
393 if (precision < 0) precision = 1;
394 else flags &= ~PAD_ZERO;
396 if (flags & SIGNED_YES) {
398 LARGEST_SIGNED value = 0;
399 switch(flags & SIZE_MASK) {
401 value = (
signed char)va_arg(ap,
int);
404 value = (short)va_arg(ap,
int);
407 value = va_arg(ap,
int);
409 #ifndef HAVE_LONGLONG 413 value = va_arg(ap,
long);
417 value = va_arg(ap,
long long);
429 switch(flags & SIZE_MASK) {
431 uvalue = (
unsigned char)va_arg(ap,
unsigned int);
434 uvalue = (
unsigned short)va_arg(ap,
unsigned int);
437 uvalue = va_arg(ap,
unsigned int);
439 #ifndef HAVE_LONGLONG 443 uvalue = va_arg(ap,
unsigned long);
447 uvalue = va_arg(ap,
unsigned long long);
453 switch(flags & (RADIX_MASK)) {
455 conv_len = output_uint_decimal(&conv_pos,uvalue);
458 conv_len = output_uint_octal(&conv_pos,uvalue);
461 conv_len = output_uint_hex(&conv_pos,uvalue, flags);
466 precision_fill = (precision > conv_len) ? precision - conv_len : 0;
467 if ((flags & (RADIX_MASK | ALTERNATE_FORM))
468 == (RADIX_OCTAL | ALTERNATE_FORM)) {
469 if (precision_fill < 1) precision_fill = 1;
472 width += precision_fill;
474 if ((flags & (RADIX_MASK | ALTERNATE_FORM))
475 == (RADIX_HEX | ALTERNATE_FORM) && uvalue != 0) {
477 if (flags & CAPS_YES) {
484 if (flags & SIGNED_YES) {
489 switch(flags & POSITIVE_MASK) {
504 field_fill = (minwidth > width) ? minwidth - width : 0;
506 if ((flags & JUSTIFY_MASK) == JUSTIFY_RIGHT) {
507 if (flags & PAD_ZERO) {
508 precision_fill += field_fill;
511 CHECKCB(fill_space(ctxt,field_fill));
516 CHECKCB(ctxt->write_str(ctxt->user_data, prefix, prefix_len));
517 written += prefix_len;
519 CHECKCB(fill_zero(ctxt,precision_fill));
520 written += precision_fill;
522 CHECKCB(ctxt->write_str(ctxt->user_data, conv_pos,conv_len));
525 if ((flags & JUSTIFY_MASK) == JUSTIFY_LEFT) {
526 CHECKCB(fill_space(ctxt,field_fill));
528 written += field_fill;
533 unsigned int field_fill;
535 char *str = va_arg(ap,
char *);
538 while(*pos !=
'\0') pos++;
544 if (precision >= 0 && precision < len) len = precision;
545 field_fill = (minwidth > len) ? minwidth - len : 0;
546 if ((flags & JUSTIFY_MASK) == JUSTIFY_RIGHT) {
547 CHECKCB(fill_space(ctxt,field_fill));
549 CHECKCB(ctxt->write_str(ctxt->user_data, str,len));
551 if ((flags & JUSTIFY_MASK) == JUSTIFY_LEFT) {
552 CHECKCB(fill_space(ctxt,field_fill));
554 written += field_fill;
559 LARGEST_UNSIGNED uvalue =
560 (LARGEST_UNSIGNED)(POINTER_INT)va_arg(ap,
void *);
561 char buffer[MAXCHARS_HEX + 3];
562 char *conv_pos = buffer + MAXCHARS_HEX+3;
563 unsigned int conv_len;
564 unsigned int field_fill;
566 conv_len = output_uint_hex(&conv_pos,uvalue,flags);
576 field_fill = (minwidth > conv_len) ? minwidth - conv_len : 0;
578 if ((flags & JUSTIFY_MASK) == JUSTIFY_RIGHT) {
579 CHECKCB(fill_space(ctxt,field_fill));
582 CHECKCB(ctxt->write_str(ctxt->user_data, conv_pos,conv_len));
585 if ((flags & JUSTIFY_MASK) == JUSTIFY_LEFT) {
586 CHECKCB(fill_space(ctxt,field_fill));
588 written += field_fill;
593 char ch = va_arg(ap,
int);
594 unsigned int field_fill = (minwidth > 1) ? minwidth - 1 : 0;
595 if ((flags & JUSTIFY_MASK) == JUSTIFY_RIGHT) {
596 CHECKCB(fill_space(ctxt,field_fill));
597 written += field_fill;
600 CHECKCB(ctxt->write_str(ctxt->user_data, &ch, 1));
603 if ((flags & JUSTIFY_MASK) == JUSTIFY_LEFT) {
604 CHECKCB(fill_space(ctxt,field_fill));
606 written+= field_fill;
611 int *p = va_arg(ap,
int*);