comparison src/lstream.h @ 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
41 41
42 #ifndef EOF 42 #ifndef EOF
43 #define EOF (-1) 43 #define EOF (-1)
44 #endif 44 #endif
45 45
46 /* Typedef specifying a count of bytes in a data block to be written 46 /* The have been some arguments over the what the type should be that
47 out or read in, using Lstream_read(), Lstream_write(), and related 47 specifies a count of bytes in a data block to be written out or read in,
48 functions. This MUST BE SIGNED, since it also is used in functions 48 using Lstream_read(), Lstream_write(), and related functions.
49 that return the number of bytes actually read to or written from in 49 Originally it was long, which worked fine; Martin "corrected" these to
50 an operation, and these functions can return -1 to signal error. 50 size_t and ssize_t on the grounds that this is theoretically cleaner and
51 is in keeping with the C standards. Unfortunately, this practice is
52 horribly error-prone due to design flaws in the way that mixed
53 signed/unsigned arithmetic happens. In fact, by doing this change,
54 Martin introduced a subtle but fatal error that caused the operation of
55 sending large mail messages to the SMTP server under Windows to fail.
56 By putting all values back to be signed, avoiding any signed/unsigned
57 mixing, the bug immediately went away. The type then in use was
58 Lstream_Data_Count, so that it be reverted cleanly if a vote came to
59 that. Now it is Bytecount.
60
61 Some earlier comments about why the type must be signed: This MUST BE
62 SIGNED, since it also is used in functions that return the number of
63 bytes actually read to or written from in an operation, and these
64 functions can return -1 to signal error.
51 65
52 Note that the standard Unix read() and write() functions define the 66 Note that the standard Unix read() and write() functions define the
53 count going in as a size_t, which is UNSIGNED, and the count going 67 count going in as a size_t, which is UNSIGNED, and the count going
54 out as an ssize_t, which is SIGNED. This is a horrible design 68 out as an ssize_t, which is SIGNED. This is a horrible design
55 flaw. Not only is it highly likely to lead to logic errors when a 69 flaw. Not only is it highly likely to lead to logic errors when a
57 bound to fail in all sorts of horrible ways when a number in the 71 bound to fail in all sorts of horrible ways when a number in the
58 upper-half of the size_t range is passed in -- this number is 72 upper-half of the size_t range is passed in -- this number is
59 unrepresentable as an ssize_t, so code that checks to see how many 73 unrepresentable as an ssize_t, so code that checks to see how many
60 bytes are actually written (which is mandatory if you are dealing 74 bytes are actually written (which is mandatory if you are dealing
61 with certain types of devices) will get completely screwed up. 75 with certain types of devices) will get completely screwed up.
76
77 --ben
62 */ 78 */
63
64 typedef EMACS_INT Lstream_Data_Count;
65 79
66 typedef enum lstream_buffering 80 typedef enum lstream_buffering
67 { 81 {
68 /* No buffering. */ 82 /* No buffering. */
69 LSTREAM_UNBUFFERED, 83 LSTREAM_UNBUFFERED,
94 however -- e.g. on process output. */ 108 however -- e.g. on process output. */
95 109
96 typedef struct lstream_implementation 110 typedef struct lstream_implementation
97 { 111 {
98 const char *name; 112 const char *name;
99 Lstream_Data_Count size; /* Number of additional bytes to be 113 Bytecount size; /* Number of additional bytes to be
100 allocated with this stream. Access this 114 allocated with this stream. Access this
101 data using Lstream_data(). */ 115 data using Lstream_data(). */
102 /* Read some data from the stream's end and store it into DATA, which 116 /* Read some data from the stream's end and store it into DATA, which
103 can hold SIZE bytes. Return the number of bytes read. A return 117 can hold SIZE bytes. Return the number of bytes read. A return
104 value of 0 means no bytes can be read at this time. This may 118 value of 0 means no bytes can be read at this time. This may
115 129
116 This function can be NULL if the stream is output-only. */ 130 This function can be NULL if the stream is output-only. */
117 /* The omniscient mly, blinded by the irresistible thrall of Common 131 /* The omniscient mly, blinded by the irresistible thrall of Common
118 Lisp, thinks that it is bogus that the types and implementations 132 Lisp, thinks that it is bogus that the types and implementations
119 of input and output streams are the same. */ 133 of input and output streams are the same. */
120 Lstream_Data_Count (*reader) (Lstream *stream, unsigned char *data, 134 Bytecount (*reader) (Lstream *stream, unsigned char *data,
121 Lstream_Data_Count size); 135 Bytecount size);
122 /* Send some data to the stream's end. Data to be sent is in DATA 136 /* Send some data to the stream's end. Data to be sent is in DATA
123 and is SIZE bytes. Return the number of bytes sent. This 137 and is SIZE bytes. Return the number of bytes sent. This
124 function can send and return fewer bytes than is passed in; in 138 function can send and return fewer bytes than is passed in; in
125 that case, the function will just be called again until there is 139 that case, the function will just be called again until there is
126 no data left or 0 is returned. A return value of 0 means that no 140 no data left or 0 is returned. A return value of 0 means that no
127 more data can be currently stored, but there is no error; the 141 more data can be currently stored, but there is no error; the
128 data will be squirrelled away until the writer can accept 142 data will be squirrelled away until the writer can accept
129 data. (This is useful, e.g., of you're dealing with a 143 data. (This is useful, e.g., of you're dealing with a
130 non-blocking file descriptor and are getting EWOULDBLOCK errors.) 144 non-blocking file descriptor and are getting EWOULDBLOCK errors.)
131 This function can be NULL if the stream is input-only. */ 145 This function can be NULL if the stream is input-only. */
132 Lstream_Data_Count (*writer) (Lstream *stream, const unsigned char *data, 146 Bytecount (*writer) (Lstream *stream, const unsigned char *data,
133 Lstream_Data_Count size); 147 Bytecount size);
134 /* Return non-zero if the last write operation on the stream resulted 148 /* Return non-zero if the last write operation on the stream resulted
135 in an attempt to block (EWOULDBLOCK). If this method does not 149 in an attempt to block (EWOULDBLOCK). If this method does not
136 exists, the implementation returns 0 */ 150 exists, the implementation returns 0 */
137 int (*was_blocked_p) (Lstream *stream); 151 int (*was_blocked_p) (Lstream *stream);
138 /* Rewind the stream. If this is NULL, the stream is not seekable. */ 152 /* Rewind the stream. If this is NULL, the stream is not seekable. */
169 struct lstream 183 struct lstream
170 { 184 {
171 struct lcrecord_header header; 185 struct lcrecord_header header;
172 const Lstream_implementation *imp; /* methods for this stream */ 186 const Lstream_implementation *imp; /* methods for this stream */
173 Lstream_buffering buffering; /* type of buffering in use */ 187 Lstream_buffering buffering; /* type of buffering in use */
174 Lstream_Data_Count buffering_size; /* number of bytes buffered */ 188 Bytecount buffering_size; /* number of bytes buffered */
175 189
176 unsigned char *in_buffer; /* holds characters read from stream end */ 190 unsigned char *in_buffer; /* holds characters read from stream end */
177 Lstream_Data_Count in_buffer_size; /* allocated size of buffer */ 191 Bytecount in_buffer_size; /* allocated size of buffer */
178 Lstream_Data_Count in_buffer_current; /* number of characters in buffer */ 192 Bytecount in_buffer_current; /* number of characters in buffer */
179 Lstream_Data_Count in_buffer_ind; /* pointer to next character to 193 Bytecount in_buffer_ind; /* pointer to next character to
180 take from buffer */ 194 take from buffer */
181 195
182 unsigned char *out_buffer; /* holds characters to write to stream end */ 196 unsigned char *out_buffer; /* holds characters to write to stream end */
183 Lstream_Data_Count out_buffer_size; /* allocated size of buffer */ 197 Bytecount out_buffer_size; /* allocated size of buffer */
184 Lstream_Data_Count out_buffer_ind; /* pointer to next buffer spot to 198 Bytecount out_buffer_ind; /* pointer to next buffer spot to
185 write a character */ 199 write a character */
186 200
187 /* The unget buffer is more or less a stack -- things get pushed 201 /* The unget buffer is more or less a stack -- things get pushed
188 onto the end and read back from the end. Lstream_read() 202 onto the end and read back from the end. Lstream_read()
189 basically reads backwards from the end to get stuff; Lstream_unread() 203 basically reads backwards from the end to get stuff; Lstream_unread()
190 similarly has to push the data on backwards. */ 204 similarly has to push the data on backwards. */
191 unsigned char *unget_buffer; /* holds characters pushed back onto input */ 205 unsigned char *unget_buffer; /* holds characters pushed back onto input */
192 Lstream_Data_Count unget_buffer_size; /* allocated size of buffer */ 206 Bytecount unget_buffer_size; /* allocated size of buffer */
193 Lstream_Data_Count unget_buffer_ind; /* pointer to next buffer spot 207 Bytecount unget_buffer_ind; /* pointer to next buffer spot
194 to write a character */ 208 to write a character */
195 209
196 Lstream_Data_Count byte_count; 210 Bytecount byte_count;
197 int flags; 211 int flags;
198 max_align_t data[1]; 212 max_align_t data[1];
199 }; 213 };
200 214
201 #define LSTREAM_TYPE_P(lstr, type) \ 215 #define LSTREAM_TYPE_P(lstr, type) \
234 int Lstream_flush (Lstream *lstr); 248 int Lstream_flush (Lstream *lstr);
235 int Lstream_flush_out (Lstream *lstr); 249 int Lstream_flush_out (Lstream *lstr);
236 int Lstream_fputc (Lstream *lstr, int c); 250 int Lstream_fputc (Lstream *lstr, int c);
237 int Lstream_fgetc (Lstream *lstr); 251 int Lstream_fgetc (Lstream *lstr);
238 void Lstream_fungetc (Lstream *lstr, int c); 252 void Lstream_fungetc (Lstream *lstr, int c);
239 Lstream_Data_Count Lstream_read (Lstream *lstr, void *data, 253 Bytecount Lstream_read (Lstream *lstr, void *data,
240 Lstream_Data_Count size); 254 Bytecount size);
241 Lstream_Data_Count Lstream_write (Lstream *lstr, const void *data, 255 Bytecount Lstream_write (Lstream *lstr, const void *data,
242 Lstream_Data_Count size); 256 Bytecount size);
243 int Lstream_was_blocked_p (Lstream *lstr); 257 int Lstream_was_blocked_p (Lstream *lstr);
244 void Lstream_unread (Lstream *lstr, const void *data, Lstream_Data_Count size); 258 void Lstream_unread (Lstream *lstr, const void *data, Bytecount size);
245 int Lstream_rewind (Lstream *lstr); 259 int Lstream_rewind (Lstream *lstr);
246 int Lstream_seekable_p (Lstream *lstr); 260 int Lstream_seekable_p (Lstream *lstr);
247 int Lstream_close (Lstream *lstr); 261 int Lstream_close (Lstream *lstr);
248 void Lstream_delete (Lstream *lstr); 262 void Lstream_delete (Lstream *lstr);
249 void Lstream_set_character_mode (Lstream *str); 263 void Lstream_set_character_mode (Lstream *str);
362 int flags); 376 int flags);
363 Lisp_Object make_filedesc_output_stream (int filedesc, int offset, int count, 377 Lisp_Object make_filedesc_output_stream (int filedesc, int offset, int count,
364 int flags); 378 int flags);
365 void filedesc_stream_set_pty_flushing (Lstream *stream, 379 void filedesc_stream_set_pty_flushing (Lstream *stream,
366 int pty_max_bytes, 380 int pty_max_bytes,
367 Bufbyte eof_char); 381 Intbyte eof_char);
368 int filedesc_stream_fd (Lstream *stream); 382 int filedesc_stream_fd (Lstream *stream);
369 Lisp_Object make_lisp_string_input_stream (Lisp_Object string, 383 Lisp_Object make_lisp_string_input_stream (Lisp_Object string,
370 Bytecount offset, 384 Bytecount offset,
371 Bytecount len); 385 Bytecount len);
372 Lisp_Object make_fixed_buffer_input_stream (const void *buf, 386 Lisp_Object make_fixed_buffer_input_stream (const void *buf,
373 Lstream_Data_Count size); 387 Bytecount size);
374 Lisp_Object make_fixed_buffer_output_stream (void *buf, 388 Lisp_Object make_fixed_buffer_output_stream (void *buf,
375 Lstream_Data_Count size); 389 Bytecount size);
376 const unsigned char *fixed_buffer_input_stream_ptr (Lstream *stream); 390 const unsigned char *fixed_buffer_input_stream_ptr (Lstream *stream);
377 unsigned char *fixed_buffer_output_stream_ptr (Lstream *stream); 391 unsigned char *fixed_buffer_output_stream_ptr (Lstream *stream);
378 Lisp_Object make_resizing_buffer_output_stream (void); 392 Lisp_Object make_resizing_buffer_output_stream (void);
379 unsigned char *resizing_buffer_stream_ptr (Lstream *stream); 393 unsigned char *resizing_buffer_stream_ptr (Lstream *stream);
380 Lisp_Object make_dynarr_output_stream (unsigned_char_dynarr *dyn); 394 Lisp_Object make_dynarr_output_stream (unsigned_char_dynarr *dyn);
381 #define LSTR_SELECTIVE 1 395 #define LSTR_SELECTIVE 1
382 #define LSTR_IGNORE_ACCESSIBLE 2 396 #define LSTR_IGNORE_ACCESSIBLE 2
383 Lisp_Object make_lisp_buffer_input_stream (struct buffer *buf, Bufpos start, 397 Lisp_Object make_lisp_buffer_input_stream (struct buffer *buf, Charbpos start,
384 Bufpos end, int flags); 398 Charbpos end, int flags);
385 Lisp_Object make_lisp_buffer_output_stream (struct buffer *buf, Bufpos pos, 399 Lisp_Object make_lisp_buffer_output_stream (struct buffer *buf, Charbpos pos,
386 int flags); 400 int flags);
387 Bufpos lisp_buffer_stream_startpos (Lstream *stream); 401 Charbpos lisp_buffer_stream_startpos (Lstream *stream);
388 402
389 #endif /* INCLUDED_lstream_h_ */ 403 #endif /* INCLUDED_lstream_h_ */