Compare commits
2 Commits
fd94247aec
...
fdf33c69b7
Author | SHA1 | Date |
---|---|---|
Kelvin Sherlock | fdf33c69b7 | |
Kelvin Sherlock | 6f2b59c4d6 |
22
command.cpp
22
command.cpp
|
@ -107,6 +107,9 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool is_script(const fs::path &path) {
|
||||||
|
return path.extension() == ".text";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -359,8 +362,6 @@ int simple_command::execute(Environment &env, const fdmask &fds, bool throwup) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (env.test()) return 0;
|
|
||||||
|
|
||||||
if (env.startup()) {
|
if (env.startup()) {
|
||||||
fprintf(stderr, "### MPW Shell - startup file may not contain external commands.\n");
|
fprintf(stderr, "### MPW Shell - startup file may not contain external commands.\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -374,6 +375,23 @@ int simple_command::execute(Environment &env, const fdmask &fds, bool throwup) {
|
||||||
//fprintf(stderr, "### MPW Shell - Command \"%s\" was not found.\n", name.c_str());
|
//fprintf(stderr, "### MPW Shell - Command \"%s\" was not found.\n", name.c_str());
|
||||||
//return -1;
|
//return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_script(path)) {
|
||||||
|
// scripts run with an isolated environment.
|
||||||
|
Environment new_env = env.subshell_environment();
|
||||||
|
new_env.set("command", path);
|
||||||
|
new_env.set_argv(path, p.arguments);
|
||||||
|
|
||||||
|
try {
|
||||||
|
return read_file(new_env, path, newfds);
|
||||||
|
} catch (const exit_command_t &ex) {
|
||||||
|
return ex.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (env.test()) return 0;
|
||||||
|
|
||||||
env.set("command", path);
|
env.set("command", path);
|
||||||
p.arguments[0] = path;
|
p.arguments[0] = path;
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,10 @@ namespace {
|
||||||
|
|
||||||
bool tf(long v) { return v; }
|
bool tf(long v) { return v; }
|
||||||
|
|
||||||
|
bool tf(const EnvironmentEntry &e) {
|
||||||
|
return tf(static_cast<std::string>(e));
|
||||||
|
}
|
||||||
|
|
||||||
// used for #. base 10 only, extra chars ignored.
|
// used for #. base 10 only, extra chars ignored.
|
||||||
int to_pound_int(const std::string &s) {
|
int to_pound_int(const std::string &s) {
|
||||||
if (s.empty()) return 0;
|
if (s.empty()) return 0;
|
||||||
|
@ -38,6 +42,29 @@ namespace {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Environment Environment::subshell_environment() {
|
||||||
|
/* clone the current environment, do not include local variables */
|
||||||
|
Environment env;
|
||||||
|
env._alias_table = _alias_table;
|
||||||
|
|
||||||
|
auto &table = env._table;
|
||||||
|
for (const auto &kv : _table) {
|
||||||
|
const auto &k = kv.first;
|
||||||
|
const auto &value = kv.second;
|
||||||
|
if (!value) continue;
|
||||||
|
|
||||||
|
if (k == "echo") env._echo = tf(value);
|
||||||
|
if (k == "exit") env._exit = tf(value);
|
||||||
|
if (k == "test") env._test = tf(value);
|
||||||
|
|
||||||
|
table.emplace_hint(table.end(), k, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return env;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string Environment::get(const std::string & key) const {
|
std::string Environment::get(const std::string & key) const {
|
||||||
auto iter = find(key);
|
auto iter = find(key);
|
||||||
if (iter == end()) return "";
|
if (iter == end()) return "";
|
||||||
|
|
|
@ -56,7 +56,8 @@ public:
|
||||||
typedef std::vector<std::pair<std::string, std::string>> alias_table_type;
|
typedef std::vector<std::pair<std::string, std::string>> alias_table_type;
|
||||||
typedef alias_table_type::const_iterator const_alias_iterator;
|
typedef alias_table_type::const_iterator const_alias_iterator;
|
||||||
|
|
||||||
//const EnvironmentEntry & lookup(const std::string &s);
|
|
||||||
|
Environment subshell_environment();
|
||||||
|
|
||||||
void set_argv(const std::string &argv0, const std::vector<std::string>& argv);
|
void set_argv(const std::string &argv0, const std::vector<std::string>& argv);
|
||||||
void set_argv(const std::vector<std::string>& argv);
|
void set_argv(const std::vector<std::string>& argv);
|
||||||
|
@ -80,10 +81,6 @@ public:
|
||||||
bool startup() const noexcept { return _startup; }
|
bool startup() const noexcept { return _startup; }
|
||||||
void startup(bool tf) noexcept { _startup = tf; }
|
void startup(bool tf) noexcept { _startup = tf; }
|
||||||
|
|
||||||
|
|
||||||
bool passthrough() const noexcept { return _passthrough; }
|
|
||||||
void passthrough(bool tf) noexcept { _passthrough = tf; }
|
|
||||||
|
|
||||||
template<class FX>
|
template<class FX>
|
||||||
void foreach(FX && fx) { for (const auto &kv : _table) { fx(kv.first, kv.second); }}
|
void foreach(FX && fx) { for (const auto &kv : _table) { fx(kv.first, kv.second); }}
|
||||||
|
|
||||||
|
@ -133,8 +130,6 @@ public:
|
||||||
private:
|
private:
|
||||||
// magic variables.
|
// magic variables.
|
||||||
|
|
||||||
friend class indent_helper;
|
|
||||||
|
|
||||||
int _indent = 0;
|
int _indent = 0;
|
||||||
int _loop = 0;
|
int _loop = 0;
|
||||||
|
|
||||||
|
@ -145,7 +140,6 @@ private:
|
||||||
int _status = 0;
|
int _status = 0;
|
||||||
int _pound = 0;
|
int _pound = 0;
|
||||||
bool _startup = false;
|
bool _startup = false;
|
||||||
bool _passthrough = false;
|
|
||||||
|
|
||||||
void set_common(const std::string &, const std::string &, bool);
|
void set_common(const std::string &, const std::string &, bool);
|
||||||
void rebuild_aliases();
|
void rebuild_aliases();
|
||||||
|
@ -155,16 +149,5 @@ private:
|
||||||
alias_table_type _alias_table;
|
alias_table_type _alias_table;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
class indent_helper {
|
|
||||||
public:
|
|
||||||
indent_helper(Environment &e) : env(e) { env._indent++; }
|
|
||||||
void release() { if (active) { active = false; env._indent--; }}
|
|
||||||
~indent_helper() { if (active) env._indent--; }
|
|
||||||
private:
|
|
||||||
Environment &env;
|
|
||||||
bool active = true;
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
17
error.h
17
error.h
|
@ -67,6 +67,21 @@ public:
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class fsstring_error: public mpw_error {
|
||||||
|
public:
|
||||||
|
fsstring_error(int status = -3) :
|
||||||
|
mpw_error(status, "MPW Shell - /s must occur in pairs.")
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
class bsstring_error: public mpw_error {
|
||||||
|
public:
|
||||||
|
bsstring_error(int status = -3) :
|
||||||
|
mpw_error(status, "MPW Shell - \\s must occur in pairs.")
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
these are used for flow-control.
|
these are used for flow-control.
|
||||||
they do not inherit from std::exception to prevent being caught
|
they do not inherit from std::exception to prevent being caught
|
||||||
|
@ -78,4 +93,4 @@ struct continue_command_t {};
|
||||||
struct exit_command_t { int value = 0; };
|
struct exit_command_t { int value = 0; };
|
||||||
struct quit_command_t {};
|
struct quit_command_t {};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -37,6 +37,13 @@
|
||||||
dchar = escape_seq | (any - escape - ["]);
|
dchar = escape_seq | (any - escape - ["]);
|
||||||
dstring = ["] dchar** ["] $err{ throw dstring_error(); } ;
|
dstring = ["] dchar** ["] $err{ throw dstring_error(); } ;
|
||||||
|
|
||||||
|
# search-forward string
|
||||||
|
fschar = escape_seq | (any - escape - [/]);
|
||||||
|
fsstring = [/] fschar** [/] $err{ throw fsstring_error(); } ;
|
||||||
|
|
||||||
|
# search-backward string
|
||||||
|
bschar = escape_seq | (any - escape - [\\]);
|
||||||
|
bsstring = [\\] bschar** [\\] $err{ throw bsstring_error(); } ;
|
||||||
|
|
||||||
action eval { eval }
|
action eval { eval }
|
||||||
|
|
||||||
|
@ -127,9 +134,16 @@
|
||||||
'-=' when eval
|
'-=' when eval
|
||||||
%push_token => { tokens.emplace_back("-=", '-='); };
|
%push_token => { tokens.emplace_back("-=", '-='); };
|
||||||
|
|
||||||
|
'=~' when eval
|
||||||
|
%push_token => { tokens.emplace_back("=~", '=~'); };
|
||||||
|
|
||||||
|
'!~' when eval
|
||||||
|
%push_token => { tokens.emplace_back("!~", '!~'); };
|
||||||
|
|
||||||
sstring => push_string;
|
sstring => push_string;
|
||||||
dstring => push_string;
|
dstring => push_string;
|
||||||
|
fsstring => push_string;
|
||||||
|
bsstring => push_string;
|
||||||
escape_seq => push_string;
|
escape_seq => push_string;
|
||||||
|
|
||||||
char => push;
|
char => push;
|
||||||
|
|
Loading…
Reference in New Issue