1627{
1628 DEBUG_open <<
"Reading rule for target " << first <<
"... ";
1629 if (false)
1630 {
1631 error:
1633 std::cerr << "Failed to load rules: syntax error" << std::endl;
1634 exit(EXIT_FAILURE);
1635 }
1636
1637
1640 if (!first.empty()) targets.push_front(first);
1641 else if (targets.empty()) goto error;
1642 else DEBUG <<
"actual target: " << targets.front() << std::endl;
1643 bool generic = false;
1645 for (string_list::const_iterator i = targets.begin(),
1646 i_end = targets.end(); i != i_end; ++i)
1647 {
1648 if (i->empty()) goto error;
1649 if ((i->find('%') != std::string::npos) != generic)
1650 {
1651 if (i == targets.begin()) generic = true;
1652 else goto error;
1653 }
1654 }
1656 if (in.get() != ':') goto error;
1657
1658 bool assignment = false, static_pattern = false;
1659
1662
1663
1664 {
1667 {
1670 {
1675 assignment = true;
1676 goto end_line;
1677 }
1678 v.push_back(d);
1679 }
1680
1684
1686 {
1692 if (rule.
targets.empty())
goto error;
1693 for (string_list::const_iterator i = rule.
targets.begin(),
1694 i_end = rule.
targets.end(); i != i_end; ++i)
1695 {
1696 if (i->find('%') == std::string::npos) goto error;
1697 }
1698 generic = false;
1699 static_pattern = true;
1700 }
1701
1703 {
1707 }
1708 }
1709
1710 end_line:
1712 if (!
skip_eol(in,
true))
goto error;
1713
1714
1715 std::ostringstream buf;
1716 while (true)
1717 {
1718 char c = in.get();
1719 if (!in.good()) break;
1720 if (c == '\t' || c == ' ')
1721 {
1722 in.get(*buf.rdbuf());
1723 if (in.fail() && !in.eof()) in.clear();
1724 }
1725 else if (c == '\r' || c == '\n')
1726 buf << c;
1727 else
1728 {
1729 in.putback(c);
1730 break;
1731 }
1732 }
1734
1735
1736 if (rule.
targets.front() ==
".PHONY")
1737 {
1738 for (string_list::const_iterator i = rule.
deps.begin(),
1739 i_end = rule.
deps.end(); i != i_end; ++i)
1740 {
1742 }
1743 return;
1744 }
1745
1746
1747 if (generic)
1748 {
1749 if (assignment) goto error;
1751 return;
1752 }
1753
1754 if (!static_pattern)
1755 {
1756 if (!rule.
script.empty() && assignment)
goto error;
1758 return;
1759 }
1760
1761 for (string_list::const_iterator i = targets.begin(),
1762 i_end = targets.end(); i != i_end; ++i)
1763 {
1767 }
1768}
static bool skip_eol(std::istream &in, bool multi=false)
static int expect_token(std::istream &in, int mask)
static std::string read_word(std::istream &in, bool detect_equal=true)
static void skip_spaces(std::istream &in)
static void register_rule(rule_t const &rule)
static void normalize_list(string_list &l, std::string const &w, std::string const &p)
static void instantiate_rule(std::string const &target, rule_t const &src, rule_t &dst)
static bool read_words(input_generator &in, string_list &res)
static rule_list generic_rules
std::list< std::string > string_list
@ Todo
Target is missing or obsolete.
assign_map assigns
Assignment of variables.
string_list wdeps
Like deps, except that they are not registered as dependencies.
std::string script
Shell script for building the targets.
string_list targets
Files produced by this rule.
std::string stem
Stem used to instantiate the rule, if any.
string_list deps
Dependencies used for an implicit call to remake at the start of the script.