zsh-workers
 help / color / mirror / code / Atom feed
* RE: PATCH: files and paths and...
@ 2000-06-28  8:43 Sven Wischnowsky
  0 siblings, 0 replies; 5+ messages in thread
From: Sven Wischnowsky @ 2000-06-28  8:43 UTC (permalink / raw)
  To: zsh-workers


Andrej Borsenkow wrote:

> ...
> 
> So, what is needed to support it is
> 
> - add backslash as path seprator to _path_files

I don't think I'll even try to do this... all that quoting could get
very ugly.

> - _path_files should recognize 'x:\' as "root".

I would have expected some help for how to detect if we are on cygwin
then ;-)

> Hmm ... there seems to be one more problem. Zsh can glob 'c:/Progr*' to
> 'c:/Program Files' but not 'c:\Progr*'. It seems, that it needs more
> deep support; globbing code should recognize '\' as valid path separator
> as well.

See above. Did Amol's port do this? I guess it did...

> Oh, yes, and NT has case-insensitive file system, that means, globbing
> should be case-insensitive by default as well.

Hm. For non-_match completion this is simple and I don't think I'll
try to change the C-code for _match to support this.


And all this for some rotten Microsoft thing. Ick.

Bye
 Sven


--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


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

* RE: PATCH: files and paths and...
  2000-06-19 13:22 Sven Wischnowsky
@ 2000-06-28  8:25 ` Andrej Borsenkow
  0 siblings, 0 replies; 5+ messages in thread
From: Andrej Borsenkow @ 2000-06-28  8:25 UTC (permalink / raw)
  To: Sven Wischnowsky, zsh-workers


> > and even
> >
> > d:\path\to\file (assuming proper quoting on shell level)
> >
> > as well. E.g. d:/temp is completely valid. Currently Zsh
> cannot complete
> > it:
>
> Of course, it can. We only need someone who writes it.
>
> Hm. I guess it understands that everywhere, yes? Not only in words
> starting with `?:/'. Otherwise someone could write something
> in _first
> to call `_files -W ...' if the current word starts with that.
>
> If it understand this in `-foo=d:/...', then we need support in
> _path_files, but that would be possible (stuff it into prepath, etc
> etc...). But only when on cygwin, of course, probably only if the
> style support-cygwin(-s-rotten-paths-urgh) is set.
>

Yes. It understand it for any file name. You can even mix for-and
back-slashes:

mw1g017@MW1G17C:/cygdrive/d/temp/zsh% dd if='d:\temp/zsh\zsh.html'
of=foo
2184+1 records in
2184+1 records out


So, what is needed to support it is

- add backslash as path seprator to _path_files
- _path_files should recognize 'x:\' as "root".

Hmm ... there seems to be one more problem. Zsh can glob 'c:/Progr*' to
'c:/Program Files' but not 'c:\Progr*'. It seems, that it needs more
deep support; globbing code should recognize '\' as valid path separator
as well.

Oh, yes, and NT has case-insensitive file system, that means, globbing
should be case-insensitive by default as well.

-andrej


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

* RE: PATCH: files and paths and...
@ 2000-06-19 13:22 Sven Wischnowsky
  2000-06-28  8:25 ` Andrej Borsenkow
  0 siblings, 1 reply; 5+ messages in thread
From: Sven Wischnowsky @ 2000-06-19 13:22 UTC (permalink / raw)
  To: zsh-workers


Andrej Borsenkow wrote:

> >   zstyle '*:files' fake '/:cygdrive' '/cygdrive:a b c...'
> >
> > Does that work?
> 
> Yes, but I personally prefer combination of
> 
> mw1g017@MW1G17C:/usr/build/zsh/Test% zstyle '*:files' accept-exact
> '/cygdrive/?((#e)|/*)'
> mw1g017@MW1G17C:/usr/build/zsh/Test% zstyle '*:files' fake /:cygdrive
> 
> to avoid listing all drives (that is the whole sense of using /cygdrive
> at all - else I could just mount them). It means, that we may complete
> non-existent drive - but there is really nothing to do about it unless
> some way to list all drives exist.
> 
> BTW as I found out, Cygwin allows you to use
> 
> <DRIVE>:/path/to/file
> 
> and even
> 
> d:\path\to\file (assuming proper quoting on shell level)
> 
> as well. E.g. d:/temp is completely valid. Currently Zsh cannot complete
> it:

Of course, it can. We only need someone who writes it.

Hm. I guess it understands that everywhere, yes? Not only in words
starting with `?:/'. Otherwise someone could write something in _first 
to call `_files -W ...' if the current word starts with that.

If it understand this in `-foo=d:/...', then we need support in
_path_files, but that would be possible (stuff it into prepath, etc
etc...). But only when on cygwin, of course, probably only if the
style support-cygwin(-s-rotten-paths-urgh) is set.

