summaryrefslogtreecommitdiff
path: root/utils/c2l/out.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/c2l/out.c')
-rw-r--r--utils/c2l/out.c825
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;
+}