From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from gatech.edu (gatech.edu [130.207.244.244]) by werple.mira.net.au (8.6.12/8.6.9) with SMTP id UAA03642 for ; Fri, 7 Jul 1995 20:24:40 +1000 Received: from math (math.skiles.gatech.edu) by gatech.edu with SMTP id AA20029 (5.65c/Gatech-10.0-IDA for ); Fri, 7 Jul 1995 06:24:02 -0400 Received: by math (5.x/SMI-SVR4) id AA21610; Fri, 7 Jul 1995 06:20:38 -0400 Resent-Date: Fri, 7 Jul 1995 11:21:28 +0100 (BST) Old-Return-Path: From: Zefram Message-Id: <19744.199507071021@stone.dcs.warwick.ac.uk> Subject: compctl -L bug fixes To: zsh-workers@math.gatech.edu (Z Shell workers mailing list) Date: Fri, 7 Jul 1995 11:21:28 +0100 (BST) X-Loop: zefram@dcs.warwick.ac.uk X-Stardate: [-31]5942.15 Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Resent-Message-Id: <"T3I94.0.aH5.rfG_l"@math> Resent-From: zsh-workers@math.gatech.edu X-Mailing-List: archive/latest/170 X-Loop: zsh-workers@math.gatech.edu Precedence: list Resent-Sender: zsh-workers-request@math.gatech.edu -----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-----