78 |
{ |
{ |
79 |
unsigned int if_cmds; /* Depth of conditional nesting. */ |
unsigned int if_cmds; /* Depth of conditional nesting. */ |
80 |
unsigned int allocated; /* Elts allocated in following arrays. */ |
unsigned int allocated; /* Elts allocated in following arrays. */ |
81 |
char *ignoring; /* Are we ignoring or interepreting? */ |
char *ignoring; /* Are we ignoring or interpreting? |
82 |
|
0=interpreting, 1=not yet interpreted, |
83 |
|
2=already interpreted */ |
84 |
char *seen_else; /* Have we already seen an `else'? */ |
char *seen_else; /* Have we already seen an `else'? */ |
85 |
}; |
}; |
86 |
|
|
132 |
static void do_define PARAMS ((char *name, unsigned int namelen, |
static void do_define PARAMS ((char *name, unsigned int namelen, |
133 |
enum variable_origin origin, |
enum variable_origin origin, |
134 |
struct ebuffer *ebuf)); |
struct ebuffer *ebuf)); |
135 |
static int conditional_line PARAMS ((char *line, const struct floc *flocp)); |
static int conditional_line PARAMS ((char *line, int len, const struct floc *flocp)); |
136 |
static void record_files PARAMS ((struct nameseq *filenames, char *pattern, char *pattern_percent, |
static void record_files PARAMS ((struct nameseq *filenames, char *pattern, char *pattern_percent, |
137 |
struct dep *deps, unsigned int cmds_started, char *commands, |
struct dep *deps, unsigned int cmds_started, char *commands, |
138 |
unsigned int commands_idx, int two_colon, |
unsigned int commands_idx, int two_colon, |
615 |
ignoring anything, since they control what we will do with |
ignoring anything, since they control what we will do with |
616 |
following lines. */ |
following lines. */ |
617 |
|
|
618 |
if (!in_ignored_define |
if (!in_ignored_define) |
|
&& (word1eq ("ifdef") || word1eq ("ifndef") |
|
|
|| word1eq ("ifeq") || word1eq ("ifneq") |
|
|
|| word1eq ("else") || word1eq ("endif"))) |
|
619 |
{ |
{ |
620 |
int i = conditional_line (p, fstart); |
int i = conditional_line (p, len, fstart); |
621 |
if (i < 0) |
if (i != -2) |
622 |
fatal (fstart, _("invalid syntax in conditional")); |
{ |
623 |
|
if (i == -1) |
624 |
|
fatal (fstart, _("invalid syntax in conditional")); |
625 |
|
|
626 |
ignoring = i; |
ignoring = i; |
627 |
continue; |
continue; |
628 |
|
} |
629 |
} |
} |
630 |
|
|
631 |
if (word1eq ("endef")) |
if (word1eq ("endef")) |
1422 |
FILENAME and LINENO are the filename and line number in the |
FILENAME and LINENO are the filename and line number in the |
1423 |
current makefile. They are used for error messages. |
current makefile. They are used for error messages. |
1424 |
|
|
1425 |
Value is -1 if the line is invalid, |
Value is -2 if the line is not a conditional at all, |
1426 |
|
-1 if the line is an invalid conditional, |
1427 |
0 if following text should be interpreted, |
0 if following text should be interpreted, |
1428 |
1 if following text should be ignored. */ |
1 if following text should be ignored. */ |
1429 |
|
|
1430 |
static int |
static int |
1431 |
conditional_line (char *line, const struct floc *flocp) |
conditional_line (char *line, int len, const struct floc *flocp) |
1432 |
{ |
{ |
|
int notdef; |
|
1433 |
char *cmdname; |
char *cmdname; |
1434 |
register unsigned int i; |
enum { c_ifdef, c_ifndef, c_ifeq, c_ifneq, c_else, c_endif } cmdtype; |
1435 |
|
unsigned int i; |
1436 |
if (*line == 'i') |
unsigned int o; |
1437 |
{ |
|
1438 |
/* It's an "if..." command. */ |
/* Compare a word, both length and contents. */ |
1439 |
notdef = line[2] == 'n'; |
#define word1eq(s) (len == sizeof(s)-1 && strneq (s, line, sizeof(s)-1)) |
1440 |
if (notdef) |
#define chkword(s, t) if (word1eq (s)) { cmdtype = (t); cmdname = (s); } |
1441 |
{ |
|
1442 |
cmdname = line[3] == 'd' ? "ifndef" : "ifneq"; |
/* Make sure this line is a conditional. */ |
1443 |
line += cmdname[3] == 'd' ? 7 : 6; |
chkword ("ifdef", c_ifdef) |
1444 |
} |
else chkword ("ifndef", c_ifndef) |
1445 |
else |
else chkword ("ifeq", c_ifeq) |
1446 |
{ |
else chkword ("ifneq", c_ifneq) |
1447 |
cmdname = line[2] == 'd' ? "ifdef" : "ifeq"; |
else chkword ("else", c_else) |
1448 |
line += cmdname[2] == 'd' ? 6 : 5; |
else chkword ("endif", c_endif) |
|
} |
|
|
} |
|
1449 |
else |
else |
1450 |
{ |
return -2; |
1451 |
/* It's an "else" or "endif" command. */ |
|
1452 |
notdef = line[1] == 'n'; |
/* Found one: skip past it and any whitespace after it. */ |
1453 |
cmdname = notdef ? "endif" : "else"; |
line = next_token (line + len); |
|
line += notdef ? 5 : 4; |
|
|
} |
|
1454 |
|
|
1455 |
line = next_token (line); |
#define EXTRANEOUS() error (flocp, _("Extraneous text after `%s' directive"), cmdname) |
1456 |
|
|
1457 |
if (*cmdname == 'e') |
/* An 'endif' cannot contain extra text, and reduces the if-depth by 1 */ |
1458 |
|
if (cmdtype == c_endif) |
1459 |
{ |
{ |
1460 |
if (*line != '\0') |
if (*line != '\0') |
1461 |
error (flocp, _("Extraneous text after `%s' directive"), cmdname); |
EXTRANEOUS (); |
1462 |
/* "Else" or "endif". */ |
|
1463 |
if (conditionals->if_cmds == 0) |
if (!conditionals->if_cmds) |
1464 |
fatal (flocp, _("extraneous `%s'"), cmdname); |
fatal (flocp, _("extraneous `%s'"), cmdname); |
1465 |
/* NOTDEF indicates an `endif' command. */ |
|
1466 |
if (notdef) |
--conditionals->if_cmds; |
1467 |
--conditionals->if_cmds; |
|
1468 |
else if (conditionals->seen_else[conditionals->if_cmds - 1]) |
goto DONE; |
1469 |
fatal (flocp, _("only one `else' per conditional")); |
} |
1470 |
|
|
1471 |
|
/* An 'else' statement can either be simple, or it can have another |
1472 |
|
conditional after it. */ |
1473 |
|
if (cmdtype == c_else) |
1474 |
|
{ |
1475 |
|
const char *p; |
1476 |
|
|
1477 |
|
if (!conditionals->if_cmds) |
1478 |
|
fatal (flocp, _("extraneous `%s'"), cmdname); |
1479 |
|
|
1480 |
|
o = conditionals->if_cmds - 1; |
1481 |
|
|
1482 |
|
if (conditionals->seen_else[o]) |
1483 |
|
fatal (flocp, _("only one `else' per conditional")); |
1484 |
|
|
1485 |
|
/* Change the state of ignorance. */ |
1486 |
|
switch (conditionals->ignoring[o]) |
1487 |
|
{ |
1488 |
|
case 0: |
1489 |
|
/* We've just been interpreting. Never do it again. */ |
1490 |
|
conditionals->ignoring[o] = 2; |
1491 |
|
break; |
1492 |
|
case 1: |
1493 |
|
/* We've never interpreted yet. Maybe this time! */ |
1494 |
|
conditionals->ignoring[o] = 0; |
1495 |
|
break; |
1496 |
|
} |
1497 |
|
|
1498 |
|
/* It's a simple 'else'. */ |
1499 |
|
if (*line == '\0') |
1500 |
|
{ |
1501 |
|
conditionals->seen_else[o] = 1; |
1502 |
|
goto DONE; |
1503 |
|
} |
1504 |
|
|
1505 |
|
/* The 'else' has extra text. That text must be another conditional |
1506 |
|
and cannot be an 'else' or 'endif'. */ |
1507 |
|
|
1508 |
|
/* Find the length of the next word. */ |
1509 |
|
for (p = line+1; *p != '\0' && !isspace ((unsigned char)*p); ++p) |
1510 |
|
; |
1511 |
|
len = p - line; |
1512 |
|
|
1513 |
|
/* If it's 'else' or 'endif' or an illegal conditional, fail. */ |
1514 |
|
if (word1eq("else") || word1eq("endif") |
1515 |
|
|| conditional_line (line, len, flocp) < 0) |
1516 |
|
EXTRANEOUS (); |
1517 |
else |
else |
1518 |
{ |
{ |
1519 |
/* Toggle the state of ignorance. */ |
/* conditional_line() created a new level of conditional. |
1520 |
conditionals->ignoring[conditionals->if_cmds - 1] |
Raise it back to this level. */ |
1521 |
= !conditionals->ignoring[conditionals->if_cmds - 1]; |
if (conditionals->ignoring[o] < 2) |
1522 |
/* Record that we have seen an `else' in this conditional. |
conditionals->ignoring[o] = conditionals->ignoring[o+1]; |
1523 |
A second `else' will be erroneous. */ |
--conditionals->if_cmds; |
1524 |
conditionals->seen_else[conditionals->if_cmds - 1] = 1; |
} |
1525 |
} |
|
1526 |
for (i = 0; i < conditionals->if_cmds; ++i) |
goto DONE; |
|
if (conditionals->ignoring[i]) |
|
|
return 1; |
|
|
return 0; |
|
1527 |
} |
} |
1528 |
|
|
1529 |
if (conditionals->allocated == 0) |
if (conditionals->allocated == 0) |
1533 |
conditionals->seen_else = (char *) xmalloc (conditionals->allocated); |
conditionals->seen_else = (char *) xmalloc (conditionals->allocated); |
1534 |
} |
} |
1535 |
|
|
1536 |
++conditionals->if_cmds; |
o = conditionals->if_cmds++; |
1537 |
if (conditionals->if_cmds > conditionals->allocated) |
if (conditionals->if_cmds > conditionals->allocated) |
1538 |
{ |
{ |
1539 |
conditionals->allocated += 5; |
conditionals->allocated += 5; |
1544 |
} |
} |
1545 |
|
|
1546 |
/* Record that we have seen an `if...' but no `else' so far. */ |
/* Record that we have seen an `if...' but no `else' so far. */ |
1547 |
conditionals->seen_else[conditionals->if_cmds - 1] = 0; |
conditionals->seen_else[o] = 0; |
1548 |
|
|
1549 |
/* Search through the stack to see if we're already ignoring. */ |
/* Search through the stack to see if we're already ignoring. */ |
1550 |
for (i = 0; i < conditionals->if_cmds - 1; ++i) |
for (i = 0; i < o; ++i) |
1551 |
if (conditionals->ignoring[i]) |
if (conditionals->ignoring[i]) |
1552 |
{ |
{ |
1553 |
/* We are already ignoring, so just push a level |
/* We are already ignoring, so just push a level to match the next |
1554 |
to match the next "else" or "endif", and keep ignoring. |
"else" or "endif", and keep ignoring. We don't want to expand |
1555 |
We don't want to expand variables in the condition. */ |
variables in the condition. */ |
1556 |
conditionals->ignoring[conditionals->if_cmds - 1] = 1; |
conditionals->ignoring[o] = 1; |
1557 |
return 1; |
return 1; |
1558 |
} |
} |
1559 |
|
|
1560 |
if (cmdname[notdef ? 3 : 2] == 'd') |
if (cmdtype == c_ifdef || cmdtype == c_ifndef) |
1561 |
{ |
{ |
|
/* "Ifdef" or "ifndef". */ |
|
1562 |
char *var; |
char *var; |
1563 |
struct variable *v; |
struct variable *v; |
1564 |
register char *p; |
char *p; |
1565 |
|
|
1566 |
/* Expand the thing we're looking up, so we can use indirect and |
/* Expand the thing we're looking up, so we can use indirect and |
1567 |
constructed variable names. */ |
constructed variable names. */ |
1575 |
return -1; |
return -1; |
1576 |
|
|
1577 |
var[i] = '\0'; |
var[i] = '\0'; |
1578 |
v = lookup_variable (var, strlen (var)); |
v = lookup_variable (var, i); |
1579 |
conditionals->ignoring[conditionals->if_cmds - 1] |
|
1580 |
= (v != 0 && *v->value != '\0') == notdef; |
conditionals->ignoring[o] = |
1581 |
|
((v != 0 && *v->value != '\0') == (cmdtype == c_ifndef)); |
1582 |
|
|
1583 |
free (var); |
free (var); |
1584 |
} |
} |
1596 |
/* Find the end of the first string. */ |
/* Find the end of the first string. */ |
1597 |
if (termin == ',') |
if (termin == ',') |
1598 |
{ |
{ |
1599 |
register int count = 0; |
int count = 0; |
1600 |
for (; *line != '\0'; ++line) |
for (; *line != '\0'; ++line) |
1601 |
if (*line == '(') |
if (*line == '(') |
1602 |
++count; |
++count; |
1670 |
*line = '\0'; |
*line = '\0'; |
1671 |
line = next_token (++line); |
line = next_token (++line); |
1672 |
if (*line != '\0') |
if (*line != '\0') |
1673 |
error (flocp, _("Extraneous text after `%s' directive"), cmdname); |
EXTRANEOUS (); |
1674 |
|
|
1675 |
s2 = variable_expand (s2); |
s2 = variable_expand (s2); |
1676 |
conditionals->ignoring[conditionals->if_cmds - 1] |
conditionals->ignoring[o] = (streq (s1, s2) == (cmdtype == c_ifneq)); |
|
= streq (s1, s2) == notdef; |
|
1677 |
} |
} |
1678 |
|
|
1679 |
|
DONE: |
1680 |
/* Search through the stack to see if we're ignoring. */ |
/* Search through the stack to see if we're ignoring. */ |
1681 |
for (i = 0; i < conditionals->if_cmds; ++i) |
for (i = 0; i < conditionals->if_cmds; ++i) |
1682 |
if (conditionals->ignoring[i]) |
if (conditionals->ignoring[i]) |