about summary refs log tree commit diff stats
path: root/subx/038---literal_strings.cc
diff options
context:
space:
mode:
Diffstat (limited to 'subx/038---literal_strings.cc')
-rw-r--r--subx/038---literal_strings.cc46
1 files changed, 37 insertions, 9 deletions
diff --git a/subx/038---literal_strings.cc b/subx/038---literal_strings.cc
index 5f2c61af..a899f725 100644
--- a/subx/038---literal_strings.cc
+++ b/subx/038---literal_strings.cc
@@ -94,6 +94,10 @@ if (line_data.find('"') != string::npos) {  // can cause false-positives, but we
 
 :(code)
 void parse_instruction_character_by_character(const string& line_data, vector<line>& out) {
+  if (line_data.find('\n') != string::npos  && line_data.find('\n') != line_data.size()-1) {
+    raise << "parse_instruction_character_by_character: should receive only a single line\n" << end();
+    return;
+  }
   // parse literals
   istringstream in(line_data);
   in >> std::noskipws;
@@ -110,23 +114,41 @@ void parse_instruction_character_by_character(const string& line_data, vector<li
       if (isspace(in.peek()))
         continue;  // '.' followed by space is comment token; skip
     }
-    ostringstream w;
-    w << c;
+    result.words.push_back(word());
     if (c == '"') {
-      // slurp until '"'
+      // slurp word data
+      ostringstream d;
+      d << c;
       while (has_data(in)) {
         in >> c;
-        w << c;
+        d << c;
         if (c == '"') break;
       }
+      result.words.back().data = d.str();
+      // slurp metadata
+      ostringstream m;
+      while (!isspace(in.peek()) && has_data(in)) {
+        in >> c;
+        if (c == '/') {
+          if (!m.str().empty()) result.words.back().metadata.push_back(m.str());
+          m.str("");
+        }
+        else {
+          m << c;
+        }
+      }
+      if (!m.str().empty()) result.words.back().metadata.push_back(m.str());
     }
-    // slurp any remaining characters until whitespace
-    while (!isspace(in.peek()) && has_data(in)) {  // peek can sometimes trigger eof(), so do it first
-      in >> c;
+    else {
+      // slurp all characters until whitespace
+      ostringstream w;
       w << c;
+      while (!isspace(in.peek()) && has_data(in)) {  // peek can sometimes trigger eof(), so do it first
+        in >> c;
+        w << c;
+      }
+      parse_word(w.str(), result.words.back());
     }
-    result.words.push_back(word());
-    parse_word(w.str(), result.words.back());
     trace(99, "parse2") << "word: " << to_string(result.words.back()) << end();
   }
   if (!result.words.empty())
@@ -212,3 +234,9 @@ void test_parse2_string_with_metadata_at_end_of_line_without_newline() {
       "parse2: word: \"test\" /f"
   );
 }
+
+//: Make sure slashes inside strings don't trigger adding stuff from inside the
+//: string to metadata.
+:(scenario parse2_string_containing_slashes)
+a "bc/def"/disp32
++parse2: word: "bc/def" /disp32
vc@akkartik.com> 2016-10-23 19:18:50 -0700 3568' href='/akkartik/mu/commit/mu.vim?h=hlt&id=af7349d50c40e0604c9bb1e9a50aa1c3c0d407d8'>af7349d5 ^
a6d9bd9b ^
e3894819 ^
b38d7fff ^
9a81d746 ^
a6d9bd9b ^


9a81d746 ^
3e1349d2 ^
3e1349d2 ^
f918675c ^
650a201d ^
af7349d5 ^
3e1349d2 ^
af7349d5 ^
3e1349d2 ^


fbf0536d ^
7a4bf4cf ^
b38d7fff ^
e3894819 ^
f918675c ^


fc2046a1 ^
1ead3562 ^
38f0b91a ^
3e1349d2 ^



b38d7fff ^

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70