diff --git a/lang/basic/src/gencode.c b/lang/basic/src/gencode.c index 710de169d..6a500d06d 100644 --- a/lang/basic/src/gencode.c +++ b/lang/basic/src/gencode.c @@ -4,6 +4,7 @@ */ #include "bem.h" +#include "system.h" #ifndef NORSCID static char rcs_id[] = "$Id$" ; @@ -59,7 +60,7 @@ List *datalist=0; datastmt() { List *l,*l1; - extern long sys_filesize(); + /* NOSTRICT */ l= (List *) salloc(sizeof(List)); l->linenr= currline->linenr; diff --git a/lang/cem/cemcom.ansi/BigPars b/lang/cem/cemcom.ansi/BigPars index 6f4b0971d..bf92e22fe 100644 --- a/lang/cem/cemcom.ansi/BigPars +++ b/lang/cem/cemcom.ansi/BigPars @@ -1,138 +1,138 @@ -!File: lint.h -/*#define LINT 1 /* if defined, 'lint' is produced */ - - -!File: pathlength.h -#define PATHLENGTH 1024 /* max. length of path to file */ - - -!File: errout.h -#define ERROUT STDERR /* file pointer for writing messages */ -#define ERR_SHADOW 5 /* a syntax error overshadows error messages - until ERR_SHADOW symbols have been - accepted without syntax error */ - - -!File: idfsize.h -#define IDFSIZE 64 /* maximum significant length of an identifier */ - - -!File: numsize.h -#define NUMSIZE 256 /* maximum length of a numeric constant */ - - -!File: nparams.h -#define NPARAMS 32 /* maximum number of parameters */ -#define STDC_NPARAMS 31 /* ANSI limit on number of parameters */ - - -!File: ifdepth.h -#define IFDEPTH 256 /* maximum number of nested if-constructions */ - - -!File: density.h -#define DENSITY 3 /* see switch.[ch] for an explanation */ - - -!File: macbuf.h -#define LAPBUF 128 /* initial size of macro replacement buffer */ -#define ARGBUF 128 /* initial size of macro parameter buffer(s) */ - - -!File: strsize.h -#define ISTRSIZE 32 /* minimum number of bytes allocated for - storing a string */ -#define RSTRSIZE 16 /* step size in enlarging the memory for - the storage of a string */ - - -!File: trgt_sizes.h -#define MAXSIZE 8 /* the maximum of the SZ_* constants */ - -/* target machine sizes */ -#define SZ_CHAR 1 -#define SZ_SHORT 2 -#define SZ_WORD 4 -#define SZ_INT 4 -#define SZ_LONG 4 -#define SZ_FLOAT 4 -#define SZ_DOUBLE 8 -#define SZ_LNGDBL 8 /* for now */ -#define SZ_POINTER 4 - -/* target machine alignment requirements */ -#define AL_CHAR 1 -#define AL_SHORT SZ_SHORT -#define AL_WORD SZ_WORD -#define AL_INT SZ_WORD -#define AL_LONG SZ_WORD -#define AL_FLOAT SZ_WORD -#define AL_DOUBLE SZ_WORD -#define AL_LNGDBL SZ_WORD -#define AL_POINTER SZ_WORD -#define AL_STRUCT 1 -#define AL_UNION 1 - - -!File: botch_free.h -/*#define BOTCH_FREE 1 /* when defined, botch freed memory, as a check */ - - -!File: dataflow.h -#define DATAFLOW 1 /* produce some compile-time xref */ - - -!File: debug.h -/*#define DEBUG 1 /* perform various self-tests */ -#define NDEBUG 1 /* disable assertions */ - - -!File: use_tmp.h -#define PREPEND_SCOPES 1 /* collect exa, exp, ina and inp commands - and if USE_TMP is defined let them - precede the rest of the generated - compact code */ -#define USE_TMP 1 /* use C_insertpart, C_endpart mechanism - to generate EM-code in the order needed - for the code-generators. If not defined, - the old-style peephole optimizer is - needed. */ - - -!File: parbufsize.h -#define PARBUFSIZE 1024 - - -!File: textsize.h -#define ITEXTSIZE 32 /* 1st piece of memory for repl. text */ - - -!File: inputtype.h -#define INP_READ_IN_ONE 1 /* read input file in one */ - - -!File: nobitfield.h -/*#define NOBITFIELD 1 /* if NOT defined, implement bitfields */ - - -!File: spec_arith.h -/* describes internal compiler arithmetics */ -#undef SPECIAL_ARITHMETICS /* something different from native long */ - - -!File: static.h -#define GSTATIC /* for large global "static" arrays */ - - -!File: nocross.h -/*#define NOCROSS 1 /* if NOT defined, cross compiler */ - - -!File: regcount.h -/*#define REGCOUNT 1 /* count occurrences for register messages */ - - -!File: dbsymtab.h -#define DBSYMTAB 1 /* ability to produce symbol table for debugger */ - - +!File: lint.h +/*#define LINT 1 *//* if defined, 'lint' is produced */ + + +!File: pathlength.h +#define PATHLENGTH 1024 /* max. length of path to file */ + + +!File: errout.h +#define ERROUT STDERR /* file pointer for writing messages */ +#define ERR_SHADOW 5 /* a syntax error overshadows error messages + until ERR_SHADOW symbols have been + accepted without syntax error */ + + +!File: idfsize.h +#define IDFSIZE 64 /* maximum significant length of an identifier */ + + +!File: numsize.h +#define NUMSIZE 256 /* maximum length of a numeric constant */ + + +!File: nparams.h +#define NPARAMS 32 /* maximum number of parameters */ +#define STDC_NPARAMS 31 /* ANSI limit on number of parameters */ + + +!File: ifdepth.h +#define IFDEPTH 256 /* maximum number of nested if-constructions */ + + +!File: density.h +#define DENSITY 3 /* see switch.[ch] for an explanation */ + + +!File: macbuf.h +#define LAPBUF 128 /* initial size of macro replacement buffer */ +#define ARGBUF 128 /* initial size of macro parameter buffer(s) */ + + +!File: strsize.h +#define ISTRSIZE 32 /* minimum number of bytes allocated for + storing a string */ +#define RSTRSIZE 16 /* step size in enlarging the memory for + the storage of a string */ + + +!File: trgt_sizes.h +#define MAXSIZE 8 /* the maximum of the SZ_* constants */ + +/* target machine sizes */ +#define SZ_CHAR 1 +#define SZ_SHORT 2 +#define SZ_WORD 4 +#define SZ_INT 4 +#define SZ_LONG 4 +#define SZ_FLOAT 4 +#define SZ_DOUBLE 8 +#define SZ_LNGDBL 8 /* for now */ +#define SZ_POINTER 4 + +/* target machine alignment requirements */ +#define AL_CHAR 1 +#define AL_SHORT SZ_SHORT +#define AL_WORD SZ_WORD +#define AL_INT SZ_WORD +#define AL_LONG SZ_WORD +#define AL_FLOAT SZ_WORD +#define AL_DOUBLE SZ_WORD +#define AL_LNGDBL SZ_WORD +#define AL_POINTER SZ_WORD +#define AL_STRUCT 1 +#define AL_UNION 1 + + +!File: botch_free.h +/*#define BOTCH_FREE 1* *//* when defined, botch freed memory, as a check */ + + +!File: dataflow.h +#define DATAFLOW 1 /* produce some compile-time xref */ + + +!File: debug.h +/*#define DEBUG 1 *//* perform various self-tests */ +#define NDEBUG 1 /* disable assertions */ + + +!File: use_tmp.h +#define PREPEND_SCOPES 1 /* collect exa, exp, ina and inp commands + and if USE_TMP is defined let them + precede the rest of the generated + compact code */ +#define USE_TMP 1 /* use C_insertpart, C_endpart mechanism + to generate EM-code in the order needed + for the code-generators. If not defined, + the old-style peephole optimizer is + needed. */ + + +!File: parbufsize.h +#define PARBUFSIZE 1024 + + +!File: textsize.h +#define ITEXTSIZE 32 /* 1st piece of memory for repl. text */ + + +!File: inputtype.h +#define INP_READ_IN_ONE 1 /* read input file in one */ + + +!File: nobitfield.h +/*#define NOBITFIELD 1 *//* if NOT defined, implement bitfields */ + + +!File: spec_arith.h +/* describes internal compiler arithmetics */ +#undef SPECIAL_ARITHMETICS /* something different from native long */ + + +!File: static.h +#define GSTATIC /* for large global "static" arrays */ + + +!File: nocross.h +/*#define NOCROSS 1 *//* if NOT defined, cross compiler */ + + +!File: regcount.h +/*#define REGCOUNT 1 *//* count occurrences for register messages */ + + +!File: dbsymtab.h +#define DBSYMTAB 1 /* ability to produce symbol table for debugger */ + + diff --git a/lang/cem/cemcom.ansi/LLlex.c b/lang/cem/cemcom.ansi/LLlex.c index f0f5d5c24..d4be03449 100644 --- a/lang/cem/cemcom.ansi/LLlex.c +++ b/lang/cem/cemcom.ansi/LLlex.c @@ -17,6 +17,8 @@ #include "Lpars.h" #include "class.h" #include "sizes.h" +#include "error.h" +#include "domacro.h" #include "specials.h" /* registration of special identifiers */ /* Data about the token yielded */ @@ -41,7 +43,16 @@ extern arith full_mask[]; extern int lint_skip_comment; #endif -int LLlex() + +/* Internal function declarations */ +static arith char_constant(char*); +static char* string_token(char *, int , int *); +static int quoted(register int); +static int hex_val(register int); +static void strflt2tok(char [], struct token *); +static void strint2tok(char [], struct token *); + +int LLlex(void) { /* LLlex() plays the role of Lexical Analyzer for the C parser. The look-ahead and putting aside of tokens are taken into @@ -72,10 +83,8 @@ int LLlex() return DOT; } -char* string_token(); -arith char_constant(); -int GetToken(ptok) register struct token* ptok; +int GetToken(register struct token* ptok) { /* GetToken() is the actual token recognizer. It calls the control line interpreter if it encounters a "\n{w}*#" @@ -379,7 +388,7 @@ go_on: /* rescan, the following character has been read */ /*NOTREACHED*/ } -arith char_constant(nm) char* nm; +static arith char_constant(char* nm) { register arith val = 0; register int ch; @@ -413,8 +422,7 @@ arith char_constant(nm) char* nm; return val; } -char* string_token(nm, stop_char, plen) char* nm; -int* plen; +static char* string_token(char *nm, int stop_char, int *plen) { register int ch; register int str_size; @@ -447,7 +455,7 @@ int* plen; return str; } -int quoted(ch) register int ch; +static int quoted(register int ch) { /* quoted() replaces an escaped character sequence by the character meant. @@ -510,12 +518,12 @@ int quoted(ch) register int ch; return ch & 0377; } -int hex_val(ch) register int ch; +static int hex_val(register int ch) { return is_dig(ch) ? ch - '0' : is_hex(ch) ? (ch - 'a' + 10) & 017 : -1; } -int GetChar() +int GetChar(void) { /* The routines GetChar and trigraph parses the trigraph sequences and removes occurences of \\\n. @@ -529,8 +537,7 @@ int GetChar() /* strflt2tok only checks the syntax of the floating-point number and * selects the right type for the number. */ -strflt2tok(fltbuf, ptok) char fltbuf[]; -struct token* ptok; +static void strflt2tok(char fltbuf[], struct token* ptok) { register char* cp = fltbuf; int malformed = 0; @@ -584,8 +591,7 @@ struct token* ptok; } } -strint2tok(intbuf, ptok) char intbuf[]; -struct token* ptok; +static void strint2tok(char intbuf[], struct token* ptok) { register char* cp = intbuf; int base = 10; diff --git a/lang/cem/cemcom.ansi/LLlex.h b/lang/cem/cemcom.ansi/LLlex.h index 678149d9f..a52f5ed78 100644 --- a/lang/cem/cemcom.ansi/LLlex.h +++ b/lang/cem/cemcom.ansi/LLlex.h @@ -9,6 +9,8 @@ called a "symbol", but it may have other information associated to it. */ +#ifndef LLLEX_H_ +#define LLLEX_H_ #include "file_info.h" @@ -56,3 +58,9 @@ extern int err_occurred; /* "error.c" */ #define ASIDE aside.tk_symb #define EOF (-1) + +int GetChar(void); +int LLlex(void); +int GetToken(register struct token* ptok); + +#endif /* LLLEX_H_ */ diff --git a/lang/cem/cemcom.ansi/LLmessage.c b/lang/cem/cemcom.ansi/LLmessage.c index c88c5eb24..299d4a82d 100644 --- a/lang/cem/cemcom.ansi/LLmessage.c +++ b/lang/cem/cemcom.ansi/LLmessage.c @@ -10,21 +10,28 @@ #include "arith.h" #include "LLlex.h" #include "Lpars.h" +#include "error.h" extern char *symbol2str(); -LLmessage(tk) { +static void insert_token(int ); + +void LLmessage(int tk) +{ err_occurred = 1; - if (tk < 0) { + if (tk < 0) + { error("end of file expected"); } - else if (tk) { + else if (tk) + { #ifndef LLNONCORR error("%s missing before %s", symbol2str(tk), symbol2str(DOT)); #endif insert_token(tk); } - else { + else + { #ifndef LLNONCORR error("%s deleted", symbol2str(DOT)); #else @@ -34,14 +41,14 @@ LLmessage(tk) { tk_nmb_at_last_syn_err = token_nmb; } -insert_token(tk) - int tk; +static void insert_token(int tk) { aside = dot; DOT = tk; - switch (tk) { + switch (tk) + { /* The operands need some body */ case IDENTIFIER: dot.tk_idf = gen_idf(); diff --git a/lang/cem/cemcom.ansi/arith.c b/lang/cem/cemcom.ansi/arith.c index b402e4b35..10d149911 100644 --- a/lang/cem/cemcom.ansi/arith.c +++ b/lang/cem/cemcom.ansi/arith.c @@ -24,16 +24,19 @@ #include "Lpars.h" #include "field.h" #include "mes.h" +#include "cstoper.h" +#include "ch3bin.h" +#include "ch3.h" +#include "error.h" + extern char *symbol2str(); extern char options[]; extern arith flt_flt2arith(); extern label code_string(); -void -arithbalance(e1p, oper, e2p) /* 3.1.2.5 */ - register struct expr **e1p, **e2p; - int oper; +/* 3.1.2.5 */ +void arithbalance(register struct expr **e1p, int oper, register struct expr **e2p) { /* The expressions *e1p and *e2p are balanced to be operands of the arithmetic operator oper. @@ -171,8 +174,7 @@ arithbalance(e1p, oper, e2p) /* 3.1.2.5 */ } } -relbalance(e1p, oper, e2p) - register struct expr **e1p, **e2p; +void relbalance(register struct expr **e1p, int oper, register struct expr **e2p) { /* The expressions *e1p and *e2p are balanced to be operands of the relational operator oper, or the ':'. @@ -204,9 +206,7 @@ relbalance(e1p, oper, e2p) arithbalance(e1p, oper, e2p); } -ch3pointer(expp, oper, tp) - struct expr **expp; - register struct type *tp; +void ch3pointer(struct expr **expp, int oper, register struct type *tp) { /* Checks whether *expp may be compared to tp using oper, as described in chapter 3.3.8 and 3.3.9. @@ -238,9 +238,7 @@ ch3pointer(expp, oper, tp) } int -any2arith(expp, oper) - register struct expr **expp; - register int oper; +any2arith(register struct expr **expp, register int oper) { /* Turns any expression into int_type, long_type, float_type, double_type or lngdbl_type. @@ -295,8 +293,7 @@ any2arith(expp, oper) return (*expp)->ex_type->tp_fund; } -erroneous2int(expp) - struct expr **expp; +void erroneous2int(struct expr **expp) { /* the (erroneous) expression *expp is replaced by an int expression @@ -310,11 +307,7 @@ erroneous2int(expp) *expp = exp; } -struct expr * -arith2arith(tp, oper, expr) - struct type *tp; - int oper; - register struct expr *expr; +struct expr *arith2arith(struct type *tp, int oper, register struct expr *expr) { /* arith2arith constructs a new expression containing a run-time conversion between some arithmetic types. @@ -328,10 +321,7 @@ arith2arith(tp, oper, expr) return new_oper(tp, new, oper, expr); } -int -int2int(expp, tp) - struct expr **expp; - register struct type *tp; +int int2int(struct expr **expp, register struct type *tp) { /* The expression *expp, which is of some integral type, is converted to the integral type tp. @@ -369,9 +359,7 @@ int2int(expp, tp) /* With compile-time constants, we don't set fp_used, since this is done * only when necessary in eval.c. */ -int2float(expp, tp) - register struct expr **expp; - struct type *tp; +void int2float(register struct expr **expp, struct type *tp) { /* The expression *expp, which is of some integral type, is converted to the floating type tp. @@ -390,9 +378,7 @@ int2float(expp, tp) } } -float2int(expp, tp) - struct expr **expp; - struct type *tp; +void float2int(struct expr **expp, struct type *tp) { /* The expression *expp, which is of some floating type, is converted to the integral type tp. @@ -418,9 +404,7 @@ float2int(expp, tp) } } -float2float(expp, tp) - register struct expr **expp; - struct type *tp; +void float2float(register struct expr **expp, struct type *tp) { /* The expression *expp, which is of some floating type, is converted to the floating type tp. @@ -436,8 +420,7 @@ float2float(expp, tp) } } -array2pointer(exp) - register struct expr *exp; +void array2pointer(register struct expr *exp) { /* The expression, which must be an array, is converted to a pointer. @@ -447,8 +430,7 @@ array2pointer(exp) , (arith)0, NO_PROTO); } -function2pointer(exp) - register struct expr *exp; +void function2pointer(register struct expr *exp) { /* The expression, which must be a function, is converted to a pointer to the function. @@ -457,8 +439,7 @@ function2pointer(exp) (arith)0, NO_PROTO); } -string2pointer(ex) - register struct expr *ex; +void string2pointer(register struct expr *ex) { /* The expression, which must be a string constant, is converted to a pointer to the string-containing area. @@ -472,9 +453,7 @@ string2pointer(ex) ex->VL_VALUE = (arith)0; } -opnd2integral(expp, oper) - register struct expr **expp; - int oper; +void opnd2integral(register struct expr **expp, int oper) { register int fund = (*expp)->ex_type->tp_fund; @@ -486,9 +465,7 @@ opnd2integral(expp, oper) } } -opnd2logical(expp, oper) - register struct expr **expp; - int oper; +void opnd2logical(register struct expr **expp, int oper) { int fund = (*expp)->ex_type->tp_fund; @@ -525,8 +502,7 @@ opnd2logical(expp, oper) } void -opnd2test(expp, oper) - register struct expr **expp; +opnd2test(register struct expr **expp, int oper) { opnd2logical(expp, oper); if ((*expp)->ex_class == Oper) { @@ -550,9 +526,7 @@ opnd2test(expp, oper) ch3bin(expp, NOTEQUAL, intexpr((arith)0, INT)); } -void -any2opnd(expp, oper) - register struct expr **expp; +void any2opnd(register struct expr **expp, int oper) { if (!*expp) return; @@ -584,8 +558,7 @@ any2opnd(expp, oper) } } -any2parameter(expp) - register struct expr **expp; +void any2parameter(register struct expr **expp) { /* To handle default argument promotions */ @@ -598,8 +571,7 @@ any2parameter(expp) } #ifndef NOBITFIELD -field2arith(expp) - register struct expr **expp; +void field2arith(register struct expr **expp) { /* The expression to extract the bitfield value from the memory word is put in the tree. @@ -630,8 +602,7 @@ field2arith(expp) /* switch_sign_fp() negates the given floating constant expression, * and frees the string representing the old value. */ -switch_sign_fp(expr) - register struct expr *expr; +void switch_sign_fp(register struct expr *expr) { flt_umin(&(expr->FL_ARITH)); } diff --git a/lang/cem/cemcom.ansi/arith.h b/lang/cem/cemcom.ansi/arith.h index 4bb403458..65b0003de 100644 --- a/lang/cem/cemcom.ansi/arith.h +++ b/lang/cem/cemcom.ansi/arith.h @@ -12,12 +12,15 @@ to save storage on small machines, SPECIAL_ARITHMETICS will be handy. */ +#ifndef ARITH_H_ +#define ARITH_H_ #include "parameters.h" #ifndef SPECIAL_ARITHMETICS -#include /* obtain definition of "arith" */ +#include /* obtain definition of "arith" */ +#include #else /* SPECIAL_ARITHMETICS */ @@ -27,6 +30,32 @@ #endif /* SPECIAL_ARITHMETICS */ +struct expr; +struct type; + #define arith_size (sizeof(arith)) #define arith_sign ((arith) 1 << (arith_size * 8 - 1)) #define max_arith (~arith_sign) + +void arithbalance(register struct expr **e1p, int oper, register struct expr **e2p); +void relbalance(register struct expr **e1p, int oper, register struct expr **e2p); +void ch3pointer(struct expr **expp, int oper, register struct type *tp); +int any2arith(register struct expr **expp, register int oper); +void erroneous2int(struct expr **expp); +struct expr *arith2arith(struct type *tp, int oper, register struct expr *expr); +int int2int(struct expr **expp, register struct type *tp); +void int2float(register struct expr **expp, struct type *tp); +void float2int(struct expr **expp, struct type *tp); +void float2float(register struct expr **expp, struct type *tp); +void array2pointer(register struct expr *exp); +void function2pointer(register struct expr *exp); +void string2pointer(register struct expr *ex); +void opnd2integral(register struct expr **expp, int oper); +void opnd2logical(register struct expr **expp, int oper); +void opnd2test(register struct expr **expp, int oper); +void any2opnd(register struct expr **expp, int oper); +void any2parameter(register struct expr **expp); +void field2arith(register struct expr **expp); +void switch_sign_fp(register struct expr *expr); + +#endif /* ARITH_H_ */ diff --git a/lang/cem/cemcom.ansi/blocks.c b/lang/cem/cemcom.ansi/blocks.c index 6d75a3670..d4df8b73e 100644 --- a/lang/cem/cemcom.ansi/blocks.c +++ b/lang/cem/cemcom.ansi/blocks.c @@ -18,7 +18,10 @@ #include "label.h" #include "stack.h" #include "Lpars.h" -extern arith NewLocal(); +#include "blocks.h" +#include "macro.h" +#include "util.h" + #define LocalPtrVar() NewLocal(pointer_size, pointer_align, reg_pointer, REGISTER) #define LocalIntVar() NewLocal(int_size, int_align, reg_any, REGISTER) #endif /* STB */ @@ -52,9 +55,7 @@ extern arith NewLocal(); while we need a loop to store the stack block into a memory object. */ -suitable_sz(sz, al) - arith sz; - int al; +int suitable_sz(arith sz, int al) { return ((int)sz % (int)word_size == 0 && al % word_align == 0) || ( @@ -64,9 +65,7 @@ suitable_sz(sz, al) ); } -store_block(sz, al) - arith sz; - int al; +void store_block(arith sz, int al) { if (suitable_sz(sz, al)) C_sti(sz); @@ -102,9 +101,7 @@ store_block(sz, al) } } -load_block(sz, al) - arith sz; - int al; +void load_block(arith sz, int al) { if (suitable_sz(sz, al)) @@ -138,9 +135,7 @@ load_block(sz, al) } } -copy_block(sz, al) - arith sz; - int al; +void copy_block(arith sz, int al) { if (suitable_sz(sz, al)) @@ -167,8 +162,7 @@ copy_block(sz, al) } #ifndef STB -copy_loop(sz, src, dst) - arith sz, src, dst; +void copy_loop(arith sz, arith src, arith dst) { /* generate inline byte-copy loop */ label l_cont = text_label(), l_stop = text_label(); diff --git a/lang/cem/cemcom.ansi/blocks.h b/lang/cem/cemcom.ansi/blocks.h new file mode 100644 index 000000000..45f18d491 --- /dev/null +++ b/lang/cem/cemcom.ansi/blocks.h @@ -0,0 +1,20 @@ +/* Copyright (c) 2019 ACK Project. + * See the copyright notice in the ACK home directory, + * in the file "Copyright". + * + * Created on: 2019-02-06 + * + */ +#ifndef BLOCKS_H_ +#define BLOCKS_H_ + +#include "parameters.h" +#include "arith.h" + +int suitable_sz(arith sz, int al); +void store_block(arith sz, int al); +void load_block(arith sz, int al); +void copy_block(arith sz, int al); +void copy_loop(arith sz, arith src, arith dst); + +#endif /* BLOCKS_H_ */ diff --git a/lang/cem/cemcom.ansi/ch3.c b/lang/cem/cemcom.ansi/ch3.c index 535426937..3132ccbb9 100644 --- a/lang/cem/cemcom.ansi/ch3.c +++ b/lang/cem/cemcom.ansi/ch3.c @@ -9,6 +9,7 @@ #include "parameters.h" #include #include "arith.h" +#include "ch3.h" #include "idf.h" #include "proto.h" #include "type.h" @@ -17,23 +18,22 @@ #include "expr.h" #include "def.h" #include "Lpars.h" +#include "error.h" +#include "ch3bin.h" #include "file_info.h" extern char options[]; extern char *symbol2str(); extern struct type *qualifier_type(); -void ch3cast(); + /* Most expression-handling routines have a pointer to a (struct type *) as first parameter. The object under the pointer gets updated in the process. */ -void -ch3sel(expp, oper, idf) - struct expr **expp; - struct idf *idf; +void ch3sel(struct expr **expp, int oper, struct idf *idf) { /* The selector idf is applied to *expp; oper may be '.' or ARROW. @@ -163,8 +163,7 @@ ch3sel(expp, oper, idf) *expp = exp; } -ch3incr(expp, oper) - struct expr **expp; +void ch3incr(struct expr **expp, int oper) { /* The monadic prefix/postfix incr/decr operator oper is applied to *expp. @@ -172,10 +171,7 @@ ch3incr(expp, oper) ch3asgn(expp, oper, intexpr((arith)1, INT)); } -void -ch3cast(expp, oper, tp) - register struct expr **expp; - register struct type *tp; +void ch3cast(register struct expr **expp, int oper, register struct type *tp) { /* The expression *expp is cast to type tp; the cast is caused by the operator oper. If the cast has @@ -412,9 +408,7 @@ ch3cast(expp, oper, tp) /* Determine whether two types are equal. */ -equal_type(tp, otp, qual_lev, diag) - register struct type *tp, *otp; - int qual_lev, diag; +int equal_type(register struct type *tp,register struct type *otp, int qual_lev, int diag) { if (tp == otp) return 1; @@ -475,8 +469,7 @@ equal_type(tp, otp, qual_lev, diag) } } -check_pseudoproto(pl, opl, diag) - register struct proto *pl, *opl; +int check_pseudoproto(register struct proto *pl,register struct proto *opl, int diag) { int retval = 1; @@ -519,9 +512,7 @@ check_pseudoproto(pl, opl, diag) return retval; } -legal_mixture(tp, otp, diag) - struct type *tp, *otp; - int diag; +int legal_mixture(struct type *tp, struct type *otp, int diag) { struct proto *pl = tp->tp_proto, *opl = otp->tp_proto; int retval = 1; @@ -562,9 +553,7 @@ legal_mixture(tp, otp, diag) return retval; } -equal_proto(pl, opl, diag) - register struct proto *pl, *opl; - int diag; +int equal_proto(register struct proto *pl, register struct proto *opl, int diag) { if (pl == opl) return 1; @@ -586,9 +575,7 @@ equal_proto(pl, opl, diag) } /* check if a type has a consqualified member */ -recurqual(tp, qual) -struct type *tp; -int qual; +int recurqual(struct type *tp, int qual) { register struct sdef *sdf; @@ -610,9 +597,7 @@ int qual; return 0; } -ch3asgn(expp, oper, expr) - struct expr **expp; - struct expr *expr; +void ch3asgn(struct expr **expp, int oper, struct expr *expr) { /* The assignment operators. "f op= e" should be interpreted as @@ -687,9 +672,7 @@ ch3asgn(expp, oper, expr) /* Some interesting (?) questions answered. */ -int -is_integral_type(tp) - register struct type *tp; +int is_integral_type(register struct type *tp) { switch (tp->tp_fund) { case CHAR: @@ -707,9 +690,7 @@ is_integral_type(tp) } } -int -is_arith_type(tp) - register struct type *tp; +int is_arith_type(register struct type *tp) { switch (tp->tp_fund) { case CHAR: diff --git a/lang/cem/cemcom.ansi/ch3.h b/lang/cem/cemcom.ansi/ch3.h new file mode 100644 index 000000000..a8970f75e --- /dev/null +++ b/lang/cem/cemcom.ansi/ch3.h @@ -0,0 +1,29 @@ +/* Copyright (c) 2019 ACK Project. See the file Copyright in + * the project root directory for more information. + * + * Created on: 2019-02-06 + * + */ +#ifndef CH3_H_ +#define CH3_H_ + +/* Structure forward declarations. */ +struct expr; +struct type; +struct proto; +struct idf; + + +void ch3sel(struct expr **expp, int oper, struct idf *idf); +void ch3incr(struct expr **expp, int oper); +void ch3cast(register struct expr **expp, int oper, register struct type *tp); +int equal_type(register struct type *tp,register struct type *otp, int qual_lev, int diag); +int check_pseudoproto(register struct proto *pl,register struct proto *opl, int diag); +int legal_mixture(struct type *tp, struct type *otp, int diag); +int equal_proto(register struct proto *pl, register struct proto *opl, int diag); +int recurqual(struct type *tp, int qual); +void ch3asgn(struct expr **expp, int oper, struct expr *expr); +int is_integral_type(register struct type *tp); +int is_arith_type(register struct type *tp); + +#endif /* CH3_H_ */ diff --git a/lang/cem/cemcom.ansi/ch3bin.c b/lang/cem/cemcom.ansi/ch3bin.c index ba75c112c..e692e98fa 100644 --- a/lang/cem/cemcom.ansi/ch3bin.c +++ b/lang/cem/cemcom.ansi/ch3bin.c @@ -15,6 +15,12 @@ #include "expr.h" #include "Lpars.h" #include "sizes.h" +#include "ch3bin.h" +#include "ch3mon.h" +#include "ch3.h" +#include "error.h" +#include "cstoper.h" +#include "fltcstoper.h" extern char options[]; extern char *symbol2str(); @@ -34,10 +40,7 @@ void pntminuspnt(); #define commutative_binop(expp, oper, expr) mk_binop(expp, oper, expr, 1) #define non_commutative_relop(expp, oper, expr) mk_binop(expp, oper, expr, 1) -void -ch3bin(expp, oper, expr) - register struct expr **expp; - struct expr *expr; +void ch3bin(register struct expr **expp, int oper, struct expr *expr) { /* apply binary operator oper between *expp and expr. NB: don't swap operands if op is one of the op= operators!!! @@ -295,9 +298,7 @@ ch3bin(expp, oper, expr) } } -void -pntminuspnt(expp, oper, expr) - register struct expr **expp, *expr; +void pntminuspnt(register struct expr **expp, int oper, register struct expr *expr) { /* Subtracting two pointers is so complicated it merits a routine of its own. @@ -328,8 +329,7 @@ pntminuspnt(expp, oper, expr) * when the arguments are switched. This is special for some relational * operators. */ -int -arg_switched(oper) +int arg_switched(int oper) { switch (oper) { case '<': return '>'; @@ -340,9 +340,7 @@ arg_switched(oper) } } -mk_binop(expp, oper, expr, commutative) - struct expr **expp; - register struct expr *expr; +void mk_binop(struct expr **expp, int oper, register struct expr *expr, int commutative) { /* Constructs in *expp the operation indicated by the operands. "commutative" indicates whether "oper" is a commutative @@ -366,8 +364,7 @@ mk_binop(expp, oper, expr, commutative) } } -pointer_arithmetic(expp1, oper, expp2) - register struct expr **expp1, **expp2; +void pointer_arithmetic(register struct expr **expp1, int oper, register struct expr **expp2) { int typ; /* prepares the integral expression expp2 in order to @@ -387,8 +384,7 @@ pointer_arithmetic(expp1, oper, expp2) ); } -pointer_binary(expp, oper, expr) - register struct expr **expp, *expr; +void pointer_binary(register struct expr **expp, int oper, register struct expr *expr) { /* constructs the pointer arithmetic expression out of a pointer expression, a binary operator and an integral diff --git a/lang/cem/cemcom.ansi/ch3bin.h b/lang/cem/cemcom.ansi/ch3bin.h new file mode 100644 index 000000000..bc6ea2d20 --- /dev/null +++ b/lang/cem/cemcom.ansi/ch3bin.h @@ -0,0 +1,21 @@ +/* Copyright (c) 2019 ACK Project. + * See the copyright notice in the ACK home directory, + * in the file "Copyright". + * + * Created on: 2019-02-06 + * + */ +#ifndef CH3BIN_H_ +#define CH3BIN_H_ + +struct expr; + +void ch3bin(register struct expr **expp, int oper, struct expr *expr); +void pntminuspnt(register struct expr **expp, int oper, register struct expr *expr); +int arg_switched(int oper); +void mk_binop(struct expr **expp, int oper, register struct expr *expr, int commutative); +void pointer_arithmetic(register struct expr **expp1, int oper, register struct expr **expp2); +void pointer_binary(register struct expr **expp, int oper, register struct expr *expr); + + +#endif /* CH3BIN_H_ */ diff --git a/lang/cem/cemcom.ansi/ch3mon.c b/lang/cem/cemcom.ansi/ch3mon.c index 8cffc2c9d..a84a141f2 100644 --- a/lang/cem/cemcom.ansi/ch3mon.c +++ b/lang/cem/cemcom.ansi/ch3mon.c @@ -5,6 +5,7 @@ /* $Id$ */ /* SEMANTIC ANALYSIS (CHAPTER 3.3) -- MONADIC OPERATORS */ +#include "ch3mon.h" #include "parameters.h" #include #include "Lpars.h" @@ -16,13 +17,15 @@ #include "expr.h" #include "def.h" #include "sizes.h" +#include "ch3.h" +#include "error.h" + extern char options[]; extern arith full_mask[/*MAXSIZE + 1*/]; /* cstoper.c */ char *symbol2str(); -ch3mon(oper, expp) - register struct expr **expp; +void ch3mon(int oper, register struct expr **expp) { /* The monadic prefix operator oper is applied to *expp. */ diff --git a/lang/cem/cemcom.ansi/ch3mon.h b/lang/cem/cemcom.ansi/ch3mon.h new file mode 100644 index 000000000..354738c42 --- /dev/null +++ b/lang/cem/cemcom.ansi/ch3mon.h @@ -0,0 +1,22 @@ +/* Copyright (c) 2019 ACK Project. + * See the copyright notice in the ACK home directory, + * in the file "Copyright". + * + * Created on: 2019-02-06 + * + */ +#ifndef CH3MON_H_ +#define CH3MON_H_ + +struct expr; + +void ch3mon(int oper, register struct expr **expp); +void ch3bin(register struct expr **expp, int oper, struct expr *expr); +void pntminuspnt(register struct expr **expp, int oper, register struct expr *expr); +int arg_switched(int oper); +void mk_binop(struct expr **expp, int oper, register struct expr *expr, int commutative); +void pointer_arithmetic(register struct expr **expp1, int oper, register struct expr **expp2); +void pointer_binary(register struct expr **expp, int oper, register struct expr *expr); + + +#endif /* CH3MON_H_ */ diff --git a/lang/cem/cemcom.ansi/code.c b/lang/cem/cemcom.ansi/code.c index a6a898ab7..d50700056 100644 --- a/lang/cem/cemcom.ansi/code.c +++ b/lang/cem/cemcom.ansi/code.c @@ -27,14 +27,24 @@ #include "expr.h" #include "sizes.h" #include "stack.h" +#include "blocks.h" +#include "struct.h" #include "level.h" +#include "dataflow.h" +#include "conversion.h" #include "decspecs.h" #include "declar.h" #include "Lpars.h" #include "specials.h" #include "atw.h" +#include "ch3.h" +#include "eval.h" +#include "stab.h" #include "LLlex.h" #include "align.h" +#include "util.h" +#include "error.h" + #ifdef LINT #include "l_lint.h" #endif /* LINT */ @@ -46,7 +56,10 @@ label lab_count = 1; label datlab_count = 1; int fp_used; -extern arith NewLocal(); /* util.c */ + +extern void str_cst(register char *, register int, int); /* ival.c */ + + /* global function info */ char *func_name; @@ -67,8 +80,7 @@ extern char *source; void loc_init(); #ifndef LINT -init_code(dst_file) - char *dst_file; +void init_code(char *dst_file) { /* init_code() initialises the output file on which the compact EM code is written @@ -105,10 +117,7 @@ init_code(dst_file) struct string_cst *str_list = 0; -label -code_string(val, len) - char *val; - int len; +label code_string(char* val, int len) { register struct string_cst *sc = new_string_cst(); label dlb = data_label(); @@ -122,8 +131,7 @@ code_string(val, len) return dlb; } -def_strings(sc) - register struct string_cst *sc; +void def_strings(register struct string_cst *sc) { while (sc) { struct string_cst *sc1 = sc; @@ -137,7 +145,7 @@ def_strings(sc) } /* flush_strings() is called from program.g after each external definition */ -flush_strings() { +void flush_strings(void) { if (str_list) { def_strings(str_list); str_list = 0; @@ -145,7 +153,7 @@ flush_strings() { } #ifndef LINT -end_code() +void end_code(void) { /* end_code() performs the actions to be taken when closing the output stream. @@ -160,7 +168,7 @@ end_code() #endif /* LINT */ #ifdef PREPEND_SCOPES -prepend_scopes() +void prepend_scopes(void) { /* prepend_scopes() runs down the list of global idf's and generates those exa's, exp's, ina's and inp's @@ -185,9 +193,7 @@ prepend_scopes() } #endif /* PREPEND_SCOPES */ -code_scope(text, def) - char *text; - register struct def *def; +void code_scope(char* text, register struct def *def) { /* generates code for one name, text, of the storage class as given by def, if meaningful. @@ -218,9 +224,7 @@ static int struct_return; static char *last_fn_given = (char *)0; static label file_name_label; -begin_proc(ds, idf) /* to be called when entering a procedure */ - struct decspecs *ds; - struct idf *idf; +void begin_proc(struct decspecs *ds, struct idf *idf) /* to be called when entering a procedure */ { /* begin_proc() is called at the entrance of a new function and performs the necessary code generation: @@ -317,8 +321,7 @@ begin_proc(ds, idf) /* to be called when entering a procedure */ #endif } -end_proc(fbytes) - arith fbytes; +void end_proc(arith fbytes) { /* end_proc() deals with the code to be generated at the end of a function, as there is: @@ -388,7 +391,7 @@ end_proc(fbytes) options['n'] = optionsn; } -do_return() +void do_return(void) { /* do_return handles the case of a return without expression. This version branches to the return label, which is @@ -401,8 +404,7 @@ do_return() C_bra(return2_label); } -do_return_expr(expr) - struct expr *expr; +void do_return_expr(struct expr *expr) { /* do_return_expr() generates the expression and the jump for a return statement with an expression. @@ -418,11 +420,11 @@ do_return_expr(expr) } void -code_declaration(idf, expr, lvl, sc) - register struct idf *idf; /* idf to be declared */ - struct expr *expr; /* initialisation; NULL if absent */ - int lvl; /* declaration level */ - int sc; /* storage class, as in the declaration */ +code_declaration( + register struct idf *idf, /* idf to be declared */ + struct expr *expr, /* initialisation; NULL if absent */ + int lvl, /* declaration level */ + int sc) /* storage class, as in the declaration */ { /* code_declaration() does the actual declaration of the variable indicated by "idf" on declaration level "lvl". @@ -530,10 +532,7 @@ code_declaration(idf, expr, lvl, sc) } } -void -loc_init(expr, id) - struct expr *expr; - struct idf *id; +void loc_init(struct expr *expr, struct idf *id) { /* loc_init() generates code for the assignment of expression expr to the local variable described by id. @@ -609,8 +608,7 @@ loc_init(expr, id) } } -bss(idf) - register struct idf *idf; +void bss(register struct idf *idf) { /* bss() allocates bss space for the global idf. */ @@ -640,9 +638,7 @@ bss(idf) } } -formal_cvt(hasproto,df) - int hasproto; - register struct def *df; +void formal_cvt(int hasproto, register struct def *df) { /* formal_cvt() converts a formal parameter of type char or short from int to that type. It also converts a formal @@ -672,9 +668,7 @@ formal_cvt(hasproto,df) #ifdef LINT /*ARGSUSED*/ #endif /* LINT */ -code_expr(expr, val, code, tlbl, flbl) - struct expr *expr; - label tlbl, flbl; +void code_expr(struct expr *expr, int val, int code, label tlbl, label flbl) { /* code_expr() is the parser's interface to the expression code generator. If line number trace is wanted, it generates a @@ -707,7 +701,7 @@ static struct stmt_block *stmt_stack; /* top of statement stack */ which are the only ones that are stacked, only the top of the stack is interesting. */ -code_break() +void code_break(void) { register struct stmt_block *stmt_block = stmt_stack; @@ -726,7 +720,7 @@ code_break() innermost statement in which continue has a meaning. */ void -code_continue() +code_continue(void) { register struct stmt_block *stmt_block = stmt_stack; @@ -743,8 +737,7 @@ code_continue() error("continue not inside for, while or do"); } -stack_stmt(break_label, cont_label) - label break_label, cont_label; +void stack_stmt(label break_label, label cont_label) { register struct stmt_block *stmt_block = new_stmt_block(); @@ -754,7 +747,7 @@ stack_stmt(break_label, cont_label) stmt_stack = stmt_block; } -unstack_stmt() +void unstack_stmt(void) { /* unstack_stmt() unstacks the data of a statement which may contain break or continue @@ -766,8 +759,7 @@ unstack_stmt() static label prc_name; -prc_entry(name) - char *name; +void prc_entry(char* name) { if (options['p']) { C_df_dlb(prc_name = data_label()); @@ -778,7 +770,7 @@ prc_entry(name) } } -prc_exit() +void prc_exit(void) { if (options['p']) { C_lae_dlb(prc_name, (arith) 0); @@ -788,9 +780,7 @@ prc_exit() } #ifdef DBSYMTAB -db_line(file, line) - char *file; - unsigned int line; +void db_line(char *file, unsigned int line) { static unsigned oldline; static char *oldfile; diff --git a/lang/cem/cemcom.ansi/code.str b/lang/cem/cemcom.ansi/code.str index b818bbea0..b3770395f 100644 --- a/lang/cem/cemcom.ansi/code.str +++ b/lang/cem/cemcom.ansi/code.str @@ -2,9 +2,15 @@ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * See the copyright notice in the ACK home directory, in the file "Copyright". */ +#ifndef CODE_H_ +#define CODE_H_ /* $Id$ */ /* C O D E - G E N E R A T O R D E F I N I T I O N S */ +#include "arith.h" +#include "label.h" + + struct string_cst { /* storing string constants */ struct string_cst *next; char *sc_value; @@ -20,3 +26,44 @@ extern struct string_cst *str_list; #define RVAL 1 #define FALSE 0 #define TRUE 1 + + +#ifndef LINT +void init_code(char *dst_file); +void end_code(void); +#endif + +struct expr; +struct def; +struct idf; + +label code_string(char* val, int len); +void def_strings(register struct string_cst *sc); +void flush_strings(void); +void code_scope(char* text, register struct def *def); +void begin_proc(struct decspecs *ds, struct idf *idf); +void end_proc(arith fbytes); +void do_return(void); +void do_return_expr(struct expr *expr); +void code_declaration(register struct idf *idf, struct expr *expr, + int lvl, int sc); +void loc_init(struct expr *expr, struct idf *id); +void bss(register struct idf *idf); +void formal_cvt(int hasproto, register struct def *df); +void code_expr(struct expr *expr, int val, int code, label tlbl, label flbl); +void code_break(void); +void code_continue(void); +void stack_stmt(label break_label, label cont_label); +void unstack_stmt(void); +void prc_entry(char* name); +void prc_exit(void); + +#ifdef PREPEND_SCOPES +void prepend_scopes(void); +#endif + +#ifdef DBSYMTAB +void db_line(char *file, unsigned int line); +#endif + +#endif diff --git a/lang/cem/cemcom.ansi/conversion.c b/lang/cem/cemcom.ansi/conversion.c index 485d8b8bd..60d4c45b5 100644 --- a/lang/cem/cemcom.ansi/conversion.c +++ b/lang/cem/cemcom.ansi/conversion.c @@ -8,11 +8,15 @@ #include "parameters.h" #ifndef LINT +#include "conversion.h" #include +#include "interface.h" #include "arith.h" #include "type.h" #include "sizes.h" #include "Lpars.h" +#include "error.h" + #define T_SIGNED 1 #define T_UNSIGNED 2 @@ -27,10 +31,9 @@ C?? */ -static int convtype(); +static int convtype(register struct type *); -conversion(from_type, to_type) - register struct type *from_type, *to_type; +void conversion(register struct type *from_type, register struct type *to_type) { register arith from_size = from_type->tp_size; register arith to_size = to_type->tp_size; @@ -126,9 +129,7 @@ conversion(from_type, to_type) /* convtype() returns in which category a given type falls: signed, unsigned or floating */ -static int -convtype(tp) - register struct type *tp; +static int convtype(register struct type *tp) { switch (tp->tp_fund) { case CHAR: diff --git a/lang/cem/cemcom.ansi/conversion.h b/lang/cem/cemcom.ansi/conversion.h new file mode 100644 index 000000000..25756a94d --- /dev/null +++ b/lang/cem/cemcom.ansi/conversion.h @@ -0,0 +1,15 @@ +/* Copyright (c) 2019 ACK Project. + * See the copyright notice in the ACK home directory, + * in the file "Copyright". + * + * Created on: 2019-02-06 + * + */ +#ifndef CONVERSION_H_ +#define CONVERSION_H_ + +struct type; + +void conversion(register struct type *from_type, register struct type *to_type); + +#endif /* CONVERSION_H_ */ diff --git a/lang/cem/cemcom.ansi/cstoper.c b/lang/cem/cemcom.ansi/cstoper.c index a63103ba3..774e356d6 100644 --- a/lang/cem/cemcom.ansi/cstoper.c +++ b/lang/cem/cemcom.ansi/cstoper.c @@ -6,6 +6,7 @@ /* C O N S T A N T E X P R E S S I O N H A N D L I N G */ #include +#include "cstoper.h" #include "parameters.h" #include #include "arith.h" @@ -14,6 +15,7 @@ #include "expr.h" #include "sizes.h" #include "Lpars.h" +#include "error.h" /* full_mask[1] == 0XFF, full_mask[2] == 0XFFFF, .. */ arith full_mask[MAXSIZE + 1]; @@ -23,8 +25,7 @@ arith max_unsigned; /* maximum unsigned on target machine */ #endif /* NOCROSS */ extern int ResultKnown; -cstbin(expp, oper, expr) - register struct expr **expp, *expr; +void cstbin(register struct expr **expp, int oper, register struct expr *expr) { /* The operation oper is performed on the constant expressions *expp(ld) and expr(ct), and the result restored in @@ -134,8 +135,7 @@ cstbin(expp, oper, expr) free_expression(expr); } -cut_size(expr) - register struct expr *expr; +void cut_size(register struct expr *expr) { /* The constant value of the expression expr is made to conform to the size of the type of the expression. @@ -170,7 +170,7 @@ cut_size(expr) expr->VL_VALUE = o1; } -init_cst() +void init_cst(void) { register int i = 0; register arith bt = (arith)0; diff --git a/lang/cem/cemcom.ansi/cstoper.h b/lang/cem/cemcom.ansi/cstoper.h new file mode 100644 index 000000000..4d0d971f1 --- /dev/null +++ b/lang/cem/cemcom.ansi/cstoper.h @@ -0,0 +1,17 @@ +/* Copyright (c) 2019 ACK Project. + * See the copyright notice in the ACK home directory, + * in the file "Copyright". + * + * Created on: 2019-02-06 + * + */ +#ifndef CSTOPER_H_ +#define CSTOPER_H_ + +struct expr; + +void cstbin(register struct expr **expp, int oper, register struct expr *expr); +void cut_size(register struct expr *expr); +void init_cst(void); + +#endif /* CSTOPER_H_ */ diff --git a/lang/cem/cemcom.ansi/dataflow.c b/lang/cem/cemcom.ansi/dataflow.c index 6a3fbcf65..cdd7781cf 100644 --- a/lang/cem/cemcom.ansi/dataflow.c +++ b/lang/cem/cemcom.ansi/dataflow.c @@ -10,26 +10,26 @@ */ #include "parameters.h" /* UF */ +#include "dataflow.h" +#include "print.h" #ifdef DATAFLOW char *CurrentFunction = 0; int NumberOfCalls; -DfaStartFunction(nm) - char *nm; +void DfaStartFunction(char* nm) { CurrentFunction = nm; NumberOfCalls = 0; } -DfaEndFunction() +void DfaEndFunction(void) { if (NumberOfCalls == 0) print("DFA: %s: --none--\n", CurrentFunction); } -DfaCallFunction(s) - char *s; +void DfaCallFunction(char* s) { print("DFA: %s: %s\n", CurrentFunction, s); ++NumberOfCalls; diff --git a/lang/cem/cemcom.ansi/dataflow.h b/lang/cem/cemcom.ansi/dataflow.h new file mode 100644 index 000000000..e353b9ac8 --- /dev/null +++ b/lang/cem/cemcom.ansi/dataflow.h @@ -0,0 +1,19 @@ +/* Copyright (c) 2019 ACK Project. + * See the copyright notice in the ACK home directory, + * in the file "Copyright". + * + * Created on: 2019-02-06 + * + */ +#ifndef DATAFLOW_H_ +#define DATAFLOW_H_ + +#ifdef DATAFLOW + +void DfaStartFunction(char* nm); +void DfaEndFunction(void); +void DfaCallFunction(char* s); + +#endif + +#endif /* DATAFLOW_H_ */ diff --git a/lang/cem/cemcom.ansi/declar.g b/lang/cem/cemcom.ansi/declar.g index d6119f59d..92adefb5f 100644 --- a/lang/cem/cemcom.ansi/declar.g +++ b/lang/cem/cemcom.ansi/declar.g @@ -1,764 +1,768 @@ -/* - * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. - * See the copyright notice in the ACK home directory, in the file "Copyright". - */ -/* $Id$ */ -/* DECLARATION SYNTAX PARSER */ - -{ -#include "parameters.h" -#include -#include -#include "idf.h" -#include "arith.h" -#include "LLlex.h" -#include "label.h" -#include "code.h" -#include "type.h" -#include "proto.h" -#include "struct.h" -#include "field.h" -#include "decspecs.h" -#include "def.h" -#include "declar.h" -#include "label.h" -#include "expr.h" -#include "sizes.h" -#include "level.h" -#ifdef LINT -#include "l_lint.h" -#endif /* LINT */ - -extern char options[]; -} - -/* 3.5 */ -declaration - {struct decspecs Ds;} -: - {Ds = null_decspecs;} - decl_specifiers(&Ds) - init_declarator_list(&Ds)? - ';' -; - -/* A `decl_specifiers' describes a sequence of a storage_class_specifier, - an unsigned_specifier, a size_specifier and a simple type_specifier, - which may occur in arbitrary order and each of which may be absent; - at least one of them must be present, however, since the totally - empty case has already be dealt with in `external_definition'. - This means that something like: - unsigned extern int short xx; - is perfectly legal C. - - On top of that, multiple occurrences of storage_class_specifiers, - unsigned_specifiers and size_specifiers are errors, but a second - type_specifier should end the decl_specifiers and be treated as - the name to be declared. - Such a language is not easily expressed in a grammar; enumeration - of the permutations is unattractive. We solve the problem by - having a regular grammar for the "soft" items, handling the single - occurrence of the type_specifier in the grammar (we have no choice), - collecting all data in a `struct decspecs' and turning that data - structure into what we want. - - The existence of declarations like - short typedef yepp; - makes all hope of writing a specific grammar for typedefs illusory. -*/ -/* Accept a single declaration specifier. Then accept zero or more - declaration specifiers. There can be a conflict on both - TYPE_IDENTIFIER and IDENTIFIER. - The following rule is used: - When we see a TYPE_IDENTIFIER, we accept it if no type-specifier was - given, and it is not directly followed by an identifier. If a - type-specifier was given, it is taken as the identifier being - declared. If it is followed by an identifier, we assume that an - error has been made, (e.g. unsigned typedeffed_int x;) and that - this will be detected later on. - When we see an IDENTIFIER, directly followed by another IDENTIFIER, - we assume that a typing mistake has been made, and we accept it as - an erroneous type-identifier. -*/ - -decl_specifiers /* non-empty */ (register struct decspecs *ds;) - /* Reads a non-empty decl_specifiers and fills the struct - decspecs *ds. - */ -: - single_decl_specifier(ds) - [ %while( (DOT==TYPE_IDENTIFIER - && ds->ds_size == 0 - && ds->ds_unsigned == 0 - && ds->ds_type == (struct type *)0) - || AHEAD == IDENTIFIER) /* always an error */ - single_decl_specifier(ds) - ]* - {do_decspecs(ds);} -; - -single_decl_specifier /* non_empty */ (register struct decspecs *ds;) -: - [ AUTO | STATIC | EXTERN | TYPEDEF | REGISTER ] - { if (ds->ds_sc_given) - error("repeated storage class specifier"); - ds->ds_sc_given = 1; - ds->ds_sc = DOT; - } -| - VOLATILE - { if (ds->ds_typequal & TQ_VOLATILE) - error("repeated type qualifier"); - ds->ds_typequal |= TQ_VOLATILE; - } -| - CONST - { if (ds->ds_typequal & TQ_CONST) - error("repeated type qualifier"); - ds->ds_typequal |= TQ_CONST; - } -| - [ SHORT | LONG ] - { if (ds->ds_size) - error("repeated size specifier"); - ds->ds_size = DOT; - } -| - [ SIGNED | UNSIGNED ] - { if (ds->ds_unsigned != 0) - error("repeated sign specifier"); - ds->ds_unsigned = DOT; - } -| - [ VOID | CHAR | INT | FLOAT | DOUBLE ] - { - idf2type(dot.tk_idf, &ds->ds_type); - ds->ds_typedef = 0; - } -| - %default TYPE_IDENTIFIER - { - idf2type(dot.tk_idf, &ds->ds_type); - ds->ds_typedef = 1; - } -| - %erroneous - IDENTIFIER - { - error("%s is not a type identifier", dot.tk_idf->id_text); - ds->ds_type = error_type; - if (dot.tk_idf->id_def) { - dot.tk_idf->id_def->df_type = error_type; - dot.tk_idf->id_def->df_sc = TYPEDEF; - } - } -| - %illegal - IDENTIFIER -| - struct_or_union_specifier(&ds->ds_type) -| - enum_specifier(&ds->ds_type) -; - -/* 3.5.2 */ -type_specifier(struct type **tpp;) - /* Used in struct/union declarations and in casts; only the - type is relevant. - */ - {struct decspecs Ds; Ds = null_decspecs;} -: - decl_specifiers(&Ds) - { - if (Ds.ds_sc_given) - error("storage class ignored"); - if (Ds.ds_sc == REGISTER) - error("register ignored"); - } - {*tpp = Ds.ds_type;} -; - -/* 3.5 */ -init_declarator_list(struct decspecs *ds;): - init_declarator(ds) - [ ',' init_declarator(ds) ]* -; - -init_declarator(register struct decspecs *ds;) - { - struct declarator Dc; - } -: - { - Dc = null_declarator; - } -[ - declarator(&Dc) - { - reject_params(&Dc); - declare_idf(ds, &Dc, level); -#ifdef LINT - lint_declare_idf(Dc.dc_idf, ds->ds_sc); -#endif /* LINT */ - } - [ - initializer(Dc.dc_idf, ds->ds_sc) - | - { code_declaration(Dc.dc_idf, (struct expr *) 0, level, ds->ds_sc); } - ] -] - { -#ifdef LINT - add_auto(Dc.dc_idf); -#endif /* LINT */ - remove_declarator(&Dc); - } -; - -/* 3.5.7: initializer */ -initializer(struct idf *idf; int sc;) - { - struct expr *expr = (struct expr *) 0; - int fund = idf->id_def->df_type->tp_fund; - int autoagg = (level >= L_LOCAL - && sc != STATIC - && ( fund == STRUCT - || fund == UNION - || fund == ARRAY)); - int globalflag = level == L_GLOBAL - || (level >= L_LOCAL && sc == STATIC); - } -: - { if (idf->id_def->df_type->tp_fund == FUNCTION) { - error("illegal initialization of function"); - idf->id_def->df_type->tp_fund = ERRONEOUS; - } - if (level == L_FORMAL2) - error("illegal initialization of formal parameter"); - } - '=' - { - if (AHEAD != '{' && AHEAD != STRING ) autoagg = 0; -#ifdef LINT - lint_statement(); -#endif /* LINT */ - if (globalflag) { - struct expr ex; - code_declaration(idf, &ex, level, sc); - } - else if (autoagg) - loc_init((struct expr *) 0, idf); - } - initial_value((globalflag || autoagg) ? - &(idf->id_def->df_type) - : (struct type **)0, - &expr) - { if (! globalflag) { - if (idf->id_def->df_type->tp_fund == FUNCTION) { - free_expression(expr); - expr = 0; - } -#ifdef DEBUG - print_expr("initializer-expression", expr); -#endif /* DEBUG */ -#ifdef LINT - change_state(idf, SET); -#endif /* LINT */ -#ifdef DBSYMTAB - if (options['g'] && level >= L_LOCAL && expr) { - db_line(expr->ex_file, (unsigned) expr->ex_line); - } -#endif /* DBSYMTAB */ - if (autoagg) - loc_init((struct expr *) 0, idf); - else code_declaration(idf, expr, level, sc); - } -#ifdef DBSYMTAB - if (options['g'] && globalflag) { - stb_string(idf->id_def, sc, idf->id_text); - } -#endif /* DBSYMTAB */ - idf_initialized(idf); - } -; - -/* - Functions yielding pointers to functions must be declared as, e.g., - int (*hehe(par1, par2))() char *par1, *par2; {} - Since the function heading is read as a normal declarator, - we just include the (formal) parameter list in the declarator - description list dc. -*/ -/* 3.5.4 */ -declarator(register struct declarator *dc;) - { struct formal *fm = NO_PARAMS; - struct proto *pl = NO_PROTO; - arith count; - int qual; - } -: - primary_declarator(dc) - [/*%while(1)*/ - '(' - [ %if (DOT != IDENTIFIER) - parameter_type_list(&pl) - | - formal_list(&fm) - | - /* empty */ - ] - ')' - { add_decl_unary(dc, FUNCTION, 0, (arith)0, fm, pl); - fm = NO_PARAMS; - } - | - arrayer(&count) - {add_decl_unary(dc, ARRAY, 0, count, NO_PARAMS, NO_PROTO);} - ]* -| - pointer(&qual) declarator(dc) - {add_decl_unary(dc, POINTER, qual, (arith)0, NO_PARAMS, NO_PROTO);} -; - -primary_declarator(register struct declarator *dc;) : - identifier(&dc->dc_idf) -| - '(' declarator(dc) ')' -; - -arrayer(arith *sizep;) - { struct expr *expr; } -: - '[' - { *sizep = (arith)-1; } - [ - constant_expression(&expr) - { - check_array_subscript(expr); - *sizep = expr->VL_VALUE; - free_expression(expr); - } - ]? - ']' -; - -formal_list (struct formal **fmp;) -: - formal(fmp) [ %persistent ',' formal(fmp) ]* -; - -formal(struct formal **fmp;) - {struct idf *idf; } -: - identifier(&idf) - { - register struct formal *new = new_formal(); - - new->fm_idf = idf; - new->next = *fmp; - *fmp = new; - if (idf->id_def && idf->id_def->df_sc == TYPEDEF) { - error("typedef name %s may not be redeclared as a parameter", idf->id_text); - } - } -; - -/* Change 2 */ -enum_specifier(register struct type **tpp;) - { - struct idf *idf; - arith l = (arith)0; - } -: - {if (*tpp) error("multiple types in declaration");} - ENUM - [ - {declare_struct(ENUM, (struct idf *) 0, tpp);} - enumerator_pack(*tpp, &l) - | - identifier(&idf) - [ - {declare_struct(ENUM, idf, tpp);} - enumerator_pack(*tpp, &l) - { -#ifdef DBSYMTAB - if (options['g']) { - stb_tag(idf->id_tag, idf->id_text); - } -#endif /*DBSYMTAB */ - } - | - {apply_struct(ENUM, idf, tpp);} - /* empty */ - ] - ] -; - -enumerator_pack(register struct type *tp; arith *lp;) : - '{' - enumerator(tp, lp) - [%while (AHEAD != '}') - ',' - enumerator(tp, lp) - ]* - [ - ',' {warning("unexpected trailing comma in enumerator pack");} - ]? - '}' - {tp->tp_size = int_size;} - /* fancy implementations that put small enums in 1 byte - or so should start here. - */ -; - -enumerator(struct type *tp; arith *lp;) - { - struct idf *idf; - struct expr *expr; - } -: - identifier(&idf) - [ - '=' - constant_expression(&expr) - { - *lp = expr->VL_VALUE; - free_expression(expr); - } - ]? - {declare_enum(tp, idf, (*lp)++);} -; - -/* 8.5 */ -struct_or_union_specifier(register struct type **tpp;) - { - int fund; - struct idf *idfX; - register struct idf *idf; - } -: - {if (*tpp) error("multiple types in declaration");} - [ STRUCT | UNION ] - {fund = DOT;} - [ - { - declare_struct(fund, (struct idf *)0, tpp); - } - struct_declaration_pack(*tpp) - | - identifier(&idfX) { idf = idfX; } - [ - { - declare_struct(fund, idf, tpp); - (idf->id_tag->tg_busy)++; - } - struct_declaration_pack(*tpp) - { - (idf->id_tag->tg_busy)--; -#ifdef DBSYMTAB - if (options['g']) { - stb_tag(idf->id_tag, idf->id_text); - } -#endif /*DBSYMTAB */ - } - | - { - /* a ';' means an empty declaration (probably) - * this means that we have to declare a new - * structure. (yegh) - */ - if (DOT == ';' && - ( !idf->id_tag || - idf->id_tag->tg_level != level || - idf->id_tag->tg_type->tp_size < 0 - )) declare_struct(fund, idf, tpp); - else apply_struct(fund, idf, tpp); - } - /* empty */ - ] - ] -; - -struct_declaration_pack(register struct type *stp;) - { - struct sdef **sdefp = &stp->tp_sdef; - arith size = (arith)0; - } -: - /* The size is only filled in after the whole struct has - been read, to prevent recursive definitions. - */ - '{' - struct_declaration(stp, &sdefp, &size)+ - '}' - {stp->tp_size = align(size, stp->tp_align); - completed(stp); - } -; - -struct_declaration(struct type *stp; struct sdef ***sdefpp; arith *szp;) - {struct type *tp;} -: - type_specifier(&tp) struct_declarator_list(tp, stp, sdefpp, szp) ';' -; - -struct_declarator_list(struct type *tp; struct type *stp; - struct sdef ***sdefpp; arith *szp;) -: - struct_declarator(tp, stp, sdefpp, szp) - [ ',' struct_declarator(tp, stp, sdefpp, szp) ]* -; - -struct_declarator(struct type *tp; struct type *stp; - struct sdef ***sdefpp; arith *szp;) - { - struct declarator Dc; - struct field *fd = 0; - } -: - { - Dc = null_declarator; - } -[ - declarator(&Dc) - {reject_params(&Dc);} - bit_expression(&fd)? -| - {Dc.dc_idf = gen_idf();} - bit_expression(&fd) -] - {add_sel(stp, declare_type(tp, &Dc), Dc.dc_idf, sdefpp, szp, fd);} - {remove_declarator(&Dc);} -; - -bit_expression(struct field **fd;) - { struct expr *expr; } -: - { - *fd = new_field(); - } - ':' - constant_expression(&expr) - { - (*fd)->fd_width = expr->VL_VALUE; - free_expression(expr); -#ifdef NOBITFIELD - error("bitfields are not implemented"); -#endif /* NOBITFIELD */ - } -; - -/* 8.7 */ -cast(struct type **tpp;) - {struct declarator Dc;} -: - {Dc = null_declarator;} - '(' - type_specifier(tpp) - abstract_declarator(&Dc) - ')' - {*tpp = declare_type(*tpp, &Dc);} - {remove_declarator(&Dc);} -; - -/* This code is an abject copy of that of 'declarator', for lack of - a two-level grammar. -*/ -abstract_declarator(register struct declarator *dc;) - { struct proto *pl = NO_PROTO; - arith count; - int qual; - } -: - primary_abstract_declarator(dc) - [ - '(' - [ - parameter_type_list(&pl) - | - /* empty */ - ] - ')' - {add_decl_unary(dc, FUNCTION, 0, (arith)0, NO_PARAMS, pl); - if (pl) remove_proto_idfs(pl); - } - | - arrayer(&count) - {add_decl_unary(dc, ARRAY, 0, count, NO_PARAMS, NO_PROTO);} - ]* -| - pointer(&qual) abstract_declarator(dc) - {add_decl_unary(dc, POINTER, qual, (arith)0, NO_PARAMS, NO_PROTO);} -; - -%first first_of_parameter_type_list, parameter_type_list; - -primary_abstract_declarator(struct declarator *dc;) -: -[%if (AHEAD == ')' || first_of_parameter_type_list(AHEAD)) - /* empty */ -| - '(' abstract_declarator(dc) ')' -] -; - -parameter_type_list(struct proto **plp;) - { int save_level; } -: - { if (level > L_PROTO) { - save_level = level; - level = L_PROTO; - } else level--; - } - parameter_decl_list(plp) - [ - ',' ELLIPSIS - { register struct proto *new = new_proto(); - - new->next = *plp; - new->pl_flag = PL_ELLIPSIS; - *plp = new; - } - - ]? - { check_for_void(*plp); - if (level == L_PROTO) - level = save_level; - else level++; - } -; - -parameter_decl_list(struct proto **plp;) -: - parameter_decl(plp) - [ %while (AHEAD != ELLIPSIS) - %persistent - ',' parameter_decl(plp) - ]* -; - -parameter_decl(struct proto **plp;) - { register struct proto *new = new_proto(); - struct declarator Dc; - struct decspecs Ds; - } -: - { Dc = null_declarator; - Ds = null_decspecs; - } - decl_specifiers(&Ds) - parameter_declarator(&Dc) - { add_proto(new, &Ds, &Dc, level); - new->next = *plp; - *plp = new; - remove_declarator(&Dc); - } -; - -/* This is weird. Due to the LR structure of the ANSI C grammar - we have to duplicate the actions of 'declarator' and - 'abstract_declarator'. Calling these separately, as in - - parameter_decl: - decl_specifiers - [ - declarator - | - abstract_declarator - ] - - - gives us a conflict on the terminals '(' and '*'. E.i. on - some input, it is impossible to decide which rule we take. - Combining the two declarators into one common declarator - is out of the question, since this results in an empty - string for the non-terminal 'declarator'. - So we combine the two only for the use of parameter_decl, - since this is the only place where they don't give - conflicts. However, this makes the grammar messy. -*/ -parameter_declarator(register struct declarator *dc;) - { struct formal *fm = NO_PARAMS; - struct proto *pl = NO_PROTO; - arith count; - int qual; - } -: - primary_parameter_declarator(dc) - [ - '(' - [ %if (DOT != IDENTIFIER) - parameter_type_list(&pl) - | - formal_list(&fm) - | - /* empty */ - ] - ')' - { add_decl_unary(dc, FUNCTION, 0, (arith)0, fm, pl); - reject_params(dc); - } - | - arrayer(&count) - {add_decl_unary(dc, ARRAY, 0, count, NO_PARAMS, NO_PROTO);} - ]* -| - pointer(&qual) parameter_declarator(dc) - {add_decl_unary(dc, POINTER, qual, (arith)0, NO_PARAMS, NO_PROTO);} -; - -primary_parameter_declarator(register struct declarator *dc;) -: -[%if (AHEAD == ')' || first_of_parameter_type_list(AHEAD) - && (AHEAD != IDENTIFIER)) - /* empty */ -| - identifier(&dc->dc_idf) -| - '(' parameter_declarator(dc) ')' -] -; - -pointer(int *qual;) -: - '*' type_qualifier_list(qual) -; - -/* Type qualifiers may come in three flavours: - volatile, const, const volatile. - These all have different semantic properties: - - volatile: - means that the object can be modified - without prior knowledge of the implementation. - - const: - means that the object can not be modified; thus - it's illegal to use this as a l-value. - - const volatile: - means that the object can be modified without - prior knowledge of the implementation, but may - not be used as a l-value. -*/ -/* 3.5.4 */ -type_qualifier_list(int *qual;) -: - { *qual = 0; } - [ - VOLATILE - { if (*qual & TQ_VOLATILE) - error("repeated type qualifier"); - *qual |= TQ_VOLATILE; - } - | - CONST - { if (*qual & TQ_CONST) - error("repeated type qualifier"); - *qual |= TQ_CONST; - } - ]* -; - -empty: -; +/* + * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. + * See the copyright notice in the ACK home directory, in the file "Copyright". + */ +/* $Id$ */ +/* DECLARATION SYNTAX PARSER */ + +{ +#include "parameters.h" +#include +#include +#include "idf.h" +#include "arith.h" +#include "LLlex.h" +#include "label.h" +#include "code.h" +#include "type.h" +#include "proto.h" +#include "struct.h" +#include "field.h" +#include "decspecs.h" +#include "declarator.h" +#include "def.h" +#include "declar.h" +#include "label.h" +#include "expr.h" +#include "sizes.h" +#include "level.h" +#include "error.h" +#include "stab.h" + +#ifdef LINT +#include "l_lint.h" +#endif /* LINT */ + +extern char options[]; +} + +/* 3.5 */ +declaration + {struct decspecs Ds;} +: + {Ds = null_decspecs;} + decl_specifiers(&Ds) + init_declarator_list(&Ds)? + ';' +; + +/* A `decl_specifiers' describes a sequence of a storage_class_specifier, + an unsigned_specifier, a size_specifier and a simple type_specifier, + which may occur in arbitrary order and each of which may be absent; + at least one of them must be present, however, since the totally + empty case has already be dealt with in `external_definition'. + This means that something like: + unsigned extern int short xx; + is perfectly legal C. + + On top of that, multiple occurrences of storage_class_specifiers, + unsigned_specifiers and size_specifiers are errors, but a second + type_specifier should end the decl_specifiers and be treated as + the name to be declared. + Such a language is not easily expressed in a grammar; enumeration + of the permutations is unattractive. We solve the problem by + having a regular grammar for the "soft" items, handling the single + occurrence of the type_specifier in the grammar (we have no choice), + collecting all data in a `struct decspecs' and turning that data + structure into what we want. + + The existence of declarations like + short typedef yepp; + makes all hope of writing a specific grammar for typedefs illusory. +*/ +/* Accept a single declaration specifier. Then accept zero or more + declaration specifiers. There can be a conflict on both + TYPE_IDENTIFIER and IDENTIFIER. + The following rule is used: + When we see a TYPE_IDENTIFIER, we accept it if no type-specifier was + given, and it is not directly followed by an identifier. If a + type-specifier was given, it is taken as the identifier being + declared. If it is followed by an identifier, we assume that an + error has been made, (e.g. unsigned typedeffed_int x;) and that + this will be detected later on. + When we see an IDENTIFIER, directly followed by another IDENTIFIER, + we assume that a typing mistake has been made, and we accept it as + an erroneous type-identifier. +*/ + +decl_specifiers /* non-empty */ (register struct decspecs *ds;) + /* Reads a non-empty decl_specifiers and fills the struct + decspecs *ds. + */ +: + single_decl_specifier(ds) + [ %while( (DOT==TYPE_IDENTIFIER + && ds->ds_size == 0 + && ds->ds_unsigned == 0 + && ds->ds_type == (struct type *)0) + || AHEAD == IDENTIFIER) /* always an error */ + single_decl_specifier(ds) + ]* + {do_decspecs(ds);} +; + +single_decl_specifier /* non_empty */ (register struct decspecs *ds;) +: + [ AUTO | STATIC | EXTERN | TYPEDEF | REGISTER ] + { if (ds->ds_sc_given) + error("repeated storage class specifier"); + ds->ds_sc_given = 1; + ds->ds_sc = DOT; + } +| + VOLATILE + { if (ds->ds_typequal & TQ_VOLATILE) + error("repeated type qualifier"); + ds->ds_typequal |= TQ_VOLATILE; + } +| + CONST + { if (ds->ds_typequal & TQ_CONST) + error("repeated type qualifier"); + ds->ds_typequal |= TQ_CONST; + } +| + [ SHORT | LONG ] + { if (ds->ds_size) + error("repeated size specifier"); + ds->ds_size = DOT; + } +| + [ SIGNED | UNSIGNED ] + { if (ds->ds_unsigned != 0) + error("repeated sign specifier"); + ds->ds_unsigned = DOT; + } +| + [ VOID | CHAR | INT | FLOAT | DOUBLE ] + { + idf2type(dot.tk_idf, &ds->ds_type); + ds->ds_typedef = 0; + } +| + %default TYPE_IDENTIFIER + { + idf2type(dot.tk_idf, &ds->ds_type); + ds->ds_typedef = 1; + } +| + %erroneous + IDENTIFIER + { + error("%s is not a type identifier", dot.tk_idf->id_text); + ds->ds_type = error_type; + if (dot.tk_idf->id_def) { + dot.tk_idf->id_def->df_type = error_type; + dot.tk_idf->id_def->df_sc = TYPEDEF; + } + } +| + %illegal + IDENTIFIER +| + struct_or_union_specifier(&ds->ds_type) +| + enum_specifier(&ds->ds_type) +; + +/* 3.5.2 */ +type_specifier(struct type **tpp;) + /* Used in struct/union declarations and in casts; only the + type is relevant. + */ + {struct decspecs Ds; Ds = null_decspecs;} +: + decl_specifiers(&Ds) + { + if (Ds.ds_sc_given) + error("storage class ignored"); + if (Ds.ds_sc == REGISTER) + error("register ignored"); + } + {*tpp = Ds.ds_type;} +; + +/* 3.5 */ +init_declarator_list(struct decspecs *ds;): + init_declarator(ds) + [ ',' init_declarator(ds) ]* +; + +init_declarator(register struct decspecs *ds;) + { + struct declarator Dc; + } +: + { + Dc = null_declarator; + } +[ + declarator(&Dc) + { + reject_params(&Dc); + declare_idf(ds, &Dc, level); +#ifdef LINT + lint_declare_idf(Dc.dc_idf, ds->ds_sc); +#endif /* LINT */ + } + [ + initializer(Dc.dc_idf, ds->ds_sc) + | + { code_declaration(Dc.dc_idf, (struct expr *) 0, level, ds->ds_sc); } + ] +] + { +#ifdef LINT + add_auto(Dc.dc_idf); +#endif /* LINT */ + remove_declarator(&Dc); + } +; + +/* 3.5.7: initializer */ +initializer(struct idf *idf; int sc;) + { + struct expr *expr = (struct expr *) 0; + int fund = idf->id_def->df_type->tp_fund; + int autoagg = (level >= L_LOCAL + && sc != STATIC + && ( fund == STRUCT + || fund == UNION + || fund == ARRAY)); + int globalflag = level == L_GLOBAL + || (level >= L_LOCAL && sc == STATIC); + } +: + { if (idf->id_def->df_type->tp_fund == FUNCTION) { + error("illegal initialization of function"); + idf->id_def->df_type->tp_fund = ERRONEOUS; + } + if (level == L_FORMAL2) + error("illegal initialization of formal parameter"); + } + '=' + { + if (AHEAD != '{' && AHEAD != STRING ) autoagg = 0; +#ifdef LINT + lint_statement(); +#endif /* LINT */ + if (globalflag) { + struct expr ex; + code_declaration(idf, &ex, level, sc); + } + else if (autoagg) + loc_init((struct expr *) 0, idf); + } + initial_value((globalflag || autoagg) ? + &(idf->id_def->df_type) + : (struct type **)0, + &expr) + { if (! globalflag) { + if (idf->id_def->df_type->tp_fund == FUNCTION) { + free_expression(expr); + expr = 0; + } +#ifdef DEBUG + print_expr("initializer-expression", expr); +#endif /* DEBUG */ +#ifdef LINT + change_state(idf, SET); +#endif /* LINT */ +#ifdef DBSYMTAB + if (options['g'] && level >= L_LOCAL && expr) { + db_line(expr->ex_file, (unsigned) expr->ex_line); + } +#endif /* DBSYMTAB */ + if (autoagg) + loc_init((struct expr *) 0, idf); + else code_declaration(idf, expr, level, sc); + } +#ifdef DBSYMTAB + if (options['g'] && globalflag) { + stb_string(idf->id_def, sc, idf->id_text); + } +#endif /* DBSYMTAB */ + idf_initialized(idf); + } +; + +/* + Functions yielding pointers to functions must be declared as, e.g., + int (*hehe(par1, par2))() char *par1, *par2; {} + Since the function heading is read as a normal declarator, + we just include the (formal) parameter list in the declarator + description list dc. +*/ +/* 3.5.4 */ +declarator(register struct declarator *dc;) + { struct formal *fm = NO_PARAMS; + struct proto *pl = NO_PROTO; + arith count; + int qual; + } +: + primary_declarator(dc) + [/*%while(1)*/ + '(' + [ %if (DOT != IDENTIFIER) + parameter_type_list(&pl) + | + formal_list(&fm) + | + /* empty */ + ] + ')' + { add_decl_unary(dc, FUNCTION, 0, (arith)0, fm, pl); + fm = NO_PARAMS; + } + | + arrayer(&count) + {add_decl_unary(dc, ARRAY, 0, count, NO_PARAMS, NO_PROTO);} + ]* +| + pointer(&qual) declarator(dc) + {add_decl_unary(dc, POINTER, qual, (arith)0, NO_PARAMS, NO_PROTO);} +; + +primary_declarator(register struct declarator *dc;) : + identifier(&dc->dc_idf) +| + '(' declarator(dc) ')' +; + +arrayer(arith *sizep;) + { struct expr *expr; } +: + '[' + { *sizep = (arith)-1; } + [ + constant_expression(&expr) + { + check_array_subscript(expr); + *sizep = expr->VL_VALUE; + free_expression(expr); + } + ]? + ']' +; + +formal_list (struct formal **fmp;) +: + formal(fmp) [ %persistent ',' formal(fmp) ]* +; + +formal(struct formal **fmp;) + {struct idf *idf; } +: + identifier(&idf) + { + register struct formal *new = new_formal(); + + new->fm_idf = idf; + new->next = *fmp; + *fmp = new; + if (idf->id_def && idf->id_def->df_sc == TYPEDEF) { + error("typedef name %s may not be redeclared as a parameter", idf->id_text); + } + } +; + +/* Change 2 */ +enum_specifier(register struct type **tpp;) + { + struct idf *idf; + arith l = (arith)0; + } +: + {if (*tpp) error("multiple types in declaration");} + ENUM + [ + {declare_struct(ENUM, (struct idf *) 0, tpp);} + enumerator_pack(*tpp, &l) + | + identifier(&idf) + [ + {declare_struct(ENUM, idf, tpp);} + enumerator_pack(*tpp, &l) + { +#ifdef DBSYMTAB + if (options['g']) { + stb_tag(idf->id_tag, idf->id_text); + } +#endif /*DBSYMTAB */ + } + | + {apply_struct(ENUM, idf, tpp);} + /* empty */ + ] + ] +; + +enumerator_pack(register struct type *tp; arith *lp;) : + '{' + enumerator(tp, lp) + [%while (AHEAD != '}') + ',' + enumerator(tp, lp) + ]* + [ + ',' {warning("unexpected trailing comma in enumerator pack");} + ]? + '}' + {tp->tp_size = int_size;} + /* fancy implementations that put small enums in 1 byte + or so should start here. + */ +; + +enumerator(struct type *tp; arith *lp;) + { + struct idf *idf; + struct expr *expr; + } +: + identifier(&idf) + [ + '=' + constant_expression(&expr) + { + *lp = expr->VL_VALUE; + free_expression(expr); + } + ]? + {declare_enum(tp, idf, (*lp)++);} +; + +/* 8.5 */ +struct_or_union_specifier(register struct type **tpp;) + { + int fund; + struct idf *idfX; + register struct idf *idf; + } +: + {if (*tpp) error("multiple types in declaration");} + [ STRUCT | UNION ] + {fund = DOT;} + [ + { + declare_struct(fund, (struct idf *)0, tpp); + } + struct_declaration_pack(*tpp) + | + identifier(&idfX) { idf = idfX; } + [ + { + declare_struct(fund, idf, tpp); + (idf->id_tag->tg_busy)++; + } + struct_declaration_pack(*tpp) + { + (idf->id_tag->tg_busy)--; +#ifdef DBSYMTAB + if (options['g']) { + stb_tag(idf->id_tag, idf->id_text); + } +#endif /*DBSYMTAB */ + } + | + { + /* a ';' means an empty declaration (probably) + * this means that we have to declare a new + * structure. (yegh) + */ + if (DOT == ';' && + ( !idf->id_tag || + idf->id_tag->tg_level != level || + idf->id_tag->tg_type->tp_size < 0 + )) declare_struct(fund, idf, tpp); + else apply_struct(fund, idf, tpp); + } + /* empty */ + ] + ] +; + +struct_declaration_pack(register struct type *stp;) + { + struct sdef **sdefp = &stp->tp_sdef; + arith size = (arith)0; + } +: + /* The size is only filled in after the whole struct has + been read, to prevent recursive definitions. + */ + '{' + struct_declaration(stp, &sdefp, &size)+ + '}' + {stp->tp_size = align(size, stp->tp_align); + completed(stp); + } +; + +struct_declaration(struct type *stp; struct sdef ***sdefpp; arith *szp;) + {struct type *tp;} +: + type_specifier(&tp) struct_declarator_list(tp, stp, sdefpp, szp) ';' +; + +struct_declarator_list(struct type *tp; struct type *stp; + struct sdef ***sdefpp; arith *szp;) +: + struct_declarator(tp, stp, sdefpp, szp) + [ ',' struct_declarator(tp, stp, sdefpp, szp) ]* +; + +struct_declarator(struct type *tp; struct type *stp; + struct sdef ***sdefpp; arith *szp;) + { + struct declarator Dc; + struct field *fd = 0; + } +: + { + Dc = null_declarator; + } +[ + declarator(&Dc) + {reject_params(&Dc);} + bit_expression(&fd)? +| + {Dc.dc_idf = gen_idf();} + bit_expression(&fd) +] + {add_sel(stp, declare_type(tp, &Dc), Dc.dc_idf, sdefpp, szp, fd);} + {remove_declarator(&Dc);} +; + +bit_expression(struct field **fd;) + { struct expr *expr; } +: + { + *fd = new_field(); + } + ':' + constant_expression(&expr) + { + (*fd)->fd_width = expr->VL_VALUE; + free_expression(expr); +#ifdef NOBITFIELD + error("bitfields are not implemented"); +#endif /* NOBITFIELD */ + } +; + +/* 8.7 */ +cast(struct type **tpp;) + {struct declarator Dc;} +: + {Dc = null_declarator;} + '(' + type_specifier(tpp) + abstract_declarator(&Dc) + ')' + {*tpp = declare_type(*tpp, &Dc);} + {remove_declarator(&Dc);} +; + +/* This code is an abject copy of that of 'declarator', for lack of + a two-level grammar. +*/ +abstract_declarator(register struct declarator *dc;) + { struct proto *pl = NO_PROTO; + arith count; + int qual; + } +: + primary_abstract_declarator(dc) + [ + '(' + [ + parameter_type_list(&pl) + | + /* empty */ + ] + ')' + {add_decl_unary(dc, FUNCTION, 0, (arith)0, NO_PARAMS, pl); + if (pl) remove_proto_idfs(pl); + } + | + arrayer(&count) + {add_decl_unary(dc, ARRAY, 0, count, NO_PARAMS, NO_PROTO);} + ]* +| + pointer(&qual) abstract_declarator(dc) + {add_decl_unary(dc, POINTER, qual, (arith)0, NO_PARAMS, NO_PROTO);} +; + +%first first_of_parameter_type_list, parameter_type_list; + +primary_abstract_declarator(struct declarator *dc;) +: +[%if (AHEAD == ')' || first_of_parameter_type_list(AHEAD)) + /* empty */ +| + '(' abstract_declarator(dc) ')' +] +; + +parameter_type_list(struct proto **plp;) + { int save_level; } +: + { if (level > L_PROTO) { + save_level = level; + level = L_PROTO; + } else level--; + } + parameter_decl_list(plp) + [ + ',' ELLIPSIS + { register struct proto *new = new_proto(); + + new->next = *plp; + new->pl_flag = PL_ELLIPSIS; + *plp = new; + } + + ]? + { check_for_void(*plp); + if (level == L_PROTO) + level = save_level; + else level++; + } +; + +parameter_decl_list(struct proto **plp;) +: + parameter_decl(plp) + [ %while (AHEAD != ELLIPSIS) + %persistent + ',' parameter_decl(plp) + ]* +; + +parameter_decl(struct proto **plp;) + { register struct proto *new = new_proto(); + struct declarator Dc; + struct decspecs Ds; + } +: + { Dc = null_declarator; + Ds = null_decspecs; + } + decl_specifiers(&Ds) + parameter_declarator(&Dc) + { add_proto(new, &Ds, &Dc, level); + new->next = *plp; + *plp = new; + remove_declarator(&Dc); + } +; + +/* This is weird. Due to the LR structure of the ANSI C grammar + we have to duplicate the actions of 'declarator' and + 'abstract_declarator'. Calling these separately, as in + + parameter_decl: + decl_specifiers + [ + declarator + | + abstract_declarator + ] + + + gives us a conflict on the terminals '(' and '*'. E.i. on + some input, it is impossible to decide which rule we take. + Combining the two declarators into one common declarator + is out of the question, since this results in an empty + string for the non-terminal 'declarator'. + So we combine the two only for the use of parameter_decl, + since this is the only place where they don't give + conflicts. However, this makes the grammar messy. +*/ +parameter_declarator(register struct declarator *dc;) + { struct formal *fm = NO_PARAMS; + struct proto *pl = NO_PROTO; + arith count; + int qual; + } +: + primary_parameter_declarator(dc) + [ + '(' + [ %if (DOT != IDENTIFIER) + parameter_type_list(&pl) + | + formal_list(&fm) + | + /* empty */ + ] + ')' + { add_decl_unary(dc, FUNCTION, 0, (arith)0, fm, pl); + reject_params(dc); + } + | + arrayer(&count) + {add_decl_unary(dc, ARRAY, 0, count, NO_PARAMS, NO_PROTO);} + ]* +| + pointer(&qual) parameter_declarator(dc) + {add_decl_unary(dc, POINTER, qual, (arith)0, NO_PARAMS, NO_PROTO);} +; + +primary_parameter_declarator(register struct declarator *dc;) +: +[%if (AHEAD == ')' || first_of_parameter_type_list(AHEAD) + && (AHEAD != IDENTIFIER)) + /* empty */ +| + identifier(&dc->dc_idf) +| + '(' parameter_declarator(dc) ')' +] +; + +pointer(int *qual;) +: + '*' type_qualifier_list(qual) +; + +/* Type qualifiers may come in three flavours: + volatile, const, const volatile. + These all have different semantic properties: + + volatile: + means that the object can be modified + without prior knowledge of the implementation. + + const: + means that the object can not be modified; thus + it's illegal to use this as a l-value. + + const volatile: + means that the object can be modified without + prior knowledge of the implementation, but may + not be used as a l-value. +*/ +/* 3.5.4 */ +type_qualifier_list(int *qual;) +: + { *qual = 0; } + [ + VOLATILE + { if (*qual & TQ_VOLATILE) + error("repeated type qualifier"); + *qual |= TQ_VOLATILE; + } + | + CONST + { if (*qual & TQ_CONST) + error("repeated type qualifier"); + *qual |= TQ_CONST; + } + ]* +; + +empty: +; diff --git a/lang/cem/cemcom.ansi/declar.str b/lang/cem/cemcom.ansi/declar.str index 884bd97e7..ebe1869bd 100644 --- a/lang/cem/cemcom.ansi/declar.str +++ b/lang/cem/cemcom.ansi/declar.str @@ -2,6 +2,9 @@ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * See the copyright notice in the ACK home directory, in the file "Copyright". */ + #ifndef DECLAR_H_ + #define DECLAR_H_ + /* $Id$ */ /* DEFINITION OF DECLARATOR DESCRIPTORS */ @@ -39,3 +42,5 @@ struct decl_unary { extern struct type *declare_type(); extern struct declarator null_declarator; + +#endif diff --git a/lang/cem/cemcom.ansi/declarator.c b/lang/cem/cemcom.ansi/declarator.c index 212b8aeb1..2795bda86 100644 --- a/lang/cem/cemcom.ansi/declarator.c +++ b/lang/cem/cemcom.ansi/declarator.c @@ -6,6 +6,7 @@ /* D E C L A R A T O R M A N I P U L A T I O N */ #include "parameters.h" +#include "declarator.h" #include #include #include "arith.h" @@ -14,18 +15,20 @@ #include "Lpars.h" #include "declar.h" #include "def.h" +#include "idf.h" #include "label.h" #include "expr.h" #include "sizes.h" #include "level.h" +#include "error.h" extern char options[]; struct declarator null_declarator; struct type * -declare_type(tp, dc) - struct type *tp; - struct declarator *dc; +declare_type( + struct type *tp, + struct declarator *dc) { /* Applies the decl_unary list starting at dc->dc_decl_unary to the type tp and returns the result. @@ -43,12 +46,7 @@ declare_type(tp, dc) return tp; } -add_decl_unary(dc, fund, qual, count, fm, pl) - register struct declarator *dc; - int qual; - arith count; - struct formal *fm; - struct proto *pl; +void add_decl_unary(register struct declarator *dc, int fund, int qual, arith count, struct formal *fm, struct proto *pl) { /* A decl_unary describing a constructor with fundamental type fund and with size count is inserted in front of the @@ -75,8 +73,7 @@ add_decl_unary(dc, fund, qual, count, fm, pl) dc->dc_decl_unary = new; } -remove_declarator(dc) - struct declarator *dc; +void remove_declarator(struct declarator *dc) { /* The decl_unary list starting at dc->dc_decl_unary is removed. @@ -91,8 +88,7 @@ remove_declarator(dc) } } -reject_params(dc) - register struct declarator *dc; +void reject_params(register struct declarator *dc) { /* The declarator is checked to have no parameters, if it is an old-style function. If it is a new-style function, @@ -120,8 +116,7 @@ reject_params(dc) } } -check_array_subscript(expr) - register struct expr *expr; +void check_array_subscript(register struct expr *expr) { arith size = expr->VL_VALUE; diff --git a/lang/cem/cemcom.ansi/declarator.h b/lang/cem/cemcom.ansi/declarator.h new file mode 100644 index 000000000..abda9de1f --- /dev/null +++ b/lang/cem/cemcom.ansi/declarator.h @@ -0,0 +1,28 @@ +/* Copyright (c) 2019 ACK Project. + * See the copyright notice in the ACK home directory, + * in the file "Copyright". + * + * Created on: 2019-02-06 + * + */ +#ifndef DECLARATOR_H_ +#define DECLARATOR_H_ + +#include "arith.h" + +/* Forward declarations. */ +struct type; +struct declarator; +struct formal; +struct proto; +struct expr; + +struct type * +declare_type(struct type *tp, struct declarator *dc); +void add_decl_unary(register struct declarator *dc, int fund, int qual, + arith count, struct formal *fm, struct proto *pl); +void remove_declarator(struct declarator *dc); +void reject_params(register struct declarator *dc); +void check_array_subscript(register struct expr *expr); + +#endif /* DECLARATOR_H_ */ diff --git a/lang/cem/cemcom.ansi/decspecs.c b/lang/cem/cemcom.ansi/decspecs.c index bef0c0d2b..42465e213 100644 --- a/lang/cem/cemcom.ansi/decspecs.c +++ b/lang/cem/cemcom.ansi/decspecs.c @@ -6,12 +6,13 @@ /* D E C L A R A T I O N S P E C I F I E R C H E C K I N G */ #include -#include "Lpars.h" #include "decspecs.h" +#include "Lpars.h" #include "arith.h" #include "type.h" #include "level.h" #include "def.h" +#include "error.h" extern char options[]; extern int level; @@ -20,36 +21,35 @@ extern struct type *qualifier_type(); struct decspecs null_decspecs; -do_decspecs(ds) - register struct decspecs *ds; +void do_decspecs(register struct decspecs *ds) { /* The provisional decspecs ds as obtained from the program - is turned into a legal consistent decspecs. - */ + is turned into a legal consistent decspecs. + */ register struct type *tp = ds->ds_type; - + assert(level != L_FORMAL1); - - if ( level == L_GLOBAL && - (ds->ds_sc == AUTO || ds->ds_sc == REGISTER) - ) { - error("no global %s variable allowed", - symbol2str(ds->ds_sc)); + + if (level == L_GLOBAL && (ds->ds_sc == AUTO || ds->ds_sc == REGISTER)) + { + error("no global %s variable allowed", symbol2str(ds->ds_sc)); ds->ds_sc = GLOBAL; } - if (level == L_FORMAL2) { - if (ds->ds_sc_given && - ds->ds_sc != REGISTER){ + if (level == L_FORMAL2) + { + if (ds->ds_sc_given && ds->ds_sc != REGISTER) + { error("%s formal illegal", symbol2str(ds->ds_sc)); ds->ds_sc = FORMAL; } } /* Since type qualifiers may be associated with types by means - of typedefs, we have to perform same basic tests down here. - */ - if (tp != (struct type *)0) { + of typedefs, we have to perform same basic tests down here. + */ + if (tp != (struct type *) 0) + { if ((ds->ds_typequal & TQ_VOLATILE) && (tp->tp_typequal & TQ_VOLATILE)) error("indirect repeated type qualifier"); if ((ds->ds_typequal & TQ_CONST) && (tp->tp_typequal & TQ_CONST)) @@ -58,49 +58,74 @@ do_decspecs(ds) } /* The tests concerning types require a full knowledge of the - type and will have to be postponed to declare_idf. - */ + type and will have to be postponed to declare_idf. + */ /* some adjustments as described in 3.5.2. */ - if (tp == 0) { + if (tp == 0) + { ds->ds_notypegiven = 1; tp = int_type; } - if (ds->ds_size) { + if (ds->ds_size) + { register int ds_isshort = (ds->ds_size == SHORT); - if (ds->ds_typedef) goto SIZE_ERROR; /* yes */ - if (tp == int_type) { - if (ds_isshort) tp = short_type; - else tp = long_type; - } else if (tp == double_type && !ds_isshort ) { + if (ds->ds_typedef) + goto SIZE_ERROR; + /* yes */ + if (tp == int_type) + { + if (ds_isshort) + tp = short_type; + else + tp = long_type; + } + else if (tp == double_type && !ds_isshort) + { tp = lngdbl_type; - } else { - SIZE_ERROR: - error("%s with illegal type",symbol2str(ds->ds_size)); + } + else + { + SIZE_ERROR: error("%s with illegal type", symbol2str(ds->ds_size)); } ds->ds_notypegiven = 0; } - if (ds->ds_unsigned) { + if (ds->ds_unsigned) + { register int ds_isunsigned = (ds->ds_unsigned == UNSIGNED); - if (ds->ds_typedef) goto SIGN_ERROR; /* yes */ + if (ds->ds_typedef) + goto SIGN_ERROR; + /* yes */ /* * All integral types are signed by default (char too), * so the case that ds->ds_unsigned == SIGNED can be ignored. */ - if (tp == schar_type) { - if (ds_isunsigned) tp = uchar_type; - } else if (tp == short_type) { - if (ds_isunsigned) tp = ushort_type; - } else if (tp == int_type) { - if (ds_isunsigned) tp = uint_type; - } else if (tp == long_type) { - if (ds_isunsigned) tp = ulong_type; - } else { - SIGN_ERROR: - error("%s with illegal type" - , symbol2str(ds->ds_unsigned)); + if (tp == schar_type) + { + if (ds_isunsigned) + tp = uchar_type; + } + else if (tp == short_type) + { + if (ds_isunsigned) + tp = ushort_type; + } + else if (tp == int_type) + { + if (ds_isunsigned) + tp = uint_type; + } + else if (tp == long_type) + { + if (ds_isunsigned) + tp = ulong_type; + } + else + { + SIGN_ERROR: error("%s with illegal type", + symbol2str(ds->ds_unsigned)); } ds->ds_notypegiven = 0; } @@ -108,15 +133,12 @@ do_decspecs(ds) } /* Make tp into a qualified type. This is not as trivial as it - may seem. If tp is a fundamental type the qualified type is - either existent or will be generated. - In case of a complex type the top of the type list will be - replaced by a qualified version. -*/ -struct type * -qualifier_type(tp, typequal) - register struct type *tp; - int typequal; + may seem. If tp is a fundamental type the qualified type is + either existent or will be generated. + In case of a complex type the top of the type list will be + replaced by a qualified version. + */ +struct type *qualifier_type(register struct type *tp, int typequal) { register struct type *dtp = tp; register int fund = tp->tp_fund; @@ -124,32 +146,34 @@ qualifier_type(tp, typequal) while (dtp && dtp->tp_typequal != typequal) dtp = dtp->next; - if (!dtp) { + if (!dtp) + { dtp = create_type(fund); dtp->tp_unsigned = tp->tp_unsigned; dtp->tp_align = tp->tp_align; dtp->tp_typequal = typequal; dtp->tp_size = tp->tp_size; #if 0 -/* The tp_function field does not exist now. See the comment in the - function_of() routine. -*/ + /* The tp_function field does not exist now. See the comment in the + function_of() routine. + */ dtp->tp_function = tp->tp_function; #endif - switch (fund) { + switch (fund) + { case ARRAY: - if (typequal) { - tp->tp_up = qualifier_type(tp->tp_up, typequal); - dtp->tp_typequal = typequal = 0; + if (typequal) + { + tp->tp_up = qualifier_type(tp->tp_up, typequal); + dtp->tp_typequal = typequal = 0; } goto nottagged; case FIELD: dtp->tp_field = tp->tp_field; /* fallthrough */ case POINTER: - case FUNCTION: /* dont't assign tp_proto */ - nottagged: - dtp->tp_up = tp->tp_up; + case FUNCTION: /* dont't assign tp_proto */ + nottagged: dtp->tp_up = tp->tp_up; break; case STRUCT: case UNION: @@ -163,6 +187,6 @@ qualifier_type(tp, typequal) dtp->next = tp->next; /* don't know head or tail */ tp->next = dtp; } - return(dtp); + return (dtp); } diff --git a/lang/cem/cemcom.ansi/decspecs.h b/lang/cem/cemcom.ansi/decspecs.h index 73a4048e2..7256b739d 100644 --- a/lang/cem/cemcom.ansi/decspecs.h +++ b/lang/cem/cemcom.ansi/decspecs.h @@ -2,6 +2,9 @@ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * See the copyright notice in the ACK home directory, in the file "Copyright". */ +#ifndef DECSPECS_H_ +#define DECSPECS_H_ + /* $Id$ */ /* DECLARATION SPECIFIER DEFINITION */ @@ -19,3 +22,10 @@ struct decspecs { extern struct type *qualifier_type(); extern struct decspecs null_decspecs; + +struct type; + +void do_decspecs(register struct decspecs *ds); +struct type *qualifier_type(register struct type *tp, int typequal); + +#endif diff --git a/lang/cem/cemcom.ansi/def.str b/lang/cem/cemcom.ansi/def.str index 0ad7af339..ad528a664 100644 --- a/lang/cem/cemcom.ansi/def.str +++ b/lang/cem/cemcom.ansi/def.str @@ -2,6 +2,9 @@ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * See the copyright notice in the ACK home directory, in the file "Copyright". */ +#ifndef DEF_H_ +#define DEF_H_ + /* $Id$ */ /* IDENTIFIER DEFINITION DESCRIPTOR */ @@ -38,3 +41,5 @@ struct def { /* for ordinary tags */ #define REG_BONUS 10 /* register candidate, declared as such */ /* ALLOCDEF "def" 50 */ + +#endif diff --git a/lang/cem/cemcom.ansi/domacro.c b/lang/cem/cemcom.ansi/domacro.c index d6fc4c501..dc77827ea 100644 --- a/lang/cem/cemcom.ansi/domacro.c +++ b/lang/cem/cemcom.ansi/domacro.c @@ -8,12 +8,17 @@ #include #include #include +#include "domacro.h" #include "parameters.h" #include "idf.h" +#include "interface.h" #include "arith.h" #include "LLlex.h" #include "Lpars.h" #include "input.h" +#include "pragma.h" +#include "skip.h" +#include "error.h" #ifdef DBSYMTAB #include @@ -23,7 +28,9 @@ int IncludeLevel = 0; extern char options[]; -struct idf* GetIdentifier(skiponerr) int skiponerr; /* skip the rest of the line on error */ +static void do_line(unsigned int); + +struct idf* GetIdentifier(int skiponerr) /* skip the rest of the line on error */ { /* returns a pointer to the descriptor of the identifier that is read from the input stream. When the input does not contain @@ -44,7 +51,7 @@ struct idf* GetIdentifier(skiponerr) int skiponerr; /* skip the rest of the line return tk.tk_idf; } -domacro() +void domacro(void) { int tok; struct token tk; @@ -70,7 +77,7 @@ domacro() SkipToNewLine(); } -do_line(l) unsigned int l; +static void do_line(unsigned int l) { struct token tk; int t = GetToken(&tk); diff --git a/lang/cem/cemcom.ansi/domacro.h b/lang/cem/cemcom.ansi/domacro.h new file mode 100644 index 000000000..75d6085a0 --- /dev/null +++ b/lang/cem/cemcom.ansi/domacro.h @@ -0,0 +1,16 @@ +/* Copyright (c) 2019 ACK Project. + * See the copyright notice in the ACK home directory, + * in the file "Copyright". + * + * Created on: 2019-02-06 + * + */ +#ifndef DOMACRO_H_ +#define DOMACRO_H_ + +struct idf; + +struct idf* GetIdentifier(int skiponerr) ; +void domacro(void); + +#endif /* DOMACRO_H_ */ diff --git a/lang/cem/cemcom.ansi/error.c b/lang/cem/cemcom.ansi/error.c index 6f2283b74..76421ed80 100644 --- a/lang/cem/cemcom.ansi/error.c +++ b/lang/cem/cemcom.ansi/error.c @@ -6,6 +6,7 @@ /* E R R O R A N D D I A G N O S T I C R O U T I N E S */ #include "parameters.h" +#include "error.h" #if __STDC__ #include #else @@ -17,13 +18,15 @@ #else #include "l_em.h" #endif /* LINT */ - +#include #include "tokenname.h" #include +#include "interface.h" #include "arith.h" #include "label.h" #include "expr.h" #include "def.h" +#include "print.h" #include "LLlex.h" /* This file contains the error-message and diagnostic @@ -56,12 +59,11 @@ extern char loptions[]; FileName, expression errors get their information from the expression, whereas other errors use the information in the token. */ - -static void _error(); +static void _error(int, char *, unsigned int, char*, va_list); #if __STDC__ /*VARARGS*/ -error(char *fmt, ...) +void error(char *fmt, ...) { va_list ap; @@ -73,7 +75,7 @@ error(char *fmt, ...) } /*VARARGS*/ -expr_error(struct expr *expr, char *fmt, ...) +void expr_error(struct expr *expr, char *fmt, ...) { va_list ap; @@ -89,7 +91,7 @@ expr_error(struct expr *expr, char *fmt, ...) } /*VARARGS*/ -lexstrict(char *fmt, ...) +void lexstrict(char *fmt, ...) { va_list ap; @@ -101,7 +103,7 @@ lexstrict(char *fmt, ...) } /*VARARGS*/ -strict(char *fmt, ...) +void strict(char *fmt, ...) { va_list ap; @@ -113,7 +115,7 @@ strict(char *fmt, ...) } /*VARARGS*/ -expr_strict(struct expr *expr, char *fmt, ...) +void expr_strict(struct expr *expr, char *fmt, ...) { va_list ap; @@ -129,7 +131,7 @@ expr_strict(struct expr *expr, char *fmt, ...) #ifdef DEBUG /*VARARGS*/ -debug(char *fmt, ...) +void debug(char *fmt, ...) { va_list ap; @@ -142,7 +144,7 @@ debug(char *fmt, ...) #endif /* DEBUG */ /*VARARGS*/ -warning(char *fmt, ...) +void warning(char *fmt, ...) { va_list ap; @@ -154,7 +156,7 @@ warning(char *fmt, ...) } /*VARARGS*/ -expr_warning(struct expr *expr, char *fmt, ...) +void expr_warning(struct expr *expr, char *fmt, ...) { va_list ap; @@ -171,7 +173,7 @@ expr_warning(struct expr *expr, char *fmt, ...) #ifdef LINT /*VARARGS*/ -def_warning(struct def *def, char *fmt, ...) +void def_warning(struct def *def, char *fmt, ...) { va_list ap; @@ -184,7 +186,7 @@ def_warning(struct def *def, char *fmt, ...) /*VARARGS*/ -hwarning(char *fmt, ...) +void hwarning(char *fmt, ...) { va_list ap; @@ -197,7 +199,7 @@ hwarning(char *fmt, ...) } /*VARARGS*/ -awarning(char *fmt, ...) +void awarning(char *fmt, ...) { va_list ap; @@ -212,7 +214,7 @@ awarning(char *fmt, ...) #endif /* LINT */ /*VARARGS*/ -lexerror(char *fmt, ...) +void lexerror(char *fmt, ...) { va_list ap; @@ -224,7 +226,7 @@ lexerror(char *fmt, ...) } /*VARARGS*/ -lexwarning(char *fmt, ...) +void lexwarning(char *fmt, ...) { va_list ap; @@ -236,7 +238,7 @@ lexwarning(char *fmt, ...) } /*VARARGS*/ -crash(char *fmt, ...) +void crash(char *fmt, ...) { va_list ap; @@ -256,7 +258,7 @@ crash(char *fmt, ...) } /*VARARGS*/ -fatal(char *fmt, ...) +void fatal(char *fmt, ...) { va_list ap; @@ -272,7 +274,7 @@ fatal(char *fmt, ...) } #else /*VARARGS*/ -error(va_alist) /* fmt, args */ +void error(va_alist) /* fmt, args */ va_dcl { va_list ap; @@ -286,7 +288,7 @@ error(va_alist) /* fmt, args */ } /*VARARGS*/ -expr_error(va_alist) /* expr, fmt, args */ +void expr_error(va_alist) /* expr, fmt, args */ va_dcl { va_list ap; @@ -306,7 +308,7 @@ expr_error(va_alist) /* expr, fmt, args */ } /*VARARGS*/ -lexstrict(va_alist) +void lexstrict(va_alist) va_dcl { va_list ap; @@ -320,7 +322,7 @@ lexstrict(va_alist) } /*VARARGS*/ -strict(va_alist) +void strict(va_alist) va_dcl { va_list ap; @@ -334,7 +336,7 @@ strict(va_alist) } /*VARARGS*/ -expr_strict(va_alist) /* expr, fmt, args */ +void expr_strict(va_alist) /* expr, fmt, args */ va_dcl { va_list ap; @@ -354,7 +356,7 @@ expr_strict(va_alist) /* expr, fmt, args */ #ifdef DEBUG /*VARARGS*/ -debug(va_alist) +void debug(va_alist) va_dcl { va_list ap; @@ -369,7 +371,7 @@ debug(va_alist) #endif /* DEBUG */ /*VARARGS*/ -warning(va_alist) +void warning(va_alist) va_dcl { va_list ap; @@ -383,7 +385,7 @@ warning(va_alist) } /*VARARGS*/ -expr_warning(va_alist) /* expr, fmt, args */ +void expr_warning(va_alist) /* expr, fmt, args */ va_dcl { va_list ap; @@ -404,7 +406,7 @@ expr_warning(va_alist) /* expr, fmt, args */ #ifdef LINT /*VARARGS*/ -def_warning(va_alist) /* def, fmt, args */ +void def_warning(va_alist) /* def, fmt, args */ va_dcl { va_list ap; @@ -421,7 +423,7 @@ def_warning(va_alist) /* def, fmt, args */ /*VARARGS*/ -hwarning(va_alist) /* fmt, args */ +void hwarning(va_alist) /* fmt, args */ va_dcl { va_list ap; @@ -436,7 +438,7 @@ hwarning(va_alist) /* fmt, args */ } /*VARARGS*/ -awarning(va_alist) /* fmt, args */ +void awarning(va_alist) /* fmt, args */ va_dcl { va_list ap; @@ -453,7 +455,7 @@ awarning(va_alist) /* fmt, args */ #endif /* LINT */ /*VARARGS*/ -lexerror(va_alist) /* fmt, args */ +void lexerror(va_alist) /* fmt, args */ va_dcl { va_list ap; @@ -467,7 +469,7 @@ lexerror(va_alist) /* fmt, args */ } /*VARARGS*/ -lexwarning(va_alist) /* fmt, args */ +void lexwarning(va_alist) /* fmt, args */ va_dcl { va_list ap; @@ -481,7 +483,7 @@ lexwarning(va_alist) /* fmt, args */ } /*VARARGS*/ -crash(va_alist) /* fmt, args */ +void crash(va_alist) /* fmt, args */ va_dcl { va_list ap; @@ -503,7 +505,7 @@ crash(va_alist) /* fmt, args */ } /*VARARGS*/ -fatal(va_alist) /* fmt, args */ +void fatal(va_alist) /* fmt, args */ va_dcl { va_list ap; @@ -521,13 +523,7 @@ fatal(va_alist) /* fmt, args */ } #endif -static void -_error(class, fn, ln, fmt, ap) - int class; - char *fn; - unsigned int ln; - char *fmt; - va_list ap; +static void _error(int class, char *fn, unsigned int ln, char* fmt, va_list ap) { char *remark; @@ -614,9 +610,9 @@ _error(class, fn, ln, fmt, ap) #endif /* LINT */ if (fn) - fprint(ERROUT, "\"%s\", line %u: ", fn, ln); + fprint(stderr, "\"%s\", line %u: ", fn, ln); if (remark) - fprint(ERROUT, "%s ", remark); - doprnt(ERROUT, fmt, ap); /* contents of error */ - fprint(ERROUT, "\n"); + fprint(stderr, "%s ", remark); + doprnt(stderr, fmt, ap); /* contents of error */ + fprint(stderr, "\n"); } diff --git a/lang/cem/cemcom.ansi/error.h b/lang/cem/cemcom.ansi/error.h new file mode 100644 index 000000000..595cd2aba --- /dev/null +++ b/lang/cem/cemcom.ansi/error.h @@ -0,0 +1,94 @@ +/* Copyright (c) 2019 ACK Project. + * See the copyright notice in the ACK home directory, + * in the file "Copyright". + * + * Created on: 2019-02-06 + * + */ +#ifndef ERROR_H_ +#define ERROR_H_ + +struct expr; + +#if __STDC__ +/*VARARGS*/ +void error(char *fmt, ...); +/*VARARGS*/ +void expr_error(struct expr *expr, char *fmt, ...); +/*VARARGS*/ +void lexstrict(char *fmt, ...); +/*VARARGS*/ +void strict(char *fmt, ...); +/*VARARGS*/ +void expr_strict(struct expr *expr, char *fmt, ...); + +#ifdef DEBUG +/*VARARGS*/ +void debug(char *fmt, ...); +#endif /* DEBUG */ + +/*VARARGS*/ +void warning(char *fmt, ...); +/*VARARGS*/ +void expr_warning(struct expr *expr, char *fmt, ...); +#ifdef LINT +/*VARARGS*/ +void def_warning(struct def *def, char *fmt, ...); +/*VARARGS*/ +void hwarning(char *fmt, ...); +/*VARARGS*/ +void awarning(char *fmt, ...); +#endif /* LINT */ + +/*VARARGS*/ +void lexerror(char *fmt, ...); +/*VARARGS*/ +void lexwarning(char *fmt, ...); +/*VARARGS*/ +void crash(char *fmt, ...); +/*VARARGS*/ +void fatal(char *fmt, ...); + +#else +/*VARARGS*/ +void error(va_alist); /* fmt, args */ +/*VARARGS*/ +void expr_error(va_alist); /* expr, fmt, args */ +/*VARARGS*/ +void lexstrict(va_alist); +/*VARARGS*/ +void strict(va_alist); +/*VARARGS*/ +void expr_strict(va_alist); /* expr, fmt, args */ +#ifdef DEBUG +/*VARARGS*/ +void debug(va_alist); +#endif /* DEBUG */ + +/*VARARGS*/ +void warning(va_alist); +/*VARARGS*/ +void expr_warning(va_alist); /* expr, fmt, args */ +#ifdef LINT + +/*VARARGS*/ +void def_warning(va_alist); /* def, fmt, args */ +/*VARARGS*/ +void hwarning(va_alist); /* fmt, args */ +/*VARARGS*/ +void awarning(va_alist); /* fmt, args */ +#endif /* LINT */ + +/*VARARGS*/ +void lexerror(va_alist); /* fmt, args */ +/*VARARGS*/ +void lexwarning(va_alist); /* fmt, args */ +/*VARARGS*/ +void crash(va_alist); /* fmt, args */ +/*VARARGS*/ +void fatal(va_alist); /* fmt, args */ +#endif + + + +#endif /* ERROR_H_ */ diff --git a/lang/cem/cemcom.ansi/estack.str b/lang/cem/cemcom.ansi/estack.str index b65629ed6..0718cca64 100644 --- a/lang/cem/cemcom.ansi/estack.str +++ b/lang/cem/cemcom.ansi/estack.str @@ -2,6 +2,9 @@ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * See the copyright notice in the ACK home directory, in the file "Copyright". */ + #ifndef ESTACK_H_ + #define ESTACK_H_ + /* $Id$ */ /* EXPRESSION STACK */ /* Used for global initializations */ @@ -19,3 +22,5 @@ struct e_stack { #define last_offset s_cnt2 #define elem_count s_cnt1 #define nelem s_cnt2 + +#endif \ No newline at end of file diff --git a/lang/cem/cemcom.ansi/eval.c b/lang/cem/cemcom.ansi/eval.c index 0ec25dac6..352d590b3 100644 --- a/lang/cem/cemcom.ansi/eval.c +++ b/lang/cem/cemcom.ansi/eval.c @@ -14,6 +14,8 @@ #include #include #include +#include "interface.h" +#include "eval.h" #include "idf.h" #include "arith.h" #include "type.h" @@ -22,13 +24,21 @@ #include "def.h" #include "expr.h" #include "sizes.h" +#include "field.h" #include "Lpars.h" #include "level.h" +#include "conversion.h" #include "stack.h" +#include "struct.h" #include "align.h" #include "mes.h" #include "atw.h" +#include "ch3.h" +#include "util.h" +#include "blocks.h" +#include "dataflow.h" #include "specials.h" +#include "error.h" #define CRASH() crash("EVAL: CRASH at line %u", __LINE__) @@ -37,8 +47,12 @@ arith NewLocal(); /* util.c */ #define LocalPtrVar() NewLocal(pointer_size, pointer_align, reg_pointer, REGISTER) extern int err_occurred; /* error.c */ -void store_val(); -void load_val(); + +/* Forward internal declarations */ +static void operands(register struct expr *, int); +static void ptr_add(arith size); +static void truthvalue(int relop); +static void compare(int relop, label lbl); /* EVAL() is the main expression-tree evaluator, which turns any legal expression tree into EM code. parameters.h: @@ -66,11 +80,7 @@ void load_val(); labels, in case they are specified (i.e. are non-zero) */ -void -EVAL(expr, val, code, true_label, false_label) - register struct expr *expr; - int val, code; - label true_label, false_label; +void EVAL(register struct expr *expr, int val, int code, label true_label, label false_label) { int vol = (code != TRUE && recurqual(expr->ex_type, TQ_VOLATILE)); register int gencode = code == TRUE; @@ -659,9 +669,7 @@ EVAL(expr, val, code, true_label, false_label) } /* compare() serves as an auxiliary function of EVAL */ -compare(relop, lbl) - int relop; - label lbl; +static void compare(int relop, label lbl) { switch (relop) { case '<': @@ -688,8 +696,7 @@ compare(relop, lbl) } /* truthvalue() serves as an auxiliary function of EVAL */ -truthvalue(relop) - int relop; +static void truthvalue(int relop) { switch (relop) { case '<': @@ -717,12 +724,10 @@ truthvalue(relop) /* assop() generates the opcode of an assignment operators op= */ -assop(type, oper) - register struct type *type; - int oper; +void assop(register struct type *type, int oper) { register arith size; - register uns = type->tp_unsigned; + register int uns = type->tp_unsigned; if ((int)(size = type->tp_size) < (int)word_size) size = word_size; @@ -822,8 +827,7 @@ assop(type, oper) } } -ptr_add(size) - arith size; +static void ptr_add(arith size) { if (size != pointer_size) { C_loc(size); @@ -840,10 +844,7 @@ ptr_add(size) - into a local static variable - absolute addressing */ -void -store_val(vl, tp) - register struct value *vl; - register struct type *tp; +void store_val(register struct value *vl, register struct type *tp) { register int inword = 0; register int indword = 0; @@ -911,11 +912,10 @@ store_val(vl, tp) - global variable - static variable - local variable + + rlval generate rlval or lval */ -void -load_val(expr, rlval) - register struct expr *expr; /* expression containing the value */ - int rlval; /* generate either LVAL or RVAL */ +void load_val(register struct expr *expr, int rlval) { register struct type *tp = expr->ex_type; int rvalue = (rlval == RVAL && expr->ex_lvalue != 0); @@ -1012,8 +1012,7 @@ load_val(expr, rlval) } } -load_cst(val, siz) - arith val, siz; +void load_cst(arith val, arith siz) { if ((int)siz <= (int)word_size) C_loc(val); @@ -1030,8 +1029,7 @@ load_cst(val, siz) } } -operands(expr, gencode) - register struct expr *expr; +static void operands(register struct expr *expr, int gencode) { EVAL(expr->OP_LEFT, RVAL, gencode, NO_LABEL, NO_LABEL); EVAL(expr->OP_RIGHT, RVAL, gencode, NO_LABEL, NO_LABEL); diff --git a/lang/cem/cemcom.ansi/eval.h b/lang/cem/cemcom.ansi/eval.h new file mode 100644 index 000000000..337b5ac57 --- /dev/null +++ b/lang/cem/cemcom.ansi/eval.h @@ -0,0 +1,37 @@ +/* Copyright (c) 2019 ACK Project. + * See the copyright notice in the ACK home directory, + * in the file "Copyright". + * + * Created on: 2019-02-06 + * + */ +#ifndef EVAL_H_ +#define EVAL_H_ + +#ifndef LINT + + +#include + +struct expr; +struct value; +struct type; + +void EVAL(register struct expr *expr, int val, int code, label true_label, label false_label); + +/* assop() generates the opcode of an assignment operators op= */ +void assop(register struct type *type, int oper); +/* store_val() generates code for a store operation. + There are four ways of storing data: + - into a global variable + - into an automatic local variable + - into a local static variable + - absolute addressing +*/ +void store_val(register struct value *vl, register struct type *tp); +void load_val(register struct expr *expr, int rlval); +void load_cst(arith val, arith siz); + +#endif /* LINT */ + +#endif /* EVAL_H_ */ diff --git a/lang/cem/cemcom.ansi/expr.c b/lang/cem/cemcom.ansi/expr.c index 7b686c3fe..b24c408d0 100644 --- a/lang/cem/cemcom.ansi/expr.c +++ b/lang/cem/cemcom.ansi/expr.c @@ -10,6 +10,7 @@ #include "parameters.h" #include #include +#include "expr.h" #include "idf.h" #include "arith.h" #include "def.h" @@ -22,20 +23,21 @@ #include "declar.h" #include "sizes.h" #include "level.h" +#include "cstoper.h" +#include "error.h" extern char *symbol2str(); extern char options[]; extern int InSizeof; -int -rank_of(oper) - int oper; +int rank_of(int oper) { /* The rank of the operator oper is returned. - */ - switch (oper) { + */ + switch (oper) + { default: - return 0; /* INT2INT etc. */ + return 0; /* INT2INT etc. */ case '[': case '(': case '.': @@ -48,7 +50,7 @@ rank_of(oper) case CAST: case SIZEOF: case ADDRESSOF: - return 2; /* monadic */ + return 2; /* monadic */ case '*': case '/': case '%': @@ -98,18 +100,18 @@ rank_of(oper) /*NOTREACHED*/ } -dot2expr(expp) - struct expr **expp; +void dot2expr(struct expr **expp) { /* The token in dot is converted into an expression, a - pointer to which is stored in *expp. - */ + pointer to which is stored in *expp. + */ register struct expr *ex = new_expr(); *expp = ex; ex->ex_file = dot.tk_file; ex->ex_line = dot.tk_line; - switch (DOT) { + switch (DOT) + { case IDENTIFIER: idf2expr(ex); break; @@ -125,25 +127,27 @@ dot2expr(expp) } } -idf2expr(expr) - register struct expr *expr; +void idf2expr(register struct expr *expr) { /* Dot contains an identifier which is turned into an - expression. - Note that this constitutes an applied occurrence of - the identifier. - */ - register struct idf *idf = dot.tk_idf; /* != 0*/ + expression. + Note that this constitutes an applied occurrence of + the identifier. + */ + register struct idf *idf = dot.tk_idf; /* != 0*/ register struct def *def = idf->id_def; - - if (def == 0) { - if (AHEAD == '(') { + + if (def == 0) + { + if (AHEAD == '(') + { /* function call, declare name implicitly (3.3.2.2) */ if (!options['o']) - warning("implicit declaration of function %s" - , idf->id_text); + warning("implicit declaration of function %s", idf->id_text); add_def(idf, EXTERN, funint_type, level); - } else { + } + else + { if (!is_anon_idf(idf)) error("%s undefined", idf->id_text); /* declare idf anyway */ @@ -153,8 +157,10 @@ idf2expr(expr) } /* now def != 0 */ #ifndef LINT - if (!InSizeof) { - if (! def->df_used) { + if (!InSizeof) + { + if (!def->df_used) + { #ifndef PREPEND_SCOPES code_scope(idf->id_text, def); #endif /* PREPEND_SCOPES */ @@ -163,46 +169,45 @@ idf2expr(expr) } #endif /* LINT */ expr->ex_type = def->df_type; - if (expr->ex_type == error_type) { + if (expr->ex_type == error_type) + { expr->ex_flags |= EX_ERROR; } expr->ex_lvalue = - ( def->df_type->tp_fund == FUNCTION || - def->df_type->tp_fund == ARRAY || - def->df_sc == ENUM - ) ? 0 : 1; + (def->df_type->tp_fund == FUNCTION || def->df_type->tp_fund == ARRAY + || def->df_sc == ENUM) ? 0 : 1; if (def->df_type->tp_typequal & TQ_CONST) expr->ex_flags |= EX_READONLY; if (def->df_type->tp_typequal & TQ_VOLATILE) expr->ex_flags |= EX_VOLATILE; expr->ex_class = Value; - if (def->df_sc == ENUM) { + if (def->df_sc == ENUM) + { expr->VL_CLASS = Const; expr->VL_VALUE = def->df_address; } #ifndef LINT - else - if (def->df_sc == STATIC && def->df_level >= L_LOCAL) { + else if (def->df_sc == STATIC && def->df_level >= L_LOCAL) + { expr->VL_CLASS = Label; expr->VL_LBL = def->df_address; - expr->VL_VALUE = (arith)0; + expr->VL_VALUE = (arith) 0; } #endif /* LINT */ - else { + else + { expr->VL_CLASS = Name; expr->VL_IDF = idf; - expr->VL_VALUE = (arith)0; + expr->VL_VALUE = (arith) 0; } } -string2expr(expp, str, len) - register struct expr **expp; - int len; - char *str; +void string2expr(register struct expr **expp, char *str, int len) + { /* The string in the argument is converted into an expression, - a pointer to which is stored in *expp. - */ + a pointer to which is stored in *expp. + */ register struct expr *ex = new_expr(); *expp = ex; @@ -217,25 +222,24 @@ string2expr(expp, str, len) ex->SG_LEN = len; } -int2expr(expr) - struct expr *expr; +void int2expr(struct expr *expr) { /* Dot contains an integer constant which is turned - into an expression. - */ + into an expression. + */ fill_int_expr(expr, dot.tk_ival, dot.tk_fund); } -float2expr(expr) - register struct expr *expr; +void float2expr(register struct expr *expr) { /* Dot contains a floating point constant which is turned - into an expression. - */ + into an expression. + */ register int fund; fund = dot.tk_fund; - switch (fund) { + switch (fund) + { case FLOAT: expr->ex_type = float_type; break; @@ -253,17 +257,15 @@ float2expr(expr) free(dot.tk_fval); assert(flt_status != FLT_NOFLT); if (flt_status == FLT_OVFL) - expr_warning(expr,"internal floating point overflow"); + expr_warning(expr, "internal floating point overflow"); } -struct expr* -intexpr(ivalue, fund) - arith ivalue; - int fund; +struct expr*intexpr( +arith ivalue, int fund) { /* The value ivalue is turned into an integer expression of - the size indicated by fund. - */ + the size indicated by fund. + */ register struct expr *expr = new_expr(); expr->ex_file = dot.tk_file; @@ -272,15 +274,14 @@ intexpr(ivalue, fund) return expr; } -fill_int_expr(ex, ivalue, fund) - register struct expr *ex; - arith ivalue; - int fund; +void fill_int_expr(register struct expr *ex, +arith ivalue, int fund) { /* Details derived from ivalue and fund are put into the - constant integer expression ex. - */ - switch (fund) { + constant integer expression ex. + */ + switch (fund) + { case INT: ex->ex_type = int_type; break; @@ -288,7 +289,7 @@ fill_int_expr(ex, ivalue, fund) ex->ex_type = uint_type; break; case LONG: - ex->ex_type = long_type; + ex->ex_type = long_type; break; case ULONG: ex->ex_type = ulong_type; @@ -303,38 +304,38 @@ fill_int_expr(ex, ivalue, fund) cut_size(ex); } -struct expr * -new_oper(tp, e1, oper, e2) - struct type *tp; - register struct expr *e1, *e2; +struct expr *new_oper(struct type *tp, register struct expr *e1, int oper, + register struct expr *e2) { /* A new expression is constructed which consists of the - operator oper which has e1 and e2 as operands; for a - monadic operator e1 == NILEXPR. - During the construction of the right recursive initialisation - tree it is possible for e2 to be NILEXPR. - */ + operator oper which has e1 and e2 as operands; for a + monadic operator e1 == NILEXPR. + During the construction of the right recursive initialisation + tree it is possible for e2 to be NILEXPR. + */ register struct expr *expr = new_expr(); register struct oper *op; - if (e2) { + if (e2) + { register struct expr *e = e2; - + while (e->ex_class == Oper && e->OP_LEFT) e = e->OP_LEFT; expr->ex_file = e->ex_file; expr->ex_line = e->ex_line; } - else - if (e1) { + else if (e1) + { register struct expr *e = e1; - + while (e->ex_class == Oper && e->OP_RIGHT) e = e->OP_RIGHT; expr->ex_file = e->ex_file; expr->ex_line = e->ex_line; } - else { + else + { expr->ex_file = dot.tk_file; expr->ex_line = dot.tk_line; } @@ -342,20 +343,22 @@ new_oper(tp, e1, oper, e2) expr->ex_type = tp; expr->ex_class = Oper; /* combine depths and flags of both expressions */ - if (e2) { + if (e2) + { int e1_depth = e1 ? e1->ex_depth : 0; int e1_flags = e1 ? e1->ex_flags : 0; - - expr->ex_depth = - (e1_depth > e2->ex_depth ? e1_depth : e2->ex_depth) + 1; + + expr->ex_depth = (e1_depth > e2->ex_depth ? e1_depth : e2->ex_depth) + + 1; expr->ex_flags = (e1_flags | e2->ex_flags) - & ~(EX_PARENS | EX_READONLY | EX_VOLATILE ); + & ~(EX_PARENS | EX_READONLY | EX_VOLATILE); } /* * A function call should be evaluated first when possible. Just say * that the expression tree is very deep. */ - if (oper == '(') { + if (oper == '(') + { expr->ex_depth = 50; } op = &expr->ex_object.ex_oper; @@ -369,42 +372,42 @@ new_oper(tp, e1, oper, e2) return expr; } -void -chk_cst_expr(expp) - struct expr **expp; +void chk_cst_expr(struct expr **expp) { /* The expression expr is checked for constancy. - - There are 6 places where constant expressions occur in C: - 1. after #if - 2. in a global initialization - 3. as size in an array declaration - 4. as value in an enum declaration - 5. as width in a bit field - 6. as case value in a switch - - The constant expression in a global initialization is - handled separately (by IVAL()). - - There are various disparate restrictions on each of - the others in the various C compilers. I have tried some - hypotheses to unify them, but all have failed. - - Special problems (of which there is only one, sizeof in - Preprocessor #if) have to be dealt with locally - */ + + There are 6 places where constant expressions occur in C: + 1. after #if + 2. in a global initialization + 3. as size in an array declaration + 4. as value in an enum declaration + 5. as width in a bit field + 6. as case value in a switch + + The constant expression in a global initialization is + handled separately (by IVAL()). + + There are various disparate restrictions on each of + the others in the various C compilers. I have tried some + hypotheses to unify them, but all have failed. + + Special problems (of which there is only one, sizeof in + Preprocessor #if) have to be dealt with locally + */ register struct expr *expr = *expp; - + #ifdef DEBUG print_expr("constant_expression", expr); #endif /* DEBUG */ - switch(expr->ex_type->tp_fund) { + switch (expr->ex_type->tp_fund) + { case CHAR: case SHORT: case INT: case ENUM: case LONG: - if (is_ld_cst(expr)) { + if (is_ld_cst(expr)) + { return; } expr_error(expr, "expression is not constant"); @@ -416,67 +419,58 @@ chk_cst_expr(expp) erroneous2int(expp); } -init_expression(eppp, expr) - register struct expr ***eppp; - struct expr *expr; +void init_expression(register struct expr ***eppp, struct expr *expr) { /* The expression expr is added to the tree designated - indirectly by **eppp. - The natural form of a tree representing an - initial_value_list is right-recursive, ie. with the - left-most comma as main operator. The iterative grammar in - expression.g, however, tends to produce a left-recursive - tree, ie. one with the right-most comma as its main - operator. - To produce a right-recursive tree from the iterative - grammar, we keep track of the address of the pointer where - the next expression must be hooked in. - */ + indirectly by **eppp. + The natural form of a tree representing an + initial_value_list is right-recursive, ie. with the + left-most comma as main operator. The iterative grammar in + expression.g, however, tends to produce a left-recursive + tree, ie. one with the right-most comma as its main + operator. + To produce a right-recursive tree from the iterative + grammar, we keep track of the address of the pointer where + the next expression must be hooked in. + */ **eppp = new_oper(void_type, expr, INITCOMMA, NILEXPR); *eppp = &(**eppp)->OP_RIGHT; } -int -is_ld_cst(expr) - register struct expr *expr; +int is_ld_cst(register struct expr *expr) { /* An expression is a `load-time constant' if it is of the form - +/- or . - */ + +/- or . + */ #ifdef LINT if (expr->ex_class == String) - return 1; + return 1; #endif /* LINT */ return expr->ex_lvalue == 0 && expr->ex_class == Value; } -int -is_cp_cst(expr) - struct expr *expr; +int is_cp_cst(struct expr *expr) { /* An expression is a `compile-time constant' if it is a - load-time constant, and the idf is not there. - */ + load-time constant, and the idf is not there. + */ return is_ld_cst(expr) && expr->VL_CLASS == Const; } -int -is_fp_cst(expr) - struct expr *expr; +int is_fp_cst(struct expr *expr) { /* An expression is a `floating-point constant' if it consists - of the float only. - */ + of the float only. + */ return expr->ex_class == Float; } -int -is_zero_cst(expr) - register struct expr *expr; +int is_zero_cst(register struct expr *expr) { flt_arith var; - switch(expr->ex_class) { + switch (expr->ex_class) + { case Value: return expr->VL_VALUE == 0; case Float: @@ -486,13 +480,14 @@ is_zero_cst(expr) /*NOTREACHED*/ } -free_expression(expr) - register struct expr *expr; +void free_expression(register struct expr *expr) { /* The expression expr is freed recursively. - */ - if (expr) { - if (expr->ex_class == Oper) { + */ + if (expr) + { + if (expr->ex_class == Oper) + { free_expression(expr->OP_LEFT); free_expression(expr->OP_RIGHT); } diff --git a/lang/cem/cemcom.ansi/expr.str b/lang/cem/cemcom.ansi/expr.str index b341524ed..97ac5b1f9 100644 --- a/lang/cem/cemcom.ansi/expr.str +++ b/lang/cem/cemcom.ansi/expr.str @@ -4,6 +4,13 @@ */ /* $Id$ */ /* EXPRESSION DESCRIPTOR */ +#ifndef EXPR_H_ +#define EXPR_H_ + +#include "parameters.h" +#include "arith.h" +#include "label.h" +#include "flt_arith.h" /* What we want to define is the struct expr, but since it contains a union of various goodies, we define them first; so be patient. @@ -97,3 +104,24 @@ extern struct expr *intexpr(), *new_oper(); /* ALLOCDEF "expr" 20 */ + + +int rank_of(int oper); +void dot2expr(struct expr **expp); +void idf2expr(register struct expr *expr); +void string2expr(register struct expr **expp, char *str, int len); +void int2expr(struct expr *expr); +void float2expr(register struct expr *expr); +struct expr* intexpr(arith ivalue, int fund); +void fill_int_expr(register struct expr *ex,arith ivalue, int fund); +struct expr *new_oper(struct type *tp, register struct expr *e1, int oper, + register struct expr *e2); +void chk_cst_expr(struct expr **expp); +void init_expression(register struct expr ***eppp, struct expr *expr); +int is_ld_cst(register struct expr *expr); +int is_cp_cst(struct expr *expr); +int is_fp_cst(struct expr *expr); +int is_zero_cst(register struct expr *expr); +void free_expression(register struct expr *expr); + +#endif \ No newline at end of file diff --git a/lang/cem/cemcom.ansi/expression.g b/lang/cem/cemcom.ansi/expression.g index 3a1284e69..0998883c1 100644 --- a/lang/cem/cemcom.ansi/expression.g +++ b/lang/cem/cemcom.ansi/expression.g @@ -1,349 +1,354 @@ -/* - * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. - * See the copyright notice in the ACK home directory, in the file "Copyright". - */ -/* $Id$ */ -/* EXPRESSION SYNTAX PARSER */ - -{ -#include -#include "parameters.h" -#include -#include "arith.h" -#include "LLlex.h" -#include "type.h" -#include "label.h" -#include "expr.h" -#include "code.h" -#include "sizes.h" - -extern struct expr *intexpr(); -int InSizeof = 0; /* inside a sizeof- expression */ -int ResultKnown = 0; /* result of the expression is already known */ - -/* Since the grammar in the standard is not LL(n), it is modified so that - * it accepts basically the same grammar. This means that there is no 1-1 - * mapping from the grammar in the standard to the grammar given here. - * Such is life. - */ -} - -/* 3.3.1 */ -primary(register struct expr **expp;) : - IDENTIFIER - {dot2expr(expp);} -| - constant(expp) -| - string(expp) -| - '(' expression(expp) ')' - { (*expp)->ex_flags |= EX_PARENS; } -; - - -/* Character string literals that are adjacent tokens - * are concatenated into a single character string - * literal. - */ -string(register struct expr **expp;) - { register int i, len; - register char *str; - register int fund; - } -: - STRING - { str = dot.tk_bts; - len = dot.tk_len; - fund = dot.tk_fund; - } - [ - STRING - { /* A pasted string keeps the type of the first - * string literal. - * The pasting of normal strings and wide - * character strings are stated as having an - * undefined behaviour. - */ - if (dot.tk_fund != fund) - warning("illegal pasting of string literals"); - str = Realloc(str, (unsigned) (--len + dot.tk_len)); - for (i = 0; i < dot.tk_len; i++) - str[len++] = dot.tk_bts[i]; - } - ]* - { string2expr(expp, str, len); } -; - -/* 3.3.2 */ -postfix_expression(register struct expr **expp;) - { int oper; - struct expr *e1 = 0; - struct idf *idf; - } -: - primary(expp) - [ - '[' expression(&e1) ']' - { ch3bin(expp, '[', e1); e1 = 0; } - | - '(' parameter_list(&e1)? ')' - { ch3bin(expp, '(', e1); call_proto(expp); e1 = 0; } - | - [ '.' | ARROW ] { oper = DOT; } - identifier(&idf) { ch3sel(expp, oper, idf); } - | - [ - PLUSPLUS { oper = POSTINCR; } - | - MINMIN { oper = POSTDECR; } - ] - { ch3incr(expp, oper); } - ]* -; - -parameter_list(struct expr **expp;) - {struct expr *e1 = 0;} -: - assignment_expression(expp) - {any2opnd(expp, PARCOMMA);} - [ %persistent - ',' - assignment_expression(&e1) - {any2opnd(&e1, PARCOMMA);} - {ch3bin(expp, PARCOMMA, e1);} - ]* -; - -%first first_of_type_specifier, type_specifier; - -/* 3.3.3 & 3.3.4 */ -unary(register struct expr **expp;) - {struct type *tp; int oper;} -: -%if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER) - cast(&tp) unary(expp) - { ch3cast(expp, CAST, tp); - (*expp)->ex_flags |= EX_CAST; - if (int_size != pointer_size) - (*expp)->ex_flags &= ~EX_PTRDIFF; - } -| - postfix_expression(expp) -| - unop(&oper) unary(expp) - {ch3mon(oper, expp);} -| - size_of(expp) -; - -/* When an identifier is used in a sizeof()-expression, we must stil not - * mark it as used. - * extern int i; .... sizeof(i) .... need not have a definition for i - */ -size_of(register struct expr **expp;) - {struct type *tp;} -: - SIZEOF { InSizeof++; } /* handle (sizeof(sizeof(int))) too */ - [%if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER) - cast(&tp) - { - *expp = intexpr(size_of_type(tp, "type"), UNSIGNED); - (*expp)->ex_flags |= EX_SIZEOF; - } - | - unary(expp) - {ch3mon(SIZEOF, expp);} - ] - { InSizeof--; } -; - -/* 3.3.5-3.3.17 */ -/* The set of operators in C is stratified in 15 levels, with level - N being treated in RM 7.N (although this is not the standard - anymore). The standard describes this in phrase-structure-grammar, - which we are unable to parse. The description that follows comes - from the old C-compiler. - - In principle each operator is assigned a rank, ranging - from 1 to 15. Such an expression can be parsed by a construct - like: - binary_expression(int maxrank;) - {int oper;} - : - binary_expression(maxrank - 1) - [%if (rank_of(DOT) <= maxrank) - binop(&oper) - binary_expression(rank_of(oper)-1) - ]? - ; - except that some call of 'unary' is necessary, depending on the - grammar. - - This simple view is marred by three complications: - 1. Level 15 (comma operator) is not allowed in many - contexts and is different. - 2. Level 13 (conditional operator) is a ternary operator, - which does not fit this scheme at all. - 3. Level 14 (assignment operators) group right-to-left, as - opposed to 2-12, which group left-to-right (or are - immaterial). - 4. The operators in level 14 start with operators in levels - 2-13 (RM 7.14: The two parts of a compound assignment - operator are separate tokens.) This causes LL1 problems. - This forces us to have four rules: - binary_expression for level 2-12 - conditional_expression for level 13 - assignment_expression for level 14 and - expression for the most general expression -*/ - -binary_expression(int maxrank; struct expr **expp;) - {int oper, OldResultKnown; struct expr *e1;} -: - unary(expp) - [%while (rank_of(DOT) <= maxrank ) - /* '?', '=', and ',' are no binops - */ - binop(&oper) - { OldResultKnown = ResultKnown; - if (oper == OR || oper == AND) { - if (is_cp_cst(*expp) || is_fp_cst(*expp)) { - if (is_zero_cst(*expp)) { - if (oper == AND) ResultKnown++; - } else if (oper == OR) ResultKnown++; - } - } - } - binary_expression(rank_of(oper)-1, &e1) - { - ch3bin(expp, oper, e1); - ResultKnown = OldResultKnown; - } - ]* -; - -/* 3.3.15 */ -conditional_expression(struct expr **expp;) - {struct expr *e1 = 0, *e2 = 0; int OldResultKnown, ConstExpr=0;} -: - /* allow all binary operators */ - binary_expression(rank_of('?') - 1, expp) - [ '?' - { OldResultKnown = ResultKnown; - if (is_cp_cst(*expp) || is_fp_cst(*expp)) { - ConstExpr++; - if (is_zero_cst(*expp)) ResultKnown++; - } - } - expression(&e1) - ':' - { if (ConstExpr) { - if (OldResultKnown == ResultKnown) ResultKnown++; - else ResultKnown = OldResultKnown; - } - } - conditional_expression(&e2) - { - ResultKnown = OldResultKnown; - ch3bin(&e1, ':', e2); - opnd2test(expp, '?'); - ch3bin(expp, '?', e1); - } - ]? -; - -/* 3.3.16 */ -assignment_expression(struct expr **expp;) - { int oper; - struct expr *e1 = 0; - } -: - conditional_expression(expp) - [ - asgnop(&oper) - assignment_expression(&e1) - {ch3asgn(expp, oper, e1);} - | - empty /* LLgen artefact ??? */ - ] -; - -/* 3.3.17 */ -expression(struct expr **expp;) - {struct expr *e1;} -: - assignment_expression(expp) - [ ',' - assignment_expression(&e1) - { - ch3bin(expp, ',', e1); - } - ]* -; - -unop(int *oper;) : - ['*' | '&' | '-' | '+' | '!' | '~' | PLUSPLUS | MINMIN] - { if (DOT == '&') DOT = ADDRESSOF; - *oper = DOT; - } -; - -multop: - '*' | '/' | '%' -; - -addop: - '+' | '-' -; - -shiftop: - LEFT | RIGHT -; - -relop: - '<' | '>' | LESSEQ | GREATEREQ -; - -eqop: - EQUAL | NOTEQUAL -; - -arithop: - multop | addop | shiftop -| - '&' | '^' | '|' -; - -binop(int *oper;) : - [ arithop | relop | eqop | AND | OR ] - {*oper = DOT;} -; - -asgnop(register int *oper;): - [ '=' | PLUSAB | MINAB | TIMESAB | DIVAB | MODAB - | LEFTAB | RIGHTAB | ANDAB | XORAB | ORAB ] - { *oper = DOT; } - -; - -constant(struct expr **expp;) : -[ - INTEGER -| - FLOATING -] {dot2expr(expp);} -; - -/* 3.4 */ -constant_expression (struct expr **expp;) : - conditional_expression(expp) - { chk_cst_expr(expp); } -; - -identifier(struct idf **idfp;) : -[ IDENTIFIER -| TYPE_IDENTIFIER -] - { *idfp = dot.tk_idf; } -; +/* + * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. + * See the copyright notice in the ACK home directory, in the file "Copyright". + */ +/* $Id$ */ +/* EXPRESSION SYNTAX PARSER */ + +{ +#include +#include "parameters.h" +#include +#include "arith.h" +#include "LLlex.h" +#include "type.h" +#include "label.h" +#include "expr.h" +#include "code.h" +#include "error.h" +#include "ch3.h" +#include "ch3bin.h" +#include "ch3mon.h" +#include "proto.h" +#include "sizes.h" + +extern struct expr *intexpr(); +int InSizeof = 0; /* inside a sizeof- expression */ +int ResultKnown = 0; /* result of the expression is already known */ + +/* Since the grammar in the standard is not LL(n), it is modified so that + * it accepts basically the same grammar. This means that there is no 1-1 + * mapping from the grammar in the standard to the grammar given here. + * Such is life. + */ +} + +/* 3.3.1 */ +primary(register struct expr **expp;) : + IDENTIFIER + {dot2expr(expp);} +| + constant(expp) +| + string(expp) +| + '(' expression(expp) ')' + { (*expp)->ex_flags |= EX_PARENS; } +; + + +/* Character string literals that are adjacent tokens + * are concatenated into a single character string + * literal. + */ +string(register struct expr **expp;) + { register int i, len; + register char *str; + register int fund; + } +: + STRING + { str = dot.tk_bts; + len = dot.tk_len; + fund = dot.tk_fund; + } + [ + STRING + { /* A pasted string keeps the type of the first + * string literal. + * The pasting of normal strings and wide + * character strings are stated as having an + * undefined behaviour. + */ + if (dot.tk_fund != fund) + warning("illegal pasting of string literals"); + str = Realloc(str, (unsigned) (--len + dot.tk_len)); + for (i = 0; i < dot.tk_len; i++) + str[len++] = dot.tk_bts[i]; + } + ]* + { string2expr(expp, str, len); } +; + +/* 3.3.2 */ +postfix_expression(register struct expr **expp;) + { int oper; + struct expr *e1 = 0; + struct idf *idf; + } +: + primary(expp) + [ + '[' expression(&e1) ']' + { ch3bin(expp, '[', e1); e1 = 0; } + | + '(' parameter_list(&e1)? ')' + { ch3bin(expp, '(', e1); call_proto(expp); e1 = 0; } + | + [ '.' | ARROW ] { oper = DOT; } + identifier(&idf) { ch3sel(expp, oper, idf); } + | + [ + PLUSPLUS { oper = POSTINCR; } + | + MINMIN { oper = POSTDECR; } + ] + { ch3incr(expp, oper); } + ]* +; + +parameter_list(struct expr **expp;) + {struct expr *e1 = 0;} +: + assignment_expression(expp) + {any2opnd(expp, PARCOMMA);} + [ %persistent + ',' + assignment_expression(&e1) + {any2opnd(&e1, PARCOMMA);} + {ch3bin(expp, PARCOMMA, e1);} + ]* +; + +%first first_of_type_specifier, type_specifier; + +/* 3.3.3 & 3.3.4 */ +unary(register struct expr **expp;) + {struct type *tp; int oper;} +: +%if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER) + cast(&tp) unary(expp) + { ch3cast(expp, CAST, tp); + (*expp)->ex_flags |= EX_CAST; + if (int_size != pointer_size) + (*expp)->ex_flags &= ~EX_PTRDIFF; + } +| + postfix_expression(expp) +| + unop(&oper) unary(expp) + {ch3mon(oper, expp);} +| + size_of(expp) +; + +/* When an identifier is used in a sizeof()-expression, we must stil not + * mark it as used. + * extern int i; .... sizeof(i) .... need not have a definition for i + */ +size_of(register struct expr **expp;) + {struct type *tp;} +: + SIZEOF { InSizeof++; } /* handle (sizeof(sizeof(int))) too */ + [%if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER) + cast(&tp) + { + *expp = intexpr(size_of_type(tp, "type"), UNSIGNED); + (*expp)->ex_flags |= EX_SIZEOF; + } + | + unary(expp) + {ch3mon(SIZEOF, expp);} + ] + { InSizeof--; } +; + +/* 3.3.5-3.3.17 */ +/* The set of operators in C is stratified in 15 levels, with level + N being treated in RM 7.N (although this is not the standard + anymore). The standard describes this in phrase-structure-grammar, + which we are unable to parse. The description that follows comes + from the old C-compiler. + + In principle each operator is assigned a rank, ranging + from 1 to 15. Such an expression can be parsed by a construct + like: + binary_expression(int maxrank;) + {int oper;} + : + binary_expression(maxrank - 1) + [%if (rank_of(DOT) <= maxrank) + binop(&oper) + binary_expression(rank_of(oper)-1) + ]? + ; + except that some call of 'unary' is necessary, depending on the + grammar. + + This simple view is marred by three complications: + 1. Level 15 (comma operator) is not allowed in many + contexts and is different. + 2. Level 13 (conditional operator) is a ternary operator, + which does not fit this scheme at all. + 3. Level 14 (assignment operators) group right-to-left, as + opposed to 2-12, which group left-to-right (or are + immaterial). + 4. The operators in level 14 start with operators in levels + 2-13 (RM 7.14: The two parts of a compound assignment + operator are separate tokens.) This causes LL1 problems. + This forces us to have four rules: + binary_expression for level 2-12 + conditional_expression for level 13 + assignment_expression for level 14 and + expression for the most general expression +*/ + +binary_expression(int maxrank; struct expr **expp;) + {int oper, OldResultKnown; struct expr *e1;} +: + unary(expp) + [%while (rank_of(DOT) <= maxrank ) + /* '?', '=', and ',' are no binops + */ + binop(&oper) + { OldResultKnown = ResultKnown; + if (oper == OR || oper == AND) { + if (is_cp_cst(*expp) || is_fp_cst(*expp)) { + if (is_zero_cst(*expp)) { + if (oper == AND) ResultKnown++; + } else if (oper == OR) ResultKnown++; + } + } + } + binary_expression(rank_of(oper)-1, &e1) + { + ch3bin(expp, oper, e1); + ResultKnown = OldResultKnown; + } + ]* +; + +/* 3.3.15 */ +conditional_expression(struct expr **expp;) + {struct expr *e1 = 0, *e2 = 0; int OldResultKnown, ConstExpr=0;} +: + /* allow all binary operators */ + binary_expression(rank_of('?') - 1, expp) + [ '?' + { OldResultKnown = ResultKnown; + if (is_cp_cst(*expp) || is_fp_cst(*expp)) { + ConstExpr++; + if (is_zero_cst(*expp)) ResultKnown++; + } + } + expression(&e1) + ':' + { if (ConstExpr) { + if (OldResultKnown == ResultKnown) ResultKnown++; + else ResultKnown = OldResultKnown; + } + } + conditional_expression(&e2) + { + ResultKnown = OldResultKnown; + ch3bin(&e1, ':', e2); + opnd2test(expp, '?'); + ch3bin(expp, '?', e1); + } + ]? +; + +/* 3.3.16 */ +assignment_expression(struct expr **expp;) + { int oper; + struct expr *e1 = 0; + } +: + conditional_expression(expp) + [ + asgnop(&oper) + assignment_expression(&e1) + {ch3asgn(expp, oper, e1);} + | + empty /* LLgen artefact ??? */ + ] +; + +/* 3.3.17 */ +expression(struct expr **expp;) + {struct expr *e1;} +: + assignment_expression(expp) + [ ',' + assignment_expression(&e1) + { + ch3bin(expp, ',', e1); + } + ]* +; + +unop(int *oper;) : + ['*' | '&' | '-' | '+' | '!' | '~' | PLUSPLUS | MINMIN] + { if (DOT == '&') DOT = ADDRESSOF; + *oper = DOT; + } +; + +multop: + '*' | '/' | '%' +; + +addop: + '+' | '-' +; + +shiftop: + LEFT | RIGHT +; + +relop: + '<' | '>' | LESSEQ | GREATEREQ +; + +eqop: + EQUAL | NOTEQUAL +; + +arithop: + multop | addop | shiftop +| + '&' | '^' | '|' +; + +binop(int *oper;) : + [ arithop | relop | eqop | AND | OR ] + {*oper = DOT;} +; + +asgnop(register int *oper;): + [ '=' | PLUSAB | MINAB | TIMESAB | DIVAB | MODAB + | LEFTAB | RIGHTAB | ANDAB | XORAB | ORAB ] + { *oper = DOT; } + +; + +constant(struct expr **expp;) : +[ + INTEGER +| + FLOATING +] {dot2expr(expp);} +; + +/* 3.4 */ +constant_expression (struct expr **expp;) : + conditional_expression(expp) + { chk_cst_expr(expp); } +; + +identifier(struct idf **idfp;) : +[ IDENTIFIER +| TYPE_IDENTIFIER +] + { *idfp = dot.tk_idf; } +; diff --git a/lang/cem/cemcom.ansi/field.c b/lang/cem/cemcom.ansi/field.c index f5635d1fe..d1b014c01 100644 --- a/lang/cem/cemcom.ansi/field.c +++ b/lang/cem/cemcom.ansi/field.c @@ -23,8 +23,11 @@ #include "align.h" #include "Lpars.h" #include "field.h" +#include "util.h" +#include "conversion.h" +#include "eval.h" + -arith NewLocal(); /* util.c */ extern arith full_mask[]; /* cstoper.c */ /* Eval_field() evaluates expressions involving bit fields. @@ -39,9 +42,9 @@ extern arith full_mask[]; /* cstoper.c */ [3] atype: the type in which the bitfield arithmetic is done; and in which bitfields are stored! */ -eval_field(expr, code) - struct expr *expr; - int code; +void eval_field( + struct expr *expr, + int code) { int op = expr->OP_OPER; register struct expr *leftop = expr->OP_LEFT; @@ -126,12 +129,12 @@ eval_field(expr, code) } } -store_field(fd, uns, code, leftop, tmpvar) - register struct field *fd; - int uns; - int code; - register struct expr *leftop; - arith tmpvar; +void store_field( + register struct field *fd, + int uns, + int code, + register struct expr *leftop, + arith tmpvar) { C_loc(fd->fd_mask); C_and(word_size); diff --git a/lang/cem/cemcom.ansi/field.str b/lang/cem/cemcom.ansi/field.str index 7b4f219a1..2c8635c43 100644 --- a/lang/cem/cemcom.ansi/field.str +++ b/lang/cem/cemcom.ansi/field.str @@ -2,6 +2,11 @@ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * See the copyright notice in the ACK home directory, in the file "Copyright". */ +#ifndef FIELD_H_ +#define FIELD_H_ + +#include "arith.h" + /* $Id$ */ /* FIELD DESCRIPTOR */ @@ -13,3 +18,20 @@ struct field { /* for field specifiers */ }; /* ALLOCDEF "field" 10 */ + +#ifndef LINT + + +#ifndef NOBITFIELD + +struct expr; + +void store_field(register struct field *fd, int uns, int code, + register struct expr *leftop, arith tmpvar); +void eval_field(struct expr *expr, int code); + +#endif /* NOBITFIELD */ + +#endif /* LINT */ + +#endif /* FIELD_H_ */ \ No newline at end of file diff --git a/lang/cem/cemcom.ansi/fltcstoper.c b/lang/cem/cemcom.ansi/fltcstoper.c index 7b48fc725..c33d7a278 100644 --- a/lang/cem/cemcom.ansi/fltcstoper.c +++ b/lang/cem/cemcom.ansi/fltcstoper.c @@ -10,18 +10,19 @@ #include "parameters.h" #include #include +#include "fltcstoper.h" #include "arith.h" #include "type.h" #include "label.h" #include "expr.h" #include "sizes.h" #include "Lpars.h" +#include "error.h" extern int ResultKnown; extern char *symbol2str(); -fltcstbin(expp, oper, expr) - register struct expr **expp, *expr; +void fltcstbin(register struct expr **expp, int oper, register struct expr *expr) { /* The operation oper is performed on the constant expressions *expp(ld) and expr(ct), and the result restored in diff --git a/lang/cem/cemcom.ansi/fltcstoper.h b/lang/cem/cemcom.ansi/fltcstoper.h new file mode 100644 index 000000000..4b65618f6 --- /dev/null +++ b/lang/cem/cemcom.ansi/fltcstoper.h @@ -0,0 +1,15 @@ +/* Copyright (c) 2019 ACK Project. + * See the copyright notice in the ACK home directory, + * in the file "Copyright". + * + * Created on: 2019-02-07 + * + */ +#ifndef FLTCSTOPER_H_ +#define FLTCSTOPER_H_ + +struct expr; + +void fltcstbin(register struct expr **expp, int oper, register struct expr *expr); + +#endif /* FLTCSTOPER_H_ */ diff --git a/lang/cem/cemcom.ansi/idf.c b/lang/cem/cemcom.ansi/idf.c index 54727221e..4d3f0fc89 100644 --- a/lang/cem/cemcom.ansi/idf.c +++ b/lang/cem/cemcom.ansi/idf.c @@ -25,6 +25,12 @@ #include "declar.h" #include "decspecs.h" #include "sizes.h" +#include "print.h" +#include "util.h" +#include "stab.h" +#include "code.h" +#include "error.h" +#include "ch3.h" #include "Lpars.h" extern char options[]; @@ -37,91 +43,92 @@ extern char *symbol2str(); #include -void global_redecl(); -struct idf * -gen_idf() + +struct idf *gen_idf(void) { /* A new idf is created out of nowhere, to serve as an - anonymous name. - */ + anonymous name. + */ static int name_cnt; char *s = Malloc(strlen(dot.tk_file) + 50); - sprint(s, "#%d in %s, line %u", - ++name_cnt, dot.tk_file, dot.tk_line); - s = Realloc(s, strlen(s)+1); + sprint(s, "#%d in %s, line %u", ++name_cnt, dot.tk_file, dot.tk_line); + s = Realloc(s, strlen(s) + 1); return str2idf(s, 0); } -int -is_anon_idf(idf) - struct idf *idf; +int is_anon_idf(struct idf *idf) { return idf->id_text[0] == '#'; } -declare_idf(ds, dc, lvl) - struct decspecs *ds; - struct declarator *dc; +void declare_idf(struct decspecs *ds, struct declarator *dc, int lvl) { /* The identifier inside dc is declared on the level lvl, with - properties deduced from the decspecs ds and the declarator - dc. - The level is given explicitly to be able to insert, e.g., - labels on the outermost level inside the function. - This routine implements the rich semantics of C - declarations. - */ + properties deduced from the decspecs ds and the declarator + dc. + The level is given explicitly to be able to insert, e.g., + labels on the outermost level inside the function. + This routine implements the rich semantics of C + declarations. + */ register struct idf *idf = dc->dc_idf; register int sc = ds->ds_sc; - /* This local copy is essential: - char b(), c; - makes b GLOBAL and c AUTO. - */ - register struct def *def = idf->id_def; /* may be NULL */ + /* This local copy is essential: + char b(), c; + makes b GLOBAL and c AUTO. + */ + register struct def *def = idf->id_def; /* may be NULL */ register struct type *type; struct stack_level *stl = stack_level_of(lvl); char formal_array = 0; - + /* determine the present type */ - if (ds->ds_type == 0) { + if (ds->ds_type == 0) + { /* at the L_FORMAL1 level there is no type specified yet - */ + */ assert(lvl == L_FORMAL1); - type = int_type; /* may change at L_FORMAL2 */ + type = int_type; /* may change at L_FORMAL2 */ } - else { + else + { /* combine the decspecs and the declarator into one type */ type = declare_type(ds->ds_type, dc); - if (type->tp_size <= (arith)0 && - actual_declaration(sc, type)) { - if (type->tp_size == (arith) -1) { + if (type->tp_size <= (arith) 0 && actual_declaration(sc, type)) + { + if (type->tp_size == (arith) -1) + { /* the type is not yet known, - but it has to be: - */ - if (type->tp_fund != VOID) { - if (level != L_GLOBAL) - error("unknown %s-type", - symbol2str(type->tp_fund)); - } else error("void is not a complete type"); + but it has to be: + */ + if (type->tp_fund != VOID) + { + if (level != L_GLOBAL) + error("unknown %s-type", symbol2str(type->tp_fund)); + } + else + error("void is not a complete type"); } - else strict("%s has size 0", idf->id_text); + else + strict("%s has size 0", idf->id_text); } } /* some additional work for formal definitions */ - if (lvl == L_FORMAL2) { - switch (type->tp_fund) { + if (lvl == L_FORMAL2) + { + switch (type->tp_fund) + { case FUNCTION: - warning("%s is a function; cannot be formal", - idf->id_text); - type = construct_type(POINTER, type, 0, (arith)0, - NO_PROTO); + warning("%s is a function; cannot be formal", idf->id_text); + type = construct_type(POINTER, type, 0, (arith) 0, + NO_PROTO); break; - case ARRAY: /* 3.7.1 */ - type = construct_type(POINTER, type->tp_up, 0, (arith)0, - NO_PROTO); + case ARRAY: /* 3.7.1 */ + type = construct_type(POINTER, type->tp_up, 0, (arith) 0, + NO_PROTO); formal_array = 1; break; case FLOAT: @@ -135,72 +142,77 @@ declare_idf(ds, dc, lvl) } } /* The tests on types, postponed from do_decspecs(), can now - be performed. - */ + be performed. + */ /* update the storage class */ - if (type && type->tp_fund == FUNCTION) { - if (lvl != L_GLOBAL) { /* 3.5.1 */ + if (type && type->tp_fund == FUNCTION) + { + if (lvl != L_GLOBAL) + { /* 3.5.1 */ if (sc == 0) sc = GLOBAL; - else if (sc != EXTERN && sc != TYPEDEF) { - error("illegal storage class %s for function with block-scope" - , symbol2str(sc)); + else if (sc != EXTERN && sc != TYPEDEF) + { + error("illegal storage class %s for function with block-scope", + symbol2str(sc)); ds->ds_sc = sc = EXTERN; } } else if (sc == 0) sc = GLOBAL; } - else /* non-FUNCTION */ - if (sc == 0) - sc = lvl == L_GLOBAL ? GLOBAL - : lvl == L_FORMAL1 || lvl == L_FORMAL2 ? FORMAL - : AUTO; + else /* non-FUNCTION */ + if (sc == 0) + sc = lvl == L_GLOBAL ? GLOBAL : + lvl == L_FORMAL1 || lvl == L_FORMAL2 ? FORMAL : AUTO; #ifdef LINT - check_hiding(idf, lvl, sc); /* of some idf by this idf */ + check_hiding(idf, lvl, sc); /* of some idf by this idf */ #endif /* LINT */ - if (def && lvl == L_LOCAL && def->df_level == L_FORMAL2) { + if (def && lvl == L_LOCAL && def->df_level == L_FORMAL2) + { error("%s redeclared", idf->id_text); } - if (def && - ( def->df_level == lvl || - ( lvl != L_GLOBAL && def->df_level > lvl ) || - (lvl == L_GLOBAL - && def->df_level == L_PROTO - && def->next && def->next->df_level == L_GLOBAL) - )) { + if (def + && (def->df_level == lvl || (lvl != L_GLOBAL && def->df_level > lvl) + || (lvl == L_GLOBAL && def->df_level == L_PROTO && def->next + && def->next->df_level == L_GLOBAL))) + { /* There is already a declaration for idf on this - level, or even more inside. - The rules differ for different levels. - */ - switch (lvl) { + level, or even more inside. + The rules differ for different levels. + */ + switch (lvl) + { case L_GLOBAL: global_redecl(idf, sc, type); def->df_file = idf->id_file; def->df_line = idf->id_line; break; - case L_FORMAL1: /* formal declaration */ + case L_FORMAL1: /* formal declaration */ error("formal %s redeclared", idf->id_text); break; - case L_FORMAL2: /* formal definition */ - default: /* local */ - if (sc != EXTERN) error("%s redeclared", idf->id_text); + case L_FORMAL2: /* formal definition */ + default: /* local */ + if (sc != EXTERN) + error("%s redeclared", idf->id_text); break; } } - else /* the idf is unknown on this level */ - if (lvl == L_FORMAL2 && sc != ENUM && good_formal(def, idf)) { + else /* the idf is unknown on this level */ + if (lvl == L_FORMAL2 && sc != ENUM && good_formal(def, idf)) + { /* formal declaration, update only */ def->df_type = type; def->df_formal_array = formal_array; def->df_sc = sc; - def->df_level = L_FORMAL2; /* CJ */ + def->df_level = L_FORMAL2; /* CJ */ def->df_file = idf->id_file; def->df_line = idf->id_line; } - else { /* fill in the def block */ + else + { /* fill in the def block */ register struct def *newdef = new_def(); newdef->next = def; @@ -218,28 +230,27 @@ declare_idf(ds, dc, lvl) update_ahead(idf); stack_idf(idf, stl); /* We now calculate the address. - Globals have names and don't get addresses, they - get numbers instead (through data_label()). - Formals are handled by declare_formals(). - So here we hand out local addresses only. - */ - if (lvl >= L_LOCAL) { + Globals have names and don't get addresses, they + get numbers instead (through data_label()). + Formals are handled by declare_formals(). + So here we hand out local addresses only. + */ + if (lvl >= L_LOCAL) + { assert(sc); - switch (sc) { + switch (sc) + { case REGISTER: case AUTO: - if (type->tp_size == (arith)-1 - && type->tp_fund != ARRAY) { - error("size of local %s unknown", - idf->id_text); - /** type = idf->id_def->df_type = int_type; **/ + if (type->tp_size == (arith) -1 && type->tp_fund != ARRAY) + { + error("size of local %s unknown", idf->id_text); + /** type = idf->id_def->df_type = int_type; **/ } - if (type->tp_size != (arith) -1) { - newdef->df_address = - NewLocal(type->tp_size, - type->tp_align, - regtype(type), - sc); + if (type->tp_size != (arith) -1) + { + newdef->df_address = NewLocal(type->tp_size, type->tp_align, + regtype(type), sc); } break; case STATIC: @@ -250,21 +261,19 @@ declare_idf(ds, dc, lvl) } } -int -actual_declaration(sc, tp) - int sc; - struct type *tp; +int actual_declaration(int sc, struct type *tp) { /* An actual_declaration needs space, right here and now. - */ + */ register int fund = tp->tp_fund; - + if (sc == ENUM || sc == TYPEDEF) /* virtual declarations */ return 0; if (fund == FUNCTION || fund == ARRAY) /* allocation solved in other ways */ return 0; - if (sc == EXTERN && fund == VOID) { + if (sc == EXTERN && fund == VOID) + { /* strange, but should be accepted */ return 0; } @@ -272,51 +281,59 @@ actual_declaration(sc, tp) return 1; } -void -global_redecl(idf, new_sc, tp) - register struct idf *idf; - struct type *tp; +void global_redecl(register struct idf *idf, int new_sc, struct type *tp) { /* A global identifier may be declared several times, - provided the declarations do not conflict; they might - conflict in type (or supplement each other in the case of - an array) or they might conflict or supplement each other - in storage class. - */ + provided the declarations do not conflict; they might + conflict in type (or supplement each other in the case of + an array) or they might conflict or supplement each other + in storage class. + */ register struct def *def = idf->id_def; - while (def->df_level != L_GLOBAL) def = def->next; - if (!equal_type(tp, def->df_type, 0, 1)) { + while (def->df_level != L_GLOBAL) + def = def->next; + if (!equal_type(tp, def->df_type, 0, 1)) + { error("redeclaration of %s with different type", idf->id_text); return; - } else update_proto(tp, def->df_type); - if (tp->tp_fund == ARRAY) { + } + else + update_proto(tp, def->df_type); + if (tp->tp_fund == ARRAY) + { /* Multiple array declaration; this may be interesting */ - if (tp->tp_size < 0) { /* new decl has [] */ + if (tp->tp_size < 0) + { /* new decl has [] */ /* nothing new */ - } else - if (def->df_type->tp_size < 0) { /* old decl has [] */ + } + else if (def->df_type->tp_size < 0) + { /* old decl has [] */ def->df_type = tp; } - } if (tp->tp_fund == FUNCTION && new_sc == GLOBAL) { + } + if (tp->tp_fund == FUNCTION && new_sc == GLOBAL) + { /* see 3.1.2.2 */ new_sc = EXTERN; } /* Now we may be able to update the storage class. - Clean out this mess as soon as we know all the possibilities - for new_sc. - For now we have: - EXTERN: we have seen the word "extern" - GLOBAL: the item was declared on the outer - level, without either "extern" or - "static". - STATIC: we have seen the word "static" - */ + Clean out this mess as soon as we know all the possibilities + for new_sc. + For now we have: + EXTERN: we have seen the word "extern" + GLOBAL: the item was declared on the outer + level, without either "extern" or + "static". + STATIC: we have seen the word "static" + */ - switch (def->df_sc) { /* the old storage class */ + switch (def->df_sc) + { /* the old storage class */ case EXTERN: - switch (new_sc) { /* the new storage class */ + switch (new_sc) + { /* the new storage class */ case STATIC: warning("%s redeclared static", idf->id_text); /* fallthrough */ @@ -331,8 +348,9 @@ global_redecl(idf, new_sc, tp) } break; case GLOBAL: - switch (new_sc) { /* the new storage class */ - case STATIC: /* linkage disagreement */ + switch (new_sc) + { /* the new storage class */ + case STATIC: /* linkage disagreement */ warning("%s redeclared static", idf->id_text); def->df_sc = new_sc; /* fallthrough */ @@ -345,8 +363,9 @@ global_redecl(idf, new_sc, tp) } break; case STATIC: - switch (new_sc) { /* the new storage class */ - case GLOBAL: /* linkage disagreement */ + switch (new_sc) + { /* the new storage class */ + case GLOBAL: /* linkage disagreement */ case EXTERN: warning("%s is already declared static", idf->id_text); /* fallthrough */ @@ -367,142 +386,147 @@ global_redecl(idf, new_sc, tp) } } -int -good_formal(def, idf) - register struct def *def; - register struct idf *idf; +int good_formal(register struct def *def, register struct idf *idf) { /* Succeeds if def is a proper L_FORMAL1 definition and - gives an error message otherwise. - */ - if (!def || def->df_level != L_FORMAL1) { /* not in parameter list */ + gives an error message otherwise. + */ + if (!def || def->df_level != L_FORMAL1) + { /* not in parameter list */ if (!is_anon_idf(idf)) error("%s not in parameter list", idf->id_text); return 0; } - assert(def->df_sc == FORMAL); /* CJ */ + assert(def->df_sc == FORMAL); /* CJ */ return 1; } -declare_params(dc) - struct declarator *dc; +void declare_params(struct declarator *dc) { /* Declares the formal parameters if they exist. - */ + */ register struct formal *fm = dc->dc_formal; - while (fm) { + while (fm) + { declare_parameter(fm->fm_idf); fm = fm->next; } } -void -idf_initialized(idf) - register struct idf *idf; +void idf_initialized(register struct idf *idf) { /* The topmost definition of idf is set to initialized. - */ - register struct def *def = idf->id_def; /* the topmost */ - - while (def->df_level <= L_PROTO) def = def->next; + */ + register struct def *def = idf->id_def; /* the topmost */ + + while (def->df_level <= L_PROTO) + def = def->next; if (def->df_initialized) error("multiple initialization of %s", idf->id_text); - if (def->df_sc == TYPEDEF) { + if (def->df_sc == TYPEDEF) + { error("typedef cannot be initialized"); return; } def->df_initialized = 1; } -declare_parameter(idf) - struct idf *idf; +void declare_parameter(struct idf *idf) { /* idf is declared as a formal. - */ + */ add_def(idf, FORMAL, int_type, level); } -declare_enum(tp, idf, l) - struct type *tp; - struct idf *idf; - arith l; +void declare_enum(struct type *tp, struct idf *idf, arith l) { /* idf is declared as an enum constant with value l. - */ + */ add_def(idf, ENUM, tp, level); idf->id_def->df_address = l; } -void -check_formals(idf, dc) - struct idf *idf; - struct declarator *dc; +void check_formals(struct idf *idf, struct declarator *dc) { register struct formal *fm = dc->dc_formal; register struct proto *pl = idf->id_def->df_type->tp_proto; register struct decl_unary *du = dc->dc_decl_unary; - if (!du) { /* error or typdef'ed function */ + if (!du) + { /* error or typdef'ed function */ error("illegal definition of %s", idf->id_text); return; } while (du - && (du->du_fund != FUNCTION - || du->next != (struct decl_unary *) 0)) { + && (du->du_fund != FUNCTION || du->next != (struct decl_unary *) 0)) + { du = du->next; } - if (!du) return; /* terrible error, signalled earlier */ + if (!du) + return; /* terrible error, signalled earlier */ - if (du->du_proto) return; + if (du->du_proto) + return; - if (pl) { + if (pl) + { /* Don't give a warning about an old-style definition, * since the arguments will be checked anyway. */ - if (pl->pl_flag & PL_ELLIPSIS) { - if (!(du->du_proto) && !(pl->pl_flag & PL_ERRGIVEN)) - error("ellipsis terminator in previous declaration"); - pl = pl->next; + if (pl->pl_flag & PL_ELLIPSIS) + { + if (!(du->du_proto) && !(pl->pl_flag & PL_ERRGIVEN)) + error("ellipsis terminator in previous declaration"); + pl = pl->next; } - else if (pl->pl_flag & PL_VOID) { - pl = pl->next; /* should be 0 */ + else if (pl->pl_flag & PL_VOID) + { + pl = pl->next; /* should be 0 */ } - while(fm && pl) { - if (!equal_type(promoted_type(fm->fm_idf->id_def->df_type) - , pl->pl_type, -1, 1)) { - if (!(pl->pl_flag & PL_ERRGIVEN)) - error("incorrect type for parameter %s" - , fm->fm_idf->id_text); - pl->pl_flag |= PL_ERRGIVEN; - } - fm = fm->next; - pl = pl->next; + while (fm && pl) + { + if (!equal_type(promoted_type(fm->fm_idf->id_def->df_type), + pl->pl_type, -1, 1)) + { + if (!(pl->pl_flag & PL_ERRGIVEN)) + error("incorrect type for parameter %s", + fm->fm_idf->id_text); + pl->pl_flag |= PL_ERRGIVEN; + } + fm = fm->next; + pl = pl->next; } - if (pl || fm) { + if (pl || fm) + { error("incorrect number of parameters"); } - } else { /* make a pseudo-prototype */ + } + else + { /* make a pseudo-prototype */ register struct proto *lpl = new_proto(); if (!options['o']) - warning("'%s' old-fashioned function definition" - , dc->dc_idf->id_text); + warning("'%s' old-fashioned function definition", + dc->dc_idf->id_text); - while (fm) { - if (pl == 0) pl = lpl; - else { + while (fm) + { + if (pl == 0) + pl = lpl; + else + { lpl->next = new_proto(); lpl = lpl->next; } lpl->pl_flag = PL_FORMAL; lpl->pl_idf = fm->fm_idf; - lpl->pl_type = - promoted_type(fm->fm_idf->id_def->df_type); + lpl->pl_type = promoted_type(fm->fm_idf->id_def->df_type); fm = fm->next; } - if (pl == 0) { /* make func(void) */ + if (pl == 0) + { /* make func(void) */ pl = lpl; pl->pl_type = void_type; pl->pl_flag = PL_FORMAL | PL_VOID; @@ -513,26 +537,26 @@ check_formals(idf, dc) dc->dc_formal = 0; } -declare_formals(idf, fp) - struct idf *idf; - arith *fp; +void declare_formals(struct idf *idf, arith *fp) { /* Declares those formals as int that haven't been declared - by the user. - An address is assigned to each formal parameter. - The total size of the formals is returned in *fp; - */ + by the user. + An address is assigned to each formal parameter. + The total size of the formals is returned in *fp; + */ register struct stack_entry *se = stack_level_of(L_FORMAL1)->sl_entry; - arith f_offset = (arith)0; + arith f_offset = (arith) 0; register int nparams = 0; int hasproto; struct def *df = idf->id_def; /* When one of the formals has the same name as the function, - it hides the function def. Get it. - */ - while (se) { - if (se->se_idf == idf) { + it hides the function def. Get it. + */ + while (se) + { + if (se->se_idf == idf) + { df = df->next; break; } @@ -540,49 +564,53 @@ declare_formals(idf, fp) } se = stack_level_of(L_FORMAL1)->sl_entry; - + hasproto = df->df_type->tp_proto != 0; #ifdef DEBUG if (options['t']) - dumpidftab("start declare_formals", 0); + dumpidftab("start declare_formals", 0); #endif /* DEBUG */ - if (is_struct_or_union(df->df_type->tp_up->tp_fund)) { + if (is_struct_or_union(df->df_type->tp_up->tp_fund)) + { /* create space for address of return value */ f_offset = pointer_size; } - while (se) { + while (se) + { df = se->se_idf->id_def; - + /* this stacklevel may also contain tags. ignore them */ - if (!df || df->df_level < L_FORMAL1 ) { + if (!df || df->df_level < L_FORMAL1) + { se = se->next; continue; } df->df_address = f_offset; /* the alignment convention for parameters is: align on - word boundaries, i.e. take care that the following - parameter starts on a new word boundary. - */ - if (! hasproto - && df->df_type->tp_fund == FLOAT - && df->df_type->tp_size != double_size) { + word boundaries, i.e. take care that the following + parameter starts on a new word boundary. + */ + if (!hasproto && df->df_type->tp_fund == FLOAT + && df->df_type->tp_size != double_size) + { f_offset = align(f_offset + double_size, (int) word_size); } - else f_offset = align(f_offset + df->df_type->tp_size, (int) word_size); + else + f_offset = align(f_offset + df->df_type->tp_size, (int) word_size); RegisterAccount(df->df_address, df->df_type->tp_size, - regtype(df->df_type), - df->df_sc); + regtype(df->df_type), df->df_sc); /* cvt int to char or short and double to float, if necessary */ formal_cvt(hasproto, df); - df->df_level = L_FORMAL2; /* CJ */ + df->df_level = L_FORMAL2; /* CJ */ if (nparams++ >= STDC_NPARAMS) strict("number of formal parameters exceeds ANSI limit"); #ifdef DBSYMTAB - if (options['g']) { + if (options['g']) + { stb_string(df, FORMAL, se->se_idf->id_text); } #endif /* DBSYMTAB */ @@ -591,11 +619,10 @@ declare_formals(idf, fp) *fp = f_offset; } -int -regtype(tp) - struct type *tp; +int regtype(struct type *tp) { - switch(tp->tp_fund) { + switch (tp->tp_fund) + { case INT: case LONG: return reg_any; @@ -609,18 +636,15 @@ regtype(tp) return -1; } -add_def(idf, sc, tp, lvl) - struct idf *idf; - struct type *tp; - int lvl; - int sc; +void add_def(struct idf *idf, int sc, struct type *tp, int lvl) { /* The identifier idf is declared on level lvl with storage - class sc and type tp, through a faked C declaration. - This is probably the wrong way to structure the problem, - but it will have to do for the time being. - */ - struct decspecs Ds; struct declarator Dc; + class sc and type tp, through a faked C declaration. + This is probably the wrong way to structure the problem, + but it will have to do for the time being. + */ + struct decspecs Ds; + struct declarator Dc; Ds = null_decspecs; Ds.ds_type = tp; @@ -630,25 +654,24 @@ add_def(idf, sc, tp, lvl) declare_idf(&Ds, &Dc, lvl); } -update_ahead(idf) - register struct idf *idf; +void update_ahead(register struct idf *idf) { /* The tk_symb of the token ahead is updated in the light of new - information about the identifier idf. - */ + information about the identifier idf. + */ register int tk_symb = AHEAD; - if ( (tk_symb == IDENTIFIER || tk_symb == TYPE_IDENTIFIER) && - ahead.tk_idf == idf - ) + if ((tk_symb == IDENTIFIER || tk_symb == TYPE_IDENTIFIER) + && ahead.tk_idf == idf) AHEAD = idf->id_def && idf->id_def->df_sc == TYPEDEF ? - TYPE_IDENTIFIER : IDENTIFIER; + TYPE_IDENTIFIER : + IDENTIFIER; } -free_formals(fm) - register struct formal *fm; +void free_formals(register struct formal *fm) { - while (fm) { + while (fm) + { struct formal *tmp = fm->next; free_formal(fm); diff --git a/lang/cem/cemcom.ansi/idf.str b/lang/cem/cemcom.ansi/idf.str index 06caa7f3e..d26ebfe56 100644 --- a/lang/cem/cemcom.ansi/idf.str +++ b/lang/cem/cemcom.ansi/idf.str @@ -2,10 +2,15 @@ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * See the copyright notice in the ACK home directory, in the file "Copyright". */ +#ifndef IDF_H_ +#define IDF_H_ + + /* $Id$ */ /* IDENTIFIER DESCRIPTOR */ #include "parameters.h" +#include "arith.h" struct id_u { int idd_reserved; /* non-zero for reserved words */ @@ -33,4 +38,28 @@ struct id_u { #include extern int level; -extern struct idf *gen_idf(); + +struct decspecs; +struct declarator; +struct type; +struct formal; + + +struct idf *gen_idf(void); +int is_anon_idf(struct idf *idf); +void declare_idf(struct decspecs *ds, struct declarator *dc, int lvl); +int actual_declaration(int sc, struct type *tp); +void global_redecl(register struct idf *idf, int new_sc, struct type *tp); +int good_formal(register struct def *def, register struct idf *idf); +void declare_params(struct declarator *dc); +void idf_initialized(register struct idf *idf); +void declare_parameter(struct idf *idf); +void declare_enum(struct type *tp, struct idf *idf, arith l); +void check_formals(struct idf *idf, struct declarator *dc); +void declare_formals(struct idf *idf, arith *fp); +int regtype(struct type *tp); +void add_def(struct idf *idf, int sc, struct type *tp, int lvl); +void update_ahead(register struct idf *idf); +void free_formals(register struct formal *fm); + +#endif \ No newline at end of file diff --git a/lang/cem/cemcom.ansi/input.c b/lang/cem/cemcom.ansi/input.c index dea9a4892..e5d019bb4 100644 --- a/lang/cem/cemcom.ansi/input.c +++ b/lang/cem/cemcom.ansi/input.c @@ -10,6 +10,7 @@ #include #include "file_info.h" #include "input.h" +#include "error.h" #define INP_PUSHBACK 3 #define INP_TYPE struct file_info @@ -20,14 +21,14 @@ struct file_info finfo; int NoUnstack; -AtEoIT() +int AtEoIT(void) { return 0; } extern char *source; -AtEoIF() +int AtEoIF(void) { if (NoUnstack) lexerror("unexpected EOF"); return 0; diff --git a/lang/cem/cemcom.ansi/input.h b/lang/cem/cemcom.ansi/input.h index 972eaf2f6..4ffbe0f5c 100644 --- a/lang/cem/cemcom.ansi/input.h +++ b/lang/cem/cemcom.ansi/input.h @@ -12,4 +12,4 @@ #define UnGetChar() ((LexSave != EOI) ? ChPushBack(LexSave) : 0) extern int LexSave; /* last character read by GetChar */ -extern int GetChar(); /* character input, with trigraph parsing */ + diff --git a/lang/cem/cemcom.ansi/ival.g b/lang/cem/cemcom.ansi/ival.g index e867aad86..80c6d1d01 100644 --- a/lang/cem/cemcom.ansi/ival.g +++ b/lang/cem/cemcom.ansi/ival.g @@ -1,774 +1,759 @@ -/* - * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. - * See the copyright notice in the ACK home directory, in the file "Copyright". - */ -/* $Id$ */ -/* CODE FOR THE INITIALISATION OF GLOBAL VARIABLES */ - -{ -#include -#include -#include "parameters.h" -#ifndef LINT -#include -#else -#include "l_em.h" -#include "l_lint.h" -#endif /* LINT */ -#include -#include -#include -#include -#include "idf.h" -#include "arith.h" -#include "label.h" -#include "expr.h" -#include "type.h" -#include "proto.h" -#include "struct.h" -#include "field.h" -#include "Lpars.h" -#include "sizes.h" -#include "align.h" -#include "level.h" -#include "def.h" -#include "LLlex.h" -#include "estack.h" -#include "stack.h" - -#define con_nullbyte() C_con_ucon("0", (arith)1) -#define aggregate_type(tp) ((tp)->tp_fund == ARRAY || (tp)->tp_fund == STRUCT) - -char *strncpy(); -extern char options[]; -static int gen_error; -static int pack_level; -struct type **gen_tphead(), **gen_tpmiddle(); -struct sdef *gen_align_to_next(); -struct e_stack *p_stack; - -void pad(); -void gen_simple_exp(); -void gen_tpcheck(); - -} - -/* initial_value recursively guides the initialisation expression. - */ -/* 3.5 */ - -initial_value(register struct type **tpp; register struct expr **expp;) : - { if (tpp) gen_tpcheck(tpp); } -[ - { if (pack_level == 0) gen_error = 0; } - assignment_expression(expp) - { -#ifdef LINT - lint_expr(*expp, USED); -#endif /* LINT */ - if ((*expp)->ex_type->tp_fund == ARRAY) - array2pointer(*expp); - if (tpp) { - if (level >= L_LOCAL - || is_ld_cst(*expp) - || is_fp_cst(*expp) - || (*expp)->ex_class == String) { - gen_simple_exp(tpp, expp); - free_expression(*expp); - *expp = 0; - } else { - expr_error(*expp,"illegal initialization"); - free_expression(*expp); - *expp = 0; - } - } - } -| - initial_value_pack(tpp, expp) -] -; - -initial_value_pack(struct type **tpp; struct expr **expp;) -: - '{' - { if (pack_level == 0) gen_error = 0; pack_level++; } - initial_value_list(tpp, expp) - { pack_level--; - if (!pack_level) { - while (p_stack) { - struct e_stack *p = p_stack->next; - - free_e_stack(p_stack); - p_stack = p; - } - } - if (pack_level < gen_error) gen_error = 0; - } - '}' -; - -initial_value_list(register struct type **tpp; struct expr **expp;) - { struct expr *e1; - register struct type **tpp2 = 0; - int err_flag = gen_error; - } -: - { if (tpp) tpp2 = gen_tphead(tpp, 0); } - initial_value(tpp2, &e1) - { if (!tpp) init_expression(&expp, e1); } - [%while (AHEAD != '}') /* >>> conflict on ',' */ - ',' - { if (tpp) tpp2 = gen_tpmiddle(); } - initial_value(tpp2, &e1) - { if (!tpp) init_expression(&expp, e1); } - ]* - { if (tpp && ! err_flag) gen_tpend(); } - ','? /* optional trailing comma */ -; - -{ -void -gen_tpcheck(tpp) - struct type **tpp; -{ - register struct type *tp; - - if (gen_error) return; - switch((tp = *tpp)->tp_fund) { - case ARRAY: - if (! valid_type(tp->tp_up, "array element")) - gen_error = pack_level; - break; - case STRUCT: - if (! valid_type(tp, "struct")) - gen_error = pack_level; - break; - case UNION: - if (! valid_type(tp, "union")) - gen_error = pack_level; - break; - case ERRONEOUS: - if (! gen_error) gen_error = pack_level; - break; - } -} - -void -gen_simple_exp(tpp, expp) - struct type **tpp; - struct expr **expp; -{ - register struct type *tp; - - if (gen_error) return; - tp = *tpp; - switch(tp->tp_fund) { - case ARRAY: - if ((*expp)->ex_class == String && tp->tp_up->tp_fund == CHAR) { - ch_array(tpp,*expp); - break; - } - /* Fall through */ - case UNION: - case STRUCT: - check_and_pad(expp, tpp); - break; - case ERRONEOUS: - case FUNCTION: - case VOID: - gen_error = pack_level; - break; - default: - check_ival(expp, tp); - break; - } -} - -struct type ** -arr_elem(tpp, p) - struct type **tpp; - struct e_stack *p; -{ - register struct type *tp = *tpp; - - if (tp->tp_up->tp_fund == CHAR && AHEAD == STRING && p->elem_count == 1) { - p->nelem = 1; - return tpp; - } - if (AHEAD == '{' || (! aggregate_type(tp->tp_up) && tp->tp_up->tp_fund != UNION)) - return &(tp->tp_up); - return gen_tphead(&(tp->tp_up), 1); -} - -struct sdef * -next_field(sd, p) - register struct sdef *sd; - register struct e_stack *p; -{ - if (sd->sd_sdef) - p->bytes_upto_here += zero_bytes(sd); - p->bytes_upto_here += - size_of_type(sd->sd_type, "selector"); - p->last_offset = sd->sd_offset; - return sd->sd_sdef; -} - -struct type ** -gen_tphead(tpp, nest) - struct type **tpp; -{ - register struct type *tp = *tpp; - register struct e_stack *p; - register struct sdef *sd; - - if (tpp && *tpp == error_type) { - gen_error = pack_level; - return 0; - } - if (gen_error) return tpp; - if (tp->tp_fund == UNION) { - /* Here, we saw a {, which could be the start of a union - initializer. It could, however, also be the start of the - initializer for the first union field ... - */ - sd = tp->tp_sdef; - if (AHEAD != '{' && - (aggregate_type(sd->sd_type) || - sd->sd_type->tp_fund == UNION)) { - /* In this case, assume that it is the start of the - initializer of the union field, so: - */ - return gen_tphead(&(tp->tp_sdef->sd_type), nest); - } - } - p = new_e_stack(); - p->next = p_stack; - p_stack = p; - p->s_nested = nest; - p->s_tpp = tpp; - switch(tp->tp_fund) { - case UNION: - p->s_def = sd = tp->tp_sdef; - p->bytes_upto_here = 0; - return &(sd->sd_type); - case ARRAY: - p->nelem = -1; - p->elem_count = 1; - if (tp->tp_size != (arith) -1) { - p->nelem = (tp->tp_size / tp->tp_up->tp_size); - } - return arr_elem(tpp, p); - case STRUCT: - p->s_def = sd = tp->tp_sdef; - p->bytes_upto_here = 0; - p->last_offset = -1; -#ifndef NOBITFIELD - while (sd && is_anon_idf(sd->sd_idf)) { - put_bf(sd->sd_type, (arith) 0); - sd = next_field(sd, p); - } -#endif - if (! sd) { - /* something wrong with this struct */ - gen_error = pack_level; - p_stack = p->next; - free_e_stack(p); - return 0; - } - p->s_def = sd; - if (AHEAD != '{' && aggregate_type(sd->sd_type)) { - return gen_tphead(&(sd->sd_type), 1); - } - return &(sd->sd_type); - case ERRONEOUS: - if (! gen_error) gen_error = pack_level; - /* fall through */ - default: - p->nelem = 1; - p->elem_count = 1; - return tpp; - } -} - -struct type ** -gen_tpmiddle() -{ - register struct type *tp; - register struct sdef *sd; - register struct e_stack *p = p_stack; - - if (gen_error) { - if (p) return p->s_tpp; - return 0; - } -again: - tp = *(p->s_tpp); - switch(tp->tp_fund) { - case ERRONEOUS: - if (! gen_error) gen_error = pack_level; - return p->s_tpp; - case UNION: - sd = p->s_def; - p->bytes_upto_here += - size_of_type(sd->sd_type, "selector"); - return p->s_tpp; - default: - if (p->elem_count == p->nelem && p->s_nested) { - p = p->next; - free_e_stack(p_stack); - p_stack = p; - goto again; - } - p->elem_count++; - if (p->nelem >= 0 && p->elem_count > p->nelem) { - too_many_initialisers(); - return p->s_tpp; - } - if (tp->tp_fund == ARRAY) { - return arr_elem(p->s_tpp, p); - } - return p->s_tpp; - case STRUCT: - sd = gen_align_to_next(p); - if (! sd) { - while (p->bytes_upto_here++ < tp->tp_size) - con_nullbyte(); - if (p->s_nested) { - p = p->next; - free_e_stack(p_stack); - p_stack = p; - goto again; - } - too_many_initialisers(); - return p->s_tpp; - } - if (AHEAD != '{' && aggregate_type(sd->sd_type)) { - return gen_tphead(&(sd->sd_type), 1); - } - return &(sd->sd_type); - } -} - -struct sdef * -gen_align_to_next(p) - register struct e_stack *p; -{ - register struct sdef *sd = p->s_def; - - if (! sd) return sd; -#ifndef NOBITFIELD - do { - if (is_anon_idf(sd->sd_idf)) put_bf(sd->sd_type, (arith) 0); -#endif - sd = next_field(sd, p); -#ifndef NOBITFIELD - } while (sd && is_anon_idf(sd->sd_idf)); -#endif - p->s_def = sd; - return sd; -} - -gen_tpend() -{ - register struct e_stack *p = p_stack; - register struct type *tp; - register struct sdef *sd; - int getout = 0; - - while (!getout && p) { - if (!gen_error) { - tp = *(p->s_tpp); - switch(tp->tp_fund) { - case UNION: - sd = p->s_def; - p->bytes_upto_here += - size_of_type(sd->sd_type, "selector"); - while (p->bytes_upto_here++ < tp->tp_size) - con_nullbyte(); - break; - case ARRAY: - if (tp->tp_size == -1) { - *(p->s_tpp) = construct_type(ARRAY, tp->tp_up, - 0, p->elem_count, NO_PROTO); - } - else { - while (p->nelem-- > p->elem_count) { - pad(tp->tp_up); - } - } - break; - case STRUCT: - sd = gen_align_to_next(p); - while (sd) { - pad(sd->sd_type); - if (sd->sd_sdef) - p->bytes_upto_here += zero_bytes(sd); - p->bytes_upto_here += - size_of_type(sd->sd_type, "selector"); - sd = sd->sd_sdef; - } - while (p->bytes_upto_here++ < tp->tp_size) - con_nullbyte(); - break; - } - } - if (! p->s_nested) getout = 1; - p = p->next; - free_e_stack(p_stack); - p_stack = p; - } -} - -/* check_and_pad() is given a simple initialisation expression - where the type can be either a simple or an aggregate type. - In the latter case, only the first member is initialised and - the rest is zeroed. -*/ -check_and_pad(expp, tpp) - struct type **tpp; - struct expr **expp; -{ - register struct type *tp = *tpp; - - if (tp->tp_fund == ARRAY) { - check_and_pad(expp, &(tp->tp_up)); /* first member */ - if (tp->tp_size == (arith)-1) - /* no size specified upto here: just - set it to the size of one member. - */ - tp = *tpp = construct_type(ARRAY, tp->tp_up, - 0, (arith)1, NO_PROTO); - else { - register int dim = tp->tp_size / tp->tp_up->tp_size; - /* pad remaining members with zeroes */ - while (--dim > 0) - pad(tp->tp_up); - } - } - else - if (tp->tp_fund == STRUCT) { - register struct sdef *sd = tp->tp_sdef; - - check_and_pad(expp, &(sd->sd_type)); - /* next selector is aligned by adding extra zeroes */ - if (sd->sd_sdef) - zero_bytes(sd); - while (sd = sd->sd_sdef) { /* pad remaining selectors */ - pad(sd->sd_type); - if (sd->sd_sdef) - zero_bytes(sd); - } - } - else if (tp->tp_fund == UNION) { - /* only the first selector can be initialized */ - register struct sdef *sd = tp->tp_sdef; - - check_and_pad(expp, &(sd->sd_type)); - } - else /* simple type */ - check_ival(expp, tp); -} - -/* pad() fills an element of type tp with zeroes. - If the element is an aggregate, pad() is called recursively. -*/ -void -pad(tpx) - struct type *tpx; -{ - register struct type *tp = tpx; - register arith sz = tp->tp_size; - - gen_tpcheck(&tpx); - if (gen_error) return; -#ifndef NOBITFIELD - if (tp->tp_fund == FIELD) { - put_bf(tp, (arith)0); - return; - } -#endif /* NOBITFIELD */ - - if (tp->tp_align >= word_align) while (sz >= word_size) { - C_con_cst((arith) 0); - sz -= word_size; - } - while (sz) { - C_con_icon("0", (arith) 1); - sz--; - } -} - -/* check_ival() checks whether the initialisation of an element - of a fundamental type is legal and, if so, performs the initialisation - by directly generating the necessary code. - No further comment is needed to explain the internal structure - of this straightforward function. -*/ -check_ival(expp, tp) - register struct type *tp; - struct expr **expp; -{ - /* The philosophy here is that ch3cast puts an explicit - conversion node in front of the expression if the types - are not compatible. In this case, the initialisation - expression is no longer a constant. - */ - register struct expr *expr = *expp; - - switch (tp->tp_fund) { - case CHAR: - case SHORT: - case INT: - case LONG: - case ENUM: - case POINTER: - ch3cast(expp, '=', tp); - expr = *expp; -#ifdef DEBUG - print_expr("init-expr after cast", expr); -#endif /* DEBUG */ - if (!is_ld_cst(expr)) - illegal_init_cst(expr); - else - if (expr->VL_CLASS == Const) - con_int(expr); - else - if (expr->VL_CLASS == Name) { - register struct idf *idf = expr->VL_IDF; - - if (idf->id_def->df_level >= L_LOCAL - && idf->id_def->df_sc != GLOBAL - && idf->id_def->df_sc != EXTERN) { - illegal_init_cst(expr); - } - else /* e.g., int f(); int p = f; */ - if (idf->id_def->df_type->tp_fund == FUNCTION) - C_con_pnam(idf->id_text); - else /* e.g., int a; int *p = &a; */ - C_con_dnam(idf->id_text, expr->VL_VALUE); - } - else { - assert(expr->VL_CLASS == Label); - C_con_dlb(expr->VL_LBL, expr->VL_VALUE); - } - break; - case FLOAT: - case DOUBLE: - case LNGDBL: - ch3cast(expp, '=', tp); - expr = *expp; -#ifdef DEBUG - print_expr("init-expr after cast", expr); -#endif /* DEBUG */ - if (expr->ex_class == Float) { - char buf[FLT_STRLEN]; - - flt_flt2str(&(expr->FL_ARITH), buf, FLT_STRLEN); - C_con_fcon(buf, expr->ex_type->tp_size); - } -#ifdef NOTDEF - -Coercion from int to float is now always done compile time. -This, to accept declarations like -double x = -(double)1; -and also to prevent runtime coercions for compile-time constants. - - else - if (expr->ex_class == Oper && expr->OP_OPER == INT2FLOAT) { - /* float f = 1; */ - expr = expr->OP_RIGHT; - if (is_cp_cst(expr)) - C_con_fcon(long2str((long)expr->VL_VALUE, 10), - tp->tp_size); - else - illegal_init_cst(expr); - } -#endif /* NOTDEF */ - else - illegal_init_cst(expr); - break; - -#ifndef NOBITFIELD - case FIELD: - ch3cast(expp, '=', tp->tp_up); - expr = *expp; -#ifdef DEBUG - print_expr("init-expr after cast", expr); -#endif /* DEBUG */ - if (is_cp_cst(expr)) - put_bf(tp, expr->VL_VALUE); - else - illegal_init_cst(expr); - break; -#endif /* NOBITFIELD */ - - case ERRONEOUS: - if (! gen_error) gen_error = pack_level; - /* fall through */ - case VOID: - break; - default: - crash("check_ival"); - /*NOTREACHED*/ - } -} - -/* ch_array() initialises an array of characters when given - a string constant. - Alignment is taken care of. -*/ -ch_array(tpp, ex) - struct type **tpp; /* type tp = array of characters */ - struct expr *ex; -{ - register struct type *tp = *tpp; - register int length = ex->SG_LEN, i; - register char *to, *from, *s; - - assert(ex->ex_class == String); - if (tp->tp_size == (arith)-1) { - /* set the dimension */ - tp = *tpp = construct_type(ARRAY, tp->tp_up, 0, (arith)length, NO_PROTO); - } - else { - arith dim = tp->tp_size / tp->tp_up->tp_size; - -#ifdef LINT - if (length == dim + 1) { - expr_warning(ex, "array is not null-terminated"); - } else -#endif - if (length > dim + 1) { - expr_strict(ex, "too many initializers"); - } - length = dim; - } - /* throw out the characters of the already prepared string */ - s = Malloc((unsigned) (length)); - clear(s, (unsigned)length); - i = length <= ex->SG_LEN ? length : ex->SG_LEN; - to = s; from = ex->SG_VALUE; - while(--i >= 0) { - *to++ = *from++; - } - free(ex->SG_VALUE); - str_cst(s, length, 0); /* a string, but not in rom */ - free(s); -} - -/* As long as some parts of the pipeline cannot handle very long string - constants, string constants are written out in chunks -*/ -str_cst(str, len, inrom) - register char *str; - register int len; - int inrom; -{ - int chunksize = ((127 + (int) word_size) / (int) word_size) * (int) word_size; - - while (len > chunksize) { - if (inrom) - C_rom_scon(str, (arith) chunksize); - else C_con_scon(str, (arith) chunksize); - len -= chunksize; - str += chunksize; - } - if (inrom) - C_rom_scon(str, (arith) len); - else C_con_scon(str, (arith) len); -} - -#ifndef NOBITFIELD -/* put_bf() takes care of the initialisation of (bit-)field - selectors of a struct: each time such an initialisation takes place, - put_bf() is called instead of the normal code generating routines. - Put_bf() stores the given integral value into "field" and - "throws" the result of "field" out if the current selector - is the last of this number of fields stored at the same address. -*/ -put_bf(tp, val) - struct type *tp; - arith val; -{ - static long field = (arith)0; - static arith offset = (arith)-1; - register struct field *fd = tp->tp_field; - register struct sdef *sd = fd->fd_sdef; - static struct expr exp; - - assert(sd); - if (offset == (arith)-1) { - /* first bitfield in this field */ - offset = sd->sd_offset; - exp.ex_type = tp->tp_up; - exp.ex_class = Value; - exp.VL_CLASS = Const; - } - if (val != 0) /* insert the value into "field" */ - field |= (val & fd->fd_mask) << fd->fd_shift; - if (sd->sd_sdef == 0 || sd->sd_sdef->sd_offset != offset) { - /* the selector was the last stored at this address */ - exp.VL_VALUE = field; - con_int(&exp); - field = (arith)0; - offset = (arith)-1; - } -} -#endif /* NOBITFIELD */ - -int -zero_bytes(sd) - register struct sdef *sd; -{ - /* fills the space between a selector of a struct - and the next selector of that struct with zero-bytes. - */ - register int n = sd->sd_sdef->sd_offset - sd->sd_offset - - size_of_type(sd->sd_type, "struct member"); - int count = n; - - while (n-- > 0) - con_nullbyte(); - return count; -} - -int -valid_type(tp, str) - struct type *tp; - char *str; -{ - assert(tp!=(struct type *)0); - if (tp->tp_size < 0) { - error("size of %s unknown", str); - return 0; - } - return 1; -} - -con_int(ex) - register struct expr *ex; -{ - register struct type *tp = ex->ex_type; - - assert(is_cp_cst(ex)); - if (tp->tp_unsigned) - C_con_ucon(long2str((long)ex->VL_VALUE, -10), tp->tp_size); - else if (tp->tp_size == word_size) - C_con_cst(ex->VL_VALUE); - else - C_con_icon(long2str((long)ex->VL_VALUE, 10), tp->tp_size); -} - -illegal_init_cst(ex) - struct expr *ex; -{ - expr_error(ex, "illegal initialization constant"); - gen_error = pack_level; -} - -too_many_initialisers() -{ - error("too many initializers"); - gen_error = pack_level; -} -} +/* + * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. + * See the copyright notice in the ACK home directory, in the file "Copyright". + */ +/* $Id$ */ +/* CODE FOR THE INITIALISATION OF GLOBAL VARIABLES */ + +{ +#include +#include +#include "parameters.h" +#ifndef LINT +#include +#else +#include "l_em.h" +#include "l_lint.h" +#endif /* LINT */ +#include +#include +#include +#include +#include +#include "idf.h" +#include "arith.h" +#include "label.h" +#include "expr.h" +#include "type.h" +#include "proto.h" +#include "struct.h" +#include "field.h" +#include "Lpars.h" +#include "sizes.h" +#include "align.h" +#include "level.h" +#include "error.h" +#include "def.h" +#include "LLlex.h" +#include "estack.h" +#include "stack.h" +#include "ch3.h" + +#define con_nullbyte() C_con_ucon("0", (arith)1) +#define aggregate_type(tp) ((tp)->tp_fund == ARRAY || (tp)->tp_fund == STRUCT) + +extern char options[]; +static int gen_error; +static int pack_level; +struct e_stack *p_stack; + +void gen_tpcheck(struct type **); +void gen_simple_exp(struct type **, struct expr **); +struct type **arr_elem(struct type **, struct e_stack *); +struct sdef *next_field(register struct sdef *,register struct e_stack *); +struct type **gen_tphead(struct type **, int); +struct type **gen_tpmiddle(void); +struct sdef *gen_align_to_next(register struct e_stack *); +void gen_tpend(void); +void check_and_pad(struct expr **, struct type **); +void pad(struct type *); +void check_ival(struct expr **, register struct type *); +void ch_array(struct type **, /* type tp = array of characters */ + struct expr *); +void str_cst(register char *, register int, int); +#ifndef NOBITFIELD +void put_bf(struct type *, arith ); +#endif /* NOBITFIELD */ +int zero_bytes(register struct sdef *); +int valid_type(struct type *, char *); +void con_int(register struct expr *); +void illegal_init_cst(struct expr *); +void too_many_initialisers(void); + +} + +/* initial_value recursively guides the initialisation expression. + */ +/* 3.5 */ + +initial_value(register struct type **tpp; register struct expr **expp;) : + { if (tpp) gen_tpcheck(tpp); } +[ + { if (pack_level == 0) gen_error = 0; } + assignment_expression(expp) + { +#ifdef LINT + lint_expr(*expp, USED); +#endif /* LINT */ + if ((*expp)->ex_type->tp_fund == ARRAY) + array2pointer(*expp); + if (tpp) { + if (level >= L_LOCAL + || is_ld_cst(*expp) + || is_fp_cst(*expp) + || (*expp)->ex_class == String) { + gen_simple_exp(tpp, expp); + free_expression(*expp); + *expp = 0; + } else { + expr_error(*expp,"illegal initialization"); + free_expression(*expp); + *expp = 0; + } + } + } +| + initial_value_pack(tpp, expp) +] +; + +initial_value_pack(struct type **tpp; struct expr **expp;) +: + '{' + { if (pack_level == 0) gen_error = 0; pack_level++; } + initial_value_list(tpp, expp) + { pack_level--; + if (!pack_level) { + while (p_stack) { + struct e_stack *p = p_stack->next; + + free_e_stack(p_stack); + p_stack = p; + } + } + if (pack_level < gen_error) gen_error = 0; + } + '}' +; + +initial_value_list(register struct type **tpp; struct expr **expp;) + { struct expr *e1; + register struct type **tpp2 = 0; + int err_flag = gen_error; + } +: + { if (tpp) tpp2 = gen_tphead(tpp, 0); } + initial_value(tpp2, &e1) + { if (!tpp) init_expression(&expp, e1); } + [%while (AHEAD != '}') /* >>> conflict on ',' */ + ',' + { if (tpp) tpp2 = gen_tpmiddle(); } + initial_value(tpp2, &e1) + { if (!tpp) init_expression(&expp, e1); } + ]* + { if (tpp && ! err_flag) gen_tpend(); } + ','? /* optional trailing comma */ +; + +{ +void gen_tpcheck(struct type **tpp) +{ + register struct type *tp; + + if (gen_error) return; + switch((tp = *tpp)->tp_fund) { + case ARRAY: + if (! valid_type(tp->tp_up, "array element")) + gen_error = pack_level; + break; + case STRUCT: + if (! valid_type(tp, "struct")) + gen_error = pack_level; + break; + case UNION: + if (! valid_type(tp, "union")) + gen_error = pack_level; + break; + case ERRONEOUS: + if (! gen_error) gen_error = pack_level; + break; + } +} + +void gen_simple_exp(struct type **tpp, struct expr **expp) +{ + register struct type *tp; + + if (gen_error) return; + tp = *tpp; + switch(tp->tp_fund) { + case ARRAY: + if ((*expp)->ex_class == String && tp->tp_up->tp_fund == CHAR) { + ch_array(tpp,*expp); + break; + } + /* Fall through */ + case UNION: + case STRUCT: + check_and_pad(expp, tpp); + break; + case ERRONEOUS: + case FUNCTION: + case VOID: + gen_error = pack_level; + break; + default: + check_ival(expp, tp); + break; + } +} + +struct type **arr_elem(struct type **tpp, struct e_stack *p) +{ + register struct type *tp = *tpp; + + if (tp->tp_up->tp_fund == CHAR && AHEAD == STRING && p->elem_count == 1) { + p->nelem = 1; + return tpp; + } + if (AHEAD == '{' || (! aggregate_type(tp->tp_up) && tp->tp_up->tp_fund != UNION)) + return &(tp->tp_up); + return gen_tphead(&(tp->tp_up), 1); +} + +struct sdef *next_field(register struct sdef *sd, + register struct e_stack *p) +{ + if (sd->sd_sdef) + p->bytes_upto_here += zero_bytes(sd); + p->bytes_upto_here += + size_of_type(sd->sd_type, "selector"); + p->last_offset = sd->sd_offset; + return sd->sd_sdef; +} + +struct type **gen_tphead(struct type **tpp, int nest) +{ + register struct type *tp = *tpp; + register struct e_stack *p; + register struct sdef *sd; + + if (tpp && *tpp == error_type) { + gen_error = pack_level; + return 0; + } + if (gen_error) return tpp; + if (tp->tp_fund == UNION) { + /* Here, we saw a {, which could be the start of a union + initializer. It could, however, also be the start of the + initializer for the first union field ... + */ + sd = tp->tp_sdef; + if (AHEAD != '{' && + (aggregate_type(sd->sd_type) || + sd->sd_type->tp_fund == UNION)) { + /* In this case, assume that it is the start of the + initializer of the union field, so: + */ + return gen_tphead(&(tp->tp_sdef->sd_type), nest); + } + } + p = new_e_stack(); + p->next = p_stack; + p_stack = p; + p->s_nested = nest; + p->s_tpp = tpp; + switch(tp->tp_fund) { + case UNION: + p->s_def = sd = tp->tp_sdef; + p->bytes_upto_here = 0; + return &(sd->sd_type); + case ARRAY: + p->nelem = -1; + p->elem_count = 1; + if (tp->tp_size != (arith) -1) { + p->nelem = (tp->tp_size / tp->tp_up->tp_size); + } + return arr_elem(tpp, p); + case STRUCT: + p->s_def = sd = tp->tp_sdef; + p->bytes_upto_here = 0; + p->last_offset = -1; +#ifndef NOBITFIELD + while (sd && is_anon_idf(sd->sd_idf)) { + put_bf(sd->sd_type, (arith) 0); + sd = next_field(sd, p); + } +#endif + if (! sd) { + /* something wrong with this struct */ + gen_error = pack_level; + p_stack = p->next; + free_e_stack(p); + return 0; + } + p->s_def = sd; + if (AHEAD != '{' && aggregate_type(sd->sd_type)) { + return gen_tphead(&(sd->sd_type), 1); + } + return &(sd->sd_type); + case ERRONEOUS: + if (! gen_error) gen_error = pack_level; + /* fall through */ + default: + p->nelem = 1; + p->elem_count = 1; + return tpp; + } +} + +struct type **gen_tpmiddle(void) +{ + register struct type *tp; + register struct sdef *sd; + register struct e_stack *p = p_stack; + + if (gen_error) { + if (p) return p->s_tpp; + return 0; + } +again: + tp = *(p->s_tpp); + switch(tp->tp_fund) { + case ERRONEOUS: + if (! gen_error) gen_error = pack_level; + return p->s_tpp; + case UNION: + sd = p->s_def; + p->bytes_upto_here += + size_of_type(sd->sd_type, "selector"); + return p->s_tpp; + default: + if (p->elem_count == p->nelem && p->s_nested) { + p = p->next; + free_e_stack(p_stack); + p_stack = p; + goto again; + } + p->elem_count++; + if (p->nelem >= 0 && p->elem_count > p->nelem) { + too_many_initialisers(); + return p->s_tpp; + } + if (tp->tp_fund == ARRAY) { + return arr_elem(p->s_tpp, p); + } + return p->s_tpp; + case STRUCT: + sd = gen_align_to_next(p); + if (! sd) { + while (p->bytes_upto_here++ < tp->tp_size) + con_nullbyte(); + if (p->s_nested) { + p = p->next; + free_e_stack(p_stack); + p_stack = p; + goto again; + } + too_many_initialisers(); + return p->s_tpp; + } + if (AHEAD != '{' && aggregate_type(sd->sd_type)) { + return gen_tphead(&(sd->sd_type), 1); + } + return &(sd->sd_type); + } +} + +struct sdef *gen_align_to_next(register struct e_stack *p) +{ + register struct sdef *sd = p->s_def; + + if (! sd) return sd; +#ifndef NOBITFIELD + do { + if (is_anon_idf(sd->sd_idf)) put_bf(sd->sd_type, (arith) 0); +#endif + sd = next_field(sd, p); +#ifndef NOBITFIELD + } while (sd && is_anon_idf(sd->sd_idf)); +#endif + p->s_def = sd; + return sd; +} + +void gen_tpend(void) +{ + register struct e_stack *p = p_stack; + register struct type *tp; + register struct sdef *sd; + int getout = 0; + + while (!getout && p) { + if (!gen_error) { + tp = *(p->s_tpp); + switch(tp->tp_fund) { + case UNION: + sd = p->s_def; + p->bytes_upto_here += + size_of_type(sd->sd_type, "selector"); + while (p->bytes_upto_here++ < tp->tp_size) + con_nullbyte(); + break; + case ARRAY: + if (tp->tp_size == -1) { + *(p->s_tpp) = construct_type(ARRAY, tp->tp_up, + 0, p->elem_count, NO_PROTO); + } + else { + while (p->nelem-- > p->elem_count) { + pad(tp->tp_up); + } + } + break; + case STRUCT: + sd = gen_align_to_next(p); + while (sd) { + pad(sd->sd_type); + if (sd->sd_sdef) + p->bytes_upto_here += zero_bytes(sd); + p->bytes_upto_here += + size_of_type(sd->sd_type, "selector"); + sd = sd->sd_sdef; + } + while (p->bytes_upto_here++ < tp->tp_size) + con_nullbyte(); + break; + } + } + if (! p->s_nested) getout = 1; + p = p->next; + free_e_stack(p_stack); + p_stack = p; + } +} + +/* check_and_pad() is given a simple initialisation expression + where the type can be either a simple or an aggregate type. + In the latter case, only the first member is initialised and + the rest is zeroed. +*/ +void check_and_pad(struct expr **expp, struct type **tpp) +{ + register struct type *tp = *tpp; + + if (tp->tp_fund == ARRAY) { + check_and_pad(expp, &(tp->tp_up)); /* first member */ + if (tp->tp_size == (arith)-1) + /* no size specified upto here: just + set it to the size of one member. + */ + tp = *tpp = construct_type(ARRAY, tp->tp_up, + 0, (arith)1, NO_PROTO); + else { + register int dim = tp->tp_size / tp->tp_up->tp_size; + /* pad remaining members with zeroes */ + while (--dim > 0) + pad(tp->tp_up); + } + } + else + if (tp->tp_fund == STRUCT) { + register struct sdef *sd = tp->tp_sdef; + + check_and_pad(expp, &(sd->sd_type)); + /* next selector is aligned by adding extra zeroes */ + if (sd->sd_sdef) + zero_bytes(sd); + while (sd = sd->sd_sdef) { /* pad remaining selectors */ + pad(sd->sd_type); + if (sd->sd_sdef) + zero_bytes(sd); + } + } + else if (tp->tp_fund == UNION) { + /* only the first selector can be initialized */ + register struct sdef *sd = tp->tp_sdef; + + check_and_pad(expp, &(sd->sd_type)); + } + else /* simple type */ + check_ival(expp, tp); +} + +/* pad() fills an element of type tp with zeroes. + If the element is an aggregate, pad() is called recursively. +*/ +void pad(struct type *tpx) +{ + register struct type *tp = tpx; + register arith sz = tp->tp_size; + + gen_tpcheck(&tpx); + if (gen_error) return; +#ifndef NOBITFIELD + if (tp->tp_fund == FIELD) { + put_bf(tp, (arith)0); + return; + } +#endif /* NOBITFIELD */ + + if (tp->tp_align >= word_align) while (sz >= word_size) { + C_con_cst((arith) 0); + sz -= word_size; + } + while (sz) { + C_con_icon("0", (arith) 1); + sz--; + } +} + +/* check_ival() checks whether the initialisation of an element + of a fundamental type is legal and, if so, performs the initialisation + by directly generating the necessary code. + No further comment is needed to explain the internal structure + of this straightforward function. +*/ +void check_ival(struct expr **expp, register struct type *tp) +{ + /* The philosophy here is that ch3cast puts an explicit + conversion node in front of the expression if the types + are not compatible. In this case, the initialisation + expression is no longer a constant. + */ + register struct expr *expr = *expp; + + switch (tp->tp_fund) { + case CHAR: + case SHORT: + case INT: + case LONG: + case ENUM: + case POINTER: + ch3cast(expp, '=', tp); + expr = *expp; +#ifdef DEBUG + print_expr("init-expr after cast", expr); +#endif /* DEBUG */ + if (!is_ld_cst(expr)) + illegal_init_cst(expr); + else + if (expr->VL_CLASS == Const) + con_int(expr); + else + if (expr->VL_CLASS == Name) { + register struct idf *idf = expr->VL_IDF; + + if (idf->id_def->df_level >= L_LOCAL + && idf->id_def->df_sc != GLOBAL + && idf->id_def->df_sc != EXTERN) { + illegal_init_cst(expr); + } + else /* e.g., int f(); int p = f; */ + if (idf->id_def->df_type->tp_fund == FUNCTION) + C_con_pnam(idf->id_text); + else /* e.g., int a; int *p = &a; */ + C_con_dnam(idf->id_text, expr->VL_VALUE); + } + else { + assert(expr->VL_CLASS == Label); + C_con_dlb(expr->VL_LBL, expr->VL_VALUE); + } + break; + case FLOAT: + case DOUBLE: + case LNGDBL: + ch3cast(expp, '=', tp); + expr = *expp; +#ifdef DEBUG + print_expr("init-expr after cast", expr); +#endif /* DEBUG */ + if (expr->ex_class == Float) { + char buf[FLT_STRLEN]; + + flt_flt2str(&(expr->FL_ARITH), buf, FLT_STRLEN); + C_con_fcon(buf, expr->ex_type->tp_size); + } +#ifdef NOTDEF + +Coercion from int to float is now always done compile time. +This, to accept declarations like +double x = -(double)1; +and also to prevent runtime coercions for compile-time constants. + + else + if (expr->ex_class == Oper && expr->OP_OPER == INT2FLOAT) { + /* float f = 1; */ + expr = expr->OP_RIGHT; + if (is_cp_cst(expr)) + C_con_fcon(long2str((long)expr->VL_VALUE, 10), + tp->tp_size); + else + illegal_init_cst(expr); + } +#endif /* NOTDEF */ + else + illegal_init_cst(expr); + break; + +#ifndef NOBITFIELD + case FIELD: + ch3cast(expp, '=', tp->tp_up); + expr = *expp; +#ifdef DEBUG + print_expr("init-expr after cast", expr); +#endif /* DEBUG */ + if (is_cp_cst(expr)) + put_bf(tp, expr->VL_VALUE); + else + illegal_init_cst(expr); + break; +#endif /* NOBITFIELD */ + + case ERRONEOUS: + if (! gen_error) gen_error = pack_level; + /* fall through */ + case VOID: + break; + default: + crash("check_ival"); + /*NOTREACHED*/ + } +} + +/* ch_array() initialises an array of characters when given + a string constant. + Alignment is taken care of. +*/ +void ch_array(struct type **tpp, /* type tp = array of characters */ + struct expr *ex) +{ + register struct type *tp = *tpp; + register int length = ex->SG_LEN, i; + register char *to, *from, *s; + + assert(ex->ex_class == String); + if (tp->tp_size == (arith)-1) { + /* set the dimension */ + tp = *tpp = construct_type(ARRAY, tp->tp_up, 0, (arith)length, NO_PROTO); + } + else { + arith dim = tp->tp_size / tp->tp_up->tp_size; + +#ifdef LINT + if (length == dim + 1) { + expr_warning(ex, "array is not null-terminated"); + } else +#endif + if (length > dim + 1) { + expr_strict(ex, "too many initializers"); + } + length = dim; + } + /* throw out the characters of the already prepared string */ + s = Malloc((unsigned) (length)); + clear(s, (unsigned)length); + i = length <= ex->SG_LEN ? length : ex->SG_LEN; + to = s; from = ex->SG_VALUE; + while(--i >= 0) { + *to++ = *from++; + } + free(ex->SG_VALUE); + str_cst(s, length, 0); /* a string, but not in rom */ + free(s); +} + +/* As long as some parts of the pipeline cannot handle very long string + constants, string constants are written out in chunks +*/ +void str_cst(register char *str, register int len, int inrom) +{ + int chunksize = ((127 + (int) word_size) / (int) word_size) * (int) word_size; + + while (len > chunksize) { + if (inrom) + C_rom_scon(str, (arith) chunksize); + else C_con_scon(str, (arith) chunksize); + len -= chunksize; + str += chunksize; + } + if (inrom) + C_rom_scon(str, (arith) len); + else C_con_scon(str, (arith) len); +} + +#ifndef NOBITFIELD +/* put_bf() takes care of the initialisation of (bit-)field + selectors of a struct: each time such an initialisation takes place, + put_bf() is called instead of the normal code generating routines. + Put_bf() stores the given integral value into "field" and + "throws" the result of "field" out if the current selector + is the last of this number of fields stored at the same address. +*/ +void put_bf(struct type *tp, arith val) +{ + static long field = (arith)0; + static arith offset = (arith)-1; + register struct field *fd = tp->tp_field; + register struct sdef *sd = fd->fd_sdef; + static struct expr exp; + + assert(sd); + if (offset == (arith)-1) { + /* first bitfield in this field */ + offset = sd->sd_offset; + exp.ex_type = tp->tp_up; + exp.ex_class = Value; + exp.VL_CLASS = Const; + } + if (val != 0) /* insert the value into "field" */ + field |= (val & fd->fd_mask) << fd->fd_shift; + if (sd->sd_sdef == 0 || sd->sd_sdef->sd_offset != offset) { + /* the selector was the last stored at this address */ + exp.VL_VALUE = field; + con_int(&exp); + field = (arith)0; + offset = (arith)-1; + } +} +#endif /* NOBITFIELD */ + +int zero_bytes(register struct sdef *sd) +{ + /* fills the space between a selector of a struct + and the next selector of that struct with zero-bytes. + */ + register int n = sd->sd_sdef->sd_offset - sd->sd_offset - + size_of_type(sd->sd_type, "struct member"); + int count = n; + + while (n-- > 0) + con_nullbyte(); + return count; +} + +int valid_type(struct type *tp, char *str) +{ + assert(tp!=(struct type *)0); + if (tp->tp_size < 0) { + error("size of %s unknown", str); + return 0; + } + return 1; +} + +void con_int(register struct expr *ex) +{ + register struct type *tp = ex->ex_type; + + assert(is_cp_cst(ex)); + if (tp->tp_unsigned) + C_con_ucon(long2str((long)ex->VL_VALUE, -10), tp->tp_size); + else if (tp->tp_size == word_size) + C_con_cst(ex->VL_VALUE); + else + C_con_icon(long2str((long)ex->VL_VALUE, 10), tp->tp_size); +} + +void illegal_init_cst(struct expr *ex) +{ + expr_error(ex, "illegal initialization constant"); + gen_error = pack_level; +} + +void too_many_initialisers(void) +{ + error("too many initializers"); + gen_error = pack_level; +} +} diff --git a/lang/cem/cemcom.ansi/label.c b/lang/cem/cemcom.ansi/label.c index fb200956e..e4c10f85d 100644 --- a/lang/cem/cemcom.ansi/label.c +++ b/lang/cem/cemcom.ansi/label.c @@ -14,11 +14,12 @@ #include "def.h" #include "type.h" #include "stack.h" +#include "error.h" + extern char options[]; -enter_label(idf, defining) - register struct idf *idf; +void enter_label(register struct idf *idf, int defining) { /* The identifier idf is entered as a label. If it is new, it is entered into the idf list with the largest possible @@ -45,8 +46,7 @@ enter_label(idf, defining) def->df_initialized = 1; } -unstack_label(idf) - register struct idf *idf; +void unstack_label(register struct idf *idf) { /* The scope in which the label idf occurred is left. */ diff --git a/lang/cem/cemcom.ansi/label.h b/lang/cem/cemcom.ansi/label.h index 629577db2..47d6b5bea 100644 --- a/lang/cem/cemcom.ansi/label.h +++ b/lang/cem/cemcom.ansi/label.h @@ -4,6 +4,8 @@ */ /* $Id$ */ /* L A B E L D E F I N I T I O N */ +#ifndef LABEL_H_ +#define LABEL_H_ #include /* obtain definition of "label" */ @@ -26,3 +28,10 @@ extern label datlab_count; not be there, and if it is there, it may be from a declaration or another application. */ + +struct idf; + +void enter_label(register struct idf *idf, int defining); +void unstack_label(register struct idf *idf); + +#endif /* LABEL_H_ */ diff --git a/lang/cem/cemcom.ansi/main.c b/lang/cem/cemcom.ansi/main.c index d8e951af3..9d9f8903f 100644 --- a/lang/cem/cemcom.ansi/main.c +++ b/lang/cem/cemcom.ansi/main.c @@ -23,7 +23,13 @@ #include "specials.h" #include "sizes.h" #include "align.h" +#include "stack.h" #include "macro.h" +#include "options.h" +#include "error.h" +#include "code.h" +#include "cstoper.h" +#include "tokenname.h" extern struct tokenname tkidf[]; extern char *symbol2str(); @@ -34,7 +40,15 @@ struct sp_id special_ids[] = { {0, 0} }; -void dependency(); +void compile(int argc, char *argv[]); +static void init(void); +static void init_specials(register struct sp_id *si); +#ifdef DEBUG +void Info(void); +#endif + +extern void C_program(void); /* program.c */ + #ifndef NOCROSS arith @@ -63,8 +77,7 @@ int char *prog_name; -main(argc, argv) - char *argv[]; +int main(int argc, char *argv[]) { /* parse and interpret the command line options */ prog_name = argv[0]; @@ -104,8 +117,7 @@ char *source = 0; char *nmlist = 0; #endif /* GEN_NM_LIST */ -compile(argc, argv) - char *argv[]; +void compile(int argc, char *argv[]) { char *result; #ifndef LINT @@ -190,7 +202,7 @@ compile(argc, argv) } } -init() +static void init(void) { init_cst(); /* initialize variables of "cstoper.c" */ reserve(tkidf); /* mark the C reserved words as such */ @@ -255,8 +267,7 @@ init() stack_level(); } -init_specials(si) - register struct sp_id *si; +static void init_specials(register struct sp_id *si) { while (si->si_identifier) { struct idf *idf = str2idf(si->si_identifier, 0); @@ -269,7 +280,7 @@ init_specials(si) } #ifdef DEBUG -Info() +void Info(void) { extern int cnt_string_cst, cnt_formal, cnt_decl_unary, cnt_def, cnt_expr, cnt_field, @@ -301,14 +312,12 @@ Info() } #endif /* DEBUG */ -void -No_Mem() /* called by alloc package */ +void No_Mem(void) /* called by alloc package */ { fatal("out of memory"); } -void -C_failed() /* called by EM_code module */ +void C_failed(void) /* called by EM_code module */ { fatal("write failed"); } diff --git a/lang/cem/cemcom.ansi/next.str b/lang/cem/cemcom.ansi/next.str new file mode 100644 index 000000000..5dd79564f --- /dev/null +++ b/lang/cem/cemcom.ansi/next.str @@ -0,0 +1 @@ +#include "parameters.h" diff --git a/lang/cem/cemcom.ansi/options.c b/lang/cem/cemcom.ansi/options.c index c0b411934..62864f5b7 100644 --- a/lang/cem/cemcom.ansi/options.c +++ b/lang/cem/cemcom.ansi/options.c @@ -9,12 +9,14 @@ #include #include #include +#include "options.h" #include "class.h" #include "macro.h" #include "idf.h" #include "arith.h" #include "sizes.h" #include "align.h" +#include "error.h" char options[128]; /* one for every char */ #ifdef LINT @@ -24,10 +26,11 @@ char loptions[128]; /* one for every char */ extern int idfsize; extern int density; -static int txt2int(); -do_option(text) - char *text; + +static int txt2int(register char **); + +void do_option(char *text) { register char opt; @@ -209,9 +212,7 @@ next_option: /* to allow combined one-char options */ } } -static int -txt2int(tp) - register char **tp; +static int txt2int(register char **tp) { /* the integer pointed to by *tp is read, while increasing *tp; the resulting value is yielded. diff --git a/lang/cem/cemcom.ansi/options.h b/lang/cem/cemcom.ansi/options.h new file mode 100644 index 000000000..ade29ed88 --- /dev/null +++ b/lang/cem/cemcom.ansi/options.h @@ -0,0 +1,13 @@ +/* Copyright (c) 2019 ACK Project. + * See the copyright notice in the ACK home directory, + * in the file "Copyright". + * + * Created on: 2019-02-07 + * + */ +#ifndef OPTIONS_H_ +#define OPTIONS_H_ + +void do_option(char *text); + +#endif /* OPTIONS_H_ */ diff --git a/lang/cem/cemcom.ansi/pragma.c b/lang/cem/cemcom.ansi/pragma.c index b4198d92b..335cb9263 100644 --- a/lang/cem/cemcom.ansi/pragma.c +++ b/lang/cem/cemcom.ansi/pragma.c @@ -6,37 +6,43 @@ /* PREPROCESSOR: PRAGMA INTERPRETER */ #include "parameters.h" +#include "pragma.h" +#include "skip.h" #define P_UNKNOWN 0 #define NR_PRAGMAS 0 -struct pkey { +struct pkey +{ char *pk_name; int pk_key; -} pragmas[NR_PRAGMAS + 1] = { - {0, P_UNKNOWN} -}; +} pragmas[NR_PRAGMAS + 1] = +{ +{ 0, P_UNKNOWN } }; extern struct idf *GetIdentifier(); -do_pragma() +void do_pragma(void) { #if NR_PRAGMAS register struct pkey *pkp = &pragmas[0]; #endif register struct idf *id = GetIdentifier(1); - if (id != (struct idf *)0) { + if (id != (struct idf *) 0) + { #if NR_PRAGMAS - while(pkp->pk_name) { + while(pkp->pk_name) + { if (strcmp(pkp->pk_name, id->id_text) == 0) - break; + break; pkp++; } - switch (pkp->pk_key) { - case P_UNKNOWN: - default: + switch (pkp->pk_key) + { + case P_UNKNOWN: + default: break; } #endif diff --git a/lang/cem/cemcom.ansi/pragma.h b/lang/cem/cemcom.ansi/pragma.h new file mode 100644 index 000000000..df62ad6c0 --- /dev/null +++ b/lang/cem/cemcom.ansi/pragma.h @@ -0,0 +1,13 @@ +/* Copyright (c) 2019 ACK Project. + * See the copyright notice in the ACK home directory, + * in the file "Copyright". + * + * Created on: 2019-02-07 + * + */ +#ifndef PRAGMA_H_ +#define PRAGMA_H_ + +void do_pragma(void); + +#endif /* PRAGMA_H_ */ diff --git a/lang/cem/cemcom.ansi/program.g b/lang/cem/cemcom.ansi/program.g index 631603cff..616065da5 100644 --- a/lang/cem/cemcom.ansi/program.g +++ b/lang/cem/cemcom.ansi/program.g @@ -1,224 +1,227 @@ -/* - * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. - * See the copyright notice in the ACK home directory, in the file "Copyright". - */ -/* $Id$ */ -/* PROGRAM PARSER */ - -/* The presence of typedef declarations renders it impossible to - make a context-free grammar of C. Consequently we need - context-sensitive parsing techniques, the simplest one being - a subtle cooperation between the parser and the lexical scanner. - The lexical scanner has to know whether to return IDENTIFIER - or TYPE_IDENTIFIER for a given tag, and it obtains this information - from the definition list, as constructed by the parser. - The present grammar is essentially LL(2), and is processed by - a parser generator which accepts LL(1) with tie breaking rules - in C, of the form %if(cond) and %while(cond). To solve the LL(1) - ambiguities, the lexical scanner does a one symbol look-ahead. - This symbol, however, cannot always be correctly assessed, since - the present symbol may cause a change in the definition list - which causes the identification of the look-ahead symbol to be - invalidated. - The lexical scanner relies on the parser (or its routines) to - detect this situation and then update the look-ahead symbol. - An alternative approach would be to reassess the look-ahead symbol - in the lexical scanner when it is promoted to dot symbol. This - would be more beautiful but less correct, since then for a short - while there would be a discrepancy between the look-ahead symbol - and the definition list; I think it would nevertheless work in - correct programs. - A third solution would be to enter the identifier as soon as it - is found; its storage class is then known, although its full type - isn't. We would have to fill that in afterwards. - - At block exit the situation is even worse. Upon reading the - closing brace, the names declared inside the function are cleared - from the name list. This action may expose a type identifier that - is the same as the identifier in the look-ahead symbol. This - situation certainly invalidates the third solution, and casts - doubts upon the second. -*/ - -%lexical LLlex; -%start C_program, program; -%start If_expr, control_if_expression; - -{ -#include "parameters.h" -#include -#include "arith.h" -#include "LLlex.h" -#include "label.h" -#include "type.h" -#include "declar.h" -#include "decspecs.h" -#include "code.h" -#include "expr.h" -#include "def.h" -#include "stack.h" -#ifdef LINT -#include "l_lint.h" -#endif /* LINT */ - -extern error(); -} - -control_if_expression - { - struct expr *exprX; - } -: - constant_expression(&exprX) - { - } -; - -/* 3.7 */ -program: - [%persistent external_definition]* - { unstack_world(); } -; - -/* A C identifier definition is remarkable in that it formulates - the declaration in a way different from most other languages: - e.g., rather than defining x as a pointer-to-integer, it defines - *x as an integer and lets the compiler deduce that x is actually - pointer-to-integer. This has profound consequences, both for the - structure of an identifier definition and for the compiler. - - A definition starts with a decl_specifiers, which contains things - like - typedef int - which is implicitly repeated for every definition in the list, and - then for each identifier a declarator is given, of the form - *a() - or so. The decl_specifiers is kept in a struct decspecs, to be - used again and again, while the declarator is stored in a struct - declarator, only to be passed to declare_idf together with the - struct decspecs. - - With the introduction of prototypes, extra problems for the scope - administration were introduced as well. We can have, for example, - int x(double x); - and - int x(double x) { ... use(x) ... } - In the first case, the parameter name can be forgotten, whereas in - the second case, the parameter should have a block scope. The - problem lies in the fact that the parameter's type is known before - the type of the function, which causes the def structure to be on - the end of the list. Our solution is as follows: - 1- In case of a declaration, throw the parameter identifier away - before the declaration of the outer x. - 2- In case of a definition, the function begin_proc() changes the - def list for the identifier. This means that declare_idf() - contains an extra test in case we already saw a declaration of - such a function, because this function is called before - begin_proc(). -*/ - -external_definition - { struct decspecs Ds; - struct declarator Dc; - } -: - { Ds = null_decspecs; - Dc = null_declarator; - } - [ %if (DOT != IDENTIFIER || AHEAD == IDENTIFIER) - decl_specifiers(&Ds) - | - {do_decspecs(&Ds);} - ] - [ - declarator(&Dc) - { - declare_idf(&Ds, &Dc, level); -#ifdef LINT - lint_ext_def(Dc.dc_idf, Ds.ds_sc); -#endif /* LINT */ - } - [ - function(&Ds, &Dc) - | - { if (! Ds.ds_sc_given && ! Ds.ds_typequal && - Ds.ds_notypegiven) { - strict("declaration specifiers missing"); - } - } - non_function(&Ds, &Dc) - ] - | - { if (! Ds.ds_sc_given && ! Ds.ds_typequal && - Ds.ds_notypegiven) { - strict("declaration missing"); - } - } - ';' - ] - {remove_declarator(&Dc); flush_strings(); } -; - -non_function(register struct decspecs *ds; register struct declarator *dc;) -: - { reject_params(dc); - } - [ - initializer(dc->dc_idf, ds->ds_sc) - | - { code_declaration(dc->dc_idf, (struct expr *) 0, level, ds->ds_sc); } - ] - { -#ifdef LINT - lint_non_function_decl(ds, dc); -#endif /* LINT */ - } - [ - ',' - init_declarator(ds) - ]* - ';' -; - -/* 3.7.1 */ -function(struct decspecs *ds; struct declarator *dc;) - { - arith fbytes; - register struct idf *idf = dc->dc_idf; - } -: - { -#ifdef LINT - lint_start_function(); -#endif /* LINT */ - idf_initialized(idf); - stack_level(); /* L_FORMAL1 declarations */ - declare_params(dc); - begin_proc(ds, idf); /* sets global function info */ - stack_level(); /* L_FORMAL2 declarations */ - declare_protos(dc); - } - declaration* - { - check_formals(idf, dc); /* check style-mixtures */ - declare_formals(idf, &fbytes); -#ifdef LINT - lint_formals(); -#endif /* LINT */ - } - compound_statement - { - end_proc(fbytes); -#ifdef LINT - lint_implicit_return(); -#endif /* LINT */ - unstack_level(); /* L_FORMAL2 declarations */ -#ifdef LINT - lint_end_formals(); -#endif /* LINT */ - unstack_level(); /* L_FORMAL1 declarations */ -#ifdef LINT - lint_end_function(); -#endif /* LINT */ - } -; +/* + * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. + * See the copyright notice in the ACK home directory, in the file "Copyright". + */ +/* $Id$ */ +/* PROGRAM PARSER */ + +/* The presence of typedef declarations renders it impossible to + make a context-free grammar of C. Consequently we need + context-sensitive parsing techniques, the simplest one being + a subtle cooperation between the parser and the lexical scanner. + The lexical scanner has to know whether to return IDENTIFIER + or TYPE_IDENTIFIER for a given tag, and it obtains this information + from the definition list, as constructed by the parser. + The present grammar is essentially LL(2), and is processed by + a parser generator which accepts LL(1) with tie breaking rules + in C, of the form %if(cond) and %while(cond). To solve the LL(1) + ambiguities, the lexical scanner does a one symbol look-ahead. + This symbol, however, cannot always be correctly assessed, since + the present symbol may cause a change in the definition list + which causes the identification of the look-ahead symbol to be + invalidated. + The lexical scanner relies on the parser (or its routines) to + detect this situation and then update the look-ahead symbol. + An alternative approach would be to reassess the look-ahead symbol + in the lexical scanner when it is promoted to dot symbol. This + would be more beautiful but less correct, since then for a short + while there would be a discrepancy between the look-ahead symbol + and the definition list; I think it would nevertheless work in + correct programs. + A third solution would be to enter the identifier as soon as it + is found; its storage class is then known, although its full type + isn't. We would have to fill that in afterwards. + + At block exit the situation is even worse. Upon reading the + closing brace, the names declared inside the function are cleared + from the name list. This action may expose a type identifier that + is the same as the identifier in the look-ahead symbol. This + situation certainly invalidates the third solution, and casts + doubts upon the second. +*/ + +%lexical LLlex; +%start C_program, program; +%start If_expr, control_if_expression; + +{ +#include "parameters.h" +#include +#include "arith.h" +#include "LLlex.h" +#include "label.h" +#include "type.h" +#include "declar.h" +#include "decspecs.h" +#include "code.h" +#include "expr.h" +#include "def.h" +#include "idf.h" +#include "declarator.h" +#include "stack.h" +#include "proto.h" +#include "error.h" +#ifdef LINT +#include "l_lint.h" +#endif /* LINT */ + +} + +control_if_expression + { + struct expr *exprX; + } +: + constant_expression(&exprX) + { + } +; + +/* 3.7 */ +program: + [%persistent external_definition]* + { unstack_world(); } +; + +/* A C identifier definition is remarkable in that it formulates + the declaration in a way different from most other languages: + e.g., rather than defining x as a pointer-to-integer, it defines + *x as an integer and lets the compiler deduce that x is actually + pointer-to-integer. This has profound consequences, both for the + structure of an identifier definition and for the compiler. + + A definition starts with a decl_specifiers, which contains things + like + typedef int + which is implicitly repeated for every definition in the list, and + then for each identifier a declarator is given, of the form + *a() + or so. The decl_specifiers is kept in a struct decspecs, to be + used again and again, while the declarator is stored in a struct + declarator, only to be passed to declare_idf together with the + struct decspecs. + + With the introduction of prototypes, extra problems for the scope + administration were introduced as well. We can have, for example, + int x(double x); + and + int x(double x) { ... use(x) ... } + In the first case, the parameter name can be forgotten, whereas in + the second case, the parameter should have a block scope. The + problem lies in the fact that the parameter's type is known before + the type of the function, which causes the def structure to be on + the end of the list. Our solution is as follows: + 1- In case of a declaration, throw the parameter identifier away + before the declaration of the outer x. + 2- In case of a definition, the function begin_proc() changes the + def list for the identifier. This means that declare_idf() + contains an extra test in case we already saw a declaration of + such a function, because this function is called before + begin_proc(). +*/ + +external_definition + { struct decspecs Ds; + struct declarator Dc; + } +: + { Ds = null_decspecs; + Dc = null_declarator; + } + [ %if (DOT != IDENTIFIER || AHEAD == IDENTIFIER) + decl_specifiers(&Ds) + | + {do_decspecs(&Ds);} + ] + [ + declarator(&Dc) + { + declare_idf(&Ds, &Dc, level); +#ifdef LINT + lint_ext_def(Dc.dc_idf, Ds.ds_sc); +#endif /* LINT */ + } + [ + function(&Ds, &Dc) + | + { if (! Ds.ds_sc_given && ! Ds.ds_typequal && + Ds.ds_notypegiven) { + strict("declaration specifiers missing"); + } + } + non_function(&Ds, &Dc) + ] + | + { if (! Ds.ds_sc_given && ! Ds.ds_typequal && + Ds.ds_notypegiven) { + strict("declaration missing"); + } + } + ';' + ] + {remove_declarator(&Dc); flush_strings(); } +; + +non_function(register struct decspecs *ds; register struct declarator *dc;) +: + { reject_params(dc); + } + [ + initializer(dc->dc_idf, ds->ds_sc) + | + { code_declaration(dc->dc_idf, (struct expr *) 0, level, ds->ds_sc); } + ] + { +#ifdef LINT + lint_non_function_decl(ds, dc); +#endif /* LINT */ + } + [ + ',' + init_declarator(ds) + ]* + ';' +; + +/* 3.7.1 */ +function(struct decspecs *ds; struct declarator *dc;) + { + arith fbytes; + register struct idf *idf = dc->dc_idf; + } +: + { +#ifdef LINT + lint_start_function(); +#endif /* LINT */ + idf_initialized(idf); + stack_level(); /* L_FORMAL1 declarations */ + declare_params(dc); + begin_proc(ds, idf); /* sets global function info */ + stack_level(); /* L_FORMAL2 declarations */ + declare_protos(dc); + } + declaration* + { + check_formals(idf, dc); /* check style-mixtures */ + declare_formals(idf, &fbytes); +#ifdef LINT + lint_formals(); +#endif /* LINT */ + } + compound_statement + { + end_proc(fbytes); +#ifdef LINT + lint_implicit_return(); +#endif /* LINT */ + unstack_level(); /* L_FORMAL2 declarations */ +#ifdef LINT + lint_end_formals(); +#endif /* LINT */ + unstack_level(); /* L_FORMAL1 declarations */ +#ifdef LINT + lint_end_function(); +#endif /* LINT */ + } +; diff --git a/lang/cem/cemcom.ansi/proto.c b/lang/cem/cemcom.ansi/proto.c index ff99ba98c..a9812b196 100644 --- a/lang/cem/cemcom.ansi/proto.c +++ b/lang/cem/cemcom.ansi/proto.c @@ -23,20 +23,24 @@ #include "declar.h" #include "decspecs.h" #include "proto.h" +#include "error.h" +#include "ch3.h" extern char options[]; -void -check_for_void(pl) - register struct proto *pl; +void check_for_void(register struct proto *pl) { register int errcnt = 0; - if (!pl) return; - if ((pl->pl_flag & PL_VOID) && !(pl->next)) return; + if (!pl) + return; + if ((pl->pl_flag & PL_VOID) && !(pl->next)) + return; - while (pl) { - if (pl->pl_flag & PL_VOID) { + while (pl) + { + if (pl->pl_flag & PL_VOID) + { if (!errcnt && !(pl->pl_flag & PL_ERRGIVEN)) error("illegal use of void in argument list"); pl->pl_flag |= PL_ERRGIVEN; @@ -46,37 +50,35 @@ check_for_void(pl) } } -add_proto(pl, ds, dc, lvl) - struct proto *pl; - struct decspecs *ds; - struct declarator *dc; - int lvl; +void add_proto(struct proto *pl, struct decspecs *ds, struct declarator *dc, + int lvl) { /* The full typed identifier or abstract type, described - by the structures decspecs and declarator are turned - a into parameter type list structure. - The parameters will be declared at level L_FORMAL2, - later on it's decided whether they were prototypes - or actual declarations. - */ + by the structures decspecs and declarator are turned + a into parameter type list structure. + The parameters will be declared at level L_FORMAL2, + later on it's decided whether they were prototypes + or actual declarations. + */ register struct idf *idf = dc->dc_idf; - register struct def *def = idf ? idf->id_def : (struct def *)0; + register struct def *def = idf ? idf->id_def : (struct def *) 0; register int sc = ds->ds_sc; register struct type *type; char formal_array = 0; - assert(ds->ds_type != (struct type *)0); + assert(ds->ds_type != (struct type * )0); pl->pl_flag = PL_FORMAL; type = declare_type(ds->ds_type, dc); - if (type->tp_size < (arith)0 && actual_declaration(sc, type)) { + if (type->tp_size < (arith) 0 && actual_declaration(sc, type)) + { extern char *symbol2str(); if (type->tp_fund != VOID) error("unknown %s-type", symbol2str(type->tp_fund)); - else { - if (idf != (struct idf *)0 - || ds->ds_sc_given - || ds->ds_typequal) { + else + { + if (idf != (struct idf *) 0 || ds->ds_sc_given || ds->ds_typequal) + { error("illegal use of void in argument list"); pl->pl_flag |= PL_ERRGIVEN; } @@ -84,43 +86,54 @@ add_proto(pl, ds, dc, lvl) pl->pl_flag |= PL_VOID; } } - if (ds->ds_sc_given && ds->ds_sc != REGISTER) { - if (!(pl->pl_flag & PL_ERRGIVEN)) { - if (ds->ds_sc != AUTO) { - error("illegal storage class in parameter declaration"); - } else { - warning("illegal storage class in parameter declaration"); - } + if (ds->ds_sc_given && ds->ds_sc != REGISTER) + { + if (!(pl->pl_flag & PL_ERRGIVEN)) + { + if (ds->ds_sc != AUTO) + { + error("illegal storage class in parameter declaration"); + } + else + { + warning("illegal storage class in parameter declaration"); + } } } /* Perform some special conversions for parameters. - */ - if (type->tp_fund == FUNCTION) { + */ + if (type->tp_fund == FUNCTION) + { type = construct_type(POINTER, type, 0, (arith) 0, NO_PROTO); - } else if (type->tp_fund == ARRAY) { + } + else if (type->tp_fund == ARRAY) + { type = construct_type(POINTER, type->tp_up, 0, (arith) 0, NO_PROTO); formal_array = 1; } /* According to the standard we should ignore the storage - class of a parameter, unless it's part of a function - definition. - However, in the routine declare_protos we don't know decspecs, - and therefore we can't complain up there. So we build up the - storage class, and keep quiet until we reach declare_protos. - */ - sc = (ds->ds_sc_given && ds->ds_sc != REGISTER) ? - 0 : sc == 0 ? FORMAL : REGISTER; + class of a parameter, unless it's part of a function + definition. + However, in the routine declare_protos we don't know decspecs, + and therefore we can't complain up there. So we build up the + storage class, and keep quiet until we reach declare_protos. + */ + sc = (ds->ds_sc_given && ds->ds_sc != REGISTER) ? 0 : + sc == 0 ? FORMAL : REGISTER; - if (def && (def->df_level == lvl /* || def->df_level < L_PROTO */ )) { + if (def && (def->df_level == lvl /* || def->df_level < L_PROTO */)) + { /* redeclaration at the same level */ error("parameter %s redeclared", idf->id_text); - } else if (idf != (struct idf *)0) { + } + else if (idf != (struct idf *) 0) + { /* New definition, redefinition hides earlier one - */ + */ register struct def *newdef = new_def(); - + newdef->next = def; newdef->df_level = lvl; newdef->df_sc = sc; @@ -133,28 +146,28 @@ add_proto(pl, ds, dc, lvl) /* newdef->df_firstbrace = 0; */ #endif /* We can't put the idf onto the stack, since these kinds - of declaration may occurs at any level, and the idf - does not necessarily go at this level. E.g. + of declaration may occurs at any level, and the idf + does not necessarily go at this level. E.g. - f() { - ... - { int func(int a, int b); - ... - } - } + f() { + ... + { int func(int a, int b); + ... + } + } - The idf's a and b declared in the prototype declaration - do not go at any level, they are simply ignored. - However, in + The idf's a and b declared in the prototype declaration + do not go at any level, they are simply ignored. + However, in - f(int a, int b) { - ... - } + f(int a, int b) { + ... + } - They should go at level L_FORMAL2. But at this stage - we don't know whether we have a prototype or function - definition. So, this process is postponed. - */ + They should go at level L_FORMAL2. But at this stage + we don't know whether we have a prototype or function + definition. So, this process is postponed. + */ idf->id_def = newdef; update_ahead(idf); } @@ -163,35 +176,33 @@ add_proto(pl, ds, dc, lvl) pl->pl_type = type; } -struct tag * -gettag(tp, idpp) -struct type *tp; -struct idf **idpp; +static struct tag * gettag(struct type *tp, struct idf **idpp) { - struct tag *tg = (struct tag *)0; + struct tag *tg = (struct tag *) 0; register int fund = tp->tp_fund; - while (fund == FIELD || fund == POINTER - || fund == ARRAY || fund == FUNCTION) { - tp = tp->tp_up; - fund = tp->tp_fund; - } + while (fund == FIELD || fund == POINTER || fund == ARRAY || fund == FUNCTION) + { + tp = tp->tp_up; + fund = tp->tp_fund; + } *idpp = tp->tp_idf; - switch(tp->tp_fund) { + switch (tp->tp_fund) + { case ENUM: case UNION: - case STRUCT: tg = tp->tp_idf->id_tag; break; + case STRUCT: + tg = tp->tp_idf->id_tag; + break; } return tg; } - -declare_protos(dc) - register struct declarator *dc; +void declare_protos(register struct declarator *dc) { /* At this points we know that the idf's in protolist are formal - parameters. So it's time to declare them at level L_FORMAL2. - */ + parameters. So it's time to declare them at level L_FORMAL2. + */ struct stack_level *stl = stack_level_of(L_FORMAL1); register struct decl_unary *du; register struct type *type; @@ -200,31 +211,39 @@ declare_protos(dc) #ifdef DEBUG if (options['t']) - dumpidftab("start declare_protos", 0); + dumpidftab("start declare_protos", 0); #endif /* DEBUG */ du = dc->dc_decl_unary; - while (du) { - if (du->du_fund == FUNCTION) { - if (du->next != (struct decl_unary *) 0) { + while (du) + { + if (du->du_fund == FUNCTION) + { + if (du->next != (struct decl_unary *) 0) + { remove_proto_idfs(du->du_proto); du->du_proto = 0; - } else break; + } + else + break; } du = du->next; } pl = du ? du->du_proto : NO_PROTO; - if (pl) { + if (pl) + { #if 0 /* the id_proto member is deleted (???) */ idf->id_proto = 0; #endif /* 0 */ - do { + do + { struct tag *tg; struct idf *idp = 0; type = pl->pl_type; /* `...' only for type checking */ - if (pl->pl_flag & PL_ELLIPSIS) { + if (pl->pl_flag & PL_ELLIPSIS) + { pl = pl->next; continue; } @@ -233,14 +252,15 @@ declare_protos(dc) if (type->tp_fund == VOID) break; - if (!pl->pl_idf || !(def = pl->pl_idf->id_def)) { + if (!pl->pl_idf || !(def = pl->pl_idf->id_def)) + { error("no parameter identifier supplied"); pl = pl->next; continue; } /* Postponed storage class checking. - */ + */ if (def->df_sc == 0) error("illegal storage class in parameter declaration"); @@ -249,7 +269,8 @@ declare_protos(dc) pl = pl->next; tg = gettag(type, &idp); - if (tg && tg->tg_level <= L_PROTO) { + if (tg && tg->tg_level <= L_PROTO) + { tg->tg_level = L_FORMAL2; stack_idf(idp, stl); } @@ -257,43 +278,47 @@ declare_protos(dc) } #ifdef DEBUG if (options['t']) - dumpidftab("end declare_protos", 0); + dumpidftab("end declare_protos", 0); #endif /* DEBUG */ } - -void -update_proto(tp, otp) - register struct type *tp, *otp; +void update_proto(register struct type *tp, register struct type *otp) { /* This routine performs the proto type updates. - Consider the following code: + Consider the following code: - int f(double g()); - int f(double g(int f(), int)); - int f(double g(int f(long double), int)); + int f(double g()); + int f(double g(int f(), int)); + int f(double g(int f(long double), int)); - The most accurate definition is the third line. - This routine will silently update all lists, - and removes the redundant occupied space. - */ + The most accurate definition is the third line. + This routine will silently update all lists, + and removes the redundant occupied space. + */ register struct proto *pl, *opl; - if (tp == otp) return; - if (!tp || !otp) return; + if (tp == otp) + return; + if (!tp || !otp) + return; - while (tp->tp_fund != FUNCTION) { - if (tp->tp_fund != POINTER && tp->tp_fund != ARRAY) return; + while (tp->tp_fund != FUNCTION) + { + if (tp->tp_fund != POINTER && tp->tp_fund != ARRAY) + return; tp = tp->tp_up; otp = otp->tp_up; - if (!tp) return; + if (!tp) + return; } pl = tp->tp_proto; opl = otp->tp_proto; - if (pl && opl) { + if (pl && opl) + { /* both have prototypes */ - while (pl && opl) { + while (pl && opl) + { update_proto(pl->pl_type, opl->pl_type); pl = pl->next; opl = opl->next; @@ -302,9 +327,13 @@ update_proto(tp, otp) * a typedef. */ otp->tp_proto = tp->tp_proto; - } else if (opl) { + } + else if (opl) + { /* old decl has type */ - } else if (pl) { + } + else if (pl) + { otp->tp_proto = pl; } @@ -314,39 +343,44 @@ update_proto(tp, otp) /* struct/union and enum tags can be declared inside prototypes * remove them from the symbol-table */ -void -remove_proto_tag(tp) -struct type *tp; +static void remove_proto_tag(struct type *tp) { register struct idf *ident; register struct tag *tgp, **tgpp; register int fund = tp->tp_fund; - while (fund == FIELD || fund == POINTER - || fund == ARRAY || fund == FUNCTION) { + while (fund == FIELD || fund == POINTER || fund == ARRAY || fund == FUNCTION) + { tp = tp->tp_up; fund = tp->tp_fund; } ident = tp->tp_idf; - switch (tp->tp_fund) { + switch (tp->tp_fund) + { case ENUM: case STRUCT: - case UNION: tgpp = &(ident->id_tag); break; - default: return; + case UNION: + tgpp = &(ident->id_tag); + break; + default: + return; } - while((*tgpp) && (*tgpp)->tg_type != tp) { + while ((*tgpp) && (*tgpp)->tg_type != tp) + { tgpp = &((*tgpp)->next); } - if (!*tgpp) return; + if (!*tgpp) + return; tgp = *tgpp; - if (tgp->tg_level > L_PROTO) return; + if (tgp->tg_level > L_PROTO) + return; #ifdef DEBUG if (options['t']) - print("Removing idf %s from list\n", + print("Removing idf %s from list\n", ident->id_text); #endif @@ -354,52 +388,55 @@ struct type *tp; free_tag(tgp); } -remove_proto_idfs(pl) - register struct proto *pl; +/* Remove all the identifier definitions from the + prototype list. */ +void remove_proto_idfs(register struct proto *pl) { - /* Remove all the identifier definitions from the - prototype list. - */ + register struct def *def; - while (pl) { - if (pl->pl_idf) { + while (pl) + { + if (pl->pl_idf) + { #ifdef DEBUG if (options['t']) - print("Removing idf %s from list\n", + print("Removing idf %s from list\n", pl->pl_idf->id_text); #endif def = pl->pl_idf->id_def; - if (def && def->df_level <= L_PROTO) { + if (def && def->df_level <= L_PROTO) + { pl->pl_idf->id_def = def->next; free_def(def); } pl->pl_idf = (struct idf *) 0; } - if (pl->pl_type) { + if (pl->pl_type) + { remove_proto_tag(pl->pl_type); } pl = pl->next; } } -void -call_proto(expp) - register struct expr **expp; +void call_proto(register struct expr **expp) { /* If the function specified by (*expp)->OP_LEFT has a prototype, - the parameters are converted according the rules specified in - par. 3.3.2.2. E.i. the parameters are converted to the prototype - counter parts as if by assignment. For the parameters falling - under ellipsis clause the old parameters conversion stuff - applies. - */ + the parameters are converted according the rules specified in + par. 3.3.2.2. E.i. the parameters are converted to the prototype + counter parts as if by assignment. For the parameters falling + under ellipsis clause the old parameters conversion stuff + applies. + */ register struct expr *left = (*expp)->OP_LEFT; register struct expr *right = (*expp)->OP_RIGHT; register struct proto *pl = NO_PROTO; - static struct proto ellipsis = { 0, 0, 0, PL_ELLIPSIS }; + static struct proto ellipsis = + { 0, 0, 0, PL_ELLIPSIS }; - if (left != NILEXPR) { /* in case of an error */ + if (left != NILEXPR) + { /* in case of an error */ register struct type *tp = left->ex_type; while (tp && tp->tp_fund != FUNCTION && tp != error_type) @@ -408,17 +445,20 @@ call_proto(expp) pl = tp->tp_proto; } - if (right != NILEXPR) { /* function call with parameters */ + if (right != NILEXPR) + { /* function call with parameters */ register struct expr **ep = &((*expp)->OP_RIGHT); register int ecnt = 0, pcnt = 0; struct expr **estack[NPARAMS]; struct proto *pstack[NPARAMS]; /* stack up the parameter expressions */ - while (right->ex_class == Oper && right->OP_OPER == PARCOMMA) { + while (right->ex_class == Oper && right->OP_OPER == PARCOMMA) + { if (ecnt == STDC_NPARAMS) expr_strict(right, "number of parameters exceeds ANSI limit"); - if (ecnt >= NPARAMS-1) { + if (ecnt >= NPARAMS - 1) + { expr_error(right, "too many parameters"); return; } @@ -429,45 +469,56 @@ call_proto(expp) estack[ecnt] = ep; /* Declarations like int f(void) do not expect any - parameters. - */ - if (pl && pl->pl_flag & PL_VOID) { + parameters. + */ + if (pl && pl->pl_flag & PL_VOID) + { expr_strict(*expp, "no parameters expected"); pl = NO_PROTO; } /* stack up the prototypes */ - if (pl) { + if (pl) + { pcnt--; - do { + do + { /* stack prototypes */ pstack[++pcnt] = pl; pl = pl->next; } while (pl); } - else { + else + { pstack[0] = &ellipsis; } - for (ecnt; ecnt >= 0; ecnt--) { + for (ecnt; ecnt >= 0; ecnt--) + { /* Only the parameters specified in the prototype - are checked and converted. The parameters that - fall under the ellipsis clause are neither - checked nor converted ! - */ - if (pcnt < 0) { - expr_error(*expp, "more parameters than specified in prototype"); + are checked and converted. The parameters that + fall under the ellipsis clause are neither + checked nor converted ! + */ + if (pcnt < 0) + { + expr_error(*expp, + "more parameters than specified in prototype"); break; } - else if (!(pstack[pcnt]->pl_flag & PL_ELLIPSIS)) { - ch3cast(estack[ecnt],CASTAB,pstack[pcnt]->pl_type); + else if (!(pstack[pcnt]->pl_flag & PL_ELLIPSIS)) + { + ch3cast(estack[ecnt], CASTAB, pstack[pcnt]->pl_type); pcnt--; - } else + } + else any2parameter(estack[ecnt]); } if (pcnt > 0 || (pcnt == 0 && !(pstack[0]->pl_flag & PL_ELLIPSIS))) expr_error(*expp, "fewer parameters than specified in prototype"); - } else { + } + else + { if (pl && !(pl->pl_flag & PL_VOID)) expr_error(*expp, "fewer parameters than specified in prototype"); } diff --git a/lang/cem/cemcom.ansi/proto.str b/lang/cem/cemcom.ansi/proto.str index 03219deee..690588265 100644 --- a/lang/cem/cemcom.ansi/proto.str +++ b/lang/cem/cemcom.ansi/proto.str @@ -2,6 +2,9 @@ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * See the copyright notice in the ACK home directory, in the file "Copyright". */ +#ifndef PROTO_H +#define PROTO_H + /* $Id$ */ /* PARAMETER TYPE LIST DEFINITION */ @@ -20,3 +23,20 @@ struct proto { #define PL_ERRGIVEN 0x08 /* ALLOCDEF "proto" 20 */ + +/* Forward structure declarations */ +struct expr; +struct type; +struct declarator; +struct decspecs; + + +void remove_proto_idfs(register struct proto *pl); +void call_proto(register struct expr **expp); +void update_proto(register struct type *tp, register struct type *otp); +void declare_protos(register struct declarator *dc); +void add_proto(struct proto *pl, struct decspecs *ds, struct declarator *dc, + int lvl); +void check_for_void(register struct proto *pl); + +#endif diff --git a/lang/cem/cemcom.ansi/skip.c b/lang/cem/cemcom.ansi/skip.c index b617f08e9..8dd6ee837 100644 --- a/lang/cem/cemcom.ansi/skip.c +++ b/lang/cem/cemcom.ansi/skip.c @@ -10,9 +10,10 @@ #include "LLlex.h" #include "class.h" #include "input.h" +#include "skip.h" -SkipToNewLine() +int SkipToNewLine(void) { register int ch; register int garbage = 0; diff --git a/lang/cem/cemcom.ansi/skip.h b/lang/cem/cemcom.ansi/skip.h new file mode 100644 index 000000000..52ef8cbda --- /dev/null +++ b/lang/cem/cemcom.ansi/skip.h @@ -0,0 +1,13 @@ +/* Copyright (c) 2019 ACK Project. + * See the copyright notice in the ACK home directory, + * in the file "Copyright". + * + * Created on: 2019-02-07 + * + */ +#ifndef SKIP_H_ +#define SKIP_H_ + +int SkipToNewLine(void); + +#endif /* SKIP_H_ */ diff --git a/lang/cem/cemcom.ansi/stab.c b/lang/cem/cemcom.ansi/stab.c index f80b360b4..a7a7928c9 100644 --- a/lang/cem/cemcom.ansi/stab.c +++ b/lang/cem/cemcom.ansi/stab.c @@ -20,6 +20,7 @@ #include #include +#include "stab.h" #include "idf.h" #include "LLlex.h" #include "stack.h" @@ -29,34 +30,34 @@ #include "field.h" #include "Lpars.h" #include "level.h" +#include "print.h" -extern long full_mask[]; -extern char *sprint(); +extern long full_mask[]; #define INCR_SIZE 64 -static struct db_str { - unsigned sz; - char *base; - char *currpos; +static struct db_str +{ + unsigned sz; + char *base; + char *currpos; } db_str; -static -create_db_str() +static void create_db_str(void) { - if (! db_str.base) { + if (!db_str.base) + { db_str.base = Malloc(INCR_SIZE); db_str.sz = INCR_SIZE; } db_str.currpos = db_str.base; } -static -addc_db_str(c) - int c; +static void addc_db_str(int c) { int df = db_str.currpos - db_str.base; - if (df >= db_str.sz-1) { + if (df >= db_str.sz - 1) + { db_str.sz += INCR_SIZE; db_str.base = Realloc(db_str.base, db_str.sz); db_str.currpos = db_str.base + df; @@ -65,34 +66,35 @@ addc_db_str(c) *db_str.currpos = '\0'; } -static -adds_db_str(s) - char *s; +static void adds_db_str(char *s) { - while (*s) addc_db_str(*s++); + while (*s) + addc_db_str(*s++); } -static void -stb_type(tp) - register struct type *tp; +static void stb_type(register struct type *tp) { - char buf[128]; - static int stb_count; - long l; + char buf[128]; + static int stb_count; + long l; - if (tp->tp_dbindex > 0) { + if (tp->tp_dbindex > 0) + { adds_db_str(sprint(buf, "%d", tp->tp_dbindex)); return; } - if (tp->tp_dbindex < 0 && tp->tp_size < 0) { + if (tp->tp_dbindex < 0 && tp->tp_size < 0) + { adds_db_str(sprint(buf, "%d", -tp->tp_dbindex)); return; } - if (tp->tp_dbindex <= 0) { + if (tp->tp_dbindex <= 0) + { tp->tp_dbindex = ++stb_count; } adds_db_str(sprint(buf, "%d=", tp->tp_dbindex)); - switch(tp->tp_fund) { + switch (tp->tp_fund) + { /* simple types ... */ case VOID: adds_db_str(sprint(buf, "%d", void_type->tp_dbindex)); @@ -101,49 +103,44 @@ stb_type(tp) case LONG: case CHAR: case SHORT: - l = full_mask[(int)tp->tp_size]; - if (tp->tp_unsigned) { - adds_db_str(sprint(buf, - "r%d;0;%ld", - tp->tp_dbindex, - l)); + l = full_mask[(int) tp->tp_size]; + if (tp->tp_unsigned) + { + adds_db_str(sprint(buf, "r%d;0;%ld", tp->tp_dbindex, l)); } - else { - l &= ~ (1L << ((int)tp->tp_size * 8 - 1)); - adds_db_str(sprint(buf, - "r%d;%ld;%ld", - tp->tp_dbindex, - -l-1, - l)); + else + { + l &= ~(1L << ((int) tp->tp_size * 8 - 1)); + adds_db_str(sprint(buf, "r%d;%ld;%ld", tp->tp_dbindex, -l - 1, l)); } break; case FLOAT: case DOUBLE: case LNGDBL: - adds_db_str(sprint(buf, - "r%d;%ld;0", - tp->tp_dbindex, - (long)tp->tp_size)); + adds_db_str( + sprint(buf, "r%d;%ld;0", tp->tp_dbindex, (long) tp->tp_size)); break; - /* constructed types ... */ + /* constructed types ... */ case POINTER: addc_db_str('*'); stb_type(tp->tp_up); break; case ARRAY: - if (tp->tp_size > 0) { + if (tp->tp_size > 0) + { adds_db_str("ar"); stb_type(int_type); - adds_db_str(sprint(buf, ";0;%ld;", tp->tp_size / tp->tp_up->tp_size - 1)); + adds_db_str( + sprint(buf, ";0;%ld;", + tp->tp_size / tp->tp_up->tp_size - 1)); stb_type(tp->tp_up); } break; case ENUM: - if (tp->tp_size < 0) { - adds_db_str(sprint(buf, - "xe%s:", - tp->tp_idf->id_text)); + if (tp->tp_size < 0) + { + adds_db_str(sprint(buf, "xe%s:", tp->tp_idf->id_text)); tp->tp_dbindex = -tp->tp_dbindex; break; } @@ -151,15 +148,16 @@ stb_type(tp) { register struct stack_entry *se = local_level->sl_entry; - while (se) { - register struct def *edef = se->se_idf->id_def; - while (edef) { - if (edef->df_type == tp && - edef->df_sc == ENUM) { - adds_db_str(sprint(buf, - "%s:%ld,", - se->se_idf->id_text, - edef->df_address)); + while (se) + { + register struct def *edef = se->se_idf->id_def; + while (edef) + { + if (edef->df_type == tp && edef->df_sc == ENUM) + { + adds_db_str( + sprint(buf, "%s:%ld,", se->se_idf->id_text, + edef->df_address)); } edef = edef->next; } @@ -170,37 +168,39 @@ stb_type(tp) break; case STRUCT: case UNION: - if (tp->tp_size < 0) { - adds_db_str(sprint(buf, - "x%c%s:", - tp->tp_fund == STRUCT ? 's' : 'u', - tp->tp_idf->id_text)); + if (tp->tp_size < 0) + { + adds_db_str( + sprint(buf, "x%c%s:", tp->tp_fund == STRUCT ? 's' : 'u', + tp->tp_idf->id_text)); tp->tp_dbindex = -tp->tp_dbindex; break; } - adds_db_str(sprint(buf, - "%c%ld", - tp->tp_fund == STRUCT ? 's' : 'u', - tp->tp_size)); + adds_db_str( + sprint(buf, "%c%ld", tp->tp_fund == STRUCT ? 's' : 'u', + tp->tp_size)); { - register struct sdef *sdef = tp->tp_sdef; + register struct sdef *sdef = tp->tp_sdef; - while (sdef) { + while (sdef) + { adds_db_str(sdef->sd_idf->id_text); addc_db_str(':'); - if (sdef->sd_type->tp_fund == FIELD) { + if (sdef->sd_type->tp_fund == FIELD) + { stb_type(sdef->sd_type->tp_up); - adds_db_str(sprint(buf, - ",%ld,%ld;", - sdef->sd_offset*8+sdef->sd_type->tp_field->fd_shift, - sdef->sd_type->tp_field->fd_width)); + adds_db_str( + sprint(buf, ",%ld,%ld;", + sdef->sd_offset * 8 + + sdef->sd_type->tp_field->fd_shift, + sdef->sd_type->tp_field->fd_width)); } - else { + else + { stb_type(sdef->sd_type); - adds_db_str(sprint(buf, - ",%ld,%ld;", - sdef->sd_offset*8, - sdef->sd_type->tp_size*8)); + adds_db_str( + sprint(buf, ",%ld,%ld;", sdef->sd_offset * 8, + sdef->sd_type->tp_size * 8)); } sdef = sdef->sd_sdef; } @@ -213,9 +213,7 @@ stb_type(tp) } } -stb_tag(tg, str) - register struct tag *tg; - char *str; +void stb_tag(register struct tag *tg, char *str) { create_db_str(); adds_db_str(str); @@ -223,16 +221,12 @@ stb_tag(tg, str) stb_type(tg->tg_type); addc_db_str(';'); C_ms_stb_cst(db_str.base, - N_LSYM, - tg->tg_type == void_type || tg->tg_type->tp_size >= 32767 - ? 0 - : (int)tg->tg_type->tp_size, - (arith) 0); + N_LSYM, + tg->tg_type == void_type || tg->tg_type->tp_size >= 32767 ? + 0 : (int) tg->tg_type->tp_size, (arith) 0); } -stb_typedef(tp, str) - register struct type *tp; - char *str; +void stb_typedef(register struct type *tp, char *str) { create_db_str(); adds_db_str(str); @@ -240,23 +234,19 @@ stb_typedef(tp, str) stb_type(tp); addc_db_str(';'); C_ms_stb_cst(db_str.base, - N_LSYM, - tp == void_type || tp->tp_size >= 32767 - ? 0 - : (int)tp->tp_size, - (arith) 0); + N_LSYM, tp == void_type || tp->tp_size >= 32767 ? 0 : (int) tp->tp_size, + (arith) 0); } -stb_string(df, kind, str) - register struct def *df; - char *str; +void stb_string(register struct def *df, int kind, char* str) { - register struct type *tp = df->df_type; + register struct type *tp = df->df_type; create_db_str(); adds_db_str(str); addc_db_str(':'); - switch(kind) { + switch (kind) + { case FUNCTION: addc_db_str(df->df_sc == STATIC ? 'f' : 'F'); stb_type(tp->tp_up); @@ -264,40 +254,50 @@ stb_string(df, kind, str) C_ms_stb_pnam(db_str.base, N_FUN, 1 /* proclevel */, str); break; default: - if (df->df_sc == FORMAL || - (df->df_sc == REGISTER && df->df_address >= 0)) { - /* value parameter */ + if (df->df_sc == FORMAL + || (df->df_sc == REGISTER && df->df_address >= 0)) + { + /* value parameter */ addc_db_str('p'); stb_type(tp); addc_db_str(';'); C_ms_stb_cst(db_str.base, N_PSYM, 0, df->df_address); } - else if (df->df_sc != AUTO && df->df_sc != REGISTER) { - /* global */ + else if (df->df_sc != AUTO && df->df_sc != REGISTER) + { + /* global */ int stabtp = df->df_initialized ? N_STSYM : N_LCSYM; - if (df->df_sc == STATIC) { - if (df->df_level >= L_LOCAL) { + if (df->df_sc == STATIC) + { + if (df->df_level >= L_LOCAL) + { addc_db_str('V'); } - else { + else + { addc_db_str('S'); } } - else { + else + { addc_db_str('G'); } stb_type(tp); addc_db_str(';'); - if (df->df_sc == STATIC && df->df_level >= L_LOCAL) { - C_ms_stb_dlb(db_str.base, stabtp, 0, (label) df->df_address, (arith) 0); + if (df->df_sc == STATIC && df->df_level >= L_LOCAL) + { + C_ms_stb_dlb(db_str.base, stabtp, 0, (label) df->df_address, + (arith) 0); } - else { + else + { C_ms_stb_dnam(db_str.base, stabtp, 0, str, (arith) 0); } } - else { /* local variable */ - stb_type(tp); /* assign type num to avoid - difficult to parse string */ + else + { /* local variable */ + stb_type(tp); /* assign type num to avoid + difficult to parse string */ addc_db_str(';'); C_ms_stb_cst(db_str.base, N_LSYM, 0, df->df_address); } diff --git a/lang/cem/cemcom.ansi/stab.h b/lang/cem/cemcom.ansi/stab.h new file mode 100644 index 000000000..5f584adf8 --- /dev/null +++ b/lang/cem/cemcom.ansi/stab.h @@ -0,0 +1,20 @@ +/* Copyright (c) 2019 ACK Project. + * See the copyright notice in the ACK home directory, + * in the file "Copyright". + * + * Created on: 2019-02-07 + * + */ +#ifndef STAB_H_ +#define STAB_H_ + + +struct def; +struct type; +struct tag; + +void stb_tag(register struct tag *tg, char *str); +void stb_typedef(register struct type *tp, char *str); +void stb_string(register struct def *df, int kind, char* str); + +#endif /* STAB_H_ */ diff --git a/lang/cem/cemcom.ansi/stack.c b/lang/cem/cemcom.ansi/stack.c index c8616b86e..1d2cd699f 100644 --- a/lang/cem/cemcom.ansi/stack.c +++ b/lang/cem/cemcom.ansi/stack.c @@ -22,6 +22,9 @@ #include "struct.h" #include "level.h" #include "mes.h" +#include "code.h" +#include "util.h" +#include "error.h" /* #include */ @@ -41,7 +44,7 @@ struct stack_level *local_level = &UniversalLevel; int level; /* Always equal to local_level->sl_level. */ -stack_level() { +void stack_level(void) { /* A new level is added on top of the identifier stack. */ register struct stack_level *stl = new_stack_level(); @@ -57,10 +60,9 @@ stack_level() { #endif /* LINT */ } -void -stack_idf(idf, stl) - struct idf *idf; - register struct stack_level *stl; +void stack_idf( + struct idf *idf, + register struct stack_level *stl) { /* The identifier idf is inserted in the stack on level stl, but only if it is not already present at this level. @@ -81,8 +83,7 @@ stack_idf(idf, stl) stl->sl_entry = se; } -struct stack_level * -stack_level_of(lvl) +struct stack_level *stack_level_of(int lvl) { /* The stack_level corresponding to level lvl is returned. The stack should probably be an array, to be extended with @@ -100,7 +101,7 @@ stack_level_of(lvl) return stl; } -unstack_level() +void unstack_level(void) { /* The top level of the identifier stack is removed. */ @@ -174,7 +175,7 @@ unstack_level() #endif /* DEBUG */ } -unstack_world() +void unstack_world(void) { /* The global level of identifiers is scanned, and final decisions are taken about such issues as @@ -263,14 +264,13 @@ unstack_world() extern char *nmlist; /* BAH! -- main.c */ static File *nfp = 0; -open_name_list() +void open_name_list(void) { if (nmlist && sys_open(nmlist, OP_WRITE, &nfp) == 0) fatal("cannot create namelist %s", nmlist); } -namelist(nm) - char *nm; +void namelist(char *nm) { if (nmlist) { sys_write(nfp, nm, strlen(nm)); diff --git a/lang/cem/cemcom.ansi/stack.str b/lang/cem/cemcom.ansi/stack.str index ddb38c56c..a7f59d1db 100644 --- a/lang/cem/cemcom.ansi/stack.str +++ b/lang/cem/cemcom.ansi/stack.str @@ -2,9 +2,14 @@ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * See the copyright notice in the ACK home directory, in the file "Copyright". */ +#ifndef STACK_H_ +#define STACK_H_ + /* $Id$ */ /* IDENTIFIER STACK DEFINITIONS */ +struct idf; + /* The identifier stack is implemented as a stack of sets. The stack is implemented by a doubly linked list, the sets by singly linked lists. @@ -30,5 +35,26 @@ struct stack_entry { /* ALLOCDEF "stack_entry" 50 */ extern struct stack_level *local_level; -extern struct stack_level *stack_level_of(); extern int level; + +/* A new level is added on top of the identifier stack. */ +void stack_level(void); +/* The identifier idf is inserted in the stack on level stl, + but only if it is not already present at this level. +*/ +void stack_idf(struct idf *idf, register struct stack_level *stl); +/*The stack_level corresponding to level lvl is returned. + The stack should probably be an array, to be extended with + realloc where needed. +*/ +struct stack_level *stack_level_of(int lvl); +/* The top level of the identifier stack is removed. */ +void unstack_level(void); +void unstack_world(void); + +#ifdef GEN_NM_LIST +void open_name_list(void); +void namelist(char *nm); +#endif /* GEN_NM_LIST */ + +#endif diff --git a/lang/cem/cemcom.ansi/statement.g b/lang/cem/cemcom.ansi/statement.g index 9eb60d2ed..3d1dcd4f2 100644 --- a/lang/cem/cemcom.ansi/statement.g +++ b/lang/cem/cemcom.ansi/statement.g @@ -1,505 +1,506 @@ -/* - * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. - * See the copyright notice in the ACK home directory, in the file "Copyright". - */ -/* $Id$ */ -/* STATEMENT SYNTAX PARSER */ - -{ -#include "parameters.h" -#ifndef LINT -#include -#else -#include "l_em.h" -#include "l_lint.h" -#endif /* LINT */ - -#include -#include "idf.h" -#include "arith.h" -#include "LLlex.h" -#include "type.h" -#include "label.h" -#include "expr.h" -#include "code.h" -#include "stack.h" -#include "def.h" -#ifdef DBSYMTAB -#include -#endif /* DBSYMTAB */ - -extern int level; -extern char options[]; -} - -/* Each statement construction is stacked in order to trace a - * statement to such a construction. Example: a case statement should - * be recognized as a piece of the most enclosing switch statement. - */ - -/* 3.6 */ -statement - { -#ifdef LINT - lint_statement(); -#endif /* LINT */ - } -: -%if (AHEAD != ':') - expression_statement -| - label ':' statement -| - compound_statement -| - if_statement -| - while_statement -| - do_statement -| - for_statement -| - switch_statement -| - case_statement -| - default_statement -| - BREAK - { - code_break(); -#ifdef LINT - lint_break_stmt(); -#endif /* LINT */ - } - ';' -| - CONTINUE - { - code_continue(); -#ifdef LINT - lint_continue_stmt(); -#endif /* LINT */ - } - ';' -| - return_statement -| - jump -| - ';' -; - - -expression_statement - { struct expr *expr; - } -: - expression(&expr) - ';' - { -#ifdef DEBUG - print_expr("expression_statement", expr); -#endif /* DEBUG */ - code_expr(expr, RVAL, FALSE, NO_LABEL, NO_LABEL); - free_expression(expr); - } -; - -/* 3.6.1 (partially) */ -label - { struct idf *idf; } -: - identifier(&idf) - { - /* This allows the following absurd case: - - typedef int grz; - main() { - grz: printf("A labelled statement\n"); - } - */ -#ifdef LINT - lint_label(); -#endif /* LINT */ - define_label(idf); - C_df_ilb((label)idf->id_label->df_address); - } -; - -/* 3.6.4.1 */ -if_statement - { - struct expr *expr; - label l_true = text_label(); - label l_false = text_label(); - label l_end = text_label(); - } -: - IF - '(' - expression(&expr) - { - opnd2test(&expr, IF); - if (is_cp_cst(expr)) { - /* The comparison has been optimized - to a 0 or 1. - */ - if (expr->VL_VALUE == (arith)0) { - C_bra(l_false); - } - /* else fall through */ -#ifdef LINT - start_if_part(1); -#endif /* LINT */ - } - else { - code_expr(expr, RVAL, TRUE, l_true, l_false); - C_df_ilb(l_true); -#ifdef LINT - start_if_part(0); -#endif /* LINT */ - } - free_expression(expr); - } - ')' - statement - [%prefer - ELSE - { -#ifdef LINT - start_else_part(); -#endif /* LINT */ - C_bra(l_end); - C_df_ilb(l_false); - } - statement - { C_df_ilb(l_end); -#ifdef LINT - end_if_else_stmt(); -#endif /* LINT */ - } - | - empty - { C_df_ilb(l_false); -#ifdef LINT - end_if_stmt(); -#endif /* LINT */ - } - ] -; - -/* 3.6.5.3 */ -while_statement - { - struct expr *expr; - label l_break = text_label(); - label l_continue = text_label(); - label l_body = text_label(); - } -: - WHILE - { - stack_stmt(l_break, l_continue); - C_df_ilb(l_continue); - } - '(' - expression(&expr) - { - opnd2test(&expr, WHILE); - if (is_cp_cst(expr)) { - if (expr->VL_VALUE == (arith)0) { - C_bra(l_break); - } - } - else { - code_expr(expr, RVAL, TRUE, l_body, l_break); - C_df_ilb(l_body); - } -#ifdef LINT - start_while_stmt(expr); -#endif /* LINT */ - } - ')' - statement - { - C_bra(l_continue); - C_df_ilb(l_break); - unstack_stmt(); - free_expression(expr); -#ifdef LINT - end_loop_body(); - end_loop_stmt(); -#endif /* LINT */ - } -; - -/* 3.6.5.2 */ -do_statement - { struct expr *expr; - label l_break = text_label(); - label l_continue = text_label(); - label l_body = text_label(); - } -: - DO - { C_df_ilb(l_body); - stack_stmt(l_break, l_continue); -#ifdef LINT - start_do_stmt(); -#endif /* LINT */ - } - statement - WHILE - '(' - { -#ifdef LINT - end_loop_body(); -#endif /* LINT */ - C_df_ilb(l_continue); - } - expression(&expr) - { - opnd2test(&expr, WHILE); - if (is_cp_cst(expr)) { - if (expr->VL_VALUE == (arith)1) { - C_bra(l_body); - } -#ifdef LINT - end_do_stmt(1, expr->VL_VALUE != (arith)0); -#endif /* LINT */ - } - else { - code_expr(expr, RVAL, TRUE, l_body, l_break); -#ifdef LINT - end_do_stmt(0, 0); -#endif /* LINT */ - } - C_df_ilb(l_break); - } - ')' - ';' - { - unstack_stmt(); - free_expression(expr); - } -; - -/* 3.6.5.3 */ -for_statement - { struct expr *e_init = 0, *e_test = 0, *e_incr = 0; - label l_break = text_label(); - label l_continue = text_label(); - label l_body = text_label(); - label l_test = text_label(); - } -: - FOR - { stack_stmt(l_break, l_continue); - } - '(' - [ - expression(&e_init) - { code_expr(e_init, RVAL, FALSE, NO_LABEL, NO_LABEL); - } - ]? - ';' - { C_df_ilb(l_test); - } - [ - expression(&e_test) - { - opnd2test(&e_test, FOR); - if (is_cp_cst(e_test)) { - if (e_test->VL_VALUE == (arith)0) { - C_bra(l_break); - } - } - else { - code_expr(e_test, RVAL, TRUE, l_body, l_break); - C_df_ilb(l_body); - } - } - ]? - ';' - expression(&e_incr)? - ')' - { -#ifdef LINT - start_for_stmt(e_test); -#endif /* LINT */ - } - statement - { -#ifdef LINT - end_loop_body(); -#endif /* LINT */ - C_df_ilb(l_continue); - if (e_incr) - code_expr(e_incr, RVAL, FALSE, - NO_LABEL, NO_LABEL); - C_bra(l_test); - C_df_ilb(l_break); - unstack_stmt(); - free_expression(e_init); - free_expression(e_test); - free_expression(e_incr); -#ifdef LINT - end_loop_stmt(); -#endif /* LINT */ - } -; - -/* 3.6.4.2 */ -switch_statement - { - struct expr *expr; - } -: - SWITCH - '(' - expression(&expr) - { - code_startswitch(&expr); -#ifdef LINT - start_switch_part(is_cp_cst(expr)); -#endif /* LINT */ - } - ')' - statement - { -#ifdef LINT - end_switch_stmt(); -#endif /* LINT */ - code_endswitch(); - free_expression(expr); - } -; - -/* 3.6.1 (partially) */ -case_statement - { - struct expr *expr; - } -: - CASE - constant_expression(&expr) - { -#ifdef LINT - lint_case_stmt(0); -#endif /* LINT */ - code_case(expr); - free_expression(expr); - } - ':' - statement -; - -/* 3.6.1 (partially) */ -default_statement -: - DEFAULT - { -#ifdef LINT - lint_case_stmt(1); -#endif /* LINT */ - code_default(); - } - ':' - statement -; - -/* 3.6.6.4 */ -return_statement - { struct expr *expr = 0; - } -: - RETURN - [ - expression(&expr) - { -#ifdef LINT - lint_ret_conv(expr); -#endif /* LINT */ - - do_return_expr(expr); - free_expression(expr); -#ifdef LINT - lint_return_stmt(VALRETURNED); -#endif /* LINT */ - } - | - empty - { - do_return(); -#ifdef LINT - lint_return_stmt(NOVALRETURNED); -#endif /* LINT */ - } - ] - ';' -; - -/* 3.6.6.1 (partially) */ -jump - { struct idf *idf; - } -: - GOTO - identifier(&idf) - ';' - { - apply_label(idf); - C_bra((label)idf->id_label->df_address); -#ifdef LINT - lint_jump_stmt(idf); -#endif /* LINT */ - } -; - -/* 3.6.2 */ -compound_statement - { -#ifdef DBSYMTAB - static int brc_level = 1; - int decl_seen = brc_level == 1; -#endif /* DBSYMTAB */ - } -: - '{' - { - stack_level(); - } - [%while ((DOT != IDENTIFIER && AHEAD != ':') || - (DOT == IDENTIFIER && AHEAD == IDENTIFIER)) - /* >>> conflict on TYPE_IDENTIFIER, IDENTIFIER */ - declaration - { -#ifdef DBSYMTAB - decl_seen++; -#endif /* DBSYMTAB */ - } - ]* - { -#ifdef DBSYMTAB - ++brc_level; - if (options['g'] && decl_seen) { - C_ms_std((char *) 0, N_LBRAC, brc_level); - } -#endif /* DBSYMTAB */ - } - [%persistent - statement - ]* - '}' - { - unstack_level(); -#ifdef DBSYMTAB - if (options['g'] && decl_seen) { - C_ms_std((char *) 0, N_RBRAC, brc_level); - } - brc_level--; -#endif /* DBSYMTAB */ - } -; +/* + * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. + * See the copyright notice in the ACK home directory, in the file "Copyright". + */ +/* $Id$ */ +/* STATEMENT SYNTAX PARSER */ + +{ +#include "parameters.h" +#ifndef LINT +#include +#else +#include "l_em.h" +#include "l_lint.h" +#endif /* LINT */ + +#include +#include "idf.h" +#include "arith.h" +#include "LLlex.h" +#include "type.h" +#include "label.h" +#include "expr.h" +#include "code.h" +#include "stack.h" +#include "def.h" +#include "switch.h" +#ifdef DBSYMTAB +#include +#endif /* DBSYMTAB */ + +extern int level; +extern char options[]; +} + +/* Each statement construction is stacked in order to trace a + * statement to such a construction. Example: a case statement should + * be recognized as a piece of the most enclosing switch statement. + */ + +/* 3.6 */ +statement + { +#ifdef LINT + lint_statement(); +#endif /* LINT */ + } +: +%if (AHEAD != ':') + expression_statement +| + label ':' statement +| + compound_statement +| + if_statement +| + while_statement +| + do_statement +| + for_statement +| + switch_statement +| + case_statement +| + default_statement +| + BREAK + { + code_break(); +#ifdef LINT + lint_break_stmt(); +#endif /* LINT */ + } + ';' +| + CONTINUE + { + code_continue(); +#ifdef LINT + lint_continue_stmt(); +#endif /* LINT */ + } + ';' +| + return_statement +| + jump +| + ';' +; + + +expression_statement + { struct expr *expr; + } +: + expression(&expr) + ';' + { +#ifdef DEBUG + print_expr("expression_statement", expr); +#endif /* DEBUG */ + code_expr(expr, RVAL, FALSE, NO_LABEL, NO_LABEL); + free_expression(expr); + } +; + +/* 3.6.1 (partially) */ +label + { struct idf *idf; } +: + identifier(&idf) + { + /* This allows the following absurd case: + + typedef int grz; + main() { + grz: printf("A labelled statement\n"); + } + */ +#ifdef LINT + lint_label(); +#endif /* LINT */ + define_label(idf); + C_df_ilb((label)idf->id_label->df_address); + } +; + +/* 3.6.4.1 */ +if_statement + { + struct expr *expr; + label l_true = text_label(); + label l_false = text_label(); + label l_end = text_label(); + } +: + IF + '(' + expression(&expr) + { + opnd2test(&expr, IF); + if (is_cp_cst(expr)) { + /* The comparison has been optimized + to a 0 or 1. + */ + if (expr->VL_VALUE == (arith)0) { + C_bra(l_false); + } + /* else fall through */ +#ifdef LINT + start_if_part(1); +#endif /* LINT */ + } + else { + code_expr(expr, RVAL, TRUE, l_true, l_false); + C_df_ilb(l_true); +#ifdef LINT + start_if_part(0); +#endif /* LINT */ + } + free_expression(expr); + } + ')' + statement + [%prefer + ELSE + { +#ifdef LINT + start_else_part(); +#endif /* LINT */ + C_bra(l_end); + C_df_ilb(l_false); + } + statement + { C_df_ilb(l_end); +#ifdef LINT + end_if_else_stmt(); +#endif /* LINT */ + } + | + empty + { C_df_ilb(l_false); +#ifdef LINT + end_if_stmt(); +#endif /* LINT */ + } + ] +; + +/* 3.6.5.3 */ +while_statement + { + struct expr *expr; + label l_break = text_label(); + label l_continue = text_label(); + label l_body = text_label(); + } +: + WHILE + { + stack_stmt(l_break, l_continue); + C_df_ilb(l_continue); + } + '(' + expression(&expr) + { + opnd2test(&expr, WHILE); + if (is_cp_cst(expr)) { + if (expr->VL_VALUE == (arith)0) { + C_bra(l_break); + } + } + else { + code_expr(expr, RVAL, TRUE, l_body, l_break); + C_df_ilb(l_body); + } +#ifdef LINT + start_while_stmt(expr); +#endif /* LINT */ + } + ')' + statement + { + C_bra(l_continue); + C_df_ilb(l_break); + unstack_stmt(); + free_expression(expr); +#ifdef LINT + end_loop_body(); + end_loop_stmt(); +#endif /* LINT */ + } +; + +/* 3.6.5.2 */ +do_statement + { struct expr *expr; + label l_break = text_label(); + label l_continue = text_label(); + label l_body = text_label(); + } +: + DO + { C_df_ilb(l_body); + stack_stmt(l_break, l_continue); +#ifdef LINT + start_do_stmt(); +#endif /* LINT */ + } + statement + WHILE + '(' + { +#ifdef LINT + end_loop_body(); +#endif /* LINT */ + C_df_ilb(l_continue); + } + expression(&expr) + { + opnd2test(&expr, WHILE); + if (is_cp_cst(expr)) { + if (expr->VL_VALUE == (arith)1) { + C_bra(l_body); + } +#ifdef LINT + end_do_stmt(1, expr->VL_VALUE != (arith)0); +#endif /* LINT */ + } + else { + code_expr(expr, RVAL, TRUE, l_body, l_break); +#ifdef LINT + end_do_stmt(0, 0); +#endif /* LINT */ + } + C_df_ilb(l_break); + } + ')' + ';' + { + unstack_stmt(); + free_expression(expr); + } +; + +/* 3.6.5.3 */ +for_statement + { struct expr *e_init = 0, *e_test = 0, *e_incr = 0; + label l_break = text_label(); + label l_continue = text_label(); + label l_body = text_label(); + label l_test = text_label(); + } +: + FOR + { stack_stmt(l_break, l_continue); + } + '(' + [ + expression(&e_init) + { code_expr(e_init, RVAL, FALSE, NO_LABEL, NO_LABEL); + } + ]? + ';' + { C_df_ilb(l_test); + } + [ + expression(&e_test) + { + opnd2test(&e_test, FOR); + if (is_cp_cst(e_test)) { + if (e_test->VL_VALUE == (arith)0) { + C_bra(l_break); + } + } + else { + code_expr(e_test, RVAL, TRUE, l_body, l_break); + C_df_ilb(l_body); + } + } + ]? + ';' + expression(&e_incr)? + ')' + { +#ifdef LINT + start_for_stmt(e_test); +#endif /* LINT */ + } + statement + { +#ifdef LINT + end_loop_body(); +#endif /* LINT */ + C_df_ilb(l_continue); + if (e_incr) + code_expr(e_incr, RVAL, FALSE, + NO_LABEL, NO_LABEL); + C_bra(l_test); + C_df_ilb(l_break); + unstack_stmt(); + free_expression(e_init); + free_expression(e_test); + free_expression(e_incr); +#ifdef LINT + end_loop_stmt(); +#endif /* LINT */ + } +; + +/* 3.6.4.2 */ +switch_statement + { + struct expr *expr; + } +: + SWITCH + '(' + expression(&expr) + { + code_startswitch(&expr); +#ifdef LINT + start_switch_part(is_cp_cst(expr)); +#endif /* LINT */ + } + ')' + statement + { +#ifdef LINT + end_switch_stmt(); +#endif /* LINT */ + code_endswitch(); + free_expression(expr); + } +; + +/* 3.6.1 (partially) */ +case_statement + { + struct expr *expr; + } +: + CASE + constant_expression(&expr) + { +#ifdef LINT + lint_case_stmt(0); +#endif /* LINT */ + code_case(expr); + free_expression(expr); + } + ':' + statement +; + +/* 3.6.1 (partially) */ +default_statement +: + DEFAULT + { +#ifdef LINT + lint_case_stmt(1); +#endif /* LINT */ + code_default(); + } + ':' + statement +; + +/* 3.6.6.4 */ +return_statement + { struct expr *expr = 0; + } +: + RETURN + [ + expression(&expr) + { +#ifdef LINT + lint_ret_conv(expr); +#endif /* LINT */ + + do_return_expr(expr); + free_expression(expr); +#ifdef LINT + lint_return_stmt(VALRETURNED); +#endif /* LINT */ + } + | + empty + { + do_return(); +#ifdef LINT + lint_return_stmt(NOVALRETURNED); +#endif /* LINT */ + } + ] + ';' +; + +/* 3.6.6.1 (partially) */ +jump + { struct idf *idf; + } +: + GOTO + identifier(&idf) + ';' + { + apply_label(idf); + C_bra((label)idf->id_label->df_address); +#ifdef LINT + lint_jump_stmt(idf); +#endif /* LINT */ + } +; + +/* 3.6.2 */ +compound_statement + { +#ifdef DBSYMTAB + static int brc_level = 1; + int decl_seen = brc_level == 1; +#endif /* DBSYMTAB */ + } +: + '{' + { + stack_level(); + } + [%while ((DOT != IDENTIFIER && AHEAD != ':') || + (DOT == IDENTIFIER && AHEAD == IDENTIFIER)) + /* >>> conflict on TYPE_IDENTIFIER, IDENTIFIER */ + declaration + { +#ifdef DBSYMTAB + decl_seen++; +#endif /* DBSYMTAB */ + } + ]* + { +#ifdef DBSYMTAB + ++brc_level; + if (options['g'] && decl_seen) { + C_ms_std((char *) 0, N_LBRAC, brc_level); + } +#endif /* DBSYMTAB */ + } + [%persistent + statement + ]* + '}' + { + unstack_level(); +#ifdef DBSYMTAB + if (options['g'] && decl_seen) { + C_ms_std((char *) 0, N_RBRAC, brc_level); + } + brc_level--; +#endif /* DBSYMTAB */ + } +; diff --git a/lang/cem/cemcom.ansi/stb.c b/lang/cem/cemcom.ansi/stb.c index 0a98e6725..4fcd26258 100644 --- a/lang/cem/cemcom.ansi/stb.c +++ b/lang/cem/cemcom.ansi/stb.c @@ -3,10 +3,10 @@ * See the copyright notice in the ACK home directory, in the file "Copyright". */ /* $Id$ */ -/* library routine for copying structs */ -__stb(n, f, t) - register char *f, *t; register n; + +/* library routine for copying structs */ +void __stb(register int n, register char *f, register char *t) { if (n > 0) do diff --git a/lang/cem/cemcom.ansi/stmt.str b/lang/cem/cemcom.ansi/stmt.str index feaa82fcd..aea09b36b 100644 --- a/lang/cem/cemcom.ansi/stmt.str +++ b/lang/cem/cemcom.ansi/stmt.str @@ -2,6 +2,9 @@ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * See the copyright notice in the ACK home directory, in the file "Copyright". */ +#ifndef STMT_H_ +#define STMT_H_ + /* $Id$ */ /* S T A T E M E N T - B L O C K D E F I N I T I O N S */ @@ -12,3 +15,5 @@ struct stmt_block { }; /* ALLOCDEF "stmt_block" 5 */ + +#endif \ No newline at end of file diff --git a/lang/cem/cemcom.ansi/struct.c b/lang/cem/cemcom.ansi/struct.c index a36b11e20..fbba71a0e 100644 --- a/lang/cem/cemcom.ansi/struct.c +++ b/lang/cem/cemcom.ansi/struct.c @@ -19,16 +19,23 @@ #include "Lpars.h" #include "align.h" #include "level.h" +#include "ch3.h" #include "sizes.h" +#include "error.h" /* Type of previous selector declared with a field width specified, if any. If a selector is declared with no field with it is set to 0. */ -static field_busy = 0; +static int field_busy = 0; extern char options[]; char *symbol2str(); -int lcm(); + +static void check_selector(register struct idf *, struct type *); +/* Greatest Common Divisor */ +static int gcd(register int , register int ); +/* Least Common Multiple */ +static int lcm(register int, register int); /* The semantics of the identification of structure/union tags is obscure. Some highly regarded compilers are found out to accept, @@ -51,13 +58,13 @@ int lcm(); as well). */ -add_sel(stp, tp, idf, sdefpp, szp, fd) /* this is horrible */ - register struct type *stp; /* type of the structure */ - struct type *tp; /* type of the selector */ - register struct idf *idf; /* idf of the selector */ - struct sdef ***sdefpp; /* address of hook to selector definition */ - arith *szp; /* pointer to struct size upto here */ - struct field *fd; +void add_sel( /* this is horrible */ + register struct type *stp, /* type of the structure */ + struct type *tp, /* type of the selector */ + register struct idf *idf, /* idf of the selector */ + struct sdef ***sdefpp, /* address of hook to selector definition */ + arith *szp, /* pointer to struct size upto here */ + struct field *fd) { /* The selector idf with type tp is added to two chains: the selector identification chain starting at idf->id_sdef, @@ -147,12 +154,11 @@ add_sel(stp, tp, idf, sdefpp, szp, fd) /* this is horrible */ } } -check_selector(idf, stp) - register struct idf *idf; - struct type *stp; /* the type of the struct */ +static void check_selector(register struct idf *idf, struct type *stp) { /* checks if idf occurs already as a selector in - struct or union *stp. + struct or union *stp. "stp" indicates the type + of the struct. */ register struct sdef *sdef = stp->tp_sdef; @@ -163,9 +169,7 @@ check_selector(idf, stp) } } -declare_struct(fund, idf, tpp) - register struct idf *idf; - struct type **tpp; +void declare_struct(int fund, register struct idf *idf, struct type **tpp) { /* A struct, union or enum (depending on fund) with tag (!) idf is declared, and its type (incomplete as it may be) is @@ -232,9 +236,9 @@ declare_struct(fund, idf, tpp) } } -apply_struct(fund, idf, tpp) - register struct idf *idf; - struct type **tpp; +void apply_struct(int fund, + register struct idf *idf, + struct type **tpp) { /* The occurrence of a struct, union or enum (depending on fund) with tag idf is noted. It may or may not have been @@ -258,10 +262,9 @@ apply_struct(fund, idf, tpp) declare_struct(fund, idf, tpp); } -struct sdef * -idf2sdef(idf, tp) - register struct idf *idf; - struct type *tp; +struct sdef *idf2sdef( + register struct idf *idf, + struct type *tp) { /* The identifier idf is identified as a selector in the struct tp. @@ -296,9 +299,7 @@ idf2sdef(idf, tp) } #if 0 -int -uniq_selector(idf_sdef) - register struct sdef *idf_sdef; +int uniq_selector(register struct sdef *idf_sdef) { /* Returns true if idf_sdef (which is guaranteed to exist) is unique for this level, i.e there is no other selector @@ -324,12 +325,12 @@ uniq_selector(idf_sdef) #ifndef NOBITFIELD arith -add_field(szp, fd, fdtpp, idf, stp) - arith *szp; /* size of struct upto here */ - register struct field *fd; /* bitfield, containing width */ - register struct type **fdtpp; /* type of selector */ - struct idf *idf; /* name of selector */ - register struct type *stp; /* current struct descriptor */ +add_field( + arith *szp, /* size of struct upto here */ + register struct field *fd, /* bitfield, containing width */ + register struct type **fdtpp, /* type of selector */ + struct idf *idf, /* name of selector */ + register struct type *stp) /* current struct descriptor */ { /* The address where this selector is put is returned. If the selector with specified width does not fit in the word, or @@ -438,18 +439,12 @@ add_field(szp, fd, fdtpp, idf, stp) #endif /* NOBITFIELD */ /* some utilities */ -int -is_struct_or_union(fund) - register int fund; +int is_struct_or_union(register int fund) { return fund == STRUCT || fund == UNION; } -/* Greatest Common Divisor - */ -int -gcd(m, n) - register int m, n; +static int gcd(register int m, register int n) { register int r; @@ -461,11 +456,8 @@ gcd(m, n) return m; } -/* Least Common Multiple - */ -int -lcm(m, n) - register int m, n; + +static int lcm(register int m, register int n) { return m * (n / gcd(m, n)); } diff --git a/lang/cem/cemcom.ansi/struct.str b/lang/cem/cemcom.ansi/struct.str index 8dafd856e..c0a95244d 100644 --- a/lang/cem/cemcom.ansi/struct.str +++ b/lang/cem/cemcom.ansi/struct.str @@ -2,7 +2,17 @@ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * See the copyright notice in the ACK home directory, in the file "Copyright". */ +#ifndef STRUCT_H_ +#define STRUCT_H_ + /* $Id$ */ + +#include "arith.h" + +struct type; +struct idf; +struct field; + /* SELECTOR DESCRIPTOR */ struct sdef { /* for selectors */ @@ -27,4 +37,26 @@ struct tag { /* for struct-, union- and enum tags */ /* ALLOCDEF "tag" 10 */ -struct sdef *idf2sdef(); +struct sdef *idf2sdef(register struct idf *idf, struct type *tp); +void add_sel( + register struct type *stp, /* type of the structure */ + struct type *tp, /* type of the selector */ + register struct idf *idf, /* idf of the selector */ + struct sdef ***sdefpp, /* address of hook to selector definition */ + arith *szp, /* pointer to struct size upto here */ + struct field *fd); +void declare_struct(int fund, register struct idf *idf, struct type **tpp); +void apply_struct(int fund, register struct idf *idf, struct type **tpp); +int is_struct_or_union(register int fund); + +#ifndef NOBITFIELD +arith +add_field( + arith *szp, /* size of struct upto here */ + register struct field *fd, /* bitfield, containing width */ + register struct type **fdtpp, /* type of selector */ + struct idf *idf, /* name of selector */ + register struct type *stp); /* current struct descriptor */ +#endif + +#endif diff --git a/lang/cem/cemcom.ansi/switch.c b/lang/cem/cemcom.ansi/switch.c index 77a9dcef3..24cb82c6f 100644 --- a/lang/cem/cemcom.ansi/switch.c +++ b/lang/cem/cemcom.ansi/switch.c @@ -23,13 +23,16 @@ #include "expr.h" #include "type.h" #include "sizes.h" +#include "switch.h" +#include "eval.h" +#include "ch3.h" +#include "error.h" extern char options[]; int density = DENSITY; -compact(nr, low, up) - arith low, up; +static int compact(int nr, arith low, arith up) { /* Careful! up - low might not fit in an arith. And then, the test "up-low < 0" might also not work to detect this @@ -49,8 +52,7 @@ static struct switch_hdr *switch_stack = 0; For simplicity, we suppose int_size == word_size. */ -code_startswitch(expp) - struct expr **expp; +void code_startswitch(struct expr **expp) { /* Check the expression, stack a new case header and fill in the necessary fields. @@ -85,7 +87,7 @@ code_startswitch(expp) C_bra(l_table); /* goto start of switch_table */ } -code_endswitch() +void code_endswitch(void) { register struct switch_hdr *sh = switch_stack; register label tablabel; @@ -158,9 +160,7 @@ code_endswitch() unstack_stmt(); } -void -code_case(expr) - struct expr *expr; +void code_case(struct expr *expr) { register arith val; register struct case_entry *ce; @@ -227,8 +227,7 @@ code_case(expr) } } -void -code_default() +void code_default(void) { register struct switch_hdr *sh = switch_stack; diff --git a/lang/cem/cemcom.ansi/switch.str b/lang/cem/cemcom.ansi/switch.str index fd2dd455b..94a45ca42 100644 --- a/lang/cem/cemcom.ansi/switch.str +++ b/lang/cem/cemcom.ansi/switch.str @@ -2,7 +2,16 @@ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * See the copyright notice in the ACK home directory, in the file "Copyright". */ +#ifndef SWITCH_H_ +#define SWITCH_H_ + /* $Id$ */ + +#include "arith.h" + +struct type; +struct expr; + /* S W I T C H - T A B L E - S T R U C T U R E */ struct switch_hdr { @@ -27,3 +36,12 @@ struct case_entry { }; /* ALLOCDEF "case_entry" 20 */ + +void code_startswitch(struct expr **expp); +void code_endswitch(void); +void code_case(struct expr *expr); +void code_default(void); + + + +#endif \ No newline at end of file diff --git a/lang/cem/cemcom.ansi/tokcase.sed b/lang/cem/cemcom.ansi/tokcase.sed new file mode 100644 index 000000000..25cd5d9d3 --- /dev/null +++ b/lang/cem/cemcom.ansi/tokcase.sed @@ -0,0 +1,3 @@ +/{[A-Z]/!d +s/.*{\(.*\),.*\(".*"\).*$/ case \1 :\ + return \2;/ diff --git a/lang/cem/cemcom.ansi/tokcasee.in b/lang/cem/cemcom.ansi/tokcasee.in new file mode 100644 index 000000000..5df07e7c9 --- /dev/null +++ b/lang/cem/cemcom.ansi/tokcasee.in @@ -0,0 +1,16 @@ + default: + if (tok <= 0) return "end of file"; + if (tok < 040 || tok >= 0177) { + return "bad token"; + } + /* fall through */ + case '\n': + case '\f': + case '\v': + case '\r': + case '\t': + index = (index+2) & (SIZBUF-1); + buf[index] = tok; + return &buf[index]; + } +} \ No newline at end of file diff --git a/lang/cem/cemcom.ansi/tokcaseh.in b/lang/cem/cemcom.ansi/tokcaseh.in new file mode 100644 index 000000000..63b1932cb --- /dev/null +++ b/lang/cem/cemcom.ansi/tokcaseh.in @@ -0,0 +1,12 @@ +/* Generated by make.tokcase */ +/* $Id$ */ +#include "Lpars.h" + +char *symbol2str(int tok) +{ +#define SIZBUF 8 + /* allow for a few invocations in f.i. an argument list */ + static char buf[SIZBUF]; + static int index; + + switch (tok) { diff --git a/lang/cem/cemcom.ansi/tokenname.c b/lang/cem/cemcom.ansi/tokenname.c index 8c52b4dcb..b430abbd8 100644 --- a/lang/cem/cemcom.ansi/tokenname.c +++ b/lang/cem/cemcom.ansi/tokenname.c @@ -11,6 +11,7 @@ #include "LLlex.h" #include "tokenname.h" #include "Lpars.h" +#include "error.h" /* To centralize the declaration of %tokens, their presence in this file is taken as their declaration. The Makefile will produce @@ -132,8 +133,7 @@ struct tokenname tkfunny[] = { /* internal keywords */ }; #endif /* ____ */ -reserve(resv) - register struct tokenname resv[]; +void reserve(register struct tokenname resv[]) { /* The names of the tokens described in resv are entered as reserved words. diff --git a/lang/cem/cemcom.ansi/tokenname.h b/lang/cem/cemcom.ansi/tokenname.h index fdff2fbc2..f3f5edb2e 100644 --- a/lang/cem/cemcom.ansi/tokenname.h +++ b/lang/cem/cemcom.ansi/tokenname.h @@ -4,6 +4,8 @@ */ /* $Id$ */ /* TOKENNAME DEFINITION */ +#ifndef TOKENNAME_H_ +#define TOKENNAME_H_ struct tokenname { /* Used for defining the name of a token as identified by its symbol @@ -11,3 +13,7 @@ struct tokenname { /* Used for defining the name of a int tn_symbol; char *tn_name; }; + +void reserve(register struct tokenname resv[]); + +#endif /* TOKENNAME_H_ */ diff --git a/lang/cem/cemcom.ansi/type.c b/lang/cem/cemcom.ansi/type.c index 2b477a725..ff3a6eab3 100644 --- a/lang/cem/cemcom.ansi/type.c +++ b/lang/cem/cemcom.ansi/type.c @@ -16,68 +16,59 @@ #include "sizes.h" #include "align.h" #include "decspecs.h" +#include "error.h" + -extern struct type *function_of(), *array_of(); -#ifndef NOBITFIELD -extern struct type *field_of(); -#endif /* NOBITFIELD */ /* To be created dynamically in main() from defaults or from command - line parameters. -*/ -struct type - *schar_type, *uchar_type, - *short_type, *ushort_type, - *word_type, *uword_type, - *int_type, *uint_type, - *long_type, *ulong_type, - *float_type, *double_type, *lngdbl_type, - *void_type, - *string_type, *funint_type, *error_type; + line parameters. + */ +struct type *schar_type, *uchar_type, *short_type, *ushort_type, *word_type, + *uword_type, *int_type, *uint_type, *long_type, *ulong_type, + *float_type, *double_type, *lngdbl_type, *void_type, *string_type, + *funint_type, *error_type; -struct type *pa_type; /* Pointer-Arithmetic type */ +struct type *pa_type; /* Pointer-Arithmetic type */ -struct type * -create_type(fund) - int fund; +struct type *create_type(int fund) { /* A brand new struct type is created, and its tp_fund set - to fund. - */ + to fund. + */ register struct type *ntp = new_type(); ntp->tp_fund = fund; - ntp->tp_size = (arith)-1; + ntp->tp_size = (arith) -1; return ntp; } -struct type * -promoted_type(tp) -struct type *tp; +struct type *promoted_type(struct type *tp) { - if (tp->tp_fund == CHAR || tp->tp_fund == SHORT) { + if (tp->tp_fund == CHAR || tp->tp_fund == SHORT) + { if (tp->tp_unsigned && (int) tp->tp_size == (int) int_size) return uint_type; - else return int_type; - } else if (tp->tp_fund == FLOAT) + else + return int_type; + } + else if (tp->tp_fund == FLOAT) return double_type; - else return tp; + else + return tp; } -struct type * -construct_type(fund, tp, qual, count, pl) - register struct type *tp; - register struct proto *pl; - arith count; /* for fund == ARRAY only */ - int qual; +struct type *construct_type(int fund, register struct type *tp, int qual, +arith count, /* for fund == ARRAY only */ +register struct proto *pl) { /* fund must be a type constructor: FIELD, FUNCTION, POINTER or - ARRAY. The pointer to the constructed type is returned. - */ + ARRAY. The pointer to the constructed type is returned. + */ register struct type *dtp; - switch (fund) { + switch (fund) + { #ifndef NOBITFIELD case FIELD: dtp = field_of(tp, qual); @@ -85,11 +76,13 @@ construct_type(fund, tp, qual, count, pl) #endif /* NOBITFIELD */ case FUNCTION: - if (tp->tp_fund == FUNCTION) { + if (tp->tp_fund == FUNCTION) + { error("function cannot yield function"); return error_type; } - if (tp->tp_fund == ARRAY) { + if (tp->tp_fund == ARRAY) + { error("function cannot yield array"); return error_type; } @@ -100,7 +93,8 @@ construct_type(fund, tp, qual, count, pl) dtp = pointer_to(tp, qual); break; case ARRAY: - if (tp->tp_fund == VOID) { + if (tp->tp_fund == VOID) + { error("cannot construct array of void"); count = (arith) -1; } @@ -113,14 +107,10 @@ construct_type(fund, tp, qual, count, pl) return dtp; } -struct type * -function_of(tp, pl, qual) - register struct type *tp; - struct proto *pl; - int qual; +struct type *function_of(register struct type *tp, struct proto *pl, int qual) { #if 0 -/* See comment below */ + /* See comment below */ register struct type *dtp = tp->tp_function; #else register struct type *dtp; @@ -128,30 +118,31 @@ function_of(tp, pl, qual) /* look for a type with the right qualifier */ #if 0 -/* the code doesn't work in the following case: - int func(); - int func(int a, int b) { return q(a); } - because updating the type works inside the data-structures for that type - thus, a new type is created for very function. This may change in the - future, when declarations with empty parameter lists become obsolete. - When it does, change type.str, decspecs.c, and this routine. Search for - the function_of pattern to find the places. -*/ + /* the code doesn't work in the following case: + int func(); + int func(int a, int b) { return q(a); } + because updating the type works inside the data-structures for that type + thus, a new type is created for very function. This may change in the + future, when declarations with empty parameter lists become obsolete. + When it does, change type.str, decspecs.c, and this routine. Search for + the function_of pattern to find the places. + */ while (dtp && (dtp->tp_typequal != qual || dtp->tp_proto != pl)) - dtp = dtp->next; + dtp = dtp->next; #else dtp = 0; #endif - if (!dtp) { + if (!dtp) + { dtp = create_type(FUNCTION); dtp->tp_up = tp; - dtp->tp_size = -1; /* function size is not known */ + dtp->tp_size = -1; /* function size is not known */ dtp->tp_align = pointer_align; dtp->tp_typequal = qual; dtp->tp_proto = pl; #if 0 -/* See comment above */ + /* See comment above */ dtp->next = tp->tp_function; tp->tp_function = dtp; #endif @@ -159,10 +150,7 @@ function_of(tp, pl, qual) return dtp; } -struct type * -pointer_to(tp, qual) - register struct type *tp; - int qual; +struct type *pointer_to(register struct type *tp, int qual) { register struct type *dtp = tp->tp_pointer; @@ -170,7 +158,8 @@ pointer_to(tp, qual) while (dtp && dtp->tp_typequal != qual) dtp = dtp->next; - if (!dtp) { + if (!dtp) + { dtp = create_type(POINTER); dtp->tp_unsigned = 1; dtp->tp_up = tp; @@ -183,11 +172,7 @@ pointer_to(tp, qual) return dtp; } -struct type * -array_of(tp, count, qual) - register struct type *tp; - arith count; - int qual; +struct type * array_of(register struct type *tp, arith count, int qual) { register struct type *dtp = tp->tp_array; @@ -195,7 +180,8 @@ array_of(tp, count, qual) while (dtp && (dtp->tp_nel != count || dtp->tp_typequal != qual)) dtp = dtp->next; - if (!dtp) { + if (!dtp) + { dtp = create_type(ARRAY); dtp->tp_up = tp; dtp->tp_nel = count; @@ -203,19 +189,18 @@ array_of(tp, count, qual) dtp->tp_typequal = qual; dtp->next = tp->tp_array; tp->tp_array = dtp; - if (tp->tp_size >= 0 && count >= 0) { + if (tp->tp_size >= 0 && count >= 0) + { dtp->tp_size = count * tp->tp_size; } - else dtp->tp_size = -1; + else + dtp->tp_size = -1; } return dtp; } #ifndef NOBITFIELD -struct type * -field_of(tp, qual) - register struct type *tp; - int qual; +struct type * field_of(register struct type *tp, int qual) { register struct type *dtp = create_type(FIELD); @@ -227,53 +212,47 @@ field_of(tp, qual) } #endif /* NOBITFIELD */ -arith -size_of_type(tp, nm) - struct type *tp; - char nm[]; +arith size_of_type(struct type *tp, char nm[]) { arith sz = tp->tp_size; - if (sz < 0) { + if (sz < 0) + { error("size of %s unknown", nm); - sz = (arith)1; + sz = (arith) 1; } return sz; } -idf2type(idf, tpp) - struct idf *idf; - struct type **tpp; +void idf2type(struct idf *idf, struct type **tpp) { /* Decoding a typedef-ed identifier or basic type: if the - size is yet unknown we have to make copy of the type - descriptor to prevent garbage at the initialisation of - arrays with unknown size. - */ + size is yet unknown we have to make copy of the type + descriptor to prevent garbage at the initialisation of + arrays with unknown size. + */ register struct type *tp = idf->id_def->df_type; - if (*tpp) error("multiple types in declaration"); - if ( tp->tp_size < (arith)0 && tp->tp_fund == ARRAY) { + if (*tpp) + error("multiple types in declaration"); + if (tp->tp_size < (arith) 0 && tp->tp_fund == ARRAY) + { *tpp = new_type(); **tpp = *tp; - /* this is really a structure assignment, AAGH!!! */ + /* this is really a structure assignment, AAGH!!! */ } - else { + else + { *tpp = tp; } } -arith -align(pos, al) - arith pos; - int al; +arith align(arith pos, int al) { return ((pos + al - 1) / al) * al; } -struct type * -standard_type(fund, sgn, algn, sz) - int algn; arith sz; +struct type * standard_type(int fund, int sgn, int algn, arith sz) { register struct type *tp = create_type(fund); @@ -284,25 +263,29 @@ standard_type(fund, sgn, algn, sz) return tp; } -completed(tp) - struct type *tp; +void completed(struct type *tp) { register struct type *atp = tp->tp_array; register struct type *etp = tp; - switch(etp->tp_fund) { + switch (etp->tp_fund) + { case STRUCT: case UNION: case ENUM: - while (etp = etp->next) { - if (! etp->tp_sdef) etp->tp_sdef = tp->tp_sdef; + while (etp = etp->next) + { + if (!etp->tp_sdef) + etp->tp_sdef = tp->tp_sdef; etp->tp_size = tp->tp_size; etp->tp_align = tp->tp_align; } break; } - while (atp) { - if (atp->tp_nel >= 0) { + while (atp) + { + if (atp->tp_nel >= 0) + { atp->tp_size = atp->tp_nel * tp->tp_size; } atp = atp->next; diff --git a/lang/cem/cemcom.ansi/type.str b/lang/cem/cemcom.ansi/type.str index 8796d61a4..b98ffbb6c 100644 --- a/lang/cem/cemcom.ansi/type.str +++ b/lang/cem/cemcom.ansi/type.str @@ -4,8 +4,13 @@ */ /* $Id$ */ /* TYPE DESCRIPTOR */ +#ifndef TYPE_H_ +#define TYPE_H_ #include "parameters.h" +#include "arith.h" + + struct type { struct type *next; /* used for ARRAY and for qualifiers */ @@ -59,13 +64,6 @@ struct type { #define TQ_VOLATILE 0x01 #define TQ_CONST 0x02 -extern struct type - *create_type(), *standard_type(), *construct_type(), *pointer_to(), - *array_of(), *function_of(), *promoted_type(); - -#ifndef NOBITFIELD -extern struct type *field_of(); -#endif /* NOBITFIELD */ extern struct type *schar_type, *uchar_type, @@ -79,6 +77,24 @@ extern struct type extern struct type *pa_type; /* type.c */ -extern arith size_of_type(), align(); +struct type *create_type(int fund); +struct type *promoted_type(struct type *tp); +struct type *construct_type(int fund, register struct type *tp, int qual, +arith count, /* for fund == ARRAY only */ + register struct proto *pl); +struct type *function_of(register struct type *tp, struct proto *pl, int qual); +struct type *pointer_to(register struct type *tp, int qual); +struct type * array_of(register struct type *tp, arith count, int qual); +#ifndef NOBITFIELD +struct type * field_of(register struct type *tp, int qual); +#endif /* NOBITFIELD */ +arith size_of_type(struct type *tp, char nm[]); +void idf2type(struct idf *idf, struct type **tpp); +arith align(arith pos, int al); +struct type * standard_type(int fund, int sgn, int algn, arith sz); +void completed(struct type *tp); + /* ALLOCDEF "type" 50 */ + +#endif \ No newline at end of file diff --git a/lang/cem/cemcom.ansi/util.c b/lang/cem/cemcom.ansi/util.c index 273fa8d78..6d3f084bf 100644 --- a/lang/cem/cemcom.ansi/util.c +++ b/lang/cem/cemcom.ansi/util.c @@ -41,16 +41,14 @@ static int loc_id; extern char options[]; -LocalInit() +void LocalInit(void) { #ifdef USE_TMP C_insertpart(loc_id = C_getid()); #endif /* USE_TMP */ } -arith -LocalSpace(sz, al) - arith sz; +arith LocalSpace(arith sz, int al) { register struct stack_level *stl = local_level; @@ -61,9 +59,7 @@ LocalSpace(sz, al) #define TABSIZ 32 static struct localvar *regs[TABSIZ]; -arith -NewLocal(sz, al, regtype, sc) - arith sz; +arith NewLocal(arith sz, int al, int regtype, int sc) { register struct localvar *tmp = FreeTmps; struct localvar *prev = 0; @@ -98,8 +94,7 @@ NewLocal(sz, al, regtype, sc) return tmp->t_offset; } -FreeLocal(off) - arith off; +void FreeLocal(arith off) { int index = (int) (off >> 2) & (TABSIZ - 1); register struct localvar *tmp = regs[index]; @@ -117,7 +112,7 @@ FreeLocal(off) } } -LocalFinish() +void LocalFinish(void) { register struct localvar *tmp, *tmp1; register int i; @@ -163,9 +158,7 @@ LocalFinish() #endif } -void -RegisterAccount(offset, size, regtype, sc) - arith offset, size; +void RegisterAccount(arith offset, arith size, int regtype, int sc) { register struct localvar *p; int index; @@ -183,9 +176,7 @@ RegisterAccount(offset, size, regtype, sc) regs[index] = p; } -static struct localvar * -find_reg(off) - arith off; +static struct localvar *find_reg(arith off) { register struct localvar *p = regs[(int)(off >> 2) & (TABSIZ - 1)]; @@ -193,8 +184,7 @@ find_reg(off) return p; } -LoadLocal(off, sz) - arith off, sz; +void LoadLocal(arith off, arith sz) { register struct localvar *p = find_reg(off); @@ -213,8 +203,7 @@ LoadLocal(off, sz) } } -StoreLocal(off, sz) - arith off, sz; +void StoreLocal(arith off, arith sz) { register struct localvar *p = find_reg(off); @@ -234,8 +223,7 @@ StoreLocal(off, sz) } #ifndef LINT -AddrLocal(off) - arith off; +void AddrLocal(arith off) { register struct localvar *p = find_reg(off); diff --git a/lang/cem/cemcom.ansi/util.str b/lang/cem/cemcom.ansi/util.str index 886432343..1e3855e3c 100644 --- a/lang/cem/cemcom.ansi/util.str +++ b/lang/cem/cemcom.ansi/util.str @@ -1,3 +1,8 @@ +#ifndef UTIL_H_ +#define UTIL_H_ + +#include "arith.h" + struct localvar { struct localvar *next; arith t_offset; /* offset from LocalBase */ @@ -9,3 +14,18 @@ struct localvar { }; /* ALLOCDEF "localvar" 10 */ + +void LocalInit(void); +arith LocalSpace(arith sz, int al); +arith NewLocal(arith sz, int al, int regtype, int sc); +void FreeLocal(arith off); +void LocalFinish(void); +void RegisterAccount(arith offset, arith size, int regtype, int sc); +void LoadLocal(arith off, arith sz); +void StoreLocal(arith off, arith sz); + +#ifndef LINT +void AddrLocal(arith off); +#endif + +#endif \ No newline at end of file diff --git a/lang/cem/cpp.ansi/ch3bin.h b/lang/cem/cpp.ansi/ch3bin.h new file mode 100644 index 000000000..ba84e0937 --- /dev/null +++ b/lang/cem/cpp.ansi/ch3bin.h @@ -0,0 +1,15 @@ +/* Copyright (c) 2019 ACK Project. + * See the copyright notice in the ACK home directory, + * in the file "Copyright". + * + * Created on: 2019-02-09 + * + */ +#ifndef CH3BIN_H_ +#define CH3BIN_H_ + +#include "arith.h" + +void ch3bin(register arith *pval, int *pis_uns, int oper, register arith val, int is_uns); + +#endif /* CH3BIN_H_ */ diff --git a/lang/cem/cpp.ansi/ch3mon.h b/lang/cem/cpp.ansi/ch3mon.h new file mode 100644 index 000000000..fd715c4a3 --- /dev/null +++ b/lang/cem/cpp.ansi/ch3mon.h @@ -0,0 +1,15 @@ +/* Copyright (c) 2019 ACK Project. + * See the copyright notice in the ACK home directory, + * in the file "Copyright". + * + * Created on: 2019-02-09 + * + */ +#ifndef CH3MON_H_ +#define CH3MON_H_ + +#include "arith.h" + +void ch3mon(int oper, register arith *pval, int *puns); + +#endif /* CH3MON_H_ */ diff --git a/lang/cem/cpp.ansi/domacro.h b/lang/cem/cpp.ansi/domacro.h new file mode 100644 index 000000000..7bdc7a465 --- /dev/null +++ b/lang/cem/cpp.ansi/domacro.h @@ -0,0 +1,27 @@ +/* Copyright (c) 2019 ACK Project. + * See the copyright notice in the ACK home directory, + * in the file "Copyright". + * + * Created on: 2019-02-09 + * + */ +#ifndef DOMACRO_H_ +#define DOMACRO_H_ + +struct idf; + +void macro_def(register struct idf* id, char* text, int nformals, int length, int flags); +void do_undef(char* argstr); +/* Control line interpreter. The '#' has already + been read by the lexical analyzer by which this function is called. + The token appearing directly after the '#' is obtained by calling + the basic lexical analyzing function GetToken() and is interpreted + to perform the action belonging to that token. + An error message is produced when the token is not recognized. + Pragma's are handled by do_pragma(). They are passed on to the + compiler. +*/ +void domacro(void); +char* GetIdentifier(int skiponerr); + +#endif /* DOMACRO_H_ */ diff --git a/lang/cem/cpp.ansi/error.h b/lang/cem/cpp.ansi/error.h new file mode 100644 index 000000000..4a8275274 --- /dev/null +++ b/lang/cem/cpp.ansi/error.h @@ -0,0 +1,42 @@ +/* Copyright (c) 2019 ACK Project. + * See the copyright notice in the ACK home directory, + * in the file "Copyright". + * + * Created on: 2019-02-09 + * + */ +#ifndef ERROR_H_ +#define ERROR_H_ + +#if __STDC__ +/*VARARGS*/ +void error(char *fmt, ...); +/*VARARGS*/ +void warning(char *fmt, ...); +/*VARARGS*/ +void strict(char *fmt, ...); +/*VARARGS*/ +void crash(char *fmt, ...); +/*VARARGS*/ +void fatal(char *fmt, ...); +#else +/*VARARGS*/ +void error(va_alist); + va_dcl + +/*VARARGS*/ +void warning(va_alist); + va_dcl + +/*VARARGS*/ +void strict(va_alist); + va_dcl +/*VARARGS*/ +void crash(va_alist); + va_dcl +/*VARARGS*/ +void fatal(va_alist); + va_dcl +#endif + +#endif /* ERROR_H_ */ diff --git a/lang/cem/cpp.ansi/expr.h b/lang/cem/cpp.ansi/expr.h new file mode 100644 index 000000000..b4c7d9b75 --- /dev/null +++ b/lang/cem/cpp.ansi/expr.h @@ -0,0 +1,14 @@ +/* Copyright (c) 2019 ACK Project. + * See the copyright notice in the ACK home directory, + * in the file "Copyright". + * + * Created on: 2019-02-09 + * + */ +#ifndef EXPR_H_ +#define EXPR_H_ + +/* The rank of the operator oper is returned. */ +int rank_of(int oper); + +#endif /* EXPR_H_ */ diff --git a/lang/cem/cpp.ansi/init.h b/lang/cem/cpp.ansi/init.h new file mode 100644 index 000000000..134c9d34e --- /dev/null +++ b/lang/cem/cpp.ansi/init.h @@ -0,0 +1,13 @@ +/* Copyright (c) 2019 ACK Project. + * See the copyright notice in the ACK home directory, + * in the file "Copyright". + * + * Created on: 2019-02-09 + * + */ +#ifndef INIT_H_ +#define INIT_H_ + +void init_pp(void); + +#endif /* INIT_H_ */ diff --git a/lang/cem/cpp.ansi/options.h b/lang/cem/cpp.ansi/options.h new file mode 100644 index 000000000..4149da026 --- /dev/null +++ b/lang/cem/cpp.ansi/options.h @@ -0,0 +1,13 @@ +/* Copyright (c) 2019 ACK Project. + * See the copyright notice in the ACK home directory, + * in the file "Copyright". + * + * Created on: 2019-02-09 + * + */ +#ifndef OPTIONS_H_ +#define OPTIONS_H_ + +void do_option(char *text); + +#endif /* OPTIONS_H_ */ diff --git a/lang/cem/cpp.ansi/preprocess.h b/lang/cem/cpp.ansi/preprocess.h new file mode 100644 index 000000000..97dea03b3 --- /dev/null +++ b/lang/cem/cpp.ansi/preprocess.h @@ -0,0 +1,14 @@ +/* Copyright (c) 2019 ACK Project. + * See the copyright notice in the ACK home directory, + * in the file "Copyright". + * + * Created on: 2019-02-09 + * + */ +#ifndef PREPROCESS_H_ +#define PREPROCESS_H_ + +void do_pragma(void); +void preprocess(char *fn); + +#endif /* PREPROCESS_H_ */ diff --git a/lang/cem/cpp.ansi/skip.h b/lang/cem/cpp.ansi/skip.h new file mode 100644 index 000000000..d32a7be96 --- /dev/null +++ b/lang/cem/cpp.ansi/skip.h @@ -0,0 +1,18 @@ +/* Copyright (c) 2019 ACK Project. + * See the copyright notice in the ACK home directory, + * in the file "Copyright". + * + * Created on: 2019-02-09 + * + */ +#ifndef SKIP_H_ +#define SKIP_H_ + +int SkipToNewLine(void); +/* Skips skips any white space and returns the first + non-space character. + */ +int skipspaces(register int ch, int skipnl); + + +#endif /* SKIP_H_ */ diff --git a/lang/m2/comp/defmodule.c b/lang/m2/comp/defmodule.c index b778d7cb2..b8dd8879c 100644 --- a/lang/m2/comp/defmodule.c +++ b/lang/m2/comp/defmodule.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "LLlex.h" @@ -32,7 +33,7 @@ #include "type.h" #ifdef DEBUG -long sys_filesize(); +size_t sys_filesize(); #endif t_idf* DefId; diff --git a/modules/src/alloc/Amake.srclist b/modules/src/alloc/Amake.srclist index 377a0a5ba..829f2183b 100644 --- a/modules/src/alloc/Amake.srclist +++ b/modules/src/alloc/Amake.srclist @@ -1,13 +1,13 @@ -L_ACK_MODULES_ALLOC = { - $PWD/Malloc.c, - $PWD/Salloc.c, - $PWD/Srealloc.c, - $PWD/Realloc.c, - $PWD/botch.c, - $PWD/clear.c, - $PWD/st_alloc.c, - $PWD/std_alloc.c, - $PWD/No_Mem.c, - $PWD/alloc.h -}; - +L_ACK_MODULES_ALLOC = { + $PWD/Malloc.c, + $PWD/Salloc.c, + $PWD/Srealloc.c, + $PWD/Realloc.c, + $PWD/botch.c, + $PWD/clear.c, + $PWD/st_alloc.c, + $PWD/std_alloc.c, + $PWD/No_Mem.c, + $PWD/alloc.h +}; + diff --git a/modules/src/alloc/Malloc.c b/modules/src/alloc/Malloc.c index 6077829ba..567b2dc08 100644 --- a/modules/src/alloc/Malloc.c +++ b/modules/src/alloc/Malloc.c @@ -17,9 +17,7 @@ extern char *malloc(); #endif #include "alloc.h" -char * -Malloc(sz) - unsigned int sz; +char *Malloc(unsigned int sz) { register char *res = malloc(sz); diff --git a/modules/src/alloc/No_Mem.c b/modules/src/alloc/No_Mem.c index 8011c1fdc..2cd3fd066 100644 --- a/modules/src/alloc/No_Mem.c +++ b/modules/src/alloc/No_Mem.c @@ -1,14 +1,15 @@ /* $Id$ */ /* * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. + * See the copyright notice in the ACK home directory, in the file "Copyright". */ -#include +#include +#include #include "alloc.h" -void -No_Mem() +void No_Mem(void) { - sys_write(STDERR, "Out of memory\n", 14); - sys_stop(S_EXIT); + fprintf(stderr,"Out of memory\n"); + exit(1); } diff --git a/modules/src/alloc/Realloc.c b/modules/src/alloc/Realloc.c index 0399dc0aa..35c6fbf1d 100644 --- a/modules/src/alloc/Realloc.c +++ b/modules/src/alloc/Realloc.c @@ -19,10 +19,7 @@ extern char *realloc(); #include "alloc.h" -char * -Realloc(ptr, sz) - char ptr[]; - unsigned int sz; +char *Realloc(char ptr[], unsigned int sz) { register char *mptr; diff --git a/modules/src/alloc/Salloc.c b/modules/src/alloc/Salloc.c index 7f98690d0..1422b1878 100644 --- a/modules/src/alloc/Salloc.c +++ b/modules/src/alloc/Salloc.c @@ -19,10 +19,7 @@ extern char *malloc(); #include "alloc.h" -char * -Salloc(str, sz) - register char *str; - register unsigned int sz; +char *Salloc(register char *str, register unsigned int sz) { /* Salloc() is not a primitive function: it just allocates a piece of storage and copies a given string into it. diff --git a/modules/src/alloc/Srealloc.c b/modules/src/alloc/Srealloc.c index d799f6f8e..32ddf9a92 100644 --- a/modules/src/alloc/Srealloc.c +++ b/modules/src/alloc/Srealloc.c @@ -12,10 +12,7 @@ #include "alloc.h" -char * -Srealloc(str, sz) - char str[]; - unsigned int sz; +char *Srealloc(char str[], unsigned int sz) { return Realloc(str, sz); } diff --git a/modules/src/alloc/alloc.3 b/modules/src/alloc/alloc.3 index f7c963cad..cd7bfbf5e 100644 --- a/modules/src/alloc/alloc.3 +++ b/modules/src/alloc/alloc.3 @@ -1,107 +1,82 @@ -.TH ALLOC 3 "$Revision$" -.ad -.SH NAME -Malloc, Salloc, Realloc, Srealloc, st_alloc, st_free\ \-\ low level memory allocation routines -.SH SYNOPSIS -.B #include -.PP -.B char *Malloc(size) -.br -.B unsigned int size; -.PP -.B char *Salloc(str, size) -.br -.B char *str; -.B unsigned int size; -.PP -.B char *Realloc(ptr, size) -.B char *buf; -.B unsigned int size; -.PP -.B char *Srealloc(str, size) -.br -.B char *str; -.br -.B unsigned int size; -.PP -.B char *st_alloc(phead, size, count) -.br -.B char **phead; -.br -.B unsigned int size; -.PP -.B st_free(ptr, phead, size) -.br -.B char *ptr; -.br -.B char **phead; -.br -.B unsigned int size; -.PP -.B void clear(ptr, size) -.br -.B char *ptr; -.br -.B unsigned int size; -.PP -.void No_Mem() -.PP -.SH DESCRIPTION -This set of routines provides a checking memory allocation mechanism. -.PP -\fIMalloc\fR returns a pointer to a block of at least \fIsize\fR -bytes, beginning on a boundary suitable for any data type. -.PP -\fISalloc\fR returns a pointer to a block of at least \fIsize\fR -bytes, initialized with the null-terminated string \fIstr\fR. -.PP -\fIRealloc\fR changes the size of -the block at \fIbuf\fR to \fIsize\fR bytes, and returns a pointer to the -(possibly moved) block. If \fIbuf\fP is a null pointer, \fIRealloc\fP -behaves as \fIMalloc\fP. -.PP -\fISrealloc\fR reallocates -the string at \fIstr\fR to \fIsize\fR bytes. -It actually does the same as \fIRealloc\fP, and exists only for -backwards compatibility. -.PP -All these routines use \fImalloc\fR and \fIrealloc\fR. -The routine \fIfree\fR can be used on pointers returned by these routines. -.PP -\fISt_alloc\fR and \fIst_free\fR provide a mechanism for maintaining free lists -of structures. -\fISt_alloc\fR takes three parameters: \fIphead\fR is a pointer to a field -containing the head of the free list, \fIsize\fR contains the size of the -structures, and \fIcount\fR indicates how many new structures must be allocated -in case the free list is exhausted. -It returns a pointer to a zero-initialized structure. -\fISt_free\fR also takes three parameters: \fIptr\fR is a pointer to -the structure to be freed, \fIphead\fR is again a pointer to a field -containing the head of the free list, and \fIsize\fR again contains the size -of the structures. -These last two routines are best used in a macro. -.PP -\fIClear\fR clears \fIsize\fR bytes, starting at \fIptr\fR. -.SH FILES -.nf -~em/modules/h/alloc.h -~em/modules/lib/liballoc.a -.fi -.SH "MODULES USED" -system(3) -.SH "SEE ALSO" -malloc(3) -.SH DIAGNOSTICS -\fIMalloc\fR, \fISalloc\fR, \fIRealloc\fP, \fISrealloc\fR, and \fIst_alloc\fR -call a routine \fINo_Mem\fR if there is no memory available. This routine -is not supposed to return. A default one, that -gives an error message and stops execution, is provided. -.SH BUGS -The -.I st_alloc -mechanism only works for structures that are large enough to contain one -pointer. -Also, -.I st_free -actually is a macro, and references its arguments more than once, so they -better not have side-effects. +.TH ALLOC 3 "$Revision$" +.ad +.SH NAME +Malloc, Salloc, Realloc, Srealloc, st_alloc, st_free\ \-\ low level memory allocation routines +.SH SYNOPSIS +.B #include +.PP +.B char *Malloc(unsigned int size) +.PP +.B char *Salloc(char *str, unsigned int size) +.PP +.B char *Realloc(char *buf, unsigned int size) +.PP +.B char *Srealloc(char *str, unsigned int size) +.PP +.B char *st_alloc(char **phead, unsigned int size, int count) +.PP +.B st_free(char *ptr, char **phead, unsigned int size) +.PP +.B void clear(char *ptr, unsigned int size) +.PP +.void No_Mem() +.PP +.SH DESCRIPTION +This set of routines provides a checking memory allocation mechanism. +.PP +\fIMalloc\fR returns a pointer to a block of at least \fIsize\fR +bytes, beginning on a boundary suitable for any data type. +.PP +\fISalloc\fR returns a pointer to a block of at least \fIsize\fR +bytes, initialized with the null-terminated string \fIstr\fR. +.PP +\fIRealloc\fR changes the size of +the block at \fIbuf\fR to \fIsize\fR bytes, and returns a pointer to the +(possibly moved) block. If \fIbuf\fP is a null pointer, \fIRealloc\fP +behaves as \fIMalloc\fP. +.PP +\fISrealloc\fR reallocates +the string at \fIstr\fR to \fIsize\fR bytes. +It actually does the same as \fIRealloc\fP, and exists only for +backwards compatibility. +.PP +All these routines use \fImalloc\fR and \fIrealloc\fR. +The routine \fIfree\fR can be used on pointers returned by these routines. +.PP +\fISt_alloc\fR and \fIst_free\fR provide a mechanism for maintaining free lists +of structures. +\fISt_alloc\fR takes three parameters: \fIphead\fR is a pointer to a field +containing the head of the free list, \fIsize\fR contains the size of the +structures, and \fIcount\fR indicates how many new structures must be allocated +in case the free list is exhausted. +It returns a pointer to a zero-initialized structure. +\fISt_free\fR also takes three parameters: \fIptr\fR is a pointer to +the structure to be freed, \fIphead\fR is again a pointer to a field +containing the head of the free list, and \fIsize\fR again contains the size +of the structures. +These last two routines are best used in a macro. +.PP +\fIClear\fR clears \fIsize\fR bytes, starting at \fIptr\fR. +.SH FILES +.nf +~em/modules/h/alloc.h +~em/modules/lib/liballoc.a +.fi +.SH "MODULES USED" +system(3) +.SH "SEE ALSO" +malloc(3) +.SH DIAGNOSTICS +\fIMalloc\fR, \fISalloc\fR, \fIRealloc\fP, \fISrealloc\fR, and \fIst_alloc\fR +call a routine \fINo_Mem\fR if there is no memory available. This routine +is not supposed to return. A default one, that +gives an error message and stops execution, is provided. +.SH BUGS +The +.I st_alloc +mechanism only works for structures that are large enough to contain one +pointer. +Also, +.I st_free +actually is a macro, and references its arguments more than once, so they +better not have side-effects. diff --git a/modules/src/alloc/botch.c b/modules/src/alloc/botch.c index 0365f75df..094627252 100644 --- a/modules/src/alloc/botch.c +++ b/modules/src/alloc/botch.c @@ -9,10 +9,7 @@ #include "alloc.h" -void -botch(ptr, n) - register char *ptr; - register unsigned int n; +void botch(register char *ptr, register unsigned int n) { while (n >= sizeof (long)) { /* high-speed botch loop */ diff --git a/modules/src/alloc/clear.c b/modules/src/alloc/clear.c index 40642238d..4cf0c87de 100644 --- a/modules/src/alloc/clear.c +++ b/modules/src/alloc/clear.c @@ -10,10 +10,7 @@ /* instead of Calloc: */ -void -clear(ptr, n) - register char *ptr; - register unsigned int n; +void clear(register char *ptr, register unsigned int n) { register long *q = (long *) ptr; diff --git a/modules/src/alloc/st_alloc.c b/modules/src/alloc/st_alloc.c index 704b853a6..0457420cc 100644 --- a/modules/src/alloc/st_alloc.c +++ b/modules/src/alloc/st_alloc.c @@ -12,16 +12,16 @@ #include #else extern char *malloc(); +#ifndef NULL +#define NULL 0 +#endif #endif #include "alloc.h" -char * -st_alloc(phead, size, count) - char **phead; - register unsigned int size; +char *st_alloc(char **phead, register unsigned int size, int count) { - register char *p; + register char *p = NULL; register long *q; char *retval; @@ -29,7 +29,7 @@ st_alloc(phead, size, count) while (count >= 1 && (p = malloc(size * count)) == 0) { count >>= 1; } - if (p == 0) { + if (p == NULL) { No_Mem(); } ((_PALLOC_) p)->_A_next = 0; diff --git a/modules/src/alloc/std_alloc.c b/modules/src/alloc/std_alloc.c index 1628c9f55..c66eb8d11 100644 --- a/modules/src/alloc/std_alloc.c +++ b/modules/src/alloc/std_alloc.c @@ -17,11 +17,7 @@ extern char *malloc(); #include "alloc.h" -char * -std_alloc(phead, size, count, pcnt) - char **phead; - register unsigned int size; - int *pcnt; +char *std_alloc(char **phead, register unsigned int size, int count, int *pcnt) { register char *p; register long *q; diff --git a/modules/src/em_code/C_out.c b/modules/src/em_code/C_out.c index 135934096..f03c10c45 100644 --- a/modules/src/em_code/C_out.c +++ b/modules/src/em_code/C_out.c @@ -9,25 +9,22 @@ /* $Id$ */ -static arg(); -static pseudo(); +static void arg(struct e_instr *p, int comma); +static void pseudo(struct e_instr *p); extern char em_flag[]; char *C_error; #define flags(pp) (em_flag[(pp)->em_opcode - sp_fmnem] & EM_PAR) -struct e_instr * -C_alloc() +struct e_instr *C_alloc(void) { static struct e_instr b; return &b; } -int -C_out(p) - register struct e_instr *p; +int C_out(register struct e_instr *p) { /* Generate EM-code from the e_instr structure "p" */ @@ -82,9 +79,7 @@ C_out(p) return 1; } -static -arg(p, comma) - register struct e_instr *p; +static void arg(register struct e_instr *p, int comma) { /* Output the argument of "p". */ @@ -145,9 +140,7 @@ arg(p, comma) } } -static -pseudo(p) - register struct e_instr *p; +static void pseudo(register struct e_instr *p) { PS(p->em_opcode); diff --git a/modules/src/em_code/bhcst.c b/modules/src/em_code/bhcst.c index a49ab59f0..63edd1b35 100644 --- a/modules/src/em_code/bhcst.c +++ b/modules/src/em_code/bhcst.c @@ -2,11 +2,7 @@ /* $Id$ */ -void -CC_bhcst(op, n, w, i) - arith n; - arith w; - int i; +void CC_bhcst(int op, arith n, arith w, int i) { /* BSS or HOL with size n, initial value a cst w, and flag i */ diff --git a/modules/src/em_code/bhdlb.c b/modules/src/em_code/bhdlb.c index 702960aa0..881331940 100644 --- a/modules/src/em_code/bhdlb.c +++ b/modules/src/em_code/bhdlb.c @@ -2,12 +2,7 @@ /* $Id$ */ -void -CC_bhdlb(op, n, s, off, i) - arith n; - label s; - arith off; - int i; +void CC_bhdlb(int op, arith n, label s, arith off, int i) { /* BSS or HOL with size n, initial value a dlb(s, off), and flag i diff --git a/modules/src/em_code/bhdnam.c b/modules/src/em_code/bhdnam.c index d47465c22..f73f85f36 100644 --- a/modules/src/em_code/bhdnam.c +++ b/modules/src/em_code/bhdnam.c @@ -2,12 +2,7 @@ /* $Id$ */ -void -CC_bhdnam(op, n, s, off, i) - arith n; - char *s; - arith off; - int i; +void CC_bhdnam(int op, arith n, char *s, arith off, int i) { /* BSS or HOL with size n, initial value a dnam(s, off), and flag i diff --git a/modules/src/em_code/bhfcon.c b/modules/src/em_code/bhfcon.c index 9c9284596..3d31be776 100644 --- a/modules/src/em_code/bhfcon.c +++ b/modules/src/em_code/bhfcon.c @@ -2,12 +2,7 @@ /* $Id$ */ -void -CC_bhfcon(op, n, s, sz, i) - arith n; - char *s; - arith sz; - int i; +void CC_bhfcon(int op, arith n, char *s, arith sz, int i) { /* BSS or HOL with size n, initial value an FCON (s, sz), and flag i diff --git a/modules/src/em_code/bhicon.c b/modules/src/em_code/bhicon.c index b6bf6ac82..21dda2aea 100644 --- a/modules/src/em_code/bhicon.c +++ b/modules/src/em_code/bhicon.c @@ -2,12 +2,7 @@ /* $Id$ */ -void -CC_bhicon(op, n, s, sz, i) - arith n; - char *s; - arith sz; - int i; +void CC_bhicon(int op, arith n, char *s, arith sz, int i) { /* BSS or HOL with size n, initial value an ICON (s, sz), and flag i diff --git a/modules/src/em_code/bhilb.c b/modules/src/em_code/bhilb.c index eba7457c6..df03fdb5e 100644 --- a/modules/src/em_code/bhilb.c +++ b/modules/src/em_code/bhilb.c @@ -2,11 +2,7 @@ /* $Id$ */ -void -CC_bhilb(op, n, l, i) - arith n; - label l; - int i; +void CC_bhilb(int op, arith n, label l, int i) { /* BSS or HOL with size n, initial value a ILB(l), and flag i diff --git a/modules/src/em_code/bhpnam.c b/modules/src/em_code/bhpnam.c index 3f9a8d6ad..e3f80e3e9 100644 --- a/modules/src/em_code/bhpnam.c +++ b/modules/src/em_code/bhpnam.c @@ -2,11 +2,7 @@ /* $Id$ */ -void -CC_bhpnam(op, n, p, i) - arith n; - char *p; - int i; +void CC_bhpnam(int op, arith n, char *p, int i) { /* BSS or HOL with size n, initial value a PNAM(p), and flag i diff --git a/modules/src/em_code/bhucon.c b/modules/src/em_code/bhucon.c index de18fe9e4..66716916c 100644 --- a/modules/src/em_code/bhucon.c +++ b/modules/src/em_code/bhucon.c @@ -2,12 +2,7 @@ /* $Id$ */ -void -CC_bhucon(op, n, s, sz, i) - arith n; - char *s; - arith sz; - int i; +void CC_bhucon(int op, arith n, char *s, arith sz, int i) { /* BSS or HOL with size n, initial value an UCON (s, sz), and flag i diff --git a/modules/src/em_code/build.lua b/modules/src/em_code/build.lua index 3a82234cb..b65ce83ca 100644 --- a/modules/src/em_code/build.lua +++ b/modules/src/em_code/build.lua @@ -89,6 +89,7 @@ local function build_variant(code, cflags) "modules+headers", "modules/src/alloc+lib", "modules/src/em_data+lib", + "modules/src/print+lib", "modules/src/system+lib", }, vars = { diff --git a/modules/src/em_code/crcst.c b/modules/src/em_code/crcst.c index 6bacdb312..8e3f59444 100644 --- a/modules/src/em_code/crcst.c +++ b/modules/src/em_code/crcst.c @@ -2,9 +2,7 @@ /* $Id$ */ -void -CC_crcst(op, v) - arith v; +void CC_crcst(int op, arith v) { /* CON or ROM with argument CST(v) */ diff --git a/modules/src/em_code/crdlb.c b/modules/src/em_code/crdlb.c index 0cafe9f3a..032bdd07f 100644 --- a/modules/src/em_code/crdlb.c +++ b/modules/src/em_code/crdlb.c @@ -2,10 +2,7 @@ /* $Id$ */ -void -CC_crdlb(op, v, off) - label v; - arith off; +void CC_crdlb(int op, label v, arith off) { /* CON or ROM with argument DLB(v, off) */ diff --git a/modules/src/em_code/crdnam.c b/modules/src/em_code/crdnam.c index c8ec92da8..d7be5506a 100644 --- a/modules/src/em_code/crdnam.c +++ b/modules/src/em_code/crdnam.c @@ -2,10 +2,7 @@ /* $Id$ */ -void -CC_crdnam(op, s, off) - char *s; - arith off; +void CC_crdnam(int op, char* s, arith off) { /* CON or ROM with argument DNAM(s, off) */ diff --git a/modules/src/em_code/crilb.c b/modules/src/em_code/crilb.c index d0db218ec..cae0774c8 100644 --- a/modules/src/em_code/crilb.c +++ b/modules/src/em_code/crilb.c @@ -2,9 +2,7 @@ /* $Id$ */ -void -CC_crilb(op, l) - label l; +void CC_crilb(int op, label l) { /* CON or ROM with argument ILB(l) */ diff --git a/modules/src/em_code/crpnam.c b/modules/src/em_code/crpnam.c index 24c4c491f..1fdc41d20 100644 --- a/modules/src/em_code/crpnam.c +++ b/modules/src/em_code/crpnam.c @@ -2,9 +2,7 @@ /* $Id$ */ -void -CC_crpnam(op, p) - char *p; +void CC_crpnam(int op, char* p) { /* CON or ROM with argument PNAM(p) */ diff --git a/modules/src/em_code/crscon.c b/modules/src/em_code/crscon.c index eab953ef4..22c0fd809 100644 --- a/modules/src/em_code/crscon.c +++ b/modules/src/em_code/crscon.c @@ -2,10 +2,7 @@ /* $Id$ */ -void -CC_crscon(op, v, s) - char *v; - arith s; +void CC_crscon(int op, char* v, arith s) { /* CON or ROM with argument SCON(v,z) */ diff --git a/modules/src/em_code/crxcon.c b/modules/src/em_code/crxcon.c index 5fc706358..57b579f28 100644 --- a/modules/src/em_code/crxcon.c +++ b/modules/src/em_code/crxcon.c @@ -2,10 +2,7 @@ /* $Id$ */ -void -CC_crxcon(op, spec, v, s) - char *v; - arith s; +void CC_crxcon(int op, int spec, char* v, arith s) { /* CON or ROM with argument ICON(v,z) */ diff --git a/modules/src/em_code/cst.c b/modules/src/em_code/cst.c index 17cfdbc9f..7b81dccf4 100644 --- a/modules/src/em_code/cst.c +++ b/modules/src/em_code/cst.c @@ -2,9 +2,7 @@ /* $Id$ */ -void -CC_cst(l) - arith l; +void CC_cst(arith l) { COMMA(); CST(l); diff --git a/modules/src/em_code/dfdlb.c b/modules/src/em_code/dfdlb.c index eb9fbab09..90452f13e 100644 --- a/modules/src/em_code/dfdlb.c +++ b/modules/src/em_code/dfdlb.c @@ -2,9 +2,7 @@ /* $Id$ */ -void -CC_dfdlb(l) - label l; +void CC_dfdlb(label l) { /* Define numeric data label */ diff --git a/modules/src/em_code/dfdnam.c b/modules/src/em_code/dfdnam.c index 1f1478b73..bfcfbed12 100644 --- a/modules/src/em_code/dfdnam.c +++ b/modules/src/em_code/dfdnam.c @@ -2,9 +2,7 @@ /* $Id$ */ -void -CC_dfdnam(s) - char *s; +void CC_dfdnam(char* s) { /* Define data label */ diff --git a/modules/src/em_code/dfilb.c b/modules/src/em_code/dfilb.c index 4dd88a136..e0f0cb483 100644 --- a/modules/src/em_code/dfilb.c +++ b/modules/src/em_code/dfilb.c @@ -2,9 +2,7 @@ /* $Id$ */ -void -CC_dfilb(l) - label l; +void CC_dfilb(label l) { /* Define instruction label */ diff --git a/modules/src/em_code/dlb.c b/modules/src/em_code/dlb.c index 8f711eb9d..5f0cd288e 100644 --- a/modules/src/em_code/dlb.c +++ b/modules/src/em_code/dlb.c @@ -2,10 +2,7 @@ /* $Id$ */ -void -CC_dlb(l, val) - label l; - arith val; +void CC_dlb(label l, arith val) { COMMA(); DOFF(l, val); diff --git a/modules/src/em_code/dnam.c b/modules/src/em_code/dnam.c index 5c0532198..85ebfa6ad 100644 --- a/modules/src/em_code/dnam.c +++ b/modules/src/em_code/dnam.c @@ -2,10 +2,7 @@ /* $Id$ */ -void -CC_dnam(str, val) - char *str; - arith val; +void CC_dnam(char* str, arith val) { COMMA(); NOFF(str, val); diff --git a/modules/src/em_code/em.c b/modules/src/em_code/em.c index cf6948bff..407f0d0f2 100644 --- a/modules/src/em_code/em.c +++ b/modules/src/em_code/em.c @@ -12,7 +12,9 @@ #include #include #include +#include "system.h" #include "alloc.h" +#include "print.h" #include "em_arith.h" #include "insert.h" #include "em_private.h" @@ -49,8 +51,8 @@ char *C_current_out = obuf; char *C_opp = obuf; #endif -void -C_flush() { +void C_flush(void) +{ #ifdef INCORE static unsigned int bufsiz; @@ -82,9 +84,7 @@ C_flush() { #define Xputbyte(c) put(c) #endif -void -C_putbyte(c) - int c; +void C_putbyte(int c) { Xputbyte(c); } @@ -94,15 +94,11 @@ C_putbyte(c) #endif /*ARGSUSED*/ -void -C_init(w, p) - arith w, p; +void C_init(arith w, arith p) { } -int -C_open(nm) - char *nm; +int C_open(char* nm) { /* Open file "nm" for output */ @@ -110,13 +106,15 @@ C_open(nm) if (nm == 0) C_ofp = STDOUT; /* standard output */ else - if (sys_open(nm, OP_WRITE, &C_ofp) == 0) + { + + if (sys_open(nm, OP_WRITE, &C_ofp) == 0) return 0; + } return 1; } -void -C_close() +void C_close(void) { /* Finish the code-generation. */ @@ -150,8 +148,7 @@ C_close() C_ofp = 0; } -int -C_busy() +int C_busy(void) { return C_ofp != 0; /* true if code is being generated */ } @@ -165,32 +162,27 @@ C_busy() names. */ -void -C_magic() +void C_magic(void) { } /*** the readable code generating routines ***/ -static -wrs(s) - register char *s; +static int wrs(register char *s) { - while (*s) { + while (*s) + { C_putbyte(*s++); } + return 0; } -void -C_pt_dnam(s) - char *s; +void C_pt_dnam(char* s) { wrs(s); } -void -C_pt_ilb(l) - label l; +void C_pt_ilb(label l) { char buf[16]; @@ -201,17 +193,14 @@ C_pt_ilb(l) extern char em_mnem[][4]; extern char em_pseu[][4]; -void -C_pt_op(x) +void C_pt_op(int x) { C_putbyte(' '); wrs(em_mnem[x - sp_fmnem]); C_putbyte(' '); } -void -C_pt_cst(l) - arith l; +void C_pt_cst(arith l) { char buf[16]; @@ -219,10 +208,7 @@ C_pt_cst(l) wrs(buf); } -void -C_pt_scon(x, y) - char *x; - arith y; +void C_pt_scon(char *x, arith y) { char xbuf[1024]; register char *p; @@ -239,17 +225,14 @@ C_pt_scon(x, y) C_putbyte('\''); } -void -C_pt_ps(x) +void C_pt_ps(int x) { C_putbyte(' '); wrs(em_pseu[x - sp_fpseu]); C_putbyte(' '); } -void -C_pt_dlb(l) - label l; +void C_pt_dlb(label l) { char buf[16]; @@ -257,10 +240,7 @@ C_pt_dlb(l) wrs(buf); } -void -C_pt_doff(l, v) - label l; - arith v; +void C_pt_doff(label l, arith v) { char buf[16]; @@ -271,10 +251,7 @@ C_pt_doff(l, v) } } -void -C_pt_noff(s, v) - char *s; - arith v; +void C_pt_noff(char *s, arith v) { char buf[16]; @@ -285,17 +262,13 @@ C_pt_noff(s, v) } } -void -C_pt_pnam(s) - char *s; +void C_pt_pnam(char *s) { C_putbyte('$'); wrs(s); } -void -C_pt_dfilb(l) - label l; +void C_pt_dfilb(label l) { char buf[16]; @@ -303,11 +276,7 @@ C_pt_dfilb(l) wrs(buf); } -void -C_pt_wcon(sp, v, sz) /* sp_icon, sp_ucon or sp_fcon with int repr */ - int sp; - char *v; - arith sz; +void C_pt_wcon(int sp, char *v, arith sz) /* sp_icon, sp_ucon or sp_fcon with int repr */ { int ch = sp == sp_icon ? 'I' : sp == sp_ucon ? 'U' : 'F'; @@ -316,18 +285,18 @@ C_pt_wcon(sp, v, sz) /* sp_icon, sp_ucon or sp_fcon with int repr */ C_pt_cst(sz); } -void -C_pt_nl() { +void C_pt_nl(void) +{ C_putbyte('\n'); } -void -C_pt_comma() { +void C_pt_comma(void) +{ C_putbyte(','); } -void -C_pt_ccend() { +void C_pt_ccend(void) +{ C_putbyte('?'); } @@ -345,8 +314,7 @@ C_pt_ccend() { names. */ -void -C_magic() +void C_magic(void) { put16(sp_magic); } @@ -355,9 +323,7 @@ C_magic() #define fit16i(x) ((x) >= (long)(-0x8000) && (x) <= (long)0x7FFF) #define fit8u(x) ((x) <= 0xFF) /* x is already unsigned */ -void -C_pt_ilb(l) - register label l; +void C_pt_ilb(register label l) { if (fit8u(l)) { put8(sp_ilb1); @@ -369,9 +335,7 @@ C_pt_ilb(l) } } -void -C_pt_dlb(l) - register label l; +void C_pt_dlb(register label l) { if (fit8u(l)) { put8(sp_dlb1); @@ -383,9 +347,7 @@ C_pt_dlb(l) } } -void -C_pt_cst(l) - register arith l; +void C_pt_cst(register arith l) { if (l >= (arith) -sp_zcst0 && l < (arith) (sp_ncst0 - sp_zcst0)) { /* we can convert 'l' to an int because its value @@ -404,10 +366,7 @@ C_pt_cst(l) } } -void -C_pt_doff(l, v) - label l; - arith v; +void C_pt_doff(label l, arith v) { if (v == 0) { C_pt_dlb(l); @@ -419,9 +378,7 @@ C_pt_doff(l, v) } } -void -C_pt_str(s) - register char *s; +void C_pt_str(register char *s) { register int len; @@ -431,18 +388,13 @@ C_pt_str(s) } } -void -C_pt_dnam(s) - char *s; +void C_pt_dnam(char* s) { put8(sp_dnam); C_pt_str(s); } -void -C_pt_noff(s, v) - char *s; - arith v; +void C_pt_noff(char* s, arith v) { if (v == 0) { C_pt_dnam(s); @@ -454,19 +406,13 @@ C_pt_noff(s, v) } } -void -C_pt_pnam(s) - char *s; +void C_pt_pnam(char* s) { put8(sp_pnam); C_pt_str(s); } -void -C_pt_wcon(sp, v, sz) /* sp_icon, sp_ucon or sp_fcon with int repr */ - int sp; - char *v; - arith sz; +void C_pt_wcon(int sp, char* v, arith sz) /* sp_icon, sp_ucon or sp_fcon with int repr */ { /* how 'bout signextension int --> long ??? */ put8(sp); @@ -474,10 +420,7 @@ C_pt_wcon(sp, v, sz) /* sp_icon, sp_ucon or sp_fcon with int repr */ C_pt_str(v); } -void -C_pt_scon(b, n) - register char *b; - register arith n; +void C_pt_scon(register char *b, register arith n) { put8(sp_scon); C_pt_cst(n); diff --git a/modules/src/em_code/em_code.h b/modules/src/em_code/em_code.h index 26a3251a5..028e5ba14 100644 --- a/modules/src/em_code/em_code.h +++ b/modules/src/em_code/em_code.h @@ -5,6 +5,7 @@ */ #include "em_mesX.h" +#include "em_arith.h" #include "ansi.h" _PROTOTYPE(void C_ms_com, (char *)); @@ -24,6 +25,8 @@ _PROTOTYPE(void C_ms_stb_ilb, (char *, int, int, label)); _PROTOTYPE(void C_ms_stb_pnam, (char *, int, int, char *)); _PROTOTYPE(void C_ms_std, (char *, int, int)); + + #ifdef PEEPHOLE #include "em_codeO.h" #include "emO_code.h" diff --git a/modules/src/em_code/em_private.h b/modules/src/em_code/em_private.h index 45b80f572..b706d9bf5 100644 --- a/modules/src/em_code/em_private.h +++ b/modules/src/em_code/em_private.h @@ -5,16 +5,16 @@ */ /* private inclusion file */ -#include -#include +#include "em_arith.h" +#include "em_label.h" /* include the EM description files */ -#include -#include -#include -#include +#include "em_spec.h" +#include "em_pseu.h" +#include "em_mnem.h" +#include "em_reg.h" -#include +#include "ansi.h" #include "em_codeEK.h" @@ -79,6 +79,10 @@ _PROTOTYPE(void C_pt_noff, (char *, arith)); _PROTOTYPE(void C_pt_pnam, (char *)); _PROTOTYPE(void C_pt_dfilb, (label)); _PROTOTYPE(void C_pt_wcon, (int, char *, arith)); +_PROTOTYPE(void C_failed, (void)); +_PROTOTYPE(void C_flush, (void)); +_PROTOTYPE(void C_internal_error, (void)); +_PROTOTYPE(void C_putbyte, (int)); #ifdef READABLE_EM _PROTOTYPE(void C_pt_ps, (int)); _PROTOTYPE(void C_pt_op, (int)); diff --git a/modules/src/em_code/end.c b/modules/src/em_code/end.c index b5ac6496b..580751a25 100644 --- a/modules/src/em_code/end.c +++ b/modules/src/em_code/end.c @@ -2,9 +2,7 @@ /* $Id$ */ -void -CC_end(l) - arith l; +void CC_end(arith l) { /* END pseudo of procedure with l locals */ diff --git a/modules/src/em_code/endarg.c b/modules/src/em_code/endarg.c index 510fc48a2..f2b6320b4 100644 --- a/modules/src/em_code/endarg.c +++ b/modules/src/em_code/endarg.c @@ -2,8 +2,7 @@ /* $Id$ */ -void -CC_endnarg() +void CC_endnarg() { /* END pseudo of procedure with unknown # of locals */ diff --git a/modules/src/em_code/exc.c b/modules/src/em_code/exc.c index 3fe2b2568..905a902fb 100644 --- a/modules/src/em_code/exc.c +++ b/modules/src/em_code/exc.c @@ -2,9 +2,7 @@ /* $Id$ */ -void -CC_exc(c1,c2) - arith c1,c2; +void CC_exc(arith c1,arith c2) { PS(ps_exc); CST(c1); diff --git a/modules/src/em_code/fcon.c b/modules/src/em_code/fcon.c index c33731fbb..bdd9f9ea0 100644 --- a/modules/src/em_code/fcon.c +++ b/modules/src/em_code/fcon.c @@ -2,10 +2,7 @@ /* $Id$ */ -void -CC_fcon(val, siz) - char *val; - arith siz; +void CC_fcon(char* val, arith siz) { COMMA(); WCON(sp_fcon, val, siz); diff --git a/modules/src/em_code/getid.c b/modules/src/em_code/getid.c index 157b7e8c6..f8fb1f5fc 100644 --- a/modules/src/em_code/getid.c +++ b/modules/src/em_code/getid.c @@ -3,8 +3,7 @@ /* Get a unique id for C_insertpart, etc. */ -int -C_getid() +int C_getid(void) { static int id = 0; diff --git a/modules/src/em_code/icon.c b/modules/src/em_code/icon.c index bed0886e0..488382939 100644 --- a/modules/src/em_code/icon.c +++ b/modules/src/em_code/icon.c @@ -2,10 +2,7 @@ /* $Id$ */ -void -CC_icon(val, siz) - char *val; - arith siz; +void CC_icon(char* val, arith siz) { COMMA(); WCON(sp_icon, val, siz); diff --git a/modules/src/em_code/ilb.c b/modules/src/em_code/ilb.c index 6c4168075..b54c4bdb8 100644 --- a/modules/src/em_code/ilb.c +++ b/modules/src/em_code/ilb.c @@ -2,9 +2,7 @@ /* $Id$ */ -void -CC_ilb(l) - label l; +void CC_ilb(label l) { COMMA(); ILB(l); diff --git a/modules/src/em_code/insert.c b/modules/src/em_code/insert.c index 00c628dcb..2048d0414 100644 --- a/modules/src/em_code/insert.c +++ b/modules/src/em_code/insert.c @@ -11,11 +11,18 @@ #include #include -#include -#include +#include +#include +#include "em_private.h" +#include "system.h" +/*#include "em_path.h"*/ +#include "alloc.h" #include "insert.h" -char *C_tmpdir = TMP_DIR; +/* To make this portable, the initial value here is NULL + * and system is used to retrieve the correct directory + */ +char *C_tmpdir = NULL; static Part *C_stable[TABSIZ]; static char *C_old_top; @@ -58,12 +65,10 @@ getbyte(b) } #endif -static C_out_parts(); -static Part *C_findpart(); +static void C_out_parts(register PartOfPart *pp); +static Part *C_findpart(int part); -static -outpart(id) - int id; +static int outpart(int id) { /* Output part "id", if present. */ @@ -73,11 +78,10 @@ outpart(id) C_out_parts(p->p_parts); p->p_parts = 0; } + return 0; } -static -C_out_parts(pp) - register PartOfPart *pp; +static void C_out_parts(register PartOfPart *pp) { /* Output the list of chunks started by "pp". The list is build in reverse order, so this routine is @@ -119,9 +123,7 @@ C_out_parts(pp) } } -static Part * -C_findpart(part) - int part; +static Part *C_findpart(int part) { /* Look for part "part" in the table. Return 0 if not present, @@ -134,14 +136,22 @@ C_findpart(part) return p; } -static -swttmp() + + + +static int swttmp(void) { #ifndef INCORE - if (C_tmpfile == 0) { - static char tmpbuf[64]; + if (C_tmpfile == NULL) { + + static char tmpbuf[FILENAME_MAX]; register char *p = tmpbuf; + if (C_tmpdir == NULL) + { + C_tmpdir = sys_gettmpdir(); + assert(C_tmpdir != NULL); + } strcpy(p, C_tmpdir); strcat(p, "/CodeXXXXXX"); close(mkstemp(p)); @@ -175,10 +185,10 @@ swttmp() C_ontmpfile = 1; } #endif + return 0; } -static -swtout() +static int swtout(void) { #ifndef INCORE if (C_ontmpfile) { @@ -203,11 +213,10 @@ swtout() C_ontmpfile = 0; } #endif + return 0; } -static int -available(part) - int part; +static int available(int part) { /* See if part "part", and all the parts it consists of, are available. Return 1 if they are, 0 otherwize @@ -240,9 +249,7 @@ available(part) return retval; } -static Part * -mkpart(part) - int part; +static Part *mkpart(int part) { /* Create a Part structure with id "part", and return a pointer to it, after checking that is does not exist @@ -266,9 +273,7 @@ mkpart(part) return p; } -static -end_partofpart(p) - register Part *p; +static void end_partofpart(register Part *p) { /* End the current chunk of part *p. */ @@ -285,9 +290,7 @@ end_partofpart(p) } } -static -resume(p) - register Part *p; +static void resume(register Part *p) { /* Resume part "p", by creating a new PartOfPart structure for it. @@ -302,9 +305,7 @@ resume(p) pp->pp_begin = C_current_out - C_BASE; } -void -C_insertpart(part) - int part; +void C_insertpart(int part) { /* Insert part "part" in the current part. If C_sequential is still set and the part to be inserted is available now, @@ -341,9 +342,7 @@ C_insertpart(part) resume(p); } -void -C_beginpart(part) - int part; +void C_beginpart(int part) { /* Now follows the definition for part "part". Suspend the current part, and add part "part" to the @@ -361,9 +360,7 @@ C_beginpart(part) resume(p); } -void -C_endpart(part) - int part; +void C_endpart(int part) { /* End the current part. The parameter "part" is just there for the checking. Do we really need it ??? diff --git a/modules/src/em_code/internerr.c b/modules/src/em_code/internerr.c index 19bd6538a..f77aadfc8 100644 --- a/modules/src/em_code/internerr.c +++ b/modules/src/em_code/internerr.c @@ -3,10 +3,11 @@ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * See the copyright notice in the ACK home directory, in the file "Copyright". */ -#include +#include +#include +#include "system.h" -void -C_internal_error() +void C_internal_error(void) { sys_write(STDERR,"internal error\n",15); sys_stop(S_EXIT); diff --git a/modules/src/em_code/makeem.sed b/modules/src/em_code/makeem.sed new file mode 100644 index 000000000..8db5d8cc9 --- /dev/null +++ b/modules/src/em_code/makeem.sed @@ -0,0 +1,18 @@ +1i\ +/* this part is generated from em_table */ +# Remove pseudo instructions +/^\(...\) \([0-9]\).*/d +# Remove opcode constant categories/count +/^\(....\) \([0-9]\).*/d +/^\(.....\) \([0-9]\).*/d +# Below are the actual replacement of opcodes. +s/^\(...\) \(d\).*/#define C_\1(c) CC_opcst(op_\1, c)/ +s/^\(...\) \([cslnfzor]\).*/#define C_\1(c) CC_opcst(op_\1, c)/ +s/^\(...\) \(w\).*/#define C_\1(w) CC_opcst(op_\1, w)\ +#define C_\1_narg() CC_opnarg(op_\1)/ +s/^\(...\) \(g\).*/#define C_\1(g) CC_opcst(op_\1, g)\ +#define C_\1_dnam(g, o) CC_opdnam(op_\1, g, o)\ +#define C_\1_dlb(g, o) CC_opdlb(op_\1, g, o)/ +s/^\(...\) \(p\).*/#define C_\1(p) CC_oppnam(op_\1, p)/ +s/^\(...\) \(b\).*/#define C_\1(b) CC_opilb(op_\1, b)/ +s/^\(...\) \(-\).*/#define C_\1() CC_op(op_\1)/ diff --git a/modules/src/em_code/msend.c b/modules/src/em_code/msend.c index f78dcae81..01745946d 100644 --- a/modules/src/em_code/msend.c +++ b/modules/src/em_code/msend.c @@ -2,8 +2,7 @@ /* $Id$ */ -void -CC_msend() +void CC_msend(void) { CEND(); NL(); diff --git a/modules/src/em_code/msstart.c b/modules/src/em_code/msstart.c index 82bc13670..edc5027fd 100644 --- a/modules/src/em_code/msstart.c +++ b/modules/src/em_code/msstart.c @@ -2,9 +2,7 @@ /* $Id$ */ -void -CC_msstart(cst) - int cst; +void CC_msstart(int cst) { /* start of message */ diff --git a/modules/src/em_code/op.c b/modules/src/em_code/op.c index ac03706b8..df98c8fd2 100644 --- a/modules/src/em_code/op.c +++ b/modules/src/em_code/op.c @@ -2,8 +2,7 @@ /* $Id$ */ -void -CC_op(opcode) +void CC_op(int opcode) { /* Instruction that never has an argument Argument types: - diff --git a/modules/src/em_code/opcst.c b/modules/src/em_code/opcst.c index 782f15c74..8f6dab35d 100644 --- a/modules/src/em_code/opcst.c +++ b/modules/src/em_code/opcst.c @@ -2,9 +2,7 @@ /* $Id$ */ -void -CC_opcst(opcode, cst) - arith cst; +void CC_opcst(int opcode, arith cst) { /* Instruction with a constant argument Argument types: c, d, l, g, f, n, s, z, o, w, r diff --git a/modules/src/em_code/opdlb.c b/modules/src/em_code/opdlb.c index 59c8ed5d6..7df00960c 100644 --- a/modules/src/em_code/opdlb.c +++ b/modules/src/em_code/opdlb.c @@ -2,10 +2,7 @@ /* $Id$ */ -void -CC_opdlb(opcode, dlb, offset) - label dlb; - arith offset; +void CC_opdlb(int opcode, label dlb, arith offset) { /* Instruction that as a numeric datalabel + offset as argument Argument types: g diff --git a/modules/src/em_code/opdnam.c b/modules/src/em_code/opdnam.c index 84fd207a9..640a52945 100644 --- a/modules/src/em_code/opdnam.c +++ b/modules/src/em_code/opdnam.c @@ -2,10 +2,7 @@ /* $Id$ */ -void -CC_opdnam(opcode, dnam, offset) - char *dnam; - arith offset; +void CC_opdnam(int opcode, char* dnam, arith offset) { /* Instruction that has a datalabel + offset as argument Argument types: g diff --git a/modules/src/em_code/opilb.c b/modules/src/em_code/opilb.c index 8cecaece8..637811dc0 100644 --- a/modules/src/em_code/opilb.c +++ b/modules/src/em_code/opilb.c @@ -2,9 +2,7 @@ /* $Id$ */ -void -CC_opilb(opcode, ilb) - label ilb; +void CC_opilb(int opcode, label ilb) { /* Instruction with instruction label argument Argument types: b diff --git a/modules/src/em_code/opnarg.c b/modules/src/em_code/opnarg.c index 241cc0002..e6fada6b1 100644 --- a/modules/src/em_code/opnarg.c +++ b/modules/src/em_code/opnarg.c @@ -2,8 +2,7 @@ /* $Id$ */ -void -CC_opnarg(opcode) +void CC_opnarg(int opcode) { /* Instruction with optional argument, but now without one Argument types: w diff --git a/modules/src/em_code/oppnam.c b/modules/src/em_code/oppnam.c index d799772fd..20e203836 100644 --- a/modules/src/em_code/oppnam.c +++ b/modules/src/em_code/oppnam.c @@ -2,9 +2,7 @@ /* $Id$ */ -void -CC_oppnam(opcode, pnam) - char *pnam; +void CC_oppnam(int opcode, char* pnam) { /* Instruction that has a procedure name as argument Argument types: p diff --git a/modules/src/em_code/pnam.c b/modules/src/em_code/pnam.c index 5e21a2a9c..e5efbfa7f 100644 --- a/modules/src/em_code/pnam.c +++ b/modules/src/em_code/pnam.c @@ -2,9 +2,7 @@ /* $Id$ */ -void -CC_pnam(str) - char *str; +void CC_pnam(char* str) { COMMA(); PNAM(str); diff --git a/modules/src/em_code/pro.c b/modules/src/em_code/pro.c index 5829a4b6d..20c9e2513 100644 --- a/modules/src/em_code/pro.c +++ b/modules/src/em_code/pro.c @@ -2,10 +2,7 @@ /* $Id$ */ -void -CC_pro(pnam, l) - char *pnam; - arith l; +void CC_pro(char* pnam, arith l) { /* PRO pseudo with procedure name pnam and # of locals l */ diff --git a/modules/src/em_code/pronarg.c b/modules/src/em_code/pronarg.c index 2204f04ae..9f714a439 100644 --- a/modules/src/em_code/pronarg.c +++ b/modules/src/em_code/pronarg.c @@ -2,9 +2,7 @@ /* $Id$ */ -void -CC_pronarg(pnam) - char *pnam; +void CC_pronarg(char* pnam) { /* PRO pseudo with procedure name pnam and unknown # of locals */ diff --git a/modules/src/em_code/psdlb.c b/modules/src/em_code/psdlb.c index 73d674d6e..a006ab950 100644 --- a/modules/src/em_code/psdlb.c +++ b/modules/src/em_code/psdlb.c @@ -2,9 +2,7 @@ /* $Id$ */ -void -CC_psdlb(op, dlb) - label dlb; +void CC_psdlb(int op, label dlb) { /* Pseudo with numeric datalabel */ diff --git a/modules/src/em_code/psdnam.c b/modules/src/em_code/psdnam.c index 5acf6971e..05815921a 100644 --- a/modules/src/em_code/psdnam.c +++ b/modules/src/em_code/psdnam.c @@ -2,9 +2,7 @@ /* $Id$ */ -void -CC_psdnam(op, dnam) - char *dnam; +void CC_psdnam(int op, char* dnam) { /* Pseudo with data label */ diff --git a/modules/src/em_code/pspnam.c b/modules/src/em_code/pspnam.c index 283fce43e..cf364ffe9 100644 --- a/modules/src/em_code/pspnam.c +++ b/modules/src/em_code/pspnam.c @@ -2,9 +2,7 @@ /* $Id$ */ -void -CC_pspnam(op, pnam) - char *pnam; +void CC_pspnam(int op, char* pnam) { /* Pseudo with procedure name */ diff --git a/modules/src/em_code/scon.c b/modules/src/em_code/scon.c index 5c204dbbf..b421b4746 100644 --- a/modules/src/em_code/scon.c +++ b/modules/src/em_code/scon.c @@ -2,10 +2,7 @@ /* $Id$ */ -void -CC_scon(str, siz) - char *str; - arith siz; +void CC_scon(char* str, arith siz) { COMMA(); SCON(str, siz); diff --git a/modules/src/em_code/ucon.c b/modules/src/em_code/ucon.c index 4520c80dd..71ed04557 100644 --- a/modules/src/em_code/ucon.c +++ b/modules/src/em_code/ucon.c @@ -2,10 +2,7 @@ /* $Id$ */ -void -CC_ucon(val,siz) - char *val; - arith siz; +void CC_ucon(char* val,arith siz) { COMMA(); WCON(sp_ucon, val, siz); diff --git a/modules/src/em_mes/C_ms_com.c b/modules/src/em_mes/C_ms_com.c index b6d22106d..328ba3f1c 100644 --- a/modules/src/em_mes/C_ms_com.c +++ b/modules/src/em_mes/C_ms_com.c @@ -6,12 +6,10 @@ #include #include -#include -#include +#include "em.h" +#include "em_mes.h" -void -C_ms_com(str) - char *str; +void C_ms_com(char* str) { C_mes_begin(ms_com); C_scon(str, (arith) (strlen(str) + 1)); diff --git a/modules/src/em_mes/C_ms_ego.c b/modules/src/em_mes/C_ms_ego.c index 1c9c5f776..0dcb27392 100644 --- a/modules/src/em_mes/C_ms_ego.c +++ b/modules/src/em_mes/C_ms_ego.c @@ -3,13 +3,10 @@ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * See the copyright notice in the ACK home directory, in the file "Copyright". */ -#include -#include +#include "em.h" +#include "em_mes.h" -void -C_ms_ego(hint, offs, siz, regno) - int hint, regno; - arith offs, siz; +void C_ms_ego(int hint, arith offs, arith siz, int regno) { C_mes_begin(ms_ego); C_cst((arith)hint); diff --git a/modules/src/em_mes/C_ms_emx.c b/modules/src/em_mes/C_ms_emx.c index e95dadd55..e4c908f3c 100644 --- a/modules/src/em_mes/C_ms_emx.c +++ b/modules/src/em_mes/C_ms_emx.c @@ -3,12 +3,10 @@ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * See the copyright notice in the ACK home directory, in the file "Copyright". */ -#include -#include +#include "em.h" +#include "em_mes.h" -void -C_ms_emx(wsiz, psiz) - arith wsiz, psiz; +void C_ms_emx(arith wsiz, arith psiz) { C_mes_begin(ms_emx); C_cst(wsiz); diff --git a/modules/src/em_mes/C_ms_err.c b/modules/src/em_mes/C_ms_err.c index df4880153..f6dfa82d7 100644 --- a/modules/src/em_mes/C_ms_err.c +++ b/modules/src/em_mes/C_ms_err.c @@ -3,11 +3,10 @@ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * See the copyright notice in the ACK home directory, in the file "Copyright". */ -#include -#include +#include "em.h" +#include "em_mes.h" -void -C_ms_err() +void C_ms_err(void) { C_mes_begin(ms_err); C_mes_end(); diff --git a/modules/src/em_mes/C_ms_flt.c b/modules/src/em_mes/C_ms_flt.c index 557cbbb2a..1f092ed68 100644 --- a/modules/src/em_mes/C_ms_flt.c +++ b/modules/src/em_mes/C_ms_flt.c @@ -3,11 +3,10 @@ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * See the copyright notice in the ACK home directory, in the file "Copyright". */ -#include -#include +#include "em.h" +#include "em_mes.h" -void -C_ms_flt() +void C_ms_flt(void) { C_mes_begin(ms_flt); C_mes_end(); diff --git a/modules/src/em_mes/C_ms_gto.c b/modules/src/em_mes/C_ms_gto.c index 29bbd1ee7..c6ba4c1cd 100644 --- a/modules/src/em_mes/C_ms_gto.c +++ b/modules/src/em_mes/C_ms_gto.c @@ -3,11 +3,10 @@ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * See the copyright notice in the ACK home directory, in the file "Copyright". */ -#include -#include +#include "em.h" +#include "em_mes.h" -void -C_ms_gto() +void C_ms_gto(void) { C_mes_begin(ms_gto); C_mes_end(); diff --git a/modules/src/em_mes/C_ms_opt.c b/modules/src/em_mes/C_ms_opt.c index 386d268bb..a80e9c812 100644 --- a/modules/src/em_mes/C_ms_opt.c +++ b/modules/src/em_mes/C_ms_opt.c @@ -3,11 +3,10 @@ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * See the copyright notice in the ACK home directory, in the file "Copyright". */ -#include -#include +#include "em.h" +#include "em_mes.h" -void -C_ms_opt() +void C_ms_opt(void) { C_mes_begin(ms_opt); C_mes_end(); diff --git a/modules/src/em_mes/C_ms_par.c b/modules/src/em_mes/C_ms_par.c index 7d7c39fe9..adb7c2fc8 100644 --- a/modules/src/em_mes/C_ms_par.c +++ b/modules/src/em_mes/C_ms_par.c @@ -3,12 +3,10 @@ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * See the copyright notice in the ACK home directory, in the file "Copyright". */ -#include -#include +#include "em.h" +#include "em_mes.h" -void -C_ms_par(nparams) - arith nparams; +void C_ms_par(arith nparams) { C_mes_begin(ms_par); C_cst(nparams); diff --git a/modules/src/em_mes/C_ms_reg.c b/modules/src/em_mes/C_ms_reg.c index c63063c84..7b1934385 100644 --- a/modules/src/em_mes/C_ms_reg.c +++ b/modules/src/em_mes/C_ms_reg.c @@ -3,13 +3,10 @@ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * See the copyright notice in the ACK home directory, in the file "Copyright". */ -#include -#include +#include "em.h" +#include "em_mes.h" -void -C_ms_reg(offs, siz, class, prior) - arith offs, siz; - int class, prior; +void C_ms_reg(arith offs, arith siz, int class, int prior) { C_mes_begin(ms_reg); C_cst(offs); diff --git a/modules/src/em_mes/C_ms_src.c b/modules/src/em_mes/C_ms_src.c index 583168140..d4556f6e8 100644 --- a/modules/src/em_mes/C_ms_src.c +++ b/modules/src/em_mes/C_ms_src.c @@ -6,13 +6,10 @@ #include #include -#include -#include +#include "em.h" +#include "em_mes.h" -void -C_ms_src(nlines, filnam) - int nlines; - char *filnam; +void C_ms_src(int nlines, char* filnam) { C_mes_begin(ms_src); C_cst((arith)nlines); diff --git a/modules/src/em_mes/C_ms_stb.c b/modules/src/em_mes/C_ms_stb.c index 430dea397..600b747dc 100644 --- a/modules/src/em_mes/C_ms_stb.c +++ b/modules/src/em_mes/C_ms_stb.c @@ -6,14 +6,10 @@ #include #include -#include -#include +#include "em.h" +#include "em_mes.h" -void -C_ms_stb_cst(s, e1, e2, e3) - char *s; - int e1, e2; - arith e3; +void C_ms_stb_cst(char* s, int e1, int e2, arith e3) { C_mes_begin(ms_stb); if (s) C_scon(s, (arith) (strlen(s)+1)); diff --git a/modules/src/em_mes/C_ms_std.c b/modules/src/em_mes/C_ms_std.c index 0399fa8ed..afc815147 100644 --- a/modules/src/em_mes/C_ms_std.c +++ b/modules/src/em_mes/C_ms_std.c @@ -6,14 +6,10 @@ #include #include -#include -#include +#include "em.h" +#include "em_mes.h" -void -C_ms_std(s, e1, l) - char *s; - int e1; - int l; +void C_ms_std(char* s, int e1, int l) { C_mes_begin(ms_std); if (s) C_scon(s, (arith) (strlen(s)+1)); diff --git a/modules/src/input/inp_pkg.body b/modules/src/input/inp_pkg.body index 0bc80804d..2a025cd52 100644 --- a/modules/src/input/inp_pkg.body +++ b/modules/src/input/inp_pkg.body @@ -40,7 +40,8 @@ extern char *malloc(); #endif -#include +#include "system.h" +#include #ifndef INP_NPUSHBACK #define INP_NPUSHBACK 1 @@ -106,7 +107,6 @@ INP_rdfile(fd, fn, size, pbuf) register long *size; char **pbuf; /* output parameter */ { - extern long sys_filesize(); int rsize; if ( @@ -137,8 +137,8 @@ INP_rdfile(fd, fn, size, pbuf) INP_PRIVATE struct INP_i_buf *i_ptr; _PROTOTYPE(INP_PRIVATE char * INP_pbuf, (void)); -INP_PRIVATE char * -INP_pbuf() + +INP_PRIVATE char *INP_pbuf(void) { register struct INP_i_buf *ib = (struct INP_i_buf *) malloc(sizeof(struct INP_i_buf)); @@ -159,8 +159,7 @@ INP_pbuf() _PROTOTYPE(INP_PRIVATE struct INP_buffer_header *INP_push_bh, (void)); _PROTOTYPE(INP_PRIVATE int INP_pop_bh, (void)); -INP_PRIVATE struct INP_buffer_header * -INP_push_bh() +INP_PRIVATE struct INP_buffer_header *INP_push_bh(void) { register struct INP_buffer_header *bh; @@ -183,8 +182,7 @@ INP_push_bh() of headers. 0 is returned if there are no more inputbuffers on the stack, 1 is returned in the other case. */ -INP_PRIVATE int -INP_pop_bh() +INP_PRIVATE int INP_pop_bh(void) { register struct INP_buffer_header *bh = INP_head; @@ -220,9 +218,11 @@ INP_rdblock(fd, buf, n) int *n; { + if (!sys_read(fd, buf, INP_BUFSIZE, n)) { return 0; } + buf[*n] = '\0'; return 1; } @@ -235,10 +235,7 @@ _PROTOTYPE(INP_PRIVATE int INP_mk_filename, (char *, char *, char **)); /* INP_mk_filename() concatenates a dir and filename. */ -INP_PRIVATE int -INP_mk_filename(dir, file, newname) - register char *dir, *file; - char **newname; +INP_PRIVATE int INP_mk_filename(register char *dir, register char *file, char **newname) { register char *dst; @@ -257,11 +254,7 @@ INP_mk_filename(dir, file, newname) /* Interface routines : InsertFile, InsertText, and loadbuf */ -int -InsertFile(filnam, table, result) - char *filnam; - char *table[]; - char **result; +int InsertFile(char *filnam, char *table[], char **result) { char *newfn = 0; @@ -327,9 +320,7 @@ InsertFile(filnam, table, result) return 0; } -int -InsertText(text, length) - char *text; +int InsertText(char *text, int length) { register struct INP_buffer_header *bh = INP_push_bh(); @@ -344,8 +335,7 @@ InsertText(text, length) ((void)((dest = *_ipp++) || (dest = loadbuf()))) /* Reads the next character, converting CRLF into LF. */ -int -loadchar(void) +int loadchar(void) { int ch; RAWLOAD(ch); @@ -368,8 +358,7 @@ loadchar(void) Note: this routine is exported due to its occurence in the definition of LoadChar [input.h], that is defined as a macro. */ -int -loadbuf() +int loadbuf(void) { register struct INP_buffer_header *bh = INP_head; static char buf[INP_NPUSHBACK + 1]; diff --git a/modules/src/print/print.h b/modules/src/print/print.h index 974e4bf1b..292796e6d 100644 --- a/modules/src/print/print.h +++ b/modules/src/print/print.h @@ -8,6 +8,7 @@ #define __PRINT_INCLUDED__ #include +#include void print(const char *fmt, ...); void fprint(File *f, const char *fmt, ...); diff --git a/modules/src/string/bts2str.c b/modules/src/string/bts2str.c index 8d0cb05f5..2caf14bfe 100644 --- a/modules/src/string/bts2str.c +++ b/modules/src/string/bts2str.c @@ -12,10 +12,10 @@ #define is_print(c) ((unsigned)((c) - ' ') <= '~' - ' ') -char * -bts2str(b, n, s) - char *b, *s; - register int n; + + + +char *bts2str(char *b, register int n, char *s) { register char *f = b, *t = s; diff --git a/modules/src/system/build.lua b/modules/src/system/build.lua index c9eba2979..b97130d98 100644 --- a/modules/src/system/build.lua +++ b/modules/src/system/build.lua @@ -6,7 +6,7 @@ clibrary { --"./lock.c", "./modtime.c", "./open.c", "./read.c", "./remove.c", "./rename.c", "./seek.c", "./stop.c", "./system.c", - --"./unlock.c", + --"./unlock.c”,”./tmpdir.c”, "./write.c", }, hdrs = { "./system.h" }, diff --git a/modules/src/system/chmode.c b/modules/src/system/chmode.c index 0c0c1f59e..bed6bcd83 100644 --- a/modules/src/system/chmode.c +++ b/modules/src/system/chmode.c @@ -4,12 +4,10 @@ */ /* $Id$ */ +#include #include "system.h" -int -sys_chmode(path, mode) - char *path; - int mode; +int sys_chmode(char* path,int mode) { - return chmod(path, mode) == 0; + return chmod(path, (mode_t)mode) == 0; } diff --git a/modules/src/system/filesize.c b/modules/src/system/filesize.c index c3a62e568..b02845113 100644 --- a/modules/src/system/filesize.c +++ b/modules/src/system/filesize.c @@ -8,13 +8,11 @@ #include #include "system.h" -long -sys_filesize(path) - char *path; +off_t sys_filesize(char* path) { struct stat st_buf; if (stat(path, &st_buf) != 0) return -1L; - return (long) st_buf.st_size; + return st_buf.st_size; } diff --git a/modules/src/system/modtime.c b/modules/src/system/modtime.c index 129c3bce3..9fe9455a6 100644 --- a/modules/src/system/modtime.c +++ b/modules/src/system/modtime.c @@ -8,13 +8,11 @@ #include #include "system.h" -long -sys_modtime(path) - char *path; +time_t sys_modtime(char* path) { struct stat st_buf; if (stat(path, &st_buf) != 0) return -1L; - return (long) st_buf.st_mtime; + return st_buf.st_mtime; } diff --git a/modules/src/system/remove.c b/modules/src/system/remove.c index 435d67b05..82b6fd4c6 100644 --- a/modules/src/system/remove.c +++ b/modules/src/system/remove.c @@ -4,11 +4,10 @@ */ /* $Id$ */ +#include #include "system.h" -int -sys_remove(path) - char *path; +int sys_remove(char* path) { - return unlink(path) == 0; + return remove(path) == 0; } diff --git a/modules/src/system/stop.c b/modules/src/system/stop.c index 05986b162..5e94367d4 100644 --- a/modules/src/system/stop.c +++ b/modules/src/system/stop.c @@ -7,15 +7,13 @@ #include #include "system.h" -void -sys_stop(how) - int how; +void sys_stop(int how) { switch(how) { case S_END: - exit(0); + exit(EXIT_SUCCESS); case S_EXIT: - exit(1); + exit(EXIT_FAILURE); case S_ABORT: default: abort(); diff --git a/modules/src/system/system.h b/modules/src/system/system.h index f596defe4..6d394d0da 100644 --- a/modules/src/system/system.h +++ b/modules/src/system/system.h @@ -6,6 +6,10 @@ #ifndef __SYSTEM_INCLUDED__ #define __SYSTEM_INCLUDED__ +#include +#include +#include + struct _sys_fildes { int o_fd; /* UNIX filedescriptor */ int o_flags; /* flags for open; 0 if not used */ @@ -40,15 +44,17 @@ int sys_reset(File *); int sys_access(char *, int); int sys_remove(char *); int sys_rename(char *, char *); -long sys_filesize(char *); +off_t sys_filesize(char *); int sys_chmode(char *, int); +/* Return the temporary directory location */ +char* sys_gettmpdir(void); #if 0 int sys_lock(char *); int sys_unlock(char *); #endif char *sys_break(int); void sys_stop(int); -long sys_modtime(char *); +time_t sys_modtime(char *); /* standard file decsriptors */ #define STDIN &_sys_ftab[0] diff --git a/modules/src/system/tmpdir.c b/modules/src/system/tmpdir.c new file mode 100644 index 000000000..d02a91b0f --- /dev/null +++ b/modules/src/system/tmpdir.c @@ -0,0 +1,27 @@ +/* Copyright (c) 2019. See the file "Copyright" in + * the root directory for more information. + * + * Created on: 2019-02-09 + * + */ +#include + +char* sys_gettmpdir(void) +{ + char* result = 0; + /* Check the UNIX temporary directory */ + result = getenv("TMPDIR"); + if (result != 0) + return result; + result = getenv("TMP"); + if (result != 0) + return result; + /* DOS compatible systems */ + result = getenv("TEMP"); + if (result != 0) + return result; + /* Then try current directory */ + return "."; +} + + diff --git a/util/LLgen/lib/incl b/util/LLgen/lib/incl index fc6250e38..05b443c14 100644 --- a/util/LLgen/lib/incl +++ b/util/LLgen/lib/incl @@ -2,6 +2,7 @@ #ifdef LL_DEBUG #include #include +#include #define LL_assert(x) assert(x) #else #define LL_assert(x) /* nothing */ @@ -30,7 +31,6 @@ extern int LLstartsymb; #define LLsincr(d) LLscnt[d]++ #define LLtincr(d) LLtcnt[d]++ -#if LL_ANSI_C extern int LL_LEXI(void); extern void LLread(void); extern int LLskip(void); @@ -48,21 +48,3 @@ extern int LLfirst(int, int); #if LL_NON_CORR extern void LLnc_recover(void); #endif -#else /* not LL_ANSI_C */ -extern LLread(); -extern int LLskip(); -extern int LLnext(); -extern LLerror(); -extern LLsafeerror(); -extern LLnewlevel(); -extern LLoldlevel(); -#ifndef LL_FASTER -extern LLscan(); -#endif -#ifndef LLNOFIRSTS -extern int LLfirst(); -#endif -#if LL_NON_CORR -extern LLnc_recover(); -#endif -#endif /* not LL_ANSI_C */ diff --git a/util/LLgen/lib/nc_rec b/util/LLgen/lib/nc_rec index 98c0d32c9..491252c68 100644 --- a/util/LLgen/lib/nc_rec +++ b/util/LLgen/lib/nc_rec @@ -1,5 +1,6 @@ #include #include +#include /* compile with -DNOFIRST to disable firstset optimization @@ -12,9 +13,7 @@ extern int LLsymb; extern int LLstartsymb; -#if LL_ANSI_C void LLmessage(int); -#endif struct stacks { @@ -119,37 +118,21 @@ static struct nonterminal *nonterminals; /* These functions must be called instead of the original functions in * 'malloc.h'. They offer a checking allocation mechanism. */ -#if LL_ANSI_C static char *Malloc(unsigned); static char *Realloc(char*, unsigned); -#else - -static char *Malloc(); -static char *Realloc(); -#endif /* These functions build the grammar */ -#if LL_ANSI_C static void init_grammar(void); static void build_grammar(void); static struct lhs *build_rule(void); static struct symbol *build_rhs(struct lhs*); static struct symbol *make_link(struct symbol*); -#else - -static init_grammar(); -static build_grammar(); -static struct lhs *build_rule(); -static struct symbol *build_rhs(); -static struct symbol *make_link(); -#endif /* These functions operate on the stacks */ -#if LL_ANSI_C static int optimize(struct stacks*, struct symbol*, int); static void read_token(void); static void start_stack(struct stacks*, int, int); @@ -179,43 +162,9 @@ static void calculate(struct stacks*, int); static void kill_stack(struct stacks *stack); void LLnc_recover(void); -#else - -static int optimize(); -static read_token(); -static start_stack(); -static continuation(); -static struct stack_elt *push_rule(); -static new_head(); -static to_delete(); -static substitute(); -static int join(); -static int path(); -static int part_of_loop(); -static generate_heads(); -static delete(); -static hyp_run(); -static check_run(); -static struct stack_elt *split(); -static test(); -static dump_stack(); -static clear_flags(); -static clear_gen_flags(); -static match_heads(); -static cleanup(); -static initialize(); -static calculate(); -static kill_stack(); -LLnc_recover(); -#endif -#if LL_ANSI_C static char *Malloc(unsigned size) -#else -static char *Malloc(size) -unsigned size; -#endif { char *p; @@ -227,13 +176,7 @@ unsigned size; } -#if LL_ANSI_C static char *Realloc(char *ptr, unsigned size) -#else -static char *Realloc(ptr, size) -char *ptr; -unsigned size; -#endif { char *p; @@ -245,11 +188,7 @@ unsigned size; } -#if LL_ANSI_C static void init_grammar(void) -#else -static init_grammar() -#endif { /* Allocate and initialize an array for terminals and nonterminals */ @@ -270,11 +209,7 @@ static init_grammar() } -#if LL_ANSI_C static void build_grammar(void) -#else -static build_grammar() -#endif { /* Build a rule for every nonterminal. The LHS must be saved first because * of the fact that the right side of an assignment statement (in C) will @@ -290,11 +225,7 @@ static build_grammar() } -#if LL_ANSI_C static struct lhs *build_rule(void) -#else -static struct lhs *build_rule() -#endif { /* Build LHS and call a funcion to create RHS */ @@ -322,12 +253,7 @@ static struct lhs *build_rule() } -#if LL_ANSI_C static struct symbol *build_rhs(struct lhs *l) -#else -static struct symbol *build_rhs(l) -struct lhs *l; -#endif { /* Build RHS by creating structs for all symbols including ALT and * EORULE. Also call a function for linking same terminals and @@ -371,12 +297,7 @@ struct lhs *l; } -#if LL_ANSI_C static struct symbol *make_link(struct symbol *r) -#else -static struct symbol *make_link(r) -struct symbol *r; -#endif { /* Link same terminals and nonterminals. Every new symbol is appended * in front of the corresponding list for efficiency. @@ -400,15 +321,7 @@ struct symbol *r; /*****************************************************************************/ -#if LL_ANSI_C static int optimize(struct stacks* stack, struct symbol *symb_ptr, int l_ahead) -#else -static int optimize(stack, symb_ptr, l_ahead) -struct stacks *stack; -struct symbol *symb_ptr; -int l_ahead; -#endif - /* Return 1 if rule symb_ptr can start with terminal l_ahead, else return 0. * The array with expected terminals will also be filled in. */ @@ -463,12 +376,7 @@ int l_ahead; } -#if LL_ANSI_C static void read_token(void) -#else -static read_token() -#endif - /* Read token and put it in global variable LLsymb, skipping * invalid tokens */ @@ -482,16 +390,8 @@ static read_token() } -#if LL_ANSI_C static void start_stack(struct stacks *stack, int base, int l_ahead) -#else -static start_stack(stack, base, l_ahead) -struct stacks *stack; -int base, l_ahead; -#endif - /* Start stack on base symbol base with lookahead l_ahead */ - { struct stack_elt *bottom, *top; struct symbol *symb_ptr; @@ -587,14 +487,7 @@ int base, l_ahead; } -#if LL_ANSI_C static void continuation(struct stacks *stack, int nt, int l_ahead) -#else -static continuation(stack, nt, l_ahead) -struct stacks *stack; -int nt, l_ahead; -#endif - /* We have 'eaten' a whole stack, and think we recognized nt. Now look for rules that we can proceed with, ie containing nt in the RHS. Each rule found will be developed untill a terminal is at the top @@ -680,15 +573,8 @@ of the stack.*/ } -#if LL_ANSI_C static struct stack_elt *push_rule(struct stack_elt *element, struct symbol *symb_ptr) -#else -static struct stack_elt *push_rule(element, symb_ptr) -struct stack_elt *element; -struct symbol *symb_ptr; -#endif - /* Append the rule symb_ptr to stack element 'element'. Return a * pointer to the new top of the stack */ @@ -735,14 +621,7 @@ struct symbol *symb_ptr; } -#if LL_ANSI_C static void new_head(struct stacks *stack, struct stack_elt *ptr) -#else -static new_head(stack, ptr) -struct stacks *stack; -struct stack_elt *ptr; -#endif - /* Make ptr a head of stack */ { @@ -773,14 +652,7 @@ struct stack_elt *ptr; } -#if LL_ANSI_C static void to_delete(struct stacks *stack, struct stack_elt *ptr) -#else -static to_delete(stack, ptr) -struct stacks *stack; -struct stack_elt *ptr; -#endif - /* Remember that ptr has to be deleted */ { @@ -814,15 +686,7 @@ struct stack_elt *ptr; } -#if LL_ANSI_C static void substitute(struct stacks *stack, struct stack_elt *top, int l_ahead) -#else -static substitute(stack, top, l_ahead) -struct stacks *stack; -struct stack_elt *top; -int l_ahead; -#endif - /* This function substitutes the NT pointed to by 'top'. 'top' should be a top * of a stack */ @@ -900,15 +764,7 @@ int l_ahead; } -#if LL_ANSI_C static int join(struct stacks *stack, struct stack_elt *top, int l_ahead) -#else -static int join(stack, top, l_ahead) -struct stacks *stack; -struct stack_elt *top; -int l_ahead; -#endif - /* This function tries to connect a NT on top of a stack with another stack, * which has already substituted this NT */ @@ -977,13 +833,7 @@ int l_ahead; #ifndef NOLOOPS -#if LL_ANSI_C static int path(struct stack_elt *se1, struct stack_elt *se2) -#else -static int path(se1, se2) -struct stack_elt *se1, *se2; -#endif /* LL_ANSI_C */ - /* If there is a path from se1 to se2 it returns 1 and marks all the paths * betweeen these two points, otherwise it returns 0. The flags LLYES and * LLNO are used for optimization. */ @@ -1014,13 +864,7 @@ struct stack_elt *se1, *se2; } -#if LL_ANSI_C static int part_of_loop(struct stack_elt *se) -#else -static int part_of_loop(se) -struct stack_elt *se; -#endif /* LL_ANSI_C */ - /* Checks if 'se' belongs to a loop */ { int i; @@ -1034,16 +878,8 @@ struct stack_elt *se; #endif /* NOLOOPS */ -#if LL_ANSI_C static void generate_heads(struct stacks *stack, struct stack_elt *se, int l_ahead) -#else -static generate_heads(stack, se, l_ahead) -struct stacks *stack; -struct stack_elt *se; -int l_ahead; -#endif - /* This funcion finds all heads starting at 'se'. */ { int i; @@ -1104,14 +940,7 @@ int l_ahead; } -#if LL_ANSI_C static void delete(struct stacks *stack, struct stack_elt *se) -#else -static delete(stack, se) -struct stacks *stack; -struct stack_elt *se; -#endif - /* This function runs down the stack(s) deleting every element which cannot be * reached anymore. */ { @@ -1172,13 +1001,7 @@ struct stack_elt *se; #ifndef NOLOOPS -#if LL_ANSI_C static void hyp_run(struct stack_elt *se) -#else -static hyp_run(se) -struct stack_elt *se; -#endif /* LL_ANSI_C */ - /* This function sets the 'hyp_ref_counts' of all elements of the loop that * 'se' belongs to to the value that 'ref_count' will get when 'se' is * deleted @@ -1212,14 +1035,7 @@ struct stack_elt *se; } -#if LL_ANSI_C static void check_run(struct stacks *stack, struct stack_elt *se) -#else -static check_run(stack, se) -struct stacks *stack; -struct stack_elt *se; -#endif /* LL_ANSI_C */ - /* This function checks all 'hyp_ref_counts' that 'hyp_run()' has set. * If one of them is not 0, 'check_run_ok' will be set to 0 indicating * that 'se' cannot be deleted. 'check_run()' also resets all 'hyp_ref_counts' @@ -1244,13 +1060,7 @@ struct stack_elt *se; #endif /* NOLOOPS */ -#if LL_ANSI_C static struct stack_elt *split(struct stack_elt *se) -#else -static struct stack_elt *split(se) -struct stack_elt *se; -#endif - /* This function splits of a NT in de stack, and returns a pointer to it */ { struct stack_elt *new_stack; @@ -1296,12 +1106,7 @@ struct stack_elt *se; #ifdef DEBUG -#if LL_ANSI_C static void test(struct stacks *stack) -#else -static test(stack) -struct stacks *stack; -#endif { struct stack_elt *se; int i; @@ -1320,13 +1125,7 @@ struct stacks *stack; } -#if LL_ANSI_C static void dump_stack(struct stack_elt *se, int level) -#else -static dump_stack(se, level) -struct stack_elt *se; -int level; -#endif { int i, j; @@ -1385,14 +1184,7 @@ int level; #endif -#if LL_ANSI_C static void clear_flags(struct stack_elt *se, char flag) -#else -static clear_flags(se, flag) -struct stack_elt *se; -char flag; -#endif - /* Clears edge flag 'flag' */ { int i; @@ -1405,13 +1197,7 @@ char flag; } } -#if LL_ANSI_C static void clear_gen_flags(struct stacks *stack) -#else -static clear_gen_flags(stack) -struct stacks *stack; -#endif - { int i; @@ -1423,14 +1209,7 @@ struct stacks *stack; } -#if LL_ANSI_C static void match_heads(struct stacks *stack, int symb) -#else -static match_heads(stack, symb) -struct stacks *stack; -int symb; -#endif - /* Match heads_buf against symb, leaving only matching heads, * whilst deallocating the non-matching stacks */ @@ -1482,13 +1261,7 @@ int symb; } -#if LL_ANSI_C static void cleanup(struct stacks *stack) -#else -static cleanup(stack) -struct stacks *stack; -#endif - /* Deletes all elements in 'cleanup_buf()' */ { int i; @@ -1502,13 +1275,7 @@ struct stacks *stack; } -#if LL_ANSI_C static void initialize(struct stacks *stack) -#else -static initialize(stack) -struct stacks *stack; -#endif - /* Initializes some variables and arrays */ { int j; @@ -1541,14 +1308,7 @@ struct stacks *stack; } -#if LL_ANSI_C static void calculate(struct stacks *stack, int l_ahead) -#else -static calculate(stack, l_ahead) -struct stacks *stack; -int l_ahead; -#endif - /* This function finds all new heads and deletes the old heads */ { int i; @@ -1592,12 +1352,7 @@ int l_ahead; } } -#if LL_ANSI_C static void kill_stack(struct stacks *stack) -#else -static kill_stack(stack) -struct stacks *stack; -#endif { int i; @@ -1609,12 +1364,7 @@ struct stacks *stack; -#if LL_ANSI_C void LLnc_recover(void) -#else -LLnc_recover() -#endif - /* This function contains the main loop for non correcting syntax error * recovery */ diff --git a/util/LLgen/lib/rec b/util/LLgen/lib/rec index ae7d69e66..2928d2c07 100644 --- a/util/LLgen/lib/rec +++ b/util/LLgen/lib/rec @@ -17,29 +17,15 @@ int LLstartsymb; static int fake_eof = 0; #endif -#if LL_ANSI_C #define LL_VOIDCST (void) void LLmessage(int); -#else -#define LL_VOIDCST -#endif #ifdef LL_USERHOOK -#if LL_ANSI_C static int LLdoskip(int); static int LLuserhook(int, int*); -#else -static int LLdoskip(); -static int LLuserhook(); -#endif #endif #ifndef LL_FASTER -#if LL_ANSI_C void LLscan(int t) -#else -LLscan(t) - int t; -#endif { /* * Check if the next symbol is equal to the parameter @@ -85,12 +71,7 @@ LLscan(t) } #endif -#if LL_ANSI_C void LLread(void) { -#else -LLread() { -#endif - #if LL_NON_CORR /* Again, check if another parser has crashed, * in that case intercept and go to the @@ -122,12 +103,7 @@ LLread() { /* NOTREACHED */ } -#if LL_ANSI_C void LLerror(int t) -#else -LLerror(t) - int t; -#endif { register int i; @@ -189,12 +165,7 @@ LLerror(t) } } -#if LL_ANSI_C void LLsafeerror(int t) -#else -LLsafeerror(t) - int t; -#endif { if (t == EOFILE && LLsymb <= 0) return; #ifdef LL_NEWMESS @@ -237,11 +208,7 @@ LLsafeerror(t) } #ifndef LLNOFIRSTS -#if LL_ANSI_C int LLfirst(int x, int d) { -#else -int LLfirst(x, d) { -#endif register int i; return (i = LLindex[x]) >= 0 && @@ -249,12 +216,7 @@ int LLfirst(x, d) { } #endif -#if LL_ANSI_C int LLnext(int n) -#else -int LLnext(n) - int n; -#endif { /* returns: 0 if the current symbol is'nt skipped, and it is'nt a member of "n", @@ -275,11 +237,7 @@ int LLnext(n) return retval; } -#if LL_ANSI_C int LLskip(void) { -#else -int LLskip() { -#endif /* returns 0 if the current symbol is'nt skipped, and 1 if it is, t.i., we have a new symbol */ @@ -287,14 +245,8 @@ int LLskip() { return LLdoskip(0); } -#if LL_ANSI_C extern void LL_USERHOOK(int, int *); static int LLuserhook(int e, int *list) -#else -static int LLuserhook(e, list) - int e; - int *list; -#endif { int old = LLsymb; LL_USERHOOK(e, list); @@ -302,12 +254,7 @@ static int LLuserhook(e, list) return LLsymb != old; } -#if LL_ANSI_C static void LLmklist(register int *list) -#else -static LLmklist(list) - register int *list; -#endif { char Xset[LL_SSIZE]; register char *p; @@ -331,12 +278,7 @@ static LLmklist(list) *list = 0; } -#if LL_ANSI_C static int LLdoskip(int e) -#else -static int LLdoskip(e) - int e; -#endif { int LLx; int list[LL_NTERMINALS+1]; @@ -395,11 +337,7 @@ static int LLdoskip(e) /* NOTREACHED */ } -#if LL_ANSI_C void LLnewlevel(unsigned int *LLsinfo) { -#else -LLnewlevel(LLsinfo) unsigned int *LLsinfo; { -#endif register int i; if (LLlevel++) { @@ -417,11 +355,7 @@ LLnewlevel(LLsinfo) unsigned int *LLsinfo; { LLtincr(0); } -#if LL_ANSI_C void LLoldlevel(unsigned int *LLsinfo) { -#else -LLoldlevel(LLsinfo) unsigned int *LLsinfo; { -#endif register int i; LLtdecr(0); diff --git a/util/LLgen/src/LLgen.c b/util/LLgen/src/LLgen.c index 6bb52f174..8676a4ca4 100644 --- a/util/LLgen/src/LLgen.c +++ b/util/LLgen/src/LLgen.c @@ -2,9 +2,6 @@ #include "Lpars.h" #define LL_LEXI scanner #define LLNOFIRSTS -#if __STDC__ || __cplusplus -#define LL_ANSI_C 1 -#endif #define LL_LEXI scanner /* $Id$ */ #ifdef LL_DEBUG @@ -38,7 +35,6 @@ extern int LLstartsymb; #define LLsincr(d) LLscnt[d]++ #define LLtincr(d) LLtcnt[d]++ -#if LL_ANSI_C extern int LL_LEXI(void); extern void LLread(void); extern int LLskip(void); @@ -56,33 +52,15 @@ extern int LLfirst(int, int); #if LL_NON_CORR extern void LLnc_recover(void); #endif -#else /* not LL_ANSI_C */ -extern LLread(); -extern int LLskip(); -extern int LLnext(); -extern LLerror(); -extern LLsafeerror(); -extern LLnewlevel(); -extern LLoldlevel(); -#ifndef LL_FASTER -extern LLscan(); -#endif -#ifndef LLNOFIRSTS -extern int LLfirst(); -#endif -#if LL_NON_CORR -extern LLnc_recover(); -#endif -#endif /* not LL_ANSI_C */ # line 20 "LLgen.g" -# include -# include -# include "types.h" -# include "io.h" -# include "extern.h" -# include "assert.h" -# include "cclass.h" +#include +#include +#include "types.h" +#include "io.h" +#include "extern.h" +#include "assert.h" +#include "cclass.h" # ifndef NORCSID static string rcsid = "$Id$"; @@ -106,15 +84,14 @@ static int max_rules; #define RULEINCR 32 /* Here are defined : */ -STATIC newnorder(); -STATIC newtorder(); -STATIC mkalt(); -STATIC mkterm(); -STATIC p_gram copyrule(); +STATIC void newnorder(int index); +STATIC void newtorder(int index); +STATIC void mkalt(p_gram prod, int condition,int lc,register p_gram res); +STATIC void mkterm(p_gram prod, int flags,int lc,register p_gram result); +STATIC p_gram copyrule(register p_gram p,int length); /* and of course LLparse() */ -STATIC -newnorder(index) { +STATIC void newnorder(int index) { static int porder; if (norder != -1) { @@ -125,8 +102,7 @@ newnorder(index) { nonterms[porder].n_next = -1; } -STATIC -newtorder(index) { +STATIC void newtorder(int index) { static int porder; if (torder != -1) { @@ -137,7 +113,7 @@ newtorder(index) { tokens[porder].t_next = -1; } -p_init() +void p_init(void) { alt_table = (p_gram )alloc(ALTINCR*sizeof(t_gram)); n_alts = 0; @@ -147,47 +123,31 @@ p_init() max_rules = RULEINCR; } -#if LL_ANSI_C static void LL1_def(void); static void LL2_rule(void); static void LL3_listel(void); static void LL4_firsts(void); static void LL5_productions( -# line 246 "LLgen.g" +# line 244 "LLgen.g" p_gram *p) ; static void LL6_simpleproduction( -# line 332 "LLgen.g" +# line 330 "LLgen.g" p_gram *p ,register int *conflres) ; static void LL7_elem( -# line 480 "LLgen.g" +# line 478 "LLgen.g" register p_gram pres) ; static void LL8_repeats( -# line 602 "LLgen.g" +# line 600 "LLgen.g" int *kind ,int *cnt) ; static void LL9_number( -# line 619 "LLgen.g" +# line 617 "LLgen.g" int *t) ; -#else -static LL1_def(); -static LL2_rule(); -static LL3_listel(); -static LL4_firsts(); -static LL5_productions(); -static LL6_simpleproduction(); -static LL7_elem(); -static LL8_repeats(); -static LL9_number(); -#endif -#if LL_ANSI_C void -#endif LL0_spec( -#if LL_ANSI_C void -#endif ) { LLsincr(0); -# line 96 "LLgen.g" +# line 94 "LLgen.g" { acount = 0; p_init(); } for (;;) { goto L_1; @@ -215,7 +175,7 @@ continue; LLsdecr(0); break; } -# line 98 "LLgen.g" +# line 96 "LLgen.g" { /* * Put an endmarker in temporary file */ @@ -226,15 +186,11 @@ break; } } static -#if LL_ANSI_C void -#endif LL1_def( -#if LL_ANSI_C void -#endif ) { -# line 108 "LLgen.g" +# line 106 "LLgen.g" register string p; switch(LLcsymb) { case /* C_IDENT */ 2 : ; @@ -275,13 +231,13 @@ LLtincr(2); LLtincr(24); LL_SAFE(C_START); LL_NOSCANDONE(C_IDENT); -# line 118 "LLgen.g" +# line 116 "LLgen.g" { p = store(lextoken.t_string); } LLtdecr(23); LL_NOSCANDONE(','); LLtdecr(2); LL_NOSCANDONE(C_IDENT); -# line 123 "LLgen.g" +# line 121 "LLgen.g" { /* * Put the declaration in the list * of start symbols @@ -309,11 +265,11 @@ case /* C_LEXICAL */ 14 : ; LLtincr(24); LL_SAFE(C_LEXICAL); LL_NOSCANDONE(C_IDENT); -# line 149 "LLgen.g" +# line 147 "LLgen.g" { if (!lexical) { lexical = store(lextoken.t_string); } - else error(linecount,"Duplicate %%lexical"); + else error(linecount,"Duplicate %%lexical", NULL); } LLtdecr(24); LL_NOSCANDONE(';'); @@ -322,16 +278,16 @@ case /* C_PREFIX */ 15 : ; LLtincr(24); LL_SAFE(C_PREFIX); LL_NOSCANDONE(C_IDENT); -# line 159 "LLgen.g" +# line 157 "LLgen.g" { if (!prefix) { prefix = store(lextoken.t_string); if (strlen(prefix) > 6) { error(linecount, - "%%prefix too long"); + "%%prefix too long",NULL); prefix[6] = 0; } } - else error(linecount,"Duplicate %%prefix"); + else error(linecount,"Duplicate %%prefix", NULL); } LLtdecr(24); LL_NOSCANDONE(';'); @@ -340,25 +296,25 @@ case /* C_ONERROR */ 16 : ; LLtincr(24); LL_SAFE(C_ONERROR); LL_NOSCANDONE(C_IDENT); -# line 171 "LLgen.g" +# line 169 "LLgen.g" { #ifdef NON_CORRECTING if (non_corr) { - warning(linecount, "%%onerror conflicts with -n option"); + warning(linecount, "%%onerror conflicts with -n option", NULL); } else #endif if (! onerror) { onerror = store(lextoken.t_string); } - else error(linecount,"Duplicate %%onerror"); + else error(linecount,"Duplicate %%onerror", NULL); } LLtdecr(24); LL_NOSCANDONE(';'); break; default: LL_SSCANDONE(C_ACTION); -# line 184 "LLgen.g" +# line 182 "LLgen.g" { acount++; } break; case /* C_FIRST */ 13 : ; @@ -367,31 +323,23 @@ break; } } static -#if LL_ANSI_C void -#endif LL3_listel( -#if LL_ANSI_C void -#endif ) { LL_NOSCANDONE(C_IDENT); -# line 194 "LLgen.g" +# line 192 "LLgen.g" { p_gram temp = search(TERMINAL,lextoken.t_string,ENTERING); newtorder(g_getcont(temp)); tokens[g_getcont(temp)].t_lineno = linecount; } } static -#if LL_ANSI_C void -#endif LL2_rule( -#if LL_ANSI_C void -#endif ) { -# line 200 "LLgen.g" +# line 198 "LLgen.g" register p_nont p; p_gram rr; register p_gram temp; @@ -402,7 +350,7 @@ LLtincr(25); LLsincr(1); LLtincr(24); LL_SAFE(C_IDENT); -# line 207 "LLgen.g" +# line 205 "LLgen.g" { temp = search(NONTERM,lextoken.t_string,BOTH); p = &nonterms[g_getcont(temp)]; if (p->n_rule) { @@ -437,11 +385,11 @@ else if (LL_3 & 1) goto L_1;} case /* C_PARAMS */ 6 : ; LLtdecr(6); LL_SAFE(C_PARAMS); -# line 225 "LLgen.g" +# line 223 "LLgen.g" { if (lextoken.t_num > 0) { p->n_flags |= PARAMS; if (lextoken.t_num > 15) { - error(linecount,"Too many parameters"); + error(linecount,"Too many parameters", NULL); } else setntparams(p,lextoken.t_num); } @@ -463,41 +411,34 @@ else if (LL_4 & 1) goto L_2;} case /* C_ACTION */ 7 : ; LLtdecr(7); LL_SAFE(C_ACTION); -# line 234 "LLgen.g" +# line 232 "LLgen.g" { p->n_flags |= LOCALS; } LLread(); } } LLtdecr(25); LL_SCANDONE(':'); -# line 236 "LLgen.g" +# line 234 "LLgen.g" { in_production = 1; } LLread(); LLsdecr(1); LL5_productions( -# line 237 "LLgen.g" +# line 235 "LLgen.g" &rr); LLtdecr(24); LL_SCANDONE(';'); -# line 238 "LLgen.g" +# line 236 "LLgen.g" { in_production = 0; } -# line 243 "LLgen.g" +# line 241 "LLgen.g" { nonterms[g_getcont(temp)].n_rule = rr;} } static -#if LL_ANSI_C void -#endif LL5_productions( -#if LL_ANSI_C -# line 246 "LLgen.g" +# line 244 "LLgen.g" p_gram *p) -#else -# line 246 "LLgen.g" - p) p_gram *p; -#endif { -# line 250 "LLgen.g" +# line 248 "LLgen.g" p_gram prod; int conflres = 0; int t = 0; @@ -506,12 +447,12 @@ p_gram *p) int o_lc, n_lc; LLtincr(26); -# line 257 "LLgen.g" +# line 255 "LLgen.g" { o_lc = linecount; } LL6_simpleproduction( -# line 258 "LLgen.g" +# line 256 "LLgen.g" p,&conflres); -# line 259 "LLgen.g" +# line 257 "LLgen.g" { if (conflres & DEF) haddefault = 1; } goto L_2; /* so that the label is used for certain */ L_2: ; @@ -523,13 +464,13 @@ LLsdecr(1); LLtincr(26); for (;;) { LL_SAFE('|'); -# line 261 "LLgen.g" +# line 259 "LLgen.g" { n_lc = linecount; } LLread(); LL6_simpleproduction( -# line 262 "LLgen.g" +# line 260 "LLgen.g" &prod,&t); -# line 263 "LLgen.g" +# line 261 "LLgen.g" { if (n_alts >= max_alts-2) { alt_table = (p_gram ) ralloc( (p_mem) alt_table, @@ -538,7 +479,7 @@ LL6_simpleproduction( if (t & DEF) { if (haddefault) { error(n_lc, - "More than one %%default in alternation"); + "More than one %%default in alternation", NULL); } haddefault = 1; } @@ -566,10 +507,10 @@ continue; LLtdecr(26); break; } -# line 282 "LLgen.g" +# line 280 "LLgen.g" { if (conflres & (COND|PREFERING|AVOIDING)) { error(n_lc, - "Resolver on last alternative not allowed"); + "Resolver on last alternative not allowed", NULL); } mkalt(*p,conflres,n_lc,&alt_table[n_alts++]); altcnt++; @@ -582,15 +523,15 @@ case /* ']' */ 28 : ; goto L_3; L_3: ; LLtdecr(26); -# line 292 "LLgen.g" +# line 290 "LLgen.g" { if (conflres & (COND|PREFERING|AVOIDING)) { error(o_lc, - "No alternation conflict resolver allowed here"); + "No alternation conflict resolver allowed here", NULL); } /* if (conflres & DEF) { error(o_lc, - "No %%default allowed here"); + "No %%default allowed here", NULL); } */ } @@ -598,14 +539,14 @@ break; default: if (LLskip()) goto L_2; goto L_3; } -# line 304 "LLgen.g" +# line 302 "LLgen.g" { n_alts -= altcnt; } } -# line 306 "LLgen.g" +# line 304 "LLgen.g" -STATIC -mkalt(prod,condition,lc,res) p_gram prod; register p_gram res; { +STATIC void mkalt(p_gram prod, int condition,int lc,register p_gram res) +{ /* * Create an alternation and initialise it. */ @@ -627,19 +568,12 @@ mkalt(prod,condition,lc,res) p_gram prod; register p_gram res; { nalts++; } static -#if LL_ANSI_C void -#endif LL6_simpleproduction( -#if LL_ANSI_C -# line 332 "LLgen.g" +# line 330 "LLgen.g" p_gram *p ,register int *conflres) -#else -# line 332 "LLgen.g" - p,conflres) p_gram *p; register int *conflres; -#endif { -# line 333 "LLgen.g" +# line 331 "LLgen.g" t_gram elem; int elmcnt = 0; int cnt, kind; @@ -675,7 +609,7 @@ else if (LL_6 & 1) goto L_1;} case /* C_DEFAULT */ 19 : ; LLtdecr(19); LL_SAFE(C_DEFAULT); -# line 338 "LLgen.g" +# line 336 "LLgen.g" { *conflres |= DEF; } LLread(); } @@ -708,17 +642,17 @@ switch(LLcsymb) { case /* C_IF */ 10 : ; LL_SAFE(C_IF); LL_NOSCANDONE(C_EXPR); -# line 344 "LLgen.g" +# line 342 "LLgen.g" { *conflres |= COND; } break; default: LL_SAFE(C_PREFER); -# line 345 "LLgen.g" +# line 343 "LLgen.g" { *conflres |= PREFERING; } break; case /* C_AVOID */ 17 : ; LL_SAFE(C_AVOID); -# line 346 "LLgen.g" +# line 344 "LLgen.g" { *conflres |= AVOIDING; } break; } @@ -747,7 +681,7 @@ else if (LL_8 & 1) goto L_6;} case /* C_ILLEGAL */ 22 : ; LLtdecr(22); LL_SAFE(C_ILLEGAL); -# line 348 "LLgen.g" +# line 346 "LLgen.g" { #ifdef NON_CORRECTING if (n_rules >= max_rules-2) { @@ -759,7 +693,7 @@ LL_SAFE(C_ILLEGAL); rule_table[n_rules++] = *search(TERMINAL, "LLILLEGAL", BOTH); if (*conflres & DEF) { - error(linecount, "%%illegal not allowed in %%default rule"); + error(linecount, "%%illegal not allowed in %%default rule", NULL); } #endif } @@ -790,9 +724,9 @@ case /* '*' */ 30 : ; case /* '+' */ 31 : ; LLsincr(4); LL7_elem( -# line 364 "LLgen.g" +# line 362 "LLgen.g" &elem); -# line 365 "LLgen.g" +# line 363 "LLgen.g" { if (n_rules >= max_rules-2) { rule_table = (p_gram) ralloc( (p_mem) rule_table, @@ -810,9 +744,9 @@ case /* '*' */ 30 : ; case /* '+' */ 31 : ; LLsdecr(4); LL8_repeats( -# line 373 "LLgen.g" +# line 371 "LLgen.g" &kind, &cnt); -# line 374 "LLgen.g" +# line 372 "LLgen.g" { if (g_gettype(&elem) != TERM) { rule_table[n_rules] = elem; g_settype((&rule_table[n_rules+1]),EORULE); @@ -835,7 +769,7 @@ case /* ']' */ 28 : ; goto L_10; L_10: ; LLsdecr(4); -# line 384 "LLgen.g" +# line 382 "LLgen.g" { if (g_gettype(&elem) == TERM) { register p_term q = g_getterm(&elem); @@ -867,7 +801,7 @@ break; default: if (LLskip()) goto L_9; goto L_10; } -# line 411 "LLgen.g" +# line 409 "LLgen.g" { if (!termdeleted && g_gettype(&elem) == TERM) { register p_term q; @@ -877,7 +811,7 @@ goto L_10; if ((q->t_flags & RESOLVER) && (kind == PLUS || kind == FIXED)) { error(linecount, - "%%while not allowed in this term"); + "%%while not allowed in this term", NULL); } /* * A persistent fixed term is the same @@ -886,7 +820,7 @@ goto L_10; if ((q->t_flags & PERSISTENT) && kind == FIXED) { error(linecount, - "Illegal %%persistent"); + "Illegal %%persistent", NULL); } */ } @@ -900,7 +834,7 @@ continue; LLsdecr(3); break; } -# line 437 "LLgen.g" +# line 435 "LLgen.g" { register p_term q; g_settype((&rule_table[n_rules]),EORULE); @@ -918,11 +852,11 @@ break; elmcnt+1); } } -# line 454 "LLgen.g" +# line 452 "LLgen.g" -STATIC -mkterm(prod,flags,lc,result) p_gram prod; register p_gram result; { +STATIC void mkterm(p_gram prod, int flags,int lc,register p_gram result) +{ /* * Create a term, initialise it and return * a grammar element containing it @@ -944,19 +878,12 @@ mkterm(prod,flags,lc,result) p_gram prod; register p_gram result; { nterms++; } static -#if LL_ANSI_C void -#endif LL7_elem( -#if LL_ANSI_C -# line 480 "LLgen.g" +# line 478 "LLgen.g" register p_gram pres) -#else -# line 480 "LLgen.g" - pres) register p_gram pres; -#endif { -# line 481 "LLgen.g" +# line 479 "LLgen.g" register int t = 0; p_gram p1; int ln; @@ -972,7 +899,7 @@ LLtincr(12); LLsincr(1); LLtincr(28); LL_SAFE('['); -# line 489 "LLgen.g" +# line 487 "LLgen.g" { ln = linecount; } LLread(); goto L_4; @@ -1003,7 +930,7 @@ case /* C_WHILE */ 11 : ; LLtdecr(11); LL_SAFE(C_WHILE); LL_NOSCANDONE(C_EXPR); -# line 490 "LLgen.g" +# line 488 "LLgen.g" { t |= RESOLVER; } LLread(); } @@ -1034,18 +961,18 @@ else if (LL_11 & 1) goto L_5;} case /* C_PERSISTENT */ 12 : ; LLtdecr(12); LL_SAFE(C_PERSISTENT); -# line 492 "LLgen.g" +# line 490 "LLgen.g" { t |= PERSISTENT; } LLread(); } } LLsdecr(1); LL5_productions( -# line 494 "LLgen.g" +# line 492 "LLgen.g" &p1); LLtdecr(28); LL_SCANDONE(']'); -# line 495 "LLgen.g" +# line 493 "LLgen.g" { mkterm(p1,t,ln,pres); } @@ -1061,7 +988,7 @@ default: break; case /* C_ERRONEOUS */ 21 : ; LL_SAFE(C_ERRONEOUS); -# line 499 "LLgen.g" +# line 497 "LLgen.g" { #ifdef NON_CORRECTING erroneous = 1; @@ -1079,14 +1006,14 @@ L_9: ; LLsdecr(5); LLtincr(6); LL_SSCANDONE(C_IDENT); -# line 507 "LLgen.g" +# line 505 "LLgen.g" { pe = search(UNKNOWN,lextoken.t_string,BOTH); *pres = *pe; #ifdef NON_CORRECTING if (erroneous) { if (g_gettype(pres) != TERMINAL){ warning(linecount, - "Erroneous only allowed on terminal"); + "Erroneous only allowed on terminal", NULL); erroneous = 0; } else @@ -1122,13 +1049,13 @@ else if (LL_12 & 1) goto L_10;} case /* C_PARAMS */ 6 : ; LLtdecr(6); LL_SAFE(C_PARAMS); -# line 522 "LLgen.g" +# line 520 "LLgen.g" { if (lextoken.t_num > 15) { - error(linecount,"Too many parameters"); + error(linecount,"Too many parameters", NULL); } else g_setnpar(pres,lextoken.t_num); if (g_gettype(pres) == TERMINAL) { error(linecount, - "Terminal with parameters"); + "Terminal with parameters", NULL); } } LLread(); @@ -1140,7 +1067,7 @@ goto L_9; case /* C_LITERAL */ 4 : ; LLsdecr(5); LL_SAFE(C_LITERAL); -# line 531 "LLgen.g" +# line 529 "LLgen.g" { pe = search(LITERAL,lextoken.t_string,BOTH); *pres = *pe; #ifdef NON_CORRECTING @@ -1154,7 +1081,7 @@ break; break; default: LLtincr(7); -# line 539 "LLgen.g" +# line 537 "LLgen.g" { g_settype(pres,ACTION); pres->g_lineno = linecount; #ifdef NON_CORRECTING @@ -1169,14 +1096,14 @@ case /* C_SUBSTART */ 20 : ; LLtincr(23); LLtincr(24); LL_SAFE(C_SUBSTART); -# line 548 "LLgen.g" +# line 546 "LLgen.g" { #ifdef NON_CORRECTING nsubstarts++; #endif } LL_NOSCANDONE(C_IDENT); -# line 555 "LLgen.g" +# line 553 "LLgen.g" { #ifdef NON_CORRECTING register p_gram temp; @@ -1205,7 +1132,7 @@ else if (LL_13 & 1) goto L_12;} case /* ',' */ 23 : ; LL_SAFE(','); LL_NOSCANDONE(C_IDENT); -# line 571 "LLgen.g" +# line 569 "LLgen.g" { #ifdef NON_CORRECTING register p_gram temp; @@ -1249,24 +1176,17 @@ break; } } static -#if LL_ANSI_C void -#endif LL8_repeats( -#if LL_ANSI_C -# line 602 "LLgen.g" +# line 600 "LLgen.g" int *kind ,int *cnt) -#else -# line 602 "LLgen.g" - kind,cnt) int *kind; int *cnt; -#endif { -# line 602 "LLgen.g" +# line 600 "LLgen.g" int t1 = 0; switch(LLcsymb) { default: LL_SAFE('?'); -# line 604 "LLgen.g" +# line 602 "LLgen.g" { *kind = OPT; } LLread(); break; @@ -1276,12 +1196,12 @@ LLtincr(3); switch(LLcsymb) { default: LL_SAFE('*'); -# line 605 "LLgen.g" +# line 603 "LLgen.g" { *kind = STAR; } break; case /* '+' */ 31 : ; LL_SAFE('+'); -# line 606 "LLgen.g" +# line 604 "LLgen.g" { *kind = PLUS; } break; } @@ -1308,12 +1228,12 @@ else if (LL_14 & 1) goto L_7;} case /* C_NUMBER */ 3 : ; LLtdecr(3); LL9_number( -# line 608 "LLgen.g" +# line 606 "LLgen.g" &t1); LLread(); } } -# line 609 "LLgen.g" +# line 607 "LLgen.g" { if (t1 == 1) { t1 = 0; if (*kind == STAR) *kind = OPT; @@ -1323,52 +1243,41 @@ LLread(); break; case /* C_NUMBER */ 3 : ; LL9_number( -# line 615 "LLgen.g" +# line 613 "LLgen.g" &t1); LLread(); break; } -# line 616 "LLgen.g" +# line 614 "LLgen.g" { *cnt = t1; } } static -#if LL_ANSI_C void -#endif LL9_number( -#if LL_ANSI_C -# line 619 "LLgen.g" +# line 617 "LLgen.g" int *t) -#else -# line 619 "LLgen.g" - t) int *t; -#endif { LL_SAFE(C_NUMBER); -# line 621 "LLgen.g" +# line 619 "LLgen.g" { *t = lextoken.t_num; if (*t <= 0 || *t >= 8192) { - error(linecount,"Illegal number"); + error(linecount,"Illegal number", NULL); } } } static -#if LL_ANSI_C void -#endif LL4_firsts( -#if LL_ANSI_C void -#endif ) { -# line 628 "LLgen.g" +# line 626 "LLgen.g" register string p; LLtincr(23); LLtincr(2); LLtincr(24); LL_SAFE(C_FIRST); LL_NOSCANDONE(C_IDENT); -# line 630 "LLgen.g" +# line 628 "LLgen.g" { p = store(lextoken.t_string); } LLtdecr(23); LL_NOSCANDONE(','); @@ -1376,7 +1285,7 @@ LLtdecr(2); LL_NOSCANDONE(C_IDENT); LLtdecr(24); LL_NOSCANDONE(';'); -# line 632 "LLgen.g" +# line 630 "LLgen.g" { /* * Store this %first in the list belonging * to this input file @@ -1393,11 +1302,11 @@ LL_NOSCANDONE(';'); } } -# line 647 "LLgen.g" +# line 645 "LLgen.g" -STATIC p_gram -copyrule(p,length) register p_gram p; { +STATIC p_gram copyrule(register p_gram p,int length) +{ /* * Returns a pointer to a grammar rule that was created in * p. The space pointed to by p can now be reused diff --git a/util/LLgen/src/LLgen.g b/util/LLgen/src/LLgen.g index c64c15b33..d3dae69ed 100644 --- a/util/LLgen/src/LLgen.g +++ b/util/LLgen/src/LLgen.g @@ -18,13 +18,13 @@ */ { -# include -# include -# include "types.h" -# include "io.h" -# include "extern.h" -# include "assert.h" -# include "cclass.h" +#include +#include +#include "types.h" +#include "io.h" +#include "extern.h" +#include "assert.h" +#include "cclass.h" # ifndef NORCSID static string rcsid = "$Id$"; @@ -48,15 +48,14 @@ static int max_rules; #define RULEINCR 32 /* Here are defined : */ -STATIC newnorder(); -STATIC newtorder(); -STATIC mkalt(); -STATIC mkterm(); -STATIC p_gram copyrule(); +STATIC void newnorder(int index); +STATIC void newtorder(int index); +STATIC void mkalt(p_gram prod, int condition,int lc,register p_gram res); +STATIC void mkterm(p_gram prod, int flags,int lc,register p_gram result); +STATIC p_gram copyrule(register p_gram p,int length); /* and of course LLparse() */ -STATIC -newnorder(index) { +STATIC void newnorder(int index) { static int porder; if (norder != -1) { @@ -67,8 +66,7 @@ newnorder(index) { nonterms[porder].n_next = -1; } -STATIC -newtorder(index) { +STATIC void newtorder(int index) { static int porder; if (torder != -1) { @@ -79,7 +77,7 @@ newtorder(index) { tokens[porder].t_next = -1; } -p_init() +void p_init(void) { alt_table = (p_gram )alloc(ALTINCR*sizeof(t_gram)); n_alts = 0; @@ -149,7 +147,7 @@ def { register string p; } { if (!lexical) { lexical = store(lextoken.t_string); } - else error(linecount,"Duplicate %%lexical"); + else error(linecount,"Duplicate %%lexical", NULL); } ';' | C_PREFIX C_IDENT @@ -160,25 +158,25 @@ def { register string p; } prefix = store(lextoken.t_string); if (strlen(prefix) > 6) { error(linecount, - "%%prefix too long"); + "%%prefix too long",NULL); prefix[6] = 0; } } - else error(linecount,"Duplicate %%prefix"); + else error(linecount,"Duplicate %%prefix", NULL); } ';' | C_ONERROR C_IDENT { #ifdef NON_CORRECTING if (non_corr) { - warning(linecount, "%%onerror conflicts with -n option"); + warning(linecount, "%%onerror conflicts with -n option", NULL); } else #endif if (! onerror) { onerror = store(lextoken.t_string); } - else error(linecount,"Duplicate %%onerror"); + else error(linecount,"Duplicate %%onerror", NULL); } ';' | C_ACTION { acount++; } @@ -225,7 +223,7 @@ rule { register p_nont p; [ C_PARAMS { if (lextoken.t_num > 0) { p->n_flags |= PARAMS; if (lextoken.t_num > 15) { - error(linecount,"Too many parameters"); + error(linecount,"Too many parameters", NULL); } else setntparams(p,lextoken.t_num); } @@ -268,7 +266,7 @@ productions(p_gram *p;) if (t & DEF) { if (haddefault) { error(n_lc, - "More than one %%default in alternation"); + "More than one %%default in alternation", NULL); } haddefault = 1; } @@ -281,7 +279,7 @@ productions(p_gram *p;) } ]+ { if (conflres & (COND|PREFERING|AVOIDING)) { error(n_lc, - "Resolver on last alternative not allowed"); + "Resolver on last alternative not allowed", NULL); } mkalt(*p,conflres,n_lc,&alt_table[n_alts++]); altcnt++; @@ -291,12 +289,12 @@ productions(p_gram *p;) | { if (conflres & (COND|PREFERING|AVOIDING)) { error(o_lc, - "No alternation conflict resolver allowed here"); + "No alternation conflict resolver allowed here", NULL); } /* if (conflres & DEF) { error(o_lc, - "No %%default allowed here"); + "No %%default allowed here", NULL); } */ } @@ -305,8 +303,8 @@ productions(p_gram *p;) ; { -STATIC -mkalt(prod,condition,lc,res) p_gram prod; register p_gram res; { +STATIC void mkalt(p_gram prod, int condition,int lc,register p_gram res) +{ /* * Create an alternation and initialise it. */ @@ -356,7 +354,7 @@ simpleproduction(p_gram *p; register int *conflres;) rule_table[n_rules++] = *search(TERMINAL, "LLILLEGAL", BOTH); if (*conflres & DEF) { - error(linecount, "%%illegal not allowed in %%default rule"); + error(linecount, "%%illegal not allowed in %%default rule", NULL); } #endif } @@ -417,7 +415,7 @@ simpleproduction(p_gram *p; register int *conflres;) if ((q->t_flags & RESOLVER) && (kind == PLUS || kind == FIXED)) { error(linecount, - "%%while not allowed in this term"); + "%%while not allowed in this term", NULL); } /* * A persistent fixed term is the same @@ -426,7 +424,7 @@ simpleproduction(p_gram *p; register int *conflres;) if ((q->t_flags & PERSISTENT) && kind == FIXED) { error(linecount, - "Illegal %%persistent"); + "Illegal %%persistent", NULL); } */ } @@ -453,8 +451,8 @@ simpleproduction(p_gram *p; register int *conflres;) ; { -STATIC -mkterm(prod,flags,lc,result) p_gram prod; register p_gram result; { +STATIC void mkterm(p_gram prod, int flags,int lc,register p_gram result) +{ /* * Create a term, initialise it and return * a grammar element containing it @@ -510,7 +508,7 @@ elem (register p_gram pres;) if (erroneous) { if (g_gettype(pres) != TERMINAL){ warning(linecount, - "Erroneous only allowed on terminal"); + "Erroneous only allowed on terminal", NULL); erroneous = 0; } else @@ -520,11 +518,11 @@ elem (register p_gram pres;) } [ C_PARAMS { if (lextoken.t_num > 15) { - error(linecount,"Too many parameters"); + error(linecount,"Too many parameters", NULL); } else g_setnpar(pres,lextoken.t_num); if (g_gettype(pres) == TERMINAL) { error(linecount, - "Terminal with parameters"); + "Terminal with parameters", NULL); } } ]? @@ -620,7 +618,7 @@ number(int *t;) : C_NUMBER { *t = lextoken.t_num; if (*t <= 0 || *t >= 8192) { - error(linecount,"Illegal number"); + error(linecount,"Illegal number", NULL); } } ; @@ -646,8 +644,8 @@ firsts { register string p; } ; { -STATIC p_gram -copyrule(p,length) register p_gram p; { +STATIC p_gram copyrule(register p_gram p,int length) +{ /* * Returns a pointer to a grammar rule that was created in * p. The space pointed to by p can now be reused diff --git a/util/LLgen/src/Lpars.c b/util/LLgen/src/Lpars.c index e241c0e9a..1b002de34 100644 --- a/util/LLgen/src/Lpars.c +++ b/util/LLgen/src/Lpars.c @@ -1,9 +1,6 @@ /* LLgen generated code from source . */ #include "Lpars.h" #define LLNOFIRSTS -#if __STDC__ || __cplusplus -#define LL_ANSI_C 1 -#endif #define LL_LEXI scanner /* $Id$ */ #ifdef LL_DEBUG @@ -37,7 +34,6 @@ extern int LLstartsymb; #define LLsincr(d) LLscnt[d]++ #define LLtincr(d) LLtcnt[d]++ -#if LL_ANSI_C extern int LL_LEXI(void); extern void LLread(void); extern int LLskip(void); @@ -55,35 +51,11 @@ extern int LLfirst(int, int); #if LL_NON_CORR extern void LLnc_recover(void); #endif -#else /* not LL_ANSI_C */ -extern LLread(); -extern int LLskip(); -extern int LLnext(); -extern LLerror(); -extern LLsafeerror(); -extern LLnewlevel(); -extern LLoldlevel(); -#ifndef LL_FASTER -extern LLscan(); -#endif -#ifndef LLNOFIRSTS -extern int LLfirst(); -#endif -#if LL_NON_CORR -extern LLnc_recover(); -#endif -#endif /* not LL_ANSI_C */ #define LL_SSIZE 4 #define LL_NSETS 6 #define LL_NTERMINALS 32 -#if LL_ANSI_C void LL0_spec(void); -#endif -#if LL_ANSI_C void LLparse(void) -#else -LLparse() -#endif { unsigned int s[LL_NTERMINALS+LL_NSETS+2]; LLnewlevel(s); @@ -401,29 +373,15 @@ int LLstartsymb; static int fake_eof = 0; #endif -#if LL_ANSI_C #define LL_VOIDCST (void) void LLmessage(int); -#else -#define LL_VOIDCST -#endif #ifdef LL_USERHOOK -#if LL_ANSI_C static int LLdoskip(int); static int LLuserhook(int, int*); -#else -static int LLdoskip(); -static int LLuserhook(); -#endif #endif #ifndef LL_FASTER -#if LL_ANSI_C void LLscan(int t) -#else -LLscan(t) - int t; -#endif { /* * Check if the next symbol is equal to the parameter @@ -469,12 +427,7 @@ LLscan(t) } #endif -#if LL_ANSI_C void LLread(void) { -#else -LLread() { -#endif - #if LL_NON_CORR /* Again, check if another parser has crashed, * in that case intercept and go to the @@ -506,12 +459,7 @@ LLread() { /* NOTREACHED */ } -#if LL_ANSI_C void LLerror(int t) -#else -LLerror(t) - int t; -#endif { register int i; @@ -573,12 +521,7 @@ LLerror(t) } } -#if LL_ANSI_C void LLsafeerror(int t) -#else -LLsafeerror(t) - int t; -#endif { if (t == EOFILE && LLsymb <= 0) return; #ifdef LL_NEWMESS @@ -621,11 +564,7 @@ LLsafeerror(t) } #ifndef LLNOFIRSTS -#if LL_ANSI_C int LLfirst(int x, int d) { -#else -int LLfirst(x, d) { -#endif register int i; return (i = LLindex[x]) >= 0 && @@ -633,12 +572,7 @@ int LLfirst(x, d) { } #endif -#if LL_ANSI_C int LLnext(int n) -#else -int LLnext(n) - int n; -#endif { /* returns: 0 if the current symbol is'nt skipped, and it is'nt a member of "n", @@ -659,11 +593,7 @@ int LLnext(n) return retval; } -#if LL_ANSI_C int LLskip(void) { -#else -int LLskip() { -#endif /* returns 0 if the current symbol is'nt skipped, and 1 if it is, t.i., we have a new symbol */ @@ -671,14 +601,8 @@ int LLskip() { return LLdoskip(0); } -#if LL_ANSI_C extern void LL_USERHOOK(int, int *); static int LLuserhook(int e, int *list) -#else -static int LLuserhook(e, list) - int e; - int *list; -#endif { int old = LLsymb; LL_USERHOOK(e, list); @@ -686,12 +610,7 @@ static int LLuserhook(e, list) return LLsymb != old; } -#if LL_ANSI_C static void LLmklist(register int *list) -#else -static LLmklist(list) - register int *list; -#endif { char Xset[LL_SSIZE]; register char *p; @@ -715,12 +634,7 @@ static LLmklist(list) *list = 0; } -#if LL_ANSI_C static int LLdoskip(int e) -#else -static int LLdoskip(e) - int e; -#endif { int LLx; int list[LL_NTERMINALS+1]; @@ -779,11 +693,7 @@ static int LLdoskip(e) /* NOTREACHED */ } -#if LL_ANSI_C void LLnewlevel(unsigned int *LLsinfo) { -#else -LLnewlevel(LLsinfo) unsigned int *LLsinfo; { -#endif register int i; if (LLlevel++) { @@ -801,11 +711,7 @@ LLnewlevel(LLsinfo) unsigned int *LLsinfo; { LLtincr(0); } -#if LL_ANSI_C void LLoldlevel(unsigned int *LLsinfo) { -#else -LLoldlevel(LLsinfo) unsigned int *LLsinfo; { -#endif register int i; LLtdecr(0); diff --git a/util/LLgen/src/alloc.c b/util/LLgen/src/alloc.c index 25ca26d6e..eb089d135 100644 --- a/util/LLgen/src/alloc.c +++ b/util/LLgen/src/alloc.c @@ -17,6 +17,7 @@ */ #include +# include "alloc.h" # include "types.h" # include "extern.h" @@ -26,29 +27,29 @@ static string rcsid = "$Id$"; static string e_nomem = "Out of memory"; -p_mem -alloc(size) unsigned size; { +p_mem alloc(unsigned int size) +{ /* Allocate "size" bytes. Panic if it fails */ p_mem p; - if ((p = malloc(size)) == 0) fatal(linecount,e_nomem); + if ((p = malloc(size)) == 0) fatal(linecount,e_nomem, NULL); return p; } -p_mem -ralloc(p,size) p_mem p; unsigned size; { +p_mem ralloc(p_mem p,unsigned int size) +{ /* Re-allocate the chunk of memory indicated by "p", to occupy "size" bytes */ - if ((p = realloc(p,size)) == 0) fatal(linecount,e_nomem); + if ((p = realloc(p,size)) == 0) fatal(linecount,e_nomem, NULL); return p; } -p_mem -new_mem(p) register p_info p; { +p_mem new_mem(register p_info p) +{ /* This routine implements arrays that can grow. It must be called every time a new element is added to it. diff --git a/util/LLgen/src/alloc.h b/util/LLgen/src/alloc.h new file mode 100644 index 000000000..a86b46064 --- /dev/null +++ b/util/LLgen/src/alloc.h @@ -0,0 +1,19 @@ +/* Copyright (c) 2019 ACK Project. + * See the copyright notice in the ACK home directory, + * in the file "Copyright". + * + * Created on: 2019-02-16 + * + */ +#ifndef ALLOC_H_ +#define ALLOC_H_ + +#include "types.h" + +p_mem alloc(unsigned int size); +p_mem ralloc(p_mem p,unsigned int size); +p_mem new_mem(register p_info p); + + + +#endif /* ALLOC_H_ */ diff --git a/util/LLgen/src/check.c b/util/LLgen/src/check.c index 6efe80c02..488021c72 100644 --- a/util/LLgen/src/check.c +++ b/util/LLgen/src/check.c @@ -17,6 +17,7 @@ */ #include +#include #include # include "types.h" # include "extern.h" @@ -28,247 +29,287 @@ static string rcsid1 = "$Id$"; # endif -static string c_first = "> firstset "; -static string c_contains = "> containset "; -static string c_follow = "> followset "; -p_set setalloc(); -static int level; +static string c_first = "> firstset "; +static string c_contains = "> containset "; +static string c_follow = "> followset "; +p_set setalloc(); +static int level; /* In this file are defined : */ -extern conflchecks(); -STATIC prline(); -STATIC printset(); -STATIC int check(); -STATIC moreverbose(); -STATIC void prrule(p_gram p); -STATIC cfcheck(); -STATIC void resolve(p_gram p); -STATIC propagate(); -STATIC spaces(); +void conflchecks(void); +STATIC void prline(char *); +STATIC void printset(register p_set, string); +STATIC int check(register p_gram); +STATIC void moreverbose(register p_set); +STATIC void prrule(p_gram); +STATIC void cfcheck(p_set, p_set, int); +STATIC void resolve(p_gram); +STATIC void propagate(p_set, register p_gram); +STATIC void spaces(void); -conflchecks() { - /* - * Check for conflicts, that is, - * in a repeating term, the FIRST and FOLLOW must be disjunct, - * unless there is a disambiguating condition. - * in an alternation, the sets that determine the direction to take, - * must be disjunct. - */ - register p_nont p; +/* + * Check for conflicts, that is, + * in a repeating term, the FIRST and FOLLOW must be disjunct, + * unless there is a disambiguating condition. + * in an alternation, the sets that determine the direction to take, + * must be disjunct. + */ +void conflchecks(void) +{ + register p_nont p; register int s; - p_file x = files; + p_file x = files; f_input = x->f_name; - if (verbose >= 3) { - for (p = nonterms; p < maxnt; p++) p->n_flags |= VERBOSE; + if (verbose >= 3) + { + for (p = nonterms; p < maxnt; p++) + p->n_flags |= VERBOSE; } - if (verbose) { - if ((fout = fopen(f_out,"w")) == NULL) fatal(1,e_noopen,f_out); + if (verbose) + { + if ((fout = fopen(f_out, "w")) == NULL) + fatal(1, e_noopen, f_out); } /* * Check the rules in the order in which they are declared, * and input file by input file, to give proper error messages */ - for (; x < maxfiles; x++) { - f_input = x->f_name; - for (s = x->f_nonterminals; s != -1; s = p->n_next) { - p = &nonterms[s]; - if (check(p->n_rule)) p->n_flags |= VERBOSE; - } - } - for (x = files; x < maxfiles; x++) { - f_input = x->f_name; - for (s = x->f_nonterminals; s != -1; s = p->n_next) { - p = &nonterms[s]; - if (p->n_flags & RECURSIVE) { - error(p->n_lineno, - "Recursion in default for nonterminal %s", - p->n_name); + for (; x < maxfiles; x++) + { + f_input = x->f_name; + for (s = x->f_nonterminals; s != -1; s = p->n_next) + { + p = &nonterms[s]; + if (check(p->n_rule)) + p->n_flags |= VERBOSE; } - /* - * If a printout is needed for this rule in - * LL.output, just do it - */ - if (verbose && (p->n_flags & VERBOSE)) { - fprintf(fout,"\n%s :\n",p->n_name); - printset(p->n_first,c_first); - printset(p->n_contains,c_contains); - printset(p->n_follow,c_follow); - fprintf(fout,"> rule%s\n\t", - p->n_flags&EMPTY ? "\t(EMPTY producing)" : ""); - level = 8; - prrule(p->n_rule); - level = 0; - prline("\n"); - } - /* - * Now, the conflicts may be resolved - */ - resolve(p->n_rule); - } } - if (verbose) fclose(fout); + for (x = files; x < maxfiles; x++) + { + f_input = x->f_name; + for (s = x->f_nonterminals; s != -1; s = p->n_next) + { + p = &nonterms[s]; + if (p->n_flags & RECURSIVE) + { + error(p->n_lineno, "Recursion in default for nonterminal %s", + p->n_name); + } + /* + * If a printout is needed for this rule in + * LL.output, just do it + */ + if (verbose && (p->n_flags & VERBOSE)) + { + fprintf(fout, "\n%s :\n", p->n_name); + printset(p->n_first, c_first); + printset(p->n_contains, c_contains); + printset(p->n_follow, c_follow); + fprintf(fout, "> rule%s\n\t", + p->n_flags & EMPTY ? "\t(EMPTY producing)" : ""); + level = 8; + prrule(p->n_rule); + level = 0; + prline("\n"); + } + /* + * Now, the conflicts may be resolved + */ + resolve(p->n_rule); + } + } + if (verbose) + fclose(fout); } -STATIC -prline(s) char *s; { +STATIC void prline(char *s) +{ fputs(s, fout); spaces(); } -STATIC -printset(p,s) register p_set p; string s; { +STATIC void printset(register p_set p, string s) +{ /* * Print the elements of a set */ - register int i; - register int j; + register int i; + register int j; register p_token pt; - string name; - int k; - int hulp; + string name; + int k; + int hulp; k = strlen(s) + 2 + level; /* * k contains relative level of indentation */ - fprintf(fout,"%s{ ",s); + fprintf(fout, "%s{ ", s); j = k; /* * j will gather the total length of the line */ - for (i = 0, pt = tokens; i < ntokens; i++,pt++) { - if (IN(p,i)) { - hulp = strlen(pt->t_string)+1; - if (pt->t_tokno < 0400) hulp += 2; - if ((j += hulp) >= 78) { + for (i = 0, pt = tokens; i < ntokens; i++, pt++) + { + if (IN(p, i)) + { + hulp = strlen(pt->t_string) + 1; + if (pt->t_tokno < 0400) + hulp += 2; + if ((j += hulp) >= 78) + { /* * Line becoming too long */ - j = k+hulp; - prline("\n"); - fprintf(fout,">%*c",k - level - 1,' '); - } - fprintf(fout, pt->t_tokno<0400 ? "'%s' " : "%s ",pt->t_string); - } - } - if (ntprint) for (i = 0; i < nnonterms; i++) { - /* - * Nonterminals in the set must also be printed - */ - if (NTIN(p,i)) { - name = nonterms[i].n_name; - hulp = strlen(name) + 3; - if ((j += hulp) >= 78) { j = k + hulp; prline("\n"); - fprintf(fout,">%*c",k - level - 1,' '); + fprintf(fout, ">%*c", k - level - 1, ' '); } - fprintf(fout,"<%s> ",name); + fprintf(fout, pt->t_tokno < 0400 ? "'%s' " : "%s ", pt->t_string); } } + if (ntprint) + for (i = 0; i < nnonterms; i++) + { + /* + * Nonterminals in the set must also be printed + */ + if (NTIN(p, i)) + { + name = nonterms[i].n_name; + hulp = strlen(name) + 3; + if ((j += hulp) >= 78) + { + j = k + hulp; + prline("\n"); + fprintf(fout, ">%*c", k - level - 1, ' '); + } + fprintf(fout, "<%s> ", name); + } + } prline("}\n"); } -STATIC int -check(p) register p_gram p; { +STATIC int check(register p_gram p) +{ /* * Search for conflicts in a grammar rule. */ - register p_set temp; + register p_set temp; register int retval; retval = 0; - for (;;) { - switch (g_gettype(p)) { - case EORULE : + for (;;) + { + switch (g_gettype(p)) + { + case EORULE: return retval; - case NONTERM : { + case NONTERM: + { register p_nont n; n = &nonterms[g_getcont(p)]; - if (g_getnpar(p) != getntparams(n)) { - error(p->g_lineno, - "Call of %s: parameter count mismatch", - n->n_name); + if (g_getnpar(p) != getntparams(n)) + { + error(p->g_lineno, "Call of %s: parameter count mismatch", + n->n_name); } - break; } - case TERM : { + break; + } + case TERM: + { register p_term q; q = g_getterm(p); retval |= check(q->t_rule); - if (r_getkind(q) == FIXED) break; - if (setempty(q->t_first)) { + if (r_getkind(q) == FIXED) + break; + if (setempty(q->t_first)) + { q->t_flags |= EMPTYFIRST; retval = 1; - error(p->g_lineno, "No symbols in term"); + error(p->g_lineno, "No symbols in term", NULL); } - if (empty(q->t_rule)) { + if (empty(q->t_rule)) + { q->t_flags |= EMPTYTERM; retval = 1; - error(p->g_lineno, "Term with variable repetition count produces empty"); + error(p->g_lineno, + "Term with variable repetition count produces empty", + NULL); } temp = setalloc(); - setunion(temp,q->t_first); - if (!setintersect(temp,q->t_follow)) { + setunion(temp, q->t_first); + if (!setintersect(temp, q->t_follow)) + { /* * q->t_first * q->t_follow != EMPTY */ - if (!(q->t_flags & RESOLVER)) { + if (!(q->t_flags & RESOLVER)) + { /* * No conflict resolver */ - error(p->g_lineno, - "Repetition conflict"); + error(p->g_lineno, "Repetition conflict", NULL); retval = 1; moreverbose(temp); } } - else { - if (q->t_flags & RESOLVER) { + else + { + if (q->t_flags & RESOLVER) + { q->t_flags |= NOCONF; - warning(p->g_lineno, - "%%while without conflict"); + warning(p->g_lineno, "%%while without conflict", NULL); } } free((p_mem) temp); - break; } - case ALTERNATION : { + break; + } + case ALTERNATION: + { register p_link l; l = g_getlink(p); temp = setalloc(); - setunion(temp,l->l_symbs); - if(!setintersect(temp,l->l_others)) { + setunion(temp, l->l_symbs); + if (!setintersect(temp, l->l_others)) + { /* * temp now contains the conflicting * symbols */ - if (!(l->l_flag & (COND|PREFERING|AVOIDING))) { - error(p->g_lineno, -"Alternation conflict"); + if (!(l->l_flag & (COND | PREFERING | AVOIDING))) + { + error(p->g_lineno, "Alternation conflict", NULL); retval = 1; moreverbose(temp); } - } else { - if (l->l_flag & (COND|PREFERING|AVOIDING)) { + } + else + { + if (l->l_flag & (COND | PREFERING | AVOIDING)) + { l->l_flag |= NOCONF; - warning(p->g_lineno, -"Conflict resolver without conflict"); + warning(p->g_lineno, "Conflict resolver without conflict", + NULL); } } - free( (p_mem) temp); - if (l->l_flag & PREFERING) propagate(l->l_symbs,p+1); + free((p_mem) temp); + if (l->l_flag & PREFERING) + propagate(l->l_symbs, p + 1); retval |= check(l->l_rule); - break; } + break; + } } p++; } } -STATIC -moreverbose(t) register p_set t; { +STATIC void moreverbose(register p_set t) +{ /* * t points to a set containing conflicting symbols and pssibly * also containing nonterminals. @@ -277,116 +318,141 @@ moreverbose(t) register p_set t; { register int i; register p_nont p; - if (verbose == 2) for (i = 0, p = nonterms; i < nnonterms; i++, p++) { - if (NTIN(t,i)) p->n_flags |= VERBOSE; - } + if (verbose == 2) + for (i = 0, p = nonterms; i < nnonterms; i++, p++) + { + if (NTIN(t, i)) + p->n_flags |= VERBOSE; + } } -STATIC -void prrule(p_gram p) { +STATIC void prrule(p_gram p) +{ /* * Create a verbose printout of grammar rule p */ - register FILE *f; - int present = 0; - int firstalt = 1; + register FILE *f; + int present = 0; + int firstalt = 1; f = fout; - for (;;) { - switch (g_gettype(p)) { - case EORULE : - fputs("\n",f); + for (;;) + { + switch (g_gettype(p)) + { + case EORULE: + fputs("\n", f); return; - case TERM : { - register p_term q; - register int c; + case TERM: + { + register p_term q; + register int c; q = g_getterm(p); - if (present) prline("\n"); - fputs("[ ",f); + if (present) + prline("\n"); + fputs("[ ", f); level += 4; - if (q->t_flags & RESOLVER) { + if (q->t_flags & RESOLVER) + { prline("%while (..)\n"); } - if (q->t_flags & PERSISTENT) { + if (q->t_flags & PERSISTENT) + { prline("%persistent\n"); } - if (r_getkind(q) != FIXED) { - if (!(q->t_flags & PERSISTENT)) { - prline("> continue repetition on the\n"); + if (r_getkind(q) != FIXED) + { + if (!(q->t_flags & PERSISTENT)) + { + prline("> continue repetition on the\n"); } printset(q->t_first, c_first); - if (q->t_flags & PERSISTENT) { - prline("> continue repetition on the\n"); + if (q->t_flags & PERSISTENT) + { + prline("> continue repetition on the\n"); } printset(q->t_contains, c_contains); prline("> terminate repetition on the\n"); - printset(q->t_follow,c_follow); - if (q->t_flags & EMPTYFIRST) { - prline(">>> empty first\n"); + printset(q->t_follow, c_follow); + if (q->t_flags & EMPTYFIRST) + { + prline(">>> empty first\n"); } - if (q->t_flags & EMPTYTERM) { - prline(">>> term produces empty\n"); + if (q->t_flags & EMPTYTERM) + { + prline(">>> term produces empty\n"); } - cfcheck(q->t_first,q->t_follow, - q->t_flags & RESOLVER); + cfcheck(q->t_first, q->t_follow, q->t_flags & RESOLVER); } prrule(q->t_rule); level -= 4; spaces(); c = r_getkind(q); - fputs(c == STAR ? "]*" : c == PLUS ? "]+" : - c == OPT ? "]?" : "]", f); - if (c = r_getnum(q)) { - fprintf(f,"%d",c); + fputs(c == STAR ? "]*" : c == PLUS ? "]+" : c == OPT ? "]?" : "]", + f); + if ((c = r_getnum(q))) + { + fprintf(f, "%d", c); } prline("\n"); - break; } - case ACTION : - fputs("{..} ",f); break; - case ALTERNATION : { + } + case ACTION: + fputs("{..} ", f); + break; + case ALTERNATION: + { register p_link l; l = g_getlink(p); - if (firstalt) { + if (firstalt) + { firstalt = 0; } - else prline("|\n"); - printset(l->l_symbs,"> alternative on "); - cfcheck(l->l_symbs, - l->l_others, - (int)(l->l_flag&(COND|PREFERING|AVOIDING))); - fputs(" ",f); + else + prline("|\n"); + printset(l->l_symbs, "> alternative on "); + cfcheck(l->l_symbs, l->l_others, + (int) (l->l_flag & (COND | PREFERING | AVOIDING))); + fputs(" ", f); level += 4; - if (l->l_flag & DEF) { + if (l->l_flag & DEF) + { prline("%default\n"); } - if (l->l_flag & AVOIDING) { + if (l->l_flag & AVOIDING) + { prline("%avoid\n"); } - if (l->l_flag & PREFERING) { + if (l->l_flag & PREFERING) + { prline("%prefer\n"); } - if (l->l_flag & COND) { + if (l->l_flag & COND) + { prline("%if ( ... )\n"); } prrule(l->l_rule); level -= 4; - if (g_gettype(p+1) == EORULE) { + if (g_gettype(p+1) == EORULE) + { return; } spaces(); - p++; continue; } - case LITERAL : - case TERMINAL : { + p++; + continue; + } + case LITERAL: + case TERMINAL: + { register p_token pt = &tokens[g_getcont(p)]; - fprintf(f,pt->t_tokno<0400 ? - "'%s' " : "%s ", pt->t_string); - break; } - case NONTERM : - fprintf(f,"%s ",nonterms[g_getcont(p)].n_name); + fprintf(f, pt->t_tokno < 0400 ? "'%s' " : "%s ", pt->t_string); + break; + } + case NONTERM: + fprintf(f, "%s ", nonterms[g_getcont(p)].n_name); break; } p++; @@ -394,8 +460,8 @@ void prrule(p_gram p) { } } -STATIC -cfcheck(s1,s2,flag) p_set s1,s2; { +STATIC void cfcheck(p_set s1, p_set s2, int flag) +{ /* * Check if s1 and s2 have elements in common. * If so, flag must be non-zero, indicating that there is a @@ -405,70 +471,82 @@ cfcheck(s1,s2,flag) p_set s1,s2; { register p_set temp; temp = setalloc(); - setunion(temp,s1); - if (!setintersect(temp,s2)) { - if (! flag) { - printset(temp,">>> conflict on "); + setunion(temp, s1); + if (!setintersect(temp, s2)) + { + if (!flag) + { + printset(temp, ">>> conflict on "); prline("\n"); } - } else { - if (flag) { + } + else + { + if (flag) + { prline(">>> %if/%while, no conflict\n"); } } free((p_mem) temp); } -STATIC -void resolve(p_gram p) { +STATIC void resolve(p_gram p) +{ /* * resolve conflicts, as specified by the user */ - for (;;) { - switch (g_gettype(p)) { - case EORULE : + for (;;) + { + switch (g_gettype(p)) + { + case EORULE: return; - case TERM : + case TERM: resolve(g_getterm(p)->t_rule); break; - case ALTERNATION : { - register p_link l; + case ALTERNATION: + { + register p_link l; l = g_getlink(p); - if (l->l_flag & AVOIDING) { + if (l->l_flag & AVOIDING) + { /* * On conflicting symbols, this rule * is never chosen */ - setminus(l->l_symbs,l->l_others); + setminus(l->l_symbs, l->l_others); } - if (setempty(l->l_symbs)) { + if (setempty(l->l_symbs)) + { /* * This may be caused by the statement above */ - error(p->g_lineno,"Alternative never chosen"); + error(p->g_lineno, "Alternative never chosen", NULL); } resolve(l->l_rule); - break; } + break; + } } p++; } } -STATIC -propagate(set,p) p_set set; register p_gram p; { +STATIC void propagate(p_set set, register p_gram p) +{ /* * Propagate the fact that on the elements of set the grammar rule * p will not be chosen. */ - while (g_gettype(p) != EORULE) { - setminus(g_getlink(p)->l_symbs,set); + while (g_gettype(p) != EORULE) + { + setminus(g_getlink(p)->l_symbs, set); p++; } } -STATIC -spaces() { - - if (level > 0) fprintf(fout,"%*c",level,' '); +STATIC void spaces(void) +{ + if (level > 0) + fprintf(fout, "%*c", level, ' '); } diff --git a/util/LLgen/src/compute.c b/util/LLgen/src/compute.c index c16c6725c..fddd7b3e0 100644 --- a/util/LLgen/src/compute.c +++ b/util/LLgen/src/compute.c @@ -18,6 +18,8 @@ */ # include +# include +# include "alloc.h" # include "types.h" # include "extern.h" # include "sets.h" @@ -28,70 +30,81 @@ static string rcsid = "$Id$"; # endif -p_set get_set(); -typedef struct lngth { - /* Structure used to compute the shortest possible - * length of a terminal production of a rule. - * In case of a tie, the second field is used. - */ +p_set get_set(); +typedef struct lngth +{ + /* Structure used to compute the shortest possible + * length of a terminal production of a rule. + * In case of a tie, the second field is used. + */ int cnt; int val; } t_length, *p_length; /* Defined in this file : */ -extern do_compute(); -STATIC createsets(); -STATIC void walk(); -STATIC co_trans(); -STATIC int nempty(); -extern empty(); -STATIC int nfirst(); -STATIC first(); -STATIC int nfollow(); -STATIC follow(); -STATIC void co_dirsymb(); -STATIC co_others(); -STATIC do_lengthcomp(); -STATIC void complength(); -STATIC void add(); -STATIC int compare(); -STATIC void setdefaults(); -STATIC do_contains(); -STATIC void contains(); -STATIC int nsafes(); -STATIC int do_safes(); -#ifdef NON_CORRECTING -STATIC int nc_nfirst(); -STATIC nc_first(); -STATIC int nc_nfollow(); -STATIC nc_follow(); -#endif -do_compute() { - /* - * Does all the work, by calling other routines (divide and conquer) - */ - register p_nont p; +void do_compute(void); +STATIC void createsets(void); +STATIC void walk(p_set u, register p_gram p); +STATIC void co_trans(int (*fc)()); +STATIC int nempty(register p_nont p); +int empty(register p_gram p); +STATIC int nfirst(register p_nont p); +#ifdef NON_CORRECTING +STATIC int nc_nfirst(register p_nont p); +#endif +STATIC int first(p_set setp, register p_gram p, int flag); +#ifdef NON_CORRECTING +STATIC int nc_first(p_set setp,register p_gram p,int flag); +#endif +STATIC int nfollow(register p_nont p); +STATIC int follow(p_set setp, register p_gram p); +#ifdef NON_CORRECTING +STATIC int nc_nfollow(register p_nont p); +#endif +STATIC void co_dirsymb(p_set setp, register p_gram p); +STATIC void co_others(p_gram p); +STATIC int ncomplength(p_nont p); +STATIC void do_lengthcomp(void); +STATIC void complength(register p_gram p, p_length le); +STATIC void add(register p_length a, int c, int v); +STATIC int compare(p_length a, p_length b); +STATIC void setdefaults(register p_gram p); +STATIC void do_contains(register p_nont n); +STATIC void contains(register p_gram p, register p_set set); +STATIC int nsafes(register p_nont p); +STATIC int do_safes(register p_gram p, int safe, register int *ch); +int t_safety(int rep, int count, int persistent, int safety); +int t_after(int rep, int count, int outsafety); + +/* + * Does all the work, by calling other routines (divide and conquer) + */ +void do_compute(void) +{ + register p_nont p; register p_start st; createsets(); - co_trans(nempty); /* Which nonterminals produce empty? */ - co_trans(nfirst); /* Computes first sets */ + co_trans(nempty); /* Which nonterminals produce empty? */ + co_trans(nfirst); /* Computes first sets */ /* * Compute FOLLOW sets. * First put EOFILE in the follow set of the start nonterminals. */ - for (st = start; st; st = st->ff_next) { + for (st = start; st; st = st->ff_next) + { p = &nonterms[st->ff_nont]; - PUTIN(p->n_follow,0); + PUTIN(p->n_follow, 0); } co_trans(nfollow); /* * Compute the sets which determine which alternative to choose * in case of a choice */ - for (p = nonterms; p < maxnt; p++) { - co_dirsymb(p->n_follow,p->n_rule); + for (p = nonterms; p < maxnt; p++) + { + co_dirsymb(p->n_follow, p->n_rule); } /* * Compute the minimum length of productions of nonterminals, @@ -101,73 +114,80 @@ do_compute() { /* * Compute the contains sets */ - for (p = nonterms; p < maxnt; p++) do_contains(p); - for (p = nonterms; p < maxnt; p++) contains(p->n_rule, (p_set) 0); + for (p = nonterms; p < maxnt; p++) + do_contains(p); + for (p = nonterms; p < maxnt; p++) + contains(p->n_rule, (p_set) 0); /* * Compute the safety of each nonterminal and term. * The safety gives an answer to the question whether a scan is done, * and how it should be handled. */ - for (p = nonterms; p < maxnt; p++) { + for (p = nonterms; p < maxnt; p++) + { /* * Don't know anything yet */ setntsafe(p, NOSAFETY); setntout(p, NOSAFETY); } - for (st = start; st; st = st->ff_next) { + for (st = start; st; st = st->ff_next) + { /* * But start symbols are called with lookahead done */ p = &nonterms[st->ff_nont]; - setntsafe(p,SCANDONE); + setntsafe(p, SCANDONE); } co_trans(nsafes); #ifdef NON_CORRECTING - if (subpars_sim) { - int s; + if (subpars_sim) + { + int s; - /* compute the union of the first sets of all start symbols - Used to compute the nc-first-sets when -s option is given */ - start_firsts = get_set(); - for (st = start; st; st = st->ff_next) { - s = setunion(start_firsts, (&nonterms[st->ff_nont])->n_first); - } + /* compute the union of the first sets of all start symbols + Used to compute the nc-first-sets when -s option is given */ + start_firsts = get_set(); + for (st = start; st; st = st->ff_next) + { + s = setunion(start_firsts, (&nonterms[st->ff_nont])->n_first); + } } - if (non_corr) { - /* compute the non_corr first sets for all nonterminals and terms */ + if (non_corr) + { + /* compute the non_corr first sets for all nonterminals and terms */ - co_trans(nc_nfirst); - for (st = start; st; st = st->ff_next) { - p = &nonterms[st->ff_nont]; - PUTIN(p->n_nc_follow,0); - } - co_trans(nc_nfollow); + co_trans(nc_nfirst); + for (st = start; st; st = st->ff_next) + { + p = &nonterms[st->ff_nont]; + PUTIN(p->n_nc_follow,0); + } + co_trans(nc_nfollow); } #endif # ifndef NDEBUG - if (debug) { + if (debug) + { fputs("Safeties:\n", stderr); - for (p = nonterms; p < maxnt; p++) { - fprintf(stderr, "%s\t%d\t%d\n", - p->n_name, - getntsafe(p), - getntout(p)); + for (p = nonterms; p < maxnt; p++) + { + fprintf(stderr, "%s\t%d\t%d\n", p->n_name, getntsafe(p), + getntout(p)); } } # endif } -STATIC -createsets() { - /* - * Allocate space for the sets. Also determine which files use - * which nonterminals, and determine which nonterminals can be - * made static. - */ +/* + * Allocate space for the sets. Also determine which files use + * which nonterminals, and determine which nonterminals can be + * made static. + */STATIC void createsets(void) +{ register p_nont p; register p_file f; register p_start st; @@ -175,11 +195,14 @@ createsets() { int n = NINTS(NBYTES(nnonterms)); p_mem alloc(); - for (f = files; f < maxfiles; f++) { + for (f = files; f < maxfiles; f++) + { register p_set s; - f->f_used = s = (p_set) alloc((unsigned)n*sizeof(*(f->f_used))); - for (i = n; i; i--) *s++ = 0; - for (i = f->f_nonterminals; i != -1; i = p->n_next) { + f->f_used = s = (p_set) alloc((unsigned) n * sizeof(*(f->f_used))); + for (i = n; i; i--) + *s++ = 0; + for (i = f->f_nonterminals; i != -1; i = p->n_next) + { p = &nonterms[i]; p->n_flags |= GENSTATIC; p->n_first = get_set(); @@ -191,32 +214,39 @@ createsets() { walk(f->f_used, p->n_rule); } } - for (f = files; f < maxfiles; f++) { - for (i = f->f_nonterminals; i != -1; i = p->n_next) { + for (f = files; f < maxfiles; f++) + { + for (i = f->f_nonterminals; i != -1; i = p->n_next) + { register p_file f2; p = &nonterms[i]; - for (f2 = files; f2 < maxfiles; f2++) { - if (f2 != f && IN(f2->f_used, i)) { + for (f2 = files; f2 < maxfiles; f2++) + { + if (f2 != f && IN(f2->f_used, i)) + { p->n_flags &= ~GENSTATIC; } } } } - for (st = start; st; st = st->ff_next) { + for (st = start; st; st = st->ff_next) + { nonterms[st->ff_nont].n_flags &= ~GENSTATIC; } } -STATIC void -walk(u, p) p_set u; register p_gram p; { - /* - * Walk through the grammar rule p, allocating sets - */ - - for (;;) { - switch (g_gettype(p)) { - case TERM : { +/* + * Walk through the grammar rule p, allocating sets + */ +STATIC void walk(p_set u, register p_gram p) +{ + for (;;) + { + switch (g_gettype(p)) + { + case TERM: + { register p_term q; q = g_getterm(p); @@ -227,8 +257,10 @@ walk(u, p) p_set u; register p_gram p; { #endif q->t_follow = get_set(); walk(u, q->t_rule); - break; } - case ALTERNATION : { + break; + } + case ALTERNATION: + { register p_link l; l = g_getlink(p); @@ -238,159 +270,192 @@ walk(u, p) p_set u; register p_gram p; { #endif l->l_others = get_set(); walk(u, l->l_rule); - break; } - case NONTERM : { + break; + } + case NONTERM: + { register int i = g_getcont(p); PUTIN(u, i); - break; } - case EORULE : + break; + } + case EORULE: return; } p++; } } -STATIC -co_trans(fc) int (*fc)(); { +STATIC void co_trans(int (*fc)()) +{ register p_nont p; register int change; - do { + do + { change = 0; - for (p = nonterms; p < maxnt; p++) { - if ((*fc)(p)) change = 1; + for (p = nonterms; p < maxnt; p++) + { + if ((*fc)(p)) + change = 1; } } while (change); } -STATIC int -nempty(p) register p_nont p; { - if (!(p->n_flags & EMPTY) && empty(p->n_rule)) { +STATIC int nempty(register p_nont p) +{ + if (!(p->n_flags & EMPTY) && empty(p->n_rule)) + { p->n_flags |= EMPTY; return 1; } return 0; } -empty(p) register p_gram p; { - /* - * Does the rule pointed to by p produce empty ? - */ +/* + * Does the rule pointed to by p produce empty ? + */ +int empty(register p_gram p) +{ - for (;;) { - switch (g_gettype(p)) { - case EORULE : + for (;;) + { + switch (g_gettype(p)) + { + case EORULE: return 1; - case TERM : { + case TERM: + { register p_term q; q = g_getterm(p); - if (r_getkind(q) == STAR - || r_getkind(q) == OPT - || empty(q->t_rule) ) break; - return 0; } - case ALTERNATION : - if (empty(g_getlink(p)->l_rule)) { + if (r_getkind(q) == STAR || r_getkind(q) == OPT || empty(q->t_rule)) + break; + return 0; + } + case ALTERNATION: + if (empty(g_getlink(p)->l_rule)) + { return 1; } - if (g_gettype(p+1) == EORULE) return 0; + if (g_gettype(p+1) == EORULE) + return 0; break; - case NONTERM : - if (nonterms[g_getcont(p)].n_flags & EMPTY) { + case NONTERM: + if (nonterms[g_getcont(p)].n_flags & EMPTY) + { break; } /* Fall through */ - case LITERAL : - case TERMINAL : + case LITERAL: + case TERMINAL: return 0; } p++; } } -STATIC int -nfirst(p) register p_nont p; { +STATIC int nfirst(register p_nont p) +{ return first(p->n_first, p->n_rule, 0); } #ifdef NON_CORRECTING -STATIC int nc_nfirst(p) register p_nont p; { +STATIC int nc_nfirst(register p_nont p) +{ return nc_first(p->n_nc_first, p->n_rule, 0); } #endif -STATIC -first(setp,p,flag) p_set setp; register p_gram p; { - /* - * Compute the FIRST set of rule p. - * If flag = 0, also the first sets for terms and alternations in - * the rule p are computed. - * The FIRST set is put in setp. - * return 1 if the set refered to by "setp" changed +/* + * Compute the FIRST set of rule p. + * If flag = 0, also the first sets for terms and alternations in + * the rule p are computed. + * The FIRST set is put in setp. + * return 1 if the set refered to by "setp" changed + */ +STATIC int first(p_set setp, register p_gram p, int flag) +{ + register int s; /* Will gather return value */ + int noenter;/* when set, unables entering of elements into + * setp. This is necessary to walk through the + * rest of rule p. */ - register s; /* Will gather return value */ - int noenter;/* when set, unables entering of elements into - * setp. This is necessary to walk through the - * rest of rule p. - */ s = 0; noenter = 0; - for (;;) { - switch (g_gettype(p)) { - case EORULE : + for (;;) + { + switch (g_gettype(p)) + { + case EORULE: return s; - case TERM : { + case TERM: + { register p_term q; q = g_getterm(p); - if (flag == 0) { - if (first(q->t_first,q->t_rule,0))/*nothing*/; + if (flag == 0) + { + if (first(q->t_first, q->t_rule, 0))/*nothing*/ + ; } - if (!noenter) s |= setunion(setp,q->t_first); + if (!noenter) + s |= setunion(setp, q->t_first); p++; - if (r_getkind(q) == STAR || - r_getkind(q) == OPT || - empty(q->t_rule)) continue; - break; } - case ALTERNATION : { + if (r_getkind(q) == STAR || r_getkind(q) == OPT || empty(q->t_rule)) + continue; + break; + } + case ALTERNATION: + { register p_link l; l = g_getlink(p); - if (flag == 0) { - if (first(l->l_symbs,l->l_rule,0))/*nothing*/; + if (flag == 0) + { + if (first(l->l_symbs, l->l_rule, 0))/*nothing*/ + ; } - if (noenter == 0) { - s |= setunion(setp,l->l_symbs); - } - if (g_gettype(p+1) == EORULE) return s; + if (noenter == 0) + { + s |= setunion(setp, l->l_symbs); } + if (g_gettype(p+1) == EORULE) + return s; + } /* Fall Through */ - case ACTION : + case ACTION: p++; continue; - case LITERAL : - case TERMINAL : - if ((noenter == 0) && !IN(setp,g_getcont(p))) { + case LITERAL: + case TERMINAL: + if ((noenter == 0) && !IN(setp,g_getcont(p))) + { s = 1; - PUTIN(setp,g_getcont(p)); + PUTIN(setp, g_getcont(p)); } p++; break; - case NONTERM : { + case NONTERM: + { register p_nont n; n = &nonterms[g_getcont(p)]; - if (noenter == 0) { - s |= setunion(setp,n->n_first); - if (ntneeded) NTPUTIN(setp,g_getcont(p)); + if (noenter == 0) + { + s |= setunion(setp, n->n_first); + if (ntneeded) + NTPUTIN(setp, g_getcont(p)); } p++; - if (n->n_flags & EMPTY) continue; - break; } + if (n->n_flags & EMPTY) + continue; + break; } - if (flag == 0) { + } + if (flag == 0) + { noenter = 1; continue; } @@ -399,99 +464,113 @@ first(setp,p,flag) p_set setp; register p_gram p; { } #ifdef NON_CORRECTING -STATIC -nc_first(setp,p,flag) p_set setp; register p_gram p; { - /* - * Compute the non_corr FIRST set of rule p. - * If flag = 0, also the non_corr first sets for terms and - * alternations in the rule p are computed. - * The non_corr FIRST set is put in setp. - * return 1 if the set refered to by "setp" changed - * If the -s flag was given, the union of the first-sets of all - * start symbols is used whenever an action occurs. Else, only the - * first-sets of startsynbols in the %substart are used - */ +/* + * Compute the non_corr FIRST set of rule p. + * If flag = 0, also the non_corr first sets for terms and + * alternations in the rule p are computed. + * The non_corr FIRST set is put in setp. + * return 1 if the set refered to by "setp" changed + * If the -s flag was given, the union of the first-sets of all + * start symbols is used whenever an action occurs. Else, only the + * first-sets of startsynbols in the %substart are used + */ +STATIC int nc_first(p_set setp,register p_gram p,int flag) +{ - register s; /* Will gather return value */ - int noenter;/* when set, unables entering of elements into - * setp. This is necessary to walk through the - * rest of rule p. - */ + register int s; /* Will gather return value */ + int noenter;/* when set, unables entering of elements into + * setp. This is necessary to walk through the + * rest of rule p. + */ s = 0; noenter = 0; - for (;;) { - switch (g_gettype(p)) { - case EORULE : + for (;;) + { + switch (g_gettype(p)) + { + case EORULE : return s; - case TERM : { - register p_term q; + case TERM : + { + register p_term q; - q = g_getterm(p); - if (flag == 0) { - if (nc_first(q->t_nc_first,q->t_rule,0))/*nothing*/; - } - if (!noenter) s |= setunion(setp,q->t_nc_first); - p++; - if (r_getkind(q) == STAR || - r_getkind(q) == OPT || - empty(q->t_rule)) continue; - break; } - case ALTERNATION : { - register p_link l; + q = g_getterm(p); + if (flag == 0) + { + if (nc_first(q->t_nc_first,q->t_rule,0))/*nothing*/; + } + if (!noenter) s |= setunion(setp,q->t_nc_first); + p++; + if (r_getkind(q) == STAR || + r_getkind(q) == OPT || + empty(q->t_rule)) continue; + break;} + case ALTERNATION : + { + register p_link l; - l = g_getlink(p); - if (flag == 0) { - if (nc_first(l->l_nc_symbs,l->l_rule,0))/*nothing*/; - } - if (noenter == 0) { - s |= setunion(setp,l->l_nc_symbs); - } - if (g_gettype(p+1) == EORULE) return s; + l = g_getlink(p); + if (flag == 0) + { + if (nc_first(l->l_nc_symbs,l->l_rule,0))/*nothing*/; + } + if (noenter == 0) + { + s |= setunion(setp,l->l_nc_symbs); + } + if (g_gettype(p+1) == EORULE) return s; } p++; continue; - case ACTION : { - register p_start subp; + case ACTION : + { + register p_start subp; - if (!noenter) - if (subpars_sim) - s |= setunion(setp, start_firsts); - else { - for (subp = g_getsubparse(p); subp; - subp = subp->ff_next) - s |= setunion(setp, (&nonterms[subp->ff_nont])->n_nc_first); + if (!noenter) + if (subpars_sim) + s |= setunion(setp, start_firsts); + else + { + for (subp = g_getsubparse(p); subp; + subp = subp->ff_next) + s |= setunion(setp, (&nonterms[subp->ff_nont])->n_nc_first); - } - p++; - continue; + } + p++; + continue; } - case LITERAL : - case TERMINAL : - if (g_getcont(p) == g_getcont(illegal_gram)) { + case LITERAL : + case TERMINAL : + if (g_getcont(p) == g_getcont(illegal_gram)) + { /* Ignore for this set. */ p++; continue; } - if ((noenter == 0) && !IN(setp,g_getcont(p))) { + if ((noenter == 0) && !IN(setp,g_getcont(p))) + { s = 1; PUTIN(setp,g_getcont(p)); } p++; break; - case NONTERM : { - register p_nont n; + case NONTERM : + { + register p_nont n; - n = &nonterms[g_getcont(p)]; - if (noenter == 0) { - s |= setunion(setp,n->n_nc_first); - if (ntneeded) NTPUTIN(setp,g_getcont(p)); - } - p++; - if (n->n_flags & EMPTY) continue; - break; } + n = &nonterms[g_getcont(p)]; + if (noenter == 0) + { + s |= setunion(setp,n->n_nc_first); + if (ntneeded) NTPUTIN(setp,g_getcont(p)); + } + p++; + if (n->n_flags & EMPTY) continue; + break;} } - if (flag == 0) { + if (flag == 0) + { noenter = 1; continue; } @@ -500,197 +579,221 @@ nc_first(setp,p,flag) p_set setp; register p_gram p; { } #endif -STATIC int -nfollow(p) register p_nont p; { +STATIC int nfollow(register p_nont p) +{ return follow(p->n_follow, p->n_rule); } -STATIC -follow(setp,p) p_set setp; register p_gram p; { - /* - * setp is the follow set for the rule p. - * Compute the follow sets in the rule p from this set. - * Return 1 if a follow set of a nonterminal changed. - */ - register s; /* Will gather return value */ +/* + * setp is the follow set for the rule p. + * Compute the follow sets in the rule p from this set. + * Return 1 if a follow set of a nonterminal changed. + */ +STATIC int follow(p_set setp, register p_gram p) +{ + register int s; /* Will gather return value */ s = 0; - for (;;) { - switch (g_gettype(p)) { - case EORULE : + for (;;) + { + switch (g_gettype(p)) + { + case EORULE: return s; - case TERM : { + case TERM: + { register p_term q; q = g_getterm(p); - if (empty(p+1)) { + if (empty(p + 1)) + { /* * If what follows the term can be empty, * everything that can follow the whole * rule can also follow the term */ - s |= setunion(q->t_follow,setp); + s |= setunion(q->t_follow, setp); } /* * Everything that can start the rest of the rule * can follow the term */ - s |= first(q->t_follow,p+1,1); - if (r_getkind(q) == STAR || - r_getkind(q) == PLUS || - r_getnum(q) ) { + s |= first(q->t_follow, p + 1, 1); + if (r_getkind(q) == STAR || r_getkind(q) == PLUS || r_getnum(q)) + { /* * If the term involves a repetition * of possibly more than one, * everything that can start the term * can also follow it. */ - s |= follow(q->t_first,q->t_rule); + s |= follow(q->t_first, q->t_rule); } /* * Now propagate the set computed sofar */ s |= follow(q->t_follow, q->t_rule); - break; } - case ALTERNATION : + break; + } + case ALTERNATION: /* * Just propagate setp */ - s |= follow(setp,g_getlink(p)->l_rule); + s |= follow(setp, g_getlink(p)->l_rule); break; - case NONTERM : { + case NONTERM: + { register p_nont n; n = &nonterms[g_getcont(p)]; - s |= first(n->n_follow,p+1,1); - if (empty(p+1)) { + s |= first(n->n_follow, p + 1, 1); + if (empty(p + 1)) + { /* * If the rest of p can produce empty, * everything that follows p can follow * the nonterminal */ - s |= setunion(n->n_follow,setp); + s |= setunion(n->n_follow, setp); } - break; } + break; + } } p++; } + return 0; } #ifdef NON_CORRECTING -STATIC int -nc_nfollow(p) register p_nont p; { +STATIC int nc_nfollow(register p_nont p) +{ return follow(p->n_nc_follow, p->n_rule); } -STATIC -nc_follow(setp,p) p_set setp; register p_gram p; { +STATIC int nc_follow(p_set setp, register p_gram p) +{ /* * setp is the follow set for the rule p. * Compute the follow sets in the rule p from this set. * Return 1 if a follow set of a nonterminal changed. */ - register s; /* Will gather return value */ + register int s; /* Will gather return value */ s = 0; - for (;;) { - switch (g_gettype(p)) { - case EORULE : + for (;;) + { + switch (g_gettype(p)) + { + case EORULE : return s; - case TERM : { - register p_term q; + case TERM : + { + register p_term q; - q = g_getterm(p); - if (empty(p+1)) { + q = g_getterm(p); + if (empty(p+1)) + { + /* + * If what follows the term can be empty, + * everything that can follow the whole + * rule can also follow the term + */ + s |= setunion(q->t_nc_follow,setp); + } /* - * If what follows the term can be empty, - * everything that can follow the whole - * rule can also follow the term + * Everything that can start the rest of the rule + * can follow the term */ - s |= setunion(q->t_nc_follow,setp); - } - /* - * Everything that can start the rest of the rule - * can follow the term - */ - s |= nc_first(q->t_nc_follow,p+1,1); - if (r_getkind(q) == STAR || - r_getkind(q) == PLUS || - r_getnum(q) ) { + s |= nc_first(q->t_nc_follow,p+1,1); + if (r_getkind(q) == STAR || + r_getkind(q) == PLUS || + r_getnum(q) ) + { + /* + * If the term involves a repetition + * of possibly more than one, + * everything that can start the term + * can also follow it. + */ + s |= nc_follow(q->t_nc_first,q->t_rule); + } /* - * If the term involves a repetition - * of possibly more than one, - * everything that can start the term - * can also follow it. + * Now propagate the set computed sofar */ - s |= nc_follow(q->t_nc_first,q->t_rule); - } - /* - * Now propagate the set computed sofar - */ - s |= nc_follow(q->t_nc_follow, q->t_rule); - break; } - case ALTERNATION : + s |= nc_follow(q->t_nc_follow, q->t_rule); + break;} + case ALTERNATION : /* * Just propagate setp */ s |= nc_follow(setp,g_getlink(p)->l_rule); break; - case NONTERM : { - register p_nont n; + case NONTERM : + { + register p_nont n; - n = &nonterms[g_getcont(p)]; - s |= nc_first(n->n_nc_follow,p+1,1); - if (empty(p+1)) { - /* - * If the rest of p can produce empty, - * everything that follows p can follow - * the nonterminal - */ - s |= setunion(n->n_nc_follow,setp); - } - break; } + n = &nonterms[g_getcont(p)]; + s |= nc_first(n->n_nc_follow,p+1,1); + if (empty(p+1)) + { + /* + * If the rest of p can produce empty, + * everything that follows p can follow + * the nonterminal + */ + s |= setunion(n->n_nc_follow,setp); + } + break;} } p++; } + return 0; } #endif -STATIC void -co_dirsymb(setp,p) p_set setp; register p_gram p; { +STATIC void co_dirsymb(p_set setp, register p_gram p) +{ /* * Walk the rule p, doing the work for alternations */ register p_gram s = 0; - for (;;) { - switch (g_gettype(p)) { - case EORULE : + for (;;) + { + switch (g_gettype(p)) + { + case EORULE: return; - case TERM : { + case TERM: + { register p_term q; q = g_getterm(p); - co_dirsymb(q->t_follow,q->t_rule); - break; } - case ALTERNATION : { + co_dirsymb(q->t_follow, q->t_rule); + break; + } + case ALTERNATION: + { register p_link l; /* * Save first alternative */ - if (!s) s = p; + if (!s) + s = p; l = g_getlink(p); - co_dirsymb(setp,l->l_rule); - if (empty(l->l_rule)) { + co_dirsymb(setp, l->l_rule); + if (empty(l->l_rule)) + { /* * If the rule can produce empty, everything * that follows it can also start it */ - setunion(l->l_symbs,setp); + setunion(l->l_symbs, setp); } - if (g_gettype(p+1) == EORULE) { + if (g_gettype(p+1) == EORULE) + { /* * Every alternation is implemented as a * choice between two alternatives : @@ -700,25 +803,27 @@ co_dirsymb(setp,p) p_set setp; register p_gram p; { */ co_others(s); return; - } } + } + } } p++; } } -STATIC -co_others(p) register p_gram p; { +STATIC void co_others(p_gram p) +{ /* * compute the l_others-sets for the list of alternatives * indicated by p */ - register p_link l1,l2; + register p_link l1, l2; l1 = g_getlink(p); p++; l2 = g_getlink(p); - setunion(l1->l_others,l2->l_symbs); - if (g_gettype(p+1) != EORULE) { + setunion(l1->l_others, l2->l_symbs); + if (g_gettype(p+1) != EORULE) + { /* * First compute l2->l_others */ @@ -726,16 +831,14 @@ co_others(p) register p_gram p; { /* * and then l1->l_others */ - setunion(l1->l_others,l2->l_others); + setunion(l1->l_others, l2->l_others); } } static p_length length; # define INFINITY 32767 -STATIC -ncomplength(p) - register p_nont p; +STATIC int ncomplength(p_nont p) { register p_length pl = &length[p - nonterms]; int x = pl->cnt; @@ -745,40 +848,43 @@ ncomplength(p) return pl->cnt < INFINITY && x == INFINITY; } -STATIC -do_lengthcomp() { - /* - * Compute the minimum length of a terminal production for each - * nonterminal. - * This length consists of two fields: the number of terminals, - * and a number that is composed of - * - the number of this alternative - * - a crude measure of the number of terms and nonterminals in the - * production of this shortest string. - */ +/* + * Compute the minimum length of a terminal production for each + * nonterminal. + * This length consists of two fields: the number of terminals, + * and a number that is composed of + * - the number of this alternative + * - a crude measure of the number of terms and nonterminals in the + * production of this shortest string. + */ +STATIC void do_lengthcomp(void) +{ register p_length pl; register p_nont p; p_mem alloc(); length = (p_length) alloc((unsigned) (nnonterms * sizeof(*length))); - for (pl = &length[nnonterms-1]; pl >= length; pl--) { + for (pl = &length[nnonterms - 1]; pl >= length; pl--) + { pl->val = pl->cnt = INFINITY; } co_trans(ncomplength); pl = length; - for (p = nonterms; p < maxnt; p++, pl++) { - if (pl->cnt == INFINITY) { + for (p = nonterms; p < maxnt; p++, pl++) + { + if (pl->cnt == INFINITY) + { p->n_flags |= RECURSIVE; } setdefaults(p->n_rule); } - free ((p_mem) length); + free((p_mem) length); } -STATIC void -complength(p,le) register p_gram p; p_length le; { +STATIC void complength(register p_gram p, p_length le) +{ /* * Walk grammar rule p, computing minimum lengths */ @@ -790,82 +896,95 @@ complength(p,le) register p_gram p; p_length le; { X.cnt = 0; X.val = 0; - for (;;) { - switch (g_gettype(p)) { - case LITERAL : - case TERMINAL : + for (;;) + { + switch (g_gettype(p)) + { + case LITERAL: + case TERMINAL: #ifdef NON_CORRECTING - if (g_getcont(p) == g_getcont(illegal_gram)) { + if (g_getcont(p) == g_getcont(illegal_gram)) + { add(&X, INFINITY, 0); break; } #endif add(&X, 1, 0); break; - case ALTERNATION : + case ALTERNATION: X.cnt = INFINITY; X.val = INFINITY; - while (g_gettype(p) != EORULE) { + while (g_gettype(p) != EORULE) + { cnt++; l = g_getlink(p); p++; - complength(l->l_rule,&i); + complength(l->l_rule, &i); i.val += cnt; - if (l->l_flag & DEF) { + if (l->l_flag & DEF) + { X = i; break; } - if (compare(&i, &X) < 0) { + if (compare(&i, &X) < 0) + { X = i; } } /* Fall through */ - case EORULE : + case EORULE: le->cnt = X.cnt; le->val = X.val; return; - case TERM : { + case TERM: + { register int rep; q = g_getterm(p); rep = r_getkind(q); X.val += 1; - if ((q->t_flags&PERSISTENT) || - rep==FIXED || rep==PLUS) { - complength(q->t_rule,&i); + if ((q->t_flags & PERSISTENT) || rep == FIXED || rep == PLUS) + { + complength(q->t_rule, &i); add(&X, i.cnt, i.val); - if (rep == FIXED && r_getnum(q) > 0) { - for (rep = r_getnum(q) - 1; - rep > 0; rep--) { + if (rep == FIXED && r_getnum(q) > 0) + { + for (rep = r_getnum(q) - 1; rep > 0; rep--) + { add(&X, i.cnt, i.val); } } } - break; } - case NONTERM : { + break; + } + case NONTERM: + { int nn = g_getcont(p); register p_length pl = &length[nn]; int x = pl->cnt; - if (x == INFINITY) { + if (x == INFINITY) + { pl->cnt = -1; - complength(nonterms[nn].n_rule,pl); + complength(nonterms[nn].n_rule, pl); x = pl->cnt; } - else if (x == -1) x = INFINITY; + else if (x == -1) + x = INFINITY; add(&X, x, pl->val); X.val += 1; - } + } } p++; } } -STATIC void -add(a, c, v) register p_length a; { +STATIC void add(register p_length a, int c, int v) +{ - if (a->cnt == INFINITY || c == INFINITY) { + if (a->cnt == INFINITY || c == INFINITY) + { a->cnt = INFINITY; return; } @@ -873,22 +992,26 @@ add(a, c, v) register p_length a; { a->cnt += c; } -STATIC int -compare(a, b) register p_length a, b; { - if (a->cnt != b->cnt) return a->cnt - b->cnt; +STATIC int compare(p_length a, p_length b) +{ + if (a->cnt != b->cnt) + return a->cnt - b->cnt; return a->val - b->val; } -STATIC void -setdefaults(p) register p_gram p; { - for (;;) { - switch(g_gettype(p)) { - case EORULE: +STATIC void setdefaults(register p_gram p) +{ + for (;;) + { + switch (g_gettype(p)) + { + case EORULE: return; - case TERM: + case TERM: setdefaults(g_getterm(p)->t_rule); break; - case ALTERNATION: { + case ALTERNATION: + { register p_link l, l1; int temp = 0, temp1, cnt = 0; t_length count, i; @@ -896,41 +1019,46 @@ setdefaults(p) register p_gram p; { count.cnt = INFINITY; count.val = INFINITY; l1 = g_getlink(p); - do { + do + { cnt++; l = g_getlink(p); p++; - complength(l->l_rule,&i); + complength(l->l_rule, &i); i.val += cnt; - if (l->l_flag & DEF) temp = 1; + if (l->l_flag & DEF) + temp = 1; temp1 = compare(&i, &count); - if (temp1 < 0 || - (temp1 == 0 && l1->l_flag & AVOIDING)) { + if (temp1 < 0 || (temp1 == 0 && l1->l_flag & AVOIDING)) + { l1 = l; count = i; } setdefaults(l->l_rule); } while (g_gettype(p) != EORULE); - if (!temp) { + if (!temp) + { /* No user specified default */ l1->l_flag |= DEF; } - return; } + return; + } } p++; } } -STATIC -do_contains(n) register p_nont n; { +STATIC void do_contains(register p_nont n) +{ /* * Compute the total set of symbols that nonterminal n can * produce */ - if (n->n_contains == 0) { + if (n->n_contains == 0) + { n->n_contains = get_set(); - contains(n->n_rule,n->n_contains); + contains(n->n_rule, n->n_contains); /* * If the rule can produce empty, delete all symbols that * can follow the rule as well as be in the rule. @@ -938,158 +1066,193 @@ do_contains(n) register p_nont n; { * symbols that are guaranteed to be eaten by the rule! * Otherwise, the generated parser may loop forever */ - if (n->n_flags & EMPTY) { - setminus(n->n_contains,n->n_follow); + if (n->n_flags & EMPTY) + { + setminus(n->n_contains, n->n_follow); } /* * But the symbols that can start the rule are always * eaten */ - setunion(n->n_contains,n->n_first); + setunion(n->n_contains, n->n_first); } } -STATIC void -contains(p,set) register p_gram p; register p_set set; { +STATIC void contains(register p_gram p, register p_set set) +{ /* * Does the real computation of the contains-sets */ - for (;;) { - switch (g_gettype(p)) { - case EORULE : + for (;;) + { + switch (g_gettype(p)) + { + case EORULE: return; - case TERM : { + case TERM: + { register p_term q; int rep; q = g_getterm(p); rep = r_getkind(q); - if ((q->t_flags & PERSISTENT) || - rep == PLUS || rep == FIXED) { + if ((q->t_flags & PERSISTENT) || rep == PLUS || rep == FIXED) + { /* * In these cases, the term belongs to the * continuation grammar. * Otherwise, q->t_contains is just * q->t_first */ - if (!q->t_contains) { - q->t_contains = get_set(); + if (!q->t_contains) + { + q->t_contains = get_set(); } - contains(q->t_rule,q->t_contains); - if (rep != FIXED || empty(q->t_rule)) { - setminus(q->t_contains,q->t_follow); + contains(q->t_rule, q->t_contains); + if (rep != FIXED || empty(q->t_rule)) + { + setminus(q->t_contains, q->t_follow); } - setunion(q->t_contains,q->t_first); - } else { + setunion(q->t_contains, q->t_first); + } + else + { contains(q->t_rule, (p_set) 0); q->t_contains = q->t_first; } - if (set) setunion(set,q->t_contains); - break; } - case NONTERM : { + if (set) + setunion(set, q->t_contains); + break; + } + case NONTERM: + { register p_nont n; n = &nonterms[g_getcont(p)]; do_contains(n); - if (set) { + if (set) + { setunion(set, n->n_contains); - if (ntneeded) NTPUTIN(set, g_getcont(p)); + if (ntneeded) + NTPUTIN(set, g_getcont(p)); } - break; } - case ALTERNATION : { + break; + } + case ALTERNATION: + { register p_link l; l = g_getlink(p); - contains(l->l_rule, - (l->l_flag & DEF) ? set : (p_set) 0); - break; } - case LITERAL : - case TERMINAL : { - register hulp; + contains(l->l_rule, (l->l_flag & DEF) ? set : (p_set) 0); + break; + } + case LITERAL: + case TERMINAL: + { + register int hulp; - if (set) { + if (set) + { hulp = g_getcont(p); assert(hulp < ntokens); - PUTIN(set,hulp); - }} + PUTIN(set, hulp); + } + } } p++; } } -STATIC int nsafes(p) register p_nont p; { - int ch; +STATIC int nsafes(register p_nont p) +{ + int ch; register int i; ch = 0; i = getntsafe(p); - if (i != NOSAFETY) { + if (i != NOSAFETY) + { i = do_safes(p->n_rule, i, &ch); - if (i < SCANDONE) i = SCANDONE; + if (i < SCANDONE) + i = SCANDONE; /* After a nonterminal, we only know whether a scan was done - or not - */ - if (getntout(p) != i) { + or not + */ + if (getntout(p) != i) + { ch = 1; - setntout(p,i); + setntout(p, i); } } return ch; } -STATIC int -do_safes(p,safe,ch) register p_gram p; register int *ch; { +STATIC int do_safes(register p_gram p, int safe, register int *ch) +{ /* * Walk the grammar rule, doing the computation described in the * comment of the procedure above this one. */ - int retval; + int retval; - for (;;) { - switch (g_gettype(p)) { - case ACTION: + for (;;) + { + switch (g_gettype(p)) + { + case ACTION: p++; continue; - case LITERAL: - case TERMINAL: + case LITERAL: + case TERMINAL: safe = NOSCANDONE; break; - case TERM : { + case TERM: + { register p_term q; - int i,rep; + int i, rep; q = g_getterm(p); i = r_getnum(q); rep = r_getkind(q); retval = do_safes(q->t_rule, - t_safety(rep,i,q->t_flags&PERSISTENT,safe),ch); + t_safety(rep, i, q->t_flags & PERSISTENT, safe), ch); settout(q, retval); safe = t_after(rep, i, retval); - break; } - case ALTERNATION : { + break; + } + case ALTERNATION: + { register p_link l; register int i; retval = -1; - while (g_gettype(p) == ALTERNATION) { + while (g_gettype(p) == ALTERNATION) + { l = g_getlink(p); p++; - if (safe > SAFE && (l->l_flag & DEF)) { - i = do_safes(l->l_rule,SAFESCANDONE,ch); + if (safe > SAFE && (l->l_flag & DEF)) + { + i = do_safes(l->l_rule, SAFESCANDONE, ch); } - else i = do_safes(l->l_rule,SAFE,ch); - if (retval == -1) retval = i; - else if (i != retval) { - if (i == NOSCANDONE || - retval == NOSCANDONE) { + else + i = do_safes(l->l_rule, SAFE, ch); + if (retval == -1) + retval = i; + else if (i != retval) + { + if (i == NOSCANDONE || retval == NOSCANDONE) + { retval = SCANDONE; } - else if (i > retval) retval = i; + else if (i > retval) + retval = i; } } - return retval; } - case NONTERM : { + return retval; + } + case NONTERM: + { register p_nont n; register int nsafe, osafe; @@ -1097,63 +1260,82 @@ do_safes(p,safe,ch) register p_gram p; register int *ch; { nsafe = getntsafe(n); osafe = safe; safe = getntout(n); - if (safe == NOSAFETY) safe = SCANDONE; - if (osafe == nsafe) break; - if (nsafe == NOSAFETY) { + if (safe == NOSAFETY) + safe = SCANDONE; + if (osafe == nsafe) + break; + if (nsafe == NOSAFETY) + { *ch = 1; setntsafe(n, osafe); break; } - if (osafe == NOSCANDONE || nsafe == NOSCANDONE) { - if (nsafe != SCANDONE) { + if (osafe == NOSCANDONE || nsafe == NOSCANDONE) + { + if (nsafe != SCANDONE) + { *ch = 1; setntsafe(n, SCANDONE); } break; } - if (osafe > nsafe) { + if (osafe > nsafe) + { setntsafe(n, osafe); *ch = 1; } - break; } - case EORULE : + break; + } + case EORULE: return safe; } p++; } } -t_safety(rep, count, persistent, safety) { +int t_safety(int rep, int count, int persistent, int safety) +{ - if (safety == NOSCANDONE) safety = SCANDONE; - switch(rep) { - default: + if (safety == NOSCANDONE) + safety = SCANDONE; + switch (rep) + { + default: assert(0); - case OPT: - if (!persistent || safety < SAFESCANDONE) return SAFE; + case OPT: + if (!persistent || safety < SAFESCANDONE) + return SAFE; return SAFESCANDONE; - case STAR: - if (persistent) return SAFESCANDONE; + case STAR: + if (persistent) + return SAFESCANDONE; return SAFE; - case PLUS: - if (persistent) { - if (safety > SAFESCANDONE) return safety; + case PLUS: + if (persistent) + { + if (safety > SAFESCANDONE) + return safety; return SAFESCANDONE; } return safety; - case FIXED: - if (!count) return safety; + case FIXED: + if (!count) + return safety; return SCANDONE; } /* NOTREACHED */ } -t_after(rep, count, outsafety) { - if (count == 0 && (rep == STAR || rep == PLUS)) { +int t_after(int rep, int count, int outsafety) +{ + if (count == 0 && (rep == STAR || rep == PLUS)) + { return SAFESCANDONE; } - if (rep != FIXED) { - if (outsafety <= SAFESCANDONE) return SAFESCANDONE; + if (rep != FIXED) + { + if (outsafety <= SAFESCANDONE) + return SAFESCANDONE; return SCANDONE; } return outsafety; diff --git a/util/LLgen/src/extern.h b/util/LLgen/src/extern.h index fca911761..f1405e786 100644 --- a/util/LLgen/src/extern.h +++ b/util/LLgen/src/extern.h @@ -2,6 +2,8 @@ * For full copyright and restrictions on use see the file COPYING in the top * level of the LLgen tree. */ +#ifndef EXTERN_H_ +#define EXTERN_H_ /* * L L G E N @@ -84,7 +86,6 @@ extern string nc_rec_file, nc_incl_file; extern int low_percentage, high_percentage; extern int min_cases_for_jmptable; extern int jmptable_option; -extern int ansi_c; #ifdef NON_CORRECTING extern int non_corr; extern int subpars_sim; @@ -92,3 +93,23 @@ extern p_gram illegal_gram; #endif extern int strip_grammar; extern int in_production; + +void error(int lineno,string s,string t); +void warning(int lineno,string s,string t); +void fatal(int lineno,string s,string t); + + +int empty(register p_gram); +int t_safety(int, int, int, int); +int t_after(int, int, int); +string store(string); +void name_init(void); +p_gram search(int, register string, int); +void co_reach(void); +void install(string, string); +void copyfile(string); + + + + +#endif /* EXTERN_H_ */ diff --git a/util/LLgen/src/gencode.c b/util/LLgen/src/gencode.c index 484319511..6599a386a 100644 --- a/util/LLgen/src/gencode.c +++ b/util/LLgen/src/gencode.c @@ -19,6 +19,8 @@ */ #include +#include +# include "alloc.h" # include "types.h" # include "io.h" # include "extern.h" @@ -34,85 +36,84 @@ static string rcsid3 = "$Id$"; * Some codestrings used more than once */ -static string c_arrend = "0 };\n"; -static string c_close = "}\n"; -static string c_break = "break;\n"; -static string c_read = "LLread();\n"; +static string c_arrend = "0 };\n"; +static string c_close = "}\n"; +static string c_break = "break;\n"; +static string c_read = "LLread();\n"; /* Some constants used for reading from the action file */ # define ENDDECL 0400 # define IDENT 0401 -static int nlabel; /* count for the generation of labels */ -static int firsts; /* are there any? */ +static int nlabel; /* count for the generation of labels */ +static int firsts; /* are there any? */ static int listcount; /* In this file the following routines are defined: */ -extern gencode(); -STATIC opentemp(); -STATIC geninclude(); -STATIC genrecovery(); +STATIC void doclose(FILE *); +STATIC int *mk_tokenlist(void); +STATIC void genhdr(void); +STATIC void opentemp(string); +STATIC void geninclude(void); +STATIC void genrecovery(void); #ifdef NON_CORRECTING -STATIC genncrecovery(); +STATIC void genncrecovery(void); #endif -STATIC string genname(); -STATIC generate(); -STATIC void prset(); -STATIC void macro(); -STATIC controlline(); -STATIC getparams(); -STATIC getansiparams(); -STATIC genprototypes(); -STATIC gettok(); -STATIC void rulecode(); -STATIC int * dopush(); -STATIC int * mk_tokenlist(); -STATIC void getaction(); -STATIC void alternation(); -STATIC codeforterm(); -STATIC genswhead(); -STATIC gencases(); -STATIC genpush(); -STATIC genpop(); -STATIC void genincrdecr(); -STATIC add_cases(); -STATIC int analyze_switch(); -STATIC out_list(); -STATIC genextname(); -STATIC correct_prefix(); +STATIC void generate(p_file); +STATIC void prset(p_set); +STATIC void macro(string, p_nont); +STATIC void controlline(void); +STATIC void getparams(void); +STATIC void genprototypes(register p_file); +STATIC void getansiparams(int); +STATIC int gettok(void); +STATIC void rulecode(register p_gram, int, int, int); +STATIC void alternation(p_gram, int, int, int, int); +STATIC int *dopush(register p_gram, int, int, int **); +STATIC void getaction(int); +STATIC int codeforterm(register p_term, int, int); +STATIC void genswhead(register p_term, int, int, int, int); +STATIC void gencases(int *, int, int); +STATIC string genname(string); +STATIC void genpush(int); +STATIC void genincrdecr(string, int); +STATIC void genpop(int); +STATIC int analyze_switch(int *); +STATIC void add_cases(p_set, int *, int); +STATIC void out_list(int *, int, int); +STATIC void genextname(int, char *, FILE *); +STATIC void correct_prefix(void); + + +extern void save_grammar(FILE *f); # define NOPOP -20000 -p_mem alloc(), ralloc(); -doclose(f) - FILE *f; +STATIC void doclose(FILE *f) { - if (ferror(f) != 0) { - fatal(0,"Write error on temporary"); + if (ferror(f) != 0) + { + fatal(0, "Write error on temporary", NULL ); } fclose(f); } -STATIC int * -mk_tokenlist() +STATIC int *mk_tokenlist(void) { register int i = ntokens; - register int *p = (int *)alloc((unsigned)(i * sizeof(int))) + i; + register int *p = (int *) alloc((unsigned) (i * sizeof(int))) + i; - while (i--) *--p = -1; + while (i--) + *--p = -1; return p; } -STATIC -genhdr() +STATIC void genhdr(void) { - if (!firsts) fputs("#define LLNOFIRSTS\n", fpars); - if (ansi_c) fputs("#define LL_ANSI_C 1\n", fpars); - else { - fputs("#if __STDC__ || __cplusplus\n#define LL_ANSI_C 1\n#endif\n", fpars); - } + if (!firsts) + fputs("#define LLNOFIRSTS\n", fpars); #ifdef NON_CORRECTING if (non_corr) fputs("#define LL_NON_CORR 1\n", fpars); #endif @@ -120,26 +121,29 @@ genhdr() copyfile(incl_file); } -gencode(argc) { +void gencode(int argc) +{ register p_file p = files; /* Set up for code generation */ - if ((fact = fopen(f_temp,"r")) == NULL) { - fatal(0,e_noopen,f_temp); + if ((fact = fopen(f_temp, "r")) == NULL ) + { + fatal(0, e_noopen, f_temp); } #ifdef NON_CORRECTING /* The non-correcting error recovery must be generated BEFORE - parser code is generated!!!! In case of conflict resolvers, - the code-generation process will delete conflicting symbols - from first and followsets, making them UNUSABLE for the - non-correcting error recovery code. + parser code is generated!!!! In case of conflict resolvers, + the code-generation process will delete conflicting symbols + from first and followsets, making them UNUSABLE for the + non-correcting error recovery code. */ if (non_corr) - genncrecovery(); + genncrecovery(); #endif /* For every source file .... */ - while (argc--) { + while (argc--) + { /* Open temporary */ f_input = p->f_name; opentemp(f_input); @@ -149,7 +153,7 @@ gencode(argc) { getaction(2); doclose(fpars); /* And install */ - install(genname(p->f_name),p->f_name); + install(genname(p->f_name), p->f_name); p++; } geninclude(); @@ -158,34 +162,37 @@ gencode(argc) { fclose(fact); } -STATIC -opentemp(str) string str; { +STATIC void opentemp(string str) +{ - if ((fpars = fopen(f_pars,"w")) == NULL) { - fatal(0,e_noopen,f_pars); + if ((fpars = fopen(f_pars, "w")) == NULL ) + { + fatal(0, e_noopen, f_pars); } - if (!str) str = "."; - fprintf(fpars,LLgenid,str); + if (!str) + str = "."; + fprintf(fpars, LLgenid, str); } -STATIC -geninclude() { +STATIC void geninclude(void) +{ register p_token p; int maxno = 0; opentemp((string) 0); - for (p = tokens; p < maxt; p++) { - if (p->t_tokno > maxno) maxno = p->t_tokno; - if (p->t_tokno >= 0400) { - fprintf(fpars,"#define %s %d\n", - p->t_string, - p->t_tokno); + for (p = tokens; p < maxt; p++) + { + if (p->t_tokno > maxno) + maxno = p->t_tokno; + if (p->t_tokno >= 0400) + { + fprintf(fpars, "#define %s %d\n", p->t_string, p->t_tokno); } } - fprintf(fpars, "#define %s_MAXTOKNO %d\n", prefix ? prefix : "LL", - maxno); + fprintf(fpars, "#define %s_MAXTOKNO %d\n", prefix ? prefix : "LL", maxno); #ifdef NON_CORRECTING - if (non_corr) { + if (non_corr) + { fprintf(fpars, "#define %sNONCORR\n", prefix ? prefix : "LL"); } #endif @@ -193,108 +200,121 @@ geninclude() { install(f_include, "."); } -STATIC -genrecovery() { - register FILE *f; +STATIC void genrecovery(void) +{ + register FILE *f; register p_token t; - register int *q; - register p_nont p; - register p_set *psetl; - int *index; - int i; + register int *q; + register p_nont p; + register p_set *psetl; + int *index; + int i; register p_start st; opentemp((string) 0); f = fpars; correct_prefix(); genhdr(); - for (st = start; st; st = st->ff_next) { + for (st = start; st; st = st->ff_next) + { /* Make sure that every set the parser needs is in the list * before generating a define of the number of them! */ p = &nonterms[st->ff_nont]; - if (g_gettype(p->n_rule) == ALTERNATION) { + if (g_gettype(p->n_rule) == ALTERNATION) + { findindex(p->n_contains); } } i = maxptr - setptr; fprintf(f, -"#define LL_SSIZE %d\n#define LL_NSETS %d\n#define LL_NTERMINALS %d\n", - nbytes, - i > 0 ? i : 1, - ntokens); - if (onerror) fprintf(f,"#define LL_USERHOOK %s\n", onerror); + "#define LL_SSIZE %d\n#define LL_NSETS %d\n#define LL_NTERMINALS %d\n", + nbytes, i > 0 ? i : 1, ntokens); + if (onerror) + fprintf(f, "#define LL_USERHOOK %s\n", onerror); #ifdef NON_CORRECTING - if (non_corr) { - fputs("static int nc_done = 0;\n", f); - fputs("static int err_seen = 0;\n", f); + if (non_corr) + { + fputs("static int nc_done = 0;\n", f); + fputs("static int err_seen = 0;\n", f); } #endif /* Now generate the routines that call the startsymbols */ - fputs("#if LL_ANSI_C\n", f); - for (st = start; st; st = st->ff_next) { + for (st = start; st; st = st->ff_next) + { p = &nonterms[st->ff_nont]; fputs("void ", f); genextname(st->ff_nont, p->n_name, f); fputs("(void);\n", f); } - fputs("#endif\n", f); - for (st = start; st; st = st->ff_next) { - fprintf(f, "#if LL_ANSI_C\nvoid %s(void)\n#else\n%s()\n#endif\n", st->ff_name, st->ff_name); + for (st = start; st; st = st->ff_next) + { + fprintf(f, "void %s(void)\n", st->ff_name); p = &nonterms[st->ff_nont]; fputs(" {\n\tunsigned int s[LL_NTERMINALS+LL_NSETS+2];", f); #ifdef NON_CORRECTING - if (non_corr) { - fputs(" \n\tint oldstartsymb;", f); - fputs(" \n\tint oldncflag;", f); - fputs(" \n\toldstartsymb = LLstartsymb;", f); - fputs(" \n\toldncflag = nc_done;", f); - fputs(" \n\tnc_done = 0;", f); - fprintf(f, "\n\tLLstartsymb = %d;", st->ff_nont + assval); + if (non_corr) + { + fputs(" \n\tint oldstartsymb;", f); + fputs(" \n\tint oldncflag;", f); + fputs(" \n\toldstartsymb = LLstartsymb;", f); + fputs(" \n\toldncflag = nc_done;", f); + fputs(" \n\tnc_done = 0;", f); + fprintf(f, "\n\tLLstartsymb = %d;", st->ff_nont + assval); } #endif fputs("\n\tLLnewlevel(s);\n\tLLread();\n", f); - if (g_gettype(p->n_rule) == ALTERNATION) { + if (g_gettype(p->n_rule) == ALTERNATION) + { genpush(findindex(p->n_contains)); } genextname(st->ff_nont, p->n_name, f); fputs("();\n", f); - if (getntout(p) == NOSCANDONE) { - fputs("\tLL_NOSCANDONE(EOFILE);\n",f); + if (getntout(p) == NOSCANDONE) + { + fputs("\tLL_NOSCANDONE(EOFILE);\n", f); } - else fputs("\tLL_SCANDONE(EOFILE);\n",f); - fputs("\tLLoldlevel(s);\n",f); + else + fputs("\tLL_SCANDONE(EOFILE);\n", f); + fputs("\tLLoldlevel(s);\n", f); #ifdef NON_CORRECTING - if (non_corr) { - fputs("\tLLstartsymb = oldstartsymb;\n", f); - fputs("\tif (nc_done == 1) { \n", f); - fputs("\t\terr_seen = 1;\n", f); - fputs("\tnc_done = oldncflag;\n", f); - fputs("\t}\n", f); + if (non_corr) + { + fputs("\tLLstartsymb = oldstartsymb;\n", f); + fputs("\tif (nc_done == 1) { \n", f); + fputs("\t\terr_seen = 1;\n", f); + fputs("\tnc_done = oldncflag;\n", f); + fputs("\t}\n", f); } #endif fputs("}\n", f); } /* Now generate the sets */ - fputs("static char LLsets[] = {\n",f); - for (psetl = setptr; psetl < maxptr; psetl++) prset(*psetl); + fputs("static char LLsets[] = {\n", f); + for (psetl = setptr; psetl < maxptr; psetl++) + prset(*psetl); fputs(c_arrend, f); index = (int *) alloc((unsigned) (assval * sizeof(int))); - for (q = index; q < &index[assval];) *q++ = -1; - for (t = tokens; t < maxt; t++) { + for (q = index; q < &index[assval];) + *q++ = -1; + for (t = tokens; t < maxt; t++) + { index[t->t_tokno] = t - tokens; } - fputs("#define LLindex (LL_index+1)\nstatic short LL_index[] = {0,0,\n",f); - for (q = index+1; q < &index[assval]; q++) { + fputs("#define LLindex (LL_index+1)\nstatic short LL_index[] = {0,0,\n", f); + for (q = index + 1; q < &index[assval]; q++) + { fprintf(f, "%d,\n", *q); } fputs(c_arrend, f); free((p_mem) index); - if (onerror) { + if (onerror) + { fputs("static short LLtok[] = {\n", f); - for (t = tokens; t < maxt; t++) { - fprintf(f, t->t_tokno<0400 ? "'%s',\n" : "%s,\n",t->t_string); + for (t = tokens; t < maxt; t++) + { + fprintf(f, t->t_tokno < 0400 ? "'%s',\n" : "%s,\n", t->t_string); } fputs(c_arrend, f); } @@ -305,52 +325,54 @@ genrecovery() { } #ifdef NON_CORRECTING -STATIC -genncrecovery() { - register FILE *f; - register p_token t; - register int *q; - int *index; +STATIC void genncrecovery(void) +{ + register FILE *f; + register p_token t; + register int *q; + int *index; - /* Generate the non-correcting error recovery file */ + /* Generate the non-correcting error recovery file */ - opentemp((string) 0); - f = fpars; + opentemp((string) 0); + f = fpars; - genhdr(); - correct_prefix(); - save_grammar(f); + genhdr(); + correct_prefix(); + save_grammar(f); - fprintf(f, "#define LLFIRST_NT %d\n", assval); - fprintf(f, "#define LLSETSIZE %d\n", nbytes); + fprintf(f, "#define LLFIRST_NT %d\n", assval); + fprintf(f, "#define LLSETSIZE %d\n", nbytes); - index = (int *) alloc((unsigned) (assval * sizeof(int))); - for (q = index; q < &index[assval];) *q++ = -1; - for (t = tokens; t < maxt; t++) { - index[t->t_tokno] = t - tokens; - } - fputs("#define LLindex (LL_index+1)\nstatic short LL_index[] = {0,0,\n",f); - for (q = index+1; q < &index[assval]; q++) { - fprintf(f, "%d,\n", *q); - } - fputs(c_arrend, f); - free((p_mem) index); + index = (int *) alloc((unsigned) (assval * sizeof(int))); + for (q = index; q < &index[assval];) *q++ = -1; + for (t = tokens; t < maxt; t++) + { + index[t->t_tokno] = t - tokens; + } + fputs("#define LLindex (LL_index+1)\nstatic short LL_index[] = {0,0,\n",f); + for (q = index+1; q < &index[assval]; q++) + { + fprintf(f, "%d,\n", *q); + } + fputs(c_arrend, f); + free((p_mem) index); - copyfile(nc_incl_file); - copyfile(nc_rec_file); + copyfile(nc_incl_file); + copyfile(nc_rec_file); - doclose(f); - install(f_nc, "."); + doclose(f); + install(f_nc, "."); } #endif -STATIC -generate(f) p_file f; { +STATIC void generate(p_file f) +{ /* * Generates a parsing routine for every nonterminal */ register int s; - register p_nont p; + register p_nont p; int i; register p_first ff; int mustpop; @@ -359,75 +381,81 @@ generate(f) p_file f; { fprintf(fpars, "#define LL_LEXI %s\n", lexical); listcount = 0; /* Generate first sets */ - for (ff = f->f_firsts; ff; ff = ff->ff_next) { - macro(ff->ff_name,&nonterms[ff->ff_nont]); + for (ff = f->f_firsts; ff; ff = ff->ff_next) + { + macro(ff->ff_name, &nonterms[ff->ff_nont]); } genhdr(); /* For every nonterminal generate a function */ - for (s = f->f_nonterminals; s != -1; s = p->n_next) { + for (s = f->f_nonterminals; s != -1; s = p->n_next) + { p = &nonterms[s]; /* Generate functions in the order in which the nonterminals * were defined in the grammar. This is important, because * of synchronisation with the action file */ - while (p->n_count--) getaction(1); - if (g_gettype(p->n_rule) == EORULE && - getntparams(p) == 0) { + while (p->n_count--) + getaction(1); + if (g_gettype(p->n_rule) == EORULE && getntparams(p) == 0) + { continue; } - if (is_first) genprototypes(f); + if (is_first) + genprototypes(f); is_first = 0; - if (p->n_flags & GENSTATIC) fputs("static\n", fpars); - fputs("#if LL_ANSI_C\nvoid\n#endif\n", fpars); + if (p->n_flags & GENSTATIC) + fputs("static\n", fpars); + fputs("void\n", fpars); genextname(s, p->n_name, fpars); - if (p->n_flags & PARAMS) { - long off = ftell(fact); - fputs("(\n#if LL_ANSI_C\n", fpars); + if (p->n_flags & PARAMS) + { + fputs("(\n", fpars); +/* long off = ftell(fact);*/ controlline(); getansiparams(1); - fseek(fact, off, 0); - fputs("#else\n", fpars); - controlline(); - getparams(); - fputs("#endif\n{\n", fpars); +/* fseek(fact, off, 0);*/ + fputs("{\n", fpars); } - else fputs("(\n#if LL_ANSI_C\nvoid\n#endif\n) {\n", fpars); - if (p->n_flags & LOCALS) getaction(1); + else + fputs("(\nvoid\n) {\n", fpars); + if (p->n_flags & LOCALS) + getaction(1); i = getntsafe(p); mustpop = NOPOP; - if (g_gettype(p->n_rule) == ALTERNATION && - i > SAFESCANDONE) { + if (g_gettype(p->n_rule) == ALTERNATION && i > SAFESCANDONE) + { mustpop = findindex(p->n_contains); - if (i == NOSCANDONE) { + if (i == NOSCANDONE) + { fputs(c_read, fpars); i = SCANDONE; } } nlabel = 1; - rulecode(p->n_rule, - i, - getntout(p) != NOSCANDONE, - mustpop); + rulecode(p->n_rule, i, getntout(p) != NOSCANDONE, mustpop); fputs(c_close, fpars); } } -STATIC void -prset(p) p_set p; { +STATIC void prset(p_set p) +{ register int k; register unsigned i; int j; j = nbytes; - for (;;) { + for (;;) + { i = (unsigned) *p++; - for (k = 0; k < sizeof(int); k++) { - fprintf(fpars,"'\\%o',",(int)(i & 0377)); + for (k = 0; k < sizeof(int); k++) + { + fprintf(fpars, "'\\%o',", (int) (i & 0377)); i >>= 8; - if (--j == 0) { - fputs("\n",fpars); + if (--j == 0) + { + fputs("\n", fpars); return; } } @@ -435,39 +463,42 @@ prset(p) p_set p; { /* NOTREACHED */ } -STATIC void -macro(s,n) string s; p_nont n; { +STATIC void macro(string s, p_nont n) +{ int i; i = findindex(n->n_first); - if (i < 0) { - fprintf(fpars, "#define %s(x) ((x) == %d)\n", - s, - tokens[-(i+1)].t_tokno); + if (i < 0) + { + fprintf(fpars, "#define %s(x) ((x) == %d)\n", s, + tokens[-(i + 1)].t_tokno); return; } firsts = 1; - fprintf(fpars,"#define %s(x) LLfirst((x), %d)\n", s, i); + fprintf(fpars, "#define %s(x) LLfirst((x), %d)\n", s, i); } -STATIC -controlline() { +STATIC void controlline(void) +{ /* Copy a compiler control line */ register int l; - register FILE *f1,*f2; + register FILE *f1, *f2; - f1 = fact; f2 = fpars; + f1 = fact; + f2 = fpars; l = getc(f1); assert(l == '\0'); - do { + do + { l = getc(f1); - if (l == EOF) fatal(0, "temp file mangled"); - putc(l,f2); - } while ( l != '\n' ) ; + if (l == EOF) + fatal(0, "temp file mangled", NULL ); + putc(l, f2); + } while (l != '\n'); } -STATIC -getparams() { +STATIC void getparams(void) +{ /* getparams is called if a nonterminal has parameters. The names * of the parameters have to be found, and they should be declared */ @@ -482,98 +513,92 @@ getparams() { off = ftell(fact); /* First pass through declaration, find the parameter names */ ltext[0] = '\0'; - while ((l = gettok()) != ENDDECL) { - if ((l == ';' || l == ',') && ltext[0] != '\0') { + while ((l = gettok()) != ENDDECL) + { + if ((l == ';' || l == ',') && ltext[0] != '\0') + { /* * The last identifier found before a ';' or a ',' * must be a parameter */ - fprintf(fpars,"%c%s", first, ltext); + fprintf(fpars, "%c%s", first, ltext); first = ','; ltext[0] = '\0'; } } - if (ltext[0] != '\0') { + if (ltext[0] != '\0') + { fprintf(fpars, "%c%s", first, ltext); add_semi = ';'; } - fputs(") ",fpars); + fputs(") ", fpars); /* * Now copy the declarations */ - l = getc(fact); /* patch: some implementations of fseek - do not work properly after "ungetc" - */ - fseek(fact,off,0); + l = getc(fact); /* patch: some implementations of fseek + do not work properly after "ungetc" + */ + fseek(fact, off, 0); getaction(0); - fprintf(fpars, "%c\n",add_semi); + fprintf(fpars, "%c\n", add_semi); } -STATIC -genprototypes(f) - register p_file f; +STATIC void genprototypes(register p_file f) { /* * Generate prototypes for all nonterminals */ register int i; - register p_nont p; - long off = ftell(fact); + register p_nont p; + long off = ftell(fact); - fputs("#if LL_ANSI_C\n", fpars); - for (i = 0; i < nnonterms; i++) { - if (! IN(f->f_used, i)) continue; + for (i = 0; i < nnonterms; i++) + { + if (!IN(f->f_used, i)) + continue; p = &nonterms[i]; - if (g_gettype(p->n_rule) == EORULE && - getntparams(p) == 0) { + if (g_gettype(p->n_rule) == EORULE && getntparams(p) == 0) + { continue; } - if (p->n_flags & GENSTATIC) fputs("static ", fpars); + if (p->n_flags & GENSTATIC) + fputs("static ", fpars); fputs("void ", fpars); genextname(i, p->n_name, fpars); - if (p->n_flags & PARAMS) { + if (p->n_flags & PARAMS) + { fputs("(\n", fpars); fseek(fact, p->n_off, 0); controlline(); getansiparams(0); } - else fputs("(void);\n", fpars); + else + fputs("(void);\n", fpars); } fseek(fact, off, 0); - fputs("#else\n", fpars); - for (i = 0; i < nnonterms; i++) { - if (! IN(f->f_used, i)) continue; - p = &nonterms[i]; - if (!(p->n_flags & GENSTATIC)) continue; - if (g_gettype(p->n_rule) == EORULE && - getntparams(p) == 0) { - continue; - } - fputs("static ", fpars); - genextname(i, p->n_name, fpars); - fputs("();\n", fpars); - } - fputs("#endif\n", fpars); } -STATIC -getansiparams(mkdef) { - /* getansiparams is called if a nonterminal has parameters - * and an ANSI C function definition/declaration has to be produced. - * If a definition has to be produced, "mkdef" is set to 1. - */ +/* getansiparams is called if a nonterminal has parameters + * and an ANSI C function definition/declaration has to be produced. + * If a definition has to be produced, "mkdef" is set to 1. + */STATIC void getansiparams(int mkdef) +{ register int l; int delayed = 0; ltext[0] = '\0'; - while ((l = gettok()) != ENDDECL) { - if (l > 0177 || c_class[l] != ISSPA) { - if (delayed) { + while ((l = gettok()) != ENDDECL) + { + if (l > 0177 || c_class[l] != ISSPA) + { + if (delayed) + { fputc(',', fpars); delayed = 0; } } - if ((l == ';' || l == ',') && ltext[0] != '\0') { + if ((l == ';' || l == ',') && ltext[0] != '\0') + { /* * The last identifier found before a ';' or a ',' * must be a parameter @@ -581,152 +606,182 @@ getansiparams(mkdef) { delayed = 1; ltext[0] = '\0'; } - else if (l == IDENT) fprintf(fpars, "%s", ltext); - else fputc(l, fpars); + else if (l == IDENT) + fprintf(fpars, "%s", ltext); + else + fputc(l, fpars); } fprintf(fpars, ") %c\n", mkdef ? ' ' : ';'); } -STATIC -gettok() { +STATIC int gettok(void) +{ /* Read from the action file. */ register int ch; - register string c; + register string c; register FILE *f; f = fact; ch = getc(f); - switch(ch) { - case '\n': - ch = getc(f); - if (ch != EOF) { - ungetc(ch,f); - if (ch != '\0') return '\n'; - } - return ENDDECL; - case '\0': - ungetc(ch,f); - /* Fall through */ - case EOF : - return ENDDECL; - default : - if (c_class[ch] == ISLET) { - c = ltext; - do { - *c++ = ch; - if (c-ltext >= LTEXTSZ) --c; - ch = getc(f); - } while (c_class[ch] == ISLET || c_class[ch] == ISDIG); - if (ch != EOF) ungetc(ch,f); - *c = '\0'; - return IDENT; - } - return ch; + switch (ch) + { + case '\n': + ch = getc(f); + if (ch != EOF) + { + ungetc(ch, f); + if (ch != '\0') + return '\n'; + } + return ENDDECL; + case '\0': + ungetc(ch, f); + /* Fall through */ + case EOF: + return ENDDECL; + default: + if (c_class[ch] == ISLET) + { + c = ltext; + do + { + *c++ = ch; + if (c - ltext >= LTEXTSZ) + --c; + ch = getc(f); + } while (c_class[ch] == ISLET || c_class[ch] == ISDIG); + if (ch != EOF) + ungetc(ch, f); + *c = '\0'; + return IDENT; + } + return ch; } } -STATIC void -rulecode(p,safety,mustscan,mustpop) register p_gram p; { +STATIC void rulecode(register p_gram p, int safety, int mustscan, int mustpop) +{ /* * Code for a production rule. */ - register int toplevel = 1; - register FILE *f; - register int *ppu; - int *pushlist; - int *ppushlist; + register int toplevel = 1; + register FILE *f; + register int *ppu; + int *pushlist; + int *ppushlist; /* * First generate code to push the contains sets of this rule * on a stack */ - ppushlist = dopush(p,safety,1, &pushlist); - if (mustpop != NOPOP) for (ppu = pushlist; ppu < ppushlist; ppu++) { - if (*ppu == mustpop) { - *ppu = mustpop = NOPOP; - break; + ppushlist = dopush(p, safety, 1, &pushlist); + if (mustpop != NOPOP) + for (ppu = pushlist; ppu < ppushlist; ppu++) + { + if (*ppu == mustpop) + { + *ppu = mustpop = NOPOP; + break; + } } - } - if (g_gettype(p) != ALTERNATION) { + if (g_gettype(p) != ALTERNATION) + { genpop(mustpop); mustpop = NOPOP; } - for (ppu = pushlist; ppu < ppushlist; ppu++) genpush(*ppu); + for (ppu = pushlist; ppu < ppushlist; ppu++) + genpush(*ppu); free((p_mem) pushlist); f = fpars; - for (;;) { - switch (g_gettype(p)) { - case EORULE : - if (mustscan && safety == NOSCANDONE) { - fputs(c_read,f); + for (;;) + { + switch (g_gettype(p)) + { + case EORULE: + if (mustscan && safety == NOSCANDONE) + { + fputs(c_read, f); } return; - case LITERAL : - case TERMINAL : { + case LITERAL: + case TERMINAL: + { register p_token t; string s; t = &tokens[g_getcont(p)]; - if (toplevel == 0) { - fprintf(f,"LLtdecr(%d);\n", g_getcont(p)); + if (toplevel == 0) + { + fprintf(f, "LLtdecr(%d);\n", g_getcont(p)); } - if (safety == SAFE) { - fputs("LL_SAFE(",f); + if (safety == SAFE) + { + fputs("LL_SAFE(", f); } - else if (safety == SAFESCANDONE) { - fputs("LL_SSCANDONE(",f); + else if (safety == SAFESCANDONE) + { + fputs("LL_SSCANDONE(", f); } - else if (safety == SCANDONE) { - fputs("LL_SCANDONE(",f); + else if (safety == SCANDONE) + { + fputs("LL_SCANDONE(", f); } - else /* if (safety == NOSCANDONE) */ { + else /* if (safety == NOSCANDONE) */ + { fputs("LL_NOSCANDONE(", f); } - if (t->t_tokno < 0400) s = "'%s');\n"; - else s = "%s);\n"; - fprintf(f,s,t->t_string); - if (safety <= SAFESCANDONE && toplevel > 0) { + if (t->t_tokno < 0400) + s = "'%s');\n"; + else + s = "%s);\n"; + fprintf(f, s, t->t_string); + if (safety <= SAFESCANDONE && toplevel > 0) + { safety = NOSCANDONE; toplevel = -1; p++; continue; } safety = NOSCANDONE; - break; } - case NONTERM : { + break; + } + case NONTERM: + { register p_nont n = &nonterms[g_getcont(p)]; - if (safety == NOSCANDONE && - getntsafe(n) < NOSCANDONE) { + if (safety == NOSCANDONE && getntsafe(n) < NOSCANDONE) + { safety = getntsafe(n); fputs(c_read, f); } - if (toplevel == 0 && - (g_gettype(n->n_rule) != ALTERNATION || - getntsafe(n) <= SAFESCANDONE)) { + if (toplevel == 0 + && (g_gettype(n->n_rule) != ALTERNATION + || getntsafe(n) <= SAFESCANDONE)) + { genpop(findindex(n->n_contains)); } genextname(g_getcont(p), n->n_name, f); - if (g_getnpar(p)) { + if (g_getnpar(p)) + { fputs("(\n", f); controlline(); getaction(0); - fputs(");\n",f); + fputs(");\n", f); } - else fputs("();\n", f); + else + fputs("();\n", f); safety = getntout(n); - break; } - case TERM : - safety = codeforterm(g_getterm(p), - safety, - toplevel); break; - case ACTION : + } + case TERM: + safety = codeforterm(g_getterm(p), safety, toplevel); + break; + case ACTION: getaction(1); p++; continue; - case ALTERNATION : + case ALTERNATION: alternation(p, safety, mustscan, mustpop, 0); return; } @@ -735,54 +790,66 @@ rulecode(p,safety,mustscan,mustpop) register p_gram p; { } } -STATIC void -alternation(pp, safety, mustscan, mustpop, lb) - p_gram pp; +STATIC void alternation(p_gram pp, int safety, int mustscan, int mustpop, + int lb) { - register p_gram p = pp; - register FILE *f = fpars; - register p_link l; - int hulp, hulp1,hulp2; - int haddefault = 0; - int nsafe; - p_set set; - p_set setalloc(); - int *tokenlist = mk_tokenlist(); - int casecnt = 0; - int compacted; - int unsafe; + register p_gram p = pp; + register FILE *f = fpars; + register p_link l; + int hulp, hulp1, hulp2; + int haddefault = 0; + int nsafe; + p_set set; + p_set setalloc(); + int *tokenlist = mk_tokenlist(); + int casecnt = 0; + int compacted; + int unsafe; assert(safety < NOSCANDONE); hulp = nlabel++; hulp1 = nlabel++; hulp2 = nlabel++; - if (!lb) lb = hulp1; + if (!lb) + lb = hulp1; unsafe = onerror || safety > SAFESCANDONE; - if (!unsafe) { + if (!unsafe) + { genpop(mustpop); mustpop = NOPOP; } - if (unsafe && hulp1 == lb) { - fprintf(f,"goto L_%d; /* so that the label is used for certain */\nL_%d: ;\n", hulp1, hulp1); + if (unsafe && hulp1 == lb) + { + fprintf(f, + "goto L_%d; /* so that the label is used for certain */\nL_%d: ;\n", + hulp1, hulp1); } - if (safety == SAFE) { + if (safety == SAFE) + { /* check if we can avoid to generate the switch */ - for (;;) { - if (g_gettype(p) == EORULE) return; + for (;;) + { + if (g_gettype(p) == EORULE) + return; l = g_getlink(p); - if (l->l_flag & COND) break; - if ((g_gettype(l->l_rule) != TERMINAL && - g_gettype(l->l_rule) != LITERAL) || - g_gettype(l->l_rule+1) != EORULE) break; + if (l->l_flag & COND) + break; + if ((g_gettype(l->l_rule) != TERMINAL + && g_gettype(l->l_rule) != LITERAL) + || g_gettype(l->l_rule+1) != EORULE) + break; p++; } p = pp; } - while (g_gettype(p) != EORULE) { + while (g_gettype(p) != EORULE) + { set = 0; l = g_getlink(p); - if (l->l_flag & COND) { - if (!(l->l_flag & NOCONF)) { + if (l->l_flag & COND) + { + if (!(l->l_flag & NOCONF)) + { set = setalloc(); setunion(set, l->l_others); setintersect(set, l->l_symbs); @@ -791,24 +858,31 @@ alternation(pp, safety, mustscan, mustpop, lb) add_cases(set, tokenlist, casecnt++); } } - if (!unsafe && (l->l_flag & DEF)) { + if (!unsafe && (l->l_flag & DEF)) + { haddefault = 1; } - else add_cases(l->l_symbs, tokenlist, casecnt++); - if (l->l_flag & DEF) { + else + add_cases(l->l_symbs, tokenlist, casecnt++); + if (l->l_flag & DEF) + { haddefault = 1; } - if ((l->l_flag & COND) && !(l->l_flag & NOCONF)) { + if ((l->l_flag & COND) && !(l->l_flag & NOCONF)) + { p++; - if (g_gettype(p+1) == EORULE) { + if (g_gettype(p+1) == EORULE) + { setminus(g_getlink(p)->l_symbs, set); free((p_mem) set); continue; } free((p_mem) set); - if (!haddefault) { + if (!haddefault) + { } - else { + else + { add_cases(l->l_others, tokenlist, casecnt++); unsafe = 0; } @@ -821,78 +895,96 @@ alternation(pp, safety, mustscan, mustpop, lb) p = pp; haddefault = 0; compacted = analyze_switch(tokenlist); - if (compacted) { + if (compacted) + { fputs("{", f); out_list(tokenlist, listcount++, casecnt); } - else fputs("switch(LLcsymb) {\n", f); + else + fputs("switch(LLcsymb) {\n", f); casecnt = 0; - while (g_gettype(p) != EORULE) { + while (g_gettype(p) != EORULE) + { l = g_getlink(p); - if (l->l_flag & COND) { - if (l->l_flag & NOCONF) { + if (l->l_flag & COND) + { + if (l->l_flag & NOCONF) + { fputs("#ifdef ___NOCONFLICT___\n", f); } - else gencases(tokenlist, casecnt++, compacted); + else + gencases(tokenlist, casecnt++, compacted); controlline(); - fputs("if (!",f); + fputs("if (!", f); getaction(0); - fprintf(f,") goto L_%d;\n", hulp); - if (l->l_flag & NOCONF) { + fprintf(f, ") goto L_%d;\n", hulp); + if (l->l_flag & NOCONF) + { fputs("#endif\n", f); } } - if (!unsafe && (l->l_flag & DEF)) { + if (!unsafe && (l->l_flag & DEF)) + { haddefault = 1; fputs("default:\n", f); } - else gencases(tokenlist, casecnt++, compacted); + else + gencases(tokenlist, casecnt++, compacted); nsafe = SAFE; - if (l->l_flag & DEF) { - if (unsafe) { - fprintf(f,"goto L_%d;\nL_%d: ;\n", hulp2, hulp2); + if (l->l_flag & DEF) + { + if (unsafe) + { + fprintf(f, "goto L_%d;\nL_%d: ;\n", hulp2, hulp2); } - if (safety != SAFE) nsafe = SAFESCANDONE; + if (safety != SAFE) + nsafe = SAFESCANDONE; } rulecode(l->l_rule, nsafe, mustscan, mustpop); - fputs(c_break,f); - if (unsafe && (l->l_flag & DEF)) { + fputs(c_break, f); + if (unsafe && (l->l_flag & DEF)) + { haddefault = 1; - fprintf(f, -"default: if (LLskip()) goto L_%d;\ngoto L_%d;\n", - lb, hulp2); + fprintf(f, "default: if (LLskip()) goto L_%d;\ngoto L_%d;\n", lb, + hulp2); } - if ((l->l_flag & COND) && !(l->l_flag & NOCONF)) { + if ((l->l_flag & COND) && !(l->l_flag & NOCONF)) + { p++; - fprintf(f,"goto L_%d;\nL_%d : ;\n", hulp, hulp); - if (g_gettype(p+1) == EORULE) { + fprintf(f, "goto L_%d;\nL_%d : ;\n", hulp, hulp); + if (g_gettype(p+1) == EORULE) + { continue; } - if (!haddefault) { + if (!haddefault) + { fputs("default:\n", f); } - else { + else + { gencases(tokenlist, casecnt++, compacted); safety = SAFE; unsafe = 0; } - if (! unsafe) { + if (!unsafe) + { genpop(mustpop); mustpop = NOPOP; } - alternation(p,safety,mustscan,mustpop,lb); + alternation(p, safety, mustscan, mustpop, lb); break; } p++; } - if (compacted) fputs(c_close, f); + if (compacted) + fputs(c_close, f); fputs(c_close, f); free((p_mem) tokenlist); } -STATIC int * -dopush(p,safety,toplevel,pp) register p_gram p; int **pp; { +STATIC int *dopush(register p_gram p, int safety, int toplevel, int **pp) +{ /* * The safety only matters if toplevel != 0 */ @@ -901,50 +993,60 @@ dopush(p,safety,toplevel,pp) register p_gram p; int **pp; { *pp = ip; - for (;;) { - if (ip - *pp >= i) { - *pp = (int *) - ralloc((p_mem) (*pp), (i + 100) * sizeof(int)); + for (;;) + { + if (ip - *pp >= i) + { + *pp = (int *) ralloc((p_mem) (*pp), (i + 100) * sizeof(int)); ip = *pp + i; i += 100; } - switch(g_gettype(p)) { - case EORULE : - case ALTERNATION : + switch (g_gettype(p)) + { + case EORULE: + case ALTERNATION: return ip; - case TERM : { + case TERM: + { register p_term q; int rep_kind, rep_count; q = g_getterm(p); rep_kind = r_getkind(q); rep_count = r_getnum(q); - if (!(toplevel > 0 && safety <= SAFESCANDONE && - (rep_kind == OPT || (rep_kind == FIXED && rep_count == 0)))) { + if (!(toplevel > 0 && safety <= SAFESCANDONE + && (rep_kind == OPT || (rep_kind == FIXED && rep_count == 0)))) + { *ip++ = findindex(q->t_contains); } - break; } - case LITERAL : - case TERMINAL : - if (toplevel > 0 && safety <= SAFESCANDONE) { + break; + } + case LITERAL: + case TERMINAL: + if (toplevel > 0 && safety <= SAFESCANDONE) + { toplevel = -1; p++; safety = NOSCANDONE; continue; } - if (toplevel == 0) *ip++ = -(g_getcont(p)+1); + if (toplevel == 0) + *ip++ = -(g_getcont(p) + 1); break; - case NONTERM : { + case NONTERM: + { register p_nont n; n = &nonterms[g_getcont(p)]; - if (toplevel == 0 || - (g_gettype(n->n_rule) == ALTERNATION && - getntsafe(n) > SAFESCANDONE)) { + if (toplevel == 0 + || (g_gettype(n->n_rule) == ALTERNATION + && getntsafe(n) > SAFESCANDONE)) + { *ip++ = findindex(n->n_contains); } - break; } - case ACTION : + break; + } + case ACTION: p++; continue; } @@ -956,158 +1058,185 @@ dopush(p,safety,toplevel,pp) register p_gram p; int **pp; { # define max(a,b) ((a) < (b) ? (b) : (a)) -STATIC void -getaction(flag) { - /* Read an action from the action file. - * flag = 1 if it is an action, - * 0 when reading parameters - */ +/* Read an action from the action file. + * flag = 1 if it is an action, + * 0 when reading parameters + */STATIC void getaction(int flag) +{ register int ch; register FILE *f; int mark = 0; - if (flag == 1) { + if (flag == 1) + { controlline(); } f = fpars; - for (;;) { + for (;;) + { ch = gettok(); - switch(ch) { - case ENDDECL: - if (flag != 2) break; + switch (ch) + { + case ENDDECL: + if (flag != 2) + break; ch = getc(fact); assert(ch == '\0'); - fputs("\n",f); - if (mark) return; + fputs("\n", f); + if (mark) + return; mark = 1; continue; - case IDENT : - fputs(ltext,f); + case IDENT: + fputs(ltext, f); continue; } mark = 0; - if (ch == ENDDECL) break; - putc(ch,f); + if (ch == ENDDECL) + break; + putc(ch, f); } - if (flag) fputs("\n",f); + if (flag) + fputs("\n", f); } -STATIC -codeforterm(q,safety,toplevel) register p_term q; { - /* - * Generate code for a term - */ - register FILE *f = fpars; - register int rep_count = r_getnum(q); - register int rep_kind = r_getkind(q); - int term_is_persistent = (q->t_flags & PERSISTENT); - int ispushed = NOPOP; +/* + * Generate code for a term + */STATIC int codeforterm(register p_term q, int safety, int toplevel) +{ + register FILE *f = fpars; + register int rep_count = r_getnum(q); + register int rep_kind = r_getkind(q); + int term_is_persistent = (q->t_flags & PERSISTENT); + int ispushed = NOPOP; - if (!(toplevel > 0 && - (safety == 0 || (!onerror && safety <= SAFESCANDONE)) && - (rep_kind == OPT || (rep_kind == FIXED && rep_count == 0)))) { + if (!(toplevel > 0 && (safety == 0 || (!onerror && safety <= SAFESCANDONE)) + && (rep_kind == OPT || (rep_kind == FIXED && rep_count == 0)))) + { ispushed = findindex(q->t_contains); } - if (safety == NOSCANDONE && (rep_kind != FIXED || rep_count == 0 || - gettout(q) != NOSCANDONE)) { + if (safety == NOSCANDONE + && (rep_kind != FIXED || rep_count == 0 || gettout(q) != NOSCANDONE)) + { fputs(c_read, f); safety = SCANDONE; } - if (rep_kind == PLUS && !term_is_persistent) { + if (rep_kind == PLUS && !term_is_persistent) + { int temp; temp = findindex(q->t_first); - if (temp != ispushed) { + if (temp != ispushed) + { genpop(ispushed); ispushed = temp; genpush(temp); } } - if (rep_count) { + if (rep_count) + { /* N > 0, so generate fixed forloop */ - fputs("{\nregister LL_i;\n", f); + fputs("{\nregister int LL_i;\n", f); assert(ispushed != NOPOP); fprintf(f, "for (LL_i = %d; LL_i >= 0; LL_i--) {\n", rep_count - 1); - if (rep_kind == FIXED) { + if (rep_kind == FIXED) + { fputs("if (!LL_i) ", f); genpop(ispushed); genpush(ispushed); - if (safety == NOSCANDONE) { + if (safety == NOSCANDONE) + { assert(gettout(q) == NOSCANDONE); fputs(c_read, f); } } } - else if (rep_kind != OPT && rep_kind != FIXED) { + else if (rep_kind != OPT && rep_kind != FIXED) + { /* '+' or '*', so generate infinite loop */ - fputs("for (;;) {\n",f); + fputs("for (;;) {\n", f); } - else if (rep_kind == OPT && - (safety == 0 || (!onerror && safety <= SAFESCANDONE))) { + else if (rep_kind == OPT + && (safety == 0 || (!onerror && safety <= SAFESCANDONE))) + { genpop(ispushed); ispushed = NOPOP; } - if (rep_kind == STAR || rep_kind == OPT) { + if (rep_kind == STAR || rep_kind == OPT) + { genswhead(q, rep_kind, rep_count, safety, ispushed); } rulecode(q->t_rule, - t_safety(rep_kind,rep_count,term_is_persistent,safety), - gettout(q) != NOSCANDONE, - rep_kind == FIXED ? ispushed : NOPOP); - if (gettout(q) == NOSCANDONE && rep_kind != FIXED) { + t_safety(rep_kind, rep_count, term_is_persistent, safety), + gettout(q) != NOSCANDONE, rep_kind == FIXED ? ispushed : NOPOP); + if (gettout(q) == NOSCANDONE && rep_kind != FIXED) + { fputs(c_read, f); } /* in the case of '+', the if is after the code for the rule */ - if (rep_kind == PLUS) { - if (rep_count) { + if (rep_kind == PLUS) + { + if (rep_count) + { fputs("if (!LL_i) break;\n", f); } genswhead(q, rep_kind, rep_count, safety, ispushed); } - if (rep_kind != OPT && rep_kind != FIXED) fputs("continue;\n", f); - if (rep_kind != FIXED) { + if (rep_kind != OPT && rep_kind != FIXED) + fputs("continue;\n", f); + if (rep_kind != FIXED) + { fputs(c_close, f); /* Close switch */ fputs(c_close, f); - if (rep_kind != OPT) { + if (rep_kind != OPT) + { genpop(ispushed); fputs(c_break, f); } } - if (rep_kind != OPT && (rep_kind != FIXED || rep_count > 0)) { - fputs(c_close, f); /* Close for */ - if (rep_count > 0) { + if (rep_kind != OPT && (rep_kind != FIXED || rep_count > 0)) + { + fputs(c_close, f); /* Close for */ + if (rep_count > 0) + { fputs(c_close, f);/* Close Register ... */ } } return t_after(rep_kind, rep_count, gettout(q)); } -STATIC -genswhead(q, rep_kind, rep_count, safety, ispushed) register p_term q; { +STATIC void genswhead(register p_term q, int rep_kind, int rep_count, + int safety, int ispushed) +{ /* * Generate switch statement for term q */ - register FILE *f = fpars; - p_set p1; - p_set setalloc(); - int hulp1 = 0, hulp2; - int safeterm; - int termissafe = 0; - int casecnt = 0; - int *tokenlist = mk_tokenlist(); - int compacted; + register FILE *f = fpars; + p_set p1; + p_set setalloc(); + int hulp1 = 0, hulp2; + int safeterm; + int termissafe = 0; + int casecnt = 0; + int *tokenlist = mk_tokenlist(); + int compacted; - if (rep_kind == PLUS) safeterm = gettout(q); - else if (rep_kind == OPT) safeterm = safety; - else /* if (rep_kind == STAR) */ safeterm = max(safety, gettout(q)); + if (rep_kind == PLUS) + safeterm = gettout(q); + else if (rep_kind == OPT) + safeterm = safety; + else + /* if (rep_kind == STAR) */safeterm = max(safety, gettout(q)); hulp2 = nlabel++; fprintf(f, "goto L_%d;\nL_%d : ", hulp2, hulp2); - if (q->t_flags & RESOLVER) { + if (q->t_flags & RESOLVER) + { hulp1 = nlabel++; - if (! (q->t_flags & NOCONF)) { + if (!(q->t_flags & NOCONF)) + { p1 = setalloc(); - setunion(p1,q->t_first); - setintersect(p1,q->t_follow); + setunion(p1, q->t_first); + setintersect(p1, q->t_follow); /* * p1 now points to a set containing the conflicting * symbols @@ -1119,61 +1248,81 @@ genswhead(q, rep_kind, rep_count, safety, ispushed) register p_term q; { free((p_mem) p1); } } - if (safeterm == 0 || (!onerror && safeterm <= SAFESCANDONE)) { + if (safeterm == 0 || (!onerror && safeterm <= SAFESCANDONE)) + { termissafe = 1; } - else add_cases(q->t_follow, tokenlist, casecnt++); - if (!onerror && (q->t_flags & PERSISTENT) && safeterm != SAFE) { + else + add_cases(q->t_follow, tokenlist, casecnt++); + if (!onerror && (q->t_flags & PERSISTENT) && safeterm != SAFE) + { add_cases(q->t_contains, tokenlist, casecnt); } - else add_cases(q->t_first, tokenlist, casecnt); + else + add_cases(q->t_first, tokenlist, casecnt); compacted = analyze_switch(tokenlist); fputs("{", f); - if (compacted) { + if (compacted) + { out_list(tokenlist, listcount++, casecnt); } - else fputs("switch(LLcsymb) {\n", f); + else + fputs("switch(LLcsymb) {\n", f); casecnt = 0; - if (q->t_flags & RESOLVER) { - if (q->t_flags & NOCONF) { + if (q->t_flags & RESOLVER) + { + if (q->t_flags & NOCONF) + { fputs("#ifdef ___NOCONFLICT___\n", f); } - else gencases(tokenlist, casecnt++, compacted); + else + gencases(tokenlist, casecnt++, compacted); controlline(); fputs("if (", f); getaction(0); fprintf(f, ") goto L_%d;\n", hulp1); - if (q->t_flags & NOCONF) { + if (q->t_flags & NOCONF) + { fputs("#endif /* ___NOCONFLICT___ */\n", f); } } - if (safeterm == 0 || (!onerror && safeterm <= SAFESCANDONE)) { + if (safeterm == 0 || (!onerror && safeterm <= SAFESCANDONE)) + { fputs("default:\n", f); } - else gencases(tokenlist, casecnt++, compacted); - if (rep_kind == OPT) genpop(ispushed); + else + gencases(tokenlist, casecnt++, compacted); + if (rep_kind == OPT) + genpop(ispushed); fputs(c_break, f); - if (! termissafe) { + if (!termissafe) + { int i; static int nvar; assert(ispushed != NOPOP); - if (ispushed >= 0) i = -ispushed; - else i = tokens[-(ispushed+1)].t_tokno; + if (ispushed >= 0) + i = -ispushed; + else + i = tokens[-(ispushed + 1)].t_tokno; ++nvar; - fprintf(f,"default:{int LL_%d=LLnext(%d);\n;if (!LL_%d) {\n", - nvar, i, nvar); - if (rep_kind == OPT) genpop(ispushed); + fprintf(f, "default:{int LL_%d=LLnext(%d);\n;if (!LL_%d) {\n", nvar, i, + nvar); + if (rep_kind == OPT) + genpop(ispushed); fputs(c_break, f); fputs(c_close, f); - fprintf(f,"else if (LL_%d & 1) goto L_%d;}\n",nvar, hulp2); + fprintf(f, "else if (LL_%d & 1) goto L_%d;}\n", nvar, hulp2); } gencases(tokenlist, casecnt, compacted); - if (q->t_flags & RESOLVER) { + if (q->t_flags & RESOLVER) + { fprintf(f, "goto L_%d;\nL_%d : ;\n", hulp1, hulp1); } - if (rep_kind == OPT) genpop(ispushed); - if (rep_count > 0) { + if (rep_kind == OPT) + genpop(ispushed); + if (rep_count > 0) + { assert(ispushed != NOPOP); fputs(rep_kind == STAR ? "if (!LL_i) " : "if (LL_i == 1) ", f); genpop(ispushed); @@ -1181,9 +1330,7 @@ genswhead(q, rep_kind, rep_count, safety, ispushed) register p_term q; { free((p_mem) tokenlist); } -STATIC -gencases(tokenlist, caseno, compacted) - int *tokenlist; +STATIC void gencases(int *tokenlist, int caseno, int compacted) { /* * setp points to a bitset indicating which cases must @@ -1203,43 +1350,54 @@ gencases(tokenlist, caseno, compacted) register p_token p; register int i; - if (compacted) fprintf(fpars, "case %d :\n", caseno); - for (i = 0, p = tokens; i < ntokens; i++, p++) { - if (tokenlist[i] == caseno) { + if (compacted) + fprintf(fpars, "case %d :\n", caseno); + for (i = 0, p = tokens; i < ntokens; i++, p++) + { + if (tokenlist[i] == caseno) + { fprintf(fpars, - compacted ? - (p->t_tokno < 0400 ? "/* case '%s' */\n" : - "/* case %s */\n") : - p->t_tokno<0400 ? "case /* '%s' */ %d : ;\n" - : "case /* %s */ %d : ;\n", - p->t_string, i); + compacted ? + (p->t_tokno < 0400 ? + "/* case '%s' */\n" : "/* case %s */\n") : + p->t_tokno < 0400 ? + "case /* '%s' */ %d : ;\n" : + "case /* %s */ %d : ;\n", p->t_string, i); } } } static char namebuf[20]; -STATIC string -genname(s) string s; { - /* - * Generate a target file name from the - * source file name s. - */ - register string c,d; +/* + * Generate a target file name from the + * source file name s. + */STATIC string genname(string s) +{ + register string c, d; c = namebuf; - while (*s) { - if (*s == '/') { - while (*s == '/') s++; - if (*s) c = namebuf; - else break; + while (*s) + { + if (*s == '/') + { + while (*s == '/') + s++; + if (*s) + c = namebuf; + else + break; } *c++ = *s++; } - for (d = c; --d > namebuf;) if (*d == '.') break; - if (d == namebuf) d = c; - if (d >= &namebuf[12]) { - fatal(0,"%s : filename too long",namebuf); + for (d = c; --d > namebuf;) + if (*d == '.') + break; + if (d == namebuf) + d = c; + if (d >= &namebuf[12]) + { + fatal(0, "%s : filename too long", namebuf); } *d++ = '.'; *d++ = 'c'; @@ -1247,97 +1405,96 @@ genname(s) string s; { return namebuf; } -STATIC -genpush(d) { +STATIC void genpush(int d) +{ genincrdecr("incr", d); } -STATIC void -genincrdecr(s, d) string s; { - if (d == NOPOP) return; - if (d >= 0) { - fprintf(fpars, "LLs%s(%d);\n", s, d / nbytes); +STATIC void genincrdecr(string s, int d) +{ + if (d == NOPOP) + return; + if (d >= 0) + { + fprintf(fpars, "LLs%s(%d);\n", s, d / nbytes); return; } fprintf(fpars, "LLt%s(%d);\n", s, -(d + 1)); } -STATIC -genpop(d) { +STATIC void genpop(int d) +{ genincrdecr("decr", d); } -STATIC int -analyze_switch(tokenlist) - int *tokenlist; +STATIC int analyze_switch(int *tokenlist) { register int i; int ncases = 0; int percentage; int maxcase = 0, mincase = 0; - if (! jmptable_option) return 0; - for (i = 0; i < ntokens; i++) { - if (tokenlist[i] >= 0) { + if (!jmptable_option) + return 0; + for (i = 0; i < ntokens; i++) + { + if (tokenlist[i] >= 0) + { ncases++; - if (! mincase) mincase = i + 1; + if (!mincase) + mincase = i + 1; maxcase = i + 1; } } - if (ncases < min_cases_for_jmptable) return 0; + if (ncases < min_cases_for_jmptable) + return 0; percentage = ncases * 100 / (maxcase - mincase); fprintf(fpars, "/* percentage is %d */\n", percentage); return percentage >= low_percentage && percentage <= high_percentage; } -STATIC -add_cases(s, tokenlist, caseno) - p_set s; - int *tokenlist; +STATIC void add_cases(p_set s, int *tokenlist, int caseno) { register int i; - for (i = 0; i < ntokens; i++) { - if (IN(s, i)) { + for (i = 0; i < ntokens; i++) + { + if (IN(s, i)) + { tokenlist[i] = caseno; } } } -STATIC -out_list(tokenlist, listno, casecnt) - int *tokenlist; +STATIC void out_list(int *tokenlist, int listno, int casecnt) { register int i; register FILE *f = fpars; - fprintf(f, "static %s LL%d_tklist[] = {", - casecnt <= 127 ? "char" : "short", - listno); + fprintf(f, "static %s LL%d_tklist[] = {", casecnt <= 127 ? "char" : "short", + listno); - for (i = 0; i < ntokens; i++) { - fprintf(f, "%c%d,", i % 10 == 0 ? '\n': ' ', tokenlist[i]); + for (i = 0; i < ntokens; i++) + { + fprintf(f, "%c%d,", i % 10 == 0 ? '\n' : ' ', tokenlist[i]); } fputs(c_arrend, f); fprintf(f, "switch(LL%d_tklist[LLcsymb]) {\n", listno); } -STATIC -genextname(d, s, f) - char *s; - FILE *f; +STATIC void genextname(int d, char *s, FILE *f) { fprintf(f, "%s%d_%s", prefix ? prefix : "LL", d, s); } -STATIC -correct_prefix() +STATIC void correct_prefix(void) { register FILE *f = fpars; register char *s = prefix; - if (s) { + if (s) + { fprintf(f, "#define LLsymb %ssymb\n", s); fprintf(f, "#define LLerror %serror\n", s); fprintf(f, "#define LLsafeerror %ssafeerror\n", s); diff --git a/util/LLgen/src/global.c b/util/LLgen/src/global.c index 8c54e7bd4..e2fcc8599 100644 --- a/util/LLgen/src/global.c +++ b/util/LLgen/src/global.c @@ -16,6 +16,7 @@ * Contains declarations visible in several other source files */ +#include # include "types.h" # include "extern.h" # include "io.h" @@ -44,8 +45,8 @@ FILE *fout; FILE *fpars; FILE *finput; FILE *fact; -char f_pars[] = PARSERFILE; -char f_temp[] = ACTFILE; +char f_pars[L_tmpnam+sizeof(char)]; /* Add one more character for NULL, just in case of buggy implementations. */ +char f_temp[L_tmpnam+sizeof(char)]; #ifdef NON_CORRECTING char f_nc[20]; #endif @@ -77,7 +78,6 @@ string nc_rec_file, nc_incl_file; int low_percentage = 10, high_percentage = 30; int min_cases_for_jmptable = 8; int jmptable_option; -int ansi_c = 0; #ifdef NON_CORRECTING int non_corr = 0; int subpars_sim = 0; diff --git a/util/LLgen/src/io.h b/util/LLgen/src/io.h index d81f96446..fdfe0d630 100644 --- a/util/LLgen/src/io.h +++ b/util/LLgen/src/io.h @@ -21,8 +21,6 @@ /* FILES */ # define OUTFILE "%s.output" /* -v option */ -# define PARSERFILE "xxxXXXXXX" /* This is what we want */ -# define ACTFILE "tempXXXXXX" /* temporary file to save actions */ # define HFILE "%spars.h" /* file for "#define's " */ # define RFILE "%spars.c" /* Error recovery */ #ifdef NON_CORRECTING diff --git a/util/LLgen/src/machdep.c b/util/LLgen/src/machdep.c index 7fddf8eb2..babe3b34d 100644 --- a/util/LLgen/src/machdep.c +++ b/util/LLgen/src/machdep.c @@ -15,48 +15,51 @@ * machdep.c * Machine dependant things */ - +#include +#ifdef USE_SYS +#include +#endif #include #include +# include "alloc.h" +# include "extern.h" # include "types.h" # ifndef NORCSID static string rcsid5 = "$Id$"; # endif -/* In this file the following routines are defined: */ -extern UNLINK(); -extern RENAME(); -extern string libpath(); +#ifndef LIBDIR +#define LIBDIR "lib" +#endif -UNLINK(x) string x; { +void UNLINK(string x) +{ /* Must remove the file "x" */ - #ifdef USE_SYS sys_remove(x); /* systemcall to remove file */ #else - unlink(x); + remove(x); #endif } -RENAME(x,y) string x,y; { +void RENAME(string x,string y) +{ /* Must move the file "x" to the file "y" */ #ifdef USE_SYS - if(! sys_rename(x,y)) fatal(1,"Cannot rename to %s",y); + if(!sys_rename(x,y)) fatal(1,"Cannot rename to %s",y); #else if (rename(x, y) == -1) fatal(1, "Cannot rename to %s", y); #endif } -string -libpath(s) string s; { +string libpath(string s) +{ /* Must deliver a full pathname to the library file "s" */ - register string p; - register length; - p_mem alloc(); + register int length; char* libdir = getenv("LLGEN_LIB_DIR"); if (!libdir) @@ -68,3 +71,11 @@ libpath(s) string s; { strcat(p,s); return p; } + +void TMPNAM(string result) +{ + if (tmpnam(result)==NULL) + { + fatal(1, "Cannot create temporary file.", NULL); + } +} diff --git a/util/LLgen/src/main.c b/util/LLgen/src/main.c index 11a5c26a8..f26446e51 100644 --- a/util/LLgen/src/main.c +++ b/util/LLgen/src/main.c @@ -29,96 +29,103 @@ static string rcsid6 = "$Id$"; # endif /* In this file the following routines are defined: */ -extern int main(); -STATIC readgrammar(); -STATIC doparse(); -extern error(); -extern fatal(); -extern comfatal(); -extern copyfile(); -extern void install(); +STATIC void readgrammar(int, char *[]); +STATIC void doparse(register p_file); +STATIC void comfatal(void); -main(argc,argv) register string argv[]; { +extern void UNLINK(string); +extern void RENAME(string, string); +extern void TMPNAM(string); +extern string libpath(string); +extern void conflchecks(void); +extern void do_compute(void); +extern void gencode(int); + +int main(int argc, register string argv[]) +{ register string arg; - string libpath(); + + TMPNAM(f_temp); + TMPNAM(f_pars); /* Initialize */ assval = 0400; /* read options */ - while (argc >= 2 && (arg = argv[1], *arg == '-')) { - while (*++arg) { - switch(*arg) { - case 'j': - case 'J': + while (argc >= 2 && (arg = argv[1], *arg == '-')) + { + while (*++arg) + { + switch (*arg) + { + case 'j': + case 'J': jmptable_option = 1; if (*++arg) min_cases_for_jmptable = atoi(arg); break; - case 'w': - case 'W': + case 'w': + case 'W': wflag = 1; continue; - case 'v': - case 'V': + case 'v': + case 'V': verbose++; continue; - case 'l': - case 'L': + case 'l': + case 'L': low_percentage = atoi(++arg); break; - case 'h': - case 'H': + case 'h': + case 'H': high_percentage = atoi(++arg); break; # ifndef NDEBUG - case 'd': - case 'D': + case 'd': + case 'D': debug++; continue; - case 'r': - case 'R': - if (rec_file) { - fprintf(stderr,"duplicate -r flag\n"); + case 'r': + case 'R': + if (rec_file) + { + fprintf(stderr, "duplicate -r flag\n"); exit(1); } rec_file = ++arg; break; - case 'i': - case 'I': - if (incl_file) { - fprintf(stderr,"duplicate -i flag\n"); + case 'i': + case 'I': + if (incl_file) + { + fprintf(stderr, "duplicate -i flag\n"); exit(1); } incl_file = ++arg; break; #endif /* not NDEBUG */ - case 'x': - case 'X': + case 'x': + case 'X': ntneeded = 1; ntprint = 1; continue; - case 'a': - case 'A': - ansi_c = 1; - continue; #ifdef NON_CORRECTING - case 'n': - case 'N': + case 'n': + case 'N': non_corr = 1; continue; - case 's': - case 'S': + case 's': + case 'S': subpars_sim = 1; continue; #endif - case 'g': - case 'G': + case 'g': + case 'G': strip_grammar = 1; continue; - default: - fprintf(stderr,"illegal option : %c\n",*arg); + default: + fprintf(stderr, "illegal option : %c\n", *arg); exit(1); } break; @@ -128,55 +135,59 @@ main(argc,argv) register string argv[]; { } #ifdef NON_CORRECTING - if ((subpars_sim) && (!non_corr)) { - fprintf(stderr,"option -s illegal without -n, turned off\n"); - subpars_sim = 0; + if ((subpars_sim) && (!non_corr)) + { + fprintf(stderr,"option -s illegal without -n, turned off\n"); + subpars_sim = 0; } #endif /* * Now check wether the sets should include nonterminals */ - if (verbose == 2) ntneeded = 1; + if (verbose == 2) + ntneeded = 1; /* * Initialise */ # ifndef NDEBUG - if (!rec_file) { + if (!rec_file) + { # endif rec_file = libpath("rec"); # ifndef NDEBUG } - if (!incl_file) { + if (!incl_file) + { # endif incl_file = libpath("incl"); # ifndef NDEBUG } # endif #ifdef NON_CORRECTING - if (non_corr) { - nc_incl_file = libpath("nc_incl"); - nc_rec_file = libpath ("nc_rec"); + if (non_corr) + { + nc_incl_file = libpath("nc_incl"); + nc_rec_file = libpath ("nc_rec"); } #endif - close(mkstemp(f_temp)); - close(mkstemp(f_pars)); - if ((fact = fopen(f_temp,"w")) == NULL) { - fputs("Cannot create temporary\n",stderr); + if ((fact = fopen(f_temp, "w")) == NULL) + { + fputs("Cannot create temporary\n", stderr); exit(1); } name_init(); - readgrammar(argc,argv); + readgrammar(argc, argv); sprintf(f_out, OUTFILE, prefix ? prefix : "LL"); /* for the following two filenames only one L is used; historical - reasons ... - */ + reasons ... + */ sprintf(f_include, HFILE, prefix ? prefix : "L"); sprintf(f_rec, RFILE, prefix ? prefix : "L"); #ifdef NON_CORRECTING if (non_corr) - sprintf(f_nc, NCFILE, prefix ? prefix : "L"); + sprintf(f_nc, NCFILE, prefix ? prefix : "L"); #endif setinit(ntneeded); maxnt = &nonterms[nnonterms]; @@ -184,50 +195,60 @@ main(argc,argv) register string argv[]; { /* * Now, the grammar is read. Do some computations */ - co_reach(); /* Check for undefined and unreachable */ - if (nerrors) comfatal(); + co_reach(); /* Check for undefined and unreachable */ + if (nerrors) + comfatal(); do_compute(); conflchecks(); - if (nerrors) comfatal(); + if (nerrors) + comfatal(); fclose(fact); - if (argc-- == 1) { + if (argc-- == 1) + { fputs("No code generation for input from standard input\n", - stderr); + stderr); } - else gencode(argc); + else + gencode(argc); UNLINK(f_temp); UNLINK(f_pars); - if (verbose) { + if (verbose) + { fprintf(stderr, "number of nonterminals: %d\n", nnonterms); fprintf(stderr, "number of tokens: %d\n", ntokens); fprintf(stderr, "number of term structures: %d\n", nterms); fprintf(stderr, "number of alternation structures: %d\n", nalts); } - exit(0); + exit(EXIT_SUCCESS); } -STATIC -readgrammar(argc,argv) char *argv[]; { +STATIC void readgrammar(int argc, char *argv[]) +{ /* * Do just what the name suggests : read the grammar */ - register p_file p; - p_mem alloc(); + register p_file p; + p_mem alloc(); linecount = 0; f_input = "no filename"; /* * Build the file structure */ - files = p = (p_file) alloc((unsigned) (argc+1) * sizeof(t_file)); - if (argc-- == 1) { + files = p = (p_file) alloc((unsigned) (argc + 1) * sizeof(t_file)); + if (argc-- == 1) + { finput = stdin; f_input = "standard input"; doparse(p++); - } else { - while (argc--) { - if ((finput = fopen(f_input=argv[1],"r")) == NULL) { - fatal(0,e_noopen,f_input); + } + else + { + while (argc--) + { + if ((finput = fopen(f_input = argv[1], "r")) == NULL) + { + fatal(0, e_noopen, f_input); } doparse(p++); argv++; @@ -235,19 +256,21 @@ readgrammar(argc,argv) char *argv[]; { } } maxfiles = p; - if (! lexical) lexical = "yylex"; + if (!lexical) + lexical = "yylex"; /* * There must be a start symbol! */ - if (! nerrors && start == 0) { - fatal(linecount,"Missing %%start"); + if (!nerrors && start == 0) + { + fatal(linecount, "Missing %%start", NULL); } - if (nerrors) comfatal(); + if (nerrors) + comfatal(); } -STATIC -doparse(p) register p_file p; { - +STATIC void doparse(register p_file p) +{ linecount = 0; p->f_name = f_input; p->f_firsts = 0; @@ -259,90 +282,100 @@ doparse(p) register p_file p; { p->f_terminals = torder; } -/* VARARGS1 */ -error(lineno,s,t,u) string s,t,u; { +void error(int lineno, string s, string t) +{ /* * Just an error message */ ++nerrors; - if (!lineno) lineno = 1; - fprintf(stderr,"\"%s\", line %d: ",f_input, lineno); - fprintf(stderr,s,t,u); - fputs("\n",stderr); + if (!lineno) + lineno = 1; + fprintf(stderr, "\"%s\", line %d: ", f_input, lineno); + fprintf(stderr, s, t); + fputs("\n", stderr); } -/* VARARGS1 */ -void -warning(lineno,s,t,u) string s,t,u; { +void warning(int lineno, string s, string t) +{ /* * Just a warning */ - if (wflag) return; - if (!lineno) lineno = 1; - fprintf(stderr,"\"%s\", line %d: (Warning) ",f_input, lineno); - fprintf(stderr,s,t,u); - fputs("\n",stderr); + if (wflag) + return; + if (!lineno) + lineno = 1; + fprintf(stderr, "\"%s\", line %d: (Warning) ", f_input, lineno); + fprintf(stderr, s, t); + fputs("\n", stderr); } -/* VARARGS1 */ -fatal(lineno,s,t,u) string s,t,u; { +void fatal(int lineno, string s, string t) +{ /* * Fatal error */ - error(lineno,s,t,u); + error(lineno, s, t); comfatal(); } -comfatal() { +STATIC void comfatal(void) +{ /* * Some common code for exit on errors */ - if (fact != NULL) { + if (fact != NULL) + { fclose(fact); UNLINK(f_temp); } - if (fpars != NULL) fclose(fpars); + if (fpars != NULL) + fclose(fpars); UNLINK(f_pars); - exit(1); + exit(EXIT_FAILURE); } -copyfile(file) string file; { +void copyfile(string file) +{ /* * Copies a file indicated by the parameter to filedescriptor fpars. */ - register int c; - register FILE *f; + register int c; + register FILE *f; - if ((f = fopen(file,"r")) == NULL) { - fatal(0,"Cannot open library file %s, call an expert",file); + if ((f = fopen(file, "r")) == NULL) + { + fatal(0, "Cannot open library file %s, call an expert", file); } - while ((c = getc(f)) != EOF) putc(c,fpars); + while ((c = getc(f)) != EOF) + putc(c, fpars); fclose(f); } -void -install(target, source) string target, source; { +void install(string target, string source) +{ /* * Copy the temporary file generated from source to target * if allowed (which means that the target must be generated * by LLgen from the source, or that the target is not present */ - register int c1, c2; - register FILE *f1, *f2; - int cnt; + register int c1, c2; + register FILE *f1, *f2; + int cnt; /* * First open temporary, generated for source */ - if ((f1 = fopen(f_pars,"r")) == NULL) { - fatal(0,e_noopen,f_pars); + if ((f1 = fopen(f_pars, "r")) == NULL) + { + fatal(0, e_noopen, f_pars); } /* * Now open target for reading */ - if ((f2 = fopen(target,"r")) == NULL) { + if ((f2 = fopen(target, "r")) == NULL) + { fclose(f1); RENAME(f_pars, target); return; @@ -355,20 +388,24 @@ install(target, source) string target, source; { /* * Now compare the target with the temporary */ - do { + do + { c1 = getc(f1); c2 = getc(f2); - if (cnt >= 0) cnt--; + if (cnt >= 0) + cnt--; } while (c1 == c2 && c1 != EOF); fclose(f1); fclose(f2); /* * Here, if c1 != c2 the target must be recreated */ - if (c1 != c2) { - if (cnt >= 0) { - fatal(0,"%s : not a file generated by LLgen",target); + if (c1 != c2) + { + if (cnt >= 0) + { + fatal(0, "%s : not a file generated by LLgen", target); } - RENAME(f_pars,target); + RENAME(f_pars, target); } } diff --git a/util/LLgen/src/name.c b/util/LLgen/src/name.c index 2b9ba11fb..25fd22d74 100644 --- a/util/LLgen/src/name.c +++ b/util/LLgen/src/name.c @@ -18,6 +18,8 @@ */ #include +#include +# include "alloc.h" # include "types.h" # include "extern.h" # include "assert.h" @@ -30,38 +32,36 @@ static string rcsid7 = "$Id$"; # define HASHSIZE 128 # define NMSIZ 2048 /* Room for names allocated NMSIZ bytes at a time */ -static char *name, *maxname; -static p_entry h_root[HASHSIZE]; /* hash table */ -static string e_literal = "Illegal literal"; -static p_entry entries, maxentries; -static t_info token_info, nont_info; +static char *name, *maxname; +static p_entry h_root[HASHSIZE]; /* hash table */ +static string e_literal = "Illegal literal"; +static p_entry entries, maxentries; +static t_info token_info, nont_info; /* Defined in this file are: */ -extern string store(); -extern name_init(); -STATIC int hash(); -STATIC p_entry newentry(); -extern p_gram search(); +STATIC int hash(string str); +STATIC p_entry newentry(string str, p_entry next); -p_mem alloc(); -p_mem new_mem(); -name_init() { - token_info.i_esize = sizeof (t_token); + +void name_init(void) +{ + token_info.i_esize = sizeof(t_token); token_info.i_incr = 50; - nont_info.i_esize = sizeof (t_nont); + nont_info.i_esize = sizeof(t_nont); nont_info.i_incr = 50; - search(TERMINAL,"EOFILE",ENTERING); + search(TERMINAL, "EOFILE", ENTERING); #ifdef NON_CORRECTING illegal_gram = search(TERMINAL,"LLILLEGAL",ENTERING); #endif } -STATIC p_entry -newentry(str, next) string str; p_entry next; { +STATIC p_entry newentry(string str, p_entry next) +{ register p_entry p; - if ((p = entries) == maxentries) { + if ((p = entries) == maxentries) + { p = (p_entry) alloc(50 * sizeof(t_entry)); maxentries = p + 50; } @@ -75,18 +75,20 @@ newentry(str, next) string str; p_entry next; { return p; } -string -store(s) string s; { - /* - * Store a string s in the name table - */ - register string s1, t ,u; +/* + * Store a string s in the name table + */ +string store(string s) +{ + register string s1, t, u; u = name; t = s; s1 = u; - do { - if (u >= maxname) { + do + { + if (u >= maxname) + { u = alloc(NMSIZ); maxname = u + NMSIZ; t = s; @@ -98,60 +100,63 @@ store(s) string s; { return s1; } -STATIC int -hash(str) string str; { - /* - * Compute the hash for string str - */ - register int i; +/* + * Compute the hash for string str + */ +STATIC int hash(string str) +{ + register int i; register string l; l = str; i = 0; - while (*l != '\0') i += *l++ & 0377; + while (*l != '\0') + i += *l++ & 0377; i += l - str; return i % HASHSIZE; } -p_gram -search(type,str,option) register string str; { - /* - * Search for object str. - * It has type UNKNOWN, LITERAL, TERMINAL or NONTERM. - * option can be ENTERING or BOTH (also looking). - */ - register int val = 0; - register p_entry p; - register int i; - int type1; +/* + * Search for object str. + * It has type UNKNOWN, LITERAL, TERMINAL or NONTERM. + * option can be ENTERING or BOTH (also looking). + */ +p_gram search(int type, register string str, int option) +{ + register int val = 0; + register p_entry p; + register int i; + int type1; i = hash(str); /* * Walk hash chain */ - for (p = h_root[i]; p != (p_entry) 0; p = p->h_next) { - if(!strcmp(p->h_name,str)) { + for (p = h_root[i]; p != (p_entry) 0; p = p->h_next) + { + if (!strcmp(p->h_name, str)) + { type1 = g_gettype(&(p->h_type)); - if (type1 != type) { - if (type1 == LITERAL || type == LITERAL) { + if (type1 != type) + { + if (type1 == LITERAL || type == LITERAL) + { continue; } - if (type == TERMINAL) { - error(linecount, - "%s: is already a nonterminal", - str); + if (type == TERMINAL) + { + error(linecount, "%s: is already a nonterminal", str); continue; } - else if (type == NONTERM) { - error(linecount, - "%s : is already a token", - str); + else if (type == NONTERM) + { + error(linecount, "%s : is already a token", str); continue; } } - if (option==ENTERING) { - error(linecount, - "%s : is already defined",str); + if (option == ENTERING) + { + error(linecount, "%s : is already defined", str); } p->h_type.g_lineno = linecount; return &(p->h_type); @@ -159,64 +164,76 @@ search(type,str,option) register string str; { } p = newentry(store(str), h_root[i]); h_root[i] = p; - if (type == TERMINAL || type == LITERAL) { + if (type == TERMINAL || type == LITERAL) + { register p_token pt; pt = (p_token) new_mem(&token_info); tokens = (p_token) token_info.i_ptr; pt->t_string = p->h_name; - if (type == LITERAL) { - if (str[0] == '\\') { + if (type == LITERAL) + { + if (str[0] == '\\') + { /* * Handle escapes in literals */ - if (str[2] == '\0') { - switch(str[1]) { - case 'n' : + if (str[2] == '\0') + { + switch (str[1]) + { + case 'n': val = '\n'; break; - case 'r' : + case 'r': val = '\r'; break; - case 'b' : + case 'b': val = '\b'; break; - case 'f' : + case 'f': val = '\f'; break; - case 't' : + case 't': val = '\t'; break; - case '\'': + case '\'': val = '\''; break; - case '\\': + case '\\': val = '\\'; break; - default : - error(linecount,e_literal); + default: + error(linecount, e_literal, NULL); } - } else { + } + else + { /* * Here, str[2] != '\0' */ - if (str[1] > '3' || str[1] < '0' || - str[2] > '7' || str[2] < '0' || - str[3] > '7' || str[3] < '0' || - str[4] != '\0') error(linecount,e_literal); - val = 64*str[1] - 73*'0' + - 8*str[2] + str[3]; + if (str[1] > '3' || str[1] < '0' || str[2] > '7' + || str[2] < '0' || str[3] > '7' || str[3] < '0' + || str[4] != '\0') + error(linecount, e_literal, NULL); + val = 64 * str[1] - 73 * '0' + 8 * str[2] + str[3]; } - } else { + } + else + { /* * No escape in literal */ - if (str[1] == '\0') val = str[0]; - else error(linecount,e_literal); + if (str[1] == '\0') + val = str[0]; + else + error(linecount, e_literal, NULL); } pt->t_tokno = val; g_settype(&(p->h_type), LITERAL); - } else { + } + else + { /* * Here, type = TERMINAL */ diff --git a/util/LLgen/src/reach.c b/util/LLgen/src/reach.c index a8ca81a47..eebdecdcb 100644 --- a/util/LLgen/src/reach.c +++ b/util/LLgen/src/reach.c @@ -17,6 +17,7 @@ * are all defined. */ +#include # include "types.h" # include "extern.h" # include "io.h" @@ -26,12 +27,18 @@ static string rcsid8 = "$Id$"; # endif -/* In this file the following routines are defined: */ -extern co_reach(); -STATIC reachable(); -STATIC void reachwalk(); -co_reach() { + + +/* In this file the following routines are defined: */ +void co_reach(void); +STATIC void reachable(register p_nont p); +STATIC void reachwalk(p_gram p); + + + +void co_reach(void) +{ /* * Check for undefined or unreachable nonterminals. */ @@ -80,8 +87,8 @@ co_reach() { } } -STATIC -reachable(p) register p_nont p; { +STATIC void reachable(register p_nont p) +{ /* * Enter the fact that p is reachable, and look for implications */ @@ -94,8 +101,8 @@ reachable(p) register p_nont p; { } } -STATIC void -reachwalk(p) register p_gram p; { +STATIC void reachwalk(p_gram p) +{ /* * Walk through rule p, looking for nonterminals. * The nonterminals found are entered as reachable diff --git a/util/LLgen/src/savegram.c b/util/LLgen/src/savegram.c index a32935ecc..3638182b5 100644 --- a/util/LLgen/src/savegram.c +++ b/util/LLgen/src/savegram.c @@ -26,6 +26,7 @@ #include +#include # include "types.h" # include "extern.h" # include "io.h" @@ -69,7 +70,8 @@ static FILE *fgram; used when LLgen called with -n -s options */ int act_nt; -save_grammar(f) FILE *f; { +void save_grammar(FILE *f) +{ /* * Save the grammar */ @@ -267,8 +269,8 @@ save_grammar(f) FILE *f; { fprintf(fgram, "#define LLNNONTERMINALS %d\n", nt_highest - assval + 1); } -STATIC void -save_rule(p, tail) register p_gram p; int tail; { +STATIC void save_rule(register p_gram p, int tail) +{ /* Walk through rule p, saving it. The non-terminal tail is appended to the rule. It needs to be appended in this function @@ -363,8 +365,8 @@ save_rule(p, tail) register p_gram p; int tail; { } } -STATIC void -save_set(p) p_set p; { +STATIC void save_set(p_set p) +{ register int k; register unsigned i; int j; diff --git a/util/LLgen/src/sets.c b/util/LLgen/src/sets.c index dd1c1364f..4422039b0 100644 --- a/util/LLgen/src/sets.c +++ b/util/LLgen/src/sets.c @@ -16,25 +16,17 @@ * Set manipulation and allocation routines. */ +#include +# include # include "types.h" # include "extern.h" # include "sets.h" -# include "assert.h" # ifndef NORCSID static string rcsid9 = "$Id$"; # endif -/* In this file the following routines are defined: */ -extern setinit(); -extern p_set setalloc(); -extern p_set get_set(); -extern int setunion(); -extern int setintersect(); -extern setminus(); -extern int setempty(); -extern int findindex(); -extern int setcount(); + int nbytes; static int setsize; @@ -43,10 +35,11 @@ p_set *setptr, *maxptr; static t_info set_info; p_mem alloc(); -setinit(nt_needed) { - /* - * Initialises some variables needed for setcomputations - */ +/* + * Initialises some variables needed for setcomputations + */ +void setinit(int nt_needed) +{ register int bitset; nbytes = NBYTES(ntokens); @@ -61,8 +54,8 @@ setinit(nt_needed) { set_info.i_incr = 20; } -p_set -get_set() { +p_set get_set(void) +{ /* * Allocate a set that cannot be freed */ @@ -80,8 +73,8 @@ get_set() { return p; } -p_set -setalloc() { +p_set setalloc(void) +{ /* * Allocate a set which can later be freed. */ @@ -95,8 +88,8 @@ setalloc() { return p; } -int -setunion(a,b) register p_set a,b; { +int setunion(register p_set a,register p_set b) +{ /* * a = a union b. * Return 1 if the set a changed @@ -115,8 +108,8 @@ setunion(a,b) register p_set a,b; { return nsub; } -int -setintersect(a,b) register p_set a,b; { +int setintersect(register p_set a,register p_set b) +{ /* * a = a intersect b. * return 1 if the result is empty @@ -132,7 +125,8 @@ setintersect(a,b) register p_set a,b; { return nempty; } -setminus(a,b) register p_set a,b; { +void setminus(register p_set a,register p_set b) +{ /* * a = a setminus b */ @@ -144,8 +138,8 @@ setminus(a,b) register p_set a,b; { } while (--i); } -int -setempty(p) register p_set p; { +int setempty(register p_set p) +{ /* * Return 1 if the set p is empty */ @@ -158,8 +152,8 @@ setempty(p) register p_set p; { return 1; } -int -findindex(set) p_set set; { +int findindex(p_set set) +{ /* * The set "set" will serve as a recovery set. * Search for it in the table. If not present, enter it. @@ -204,8 +198,8 @@ findindex(set) p_set set; { return nbytes * (maxptr++ - setptr); } -int -setcount(set, saved) register p_set set; int *saved; { +int setcount(register p_set set, int *saved) +{ register int i, j; for (j = 0, i = 0; i < ntokens; i++) { diff --git a/util/LLgen/src/sets.h b/util/LLgen/src/sets.h index 501c3c154..87de245d3 100644 --- a/util/LLgen/src/sets.h +++ b/util/LLgen/src/sets.h @@ -2,6 +2,8 @@ * For full copyright and restrictions on use see the file COPYING in the top * level of the LLgen tree. */ +#ifndef SETS_H_ +#define SETS_H_ /* * L L G E N @@ -31,3 +33,44 @@ extern int tsetsize; extern p_set *setptr, *maxptr; extern int nbytes; + +/* + * Initialises some variables needed for setcomputations + */ +void setinit(int nt_needed); +/* + * Allocate a set that cannot be freed + */ +p_set get_set(void); +/* + * Allocate a set which can later be freed. + */ +p_set setalloc(void); +/* + * a = a union b. + * Return 1 if the set a changed + */ +int setunion(register p_set a,register p_set b); +/* + * a = a intersect b. + * return 1 if the result is empty + */ +int setintersect(register p_set a,register p_set b); +/* + * a = a setminus b + */ +void setminus(register p_set a,register p_set b); +/* + * Return 1 if the set p is empty + */ +int setempty(register p_set p); +/* + * The set "set" will serve as a recovery set. + * Search for it in the table. If not present, enter it. + * Here is room for improvement. At the moment, the list of + * sets is examined with linear search. + */ +int findindex(p_set set); +int setcount(register p_set set, int *saved); + +#endif /* SETS_H_ */ diff --git a/util/LLgen/src/tokens.c b/util/LLgen/src/tokens.c index 9d94d8716..0ac98a93b 100644 --- a/util/LLgen/src/tokens.c +++ b/util/LLgen/src/tokens.c @@ -2,9 +2,6 @@ #include "Lpars.h" #define LL_LEXI scanner #define LLNOFIRSTS -#if __STDC__ || __cplusplus -#define LL_ANSI_C 1 -#endif #define LL_LEXI scanner /* $Id$ */ #ifdef LL_DEBUG @@ -38,7 +35,6 @@ extern int LLstartsymb; #define LLsincr(d) LLscnt[d]++ #define LLtincr(d) LLtcnt[d]++ -#if LL_ANSI_C extern int LL_LEXI(void); extern void LLread(void); extern int LLskip(void); @@ -56,29 +52,11 @@ extern int LLfirst(int, int); #if LL_NON_CORR extern void LLnc_recover(void); #endif -#else /* not LL_ANSI_C */ -extern LLread(); -extern int LLskip(); -extern int LLnext(); -extern LLerror(); -extern LLsafeerror(); -extern LLnewlevel(); -extern LLoldlevel(); -#ifndef LL_FASTER -extern LLscan(); -#endif -#ifndef LLNOFIRSTS -extern int LLfirst(); -#endif -#if LL_NON_CORR -extern LLnc_recover(); -#endif -#endif /* not LL_ANSI_C */ # line 20 "tokens.g" #include -# include "types.h" +#include "types.h" # include "io.h" # include "extern.h" # include "assert.h" @@ -89,17 +67,17 @@ static string rcsidc = "$Id$"; # endif /* Here are defined : */ -extern int scanner(); -extern LLmessage(); -extern int input(); -extern unput(); -extern void skipcomment(); +int scanner(void); +void LLmessage(int d); +int input(void); +void unput(int c); +void skipcomment(int flag); # ifdef LINE_DIRECTIVE -STATIC linedirective(); +STATIC void linedirective(void); # endif -STATIC string cpy(); -STATIC string vallookup(); -STATIC void copyact(); +STATIC string cpy(int s,register string p,int inserted); +STATIC string vallookup(int s); +STATIC void copyact(char ch1,char ch2,int flag,int level); static int nparams; # line 76 "tokens.g" @@ -145,8 +123,8 @@ static t_token savedtok; /* to save lextoken in case of an insertion */ static int nostartline; /* = 0 if at the start of a line */ # endif -STATIC void -copyact(ch1,ch2,flag,level) char ch1,ch2; { +STATIC void copyact(char ch1,char ch2,int flag,int level) +{ /* * Copy an action to file f. Opening bracket is ch1, closing bracket * is ch2. @@ -155,8 +133,8 @@ copyact(ch1,ch2,flag,level) char ch1,ch2; { */ static int text_seen = 0; register FILE *f; - register ch; /* Current char */ - register match; /* used to read strings */ + register int ch; /* Current char */ + register int match; /* used to read strings */ int saved = linecount; /* save linecount */ int sav_strip = strip_grammar; @@ -187,7 +165,7 @@ copyact(ch1,ch2,flag,level) char ch1,ch2; { case ')': case '}': case ']': - error(linecount,"Parentheses mismatch"); + error(linecount,"Parentheses mismatch", NULL); break; case '(': text_seen = 1; @@ -218,7 +196,7 @@ copyact(ch1,ch2,flag,level) char ch1,ch2; { text_seen = 0; nparams++; if (ch == ',' && (flag & 2)) { - warning(linecount, "Parameters may not be separated with a ','"); + warning(linecount, "Parameters may not be separated with a ','",NULL); ch = ';'; } } @@ -239,7 +217,7 @@ copyact(ch1,ch2,flag,level) char ch1,ch2; { ch = input(); } if (ch == '\n') { - error(linecount,"Newline in string"); + error(linecount,"Newline in string", NULL); unput(match); } putc(ch,f); @@ -247,7 +225,7 @@ copyact(ch1,ch2,flag,level) char ch1,ch2; { if (ch == match) break; /* Fall through */ case EOF : - if (!level) error(saved,"Action does not terminate"); + if (!level) error(saved,"Action does not terminate", NULL); strip_grammar = sav_strip; return; default: @@ -257,7 +235,8 @@ copyact(ch1,ch2,flag,level) char ch1,ch2; { } } -scanner() { +int scanner(void) +{ /* * Lexical analyser, what else */ @@ -307,7 +286,7 @@ scanner() { for (;;) { ch = input(); if (ch == '\n' || ch == EOF) { - error(linecount,"Missing '"); + error(linecount,"Missing '", NULL); break; } if (ch == '\'') break; @@ -327,7 +306,7 @@ scanner() { case ISSPA : continue; case ISDIG : { - register i = 0; + register int i = 0; do { i = 10 * i + (ch - '0'); ch= input(); @@ -371,7 +350,7 @@ scanner() { } w++; } - error(linecount,"Illegal reserved word"); + error(linecount,"Illegal reserved word",NULL); } lextoken.t_string = ltext; return C_IDENT; @@ -382,11 +361,12 @@ scanner() { static int backupc; /* for unput() */ static int nonline; /* = 1 if last char read was a newline */ -input() { +int input(void) +{ /* * Low level input routine, used by all other input routines */ - register c; + register int c; if (c = backupc) { /* Last char was "unput()". Deliver it again @@ -413,15 +393,16 @@ input() { return c; } -unput(c) { +void unput(int c) +{ /* * "unread" c */ backupc = c; } -void -skipcomment(flag) { +void skipcomment(int flag) +{ /* * Skip comment. If flag != 0, the comment is inside a fragment * of C-code, so keep it. @@ -430,7 +411,7 @@ skipcomment(flag) { int saved; /* line count on which comment starts */ saved = linecount; - if (input() != '*') error(linecount,"Illegal comment"); + if (input() != '*') error(linecount,"Illegal comment",NULL); if (flag) putc('*', fact); do { ch = input(); @@ -441,12 +422,12 @@ skipcomment(flag) { if (ch == '/') return; } } while (ch != EOF); - error(saved,"Comment does not terminate"); + error(saved,"Comment does not terminate", NULL); } # ifdef LINE_DIRECTIVE -STATIC -linedirective() { +STATIC void linedirective(void) +{ /* * Read a line directive */ @@ -463,7 +444,7 @@ linedirective() { ch = input(); } while (ch != '\n' && c_class[ch] != ISDIG); if (ch == '\n') { - error(linecount,s_error); + error(linecount,s_error, NULL); return; } i = 0; @@ -478,7 +459,7 @@ linedirective() { *c++ = ch = input(); } while (ch != '"' && ch != '\n'); if (ch == '\n') { - error(linecount,s_error); + error(linecount,s_error, NULL); return; } *--c = '\0'; @@ -494,8 +475,8 @@ linedirective() { } # endif -STATIC string -vallookup(s) { +STATIC string vallookup(int s) +{ /* * Look up the keyword that has token number s */ @@ -508,8 +489,8 @@ vallookup(s) { return 0; } -STATIC string -cpy(s,p,inserted) register string p; { +STATIC string cpy(int s,register string p,int inserted) +{ /* * Create a piece of error message for token s and put it at p. * inserted = 0 if the token s was deleted (in which case we have @@ -579,7 +560,9 @@ cpy(s,p,inserted) register string p; { return p; } -LLmessage(d) { + +void LLmessage(int d) +{ /* * d is either 0, in which case the current token has been deleted, * or non-zero, in which case it represents a token that is inserted diff --git a/util/LLgen/src/tokens.g b/util/LLgen/src/tokens.g index 79ee579da..3f8eb29b5 100644 --- a/util/LLgen/src/tokens.g +++ b/util/LLgen/src/tokens.g @@ -19,7 +19,7 @@ { #include -# include "types.h" +#include "types.h" # include "io.h" # include "extern.h" # include "assert.h" @@ -30,17 +30,17 @@ static string rcsidc = "$Id$"; # endif /* Here are defined : */ -extern int scanner(); -extern LLmessage(); -extern int input(); -extern unput(); -extern void skipcomment(); +int scanner(void); +void LLmessage(int d); +int input(void); +void unput(int c); +void skipcomment(int flag); # ifdef LINE_DIRECTIVE -STATIC linedirective(); +STATIC void linedirective(void); # endif -STATIC string cpy(); -STATIC string vallookup(); -STATIC void copyact(); +STATIC string cpy(int s,register string p,int inserted); +STATIC string vallookup(int s); +STATIC void copyact(char ch1,char ch2,int flag,int level); static int nparams; } @@ -115,8 +115,8 @@ static t_token savedtok; /* to save lextoken in case of an insertion */ static int nostartline; /* = 0 if at the start of a line */ # endif -STATIC void -copyact(ch1,ch2,flag,level) char ch1,ch2; { +STATIC void copyact(char ch1,char ch2,int flag,int level) +{ /* * Copy an action to file f. Opening bracket is ch1, closing bracket * is ch2. @@ -125,8 +125,8 @@ copyact(ch1,ch2,flag,level) char ch1,ch2; { */ static int text_seen = 0; register FILE *f; - register ch; /* Current char */ - register match; /* used to read strings */ + register int ch; /* Current char */ + register int match; /* used to read strings */ int saved = linecount; /* save linecount */ int sav_strip = strip_grammar; @@ -157,7 +157,7 @@ copyact(ch1,ch2,flag,level) char ch1,ch2; { case ')': case '}': case ']': - error(linecount,"Parentheses mismatch"); + error(linecount,"Parentheses mismatch", NULL); break; case '(': text_seen = 1; @@ -188,7 +188,7 @@ copyact(ch1,ch2,flag,level) char ch1,ch2; { text_seen = 0; nparams++; if (ch == ',' && (flag & 2)) { - warning(linecount, "Parameters may not be separated with a ','"); + warning(linecount, "Parameters may not be separated with a ','",NULL); ch = ';'; } } @@ -209,7 +209,7 @@ copyact(ch1,ch2,flag,level) char ch1,ch2; { ch = input(); } if (ch == '\n') { - error(linecount,"Newline in string"); + error(linecount,"Newline in string", NULL); unput(match); } putc(ch,f); @@ -217,7 +217,7 @@ copyact(ch1,ch2,flag,level) char ch1,ch2; { if (ch == match) break; /* Fall through */ case EOF : - if (!level) error(saved,"Action does not terminate"); + if (!level) error(saved,"Action does not terminate", NULL); strip_grammar = sav_strip; return; default: @@ -227,7 +227,8 @@ copyact(ch1,ch2,flag,level) char ch1,ch2; { } } -scanner() { +int scanner(void) +{ /* * Lexical analyser, what else */ @@ -277,7 +278,7 @@ scanner() { for (;;) { ch = input(); if (ch == '\n' || ch == EOF) { - error(linecount,"Missing '"); + error(linecount,"Missing '", NULL); break; } if (ch == '\'') break; @@ -297,7 +298,7 @@ scanner() { case ISSPA : continue; case ISDIG : { - register i = 0; + register int i = 0; do { i = 10 * i + (ch - '0'); ch= input(); @@ -341,7 +342,7 @@ scanner() { } w++; } - error(linecount,"Illegal reserved word"); + error(linecount,"Illegal reserved word",NULL); } lextoken.t_string = ltext; return C_IDENT; @@ -352,11 +353,12 @@ scanner() { static int backupc; /* for unput() */ static int nonline; /* = 1 if last char read was a newline */ -input() { +int input(void) +{ /* * Low level input routine, used by all other input routines */ - register c; + register int c; if (c = backupc) { /* Last char was "unput()". Deliver it again @@ -383,15 +385,16 @@ input() { return c; } -unput(c) { +void unput(int c) +{ /* * "unread" c */ backupc = c; } -void -skipcomment(flag) { +void skipcomment(int flag) +{ /* * Skip comment. If flag != 0, the comment is inside a fragment * of C-code, so keep it. @@ -400,7 +403,7 @@ skipcomment(flag) { int saved; /* line count on which comment starts */ saved = linecount; - if (input() != '*') error(linecount,"Illegal comment"); + if (input() != '*') error(linecount,"Illegal comment",NULL); if (flag) putc('*', fact); do { ch = input(); @@ -411,12 +414,12 @@ skipcomment(flag) { if (ch == '/') return; } } while (ch != EOF); - error(saved,"Comment does not terminate"); + error(saved,"Comment does not terminate", NULL); } # ifdef LINE_DIRECTIVE -STATIC -linedirective() { +STATIC void linedirective(void) +{ /* * Read a line directive */ @@ -433,7 +436,7 @@ linedirective() { ch = input(); } while (ch != '\n' && c_class[ch] != ISDIG); if (ch == '\n') { - error(linecount,s_error); + error(linecount,s_error, NULL); return; } i = 0; @@ -448,7 +451,7 @@ linedirective() { *c++ = ch = input(); } while (ch != '"' && ch != '\n'); if (ch == '\n') { - error(linecount,s_error); + error(linecount,s_error, NULL); return; } *--c = '\0'; @@ -464,8 +467,8 @@ linedirective() { } # endif -STATIC string -vallookup(s) { +STATIC string vallookup(int s) +{ /* * Look up the keyword that has token number s */ @@ -478,8 +481,8 @@ vallookup(s) { return 0; } -STATIC string -cpy(s,p,inserted) register string p; { +STATIC string cpy(int s,register string p,int inserted) +{ /* * Create a piece of error message for token s and put it at p. * inserted = 0 if the token s was deleted (in which case we have @@ -549,7 +552,9 @@ cpy(s,p,inserted) register string p; { return p; } -LLmessage(d) { + +void LLmessage(int d) +{ /* * d is either 0, in which case the current token has been deleted, * or non-zero, in which case it represents a token that is inserted diff --git a/util/LLgen/src/types.h b/util/LLgen/src/types.h index da18696f6..0de5397b8 100644 --- a/util/LLgen/src/types.h +++ b/util/LLgen/src/types.h @@ -2,6 +2,8 @@ * For full copyright and restrictions on use see the file COPYING in the top * level of the LLgen tree. */ +#ifndef TYPES_H_ +#define TYPES_H_ /* * L L G E N @@ -270,3 +272,5 @@ typedef struct info_alloc { # else /* not NDEBUG */ # define STATIC extern # endif /* not NDEBUG */ + +#endif /* TYPES_H_ */ diff --git a/util/cmisc/prid.c b/util/cmisc/prid.c index 79818bb27..66aabd584 100644 --- a/util/cmisc/prid.c +++ b/util/cmisc/prid.c @@ -15,6 +15,7 @@ #include #include +#include extern char *ProgName; @@ -24,10 +25,21 @@ extern char *ProgName; int maxlen = DEF_LENGTH; -BeginOfProgram() {} -DoOption(str) - char *str; +void InsertId(char *); +char *Malloc(unsigned int); +char *Salloc(char *); +int EnHash(char*); +void EndOfProgram(void); +void DoOption(char*); +void CheckId(char *, int); + + + + +void BeginOfProgram(void) {} + +void DoOption(char* str) { switch (str[1]) { @@ -45,8 +57,7 @@ DoOption(str) } } -CheckId(id, len) - char *id; +void CheckId(char *id, int len) { if (len >= maxlen) { InsertId(id); @@ -62,10 +73,7 @@ struct idf { struct idf *hash_tab[HASHSIZE]; -char *Malloc(), *Salloc(); - -InsertId(id) - char *id; +void InsertId(char *id) { int hash_val = EnHash(id); register struct idf *idp = hash_tab[hash_val]; @@ -85,11 +93,9 @@ InsertId(id) } } -char * -Malloc(n) - unsigned n; +char *Malloc(unsigned int n) { - char *mem, *malloc(); + char *mem; if ((mem = malloc(n)) == 0) { fprintf(stderr, "%s: out of memory\n", ProgName); @@ -98,21 +104,19 @@ Malloc(n) return mem; } -char * -Salloc(str) - char *str; +char *Salloc(char *str) { + if (str == 0) str = ""; return strcpy(Malloc((unsigned)strlen(str) + 1), str); } -EnHash(id) - char *id; +int EnHash(char *id) { register unsigned hash_val = 0; - register n = maxlen; + register int n = maxlen; while (n-- && *id) hash_val = 31 * hash_val + *id++; @@ -120,7 +124,7 @@ EnHash(id) return hash_val % (unsigned) HASHSIZE; } -EndOfProgram() +void EndOfProgram(void) { register struct idf *idp; register int i; diff --git a/util/make/README b/util/make/README index 2c8d12f1b..240615627 100644 --- a/util/make/README +++ b/util/make/README @@ -1,42 +1,45 @@ -Following is a repost of the public domain 'make' that I posted -to net.sources a couple of months ago. I have fixed a few bugs, and -added some more features, and the resulting changes amounted to -about as much text as the whole program (hence the repost). - -For those that missed the net.sources posting, this is a public domain -re-implementation of the UNIX make program. There is no manual included; -for documentation, refer to a UNIX manual, or the source. - -Here is a list of the changes made: - -i) If '-' (ignore) or '@' (silent) where used at the start - of a command, their effect was not turned off for the following - commands. -ii) A special target (.SUFFIXES, .PRECIOUS) or a rule (.c.o, .a.o), - if first in the file would be taken as the default target. - This resulted in error messages like "Don't know how to - make .c", because things like .SUFFIXES were being made. - This was further complicated by --- -iii) Special target lines with no dependents (ie. .SUFFIXES:\n) - were not clearing out the existing dependents like - they should. -iv) Default rules could not be redefined because of the error - checking for commands being defined twice. Now you are - allowed to define a target beinging with '.', having - no dependents with commands. -v) The -q option didn't do the time comparison correctly, - or clear the variable used to keep track of this. Thus - it didn't work very well. -vi) The syntax ${..} for macro's supported by UNIX make was - not supported. -vii) There wuz a couple of spelling errors. -viii) When make checked for implicit rules on targets without - a suffix, there were problems. (Note: The ~ feature of - UNIX make wasn't and still isn't supported) -ix) The -n option did not print @ lines like it was supposed to. -x) :: added. (See UNIX manual) -xi) $? added. (see UNIX manual) - -Hacked further by Ceriel Jacobs to make it work better. Use this "make" to -install ACK under Microsoft Xenix V3.2. Some of the makefiles are just too -big for the Xenix "make". Strange, they work on a PDP-11 ... +Following is a repost of the public domain 'make' that I posted +to net.sources a couple of months ago. I have fixed a few bugs, and +added some more features, and the resulting changes amounted to +about as much text as the whole program (hence the repost). + +For those that missed the net.sources posting, this is a public domain +re-implementation of the UNIX make program. There is no manual included; +for documentation, refer to a UNIX manual, or the source. + +Here is a list of the changes made: + +i) If '-' (ignore) or '@' (silent) where used at the start + of a command, their effect was not turned off for the following + commands. +ii) A special target (.SUFFIXES, .PRECIOUS) or a rule (.c.o, .a.o), + if first in the file would be taken as the default target. + This resulted in error messages like "Don't know how to + make .c", because things like .SUFFIXES were being made. + This was further complicated by --- +iii) Special target lines with no dependents (ie. .SUFFIXES:\n) + were not clearing out the existing dependents like + they should. +iv) Default rules could not be redefined because of the error + checking for commands being defined twice. Now you are + allowed to define a target beinging with '.', having + no dependents with commands. +v) The -q option didn't do the time comparison correctly, + or clear the variable used to keep track of this. Thus + it didn't work very well. +vi) The syntax ${..} for macro's supported by UNIX make was + not supported. +vii) There wuz a couple of spelling errors. +viii) When make checked for implicit rules on targets without + a suffix, there were problems. (Note: The ~ feature of + UNIX make wasn't and still isn't supported) +ix) The -n option did not print @ lines like it was supposed to. +x) :: added. (See UNIX manual) +xi) $? added. (see UNIX manual) + +Hacked further by Ceriel Jacobs to make it work better. Use this "make" to +install ACK under Microsoft Xenix V3.2. Some of the makefiles are just too +big for the Xenix "make". Strange, they work on a PDP-11 ... + +Made it almost ISO C90 and POSIX portable by Carl Eric Codere, and +also made it safer by using correct datatypes on some library calls. diff --git a/util/make/check.c b/util/make/check.c index 2951c4096..c588e624f 100644 --- a/util/make/check.c +++ b/util/make/check.c @@ -7,64 +7,13 @@ #include #include "h.h" - -/* - * Prints out the structures as defined in memory. Good for check - * that you make file does what you want (and for debugging make). - */ -void -prt() -{ - register struct name * np; - register struct depend * dp; - register struct line * lp; - register struct cmd * cp; - register struct macro * mp; - - - for (mp = macrohead; mp; mp = mp->m_next) - fprintf(stderr, "%s = %s\n", mp->m_name, mp->m_val); - - fputc('\n', stderr); - - for (np = namehead.n_next; np; np = np->n_next) - { - if (np->n_flag & N_DOUBLE) - fprintf(stderr, "%s::\n", np->n_name); - else - fprintf(stderr, "%s:\n", np->n_name); - if (np == firstname) - fprintf(stderr, "(MAIN NAME)\n"); - for (lp = np->n_line; lp; lp = lp->l_next) - { - fputc(':', stderr); - for (dp = lp->l_dep; dp; dp = dp->d_next) - fprintf(stderr, " %s", dp->d_name->n_name); - fputc('\n', stderr); - - for (cp = lp->l_cmd; cp; cp = cp->c_next) -#ifdef os9 - fprintf(stderr, "- %s\n", cp->c_cmd); -#else - fprintf(stderr, "-\t%s\n", cp->c_cmd); -#endif - fputc('\n', stderr); - } - fputc('\n', stderr); - } -} - - /* * Recursive routine that does the actual checking. */ -void -check(np) -struct name * np; +static void check(struct name *np) { - register struct depend * dp; - register struct line * lp; - + register struct depend * dp; + register struct line * lp; if (np->n_flag & N_MARK) fatal("Circular dependency from %s", np->n_name); @@ -75,10 +24,51 @@ struct name * np; for (dp = lp->l_dep; dp; dp = dp->d_next) check(dp->d_name); - np->n_flag &= ~N_MARK; + np->n_flag &= (uchar)~N_MARK; } +/* + * Prints out the structures as defined in memory. Good for check + * that you make file does what you want (and for debugging make). + */ +void prt(void) +{ + register struct name * np; + register struct depend * dp; + register struct line * lp; + register struct cmd * cp; + register struct macro * mp; + + for (mp = macrohead; mp; mp = mp->m_next) + fprintf(stderr, "%s = %s\n", mp->m_name, mp->m_val); + + fputc('\n', stderr); + + for (np = namehead.n_next; np; np = np->n_next) + { + if (np->n_flag & N_DOUBLE) + fprintf(stderr, "%s::\n", np->n_name); + else + fprintf(stderr, "%s:\n", np->n_name); + if (np == firstname) + fprintf(stderr, "(MAIN NAME)\n"); + for (lp = np->n_line; lp; lp = lp->l_next) + { + fputc(':', stderr); + for (dp = lp->l_dep; dp; dp = dp->d_next) + fprintf(stderr, " %s", dp->d_name->n_name); + fputc('\n', stderr); + + for (cp = lp->l_cmd; cp; cp = cp->c_next) + fprintf(stderr, "-\t%s\n", cp->c_cmd); + fputc('\n', stderr); + } + fputc('\n', stderr); + } + } + + /* * Look for circular dependancies. * ie. @@ -86,27 +76,22 @@ struct name * np; * b: a * is a circular dep */ -void -circh() +void circh(void) { - register struct name * np; - + register struct name * np; for (np = namehead.n_next; np; np = np->n_next) check(np); } - /* * Check the target .PRECIOUS, and mark its dependentd as precious */ -void -precious() +void precious(void) { - register struct depend * dp; - register struct line * lp; - register struct name * np; - + register struct depend * dp; + register struct line * lp; + register struct name * np; if (!((np = newname(".PRECIOUS"))->n_flag & N_TARG)) return; diff --git a/util/make/h.h b/util/make/h.h index 1dcab8998..c83f5b2a9 100644 --- a/util/make/h.h +++ b/util/make/h.h @@ -1,145 +1,127 @@ /* - * Include header for make + * Include header for make * - * $Header$ + * $Header$ */ #ifndef uchar -#ifdef os9 -#define uchar char -#define void int -#define fputc putc -#else -#define uchar unsigned char -#endif +#define uchar unsigned char #endif -#define bool int -#define time_t long -#define TRUE (1) -#define FALSE (0) -#define max(a,b) ((a)>(b)?(a):(b)) +#include -#define DEFN1 "makefile" /* Default names */ -#ifdef unix -#define DEFN2 "Makefile" -#endif -#ifdef eon -#define DEFN2 "Makefile" -#endif -/* os9 is case insensitive */ +#define bool int +#define TRUE (1) +#define FALSE (0) -#define LZ (2048) /* Line size */ +#define DEFN1 "makefile" /* Default names */ +#define DEFN2 "Makefile" + +#define LZ (2048) /* Line size */ /* - * A name. This represents a file, either to be made, or existant + * A name. This represents a file, either to be made, or existant */ struct name { - struct name * n_next; /* Next in the list of names */ - char * n_name; /* Called */ - struct line * n_line; /* Dependencies */ - time_t n_time; /* Modify time of this name */ - uchar n_flag; /* Info about the name */ + struct name * n_next; /* Next in the list of names */ + char * n_name; /* Called */ + struct line * n_line; /* Dependencies */ + time_t n_time; /* Modify time of this name */ + uchar n_flag; /* Info about the name */ }; -#define N_MARK 0x01 /* For cycle check */ -#define N_DONE 0x02 /* Name looked at */ -#define N_TARG 0x04 /* Name is a target */ -#define N_PREC 0x08 /* Target is precious */ -#define N_DOUBLE 0x10 /* Double colon target */ +#define N_MARK 0x01 /* For cycle check */ +#define N_DONE 0x02 /* Name looked at */ +#define N_TARG 0x04 /* Name is a target */ +#define N_PREC 0x08 /* Target is precious */ +#define N_DOUBLE 0x10 /* Double colon target */ /* - * Definition of a target line. + * Definition of a target line. */ -struct line +struct line { - struct line * l_next; /* Next line (for ::) */ - struct depend * l_dep; /* Dependents for this line */ - struct cmd * l_cmd; /* Commands for this line */ + struct line * l_next; /* Next line (for ::) */ + struct depend * l_dep; /* Dependents for this line */ + struct cmd * l_cmd; /* Commands for this line */ }; /* - * List of dependents for a line + * List of dependents for a line */ -struct depend +struct depend { - struct depend * d_next; /* Next dependent */ - struct name * d_name; /* Name of dependent */ + struct depend * d_next; /* Next dependent */ + struct name * d_name; /* Name of dependent */ }; /* - * Commands for a line + * Commands for a line */ -struct cmd +struct cmd { - struct cmd * c_next; /* Next command line */ - char * c_cmd; /* Command line */ + struct cmd * c_next; /* Next command line */ + char * c_cmd; /* Command line */ }; /* - * Macro storage + * Macro storage */ -struct macro +struct macro { - struct macro * m_next; /* Next variable */ - char * m_name; /* Called ... */ - char * m_val; /* Its value */ - uchar m_flag; /* Infinite loop check */ - uchar m_prio; /* 5 levels: - - 0 for internal ($(CC), etc) - - 1 (reserved for environment) - - 2 for makefile - - 3 for command line - - 4 for special ($*,$<, etc) - */ + struct macro * m_next; /* Next variable */ + char * m_name; /* Called ... */ + char * m_val; /* Its value */ + uchar m_flag; /* Infinite loop check */ + uchar m_prio; /* 5 levels: + - 0 for internal ($(CC), etc) + - 1 (reserved for environment) + - 2 for makefile + - 3 for command line + - 4 for special ($*,$<, etc) + */ }; -extern char * myname; -extern struct name namehead; -extern struct macro * macrohead; -extern struct name * firstname; -extern bool silent; -extern bool ignore; -extern bool rules; -extern bool dotouch; -extern bool quest; -extern bool domake; -extern char str1[]; -extern char str2[]; -extern int lineno; +extern char * myname; +extern struct name namehead; +extern struct macro * macrohead; +extern struct name * firstname; +extern bool silent; +extern bool ignore; +extern bool rules; +extern bool dotouch; +extern bool quest; +extern bool domake; +extern char str1[]; +extern char str2[]; +extern int lineno; -char * fgets(); -char * index(); -char * rindex(); -char * malloc(); -char * strcpy(); -char * strcat(); -extern int errno; - -void circh(); -char * getmacro(); -struct macro * setmacro(); -void input(); -void error(); -void expand(); -void fatal(); -int make(); -void modtime(); -struct name * newname(); -struct depend * newdep(); -struct cmd * newcmd(); -void newline(); -void prt(); -char * suffix(); -void touch(); -void makerules(); -char * gettok(); -void precious(); +void circh(void); +char * getmacro(char* name); +struct macro * setmacro(char* name, char* val, int prio); +void input(FILE *fd); +void error(char *msg, char* a1); +void expand(char *str); +void fatal(char* msg, char* value); +bool dyndep(struct name *np); +int make(struct name *np, int level); +void modtime(struct name *np); +struct name *newname(char *name); +struct depend *newdep(struct name *np, struct depend *dp); +struct cmd *newcmd(char *str, struct cmd *cp); +void newline(struct name *np, struct depend *dp, struct cmd *cp, int flag); +void prt(void); +char *suffix(char *name); +void touch(struct name *np); +void makerules(void); +char *gettok(char **ptr); +void precious(void); +bool mgetline(char* str, FILE* fd); diff --git a/util/make/input.c b/util/make/input.c index 3e4b88e51..613c33bad 100644 --- a/util/make/input.c +++ b/util/make/input.c @@ -1,80 +1,67 @@ /* - * Parse a makefile + * Parse a makefile * - * $Header$ + * $Header$ */ - #include -#include +#include +#include +#include #include "h.h" +struct name namehead; +struct name * firstname; -struct name namehead; -struct name * firstname; - -char str1[LZ]; /* General store */ -char str2[LZ]; - +char str1[LZ]; /* General store */ +char str2[LZ]; /* - * Intern a name. Return a pointer to the name struct + * Intern a name. Return a pointer to the name struct */ -struct name * -newname(name) -char * name; +struct name *newname(char *name) { - register struct name * rp; - register struct name * rrp; - register char * cp; + register struct name * rp; + register struct name * rrp; + register char * cp; - for - ( - rp = namehead.n_next, rrp = &namehead; - rp; - rp = rp->n_next, rrp = rrp->n_next - ) + for (rp = namehead.n_next, rrp = &namehead; rp; + rp = rp->n_next, rrp = rrp->n_next) if (strcmp(name, rp->n_name) == 0) return rp; - if ((rp = (struct name *)malloc(sizeof (struct name))) - == (struct name *)0) - fatal("No memory for name"); + if ((rp = (struct name *) malloc(sizeof(struct name))) == (struct name *) 0) + fatal("No memory for name",NULL); rrp->n_next = rp; - rp->n_next = (struct name *)0; - if ((cp = malloc((unsigned)(strlen(name)+1))) == (char *)0) - fatal("No memory for name"); + rp->n_next = (struct name *) 0; + if ((cp = malloc((unsigned) (strlen(name) + 1))) == (char *) 0) + fatal("No memory for name",NULL); strcpy(cp, name); rp->n_name = cp; - rp->n_line = (struct line *)0; - rp->n_time = (time_t)0; + rp->n_line = (struct line *) 0; + rp->n_time = (time_t) 0; rp->n_flag = 0; return rp; } - /* - * Add a dependant to the end of the supplied list of dependants. - * Return the new head pointer for that list. + * Add a dependant to the end of the supplied list of dependants. + * Return the new head pointer for that list. */ -struct depend * -newdep(np, dp) -struct name * np; -struct depend * dp; +struct depend *newdep(struct name *np, struct depend *dp) { - register struct depend * rp; - register struct depend * rrp; + register struct depend * rp; + register struct depend * rrp; - - if ((rp = (struct depend *)malloc(sizeof (struct depend))) - == (struct depend *)0) - fatal("No memory for dependant"); - rp->d_next = (struct depend *)0; + if ((rp = (struct depend *) malloc(sizeof(struct depend))) + == (struct depend *) 0) + fatal("No memory for dependant",NULL); + rp->d_next = (struct depend *) 0; rp->d_name = np; - if (dp == (struct depend *)0) + if (dp == (struct depend *) 0) return rp; for (rrp = dp; rrp->d_next; rrp = rrp->d_next) @@ -85,40 +72,34 @@ struct depend * dp; return dp; } - /* - * Add a command to the end of the supplied list of commands. - * Return the new head pointer for that list. + * Add a command to the end of the supplied list of commands. + * Return the new head pointer for that list. */ -struct cmd * -newcmd(str, cp) -char * str; -struct cmd * cp; +struct cmd *newcmd(char *str, struct cmd *cp) { - register struct cmd * rp; - register struct cmd * rrp; - register char * rcp; + register struct cmd * rp; + register struct cmd * rrp; + register char * rcp; - - if (rcp = rindex(str, '\n')) - *rcp = '\0'; /* Loose newline */ + if ((rcp = strrchr(str, '\n'))) + *rcp = '\0'; /* Loose newline */ while (isspace(*str)) str++; - if (*str == '\0') /* If nothing left, the exit */ + if (*str == '\0') /* If nothing left, the exit */ return 0; - if ((rp = (struct cmd *)malloc(sizeof (struct cmd))) - == (struct cmd *)0) - fatal("No memory for command"); - rp->c_next = (struct cmd *)0; - if ((rcp = malloc((unsigned)(strlen(str)+1))) == (char *)0) - fatal("No memory for command"); + if ((rp = (struct cmd *) malloc(sizeof(struct cmd))) == (struct cmd *) 0) + fatal("No memory for command",NULL); + rp->c_next = (struct cmd *) 0; + if ((rcp = malloc((unsigned) (strlen(str) + 1))) == (char *) 0) + fatal("No memory for command",NULL); strcpy(rcp, str); rp->c_cmd = rcp; - if (cp == (struct cmd *)0) + if (cp == (struct cmd *) 0) return rp; for (rrp = cp; rrp->c_next; rrp = rrp->c_next) @@ -129,58 +110,48 @@ struct cmd * cp; return cp; } - /* - * Add a new 'line' of stuff to a target. This check to see - * if commands already exist for the target. If flag is set, - * the line is a double colon target. + * Add a new 'line' of stuff to a target. This check to see + * if commands already exist for the target. If flag is set, + * the line is a double colon target. * - * Kludges: - * i) If the new name begins with a '.', and there are no dependents, - * then the target must cease to be a target. This is for .SUFFIXES. - * ii) If the new name begins with a '.', with no dependents and has - * commands, then replace the current commands. This is for - * redefining commands for a default rule. - * Neither of these free the space used by dependents or commands, - * since they could be used by another target. + * Kludges: + * i) If the new name begins with a '.', and there are no dependents, + * then the target must cease to be a target. This is for .SUFFIXES. + * ii) If the new name begins with a '.', with no dependents and has + * commands, then replace the current commands. This is for + * redefining commands for a default rule. + * Neither of these free the space used by dependents or commands, + * since they could be used by another target. */ -void -newline(np, dp, cp, flag) -struct name * np; -struct depend * dp; -struct cmd * cp; +void newline(struct name *np, struct depend *dp, struct cmd *cp, int flag) { - bool hascmds = FALSE; /* Target has commands */ - register struct line * rp; - register struct line * rrp; - + bool hascmds = FALSE; /* Target has commands */ + register struct line * rp; + register struct line * rrp; /* Handle the .SUFFIXES case */ - if (! strcmp(np->n_name, ".SUFFIXES") && !dp && !cp) + if (!strcmp(np->n_name, ".SUFFIXES") && !dp && !cp) { for (rp = np->n_line; rp; rp = rrp) { rrp = rp->l_next; - free((char *)rp); + free((char *) rp); } - np->n_line = (struct line *)0; - np->n_flag &= ~N_TARG; + np->n_line = (struct line *) 0; + np->n_flag &= (uchar)~N_TARG; return; } /* This loop must happen since rrp is used later. */ - for - ( - rp = np->n_line, rrp = (struct line *)0; - rp; - rrp = rp, rp = rp->l_next - ) + for (rp = np->n_line, rrp = (struct line *) 0; rp; + rrp = rp, rp = rp->l_next) if (rp->l_cmd) hascmds = TRUE; if (hascmds && cp && !(np->n_flag & N_DOUBLE)) /* Handle the implicit rules redefinition case */ - if (np->n_name[0] == '.' && dp == (struct depend *)0) + if (np->n_name[0] == '.' && dp == (struct depend *) 0) { np->n_line->l_cmd = cp; return; @@ -188,13 +159,12 @@ struct cmd * cp; else error("Commands defined twice for target %s", np->n_name); if (np->n_flag & N_TARG) - if (!(np->n_flag & N_DOUBLE) != !flag) /* like xor */ + if (!(np->n_flag & N_DOUBLE) != !flag) /* like xor */ error("Inconsistent rules for target %s", np->n_name); - if ((rp = (struct line *)malloc(sizeof (struct line))) - == (struct line *)0) - fatal("No memory for line"); - rp->l_next = (struct line *)0; + if ((rp = (struct line *) malloc(sizeof(struct line))) == (struct line *) 0) + fatal("No memory for line",NULL); + rp->l_next = (struct line *) 0; rp->l_dep = dp; rp->l_cmd = cp; @@ -208,68 +178,60 @@ struct cmd * cp; np->n_flag |= N_DOUBLE; } - /* - * Parse input from the makefile, and construct a tree structure - * of it. + * Parse input from the makefile, and construct a tree structure + * of it. */ -void -input(fd) -FILE * fd; +void input(FILE *fd) { - char * p; /* General */ - char * q; - struct name * np; - struct depend * dp; - struct cmd * cp; - bool dbl; + char * p; /* General */ + char * q; + struct name * np; + struct depend * dp; + struct cmd * cp; + bool dbl; - - if (getline(str1, fd)) /* Read the first line */ + if (mgetline(str1, fd)) /* Read the first line */ return; - for(;;) + for (;;) { -#ifdef os9 - if (*str1 == ' ') /* Rules without targets */ -#else - if (*str1 == '\t') /* Rules without targets */ -#endif - error("Rules not allowed here"); + if (*str1 == '\t') /* Rules without targets */ + error("Rules not allowed here", NULL ); p = str1; - while (isspace(*p)) /* Find first target */ + while (isspace(*p)) /* Find first target */ p++; - while (((q = index(p, '=')) != (char *)0) && - (p != q) && (q[-1] == '\\')) /* Find value */ + while (((q = strchr(p, '=')) != (char *) 0) && (p != q) + && (q[-1] == '\\')) /* Find value */ { - register char * a; + register char * a; - a = q - 1; /* Del \ chr; move rest back */ + a = q - 1; /* Del \ chr; move rest back */ p = q; - while(*a++ = *q++) + while ((*a++ = *q++)) ; } - if (q != (char *)0) + if (q != (char *) 0) { - register char * a; + register char * a; - *q++ = '\0'; /* Separate name and val */ + *q++ = '\0'; /* Separate name and val */ while (isspace(*q)) q++; - if (p = rindex(q, '\n')) + if ((p = strrchr(q, '\n'))) *p = '\0'; p = str1; - if ((a = gettok(&p)) == (char *)0) - error("No macro name"); + if ((a = gettok(&p)) == (char *) 0) + error("No macro name", NULL ); setmacro(a, q, 2); - if (getline(str1, fd)) + if (mgetline(str1, fd)) return; continue; } @@ -277,23 +239,23 @@ FILE * fd; expand(str1); p = str1; - while (((q = index(p, ':')) != (char *)0) && - (p != q) && (q[-1] == '\\')) /* Find dependents */ + while (((q = strchr(p, ':')) != (char *) 0) && (p != q) + && (q[-1] == '\\')) /* Find dependents */ { - register char * a; + register char * a; - a = q - 1; /* Del \ chr; move rest back */ + a = q - 1; /* Del \ chr; move rest back */ p = q; - while(*a++ = *q++) + while ((*a++ = *q++)) ; } - if (q == (char *)0) - error("No targets provided"); + if (q == (char *) 0) + error("No targets provided", NULL ); - *q++ = '\0'; /* Separate targets and dependents */ + *q++ = '\0'; /* Separate targets and dependents */ - if (*q == ':') /* Double colon */ + if (*q == ':') /* Double colon */ { dbl = 1; q++; @@ -301,40 +263,36 @@ FILE * fd; else dbl = 0; - for (dp = (struct depend *)0; ((p = gettok(&q)) != (char *)0);) - /* get list of dep's */ + for (dp = (struct depend *) 0; ((p = gettok(&q)) != (char *) 0);) + /* get list of dep's */ { - np = newname(p); /* Intern name */ - dp = newdep(np, dp); /* Add to dep list */ + np = newname(p); /* Intern name */ + dp = newdep(np, dp); /* Add to dep list */ } *((q = str1) + strlen(str1) + 1) = '\0'; - /* Need two nulls for gettok (Remember separation) */ + /* Need two nulls for gettok (Remember separation) */ - cp = (struct cmd *)0; - if (getline(str2, fd) == FALSE) /* Get commands */ + cp = (struct cmd *) 0; + if (mgetline(str2, fd) == FALSE) /* Get commands */ { -#ifdef os9 - while (*str2 == ' ') -#else while (*str2 == '\t') -#endif { cp = newcmd(&str2[0], cp); - if (getline(str2, fd)) + if (mgetline(str2, fd)) break; } } - while ((p = gettok(&q)) != (char *)0) /* Get list of targ's */ + while ((p = gettok(&q)) != (char *) 0) /* Get list of targ's */ { - np = newname(p); /* Intern name */ + np = newname(p); /* Intern name */ newline(np, dp, cp, dbl); if (!firstname && p[0] != '.') firstname = np; } - if (feof(fd)) /* EOF? */ + if (feof(fd)) /* EOF? */ return; strcpy(str1, str2); diff --git a/util/make/macro.c b/util/make/macro.c index 5c4b76de9..160996ed7 100644 --- a/util/make/macro.c +++ b/util/make/macro.c @@ -1,167 +1,156 @@ /* - * Macro control for make + * Macro control for make * - * $Header$ + * $Header$ */ +#include +#include +#include #include "h.h" -struct macro * macrohead; +struct macro * macrohead; -struct macro * -getmp(name) -char * name; +static struct macro *getmp(char *name) { - register struct macro * rp; + register struct macro * rp; - for (rp = macrohead; rp; rp = rp->m_next) - if (strcmp(name, rp->m_name) == 0) - return rp; - return (struct macro *)0; + for (rp = macrohead; rp; rp = rp->m_next) + if (strcmp(name, rp->m_name) == 0) + return rp; + return (struct macro *)0; } -char * -getmacro(name) -char * name; +char * getmacro(char* name) { - struct macro * mp; + struct macro * mp; - if (mp = getmp(name)) - return mp->m_val; - else - return ""; + if ((mp = getmp(name))) + return mp->m_val; + else + return ""; } -struct macro * -setmacro(name, val, prio) -char * name; -char * val; +struct macro * setmacro(char* name, char* val, int prio) { - register struct macro * rp; - register char * cp; + register struct macro * rp; + register char * cp; - /* Replace macro definition if it exists */ - for (rp = macrohead; rp; rp = rp->m_next) - if (strcmp(name, rp->m_name) == 0) - { - if (prio < rp->m_prio) - return rp; - free(rp->m_val); /* Free space from old */ - break; - } + /* Replace macro definition if it exists */ + for (rp = macrohead; rp; rp = rp->m_next) + if (strcmp(name, rp->m_name) == 0) + { + if (prio < rp->m_prio) + return rp; + free(rp->m_val); /* Free space from old */ + break; + } - if (!rp) /* If not defined, allocate space for new */ - { - if ((rp = (struct macro *)malloc(sizeof (struct macro))) - == (struct macro *)0) - fatal("No memory for macro"); + if (!rp) /* If not defined, allocate space for new */ + { + if ((rp = (struct macro *)malloc(sizeof (struct macro))) + == (struct macro *)0) + fatal("No memory for macro",NULL); - rp->m_next = macrohead; - macrohead = rp; - rp->m_flag = FALSE; + rp->m_next = macrohead; + macrohead = rp; + rp->m_flag = FALSE; - if ((cp = malloc((unsigned)(strlen(name)+1))) == (char *)0) - fatal("No memory for macro"); - strcpy(cp, name); - rp->m_name = cp; - } + if ((cp = malloc((unsigned)(strlen(name)+1))) == (char *)0) + fatal("No memory for macro",NULL); + strcpy(cp, name); + rp->m_name = cp; + } - if ((cp = malloc((unsigned)(strlen(val)+1))) == (char *)0) - fatal("No memory for macro"); - strcpy(cp, val); /* Copy in new value */ - rp->m_val = cp; - rp->m_prio = prio; + if ((cp = malloc((unsigned)(strlen(val)+1))) == (char *)0) + fatal("No memory for macro",NULL); + strcpy(cp, val); /* Copy in new value */ + rp->m_val = cp; + rp->m_prio = (uchar)prio; - return rp; + return rp; } -#define MBUFSIZ 128 +#define MBUFSIZ 128 /* - * Do the dirty work for expand + * Do the dirty work for expand */ -void -doexp(to, from, len, buf) -char ** to; -char * from; -int * len; -char * buf; +static void doexp(char **to, char* from, int* len, char* buf) { - register char * rp; - register char * p; - register char * q; - register struct macro * mp; + register char * rp; + register char * p; + register char * q; + register struct macro * mp; - rp = from; - p = *to; - while (*rp) - { - if (*rp != '$') - { - *p++ = *rp++; - (*len)--; - } - else - { - q = buf; - if (*++rp == '{') - while (*++rp && *rp != '}') { - if (q < &buf[MBUFSIZ-1]) *q++ = *rp; - } - else if (*rp == '(') - while (*++rp && *rp != ')') { - if (q < &buf[MBUFSIZ-1]) *q++ = *rp; - } - else if (!*rp) - { - *p++ = '$'; - break; - } - else - *q++ = *rp; - *q = '\0'; - if (*rp) - rp++; - if (!(mp = getmp(buf))) - mp = setmacro(buf, "", 2); - if (mp->m_flag) - fatal("Infinitely recursive macro %s", mp->m_name); - mp->m_flag = TRUE; - *to = p; - doexp(to, mp->m_val, len, buf); - p = *to; - mp->m_flag = FALSE; - } - if (*len <= 0) - error("Expanded line too line"); - } - *p = '\0'; - *to = p; + rp = from; + p = *to; + while (*rp) + { + if (*rp != '$') + { + *p++ = *rp++; + (*len)--; + } + else + { + q = buf; + if (*++rp == '{') + while (*++rp && *rp != '}') { + if (q < &buf[MBUFSIZ-1]) *q++ = *rp; + } + else if (*rp == '(') + while (*++rp && *rp != ')') { + if (q < &buf[MBUFSIZ-1]) *q++ = *rp; + } + else if (!*rp) + { + *p++ = '$'; + break; + } + else + *q++ = *rp; + *q = '\0'; + if (*rp) + rp++; + if (!(mp = getmp(buf))) + mp = setmacro(buf, "", 2); + if (mp->m_flag) + fatal("Infinitely recursive macro %s", mp->m_name); + mp->m_flag = TRUE; + *to = p; + doexp(to, mp->m_val, len, buf); + p = *to; + mp->m_flag = FALSE; + } + if (*len <= 0) + error("Expanded line too line", NULL); + } + *p = '\0'; + *to = p; } /* - * Expand any macros in str. + * Expand any macros in str. */ -void -expand(str) -char * str; +void expand(char *str) { - char *a; - static char b[MBUFSIZ]; /* temp storage for macroname */ - char * p = str; - int len = LZ-1; + char *a; + static char b[MBUFSIZ]; /* temp storage for macroname */ + char * p = str; + int len = LZ-1; - a = malloc((unsigned)(strlen(str)+1)); - if (!a) fatal("No memory for expand"); - strcpy(a, str); - doexp(&p, a, &len, b); - free(a); + a = malloc((unsigned)(strlen(str)+1)); + if (!a) fatal("No memory for expand",NULL); + strcpy(a, str); + doexp(&p, a, &len, b); + free(a); } diff --git a/util/make/main.c b/util/make/main.c index 68a31c481..a2ce602f7 100644 --- a/util/make/main.c +++ b/util/make/main.c @@ -1,261 +1,204 @@ /* - * make [-f makefile] [-ins] [target(s) ...] + * make [-f makefile] [-ins] [target(s) ...] * - * (Better than EON mk but not quite as good as UNIX make) + * (Better than EON mk but not quite as good as UNIX make) * - * -f makefile name - * -i ignore exit status - * -n Pretend to make - * -p Print all macros & targets - * -q Question up-to-dateness of target. Return exit status 1 if not - * -r Don't not use inbuilt rules - * -s Make silently - * -t Touch files instead of making them - * -m Change memory requirements (EON only) - * -k For the time being: accept but ignore + * -f makefile name + * -i ignore exit status + * -n Pretend to make + * -p Print all macros & targets + * -q Question up-to-dateness of target. Return exit status 1 if not + * -r Don't not use inbuilt rules + * -s Make silently + * -t Touch files instead of making them + * -m Change memory requirements (EON only) + * -k For the time being: accept but ignore * - * $Header$ + * $Header$ */ #include +#include +#include #include "h.h" -#ifdef unix -#include -#endif +char * myname; +char * makefile; /* The make file */ #ifdef eon -#include -#endif -#ifdef os9 -#include +unsigned memspace = MEMSPACE; #endif +FILE * ifd; /* Input file desciptor */ +bool domake = TRUE; /* Go through the motions option */ +bool ignore = FALSE; /* Ignore exit status option */ +bool silent = FALSE; /* Silent option */ +bool print = FALSE; /* Print debuging information */ +bool rules = TRUE; /* Use inbuilt rules */ +bool dotouch = FALSE;/* Touch files instead of making */ +bool quest = FALSE; /* Question up-to-dateness of file */ -#ifdef eon -#define MEMSPACE (16384) -#endif +static void usage(void); -char * myname; -char * makefile; /* The make file */ -#ifdef eon -unsigned memspace = MEMSPACE; -#endif - -FILE * ifd; /* Input file desciptor */ -bool domake = TRUE; /* Go through the motions option */ -bool ignore = FALSE; /* Ignore exit status option */ -bool silent = FALSE; /* Silent option */ -bool print = FALSE; /* Print debuging information */ -bool rules = TRUE; /* Use inbuilt rules */ -bool dotouch = FALSE;/* Touch files instead of making */ -bool quest = FALSE; /* Question up-to-dateness of file */ - - -void -main(argc, argv) -int argc; -char ** argv; +int main(int argc, char** argv) { - register char * p; /* For argument processing */ - int estat = 0; /* For question */ - register struct name * np; - int nargc = 0; - char **nargv; - int fflag = 0; + register char * p; /* For argument processing */ + int estat = 0; /* For question */ + register struct name * np; + int nargc = 0; + char **nargv; + int fflag = 0; - myname = (argc-- < 1) ? "make" : *argv++; - nargv = argv; + myname = (argc-- < 1) ? "make" : *argv++; + nargv = argv; - while (argc > 0) - { - argc--; /* One less to process */ - p = *argv++; /* Now processing this one */ + while (argc > 0) + { + argc--; /* One less to process */ + p = *argv++; /* Now processing this one */ - if (*p == '-') while (*++p != '\0') - { - switch(*p) - { - case 'f': /* Alternate file name */ - fflag = 1; - break; -#ifdef eon - case 'm': /* Change space requirements */ - if (*++p == '\0') - { - if (argc-- <= 0) - usage(); - p = *argv++; - } - memspace = atoi(p); - goto end_of_args; -#endif - case 'n': /* Pretend mode */ - domake = FALSE; - break; - case 'i': /* Ignore fault mode */ - ignore = TRUE; - break; - case 's': /* Silent about commands */ - silent = TRUE; - break; - case 'p': - print = TRUE; - break; - case 'r': - rules = FALSE; - break; - case 't': - dotouch = TRUE; - break; - case 'q': - quest = TRUE; - break; - case 'k': - break; - default: /* Wrong option */ - usage(); - } - } - else { - if (fflag) { - if (argc <= 0) usage(); - makefile = p; - fflag = 0; - } - else { - nargc++; - *nargv++ = p; - } - } - end_of_args:; - } - argv = nargv - nargc; - argc = nargc; + if (*p == '-') while (*++p != '\0') + { + switch(*p) + { + case 'f': /* Alternate file name */ + fflag = 1; + break; + case 'n': /* Pretend mode */ + domake = FALSE; + break; + case 'i': /* Ignore fault mode */ + ignore = TRUE; + break; + case 's': /* Silent about commands */ + silent = TRUE; + break; + case 'p': + print = TRUE; + break; + case 'r': + rules = FALSE; + break; + case 't': + dotouch = TRUE; + break; + case 'q': + quest = TRUE; + break; + case 'k': + break; + default: /* Wrong option */ + usage(); + } + } + else { + if (fflag) { + if (argc <= 0) usage(); + makefile = p; + fflag = 0; + } + else { + nargc++; + *nargv++ = p; + } + } + end_of_args:; + } + argv = nargv - nargc; + argc = nargc; -#ifdef eon - if (initalloc(memspace) == 0xffff) /* Must get memory for alloc */ - fatal("Cannot initalloc memory"); -#endif - if (makefile && strcmp(makefile, "-") == 0) /* Can use stdin as makefile */ - ifd = stdin; - else - if (!makefile) /* If no file, then use default */ - { - if ((ifd = fopen(DEFN1, "r")) == (FILE *)0) -#ifdef eon - if (errno != ER_NOTF) - fatal("Can't open %s; error %02x", DEFN1, errno); -#endif -#ifdef unix - if (errno != ENOENT) - fatal("Can't open %s; error %02x", DEFN1, errno); -#endif -#ifndef os9 - if ((ifd == (FILE *)0) - && ((ifd = fopen(DEFN2, "r")) == (FILE *)0)) - fatal("Can't open %s", DEFN2); -#else - fatal("Can't open %s", DEFN1); -#endif - } - else - if ((ifd = fopen(makefile, "r")) == (FILE *)0) - fatal("Can't open %s", makefile); + if (makefile && strcmp(makefile, "-") == 0) /* Can use stdin as makefile */ + ifd = stdin; + else + if (!makefile) /* If no file, then use default */ + { + if ((ifd = fopen(DEFN1, "r")) == NULL) + if ((ifd == NULL) + && ((ifd = fopen(DEFN2, "r")) == NULL)) + fatal("Can't open %s", DEFN2); + } + else + if ((ifd = fopen(makefile, "r")) == NULL) + fatal("Can't open %s", makefile); - makerules(); + makerules(); - setmacro("$", "$", 4); + setmacro("$", "$", 4); - while (argc && (p = index(*argv, '='))) - { - char c; + while (argc && (p = strchr(*argv, '='))) + { + char c; - c = *p; - *p = '\0'; - setmacro(*argv, p+1, 3); - *p = c; + c = *p; + *p = '\0'; + setmacro(*argv, p+1, 3); + *p = c; - argv++; - argc--; - } + argv++; + argc--; + } - input(ifd); /* Input all the gunga */ - fclose(ifd); /* Finished with makefile */ - lineno = 0; /* Any calls to error now print no line number */ + input(ifd); /* Input all the gunga */ + fclose(ifd); /* Finished with makefile */ + lineno = 0; /* Any calls to error now print no line number */ - if (print) - prt(); /* Print out structures */ + if (print) + prt(); /* Print out structures */ - np = newname(".SILENT"); - if (np->n_flag & N_TARG) - silent = TRUE; + np = newname(".SILENT"); + if (np->n_flag & N_TARG) + silent = TRUE; - np = newname(".IGNORE"); - if (np->n_flag & N_TARG) - ignore = TRUE; + np = newname(".IGNORE"); + if (np->n_flag & N_TARG) + ignore = TRUE; - precious(); + precious(); - if (!firstname) - fatal("No targets defined"); + if (!firstname) + fatal("No targets defined",NULL); - circh(); /* Check circles in target definitions */ + circh(); /* Check circles in target definitions */ - if (!argc) - estat = make(firstname, 0); - else while (argc--) - { - if (!print && !silent && strcmp(*argv, "love") == 0) - printf("Not war!\n"); - estat |= make(newname(*argv++), 0); - } + if (!argc) + estat = make(firstname, 0); + else while (argc--) + { + if (!print && !silent && strcmp(*argv, "love") == 0) + printf("Not war!\n"); + estat |= make(newname(*argv++), 0); + } - if (quest) - exit(estat); - else - exit(0); + if (quest) + exit(estat); + else + exit(0); + return 0; } -usage() +static void usage(void) { - fprintf(stderr, "Usage: %s [-f makefile] [-inpqrst] [macro=val ...] [target(s) ...]\n", myname); - exit(1); + fprintf(stderr, "Usage: %s [-f makefile] [-inpqrst] [macro=val ...] [target(s) ...]\n", myname); + exit(1); } /*VARARGS1*/ -void -fatal(msg, a1, a2, a3, a4, a5, a6) -char *msg; +void fatal(char *msg, char* value) { - fprintf(stderr, "%s: ", myname); - fprintf(stderr, msg, a1, a2, a3, a4, a5, a6); - fputc('\n', stderr); - exit(1); + if (value != NULL) + { + fprintf(stderr, "%s: ", myname); + fprintf(stderr, msg, value); + } else + { + fprintf(stderr, "%s: ", myname); + fprintf(stderr, msg); + } + fputc('\n', stderr); + exit(1); } -char * -index(s, c) - register char *s, c; -{ - while (*s) - if (*s++ == c) - return --s; - return (char *)0; -} - -char * -rindex(str, chr) - register char *str, chr; -{ - register char *retptr = 0; - - while (*str) - if (*str++ == chr) - retptr = &str[-1]; - return retptr; -} diff --git a/util/make/make.c b/util/make/make.c index c28520b15..f41901cf8 100644 --- a/util/make/make.c +++ b/util/make/make.c @@ -1,482 +1,308 @@ /* - * Do the actual making for make + * Do the actual making for make * - * $Header$ + * $Header$ */ #include -#ifdef unix +#include +#include +#include #include #include #include +/* UNIX specific */ +#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) +#ifndef unix +#define unix #endif -#ifdef eon -#include -#include #endif -#ifdef os9 -#include -#include -#include -#include -#include + +#if defined(__MINGW32__) || defined(__MINGW64__) +#ifndef unix +#define unix +#endif +#endif + + + +#ifdef unix +#include +#include #endif #include "h.h" +void docmds(struct name *np); + +#ifndef max +#define max(a,b) ((a)>(b)?(a):(b)) +#endif /* - * Exec a shell that returns exit status correctly (/bin/esh). - * The standard EON shell returns the process number of the last - * async command, used by the debugger (ugg). - * [exec on eon is like a fork+exec on unix] + * Exec a shell that returns exit status correctly (/bin/esh). + * The standard EON shell returns the process number of the last + * async command, used by the debugger (ugg). + * [exec on eon is like a fork+exec on unix] */ -int -dosh(string, shell) -char * string; -char * shell; +static int dosh(char *string, char *shell) { - int number; + return system(string); +} + +/* + * Do commands to make a target + */ +static void docmds1(struct name *np, struct line *lp) +{ + bool ssilent; + bool signore; + int estat; + register char * q; + register char * p; + char * shell; + register struct cmd * cp; + + + if (*(shell = getmacro("SHELL")) == '\0') #ifdef unix - return system(string); + shell = "/bin/sh"; #endif -#ifdef eon - return ((number = execl(shell, shell,"-c", string, 0)) == -1) ? - -1: /* couldn't start the shell */ - wait(number); /* return its exit status */ -#endif -#ifdef os9 - int status, pid; + for (cp = lp->l_cmd; cp; cp = cp->c_next) + { + strcpy(str1, cp->c_cmd); + expand(str1); + q = str1; + ssilent = silent; + signore = ignore; + while ((*q == '@') || (*q == '-')) + { + if (*q == '@') /* Specific silent */ + ssilent = TRUE; + else /* Specific ignore */ + signore = TRUE; + q++; /* Not part of the command */ + } - strcat(string, "\n"); - if ((number = os9fork(shell, strlen(string), string, 0, 0, 0)) == -1) - return -1; /* Couldn't start a shell */ - do - { - if ((pid = wait(&status)) == -1) - return -1; /* child already died!?!? */ - } while (pid != number); + if (!domake) + ssilent = 0; - return status; -#endif + if (!ssilent) + fputs(" ", stdout); + + for (p=q; *p; p++) + { + if (*p == '\n' && p[1] != '\0') + { + *p = ' '; + if (!ssilent) + fputs("\\\n", stdout); + } + else if (!ssilent) + putchar(*p); + } + if (!ssilent) { + putchar('\n'); + fflush(stdout); + } + + if (domake) + { /* Get the shell to execute it */ + if ((estat = dosh(q, shell)) != 0) + { + if (estat == -1) + fatal("Couldn't execute %s", shell); + else + { + printf("%s: Error code %d", myname, estat); + if (signore) + fputs(" (Ignored)\n", stdout); + else + { + putchar('\n'); + if (!(np->n_flag & N_PREC)) + if (remove(np->n_name) == 0) + printf("%s: '%s' removed.\n", myname, np->n_name); + exit(1); + } + } + fflush(stdout); + } + } + } +} + + +void docmds(struct name *np) +{ + register struct line * lp; + + + for (lp = np->n_line; lp; lp = lp->l_next) + docmds1(np, lp); } /* - * Do commands to make a target + * Get the modification time of a file. If the first + * doesn't exist, it's modtime is set to 0. */ -void -docmds1(np, lp) -struct name * np; -struct line * lp; +void modtime(struct name *np) { - bool ssilent; - bool signore; - int estat; - register char * q; - register char * p; - char * shell; - register struct cmd * cp; + struct stat info; + if (stat(np->n_name, &info) < 0) + { + if (errno != ENOENT) + fatal("Can't open %s", np->n_name); - if (*(shell = getmacro("SHELL")) == '\0') -#ifdef eon - shell = ":bin/esh"; -#endif -#ifdef unix - shell = "/bin/sh"; -#endif -#ifdef os9 - shell = "shell"; -#endif - - for (cp = lp->l_cmd; cp; cp = cp->c_next) - { - strcpy(str1, cp->c_cmd); - expand(str1); - q = str1; - ssilent = silent; - signore = ignore; - while ((*q == '@') || (*q == '-')) - { - if (*q == '@') /* Specific silent */ - ssilent = TRUE; - else /* Specific ignore */ - signore = TRUE; - q++; /* Not part of the command */ - } - - if (!domake) - ssilent = 0; - - if (!ssilent) - fputs(" ", stdout); - - for (p=q; *p; p++) - { - if (*p == '\n' && p[1] != '\0') - { - *p = ' '; - if (!ssilent) - fputs("\\\n", stdout); - } - else if (!ssilent) - putchar(*p); - } - if (!ssilent) { - putchar('\n'); - fflush(stdout); - } - - if (domake) - { /* Get the shell to execute it */ - if ((estat = dosh(q, shell)) != 0) - { - if (estat == -1) - fatal("Couldn't execute %s", shell); - else - { - printf("%s: Error code %d", myname, estat); - if (signore) - fputs(" (Ignored)\n", stdout); - else - { - putchar('\n'); - if (!(np->n_flag & N_PREC)) - if (unlink(np->n_name) == 0) - printf("%s: '%s' removed.\n", myname, np->n_name); - exit(1); - } - } - fflush(stdout); - } - } - } -} - - -docmds(np) -struct name * np; -{ - register struct line * lp; - - - for (lp = np->n_line; lp; lp = lp->l_next) - docmds1(np, lp); -} - - -#ifdef os9 -/* - * Some stuffing around to get the modified time of a file - * in an os9 file system - */ -getmdate(fd, tbp) -struct sgtbuf * tbp; -{ - struct registers regs; - static struct fildes fdbuf; - - - regs.rg_a = fd; - regs.rg_b = SS_FD; - regs.rg_x = &fdbuf; - regs.rg_y = sizeof (fdbuf); - - if (_os9(I_GETSTT, ®s) == -1) - { - errno = regs.rg_b & 0xff; - return -1; - } - if (tbp) - { - _strass(tbp, fdbuf.fd_date, sizeof (fdbuf.fd_date)); - tbp->t_second = 0; /* Files are only acurate to mins */ - } - return 0; + np->n_time = 0L; + } + else + np->n_time = info.st_mtime; } /* - * Kludge routine to return an aproximation of how many - * seconds since 1980. Dates will be in order, but will not - * be lineer + * Update the mod time of a file to now. */ -time_t -cnvtime(tbp) -struct sgtbuf *tbp; -{ - long acc; - - - acc = tbp->t_year - 80; /* Baseyear is 1980 */ - acc = acc * 12 + tbp->t_month; - acc = acc * 31 + tbp->t_day; - acc = acc * 24 + tbp->t_hour; - acc = acc * 60 + tbp->t_minute; - acc = acc * 60 + tbp->t_second; - - return acc; -} - - -/* - * Get the current time in the internal format - */ -time(tp) -time_t * tp; -{ - struct sgtbuf tbuf; - - - if (getime(&tbuf) < 0) - return -1; - - if (tp) - *tp = cnvtime(&tbuf); - - return 0; -} -#endif - - -/* - * Get the modification time of a file. If the first - * doesn't exist, it's modtime is set to 0. - */ -void -modtime(np) -struct name * np; +void touch(struct name *np) { #ifdef unix - struct stat info; + if (!domake || !silent) + printf(" touch(%s)\n", np->n_name); + if (domake) + { + struct utimbuf a; + time_t timeval; - if (stat(np->n_name, &info) < 0) - { - if (errno != ENOENT) - fatal("Can't open %s; error %d", np->n_name, errno); - - np->n_time = 0L; - } - else - np->n_time = info.st_mtime; + a.actime = a.modtime = time(&timeval); + if (utime(np->n_name, &a) < 0) + printf("%s: '%s' not touched - non-existant\n", + myname, np->n_name); + } #endif -#ifdef eon - struct stat info; - int fd; +} +static void make1(struct name *np, struct line *lp, struct depend *qdp) +{ + register struct depend * dp; + register char *p; - if ((fd = open(np->n_name, 0)) < 0) - { - if (errno != ER_NOTF) - fatal("Can't open %s; error %02x", np->n_name, errno); - - np->n_time = 0L; - } - else if (getstat(fd, &info) < 0) - fatal("Can't getstat %s; error %02x", np->n_name, errno); - else - np->n_time = info.st_mod; - - close(fd); -#endif -#ifdef os9 - struct sgtbuf info; - int fd; - - - if ((fd = open(np->n_name, 0)) < 0) - { - if (errno != E_PNNF) - fatal("Can't open %s; error %02x", np->n_name, errno); - - np->n_time = 0L; - } - else if (getmdate(fd, &info) < 0) - fatal("Can't getstat %s; error %02x", np->n_name, errno); - else - np->n_time = cnvtime(&info); - - close(fd); -#endif + if (dotouch) + touch(np); + else + { + strcpy(str1, ""); + for (dp = qdp; dp; dp = qdp) + { + if (strlen(str1)) + strcat(str1, " "); + strcat(str1, dp->d_name->n_name); + qdp = dp->d_next; + free((char *)dp); + } + setmacro("?", str1, 4); + setmacro("@", np->n_name, 4); + p = strrchr(np->n_name, '.'); + if (p) *p = 0; + setmacro("*", np->n_name, 4); + if (p) *p = '.'; + if (lp) /* lp set if doing a :: rule */ + docmds1(np, lp); + else + docmds(np); + } } /* - * Update the mod time of a file to now. + * Recursive routine to make a target. */ -void -touch(np) -struct name * np; +int make(struct name *np, int level) { - char c; - int fd; + register struct depend * dp; + register struct line * lp; + register struct depend * qdp; + time_t dtime = 1; + bool didsomething = 0; + int dynamic = 0; - if (!domake || !silent) - printf(" touch(%s)\n", np->n_name); + if (np->n_flag & N_DONE) + return 0; - if (domake) - { -#ifdef unix - long a[2]; - long time(); + if (!np->n_time) + modtime(np); /* Gets modtime of this file */ - a[0] = a[1] = time((long *)0); - if (utime(np->n_name, &a[0]) < 0) - printf("%s: '%s' not touched - non-existant\n", - myname, np->n_name); -#endif -#ifdef eon - if ((fd = open(np->n_name, 0)) < 0) - printf("%s: '%s' not touched - non-existant\n", - myname, np->n_name); - else - { - uread(fd, &c, 1, 0); - uwrite(fd, &c, 1); - } - close(fd); -#endif -#ifdef os9 - /* - * Strange that something almost as totally useless - * as this is easy to do in os9! - */ - if ((fd = open(np->n_name, S_IWRITE)) < 0) - printf("%s: '%s' not touched - non-existant\n", - myname, np->n_name); - close(fd); -#endif - } + if (rules) + { + for (lp = np->n_line; lp; lp = lp->l_next) + if (lp->l_cmd) + break; + if (!lp) { + dyndep(np); + dynamic = 1; + } + } + + if (!(np->n_flag & N_TARG) && np->n_time == 0L) + fatal("Don't know how to make %s", np->n_name); + + for (qdp = (struct depend *)0, lp = np->n_line; lp; lp = lp->l_next) + { + for (dp = lp->l_dep; dp; dp = dp->d_next) + { + char *sv = 0; + if (dynamic) { + char *s = getmacro("<"); + + if (s) { + sv = malloc((unsigned)(strlen(s)+1)); + if (!sv) { + fatal("no space for saved $<",NULL); + } + strcpy(sv, s); + } + } + make(dp->d_name, level+1); + if (dynamic && sv) { + setmacro("<", sv, 4); + free(sv); + } + if (np->n_time < dp->d_name->n_time) + qdp = newdep(dp->d_name, qdp); + dtime = max(dtime, dp->d_name->n_time); + } + if (!quest && (np->n_flag & N_DOUBLE) && (np->n_time < dtime)) + { + make1(np, lp, qdp); /* free()'s qdp */ + dtime = 1; + qdp = (struct depend *)0; + didsomething++; + } + } + + np->n_flag |= N_DONE; + + if (quest) + { + long t; + + t = np->n_time; + time(&np->n_time); + return t < dtime; + } + else if (np->n_time < dtime && !(np->n_flag & N_DOUBLE)) + { + make1(np, (struct line *)0, qdp); /* free()'s qdp */ + time(&np->n_time); + } + else if (level == 0 && !didsomething) + printf("%s: '%s' is up to date\n", myname, np->n_name); + return 0; } -/* - * Recursive routine to make a target. - */ -int -make(np, level) -struct name * np; -int level; -{ - register struct depend * dp; - register struct line * lp; - register struct depend * qdp; - time_t dtime = 1; - bool didsomething = 0; - int dynamic = 0; - - - if (np->n_flag & N_DONE) - return 0; - - if (!np->n_time) - modtime(np); /* Gets modtime of this file */ - - if (rules) - { - for (lp = np->n_line; lp; lp = lp->l_next) - if (lp->l_cmd) - break; - if (!lp) { - dyndep(np); - dynamic = 1; - } - } - - if (!(np->n_flag & N_TARG) && np->n_time == 0L) - fatal("Don't know how to make %s", np->n_name); - - for (qdp = (struct depend *)0, lp = np->n_line; lp; lp = lp->l_next) - { - for (dp = lp->l_dep; dp; dp = dp->d_next) - { - char *sv = 0; - if (dynamic) { - char *s = getmacro("<"); - - if (s) { - sv = malloc((unsigned)(strlen(s)+1)); - if (!sv) { - fatal("no space for saved $<"); - } - strcpy(sv, s); - } - } - make(dp->d_name, level+1); - if (dynamic && sv) { - setmacro("<", sv, 4); - free(sv); - } - if (np->n_time < dp->d_name->n_time) - qdp = newdep(dp->d_name, qdp); - dtime = max(dtime, dp->d_name->n_time); - } - if (!quest && (np->n_flag & N_DOUBLE) && (np->n_time < dtime)) - { - make1(np, lp, qdp); /* free()'s qdp */ - dtime = 1; - qdp = (struct depend *)0; - didsomething++; - } - } - - np->n_flag |= N_DONE; - - if (quest) - { - long t; - - t = np->n_time; - time(&np->n_time); - return t < dtime; - } - else if (np->n_time < dtime && !(np->n_flag & N_DOUBLE)) - { - make1(np, (struct line *)0, qdp); /* free()'s qdp */ - time(&np->n_time); - } - else if (level == 0 && !didsomething) - printf("%s: '%s' is up to date\n", myname, np->n_name); - return 0; -} - - -make1(np, lp, qdp) -register struct depend * qdp; -struct line * lp; -struct name * np; -{ - register struct depend * dp; - register char *p; - char *rindex(); - - - if (dotouch) - touch(np); - else - { - strcpy(str1, ""); - for (dp = qdp; dp; dp = qdp) - { - if (strlen(str1)) - strcat(str1, " "); - strcat(str1, dp->d_name->n_name); - qdp = dp->d_next; - free((char *)dp); - } - setmacro("?", str1, 4); - setmacro("@", np->n_name, 4); - p = rindex(np->n_name, '.'); - if (p) *p = 0; - setmacro("*", np->n_name, 4); - if (p) *p = '.'; - if (lp) /* lp set if doing a :: rule */ - docmds1(np, lp); - else - docmds(np); - } -} diff --git a/util/make/reader.c b/util/make/reader.c index f015442ce..ce3d78c08 100644 --- a/util/make/reader.c +++ b/util/make/reader.c @@ -1,119 +1,121 @@ /* - * Read in makefile + * Read in makefile * - * $Header$ + * $Header$ */ +#include +#include #include -#include +#include #include "h.h" -int lineno; +int lineno; /* - * Syntax error handler. Print message, with line number, and exits. + * Syntax error handler. Print message, with line number, and exits. */ /*VARARGS1*/ -void -error(msg, a1, a2, a3) -char * msg; +void error(char *msg, char* a1) { - fprintf(stderr, "%s: ", myname); - fprintf(stderr, msg, a1, a2, a3); - if (lineno) - fprintf(stderr, " near line %d", lineno); - fputc('\n', stderr); - exit(1); + fprintf(stderr, "%s: ", myname); + if (a1 != NULL) + { + fprintf(stderr, msg, a1); + } else + { + fprintf(stderr, "%s",msg); + } + + if (lineno) + fprintf(stderr, " near line %d", lineno); + fputc('\n', stderr); + exit(1); } /* - * Read a line into the supplied string of length LZ. Remove - * comments, ignore blank lines. Deal with quoted (\) #, and - * quoted newlines. If EOF return TRUE. + * Read a line into the supplied string of length LZ. Remove + * comments, ignore blank lines. Deal with quoted (\) #, and + * quoted newlines. If EOF return TRUE. */ -bool -getline(str, fd) -char * str; -FILE * fd; +bool mgetline(char* str, FILE* fd) { - register char * p; - char * q; - int pos = 0; + register char * p; + char * q; + int pos = 0; - for (;;) - { - if (fgets(str+pos, LZ-pos, fd) == (char *)0) - return TRUE; /* EOF */ + for (;;) + { + if (fgets(str+pos, LZ-pos, fd) == (char *)0) + return TRUE; /* EOF */ - lineno++; + lineno++; - if ((p = index(str+pos, '\n')) == (char *)0) - error("Line too long"); + if ((p = strchr(str+pos, '\n')) == (char *)0) + error("Line too long", NULL); - if (p[-1] == '\\') - { - p[-1] = '\n'; - pos = p - str; - continue; - } + if (p[-1] == '\\') + { + p[-1] = '\n'; + pos = p - str; + continue; + } - p = str; - while (((q = index(p, '#')) != (char *)0) && - (p != q) && (q[-1] == '\\')) - { - char *a; + p = str; + while (((q = strchr(p, '#')) != (char *)0) && + (p != q) && (q[-1] == '\\')) + { + char *a; - a = q - 1; /* Del \ chr; move rest back */ - p = q; - while (*a++ = *q++) - ; - } - if (q != (char *)0) - { - q[0] = '\n'; - q[1] = '\0'; - } + a = q - 1; /* Del \ chr; move rest back */ + p = q; + while ((*a++ = *q++)) + ; + } + if (q != (char *)0) + { + q[0] = '\n'; + q[1] = '\0'; + } - p = str; - while (isspace(*p)) /* Checking for blank */ - p++; + p = str; + while (isspace(*p)) /* Checking for blank */ + p++; - if (*p != '\0') - return FALSE; - pos = 0; - } + if (*p != '\0') + return FALSE; + pos = 0; + } } /* - * Get a word from the current line, surounded by white space. - * return a pointer to it. String returned has no white spaces - * in it. + * Get a word from the current line, surounded by white space. + * return a pointer to it. String returned has no white spaces + * in it. */ -char * -gettok(ptr) -char **ptr; +char *gettok(char **ptr) { - register char * p; + register char * p; - while (isspace(**ptr)) /* Skip spaces */ - (*ptr)++; + while (isspace(**ptr)) /* Skip spaces */ + (*ptr)++; - if (**ptr == '\0') /* Nothing after spaces */ - return NULL; + if (**ptr == '\0') /* Nothing after spaces */ + return NULL; - p = *ptr; /* word starts here */ + p = *ptr; /* word starts here */ - while ((**ptr != '\0') && (!isspace(**ptr))) - (*ptr)++; /* Find end of word */ + while ((**ptr != '\0') && (!isspace(**ptr))) + (*ptr)++; /* Find end of word */ - *(*ptr)++ = '\0'; /* Terminate it */ + *(*ptr)++ = '\0'; /* Terminate it */ - return(p); + return(p); } diff --git a/util/make/rules.c b/util/make/rules.c index e2d7dfacb..a434511c9 100644 --- a/util/make/rules.c +++ b/util/make/rules.c @@ -1,257 +1,253 @@ /* - * Control of the implicit suffix rules + * Control of the implicit suffix rules * - * $Header$ + * $Header$ */ - +#include +#include #include "h.h" /* - * Return a pointer to the suffix of a name + * Return a pointer to the suffix of a name */ -char * -suffix(name) -char * name; +char *suffix(char *name) { - return rindex(name, '.'); + return strrchr(name, '.'); } /* - * Dynamic dependency. This routine applies the suffis rules - * to try and find a source and a set of rules for a missing - * target. If found, np is made into a target with the implicit - * source name, and rules. Returns TRUE if np was made into - * a target. + * Dynamic dependency. This routine applies the suffis rules + * to try and find a source and a set of rules for a missing + * target. If found, np is made into a target with the implicit + * source name, and rules. Returns TRUE if np was made into + * a target. */ -bool -dyndep(np) -struct name * np; +bool dyndep(struct name *np) { - register char * p; - register char * q; - register char * suff; /* Old suffix */ - register char * basename; /* Name without suffix */ - struct name * op; /* New dependent */ - struct name * sp; /* Suffix */ - struct line * lp; - struct depend * dp; - char * newsuff; + register char * p; + register char * q; + register char * suff; /* Old suffix */ + register char * basename; /* Name without suffix */ + struct name * op; /* New dependent */ + struct name * sp; /* Suffix */ + struct line * lp; + struct depend * dp; + char * newsuff; - p = str1; - q = np->n_name; - if (!(suff = suffix(q))) - return FALSE; /* No suffix */ - while (q < suff) - *p++ = *q++; - *p = '\0'; - basename = setmacro("*", str1, 4)->m_val; + p = str1; + q = np->n_name; + if (!(suff = suffix(q))) + return FALSE; /* No suffix */ + while (q < suff) + *p++ = *q++; + *p = '\0'; + basename = setmacro("*", str1, 4)->m_val; - if (!((sp = newname(".SUFFIXES"))->n_flag & N_TARG)) - return FALSE; + if (!((sp = newname(".SUFFIXES"))->n_flag & N_TARG)) + return FALSE; - for (lp = sp->n_line; lp; lp = lp->l_next) - for (dp = lp->l_dep; dp; dp = dp->d_next) - { - newsuff = dp->d_name->n_name; - if (strlen(suff)+strlen(newsuff)+1 >= LZ) - fatal("Suffix rule too long"); - p = str1; - q = newsuff; - while (*p++ = *q++) - ; - p--; - q = suff; - while (*p++ = *q++) - ; - sp = newname(str1); - if (sp->n_flag & N_TARG) - { - p = str1; - q = basename; - if (strlen(basename) + strlen(newsuff)+1 >= LZ) - fatal("Implicit name too long"); - while (*p++ = *q++) - ; - p--; - q = newsuff; - while (*p++ = *q++) - ; - op = newname(str1); - if (!op->n_time) - modtime(op); - if (op->n_time || (op->n_flag & N_TARG)) - { - dp = newdep(op, (struct depend *)0); - newline(np, dp, sp->n_line->l_cmd, 0); - setmacro("<", op->n_name, 4); - return TRUE; - } - } - } - return FALSE; + for (lp = sp->n_line; lp; lp = lp->l_next) + for (dp = lp->l_dep; dp; dp = dp->d_next) + { + newsuff = dp->d_name->n_name; + if (strlen(suff)+strlen(newsuff)+1 >= LZ) + fatal("Suffix rule too long",NULL); + p = str1; + q = newsuff; + while ((*p++ = *q++)) + ; + p--; + q = suff; + while ((*p++ = *q++)) + ; + sp = newname(str1); + if (sp->n_flag & N_TARG) + { + p = str1; + q = basename; + if (strlen(basename) + strlen(newsuff)+1 >= LZ) + fatal("Implicit name too long",NULL); + while ((*p++ = *q++)) + ; + p--; + q = newsuff; + while ((*p++ = *q++)) + ; + op = newname(str1); + if (!op->n_time) + modtime(op); + if (op->n_time || (op->n_flag & N_TARG)) + { + dp = newdep(op, (struct depend *)0); + newline(np, dp, sp->n_line->l_cmd, 0); + setmacro("<", op->n_name, 4); + return TRUE; + } + } + } + return FALSE; } /* - * Make the default rules + * Make the default rules */ -void -makerules() +void makerules(void) { - struct cmd * cp; - struct name * np; - struct depend * dp; + struct cmd * cp; + struct name * np; + struct depend * dp; #ifdef eon - setmacro("BDSCC", "asm", 0); - /* setmacro("BDSCFLAGS", "", 0); */ - cp = newcmd("$(BDSCC) $(BDSCFLAGS) -n $<", (struct cmd *)0); - np = newname(".c.o"); - newline(np, (struct depend *)0, cp, 0); + setmacro("BDSCC", "asm", 0); + /* setmacro("BDSCFLAGS", "", 0); */ + cp = newcmd("$(BDSCC) $(BDSCFLAGS) -n $<", (struct cmd *)0); + np = newname(".c.o"); + newline(np, (struct depend *)0, cp, 0); - setmacro("CC", "c", 0); - setmacro("CFLAGS", "-O", 0); - cp = newcmd("$(CC) $(CFLAGS) -c $<", (struct cmd *)0); - np = newname(".c.obj"); - newline(np, (struct depend *)0, cp, 0); + setmacro("CC", "c", 0); + setmacro("CFLAGS", "-O", 0); + cp = newcmd("$(CC) $(CFLAGS) -c $<", (struct cmd *)0); + np = newname(".c.obj"); + newline(np, (struct depend *)0, cp, 0); - setmacro("M80", "asm -n", 0); - /* setmacro("M80FLAGS", "", 0); */ - cp = newcmd("$(M80) $(M80FLAGS) $<", (struct cmd *)0); - np = newname(".mac.o"); - newline(np, (struct depend *)0, cp, 0); + setmacro("M80", "asm -n", 0); + /* setmacro("M80FLAGS", "", 0); */ + cp = newcmd("$(M80) $(M80FLAGS) $<", (struct cmd *)0); + np = newname(".mac.o"); + newline(np, (struct depend *)0, cp, 0); - setmacro("AS", "zas", 0); - /* setmacro("ASFLAGS", "", 0); */ - cp = newcmd("$(ZAS) $(ASFLAGS) -o $@ $<", (struct cmd *)0); - np = newname(".as.obj"); - newline(np, (struct depend *)0, cp, 0); + setmacro("AS", "zas", 0); + /* setmacro("ASFLAGS", "", 0); */ + cp = newcmd("$(ZAS) $(ASFLAGS) -o $@ $<", (struct cmd *)0); + np = newname(".as.obj"); + newline(np, (struct depend *)0, cp, 0); - np = newname(".as"); - dp = newdep(np, (struct depend *)0); - np = newname(".obj"); - dp = newdep(np, dp); - np = newname(".c"); - dp = newdep(np, dp); - np = newname(".o"); - dp = newdep(np, dp); - np = newname(".mac"); - dp = newdep(np, dp); - np = newname(".SUFFIXES"); - newline(np, dp, (struct cmd *)0, 0); + np = newname(".as"); + dp = newdep(np, (struct depend *)0); + np = newname(".obj"); + dp = newdep(np, dp); + np = newname(".c"); + dp = newdep(np, dp); + np = newname(".o"); + dp = newdep(np, dp); + np = newname(".mac"); + dp = newdep(np, dp); + np = newname(".SUFFIXES"); + newline(np, dp, (struct cmd *)0, 0); #endif /* - * Some of the UNIX implicit rules + * Some of the UNIX implicit rules */ #ifdef unix - setmacro("CC", "cc", 0); - setmacro("CFLAGS", "-O", 0); + setmacro("CC", "cc", 0); + setmacro("CFLAGS", "-O", 0); #ifdef MINIX - cp = newcmd("$(CC) $(CFLAGS) -S $<", (struct cmd *)0); - np = newname(".c.s"); + cp = newcmd("$(CC) $(CFLAGS) -S $<", (struct cmd *)0); + np = newname(".c.s"); #else - cp = newcmd("$(CC) $(CFLAGS) -c $<", (struct cmd *)0); - np = newname(".c.o"); -#endif MINIX - newline(np, (struct depend *)0, cp, 0); + cp = newcmd("$(CC) $(CFLAGS) -c $<", (struct cmd *)0); + np = newname(".c.o"); +#endif /* MINIX */ + newline(np, (struct depend *)0, cp, 0); - setmacro("AS", "as", 0); - cp = newcmd("$(AS) -o $@ $<", (struct cmd *)0); - np = newname(".s.o"); - newline(np, (struct depend *)0, cp, 0); + setmacro("AS", "as", 0); + cp = newcmd("$(AS) -o $@ $<", (struct cmd *)0); + np = newname(".s.o"); + newline(np, (struct depend *)0, cp, 0); - setmacro("YACC", "yacc", 0); - /* setmacro("YFLAGS", "", 0); */ - cp = newcmd("$(YACC) $(YFLAGS) $<", (struct cmd *)0); - cp = newcmd("mv y.tab.c $@", cp); - np = newname(".y.c"); - newline(np, (struct depend *)0, cp, 0); + setmacro("YACC", "yacc", 0); + /* setmacro("YFLAGS", "", 0); */ + cp = newcmd("$(YACC) $(YFLAGS) $<", (struct cmd *)0); + cp = newcmd("mv y.tab.c $@", cp); + np = newname(".y.c"); + newline(np, (struct depend *)0, cp, 0); - cp = newcmd("$(YACC) $(YFLAGS) $<", (struct cmd *)0); - cp = newcmd("$(CC) $(CFLAGS) -c y.tab.c", cp); - cp = newcmd("rm y.tab.c", cp); - cp = newcmd("mv y.tab.o $@", cp); - np = newname(".y.o"); - newline(np, (struct depend *)0, cp, 0); + cp = newcmd("$(YACC) $(YFLAGS) $<", (struct cmd *)0); + cp = newcmd("$(CC) $(CFLAGS) -c y.tab.c", cp); + cp = newcmd("rm y.tab.c", cp); + cp = newcmd("mv y.tab.o $@", cp); + np = newname(".y.o"); + newline(np, (struct depend *)0, cp, 0); - setmacro("LEX", "lex", 0); - /* setmacro("LFLAGS", "", 0); */ - cp = newcmd("$(LEX) $(LFLAGS) $<", (struct cmd *)0); - cp = newcmd("mv lex.yy.c $@", cp); - np = newname(".l.c"); - newline(np, (struct depend *)0, cp, 0); + setmacro("LEX", "lex", 0); + /* setmacro("LFLAGS", "", 0); */ + cp = newcmd("$(LEX) $(LFLAGS) $<", (struct cmd *)0); + cp = newcmd("mv lex.yy.c $@", cp); + np = newname(".l.c"); + newline(np, (struct depend *)0, cp, 0); - cp = newcmd("$(LEX) $(LFLAGS) $<", (struct cmd *)0); - cp = newcmd("$(CC) $(CFLAGS) -c lex.yy.c", cp); - cp = newcmd("rm lex.yy.c", cp); - cp = newcmd("mv lex.yy.o $@", cp); - np = newname(".l.o"); - newline(np, (struct depend *)0, cp, 0); + cp = newcmd("$(LEX) $(LFLAGS) $<", (struct cmd *)0); + cp = newcmd("$(CC) $(CFLAGS) -c lex.yy.c", cp); + cp = newcmd("rm lex.yy.c", cp); + cp = newcmd("mv lex.yy.o $@", cp); + np = newname(".l.o"); + newline(np, (struct depend *)0, cp, 0); - np = newname(".s"); - dp = newdep(np, (struct depend *)0); - np = newname(".o"); - dp = newdep(np, dp); - np = newname(".c"); - dp = newdep(np, dp); - np = newname(".y"); - dp = newdep(np, dp); - np = newname(".l"); - dp = newdep(np, dp); - np = newname(".SUFFIXES"); - newline(np, dp, (struct cmd *)0, 0); + np = newname(".s"); + dp = newdep(np, (struct depend *)0); + np = newname(".o"); + dp = newdep(np, dp); + np = newname(".c"); + dp = newdep(np, dp); + np = newname(".y"); + dp = newdep(np, dp); + np = newname(".l"); + dp = newdep(np, dp); + np = newname(".SUFFIXES"); + newline(np, dp, (struct cmd *)0, 0); #endif #ifdef os9 /* - * Fairlight use an enhanced version of the C sub-system. - * They have a specialised macro pre-processor. + * Fairlight use an enhanced version of the C sub-system. + * They have a specialised macro pre-processor. */ - setmacro("CC", "cc", 0); - setmacro("CFLAGS", "-z", 0); - cp = newcmd("$(CC) $(CFLAGS) -r $<", (struct cmd *)0); + setmacro("CC", "cc", 0); + setmacro("CFLAGS", "-z", 0); + cp = newcmd("$(CC) $(CFLAGS) -r $<", (struct cmd *)0); - np = newname(".c.r"); - newline(np, (struct depend *)0, cp, 0); - np = newname(".ca.r"); - newline(np, (struct depend *)0, cp, 0); - np = newname(".a.r"); - newline(np, (struct depend *)0, cp, 0); - np = newname(".o.r"); - newline(np, (struct depend *)0, cp, 0); - np = newname(".mc.r"); - newline(np, (struct depend *)0, cp, 0); - np = newname(".mca.r"); - newline(np, (struct depend *)0, cp, 0); - np = newname(".ma.r"); - newline(np, (struct depend *)0, cp, 0); - np = newname(".mo.r"); - newline(np, (struct depend *)0, cp, 0); + np = newname(".c.r"); + newline(np, (struct depend *)0, cp, 0); + np = newname(".ca.r"); + newline(np, (struct depend *)0, cp, 0); + np = newname(".a.r"); + newline(np, (struct depend *)0, cp, 0); + np = newname(".o.r"); + newline(np, (struct depend *)0, cp, 0); + np = newname(".mc.r"); + newline(np, (struct depend *)0, cp, 0); + np = newname(".mca.r"); + newline(np, (struct depend *)0, cp, 0); + np = newname(".ma.r"); + newline(np, (struct depend *)0, cp, 0); + np = newname(".mo.r"); + newline(np, (struct depend *)0, cp, 0); - np = newname(".r"); - dp = newdep(np, (struct depend *)0); - np = newname(".mc"); - dp = newdep(np, dp); - np = newname(".mca"); - dp = newdep(np, dp); - np = newname(".c"); - dp = newdep(np, dp); - np = newname(".ca"); - dp = newdep(np, dp); - np = newname(".ma"); - dp = newdep(np, dp); - np = newname(".mo"); - dp = newdep(np, dp); - np = newname(".o"); - dp = newdep(np, dp); - np = newname(".a"); - dp = newdep(np, dp); - np = newname(".SUFFIXES"); - newline(np, dp, (struct cmd *)0, 0); + np = newname(".r"); + dp = newdep(np, (struct depend *)0); + np = newname(".mc"); + dp = newdep(np, dp); + np = newname(".mca"); + dp = newdep(np, dp); + np = newname(".c"); + dp = newdep(np, dp); + np = newname(".ca"); + dp = newdep(np, dp); + np = newname(".ma"); + dp = newdep(np, dp); + np = newname(".mo"); + dp = newdep(np, dp); + np = newname(".o"); + dp = newdep(np, dp); + np = newname(".a"); + dp = newdep(np, dp); + np = newname(".SUFFIXES"); + newline(np, dp, (struct cmd *)0, 0); #endif } diff --git a/util/topgen/LLlex.c b/util/topgen/LLlex.c index fb156d4d0..64d9cb352 100644 --- a/util/topgen/LLlex.c +++ b/util/topgen/LLlex.c @@ -21,8 +21,11 @@ static struct token aside; /* to put currrent token aside, when a token int newline, lineno; /* To keep track of linenumbers */ extern FILE *input; /* file descriptor of machine table */ -LLlex() { - register c; +extern void error(char *s, char* s1); + + +int LLlex(void) { + register int c; if (aside.t_tokno) { /* A token was pushed aside, return it now */ dot = aside; @@ -52,7 +55,7 @@ LLlex() { if (c == EOF) { c = lineno; lineno = l; - error("Unterminated comment"); + error("Unterminated comment", ""); lineno = c; c = EOF; } @@ -116,13 +119,14 @@ LLlex() { } } -LLmessage(d) { +void LLmessage(int d) +{ static int savlineno; if (savlineno != lineno) { /* Only an error message if on another line number */ savlineno = lineno; - error("Syntax error"); + error("Syntax error",""); } if (d > 0) { /* "d" is the token to be inserted. diff --git a/util/topgen/hash.c b/util/topgen/hash.c index 03b214ecc..cafe26d69 100644 --- a/util/topgen/hash.c +++ b/util/topgen/hash.c @@ -8,83 +8,89 @@ * maintains the the lists of hashed patterns * Functions : addtohashtable() and printhashtable() */ - + #include #include #include #include "misc.h" +#include "hash.h" -struct hlist { /* linear list of pattern numbers */ - int h_patno; - struct hlist *h_next; +struct hlist +{ /* linear list of pattern numbers */ + int h_patno; + struct hlist *h_next; }; -static struct hlist *hashtable[129]; /* an array of ptr's to these lists, - * the index in the array is the - * result of hashing - */ +static struct hlist *hashtable[129]; /* an array of ptr's to these lists, + * the index in the array is the + * result of hashing + */ -static unsigned -hash(string) char *string; { +static unsigned hash(char* string) +{ register char *p; - register unsigned i,sum; + register unsigned i, sum; - if (strcmp(string,"ANY") == 0) return 128; - for (sum=i=0,p=string;*p;i += 3) - sum += (*p++)<<(i&03); + if (strcmp(string, "ANY") == 0) + return 128; + for (sum = i = 0, p = string; *p; i += 3) + sum += (*p++) << (i & 03); return sum % 128; } +void addtohashtable(char* s, int n) +{ + /* + * Add a new pattern number to the hashtable. + * s is the key, n the pattern number + */ + unsigned hval; + register struct hlist *p; -addtohashtable(s,n) char *s; { - /* - * Add a new pattern number to the hashtable. - * s is the key, n the pattern number - */ - unsigned hval; - register struct hlist *p; - - hval = hash(s); - p = (struct hlist *) malloc(sizeof *p); - p->h_patno = n; - /* - * Now insert in front of the list - * This way, the list will be sorted from high to low, which is the - * wrong way around, but easy - */ - p->h_next = hashtable[hval]; - hashtable[hval] = p; + hval = hash(s); + p = (struct hlist *) malloc(sizeof *p); + p->h_patno = n; + /* + * Now insert in front of the list + * This way, the list will be sorted from high to low, which is the + * wrong way around, but easy + */ + p->h_next = hashtable[hval]; + hashtable[hval] = p; } -static -prhlist(p) struct hlist *p; { - /* - * Print a list in reversed order (see comment above) - */ +static void prhlist(struct hlist *p) +{ + /* + * Print a list in reversed order (see comment above) + */ - if (p) { - prhlist(p->h_next); - fprintf(genc,"%d, ",p->h_patno - 1); - } + if (p) + { + prhlist(p->h_next); + fprintf(genc, "%d, ", p->h_patno - 1); + } } - -printhashtable() { - /* - * Print the linear lists, and also output an array of - * pointers to them - */ - register i; - register struct hlist *p; - for (i = 1; i <= 128; i++) { - fprintf(genc,"int hash%d[] = { ",i); - prhlist(hashtable[i-1]); - fputs("-1};\n",genc); - } - fputs("int hashany[] = { ", genc); - prhlist(hashtable[128]); - fputs("-1 };\n",genc); - fputs("int *hashtab[] = {\n",genc); - for (i = 1; i <= 128; i++) fprintf(genc,"\thash%d,\n",i); - fputs("\thashany\n};\n",genc); +void printhashtable(void) +{ + /* + * Print the linear lists, and also output an array of + * pointers to them + */ + register int i; + + for (i = 1; i <= 128; i++) + { + fprintf(genc, "int hash%d[] = { ", i); + prhlist(hashtable[i - 1]); + fputs("-1};\n", genc); + } + fputs("int hashany[] = { ", genc); + prhlist(hashtable[128]); + fputs("-1 };\n", genc); + fputs("int *hashtab[] = {\n", genc); + for (i = 1; i <= 128; i++) + fprintf(genc, "\thash%d,\n", i); + fputs("\thashany\n};\n", genc); } diff --git a/util/topgen/hash.h b/util/topgen/hash.h new file mode 100644 index 000000000..af54c0ab6 --- /dev/null +++ b/util/topgen/hash.h @@ -0,0 +1,23 @@ +/* + * hash.h + * + * Created on: 2018-11-24 + * Author: carl + */ + +#ifndef __HASH_H_INCLUDED__ +#define __HASH_H_INCLUDED__ + +/* + * Add a new pattern number to the hashtable. + * s is the key, n the pattern number + */ +void addtohashtable(char* s, int n); +/* + * Print the linear lists, and also output an array of + * pointers to them + */ +void printhashtable(void); + + +#endif /* __HASH_H_INCLUDED__ */ diff --git a/util/topgen/main.c b/util/topgen/main.c index 2f211f837..35e0585d7 100644 --- a/util/topgen/main.c +++ b/util/topgen/main.c @@ -11,6 +11,7 @@ #include #include +#include "Lpars.h" extern int lineno, newline; @@ -19,8 +20,10 @@ static int nerrors; char *linedir = "#line %d \"%s\"\n"; /* format of line directive */ char *inpfile; -main(argc,argv) char *argv[]; { +extern void LLparse(void); +int main(int argc,char* argv[]) +{ newline = 1; if (argc != 3) { fprintf(stderr,"Usage : %s targetoptimizerdescription outputdir\n",argv[0]); @@ -48,15 +51,16 @@ main(argc,argv) char *argv[]; { } /* VARARGS1 */ -error(s, s1) char *s, *s1; { - +void error(char *s, char* s1) +{ nerrors++; fprintf(stderr,"\"%s\", line %d: ",inpfile,lineno); fprintf(stderr,s,s1); putc('\n',stderr); } -onlyspace(s) register char *s; { +int onlyspace(register char* s) +{ while (*s) { if (*s != ' ' && *s != '\t' && *s != '\n') return 0; diff --git a/util/topgen/pattern.c b/util/topgen/pattern.c index db6ad6268..9e84f5059 100644 --- a/util/topgen/pattern.c +++ b/util/topgen/pattern.c @@ -32,7 +32,8 @@ static struct pattern *pattable, /* ptr to pattern array */ * be allocated */ -addpattern(str,l,np,nr) char *str; { +void addpattern(char* str,int l,int np,int nr) +{ /* * Just add a pattern to the list. * "str" is the constraint, "l" is the line number, @@ -62,8 +63,8 @@ addpattern(str,l,np,nr) char *str; { p->p_nrepl = nr; } -static -prconstraint(str) char *str; { +static void prconstraint(char* str) +{ /* * prints a constraint, with variable names replaced */ @@ -104,13 +105,13 @@ prconstraint(str) char *str; { } } -printpatterns() { +void printpatterns(void) { /* * Prints the pattern_descr table and generates the routine * "check_constraint" */ register struct pattern *p; - register i; + register int i; p = pattable; i = 1; @@ -127,7 +128,7 @@ printpatterns() { while (p < current) { if (p->p_constraint) { /* The pattern has a constraint */ - fprintf(genc,"\tcase %d :\n",p - pattable); + fprintf(genc,"\tcase %d :\n",(int)(p - pattable)); fprintf(genc,linedir,p->p_lineno,inpfile); /* linedirective */ fputs("\tr = (",genc); prconstraint(p->p_constraint); diff --git a/util/topgen/pattern.h b/util/topgen/pattern.h new file mode 100644 index 000000000..863fb0557 --- /dev/null +++ b/util/topgen/pattern.h @@ -0,0 +1,27 @@ +/* + * pattern.h + * + * Created on: 2018-11-25 + * Author: carl + */ + +#ifndef __PATTERN_H_INCLUDED__ +#define __PATTERN_H_INCLUDED__ + + +/* + * Just add a pattern to the list. + * "str" is the constraint, "l" is the line number, + * "np" is the number of instructions in the pattern, + * "nr" is the number of instructions in the replacement + * Space is allocated in chunks of 50 + */ +void addpattern(char* str,int l,int np,int nr); + +/* + * Prints the pattern_descr table and generates the routine + * "check_constraint" + */ +void printpatterns(void); + +#endif /* __PATTERN_H_INCLUDED__ */ diff --git a/util/topgen/symtab.c b/util/topgen/symtab.c index b5511d0dc..da1af3dfd 100644 --- a/util/topgen/symtab.c +++ b/util/topgen/symtab.c @@ -15,6 +15,8 @@ struct symtab *idtable, *deftable; +extern void error(char *s, char* s1); + struct symtab * findident(s, mode, table) char *s; struct symtab **table; { /* @@ -24,7 +26,7 @@ findident(s, mode, table) char *s; struct symtab **table; { * table yet, otherwise an error results */ register struct symtab *p; - register n; + register int n; if (!*table) { /* No entry for this symbol */ if (mode == LOOKING) return (struct symtab *) 0; diff --git a/util/topgen/topgen.g b/util/topgen/topgen.g index 45c573e94..1d0284d63 100644 --- a/util/topgen/topgen.g +++ b/util/topgen/topgen.g @@ -1,311 +1,320 @@ -/* $Id$ */ -/* - * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. - * See the copyright notice in the ACK home directory, in the file "Copyright". - */ -/* t o p g e n . g - * - * Grammar of optimizer description, and some code generation - */ - -%token LETTER, DIGIT, OTHER, SPACE; -%token LINE_TERMINATOR, OPERAND_SEPARATOR, INSTRUCTION_SEPARATOR, - PATTERN_SEPARATOR, OPEN_BRACKET, CLOSE_BRACKET; -%lexical LLlex; -%start LLparse, optim_description; - -{ -#include -#include -#include -#include "token.h" -#include "symtab.h" -#include "misc.h" - -char idbuf[BUFSIZ], buf[BUFSIZ]; -int countid; /* # of variables */ -int countpat; /* # of patterns */ -static int patlen; /* Maximum number of instructions in pattern */ -static int maxoperand; /* Maximum number of operands of instruction */ -extern FILE *input; /* file descriptor of inputfile */ -} - -optim_description - { struct symtab *p; } : - SPACE* parameter_line* - { p = findident("MAXOP",LOOKING,&deftable); - if (p == 0) maxoperand = 2; /* default */ - else maxoperand = p->s_num; - } - separator SPACE* mode_definitions - separator SPACE* patterns - separator - { register int c; - fprintf(genc, linedir, lineno, inpfile); - while ((c = getc(input)) != EOF) { - putc(c,genc); - } - } -; - -parameter_line - { struct symtab *p;} : - identifier - { p = findident(idbuf,ENTERING,&deftable);} - SPACE - value - { p->s_num = atoi(buf);} - /* This action in fact only needed for MAXOP */ - LINE_TERMINATOR - SPACE* - { fprintf(genh,"#define %s %s\n",p->s_name,buf);} -; - -value - { char *p1 = buf;} : - [ - [ OPEN_BRACKET - | CLOSE_BRACKET - | OPERAND_SEPARATOR - | PATTERN_SEPARATOR - | INSTRUCTION_SEPARATOR - | SPACE - | LETTER - | DIGIT - | OTHER - | '%' - ] - { *p1++ = dot.t_attrib;} - ]* - { *p1 = '\0';} -; - -mode_definitions - { int lin; } : - { fputs("tok_chk(varno) {\n\tint r;\n", genc); - fputs("\tchar *VAL;\n\n",genc); - fputs("\tVAL = var[varno].value;\n",genc); - fputs("\tswitch(varno) {\n",genc); - } - [ - token_list - constraint(&lin) - { fprintf(genc,linedir,lin,inpfile); - fprintf(genc,"\t\tr = (%s); break;\n",buf); - } - LINE_TERMINATOR - SPACE* - ]* - { fputs("\tdefault :\n\t\tassert(0);\n",genc); - fputs("\t}\n\treturn r;\n}\n\n",genc); - } -; - -token_list : - new_identifier - SPACE* - [ - OPERAND_SEPARATOR - SPACE* - new_identifier - SPACE* - ]* -; - -new_identifier - { struct symtab *p;} : - identifier - { p = findident(idbuf,ENTERING,&idtable); - p->s_num = ++countid; - fprintf(genc,"\tcase %d:\n", countid); - } -; - -constraint (int *lin;) - { char *p = buf; } : - OPEN_BRACKET - { *lin = lineno;} - [ - [ LINE_TERMINATOR - | OPERAND_SEPARATOR - | PATTERN_SEPARATOR - | INSTRUCTION_SEPARATOR - | LETTER - | DIGIT - | SPACE - | OTHER - | '%' - ] - { *p++ = dot.t_attrib;} - ]* - { *p = '\0'; - if (onlyspace(buf)) strcpy(buf,"TRUE"); - } - CLOSE_BRACKET - SPACE* -; - -patterns - { int lin; - char *constr; - int np, nr; - } : -[ - { countpat++; - constr = (char *) 0; - fprintf(genc,"struct instr_descr pat%d[] = {\n", - countpat); - } - instruction_list(&np) - { if (np > patlen) patlen = np; - fputs("\n};\n\n",genc); - } - [ - constraint(&lin) - { /* Save the constraint, we need it later on */ - constr = malloc((unsigned)(strlen(buf)+1)); - strcpy(constr,buf); - } - ]? - PATTERN_SEPARATOR - { fprintf(genc,"struct instr_descr rep%d[] = {\n", - countpat); - } - replacement(&nr) - { fputs("\n};\n\n",genc);} - LINE_TERMINATOR - SPACE* - { addpattern(constr,lin,np,nr);} -]* - { printhashtable(); - printpatterns(); - fprintf(genh,"#define NRVARS %d\n",countid); - fprintf(genh,"#define NRPATTERNS %d\n",countpat); - fprintf(genh,"#define MIN_WINDOW_SIZE %d\n", - patlen+3); - fclose(genh); - } -; - -instruction_list(int *n;) : - instruction(1) - { *n = 1;} - [ - INSTRUCTION_SEPARATOR - { fputs(",\n",genc);} - SPACE* - instruction(0) - { *n += 1;} - ]* -; - -instruction(int opt;) - { int count = 0;} : - opcode(opt) - { if (strcmp(buf,"ANY") != 0) { - fprintf(genc,"\t{\"%s\", {",buf); - } - else fputs("\t{(char *) 0, {",genc); - count = 0; - } - [ - operand(' ') - { count = 1;} - [ - OPERAND_SEPARATOR - { count++;} - SPACE* - operand(',') - ]* - { if (count > maxoperand) { - error("Too many operands"); - } - } - ]? - { while (count++ < maxoperand) { - fprintf(genc,"%c{\"\",-1,\"\"}",count == 1 ? ' ' : ','); - } - putc('}',genc); - putc('}',genc); - } -; - -opcode(int opt;) - { char *p = buf;} : - [ - [ LETTER - | DIGIT - | OTHER - ] - { *p++ = dot.t_attrib;} - ]+ - SPACE+ - { *p = '\0'; - if (opt) addtohashtable(buf,countpat); - } -; - -operand(int c;) - { register struct symtab *p = 0;} : - { fprintf(genc, "%c{\"", c);} - [ - identifier - { if (!p) { - p = findident(idbuf,LOOKING,&idtable); - if (p) fprintf(genc,"\",%d,\"",p->s_num); - else fputs(idbuf,genc); - } - else fputs(idbuf,genc); - } - | DIGIT - { putc(dot.t_attrib,genc);} - | OTHER - { putc(dot.t_attrib,genc);} - ]+ - { if (p) fputs("\"}",genc); - else fputs("\",0,\"\"}",genc); - } - SPACE* -; - -replacement (int *n;) - {register i;} : - SPACE* - { *n = 0;} - [ - instruction(0) - { *n = 1;} - [ - INSTRUCTION_SEPARATOR - { fputs(",\n", genc);} - SPACE* - instruction(0) - { *n += 1;} - ]* - | /* empty replacement, but there must be a - * structure initializer anyway - */ - { fputs("\t{\"\", {",genc); - for (i = 0; i < maxoperand; i++) { - fprintf(genc, "%c{\"\",-1,\"\"}",i?',':' '); - } - fputs("}}",genc); - } - ] -; - - -identifier - { char *p = idbuf; } : - LETTER - { *p++ = dot.t_attrib;} - [ %while (1) - LETTER { *p++ = dot.t_attrib;} - | DIGIT { *p++ = dot.t_attrib;} - ]* - { *p = '\0';} -; - -separator : - '%' '%' SPACE* LINE_TERMINATOR -; +/* $Id$ */ +/* + * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. + * See the copyright notice in the ACK home directory, in the file "Copyright". + */ +/* t o p g e n . g + * + * Grammar of optimizer description, and some code generation + */ + +%token LETTER, DIGIT, OTHER, SPACE; +%token LINE_TERMINATOR, OPERAND_SEPARATOR, INSTRUCTION_SEPARATOR, + PATTERN_SEPARATOR, OPEN_BRACKET, CLOSE_BRACKET; +%lexical LLlex; +%start LLparse, optim_description; + +{ +#include +#include +#include +#include "token.h" +#include "symtab.h" +#include "misc.h" +#include "hash.h" +#include "pattern.h" + +char idbuf[BUFSIZ], buf[BUFSIZ]; +int countid; /* # of variables */ +int countpat; /* # of patterns */ +static int patlen; /* Maximum number of instructions in pattern */ +static int maxoperand; /* Maximum number of operands of instruction */ +extern FILE *input; /* file descriptor of inputfile */ + + + +extern int onlyspace(char* s); +extern void error(char *s, char* s1); + + +} + +optim_description + { struct symtab *p; } : + SPACE* parameter_line* + { p = findident("MAXOP",LOOKING,&deftable); + if (p == 0) maxoperand = 2; /* default */ + else maxoperand = p->s_num; + } + separator SPACE* mode_definitions + separator SPACE* patterns + separator + { register int c; + fprintf(genc, linedir, lineno, inpfile); + while ((c = getc(input)) != EOF) { + putc(c,genc); + } + } +; + +parameter_line + { struct symtab *p;} : + identifier + { p = findident(idbuf,ENTERING,&deftable);} + SPACE + value + { p->s_num = atoi(buf);} + /* This action in fact only needed for MAXOP */ + LINE_TERMINATOR + SPACE* + { fprintf(genh,"#define %s %s\n",p->s_name,buf);} +; + +value + { char *p1 = buf;} : + [ + [ OPEN_BRACKET + | CLOSE_BRACKET + | OPERAND_SEPARATOR + | PATTERN_SEPARATOR + | INSTRUCTION_SEPARATOR + | SPACE + | LETTER + | DIGIT + | OTHER + | '%' + ] + { *p1++ = dot.t_attrib;} + ]* + { *p1 = '\0';} +; + +mode_definitions + { int lin; } : + { fputs("tok_chk(varno) {\n\tint r;\n", genc); + fputs("\tchar *VAL;\n\n",genc); + fputs("\tVAL = var[varno].value;\n",genc); + fputs("\tswitch(varno) {\n",genc); + } + [ + token_list + constraint(&lin) + { fprintf(genc,linedir,lin,inpfile); + fprintf(genc,"\t\tr = (%s); break;\n",buf); + } + LINE_TERMINATOR + SPACE* + ]* + { fputs("\tdefault :\n\t\tassert(0);\n",genc); + fputs("\t}\n\treturn r;\n}\n\n",genc); + } +; + +token_list : + new_identifier + SPACE* + [ + OPERAND_SEPARATOR + SPACE* + new_identifier + SPACE* + ]* +; + +new_identifier + { struct symtab *p;} : + identifier + { p = findident(idbuf,ENTERING,&idtable); + p->s_num = ++countid; + fprintf(genc,"\tcase %d:\n", countid); + } +; + +constraint (int *lin;) + { char *p = buf; } : + OPEN_BRACKET + { *lin = lineno;} + [ + [ LINE_TERMINATOR + | OPERAND_SEPARATOR + | PATTERN_SEPARATOR + | INSTRUCTION_SEPARATOR + | LETTER + | DIGIT + | SPACE + | OTHER + | '%' + ] + { *p++ = dot.t_attrib;} + ]* + { *p = '\0'; + if (onlyspace(buf)) strcpy(buf,"TRUE"); + } + CLOSE_BRACKET + SPACE* +; + +patterns + { int lin; + char *constr; + int np, nr; + } : +[ + { countpat++; + constr = (char *) 0; + fprintf(genc,"struct instr_descr pat%d[] = {\n", + countpat); + } + instruction_list(&np) + { if (np > patlen) patlen = np; + fputs("\n};\n\n",genc); + } + [ + constraint(&lin) + { /* Save the constraint, we need it later on */ + constr = malloc((unsigned)(strlen(buf)+1)); + strcpy(constr,buf); + } + ]? + PATTERN_SEPARATOR + { fprintf(genc,"struct instr_descr rep%d[] = {\n", + countpat); + } + replacement(&nr) + { fputs("\n};\n\n",genc);} + LINE_TERMINATOR + SPACE* + { addpattern(constr,lin,np,nr);} +]* + { printhashtable(); + printpatterns(); + fprintf(genh,"#define NRVARS %d\n",countid); + fprintf(genh,"#define NRPATTERNS %d\n",countpat); + fprintf(genh,"#define MIN_WINDOW_SIZE %d\n", + patlen+3); + fclose(genh); + } +; + +instruction_list(int *n;) : + instruction(1) + { *n = 1;} + [ + INSTRUCTION_SEPARATOR + { fputs(",\n",genc);} + SPACE* + instruction(0) + { *n += 1;} + ]* +; + +instruction(int opt;) + { int count = 0;} : + opcode(opt) + { if (strcmp(buf,"ANY") != 0) { + fprintf(genc,"\t{\"%s\", {",buf); + } + else fputs("\t{(char *) 0, {",genc); + count = 0; + } + [ + operand(' ') + { count = 1;} + [ + OPERAND_SEPARATOR + { count++;} + SPACE* + operand(',') + ]* + { if (count > maxoperand) { + error("Too many operands",""); + } + } + ]? + { while (count++ < maxoperand) { + fprintf(genc,"%c{\"\",-1,\"\"}",count == 1 ? ' ' : ','); + } + putc('}',genc); + putc('}',genc); + } +; + +opcode(int opt;) + { char *p = buf;} : + [ + [ LETTER + | DIGIT + | OTHER + ] + { *p++ = dot.t_attrib;} + ]+ + SPACE+ + { *p = '\0'; + if (opt) addtohashtable(buf,countpat); + } +; + +operand(int c;) + { register struct symtab *p = 0;} : + { fprintf(genc, "%c{\"", c);} + [ + identifier + { if (!p) { + p = findident(idbuf,LOOKING,&idtable); + if (p) fprintf(genc,"\",%d,\"",p->s_num); + else fputs(idbuf,genc); + } + else fputs(idbuf,genc); + } + | DIGIT + { putc(dot.t_attrib,genc);} + | OTHER + { putc(dot.t_attrib,genc);} + ]+ + { if (p) fputs("\"}",genc); + else fputs("\",0,\"\"}",genc); + } + SPACE* +; + +replacement (int *n;) + {register int i;} : + SPACE* + { *n = 0;} + [ + instruction(0) + { *n = 1;} + [ + INSTRUCTION_SEPARATOR + { fputs(",\n", genc);} + SPACE* + instruction(0) + { *n += 1;} + ]* + | /* empty replacement, but there must be a + * structure initializer anyway + */ + { fputs("\t{\"\", {",genc); + for (i = 0; i < maxoperand; i++) { + fprintf(genc, "%c{\"\",-1,\"\"}",i?',':' '); + } + fputs("}}",genc); + } + ] +; + + +identifier + { char *p = idbuf; } : + LETTER + { *p++ = dot.t_attrib;} + [ %while (1) + LETTER { *p++ = dot.t_attrib;} + | DIGIT { *p++ = dot.t_attrib;} + ]* + { *p = '\0';} +; + +separator : + '%' '%' SPACE* LINE_TERMINATOR +;