home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / gcc-2.7.2.1-src.tgz / tar.out / fsf / gcc / gen-protos.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  4KB  |  180 lines

  1. /* gen-protos.c - massages a list of prototypes, for use by fixproto.
  2.    Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or modify it
  5. under the terms of the GNU General Public License as published by the
  6. Free Software Foundation; either version 2, or (at your option) any
  7. later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. GNU General Public License for more details.
  13.  
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
  17.  
  18. #include <stdio.h>
  19. #include <ctype.h>
  20. #include "hconfig.h"
  21. #include "scan.h"
  22. #include "cpplib.h"
  23. #include "cpphash.h"
  24.  
  25. #define HASH_SIZE 2503 /* a prime */
  26.  
  27. int
  28. hashf (name, len, hashsize)
  29.      register U_CHAR *name;
  30.      register int len;
  31.      int hashsize;
  32. {
  33.   register int r = 0;
  34.  
  35.   while (len--)
  36.     r = HASHSTEP (r, *name++);
  37.  
  38.   return MAKE_POS (r) % hashsize;
  39. }
  40.  
  41. int hash_tab[HASH_SIZE];
  42. int verbose = 0;
  43.  
  44. sstring linebuf;
  45.  
  46. /* Avoid error if config defines abort as fancy_abort.
  47.    It's not worth "really" implementing this because ordinary
  48.    compiler users never run fix-header.  */
  49.  
  50. void
  51. fancy_abort ()
  52. {
  53.   abort ();
  54. }
  55.  
  56. int
  57. main (argc, argv)
  58.      int argc;
  59.      char** argv;
  60. {
  61.   FILE *inf = stdin;
  62.   FILE *outf = stdout;
  63.   int next_index = 0;
  64.   int i, i0;
  65.  
  66.   fprintf (outf, "struct fn_decl std_protos[] = {\n");
  67.  
  68.   for (;;)
  69.     {
  70.       int c = skip_spaces (inf, ' ');
  71.       int param_nesting = 1;
  72.       char *param_start, *param_end, *decl_start,
  73.       *name_start, *name_end;
  74.       register char *ptr;
  75.       if (c == EOF)
  76.     break;
  77.       linebuf.ptr = linebuf.base;
  78.       ungetc (c, inf);
  79.       c = read_upto (inf, &linebuf, '\n');
  80.       if (linebuf.base[0] == '#') /* skip cpp command */
  81.     continue;
  82.       if (linebuf.base[0] == '\0') /* skip empty line */
  83.     continue;
  84.  
  85.       ptr = linebuf.ptr - 1;
  86.       while (*ptr == ' ' || *ptr == '\t') ptr--;
  87.       if (*ptr-- != ';')
  88.     {
  89.       fprintf (stderr, "Funny input line: %s\n", linebuf.base);
  90.       continue;
  91.     }
  92.       while (*ptr == ' ' || *ptr == '\t') ptr--;
  93.       if (*ptr != ')')
  94.     {
  95.       fprintf (stderr, "Funny input line: %s\n", linebuf.base);
  96.       continue;
  97.     }
  98.       param_end = ptr;
  99.       for (;;)
  100.     {
  101.       int c = *--ptr;
  102.       if (c == '(' && --param_nesting == 0)
  103.         break;
  104.       else if (c == ')')
  105.         param_nesting++;
  106.     }
  107.       param_start = ptr+1;
  108.  
  109.       ptr--;
  110.       while (*ptr == ' ' || *ptr == '\t') ptr--;
  111.  
  112.       if (!isalnum (*ptr))
  113.     {
  114.       if (verbose)
  115.         fprintf (stderr, "%s: Can't handle this complex prototype: %s\n",
  116.              argv[0], linebuf.base);
  117.       continue;
  118.     }
  119.       name_end = ptr+1;
  120.  
  121.       while (isalnum (*ptr) || *ptr == '_') --ptr;
  122.       name_start = ptr+1;
  123.       while (*ptr == ' ' || *ptr == '\t') ptr--;
  124.       ptr[1] = 0;
  125.       *name_end = 0;
  126.       *param_end = 0;
  127.       *name_end = 0;
  128.  
  129.       decl_start = linebuf.base;
  130.       if (strncmp (decl_start, "typedef ", 8) == 0)
  131.     continue;
  132.       if (strncmp (decl_start, "extern ", 7) == 0)
  133.     decl_start += 7;
  134.  
  135.  
  136.       /* NOTE:  If you edit this,
  137.      also edit lookup_std_proto in fix-header.c !! */
  138.       i = hashf (name_start, name_end - name_start, HASH_SIZE);
  139.       i0 = i;
  140.       if (hash_tab[i] != 0)
  141.     {
  142.       for (;;)
  143.         {
  144.           i = (i+1) % HASH_SIZE;
  145.           if (i == i0)
  146.         abort ();
  147.           if (hash_tab[i] == 0)
  148.         break;
  149.         }
  150.     }
  151.       hash_tab[i] = next_index;
  152.  
  153.       fprintf (outf, "  {\"%s\", \"%s\", \"%s\" },\n",
  154.            name_start, decl_start, param_start);
  155.  
  156.       next_index++;
  157.  
  158.       if (c == EOF)
  159.     break;
  160.     }
  161.   fprintf (outf, "{0, 0, 0}\n};\n");
  162.  
  163.  
  164.   fprintf (outf, "#define HASH_SIZE %d\n", HASH_SIZE);
  165.   fprintf (outf, "short hash_tab[HASH_SIZE] = {\n");
  166.   for (i = 0; i < HASH_SIZE; i++)
  167.     fprintf (outf, "  %d,\n", hash_tab[i]);
  168.   fprintf (outf, "};\n");
  169.  
  170.   return 0;
  171. }
  172.  
  173. void
  174. fatal (s)
  175.      char *s;
  176. {
  177.   fprintf (stderr, "%s: %s\n", "gen-protos", s);
  178.   exit (FATAL_EXIT_CODE);
  179. }
  180.