/** * This routine will be called by db_walk_tree() once all the solids * in this region have been visited. * * This routine must be prepared to run in parallel. As a result, * note that the details of the solids pointed to by the soltab * pointers in the tree may not be filled in when this routine is * called (due to the way multiple instances of solids are handled). * Therefore, everything which referred to the tree has been moved out * into the serial section. (_rt_tree_region_assign, rt_bound_tree) */ HIDDEN union tree * _rt_gettree_region_end(struct db_tree_state *tsp, const struct db_full_path *pathp, union tree *curtree, void *client_data) { struct region *rp; struct directory *dp = NULL; size_t shader_len=0; struct rt_i *rtip; Tcl_HashTable *tbl = (Tcl_HashTable *)client_data; Tcl_HashEntry *entry; matp_t inv_mat; struct bu_attribute_value_set avs; struct bu_attribute_value_pair *avpp; RT_CK_DBI(tsp->ts_dbip); RT_CK_FULL_PATH(pathp); RT_CK_TREE(curtree); rtip = tsp->ts_rtip; RT_CK_RTI(rtip); RT_CK_RESOURCE(tsp->ts_resp); if (curtree->tr_op == OP_NOP) { /* Ignore empty regions */ return curtree; } BU_ALLOC(rp, struct region); rp->l.magic = RT_REGION_MAGIC; rp->reg_regionid = tsp->ts_regionid; rp->reg_is_fastgen = tsp->ts_is_fastgen; rp->reg_aircode = tsp->ts_aircode; rp->reg_gmater = tsp->ts_gmater; rp->reg_los = tsp->ts_los; dp = (struct directory *)DB_FULL_PATH_CUR_DIR(pathp); if (!dp) return TREE_NULL; bu_avs_init_empty(&avs); if (db5_get_attributes(tsp->ts_dbip, &avs, dp) == 0) { /* copy avs */ bu_avs_init_empty(&(rp->attr_values)); for (BU_AVS_FOR(avpp, &(tsp->ts_attrs))) { bu_avs_add(&(rp->attr_values), avpp->name, bu_avs_get(&avs, avpp->name)); } }
HIDDEN int constraint_eval(void *datap, int argc, const char *argv[]) { size_t i, obj; struct directory *dp; struct bu_attribute_value_set avs; struct bu_attribute_value_pair *avpp; int ret = BRLCAD_OK; struct ged *gedp = (struct ged *)datap; if (!gedp || argc < 1 || !argv) return BRLCAD_ERROR; GED_CHECK_READ_ONLY(gedp, GED_ERROR); /* multiple arguments assumed to be multiple objects */ for (obj = 0; 2+obj < (size_t)argc; obj++) { /* load the constraint object */ dp = db_lookup(gedp->ged_wdbp->dbip, argv[2+obj], LOOKUP_QUIET); if (dp == RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, "Unable to find %s in the database.\n", argv[2+obj]); ret = BRLCAD_ERROR; continue; } bu_avs_init_empty(&avs); if (db5_get_attributes(gedp->ged_wdbp->dbip, &avs, dp)) { bu_vls_printf(gedp->ged_result_str, "Cannot get constraints from %s\n", dp->d_namep); ret = BRLCAD_ERROR; } for (i=0, avpp = avs.avp; i < avs.count; i++, avpp++) { bu_vls_printf(gedp->ged_result_str, "Evaluating %s constraint: %s %s\n", argv[2+obj], avpp->name, avpp->value); bu_vls_printf(gedp->ged_result_str, "<<constraint eval here>>\n"); } bu_avs_free(&avs); } return ret; }
HIDDEN int constraint_set(void *datap, int argc, const char *argv[]) { struct directory *dp; struct bu_attribute_value_set avs = BU_AVS_INIT_ZERO; struct bu_vls expression = BU_VLS_INIT_ZERO; struct ged *gedp = (struct ged *)datap; if (!gedp || argc < 3 || !argv) return BRLCAD_ERROR; GED_CHECK_READ_ONLY(gedp, GED_ERROR); dp = db_lookup(gedp->ged_wdbp->dbip, argv[2], LOOKUP_QUIET); if (!dp) { /* TODO: need to create the object here */ return BRLCAD_ERROR; } if (db5_get_attributes(gedp->ged_wdbp->dbip, &avs, dp)) { bu_vls_printf(gedp->ged_result_str, "Cannot get constraints for %s\n", dp->d_namep); bu_avs_free(&avs); return BRLCAD_ERROR; } bu_vls_from_argv(&expression, argc-4, &argv[4]); (void)bu_avs_add(&avs, argv[3], bu_vls_addr(&expression)); bu_vls_free(&expression); if (db5_update_attributes(dp, &avs, gedp->ged_wdbp->dbip)) { bu_vls_printf(gedp->ged_result_str, "Failed to set constraints on %s\n", dp->d_namep); bu_avs_free(&avs); return GED_ERROR; } bu_avs_free(&avs); return BRLCAD_OK; }
int ged_lc(struct ged *gedp, int argc, const char *argv[]) { char *file_name = NULL; int file_name_flag_cnt = 0; int sort_column = 1; int sort_column_flag_cnt = 0; int find_duplicates_flag = 0; int skip_special_duplicates_flag = 0; int skip_subtracted_regions_flag = 0; int descending_sort_flag = 0; int unrecognized_flag_cnt = 0; int orig_argc; const char **orig_argv; static const char *usage = "[-d|-s] [-r] [-z] [-0|-1|-2|-3|-4|-5] [-f {FileName}] {GroupName}"; int c; int error_cnt = 0; FILE *outfile = NULL; struct bu_vls *output; const char *group_name; size_t i,j; struct bu_ptbl results1 = BU_PTBL_INIT_ZERO; struct bu_ptbl results2 = BU_PTBL_INIT_ZERO; char *path; char *plan; struct db_full_path root; int matches; struct region_record *regions; size_t ignored_cnt = 0; /* The defaults are the minimum widths to accommodate column headers */ size_t region_id_len_max = 2; size_t material_id_len_max = 3; size_t los_len_max = 3; size_t obj_len_max = 6; /* For the output at the end */ size_t start, end, incr; /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s\n", usage); return GED_HELP; } GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); bu_optind = 1; /* re-init bu_getopt() */ while ((c = bu_getopt(argc, (char * const *)argv, "dsrz012345f:")) != -1) { switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': sort_column_flag_cnt++; sort_column = c - '0'; break; case 'f': file_name_flag_cnt++; file_name = bu_optarg; break; case 's': skip_special_duplicates_flag = 1; /* FALLTHROUGH */ case 'd': find_duplicates_flag = 1; break; case 'r': skip_subtracted_regions_flag = 1; break; case 'z': descending_sort_flag = 1; break; default: unrecognized_flag_cnt++; } } orig_argc = argc; orig_argv = argv; argc -= (bu_optind - 1); argv += (bu_optind - 1); /* Attempt to recreate the exact error messages from the original lc.tcl */ if (file_name_flag_cnt > 1) { bu_vls_printf(gedp->ged_result_str, "Error: '-f' used more than once.\n"); error_cnt++; } if (sort_column_flag_cnt > 1) { bu_vls_printf(gedp->ged_result_str, "Error: Sort column defined more than once.\n"); error_cnt++; } if (file_name_flag_cnt + argc + unrecognized_flag_cnt > 3) { bu_vls_printf(gedp->ged_result_str, "Error: More than one group name and/or file name was specified.\n"); error_cnt++; } else if (argc < 2) { if (file_name_flag_cnt && !file_name) { bu_vls_printf(gedp->ged_result_str, "Error: Group name and file name not specified\n"); } else { bu_vls_printf(gedp->ged_result_str, "Error: Group name not specified.\n"); } error_cnt++; } else if (argc + unrecognized_flag_cnt > 2) { bu_vls_printf(gedp->ged_result_str, "Error: More than one group name was specified.\n"); error_cnt++; } else if (file_name_flag_cnt && !file_name) { bu_vls_printf(gedp->ged_result_str, "Error: File name not specified.\n"); error_cnt++; } if (file_name) { char *norm_name; norm_name = bu_realpath(file_name, NULL); if (file_name[0] == '-') { bu_vls_printf(gedp->ged_result_str, "Error: File name can not start with '-'.\n"); error_cnt++; } else if (bu_file_exists(file_name, NULL)) { bu_vls_printf(gedp->ged_result_str, "Error: Output file %s already exists.\n",norm_name); error_cnt++; } else { outfile = fopen(file_name, "w"); if (!outfile) { bu_vls_printf(gedp->ged_result_str, "Error: %d\n", errno); error_cnt++; } } bu_vls_printf(gedp->ged_result_str, "Output filename: %s\n", norm_name); bu_free(norm_name, "ged_lc"); output = bu_vls_vlsinit(); } else { output = gedp->ged_result_str; } if (error_cnt > 0) { return GED_ERROR; } group_name = argv[1]; /* The 7 is for the "-name" and '\0' */ plan = (char *) bu_malloc(sizeof(char) * (strlen(group_name) + 7), "ged_lc"); sprintf(plan, "-name %s", group_name); matches = db_search(&results1, DB_SEARCH_TREE, plan, 0, NULL, gedp->ged_wdbp->dbip); if (matches < 1) { bu_vls_printf(gedp->ged_result_str, "Error: Group '%s' does not exist.\n", group_name); return GED_ERROR; } bu_free(plan, "ged_lc"); db_search_free(&results1); if (skip_subtracted_regions_flag) { plan = "-type region ! -bool -"; } else { plan = "-type region"; } path = (char *) bu_malloc(sizeof(char) * (strlen(group_name) + 2), "ged_lc"); sprintf(path, "/%s", group_name); db_string_to_path(&root, gedp->ged_wdbp->dbip, path); matches = db_search(&results2, DB_SEARCH_TREE, plan, root.fp_len, root.fp_names, gedp->ged_wdbp->dbip); bu_free(path, "ged_lc"); if (matches < 1) { return GED_ERROR; } regions = (struct region_record *) bu_malloc(sizeof(struct region_record) * BU_PTBL_LEN(&results2), "ged_lc"); for (i = 0; i < BU_PTBL_LEN(&results2); i++) { struct db_full_path *entry = (struct db_full_path *)BU_PTBL_GET(&results2, i); struct directory *dp_curr_dir = DB_FULL_PATH_CUR_DIR(entry); struct bu_attribute_value_set avs; j = BU_PTBL_LEN(&results2) - i - 1 ; regions[j].ignore = 0; bu_avs_init_empty(&avs); db5_get_attributes(gedp->ged_wdbp->dbip, &avs, dp_curr_dir); regions[j].region_id = get_attr(&avs, "region_id"); V_MAX(region_id_len_max, strlen(regions[j].region_id)); regions[j].material_id = get_attr(&avs, "material_id"); V_MAX(material_id_len_max, strlen(regions[j].material_id)); regions[j].los = get_attr(&avs, "los"); V_MAX(los_len_max, strlen(regions[j].los)); regions[j].obj_name = dp_curr_dir->d_namep; V_MAX(obj_len_max, strlen(regions[j].obj_name)); if (entry->fp_len > 1) { struct directory *dp_parent = DB_FULL_PATH_GET(entry, entry->fp_len - 2); regions[j].obj_parent = dp_parent->d_namep; } else { regions[j].obj_parent = "--"; } } if (find_duplicates_flag) { bu_sort((void *) regions, BU_PTBL_LEN(&results2), sizeof(struct region_record), cmp_regions, NULL); for (i = 1; i < BU_PTBL_LEN(&results2); i++) { int same; if (skip_special_duplicates_flag) { same = !cmp_regions((void *)&(regions[i - 1]), (void *)&(regions[i]), NULL); } else { same = !bu_strcmp(regions[i - 1].region_id, regions[i].region_id); } if (same) { regions[i].ignore = 1; ignored_cnt++; } } if (ignored_cnt == BU_PTBL_LEN(&results2)) { if (file_name) { print_cmd_args(output, orig_argc, orig_argv); bu_vls_printf(output, "No duplicate region_id\n"); bu_vls_fwrite(outfile, output); fclose(outfile); } bu_vls_printf(gedp->ged_result_str, "No duplicate region_id\n"); bu_vls_printf(gedp->ged_result_str, "Done.\n"); bu_free(regions, "ged_lc"); return GED_ERROR; } } if (sort_column > 0) { bu_sort((void *) regions, BU_PTBL_LEN(&results2), sizeof(struct region_record), sort_regions, (void *)&sort_column); } if (file_name) { print_cmd_args(output, orig_argc, orig_argv); } bu_vls_printf(output, "List length: %d\n", BU_PTBL_LEN(&results2) - ignored_cnt); bu_vls_printf(output, "%-*s %-*s %-*s %-*s %s\n", region_id_len_max + 1, "ID", material_id_len_max + 1, "MAT", los_len_max, "LOS", obj_len_max, "REGION", "PARENT"); end = BU_PTBL_LEN(&results2); if (descending_sort_flag) { start = end - 1; end = -1; incr = -1; } else { start = 0; incr = 1; } for (i = start; i != end; i += incr) { if (regions[i].ignore) { continue; } bu_vls_printf(output, "%-*s %-*s %-*s %-*s %s\n", region_id_len_max + 1, regions[i].region_id, material_id_len_max + 1, regions[i].material_id, los_len_max, regions[i].los, obj_len_max, regions[i].obj_name, regions[i].obj_parent); } bu_vls_printf(gedp->ged_result_str, "Done.\n"); if (file_name) { bu_vls_fwrite(outfile, output); fclose(outfile); } bu_free(regions, "ged_lc"); return GED_OK; }
int ged_dbcopy(struct ged *from_gedp, struct ged *to_gedp, const char *from, const char *to, int fflag) { struct directory *from_dp; struct bu_external external; GED_CHECK_DATABASE_OPEN(from_gedp, GED_ERROR); GED_CHECK_DATABASE_OPEN(to_gedp, GED_ERROR); GED_CHECK_READ_ONLY(to_gedp, GED_ERROR); /* initialize result */ bu_vls_trunc(from_gedp->ged_result_str, 0); bu_vls_trunc(to_gedp->ged_result_str, 0); GED_DB_LOOKUP(from_gedp, from_dp, from, LOOKUP_NOISY, GED_ERROR & GED_QUIET); if (!fflag && db_lookup(to_gedp->ged_wdbp->dbip, to, LOOKUP_QUIET) != RT_DIR_NULL) { bu_vls_printf(from_gedp->ged_result_str, "%s already exists.", to); return GED_ERROR; } if (db_get_external(&external, from_dp, from_gedp->ged_wdbp->dbip)) { bu_vls_printf(from_gedp->ged_result_str, "Database read error, aborting\n"); return GED_ERROR; } if (wdb_export_external(to_gedp->ged_wdbp, &external, to, from_dp->d_flags, from_dp->d_minor_type) < 0) { bu_free_external(&external); bu_vls_printf(from_gedp->ged_result_str, "Failed to write new object (%s) to database - aborting!!\n", to); return GED_ERROR; } bu_free_external(&external); /* Need to do something extra for _GLOBAL */ if (db_version(to_gedp->ged_wdbp->dbip) > 4 && BU_STR_EQUAL(to, DB5_GLOBAL_OBJECT_NAME)) { struct directory *to_dp; struct bu_attribute_value_set avs; const char *val; GED_DB_LOOKUP(to_gedp, to_dp, to, LOOKUP_NOISY, GED_ERROR & GED_QUIET); bu_avs_init_empty(&avs); if (db5_get_attributes(to_gedp->ged_wdbp->dbip, &avs, to_dp)) { bu_vls_printf(from_gedp->ged_result_str, "Cannot get attributes for object %s\n", to_dp->d_namep); return GED_ERROR; } if ((val = bu_avs_get(&avs, "title")) != NULL) to_gedp->ged_wdbp->dbip->dbi_title = strdup(val); if ((val = bu_avs_get(&avs, "units")) != NULL) { double loc2mm; if ((loc2mm = bu_mm_value(val)) > 0) { to_gedp->ged_wdbp->dbip->dbi_local2base = loc2mm; to_gedp->ged_wdbp->dbip->dbi_base2local = 1.0 / loc2mm; } } if ((val = bu_avs_get(&avs, "regionid_colortable")) != NULL) { rt_color_free(); db5_import_color_table((char *)val); } bu_avs_free(&avs); } return GED_OK; }
int ged_concat(struct ged *gedp, int argc, const char *argv[]) { struct db_i *newdbp; struct directory *dp; Tcl_HashTable name_tbl; Tcl_HashTable used_names_tbl; Tcl_HashEntry *ptr; Tcl_HashSearch search; struct bu_attribute_value_set g_avs; const char *cp; char *colorTab; struct ged_concat_data cc_data; const char *oldfile; static const char *usage = "[-u] [-t] [-c] [-s|-p] file.g [suffix|prefix]"; int importUnits = 0; int importTitle = 0; int importColorTable = 0; int saveGlobalAttrs = 0; int c; const char *commandName; 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); if (argc < 2) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } bu_vls_init(&cc_data.affix); cc_data.copy_mode = 0; commandName = argv[0]; /* process args */ bu_optind = 1; bu_opterr = 0; while ((c=bu_getopt(argc, (char * const *)argv, "utcsp")) != -1) { switch (c) { case 'u': importUnits = 1; break; case 't': importTitle = 1; break; case 'c': importColorTable = 1; break; case 'p': cc_data.copy_mode |= AUTO_PREFIX; break; case 's': cc_data.copy_mode |= AUTO_SUFFIX; break; default: { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", commandName, usage); bu_vls_free(&cc_data.affix); return GED_ERROR; } } } argc -= bu_optind; argv += bu_optind; if (argc == 0) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", commandName, usage); return GED_ERROR; } oldfile = argv[0]; argc--; argv++; if (cc_data.copy_mode) { /* specified suffix or prefix explicitly */ if (cc_data.copy_mode & AUTO_PREFIX) { if (argc == 0 || BU_STR_EQUAL(argv[0], "/")) { cc_data.copy_mode = NO_AFFIX | CUSTOM_PREFIX; } else { (void)bu_vls_strcpy(&cc_data.affix, argv[0]); cc_data.copy_mode |= CUSTOM_PREFIX; } } else if (cc_data.copy_mode & AUTO_SUFFIX) { if (argc == 0 || BU_STR_EQUAL(argv[0], "/")) { cc_data.copy_mode = NO_AFFIX | CUSTOM_SUFFIX; } else { (void)bu_vls_strcpy(&cc_data.affix, argv[0]); cc_data.copy_mode |= CUSTOM_SUFFIX; } } else { bu_vls_free(&cc_data.affix); bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", commandName, usage); return GED_ERROR; } } else { /* no prefix/suffix preference, use prefix */ cc_data.copy_mode |= AUTO_PREFIX; if (argc == 0 || BU_STR_EQUAL(argv[0], "/")) { cc_data.copy_mode = NO_AFFIX | CUSTOM_PREFIX; } else { (void)bu_vls_strcpy(&cc_data.affix, argv[0]); cc_data.copy_mode |= CUSTOM_PREFIX; } } if (db_version(gedp->ged_wdbp->dbip) < 5) { if (bu_vls_strlen(&cc_data.affix) > _GED_V4_MAXNAME-1) { bu_log("ERROR: affix [%s] is too long for v%d\n", bu_vls_addr(&cc_data.affix), db_version(gedp->ged_wdbp->dbip)); bu_vls_free(&cc_data.affix); return GED_ERROR; } } /* open the input file */ if ((newdbp = db_open(oldfile, DB_OPEN_READONLY)) == DBI_NULL) { bu_vls_free(&cc_data.affix); perror(oldfile); bu_vls_printf(gedp->ged_result_str, "%s: Can't open geometry database file %s", commandName, oldfile); return GED_ERROR; } if (db_version(newdbp) > 4 && db_version(gedp->ged_wdbp->dbip) < 5) { bu_vls_free(&cc_data.affix); bu_vls_printf(gedp->ged_result_str, "%s: databases are incompatible, use dbupgrade on %s first", commandName, gedp->ged_wdbp->dbip->dbi_filename); return GED_ERROR; } db_dirbuild(newdbp); cc_data.new_dbip = newdbp; cc_data.old_dbip = gedp->ged_wdbp->dbip; /* visit each directory pointer in the input database */ Tcl_InitHashTable(&name_tbl, TCL_STRING_KEYS); Tcl_InitHashTable(&used_names_tbl, TCL_STRING_KEYS); if (importUnits || importTitle || importColorTable) { saveGlobalAttrs = 1; } FOR_ALL_DIRECTORY_START(dp, newdbp) { if (dp->d_major_type == DB5_MAJORTYPE_ATTRIBUTE_ONLY) { if (saveGlobalAttrs) { if (db5_get_attributes(newdbp, &g_avs, dp)) { bu_vls_printf(gedp->ged_result_str, "%s: Can't get global attributes from %s", commandName, oldfile); return GED_ERROR; } } continue; } copy_object(gedp, dp, newdbp, gedp->ged_wdbp->dbip, &name_tbl, &used_names_tbl, &cc_data); } FOR_ALL_DIRECTORY_END; bu_vls_free(&cc_data.affix); rt_mempurge(&(newdbp->dbi_freep)); /* Free all the directory entries, and close the input database */ db_close(newdbp); if (importColorTable) { colorTab = bu_strdup(bu_avs_get(&g_avs, "regionid_colortable")); db5_import_color_table(colorTab); bu_free(colorTab, "colorTab"); } else if (saveGlobalAttrs) { bu_avs_remove(&g_avs, "regionid_colortable"); } if (importTitle) { if ((cp = bu_avs_get(&g_avs, "title")) != NULL) { char *oldTitle = gedp->ged_wdbp->dbip->dbi_title; gedp->ged_wdbp->dbip->dbi_title = bu_strdup(cp); if (oldTitle) { bu_free(oldTitle, "old title"); } } } else if (saveGlobalAttrs) { bu_avs_remove(&g_avs, "title"); } if (importUnits) { if ((cp = bu_avs_get(&g_avs, "units")) != NULL) { double dd; if (sscanf(cp, "%lf", &dd) != 1 || NEAR_ZERO(dd, VUNITIZE_TOL)) { bu_log("copy_object(%s): improper database, %s object attribute 'units'=%s is invalid\n", oldfile, DB5_GLOBAL_OBJECT_NAME, cp); bu_avs_remove(&g_avs, "units"); } else { gedp->ged_wdbp->dbip->dbi_local2base = dd; gedp->ged_wdbp->dbip->dbi_base2local = 1 / dd; } } } else if (saveGlobalAttrs) { bu_avs_remove(&g_avs, "units"); } if (saveGlobalAttrs) { dp = db_lookup(gedp->ged_wdbp->dbip, DB5_GLOBAL_OBJECT_NAME, LOOKUP_NOISY); db5_update_attributes(dp, &g_avs, gedp->ged_wdbp->dbip); } db_sync(gedp->ged_wdbp->dbip); /* force changes to disk */ /* Free the Hash tables */ ptr = Tcl_FirstHashEntry(&name_tbl, &search); while (ptr) { bu_free((char *)Tcl_GetHashValue(ptr), "new name"); ptr = Tcl_NextHashEntry(&search); } Tcl_DeleteHashTable(&name_tbl); Tcl_DeleteHashTable(&used_names_tbl); return GED_OK; }
struct bu_ptbl * db_lookup_by_attr(struct db_i *dbip, int dir_flags, struct bu_attribute_value_set *avs, int op) { struct bu_attribute_value_set obj_avs; struct directory *dp; struct bu_ptbl *tbl; int match_count = 0; int attr_count; int i, j; int draw; RT_CK_DBI(dbip); if (avs) { BU_CK_AVS(avs); attr_count = avs->count; } else { attr_count = 0; } BU_ALLOC(tbl, struct bu_ptbl); bu_ptbl_init(tbl, 128, "wdb_get_by_attr ptbl_init"); FOR_ALL_DIRECTORY_START(dp, dbip) { if ((dp->d_flags & dir_flags) == 0) continue; /* Skip phony entries */ if (dp->d_addr == RT_DIR_PHONY_ADDR) continue; if (attr_count) { bu_avs_init_empty(&obj_avs); if (db5_get_attributes(dbip, &obj_avs, dp) < 0) { bu_log("ERROR: failed to get attributes for %s\n", dp->d_namep); return (struct bu_ptbl *)NULL; } draw = 0; match_count = 0; for (i = 0; (size_t)i < (size_t)avs->count; i++) { for (j = 0; (size_t)j < (size_t)obj_avs.count; j++) { if (BU_STR_EQUAL(avs->avp[i].name, obj_avs.avp[j].name)) { if (BU_STR_EQUAL(avs->avp[i].value, obj_avs.avp[j].value)) { if (op == 2) { draw = 1; break; } else { match_count++; } } } } if (draw) break; } bu_avs_free(&obj_avs); } else { draw = 1; } if (draw || match_count == attr_count) { bu_ptbl_ins(tbl, (long *)dp); } } FOR_ALL_DIRECTORY_END; return tbl; }