1 |
/* ASCEND modeling 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 |
/* hard wiring NDEBUG here is a misuse of NDEBUG and causes errors/warning |
28 |
on the compile line. renamed to NOISY.*/ |
29 |
# define NOISY 1 |
30 |
#endif |
31 |
|
32 |
#ifndef NOISY |
33 |
# include <assert.h> |
34 |
# define M(MSG) fprintf(stderr,"%s:%d: (%s) %s\n",__FILE__,__LINE__,__FUNCTION__,MSG);fflush(stderr) |
35 |
# define MC(CLR,MSG) fprintf(stderr,"\033[%sm%s:%d: (%s) %s\033[0m\n",CLR,__FILE__,__LINE__,__FUNCTION__,MSG) |
36 |
# define MM(MSG) MC("34",MSG) |
37 |
# define X(VAR) fprintf(stderr,"%s:%d: (%s) %s=%s\n",__FILE__,__LINE__,__FUNCTION__,#VAR,VAR) |
38 |
# define XC(CLR,VAR) fprintf(stderr,"\033[%sm%s:%d: (%s) %s=%s\033[0m\n",CLR,__FILE__,__LINE__,__FUNCTION__,#VAR,VAR) |
39 |
# define C(VAR) fprintf(stderr,"%s:%d: (%s) %s=%c\n",__FILE__,__LINE__,__FUNCTION__,#VAR,VAR) |
40 |
# define V(VAR) fprintf(stderr,"%s:%d: (%s) %s=%d\n",__FILE__,__LINE__,__FUNCTION__,#VAR,(VAR)) |
41 |
# define D(VAR) fprintf(stderr,"%s:%d: (%s) %s=",__FILE__,__LINE__,__FUNCTION__,#VAR);ospath_debug(VAR) |
42 |
# define DD(VAR) fprintf(stderr,"%c[34;1m%s:%d: (%s)%c[0m %s=",27,__FILE__,__LINE__,__FUNCTION__,27,#VAR);ospath_debug(VAR) |
43 |
#else /* NOISY*/ |
44 |
# include <assert.h> |
45 |
# define M(MSG) ((void)0) |
46 |
# define MC(CLR,MSG) ((void)0) |
47 |
# define X(VAR) ((void)0) |
48 |
# define XC(CLR,VAR) ((void)0) |
49 |
# define C(VAR) ((void)0) |
50 |
# define V(VAR) ((void)0) |
51 |
# define D(VAR) ((void)0) |
52 |
# define DD(VAR) ((void)0) |
53 |
# define MM(VAR) ((void)0) |
54 |
#endif /* NOISY*/ |
55 |
|
56 |
#if !defined(FREE) && !defined(MALLOC) |
57 |
# define FREE free |
58 |
# define MALLOC malloc |
59 |
#endif |
60 |
|
61 |
#define ENV_MAX_VAR_NAME 64 /* arbitrarily*/ |
62 |
|
63 |
char * env_subst_level(const char *path,GetEnvFn *getenvptr, int level); |
64 |
|
65 |
char * env_subst(const char *path,GetEnvFn *getenvptr){ |
66 |
char *dest; |
67 |
|
68 |
X(path); |
69 |
|
70 |
/* no substitution required */ |
71 |
if(getenvptr==NULL){ |
72 |
dest = MALLOC(sizeof(char) * (strlen(path) + 1)); |
73 |
strcpy(dest,path); |
74 |
return dest; |
75 |
} |
76 |
|
77 |
return env_subst_level(path,getenvptr, 0); |
78 |
} |
79 |
|
80 |
|
81 |
int env_import(const char *varname,GetEnvFn *getenvptr,PutEnvFn *putenvptr){ |
82 |
char *val = (*getenvptr)(varname); |
83 |
char *envcmd; |
84 |
if(val!=NULL){ |
85 |
envcmd = MALLOC(sizeof(char) * (strlen(varname) + 1 + strlen(val) + 1)); |
86 |
sprintf(envcmd,"%s=%s",varname,val); |
87 |
return (*putenvptr)(envcmd); |
88 |
} |
89 |
return -1; |
90 |
} |
91 |
|
92 |
char * env_subst_level(const char *path,GetEnvFn *getenvptr, int level){ |
93 |
char *dest, *dest1; |
94 |
char *msg; |
95 |
char *p, *q, *i, *j, *val; |
96 |
char varname[ENV_MAX_VAR_NAME+1]; |
97 |
int len, vallen, newlen; |
98 |
int copy_in_place; |
99 |
/*size_t L;*/ |
100 |
(void)level; |
101 |
len = strlen(path); |
102 |
|
103 |
dest = MALLOC(sizeof(char)*(strlen(path)+1)); |
104 |
strcpy(dest,path); |
105 |
|
106 |
X(dest); |
107 |
V(len); |
108 |
|
109 |
/* scan backwards for $ */ |
110 |
for(p=dest+len-1; p>=dest; --p){ |
111 |
C(*p); |
112 |
|
113 |
if(*p=='$'){ |
114 |
M("FOUND DOLLAR SIGN"); |
115 |
++p; |
116 |
/* FIXME: note this is i = j = varname in C; p is ignored. */ |
117 |
for(i=p, j=varname; i<dest+len && j<varname+ENV_MAX_VAR_NAME; ++i,++j){ |
118 |
/*C(*i);*/ |
119 |
if(!( |
120 |
(*i >= 'A' && *i < 'Z') |
121 |
|| (*i == '_') |
122 |
)){ |
123 |
M("NON-VARNAME CHAR FOUND"); |
124 |
break; |
125 |
} |
126 |
/*M("ADDING TO VARNAME");*/ |
127 |
*j=*i; |
128 |
} |
129 |
/*M("COMPLETED VARNAME");*/ |
130 |
*j='\0'; |
131 |
X(varname); |
132 |
|
133 |
if(j==varname+ENV_MAX_VAR_NAME){ |
134 |
FREE(dest); |
135 |
msg = "__VAR_NAME_TOO_LONG__"; |
136 |
dest = MALLOC(sizeof(char)*(strlen(msg)+1)); |
137 |
strcpy(dest,msg); |
138 |
return dest; |
139 |
} |
140 |
M("FOUND VAR NAME"); |
141 |
X(varname); |
142 |
val = (*getenvptr)(varname); |
143 |
if(val==NULL){ |
144 |
/*replace with null*/ |
145 |
q = --p; |
146 |
for(j=i; j<dest+strlen(varname); ++j, ++q){ |
147 |
*q=*j; |
148 |
M(p); |
149 |
} |
150 |
*q='\0'; |
151 |
M(p); |
152 |
}else{ |
153 |
vallen=strlen(val); |
154 |
X(val); |
155 |
V(strlen(val)); |
156 |
X(dest); |
157 |
V(strlen(dest)); |
158 |
X(varname); |
159 |
V(strlen(varname)); |
160 |
--p; |
161 |
V((i-p)); |
162 |
C(*i); |
163 |
C(*p); |
164 |
|
165 |
if(vallen > (i-p)){ |
166 |
copy_in_place = 0; |
167 |
}else{ |
168 |
copy_in_place = 1; |
169 |
} |
170 |
|
171 |
if(copy_in_place){ |
172 |
M("COPY_IN_PLACE"); |
173 |
|
174 |
for(j=p, q=val; *q!='\0'; ++q, ++j){ |
175 |
*j=*q; |
176 |
} |
177 |
|
178 |
X(p); |
179 |
X(i); |
180 |
C(*j); |
181 |
|
182 |
for(q=i;*q!='\0'; ++q, ++j){ |
183 |
*j=*q; |
184 |
C(*q); |
185 |
} |
186 |
*j='\0'; |
187 |
|
188 |
}else{ |
189 |
MC("1","COPY FROM DUPLICATE"); |
190 |
newlen = strlen(dest)+vallen-(i-p); |
191 |
|
192 |
dest1 = MALLOC(sizeof(char)*(newlen+1)); |
193 |
strcpy(dest1,dest); |
194 |
|
195 |
p = dest1 + (p - dest); |
196 |
|
197 |
X(p); |
198 |
X(i); |
199 |
X(dest1); |
200 |
|
201 |
for(j=p, q=val; *q!='\0'; ++q, ++j){ |
202 |
C(*q); |
203 |
*j=*q; |
204 |
} |
205 |
X(p); |
206 |
|
207 |
X(dest); |
208 |
for(q=i;*q!='\0'; ++q, ++j){ |
209 |
C(*q); |
210 |
*j=*q; |
211 |
} |
212 |
|
213 |
*j='\0'; |
214 |
|
215 |
i = dest1 + (i - dest); |
216 |
|
217 |
/* throw away the old copy */ |
218 |
FREE(dest); |
219 |
dest = dest1; |
220 |
|
221 |
} |
222 |
|
223 |
XC("34;1",dest); |
224 |
|
225 |
/* move to the the end of the just-inserted chars */ |
226 |
p = i+1; |
227 |
C(*p); |
228 |
|
229 |
} |
230 |
|
231 |
} |
232 |
} |
233 |
M("DONE"); |
234 |
return dest; |
235 |
} |
236 |
|
237 |
/*-------------------------------- |
238 |
some simple test routines... |
239 |
*/ |
240 |
#ifdef TEST |
241 |
|
242 |
#include <assert.h> |
243 |
|
244 |
/* switch to boldface for messages in 'main' */ |
245 |
#undef D |
246 |
#define D DD |
247 |
#undef M |
248 |
#define M MM |
249 |
|
250 |
int main(void){ |
251 |
char s1[]="$ASCENDTK/bitmaps"; |
252 |
char *r; |
253 |
|
254 |
M(s1); |
255 |
|
256 |
r = env_subst(s1,getenv); |
257 |
M(r); |
258 |
|
259 |
/*assert(strcmp(r,"C:/msys/1.0/share/ascend/share")==0);*/ |
260 |
} |
261 |
|
262 |
#endif |