1212#include "sysroots.h"
1313
1414#include "gaputils.h"
15+ #include "listfunc.h"
1516#include "plist.h"
1617#include "stringobj.h"
1718#include "sysfiles.h"
@@ -47,8 +48,7 @@ char SyDefaultRootPath[GAP_PATH_MAX] = "./";
4748** name of a library file 'strcat( SyGapRootPaths[i], "lib/init.g" );' must
4849** be a valid filename.
4950*/
50- enum { MAX_GAP_DIRS = 16 };
51- static Char SyGapRootPaths [MAX_GAP_DIRS ][GAP_PATH_MAX ];
51+ Obj SyGapRootPaths ;
5252
5353
5454/****************************************************************************
@@ -62,13 +62,12 @@ static Char SyGapRootPaths[MAX_GAP_DIRS][GAP_PATH_MAX];
6262Obj SyFindGapRootFile (const Char * filename )
6363{
6464 int len = strlen (filename );
65- for (int k = 0 ; k < ARRAY_SIZE (SyGapRootPaths ); k ++ ) {
66- if (SyGapRootPaths [k ][0 ]) {
67- Obj path = MakeString (SyGapRootPaths [k ]);
68- AppendCStr (path , filename , len );
69- if (SyIsReadableFile (CSTR_STRING (path )) == 0 ) {
70- return path ;
71- }
65+ int npaths = LEN_PLIST (SyGapRootPaths );
66+ for (int k = 1 ; k <= npaths ; k ++ ) {
67+ Obj path = CopyToStringRep (ELM_PLIST (SyGapRootPaths , k ));
68+ AppendCStr (path , filename , len );
69+ if (SyIsReadableFile (CSTR_STRING (path )) == 0 ) {
70+ return path ;
7271 }
7372 }
7473 return 0 ;
@@ -95,10 +94,12 @@ Obj SyFindGapRootFile(const Char * filename)
9594*/
9695void SySetGapRootPath (const Char * string )
9796{
98- const Char * p ;
99- Char * q ;
100- Int i ;
101- Int n ;
97+ Int pos = 1 ;
98+
99+ if (SyGapRootPaths == 0 ) {
100+ SyGapRootPaths = NEW_PLIST (T_PLIST_EMPTY , 0 ); // FIXME
101+ }
102+
102103
103104 // set string to a default value if unset
104105 if (string == 0 || * string == 0 ) {
@@ -107,110 +108,79 @@ void SySetGapRootPath(const Char * string)
107108
108109 // check if we append, prepend or overwrite.
109110 if (string [0 ] == ';' ) {
110- // Count the number of root directories already present.
111- n = 0 ;
112- while (SyGapRootPaths [n ][0 ] != '\0' )
113- n ++ ;
111+ // append
112+ pos = LEN_PLIST (SyGapRootPaths ) + 1 ;
114113
115114 // Skip leading semicolon.
116115 string ++ ;
117116 }
118117 else if (string [strlen (string ) - 1 ] == ';' ) {
119- // Count the number of directories in 'string'.
120- n = 0 ;
121- p = string ;
122- while (* p )
123- if (* p ++ == ';' )
124- n ++ ;
125-
126- // Find last root path.
127- for (i = 0 ; i < MAX_GAP_DIRS ; i ++ )
128- if (SyGapRootPaths [i ][0 ] == '\0' )
129- break ;
130- i -- ;
131-
132- #ifdef HPCGAP
133- n *= 2 ; // for each root <ROOT> we also add <ROOT/hpcgap> as a root
134- #endif
135-
136- // Move existing root paths to the back
137- if (i + n >= MAX_GAP_DIRS )
138- return ;
139- while (i >= 0 ) {
140- memcpy (SyGapRootPaths [i + n ], SyGapRootPaths [i ],
141- sizeof (SyGapRootPaths [i + n ]));
142- i -- ;
143- }
144-
145- n = 0 ;
118+ // prepend
146119 }
147120 else {
148- // Make sure to wipe out all possibly existing root paths
149- for (i = 0 ; i < MAX_GAP_DIRS ; i ++ )
150- SyGapRootPaths [i ][0 ] = '\0' ;
151- n = 0 ;
121+ SET_LEN_PLIST (SyGapRootPaths , 0 );
122+ RetypeBagSM (SyGapRootPaths , T_PLIST_EMPTY );
123+ // TODO: also adjust filters...
152124 }
153125
154126 // unpack the argument
155- p = string ;
127+ const Char * p = string ;
156128 while (* p ) {
157- if (n >= MAX_GAP_DIRS )
158- return ;
159-
160- q = SyGapRootPaths [n ];
161- while (* p && * p != ';' ) {
162- * q = * p ++ ;
163-
164- #ifdef SYS_IS_CYGWIN32
165- // change backslash to slash for Windows
166- if (* q == '\\' )
167- * q = '/' ;
168- #endif
129+ Obj path ;
169130
131+ // locate next semicolon or string end
132+ const Char * q = p ;
133+ while (* q && * q != ';' ) {
170134 q ++ ;
171135 }
172- if (q == SyGapRootPaths [n ]) {
173- strxcpy (SyGapRootPaths [n ], "./" , sizeof (SyGapRootPaths [n ]));
174- }
175- else if (q [-1 ] != '/' ) {
176- * q ++ = '/' ;
177- * q = '\0' ;
178- }
179- else {
180- * q = '\0' ;
181- }
182- if (* p ) {
183- p ++ ;
136+
137+ if (q == p ) {
138+ // empty string treated as ./
139+ path = MakeString ("./" );
140+ // TODO: insert output of getcwd??
141+ } else {
142+ if (* p == '~' ) {
143+ const char * userhome = getenv ("HOME" );
144+ if (!userhome )
145+ userhome = "" ;
146+ path = MakeString (userhome );
147+ p ++ ;
148+ AppendCStr (path , p , q - p );
149+ }
150+ else {
151+ path = MakeStringWithLen (p , q - p );
152+ }
153+
154+ Char * r = CSTR_STRING (path );
155+ #ifdef SYS_IS_CYGWIN32
156+ while (* r ) {
157+ // change backslash to slash for Windows
158+ if (* r == '\\' )
159+ * r = '/' ;
160+ r ++ ;
161+ }
162+ #endif
163+
164+ // ensure path ends with a slash
165+ r = CSTR_STRING (path ) + GET_LEN_STRING (path ) - 1 ;
166+ if (* r != '/' ) {
167+ AppendCStr (path , "/" , 1 );
168+ }
184169 }
185- n ++ ;
170+
171+ p = * q ? q + 1 : q ;
172+
173+ AddPlist3 (SyGapRootPaths , path , pos );
174+ pos ++ ;
175+
186176#ifdef HPCGAP
187177 // for each root <ROOT> to be added, we first add <ROOT/hpcgap> as a root
188- if (n < MAX_GAP_DIRS ) {
189- gap_strlcpy (SyGapRootPaths [n ], SyGapRootPaths [n - 1 ],
190- sizeof (SyGapRootPaths [n ]));
191- }
192- strxcat (SyGapRootPaths [n - 1 ], "hpcgap/" ,
193- sizeof (SyGapRootPaths [n - 1 ]));
194- n ++ ;
195- #endif
196- }
178+ path = CopyToStringRep (path );
179+ AppendCStr (path , "hpcgap/" , 7 );
197180
198- // replace leading tilde ~ by HOME environment variable
199- // TODO; instead of iterating over all entries each time, just
200- // do this for the new entries
201- char * userhome = getenv ("HOME" );
202- if (!userhome || !* userhome )
203- return ;
204- const UInt userhomelen = strlen (userhome );
205- for (i = 0 ; i < MAX_GAP_DIRS && SyGapRootPaths [i ][0 ]; i ++ ) {
206- const UInt pathlen = strlen (SyGapRootPaths [i ]);
207- if (SyGapRootPaths [i ][0 ] == '~' &&
208- userhomelen + pathlen < sizeof (SyGapRootPaths [i ])) {
209- SyMemmove (SyGapRootPaths [i ] + userhomelen ,
210- // don't copy the ~ but the trailing '\0'
211- SyGapRootPaths [i ] + 1 , pathlen );
212- memcpy (SyGapRootPaths [i ], userhome , userhomelen );
213- }
181+ AddPlist3 (SyGapRootPaths , path , pos );
182+ pos ++ ;
183+ #endif
214184 }
215185}
216186
@@ -221,12 +191,5 @@ void SySetGapRootPath(const Char * string)
221191*/
222192Obj SyGetGapRootPaths (void )
223193{
224- Obj tmp = NEW_PLIST_IMM (T_PLIST , MAX_GAP_DIRS );
225- for (int i = 0 ; i < MAX_GAP_DIRS ; i ++ ) {
226- if (SyGapRootPaths [i ][0 ]) {
227- PushPlist (tmp , MakeImmString (SyGapRootPaths [i ]));
228- }
229- }
230- MakeImmutableNoRecurse (tmp );
231- return tmp ;
194+ return SyGapRootPaths ;
232195}
0 commit comments