aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2014-01-09 18:14:09 +0000
committerWerner Koch <[email protected]>2014-01-14 15:23:05 +0000
commit78a06348fb07f2dce861615cc6d19964818f7334 (patch)
tree546cb9423d59115c61a0eaadaf5f5e78b532d3e2
parentpo: Update de.po. (diff)
downloadlibgpg-error-78a06348fb07f2dce861615cc6d19964818f7334.tar.gz
libgpg-error-78a06348fb07f2dce861615cc6d19964818f7334.zip
Improve maintainability by rewriting the mkheader helper.
* src/mkheader.c: New. Based on the mkheader from Libassuan. * src/mkheader.awk: Remove. * src/errnos.in: Add trailing linefeed. * src/gpg-error.h.in: Change meta include directives for use with mkheader.c. * src/Makefile.am (EXTRA_DIST): Replace mkheader.awk by mkheader.c (BUILT_SOURCES): Remove extra-h.in. (CLEANFILES): Remove extra-h.in. Add mkheader.c. (parts_of_gpg_error_h): New. (extra-h.in): Remove rule. (mkheader): Add rule. (gpg-error.h): Change rule to use mkheader. Signed-off-by: Werner Koch <[email protected]>
-rw-r--r--src/Makefile.am54
-rw-r--r--src/errnos.in10
-rw-r--r--src/gpg-error.h.in20
-rw-r--r--src/mkheader.awk218
-rw-r--r--src/mkheader.c363
5 files changed, 404 insertions, 261 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 7143dbd..74d89be 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,5 +1,5 @@
# Makefile.am for libgpg-error.
-# Copyright (C) 2003, 2004 g10 Code GmbH
+# Copyright (C) 2003, 2004, 2014 g10 Code GmbH
#
# This file is part of libgpg-error.
#
@@ -14,8 +14,7 @@
# 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, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+# License along with this program; if not, see <http://www.gnu.org/licenses/>.
# We distribute the generated sources err-sources.h and err-codes.h,
# because they are needed to build the po directory, and they don't
@@ -41,20 +40,20 @@ m4data_DATA = gpg-error.m4
EXTRA_DIST = mkstrtable.awk err-sources.h.in err-codes.h.in \
mkerrnos.awk errnos.in README \
mkerrcodes.awk mkerrcodes1.awk mkerrcodes2.awk mkerrcodes.c \
- mkheader.awk gpg-error.h.in mkw32errmap.c w32-add.h w32ce-add.h \
+ mkheader.c gpg-error.h.in mkw32errmap.c w32-add.h w32ce-add.h \
err-sources.h err-codes.h gpg-error-config.in gpg-error.m4 \
gpg-error.def.in versioninfo.rc.in
BUILT_SOURCES = err-sources.h err-codes.h code-to-errno.h code-from-errno.h \
err-sources-sym.h err-codes-sym.h errnos-sym.h gpg-error.h \
- gpg-error.def extra-h.in mkw32errmap.map.c
+ gpg-error.def mkw32errmap.map.c
tmp_files = _mkerrcodes.h _gpg-error.def.h mkw32errmap.tab.h mkw32errmap.map.c
CLEANFILES = err-sources.h err-codes.h code-to-errno.h code-from-errno.h \
gpg-error.h mkerrcodes mkerrcodes.h gpg-error.def mkw32errmap.tab.h \
mkw32errmap.map.c err-sources-sym.h err-codes-sym.h errnos-sym.h \
- gpg-extra/errno.h extra-h.in $(tmp_files)
+ gpg-extra/errno.h mkheader $(tmp_files)
if HAVE_W32_SYSTEM
arch_sources = w32-gettext.c
@@ -99,6 +98,15 @@ libgpg_error_la_LDFLAGS = -version-info \
@LIBGPG_ERROR_LT_CURRENT@:@LIBGPG_ERROR_LT_REVISION@:@LIBGPG_ERROR_LT_AGE@ \
$(no_undefined) $(export_symbols)
+parts_of_gpg_error_h = \
+ gpg-error.h.in \
+ err-sources.h.in \
+ err-codes.h.in \
+ errnos.in \
+ w32-add.h \
+ w32ce-add.h
+
+
libgpg_error_la_SOURCES = gpg-error.h gettext.h $(arch_sources) \
init.c init.h version.c \
strsource.c strerror.c code-to-errno.c code-from-errno.c
@@ -187,32 +195,14 @@ errnos-sym.h: Makefile mkstrtable.awk errnos.in
-v prefix=GPG_ERR_ -v namespace=errnos_ \
$(srcdir)/errnos.in >$@
-# We depend on versioninfo.rc because that is build by config.status
-# and thus has up-to-date version numbers.
-extra-h.in: Makefile w32-add.h w32ce-add.h versioninfo.rc
- -rm extra-h.in
- echo "/* The version string of this header. */" >>extra-h.in
- echo "#define GPG_ERROR_VERSION \"$(PACKAGE_VERSION)\"" >>extra-h.in
- echo >>extra-h.in
- echo "/* The version number of this header. */" >>extra-h.in
- echo "#define GPG_ERROR_VERSION_NUMBER $(VERSION_NUMBER)" >>extra-h.in
- echo >>extra-h.in
-if HAVE_W32_SYSTEM
- cat $(srcdir)/w32-add.h >>extra-h.in
-endif
-if HAVE_W32CE_SYSTEM
- cat $(srcdir)/w32ce-add.h >>extra-h.in
-endif
- echo EOF >>extra-h.in
-
-gpg-error.h: Makefile mkheader.awk err-sources.h.in err-codes.h.in \
- errnos.in extra-h.in gpg-error.h.in
- $(AWK) -f $(srcdir)/mkheader.awk \
- $(srcdir)/err-sources.h.in \
- $(srcdir)/err-codes.h.in \
- $(srcdir)/errnos.in \
- extra-h.in \
- $(srcdir)/gpg-error.h.in > $@
+mkheader: mkheader.c Makefile
+ $(CC_FOR_BUILD) -g -O0 -I. -I$(srcdir) -o $@ $(srcdir)/mkheader.c
+
+# We also depend on versioninfo.rc because that is build by
+# config.status and thus has up-to-date version numbers.
+gpg-error.h: Makefile mkheader $(parts_of_gpg_error_h) versioninfo.rc
+ ./mkheader $(host_os) $(srcdir)/gpg-error.h.in \
+ $(PACKAGE_VERSION) $(VERSION_NUMBER) >$@
install-data-local:
diff --git a/src/errnos.in b/src/errnos.in
index 0688047..018fb9a 100644
--- a/src/errnos.in
+++ b/src/errnos.in
@@ -1,5 +1,5 @@
-# errnos.h.in - List of system error values input file.
-/* errnos.h - List of system error values.
+# errnos.in - List of system error values input file.
+/* errnos.in - List of system error values.
Copyright (C) 2003, 2004 g10 Code GmbH
This file is part of libgpg-error.
@@ -8,12 +8,12 @@
modify it under the terms of the GNU Lesser General Public License
as published by the Free Software Foundation; either version 2.1 of
the License, or (at your option) any later version.
-
+
libgpg-error 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 libgpg-error; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -169,4 +169,4 @@
137 EUSERS
138 EWOULDBLOCK
139 EXDEV
-140 EXFULL \ No newline at end of file
+140 EXFULL
diff --git a/src/gpg-error.h.in b/src/gpg-error.h.in
index 303fac0..a2fb044 100644
--- a/src/gpg-error.h.in
+++ b/src/gpg-error.h.in
@@ -1,5 +1,5 @@
-/* gpg-error.h - Public interface to libgpg-error.
- Copyright (C) 2003, 2004, 2010, 2013 g10 Code GmbH
+/* gpg-error.h - Public interface to libgpg-error. -*- c -*-
+ Copyright (C) 2003, 2004, 2010, 2013, 2014 g10 Code GmbH
This file is part of libgpg-error.
@@ -15,6 +15,8 @@
You should have received a copy of the GNU Lesser General Public
License along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+ @configure_input@
*/
@@ -77,7 +79,7 @@ extern "C" {
entries. */
typedef enum
{
-@include err-sources.h.in
+@include:err-sources@
/* This is one more than the largest allowed entry. */
GPG_ERR_SOURCE_DIM = 128
@@ -90,11 +92,11 @@ typedef enum
entries. */
typedef enum
{
-@include err-codes.h.in
+@include:err-codes@
/* The following error codes are used to map system errors. */
#define GPG_ERR_SYSTEM_ERROR (1 << 15)
-@include errnos.in
+@include:errnos@
/* This is one more than the largest allowed entry. */
GPG_ERR_CODE_DIM = 65536
@@ -248,7 +250,13 @@ void gpg_err_set_errno (int err);
/* Return or check the version. */
const char *gpg_error_check_version (const char *req_version);
-@include extra-h.in
+/* The version string of this header. */
+#define GPG_ERROR_VERSION @version@
+
+/* The version number of this header. */
+#define GPG_ERROR_VERSION_NUMBER @version-number@
+
+@include:os-add@
/* Self-documenting convenience functions. */
diff --git a/src/mkheader.awk b/src/mkheader.awk
deleted file mode 100644
index 0ff08f9..0000000
--- a/src/mkheader.awk
+++ /dev/null
@@ -1,218 +0,0 @@
-# mkheader.awk
-# Copyright (C) 2003, 2004 g10 Code GmbH
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of
-# the License, or (at your option) any later version.
-#
-# This program 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
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-#
-# As a special exception, g10 Code GmbH gives unlimited permission to
-# copy, distribute and modify the C source files that are the output
-# of mkheader.awk. You need not follow the terms of the GNU General
-# Public License when using or distributing such scripts, even though
-# portions of the text of mkheader.awk appear in them. The GNU
-# General Public License (GPL) does govern all other use of the material
-# that constitutes the mkheader.awk program.
-#
-# Certain portions of the mkheader.awk source text are designed to be
-# copied (in certain cases, depending on the input) into the output of
-# mkheader.awk. We call these the "data" portions. The rest of the
-# mkheader.awk source text consists of comments plus executable code
-# that decides which of the data portions to output in any given case.
-# We call these comments and executable code the "non-data" portions.
-# mkheader.h never copies any of the non-data portions into its output.
-#
-# This special exception to the GPL applies to versions of mkheader.awk
-# released by g10 Code GmbH. When you make and distribute a modified version
-# of mkheader.awk, you may extend this special exception to the GPL to
-# apply to your modified version as well, *unless* your modified version
-# has the potential to copy into its output some of the text that was the
-# non-data portion of the version that you started with. (In other words,
-# unless your change moves or copies text from the non-data portions to the
-# data portions.) If your modification has such potential, you must delete
-# any notice of this special exception to the GPL from your modified version.
-
-# This script processes gpg-error.h.in in an awful way.
-# Its input is, one after another, the content of the err-sources.h.in file,
-# the err-codes.h.in file, the errnos.in file, and then gpg-error.h.in.
-# There is nothing fancy about this.
-#
-# An alternative would be to use getline to get the content of the first three files,
-# but then we need to pre-process gpg-error.h.in with configure to get
-# at the full path of the files in @srcdir@.
-
-BEGIN {
- FS = "[\t]+";
-# sources_nr holds the number of error sources.
- sources_nr = 0;
-# codes_nr holds the number of error codes.
- codes_nr = 0;
-# errnos_nr holds the number of system errors.
- errnos_nr = 0;
-# extra_nr holds the number of extra lines to be included.
- extra_nr = 0
-
-# These variables walk us through our input.
- sources_header = 1;
- sources_body = 0;
- between_sources_and_codes = 0;
- codes_body = 0;
- between_codes_and_errnos = 0;
- errnos_body = 0;
- extra_body = 0;
- gpg_error_h = 0;
-
- print "/* Output of mkheader.awk. DO NOT EDIT. -*- buffer-read-only: t -*- */";
- print "";
-
-}
-
-
-sources_header {
- if ($1 ~ /^[0123456789]+$/)
- {
- sources_header = 0;
- sources_body = 1;
- }
-}
-
-sources_body {
- sub (/\#.+/, "");
- sub (/[ ]+$/, ""); # Strip trailing space and tab characters.
-
- if (/^$/)
- next;
-
- if ($1 == "")
- {
- sources_body = 0;
- between_sources_and_codes = 1;
- }
- else
- {
-# Remember the error source number and symbol of each error source.
- sources_idx[sources_nr] = $1;
- sources_sym[sources_nr] = $2;
- sources_nr++;
- }
-}
-
-between_sources_and_codes {
- if ($1 ~ /^[0123456789]+$/)
- {
- between_sources_and_codes = 0;
- codes_body = 1;
- }
-}
-
-codes_body {
- sub (/\#.+/, "");
- sub (/[ ]+$/, ""); # Strip trailing space and tab characters.
-
- if (/^$/)
- next;
-
- if ($1 == "")
- {
- codes_body = 0;
- between_codes_and_errnos = 1;
- }
- else
- {
-# Remember the error code number and symbol of each error source.
- codes_idx[codes_nr] = $1;
- codes_sym[codes_nr] = $2;
- codes_nr++;
- }
-}
-
-between_codes_and_errnos {
- if ($1 ~ /^[0-9]/)
- {
- between_codes_and_errnos = 0;
- errnos_body = 1;
- }
-}
-
-errnos_body {
- sub (/\#.+/, "");
- sub (/[ ]+$/, ""); # Strip trailing space and tab characters.
-
- if (/^$/)
- next;
-
- if ($1 !~ /^[0-9]/)
- {
-# Note that this assumes that extra_body.in doesn't start with a digit.
- errnos_body = 0;
- extra_body = 1;
- }
- else
- {
- errnos_idx[errnos_nr] = "GPG_ERR_SYSTEM_ERROR | " $1;
- errnos_sym[errnos_nr] = "GPG_ERR_" $2;
- errnos_nr++;
- }
-}
-
-extra_body {
- if (/^##/)
- next
-
- if (/^EOF/)
- {
- extra_body = 0;
- gpg_error_h = 1;
- next;
- }
- else
- {
- extra_line[extra_nr] = $0;
- extra_nr++;
- }
-}
-
-gpg_error_h {
- if ($0 ~ /^@include err-sources/)
- {
- for (i = 0; i < sources_nr; i++)
- {
- print " " sources_sym[i] " = " sources_idx[i] ",";
-# print "#define " sources_sym[i] " (" sources_idx[i] ")";
- }
- }
- else if ($0 ~ /^@include err-codes/)
- {
- for (i = 0; i < codes_nr; i++)
- {
- print " " codes_sym[i] " = " codes_idx[i] ",";
-# print "#define " codes_sym[i] " (" codes_idx[i] ")";
- }
- }
- else if ($0 ~ /^@include errnos/)
- {
- for (i = 0; i < errnos_nr; i++)
- {
- print " " errnos_sym[i] " = " errnos_idx[i] ",";
-# print "#define " errnos_sym[i] " (" errnos_idx[i] ")";
- }
- }
- else if ($0 ~ /^@include extra-h.in/)
- {
- for (i = 0; i < extra_nr; i++)
- {
- print extra_line[i];
- }
- }
- else
- print;
-}
diff --git a/src/mkheader.c b/src/mkheader.c
new file mode 100644
index 0000000..eea7914
--- /dev/null
+++ b/src/mkheader.c
@@ -0,0 +1,363 @@
+/* mkheader.c - Create a header file for libgpg-error
+ * Copyright (C) 2010 Free Software Foundation, Inc.
+ * Copyright (C) 2014 g10 Code GmbH
+ *
+ * This file is free software; as a special exception the author gives
+ * unlimited permission to copy and/or distribute it, with or without
+ * modifications, as long as this notice is preserved.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#define PGM "mkheader"
+
+#define LINESIZE 1024
+
+static const char *host_os;
+static char *srcdir;
+static const char *hdr_version;
+static const char *hdr_version_number;
+
+
+/* Write LINE to stdout. The function is allowed to modify LINE. */
+static void
+write_str (char *line)
+{
+ if (fputs (line, stdout) == EOF)
+ {
+ fprintf (stderr, PGM ": error writing to stdout: %s\n", strerror (errno));
+ exit (1);
+ }
+}
+
+static void
+write_line (char *line)
+{
+ if (puts (line) == EOF)
+ {
+ fprintf (stderr, PGM ": error writing to stdout: %s\n", strerror (errno));
+ exit (1);
+ }
+}
+
+
+/* Write SOURCE or CODES line to stdout. The function is allowed to
+ modify LINE. Trailing white space is already removed. Passing
+ NULL resets the internal state. */
+static void
+write_sources_or_codes (char *line)
+{
+ static int in_intro;
+ char *p1, *p2;
+
+ if (!line)
+ {
+ in_intro = 1;
+ return;
+ }
+
+ if (!*line)
+ return;
+
+ if (in_intro)
+ {
+ if (!strchr ("0123456789", *line))
+ return;
+ in_intro = 0;
+ }
+
+ p1 = strtok (line, " \t");
+ p2 = p1? strtok (NULL, " \t") : NULL;
+
+ if (p1 && p2 && strchr ("0123456789", *p1) && *p2)
+ {
+ write_str (" ");
+ write_str (p2);
+ write_str (" = ");
+ write_str (p1);
+ write_str (",\n");
+ }
+}
+
+
+/* Write system errnos to stdout. The function is allowed to
+ modify LINE. Trailing white space is already removed. Passing
+ NULL resets the internal state. */
+static void
+write_errnos_in (char *line)
+{
+ static int state;
+ char *p1, *p2;
+
+ if (!line)
+ {
+ state = 0;
+ return;
+ }
+
+ if (!*line)
+ return;
+
+ if (!state && strchr ("0123456789", *line))
+ state = 1;
+ else if (state == 1 && !strchr ("0123456789", *line))
+ state = 2;
+
+ if (state != 1)
+ return;
+
+ p1 = strtok (line, " \t");
+ p2 = p1? strtok (NULL, " \t") : NULL;
+
+ if (p1 && p2 && strchr ("0123456789", *p1) && *p2)
+ {
+ write_str (" GPG_ERR_");
+ write_str (p2);
+ write_str (" = GPG_ERR_SYSTEM_ERROR | ");
+ write_str (p1);
+ write_str (",\n");
+ }
+}
+
+
+/* Include the file NAME from the source directory. The included file
+ is not further expanded. It may have comments indicated by a
+ double hash mark at the begin of a line. OUTF is called for each
+ read line and passed a buffer with the content of line sans line
+ line endings. */
+static void
+include_file (const char *fname, int lnr, const char *name, void (*outf)(char*))
+{
+ FILE *fp;
+ char *incfname;
+ int inclnr;
+ char line[LINESIZE];
+
+ incfname = malloc (strlen (srcdir) + strlen (name) + 1);
+ if (!incfname)
+ {
+ fputs (PGM ": out of core\n", stderr);
+ exit (1);
+ }
+ strcpy (incfname, srcdir);
+ strcat (incfname, name);
+
+ fp = fopen (incfname, "r");
+ if (!fp)
+ {
+ fprintf (stderr, "%s:%d: error including `%s': %s\n",
+ fname, lnr, incfname, strerror (errno));
+ exit (1);
+ }
+
+ inclnr = 0;
+ while (fgets (line, LINESIZE, fp))
+ {
+ size_t n = strlen (line);
+
+ inclnr++;
+ if (!n || line[n-1] != '\n')
+ {
+ fprintf (stderr,
+ "%s:%d: trailing linefeed missing, line too long or "
+ "embedded nul character\n", incfname, inclnr);
+ fprintf (stderr,"%s:%d: note: file '%s' included from here\n",
+ fname, lnr, incfname);
+ exit (1);
+ }
+ line[--n] = 0;
+ while (line[n] == ' ' || line[n] == '\t' || line[n] == '\r')
+ {
+ line[n] = 0;
+ if (!n)
+ break;
+ n--;
+ }
+
+ if (line[0] == '#' && line[1] == '#')
+ {
+ if (!strncmp (line+2, "EOF##", 5))
+ break; /* Forced EOF. */
+ }
+ else
+ outf (line);
+ }
+ if (ferror (fp))
+ {
+ fprintf (stderr, "%s:%d: error reading `%s': %s\n",
+ fname, lnr, incfname, strerror (errno));
+ exit (1);
+ }
+ fclose (fp);
+ free (incfname);
+}
+
+
+static int
+write_special (const char *fname, int lnr, const char *tag)
+{
+ if (!strcmp (tag, "version"))
+ {
+ putchar ('\"');
+ fputs (hdr_version, stdout);
+ putchar ('\"');
+ putchar ('\n');
+ }
+ else if (!strcmp (tag, "version-number"))
+ {
+ fputs (hdr_version_number, stdout);
+ putchar ('\n');
+ }
+ else if (!strcmp (tag, "include:err-sources"))
+ {
+ write_sources_or_codes (NULL);
+ include_file (fname, lnr, "err-sources.h.in", write_sources_or_codes);
+ }
+ else if (!strcmp (tag, "include:err-codes"))
+ {
+ write_sources_or_codes (NULL);
+ include_file (fname, lnr, "err-codes.h.in", write_sources_or_codes);
+ }
+ else if (!strcmp (tag, "include:errnos"))
+ {
+ include_file (fname, lnr, "errnos.in", write_errnos_in);
+ }
+ else if (!strcmp (tag, "include:os-add"))
+ {
+ if (!strcmp (host_os, "mingw32"))
+ {
+ include_file (fname, lnr, "w32-add.h", write_line);
+ }
+ else if (!strcmp (host_os, "mingw32ce"))
+ {
+ include_file (fname, lnr, "w32-add.h", write_line);
+ include_file (fname, lnr, "w32ce-add.h", write_line);
+ }
+ }
+ else
+ return 0; /* Unknown tag. */
+
+ return 1; /* Tag processed. */
+}
+
+
+int
+main (int argc, char **argv)
+{
+ FILE *fp;
+ char line[LINESIZE];
+ int lnr = 0;
+ const char *fname, *s;
+ char *p1, *p2;
+
+ if (argc)
+ {
+ argc--; argv++;
+ }
+
+ if (argc != 4)
+ {
+ fputs ("usage: " PGM " host_os template.h version version_number\n",
+ stderr);
+ return 1;
+ }
+ host_os = argv[0];
+ fname = argv[1];
+ hdr_version = argv[2];
+ hdr_version_number = argv[3];
+
+ srcdir = malloc (strlen (fname) + 2 + 1);
+ if (!srcdir)
+ {
+ fputs (PGM ": out of core\n", stderr);
+ return 1;
+ }
+ strcpy (srcdir, fname);
+ p1 = strrchr (srcdir, '/');
+ if (p1)
+ p1[1] = 0;
+ else
+ strcpy (srcdir, "./");
+
+ fp = fopen (fname, "r");
+ if (!fp)
+ {
+ fprintf (stderr, "%s:%d: can't open file: %s",
+ fname, lnr, strerror (errno));
+ return 1;
+ }
+
+ while (fgets (line, LINESIZE, fp))
+ {
+ size_t n = strlen (line);
+
+ lnr++;
+ if (!n || line[n-1] != '\n')
+ {
+ fprintf (stderr,
+ "%s:%d: trailing linefeed missing, line too long or "
+ "embedded nul character\n", fname, lnr);
+ break;
+ }
+ line[--n] = 0;
+
+ p1 = strchr (line, '@');
+ p2 = p1? strchr (p1+1, '@') : NULL;
+ if (!p1 || !p2 || p2-p1 == 1)
+ {
+ puts (line);
+ continue;
+ }
+ *p1++ = 0;
+ *p2++ = 0;
+ fputs (line, stdout);
+
+ if (!strcmp (p1, "configure_input"))
+ {
+ s = strrchr (fname, '/');
+ printf ("Do not edit. Generated from %s by %s for %s.",
+ s? s+1 : fname, PGM, host_os);
+ fputs (p2, stdout);
+ putchar ('\n');
+ }
+ else if (!write_special (fname, lnr, p1))
+ {
+ putchar ('@');
+ fputs (p1, stdout);
+ putchar ('@');
+ fputs (p2, stdout);
+ putchar ('\n');
+ }
+ }
+
+ if (ferror (fp))
+ {
+ fprintf (stderr, "%s:%d: error reading file: %s\n",
+ fname, lnr, strerror (errno));
+ return 1;
+ }
+
+ fputs ("/*\n"
+ "Loc" "al Variables:\n"
+ "buffer-read-only: t\n"
+ "End:\n"
+ "*/\n", stdout);
+
+ if (ferror (stdout))
+ {
+ fprintf (stderr, PGM ": error writing to stdout: %s\n", strerror (errno));
+ return 1;
+ }
+
+ fclose (fp);
+
+ return 0;
+}