about summary refs log tree commit diff
path: root/lib
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2018-10-07 02:25:17 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2018-10-07 02:25:17 +0000
commitb3bcf33e9f1a9487c0bdbcc0507cc5fd22369af8 (patch)
treee8bda3cd5a822a45b4e3e93b0c7a9efcbfaaebb2 /lib
parent4c0ea17a85f6eb059efe418b0a160f4a22326c7c (diff)
downloadnetpbm-mirror-b3bcf33e9f1a9487c0bdbcc0507cc5fd22369af8.tar.gz
netpbm-mirror-b3bcf33e9f1a9487c0bdbcc0507cc5fd22369af8.tar.xz
netpbm-mirror-b3bcf33e9f1a9487c0bdbcc0507cc5fd22369af8.zip
add pm_getline
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@3391 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'lib')
-rw-r--r--lib/pm.h7
-rw-r--r--lib/pmfileio.c67
2 files changed, 74 insertions, 0 deletions
diff --git a/lib/pm.h b/lib/pm.h
index 4f56dc5a..3fc92fb4 100644
--- a/lib/pm.h
+++ b/lib/pm.h
@@ -373,6 +373,13 @@ char*
 pm_read_unknown_size(FILE * const ifP,
                      long * const buf);
 
+void
+pm_getline(FILE *   const ifP,
+           char **  const bufferP,
+           size_t * const bufferSzP,
+           int *    const eofP,
+           size_t * const lineLenP);
+
 short
 pm_bs_short(short const s);
 
diff --git a/lib/pmfileio.c b/lib/pmfileio.c
index 738ba336..33f89110 100644
--- a/lib/pmfileio.c
+++ b/lib/pmfileio.c
@@ -839,6 +839,73 @@ pm_read_unknown_size(FILE * const file,
 
 
 
+void
+pm_getline(FILE *   const ifP,
+           char **  const bufferP,
+           size_t * const bufferSzP,
+           int *    const eofP,
+           size_t * const lineLenP) {
+/*----------------------------------------------------------------------------
+   This is like POSIX 'getline'.
+
+   But we don't include the newline in the returned line.
+-----------------------------------------------------------------------------*/
+    char * buffer;
+    size_t bufferSz;
+    bool gotLine;
+    bool eof;
+    size_t nReadSoFar;
+
+    buffer   = *bufferP;    /* initial value */
+    bufferSz = *bufferSzP;  /* initial value */
+
+    for (nReadSoFar = 0, gotLine = false, eof = false;
+         !gotLine && !eof; ) {
+
+        int rc;
+
+        rc = fgetc(ifP);
+
+        if (rc == EOF) {
+            if (ferror(ifP))
+                pm_error("Error reading input file.  fgets() failed with "
+                         "errno %d (%s)", errno, strerror(errno));
+
+            if (nReadSoFar == 0) {
+                /* Didn't get anything before EOF, so return EOF */
+                eof = true;
+            } else {
+                /* End of file ends the line */
+                gotLine = true;
+            }
+        } else {
+            char const c = (char)rc;
+
+            if (c == '\n') {
+                /* Newline ends the line, and is not part of it */
+                gotLine = true;
+            } else {
+                if (nReadSoFar + 2 > bufferSz) {
+                    /* + 2 = 1 for 'c', one for terminating NUL */
+                    bufferSz += 128;
+                    REALLOCARRAY(buffer, bufferSz);
+                }
+                buffer[nReadSoFar++] = c;
+            }
+        }
+    }
+
+    if (gotLine)
+        buffer[nReadSoFar] = '\0';
+
+    *eofP      = eof;
+    *bufferP   = buffer;
+    *bufferSzP = bufferSz;
+    *lineLenP  = nReadSoFar;
+}
+
+
+
 union cheat {
     uint32_t l;
     short s;