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 |
|
79 |
int env_import(const char *varname,GetEnvFn *getenvptr,PutEnvFn *putenvptr){ |
80 |
char *val = (*getenvptr)(varname); |
81 |
char *envcmd; |
82 |
if(val!=NULL){ |
83 |
envcmd = MALLOC(sizeof(char) * (strlen(varname) + 1 + strlen(val) + 1)); |
84 |
sprintf(envcmd,"%s=%s",varname,val); |
85 |
return (*putenvptr)(envcmd); |
86 |
} |
87 |
return -1; |
88 |
} |
89 |
|
90 |
char * env_subst_level(const char *path,GetEnvFn *getenvptr, int level){ |
91 |
char *dest, *dest1; |
92 |
char *msg; |
93 |
char *p, *q, *i, *j, *val; |
94 |
char varname[ENV_MAX_VAR_NAME+1]; |
95 |
int len, vallen, newlen; |
96 |
int copy_in_place; |
97 |
size_t L; |
98 |
len = strlen(path); |
99 |
|
100 |
dest = MALLOC(sizeof(char)*(strlen(path)+1)); |
101 |
strcpy(dest,path); |
102 |
|
103 |
X(dest); |
104 |
V(len); |
105 |
|
106 |
// scan backwards for $ |
107 |
for(p=dest+len-1; p>=dest; --p){ |
108 |
C(*p); |
109 |
|
110 |
if(*p=='$'){ |
111 |
M("FOUND DOLLAR SIGN"); |
112 |
++p; |
113 |
for(i=p, j=varname; i<dest+len, j<varname+ENV_MAX_VAR_NAME; ++i,++j){ |
114 |
//C(*i); |
115 |
if(!( |
116 |
(*i >= 'A' && *i < 'Z') |
117 |
|| (*i == '_') |
118 |
)){ |
119 |
M("NON-VARNAME CHAR FOUND"); |
120 |
break; |
121 |
} |
122 |
//M("ADDING TO VARNAME"); |
123 |
*j=*i; |
124 |
} |
125 |
//M("COMPLETED VARNAME"); |
126 |
*j='\0'; |
127 |
X(varname); |
128 |
|
129 |
if(j==varname+ENV_MAX_VAR_NAME){ |
130 |
FREE(dest); |
131 |
msg = "__VAR_NAME_TOO_LONG__"; |
132 |
dest = MALLOC(sizeof(char)*(strlen(msg)+1)); |
133 |
strcpy(dest,msg); |
134 |
return dest; |
135 |
} |
136 |
M("FOUND VAR NAME"); |
137 |
X(varname); |
138 |
val = (*getenvptr)(varname); |
139 |
if(val==NULL){ |
140 |
//replace with null |
141 |
q = --p; |
142 |
for(j=i; j<dest+strlen(varname); ++j, ++q){ |
143 |
*q=*j; |
144 |
M(p); |
145 |
} |
146 |
*q='\0'; |
147 |
M(p); |
148 |
}else{ |
149 |
vallen=strlen(val); |
150 |
X(val); |
151 |
V(strlen(val)); |
152 |
X(dest); |
153 |
V(strlen(dest)); |
154 |
X(varname); |
155 |
V(strlen(varname)); |
156 |
--p; |
157 |
V((i-p)); |
158 |
C(*i); |
159 |
C(*p); |
160 |
|
161 |
if(vallen > (i-p)){ |
162 |
copy_in_place = 0; |
163 |
}else{ |
164 |
copy_in_place = 1; |
165 |
} |
166 |
|
167 |
if(copy_in_place){ |
168 |
M("COPY_IN_PLACE"); |
169 |
|
170 |
for(j=p, q=val; *q!='\0'; ++q, ++j){ |
171 |
*j=*q; |
172 |
} |
173 |
|
174 |
X(p); |
175 |
X(i); |
176 |
C(*j); |
177 |
|
178 |
for(q=i;*q!='\0'; ++q, ++j){ |
179 |
*j=*q; |
180 |
C(*q); |
181 |
} |
182 |
*j='\0'; |
183 |
|
184 |
}else{ |
185 |
MC("1","COPY FROM DUPLICATE"); |
186 |
newlen = strlen(dest)+vallen-(i-p); |
187 |
|
188 |
dest1 = MALLOC(sizeof(char)*(newlen+1)); |
189 |
strcpy(dest1,dest); |
190 |
|
191 |
p = dest1 + (p - dest); |
192 |
|
193 |
X(p); |
194 |
X(i); |
195 |
X(dest1); |
196 |
|
197 |
for(j=p, q=val; *q!='\0'; ++q, ++j){ |
198 |
C(*q); |
199 |
*j=*q; |
200 |
} |
201 |
X(p); |
202 |
|
203 |
X(dest); |
204 |
for(q=i;*q!='\0'; ++q, ++j){ |
205 |
C(*q); |
206 |
*j=*q; |
207 |
} |
208 |
|
209 |
*j='\0'; |
210 |
|
211 |
i = dest1 + (i - dest); |
212 |
|
213 |
/* throw away the old copy */ |
214 |
FREE(dest); |
215 |
dest = dest1; |
216 |
|
217 |
} |
218 |
|
219 |
XC("34;1",dest); |
220 |
|
221 |
/* move to the the end of the just-inserted chars */ |
222 |
p = i+1; |
223 |
C(*p); |
224 |
|
225 |
} |
226 |
|
227 |
} |
228 |
} |
229 |
M("DONE"); |
230 |
return dest; |
231 |
} |
232 |
|
233 |
/*-------------------------------- |
234 |
some simple test routines... |
235 |
*/ |
236 |
#ifdef TEST |
237 |
|
238 |
#include <assert.h> |
239 |
|
240 |
// switch to boldface for messages in 'main' |
241 |
#undef D |
242 |
#define D DD |
243 |
#undef M |
244 |
#define M MM |
245 |
|
246 |
int main(void){ |
247 |
char s1[]="$ASCENDTK/bitmaps"; |
248 |
char *r; |
249 |
|
250 |
M(s1); |
251 |
|
252 |
r = env_subst(s1,getenv); |
253 |
M(r); |
254 |
|
255 |
//assert(strcmp(r,"C:/msys/1.0/share/ascend/share")==0); |
256 |
} |
257 |
|
258 |
#endif |