diff options
author | John Wiegley <johnw@newartisans.com> | 2009-10-26 17:17:01 -0400 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2009-10-26 17:17:01 -0400 |
commit | feff681f4464eb9b538bde613afaf3b03c7c223a (patch) | |
tree | 0dbe6b679048f0de05b9bd50d4fed53c68552dce /src | |
parent | 92d1bbbe75df71731d458f5b48bcb0f145428920 (diff) | |
download | fork-ledger-feff681f4464eb9b538bde613afaf3b03c7c223a.tar.gz fork-ledger-feff681f4464eb9b538bde613afaf3b03c7c223a.tar.bz2 fork-ledger-feff681f4464eb9b538bde613afaf3b03c7c223a.zip |
Improved argument parsing logic used by the REPL
It now handles quoted strings, although it doesn't understand escape
sequences yet.
Diffstat (limited to 'src')
-rw-r--r-- | src/main.cc | 15 | ||||
-rw-r--r-- | src/utils.cc | 53 | ||||
-rw-r--r-- | src/utils.h | 2 |
3 files changed, 55 insertions, 15 deletions
diff --git a/src/main.cc b/src/main.cc index c9a922af..9f0e8690 100644 --- a/src/main.cc +++ b/src/main.cc @@ -37,21 +37,6 @@ using namespace ledger; -namespace { - strings_list split_arguments(char * line) - { - strings_list args; - - // jww (2009-02-04): This is too naive - for (char * p = std::strtok(line, " \t"); - p; - p = std::strtok(NULL, " \t")) - args.push_back(p); - - return args; - } -} - #ifdef HAVE_BOOST_PYTHON namespace ledger { extern char * argv0; diff --git a/src/utils.cc b/src/utils.cc index 0afea4c2..85a7aa46 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -442,6 +442,59 @@ string::~string() throw() { ledger::string empty_string(""); +ledger::strings_list split_arguments(const char * line) +{ + using namespace ledger; + + strings_list args; + + char buf[4096]; + char * q = buf; + char in_quoted_string = '\0'; + + for (const char * p = line; *p; p++) { + if (! in_quoted_string && std::isspace(*p)) { + if (q != buf) { + *q = '\0'; + args.push_back(buf); + q = buf; + } + } + else if (in_quoted_string != '\'' && *p == '\\') { + p++; + if (! *p) + throw_(std::logic_error, _("Invalid use of backslash")); + *q++ = *p; + } + else if (in_quoted_string != '"' && *p == '\'') { + if (in_quoted_string == '\'') + in_quoted_string = '\0'; + else + in_quoted_string = '\''; + } + else if (in_quoted_string != '\'' && *p == '"') { + if (in_quoted_string == '"') + in_quoted_string = '\0'; + else + in_quoted_string = '"'; + } + else { + *q++ = *p; + } + } + + if (in_quoted_string) + throw_(std::logic_error, + _("Unterminated string, expected '%1'") << in_quoted_string); + + if (q != buf) { + *q = '\0'; + args.push_back(buf); + } + + return args; +} + /********************************************************************** * * Logging diff --git a/src/utils.h b/src/utils.h index 7f5ca017..98bdf9af 100644 --- a/src/utils.h +++ b/src/utils.h @@ -237,6 +237,8 @@ inline bool operator!=(const string& __lhs, const char* __rhs) extern ledger::string empty_string; +ledger::strings_list split_arguments(const char * line); + #define IF_VERIFY() if (DO_VERIFY()) /*@}*/ |