zsh-workers
 help / color / mirror / code / Atom feed
* PATCH: _a2ps (+ _long_options)
@ 1999-03-10 16:03 Sven Wischnowsky
  1999-03-10 17:28 ` PATCH: ${foo#* } Peter Stephenson
  0 siblings, 1 reply; 2+ messages in thread
From: Sven Wischnowsky @ 1999-03-10 16:03 UTC (permalink / raw)
  To: zsh-workers


I only wanted to improve the completion for `_a2ps' and then
discovered that matching as in `${foo#* }' is extremly slow if `foo'
contains lots of spaces. So much so, that I had to change
`_long_options' to make the changed `_a2ps' usable.

Try:

  % a=''
  % repeat 500 a="$a a"
  % echo "${a#* }"

If I remember correctly, Peter said something about performance when
cleaning up `getmatch()'.

Bye
 Sven

diff -u oc/User/_a2ps Completion/User/_a2ps
--- oc/User/_a2ps	Tue Mar  9 15:25:02 1999
+++ Completion/User/_a2ps	Wed Mar 10 15:59:43 1999
@@ -2,7 +2,38 @@
 
 # This is for the GNU version of a2ps.
 
-_long_options -t '*\*'         '(yes no)' \
-                 '*=DIRECTION' '(rows columns)' \
-                 '*=TYPE'      '(r n nr rn any)' ||
+if [[ "$words[1]" != "$_a2ps_cache_cmd" ]]; then
+  local descr
+
+  _a2ps_cache_cmd="$words[1]"
+
+  descr=( "${(@)${(f@)$($words[1] --list=features)//
+ /	}:#}" )
+
+  _a2ps_cache_values=(
+      "${descr[(r)Known style sheets*]#*	}"
+      "${descr[(r)Known encodings*]#*	}"
+      "${descr[(r)Known media*]#*	}"
+      "${descr[(r)Known prologues*]#*	}"
+      "${descr[(r)Known PostScript Printer Descriptions*]#*	}"
+      "${descr[(r)Known output destination*]#*	}"
+      "${descr[(r)Known user options*]#*	}"
+      "${descr[(r)Known Variables*]#*	}"
+  )
+fi
+
+_long_options -t '*\*'                '(yes no)' \
+                 '*=DIRECTION'        '(rows columns)' \
+                 '*=TYPE'             '(r n nr rn any)' \
+		 '--highlight-level*' '(none normal heavy)' \
+		 '--version-control*' '(none off t numbered nil 
+		                        existing never simple)' \
+	         '--pretty-print*'    "[${_a2ps_cache_values[1]}]" \
+	         '--encoding*'        "(${_a2ps_cache_values[2]})" \
+	         '--medium*'          "[${_a2ps_cache_values[3]}]" \
+	         '--prologue*'        "[${_a2ps_cache_values[4]}]" \
+	         '--ppd*'             "[${_a2ps_cache_values[5]}]" \
+	         '--printer*'         "[${_a2ps_cache_values[6]}]" \
+	         '--user-option*'     "[${_a2ps_cache_values[7]}]" \
+	         '--variable*'        "[${_a2ps_cache_values[8]}]" ||
     _files -F fignore -g '*~*.(ps|PS|eps|EPS)'
diff -u oc/User/_long_options Completion/User/_long_options
--- oc/User/_long_options	Tue Mar  9 15:25:04 1999
+++ Completion/User/_long_options	Wed Mar 10 16:52:49 1999
@@ -71,7 +71,7 @@
   # No, store the new command name and clear the old parameters.
 
   _lo_cache_cmd="$tmp"
-  (( $+_lo_cache_actions )) && unset ${_lo_cache_actions%% *} _lo_cache_actions
+  (( $+_lo_cache_actions )) && unset "$_lo_cache_names[@]" _lo_cache_actions _lo_cache_names
 
   local opts pattern anum=1 tmpo str
 
@@ -119,9 +119,8 @@
     # argument is optional. The name of the array built contains
     # `_arg_' for mandatory arguments, `_optarg_' for optional
     # arguments, and `_simple_' for options that don't get an
