formats introduced
This commit is contained in:
parent
bcb3b108a5
commit
ac21f8d98a
7 changed files with 355 additions and 141 deletions
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
# Machine and environ dependent definitions
|
# Machine and environ dependent definitions
|
||||||
EMHOME = /usr/em
|
EMHOME = /usr/em
|
||||||
LPASS1 = ../lpass1
|
LPASS1 = $(EMHOME)/lang/cem/cemcom
|
||||||
|
|
||||||
# Libraries and EM interface definitions
|
# Libraries and EM interface definitions
|
||||||
SYSLIB = $(EMHOME)/modules/lib/libsystem.a
|
SYSLIB = $(EMHOME)/modules/lib/libsystem.a
|
||||||
|
@ -24,12 +24,13 @@ CFLAGS = -I$(EMHOME)/modules/h -I$(EMHOME)/modules/pkg -I/usr/include
|
||||||
.str.h:
|
.str.h:
|
||||||
$(LPASS1)/make.allocd <$*.str >$*.h
|
$(LPASS1)/make.allocd <$*.str >$*.h
|
||||||
|
|
||||||
SRC = lpass2.c read.c report.c class.c
|
SRC = lpass2.c checkargs.c read.c report.c class.c l_print3ack.c
|
||||||
OBJ = lpass2.o read.o report.o class.o
|
OBJ = lpass2.o checkargs.o read.o report.o class.o l_print3ack.o
|
||||||
|
|
||||||
test: lpass2
|
test: lpass2
|
||||||
make lint
|
lpass2 -xh <.i
|
||||||
# lpass2 -xh <.i
|
# make lint
|
||||||
|
|
||||||
|
|
||||||
lpass2: $(OBJ) Makefile next.o
|
lpass2: $(OBJ) Makefile next.o
|
||||||
$(CC) $(COPTIONS) $(LDFLAGS) $(OBJ) next.o $(LLIBS) -o lpass2
|
$(CC) $(COPTIONS) $(LDFLAGS) $(OBJ) next.o $(LLIBS) -o lpass2
|
||||||
|
|
248
lang/cem/lint/lpass2/checkargs.c
Normal file
248
lang/cem/lint/lpass2/checkargs.c
Normal file
|
@ -0,0 +1,248 @@
|
||||||
|
/*
|
||||||
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||||
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||||
|
*/
|
||||||
|
/* $Header$ */
|
||||||
|
|
||||||
|
/******** A R G U M E N T T Y P E C H E C K I N G ********/
|
||||||
|
|
||||||
|
#include "private.h"
|
||||||
|
#include "inpdef.h"
|
||||||
|
|
||||||
|
extern char *strcpy();
|
||||||
|
|
||||||
|
#define streq(s1,s2) (strcmp(s1, s2) == 0)
|
||||||
|
|
||||||
|
/* a format is developed into a normal parameter definition */
|
||||||
|
PRIVATE int is_formatargs; /* present or not */
|
||||||
|
PRIVATE char formatargs[1000]; /* the definitions */
|
||||||
|
|
||||||
|
PRIVATE chk_argtps();
|
||||||
|
PRIVATE char *next_atype();
|
||||||
|
PRIVATE int type_match();
|
||||||
|
|
||||||
|
int
|
||||||
|
type_equal(act, form)
|
||||||
|
char *act, *form;
|
||||||
|
{
|
||||||
|
return streq(act, form)
|
||||||
|
|| streq(act, "erroneous")
|
||||||
|
|| streq(form, "erroneous");
|
||||||
|
}
|
||||||
|
|
||||||
|
chk_args(id, def)
|
||||||
|
struct inpdef *id, *def;
|
||||||
|
{
|
||||||
|
char *act_tp = id->id_argtps;
|
||||||
|
int nrargs = 0; /* number of args */
|
||||||
|
|
||||||
|
/* clear format */
|
||||||
|
is_formatargs = 0;
|
||||||
|
|
||||||
|
/* check normal arguments */
|
||||||
|
chk_argtps(id, def, &nrargs, act_tp, def->id_argtps);
|
||||||
|
|
||||||
|
if (is_formatargs) {
|
||||||
|
/* there was a format */
|
||||||
|
register int i;
|
||||||
|
|
||||||
|
/* skip over the actuals already covered */
|
||||||
|
for (i = 0; i < nrargs; i++) {
|
||||||
|
act_tp = next_atype(act_tp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* and check the format arguments */
|
||||||
|
chk_argtps(id, (struct inpdef *)0, &nrargs,
|
||||||
|
act_tp, &formatargs[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PRIVATE chk_argtps(id, def, nrargs, act_tp, form_tp)
|
||||||
|
struct inpdef *id; /* the actual call */
|
||||||
|
struct inpdef *def; /* 0 for format-derived definition */
|
||||||
|
int *nrargs; /* in-out parameter, counting */
|
||||||
|
char *act_tp; /* actual types */
|
||||||
|
char *form_tp; /* formal type definitions */
|
||||||
|
{
|
||||||
|
while (*act_tp && *form_tp) {
|
||||||
|
register char *act_start = act_tp;
|
||||||
|
register char *form_start = form_tp;
|
||||||
|
|
||||||
|
/* isolate actual argument type */
|
||||||
|
act_tp = next_atype(act_tp);
|
||||||
|
act_tp[-1] = '\0';
|
||||||
|
|
||||||
|
/* isolate formal argument type */
|
||||||
|
form_tp = next_atype(form_tp);
|
||||||
|
form_tp[-1] = '\0';
|
||||||
|
|
||||||
|
(*nrargs)++;
|
||||||
|
if (!type_match(id, act_start, form_start)) {
|
||||||
|
report("%L: arg %d of %s differs from that in %L",
|
||||||
|
id, *nrargs, id->id_name, def);
|
||||||
|
}
|
||||||
|
act_tp[-1] = ':';
|
||||||
|
form_tp[-1] = ':';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*form_tp) {
|
||||||
|
/* formal type definitions not exhausted */
|
||||||
|
report("%L: %s has fewer arguments than in %L",
|
||||||
|
id, id->id_name, def);
|
||||||
|
}
|
||||||
|
if (*act_tp) {
|
||||||
|
/* actual types not exhausted */
|
||||||
|
if (def && def->id_nrargs < 0) {
|
||||||
|
/* the function had VARARGS */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
report("%L: %s has more arguments than in %L",
|
||||||
|
id, id->id_name, def);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PRIVATE char *
|
||||||
|
next_atype(tp)
|
||||||
|
char *tp;
|
||||||
|
{
|
||||||
|
while (*tp && *tp != ':') {
|
||||||
|
tp++;
|
||||||
|
}
|
||||||
|
if (*tp == ':') {
|
||||||
|
tp++;
|
||||||
|
}
|
||||||
|
return tp;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
PRIVATE type_match(id, act, form)
|
||||||
|
struct inpdef *id;
|
||||||
|
char *act, *form;
|
||||||
|
{
|
||||||
|
if (form[0] == '"' && act[0] == '"') {
|
||||||
|
conv_format(id, act, form);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (form[0] == '"' && streq(act, "char*"))
|
||||||
|
|| (act[0] == '"' && streq(form, "char*"))
|
||||||
|
) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type_equal(act, form))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (act[0] == '+') {
|
||||||
|
/* a non-negative constant */
|
||||||
|
/* might be signed or unsigned */
|
||||||
|
if (type_equal(&act[1], form))
|
||||||
|
return 1;
|
||||||
|
if ( strncmp(form, "unsigned ", strlen("unsigned ")) == 0
|
||||||
|
&& type_equal(&act[1], &form[strlen("unsigned ")])
|
||||||
|
) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRIVATE conv_format(id, act, form)
|
||||||
|
struct inpdef *id;
|
||||||
|
char *act, *form;
|
||||||
|
{
|
||||||
|
/* convert the actual format into a def-list, using the
|
||||||
|
formal format (form) as a map to convert from %X to type
|
||||||
|
*/
|
||||||
|
register char *fmt = &formatargs[0];
|
||||||
|
|
||||||
|
is_formatargs = 1;
|
||||||
|
while (*act) {
|
||||||
|
register char *map;
|
||||||
|
|
||||||
|
/* find next conversion specification */
|
||||||
|
while (*act && *act != '%') {
|
||||||
|
act++;
|
||||||
|
}
|
||||||
|
if (*act++ != '%')
|
||||||
|
break;
|
||||||
|
if (*act == '%') {
|
||||||
|
/* %% */
|
||||||
|
act++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* process options */
|
||||||
|
if (*act && *act == '-') {
|
||||||
|
act++;
|
||||||
|
}
|
||||||
|
while (*act && ('0' <= *act && *act <= '9')) {
|
||||||
|
act++;
|
||||||
|
}
|
||||||
|
if (*act == '*') {
|
||||||
|
act++;
|
||||||
|
strcpy(fmt, "int:");
|
||||||
|
fmt += 4;
|
||||||
|
}
|
||||||
|
if (*act && *act == '.') {
|
||||||
|
act++;
|
||||||
|
}
|
||||||
|
while (*act && ('0' <= *act && *act <= '9')) {
|
||||||
|
act++;
|
||||||
|
}
|
||||||
|
if (*act == '*') {
|
||||||
|
act++;
|
||||||
|
strcpy(fmt, "int:");
|
||||||
|
fmt += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
map = form;
|
||||||
|
while (*map) {
|
||||||
|
register char *cs = act;
|
||||||
|
|
||||||
|
/* find next conversion mapping */
|
||||||
|
while (*map && *map != '%') {
|
||||||
|
map++;
|
||||||
|
}
|
||||||
|
if (*map++ != '%') {
|
||||||
|
/* we ran off the map */
|
||||||
|
report("%L: unknown conversion specification in format",
|
||||||
|
id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*map && *map != '=') {
|
||||||
|
register int match = 0;
|
||||||
|
|
||||||
|
if (*map == '[') {
|
||||||
|
while (*map && *map != ']') {
|
||||||
|
if (*map == *cs) {
|
||||||
|
match = 1;
|
||||||
|
}
|
||||||
|
map++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
match = (*map == *cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match) {
|
||||||
|
map++, cs++;
|
||||||
|
}
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
if (*map++ == '=') {
|
||||||
|
/* found the type belonging to %*cs */
|
||||||
|
while (*map && *map != '%' && *map != '"') {
|
||||||
|
*fmt++ = *map++;
|
||||||
|
}
|
||||||
|
*fmt++ = ':';
|
||||||
|
act = cs;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*fmt++ = '\0';
|
||||||
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
class[] contains a bit pattern for each letter, with those bits set
|
class[] contains a bit pattern for each letter, with those bits set
|
||||||
that correspond to the lint class meaning of the letter.
|
that correspond to the lint class meaning of the letter.
|
||||||
|
|
||||||
This facility is used through the macro is_class(inpdef_var, CL_???)
|
This facility is used through the macro is_class(inpdef_var, CL_XXX)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CL_DEF (1<<0)
|
#define CL_DEF (1<<0)
|
||||||
|
|
30
lang/cem/lint/lpass2/l_print3ack.c
Normal file
30
lang/cem/lint/lpass2/l_print3ack.c
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||||
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||||
|
*/
|
||||||
|
/* $Header$ */
|
||||||
|
|
||||||
|
/* A C K P R I N T M O D U L E D E F I N T I O N S */
|
||||||
|
|
||||||
|
#ifdef lint
|
||||||
|
|
||||||
|
#include <system.h>
|
||||||
|
|
||||||
|
/* LINTLIBRARY */
|
||||||
|
|
||||||
|
/* FORMAT0 $
|
||||||
|
%[bdox] = int %l[bdox] = long
|
||||||
|
%c = int %s = char *
|
||||||
|
%u = unsigned int
|
||||||
|
$ */
|
||||||
|
print(format) char *format; { ; }
|
||||||
|
|
||||||
|
/* FORMAT1 */
|
||||||
|
fprint(filep, format) File *filep; char *format; { ; }
|
||||||
|
/* FORMAT1 */
|
||||||
|
sprint(s, format) char *s; char *format; { ; }
|
||||||
|
/* FORMAT1 */
|
||||||
|
doprnt(filep, format) File *filep; char *format; { ; }
|
||||||
|
|
||||||
|
#endif lint
|
||||||
|
|
|
@ -15,13 +15,11 @@
|
||||||
extern char *strcpy();
|
extern char *strcpy();
|
||||||
|
|
||||||
#define streq(s1,s2) (strcmp(s1, s2) == 0)
|
#define streq(s1,s2) (strcmp(s1, s2) == 0)
|
||||||
#define min(a,b) ((a) <= (b) ? (a) : (b))
|
|
||||||
|
|
||||||
PRIVATE char cur_name[NAMESIZE];
|
PRIVATE char cur_name[NAMESIZE];
|
||||||
PRIVATE struct inpdef *dot, *lib, *ext, *sta;
|
PRIVATE struct inpdef *dot, *lib, *ext, *sta;
|
||||||
|
|
||||||
PRIVATE check_args();
|
PRIVATE chk_def();
|
||||||
PRIVATE check_def();
|
|
||||||
PRIVATE ext_decls();
|
PRIVATE ext_decls();
|
||||||
PRIVATE ext_def();
|
PRIVATE ext_def();
|
||||||
PRIVATE get_dot();
|
PRIVATE get_dot();
|
||||||
|
@ -32,8 +30,6 @@ PRIVATE one_func_call();
|
||||||
PRIVATE one_var_usage();
|
PRIVATE one_var_usage();
|
||||||
PRIVATE stat_def();
|
PRIVATE stat_def();
|
||||||
PRIVATE statics();
|
PRIVATE statics();
|
||||||
PRIVATE int type_equal();
|
|
||||||
PRIVATE int type_match();
|
|
||||||
PRIVATE usage();
|
PRIVATE usage();
|
||||||
|
|
||||||
#define same_name() (dot && streq(cur_name, dot->id_name))
|
#define same_name() (dot && streq(cur_name, dot->id_name))
|
||||||
|
@ -67,7 +63,7 @@ main(argc, argv)
|
||||||
ext_decls();
|
ext_decls();
|
||||||
usage(0);
|
usage(0);
|
||||||
if (ext)
|
if (ext)
|
||||||
check_def(ext);
|
chk_def(ext);
|
||||||
statics();
|
statics();
|
||||||
if (same_name()) {
|
if (same_name()) {
|
||||||
/* there are more lines for this name that have
|
/* there are more lines for this name that have
|
||||||
|
@ -199,6 +195,7 @@ PRIVATE one_ext_decl(kind, other_kind, other_class)
|
||||||
report("%L: %s %s %s as %s at %L",
|
report("%L: %s %s %s as %s at %L",
|
||||||
dot, kind, dot->id_name, defdec(def), other_kind, def);
|
dot, kind, dot->id_name, defdec(def), other_kind, def);
|
||||||
/* no further testing possible */
|
/* no further testing possible */
|
||||||
|
get_dot();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,7 +261,7 @@ PRIVATE one_func_call(def)
|
||||||
def->id_called = 1;
|
def->id_called = 1;
|
||||||
|
|
||||||
if (def->id_args) {
|
if (def->id_args) {
|
||||||
check_args(dot, def);
|
chk_args(dot, def);
|
||||||
if ( dot->id_valused == USED
|
if ( dot->id_valused == USED
|
||||||
&& def->id_valreturned == NOVALRETURNED
|
&& def->id_valreturned == NOVALRETURNED
|
||||||
) {
|
) {
|
||||||
|
@ -284,7 +281,7 @@ PRIVATE one_func_call(def)
|
||||||
def->id_voided = 1;
|
def->id_voided = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
panic("invalid dot->id_valused in check");
|
panic("invalid dot->id_valused in one_func_call()");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,7 +323,7 @@ PRIVATE statics()
|
||||||
stat_def(stnr);
|
stat_def(stnr);
|
||||||
usage(stnr);
|
usage(stnr);
|
||||||
if (sta)
|
if (sta)
|
||||||
check_def(sta);
|
chk_def(sta);
|
||||||
|
|
||||||
if (same_obj(stnr))
|
if (same_obj(stnr))
|
||||||
panic("sequence error in input");
|
panic("sequence error in input");
|
||||||
|
@ -360,7 +357,7 @@ PRIVATE stat_def(stnr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PRIVATE check_def(def)
|
PRIVATE chk_def(def)
|
||||||
struct inpdef *def;
|
struct inpdef *def;
|
||||||
{
|
{
|
||||||
if (!def)
|
if (!def)
|
||||||
|
@ -396,104 +393,6 @@ PRIVATE check_def(def)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/******** T Y P E C H E C K I N G ********/
|
|
||||||
|
|
||||||
PRIVATE check_args(id, def)
|
|
||||||
struct inpdef *id, *def;
|
|
||||||
{
|
|
||||||
register char *act_tp = id->id_argtps;
|
|
||||||
register char *def_tp = def->id_argtps;
|
|
||||||
register int i;
|
|
||||||
register int nrargs; /* # of args to be type-checked */
|
|
||||||
register int varargs;
|
|
||||||
|
|
||||||
/* determine nrargs */
|
|
||||||
if (def->id_nrargs < 0) {
|
|
||||||
varargs = 1;
|
|
||||||
nrargs = -def->id_nrargs - 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
varargs = 0;
|
|
||||||
nrargs = def->id_nrargs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* adjust nrargs, if necessary */
|
|
||||||
if (varargs) {
|
|
||||||
if (nrargs > id->id_nrargs) {
|
|
||||||
report("%L: number of args to %s differs from %L",
|
|
||||||
id, id->id_name, def);
|
|
||||||
nrargs = id->id_nrargs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (nrargs != id->id_nrargs) {
|
|
||||||
report("%L: number of args to %s differs from %L",
|
|
||||||
id, id->id_name, def);
|
|
||||||
nrargs = min(nrargs, id->id_nrargs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 1; i <= nrargs; i++) {
|
|
||||||
register char *act_par = act_tp;
|
|
||||||
register char *def_par = def_tp;
|
|
||||||
|
|
||||||
/* isolate actual argument type */
|
|
||||||
while (*act_tp) {
|
|
||||||
if (*act_tp == ':') {
|
|
||||||
*act_tp = '\0';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
act_tp++;
|
|
||||||
}
|
|
||||||
/* isolate formal argument type */
|
|
||||||
while (*def_tp) {
|
|
||||||
if (*def_tp == ':') {
|
|
||||||
*def_tp = '\0';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
def_tp++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!type_match(act_par, def_par)) {
|
|
||||||
report("%L: arg %d of %s differs from that at %L",
|
|
||||||
id, i, id->id_name, def);
|
|
||||||
}
|
|
||||||
*act_tp++ = ':';
|
|
||||||
*def_tp++ = ':';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
PRIVATE type_equal(act, def)
|
|
||||||
char *act, *def;
|
|
||||||
{
|
|
||||||
return streq(act, def)
|
|
||||||
|| streq(act, "erroneous")
|
|
||||||
|| streq(def, "erroneous");
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
PRIVATE type_match(act, def)
|
|
||||||
char *act, *def;
|
|
||||||
{
|
|
||||||
if (type_equal(act, def))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (act[0] == '+') {
|
|
||||||
/* a non-negative constant */
|
|
||||||
/* might be signed or unsigned */
|
|
||||||
if (type_equal(&act[1], def))
|
|
||||||
return 1;
|
|
||||||
if ( strncmp(def, "unsigned ", strlen("unsigned ")) == 0
|
|
||||||
&& type_equal(&act[1], &def[strlen("unsigned ")])
|
|
||||||
) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/******** D E B U G G I N G ********/
|
/******** D E B U G G I N G ********/
|
||||||
|
|
||||||
print_id(name, id)
|
print_id(name, id)
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
#include "private.h"
|
#include "private.h"
|
||||||
|
|
||||||
PRIVATE int LineNr = 1;
|
int LineNr = 1;
|
||||||
|
|
||||||
/* Two dangerous macro's. They replace a single statement by
|
/* Two dangerous macro's. They replace a single statement by
|
||||||
* two statements
|
* two statements
|
||||||
|
@ -25,10 +25,13 @@ PRIVATE int LineNr = 1;
|
||||||
#define loadchar(ch) LoadChar(ch); if (ch=='\n') LineNr++
|
#define loadchar(ch) LoadChar(ch); if (ch=='\n') LineNr++
|
||||||
#define pushback(ch) PushBack(); if (ch=='\n') LineNr--
|
#define pushback(ch) PushBack(); if (ch=='\n') LineNr--
|
||||||
|
|
||||||
|
/* all the ReadX() functions return 0 upon EOI */
|
||||||
PRIVATE int ReadString();
|
PRIVATE int ReadString();
|
||||||
PRIVATE int ReadInt();
|
PRIVATE int ReadInt();
|
||||||
PRIVATE SkipChar();
|
|
||||||
PRIVATE int ReadArgs();
|
PRIVATE int ReadArgs();
|
||||||
|
PRIVATE int ReadArg();
|
||||||
|
|
||||||
|
PRIVATE SkipChar();
|
||||||
|
|
||||||
int
|
int
|
||||||
get_id(id)
|
get_id(id)
|
||||||
|
@ -79,20 +82,18 @@ get_id(id)
|
||||||
|
|
||||||
if (!ReadString(id->id_file, '\n', FNAMESIZE))
|
if (!ReadString(id->id_file, '\n', FNAMESIZE))
|
||||||
return 0;
|
return 0;
|
||||||
return (1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRIVATE int
|
PRIVATE int
|
||||||
ReadString(buf, delim, maxsize)
|
ReadString(buf, delim, maxsize)
|
||||||
char *buf;
|
char *buf;
|
||||||
{
|
{
|
||||||
/* Reads a string until 'delim' is encountered.
|
/* Reads a string until 'delim' is encountered; delim is
|
||||||
Delim is discarded.
|
discarded.
|
||||||
If 'maxsize-1' is exceeded, "string too long" is written
|
If 'maxsize-1' is exceeded or the string contains a newline
|
||||||
by panic().
|
(which is not delim), panic() is called.
|
||||||
A '\0' is appended to the string.
|
A '\0' is appended to the string.
|
||||||
At EOI 0 is returned, else the length of the string (including
|
|
||||||
the appended '\0') is returned.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int ch = 0;
|
int ch = 0;
|
||||||
|
@ -104,14 +105,18 @@ ReadString(buf, delim, maxsize)
|
||||||
return 0;
|
return 0;
|
||||||
if (ch == delim)
|
if (ch == delim)
|
||||||
break;
|
break;
|
||||||
|
if (ch == '\n') {
|
||||||
|
panic("newline in string");
|
||||||
|
/*NOTREACHED*/
|
||||||
|
}
|
||||||
buf[nread++] = (char)ch;
|
buf[nread++] = (char)ch;
|
||||||
}
|
}
|
||||||
buf[nread++] = '\0';
|
buf[nread++] = '\0';
|
||||||
if (ch != delim) {
|
if (ch != delim) {
|
||||||
panic("line %d: string too long: %s", LineNr, buf);
|
panic("string too long");
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
return (nread);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRIVATE int
|
PRIVATE int
|
||||||
|
@ -123,7 +128,6 @@ ReadInt(ip)
|
||||||
* Non-digits except minus-sign in front of the number are discarded.
|
* Non-digits except minus-sign in front of the number are discarded.
|
||||||
* Doesn't check on overflow.
|
* Doesn't check on overflow.
|
||||||
* Just a minus-sign is interpreted as 0. (To prevent a look-ahead.)
|
* Just a minus-sign is interpreted as 0. (To prevent a look-ahead.)
|
||||||
* At EOI 0 is returned, else 1.
|
|
||||||
*/
|
*/
|
||||||
int ch;
|
int ch;
|
||||||
int negative = 0;
|
int negative = 0;
|
||||||
|
@ -148,24 +152,12 @@ ReadInt(ip)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRIVATE SkipChar(ch)
|
|
||||||
{
|
|
||||||
int c;
|
|
||||||
|
|
||||||
loadchar(c);
|
|
||||||
if (c != ch) {
|
|
||||||
panic("line %d: bad format, '%c' expected; '%c' read",
|
|
||||||
LineNr, ch, c);
|
|
||||||
/*NOTREACHED*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PRIVATE int
|
PRIVATE int
|
||||||
ReadArgs(nrargs, buf)
|
ReadArgs(nrargs, buf)
|
||||||
char *buf;
|
char *buf;
|
||||||
{
|
{
|
||||||
/* Reads a string into buf with format
|
/* Reads a string into buf with format
|
||||||
<type1>:<type2>: ... :<typeN>:
|
<type1>:<type2>: ... :<typeN>:\0
|
||||||
Note: format must include the final colon.
|
Note: format must include the final colon.
|
||||||
*/
|
*/
|
||||||
int i;
|
int i;
|
||||||
|
@ -179,7 +171,7 @@ ReadArgs(nrargs, buf)
|
||||||
for (i = 0; i < nrargs; i++) {
|
for (i = 0; i < nrargs; i++) {
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
if (!ReadString(buf, ':', ARGTPSSIZE-charcount-1))
|
if (!ReadArg(buf, ARGTPSSIZE-charcount-1))
|
||||||
return 0;
|
return 0;
|
||||||
n = strlen(buf) + 1;
|
n = strlen(buf) + 1;
|
||||||
charcount += n;
|
charcount += n;
|
||||||
|
@ -190,3 +182,40 @@ ReadArgs(nrargs, buf)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PRIVATE int
|
||||||
|
ReadArg(buf, size)
|
||||||
|
char *buf;
|
||||||
|
int size;
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
loadchar(ch);
|
||||||
|
switch (ch) {
|
||||||
|
case '"': /* formal format or actual string */
|
||||||
|
*buf++ = ch;
|
||||||
|
if (!ReadString(buf, ch, size-1))
|
||||||
|
return 0;
|
||||||
|
buf += strlen(buf);
|
||||||
|
*buf++ = ch;
|
||||||
|
*buf++ = '\0';
|
||||||
|
SkipChar(':');
|
||||||
|
return 1;
|
||||||
|
default: /* normal type */
|
||||||
|
pushback(ch);
|
||||||
|
return ReadString(buf, ':', size);
|
||||||
|
case EOI:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PRIVATE SkipChar(ch)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
|
||||||
|
loadchar(c);
|
||||||
|
if (c != ch) {
|
||||||
|
panic("bad format, '%c' expected; '%c' read", ch, c);
|
||||||
|
/*NOTREACHED*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
#define MSGOUT STDERR /* filedes on which to write the messages */
|
#define MSGOUT STDERR /* filedes on which to write the messages */
|
||||||
#define ERROUT STDERR /* filedes on which to write the panics */
|
#define ERROUT STDERR /* filedes on which to write the panics */
|
||||||
|
|
||||||
|
extern int LineNr;
|
||||||
|
|
||||||
PRIVATE rep_loc();
|
PRIVATE rep_loc();
|
||||||
|
|
||||||
/* VARARGS */
|
/* VARARGS */
|
||||||
|
@ -90,6 +92,11 @@ PRIVATE
|
||||||
rep_loc(id)
|
rep_loc(id)
|
||||||
struct inpdef *id;
|
struct inpdef *id;
|
||||||
{
|
{
|
||||||
|
/* a definition can come from a number of places */
|
||||||
|
if (!id) {
|
||||||
|
fprint(MSGOUT, "format");
|
||||||
|
}
|
||||||
|
else
|
||||||
if (is_class(id, CL_LIB)) {
|
if (is_class(id, CL_LIB)) {
|
||||||
fprint(MSGOUT, "library file %s", id->id_file);
|
fprint(MSGOUT, "library file %s", id->id_file);
|
||||||
}
|
}
|
||||||
|
@ -103,7 +110,7 @@ rep_loc(id)
|
||||||
panic(fmt, args)
|
panic(fmt, args)
|
||||||
char *fmt;
|
char *fmt;
|
||||||
{
|
{
|
||||||
fprint(ERROUT, "PANIC, lint, pass2: ");
|
fprint(ERROUT, "PANIC, lint, pass2: line %d: ", LineNr);
|
||||||
doprnt(ERROUT, fmt, &args);
|
doprnt(ERROUT, fmt, &args);
|
||||||
fprint(ERROUT, "\n");
|
fprint(ERROUT, "\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
Loading…
Reference in a new issue