From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- web/noweb/src/c/getline.nw | 94 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 web/noweb/src/c/getline.nw (limited to 'web/noweb/src/c/getline.nw') diff --git a/web/noweb/src/c/getline.nw b/web/noweb/src/c/getline.nw new file mode 100644 index 0000000000..9ba4c6160d --- /dev/null +++ b/web/noweb/src/c/getline.nw @@ -0,0 +1,94 @@ +% Copyright 1991 by Norman Ramsey. All rights reserved. +% See file COPYRIGHT for more information. +@ +\section{Utility functions} + +\subsection{Line-oriented input} +[[getline_nw]] is reads in the next line, no matter +how long it is, expanding tabs. +I allocate more and more space for the line, until I've +read a whole line or until I run out of space, whichever comes first. +The buffer grows in size exponentially, so the cost in overhead is roughly the logarithm +of the length of the longest line. +@ +[[getline_nw]] reuses the same internal buffers over and over, so subsequent +calls destroy the results of previous calls. +<<*>>= +static char rcsid[] = "$Id: getline.nw,v 2.24 2008/10/06 01:03:05 nr Exp nr $"; +static char rcsname[] = "$Name: v2_12 $"; +#define START_SIZE 128 /* initial buffer size */ + +#include +#include +#include +#include "columns.h" +#include "errors.h" +#include "getline.h" + +static char *buf1 = NULL, *buf2 = NULL; /* lines without, with tabs expanded */ +static int buf_size = START_SIZE; /* size of both buffers if non-NULL */ + +<> +@ +<
>= +char *getline_expand (FILE *fp); + /* grab a line in buffer, return new buffer or NULL for eof + tabs in line are expanded according to tabsize */ +char *getline_nw (FILE *fp); + /* grab a line in the buffer, return a new buffer or NULL for eof + no expansion of tabs */ +@ N.B. In 2008, [[getline]] became part of a POSIX standard, +so Noweb's version (which is 20 years old) is now [[getline_nw]]. +@ +<>= +void new_buffers(void) { + checkptr(buf1 = (char *) realloc(buf1, buf_size)); + checkptr(buf2 = (char *) realloc(buf2, buf_size)); +} +<>= +char *getline_nw (FILE *fp) { + + <> + + buf1=fgets(buf1, buf_size, fp); + if (buf1==NULL) return buf1; /* end of file */ + while (buf1[strlen(buf1)-1] != '\n') { /* failed to get whole line */ + buf_size *= 2; + new_buffers(); + if (fgets(buf1+strlen(buf1),buf_size-strlen(buf1),fp)==NULL) + return buf1; /* end of file */ + } + (void)rcsid; /* avoid a warning */ + (void)rcsname; /* avoid a warning */ + return buf1; +} +<>= +char *getline_expand (FILE *fp) { + char *s, *t; + int width; + + if (getline_nw(fp)==NULL) return NULL; + < buf_size - 1]], allocate new buffers>> + s = buf1; t = buf2; width=0; + while (*s) + if (*s=='\t' && tabsize > 0) { + do { + *t++ = ' '; width++; + } while (width % tabsize != 0); + s++; + } else { + *t++ = *s++; width++; + } + *t='\0'; + return buf2; +} +<>= +if (buf1==NULL) { + checkptr(buf1 = (char *) malloc (buf_size)); + checkptr(buf2 = (char *) malloc (buf_size)); +} +< buf_size - 1]], allocate new buffers>>= +if (columnwidth(buf1) > buf_size - 1) { + while (columnwidth(buf1) > buf_size - 1) buf_size *= 2; + new_buffers(); +} -- cgit v1.2.3