Пример #1
0
/* 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;
}
Пример #2
0
/* 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, &params)) {
	  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);
}
Пример #3
0
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;
}
Пример #4
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;
}