70 auto first = _contributors.begin();
71 auto last = _contributors.end();
72 for ( ;first != last; ++first) {
73 int submax = (*first)->snapshot_max();
83 _defn.reset(
new string(defn));
89 make_dirty(pseudo_snapshot::define_in_progress);
92 set_parameters(params);
100 make_dirty(pseudo_snapshot::undef_in_progress);
110 set<string>::const_iterator lb =
111 _selected_symbols_set_.lower_bound(name);
112 if (lb != _selected_symbols_set_.end() &&
113 (name == *lb || wildcard_match(*lb,name))) {
116 return lb != _selected_symbols_set_.begin() && wildcard_match(*--lb,name);
126 #if CXX11_HAVE_STRING_BACK
127 if (wildcard.back() !=
'*') {
129 if (*(--wildcard.end()) !=
'*') {
133 size_t min_len = wildcard.length() - 1;
134 if (name.length() < min_len) {
137 return memcmp(name.data(),wildcard.data(),min_len) == 0;
144 size_t leader = arg.find(
',');
145 for ( ;leader != string::npos;
146 follower = leader + 1,leader = arg.find(
',',follower)) {
147 string pattern = arg.substr(follower,leader - follower);
148 if (pattern.length()) {
149 add_pattern(pattern);
152 if (follower < arg.length()) {
153 add_pattern(arg.substr(follower));
159 auto first = _contributors.begin();
160 auto const last = _contributors.end();
161 for ( ;first != last; ++first) {
162 (*first)->report_premiere();
165 if (origin() == provenance::global) {
167 if (!ref.reported()) {
175 auto i = _sym_tab_.begin();
177 for ( ; i != _sym_tab_.end(); ++i) {
178 nsyms += i->second._provenance == source;
185 static bool done =
false;
191 auto i = _sym_tab_.begin();
192 for ( i = _sym_tab_.begin(); i != _sym_tab_.end(); ++i) {
193 if (i->second.origin() == provenance::global) {
194 i->second.report_premiere();
201 if (which_parameter(other.id()) != string::npos) {
205 make_self_referential();
208 if (other->subscribes_to(_loc)) {
209 make_self_referential();
210 other->make_self_referential();
213 if (find(_contributors.begin(),_contributors.end(),other) ==
214 _contributors.end()) {
215 _contributors.push_back(other);
216 other->_subscribers.push_back(_loc);
218 for (
auto i = other->_contributors.begin();
219 i != other->_contributors.end(); ++i) {
225 return find(_contributors.begin(),_contributors.end(),other) !=
231 if (!_defn || _defn->empty()) {
234 assert(_contributors.empty());
242 if (args && _loc != loc && !loc->configured() && !loc->invoked()) {
243 loc->set_parameters(args.size());
249 auto i = _contributors.begin();
250 for ( ;i != _contributors.end(); ++i) {
251 auto & contributes_to = (*i)->_subscribers;
252 auto j = find(contributes_to.begin(),contributes_to.end(),_loc);
253 if (j != contributes_to.end()) {
254 contributes_to.erase(j);
257 _contributors.clear();
262 if (count() <
size_t(_last_global_snapshot_) + 1) {
266 auto i = ++_sym_tab_.begin();
268 for ( ;i != _sym_tab_.end(); ++i) {
269 i->second.unsubscribe();
273 for (i = ++_sym_tab_.begin(); i != _sym_tab_.end();) {
274 if (i->second.origin() == provenance::transient) {
275 i = _sym_tab_.erase(i);
282 for (i = ++_sym_tab_.begin(); i != _sym_tab_.end(); ++i) {
286 if (i->second.origin() == provenance::global) {
287 i->second.subscribe();
289 i->second.clear_parameters();
290 i->second.set_invoked(
false);
293 _current_snapshot_ = count();
295 report_global_config();
306 if (!clean() && !_contributors.empty()) {
308 for (
auto i = _contributors.begin(); i != _contributors.end(); ++i) {
311 string const &
id = (*i)->id();
312 vector<argument_list> args_seen;
315 if (find(args_seen.begin(),args_seen.end(),args)
316 == args_seen.end()) {
317 args_seen.push_back(args);
328 char const * action =
nullptr;
330 case pseudo_snapshot::define_in_progress:
333 case pseudo_snapshot::undef_in_progress:
334 action =
"Undefining";
336 case pseudo_snapshot::infinite:
341 for (
auto i = _subscribers.begin(); i != _subscribers.end(); ++i) {
342 if (!(*i)->dirty()) {
347 << action <<
" \"" << id()
348 <<
"\" retrospectively affects the meaning of \""
349 << (*i)->signature() <<
'\"' <<
emit();
358 size_t off = size_t(chew);
362 "Malformed macro parameter list for symbol \""
363 << id() <<
"\"" <<
emit();
370 <<
"Garbage in \"-D" << id()
371 << chew.
buf().substr(off) <<
'\"' <<
emit();
378 if (definition != *_defn ||
379 params.
size() != parameters().size()) {
383 <<
"\" contradicts prior \"-D" << id()
384 << parameters().str()
385 <<
'=' << *_defn <<
'\"' <<
emit();
389 <<
"Duplicated \"-D" << id() << parameters().str()
390 <<
'=' << definition <<
"\" ignored" <<
emit();
396 <<
'=' << definition <<
"\" contradicts prior \"-U"
397 << id() <<
'\"' <<
emit();
401 set_pseudo_snapshot(pseudo_snapshot::define_in_progress);
402 set_definition(definition);
403 set_parameters(params);
404 _provenance = provenance::global;
409 string const & definition)
412 bool is_global = _provenance == provenance::global;
415 if (definition != *_defn ||
416 params.
size() != parameters().size()) {
420 << id() << params.
str()
421 <<
'=' << definition <<
"\", after \""
422 << id() << parameters().str()
423 <<
'=' << *_defn <<
"\" at line "
434 else if (!is_global) {
445 else if (is_global) {
455 <<
"\"-D" << id() << params.
str()
457 <<
"\" has been assumed for the current file" <<
emit();
459 define(definition,params);
460 _provenance = provenance::transient;
466 set_parameters(params);
467 _provenance = provenance::unconfigured;
481 <<
"\" contradicts prior \"-D" << id() <<
'='
482 << *_defn <<
'\"' <<
emit();
488 << id() <<
"\" ignored" <<
emit();
492 set_pseudo_snapshot(pseudo_snapshot::undef_in_progress);
494 _provenance = provenance::global;
501 bool is_global = _provenance == provenance::global;
506 <<
"undefining " << id() <<
", after defining "
507 << id() << parameters().str()
508 <<
'=' << *_defn <<
" at line "
519 else if (is_global) {
530 "\" has been assumed for the current file" <<
emit();
533 _provenance = provenance::transient;
539 _provenance = provenance::unconfigured;
544 template<
class CharSeq>
550 locator sloc = lookup(
id);
static parsed_line & cur_line()
Get a reference to the current output line.
bool well_formed() const
Say whether the parameter_list_base is well-formed.
template struct traits::is_random_access_char_sequence<T> exports a static const boolean member value...
error_msg< 8 > error_invalid_args
Report that the commandline options are not a valid combination.
static void forget()
Forget about an apparent contradiction.
static void save(cause why, std::string const &symname)
Save diagnostic details of a potential contradiction.
static int _last_global_snapshot_
The last snapshot number consumed by the global configuration.
void set_directive_type(directive_type dtype)
Set the directive type of the line.
void undef()
Undefine thesymbol.
std::string str() const
Cast the parameter list to its canonical string representation.
A directive line of no more specific type that is to be kept.
void subscribe_to(locator other)
Record the symbol's definition as referring to another another symbol, and recursively as referring t...
static bool selected_symbols()
Is symbol reporting restricted to a selected set?
static bool selected(std::string const &id)
Say whether a symbol name matches a selection pattern for reporting.
error_msg< 17 > error_malformed_macro
Report a malformed macro parameter list.
size_t size() const
Get the number of parameters in the parameter_list_base
std::string find_any_in(chewer< CharSeq > &chew, size_t &off)
Search a terminal portion of a CharSeq for any identifier.
struct symbol::locator encapsulates a symbol table entry.
static locator find_any_in(chewer< CharSeq > &chew, size_t &off)
Search a terminal portion of a CharSeq for any known symbol name.
warning_msg< 5 > warning_differing_redef
Report that an in-source #define defines a symbol differently from a prior one.
static command_code get_command()
Get the operative coan command code.
static bool is_unconditional_line()
Is the current line outside any #if scope or in the scope of a satisfied #if?
void set_definition(std::string const &defn)
Set the definition of the symbol.
warning_msg< 6 > warning_undefing_defined
Report that an in-source #undef undefines a symbol previously defined by an in-source #define...
static bool wildcard_match(std::string const &wildcard, std::string const &name)
Say whether a symbol name matches a *-terminated wildcard prefix.
static symbol_table _sym_tab_
The symbol table.
Class argument_list encapsulates a list of macro arguments, i.e. the arguments to a macro reference...
line_type digest_transient_define(formal_parameter_list const ¶ms, std::string const &definition)
Analyse and handle an in-source define directive for this symbol.
The commandline, considered as a #define/#undef
size_t find_first_in(std::string const &id, chewer< CharSeq > &chew)
Find the first occurrence of an identifier within a terminal segment a CharSeq
static size_t count()
Get the number of symbols in the symbol table.
static void set_selection(char const *optarg)
void define(std::string const &defn, formal_parameter_list const ¶ms)
Define symbol.
An in-souce #define differently redefines a -D option.
An in-souce #undef contradicts a -D option.
warning_msg< 27 > warning_transient_symbol_added
unsigned num() const
Get the greatest source line number spanned by this line.
void make_dirty(pseudo_snapshot n=pseudo_snapshot::pristine)
Assign the symbol state a pseudo snapshot number, signifying that it is out of date, and recursively to all its subscribers.
static void report_global_config()
Report the global configuration, according to options.
sequence_type & buf()
Get a [const] reference to the associated sequence_type
line_type digest_transient_undef()
Analyse and handle an in-source undef directive for this symbol.
static bool list_once_per_file()
Do we report the listed items just once per input file?
static bool expand_references()
Do we report the expansions reported symbols?
A directive line of no more specific type than that is to be dropped.
void report() const
Report a reference to this symbol.
chew_mode::name const name
An exemplar chew_mode::name
The tag class is inserted in a diagnostic_base to tell it to emit itself.
static int _current_snapshot_
The current sequential snapshot number.
void report_premiere()
Report a symbol as resolved from the global configuration. The method invokes itself recursively on a...
static void insert(cause why, std::string const &symname)
Insert an error diagnostic into the output as a error directive or comment.
An in-souce #define contradicts a -U option.
static std::string const & last_conflicted_symbol_id()
Get the name of the latest #undef-ed symbol.
bool subscribes_to(locator other) const
Say whether the symbol's definition refers to another another symbol, directly or indirectly...
static void per_file_init()
Delete all transient symbols from the symbol table.
static std::set< std::string > _selected_symbols_set_
The set of symbols selected for reporting, if any.
static void flush()
Discharge any pending contradiction.
void subscribe()
Acquire all the symbol's contributors.
warning_msg< 1 > warning_duplicate_args
Report that same argument occurs for multiple --define or --undefine options.
info_msg< 3 > info_retrospective_redefinition
Report a #define or #undef that retrospectively affects the meaning of another symbol.
symbol_table::value_type table_entry
Type of entry in the symbol table.
`template struct chewer<CharSeq> is a cursor-like type that is associated with a character-sequence t...
template class canonical<What> encapsulates the canonical representation of values of type What...
void digest_global_define(chewer< std::string > &chew)
Analyse and handle a -D option for this symbol.
static bool no_transients()
static table_entry _null_
The table entry of the null symbol.
bool deselected() const
Say whether the symbol is deselected per the --select option.
line_type
Enumeration of types of input lines.
static void erase_symbol(std::string const &id)
Delete all cached references of a given symbol.
struct symbol encapsulates a preprocessor symbol's state
char * optarg
Argument to an option parsed by getopt_long()
void unsubscribe()
Forget all the symbol's contributors.
void digest_global_undef(chewer< std::string > &chew)
Analyse and handle a -U option for this symbol.
int snapshot_max() const
Get the maximum sequential snapshot number in the the recursive closure of this symbol its contributo...
error_msg< 12 > error_garbage_arg