Commit 444066e5 authored by Ken Thompson's avatar Ken Thompson

interpret lines that look like

	//line 10 units.y
which is equiv to c
	#line 10 units.y
the purpose is to generate diagnostics
that correctly point to preprocessed source.

R=rsc
CC=golang-dev
https://golang.org/cl/1863042
parent ad665e4f
...@@ -25,6 +25,7 @@ static void ungetc(int); ...@@ -25,6 +25,7 @@ static void ungetc(int);
static int32 getr(void); static int32 getr(void);
static int escchar(int, int*, vlong*); static int escchar(int, int*, vlong*);
static void addidir(char*); static void addidir(char*);
static int getlinepragma(void);
static char *goos, *goarch, *goroot; static char *goos, *goarch, *goroot;
...@@ -658,8 +659,8 @@ l0: ...@@ -658,8 +659,8 @@ l0:
} }
} }
if(c1 == '/') { if(c1 == '/') {
c = getlinepragma();
for(;;) { for(;;) {
c = getr();
if(c == '\n') { if(c == '\n') {
ungetc(c); ungetc(c);
goto l0; goto l0;
...@@ -668,6 +669,7 @@ l0: ...@@ -668,6 +669,7 @@ l0:
yyerror("eof in comment"); yyerror("eof in comment");
errorexit(); errorexit();
} }
c = getr();
} }
} }
if(c1 == '=') { if(c1 == '=') {
...@@ -1106,6 +1108,63 @@ caseout: ...@@ -1106,6 +1108,63 @@ caseout:
return LLITERAL; return LLITERAL;
} }
/*
* read and interpret syntax that looks like
* //line 15 parse.y
* as a discontenuity in sequential line numbers.
* the next line of input comes from parse.y:15
*/
static int
getlinepragma(void)
{
int i, c, n;
char *cp, *ep;
Hist *h;
for(i=0; i<5; i++) {
c = getr();
if(c != "line "[i])
return c;
}
n = 0;
for(;;) {
c = getr();
if(!isdigit(c))
break;
n = n*10 + (c-'0');
}
if(c != ' ' || n == 0)
return c;
cp = lexbuf;
ep = lexbuf+sizeof(lexbuf)-5;
for(;;) {
c = getr();
if(c == ' ')
continue;
if(c == '\n')
break;
*cp++ = c;
if(cp >= ep)
break;
}
*cp = 0;
// n--; // weve already seen the newline
if(n > 0) {
// try to avoid allocating file name over and over
for(h=hist; h!=H; h=h->link) {
if(h->name != nil && strcmp(h->name, lexbuf) == 0) {
linehist(h->name, n, 0);
return c;
}
}
linehist(strdup(lexbuf), n, 0);
}
return c;
}
int32 int32
yylex(void) yylex(void)
{ {
......
...@@ -228,11 +228,14 @@ linehist(char *file, int32 off, int relative) ...@@ -228,11 +228,14 @@ linehist(char *file, int32 off, int relative)
if(debug['i']) { if(debug['i']) {
if(file != nil) { if(file != nil) {
if(off < 0) if(off < 0)
print("pragma %s at line %L\n", file, lineno); print("pragma %s at line %L\n", file, lexlineno);
else else
print("import %s at line %L\n", file, lineno); if(off > 0)
print("line %s at line %L\n", file, lexlineno);
else
print("import %s at line %L\n", file, lexlineno);
} else } else
print("end of import at line %L\n", lineno); print("end of import at line %L\n", lexlineno);
} }
if(off < 0 && file[0] != '/' && !relative) { if(off < 0 && file[0] != '/' && !relative) {
...@@ -894,12 +897,21 @@ Lconv(Fmt *fp) ...@@ -894,12 +897,21 @@ Lconv(Fmt *fp)
if(lno < h->line) if(lno < h->line)
break; break;
if(h->name) { if(h->name) {
if(n < HISTSZ) { /* beginning of file */ if(h->offset > 0) {
a[n].incl = h; // #line directive
a[n].idel = h->line; if(n > 0 && n < HISTSZ) {
a[n].line = 0; a[n-1].line = h;
a[n-1].ldel = h->line - h->offset + 1;
}
} else {
// beginning of file
if(n < HISTSZ) {
a[n].incl = h;
a[n].idel = h->line;
a[n].line = 0;
}
n++;
} }
n++;
continue; continue;
} }
n--; n--;
...@@ -921,12 +933,12 @@ Lconv(Fmt *fp) ...@@ -921,12 +933,12 @@ Lconv(Fmt *fp)
} }
if(a[i].line) if(a[i].line)
fmtprint(fp, "%s:%ld[%s:%ld]", fmtprint(fp, "%s:%ld[%s:%ld]",
a[i].line->name, lno-a[i].ldel+1, a[i].line->name, lno-a[i].ldel,
a[i].incl->name, lno-a[i].idel+1); a[i].incl->name, lno-a[i].idel);
else else
fmtprint(fp, "%s:%ld", fmtprint(fp, "%s:%ld",
a[i].incl->name, lno-a[i].idel+1); a[i].incl->name, lno-a[i].idel+1);
lno = a[i].incl->line - 1; /* now print out start of this file */ lno = a[i].incl->line - 1; // now print out start of this file
} }
if(n == 0) if(n == 0)
fmtprint(fp, "<epoch>"); fmtprint(fp, "<epoch>");
......
...@@ -675,7 +675,7 @@ outer: ...@@ -675,7 +675,7 @@ outer:
// //
if t == MARK { if t == MARK {
if !lflag { if !lflag {
fmt.Fprintf(ftable, "\n//line %v:%v\n", infile, lineno) fmt.Fprintf(ftable, "\n//line %v %v\n", lineno, infile)
} }
for { for {
c := getrune(finput) c := getrune(finput)
...@@ -2066,6 +2066,7 @@ nextk: ...@@ -2066,6 +2066,7 @@ nextk:
func output() { func output() {
var c, u, v int var c, u, v int
fmt.Fprintf(ftable, "\n//line 1 yacctab\n")
fmt.Fprintf(ftable, "var\tyyExca = []int {\n") fmt.Fprintf(ftable, "var\tyyExca = []int {\n")
noset := mkset() noset := mkset()
...@@ -2825,8 +2826,10 @@ func others() { ...@@ -2825,8 +2826,10 @@ func others() {
c = getrune(finput) c = getrune(finput)
} }
parts := strings.Split(yaccpar, "yyrun()", 2)
// copy yaccpar // copy yaccpar
fmt.Fprintf(ftable, "\n//line 1 yaccpar\n")
parts := strings.Split(yaccpar, "yyrun()", 2)
fmt.Fprintf(ftable, "%v", parts[0]) fmt.Fprintf(ftable, "%v", parts[0])
ftable.Write(fcode.Bytes()) ftable.Write(fcode.Bytes())
fmt.Fprintf(ftable, "%v", parts[1]) fmt.Fprintf(ftable, "%v", parts[1])
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment