Major editing.
authorrms <rms>
Sun, 24 Nov 1991 21:24:35 +0000 (21:24 +0000)
committerrms <rms>
Sun, 24 Nov 1991 21:24:35 +0000 (21:24 +0000)
manual/stdio.texi

index 33d9166..38498f6 100644 (file)
@@ -10,25 +10,27 @@ representing a communications channel to a file, device, or process.
 useful here.
 
 @menu
-* Streams::                    About the data type representing a stream.
-* Standard Streams::           Streams to the standard input and output 
-                                devices are created for you.
-* Opening and Closing Streams::        How to create a stream to talk to a file.
-* Character Output::           Unformatted output by characters and lines.
-* Character Input::            Unformatted input by characters and lines.
-* Formatted Output::           @code{printf} and related functions.
-* Customizing Printf::         You can define new conversion specifiers for
-                                @code{printf} and friends.
-* Formatted Input::            @code{scanf} and related functions.
-* Block Input/Output::         Input and output operations on blocks of data.
-* End-Of-File and Errors::     How you can tell if an i/o error happens.
-* File Positioning::           About random-access streams.
-* Text and Binary Streams::    Some systems distinguish between text files
-                                and binary files.
-* Stream Buffering::           How to control buffering of streams.
-* Temporary Files::            How to open a temporary file.
-* Other Kinds of Streams::     How you can open additional kinds of
-                                streams.
+* Streams::                     About the data type representing a stream.
+* Standard Streams::            Streams to the standard input and output 
+                                 devices are created for you.
+* Opening and Closing Streams:: How to create a stream to talk to a file.
+* Character Output::            Unformatted output by characters and lines.
+* Character Input::             Unformatted input by characters and lines.
+* Unreading::                   Peeking ahead/pushing back input just read.
+* Formatted Output::            @code{printf} and related functions.
+* Customizing Printf::          You can define new conversion specifiers for
+                                 @code{printf} and friends.
+* Formatted Input::             @code{scanf} and related functions.
+* Block Input/Output::          Input and output operations on blocks of data.
+* End-Of-File and Errors::      How you can tell if an I/O error happens.
+* Text and Binary Streams::     Some systems distinguish between text files
+                                 and binary files.
+* File Positioning::            About random-access streams.
+* Portable Positioning::        Random access on peculiar ANSI C systems.
+* Stream Buffering::            How to control buffering of streams.
+* Temporary Files::             How to open a temporary file.
+* Other Kinds of Streams::      How you can open additional kinds of
+                                 streams.
 @end menu
 
 @node Streams
@@ -54,12 +56,13 @@ This is the data type is used to represent stream objects.  A
 connection to the associated file, including such things as the file
 position indicator and buffering information.  Each stream also has
 error and end-of-file status indicators that can be tested with the
-@code{ferror} and @code{feof} functions; @pxref{End-Of-File and Errors}.
+@code{ferror} and @code{feof} functions; see @ref{End-Of-File and
+Errors}.
 @end deftp
 
 @code{FILE} objects are allocated and managed internally by the
 input/output library functions.  Don't try to create your own objects of
-type @code{FILE}.  Instead, let the library do it.  Your programs should
+type @code{FILE}; let the library do it.  Your programs should
 deal only with pointers to these objects (that is, @code{FILE *} values)
 rather than the objects themselves.
 
@@ -104,11 +107,11 @@ by the program.
 
 In the GNU system, you can specify what files or processes correspond to
 these streams using the pipe and redirection facilities provided by the
-shell.  (The primitives for implementating these facilities are
+shell.  (The primitives shells use to implement these facilities are
 described in @ref{File System Interface}.)  Most other operating systems
 provide similar mechanisms, but the details of how to use them can vary.
 
-It is probably not a good idea to close any of these streams.
+It is probably not a good idea to close any of the standard streams.
 
 
 @node Opening and Closing Streams
@@ -121,7 +124,7 @@ involve creating a new file.
 
 @cindex closing a stream
 When a stream is closed with @code{fclose}, the connection between the
-stream and the file is removed.  After you have closed a stream, you
+stream and the file is cancelled.  After you have closed a stream, you
 cannot perform any additional operations on it any more.
 
 The functions in this section are declared in the header file
@@ -172,10 +175,12 @@ to the end of the file.
 
 Any of the above sequences can also be followed by a character @samp{b}
 to indicate that a binary (rather than text) stream should be created;
-@pxref{Text and Binary Streams}.  If both @samp{+} and @samp{b} are
+see @ref{Text and Binary Streams}.  If both @samp{+} and @samp{b} are
 specified, they can appear in either order.  For example, @code{"r+b"}
 and @code{"rb+"} are equivalent; they both specify an existing binary
-file being opened for both read and write access.
+file being opened for both read and write access.  In GNU and other
+POSIX systems, `b' has no effect since there is no difference between 
+text and binary streams.
 
 When a file is opened with the @samp{+} option for both reading and
 writing, you must call either @code{fflush} (@pxref{Stream Buffering})
@@ -200,9 +205,12 @@ If the open fails, @code{fopen} returns a null pointer.
 
 You can have multiple streams (or file descriptors) pointing to the same
 file open at the same time.  If you do only input, this works fine, but
-you can get unpredictable results if you are writing to the file.  The
-file locking facilities can be useful in this context; @pxref{File
-Locks}.
+you can get unpredictable results if you are writing to the file.  It is
+unusual to have more than one stream open for a given file in one
+program, but not unusual for several programs (or at least several
+instances of one program) to open the same file.  In such cases, your
+programs should use the file locking facilities to avoid simultaneous
+access.  @xref{File Locks}.
 
 
 @comment stdio.h
@@ -222,7 +230,14 @@ This function causes @var{stream} to be closed and the connection to
 the corresponding file to be broken.  Any buffered output is written
 and any buffered input is discarded.  The @code{fclose} function returns
 a value of @code{0} if the file was closed successfully, and @code{EOF}
-if an error was detected.
+if an error was detected. 
+
+It is important to check for errors when you call @code{fclose} to close
+an output stream, because real, everyday errors can be detected at this
+time.  For example, when @code{fclose} writes the remaining buffered
+output, it might get an error because the disk is full.  Even if you you
+know the buffer is empty, errors can still occur when closing a file if
+you are using NFS.
 @end deftypefun
 
 If the @code{main} function to your program returns, or if you call the
@@ -232,18 +247,25 @@ in any other manner, such as by calling the @code{abort} function
 (@pxref{Aborting a Program}) or from a fatal signal (@pxref{Signal
 Handling}), open streams might not be closed properly.  Buffered output
 may not be flushed and files may not be complete.  For more information
-on buffering of streams, @pxref{Stream Buffering}.
+on buffering of streams, see @ref{Stream Buffering}.
 
 @comment stdio.h
 @comment ANSI
 @deftypefun {FILE *} freopen (const char *@var{filename}, const char *@var{opentype}, FILE *@var{stream})
 This function is like a combination of @code{fclose} and @code{fopen}.
 It first closes the stream referred to by @var{stream}, ignoring any
-errors that are detected in the process.  Then the file named by
-@var{filename} is opened with mode @var{opentype} as for @code{fopen}, and
-associated with the same stream object @var{stream}.  If the operation
-fails, a null pointer is returned; otherwise, @code{freopen} returns
-@var{stream}.
+errors that are detected in the process.  (Because errors are ignored,
+you should not use @code{freopen} on an output stream if you have
+actually done any output using the stream.)  Then the file named by
+@var{filename} is opened with mode @var{opentype} as for @code{fopen},
+and associated with the same stream object @var{stream}.
+
+If the operation fails, a null pointer is returned; otherwise,
+@code{freopen} returns @var{stream}.
+
+The main use of @code{freopen} is to connect a standard stream such as
+@code{stdir} with a file of your own choice.  This is useful in programs
+in which use of a standard stream for certain purposes is hard-coded.
 @end deftypefun
 
 
@@ -254,7 +276,7 @@ fails, a null pointer is returned; otherwise, @code{freopen} returns
 This section describes functions for performing character- and
 line-oriented output.  Largely for historical compatibility, there are
 several variants of these functions, but as a matter of style (and for
-simplicity!) it's suggested that you stick with using @code{fputc} and
+simplicity!) we suggest you stick with using @code{fputc} and
 @code{fputs}, and perhaps @code{putc} and @code{putchar}.
 
 These functions are declared in the header file @file{stdio.h}.
@@ -272,11 +294,13 @@ character @var{c} is returned.
 @comment stdio.h
 @comment ANSI
 @deftypefun int putc (int @var{c}, FILE *@var{stream})
-This is just like @code{fputc}, except that it is permissible (and
-typical) for it to be implemented as a macro that evaluates the
-@var{stream} argument more than once.  (Of course, @code{fputc} can be
-implemented as a macro too, but only in such a way that it doesn't
-evaluate its arguments more than once.)
+This is just like @code{fputc}, except that most systems implement it as
+a macro, making it faster.  One consequence is that it may evaluate the
+@var{stream} argument more than once.
+
+In the GNU library, @code{fputc} also has a definition as a macro, which
+is just as fast but computes its arguments only once.  So there is no
+reason to prefer @code{putc} with the GNU library.
 @end deftypefun
 
 @comment stdio.h
@@ -292,25 +316,37 @@ The @code{putchar} function is equivalent to @code{fputc} with
 The function @code{fputs} writes the string @var{s} to the stream
 @var{stream}.  The terminating null character is not written.
 This function does @emph{not} add a newline character, either.
+It outputs only the chars in the string.
 
 This function returns @code{EOF} if a write error occurs, and otherwise
 a non-negative value.
+
+For example:
+
+@example
+fputs ("Are ", stdout);
+fputs ("you ", stdout);
+fputs ("hungry?\n", stdout);
+@end example
+
+@noindent
+outputs the text @samp{Are you hungry?} followed by a newline.
 @end deftypefun
 
 @comment stdio.h
 @comment ANSI
 @deftypefun int puts (const char *@var{s})
 The @code{puts} function writes the string @var{s} to the stream
-@code{stdout}.  The terminating null character is not written, but
-a newline character is appended to the output; this differs from
-@code{fputs}, which does not add a newline.
+@code{stdout} followed by a newline.  The terminating null character of
+the string is not written.
 @end deftypefun
 
 @comment stdio.h
 @comment SVID
 @deftypefun int putw (int @var{w}, FILE *@var{stream})
 This function writes the word @var{w} (that is, an @code{int}) to
-@var{stream}.  It's provided for compatibility with SVID.
+@var{stream}.  It is provided for compatibility with SVID, but we
+recommend you use @code{fwrite} instead (@pxref{Block Input/Output}).
 @end deftypefun
 
 @node Character Input
@@ -319,9 +355,9 @@ This function writes the word @var{w} (that is, an @code{int}) to
 @cindex reading from a stream, by characters
 This section describes functions for performing character- and
 line-oriented input.  Again, there are several variants of these
-functions, some of which are considered obsolete stylistically.
-It's suggested that you stick with @code{fgetc}, @code{fgets}, and
-maybe @code{ungetc}, @code{getc}, and @code{getchar}.
+functions, some of which are considered obsolete stylistically.  It's
+suggested that you stick with @code{fgetc}, @code{fgets}, @code{ungetc},
+and maybe @code{getc} and @code{getchar}.
 
 These functions are declared in the header file @file{stdio.h}.
 @pindex stdio.h
@@ -350,72 +386,63 @@ The @code{getchar} function is equivalent to @code{fgetc} with @code{stdin}
 as the value of the @var{stream} argument.
 @end deftypefun
 
-@comment stdio.h
-@comment ANSI
-@deftypefun int ungetc (int @var{c}, FILE *@var{stream})
-The @code{ungetc} function is provided to support a limited form of
-input lookahead.  The character @var{c} (which must not be @code{EOF})
-is ``pushed back'' onto the input stream @var{stream}, where it can be
-read back in again.
-
-The character that you push back doesn't have to be the same as the last
-character that was actually read from the stream.  In fact, it isn't
-necessary to actually read any characters from the stream before
-unreading them with @code{ungetc}!
-
-The GNU C library only supports one character of pushback.  Other
-systems might let you push back multiple characters; in such
-implementations, reading from the stream retrieves the characters in the
-reverse order that they were pushed.
-
-Pushing back characters doesn't alter the file; only the internal
-buffering for the stream is affected.  If a file positioning function
-(such as @code{fseek} or @code{rewind}; @pxref{File Positioning}) is
-called, any unread pushed-back characters are discarded.
-
-If the stream is at end-of-file when a character is pushed back, the
-end-of-file indicator for the stream is cleared.
-@end deftypefun
-
-Here is an example showing the use of @code{getc} and @code{ungetc}
-to skip over whitespace characters.  The first non-whitespace character
-read is pushed back, so it can be seen again on the next read operation
-on the stream.
+Here is an example of a function that does input using @code{fgetc}.  It
+would work just as well using @code{getc} instead, or using
+@code{getchar ()} instead of @code{fgetc (stdin)}.
 
 @example
-#include <stdio.h>
-
-void skip_whitespace (FILE *stream)
+int
+y_or_n_p (const char *question)
 @{
-  int c;
-  do @{
-    c = getc (stream);
-    if (c == EOF) return;
-  @} while (isspace (c));
-  ungetc (c, stream);
+  fputs (question, stdout);
+  while (1) @{
+    int c, answer;
+    /* @r{Write a space to separate answer from question.} */
+    fputc (' ', stdout);
+    /* @r{Read the first character of the line.}
+       @r{This should be the answer character, but might not be.} */
+    c = tolower (fgetc (stdin));
+    answer = c;
+    /* @r{Discard rest of input line.} */
+    while (c != '\n')
+      c = fgetc (stdin);
+    /* @r{Obey the answer if it was valid.} */
+    if (answer == 'y')
+      return 1;
+    if (answer == 'n')
+      return 0;
+    /* @r{Answer was invalid: ask for valid answer.} */
+    fputs ("Please answer y or n:", stdout);
+  @}
 @}
 @end example
 
-
 @comment stdio.h
 @comment ANSI
 @deftypefun {char *} fgets (char *@var{s}, int @var{count}, FILE *@var{stream})
 The @code{fgets} function reads characters from the stream @var{stream}
 up to and including a newline character and stores them in the string
-@var{s}.  At most, one less than @var{count} characters are read;
-since a null character is added to mark the end of the string,
-@var{count} effectively specifies the minimum allocation size for the
-string @var{s}.
-
-In the event of an end-of-file condition, if no characters have yet been
-read, then the contents of the array @var{s} are unchanged and a null
-pointer is returned.  A null pointer is also returned if a read error
-occurs.  Otherwise, the return value is the pointer @var{s}.
+@var{s}, adding a null character to mark the end of the string.  You
+must supply @var{count} characters worth of space in @var{s}, but the
+number of characters read is at most @var{count} @minus{} 1.  The extra
+character space is used to hold the null character at the end of the
+string.
+
+If the system is already at end of file when you call @code{fgets}, then
+the contents of the array @var{s} are unchanged and a null pointer is
+returned.  A null pointer is also returned if a read error occurs.
+Otherwise, the return value is the pointer @var{s}.
+
+@strong{Warning:}  If the input data has a null character, you can't tell.
+So don't use @code{fgets} unless you know the data cannot contain a null.
+Don't use it to read files edited by the user because, if the user inserts
+a null character, you should either handle it properly or print a clear
+error message.
 @end deftypefun
 
 @comment stdio.h
 @comment ANSI
-@deftypefun {char *} gets (char *@var{s})
+@deftypefn {Deprecated function} {char *} gets (char *@var{s})
 The function @code{gets} reads characters from the stream @code{stdin}
 up to the next newline character, and stores them in the string @var{s}.
 The newline character is discarded (note that this differs from the
@@ -432,9 +459,128 @@ The GNU library includes it for compatibility only.  You should
 @comment SVID
 @deftypefun int getw (FILE *@var{stream})
 This function reads a word (that is, an @code{int}) from @var{stream}.
-It's provided for compatibility with SVID.
+It's provided for compatibility with SVID.  We recommend you use
+@code{fread} instead (@pxref{Block Input/Output}).
 @end deftypefun
 
+@node Unreading
+@section Unreading
+@cindex peeking at input
+@cindex unreading characters
+@cindex pushing input back
+
+In parser programs it is often useful to examine the next character in
+the input stream without removing it from the stream.  This is called
+``peeking ahead'' at the input because your program gets a glimpse of
+the input it will read next.
+
+Using stream I/O, you can peek ahead at input by first reading it and
+then @dfn{unreading} it (also called  @dfn{pushing it back} on the stream).  
+Unreading a character makes it available to be input again from the stream,
+by  the next call to @code{fgetc} or other input function on that stream.
+
+@menu
+* Unreading Idea::    An explanation of unreading with pictures.
+* How Unread::        How to call @code{ungetc} to do unreading.
+@end menu
+
+@node Unreading Idea
+@subsection What Unreading Means
+
+Here is a pictorial explanation of unreading.  Suppose you have a
+stream reading a file that contains just six characters, the letters
+@samp{foobar}.  Suppose you have read three characters so far.  The
+situation looks like this:
+
+@example
+f  o  o  b  a  r
+         ^
+@end example
+
+@noindent
+so the next input character will be @samp{b}.
+
+If instead of reading @samp{b} you unread the letter @samp{o}, you get a
+situation like this:
+
+@example
+f  o  o  b  a  r
+         |
+      o--
+      ^
+@end example
+
+@noindent
+so that the next input characters will be @samp{o} and @samp{b}.
+
+If you unread @samp{9} instead of @samp{o}, you get this situation:
+
+@example
+f  o  o  b  a  r
+         |
+      9--
+      ^
+@end example
+
+@noindent
+so that the next input characters will be @samp{9} and @samp{b}.
+
+@node How Unread
+@subsection Using @code{ungetc} To Do Unreading
+The function to unread a character is called @code{ungetc}, because it
+reverses the action of @code{fgetc}.
+
+@comment stdio.h
+@comment ANSI
+@deftypefun int ungetc (int @var{c}, FILE *@var{stream})
+The @code{ungetc} function pushes back the character @var{c} onto the
+input stream @var{stream}.  So the next input from @var{stream} will
+read @var{c} before anything else.
+
+The character that you push back doesn't have to be the same as the last
+character that was actually read from the stream.  In fact, it isn't
+necessary to actually read any characters from the stream before
+unreading them with @code{ungetc}!  But that is a strange way to write
+a program; usually @code{ungetc} is used only to unread a character
+that was just read from the same stream.
+
+The GNU C library only supports one character of pushback---in other
+words, it does not work to call @code{ungetc} twice without doing input
+in between.  Other systems might let you push back multiple characters;
+then reading from the stream retrieves the characters in the reverse
+order that they were pushed.
+
+Pushing back characters doesn't alter the file; only the internal
+buffering for the stream is affected.  If a file positioning function
+(such as @code{fseek} or @code{rewind}; @pxref{File Positioning}) is
+called, any pending pushed-back characters are discarded.
+
+Unreading a character on a stream that is at end-of-file clears the
+end-of-file indicator for the stream, because it makes the character of
+input available.  Reading that character will set the end-of-file
+indicator again.
+@end deftypefun
+
+Here is an example showing the use of @code{getc} and @code{ungetc} to
+skip over whitespace characters.  When this function reaches a
+non-whitespace character, it unreads that character to be seen again on
+the next read operation on the stream.
+
+@example
+#include <stdio.h>
+
+void
+skip_whitespace (FILE *stream)
+@{
+  int c;
+  do @{
+    c = getc (stream);
+    if (c == EOF) return;
+  @} while (isspace (c));
+  ungetc (c, stream);
+@}
+@end example
 
 @node Formatted Output
 @section Formatted Output
@@ -445,35 +591,37 @@ It's provided for compatibility with SVID.
 @cindex writing to a stream, formatted
 The functions described in this section (@code{printf} and related
 functions) provide a convenient way to perform formatted output.  You
-call @code{printf} with a @dfn{format string} or @dfn{template} that
-specifies how to print the values of the remaining arguments.
+call @code{printf} with a @dfn{format string} or @dfn{template string}
+that specifies how to format the values of the remaining arguments.
 
 Unless your program is a filter that specifically performs line- or
 character-oriented processing, using @code{printf} or one of the other
-related functions described in this section is almost always the easiest
-and most concise way to handle program output.  These functions are
-especially useful for printing messages, tables of data, and the like.
+related functions described in this section is usually the easiest and
+most concise way to perform output.  These functions are especially
+useful for printing error messages, tables of data, and the like.
 
 @menu
-* Formatted Output Basics::            Some examples to get you started.
-* Output Conversion Syntax::           General syntax of conversion
+* Formatted Output Basics::             Some examples to get you started.
+* Output Conversion Syntax::            General syntax of conversion
                                          specifications.
-* Table of Output Conversions::                Summary of output conversions and
+* Table of Output Conversions::         Summary of output conversions and
                                          what they do.
-* Integer Conversions::                        Details about formatting of integers.
-* Floating-Point Conversions::         Details about formatting of
+* Integer Conversions::                 Details about formatting of integers.
+* Floating-Point Conversions::          Details about formatting of
                                          floating-point numbers.
-* Other Output Conversions::           Details about formatting of strings,
-                                        characters, pointers, and the like.
-* Formatted Output Functions::         Descriptions of the actual functions.
-* Variable Arguments Output Functions:: More functions.
+* Other Output Conversions::            Details about formatting of strings,
+                                         characters, pointers, and the like.
+* Formatted Output Functions::          Descriptions of the actual functions.
+* Variable Arguments Output Functions:: @code{vprintf} and friends.
+* Parsing a Template String::           What kinds of args
+                                         does a given template call for?
 @end menu
 
 @node Formatted Output Basics
 @subsection Formatted Output Basics
 
 The @code{printf} function can be used to print any number of arguments.
-The format template string argument you supply in a call provides
+The template string argument you supply in a call provides
 information not only about the number of additional arguments, but also
 about their types and what style should be used for printing them.
 
@@ -486,7 +634,7 @@ formatted and written to the output stream.  For example,
 @example
 int pct = 37;
 char filename[] = "foo.txt";
-printf ("Processing of %s is %d%% finished.\nPlease be patient.\n",
+printf ("Processing of `%s' is %d%% finished.\nPlease be patient.\n",
         filename, pct);
 @end example
 
