Blame src/mkheader.c

Packit fc043f
/* mkheader.c - Create a header file for libgpg-error
Packit fc043f
 * Copyright (C) 2010 Free Software Foundation, Inc.
Packit fc043f
 * Copyright (C) 2014 g10 Code GmbH
Packit fc043f
 *
Packit fc043f
 * This file is free software; as a special exception the author gives
Packit fc043f
 * unlimited permission to copy and/or distribute it, with or without
Packit fc043f
 * modifications, as long as this notice is preserved.
Packit fc043f
 *
Packit fc043f
 * This file is distributed in the hope that it will be useful, but
Packit fc043f
 * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
Packit fc043f
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Packit fc043f
 */
Packit fc043f
Packit fc043f
Packit fc043f
#include <stdio.h>
Packit fc043f
#include <stdlib.h>
Packit fc043f
#include <string.h>
Packit fc043f
#include <errno.h>
Packit fc043f
#include <unistd.h>
Packit fc043f
Packit fc043f
#define PGM "mkheader"
Packit fc043f
Packit fc043f
#define LINESIZE 1024
Packit fc043f
Packit fc043f
static const char *host_os;
Packit fc043f
static char *host_triplet;
Packit fc043f
static char *srcdir;
Packit fc043f
static const char *hdr_version;
Packit fc043f
static const char *hdr_version_number;
Packit fc043f
Packit fc043f
/* Values take from the supplied config.h.  */
Packit fc043f
static int have_stdint_h;
Packit fc043f
static int have_sys_types_h;
Packit fc043f
static int have_w32_system;
Packit fc043f
static int have_w64_system;
Packit fc043f
static char *replacement_for_off_type;
Packit fc043f
static int use_posix_threads;
Packit fc043f
Packit fc043f
/* Various state flags.  */
Packit fc043f
static int stdint_h_included;
Packit fc043f
static int sys_types_h_included;
Packit fc043f
Packit fc043f
Packit fc043f
/* The usual free wrapper.  */
Packit fc043f
static void
Packit fc043f
xfree (void *a)
Packit fc043f
{
Packit fc043f
  if (a)
Packit fc043f
    free (a);
Packit fc043f
}
Packit fc043f
Packit fc043f
Packit fc043f
static char *
Packit fc043f
xstrdup (const char *string)
Packit fc043f
{
Packit fc043f
  char *p;
Packit fc043f
  size_t len = strlen (string) + 1;
Packit fc043f
Packit fc043f
  p = malloc (len);
Packit fc043f
  if (!p)
Packit fc043f
    {
Packit fc043f
      fputs (PGM ": out of core\n", stderr);
Packit fc043f
      exit (1);
Packit fc043f
    }
Packit fc043f
  memcpy (p, string, len);
Packit fc043f
  return p;
Packit fc043f
}
Packit fc043f
Packit fc043f
Packit fc043f
/* Return a malloced string with TRIPLET.  If TRIPLET has an alias
Packit fc043f
   return that instead.  In general build-aux/config.sub should do the
Packit fc043f
   aliasing but some returned triplets are anyway identical and thus we
Packit fc043f
   use this function to map it to the canonical form.  */
