OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [fixincludes/] [fixfixes.c] - Diff between revs 154 and 816

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 154 Rev 816
 
 
/*
/*
 
 
   Test to see if a particular fix should be applied to a header file.
   Test to see if a particular fix should be applied to a header file.
 
 
   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004
   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004
   Free Software Foundation, Inc.
   Free Software Foundation, Inc.
 
 
= = = = = = = = = = = = = = = = = = = = = = = = =
= = = = = = = = = = = = = = = = = = = = = = = = =
 
 
NOTE TO DEVELOPERS
NOTE TO DEVELOPERS
 
 
The routines you write here must work closely with fixincl.c.
The routines you write here must work closely with fixincl.c.
 
 
Here are the rules:
Here are the rules:
 
 
1.  Every test procedure name must be suffixed with "_fix".
1.  Every test procedure name must be suffixed with "_fix".
    These routines will be referenced from inclhack.def, sans the suffix.
    These routines will be referenced from inclhack.def, sans the suffix.
 
 
2.  Use the "FIX_PROC_HEAD()" macro _with_ the "_fix" suffix
2.  Use the "FIX_PROC_HEAD()" macro _with_ the "_fix" suffix
    (I cannot use the ## magic from ANSI C) for defining your entry point.
    (I cannot use the ## magic from ANSI C) for defining your entry point.
 
 
3.  Put your test name into the FIXUP_TABLE.
3.  Put your test name into the FIXUP_TABLE.
 
 
4.  Do not read anything from stdin.  It is closed.
4.  Do not read anything from stdin.  It is closed.
 
 
5.  Write to stderr only in the event of a reportable error
5.  Write to stderr only in the event of a reportable error
    In such an event, call "exit (EXIT_FAILURE)".
    In such an event, call "exit (EXIT_FAILURE)".
 
 
6.  You have access to the fixDescList entry for the fix in question.
6.  You have access to the fixDescList entry for the fix in question.
    This may be useful, for example, if there are interesting strings
    This may be useful, for example, if there are interesting strings
    or pre-compiled regular expressions stored there.
    or pre-compiled regular expressions stored there.
 
 
= = = = = = = = = = = = = = = = = = = = = = = = =
= = = = = = = = = = = = = = = = = = = = = = = = =
 
 
This file is part of GCC.
This file is part of GCC.
 
 
GCC is free software; you can redistribute it and/or modify
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
the Free Software Foundation; either version 2, or (at your option)
any later version.
any later version.
 
 
GCC is distributed in the hope that it will be useful,
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
GNU General Public License for more details.
 
 
You should have received a copy of the GNU General Public License
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING.  If not, write to
along with GCC; see the file COPYING.  If not, write to
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.  */
Boston, MA 02110-1301, USA.  */
 
 
#include "fixlib.h"
#include "fixlib.h"
#define    GTYPE_SE_CT 1
#define    GTYPE_SE_CT 1
 
 
#ifdef SEPARATE_FIX_PROC
#ifdef SEPARATE_FIX_PROC
#include "fixincl.x"
#include "fixincl.x"
#endif
#endif
 
 
tSCC zNeedsArg[] = "fixincl error:  `%s' needs %s argument (c_fix_arg[%d])\n";
tSCC zNeedsArg[] = "fixincl error:  `%s' needs %s argument (c_fix_arg[%d])\n";
 
 
typedef void t_fix_proc (const char *, const char *, tFixDesc *) ;
typedef void t_fix_proc (const char *, const char *, tFixDesc *) ;
typedef struct {
typedef struct {
    const char*  fix_name;
    const char*  fix_name;
    t_fix_proc*  fix_proc;
    t_fix_proc*  fix_proc;
} fix_entry_t;
} fix_entry_t;
 
 
#define FIXUP_TABLE \
#define FIXUP_TABLE \
  _FT_( "char_macro_def",   char_macro_def_fix ) \
  _FT_( "char_macro_def",   char_macro_def_fix ) \
  _FT_( "char_macro_use",   char_macro_use_fix ) \
  _FT_( "char_macro_use",   char_macro_use_fix ) \
  _FT_( "format",           format_fix )         \
  _FT_( "format",           format_fix )         \
  _FT_( "machine_name",     machine_name_fix )   \
  _FT_( "machine_name",     machine_name_fix )   \
  _FT_( "wrap",             wrap_fix )           \
  _FT_( "wrap",             wrap_fix )           \
  _FT_( "gnu_type",         gnu_type_fix )
  _FT_( "gnu_type",         gnu_type_fix )
 
 
 
 
#define FIX_PROC_HEAD( fix )    \
#define FIX_PROC_HEAD( fix )    \
static void fix (const char* filname ATTRIBUTE_UNUSED , \
static void fix (const char* filname ATTRIBUTE_UNUSED , \
                 const char* text ATTRIBUTE_UNUSED , \
                 const char* text ATTRIBUTE_UNUSED , \
                 tFixDesc* p_fixd ATTRIBUTE_UNUSED )
                 tFixDesc* p_fixd ATTRIBUTE_UNUSED )
 
 
#ifdef NEED_PRINT_QUOTE
#ifdef NEED_PRINT_QUOTE
/*
/*
 *  Skip over a quoted string.  Single quote strings may
 *  Skip over a quoted string.  Single quote strings may
 *  contain multiple characters if the first character is
 *  contain multiple characters if the first character is
 *  a backslash.  Especially a backslash followed by octal digits.
 *  a backslash.  Especially a backslash followed by octal digits.
 *  We are not doing a correctness syntax check here.
 *  We are not doing a correctness syntax check here.
 */
 */
