Blame stdlib/isomac.c

Packit Service 82fcde
/* Check system header files for ISO 9899:1990 (ISO C) compliance.
Packit Service 82fcde
   Copyright (C) 1996-2018 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
   Contributed by Jens Schweikhardt <schweikh@noc.dfn.de>, 1996.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library; if not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
/* This is a simple minded program that tries to find illegal macro
Packit Service 82fcde
   definitions in system header files. Illegal macro definitions are
Packit Service 82fcde
   those not from the implementation namespace (i.e. not starting with
Packit Service 82fcde
   an underscore) or not matching any identifier mandated by The
Packit Service 82fcde
   Standard. Some common macro names are considered okay, e.g. all those
Packit Service 82fcde
   beginning with E (which may be defined in <errno.h>) or ending in
Packit Service 82fcde
   _MAX. See the arrays prefix[] and suffix[] below for details.
Packit Service 82fcde
Packit Service 82fcde
   In a compliant implementation no other macros can be defined, because
Packit Service 82fcde
   you could write strictly conforming programs that may fail to compile
Packit Service 82fcde
   due to syntax errors: suppose <stdio.h> defines PIPE_BUF, then the
Packit Service 82fcde
   conforming
Packit Service 82fcde
Packit Service 82fcde
   #include <assert.h>
Packit Service 82fcde
   #include <stdio.h>      <- or where the bogus macro is defined
Packit Service 82fcde
   #include <string.h>
Packit Service 82fcde
   #define STR(x) #x
Packit Service 82fcde
   #define XSTR(x) STR(x)
Packit Service 82fcde
   int main (void)
Packit Service 82fcde
   {
Packit Service 82fcde
     int PIPE_BUF = 0;
Packit Service 82fcde
     assert (strcmp ("PIPE_BUF", XSTR (PIPE_BUF)) == 0);
Packit Service 82fcde
     return 0;
Packit Service 82fcde
   }
Packit Service 82fcde
Packit Service 82fcde
   is expected to compile and meet the assertion. If it does not, your
Packit Service 82fcde
   compiler compiles some other language than Standard C.
Packit Service 82fcde
Packit Service 82fcde
   REQUIREMENTS:
Packit Service 82fcde
     This program calls gcc to get the list of defined macros. If you
Packit Service 82fcde
     don't have gcc you're probably out of luck unless your compiler or
Packit Service 82fcde
     preprocessor has something similar to gcc's -dM option. Tune
Packit Service 82fcde
     PRINT_MACROS in this case. This program assumes headers are found
Packit Service 82fcde
     under /usr/include and that there is a writable /tmp directory.
Packit Service 82fcde
     Tune SYSTEM_INCLUDE if your system differs.
Packit Service 82fcde
     #define BROKEN_SYSTEM if system(NULL) bombs -- one more violation
Packit Service 82fcde
     of ISO C, by the way.
Packit Service 82fcde
Packit Service 82fcde
   OUTPUT:
Packit Service 82fcde
     Each header file name is printed, followed by illegal macro names
Packit Service 82fcde
     and their definition. For the above example, you would see
Packit Service 82fcde
     ...
Packit Service 82fcde
     /usr/include/stdio.h
Packit Service 82fcde
     #define PIPE_BUF 5120
Packit Service 82fcde
     ...
Packit Service 82fcde
     If your implementation does not yet incorporate Amendment 1 you
Packit Service 82fcde
     will see messages about iso646.h, wctype.h and wchar.h not being
Packit Service 82fcde
     found.  */
Packit Service 82fcde
Packit Service 82fcde
#ifndef _GNU_SOURCE
Packit Service 82fcde
# define _GNU_SOURCE 1
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#include <ctype.h>
Packit Service 82fcde
#include <stdio.h>
Packit Service 82fcde
#include <stdlib.h>
Packit Service 82fcde
#include <string.h>
Packit Service 82fcde
Packit Service 82fcde
#define HEADER_MAX          256
Packit Service 82fcde
Packit Service 82fcde
static char macrofile[] = "/tmp/isomac.XXXXXX";
Packit Service 82fcde
Packit Service 82fcde
/* ISO C header names including Amendment 1 (without ".h" suffix).  */
Packit Service 82fcde
static char *header[] =
Packit Service 82fcde
{
Packit Service 82fcde
  "assert", "ctype", "errno", "float", "iso646", "limits", "locale",
Packit Service 82fcde
  "math", "setjmp", "signal", "stdarg", "stddef", "stdio", "stdlib",
Packit Service 82fcde
  "string", "time", "wchar", "wctype"
Packit Service 82fcde
};
Packit Service 82fcde
Packit Service 82fcde
/* Macros with these prefixes are considered okay.  */
Packit Service 82fcde
static char *prefix[] =
Packit Service 82fcde
{
Packit Service 82fcde
  "_", "E", "is", "str", "mem", "SIG", "FLT_", "DBL_", "LDBL_",
Packit Service 82fcde
  "LC_", "wmem", "wcs"
Packit Service 82fcde
};
Packit Service 82fcde
Packit Service 82fcde
/* Macros with these suffixes are considered okay.  Will not work for
Packit Service 82fcde
   parametrized macros with arguments.  */
