Patch:Android:Applied patch 'android_fix.patch' from ticket #538 and #522, librairies...
[navit-package] / navit / support / wordexp / wordexp.c
1
2 #include <config.h>
3
4 #include <sys/types.h>
5 #include <assert.h>
6 #include <fcntl.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <unistd.h>
11 #include "wordexp.h"
12 #include "glob.h"
13
14
15 static int
16 is_valid_variable_char(char c, int pos)
17 {
18         if ( (pos && c >= '0' && c <= '9') ||
19               c == '_' ||
20              (c >= 'a' && c <= 'z') ||
21              (c >= 'A' && c <= 'Z'))
22                 return 1;
23         return 0;
24 }
25
26 /*
27  * @brief replace all names of $NAME ${NAME}
28  * with the corresponding environment variable 
29  * @ param in: the string to be checked
30  * @ return the expanded string or a copy of the existing string
31  * must be free() by the calling function 
32 */
33 static char *
34 expand_variables(const char *in)
35 {
36         char *var,*pos,*ret=strdup(in);
37         char *val,*str;
38         pos=ret;
39         while ((var=strchr(pos, '$'))) {
40                 char *name,*begin=var+1;
41                 int npos=0,bpos=0,slen,elen;
42                 *var='\0';
43                 if (var[1] == '{') {
44                         begin++;
45                         while (begin[npos]) {
46                                 bpos=npos;
47                                 if (begin[npos++] == '}') 
48                                         break;
49                         }
50                 } else {
51                         while (is_valid_variable_char(begin[npos],npos)) 
52                                 npos++; 
53                         bpos=npos;
54                 }
55                 name=strdup(begin);
56                 name[bpos]='\0';                
57                 val=getenv(name);
58                 free(name);
59                 if (! val)
60                         val="";
61                 slen=strlen(ret)+strlen(val);
62                 elen=strlen(begin+npos);
63                 str=malloc(slen+elen+1);
64                 strcpy(str,ret);
65                 strcat(str,val);
66                 strcat(str,begin+npos);
67                 free(ret);
68                 ret=str;
69                 pos=ret+slen;
70         }
71         return ret;
72 }
73
74 /*
75  * @brief minimal realization of wordexp according to IEEE standard
76  * shall perform word expansion as described in the Shell
77  * expansion of ´$NAME´ or ´${NAME}´
78  * expansion of ´*´ and ´?´
79  * @param words: pointer to a string containing one or more words to be expanded
80  * but here only one word supported
81  */
82 int 
83 wordexp(const char *words, wordexp_t *we, int flags)
84 {       
85         int     i;
86         int     error = 0;
87         char   *words_expanded;
88 #ifdef HAVE_API_WIN32_BASE
89         glob_t  pglob;
90 #endif
91
92         assert(we != NULL);
93         assert(words != NULL);
94  
95         /* expansion of ´$NAME´ or ´${NAME}´ */
96         words_expanded=expand_variables(words);
97 #ifdef HAVE_API_WIN32_BASE
98         /* expansion of ´*´, ´?´ */
99         error=glob(words_expanded, 0, NULL, &pglob);
100         if (!error)
101         {
102                 /* copy the content of struct of glob into struct of wordexp */
103                 we->we_wordc = pglob.gl_pathc;
104                 we->we_offs = pglob.gl_offs;
105                 we->we_wordv = malloc(we->we_wordc * sizeof(char*));
106                 for (i=0; i<we->we_wordc; i++)
107                 {
108                         we->we_wordv[i] = strdup(pglob.gl_pathv[i]);
109                 }               
110                 globfree(&pglob);
111                 free(words_expanded);
112         }
113         else
114         {
115 #endif
116                 we->we_wordc = 1;               
117                 we->we_wordv = malloc(sizeof(char*));   
118                 we->we_wordv[0] = words_expanded;
119 #ifdef HAVE_API_WIN32_BASE
120         }
121 #endif
122
123
124         return error;   
125 }
126
127
128 void wordfree(wordexp_t *we)
129 {
130         int i;
131
132         for (i=0; i < we->we_wordc; i++)
133         {
134                 free (we->we_wordv[i]);
135         }
136         
137         free (we->we_wordv);
138         we->we_wordc = 0;
139 }