diff options
Diffstat (limited to 'utils/c2l/out.c')
| -rw-r--r-- | utils/c2l/out.c | 825 |
1 files changed, 825 insertions, 0 deletions
diff --git a/utils/c2l/out.c b/utils/c2l/out.c new file mode 100644 index 00000000..ab81a995 --- /dev/null +++ b/utils/c2l/out.c @@ -0,0 +1,825 @@ +#include "cc.h" + +#define INCREMENT 8 +#define DEVNULL "/dev/null" + +static int indent = 0; +static int fd = -1; +static int nf = 0; +static int mylineno = 1; + +typedef struct Com{ + int lno; + char *s; + Node *n; + int tba; + struct Com *nxt; +} Com; + +Com *hdc, *curc; + +typedef struct File{ + char *s; + char *f; + char *m; + int b; + int loc; + int in; + int tg; + Node *n; + Com *c; + struct File *nxt; +} File; + +typedef struct Create{ + char *s; + struct Create *nxt; +} Create; + +File *fs; +Create *cs; + +static void genmsg(void); +static int isloc(void); + +static void +addcreate(char *s) +{ + Create *c; + + if(strcmp(s, DEVNULL) == 0) + return; + c = (Create*)malloc(sizeof(Create)); + c->s = malloc(strlen(s)+1); + strcpy(c->s, s); + c->nxt = cs; + cs = c; +} + +static int +created(char *s) +{ + Create *c; + + for(c = cs; c != nil; c = c->nxt) + if(strcmp(s, c->s) == 0) + return 1; + return 0; +} + +int +dolog(void) +{ + if(justcode) + return 0; + return domod || !doinc || inmain; +} + +static char* +curf(void) +{ + File *f; + + for(f = fs; f != nil; f = f->nxt) + if(f->f != nil) + return f->s; + return nil; +} + +static char* +curm(void) +{ + File *f; + + for(f = fs; f != nil; f = f->nxt) + if(f->f != nil) + return f->m; + return nil; +} + +void +setmod(Sym *s) +{ + if(domod && s->mod == nil && ism() && !(doloc && !isloc())) + s->mod = curm(); +} + +char * +outmod(char *buf, int up) +{ + char *s, *t; + + s = curf(); + if(s == nil) + return ""; + t = strchr(s, '.'); + if(t != nil) + *t = '\0'; + strcpy(buf, s); + if(t != nil) + *t = '.'; + if(up == 1 || (up < 0 && ism())) + buf[0] = toupper(buf[0]); + return buf; +} + +int +ism(void) +{ + return !isb(); +} + +int +isb(void) +{ + File *f; + + for(f = fs; f != nil; f = f->nxt) + if(f->f != nil) + return f->b; + return 0; +} + +static int +isloc(void) +{ + File *f; + + for(f = fs; f != nil; f = f->nxt) + if(f->f != nil) + return f->loc; + return 0; +} + +static File* +pushf(void) +{ + static File zfile; + File *f; + + f = (File*)malloc(sizeof(File)); + *f = zfile; + f->s = nil; + f->f = nil; + f->m = nil; + f->nxt = fs; + fs = f; + return f; +} + +static void +popf(void) +{ + File *f; + + f = fs; + fs = fs->nxt; + if(f->s != nil) + free(f->s); + free(f); +} + +static void +setf(File *f, char *s) +{ + int n; + char *t; + + if(s != nil){ + t = strrchr(s, '/'); + f->loc = t == nil; + if(t != nil) + s = t+1; + n = strlen(s); + f->s = malloc(n+1); + strcpy(f->s, s); + s = f->s; + if(n > 2 && s[n-2] == '.'){ + f->m = malloc(n-1); + strncpy(f->m, s, n-2); + if(s[n-1] == 'h') + s[n-1] = 'm'; + else if(s[n-1] == 'c'){ + s[n-1] = 'b'; + f->b = 1; + } + else + s = nil; + } + else + s = nil; + if(s == nil){ + free(f->s); + if(f->m != nil) + free(f->m); + f->s = nil; + f->m = nil; + } + } + f->f = f->s; + if(f->s != nil && nf > 0){ + if(doinc || doloc && !f->loc) + f->f = DEVNULL; + else if(!domod) + f->f = nil; + } +} + +void +outpush0(char *s, Node *n) +{ + File *f; + + f = pushf(); + setf(f, s); + if(f->f != nil){ + nf++; + f->tg = taggen; + taggen = 0; + f->n = n; + f->c = hdc; + hdc = nil; + } +} + +void +outpop0(int lno) +{ + File *f; + + USED(lno); + f = fs; + if(f->f != nil){ + nf--; + taggen = f->tg; + f->n->left = (void*)hdc; + hdc = f->c; + } + popf(); +} + +void +outpush2(char *s, Node *n) +{ + File *f; + + f = pushf(); + setf(f, s); + if(f->f != nil){ + if(fd >= 0){ + newsec(0); + close(fd); + close(1); + fd = -1; + } + if(created(f->f)) + f->f = DEVNULL; /* don't overwrite original if included again */ + fd = create(f->f, OWRITE, 0664); + if(fd >= 0) + addcreate(f->f); + mydup(fd, 1); + nf++; + f->tg = taggen; + taggen = 0; + f->c = hdc; + if(n != Z) + hdc = (void*)n->left; + else + hdc = nil; + f->in = indent; + indent = 0; + genmsg(); + pgen(f->b); + } +} + +void +outpop2(int lno) +{ + File *f, *g; + + f = fs; + if(f->f != nil){ + if(fd >= 0){ + newsec(0); + output(lno, 1); + epgen(f->b); + close(fd); + close(1); + fd = -1; + } + for(g = fs->nxt; g != nil; g = g->nxt){ + if(g->f != nil){ + fd = open(g->f, OWRITE); + seek(fd, 0, 2); + mydup(fd, 1); + break; + } + } + nf--; + taggen = f->tg; + hdc = f->c; + indent = f->in; + } + popf(); +} + +static void +xprint(char *s) +{ + if(nerrors == 0) + print(s); +} + +static int tot = 0; + +static void +doindent(int d) +{ + int i; + + for(i = 0; i < d/8; i++) + xprint("\t"); + for(i = 0; i < d%8; i++) + xprint(" "); +} + +void +incind(void) +{ + indent += INCREMENT; +} + +void +decind(void) +{ + indent -= INCREMENT; +} + +int +zeroind(void) +{ + int i = indent; + + indent = 0; + return i; +} + +void +restoreind(int i) +{ + indent = i; +} + +void +newline0(void) +{ + xprint("\n"); + tot = 0; + mylineno++; +} + +void +newline(void) +{ + if(!outcom(1)){ + xprint("\n"); + mylineno++; + } + tot = 0; +} + +static void +lprint(char *s) +{ + if(tot == 0) { + doindent(indent); + tot += indent; + } + xprint(s); + tot += strlen(s); +} + +void +prline(char *s) +{ + xprint(s); + xprint("\n"); + mylineno++; +} + +void +prdelim(char *s) +{ + if(*s == '%'){ + if(*++s == '=') + lprint("%%="); + else + lprint("%%"); + return; + } + lprint(s); +} + +void +prkeywd(char *kw) +{ + lprint(kw); +} + +void +prid(char *s) +{ + lprint(s); +} + +static void +priddol(char *s, int dol) +{ + char *t; + char buf[128]; + + if(dol){ + t = strchr(s, '$'); + if(t != nil) + *t = '_'; + lprint(s); + if(t != nil){ + strcpy(buf, s); + while(slookup(buf)->type != T){ + strcat(buf, "x"); + lprint("x"); + } + *t = '$'; + } + } + else + lprint(s); +} + +void +prsym(Sym *s, int mod) +{ + char buf[128]; + int c; + + if(mod && s->mod && strcmp(s->mod, curm()) != 0 && (!s->limbo || s->class == CEXTERN)){ + c = isconsym(s); + if(c >= 0){ + if(c){ + s->mod[0] = toupper(s->mod[0]); + lprint(s->mod); + s->mod[0] = tolower(s->mod[0]); + } + else + lprint(s->mod); + lprint("->"); + usemod(s, !c); + } + } + if(s->lname) + prid(s->lname); + else{ + priddol(s->name, s->class == CSTATIC); + if(s->lkw){ + strcpy(buf, s->name); + for(;;){ + strcat(buf, "x"); + lprint("x"); + s = slookup(buf); + if(s->type == T) + break; + } + } + } +} + +int +arrow(Sym *s) +{ + if(s->mod && strcmp(s->mod, curm()) != 0) + return isconsym(s) >= 0; + return 0; +} + +void +prsym0(Sym *s) +{ + int c; + + if(s->mod && strcmp(s->mod, curm()) != 0){ + c = isconsym(s); + if(c >= 0) + usemod(s, !c); + } +} + +static int +isprintable(int c) +{ + if(c >= 0x20 && c <= 0x7e) + return 1; + return c == '\0' || c == '\n' || c == '\t' || c == '\b' || c == '\r' || c == '\f' || c == '\a' || c == '\v'; +} + +static int +hex(int c) +{ + if(c < 10) + return c+'0'; + return c+'a'-10; +} + +void +prchar0(vlong x, int quote) +{ + int c, e, i = 0; + static char buf[16]; + + if(quote) + buf[i++] = '\''; + c = x; + if(c < 0 || c > 255 || !isprintable(c)){ + if(c&0xffff0000) + diag(Z, "character too big"); + buf[i++] = '\\'; + buf[i++] = 'u'; + buf[i++] = hex((c>>12)&0xf); + buf[i++] = hex((c>>8)&0xf); + buf[i++] = hex((c>>4)&0xf); + buf[i++] = hex((c>>0)&0xf); + } + else{ + e = 0; + switch(c){ + case '\n': e = 'n'; break; + case '\t': e = 't'; break; + case '\b': e = 'b'; break; + case '\r': e = 'r'; break; + case '\f': e = 'f'; break; + case '\a': e = 'a'; break; + case '\v': e = 'v'; break; + case '"': if(!quote) e = '"'; break; + case '\'': if(quote) e = '\''; break; + case '\\': e = '\\'; break; + case '%': buf[i++] = c; break; + case 0: e = '0'; if(strings) prcom("nul byte in string ?", Z); break; + } + if(e != 0){ + buf[i++] = '\\'; + c = e; + } + buf[i++] = c; + } + if(quote) + buf[i++] = '\''; + buf[i] = '\0'; + lprint(buf); +} + +void +prchar(vlong x) +{ + prchar0(x, 1); +} + +void +prstr(char *s) +{ + uchar *t; + Rune r; + + t = (uchar*)s; + lprint("\""); + while(*t != 0){ + if(*t & 0x80){ + t += chartorune(&r, (char*)t); + prchar0(r, 0); + } + else + prchar0(*t++, 0); + } + lprint("\""); +} + +void +prlstr(ushort *s) +{ + lprint("\""); + while(*s != 0) + prchar0(*s++, 0); + lprint("\""); +} + +void +prreal(double x, char *s, int b) +{ + static char buf[128]; + + if(b != KDEC) + diag(Z, "not base 10 in prreal"); + if(s != nil) + lprint(s); + else{ + sprint(buf, "%f", x); + lprint(buf); + } +} + +void +prnum(vlong x, int b, Type *t) +{ + static char buf[128]; + int w; + vlong m; + + w = 4; + if(t != T) + w = ewidth[t->etype]; + m = MASK(8*w); + if(b == KHEX) + sprint(buf, "16r%llux", x&m); + else if(b == KOCT) + sprint(buf, "8r%lluo", x&m); + else + sprint(buf, "%lld", x); + lprint(buf); +} + +char *cb; +int cn, csz; + +static void +outcom0(Com *c) +{ + Node *n; + char *s, *t, *u; + + s = c->s; + n = c->n; + if(comm && c->tba){ + t = strchr(s, '\n'); + *t = '\0'; + fprint(2, "%s:%d: %s", curf(), mylineno, s); + *t = '\n'; + if(n != Z){ + mydup(2, 1); + expgen(n); + mydup(fd, 1); + } + fprint(2, "\n"); + } + while(*s != '\0'){ + t = strchr(s, '\n'); + *t = '\0'; + if(tot != 0) + prdelim("\t"); + prdelim("# "); + while((u = strchr(s, '%')) != nil){ + /* do not let print interpret % ! */ + *u = 0; + lprint(s); + *u = '%'; + lprint("%%"); + s = u+1; + } + lprint(s); + if(n == Z) + newline0(); + *t = '\n'; + s = t+1; + } + if(n != Z){ + expgen(n); + newline0(); + } +} + +int +outcom(int f) +{ + int lno, nl; + Com *c; + + nl = 0; + lno = pline+f; + c = hdc; + while(c != nil && c->lno < lno){ +/* print("outcom: %d < %d (f=%d)\n", c->lno, lno, f); */ + nl = 1; + outcom0(c); + hdc = hdc->nxt; + free(c->s); + free(c); + c = hdc; + } + return nl; +} + +void +startcom(int lno) +{ + Com *c, **ac; + + c = (Com *)malloc(sizeof(Com)); + c->lno = lno; + c->s = nil; + c->n = Z; + c->tba = 0; + c->nxt = nil; + for(ac = &hdc; *ac != nil && (*ac)->lno <= lno; ac = &(*ac)->nxt) + ; + c->nxt = *ac; + curc = *ac = c; +} + +void +addcom(int rr) +{ + int i, nb; + char *ncb; + char s[UTFmax]; + Rune r[1]; + + if(rr >= Runeself){ + r[0] = rr; + nb = runetochar(s, r); + } + else{ + nb = 1; + s[0] = rr; + } + if(cn+nb-1 >= csz){ + csz += 32; + ncb = malloc(csz); + memcpy(ncb, cb, cn); + free(cb); + cb = ncb; + } + for(i = 0; i < nb; i++) + cb[cn++] = s[i]; +} + +void +endcom(void) +{ + char *s; + + addcom('\n'); + addcom('\0'); + s = malloc(strlen(cb)+1); + strcpy(s, cb); + curc->s = s; +/* print("com %d %s\n", curc->lno, s); */ + cn = 0; +} + +void +linit() +{ + csz = 32; + cb = malloc(csz); + sysinit(); +} + +static void +genmsg(void) +{ + prline("#"); + prline("# initially generated by c2l"); + prline("#"); + prline(""); +} + +void +prcom(char *s, Node *n) +{ + Com *c; + + startcom(pline); + c = curc; + sprint(cb, "TBA %s", s); + cn = strlen(cb); + c->n = n; + c->tba = 1; + endcom(); +} + +void +output(long lno, int com) +{ +/* print("output(%ld)\n", lno); */ + pline = lno; + if(com) + outcom(0); +} + +int +exists(char *f) +{ + int fd; + + fd = open(f, OREAD); + close(fd); + return fd >= 0; +} |
