aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/lexer/parseline.h10
-rw-r--r--module-test/parseline_test.cc61
-rw-r--r--src/lexer/parseline.cc80
-rw-r--r--src/lexer/token.cc2
4 files changed, 152 insertions, 1 deletions
diff --git a/include/lexer/parseline.h b/include/lexer/parseline.h
new file mode 100644
index 0000000..e52b50e
--- /dev/null
+++ b/include/lexer/parseline.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include <string>
+
+namespace ov4
+{
+
+char **parseline(const std::string &s);
+
+}
diff --git a/module-test/parseline_test.cc b/module-test/parseline_test.cc
new file mode 100644
index 0000000..047be48
--- /dev/null
+++ b/module-test/parseline_test.cc
@@ -0,0 +1,61 @@
+/*
+ * test lexer/parseline
+$
+g++ \
+ module-test/parseline_test.cc \
+ src/lexer/parseline.cc \
+ src/util/string.cc \
+ -std=c++23 -Iinclude \
+ -O0 -ggdb3 -fno-omit-frame-pointer -fno-inline -D_GLIBCXX_ASSERTIONS \
+ -o module-test/parseline_test.out
+*/
+
+#include <iostream>
+#include <print>
+
+#include "lexer/parseline.h"
+
+using namespace std;
+
+int main()
+{
+ int test_case = 0;
+ println("start test");
+ cin >> test_case;
+ string s;
+
+ switch (test_case)
+ {
+ case 0:
+ s = "alpha beta";
+ break;
+
+ case 1:
+ s = "alpha \'arg1 and arg2\'";
+ break;
+
+ case 2:
+ s = "alpha \'arg1 \" arg2 arg3 \'";
+ break;
+
+ case 3:
+ s = "alpha \'arg1 \"arg2 arg3\" arg4 \'";
+ break;
+
+ default:
+ return 0;
+ }
+ char **p = ov4::parseline(s);
+ if (p == nullptr)
+ {
+ println("Ooooops nullptr");
+ return 0;
+ }
+ for (size_t i = 0; ; i++)
+ {
+ if (p[i] == nullptr)
+ break;
+ println("{}", p[i]);
+ }
+ return 0;
+}
diff --git a/src/lexer/parseline.cc b/src/lexer/parseline.cc
new file mode 100644
index 0000000..064f876
--- /dev/null
+++ b/src/lexer/parseline.cc
@@ -0,0 +1,80 @@
+#include "lexer/parseline.h"
+
+#include <vector>
+
+#include "lexer/enum_type.h"
+#include "util/string.h"
+
+using namespace std;
+
+namespace ov4
+{
+
+char **parseline(const std::string &s)
+{
+ guard_type guard = GUARD_OFF;
+ vector<string> v;
+ size_t len = s.size();
+ string prev_str = "";
+ char c;
+
+ for (size_t i = 0; i < len; i++)
+ {
+
+ c = s[i];
+ if (c == ' ' && guard == GUARD_OFF) continue;
+
+ if (c == '\'' || c == '\"')
+ {
+
+ // turn on GUARD
+ if (guard == GUARD_OFF)
+ {
+ guard = (c == '\'') ? GUARD_STRONG : GUARD_WEAK;
+ if (i+1 == len)
+ {
+ v.push_back(prev_str);
+ prev_str = "";
+ }
+ continue;
+ }
+ // turn off
+ else if (guard == GUARD_STRONG && c == '\'')
+ {
+ guard = GUARD_OFF;
+ if (i+1 == len)
+ {
+ v.push_back(prev_str);
+ prev_str = "";
+ }
+ continue;
+ }
+ // turn off
+ else if (guard == GUARD_WEAK && c == '\"')
+ {
+ guard = GUARD_OFF;
+ if (i+1 == len)
+ {
+ v.push_back(prev_str);
+ prev_str = "";
+ }
+ continue;
+ }
+ // if this (single/double) quotation mark is guarded
+ // it should be saved
+ }
+
+ prev_str += c;
+
+ if ((i+1 >= len) || (s[i+1] == ' ' && guard == GUARD_OFF))
+ {
+ v.push_back(prev_str);
+ prev_str = "";
+ continue;
+ }
+ }
+
+ return string2argv_alloc(v);
+}
+
+}
diff --git a/src/lexer/token.cc b/src/lexer/token.cc
index b9b8242..ec69090 100644
--- a/src/lexer/token.cc
+++ b/src/lexer/token.cc
@@ -12,7 +12,7 @@
using namespace std; // remove this
-constexpr bool TOKEN_DEBUG = true;
+constexpr bool TOKEN_DEBUG = false;
namespace ov4
{