comparison src/doprnt.c @ 398:74fd4e045ea6 r21-2-29

Import from CVS: tag r21-2-29
author cvs
date Mon, 13 Aug 2007 11:13:30 +0200
parents 8626e4521993
children de805c49cfc1
comparison
equal deleted inserted replaced
397:f4aeb21a5bad 398:74fd4e045ea6
29 #include "lisp.h" 29 #include "lisp.h"
30 30
31 #include "buffer.h" 31 #include "buffer.h"
32 #include "lstream.h" 32 #include "lstream.h"
33 33
34 static CONST char *valid_flags = "-+ #0"; 34 static const char *valid_flags = "-+ #0";
35 35
36 static CONST char *valid_converters = "diouxXfeEgGcsS"; 36 static const char *valid_converters = "diouxXfeEgGcsS";
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 typedef struct printf_spec printf_spec;
43 struct printf_spec 43 struct printf_spec
44 { 44 {
45 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:
97 truncated to that many character. 97 truncated to that many character.
98 98
99 Note that MINLEN and MAXLEN are Charcounts but LEN is a Bytecount. */ 99 Note that MINLEN and MAXLEN are Charcounts but LEN is a Bytecount. */
100 100
101 static void 101 static void
102 doprnt_1 (Lisp_Object stream, CONST Bufbyte *string, Bytecount len, 102 doprnt_1 (Lisp_Object stream, const Bufbyte *string, Bytecount len,
103 Charcount minlen, Charcount maxlen, int minus_flag, int zero_flag) 103 Charcount minlen, Charcount maxlen, int minus_flag, int zero_flag)
104 { 104 {
105 Charcount cclen; 105 Charcount cclen;
106 Bufbyte pad; 106 Bufbyte pad;
107 Lstream *lstr = XLSTREAM (stream); 107 Lstream *lstr = XLSTREAM (stream);
138 to_add--; 138 to_add--;
139 } 139 }
140 } 140 }
141 } 141 }
142 142
143 static CONST Bufbyte * 143 static const Bufbyte *
144 parse_off_posnum (CONST Bufbyte *start, CONST Bufbyte *end, int *returned_num) 144 parse_off_posnum (const Bufbyte *start, const Bufbyte *end, int *returned_num)
145 { 145 {
146 Bufbyte arg_convert[100]; 146 Bufbyte arg_convert[100];
147 REGISTER Bufbyte *arg_ptr = arg_convert; 147 REGISTER Bufbyte *arg_ptr = arg_convert;
148 148
149 *returned_num = -1; 149 *returned_num = -1;
176 if (spec.zero_flag && spec.space_flag) \ 176 if (spec.zero_flag && spec.space_flag) \
177 spec.zero_flag = 0; \ 177 spec.zero_flag = 0; \
178 } while (0) 178 } while (0)
179 179
180 static printf_spec_dynarr * 180 static printf_spec_dynarr *
181 parse_doprnt_spec (CONST Bufbyte *format, Bytecount format_length) 181 parse_doprnt_spec (const Bufbyte *format, Bytecount format_length)
182 { 182 {
183 CONST Bufbyte *fmt = format; 183 const Bufbyte *fmt = format;
184 CONST Bufbyte *fmt_end = format + format_length; 184 const Bufbyte *fmt_end = format + format_length;
185 printf_spec_dynarr *specs = Dynarr_new (printf_spec); 185 printf_spec_dynarr *specs = Dynarr_new (printf_spec);
186 int prev_argnum = 0; 186 int prev_argnum = 0;
187 187
188 while (1) 188 while (1)
189 { 189 {
190 struct printf_spec spec; 190 struct printf_spec spec;
191 CONST Bufbyte *text_end; 191 const Bufbyte *text_end;
192 Bufbyte ch; 192 Bufbyte ch;
193 193
194 xzero (spec); 194 xzero (spec);
195 if (fmt == fmt_end) 195 if (fmt == fmt_end)
196 return specs; 196 return specs;
214 continue; 214 continue;
215 } 215 }
216 216
217 /* Is there a field number specifier? */ 217 /* Is there a field number specifier? */
218 { 218 {
219 CONST Bufbyte *ptr; 219 const Bufbyte *ptr;
220 int fieldspec; 220 int fieldspec;
221 221
222 ptr = parse_off_posnum (fmt, fmt_end, &fieldspec); 222 ptr = parse_off_posnum (fmt, fmt_end, &fieldspec);
223 if (fieldspec > 0 && ptr != fmt_end && *ptr == '$') 223 if (fieldspec > 0 && ptr != fmt_end && *ptr == '$')
224 { 224 {
384 match the actual type **after default promotions**." */ 384 match the actual type **after default promotions**." */
385 385
386 if (strchr (int_converters, ch)) 386 if (strchr (int_converters, ch))
387 { 387 {
388 if (spec->h_flag) 388 if (spec->h_flag)
389 arg.i = va_arg (vargs, short); 389 arg.i = va_arg (vargs, int /* short */);
390 else if (spec->l_flag) 390 else if (spec->l_flag)
391 arg.l = va_arg (vargs, long); 391 arg.l = va_arg (vargs, long);
392 else 392 else
393 arg.i = va_arg (vargs, int); 393 arg.i = va_arg (vargs, int);
394 } 394 }
395 else if (strchr (unsigned_int_converters, ch)) 395 else if (strchr (unsigned_int_converters, ch))
396 { 396 {
397 if (spec->h_flag) 397 if (spec->h_flag)
398 arg.ui = va_arg (vargs, unsigned short); 398 arg.ui = va_arg (vargs, unsigned int /* unsigned short */);
399 else if (spec->l_flag) 399 else if (spec->l_flag)
400 arg.ul = va_arg (vargs, unsigned long); 400 arg.ul = va_arg (vargs, unsigned long);
401 else 401 else
402 arg.ui = va_arg (vargs, unsigned int); 402 arg.ui = va_arg (vargs, unsigned int);
403 } 403 }
421 if LARGS is non-zero, it should be a pointer to NARGS worth of 421 if LARGS is non-zero, it should be a pointer to NARGS worth of
422 Lisp arguments. Otherwise, VARGS should be a va_list referring 422 Lisp arguments. Otherwise, VARGS should be a va_list referring
423 to the arguments. */ 423 to the arguments. */
424 424
425 static Bytecount 425 static Bytecount
426 emacs_doprnt_1 (Lisp_Object stream, CONST Bufbyte *format_nonreloc, 426 emacs_doprnt_1 (Lisp_Object stream, const Bufbyte *format_nonreloc,
427 Lisp_Object format_reloc, Bytecount format_length, 427 Lisp_Object format_reloc, Bytecount format_length,
428 int nargs, 428 int nargs,
429 /* #### Gag me, gag me, gag me */ 429 /* #### Gag me, gag me, gag me */
430 CONST Lisp_Object *largs, va_list vargs) 430 const Lisp_Object *largs, va_list vargs)
431 { 431 {
432 printf_spec_dynarr *specs = 0; 432 printf_spec_dynarr *specs = 0;
433 printf_arg_dynarr *args = 0; 433 printf_arg_dynarr *args = 0;
434 REGISTER int i; 434 REGISTER int i;
435 int init_byte_count = Lstream_byte_count (XLSTREAM (stream)); 435 int init_byte_count = Lstream_byte_count (XLSTREAM (stream));
438 { 438 {
439 format_nonreloc = XSTRING_DATA (format_reloc); 439 format_nonreloc = XSTRING_DATA (format_reloc);
440 format_length = XSTRING_LENGTH (format_reloc); 440 format_length = XSTRING_LENGTH (format_reloc);
441 } 441 }
442 if (format_length < 0) 442 if (format_length < 0)
443 format_length = (Bytecount) strlen ((CONST char *) format_nonreloc); 443 format_length = (Bytecount) strlen ((const char *) format_nonreloc);
444 444
445 specs = parse_doprnt_spec (format_nonreloc, format_length); 445 specs = parse_doprnt_spec (format_nonreloc, format_length);
446 if (largs) 446 if (largs)
447 { 447 {
448 /* allow too many args for string, but not too few */ 448 /* allow too many args for string, but not too few */
536 string_len = strlen ((char *) string); 536 string_len = strlen ((char *) string);
537 } 537 }
538 else 538 else
539 { 539 {
540 Lisp_Object obj = largs[spec->argnum - 1]; 540 Lisp_Object obj = largs[spec->argnum - 1];
541 struct Lisp_String *ls; 541 Lisp_String *ls;
542 542
543 if (ch == 'S') 543 if (ch == 'S')
544 { 544 {
545 /* For `S', prin1 the argument and then treat like 545 /* For `S', prin1 the argument and then treat like
546 a string. */ 546 a string. */
695 return Lstream_byte_count (XLSTREAM (stream)) - init_byte_count; 695 return Lstream_byte_count (XLSTREAM (stream)) - init_byte_count;
696 } 696 }
697 697
698 /* You really don't want to know why this is necessary... */ 698 /* You really don't want to know why this is necessary... */
699 static Bytecount 699 static Bytecount
700 emacs_doprnt_2 (Lisp_Object stream, CONST Bufbyte *format_nonreloc, 700 emacs_doprnt_2 (Lisp_Object stream, const Bufbyte *format_nonreloc,
701 Lisp_Object format_reloc, Bytecount format_length, int nargs, 701 Lisp_Object format_reloc, Bytecount format_length, int nargs,
702 CONST Lisp_Object *largs, ...) 702 const Lisp_Object *largs, ...)
703 { 703 {
704 va_list vargs; 704 va_list vargs;
705 Bytecount val; 705 Bytecount val;
706 va_start (vargs, largs); 706 va_start (vargs, largs);
707 val = emacs_doprnt_1 (stream, format_nonreloc, format_reloc, 707 val = emacs_doprnt_1 (stream, format_nonreloc, format_reloc,
730 730
731 DO NOT pass the data from a Lisp string as the FORMAT_NONRELOC 731 DO NOT pass the data from a Lisp string as the FORMAT_NONRELOC
732 parameter, because this function can cause GC. */ 732 parameter, because this function can cause GC. */
733 733
734 Bytecount 734 Bytecount
735 emacs_doprnt_c (Lisp_Object stream, CONST Bufbyte *format_nonreloc, 735 emacs_doprnt_c (Lisp_Object stream, const Bufbyte *format_nonreloc,
736 Lisp_Object format_reloc, Bytecount format_length, 736 Lisp_Object format_reloc, Bytecount format_length,
737 ...) 737 ...)
738 { 738 {
739 int val; 739 int val;
740 va_list vargs; 740 va_list vargs;
747 } 747 }
748 748
749 /* Like emacs_doprnt_c but the args come in va_list format. */ 749 /* Like emacs_doprnt_c but the args come in va_list format. */
750 750
751 Bytecount 751 Bytecount
752 emacs_doprnt_va (Lisp_Object stream, CONST Bufbyte *format_nonreloc, 752 emacs_doprnt_va (Lisp_Object stream, const Bufbyte *format_nonreloc,
753 Lisp_Object format_reloc, Bytecount format_length, 753 Lisp_Object format_reloc, Bytecount format_length,
754 va_list vargs) 754 va_list vargs)
755 { 755 {
756 return emacs_doprnt_1 (stream, format_nonreloc, format_reloc, 756 return emacs_doprnt_1 (stream, format_nonreloc, format_reloc,
757 format_length, 0, 0, vargs); 757 format_length, 0, 0, vargs);
761 C arguments. This causes somewhat different behavior from 761 C arguments. This causes somewhat different behavior from
762 the above two functions (which should act like printf). 762 the above two functions (which should act like printf).
763 See `format' for a description of this behavior. */ 763 See `format' for a description of this behavior. */
764 764
765 Bytecount 765 Bytecount
766 emacs_doprnt_lisp (Lisp_Object stream, CONST Bufbyte *format_nonreloc, 766 emacs_doprnt_lisp (Lisp_Object stream, const Bufbyte *format_nonreloc,
767 Lisp_Object format_reloc, Bytecount format_length, 767 Lisp_Object format_reloc, Bytecount format_length,
768 int nargs, CONST Lisp_Object *largs) 768 int nargs, const Lisp_Object *largs)
769 { 769 {
770 return emacs_doprnt_2 (stream, format_nonreloc, format_reloc, 770 return emacs_doprnt_2 (stream, format_nonreloc, format_reloc,
771 format_length, nargs, largs); 771 format_length, nargs, largs);
772 } 772 }
773 773
774 /* Like the previous function but takes a variable number of arguments. */ 774 /* Like the previous function but takes a variable number of arguments. */
775 775
776 Bytecount 776 Bytecount
777 emacs_doprnt_lisp_2 (Lisp_Object stream, CONST Bufbyte *format_nonreloc, 777 emacs_doprnt_lisp_2 (Lisp_Object stream, const Bufbyte *format_nonreloc,
778 Lisp_Object format_reloc, Bytecount format_length, 778 Lisp_Object format_reloc, Bytecount format_length,
779 int nargs, ...) 779 int nargs, ...)
780 { 780 {
781 va_list vargs; 781 va_list vargs;
782 int i; 782 int i;
794 /* The following four functions work like the above three but 794 /* The following four functions work like the above three but
795 return their output as a Lisp string instead of sending it 795 return their output as a Lisp string instead of sending it
796 to a stream. */ 796 to a stream. */
797 797
798 Lisp_Object 798 Lisp_Object
799 emacs_doprnt_string_c (CONST Bufbyte *format_nonreloc, 799 emacs_doprnt_string_c (const Bufbyte *format_nonreloc,
800 Lisp_Object format_reloc, Bytecount format_length, 800 Lisp_Object format_reloc, Bytecount format_length,
801 ...) 801 ...)
802 { 802 {
803 va_list vargs; 803 va_list vargs;
804 Lisp_Object obj; 804 Lisp_Object obj;
817 Lstream_delete (XLSTREAM (stream)); 817 Lstream_delete (XLSTREAM (stream));
818 return obj; 818 return obj;
819 } 819 }
820 820
821 Lisp_Object 821 Lisp_Object
822 emacs_doprnt_string_va (CONST Bufbyte *format_nonreloc, 822 emacs_doprnt_string_va (const Bufbyte *format_nonreloc,
823 Lisp_Object format_reloc, Bytecount format_length, 823 Lisp_Object format_reloc, Bytecount format_length,
824 va_list vargs) 824 va_list vargs)
825 { 825 {
826 /* I'm fairly sure that this function cannot actually GC. 826 /* I'm fairly sure that this function cannot actually GC.
827 That can only happen when the arguments to emacs_doprnt_1() are 827 That can only happen when the arguments to emacs_doprnt_1() are
840 Lstream_delete (XLSTREAM (stream)); 840 Lstream_delete (XLSTREAM (stream));
841 return obj; 841 return obj;
842 } 842 }
843 843
844 Lisp_Object 844 Lisp_Object
845 emacs_doprnt_string_lisp (CONST Bufbyte *format_nonreloc, 845 emacs_doprnt_string_lisp (const Bufbyte *format_nonreloc,
846 Lisp_Object format_reloc, Bytecount format_length, 846 Lisp_Object format_reloc, Bytecount format_length,
847 int nargs, CONST Lisp_Object *largs) 847 int nargs, const Lisp_Object *largs)
848 { 848 {
849 Lisp_Object obj; 849 Lisp_Object obj;
850 Lisp_Object stream = make_resizing_buffer_output_stream (); 850 Lisp_Object stream = make_resizing_buffer_output_stream ();
851 struct gcpro gcpro1; 851 struct gcpro gcpro1;
852 852
860 Lstream_delete (XLSTREAM (stream)); 860 Lstream_delete (XLSTREAM (stream));
861 return obj; 861 return obj;
862 } 862 }
863 863
864 Lisp_Object 864 Lisp_Object
865 emacs_doprnt_string_lisp_2 (CONST Bufbyte *format_nonreloc, 865 emacs_doprnt_string_lisp_2 (const Bufbyte *format_nonreloc,
866 Lisp_Object format_reloc, Bytecount format_length, 866 Lisp_Object format_reloc, Bytecount format_length,
867 int nargs, ...) 867 int nargs, ...)
868 { 868 {
869 Lisp_Object obj; 869 Lisp_Object obj;
870 Lisp_Object stream = make_resizing_buffer_output_stream (); 870 Lisp_Object stream = make_resizing_buffer_output_stream ();