Packit fc043f
static char *
Packit fc043f
canon_host_triplet (const char *triplet)
Packit fc043f
{
Packit fc043f
  struct {
Packit fc043f
    const char *name;
Packit fc043f
    const char *alias;
Packit fc043f
  } tbl[] = {
Packit fc043f
    {"i486-pc-linux-gnu", "i686-pc-linux-gnu" },
Packit fc043f
    {"i586-pc-linux-gnu" },
Packit fc043f
    {"i486-pc-gnu", "i686-pc-gnu"},
Packit fc043f
    {"i586-pc-gnu"},
Packit fc043f
    {"i486-pc-kfreebsd-gnu", "i686-pc-kfreebsd-gnu"},
Packit fc043f
    {"i586-pc-kfreebsd-gnu"},
Packit fc043f
Packit fc043f
    {"x86_64-pc-linux-gnuhardened1", "x86_64-pc-linux-gnu" },
Packit fc043f
Packit fc043f
    {"powerpc-unknown-linux-gnuspe", "powerpc-unknown-linux-gnu" },
Packit fc043f
Packit fc043f
    {"arm-unknown-linux-gnueabihf",  "arm-unknown-linux-gnueabi" },
Packit fc043f
    {"armv7-unknown-linux-gnueabihf"  },
Packit fc043f
    {"armv5-unknown-linux-musleabi"   },
Packit fc043f
    {"armv6-unknown-linux-musleabihf" },
Packit fc043f
Packit fc043f
    { NULL }
Packit fc043f
  };
Packit fc043f
  int i;
Packit fc043f
  const char *lastalias = NULL;
Packit fc043f
Packit fc043f
  for (i=0; tbl[i].name; i++)
Packit fc043f
    {
Packit fc043f
      if (tbl[i].alias)
Packit fc043f
        lastalias = tbl[i].alias;
Packit fc043f
      if (!strcmp (tbl[i].name, triplet))
Packit fc043f
        {
Packit fc043f
          if (!lastalias)
Packit fc043f
            break; /* Ooops: first entry has no alias.  */
Packit fc043f
          return xstrdup (lastalias);
Packit fc043f
        }
Packit fc043f
    }
Packit fc043f
  return xstrdup (triplet);
Packit fc043f
}
Packit fc043f
Packit fc043f
Packit fc043f
/* Parse the supplied config.h file and extract required info.
Packit fc043f
   Returns 0 on success.  */
Packit fc043f
static int
Packit fc043f
parse_config_h (const char *fname)
Packit fc043f
{
Packit fc043f
  FILE *fp;
Packit fc043f
  char line[LINESIZE];
Packit fc043f
  int lnr = 0;
Packit fc043f
  char *p1;
Packit fc043f
Packit fc043f
  fp = fopen (fname, "r");
Packit fc043f
  if (!fp)
Packit fc043f
    {
Packit fc043f
      fprintf (stderr, "%s:%d: can't open file: %s",
Packit fc043f
               fname, lnr, strerror (errno));
Packit fc043f
      return 1;
Packit fc043f
    }
Packit fc043f
Packit fc043f
  while (fgets (line, LINESIZE, fp))
Packit fc043f
    {
Packit fc043f
      size_t n = strlen (line);
Packit fc043f
Packit fc043f
      lnr++;
Packit fc043f
      if (!n || line[n-1] != '\n')
Packit fc043f
        {
Packit fc043f
          fprintf (stderr,
Packit fc043f
                   "%s:%d: trailing linefeed missing, line too long or "
Packit fc043f
                   "embedded nul character\n", fname, lnr);
Packit fc043f
          break;
Packit fc043f
        }
Packit fc043f
      line[--n] = 0;
Packit fc043f
Packit fc043f
      if (strncmp (line, "#define ", 8))
Packit fc043f
        continue; /* We are only interested in define lines.  */
Packit fc043f
      p1 = strtok (line + 8, " \t");
Packit fc043f
      if (!*p1)
Packit fc043f
        continue; /* oops */
Packit fc043f
      if (!strcmp (p1, "HAVE_STDINT_H"))
Packit fc043f
        have_stdint_h = 1;
Packit fc043f
      else if (!strcmp (p1, "HAVE_SYS_TYPES_H"))
Packit fc043f
        have_sys_types_h = 1;
Packit fc043f
      else if (!strcmp (p1, "HAVE_W32_SYSTEM"))
Packit fc043f
        have_w32_system = 1;
Packit fc043f
      else if (!strcmp (p1, "HAVE_W64_SYSTEM"))
Packit fc043f
        have_w64_system = 1;
Packit fc043f
      else if (!strcmp (p1, "REPLACEMENT_FOR_OFF_T"))
Packit fc043f
        {
Packit fc043f
          p1 = strtok (NULL, "\"");
Packit fc043f
          if (!*p1)
Packit fc043f
            continue; /* oops */
Packit fc043f
          xfree (replacement_for_off_type);
Packit fc043f
          replacement_for_off_type = xstrdup (p1);
Packit fc043f
        }
Packit fc043f
      else if (!strcmp (p1, "USE_POSIX_THREADS"))
Packit fc043f
        use_posix_threads = 1;
Packit fc043f
    }
Packit fc043f
Packit fc043f
  if (ferror (fp))
Packit fc043f
    {
Packit fc043f
      fprintf (stderr, "%s:%d: error reading file: %s\n",
Packit fc043f
               fname, lnr, strerror (errno));
Packit fc043f
      return 1;
Packit fc043f
    }
Packit fc043f
Packit fc043f
  fclose (fp);
Packit fc043f
  return 0;
Packit fc043f
}
Packit fc043f
Packit fc043f
Packit fc043f
/* Write LINE to stdout.  The function is allowed to modify LINE.  */
Packit fc043f
static void
Packit fc043f
write_str (char *line)
Packit fc043f
{
Packit fc043f
  if (fputs (line, stdout) == EOF)
Packit fc043f
    {
Packit fc043f
      fprintf (stderr, PGM ": error writing to stdout: %s\n", strerror (errno));
Packit fc043f
      exit (1);
Packit fc043f
    }
Packit fc043f
}
Packit fc043f
Packit fc043f
static void
Packit fc043f
write_line (char *line)
Packit fc043f
{
Packit fc043f
  if (puts (line) == EOF)
Packit fc043f
    {
Packit fc043f
      fprintf (stderr, PGM ": error writing to stdout: %s\n", strerror (errno));
Packit fc043f
      exit (1);
Packit fc043f
    }
Packit fc043f
}
Packit fc043f
Packit fc043f
Packit fc043f
/* Write SOURCE or CODES line to stdout.  The function is allowed to
Packit fc043f
   modify LINE.  Trailing white space is already removed.  Passing
Packit fc043f
   NULL resets the internal state.  */
