Ejemplo n.º 1
0
/*
 * Parse a sequence into an array of sorted & merged ranges.
 */
EXPORTED struct seqset *seqset_parse(const char *sequence,
			    struct seqset *set,
			    unsigned maxval)
{
    unsigned start = 0, end = 0;

    /* short circuit no sequence */
    if (!sequence) return NULL;

    if (!set) set = seqset_init(maxval, SEQ_SPARSE);

    while (*sequence) {
	if (read_num(&sequence, maxval, &start))
	    fatal("invalid sequence", EC_SOFTWARE);
	if (*sequence == ':') {
	    sequence++;
	    if (read_num(&sequence, maxval, &end))
		fatal("invalid sequence", EC_SOFTWARE);
	}
	else 
	    end = start;
	if (start > end) {
	    unsigned i = end;
	    end = start;
	    start = i;
	}

	if (set->len == set->alloc) {
	    set->alloc += SETGROWSIZE;
	    set->set = xrealloc(set->set, set->alloc * sizeof(struct seq_range));
	}
	set->set[set->len].low = start;
	set->set[set->len].high = end;
	set->len++;

	if (*sequence == ',')
	    sequence++;
	/* could test for invalid chars here, but the number parser next
	 * time through will grab them, so no need */
    }

    seqset_simplify(set);
    return set;
}
Ejemplo n.º 2
0
int main(int argc, char *argv[])
{
    const char *alt_config = NULL;
    unsigned maxval = 0;
    int flags = SEQ_MERGE;
    struct seqset *seq = NULL;
    int opt;
    unsigned num;
    char *res;
    const char *origlist = NULL;

    while ((opt = getopt(argc, argv, "C:m:o:s")) != EOF) {
	switch (opt) {
	case 'C': /* alt config file */
	    alt_config = optarg;
	    break;
	case 'm': /* maxval */
	    parseuint32(optarg, NULL, &maxval);
	    break;
	case 'o':
	    origlist = optarg;
	    break;
	case 's':
	    flags = SEQ_SPARSE;
	}
    }
	
    if ((argc - optind) < 1) usage(argv[0]);

    cyrus_init(alt_config, "cyr_sequence", 0);

    /* special case */
    if (!strcmp(argv[optind], "create")) {
	int i;
	seq = seqset_init(maxval, flags);
	for (i = optind + 1; i < argc; i++) {
	    char *ptr = argv[i];
	    int isadd = 1;
	    if (*ptr == '~') {
		isadd = 0;
		ptr++;
	    }
	    if (parseuint32(ptr, NULL, &num))
		printf("%s NAN\n", argv[i]);
	    else
		seqset_add(seq, num, isadd);
	}
	if (origlist) {
	    unsigned oldmax = seq_lastnum(origlist, NULL);
	    if (oldmax > maxval) {
		struct seqset *origseq = seqset_parse(origlist, NULL, oldmax);
		unsigned val;
		for (val = maxval + 1; val <= oldmax; val++)
		    seqset_add(seq, val, seqset_ismember(origseq, val));
		seqset_free(origseq);
	    }
	}
	res = seqset_cstring(seq);
	printf("%s\n", res);
	free(res);
    }
    else if (!strcmp(argv[optind], "parsed")) {
	unsigned i;
	seq = seqset_parse(argv[optind+1], NULL, maxval);
	printf("Sections: " SIZE_T_FMT "\n", seq->len);
	for (i = 0; i < seq->len; i++) {
	    if (seq->set[i].high == UINT_MAX)
		printf(" [%u, *]\n", seq->set[i].low);
	    else
		printf(" [%u, %u]\n", seq->set[i].low, seq->set[i].high);
	}
    }
    else if (!strcmp(argv[optind], "compress")) {
	seq = seqset_parse(argv[optind+1], NULL, maxval);
	res = seqset_cstring(seq);
	printf("%s\n", res);
	free(res);
    }
    else if (!strcmp(argv[optind], "members")) {
	seq = seqset_parse(argv[optind+1], NULL, maxval);
	while ((num = seqset_getnext(seq))) {
	    printf("%u\n", num);
	}
    }
    else if (!strcmp(argv[optind], "join")) {
	struct seqset *seq2;
	seq = seqset_parse(argv[optind+1], NULL, maxval);
	seq2 = seqset_parse(argv[optind+2], NULL, maxval);
	seqset_join(seq, seq2);
	res = seqset_cstring(seq);
	printf("%s\n", res);
	free(res);
    }
    else if (!strcmp(argv[optind], "ismember")) {
	int i;
	seq = seqset_parse(argv[optind+1], NULL, maxval);
	for (i = optind + 2; i < argc; i++) {
	    if (parseuint32(argv[i], NULL, &num))
		printf("%s NAN\n", argv[i]);
	    else
		printf("%d %s\n", num, seqset_ismember(seq, num) ? "Yes" : "No");
	}
    }
    else {
	printf("Unknown command %s", argv[optind]);
    }

    seqset_free(seq);

    cyrus_done();

    return 0;
}