Hi,

this patch adds code from p9p to support spaces in file or dir
names. I use the 9front version because it has been mantained, but
there are more fixes in p9p to be imported.

adr
diff -Nur /n/9front/sys/src/cmd/acme/fns.h /sys/src/cmd/acme/fns.h
--- /n/9front/sys/src/cmd/acme/fns.h    Mon Jul 11 20:01:08 2022
+++ /sys/src/cmd/acme/fns.h     Mon Feb 20 15:23:42 2023
@@ -90,6 +90,7 @@
 void          flushwarnings(void);
 long  nlcount(Text*, long, long, long*);
 long  nlcounttopos(Text*, long, long, long);
+Rune*  parsetag(Window*, int, int*);

 #define       runemalloc(a)           (Rune*)emalloc((a)*sizeof(Rune))
 #define       runerealloc(a, b)       (Rune*)erealloc((a), (b)*sizeof(Rune))
diff -Nur /n/9front/sys/src/cmd/acme/look.c /sys/src/cmd/acme/look.c
--- /n/9front/sys/src/cmd/acme/look.c   Mon Jul 11 20:01:08 2022
+++ /sys/src/cmd/acme/look.c    Mon Feb 20 15:47:24 2023
@@ -397,9 +397,9 @@
 Runestr
 dirname(Text *t, Rune *r, int n)
 {
-       Rune *b, c;
-       uint m, nt;
-       int slash;
+       Rune *b;
+       uint nt;
+       int slash, i;
       Runestr tmp;

       b = nil;
@@ -410,15 +410,13 @@
               goto Rescue;
       if(n>=1 && r[0]=='/')
               goto Rescue;
-       b = runemalloc(nt+n+1);
-       bufread(t->w->tag.file, 0, b, nt);
+       b = parsetag(t->w, n, &i);
       slash = -1;
-       for(m=0; m<nt; m++){
-               c = b[m];
-               if(c == '/')
-                       slash = m;
-               if(c==' ' || c=='\t')
+       for(i--; i >= 0; i--){
+               if(b[i] == '/'){
+                       slash = i;
                       break;
+               }
       }
       if(slash < 0)
               goto Rescue;
@@ -502,7 +500,7 @@
       if(nname == -1)
               nname = n;
       for(i=0; i<nname; i++)
-               if(!isfilec(r[i]))
+               if(!isfilec(r[i]) && r[i] != ' ')
                       goto Isntfile;
       /*
        * See if it's a file name in <>, and turn that into an include
diff -Nur /n/9front/sys/src/cmd/acme/wind.c /sys/src/cmd/acme/wind.c
--- /n/9front/sys/src/cmd/acme/wind.c   Mon Jul 11 20:01:08 2022
+++ /sys/src/cmd/acme/wind.c    Mon Feb 20 15:20:37 2023
@@ -109,14 +109,26 @@
       return rr - r;
 }

+int
+delrunepos(Window *w)
+{
+       Rune *r;
+       int i;
+
+       r = parsetag(w, 0, &i);
+       free(r);
+       i += 2;
+       if(i >= w->tag.file->nc)
+               return -1;
+       return i;
+}
+
 void
 movetodel(Window *w)
 {
       int n;
- - n = tagrunepos(w, delcmd);
-       free(delcmd);
-       delcmd = nil;
+
+       n = delrunepos(w);
       if(n < 0)
               return;
       moveto(mousectl, addpt(frptofchar(&w->tag, n), Pt(4, 
w->tag.font->height-4)));
@@ -141,7 +153,7 @@

       if(!w->tagexpand) {
               /* use just as many lines as needed to show the Del */
-               n = tagrunepos(w, delcmd);
+               n = delrunepos(w);
               if(n < 0)
                       return 1;
               p = subpt(frptofchar(&w->tag, n), w->tag.r.min);
@@ -412,11 +424,7 @@

       /* w must be committed */
       n = w->tag.file->nc;
-       r = runemalloc(n);
-       bufread(w->tag.file, 0, r, n);
-       for(i=0; i<n; i++)
-               if(r[i]==' ' || r[i]=='\t')
-                       break;
+       r = parsetag(w, 0, &i);
       for(; i<n; i++)
               if(r[i] == '|')
                       break;
@@ -433,6 +441,38 @@
       textsetselect(&w->tag, w->tag.q0, w->tag.q1);
 }

+Rune*
+parsetag(Window *w, int extra, int *len)
+{
+       static Rune Ldelsnarf[] = { ' ', 'D', 'e', 'l', ' ', 'S', 'n', 'a', 
'r', 'f', 0 };
+       static Rune Lspacepipe[] = { ' ', '|', 0 };
+       static Rune Ltabpipe[] = { '\t', '|', 0 };
+       int i;
+       Rune *r, *p, *pipe;
+
+       r = runemalloc(w->tag.file->nc+extra+1);
+       bufread(w->tag.file, 0, r, w->tag.file->nc);
+       r[w->tag.file->nc] = '\0';
+
+       /*
+        * " |" or "\t|" ends left half of tag
+        * If we find " Del Snarf" in the left half of the tag
+        * (before the pipe), that ends the file name.
+        */
+       pipe = runestrstr(r, Lspacepipe);
+       if((p = runestrstr(r, Ltabpipe)) != nil && (pipe == nil || p < pipe))
+               pipe = p;
+       if((p = runestrstr(r, Ldelsnarf)) != nil && (pipe == nil || p < pipe))
+               i = p - r;
+       else {
+               for(i=0; i<w->tag.file->nc; i++)
+                       if(r[i]==' ' || r[i]=='\t')
+                               break;
+       }
+       *len = i;
+       return r;
+}
+
 void
 winsettag1(Window *w)
 {
@@ -445,12 +485,7 @@
       /* there are races that get us here with stuff in the tag cache, so we 
take extra care to sync it */
       if(w->tag.ncache!=0 || w->tag.file->mod)
               wincommit(w, &w->tag);  /* check file name; also guarantees we 
can modify tag contents */
-       old = runemalloc(w->tag.file->nc+1);
-       bufread(w->tag.file, 0, old, w->tag.file->nc);
-       old[w->tag.file->nc] = '\0';
-       for(i=0; i<w->tag.file->nc; i++)
-               if(old[i]==' ' || old[i]=='\t')
-                       break;
+       old = parsetag(w, 0, &i);
       if(runeeq(old, i, w->body.file->name, w->body.file->nname) == FALSE){
               textdelete(&w->tag, 0, i, TRUE);
               textinsert(&w->tag, 0, w->body.file->name, w->body.file->nname, 
TRUE);
@@ -458,7 +493,6 @@
               old = runemalloc(w->tag.file->nc+1);
               bufread(w->tag.file, 0, old, w->tag.file->nc);
               old[w->tag.file->nc] = '\0';
-               w->tagsafe = FALSE;
       }
       new = runemalloc(w->body.file->nname+100);
       i = 0;
@@ -572,11 +606,7 @@
                       textcommit(f->text[i], FALSE);  /* no-op for t */
       if(t->what == Body)
               return;
-       r = runemalloc(w->tag.file->nc);
-       bufread(w->tag.file, 0, r, w->tag.file->nc);
-       for(i=0; i<w->tag.file->nc; i++)
-               if(r[i]==' ' || r[i]=='\t')
-                       break;
+       r = parsetag(w, 0, &i);
       if(runeeq(r, i, w->body.file->name, w->body.file->nname) == FALSE){
               seq++;
               filemark(w->body.file);
@@ -611,11 +641,11 @@
               r = runerealloc(r, n+1);
               r[n] = 0;
       }
+       free(a);
       if((d->qid.type&QTDIR) == 0){
               free(d);
               warning(nil, "%s: not a directory\n", a);
               free(r);
-               free(a);
               return;
       }
       free(a);
------------------------------------------
9fans: 9fans
Permalink: 
https://9fans.topicbox.com/groups/9fans/Tc1d9d9ca3a94e285-M502a002b31fde997a5913efb
Delivery options: https://9fans.topicbox.com/groups/9fans/subscription
diff -Nur /n/9front/sys/src/cmd/acme/fns.h /sys/src/cmd/acme/fns.h
--- /n/9front/sys/src/cmd/acme/fns.h    Mon Jul 11 20:01:08 2022
+++ /sys/src/cmd/acme/fns.h     Mon Feb 20 15:23:42 2023
@@ -90,6 +90,7 @@
 void           flushwarnings(void);
 long   nlcount(Text*, long, long, long*);
 long   nlcounttopos(Text*, long, long, long);
+Rune*  parsetag(Window*, int, int*);
 
 #define        runemalloc(a)           (Rune*)emalloc((a)*sizeof(Rune))
 #define        runerealloc(a, b)       (Rune*)erealloc((a), (b)*sizeof(Rune))
diff -Nur /n/9front/sys/src/cmd/acme/look.c /sys/src/cmd/acme/look.c
--- /n/9front/sys/src/cmd/acme/look.c   Mon Jul 11 20:01:08 2022
+++ /sys/src/cmd/acme/look.c    Mon Feb 20 15:47:24 2023
@@ -397,9 +397,9 @@
 Runestr
 dirname(Text *t, Rune *r, int n)
 {
-       Rune *b, c;
-       uint m, nt;
-       int slash;
+       Rune *b;
+       uint nt;
+       int slash, i;
        Runestr tmp;
 
        b = nil;
@@ -410,15 +410,13 @@
                goto Rescue;
        if(n>=1 && r[0]=='/')
                goto Rescue;
-       b = runemalloc(nt+n+1);
-       bufread(t->w->tag.file, 0, b, nt);
+       b = parsetag(t->w, n, &i);
        slash = -1;
-       for(m=0; m<nt; m++){
-               c = b[m];
-               if(c == '/')
-                       slash = m;
-               if(c==' ' || c=='\t')
+       for(i--; i >= 0; i--){
+               if(b[i] == '/'){
+                       slash = i;
                        break;
+               }
        }
        if(slash < 0)
                goto Rescue;
@@ -502,7 +500,7 @@
        if(nname == -1)
                nname = n;
        for(i=0; i<nname; i++)
-               if(!isfilec(r[i]))
+               if(!isfilec(r[i]) && r[i] != ' ')
                        goto Isntfile;
        /*
         * See if it's a file name in <>, and turn that into an include
diff -Nur /n/9front/sys/src/cmd/acme/wind.c /sys/src/cmd/acme/wind.c
--- /n/9front/sys/src/cmd/acme/wind.c   Mon Jul 11 20:01:08 2022
+++ /sys/src/cmd/acme/wind.c    Mon Feb 20 15:20:37 2023
@@ -109,14 +109,26 @@
        return rr - r;
 }
 
+int
+delrunepos(Window *w)
+{
+       Rune *r;
+       int i;
+
+       r = parsetag(w, 0, &i);
+       free(r);
+       i += 2;
+       if(i >= w->tag.file->nc)
+               return -1;
+       return i;
+}
+
 void
 movetodel(Window *w)
 {
        int n;
-       
-       n = tagrunepos(w, delcmd);
-       free(delcmd);
-       delcmd = nil;
+
+       n = delrunepos(w);
        if(n < 0)
                return;
        moveto(mousectl, addpt(frptofchar(&w->tag, n), Pt(4, 
w->tag.font->height-4)));
@@ -141,7 +153,7 @@
        
        if(!w->tagexpand) {
                /* use just as many lines as needed to show the Del */
-               n = tagrunepos(w, delcmd);
+               n = delrunepos(w);
                if(n < 0)
                        return 1;
                p = subpt(frptofchar(&w->tag, n), w->tag.r.min);
@@ -412,11 +424,7 @@
 
        /* w must be committed */
        n = w->tag.file->nc;
-       r = runemalloc(n);
-       bufread(w->tag.file, 0, r, n);
-       for(i=0; i<n; i++)
-               if(r[i]==' ' || r[i]=='\t')
-                       break;
+       r = parsetag(w, 0, &i);
        for(; i<n; i++)
                if(r[i] == '|')
                        break;
@@ -433,6 +441,38 @@
        textsetselect(&w->tag, w->tag.q0, w->tag.q1);
 }
 
+Rune*
+parsetag(Window *w, int extra, int *len)
+{
+       static Rune Ldelsnarf[] = { ' ', 'D', 'e', 'l', ' ', 'S', 'n', 'a', 
'r', 'f', 0 };
+       static Rune Lspacepipe[] = { ' ', '|', 0 };
+       static Rune Ltabpipe[] = { '\t', '|', 0 };
+       int i;
+       Rune *r, *p, *pipe;
+
+       r = runemalloc(w->tag.file->nc+extra+1);
+       bufread(w->tag.file, 0, r, w->tag.file->nc);
+       r[w->tag.file->nc] = '\0';
+
+       /*
+        * " |" or "\t|" ends left half of tag
+        * If we find " Del Snarf" in the left half of the tag
+        * (before the pipe), that ends the file name.
+        */
+       pipe = runestrstr(r, Lspacepipe);
+       if((p = runestrstr(r, Ltabpipe)) != nil && (pipe == nil || p < pipe))
+               pipe = p;
+       if((p = runestrstr(r, Ldelsnarf)) != nil && (pipe == nil || p < pipe))
+               i = p - r;
+       else {
+               for(i=0; i<w->tag.file->nc; i++)
+                       if(r[i]==' ' || r[i]=='\t')
+                               break;
+       }
+       *len = i;
+       return r;
+}
+
 void
 winsettag1(Window *w)
 {
@@ -445,12 +485,7 @@
        /* there are races that get us here with stuff in the tag cache, so we 
take extra care to sync it */
        if(w->tag.ncache!=0 || w->tag.file->mod)
                wincommit(w, &w->tag);  /* check file name; also guarantees we 
can modify tag contents */
-       old = runemalloc(w->tag.file->nc+1);
-       bufread(w->tag.file, 0, old, w->tag.file->nc);
-       old[w->tag.file->nc] = '\0';
-       for(i=0; i<w->tag.file->nc; i++)
-               if(old[i]==' ' || old[i]=='\t')
-                       break;
+       old = parsetag(w, 0, &i);
        if(runeeq(old, i, w->body.file->name, w->body.file->nname) == FALSE){
                textdelete(&w->tag, 0, i, TRUE);
                textinsert(&w->tag, 0, w->body.file->name, w->body.file->nname, 
TRUE);
@@ -458,7 +493,6 @@
                old = runemalloc(w->tag.file->nc+1);
                bufread(w->tag.file, 0, old, w->tag.file->nc);
                old[w->tag.file->nc] = '\0';
-               w->tagsafe = FALSE;
        }
        new = runemalloc(w->body.file->nname+100);
        i = 0;
@@ -572,11 +606,7 @@
                        textcommit(f->text[i], FALSE);  /* no-op for t */
        if(t->what == Body)
                return;
-       r = runemalloc(w->tag.file->nc);
-       bufread(w->tag.file, 0, r, w->tag.file->nc);
-       for(i=0; i<w->tag.file->nc; i++)
-               if(r[i]==' ' || r[i]=='\t')
-                       break;
+       r = parsetag(w, 0, &i);
        if(runeeq(r, i, w->body.file->name, w->body.file->nname) == FALSE){
                seq++;
                filemark(w->body.file);
@@ -611,11 +641,11 @@
                r = runerealloc(r, n+1);
                r[n] = 0;
        }
+       free(a);
        if((d->qid.type&QTDIR) == 0){
                free(d);
                warning(nil, "%s: not a directory\n", a);
                free(r);
-               free(a);
                return;
        }
        free(a);

Reply via email to