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; }
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; }