107 {
"complement",
no_argument,
nullptr, OPT_COMPLEMENT },
114 {
"keepgoing",
no_argument,
nullptr, OPT_KEEPGOING },
118 {
"includes",
no_argument,
nullptr, OPT_INCLUDES },
122 {
"once-per-file",
no_argument,
nullptr, OPT_ONCE_PER_FILE },
126 {
"inactive",
no_argument,
nullptr, OPT_INACTIVE },
128 {
"implicit",
no_argument,
nullptr, OPT_IMPLICIT },
130 {
"no-transients",
no_argument,
nullptr, OPT_NO_TRANSIENTS },
161 OPT_IFS, OPT_DEFS, OPT_UNDEFS, OPT_INCLUDES, OPT_LOCATE,
162 OPT_ONCE, OPT_SYSTEM, OPT_LOCAL, OPT_ACTIVE, OPT_INACTIVE,
163 OPT_EXPAND, OPT_PREFIX, OPT_EXPLAIN, OPT_SELECT, OPT_LNS,
168 OPT_REPLACE, OPT_CONFLICT, OPT_DISCARD, OPT_LINE, OPT_SYSTEM,
169 OPT_LOCAL, OPT_BACKUP, OPT_COMPLEMENT, OPT_DIR, OPT_PREFIX, 0
173 OPT_REPLACE, OPT_CONFLICT, OPT_DISCARD, OPT_LINE, OPT_BACKUP,
174 OPT_IFS, OPT_DEFS, OPT_UNDEFS, OPT_INCLUDES, OPT_COMPLEMENT,
175 OPT_EXPAND, OPT_DIR, OPT_PREFIX, OPT_EXPLAIN, OPT_SELECT,
180 OPT_REPLACE, OPT_CONFLICT, OPT_DISCARD, OPT_LINE, OPT_BACKUP,
181 OPT_IFS, OPT_DEFS, OPT_UNDEFS, OPT_INCLUDES, OPT_COMPLEMENT,
182 OPT_EXPAND, OPT_DIR, OPT_PREFIX, OPT_EXPLAIN, OPT_SELECT,
187 OPT_REPLACE, OPT_CONFLICT, OPT_DISCARD, OPT_LINE, OPT_BACKUP,
188 OPT_SYSTEM, OPT_LOCAL, OPT_IFS, OPT_DEFS, OPT_UNDEFS, OPT_INCLUDES,
189 OPT_COMPLEMENT, OPT_EXPAND, OPT_DIR, OPT_PREFIX, OPT_EXPLAIN,
190 OPT_SELECT, OPT_LNS, 0
194 OPT_REPLACE, OPT_CONFLICT, OPT_DISCARD, OPT_LINE, OPT_BACKUP,
195 OPT_SYSTEM, OPT_LOCAL, OPT_IFS, OPT_DEFS, OPT_UNDEFS, OPT_INCLUDES,
196 OPT_COMPLEMENT, OPT_EXPAND, OPT_DIR, OPT_PREFIX, OPT_EXPLAIN,
197 OPT_SELECT, OPT_LNS, 0
201 OPT_REPLACE, OPT_CONFLICT, OPT_DISCARD, OPT_LINE, OPT_BACKUP,
202 OPT_SYSTEM, OPT_LOCAL, OPT_IFS, OPT_DEFS, OPT_UNDEFS, OPT_INCLUDES,
203 OPT_COMPLEMENT, OPT_EXPAND, OPT_DIR, OPT_PREFIX, OPT_EXPLAIN,
204 OPT_SELECT, OPT_LNS, 0
208 OPT_REPLACE, OPT_CONFLICT, OPT_DISCARD, OPT_LINE, OPT_BACKUP,
209 OPT_SYSTEM, OPT_LOCAL, OPT_IFS, OPT_DEFS, OPT_UNDEFS, OPT_INCLUDES,
210 OPT_COMPLEMENT, OPT_EXPAND, OPT_DIR, OPT_PREFIX, OPT_EXPLAIN,
211 OPT_SELECT, OPT_LNS, 0
215 OPT_IFS, OPT_DEFS, OPT_UNDEFS, OPT_INCLUDES, OPT_LOCATE,
216 OPT_ONCE, OPT_SYSTEM, OPT_LOCAL, OPT_ACTIVE, OPT_INACTIVE,
217 OPT_BACKUP, OPT_EXPAND, OPT_EXPLAIN, OPT_SELECT, OPT_LNS,
254 struct option * longopt = long_options;
255 char *opts_str = opts;
256 for ( ; longopt->
name; ++longopt, ++opts_str) {
257 *opts_str = longopt->
val;
278 if (_diagnostic_filter_ < 0 && arg !=
"verbose") {
280 warn <<
"Can't mix --verbose with --gag.'--gag " << arg <<
" ignored";
281 cerr << warn.
text() <<
'\n';
284 if (arg ==
"progress") {
286 }
else if (arg ==
"info") {
288 }
else if (arg ==
"warning") {
290 }
else if (arg ==
"error") {
292 }
else if (arg ==
"abort") {
294 }
else if (arg ==
"summary") {
296 }
else if (arg ==
"verbose") {
297 if (_diagnostic_filter_ > 0) {
299 "Can't mix --verbose with --gag. '--verbose' ignored" <<
emit();
301 }
else if (_diagnostic_filter_ < 0) {
305 _diagnostic_filter_ = -1;
309 << arg <<
'\"' <<
emit();
311 if (
int(mask) & _diagnostic_filter_) {
314 _diagnostic_filter_ |= int(mask);
316 config_diagnostics(
"progress");
318 config_diagnostics(
"info");
320 config_diagnostics(
"warning");
322 config_diagnostics(
"error");
328 if (!_diagnostic_filter_) {
331 config_diagnostics(
"info");
332 config_diagnostics(
"summary");
333 }
else if (_diagnostic_filter_ == -1) {
336 _diagnostic_filter_ = 0;
342 char const *cmdname = cmd->
name;
346 <<
" is an invalid or ambiguous option for command \""
347 << cmdname <<
'\"' <<
emit();
355 "No such file or directory as \"" << path <<
'\"' <<
emit();
361 "--recurse not specified. Ignoring directory \"" << path <<
368 if (prefix == spin_dir_path || prefix == new_path) {
370 "cannot include or be included by or identical with "
371 "any input directory" <<
emit();
378 "\" ignored" <<
emit();
385 int opt, save_ind, long_index;
390 (opt =
getopt_long(argc,argv,opts,long_options,&long_index))
393 opt,cmd_exclusion_lists,
true)) {
394 error_invalid_opt(_command_,opt);
400 _parsing_file_ =
true;
402 _parsing_file_ =
false;
407 string option_arg(
optarg);
408 if (option_arg.length() > 1) {
409 if (option_arg ==
"delete") {
411 }
else if (option_arg ==
"comment") {
413 }
else if (option_arg ==
"error") {
416 error_usage() <<
"Invalid argument for --conflict: \""
417 << option_arg <<
'\"' <<
emit();
420 switch(option_arg[0]) {
432 << option_arg[0] <<
'\"' <<
emit();
439 string option_arg(
optarg);
440 if (option_arg.length() == 1) {
441 switch(option_arg[0]) {
443 option_arg =
"progress";
449 option_arg =
"warning";
452 option_arg =
"error";
455 option_arg =
"abend";
458 option_arg =
"summary";
464 config_diagnostics(option_arg);
468 config_diagnostics(
"verbose");
497 string option_arg(
optarg);
498 if (option_arg.length() > 1) {
499 if (option_arg ==
"drop") {
501 }
else if (option_arg ==
"blank") {
503 }
else if (option_arg ==
"comment") {
506 error_usage() <<
"Invalid argument for --discard: \""
510 switch(option_arg[0]) {
528 _line_directives_ =
true;
531 _list_locate_ =
true;
534 _list_only_active_ =
true;
537 _list_only_inactive_ =
true;
540 _expand_references_ =
true;
543 _list_only_once_ =
true;
545 case OPT_ONCE_PER_FILE:
546 _list_once_per_file_ =
true;
549 _list_symbols_in_ifs_ =
true;
552 _list_symbols_in_defs_ =
true;
555 _list_symbols_in_undefs_ =
true;
558 _list_symbols_in_includes_ =
true;
561 _list_symbols_in_lines_ =
true;
564 _list_system_includes_ =
true;
567 _list_local_includes_ =
true;
589 case OPT_NO_TRANSIENTS:
591 _no_transients_ =
true;
593 <<
"prohibits coan from taking account of the effects of "
594 <<
"in-source #define and #undef directives. "
595 <<
"Use at your own risk." <<
emit();
608 _expand_references_ = _explain_references_ =
true;
614 _selected_symbols_ =
true;
616 case OPT_EXPAND_MAX: {
620 _max_expansion_ = strtoul(
optarg,&endp,10);
621 if (*endp && (*endp ==
'K' || *endp ==
'k')) {
622 _max_expansion_ *= 1024;
626 error_usage() <<
"Invalid argument for --max-expansion: \""
633 "Invalid or ambiguous option: \"" << argv[
optind - 1] <<
'\"'
637 if (!_parsing_file_) {
639 finalise_diagnostics();
640 if (!progress_gagged()) {
643 for (
int i = 0; i < options; ++i) {
644 msg << argv[i] <<
' ';
653 "You have not --define-ed or --undef-ed any symbols. "
654 "Only in-source #define/#undef directives will have "
655 "any effects" <<
emit();
664 for ( ; argc; --argc,++argv,++_cmd_line_files_) {
671 std::vector<char *> arg_addrs;
672 if (_argfile_argv_.size()) {
675 ifstream in(argsfile.c_str());
678 argsfile <<
" for reading" <<
emit();
681 _argfile_argv_.push_back(_prog_name_);
682 copy(istream_iterator<string>(in),
683 istream_iterator<string>(),
684 back_inserter<vector<string> >(_argfile_argv_));
686 vector<string>::iterator iter = _argfile_argv_.begin();
687 vector<string>::iterator end = _argfile_argv_.end();
688 for( ; iter != end; ++iter ) {
689 arg_addrs.push_back(const_cast<char *>(iter->c_str()));
691 parse_command_args(
int(arg_addrs.size()),&arg_addrs[0]);
696 _exec_path_ = string(*argv);
697 size_t last_slash = _exec_path_.find_last_of(
PATH_DELIM);
698 if (last_slash == string::npos) {
699 _prog_name_ = _exec_path_;
701 _prog_name_ = _exec_path_.substr(last_slash + 1);
721 parse_command_args(argc,argv);
723 }
else if (argc < 2) {
727 <<
"\" is not a coan command" <<
emit();
733 int cmd_code = _command_->cmd_code;
734 bool input_is_stdin =
false;
736 if (_list_only_active_ && _list_only_inactive_) {
739 if (_list_only_once_ && _list_once_per_file_) {
741 <<
"--once-only is inconsistent with --once-per-file" <<
emit();
743 if (_line_directives_ && _discard_policy_ !=
DISCARD_DROP) {
744 error_usage() <<
"--line is inconsistent with --discard blank|comment"
747 if (_cmd_line_files_ == 0) {
751 input_is_stdin =
true;
756 (void)add_files(infile);
762 "Nothing to do. No input files selected." <<
emit();
764 if (cmd_code ==
CMD_SOURCE && !input_is_stdin &&
767 "The \"source\" command needs --replace to process multiple files"
771 if (!_list_symbols_in_ifs_ &&
772 !_list_symbols_in_defs_ &&
773 !_list_symbols_in_undefs_ &&
774 !_list_symbols_in_includes_) {
776 _list_symbols_in_ifs_ = _list_symbols_in_defs_ =
777 _list_symbols_in_undefs_ = _list_symbols_in_includes_ =
true;
781 if (!_list_system_includes_ && !_list_local_includes_) {
783 _list_system_includes_ = _list_local_includes_ =
true;
progress_msg< 4 > progress_file_tracker
Report total input files found.
The option cannot have an argument.
static bool implicit()
Do we implicitly --undef all unconfigured symbols?
static bool _list_only_once_
Do we report only the first occurrence of listed items?
error_msg< 7 > error_one_file_only
template struct warning_msg<Id> generically encapsulates a warning diagnostic.
static int const includes_cmd_exclusions[]
Excluded options for the includes command.
A fatal error disgnostic.
static int const errors_cmd_exclusions[]
Excluded options for the errors command.
abend_msg< 14 > abend_invalid_spin_dir
Report that a spin directory includes, is included by or is same as an input directory.
An informational diagnostic.
int val
Value to be returned or stored by getopt_long().
static std::string _backup_suffix_
Suffix for backup files.
static void add(std::string const &path)
Add files to the dataset.
The symbol is globally configured by a commandline option.
static bool _list_only_inactive_
Do list items only from dropped lines?
info_msg< 1 > info_duplicate_mask
Report a duplicate diagnostic selection option.
static bool _list_local_includes_
Do we list local #include directives?
discard_policy
Symbolic constants denoting policies for discarding lines.
Manages coan's commandline arguments.
void version()
Write version information about the program on cout.
static bool _list_only_active_
Do we list items only from kept lines?
struct symbol::locator encapsulates a symbol table entry.
static void parse(int argc, char *argv[])
Parse the commandline.
static bool _selected_symbols_
Is symbol reporting restricted to a selected set?
static void error_invalid_opt(struct cmd_option const *cmd, int bad_opt)
Raise a usage error when an option is invalid for the active command.
static int const lines_cmd_exclusions[]
Excluded options for the lines command.
error_msg< 9 > error_usage
Report that the commandline is syntactically invalid.
unsigned obj_type_t
Abstract type of filesystem object types.
static int const source_cmd_exclusions[]
Excluded options for the source command.
warning_msg< 13 > warning_verbose_only
Report the --verbose option is mixed with the --gag option.
bool is_file(obj_type_t type)
Say whether an object type is a file.
bool is_dir(obj_type_t type)
Say whether an object type is a directory.
static int _cmd_line_files_
The number of input files/dirs specified on the commandline.
static unsigned _max_expansion_
Limit size for reported macro expansions.
static command_code get_command()
Get the operative coan command code.
const char * get_long_opt_name(struct option const *longopts, int opt)
Look up the long name of the an option in an array of struct option.
static bool _recurse_
Recurse into directories?
static std::string _memfile_
Read whole ARGFILE into this storage.
static int const spin_cmd_exclusions[]
Excluded options for the spin command.
Comment out a contradicted directive.
static int const pragmas_cmd_exclusions[]
Excluded options for the pragmas command.
static int const symbols_cmd_exclusions[]
Excluded options for the symbols command.
static bool _got_opts_
Have we got all commandline options?
int optind
Index of option parsed by getopt_long()
int getopt_long(int argc, char *argv[], const char *optstr, const struct option *longopts, int *longind)
Parse commandline options.
static void parse_file(std::string const &argsfile)
Parse commandline options from a file.
static size_t count()
Get the number of symbols in the symbol table.
static void set_selection(char const *optarg)
abend_msg< 7 > abend_no_file
Report can't identify file or directory.
static void parse_command_args(int argc, char *argv[])
Parse the options to the active coan command.
const char * name
The name of the option.
static void finish()
Analyse the class global state after parsing the commandline.
static bool _implicit_
Do we implicitly --undef all unconfigured symbols?
Info structure for an option for getopt_long().
static std::string const & spin_dir()
Get the name of operative spin directory.
bool opts_are_compatible(int opt_excluder, int opt_excluded, struct exclusion_list const *exclusions, bool indexed)
Say whether options are compatible with respect to specified incompatibilities.
severity
Enumerated constants representing the severities of diagnostics.
static std::string read_filename()
Read the name of a source file from stdin.
static void finalise_diagnostics()
Configure the final state of diagnostic output filtering.
static bool _expand_references_
Do we report the expansions of symbol references?
static void set_spin_prefix(char const *optarg)
Set a path prefix (of input files) that will be assumed to match the name of the spin directory...
static bool _no_transients_
template struct progress_msg<Id>` generically encapsulates a progress diagnostic. ...
static char opts[]
Array in which we will assemble the shortopts arguments for getopts_long()
static bool _eval_wip_
Do we evaluate constants in truth-functional contexts or treat them as unknowns?
const char * name
The name of the option.
Delete a contradicted directive.
static void set_filter(std::string extensions)
Specify the filtering of files in the dataset.
int cmd_code
Value to be returned if the command is matched.
static void top()
Reinitialize the class static state.
The option must have an argument.
static bool _keepgoing_
Continue to process input files after errors.
The tag class is inserted in a diagnostic_base to tell it to emit itself.
abend_msg< 2 > abend_cant_open_input
Report cannot open an input file.
static unsigned files()
Get the number of files in the dataset.
contradiction_policy
Symbolic constants denoting policies for handling contradictions.
static void config_diagnostics(std::string const &arg)
Configure diagnostic output.
warning_msg< 15 > warning_dir_ignored
Report directory name ignored on input when --recurse not not specified.
static path common_prefix(path const &lhs, path const &rhs)
Get the common initial prefix of two paths.
static bool _list_system_includes_
Do we list system #include directives?
static bool progress_gagged()
Say whether progress messages are suppressed.
static bool _list_locate_
Do we report file and line numbers for listed items?
static int const defs_cmd_exclusions[]
Excluded options for the defs command.
static bool _explain_references_
Do we report the derivation of symbol resolutions?
static std::vector< std::string > _argfile_argv_
Array of options read from --file ARGFILE
static discard_policy _discard_policy_
Policy for discarding lines.
`template struct chewer<CharSeq> is a cursor-like type that is associated with a character-sequence t...
error_msg< 6 > error_nothing_to_do
Report that the commandline does not specify anything to do.
std::string text() const
Get the text of the diagnostic.
Info structure for a command option for get_command()
void digest_global_define(chewer< std::string > &chew)
Analyse and handle a -D option for this symbol.
warning_msg< 30 > warning_no_transients_used
Report that the unsafe --no-transients option is used.
static bool spin()
Say whether there is any spin directory.
static bool diagnostic_gagged(unsigned reason)
Say whether a diagnostic reason code is gagged.
static std::string _exec_path_
argv[0]
static bool _list_symbols_in_lines_
Do we list symbols in #line directives?
static void set_contradiction_policy(contradiction_policy p)
Set the operative contradiction policy.
bool is_slink(obj_type_t type)
Say whether an object type is a symbolic link.
Encapsulates a filesystem path.
static bool _plaintext_
Are we to omit parsing for comments?
static bool _complement_
Are to output lines instead of dropping tem and vice versa?
Replace a contradicted directive with an #error
void help()
Write brief command usage information to cout.
command_code
Sequential symbolic constants for coan commands.
static void set_spin_dir(char const *optarg)
Set the directory in which to output a spin.
static void parse_executable(char **argv)
Parse the full and short names of the executable.
cmd_option const * get_command_option(int argc, char *argv[], cmd_option const *commands)
Look for a command option at the start of commandline arguments.
static bool _list_symbols_in_ifs_
Do we list symbols in `#if/else/endif directives?
error_msg< 11 > error_multiple_argfiles
Report that the --file option occurs more than once.
static bool _list_symbols_in_undefs_
Do we list symbols in #undef directives?
obj_type_t obj_type(std::string const &name)
Get the type of the object putatively designated by a filename.
static void add_files(std::string const &path)
Add files to the input dataset.
int has_arg
Can the option take an argument? One of:
static int _diagnostic_filter_
Bitmask of diagnostic filters.
static void make_opts_list()
Assemble the shortopts arguments for getopts_long().
static bool _list_symbols_in_defs_
Do we list symbols in #define directives?
static struct cmd_option * _command_
Pointer to the details of the operative coan command.
Structure representing a set of options that are excluded by another option.
static bool _parsing_file_
Are we parsing an argsfile ?
char * optarg
Argument to an option parsed by getopt_long()
warning_msg< 29 > warning_broken_symlink
Report that input file is a broken symbolic link.
warning_msg< 28 > warning_no_syms
Report that the commandline does not specify any --define or --undef
static bool _list_once_per_file_
Do we report only the first occurrence per file of listed items?
static bool _line_directives_
Do we output #line directives?
static std::string _prog_name_
Filename element of exec_path
static int const directives_cmd_exclusions[]
Excluded options for the directives command.
void digest_global_undef(chewer< std::string > &chew)
Analyse and handle a -U option for this symbol.
progress_msg< 2 > progress_building_tree
Peport building the input tree.
The option may or may not have an argument.
static bool _replace_
Do we replace input files with output files?
static bool _list_symbols_in_includes_
Do we list symbols in #include directives?