BRL-CAD
dup.c
Go to the documentation of this file.
1 /* D U P . 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/dup.c
21  *
22  * The dup command.
23  *
24  */
25 
26 #include "common.h"
27 
28 #include <string.h>
29 
30 #include "bu/cmd.h"
31 
32 #include "./ged_private.h"
33 
34 
36  struct db_i *main_dbip;
37  struct rt_wdb *wdbp;
38  struct directory **dup_dirp;
39 };
40 
41 
42 static void
43 dup_dir_check5(struct db_i *input_dbip,
44  const struct db5_raw_internal *rip,
45  off_t addr,
46  void *ptr)
47 {
48  char *name;
49  struct directory *dupdp;
50  struct bu_vls local = BU_VLS_INIT_ZERO;
51  struct dir_check_stuff *dcsp = (struct dir_check_stuff *)ptr;
52 
53  if (dcsp->main_dbip == DBI_NULL)
54  return;
55 
56  RT_CK_DBI(input_dbip);
57  RT_CK_RIP(rip);
58 
59  if (rip->h_dli == DB5HDR_HFLAGS_DLI_HEADER_OBJECT) return;
60  if (rip->h_dli == DB5HDR_HFLAGS_DLI_FREE_STORAGE) return;
61 
62  name = (char *)rip->name.ext_buf;
63 
64  if (name == (char *)NULL) return;
65  if (addr == 0) return;
66 
67  /* do not compare _GLOBAL */
68  if (rip->major_type == DB5_MAJORTYPE_ATTRIBUTE_ONLY &&
69  rip->minor_type == 0)
70  return;
71 
72  /* Add the prefix, if any */
73  if (db_version(dcsp->main_dbip) < 5) {
74  if (dcsp->wdbp->wdb_ncharadd > 0) {
75  bu_vls_strncpy(&local, bu_vls_addr(&dcsp->wdbp->wdb_prestr), dcsp->wdbp->wdb_ncharadd);
76  bu_vls_strcat(&local, name);
77  } else {
78  bu_vls_strncpy(&local, name, _GED_V4_MAXNAME);
79  }
81  } else {
82  if (dcsp->wdbp->wdb_ncharadd > 0) {
83  (void)bu_vls_vlscat(&local, &dcsp->wdbp->wdb_prestr);
84  (void)bu_vls_strcat(&local, name);
85  } else {
86  (void)bu_vls_strcat(&local, name);
87  }
88  }
89 
90  /* Look up this new name in the existing (main) database */
91  if ((dupdp = db_lookup(dcsp->main_dbip, bu_vls_addr(&local), LOOKUP_QUIET)) != RT_DIR_NULL) {
92  /* Duplicate found, add it to the list */
93  dcsp->wdbp->wdb_num_dups++;
94  *dcsp->dup_dirp++ = dupdp;
95  }
96 
97  bu_vls_free(&local);
98 
99  return;
100 }
101 
102 
103 /**
104  *@brief
105  * Check a name against the global directory.
106  */
107 static int
108 dup_dir_check(struct db_i *input_dbip, const char *name, off_t UNUSED(laddr), size_t UNUSED(len), int UNUSED(flags), void *ptr)
109 {
110  struct directory *dupdp;
111  struct bu_vls local = BU_VLS_INIT_ZERO;
112  struct dir_check_stuff *dcsp = (struct dir_check_stuff *)ptr;
113 
114  if (dcsp->main_dbip == DBI_NULL)
115  return 0;
116 
117  RT_CK_DBI(input_dbip);
118 
119  /* Add the prefix, if any */
120  if (db_version(dcsp->main_dbip) < 5) {
121  if (dcsp->wdbp->wdb_ncharadd > 0) {
122  bu_vls_strncpy(&local, bu_vls_addr(&dcsp->wdbp->wdb_prestr), dcsp->wdbp->wdb_ncharadd);
123  bu_vls_strcat(&local, name);
124  } else {
125  bu_vls_strncpy(&local, name, _GED_V4_MAXNAME);
126  }
127  bu_vls_trunc(&local, _GED_V4_MAXNAME);
128  } else {
129  if (dcsp->wdbp->wdb_ncharadd > 0) {
130  bu_vls_vlscat(&local, &dcsp->wdbp->wdb_prestr);
131  bu_vls_strcat(&local, name);
132  } else {
133  bu_vls_strcat(&local, name);
134  }
135  }
136 
137  /* Look up this new name in the existing (main) database */
138  if ((dupdp = db_lookup(dcsp->main_dbip, bu_vls_addr(&local), LOOKUP_QUIET)) != RT_DIR_NULL) {
139  /* Duplicate found, add it to the list */
140  dcsp->wdbp->wdb_num_dups++;
141  *dcsp->dup_dirp++ = dupdp;
142  }
143  bu_vls_free(&local);
144  return 0;
145 }
146 
147 
148 int
149 ged_dup(struct ged *gedp, int argc, const char *argv[])
150 {
151  struct db_i *newdbp = DBI_NULL;
152  struct directory **dirp0 = (struct directory **)NULL;
153  struct dir_check_stuff dcs;
154  static const char *usage = "file.g prefix";
155 
157  GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
158 
159  /* initialize result */
160  bu_vls_trunc(gedp->ged_result_str, 0);
161 
162  /* must be wanting help */
163  if (argc == 1) {
164  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
165  return GED_HELP;
166  }
167 
168  if (argc > 3) {
169  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
170  return GED_ERROR;
171  }
172 
173  bu_vls_trunc(&gedp->ged_wdbp->wdb_prestr, 0);
174  if (argc == 3)
175  (void)bu_vls_strcpy(&gedp->ged_wdbp->wdb_prestr, argv[2]);
176 
177  gedp->ged_wdbp->wdb_num_dups = 0;
178  if (db_version(gedp->ged_wdbp->dbip) < 5) {
179  if ((gedp->ged_wdbp->wdb_ncharadd = bu_vls_strlen(&gedp->ged_wdbp->wdb_prestr)) > 12) {
180  gedp->ged_wdbp->wdb_ncharadd = 12;
181  bu_vls_trunc(&gedp->ged_wdbp->wdb_prestr, 12);
182  }
183  } else {
185  }
186 
187  /* open the input file */
188  if ((newdbp = db_open(argv[1], DB_OPEN_READONLY)) == DBI_NULL) {
189  perror(argv[1]);
190  bu_vls_printf(gedp->ged_result_str, "dup: Cannot open geometry database file %s", argv[1]);
191  return GED_ERROR;
192  }
193 
195  "\n*** Comparing %s with %s for duplicate names\n",
196  gedp->ged_wdbp->dbip->dbi_filename, argv[1]);
197  if (gedp->ged_wdbp->wdb_ncharadd) {
199  " For comparison, all names in %s were prefixed with: %s\n",
200  argv[1], bu_vls_addr(&gedp->ged_wdbp->wdb_prestr));
201  }
202 
203  /* Get array to hold names of duplicates */
204  if ((dirp0 = _ged_getspace(gedp->ged_wdbp->dbip, 0)) == (struct directory **) 0) {
205  bu_vls_printf(gedp->ged_result_str, "f_dup: unable to get memory\n");
206  db_close(newdbp);
207  return GED_ERROR;
208  }
209 
210  /* Scan new database for overlaps */
211  dcs.main_dbip = gedp->ged_wdbp->dbip;
212  dcs.wdbp = gedp->ged_wdbp;
213  dcs.dup_dirp = dirp0;
214  if (db_version(newdbp) < 5) {
215  if (db_scan(newdbp, dup_dir_check, 0, (void *)&dcs) < 0) {
216  bu_vls_printf(gedp->ged_result_str, "dup: db_scan failure");
217  bu_free((void *)dirp0, "_ged_getspace array");
218  db_close(newdbp);
219  return GED_ERROR;
220  }
221  } else {
222  if (db5_scan(newdbp, dup_dir_check5, (void *)&dcs) < 0) {
223  bu_vls_printf(gedp->ged_result_str, "dup: db_scan failure");
224  bu_free((void *)dirp0, "_ged_getspace array");
225  db_close(newdbp);
226  return GED_ERROR;
227  }
228  }
229  rt_mempurge(&(newdbp->dbi_freep)); /* didn't really build a directory */
230 
231  _ged_vls_col_pr4v(gedp->ged_result_str, dirp0, (int)(dcs.dup_dirp - dirp0), 0);
232  bu_vls_printf(gedp->ged_result_str, "\n ----- %d duplicate names found -----", gedp->ged_wdbp->wdb_num_dups);
233  bu_free((void *)dirp0, "_ged_getspace array");
234  db_close(newdbp);
235 
236  return GED_OK;
237 }
238 
239 
240 /*
241  * Local Variables:
242  * tab-width: 8
243  * mode: C
244  * indent-tabs-mode: t
245  * c-file-style: "stroustrup"
246  * End:
247  * ex: shiftwidth=4 tabstop=8
248  */
void _ged_vls_col_pr4v(struct bu_vls *vls, struct directory **list_of_names, size_t num_in_list, int no_decorate)
Definition: ls.c:84
void usage(struct ged *gedp)
Definition: coil.c:315
#define GED_OK
Definition: ged.h:55
void rt_mempurge(struct mem_map **pp)
Definition: memalloc.c:316
Definition: raytrace.h:800
int wdb_num_dups
Definition: raytrace.h:1275
struct directory ** _ged_getspace(struct db_i *dbip, size_t num_entries)
Definition: ls.c:49
Definition: ged.h:338
struct db_i * dbip
Definition: raytrace.h:1266
struct db_i * main_dbip
Definition: dup.c:36
Definition: clone.c:90
void bu_vls_strcat(struct bu_vls *vp, const char *s)
Definition: vls.c:368
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 ged_dup(struct ged *gedp, int argc, const char *argv[])
Definition: dup.c:149
int db_version(struct db_i *dbip)
Definition: db5_scan.c:414
void bu_vls_strncpy(struct bu_vls *vp, const char *s, size_t n)
Definition: vls.c:339
struct rt_wdb * ged_wdbp
Definition: ged.h:340
Header file for the BRL-CAD common definitions.
#define GED_ERROR
Definition: ged.h:61
#define _GED_V4_MAXNAME
Definition: ged_private.h:48
if(share_geom)
Definition: nmg_mod.c:3829
void bu_vls_free(struct bu_vls *vp)
Definition: vls.c:248
#define GED_CHECK_DATABASE_OPEN(_gedp, _flags)
Definition: ged.h:114
#define LOOKUP_QUIET
Definition: raytrace.h:893
size_t bu_vls_strlen(const struct bu_vls *vp)
Definition: vls.c:189
void db_close(struct db_i *dbip)
#define UNUSED(parameter)
Definition: common.h:239
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
struct bu_vls wdb_prestr
Definition: raytrace.h:1273
#define RT_CK_DBI(_p)
Definition: raytrace.h:829
struct rt_wdb * wdbp
Definition: dup.c:37
#define DBI_NULL
Definition: raytrace.h:827
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
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 db_scan(struct db_i *, int(*handler)(struct db_i *, const char *name, off_t addr, size_t nrec, int flags, void *client_data), int do_old_matter, void *client_data)
#define GED_HELP
Definition: ged.h:62
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
#define BU_VLS_INIT_ZERO
Definition: vls.h:84
struct directory ** dup_dirp
Definition: dup.c:38
void bu_vls_vlscat(struct bu_vls *dest, const struct bu_vls *src)
Definition: vls.c:415
Definition: vls.h:56
char * dbi_filename
file name
Definition: raytrace.h:805
int db5_scan(struct db_i *dbip, void(*handler)(struct db_i *, const struct db5_raw_internal *, off_t addr, void *client_data), void *client_data)
Definition: db5_scan.c:36
int wdb_ncharadd
Definition: raytrace.h:1274