9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
* [9fans] Acme: support spaces in file|dir names
@ 2023-02-20 16:06 adr
  2023-02-20 17:23 ` hiro
  0 siblings, 1 reply; 5+ messages in thread
From: adr @ 2023-02-20 16:06 UTC (permalink / raw)
  To: 9fans

[-- Attachment #1: Type: text/plain, Size: 7049 bytes --]

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

[-- Attachment #2: Type: text/plain, Size: 5251 bytes --]

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);

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2023-02-24 20:22 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-20 16:06 [9fans] Acme: support spaces in file|dir names adr
2023-02-20 17:23 ` hiro
2023-02-20 18:05   ` adr
2023-02-20 19:27     ` hiro
2023-02-24 20:21     ` Nicola Girardi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).