=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/make/parse.c,v retrieving revision 1.106 retrieving revision 1.107 diff -c -r1.106 -r1.107 *** src/usr.bin/make/parse.c 2012/10/02 10:29:31 1.106 --- src/usr.bin/make/parse.c 2012/10/09 19:45:34 1.107 *************** *** 1,4 **** ! /* $OpenBSD: parse.c,v 1.106 2012/10/02 10:29:31 espie Exp $ */ /* $NetBSD: parse.c,v 1.29 1997/03/10 21:20:04 christos Exp $ */ /* --- 1,4 ---- ! /* $OpenBSD: parse.c,v 1.107 2012/10/09 19:45:34 espie Exp $ */ /* $NetBSD: parse.c,v 1.29 1997/03/10 21:20:04 christos Exp $ */ /* *************** *** 156,162 **** static const char *parse_do_targets(Lst, unsigned int *, const char *); static void parse_target_line(struct growableArray *, const char *, ! const char *); static void finish_commands(struct growableArray *); static void parse_commands(struct growableArray *, const char *); --- 156,162 ---- static const char *parse_do_targets(Lst, unsigned int *, const char *); static void parse_target_line(struct growableArray *, const char *, ! const char *, bool *); static void finish_commands(struct growableArray *); static void parse_commands(struct growableArray *, const char *); *************** *** 177,186 **** } specials[] = { { P(NODE_EXEC), SPECIAL_EXEC | SPECIAL_TARGETSOURCE, OP_EXEC, }, { P(NODE_IGNORE), SPECIAL_IGNORE | SPECIAL_TARGETSOURCE, OP_IGNORE, }, ! { P(NODE_INCLUDES), SPECIAL_DEPRECATED | SPECIAL_TARGET, 0, }, { P(NODE_INVISIBLE),SPECIAL_INVISIBLE | SPECIAL_TARGETSOURCE,OP_INVISIBLE, }, { P(NODE_JOIN), SPECIAL_JOIN | SPECIAL_TARGETSOURCE, OP_JOIN, }, ! { P(NODE_LIBS), SPECIAL_DEPRECATED | SPECIAL_TARGET, 0, }, { P(NODE_MADE), SPECIAL_MADE | SPECIAL_TARGETSOURCE, OP_MADE, }, { P(NODE_MAIN), SPECIAL_MAIN | SPECIAL_TARGET, 0, }, { P(NODE_MAKE), SPECIAL_MAKE | SPECIAL_TARGETSOURCE, OP_MAKE, }, --- 177,186 ---- } specials[] = { { P(NODE_EXEC), SPECIAL_EXEC | SPECIAL_TARGETSOURCE, OP_EXEC, }, { P(NODE_IGNORE), SPECIAL_IGNORE | SPECIAL_TARGETSOURCE, OP_IGNORE, }, ! { P(NODE_INCLUDES), SPECIAL_NOTHING | SPECIAL_TARGET, 0, }, { P(NODE_INVISIBLE),SPECIAL_INVISIBLE | SPECIAL_TARGETSOURCE,OP_INVISIBLE, }, { P(NODE_JOIN), SPECIAL_JOIN | SPECIAL_TARGETSOURCE, OP_JOIN, }, ! { P(NODE_LIBS), SPECIAL_NOTHING | SPECIAL_TARGET, 0, }, { P(NODE_MADE), SPECIAL_MADE | SPECIAL_TARGETSOURCE, OP_MADE, }, { P(NODE_MAIN), SPECIAL_MAIN | SPECIAL_TARGET, 0, }, { P(NODE_MAKE), SPECIAL_MAKE | SPECIAL_TARGETSOURCE, OP_MAKE, }, *************** *** 189,195 **** { P(NODE_NOTMAIN), SPECIAL_NOTMAIN | SPECIAL_TARGETSOURCE, OP_NOTMAIN, }, { P(NODE_NOTPARALLEL),SPECIAL_NOTPARALLEL | SPECIAL_TARGET, 0, }, { P(NODE_NO_PARALLEL),SPECIAL_NOTPARALLEL | SPECIAL_TARGET, 0, }, ! { P(NODE_NULL), SPECIAL_DEPRECATED | SPECIAL_TARGET, 0, }, { P(NODE_OPTIONAL), SPECIAL_OPTIONAL | SPECIAL_TARGETSOURCE,OP_OPTIONAL, }, { P(NODE_ORDER), SPECIAL_ORDER | SPECIAL_TARGET, 0, }, { P(NODE_PARALLEL), SPECIAL_PARALLEL | SPECIAL_TARGET, 0, }, --- 189,195 ---- { P(NODE_NOTMAIN), SPECIAL_NOTMAIN | SPECIAL_TARGETSOURCE, OP_NOTMAIN, }, { P(NODE_NOTPARALLEL),SPECIAL_NOTPARALLEL | SPECIAL_TARGET, 0, }, { P(NODE_NO_PARALLEL),SPECIAL_NOTPARALLEL | SPECIAL_TARGET, 0, }, ! { P(NODE_NULL), SPECIAL_NOTHING | SPECIAL_TARGET, 0, }, { P(NODE_OPTIONAL), SPECIAL_OPTIONAL | SPECIAL_TARGETSOURCE,OP_OPTIONAL, }, { P(NODE_ORDER), SPECIAL_ORDER | SPECIAL_TARGET, 0, }, { P(NODE_PARALLEL), SPECIAL_PARALLEL | SPECIAL_TARGET, 0, }, *************** *** 198,212 **** { P(NODE_PRECIOUS), SPECIAL_PRECIOUS | SPECIAL_TARGETSOURCE,OP_PRECIOUS, }, { P(NODE_RECURSIVE),SPECIAL_MAKE | SPECIAL_TARGETSOURCE, OP_MAKE, }, { P(NODE_SILENT), SPECIAL_SILENT | SPECIAL_TARGETSOURCE, OP_SILENT, }, ! { P(NODE_SINGLESHELL),SPECIAL_SINGLESHELL | SPECIAL_TARGET, 0, }, { P(NODE_SUFFIXES), SPECIAL_SUFFIXES | SPECIAL_TARGET, 0, }, { P(NODE_USE), SPECIAL_USE | SPECIAL_TARGETSOURCE, OP_USE, }, { P(NODE_WAIT), SPECIAL_WAIT | SPECIAL_TARGETSOURCE, 0 }, { P(NODE_CHEAP), SPECIAL_CHEAP | SPECIAL_TARGETSOURCE, OP_CHEAP, }, { P(NODE_EXPENSIVE),SPECIAL_EXPENSIVE | SPECIAL_TARGETSOURCE,OP_EXPENSIVE, }, ! #if 0 ! { P(NODE_NOPATH), SPECIAL_NOPATH, }, ! #endif }; #undef P --- 198,211 ---- { P(NODE_PRECIOUS), SPECIAL_PRECIOUS | SPECIAL_TARGETSOURCE,OP_PRECIOUS, }, { P(NODE_RECURSIVE),SPECIAL_MAKE | SPECIAL_TARGETSOURCE, OP_MAKE, }, { P(NODE_SILENT), SPECIAL_SILENT | SPECIAL_TARGETSOURCE, OP_SILENT, }, ! { P(NODE_SINGLESHELL),SPECIAL_NOTHING | SPECIAL_TARGET, 0, }, { P(NODE_SUFFIXES), SPECIAL_SUFFIXES | SPECIAL_TARGET, 0, }, { P(NODE_USE), SPECIAL_USE | SPECIAL_TARGETSOURCE, OP_USE, }, { P(NODE_WAIT), SPECIAL_WAIT | SPECIAL_TARGETSOURCE, 0 }, { P(NODE_CHEAP), SPECIAL_CHEAP | SPECIAL_TARGETSOURCE, OP_CHEAP, }, { P(NODE_EXPENSIVE),SPECIAL_EXPENSIVE | SPECIAL_TARGETSOURCE,OP_EXPENSIVE, }, ! { P(NODE_POSIX), SPECIAL_NOTHING | SPECIAL_TARGET, 0 }, ! { P(NODE_SCCS_GET), SPECIAL_NOTHING | SPECIAL_TARGET, 0 }, }; #undef P *************** *** 722,732 **** extern int maxJobs; maxJobs = 1; - break; - } - case SPECIAL_SINGLESHELL: compatMake = 1; break; case SPECIAL_ORDER: predecessor = NULL; break; --- 721,729 ---- extern int maxJobs; maxJobs = 1; compatMake = 1; break; + } case SPECIAL_ORDER: predecessor = NULL; break; *************** *** 858,868 **** break; } } else if (specType == SPECIAL_MFLAGS) { ! /*Call on functions in main.c to deal with these arguments */ Main_ParseArgLine(line); return; ! } else if (specType == SPECIAL_NOTPARALLEL || ! specType == SPECIAL_SINGLESHELL) { return; } --- 855,864 ---- break; } } else if (specType == SPECIAL_MFLAGS) { ! /* Call on functions in main.c to deal with these arguments */ Main_ParseArgLine(line); return; ! } else if (specType == SPECIAL_NOTPARALLEL) { return; } *************** *** 870,876 **** * NOW GO FOR THE SOURCES */ if (specType == SPECIAL_SUFFIXES || specType == SPECIAL_PATH || ! specType == SPECIAL_DEPRECATED) { while (*line) { /* * If the target was one that doesn't take files as its --- 866,872 ---- * NOW GO FOR THE SOURCES */ if (specType == SPECIAL_SUFFIXES || specType == SPECIAL_PATH || ! specType == SPECIAL_NOTHING) { while (*line) { /* * If the target was one that doesn't take files as its *************** *** 988,1023 **** * ParseAddCmd -- * Lst_ForEach function to add a command line to all targets * ! * Side Effects: ! * A new element is added to the commands list of the node. */ static void ParseAddCmd(void *gnp, void *cmd) { GNode *gn = (GNode *)gnp; ! /* if target already supplied, ignore commands */ if (!(gn->type & OP_HAS_COMMANDS)) Lst_AtEnd(&gn->commands, cmd); } /*- *----------------------------------------------------------------------- * ParseHasCommands -- ! * Callback procedure for Parse_File when destroying the list of ! * targets on the last dependency line. Marks a target as already ! * having commands if it does, to keep from having shell commands ! * on multiple dependency lines. ! * ! * Side Effects: ! * OP_HAS_COMMANDS may be set for the target. *----------------------------------------------------------------------- */ static void ! ParseHasCommands(void *gnp) /* Node to examine */ { GNode *gn = (GNode *)gnp; ! if (!Lst_IsEmpty(&gn->commands)) ! gn->type |= OP_HAS_COMMANDS; } --- 984,1023 ---- * ParseAddCmd -- * Lst_ForEach function to add a command line to all targets * ! * The new command may be added to the commands list of the node. ! * ! * If the target already had commands, we ignore the new ones, but ! * we note that we got double commands (in case we actually get to run ! * that ambiguous target). ! * ! * Note this does not apply to :: dependency lines, since those ! * will generate fresh cloned nodes and add them to the cohorts ! * field of the main node. */ static void ParseAddCmd(void *gnp, void *cmd) { GNode *gn = (GNode *)gnp; ! if (!(gn->type & OP_HAS_COMMANDS)) Lst_AtEnd(&gn->commands, cmd); + else + gn->type |= OP_DOUBLE; } /*- *----------------------------------------------------------------------- * ParseHasCommands -- ! * Record that the target gained commands through OP_HAS_COMMANDS, ! * so that double command lists may be ignored. *----------------------------------------------------------------------- */ static void ! ParseHasCommands(void *gnp) { GNode *gn = (GNode *)gnp; ! gn->type |= OP_HAS_COMMANDS; ! } *************** *** 1383,1392 **** ***/ static void finish_commands(struct growableArray *targets) { Array_Every(targets, ParseHasCommands); - Array_Reset(targets); } static void --- 1383,1430 ---- ***/ static void + build_target_group(struct growableArray *targets) + { + unsigned int i; + LstNode ln; + bool seen_target = false; + + if (targets->n == 1) + return; + if (targets->a[0]->groupling != NULL) + return; + /* XXX */ + if (targets->a[0]->type & OP_TRANSFORM) + return; + for (ln = Lst_First(&targets->a[0]->commands); ln != NULL; + ln = Lst_Adv(ln)) { + struct command *cmd = Lst_Datum(ln); + if (Var_Check_for_target(cmd->string)) { + seen_target = true; + break; + } + } + if (DEBUG(TARGGROUP)) { + fprintf(stderr, + seen_target ? "No target group at %lu: ": + "Target group at %lu:", Parse_Getlineno()); + for (i = 0; i < targets->n; i++) + fprintf(stderr, " %s", targets->a[i]->name); + fprintf(stderr, "\n"); + } + if (seen_target) + return; + + for (i = 0; i < targets->n; i++) { + targets->a[i]->groupling = targets->a[(i+1)%targets->n]; + } + } + + static void finish_commands(struct growableArray *targets) { + build_target_group(targets); Array_Every(targets, ParseHasCommands); } static void *************** *** 1402,1408 **** memcpy(&cmd->string, line, len+1); Parse_FillLocation(&cmd->location); - Array_ForEach(targets, ParseAddCmd, cmd); } --- 1440,1445 ---- *************** *** 1438,1444 **** static void parse_target_line(struct growableArray *targets, const char *line, ! const char *stripped) { size_t pos; char *end; --- 1475,1481 ---- static void parse_target_line(struct growableArray *targets, const char *line, ! const char *stripped, bool *pcommands_seen) { size_t pos; char *end; *************** *** 1476,1483 **** do { cmd++; } while (isspace(*cmd)); ! if (*cmd != '\0') parse_commands(targets, cmd); } } --- 1513,1522 ---- do { cmd++; } while (isspace(*cmd)); ! if (*cmd != '\0') { parse_commands(targets, cmd); + *pcommands_seen = true; + } } } *************** *** 1486,1491 **** --- 1525,1531 ---- { char *line; bool expectingCommands = false; + bool commands_seen = false; /* somewhat permanent spaces to shave time */ BUFFER buf; *************** *** 1498,1506 **** do { while ((line = Parse_ReadNormalLine(&buf)) != NULL) { if (*line == '\t') { ! if (expectingCommands) parse_commands(>argets, line+1); ! else Parse_Error(PARSE_FATAL, "Unassociated shell command \"%s\"", line); --- 1538,1547 ---- do { while ((line = Parse_ReadNormalLine(&buf)) != NULL) { if (*line == '\t') { ! if (expectingCommands) { ! commands_seen = true; parse_commands(>argets, line+1); ! } else Parse_Error(PARSE_FATAL, "Unassociated shell command \"%s\"", line); *************** *** 1509,1521 **** line); if (!parse_as_special_line(&buf, ©, stripped)) { ! if (expectingCommands) finish_commands(>argets); if (Parse_As_Var_Assignment(stripped)) expectingCommands = false; else { parse_target_line(>argets, ! line, stripped); expectingCommands = true; } } --- 1550,1565 ---- line); if (!parse_as_special_line(&buf, ©, stripped)) { ! if (commands_seen) finish_commands(>argets); + commands_seen = false; + Array_Reset(>argets); if (Parse_As_Var_Assignment(stripped)) expectingCommands = false; else { parse_target_line(>argets, ! line, stripped, ! &commands_seen); expectingCommands = true; } } *************** *** 1523,1529 **** } } while (Parse_NextFile()); ! if (expectingCommands) finish_commands(>argets); /* Make sure conditionals are clean. */ Cond_End(); --- 1567,1573 ---- } } while (Parse_NextFile()); ! if (commands_seen) finish_commands(>argets); /* Make sure conditionals are clean. */ Cond_End();