scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit fcec548cff5349d73e1c64a99aee77ce2331858d
parent 10561bd468a51e001fea28922b18d172d832d72b
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Tue, 31 May 2022 08:14:52 +0200

Merge remote-tracking branch 'origin/master'

Diffstat:
Minclude/bits/darwin/sys.h | 4+++-
Minclude/bits/dragonfly/sys.h | 4+++-
Minclude/bits/linux/sys.h | 2++
Minclude/bits/netbsd/sys.h | 4+++-
Minclude/bits/openbsd/sys.h | 4+++-
Minclude/scc/scc/syscrts.def.h | 6+++++-
Msrc/cmd/cc/cc1/cc1.h | 3+++
Msrc/cmd/cc/cc1/cpp.c | 103+++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------
Msrc/cmd/cc/cc1/lex.c | 22++--------------------
Msrc/cmd/cc/posix/cc.c | 8+++++---
Msrc/libc/arch/posix/Makefile | 1+
Asrc/libc/arch/posix/tmpfile.c | 21+++++++++++++++++++++
Msrc/libc/objs/amd64-linux.mk | 1+
Msrc/libc/objs/amd64-netbsd.mk | 1+
Msrc/libc/objs/amd64-openbsd.mk | 1+
Msrc/libc/stdio/_fpopen.c | 11++++++++---
16 files changed, 136 insertions(+), 60 deletions(-)