Packit fc043f
static void
Packit fc043f
write_sources_or_codes (char *line)
Packit fc043f
{
Packit fc043f
  static int in_intro;
Packit fc043f
  char *p1, *p2;
Packit fc043f
Packit fc043f
  if (!line)
Packit fc043f
    {
Packit fc043f
      in_intro = 1;
Packit fc043f
      return;
Packit fc043f
    }
Packit fc043f
Packit fc043f
  if (!*line)
Packit fc043f
    return;
Packit fc043f
Packit fc043f
  if (in_intro)
Packit fc043f
    {
Packit fc043f
      if (!strchr ("0123456789", *line))
Packit fc043f
        return;
Packit fc043f
      in_intro = 0;
Packit fc043f
    }
Packit fc043f
Packit fc043f
  p1 = strtok (line, " \t");
Packit fc043f
  p2 = p1? strtok (NULL, " \t") : NULL;
Packit fc043f
Packit fc043f
  if (p1 && p2 && strchr ("0123456789", *p1) && *p2)
Packit fc043f
    {
Packit fc043f
      write_str ("    ");
Packit fc043f
      write_str (p2);
Packit fc043f
      write_str (" = ");
Packit fc043f
      write_str (p1);
Packit fc043f
      write_str (",\n");
Packit fc043f
    }
Packit fc043f
}
Packit fc043f
Packit fc043f
Packit fc043f
/* Write system errnos to stdout.  The function is allowed to
Packit fc043f
   modify LINE.  Trailing white space is already removed.  Passing
Packit fc043f
   NULL resets the internal state.  */
