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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1639 - (hide annotations) (download) (as text)
Thu Nov 8 12:50:01 2007 UTC (13 years, 2 months ago) by jpye
File MIME type: text/x-csrc
File size: 12444 byte(s)
Removed lint.
test_parse_string_module is working now.
1 aw0a 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 johnpye 399 #include "ascConfig.h"
38     #include "ascPanic.h"
39     #include "ascMalloc.h"
40     #include "ascEnvVar.h"
41     #include <general/list.h>
42 aw0a 1
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 johnpye 908 const char *name;
57 aw0a 1 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 johnpye 341
65 aw0a 1 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 johnpye 709 ev = ASC_NEW(struct asc_env_t);
82 aw0a 1 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 johnpye 908 ascfree((char *)ev->name);
100 aw0a 1 gl_free_and_destroy(ev->data);
101     ascfree(ev);
102     }
103    
104     /*
105     * compare two env variable data blobs by name.
106     */
107 johnpye 956
108     CmpFunc CmpEv;
109    
110     static
111 aw0a 1 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 johnpye 589 struct asc_env_t *FindEnvVar(const char *name)
130 aw0a 1 {
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 johnpye 908 #if 0
138     FPRINTF(ASCERR,"ENV VAR '%s' NOT FOUND\n",name);
139     #endif
140 aw0a 1 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 jds 59 int Asc_InitEnvironment(unsigned long len)
176 aw0a 1 {
177 jds 59 if (g_env_list != NULL) {
178 aw0a 1 return 1;
179     }
180 jds 59 g_env_list = gl_create(len);
181     if (g_env_list == NULL) {
182 aw0a 1 return 1;
183     }
184     return 0;
185     }
186    
187 jds 59
188 aw0a 1 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 jds 59
199 aw0a 1 int Asc_SetPathList(CONST char *envvar, CONST char *pathstring)
200     {
201 jds 59 char g_path_var[MAX_ENV_VAR_LENGTH];
202     unsigned int c, length, spcseen=0;
203 aw0a 1 struct asc_env_t *ev;
204     char *keepname;
205     CONST char *path;
206     char *putenvstring;
207    
208 jds 59 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 aw0a 1 return 1;
215     }
216     /*
217 jds 59 * transform envvar into a string w/out lead/trail blanks and copy.
218 aw0a 1 */
219     putenvstring = g_path_var;
220 jds 59 snprintf(putenvstring, MAX_ENV_VAR_LENGTH, "%s", envvar);
221 aw0a 1 /* 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 jds 59 /* backup to before last trailing space */
231 aw0a 1 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 johnpye 708 keepname = ASC_NEW_ARRAY(char,c+1);
240 aw0a 1 if (keepname == NULL) {
241     return 1;
242     }
243 jds 59 strncpy(keepname, putenvstring, c);
244 aw0a 1 keepname[c] = '\0';
245 jds 59 /* delete the old variable if it was already assigned */
246 aw0a 1 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 jds 59 AppendEnvVar(g_env_list, ev);
256    
257     /*
258 johnpye 341 * copy/split the pathstring
259 jds 59 */
260 aw0a 1 path = pathstring;
261    
262 jds 59 /* strip any leading whitespace */
263 aw0a 1 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 jds 59 while(( *path != PATHDIV ) &&
270     ( *path != '\0' ) &&
271     ( length < (MAX_ENV_VAR_LENGTH - 1) )) {
272 aw0a 1 g_path_var[length++] = *(path++);
273     }
274 jds 59 /* 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 aw0a 1 }
280 jds 59 /* otherwise advance to the next substring in path */
281     else {
282     while(( *path != PATHDIV ) && ( *path != '\0' )) {
283     path++;
284     }
285 aw0a 1 }
286 jds 59 /* 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 aw0a 1 while( isspace(*path) || ( *path == PATHDIV ) ) path++;
295     }
296     return 0;
297     }
298    
299 jds 59
300 johnpye 341 int Asc_PutEnv(CONST char *envstring)
301 aw0a 1 {
302 jds 59 char g_path_var[MAX_ENV_VAR_LENGTH];
303     unsigned int c, length, spcseen=0, rhs;
304 aw0a 1 struct asc_env_t *ev;
305     char *keepname, *path, *putenvstring;
306    
307 jds 59 if ((g_env_list == NULL) ||
308     (envstring == NULL) ||
309     (strlen(envstring) == 0) ||
310     (strlen(envstring) >= MAX_ENV_VAR_LENGTH)) {
311 aw0a 1 return 1;
312     }
313 jds 59
314 aw0a 1 putenvstring = g_path_var;
315 jds 59 snprintf(putenvstring, MAX_ENV_VAR_LENGTH, "%s", envstring);
316 aw0a 1 /* trim leading whitespace */
317     while (isspace(putenvstring[0])) {
318     putenvstring++;
319     }
320 jds 59 /* locate '=' or EOS, counting whitespace along the way */
321 aw0a 1 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 johnpye 708 keepname = ASC_NEW_ARRAY(char,c+1);
341 aw0a 1 if (keepname == NULL) {
342     return 1;
343     }
344     strncpy(keepname,putenvstring,c);
345     keepname[c] = '\0';
346 jds 59 /* delete the old variable if it was already assigned */
347 aw0a 1 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 jds 103
357 aw0a 1 AppendEnvVar(g_env_list,ev);
358 jds 59 path = putenvstring + rhs + 1; /* got past the '=' */
359 aw0a 1
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 jds 59 while (( length > 0 ) && isspace(g_path_var[length-1])) {
370 aw0a 1 length--;
371     }
372 jds 59 if ( length > 0) {
373     g_path_var[length++] = '\0';
374     if (Asc_AppendPath(keepname,g_path_var)!=0) {
375     return 1;
376     }
377 aw0a 1 }
378     while( isspace(*path) || ( *path == PATHDIV ) ) path++;
379     }
380     return 0;
381     }
382    
383 jds 59
384 aw0a 1 int Asc_ImportPathList(CONST char *envvar)
385     {
386 jds 59 char *rhs;
387    
388     if (( g_env_list == NULL ) ||
389     ( envvar == NULL ) ||
390     ( strlen(envvar) == 0 )) {
391 aw0a 1 return 1;
392     }
393     rhs = getenv(envvar);
394 johnpye 589 if (( rhs == NULL ) || ( strlen(rhs) == 0 )) {
395 aw0a 1 return 1;
396     }
397 jds 59 return Asc_SetPathList(envvar, rhs);
398 aw0a 1 }
399    
400 jds 59
401 aw0a 1 int Asc_AppendPath(char *envvar, char *newelement)
402     {
403     struct asc_env_t *ev;
404     char *keepname, *keepval;
405 jds 59
406     if ((g_env_list == NULL) ||
407     (envvar == NULL) ||
408     (newelement == NULL) ||
409     (strlen(envvar) == 0) ||
410     (strlen(newelement) == 0)) {
411 aw0a 1 return 1;
412     }
413     ev = FindEnvVar(envvar);
414     if (ev == NULL) {
415 johnpye 1220 keepname = ASC_STRDUP(envvar);
416 aw0a 1 if (keepname == NULL) {
417     return 1;
418     }
419     ev = CreateEnvVar(keepname);
420     if (ev == NULL) {
421     ascfree(keepname);
422     return 1;
423     }
424 jds 59 AppendEnvVar(g_env_list, ev);
425 aw0a 1 }
426 johnpye 1220 keepval = ASC_STRDUP(newelement);
427 jds 59
428 aw0a 1 if (keepval == NULL) {
429     return 1;
430     }
431 jds 59 gl_append_ptr(ev->data, keepval);
432 aw0a 1 return 0;
433     }
434    
435 johnpye 1061 const char **Asc_GetPathList(const char *envvar, int *argc){
436 aw0a 1 struct asc_env_t *ev;
437 johnpye 908 CONST char **argv;
438 aw0a 1 char *tmppos, *val;
439 jds 59 unsigned long len, c, slen;
440 aw0a 1
441 jds 59 if ( argc == NULL ) {
442     return NULL;
443     }
444     if (( g_env_list == NULL ) ||
445     ( envvar == NULL )) {
446 johnpye 62 FPRINTF(ASCERR,"G_ENV_LIST IS NULL LOOKING FOR %s\n",envvar);
447 aw0a 1 *argc = -1;
448     return NULL;
449     }
450 jds 59 if ( strlen(envvar) == 0 ) {
451 aw0a 1 *argc = 0;
452     return NULL;
453     }
454     ev = FindEnvVar(envvar);
455     if (ev==NULL ) {
456 johnpye 62 FPRINTF(ASCERR,"UNABLE TO FINDENVVAR %s\n",envvar);
457    
458 aw0a 1 *argc = 0;
459     return NULL;
460     }
461 jds 59 len = gl_length(ev->data);
462     slen = (len+1)*sizeof(char *); /* space for argv pointers */
463 aw0a 1 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 johnpye 908 argv = ASC_NEW_ARRAY(CONST char *,slen);
468 jds 59 if ( argv == NULL ) {
469 aw0a 1 *argc = -1;
470     return NULL;
471     }
472     tmppos = (char *)argv;
473     tmppos += (len+1)*sizeof(char *);
474 jds 59 for (c = 1 ; c <= len ; c++) {
475 aw0a 1 val = (char *)gl_fetch(ev->data,(unsigned long)c);
476     argv[c-1] = tmppos;
477 jds 59 while ( *val != '\0' ) {
478     *tmppos++ = *val++;
479     }
480     *tmppos++ = *val; /* include trailing '\0' */
481 aw0a 1 }
482     argv[len] = NULL;
483     *argc = (int)len;
484     return argv;
485     }
486    
487 jds 59
488 johnpye 586 char *Asc_GetEnv(const char *envvar)
489 aw0a 1 {
490     struct asc_env_t *ev;
491     char *result, *val, *tmppos;
492 jds 59 unsigned long slen, c, llen;
493    
494     if ((g_env_list == NULL) ||
495     (envvar == NULL) ||
496     (strlen(envvar) == 0)) {
497 aw0a 1 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 johnpye 708 result = ASC_NEW_ARRAY(char,slen+1);
509 aw0a 1 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 jds 59 while (*val != '\0') {
516     *tmppos++ = *val++;
517     }
518     *tmppos++ = PATHDIV; /* include delimiter */
519 aw0a 1 }
520 jds 59 result[slen-1] = '\0'; /* overwrite final trailing delimiter */
521 aw0a 1 return result;
522     }
523    
524 jds 59
525 johnpye 908 const char **Asc_EnvNames(int *argc)
526 aw0a 1 {
527 johnpye 908 const char **argv;
528 aw0a 1 unsigned long c, len;
529 jds 59
530 aw0a 1 if (g_env_list == NULL) {
531     *argc = -1;
532     return NULL;
533     }
534     len = gl_length(g_env_list);
535     *argc = (int)len;
536 johnpye 908 argv = ASC_NEW_ARRAY(CONST char *,*argc + 1);
537 aw0a 1 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