Revision: 71779 http://sourceforge.net/p/brlcad/code/71779 Author: starseeker Date: 2018-09-22 00:20:50 +0000 (Sat, 22 Sep 2018) Log Message: ----------- Add lookup and reporting for references to missing objects (just combs so far)
Modified Paths: -------------- brlcad/trunk/src/libged/lint.cpp Modified: brlcad/trunk/src/libged/lint.cpp =================================================================== --- brlcad/trunk/src/libged/lint.cpp 2018-09-21 23:22:32 UTC (rev 71778) +++ brlcad/trunk/src/libged/lint.cpp 2018-09-22 00:20:50 UTC (rev 71779) @@ -24,6 +24,8 @@ #include "common.h" +#include <set> + extern "C" { #include "bu/opt.h" #include "raytrace.h" @@ -79,6 +81,13 @@ struct bu_ptbl *paths; }; + +struct _ged_missing_data { + struct ged *gedp; + std::set<std::string> missing; +}; + + /* Because lint is intended to be a deep inspection of the .g looking for problems, * we need to do this check using the low level tree walk rather than operating on * a search result set (which has checks to filter out cyclic paths.) */ @@ -201,14 +210,82 @@ return ret; } +HIDDEN void +_ged_lint_comb_find_invalid(struct _ged_missing_data *mdata, const char *parent, struct db_i *dbip, union tree *tp) +{ + if (!tp) return; + + RT_CHECK_DBI(dbip); + RT_CK_TREE(tp); + + switch (tp->tr_op) { + case OP_UNION: + case OP_INTERSECT: + case OP_SUBTRACT: + case OP_XOR: + _ged_lint_comb_find_invalid(mdata, parent, dbip, tp->tr_b.tb_right); + /* fall through */ + case OP_NOT: + case OP_GUARD: + case OP_XNOP: + _ged_lint_comb_find_invalid(mdata, parent, dbip, tp->tr_b.tb_left); + break; + case OP_DB_LEAF: + if (db_lookup(dbip, tp->tr_l.tl_name, LOOKUP_QUIET) == RT_DIR_NULL) { + std::string inst = std::string(parent) + std::string("/") + std::string(tp->tr_l.tl_name); + mdata->missing.insert(inst); + } + break; + default: + bu_log("_ged_lint_comb_find_invalid: unrecognized operator %d\n", tp->tr_op); + bu_bomb("_ged_lint_comb_find_invalid\n"); + } +} + int -_ged_missing_check(struct ged *gedp, int argc, struct directory **dpa) +_ged_missing_check(struct _ged_missing_data *mdata, struct ged *gedp, int argc, struct directory **dpa) { + struct directory *dp; int ret = GED_OK; if (!gedp) return GED_ERROR; if (argc) { + unsigned int i; + struct bu_ptbl *pc = NULL; + const char *osearch = "-type comb"; if (!dpa) return GED_ERROR; - } + BU_ALLOC(pc, struct bu_ptbl); + if (db_search(pc, DB_SEARCH_RETURN_UNIQ_DP, osearch, argc, dpa, gedp->ged_wdbp->dbip, NULL) < 0) { + ret = GED_ERROR; + bu_ptbl_free(pc); + bu_free(pc, "pc table"); + } else { + for (i = 0; i < BU_PTBL_LEN(pc); i++) { + dp = (struct directory *)BU_PTBL_GET(pc, i); + if (dp->d_flags & RT_DIR_COMB) { + struct rt_db_internal in; + struct rt_comb_internal *comb; + if (rt_db_get_internal(&in, dp, gedp->ged_wdbp->dbip, NULL, &rt_uniresource) < 0) continue; + comb = (struct rt_comb_internal *)in.idb_ptr; + _ged_lint_comb_find_invalid(mdata, dp->d_namep, gedp->ged_wdbp->dbip, comb->tree); + } + } + bu_ptbl_free(pc); + bu_free(pc, "pc table"); + } + } else { + int i; + for (i = 0; i < RT_DBNHASH; i++) { + for (dp = gedp->ged_wdbp->dbip->dbi_Head[i]; dp != RT_DIR_NULL; dp = dp->d_forw) { + if (dp->d_flags & RT_DIR_COMB) { + struct rt_db_internal in; + struct rt_comb_internal *comb; + if (rt_db_get_internal(&in, dp, gedp->ged_wdbp->dbip, NULL, &rt_uniresource) < 0) continue; + comb = (struct rt_comb_internal *)in.idb_ptr; + _ged_lint_comb_find_invalid(mdata, dp->d_namep, gedp->ged_wdbp->dbip, comb->tree); + } + } + } + } return ret; } @@ -219,7 +296,7 @@ if (!gedp) return GED_ERROR; if (argc) { if (!dpa) return GED_ERROR; - } + } return ret; } @@ -235,6 +312,7 @@ struct directory **dpa = NULL; int nonexist_obj_cnt = 0; struct _ged_cyclic_data *cdata = NULL; + struct _ged_missing_data *mdata = new struct _ged_missing_data; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); @@ -299,10 +377,20 @@ } if (opts->missing_check) { - ret = _ged_missing_check(gedp, argc, dpa); + bu_log("Checking for references to non-extant objects...\n"); + mdata->gedp = gedp; + ret = _ged_missing_check(mdata, gedp, argc, dpa); if (ret != GED_OK) { goto ged_lint_memfree; } + if (mdata->missing.size()) { + std::set<std::string>::iterator s_it; + bu_vls_printf(gedp->ged_result_str, "Found references to missing objects:\n"); + for (s_it = mdata->missing.begin(); s_it != mdata->missing.end(); s_it++) { + std::string mstr = *s_it; + bu_vls_printf(gedp->ged_result_str, " %s\n", mstr.c_str()); + } + } } if (opts->non_solid_check) { @@ -323,6 +411,9 @@ BU_PUT(cdata->paths, struct bu_ptbl); BU_PUT(cdata, struct _ged_cyclic_data); } + + delete mdata; + if (dpa) bu_free(dpa, "dp array"); return ret; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. _______________________________________________ BRL-CAD Source Commits mailing list brlcad-commits@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/brlcad-commits