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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 543 - (show annotations) (download) (as text)
Thu Apr 27 00:04:13 2006 UTC (13 years, 10 months ago) by johnpye
File MIME type: text/x-csrc
File size: 33497 byte(s)
Fix windows behaviour for 'IMPORT "johnpye/extfn/extfntest";'
1 #include <string.h>
2 #include <malloc.h>
3 #include <stdio.h>
4 #include <ctype.h>
5
6 #include "ospath.h"
7
8 // 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
16 #define VERBOSE
17
18 #if !defined(TEST) && !defined(VERBOSE)
19 # define NDEBUG
20 #endif
21
22 //#define TRY_GETPWUID
23
24 #define DO_FIXSLASHES
25
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 // PATH_MAX is in ospath.h
63 #define DRIVEMAX 3
64 #define LISTMAX 256
65
66 #ifdef __WIN32__ /* && !defined(__MINGW32__) */
67 # define WINPATHS
68 #endif
69
70 struct FilePath{
71 char path[PATH_MAX]; /// the string version of the represented POSIX path
72
73 #ifdef WINPATHS
74 char drive[DRIVEMAX]; /// the drive the path resides on (field is absent in POSIX systems)
75 #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
86 #ifdef DO_FIXSLASHES
87 void ospath_fixslash(char *path);
88 #endif
89
90 struct FilePath *ospath_getcwd();
91
92 /**
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 2. Resolve a leading tilde (~) to the current user's HOME path
99
100 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 */
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 # define PATH_LISTSEP_CHAR ';'
127 # define PATH_LISTSEP_STR ";"
128 # define PATH_WRONGSLASH_CHAR '/'
129 # define PATH_WRONGSLASH_STR "/"
130 #else
131 # define PATH_SEPARATOR_STR "/"
132 # define PATH_SEPARATOR_CHAR '/'
133 # define PATH_LISTSEP_CHAR ':'
134 # define PATH_LISTSEP_STR ":"
135 # define PATH_WRONGSLASH_CHAR '\\'
136 # define PATH_WRONGSLASH_STR "\\"
137 #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 STRNCPY(fp->path, path, PATH_MAX);
146 //X(fp->path);
147 //X(path);
148 assert(strcmp(fp->path,path)==0);
149 #ifdef WINPATHS
150 //X(fp->drive);
151 ospath_extractdriveletter(fp);
152 #endif
153
154 //X(fp->drive);
155
156 #ifdef DO_FIXSLASHES
157 ospath_fixslash(fp->path);
158 #endif
159
160 ospath_cleanup(fp);
161
162 //D(fp);
163
164 return fp;
165 }
166
167 void ospath_free(struct FilePath *fp){
168 FREE(fp);
169 }
170
171 /**
172 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 struct FilePath *ospath_new_from_posix(char *posixpath){
190 struct FilePath *fp = MALLOC(sizeof(struct FilePath));
191 STRNCPY(fp->path,posixpath,PATH_MAX);
192 #ifdef WINPATHS
193 X(fp->path);
194 ospath_extractdriveletter(fp);
195 #endif
196
197 #ifdef DO_FIXSLASHES
198 ospath_fixslash(fp->path);
199 #endif
200
201 //X(fp->path);
202
203 ospath_cleanup(fp);
204
205 return fp;
206 }
207
208 #ifdef DO_FIXSLASHES
209 void ospath_fixslash(char *path){
210
211 char *p;
212 char temp[PATH_MAX];
213 int startslash;
214 int endslash;
215 STRTOKVAR(nexttok);
216
217 STRNCPY(temp,path,PATH_MAX);
218
219 //X(path);
220
221 startslash = (strlen(temp) > 0 && temp[0] == PATH_WRONGSLASH_CHAR);
222 endslash = (strlen(temp) > 1 && temp[strlen(temp) - 1] == PATH_WRONGSLASH_CHAR);
223
224 //V(startslash);
225 //V(endslash);
226
227 // reset fp->path as required.
228 STRNCPY(path, (startslash ? PATH_SEPARATOR_STR : ""), PATH_MAX);
229
230 //M("STARTING STRTOK");
231 for(p = STRTOK(temp, PATH_WRONGSLASH_STR,nexttok);
232 p!=NULL;
233 p = STRTOK(NULL,PATH_WRONGSLASH_STR,nexttok)
234 ){
235 // add a separator if we've already got some stuff
236 if(
237 strlen(path) > 0
238 && path[strlen(path) - 1] != PATH_SEPARATOR_CHAR
239 ){
240 STRCAT(path,PATH_SEPARATOR_STR);
241 }
242
243 STRCAT(path,p);
244 }
245 //M("FINISHED STRTOK");
246
247 // put / on end as required, according to what the starting path had
248 if(endslash && (strlen(path) > 0 ? (path[strlen(path) - 1] != PATH_SEPARATOR_CHAR) : 1))
249 {
250 //M("adding endslash!");
251
252 STRCAT(path, PATH_SEPARATOR_STR);
253 }
254
255 //X(path);
256 }
257 #endif
258
259
260 /// Create but with no 'cleanup' call
261 struct FilePath *ospath_new_noclean(const char *path){
262 struct FilePath *fp = MALLOC(sizeof(struct FilePath));
263 STRNCPY(fp->path,path,PATH_MAX);
264
265 #ifdef WINPATHS
266 //X(fp->path);
267 ospath_extractdriveletter(fp);
268 #endif
269
270 //D(fp);
271
272 /*
273 #ifdef DO_FIXSLASHES
274 ospath_fixslash(fp->path);
275 D(fp);
276 #endif
277 */
278 return fp;
279 }
280
281 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 /**
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 const char *pfx = (const char *)getenv("HOME");
303 struct FilePath *fp;
304
305 #ifndef __WIN32__
306 # ifdef TRY_GETPWUID
307 struct passwd *pw;
308
309 if(pfx==NULL){
310 pw = (struct passwd*)getpwuid(getuid());
311
312 if(pw){
313 pfx = pw->pw_dir;
314 }
315 }
316 # endif
317 #endif
318
319 // 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 #ifdef DO_FIXSLASHES
324 ospath_fixslash(fp->path);
325 #endif
326
327 return fp;
328 }
329
330 #ifdef WINPATHS
331 void ospath_extractdriveletter(struct FilePath *fp)
332 {
333 char *p;
334 //M("SOURCE");
335 //X(fp->path);
336 //fprintf(stderr,"CHAR 1 = %c\n",fp->path[1]);
337
338 // extract the drive the path resides on...
339 if(strlen(fp->path) >= 2 && fp->path[1] == ':')
340 {
341 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 }
346 *(p-2)='\0';
347 }else{
348 STRNCPY(fp->drive,"",DRIVEMAX);
349 }
350 //M("RESULT");
351 //X(fp->path);
352 //X(fp->drive);
353 }
354 #endif
355
356 void ospath_cleanup(struct FilePath *fp){
357 char path[PATH_MAX];
358 char *p;
359 struct FilePath *home;
360 struct FilePath *working;
361 struct FilePath *parent;
362 STRTOKVAR(nexttok);
363
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 //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
372 home = ospath_gethomepath();
373
374 // create a copy of fp->path.
375 STRCPY(path, fp->path);
376
377 // reset fp->path as required.
378 STRCPY(fp->path, (startslash ? PATH_SEPARATOR_STR : ""));
379
380 X(path);
381
382 // split path into it tokens, using STRTOK which is NOT reentrant
383 // so be careful!
384
385 //M("STARTING STRTOK");
386 for(p = STRTOK(path, PATH_SEPARATOR_STR,nexttok);
387 p!=NULL;
388 p = STRTOK(NULL,PATH_SEPARATOR_STR,nexttok)
389 ){
390 //M("NEXT TOKEN");
391 //X(p);
392 //X(path+strlen(p)+1);
393 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 X(path);
410
411 working = ospath_getcwd();
412
413 D(working);
414 #ifdef WINPATHS
415 X(working->drive);
416 #endif
417 X(p);
418 X(path);
419
420 ospath_copy(fp,working);
421
422
423 D(fp);
424 X(p);
425 //X(path+strlen(p)+1);
426
427 //ospath_free(working);
428 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 //ospath_free(parent);
441 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 STRCAT(fp->path,PATH_SEPARATOR_STR);
450 }
451
452 // add the present path component
453 STRCAT(fp->path, p);
454 }
455 //M("FINISHED STRTOK");
456
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 STRCAT(fp->path, PATH_SEPARATOR_STR);
461 }
462 }
463
464
465 int ospath_isvalid(struct FilePath *fp){
466 //if(fp==NULL) return 0;
467 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 STRCPY(s,fp->drive);
476 STRCAT(s,fp->path);
477 #else
478 s = CALLOC(strlen(fp->path),sizeof(char));
479 STRCPY(s,fp->path);
480 #endif
481 return s;
482 }
483
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
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 int length;
514 int offset;
515 char *pos;
516 int len1;
517 char sub[PATH_MAX];
518 struct FilePath *fp1;
519
520 D(fp);
521
522 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 /// 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
536 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 #ifdef WINPATHS
545 STRCPY(sub,fp->drive);
546 STRNCAT(sub,fp->path,len1);
547 #else
548 STRNCPY(sub,fp->path,len1);
549 sub[len1]='\0';
550 #endif
551 X(sub);
552 if(strcmp(sub,"")==0){
553 M("DIRECTORY IS EMPTY");
554 STRCAT(sub,PATH_SEPARATOR_STR);
555 }
556 }else{
557 E("NO PARENT DIR");
558 return ospath_new_noclean(fp->path);
559 }
560
561 fp1 = ospath_new_noclean(sub);
562 D(fp1);
563 return fp1;
564 }
565
566 struct FilePath *ospath_getparentatdepthn(struct FilePath *fp, unsigned depth)
567 {
568 int startslash;
569 char path[PATH_MAX];
570 char *temp;
571 char *p;
572 STRTOKVAR(nexttok);
573 #ifdef WINPATHS
574 char temp2[PATH_MAX];
575 #endif
576
577 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 startslash = (strlen(fp->path) > 0 && fp->path[0] == PATH_SEPARATOR_CHAR);
587
588 // create a copy of fp->path.
589 STRCPY(path, fp->path);
590
591 // reset fp->path as required.
592 temp = startslash ? PATH_SEPARATOR_STR : "";
593
594 // split path into it tokens.
595 //M("STARTING STRTOK");
596 p = STRTOK(path, PATH_SEPARATOR_STR, nexttok);
597
598 while(p && depth > 0)
599 {
600 if(strlen(temp) > 0 && temp[strlen(temp) - 1] != PATH_SEPARATOR_CHAR)
601 {
602 strcat(temp,PATH_SEPARATOR_STR);
603 }
604
605 STRCAT(temp,p);
606 --depth;
607
608 p = STRTOK(NULL, PATH_SEPARATOR_STR, nexttok);
609 }
610 //M("FINISHED STRTOK");
611
612 // put / on end as required
613 if(strlen(temp) > 0 ? (temp[strlen(temp) - 1] != PATH_SEPARATOR_CHAR) : 1)
614 {
615 strcat(temp,PATH_SEPARATOR_STR);
616 }
617
618 #ifdef WINPATHS
619 STRCPY(temp2,fp->drive);
620 STRCAT(temp2,temp);
621 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 unsigned length, offset;
630 char *pos;
631
632 if(strlen(fp->path) == 0){
633 // return empty name.
634 return "";
635 }
636
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 length = strlen(fp->path);
644 offset = length;
645
646 pos = strrchr(fp->path, PATH_SEPARATOR_CHAR); /* OFFSET! */
647
648 // extract filename given position of find / and return it.
649 if(pos != NULL){
650 unsigned length1 = length - ((pos - fp->path) + 1);
651 temp = CALLOC(length1,sizeof(char));
652
653 V(length1);
654 STRNCPY(temp, pos + 1, length1);
655 return temp;
656 }else{
657 temp = CALLOC(length,sizeof(char));
658 STRNCPY(temp, fp->path, length);
659 return temp;
660 }
661 }
662
663 char *ospath_getfilestem(struct FilePath *fp){
664 char *temp;
665 char *pos;
666
667 if(!ospath_isvalid(fp)){
668 return NULL;
669 }
670
671 temp = ospath_getbasefilename(fp);
672 if(temp==NULL){
673 // it's a directory
674 return NULL;
675 }
676
677 pos = strrchr(temp,'.');
678
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 return temp;
689 }
690
691 char *ospath_getfileext(struct FilePath *fp){
692 char *temp, *temp2, *pos;
693 int len1;
694
695 if(!ospath_isvalid(fp)){
696 return NULL;
697 }
698
699 temp = ospath_getbasefilename(fp);
700 if(temp==NULL){
701 // it's a directory
702 return NULL;
703 }
704
705 // make sure there is no / on the end.
706 /// FIXME: is this good policy, removing a trailing slash?
707 if(temp[strlen(temp) - 1] == PATH_SEPARATOR_CHAR){
708 temp[strlen(temp)-1] = '\0';
709 }
710
711 pos = strrchr(temp,'.');
712
713 if(pos != NULL && pos!=temp){
714 // extract extension.
715 len1 = temp + strlen(temp) - pos;
716 temp2 = CALLOC(len1, sizeof(char));
717 STRNCPY(temp2, pos, len1);
718 }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 //M("WIN ROOT");
765 char *temp;
766 struct FilePath *r;
767
768 if(strlen(fp->drive)){
769 temp = CALLOC(strlen(fp->drive)+1, sizeof(char));
770 STRCPY(temp,fp->drive);
771 STRCAT(temp,PATH_SEPARATOR_STR);
772 X(temp);
773 r = ospath_new(temp);
774 FREE(temp);
775 }else{
776 r = ospath_new(fp->path);
777 }
778 return r;
779 #else
780 //M("JUST RETURNING PATH SEP");
781 return ospath_new(PATH_SEPARATOR_STR);
782 #endif
783 }
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
802 int ospath_cmp(struct FilePath *fp1, struct FilePath *fp2){
803 char temp[2][PATH_MAX];
804 #ifdef WINPATHS
805 char *p;
806 #endif
807
808 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 //M("BOTH ARE VALID");
820
821 #ifdef WINPATHS
822 //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 #else
831 STRCPY(temp[0], fp1->path);
832 STRCPY(temp[1], fp2->path);
833 #endif
834
835 #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 // 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 STRCAT(temp[0],PATH_SEPARATOR_STR);
850 }
851
852 if(temp[1][strlen(temp[1]) - 1] != PATH_SEPARATOR_CHAR){
853 STRCAT(temp[1],PATH_SEPARATOR_STR);
854 }
855
856 //X(temp[0]);
857 //X(temp[1]);
858
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 char temp[2][PATH_MAX];
866 char temp2[PATH_MAX];
867 struct FilePath *r;
868
869 fp = MALLOC(sizeof(struct FilePath));
870
871 D(fp1);
872 D(fp2);
873
874 if(!ospath_isvalid(fp1)){
875 if(ospath_isvalid(fp2)){
876 ospath_copy(fp,fp2);
877 }else{
878 // both invalid
879 ospath_copy(fp,fp1);
880 }
881 return fp;
882 }
883
884 if(!ospath_isvalid(fp2)){
885 ospath_copy(fp,fp1);
886 return fp;
887 }
888
889 // not just a copy of one or the other...
890 ospath_free(fp);
891
892 // now, both paths are valid...
893
894 #ifdef WINPATHS
895 STRNCPY(temp[0],fp1->drive,PATH_MAX);
896 STRNCAT(temp[0],fp1->path,PATH_MAX-strlen(temp[0]));
897 #else
898 STRNCPY(temp[0], fp1->path,PATH_MAX);
899 #endif
900
901 STRNCPY(temp[1], fp2->path,PATH_MAX);
902
903 // make sure temp has a / on the end.
904 if(temp[0][strlen(temp[0]) - 1] != PATH_SEPARATOR_CHAR)
905 {
906 STRNCAT(temp[0],PATH_SEPARATOR_STR,PATH_MAX-strlen(temp[0]));
907 }
908
909 #ifdef DO_FIXSLASHES
910 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 // 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 STRNCPY(temp2,temp[0],PATH_MAX);
926 STRNCAT(temp2,temp[1],PATH_MAX-strlen(temp2));
927 //V(strlen(temp2));
928 //X(temp2);
929 r = ospath_new_noclean(temp2);
930 D(r);
931 /* ospath_cleanup(r);*/
932 return r;
933 }
934
935 void ospath_append(struct FilePath *fp, struct FilePath *fp1){
936 char *p;
937 char *temp[2];
938 struct FilePath fp2;
939
940 ospath_copy(&fp2,fp1);
941 #ifdef DO_FIXSLASHES
942 ospath_fixslash(fp2.path);
943 #endif
944
945 if(!ospath_isvalid(&fp2)){
946 M("fp1 invalid");
947 return;
948 }
949
950 if(!ospath_isvalid(fp) && ospath_isvalid(&fp2)){
951 // set this object to be the same as the rhs
952 M("fp invalid");
953 ospath_copy(fp,&fp2);
954 #ifdef DO_FIXSLASHES
955 ospath_fixslash(fp->path);
956 #endif
957 return;
958 }
959
960 //X(fp->path);
961 //X(fp2.path);
962
963 // both paths are valid...
964 temp[0] = CALLOC(1+strlen(fp->path), sizeof(char));
965 STRCPY(temp[0], fp->path);
966 temp[1] = CALLOC(strlen(fp2.path), sizeof(char));
967 STRCPY(temp[1], fp2.path);
968
969 //X(temp[0]);
970 //X(temp[1]);
971
972 // make sure temp has a / on the end.
973 if(temp[0][strlen(temp[0]) - 1] != PATH_SEPARATOR_CHAR)
974 {
975 STRCAT(temp[0],PATH_SEPARATOR_STR);
976 }
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 //X(temp[0]);
987 //X(temp[1]);
988
989 // create new path string.
990 STRCPY(fp->path,temp[0]);
991 STRCAT(fp->path,temp[1]);
992
993 FREE(temp[0]);
994 FREE(temp[1]);
995
996 X(fp);
997 ospath_cleanup(fp);
998 }
999
1000 void ospath_copy(struct FilePath *dest, struct FilePath *src){
1001 STRCPY(dest->path,src->path);
1002 #ifdef WINPATHS
1003 STRCPY(dest->drive,src->drive);
1004 #endif
1005 }
1006
1007 void ospath_debug(struct FilePath *fp){
1008 #ifdef WINPATHS
1009 fprintf(stderr,"{\"%s\",\"%s\"}\n",fp->drive,fp->path);
1010 #else
1011 fprintf(stderr,"{\"%s\"}\n",fp->path);
1012 #endif
1013 }
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
1026 //------------------------
1027 // SEARCH PATH FUNCTIONS
1028
1029 struct FilePath **ospath_searchpath_new(const char *path){
1030 char *p;
1031 char *list[LISTMAX];
1032 unsigned n=0;
1033 char *c;
1034 unsigned i;
1035 struct FilePath **pp;
1036 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 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 for(i=0;i<n;++i){
1084 #ifdef DO_FIXSLASHES
1085 ospath_fixslash(pp[i]->path);
1086 #endif
1087 D(pp[i]);
1088 }
1089
1090 return pp;
1091 }
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 }
1100
1101 struct FilePath *ospath_searchpath_iterate(
1102 struct FilePath **searchpath
1103 , FilePathTestFn *testfn
1104 , void *searchdata
1105 ){
1106 struct FilePath **p;
1107
1108 p = searchpath;
1109
1110 M("SEARCHING IN...");
1111 for(p=searchpath; *p!=NULL; ++p){
1112 D(*p);
1113 }
1114
1115 for(p=searchpath; *p!=NULL; ++p){
1116 D(*p);
1117 if((*testfn)(*p,searchdata)){
1118 return *p;
1119 }
1120 }
1121 return NULL;
1122 }
1123
1124
1125 /*--------------------------------
1126 some simple test routines...
1127 */
1128 #ifdef TEST
1129
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 struct FilePath *fp, *fp1, *fp2;
1137 fp = (struct FilePath *)file;
1138 D(fp);
1139 fp1 = ospath_concat(path,fp);
1140 D(fp1);
1141
1142 fp2 = ospath_new("\\GTK\\bin\\johnpye\\extfn");
1143 if(ospath_cmp(fp1,fp2)==0){
1144 return 1;
1145 }
1146 return 0;
1147 }
1148
1149 #include <assert.h>
1150
1151 int main(void){
1152 struct FilePath *fp1, *fp2, *fp3, *fp4;
1153 char *s1, *s2;
1154 struct FilePath **pp, **p1;// will be returned null-terminated
1155 #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
1163 //------------------------
1164
1165 fp1 = ospath_new_from_posix("/usr/local/hello/");
1166 fp2 = ospath_getparent(fp1);
1167 fp3 = ospath_new_from_posix("/usr/local");
1168
1169 D(fp1);
1170 D(fp2);
1171 D(fp3);
1172 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 fp1 = ospath_new_from_posix("models/johnpye/extfn/extfntest");
1180 D(fp1);
1181 fp2 = ospath_new("models\\johnpye\\extfn\\extfntest");
1182 D(fp2);
1183 D(fp1);
1184 assert(ospath_cmp(fp1,fp2)==0);
1185 M("Passed 'new_from_posix' test\n");
1186
1187 ospath_free(fp1);
1188 ospath_free(fp2);
1189
1190 //------------------------
1191 fp1 = ospath_new(".\\src/.\\images\\..\\\\movies\\");
1192 fp2 = ospath_new(".\\src\\movies");
1193
1194 D(fp1);
1195 D(fp2);
1196
1197 assert(ospath_cmp(fp1,fp2)==0);
1198 M("Passed mid-path '..' cleanup test\n");
1199
1200 ospath_free(fp2);
1201
1202 fp2 = ospath_new("./src/movies\\kubrick");
1203 fp3 = ospath_getparent(fp2);
1204
1205 D(fp2);
1206 D(fp3);
1207
1208 assert(ospath_cmp(fp1,fp3)==0);
1209 M("Passed 'second cleanup' test\n");
1210
1211 //------------------------
1212
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 D(fp2);
1222
1223 fp4 = ospath_new("\\home\\john\\where\\mojo\\");
1224
1225 D(fp2);
1226 assert(ospath_cmp(fp2,fp4)==0);
1227 M("Passed 'append' test\n");
1228
1229 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 ospath_append(fp2,fp3);
1242 M("AFTER APPENDING ../..");
1243 D(fp2);
1244
1245 M("GETTING ROOT");
1246 fp4 = ospath_root(fp2);
1247 M("ROOT FOUND:");
1248 D(fp4);
1249
1250 assert(ospath_cmp(fp2,fp4)==0);
1251 M("Passed 'append ../..' test\n");
1252
1253 ospath_free(fp2);
1254 ospath_free(fp3);
1255 ospath_free(fp4);
1256
1257 //-------------------------
1258
1259 fp1 = ospath_new("~\\somewhere\\..");
1260 fp2 = ospath_new("~/.");
1261
1262 assert(ospath_cmp(fp1,fp2)==0);
1263
1264 D(fp2);
1265
1266 ospath_free(fp1);
1267 ospath_free(fp2);
1268
1269 fp1 = ospath_new("/usr/local/include");
1270 fp2 = ospath_new("/usr/include/../local/include");
1271
1272 D(fp1);
1273 D(fp2);
1274
1275 assert(ospath_cmp(fp1,fp2)==0);
1276 M("Passed another mid-path '..' test\n");
1277
1278 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 fp1 = ospath_new("c:/Program Files");
1297 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 fp1 = ospath_new("c:/Program Files/");
1310 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 fp1 = ospath_new("c:/Program Files/GnuWin32/bin");
1323 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 #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 D(fp1);
1348 D(pp[0]);
1349
1350 assert(ospath_cmp(pp[0],fp1)==0);
1351
1352 fp2 = ospath_new_noclean("johnpye/extfn");
1353
1354 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 ospath_free(fp1);
1360 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
1384 //-------------------------------
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 //---------------------------------
1580 M("ALL TESTS PASSED");
1581 }
1582
1583 #endif

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