From 6f8e71c1b8400dc6be316f1770d885bde078cf1c Mon Sep 17 00:00:00 2001 From: Serge Vakulenko Date: Fri, 2 May 2014 22:00:30 -0700 Subject: [PATCH] Include files modified for compatibility with SmallerC. Fixed bug in C preprocessor: buffer size reduced to avoid allocation failure. Added option -v for smlrc. New example stdarg.c: a demo of function with variable arguments. --- Makefile | 6 +- include/stdarg.h | 55 ++- include/stdio.h | 9 +- include/unistd.h | 9 +- share/example/Makefile | 4 +- share/example/Makefile-host | 15 +- share/example/chello.c | 4 +- share/example/stdarg.c | 34 ++ src/cmd/cpp/Makefile | 22 +- src/cmd/cpp/cpp.c | 11 +- src/cmd/cpp/cpp.h | 11 +- src/cmd/cpp/scanner.l | 932 ------------------------------------ src/cmd/cpp/token.c | 4 +- src/cmd/smlrc/smlrc.c | 12 +- 14 files changed, 131 insertions(+), 997 deletions(-) create mode 100644 share/example/stdarg.c delete mode 100644 src/cmd/cpp/scanner.l diff --git a/Makefile b/Makefile index 7a82752..a95e0be 100644 --- a/Makefile +++ b/Makefile @@ -82,7 +82,7 @@ SHARE_FILES = share/re.help share/example/Makefile \ share/example/blkjack.bas share/example/hilow.bas \ share/example/stars.bas share/example/prime.scm \ share/example/fact.fth share/example/echo.S \ - $(wildcard share/smallc/*) + share/example/stdarg.c $(wildcard share/smallc/*) MANFILES = share/man/ share/man/cat1/ share/man/cat2/ share/man/cat3/ \ share/man/cat4/ share/man/cat5/ share/man/cat6/ share/man/cat7/ \ share/man/cat8/ $(wildcard share/man/cat?/*) @@ -194,11 +194,11 @@ else endif # TODO: make it relative to Target -installflash: +installflash: sudo pic32prog sys/pic32/fubarino/unix.hex # TODO: make it relative to Target -installboot: +installboot: sudo pic32prog sys/pic32/fubarino/bootloader.hex .profile: etc/root/dot.profile diff --git a/include/stdarg.h b/include/stdarg.h index 27ffdda..54710a5 100644 --- a/include/stdarg.h +++ b/include/stdarg.h @@ -4,32 +4,49 @@ #ifndef _STDARG_H #define _STDARG_H -/* Define __gnuc_va_list. */ +/* + * Define va_start, va_arg, va_end, va_copy. + */ +#if defined(__GNUC__) /* Gnu C */ +# define va_start(ap, last) __builtin_va_start((ap), last) +# define va_arg(ap, type) __builtin_va_arg((ap), type) +# define va_end(ap) __builtin_va_end((ap)) +# define va_copy(dest, src) __builtin_va_copy((dest), (src)) +#elif defined(__PCC__) /* PCC */ +# define va_start(ap, last) __builtin_stdarg_start((ap), last) +# define va_arg(ap, type) __builtin_va_arg((ap), type) +# define va_end(ap) __builtin_va_end((ap)) +# define va_copy(dest, src) __builtin_va_copy((dest), (src)) -#ifdef __GNUC__ -# ifndef __GNUC_VA_LIST -# define __GNUC_VA_LIST - typedef __builtin_va_list __gnuc_va_list; -# endif -# define va_start(ap, last) __builtin_va_start((ap), last) +#else /* SmallerC, LCC */ +# define va_start(ap, last) (ap = ((char*)&(last) + \ + (((sizeof(last) + sizeof(int) - 1) / sizeof(int)) * sizeof(int)))) +# define va_arg(ap, type) ((type*)(ap += \ + sizeof(type) == sizeof(int) ? sizeof(type) : \ + (-(int)(ap) & (sizeof(type) - 1)) + sizeof(type)))[-1] +# define va_end(ap) +# define va_copy(dest, src) (dest = (src)) #endif -#ifdef __PCC__ -# define va_start(ap, last) __builtin_stdarg_start((ap), last) -#endif -#define va_arg(ap, type) __builtin_va_arg((ap), type) -#define va_end(ap) __builtin_va_end((ap)) -#define va_copy(dest, src) __builtin_va_copy((dest), (src)) - +/* + * Define va_list. + */ #ifndef _VA_LIST_T -#define _VA_LIST_T -#ifdef __GNUC__ +# define _VA_LIST_T +# if defined(__GNUC__) || defined(__PCC__) typedef __builtin_va_list va_list; +# else + typedef char *va_list; +# endif #endif -#ifdef __SMALLER_C__ - typedef int *va_list; -#endif + +/* + * Define __gnuc_va_list. + */ +#if defined(__GNUC__) && !defined(__GNUC_VA_LIST) +# define __GNUC_VA_LIST + typedef __builtin_va_list __gnuc_va_list; #endif #endif /* not _STDARG_H */ diff --git a/include/stdio.h b/include/stdio.h index 97e47a5..bae653e 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -110,7 +110,12 @@ int scanf (const char *, ...); int sscanf (const char *, const char *, ...); #ifndef _VA_LIST_ -#define va_list __builtin_va_list /* For GCC */ +# ifdef __GNUC__ +# define va_list __builtin_va_list /* For Gnu C */ +# endif +# ifdef __SMALLER_C__ +# define va_list char * /* For Smaller C */ +# endif #endif int vfprintf (FILE *, const char *, va_list); @@ -126,7 +131,7 @@ int _doprnt (const char *, va_list, FILE *); int _doscan (FILE *, const char *, va_list); #ifndef _VA_LIST_ -#undef va_list +# undef va_list #endif void perror (const char *); diff --git a/include/unistd.h b/include/unistd.h index e16b28e..0ff1ed1 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -143,7 +143,12 @@ extern char *optarg; /* getopt(3) external variables */ extern int opterr, optind, optopt; #ifndef _VA_LIST_ -#define va_list __builtin_va_list /* For GCC */ +# ifdef __GNUC__ +# define va_list __builtin_va_list /* For Gnu C */ +# endif +# ifdef __SMALLER_C__ +# define va_list char * /* For Smaller C */ +# endif #endif void err (int eval, const char *fmt, ...); @@ -156,6 +161,6 @@ void vwarn (const char *fmt, va_list ap); void vwarnx (const char *fmt, va_list ap); #ifndef _VA_LIST_ -#undef va_list +# undef va_list #endif #endif /* !_UNISTD_H_ */ diff --git a/share/example/Makefile b/share/example/Makefile index 97b9a6d..065dd8f 100644 --- a/share/example/Makefile +++ b/share/example/Makefile @@ -1,5 +1,5 @@ -all: ashello echo +all: ashello echo chello ashello: ashello.o $(LD) ashello.o -o $@ @@ -11,4 +11,4 @@ echo: echo.o $(LD) $@.o -o $@ clean: - rm -f *.o ashello echo *.dis *~ + rm -f *.o ashello echo chello *.dis *~ diff --git a/share/example/Makefile-host b/share/example/Makefile-host index b18e867..1f4f425 100644 --- a/share/example/Makefile-host +++ b/share/example/Makefile-host @@ -5,13 +5,13 @@ CFLAGS += -Werror ASFLAGS += -DCROSS ASLDFLAGS = --oformat=elf32-tradlittlemips -N -nostartfiles -T $(TOPSRC)/src/elf32-mips.ld -all: hello cplus +all: chello cplus echo stdarg -hello: hello.o - ${CC} ${LDFLAGS} -o hello.elf hello.o ${LIBS} - ${OBJDUMP} -S hello.elf > hello.dis - ${SIZE} hello.elf - ${ELF2AOUT} hello.elf $@ +chello: chello.o + ${CC} ${LDFLAGS} -o chello.elf chello.o ${LIBS} + ${OBJDUMP} -S chello.elf > chello.dis + ${SIZE} chello.elf + ${ELF2AOUT} chello.elf $@ cplus: cplus.o ${CXX} ${LDFLAGS} -nostdlib -o cplus.elf cplus.o ${LIBS} @@ -24,7 +24,6 @@ echo: echo.o ${OBJDUMP} -S $@.elf > $@.dis ${SIZE} $@.elf ${ELF2AOUT} $@.elf $@ - ./aout $@ > $@.dis clean: - rm -f *.o *.elf ${MAN} hello cplus *.elf *.dis tags *~ + rm -f *.o *.elf ${MAN} chello cplus echo stdarg *.elf *.dis tags *~ diff --git a/share/example/chello.c b/share/example/chello.c index 14d9b7d..4634ab5 100644 --- a/share/example/chello.c +++ b/share/example/chello.c @@ -2,6 +2,6 @@ int main() { - printf ("Hello, C World!\n"); - return 0; + printf ("Hello, C World!\n"); + return 0; } diff --git a/share/example/stdarg.c b/share/example/stdarg.c new file mode 100644 index 0000000..ac0c53d --- /dev/null +++ b/share/example/stdarg.c @@ -0,0 +1,34 @@ +#include +#include + +void print(char *fmt, ...) +{ + va_list ap; + int d; + char c, *s; + + va_start(ap, fmt); + while (*fmt) { + switch (*fmt++) { + case 's': /* string */ + s = va_arg(ap, char*); + printf("string %s\n", s); + break; + case 'd': /* int */ + d = va_arg(ap, int); + printf("int %d\n", d); + break; + case 'c': /* char */ + c = va_arg(ap, int); + printf("char %c\n", c); + break; + } + } + va_end(ap); +} + +int main() +{ + print("sdcsdc", "abracadabra", 12345, 'Z', "foo", 365, '%'); + return 0; +} diff --git a/src/cmd/cpp/Makefile b/src/cmd/cpp/Makefile index 6366aca..5467708 100644 --- a/src/cmd/cpp/Makefile +++ b/src/cmd/cpp/Makefile @@ -24,7 +24,7 @@ $(MAN): ${MANSRC} ${MANROFF} $< > $@ clean: - rm -f *.o *.0 *.elf cpp *.elf *.dis tags *~ lex.yy.c y.tab.[ch] tests/run* + rm -f *.o *.0 *.elf cpp *.dis tags *~ lex.yy.c y.tab.[ch] tests/run* install: all install cpp $(DESTDIR)/bin/ @@ -41,23 +41,23 @@ cpy.o y.tab.h: cpy.y $(CC) $(DEFS) $(CPPFLAGS) $(CFLAGS) -c -o cpy.o y.tab.c test: - ./cpp.elf < tests/test1 > tests/run1 + ./cpp < tests/test1 > tests/run1 cmp tests/run1 tests/res1 - ./cpp.elf < tests/test2 > tests/run2 + ./cpp < tests/test2 > tests/run2 cmp tests/run2 tests/res2 - ./cpp.elf < tests/test3 > tests/run3 + ./cpp < tests/test3 > tests/run3 cmp tests/run3 tests/res3 - ./cpp.elf < tests/test4 > tests/run4 + ./cpp < tests/test4 > tests/run4 cmp tests/run4 tests/res4 - ./cpp.elf < tests/test5 > tests/run5 + ./cpp < tests/test5 > tests/run5 cmp tests/run5 tests/res5 - ./cpp.elf < tests/test6 > tests/run6 + ./cpp < tests/test6 > tests/run6 cmp tests/run6 tests/res6 - ./cpp.elf < tests/test7 > tests/run7 + ./cpp < tests/test7 > tests/run7 cmp tests/run7 tests/res7 - ./cpp.elf < tests/test8 > tests/run8 + ./cpp < tests/test8 > tests/run8 cmp tests/run8 tests/res8 - ./cpp.elf < tests/test9 > tests/run9 + ./cpp < tests/test9 > tests/run9 cmp tests/run9 tests/res9 - ./cpp.elf < tests/test10 > tests/run10 + ./cpp < tests/test10 > tests/run10 cmp tests/run10 tests/res10 diff --git a/src/cmd/cpp/cpp.c b/src/cmd/cpp/cpp.c index 4c9cd19..94ca6f7 100644 --- a/src/cmd/cpp/cpp.c +++ b/src/cmd/cpp/cpp.c @@ -350,7 +350,8 @@ addidir(char *idir, struct incs **ww) return; ww = &w->next; } - if ((w = calloc(sizeof(struct incs), 1)) == NULL) + w = calloc(sizeof(struct incs), 1); + if (w == NULL) error("couldn't add path %s", idir); w->dir = (uchar *)idir; w->dev = st.st_dev; @@ -1310,14 +1311,18 @@ expdef(const uchar *vp, struct recur *rp, int gotwarn) int ellips = 0, shot = gotwarn; DPRINT(("expdef rp %s\n", (rp ? (const char *)rp->sp->namep : ""))); - if ((c = sloscan()) != '(') + c = sloscan(); + if (c != '(') error("got %c, expected (", c); + if (vp[1] == VARG) { narg = *vp--; ellips = 1; } else narg = vp[1]; - if ((args = malloc(sizeof(uchar *) * (narg+ellips))) == NULL) + + args = malloc(sizeof(uchar *) * (narg+ellips)); + if (args == NULL) error("expdef: out of mem"); /* diff --git a/src/cmd/cpp/cpp.h b/src/cmd/cpp/cpp.h index 905cbd2..1356dd8 100644 --- a/src/cmd/cpp/cpp.h +++ b/src/cmd/cpp/cpp.h @@ -58,7 +58,7 @@ extern int ofd; #define ENTER 1 /* buffer used internally */ -#define CPPBUF BUFSIZ +#define CPPBUF 512 #define NAMEMAX CPPBUF /* currently pushbackbuffer */ @@ -138,13 +138,8 @@ void line(void); uchar *sheap(const char *fmt, ...); void xwarning(uchar *); void xerror(uchar *); -#ifdef HAVE_CPP_VARARG_MACRO_GCC -#define warning(...) xwarning(sheap(__VA_ARGS__)) -#define error(...) xerror(sheap(__VA_ARGS__)) -#else -#define warning printf -#define error printf -#endif +#define warning(args...) xwarning(sheap(args)) +#define error(args...) xerror(sheap(args)) void expmac(struct recur *); int cinput(void); void getcmnt(void); diff --git a/src/cmd/cpp/scanner.l b/src/cmd/cpp/scanner.l deleted file mode 100644 index cfe5845..0000000 --- a/src/cmd/cpp/scanner.l +++ /dev/null @@ -1,932 +0,0 @@ -%{ -/* - * Copyright (c) 2004 Anders Magnusson. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include -#include -#include -#include -#include -#include - -#include "compat.h" -#include "cpp.h" -#include "y.tab.h" -%} - -%{ -static void cvtdig(int rad); -static int charcon(uchar *); -static void elsestmt(void); -static void ifdefstmt(void); -static void ifndefstmt(void); -static void endifstmt(void); -static void ifstmt(void); -static void cpperror(void); -static void pragmastmt(void); -static void undefstmt(void); -static void cpperror(void); -static void elifstmt(void); -static void storepb(void); -static void badop(const char *); -void include(void); -void define(void); - -extern int yyget_lineno (void); -extern void yyset_lineno (int); - -static int inch(void); - -static int scale, gotdef, contr; -int inif; - -#ifdef FLEX_SCANNER /* should be set by autoconf instead */ -static int -yyinput(char *b, int m) -{ - int c, i; - - for (i = 0; i < m; i++) { - if ((c = inch()) < 0) - break; - *b++ = c; - if (c == '\n') { - i++; - break; - } - } - return i; -} -#undef YY_INPUT -#undef YY_BUF_SIZE -#define YY_BUF_SIZE (8*65536) -#define YY_INPUT(b,r,m) (r = yyinput(b, m)) -#ifdef HAVE_CPP_VARARG_MACRO_GCC -#define fprintf(x, ...) error(__VA_ARGS__) -#endif -#define ECHO putstr((uchar *)yytext) -#undef fileno -#define fileno(x) 0 - -#if YY_FLEX_SUBMINOR_VERSION >= 31 -/* Hack to avoid unnecessary warnings */ -FILE *yyget_in (void); -FILE *yyget_out (void); -int yyget_leng (void); -char *yyget_text (void); -void yyset_in (FILE * in_str ); -void yyset_out (FILE * out_str ); -int yyget_debug (void); -void yyset_debug (int bdebug ); -int yylex_destroy (void); -#endif -#else /* Assume lex here */ -#undef input -#undef unput -#define input() inch() -#define unput(ch) unch(ch) -#endif -#define PRTOUT(x) if (YYSTATE || slow) return x; if (!flslvl) putstr((uchar *)yytext); -/* protection against recursion in #include */ -#define MAX_INCLEVEL 100 -static int inclevel; -%} - -D [0-9] -L [a-zA-Z_] -H [a-fA-F0-9] -E [Ee][+-]?{D}+ -FS (f|F|l|L) -IS (u|U|l|L)* -WS [\t ] - -%s IFR CONTR DEF COMMENT - -%% - -"\n" { int os = YYSTATE; - if (os != IFR) - BEGIN 0; - ifiles->lineno++; - if (flslvl == 0) { - if (ifiles->lineno == 1) - prtline(); - else - putch('\n'); - } - if ((os != 0 || slow) && !contr) - return '\n'; - contr = 0; - } - -"\r" { ; /* Ignore CR's */ } - -"++" { badop("++"); } -"--" { badop("--"); } -"==" { return EQ; } -"!=" { return NE; } -"<=" { return LE; } -"<<" { return LS; } -">>" { return RS; } -">=" { return GE; } -"||" { return OROR; } -"&&" { return ANDAND; } -"defined" { int p, c; - gotdef = 1; - if ((p = c = yylex()) == '(') - c = yylex(); - if (c != IDENT || (p != IDENT && p != '(')) - error("syntax error"); - if (p == '(' && yylex() != ')') - error("syntax error"); - return NUMBER; - } - -{WS}+ { ; } -{L}({L}|{D})* { - yylval.node.op = NUMBER; - if (gotdef) { - yylval.node.nd_val - = lookup((uchar *)yytext, FIND) != 0; - gotdef = 0; - return IDENT; - } - yylval.node.nd_val = 0; - return NUMBER; - } - -[0-9][0-9]* { - if (slow && !YYSTATE) - return IDENT; - scale = yytext[0] == '0' ? 8 : 10; - goto num; - } - -0[xX]{H}+{IS}? { scale = 16; - num: if (YYSTATE == IFR) - cvtdig(scale); - PRTOUT(NUMBER); - } -0{D}+{IS}? { scale = 8; goto num; } -{D}+{IS}? { scale = 10; goto num; } -'(\\.|[^\\'])+' { - if (YYSTATE || slow) { - yylval.node.op = NUMBER; - yylval.node.nd_val = charcon((uchar *)yytext); - return (NUMBER); - } - if (tflag) - yyless(1); - if (!flslvl) - putstr((uchar *)yytext); - } - -. { return yytext[0]; } - -{D}+{E}{FS}? { PRTOUT(FPOINT); } -{D}*"."{D}+({E})?{FS}? { PRTOUT(FPOINT); } -{D}+"."{D}*({E})?{FS}? { PRTOUT(FPOINT); } - -^{WS}*#{WS}* { extern int inmac; - - if (inmac) - error("preprocessor directive found " - "while expanding macro"); - contr = 1; - BEGIN CONTR; - } -{WS}+ { PRTOUT(WSPACE); } - -"ifndef" { contr = 0; ifndefstmt(); } -"ifdef" { contr = 0; ifdefstmt(); } -"if" { contr = 0; storepb(); BEGIN IFR; ifstmt(); BEGIN 0; } -"include" { contr = 0; BEGIN 0; include(); prtline(); } -"else" { contr = 0; elsestmt(); } -"endif" { contr = 0; endifstmt(); } -"error" { contr = 0; if (slow) return IDENT; cpperror(); BEGIN 0; } -"define" { contr = 0; BEGIN DEF; define(); BEGIN 0; } -"undef" { contr = 0; if (slow) return IDENT; undefstmt(); } -"line" { contr = 0; storepb(); BEGIN 0; line(); } -"pragma" { contr = 0; pragmastmt(); BEGIN 0; } -"elif" { contr = 0; storepb(); BEGIN IFR; elifstmt(); BEGIN 0; } - - - -"//".*$ { /* if (tflag) yyless(..) */ - if (Cflag && !flslvl && !slow) - putstr((uchar *)yytext); - else if (!flslvl) - putch(' '); - } -"/*" { int c, wrn; - int prtcm = Cflag && !flslvl && !slow; - extern int readmac; - - if (Cflag && !flslvl && readmac) - return CMNT; - - if (prtcm) - putstr((uchar *)yytext); - wrn = 0; - more: while ((c = input()) && c != '*') { - if (c == '\n') - putch(c), ifiles->lineno++; - else if (c == 1) /* WARN */ - wrn = 1; - else if (prtcm) - putch(c); - } - if (c == 0) - return 0; - if (prtcm) - putch(c); - if ((c = input()) && c != '/') { - unput(c); - goto more; - } - if (prtcm) - putch(c); - if (c == 0) - return 0; - if (!tflag && !Cflag && !flslvl) - unput(' '); - if (wrn) - unput(1); - } - -"##" { return CONCAT; } -"#" { return MKSTR; } -"..." { return ELLIPS; } -"__VA_ARGS__" { return VA_ARGS; } - -L?\"(\\.|[^\\"])*\" { PRTOUT(STRING); } -[a-zA-Z_0-9]+ { /* {L}({L}|{D})* */ - struct symtab *nl; - if (slow) - return IDENT; - if (YYSTATE == CONTR) { - if (flslvl == 0) { - /*error("undefined control");*/ - while (input() != '\n') - ; - unput('\n'); - BEGIN 0; - goto xx; - } else { - BEGIN 0; /* do nothing */ - } - } - if (flslvl) { - ; /* do nothing */ - } else if (isdigit((int)yytext[0]) == 0 && - (nl = lookup((uchar *)yytext, FIND)) != 0) { - uchar *op = stringbuf; - putstr(gotident(nl)); - stringbuf = op; - } else - putstr((uchar *)yytext); - xx: ; - } - -. { - if (contr) { - while (input() != '\n') - ; - unput('\n'); - BEGIN 0; - contr = 0; - goto yy; - } - if (YYSTATE || slow) - return yytext[0]; - if (yytext[0] == 6) { /* PRAGS */ - uchar *obp = stringbuf; - extern uchar *prtprag(uchar *); - *stringbuf++ = yytext[0]; - do { - *stringbuf = input(); - } while (*stringbuf++ != 14); - prtprag(obp); - stringbuf = obp; - } else { - PRTOUT(yytext[0]); - } - yy:; - } - -%% - -uchar *yyp, yybuf[CPPBUF]; - -int yylex(void); -int yywrap(void); - -static int -inpch(void) -{ - int len; - - if (ifiles->curptr < ifiles->maxread) - return *ifiles->curptr++; - - if ((len = read(ifiles->infil, ifiles->buffer, CPPBUF)) < 0) - error("read error on file %s", ifiles->orgfn); - if (len == 0) - return -1; - ifiles->curptr = ifiles->buffer; - ifiles->maxread = ifiles->buffer + len; - return inpch(); -} - -#define unch(c) *--ifiles->curptr = c - -static int -inch(void) -{ - int c; - -again: switch (c = inpch()) { - case '\\': /* continued lines */ -msdos: if ((c = inpch()) == '\n') { - ifiles->lineno++; - putch('\n'); - goto again; - } else if (c == '\r') - goto msdos; - unch(c); - return '\\'; - case '?': /* trigraphs */ - if ((c = inpch()) != '?') { - unch(c); - return '?'; - } - switch (c = inpch()) { - case '=': c = '#'; break; - case '(': c = '['; break; - case ')': c = ']'; break; - case '<': c = '{'; break; - case '>': c = '}'; break; - case '/': c = '\\'; break; - case '\'': c = '^'; break; - case '!': c = '|'; break; - case '-': c = '~'; break; - default: - unch(c); - unch('?'); - return '?'; - } - unch(c); - goto again; - default: - return c; - } -} - -/* - * Let the command-line args be faked defines at beginning of file. - */ -static void -prinit(struct initar *it, struct includ *ic) -{ - char *a, *pre, *post; - - if (it->next) - prinit(it->next, ic); - pre = post = NULL; /* XXX gcc */ - switch (it->type) { - case 'D': - pre = "#define "; - if ((a = strchr(it->str, '=')) != NULL) { - *a = ' '; - post = "\n"; - } else - post = " 1\n"; - break; - case 'U': - pre = "#undef "; - post = "\n"; - break; - case 'i': - pre = "#include \""; - post = "\"\n"; - break; - default: - error("prinit"); - } - strlcat((char *)ic->buffer, pre, CPPBUF+1); - strlcat((char *)ic->buffer, it->str, CPPBUF+1); - if (strlcat((char *)ic->buffer, post, CPPBUF+1) >= CPPBUF+1) - error("line exceeds buffer size"); - - ic->lineno--; - while (*ic->maxread) - ic->maxread++; -} - -/* - * A new file included. - * If ifiles == NULL, this is the first file and already opened (stdin). - * Return 0 on success, -1 if file to be included is not found. - */ -int -pushfile(uchar *file) -{ - extern struct initar *initar; - struct includ ibuf; - struct includ *ic; - int c, otrulvl; - - ic = &ibuf; - ic->next = ifiles; - - slow = 0; - if (file != NULL) { - if ((ic->infil = open((char *)file, O_RDONLY)) < 0) - return -1; - ic->orgfn = ic->fname = file; - if (++inclevel > MAX_INCLEVEL) - error("Limit for nested includes exceeded"); - } else { - ic->infil = 0; - ic->orgfn = ic->fname = (uchar *)""; - } - ic->buffer = ic->bbuf+NAMEMAX; - ic->curptr = ic->buffer; - ifiles = ic; - ic->lineno = 1; - ic->maxread = ic->curptr; - prtline(); - if (initar) { - *ic->maxread = 0; - prinit(initar, ic); - if (dMflag) - write(ofd, ic->buffer, strlen((char *)ic->buffer)); - initar = NULL; - } - - otrulvl = trulvl; - - if ((c = yylex()) != 0) - error("yylex returned %d", c); - - if (otrulvl != trulvl || flslvl) - error("unterminated conditional"); - - ifiles = ic->next; - close(ic->infil); - inclevel--; - return 0; -} - -/* - * Print current position to output file. - */ -void -prtline() -{ - uchar *s, *os = stringbuf; - - if (Mflag) { - if (dMflag) - return; /* no output */ - if (ifiles->lineno == 1) { - s = sheap("%s: %s\n", Mfile, ifiles->fname); - write(ofd, s, strlen((char *)s)); - } - } else if (!Pflag) - putstr(sheap("# %d \"%s\"\n", ifiles->lineno, ifiles->fname)); - stringbuf = os; -} - -void -cunput(int c) -{ -#ifdef CPP_DEBUG - extern int dflag; - if (dflag)printf(": '%c'(%d)", c > 31 ? c : ' ', c); -#endif - unput(c); -} - -int yywrap(void) { return 1; } - -static int -dig2num(int c) -{ - if (c >= 'a') - c = c - 'a' + 10; - else if (c >= 'A') - c = c - 'A' + 10; - else - c = c - '0'; - return c; -} - -/* - * Convert string numbers to unsigned long long and check overflow. - */ -static void -cvtdig(int rad) -{ - unsigned long long rv = 0; - unsigned long long rv2 = 0; - char *y = yytext; - int c; - - c = *y++; - if (rad == 16) - y++; - while (isxdigit(c)) { - rv = rv * rad + dig2num(c); - /* check overflow */ - if (rv / rad < rv2) - error("Constant \"%s\" is out of range", yytext); - rv2 = rv; - c = *y++; - } - y--; - while (*y == 'l' || *y == 'L') - y++; - yylval.node.op = *y == 'u' || *y == 'U' ? UNUMBER : NUMBER; - yylval.node.nd_uval = rv; - if ((rad == 8 || rad == 16) && yylval.node.nd_val < 0) - yylval.node.op = UNUMBER; - if (yylval.node.op == NUMBER && yylval.node.nd_val < 0) - /* too large for signed */ - error("Constant \"%s\" is out of range", yytext); -} - -static int -charcon(uchar *p) -{ - int val, c; - - p++; /* skip first ' */ - val = 0; - if (*p++ == '\\') { - switch (*p++) { - case 'a': val = '\a'; break; - case 'b': val = '\b'; break; - case 'f': val = '\f'; break; - case 'n': val = '\n'; break; - case 'r': val = '\r'; break; - case 't': val = '\t'; break; - case 'v': val = '\v'; break; - case '\"': val = '\"'; break; - case '\'': val = '\''; break; - case '\\': val = '\\'; break; - case 'x': - while (isxdigit(c = *p)) { - val = val * 16 + dig2num(c); - p++; - } - break; - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': - p--; - while (isdigit(c = *p)) { - val = val * 8 + (c - '0'); - p++; - } - break; - default: val = p[-1]; - } - - } else - val = p[-1]; - return val; -} - -static void -chknl(int ignore) -{ - int t; - - slow = 1; - while ((t = yylex()) == WSPACE) - ; - if (t != '\n') { - if (ignore) { - warning("newline expected, got \"%s\"", yytext); - /* ignore rest of line */ - while ((t = yylex()) && t != '\n') - ; - } - else - error("newline expected, got \"%s\"", yytext); - } - slow = 0; -} - -static void -elsestmt(void) -{ - if (flslvl) { - if (elflvl > trulvl) - ; - else if (--flslvl!=0) { - flslvl++; - } else { - trulvl++; - prtline(); - } - } else if (trulvl) { - flslvl++; - trulvl--; - } else - error("If-less else"); - if (elslvl==trulvl+flslvl) - error("Too many else"); - elslvl=trulvl+flslvl; - chknl(1); -} - -static void -ifdefstmt(void) -{ - int t; - - if (flslvl) { - /* just ignore the rest of the line */ - while (input() != '\n') - ; - unput('\n'); - yylex(); - flslvl++; - return; - } - slow = 1; - do - t = yylex(); - while (t == WSPACE); - if (t != IDENT) - error("bad ifdef"); - slow = 0; - if (flslvl == 0 && lookup((uchar *)yytext, FIND) != 0) - trulvl++; - else - flslvl++; - chknl(0); -} - -static void -ifndefstmt(void) -{ - int t; - - slow = 1; - do - t = yylex(); - while (t == WSPACE); - if (t != IDENT) - error("bad ifndef"); - slow = 0; - if (flslvl == 0 && lookup((uchar *)yytext, FIND) == 0) - trulvl++; - else - flslvl++; - chknl(0); -} - -static void -endifstmt(void) -{ - if (flslvl) { - flslvl--; - if (flslvl == 0) - prtline(); - } else if (trulvl) - trulvl--; - else - error("If-less endif"); - if (flslvl == 0) - elflvl = 0; - elslvl = 0; - chknl(1); -} - -/* - * Note! Ugly! - * Walk over the string s and search for defined, and replace it with - * spaces and a 1 or 0. - */ -static void -fixdefined(uchar *s) -{ - uchar *bc, oc; - - for (; *s; s++) { - if (*s != 'd') - continue; - if (memcmp(s, "defined", 7)) - continue; - /* Ok, got defined, can scratch it now */ - memset(s, ' ', 7); - s += 7; -#define WSARG(x) (x == ' ' || x == '\t') - if (*s != '(' && !WSARG(*s)) - continue; - while (WSARG(*s)) - s++; - if (*s == '(') - s++; - while (WSARG(*s)) - s++; -#define IDARG(x) ((x>= 'A' && x <= 'Z') || (x >= 'a' && x <= 'z') || (x == '_')) -#define NUMARG(x) (x >= '0' && x <= '9') - if (!IDARG(*s)) - error("bad defined arg"); - bc = s; - while (IDARG(*s) || NUMARG(*s)) - s++; - oc = *s; - *s = 0; - *bc = (lookup(bc, FIND) != 0) + '0'; - memset(bc+1, ' ', s-bc-1); - *s = oc; - } -} - -/* - * get the full line of identifiers after an #if, pushback a WARN and - * the line and prepare for expmac() to expand. - * This is done before switching state. When expmac is finished, - * pushback the expanded line, change state and call yyparse. - */ -static void -storepb(void) -{ - uchar *opb = stringbuf; - int c; - - while ((c = input()) != '\n') { - if (c == '/') { - if ((c = input()) == '*') { - /* ignore comments here whatsoever */ - uchar *g = stringbuf; - getcmnt(); - stringbuf = g; - continue; - } else if (c == '/') { - while ((c = input()) && c != '\n') - ; - break; - } - unput(c); - c = '/'; - } - savch(c); - } - cunput('\n'); - savch(0); - fixdefined(opb); /* XXX can fail if #line? */ - cunput(1); /* WARN XXX */ - unpstr(opb); - stringbuf = opb; - slow = 1; - expmac(NULL); - slow = 0; - /* line now expanded */ - while (stringbuf > opb) - cunput(*--stringbuf); -} - -static void -ifstmt(void) -{ - if (flslvl == 0) { - slow = 1; - if (yyparse()) - ++trulvl; - else - ++flslvl; - slow = 0; - } else - ++flslvl; -} - -static void -elifstmt(void) -{ - if (flslvl == 0) - elflvl = trulvl; - if (flslvl) { - if (elflvl > trulvl) - ; - else if (--flslvl!=0) - ++flslvl; - else { - slow = 1; - if (yyparse()) { - ++trulvl; - prtline(); - } else - ++flslvl; - slow = 0; - } - } else if (trulvl) { - ++flslvl; - --trulvl; - } else - error("If-less elif"); -} - -static uchar * -svinp(void) -{ - int c; - uchar *cp = stringbuf; - - while ((c = input()) && c != '\n') - savch(c); - savch('\n'); - savch(0); - BEGIN 0; - return cp; -} - -static void -cpperror(void) -{ - uchar *cp; - int c; - - if (flslvl) - return; - c = yylex(); - if (c != WSPACE && c != '\n') - error("bad error"); - cp = svinp(); - if (flslvl) - stringbuf = cp; - else - error("%s", cp); -} - -static void -undefstmt(void) -{ - struct symtab *np; - - slow = 1; - if (yylex() != WSPACE || yylex() != IDENT) - error("bad undef"); - if (flslvl == 0 && (np = lookup((uchar *)yytext, FIND))) - np->value = 0; - slow = 0; - chknl(0); -} - -static void -pragmastmt(void) -{ - int c; - - slow = 1; - if (yylex() != WSPACE) - error("bad pragma"); - if (!flslvl) - putstr((uchar *)"#pragma "); - do { - c = input(); - if (!flslvl) - putch(c); /* Do arg expansion instead? */ - } while (c && c != '\n'); - ifiles->lineno++; - prtline(); - slow = 0; -} - -static void -badop(const char *op) -{ - error("invalid operator in preprocessor expression: %s", op); -} - -int -cinput() -{ - return input(); -} diff --git a/src/cmd/cpp/token.c b/src/cmd/cpp/token.c index d0f387f..aeac691 100644 --- a/src/cmd/cpp/token.c +++ b/src/cmd/cpp/token.c @@ -767,8 +767,10 @@ pushfile(const uchar *file, const uchar *fn, int idx, void *incs) if (file != NULL) { ic->infil = open((const char *)file, O_RDONLY); - if (ic->infil < 0) + if (ic->infil < 0) { + free(ic); return -1; + } ic->orgfn = ic->fname = file; if (++inclevel > MAX_INCLEVEL) error("Limit for nested includes exceeded"); diff --git a/src/cmd/smlrc/smlrc.c b/src/cmd/smlrc/smlrc.c index c3e4b2b..977fc13 100644 --- a/src/cmd/smlrc/smlrc.c +++ b/src/cmd/smlrc/smlrc.c @@ -1792,7 +1792,7 @@ int GetToken(void) // Ignore gcc-style #line's flags, if any while (!strchr("\r\n", *p)) ShiftCharN(1); - + LineNo = line - 1; // "line" is the number of the next line LinePos = 1; @@ -6122,7 +6122,7 @@ int ParseDecl(int tok, unsigned structInfo[4], int cast, int label) #ifndef NO_TYPEDEF_ENUM typeDef | #endif - Static) && + Static) && !strcmp(IdentTable + SyntaxStack[lastSyntaxPtr][1], "") && tok == ';') { @@ -7593,6 +7593,10 @@ int main(int argc, char** argv) verbose = 1; continue; } + else if (!strcmp(argv[i], "-v")) + { + continue; + } #ifndef NO_PREPROCESSOR else if (!strcmp(argv[i], "-I")) { @@ -7661,7 +7665,7 @@ int main(int argc, char** argv) LinePoss[0] = LinePos; FileCnt++; continue; - } + } else if (FileCnt == 1 && OutFile == NULL) { // This should be the output file name @@ -7669,7 +7673,7 @@ int main(int argc, char** argv) //error("Cannot open output file \"%s\"\n", argv[i]); errorFile(argv[i]); continue; - } + } error("Invalid or unsupported command line option\n"); }