/[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 588 - (show annotations) (download) (as text)
Thu May 11 02:06:46 2006 UTC (14 years, 2 months ago) by johnpye
File MIME type: text/x-csrc
File size: 35347 byte(s)
This fixes the new Driver.c implementation. Now, default values of the environment variables
are specified in the file base/generic/utilities/config.h.in, which should be tooled up with
you configuration process. These default values will be subject to environment substiution,
so that if you set the default ASCENDTK=$ASCENDDIST/TK, that will be expanded *at runtime*.
This is to help with the 'application folder' style of installation off-root.
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 V(remaining);
483 #ifdef WINPATHS
484 STRNCAT(dest,fp->drive,remaining);
485 STRNCAT(dest,fp->path,remaining-strlen(dest));
486 #else
487 STRNCAT(dest,fp->path,remaining);
488 #endif
489 D(fp);
490 }
491
492 void ospath_fwrite(struct FilePath *fp, FILE *dest){
493 #ifdef WINPATHS
494 fprintf(dest,"%s%s",fp->drive,fp->path);
495 #else
496 fprintf(dest,"%s",fp->path);
497 #endif
498 }
499
500 unsigned ospath_length(struct FilePath *fp){
501 #ifdef WINPATHS
502 // we've already validated this path, so it's on to just add it up
503 // (unless someone has been tinkering with the internal structure here)
504 return (unsigned) (strlen(fp->drive) + strlen(fp->path));
505 #else
506 return (unsigned) (strlen(fp->path));
507 #endif
508 }
509
510 struct FilePath *ospath_getparent(struct FilePath *fp)
511 {
512 int length;
513 int offset;
514 char *pos;
515 int len1;
516 char sub[PATH_MAX];
517 struct FilePath *fp1;
518
519 D(fp);
520
521 if(strlen(fp->path) == 0 || ospath_isroot(fp))
522 {
523 // return empty path.
524 return ospath_new("");
525 }
526
527 // reverse find a / ignoring the end / if it exists.
528 /// FIXME
529 length = strlen(fp->path);
530 offset = (
531 fp->path[length - 1] == PATH_SEPARATOR_CHAR // last char is slash?
532 && length > 1 // and more than just leading slash...
533 ) ? length - 1 : length; // then remove last char
534
535 for(pos = fp->path + offset - 1; *pos!=PATH_SEPARATOR_CHAR && pos>=fp->path; --pos){
536 //fprintf(stderr,"CURRENT CHAR: %c\n",*pos);
537 }
538
539 len1 = (int)pos - (int)fp->path;
540 V(len1);
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 = (char *)MALLOC(sizeof(char)*length1);
652
653 V(length1);
654 STRNCPY(temp, pos + 1, length1);
655 return temp;
656 }else{
657 temp = (char *)MALLOC(sizeof(char)*length);
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 + 1;
716 temp2 = (char *)MALLOC(sizeof(char)*len1);
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 = (char *)MALLOC(sizeof(char)*strlen(fp->drive)+1);
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 struct FilePath *fp;
807 #endif
808
809 if(!ospath_isvalid(fp1)){
810 if(!ospath_isvalid(fp2)){
811 return 0;
812 }else{
813 return -1;
814 }
815 }else if(!ospath_isvalid(fp2)){
816 return 1;
817 }
818
819 // now, both are valid...
820 //M("BOTH ARE VALID");
821
822 //Check that paths both have drives, if applic.
823 #ifdef WINPATHS
824 if(strcmp(fp1->drive,"")==0){
825 M("PATH IS MISSING DRIVE LETTER");
826 D(fp1);
827 fp = ospath_getcwd();
828 assert(strlen(fp->drive)!=0);
829 X(fp->drive);
830 STRCPY(temp[0],fp->drive);
831 ospath_free(fp);
832 }else{
833 STRCPY(temp[0],fp1->drive);
834 }
835
836 if(strcmp(fp2->drive,"")==0){
837 M("PATH IS MISSING DRIVE LETTER");
838 D(fp2);
839 fp = ospath_getcwd();
840 assert(strlen(fp->drive)!=0);
841 X(fp->drive);
842 STRCPY(temp[1],fp->drive);
843 ospath_free(fp);
844 }else{
845 STRCPY(temp[1],fp2->drive);
846 }
847
848 STRCAT(temp[0],fp1->path);
849 STRCAT(temp[1],fp2->path);
850 #else
851 STRCPY(temp[0], fp1->path);
852 STRCPY(temp[1], fp2->path);
853 #endif
854
855 #ifdef WINPATHS
856 X(temp[0]);
857 for(p=temp[0];*p!='\0';++p){
858 *p=tolower(*p);
859 //C(*p);
860 }
861 X(temp[1]);
862 for(p=temp[1];*p!='\0';++p){
863 *p=tolower(*p);
864 //C(*p);
865 }
866 X(temp[0]);
867 X(temp[1]);
868 #endif
869
870 // we will count two paths that different only in a trailing slash to be the *same*
871 // so we add trailing slashes to both now:
872 if(temp[0][strlen(temp[0]) - 1] != PATH_SEPARATOR_CHAR){
873 STRCAT(temp[0],PATH_SEPARATOR_STR);
874 }
875
876 if(temp[1][strlen(temp[1]) - 1] != PATH_SEPARATOR_CHAR){
877 STRCAT(temp[1],PATH_SEPARATOR_STR);
878 }
879
880 //X(temp[0]);
881 //X(temp[1]);
882
883 return strcmp(temp[0],temp[1]);
884 }
885
886 struct FilePath *ospath_concat(struct FilePath *fp1, struct FilePath *fp2){
887
888 struct FilePath *fp;
889 char temp[2][PATH_MAX];
890 char temp2[PATH_MAX];
891 struct FilePath *r;
892
893 fp = (struct FilePath *)MALLOC(sizeof(struct FilePath));
894
895 D(fp1);
896 D(fp2);
897
898 if(!ospath_isvalid(fp1)){
899 if(ospath_isvalid(fp2)){
900 ospath_copy(fp,fp2);
901 }else{
902 // both invalid
903 ospath_copy(fp,fp1);
904 }
905 return fp;
906 }
907
908 if(!ospath_isvalid(fp2)){
909 ospath_copy(fp,fp1);
910 return fp;
911 }
912
913 // not just a copy of one or the other...
914 ospath_free(fp);
915
916 // now, both paths are valid...
917
918 #ifdef WINPATHS
919 STRNCPY(temp[0],fp1->drive,PATH_MAX);
920 STRNCAT(temp[0],fp1->path,PATH_MAX-strlen(temp[0]));
921 #else
922 STRNCPY(temp[0], fp1->path,PATH_MAX);
923 #endif
924
925 STRNCPY(temp[1], fp2->path,PATH_MAX);
926
927 // make sure temp has a / on the end.
928 if(temp[0][strlen(temp[0]) - 1] != PATH_SEPARATOR_CHAR)
929 {
930 STRNCAT(temp[0],PATH_SEPARATOR_STR,PATH_MAX-strlen(temp[0]));
931 }
932
933 #ifdef DO_FIXSLASHES
934 ospath_fixslash(temp[0]);
935 ospath_fixslash(temp[1]);
936 #endif
937
938 //V(strlen(temp[0]));
939 //X(temp[0]);
940 //V(strlen(temp[1]));
941 //X(temp[1]);
942
943 // make sure rhs path has NOT got a / at the start.
944 if(temp[1][0] == PATH_SEPARATOR_CHAR){
945 return NULL;
946 }
947
948 // create a new path object with the two path strings appended together.
949 STRNCPY(temp2,temp[0],PATH_MAX);
950 STRNCAT(temp2,temp[1],PATH_MAX-strlen(temp2));
951 //V(strlen(temp2));
952 //X(temp2);
953 r = ospath_new_noclean(temp2);
954 D(r);
955
956 /* ospath_cleanup(r);*/
957 return r;
958 }
959
960 void ospath_append(struct FilePath *fp, struct FilePath *fp1){
961 char *p;
962 char temp[2][PATH_MAX];
963 struct FilePath fp2;
964
965 ospath_copy(&fp2,fp1);
966 #ifdef DO_FIXSLASHES
967 ospath_fixslash(fp2.path);
968 #endif
969
970 if(!ospath_isvalid(&fp2)){
971 M("fp1 invalid");
972 return;
973 }
974
975 if(!ospath_isvalid(fp) && ospath_isvalid(&fp2)){
976 // set this object to be the same as the rhs
977 M("fp invalid");
978 ospath_copy(fp,&fp2);
979 #ifdef DO_FIXSLASHES
980 ospath_fixslash(fp->path);
981 #endif
982 return;
983 }
984
985 X(fp->path);
986 X(fp2.path);
987
988 // both paths are valid...
989 //temp[0] = CALLOC(1+strlen(fp->path), sizeof(char));
990 STRNCPY(temp[0], fp->path, PATH_MAX);
991 //temp[1] = CALLOC(strlen(fp2.path), sizeof(char));
992 STRNCPY(temp[1], fp2.path, PATH_MAX);
993
994 X(temp[0]);
995 X(temp[1]);
996
997 // make sure temp has a / on the end.
998 if(temp[0][strlen(temp[0]) - 1] != PATH_SEPARATOR_CHAR)
999 {
1000 STRCAT(temp[0],PATH_SEPARATOR_STR);
1001 }
1002
1003 // make sure rhs path has NOT got a / at the start.
1004 if(temp[1][0] == PATH_SEPARATOR_CHAR){
1005 for(p=temp[1]+1; *p != '\0'; ++p){
1006 *(p-1)=*p;
1007 }
1008 *(p-1)='\0';
1009 }
1010
1011 X(temp[0]);
1012 X(temp[1]);
1013
1014 // create new path string.
1015 STRNCPY(fp->path,temp[0], PATH_MAX);
1016 STRNCAT(fp->path,temp[1], PATH_MAX-strlen(fp->path));
1017
1018 X(fp->path);
1019
1020 //FREE(temp[0]);
1021 //M("Freed temp[0]");
1022 //FREE(temp[1]);
1023 //M("Freed temp[1]");
1024
1025 D(fp);
1026 ospath_cleanup(fp);
1027 }
1028
1029 void ospath_copy(struct FilePath *dest, struct FilePath *src){
1030 STRCPY(dest->path,src->path);
1031 #ifdef WINPATHS
1032 STRCPY(dest->drive,src->drive);
1033 #endif
1034 }
1035
1036 void ospath_debug(struct FilePath *fp){
1037 #ifdef WINPATHS
1038 fprintf(stderr,"{\"%s\",\"%s\"}\n",fp->drive,fp->path);
1039 #else
1040 fprintf(stderr,"{\"%s\"}\n",fp->path);
1041 #endif
1042 }
1043
1044 FILE *ospath_fopen(struct FilePath *fp, const char *mode){
1045 char s[PATH_MAX];
1046 if(!ospath_isvalid(fp)){
1047 E("Invalid path");
1048 return NULL;
1049 }
1050 ospath_strcpy(fp,s,PATH_MAX);
1051 FILE *f = fopen(s,mode);
1052 return f;
1053 }
1054
1055 //------------------------
1056 // SEARCH PATH FUNCTIONS
1057
1058 struct FilePath **ospath_searchpath_new(const char *path){
1059 char *p;
1060 char *list[LISTMAX];
1061 unsigned n=0;
1062 char *c;
1063 unsigned i;
1064 struct FilePath **pp;
1065 STRTOKVAR(nexttok);
1066
1067 char path1[PATH_MAX];
1068 strncpy(path1,path,PATH_MAX);
1069
1070 X(path1);
1071 X(PATH_LISTSEP_STR);
1072
1073 V(strlen(path1));
1074 V(strlen(PATH_LISTSEP_STR));
1075
1076 /*
1077 c = strstr(path,PATH_LISTSEP_CHAR);
1078 if(c==NULL){
1079 E("NO TOKEN FOUND");
1080 }
1081 */
1082
1083 p=STRTOK(path1,PATH_LISTSEP_STR,nexttok);
1084 X(p);
1085 for(; p!= NULL; p=STRTOK(NULL,PATH_LISTSEP_STR,nexttok)){
1086 c = (char *)MALLOC(sizeof(char)*strlen(p));
1087 X(p);
1088 STRCPY(c,p);
1089 if(n>=LISTMAX){
1090 E("IGNORING SOME PATH COMPONENTS");
1091 break;
1092 }
1093 list[n++]=c;
1094 }
1095
1096 /*
1097 for(i=0;i<n;++i){
1098 X(list[i]);
1099 }
1100 V(n);
1101 */
1102
1103 pp = (struct FilePath **)MALLOC(sizeof(struct FilePath*)*(n+1));
1104 for(i=0; i<n; ++i){
1105 //V(i);
1106 //X(list[i]);
1107 pp[i] = ospath_new_noclean(list[i]);
1108 //D(pp[i]);
1109 }
1110 pp[n] = NULL;
1111
1112 for(i=0;i<n;++i){
1113 #ifdef DO_FIXSLASHES
1114 ospath_fixslash(pp[i]->path);
1115 #endif
1116 D(pp[i]);
1117 }
1118
1119 return pp;
1120 }
1121
1122 void ospath_searchpath_free(struct FilePath **searchpath){
1123 struct FilePath **p;
1124 for(p=searchpath; *p!=NULL; ++p){
1125 ospath_free(*p);
1126 }
1127 FREE(searchpath);
1128 }
1129
1130 struct FilePath *ospath_searchpath_iterate(
1131 struct FilePath **searchpath
1132 , FilePathTestFn *testfn
1133 , void *searchdata
1134 ){
1135 struct FilePath **p;
1136
1137 p = searchpath;
1138
1139 M("SEARCHING IN...");
1140 for(p=searchpath; *p!=NULL; ++p){
1141 D(*p);
1142 }
1143
1144 for(p=searchpath; *p!=NULL; ++p){
1145 D(*p);
1146 if((*testfn)(*p,searchdata)){
1147 return *p;
1148 }
1149 }
1150 return NULL;
1151 }
1152
1153
1154 /*--------------------------------
1155 some simple test routines...
1156 */
1157 #ifdef TEST
1158
1159 FilePathTestFn ospath_searchpath_testexists;
1160
1161 /**
1162 This is a sample searchpath test function. Assumes the 'userfdata' is a
1163 relative FilePath which is appended to path, and then if it matches
1164 the path \GTK\bin\johnpye\extfn, returns true. This is of
1165 course a fairly useless test function, so it's just for testing.
1166 */
1167 int ospath_searchpath_testexists(struct FilePath *path,void *file){
1168 struct FilePath *fp, *fp1, *fp2;
1169 fp = (struct FilePath *)file;
1170 D(fp);
1171 fp1 = ospath_concat(path,fp);
1172 D(fp1);
1173
1174 #ifdef WINPATHS
1175 fp2 = ospath_new("c:\\GTK\\bin\\johnpye\\extfn");
1176 #else
1177 fp2 = ospath_new("/GTK/bin/johnpye/extfn");
1178 #endif
1179
1180 char *t=ospath_str(fp1);
1181 MC("1",t);
1182 FREE(t);
1183
1184 t=ospath_str(fp2);
1185 MC("31;1",t);
1186 FREE(t);
1187
1188 if(ospath_cmp(fp1,fp2)==0){
1189 MC("32","MATCH");
1190 return 1;
1191 }
1192 MC("31","NO MATCH");
1193 return 0;
1194 }
1195
1196 #include <assert.h>
1197
1198 // switch to boldface for messages in 'main'
1199 #undef D
1200 #define D DD
1201 #undef M
1202 #define M MM
1203
1204 int main(void){
1205 struct FilePath *fp1, *fp2, *fp3, *fp4;
1206 char *s1;
1207 struct FilePath **pp, **p1;// will be returned null-terminated
1208 #ifdef WINPATHS
1209 char pathtext[]="c:\\Program Files\\GnuWin32\\bin;c:\\GTK\\bin;e:\\ascend\\;..\\..\\pygtk";
1210 char pathtext2[]="c:\\Program Files\\ASCEND\\models";
1211 #else
1212 char pathtext[]="\\Program Files\\GnuWin32\\bin:\\GTK\\bin:\\ascend\\:..\\..\\pygtk";
1213 char pathtext2[]="/usr/local/ascend/models";
1214 #endif
1215
1216 //------------------------
1217
1218 fp1 = ospath_new_from_posix("/usr/local/hello/");
1219 fp2 = ospath_getparent(fp1);
1220 fp3 = ospath_new_from_posix("/usr/local");
1221
1222 D(fp1);
1223 D(fp2);
1224 D(fp3);
1225 assert(ospath_cmp(fp2,fp3)==0);
1226 M("Passed 'getparent' test\n");
1227
1228 ospath_free(fp1); ospath_free(fp2); ospath_free(fp3);
1229
1230 //------------------------
1231
1232 fp1 = ospath_new_from_posix("models/johnpye/extfn/extfntest");
1233 D(fp1);
1234 fp2 = ospath_new("models\\johnpye\\extfn\\extfntest");
1235 D(fp2);
1236 D(fp1);
1237 assert(ospath_cmp(fp1,fp2)==0);
1238 M("Passed 'new_from_posix' test\n");
1239
1240 ospath_free(fp1);
1241 ospath_free(fp2);
1242
1243 //------------------------
1244 fp1 = ospath_new(".\\src/.\\images\\..\\\\movies\\");
1245 fp2 = ospath_new(".\\src\\movies");
1246
1247 D(fp1);
1248 D(fp2);
1249
1250 assert(ospath_cmp(fp1,fp2)==0);
1251 M("Passed mid-path '..' cleanup test\n");
1252
1253 ospath_free(fp2);
1254
1255 fp2 = ospath_new("./src/movies\\kubrick");
1256 fp3 = ospath_getparent(fp2);
1257
1258 D(fp2);
1259 D(fp3);
1260
1261 assert(ospath_cmp(fp1,fp3)==0);
1262 M("Passed 'second cleanup' test\n");
1263
1264 //------------------------
1265
1266 fp2 = ospath_new("\\home\\john");
1267 fp3 = ospath_new("where\\mojo");
1268
1269 D(fp2);
1270 D(fp3);
1271
1272 ospath_append(fp2,fp3);
1273
1274 D(fp2);
1275
1276 fp4 = ospath_new("\\home\\john\\where\\mojo\\");
1277
1278 D(fp2);
1279 assert(ospath_cmp(fp2,fp4)==0);
1280 M("Passed 'append' test\n");
1281
1282 ospath_free(fp3);
1283 ospath_free(fp2);
1284
1285 //---------------------------
1286
1287 fp3 = ospath_new_noclean("../..");
1288 D(fp3);
1289
1290 // test with appending ../.. to an existing path
1291 fp2 = ospath_new("\\home\\john");
1292 M("ORIGINAL PATH");
1293 D(fp2);
1294 ospath_append(fp2,fp3);
1295 M("AFTER APPENDING ../..");
1296 D(fp2);
1297
1298 M("GETTING ROOT");
1299 fp4 = ospath_root(fp2);
1300 M("ROOT FOUND:");
1301 D(fp4);
1302
1303 assert(ospath_cmp(fp2,fp4)==0);
1304 M("Passed 'append ../..' test\n");
1305
1306 ospath_free(fp2);
1307 ospath_free(fp3);
1308 ospath_free(fp4);
1309
1310 //-------------------------
1311
1312 fp1 = ospath_new("~\\somewhere\\..");
1313 fp2 = ospath_new("~/.");
1314
1315 assert(ospath_cmp(fp1,fp2)==0);
1316
1317 D(fp2);
1318
1319 ospath_free(fp1);
1320 ospath_free(fp2);
1321
1322 fp1 = ospath_new("/usr/local/include");
1323 fp2 = ospath_new("/usr/include/../local/include");
1324
1325 D(fp1);
1326 D(fp2);
1327
1328 assert(ospath_cmp(fp1,fp2)==0);
1329 M("Passed another mid-path '..' test\n");
1330
1331 ospath_free(fp1);
1332 ospath_free(fp2);
1333
1334 //---------------------------
1335
1336 fp1 = ospath_new("/home");
1337 fp2 = ospath_new("john");
1338 fp3 = ospath_concat(fp1, fp2);
1339
1340 fp4 = ospath_new("/home/john");
1341
1342 assert(ospath_cmp(fp3,fp4)==0);
1343 M("Passed 'ospath_concat' test\n");
1344
1345 ospath_free(fp1); ospath_free(fp2); ospath_free(fp3); ospath_free(fp4);
1346
1347 //---------------------------
1348
1349 fp1 = ospath_new("c:/Program Files");
1350 fp2 = ospath_new("GnuWin32\\bin");
1351 fp3 = ospath_concat(fp1, fp2);
1352
1353 fp4 = ospath_new("c:/Program Files/GnuWin32/bin");
1354
1355 assert(ospath_cmp(fp3,fp4)==0);
1356 M("Passed 'ospath_concat' test\n");
1357
1358 ospath_free(fp1); ospath_free(fp2); ospath_free(fp3); ospath_free(fp4);
1359
1360 //---------------------------
1361
1362 fp1 = ospath_new("c:/Program Files/");
1363 fp2 = ospath_new("GnuWin32\\bin");
1364 fp3 = ospath_concat(fp1, fp2);
1365
1366 fp4 = ospath_new("c:/Program Files/GnuWin32/bin");
1367
1368 assert(ospath_cmp(fp3,fp4)==0);
1369 M("Passed trailing-slash 'ospath_concat' test\n");
1370
1371 ospath_free(fp1); ospath_free(fp2); ospath_free(fp3); ospath_free(fp4);
1372
1373 //---------------------------
1374
1375 fp1 = ospath_new("c:/Program Files/GnuWin32/bin");
1376 fp2 = ospath_new("johnpye/extfn");
1377 fp3 = ospath_concat(fp1, fp2);
1378
1379 fp4 = ospath_new("c:/Program Files/GnuWin32/bin/johnpye/extfn");
1380
1381 assert(ospath_cmp(fp3,fp4)==0);
1382 M("Passed trailing-slash 'ospath_concat' test\n");
1383
1384 ospath_free(fp1); ospath_free(fp2); ospath_free(fp3); ospath_free(fp4);
1385
1386 //---------------------------
1387
1388 pp = ospath_searchpath_new(pathtext);
1389
1390 for(p1=pp; *p1!=NULL; ++p1){
1391 D(*p1);
1392 }
1393
1394 #ifdef WINPATHS
1395 fp1 = ospath_new("c:\\program files\\GnuWin32\\bin");
1396 #else
1397 fp1 = ospath_new("\\Program Files\\GnuWin32\\bin");
1398 #endif
1399
1400 assert(pp[0]!=NULL);
1401 assert(fp1!=NULL);
1402
1403 D(fp1);
1404 D(pp[0]);
1405
1406 assert(ospath_cmp(pp[0],fp1)==0);
1407
1408
1409
1410 fp2 = ospath_new_noclean("johnpye/extfn");
1411 D(fp2);
1412
1413 fflush(stderr);
1414
1415 fp3 = ospath_searchpath_iterate(pp,&ospath_searchpath_testexists,(void*)fp2);
1416
1417 assert(fp3!=NULL);
1418 D(fp3);
1419 D(pp[1]);
1420
1421 assert(ospath_cmp(fp3,pp[1])==0);
1422 M("Passed path-search test\n");
1423
1424 ospath_free(fp1);
1425 ospath_free(fp2);
1426 ospath_searchpath_free(pp);
1427
1428 //-------------------------------
1429
1430 M("Path-search test 2...");
1431
1432 pp = ospath_searchpath_new(pathtext2);
1433
1434 assert(pp!=NULL);
1435
1436 for (p1=pp; *p1!=NULL; ++p1){
1437 D(*p1);
1438 }
1439
1440 fp2 = ospath_new_noclean("johnpye/extfn/extfntest");
1441 D(fp2);
1442
1443 fp3 = ospath_searchpath_iterate(pp,&ospath_searchpath_testexists,(void*)fp2);
1444 assert(fp3==NULL);
1445
1446 M("Passed path-search test 2\n");
1447
1448 ospath_free(fp2);
1449 ospath_free(fp3);
1450 ospath_searchpath_free(pp);
1451
1452 //-------------------------------
1453
1454 fp1 = ospath_new("/usr/share/data/ascend/models/johnpye/extfn/extfntest.a4c");
1455 D(fp1);
1456 s1 = ospath_getbasefilename(fp1);
1457 X(s1);
1458 assert(strcmp(s1,"extfntest.a4c")==0);
1459 M("Passed getbasefilename test\n");
1460
1461 ospath_free(fp1);
1462 FREE(s1);
1463
1464 //-------------------------------
1465
1466 fp1 = ospath_new("extfntest.a4c");
1467 D(fp1);
1468 s1 = ospath_getbasefilename(fp1);
1469 X(s1);
1470 assert(strcmp(s1,"extfntest.a4c")==0);
1471 M("Passed getbasefilename test 2\n");
1472
1473 ospath_free(fp1);
1474 FREE(s1);
1475
1476
1477 //-------------------------------
1478
1479 fp1 = ospath_new("/here/is/my/path.dir/");
1480 D(fp1);
1481 s1 = ospath_getbasefilename(fp1);
1482 X(s1);
1483 assert(NULL==s1);
1484 M("Passed getbasefilename test 3\n");
1485
1486 ospath_free(fp1);
1487 FREE(s1);
1488
1489 //-------------------------------
1490
1491 #ifdef WINPATHS
1492 fp1 = ospath_new("c:extfntest.a4c");
1493 D(fp1);
1494 s1 = ospath_getbasefilename(fp1);
1495 X(s1);
1496 assert(strcmp(s1,"extfntest.a4c")==0);
1497 M("Passed getbasefilename test WINPATHS\n");
1498
1499 ospath_free(fp1);
1500 FREE(s1);
1501 #endif
1502
1503 //-------------------------------
1504
1505 fp1 = ospath_new("/usr/share/data/ascend/models/johnpye/extfn/extfntest.a4c");
1506 D(fp1);
1507 s1 = ospath_getfilestem(fp1);
1508 X(s1);
1509 assert(strcmp(s1,"extfntest")==0);
1510 M("Passed getfilestem test\n");
1511
1512 ospath_free(fp1);
1513 FREE(s1);
1514
1515 //-------------------------------
1516
1517 fp1 = ospath_new("/usr/share/data/ascend/models/johnpye/extfn/extfntest");
1518 D(fp1);
1519 s1 = ospath_getfilestem(fp1);
1520 X(s1);
1521 assert(strcmp(s1,"extfntest")==0);
1522 M("Passed getfilestem test 2\n");
1523
1524 ospath_free(fp1);
1525 FREE(s1);
1526
1527 //-------------------------------
1528
1529 fp1 = ospath_new("/usr/share/data/ascend/.ascend.ini");
1530 D(fp1);
1531 s1 = ospath_getfilestem(fp1);
1532 X(s1);
1533 assert(strcmp(s1,".ascend")==0);
1534 M("Passed getfilestem test 3\n");
1535
1536 ospath_free(fp1);
1537 FREE(s1);
1538
1539 //-------------------------------
1540
1541 fp1 = ospath_new("~/.vimrc");
1542 D(fp1);
1543 s1 = ospath_getfilestem(fp1);
1544 X(s1);
1545 assert(strcmp(s1,".vimrc")==0);
1546 M("Passed getfilestem test 3\n");
1547
1548 ospath_free(fp1);
1549 FREE(s1);
1550
1551 //-------------------------------
1552
1553 fp1 = ospath_new("~/src/ascend-0.9.5-1.jdpipe.src.rpm");
1554 D(fp1);
1555 s1 = ospath_getfilestem(fp1);
1556 X(s1);
1557 assert(strcmp(s1,"ascend-0.9.5-1.jdpipe.src")==0);
1558 M("Passed getfilestem test 4\n");
1559
1560 ospath_free(fp1);
1561 FREE(s1);
1562
1563 //-------------------------------
1564
1565 fp1 = ospath_new("~/dir1/dir2/");
1566 D(fp1);
1567 s1 = ospath_getfilestem(fp1);
1568 X(s1);
1569 assert(NULL==s1);
1570 M("Passed getfilestem test 5\n");
1571
1572 ospath_free(fp1);
1573 FREE(s1);
1574
1575 //-------------------------------
1576
1577 fp1 = ospath_new("~/src/ascend-0.9.5-1.jdpipe.src.rpm");
1578 D(fp1);
1579 s1 = ospath_getfileext(fp1);
1580 X(s1);
1581 assert(strcmp(s1,".rpm")==0);
1582 M("Passed getbasefileext test\n");
1583
1584 ospath_free(fp1);
1585 FREE(s1);
1586
1587 //-------------------------------
1588
1589 fp1 = ospath_new("~/.vimrc");
1590 D(fp1);
1591 s1 = ospath_getfileext(fp1);
1592 X(s1);
1593 assert(s1==NULL);
1594 M("Passed getbasefileext test 2\n");
1595
1596 ospath_free(fp1);
1597 FREE(s1);
1598
1599 //-------------------------------
1600
1601 fp1 = ospath_new("./ascend4");
1602 D(fp1);
1603 s1 = ospath_getfileext(fp1);
1604 X(s1);
1605 assert(s1==NULL);
1606 M("Passed getbasefileext test 3\n");
1607
1608 ospath_free(fp1);
1609 FREE(s1);
1610
1611 //-------------------------------
1612
1613 fp1 = ospath_new("/home/myfile");
1614 fp2 = ospath_getdir(fp1);
1615 fp3 = ospath_new("/home");
1616 assert(ospath_cmp(fp2,fp3)==0);
1617 M("Passed ospath_getdir test\n");
1618
1619 ospath_free(fp1);
1620 ospath_free(fp2);
1621 ospath_free(fp3);
1622
1623 //-------------------------------
1624
1625 fp1 = ospath_new("/home/myfile.ext");
1626 fp2 = ospath_getdir(fp1);
1627 fp3 = ospath_new("/home");
1628 assert(ospath_cmp(fp2,fp3)==0);
1629 M("Passed ospath_getdir test 2\n");
1630
1631 ospath_free(fp1);
1632 ospath_free(fp2);
1633 ospath_free(fp3);
1634
1635 //-------------------------------
1636
1637 fp1 = ospath_new("/home/mydir/");
1638 fp2 = ospath_getdir(fp1);
1639 fp3 = ospath_new("/home/mydir");
1640 assert(ospath_cmp(fp2,fp3)==0);
1641 M("Passed ospath_getdir test 3\n");
1642
1643 ospath_free(fp1);
1644 ospath_free(fp2);
1645 ospath_free(fp3);
1646
1647 //---------------------------------
1648 M("ALL TESTS PASSED");
1649 return 0;
1650 }
1651
1652 #define DONE_TEST
1653
1654 #endif

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