/[ascend]/trunk/base/generic/general/ospath.c
ViewVC logotype

Annotation of /trunk/base/generic/general/ospath.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 551 - (hide annotations) (download) (as text)
Sat Apr 29 04:19:17 2006 UTC (13 years, 11 months ago) by johnpye
File MIME type: text/x-csrc
File size: 33503 byte(s)
Added LICENSE.txt to root directory
Fixed a 'const' problem in ospath
Fixed up some variable names and key errors in SConstruct
Modified License-Warranty.tcl in accordance with the recommendations in the GPL.
1 johnpye 541 #include <string.h>
2     #include <malloc.h>
3 johnpye 534 #include <stdio.h>
4 johnpye 535 #include <ctype.h>
5 johnpye 534
6     #include "ospath.h"
7    
8 johnpye 541 // to test this code, 'gcc -DTEST ospath.c && ./a'
9    
10     #if defined(WIN32) || defined(__WIN32) || defined(_MSC_VER)
11     # ifndef __WIN32__
12     # define __WIN32__
13     # endif
14     #endif
15 johnpye 542
16 johnpye 543 #define VERBOSE
17 johnpye 541
18 johnpye 542 #if !defined(TEST) && !defined(VERBOSE)
19 johnpye 541 # define NDEBUG
20     #endif
21 johnpye 542
22     //#define TRY_GETPWUID
23    
24     #define DO_FIXSLASHES
25 johnpye 541
26     #ifndef NDEBUG
27     # include <assert.h>
28     # define M(MSG) fprintf(stderr,"%s:%d: (%s) %s\n",__FILE__,__LINE__,__FUNCTION__,MSG)
29     # define X(VAR) fprintf(stderr,"%s:%d: (%s) %s=%s\n",__FILE__,__LINE__,__FUNCTION__,#VAR,VAR)
30     # define V(VAR) fprintf(stderr,"%s:%d: (%s) %s=%d\n",__FILE__,__LINE__,__FUNCTION__,#VAR,(VAR))
31     # define D(VAR) fprintf(stderr,"%s:%d: (%s) %s=",__FILE__,__LINE__,__FUNCTION__,#VAR);ospath_debug(VAR)
32     #else
33     # include <assert.h>
34     # define M(MSG) ((void)0)
35     # define X(VAR) ((void)0)
36     # define V(VAR) ((void)0)
37     # define D(VAR) ((void)0)
38     #endif
39    
40     #if defined(__WIN32__) && !defined(__MINGW32__)
41     # include <direct.h>
42     # include <stdlib.h>
43     # define STRCPY strcpy
44     # define STRNCPY(dest,src,n) strncpy_s(dest,n,src,n)
45     # define STRCAT strcat
46     # define STRNCAT strncat
47     # define STRTOK(STR,PAT,VAR) strtok_s(STR,PAT,&VAR)
48     # define STRTOKVAR(VAR) char *VAR
49     # define GETCWD getcwd
50     # define GETENV(VAR) getenv(VAR)
51     #else
52     # define STRCPY strcpy
53     # define STRNCPY(dest,src,n) strncpy(dest,src,n)
54     # define STRCAT strcat
55     # define STRNCAT strncat
56     # define STRTOK(STR,PAT,VAR) strtok(STR,PAT)
57     # define STRTOKVAR(VAR) ((void)0)
58     # define GETCWD getcwd
59     # define GETENV(VAR) getenv(VAR)
60     #endif
61    
62 johnpye 542 // PATH_MAX is in ospath.h
63 johnpye 541 #define DRIVEMAX 3
64     #define LISTMAX 256
65    
66     #ifdef __WIN32__ /* && !defined(__MINGW32__) */
67 johnpye 534 # define WINPATHS
68     #endif
69    
70     struct FilePath{
71 johnpye 542 char path[PATH_MAX]; /// the string version of the represented POSIX path
72 johnpye 534
73     #ifdef WINPATHS
74 johnpye 541 char drive[DRIVEMAX]; /// the drive the path resides on (field is absent in POSIX systems)
75 johnpye 534 #endif
76     };
77    
78     #include <string.h>
79    
80     #define MALLOC malloc
81     #define FREE free
82     #define CALLOC calloc
83    
84     #define E(MSG) fprintf(stderr,"%s:%d: (%s) ERROR: %s\n",__FILE__,__LINE__,__FUNCTION__,MSG)
85 johnpye 542
86     #ifdef DO_FIXSLASHES
87     void ospath_fixslash(char *path);
88     #endif
89 johnpye 534
90 johnpye 541 struct FilePath *ospath_getcwd();
91    
92 johnpye 534 /**
93     This function cleans up the path string used to construct the FilePath object:
94     1. Get rid of multiple / 's one after the other...
95    
96     ie. "///usr/bin///hello/////there// --> "/usr/bin/hello/there/"
97    
98 johnpye 535 2. Resolve a leading tilde (~) to the current user's HOME path
99 johnpye 534
100 johnpye 535 3. Remove redundant /./ in middle of path
101    
102     4. Remove reduncant dir/.. in path
103    
104     5. Environment substitution??
105    
106     6. On windows, drive reference if not specified
107    
108     7. What about \\server\path and URLs, gnomefs, etc?
109 johnpye 534 */
110     void ospath_cleanup(struct FilePath *);
111    
112     void ospath_copy(struct FilePath *dest, struct FilePath *src);
113    
114    
115     #ifdef WINPATHS
116     /**
117     This function splits out the drive letter in the path string, thus completing
118     the correct construction of a FilePath object under Win32.
119     */
120     void ospath_extractdriveletter(struct FilePath *);
121     #endif
122    
123     #ifdef WINPATHS
124     # define PATH_SEPARATOR_STR "\\"
125     # define PATH_SEPARATOR_CHAR '\\'
126 johnpye 541 # define PATH_LISTSEP_CHAR ';'
127 johnpye 542 # define PATH_LISTSEP_STR ";"
128     # define PATH_WRONGSLASH_CHAR '/'
129     # define PATH_WRONGSLASH_STR "/"
130 johnpye 534 #else
131     # define PATH_SEPARATOR_STR "/"
132     # define PATH_SEPARATOR_CHAR '/'
133 johnpye 541 # define PATH_LISTSEP_CHAR ':'
134     # define PATH_LISTSEP_STR ":"
135 johnpye 542 # define PATH_WRONGSLASH_CHAR '\\'
136     # define PATH_WRONGSLASH_STR "\\"
137 johnpye 534 #endif
138    
139     /**
140     Create a new path structure from a string
141     */
142     struct FilePath *ospath_new(const char *path){
143     struct FilePath *fp;
144     fp = MALLOC(sizeof(struct FilePath));
145 johnpye 542 STRNCPY(fp->path, path, PATH_MAX);
146 johnpye 541 //X(fp->path);
147     //X(path);
148     assert(strcmp(fp->path,path)==0);
149 johnpye 534 #ifdef WINPATHS
150 johnpye 541 //X(fp->drive);
151 johnpye 534 ospath_extractdriveletter(fp);
152     #endif
153    
154 johnpye 541 //X(fp->drive);
155    
156 johnpye 542 #ifdef DO_FIXSLASHES
157 johnpye 541 ospath_fixslash(fp->path);
158     #endif
159    
160 johnpye 534 ospath_cleanup(fp);
161    
162 johnpye 541 //D(fp);
163    
164 johnpye 534 return fp;
165     }
166    
167 johnpye 541 void ospath_free(struct FilePath *fp){
168     FREE(fp);
169     }
170    
171 johnpye 534 /**
172 johnpye 535 This function will serve to allow #include-style file paths
173     to be specified with platform-independent forward slashes then
174     translated into the local filesystem format for subsequent use.
175    
176     This method should be identical to ospath_new on posix, right?
177    
178     @NOTE: on windows, we also want:
179     C:dir/file --> c:$PWD\dir\file
180     e:/hello --> e:\hello
181     here/i/am --> here\i\am
182    
183     @NOTE:
184     A path-search function should create full file paths by
185     appending relative file to each component of the search path
186     then performing a callback on each one to determine if the
187     match is OK or not.
188     */
189 johnpye 551 struct FilePath *ospath_new_from_posix(const char *posixpath){
190 johnpye 535 struct FilePath *fp = MALLOC(sizeof(struct FilePath));
191 johnpye 542 STRNCPY(fp->path,posixpath,PATH_MAX);
192 johnpye 535 #ifdef WINPATHS
193     X(fp->path);
194     ospath_extractdriveletter(fp);
195     #endif
196    
197 johnpye 542 #ifdef DO_FIXSLASHES
198 johnpye 541 ospath_fixslash(fp->path);
199     #endif
200 johnpye 535
201 johnpye 541 //X(fp->path);
202    
203     ospath_cleanup(fp);
204    
205     return fp;
206     }
207 johnpye 542
208     #ifdef DO_FIXSLASHES
209 johnpye 541 void ospath_fixslash(char *path){
210    
211     char *p;
212 johnpye 542 char temp[PATH_MAX];
213 johnpye 541 int startslash;
214     int endslash;
215     STRTOKVAR(nexttok);
216    
217 johnpye 542 STRNCPY(temp,path,PATH_MAX);
218 johnpye 541
219 johnpye 535 //X(path);
220    
221 johnpye 542 startslash = (strlen(temp) > 0 && temp[0] == PATH_WRONGSLASH_CHAR);
222     endslash = (strlen(temp) > 1 && temp[strlen(temp) - 1] == PATH_WRONGSLASH_CHAR);
223 johnpye 535
224     //V(startslash);
225     //V(endslash);
226    
227     // reset fp->path as required.
228 johnpye 542 STRNCPY(path, (startslash ? PATH_SEPARATOR_STR : ""), PATH_MAX);
229 johnpye 535
230 johnpye 541 //M("STARTING STRTOK");
231 johnpye 542 for(p = STRTOK(temp, PATH_WRONGSLASH_STR,nexttok);
232 johnpye 535 p!=NULL;
233 johnpye 542 p = STRTOK(NULL,PATH_WRONGSLASH_STR,nexttok)
234 johnpye 535 ){
235     // add a separator if we've already got some stuff
236     if(
237 johnpye 541 strlen(path) > 0
238     && path[strlen(path) - 1] != PATH_SEPARATOR_CHAR
239 johnpye 535 ){
240 johnpye 541 STRCAT(path,PATH_SEPARATOR_STR);
241 johnpye 535 }
242    
243 johnpye 541 STRCAT(path,p);
244 johnpye 535 }
245 johnpye 541 //M("FINISHED STRTOK");
246 johnpye 535
247     // put / on end as required, according to what the starting path had
248 johnpye 541 if(endslash && (strlen(path) > 0 ? (path[strlen(path) - 1] != PATH_SEPARATOR_CHAR) : 1))
249 johnpye 535 {
250     //M("adding endslash!");
251    
252 johnpye 541 STRCAT(path, PATH_SEPARATOR_STR);
253 johnpye 535 }
254    
255 johnpye 541 //X(path);
256 johnpye 542 }
257     #endif
258 johnpye 535
259 johnpye 542
260 johnpye 541 /// Create but with no 'cleanup' call
261 johnpye 534 struct FilePath *ospath_new_noclean(const char *path){
262     struct FilePath *fp = MALLOC(sizeof(struct FilePath));
263 johnpye 542 STRNCPY(fp->path,path,PATH_MAX);
264 johnpye 534
265     #ifdef WINPATHS
266 johnpye 541 //X(fp->path);
267 johnpye 534 ospath_extractdriveletter(fp);
268     #endif
269    
270 johnpye 541 //D(fp);
271    
272     /*
273 johnpye 542 #ifdef DO_FIXSLASHES
274 johnpye 541 ospath_fixslash(fp->path);
275     D(fp);
276     #endif
277     */
278 johnpye 534 return fp;
279     }
280    
281 johnpye 541 struct FilePath *ospath_getcwd(void){
282     struct FilePath *fp = MALLOC(sizeof(struct FilePath));
283     char *cwd;
284    
285     // get current working directory
286     cwd = (char *)GETCWD(NULL, 0);
287    
288     // create new path with resolved working directory
289     fp = ospath_new_noclean(cwd != NULL ? cwd : ".");
290    
291     D(fp);
292    
293     return fp;
294     }
295    
296 johnpye 534 /**
297     Use getenv() function to retrieve HOME path, or if not set, use
298     the password database and try to retrieve it that way (???)
299     */
300     struct FilePath *ospath_gethomepath(void){
301    
302 johnpye 542 const char *pfx = (const char *)getenv("HOME");
303 johnpye 541 struct FilePath *fp;
304 johnpye 534
305 johnpye 542 #ifndef __WIN32__
306     # ifdef TRY_GETPWUID
307 johnpye 541 struct passwd *pw;
308    
309 johnpye 534 if(pfx==NULL){
310 johnpye 542 pw = (struct passwd*)getpwuid(getuid());
311 johnpye 534
312     if(pw){
313 johnpye 542 pfx = pw->pw_dir;
314 johnpye 534 }
315 johnpye 542 }
316     # endif
317 johnpye 534 #endif
318    
319 johnpye 541 // create path object from HOME, but don't compress it
320     // (because that would lead to an infinite loop)
321     fp = ospath_new_noclean(pfx ? pfx : "");
322    
323 johnpye 542 #ifdef DO_FIXSLASHES
324 johnpye 541 ospath_fixslash(fp->path);
325     #endif
326    
327     return fp;
328 johnpye 534 }
329    
330     #ifdef WINPATHS
331     void ospath_extractdriveletter(struct FilePath *fp)
332     {
333 johnpye 541 char *p;
334     //M("SOURCE");
335     //X(fp->path);
336     //fprintf(stderr,"CHAR 1 = %c\n",fp->path[1]);
337    
338 johnpye 534 // extract the drive the path resides on...
339     if(strlen(fp->path) >= 2 && fp->path[1] == ':')
340     {
341 johnpye 541 STRNCPY(fp->drive,fp->path,2);
342     fp->drive[2]='\0';
343     for(p=fp->path+2; *p!='\0'; ++p){
344     *(p-2)=*p;
345 johnpye 534 }
346 johnpye 541 *(p-2)='\0';
347 johnpye 535 }else{
348 johnpye 541 STRNCPY(fp->drive,"",DRIVEMAX);
349 johnpye 534 }
350 johnpye 541 //M("RESULT");
351     //X(fp->path);
352     //X(fp->drive);
353 johnpye 534 }
354     #endif
355    
356     void ospath_cleanup(struct FilePath *fp){
357 johnpye 542 char path[PATH_MAX];
358 johnpye 534 char *p;
359     struct FilePath *home;
360 johnpye 541 struct FilePath *working;
361 johnpye 534 struct FilePath *parent;
362 johnpye 541 STRTOKVAR(nexttok);
363 johnpye 534
364     // compress the path, and resolve ~
365     int startslash = (strlen(fp->path) > 0 && fp->path[0] == PATH_SEPARATOR_CHAR);
366     int endslash = (strlen(fp->path) > 1 && fp->path[strlen(fp->path) - 1] == PATH_SEPARATOR_CHAR);
367    
368 johnpye 535 //fprintf(stderr,"FS ON START = %d\n",startslash);
369     //fprintf(stderr,"FS ON END = %d\n",endslash);
370     //fprintf(stderr,"FIRST CHAR = %c\n",fp->path[0]);
371 johnpye 534
372     home = ospath_gethomepath();
373    
374     // create a copy of fp->path.
375 johnpye 541 STRCPY(path, fp->path);
376 johnpye 534
377     // reset fp->path as required.
378 johnpye 541 STRCPY(fp->path, (startslash ? PATH_SEPARATOR_STR : ""));
379 johnpye 534
380 johnpye 541 X(path);
381 johnpye 534
382 johnpye 541 // split path into it tokens, using STRTOK which is NOT reentrant
383 johnpye 534 // so be careful!
384    
385 johnpye 541 //M("STARTING STRTOK");
386     for(p = STRTOK(path, PATH_SEPARATOR_STR,nexttok);
387 johnpye 534 p!=NULL;
388 johnpye 541 p = STRTOK(NULL,PATH_SEPARATOR_STR,nexttok)
389 johnpye 534 ){
390 johnpye 541 //M("NEXT TOKEN");
391 johnpye 535 //X(p);
392 johnpye 541 //X(path+strlen(p)+1);
393 johnpye 534 if(strcmp(p, "~")==0){
394    
395     if(p == path){ // check that the ~ is the first character in the path
396     if(ospath_isvalid(home)){
397     ospath_copy(fp,home);
398     continue;
399     }else{
400     E("HOME does not resolve to valid path");
401     }
402     }else{
403     E("A tilde (~) present as a component in a file path must be at the start!");
404     }
405     }else if(strcmp(p, ".") == 0){
406    
407     if(p==path){// start of path:
408     M("EXPANDING LEADING '.' IN PATH");
409 johnpye 541 X(path);
410 johnpye 534
411 johnpye 541 working = ospath_getcwd();
412 johnpye 534
413 johnpye 541 D(working);
414 johnpye 542 #ifdef WINPATHS
415     X(working->drive);
416     #endif
417 johnpye 541 X(p);
418     X(path);
419 johnpye 534
420 johnpye 541 ospath_copy(fp,working);
421    
422    
423     D(fp);
424     X(p);
425     //X(path+strlen(p)+1);
426    
427     //ospath_free(working);
428 johnpye 534 continue;
429     }else{// later in the path: just skip it
430     M("SKIPPING '.' IN PATH");
431     continue;
432     }
433    
434     }else if(strcmp(p, "..") == 0){
435     M("GOING TO PARENT");
436     parent = ospath_getparent(fp);
437     if(ospath_isvalid(parent)){
438     ospath_copy(fp,parent);
439     }
440 johnpye 541 //ospath_free(parent);
441 johnpye 534 continue;
442     }
443    
444     // add a separator if we've already got some stuff
445     if(
446     strlen(fp->path) > 0
447     && fp->path[strlen(fp->path) - 1] != PATH_SEPARATOR_CHAR
448     ){
449 johnpye 541 STRCAT(fp->path,PATH_SEPARATOR_STR);
450 johnpye 534 }
451    
452     // add the present path component
453 johnpye 541 STRCAT(fp->path, p);
454 johnpye 534 }
455 johnpye 541 //M("FINISHED STRTOK");
456 johnpye 534
457     // put / on end as required, according to what the starting path had
458     if(endslash && (strlen(fp->path) > 0 ? (fp->path[strlen(fp->path) - 1] != PATH_SEPARATOR_CHAR) : 1))
459     {
460 johnpye 541 STRCAT(fp->path, PATH_SEPARATOR_STR);
461 johnpye 534 }
462     }
463    
464    
465 johnpye 542 int ospath_isvalid(struct FilePath *fp){
466     //if(fp==NULL) return 0;
467 johnpye 534 return strlen(fp->path) > 0 ? 1 : 0;
468     }
469    
470    
471     char *ospath_str(struct FilePath *fp){
472     char *s;
473     #ifdef WINPATHS
474     s = CALLOC(strlen(fp->drive)+strlen(fp->path),sizeof(char));
475 johnpye 541 STRCPY(s,fp->drive);
476     STRCAT(s,fp->path);
477 johnpye 534 #else
478     s = CALLOC(strlen(fp->path),sizeof(char));
479 johnpye 541 STRCPY(s,fp->path);
480 johnpye 534 #endif
481     return s;
482     }
483 johnpye 542
484     void ospath_strcpy(struct FilePath *fp, char *dest, int destsize){
485     #ifdef WINPATHS
486     STRNCPY(dest,fp->drive,destsize);
487     STRNCAT(dest,fp->path,destsize-strlen(dest));
488     #else
489     STRNCPY(dest,fp->path,destsize);
490     #endif
491     }
492 johnpye 534
493     void ospath_fwrite(struct FilePath *fp, FILE *dest){
494     #ifdef WINPATHS
495     fprintf(dest,"%s%s",fp->drive,fp->path);
496     #else
497     fprintf(dest,"%s",fp->path);
498     #endif
499     }
500    
501     unsigned ospath_length(struct FilePath *fp){
502     #ifdef WINPATHS
503     // we've already validated this path, so it's on to just add it up
504     // (unless someone has been tinkering with the internal structure here)
505     return (unsigned) (strlen(fp->drive) + strlen(fp->path));
506     #else
507     return (unsigned) (strlen(fp->path));
508     #endif
509     }
510    
511     struct FilePath *ospath_getparent(struct FilePath *fp)
512     {
513 johnpye 541 int length;
514     int offset;
515     char *pos;
516     int len1;
517 johnpye 542 char sub[PATH_MAX];
518 johnpye 541 struct FilePath *fp1;
519    
520     D(fp);
521    
522 johnpye 534 if(strlen(fp->path) == 0 || ospath_isroot(fp))
523     {
524     // return empty path.
525     return ospath_new("");
526     }
527    
528     // reverse find a / ignoring the end / if it exists.
529 johnpye 541 /// FIXME
530     length = strlen(fp->path);
531     offset = (
532     fp->path[length - 1] == PATH_SEPARATOR_CHAR // last char is slash?
533     && length > 1 // and more than just leading slash...
534     ) ? length - 1 : length; // then remove last char
535 johnpye 534
536 johnpye 541 for(pos = fp->path + offset - 1; *pos!=PATH_SEPARATOR_CHAR && pos>=fp->path; --pos){
537     //fprintf(stderr,"CURRENT CHAR: %c\n",*pos);
538     }
539    
540     len1 = (int)pos - (int)fp->path;
541     //fprintf(stderr,"POS = %d\n",len1);
542    
543     if(*pos==PATH_SEPARATOR_CHAR){
544 johnpye 534 #ifdef WINPATHS
545 johnpye 541 STRCPY(sub,fp->drive);
546 johnpye 542 STRNCAT(sub,fp->path,len1);
547     #else
548     STRNCPY(sub,fp->path,len1);
549     sub[len1]='\0';
550 johnpye 534 #endif
551 johnpye 541 X(sub);
552     if(strcmp(sub,"")==0){
553     M("DIRECTORY IS EMPTY");
554     STRCAT(sub,PATH_SEPARATOR_STR);
555     }
556 johnpye 534 }else{
557 johnpye 541 E("NO PARENT DIR");
558     return ospath_new_noclean(fp->path);
559 johnpye 534 }
560 johnpye 541
561     fp1 = ospath_new_noclean(sub);
562     D(fp1);
563     return fp1;
564 johnpye 534 }
565    
566     struct FilePath *ospath_getparentatdepthn(struct FilePath *fp, unsigned depth)
567     {
568 johnpye 541 int startslash;
569 johnpye 542 char path[PATH_MAX];
570 johnpye 541 char *temp;
571     char *p;
572     STRTOKVAR(nexttok);
573     #ifdef WINPATHS
574 johnpye 542 char temp2[PATH_MAX];
575 johnpye 541 #endif
576    
577 johnpye 534 if(
578     !ospath_isvalid(fp)
579     || depth >= ospath_depth(fp)
580     ){
581     return fp;
582     }
583    
584     // create FilePath object to parent object at depth N relative to this
585     // path object.
586 johnpye 541 startslash = (strlen(fp->path) > 0 && fp->path[0] == PATH_SEPARATOR_CHAR);
587 johnpye 534
588     // create a copy of fp->path.
589 johnpye 541 STRCPY(path, fp->path);
590 johnpye 534
591     // reset fp->path as required.
592 johnpye 541 temp = startslash ? PATH_SEPARATOR_STR : "";
593 johnpye 534
594     // split path into it tokens.
595 johnpye 541 //M("STARTING STRTOK");
596     p = STRTOK(path, PATH_SEPARATOR_STR, nexttok);
597 johnpye 534
598     while(p && depth > 0)
599     {
600     if(strlen(temp) > 0 && temp[strlen(temp) - 1] != PATH_SEPARATOR_CHAR)
601     {
602 johnpye 542 strcat(temp,PATH_SEPARATOR_STR);
603 johnpye 534 }
604    
605 johnpye 541 STRCAT(temp,p);
606 johnpye 534 --depth;
607    
608 johnpye 541 p = STRTOK(NULL, PATH_SEPARATOR_STR, nexttok);
609 johnpye 534 }
610 johnpye 541 //M("FINISHED STRTOK");
611 johnpye 534
612     // put / on end as required
613     if(strlen(temp) > 0 ? (temp[strlen(temp) - 1] != PATH_SEPARATOR_CHAR) : 1)
614     {
615 johnpye 542 strcat(temp,PATH_SEPARATOR_STR);
616 johnpye 534 }
617    
618     #ifdef WINPATHS
619 johnpye 541 STRCPY(temp2,fp->drive);
620     STRCAT(temp2,temp);
621 johnpye 534 return ospath_new_noclean(temp2);
622     #else
623     return ospath_new_noclean(temp);
624     #endif
625     }
626    
627     char *ospath_getbasefilename(struct FilePath *fp){
628     char *temp;
629 johnpye 541 unsigned length, offset;
630     char *pos;
631 johnpye 534
632     if(strlen(fp->path) == 0){
633     // return empty name.
634     return "";
635     }
636 johnpye 542
637     if(fp->path[strlen(fp->path)-1]==PATH_SEPARATOR_CHAR){
638     return NULL;
639     }
640    
641     // reverse find '/' but DON'T ignore a trailing slash
642     // (this is changed from the original implementation)
643 johnpye 541 length = strlen(fp->path);
644 johnpye 542 offset = length;
645 johnpye 534
646 johnpye 541 pos = strrchr(fp->path, PATH_SEPARATOR_CHAR); /* OFFSET! */
647 johnpye 534
648     // extract filename given position of find / and return it.
649 johnpye 542 if(pos != NULL){
650     unsigned length1 = length - ((pos - fp->path) + 1);
651 johnpye 534 temp = CALLOC(length1,sizeof(char));
652 johnpye 543
653 johnpye 542 V(length1);
654 johnpye 541 STRNCPY(temp, pos + 1, length1);
655 johnpye 534 return temp;
656     }else{
657     temp = CALLOC(length,sizeof(char));
658 johnpye 541 STRNCPY(temp, fp->path, length);
659 johnpye 534 return temp;
660     }
661     }
662    
663 johnpye 542 char *ospath_getfilestem(struct FilePath *fp){
664 johnpye 541 char *temp;
665     char *pos;
666    
667 johnpye 534 if(!ospath_isvalid(fp)){
668     return NULL;
669     }
670    
671 johnpye 542 temp = ospath_getbasefilename(fp);
672     if(temp==NULL){
673     // it's a directory
674     return NULL;
675     }
676    
677 johnpye 541 pos = strrchr(temp,'.');
678 johnpye 542
679     if(pos==NULL || pos==temp){
680     // no extension, or a filename starting with '.'
681     // -- return the whole filename
682     return temp;
683     }
684    
685     // remove extension.
686     *pos = '\0';
687    
688 johnpye 534 return temp;
689     }
690    
691 johnpye 542 char *ospath_getfileext(struct FilePath *fp){
692 johnpye 541 char *temp, *temp2, *pos;
693     int len1;
694    
695 johnpye 534 if(!ospath_isvalid(fp)){
696     return NULL;
697     }
698    
699 johnpye 542 temp = ospath_getbasefilename(fp);
700     if(temp==NULL){
701     // it's a directory
702     return NULL;
703     }
704 johnpye 534
705 johnpye 542 // make sure there is no / on the end.
706     /// FIXME: is this good policy, removing a trailing slash?
707 johnpye 534 if(temp[strlen(temp) - 1] == PATH_SEPARATOR_CHAR){
708     temp[strlen(temp)-1] = '\0';
709     }
710    
711 johnpye 541 pos = strrchr(temp,'.');
712 johnpye 534
713 johnpye 542 if(pos != NULL && pos!=temp){
714 johnpye 534 // extract extension.
715 johnpye 541 len1 = temp + strlen(temp) - pos;
716 johnpye 534 temp2 = CALLOC(len1, sizeof(char));
717 johnpye 541 STRNCPY(temp2, pos, len1);
718 johnpye 534 }else{
719     // no extension
720     temp2 = NULL;
721     }
722     FREE(temp);
723     return temp2;
724     }
725    
726     int ospath_isroot(struct FilePath *fp)
727     {
728     if(!ospath_isvalid(fp))
729     {
730     return 0;
731     }
732    
733     return fp->path == PATH_SEPARATOR_STR ? 1 : 0;
734     }
735    
736     unsigned ospath_depth(struct FilePath *fp){
737     unsigned length;
738     unsigned depth;
739     unsigned i;
740    
741     length = strlen(fp->path);
742     depth = 0;
743    
744     for(i = 0; i < length; i++){
745     if(fp->path[i] == PATH_SEPARATOR_CHAR){
746     ++depth;
747     }
748     }
749    
750     if(
751     depth > 0
752     && length > 0
753     && fp->path[length - 1] == PATH_SEPARATOR_CHAR
754     ){
755     // PATH_SEPARATOR_CHAR on the end, reduce count by 1
756     --depth;
757     }
758    
759     return depth;
760     }
761    
762     struct FilePath *ospath_root(struct FilePath *fp){
763     #ifdef WINPATHS
764 johnpye 541 //M("WIN ROOT");
765 johnpye 534 char *temp;
766     struct FilePath *r;
767 johnpye 541
768 johnpye 534 if(strlen(fp->drive)){
769     temp = CALLOC(strlen(fp->drive)+1, sizeof(char));
770 johnpye 541 STRCPY(temp,fp->drive);
771     STRCAT(temp,PATH_SEPARATOR_STR);
772     X(temp);
773 johnpye 534 r = ospath_new(temp);
774     FREE(temp);
775     }else{
776 johnpye 541 r = ospath_new(fp->path);
777 johnpye 534 }
778     return r;
779     #else
780 johnpye 541 //M("JUST RETURNING PATH SEP");
781 johnpye 534 return ospath_new(PATH_SEPARATOR_STR);
782     #endif
783 johnpye 542 }
784    
785     struct FilePath *ospath_getdir(struct FilePath *fp){
786     char *pos;
787     char s[PATH_MAX];
788    
789     pos = strrchr(fp->path,PATH_SEPARATOR_CHAR);
790     if(pos==NULL){
791     return ospath_new(".");
792     }
793     #ifdef WINPATHS
794     strncpy(s,fp->drive,PATH_MAX);
795     strncat(s,fp->path,pos - fp->path);
796     #else
797     strncpy(s,fp->path,pos - fp->path);
798     #endif
799     return ospath_new(s);
800     }
801 johnpye 534
802 johnpye 541 int ospath_cmp(struct FilePath *fp1, struct FilePath *fp2){
803 johnpye 542 char temp[2][PATH_MAX];
804 johnpye 541 #ifdef WINPATHS
805     char *p;
806     #endif
807    
808 johnpye 534 if(!ospath_isvalid(fp1)){
809     if(!ospath_isvalid(fp2)){
810     return 0;
811     }else{
812     return -1;
813     }
814     }else if(!ospath_isvalid(fp2)){
815     return 1;
816     }
817    
818     // now, both are valid...
819 johnpye 535 //M("BOTH ARE VALID");
820 johnpye 534
821     #ifdef WINPATHS
822 johnpye 541 //X(fp1->drive);
823     STRCPY(temp[0],fp1->drive);
824     //X(temp[0]);
825     //X(fp1->path);
826     STRCAT(temp[0],fp1->path);
827     //X(temp[0]);
828     STRCPY(temp[1],fp2->drive);
829     STRCAT(temp[1],fp2->path);
830 johnpye 534 #else
831 johnpye 541 STRCPY(temp[0], fp1->path);
832     STRCPY(temp[1], fp2->path);
833 johnpye 534 #endif
834    
835 johnpye 541 #ifdef WINPATHS
836     for(p=temp[0];*p!='\0';++p){
837     *p=tolower(*p);
838     }
839     for(p=temp[1];*p!='\0';++p){
840     *p=tolower(*p);
841     }
842     X(temp[0]);
843     X(temp[1]);
844     #endif
845    
846 johnpye 534 // we will count two paths that different only in a trailing slash to be the *same*
847     // so we add trailing slashes to both now:
848     if(temp[0][strlen(temp[0]) - 1] != PATH_SEPARATOR_CHAR){
849 johnpye 541 STRCAT(temp[0],PATH_SEPARATOR_STR);
850 johnpye 534 }
851    
852     if(temp[1][strlen(temp[1]) - 1] != PATH_SEPARATOR_CHAR){
853 johnpye 541 STRCAT(temp[1],PATH_SEPARATOR_STR);
854 johnpye 534 }
855    
856 johnpye 541 //X(temp[0]);
857     //X(temp[1]);
858 johnpye 534
859     return strcmp(temp[0],temp[1]);
860     }
861    
862     struct FilePath *ospath_concat(struct FilePath *fp1, struct FilePath *fp2){
863    
864     struct FilePath *fp;
865 johnpye 542 char temp[2][PATH_MAX];
866     char temp2[PATH_MAX];
867 johnpye 541 struct FilePath *r;
868    
869 johnpye 534 fp = MALLOC(sizeof(struct FilePath));
870    
871 johnpye 541 D(fp1);
872     D(fp2);
873    
874 johnpye 534 if(!ospath_isvalid(fp1)){
875     if(ospath_isvalid(fp2)){
876 johnpye 541 ospath_copy(fp,fp2);
877 johnpye 534 }else{
878     // both invalid
879 johnpye 541 ospath_copy(fp,fp1);
880 johnpye 534 }
881     return fp;
882     }
883    
884     if(!ospath_isvalid(fp2)){
885 johnpye 541 ospath_copy(fp,fp1);
886 johnpye 534 return fp;
887     }
888    
889     // not just a copy of one or the other...
890 johnpye 541 ospath_free(fp);
891 johnpye 534
892     // now, both paths are valid...
893    
894     #ifdef WINPATHS
895 johnpye 542 STRNCPY(temp[0],fp1->drive,PATH_MAX);
896     STRNCAT(temp[0],fp1->path,PATH_MAX-strlen(temp[0]));
897 johnpye 534 #else
898 johnpye 542 STRNCPY(temp[0], fp1->path,PATH_MAX);
899 johnpye 534 #endif
900 johnpye 542
901     STRNCPY(temp[1], fp2->path,PATH_MAX);
902 johnpye 534
903     // make sure temp has a / on the end.
904     if(temp[0][strlen(temp[0]) - 1] != PATH_SEPARATOR_CHAR)
905     {
906 johnpye 542 STRNCAT(temp[0],PATH_SEPARATOR_STR,PATH_MAX-strlen(temp[0]));
907 johnpye 534 }
908    
909 johnpye 542 #ifdef DO_FIXSLASHES
910 johnpye 541 ospath_fixslash(temp[0]);
911     ospath_fixslash(temp[1]);
912     #endif
913    
914     //V(strlen(temp[0]));
915     //X(temp[0]);
916     //V(strlen(temp[1]));
917     //X(temp[1]);
918    
919 johnpye 534 // make sure rhs path has NOT got a / at the start.
920     if(temp[1][0] == PATH_SEPARATOR_CHAR){
921     return NULL;
922     }
923    
924     // create a new path object with the two path strings appended together.
925 johnpye 542 STRNCPY(temp2,temp[0],PATH_MAX);
926     STRNCAT(temp2,temp[1],PATH_MAX-strlen(temp2));
927 johnpye 541 //V(strlen(temp2));
928     //X(temp2);
929 johnpye 534 r = ospath_new_noclean(temp2);
930 johnpye 541 D(r);
931     /* ospath_cleanup(r);*/
932 johnpye 534 return r;
933     }
934    
935     void ospath_append(struct FilePath *fp, struct FilePath *fp1){
936     char *p;
937 johnpye 541 char *temp[2];
938     struct FilePath fp2;
939 johnpye 534
940 johnpye 541 ospath_copy(&fp2,fp1);
941 johnpye 542 #ifdef DO_FIXSLASHES
942 johnpye 541 ospath_fixslash(fp2.path);
943 johnpye 542 #endif
944 johnpye 541
945     if(!ospath_isvalid(&fp2)){
946 johnpye 534 M("fp1 invalid");
947     return;
948     }
949    
950 johnpye 541 if(!ospath_isvalid(fp) && ospath_isvalid(&fp2)){
951 johnpye 534 // set this object to be the same as the rhs
952     M("fp invalid");
953 johnpye 541 ospath_copy(fp,&fp2);
954 johnpye 542 #ifdef DO_FIXSLASHES
955     ospath_fixslash(fp->path);
956     #endif
957 johnpye 534 return;
958     }
959    
960 johnpye 541 //X(fp->path);
961     //X(fp2.path);
962 johnpye 534
963     // both paths are valid...
964     temp[0] = CALLOC(1+strlen(fp->path), sizeof(char));
965 johnpye 541 STRCPY(temp[0], fp->path);
966     temp[1] = CALLOC(strlen(fp2.path), sizeof(char));
967     STRCPY(temp[1], fp2.path);
968 johnpye 534
969 johnpye 541 //X(temp[0]);
970     //X(temp[1]);
971 johnpye 534
972     // make sure temp has a / on the end.
973     if(temp[0][strlen(temp[0]) - 1] != PATH_SEPARATOR_CHAR)
974     {
975 johnpye 541 STRCAT(temp[0],PATH_SEPARATOR_STR);
976 johnpye 534 }
977    
978     // make sure rhs path has NOT got a / at the start.
979     if(temp[1][0] == PATH_SEPARATOR_CHAR){
980     for(p=temp[1]+1; *p != '\0'; ++p){
981     *(p-1)=*p;
982     }
983     *(p-1)='\0';
984     }
985    
986 johnpye 541 //X(temp[0]);
987     //X(temp[1]);
988 johnpye 534
989     // create new path string.
990 johnpye 541 STRCPY(fp->path,temp[0]);
991     STRCAT(fp->path,temp[1]);
992 johnpye 534
993     FREE(temp[0]);
994     FREE(temp[1]);
995 johnpye 541
996     X(fp);
997     ospath_cleanup(fp);
998 johnpye 534 }
999    
1000     void ospath_copy(struct FilePath *dest, struct FilePath *src){
1001 johnpye 541 STRCPY(dest->path,src->path);
1002 johnpye 534 #ifdef WINPATHS
1003 johnpye 541 STRCPY(dest->drive,src->drive);
1004 johnpye 534 #endif
1005     }
1006    
1007 johnpye 541 void ospath_debug(struct FilePath *fp){
1008 johnpye 534 #ifdef WINPATHS
1009 johnpye 541 fprintf(stderr,"{\"%s\",\"%s\"}\n",fp->drive,fp->path);
1010     #else
1011     fprintf(stderr,"{\"%s\"}\n",fp->path);
1012 johnpye 534 #endif
1013 johnpye 542 }
1014    
1015     FILE *ospath_fopen(struct FilePath *fp, const char *mode){
1016     char s[PATH_MAX];
1017     if(!ospath_isvalid(fp)){
1018     E("Invalid path");
1019     return NULL;
1020     }
1021     ospath_strcpy(fp,s,PATH_MAX);
1022     FILE *f = fopen(s,mode);
1023     return f;
1024     }
1025 johnpye 534
1026 johnpye 541 //------------------------
1027     // SEARCH PATH FUNCTIONS
1028    
1029 johnpye 542 struct FilePath **ospath_searchpath_new(const char *path){
1030 johnpye 541 char *p;
1031     char *list[LISTMAX];
1032     unsigned n=0;
1033     char *c;
1034     unsigned i;
1035     struct FilePath **pp;
1036 johnpye 542 STRTOKVAR(nexttok);
1037    
1038     char path1[PATH_MAX];
1039     strncpy(path1,path,PATH_MAX);
1040    
1041     X(path1);
1042     X(PATH_LISTSEP_STR);
1043    
1044     V(strlen(path1));
1045     V(strlen(PATH_LISTSEP_STR));
1046    
1047     /*
1048     c = strstr(path,PATH_LISTSEP_CHAR);
1049     if(c==NULL){
1050     E("NO TOKEN FOUND");
1051     }
1052     */
1053    
1054     p=STRTOK(path1,PATH_LISTSEP_STR,nexttok);
1055     X(p);
1056     for(; p!= NULL; p=STRTOK(NULL,PATH_LISTSEP_STR,nexttok)){
1057 johnpye 541 c = CALLOC(strlen(p),sizeof(char));
1058     X(p);
1059     STRCPY(c,p);
1060     if(n>=LISTMAX){
1061     E("IGNORING SOME PATH COMPONENTS");
1062     break;
1063     }
1064     list[n++]=c;
1065     }
1066    
1067     /*
1068     for(i=0;i<n;++i){
1069     X(list[i]);
1070     }
1071     V(n);
1072     */
1073    
1074     pp = CALLOC(n+1,sizeof(struct FilePath*));
1075     for(i=0; i<n; ++i){
1076     //V(i);
1077     //X(list[i]);
1078     pp[i] = ospath_new_noclean(list[i]);
1079     //D(pp[i]);
1080     }
1081     pp[n] = NULL;
1082    
1083 johnpye 542 for(i=0;i<n;++i){
1084     #ifdef DO_FIXSLASHES
1085     ospath_fixslash(pp[i]->path);
1086     #endif
1087 johnpye 541 D(pp[i]);
1088     }
1089    
1090     return pp;
1091 johnpye 542 }
1092    
1093     void ospath_searchpath_free(struct FilePath **searchpath){
1094     struct FilePath **p;
1095     for(p=searchpath; *p!=NULL; ++p){
1096     ospath_free(*p);
1097     }
1098     FREE(searchpath);
1099 johnpye 541 }
1100    
1101     struct FilePath *ospath_searchpath_iterate(
1102     struct FilePath **searchpath
1103     , FilePathTestFn *testfn
1104     , void *searchdata
1105     ){
1106     struct FilePath **p;
1107    
1108 johnpye 542 p = searchpath;
1109    
1110     M("SEARCHING IN...");
1111     for(p=searchpath; *p!=NULL; ++p){
1112     D(*p);
1113     }
1114 johnpye 543
1115 johnpye 542 for(p=searchpath; *p!=NULL; ++p){
1116     D(*p);
1117 johnpye 541 if((*testfn)(*p,searchdata)){
1118     return *p;
1119     }
1120     }
1121     return NULL;
1122     }
1123    
1124    
1125 johnpye 534 /*--------------------------------
1126     some simple test routines...
1127     */
1128     #ifdef TEST
1129 johnpye 541
1130     FilePathTestFn ospath_searchpath_testexists;
1131    
1132     /**
1133     Return 1 if the file exists relative inside path
1134     */
1135     int ospath_searchpath_testexists(struct FilePath *path,void *file){
1136 johnpye 542 struct FilePath *fp, *fp1, *fp2;
1137 johnpye 541 fp = (struct FilePath *)file;
1138     D(fp);
1139     fp1 = ospath_concat(path,fp);
1140 johnpye 542 D(fp1);
1141    
1142     fp2 = ospath_new("\\GTK\\bin\\johnpye\\extfn");
1143     if(ospath_cmp(fp1,fp2)==0){
1144     return 1;
1145     }
1146 johnpye 541 return 0;
1147     }
1148    
1149 johnpye 534 #include <assert.h>
1150    
1151     int main(void){
1152 johnpye 542 struct FilePath *fp1, *fp2, *fp3, *fp4;
1153     char *s1, *s2;
1154 johnpye 541 struct FilePath **pp, **p1;// will be returned null-terminated
1155 johnpye 542 #ifdef WINPATHS
1156     char pathtext[]="c:\\Program Files\\GnuWin32\\bin;c:\\GTK\\bin;e:\\ascend\\;..\\..\\pygtk";
1157     char pathtext2[]="c:\\Program Files\\ASCEND\\models";
1158     #else
1159     char pathtext[]="\\Program Files\\GnuWin32\\bin:\\GTK\\bin:\\ascend\\:..\\..\\pygtk";
1160     char pathtext2[]="/usr/local/ascend/models";
1161     #endif
1162 johnpye 534
1163 johnpye 541 //------------------------
1164    
1165     fp1 = ospath_new_from_posix("/usr/local/hello/");
1166     fp2 = ospath_getparent(fp1);
1167     fp3 = ospath_new_from_posix("/usr/local");
1168 johnpye 542
1169     D(fp1);
1170     D(fp2);
1171     D(fp3);
1172 johnpye 541 assert(ospath_cmp(fp2,fp3)==0);
1173     M("Passed 'getparent' test\n");
1174    
1175     ospath_free(fp1); ospath_free(fp2); ospath_free(fp3);
1176    
1177     //------------------------
1178    
1179 johnpye 535 fp1 = ospath_new_from_posix("models/johnpye/extfn/extfntest");
1180     D(fp1);
1181     fp2 = ospath_new("models\\johnpye\\extfn\\extfntest");
1182     D(fp2);
1183 johnpye 541 D(fp1);
1184 johnpye 535 assert(ospath_cmp(fp1,fp2)==0);
1185 johnpye 541 M("Passed 'new_from_posix' test\n");
1186 johnpye 535
1187 johnpye 541 ospath_free(fp1);
1188     ospath_free(fp2);
1189 johnpye 535
1190     //------------------------
1191 johnpye 541 fp1 = ospath_new(".\\src/.\\images\\..\\\\movies\\");
1192 johnpye 534 fp2 = ospath_new(".\\src\\movies");
1193    
1194     D(fp1);
1195     D(fp2);
1196    
1197     assert(ospath_cmp(fp1,fp2)==0);
1198 johnpye 541 M("Passed mid-path '..' cleanup test\n");
1199 johnpye 534
1200 johnpye 541 ospath_free(fp2);
1201 johnpye 534
1202 johnpye 541 fp2 = ospath_new("./src/movies\\kubrick");
1203 johnpye 534 fp3 = ospath_getparent(fp2);
1204    
1205 johnpye 541 D(fp2);
1206     D(fp3);
1207    
1208 johnpye 534 assert(ospath_cmp(fp1,fp3)==0);
1209 johnpye 541 M("Passed 'second cleanup' test\n");
1210 johnpye 534
1211 johnpye 535 //------------------------
1212 johnpye 534
1213     fp2 = ospath_new("\\home\\john");
1214     fp3 = ospath_new("where\\mojo");
1215    
1216     D(fp2);
1217     D(fp3);
1218    
1219     ospath_append(fp2,fp3);
1220    
1221 johnpye 541 D(fp2);
1222    
1223 johnpye 535 fp4 = ospath_new("\\home\\john\\where\\mojo\\");
1224 johnpye 534
1225     D(fp2);
1226 johnpye 535 assert(ospath_cmp(fp2,fp4)==0);
1227 johnpye 541 M("Passed 'append' test\n");
1228 johnpye 534
1229 johnpye 541 ospath_free(fp3);
1230     ospath_free(fp2);
1231    
1232     //---------------------------
1233    
1234     fp3 = ospath_new_noclean("../..");
1235     D(fp3);
1236    
1237     // test with appending ../.. to an existing path
1238     fp2 = ospath_new("\\home\\john");
1239     M("ORIGINAL PATH");
1240     D(fp2);
1241 johnpye 534 ospath_append(fp2,fp3);
1242 johnpye 541 M("AFTER APPENDING ../..");
1243     D(fp2);
1244    
1245     M("GETTING ROOT");
1246 johnpye 534 fp4 = ospath_root(fp2);
1247 johnpye 541 M("ROOT FOUND:");
1248 johnpye 534 D(fp4);
1249    
1250     assert(ospath_cmp(fp2,fp4)==0);
1251 johnpye 541 M("Passed 'append ../..' test\n");
1252 johnpye 535
1253 johnpye 541 ospath_free(fp2);
1254     ospath_free(fp3);
1255     ospath_free(fp4);
1256 johnpye 534
1257 johnpye 541 //-------------------------
1258 johnpye 534
1259 johnpye 541 fp1 = ospath_new("~\\somewhere\\..");
1260 johnpye 534 fp2 = ospath_new("~/.");
1261    
1262     assert(ospath_cmp(fp1,fp2)==0);
1263    
1264     D(fp2);
1265    
1266 johnpye 541 ospath_free(fp1);
1267     ospath_free(fp2);
1268 johnpye 534
1269     fp1 = ospath_new("/usr/local/include");
1270     fp2 = ospath_new("/usr/include/../local/include");
1271    
1272     D(fp1);
1273     D(fp2);
1274    
1275 johnpye 541 assert(ospath_cmp(fp1,fp2)==0);
1276     M("Passed another mid-path '..' test\n");
1277 johnpye 535
1278 johnpye 541 ospath_free(fp1);
1279     ospath_free(fp2);
1280    
1281     //---------------------------
1282    
1283     fp1 = ospath_new("/home");
1284     fp2 = ospath_new("john");
1285     fp3 = ospath_concat(fp1, fp2);
1286    
1287     fp4 = ospath_new("/home/john");
1288    
1289     assert(ospath_cmp(fp3,fp4)==0);
1290     M("Passed 'ospath_concat' test\n");
1291    
1292     ospath_free(fp1); ospath_free(fp2); ospath_free(fp3); ospath_free(fp4);
1293    
1294     //---------------------------
1295    
1296 johnpye 542 fp1 = ospath_new("c:/Program Files");
1297 johnpye 541 fp2 = ospath_new("GnuWin32\\bin");
1298     fp3 = ospath_concat(fp1, fp2);
1299    
1300     fp4 = ospath_new("c:/Program Files/GnuWin32/bin");
1301    
1302     assert(ospath_cmp(fp3,fp4)==0);
1303     M("Passed 'ospath_concat' test\n");
1304    
1305     ospath_free(fp1); ospath_free(fp2); ospath_free(fp3); ospath_free(fp4);
1306    
1307     //---------------------------
1308    
1309 johnpye 542 fp1 = ospath_new("c:/Program Files/");
1310 johnpye 541 fp2 = ospath_new("GnuWin32\\bin");
1311     fp3 = ospath_concat(fp1, fp2);
1312    
1313     fp4 = ospath_new("c:/Program Files/GnuWin32/bin");
1314    
1315     assert(ospath_cmp(fp3,fp4)==0);
1316     M("Passed trailing-slash 'ospath_concat' test\n");
1317    
1318     ospath_free(fp1); ospath_free(fp2); ospath_free(fp3); ospath_free(fp4);
1319    
1320     //---------------------------
1321    
1322 johnpye 542 fp1 = ospath_new("c:/Program Files/GnuWin32/bin");
1323 johnpye 541 fp2 = ospath_new("johnpye/extfn");
1324     fp3 = ospath_concat(fp1, fp2);
1325    
1326     fp4 = ospath_new("c:/Program Files/GnuWin32/bin/johnpye/extfn");
1327    
1328     assert(ospath_cmp(fp3,fp4)==0);
1329     M("Passed trailing-slash 'ospath_concat' test\n");
1330    
1331     ospath_free(fp1); ospath_free(fp2); ospath_free(fp3); ospath_free(fp4);
1332    
1333     //---------------------------
1334    
1335     pp = ospath_searchpath_new(pathtext);
1336    
1337     for(p1=pp; *p1!=NULL; ++p1){
1338     D(*p1);
1339     }
1340    
1341 johnpye 542 #ifdef WINPATHS
1342     fp1 = ospath_new("c:\\program files\\GnuWin32\\bin");
1343     #else
1344     fp1 = ospath_new("\\Program Files\\GnuWin32\\bin");
1345     #endif
1346    
1347 johnpye 541 D(fp1);
1348     D(pp[0]);
1349    
1350 johnpye 542 assert(ospath_cmp(pp[0],fp1)==0);
1351 johnpye 541
1352     fp2 = ospath_new_noclean("johnpye/extfn");
1353    
1354 johnpye 542 fp3 = ospath_searchpath_iterate(pp,&ospath_searchpath_testexists,(void*)fp2);
1355    
1356     assert(ospath_cmp(fp3,pp[1])==0);
1357     M("Passed path-search test\n");
1358    
1359 johnpye 543 ospath_free(fp1);
1360 johnpye 542 ospath_free(fp2);
1361     ospath_searchpath_free(pp);
1362    
1363     //-------------------------------
1364    
1365     pp = ospath_searchpath_new(pathtext2);
1366    
1367     for (p1=pp; *p1!=NULL; ++p1){
1368     D(*p1);
1369     }
1370    
1371     fp2 = ospath_new_noclean("johnpye/extfn/extfntest");
1372     fp3 = ospath_searchpath_iterate(pp,&ospath_searchpath_testexists,(void*)fp2);
1373    
1374     D(fp2);
1375     D(fp3);
1376    
1377     assert(fp3==NULL);
1378     M("Passed path-search test 2\n");
1379    
1380     ospath_free(fp2);
1381     ospath_free(fp3);
1382     ospath_searchpath_free(pp);
1383 johnpye 543
1384 johnpye 542 //-------------------------------
1385    
1386     fp1 = ospath_new("/usr/share/data/ascend/models/johnpye/extfn/extfntest.a4c");
1387     D(fp1);
1388     s1 = ospath_getbasefilename(fp1);
1389     X(s1);
1390     assert(strcmp(s1,"extfntest.a4c")==0);
1391     M("Passed getbasefilename test\n");
1392    
1393     ospath_free(fp1);
1394     FREE(s1);
1395    
1396     //-------------------------------
1397    
1398     fp1 = ospath_new("extfntest.a4c");
1399     D(fp1);
1400     s1 = ospath_getbasefilename(fp1);
1401     X(s1);
1402     assert(strcmp(s1,"extfntest.a4c")==0);
1403     M("Passed getbasefilename test 2\n");
1404    
1405     ospath_free(fp1);
1406     FREE(s1);
1407    
1408    
1409     //-------------------------------
1410    
1411     fp1 = ospath_new("/here/is/my/path.dir/");
1412     D(fp1);
1413     s1 = ospath_getbasefilename(fp1);
1414     X(s1);
1415     assert(NULL==s1);
1416     M("Passed getbasefilename test 3\n");
1417    
1418     ospath_free(fp1);
1419     FREE(s1);
1420    
1421     //-------------------------------
1422    
1423     #ifdef WINPATHS
1424     fp1 = ospath_new("c:extfntest.a4c");
1425     D(fp1);
1426     s1 = ospath_getbasefilename(fp1);
1427     X(s1);
1428     assert(strcmp(s1,"extfntest.a4c")==0);
1429     M("Passed getbasefilename test WINPATHS\n");
1430    
1431     ospath_free(fp1);
1432     FREE(s1);
1433     #endif
1434    
1435     //-------------------------------
1436    
1437     fp1 = ospath_new("/usr/share/data/ascend/models/johnpye/extfn/extfntest.a4c");
1438     D(fp1);
1439     s1 = ospath_getfilestem(fp1);
1440     X(s1);
1441     assert(strcmp(s1,"extfntest")==0);
1442     M("Passed getfilestem test\n");
1443    
1444     ospath_free(fp1);
1445     FREE(s1);
1446    
1447     //-------------------------------
1448    
1449     fp1 = ospath_new("/usr/share/data/ascend/models/johnpye/extfn/extfntest");
1450     D(fp1);
1451     s1 = ospath_getfilestem(fp1);
1452     X(s1);
1453     assert(strcmp(s1,"extfntest")==0);
1454     M("Passed getfilestem test 2\n");
1455    
1456     ospath_free(fp1);
1457     FREE(s1);
1458    
1459     //-------------------------------
1460    
1461     fp1 = ospath_new("/usr/share/data/ascend/.ascend.ini");
1462     D(fp1);
1463     s1 = ospath_getfilestem(fp1);
1464     X(s1);
1465     assert(strcmp(s1,".ascend")==0);
1466     M("Passed getfilestem test 3\n");
1467    
1468     ospath_free(fp1);
1469     FREE(s1);
1470    
1471     //-------------------------------
1472    
1473     fp1 = ospath_new("~/.vimrc");
1474     D(fp1);
1475     s1 = ospath_getfilestem(fp1);
1476     X(s1);
1477     assert(strcmp(s1,".vimrc")==0);
1478     M("Passed getfilestem test 3\n");
1479    
1480     ospath_free(fp1);
1481     FREE(s1);
1482    
1483     //-------------------------------
1484    
1485     fp1 = ospath_new("~/src/ascend-0.9.5-1.jdpipe.src.rpm");
1486     D(fp1);
1487     s1 = ospath_getfilestem(fp1);
1488     X(s1);
1489     assert(strcmp(s1,"ascend-0.9.5-1.jdpipe.src")==0);
1490     M("Passed getfilestem test 4\n");
1491    
1492     ospath_free(fp1);
1493     FREE(s1);
1494    
1495     //-------------------------------
1496    
1497     fp1 = ospath_new("~/dir1/dir2/");
1498     D(fp1);
1499     s1 = ospath_getfilestem(fp1);
1500     X(s1);
1501     assert(NULL==s1);
1502     M("Passed getfilestem test 5\n");
1503    
1504     ospath_free(fp1);
1505     FREE(s1);
1506    
1507     //-------------------------------
1508    
1509     fp1 = ospath_new("~/src/ascend-0.9.5-1.jdpipe.src.rpm");
1510     D(fp1);
1511     s1 = ospath_getfileext(fp1);
1512     X(s1);
1513     assert(strcmp(s1,".rpm")==0);
1514     M("Passed getbasefileext test\n");
1515    
1516     ospath_free(fp1);
1517     FREE(s1);
1518    
1519     //-------------------------------
1520    
1521     fp1 = ospath_new("~/.vimrc");
1522     D(fp1);
1523     s1 = ospath_getfileext(fp1);
1524     X(s1);
1525     assert(s1==NULL);
1526     M("Passed getbasefileext test 2\n");
1527    
1528     ospath_free(fp1);
1529     FREE(s1);
1530    
1531     //-------------------------------
1532    
1533     fp1 = ospath_new("./ascend4");
1534     D(fp1);
1535     s1 = ospath_getfileext(fp1);
1536     X(s1);
1537     assert(s1==NULL);
1538     M("Passed getbasefileext test 3\n");
1539    
1540     ospath_free(fp1);
1541     FREE(s1);
1542    
1543     //-------------------------------
1544    
1545     fp1 = ospath_new("/home/myfile");
1546     fp2 = ospath_getdir(fp1);
1547     fp3 = ospath_new("/home");
1548     assert(ospath_cmp(fp2,fp3)==0);
1549     M("Passed ospath_getdir test\n");
1550    
1551     ospath_free(fp1);
1552     ospath_free(fp2);
1553     ospath_free(fp3);
1554    
1555     //-------------------------------
1556    
1557     fp1 = ospath_new("/home/myfile.ext");
1558     fp2 = ospath_getdir(fp1);
1559     fp3 = ospath_new("/home");
1560     assert(ospath_cmp(fp2,fp3)==0);
1561     M("Passed ospath_getdir test 2\n");
1562    
1563     ospath_free(fp1);
1564     ospath_free(fp2);
1565     ospath_free(fp3);
1566    
1567     //-------------------------------
1568    
1569     fp1 = ospath_new("/home/mydir/");
1570     fp2 = ospath_getdir(fp1);
1571     fp3 = ospath_new("/home/mydir");
1572     assert(ospath_cmp(fp2,fp3)==0);
1573     M("Passed ospath_getdir test 3\n");
1574    
1575     ospath_free(fp1);
1576     ospath_free(fp2);
1577     ospath_free(fp3);
1578    
1579 johnpye 543 //---------------------------------
1580 johnpye 541 M("ALL TESTS PASSED");
1581 johnpye 534 }
1582    
1583     #endif

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