Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/make make: clean up eat_dots for meta mode, part 2



details:   https://anonhg.NetBSD.org/src/rev/0c123597e72f
branches:  trunk
changeset: 359831:0c123597e72f
user:      rillig <rillig%NetBSD.org@localhost>
date:      Wed Jan 26 12:41:26 2022 +0000

description:
make: clean up eat_dots for meta mode, part 2

At least on OpenBSD, "If the src and dst strings overlap, the behavior
is undefined" (since 2013-09-25), so rather use memmove instead.

Keep all other bugs for now, for example "/a/b//../" is reduced to
"/a/b/" instead of the correct "/a/", and for repeated "/././././" in
long paths, the performance is quadratic instead of linear.

Inline the two calls to eat_dots, turning the first into a two-liner.

diffstat:

 usr.bin/make/meta.c |  39 ++++++++++++++++++---------------------
 1 files changed, 18 insertions(+), 21 deletions(-)

diffs (63 lines):

diff -r 97391fb26a24 -r 0c123597e72f usr.bin/make/meta.c
--- a/usr.bin/make/meta.c       Wed Jan 26 12:16:03 2022 +0000
+++ b/usr.bin/make/meta.c       Wed Jan 26 12:41:26 2022 +0000
@@ -1,4 +1,4 @@
-/*      $NetBSD: meta.c,v 1.193 2022/01/26 12:16:03 rillig Exp $ */
+/*      $NetBSD: meta.c,v 1.194 2022/01/26 12:41:26 rillig Exp $ */
 
 /*
  * Implement 'meta' mode.
@@ -205,27 +205,25 @@
  * we use this, to clean up ./ and ../
  */
 static void
-eat_dots(char *buf, size_t bufsz, const char *eat, size_t eatlen)
+eat_dots(char *buf)
 {
-    char *cp;
-    char *cp2;
+    char *p;
+
+    while ((p = strstr(buf, "/./")) != NULL)
+       memmove(p, p + 2, strlen(p + 2) + 1);
 
-    do {
-       cp = strstr(buf, eat);
-       if (cp != NULL) {
-           cp2 = cp + eatlen;
-           if (eatlen == 3 && cp > buf) {
-               do {
-                   cp--;
-               } while (cp > buf && *cp != '/');
-           }
-           if (*cp == '/') {
-               strlcpy(cp, cp2, bufsz - (size_t)(cp - buf));
-           } else {
-               return;                 /* can't happen? */
-           }
+    while ((p = strstr(buf, "/../")) != NULL) {
+       char *p2 = p + 3;
+       if (p > buf) {
+           do {
+               p--;
+           } while (p > buf && *p != '/');
        }
-    } while (cp != NULL);
+       if (*p == '/')
+           memmove(p, p2, strlen(p2) + 1);
+       else
+           return;             /* can't happen? */
+    }
 }
 
 static char *
@@ -269,8 +267,7 @@
            } else {
                snprintf(buf, sizeof buf, "%s/%s", cwd, tname);
            }
-           eat_dots(buf, sizeof buf, "/./", 2);
-           eat_dots(buf, sizeof buf, "/../", 3);
+           eat_dots(buf);
            tname = buf;
        }
     }



Home | Main Index | Thread Index | Old Index