BRL-CAD
regionfix.c
Go to the documentation of this file.
1 /* R E G I O N F I X . C
2  * BRL-CAD
3  *
4  * Copyright (c) 1989-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 
21 
22 #include "common.h"
23 
24 #include <stdlib.h>
25 #include <sys/types.h>
26 #include <ctype.h>
27 #include <string.h>
28 #include <regex.h>
29 #include "bio.h"
30 
31 #include "vmath.h"
32 #include "raytrace.h"
33 
34 
35 void
36 rt_regionfix(struct rt_i *rtip)
37 {
38  FILE *fp;
39  char *file;
40  char *line;
41  char *tabp;
42  int linenum = 0;
43  register struct region *rp;
44  int ret;
45  int oldid;
46  int newid;
47  struct bu_vls name = BU_VLS_INIT_ZERO;
48 
49  RT_CK_RTI(rtip);
50 
51  /* If application has provided an alternative file name before
52  * rt_prep() was called, then use that. Otherwise, replace ".g"
53  * suffix on database name with ".regexp".
54  */
55  file = rtip->rti_region_fix_file;
56  if (file == (char *)NULL) {
57  bu_vls_strcpy(&name, rtip->rti_dbip->dbi_filename);
58  if ((tabp = strrchr(bu_vls_addr(&name), '.')) != NULL) {
59  /* Chop off "." and suffix */
60  bu_vls_trunc(&name, tabp-bu_vls_addr(&name));
61  }
62  bu_vls_strcat(&name, ".regexp");
63  file = bu_vls_addr(&name);
64  }
65 
66  fp = fopen(file, "rb");
67  if (fp == NULL) {
68  if (rtip->rti_region_fix_file) perror(file);
69  bu_vls_free(&name);
70  return;
71  }
72  bu_log("librt/rt_regionfix(%s): Modifying instanced region-ids.\n", file);
73 
74  while ((line = rt_read_cmd(fp)) != (char *) 0) {
75  regex_t re_space;
76  linenum++;
77 
78  /* For now, establish a simple format:
79  * regexp TAB [more_white_space] formula SEMICOLON
80  */
81  if ((tabp = strchr(line, '\t')) == (char *)0) {
82  bu_log("%s: missing TAB on line %d:\n%s\n", file, linenum, line);
83  continue; /* just ignore it */
84  }
85 
86  *tabp++ = '\0';
87  while (*tabp && isspace((int)*tabp)) tabp++;
88  if ((ret = regcomp(&re_space, line, 0)) != 0) {
89  bu_log("%s: line %d, regcomp error '%d'\n", file, linenum, ret);
90  continue; /* just ignore it */
91  }
92 
93  for (BU_LIST_FOR(rp, region, &(rtip->HeadRegion))) {
94  ret = regexec(&re_space, (char *)rp->reg_name, 0, 0, 0);
96  bu_log("'%s' %s '%s'\n", line,
97  ret==1 ? "==" : "!=",
98  rp->reg_name);
99  }
100  if ((ret) == 0)
101  continue; /* didn't match */
102  if (ret == -1) {
103  bu_log("%s: line %d, invalid regular expression\n", file, linenum);
104  break; /* on to next RE */
105  }
106 
107  /*
108  * RE matched this name, perform indicated operation
109  * For now, choices are limited. Later this might
110  * become an interpreted expression. For now:
111  * 99 replace old region id with "num"
112  * +99 increment old region id with "num"
113  * (which may itself be a negative number)
114  * +uses increment old region id by the
115  * current instance (use) count.
116  */
117  oldid = rp->reg_regionid;
118  if (BU_STR_EQUAL(tabp, "+uses")) {
119  newid = oldid + rp->reg_instnum;
120  } else if (*tabp == '+') {
121  newid = oldid + atoi(tabp+1);
122  } else {
123  newid = atoi(tabp);
124  if (newid == 0) bu_log("%s, line %d Warning: new id = 0\n", file, linenum);
125  }
126  if (RT_G_DEBUG&DEBUG_INSTANCE) {
127  bu_log("%s instance %ld: region id changed from %d to %d\n",
128  rp->reg_name, rp->reg_instnum,
129  oldid, newid);
130  }
131  rp->reg_regionid = newid;
132  }
133  regfree(&re_space);
134  bu_free(line, "reg_expr line");
135  }
136  fclose(fp);
137  bu_vls_free(&name);
138 }
139 
140 
141 /*
142  * Local Variables:
143  * mode: C
144  * tab-width: 8
145  * indent-tabs-mode: t
146  * c-file-style: "stroustrup"
147  * End:
148  * ex: shiftwidth=4 tabstop=8
149  */
#define BU_LIST_FOR(p, structure, hp)
Definition: list.h:365
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
#define RT_CK_RTI(_p)
Definition: raytrace.h:1833
void bu_vls_strcat(struct bu_vls *vp, const char *s)
Definition: vls.c:368
struct bu_list HeadRegion
ptr of list of regions in model
Definition: raytrace.h:1778
void bu_vls_trunc(struct bu_vls *vp, int len)
Definition: vls.c:198
Header file for the BRL-CAD common definitions.
void rt_regionfix(struct rt_i *rtip)
Definition: regionfix.c:36
const char * reg_name
Identifying string.
Definition: raytrace.h:539
char * strchr(const char *sp, int c)
void bu_vls_free(struct bu_vls *vp)
Definition: vls.c:248
#define RT_G_DEBUG
Definition: raytrace.h:1718
int reg_regionid
Region ID code. If <=0, use reg_aircode.
Definition: raytrace.h:542
char * rt_read_cmd(FILE *fp)
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
#define DEBUG_INSTANCE
4 regionid instance revectoring
Definition: raytrace.h:85
long reg_instnum
instance number, from d_uses
Definition: raytrace.h:550
struct db_i * rti_dbip
prt to Database instance struct
Definition: raytrace.h:1774
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
char * rti_region_fix_file
rt_regionfix() file or NULL
Definition: raytrace.h:1762
Definition: vls.h:56
char * dbi_filename
file name
Definition: raytrace.h:805
#define BU_STR_EQUAL(s1, s2)
Definition: str.h:126