Upgrade to latest released SIPB version I can find. (Unfortunately, the

original releases were not numbered.)
This commit is contained in:
Garrett Wollman 1995-01-14 22:29:34 +00:00
parent af4d8ead38
commit 5e914d3b8d
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=5624
7 changed files with 449 additions and 186 deletions

View File

@ -1,14 +1,17 @@
# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
# $Id: Makefile,v 1.1.1.1 1994/09/30 14:49:49 csgr Exp $
# $Id$
PROG= compile_et
CFLAGS+=-I. -I${.CURDIR}
SRCS= compile_et.c error_message.c et_name.c init_et.c perror.c error_table.c
DPADD= ${LIBL}
LDADD= -ll
CLEANFILES=et_lex.lex.c y.tab.c y.tab.h error_table.c
NOMAN= noman
SRCS= compile_et.c error_table.y
CFLAGS+= -I. -I${.CURDIR}/../libcom_err
CLEANFILES+= et_lex.lex.c
DPADD+= ${LIBL}
LDADD+= -ll
error_table.c: et_lex.lex.c
beforedepend: et_lex.lex.c
error_table.o: et_lex.lex.c
.l.c:
${LEX} -l -t ${.IMPSRC} > ${.TARGET}
.include <bsd.prog.mk>

View File

@ -0,0 +1,79 @@
.\" Copyright (c) 1988 Massachusetts Institute of Technology,
.\" Student Information Processing Board. All rights reserved.
.\"
.\" $Header$
.\"
.TH COMPILE_ET 1 "22 Nov 1988" SIPB
.SH NAME
compile_et \- error table compiler
.SH SYNOPSIS
.B compile_et
file
.SH DESCRIPTION
.B Compile_et
converts a table listing error-code names and associated messages into
a C source file suitable for use with the
.IR com_err (3)
library.
The source file name must end with a suffix of ``.et''; the file
consists of a declaration supplying the name (up to four characters
long) of the error-code table:
.B error_table
.I name
followed by up to 256 entries of the form:
.B error_code
.I name,
"
.I string
"
and a final
.B end
to indicate the end of the table.
The name of the table is used to construct the name of a subroutine
.I initialize_XXXX_error_table
which must be called in order for the
.I com_err
library to recognize the error table.
The various error codes defined are assigned sequentially increasing
numbers (starting with a large number computed as a hash function of
the name of the table); thus for compatibility it is suggested that
new codes be added only to the end of an existing table, and that no
codes be removed from tables.
The names defined in the table are placed into a C header file with
preprocessor directives defining them as integer constants of up to
32 bits in magnitude.
A C source file is also generated which should be compiled and linked
with the object files which reference these error codes; it contains
the text of the messages and the initialization subroutine. Both C
files have names derived from that of the original source file, with
the ``.et'' suffix replaced by ``.c'' and ``.h''.
A ``#'' in the source file is treated as a comment character, and all
remaining text to the end of the source line will be ignored.
.SH BUGS
Since
.B compile_et
uses a very simple parser based on
.IR yacc (1),
its error recovery leaves much to be desired.
.\" .IR for manual entries
.\" .PP for paragraph breaks
.SH "SEE ALSO"
com_err (3).
Ken Raeburn, "A Common Error Description Library for UNIX".

View File

