summaryrefslogtreecommitdiff
path: root/lib/libc/stdio
diff options
context:
space:
mode:
authorcgd <cgd@NetBSD.org>1993-12-22 07:10:58 +0000
committercgd <cgd@NetBSD.org>1993-12-22 07:10:58 +0000
commit6039a60bb3d3ab2b4e361375cedda55faa9fd334 (patch)
treed86d23aa5904aa4dd7fda9d194d77eb5ca6b06f4 /lib/libc/stdio
parent87815db712bf82e90bb3262d3364031c33c06ed8 (diff)
don't squish newline at end of fgetline()... from bostic
Diffstat (limited to 'lib/libc/stdio')
-rw-r--r--lib/libc/stdio/fgetline.339
-rw-r--r--lib/libc/stdio/fgetline.c77
2 files changed, 57 insertions, 59 deletions
diff --git a/lib/libc/stdio/fgetline.3 b/lib/libc/stdio/fgetline.3
index c5a027b0aba..631401e9ebe 100644
--- a/lib/libc/stdio/fgetline.3
+++ b/lib/libc/stdio/fgetline.3
@@ -1,5 +1,5 @@
-.\" Copyright (c) 1990, 1991 The Regents of the University of California.
-.\" All rights reserved.
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
@@ -29,10 +29,10 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" from: @(#)fgetline.3 5.4 (Berkeley) 4/19/91
-.\" $Id: fgetline.3,v 1.3 1993/11/29 22:06:46 jtc Exp $
+.\" from: @(#)fgetline.3 8.1 (Berkeley) 6/9/93
+.\" $Id: fgetline.3,v 1.4 1993/12/22 07:11:09 cgd Exp $
.\"
-.Dd April 19, 1991
+.Dd June 9, 1993
.Dt FGETLINE 3
.Os
.Sh NAME
@@ -48,14 +48,18 @@ The
function
returns a pointer to the next line from the stream referenced by
.Fa stream .
-The newline character at the end of the line is replaced by a
-.Dv NUL .
-.Pp
-If
+This line is
+.Em not
+a C string as it does not end with a terminating
+.Dv NUL
+character.
+The length of the line, including the final newline,
+is stored in the memory location to which
.Fa len
-is non-NULL, the length of the line, not counting the terminating
-.Dv NUL ,
-is stored in the memory location it references.
+points.
+(Note, however, that if the line is the last
+in a file that does not end in a newline,
+the returned text will not contain a newline.)
.Sh RETURN VALUES
Upon successful completion a pointer is returned;
this pointer becomes invalid after the next
@@ -87,11 +91,10 @@ cleared with
.Xr clearerr 3 .
.Pp
The text to which the returned pointer points may be modified,
-provided that no changes are made beyond the terminating
-.Dv NUL .
+provided that no changes are made beyond the returned size.
These changes are lost as soon as the pointer becomes invalid.
.Sh ERRORS
-.Bl -tag -width Er
+.Bl -tag -width [EBADF]
.It Bq Er EBADF
The argument
.Fa stream
@@ -118,8 +121,4 @@ or
.Sh HISTORY
The
.Fn fgetline
-function is
-.Ud .
-.Sh BUGS
-It is not possible to tell whether the final line of an input file
-was terminated with a newline.
+function first appeared in 4.4BSD.
diff --git a/lib/libc/stdio/fgetline.c b/lib/libc/stdio/fgetline.c
index d6948a9093f..b064af7c850 100644
--- a/lib/libc/stdio/fgetline.c
+++ b/lib/libc/stdio/fgetline.c
@@ -1,6 +1,6 @@
/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Chris Torek.
@@ -35,8 +35,8 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fgetline.c 5.2 (Berkeley) 5/4/91";*/
-static char *rcsid = "$Id: fgetline.c,v 1.3 1993/08/26 00:46:41 jtc Exp $";
+/* from: static char sccsid[] = "@(#)fgetline.c 8.1 (Berkeley) 6/4/93"; */
+static char *rcsid = "$Id: fgetline.c,v 1.4 1993/12/22 07:11:10 cgd Exp $";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
@@ -46,8 +46,10 @@ static char *rcsid = "$Id: fgetline.c,v 1.3 1993/08/26 00:46:41 jtc Exp $";
/*
* Expand the line buffer. Return -1 on error.
+#ifdef notdef
* The `new size' does not account for a terminating '\0',
* so we add 1 here.
+#endif
*/
__slbexpand(fp, newsize)
FILE *fp;
@@ -55,7 +57,10 @@ __slbexpand(fp, newsize)
{
void *p;
- if (fp->_lb._size >= ++newsize)
+#ifdef notdef
+ ++newsize;
+#endif
+ if (fp->_lb._size >= newsize)
return (0);
if ((p = realloc(fp->_lb._base, newsize)) == NULL)
return (-1);
@@ -66,9 +71,10 @@ __slbexpand(fp, newsize)
/*
* Get an input line. The returned pointer often (but not always)
- * points into a stdio buffer. Fgetline smashes the newline (if any)
- * in the stdio buffer; callers must not use it on streams that
- * have `magic' setvbuf() games happening.
+ * points into a stdio buffer. Fgetline does not alter the text of
+ * the returned line (which is thus not a C string because it will
+ * not necessarily end with '\0'), but does allow callers to modify
+ * it if they wish. Thus, we set __SMOD in case the caller does.
*/
char *
fgetline(fp, lenp)
@@ -81,8 +87,7 @@ fgetline(fp, lenp)
/* make sure there is input */
if (fp->_r <= 0 && __srefill(fp)) {
- if (lenp != NULL)
- *lenp = 0;
+ *lenp = 0;
return (NULL);
}
@@ -91,31 +96,26 @@ fgetline(fp, lenp)
register char *ret;
/*
- * Found one. Flag buffer as modified to keep
- * fseek from `optimising' a backward seek, since
- * the newline is about to be trashed. (We should
- * be able to get away with doing this only if
- * p is not pointing into an ungetc buffer, since
- * fseek discards ungetc data, but this is the
- * usual case anyway.)
+ * Found one. Flag buffer as modified to keep fseek from
+ * `optimising' a backward seek, in case the user stomps on
+ * the text.
*/
+ p++; /* advance over it */
ret = (char *)fp->_p;
- len = p - fp->_p;
+ *lenp = len = p - fp->_p;
fp->_flags |= __SMOD;
- *p = 0;
- fp->_r -= len + 1;
- fp->_p = p + 1;
- if (lenp != NULL)
- *lenp = len;
+ fp->_r -= len;
+ fp->_p = p;
return (ret);
}
/*
* We have to copy the current buffered data to the line buffer.
+ * As a bonus, though, we can leave off the __SMOD.
*
- * OPTIMISTIC is length that we (optimistically)
- * expect will accomodate the `rest' of the string,
- * on each trip through the loop below.
+ * OPTIMISTIC is length that we (optimistically) expect will
+ * accomodate the `rest' of the string, on each trip through the
+ * loop below.
*/
#define OPTIMISTIC 80
@@ -123,14 +123,13 @@ fgetline(fp, lenp)
register size_t diff;
/*
- * Make sure there is room for more bytes.
- * Copy data from file buffer to line buffer,
- * refill file and look for newline. The
- * loop stops only when we find a newline.
+ * Make sure there is room for more bytes. Copy data from
+ * file buffer to line buffer, refill file and look for
+ * newline. The loop stops only when we find a newline.
*/
if (__slbexpand(fp, len + OPTIMISTIC))
goto error;
- (void) bcopy((void *)fp->_p, (void *)(fp->_lb._base + off),
+ (void)memcpy((void *)(fp->_lb._base + off), (void *)fp->_p,
len - off);
off = len;
if (__srefill(fp))
@@ -139,24 +138,24 @@ fgetline(fp, lenp)
continue;
/* got it: finish up the line (like code above) */
- fp->_flags |= __SMOD; /* soon */
+ p++;
diff = p - fp->_p;
len += diff;
if (__slbexpand(fp, len))
goto error;
- (void) bcopy((void *)fp->_p, (void *)(fp->_lb._base + off),
+ (void)memcpy((void *)(fp->_lb._base + off), (void *)fp->_p,
diff);
- fp->_r -= diff + 1;
- fp->_p = p + 1;
+ fp->_r -= diff;
+ fp->_p = p;
break;
}
- if (lenp != NULL)
- *lenp = len;
+ *lenp = len;
+#ifdef notdef
fp->_lb._base[len] = 0;
+#endif
return ((char *)fp->_lb._base);
error:
- if (lenp != NULL)
- *lenp = 0; /* ??? */
+ *lenp = 0; /* ??? */
return (NULL); /* ??? */
}