mirror of
https://github.com/tstack/lnav
synced 2024-11-01 21:40:34 +00:00
[cmd] replace wordexp with shlex
This commit is contained in:
parent
16e988d132
commit
ab62d27757
@ -91,6 +91,17 @@ check_output() {
|
|||||||
test_num=`expr ${test_num} \+ 1`
|
test_num=`expr ${test_num} \+ 1`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check_output_ws() {
|
||||||
|
diff -u - ${test_file_base}_${test_num}.tmp > ${test_file_base}_${test_num}.diff
|
||||||
|
if test $? -ne 0; then
|
||||||
|
echo $LAST_TEST
|
||||||
|
echo $1
|
||||||
|
cat ${test_file_base}_${test_num}.diff
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
test_num=`expr ${test_num} \+ 1`
|
||||||
|
}
|
||||||
|
|
||||||
test_err_filename() {
|
test_err_filename() {
|
||||||
echo ${test_file_base}_${test_num}.err
|
echo ${test_file_base}_${test_num}.err
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include "pcrecpp.h"
|
#include "pcrecpp.h"
|
||||||
#include "lnav.hh"
|
#include "lnav.hh"
|
||||||
#include "log_format_loader.hh"
|
#include "log_format_loader.hh"
|
||||||
|
#include "shlex.hh"
|
||||||
|
|
||||||
#include "command_executor.hh"
|
#include "command_executor.hh"
|
||||||
|
|
||||||
@ -328,35 +329,32 @@ string execute_file(const string &path_and_args, bool multiline)
|
|||||||
{
|
{
|
||||||
map<string, vector<string> > scripts;
|
map<string, vector<string> > scripts;
|
||||||
map<string, vector<string> >::iterator iter;
|
map<string, vector<string> >::iterator iter;
|
||||||
static_root_mem<wordexp_t, wordfree> wordmem;
|
vector<string> split_args;
|
||||||
string msg, retval;
|
string msg, retval;
|
||||||
|
shlex lexer(path_and_args);
|
||||||
|
|
||||||
log_info("Executing file: %s", path_and_args.c_str());
|
log_info("Executing file: %s", path_and_args.c_str());
|
||||||
|
|
||||||
int exp_rc = wordexp(path_and_args.c_str(),
|
if (!lexer.split(split_args, lnav_data.ld_local_vars.top())) {
|
||||||
wordmem.inout(),
|
retval = "error: unable to parse path";
|
||||||
WRDE_NOCMD | WRDE_UNDEF);
|
|
||||||
|
|
||||||
if (!wordexperr(exp_rc, msg)) {
|
|
||||||
retval = msg;
|
|
||||||
}
|
}
|
||||||
else if (wordmem->we_wordc == 0) {
|
else if (split_args.empty()) {
|
||||||
retval = "error: no script specified";
|
retval = "error: no script specified";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
lnav_data.ld_local_vars.push(map<string, string>());
|
lnav_data.ld_local_vars.push(map<string, string>());
|
||||||
|
|
||||||
string script_name = wordmem->we_wordv[0];
|
string script_name = split_args[0];
|
||||||
map<string, string> &vars = lnav_data.ld_local_vars.top();
|
map<string, string> &vars = lnav_data.ld_local_vars.top();
|
||||||
char env_arg_name[32];
|
char env_arg_name[32];
|
||||||
string result, open_error = "file not found";
|
string result, open_error = "file not found";
|
||||||
|
|
||||||
snprintf(env_arg_name, sizeof(env_arg_name), "%d", (int) wordmem->we_wordc - 1);
|
snprintf(env_arg_name, sizeof(env_arg_name), "%d", (int) split_args.size() - 1);
|
||||||
|
|
||||||
vars["#"] = env_arg_name;
|
vars["#"] = env_arg_name;
|
||||||
for (unsigned int lpc = 0; lpc < wordmem->we_wordc; lpc++) {
|
for (unsigned int lpc = 0; lpc < split_args.size(); lpc++) {
|
||||||
snprintf(env_arg_name, sizeof(env_arg_name), "%d", lpc);
|
snprintf(env_arg_name, sizeof(env_arg_name), "%d", lpc);
|
||||||
vars[env_arg_name] = wordmem->we_wordv[lpc];
|
vars[env_arg_name] = split_args[lpc];
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<string> paths_to_exec;
|
vector<string> paths_to_exec;
|
||||||
|
@ -1925,7 +1925,7 @@ static void looper(void)
|
|||||||
"to switch to the next/previous file"));
|
"to switch to the next/previous file"));
|
||||||
}
|
}
|
||||||
if (lnav_data.ld_view_stack.top() == &lnav_data.ld_views[LNV_TEXT] &&
|
if (lnav_data.ld_view_stack.top() == &lnav_data.ld_views[LNV_TEXT] &&
|
||||||
lnav_data.ld_text_source.text_line_count() == 0 &&
|
lnav_data.ld_text_source.empty() &&
|
||||||
lnav_data.ld_log_source.text_line_count() > 0) {
|
lnav_data.ld_log_source.text_line_count() > 0) {
|
||||||
textview_curses *tc_log = &lnav_data.ld_views[LNV_LOG];
|
textview_curses *tc_log = &lnav_data.ld_views[LNV_LOG];
|
||||||
lnav_data.ld_view_stack.pop();
|
lnav_data.ld_view_stack.pop();
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <wordexp.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -459,15 +458,13 @@ static string com_save_to(string cmdline, vector<string> &args)
|
|||||||
|
|
||||||
fn = trim(remaining_args(cmdline, args));
|
fn = trim(remaining_args(cmdline, args));
|
||||||
|
|
||||||
static_root_mem<wordexp_t, wordfree> wordmem;
|
vector<string> split_args;
|
||||||
|
shlex lexer(fn);
|
||||||
|
|
||||||
int rc = wordexp(fn.c_str(), wordmem.inout(), WRDE_NOCMD | WRDE_UNDEF);
|
if (!lexer.split(split_args, lnav_data.ld_local_vars.top())) {
|
||||||
|
return "error: unable to parse arguments";
|
||||||
if (!wordexperr(rc, retval)) {
|
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
if (split_args.size() > 1) {
|
||||||
if (wordmem->we_wordc > 1) {
|
|
||||||
return "error: more than one file name was matched";
|
return "error: more than one file name was matched";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -495,7 +492,7 @@ static string com_save_to(string cmdline, vector<string> &args)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(wordmem->we_wordv[0], "-") == 0) {
|
if (split_args[0] == "-") {
|
||||||
outfile = stdout;
|
outfile = stdout;
|
||||||
if (lnav_data.ld_flags & LNF_HEADLESS) {
|
if (lnav_data.ld_flags & LNF_HEADLESS) {
|
||||||
lnav_data.ld_stdout_used = true;
|
lnav_data.ld_stdout_used = true;
|
||||||
@ -515,8 +512,8 @@ static string com_save_to(string cmdline, vector<string> &args)
|
|||||||
args[0].c_str());
|
args[0].c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((outfile = fopen(wordmem->we_wordv[0], mode)) == NULL) {
|
else if ((outfile = fopen(split_args[0].c_str(), mode)) == NULL) {
|
||||||
return "error: unable to open file -- " + string(wordmem->we_wordv[0]);
|
return "error: unable to open file -- " + split_args[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args[0] == "write-csv-to") {
|
if (args[0] == "write-csv-to") {
|
||||||
@ -1306,7 +1303,7 @@ static string com_open(string cmdline, vector<string> &args)
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static_root_mem<wordexp_t, wordfree> wordmem;
|
vector<string> word_exp;
|
||||||
list<logfile *>::iterator file_iter;
|
list<logfile *>::iterator file_iter;
|
||||||
size_t colon_index;
|
size_t colon_index;
|
||||||
int top = 0;
|
int top = 0;
|
||||||
@ -1314,14 +1311,15 @@ static string com_open(string cmdline, vector<string> &args)
|
|||||||
|
|
||||||
pat = trim(remaining_args(cmdline, args));
|
pat = trim(remaining_args(cmdline, args));
|
||||||
|
|
||||||
int rc = wordexp(pat.c_str(), wordmem.inout(), WRDE_NOCMD | WRDE_UNDEF);
|
vector<string> split_args;
|
||||||
|
shlex lexer(pat);
|
||||||
|
|
||||||
if (!wordexperr(rc, retval)) {
|
if (!lexer.split(split_args, lnav_data.ld_local_vars.top())) {
|
||||||
return retval;
|
return "error: unable to parse arguments";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t lpc = 0; lpc < wordmem->we_wordc; lpc++) {
|
for (size_t lpc = 0; lpc < split_args.size(); lpc++) {
|
||||||
string fn = wordmem->we_wordv[lpc];
|
string fn = split_args[lpc];
|
||||||
|
|
||||||
if (startswith(fn, "pt:")) {
|
if (startswith(fn, "pt:")) {
|
||||||
lnav_data.ld_pt_search = fn;
|
lnav_data.ld_pt_search = fn;
|
||||||
|
@ -516,6 +516,7 @@ void readline_shlex_highlighter(attr_line_t &al, int x)
|
|||||||
&view_curses::VC_STYLE,
|
&view_curses::VC_STYLE,
|
||||||
error_attrs));
|
error_attrs));
|
||||||
break;
|
break;
|
||||||
|
case ST_TILDE:
|
||||||
case ST_ESCAPE:
|
case ST_ESCAPE:
|
||||||
al.with_attr(string_attr(
|
al.with_attr(string_attr(
|
||||||
line_range(cap.c_begin, cap.c_end),
|
line_range(cap.c_begin, cap.c_end),
|
||||||
@ -556,6 +557,8 @@ void readline_shlex_highlighter(attr_line_t &al, int x)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ST_WHITESPACE:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
111
src/shlex.hh
111
src/shlex.hh
@ -38,6 +38,7 @@
|
|||||||
|
|
||||||
enum shlex_token_t {
|
enum shlex_token_t {
|
||||||
ST_ERROR,
|
ST_ERROR,
|
||||||
|
ST_WHITESPACE,
|
||||||
ST_ESCAPE,
|
ST_ESCAPE,
|
||||||
ST_DOUBLE_QUOTE_START,
|
ST_DOUBLE_QUOTE_START,
|
||||||
ST_DOUBLE_QUOTE_END,
|
ST_DOUBLE_QUOTE_END,
|
||||||
@ -45,6 +46,7 @@ enum shlex_token_t {
|
|||||||
ST_SINGLE_QUOTE_END,
|
ST_SINGLE_QUOTE_END,
|
||||||
ST_VARIABLE_REF,
|
ST_VARIABLE_REF,
|
||||||
ST_QUOTED_VARIABLE_REF,
|
ST_QUOTED_VARIABLE_REF,
|
||||||
|
ST_TILDE,
|
||||||
};
|
};
|
||||||
|
|
||||||
class shlex {
|
class shlex {
|
||||||
@ -126,6 +128,33 @@ public:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case '~':
|
||||||
|
switch (this->s_state) {
|
||||||
|
case STATE_NORMAL:
|
||||||
|
cap_out.c_begin = this->s_index;
|
||||||
|
this->s_index += 1;
|
||||||
|
cap_out.c_end = this->s_index;
|
||||||
|
token_out = ST_TILDE;
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ' ':
|
||||||
|
case '\t':
|
||||||
|
switch (this->s_state) {
|
||||||
|
case STATE_NORMAL:
|
||||||
|
cap_out.c_begin = this->s_index;
|
||||||
|
while (isspace(this->s_str[this->s_index])) {
|
||||||
|
this->s_index += 1;
|
||||||
|
}
|
||||||
|
cap_out.c_end = this->s_index;
|
||||||
|
token_out = ST_WHITESPACE;
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -151,6 +180,9 @@ public:
|
|||||||
case ST_ESCAPE:
|
case ST_ESCAPE:
|
||||||
result.append(1, this->s_str[cap.c_begin + 1]);
|
result.append(1, this->s_str[cap.c_begin + 1]);
|
||||||
break;
|
break;
|
||||||
|
case ST_WHITESPACE:
|
||||||
|
result.append(&this->s_str[cap.c_begin], cap.length());
|
||||||
|
break;
|
||||||
case ST_VARIABLE_REF:
|
case ST_VARIABLE_REF:
|
||||||
case ST_QUOTED_VARIABLE_REF: {
|
case ST_QUOTED_VARIABLE_REF: {
|
||||||
int extra = token == ST_VARIABLE_REF ? 0 : 1;
|
int extra = token == ST_VARIABLE_REF ? 0 : 1;
|
||||||
@ -166,6 +198,17 @@ public:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ST_TILDE: {
|
||||||
|
const char *home_dir = getenv("HOME");
|
||||||
|
|
||||||
|
if (home_dir != NULL) {
|
||||||
|
result.append(home_dir);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result.append("~");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -177,6 +220,74 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool split(std::vector<std::string> &result, const std::map<std::string, std::string> &vars) {
|
||||||
|
result.clear();
|
||||||
|
|
||||||
|
pcre_context::capture_t cap;
|
||||||
|
shlex_token_t token;
|
||||||
|
int last_index = 0;
|
||||||
|
bool start_new = true;
|
||||||
|
|
||||||
|
while (isspace(this->s_str[this->s_index])) {
|
||||||
|
this->s_index += 1;
|
||||||
|
}
|
||||||
|
while (this->tokenize(cap, token)) {
|
||||||
|
if (start_new) {
|
||||||
|
result.push_back("");
|
||||||
|
start_new = false;
|
||||||
|
}
|
||||||
|
result.back().append(&this->s_str[last_index], cap.c_begin - last_index);
|
||||||
|
switch (token) {
|
||||||
|
case ST_ERROR:
|
||||||
|
return false;
|
||||||
|
case ST_ESCAPE:
|
||||||
|
result.back().append(1, this->s_str[cap.c_begin + 1]);
|
||||||
|
break;
|
||||||
|
case ST_WHITESPACE:
|
||||||
|
start_new = true;
|
||||||
|
break;
|
||||||
|
case ST_VARIABLE_REF:
|
||||||
|
case ST_QUOTED_VARIABLE_REF: {
|
||||||
|
int extra = token == ST_VARIABLE_REF ? 0 : 1;
|
||||||
|
std::string var_name(&this->s_str[cap.c_begin + 1 + extra], cap.length() - 1 - extra * 2);
|
||||||
|
std::map<std::string, std::string>::const_iterator local_var;
|
||||||
|
const char *var_value = getenv(var_name.c_str());
|
||||||
|
|
||||||
|
if ((local_var = vars.find(var_name)) != vars.end()) {
|
||||||
|
result.back().append(local_var->second);
|
||||||
|
}
|
||||||
|
else if (var_value != NULL) {
|
||||||
|
result.back().append(var_value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ST_TILDE: {
|
||||||
|
const char *home_dir = getenv("HOME");
|
||||||
|
|
||||||
|
if (home_dir != NULL) {
|
||||||
|
result.back().append(home_dir);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result.back().append("~");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
last_index = cap.c_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last_index < this->s_len) {
|
||||||
|
if (start_new || result.empty()) {
|
||||||
|
result.push_back("");
|
||||||
|
}
|
||||||
|
result.back().append(&this->s_str[last_index], this->s_len - last_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
this->s_index = 0;
|
this->s_index = 0;
|
||||||
this->s_state = STATE_NORMAL;
|
this->s_state = STATE_NORMAL;
|
||||||
|
@ -37,6 +37,7 @@ using namespace std;
|
|||||||
|
|
||||||
const char *ST_TOKEN_NAMES[] = {
|
const char *ST_TOKEN_NAMES[] = {
|
||||||
"err",
|
"err",
|
||||||
|
"wsp",
|
||||||
"esc",
|
"esc",
|
||||||
"dst",
|
"dst",
|
||||||
"den",
|
"den",
|
||||||
@ -44,6 +45,7 @@ const char *ST_TOKEN_NAMES[] = {
|
|||||||
"sen",
|
"sen",
|
||||||
"ref",
|
"ref",
|
||||||
"qrf",
|
"qrf",
|
||||||
|
"til",
|
||||||
};
|
};
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
@ -84,6 +86,14 @@ int main(int argc, char *argv[])
|
|||||||
if (lexer.eval(result, map<string, string>())) {
|
if (lexer.eval(result, map<string, string>())) {
|
||||||
printf("eval -- %s\n", result.c_str());
|
printf("eval -- %s\n", result.c_str());
|
||||||
}
|
}
|
||||||
|
lexer.reset();
|
||||||
|
std::vector<std::string> sresult;
|
||||||
|
if (lexer.split(sresult, map<string, string>())) {
|
||||||
|
printf("split:\n");
|
||||||
|
for (int lpc = 0; lpc < sresult.size(); lpc++) {
|
||||||
|
printf(" %d -- %s\n", lpc, sresult[lpc].c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#! /bin/bash
|
#! /bin/bash
|
||||||
|
|
||||||
run_test ${lnav_test} -n \
|
run_test ${lnav_test} -n \
|
||||||
-c "|${test_dir}/toplevel.lnav 123 456" \
|
-c "|${test_dir}/toplevel.lnav 123 456 789" \
|
||||||
${test_dir}/logfile_access_log.0
|
${test_dir}/logfile_access_log.0
|
||||||
|
|
||||||
check_error_output "include toplevel.lnav" <<EOF
|
check_error_output "include toplevel.lnav" <<EOF
|
||||||
@ -9,7 +9,7 @@ EOF
|
|||||||
|
|
||||||
check_output "include toplevel.lnav" <<EOF
|
check_output "include toplevel.lnav" <<EOF
|
||||||
toplevel here 123 456
|
toplevel here 123 456
|
||||||
nested here nested.lnav abc
|
nested here nested.lnav abc 789
|
||||||
192.168.202.254 - - [20/Jul/2009:22:59:26 +0000] "GET /vmw/cgi/tramp HTTP/1.0" 200 134 "-" "gPXE/0.9.7"
|
192.168.202.254 - - [20/Jul/2009:22:59:26 +0000] "GET /vmw/cgi/tramp HTTP/1.0" 200 134 "-" "gPXE/0.9.7"
|
||||||
192.168.202.254 - - [20/Jul/2009:22:59:29 +0000] "GET /vmw/vSphere/default/vmkboot.gz HTTP/1.0" 404 46210 "-" "gPXE/0.9.7"
|
192.168.202.254 - - [20/Jul/2009:22:59:29 +0000] "GET /vmw/vSphere/default/vmkboot.gz HTTP/1.0" 404 46210 "-" "gPXE/0.9.7"
|
||||||
192.168.202.254 - - [20/Jul/2009:22:59:29 +0000] "GET /vmw/vSphere/default/vmkernel.gz HTTP/1.0" 200 78929 "-" "gPXE/0.9.7"
|
192.168.202.254 - - [20/Jul/2009:22:59:29 +0000] "GET /vmw/vSphere/default/vmkernel.gz HTTP/1.0" 200 78929 "-" "gPXE/0.9.7"
|
||||||
|
@ -5,104 +5,142 @@ export DEF='xyz'
|
|||||||
|
|
||||||
run_test ./drive_shlexer '$FOO'
|
run_test ./drive_shlexer '$FOO'
|
||||||
|
|
||||||
check_output "var ref" <<EOF
|
check_output_ws "var ref" <<EOF
|
||||||
\$FOO
|
\$FOO
|
||||||
ref ^--^
|
ref ^--^
|
||||||
eval -- bar
|
eval -- bar
|
||||||
|
split:
|
||||||
|
0 -- bar
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
run_test ./drive_shlexer '${FOO}'
|
run_test ./drive_shlexer '${FOO}'
|
||||||
|
|
||||||
check_output "var ref" <<EOF
|
check_output_ws "var ref" <<EOF
|
||||||
\${FOO}
|
\${FOO}
|
||||||
qrf ^----^
|
qrf ^----^
|
||||||
eval -- bar
|
eval -- bar
|
||||||
|
split:
|
||||||
|
0 -- bar
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
run_test ./drive_shlexer '\a'
|
run_test ./drive_shlexer '\a'
|
||||||
|
|
||||||
check_output "escape" <<EOF
|
check_output_ws "escape" <<EOF
|
||||||
\a
|
\a
|
||||||
esc ^^
|
esc ^^
|
||||||
eval -- a
|
eval -- a
|
||||||
|
split:
|
||||||
|
0 -- a
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
run_test ./drive_shlexer '\'
|
run_test ./drive_shlexer '\'
|
||||||
|
|
||||||
check_output "error" <<EOF
|
check_output_ws "error" <<EOF
|
||||||
\\
|
\\
|
||||||
err ^
|
err ^
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
run_test ./drive_shlexer "'abc'"
|
run_test ./drive_shlexer "'abc'"
|
||||||
|
|
||||||
check_output "single" <<EOF
|
check_output_ws "single" <<EOF
|
||||||
'abc'
|
'abc'
|
||||||
sst ^
|
sst ^
|
||||||
sen ^
|
sen ^
|
||||||
eval -- abc
|
eval -- abc
|
||||||
|
split:
|
||||||
|
0 -- abc
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
run_test ./drive_shlexer '"def"'
|
run_test ./drive_shlexer '"def"'
|
||||||
|
|
||||||
check_output "double" <<EOF
|
check_output_ws "double" <<EOF
|
||||||
"def"
|
"def"
|
||||||
dst ^
|
dst ^
|
||||||
den ^
|
den ^
|
||||||
eval -- def
|
eval -- def
|
||||||
|
split:
|
||||||
|
0 -- def
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
run_test ./drive_shlexer '"'"'"'"'
|
run_test ./drive_shlexer '"'"'"'"'
|
||||||
|
|
||||||
check_output "double with single" <<EOF
|
check_output_ws "double with single" <<EOF
|
||||||
"'"
|
"'"
|
||||||
dst ^
|
dst ^
|
||||||
den ^
|
den ^
|
||||||
eval -- '
|
eval -- '
|
||||||
|
split:
|
||||||
|
0 -- '
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
run_test ./drive_shlexer "'"'"'"'"
|
run_test ./drive_shlexer "'"'"'"'"
|
||||||
|
|
||||||
check_output "single with double" <<EOF
|
check_output_ws "single with double" <<EOF
|
||||||
'"'
|
'"'
|
||||||
sst ^
|
sst ^
|
||||||
sen ^
|
sen ^
|
||||||
eval -- "
|
eval -- "
|
||||||
|
split:
|
||||||
|
0 -- "
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
run_test ./drive_shlexer '"abc $DEF 123"'
|
run_test ./drive_shlexer '"abc $DEF 123"'
|
||||||
|
|
||||||
check_output "double w/ref" <<EOF
|
check_output_ws "double w/ref" <<EOF
|
||||||
"abc \$DEF 123"
|
"abc \$DEF 123"
|
||||||
dst ^
|
dst ^
|
||||||
ref ^--^
|
ref ^--^
|
||||||
den ^
|
den ^
|
||||||
eval -- abc xyz 123
|
eval -- abc xyz 123
|
||||||
|
split:
|
||||||
|
0 -- abc xyz 123
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
run_test ./drive_shlexer '"abc ${DEF} 123"'
|
run_test ./drive_shlexer '"abc ${DEF} 123"'
|
||||||
|
|
||||||
check_output "double w/ref" <<EOF
|
check_output_ws "double w/quoted-ref" <<EOF
|
||||||
"abc \${DEF} 123"
|
"abc \${DEF} 123"
|
||||||
dst ^
|
dst ^
|
||||||
qrf ^----^
|
qrf ^----^
|
||||||
den ^
|
den ^
|
||||||
eval -- abc xyz 123
|
eval -- abc xyz 123
|
||||||
|
split:
|
||||||
|
0 -- abc xyz 123
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
run_test ./drive_shlexer "'abc \$DEF 123'"
|
run_test ./drive_shlexer "'abc \$DEF 123'"
|
||||||
|
|
||||||
check_output "single w/ref" <<EOF
|
check_output_ws "single w/ref" <<EOF
|
||||||
'abc \$DEF 123'
|
'abc \$DEF 123'
|
||||||
sst ^
|
sst ^
|
||||||
sen ^
|
sen ^
|
||||||
eval -- abc \$DEF 123
|
eval -- abc \$DEF 123
|
||||||
|
split:
|
||||||
|
0 -- abc \$DEF 123
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
run_test ./drive_shlexer 'abc $DEF 123'
|
run_test ./drive_shlexer 'abc $DEF 123'
|
||||||
|
|
||||||
check_output "unquoted" <<EOF
|
check_output_ws "unquoted" <<EOF
|
||||||
abc \$DEF 123
|
abc \$DEF 123
|
||||||
|
wsp ^
|
||||||
ref ^--^
|
ref ^--^
|
||||||
eval -- abc xyz 123
|
wsp ^^
|
||||||
|
eval -- abc xyz 123
|
||||||
|
split:
|
||||||
|
0 -- abc
|
||||||
|
1 -- xyz
|
||||||
|
2 -- 123
|
||||||
|
EOF
|
||||||
|
|
||||||
|
run_test ./drive_shlexer '~ foo'
|
||||||
|
|
||||||
|
check_output_ws "tilde" <<EOF
|
||||||
|
~ foo
|
||||||
|
til ^
|
||||||
|
wsp ^
|
||||||
|
eval -- ../test foo
|
||||||
|
split:
|
||||||
|
0 -- ../test
|
||||||
|
1 -- foo
|
||||||
EOF
|
EOF
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
|
|
||||||
:eval :echo toplevel here $1 $2
|
:eval :echo toplevel here $1 $2
|
||||||
|
|
||||||
|nested.lnav abc
|
|nested.lnav abc $3
|
||||||
|
Loading…
Reference in New Issue
Block a user