Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

compctl -L bug fixes



-----BEGIN PGP SIGNED MESSAGE-----

There are a couple of problems in various builtins relating to quoting
(or rather lack of quoting) of shell metacharacters.  For example:

% compctl -a 'a*command'
% compctl -L | grep command
compctl -a a*command

More seriously:

% compctl -a a%dnothercommand
% compctl -L | grep nother
compctl -a a-276919296nothercommand

(Yes, it's being passed as the first argument to printf().)

The patch below takes the innards of the alias-printing function, which
gets quoting right, and puts them in a new function.  This function is
then used by compctl and alias in appropriate places.  As well as
fixing the lack of quoting where it's needed, this also improves the
quoting in bits of compctl, where currently SQs are always used, even
when unnecessary and unsightly.

Btw, the reporter script is a little out of date.  It should be changed
to use compctl -L, which after this patch does everything that reporter
tries to do with the compctls.  It also doesn't need to fiddle with the
alias output, which is correctly quoted in the builtin.

 -zefram

      *** Src/builtin.c.old	Fri Jul  7 09:29:14 1995
      --- Src/builtin.c	Fri Jul  7 10:53:00 1995
      ***************
      *** 2455,2470 ****
        	    if (cclist & 1) {
        		printf("compctl ");
        		if (cc == &cc_compos)
      ! 		    printf("-C ");
        		if (cc == &cc_default)
      ! 		    printf("-D ");
         		if (cc == &cc_first)
         		    printf("-T");
      ! 	    } else 
      ! 		printf("%s ", s);
        	/* loop through flags w/o args that are set, printing them if so */
        	if (flags & t) {
      ! 	    putchar('-');
        	    if ((flags & (CC_ALREG | CC_ALGLOB)) == (CC_ALREG | CC_ALGLOB))
        		putchar('a'), flags &= ~(CC_ALREG | CC_ALGLOB);
        	    while (*css) {
      --- 2455,2470 ----
        	    if (cclist & 1) {
        		printf("compctl ");
        		if (cc == &cc_compos)
      ! 		    printf("-C");
        		if (cc == &cc_default)
      ! 		    printf("-D");
         		if (cc == &cc_first)
         		    printf("-T");
      ! 	    } else
      ! 		printquoted(s);
        	/* loop through flags w/o args that are set, printing them if so */
        	if (flags & t) {
      ! 	    printf(" -");
        	    if ((flags & (CC_ALREG | CC_ALGLOB)) == (CC_ALREG | CC_ALGLOB))
        		putchar('a'), flags &= ~(CC_ALREG | CC_ALGLOB);
        	    while (*css) {
      ***************
      *** 2474,2490 ****
        		flags >>= 1;
        		t >>= 1;
        	    }
      - 	    putchar(' ');
        	}
        	/* now flags with arguments */
        	flags = cc->mask;
      ! 	if (cc->keyvar)
      ! 	    if (*cc->keyvar == '(') {
      ! 		printf("-k \'");
      ! 		printqt(cc->keyvar);
      ! 		printf("\' ");
      ! 	    } else
      ! 		printf("-k %s ", cc->keyvar);
        	printif(cc->func, 'K');
        	printif(cc->explain, 'X');
        	printif(cc->prefix, 'P');
      --- 2474,2486 ----
        		flags >>= 1;
        		t >>= 1;
        	    }
        	}
        	/* now flags with arguments */
        	flags = cc->mask;
      ! 	if (cc->keyvar) {
      ! 	    printf(" -k ");
      ! 	    printquoted(cc->keyvar);
      ! 	}
        	printif(cc->func, 'K');
        	printif(cc->explain, 'X');
        	printif(cc->prefix, 'P');
      ***************
      *** 2493,2501 ****
        	printif(cc->str, 's');
        	printif(cc->subcmd, 'l');
        	if (cc->hpat) {
      ! 	    printf("-H %d \'", cc->hnum);
      ! 	    printqt(cc->hpat);
      ! 	    printf("\' ");
        	}
        	/* now the -x ... -- extended completion part */
        	if (cc->ext) {
      --- 2489,2496 ----
        	printif(cc->str, 's');
        	printif(cc->subcmd, 'l');
        	if (cc->hpat) {
      ! 	    printf(" -H %d ", cc->hnum);
      ! 	    printquoted(cc->hpat);
        	}
        	/* now the -x ... -- extended completion part */
        	if (cc->ext) {
      ***************
      *** 2503,2515 ****
        	    int i;
        
        	    cc2 = cc->ext;
      ! 	    printf("-x ");
        
        	    while (cc2) {
        		/* loop over conditions */
        		c = cc2->cond;
        
      ! 		putchar('\'');
        		for (c = cc2->cond; c;) {
        		    /* loop over or's */
        		    o = c->or;
      --- 2498,2510 ----
        	    int i;
        
        	    cc2 = cc->ext;
      ! 	    printf(" -x");
        
        	    while (cc2) {
        		/* loop over conditions */
        		c = cc2->cond;
        
      ! 		printf(" '");
        		for (c = cc2->cond; c;) {
        		    /* loop over or's */
        		    o = c->or;
      ***************
      *** 2547,2553 ****
        		    if ((c = o))
        			printf(" , ");
        		}
      ! 		printf("\' ");
        		c = cc2->cond;
        		cc2->cond = NULL;
        		/* now print the flags for the current condition */
      --- 2542,2548 ----
        		    if ((c = o))
        			printf(" , ");
        		}
      ! 		putchar('\'');
        		c = cc2->cond;
        		cc2->cond = NULL;
        		/* now print the flags for the current condition */
      ***************
      *** 2554,2573 ****
        		printcompctl((char *) NULL, cc2);
        		cc2->cond = c;
        		if ((cc2 = (Compctl) (cc2->next)))
      ! 		    printf("- ");
        	    }
        	    if (cclist & 1)
      ! 		printf("-- ");
        	}
        	if (cc && cc->xor) {
        	    /* print or'd (+) completions */
      ! 	    printf("+ ");
        	    if (cc->xor != &cc_default)
        		printcompctl((char *) NULL, cc->xor);
        	}
        	if (s) {
      ! 	    if (cclist & 1)
      ! 		printf(s);
        	    putchar('\n');
        	}
            }
      --- 2549,2570 ----
        		printcompctl((char *) NULL, cc2);
        		cc2->cond = c;
        		if ((cc2 = (Compctl) (cc2->next)))
      ! 		    printf(" -");
        	    }
        	    if (cclist & 1)
      ! 		printf(" --");
        	}
        	if (cc && cc->xor) {
        	    /* print or'd (+) completions */
      ! 	    printf(" +");
        	    if (cc->xor != &cc_default)
        		printcompctl((char *) NULL, cc->xor);
        	}
        	if (s) {
      ! 	    if (cclist & 1) {
      ! 		putchar(' ');
      ! 		printquoted(s);
      ! 	    }
        	    putchar('\n');
        	}
            }
      ***************
      *** 2585,2594 ****
        void
        printqt(char *str)
        {
      !     /* Print str, but turn any single quote into '\''. */
            for (; *str; str++)
        	if (*str == '\'')
      ! 	    printf("\'\\\'\'");
        	else
        	    putchar(*str);
        }
      --- 2582,2591 ----
        void
        printqt(char *str)
        {
      !     /* Print str, but turn any single quote into '\'' or ''. */
            for (; *str; str++)
        	if (*str == '\'')
      ! 	    printf(isset(RCQUOTES) ? "''" : "'\\''");
        	else
        	    putchar(*str);
        }
      ***************
      *** 2599,2607 ****
        {
            /* If flag c has an argument, print that */
            if (str) {
      ! 	printf("-%c \'", c);
      ! 	printqt(str);
      ! 	printf("\' ");
            }
        }
        
      --- 2596,2603 ----
        {
            /* If flag c has an argument, print that */
            if (str) {
      ! 	printf(" -%c ", c);
      ! 	printquoted(str);
            }
        }
        
      ***************
      *** 3947,3997 ****
        void
        printalias(char *s, Alias a)
        {
      -     char *ptr;
      -     int special = 0, inquote = 0;
      - 
            if (!showflag ||			/* single requested alias */
        	(showflag == 1 && !a->cmd) ||   /* global alias           */
        	(showflag == 2 && a->cmd)) {	/* regular alias          */
      ! 	/* check for special characters in the expansion text     */
      ! 	for (ptr = a->text; *ptr; ptr++)
      ! 	    if (ispecial(*ptr))
      ! 		special++;
      ! 	if (special) {
      ! 	    /* quote the replacement text, because of special characters */
      ! 	    if (isset(RCQUOTES)) {
      ! 		/* use rc-style quotes-within-quotes for the whole string */
      ! 		printf("%s=\'", s);
      ! 		for (ptr = a->text; *ptr; ptr++) {
      ! 		    if (*ptr == '\'')
      ! 			printf("\'\'");
      ! 		    else
      ! 			putchar(*ptr);
      ! 		}
      ! 		printf("\'\n");
      ! 	    } else {
      ! 		/* use Bourne-style quoting, avoiding empty quoted strings */
      ! 		printf("%s=", s);
      ! 		for (ptr = a->text; *ptr; ptr++) {
      ! 		    if (*ptr == '\'' && inquote) {
      ! 			printf("\'\\\'");
      ! 			inquote = 0;
      ! 		    } else if (*ptr == '\'')
      ! 			printf("\\\'");
      ! 		    else if (!inquote) {
      ! 			printf("\'%c",*ptr);
      ! 			inquote = 1;
      ! 		    } else
      ! 			putchar(*ptr);
      ! 		}
      ! 		if (inquote)
      ! 		    putchar('\'');
      ! 		putchar('\n');
      ! 	    }
      ! 	} else
      ! 	    /* no special characters */
      ! 	    printf("%s=%s\n", s, a->text);
      ! 	}
        }
        
        /**** resource limit builtins ****/
      --- 3943,3956 ----
        void
        printalias(char *s, Alias a)
        {
            if (!showflag ||			/* single requested alias */
        	(showflag == 1 && !a->cmd) ||   /* global alias           */
        	(showflag == 2 && a->cmd)) {	/* regular alias          */
      ! 	printquoted(s);
      ! 	putchar('=');
      ! 	printquoted(a->text);
      ! 	putchar('\n');
      !     }
        }
        
        /**** resource limit builtins ****/
      ***************
      *** 5890,5893 ****
      --- 5849,5908 ----
        {
            putchar(c);
            return 0;
      + }
      + 
      + /* Print a string, quoted if it contains special characters. */
      + 
      + /**/
      + void
      + printquoted(char *str)
      + {
      +     char *ptr;
      +     int special = 0, inquote = 0;
      + 
      +     /* check for empty string */
      +     if(!*str) {
      + 	printf("''");
      + 	return;
      +     }
      + 
      +     /* check for special characters in the string */
      +     for (ptr = str; *ptr; ptr++)
      + 	if (ispecial(*ptr)) {
      + 	    special=1;
      + 	    break;
      + 	}
      +     if(!special) {
      + 	/* no special characters at all */
      + 	printf("%s", str);
      + 	return;
      +     }
      + 
      +     if (isset(RCQUOTES)) {
      + 	/* use rc-style quotes-within-quotes for the whole string */
      + 	putchar('\'');
      + 	for (ptr = str; *ptr; ptr++) {
      + 	    if (*ptr == '\'')
      + 		printf("''");
      + 	    else
      + 		putchar(*ptr);
      + 	}
      + 	putchar('\'');
      +     } else {
      + 	/* use Bourne-style quoting, avoiding empty quoted strings */
      + 	for (ptr = str; *ptr; ptr++) {
      + 	    if (*ptr == '\'' && inquote) {
      + 		printf("'\\'");
      + 		inquote = 0;
      + 	    } else if (*ptr == '\'')
      + 		printf("\\'");
      + 	    else if (!inquote) {
      + 		printf("'%c",*ptr);
      + 		inquote = 1;
      + 	    } else
      + 		putchar(*ptr);
      + 	}
      + 	if (inquote)
      + 	    putchar('\'');
      +     }
        }

-----BEGIN PGP SIGNATURE-----
Version: 2.6.i

iQBVAgUBL/0IOWWJ8JfKi+e9AQEc+wH/br+2tNpMPNlmTi8bA5GduUNSB9QflD8+
yFQ5UNCgQiHdNBN71729W3/AMxnxywyPlNjbiIUuEppqoszB9Y+QJQ==
=Apvw
-----END PGP SIGNATURE-----



Messages sorted by: Reverse Date, Date, Thread, Author