static char*
static char*
print_quote(char q, char* text )
print_quote(char q, char* text )
{
{
  fputc( q, stdout );
  fputc( q, stdout );
 
 
  for (;;)
  for (;;)
    {
    {
      char ch = *(text++);
      char ch = *(text++);
      fputc( ch, stdout );
      fputc( ch, stdout );
 
 
      switch (ch)
      switch (ch)
        {
        {
        case '\\':
        case '\\':
          if (*text == NUL)
          if (*text == NUL)
            goto quote_done;
            goto quote_done;
 
 
          fputc( *(text++), stdout );
          fputc( *(text++), stdout );
          break;
          break;
 
 
        case '"':
        case '"':
        case '\'':
        case '\'':
          if (ch != q)
          if (ch != q)
            break;
            break;
          /*FALLTHROUGH*/
          /*FALLTHROUGH*/
 
 
        case '\n':
        case '\n':
        case NUL:
        case NUL:
          goto quote_done;
          goto quote_done;
        }
        }
    } quote_done:;
    } quote_done:;
 
 
  return text;
  return text;
}
}
#endif /* NEED_PRINT_QUOTE */
#endif /* NEED_PRINT_QUOTE */
 
 
 
 
/*
/*
 *  Emit the GNU standard type wrapped up in such a way that
 *  Emit the GNU standard type wrapped up in such a way that
 *  this thing can be encountered countless times during a compile
 *  this thing can be encountered countless times during a compile
 *  and not cause even a warning.
 *  and not cause even a warning.
 */
 */
static const char*
static const char*
emit_gnu_type (const char* text, regmatch_t* rm )
emit_gnu_type (const char* text, regmatch_t* rm )
{
{
  char z_TYPE[ 64 ];
  char z_TYPE[ 64 ];
  char z_type[ 64 ];
  char z_type[ 64 ];
 
 
  fwrite (text, rm[0].rm_so, 1, stdout);
  fwrite (text, rm[0].rm_so, 1, stdout);
 
 
  {
  {
    const char* ps = text   + rm[1].rm_so;
    const char* ps = text   + rm[1].rm_so;
    const char* pe = text   + rm[1].rm_eo;
    const char* pe = text   + rm[1].rm_eo;
    char* pd = z_type;
    char* pd = z_type;
    char* pD = z_TYPE;
    char* pD = z_TYPE;
 
 
    while (ps < pe)
    while (ps < pe)
      *(pD++) = TOUPPER( *(pd++) = *(ps++) );
      *(pD++) = TOUPPER( *(pd++) = *(ps++) );
 
 
    *pD = *pd = NUL;
    *pD = *pd = NUL;
  }
  }
 
 
  /*
  /*
   *  Now print out the reformed typedef,
   *  Now print out the reformed typedef,
   *  with a C++ guard for WCHAR
   *  with a C++ guard for WCHAR
   */
   */
  {
  {
    tSCC z_fmt[] = "\
    tSCC z_fmt[] = "\
#if !defined(_GCC_%s_T)%s\n\
#if !defined(_GCC_%s_T)%s\n\
#define _GCC_%s_T\n\
#define _GCC_%s_T\n\
typedef __%s_TYPE__ %s_t;\n\
typedef __%s_TYPE__ %s_t;\n\
#endif\n";
#endif\n";
 
 
    const char *const pz_guard = (strcmp (z_type, "wchar") == 0)
    const char *const pz_guard = (strcmp (z_type, "wchar") == 0)
                           ? " && ! defined(__cplusplus)" : "";
                           ? " && ! defined(__cplusplus)" : "";
 
 
    printf (z_fmt, z_TYPE, pz_guard, z_TYPE, z_TYPE, z_type);
    printf (z_fmt, z_TYPE, pz_guard, z_TYPE, z_TYPE, z_type);
  }
  }
 
 
  return text += rm[0].rm_eo;
  return text += rm[0].rm_eo;
}
}
 
 
 
 
/*
/*
 *  Copy the `format' string to std out, replacing `%n' expressions
 *  Copy the `format' string to std out, replacing `%n' expressions
 *  with the matched text from a regular expression evaluation.
 *  with the matched text from a regular expression evaluation.
 *  Doubled '%' characters will be replaced with a single copy.
 *  Doubled '%' characters will be replaced with a single copy.
 *  '%' characters in other contexts and all other characters are
 *  '%' characters in other contexts and all other characters are
 *  copied out verbatim.
 *  copied out verbatim.
 */
 */
static void
static void
format_write (tCC* format, tCC* text, regmatch_t av[] )
format_write (tCC* format, tCC* text, regmatch_t av[] )
{
{
  int c;
  int c;
 
 
  while ((c = (unsigned)*(format++)) != NUL) {
  while ((c = (unsigned)*(format++)) != NUL) {
 
 
    if (c != '%')
    if (c != '%')
      {
      {
        putchar(c);
        putchar(c);
        continue;
        continue;
      }
      }
 
 
    c = (unsigned)*(format++);
    c = (unsigned)*(format++);
 
 
    /*
    /*
     *  IF the character following a '%' is not a digit,
     *  IF the character following a '%' is not a digit,
     *  THEN we will always emit a '%' and we may or may
     *  THEN we will always emit a '%' and we may or may
     *  not emit the following character.  We will end on
     *  not emit the following character.  We will end on
     *  a NUL and we will emit only one of a pair of '%'.
     *  a NUL and we will emit only one of a pair of '%'.
     */
     */
    if (! ISDIGIT ( c ))
    if (! ISDIGIT ( c ))
      {
      {
        putchar( '%' );
        putchar( '%' );
        switch (c) {
        switch (c) {
        case NUL:
        case NUL:
          return;
          return;
        case '%':
        case '%':
          break;
          break;
        default:
        default:
          putchar(c);
          putchar(c);
        }
        }
      }
      }
 
 
    /*
    /*
     *  Emit the matched subexpression numbered 'c'.
     *  Emit the matched subexpression numbered 'c'.
     *  IF, of course, there was such a match...
     *  IF, of course, there was such a match...
     */
     */
    else {
    else {
      regmatch_t*  pRM = av + (c - (unsigned)'0');
      regmatch_t*  pRM = av + (c - (unsigned)'0');
      size_t len;
      size_t len;
 
 
      if (pRM->rm_so < 0)
      if (pRM->rm_so < 0)
        continue;
        continue;
 
 
      len = pRM->rm_eo - pRM->rm_so;
      len = pRM->rm_eo - pRM->rm_so;
      if (len > 0)
      if (len > 0)
        fwrite(text + pRM->rm_so, len, 1, stdout);
        fwrite(text + pRM->rm_so, len, 1, stdout);
    }
    }
  }
  }
}
}
 
 
 
 
/*
/*
 *  Search for multiple copies of a regular expression.  Each block
 *  Search for multiple copies of a regular expression.  Each block
 *  of matched text is replaced with the format string, as described
 *  of matched text is replaced with the format string, as described
 *  above in `format_write'.
 *  above in `format_write'.
 */
 */
