Mercurial > hg > xemacs-beta
comparison src/doprnt.c @ 185:3d6bfa290dbd r20-3b19
Import from CVS: tag r20-3b19
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:55:28 +0200 |
parents | 54cc21c15cbb |
children | b405438285a2 |
comparison
equal
deleted
inserted
replaced
184:bcd2674570bf | 185:3d6bfa290dbd |
---|---|
37 static CONST char *int_converters = "dic"; | 37 static CONST char *int_converters = "dic"; |
38 static CONST char *unsigned_int_converters = "ouxX"; | 38 static CONST char *unsigned_int_converters = "ouxX"; |
39 static CONST char *double_converters = "feEgG"; | 39 static CONST char *double_converters = "feEgG"; |
40 static CONST char *string_converters = "sS"; | 40 static CONST char *string_converters = "sS"; |
41 | 41 |
42 typedef struct printf_spec printf_spec; | |
42 struct printf_spec | 43 struct printf_spec |
43 { | 44 { |
44 int argnum; /* which argument does this spec want? This is one-based: | 45 int argnum; /* which argument does this spec want? This is one-based: |
45 The first argument given is numbered 1, the second | 46 The first argument given is numbered 1, the second |
46 is 2, etc. This is to handle %##$x-type specs. */ | 47 is 2, etc. This is to handle %##$x-type specs. */ |
59 Bytecount text_before; /* position of the first character of the | 60 Bytecount text_before; /* position of the first character of the |
60 block of literal text before this spec */ | 61 block of literal text before this spec */ |
61 Bytecount text_before_len; /* length of that text */ | 62 Bytecount text_before_len; /* length of that text */ |
62 }; | 63 }; |
63 | 64 |
65 typedef union printf_arg printf_arg; | |
64 union printf_arg | 66 union printf_arg |
65 { | 67 { |
66 int i; | 68 int i; |
67 unsigned int ui; | 69 unsigned int ui; |
68 long l; | 70 long l; |
118 { | 120 { |
119 Lstream_putc (lstr, pad); | 121 Lstream_putc (lstr, pad); |
120 to_add--; | 122 to_add--; |
121 } | 123 } |
122 } | 124 } |
123 | 125 |
124 if (maxlen >= 0) | 126 if (maxlen >= 0) |
125 len = charcount_to_bytecount (string, min (maxlen, cclen)); | 127 len = charcount_to_bytecount (string, min (maxlen, cclen)); |
126 Lstream_write (lstr, string, len); | 128 Lstream_write (lstr, string, len); |
127 | 129 |
128 /* Padding at end to left-justify ... */ | 130 /* Padding at end to left-justify ... */ |
140 static CONST Bufbyte * | 142 static CONST Bufbyte * |
141 parse_off_posnum (CONST Bufbyte *start, CONST Bufbyte *end, int *returned_num) | 143 parse_off_posnum (CONST Bufbyte *start, CONST Bufbyte *end, int *returned_num) |
142 { | 144 { |
143 Bufbyte arg_convert[100]; | 145 Bufbyte arg_convert[100]; |
144 REGISTER Bufbyte *arg_ptr = arg_convert; | 146 REGISTER Bufbyte *arg_ptr = arg_convert; |
145 | 147 |
146 *returned_num = -1; | 148 *returned_num = -1; |
147 while (start != end && isdigit (*start)) | 149 while (start != end && isdigit (*start)) |
148 { | 150 { |
149 if (arg_ptr - arg_convert >= sizeof (arg_convert) - 1) | 151 if (arg_ptr - arg_convert >= sizeof (arg_convert) - 1) |
150 error ("Format converter number too large"); | 152 error ("Format converter number too large"); |
169 static printf_spec_dynarr * | 171 static printf_spec_dynarr * |
170 parse_doprnt_spec (CONST Bufbyte *format, Bytecount format_length) | 172 parse_doprnt_spec (CONST Bufbyte *format, Bytecount format_length) |
171 { | 173 { |
172 CONST Bufbyte *fmt = format; | 174 CONST Bufbyte *fmt = format; |
173 CONST Bufbyte *fmt_end = format + format_length; | 175 CONST Bufbyte *fmt_end = format + format_length; |
174 printf_spec_dynarr *specs = Dynarr_new (struct printf_spec); | 176 printf_spec_dynarr *specs = Dynarr_new (printf_spec); |
175 int prev_argnum = 0; | 177 int prev_argnum = 0; |
176 | 178 |
177 while (1) | 179 while (1) |
178 { | 180 { |
179 struct printf_spec spec; | 181 struct printf_spec spec; |
233 case '0': spec.zero_flag = 1; break; | 235 case '0': spec.zero_flag = 1; break; |
234 default: abort (); | 236 default: abort (); |
235 } | 237 } |
236 NEXT_ASCII_BYTE (ch); | 238 NEXT_ASCII_BYTE (ch); |
237 } | 239 } |
238 | 240 |
239 /* Parse off the minimum field width */ | 241 /* Parse off the minimum field width */ |
240 fmt--; /* back up */ | 242 fmt--; /* back up */ |
241 fmt = parse_off_posnum (fmt, fmt_end, &spec.minwidth); | 243 fmt = parse_off_posnum (fmt, fmt_end, &spec.minwidth); |
242 if (spec.minwidth == -1) | 244 if (spec.minwidth == -1) |
243 spec.minwidth = 0; | 245 spec.minwidth = 0; |
308 } | 310 } |
309 | 311 |
310 static printf_arg_dynarr * | 312 static printf_arg_dynarr * |
311 get_doprnt_args (printf_spec_dynarr *specs, va_list vargs) | 313 get_doprnt_args (printf_spec_dynarr *specs, va_list vargs) |
312 { | 314 { |
313 printf_arg_dynarr *args = Dynarr_new (union printf_arg); | 315 printf_arg_dynarr *args = Dynarr_new (printf_arg); |
314 union printf_arg arg; | 316 union printf_arg arg; |
315 REGISTER int i; | 317 REGISTER int i; |
316 int args_needed = get_args_needed (specs); | 318 int args_needed = get_args_needed (specs); |
317 | 319 |
318 memset (&arg, 0, sizeof (union printf_arg)); | 320 memset (&arg, 0, sizeof (union printf_arg)); |
377 to the arguments. */ | 379 to the arguments. */ |
378 | 380 |
379 static Bytecount | 381 static Bytecount |
380 emacs_doprnt_1 (Lisp_Object stream, CONST Bufbyte *format_nonreloc, | 382 emacs_doprnt_1 (Lisp_Object stream, CONST Bufbyte *format_nonreloc, |
381 Lisp_Object format_reloc, Bytecount format_length, | 383 Lisp_Object format_reloc, Bytecount format_length, |
382 int nargs, | 384 int nargs, |
383 /* #### Gag me, gag me, gag me */ | 385 /* #### Gag me, gag me, gag me */ |
384 CONST Lisp_Object *largs, va_list vargs) | 386 CONST Lisp_Object *largs, va_list vargs) |
385 { | 387 { |
386 printf_spec_dynarr *specs = 0; | 388 printf_spec_dynarr *specs = 0; |
387 printf_arg_dynarr *args = 0; | 389 printf_arg_dynarr *args = 0; |
443 Bytecount string_len; | 445 Bytecount string_len; |
444 | 446 |
445 if (!largs) | 447 if (!largs) |
446 { | 448 { |
447 string = Dynarr_at (args, spec->argnum - 1).bp; | 449 string = Dynarr_at (args, spec->argnum - 1).bp; |
450 /* error() can be called with null string arguments. | |
451 E.g., in fileio.c, the return value of strerror() | |
452 is never checked. We'll print (null), like some | |
453 printf implementations do. Would it be better (and safe) | |
454 to signal an error instead? Or should we just use the | |
455 empty string? -dkindred@cs.cmu.edu 8/1997 | |
456 */ | |
457 if (!string) | |
458 string = "(null)"; | |
448 string_len = strlen ((char *) string); | 459 string_len = strlen ((char *) string); |
449 } | 460 } |
450 else | 461 else |
451 { | 462 { |
452 Lisp_Object obj = largs[spec->argnum - 1]; | 463 Lisp_Object obj = largs[spec->argnum - 1]; |
530 | 541 |
531 if (spec->l_flag) | 542 if (spec->l_flag) |
532 a = (Emchar) arg.l; | 543 a = (Emchar) arg.l; |
533 else | 544 else |
534 a = (Emchar) arg.i; | 545 a = (Emchar) arg.i; |
535 | 546 |
536 if (!valid_char_p (a)) | 547 if (!valid_char_p (a)) |
537 error ("invalid character value %d to %%c spec", a); | 548 error ("invalid character value %d to %%c spec", a); |
538 | 549 |
539 charlen = set_charptr_emchar (charbuf, a); | 550 charlen = set_charptr_emchar (charbuf, a); |
540 doprnt_1 (stream, charbuf, charlen, spec->minwidth, | 551 doprnt_1 (stream, charbuf, charlen, spec->minwidth, |
688 Bytecount | 699 Bytecount |
689 emacs_doprnt_lisp_2 (Lisp_Object stream, CONST Bufbyte *format_nonreloc, | 700 emacs_doprnt_lisp_2 (Lisp_Object stream, CONST Bufbyte *format_nonreloc, |
690 Lisp_Object format_reloc, Bytecount format_length, | 701 Lisp_Object format_reloc, Bytecount format_length, |
691 int nargs, ...) | 702 int nargs, ...) |
692 { | 703 { |
693 Lisp_Object *foo; | |
694 va_list vargs; | 704 va_list vargs; |
695 int i; | 705 int i; |
696 | 706 Lisp_Object *foo = alloca_array (Lisp_Object, nargs); |
697 foo = (Lisp_Object *) alloca (nargs * sizeof (Lisp_Object)); | 707 |
698 va_start (vargs, nargs); | 708 va_start (vargs, nargs); |
699 for (i = 0; i < nargs; i++) | 709 for (i = 0; i < nargs; i++) |
700 foo[i] = va_arg (vargs, Lisp_Object); | 710 foo[i] = va_arg (vargs, Lisp_Object); |
701 va_end (vargs); | 711 va_end (vargs); |
702 | 712 |
703 return emacs_doprnt_2 (stream, format_nonreloc, format_reloc, | 713 return emacs_doprnt_2 (stream, format_nonreloc, format_reloc, |
704 format_length, nargs, foo); | 714 format_length, nargs, foo); |
705 } | 715 } |
706 | 716 |
707 /* The following four functions work like the above three but | 717 /* The following four functions work like the above three but |
780 int nargs, ...) | 790 int nargs, ...) |
781 { | 791 { |
782 Lisp_Object obj; | 792 Lisp_Object obj; |
783 Lisp_Object stream = make_resizing_buffer_output_stream (); | 793 Lisp_Object stream = make_resizing_buffer_output_stream (); |
784 struct gcpro gcpro1; | 794 struct gcpro gcpro1; |
785 Lisp_Object *foo; | |
786 va_list vargs; | 795 va_list vargs; |
787 int i; | 796 int i; |
788 | 797 Lisp_Object *foo = alloca_array (Lisp_Object, nargs); |
789 foo = (Lisp_Object *) alloca (nargs * sizeof (Lisp_Object)); | 798 |
790 va_start (vargs, nargs); | 799 va_start (vargs, nargs); |
791 for (i = 0; i < nargs; i++) | 800 for (i = 0; i < nargs; i++) |
792 foo[i] = va_arg (vargs, Lisp_Object); | 801 foo[i] = va_arg (vargs, Lisp_Object); |
793 va_end (vargs); | 802 va_end (vargs); |
794 | 803 |
795 GCPRO1 (stream); | 804 GCPRO1 (stream); |
796 emacs_doprnt_2 (stream, format_nonreloc, format_reloc, | 805 emacs_doprnt_2 (stream, format_nonreloc, format_reloc, |
797 format_length, nargs, foo); | 806 format_length, nargs, foo); |
798 Lstream_flush (XLSTREAM (stream)); | 807 Lstream_flush (XLSTREAM (stream)); |
799 obj = make_string (resizing_buffer_stream_ptr (XLSTREAM (stream)), | 808 obj = make_string (resizing_buffer_stream_ptr (XLSTREAM (stream)), |