BRL-CAD
concat.c
Go to the documentation of this file.
1 /* C O N C A T . C
2  * BRL-CAD
3  *
4  * Copyright (c) 2008-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 /** @file libged/concat.c
21  *
22  * The concat command.
23  *
24  */
25 
26 #include "common.h"
27 
28 #include <string.h>
29 
30 #include "bu/cmd.h"
31 #include "bu/getopt.h"
32 #include "rtgeom.h"
33 
34 #include "./ged_private.h"
35 
36 
37 /**
38  * structure used by the dbconcat command for keeping tract of where
39  * objects are being copied to and from, and what type of affix to
40  * use.
41  */
43  int copy_mode;
44  struct db_i *old_dbip;
45  struct db_i *new_dbip;
46  struct bu_vls affix;
47 };
48 
49 
50 #define NO_AFFIX 1<<0
51 #define AUTO_PREFIX 1<<1
52 #define AUTO_SUFFIX 1<<2
53 #define CUSTOM_PREFIX 1<<3
54 #define CUSTOM_SUFFIX 1<<4
55 
56 
57 /**
58  * find a new unique name given a list of previously used names, and
59  * the type of naming mode that described what type of affix to use.
60  */
61 static char *
62 get_new_name(const char *name,
63  struct db_i *dbip,
64  Tcl_HashTable *name_tbl,
65  Tcl_HashTable *used_names_tbl,
66  struct ged_concat_data *cc_data)
67 {
68  struct bu_vls new_name = BU_VLS_INIT_ZERO;
69  Tcl_HashEntry *ptr = NULL;
70  char *aname = NULL;
71  char *ret_name = NULL;
72  int int_new=0;
73  long num=0;
74 
75  RT_CK_DBI(dbip);
76  BU_ASSERT(name_tbl);
77  BU_ASSERT(used_names_tbl);
78  BU_ASSERT(cc_data);
79 
80  if (!name) {
81  bu_log("WARNING: encountered NULL name, renaming to \"UNKNOWN\"\n");
82  name = "UNKNOWN";
83  }
84 
85  ptr = Tcl_CreateHashEntry(name_tbl, name, &int_new);
86 
87  if (!int_new) {
88  return (char *)Tcl_GetHashValue(ptr);
89  }
90 
91  do {
92  /* iterate until we find an object name that is not in
93  * use, trying to accommodate the user's requested affix
94  * naming mode.
95  */
96 
97  bu_vls_trunc(&new_name, 0);
98 
99  if (cc_data->copy_mode & NO_AFFIX) {
100  if (num > 0 && cc_data->copy_mode & CUSTOM_PREFIX) {
101  /* auto-increment prefix */
102  bu_vls_printf(&new_name, "%ld_", num);
103  }
104  bu_vls_strcat(&new_name, name);
105  if (num > 0 && cc_data->copy_mode & CUSTOM_SUFFIX) {
106  /* auto-increment suffix */
107  bu_vls_printf(&new_name, "_%ld", num);
108  }
109  } else if (cc_data->copy_mode & CUSTOM_SUFFIX) {
110  /* use custom suffix */
111  bu_vls_strcpy(&new_name, name);
112  if (num > 0) {
113  bu_vls_printf(&new_name, "_%ld_", num);
114  }
115  bu_vls_vlscat(&new_name, &cc_data->affix);
116  } else if (cc_data->copy_mode & CUSTOM_PREFIX) {
117  /* use custom prefix */
118  bu_vls_vlscat(&new_name, &cc_data->affix);
119  if (num > 0) {
120  bu_vls_printf(&new_name, "_%ld_", num);
121  }
122  bu_vls_strcat(&new_name, name);
123  } else if (cc_data->copy_mode & AUTO_SUFFIX) {
124  /* use auto-incrementing suffix */
125  bu_vls_strcat(&new_name, name);
126  bu_vls_printf(&new_name, "_%ld", num);
127  } else if (cc_data->copy_mode & AUTO_PREFIX) {
128  /* use auto-incrementing prefix */
129  bu_vls_printf(&new_name, "%ld_", num);
130  bu_vls_strcat(&new_name, name);
131  } else {
132  /* no custom suffix/prefix specified, use prefix */
133  if (num > 0) {
134  bu_vls_printf(&new_name, "_%ld", num);
135  }
136  bu_vls_strcpy(&new_name, name);
137  }
138 
139  /* make sure it fits for v4 */
140  if (db_version(cc_data->old_dbip) < 5) {
141  if (bu_vls_strlen(&new_name) > _GED_V4_MAXNAME) {
142  bu_log("ERROR: generated new name [%s] is too long (%zu > %d)\n", bu_vls_addr(&new_name), bu_vls_strlen(&new_name), _GED_V4_MAXNAME);
143  }
144  return NULL;
145  }
146  aname = bu_vls_addr(&new_name);
147 
148  num++;
149 
150  } while (db_lookup(dbip, aname, LOOKUP_QUIET) != RT_DIR_NULL ||
151  Tcl_FindHashEntry(used_names_tbl, aname) != NULL);
152 
153  /* if they didn't get what they asked for, warn them */
154  if (num > 1) {
155  if (cc_data->copy_mode & NO_AFFIX) {
156  bu_log("WARNING: unable to import [%s] without an affix, imported as [%s]\n", name, bu_vls_addr(&new_name));
157  } else if (cc_data->copy_mode & CUSTOM_SUFFIX) {
158  bu_log("WARNING: unable to import [%s] as [%s%s], imported as [%s]\n", name, name, bu_vls_addr(&cc_data->affix), bu_vls_addr(&new_name));
159  } else if (cc_data->copy_mode & CUSTOM_PREFIX) {
160  bu_log("WARNING: unable to import [%s] as [%s%s], imported as [%s]\n", name, bu_vls_addr(&cc_data->affix), name, bu_vls_addr(&new_name));
161  }
162  }
163 
164  /* we should now have a unique name. store it in the hash */
165  ret_name = bu_vls_strgrab(&new_name);
166  Tcl_SetHashValue(ptr, (ClientData)ret_name);
167  (void)Tcl_CreateHashEntry(used_names_tbl, ret_name, &int_new);
168  bu_vls_free(&new_name);
169 
170  return ret_name;
171 }
172 
173 
174 static void
175 adjust_names(union tree *trp,
176  struct db_i *dbip,
177  Tcl_HashTable *name_tbl,
178  Tcl_HashTable *used_names_tbl,
179  struct ged_concat_data *cc_data)
180 {
181  char *new_name;
182 
183  if (trp == NULL) {
184  return;
185  }
186 
187  switch (trp->tr_op) {
188  case OP_DB_LEAF:
189  new_name = get_new_name(trp->tr_l.tl_name, dbip,
190  name_tbl, used_names_tbl, cc_data);
191  if (new_name) {
192  bu_free(trp->tr_l.tl_name, "leaf name");
193  trp->tr_l.tl_name = bu_strdup(new_name);
194  }
195  break;
196  case OP_UNION:
197  case OP_INTERSECT:
198  case OP_SUBTRACT:
199  case OP_XOR:
200  adjust_names(trp->tr_b.tb_left, dbip,
201  name_tbl, used_names_tbl, cc_data);
202  adjust_names(trp->tr_b.tb_right, dbip,
203  name_tbl, used_names_tbl, cc_data);
204  break;
205  case OP_NOT:
206  case OP_GUARD:
207  case OP_XNOP:
208  adjust_names(trp->tr_b.tb_left, dbip,
209  name_tbl, used_names_tbl, cc_data);
210  break;
211  }
212 }
213 
214 
215 static int
216 copy_object(struct ged *gedp,
217  struct directory *input_dp,
218  struct db_i *input_dbip,
219  struct db_i *curr_dbip,
220  Tcl_HashTable *name_tbl,
221  Tcl_HashTable *used_names_tbl,
222  struct ged_concat_data *cc_data)
223 {
224  struct rt_db_internal ip;
225  struct rt_extrude_internal *extr;
226  struct rt_dsp_internal *dsp;
227  struct rt_comb_internal *comb;
228  struct directory *new_dp;
229  char *new_name;
230 
231  if (rt_db_get_internal(&ip, input_dp, input_dbip, NULL, &rt_uniresource) < 0) {
233  "Failed to get internal form of object (%s) - aborting!!!\n",
234  input_dp->d_namep);
235  return GED_ERROR;
236  }
237 
238  if (ip.idb_major_type == DB5_MAJORTYPE_BRLCAD) {
239  /* adjust names of referenced object in any object that reference other objects */
240  switch (ip.idb_minor_type) {
241  case DB5_MINORTYPE_BRLCAD_COMBINATION:
242  comb = (struct rt_comb_internal *)ip.idb_ptr;
243  RT_CK_COMB(comb);
244  adjust_names(comb->tree, curr_dbip, name_tbl, used_names_tbl, cc_data);
245  break;
246  case DB5_MINORTYPE_BRLCAD_EXTRUDE:
247  extr = (struct rt_extrude_internal *)ip.idb_ptr;
248  RT_EXTRUDE_CK_MAGIC(extr);
249 
250  new_name = get_new_name(extr->sketch_name, curr_dbip, name_tbl, used_names_tbl, cc_data);
251  if (new_name) {
252  bu_free(extr->sketch_name, "sketch name");
253  extr->sketch_name = bu_strdup(new_name);
254  }
255  break;
256  case DB5_MINORTYPE_BRLCAD_DSP:
257  dsp = (struct rt_dsp_internal *)ip.idb_ptr;
258  RT_DSP_CK_MAGIC(dsp);
259 
260  if (dsp->dsp_datasrc == RT_DSP_SRC_OBJ) {
261  /* This dsp references a database object, may need to change its name */
262  new_name = get_new_name(bu_vls_addr(&dsp->dsp_name), curr_dbip,
263  name_tbl, used_names_tbl, cc_data);
264  if (new_name) {
265  bu_vls_free(&dsp->dsp_name);
266  bu_vls_strcpy(&dsp->dsp_name, new_name);
267  }
268  }
269  break;
270  }
271  }
272 
273  new_name = get_new_name(input_dp->d_namep, curr_dbip, name_tbl, used_names_tbl, cc_data);
274  if (!new_name) {
275  new_name = input_dp->d_namep;
276  }
277  if ((new_dp = db_diradd(curr_dbip, new_name, RT_DIR_PHONY_ADDR, 0, input_dp->d_flags,
278  (void *)&input_dp->d_minor_type)) == RT_DIR_NULL) {
280  "Failed to add new object name (%s) to directory - aborting!!\n",
281  new_name);
282  return GED_ERROR;
283  }
284 
285  if (rt_db_put_internal(new_dp, curr_dbip, &ip, &rt_uniresource) < 0) {
287  "Failed to write new object (%s) to database - aborting!!\n",
288  new_name);
289  return GED_ERROR;
290  }
291 
292  return GED_OK;
293 }
294 
295 
296 int
297 ged_concat(struct ged *gedp, int argc, const char *argv[])
298 {
299  struct db_i *newdbp;
300  struct directory *dp;
301  Tcl_HashTable name_tbl;
302  Tcl_HashTable used_names_tbl;
303  Tcl_HashEntry *ptr;
304  Tcl_HashSearch search;
305  struct bu_attribute_value_set g_avs;
306  const char *cp;
307  char *colorTab;
308  struct ged_concat_data cc_data;
309  const char *oldfile;
310  static const char *usage = "[-u] [-t] [-c] [-s|-p] file.g [suffix|prefix]";
311  int importUnits = 0;
312  int importTitle = 0;
313  int importColorTable = 0;
314  int saveGlobalAttrs = 0;
315  int c;
316  const char *commandName;
317 
320  GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
321 
322  /* initialize result */
323  bu_vls_trunc(gedp->ged_result_str, 0);
324 
325  if (argc < 2) {
326  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
327  return GED_ERROR;
328  }
329 
330  bu_vls_init(&cc_data.affix);
331  cc_data.copy_mode = 0;
332  commandName = argv[0];
333 
334  /* process args */
335  bu_optind = 1;
336  bu_opterr = 0;
337  while ((c=bu_getopt(argc, (char * const *)argv, "utcsp")) != -1) {
338  switch (c) {
339  case 'u':
340  importUnits = 1;
341  break;
342  case 't':
343  importTitle = 1;
344  break;
345  case 'c':
346  importColorTable = 1;
347  break;
348  case 'p':
349  cc_data.copy_mode |= AUTO_PREFIX;
350  break;
351  case 's':
352  cc_data.copy_mode |= AUTO_SUFFIX;
353  break;
354  default: {
355  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", commandName, usage);
356  bu_vls_free(&cc_data.affix);
357  return GED_ERROR;
358  }
359  }
360  }
361  argc -= bu_optind;
362  argv += bu_optind;
363 
364  if (argc == 0) {
365  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", commandName, usage);
366  return GED_ERROR;
367  }
368 
369  oldfile = argv[0];
370 
371  argc--;
372  argv++;
373 
374  if (cc_data.copy_mode) {
375  /* specified suffix or prefix explicitly */
376 
377  if (cc_data.copy_mode & AUTO_PREFIX) {
378 
379  if (argc == 0 || BU_STR_EQUAL(argv[0], "/")) {
380  cc_data.copy_mode = NO_AFFIX | CUSTOM_PREFIX;
381  } else {
382  (void)bu_vls_strcpy(&cc_data.affix, argv[0]);
383  cc_data.copy_mode |= CUSTOM_PREFIX;
384  }
385 
386  } else if (cc_data.copy_mode & AUTO_SUFFIX) {
387 
388  if (argc == 0 || BU_STR_EQUAL(argv[0], "/")) {
389  cc_data.copy_mode = NO_AFFIX | CUSTOM_SUFFIX;
390  } else {
391  (void)bu_vls_strcpy(&cc_data.affix, argv[0]);
392  cc_data.copy_mode |= CUSTOM_SUFFIX;
393  }
394 
395  } else {
396  bu_vls_free(&cc_data.affix);
397  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", commandName, usage);
398  return GED_ERROR;
399  }
400 
401  } else {
402  /* no prefix/suffix preference, use prefix */
403 
404  cc_data.copy_mode |= AUTO_PREFIX;
405 
406  if (argc == 0 || BU_STR_EQUAL(argv[0], "/")) {
407  cc_data.copy_mode = NO_AFFIX | CUSTOM_PREFIX;
408  } else {
409  (void)bu_vls_strcpy(&cc_data.affix, argv[0]);
410  cc_data.copy_mode |= CUSTOM_PREFIX;
411  }
412 
413  }
414 
415  if (db_version(gedp->ged_wdbp->dbip) < 5) {
416  if (bu_vls_strlen(&cc_data.affix) > _GED_V4_MAXNAME-1) {
417  bu_log("ERROR: affix [%s] is too long for v%d\n", bu_vls_addr(&cc_data.affix), db_version(gedp->ged_wdbp->dbip));
418  bu_vls_free(&cc_data.affix);
419  return GED_ERROR;
420  }
421  }
422 
423  /* open the input file */
424  if ((newdbp = db_open(oldfile, DB_OPEN_READONLY)) == DBI_NULL) {
425  bu_vls_free(&cc_data.affix);
426  perror(oldfile);
427  bu_vls_printf(gedp->ged_result_str, "%s: Can't open geometry database file %s", commandName, oldfile);
428  return GED_ERROR;
429  }
430 
431  if (db_version(newdbp) > 4 && db_version(gedp->ged_wdbp->dbip) < 5) {
432  bu_vls_free(&cc_data.affix);
433  bu_vls_printf(gedp->ged_result_str, "%s: databases are incompatible, use dbupgrade on %s first",
434  commandName, gedp->ged_wdbp->dbip->dbi_filename);
435  return GED_ERROR;
436  }
437 
438  db_dirbuild(newdbp);
439 
440  cc_data.new_dbip = newdbp;
441  cc_data.old_dbip = gedp->ged_wdbp->dbip;
442 
443  /* visit each directory pointer in the input database */
444  Tcl_InitHashTable(&name_tbl, TCL_STRING_KEYS);
445  Tcl_InitHashTable(&used_names_tbl, TCL_STRING_KEYS);
446 
447  if (importUnits || importTitle || importColorTable) {
448  saveGlobalAttrs = 1;
449  }
450  FOR_ALL_DIRECTORY_START(dp, newdbp) {
451  if (dp->d_major_type == DB5_MAJORTYPE_ATTRIBUTE_ONLY) {
452  if (saveGlobalAttrs) {
453  if (db5_get_attributes(newdbp, &g_avs, dp)) {
454  bu_vls_printf(gedp->ged_result_str, "%s: Can't get global attributes from %s", commandName, oldfile);
455  return GED_ERROR;
456  }
457  }
458  continue;
459  }
460  copy_object(gedp, dp, newdbp, gedp->ged_wdbp->dbip, &name_tbl, &used_names_tbl, &cc_data);
462 
463  bu_vls_free(&cc_data.affix);
464  rt_mempurge(&(newdbp->dbi_freep));
465 
466  /* Free all the directory entries, and close the input database */
467  db_close(newdbp);
468 
469  if (importColorTable) {
470  if ((cp = bu_avs_get(&g_avs, "regionid_colortable")) != NULL) {
471  colorTab = bu_strdup(cp);
472  db5_import_color_table(colorTab);
473  bu_free(colorTab, "colorTab");
474  } else {
475  bu_vls_printf(gedp->ged_result_str, "%s: no region color table "
476  "was found in %s to import\n", commandName, oldfile);
477  }
478  } else if (saveGlobalAttrs) {
479  bu_avs_remove(&g_avs, "regionid_colortable");
480  }
481 
482  if (importTitle) {
483  if ((cp = bu_avs_get(&g_avs, "title")) != NULL) {
484  char *oldTitle = gedp->ged_wdbp->dbip->dbi_title;
485  gedp->ged_wdbp->dbip->dbi_title = bu_strdup(cp);
486  if (oldTitle) {
487  bu_free(oldTitle, "old title");
488  }
489  } else {
491  "%s: no title was found in %s to import\n", commandName,
492  oldfile);
493  }
494  } else if (saveGlobalAttrs) {
495  bu_avs_remove(&g_avs, "title");
496  }
497 
498  if (importUnits) {
499  if ((cp = bu_avs_get(&g_avs, "units")) != NULL) {
500  double dd;
501  if (sscanf(cp, "%lf", &dd) != 1 || NEAR_ZERO(dd, VUNITIZE_TOL)) {
502  bu_log("copy_object(%s): improper database, %s object attribute 'units'=%s is invalid\n",
503  oldfile, DB5_GLOBAL_OBJECT_NAME, cp);
504  bu_avs_remove(&g_avs, "units");
505  } else {
506  gedp->ged_wdbp->dbip->dbi_local2base = dd;
507  gedp->ged_wdbp->dbip->dbi_base2local = 1 / dd;
508  }
509  } else {
511  "%s: no units were found in %s to import\n", commandName,
512  oldfile);
513  }
514  } else if (saveGlobalAttrs) {
515  bu_avs_remove(&g_avs, "units");
516  }
517 
518  if (saveGlobalAttrs) {
519  dp = db_lookup(gedp->ged_wdbp->dbip, DB5_GLOBAL_OBJECT_NAME, LOOKUP_NOISY);
520  db5_update_attributes(dp, &g_avs, gedp->ged_wdbp->dbip);
521  }
522 
523  db_sync(gedp->ged_wdbp->dbip); /* force changes to disk */
524 
525  /* Free the Hash tables */
526  ptr = Tcl_FirstHashEntry(&name_tbl, &search);
527  while (ptr) {
528  bu_free((char *)Tcl_GetHashValue(ptr), "new name");
529  ptr = Tcl_NextHashEntry(&search);
530  }
531  Tcl_DeleteHashTable(&name_tbl);
532  Tcl_DeleteHashTable(&used_names_tbl);
533 
534  return GED_OK;
535 }
536 
537 
538 /*
539  * Local Variables:
540  * tab-width: 8
541  * mode: C
542  * indent-tabs-mode: t
543  * c-file-style: "stroustrup"
544  * End:
545  * ex: shiftwidth=4 tabstop=8
546  */
void usage(struct ged *gedp)
Definition: coil.c:315
void bu_vls_init(struct bu_vls *vp)
Definition: vls.c:56
#define GED_OK
Definition: ged.h:55
char * d_namep
pointer to name string
Definition: raytrace.h:859
void rt_mempurge(struct mem_map **pp)
Definition: memalloc.c:316
Definition: raytrace.h:800
#define FOR_ALL_DIRECTORY_START(_dp, _dbip)
Definition: raytrace.h:895
unsigned char d_major_type
object major type
Definition: raytrace.h:870
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
int rt_db_get_internal(struct rt_db_internal *ip, const struct directory *dp, const struct db_i *dbip, const mat_t mat, struct resource *resp)
Definition: dir.c:76
int rt_db_put_internal(struct directory *dp, struct db_i *dbip, struct rt_db_internal *ip, struct resource *resp)
Definition: dir.c:136
int db5_update_attributes(struct directory *dp, struct bu_attribute_value_set *avsp, struct db_i *dbip)
Definition: attributes.c:285
Definition: ged.h:338
struct db_i * dbip
Definition: raytrace.h:1266
Definition: clone.c:90
void bu_vls_strcat(struct bu_vls *vp, const char *s)
Definition: vls.c:368
#define OP_XOR
Binary: L xor R, not both.
Definition: raytrace.h:1130
void bu_vls_trunc(struct bu_vls *vp, int len)
Definition: vls.c:198
#define GED_CHECK_ARGC_GT_0(_gedp, _argc, _flags)
Definition: ged.h:202
struct directory * db_lookup(const struct db_i *, const char *name, int noisy)
Definition: db_lookup.c:153
int db_version(struct db_i *dbip)
Definition: db5_scan.c:414
#define RT_CK_COMB(_p)
Definition: raytrace.h:955
#define FOR_ALL_DIRECTORY_END
Definition: raytrace.h:899
struct bu_vls affix
Definition: concat.c:46
struct rt_wdb * ged_wdbp
Definition: ged.h:340
Header file for the BRL-CAD common definitions.
int bu_optind
Definition: globals.c:89
#define OP_XNOP
Unary: L, mark region.
Definition: raytrace.h:1136
#define BU_ASSERT(_equation)
Definition: defines.h:216
int bu_getopt(int nargc, char *const nargv[], const char *ostr)
Definition: getopt.c:43
#define GED_ERROR
Definition: ged.h:61
union tree * tb_left
Definition: raytrace.h:1149
#define _GED_V4_MAXNAME
Definition: ged_private.h:48
const char * bu_avs_get(const struct bu_attribute_value_set *avp, const char *attribute)
Definition: avs.c:172
#define CUSTOM_SUFFIX
Definition: concat.c:54
#define AUTO_PREFIX
Definition: concat.c:51
void bu_vls_free(struct bu_vls *vp)
Definition: vls.c:248
unsigned char d_minor_type
object minor type
Definition: raytrace.h:871
#define OP_SUBTRACT
Binary: L subtract R.
Definition: raytrace.h:1129
int copy_mode
Definition: concat.c:43
struct resource rt_uniresource
default. Defined in librt/globals.c
Definition: globals.c:41
#define OP_INTERSECT
Binary: L intersect R.
Definition: raytrace.h:1128
#define GED_CHECK_DATABASE_OPEN(_gedp, _flags)
Definition: ged.h:114
char * dbi_title
title from IDENT rec
Definition: raytrace.h:809
#define OP_DB_LEAF
Leaf of combination, db fmt.
Definition: raytrace.h:1139
#define NO_AFFIX
Definition: concat.c:50
char * bu_vls_strgrab(struct bu_vls *vp)
Definition: vls.c:290
int bu_avs_remove(struct bu_attribute_value_set *avp, const char *attribute)
Definition: avs.c:195
#define LOOKUP_QUIET
Definition: raytrace.h:893
#define NEAR_ZERO(val, epsilon)
Definition: color.c:55
#define CUSTOM_PREFIX
Definition: concat.c:53
#define RT_DIR_PHONY_ADDR
Special marker for d_addr field.
Definition: raytrace.h:879
#define AUTO_SUFFIX
Definition: concat.c:52
size_t bu_vls_strlen(const struct bu_vls *vp)
Definition: vls.c:189
char * tl_name
Name of this leaf (bu_strdup'ed)
Definition: raytrace.h:1174
struct tree::tree_node tr_b
void db_close(struct db_i *dbip)
#define OP_GUARD
Unary: not L, or else!
Definition: raytrace.h:1135
struct mem_map * dbi_freep
PRIVATE: map of free granules.
Definition: raytrace.h:819
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
struct bu_vls * ged_result_str
Definition: ged.h:357
double dbi_base2local
unit conversion factors
Definition: raytrace.h:808
void db5_import_color_table(char *cp)
Definition: db5_io.c:996
#define RT_CK_DBI(_p)
Definition: raytrace.h:829
struct directory * db_diradd(struct db_i *, const char *name, off_t laddr, size_t len, int flags, void *ptr)
Definition: db_lookup.c:190
struct tree::tree_db_leaf tr_l
union tree * tb_right
Definition: raytrace.h:1150
#define DBI_NULL
Definition: raytrace.h:827
int bu_opterr
Definition: globals.c:88
union tree * tree
Leading to tree_db_leaf leaves.
Definition: raytrace.h:938
void bu_vls_printf(struct bu_vls *vls, const char *fmt,...) _BU_ATTR_PRINTF23
Definition: vls.c:694
#define RT_DIR_NULL
Definition: raytrace.h:875
#define LOOKUP_NOISY
Definition: raytrace.h:892
void * ptr
ptr to in-memory-only obj
Definition: raytrace.h:862
#define DB_OPEN_READONLY
Definition: raytrace.h:3550
struct db_i * db_open(const char *name, const char *mode)
Definition: db_open.c:59
int ged_concat(struct ged *gedp, int argc, const char *argv[])
Definition: concat.c:297
void bu_vls_strcpy(struct bu_vls *vp, const char *s)
Definition: vls.c:310
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
double dbi_local2base
local2mm
Definition: raytrace.h:807
int db_dirbuild(struct db_i *dbip)
Definition: db5_scan.c:301
struct db_i * new_dbip
Definition: concat.c:45
#define BU_VLS_INIT_ZERO
Definition: vls.h:84
void bu_vls_vlscat(struct bu_vls *dest, const struct bu_vls *src)
Definition: vls.c:415
#define GED_CHECK_READ_ONLY(_gedp, _flags)
Definition: ged.h:181
int db5_get_attributes(const struct db_i *dbip, struct bu_attribute_value_set *avs, const struct directory *dp)
Definition: db5_io.c:1027
int d_flags
flags
Definition: raytrace.h:869
Definition: vls.h:56
char * dbi_filename
file name
Definition: raytrace.h:805
#define OP_UNION
Binary: L union R.
Definition: raytrace.h:1127
void db_sync(struct db_i *dbip)
Definition: db_open.c:434
#define OP_NOT
Unary: not L.
Definition: raytrace.h:1134
struct db_i * old_dbip
Definition: concat.c:44
#define bu_strdup(s)
Definition: str.h:71
#define BU_STR_EQUAL(s1, s2)
Definition: str.h:126