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)),