1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
// file : build/rule -*- C++ -*-
// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
#ifndef BUILD_RULE
#define BUILD_RULE
#include <string>
#include <cstddef> // nullptr_t
#include <build/types>
#include <build/target>
#include <build/operation>
namespace build
{
class match_result
{
public:
typedef build::target target_type;
typedef build::prerequisite prerequisite_type;
// Can contain neither (both are NULL), one of, or both. If both
// are NULL, then it is a "no match" indicator.
//
// Note that if the "payload" is stored in *value instead of
// prerequisite, then target must not be NULL.
//
union
{
prerequisite_type* prerequisite;
bool bvalue;
void* pvalue;
const void* cpvalue;
};
target_type* target;
action recipe_action = action (); // Used as recipe's action if set.
match_result (std::nullptr_t v = nullptr): prerequisite (v), target (v) {}
match_result (prerequisite_type& p): prerequisite (&p), target (nullptr) {}
match_result (prerequisite_type* p): prerequisite (p), target (nullptr) {}
match_result (target_type& t): prerequisite (nullptr), target (&t) {}
match_result (target_type* t): prerequisite (nullptr), target (t) {}
match_result (const prerequisite_member& pm)
: prerequisite (&pm.prerequisite.get ()), target (pm.target) {}
match_result (target_type& t, bool v): bvalue (v), target (&t) {}
match_result (target_type& t, void* v): pvalue (v), target (&t) {}
match_result (target_type& t, const void* v): cpvalue (v), target (&t) {}
match_result (target_type& t, std::nullptr_t v): pvalue (v), target (&t) {}
explicit
operator bool () const
{
return target != nullptr || prerequisite != nullptr;
}
};
class rule
{
public:
virtual match_result
match (action, target&, const std::string& hint) const = 0;
virtual recipe
apply (action, target&, const match_result&) const = 0;
};
// Fallback rule that on update verifies that the file exists and is
// not older than any of its prerequisites.
//
class file_rule: public rule
{
public:
virtual match_result
match (action, target&, const std::string& hint) const;
virtual recipe
apply (action, target&, const match_result&) const;
static target_state
perform_update (action, target&);
static file_rule instance;
};
class alias_rule: public rule
{
public:
virtual match_result
match (action, target&, const std::string& hint) const;
virtual recipe
apply (action, target&, const match_result&) const;
static alias_rule instance;
};
class fsdir_rule: public rule
{
public:
virtual match_result
match (action, target&, const std::string& hint) const;
virtual recipe
apply (action, target&, const match_result&) const;
static target_state
perform_update (action, target&);
static target_state
perform_clean (action, target&);
static fsdir_rule instance;
};
// Fallback rule that always matches and does nothing.
//
class fallback_rule: public build::rule
{
public:
virtual match_result
match (action, target& t, const std::string&) const {return t;}
virtual recipe
apply (action, target&, const match_result&) const {return noop_recipe;}
static fallback_rule instance;
};
}
#endif // BUILD_RULE
|