BRL-CAD
attr.c
Go to the documentation of this file.
1 /* A T T R . 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/attr.c
21  *
22  * The attr command.
23  *
24  */
25 
26 #include "common.h"
27 
28 #include <string.h>
29 
30 #include "bu/sort.h"
31 #include "./ged_private.h"
32 
33 
34 typedef enum {
43 } attr_cmd_t;
44 
45 
46 /*
47  * avs attribute comparison function, e.g. for bu_sort
48  */
49 HIDDEN int
50 attr_cmp(const void *p1, const void *p2, void *UNUSED(arg))
51 {
52  return bu_strcmp(((struct bu_attribute_value_pair *)p1)->name,
53  ((struct bu_attribute_value_pair *)p2)->name);
54 }
55 
56 
57 HIDDEN int
58 attr_cmp_nocase(const void *p1, const void *p2, void *UNUSED(arg))
59 {
60  return bu_strcasecmp(((struct bu_attribute_value_pair *)p1)->name,
61  ((struct bu_attribute_value_pair *)p2)->name);
62 }
63 
64 
65 HIDDEN int
66 attr_cmp_value(const void *p1, const void *p2, void *UNUSED(arg))
67 {
68  return bu_strcmp(((struct bu_attribute_value_pair *)p1)->value,
69  ((struct bu_attribute_value_pair *)p2)->value);
70 }
71 
72 
73 HIDDEN int
74 attr_cmp_value_nocase(const void *p1, const void *p2, void *UNUSED(arg))
75 {
76  return bu_strcasecmp(((struct bu_attribute_value_pair *)p1)->value,
77  ((struct bu_attribute_value_pair *)p2)->value);
78 }
79 
80 
81 HIDDEN int
82 attr_pretty_print(struct ged *gedp, struct directory *dp, const char *name)
83 {
84  if (dp->d_flags & RT_DIR_COMB) {
85  if (dp->d_flags & RT_DIR_REGION) {
86  bu_vls_printf(gedp->ged_result_str, "%s region:\n", name);
87  } else {
88  bu_vls_printf(gedp->ged_result_str, "%s combination:\n", name);
89  }
90  } else if (dp->d_flags & RT_DIR_SOLID) {
91  struct rt_db_internal intern;
92  GED_DB_GET_INTERNAL(gedp, &intern, dp, (fastf_t *)NULL, &rt_uniresource, GED_ERROR);
93  bu_vls_printf(gedp->ged_result_str, "%s %s:\n", name, intern.idb_meth->ft_label);
94  rt_db_free_internal(&intern);
95  } else {
96  switch (dp->d_major_type) {
97  case DB5_MAJORTYPE_ATTRIBUTE_ONLY:
98  bu_vls_printf(gedp->ged_result_str, "%s global:\n", name);
99  break;
100  case DB5_MAJORTYPE_BINARY_MIME:
101  bu_vls_printf(gedp->ged_result_str, "%s binary(mime):\n", name);
102  break;
103  case DB5_MAJORTYPE_BINARY_UNIF:
104  bu_vls_printf(gedp->ged_result_str, "%s %s:\n", name,
105  binu_types[dp->d_minor_type]);
106  break;
107  }
108  }
109 
110  return GED_OK;
111 }
112 
113 
115 attr_cmd(const char* arg)
116 {
117  /* sub-commands */
118  const char APPEND[] = "append";
119  const char GET[] = "get";
120  const char LIST[] = "list";
121  const char RM[] = "rm";
122  const char SET[] = "set";
123  const char SHOW[] = "show";
124  const char SORT[] = "sort";
125 
126  /* in one user's predicted order of frequency: */
127  if (BU_STR_EQUIV(SHOW, arg))
128  return ATTR_SHOW;
129  else if (BU_STR_EQUIV(SET, arg))
130  return ATTR_SET;
131  else if (BU_STR_EQUIV(SORT, arg))
132  return ATTR_SORT;
133  else if (BU_STR_EQUIV(RM, arg))
134  return ATTR_RM;
135  else if (BU_STR_EQUIV(APPEND, arg))
136  return ATTR_APPEND;
137  else if (BU_STR_EQUIV(GET, arg))
138  return ATTR_GET;
139  else if (BU_STR_EQUIV(LIST, arg))
140  return ATTR_LIST;
141  else
142  return ATTR_UNKNOWN;
143 }
144 
145 
146 HIDDEN void
147 attr_print(struct ged *gedp, struct bu_attribute_value_set *avs,
148  const size_t max_attr_name_len)
149 {
150  struct bu_attribute_value_pair *avpp;
151  size_t i;
152 
153  for (i = 0, avpp = avs->avp; i < avs->count; i++, avpp++) {
154  size_t len_diff = 0;
155  size_t count = 0;
156  bu_vls_printf(gedp->ged_result_str, "\t%s", avpp->name);
157  len_diff = max_attr_name_len - strlen(avpp->name);
158  while (count < (len_diff) + 1) {
159  bu_vls_printf(gedp->ged_result_str, " ");
160  count++;
161  }
162  bu_vls_printf(gedp->ged_result_str, "%s\n", avpp->value);
163  }
164 }
165 
166 
167 int
168 ged_attr(struct ged *gedp, int argc, const char *argv[])
169 {
170  size_t i;
171  struct directory *dp;
172  struct bu_attribute_value_pair *avpp;
173  static const char *usage = "{set|get|show|rm|append|sort} object [key [value] ... ]";
174  attr_cmd_t scmd;
175  struct directory **paths = NULL;
176  size_t path_cnt = 0;
177 
178  /* sort types */
179  const char CASE[] = "case";
180  const char NOCASE[] = "nocase";
181  const char VALUE[] = "value";
182  const char VALUE_NOCASE[] = "value-nocase";
183 
184  GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
185 
186  /* initialize result */
187  bu_vls_trunc(gedp->ged_result_str, 0);
188 
189  /* must be wanting help */
190  if (argc == 1) {
191  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
192  return GED_HELP;
193  }
194 
195  if (argc < 3) {
196  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
197  return GED_ERROR;
198  }
199 
200  /* Verify that this wdb supports lookup operations
201  (non-null dbip) */
203 
204  /* this is only valid for v5 databases */
205  if (db_version(gedp->ged_wdbp->dbip) < 5) {
206  bu_vls_printf(gedp->ged_result_str, "Attributes are not available for this database format.\nPlease upgrade your database format using \"dbupgrade\" to enable attributes.");
207  return GED_ERROR;
208  }
209 
210  scmd = attr_cmd(argv[1]);
211 
212  path_cnt = db_ls(gedp->ged_wdbp->dbip, DB_LS_HIDDEN, argv[2], &paths);
213 
214  if (path_cnt == 0) {
215  bu_vls_printf(gedp->ged_result_str, "Cannot locate objects matching %s\n", argv[2]);
216  return GED_ERROR;
217  }
218 
219  if (scmd == ATTR_SORT) {
220  for (i = 0; i < path_cnt; i++) {
221  /* for pretty printing */
222  size_t j = 0;
223  size_t max_attr_name_len = 0;
224  size_t max_attr_value_len = 0;
225 
226  struct bu_attribute_value_set avs;
227  bu_avs_init_empty(&avs);
228 
229  dp = paths[i];
230 
231  if (db5_get_attributes(gedp->ged_wdbp->dbip, &avs, dp)) {
232  bu_vls_printf(gedp->ged_result_str, "Cannot get attributes for object %s\n", dp->d_namep);
233  return GED_ERROR;
234  }
235  bu_sort(&avs.avp[0], avs.count, sizeof(struct bu_attribute_value_pair), attr_cmp, NULL);
236  /* get a jump on calculating name and value lengths */
237  for (j = 0, avpp = avs.avp; j < avs.count; j++, avpp++) {
238  size_t len = strlen(avpp->name);
239  if (len > max_attr_name_len)
240  max_attr_name_len = len;
241  if (avpp->value) {
242  len = strlen(avpp->value);
243  if (len > max_attr_value_len)
244  max_attr_value_len = len;
245  }
246  }
247 
248  /* pretty print */
249  if ((attr_pretty_print(gedp, dp, argv[2])) != GED_OK) {
250  return GED_ERROR;
251  }
252  if (argc == 3) {
253  /* just list the already sorted attribute-value pairs */
254  attr_print(gedp, &avs, max_attr_name_len);
255  } else {
256  /* argv[3] is the sort type: 'case', 'nocase', 'value', 'value-nocase' */
257  if (BU_STR_EQUIV(argv[3], NOCASE)) {
258  bu_sort(&avs.avp[0], avs.count, sizeof(struct bu_attribute_value_pair), attr_cmp_nocase, NULL);
259  } else if (BU_STR_EQUIV(argv[3], VALUE)) {
260  bu_sort(&avs.avp[0], avs.count, sizeof(struct bu_attribute_value_pair), attr_cmp_value, NULL);
261  } else if (BU_STR_EQUIV(argv[3], VALUE_NOCASE)) {
262  bu_sort(&avs.avp[0], avs.count, sizeof(struct bu_attribute_value_pair), attr_cmp_value_nocase, NULL);
263  } else if (BU_STR_EQUIV(argv[3], CASE)) {
264  ; /* don't need to do anything since this is the existing (default) sort */
265  }
266  /* just list the already sorted attribute-value pairs */
267  attr_print(gedp, &avs, max_attr_name_len);
268  }
269  bu_avs_free(&avs);
270  }
271  } else if (scmd == ATTR_GET) {
272  if (path_cnt == 1) {
273  struct bu_attribute_value_set avs;
274  bu_avs_init_empty(&avs);
275 
276  dp = paths[0];
277 
278  if (db5_get_attributes(gedp->ged_wdbp->dbip, &avs, dp)) {
279  bu_vls_printf(gedp->ged_result_str, "Cannot get attributes for object %s\n", dp->d_namep);
280  return GED_ERROR;
281  }
282  bu_sort(&avs.avp[0], avs.count, sizeof(struct bu_attribute_value_pair), attr_cmp, NULL);
283 
284  if (argc == 3) {
285  /* just list all the attributes */
286  for (i = 0, avpp = avs.avp; i < avs.count; i++, avpp++) {
287  bu_vls_printf(gedp->ged_result_str, "%s {%s} ", avpp->name, avpp->value);
288  }
289  } else {
290  const char *val;
291  int do_separators=argc-4; /* if more than one attribute */
292 
293  for (i = 3; i < (size_t)argc; i++) {
294  val = bu_avs_get(&avs, argv[i]);
295  if (!val) {
297  "Object %s does not have a %s attribute\n",
298  dp->d_namep,
299  argv[i]);
300  bu_avs_free(&avs);
301  return GED_ERROR;
302  }
303  if (do_separators) {
304  bu_vls_printf(gedp->ged_result_str, "{%s} ", val);
305  } else {
306  bu_vls_printf(gedp->ged_result_str, "%s", val);
307  }
308  }
309  }
310  bu_avs_free(&avs);
311  } else {
312  for (i = 0; i < path_cnt; i++) {
313  size_t j = 0;
314  struct bu_vls obj_vals = BU_VLS_INIT_ZERO;
315  struct bu_attribute_value_set avs;
316  bu_avs_init_empty(&avs);
317  dp = paths[i];
318 
319  if (db5_get_attributes(gedp->ged_wdbp->dbip, &avs, dp)) {
320  bu_vls_printf(gedp->ged_result_str, "Cannot get attributes for object %s\n", dp->d_namep);
321  return GED_ERROR;
322  }
323  bu_sort(&avs.avp[0], avs.count, sizeof(struct bu_attribute_value_pair), attr_cmp, NULL);
324 
325  if (argc == 3) {
326  /* just list all the attributes */
327  for (j = 0, avpp = avs.avp; j < avs.count; j++, avpp++) {
328  bu_vls_printf(&obj_vals, "%s {%s} ", avpp->name, avpp->value);
329  }
330  } else {
331  const char *val;
332  int do_separators=argc-4; /* if more than one attribute */
333 
334  for (j = 3; j < (size_t)argc; j++) {
335  val = bu_avs_get(&avs, argv[j]);
336  if (val) {
337  if (do_separators) {
338  bu_vls_printf(&obj_vals, "{%s} ", val);
339  } else {
340  bu_vls_printf(&obj_vals, "%s", val);
341  }
342  }
343  }
344  }
345  if (strlen(bu_vls_addr(&obj_vals)) > 0) {
346  bu_vls_printf(gedp->ged_result_str, "%s: ", dp->d_namep);
347  bu_vls_printf(gedp->ged_result_str, "%s", bu_vls_addr(&obj_vals));
348 
349  if (i < path_cnt-1) {
350  bu_vls_printf(gedp->ged_result_str, "\n");
351  }
352  }
353 
354  bu_vls_free(&obj_vals);
355  bu_avs_free(&avs);
356  }
357  }
358  } else if (scmd == ATTR_LIST) {
359  struct bu_attribute_value_set avs;
360  bu_avs_init_empty(&avs);
361 
362  for (i = 0; i < path_cnt; i++) {
363  struct bu_attribute_value_set lavs;
364  bu_avs_init_empty(&lavs);
365  dp = paths[i];
366  if (db5_get_attributes(gedp->ged_wdbp->dbip, &lavs, dp)) {
367  bu_vls_printf(gedp->ged_result_str, "Cannot get attributes for object %s\n", dp->d_namep);
368  return GED_ERROR;
369  }
370  bu_avs_merge(&avs, &lavs);
371  bu_avs_free(&lavs);
372  }
373  /* Now that we have them all, sort */
374  bu_sort(&avs.avp[0], avs.count, sizeof(struct bu_attribute_value_pair), attr_cmp, NULL);
375  /* list all the attributes */
376  for (i = 0, avpp = avs.avp; i < avs.count; i++, avpp++) {
377  bu_vls_printf(gedp->ged_result_str, "%s\n", avpp->name);
378  }
379  bu_avs_free(&avs);
380  } else if (scmd == ATTR_SET) {
382  /* setting attribute/value pairs */
383  if ((argc - 3) % 2) {
385  "Error: attribute names and values must be in pairs!!!\n");
386  return GED_ERROR;
387  }
388  for (i = 0; i < path_cnt; i++) {
389  size_t j = 3;
390  struct bu_attribute_value_set avs;
391  bu_avs_init_empty(&avs);
392  dp = paths[i];
393 
394  if (db5_get_attributes(gedp->ged_wdbp->dbip, &avs, dp)) {
395  bu_vls_printf(gedp->ged_result_str, "Cannot get attributes for object %s\n", dp->d_namep);
396  return GED_ERROR;
397  }
398  bu_sort(&avs.avp[0], avs.count, sizeof(struct bu_attribute_value_pair), attr_cmp, NULL);
399  while (j < (size_t)argc) {
400  if (BU_STR_EQUAL(argv[j], "region") && BU_STR_EQUAL(argv[j+1], "R")) {
401  dp->d_flags |= RT_DIR_REGION;
402  }
403  (void)bu_avs_add(&avs, argv[j], argv[j+1]);
404  j += 2;
405  }
406  db5_standardize_avs(&avs);
407  if (db5_update_attributes(dp, &avs, gedp->ged_wdbp->dbip)) {
409  "Error: failed to update attributes\n");
410  bu_avs_free(&avs);
411  return GED_ERROR;
412  }
413  /* avs is freed by db5_update_attributes() */
414  }
415 
416  } else if (scmd == ATTR_RM) {
418  for (i = 0; i < path_cnt; i++) {
419  size_t j = 3;
420  struct bu_attribute_value_set avs;
421  bu_avs_init_empty(&avs);
422  dp = paths[i];
423 
424  if (db5_get_attributes(gedp->ged_wdbp->dbip, &avs, dp)) {
425  bu_vls_printf(gedp->ged_result_str, "Cannot get attributes for object %s\n", dp->d_namep);
426  return GED_ERROR;
427  }
428  bu_sort(&avs.avp[0], avs.count, sizeof(struct bu_attribute_value_pair), attr_cmp, NULL);
429 
430  while (j < (size_t)argc) {
431  if (BU_STR_EQUAL(argv[j], "region")) {
432  dp->d_flags = dp->d_flags & ~(RT_DIR_REGION);
433  }
434  (void)bu_avs_remove(&avs, argv[j]);
435  j++;
436  }
437  if (db5_replace_attributes(dp, &avs, gedp->ged_wdbp->dbip)) {
439  "Error: failed to update attributes\n");
440  bu_avs_free(&avs);
441  return GED_ERROR;
442  }
443  /* avs is freed by db5_replace_attributes() */
444  }
445 
446  } else if (scmd == ATTR_APPEND) {
448  if ((argc-3) % 2) {
450  "Error: attribute names and values must be in pairs!!!\n");
451  return GED_ERROR;
452  }
453  for (i = 0; i < path_cnt; i++) {
454  size_t j = 3;
455  struct bu_attribute_value_set avs;
456  bu_avs_init_empty(&avs);
457  dp = paths[i];
458 
459  if (db5_get_attributes(gedp->ged_wdbp->dbip, &avs, dp)) {
460  bu_vls_printf(gedp->ged_result_str, "Cannot get attributes for object %s\n", dp->d_namep);
461  return GED_ERROR;
462  }
463  bu_sort(&avs.avp[0], avs.count, sizeof(struct bu_attribute_value_pair), attr_cmp, NULL);
464 
465  while (j < (size_t)argc) {
466  const char *old_val;
467  if (BU_STR_EQUAL(argv[j], "region") && BU_STR_EQUAL(argv[j+1], "R")) {
468  dp->d_flags |= RT_DIR_REGION;
469  }
470  old_val = bu_avs_get(&avs, argv[j]);
471  if (!old_val) {
472  (void)bu_avs_add(&avs, argv[j], argv[j+1]);
473  } else {
474  struct bu_vls vls = BU_VLS_INIT_ZERO;
475 
476  bu_vls_strcat(&vls, old_val);
477  bu_vls_strcat(&vls, argv[j+1]);
478  bu_avs_add_vls(&avs, argv[j], &vls);
479  bu_vls_free(&vls);
480  }
481 
482  j += 2;
483  }
484  if (db5_replace_attributes(dp, &avs, gedp->ged_wdbp->dbip)) {
486  "Error: failed to update attributes\n");
487  bu_avs_free(&avs);
488  return GED_ERROR;
489  }
490 
491  /* avs is freed by db5_replace_attributes() */
492  }
493  } else if (scmd == ATTR_SHOW) {
494  for (i = 0; i < path_cnt; i++) {
495  /* for pretty printing */
496  size_t max_attr_name_len = 0;
497  size_t max_attr_value_len = 0;
498 
499  size_t j = 0;
500  size_t tabs1 = 0;
501  struct bu_attribute_value_set avs;
502  bu_avs_init_empty(&avs);
503  dp = paths[i];
504 
505  if (db5_get_attributes(gedp->ged_wdbp->dbip, &avs, dp)) {
506  bu_vls_printf(gedp->ged_result_str, "Cannot get attributes for object %s\n", dp->d_namep);
507  return GED_ERROR;
508  }
509 
510  /* get a jump on calculating name and value lengths */
511  for (j = 0, avpp = avs.avp; j < avs.count; j++, avpp++) {
512  size_t len = strlen(avpp->name);
513  if (len > max_attr_name_len)
514  max_attr_name_len = len;
515  if (avpp->value) {
516  len = strlen(avpp->value);
517  if (len > max_attr_value_len)
518  max_attr_value_len = len;
519  }
520  }
521 
522  /* pretty print */
523  if ((attr_pretty_print(gedp, dp, dp->d_namep)) != GED_OK) {
524  return GED_ERROR;
525  }
526 
527  if (argc == 3) {
528  /* just display all attributes */
529  attr_print(gedp, &avs, max_attr_name_len);
530  } else {
531  const char *val;
532  size_t len;
533 
534  /* show just the specified attributes */
535  for (j = 0; j < (size_t)argc; j++) {
536  len = strlen(argv[j]);
537  if (len > max_attr_name_len) {
538  max_attr_name_len = len;
539  }
540  }
541  tabs1 = 2 + max_attr_name_len/8;
542  for (j = 3; j < (size_t)argc; j++) {
543  size_t tabs2;
544  size_t k;
545  const char *c;
546 
547  val = bu_avs_get(&avs, argv[j]);
548  if (!val && path_cnt == 1) {
550  "Object %s does not have a %s attribute\n",
551  dp->d_namep,
552  argv[j]);
553  bu_avs_free(&avs);
554  return GED_ERROR;
555  } else {
556  if (val) {
557  bu_vls_printf(gedp->ged_result_str, "\t%s", argv[j]);
558  len = strlen(val);
559  tabs2 = tabs1 - 1 - len/8;
560  for (k = 0; k < tabs2; k++) {
561  bu_vls_putc(gedp->ged_result_str, '\t');
562  }
563  c = val;
564  while (*c) {
565  bu_vls_putc(gedp->ged_result_str, *c);
566  if (*c == '\n') {
567  for (k = 0; k < tabs1; k++) {
568  bu_vls_putc(gedp->ged_result_str, '\t');
569  }
570  }
571  c++;
572  }
573  bu_vls_putc(gedp->ged_result_str, '\n');
574  }
575  }
576  }
577  }
578  }
579  } else {
580  bu_vls_printf(gedp->ged_result_str, "ERROR: unrecognized attr subcommand %s\n", argv[1]);
581  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
582 
583  return GED_ERROR;
584  }
585 
586  return GED_OK;
587 }
588 
589 
590 /*
591  * Local Variables:
592  * tab-width: 8
593  * mode: C
594  * indent-tabs-mode: t
595  * c-file-style: "stroustrup"
596  * End:
597  * ex: shiftwidth=4 tabstop=8
598  */
Definition: db_flip.c:35
void usage(struct ged *gedp)
Definition: coil.c:315
#define GED_OK
Definition: ged.h:55
char * d_namep
pointer to name string
Definition: raytrace.h:859
unsigned char d_major_type
object major type
Definition: raytrace.h:870
size_t db5_standardize_avs(struct bu_attribute_value_set *avs)
Definition: db5_attr.c:223
void bu_avs_init_empty(struct bu_attribute_value_set *avp)
Definition: avs.c:36
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
HIDDEN int attr_cmp_value(const void *p1, const void *p2, void *arg)
Definition: attr.c:66
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
int bu_avs_add(struct bu_attribute_value_set *avp, const char *attribute, const char *value)
Definition: avs.c:78
void bu_avs_merge(struct bu_attribute_value_set *dest, const struct bu_attribute_value_set *src)
Definition: avs.c:154
HIDDEN int attr_cmp_value_nocase(const void *p1, const void *p2, void *arg)
Definition: attr.c:74
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
Definition: attr.c:38
int db_version(struct db_i *dbip)
Definition: db5_scan.c:414
HIDDEN int attr_pretty_print(struct ged *gedp, struct directory *dp, const char *name)
Definition: attr.c:82
struct rt_wdb * ged_wdbp
Definition: ged.h:340
Header file for the BRL-CAD common definitions.
const char * binu_types[]
Definition: globals.c:55
Definition: attr.c:36
const char * value
Definition: avs.h:62
#define RT_DIR_REGION
region
Definition: raytrace.h:885
char ft_label[9]
Definition: raytrace.h:2044
Definition: attr.c:41
#define GED_ERROR
Definition: ged.h:61
#define HIDDEN
Definition: common.h:86
const char * bu_avs_get(const struct bu_attribute_value_set *avp, const char *attribute)
Definition: avs.c:172
HIDDEN attr_cmd_t attr_cmd(const char *arg)
Definition: attr.c:115
HIDDEN void attr_print(struct ged *gedp, struct bu_attribute_value_set *avs, const size_t max_attr_name_len)
Definition: attr.c:147
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 SORT(a, b)
Definition: tri_tri.c:74
struct resource rt_uniresource
default. Defined in librt/globals.c
Definition: globals.c:41
HIDDEN int attr_cmp(const void *p1, const void *p2, void *arg)
Definition: attr.c:50
#define GED_CHECK_DATABASE_OPEN(_gedp, _flags)
Definition: ged.h:114
struct bu_attribute_value_pair * avp
Definition: avs.h:89
int bu_avs_remove(struct bu_attribute_value_set *avp, const char *attribute)
Definition: avs.c:195
#define RT_DIR_SOLID
this name is a solid
Definition: raytrace.h:883
const struct rt_functab * idb_meth
for ft_ifree(), etc.
Definition: raytrace.h:194
void bu_sort(void *array, size_t nummemb, size_t sizememb, int(*compare)(const void *, const void *, void *), void *context)
Definition: sort.c:110
int db5_replace_attributes(struct directory *dp, struct bu_attribute_value_set *avsp, struct db_i *dbip)
Definition: attributes.c:223
#define BU_STR_EQUIV(s1, s2)
Definition: str.h:135
HIDDEN int attr_cmp_nocase(const void *p1, const void *p2, void *arg)
Definition: attr.c:58
#define UNUSED(parameter)
Definition: common.h:239
Definition: attr.c:40
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
struct bu_vls * ged_result_str
Definition: ged.h:357
size_t db_ls(const struct db_i *dbip, int flags, const char *pattern, struct directory ***dpv)
Definition: ls.c:58
Definition: attr.c:37
int bu_strcmp(const char *string1, const char *string2)
Definition: str.c:171
attr_cmd_t
Definition: attr.c:34
#define RT_DIR_COMB
combination
Definition: raytrace.h:884
void bu_vls_printf(struct bu_vls *vls, const char *fmt,...) _BU_ATTR_PRINTF23
Definition: vls.c:694
#define GED_HELP
Definition: ged.h:62
#define GED_DB_GET_INTERNAL(_gedp, _intern, _dp, _mat, _resource, _flags)
Definition: ged.h:233
int bu_avs_add_vls(struct bu_attribute_value_set *avp, const char *attribute, const struct bu_vls *value_vls)
Definition: avs.c:144
const char * name
Definition: avs.h:61
Definition: attr.c:39
int ged_attr(struct ged *gedp, int argc, const char *argv[])
Definition: attr.c:168
#define BU_VLS_INIT_ZERO
Definition: vls.h:84
#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
double fastf_t
Definition: defines.h:300
void bu_vls_putc(struct bu_vls *vp, int c)
Definition: vls.c:666
void bu_avs_free(struct bu_attribute_value_set *avp)
Definition: avs.c:235
void rt_db_free_internal(struct rt_db_internal *ip)
Definition: dir.c:216
int bu_strcasecmp(const char *string1, const char *string2)
Definition: str.c:211
#define BU_STR_EQUAL(s1, s2)
Definition: str.h:126
#define DB_LS_HIDDEN
Definition: raytrace.h:4655