static int bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func)) { struct cadata dat; char *p, **sp, *e, *m = NULL, *mstr = NULL; int dm; Cmatcher match = NULL; if (incompfunc != 1) { zwarnnam(name, "can only be called from completion function"); return 1; } dat.ipre = dat.isuf = dat.ppre = dat.psuf = dat.prpre = dat.mesg = dat.pre = dat.suf = dat.group = dat.rems = dat.remf = dat.disp = dat.ign = dat.exp = dat.apar = dat.opar = dat.dpar = NULL; dat.match = NULL; dat.flags = 0; dat.aflags = CAF_MATCH; dat.dummies = 0; for (; *argv && **argv == '-'; argv++) { if (!(*argv)[1]) { argv++; break; } for (p = *argv + 1; *p; p++) { sp = NULL; e = NULL; dm = 0; switch (*p) { case 'q': dat.flags |= CMF_REMOVE; break; case 'Q': dat.aflags |= CAF_QUOTE; break; case 'C': dat.aflags |= CAF_ALL; break; case 'f': dat.flags |= CMF_FILE; break; case 'e': dat.flags |= CMF_ISPAR; break; case 'a': dat.aflags |= CAF_ARRAYS; break; case 'k': dat.aflags |= CAF_ARRAYS|CAF_KEYS; break; case 'F': sp = &(dat.ign); e = "string expected after -%c"; break; case 'n': dat.flags |= CMF_NOLIST; break; case 'U': dat.aflags &= ~CAF_MATCH; break; case 'P': sp = &(dat.pre); e = "string expected after -%c"; break; case 'S': sp = &(dat.suf); e = "string expected after -%c"; break; case 'J': sp = &(dat.group); e = "group name expected after -%c"; break; case 'V': if (!dat.group) dat.aflags |= CAF_NOSORT; sp = &(dat.group); e = "group name expected after -%c"; break; case '1': if (!(dat.aflags & CAF_UNIQCON)) dat.aflags |= CAF_UNIQALL; break; case '2': if (!(dat.aflags & CAF_UNIQALL)) dat.aflags |= CAF_UNIQCON; break; case 'i': sp = &(dat.ipre); e = "string expected after -%c"; break; case 'I': sp = &(dat.isuf); e = "string expected after -%c"; break; case 'p': sp = &(dat.ppre); e = "string expected after -%c"; break; case 's': sp = &(dat.psuf); e = "string expected after -%c"; break; case 'W': sp = &(dat.prpre); e = "string expected after -%c"; break; case 'M': sp = &m; e = "matching specification expected after -%c"; dm = 1; break; case 'X': sp = &(dat.exp); e = "string expected after -%c"; break; case 'x': sp = &(dat.mesg); e = "string expected after -%c"; break; case 'r': dat.flags |= CMF_REMOVE; sp = &(dat.rems); e = "string expected after -%c"; break; case 'R': dat.flags |= CMF_REMOVE; sp = &(dat.remf); e = "function name expected after -%c"; break; case 'A': sp = &(dat.apar); e = "parameter name expected after -%c"; break; case 'O': sp = &(dat.opar); e = "parameter name expected after -%c"; break; case 'D': sp = &(dat.dpar); e = "parameter name expected after -%c"; break; case 'd': sp = &(dat.disp); e = "parameter name expected after -%c"; break; case 'l': dat.flags |= CMF_DISPLINE; break; case 'o': dat.flags |= CMF_MORDER; break; case 'E': if (p[1]) { dat.dummies = atoi(p + 1); p = "" - 1; } else if (argv[1]) { argv++; dat.dummies = atoi(*argv); p = "" - 1; } else { zwarnnam(name, "number expected after -%c", *p); zsfree(mstr); return 1; } if (dat.dummies < 0) { zwarnnam(name, "invalid number: %d", dat.dummies); zsfree(mstr); return 1; } break; case '-': argv++; goto ca_args; default: zwarnnam(name, "bad option: -%c", *p); zsfree(mstr); return 1; } if (sp) { if (p[1]) { if (!*sp) *sp = p + 1; p = "" - 1; } else if (argv[1]) { argv++; if (!*sp) *sp = *argv; p = "" - 1; } else { zwarnnam(name, e, *p); zsfree(mstr); return 1; } if (dm) { if (mstr) { char *tmp = tricat(mstr, " ", m); zsfree(mstr); mstr = tmp; } else mstr = ztrdup(m); m = NULL; } } } } ca_args: if (mstr && (match = parse_cmatcher(name, mstr)) == pcm_err) { zsfree(mstr); return 1; } zsfree(mstr); if (!*argv && !dat.group && !dat.mesg && !(dat.aflags & (CAF_NOSORT|CAF_UNIQALL|CAF_UNIQCON|CAF_ALL))) return 1; dat.match = match = cpcmatcher(match); dm = addmatches(&dat, argv); freecmatcher(match); return dm; }
static int bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func)) { struct cadata dat; char *mstr = NULL; /* argument of -M options, accumulated */ int added; /* return value */ Cmatcher match = NULL; if (incompfunc != 1) { zwarnnam(name, "can only be called from completion function"); return 1; } dat.ipre = dat.isuf = dat.ppre = dat.psuf = dat.prpre = dat.mesg = dat.pre = dat.suf = dat.group = dat.rems = dat.remf = dat.disp = dat.ign = dat.exp = dat.apar = dat.opar = dat.dpar = NULL; dat.match = NULL; dat.flags = 0; dat.aflags = CAF_MATCH; dat.dummies = -1; for (; *argv && **argv == '-'; argv++) { char *p; /* loop variable, points into argv */ if (!(*argv)[1]) { argv++; break; } for (p = *argv + 1; *p; p++) { char *m = NULL; /* argument of -M option (this one only) */ char **sp = NULL; /* the argument to an option should be copied to *sp. */ const char *e; /* error message */ switch (*p) { case 'q': dat.flags |= CMF_REMOVE; break; case 'Q': dat.aflags |= CAF_QUOTE; break; case 'C': dat.aflags |= CAF_ALL; break; case 'f': dat.flags |= CMF_FILE; break; case 'e': dat.flags |= CMF_ISPAR; break; case 'a': dat.aflags |= CAF_ARRAYS; break; case 'k': dat.aflags |= CAF_ARRAYS|CAF_KEYS; break; case 'F': sp = &(dat.ign); e = "string expected after -%c"; break; case 'n': dat.flags |= CMF_NOLIST; break; case 'U': dat.aflags &= ~CAF_MATCH; break; case 'P': sp = &(dat.pre); e = "string expected after -%c"; break; case 'S': sp = &(dat.suf); e = "string expected after -%c"; break; case 'J': sp = &(dat.group); e = "group name expected after -%c"; break; case 'V': if (!dat.group) dat.aflags |= CAF_NOSORT; sp = &(dat.group); e = "group name expected after -%c"; break; case '1': if (!(dat.aflags & CAF_UNIQCON)) dat.aflags |= CAF_UNIQALL; break; case '2': if (!(dat.aflags & CAF_UNIQALL)) dat.aflags |= CAF_UNIQCON; break; case 'i': sp = &(dat.ipre); e = "string expected after -%c"; break; case 'I': sp = &(dat.isuf); e = "string expected after -%c"; break; case 'p': sp = &(dat.ppre); e = "string expected after -%c"; break; case 's': sp = &(dat.psuf); e = "string expected after -%c"; break; case 'W': sp = &(dat.prpre); e = "string expected after -%c"; break; case 'M': sp = &m; e = "matching specification expected after -%c"; break; case 'X': sp = &(dat.exp); e = "string expected after -%c"; break; case 'x': sp = &(dat.mesg); e = "string expected after -%c"; break; case 'r': dat.flags |= CMF_REMOVE; sp = &(dat.rems); e = "string expected after -%c"; break; case 'R': dat.flags |= CMF_REMOVE; sp = &(dat.remf); e = "function name expected after -%c"; break; case 'A': sp = &(dat.apar); e = "parameter name expected after -%c"; break; case 'O': sp = &(dat.opar); e = "parameter name expected after -%c"; break; case 'D': sp = &(dat.dpar); e = "parameter name expected after -%c"; break; case 'd': sp = &(dat.disp); e = "parameter name expected after -%c"; break; case 'l': dat.flags |= CMF_DISPLINE; break; case 'o': dat.flags |= CMF_MORDER; break; case 'E': if (p[1]) { dat.dummies = atoi(p + 1); p = "" - 1; } else if (argv[1]) { argv++; dat.dummies = atoi(*argv); p = "" - 1; } else { zwarnnam(name, "number expected after -%c", *p); zsfree(mstr); return 1; } if (dat.dummies < 0) { zwarnnam(name, "invalid number: %d", dat.dummies); zsfree(mstr); return 1; } break; case '-': argv++; goto ca_args; default: zwarnnam(name, "bad option: -%c", *p); zsfree(mstr); return 1; } if (sp) { if (p[1]) { /* Pasted argument: -Xfoo. */ if (!*sp) *sp = p + 1; p = "" - 1; } else if (argv[1]) { /* Argument in a separate word: -X foo. */ argv++; if (!*sp) *sp = *argv; p = "" - 1; } else { /* Missing argument: argv[N] == "-X", argv[N+1] == NULL. */ zwarnnam(name, e, *p); zsfree(mstr); return 1; } if (m) { if (mstr) { char *tmp = tricat(mstr, " ", m); zsfree(mstr); mstr = tmp; } else mstr = ztrdup(m); } } } } ca_args: if (mstr && (match = parse_cmatcher(name, mstr)) == pcm_err) { zsfree(mstr); return 1; } zsfree(mstr); if (!*argv && !dat.group && !dat.mesg && !(dat.aflags & (CAF_NOSORT|CAF_UNIQALL|CAF_UNIQCON|CAF_ALL))) return 1; dat.match = match = cpcmatcher(match); added = addmatches(&dat, argv); freecmatcher(match); return added; }