Packit fc043f
static void
Packit fc043f
write_errnos_in (char *line)
Packit fc043f
{
Packit fc043f
  static int state;
Packit fc043f
  char *p1, *p2;
Packit fc043f
Packit fc043f
  if (!line)
Packit fc043f
    {
Packit fc043f
      state = 0;
Packit fc043f
      return;
Packit fc043f
    }
Packit fc043f
Packit fc043f
  if (!*line)
Packit fc043f
    return;
Packit fc043f
Packit fc043f
  if (!state && strchr ("0123456789", *line))
Packit fc043f
    state = 1;
Packit fc043f
  else if (state == 1 && !strchr ("0123456789", *line))
Packit fc043f
    state = 2;
Packit fc043f
Packit fc043f
  if (state != 1)
Packit fc043f
    return;
Packit fc043f
Packit fc043f
  p1 = strtok (line, " \t");
Packit fc043f
  p2 = p1? strtok (NULL, " \t") : NULL;
Packit fc043f
Packit fc043f
  if (p1 && p2 && strchr ("0123456789", *p1) && *p2)
Packit fc043f
    {
Packit fc043f
      write_str ("    GPG_ERR_");
Packit fc043f
      write_str (p2);
Packit fc043f
      write_str (" = GPG_ERR_SYSTEM_ERROR | ");
Packit fc043f
      write_str (p1);
Packit fc043f
      write_str (",\n");
Packit fc043f
    }
Packit fc043f
}
Packit fc043f
Packit fc043f
Packit fc043f
/* Create the full file name for NAME and return a newly allocated
Packit fc043f
   string with it.  If name contains a '&' and REPL is not NULL
Packit fc043f
   replace '&' with REPL. */
Packit fc043f
static char *
Packit fc043f
mk_include_name (const char *name, const char *repl)
Packit fc043f
{
Packit fc043f
  FILE *fp;
Packit fc043f
  char *incfname, *p;
Packit fc043f
  const char *s;
Packit fc043f
Packit fc043f
  incfname = malloc (strlen (srcdir) + strlen (name)
Packit fc043f
                     + (repl?strlen (repl):0) + 1);
Packit fc043f
  if (!incfname)
Packit fc043f
    {
Packit fc043f
      fputs (PGM ": out of core\n", stderr);
Packit fc043f
      exit (1);
Packit fc043f
    }
Packit fc043f
Packit fc043f
  if (*name == '.' && name[1] == '/')
Packit fc043f
    *incfname = 0;
Packit fc043f
  else
Packit fc043f
    strcpy (incfname, srcdir);
Packit fc043f
  p = incfname + strlen (incfname);
Packit fc043f
  for (s=name; *s; s++)
Packit fc043f
    {
Packit fc043f
      if (*s == '&' && repl)
Packit fc043f
        {
Packit fc043f
          while (*repl)
Packit fc043f
            *p++ = *repl++;
Packit fc043f
          repl = NULL;  /* Replace only once.  */
Packit fc043f
        }
Packit fc043f
      else
Packit fc043f
        *p++ = *s;
Packit fc043f
    }
Packit fc043f
  *p = 0;
Packit fc043f
  return incfname;
Packit fc043f
}
Packit fc043f
Packit fc043f
Packit fc043f
/* Include the file NAME from the source directory.  The included file
Packit fc043f
   is not further expanded.  It may have comments indicated by a
Packit fc043f
   double hash mark at the begin of a line.  OUTF is called for each
Packit fc043f
   read line and passed a buffer with the content of line sans line
Packit fc043f
   line endings.  If NAME is prefixed with "./" it is included from
Packit fc043f
   the current directory and not from the source directory. */