-    # argument. In `_lo_cache_actions' we save the names of these
-    # arrays together with the associated action (Separated by a
-    # space).
+    # argument. In `_lo_cache_names' we save the names of these
+    # arrays and in `_lo_cache_actions' the associated actions.
 
     # If the action is a list of words in brackets, this denotes
     # options that get an optional argument. If the action is a list
@@ -145,7 +144,8 @@
 
         tmp=("${(@)tmp:#*\[\=*}")
         tmpo=("${(@)${(@)tmpo%%\=*}//[^a-z0-9-]}")
-        _lo_cache_actions[anum]="_lo_cache_optarg_$anum $action"
+        _lo_cache_names[anum]="_lo_cache_optarg_$anum"
+        _lo_cache_actions[anum]="$action"
         eval "_lo_cache_optarg_${anum}=(\"\$tmpo[@]\")"
 	(( anum++ ))
       fi
@@ -157,7 +157,8 @@
       if (( $#tmpo )); then
         tmp=("${(@)tmp:#*\=*}")
         tmpo=("${(@)${(@)tmpo%%\=*}//[^a-z0-9-]}")
-        _lo_cache_actions[anum]="_lo_cache_arg_$anum $action"
+        _lo_cache_names[anum]="_lo_cache_arg_$anum"
+        _lo_cache_actions[anum]="$action"
         eval "_lo_cache_arg_${anum}=(\"\$tmpo[@]\")"
 	(( anum++ ))
       fi
@@ -171,7 +172,8 @@
 
     tmp=("${(@)${(@)tmp%%\=*}//[^a-z0-9-]}")
     if (( $#tmp )); then
-      _lo_cache_actions[anum]="$name $action"
+      _lo_cache_names[anum]="$name"
+      _lo_cache_actions[anum]="$action"
       eval "${name}=(\"\$tmp[@]\")"
       (( anum++ ))
     fi
@@ -188,7 +190,7 @@
   # It contains a `=', now we ignore anything up to it, but first save 
   # the old contents of the special parameters we change.
 
-  local oipre opre osuf pre parto parta pat patflags
+  local oipre opre osuf pre parto parta pat patflags anum=1
 
   oipre="$IPREFIX"
   opre="$PREFIX"
@@ -212,9 +214,8 @@
   # with the name. If the action is a list of words, we just add them, 
   # otherwise we invoke the command or function named.
 
-  for i in "$_lo_cache_actions[@]"; do
-    name="${i%% *}"
-    action="${i#* }"
+  for name in "$_lo_cache_names[@]"; do
+    action="$_lo_cache_actions[anum]"
     if (( ${(@)${(@P)name}[(I)$pre]} )); then
       if [[ "$action[1]" = (\[|\() ]]; then
         compadd - ${=action[2,-2]}
@@ -237,28 +238,27 @@
     if [[ $#tmp -eq 1 ]]; then
       if [[ -z "$parto" ]]; then
         parto="$tmp[1]"
-	parta="$i"
+	parta="$action"
       else
         parto=-
       fi
     elif (( $#tmp )); then
       parto=-
     fi
+    (( anum++ ))
   done
 
   # If we found only one matching option, we accept it and immediatly
   # try to complete the string after the `='.
 
   if [[ -n "$parto" && "$parto" != - ]]; then
-    name="${parta%% *}"
-    action="${parta#* }"
     IPREFIX="${parto}="
 
-    if (( $#action )); then
-      if [[ "$action[1]" = (\[|\() ]]; then
-        compadd - ${=action[2,-2]}
+    if (( $#parta )); then
+      if [[ "$parta[1]" = (\[|\() ]]; then
+        compadd - ${=parta[2,-2]}
       else
-        $=action
+        $=parta
       fi
     else
       compadd -S '' - "$PREFIX"
@@ -287,9 +287,9 @@
   suffix=('-S=')
 fi
 
-for i in "$_lo_cache_actions[@]"; do
-  name="${i%% *}"
-  action="${i#* }"
+anum=1
+for name in "$_lo_cache_names[@]"; do
+  action="$_lo_cache_actions[anum]"
 
   if [[ "$name" = *_optarg_* ]]; then
     compadd -M 'r:|-=* r:|=*' -Qq "$suffix[@]" -s "$str" - \
@@ -301,6 +301,7 @@
     compadd -M 'r:|-=* r:|=*' -Q - \
             "${(@P)name}" && ret=0
   fi
+  (( anum++ ))
 done
 
 return ret

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


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

* PATCH: ${foo#* }
  1999-03-10 16:03 PATCH: _a2ps (+ _long_options) Sven Wischnowsky
@ 1999-03-10 17:28 ` Peter Stephenson
  0 siblings, 0 replies; 2+ messages in thread
From: Peter Stephenson @ 1999-03-10 17:28 UTC (permalink / raw)
  To: zsh-workers

Sven Wischnowsky wrote:
> I only wanted to improve the completion for `_a2ps' and then
> discovered that matching as in `${foo#* }' is extremly slow if `foo'
> contains lots of spaces. So much so, that I had to change
> `_long_options' to make the changed `_a2ps' usable.
> 
> Try:
> 
>   % a=''
>   % repeat 500 a="$a a"
>   % echo "${a#* }"
> 
> If I remember correctly, Peter said something about performance when
> cleaning up `getmatch()'.

There were two ways of doing this; I picked the one assuming that the
quickest way was to start from the longest match and shorten, which in this
case is obviously wrong.

The adaption below is still a compromise.  The reason is that the way the
pattern matcher works makes it easy to get the longest match, but you
always have to get the shortest by brute force; so if the pattern doesn't
match at all, it can be slow to get the shortest match, since it has to try
the entire string (though this is not a problem in the example here).  In
this version, the longest match is still always found first, but the
shortest is then found by gradually lengthening the string towards that.
Maybe this will keep everyone happy.  It certainly ought to be OK for
spaces in normal text, where they occur frequently.

--- Src/glob.c.short	Mon Mar  1 10:45:43 1999
+++ Src/glob.c	Wed Mar 10 18:15:24 1999
@@ -2304,26 +2304,25 @@
     case SUB_LONG:
 	/*
 	 * Largest/smallest possible match at head of string.
-	 * First get the longest match.
+	 * First get the longest match...
 	 */
 	if (dolongestmatch(s, c, 0)) {
 	    char *mpos = pptr;
-	    while (!(fl & SUB_LONG) && pptr > s) {
-		/*
-		 * If we want the shortest, keep backing up to the
-		 * previous character and find the longest up to there.
-		 * That way we can usually reach the shortest in only
-		 * a few attempts.
-		 */
-		t = (pptr > s + 1 && pptr[-2] == Meta) ? pptr - 2 : pptr -1;
+	    if (!(fl & SUB_LONG)) {
+	      /*
+	       * ... now we know whether it's worth looking for the
+	       * shortest, which we do by brute force.
+	       */
+	      for (t = s; t < mpos; METAINC(t)) {
 		sav = *t;
 		*t = '\0';
-		if (!dolongestmatch(s, c, 0)) {
-		    *t = sav;
-		    break;
+		if (dolongestmatch(s, c, 0)) {
+		  mpos = pptr;
+		  *t = sav;
+		  break;
 		}
-		mpos = pptr;
 		*t = sav;
+	      }
 	    }
 	    *sp = get_match_ret(*sp, 0, mpos-s, fl, replstr);
 	    return 1;

-- 
Peter Stephenson <pws@ibmth.df.unipi.it>       Tel: +39 050 844536
WWW:  http://www.ifh.de/~pws/
Dipartimento di Fisica, Via Buonarroti 2, 56127 Pisa, Italy


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

end of thread, other threads:[~1999-03-10 17:46 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-03-10 16:03 PATCH: _a2ps (+ _long_options) Sven Wischnowsky
1999-03-10 17:28 ` PATCH: ${foo#* } Peter Stephenson

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