Packit Service 82fcde
static char *suffix[] =
Packit Service 82fcde
{
Packit Service 82fcde
  "_MAX", "_MIN"
Packit Service 82fcde
};
Packit Service 82fcde
Packit Service 82fcde
/* These macros are considered okay. In fact, these are just more prefixes.  */
Packit Service 82fcde
static char *macros[] =
Packit Service 82fcde
{
Packit Service 82fcde
  "BUFSIZ", "CHAR_BIT", "CHAR_MAX", "CHAR_MIN", "CLOCKS_PER_SEC",
Packit Service 82fcde
  "DBL_DIG", "DBL_EPSILON", "DBL_MANT_DIG", "DBL_MAX",
Packit Service 82fcde
  "DBL_MAX_10_EXP", "DBL_MAX_EXP", "DBL_MIN", "DBL_MIN_10_EXP",
Packit Service 82fcde
  "DBL_MIN_EXP", "EDOM", "EILSEQ", "EOF", "ERANGE", "EXIT_FAILURE",
Packit Service 82fcde
  "EXIT_SUCCESS", "FILENAME_MAX", "FLT_DIG", "FLT_EPSILON",
Packit Service 82fcde
  "FLT_MANT_DIG", "FLT_MAX", "FLT_MAX_10_EXP", "FLT_MAX_EXP",
Packit Service 82fcde
  "FLT_MIN", "FLT_MIN_10_EXP", "FLT_MIN_EXP", "FLT_RADIX",
Packit Service 82fcde
  "FLT_ROUNDS", "FOPEN_MAX", "HUGE_VAL", "INT_MAX", "INT_MIN",
Packit Service 82fcde
  "LC_ALL", "LC_COLLATE", "LC_CTYPE", "LC_MONETARY", "LC_NUMERIC",
Packit Service 82fcde
  "LC_TIME", "LDBL_DIG", "LDBL_EPSILON", "LDBL_MANT_DIG", "LDBL_MAX",
Packit Service 82fcde
  "LDBL_MAX_10_EXP", "LDBL_MAX_EXP", "LDBL_MIN", "LDBL_MIN_10_EXP",
Packit Service 82fcde
  "LDBL_MIN_EXP", "LONG_MAX", "LONG_MIN", "L_tmpnam", "MB_CUR_MAX",
Packit Service 82fcde
  "MB_LEN_MAX", "NDEBUG", "NULL", "RAND_MAX", "SCHAR_MAX",
Packit Service 82fcde
  "SCHAR_MIN", "SEEK_CUR", "SEEK_END", "SEEK_SET", "SHRT_MAX",
Packit Service 82fcde
  "SHRT_MIN", "SIGABRT", "SIGFPE", "SIGILL", "SIGINT", "SIGSEGV",
Packit Service 82fcde
  "SIGTERM", "SIG_DFL", "SIG_ERR", "SIG_IGN", "TMP_MAX", "UCHAR_MAX",
Packit Service 82fcde
  "UINT_MAX", "ULONG_MAX", "USHRT_MAX", "WCHAR_MAX", "WCHAR_MIN",
Packit Service 82fcde
  "WEOF", "_IOFBF", "_IOLBF", "_IONBF", "abort", "abs", "acos",
Packit Service 82fcde
  "acosf", "acosl", "and", "and_eq", "asctime", "asin", "asinf",
Packit Service 82fcde
  "asinl", "assert", "atan", "atan2", "atan2f", "atan2l", "atanf",
Packit Service 82fcde
  "atanl", "atexit", "atof", "atoi", "atol", "bitand", "bitor",
Packit Service 82fcde
  "bsearch", "btowc", "calloc", "ceil", "ceilf", "ceill", "clearerr",
Packit Service 82fcde
  "clock", "clock_t", "compl", "cos", "cosf", "cosh", "coshf",
Packit Service 82fcde
  "coshl", "cosl", "ctime", "difftime", "div", "div_t", "errno",
Packit Service 82fcde
  "exit", "exp", "expf", "expl", "fabs", "fabsf", "fabsl", "fclose",
Packit Service 82fcde
  "feof", "ferror", "fflush", "fgetc", "fgetpos", "fgets", "fgetwc",
Packit Service 82fcde
  "fgetws", "floor", "floorf", "floorl", "fmod", "fmodf", "fmodl",
Packit Service 82fcde
  "fopen", "fprintf", "fputc", "fputs", "fputwc", "fputws", "fread",
Packit Service 82fcde
  "free", "freopen", "frexp", "frexpf", "frexpl", "fscanf", "fseek",
Packit Service 82fcde
  "fsetpos", "ftell", "fwide", "fwprintf", "fwrite", "fwscanf",
Packit Service 82fcde
  "getc", "getchar", "getenv", "gets", "getwc", "getwchar", "gmtime",
Packit Service 82fcde
  "isalnum", "isalpha", "iscntrl", "isdigit", "isgraph", "islower",
Packit Service 82fcde
  "isprint", "ispunct", "isspace", "isupper", "iswalnum", "iswalpha",
Packit Service 82fcde
  "iswcntrl", "iswctype", "iswdigit", "iswgraph", "iswlower",
Packit Service 82fcde
  "iswprint", "iswpunct", "iswspace", "iswupper", "iswxdigit",
Packit Service 82fcde
  "isxdigit", "labs", "ldexp", "ldexpf", "ldexpl", "ldiv", "ldiv_t",
Packit Service 82fcde
  "localeconv", "localtime", "log", "log10", "log10f", "log10l",
Packit Service 82fcde
  "logf", "logl", "longjmp", "malloc", "mblen", "mbrlen", "mbrtowc",
Packit Service 82fcde
  "mbsinit", "mbsrtowcs", "mbstate_t", "mbstowcs", "mbtowc", "memchr",
Packit Service 82fcde
  "memcmp", "memcpy", "memmove", "memset", "mktime", "modf", "modff",
Packit Service 82fcde
  "modfl", "not", "not_eq", "offsetof", "or", "or_eq", "perror",
Packit Service 82fcde
  "pow", "powf", "powl", "printf", "ptrdiff_t", "putc", "putchar",
Packit Service 82fcde
  "puts", "putwc", "putwchar", "qsort", "raise", "rand", "realloc",
Packit Service 82fcde
  "remove", "rename", "rewind", "scanf", "setbuf", "setjmp",
Packit Service 82fcde
  "setlocale", "setvbuf", "sig_atomic_t", "signal", "sin", "sinf",
Packit Service 82fcde
  "sinh", "sinhf", "sinhl", "sinl", "size_t", "sprintf", "sqrt",
Packit Service 82fcde
  "sqrtf", "sqrtl", "srand", "sscanf", "stderr", "stdin", "stdout",
Packit Service 82fcde
  "strcat", "strchr", "strcmp", "strcoll", "strcpy", "strcspn",
Packit Service 82fcde
  "strerror", "strftime", "strlen", "strncat", "strncmp", "strncpy",
Packit Service 82fcde
  "strpbrk", "strrchr", "strspn", "strstr", "strtod", "strtok",
Packit Service 82fcde
  "strtol", "strtoul", "strxfrm", "swprintf", "swscanf", "system",
Packit Service 82fcde
  "tan", "tanf", "tanh", "tanhf", "tanhl", "tanl", "time", "time_t",
Packit Service 82fcde
  "tmpfile", "tmpnam", "tolower", "toupper", "towctrans", "towlower",
Packit Service 82fcde
  "towupper", "ungetc", "ungetwc", "va_arg", "va_copy", "va_end", "va_start",
Packit Service 82fcde
  "vfprintf", "vfwprintf", "vprintf", "vsprintf", "vswprintf",
Packit Service 82fcde
  "vwprintf", "wchar_t", "wcrtomb", "wcscat", "wcschr", "wcscmp",
Packit Service 82fcde
  "wcscoll", "wcscpy", "wcscspn", "wcsftime", "wcslen", "wcsncat",
Packit Service 82fcde
  "wcsncmp", "wcsncpy", "wcspbrk", "wcsrchr", "wcsrtombs", "wcsspn",
Packit Service 82fcde
  "wcsstr", "wcstod", "wcstok", "wcstol", "wcstombs", "wcstoul",
Packit Service 82fcde
  "wcsxfrm", "wctob", "wctomb", "wctrans", "wctrans_t", "wctype",
Packit Service 82fcde
  "wctype_t", "wint_t", "wmemchr", "wmemcmp", "wmemcpy", "wmemmove",
Packit Service 82fcde
  "wmemset", "wprintf", "wscanf", "xor", "xor_eq"
Packit Service 82fcde
};
Packit Service 82fcde
Packit Service 82fcde
#define NUMBER_OF_HEADERS              (sizeof header / sizeof *header)
Packit Service 82fcde
#define NUMBER_OF_PREFIXES             (sizeof prefix / sizeof *prefix)
Packit Service 82fcde
#define NUMBER_OF_SUFFIXES             (sizeof suffix / sizeof *suffix)
Packit Service 82fcde
#define NUMBER_OF_MACROS               (sizeof macros / sizeof *macros)
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Format string to build command to invoke compiler.  */
Packit Service 82fcde
static const char fmt[] = "\
Packit Service 82fcde
echo \"#include <%s>\" |\
Packit Service 82fcde
%s -E -dM -ansi -pedantic %s -D_LIBC -D_ISOMAC \
Packit Service 82fcde
-DIN_MODULE=MODULE_extramodules -I. \
Packit Service 82fcde
-isystem `%s --print-prog-name=include` - 2> /dev/null > %s";
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* The compiler we use (given on the command line).  */
Packit Service 82fcde
char *CC;
Packit Service 82fcde
/* The -I parameters for CC to find all headers.  */
Packit Service 82fcde
char *INC;
Packit Service 82fcde
Packit Service 82fcde
static char *xstrndup (const char *, size_t);
Packit Service 82fcde
static const char **get_null_defines (void);
Packit Service 82fcde
static int check_header (const char *, const char **);
Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
main (int argc, char *argv[])
Packit Service 82fcde
{
Packit Service 82fcde
  int h;
Packit Service 82fcde
  int result = 0;
Packit Service 82fcde
  const char **ignore_list;
Packit Service 82fcde
Packit Service 82fcde
  CC = argc > 1 ? argv[1] : "gcc";
Packit Service 82fcde
  INC = argc > 2 ? argv[2] : "";
Packit Service 82fcde
Packit Service 82fcde
  if (system (NULL) == 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      puts ("Sorry, no command processor.");
Packit Service 82fcde
      return EXIT_FAILURE;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  /* First get list of symbols which are defined by the compiler.  */
Packit Service 82fcde
  ignore_list = get_null_defines ();
Packit Service 82fcde
Packit Service 82fcde
  fputs ("Tested files:\n", stdout);
Packit Service 82fcde
Packit Service 82fcde
  for (h = 0; h < NUMBER_OF_HEADERS; ++h)
Packit Service 82fcde
    {
Packit Service 82fcde
      char file_name[HEADER_MAX];
Packit Service 82fcde
      sprintf (file_name, "%s.h", header[h]);
Packit Service 82fcde
      result |= check_header (file_name, ignore_list);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  remove (macrofile);
Packit Service 82fcde
Packit Service 82fcde
  /* The test suite should return errors but for now this is not
Packit Service 82fcde
     practical.  Give a warning and ask the user to correct the bugs.  */
Packit Service 82fcde
  return result;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
static char *
Packit Service 82fcde
xstrndup (const char *s, size_t n)
Packit Service 82fcde
{
Packit Service 82fcde
  size_t len = n;
Packit Service 82fcde
  char *new = malloc (len + 1);
Packit Service 82fcde
Packit Service 82fcde
  if (new == NULL)
Packit Service 82fcde
    return NULL;
Packit Service 82fcde
Packit Service 82fcde
  new[len] = '\0';
Packit Service 82fcde
  return memcpy (new, s, len);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
static const char **
Packit Service 82fcde
get_null_defines (void)
Packit Service 82fcde
{
Packit Service 82fcde
  char line[BUFSIZ], *command;
Packit Service 82fcde
  char **result = NULL;
Packit Service 82fcde
  size_t result_len = 0;
Packit Service 82fcde
  size_t result_max = 0;
Packit Service 82fcde
  FILE *input;
Packit Service 82fcde
  int first = 1;
Packit Service 82fcde
Packit Service 82fcde
  int fd = mkstemp (macrofile);
Packit Service 82fcde
  if (fd == -1)
Packit Service 82fcde
    {
Packit Service 82fcde
      printf ("mkstemp failed: %m\n");
Packit Service 82fcde
      exit (1);
Packit Service 82fcde
    }
Packit Service 82fcde
  close (fd);
Packit Service 82fcde
Packit Service 82fcde
  command = malloc (sizeof fmt + sizeof "/dev/null" + 2 * strlen (CC)
Packit Service 82fcde
		    + strlen (INC) + strlen (macrofile));
Packit Service 82fcde
Packit Service 82fcde
  if (command == NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      puts ("No more memory.");
Packit Service 82fcde
      exit (1);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  sprintf (command, fmt, "/dev/null", CC, INC, CC, macrofile);
Packit Service 82fcde
Packit Service 82fcde
  if (system (command))
Packit Service 82fcde
    {
Packit Service 82fcde
      puts ("system() returned nonzero");
Packit Service 82fcde
      free (command);
Packit Service 82fcde
      return NULL;
Packit Service 82fcde
    }
Packit Service 82fcde
  free (command);
Packit Service 82fcde
  input = fopen (macrofile, "r");
Packit Service 82fcde
Packit Service 82fcde
  if (input == NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      printf ("Could not read %s: ", macrofile);
Packit Service 82fcde
      perror (NULL);
Packit Service 82fcde
      return NULL;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  while (fgets (line, sizeof line, input) != NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      int i, okay = 0;
Packit Service 82fcde
      size_t endmac;
Packit Service 82fcde
      char *start, *end;
Packit Service 82fcde
      if (strlen (line) < 9 || line[7] != ' ')
Packit Service 82fcde
	{ /* "#define A" */
Packit Service 82fcde
	  printf ("Malformed input, expected '#define MACRO'\ngot '%s'\n",
Packit Service 82fcde
		  line);
Packit Service 82fcde
	  continue;
Packit Service 82fcde
	}
Packit Service 82fcde
      if (line[8] == '_')
Packit Service 82fcde
	/* It's a safe identifier.  */
Packit Service 82fcde
	continue;
Packit Service 82fcde
      if (result_len == result_max)
Packit Service 82fcde
	{
Packit Service 82fcde
	  result_max += 10;
Packit Service 82fcde
	  result = realloc (result, result_max * sizeof (char **));
Packit Service 82fcde
	  if (result == NULL)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      puts ("No more memory.");
Packit Service 82fcde
	      exit (1);
Packit Service 82fcde
	    }
Packit Service 82fcde
	}
Packit Service 82fcde
      start = &line[8];
Packit Service 82fcde
      for (end = start + 1; !isspace (*end) && *end != '\0'; ++end)
Packit Service 82fcde
	;
Packit Service 82fcde
      result[result_len] = xstrndup (start, end - start);
Packit Service 82fcde
Packit Service 82fcde
      if (strcmp (result[result_len], "IN_MODULE") != 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  if (first)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      fputs ("The following identifiers will be ignored since the compiler defines them\nby default:\n", stdout);
Packit Service 82fcde
	      first = 0;
Packit Service 82fcde
	    }
Packit Service 82fcde
	  puts (result[result_len]);
Packit Service 82fcde
	}
Packit Service 82fcde
      ++result_len;
Packit Service 82fcde
    }
Packit Service 82fcde
  if (result_len == result_max)
Packit Service 82fcde
    {
Packit Service 82fcde
      result_max += 1;
Packit Service 82fcde
      result = realloc (result, result_max * sizeof (char **));
Packit Service 82fcde
      if (result == NULL)
Packit Service 82fcde
	{
Packit Service 82fcde
	  puts ("No more memory.");
Packit Service 82fcde
	  exit (1);
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
  result[result_len] = NULL;
Packit Service 82fcde
  fclose (input);
Packit Service 82fcde
Packit Service 82fcde
  return (const char **) result;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
static int
Packit Service 82fcde
check_header (const char *file_name, const char **except)
Packit Service 82fcde
{
Packit Service 82fcde
  char line[BUFSIZ], *command;
Packit Service 82fcde
  FILE *input;
Packit Service 82fcde
  int result = 0;
Packit Service 82fcde
Packit Service 82fcde
  command = malloc (sizeof fmt + strlen (file_name) + 2 * strlen (CC)
Packit Service 82fcde
		    + strlen (INC) + strlen (macrofile));
Packit Service 82fcde
Packit Service 82fcde
  if (command == NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      puts ("No more memory.");
Packit Service 82fcde
      exit (1);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  puts (file_name);
Packit Service 82fcde
  sprintf (command, fmt, file_name, CC, INC, CC, macrofile);
Packit Service 82fcde
Packit Service 82fcde
  if (system (command))
Packit Service 82fcde
    {
Packit Service 82fcde
      puts ("system() returned nonzero");
Packit Service 82fcde
      result = 1;
Packit Service 82fcde
    }
Packit Service 82fcde
  free (command);
Packit Service 82fcde
  input = fopen (macrofile, "r");
Packit Service 82fcde
Packit Service 82fcde
  if (input == NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      printf ("Could not read %s: ", macrofile);
Packit Service 82fcde
      perror (NULL);
Packit Service 82fcde
      return 1;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  while (fgets (line, sizeof line, input) != NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      int i, okay = 0;
Packit Service 82fcde
      size_t endmac;
Packit Service 82fcde
      const char **cpp;
Packit Service 82fcde
      if (strlen (line) < 9 || line[7] != ' ')
Packit Service 82fcde
	{ /* "#define A" */
Packit Service 82fcde
	  printf ("Malformed input, expected '#define MACRO'\ngot '%s'\n",
Packit Service 82fcde
		  line);
Packit Service 82fcde
	  result = 1;
Packit Service 82fcde
	  continue;
Packit Service 82fcde
	}
Packit Service 82fcde
      for (i = 0; i < NUMBER_OF_PREFIXES; ++i)
Packit Service 82fcde
	{
Packit Service 82fcde
	  if (!strncmp (line+8, prefix[i], strlen (prefix[i]))) {
Packit Service 82fcde
	    ++okay;
Packit Service 82fcde
	    break;
Packit Service 82fcde
	  }
Packit Service 82fcde
	}
Packit Service 82fcde
      if (okay)
Packit Service 82fcde
	continue;
Packit Service 82fcde
      for (i = 0; i < NUMBER_OF_MACROS; ++i)
Packit Service 82fcde
	{
Packit Service 82fcde
	  if (!strncmp (line + 8, macros[i], strlen (macros[i])))
Packit Service 82fcde
	    {
Packit Service 82fcde
	      ++okay;
Packit Service 82fcde
	      break;
Packit Service 82fcde
	    }
Packit Service 82fcde
	}
Packit Service 82fcde
      if (okay)
Packit Service 82fcde
	continue;
Packit Service 82fcde
      /* Find next char after the macro identifier; this can be either
Packit Service 82fcde
	 a space or an open parenthesis.  */
Packit Service 82fcde
      endmac = strcspn (line + 8, " (");
Packit Service 82fcde
      if (line[8+endmac] == '\0')
Packit Service 82fcde
	{
Packit Service 82fcde
	  printf ("malformed input, expected '#define MACRO VALUE'\n"
Packit Service 82fcde
		  "got '%s'\n", line);
Packit Service 82fcde
	  result = 1;
Packit Service 82fcde
	  continue;
Packit Service 82fcde
	}
Packit Service 82fcde
      for (i = 0; i < NUMBER_OF_SUFFIXES; ++i)
Packit Service 82fcde
	{
Packit Service 82fcde
	  size_t len = strlen (suffix[i]);
Packit Service 82fcde
	  if (!strncmp (line + 8 + endmac - len, suffix[i], len))
Packit Service 82fcde
	    {
Packit Service 82fcde
	      ++okay;
Packit Service 82fcde
	      break;
Packit Service 82fcde
	    }
Packit Service 82fcde
	}
Packit Service 82fcde
      if (okay)
Packit Service 82fcde
	continue;
Packit Service 82fcde
      if (except != NULL)
Packit Service 82fcde
	for (cpp = except; *cpp != NULL; ++cpp)
Packit Service 82fcde
	  {
Packit Service 82fcde
	    size_t len = strlen (*cpp);
Packit Service 82fcde
	    if (!strncmp (line + 8, *cpp, len) && isspace (line[8 + len]))
Packit Service 82fcde
	      {
Packit Service 82fcde
		++okay;
Packit Service 82fcde
		break;
Packit Service 82fcde
	      }
Packit Service 82fcde
	  }
Packit Service 82fcde
      if (!okay)
Packit Service 82fcde
	{
Packit Service 82fcde
	  fputs (line, stdout);
Packit Service 82fcde
	  result = 2;
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
  fclose (input);
Packit Service 82fcde
Packit Service 82fcde
  return result;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* EOF */