From 2028f82cbc982baab42388d85e8e1861626b47e7 Mon Sep 17 00:00:00 2001
From: Per Hedbor <ph@opera.com>
Date: Mon, 21 Jul 2014 13:54:49 +0200
Subject: [PATCH] Added a new string syntax

They will all start and end a literal string.

A literal string can contain any characters except the end sequence.

The main usecase is writing code in a string.

As an example:

string test = #{
This is a literal string.
They can contain any characters, no de-quoting is done at all.

So, as an example, foo "bar" 'gazonk' \

Valid quote sequences are #{, #( and #[.
They are ended by # followed by }, ) and ], respectively.

So, you can use the two other quotes inside the string, if you want to, like:

Also, no preprocessing is done inside the string.

The main usecase for these strings is to write code in code.
---
 src/cpp.c          | 15 +++++++++++++++
 src/preprocessor.h | 12 +++++++++---
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/src/cpp.c b/src/cpp.c
index b3bc819b3d..581249b9b3 100644
--- a/src/cpp.c
+++ b/src/cpp.c
@@ -1130,6 +1130,20 @@ static ptrdiff_t readstring( struct cpp *this, const PCHARP data, ptrdiff_t len,
   return pos;
 }
 
+static ptrdiff_t readstring_lit( struct cpp *this, const PCHARP data, ptrdiff_t len, ptrdiff_t pos,
+			     struct string_builder*nf, INT32 ec)
+{
+  INT32 ch;
+  while(1)
+    if(++pos>=len)
+      cpp_error(this,"End of file in string.");
+    else if((ch=INDEX_PCHARP(data,pos)) == '#' && INDEX_PCHARP(data,pos+1)==ec)
+        return pos + 2;
+    else
+        string_builder_putchar(nf, ch);
+  return pos;
+}
+
 static ptrdiff_t fixstring(struct cpp *this, const PCHARP data, ptrdiff_t len,
 			   ptrdiff_t pos, struct string_builder *nf, int outp)
 {
@@ -1989,6 +2003,7 @@ static void free_one_define(struct hash_entry *h)
  */
 #define READSTRING(nf) (pos=readstring(this,data,len,pos,&nf,0))
 #define READSTRING2(nf) (pos=readstring(this,data,len,pos,&nf,1))
+#define READSTRING3(nf,ec) (pos=readstring_lit(this,data,len,pos,&nf,ec))
 #define FIXSTRING(nf,outp) (pos=fixstring(this,data,len,pos,&nf,outp))
 
 /* Gobble an identifier at the current position. */
diff --git a/src/preprocessor.h b/src/preprocessor.h
index f713d22b9c..2e9760978a 100644
--- a/src/preprocessor.h
+++ b/src/preprocessor.h
@@ -564,13 +564,19 @@ static ptrdiff_t low_cpp(struct cpp *this,
           case '"':
             {
               struct string_builder nf;
+              char end;
               init_string_builder(&nf, 0);
-
               READSTRING2(nf);
+              goto stringout;
+          case '(': end = ')'; goto litstring;
+          case '[': end = ']'; goto litstring;
+          case '{': end = '}';
+            litstring:
+              init_string_builder(&nf, 0);
+              READSTRING3(nf,end);
+            stringout:
               if(OUTP())
-              {
                 PUSH_STRING_SHIFT(nf.s->str, nf.s->len,nf.s->size_shift, &this->buf);
-              }
               free_string_builder(&nf);
               break;
             }
-- 
GitLab