home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Distributions / ucb / 2bsd.tar.gz / 2bsd.tar / upgrade / src / mkstr.c < prev    next >
C/C++ Source or Header  |  1979-04-19  |  5KB  |  279 lines

  1. #include <retrofit.h>
  2. #include <stdio.h>
  3.  
  4. #define    ungetchar(c)    ungetc(c, stdin)
  5.  
  6. long    ftell();
  7. /*
  8.  * mkstr - create a string error message file by massaging C source
  9.  *
  10.  * Bill Joy UCB August 1977
  11.  *
  12.  * Modified March 1978 to hash old messages to be able to recompile
  13.  * without addding messages to the message file (usually)
  14.  *
  15.  * Based on an earlier program conceived by Bill Joy and Chuck Haley
  16.  *
  17.  * Program to create a string error message file
  18.  * from a group of C programs.  Arguments are the name
  19.  * of the file where the strings are to be placed, the
  20.  * prefix of the new files where the processed source text
  21.  * is to be placed, and the files to be processed.
  22.  *
  23.  * The program looks for 'error("' in the source stream.
  24.  * Whenever it finds this, the following characters from the '"'
  25.  * to a '"' are replaced by 'seekpt' where seekpt is a
  26.  * pointer into the error message file.
  27.  * If the '(' is not immediately followed by a '"' no change occurs.
  28.  *
  29.  * The optional '-' causes strings to be added at the end of the
  30.  * existing error message file for recompilation of single routines.
  31.  */
  32.  
  33.  
  34. FILE    *mesgread, *mesgwrite;
  35. char    *progname;
  36. char    usagestr[]    "usage: %s [ - ] mesgfile prefix file ...\n";
  37. char    name[100], *np;
  38.  
  39. main(argc, argv)
  40.     int argc;
  41.     char *argv[];
  42. {
  43.     char addon = 0;
  44.  
  45.     argc--, progname = *argv++;
  46.     if (argc > 1 && argv[0][0] == '-')
  47.         addon++, argc--, argv++;
  48.     if (argc < 3)
  49.         fprintf(stderr, usagestr, progname), exit(1);
  50.     mesgwrite = fopen(argv[0], addon ? "a" : "w");
  51.     if (mesgwrite == NULL)
  52.         perror(argv[0]), exit(1);
  53.     mesgread = fopen(argv[0], "r");
  54.     if (mesgread == NULL)
  55.         perror(argv[0]), exit(1);
  56.     inithash();
  57.     argc--, argv++;
  58.     strcpy(name, argv[0]);
  59.     np = name + strlen(name);
  60.     argc--, argv++;
  61.     do {
  62.         strcpy(np, argv[0]);
  63.         if (freopen(name, "w", stdout) == NULL)
  64.             perror(name), exit(1);
  65.         if (freopen(argv[0], "r", stdin) == NULL)
  66.             perror(argv[0]), exit(1);
  67.         process();
  68.         argc--, argv++;
  69.     } while (argc > 0);
  70.     exit(0);
  71. }
  72.  
  73. process()
  74. {
  75.     register char *cp;
  76.     register c;
  77.  
  78.     for (;;) {
  79.         c = getchar();
  80.         if (c == EOF)
  81.             return;
  82.         if (c != 'e') {
  83.             putchar(c);
  84.             continue;
  85.         }
  86.         if (match("error(")) {
  87.             printf("error(");
  88.             c = getchar();
  89.             if (c != '"')
  90.                 putchar(c);
  91.             else
  92.                 copystr();
  93.         }
  94.     }
  95. }
  96.  
  97. match(ocp)
  98.     char *ocp;
  99. {
  100.     register char *cp;
  101.     register c;
  102.  
  103.     for (cp = ocp + 1; *cp; cp++) {
  104.         c = getchar();
  105.         if (c != *cp) {
  106.             while (ocp < cp)
  107.                 putchar(*ocp++);
  108.             ungetchar(c);
  109.             return (0);
  110.         }
  111.     }
  112.     return (1);
  113. }
  114.  
  115. copystr()
  116. {
  117.     register c, ch;
  118.     char buf[512];
  119.     register char *cp = buf;
  120.  
  121.     for (;;) {
  122.         c = getchar();
  123.         if (c == EOF)
  124.             break;
  125.         switch (c) {
  126.  
  127.         case '"':
  128.             *cp++ = 0;
  129.             goto out;
  130.         case '\\':
  131.             c = getchar();
  132.             switch (c) {
  133.  
  134.             case 'b':
  135.                 c = '\b';
  136.                 break;
  137.             case 't':
  138.                 c = '\t';
  139.                 break;
  140.             case 'r':
  141.                 c = '\r';
  142.                 break;
  143.             case 'n':
  144.                 c = '\n';
  145.                 break;
  146.             case '\n':
  147.                 continue;
  148.             case 'f':
  149.                 c = '\f';
  150.                 break;
  151.             case '0':
  152.                 c = 0;
  153.                 break;
  154.             case '\\':
  155.                 break;
  156.             default:
  157.                 if (!octdigit(c))
  158.                     break;
  159.                 c =- '0';
  160.                 ch = getchar();
  161.                 if (!octdigit(ch))
  162.                     break;
  163.                 c =<< 7, c =+ ch - '0';
  164.                 ch = getchar();
  165.                 if (!octdigit(ch))
  166.                     break;
  167.                 c =<< 3, c=+ ch - '0', ch = -1;
  168.                 break;
  169.             }
  170.         }
  171.         *cp++ = c;
  172.     }
  173. out:
  174.     *cp = 0;
  175.     printf("%d", hashit(buf, 1));
  176. }
  177.  
  178. octdigit(c)
  179.     char c;
  180. {
  181.  
  182.     return (c >= '0' && c <= '7');
  183. }
  184.  
  185. inithash()
  186. {
  187.     char buf[512];
  188.     int mesgpt = 0;
  189.  
  190.     rewind(mesgread);
  191.     while (fgetNUL(buf, sizeof buf, mesgread) != NULL) {
  192.         hashit(buf, 0, mesgpt);
  193.         mesgpt += strlen(buf) + 2;
  194.     }
  195. }
  196.  
  197. #define    NBUCKETS    511
  198.  
  199. struct    hash {
  200.     long    hval;
  201.     unsigned hpt;
  202.     struct    hash *hnext;
  203. } *bucket[NBUCKETS];
  204.  
  205. hashit(str, really, fakept)
  206.     char *str;
  207.     char really;
  208.     unsigned fakept;
  209. {
  210.     int i;
  211.     register struct hash *hp;
  212.     char buf[512];
  213.     long hashval = 0;
  214.     register char *cp;
  215.  
  216.     if (really)
  217.         fflush(mesgwrite);
  218.     for (cp = str; *cp;)
  219.         hashval = (hashval << 1) + *cp++;
  220.     i = hashval % NBUCKETS;
  221.     if (i < 0)
  222.         i =+ NBUCKETS;
  223.     if (really != 0)
  224.         for (hp = bucket[i]; hp != 0; hp = hp->hnext)
  225.         if (hp->hval == hashval) {
  226.             fseek(mesgread, (long) hp->hpt, 0);
  227.             fgetNUL(buf, sizeof buf, mesgread);
  228. /*
  229.             fprintf(stderr, "Got (from %d) %s\n", hp->hpt, buf);
  230. */
  231.             if (strcmp(buf, str) == 0)
  232.                 break;
  233.         }
  234.     if (!really || hp == 0) {
  235.         hp = calloc(1, sizeof *hp);
  236.         hp->hnext = bucket[i];
  237.         hp->hval = hashval;
  238.         hp->hpt = really ? ftell(mesgwrite) : fakept;
  239.         if (really) {
  240.             fwrite(str, sizeof (char), strlen(str) + 1, mesgwrite);
  241.             fwrite("\n", sizeof (char), 1, mesgwrite);
  242.         }
  243.         bucket[i] = hp;
  244.     }
  245. /*
  246.     fprintf(stderr, "%s hashed to %ld at %d\n", str, hp->hval, hp->hpt);
  247. */
  248.     return (hp->hpt);
  249. }
  250.  
  251. #include <sys/types.h>
  252. #include <sys/stat.h>
  253.  
  254. long
  255. tell(unit)
  256.     int unit;
  257. {
  258.     struct stat stb;
  259.  
  260.     if (fstat(unit, &stb))
  261.         return (-1);
  262.     return ((unsigned) stb.st_size);
  263. }
  264.  
  265. fgetNUL(obuf, rmdr, file)
  266.     char *obuf;
  267.     register int rmdr;
  268.     FILE *file;
  269. {
  270.     register char c;
  271.     register char *buf = obuf;
  272.  
  273.     while (--rmdr > 0 && (c = getc(file)) != 0 && c != EOF)
  274.         *buf++ = c;
  275.     *buf++ = 0;
  276.     getc(file);
  277.     return ((feof(file) || ferror(file)) ? NULL : obuf);
  278. }
  279.