1629{
1630 DEBUG_open <<
"Reading rule for target " << first <<
"... ";
1631 if (false)
1632 {
1633 error:
1635 std::cerr << "Failed to load rules: syntax error" << std::endl;
1636 exit(EXIT_FAILURE);
1637 }
1638
1639
1642 if (!first.empty()) targets.push_front(first);
1643 else if (targets.empty()) goto error;
1644 else DEBUG <<
"actual target: " << targets.front() << std::endl;
1645 bool generic = false;
1647 for (string_list::const_iterator i = targets.begin(),
1648 i_end = targets.end(); i != i_end; ++i)
1649 {
1650 if (i->empty()) goto error;
1651 if ((i->find('%') != std::string::npos) != generic)
1652 {
1653 if (i == targets.begin()) generic = true;
1654 else goto error;
1655 }
1656 }
1658 if (in.get() != ':') goto error;
1659
1660 bool assignment = false, static_pattern = false;
1661
1664
1665
1666 {
1669 {
1672 {
1677 assignment = true;
1678 goto end_line;
1679 }
1680 v.push_back(d);
1681 }
1682
1686
1688 {
1694 if (rule.
targets.empty())
goto error;
1695 for (string_list::const_iterator i = rule.
targets.begin(),
1696 i_end = rule.
targets.end(); i != i_end; ++i)
1697 {
1698 if (i->find('%') == std::string::npos) goto error;
1699 }
1700 generic = false;
1701 static_pattern = true;
1702 }
1703
1705 {
1709 }
1710 }
1711
1712 end_line:
1714 if (!
skip_eol(in,
true))
goto error;
1715
1716
1717 std::ostringstream buf;
1718 while (true)
1719 {
1720 char c = in.get();
1721 if (!in.good()) break;
1722 if (c == '\t' || c == ' ')
1723 {
1724 in.get(*buf.rdbuf());
1725 if (in.fail() && !in.eof()) in.clear();
1726 }
1727 else if (c == '\r' || c == '\n')
1728 buf << c;
1729 else
1730 {
1731 in.putback(c);
1732 break;
1733 }
1734 }
1736
1737
1738 if (rule.
targets.front() ==
".PHONY")
1739 {
1740 for (string_list::const_iterator i = rule.
deps.begin(),
1741 i_end = rule.
deps.end(); i != i_end; ++i)
1742 {
1744 }
1745 return;
1746 }
1747
1748
1749 if (generic)
1750 {
1751 if (assignment) goto error;
1753 return;
1754 }
1755
1756 if (!static_pattern)
1757 {
1758 if (!rule.
script.empty() && assignment)
goto error;
1760 return;
1761 }
1762
1763 for (string_list::const_iterator i = targets.begin(),
1764 i_end = targets.end(); i != i_end; ++i)
1765 {
1769 }
1770}
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.