static int32 getr(void);
static int escchar(int, int*, vlong*);
static void addidir(char*);
+static int getlinepragma(void);
static char *goos, *goarch, *goroot;
}
}
if(c1 == '/') {
+ c = getlinepragma();
for(;;) {
- c = getr();
if(c == '\n') {
ungetc(c);
goto l0;
yyerror("eof in comment");
errorexit();
}
+ c = getr();
}
}
if(c1 == '=') {
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
yylex(void)
{
if(debug['i']) {
if(file != nil) {
if(off < 0)
- print("pragma %s at line %L\n", file, lineno);
+ print("pragma %s at line %L\n", file, lexlineno);
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
- 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(lno < h->line)
break;
if(h->name) {
- if(n < HISTSZ) { /* beginning of file */
- a[n].incl = h;
- a[n].idel = h->line;
- a[n].line = 0;
+ if(h->offset > 0) {
+ // #line directive
+ if(n > 0 && n < HISTSZ) {
+ 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;
}
n--;
}
if(a[i].line)
fmtprint(fp, "%s:%ld[%s:%ld]",
- a[i].line->name, lno-a[i].ldel+1,
- a[i].incl->name, lno-a[i].idel+1);
+ a[i].line->name, lno-a[i].ldel,
+ a[i].incl->name, lno-a[i].idel);
else
fmtprint(fp, "%s:%ld",
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)
fmtprint(fp, "<epoch>");
//
if t == MARK {
if !lflag {
- fmt.Fprintf(ftable, "\n//line %v:%v\n", infile, lineno)
+ fmt.Fprintf(ftable, "\n//line %v %v\n", lineno, infile)
}
for {
c := getrune(finput)
func output() {
var c, u, v int
+ fmt.Fprintf(ftable, "\n//line 1 yacctab\n")
fmt.Fprintf(ftable, "var\tyyExca = []int {\n")
noset := mkset()
c = getrune(finput)
}
- parts := strings.Split(yaccpar, "yyrun()", 2)
// copy yaccpar
+ fmt.Fprintf(ftable, "\n//line 1 yaccpar\n")
+
+ parts := strings.Split(yaccpar, "yyrun()", 2)
fmt.Fprintf(ftable, "%v", parts[0])
ftable.Write(fcode.Bytes())
fmt.Fprintf(ftable, "%v", parts[1])