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

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