/** * List formats installed in global nirt data directory */ void listformats(void) { size_t files, i; char **filearray = NULL; char suffix[6]="*.nrt"; FILE *cfPtr = NULL; int fnddesc; struct bu_vls nirtfilespath = BU_VLS_INIT_ZERO; struct bu_vls nirtpathtofile = BU_VLS_INIT_ZERO; struct bu_vls vlsfileline = BU_VLS_INIT_ZERO; /* get a nirt directory listing */ bu_vls_printf(&nirtfilespath, "%s", bu_brlcad_data("nirt", 0)); files = bu_dir_list(bu_vls_addr(&nirtfilespath), suffix, &filearray); /* open every nirt file we find and extract the description */ for (i = 0; i < files; i++) { bu_vls_trunc(&nirtpathtofile, 0); bu_vls_trunc(&vlsfileline, 0); bu_vls_printf(&nirtpathtofile, "%s/%s", bu_vls_addr(&nirtfilespath), filearray[i]); cfPtr = fopen(bu_vls_addr(&nirtpathtofile), "rb"); fnddesc = 0; while (bu_vls_gets(&vlsfileline, cfPtr) && fnddesc == 0) { if (bu_strncmp(bu_vls_addr(&vlsfileline), "# Description: ", 15) == 0) { fnddesc = 1; bu_log("%s\n", bu_vls_addr(&vlsfileline)+15); } bu_vls_trunc(&vlsfileline, 0); } fclose(cfPtr); } /* release resources */ bu_free_argv(files, filearray); bu_vls_free(&vlsfileline); bu_vls_free(&nirtfilespath); bu_vls_free(&nirtpathtofile); }
void db_close(register struct db_i *dbip) { register int i; register struct directory *dp, *nextdp; if (!dbip) return; RT_CK_DBI(dbip); if (RT_G_DEBUG&DEBUG_DB) bu_log("db_close(%s) %p uses=%d\n", dbip->dbi_filename, (void *)dbip, dbip->dbi_uses); bu_semaphore_acquire(BU_SEM_LISTS); if ((--dbip->dbi_uses) > 0) { bu_semaphore_release(BU_SEM_LISTS); /* others are still using this database */ return; } bu_semaphore_release(BU_SEM_LISTS); /* ready to free the database -- use count is now zero */ /* free up any mapped files */ if (dbip->dbi_mf) { /* * We're using an instance of a memory mapped file. * We have two choices: * Either dissociate from the memory mapped file * by clearing dbi_mf->apbuf, or * keeping our already-scanned dbip ready for * further use, with our dbi_uses counter at 0. * For speed of re-open, at the price of some address space, * the second choice is taken. */ bu_close_mapped_file(dbip->dbi_mf); bu_free_mapped_files(0); dbip->dbi_mf = (struct bu_mapped_file *)NULL; } /* try to ensure/encourage that the file is written out */ db_sync(dbip); if (dbip->dbi_fp) { fclose(dbip->dbi_fp); } if (dbip->dbi_title) bu_free(dbip->dbi_title, "dbi_title"); if (dbip->dbi_filename) bu_free(dbip->dbi_filename, "dbi_filename"); db_free_anim(dbip); rt_color_free(); /* Free MaterHead list */ /* Release map of database holes */ rt_mempurge(&(dbip->dbi_freep)); rt_memclose(); dbip->dbi_inmem = NULL; /* sanity */ bu_ptbl_free(&dbip->dbi_clients); /* Free all directory entries */ for (i = 0; i < RT_DBNHASH; i++) { for (dp = dbip->dbi_Head[i]; dp != RT_DIR_NULL;) { RT_CK_DIR(dp); nextdp = dp->d_forw; RT_DIR_FREE_NAMEP(dp); /* frees d_namep */ if ((dp->d_flags & RT_DIR_INMEM) && (dp->d_un.ptr != NULL)) { bu_free(dp->d_un.ptr, "db_close d_un.ptr"); dp->d_un.ptr = NULL; dp->d_len = 0; } /* Put 'dp' back on the freelist */ dp->d_forw = rt_uniresource.re_directory_hd; rt_uniresource.re_directory_hd = dp; /* null'ing the forward pointer here is a huge * memory leak as it causes the loss of all * nodes on the freelist except the first. * (so don't do it) */ dp = nextdp; } dbip->dbi_Head[i] = RT_DIR_NULL; /* sanity*/ } if (dbip->dbi_filepath != NULL) { bu_free_argv(2, dbip->dbi_filepath); dbip->dbi_filepath = NULL; /* sanity */ } bu_free((char *)dbip, "struct db_i"); }