commit:     35d7272b07fbbdc21c13b963e042aaf62481430a
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Thu May  2 15:46:37 2019 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Thu May  2 15:46:37 2019 +0000
URL:        https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=35d7272b

libq/cache: implement escape processing in cache_read_file_ebuild

- replace escapes (\\ -> \, \" -> ")
- replace line-continuation escape+nl by space

Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>

 TODO.md      |  6 ++----
 libq/cache.c | 36 +++++++++++++++++++++++++-----------
 2 files changed, 27 insertions(+), 15 deletions(-)

diff --git a/TODO.md b/TODO.md
index 3a3c26a..9d44710 100644
--- a/TODO.md
+++ b/TODO.md
@@ -11,14 +11,14 @@
 - multiline reads don't yet work for quse/qsearch
 
 - standardize/unify/clean up misc handling of colors
+  define rules:
+    BOLD CATEGORY/ BLUE PKG GREEN ::REPO NORM [ MAGENTA USE NORM ]
 
 - remove odd rmspace for each string in libq/set.c (allows a lot less
   malloc/frees)
 
 - make set.c to array (xarray) instead of C-array (list)
 
-- equiv of `equery m` (metadata)
-
 - env vars only get expanded once, so this fails:<br>
   `ACCEPT_LICENSE="foo"`<br>
   `ACCEPT_LICENSE="${ACCEPT_LICENSE} bar"`<br>
@@ -30,8 +30,6 @@
 
 - vdb repo/slot think about when it is freed (see cache\_pkg\_close)
 
-- cache:cache\_read\_file\_ebuild deal with \\\\n sequences
-
 - qcache -> rename to qkeyword
 
 - quse -K -> move to qkeyword

diff --git a/libq/cache.c b/libq/cache.c
index ee3a47c..9993002 100644
--- a/libq/cache.c
+++ b/libq/cache.c
@@ -370,8 +370,9 @@ cache_read_file_ebuild(cache_pkg_ctx *pkg_ctx)
        size_t len;
        char *p;
        char *q;
-       char *r;
+       char *w;
        char **key;
+       bool esc;
        bool findnl;
 
        if ((f = fdopen(pkg_ctx->fd, "r")) == NULL)
@@ -422,22 +423,35 @@ cache_read_file_ebuild(cache_pkg_ctx *pkg_ctx)
                        if (*q == '"' || *q == '\'') {
                                /* find matching quote */
                                p++;
+                               w = p;
+                               esc = false;
                                do {
-                                       while (*p != '\0' && *p != *q)
-                                               p++;
-                                       if (*p == *q) {
-                                               for (r = p - 1; r > q; r--)
-                                                       if (*r != '\\')
-                                                               break;
-                                               if (r != q && (p - 1 - r) % 2 
== 1) {
-                                                       /* escaped, move along 
*/
-                                                       p++;
-                                                       continue;
+                                       while (*p != '\0' && *p != *q) {
+                                               if (*p == '\\') {
+                                                       esc = !esc;
+                                                       if (esc) {
+                                                               p++;
+                                                               continue;
+                                                       }
+                                               } else {
+                                                       /* implement line 
continuation (\ before newline) */
+                                                       if (esc && (*p == '\n' 
|| *p == '\r'))
+                                                               *p = ' ';
+                                                       esc = false;
                                                }
+
+                                               *w++ = *p++;
+                                       }
+                                       if (*p == *q && esc) {
+                                               /* escaped, move along */
+                                               esc = false;
+                                               *w++ = *p++;
+                                               continue;
                                        }
                                        break;
                                } while (1);
                                q++;
+                               *w = '\0';
                        } else {
                                /* find first whitespace */
                                while (!isspace((int)*p))

Reply via email to