Packit fc043f
static void
Packit fc043f
include_file (const char *fname, int lnr, const char *name, void (*outf)(char*))
Packit fc043f
{
Packit fc043f
  FILE *fp;
Packit fc043f
  char *incfname;
Packit fc043f
  int inclnr;
Packit fc043f
  char line[LINESIZE];
Packit fc043f
  int repl_flag;
Packit fc043f
Packit fc043f
  repl_flag = !!strchr (name, '&';;
Packit fc043f
  incfname = mk_include_name (name, repl_flag? host_triplet : NULL);
Packit fc043f
  fp = fopen (incfname, "r");
Packit fc043f
  if (!fp && repl_flag)
Packit fc043f
    {
Packit fc043f
      /* Try again using the OS string.  */
Packit fc043f
      free (incfname);
Packit fc043f
      incfname = mk_include_name (name, host_os);
Packit fc043f
      fp = fopen (incfname, "r");
Packit fc043f
    }
Packit fc043f
  if (!fp)
Packit fc043f
    {
Packit fc043f
      fprintf (stderr, "%s:%d: error including `%s': %s\n",
Packit fc043f
               fname, lnr, incfname, strerror (errno));
Packit fc043f
      exit (1);
Packit fc043f
    }
Packit fc043f
Packit fc043f
  if (repl_flag)
Packit fc043f
    fprintf (stderr,"%s:%d: note: including '%s'\n",
Packit fc043f
             fname, lnr, incfname);
Packit fc043f
Packit fc043f
  inclnr = 0;
Packit fc043f
  while (fgets (line, LINESIZE, fp))
Packit fc043f
    {
Packit fc043f
      size_t n = strlen (line);
Packit fc043f
Packit fc043f
      inclnr++;
Packit fc043f
      if (!n || line[n-1] != '\n')
Packit fc043f
        {
Packit fc043f
          fprintf (stderr,
Packit fc043f
                   "%s:%d: trailing linefeed missing, line too long or "
Packit fc043f
                   "embedded nul character\n", incfname, inclnr);
Packit fc043f
          fprintf (stderr,"%s:%d: note: file '%s' included from here\n",
Packit fc043f
                   fname, lnr, incfname);
Packit fc043f
          exit (1);
Packit fc043f
        }
Packit fc043f
      line[--n] = 0;
Packit fc043f
      while (line[n] == ' ' || line[n] == '\t' || line[n] == '\r')
Packit fc043f
        {
Packit fc043f
          line[n] = 0;
Packit fc043f
          if (!n)
Packit fc043f
            break;
Packit fc043f
          n--;
Packit fc043f
        }
Packit fc043f
Packit fc043f
      if (line[0] == '#' && line[1] == '#')
Packit fc043f
        {
Packit fc043f
          if (!strncmp (line+2, "EOF##", 5))
Packit fc043f
            break; /* Forced EOF.  */
Packit fc043f
        }
Packit fc043f
      else
Packit fc043f
        outf (line);
Packit fc043f
    }
Packit fc043f
  if (ferror (fp))
Packit fc043f
    {
Packit fc043f
      fprintf (stderr, "%s:%d: error reading `%s': %s\n",
Packit fc043f
               fname, lnr, incfname, strerror (errno));
Packit fc043f
      exit (1);
Packit fc043f
    }
Packit fc043f
  fclose (fp);
Packit fc043f
  free (incfname);
Packit fc043f
}
Packit fc043f
Packit fc043f
Packit fc043f
/* Try to include the file NAME.  Returns true if it does not
Packit fc043f
   exist. */
Packit fc043f
static int
Packit fc043f
try_include_file (const char *fname, int lnr, const char *name,
Packit fc043f
                  void (*outf)(char*))
Packit fc043f
{
Packit fc043f
  int rc;
Packit fc043f
  char *incfname;
Packit fc043f
  int repl_flag;
Packit fc043f
Packit fc043f
  repl_flag = !!strchr (name, '&';;
Packit fc043f
  incfname = mk_include_name (name, repl_flag? host_triplet : NULL);
Packit fc043f
  rc = access (incfname, R_OK);
Packit fc043f
  if (rc && repl_flag)
Packit fc043f
    {
Packit fc043f
      free (incfname);
Packit fc043f
      incfname = mk_include_name (name, host_os);
Packit fc043f
      rc = access (incfname, R_OK);
Packit fc043f
    }
Packit fc043f
  if (!rc)
Packit fc043f
    include_file (fname, lnr, name, outf);
Packit fc043f
Packit fc043f
  free (incfname);
Packit fc043f
  return rc;
Packit fc043f
}
Packit fc043f
Packit fc043f
Packit fc043f
static int
Packit fc043f
write_special (const char *fname, int lnr, const char *tag)
Packit fc043f
{
Packit fc043f
  if (!strcmp (tag, "version"))
Packit fc043f
    {
Packit fc043f
      putchar ('\"');
Packit fc043f
      fputs (hdr_version, stdout);
Packit fc043f
      putchar ('\"');
Packit fc043f
    }
Packit fc043f
  else if (!strcmp (tag, "version-number"))
Packit fc043f
    {
Packit fc043f
      fputs (hdr_version_number, stdout);
Packit fc043f
    }
Packit fc043f
  else if (!strcmp (tag, "define:gpgrt_off_t"))
Packit fc043f
    {
Packit fc043f
      if (!replacement_for_off_type)
Packit fc043f
        {
Packit fc043f
          fprintf (stderr, "%s:%d: replacement for off_t not defined\n",
Packit fc043f
                   fname, lnr);
Packit fc043f
          exit (1);
Packit fc043f
        }
Packit fc043f
      else
Packit fc043f
        {
Packit fc043f
          if (!strcmp (replacement_for_off_type, "int64_t")
Packit fc043f
              && !stdint_h_included && have_stdint_h)
Packit fc043f
            {
Packit fc043f
              fputs ("#include <stdint.h>\n\n", stdout);
Packit fc043f
              stdint_h_included = 1;
Packit fc043f
            }
Packit fc043f
          printf ("typedef %s gpgrt_off_t;\n", replacement_for_off_type);
Packit fc043f
        }
Packit fc043f
    }
Packit fc043f
  else if (!strcmp (tag, "define:gpgrt_ssize_t"))
Packit fc043f
    {
Packit fc043f
      if (have_w64_system)
Packit fc043f
        {
Packit fc043f
          if (!stdint_h_included && have_stdint_h)
Packit fc043f
            {
Packit fc043f
              fputs ("# include <stdint.h>\n", stdout);
Packit fc043f
              stdint_h_included = 1;
Packit fc043f
            }
Packit fc043f
          fputs ("typedef int64_t gpgrt_ssize_t;\n", stdout);
Packit fc043f
        }
Packit fc043f
      else if (have_w32_system)
Packit fc043f
        {
Packit fc043f
          fputs ("typedef long    gpgrt_ssize_t;\n", stdout);
Packit fc043f
        }
Packit fc043f
      else
Packit fc043f
        {
Packit fc043f
          if (!sys_types_h_included)
Packit fc043f
            {
Packit fc043f
              fputs ("#include <sys/types.h>\n", stdout);
Packit fc043f
              sys_types_h_included = 1;
Packit fc043f
            }
Packit fc043f
          fputs ("typedef ssize_t gpgrt_ssize_t;\n", stdout);
Packit fc043f
        }
Packit fc043f
    }
Packit fc043f
  else if (!strcmp (tag, "api_ssize_t"))
Packit fc043f
    {
Packit fc043f
      if (have_w32_system)
Packit fc043f
        fputs ("gpgrt_ssize_t", stdout);
Packit fc043f
      else
Packit fc043f
        fputs ("ssize_t", stdout);
Packit fc043f
    }
Packit fc043f
  else if (!strcmp (tag, "define:pid_t"))
Packit fc043f
    {
Packit fc043f
      if (have_sys_types_h)
Packit fc043f
        {
Packit fc043f
          if (!sys_types_h_included)
Packit fc043f
            {
Packit fc043f
              fputs ("#include <sys/types.h>\n", stdout);
Packit fc043f
              sys_types_h_included = 1;
Packit fc043f
            }
Packit fc043f
        }
Packit fc043f
      else if (have_w64_system)
Packit fc043f
        {
Packit fc043f
          if (!stdint_h_included && have_stdint_h)
Packit fc043f
            {
Packit fc043f
              fputs ("#include <stdint.h>\n", stdout);
Packit fc043f
              stdint_h_included = 1;
Packit fc043f
            }
Packit fc043f
          fputs ("typedef int64_t pid_t\n", stdout);
Packit fc043f
        }
Packit fc043f
      else
Packit fc043f
        {
Packit fc043f
          fputs ("typedef int     pid_t\n", stdout);
Packit fc043f
        }
Packit fc043f
    }
Packit fc043f
  else if (!strcmp (tag, "include:err-sources"))
Packit fc043f
    {
Packit fc043f
      write_sources_or_codes (NULL);
Packit fc043f
      include_file (fname, lnr, "err-sources.h.in", write_sources_or_codes);
Packit fc043f
    }
Packit fc043f
  else if (!strcmp (tag, "include:err-codes"))
Packit fc043f
    {
Packit fc043f
      write_sources_or_codes (NULL);
Packit fc043f
      include_file (fname, lnr, "err-codes.h.in", write_sources_or_codes);
Packit fc043f
    }
Packit fc043f
  else if (!strcmp (tag, "include:errnos"))
Packit fc043f
    {
Packit fc043f
      include_file (fname, lnr, "errnos.in", write_errnos_in);
Packit fc043f
    }
Packit fc043f
  else if (!strcmp (tag, "include:os-add"))
Packit fc043f
    {
Packit fc043f
      if (!strcmp (host_os, "mingw32"))
Packit fc043f
        {
Packit fc043f
          include_file (fname, lnr, "w32-add.h", write_line);
Packit fc043f
        }
Packit fc043f
      else if (!strcmp (host_os, "mingw32ce"))
Packit fc043f
        {
Packit fc043f
          include_file (fname, lnr, "w32-add.h", write_line);
Packit fc043f
          include_file (fname, lnr, "w32ce-add.h", write_line);
Packit fc043f
        }
Packit fc043f
    }
Packit fc043f
  else if (!strcmp (tag, "include:lock-obj"))
Packit fc043f
    {
Packit fc043f
      if (try_include_file (fname, lnr, "./lock-obj-pub.native.h", write_line))
Packit fc043f
        include_file (fname, lnr, "syscfg/lock-obj-pub.&.h", write_line);
Packit fc043f
    }
Packit fc043f
  else
Packit fc043f
    return 0; /* Unknown tag.  */
Packit fc043f
Packit fc043f
  return 1; /* Tag processed.  */
Packit fc043f
}
Packit fc043f
Packit fc043f
Packit fc043f
int
Packit fc043f
main (int argc, char **argv)
Packit fc043f
{
Packit fc043f
  FILE *fp;
Packit fc043f
  char line[LINESIZE];
Packit fc043f
  int lnr = 0;
Packit fc043f
  const char *fname, *s;
Packit fc043f
  char *p1, *p2;
Packit fc043f
  const char *config_h;
Packit fc043f
  const char *host_triplet_raw;
Packit fc043f
Packit fc043f
  if (argc)
Packit fc043f
    {
Packit fc043f
      argc--; argv++;
Packit fc043f
    }
Packit fc043f
Packit fc043f
  if (argc != 6)
Packit fc043f
    {
Packit fc043f
      fputs ("usage: " PGM
Packit fc043f
             " host_os host_triplet template.h config.h"
Packit fc043f
             " version version_number\n",
Packit fc043f
             stderr);
Packit fc043f
      return 1;
Packit fc043f
    }
Packit fc043f
  host_os = argv[0];
Packit fc043f
  host_triplet_raw = argv[1];
Packit fc043f
  fname = argv[2];
Packit fc043f
  config_h = argv[3];
Packit fc043f
  hdr_version = argv[4];
Packit fc043f
  hdr_version_number = argv[5];
Packit fc043f
Packit fc043f
  host_triplet = canon_host_triplet (host_triplet_raw);
Packit fc043f
Packit fc043f
  srcdir = malloc (strlen (fname) + 2 + 1);
Packit fc043f
  if (!srcdir)
Packit fc043f
    {
Packit fc043f
      fputs (PGM ": out of core\n", stderr);
Packit fc043f
      return 1;
Packit fc043f
    }
Packit fc043f
  strcpy (srcdir, fname);
Packit fc043f
  p1 = strrchr (srcdir, '/');
Packit fc043f
  if (p1)
Packit fc043f
    p1[1] = 0;
Packit fc043f
  else
Packit fc043f
    strcpy (srcdir, "./");
Packit fc043f
Packit fc043f
  if (parse_config_h (config_h))
Packit fc043f
    return 1;
Packit fc043f
Packit fc043f
  fp = fopen (fname, "r");
Packit fc043f
  if (!fp)
Packit fc043f
    {
Packit fc043f
      fprintf (stderr, "%s:%d: can't open file: %s",
Packit fc043f
               fname, lnr, strerror (errno));
Packit fc043f
      return 1;
Packit fc043f
    }
Packit fc043f
Packit fc043f
  while (fgets (line, LINESIZE, fp))
Packit fc043f
    {
Packit fc043f
      size_t n = strlen (line);
Packit fc043f
Packit fc043f
      lnr++;
Packit fc043f
      if (!n || line[n-1] != '\n')
Packit fc043f
        {
Packit fc043f
          fprintf (stderr,
Packit fc043f
                   "%s:%d: trailing linefeed missing, line too long or "
Packit fc043f
                   "embedded nul character\n", fname, lnr);
Packit fc043f
          break;
Packit fc043f
        }
Packit fc043f
      line[--n] = 0;
Packit fc043f
Packit fc043f
      p1 = strchr (line, '@');
Packit fc043f
      p2 = p1? strchr (p1+1, '@') : NULL;
Packit fc043f
      if (!p1 || !p2 || p2-p1 == 1)
Packit fc043f
        {
Packit fc043f
          puts (line);
Packit fc043f
          continue;
Packit fc043f
        }
Packit fc043f
      *p1++ = 0;
Packit fc043f
      *p2++ = 0;
Packit fc043f
      fputs (line, stdout);
Packit fc043f
Packit fc043f
      if (!strcmp (p1, "configure_input"))
Packit fc043f
        {
Packit fc043f
          s = strrchr (fname, '/');
Packit fc043f
          printf ("Do not edit.  Generated from %s for:\n%*s",
Packit fc043f
                  s? s+1 : fname, (int)(p1 - line) + 13, "");
Packit fc043f
          if (!strcmp (host_triplet, host_triplet_raw))
Packit fc043f
            printf ("%s", host_triplet);
Packit fc043f
          else
Packit fc043f
            printf ("%s (%s)", host_triplet, host_triplet_raw);
Packit fc043f
          if (!use_posix_threads && !have_w32_system && !have_w64_system)
Packit fc043f
            fputs (" NO-THREADS", stdout);
Packit fc043f
          fputs (p2, stdout);
Packit fc043f
        }
Packit fc043f
      else if (!write_special (fname, lnr, p1))
Packit fc043f
        {
Packit fc043f
          putchar ('@');
Packit fc043f
          fputs (p1, stdout);
Packit fc043f
          putchar ('@');
Packit fc043f
          fputs (p2, stdout);
Packit fc043f
        }
Packit fc043f
      else if (*p2)
Packit fc043f
        {
Packit fc043f
          fputs (p2, stdout);
Packit fc043f
        }
Packit fc043f
      putchar ('\n');
Packit fc043f
    }
Packit fc043f
Packit fc043f
  if (ferror (fp))
Packit fc043f
    {
Packit fc043f
      fprintf (stderr, "%s:%d: error reading file: %s\n",
Packit fc043f
               fname, lnr, strerror (errno));
Packit fc043f
      return 1;
Packit fc043f
    }
Packit fc043f
Packit fc043f
  fputs ("/*\n"
Packit fc043f
         "Loc" "al Variables:\n"
Packit fc043f
         "buffer-read-only: t\n"
Packit fc043f
         "End:\n"
Packit fc043f
         "*/\n", stdout);
Packit fc043f
Packit fc043f
  if (ferror (stdout))
Packit fc043f
    {
Packit fc043f
      fprintf (stderr, PGM ": error writing to stdout: %s\n", strerror (errno));
Packit fc043f
      return 1;
Packit fc043f
    }
Packit fc043f
Packit fc043f
  fclose (fp);
Packit fc043f
Packit fc043f
  xfree (host_triplet);
Packit fc043f
  return 0;
Packit fc043f
}