/[ascend]/trunk/base/generic/utilities/ascEnvVar.c
ViewVC logotype

Contents of /trunk/base/generic/utilities/ascEnvVar.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1639 - (show annotations) (download) (as text)
Thu Nov 8 12:50:01 2007 UTC (13 years ago) by jpye
File MIME type: text/x-csrc
File size: 12444 byte(s)
Removed lint.
test_parse_string_module is working now.
1 /*
2 * Ascend Environment Variable Imitation
3 * by Ben Allan
4 * Created: 6/3/97
5 * Version: $Revision: 1.5 $
6 * Version control file: $RCSfile: ascEnvVar.c,v $
7 * Date last modified: $Date: 1997/07/18 12:04:07 $
8 * Last modified by: $Author: mthomas $
9 *
10 * This file is part of the Ascend Language Interpreter.
11 *
12 * Copyright (C) 1997 Benjamin Andrew Allan
13 *
14 * The Ascend Language Interpreter is free software; you can redistribute
15 * it and/or modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
18 *
19 * The Ascend Language Interpreter is distributed in hope that it will be
20 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with the program; if not, write to the Free Software Foundation,
26 * Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check the file named
27 * COPYING.
28 *
29 * This file exists because win32, among others, can't keep their
30 * POSIX compliance up. In particular, getting and setting
31 * environment vars is exceedingly unreliable.
32 * This file implements a general way to store and fetch multiple
33 * paths.
34 */
35
36 #include <ctype.h>
37 #include "ascConfig.h"
38 #include "ascPanic.h"
39 #include "ascMalloc.h"
40 #include "ascEnvVar.h"
41 #include <general/list.h>
42
43 #ifdef __WIN32__
44 #define SLASH '\\'
45 #define PATHDIV ';'
46 #else /* ! __WIN32__ */
47 #define SLASH '/'
48 #define PATHDIV ':'
49 #endif
50
51 /*
52 * structure we have for each envvar.
53 * each contains a list with pointers to strings.
54 */
55 struct asc_env_t {
56 const char *name;
57 struct gl_list_t *data;
58 };
59
60 /*
61 * This list is a list of pointer to struct asc_env_t's
62 * that constitute the environment.
63 */
64
65 static
66 struct gl_list_t *g_env_list = NULL;
67
68 /*
69 * ev = CreateEnvVar(envvar_name_we_own);
70 * Returns NULL, or the asc_env_t requested.
71 * The requested has an empty gl_list.
72 * The name sent is the user's responsibility if we
73 * return NULL, OTHERWISE it is henceforth ours.
74 * We do not append the requested to the global list; that is the
75 * caller's job.
76 */
77 static
78 struct asc_env_t *CreateEnvVar(char *keepname)
79 {
80 struct asc_env_t *ev;
81 ev = ASC_NEW(struct asc_env_t);
82 if (ev == NULL) {
83 return NULL;
84 }
85 ev->data = gl_create(4);
86 ev->name = keepname;
87 return ev;
88 }
89
90 /*
91 * clear out a env variable data blob.
92 */
93 static
94 void DestroyEnvVar(struct asc_env_t *ev)
95 {
96 if (ev==NULL) {
97 return;
98 }
99 ascfree((char *)ev->name);
100 gl_free_and_destroy(ev->data);
101 ascfree(ev);
102 }
103
104 /*
105 * compare two env variable data blobs by name.
106 */
107
108 CmpFunc CmpEv;
109
110 static
111 int CmpEV(struct asc_env_t *ev1, struct asc_env_t *ev2)
112 {
113 if (ev1==ev2) {
114 return 0;
115 }
116 if (ev1==NULL || ev1->name == NULL) {
117 return 1;
118 }
119 if (ev2==NULL || ev2->name == NULL) {
120 return -1;
121 }
122 return strcmp(ev1->name,ev2->name);
123 }
124
125 /*
126 * returns the envvar with the name specified.
127 */
128 static
129 struct asc_env_t *FindEnvVar(const char *name)
130 {
131 unsigned long pos;
132 struct asc_env_t dummy;
133
134 dummy.name = name;
135 pos = gl_search(g_env_list,&dummy,(CmpFunc)CmpEV);
136 if (pos==0) {
137 #if 0
138 FPRINTF(ASCERR,"ENV VAR '%s' NOT FOUND\n",name);
139 #endif
140 return NULL;
141 }
142 return (struct asc_env_t *)gl_fetch(g_env_list,pos);
143 }
144
145 /*
146 * add a var to the global sorted list.
147 */
148 static
149 void AppendEnvVar(struct gl_list_t *env, struct asc_env_t *ev)
150 {
151 gl_insert_sorted(env,ev,(CmpFunc)CmpEV);
152 }
153
154 /*
155 * removes and destroys a var in the environment, if it exists.
156 */
157 static
158 void DeleteEnvVar(char *name)
159 {
160 unsigned long pos;
161 struct asc_env_t *ev;
162 struct asc_env_t dummy;
163
164 dummy.name = name;
165
166 if (name == NULL || g_env_list == NULL) {
167 return;
168 }
169 pos = gl_search(g_env_list,&dummy,(CmpFunc)CmpEV);
170 ev = (struct asc_env_t *)gl_fetch(g_env_list,pos);
171 gl_delete(g_env_list,pos,0);
172 DestroyEnvVar(ev);
173 }
174
175 int Asc_InitEnvironment(unsigned long len)
176 {
177 if (g_env_list != NULL) {
178 return 1;
179 }
180 g_env_list = gl_create(len);
181 if (g_env_list == NULL) {
182 return 1;
183 }
184 return 0;
185 }
186
187
188 void Asc_DestroyEnvironment(void)
189 {
190 if (g_env_list == NULL) {
191 return;
192 }
193 gl_iterate(g_env_list,(void (*)(VOIDPTR))DestroyEnvVar);
194 gl_destroy(g_env_list);
195 g_env_list = NULL;
196 }
197
198
199 int Asc_SetPathList(CONST char *envvar, CONST char *pathstring)
200 {
201 char g_path_var[MAX_ENV_VAR_LENGTH];
202 unsigned int c, length, spcseen=0;
203 struct asc_env_t *ev;
204 char *keepname;
205 CONST char *path;
206 char *putenvstring;
207
208 if ((g_env_list == NULL) ||
209 (envvar == NULL) ||
210 (strlen(envvar) == 0) ||
211 (pathstring == NULL) ||
212 (strlen(pathstring) == 0) ||
213 (strlen(envvar) >= MAX_ENV_VAR_LENGTH)) {
214 return 1;
215 }
216 /*
217 * transform envvar into a string w/out lead/trail blanks and copy.
218 */
219 putenvstring = g_path_var;
220 snprintf(putenvstring, MAX_ENV_VAR_LENGTH, "%s", envvar);
221 /* trim leading whitespace */
222 while (isspace(putenvstring[0])) {
223 putenvstring++;
224 }
225 for (c = 0; putenvstring[c] !='\0'; c++) {
226 if (isspace(putenvstring[c])) {
227 spcseen++;
228 }
229 }
230 /* backup to before last trailing space */
231 while (isspace(putenvstring[c-1])) {
232 c--;
233 spcseen--;
234 }
235 /* check for no spaces in keepname */
236 if (spcseen) {
237 return 1;
238 }
239 keepname = ASC_NEW_ARRAY(char,c+1);
240 if (keepname == NULL) {
241 return 1;
242 }
243 strncpy(keepname, putenvstring, c);
244 keepname[c] = '\0';
245 /* delete the old variable if it was already assigned */
246 ev = FindEnvVar(keepname);
247 if (ev!=NULL) {
248 DeleteEnvVar(keepname);
249 }
250 ev = CreateEnvVar(keepname);
251 if (ev == NULL) {
252 ascfree(keepname);
253 return 1;
254 }
255 AppendEnvVar(g_env_list, ev);
256
257 /*
258 * copy/split the pathstring
259 */
260 path = pathstring;
261
262 /* strip any leading whitespace */
263 while( isspace( *path ) ) {
264 path++;
265 }
266 while( *path != '\0' ) {
267 length = 0;
268 /* copy the directory from path to the g_path_var */
269 while(( *path != PATHDIV ) &&
270 ( *path != '\0' ) &&
271 ( length < (MAX_ENV_VAR_LENGTH - 1) )) {
272 g_path_var[length++] = *(path++);
273 }
274 /* if we didn't run out of room, strip trailing whitespace */
275 if (( length > 0) && ( length < (MAX_ENV_VAR_LENGTH - 1) )) {
276 while (isspace(g_path_var[length-1])) {
277 length--;
278 }
279 }
280 /* otherwise advance to the next substring in path */
281 else {
282 while(( *path != PATHDIV ) && ( *path != '\0' )) {
283 path++;
284 }
285 }
286 /* append the value if not empty */
287 if ( length > 0 ) {
288 g_path_var[length++] = '\0';
289 if ( Asc_AppendPath(keepname,g_path_var) != 0 ) {
290 return 1;
291 }
292 }
293 /* advance path past any whitespace & delimiters */
294 while( isspace(*path) || ( *path == PATHDIV ) ) path++;
295 }
296 return 0;
297 }
298
299
300 int Asc_PutEnv(CONST char *envstring)
301 {
302 char g_path_var[MAX_ENV_VAR_LENGTH];
303 unsigned int c, length, spcseen=0, rhs;
304 struct asc_env_t *ev;
305 char *keepname, *path, *putenvstring;
306
307 if ((g_env_list == NULL) ||
308 (envstring == NULL) ||
309 (strlen(envstring) == 0) ||
310 (strlen(envstring) >= MAX_ENV_VAR_LENGTH)) {
311 return 1;
312 }
313
314 putenvstring = g_path_var;
315 snprintf(putenvstring, MAX_ENV_VAR_LENGTH, "%s", envstring);
316 /* trim leading whitespace */
317 while (isspace(putenvstring[0])) {
318 putenvstring++;
319 }
320 /* locate '=' or EOS, counting whitespace along the way */
321 for (c = 0; putenvstring[c] !='\0' && putenvstring[c] != '='; c++) {
322 if (isspace(putenvstring[c])) {
323 spcseen++;
324 }
325 }
326 /* check for empty rhs */
327 if (putenvstring[c] == '\0') {
328 return 1;
329 }
330 rhs = c;
331 /* backup space before = */
332 while (isspace(putenvstring[c-1])) {
333 c--;
334 spcseen--;
335 }
336 /* check for no spaces in keepname */
337 if (spcseen) {
338 return 1;
339 }
340 keepname = ASC_NEW_ARRAY(char,c+1);
341 if (keepname == NULL) {
342 return 1;
343 }
344 strncpy(keepname,putenvstring,c);
345 keepname[c] = '\0';
346 /* delete the old variable if it was already assigned */
347 ev = FindEnvVar(keepname);
348 if (ev!=NULL) {
349 DeleteEnvVar(keepname);
350 }
351 ev = CreateEnvVar(keepname);
352 if (ev == NULL) {
353 ascfree(keepname);
354 return 1;
355 }
356
357 AppendEnvVar(g_env_list,ev);
358 path = putenvstring + rhs + 1; /* got past the '=' */
359
360 while( isspace( *path ) ) {
361 path++;
362 }
363 while( *path != '\0' ) {
364 length = 0;
365 /* copy the directory from path to the g_path_var */
366 while(( *path != PATHDIV ) && ( *path != '\0' )) {
367 g_path_var[length++] = *(path++);
368 }
369 while (( length > 0 ) && isspace(g_path_var[length-1])) {
370 length--;
371 }
372 if ( length > 0) {
373 g_path_var[length++] = '\0';
374 if (Asc_AppendPath(keepname,g_path_var)!=0) {
375 return 1;
376 }
377 }
378 while( isspace(*path) || ( *path == PATHDIV ) ) path++;
379 }
380 return 0;
381 }
382
383
384 int Asc_ImportPathList(CONST char *envvar)
385 {
386 char *rhs;
387
388 if (( g_env_list == NULL ) ||
389 ( envvar == NULL ) ||
390 ( strlen(envvar) == 0 )) {
391 return 1;
392 }
393 rhs = getenv(envvar);
394 if (( rhs == NULL ) || ( strlen(rhs) == 0 )) {
395 return 1;
396 }
397 return Asc_SetPathList(envvar, rhs);
398 }
399
400
401 int Asc_AppendPath(char *envvar, char *newelement)
402 {
403 struct asc_env_t *ev;
404 char *keepname, *keepval;
405
406 if ((g_env_list == NULL) ||
407 (envvar == NULL) ||
408 (newelement == NULL) ||
409 (strlen(envvar) == 0) ||
410 (strlen(newelement) == 0)) {
411 return 1;
412 }
413 ev = FindEnvVar(envvar);
414 if (ev == NULL) {
415 keepname = ASC_STRDUP(envvar);
416 if (keepname == NULL) {
417 return 1;
418 }
419 ev = CreateEnvVar(keepname);
420 if (ev == NULL) {
421 ascfree(keepname);
422 return 1;
423 }
424 AppendEnvVar(g_env_list, ev);
425 }
426 keepval = ASC_STRDUP(newelement);
427
428 if (keepval == NULL) {
429 return 1;
430 }
431 gl_append_ptr(ev->data, keepval);
432 return 0;
433 }
434
435 const char **Asc_GetPathList(const char *envvar, int *argc){
436 struct asc_env_t *ev;
437 CONST char **argv;
438 char *tmppos, *val;
439 unsigned long len, c, slen;
440
441 if ( argc == NULL ) {
442 return NULL;
443 }
444 if (( g_env_list == NULL ) ||
445 ( envvar == NULL )) {
446 FPRINTF(ASCERR,"G_ENV_LIST IS NULL LOOKING FOR %s\n",envvar);
447 *argc = -1;
448 return NULL;
449 }
450 if ( strlen(envvar) == 0 ) {
451 *argc = 0;
452 return NULL;
453 }
454 ev = FindEnvVar(envvar);
455 if (ev==NULL ) {
456 FPRINTF(ASCERR,"UNABLE TO FINDENVVAR %s\n",envvar);
457
458 *argc = 0;
459 return NULL;
460 }
461 len = gl_length(ev->data);
462 slen = (len+1)*sizeof(char *); /* space for argv pointers */
463 for (c = 1; c <= len; c++) {
464 /* space for the values */
465 slen += (strlen((char *)gl_fetch(ev->data,(unsigned long)c)) +1 );
466 }
467 argv = ASC_NEW_ARRAY(CONST char *,slen);
468 if ( argv == NULL ) {
469 *argc = -1;
470 return NULL;
471 }
472 tmppos = (char *)argv;
473 tmppos += (len+1)*sizeof(char *);
474 for (c = 1 ; c <= len ; c++) {
475 val = (char *)gl_fetch(ev->data,(unsigned long)c);
476 argv[c-1] = tmppos;
477 while ( *val != '\0' ) {
478 *tmppos++ = *val++;
479 }
480 *tmppos++ = *val; /* include trailing '\0' */
481 }
482 argv[len] = NULL;
483 *argc = (int)len;
484 return argv;
485 }
486
487
488 char *Asc_GetEnv(const char *envvar)
489 {
490 struct asc_env_t *ev;
491 char *result, *val, *tmppos;
492 unsigned long slen, c, llen;
493
494 if ((g_env_list == NULL) ||
495 (envvar == NULL) ||
496 (strlen(envvar) == 0)) {
497 return NULL;
498 }
499 ev = FindEnvVar(envvar);
500 if (ev==NULL ) {
501 return NULL;
502 }
503 slen = 0;
504 llen = gl_length(ev->data);
505 for (c = 1; c <= llen; c++) {
506 slen += (strlen((char *)gl_fetch(ev->data,(unsigned long)c)) +1 );
507 }
508 result = ASC_NEW_ARRAY(char,slen+1);
509 if (result == NULL) {
510 return NULL;
511 }
512 tmppos = result;
513 for (c = 1; c <= llen; c++) {
514 val = (char *)gl_fetch(ev->data,(unsigned long)c);
515 while (*val != '\0') {
516 *tmppos++ = *val++;
517 }
518 *tmppos++ = PATHDIV; /* include delimiter */
519 }
520 result[slen-1] = '\0'; /* overwrite final trailing delimiter */
521 return result;
522 }
523
524
525 const char **Asc_EnvNames(int *argc)
526 {
527 const char **argv;
528 unsigned long c, len;
529
530 if (g_env_list == NULL) {
531 *argc = -1;
532 return NULL;
533 }
534 len = gl_length(g_env_list);
535 *argc = (int)len;
536 argv = ASC_NEW_ARRAY(CONST char *,*argc + 1);
537 if (argv==NULL) {
538 *argc = -1;
539 return NULL;
540 }
541 for (c = 1; c <= len; c++) {
542 argv[c-1] = ((struct asc_env_t *)gl_fetch(g_env_list,c))->name;
543 }
544 argv[len] = NULL;
545 return argv;
546 }

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22