diff --git a/include/bits/darwin/sys.h b/include/bits/darwin/sys.h @@ -3,9 +3,11 @@ #define O_RDWR 0x00000002 #define O_ACCMODE 0x00000003 +#define O_CLOEXEC 0x00400000 +#define O_EXCL 0x00000800 #define O_TRUNC 0x00000400 -#define O_APPEND 0x00000008 #define O_CREAT 0x00000200 +#define O_APPEND 0x00000008 #define AT_FDCWD -100 #define CLOCKS_PER_SEC ((clock_t) 1000000) diff --git a/include/bits/dragonfly/sys.h b/include/bits/dragonfly/sys.h @@ -3,9 +3,11 @@ #define O_RDWR 0x00000002 #define O_ACCMODE 0x00000003 +#define O_CLOEXEC 0x00400000 +#define O_EXCL 0x00000800 #define O_TRUNC 0x00000400 -#define O_APPEND 0x00000008 #define O_CREAT 0x00000200 +#define O_APPEND 0x00000008 #define AT_FDCWD -100 #define CLOCKS_PER_SEC ((clock_t) 128) diff --git a/include/bits/linux/sys.h b/include/bits/linux/sys.h @@ -3,8 +3,10 @@ #define O_RDWR 0x00000002 #define O_ACCMODE 0x00000003 +#define O_CLOEXEC 0x00080000 #define O_TRUNC 0x00000200 #define O_APPEND 0x00000400 +#define O_EXCL 0x00000080 #define O_CREAT 0x00000040 #define AT_FDCWD -100 diff --git a/include/bits/netbsd/sys.h b/include/bits/netbsd/sys.h @@ -3,9 +3,11 @@ #define O_RDWR 0x00000002 #define O_ACCMODE 0x00000003 +#define O_CLOEXEC 0x00400000 +#define O_EXCL 0x00000800 #define O_TRUNC 0x00000400 -#define O_APPEND 0x00000008 #define O_CREAT 0x00000200 +#define O_APPEND 0x00000008 #define AT_FDCWD -100 #define CLOCKS_PER_SEC ((clock_t) 100) diff --git a/include/bits/openbsd/sys.h b/include/bits/openbsd/sys.h @@ -3,9 +3,11 @@ #define O_RDWR 0x00000002 #define O_ACCMODE 0x00000003 +#define O_CLOEXEC 0x00010000 +#define O_EXCL 0x00000800 #define O_TRUNC 0x00000400 -#define O_APPEND 0x00000008 #define O_CREAT 0x00000200 +#define O_APPEND 0x00000008 #define AT_FDCWD -100 #define CLOCKS_PER_SEC ((clock_t) 100) diff --git a/include/scc/scc/syscrts.def.h b/include/scc/scc/syscrts.def.h @@ -1,5 +1,9 @@ /* configure below your system crts */ -char *syscrts[] = { +char *syscrtsb[] = { "%p/lib/scc/%a-%s/crt.o", NULL }; + +char *syscrtse[] = { + NULL +}; diff --git a/src/cmd/cc/cc1/cc1.h b/src/cmd/cc/cc1/cc1.h @@ -396,6 +396,7 @@ struct yystype { unsigned char token; }; +#ifdef NR_MACROARG struct macro { Symbol *sym; char *fname; @@ -404,7 +405,9 @@ struct macro { char *def; int bufsiz; int npars; + Symbol *hideset[NR_MACROARG]; }; +#endif #ifdef stdin struct input { diff --git a/src/cmd/cc/cc1/cpp.c b/src/cmd/cc/cc1/cpp.c @@ -28,7 +28,6 @@ defdefine(char *name, char *val, char *source) .name = name, .flags = SDECLARED, }; - Macro *mp; if (!val) val = ""; @@ -38,12 +37,9 @@ defdefine(char *name, char *val, char *source) } sprintf(buffer, fmt, name, val); - mp = newmacro(sym); - mp->buffer = buffer; - mp->fname = source; - lineno = ++ncmdlines; - addinput(IMACRO, mp, FAIL); + + addinput(IPARAM, buffer, FAIL); cpp(); delinput(); } @@ -120,6 +116,7 @@ parameter(Macro *mp) { int siz; char *s, *begin, *end; + Input *ip = input; begin = input->begin; for (;;) { @@ -131,6 +128,8 @@ parameter(Macro *mp) end = input->begin - 1; while (end > begin && isspace(end[-1])) --end; + while (begin < end && isspace(begin[0])) + ++begin; siz = end - begin; s = memcpy(xmalloc(siz+1), begin, siz); @@ -149,14 +148,15 @@ parsepars(Macro *mp) int n; if (mp->npars == -1) - return -1; - if (ahead() != '(' && mp->npars > 0) + return 1; + if (ahead() != '(') return 0; disexpand = 1; next(); n = 0; - if (ahead() == ')') { + + if (mp->npars == 0 && ahead() == ')') { next(); } else { do { @@ -164,6 +164,7 @@ parsepars(Macro *mp) mp->arglist[n] = parameter(mp); } while (++n < NR_MACROARG && yytoken == ','); } + if (yytoken != ')') error("incorrect macro function-alike invocation"); disexpand = 0; @@ -181,7 +182,7 @@ parsepars(Macro *mp) static int expandarg(char *arg, char *buf, int bufsiz) { - int siz, n; + int siz; char *s = buf; addinput(IPARAM, arg, FAIL); @@ -211,6 +212,11 @@ copymacro(Macro *mp) char *s, *p, *arg, *bp; int size, bufsiz; + if (mp->sym == symfile) + return sprintf(mp->buffer, "\"%s\" ", filenam); + if (mp->sym == symline) + return sprintf(mp->buffer, "%d ", lineno); + bp = mp->buffer; bufsiz = mp->bufsiz; for (s = mp->def; c = *s; ++s) { @@ -296,10 +302,45 @@ expansion_too_long: error("macro expansion of \"%s\" too long", mp->sym->name); } +static void +addhideset(Input *ip, Symbol *sym) +{ + Symbol **set; + Symbol **p; + + set = ip->macro->hideset; + for (p = set; p < &set[NR_MACROARG] && *p; ++p) { + if (*p == sym) + return; + } + + if (p == &set[NR_MACROARG]) + error("too complex macro expansion"); + + *p = sym; + DBG("MACRO Adding %s to hideset of %s", + sym->name, ip->macro->sym->name); +} + +static void +hide(Symbol *sym) +{ + DBG("SYM: hidding symbol %s %d", sym->name, sym->hide); + sym->hide = 1; +} + +static void +unhide(Symbol *sym) +{ + DBG("SYM: unhidding symbol %s %d", sym->name, sym->hide); + sym->hide = 0; +} + void delmacro(Macro *mp) { int i; + Symbol **p; if (!mp) return; @@ -308,6 +349,10 @@ delmacro(Macro *mp) for (i = 0; i < mp->npars; i++) free(mp->arglist[i]); } + + for (p = mp->hideset; p < &mp->hideset[NR_MACROARG] && *p; ++p) + unhide(*p); + free(mp->arglist); free(mp); } @@ -318,10 +363,9 @@ newmacro(Symbol *sym) Macro *mp; mp = xmalloc(sizeof(*mp)); + *mp = (Macro) {0}; mp->sym = sym; - mp->arglist = NULL; mp->def = sym->u.s + 3; - mp->npars = 0; if (sym->u.s) mp->npars = atoi(sym->u.s); @@ -331,9 +375,10 @@ newmacro(Symbol *sym) int expand(Symbol *sym) { - int elen; + int siz; Macro *mp; - char buffer[INPUTSIZ]; + Input *ip; + Symbol **p; DBG("MACRO '%s' detected disexpand=%d hide=%d", sym->name, disexpand, sym->hide); @@ -343,28 +388,28 @@ expand(Symbol *sym) mp = newmacro(sym); mp->fname = filenam; - mp->buffer = buffer; - mp->bufsiz = INPUTSIZ-1; - - if (sym == symfile) { - elen = sprintf(buffer, "\"%s\" ", filenam); - goto substitute; - } - if (sym == symline) { - elen = sprintf(buffer, "%d ", lineno); - goto substitute; - } if (!parsepars(mp)) { delmacro(mp); return 0; } - elen = copymacro(mp); -substitute: - buffer[elen] = '\0'; - DBG("MACRO '%s' expanded to :'%s'", mp->sym->name, buffer); addinput(IMACRO, mp, FAIL); + mp->buffer = input->line; + mp->bufsiz = INPUTSIZ-1; + + siz = copymacro(mp); + mp->buffer[siz] = '\0'; + + for (ip = input; ip; ip = ip->next) { + if ((ip->flags & ITYPE) == IMACRO) + addhideset(ip, sym); + } + + for (p = mp->hideset; p < &mp->hideset[NR_MACROARG] && *p; ++p) + hide(*p); + + DBG("MACRO '%s' expanded to :'%s'", mp->sym->name, mp->buffer); return 1; } diff --git a/src/cmd/cc/cc1/lex.c b/src/cmd/cc/cc1/lex.c @@ -48,22 +48,6 @@ setloc(char *fname, unsigned line) lineno = input->lineno = line; } -static void -hide(Symbol *sym) -{ - assert(sym->hide == 0); - sym->hide = 1; - DBG("SYM: hidding symbol %s %d", sym->name, sym->hide); -} - -static void -unhide(Symbol *sym) -{ - assert(sym->hide == 1); - DBG("SYM: unhidding symbol %s %d", sym->name, sym->hide); - sym->hide = 0; -} - int addinput(int type, void *arg, int fail) { @@ -84,8 +68,7 @@ addinput(int type, void *arg, int fail) sym = mp->sym; fname = mp->fname; buffer = mp->buffer; - hide(sym); - DBG("INPUT: macro %s expanded to '%s'", sym->name, buffer); + DBG("INPUT: expanding macro %s", sym->name); break; case IPARAM: fp = NULL; @@ -162,7 +145,7 @@ delinput(void) break; case IMACRO: DBG("INPUT: macro %s finished", ip->macro->sym->name); - unhide(ip->macro->sym); + delmacro(ip->macro); break; case IPARAM: DBG("INPUT: macro param finished"); @@ -175,7 +158,6 @@ delinput(void) } input = ip->next; - delmacro(ip->macro); free(ip->filenam); free(ip->line); free(ip); diff --git a/src/cmd/cc/posix/cc.c b/src/cmd/cc/posix/cc.c @@ -201,8 +201,8 @@ inittool(int tool) addarg(tool, "-L"); addarg(tool, path(syslibs[n])); } - for (n = 0; syscrts[n]; ++n) - addarg(tool, path(syscrts[n])); + for (n = 0; syscrtsb[n]; ++n) + addarg(tool, path(syscrtsb[n])); break; case AS: addarg(tool, "-o"); @@ -525,7 +525,7 @@ int main(int argc, char *argv[]) { struct items linkchain = { .n = 0, }; - int link; + int link, n; atexit(terminate); @@ -652,6 +652,8 @@ operand: if (link && !failure) { addarg(LD, xstrdup("-lc")); addarg(LD, xstrdup("-lcrt")); + for (n = 0; syscrtse[n]; ++n) + addarg(LD, path(syscrtse[n])); spawn(settool(LD, NULL, LAST_TOOL)); validatetools(); } diff --git a/src/libc/arch/posix/Makefile b/src/libc/arch/posix/Makefile @@ -15,6 +15,7 @@ OBJS=\ signal.$O\ system.$O\ time.$O\ + tmpfile.$O\ all: $(OBJS) diff --git a/src/libc/arch/posix/tmpfile.c b/src/libc/arch/posix/tmpfile.c @@ -0,0 +1,21 @@ +#include <stdio.h> + +#include "../../syscall.h" + +#undef tmpfile + +FILE * +tmpfile(void) +{ + char *fname; + FILE *fp; + + for (;;) { + if ((fname = tmpnam(NULL)) == NULL) + return NULL; + if ((fp = fopen(fname, "wt+")) == NULL) + continue; + _unlink(fname); + return fp; + } +} diff --git a/src/libc/objs/amd64-linux.mk b/src/libc/objs/amd64-linux.mk @@ -47,4 +47,5 @@ OBJS =\ arch/posix/signal.$O\ arch/posix/system.$O\ arch/posix/time.$O\ + arch/posix/tmpfile.$O\ string/strlen.$O\ diff --git a/src/libc/objs/amd64-netbsd.mk b/src/libc/objs/amd64-netbsd.mk @@ -39,4 +39,5 @@ OBJS =\ arch/posix/signal.$O\ arch/posix/system.$O\ arch/posix/time.$O\ + arch/posix/tmpfile.$O\ string/strlen.$O\ diff --git a/src/libc/objs/amd64-openbsd.mk b/src/libc/objs/amd64-openbsd.mk @@ -43,4 +43,5 @@ OBJS =\ arch/posix/signal.$O\ arch/posix/system.$O\ arch/posix/time.$O\ + arch/posix/tmpfile.$O\ string/strlen.$O\ diff --git a/src/libc/stdio/_fpopen.c b/src/libc/stdio/_fpopen.c @@ -12,9 +12,10 @@ _fpopen(const char *restrict fname, const char *restrict mode, FILE * restrict fp) { - int i, flags, fd, rw, bin; + int i, flags, fd, rw, bin, rights;; flags = rw = bin = 0; + rights = 0666; if (mode[0] == '\0') goto einval; @@ -31,6 +32,10 @@ _fpopen(const char *restrict fname, goto einval; bin = 1; break; + case 't': + flags |= O_EXCL | O_CLOEXEC; + rights = 0600; + break; default: goto einval; } @@ -46,7 +51,7 @@ _fpopen(const char *restrict fname, flags |= (rw) ? O_RDWR : O_WRONLY; break; case 'r': - flags = (rw) ? O_RDWR : O_RDONLY; + flags |= (rw) ? O_RDWR : O_RDONLY; break; default: einval: @@ -54,7 +59,7 @@ _fpopen(const char *restrict fname, return NULL; } - if ((fd = _open(fname, flags, 0666)) < 0) + if ((fd = _open(fname, flags, rights)) < 0) return NULL; fp->buf = NULL;