Skip to content

Commit

Permalink
scan: Allow stray indented but otherwise empty lines
Browse files Browse the repository at this point in the history
This is not very common, but ninja accepts this and it has shown
up in at least one project.
  • Loading branch information
michaelforney committed Apr 9, 2021
1 parent 11afcfe commit aff2085
Showing 1 changed file with 25 additions and 38 deletions.
63 changes: 25 additions & 38 deletions scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,32 +73,32 @@ isvar(int c)
return issimplevar(c) || c == '.';
}

static void
crlf(struct scanner *s)
static bool
newline(struct scanner *s)
{
if (next(s) != '\n')
scanerror(s, "expected '\\n' after '\\r'");
switch (s->chr) {
case '\r':
if (next(s) != '\n')
scanerror(s, "expected '\\n' after '\\r'");
/* fallthrough */
case '\n':
next(s);
return true;
}
return false;
}

static bool
singlespace(struct scanner *s)
{
int c;

switch (s->chr) {
case '$':
c = getc(s->f);
switch (c) {
case '\r':
crlf(s);
/* fallthrough */
case '\n':
break;
default:
ungetc(c, s->f);
return false;
}
/* fallthrough */
next(s);
if (newline(s))
return true;
ungetc(s->chr, s->f);
s->chr = '$';
return false;
case ' ':
next(s);
return true;
Expand All @@ -122,8 +122,7 @@ comment(struct scanner *s)
if (s->chr != '#')
return false;
do next(s);
while (s->chr != '\n');
next(s);
while (!newline(s));
return true;
}

Expand Down Expand Up @@ -162,17 +161,15 @@ scankeyword(struct scanner *s, char **var)
switch (s->chr) {
case ' ':
space(s);
if (s->chr != '#')
if (!comment(s) && !newline(s))
scanerror(s, "unexpected indent");
/* fallthrough */
break;
case '#':
comment(s);
break;
case '\r':
crlf(s);
/* fallthrough */
case '\n':
next(s);
newline(s);
break;
case EOF:
return EOF;
Expand Down Expand Up @@ -243,10 +240,8 @@ escape(struct scanner *s, struct evalstring ***end)
addstringpart(end, true);
break;
case '\r':
crlf(s);
/* fallthrough */
case '\n':
next(s);
newline(s);
space(s);
break;
default:
Expand Down Expand Up @@ -349,21 +344,13 @@ scanindent(struct scanner *s)
for (;;) {
indent = space(s);
if (!comment(s))
return indent;
return indent && !newline(s);
}
}

void
scannewline(struct scanner *s)
{
switch (s->chr) {
case '\r':
crlf(s);
/* fallthrough */
case '\n':
next(s);
break;
default:
if (!newline(s))
scanerror(s, "expected newline");
}
}

0 comments on commit aff2085

Please sign in to comment.