BRL-CAD
how.c
Go to the documentation of this file.
1 /* H O W . 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/how.c
21  *
22  * The how command.
23  *
24  */
25 
26 #include "common.h"
27 
28 #include <stdlib.h>
29 #include <string.h>
30 
31 #include "bu/cmd.h"
32 
33 
34 #include "./ged_private.h"
35 
36 
37 /*
38  * Returns "how" an object is being displayed.
39  *
40  * Usage:
41  * how [-b] object
42  *
43  */
44 int
45 ged_how(struct ged *gedp, int argc, const char *argv[])
46 {
47  int good;
48  struct directory **dpp;
49  int both = 0;
50  static const char *usage = "[-b] object";
51 
54  GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
55 
56  /* initialize result */
57  bu_vls_trunc(gedp->ged_result_str, 0);
58 
59  /* must be wanting help */
60  if (argc == 1) {
61  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
62  return GED_HELP;
63  }
64 
65  if (3 < argc) {
66  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
67  return GED_ERROR;
68  }
69 
70  if (argc == 3 &&
71  argv[1][0] == '-' &&
72  argv[1][1] == 'b') {
73  both = 1;
74 
75  if ((dpp = _ged_build_dpp(gedp, argv[2])) == NULL)
76  goto good_label;
77  } else {
78  if ((dpp = _ged_build_dpp(gedp, argv[1])) == NULL)
79  goto good_label;
80  }
81 
82  good = dl_how(gedp->ged_gdp->gd_headDisplay, gedp->ged_result_str, dpp, both);
83 
84  /* match NOT found */
85  if (!good) bu_vls_printf(gedp->ged_result_str, "-1");
86 
87 good_label:
88  if (dpp != (struct directory **)NULL)
89  bu_free((void *)dpp, "ged_how: directory pointers");
90 
91  return GED_OK;
92 }
93 
94 
95 struct directory **
96 _ged_build_dpp(struct ged *gedp,
97  const char *path) {
98  struct directory *dp;
99  struct directory **dpp;
100  int i;
101  char *begin;
102  char *end;
103  char *newstr;
104  char *list;
105  int ac;
106  const char **av;
107  const char **av_orig = NULL;
108  struct bu_vls vls = BU_VLS_INIT_ZERO;
109 
110  /*
111  * First, build an array of the object's path components.
112  * We store the list in av_orig below.
113  */
114  newstr = strdup(path);
115  begin = newstr;
116  while ((end = strchr(begin, '/')) != NULL) {
117  *end = '\0';
118  bu_vls_printf(&vls, "%s ", begin);
119  begin = end + 1;
120  }
121  bu_vls_printf(&vls, "%s ", begin);
122  free((void *)newstr);
123 
124  list = bu_vls_addr(&vls);
125 
126  if (Tcl_SplitList((Tcl_Interp *)brlcad_interp, list, &ac, &av_orig) != TCL_OK) {
127  bu_vls_printf(gedp->ged_result_str, "-1");
128  bu_vls_free(&vls);
129  return (struct directory **)NULL;
130  }
131 
132  /* skip first element if empty */
133  av = av_orig;
134  if (*av[0] == '\0') {
135  --ac;
136  ++av;
137  }
138 
139  /* ignore last element if empty */
140  if (*av[ac-1] == '\0')
141  --ac;
142 
143  /*
144  * Next, we build an array of directory pointers that
145  * correspond to the object's path.
146  */
147  dpp = (struct directory **)bu_calloc(ac+1, sizeof(struct directory *), "_ged_build_dpp: directory pointers");
148  for (i = 0; i < ac; ++i) {
149  if ((dp = db_lookup(gedp->ged_wdbp->dbip, av[i], 0)) != RT_DIR_NULL)
150  dpp[i] = dp;
151  else {
152  /* object is not currently being displayed */
153  bu_vls_printf(gedp->ged_result_str, "-1");
154 
155  bu_free((void *)dpp, "_ged_build_dpp: directory pointers");
156  Tcl_Free((char *)av_orig);
157  bu_vls_free(&vls);
158  return (struct directory **)NULL;
159  }
160  }
161 
162  dpp[i] = RT_DIR_NULL;
163 
164  Tcl_Free((char *)av_orig);
165  bu_vls_free(&vls);
166  return dpp;
167 }
168 
169 
170 /*
171  * Local Variables:
172  * tab-width: 8
173  * mode: C
174  * indent-tabs-mode: t
175  * c-file-style: "stroustrup"
176  * End:
177  * ex: shiftwidth=4 tabstop=8
178  */
void usage(struct ged *gedp)
Definition: coil.c:315
#define GED_OK
Definition: ged.h:55
Definition: ged.h:338
struct db_i * dbip
Definition: raytrace.h:1266
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
struct rt_wdb * ged_wdbp
Definition: ged.h:340
Header file for the BRL-CAD common definitions.
struct bu_list * gd_headDisplay
head of display list
Definition: ged.h:307
#define GED_ERROR
Definition: ged.h:61
char * strchr(const char *sp, int c)
int ged_how(struct ged *gedp, int argc, const char *argv[])
Definition: how.c:45
void bu_vls_free(struct bu_vls *vp)
Definition: vls.c:248
#define GED_CHECK_DATABASE_OPEN(_gedp, _flags)
Definition: ged.h:114
struct directory ** _ged_build_dpp(struct ged *gedp, const char *path)
Definition: how.c:96
void * bu_calloc(size_t nelem, size_t elsize, const char *str)
Definition: malloc.c:321
#define GED_CHECK_DRAWABLE(_gedp, _flags)
Definition: ged.h:129
int dl_how(struct bu_list *hdlp, struct bu_vls *vls, struct directory **dpp, int both)
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
struct bu_vls * ged_result_str
Definition: ged.h:357
struct ged_drawable * ged_gdp
Definition: ged.h:360
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 GED_HELP
Definition: ged.h:62
char * strdup(const char *cp)
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
ustring both
#define BU_VLS_INIT_ZERO
Definition: vls.h:84
Definition: vls.h:56
Tcl_Interp * brlcad_interp
Definition: tcl.c:41