FIX_PROC_HEAD( format_fix )
FIX_PROC_HEAD( format_fix )
{
{
  tCC*  pz_pat = p_fixd->patch_args[2];
  tCC*  pz_pat = p_fixd->patch_args[2];
  tCC*  pz_fmt = p_fixd->patch_args[1];
  tCC*  pz_fmt = p_fixd->patch_args[1];
  regex_t re;
  regex_t re;
  regmatch_t rm[10];
  regmatch_t rm[10];
  IGNORE_ARG(filname);
  IGNORE_ARG(filname);
 
 
  /*
  /*
   *  We must have a format
   *  We must have a format
   */
   */
  if (pz_fmt == (tCC*)NULL)
  if (pz_fmt == (tCC*)NULL)
    {
    {
      fprintf( stderr, zNeedsArg, p_fixd->fix_name, "replacement format", 0 );
      fprintf( stderr, zNeedsArg, p_fixd->fix_name, "replacement format", 0 );
      exit (EXIT_BROKEN);
      exit (EXIT_BROKEN);
    }
    }
 
 
  /*
  /*
   *  IF we don't have a search text, then go find the first
   *  IF we don't have a search text, then go find the first
   *  regular expression among the tests.
   *  regular expression among the tests.
   */
   */
  if (pz_pat == (tCC*)NULL)
  if (pz_pat == (tCC*)NULL)
    {
    {
      tTestDesc* pTD = p_fixd->p_test_desc;
      tTestDesc* pTD = p_fixd->p_test_desc;
      int        ct  = p_fixd->test_ct;
      int        ct  = p_fixd->test_ct;
      for (;;)
      for (;;)
        {
        {
          if (ct-- <= 0)
          if (ct-- <= 0)
            {
            {
              fprintf( stderr, zNeedsArg, p_fixd->fix_name, "search text", 1 );
              fprintf( stderr, zNeedsArg, p_fixd->fix_name, "search text", 1 );
              exit (EXIT_BROKEN);
              exit (EXIT_BROKEN);
            }
            }
 
 
          if (pTD->type == TT_EGREP)
          if (pTD->type == TT_EGREP)
            {
            {
              pz_pat = pTD->pz_test_text;
              pz_pat = pTD->pz_test_text;
              break;
              break;
            }
            }
 
 
          pTD++;
          pTD++;
        }
        }
    }
    }
 
 
  /*
  /*
   *  Replace every copy of the text we find
   *  Replace every copy of the text we find
   */
   */
  compile_re (pz_pat, &re, 1, "format search-text", "format_fix" );
  compile_re (pz_pat, &re, 1, "format search-text", "format_fix" );
  while (xregexec (&re, text, 10, rm, 0) == 0)
  while (xregexec (&re, text, 10, rm, 0) == 0)
    {
    {
      fwrite( text, rm[0].rm_so, 1, stdout );
      fwrite( text, rm[0].rm_so, 1, stdout );
      format_write( pz_fmt, text, rm );
      format_write( pz_fmt, text, rm );
      text += rm[0].rm_eo;
      text += rm[0].rm_eo;
    }
    }
 
 
  /*
  /*
   *  Dump out the rest of the file
   *  Dump out the rest of the file
   */
   */
  fputs (text, stdout);
  fputs (text, stdout);
}
}
 
 
 
 
/* Scan the input file for all occurrences of text like this:
/* Scan the input file for all occurrences of text like this:
 
 
   #define TIOCCONS _IO(T, 12)
   #define TIOCCONS _IO(T, 12)
 
 
   and change them to read like this:
   and change them to read like this:
 
 
   #define TIOCCONS _IO('T', 12)
   #define TIOCCONS _IO('T', 12)
 
 
   which is the required syntax per the C standard.  (The definition of
   which is the required syntax per the C standard.  (The definition of
   _IO also has to be tweaked - see below.)  'IO' is actually whatever you
   _IO also has to be tweaked - see below.)  'IO' is actually whatever you
   provide as the `c_fix_arg' argument.  */
   provide as the `c_fix_arg' argument.  */
 
 
FIX_PROC_HEAD( char_macro_use_fix )
FIX_PROC_HEAD( char_macro_use_fix )
{
{
  /* This regexp looks for a traditional-syntax #define (# in column 1)
  /* This regexp looks for a traditional-syntax #define (# in column 1)
     of an object-like macro.  */
     of an object-like macro.  */
  static const char pat[] =
  static const char pat[] =
    "^#[ \t]*define[ \t]+[_A-Za-z][_A-Za-z0-9]*[ \t]+";
    "^#[ \t]*define[ \t]+[_A-Za-z][_A-Za-z0-9]*[ \t]+";
  static regex_t re;
  static regex_t re;
 
 
  const char* str = p_fixd->patch_args[1];
  const char* str = p_fixd->patch_args[1];
  regmatch_t rm[1];
  regmatch_t rm[1];
  const char *p, *limit;
  const char *p, *limit;
  size_t len;
  size_t len;
  IGNORE_ARG(filname);
  IGNORE_ARG(filname);
 
 
  if (str == NULL)
  if (str == NULL)
    {
    {
      fprintf (stderr, zNeedsArg, p_fixd->fix_name, "ioctl type", 0);
      fprintf (stderr, zNeedsArg, p_fixd->fix_name, "ioctl type", 0);
      exit (EXIT_BROKEN);
      exit (EXIT_BROKEN);
    }
    }
 
 
  len = strlen (str);
  len = strlen (str);
  compile_re (pat, &re, 1, "macro pattern", "char_macro_use_fix");
  compile_re (pat, &re, 1, "macro pattern", "char_macro_use_fix");
 
 
  for (p = text;
  for (p = text;
       xregexec (&re, p, 1, rm, 0) == 0;
       xregexec (&re, p, 1, rm, 0) == 0;
       p = limit + 1)
       p = limit + 1)
    {
    {
      /* p + rm[0].rm_eo is the first character of the macro replacement.
      /* p + rm[0].rm_eo is the first character of the macro replacement.
         Find the end of the macro replacement, and the STR we were
         Find the end of the macro replacement, and the STR we were
         sent to look for within the replacement.  */
         sent to look for within the replacement.  */
      p += rm[0].rm_eo;
      p += rm[0].rm_eo;
      limit = p - 1;
      limit = p - 1;
      do
      do
        {
        {
          limit = strchr (limit + 1, '\n');
          limit = strchr (limit + 1, '\n');
          if (!limit)
          if (!limit)
            goto done;
            goto done;
        }
        }
      while (limit[-1] == '\\');
      while (limit[-1] == '\\');
 
 
      do
      do
        {
        {
          if (*p == str[0] && !strncmp (p+1, str+1, len-1))
          if (*p == str[0] && !strncmp (p+1, str+1, len-1))
            goto found;
            goto found;
        }
        }
      while (++p < limit - len);
      while (++p < limit - len);
      /* Hit end of line.  */
      /* Hit end of line.  */
      continue;
      continue;
 
 
    found:
    found:
      /* Found STR on this line.  If the macro needs fixing,
      /* Found STR on this line.  If the macro needs fixing,
         the next few chars will be whitespace or uppercase,
         the next few chars will be whitespace or uppercase,
         then an open paren, then a single letter.  */
         then an open paren, then a single letter.  */
      while ((ISSPACE (*p) || ISUPPER (*p)) && p < limit) p++;
      while ((ISSPACE (*p) || ISUPPER (*p)) && p < limit) p++;
      if (*p++ != '(')
      if (*p++ != '(')
        continue;
        continue;
      if (!ISALPHA (*p))
      if (!ISALPHA (*p))
        continue;
        continue;
      if (ISIDNUM (p[1]))
      if (ISIDNUM (p[1]))
        continue;
        continue;
 
 
      /* Splat all preceding text into the output buffer,
      /* Splat all preceding text into the output buffer,
         quote the character at p, then proceed.  */
         quote the character at p, then proceed.  */
      fwrite (text, 1, p - text, stdout);
      fwrite (text, 1, p - text, stdout);
      putchar ('\'');
      putchar ('\'');
      putchar (*p);
      putchar (*p);
      putchar ('\'');
      putchar ('\'');
      text = p + 1;
      text = p + 1;
    }
    }
 done:
 done:
  fputs (text, stdout);
  fputs (text, stdout);
}
}
 
 
 
 
/* Scan the input file for all occurrences of text like this:
/* Scan the input file for all occurrences of text like this:
 
 
   #define xxxIOxx(x, y) (....'x'<<16....)
   #define xxxIOxx(x, y) (....'x'<<16....)
 
 
   and change them to read like this:
   and change them to read like this:
 
 
   #define xxxIOxx(x, y) (....x<<16....)
   #define xxxIOxx(x, y) (....x<<16....)
 
 
   which is the required syntax per the C standard.  (The uses of _IO
   which is the required syntax per the C standard.  (The uses of _IO
   also has to be tweaked - see above.)  'IO' is actually whatever
   also has to be tweaked - see above.)  'IO' is actually whatever
   you provide as the `c_fix_arg' argument.  */
   you provide as the `c_fix_arg' argument.  */
FIX_PROC_HEAD( char_macro_def_fix )
FIX_PROC_HEAD( char_macro_def_fix )
{
{
  /* This regexp looks for any traditional-syntax #define (# in column 1).  */
  /* This regexp looks for any traditional-syntax #define (# in column 1).  */
  static const char pat[] =
  static const char pat[] =
    "^#[ \t]*define[ \t]+";
    "^#[ \t]*define[ \t]+";
  static regex_t re;
  static regex_t re;
 
 
  const char* str = p_fixd->patch_args[1];
  const char* str = p_fixd->patch_args[1];
  regmatch_t rm[1];
  regmatch_t rm[1];
  const char *p, *limit;
  const char *p, *limit;
  char arg;
  char arg;
  size_t len;
  size_t len;
  IGNORE_ARG(filname);
  IGNORE_ARG(filname);
 
 
  if (str == NULL)
  if (str == NULL)
    {
    {
      fprintf (stderr, zNeedsArg, p_fixd->fix_name, "ioctl type", 0);
      fprintf (stderr, zNeedsArg, p_fixd->fix_name, "ioctl type", 0);
      exit (EXIT_BROKEN);
      exit (EXIT_BROKEN);
    }
    }
 
 
  len = strlen (str);
  len = strlen (str);
  compile_re (pat, &re, 1, "macro pattern", "fix_char_macro_defines");
  compile_re (pat, &re, 1, "macro pattern", "fix_char_macro_defines");
 
 
  for (p = text;
  for (p = text;
       xregexec (&re, p, 1, rm, 0) == 0;
       xregexec (&re, p, 1, rm, 0) == 0;
       p = limit + 1)
       p = limit + 1)
    {
    {
      /* p + rm[0].rm_eo is the first character of the macro name.
      /* p + rm[0].rm_eo is the first character of the macro name.
         Find the end of the macro replacement, and the STR we were
         Find the end of the macro replacement, and the STR we were
         sent to look for within the name.  */
         sent to look for within the name.  */
      p += rm[0].rm_eo;
      p += rm[0].rm_eo;
      limit = p - 1;
      limit = p - 1;
      do
      do
        {
        {
          limit = strchr (limit + 1, '\n');
          limit = strchr (limit + 1, '\n');
          if (!limit)
          if (!limit)
            goto done;
            goto done;
        }
        }
      while (limit[-1] == '\\');
      while (limit[-1] == '\\');
 
 
      do
      do
        {
        {
          if (*p == str[0] && !strncmp (p+1, str+1, len-1))
          if (*p == str[0] && !strncmp (p+1, str+1, len-1))
            goto found;
            goto found;
          p++;
          p++;
        }
        }
      while (ISIDNUM (*p));
      while (ISIDNUM (*p));
      /* Hit end of macro name without finding the string.  */
      /* Hit end of macro name without finding the string.  */
      continue;
      continue;
 
 
    found:
    found:
      /* Found STR in this macro name.  If the macro needs fixing,
      /* Found STR in this macro name.  If the macro needs fixing,
         there may be a few uppercase letters, then there will be an
         there may be a few uppercase letters, then there will be an
         open paren with _no_ intervening whitespace, and then a
         open paren with _no_ intervening whitespace, and then a
         single letter.  */
         single letter.  */
      while (ISUPPER (*p) && p < limit) p++;
      while (ISUPPER (*p) && p < limit) p++;
      if (*p++ != '(')
      if (*p++ != '(')
        continue;
        continue;
      if (!ISALPHA (*p))
      if (!ISALPHA (*p))
        continue;
        continue;
      if (ISIDNUM (p[1]))
      if (ISIDNUM (p[1]))
        continue;
        continue;
 
 
      /* The character at P is the one to look for in the following
      /* The character at P is the one to look for in the following
         text.  */
         text.  */
      arg = *p;
      arg = *p;
      p += 2;
      p += 2;
 
 
      while (p < limit)
      while (p < limit)
        {
        {
          if (p[-1] == '\'' && p[0] == arg && p[1] == '\'')
          if (p[-1] == '\'' && p[0] == arg && p[1] == '\'')
            {
            {
              /* Remove the quotes from this use of ARG.  */
              /* Remove the quotes from this use of ARG.  */
              p--;
              p--;
              fwrite (text, 1, p - text, stdout);
              fwrite (text, 1, p - text, stdout);
              putchar (arg);
              putchar (arg);
              p += 3;
              p += 3;
              text = p;
              text = p;
            }
            }
          else
          else
            p++;
            p++;
        }
        }
    }
    }
 done:
 done:
  fputs (text, stdout);
  fputs (text, stdout);
}
}
 
 
/* Fix for machine name #ifdefs that are not in the namespace reserved
/* Fix for machine name #ifdefs that are not in the namespace reserved
   by the C standard.  They won't be defined if compiling with -ansi,
   by the C standard.  They won't be defined if compiling with -ansi,
   and the headers will break.  We go to some trouble to only change
   and the headers will break.  We go to some trouble to only change
   #ifdefs where the macro is defined by GCC in non-ansi mode; this
   #ifdefs where the macro is defined by GCC in non-ansi mode; this
   minimizes the number of headers touched.  */
   minimizes the number of headers touched.  */
 
 
#define SCRATCHSZ 64   /* hopefully long enough */
#define SCRATCHSZ 64   /* hopefully long enough */
 
 
FIX_PROC_HEAD( machine_name_fix )
FIX_PROC_HEAD( machine_name_fix )
{
{
  regmatch_t match[2];
  regmatch_t match[2];
  const char *line, *base, *limit, *p, *q;
  const char *line, *base, *limit, *p, *q;
  regex_t *label_re, *name_re;
  regex_t *label_re, *name_re;
  char scratch[SCRATCHSZ];
  char scratch[SCRATCHSZ];
  size_t len;
  size_t len;
  IGNORE_ARG(filname);
  IGNORE_ARG(filname);
  IGNORE_ARG(p_fixd);
  IGNORE_ARG(p_fixd);
 
 
  if (!mn_get_regexps (&label_re, &name_re, "machine_name_fix"))
  if (!mn_get_regexps (&label_re, &name_re, "machine_name_fix"))
    {
    {
      fputs( "The target machine has no needed machine name fixes\n", stderr );
      fputs( "The target machine has no needed machine name fixes\n", stderr );
      goto done;
      goto done;
    }
    }
 
 
  scratch[0] = '_';
  scratch[0] = '_';
  scratch[1] = '_';
  scratch[1] = '_';
 
 
  for (base = text;
  for (base = text;
       xregexec (label_re, base, 2, match, 0) == 0;
       xregexec (label_re, base, 2, match, 0) == 0;
       base = limit)
       base = limit)
    {
    {
      base += match[0].rm_eo;
      base += match[0].rm_eo;
      /* We're looking at an #if or #ifdef.  Scan forward for the
      /* We're looking at an #if or #ifdef.  Scan forward for the
         next non-escaped newline.  */
         next non-escaped newline.  */
      line = limit = base;
      line = limit = base;
      do
      do
        {
        {
          limit++;
          limit++;
          limit = strchr (limit, '\n');
          limit = strchr (limit, '\n');
          if (!limit)
          if (!limit)
            goto done;
            goto done;
        }
        }
      while (limit[-1] == '\\');
      while (limit[-1] == '\\');
 
 
      /* If the 'name_pat' matches in between base and limit, we have
      /* If the 'name_pat' matches in between base and limit, we have
         a bogon.  It is not worth the hassle of excluding comments
         a bogon.  It is not worth the hassle of excluding comments
         because comments on #if/#ifdef lines are rare, and strings on
         because comments on #if/#ifdef lines are rare, and strings on
         such lines are illegal.
         such lines are illegal.
 
 
         REG_NOTBOL means 'base' is not at the beginning of a line, which
         REG_NOTBOL means 'base' is not at the beginning of a line, which
         shouldn't matter since the name_re has no ^ anchor, but let's
         shouldn't matter since the name_re has no ^ anchor, but let's
         be accurate anyway.  */
         be accurate anyway.  */
 
 
      for (;;)
      for (;;)
        {
        {
        again:
        again:
          if (base == limit)
          if (base == limit)
            break;
            break;
 
 
          if (xregexec (name_re, base, 1, match, REG_NOTBOL))
          if (xregexec (name_re, base, 1, match, REG_NOTBOL))
            goto done;  /* No remaining match in this file */
            goto done;  /* No remaining match in this file */
 
 
          /* Match; is it on the line?  */
          /* Match; is it on the line?  */
          if (match[0].rm_eo > limit - base)
          if (match[0].rm_eo > limit - base)
            break;
            break;
 
 
          p = base + match[0].rm_so;
          p = base + match[0].rm_so;
          base += match[0].rm_eo;
          base += match[0].rm_eo;
 
 
          /* One more test: if on the same line we have the same string
          /* One more test: if on the same line we have the same string
             with the appropriate underscores, then leave it alone.
             with the appropriate underscores, then leave it alone.
             We want exactly two leading and trailing underscores.  */
             We want exactly two leading and trailing underscores.  */
          if (*p == '_')
          if (*p == '_')
            {
            {
              len = base - p - ((*base == '_') ? 2 : 1);
              len = base - p - ((*base == '_') ? 2 : 1);
              q = p + 1;
              q = p + 1;
            }
            }
          else
          else
            {
            {
              len = base - p - ((*base == '_') ? 1 : 0);
              len = base - p - ((*base == '_') ? 1 : 0);
              q = p;
              q = p;
            }
            }
          if (len + 4 > SCRATCHSZ)
          if (len + 4 > SCRATCHSZ)
            abort ();
            abort ();
          memcpy (&scratch[2], q, len);
          memcpy (&scratch[2], q, len);
          len += 2;
          len += 2;
          scratch[len++] = '_';
          scratch[len++] = '_';
          scratch[len++] = '_';
          scratch[len++] = '_';
 
 
          for (q = line; q <= limit - len; q++)
          for (q = line; q <= limit - len; q++)
            if (*q == '_' && !strncmp (q, scratch, len))
            if (*q == '_' && !strncmp (q, scratch, len))
              goto again;
              goto again;
 
 
          fwrite (text, 1, p - text, stdout);
          fwrite (text, 1, p - text, stdout);
          fwrite (scratch, 1, len, stdout);
          fwrite (scratch, 1, len, stdout);
 
 
          text = base;
          text = base;
        }
        }
    }
    }
 done:
 done:
  fputs (text, stdout);
  fputs (text, stdout);
}
}
 
 
 
 
FIX_PROC_HEAD( wrap_fix )
FIX_PROC_HEAD( wrap_fix )
{
{
  tSCC   z_no_wrap_pat[] = "^#if.*__need_";
  tSCC   z_no_wrap_pat[] = "^#if.*__need_";
  static regex_t no_wrapping_re; /* assume zeroed data */
  static regex_t no_wrapping_re; /* assume zeroed data */
 
 
  tCC*   pz_name = NULL;
  tCC*   pz_name = NULL;
 
 
  if (no_wrapping_re.allocated == 0)
  if (no_wrapping_re.allocated == 0)
    compile_re( z_no_wrap_pat, &no_wrapping_re, 0, "no-wrap pattern",
    compile_re( z_no_wrap_pat, &no_wrapping_re, 0, "no-wrap pattern",
                "wrap-fix" );
                "wrap-fix" );
 
 
  /*
  /*
   *  IF we do *not* match the no-wrap re, then we have a double negative.
   *  IF we do *not* match the no-wrap re, then we have a double negative.
   *  A double negative means YES.
   *  A double negative means YES.
   */
   */
  if (xregexec( &no_wrapping_re, text, 0, NULL, 0 ) != 0)
  if (xregexec( &no_wrapping_re, text, 0, NULL, 0 ) != 0)
    {
    {
      /*
      /*
       *  A single file can get wrapped more than once by different fixes.
       *  A single file can get wrapped more than once by different fixes.
       *  A single fix can wrap multiple files.  Therefore, guard with
       *  A single fix can wrap multiple files.  Therefore, guard with
       *  *both* the fix name and the file name.
       *  *both* the fix name and the file name.
       */
       */
      size_t ln = strlen( filname ) + strlen( p_fixd->fix_name ) + 14;
      size_t ln = strlen( filname ) + strlen( p_fixd->fix_name ) + 14;
      char*  pz = XNEWVEC (char, ln);
      char*  pz = XNEWVEC (char, ln);
      pz_name = pz;
      pz_name = pz;
      sprintf( pz, "FIXINC_WRAP_%s-%s", filname, p_fixd->fix_name );
      sprintf( pz, "FIXINC_WRAP_%s-%s", filname, p_fixd->fix_name );
 
 
      for (pz += 12; 1; pz++) {
      for (pz += 12; 1; pz++) {
        char ch = *pz;
        char ch = *pz;
 
 
        if (ch == NUL)
        if (ch == NUL)
          break;
          break;
 
 
        if (! ISALNUM( ch )) {
        if (! ISALNUM( ch )) {
          *pz = '_';
          *pz = '_';
        }
        }
        else {
        else {
          *pz = TOUPPER( ch );
          *pz = TOUPPER( ch );
        }
        }
      }
      }
 
 
      printf( "#ifndef %s\n", pz_name );
      printf( "#ifndef %s\n", pz_name );
      printf( "#define %s 1\n\n", pz_name );
      printf( "#define %s 1\n\n", pz_name );
    }
    }
 
 
  if (p_fixd->patch_args[1] == (tCC*)NULL)
  if (p_fixd->patch_args[1] == (tCC*)NULL)
    fputs( text, stdout );
    fputs( text, stdout );
 
 
  else {
  else {
    fputs( p_fixd->patch_args[1], stdout );
    fputs( p_fixd->patch_args[1], stdout );
    fputs( text, stdout );
    fputs( text, stdout );
    if (p_fixd->patch_args[2] != (tCC*)NULL)
    if (p_fixd->patch_args[2] != (tCC*)NULL)
      fputs( p_fixd->patch_args[2], stdout );
      fputs( p_fixd->patch_args[2], stdout );
  }
  }
 
 
  if (pz_name != NULL) {
  if (pz_name != NULL) {
    printf( "\n#endif  /* %s */\n", pz_name );
    printf( "\n#endif  /* %s */\n", pz_name );
    free( (void*)pz_name );
    free( (void*)pz_name );
  }
  }
}
}
 
 
 
 
/*
/*
 *  Search for multiple copies of a regular expression.  Each block
 *  Search for multiple copies of a regular expression.  Each block
 *  of matched text is replaced with the format string, as described
 *  of matched text is replaced with the format string, as described
 *  above in `format_write'.
 *  above in `format_write'.
 */
 */
FIX_PROC_HEAD( gnu_type_fix )
FIX_PROC_HEAD( gnu_type_fix )
{
{
  const char* pz_pat;
  const char* pz_pat;
  regex_t    re;
  regex_t    re;
  regmatch_t rm[GTYPE_SE_CT+1];
  regmatch_t rm[GTYPE_SE_CT+1];
  IGNORE_ARG(filname);
  IGNORE_ARG(filname);
 
 
  {
  {
    tTestDesc* pTD = p_fixd->p_test_desc;
    tTestDesc* pTD = p_fixd->p_test_desc;
    int        ct  = p_fixd->test_ct;
    int        ct  = p_fixd->test_ct;
    for (;;)
    for (;;)
      {
      {
        if (ct-- <= 0)
        if (ct-- <= 0)
          {
          {
            fprintf (stderr, zNeedsArg, p_fixd->fix_name, "search text", 1);
            fprintf (stderr, zNeedsArg, p_fixd->fix_name, "search text", 1);
            exit (EXIT_BROKEN);
            exit (EXIT_BROKEN);
          }
          }
 
 
        if (pTD->type == TT_EGREP)
        if (pTD->type == TT_EGREP)
          {
          {
            pz_pat = pTD->pz_test_text;
            pz_pat = pTD->pz_test_text;
            break;
            break;
          }
          }
 
 
        pTD++;
        pTD++;
      }
      }
  }
  }
 
 
  compile_re (pz_pat, &re, 1, "gnu type typedef", "gnu_type_fix");
  compile_re (pz_pat, &re, 1, "gnu type typedef", "gnu_type_fix");
 
 
  while (xregexec (&re, text, GTYPE_SE_CT+1, rm, 0) == 0)
  while (xregexec (&re, text, GTYPE_SE_CT+1, rm, 0) == 0)
    {
    {
      text = emit_gnu_type (text, rm);
      text = emit_gnu_type (text, rm);
    }
    }
 
 
  /*
  /*
   *  Dump out the rest of the file
   *  Dump out the rest of the file
   */
   */
  fputs (text, stdout);
  fputs (text, stdout);
}
}
 
 
 
 
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
 
 
     test for fix selector
     test for fix selector
 
 
     THIS IS THE ONLY EXPORTED ROUTINE
     THIS IS THE ONLY EXPORTED ROUTINE
 
 
*/
*/
void
void
apply_fix( tFixDesc* p_fixd, tCC* filname )
apply_fix( tFixDesc* p_fixd, tCC* filname )
{
{
#define _FT_(n,p) { n, p },
#define _FT_(n,p) { n, p },
  static fix_entry_t fix_table[] = { FIXUP_TABLE { NULL, NULL }};
  static fix_entry_t fix_table[] = { FIXUP_TABLE { NULL, NULL }};
#undef _FT_
#undef _FT_
#define FIX_TABLE_CT (ARRAY_SIZE (fix_table)-1)
#define FIX_TABLE_CT (ARRAY_SIZE (fix_table)-1)
 
 
  tCC* fixname = p_fixd->patch_args[0];
  tCC* fixname = p_fixd->patch_args[0];
  char* buf;
  char* buf;
  int ct = FIX_TABLE_CT;
  int ct = FIX_TABLE_CT;
  fix_entry_t* pfe = fix_table;
  fix_entry_t* pfe = fix_table;
 
 
  for (;;)
  for (;;)
    {
    {
      if (strcmp (pfe->fix_name, fixname) == 0)
      if (strcmp (pfe->fix_name, fixname) == 0)
        break;
        break;
      if (--ct <= 0)
      if (--ct <= 0)
        {
        {
          fprintf (stderr, "fixincl error:  the `%s' fix is unknown\n",
          fprintf (stderr, "fixincl error:  the `%s' fix is unknown\n",
                   fixname );
                   fixname );
          exit (EXIT_BROKEN);
          exit (EXIT_BROKEN);
        }
        }
      pfe++;
      pfe++;
    }
    }
 
 
  buf = load_file_data (stdin);
  buf = load_file_data (stdin);
  (*pfe->fix_proc)( filname, buf, p_fixd );
  (*pfe->fix_proc)( filname, buf, p_fixd );
}
}
 
 
#ifdef SEPARATE_FIX_PROC
#ifdef SEPARATE_FIX_PROC
tSCC z_usage[] =
tSCC z_usage[] =
"USAGE: applyfix <fix-name> <file-to-fix> <file-source> <file-destination>\n";
"USAGE: applyfix <fix-name> <file-to-fix> <file-source> <file-destination>\n";
tSCC z_reopen[] =
tSCC z_reopen[] =
"FS error %d (%s) reopening %s as std%s\n";
"FS error %d (%s) reopening %s as std%s\n";
 
 
int
int
main( int argc, char** argv )
main( int argc, char** argv )
{
{
  tFixDesc* pFix;
  tFixDesc* pFix;
  char* pz_tmptmp;
  char* pz_tmptmp;
  char* pz_tmp_base;
  char* pz_tmp_base;
  char* pz_tmp_dot;
  char* pz_tmp_dot;
 
 
  if (argc != 5)
  if (argc != 5)
    {
    {
    usage_failure:
    usage_failure:
      fputs (z_usage, stderr);
      fputs (z_usage, stderr);
      return EXIT_FAILURE;
      return EXIT_FAILURE;
    }
    }
 
 
  initialize_opts ();
  initialize_opts ();
 
 
  {
  {
    char* pz = argv[1];
    char* pz = argv[1];
    long  idx;
    long  idx;
 
 
    if (! ISDIGIT ( *pz ))
    if (! ISDIGIT ( *pz ))
      goto usage_failure;
      goto usage_failure;
 
 
    idx = strtol (pz, &pz, 10);
    idx = strtol (pz, &pz, 10);
    if ((*pz != NUL) || ((unsigned)idx >= FIX_COUNT))
    if ((*pz != NUL) || ((unsigned)idx >= FIX_COUNT))
      goto usage_failure;
      goto usage_failure;
    pFix = fixDescList + idx;
    pFix = fixDescList + idx;
  }
  }
 
 
  if (freopen (argv[3], "r", stdin) != stdin)
  if (freopen (argv[3], "r", stdin) != stdin)
    {
    {
      fprintf (stderr, z_reopen, errno, strerror( errno ), argv[3], "in");
      fprintf (stderr, z_reopen, errno, strerror( errno ), argv[3], "in");
      return EXIT_FAILURE;
      return EXIT_FAILURE;
    }
    }
 
 
  pz_tmptmp = XNEWVEC (char, strlen (argv[4]) + 5);
  pz_tmptmp = XNEWVEC (char, strlen (argv[4]) + 5);
  strcpy( pz_tmptmp, argv[4] );
  strcpy( pz_tmptmp, argv[4] );
 
 
  /* Don't lose because "12345678" and "12345678X" map to the same
  /* Don't lose because "12345678" and "12345678X" map to the same
     file under DOS restricted 8+3 file namespace.  Note that DOS
     file under DOS restricted 8+3 file namespace.  Note that DOS
     doesn't allow more than one dot in the trunk of a file name.  */
     doesn't allow more than one dot in the trunk of a file name.  */
  pz_tmp_base = basename( pz_tmptmp );
  pz_tmp_base = basename( pz_tmptmp );
  pz_tmp_dot = strchr( pz_tmp_base, '.' );
  pz_tmp_dot = strchr( pz_tmp_base, '.' );
#ifdef _PC_NAME_MAX
#ifdef _PC_NAME_MAX
  if (pathconf( pz_tmptmp, _PC_NAME_MAX ) <= 12 /* is this DOS or Windows9X? */
  if (pathconf( pz_tmptmp, _PC_NAME_MAX ) <= 12 /* is this DOS or Windows9X? */
      && pz_tmp_dot != (char*)NULL)
      && pz_tmp_dot != (char*)NULL)
    strcpy (pz_tmp_dot+1, "X"); /* nuke the original extension */
    strcpy (pz_tmp_dot+1, "X"); /* nuke the original extension */
  else
  else
#endif /* _PC_NAME_MAX */
#endif /* _PC_NAME_MAX */
    strcat (pz_tmptmp, ".X");
    strcat (pz_tmptmp, ".X");
  if (freopen (pz_tmptmp, "w", stdout) != stdout)
  if (freopen (pz_tmptmp, "w", stdout) != stdout)
    {
    {
      fprintf (stderr, z_reopen, errno, strerror( errno ), pz_tmptmp, "out");
      fprintf (stderr, z_reopen, errno, strerror( errno ), pz_tmptmp, "out");
      return EXIT_FAILURE;
      return EXIT_FAILURE;
    }
    }
 
 
  apply_fix (pFix, argv[1]);
  apply_fix (pFix, argv[1]);
  fclose (stdout);
  fclose (stdout);
  fclose (stdin);
  fclose (stdin);
  unlink (argv[4]);
  unlink (argv[4]);
  if (rename (pz_tmptmp, argv[4]) != 0)
  if (rename (pz_tmptmp, argv[4]) != 0)
    {
    {
      fprintf (stderr, "error %d (%s) renaming %s to %s\n", errno,
      fprintf (stderr, "error %d (%s) renaming %s to %s\n", errno,
               strerror( errno ), pz_tmptmp, argv[4]);
               strerror( errno ), pz_tmptmp, argv[4]);
      return EXIT_FAILURE;
      return EXIT_FAILURE;
    }
    }
 
 
  return EXIT_SUCCESS;
  return EXIT_SUCCESS;
}
}
#endif
#endif
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.