]> Savannah Git Hosting - gnulib.git/commitdiff
sf-istream: New module.
authorBruno Haible <bruno@clisp.org>
Tue, 24 Sep 2024 10:30:54 +0000 (12:30 +0200)
committerBruno Haible <bruno@clisp.org>
Tue, 24 Sep 2024 10:30:54 +0000 (12:30 +0200)
* lib/sf-istream.h: New file.
* lib/sf-istream.c: New file.
* modules/sf-istream: New file.
* doc/posix-functions/fmemopen.texi: Mention the new module.

ChangeLog
doc/posix-functions/fmemopen.texi
lib/sf-istream.c [new file with mode: 0644]
lib/sf-istream.h [new file with mode: 0644]
modules/sf-istream [new file with mode: 0644]

index c870d9dd1c97d601d54acfd3ecabf74f3efdea3d..2b0ffa4da0b6aba69d1640d05d71bf595896208d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2024-09-24  Bruno Haible  <bruno@clisp.org>
+
+       sf-istream: New module.
+       * lib/sf-istream.h: New file.
+       * lib/sf-istream.c: New file.
+       * modules/sf-istream: New file.
+       * doc/posix-functions/fmemopen.texi: Mention the new module.
+
 2024-09-23  Bruno Haible  <bruno@clisp.org>
 
        getopt-posix: Fix compilation error in C++ mode (regression 2024-09-21).
index da92ba2d72e83df9579eb95be8c404f299579db6..7f66b100ba68a4f162989d9ed6f0120c3bd1a3e5 100644 (file)
@@ -16,3 +16,6 @@ Portability problems not fixed by Gnulib:
 This function is missing on many non-glibc platforms:
 Mac OS X 10.5, FreeBSD 6.0, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, HP-UX 11, Solaris 11.3, Cygwin 1.5.x, mingw, MSVC 14, Android 5.1.
 @end itemize
+
+An alternative to the @code{fmemopen} function is the Gnulib module
+@code{sf-istream}.
diff --git a/lib/sf-istream.c b/lib/sf-istream.c
new file mode 100644 (file)
index 0000000..1bc4fa1
--- /dev/null
@@ -0,0 +1,96 @@
+/* A string or file based input stream.
+   Copyright (C) 2024 Free Software Foundation, Inc.
+
+   This file is free software: you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation, either version 3 of the
+   License, or (at your option) any later version.
+
+   This file is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2024.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include "sf-istream.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+void
+sf_istream_init_from_file (sf_istream_t *stream, FILE *fp)
+{
+  stream->fp = fp;
+  stream->input = NULL;
+  stream->input_end = NULL;
+}
+
+void
+sf_istream_init_from_string (sf_istream_t *stream,
+                             const char *input)
+{
+  stream->fp = NULL;
+  stream->input = input;
+  stream->input_end = input + strlen (input);
+}
+
+void
+sf_istream_init_from_string_desc (sf_istream_t *stream,
+                                  string_desc_t input)
+{
+  stream->fp = NULL;
+  stream->input = string_desc_data (input);
+  stream->input_end = stream->input + string_desc_length (input);
+}
+
+int
+sf_getc (sf_istream_t *stream)
+{
+  int c;
+
+  if (stream->fp != NULL)
+    c = getc (stream->fp);
+  else
+    {
+      if (stream->input == stream->input_end)
+        return EOF;
+      c = (unsigned char) *(stream->input++);
+    }
+
+  return c;
+}
+
+int
+sf_ferror (sf_istream_t *stream)
+{
+  return (stream->fp != NULL && ferror (stream->fp));
+}
+
+void
+sf_ungetc (sf_istream_t *stream, int c)
+{
+  if (c != EOF)
+    {
+      if (stream->fp != NULL)
+        ungetc (c, stream->fp);
+      else
+        {
+          stream->input--;
+          if (!(c == (unsigned char) *stream->input))
+            /* C was incorrect.  */
+            abort ();
+        }
+    }
+}
+
+void
+sf_free (sf_istream_t *stream)
+{
+}
diff --git a/lib/sf-istream.h b/lib/sf-istream.h
new file mode 100644 (file)
index 0000000..e45c561
--- /dev/null
@@ -0,0 +1,77 @@
+/* A string or file based input stream.
+   Copyright (C) 2024 Free Software Foundation, Inc.
+
+   This file is free software: you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation, either version 3 of the
+   License, or (at your option) any later version.
+
+   This file is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2024.  */
+
+#ifndef _SF_ISTREAM_H
+#define _SF_ISTREAM_H
+
+#include <stdio.h>
+
+#include "string-desc.h"
+
+/* An input stream type that can read from a file or from a string.  */
+typedef struct sf_istream sf_istream_t;
+struct sf_istream
+{
+  /* The input file stream, when reading from a file.  */
+  FILE *fp;
+  /* The input area, when reading from a string.  */
+  const char *input;
+  const char *input_end;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Initializes STREAM to read from FP.
+   FP must be a FILE stream open for reading.  */
+extern void sf_istream_init_from_file (sf_istream_t *stream, FILE *fp);
+/* Initializes STREAM to read from a NUL-terminated string INPUT.
+   The contents of INPUT must stay available and unchanged as long as STREAM
+   is in use.  */
+extern void sf_istream_init_from_string (sf_istream_t *stream,
+                                         const char *input);
+/* Initializes STREAM to read from a string INPUT.
+   The contents of INPUT must stay available and unchanged as long as STREAM
+   is in use.  Operations on STREAM will not modify the contents of INPUT.  */
+extern void sf_istream_init_from_string_desc (sf_istream_t *stream,
+                                              string_desc_t input);
+
+/* Reads a single 'char' from STREAM, and returns it as an 'unsigned char'.
+   Returns EOF when the end of stream was already reached.  */
+extern int sf_getc (sf_istream_t *stream);
+
+/* Tests whether STREAM has encountered an error.
+   You may want to call this function after sf_getc (stream) has
+   returned EOF; in other situations it is guaranteed to return 0.  */
+extern int sf_ferror (sf_istream_t *stream);
+
+/* Assuming that C was the last value returned by sf_getc (stream),
+   this call pushes back C onto the stream.
+   Only 1 character of pushback is guaranteed.  */
+extern void sf_ungetc (sf_istream_t *stream, int c);
+
+/* Frees all memory held by STREAM.
+   This call has no effect on the arguments provided to sf_istream_init_*.  */
+extern void sf_free (sf_istream_t *stream);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SF_ISTREAM_H */
diff --git a/modules/sf-istream b/modules/sf-istream
new file mode 100644 (file)
index 0000000..ab1289d
--- /dev/null
@@ -0,0 +1,23 @@
+Description:
+A string or file based input stream.
+
+Files:
+lib/sf-istream.h
+lib/sf-istream.c
+
+Depends-on:
+string-desc
+
+configure.ac:
+
+Makefile.am:
+lib_SOURCES += sf-istream.c
+
+Include:
+"sf-istream.h"
+
+License:
+LGPL
+
+Maintainer:
+all