comparison src/doprnt.c @ 665:fdefd0186b75

[xemacs-hg @ 2001-09-20 06:28:42 by ben] The great integral types renaming. The purpose of this is to rationalize the names used for various integral types, so that they match their intended uses and follow consist conventions, and eliminate types that were not semantically different from each other. The conventions are: -- All integral types that measure quantities of anything are signed. Some people disagree vociferously with this, but their arguments are mostly theoretical, and are vastly outweighed by the practical headaches of mixing signed and unsigned values, and more importantly by the far increased likelihood of inadvertent bugs: Because of the broken "viral" nature of unsigned quantities in C (operations involving mixed signed/unsigned are done unsigned, when exactly the opposite is nearly always wanted), even a single error in declaring a quantity unsigned that should be signed, or even the even more subtle error of comparing signed and unsigned values and forgetting the necessary cast, can be catastrophic, as comparisons will yield wrong results. -Wsign-compare is turned on specifically to catch this, but this tends to result in a great number of warnings when mixing signed and unsigned, and the casts are annoying. More has been written on this elsewhere. -- All such quantity types just mentioned boil down to EMACS_INT, which is 32 bits on 32-bit machines and 64 bits on 64-bit machines. This is guaranteed to be the same size as Lisp objects of type `int', and (as far as I can tell) of size_t (unsigned!) and ssize_t. The only type below that is not an EMACS_INT is Hashcode, which is an unsigned value of the same size as EMACS_INT. -- Type names should be relatively short (no more than 10 characters or so), with the first letter capitalized and no underscores if they can at all be avoided. -- "count" == a zero-based measurement of some quantity. Includes sizes, offsets, and indexes. -- "bpos" == a one-based measurement of a position in a buffer. "Charbpos" and "Bytebpos" count text in the buffer, rather than bytes in memory; thus Bytebpos does not directly correspond to the memory representation. Use "Membpos" for this. -- "Char" refers to internal-format characters, not to the C type "char", which is really a byte. -- For the actual name changes, see the script below. I ran the following script to do the conversion. (NOTE: This script is idempotent. You can safely run it multiple times and it will not screw up previous results -- in fact, it will do nothing if nothing has changed. Thus, it can be run repeatedly as necessary to handle patches coming in from old workspaces, or old branches.) There are two tags, just before and just after the change: `pre-integral-type-rename' and `post-integral-type-rename'. When merging code from the main trunk into a branch, the best thing to do is first merge up to `pre-integral-type-rename', then apply the script and associated changes, then merge from `post-integral-type-change' to the present. (Alternatively, just do the merging in one operation; but you may then have a lot of conflicts needing to be resolved by hand.) Script `fixtypes.sh' follows: ----------------------------------- cut ------------------------------------ files="*.[ch] s/*.h m/*.h config.h.in ../configure.in Makefile.in.in ../lib-src/*.[ch] ../lwlib/*.[ch]" gr Memory_Count Bytecount $files gr Lstream_Data_Count Bytecount $files gr Element_Count Elemcount $files gr Hash_Code Hashcode $files gr extcount bytecount $files gr bufpos charbpos $files gr bytind bytebpos $files gr memind membpos $files gr bufbyte intbyte $files gr Extcount Bytecount $files gr Bufpos Charbpos $files gr Bytind Bytebpos $files gr Memind Membpos $files gr Bufbyte Intbyte $files gr EXTCOUNT BYTECOUNT $files gr BUFPOS CHARBPOS $files gr BYTIND BYTEBPOS $files gr MEMIND MEMBPOS $files gr BUFBYTE INTBYTE $files gr MEMORY_COUNT BYTECOUNT $files gr LSTREAM_DATA_COUNT BYTECOUNT $files gr ELEMENT_COUNT ELEMCOUNT $files gr HASH_CODE HASHCODE $files ----------------------------------- cut ------------------------------------ `fixtypes.sh' is a Bourne-shell script; it uses 'gr': ----------------------------------- cut ------------------------------------ #!/bin/sh # Usage is like this: # gr FROM TO FILES ... # globally replace FROM with TO in FILES. FROM and TO are regular expressions. # backup files are stored in the `backup' directory. from="$1" to="$2" shift 2 echo ${1+"$@"} | xargs global-replace "s/$from/$to/g" ----------------------------------- cut ------------------------------------ `gr' in turn uses a Perl script to do its real work, `global-replace', which follows: ----------------------------------- cut ------------------------------------ : #-*- Perl -*- ### global-modify --- modify the contents of a file by a Perl expression ## Copyright (C) 1999 Martin Buchholz. ## Copyright (C) 2001 Ben Wing. ## Authors: Martin Buchholz <martin@xemacs.org>, Ben Wing <ben@xemacs.org> ## Maintainer: Ben Wing <ben@xemacs.org> ## Current Version: 1.0, May 5, 2001 # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with XEmacs; see the file COPYING. If not, write to the Free # Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. eval 'exec perl -w -S $0 ${1+"$@"}' if 0; use strict; use FileHandle; use Carp; use Getopt::Long; use File::Basename; (my $myName = $0) =~ s@.*/@@; my $usage=" Usage: $myName [--help] [--backup-dir=DIR] [--line-mode] [--hunk-mode] PERLEXPR FILE ... Globally modify a file, either line by line or in one big hunk. Typical usage is like this: [with GNU print, GNU xargs: guaranteed to handle spaces, quotes, etc. in file names] find . -name '*.[ch]' -print0 | xargs -0 $0 's/\bCONST\b/const/g'\n [with non-GNU print, xargs] find . -name '*.[ch]' -print | xargs $0 's/\bCONST\b/const/g'\n The file is read in, either line by line (with --line-mode specified) or in one big hunk (with --hunk-mode specified; it's the default), and the Perl expression is then evalled with \$_ set to the line or hunk of text, including the terminating newline if there is one. It should destructively modify the value there, storing the changed result in \$_. Files in which any modifications are made are backed up to the directory specified using --backup-dir, or to `backup' by default. To disable this, use --backup-dir= with no argument. Hunk mode is the default because it is MUCH MUCH faster than line-by-line. Use line-by-line only when it matters, e.g. you want to do a replacement only once per line (the default without the `g' argument). Conversely, when using hunk mode, *ALWAYS* use `g'; otherwise, you will only make one replacement in the entire file! "; my %options = (); $Getopt::Long::ignorecase = 0; &GetOptions ( \%options, 'help', 'backup-dir=s', 'line-mode', 'hunk-mode', ); die $usage if $options{"help"} or @ARGV <= 1; my $code = shift; die $usage if grep (-d || ! -w, @ARGV); sub SafeOpen { open ((my $fh = new FileHandle), $_[0]); confess "Can't open $_[0]: $!" if ! defined $fh; return $fh; } sub SafeClose { close $_[0] or confess "Can't close $_[0]: $!"; } sub FileContents { my $fh = SafeOpen ("< $_[0]"); my $olddollarslash = $/; local $/ = undef; my $contents = <$fh>; $/ = $olddollarslash; return $contents; } sub WriteStringToFile { my $fh = SafeOpen ("> $_[0]"); binmode $fh; print $fh $_[1] or confess "$_[0]: $!\n"; SafeClose $fh; } foreach my $file (@ARGV) { my $changed_p = 0; my $new_contents = ""; if ($options{"line-mode"}) { my $fh = SafeOpen $file; while (<$fh>) { my $save_line = $_; eval $code; $changed_p = 1 if $save_line ne $_; $new_contents .= $_; } } else { my $orig_contents = $_ = FileContents $file; eval $code; if ($_ ne $orig_contents) { $changed_p = 1; $new_contents = $_; } } if ($changed_p) { my $backdir = $options{"backup-dir"}; $backdir = "backup" if !defined ($backdir); if ($backdir) { my ($name, $path, $suffix) = fileparse ($file, ""); my $backfulldir = $path . $backdir; my $backfile = "$backfulldir/$name"; mkdir $backfulldir, 0755 unless -d $backfulldir; print "modifying $file (original saved in $backfile)\n"; rename $file, $backfile; } WriteStringToFile ($file, $new_contents); } } ----------------------------------- cut ------------------------------------ In addition to those programs, I needed to fix up a few other things, particularly relating to the duplicate definitions of types, now that some types merged with others. Specifically: 1. in lisp.h, removed duplicate declarations of Bytecount. The changed code should now look like this: (In each code snippet below, the first and last lines are the same as the original, as are all lines outside of those lines. That allows you to locate the section to be replaced, and replace the stuff in that section, verifying that there isn't anything new added that would need to be kept.) --------------------------------- snip ------------------------------------- /* Counts of bytes or chars */ typedef EMACS_INT Bytecount; typedef EMACS_INT Charcount; /* Counts of elements */ typedef EMACS_INT Elemcount; /* Hash codes */ typedef unsigned long Hashcode; /* ------------------------ dynamic arrays ------------------- */ --------------------------------- snip ------------------------------------- 2. in lstream.h, removed duplicate declaration of Bytecount. Rewrote the comment about this type. The changed code should now look like this: --------------------------------- snip ------------------------------------- #endif /* The have been some arguments over the what the type should be that specifies a count of bytes in a data block to be written out or read in, using Lstream_read(), Lstream_write(), and related functions. Originally it was long, which worked fine; Martin "corrected" these to size_t and ssize_t on the grounds that this is theoretically cleaner and is in keeping with the C standards. Unfortunately, this practice is horribly error-prone due to design flaws in the way that mixed signed/unsigned arithmetic happens. In fact, by doing this change, Martin introduced a subtle but fatal error that caused the operation of sending large mail messages to the SMTP server under Windows to fail. By putting all values back to be signed, avoiding any signed/unsigned mixing, the bug immediately went away. The type then in use was Lstream_Data_Count, so that it be reverted cleanly if a vote came to that. Now it is Bytecount. Some earlier comments about why the type must be signed: This MUST BE SIGNED, since it also is used in functions that return the number of bytes actually read to or written from in an operation, and these functions can return -1 to signal error. Note that the standard Unix read() and write() functions define the count going in as a size_t, which is UNSIGNED, and the count going out as an ssize_t, which is SIGNED. This is a horrible design flaw. Not only is it highly likely to lead to logic errors when a -1 gets interpreted as a large positive number, but operations are bound to fail in all sorts of horrible ways when a number in the upper-half of the size_t range is passed in -- this number is unrepresentable as an ssize_t, so code that checks to see how many bytes are actually written (which is mandatory if you are dealing with certain types of devices) will get completely screwed up. --ben */ typedef enum lstream_buffering --------------------------------- snip ------------------------------------- 3. in dumper.c, there are four places, all inside of switch() statements, where XD_BYTECOUNT appears twice as a case tag. In each case, the two case blocks contain identical code, and you should *REMOVE THE SECOND* and leave the first.
author ben
date Thu, 20 Sep 2001 06:31:11 +0000
parents b39c14581166
children 943eaba38521
comparison
equal deleted inserted replaced
664:6e99cc8c6ca5 665:fdefd0186b75
66 union printf_arg 66 union printf_arg
67 { 67 {
68 long l; 68 long l;
69 unsigned long ul; 69 unsigned long ul;
70 double d; 70 double d;
71 Bufbyte *bp; 71 Intbyte *bp;
72 }; 72 };
73 73
74 /* We maintain a list of all the % specs in the specification, 74 /* We maintain a list of all the % specs in the specification,
75 along with the offset and length of the block of literal text 75 along with the offset and length of the block of literal text
76 before each spec. In addition, we have a "dummy" spec that 76 before each spec. In addition, we have a "dummy" spec that
96 right to that many characters. 96 right to that many characters.
97 97
98 Note that MINLEN and MAXLEN are Charcounts but LEN is a Bytecount. */ 98 Note that MINLEN and MAXLEN are Charcounts but LEN is a Bytecount. */
99 99
100 static void 100 static void
101 doprnt_1 (Lisp_Object stream, const Bufbyte *string, Bytecount len, 101 doprnt_1 (Lisp_Object stream, const Intbyte *string, Bytecount len,
102 Charcount minlen, Charcount maxlen, int minus_flag, int zero_flag) 102 Charcount minlen, Charcount maxlen, int minus_flag, int zero_flag)
103 { 103 {
104 Lstream *lstr = XLSTREAM (stream); 104 Lstream *lstr = XLSTREAM (stream);
105 Charcount cclen = bytecount_to_charcount (string, len); 105 Charcount cclen = bytecount_to_charcount (string, len);
106 int to_add = minlen - cclen; 106 int to_add = minlen - cclen;
118 if (minus_flag) 118 if (minus_flag)
119 while (to_add-- > 0) 119 while (to_add-- > 0)
120 Lstream_putc (lstr, zero_flag ? '0' : ' '); 120 Lstream_putc (lstr, zero_flag ? '0' : ' ');
121 } 121 }
122 122
123 static const Bufbyte * 123 static const Intbyte *
124 parse_off_posnum (const Bufbyte *start, const Bufbyte *end, int *returned_num) 124 parse_off_posnum (const Intbyte *start, const Intbyte *end, int *returned_num)
125 { 125 {
126 Bufbyte arg_convert[100]; 126 Intbyte arg_convert[100];
127 REGISTER Bufbyte *arg_ptr = arg_convert; 127 REGISTER Intbyte *arg_ptr = arg_convert;
128 128
129 *returned_num = -1; 129 *returned_num = -1;
130 while (start != end && isdigit (*start)) 130 while (start != end && isdigit (*start))
131 { 131 {
132 if (arg_ptr - arg_convert >= (int) sizeof (arg_convert) - 1) 132 if (arg_ptr - arg_convert >= (int) sizeof (arg_convert) - 1)
156 if (spec.zero_flag && spec.space_flag) \ 156 if (spec.zero_flag && spec.space_flag) \
157 spec.zero_flag = 0; \ 157 spec.zero_flag = 0; \
158 } while (0) 158 } while (0)
159 159
160 static printf_spec_dynarr * 160 static printf_spec_dynarr *
161 parse_doprnt_spec (const Bufbyte *format, Bytecount format_length) 161 parse_doprnt_spec (const Intbyte *format, Bytecount format_length)
162 { 162 {
163 const Bufbyte *fmt = format; 163 const Intbyte *fmt = format;
164 const Bufbyte *fmt_end = format + format_length; 164 const Intbyte *fmt_end = format + format_length;
165 printf_spec_dynarr *specs = Dynarr_new (printf_spec); 165 printf_spec_dynarr *specs = Dynarr_new (printf_spec);
166 int prev_argnum = 0; 166 int prev_argnum = 0;
167 167
168 while (1) 168 while (1)
169 { 169 {
170 struct printf_spec spec; 170 struct printf_spec spec;
171 const Bufbyte *text_end; 171 const Intbyte *text_end;
172 Bufbyte ch; 172 Intbyte ch;
173 173
174 xzero (spec); 174 xzero (spec);
175 if (fmt == fmt_end) 175 if (fmt == fmt_end)
176 return specs; 176 return specs;
177 text_end = (Bufbyte *) memchr (fmt, '%', fmt_end - fmt); 177 text_end = (Intbyte *) memchr (fmt, '%', fmt_end - fmt);
178 if (!text_end) 178 if (!text_end)
179 text_end = fmt_end; 179 text_end = fmt_end;
180 spec.text_before = fmt - format; 180 spec.text_before = fmt - format;
181 spec.text_before_len = text_end - fmt; 181 spec.text_before_len = text_end - fmt;
182 fmt = text_end; 182 fmt = text_end;
194 continue; 194 continue;
195 } 195 }
196 196
197 /* Is there a field number specifier? */ 197 /* Is there a field number specifier? */
198 { 198 {
199 const Bufbyte *ptr; 199 const Intbyte *ptr;
200 int fieldspec; 200 int fieldspec;
201 201
202 ptr = parse_off_posnum (fmt, fmt_end, &fieldspec); 202 ptr = parse_off_posnum (fmt, fmt_end, &fieldspec);
203 if (fieldspec > 0 && ptr != fmt_end && *ptr == '$') 203 if (fieldspec > 0 && ptr != fmt_end && *ptr == '$')
204 { 204 {
380 arg.ul = (unsigned long) va_arg (vargs, unsigned int); 380 arg.ul = (unsigned long) va_arg (vargs, unsigned int);
381 } 381 }
382 else if (strchr (double_converters, ch)) 382 else if (strchr (double_converters, ch))
383 arg.d = va_arg (vargs, double); 383 arg.d = va_arg (vargs, double);
384 else if (strchr (string_converters, ch)) 384 else if (strchr (string_converters, ch))
385 arg.bp = va_arg (vargs, Bufbyte *); 385 arg.bp = va_arg (vargs, Intbyte *);
386 else abort (); 386 else abort ();
387 387
388 Dynarr_add (args, arg); 388 Dynarr_add (args, arg);
389 } 389 }
390 390
399 if LARGS is non-zero, it should be a pointer to NARGS worth of 399 if LARGS is non-zero, it should be a pointer to NARGS worth of
400 Lisp arguments. Otherwise, VARGS should be a va_list referring 400 Lisp arguments. Otherwise, VARGS should be a va_list referring
401 to the arguments. */ 401 to the arguments. */
402 402
403 static Bytecount 403 static Bytecount
404 emacs_doprnt_1 (Lisp_Object stream, const Bufbyte *format_nonreloc, 404 emacs_doprnt_1 (Lisp_Object stream, const Intbyte *format_nonreloc,
405 Lisp_Object format_reloc, Bytecount format_length, 405 Lisp_Object format_reloc, Bytecount format_length,
406 int nargs, 406 int nargs,
407 /* #### Gag me, gag me, gag me */ 407 /* #### Gag me, gag me, gag me */
408 const Lisp_Object *largs, va_list vargs) 408 const Lisp_Object *largs, va_list vargs)
409 { 409 {
453 if (!ch) 453 if (!ch)
454 continue; 454 continue;
455 455
456 if (ch == '%') 456 if (ch == '%')
457 { 457 {
458 doprnt_1 (stream, (Bufbyte *) &ch, 1, 0, -1, 0, 0); 458 doprnt_1 (stream, (Intbyte *) &ch, 1, 0, -1, 0, 0);
459 continue; 459 continue;
460 } 460 }
461 461
462 /* The char '*' as converter means the field width, precision 462 /* The char '*' as converter means the field width, precision
463 was specified as an argument. Extract the data and forward 463 was specified as an argument. Extract the data and forward
495 if (largs && (spec->argnum < 1 || spec->argnum > nargs)) 495 if (largs && (spec->argnum < 1 || spec->argnum > nargs))
496 syntax_error ("Invalid repositioning argument", make_int (spec->argnum)); 496 syntax_error ("Invalid repositioning argument", make_int (spec->argnum));
497 497
498 else if (ch == 'S' || ch == 's') 498 else if (ch == 'S' || ch == 's')
499 { 499 {
500 Bufbyte *string; 500 Intbyte *string;
501 Bytecount string_len; 501 Bytecount string_len;
502 502
503 if (!largs) 503 if (!largs)
504 { 504 {
505 string = Dynarr_at (args, spec->argnum - 1).bp; 505 string = Dynarr_at (args, spec->argnum - 1).bp;
509 printf implementations do. Would it be better (and safe) 509 printf implementations do. Would it be better (and safe)
510 to signal an error instead? Or should we just use the 510 to signal an error instead? Or should we just use the
511 empty string? -dkindred@cs.cmu.edu 8/1997 511 empty string? -dkindred@cs.cmu.edu 8/1997
512 */ 512 */
513 if (!string) 513 if (!string)
514 string = (Bufbyte *) "(null)"; 514 string = (Intbyte *) "(null)";
515 string_len = strlen ((char *) string); 515 string_len = strlen ((char *) string);
516 } 516 }
517 else 517 else
518 { 518 {
519 Lisp_Object obj = largs[spec->argnum - 1]; 519 Lisp_Object obj = largs[spec->argnum - 1];
578 578
579 if (ch == 'c') 579 if (ch == 'c')
580 { 580 {
581 Emchar a; 581 Emchar a;
582 Bytecount charlen; 582 Bytecount charlen;
583 Bufbyte charbuf[MAX_EMCHAR_LEN]; 583 Intbyte charbuf[MAX_EMCHAR_LEN];
584 584
585 a = (Emchar) arg.l; 585 a = (Emchar) arg.l;
586 586
587 if (!valid_char_p (a)) 587 if (!valid_char_p (a))
588 syntax_error ("invalid character value %d to %%c spec", make_char (a)); 588 syntax_error ("invalid character value %d to %%c spec", make_char (a));
642 sprintf (text_to_print, constructed_spec, arg.ul); 642 sprintf (text_to_print, constructed_spec, arg.ul);
643 else 643 else
644 sprintf (text_to_print, constructed_spec, arg.l); 644 sprintf (text_to_print, constructed_spec, arg.l);
645 } 645 }
646 646
647 doprnt_1 (stream, (Bufbyte *) text_to_print, 647 doprnt_1 (stream, (Intbyte *) text_to_print,
648 strlen (text_to_print), 0, -1, 0, 0); 648 strlen (text_to_print), 0, -1, 0, 0);
649 } 649 }
650 } 650 }
651 } 651 }
652 652
658 return Lstream_byte_count (XLSTREAM (stream)) - init_byte_count; 658 return Lstream_byte_count (XLSTREAM (stream)) - init_byte_count;
659 } 659 }
660 660
661 /* You really don't want to know why this is necessary... */ 661 /* You really don't want to know why this is necessary... */
662 static Bytecount 662 static Bytecount
663 emacs_doprnt_2 (Lisp_Object stream, const Bufbyte *format_nonreloc, 663 emacs_doprnt_2 (Lisp_Object stream, const Intbyte *format_nonreloc,
664 Lisp_Object format_reloc, Bytecount format_length, int nargs, 664 Lisp_Object format_reloc, Bytecount format_length, int nargs,
665 const Lisp_Object *largs, ...) 665 const Lisp_Object *largs, ...)
666 { 666 {
667 va_list vargs; 667 va_list vargs;
668 Bytecount val; 668 Bytecount val;
693 693
694 DO NOT pass the data from a Lisp string as the FORMAT_NONRELOC 694 DO NOT pass the data from a Lisp string as the FORMAT_NONRELOC
695 parameter, because this function can cause GC. */ 695 parameter, because this function can cause GC. */
696 696
697 Bytecount 697 Bytecount
698 emacs_doprnt_c (Lisp_Object stream, const Bufbyte *format_nonreloc, 698 emacs_doprnt_c (Lisp_Object stream, const Intbyte *format_nonreloc,
699 Lisp_Object format_reloc, Bytecount format_length, 699 Lisp_Object format_reloc, Bytecount format_length,
700 ...) 700 ...)
701 { 701 {
702 int val; 702 int val;
703 va_list vargs; 703 va_list vargs;
710 } 710 }
711 711
712 /* Like emacs_doprnt_c but the args come in va_list format. */ 712 /* Like emacs_doprnt_c but the args come in va_list format. */
713 713
714 Bytecount 714 Bytecount
715 emacs_doprnt_va (Lisp_Object stream, const Bufbyte *format_nonreloc, 715 emacs_doprnt_va (Lisp_Object stream, const Intbyte *format_nonreloc,
716 Lisp_Object format_reloc, Bytecount format_length, 716 Lisp_Object format_reloc, Bytecount format_length,
717 va_list vargs) 717 va_list vargs)
718 { 718 {
719 return emacs_doprnt_1 (stream, format_nonreloc, format_reloc, 719 return emacs_doprnt_1 (stream, format_nonreloc, format_reloc,
720 format_length, 0, 0, vargs); 720 format_length, 0, 0, vargs);
724 C arguments. This causes somewhat different behavior from 724 C arguments. This causes somewhat different behavior from
725 the above two functions (which should act like printf). 725 the above two functions (which should act like printf).
726 See `format' for a description of this behavior. */ 726 See `format' for a description of this behavior. */
727 727
728 Bytecount 728 Bytecount
729 emacs_doprnt_lisp (Lisp_Object stream, const Bufbyte *format_nonreloc, 729 emacs_doprnt_lisp (Lisp_Object stream, const Intbyte *format_nonreloc,
730 Lisp_Object format_reloc, Bytecount format_length, 730 Lisp_Object format_reloc, Bytecount format_length,
731 int nargs, const Lisp_Object *largs) 731 int nargs, const Lisp_Object *largs)
732 { 732 {
733 return emacs_doprnt_2 (stream, format_nonreloc, format_reloc, 733 return emacs_doprnt_2 (stream, format_nonreloc, format_reloc,
734 format_length, nargs, largs); 734 format_length, nargs, largs);
735 } 735 }
736 736
737 /* Like the previous function but takes a variable number of arguments. */ 737 /* Like the previous function but takes a variable number of arguments. */
738 738
739 Bytecount 739 Bytecount
740 emacs_doprnt_lisp_2 (Lisp_Object stream, const Bufbyte *format_nonreloc, 740 emacs_doprnt_lisp_2 (Lisp_Object stream, const Intbyte *format_nonreloc,
741 Lisp_Object format_reloc, Bytecount format_length, 741 Lisp_Object format_reloc, Bytecount format_length,
742 int nargs, ...) 742 int nargs, ...)
743 { 743 {
744 va_list vargs; 744 va_list vargs;
745 int i; 745 int i;
757 /* The following four functions work like the above three but 757 /* The following four functions work like the above three but
758 return their output as a Lisp string instead of sending it 758 return their output as a Lisp string instead of sending it
759 to a stream. */ 759 to a stream. */
760 760
761 Lisp_Object 761 Lisp_Object
762 emacs_doprnt_string_c (const Bufbyte *format_nonreloc, 762 emacs_doprnt_string_c (const Intbyte *format_nonreloc,
763 Lisp_Object format_reloc, Bytecount format_length, 763 Lisp_Object format_reloc, Bytecount format_length,
764 ...) 764 ...)
765 { 765 {
766 va_list vargs; 766 va_list vargs;
767 Lisp_Object obj; 767 Lisp_Object obj;
780 Lstream_delete (XLSTREAM (stream)); 780 Lstream_delete (XLSTREAM (stream));
781 return obj; 781 return obj;
782 } 782 }
783 783
784 Lisp_Object 784 Lisp_Object
785 emacs_doprnt_string_va (const Bufbyte *format_nonreloc, 785 emacs_doprnt_string_va (const Intbyte *format_nonreloc,
786 Lisp_Object format_reloc, Bytecount format_length, 786 Lisp_Object format_reloc, Bytecount format_length,
787 va_list vargs) 787 va_list vargs)
788 { 788 {
789 /* I'm fairly sure that this function cannot actually GC. 789 /* I'm fairly sure that this function cannot actually GC.
790 That can only happen when the arguments to emacs_doprnt_1() are 790 That can only happen when the arguments to emacs_doprnt_1() are
803 Lstream_delete (XLSTREAM (stream)); 803 Lstream_delete (XLSTREAM (stream));
804 return obj; 804 return obj;
805 } 805 }
806 806
807 Lisp_Object 807 Lisp_Object
808 emacs_doprnt_string_lisp (const Bufbyte *format_nonreloc, 808 emacs_doprnt_string_lisp (const Intbyte *format_nonreloc,
809 Lisp_Object format_reloc, Bytecount format_length, 809 Lisp_Object format_reloc, Bytecount format_length,
810 int nargs, const Lisp_Object *largs) 810 int nargs, const Lisp_Object *largs)
811 { 811 {
812 Lisp_Object obj; 812 Lisp_Object obj;
813 Lisp_Object stream = make_resizing_buffer_output_stream (); 813 Lisp_Object stream = make_resizing_buffer_output_stream ();
823 Lstream_delete (XLSTREAM (stream)); 823 Lstream_delete (XLSTREAM (stream));
824 return obj; 824 return obj;
825 } 825 }
826 826
827 Lisp_Object 827 Lisp_Object
828 emacs_doprnt_string_lisp_2 (const Bufbyte *format_nonreloc, 828 emacs_doprnt_string_lisp_2 (const Intbyte *format_nonreloc,
829 Lisp_Object format_reloc, Bytecount format_length, 829 Lisp_Object format_reloc, Bytecount format_length,
830 int nargs, ...) 830 int nargs, ...)
831 { 831 {
832 Lisp_Object obj; 832 Lisp_Object obj;
833 Lisp_Object stream = make_resizing_buffer_output_stream (); 833 Lisp_Object stream = make_resizing_buffer_output_stream ();