@ -1,17 +1,30 @@
/*
*
* Copyright 1986, 1987 by MIT Student Information Processing Board
* For copyright info, see "Copyright.SIPB".
* Copyright 1986, 1987, 1988
* by MIT Student Information Processing Board.
*
* For copyright info, see "mit-sipb-copyright.h".
*
* $Id: compile_et.c,v 1.2 1994/07/19 19:21:24 g89r4222 Exp $
*/
#include <stdio.h>
#include <sys/file.h>
#include <strings.h>
#include <string.h>
#include <sys/param.h>
#include "mit-sipb-copyright.h"
#include "compiler.h"
static char copyright[] = "Copyright 1987 by MIT Student Information Processing Board";
#ifndef __STDC__
#define const
#endif
#ifndef lint
static const char copyright[] =
"Copyright 1987,1988 by MIT Student Information Processing Board";
static const char rcsid_compile_et_c[] =
"$Header: /afs/rel-eng.athena.mit.edu/project/release/current/source/athena/athena.lib/et/RCS/compile_et.c,v 1.3 91/02/28 15:15:23 epeisach Exp $";
#endif
extern char *gensym();
extern char *current_token;
@ -19,154 +32,259 @@ extern int table_number, current;
char buffer[BUFSIZ];
char *table_name = (char *)NULL;
FILE *hfile, *cfile;
/* C library */
extern char *malloc();
extern int errno;
/* lex stuff */
extern FILE *yyin;
extern int yylineno;
char * xmalloc (size) unsigned int size; {
char * p = malloc (size);
if (!p) {
perror (whoami);
exit (1);
}
return p;
}
static int check_arg (str_list, arg) char const *const *str_list, *arg; {
while (*str_list)
if (!strcmp(arg, *str_list++))
return 1;
return 0;
}
static const char *const debug_args[] = {
"d",
"debug",
0,
};
static const char *const lang_args[] = {
"lang",
"language",
0,
};
static const char *const language_names[] = {
"C",
"K&R C",
"C++",
0,
};
static const char * const c_src_prolog[] = {
"static const char * const text[] = {\n",
0,
};
static const char * const krc_src_prolog[] = {
"#ifdef __STDC__\n",
"#define NOARGS void\n",
"#else\n",
"#define NOARGS\n",
"#define const\n",
"#endif\n\n",
"static const char * const text[] = {\n",
0,
};
static const char *const struct_def[] = {
"struct error_table {\n",
" char const * const * msgs;\n",
" long base;\n",
" int n_msgs;\n",
"};\n",
"struct et_list {\n",
" struct et_list *next;\n",
" const struct error_table * table;\n",
"};\n",
"extern struct et_list *_et_list;\n",
"\n", 0,
};
static const char warning[] =
"/*\n * %s:\n * This file is automatically generated; please do not edit it.\n */\n";
/* pathnames */
char c_file[MAXPATHLEN]; /* temporary file */
char c_file[MAXPATHLEN]; /* output file */
char h_file[MAXPATHLEN]; /* output */
char o_file[MAXPATHLEN]; /* output */
char et_file[MAXPATHLEN]; /* input */
main(argc, argv)
int argc;
char **argv;
{
register char *p;
int n_flag = 0, debug = 0;
while (argc > 2) {
register char *arg, ch;
arg = argv[--argc];
if (strlen(arg) != 2 || arg[0] != '-')
goto usage;
ch = arg[1];
if (ch == 'n')
n_flag++;
else if (ch == 'd')
debug++;
else
goto usage;
}
if (argc != 2) {
usage:
fprintf(stderr, "Usage: %s et_file [-n]\n", argv[0]);
exit(1);
}
strcpy(et_file, argv[1]);
p = rindex(et_file, '/');
if (p == (char *)NULL)
p = et_file;
else
p++;
p = rindex(p, '.');
if (!strcmp(p, ".et"))
*++p = '\0';
else {
if (!p)
p = et_file;
while (*p)
p++;
*p++ = '.';
*p = '\0';
}
/* p points at null where suffix should be */
strcpy(p, "et.c");
strcpy(c_file, et_file);
p[0] = 'h';
p[1] = '\0';
strcpy(h_file, et_file);
p[0] = 'o';
strcpy(o_file, et_file);
p[0] = 'e';
p[1] = 't';
p[2] = '\0';
yyin = fopen(et_file, "r");
if (!yyin) {
perror(et_file);
exit(1);
}
hfile = fopen(h_file, "w");
if (hfile == (FILE *)NULL) {
perror(h_file);
exit(1);
}
cfile = fopen(c_file, "w");
if (cfile == (FILE *)NULL) {
perror("Can't open temp file");
exit(1);
}
/* parse it */
fputs("#define NULL 0\n", cfile);
fputs("static char *_et[] = {\n", cfile);
yyparse();
fclose(yyin); /* bye bye input file */
fputs("\t(char *)0\n};\n", cfile);
fputs("extern int init_error_table();\n\n", cfile);
fprintf(cfile, "int %s_err_base = %d;\n\n", table_name, table_number);
fprintf(cfile, "int\ninit_%s_err_tbl()\n", table_name);
fprintf(cfile, "{\n\treturn(init_error_table(_et, %d, %d));\n}\n",
table_number, current);
fclose(cfile);
fputs("extern int init_", hfile);
fputs(table_name, hfile);
fputs("_err_tbl();\nextern int ", hfile);
fputs(table_name, hfile);
fputs("_err_base;\n", hfile);
fclose(hfile); /* bye bye hfile */
if (n_flag)
exit(0);
if (!fork()) {
p = rindex(c_file, '/');
if (p) {
*p++ = '\0';
chdir(c_file);
}
else
p = c_file;
execlp("cc", "cc", "-c", "-R", "-O", p, 0);
perror("cc");
exit(1);
}
else wait(0);
if (!debug)
(void) unlink(c_file);
/* make it .o file name */
c_file[strlen(c_file)-1] = 'o';
if (!fork()) {
execlp("cp", "cp", c_file, o_file, 0);
perror("cp");
exit(1);
}
else wait(0);
if (!debug)
(void) unlink(c_file);
exit(0);
static void usage () {
fprintf (stderr, "%s: usage: %s ERROR_TABLE\n",
whoami, whoami);
exit (1);
}
yyerror(s)
char *s;
{
fputs(s, stderr);
fprintf(stderr, "\nLine number %d; last token was '%s'\n",
yylineno, current_token);
static void dup_err (type, one, two) char const *type, *one, *two; {
fprintf (stderr, "%s: multiple %s specified: `%s' and `%s'\n",
whoami, type, one, two);
usage ();
}
int main (argc, argv) int argc; char **argv; {
char *p, *ename;
int len;
char const * const *cpp;
int got_language = 0;
/* argument parsing */
debug = 0;
filename = 0;
whoami = argv[0];
p = strrchr (whoami, '/');
if (p)
whoami = p+1;
while (argv++, --argc) {
char *arg = *argv;
if (arg[0] != '-') {
if (filename)
dup_err ("filenames", filename, arg);
filename = arg;
}
else {
arg++;
if (check_arg (debug_args, arg))
debug++;
else if (check_arg (lang_args, arg)) {
got_language++;
arg = *++argv, argc--;
if (!arg)
usage ();
if (language)
dup_err ("languanges", language_names[(int)language], arg);
#define check_lang(x,v) else if (!strcasecmp(arg,x)) language = v
check_lang ("c", lang_C);
check_lang ("ansi_c", lang_C);
check_lang ("ansi-c", lang_C);
check_lang ("krc", lang_KRC);
check_lang ("kr_c", lang_KRC);
check_lang ("kr-c", lang_KRC);
check_lang ("k&r-c", lang_KRC);
check_lang ("k&r_c", lang_KRC);
check_lang ("c++", lang_CPP);
check_lang ("cplusplus", lang_CPP);
check_lang ("c-plus-plus", lang_CPP);
#undef check_lang
else {
fprintf (stderr, "%s: unknown language name `%s'\n",
whoami, arg);
fprintf (stderr, "\tpick one of: C K&R-C\n");
exit (1);
}
}
else {
fprintf (stderr, "%s: unknown control argument -`%s'\n",
whoami, arg);
usage ();
}
}
}
if (!filename)
usage ();
if (!got_language)
language = lang_KRC;
else if (language == lang_CPP) {
fprintf (stderr, "%s: Sorry, C++ support is not yet finished.\n",
whoami);
exit (1);
}
p = xmalloc (strlen (filename) + 5);
strcpy (p, filename);
filename = p;
p = strrchr(filename, '/');
if (p == (char *)NULL)
p = filename;
else
p++;
ename = p;
len = strlen (ename);
p += len - 3;
if (strcmp (p, ".et"))
p += 3;
*p++ = '.';
/* now p points to where "et" suffix should start */
/* generate new filenames */
strcpy (p, "c");
strcpy (c_file, ename);
*p = 'h';
strcpy (h_file, ename);
strcpy (p, "et");
yyin = fopen(filename, "r");
if (!yyin) {
perror(filename);
exit(1);
}
hfile = fopen(h_file, "w");
if (hfile == (FILE *)NULL) {
perror(h_file);
exit(1);
}
fprintf (hfile, warning, h_file);
cfile = fopen(c_file, "w");
if (cfile == (FILE *)NULL) {
perror(c_file);
exit(1);
}
fprintf (cfile, warning, c_file);
/* prologue */
if (language == lang_C)
cpp = c_src_prolog;
else if (language == lang_KRC)
cpp = krc_src_prolog;
else
abort ();
while (*cpp)
fputs (*cpp++, cfile);
/* parse it */
yyparse();
fclose(yyin); /* bye bye input file */
fputs (" 0\n};\n\n", cfile);
for (cpp = struct_def; *cpp; cpp++)
fputs (*cpp, cfile);
fprintf(cfile,
"static const struct error_table et = { text, %ldL, %d };\n\n",
table_number, current);
fputs("static struct et_list link = { 0, 0 };\n\n",
cfile);
fprintf(cfile, "void initialize_%s_error_table (%s) {\n",
table_name, (language == lang_C) ? "void" : "NOARGS");
fputs(" if (!link.table) {\n", cfile);
fputs(" link.next = _et_list;\n", cfile);
fputs(" link.table = &et;\n", cfile);
fputs(" _et_list = &link;\n", cfile);
fputs(" }\n", cfile);
fputs("}\n", cfile);
fclose(cfile);
fprintf (hfile, "extern void initialize_%s_error_table ();\n",
table_name);
fprintf (hfile, "#define ERROR_TABLE_BASE_%s (%ldL)\n",
table_name, table_number);
/* compatibility... */
fprintf (hfile, "\n/* for compatibility with older versions... */\n");
fprintf (hfile, "#define init_%s_err_tbl initialize_%s_error_table\n",
table_name, table_name);
fprintf (hfile, "#define %s_err_base ERROR_TABLE_BASE_%s\n", table_name,
table_name);
fclose(hfile); /* bye bye include file */
return 0;
}
int yyerror(s) char *s; {
fputs(s, stderr);
fprintf(stderr, "\nLine number %d; last token was '%s'\n",
yylineno, current_token);
}

View File

@ -0,0 +1,20 @@
/*
* definitions common to the source files of the error table compiler
*/
#ifndef __STDC__
/* loser */
#undef const
#define const
#endif
enum lang {
lang_C, /* ANSI C (default) */
lang_KRC, /* C: ANSI + K&R */
lang_CPP /* C++ */
};
int debug; /* dump debugging info? */
char *filename; /* error table source */
enum lang language;
const char *whoami;

View File

@ -56,23 +56,33 @@ description : QUOTED_STRING
%%
/*
*
* Copyright 1986, 1987 by the MIT Student Information Processing Board
* For copyright info, see Copyright.SIPB.
*
* For copyright info, see mit-sipb-copyright.h.
*/
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/time.h>
#include "internal.h"
#include "error_table.h"
#include "mit-sipb-copyright.h"
#ifndef lint
static char const rcsid_error_table_y[] =
"$Header: error_table.y,v 1.7 89/01/01 07:23:17 raeburn Locked $";
#endif
char *malloc(), *realloc();
extern FILE *hfile, *cfile;
static long gensym_n = 0;
char *
gensym(x)
char *x;
char const *x;
{
char *symbol;
if (!gensym_n) {
@ -89,7 +99,7 @@ gensym(x)
char *
ds(string)
char *string;
char const *string;
{
char *rv;
rv = malloc(strlen(string)+1);
@ -99,7 +109,7 @@ ds(string)
char *
quote(string)
char *string;
char const *string;
{
char *rv;
rv = malloc(strlen(string)+3);
@ -109,12 +119,12 @@ quote(string)
return(rv);
}
int table_number;
long table_number;
int current = 0;
char **error_codes = (char **)NULL;
add_ec(name, description)
char *name, *description;
char const *name, *description;
{
fprintf(cfile, "\t\"%s\",\n", description);
if (error_codes == (char **)NULL) {
@ -128,9 +138,9 @@ add_ec(name, description)
}
add_ec_val(name, val, description)
char *name, *val, *description;
char const *name, *val, *description;
{
int ncurrent = atoi(val);
const int ncurrent = atoi(val);
if (ncurrent < current) {
printf("Error code %s (%d) out of order", name,
current);
@ -156,8 +166,8 @@ put_ecs()
int i;
for (i = 0; i < current; i++) {
if (error_codes[i] != (char *)NULL)
fprintf(hfile, "#define %-40s ((%s)%d)\n",
error_codes[i], ERROR_CODE, table_number + i);
fprintf(hfile, "#define %-40s (%ldL)\n",
error_codes[i], table_number + i);
}
}
@ -168,26 +178,43 @@ put_ecs()
* digits -> 53-62
* underscore-> 63
*/
int
char_to_num(c)
static const char char_set[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
int char_to_num(c)
char c;
{
if (isupper(c))
return(c-'A'+1);
else if (islower(c))
return(c-'a'+27);
else if (isdigit(c))
return(c-'0'+53);
else {
fprintf(stderr, "Illegal character in name: %c\n", c);
exit(1);
/*NOTREACHED*/
const char *where;
int diff;
where = strchr (char_set, c);
if (where) {
diff = where - char_set + 1;
assert (diff < (1 << ERRCODE_RANGE));
return diff;
}
else if (isprint (c))
fprintf (stderr,
"Illegal character `%c' in error table name\n",
c);
else
fprintf (stderr,
"Illegal character %03o in error table name\n",
c);
exit (1);
}
set_table_num(string)
char *string;
{
if (char_to_num (string[0]) > char_to_num ('z')) {
fprintf (stderr, "%s%s%s%s",
"First character of error table name must be ",
"a letter; name ``",
string, "'' rejected\n");
exit (1);
}
if (strlen(string) > 4) {
fprintf(stderr, "Table name %s too long, truncated ",
string);

View File

@ -1,9 +1,4 @@
%{
extern int yylineno;
int yylineno = 1;
%}
PC [^\"\n]
PC [^\"]
AN [A-Z_a-z0-9]
%%
@ -13,8 +8,7 @@ error_code return ERROR_CODE_ENTRY;
ec return ERROR_CODE_ENTRY;
end return END;
[\t ]+ ;
\n ++yylineno;
[\t\n ] ;
\"{PC}*\" { register char *p; yylval.dynstr = ds(yytext+1);
if (p=rindex(yylval.dynstr, '"')) *p='\0';
@ -23,7 +17,10 @@ end return END;
{AN}* { yylval.dynstr = ds(yytext); return STRING; }
#.*\n ++yylineno;
#.*\n ;
. { return (*yytext); }
%%
#ifndef lint
static char rcsid_et_lex_lex_l[] = "$Header: et_lex.lex.l,v 1.3 87/10/31 06:28:05 raeburn Exp $";
#endif

View File

@ -0,0 +1,19 @@
/*
Copyright 1987, 1988 by the Student Information Processing Board
of the Massachusetts Institute of Technology
Permission to use, copy, modify, and distribute this software
and its documentation for any purpose and without fee is
hereby granted, provided that the above copyright notice
appear in all copies and that both that copyright notice and
this permission notice appear in supporting documentation,
and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.
M.I.T. and the M.I.T. S.I.P.B. make no representations about
the suitability of this software for any purpose. It is
provided "as is" without express or implied warranty.
*/