diff options
author | Werner Koch <[email protected]> | 2014-09-11 12:33:46 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2014-09-11 12:37:21 +0000 |
commit | 5a4684f3b0db4cd5c13f94b1319c245ef96ce91d (patch) | |
tree | eb3c5750c13c246b14ff2ed1646616face838be0 /src/mkheader.c | |
parent | Fix compiler warning for w32. (diff) | |
download | libgpg-error-5a4684f3b0db4cd5c13f94b1319c245ef96ce91d.tar.gz libgpg-error-5a4684f3b0db4cd5c13f94b1319c245ef96ce91d.zip |
Fix problems with ssize_t and off_t.
* configure.ac (AC_SYS_LARGEFILE): New.
(AC_CHECK_HEADERS): Check for stdint.h.
(AC_CHECK_SIZEOF): Add for int, long and long long.
(REPLACEMENT_FOR_OFF_T): New ac_define.
* src/mkheader.c (have_stdint_h, have_w32_system, have_w64_system)
(replacement_for_off_type, stdint_h_included): New.
(xfree, xstrdup): New.
(parse_config_h): New.
(write_special): Support "define:gpgrt_off_t", "define:gpgrt_ssize_t",
"api_ssize_t" tags.
(main): Add config.h arg. Call parse_config_h. Fix substitute code.
* src/Makefile.am (gpg-error.h): Pass config.h to mkheader.
* src/gpg-error.h.in: Include definitions for gpgrt_ssize_t and
gpgrt_off_t. Let mkheader insert ssize_t keywords. Chnage all off_t
to gpgrt_off_t.
* src/estream.c: Change all off_t to gpgrt_off_t. Chnage all ssize_t
to gpgrt_ssize_t.
* src/visibility.c (gpgrt_fseeko): Use gpgrt_off_t.
(gpgrt_ftello): Ditto.
(gpgrt_getline): Use gpgrt_ssize_t.
(gpgrt_read_line): Ditto.
Diffstat (limited to 'src/mkheader.c')
-rw-r--r-- | src/mkheader.c | 169 |
1 files changed, 161 insertions, 8 deletions
diff --git a/src/mkheader.c b/src/mkheader.c index 43e7fd8..9fe0695 100644 --- a/src/mkheader.c +++ b/src/mkheader.c @@ -28,6 +28,105 @@ 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_w32_system; +static int have_w64_system; +static char *replacement_for_off_type; + +/* Various state flags. */ +static int stdint_h_included; + + +/* The usual free wrapper. */ +static void +xfree (void *a) +{ + if (a) + free (a); +} + + +static char * +xstrdup (const char *string) +{ + char *p; + + p = malloc (strlen (string)+1); + if (!p) + { + fputs (PGM ": out of core\n", stderr); + exit (1); + } + strcpy (p, string); + return p; +} + + +/* 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_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); + } + } + + 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 @@ -283,12 +382,57 @@ write_special (const char *fname, int lnr, const char *tag) 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, "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 <stdint.h>\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 <stdint.h>\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 + { + fputs ("#include <sys/types.h>\n" + "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, "include:err-sources")) { @@ -336,24 +480,27 @@ main (int argc, char **argv) int lnr = 0; const char *fname, *s; char *p1, *p2; + const char *config_h; if (argc) { argc--; argv++; } - if (argc != 5) + if (argc != 6) { fputs ("usage: " PGM - " host_os host_triplet template.h version version_number\n", + " host_os host_triplet template.h config.h" + " version version_number\n", stderr); return 1; } host_os = argv[0]; host_triplet = argv[1]; fname = argv[2]; - hdr_version = argv[3]; - hdr_version_number = argv[4]; + config_h = argv[3]; + hdr_version = argv[4]; + hdr_version_number = argv[5]; srcdir = malloc (strlen (fname) + 2 + 1); if (!srcdir) @@ -368,6 +515,9 @@ main (int argc, char **argv) else strcpy (srcdir, "./"); + if (parse_config_h (config_h)) + return 1; + fp = fopen (fname, "r"); if (!fp) { @@ -407,7 +557,6 @@ main (int argc, char **argv) printf ("Do not edit. Generated from %s for %s.", s? s+1 : fname, host_triplet); fputs (p2, stdout); - putchar ('\n'); } else if (!write_special (fname, lnr, p1)) { @@ -415,8 +564,12 @@ main (int argc, char **argv) fputs (p1, stdout); putchar ('@'); fputs (p2, stdout); - putchar ('\n'); } + else if (p2 && *p2) + { + fputs (p2, stdout); + } + putchar ('\n'); } if (ferror (fp)) |