Пример #1
0
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;
}
Пример #2
0
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;
}