Exemple #1
0
int
ged_killall(struct ged *gedp, int argc, const char *argv[])
{
    int nflag;
    int ret;
    static const char *usage = "[-n] object(s)";

    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
    GED_CHECK_DRAWABLE(gedp, GED_ERROR);
    GED_CHECK_READ_ONLY(gedp, GED_ERROR);
    GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);

    /* initialize result */
    bu_vls_trunc(gedp->ged_result_str, 0);

    /* must be wanting help */
    if (argc == 1) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_HELP;
    }

    /* Process the -n option */
    if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'n' && argv[1][2] == '\0') {
	int i;
	nflag = 1;

	/* Objects that would be killed are in the first sublist */
	bu_vls_printf(gedp->ged_result_str, "{");
	for (i = 2; i < argc; i++)
	    bu_vls_printf(gedp->ged_result_str, "%s ", argv[i]);
	bu_vls_printf(gedp->ged_result_str, "} {");
    } else
	nflag = 0;

    gedp->ged_internal_call = 1;
    if ((ret = ged_killrefs(gedp, argc, argv)) != GED_OK) {
	gedp->ged_internal_call = 0;
	bu_vls_printf(gedp->ged_result_str, "KILL skipped because of earlier errors.\n");
	return ret;
    }
    gedp->ged_internal_call = 0;

    if (nflag) {
	/* Close the sublist of objects that reference the would-be killed objects. */
	bu_vls_printf(gedp->ged_result_str, "}");
	return GED_OK;
    }

    /* ALL references removed...now KILL the object[s] */
    /* reuse argv[] */
    argv[0] = "kill";
    return ged_kill(gedp, argc, argv);
}
int
ged_killtree(struct ged *gedp, int argc, const char *argv[])
{
    struct directory *dp;
    int i;
    int c;
    struct killtree_data gktd;
    static const char *usage = "[-a|-f|-n] object(s)";

    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
    GED_CHECK_READ_ONLY(gedp, GED_ERROR);
    GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);

    /* initialize result */
    bu_vls_trunc(gedp->ged_result_str, 0);

    /* must be wanting help */
    if (argc == 1) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_HELP;
    }

    gktd.gedp = gedp;
    gktd.killrefs = 0;
    gktd.print = 0;
    gktd.force = 0;
    gktd.ac = 1;
    gktd.top = NULL;

    gktd.av = (char **)bu_calloc(1, sizeof(char *) * AV_STEP, "alloc av");
    gktd.av_capacity = AV_STEP;
    BU_ASSERT(gktd.ac + argc + 2 < AV_STEP); /* potential -n opts */
    gktd.av[0] = "killrefs";
    gktd.av[1] = (char *)0;

    bu_optind = 1;
    while ((c = bu_getopt(argc, (char * const *)argv, "afn")) != -1) {
	switch (c) {
	    case 'a':
		gktd.killrefs = 1;
		break;
	    case 'n':
		gktd.print = 1;
		gktd.av[gktd.ac++] = bu_strdup("-n");
		gktd.av[gktd.ac] = (char *)0;
		break;
	    case 'f':
		gktd.force = 1;
		break;
	    default:
		bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
		bu_free(gktd.av, "free av (error)");
		gktd.av = NULL;
		return GED_ERROR;
	}
    }

    argc -= (bu_optind - 1);
    argv += (bu_optind - 1);

    /* Objects that would be killed are in the first sublist */
    if (gktd.print)
	bu_vls_printf(gedp->ged_result_str, "{");

    for (i = 1; i < argc; i++) {
	if ((dp = db_lookup(gedp->ged_wdbp->dbip, argv[i], LOOKUP_NOISY)) == RT_DIR_NULL)
	    continue;

	/* ignore phony objects */
	if (dp->d_addr == RT_DIR_PHONY_ADDR)
	    continue;

	/* stash the what's killed so we can find refs elsewhere */
	gktd.top = argv[i];

	db_functree(gedp->ged_wdbp->dbip, dp,
		    killtree_callback, killtree_callback,
		    gedp->ged_wdbp->wdb_resp, (void *)&gktd);
    }

    /* Close the sublist of would-be killed objects. Also open the
     * sublist of objects that reference the would-be killed objects.
     */
    if (gktd.print)
	bu_vls_printf(gedp->ged_result_str, "} {");

    if (gktd.killrefs && gktd.ac > 1) {
	gedp->ged_internal_call = 1;
	(void)ged_killrefs(gedp, gktd.ac, (const char **)gktd.av);
	gedp->ged_internal_call = 0;

	for (i = 1; i < gktd.ac; i++) {
	    if (!gktd.print)
		bu_vls_printf(gedp->ged_result_str, "Freeing %s\n", gktd.av[i]);
	    bu_free((void *)gktd.av[i], "killtree_data");
	    gktd.av[i] = NULL;
	}
    }

    if (gktd.print)
	bu_vls_printf(gedp->ged_result_str, "}");

    bu_free(gktd.av, "free av");
    gktd.av = NULL;

    return GED_OK;
}