Put lots of things in anonymous namespaces

This is an attempt to help prevent ODR violations by making stuff local
to a file, instead of emitting weak symbols.
This commit is contained in:
ridiculousfish 2021-09-27 17:34:49 -07:00
parent accba09709
commit 89c02cfe81
10 changed files with 100 additions and 91 deletions

View file

@ -16,6 +16,7 @@
static const int kAutoloadStalenessInterval = 15;
/// Represents a file that we might want to autoload.
namespace {
struct autoloadable_file_t {
/// The path to the file.
wcstring path;
@ -23,6 +24,7 @@ struct autoloadable_file_t {
/// The metadata for the file.
file_id_t file_id;
};
} // namespace
/// Class representing a cache of files that may be autoloaded.
/// This is responsible for performing cached accesses to a set of paths.

View file

@ -31,6 +31,7 @@ static const wcstring var_name_prefix = L"_flag_";
#define BUILTIN_ERR_INVALID_OPT_SPEC _(L"%ls: Invalid option spec '%ls' at char '%lc'\n")
namespace {
struct option_spec_t {
wchar_t short_flag;
wcstring long_flag;
@ -58,6 +59,7 @@ struct argparse_cmd_opts_t {
std::unordered_map<wcstring, wchar_t> long_to_short_flag;
std::vector<std::vector<wchar_t>> exclusive_flag_sets;
};
} // namespace
static const wchar_t *const short_options = L"+:hn:six:N:X:";
static const struct woption long_options[] = {

View file

@ -26,6 +26,7 @@
#include "wgetopt.h"
#include "wutil.h" // IWYU pragma: keep
namespace {
struct function_cmd_opts_t {
bool print_help = false;
bool shadow_scope = true;
@ -35,6 +36,7 @@ struct function_cmd_opts_t {
wcstring_list_t inherit_vars;
wcstring_list_t wrap_targets;
};
} // namespace
// This command is atypical in using the "-" (RETURN_IN_ORDER) option for flag parsing.
// This is needed due to the semantics of the -a/--argument-names flag.

View file

@ -71,6 +71,7 @@
class parser_t;
namespace {
struct builtin_printf_state_t {
// Out and err streams. Note this is a captured reference!
io_streams_t &streams;
@ -100,9 +101,9 @@ struct builtin_printf_state_t {
void print_esc_char(wchar_t c);
void append_output(wchar_t c);
void append_output(const wchar_t *c);
void append_format_output(const wchar_t *fmt, ...);
};
} // namespace
static bool is_octal_digit(wchar_t c) { return iswdigit(c) && c < L'8'; }
@ -237,13 +238,6 @@ void builtin_printf_state_t::append_output(wchar_t c) {
streams.out.push_back(c);
}
void builtin_printf_state_t::append_output(const wchar_t *c) {
// Don't output if we're done.
if (early_exit) return;
streams.out.append(c);
}
void builtin_printf_state_t::append_format_output(const wchar_t *fmt, ...) {
// Don't output if we're done.
if (early_exit) return;

View file

@ -35,6 +35,7 @@
#include "wgetopt.h"
#include "wutil.h" // IWYU pragma: keep
namespace {
struct read_cmd_opts_t {
bool print_help = false;
int place = ENV_USER;
@ -56,6 +57,7 @@ struct read_cmd_opts_t {
int nchars = 0;
bool one_line = false;
};
} // namespace
static const wchar_t *const short_options = L":ac:d:fghiLln:p:sStuxzP:UR:L";
static const struct woption long_options[] = {{L"array", no_argument, nullptr, 'a'},

View file

@ -295,6 +295,7 @@ static int env_set_reporting_errors(const wchar_t *cmd, const wcstring &key, int
return retval;
}
namespace {
/// A helper type returned by split_var_and_indexes.
struct split_var_t {
wcstring varname; // name of the variable
@ -304,6 +305,7 @@ struct split_var_t {
/// \return the number of elements in our variable, or 0 if missing.
long varsize() const { return var ? static_cast<long>(var->as_list().size()) : 0L; }
};
} // namespace
/// Extract indexes from an argument of the form `var_name[index1 index2...]`.
/// The argument \p arg is split into a variable name and list of indexes, which is returned by

View file

@ -95,6 +95,7 @@ static maybe_t<job_control_t> job_control_str_to_mode(const wchar_t *mode, const
return none();
}
namespace {
struct status_cmd_opts_t {
int level{1};
maybe_t<job_control_t> new_job_control_mode{};
@ -102,6 +103,7 @@ struct status_cmd_opts_t {
status_cmd_t status_cmd{STATUS_UNDEF};
bool print_help{false};
};
} // namespace
/// Note: Do not add new flags that represent subcommands. We're encouraging people to switch to
/// the non-flag subcommand form. While these flags are deprecated they must be supported at

View file

@ -42,6 +42,8 @@
// This should be about the size of a line.
#define STRING_CHUNK_SIZE 128
namespace {
static void string_error(io_streams_t &streams, const wchar_t *fmt, ...) {
streams.err.append(L"string ");
va_list va;
@ -66,7 +68,6 @@ static const wchar_t *string_get_arg_argv(int *argidx, const wchar_t *const *arg
}
// A helper type for extracting arguments from either argv or stdin.
namespace {
class arg_iterator_t {
// The list of arguments passed to the string builtin.
const wchar_t *const *argv_;
@ -132,7 +133,6 @@ class arg_iterator_t {
}
}
};
} // namespace
// This is used by the string subcommands to communicate with the option parser which flags are
// valid and get the result of parsing the command for flags.
@ -808,6 +808,7 @@ static int string_length(parser_t &parser, io_streams_t &streams, int argc, cons
return nnonempty > 0 ? STATUS_CMD_OK : STATUS_CMD_ERROR;
}
namespace {
class string_matcher_t {
protected:
const options_t opts;
@ -1210,6 +1211,7 @@ class pcre2_matcher_t final : public string_matcher_t {
bool is_valid() const override { return regex.is_valid(); }
};
} // namespace
static int string_match(parser_t &parser, io_streams_t &streams, int argc, const wchar_t **argv) {
const wchar_t *cmd = argv[0];
@ -1881,6 +1883,7 @@ static constexpr const struct string_subcommand {
{L"upper", &string_upper},
};
ASSERT_SORTED_BY_NAME(string_subcommands);
} // namespace
/// The string builtin, for manipulating strings.
maybe_t<int> builtin_string(parser_t &parser, io_streams_t &streams, const wchar_t **argv) {

View file

@ -242,7 +242,7 @@ bool is_windows_subsystem_for_linux() {
/// alignment must be a power of 2 and in range [1, 64].
/// This is intended to return the end point of the "unaligned prefix" of a vectorized loop.
template <size_t Align>
inline const char *align_start(const char *start, size_t len) {
static inline const char *align_start(const char *start, size_t len) {
static_assert(Align >= 1 && Align <= 64, "Alignment must be in range [1, 64]");
static_assert((Align & (Align - 1)) == 0, "Alignment must be power of 2");
uintptr_t startu = reinterpret_cast<uintptr_t>(start);
@ -262,7 +262,7 @@ inline const char *align_start(const char *start, size_t len) {
/// If there is no such pointer, return \p start.
/// This is intended to be the start point of the "unaligned suffix" of a vectorized loop.
template <size_t Align>
inline const char *align_end(const char *start, size_t len) {
static inline const char *align_end(const char *start, size_t len) {
static_assert(Align >= 1 && Align <= 64, "Alignment must be in range [1, 64]");
static_assert((Align & (Align - 1)) == 0, "Alignment must be power of 2");
// How much do we have to subtract to align it? Its value, mod Align.
@ -617,7 +617,7 @@ static unsigned long long absolute_value(long long x) {
}
template <typename CharT>
void format_safe_impl(CharT *buff, size_t size, unsigned long long val) {
static void format_safe_impl(CharT *buff, size_t size, unsigned long long val) {
size_t idx = 0;
if (val == 0) {
buff[idx++] = '0';

View file

@ -88,7 +88,7 @@ static const wcstring &C_(const wcstring &s) { return s; }
/// If option is non-empty, it specifies a switch for the command. If \c comp is also not empty, it
/// contains a list of non-switch arguments that may only follow directly after the specified
/// switch.
using complete_entry_opt_t = struct complete_entry_opt {
struct complete_entry_opt_t {
// Text of the option (like 'foo').
wcstring option;
// Type of the option: args-oly, short, single_long, or double_long.
@ -139,16 +139,32 @@ class completion_entry_t {
const unsigned int order;
/// Getters for option list.
const option_list_t &get_options() const;
const option_list_t &get_options() const { return options; }
/// Adds or removes an option.
void add_option(const complete_entry_opt_t &opt);
void add_option(const complete_entry_opt_t &opt) { options.push_front(opt); }
bool remove_option(const wcstring &option, complete_option_type_t type);
completion_entry_t(wcstring c, bool type)
: cmd(std::move(c)), cmd_is_path(type), order(++k_complete_order) {}
};
/// Remove all completion options in the specified entry that match the specified short / long
/// option strings. Returns true if it is now empty and should be deleted, false if it's not empty.
/// Must be called while locked.
bool completion_entry_t::remove_option(const wcstring &option, complete_option_type_t type) {
auto iter = this->options.begin();
while (iter != this->options.end()) {
if (iter->option == option && iter->type == type) {
iter = this->options.erase(iter);
} else {
// Just go to the next one.
++iter;
}
}
return this->options.empty();
}
/// Set of all completion entries.
namespace std {
template <>
@ -164,6 +180,7 @@ struct equal_to<completion_entry_t> {
return c1.cmd == c2.cmd;
}
};
} // namespace std
using completion_entry_set_t = std::unordered_set<completion_entry_t>;
static owning_lock<completion_entry_set_t> s_completion_set;
@ -178,10 +195,6 @@ static bool compare_completions_by_order(const completion_entry_t &p1,
return p1.order < p2.order;
}
void completion_entry_t::add_option(const complete_entry_opt_t &opt) { options.push_front(opt); }
const option_list_t &completion_entry_t::get_options() const { return options; }
description_func_t const_desc(const wcstring &s) {
return [=](const wcstring &ignored) {
UNUSED(ignored);
@ -343,6 +356,7 @@ void completions_sort_and_prioritize(completion_list_t *comps, completion_reques
}
}
namespace {
/// Class representing an attempt to compute completions.
class completer_t {
/// The operation context for this completion.
@ -461,12 +475,6 @@ class completer_t {
// Autoloader for completions.
static owning_lock<autoload_t> completion_autoloader{autoload_t(L"fish_complete_path")};
/// Create a new completion entry.
void append_completion(completion_list_t *completions, wcstring comp, wcstring desc,
complete_flags_t flags, string_fuzzy_match_t match) {
completions->emplace_back(std::move(comp), std::move(desc), match, flags);
}
/// Test if the specified script returns zero. The result is cached, so that if multiple completions
/// use the same condition, it needs only be evaluated once. condition_cache_clear must be called
/// after a completion run to make sure that there are no stale completions.
@ -504,71 +512,6 @@ static completion_entry_t &complete_get_exact_entry(completion_entry_set_t &comp
return const_cast<completion_entry_t &>(*ins.first);
}
void complete_add(const wchar_t *cmd, bool cmd_is_path, const wcstring &option,
complete_option_type_t option_type, completion_mode_t result_mode,
const wchar_t *condition, const wchar_t *comp, const wchar_t *desc,
complete_flags_t flags) {
assert(cmd && "Null command");
// option should be empty iff the option type is arguments only.
assert(option.empty() == (option_type == option_type_args_only));
// Lock the lock that allows us to edit the completion entry list.
auto completion_set = s_completion_set.acquire();
completion_entry_t &c = complete_get_exact_entry(*completion_set, cmd, cmd_is_path);
// Create our new option.
complete_entry_opt_t opt;
opt.option = option;
opt.type = option_type;
opt.result_mode = result_mode;
if (comp) opt.comp = comp;
if (condition) opt.condition = condition;
if (desc) opt.desc = desc;
opt.flags = flags;
c.add_option(opt);
}
/// Remove all completion options in the specified entry that match the specified short / long
/// option strings. Returns true if it is now empty and should be deleted, false if it's not empty.
/// Must be called while locked.
bool completion_entry_t::remove_option(const wcstring &option, complete_option_type_t type) {
auto iter = this->options.begin();
while (iter != this->options.end()) {
if (iter->option == option && iter->type == type) {
iter = this->options.erase(iter);
} else {
// Just go to the next one.
++iter;
}
}
return this->options.empty();
}
void complete_remove(const wcstring &cmd, bool cmd_is_path, const wcstring &option,
complete_option_type_t type) {
auto completion_set = s_completion_set.acquire();
completion_entry_t tmp_entry(cmd, cmd_is_path);
auto iter = completion_set->find(tmp_entry);
if (iter != completion_set->end()) {
// const_cast: See SET_ELEMENTS_ARE_IMMUTABLE.
auto &entry = const_cast<completion_entry_t &>(*iter);
bool delete_it = entry.remove_option(option, type);
if (delete_it) {
completion_set->erase(iter);
}
}
}
void complete_remove_all(const wcstring &cmd, bool cmd_is_path) {
auto completion_set = s_completion_set.acquire();
completion_entry_t tmp_entry(cmd, cmd_is_path);
completion_set->erase(tmp_entry);
}
/// Find the full path and commandname from a command string 'str'.
static void parse_cmd_string(const wcstring &str, wcstring *path, wcstring *cmd,
const environment_t &vars) {
@ -1760,6 +1703,63 @@ void completer_t::perform_for_commandline(wcstring cmdline) {
mark_completions_duplicating_arguments(cmdline, current_token, tokens);
}
} // namespace
/// Create a new completion entry.
void append_completion(completion_list_t *completions, wcstring comp, wcstring desc,
complete_flags_t flags, string_fuzzy_match_t match) {
completions->emplace_back(std::move(comp), std::move(desc), match, flags);
}
void complete_add(const wchar_t *cmd, bool cmd_is_path, const wcstring &option,
complete_option_type_t option_type, completion_mode_t result_mode,
const wchar_t *condition, const wchar_t *comp, const wchar_t *desc,
complete_flags_t flags) {
assert(cmd && "Null command");
// option should be empty iff the option type is arguments only.
assert(option.empty() == (option_type == option_type_args_only));
// Lock the lock that allows us to edit the completion entry list.
auto completion_set = s_completion_set.acquire();
completion_entry_t &c = complete_get_exact_entry(*completion_set, cmd, cmd_is_path);
// Create our new option.
complete_entry_opt_t opt;
opt.option = option;
opt.type = option_type;
opt.result_mode = result_mode;
if (comp) opt.comp = comp;
if (condition) opt.condition = condition;
if (desc) opt.desc = desc;
opt.flags = flags;
c.add_option(opt);
}
void complete_remove(const wcstring &cmd, bool cmd_is_path, const wcstring &option,
complete_option_type_t type) {
auto completion_set = s_completion_set.acquire();
completion_entry_t tmp_entry(cmd, cmd_is_path);
auto iter = completion_set->find(tmp_entry);
if (iter != completion_set->end()) {
// const_cast: See SET_ELEMENTS_ARE_IMMUTABLE.
auto &entry = const_cast<completion_entry_t &>(*iter);
bool delete_it = entry.remove_option(option, type);
if (delete_it) {
completion_set->erase(iter);
}
}
}
void complete_remove_all(const wcstring &cmd, bool cmd_is_path) {
auto completion_set = s_completion_set.acquire();
completion_entry_t tmp_entry(cmd, cmd_is_path);
completion_set->erase(tmp_entry);
}
completion_list_t complete(const wcstring &cmd_with_subcmds, completion_request_flags_t flags,
const operation_context_t &ctx) {
// Determine the innermost subcommand.