From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mimir.eigenstate.org ([206.124.132.107]) by ewsd; Tue Oct 27 23:16:31 -0400 2020 Received: from abbatoir.fios-router.home (pool-74-101-2-6.nycmny.fios.verizon.net [74.101.2.6]) by mimir.eigenstate.org (OpenSMTPD) with ESMTPSA id 8c26a8ea (TLSv1.2:ECDHE-RSA-AES256-SHA:256:NO); Tue, 27 Oct 2020 20:16:22 -0700 (PDT) Message-ID: To: cinap_lenrek@felloff.net, 9front@9front.org Subject: Re: [9front] rc: null list in concatenation line numbers Date: Tue, 27 Oct 2020 20:16:20 -0700 From: ori@eigenstate.org In-Reply-To: MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit List-ID: <9front.9front.org> List-Help: X-Glyph: ➈ X-Bullshit: anonymous SVG interface software > yeah, but Xreturn just pops the thread! so just put the code > file name in the thread and it will restore automatically. > just like the thread references the code block... but maybe > i'm missing something else? > > the idea basically was that you can completely get rid of > the file name table then... Yep, I was being too clever, and getting tripped up by the rewind/replay logic. Doing less made it work. Here's another iteration. It also handles /env/fn#foo, and uses \n as the line separator for /env/fn#foo so that we have some useful line numbers. We can probably figure out some javascript source maps or something to map back from /env/fn#foo to the file that it came from, after. Thanks mischief for the question. diff -r 0e47f4a0c4d6 sys/src/cmd/rc/code.c --- a/sys/src/cmd/rc/code.c Tue Oct 27 15:16:03 2020 +0100 +++ b/sys/src/cmd/rc/code.c Tue Oct 27 20:15:43 2020 -0700 @@ -6,10 +6,12 @@ #define c0 t->child[0] #define c1 t->child[1] #define c2 t->child[2] +code *codebuf; int codep, ncode; #define emitf(x) ((codep!=ncode || morecode()), codebuf[codep].f = (x), codep++) #define emiti(x) ((codep!=ncode || morecode()), codebuf[codep].i = (x), codep++) #define emits(x) ((codep!=ncode || morecode()), codebuf[codep].s = (x), codep++) + void stuffdot(int); char *fnstr(tree*); void outcode(tree*, int); @@ -38,7 +40,7 @@ compile(tree *t) { ncode = 100; - codebuf = (code *)emalloc(ncode*sizeof codebuf[0]); + codebuf = emalloc(ncode*sizeof codebuf[0]); codep = 0; emiti(0); /* reference count */ outcode(t, flag['e']?1:0); @@ -64,12 +66,8 @@ { io *f = openstr(); void *v; - extern char nl; - char svnl = nl; - nl = ';'; pfmt(f, "%t", t); - nl = svnl; v = f->strp; f->strp = 0; closeio(f); @@ -79,12 +77,19 @@ void outcode(tree *t, int eflag) { + static int line; int p, q; tree *tt; + char *f; if(t==0) return; if(t->type!=NOT && t->type!=';') runq->iflast = 0; + if(t->line != line){ + line = t->line; + emitf(Xsrcline); + emiti(line); + } switch(t->type){ default: pfmt(err, "bad type %d in outcode\n", t->type); @@ -174,6 +179,12 @@ emitf(Xfn); p = emiti(0); emits(fnstr(c1)); + if((f = curfile(runq)) != nil){ + emitf(Xsrcfile); + emits(strdup(f)); + } + emitf(Xsrcline); + emiti(lexline); outcode(c1, eflag); emitf(Xunlocal); /* get rid of $* */ emitf(Xreturn); diff -r 0e47f4a0c4d6 sys/src/cmd/rc/exec.c --- a/sys/src/cmd/rc/exec.c Tue Oct 27 15:16:03 2020 +0100 +++ b/sys/src/cmd/rc/exec.c Tue Oct 27 20:15:43 2020 -0700 @@ -14,11 +14,12 @@ struct thread *p = new(struct thread); p->code = codecopy(c); + p->line = runq?runq->line:0; p->pc = pc; p->argv = 0; - p->redir = p->startredir = runq?runq->redir:0; + p->redir = p->startredir = runq?runq->redir:nil; p->local = local; - p->cmdfile = 0; + p->cmdfile = nil; p->cmdfd = 0; p->eof = 0; p->iflag = 0; @@ -201,10 +202,14 @@ bootstrap[i++].f = Xexit; bootstrap[i].i = 0; start(bootstrap, 1, (var *)0); + runq->cmdfile = strdup("rc"); /* prime bootstrap argv */ pushlist(); argv0 = estrdup(argv[0]); for(i = argc-1;i!=0;--i) pushword(argv[i]); + + lexline = 0; + for(;;){ if(flag['r']) pfnc(err, runq); @@ -932,7 +937,7 @@ if(p->cmdfile) free(p->cmdfile); closeio(p->cmdfd); - Xreturn(); /* should this be omitted? */ + Xreturn(); } else{ if(Eintr()){ @@ -950,13 +955,22 @@ freenodes(); } +char* +curfile(thread *p) +{ + for(; p != nil; p = p->ret) + if(p->cmdfile != nil) + return p->cmdfile; + return "unknown"; +} + void Xerror(char *s) { if(strcmp(argv0, "rc")==0 || strcmp(argv0, "/bin/rc")==0) - pfmt(err, "rc: %s: %r\n", s); + pfmt(err, "rc:%d: %s: %r\n", runq->line, s); else - pfmt(err, "rc (%s): %s: %r\n", argv0, s); + pfmt(err, "%s:%d: %s: %r\n", curfile(runq), runq->line, s); flush(err); setstatus("error"); while(!runq->iflag) Xreturn(); @@ -966,9 +980,9 @@ Xerror1(char *s) { if(strcmp(argv0, "rc")==0 || strcmp(argv0, "/bin/rc")==0) - pfmt(err, "rc: %s\n", s); + pfmt(err, "rc:%d: %s\n", runq->line, s); else - pfmt(err, "rc (%s): %s\n", argv0, s); + pfmt(err, "%s:%d: %s\n", curfile(runq), runq->line, s); flush(err); setstatus("error"); while(!runq->iflag) Xreturn(); @@ -1025,3 +1039,16 @@ { globlist(runq->argv->words); } + +void +Xsrcline(void) +{ + runq->line = runq->code[runq->pc++].i; +} + +void +Xsrcfile(void) +{ + free(runq->cmdfile); + runq->cmdfile = strdup(runq->code[runq->pc++].s); +} diff -r 0e47f4a0c4d6 sys/src/cmd/rc/exec.h --- a/sys/src/cmd/rc/exec.h Tue Oct 27 15:16:03 2020 +0100 +++ b/sys/src/cmd/rc/exec.h Tue Oct 27 20:15:43 2020 -0700 @@ -5,7 +5,7 @@ extern void Xconc(void), Xcount(void), Xdelfn(void), Xdol(void), Xqw(void), Xdup(void); extern void Xexit(void), Xfalse(void), Xfn(void), Xfor(void), Xglob(void); extern void Xjump(void), Xmark(void), Xmatch(void), Xpipe(void), Xread(void); -extern void Xrdwr(void); +extern void Xrdwr(void), Xsrcline(void), Xsrcfile(void); extern void Xrdfn(void), Xunredir(void), Xstar(void), Xreturn(void), Xsubshell(void); extern void Xtrue(void), Xword(void), Xglobs(void), Xwrite(void), Xpipefd(void), Xcase(void); extern void Xlocal(void), Xunlocal(void), Xassign(void), Xsimple(void), Xpopm(void); @@ -30,7 +30,7 @@ struct redir{ char type; /* what to do */ short from, to; /* what to do it to */ - struct redir *next; /* what else to do (reverse order) */ + redir *next; /* what else to do (reverse order) */ }; #define NSTATUS ERRMAX /* length of status (from plan 9) */ /* @@ -40,14 +40,15 @@ #define RDUP 2 /* dup2(from, to); */ #define RCLOSE 3 /* close(from); */ struct thread{ - union code *code; /* code for this thread */ + code *code; /* code for this thread */ int pc; /* code[pc] is the next instruction */ - struct list *argv; /* argument stack */ - struct redir *redir; /* redirection stack */ - struct redir *startredir; /* redir inheritance point */ - struct var *local; /* list of local variables */ + int line; /* source code line */ + list *argv; /* argument stack */ + redir *redir; /* redirection stack */ + redir *startredir; /* redir inheritance point */ + var *local; /* list of local variables */ char *cmdfile; /* file name in Xrdcmd */ - struct io *cmdfd; /* file descriptor for Xrdcmd */ + io *cmdfd; /* file descriptor for Xrdcmd */ int iflast; /* static `if not' checking */ int eof; /* is cmdfd at eof? */ int iflag; /* interactive? */ @@ -55,7 +56,7 @@ int pid; /* process for Xpipewait to wait for */ char status[NSTATUS]; /* status for Xpipewait */ tree *treenodes; /* tree nodes created by this process */ - thread *ret; /* who continues when this finishes */ + thread *ret; /* who continues when this finishes */ }; thread *runq; code *codecopy(code*); @@ -74,3 +75,4 @@ void execexit(void), execshift(void); void execwait(void), execumask(void), execdot(void), execflag(void); void execfunc(var*), execcmds(io *); +char *curfile(thread*); \ No newline at end of file diff -r 0e47f4a0c4d6 sys/src/cmd/rc/lex.c --- a/sys/src/cmd/rc/lex.c Tue Oct 27 15:16:03 2020 +0100 +++ b/sys/src/cmd/rc/lex.c Tue Oct 27 20:15:43 2020 -0700 @@ -25,6 +25,13 @@ int doprompt = 1; int inquote; int incomm; +int lastc; +int ndot; +int nerror; +int lexline; +int nlexpath; +int lexpathsz; + /* * Look ahead in the input stream */ @@ -39,13 +46,14 @@ /* * Consume the lookahead character. */ - int advance(void) { int c = nextc(); lastc = future; future = EOF; + if(c == '\n') + lexline++; return c; } /* diff -r 0e47f4a0c4d6 sys/src/cmd/rc/pcmd.c --- a/sys/src/cmd/rc/pcmd.c Tue Oct 27 15:16:03 2020 +0100 +++ b/sys/src/cmd/rc/pcmd.c Tue Oct 27 20:15:43 2020 -0700 @@ -1,7 +1,7 @@ #include "rc.h" #include "io.h" #include "fns.h" -char nl='\n'; /* change to semicolon for bourne-proofing */ + #define c0 t->child[0] #define c1 t->child[1] #define c2 t->child[2] @@ -76,7 +76,7 @@ case ';': if(c0){ if(c1) - pfmt(f, "%t%c%t", c0, nl, c1); + pfmt(f, "%t\n%t", c0, c1); else pfmt(f, "%t", c0); } else pfmt(f, "%t", c1); diff -r 0e47f4a0c4d6 sys/src/cmd/rc/pfnc.c --- a/sys/src/cmd/rc/pfnc.c Tue Oct 27 15:16:03 2020 +0100 +++ b/sys/src/cmd/rc/pfnc.c Tue Oct 27 20:15:43 2020 -0700 @@ -51,6 +51,7 @@ Xrdfn, "Xrdfn", Xsimple, "Xsimple", Xqw, "Xqw", + Xsrcline, "Xsrcline", 0}; void @@ -59,7 +60,8 @@ int i; void (*fn)(void) = t->code[t->pc].f; list *a; - pfmt(fd, "pid %d cycle %p %d ", getpid(), t->code, t->pc); + + pfmt(fd, "%s:%d: pid %d cycle %p %d ", t->cmdfile, t->line, getpid(), t->code, t->pc); for(i = 0;fname[i].f;i++) if(fname[i].f==fn){ pstr(fd, fname[i].name); break; diff -r 0e47f4a0c4d6 sys/src/cmd/rc/plan9.c --- a/sys/src/cmd/rc/plan9.c Tue Oct 27 15:16:03 2020 +0100 +++ b/sys/src/cmd/rc/plan9.c Tue Oct 27 20:15:43 2020 -0700 @@ -164,9 +164,12 @@ if(runq->argv->words == 0) poplist(); else { + free(runq->cmdfile); int f = open(runq->argv->words->word, 0); + lexline = 0; + runq->cmdfile = strdup(runq->argv->words->word); + runq->pc--; popword(); - runq->pc--; if(f>=0) execcmds(openfd(f)); } } diff -r 0e47f4a0c4d6 sys/src/cmd/rc/rc.h --- a/sys/src/cmd/rc/rc.h Tue Oct 27 15:16:03 2020 +0100 +++ b/sys/src/cmd/rc/rc.h Tue Oct 27 20:15:43 2020 -0700 @@ -43,6 +43,7 @@ char *str; int quoted; int iskw; + int line; tree *child[3]; tree *next; }; @@ -54,6 +55,7 @@ tree *simplemung(tree*), *heredoc(tree*); void freetree(tree*); tree *cmdtree; + /* * The first word of any code vector is a reference count. * Always create a new reference to a code vector by calling codecopy(.). @@ -126,10 +128,12 @@ */ #define onebyte(c) ((c&0x80)==0x00) -char **argp; -char **args; -int nerror; /* number of errors encountered during compilation */ -int doprompt; /* is it time for a prompt? */ +extern char **argp; +extern char **args; +extern int nerror; /* number of errors encountered during compilation */ +extern int doprompt; /* is it time for a prompt? */ +extern int lexline; + /* * Which fds are the reading/writing end of a pipe? * Unfortunately, this can vary from system to system. @@ -143,7 +147,7 @@ * How many dot commands have we executed? * Used to ensure that -v flag doesn't print rcmain. */ -int ndot; +extern int ndot; +extern int lastc; +extern int lastword; char *getstatus(void); -int lastc; -int lastword; diff -r 0e47f4a0c4d6 sys/src/cmd/rc/simple.c --- a/sys/src/cmd/rc/simple.c Tue Oct 27 15:16:03 2020 +0100 +++ b/sys/src/cmd/rc/simple.c Tue Oct 27 20:15:43 2020 -0700 @@ -11,7 +11,7 @@ */ int exitnext(void){ - union code *c=&runq->code[runq->pc]; + code *c=&runq->code[runq->pc]; while(c->f==Xpopredir || c->f==Xunlocal) c++; return c->f==Xexit; } @@ -260,6 +260,7 @@ execcmds(io *f) { static int first = 1; + if(first){ rdcmds[0].i = 1; rdcmds[1].f = Xrdcmds; @@ -319,6 +320,7 @@ } else eflagok = 1; + popword(); if(p->argv->words && strcmp(p->argv->words->word, "-i")==0){ iflag = 1; @@ -354,6 +356,9 @@ Xerror(".: can't open"); return; } + + lexline = 1; + /* set up for a new command loop */ start(dotcmds, 1, (struct var *)0); pushredir(RCLOSE, fd, 0); diff -r 0e47f4a0c4d6 sys/src/cmd/rc/tree.c --- a/sys/src/cmd/rc/tree.c Tue Oct 27 15:16:03 2020 +0100 +++ b/sys/src/cmd/rc/tree.c Tue Oct 27 20:15:43 2020 -0700 @@ -16,6 +16,7 @@ t->str = 0; t->child[0] = t->child[1] = t->child[2] = 0; t->next = treenodes; + t->line = lexline; treenodes = t; return t; }