On Sun, Oct 14, 2012 at 06:49:34PM +0200, Marc Espie wrote: > millert@ already saw all of this. > This solves a few minor/major problems. > > - Theo wants no blank line at end of ^C error messages. This blank line > actually comes from the shell/tty, so we have to refrain printing out the > last \n in that situation.
This part was confusing. Put on hold for now. > - make sure errors go thru handle_all_signals(), so that signals are handled > properly. Implied by posix, so keep. The rest doesn't change, new patch follows (smaller actually) > > 1/- We have outgrown Buf_KillTrailingSpaces. More importantly, this fixes some > posix compliance bug, since spaces at end of variable assignments are NOT > supposed to get stripped. > So far, one non-compliant Makefile got fixed in xenocara. src seems very happy > with this. Basically, this means that for POSIX; > A = some value # and some comment > > Then A will be set to exactly 'some value '. > (spaces around the = sign get stripped, but spaces before a comment DON'T) > > - compat mode should expand .USE right away. It can never be an aliased > target. > And accordingly, this turns into a straight switch() right away > > 2/- fix the cond parser to actually LOOK for its "special keywords" instead > of blindly ignoring other stuff (this is the cause of .if existS fix in cc, > btw). Use isspace more consistently while there... > > - make parse/cond error messages look MORE like the new regular error message. > This can be tweaked some more if necessary. > > - zap an extra cond error message that's not needed since the .if/.endif > parser > is verbose enough. > > - remove some MORE verbosity that's not needed. > > - unclosed var specs in varmodifiers should be treated the same as the common > one. > > (there are some other Errors in varmodifiers that may or may not need to > be turned into errors, but this can wait). > > > Out of this, I'd like feedback on the improved messages, and most importantly > TESTS about the more bitchy cond parser and posix compliant general parser. > > Note that this can easily be cut into a few easy to read, independent patches. > But I'm mostly interested in ppl running all of that and reporting problems. > > If any problems, I expect they will come from 1/ and 2/ mostly. Index: buf.c =================================================================== RCS file: /home/openbsd/cvs/src/usr.bin/make/buf.c,v retrieving revision 1.24 diff -u -p -r1.24 buf.c --- buf.c 21 Sep 2012 07:55:20 -0000 1.24 +++ buf.c 13 Oct 2012 14:22:50 -0000 @@ -161,13 +161,3 @@ Buf_Init(Buffer bp, size_t size) bp->inPtr = bp->endPtr = bp->buffer = emalloc(size); bp->endPtr += size; } - -void -Buf_KillTrailingSpaces(Buffer bp) -{ - while (bp->inPtr > bp->buffer + 1 && isspace(bp->inPtr[-1])) { - if (bp->inPtr[-2] == '\\') - break; - bp->inPtr--; - } -} Index: buf.h =================================================================== RCS file: /home/openbsd/cvs/src/usr.bin/make/buf.h,v retrieving revision 1.21 diff -u -p -r1.21 buf.h --- buf.h 2 Oct 2012 10:29:30 -0000 1.21 +++ buf.h 13 Oct 2012 14:22:55 -0000 @@ -131,10 +131,6 @@ do { \ * Adds characters between s and e to buffer. */ #define Buf_Addi(b, s, e) Buf_AddChars((b), (e) - (s), (s)) -/* Buf_KillTrailingSpaces(buf); - * Removes non-backslashed spaces at the end of a buffer. */ -extern void Buf_KillTrailingSpaces(Buffer); - extern void Buf_printf(Buffer, const char *, ...); #define Buf_puts(b, s) Buf_AddChars((b), strlen(s), (s)) Index: compat.c =================================================================== RCS file: /home/openbsd/cvs/src/usr.bin/make/compat.c,v retrieving revision 1.77 diff -u -p -r1.77 compat.c --- compat.c 21 Sep 2012 07:55:20 -0000 1.77 +++ compat.c 14 Oct 2012 15:15:21 -0000 @@ -86,6 +86,12 @@ CompatMake(void *gnp, /* The node to mak */ if (gn == pgn) return; + /* handle .USE right away */ + if (gn->type & OP_USE) { + Make_HandleUse(gn, pgn); + return; + } + look_harder_for_target(gn); if (pgn != NULL && is_sibling(gn, pgn)) @@ -103,9 +109,8 @@ CompatMake(void *gnp, /* The node to mak } while (sib != gn); } - if (gn->type & OP_USE) { - Make_HandleUse(gn, pgn); - } else if (gn->built_status == UNKNOWN) { + switch(gn->built_status) { + case UNKNOWN: /* First mark ourselves to be made, then apply whatever * transformations the suffix module thinks are necessary. * Once that's done, we can descend and make all our children. @@ -232,30 +237,29 @@ CompatMake(void *gnp, /* The node to mak print_errors(); exit(1); } - } else if (gn->built_status == ERROR) + break; + case ERROR: /* Already had an error when making this beastie. Tell the * parent to abort. */ pgn->must_make = false; - else { - switch (gn->built_status) { - case BEINGMADE: - Error("Graph cycles through %s", gn->name); - gn->built_status = ERROR; - pgn->must_make = false; - break; - case MADE: - if ((gn->type & OP_EXEC) == 0) { - pgn->childMade = true; - Make_TimeStamp(pgn, gn); - } - break; - case UPTODATE: - if ((gn->type & OP_EXEC) == 0) - Make_TimeStamp(pgn, gn); - break; - default: - break; + break; + case BEINGMADE: + Error("Graph cycles through %s", gn->name); + gn->built_status = ERROR; + pgn->must_make = false; + break; + case MADE: + if ((gn->type & OP_EXEC) == 0) { + pgn->childMade = true; + Make_TimeStamp(pgn, gn); } + break; + case UPTODATE: + if ((gn->type & OP_EXEC) == 0) + Make_TimeStamp(pgn, gn); + break; + default: + break; } } Index: cond.c =================================================================== RCS file: /home/openbsd/cvs/src/usr.bin/make/cond.c,v retrieving revision 1.46 diff -u -p -r1.46 cond.c --- cond.c 11 Oct 2012 14:56:17 -0000 1.46 +++ cond.c 14 Oct 2012 16:47:17 -0000 @@ -198,40 +198,42 @@ CondGetArg(const char **linePtr, struct const char *cp; cp = *linePtr; + /* Set things up to return faster in case of problem */ + arg->s = cp; + arg->e = cp; + arg->tofree = false; + + /* make and defined are not really keywords, so if CondGetArg doesn't + * work... + */ if (parens) { - while (*cp != '(' && *cp != '\0') + while (isspace(*cp)) cp++; if (*cp == '(') cp++; + else + return false; } - if (*cp == '\0') { - /* No arguments whatsoever. Because 'make' and 'defined' aren't - * really "reserved words", we don't print a message. I think - * this is better than hitting the user with a warning message - * every time s/he uses the word 'make' or 'defined' at the - * beginning of a symbol... */ - arg->s = cp; - arg->e = cp; - arg->tofree = false; + if (*cp == '\0') return false; - } - while (*cp == ' ' || *cp == '\t') + while (isspace(*cp)) cp++; - cp = VarName_Get(cp, arg, NULL, true, find_cond); - while (*cp == ' ' || *cp == '\t') - cp++; - if (parens && *cp != ')') { - Parse_Error(PARSE_WARNING, - "Missing closing parenthesis for %s()", func); - return false; - } else if (parens) - /* Advance pointer past close parenthesis. */ + while (isspace(*cp)) cp++; + if (parens) { + if (*cp == ')') + cp++; + else { + Parse_Error(PARSE_WARNING, + "Missing closing parenthesis for %s()", func); + return false; + } + } *linePtr = cp; return true; @@ -747,7 +749,7 @@ CondToken(bool doEval) return t; } - while (*condExpr == ' ' || *condExpr == '\t') + while (isspace(*condExpr)) condExpr++; switch (*condExpr) { case '(': @@ -1164,8 +1166,9 @@ Cond_End(void) condTop == 0 ? "at least ": "", MAXIF-condTop, MAXIF-condTop == 1 ? "" : "s"); for (i = MAXIF-1; i >= condTop; i--) { - fprintf(stderr, "\t at line %lu of %s\n", - condStack[i].origin.lineno, condStack[i].origin.fname); + fprintf(stderr, "\t(%s:%lu)\n", + condStack[i].origin.fname, + condStack[i].origin.lineno); } } condTop = MAXIF; Index: error.c =================================================================== RCS file: /home/openbsd/cvs/src/usr.bin/make/error.c,v retrieving revision 1.23 diff -u -p -r1.23 error.c --- error.c 2 Oct 2012 10:29:30 -0000 1.23 +++ error.c 13 Oct 2012 23:43:13 -0000 @@ -149,13 +149,19 @@ static void ParseVErrorInternal(const Location *origin, int type, const char *fmt, va_list ap) { - if (origin->fname) - (void)fprintf(stderr, "\"%s\", line %lu: ", origin->fname, origin->lineno); - if (type == PARSE_WARNING) - (void)fprintf(stderr, "warning: "); - (void)vfprintf(stderr, fmt, ap); + static bool first = true; + fprintf(stderr, "*** %s", + type == PARSE_WARNING ? "Warning" : "Parse error"); + if (first) { + fprintf(stderr, " in %s: ", Var_Value(".CURDIR")); + first = false; + } else + fprintf(stderr, ": "); + vfprintf(stderr, fmt, ap); va_end(ap); - (void)fprintf(stderr, "\n"); + if (origin->fname) + fprintf(stderr, " (%s:%lu)", origin->fname, origin->lineno); + fprintf(stderr, "\n"); if (type == PARSE_FATAL) fatal_errors ++; } Index: job.c =================================================================== RCS file: /home/openbsd/cvs/src/usr.bin/make/job.c,v retrieving revision 1.130 diff -u -p -r1.130 job.c --- job.c 9 Oct 2012 19:46:33 -0000 1.130 +++ job.c 14 Oct 2012 17:13:36 -0000 @@ -160,6 +160,9 @@ static void kill_with_sudo_maybe(pid_t, static void debug_kill_printf(const char *, ...); static void debug_vprintf(const char *, va_list); static void may_remove_target(Job *); +static const char *really_kill(Job *, int); +static void print_error(Job *); +static void internal_print_errors(void); static void kill_with_sudo_maybe(pid_t pid, int signo, const char *p) @@ -259,8 +262,8 @@ print_error(Job *j) may_remove_target(j); } -void -print_errors(void) +static void +internal_print_errors() { Job *j, *k, *jnext; @@ -282,6 +285,13 @@ print_errors(void) } } +void +print_errors(void) +{ + handle_all_signals(); + internal_print_errors(); +} + static void setup_signal(int sig) { @@ -842,7 +852,7 @@ handle_fatal_signal(int signo) } } loop_handle_running_jobs(); - print_errors(); + internal_print_errors(); /* die by that signal */ sigprocmask(SIG_BLOCK, &sigset, NULL); @@ -850,6 +860,8 @@ handle_fatal_signal(int signo) kill(getpid(), signo); sigprocmask(SIG_SETMASK, &emptyset, NULL); /*NOTREACHED*/ + fprintf(stderr, "This should never happen\n"); + exit(1); } /* Index: lowparse.c =================================================================== RCS file: /home/openbsd/cvs/src/usr.bin/make/lowparse.c,v retrieving revision 1.30 diff -u -p -r1.30 lowparse.c --- lowparse.c 2 Oct 2012 10:29:31 -0000 1.30 +++ lowparse.c 13 Oct 2012 14:23:14 -0000 @@ -279,11 +279,9 @@ Parse_ReadNextConditionalLine(Buffer lin if (c == '\n') current->origin.lineno++; } - if (c == EOF) { - Parse_Error(PARSE_FATAL, - "Unclosed conditional"); + if (c == EOF) + /* Unclosed conditional, reported by cond.c */ return NULL; - } } current->origin.lineno++; } @@ -452,7 +450,6 @@ Parse_ReadNormalLine(Buffer linebuf) return NULL; else { read_logical_line(linebuf, c); - Buf_KillTrailingSpaces(linebuf); return Buf_Retrieve(linebuf); } } @@ -489,10 +486,8 @@ Parse_FillLocation(Location *origin) void Parse_ReportErrors(void) { - if (fatal_errors) { - fprintf(stderr, - "Fatal errors encountered -- cannot continue\n"); + if (fatal_errors) exit(1); - } else + else assert(current == NULL); } Index: parse.c =================================================================== RCS file: /home/openbsd/cvs/src/usr.bin/make/parse.c,v retrieving revision 1.107 diff -u -p -r1.107 parse.c --- parse.c 9 Oct 2012 19:45:34 -0000 1.107 +++ parse.c 13 Oct 2012 14:23:17 -0000 @@ -1048,7 +1048,6 @@ strip_comments(Buffer copy, const char * break; } Buf_Addi(copy, line, p); - Buf_KillTrailingSpaces(copy); return Buf_Retrieve(copy); } } Index: varmodifiers.c =================================================================== RCS file: /home/openbsd/cvs/src/usr.bin/make/varmodifiers.c,v retrieving revision 1.32 diff -u -p -r1.32 varmodifiers.c --- varmodifiers.c 12 Oct 2012 13:20:11 -0000 1.32 +++ varmodifiers.c 13 Oct 2012 10:15:01 -0000 @@ -1514,7 +1514,7 @@ VarModifiers_Apply(char *str, const stru printf("Result is \"%s\"\n", str); } if (*tstr == '\0') - Error("Unclosed variable specification"); + Parse_Error(PARSE_FATAL, "Unclosed variable specification"); else tstr++;