builtin_alias / builtin_unalias.

This commit is contained in:
Kelvin Sherlock 2016-06-22 13:47:48 -04:00
parent 6bfad57a35
commit 45eade7af5
5 changed files with 138 additions and 0 deletions

View File

@ -318,7 +318,60 @@ int builtin_unexport(Environment &env, const std::vector<std::string> &tokens, c
return export_common(env, false, tokens, fds);
}
int builtin_alias(Environment &env, const std::vector<std::string> &tokens, const fdmask &fds) {
// alias -> lists all aliases
// alias name -> list single alias
// alias name parms... -> add a new alias.
if (tokens.size() == 1) {
for (const auto &p : env.aliases()) {
fprintf(stdout, "Alias %s %s\n", quote(p.first).c_str(), quote(p.second).c_str());
}
return 0;
}
std::string name = tokens[1];
if (tokens.size() == 2) {
const auto as = env.find_alias(name);
if (as.empty()) {
fprintf(stderr, "### Alias - No alias exists for %s\n", quote(name).c_str());
return 1;
}
fprintf(stdout, "Alias %s %s\n", quote(name).c_str(), quote(as).c_str());
return 0;
}
std::string as;
for (const auto &s : make_offset_range(tokens, 2)) {
as += s;
as.push_back(' ');
}
as.pop_back();
// add/remove it to the alias table...
if (as.empty()) {
env.remove_alias(name);
}
else {
env.add_alias(std::move(name), std::move(as));
}
return 0;
}
int builtin_unalias(Environment &env, const std::vector<std::string> &tokens, const fdmask &) {
// unalias -> remove all aliases.
// unalias name -> remove single alias.
if (tokens.size() == 1) {
env.remove_alias();
return 0;
}
for (const auto &x : make_offset_range(tokens, 1)) {
env.remove_alias(x);
}
return 0;
}
int builtin_echo(Environment &env, const std::vector<std::string> &tokens, const fdmask &fds) {

View File

@ -21,6 +21,8 @@ int builtin_unexport(Environment &e, const std::vector<std::string> &, const fdm
int builtin_unset(Environment &e, const std::vector<std::string> &, const fdmask &);
int builtin_version(Environment &e, const std::vector<std::string> &, const fdmask &);
int builtin_which(Environment &e, const std::vector<std::string> &, const fdmask &);
int builtin_alias(Environment &e, const std::vector<std::string> &, const fdmask &);
int builtin_unalias(Environment &e, const std::vector<std::string> &, const fdmask &);
int builtin_evaluate(Environment &e, std::vector<token> &&, const fdmask &);

View File

@ -168,6 +168,7 @@ namespace {
std::unordered_map<std::string, int (*)(Environment &, const std::vector<std::string> &, const fdmask &)> builtins = {
{"aboutbox", builtin_aboutbox},
{"alias", builtin_alias},
{"directory", builtin_directory},
{"echo", builtin_echo},
{"exists", builtin_exists},
@ -176,6 +177,7 @@ namespace {
{"quote", builtin_quote},
{"set", builtin_set},
{"shift", builtin_shift},
{"unalias", builtin_unalias},
{"unexport", builtin_unexport},
{"unset", builtin_unset},
{"version", builtin_version},

View File

@ -190,3 +190,66 @@ namespace {
}
void Environment::rebuild_aliases() {
std::string as;
for (const auto &p : _alias_table) {
as += p.first;
as.push_back(',');
}
as.pop_back();
set_common("aliases", as, true);
}
void Environment::remove_alias() {
_alias_table.clear();
set_common("aliases", "", true);
}
void Environment::remove_alias(const std::string &name) {
std::string k(name);
lowercase(k);
auto iter = std::remove_if(_alias_table.begin(), _alias_table.end(), [&k](const auto &p){
return k == p.first;
});
_alias_table.erase(iter, _alias_table.end());
rebuild_aliases();
}
const std::string &Environment::find_alias(const std::string &name) const {
std::string k(name);
lowercase(k);
auto iter = std::find_if(_alias_table.begin(), _alias_table.end(), [&k](const auto &p){
return k == p.first;
});
if (iter == _alias_table.end()) {
static std::string empty;
return empty;
}
return iter->second;
}
void Environment::add_alias(std::string &&name, std::string &&value) {
lowercase(name);
auto iter = std::find_if(_alias_table.begin(), _alias_table.end(), [&name](const auto &p){
return name == p.first;
});
if (iter == _alias_table.end()) {
_alias_table.emplace_back(std::make_pair(std::move(name), std::move(value)));
} else {
iter->second = std::move(value);
}
rebuild_aliases();
}

View File

@ -51,6 +51,10 @@ public:
typedef mapped_type::iterator iterator;
typedef mapped_type::const_iterator const_iterator;
typedef std::vector<std::pair<std::string, std::string>> alias_table_type;
typedef alias_table_type::const_iterator const_alias_iterator;
//const EnvironmentEntry & lookup(const std::string &s);
void set_argv(const std::string &argv0, const std::vector<std::string>& argv);
@ -114,6 +118,17 @@ public:
constexpr bool loop() const noexcept { return _loop; }
const alias_table_type &aliases() const { return _alias_table; }
void add_alias(std::string &&name, std::string &&value);
const std::string &find_alias(const std::string &s) const;
void remove_alias(const std::string &name);
void remove_alias();
const_alias_iterator alias_begin() const { return _alias_table.begin(); }
const_alias_iterator alias_end() const { return _alias_table.end(); }
private:
// magic variables.
@ -132,8 +147,11 @@ private:
bool _passthrough = false;
void set_common(const std::string &, const std::string &, bool);
void rebuild_aliases();
std::unordered_map<std::string, EnvironmentEntry> _table;
alias_table_type _alias_table;
};
/*