1 |
/* ASCEND modelling environment |
2 |
Copyright (C) 2006 Carnegie Mellon University |
3 |
|
4 |
This program is free software; you can redistribute it and/or modify |
5 |
it under the terms of the GNU General Public License as published by |
6 |
the Free Software Foundation; either version 2, or (at your option) |
7 |
any later version. |
8 |
|
9 |
This program is distributed in the hope that it will be useful, |
10 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 |
GNU General Public License for more details. |
13 |
|
14 |
You should have received a copy of the GNU General Public License |
15 |
along with this program; if not, write to the Free Software |
16 |
Foundation, Inc., 59 Temple Place - Suite 330, |
17 |
Boston, MA 02111-1307, USA. |
18 |
*/ |
19 |
|
20 |
#include "env.h" |
21 |
|
22 |
#include <stdlib.h> |
23 |
#include <string.h> |
24 |
#include <stdio.h> |
25 |
|
26 |
#if !defined(TEST) && !defined(VERBOSE) |
27 |
# define NDEBUG |
28 |
#endif |
29 |
|
30 |
#ifndef NDEBUG |
31 |
# include <assert.h> |
32 |
# define M(MSG) fprintf(stderr,"%s:%d: (%s) %s\n",__FILE__,__LINE__,__FUNCTION__,MSG);fflush(stderr) |
33 |
# define MC(CLR,MSG) fprintf(stderr,"\033[%sm%s:%d: (%s) %s\033[0m\n",CLR,__FILE__,__LINE__,__FUNCTION__,MSG) |
34 |
# define MM(MSG) MC("34",MSG) |
35 |
# define X(VAR) fprintf(stderr,"%s:%d: (%s) %s=%s\n",__FILE__,__LINE__,__FUNCTION__,#VAR,VAR) |
36 |
# define XC(CLR,VAR) fprintf(stderr,"\033[%sm%s:%d: (%s) %s=%s\033[0m\n",CLR,__FILE__,__LINE__,__FUNCTION__,#VAR,VAR) |
37 |
# define C(VAR) fprintf(stderr,"%s:%d: (%s) %s=%c\n",__FILE__,__LINE__,__FUNCTION__,#VAR,VAR) |
38 |
# define V(VAR) fprintf(stderr,"%s:%d: (%s) %s=%d\n",__FILE__,__LINE__,__FUNCTION__,#VAR,(VAR)) |
39 |
# define D(VAR) fprintf(stderr,"%s:%d: (%s) %s=",__FILE__,__LINE__,__FUNCTION__,#VAR);ospath_debug(VAR) |
40 |
# define DD(VAR) fprintf(stderr,"%c[34;1m%s:%d: (%s)%c[0m %s=",27,__FILE__,__LINE__,__FUNCTION__,27,#VAR);ospath_debug(VAR) |
41 |
#else |
42 |
# include <assert.h> |
43 |
# define M(MSG) ((void)0) |
44 |
# define MC(CLR,MSG) ((void)0) |
45 |
# define X(VAR) ((void)0) |
46 |
# define XC(CLR,VAR) ((void)0) |
47 |
# define C(VAR) ((void)0) |
48 |
# define V(VAR) ((void)0) |
49 |
# define D(VAR) ((void)0) |
50 |
# define DD(VAR) ((void)0) |
51 |
# define MM(VAR) ((void)0) |
52 |
#endif |
53 |
|
54 |
#if !defined(FREE) && !defined(MALLOC) |
55 |
# define FREE free |
56 |
# define MALLOC malloc |
57 |
#endif |
58 |
|
59 |
#define ENV_MAX_VAR_NAME 64 // arbitrarily |
60 |
|
61 |
char * env_subst_level(const char *path,GetEnvFn *getenvptr, int level); |
62 |
|
63 |
char * env_subst(const char *path,GetEnvFn *getenvptr){ |
64 |
char *dest; |
65 |
|
66 |
X(path); |
67 |
|
68 |
// no substitution required |
69 |
if(getenvptr==NULL){ |
70 |
dest = MALLOC(sizeof(char) * (strlen(path) + 1)); |
71 |
strcpy(dest,path); |
72 |
return dest; |
73 |
} |
74 |
|
75 |
return env_subst_level(path,getenvptr, 0); |
76 |
} |
77 |
|
78 |
char * env_subst_level(const char *path,GetEnvFn *getenvptr, int level){ |
79 |
char *dest, *dest1; |
80 |
char *msg; |
81 |
char *p, *q, *i, *j, *val; |
82 |
char varname[ENV_MAX_VAR_NAME+1]; |
83 |
int len, vallen, newlen; |
84 |
int copy_in_place; |
85 |
size_t L; |
86 |
len = strlen(path); |
87 |
|
88 |
dest = MALLOC(sizeof(char)*(strlen(path)+1)); |
89 |
strcpy(dest,path); |
90 |
|
91 |
X(dest); |
92 |
V(len); |
93 |
|
94 |
// scan backwards for $ |
95 |
for(p=dest+len-1; p>=dest; --p){ |
96 |
C(*p); |
97 |
|
98 |
if(*p=='$'){ |
99 |
M("FOUND DOLLAR SIGN"); |
100 |
++p; |
101 |
for(i=p, j=varname; i<dest+len, j<varname+ENV_MAX_VAR_NAME; ++i,++j){ |
102 |
//C(*i); |
103 |
if(!( |
104 |
(*i >= 'A' && *i < 'Z') |
105 |
|| (*i == '_') |
106 |
)){ |
107 |
M("NON-VARNAME CHAR FOUND"); |
108 |
break; |
109 |
} |
110 |
//M("ADDING TO VARNAME"); |
111 |
*j=*i; |
112 |
} |
113 |
//M("COMPLETED VARNAME"); |
114 |
*j='\0'; |
115 |
X(varname); |
116 |
|
117 |
if(j==varname+ENV_MAX_VAR_NAME){ |
118 |
FREE(dest); |
119 |
msg = "__VAR_NAME_TOO_LONG__"; |
120 |
dest = MALLOC(sizeof(char)*(strlen(msg)+1)); |
121 |
strcpy(dest,msg); |
122 |
return dest; |
123 |
} |
124 |
M("FOUND VAR NAME"); |
125 |
X(varname); |
126 |
val = (*getenvptr)(varname); |
127 |
if(val==NULL){ |
128 |
//replace with null |
129 |
q = --p; |
130 |
for(j=i; j<dest+strlen(varname); ++j, ++q){ |
131 |
*q=*j; |
132 |
M(p); |
133 |
} |
134 |
*q='\0'; |
135 |
M(p); |
136 |
}else{ |
137 |
vallen=strlen(val); |
138 |
X(val); |
139 |
V(strlen(val)); |
140 |
X(dest); |
141 |
V(strlen(dest)); |
142 |
X(varname); |
143 |
V(strlen(varname)); |
144 |
--p; |
145 |
V((i-p)); |
146 |
C(*i); |
147 |
C(*p); |
148 |
|
149 |
if(vallen > (i-p)){ |
150 |
copy_in_place = 0; |
151 |
}else{ |
152 |
copy_in_place = 1; |
153 |
} |
154 |
|
155 |
if(copy_in_place){ |
156 |
M("COPY_IN_PLACE"); |
157 |
|
158 |
for(j=p, q=val; *q!='\0'; ++q, ++j){ |
159 |
*j=*q; |
160 |
} |
161 |
|
162 |
X(p); |
163 |
X(i); |
164 |
C(*j); |
165 |
|
166 |
for(q=i;*q!='\0'; ++q, ++j){ |
167 |
*j=*q; |
168 |
C(*q); |
169 |
} |
170 |
*j='\0'; |
171 |
|
172 |
}else{ |
173 |
MC("1","COPY FROM DUPLICATE"); |
174 |
newlen = strlen(dest)+vallen-(i-p); |
175 |
|
176 |
dest1 = MALLOC(sizeof(char)*(newlen+1)); |
177 |
strcpy(dest1,dest); |
178 |
|
179 |
p = dest1 + (p - dest); |
180 |
|
181 |
X(p); |
182 |
X(i); |
183 |
X(dest1); |
184 |
|
185 |
for(j=p, q=val; *q!='\0'; ++q, ++j){ |
186 |
C(*q); |
187 |
*j=*q; |
188 |
} |
189 |
X(p); |
190 |
|
191 |
X(dest); |
192 |
for(q=i;*q!='\0'; ++q, ++j){ |
193 |
C(*q); |
194 |
*j=*q; |
195 |
} |
196 |
|
197 |
*j='\0'; |
198 |
|
199 |
i = dest1 + (i - dest); |
200 |
|
201 |
/* throw away the old copy */ |
202 |
FREE(dest); |
203 |
dest = dest1; |
204 |
|
205 |
} |
206 |
|
207 |
XC("34;1",dest); |
208 |
|
209 |
/* move to the the end of the just-inserted chars */ |
210 |
p = i+1; |
211 |
C(*p); |
212 |
|
213 |
} |
214 |
|
215 |
} |
216 |
} |
217 |
M("DONE"); |
218 |
return dest; |
219 |
} |
220 |
|
221 |
/*-------------------------------- |
222 |
some simple test routines... |
223 |
*/ |
224 |
#ifdef TEST |
225 |
|
226 |
#include <assert.h> |
227 |
|
228 |
// switch to boldface for messages in 'main' |
229 |
#undef D |
230 |
#define D DD |
231 |
#undef M |
232 |
#define M MM |
233 |
|
234 |
int main(void){ |
235 |
char s1[]="$ASCENDTK/bitmaps"; |
236 |
char *r; |
237 |
|
238 |
M(s1); |
239 |
|
240 |
r = env_subst(s1,getenv); |
241 |
M(r); |
242 |
|
243 |
//assert(strcmp(r,"C:/msys/1.0/share/ascend/share")==0); |
244 |
} |
245 |
|
246 |
#endif |