/[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 589 - (show annotations) (download) (as text)
Thu May 11 03:10:43 2006 UTC (14 years, 6 months ago) by johnpye
File MIME type: text/x-csrc
File size: 35366 byte(s)
Fixing some malloc bugs.
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(strcmp(p, "~")==0){
377
378 if(p == path){ // check that the ~ is the first character in the path
379 if(ospath_isvalid(home)){
380 ospath_copy(fp,home);
381 continue;
382 }else{
383 E("HOME does not resolve to valid path");
384 }
385 }else{
386 E("A tilde (~) present as a component in a file path must be at the start!");
387 }
388 }else if(strcmp(p, ".") == 0){
389
390 if(p==path){// start of path:
391 M("EXPANDING LEADING '.' IN PATH");
392 X(path);
393
394 working = ospath_getcwd();
395
396 D(working);
397 #ifdef WINPATHS
398 X(working->drive);
399 #endif
400 X(p);
401 X(path);
402
403 ospath_copy(fp,working);
404
405
406 D(fp);
407 X(p);
408 //X(path+strlen(p)+1);
409
410 //ospath_free(working);
411 continue;
412 }else{// later in the path: just skip it
413 M("SKIPPING '.' IN PATH");
414 continue;
415 }
416
417 }else if(strcmp(p, "..") == 0){
418 M("GOING TO PARENT");
419 parent = ospath_getparent(fp);
420 if(ospath_isvalid(parent)){
421 ospath_copy(fp,parent);
422 }
423 //ospath_free(parent);
424 continue;
425 }
426
427 // add a separator if we've already got some stuff
428 if(
429 strlen(fp->path) > 0
430 && fp->path[strlen(fp->path) - 1] != PATH_SEPARATOR_CHAR
431 ){
432 STRCAT(fp->path,PATH_SEPARATOR_STR);
433 }
434
435 // add the present path component
436 STRCAT(fp->path, p);
437 }
438 //M("FINISHED STRTOK");
439
440 // put / on end as required, according to what the starting path had
441 if(endslash && (strlen(fp->path) > 0 ? (fp->path[strlen(fp->path) - 1] != PATH_SEPARATOR_CHAR) : 1))
442 {
443 STRCAT(fp->path, PATH_SEPARATOR_STR);
444 }
445 }
446
447
448 int ospath_isvalid(struct FilePath *fp){
449 //if(fp==NULL) return 0;
450 return strlen(fp->path) > 0 ? 1 : 0;
451 }
452
453
454 char *ospath_str(struct FilePath *fp){
455 char *s;
456 #ifdef WINPATHS
457 s = (char *)MALLOC(sizeof(char)*(strlen(fp->drive)+strlen(fp->path) +1) );
458 STRCPY(s,fp->drive);
459 STRCAT(s,fp->path);
460 #else
461 s = MALLOC(sizeof(char)*(strlen(fp->path)+1));
462 STRCPY(s,fp->path);
463 #endif
464 return s;
465 }
466
467 void ospath_strcpy(struct FilePath *fp, char *dest, int destsize){
468 #ifdef WINPATHS
469 STRNCPY(dest,fp->drive,destsize);
470 STRNCAT(dest,fp->path,destsize-strlen(dest));
471 #else
472 STRNCPY(dest,fp->path,destsize);
473 #endif
474 }
475
476
477 void ospath_strcat(struct FilePath *fp, char *dest, int destsize){
478 int remaining = destsize - strlen(dest);
479 V(remaining);
480 #ifdef WINPATHS
481 STRNCAT(dest,fp->drive,remaining);
482 STRNCAT(dest,fp->path,remaining-strlen(dest));
483 #else
484 STRNCAT(dest,fp->path,remaining);
485 #endif
486 D(fp);
487 }
488
489 void ospath_fwrite(struct FilePath *fp, FILE *dest){
490 #ifdef WINPATHS
491 fprintf(dest,"%s%s",fp->drive,fp->path);
492 #else
493 fprintf(dest,"%s",fp->path);
494 #endif
495 }
496
497 unsigned ospath_length(struct FilePath *fp){
498 #ifdef WINPATHS
499 // we've already validated this path, so it's on to just add it up
500 // (unless someone has been tinkering with the internal structure here)
501 return (unsigned) (strlen(fp->drive) + strlen(fp->path));
502 #else
503 return (unsigned) (strlen(fp->path));
504 #endif
505 }
506
507 struct FilePath *ospath_getparent(struct FilePath *fp)
508 {
509 int length;
510 int offset;
511 char *pos;
512 int len1;
513 char sub[PATH_MAX];
514 struct FilePath *fp1, *fp2;
515
516 D(fp);
517
518 if(strlen(fp->path) == 0){
519 fp1 = ospath_getcwd();
520 fp2 = ospath_getparent(fp1);
521 ospath_free(fp1);
522 return fp2;
523 }else if(ospath_isroot(fp)){
524 // stay at root
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 V(len1);
542 //fprintf(stderr,"POS = %d\n",len1);
543
544 if(*pos==PATH_SEPARATOR_CHAR){
545 #ifdef WINPATHS
546 STRCPY(sub,fp->drive);
547 STRNCAT(sub,fp->path,len1);
548 #else
549 STRNCPY(sub,fp->path,len1);
550 sub[len1]='\0';
551 #endif
552 X(sub);
553 if(strcmp(sub,"")==0){
554 M("DIRECTORY IS EMPTY");
555 STRCAT(sub,PATH_SEPARATOR_STR);
556 }
557 }else{
558 E("NO PARENT DIR");
559 return ospath_new_noclean(fp->path);
560 }
561
562 fp1 = ospath_new_noclean(sub);
563 D(fp1);
564 return fp1;
565 }
566
567 struct FilePath *ospath_getparentatdepthn(struct FilePath *fp, unsigned depth)
568 {
569 int startslash;
570 char path[PATH_MAX];
571 char *temp;
572 char *p;
573 STRTOKVAR(nexttok);
574 #ifdef WINPATHS
575 char temp2[PATH_MAX];
576 #endif
577
578 if(
579 !ospath_isvalid(fp)
580 || depth >= ospath_depth(fp)
581 ){
582 return fp;
583 }
584
585 // create FilePath object to parent object at depth N relative to this
586 // path object.
587 startslash = (strlen(fp->path) > 0 && fp->path[0] == PATH_SEPARATOR_CHAR);
588
589 // create a copy of fp->path.
590 STRCPY(path, fp->path);
591
592 // reset fp->path as required.
593 temp = startslash ? PATH_SEPARATOR_STR : "";
594
595 // split path into it tokens.
596 //M("STARTING STRTOK");
597 p = STRTOK(path, PATH_SEPARATOR_STR, nexttok);
598
599 while(p && depth > 0)
600 {
601 if(strlen(temp) > 0 && temp[strlen(temp) - 1] != PATH_SEPARATOR_CHAR)
602 {
603 strcat(temp,PATH_SEPARATOR_STR);
604 }
605
606 STRCAT(temp,p);
607 --depth;
608
609 p = STRTOK(NULL, PATH_SEPARATOR_STR, nexttok);
610 }
611 //M("FINISHED STRTOK");
612
613 // put / on end as required
614 if(strlen(temp) > 0 ? (temp[strlen(temp) - 1] != PATH_SEPARATOR_CHAR) : 1)
615 {
616 strcat(temp,PATH_SEPARATOR_STR);
617 }
618
619 #ifdef WINPATHS
620 STRCPY(temp2,fp->drive);
621 STRCAT(temp2,temp);
622 return ospath_new_noclean(temp2);
623 #else
624 return ospath_new_noclean(temp);
625 #endif
626 }
627
628 char *ospath_getbasefilename(struct FilePath *fp){
629 char *temp;
630 unsigned length, offset;
631 char *pos;
632
633 if(strlen(fp->path) == 0){
634 // return empty name.
635 return "";
636 }
637
638 if(fp->path[strlen(fp->path)-1]==PATH_SEPARATOR_CHAR){
639 return NULL;
640 }
641
642 // reverse find '/' but DON'T ignore a trailing slash
643 // (this is changed from the original implementation)
644 length = strlen(fp->path);
645 offset = length;
646
647 pos = strrchr(fp->path, PATH_SEPARATOR_CHAR); /* OFFSET! */
648
649 // extract filename given position of find / and return it.
650 if(pos != NULL){
651 unsigned length1 = length - ((pos - fp->path) + 1);
652 temp = (char *)MALLOC(sizeof(char)*length1);
653
654 V(length1);
655 STRNCPY(temp, pos + 1, length1);
656 return temp;
657 }else{
658 temp = (char *)MALLOC(sizeof(char)*length);
659 STRNCPY(temp, fp->path, length);
660 return temp;
661 }
662 }
663
664 char *ospath_getfilestem(struct FilePath *fp){
665 char *temp;
666 char *pos;
667
668 if(!ospath_isvalid(fp)){
669 return NULL;
670 }
671
672 temp = ospath_getbasefilename(fp);
673 if(temp==NULL){
674 // it's a directory
675 return NULL;
676 }
677
678 pos = strrchr(temp,'.');
679
680 if(pos==NULL || pos==temp){
681 // no extension, or a filename starting with '.'
682 // -- return the whole filename
683 return temp;
684 }
685
686 // remove extension.
687 *pos = '\0';
688
689 return temp;
690 }
691
692 char *ospath_getfileext(struct FilePath *fp){
693 char *temp, *temp2, *pos;
694 int len1;
695
696 if(!ospath_isvalid(fp)){
697 return NULL;
698 }
699
700 temp = ospath_getbasefilename(fp);
701 if(temp==NULL){
702 // it's a directory
703 return NULL;
704 }
705
706 // make sure there is no / on the end.
707 /// FIXME: is this good policy, removing a trailing slash?
708 if(temp[strlen(temp) - 1] == PATH_SEPARATOR_CHAR){
709 temp[strlen(temp)-1] = '\0';
710 }
711
712 pos = strrchr(temp,'.');
713
714 if(pos != NULL && pos!=temp){
715 // extract extension.
716 len1 = temp + strlen(temp) - pos + 1;
717 temp2 = (char *)MALLOC(sizeof(char)*len1);
718 STRNCPY(temp2, pos, len1);
719 }else{
720 // no extension
721 temp2 = NULL;
722 }
723 FREE(temp);
724 return temp2;
725 }
726
727 int ospath_isroot(struct FilePath *fp)
728 {
729 if(!ospath_isvalid(fp))
730 {
731 return 0;
732 }
733
734 return fp->path == PATH_SEPARATOR_STR ? 1 : 0;
735 }
736
737 unsigned ospath_depth(struct FilePath *fp){
738 unsigned length;
739 unsigned depth;
740 unsigned i;
741
742 length = strlen(fp->path);
743 depth = 0;
744
745 for(i = 0; i < length; i++){
746 if(fp->path[i] == PATH_SEPARATOR_CHAR){
747 ++depth;
748 }
749 }
750
751 if(
752 depth > 0
753 && length > 0
754 && fp->path[length - 1] == PATH_SEPARATOR_CHAR
755 ){
756 // PATH_SEPARATOR_CHAR on the end, reduce count by 1
757 --depth;
758 }
759
760 return depth;
761 }
762
763 struct FilePath *ospath_root(struct FilePath *fp){
764 #ifdef WINPATHS
765 //M("WIN ROOT");
766 char *temp;
767 struct FilePath *r;
768
769 if(strlen(fp->drive)){
770 temp = (char *)MALLOC(sizeof(char)*strlen(fp->drive)+1);
771 STRCPY(temp,fp->drive);
772 STRCAT(temp,PATH_SEPARATOR_STR);
773 X(temp);
774 r = ospath_new(temp);
775 FREE(temp);
776 }else{
777 r = ospath_new(fp->path);
778 }
779 return r;
780 #else
781 //M("JUST RETURNING PATH SEP");
782 return ospath_new(PATH_SEPARATOR_STR);
783 #endif
784 }
785
786 struct FilePath *ospath_getdir(struct FilePath *fp){
787 char *pos;
788 char s[PATH_MAX];
789
790 pos = strrchr(fp->path,PATH_SEPARATOR_CHAR);
791 if(pos==NULL){
792 return ospath_new(".");
793 }
794 #ifdef WINPATHS
795 strncpy(s,fp->drive,PATH_MAX);
796 strncat(s,fp->path,pos - fp->path);
797 #else
798 strncpy(s,fp->path,pos - fp->path);
799 #endif
800 return ospath_new(s);
801 }
802
803 int ospath_cmp(struct FilePath *fp1, struct FilePath *fp2){
804 char temp[2][PATH_MAX];
805 #ifdef WINPATHS
806 char *p;
807 struct FilePath *fp;
808 #endif
809
810 if(!ospath_isvalid(fp1)){
811 if(!ospath_isvalid(fp2)){
812 return 0;
813 }else{
814 return -1;
815 }
816 }else if(!ospath_isvalid(fp2)){
817 return 1;
818 }
819
820 // now, both are valid...
821 //M("BOTH ARE VALID");
822
823 //Check that paths both have drives, if applic.
824 #ifdef WINPATHS
825 if(strcmp(fp1->drive,"")==0){
826 M("PATH IS MISSING DRIVE LETTER");
827 D(fp1);
828 fp = ospath_getcwd();
829 assert(strlen(fp->drive)!=0);
830 X(fp->drive);
831 STRCPY(temp[0],fp->drive);
832 ospath_free(fp);
833 }else{
834 STRCPY(temp[0],fp1->drive);
835 }
836
837 if(strcmp(fp2->drive,"")==0){
838 M("PATH IS MISSING DRIVE LETTER");
839 D(fp2);
840 fp = ospath_getcwd();
841 assert(strlen(fp->drive)!=0);
842 X(fp->drive);
843 STRCPY(temp[1],fp->drive);
844 ospath_free(fp);
845 }else{
846 STRCPY(temp[1],fp2->drive);
847 }
848
849 STRCAT(temp[0],fp1->path);
850 STRCAT(temp[1],fp2->path);
851 #else
852 STRCPY(temp[0], fp1->path);
853 STRCPY(temp[1], fp2->path);
854 #endif
855
856 #ifdef WINPATHS
857 X(temp[0]);
858 for(p=temp[0];*p!='\0';++p){
859 *p=tolower(*p);
860 //C(*p);
861 }
862 X(temp[1]);
863 for(p=temp[1];*p!='\0';++p){
864 *p=tolower(*p);
865 //C(*p);
866 }
867 X(temp[0]);
868 X(temp[1]);
869 #endif
870
871 // we will count two paths that different only in a trailing slash to be the *same*
872 // so we add trailing slashes to both now:
873 if(temp[0][strlen(temp[0]) - 1] != PATH_SEPARATOR_CHAR){
874 STRCAT(temp[0],PATH_SEPARATOR_STR);
875 }
876
877 if(temp[1][strlen(temp[1]) - 1] != PATH_SEPARATOR_CHAR){
878 STRCAT(temp[1],PATH_SEPARATOR_STR);
879 }
880
881 //X(temp[0]);
882 //X(temp[1]);
883
884 return strcmp(temp[0],temp[1]);
885 }
886
887 struct FilePath *ospath_concat(struct FilePath *fp1, struct FilePath *fp2){
888
889 struct FilePath *fp;
890 char temp[2][PATH_MAX];
891 char temp2[PATH_MAX];
892 struct FilePath *r;
893
894 fp = (struct FilePath *)MALLOC(sizeof(struct FilePath));
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