Beispiel #1
0
static int
validate_beg(Cx_t* cx, Cxexpr_t* expr, void* data, Cxdisc_t* disc)
{
	char**			argv = (char**)data;
	int			errors = error_info.errors;
	char*			s;
	State_t*		state;
	Cxvariable_t*		variable;
	register Field_t*	field;
	Field_t*		lastfield;
	Cxconstraint_t*		constraint;
	int			all;
	int			list;
	Vmalloc_t*		vm;

	if (!(vm = vmopen(Vmdcheap, Vmlast, 0)) || !(state = vmnewof(vm, 0, State_t, 1, 0)))
	{
		if (vm)
			vmclose(vm);
		if (disc->errorf)
			(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space");
		return -1;
	}
	state->vm = vm;
	list = 0;
	sfprintf(cx->buf, "%s%s", strchr(dss_lib_validate.description, '['), validate_usage);
	s = sfstruse(cx->buf);
	for (;;)
	{
		switch (optget(argv, s))
		{
		case 'd':
			state->discard = 1;
			continue;
		case 'l':
			list = 1;
			continue;
		case 'r':
			if (!(state->setf = cxcallout(cx, CX_SET, cx->state->type_void, cx->state->type_void, cx->disc)))
			{
				if (cx->disc->errorf)
					(*cx->disc->errorf)(NiL, cx->disc, 3, "reair requires CX_SET callout");
				return -1;
			}
			continue;
		case 's':
			state->summary = 1;
			continue;
		case 'v':
			state->summary = state->verbose = 1;
			continue;
		case '?':
			if (disc->errorf)
				(*disc->errorf)(NiL, disc, ERROR_USAGE|4, "%s", opt_info.arg);
			else
				return -1;
			continue;
		case ':':
			if (disc->errorf)
				(*disc->errorf)(NiL, disc, 2, "%s", opt_info.arg);
			else
				return -1;
			continue;
		}
		break;
	}
	if (error_info.errors > errors)
		goto bad;
	argv += opt_info.index;
	if (all = !*argv)
		variable = 0;
	do
	{
		if (all)
		{
			if (!(variable = (Cxvariable_t*)(variable ? dtnext(cx->fields, variable) : dtfirst(cx->fields))))
				break;
		}
		else if (!(variable = cxvariable(cx, *argv, NiL, disc)))
			goto bad;
		if (variable->format.constraint || variable->format.map)
		{
			if (!(field = vmnewof(vm, 0, Field_t, 1, 0)))
			{
				if (disc->errorf)
					(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space");
				goto bad;
			}
			field->variable = variable;
			if (state->field)
				lastfield = lastfield->next = field;
			else
				lastfield = state->field = field;
		}
	} while (all || *++argv);
	if (!state->field && disc->errorf)
		(*disc->errorf)(NiL, disc, 1, "no field has constraints or maps");
	if (list)
	{
		for (field = state->field; field; field = field->next)
		{
			sfprintf(expr->op, "%16s", field->variable->name);
			if (field->variable->format.map)
				sfprintf(expr->op, " map");
			if (constraint = field->variable->format.constraint)
			{
				if (constraint->name)
					sfprintf(expr->op, " name=%s", constraint->name);
				if (constraint->constraintf)
					sfprintf(expr->op, " external");
				if (cxisnumber(field->variable->type))
				{
					if (constraint->def)
						number(expr->op, "default", constraint->def->number, &field->variable->format);
					if (constraint->min)
						number(expr->op, "min", constraint->min->number, &field->variable->format);
					if (constraint->max)
						number(expr->op, "max", constraint->max->number, &field->variable->format);
				}
				else if (cxisstring(field->variable->type) && constraint->def)
					sfprintf(expr->op, " default=\"%-.*s\"", constraint->def->string.size, constraint->def->string.data);
				if (constraint->expression)
					sfprintf(expr->op, " expression=\"%s\"", constraint->expression);
				if (constraint->pattern)
					sfprintf(expr->op, " pattern=\"%s\"", constraint->pattern);
			}
			sfprintf(expr->op, "\n");
		}
		goto bad;
	}
	if (!(state->getf = cxcallout(cx, CX_GET, cx->state->type_void, cx->state->type_void, cx->disc)))
	{
		if (cx->disc->errorf)
			(*cx->disc->errorf)(NiL, cx->disc, 3, "validation requires CX_GET callout");
		goto bad;
	}
	if (!state->verbose)
	{
		state->invaliddisc.comparf = invalidcmp;
		if (!(state->invalid = dtnew(vm, &state->invaliddisc, Dtoset)))
		{
			if (cx->disc->errorf)
				(*cx->disc->errorf)(NiL, cx->disc, 3, "validation requires CX_GET callout");
			goto bad;
		}
	}
	expr->data = state;
	return 0;
 bad:
	vmclose(vm);
	return -1;
}
Beispiel #2
0
static int
merge_beg(Cx_t* cx, Cxexpr_t* expr, void* data, Cxdisc_t* disc)
{
	register State_t*	state;
	register File_t*	file;
	char**			argv = (char**)data;
	char**			files = expr->files;
	Dss_t*			dss = DSS(cx);
	int			errors = error_info.errors;
	int			i;
	int			k;
	int			n;
	int			r;
	char*			path;
	char*			u;
	char**			v;
	Cxvariable_t*		variable;
	Cxoperand_t*		operands;
	Key_t*			key;
	Key_t*			lastkey;
	Key_t*			keys;
	Vmalloc_t*		vm;

	if (!(vm = vmopen(Vmdcheap, Vmbest, 0)))
	{
		if (disc->errorf)
			(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space");
		return -1;
	}
	r = -1;
	k = 0;
	keys = 0;
	sfprintf(cx->buf, "%s%s", strchr(dss_lib_merge.description, '['), merge_usage);
	u = sfstruse(cx->buf);
	for (;;)
	{
		switch (i = optget(argv, u))
		{
		case 'k':
		case 'r':
			if (!(variable = cxvariable(cx, opt_info.arg, NiL, disc)))
				goto bad;
			if (!(key = vmnewof(vm, 0, Key_t, 1, 0)))
			{
				if (disc->errorf)
					(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space");
				goto bad;
			}
			key->variable = variable;
			key->sense = (i == 'r') ? -1 : 1;
			if (keys)
				lastkey = lastkey->next = key;
			else
				lastkey = keys = key;
			k++;
			continue;
		case '?':
			if (disc->errorf)
				(*disc->errorf)(NiL, disc, ERROR_USAGE|4, "%s", opt_info.arg);
			else
				return -1;
			continue;
		case ':':
			if (disc->errorf)
				(*disc->errorf)(NiL, disc, 2, "%s", opt_info.arg);
			else
				return -1;
			continue;
		}
		break;
	}
	if (error_info.errors > errors)
		goto bad;
	argv += opt_info.index;
	for (v = argv; *v; v++);
	n = v - argv;
	if (files)
	{
		for (v = files; *v; v++);
		n += v - files;
	}
	if (!n)
		n = 1;
	if (!(state = vmnewof(vm, 0, State_t, 1, (n - 1) * sizeof(File_t))) || !(operands = vmnewof(vm, 0, Cxoperand_t, n * k, 0)))
	{
		if (cx->disc->errorf)
			(*cx->disc->errorf)(NiL, cx->disc, ERROR_SYSTEM|2, "out of space");
		goto bad;
	}
	state->cx = cx;
	if (!(state->getf = cxcallout(cx, CX_GET, cx->state->type_void, cx->state->type_void, cx->disc)))
	{
		if (cx->disc->errorf)
			(*cx->disc->errorf)(NiL, cx->disc, 2, "CX_GET callout required");
		goto bad;
	}
	state->nfiles = n;
	state->nkeys = k;
	state->keys = keys;
	for (n = 0; n < state->nfiles; n++)
	{
		state->files[n].data = operands;
		operands += k;
	}
	state->orderdisc.comparf = ordercmp;
	if (!(state->order = dtnew(vm, &state->orderdisc, Dtoset)))
	{
		if (cx->disc->errorf)
			(*cx->disc->errorf)(NiL, cx->disc, ERROR_SYSTEM|2, "out of space");
		goto bad;
	}
	n = 0;
	if (path = *argv)
		argv++;
	else if (files)
	{
		argv = files;
		files = 0;
		if (path = *argv)
			argv++;
	}
	for (;;)
	{
		if (!(state->files[n].file = dssfopen(dss, path, NiL, DSS_FILE_READ, NiL)))
			goto drop;
		enter(dss, state, &state->files[n]);
		n++;
		if (!(path = *argv++))
		{
			if (!files)
				break;
			argv = files;
			files = 0;
			if (!(path = *argv++))
				break;
		}
	}
	expr = expr->pass;
	if (dssbeg(dss, expr))
		goto drop;
	while (file = (File_t*)dtfirst(state->order))
	{
		if (dsseval(dss, expr, file->record) < 0)
			goto drop;
		enter(dss, state, file);
	}
	if (error_info.errors == errors)
		r = 0;
 drop:
	for (n = 0; n < state->nfiles; n++)
		if (state->files[n].file)
			dssfclose(state->files[n].file);
 bad:
	vmclose(vm);
	return r;
}