BRL-CAD
namegen.c
Go to the documentation of this file.
1 /* N A M E G E N . 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 /** @addtogroup librt */
21 /** @{ */
22 /** @file librt/namegen.c
23  *
24  * Implements parser and next-name routines for BRL-CAD object names
25  *
26  * There are several tools in BRL-CAD which require automatic naming
27  * of auto-generated objects, such as clone and mirror. The routines
28  * defined here provide a general and universal method for taking a
29  * supplied object name and using it as a basis for generating new
30  * names, based on a printf-like syntax specific to BRL-CAD names:
31  *
32  * n - naming component of the primitive, defined as either the part
33  * of the primitive name from the first character up to the first
34  * separator, a non-incremental, non-extension string between
35  * separators in the name, or a non-incremental non-extension string
36  * between a separator and the end of the primitive name.
37  *
38  * s - a separator between naming elements, one of "-", "_" or ".".
39  * Note that if one or more of these characters is present but no
40  * separator has been specified, the presence of these characters is
41  * not regarded as indicating a separator.
42  *
43  * i - an incremental section, changed when a new name is to be
44  * generated.
45  *
46  * e - an extension - like %n, but can optionally be assigned based on
47  * the type of object being created.
48  *
49  * A formatting string for a primitive name MUST have at least one
50  * incremental section. If no separators are specified between a %n
51  * and a %i, it is assumed that the first digit character encountered
52  * is part of the %i and the previous non-digit character is the final
53  * character in that %n or %e region. To have digits present in a %n
54  * which is to be followed by a %i it is required to have a separator
55  * between the %n region and the %i region.
56  */
57 
58 #include "common.h"
59 
60 #include <stdlib.h>
61 #include <ctype.h>
62 #include <string.h>
63 #include <stdarg.h>
64 #include <regex.h>
65 #include "bio.h"
66 
67 #include "bn.h"
68 #include "db.h"
69 #include "raytrace.h"
70 
71 
72 
73 #define ASSEM_EXT ' '
74 #define REGION_EXT 'r'
75 #define COMB_EXT 'c'
76 #define PRIM_EXT 's'
77 
78 
82 };
83 
84 
85 static int
86 count_format_blocks(char *formatstring)
87 {
88  size_t i;
89  int components = 0;
90  for (i=0; i < strlen(formatstring); i++) {
91  if (formatstring[i] == '(') {
92  components++;
93  }
94  }
95  return components;
96 }
97 
98 
99 static int
100 is_number(char *substring)
101 {
102  int ret = -1;
103  regex_t compiled_regex;
104  ret=regcomp(&compiled_regex, "^[0-9]+$", REG_EXTENDED);
105  ret=regexec(&compiled_regex, substring, 0, 0, 0);
106  if (ret == 0) {
107  return 1;
108  } else {
109  return -1;
110  }
111 }
112 
113 
114 static int
115 contains_number(char *substring)
116 {
117  int ret = -1;
118  regex_t compiled_regex;
119  ret=regcomp(&compiled_regex, "[0-9]+", REG_EXTENDED);
120  ret=regexec(&compiled_regex, substring, 0, 0, 0);
121  if (ret == 0) {
122  return 1;
123  } else {
124  return -1;
125  }
126 }
127 
128 
129 static void
130 test_regex(char *name, int style)
131 {
132  struct formatting_style standard1 = {BU_VLS_INIT_ZERO, 0};
133  struct formatting_style standard2 = {BU_VLS_INIT_ZERO, 0};
134 
135  regex_t compiled_regex;
136  regmatch_t *result_locations;
137  int i, ret, components = 0;
138  struct bu_vls testresult = BU_VLS_INIT_ZERO;
139 
140  int *iterators;
141 
142  bu_vls_init(&(standard1.regex_spec));
143  bu_vls_strcat(&(standard1.regex_spec), "([rcs][.])?([^0-9^.]*)?([0-9]*)?([.][oicb])?([0-9]*)?([+u-])?([0-9]*)?");
144  standard1.pos_of_type_id_char = 1;
145 
146  bu_vls_init(&(standard2.regex_spec));
147  bu_vls_strcat(&(standard2.regex_spec), "([^0-9^.]*)?([0-9]*)?([^.]*)?([.][rcs])?([0-9]*)?([+u-])?([0-9]*)?");
148  standard2.pos_of_type_id_char = 5;
149 
150  if (style == 1) {
151  ret = regcomp(&compiled_regex, bu_vls_addr(&(standard1.regex_spec)), REG_EXTENDED);
152  if (ret != 0) {
153  perror("regcomp");
154  }
155  components = count_format_blocks(bu_vls_addr(&(standard1.regex_spec)));
156  }
157 
158  if (style == 2) {
159  ret = regcomp(&compiled_regex, bu_vls_addr(&(standard2.regex_spec)), REG_EXTENDED);
160  if (ret != 0) {
161  perror("regcomp");
162  }
163  components = count_format_blocks(bu_vls_addr(&(standard2.regex_spec)));
164  }
165 
166  result_locations = (regmatch_t *)bu_calloc(components + 1, sizeof(regmatch_t), "array to hold answers from regex");
167 
168  bu_log("components: %d\n", components);
169 
170  iterators = (int *)bu_calloc(components, sizeof(int), "array for iterator status of results");
171 
172  ret = regexec(&compiled_regex, name, components+1, result_locations, 0);
173  if (ret == 0) {
174  for (i=1; i<=components; i++) {
175  bu_vls_trunc(&testresult, 0);
176  bu_vls_strncpy(&testresult, name+result_locations[i].rm_so, result_locations[i].rm_eo - result_locations[i].rm_so);
177  if (is_number(bu_vls_addr(&testresult)) == 1) {
178  iterators[i-1] = 1;
179  } else {
180  if (contains_number(bu_vls_addr(&testresult)) == 1) {
181  iterators[i-1] = 2;
182  }
183  }
184  bu_log("%s\n", bu_vls_addr(&testresult));
185  }
186 
187  for (i=0; i<components; i++) {
188  bu_log("%d ", iterators[i]);
189  }
190  bu_log("\n");
191  }
192 
193  bu_free(result_locations, "free regex results");
194 }
195 
196 
198  struct bu_list l;
200  int numerval;
201 };
202 
203 
209  int object_type; /* 0 = unknown, 1 = solid, 2 = comb, 3 = region, 4 = assembly*/
210 };
211 
212 
214  struct bu_list l;
216 };
217 
218 
219 int
220 main()
221 {
222  /*
223  int num_of_copies = 10;
224  int j;
225  char **av;
226  struct db_i *dbip;
227  */
228  struct bu_vls temp = BU_VLS_INIT_ZERO;
229 
230  bu_vls_trunc(&temp, 0);
231  bu_vls_printf(&temp, "%s", "s.bcore12.b3");
232 
233  test_regex("core-001a1b.s1+1", 1);
234  test_regex("s.bcore12.b3", 1);
235  test_regex("comb1.c", 1);
236  test_regex("comb2.r", 1);
237  test_regex("comb3.r", 1);
238  test_regex("assem1", 1);
239  test_regex("test.q", 1);
240  test_regex("core-001a1b.s1+1", 2);
241  test_regex("s.bcore12.b3", 2);
242  test_regex("comb1.c", 2);
243  test_regex("comb2.r", 2);
244  test_regex("assem1", 2);
245  test_regex("test.q", 2);
246 
247  return 1;
248 }
249 
250 
251 /** @} */
252 /*
253  * Local Variables:
254  * tab-width: 8
255  * mode: C
256  * indent-tabs-mode: t
257  * c-file-style: "stroustrup"
258  * End:
259  * ex: shiftwidth=4 tabstop=8
260  */
void bu_vls_init(struct bu_vls *vp)
Definition: vls.c:56
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
Definition: list.h:118
int pos_of_type_id_char
Definition: namegen.c:81
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
struct bu_vls extension
Definition: namegen.c:208
void bu_vls_strncpy(struct bu_vls *vp, const char *s, size_t n)
Definition: vls.c:339
Header file for the BRL-CAD common definitions.
struct bu_vls namestring
Definition: namegen.c:215
struct bu_list l
Definition: namegen.c:214
int main(int ac, char *av[])
Definition: bu_b64.c:63
struct bu_list name_components
Definition: namegen.c:205
void * bu_calloc(size_t nelem, size_t elsize, const char *str)
Definition: malloc.c:321
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
struct bu_vls namestring
Definition: namegen.c:199
struct bu_vls regex_spec
Definition: namegen.c:80
void bu_vls_printf(struct bu_vls *vls, const char *fmt,...) _BU_ATTR_PRINTF23
Definition: vls.c:694
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
struct bu_list separators
Definition: namegen.c:206
#define BU_VLS_INIT_ZERO
Definition: vls.h:84
struct bu_list l
Definition: namegen.c:198
Definition: vls.h:56
struct bu_list incrementals
Definition: namegen.c:207