diff --git a/src/Makefile.am b/src/Makefile.am index 380ea7c..914768c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,352 +1,352 @@ # Makefile.am for libgpg-error. # Copyright (C) 2003, 2004, 2014 g10 Code GmbH # # This file is part of libgpg-error. # # libgpg-error 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 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 this program; if not, see . # SPDX-License-Identifier: LGPL-2.1+ # # 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 # depend on the configuration anyway. # if HAVE_W32CE_SYSTEM gpg_extra_headers = gpg-extra/errno.h extra_cppflags = -idirafter gpg-extra else gpg_extra_headers = extra_cppflags = endif localedir = $(datadir)/locale bin_PROGRAMS = gpg-error if HAVE_W32_SYSTEM noinst_PROGRAMS = gen-w32-lock-obj else noinst_PROGRAMS = gen-posix-lock-obj endif # Distributed lock object definitions for cross compilation. lock_obj_pub = \ syscfg/lock-obj-pub.aarch64-unknown-linux-gnu.h \ syscfg/lock-obj-pub.aarch64-apple-darwin.h \ syscfg/lock-obj-pub.alpha-unknown-linux-gnu.h \ syscfg/lock-obj-pub.arm-unknown-linux-androideabi.h \ syscfg/lock-obj-pub.arm-unknown-linux-gnueabi.h \ syscfg/lock-obj-pub.arm-apple-darwin.h \ syscfg/lock-obj-pub.hppa-unknown-linux-gnu.h \ syscfg/lock-obj-pub.i386-apple-darwin.h \ - syscfg/lock-obj-pub.i686-pc-gnu.h \ - syscfg/lock-obj-pub.i686-pc-kfreebsd-gnu.h \ - syscfg/lock-obj-pub.i686-pc-linux-gnu.h \ + syscfg/lock-obj-pub.i686-unknown-gnu.h \ + syscfg/lock-obj-pub.i686-unknown-kfreebsd-gnu.h \ + syscfg/lock-obj-pub.i686-unknown-linux-gnu.h \ syscfg/lock-obj-pub.m68k-unknown-linux-gnu.h \ syscfg/lock-obj-pub.mips-unknown-linux-gnu.h \ syscfg/lock-obj-pub.mips64el-unknown-linux-gnuabi64.h \ syscfg/lock-obj-pub.mipsel-unknown-linux-gnu.h \ syscfg/lock-obj-pub.nios2-unknown-linux-gnu.h \ syscfg/lock-obj-pub.or1k-unknown-linux-gnu.h \ syscfg/lock-obj-pub.powerpc-unknown-linux-gnu.h \ syscfg/lock-obj-pub.powerpc64-unknown-linux-gnu.h \ syscfg/lock-obj-pub.powerpc64le-unknown-linux-gnu.h \ syscfg/lock-obj-pub.powerpc-unknown-linux-gnuspe.h \ syscfg/lock-obj-pub.riscv64-unknown-linux-gnu.h \ - syscfg/lock-obj-pub.s390x-ibm-linux-gnu.h \ + syscfg/lock-obj-pub.s390x-unknown-linux-gnu.h \ syscfg/lock-obj-pub.sh3-unknown-linux-gnu.h \ syscfg/lock-obj-pub.sh4-unknown-linux-gnu.h \ syscfg/lock-obj-pub.sparc-unknown-linux-gnu.h \ syscfg/lock-obj-pub.sparc64-unknown-linux-gnu.h \ syscfg/lock-obj-pub.x86_64-apple-darwin.h \ - syscfg/lock-obj-pub.x86_64-pc-kfreebsd-gnu.h \ - syscfg/lock-obj-pub.x86_64-pc-linux-gnu.h \ - syscfg/lock-obj-pub.x86_64-pc-linux-gnux32.h \ - syscfg/lock-obj-pub.x86_64-pc-linux-musl.h \ + syscfg/lock-obj-pub.x86_64-unknown-kfreebsd-gnu.h \ + syscfg/lock-obj-pub.x86_64-unknown-linux-gnu.h \ + syscfg/lock-obj-pub.x86_64-unknown-linux-gnux32.h \ + syscfg/lock-obj-pub.x86_64-unknown-linux-musl.h \ syscfg/lock-obj-pub.tilegx-unknown-linux-gnu.h \ syscfg/lock-obj-pub.ia64-unknown-linux-gnu.h \ syscfg/lock-obj-pub.mingw32.h lib_LTLIBRARIES = libgpg-error.la nodist_include_HEADERS = gpg-error.h gpgrt.h bin_SCRIPTS = gpg-error-config nodist_bin_SCRIPTS = gpgrt-config m4datadir = $(datadir)/aclocal m4data_DATA = gpg-error.m4 gpgrt.m4 pkgconfigdir = $(datadir)/pkgconfig pkgconfig_DATA = gpg-error.pc 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.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 gpgrt.m4 \ gpg-error.vers gpg-error.def.in \ versioninfo.rc.in gpg-error.w32-manifest.in \ gpg-error-config-new.in gpg-error-config-test.sh gpg-error.pc.in \ $(lock_obj_pub) 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 gpgrt.h \ gpgrt-config 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 gpgrt.h gpgrt-config \ mkerrcodes$(EXEEXT_FOR_BUILD) 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 mkheader$(EXEEXT_FOR_BUILD) \ gpg-error-config gpg-error-config-test.log \ $(tmp_files) lock-obj-pub.native.h TESTS = gpg-error-config-test.sh # # {{{ Begin Windows part # if HAVE_W32_SYSTEM arch_sources = w32-gettext.c w32-lock.c w32-lock-obj.h w32-thread.c \ w32-iconv.c w32-estream.c w32-reg.c spawn-w32.c RCCOMPILE = $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ -DLOCALEDIR=\"$(localedir)\" $(AM_CPPFLAGS) $(CPPFLAGS) LTRCCOMPILE = $(LIBTOOL) --mode=compile --tag=RC $(RCCOMPILE) SUFFIXES = .rc .lo .rc.lo: $(LTRCCOMPILE) -i "$<" -o "$@" gpg_error_res = versioninfo.lo no_undefined = -no-undefined export_symbols = -export-symbols gpg-error.def # i686-w64-mingw32.gcc version 4.9.1 takes the long long helper # functions from libgcc_s_sjlj-1.dll and not from a static libgcc. As # a plain C program we do not use exception handler and thus there is # no need to use this DLL. Thus we force gcc to link that statically. extra_ltoptions = -XCClinker -static-libgcc versioninfo.lo : gpg-error.w32-manifest install-def-file: gpg-error.def -$(INSTALL) -d $(DESTDIR)$(libdir) $(INSTALL) gpg-error.def $(DESTDIR)$(libdir)/gpg-error.def uninstall-def-file: -rm $(DESTDIR)$(libdir)/gpg-error.def libgpg_error_la_DEPENDENCIES = $(gpg_error_res) gpg-error.def intllibs = socklibs = -lws2_32 # # }}} End Windows part # else # # {{{ Begin Unix part # arch_sources = posix-lock.c posix-lock-obj.h posix-thread.c spawn-posix.c gpg_error_res = no_undefined = export_symbols = extra_ltoptions = install-def-file: uninstall-def-file: intllibs = @LTLIBINTL@ socklibs = endif # # }}} End Unix part # if HAVE_LD_VERSION_SCRIPT libgpg_error_vers_opt = -Wl,--version-script=$(srcdir)/gpg-error.vers else libgpg_error_vers_opt = endif libgpg_error_la_LDFLAGS = \ $(no_undefined) $(export_symbols) $(libgpg_error_vers_opt) \ $(extra_ltoptions) -version-info \ @LIBGPG_ERROR_LT_CURRENT@:@LIBGPG_ERROR_LT_REVISION@:@LIBGPG_ERROR_LT_AGE@ libgpg_error_la_SOURCES = gettext.h $(arch_sources) \ gpgrt-int.h init.c init.h version.c lock.h thread.h \ estream.c estream-printf.c estream-printf.h \ strsource.c strerror.c code-to-errno.c code-from-errno.c \ visibility.c visibility.h \ sysutils.c \ syscall-clamp.c \ logging.c \ b64dec.c b64enc.c \ argparse.c nodist_libgpg_error_la_SOURCES = gpg-error.h # libgpg_error_la_DEPENDENCIES = \ # $(srcdir)/gpg-error.vers # Note that RCCOMPILE needs the same defines as ..._la_CPPFLAGS but # without the extra_cppflags because they may include am -idirafter # which is not supported by the RC compiler. libgpg_error_la_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\" $(extra_cppflags) libgpg_error_la_LIBADD = $(gpg_error_res) $(intllibs) $(socklibs) $(LIBTHREAD) gpg_error_SOURCES = strsource-sym.c strerror-sym.c gpg-error.c gpg_error_CPPFLAGS = -DPKGDATADIR=\"$(pkgdatadir)\" \ -DLOCALEDIR=\"$(localedir)\" $(extra_cppflags) gpg_error_LDADD = ./libgpg-error.la $(LTLIBINTL) # We build err-sources.h and err-codes.h in the source directory. # This is needed because gettext does only look into the source # directory to find the files listed in po/POTFILE.in. To make these # rules work we also need to depend on Makefile.am and not on the # generated files Makefile.in or Makefile. $(srcdir)/err-sources.h: Makefile.am mkstrtable.awk err-sources.h.in $(AWK) -f $(srcdir)/mkstrtable.awk -v textidx=3 \ $(srcdir)/err-sources.h.in >$@ err-sources-sym.h: Makefile mkstrtable.awk err-sources.h.in $(AWK) -f $(srcdir)/mkstrtable.awk -v textidx=2 -v nogettext=1 \ $(srcdir)/err-sources.h.in >$@ $(srcdir)/err-codes.h: Makefile.am mkstrtable.awk err-codes.h.in $(AWK) -f $(srcdir)/mkstrtable.awk -v textidx=3 \ $(srcdir)/err-codes.h.in >$@ err-codes-sym.h: Makefile mkstrtable.awk err-codes.h.in $(AWK) -f $(srcdir)/mkstrtable.awk -v textidx=2 -v nogettext=1 \ $(srcdir)/err-codes.h.in >$@ code-to-errno.h: Makefile mkerrnos.awk errnos.in $(AWK) -f $(srcdir)/mkerrnos.awk $(srcdir)/errnos.in >$@ # It is correct to use $(CPP). We want the host's idea of the error codes. mkerrcodes.h: Makefile mkerrcodes.awk $(gpg_extra_headers) $(AWK) -f $(srcdir)/mkerrcodes1.awk $(srcdir)/errnos.in >_$@ $(CPP) $(CPPFLAGS) $(extra_cppflags) -P _$@ | grep GPG_ERR_ | \ $(AWK) -f $(srcdir)/mkerrcodes.awk >$@ -rm _$@ if HAVE_W32CE_SYSTEM # It is correct to use $(CPP). We want the host's idea of the error codes. mkw32errmap.tab.h: Makefile mkw32errmap.c $(CPP) -DRESOLVE_MACROS $(srcdir)/mkw32errmap.c | \ grep '{&mkw32errmap_marker' >$@ mkw32errmap.map.c: mkw32errmap$(EXEEXT_FOR_BUILD) ./mkw32errmap$(EXEEXT_FOR_BUILD) --map > $@ gpg-extra/errno.h: mkw32errmap$(EXEEXT_FOR_BUILD) -$(MKDIR_P) gpg-extra ./mkw32errmap$(EXEEXT_FOR_BUILD) > $@ else mkw32errmap.map.c: echo "/*dummy*/" > $@ endif # We use CC proper for preprocessing thus we have to convince it that # the data is really to be preprocessed. gpg-error.def: Makefile gpg-error.def.in cat $(srcdir)/gpg-error.def.in >_$@.h $(CPP) $(DEFAULT_INCLUDES) $(INCLUDES) $(extra_cppflags) _$@.h | \ grep -v '^#' >$@ -rm _$@.h # It is correct to use $(CC_FOR_BUILD) here. We want to run the # program at build time. mkerrcodes$(EXEEXT_FOR_BUILD): mkerrcodes.c mkerrcodes.h Makefile $(CC_FOR_BUILD) -I. -I$(srcdir) -o $@ $(srcdir)/mkerrcodes.c if HAVE_W32CE_SYSTEM # It is correct to use $(CC_FOR_BUILD) here. We want to run the # program at build time. mkw32errmap$(EXEEXT_FOR_BUILD): mkw32errmap.c mkw32errmap.tab.h Makefile $(CC_FOR_BUILD) -I. -I$(srcdir) -o $@ $(srcdir)/mkw32errmap.c endif code-from-errno.h: mkerrcodes$(EXEEXT_FOR_BUILD) Makefile ./mkerrcodes$(EXEEXT_FOR_BUILD) | $(AWK) -f $(srcdir)/mkerrcodes2.awk >$@ errnos-sym.h: Makefile mkstrtable.awk errnos.in $(AWK) -f $(srcdir)/mkstrtable.awk -v textidx=2 -v nogettext=1 \ -v prefix=GPG_ERR_ -v namespace=errnos_ \ $(srcdir)/errnos.in >$@ mkheader$(EXEEXT_FOR_BUILD): mkheader.c Makefile $(CC_FOR_BUILD) -g -O0 -I. -I$(srcdir) -o $@ $(srcdir)/mkheader.c 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 \ $(lock_obj_pub) # If we are cross-compiling or building on Windows we better make sure # that no stale native lock include file will be found by mkheader. if FORCE_USE_SYSCFG pre_mkheader_cmds = if test -f lock-obj-pub.native.h; \ then rm lock-obj-pub.native.h; fi else pre_mkheader_cmds = : parts_of_gpg_error_h += ./lock-obj-pub.native.h ./lock-obj-pub.native.h: Makefile gen-posix-lock-obj$(EXEEXT) posix-lock-obj.h ./gen-posix-lock-obj >$@ endif # 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$(EXEEXT_FOR_BUILD) $(parts_of_gpg_error_h) \ versioninfo.rc ../config.h $(pre_mkheader_cmds) ./mkheader$(EXEEXT_FOR_BUILD) $(host_os) $(host_triplet) $(srcdir)/gpg-error.h.in \ ../config.h $(PACKAGE_VERSION) $(VERSION_NUMBER) >$@ gpgrt.h: gpg-error.h cp gpg-error.h gpgrt.h gpgrt-config: gpg-error-config cp gpg-error-config gpgrt-config gpg-error-config: gpg-error-config-new gpg-error-config-old @echo -n "Confirm gpg-error-config works... " @if $(srcdir)/gpg-error-config-test.sh --old-new; then \ echo "good"; \ cp gpg-error-config-new $@; \ else \ echo "no"; \ echo "*** Please report to with gpg-error-config-test.log"; \ cp gpg-error-config-old $@; \ fi install-data-local: if HAVE_W32CE_SYSTEM -$(MKDIR_P) "$(DESTDIR)$(includedir)/gpg-extra" $(INSTALL_DATA) gpg-extra/errno.h \ "$(DESTDIR)$(includedir)/gpg-extra/errno.h" else : endif diff --git a/src/mkheader.c b/src/mkheader.c index 2fc5fad..7a38a1b 100644 --- a/src/mkheader.c +++ b/src/mkheader.c @@ -1,690 +1,752 @@ /* 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 #include #include #include #include #define PGM "mkheader" #define LINESIZE 1024 static const char *host_os; static char *host_triplet; static char *srcdir; static const char *hdr_version; static const char *hdr_version_number; /* Values take from the supplied config.h. */ static int have_stdint_h; static int have_sys_types_h; static int have_w32_system; static int have_w64_system; static char *replacement_for_off_type; static int use_posix_threads; /* Various state flags. */ static int stdint_h_included; static int sys_types_h_included; /* The usual free wrapper. */ static void xfree (void *a) { if (a) free (a); } static char * -xstrdup (const char *string) +xmalloc (size_t n) { char *p; - size_t len = strlen (string) + 1; - p = malloc (len); + p = malloc (n); if (!p) { fputs (PGM ": out of core\n", stderr); exit (1); } + return p; +} + + +static char * +xstrdup (const char *string) +{ + char *p; + size_t len = strlen (string) + 1; + + p = xmalloc (len); memcpy (p, string, len); return p; } /* Return a malloced string with TRIPLET. If TRIPLET has an alias return that instead. In general build-aux/config.sub should do the - aliasing but some returned triplets are anyway identical and thus we - use this function to map it to the canonical form. */ + aliasing but some returned triplets are anyway identical and thus + we use this function to map it to the canonical form. + NO_VENDOR_HACK is for internal use; caller must call with 0. */ static char * -canon_host_triplet (const char *triplet) +canon_host_triplet (const char *triplet, int no_vendor_hack) { struct { const char *name; const char *alias; } tbl[] = { - {"i486-pc-linux-gnu", "i686-pc-linux-gnu" }, + {"i486-pc-linux-gnu", "i686-unknown-linux-gnu" }, {"i586-pc-linux-gnu" }, - {"i486-pc-gnu", "i686-pc-gnu"}, + {"i686-pc-linux-gnu" }, + {"arc-oe-linux-uclibc" }, /* Other CPU but same struct. */ + + {"i486-pc-gnu", "i686-unknown-gnu"}, {"i586-pc-gnu"}, - {"i486-pc-kfreebsd-gnu", "i686-pc-kfreebsd-gnu"}, + {"i686-pc-gnu"}, + + {"i486-pc-kfreebsd-gnu", "i686-unknown-kfreebsd-gnu"}, {"i586-pc-kfreebsd-gnu"}, + {"i686-pc-kfreebsd-gnu"}, - {"x86_64-pc-linux-gnuhardened1", "x86_64-pc-linux-gnu" }, + {"x86_64-pc-linux-gnuhardened1", "x86_64-unknown-linux-gnu" }, + {"x86_64-pc-linux-gnu" }, {"powerpc-unknown-linux-gnuspe", "powerpc-unknown-linux-gnu" }, {"arm-unknown-linux-gnueabihf", "arm-unknown-linux-gnueabi" }, {"armv7-unknown-linux-gnueabihf" }, {"armv5-unknown-linux-musleabi" }, {"armv6-unknown-linux-musleabihf" }, { NULL } }; int i; const char *lastalias = NULL; + const char *s; for (i=0; tbl[i].name; i++) { if (tbl[i].alias) lastalias = tbl[i].alias; if (!strcmp (tbl[i].name, triplet)) { if (!lastalias) break; /* Ooops: first entry has no alias. */ return xstrdup (lastalias); } } + for (i=0, s=triplet; *s; s++) + if (*s == '-') + i++; + if (i > 2 && !no_vendor_hack) + { + /* We have a 4 part "triplet": CPU-VENDOR-KERNEL-SYSTEM where + * the last two parts replace the OS part of a real triplet. + * The VENDOR part is then in general useless because + * KERNEL-SYSTEM is specific enough. We now do a second pass by + * replacing VENDOR with "unknown". */ + char *p; + char *buf = xmalloc (strlen (triplet) + 7 + 1); + + for (p=buf,s=triplet,i=0; *s; s++) + { + *p++ = *s; + if (*s == '-' && ++i == 1) + { + memcpy (p, "unknown-",8); + p += 8; + for (s++; *s != '-'; s++) + ; + } + } + *p = 0; + p = canon_host_triplet (buf, 1); + xfree (buf); + return p; + } + return xstrdup (triplet); } /* Parse the supplied config.h file and extract required info. Returns 0 on success. */ static int parse_config_h (const char *fname) { FILE *fp; char line[LINESIZE]; int lnr = 0; char *p1; 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; if (strncmp (line, "#define ", 8)) continue; /* We are only interested in define lines. */ p1 = strtok (line + 8, " \t"); if (!*p1) continue; /* oops */ if (!strcmp (p1, "HAVE_STDINT_H")) have_stdint_h = 1; else if (!strcmp (p1, "HAVE_SYS_TYPES_H")) have_sys_types_h = 1; else if (!strcmp (p1, "HAVE_W32_SYSTEM")) have_w32_system = 1; else if (!strcmp (p1, "HAVE_W64_SYSTEM")) have_w64_system = 1; else if (!strcmp (p1, "REPLACEMENT_FOR_OFF_T")) { p1 = strtok (NULL, "\""); if (!*p1) continue; /* oops */ xfree (replacement_for_off_type); replacement_for_off_type = xstrdup (p1); } else if (!strcmp (p1, "USE_POSIX_THREADS")) use_posix_threads = 1; } if (ferror (fp)) { fprintf (stderr, "%s:%d: error reading file: %s\n", fname, lnr, strerror (errno)); return 1; } fclose (fp); return 0; } /* 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"); } } /* Create the full file name for NAME and return a newly allocated string with it. If name contains a '&' and REPL is not NULL replace '&' with REPL. */ static char * mk_include_name (const char *name, const char *repl) { FILE *fp; char *incfname, *p; const char *s; incfname = malloc (strlen (srcdir) + strlen (name) + (repl?strlen (repl):0) + 1); if (!incfname) { fputs (PGM ": out of core\n", stderr); exit (1); } if (*name == '.' && name[1] == '/') *incfname = 0; else strcpy (incfname, srcdir); p = incfname + strlen (incfname); for (s=name; *s; s++) { if (*s == '&' && repl) { while (*repl) *p++ = *repl++; repl = NULL; /* Replace only once. */ } else *p++ = *s; } *p = 0; return incfname; } /* 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. If NAME is prefixed with "./" it is included from the current directory and not from the source directory. */ static void include_file (const char *fname, int lnr, const char *name, void (*outf)(char*)) { FILE *fp; char *incfname; int inclnr; char line[LINESIZE]; int repl_flag; repl_flag = !!strchr (name, '&'); incfname = mk_include_name (name, repl_flag? host_triplet : NULL); fp = fopen (incfname, "r"); if (!fp && repl_flag) { /* Try again using the OS string. */ free (incfname); incfname = mk_include_name (name, host_os); fp = fopen (incfname, "r"); } if (!fp) { fprintf (stderr, "%s:%d: error including `%s': %s\n", fname, lnr, incfname, strerror (errno)); exit (1); } if (repl_flag) fprintf (stderr,"%s:%d: note: including '%s'\n", fname, lnr, incfname); 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); } /* Try to include the file NAME. Returns true if it does not exist. */ static int try_include_file (const char *fname, int lnr, const char *name, void (*outf)(char*)) { int rc; char *incfname; int repl_flag; repl_flag = !!strchr (name, '&'); incfname = mk_include_name (name, repl_flag? host_triplet : NULL); rc = access (incfname, R_OK); if (rc && repl_flag) { free (incfname); incfname = mk_include_name (name, host_os); rc = access (incfname, R_OK); } if (!rc) include_file (fname, lnr, name, outf); free (incfname); return rc; } static int write_special (const char *fname, int lnr, const char *tag) { if (!strcmp (tag, "version")) { putchar ('\"'); fputs (hdr_version, stdout); putchar ('\"'); } else if (!strcmp (tag, "version-number")) { fputs (hdr_version_number, stdout); } else if (!strcmp (tag, "define:gpgrt_off_t")) { if (!replacement_for_off_type) { fprintf (stderr, "%s:%d: replacement for off_t not defined\n", fname, lnr); exit (1); } else { if (!strcmp (replacement_for_off_type, "int64_t") && !stdint_h_included && have_stdint_h) { fputs ("#include \n\n", stdout); stdint_h_included = 1; } printf ("typedef %s gpgrt_off_t;\n", replacement_for_off_type); } } else if (!strcmp (tag, "define:gpgrt_ssize_t")) { if (have_w64_system) { if (!stdint_h_included && have_stdint_h) { fputs ("# include \n", stdout); stdint_h_included = 1; } fputs ("typedef int64_t gpgrt_ssize_t;\n", stdout); } else if (have_w32_system) { fputs ("typedef long gpgrt_ssize_t;\n", stdout); } else { if (!sys_types_h_included) { fputs ("#include \n", stdout); sys_types_h_included = 1; } fputs ("typedef ssize_t gpgrt_ssize_t;\n", stdout); } } else if (!strcmp (tag, "api_ssize_t")) { if (have_w32_system) fputs ("gpgrt_ssize_t", stdout); else fputs ("ssize_t", stdout); } else if (!strcmp (tag, "define:pid_t")) { if (have_sys_types_h) { if (!sys_types_h_included) { fputs ("#include \n", stdout); sys_types_h_included = 1; } } else if (have_w64_system) { if (!stdint_h_included && have_stdint_h) { fputs ("#include \n", stdout); stdint_h_included = 1; } fputs ("typedef int64_t pid_t\n", stdout); } else { fputs ("typedef int pid_t\n", stdout); } } 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 if (!strcmp (tag, "include:lock-obj")) { if (try_include_file (fname, lnr, "./lock-obj-pub.native.h", write_line)) include_file (fname, lnr, "syscfg/lock-obj-pub.&.h", write_line); } else return 0; /* Unknown tag. */ return 1; /* Tag processed. */ } int main (int argc, char **argv) { - FILE *fp; + FILE *fp = NULL; char line[LINESIZE]; int lnr = 0; const char *fname, *s; char *p1, *p2; const char *config_h; const char *host_triplet_raw; if (argc) { argc--; argv++; } - if (argc != 6) + if (argc == 1) + { + /* Print just the canonicalized host triplet. */ + host_triplet = canon_host_triplet (argv[0], 0); + printf ("%s\n", host_triplet); + goto leave; + } + else if (argc == 6) + ; /* Standard operation. */ + else { fputs ("usage: " PGM " host_os host_triplet template.h config.h" - " version version_number\n", + " version version_number\n" + " " PGM + " host_triplet\n", stderr); return 1; } host_os = argv[0]; host_triplet_raw = argv[1]; fname = argv[2]; config_h = argv[3]; hdr_version = argv[4]; hdr_version_number = argv[5]; - host_triplet = canon_host_triplet (host_triplet_raw); + host_triplet = canon_host_triplet (host_triplet_raw, 0); 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, "./"); if (parse_config_h (config_h)) return 1; 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 for:\n%*s", s? s+1 : fname, (int)(p1 - line) + 13, ""); if (!strcmp (host_triplet, host_triplet_raw)) printf ("%s", host_triplet); else printf ("%s (%s)", host_triplet, host_triplet_raw); if (!use_posix_threads && !have_w32_system && !have_w64_system) fputs (" NO-THREADS", stdout); fputs (p2, stdout); } else if (!write_special (fname, lnr, p1)) { putchar ('@'); fputs (p1, stdout); putchar ('@'); fputs (p2, stdout); } else if (*p2) { 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); + leave: if (ferror (stdout)) { fprintf (stderr, PGM ": error writing to stdout: %s\n", strerror (errno)); return 1; } - fclose (fp); + if (fp) + fclose (fp); xfree (host_triplet); return 0; } diff --git a/src/syscfg/lock-obj-pub.i686-pc-gnu.h b/src/syscfg/lock-obj-pub.i686-unknown-gnu.h similarity index 100% rename from src/syscfg/lock-obj-pub.i686-pc-gnu.h rename to src/syscfg/lock-obj-pub.i686-unknown-gnu.h diff --git a/src/syscfg/lock-obj-pub.i686-pc-kfreebsd-gnu.h b/src/syscfg/lock-obj-pub.i686-unknown-kfreebsd-gnu.h similarity index 100% rename from src/syscfg/lock-obj-pub.i686-pc-kfreebsd-gnu.h rename to src/syscfg/lock-obj-pub.i686-unknown-kfreebsd-gnu.h diff --git a/src/syscfg/lock-obj-pub.i686-pc-linux-gnu.h b/src/syscfg/lock-obj-pub.i686-unknown-linux-gnu.h similarity index 100% rename from src/syscfg/lock-obj-pub.i686-pc-linux-gnu.h rename to src/syscfg/lock-obj-pub.i686-unknown-linux-gnu.h diff --git a/src/syscfg/lock-obj-pub.s390x-ibm-linux-gnu.h b/src/syscfg/lock-obj-pub.s390x-unknown-linux-gnu.h similarity index 100% rename from src/syscfg/lock-obj-pub.s390x-ibm-linux-gnu.h rename to src/syscfg/lock-obj-pub.s390x-unknown-linux-gnu.h diff --git a/src/syscfg/lock-obj-pub.x86_64-pc-kfreebsd-gnu.h b/src/syscfg/lock-obj-pub.x86_64-unknown-kfreebsd-gnu.h similarity index 100% rename from src/syscfg/lock-obj-pub.x86_64-pc-kfreebsd-gnu.h rename to src/syscfg/lock-obj-pub.x86_64-unknown-kfreebsd-gnu.h diff --git a/src/syscfg/lock-obj-pub.x86_64-pc-linux-gnu.h b/src/syscfg/lock-obj-pub.x86_64-unknown-linux-gnu.h similarity index 100% rename from src/syscfg/lock-obj-pub.x86_64-pc-linux-gnu.h rename to src/syscfg/lock-obj-pub.x86_64-unknown-linux-gnu.h diff --git a/src/syscfg/lock-obj-pub.x86_64-pc-linux-gnux32.h b/src/syscfg/lock-obj-pub.x86_64-unknown-linux-gnux32.h similarity index 100% rename from src/syscfg/lock-obj-pub.x86_64-pc-linux-gnux32.h rename to src/syscfg/lock-obj-pub.x86_64-unknown-linux-gnux32.h diff --git a/src/syscfg/lock-obj-pub.x86_64-pc-linux-musl.h b/src/syscfg/lock-obj-pub.x86_64-unknown-linux-musl.h similarity index 100% rename from src/syscfg/lock-obj-pub.x86_64-pc-linux-musl.h rename to src/syscfg/lock-obj-pub.x86_64-unknown-linux-musl.h