/* * Build a substitution from the equalities stored in v * - every element of v must be the id of a asserted equality * - if an equality can't be added to the substitution, it's left in v */ static substitution_t *subst_from_explanation(test_bench_t *bench, ivector_t *v) { substitution_t *s; op_stack_t *stack; offset_equality_t e; uint32_t i, j, n; int32_t id; s = (substitution_t *) safe_malloc(sizeof(substitution_t)); init_substitution(s, bench->ptable->npolys); stack = &bench->stack; j = 0; n = v->size; for (i=0; i<n; i++) { id = v->data[i]; assert(0 <= id && id < stack->top); assert(stack->data[id].tag == ASSERT_EQ); e = stack->data[id].arg.eq; // make a copy of eq[id] subst_eq(s, &e); // normalize eq modulo previous equalities if (e.lhs == e.rhs) { // keep in v v->data[j] = id; j ++; } else { // add to subst if (e.lhs < 0) { // convert 0 := rhs + offset into rhs = - offset e.lhs = e.rhs; e.rhs = -1; e.offset = - e.offset; } add_subst(s, e.lhs, e.rhs, e.offset); } } v->size = j; return s; }
static void init_test_bench(test_bench_t *bench, poly_table_t *ptable) { uint32_t nv, np; np = ptable->npolys; nv = ptable->nvars; bench->base_level = 0; bench->decision_level = 0; bench->conflict = false; bench->conflict_eq = -1; bench->mngr_conflict = false; bench->show_details = false; bench->ptable = ptable; init_substitution(&bench->subst, np); init_subst_queue(&bench->squeue, nv); init_active_polys(&bench->act, np); init_op_stack(&bench->stack); init_equality_queue(&bench->equeue, np); init_offset_manager(&bench->manager, &bench->equeue, notify_equality); init_poly_buffer(&bench->buffer); }
void add_substitution(struct bsdtar *bsdtar, const char *rule_text) { struct subst_rule *rule; struct substitution *subst; const char *end_pattern, *start_subst; char *pattern; int r; if ((subst = bsdtar->substitution) == NULL) { init_substitution(bsdtar); subst = bsdtar->substitution; } rule = malloc(sizeof(*rule)); if (rule == NULL) lafe_errc(1, errno, "Out of memory"); rule->next = NULL; if (subst->last_rule == NULL) subst->first_rule = rule; else subst->last_rule->next = rule; subst->last_rule = rule; if (*rule_text == '\0') lafe_errc(1, 0, "Empty replacement string"); end_pattern = strchr(rule_text + 1, *rule_text); if (end_pattern == NULL) lafe_errc(1, 0, "Invalid replacement string"); pattern = malloc(end_pattern - rule_text); if (pattern == NULL) lafe_errc(1, errno, "Out of memory"); memcpy(pattern, rule_text + 1, end_pattern - rule_text - 1); pattern[end_pattern - rule_text - 1] = '\0'; if ((r = regcomp(&rule->re, pattern, REG_BASIC)) != 0) { char buf[80]; regerror(r, &rule->re, buf, sizeof(buf)); lafe_errc(1, 0, "Invalid regular expression: %s", buf); } free(pattern); start_subst = end_pattern + 1; end_pattern = strchr(start_subst, *rule_text); if (end_pattern == NULL) lafe_errc(1, 0, "Invalid replacement string"); rule->result = malloc(end_pattern - start_subst + 1); if (rule->result == NULL) lafe_errc(1, errno, "Out of memory"); memcpy(rule->result, start_subst, end_pattern - start_subst); rule->result[end_pattern - start_subst] = '\0'; /* Defaults */ rule->global = 0; /* Don't do multiple replacements. */ rule->print = 0; /* Don't print. */ rule->regular = 1; /* Rewrite regular filenames. */ rule->symlink = 1; /* Rewrite symlink targets. */ rule->hardlink = 1; /* Rewrite hardlink targets. */ while (*++end_pattern) { switch (*end_pattern) { case 'g': case 'G': rule->global = 1; break; case 'h': rule->hardlink = 1; break; case 'H': rule->hardlink = 0; break; case 'p': case 'P': rule->print = 1; break; case 'r': rule->regular = 1; break; case 'R': rule->regular = 0; break; case 's': rule->symlink = 1; break; case 'S': rule->symlink = 0; break; default: lafe_errc(1, 0, "Invalid replacement flag %c", *end_pattern); } } }