@@ -494,7 +642,7 @@ printf ("Processing of %s is %d%% finished.\nPlease be patient.\n",
 produces output like
 
 @example
-Processing of foo.txt is 37% finished.
+Processing of `foo.txt' is 37% finished.
 Please be patient.
 @end example
 
@@ -514,12 +662,12 @@ using the @samp{%f} conversion or in exponential notation using the
 or @samp{%f} format, depending on what is more appropriate for the
 magnitude of the particular number.
 
-The syntax of conversion specifications actually permits you to put a
-bunch of options between the @samp{%} and the character that indicates
-which conversion to apply.  These options modify the ordinary behavior
-of the conversion.  For example, most conversion specifications permit
-you to specify a minimum field width and a flag indicating whether you
-want the result left- or right-justified within the field.
+You can control formatting more precisely by writing @dfn{modifier}
+between the @samp{%} and the character that indicates which conversion
+to apply.  These alter slightly the ordinary behavior of the conversion.
+For example, most conversion specifications permit you to specify a
+minimum field width and a flag indicating whether you want the result
+left- or right-justified within the field.
 
 The specific flags and modifiers that are permitted and their
 interpretation vary depending on the particular conversion.  They're all
@@ -533,29 +681,29 @@ tables.
 @subsection Output Conversion Syntax
 
 This section provides details about the precise syntax of conversion
-specifications that can appear in a @code{printf} format template
+specifications that can appear in a @code{printf} template
 string.
 
-Characters in the format template string that are not part of a
+Characters in the template string that are not part of a
 conversion specification are printed as-is to the output stream.
 Multibyte character sequences (@pxref{Extended Characters}) are permitted in
-a format template string.
+a template string.
 
-The conversion specifications in a @code{printf} format template have
+The conversion specifications in a @code{printf} template string have
 the general form:
 
 @example
-% @var{flags} @var{width} . @var{precision} @var{type} @var{conversion}
+% @var{flags} @var{width} @r{[} . @var{precision} @r{]} @var{type} @var{conversion}
 @end example
 
 For example, in the conversion specifier @samp{%-10.8ld}, the @samp{-}
 is a flag, @samp{10} specifies the field width, the precision is
 @samp{8}, the letter @samp{l} is a type modifier, and @samp{d} specifies
-the conversion style.  (What this particular type specifier says is to
+the conversion style.  (This particular type specifier says to
 print a @code{long int} argument in decimal notation, with a minimum of
 8 digits left-justified in a field at least 10 characters wide.)
 
-More specifically, output conversion specifications consist of an
+In more detail, output conversion specifications consist of an
 initial @samp{%} character followed in sequence by:
 
 @itemize @bullet
@@ -576,7 +724,7 @@ within the field.
 The GNU library's version of @code{printf} also allows you to specify a
 field width of @samp{*}.  This means that the next argument in the
 argument list (before the actual value to be printed) is used as the
-field width.  The value must be an @code{int}.  Other versions of C may
+field width.  The value must be an @code{int}.  Other C library versions may
 not recognize this syntax.
 
 @item 
@@ -590,15 +738,16 @@ The GNU library's version of @code{printf} also allows you to specify a
 precision of @samp{*}.  This means that the next argument in the
 argument list (before the actual value to be printed) is used as the
 precision.  The value must be an @code{int}.  If you specify @samp{*}
-for both the field width and precision, the field width argument precedes
-the precision argument.  Other versions of C may not recognize this syntax.
+for both the field width and precision, the field width argument
+precedes the precision argument.  Other C library versions may not
+recognize this syntax.
 
 @item
 An optional @dfn{type modifier character}, which is used to specify the
 data type of the corresponding argument if it differs from the default
 type.  (For example, the integer conversions assume a type of @code{int},
-but you can use the same conversions with a type modifier to print
-@code{long int} or @code{short int} objects.)
+but you can specify @samp{h}, @samp{l}, or @samp{L} for other integer
+types.
 @cindex type modifier character (@code{printf})
 
 @item
@@ -619,38 +768,43 @@ Here is a table summarizing what all the different conversions do:
 @table @asis
 @item @samp{%d}, @samp{%i}
 Print an integer as a signed decimal number.  @xref{Integer
-Conversions}, for details on all the options.
+Conversions}, for details.  @samp{%d} and @samp{%i} are synonymous for
+output, but are different when used with @code{scanf} for input
+(@pxref{Table of Input Conversions}).
 
 @item @samp{%o}
 Print an integer as an unsigned octal number.  @xref{Integer
-Conversions}, for details on all the options.
+Conversions}, for details.
 
 @item @samp{%u}
 Print an integer as an unsigned decimal number.  @xref{Integer
-Conversions}, for details on all the options.
+Conversions}, for details.
 
 @item @samp{%x}, @samp{%X}
-Print an integer as an unsigned hexadecimal number.  @xref{Integer
-Conversions}, for details on all the options.
+Print an integer as an unsigned hexadecimal number.  @samp{%x} uses
+lower-case letters and @samp{%X} uses upper-case.  @xref{Integer
+Conversions}, for details.
 
 @item @samp{%f}
 Print a floating-point number in normal (fixed-point) notation.
-@xref{Floating-Point Conversions}, for details on all the options.
+@xref{Floating-Point Conversions}, for details.
 
 @item @samp{%e}, @samp{%E}
-Print a floating-point number in exponential notation.
-@xref{Floating-Point Conversions}, for details on all the options.
+Print a floating-point number in exponential notation.  @samp{%e} uses
+lower-case letters and @samp{%E} uses upper-case.  @xref{Floating-Point
+Conversions}, for details.
 
 @item @samp{%g}, @samp{%G}
 Print a floating-point number in either normal or exponential notation,
-whichever is more appropriate for its magnitude.  @xref{Floating-Point
-Conversions}, for details on all the options.
+whichever is more appropriate for its magnitude.  @samp{%g} uses
+lower-case letters and @samp{%G} uses upper-case.  @xref{Floating-Point
+Conversions}, for details.
 
 @item @samp{%c}
 Print a single character.  @xref{Other Output Conversions}.
 
 @item @samp{%s}
-Print a string).  @xref{Other Output Conversions}.
+Print a string.  @xref{Other Output Conversions}.
 
 @item @samp{%p}
 Print the value of a pointer.  @xref{Other Output Conversions}.
@@ -666,13 +820,13 @@ Print a literal @samp{%} character.  @xref{Other Output Conversions}.
 printing a @code{size_t} value in decimal notation.  Is this something
 we want to publicize?
 
-If the syntax of a conversion specification is invalid, the behavior is
-undefined.  If there aren't enough function arguments provided to supply
-values for all the conversion specifications in the format template, or
-if the arguments are not of the correct types, the behavior is also
-undefined.  On the other hand, if you supply more arguments than
-conversion specifications, the extra argument values are simply ignored;
-but this is not really a good style to use.
+If the syntax of a conversion specification is invalid, unpredictable
+things will happen, so don't do this.  If there aren't enough function
+arguments provided to supply values for all the conversion
+specifications in the template string, or if the arguments are not of
+the correct types, the results are unpredictable.  If you supply more
+arguments than conversion specifications, the extra argument values are
+simply ignored; this is sometimes useful.
 
 @node Integer Conversions
 @subsection Integer Conversions
@@ -688,7 +842,7 @@ decimal, or hexadecimal number (respectively).  The @samp{%X} conversion
 specification is just like @samp{%x} except that it uses the characters
 @samp{ABCDEF} as digits instead of @samp{abcdef}.
 
-The following flags can be provided:
+The following flags are meaningful:
 
 @table @asis
 @item @samp{-}
@@ -696,8 +850,8 @@ Left-justify the result in the field (instead of the normal
 right-justification).
 
 @item @samp{+}
-For the signed @samp{%d} and @samp{%i} conversions, always include a
-plus or minus sign in the result.
+For the signed @samp{%d} and @samp{%i} conversions, print a
+plus sign if the value is positive.
 
 @item @samp{ }
 For the signed @samp{%d} and @samp{%i} conversions, if the result
@@ -719,16 +873,19 @@ flag is also specified, or if a precision is specified.
 @end table
 
 If a precision is supplied, it specifies the minimum number of digits to
-appear; leading zeros are produced if necessary.  The precision defaults
-to @code{1}.  If you convert a value of zero with a precision of zero,
-then no characters at all are produced.
+appear; leading zeros are produced if necessary.  If you don't specify a
+precision, the number is printed with as many digits as it needs.  If
+you convert a value of zero with a precision of zero, then no characters
+at all are produced.
 
 Without a type modifier, the corresponding argument is treated as an
 @code{int} (for the signed conversions @samp{%i} and @samp{%d}) or
 @code{unsigned int} (for the unsigned conversions @samp{%o}, @samp{%u},
 @samp{%x}, and @samp{%X}).  Recall that since @code{printf} and friends
-are variadic, optional @code{char} and @code{short} arguments are
-already upgraded to @code{int} by the default argument promotions.
+are variadic, any @code{char} and @code{short} arguments are
+automatically converted to @code{int} by the default argument
+promotions.  For arguments of other integer types, you can use these
+modifiers:
 
 @table @samp
 @item h
@@ -748,10 +905,10 @@ an extension supported by the GNU C compiler.  On systems that don't
 support extra-long integers, this is the same as @code{long int}.)
 @end table
 
-For example, using the format string:
+For example, using the template string:
 
 @example
-|%5d|%-5d|%+5d|% 5d|%05d|%5.0d|%5.2d|%d|\n"
+|%5d|%-5d|%+5d|%+-5d|% 5d|%05d|%5.0d|%5.2d|%d|\n"
 @end example
 
 @noindent
@@ -759,9 +916,9 @@ to print numbers using the different options for the @samp{%d}
 conversion gives results like:
 
 @example
-|    0|0    |   +0|    0|00000|     |   00|0|
-|    1|1    |   +1|    1|00001|    1|   01|1|
-|   -1|-1   |   -1|   -1|-0001|   -1|  -01|-1|
+|    0|0    |   +0|+0   |    0|00000|     |   00|0|
+|    1|1    |   +1|+1   |    1|00001|    1|   01|1|
+|   -1|-1   |   -1|-1   |   -1|-0001|   -1|  -01|-1|
 |100000|100000|+100000| 100000|100000|100000|100000|100000|
 @end example
 
@@ -769,7 +926,7 @@ In particular, notice what happens in the last case where the number
 is too large to fit in the minimum field width specified.
 
 Here are some more examples showing how unsigned integers print under
-various format options, using the format string:
+various format options, using the template string:
 
 @example
 "|%5u|%5o|%5x|%5X|%#5o|%#5x|%#5X|%#10.8x|\n"
@@ -785,15 +942,15 @@ various format options, using the format string:
 @node Floating-Point Conversions
 @subsection Floating-Point Conversions
 
-This section discusses the conversion specifications for formatting
-floating-point numbers: the @samp{%f}, @samp{%e}, @samp{%E},
-@samp{%g}, and @samp{%G} conversions.
+This section discusses the conversion specifications for floating-point
+numbers: the @samp{%f}, @samp{%e}, @samp{%E}, @samp{%g}, and @samp{%G}
+conversions.
 
 The @samp{%f} conversion prints its argument in fixed-point notation,
 producing output of the form
 [@code{-}]@var{ddd}@code{.}@var{ddd},
 where the number of digits following the decimal point is controlled
-by the precision.
+by the precision you specify.
 
 The @samp{%e} conversion prints its argument in exponential notation,
 producing output of the form
@@ -805,9 +962,10 @@ the precision.  The exponent always contains at least two digits.  The
 
 The @samp{%g} and @samp{%G} conversions print the argument in the style
 of @samp{%e} or @samp{%E} (respectively) if the exponent would be less
-than -4 or greater than or equal to the precision.  Trailing zeros are
-removed from the fractional portion of the result and a decimal-point
-character appears only if it is followed by a digit.
+than -4 or greater than or equal to the precision; otherwise they use the
+@samp{%f} style.  Trailing zeros are removed from the fractional portion
+of the result and a decimal-point character appears only if it is
+followed by a digit.
 
 The following flags can be used to modify the behavior:
 
@@ -846,8 +1004,8 @@ print; if @code{0} or not specified, it is treated like a value of
 @code{1}.
 
 Without a type modifier, the floating-point conversions use an argument
-of type @code{double}.  (By the default argument conversions, any
-@code{float} arguments are automatically promoted to @code{double}.)
+of type @code{double}.  (By the default argument promotions, any
+@code{float} arguments are automatically converted to @code{double}.)
 The following type modifier is supported:
 
 @table @samp
@@ -858,7 +1016,7 @@ double}.
 
 Here are some examples showing how numbers print using the various
 floating-point conversions.  All of the numbers were printed using
-the format string:
+this template string:
 
 @example
 "|%12.4f|%12.4e|%12.4g|\n"
@@ -889,6 +1047,14 @@ The @samp{%c} conversion prints a single character.  The @code{int}
 argument is first converted to an @code{unsigned char}.  The @samp{-}
 flag can be used to specify left-justification in the field, but no
 other flags are defined, and no precision or type modifier can be given.
+For example:
+
+@example
+printf ("%c%c%c%c%c", 'h', 'e', 'l', 'l', 'o');
+@end example
+
+@noindent
+prints @samp{hello}.
 
 The @samp{%s} conversion prints a string.  The corresponding argument
 must be of type @code{char *}.  A precision can be specified to indicate
@@ -896,22 +1062,41 @@ the maximum number of characters to write; otherwise characters in the
 string up to but not including the terminating null character are
 written to the output stream.  The @samp{-} flag can be used to specify
 left-justification in the field, but no other flags or type modifiers
-are defined for this conversion.
+are defined for this conversion.  For example:
+
+@example
+printf ("%3s%-6s", "no", "where");
+@end example
+
+@noindent
+prints @samp{ nowhere }.
 
 If you accidentally pass a null pointer as the argument for a @samp{%s}
-conversion, the GNU library prints it as @samp{(null)}.  This is more
-because this is such a common program bug than because you ought to depend
-on this behavior in normal use, however.
+conversion, the GNU library prints it as @samp{(null)}.  We think this
+is more useful than crashing.  But it's not good practice to pass a null
+argument intentionally.
 
 The @samp{%p} conversion prints a pointer value.  The corresponding
-argument must be of type @code{void *}.
+argument must be of type @code{void *}.  In practice, you can use any
+type of pointer.
 
 In the GNU system, non-null pointers are printed as unsigned integers,
 as if a @samp{%#x} conversion were used.  Null pointers print as
 @samp{(nil)}.  (Pointers might print differently in other systems.)
 
-Again, you can supply the @samp{-} flag with the @samp{%p} conversion to
-specify left-justification but no other flags, precision, or type
+For example:
+
+@example
+printf ("%p", "testing");
+@end example
+
+@noindent
+prints @samp{0x} followed by a hexadecimal number---the address of the
+string constant @code{"testing"}.  It does not print the word
+@samp{testing}.
+
+You can supply the @samp{-} flag with the @samp{%p} conversion to
+specify left-justification, but no other flags, precision, or type
 modifiers are defined.
 
 The @samp{%n} conversion is unlike any of the other output conversions.
@@ -937,7 +1122,8 @@ prints:
 @end example
 
 @noindent
-and sets @code{nchar} to @code{7}.
+and sets @code{nchar} to @code{7}, because @samp{3 bears} is seven 
+characters.
 
 
 The @samp{%%} conversion prints a literal @samp{%} character.  This
@@ -956,7 +1142,7 @@ Prototypes for these functions are in the header file @file{stdio.h}.
 @comment ANSI
 @deftypefun int printf (const char *@var{template}, @dots{})
 The @code{printf} function prints the optional arguments under the
-control of the format template @var{template} to the stream
+control of the template string @var{template} to the stream
 @code{stdout}.  It returns the number of characters printed, or a
 negative value if there was an output error.
 @end deftypefun
@@ -979,16 +1165,17 @@ The @code{sprintf} function returns the number of characters stored in
 the array @var{s}, not including the terminating null character.
 
 The behavior of this function is undefined if copying takes place
-between objects that overlap --- for example, if @var{s} is also given
+between objects that overlap---for example, if @var{s} is also given
 as an argument to be printed under control of the @samp{%s} conversion.
 @xref{Copying and Concatenation}.
 
 @strong{Warning:} The @code{sprintf} function can be @strong{dangerous}
 because it can potentially output more characters than can fit in the
 allocation size of the string @var{s}.  Remember that the field width
-given in a conversion specification is only a @emph{minimum} value.  The
-@code{snprintf} function lets you specify the maximum number of
-characters to produce.
+given in a conversion specification is only a @emph{minimum} value.
+
+To avoid this problem, you can use @code{snprintf} or @code{asprintf},
+described below.
 @end deftypefun
 
 @comment stdio.h
@@ -997,11 +1184,38 @@ characters to produce.
 The @code{snprintf} function is similar to @code{sprintf}, except that
 the @var{size} argument specifies the maximum number of characters to
 produce.  The trailing null character is counted towards this limit, so
-the largest value you should specify is the allocation size of the array
-@var{s}.
-@end deftypefun
+you should allocate at least @var{size} characters for the string @var{s}.
+
+The return value is the number of characters stored, not including the
+terminating null.  If this value equals @var{size}, then there was not
+enough space in @var{s} for all the output.  You should try again with a
+bigger output string.  Here is an example of doing this:
+
+@smallexample
+/* @r{Print a message describing the value of a variable}
+   @r{whose name is @var{name} and whose value is @var{value}.} */
+char *
+make_message (char *name, char *value)
+@{
+  /* @r{Guess we need no more than 100 chars of space.} */
+  int size = 100;
+  char *buffer = (char *) xmalloc (size);
+  while (1) @{
+    /* @r{Try to print in the allocated space.} */
+    int nchars = snprintf (buffer, size,
+                           "value of %s is %s", name, value);
+    /* @r{If that worked, return the string.} */
+    if (nchars < size)
+      return buffer;
+    /* @r{Else try again with twice as much space.} */
+    size *= 2;
+    buffer = (char *) xrealloc (size, buffer);
+  @}
+@}
+@end smallexample
 
-@strong{Incomplete:}  RMS suggests putting an example here.
+In practice, it is often easier just to use @code{asprintf}, below.
+@end deftypefun
 
 @comment stdio.h
 @comment GNU
@@ -1012,30 +1226,63 @@ Allocation}) to hold the output, instead of putting the output in a
 buffer you allocate in advance.  The @var{ptr} argument should be the
 address of a @code{char *} object, and @code{asprintf} stores a pointer
 to the newly allocated string at that location.
-@end deftypefun
 
-@strong{Incomplete:}  RMS suggests putting an example here.
+Here is how to use @code{asprint} to get the same result as the
+@code{snprintf} example, but more easily:
+
+@smallexample
+/* @r{Print a message describing the value of a variable}
+   @r{whose name is @var{name} and whose value is @var{value}.} */
+char *
+make_message (char *name, char *value)
+@{
+  char *result;
+  snprintf (&result, "value of %s is %s", name, value);
+  return result;
+@}
+@end smallexample
+@end deftypefun
 
 @node Variable Arguments Output Functions
 @subsection Variable Arguments Output Functions
 
 The functions @code{vprintf} and friends are provided so that you can
 define your own variadic @code{printf}-like functions that make use of
-the same internals as the built-in formatted output functions.  Since
-the C language does not have an operator similar to the Lisp
-@code{apply} function that permits a function call (as opposed to a
-function definition) with a non-constant number of arguments, there's
-simply no way for one variadic function to pass the tail of its argument
-list to another variadic function; the second function has to be defined
-in such a way that it takes a @code{va_list} argument instead.
+the same internals as the built-in formatted output functions.
+
+The most natural way to define such functions would be to use a language
+construct to say, ``Call @code{printf} and pass this template plus all
+of my arguments after the first five.''  But there is no way to do this
+in C, and it would be hard to provide a way, since at the C language
+level there is no way to tell how many arguments your function received.
+
+Since that method is impossible, we provide alternative functions, the
+@code{vprintf} series, which lets you pass a @code{va_list} to describe
+``all of my arguments after the first five.''
 
 Before calling @code{vprintf} or the other functions listed in this
 section, you @emph{must} call @code{va_start} (@pxref{Variable Argument
-Facilities}) to initialize @var{ap}, and you @emph{may} call
-@code{va_arg} to skip over some of the initial arguments.  The
-@code{vprintf} function does not invoke the @code{va_end} macro, but
-further calls to @code{va_arg} with @var{ap} are not permitted once
-@code{vprintf} returns.
+Facilities}) to initialize a pointer to the variable arguments.  Then
+you can call @code{va_arg} to fetch the arguments that you want to
+handle yourself.  This advances the pointer past those arguments.
+
+Once your @code{va_list} pointer is pointing at the argument of your
+choice, you are ready to call @code{vprintf}.  That argument and all
+subsequent arguments that were passed to your function are used by
+@code{vprintf} along with the template that you specified separately.
+
+In some other systems, the @code{va_list} pointer may become invalid
+after the call to @code{vprintf}, so you must not use @code{va_arg}
+after you call @code{vprintf}.  Instead, you should call @code{va_end}
+to retire the pointer from service.  However, you can safely call
+@code{va_start} on another pointer variable and begin fetching the
+arguments again through that pointer.  Calling @code{vfprintf} does
+not destroy the argument list of your function, merely the particular
+pointer that you passed to it.
+
+The GNU library does not have such restrictions.  You can safely continue
+to fetch arguments from a @code{va_list} pointer after passing it to
+@code{vprintf}, and @code{va_end} is a no-op.
 
 Prototypes for these functions are declared in @file{stdio.h}.
 @pindex stdio.h
@@ -1085,7 +1332,8 @@ with a prefix indicating the name of the program.
 #include <stdio.h>
 #include <stdarg.h>
 
-void eprintf (char *template, ...)
+void
+eprintf (char *template, ...)
 @{
   va_list ap;
   extern char *program_name;
@@ -1098,49 +1346,185 @@ void eprintf (char *template, ...)
 @end example
 
 @noindent
-You could call this function like:
+You could call @code{eprintf} like this:
 
 @example
-eprintf ("The file %s does not exist.\n", filename);
+eprintf ("file `%s' does not exist\n", filename);
 @end example
 
+@node Parsing a Template String
+@subsection Parsing a Template String
+@cindex parsing a template string
+
+You can use the function @code{parse_printf_format} to obtain
+information about the number and types of arguments that are expected by
+a given template string.  This function permits interpreters that
+provide interfaces to @code{printf} to avoid passing along invalid
+arguments from the user's program, which could cause a crash.
+
+@comment printf.h
+@comment GNU
+@deftypefun size_t parse_printf_format (const char *@var{template}, size_t @var{n}, int *@var{argtypes})
+This function returns information about the number and types of
+arguments expected by the @code{printf} template string @var{template}.
+The information is stored in the array @var{argtypes}.  One element of
+this array is used for each argument expected.  This information is
+encoded using the various @samp{PA_} macros, listed below.
+
+The @var{n} argument specifies the number of elements in the array
+@var{argtypes}.  @code{parse_printf_format} will not try to write more
+elements than this.
+
+@code{parse_printf_format} returns the total number of arguments required
+by @var{template}.  If this number is greater than @var{n}, then the
+information returned describes only the first @var{n} arguments.  If you
+want information about more than that many arguments, allocate a bigger
+array and call @code{parse_printf_format} again.
+@end deftypefun
+
+The argument types are encoded as a combination of a basic type and
+modifier flag bits.
+
+@comment printf.h
+@comment GNU
+@deftypevr Macro int PA_FLAG_MASK
+This macro is a bitmask for the type modifier flag bits.  Write
+@code{(argtypes[i] & PA_FLAG_MASK)} to extract just the flag bits for an
+argument, or @code{(argtypes[i] & ~PA_FLAG_MASK)} to extract just the
+basic type code.
+@end deftypevr
+
+Here are symbolic constants that represent the basic types; they stand
+for integer values.
+
+@comment printf.h
+@comment GNU
+@deftypevr Macro int PA_INT
+This specifies that the base type is @code{int}.
+@end deftypevr
+
+@comment printf.h
+@comment GNU
+@deftypevr Macro int PA_CHAR
+This specifies that the base type is @code{int}, cast to @code{char}.
+@end deftypevr
+
+@comment printf.h
+@comment GNU
+@deftypevr Macro int PA_STRING
+This specifies that the base type is @code{char *}, a null-terminated string.
+@end deftypevr
+
+@comment printf.h
+@comment GNU
+@deftypevr Macro int PA_POINTER
+This specifies that the base type is @code{void *}, an arbitrary pointer.
+@end deftypevr
+
+@comment printf.h
+@comment GNU
+@deftypevr Macro int PA_FLOAT
+This specifies that the base type is @code{double}.
+
+@strong{Incomplete:}  Should this be @code{float} instead?  How do you
+encode the type of @code{float *}?
+@end deftypevr
+
+@comment printf.h
+@comment GNU
+@deftypevr Macro int PA_LAST
+You can define additional base types for your own programs as offsets
+from @code{PA_LAST}.  For example, if you have data types @samp{foo}
+and @samp{bar} with their own specialized @code{printf} conversions,
+you could define encodings for these types as:
+
+@example
+#define PA_FOO  PA_LAST
+#define PA_BAR  (PA_LAST + 1)
+@end example
+@end deftypevr
+
+Here are the flag bits that modify a basic type.  They are combined with
+the code for the basic type using inclusive-or.
+
+@comment printf.h
+@comment GNU
+@deftypevr Macro int PA_FLAG_PTR
+If this bit is set, it indicates that the encoded type is a pointer to
+the base type, rather than an immediate value.
+For example, @samp{PA_INT|PA_FLAG_PTR} represents the type @samp{int *}.
+@end deftypevr
+
+@comment printf.h
+@comment GNU
+@deftypevr Macro int PA_FLAG_SHORT
+If this bit is set, it indicates that the base type is modified with
+@code{short}.  (This corresponds to the @samp{h} type modifier.)
+@end deftypevr
+
+@comment printf.h
+@comment GNU
+@deftypevr Macro int PA_FLAG_LONG
+If this bit is set, it indicates that the base type is modified with
+@code{long}.  (This corresponds to the @samp{l} type modifier.)
+@end deftypevr
+
+@comment printf.h
+@comment GNU
+@deftypevr Macro int PA_FLAG_LONGLONG
+If this bit is set, it indicates that the base type is modified with
+@code{long long}.  (This corresponds to the @samp{L} type modifier.)
+@end deftypevr
+
+@comment printf.h
+@comment GNU
+@deftypevr Macro int PA_FLAG_LONGDOUBLE
+This is a synonym for @code{PA_FLAG_LONGLONG}, used by convention with
+a base type of @code{PA_DOUBLE} to indicate a type of @code{long double}.
+@end deftypevr
+
+@strong{Incomplete:} Should have an example here from a fictional
+interpreter, showing how one might validate a list of args and then
+call @code{vprintf}.
+
 @node Customizing Printf
 @section Customizing Printf
 @cindex customizing @code{printf}
 @cindex defining new @code{printf} conversions
 @cindex extending @code{printf}
 
-The GNU C library lets you define new conversion specifiers for 
-@code{printf} format templates.  To do this, you must include the
-header file @file{printf.h} in your program.
-@pindex printf.h
+The GNU C library lets you define your own custom conversion specifiers
+for @code{printf} template strings, to teach @code{printf} clever ways
+to print the important data structures of your program.
 
 The way you do this is by registering the conversion with
-@code{register_printf_function}; @pxref{Registering New Conversions}.
+@code{register_printf_function}; see @ref{Registering New Conversions}.
 One of the arguments you pass to this function is a pointer to a handler
-function that produces the actual output; @pxref{Defining the Output Handler},
-for information on how to write this function.  
+function that produces the actual output; see @ref{Defining the Output
+Handler}, for information on how to write this function.
 
 You can also install a function that just returns information about the
 number and type of arguments expected by the conversion specifier.
-@xref{Parsing a Format Template}, for information about this.
+@xref{Parsing a Template String}, for information about this.
+
+The facilities of this section are declared in the header file
+@file{printf.h}.
 
 @menu
 * Registering New Conversions::
 * Conversion Specifier Options::
 * Defining the Output Handler::
-* Parsing a Format Template::
 * Printf Extension Example::
 @end menu
 
 @strong{Portability Note:} The ability to extend the syntax of
-@code{printf} format templates is a GNU extension.  ANSI standard C has
+@code{printf} template strings is a GNU extension.  ANSI standard C has
 nothing similar.
 
 @node Registering New Conversions
 @subsection Registering New Conversions
 
-The function to register a new conversion is
+The function to register a new output conversion is
 @code{register_printf_function}, declared in @file{printf.h}.
 @pindex printf.h
 
@@ -1148,23 +1532,25 @@ The function to register a new conversion is
 @comment GNU
 @deftypefun int register_printf_function (int @var{spec}, printf_function @var{handler_function}, printf_arginfo_function @var{arginfo_function})
 This function defines the conversion specifier character @var{spec}.
+Thus, if @var{spec} is @code{'q'}, it defines the conversion @samp{%q}.
 
 The @var{handler_function} is the function called by @code{printf} and
-friends when this conversion appears in a format template string.
+friends when this conversion appears in a template string.
 @xref{Defining the Output Handler}, for information about how to define
 a function to pass as this argument.  If you specify a null pointer, any
 existing handler function for @var{spec} is removed.
 
 The @var{arginfo_function} is the function called by
-@code{parse_printf_format} when this conversion appears in a format
-template string.  @xref{Parsing a Format Template}, for information
+@code{parse_printf_format} when this conversion appears in a
+template string.  @xref{Parsing a Template String}, for information
 about this.
 
 Normally, you install both functions for a conversion at the same time,
 but if you are never going to call @code{parse_printf_format}, you do
 not need to define an arginfo function.
 
-The return value is @code{0} on success, and @code{-1} on failure.
+The return value is @code{0} on success, and @code{-1} on failure
+(which occurs if @var{spec} is out of range).
 
 You can redefine the standard output conversions, but this is probably
 not a good idea because of the potential for confusion.  Library routines
@@ -1174,6 +1560,11 @@ written by other people could break if you do this.
 @node Conversion Specifier Options
 @subsection Conversion Specifier Options
 
+If you define a meaning for @samp{%q}, what if the template contains
+@samp{%+Sq} or @samp{%-#q}?  To implement a sensible meaning for these,
+the handler when called needs to be able to get the options specified in
+the template.
+
 Both the @var{handler_function} and @var{arginfo_function} arguments
 to @code{register_printf_function} accept an argument of type
 @code{struct print_info}, which contains information about the options
@@ -1185,30 +1576,32 @@ is declared in the header file @file{printf.h}.
 @comment GNU
 @deftp {struct Type} printf_info
 This structure is used to pass information about the options appearing
-in an instance of a conversion specifier in a @code{printf} format
-template to the handler and arginfo functions for that specifier.  It
+in an instance of a conversion specifier in a @code{printf} template
+string to the handler and arginfo functions for that specifier.  It
 contains the following members:
 
 @table @code
 @item int prec
-This is the precision.  The value is @code{-1} if no precision was specified.
-If the precision was given as @samp{*}, the @code{printf_info} structure
-passed to the handler function contains the actual value retrieved from
-the argument list.  But the structure passed to the arginfo function
-contains a value of @code{INT_MIN}, since the actual value is not known.
+This is the precision specified.  The value is @code{-1} if no precision
+was specified.  If the precision was given as @samp{*}, the
+@code{printf_info} structure passed to the handler function contains the
+actual value retrieved from the argument list.  But the structure passed
+to the arginfo function contains a value of @code{INT_MIN}, since the
+actual value is not known.
 
 @item int width
-This is the minimum field width.  The value is @code{0} if no width was
-specified.  If the field width was given as @samp{*}, the
-@code{printf_info} structure passed to the handler function contains
-the actual value retrieved from the argument list.  But the structure
-passed to the arginfo function contains a value of @code{INT_MIN},
-since the actual value is not known.
+This is the minimum field width specified.  The value is @code{0} if no
+width was specified.  If the field width was given as @samp{*}, the
+@code{printf_info} structure passed to the handler function contains the
+actual value retrieved from the argument list.  But the structure passed
+to the arginfo function contains a value of @code{INT_MIN}, since the
+actual value is not known.
 
 @item char spec
-This is the conversion specifier character.  It's stored in the structure
-so that you can register the same handler function for multiple characters,
-but still have a way to tell them apart when the handler function is called.
+This is the conversion specifier character specified.  It's stored in
+the structure so that you can register the same handler function for
+multiple characters, but still have a way to tell them apart when the
+handler function is called.
 
 @item unsigned int is_long_double
 This is a boolean that is true if the @samp{L} type modifier was specified.
@@ -1245,80 +1638,54 @@ width.  The value is @code{'0'} if the @samp{0} flag was specified, and
 Now let's look at how to define the handler and arginfo functions
 which are passed as arguments to @code{register_printf_function}.
 
-@comment printf.h
-@comment GNU
-@deftp {Data Type} printf_function
-This type is used to describe handler functions for conversion specifiers.
-
 You should define your handler functions with a prototype like:
 
 @example
-int @var{function} (FILE *@var{stream}, const struct printf_info *@var{info},
-                    va_list *@var{app})
+int @var{function} (FILE *stream, const struct printf_info *info,
+                    va_list *ap_pointer)
 @end example
 
-The @var{stream} argument passed to the handler function is the stream to
+The @code{stream} argument passed to the handler function is the stream to
 which it should write output.
 
-The @var{info} argument is a pointer to a structure that contains
+The @code{info} argument is a pointer to a structure that contains
 information about the various options that were included with the
-conversion in the format template string.  You should not modify this
-structure inside your handler function.
-
-The @var{app} argument is used to pass the tail of the variable argument
-list containing the values to be printed to your handler.  Unlike most
-other functions that can be passed an explicit variable argument list,
-this is a @emph{pointer} to a @code{va_list}, rather than the
-@code{va_list} itself.  (Basically, passing a pointer here allows the
-function that calls your handler function to update its own @code{va_list}
-variable to account for the arguments that your handler processes.)
-@xref{Variable Argument Facilities}.
+conversion in the template string.  You should not modify this structure
+inside your handler function.  @xref{Conversion Specifier Options}, for
+a description of this data structure.
+
+The @code{ap_pointer} argument is used to pass the tail of the variable
+argument list containing the values to be printed to your handler.
+Unlike most other functions that can be passed an explicit variable
+argument list, this is a @emph{pointer} to a @code{va_list}, rather than
+the @code{va_list} itself.  Thus, you should fetch arguments by
+means of @code{va_arg (@var{type}, *ap_pointer)}.
+
+(Passing a pointer here allows the function that calls your handler
+function to update its own @code{va_list} variable to account for the
+arguments that your handler processes.  @xref{Variable Argument
+Facilities}.)
 
 The return value from your handler function should be the number of
 argument values that it processes from the variable argument list.  You
 can also return a value of @code{-1} to indicate an error.
-@end deftp
-
-
-@node Parsing a Format Template
-@subsection Parsing a Format Template
-@cindex parsing a format template
-
-You can use the function @code{parse_printf_format} to obtain information
-about the number and types of arguments that are expected by a format
-template.  This function is primarily intended for performing error checking
-on calls to @code{printf} and related functions from within applications
-such as interpreters.
 
 @comment printf.h
 @comment GNU
-@deftypefun size_t parse_printf_format (const char *@var{template}, size_t @var{n}, int *@var{argtypes})
-This function returns information about the number and types of arguments
-expected by the @code{printf} format template @var{template}.  
-
-The @var{n} argument specifies the maximum number of arguments.  The
-allocation size of the array @var{argtypes} should be at least this many
-elements.  The return value is the actual number of arguments expected,
-and the array is filled in with information about their types.  This
-information is encoded using the various @samp{PA_} macros, listed below.
-@end deftypefun
+@deftp {Data Type} printf_function
+This is the data type that a handler function should have.
+@end deftp
 
-If you have are going to use @code{parse_printf_format} in your
+If you are going to use @code{parse_printf_format} in your
 application, you should also define a function to pass as the
 @var{arginfo_function} argument for each new conversion you install with
 @code{register_printf_function}. 
 
-@comment printf.h
-@comment GNU
-@deftp {Data Type} printf_arginfo_function
-This type is used to describe functions that return information about
-the number and type of arguments used by a conversion specifier.
-
 You should define these functions with a prototype like:
 
 @example
-int @var{function} (const struct printf_info *@var{info},
-                    size_t @var{n}, int *@var{argtypes})
+int @var{function} (const struct printf_info *info,
+                    size_t n, int *argtypes)
 @end example
 
 The return value from the function should be the number of arguments
@@ -1326,103 +1693,13 @@ the conversion expects, up to a maximum of @var{n}.  The function should
 also fill in the @var{argtypes} array with information about the types
 of each of these arguments.  This information is encoded using the
 various @samp{PA_} macros.
-@end deftp
-
-The types of the arguments expected by a @code{printf} conversion are
-encoded by using one of these base types:
-
-@comment printf.h
-@comment GNU
-@deftypevr Macro int PA_INT
-This specifies that the base type is @code{int}.
-@end deftypevr
-
-@comment printf.h
-@comment GNU
-@deftypevr Macro int PA_CHAR
-This specifies that the base type is @code{int}, cast to @code{char}.
-@end deftypevr
-
-@comment printf.h
-@comment GNU
-@deftypevr Macro int PA_STRING
-This specifies that the base type is @code{char *}, a null-terminated string.
-@end deftypevr
-
-@comment printf.h
-@comment GNU
-@deftypevr Macro int PA_POINTER
-This specifies that the base type is @code{void *}, an arbitrary pointer.
-@end deftypevr
-
-@comment printf.h
-@comment GNU
-@deftypevr Macro int PA_FLOAT
-This specifies that the base type is @code{double}.
-
-@strong{Incomplete:}  Should this be @code{float} instead?  How do you
-encode the type of @code{float *}?
-@end deftypevr
-
-@comment printf.h
-@comment GNU
-@deftypevr Macro int PA_LAST
-You can define additional base types for your own programs as offsets
-from @code{PA_LAST}.  For example, if you have data types @samp{foo}
-and @samp{bar} with their own specialized @code{printf} conversions,
-you could define encodings for these types as:
-
-@example
-#define PA_FOO  PA_LAST
-#define PA_BAR  (PA_LAST + 1)
-@end example
-@end deftypevr
-
-You can also specify type modifiers in the encoded type as a bit mask,
-using the following macros:
 
 @comment printf.h
 @comment GNU
-@deftypevr Macro int PA_FLAG_MASK
-This macro can be used to extract the type modifier flags from an encoded
-type.
-@end deftypevr
-
-@comment printf.h
-@comment GNU
-@deftypevr Macro int PA_FLAG_PTR
-If this bit is set, it indicates that the encoded type is a pointer to
-the base type, rather than an immediate value.
-For example, @samp{PA_INT|PA_FLAG_PTR} represents the type @samp{int *}.
-@end deftypevr
-
-@comment printf.h
-@comment GNU
-@deftypevr Macro int PA_FLAG_SHORT
-If this bit is set, it indicates that the base type is modified with
-@code{short}.  (This corresponds to the @samp{h} type modifier.)
-@end deftypevr
-
-@comment printf.h
-@comment GNU
-@deftypevr Macro int PA_FLAG_LONG
-If this bit is set, it indicates that the base type is modified with
-@code{long}.  (This corresponds to the @samp{l} type modifier.)
-@end deftypevr
-
-@comment printf.h
-@comment GNU
-@deftypevr Macro int PA_FLAG_LONGLONG
-If this bit is set, it indicates that the base type is modified with
-@code{long long}.  (This corresponds to the @samp{L} type modifier.)
-@end deftypevr
-
-@comment printf.h
-@comment GNU
-@deftypevr Macro int PA_FLAG_LONGDOUBLE
-This is a synonym for @code{PA_FLAG_LONGLONG}, used by convention with
-a base type of @code{PA_FLOAT} to indicate a type of @code{long double}.
-@end deftypevr
+@deftp {Data Type} printf_arginfo_function
+This type is used to describe functions that return information about
+the number and type of arguments used by a conversion specifier.
+@end deftp
 
 @node Printf Extension Example
 @subsection Printf Extension Example
@@ -1439,42 +1716,44 @@ left-justification options, but ignores everything else.
 #include <printf.h>
 #include <stdarg.h>
 
-typedef struct widget @{
-    char *name;
-    @dots{}
-@} Widget;
-
+struct widget 
+@{
+  char *name;
+  @dots{}
+@};
 
-int print_widget (FILE *stream, const struct printf_info *info,
-                 va_list *app)
+int
+print_widget (FILE *stream, const struct printf_info *info,
+              va_list *app)
 @{
-  Widget *w;
+  struct widget *w;
   char *buffer;
-  int fill, i;
+  int padding_amount, i;
 
+  /* @r{Fetch the widget to be printed.} */
+  w = va_arg (*app, struct widget *);
   /* @r{Format the output into a string.} */
-  w = va_arg (*app, Widget *);
-  fill = info->width -
-      asprintf (&buffer, "<Widget %p: %s>", w, w->name);
+  padding_amount
+    = (info->width -
+       asprintf (&buffer, "<Widget %p: %s>", w, w->name));
 
   /* @r{Pad to the minimum field width and print to the stream.} */
   if (!info->left)
-    for (i=0; i<fill; i++) fputc (' ', stream);
+    for (i = 0; i < padding_amount; i++) fputc (' ', stream);
   fputs (buffer, stream);
   if (info->left)
-    for (i=0; i<fill; i++) fputc (' ', stream);
+    for (i = 0; i < padding_amount; i++) fputc (' ', stream);
 
   /* @r{Clean up and return.} */
   free (buffer);
   return 1;
 @}
 
-
-void main (void)
+void
+main (void)
 @{
-
   /* @r{Make a widget to print.} */
-  Widget mywidget;
+  struct widget mywidget;
   mywidget.name = "mywidget";
 
   /* @r{Register the print function for widgets.} */
@@ -1506,16 +1785,17 @@ The functions described in this section (@code{scanf} and related
 functions) provide facilities for formatted input analogous to the
 formatted output facilities.  These functions provide a mechanism for
 reading arbitrary values under the control of a @dfn{format string} or
-@dfn{template}.
+@dfn{template string}.
 
 @menu
 * Formatted Input Basics::      Some basics to get you started.
-* Input Conversion Syntax::    Syntax of conversion specifications.
-* Table of Input Conversions:: Summary of input conversions and what they do.
-* Numeric Input Conversions::  Details of conversions for reading numbers.
-* String Input Conversions::   Details of conversions for reading strings.
-* Other Input Conversions::    Details of miscellaneous other conversions.
-* Formatted Input Functions::  Descriptions of the actual functions.
+* Input Conversion Syntax::     Syntax of conversion specifications.
+* Table of Input Conversions::  Summary of input conversions and what they do.
+* Numeric Input Conversions::   Details of conversions for reading numbers.
+* String Input Conversions::    Details of conversions for reading strings.
+* Other Input Conversions::     Details of miscellaneous other conversions.
+* Formatted Input Functions::   Descriptions of the actual functions.
+* Variable Arguments Input Functions::   @code{vscanf} and friends.
 @end menu
 
 @node Formatted Input Basics
@@ -1523,7 +1803,7 @@ reading arbitrary values under the control of a @dfn{format string} or
 
 Calls to @code{scanf} are superficially similar to calls to
 @code{printf} in that arbitrary arguments are read under the control of
-a format template string.  While the syntax of the conversion
+a template string.  While the syntax of the conversion
 specifications in the template is very similar to that for
 @code{printf}, the interpretation of the template is oriented more
 towards free-format input and simple pattern matching, rather than
@@ -1556,7 +1836,8 @@ in the contents of tables.  For example, here is a function that uses
 @code{scanf} to initialize an array of @code{double}s:
 
 @example
-void readarray (double *array, int n)
+void
+readarray (double *array, int n)
 @{
   int i;
   for (i=0; i<n; i++)
@@ -1574,12 +1855,12 @@ If you are trying to read input that doesn't match a single, fixed
 pattern, you may be better off using a tool such as Bison to generate
 a parser, rather than using @code{scanf}.  For more information about
 this, see @cite{The Bison Reference Manual}.
-
+@c ??? Don't use @cite, use @xref with five args.
 
 @node Input Conversion Syntax
 @subsection Input Conversion Syntax
 
-A @code{scanf} format template is a string that contains ordinary
+A @code{scanf} template string is a string that contains ordinary
 multibyte characters and conversion specifications introduced by a
 @samp{%} character.
 
@@ -1587,13 +1868,15 @@ Any whitespace character (as defined by the @code{isspace} function;
 @pxref{Classification of Characters}) in the template causes any number
 of whitespace characters in the input stream to be read and discarded.
 The whitespace characters that are matched need not be exactly the same
-whitespace characters that appear in the format template.
+whitespace characters that appear in the template string.  For example,
+write @samp{ , } in the template to recognize a comma with optional
+whitespace before and after.
 
-Other characters in the format template that are not part of conversion
+Other characters in the template string that are not part of conversion
 specifications must match characters in the input stream exactly; if
 this is not the case, a matching failure occurs.
 
-The conversion specifications in a @code{scanf} format template
+The conversion specifications in a @code{scanf} template string
 have the general form:
 
 @example
@@ -1608,8 +1891,8 @@ More specifically, input conversion specifications consist of an initial
 An optional @dfn{flag character} @samp{*}, which causes assignment to be
 suppressed.  If this flag appears, input is read from the stream and
 matched against the conversion specification in the usual way, but no
-optional argument is used, no assignment takes place, and the count
-of successful assignments is not incremented.
+optional pointer argument is used, no assignment takes place, and the
+count of successful assignments is not incremented.
 @cindex flag character (@code{scanf})
 
 @item
@@ -1619,6 +1902,8 @@ this maximum is reached or when a non-matching character is found,
 whichever happens first.  Most conversions discard initial whitespace
 characters (those that don't are explicitly documented), and these
 discarded characters don't count towards the maximum field width.
+Most input conversions store a null character to mark the end of the
+input; the maximum field width does not include this terminator.
 @cindex maximum field width (@code{scanf})
 
 @item
@@ -1645,7 +1930,7 @@ Here is a table that summarizes the various conversion specifications:
 
 @table @asis
 @item @samp{%d}
-Matches an optionally signed integer in decimal radix; @pxref{Numeric
+Matches an optionally signed integer written in decimal.  @xref{Numeric
 Input Conversions}.
 
 @item @samp{%i}
@@ -1654,19 +1939,19 @@ language defines for specifying an integer constant.  @xref{Numeric
 Input Conversions}.
 
 @item @samp{%o}
-Matches an unsigned integer in octal radix; @pxref{Numeric
+Matches an unsigned integer in octal radix.  @xref{Numeric
 Input Conversions}.
 
 @item @samp{%u}
-Matches an unsigned integer in decimal radix; @pxref{Numeric
+Matches an unsigned integer in decimal radix.  @xref{Numeric
 Input Conversions}.
 
 @item @samp{%x}, @samp{%X}
-Matches an unsigned integer in hexadecimal radix; @pxref{Numeric
+Matches an unsigned integer in hexadecimal radix.  @xref{Numeric
 Input Conversions}.
 
 @item @samp{%e}, @samp{%f}, @samp{%g}, @samp{%E}, @samp{%G}
-Matches an optionally signed floating-point number; @pxref{Numeric Input
+Matches an optionally signed floating-point number.  @xref{Numeric Input
 Conversions}.
 
 @item @samp{%s}
@@ -1674,8 +1959,8 @@ Matches a string of non-whitespace characters.  @xref{String Input
 Conversions}.
 
 @item @samp{%[}
-Matches a string of characters that belong to a set.  @xref{String Input
-Conversions}.
+Matches a string of characters that belong to a specified set.
+@xref{String Input Conversions}.
 
 @item @samp{%c}
 Matches a string of one or more characters; the number of characters
@@ -1688,7 +1973,7 @@ by the @samp{%p} output conversion for @code{printf}.  @xref{Other Input
 Conversions}.
 
 @item @samp{%n}
-This conversion doesn't read any characters; it produces the number of
+This conversion doesn't read any characters; it records the number of
 characters read so far by this call.  @xref{Other Input Conversions}.
 
 @item @samp{%%}
@@ -1698,7 +1983,7 @@ corresponding argument is used.  @xref{Other Input Conversions}.
 
 If the syntax of a conversion specification is invalid, the behavior is
 undefined.  If there aren't enough function arguments provided to supply
-addresses for all the conversion specifications in the format template
+addresses for all the conversion specifications in the template strings
 that perform assignments, or if the arguments are not of the correct
 types, the behavior is also undefined.  On the other hand, if there are
 extra arguments, their values are simply ignored.
@@ -1779,12 +2064,16 @@ Specifies that the argument is of type @code{long double *}.
 
 This section describes the @code{scanf} input conversions for reading
 string and character values: @samp{%s}, @samp{%[}, and @samp{%c}.  
-
 The corresponding argument for all of these conversions should be of
-type @code{char *}.  Make sure that the allocation size of the array
-that the argument points to is large enough to hold all the characters
-and the null character which is added to mark the end of the string.
-You can specify a field width to limit the number of characters read.
+type @code{char *}.
+
+@strong{Warning:} the argument points to an array of characters where
+the input is stored.  To make a robust program, you must make sure that
+the input (including terminating null) cannot possibly exceed the size
+of this array.  In general, the only way to do this is to specify a
+maximum field width equal to the size you have allocated (minus one, to
+leave room for the terminating null).  @strong{Always specify a field
+width to limit the number of characters read.}
 
 The @samp{%c} conversion is the simplest.  It matches a fixed-sized
 string of characters.  The number of characters read is controlled by
@@ -1795,9 +2084,12 @@ initial whitespace characters.
 
 The @samp{%s} conversion matches a string of non-whitespace characters.
 Unlike @samp{%c}, this conversion does skip over initial whitespace and
-does mark the end of the string with a null character.  If you do not
-specify a field width for @samp{%s}, then the number of characters read
-is limited only by where the next whitespace character appears.
+does mark the end of the string with a null character.
+
+@strong{Warning:} If you do not specify a field width for @samp{%s},
+then the number of characters read is limited only by where the next
+whitespace character appears.  This almost certainly means your program
+will crash if given invalid input.
 
 For example, reading the input:
 
@@ -1819,7 +2111,7 @@ cases:
 
 @itemize @bullet
 @item 
-If a cirumflex character @samp{^} immediately follows the
+If a caret character @samp{^} immediately follows the
 initial @samp{[}, then the set that is used for matching is the
 @emph{complement} of the set of characters that are explicitly listed.
 
@@ -1838,29 +2130,35 @@ characters.
 Here are some examples of @samp{%[} conversions and what they mean.
 
 @table @samp
-@item %[1234567890]
-Matches a string of digits.
+@item %25[1234567890]
+Matches a string of up to 25 digits.
 
-@item %[][]
-Matches a string of square brackets.
+@item %25[][]
+Matches a string of up to 25 square brackets.
 
-@item %[^ \f\n\r\t\v]
-Matches a string that doesn't contain any of the standard whitespace
-characters.  This is slightly different from @samp{%s}, because if the
-input begins with a whitespace character, @samp{%[} reports a
-matching failure while @samp{%s} simply discards the initial
-whitespace.
+@item %25[^ \f\n\r\t\v]
+Matches a string up to 25 characters long that doesn't contain any of
+the standard whitespace characters.  This is slightly different from
+@samp{%s}, because if the input begins with a whitespace character,
+@samp{%[} reports a matching failure while @samp{%s} simply discards the
+initial whitespace.
 
 @item %[a-z] 
 Matches a string of lowercase characters.
 @end table
 
-The @samp{%s} and @samp{%[} conversions are potentially
-@strong{dangerous} because they can overflow the allocation size of the
-argument string.  You should @strong{always} specify a maximum field
-width with the @samp{%s} and @samp{%[} conversions to prevent this from
-happening (but then you will probably get a matching error instead if
-the input string is too long).
+One more reminder: the @samp{%s} and @samp{%[} conversions are
+potentially @strong{dangerous} if you don't specify a maximum width,
+because input too long would overflow whatever buffer you have provided
+for it.  No matter how long your buffer is, a user could supply input
+that is longer.  Don't assume that the input will be short enough to
+fit; a well-written program reports invalid input with a comprehensible
+error message, not with a crash.
+
+So make your programs clean---@strong{always} specify a maximum field
+width with the @samp{%s} and @samp{%[} conversions.  Then you will
+probably get a matching error instead if the input string is too long,
+and you can detect this and report it properly.
 
 
 @node Other Input Conversions
@@ -1871,7 +2169,7 @@ This section describes the miscellaneous input conversions.
 The @samp{%p} conversion is used to read a pointer value.  It recognizes
 the same syntax as is used by the @samp{%p} output conversion for
 @code{printf}.  The corresponding argument should be of type @code{void **};
-that is, the address of a pointer.
+that is, the address of a place to store a pointer.
 
 The resulting pointer value is not guaranteed to be valid if it was not
 originally written during the same program execution that reads it in.
@@ -1879,10 +2177,15 @@ originally written during the same program execution that reads it in.
 The @samp{%n} conversion produces the number of characters read so far
 by this call.  The corresponding argument should be of type @code{int *}.
 This conversion works in the same way as the @samp{%n} conversion for
-@code{printf}; @pxref{Other Output Conversions}, for an example.
+@code{printf}; see @ref{Other Output Conversions}, for an example.
 
 The @samp{%n} conversion is the only mechanism for determining the
 success of literal matches or conversions with suppressed assignments.
+If the @samp{%n} follows the locus of a matching failure, then no value
+is stored for it since @code{scanf} returns before processing the
+@samp{%n}.  If you store @code{-1} in that argument slot before calling
+@code{scanf}, the presence of @code{-1} after @code{scanf} indicates an
+error before the @samp{%n} was reached.
 
 Finally, the @samp{%%} conversion matches a literal @samp{%} character
 in the input stream, without using an argument.  This conversion does
@@ -1900,7 +2203,7 @@ Prototypes for these functions are in the header file @file{stdio.h}.
 @comment ANSI
 @deftypefun int scanf (const char *@var{template}, @dots{})
 The @code{scanf} function reads formatted input from the stream
-@code{stdin} under the control of the format template @var{template}.
+@code{stdin} under the control of the template string @var{template}.
 The optional arguments are pointers to the places which receive the
 resulting values.
 
@@ -1921,30 +2224,35 @@ from the stream @var{stream} instead of @code{stdin}.
 @comment ANSI
 @deftypefun int sscanf (const char *@var{s}, const char *@var{template}, @dots{})
 This is like @code{scanf}, except that the characters are taken from the
-null-terminated string @var{s} instead of read from a stream.  Reaching
-the end of the string is treated as an end-of-file condition.
+null-terminated string @var{s} instead of from a stream.  Reaching the
+end of the string is treated as an end-of-file condition.
 
 The behavior of this function is undefined if copying takes place
-between objects that overlap --- for example, if @var{s} is also given
+between objects that overlap---for example, if @var{s} is also given
 as an argument to receive a string read under control of the @samp{%s}
 conversion.
 @end deftypefun
 
+@node Variable Arguments Input Functions
+@subsection Variable Arguments Input Functions
+
+The functions @code{vscanf} and friends are provided so that you can
+define your own variadic @code{scanf}-like functions that make use of
+the same internals as the built-in formatted output functions.
+These functions are analogous to the @code{vprintf} series of output
+functions.  @xref{Variable Arguments Output Functions}, for important
+information on how to use them.
+
+@strong{Portability Note:} The functions listed in this section are GNU
+extensions.
+
 @comment stdio.h
 @comment GNU
 @deftypefun int vscanf (const char *@var{template}, va_list @var{ap})
 This function is similar to @code{scanf} except that, instead of taking
 a variable number of arguments directly, it takes an argument list
-pointer @var{ap}.  Before calling @code{vscanf}, you @emph{must} call
-@code{va_start} (@pxref{Variable Argument Facilities}) to initialize
-@var{ap}, and you @emph{may} call @code{va_arg} to skip over some of the
-initial arguments.  The @code{vscanf} function does not invoke the
-@code{va_end} macro, but further calls to @code{va_arg} with @var{ap}
-are not permitted once @code{vscanf} returns.
-
-The @code{vscanf} function is typically used to do input in the same
-kinds of situations as where @code{vprintf} is used to do output.
-@xref{Formatted Output Functions}.
+pointer @var{ap} of type @code{va_list} (@pxref{Variable Argument
+Facilities}).
 @end deftypefun
 
 @comment stdio.h
@@ -1961,11 +2269,6 @@ This is the equivalent of @code{sscanf} with the variable argument list
 specified directly as for @code{vscanf}.
 @end deftypefun
 
-@strong{Portability Note:} Of the functions listed in this section, only
-@code{scanf}, @code{fscanf}, and @code{sscanf} are included in ANSI C.
-The @code{vscanf}, @code{vfscanf}, and @code{vsscanf} functions are
-GNU extensions.
-
 @node Block Input/Output
 @section Block Input/Output
 
@@ -1973,19 +2276,19 @@ This section describes how to do input and output operations on blocks
 of data.  You can use these functions to read and write binary data, as
 well as to read and write text in fixed-size blocks instead of by
 characters or lines.
-@cindex binary i/o to a stream
-@cindex block i/o to a stream
+@cindex binary I/O to a stream
+@cindex block I/O to a stream
 @cindex reading from a stream, by blocks
 @cindex writing to a stream, by blocks
 
 Binary files are typically used to read and write blocks of data in the
 same format as is used to represent the data in a running program.  In
-other words, arbitrary blocks of memory --- not just character or string
-objects --- can be written to a binary file, and meaningfully read in
-again under the same implementation.
+other words, arbitrary blocks of memory---not just character or string
+objects---can be written to a binary file, and meaningfully read in
+again by the same program.
 
 Storing data in binary form is often considerably more efficient than
-using the formatted i/o functions.  Also, for floating-point numbers,
+using the formatted I/O functions.  Also, for floating-point numbers,
 the binary form avoids possible loss of precision in the conversion
 process.  On the other hand, binary files can't be examined or modified
 easily using many standard file utilities (such as text editors), and
@@ -2004,6 +2307,9 @@ number of objects actually read, which might be less than @var{count} if
 a read error or end-of-file occurs.  This function returns a value of
 zero (and doesn't read anything) if either @var{size} or @var{count} is
 zero.
+
+@c ??? What happens for EOF in middle of an object?
+@c ??? Does this always read an integral number of objects?
 @end deftypefun
 
 @comment stdio.h
@@ -2013,6 +2319,10 @@ This function writes up to @var{count} objects of size @var{size} from
 the array @var{data}, to the stream @var{stream}.  The return value is
 the number of objects actually written, which is less than @var{count}
 only if a write error occurs.
+
+@c ??? What happens if medium is full in the middle of an object?
+@c ??? Does it write an incomplete object?
+@c ??? Can that happen in any other case?
 @end deftypefun
 
 
@@ -2026,28 +2336,28 @@ Since @code{EOF} is used to report both end-of-file and random errors,
 it's often better to use the @code{feof} function to check explicitly
 for end-of-file and @code{ferror} to check for errors.  These functions
 check indicators that are part of the internal state of the stream
-object, that are set if the appropriate condition was detected by a
-previous i/o operation on that stream.
+object, indicators set if the appropriate condition was detected by a
+previous I/O operation on that stream.
 
-These facilities are declared in the header file @file{stdio.h}.
+These symbols are declared in the header file @file{stdio.h}.
 @pindex stdio.h
 
 @comment stdio.h
 @comment ANSI
 @deftypevr Macro int EOF
-This macro expands to an integer constant expression that is returned
+This macro is an integer value that is returned
 by a number of functions to indicate an end-of-file condition, or some
-other error situation.  The value of this constant is always a negative
-number; in the GNU system, its value is @code{-1}.
+other error situation.  With the GNU library, @code{EOF} is @code{-1}.
+In other libraries, its value may be some other negative number.
 @end deftypevr
 
 @comment stdio.h
 @comment ANSI
 @deftypefun void clearerr (FILE *@var{stream})
-This function resets the end-of-file and error indicators for the
+This function clears the end-of-file and error indicators for the
 stream @var{stream}.
 
-The file positioning functions (@pxref{File Positioning}) also reset the
+The file positioning functions (@pxref{File Positioning}) also clear the
 end-of-file indicator for the stream.
 @end deftypefun
 
@@ -2070,14 +2380,70 @@ In addition to setting the error indicator associated with the stream,
 the functions that operate on streams also set @code{errno} in the same
 way as the corresponding low-level functions that operate on file
 descriptors.  For example, all of the functions that perform output to a
-stream --- such as @code{fputc}, @code{printf}, and @code{fflush} ---
-behave as if they were implemented in terms of @code{write}, and all of
-the @code{errno} error conditions defined for @code{write} are
-meaningful for these functions.
+stream---such as @code{fputc}, @code{printf}, and @code{fflush}---are
+implemented in terms of @code{write}, and all of the @code{errno} error
+conditions defined for @code{write} are meaningful for these functions.
+For more information about the descriptor-level I/O functions, see
+@ref{Low-Level Input/Output}.
+
+@node Text and Binary Streams
+@section Text and Binary Streams
+
+The GNU system and other POSIX-compatible operating systems organize all
+files as uniform sequences of characters.  However, some other systems
+make a distinction between files containing text and files containing
+binary data, and the input and output facilities of ANSI C provide for
+this distinction.  This section tells you how to write programs portable
+to such systems.
 
-For more information about the functions that operate on file
-descriptors, @pxref{Low-Level Input/Output}.
+@cindex text stream
+@cindex binary stream
+When you open a stream, you can specify either a @dfn{text stream} or a
+@dfn{binary stream}.  You indicate that you want a binary stream by
+specifying the @samp{b} modifier in the @var{opentype} argument to
+@code{fopen}; see @ref{Opening and Closing Streams}.  Without this
+option, @code{fopen} opens the file as a text stream.
 
+Text and binary streams differ in several ways:
+
+@itemize @bullet
+@item
+The data read from a text stream is divided into @dfn{lines} which are
+terminated by newline (@code{'\n'}) characters, while a binary stream is
+simply a long series of characters.  A text stream might on some systems
+fail to handle lines more than 254 characters long (including the
+terminating newline character).
+@cindex lines (in a text file)
+
+@item
+On some systems, text files can contain only printing characters,
+horizontal tab characters, and newlines, and so text streams may not
+support other characters.  However, binary streams can handle any
+character value.
+
+@item
+Space characters that are written immediately preceeding a newline
+character in a text stream may disappear when the file is read in again.
+
+@item
+More generally, there need not be a one-to-one mapping between
+characters that are read from or written to a text stream, and the
+characters in the actual file.
+@end itemize
+
+Since a binary stream is always more capable and more predictable than a
+text stream, you might wonder what purpose text streams serve.  Why not
+simply always use binary streams?  The answer is that on these operating
+systems, text and binary streams use different file formats, and the
+only way to read or write ``an ordinary file of text'' that can work
+with other text-oriented programs is through a text stream.
+
+@c ??? Roland, is this true?
+On POSIX systems, there is no difference between text streams and binary
+streams.  When you open a stream, you get the same kind of stream
+regardless of whether you ask for binary.  This stream can handle any
+file content, and has none of the restrictions that text streams
+sometimes have.
 
 @node File Positioning
 @section File Positioning
@@ -2085,13 +2451,21 @@ descriptors, @pxref{Low-Level Input/Output}.
 @cindex positioning a stream
 @cindex seeking on a stream
 
-You can use the functions in this section to inquire about or modify the
-file position indicator associated with a stream; @pxref{Input/Output
-Concepts}.  In the GNU system, the file position indicator is the number of
-bytes from the beginning of the file.
-
-The functions and macros listed in this section are declared in the
-header file @file{stdio.h}.
+The @dfn{file position} of a stream describes where in the file the
+stream is currently reading or writing.  I/O on the stream advances the
+file position through the file.  In the GNU system, the file position is
+represented as an integer, which counts the number of bytes from the
+beginning of the file.  @xref{File Position}.
+
+During I/O to an ordinary disk file, you can change the file position
+whenever you wish, so as to read or write any portion of the file.  Some
+other kinds of files may also permit this.  Files which support changing
+the file position are sometimes referred to as @dfn{random-access}
+files.
+
+You can use the functions in this section to examine or modify the file
+position indicator associated with a stream.  The symbols listed below
+are declared in the header file @file{stdio.h}.
 @pindex stdio.h
 
 @comment stdio.h
@@ -2117,13 +2491,17 @@ file, the current file position, or the end of the file, respectively.
 
 This function returns a value of zero if the operation was successful,
 and a nonzero value to indicate failure.  A successful call also clears
-any end-of-file condition on the @var{stream} and discards any characters
+the end-of-file indicator of @var{stream} and discards any characters
 that were ``pushed back'' by the use of @code{ungetc}.
+
+@code{fseek} either flushes any buffered output before setting the file
+position or else remembers it so it will be written later in its proper
+place in the file.
 @end deftypefun
 
-@strong{Portability Note:}  In systems that are not POSIX-compliant,
-@code{ftell} and @code{fseek} only work reliably on binary streams.
-@xref{Text and Binary Streams}.  
+@strong{Portability Note:} In non-POSIX systems, @code{ftell} and
+@code{fseek} might work reliably only on binary streams.  @xref{Text and
+Binary Streams}.
 
 The following symbolic constants are defined for use as the @var{whence}
 argument to @code{fseek}.  They are also used with the @code{lseek}
@@ -2133,27 +2511,25 @@ for file locks (@pxref{Control Operations on Files}).
 @comment stdio.h
 @comment ANSI
 @deftypevr Macro int SEEK_SET
-This macro expands into an integer constant expression that can be used
-as the @var{whence} argument to the @code{fseek} function, to
-specify that the offset provided is relative to the beginning of the
-file.
+This is an integer constant which, when used as the @var{whence}
+argument to the @code{fseek} function, specifies that the offset
+provided is relative to the beginning of the file.
 @end deftypevr
 
 @comment stdio.h
 @comment ANSI
 @deftypevr Macro int SEEK_CUR
-This macro expands into an integer constant expression that can be used
-as the @var{whence} argument to the @code{fseek} function, to
-specify that the offset provided is relative to the currrent file
-position.
+This is an integer constant which, when used as the @var{whence}
+argument to the @code{fseek} function, specifies that the offset
+provided is relative to the currrent file position.
 @end deftypevr
 
 @comment stdio.h
 @comment ANSI
 @deftypevr Macro int SEEK_END
-This macro expands into an integer constant expression that can be used
-as the @var{whence} argument to the @code{fseek} function, to
-specify that the offset provided is relative to the end of the file.
+This is an integer constant which, when used as the @var{whence}
+argument to the @code{fseek} function, specifies that the offset
+provided is relative to the end of the file.
 @end deftypevr
 
 @comment stdio.h
@@ -2166,93 +2542,55 @@ begining of the file.  It is equivalent to calling @code{fseek} on the
 value is discarded and the error indicator for the stream is reset.
 @end deftypefun
 
+@node Portable Positioning
+@section Portable File-Position Functions
 
-@node Text and Binary Streams
-@section Text and Binary Streams
+On the GNU system, the file position is truly a character count.  You
+can specify any character count value as an argument to @code{fseek} and
+get reliable results for any random access file.  However, some ANSI C
+systems do not represent file positions in this way.
 
-The GNU system and other POSIX-compatible operating systems organize all
-files as uniform sequences of characters.  However, some other systems
-make a distinction between files containing text and files containing
-binary data, and the input and output facilities provided by ANSI C are
-general enough to support this distinction.  This section contains
-information you need to know if you are concerned about making your
-programs portable to non-POSIX systems.
-
-@cindex text stream
-@cindex binary stream
-In ANSI C, a file can be opened as either a @dfn{text stream} or as a
-@dfn{binary stream}.  You indicate that you want a binary stream by
-specifying the @samp{b} modifier in the @var{opentype} argument to
-@code{fopen}; @pxref{Opening and Closing Streams}.  Without this option,
-@code{fopen} opens the file as a text stream.
+On some systems where text streams truly differ from binary streams, it
+is impossible to represent the file position of a text stream as a count
+of characters from the beginning of the file.  For example, the file
+position on some systems must encode both a record offset within the
+file, and a character offset within the record.
 
-There are three areas where the two kinds of streams differ:
+As a consequence, if you want your programs to be portable to these
+systems, you must observe certain rules:
 
 @itemize @bullet
 @item
-A text stream is divided into @dfn{lines} which are terminated by
-newline (@code{'\n'}) characters, while a binary stream is simply a long
-series of characters.  A text stream must be able to handle lines up to
-254 characters long (including the terminating newline character).
-@cindex lines (in a text file)
-
-@item
-A text stream can (portably) consist only of printing
-characters, horizontal tab characters, and newlines; while any character
-object can be written to or read from a binary stream.
-
-@item
-Space characters that are written immediately preceeding a newline
-character in a text stream may disappear when the file is read in again.
-
-@item
-More generally, there need not be a one-to-one mapping between
-characters that are read from or written to a text stream, and the
-characters in the actual file.
-@end itemize
-
-A consequence of this last point is that file positions for text streams
-may not be representable as a character offset from the beginning of the
-file.  On some systems, for example, the file position must encode both
-a record offset within the file, and a character offset within the
-record.
-
-The specific restrictions that result from this are:
-
-@itemize @bullet
-@item
-The @code{long int} value that @code{fseek} and @code{ftell} use to
-represent the file position indicator may not be able to encode a
-sufficient range of values to handle large files.
-
-@item
-The only guaranteed property of the value returned from @code{ftell} on
-a text stream is that it can be used as the @var{offset} argument in a
-call to @code{fseek} to represent the same file position.
+The value returned from @code{ftell} on a text stream has no predictable
+relationship to the number of characters you have read so far.  The only
+thing you can rely on is that you can use it subsequently as the
+@var{offset} argument to @code{fseek} to move back to the same file
+position.
 
 @item 
 In a call to @code{fseek} on a text stream, either the @var{offset} must
 either be zero; or @var{whence} must be @code{SEEK_SET} and the
 @var{offset} must be the result of an earlier call to @code{ftell} on
-the same @var{stream}.
-
-@item
-A @var{whence} value of @code{SEEK_END} in a call to @code{fseek} may
-not work on binary streams.
+the same stream.
 
 @item
 The value of the file position indicator of a text stream is undefined
 while there are characters that have been pushed back with @code{ungetc}
-that haven't been read or discarded.  @xref{Character Input}.
+that haven't been read or discarded.  @xref{Unreading}.
 @end itemize
 
-To get around the problems with @code{ftell} and @code{fseek}, you can
-use the functions @code{fgetpos} and @code{fsetpos} instead.  These
-functions represent the file position as a @code{fpos_t} object, with
-an implementation-dependent internal representation.
+But even if you observe these rules, you may still have trouble for long
+files, because @code{ftell} and @code{fseek} use a @code{long int} value
+to represent the file position.  This type may not have room to encode
+all the file positions in a large file.
 
-Prototypes for these functions are declared in the header file
-@file{stdio.h}.
+So if you do want to support systems with peculiar encodings for the
+file positions, it is better to use the functions @code{fgetpos} and
+@code{fsetpos} instead.  These functions represent the file position
+using the data type @code{fpos_t}, whose internal representation varies
+from system to system.
+
+These symbols are declared in the header file @file{stdio.h}.
 @pindex stdio.h
 
 @comment stdio.h
@@ -2304,22 +2642,22 @@ streams, you need to understand how buffering works when you design the
 user interface to your program.  Otherwise, you might find that output
 (such as progress or prompt messages) doesn't appear when you intended
 it to, or that input typed by the user is made available by lines
-instead of by single characters, or see other unexpected behavior.  
+instead of by single characters, or other unexpected behavior.  
 
 This section deals only with controlling when characters are transmitted
 between the stream and the file or device, and @emph{not} with how
 things like echoing, flow control, and the like are handled on specific
 classes of devices.  For information on common control operations on
-terminal devices, @pxref{Low-Level Terminal Interface}.
+terminal devices, see @ref{Low-Level Terminal Interface}.
 
-You can also bypass the stream buffering facilities altogether by using
-the low-level input and output functions that operate on file descriptors
+You can bypass the stream buffering facilities altogether by using the
+low-level input and output functions that operate on file descriptors
 instead.  @xref{Low-Level Input/Output}.
 
 @menu
-* Buffering Concepts::         Terminology is defined here.
-* Flushing Buffers::           How to ensure that output buffers are flushed.
-* Controlling Buffering::      How to specify what kind of buffering to use.
+* Buffering Concepts::          Terminology is defined here.
+* Flushing Buffers::            How to ensure that output buffers are flushed.
+* Controlling Buffering::       How to specify what kind of buffering to use.
 @end menu
 
 @node Buffering Concepts
@@ -2376,34 +2714,31 @@ in the GNU system messes with input modes on a terminal device, does it?
 @subsection Flushing Buffers
 
 @cindex flushing a stream
-@dfn{Flushing} output on a buffered stream causes any accumulated
-characters to be transmitted to the file.  You can flush
-buffers explicitly with the @code{fflush} function, but there are many
-circumstances when buffered output is flushed automatically:
+@dfn{Flushing} output on a buffered stream means transmitting all
+accumulated characters to the file.  There are many circumstances when
+buffered output on a stream is flushed automatically:
 
 @itemize @bullet
 @item
-Output buffers are flushed when they are full.
+When you try to do output and the output buffer is full.
 
 @item
-On a line buffered stream, writing a newline causes output on
-that stream to be flushed.  
+When the stream is closed.
 
-@item
-Performing a read operation on an unbuffered stream (or on a line
-buffered stream when it needs to do actual input) causes accumulated
-output on all open streams to be flushed.
+@item 
+When the program terminates by calling @code{exit}.
+@c ??? xref here.
 
 @item
-Closing a stream causes accumulated output on that stream to be flushed
-first.
+When a newline is written, if the stream is line-buffered.
 
 @item
-On normal program exit, output is flushed as part of closing all open
-streams.
+Whenever an input operation on @emph{any} stream actually reads data
+from the file.
 @end itemize
 
-The prototype for @code{fflush} is in the header file @file{stdio.h}.
+If you want to flush the buffered output at another time, call
+@code{fflush}, which is declared in the header file @file{stdio.h}.
 @pindex stdio.h
 
 @comment stdio.h
@@ -2425,20 +2760,14 @@ Fortunately, this ``feature'' seems to be becoming less common.  You do
 not need to worry about this in the GNU system.
 
 
-@node Controlling Buffering
-@subsection Controlling Buffering
+@node Specifying Which Kind of Buffering
+@subsection Specifying Which Kind of Buffering
 
 After opening a stream (but before any other operations have been
 performed on it), you can explicitly specify what kind of buffering you
 want it to have using the @code{setvbuf} function.
 @cindex buffering, controlling
 
-Implementations are not required to actually support changes in the
-buffering mode, and requests to do so may simply fail.
-
-@strong{Incomplete:} Does the GNU system support all the buffering modes
-on all kinds of files?  If not, what are the restrictions?
-
 The facilities listed in this section are declared in the header
 file @file{stdio.h}.
 @pindex stdio.h
@@ -2451,20 +2780,22 @@ have the buffering mode @var{mode}, which can be either @code{_IOFBF}
 (for full buffering), @code{_IOLBF} (for line buffering), or
 @code{_IONBF} (for unbuffered input/output).
 
-If you want a buffer for the stream to be allocated automatically, you
-can specify a null pointer as the @var{buf} argument.  Otherwise,
-@var{buf} should be a character array that can hold at least @var{size}
-characters.
+If you specify a null pointer as the @var{buf} argument, then @code{setvbuf}
+allocates a buffer itself using @code{malloc}.  This buffer will be freed
+when you close the stream.
 
-The extent of the array you pass as the @var{buf} argument should be at
-least as great as the open stream; you should usually either allocate it
-statically, or @code{malloc} (@pxref{Unconstrained Allocation}) the
-buffer.  Using an automatic array is not a good idea unless you close
-the file before exiting the block that declares the array.
+Otherwise, @var{buf} should be a character array that can hold at least
+@var{size} characters.  You should not free the space for this array as
+long as the stream remains open and this array remains its buffer.  You
+should usually either allocate it statically, or @code{malloc}
+(@pxref{Unconstrained Allocation}) the buffer.  Using an automatic array
+is not a good idea unless you close the file before exiting the block
+that declares the array.
 
-The contents of the array are indeterminate as long as the stream is
-open.  You shouldn't try to access the values in the array while you are
-using it for buffering.
+While the array remains a stream buffer, the stream I/O functions will
+use the buffer for their internal purposes.  You shouldn't try to access
+the values in the array directly while the stream is using it for
+buffering.
 
 The @code{setvbuf} function returns zero on success, or a nonzero value
 if the value of @var{mode} is not valid or if the request could not
@@ -2498,14 +2829,20 @@ specify that the stream should be unbuffered.
 @comment stdio.h
 @comment ANSI
 @deftypevr Macro int BUFSIZ
-The value of this macro is an integer constant expression that is an
-appropriate (but implementation-defined) value for the @var{size}
-argument to @code{setvbuf}.  This value is guaranteed to be at least
-@code{256}.
+The value of this macro is an integer constant expression that is good
+to use for the @var{size} argument to @code{setvbuf}.  This value is
+guaranteed to be at least @code{256}.
+
+The value of @code{BUFSIZ} is chosen on each system so as to make stream
+I/O efficient.  So it is a good idea to use @code{BUFSIZ} as the size 
+for the buffer when you call @code{setvbuf}.
 
 Sometimes people also use @code{BUFSIZ} as the allocation size of
 buffers used for related purposes, such as strings used to receive a
-line of input with @code{fgets} (@pxref{Character Input}).
+line of input with @code{fgets} (@pxref{Character Input}).  There is no
+particular reason to use @code{BUFSIZ} for this instead of any other
+integer, except that it might lead to doing I/O in chunks of an
+efficient size.
 @end deftypevr
 
 @comment stdio.h
@@ -2514,19 +2851,19 @@ line of input with @code{fgets} (@pxref{Character Input}).
 If @var{buf} is a null pointer, the effect of this function is
 equivalent to calling @code{setvbuf} with a @var{mode} argument of
 @code{_IONBF}.  Otherwise, it is equivalent to calling @code{setvbuf}
-with a @var{mode} of @code{_IOFBF} and a @var{size} argument of
-@code{BUFSIZ}.
+with @var{buf}, and a @var{mode} of @code{_IOFBF} and a @var{size}
+argument of @code{BUFSIZ}.
 
 The @code{setbuf} function is provided for compatibility with old code;
-using @code{setvbuf} instead is a more modern style.
+use @code{setvbuf} in all new programs.
 @end deftypefun
 
 @comment stdio.h
 @comment BSD
 @deftypefun void setbuffer (FILE *@var{stream}, char *@var{buf}, size_t @var{size})
 If @var{buf} is a null pointer, this function makes @var{stream} unbuffered.
-Otherwise, it makes @var{stream} fully buffered using that array as the
-buffer.  The @var{size} argument specifies the length of the array.
+Otherwise, it makes @var{stream} fully buffered using @var{buf} as the
+buffer.  The @var{size} argument specifies the length of @var{buf}.
 
 This function is provided for compatibility with old BSD code.  Use
 @code{setvbuf} instead.
@@ -2535,8 +2872,8 @@ This function is provided for compatibility with old BSD code.  Use
 @comment stdio.h
 @comment BSD
 @deftypefun void setlinebuf (FILE *@var{stream})
-This function makes @var{stream} be line-buffered, using an
-automatically-allocated buffer.
+This function makes @var{stream} be line-buffered, and allocates the
+buffer for you.
 
 This function is provided for compatibility with old BSD code.  Use
 @code{setvbuf} instead.
@@ -2547,9 +2884,9 @@ This function is provided for compatibility with old BSD code.  Use
 @section Temporary Files
 
 If you need to use a temporary file in your program, you can use the
-@code{tmpfile} function to do this.  Or, you can use the @code{tmpnam}
-function to get the name of a temporary file and then open it in the
-usual way with @code{fopen}.
+@code{tmpfile} function to open it.  Or you can use the @code{tmpnam}
+function make a name for a temporary file and then open it in the usual
+way with @code{fopen}.
 
 These facilities are declared in the header file @file{stdio.h}.
 @pindex stdio.h
@@ -2558,12 +2895,12 @@ These facilities are declared in the header file @file{stdio.h}.
 @comment ANSI
 @deftypefun {FILE *} tmpfile (void)
 This function creates a temporary binary file for update mode, as if by
-calling @code{fopen} with mode @code{"wb+"}.  The file is removed 
-automatically when it is closed or when the program terminates normally
-(but not if the program terminates abnormally).
+calling @code{fopen} with mode @code{"wb+"}.  The file is deleted
+automatically when it is closed or when the program terminates.  (On
+some other ANSI C systems the file may fail to be deleted if the program
+terminates abnormally).
 @end deftypefun
 
-
 @comment stdio.h
 @comment ANSI
 @deftypefun {char *} tmpnam (char *@var{result})
@@ -2573,6 +2910,11 @@ argument is a null pointer, the return value is a pointer to an internal
 static string, which might be modified by subsequent calls.  Otherwise,
 the @var{result} argument should be a pointer to an array of at least
 @code{L_tmpnam} characters, and the result is written into that array.
+
+It is possible for @code{tmpnam} to fail if you call it too many times.
+This is because the fixed length of a temporary file name gives room for
+only a finite number of different names.  If @code{tmpnam} fails, it
+returns a null pointer.
 @end deftypefun
 
 @comment stdio.h
@@ -2586,10 +2928,16 @@ file name generated by the @code{tmpnam} function.
 @comment stdio.h
 @comment ANSI
 @deftypevr Macro int TMP_MAX
-The value of this macro is an integer constant expression that represents
-the minimum number of unique file names that can be generated by
-the @code{tmpnam} function.  The value of this macro is guaranteed to
-be at least @code{25}.
+The macro @code{TMP_MAX} is a lower bound for how many temporary names
+you can create with @code{tmpnam}.  You can rely on being able to call
+@code{tmpnam} at least this many times before it might fail saying you
+have made too many temporary file names.
+
+With the GNU library, you can create a very large number of temporary
+file names---if you actually create the files, you will probably run out
+of disk space before you run out of names.  Some other systems have a
+fixed, small limit on the number of temporary files.  The limit is never
+less than @code{25}.
 @end deftypevr
 
 @comment stdio.h
@@ -2616,17 +2964,18 @@ The value of the @code{P_tmpdir} macro.
 @item
 The directory @file{/tmp}.
 @end itemize
+
+This function is defined for SVID compatibility.
+@c ??? Add xref to the node for feature test macros.
 @end deftypefun
 @cindex TMPDIR environment variable
 
 @comment stdio.h
 @comment SVID
-@deftypevr Macro {char *} P_tmpdir
-The value of this macro is the file name prefix identifying
-the default directory for temporary files.  It is used by @code{tempnam}.
+@deftypevr {SVID Macro} {char *} P_tmpdir
+This macro is the name of the default directory for temporary files.
 @end deftypevr
 
-
 @node Other Kinds of Streams
 @section Other Kinds of Streams
 
@@ -2639,8 +2988,8 @@ These kinds of streams are used internally to implement the
 stream explicitly, using the functions described in @ref{String Streams}.
 
 More generally, you can define streams that do input/output to arbitrary
-objects using a function protocol.  This protocol is discussed in 
-@ref{Generalized Streams}.
+objects using functions supplied by your program.  This protocol is
+discussed in @ref{Generalized Streams}.
 
 @strong{Portability Note:} The facilities described in this section are
 specific to GNU.  Other systems or C implementations might or might not
@@ -2653,25 +3002,25 @@ provide equivalent functionality.
 
 @node String Streams
 @subsection String Streams
-@cindex stream, for i/o to a string
+@cindex stream, for I/O to a string
 @cindex string stream
 The @code{fmemopen} and @code{open_memstream} functions allow you to do
-i/o to a string or memory buffer.  These facilities are declared in
+I/O to a string or memory buffer.  These facilities are declared in
 @file{stdio.h}.
 @pindex stdio.h
 
 @comment stdio.h
 @comment GNU
-@deftypefun {FILE *} fmemopen (void *@var{a}, size_t @var{size}, const char *@var{opentype})
+@deftypefun {FILE *} fmemopen (void *@var{buf}, size_t @var{size}, const char *@var{opentype})
 This function opens a stream that allows the access specified by the
 @var{opentype} argument, that reads from or writes to the buffer specified
-by the argument @var{a}.  This array must be at least @var{size} bytes long.
+by the argument @var{buf}.  This array must be at least @var{size} bytes long.
 
 @ignore
 @strong{Incomplete:}  This seems useless since the stream does not
 support file positioning.
 
-If you specify a null pointer as the @var{a} argument, @code{fmemopen}
+If you specify a null pointer as the @var{buf} argument, @code{fmemopen}
 dynamically allocates (as with @code{malloc}; @pxref{Unconstrained
 Allocation}) an array @var{size} bytes long.  This is really only useful
 if you are going to write things to the buffer and then read them back
@@ -2679,10 +3028,11 @@ in again, because you have no way of actually getting a pointer to the
 buffer.  The buffer is freed when the stream is open.
 @end ignore
 
-If the @var{opentype} specifies append mode, then the initial file
-position is set to the first null character in the buffer.  Otherwise
-the initial file position is at the beginning of the buffer.  The newly
-created stream does not support file positioning operations.
+The argument @var{opentype} is the same as in @code{fopen}
+(@xref{Opening and Closing Streams}).  If the @var{opentype} specifies
+append mode, then the initial file position is set to the first null
+character in the buffer.  Otherwise the initial file position is at the
+beginning of the buffer.
 
 When a stream open for writing is flushed or closed, a null character
 (zero byte) is written at the end of the buffer if it fits.  You
@@ -2691,7 +3041,7 @@ Attempts to write more than @var{size} bytes to the buffer result
 in an error.
 
 For a stream open for reading, null characters (zero bytes) in the
-buffer are @emph{not} significant.  Read operations return end-of-file
+buffer do not count as end-of-file.  Read operations return end-of-file
 only when the file position advances past @var{size} bytes.  So, if you
 want to read characters from a null-terminated string, you should supply
 the length of the string as the @var{size} argument.
@@ -2705,7 +3055,8 @@ reading from a string:
 
 static char buffer[] = "foobar";
 
-void main (void)
+void
+main (void)
 @{
   int ch;
   FILE *stream;
@@ -2737,10 +3088,10 @@ Allocation}) and grown as necessary.
 
 When the stream is closed with @code{fclose} or flushed with
 @code{fflush}, the locations @var{ptr} and @var{sizeloc} are updated to
-contain the pointer to the buffer and its size.  If you do an
-@code{fflush} and then further output operations on the stream, you can
-no longer depend on these pointers being accurate.  You must flush or
-close the stream again to update them.
+contain the pointer to the buffer and its size.  The values thus stored
+remain valid only as long as no further output on the stream takes
+place.  If you do more output, you must flush or close the stream again
+to store new values before you use them again.
 
 A null character is written at the end of the buffer.  This null character
 is @emph{not} included in the size value stored at @var{sizeloc}.
@@ -2751,7 +3102,8 @@ Here is an example of using @code{open_memstream}:
 @example
 #include <stdio.h>
 
-void main (void)
+void
+main (void)
 @{
   char *bp;
   size_t size;
@@ -2760,35 +3112,55 @@ void main (void)
   stream = open_memstream (&bp, &size);
   fprintf (stream, "hello");
   fflush (stream);
-  printf ("buf = %s, size = %d\n", bp, size);
+  printf ("buf = `%s', size = %d\n", bp, size);
   fprintf (stream, ", world");
   fclose (stream);
-  printf ("buf = %s, size = %d\n", bp, size);
+  printf ("buf = `%s', size = %d\n", bp, size);
 @}
 @end example
 
 This program produces the following output:
 
 @example
-buf = hello, size = 5
-buf = hello, world, size = 12
+buf = `hello', size = 5
+buf = `hello, world', size = 12
 @end example
 
-@node Generalized Streams
-@subsection Generalized Streams
+@node Programming Your Own Streams
+@subsection Programming Your Own Streams
+@cindex custom streams
+@cindex programming your own streams
 
 This section describes how you can make a stream that gets input from an
-arbitrary data source or writes output to an arbitrary data sink.  We
-refer to this source or sink as a @dfn{cookie}.  The cookie is specified
-as a pointer value (a @code{void *}), but the cookie can point to any
-kind of object that you want to use to keep track of state information
-for the stream.
-@cindex cookie, for generalized streams
-@cindex generalized streams
-
-The protocol for transferring data to or from the cookie is defined by
-a set of functions.  You provide appropriate definitions for these 
-functions, and store them in an @code{__io_functions} data structure.
+arbitrary data source or writes output to an arbitrary data sink
+programmed by you.  We call these @dfn{custom streams}.
+
+@menu
+* Streams and Cookies::
+* Hook Functions::
+@end menu
+
+@node Streams and Cookies
+@cindex cookie, for custom streams
+
+Inside every custom stream is a special object called the @dfn{cookie}.
+This is an object supplied by you which records where to fetch or store
+the data read or written.  It is up to you to define a data type to use
+for the cookie.  The stream functions in the library they never refer
+directly to its contents, and they don't even know what the type is;
+they record its address with type @code{void *}.
+
+To implement custom stream, you must specify @emph{how} to fetch or
+store the data in the specified place.  You do this by defining
+@dfn{hook functions} to read, write, change ``file position'', and close
+the stream.  All four of these functions will be passed the stream's
+cookie so they can tell where to fetch or store the data.  The library
+functions don't know what's inside the cookie, but your functions will
+know.
+
+When you create a custom stream, you must specify the cookie pointer,
+and also the four hook functions stored in a structure of type 
+@code{__io_functions}.
 
 These facilities are declared in @file{stdio.h}.
 @pindex stdio.h
@@ -2803,60 +3175,70 @@ the following members:
 @table @code
 @item __io_read *__read
 This is the function that reads data from the cookie.  If the value is a
-null pointer, then read operations on ths stream always return @code{EOF}.
+null pointer instead of a function, then read operations on ths stream
+always return @code{EOF}.
 
 @item __io_write *__write
 This is the function that writes data to the cookie.  If the value is a
-null pointer, then data written to the stream is discarded.
+null pointer instead of a function, then data written to the stream is
+discarded.
 
 @item __io_seek *__seek
-This is the function that performs the equivalent of file positioning
-on the cookie.  If the value is a null pointer, calls to @code{fseek}
-on this stream return an @code{ESPIPE} error.
+This is the function that performs the equivalent of file positioning on
+the cookie.  If the value is a null pointer instead of a function, calls
+to @code{fseek} on this stream return an @code{ESPIPE} error.
 
 @item __io_close *__close
-This function performs any appropriate cleanup on the cookie when closing
-the stream.  If the value is a null pointer, nothing special is done
-to close the cookie when the stream is closed.
+This function performs any appropriate cleanup on the cookie when
+closing the stream.  If the value is a null pointer instead of a
+function, nothing special is done to close the cookie when the stream is
+closed.
 @end table
 @end deftp
 
-Here are more details on how you should define the individual functions
-stored in this structure.
-
 @comment stdio.h
 @comment GNU
-@deftp {Data Type} __io_read
+@deftypefun {FILE *} fopencookie (void *@var{cookie}, const char *@var{opentype}, __io_functions @var{io_functions})
+This function actually creates the stream for communicating with the
+@var{cookie} using the functions in the @var{io_functions} argument.
+The @var{opentype} argument is interpreted as for @code{fopen};
+see @ref{Opening and Closing Streams}.  (But note that the ``truncate on
+open'' option is ignored.)
+
+@strong{Incomplete:} What is the default buffering mode for the newly
+created stream?
+
+The @code{fopencookie} function returns the newly created stream, or a null
+pointer in case of an error.
+@end deftypefun
+
+@node Hook Functions
+@subsection Custom Stream Hook Functions
+@cindex hook functions (of custom streams)
+
+Here are more details on how you should define the four hook functions
+that a custom stream needs.
+
 You should define the function to read data from the cookie as:
 
 @example
 int @var{function} (void *@var{cookie}, void *@var{buffer}, size_t @var{size})
 @end example
 
-This is very similar to the @code{read} function; @pxref{Input and
+This is very similar to the @code{read} function; see @ref{Input and
 Output Primitives}.  Your function should transfer up to @var{size}
 bytes into the @var{buffer}, and return the number of bytes read.
 You can return a value of @code{-1} to indicate an error.
-@end deftp
-
-@comment stdio.h
-@comment GNU
-@deftp {Data Type} __io_write
 You should define the function to write data to the cookie as:
 
 @example
 int @var{function} (void *@var{cookie}, const void *@var{buffer}, size_t @var{size})
 @end example
 
-This is very similar to the @code{write} function; @pxref{Input and
+This is very similar to the @code{write} function; see @ref{Input and
 Output Primitives}.  Your function should transfer up to @var{size}
 bytes from the buffer, and return the number of bytes written.  You can
 return a value of @code{-1} to indicate an error.
-@end deftp
-
-@comment stdio.h
-@comment GNU
-@deftp {Data Type} __io_seek
 You should define the function to perform seek operations on the cookie as:
 
 @example
@@ -2864,7 +3246,7 @@ int @var{function} (void *@var{cookie}, fpos_t *@var{position}, int @var{whence}
 @end example
 
 For this function, the @code{position} and @code{whence} arguments are
-interpreted as for @code{fgetpos}; @pxref{Text and Binary Streams}.
+interpreted as for @code{fgetpos}; see @ref{Text and Binary Streams}.
 Remember that in the GNU system, @code{fpos_t} is equivalent to
 @code{off_t} or @code{long int}, and simply represents the number of
 bytes from the beginning of the file.
@@ -2873,11 +3255,7 @@ After doing the seek operation, your function should store the resulting
 file position relative to the beginning of the file in @var{position}.
 Your function should return a value of @code{0} on success and @code{-1}
 to indicate an error.
-@end deftp
 
-@comment stdio.h
-@comment GNU
-@deftp {Data Type} __io_close
 You should define the function to do cleanup operations on the cookie
 appropriate for closing the stream as:
 
@@ -2887,33 +3265,31 @@ int @var{function} (void *@var{cookie})
 
 Your function should return @code{-1} to indicate an error, and @code{0}
 otherwise.
-@end deftp
 
 @comment stdio.h
 @comment GNU
-@deftypevar __io_functions __default_io_functions
-This is the default set of functions used internally for streams associated
-with file descriptors.  Their cookie argument is treated as an @code{int *},
-pointing to a location containing the file descriptor.
-
-@strong{Incomplete:}  Why should we publicize this?
-@end deftypevar
+@deftp {Data Type} __io_read
+This is the data type that the read function for a custom stream should have.
+If you declare the function as shown above, this is the type it will have.
+@end deftp
 
 @comment stdio.h
 @comment GNU
-@deftypefun {FILE *} fopencookie (void *@var{cookie}, const char *@var{opentype}, __io_functions @var{io_functions})
-This function actually creates the stream for communicating with the
-@var{cookie} using the functions in the @var{io_functions} argument.
-The @var{opentype} argument is interpreted as for @code{fopen};
-@pxref{Opening and Closing Streams}.  (But note that the ``truncate on
-open'' option is ignored.)
+@deftp {Data Type} __io_write
+The data type of the write function for a custom stream.
+@end deftp
 
-@strong{Incomplete:} What is the default buffering mode for the newly
-created stream?
+@comment stdio.h
+@comment GNU
+@deftp {Data Type} __io_seek
+The data type of the seek function for a custom stream.
+@end deftp
 
-The @code{fopencookie} function returns the newly created stream, or a null
-pointer in case of an error.
-@end deftypefun
+@comment stdio.h
+@comment GNU
+@deftp {Data Type} __io_close
+The data type of the close function for a custom stream.
+@end deftp
 
 @strong{Incomplete:}  Roland says: