/* theta_type -- compute type of a theta-exp or theta-select */ PRIVATE type theta_type(tree t, env e, type a, tree cxt) { def d = get_schema((tok) t->x_the_name, t->x_loc); schema s; env e1 = new_env(e); type b; int i; if (d == NULL) return err_type; s = d->d_schema; check_rename(s, (tok) t->x_the_decor, t->x_the_rename, t); for (i = 0; i < s->z_ncomps; i++) { sym x = s->z_comp[i].z_name; sym xp = get_rename(x, (tok) t->x_the_decor, t->x_the_rename); type tt = (a == NULL ? ref_type(xp, nil, e, t) : comp_type(a, xp, cxt, t->x_loc)); add_def(VAR, x, tt, e1); } b = mk_sproduct(mk_schema(e1)); if (! aflag && d->d_abbrev && d->d_nparams == 0 && type_equal(b, arid, mk_sproduct(s), arid)) return mk_abbrev(d, arid); else return b; }
/* do_sref -- add the variables of a schema reference to an env */ PUBLIC void do_sref(tree t, env e, env v) { tok dec = (tok) t->x_sref_decor; tree renames = t->x_sref_renames; def d; schema s; frame params; int i; if (t->x_kind != SREF) bad_tag("do_sref", t->x_kind); if (! open_sref(t, e, &d, ¶ms)) { v->e_partial = TRUE; return; } s = d->d_schema; check_rename(d->d_schema, dec, renames, t); for (i = 0; i < s->z_ncomps; i++) merge_def(VAR, get_rename(s->z_comp[i].z_name, dec, renames), seal(s->z_comp[i].z_type, params), v, t, t->x_loc); }
static int diversion_remove(const char *const *argv) { const char *filename = argv[0]; struct fsys_namenode *namenode; struct fsys_diversion *contest, *altname; struct file file_from, file_to; struct pkgset *pkgset; opt_rename_setup(); if (!filename || argv[1]) badusage(_("--%s needs a single argument"), cipaction->olong); diversion_check_filename(filename); namenode = fsys_hash_find_node(filename, FHFF_NONE); if (namenode == NULL || namenode->divert == NULL || namenode->divert->useinstead == NULL) { if (opt_verbose > 0) printf(_("No diversion '%s', none removed.\n"), diversion_current(filename)); return 0; } if (opt_pkgname == NULL) pkgset = NULL; else pkgset = pkg_hash_find_set(opt_pkgname); contest = namenode->divert; altname = contest->useinstead->divert; if (opt_divertto != NULL && strcmp(opt_divertto, contest->useinstead->name) != 0) ohshit(_("mismatch on divert-to\n" " when removing '%s'\n" " found '%s'"), diversion_current(filename), diversion_describe(contest)); if (!opt_pkgname_match_any && pkgset != contest->pkgset) ohshit(_("mismatch on package\n" " when removing '%s'\n" " found '%s'"), diversion_current(filename), diversion_describe(contest)); /* Ignore removal request if the diverted file is still owned * by another package in the same set. */ if (diversion_is_shared(pkgset, namenode)) { if (opt_verbose > 0) printf(_("Ignoring request to remove shared diversion '%s'.\n"), diversion_describe(contest)); return 0; } if (opt_verbose > 0) printf(_("Removing '%s'\n"), diversion_describe(contest)); file_init(&file_from, altname->camefrom->name); file_init(&file_to, contest->useinstead->name); /* Remove entries from database. */ contest->useinstead->divert = NULL; altname->camefrom->divert = NULL; if (opt_rename) opt_rename = check_rename(&file_to, &file_from); if (opt_rename && !opt_test) file_rename(&file_to, &file_from); if (!opt_test) divertdb_write(); return 0; }
static int diversion_add(const char *const *argv) { const char *filename = argv[0]; struct file file_from, file_to; struct fsys_diversion *contest, *altname; struct fsys_namenode *fnn_from, *fnn_to; struct pkgset *pkgset; opt_pkgname_match_any = false; opt_rename_setup(); /* Handle filename. */ if (!filename || argv[1]) badusage(_("--%s needs a single argument"), cipaction->olong); diversion_check_filename(filename); file_init(&file_from, filename); file_stat(&file_from); if (file_from.stat_state == FILE_STAT_VALID && S_ISDIR(file_from.stat.st_mode)) badusage(_("cannot divert directories")); fnn_from = fsys_hash_find_node(filename, 0); /* Handle divertto. */ if (opt_divertto == NULL) opt_divertto = str_fmt("%s.distrib", filename); if (strcmp(filename, opt_divertto) == 0) badusage(_("cannot divert file '%s' to itself"), filename); file_init(&file_to, opt_divertto); fnn_to = fsys_hash_find_node(opt_divertto, 0); /* Handle package name. */ if (opt_pkgname == NULL) pkgset = NULL; else pkgset = pkg_hash_find_set(opt_pkgname); /* Check we are not stomping over an existing diversion. */ if (fnn_from->divert || fnn_to->divert) { if (fnn_to->divert && fnn_to->divert->camefrom && strcmp(fnn_to->divert->camefrom->name, filename) == 0 && fnn_from->divert && fnn_from->divert->useinstead && strcmp(fnn_from->divert->useinstead->name, opt_divertto) == 0 && fnn_from->divert->pkgset == pkgset) { if (opt_verbose > 0) printf(_("Leaving '%s'\n"), diversion_describe(fnn_from->divert)); return 0; } ohshit(_("'%s' clashes with '%s'"), diversion_current(filename), fnn_from->divert ? diversion_describe(fnn_from->divert) : diversion_describe(fnn_to->divert)); } /* Create new diversion. */ contest = nfmalloc(sizeof(*contest)); altname = nfmalloc(sizeof(*altname)); altname->camefrom = fnn_from; altname->camefrom->divert = contest; altname->useinstead = NULL; altname->pkgset = pkgset; contest->useinstead = fnn_to; contest->useinstead->divert = altname; contest->camefrom = NULL; contest->pkgset = pkgset; /* Update database and file system if needed. */ if (opt_verbose > 0) printf(_("Adding '%s'\n"), diversion_describe(contest)); if (opt_rename) opt_rename = check_rename(&file_from, &file_to); /* Check we are not renaming a file owned by the diverting pkgset. */ if (opt_rename && diversion_is_owned_by_self(pkgset, fnn_from)) { if (opt_verbose > 0) printf(_("Ignoring request to rename file '%s' " "owned by diverting package '%s'\n"), filename, pkgset->name); opt_rename = false; } if (opt_rename && diversion_is_essential(fnn_from)) warning(_("diverting file '%s' from an Essential package with " "rename is dangerous, use --no-rename"), filename); if (!opt_test) { divertdb_write(); if (opt_rename) file_rename(&file_from, &file_to); } return 0; }