1BSD/s6/mkstr.c
#
/*
* mkstr - create a string error message file by massaging C source
*
* Bill Joy UCB August 1977
*
* Based on an earlier program conceived by Bill Joy and Chuck Haley
*
* Program to create a string error message file
* from a group of C programs. Arguments are the name
* of the file where the strings are to be placed, the
* prefix of the new files where the processed source text
* is to be placed, and the files to be processed.
*
* The program looks for 'error("' in the source stream.
* Whenever it finds this, this and the following characters from the '"'
* to a '"' are replaced by 'error(seekpt' where seekpt is a
* pointer into the error message file.
* If the '(' is not immediately followed by a '"' only the name change
* occurs.
*
* The optional '-' causes strings to be added at the end of the
* existing error message file for recompilation of single routines.
*/
extern fout;
int ibuf[259], sbuf[259];
int stbuf[18];
char addon;
char *progname;
char usagestr[] "usage: %s [ - ] mesgfile prefix file ...\n";
char name[100], *np;
int seekpt;
main(argc, argv)
int argc;
char *argv[];
{
argc--, progname = *argv++;
if (argc > 1 && argv[0][0] == '-')
addon++, argc--, argv++;
if (argc < 3)
printf(usagestr, progname), exit(1);
if (addon == 0 || (sbuf[0] = open(argv[0], 1)) < 0)
if (fcreat(argv[0], sbuf) < 0)
perror(argv[0]), exit(1);
fstat(sbuf[0], stbuf);
seekpt = stbuf[5];
seek(sbuf[0], 0, 2);
argc--, argv++;
fout = dup(1);
strcpy(name, argv[0]);
np = name + strlen(name);
argc--, argv++;
do {
strcpy(np, argv[0]);
close(1);
if (creat(name, 0644) < 0)
perror(name), exit(1);
fout = dup(1);
close(0);
if (fopen(argv[0], ibuf) < 0)
perror(argv[0]), exit(1);
process();
flush();
close(fout);
argc--, argv++;
} while (argc > 0);
fflush(sbuf);
}
process()
{
register char *cp;
register c;
for (;;) {
c = getc(ibuf);
again:
if (c == -1)
return;
if (c != 'e') {
putchar(c);
continue;
}
c = nomatch("error(");
if (c != -1)
goto again;
printf("error(");
c = getc(ibuf);
if (c != '"')
putchar(c);
else
copystr();
}
}
nomatch(ocp)
char *ocp;
{
register char *cp;
register c;
for (cp = ocp + 1; *cp; cp++) {
c = getc(ibuf);
if (c != *cp) {
while (ocp < cp)
putchar(*ocp++);
return (c);
}
}
return (-1);
}
copystr()
{
register c, ch;
printf("%d", seekpt);
ch = -1;
for (;;) {
c = ch;
ch = -1;
if (c == -1)
c = getc(ibuf);
switch (c) {
case '"':
putc(0, sbuf);
putc('\n', sbuf);
seekpt =+ 2;
return;
case '\\':
c = getc(ibuf);
switch (c) {
case 'b':
c = '\b';
break;
case 't':
c = '\t';
break;
case 'r':
c = '\r';
break;
case 'n':
c = '\n';
break;
case '\n':
continue;
case 'f':
c = '\f';
break;
case '0':
c = 0;
break;
case '\\':
break;
default:
if (!octdigit(c))
break;
c =- '0';
ch = getc(ibuf);
if (!octdigit(ch))
break;
c =<< 7, c =+ ch - '0';
ch = getc(ibuf);
if (!octdigit(ch))
break;
c =<< 3, c=+ ch - '0', ch = -1;
break;
}
}
putc(c, sbuf), seekpt++;
}
}
octdigit(c)
char c;
{
return (c >= '0' && c <= '7');
}
strcpy(to, from)
register char *to, *from;
{
while (*to++ = *from++)
continue;
}