> ls d:/tTAB gives nothing. Sigh ... but probably we should move this
> discussion to zsh-users (to find out, just how useful it is at all).

Yes. The other stuff might be useful elsewhere. I've no idea how many
(poor) people (are forced to) use cygwin?


Bye
 Sven


--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


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

* RE: PATCH: files and paths and...
  2000-06-19  9:29 Sven Wischnowsky
@ 2000-06-19 12:46 ` Andrej Borsenkow
  0 siblings, 0 replies; 5+ messages in thread
From: Andrej Borsenkow @ 2000-06-19 12:46 UTC (permalink / raw)
  To: Sven Wischnowsky, zsh-workers


>
>   zstyle '*:files' fake '/:cygdrive' '/cygdrive:a b c...'
>
> Does that work?
>

Yes, but I personally prefer combination of

mw1g017@MW1G17C:/usr/build/zsh/Test% zstyle '*:files' accept-exact
'/cygdrive/?((#e)|/*)'
mw1g017@MW1G17C:/usr/build/zsh/Test% zstyle '*:files' fake /:cygdrive

to avoid listing all drives (that is the whole sense of using /cygdrive
at all - else I could just mount them). It means, that we may complete
non-existent drive - but there is really nothing to do about it unless
some way to list all drives exist.

BTW as I found out, Cygwin allows you to use

<DRIVE>:/path/to/file

and even

d:\path\to\file (assuming proper quoting on shell level)

as well. E.g. d:/temp is completely valid. Currently Zsh cannot complete
it:

ls d:/tTAB gives nothing. Sigh ... but probably we should move this
discussion to zsh-users (to find out, just how useful it is at all). One
way is to use cygpath utility that converts between DOS/Unix:

mw1g017@MW1G17C:/usr/build/zsh/Test% cygpath
Usage: cygpath [-p|--path] (-u|--unix)|(-w|--windows) filename
  -a|--absolute         output absolute path
  -c|--close handle     close handle (for use in captured process)
  -f|--file file        read file for path information
  -u|--unix             print Unix form of filename
  -w|--windows          print Windows form of filename
  -W|--windir           print `Windows' directory
  -S|--sysdir           print `system' directory
  -p|--path             filename argument is a path
mw1g017@MW1G17C:/usr/build/zsh/Test% cygpath -u d:/temp
/cygdrive/d/temp
mw1g017@MW1G17C:/usr/build/zsh/Test% cygpath -u d:\\temp
/cygdrive/d/temp
mw1g017@MW1G17C:/usr/build/zsh/Test% cygpath -w /usr

-andrej


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

* PATCH: files and paths and...
@ 2000-06-19  9:29 Sven Wischnowsky
  2000-06-19 12:46 ` Andrej Borsenkow
  0 siblings, 1 reply; 5+ messages in thread
From: Sven Wischnowsky @ 2000-06-19  9:29 UTC (permalink / raw)
  To: zsh-workers


I'm trying to group my patches... this one's for _path_files and
friends.


Tanaka Akira wrote:

> Accidentaly, I found that zsh dumps core as follows.
> 
> Z(2):akr@flux% Src/zsh -f
> flux% bindkey -e; autoload -U compinit; compinit -D; compdef _tst tst
> flux% _tst() { _files -g -/ }
> flux% zstyle ':completion:*' ignored-patterns '*'
> flux% tst -<TAB>
> zsh: segmentation fault (core dumped)  Src/zsh -f
> Z(2):akr@flux% 
> 
> Note that I couldn't get proper backtrace.

Missing initialisation for a string buffer when adding zero-length
matches.


The other things we were discussing:

Peter Stephenson wrote:

> Andrej wrote:
> > Even if
> > we cannot find out all drives (is it possible?) _path_files still has to
> > treat /cygdrive/?/ specially, and not try to glob it. It can also always
> > offer ``cygdrive'' for the first component (of course, if it matches
> > current prefix/suffix).
> 
> Sven will have to answer for the feasibility of all of this, but...
> 
> One thing that might fit our needs here and elsewhere (e.g. speedups of
> path completion when you know you don't want initial path components
> re-jigged) is a style along the lines of fix-path-prefix, only maybe with a
> better name.  A number would fix that many components (`2', here), while
> something else e.g. `all' would turn off completion of earlier bits of the
> path altogether.  A more generic `fix-prefix' might possibly be useful in
> certain other completions.

I decided that this is really an accept-exact thingy, applied to
in-path completion. Good idea? I mean... it really *is* about
accepting prefix paths if they exist, i.e. if there are exact matches.

So, the patch enhances the accept-exact style to take not only boolean 
values, but also patterns, BUT ONLY when looked up with the `files'
tag. When one of the patterns matches the path typed so far and there
are such directories, _path_files will not try to glob them. The
change below this is, of course, that _path_files now looks up the
accept-exact style at all. One thing I couldn't decide is if
_path_files should use the setting of REC_EXACT, too. Currently it
doesn't, because if the style isn't set, but REC_EXACT is, that would
mean to behave as if the style were set to `true' and then _path_files 
would skip all fully typed paths, so that if there is `foobar/yyy',
and `foo/xxx', completing `foo/y<TAB>' would not complete to
`foobar/yyy'. It's easy to make it use REC_EXACT, though. Should we?

The foo/foobar thing is the example I used to say that we can't always 
accept path prefixes, so the patch takes it back, or, more precisely,
replaces it with that accep-exact thing.

Then there is the other thing:

> While this may be useful, I meant something different. I'd prefer if
> /c/d/t would still complete to /cygdrive/d/temp. I meant, that
> _path_files (BTW I agree that it already deserves to be converted to
> shell code. It may even give old compctl the ability to complete paths)

I suggested adding a way to `fake' matches and the patch adds the
`fake' style (is that a good name? I used a rather generic name
because there may be other places where something like this might
become useful). It's values are of the form `dir:names...', which
means that when completing inside directory `dir', completion will
also complete to the `names'. So, if I got that cygwin stuff right,
one could do:

  zstyle '*:files' fake '/:cygdrive' '/cygdrive:a b c...'

Does that work?

I haven't yet tried to use this mechanism to automatically complete
automounted directories, but I think this would be a nice use. This
should probably be detected and done automatically, I think.


And then the patch also contains the optimisations I already talked
about but had forgotten to include in the patches I committed.

Bye
 Sven

Index: Completion/Core/_path_files
===================================================================
RCS file: /cvsroot/zsh/zsh/Completion/Core/_path_files,v
retrieving revision 1.21
diff -u -r1.21 _path_files
--- Completion/Core/_path_files	2000/06/13 09:05:37	1.21
+++ Completion/Core/_path_files	2000/06/19 09:28:41
@@ -6,7 +6,7 @@
 local linepath realpath donepath prepath testpath exppath skips skipped
 local tmp1 tmp2 tmp3 tmp4 i orig eorig pre suf tpre tsuf opre osuf cpre
 local pats haspats ignore pfxsfx sopt gopt opt sdirs ignpar cfopt
-local nm=$compstate[nmatches] menu matcher mopts sort match mid
+local nm=$compstate[nmatches] menu matcher mopts sort match mid accex fake
 
 typeset -U prepaths exppaths
 
@@ -139,12 +139,14 @@
   skips='((.|..)/)##'
 fi
 
-zstyle -s ":completion:${curcontext}:paths" special-dirs sdirs &&
-    [[ "$sdirs" = (yes|true|on|1) ]] && sdirs=yes
+zstyle -s ":completion:${curcontext}:paths" special-dirs sdirs
 
 [[ "$pats" = ((|*[[:blank:]])\*(|[[:blank:]]*)|*\([^[:blank:]]#/[^[:blank:]]#\)*) ]] &&
     sopt=$sopt/
 
+zstyle -a ":completion:${curcontext}:files" accept-exact accex
+zstyle -a ":completion:${curcontext}:files" fake fake
+
 zstyle -s ":completion:${curcontext}:files" ignore-parents ignpar
 
 if [[ -n "$compstate[pattern_match]" &&
@@ -314,33 +316,33 @@
     # Get the matching files by globbing.
 
     if [[ "$tpre$tsuf" = */* ]]; then
-      compfiles -P$cfopt tmp1 "$skipped" "$_matcher" "$sdirs"
+      compfiles -P$cfopt tmp1 accex "$skipped" "$_matcher" "$sdirs" fake
     elif [[ "$sopt" = *[/f]* ]]; then
-      compfiles -p$cfopt tmp1 "$skipped" "$_matcher" "$sdirs" "$pats[@]"
+      compfiles -p$cfopt tmp1 accex "$skipped" "$_matcher" "$sdirs" fake "$pats[@]"
     else
-      compfiles -p$cfopt tmp1 "$skipped" "$_matcher" '' "$pats[@]"
+      compfiles -p$cfopt tmp1 accex "$skipped" "$_matcher" '' fake "$pats[@]"
     fi
     tmp1=( $~tmp1 )
 
     if [[ -n "$PREFIX$SUFFIX" ]]; then
       # See which of them match what's on the line.
 
-      if [[ -n "$_comp_correct" ]]; then
-        tmp2=( "$tmp1[@]" )
-        builtin compadd -D tmp1 -F _comp_ignore "$matcher[@]" - "${(@)tmp1:t}"
-
-        if [[ $#tmp1 -eq 0 ]]; then
-          tmp1=( "$tmp2[@]" )
-	  compadd -D tmp1 -F _comp_ignore "$matcher[@]" - "${(@)tmp2:t}"
-        fi
-      else
-        if [[ "$tmp1[1]" = */* ]]; then
+      if [[ "$tmp1[1]" = */* ]]; then
+        if [[ -n "$_comp_correct" ]]; then
           tmp2=( "$tmp1[@]" )
+          builtin compadd -D tmp1 -F _comp_ignore "$matcher[@]" - "${(@)tmp1:t}"
+
+          if [[ $#tmp1 -eq 0 ]]; then
+            tmp1=( "$tmp2[@]" )
+	    compadd -D tmp1 -F _comp_ignore "$matcher[@]" - "${(@)tmp2:t}"
+          fi
         else
-          tmp2=( '' )
+          tmp2=( "$tmp1[@]" )
+          compadd -D tmp1 -F _comp_ignore "$matcher[@]" - "${(@)tmp1:t}"
         fi
-
-        compadd -D tmp1 -F _comp_ignore "$matcher[@]" - "${(@)tmp1:t}"
+      else
+        tmp2=( '' )
+        compadd -D tmp1 -F _comp_ignore "$matcher[@]" -a tmp1
       fi
 
       # If no file matches, save the expanded path and continue with
@@ -431,26 +433,18 @@
   tmp3="$pre$suf"
   tpre="$pre"
   tsuf="$suf"
-  tmp1=( "${(@)tmp1#${prepath}${realpath}${testpath}}" )
+  [[ -n "${prepath}${realpath}${testpath}" ]] &&
+      tmp1=( "${(@)tmp1#${prepath}${realpath}${testpath}}" )
 
   while true; do
 
     # First we check if some of the files match the original string
     # for this component. If there are some we remove all other
     # names. This avoids having `foo' complete to `foo' and `foobar'.
-
-    if [[ "$tmp3" = */* ]]; then
-      tmp4=( "${(@M)tmp1:#${tmp3%%/*}/*}" )
-      (( $#tmp4 )) && tmp1=( "$tmp4[@]" )
-    fi
+    # The return value is non-zero if the component is ambiguous.
 
-    # Next we see if this component is ambiguous.
-
-    if [[ "$tmp3" = */* ]]; then
-       tmp4=$tmp1[(I)^${${tmp1[1]%%/*}//(#b)([][\\<>(|)^#~*?])/\\$match[1]}/*]
-    else
-       tmp4=$tmp1[(I)^${tmp1[1]//(#b)([][\\<>(|)^#~*?])/\\$match[1]}]
-    fi
+    compfiles -r tmp1 "$tmp3"
+    tmp4=$?
 
     if [[ "$tpre" = */* ]]; then
       tmp2="${cpre}${tpre%%/*}"
Index: Doc/Zsh/compsys.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/compsys.yo,v
retrieving revision 1.68
diff -u -r1.68 compsys.yo
--- Doc/Zsh/compsys.yo	2000/06/19 08:47:44	1.68
+++ Doc/Zsh/compsys.yo	2000/06/19 09:28:43
@@ -780,6 +780,13 @@
 same as the string on the line, this match will immediately be
 accepted.
 
+When completing filenames (where it is looked up for the tt(files)
+tag), this style also accepts any number of patterns as the value. If
+this is used, pathnames matching one of these patterns will be
+accepted immediately even if the command line contains some more
+partially typed pathname components and these match no file under the
+directory accepted.
+
 Note that this is also used by the tt(_expand) completer to decide if
 words beginning with a tilde or parameter expansion should be
 expanded. This means that if, for example, there are parameters
@@ -967,6 +974,17 @@
 generated this way (e.g. due to the option tt(AUTO_MENU) being set),
 this will also cycle through the names of the files in pathname
 components after the first ambiguous one.
+)
+kindex(fake, completion style)
+item(tt(fake))(
+Currently, this style is only used when completing files and lookup up 
+with the tag tt(files).  Its values are of the form
+`var(dir)tt(:)var(names...)'.  This will add the var(names) as
+possible matches when completing in the directory var(dir), even if no 
+such files really exist.
+
+This can be useful on systems that support special filesystems whose
+top-level pathnames can not be listed or generated with glob patterns.
 )
 kindex(file-patterns, completion style)
 item(tt(file-patterns))(
Index: Src/Zle/compcore.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/compcore.c,v
retrieving revision 1.31
diff -u -r1.31 compcore.c
--- Src/Zle/compcore.c	2000/06/09 11:14:34	1.31
+++ Src/Zle/compcore.c	2000/06/19 09:28:44
@@ -1914,8 +1914,8 @@
 	    if (aign || pign) {
 		int il = ppl + sl + psl, addit = 1;
 
-		if (il > ilen)
-		    ibuf = (char *) zhalloc((ilen = il) + 1);
+		if (il + 1> ilen)
+		    ibuf = (char *) zhalloc((ilen = il) + 2);
 
 		if (ppl)
 		    memcpy(ibuf, dat->ppre, ppl);
Index: Src/Zle/computil.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/computil.c,v
retrieving revision 1.30
diff -u -r1.30 computil.c
--- Src/Zle/computil.c	2000/06/15 08:09:09	1.30
+++ Src/Zle/computil.c	2000/06/19 09:28:45
@@ -3058,17 +3058,37 @@
 #define PATH_MAX2 (PATH_MAX * 2)
 
 static LinkList
-cfp_test_exact(LinkList names, char *skipped)
+cfp_test_exact(LinkList names, char **accept, char *skipped)
 {
     char buf[PATH_MAX2 + 1], *suf, *p;
     int l, sl, found = 0;
     struct stat st;
     LinkNode node;
-    LinkList ret = newlinklist();
+    LinkList ret = newlinklist(), alist = NULL;
 
-    if (!(compprefix && *compprefix) && !(compsuffix && *compsuffix))
+    if ((!(compprefix && *compprefix) && !(compsuffix && *compsuffix)) ||
+	(!accept || !*accept ||
+	 ((!strcmp(*accept, "false") || !strcmp(*accept, "no") ||
+	   !strcmp(*accept, "off") || !strcmp(*accept, "0")) && !accept[1])))
 	return NULL;
 
+    if (accept[1] ||
+	(strcmp(*accept, "true") && strcmp(*accept, "yes") &&
+	 strcmp(*accept, "on") && strcmp(*accept, "1"))) {
+	Patprog prog;
+
+	alist = newlinklist();
+
+	for (; (p = *accept); accept++) {
+	    if (*p == '*' && !p[1]) {
+		alist = NULL;
+		break;
+	    }
+	    tokenize(p = dupstring(p));
+	    if ((prog = patcompile(p, 0, NULL)))
+		addlinknode(alist, prog);
+	}
+    }
     sl = strlen(skipped) + (compprefix ? strlen(compprefix) : 0) +
 	(compsuffix ? strlen(compsuffix) : 0);
 
@@ -3078,11 +3098,22 @@
     suf = dyncat(skipped, rembslash(dyncat(compprefix, compsuffix)));
 
     for (node = firstnode(names); node; incnode(node)) {
-	if ((l = strlen(p = (char *) getdata(node))) && l + sl < PATH_MAX2) {
+	l = strlen(p = (char *) getdata(node));
+	if (l + sl < PATH_MAX2) {
 	    strcpy(buf, p);
 	    strcpy(buf + l, suf);
+
+	    if (!ztat(buf, &st, 0)) {
+		if (alist) {
+		    LinkNode anode;
 
-	    if (!ztat(buf, &st, 0) && S_ISDIR(st.st_mode)) {
+		    for (anode = firstnode(alist); anode; incnode(anode))
+			if (pattry((Patprog) getdata(anode), buf))
+			    break;
+
+		    if (!anode)
+			continue;
+		}
 		found = 1;
 		addlinknode(ret, dupstring(buf));
 	    }
@@ -3334,12 +3365,14 @@
 }
 
 static LinkList
-cfp_add_sdirs(LinkList final, LinkList orig, char *skipped, char *sdirs)
+cfp_add_sdirs(LinkList final, LinkList orig, char *skipped,
+	      char *sdirs, char **fake)
 {
     int add = 0;
 
-    if (*sdirs) {
-	if (!strcmp(sdirs, "yes"))
+    if (*sdirs && (isset(GLOBDOTS) || (compprefix && *compprefix == '.'))) {
+	if (!strcmp(sdirs, "yes") || !strcmp(sdirs, "true") ||
+	    !strcmp(sdirs, "on") || !strcmp(sdirs, "1"))
 	    add = 2;
 	else if (!strcmp(sdirs, ".."))
 	    add = 1;
@@ -3350,25 +3383,77 @@
 	char *s2 = (add == 2 ? dyncat(skipped, ".") : NULL), *m;
 
 	for (node = firstnode(orig); node; incnode(node)) {
-	    if (*(m = (char *) getdata(node))) {
-		addlinknode(final, dyncat((char *) getdata(node), s1));
+	    if ((m = (char *) getdata(node))) {
+		addlinknode(final, dyncat(m, s1));
 		if (s2)
-		    addlinknode(final, dyncat((char *) getdata(node), s2));
+		    addlinknode(final, dyncat(m, s2));
 	    }
 	}
     }
+    if (fake && *fake) {
+	LinkNode node;
+	char *m, *f, *p, *t, *a, c;
+	int sl = strlen(skipped) + 1;
+	struct stat st1, st2;
+
+	for (; (f = *fake); fake++) {
+	    f = dupstring(f);
+	    for (p = t = f; *p; p++) {
+		if (*p == ':')
+		    break;
+		else if (*p == '\\' && p[1])
+		    p++;
+		*t++ = *p;
+	    }
+	    if (*p) {
+		*t = *p++ = '\0';
+		if (!*p)
+		    continue;
+
+		for (node = firstnode(orig); node; incnode(node)) {
+		    if ((m = (char *) getdata(node)) &&
+			(!strcmp(f, m) ||
+			 (!stat(f, &st1) && !stat((*m ? m : "."), &st2) &&
+			  st1.st_dev == st2.st_dev &&
+			  st1.st_ino == st2.st_ino))) {
+			while (*p) {
+			    while (*p && inblank(*p))
+				p++;
+			    if (!*p)
+				break;
+			    for (f = t = p; *p; p++) {
+				if (inblank(*p))
+				    break;
+				else if (*p == '\\' && p[1])
+				    p++;
+				*t++ = *p;
+			    }
+			    c = *t;
+			    *t = '\0';
+			    a = (char *) zhalloc(strlen(m) + sl + strlen(f));
+			    strcpy(a, m);
+			    strcat(a, skipped);
+			    strcat(a, f);
+			    addlinknode(final, a);
+			    *t = c;
+			}
+		    }
+		}
+	    }
+	}
+    }
     return final;
 }
 
 static LinkList
-cf_pats(int dirs, int noopt, LinkList names, char *skipped, char *matcher,
-	char *sdirs, char **pats)
+cf_pats(int dirs, int noopt, LinkList names, char **accept, char *skipped,
+	char *matcher, char *sdirs, char **fake, char **pats)
 {
     LinkList ret;
     char *dpats[2];
 
-    if (dirs && (ret = cfp_test_exact(names, skipped)))
-	return cfp_add_sdirs(ret, names, skipped, sdirs);
+    if ((ret = cfp_test_exact(names, accept, skipped)))
+	return cfp_add_sdirs(ret, names, skipped, sdirs, fake);
 
     if (dirs) {
 	dpats[0] = "*(-/)";
@@ -3379,7 +3464,7 @@
 	cfp_opt_pats(pats, matcher);
 
     return cfp_add_sdirs(cfp_bld_pats(dirs, names, skipped, pats),
-			 names, skipped, sdirs);
+			 names, skipped, sdirs, fake);
 }
 
 static void
@@ -3421,6 +3506,61 @@
     }
 }
 
+static LinkList
+cf_remove_other(char **names, char *pre, int *amb)
+{
+    char *p;
+
+    if ((p = strchr(pre, '/'))) {
+	char **n;
+
+	*p = '\0';
+	pre = dyncat(pre, "/");
+	*p = '/';
+
+	for (n = names; *n; n++)
+	    if (strpfx(pre, *n))
+		break;
+
+	if (*n) {
+	    LinkList ret = newlinklist();
+
+	    for (; *names; names++)
+		if (strpfx(pre, *names))
+		    addlinknode(ret, dupstring(*names));
+
+	    *amb = 0;
+
+	    return ret;
+	} else {
+	    if (!(p = *names++))
+		*amb = 0;
+	    else {
+		char *q;
+
+		if ((q = strchr((p = dupstring(p)), '/')))
+		    *q = '\0';
+
+		for (; *names; names++)
+		    if (!strpfx(p, *names)) {
+			*amb = 1;
+			return NULL;
+		    }
+	    }
+	}
+    } else {
+	if (!(p = *names++))
+	    *amb = 0;
+	else
+	    for (; *names; names++)
+		if (strcmp(p, *names)) {
+		    *amb = 1;
+		    return NULL;
+		}
+    }
+    return NULL;
+}
+
 static int
 bin_compfiles(char *nam, char **args, char *ops, int func)
 {
@@ -3438,8 +3578,8 @@
 	    char **tmp;
 	    LinkList l;
 
-	    if (!args[1] || !args[2] || !args[3] || !args[4] ||
-		(args[0][1] == 'p' && !args[5])) {
+	    if (!args[1] || !args[2] || !args[3] || !args[4] || !args[5] ||
+		!args[6] || (args[0][1] == 'p' && !args[7])) {
 		zwarnnam(nam, "too few arguments", NULL, 0);
 		return 1;
 	    }
@@ -3450,8 +3590,9 @@
 	    for (l = newlinklist(); *tmp; tmp++)
 		addlinknode(l, *tmp);
 	    set_list_array(args[1], cf_pats((args[0][1] == 'P'), !!args[0][2],
-					    l, args[2], args[3], args[4],
-					    args + 5));
+					    l, getaparam(args[2]), args[3],
+					    args[4], args[5],
+					    getaparam(args[6]), args + 7));
 	    return 0;
 	}
     case 'i':
@@ -3482,6 +3623,28 @@
 	    cf_ignore(tmp, l, args[3], args[4]);
 	    set_list_array(args[2], l);
 	    return 0;
+	}
+    case 'r':
+	{
+	    char **tmp;
+	    LinkList l;
+	    int ret = 0;
+
+	    if (!args[1] || !args[2]) {
+		zwarnnam(nam, "too few arguments", NULL, 0);
+		return 1;
+	    }
+	    if (args[3]) {
+		zwarnnam(nam, "too many arguments", NULL, 0);
+		return 1;
+	    }
+	    if (!(tmp = getaparam(args[1]))) {
+		zwarnnam(nam, "unknown parameter: %s", args[1], 0);
+		return 0;
+	    }
+	    if ((l = cf_remove_other(tmp, args[2], &ret)))
+		set_list_array(args[1], l);
+	    return ret;
 	}
     }
     zwarnnam(nam, "invalid option: %s", *args, 0);

--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


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

end of thread, other threads:[~2000-06-28  8:43 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-06-28  8:43 PATCH: files and paths and Sven Wischnowsky
  -- strict thread matches above, loose matches on Subject: below --
2000-06-19 13:22 Sven Wischnowsky
2000-06-28  8:25 ` Andrej Borsenkow
2000-06-19  9:29 Sven Wischnowsky
2000-06-19 12:46 ` Andrej Borsenkow

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

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