/[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 535 - (show annotations) (download) (as text)
Tue Apr 25 14:55:48 2006 UTC (14 years, 1 month ago) by johnpye
File MIME type: text/x-csrc
File size: 18943 byte(s)
Little more progress on the ospath stuff. Hoping that this can be used to refactor the module (a4c) and external library (.so/.dll) search methods. Still some bugs though.
1 #include <stdio.h>
2 #include <ctype.h>
3
4 #include "ospath.h"
5
6 #if defined(__WIN32__) /* && !defined(__MINGW32__) */
7 # define WINPATHS
8 #endif
9
10 struct FilePath{
11 char path[PATHMAX]; /// the string version of the represented POSIX path
12
13 #ifdef WINPATHS
14 char drive[2]; /// the drive the path resides on (field is absent in POSIX systems)
15 #endif
16 };
17
18 #include <string.h>
19
20 #define MALLOC malloc
21 #define FREE free
22 #define CALLOC calloc
23
24 #define M(MSG) fprintf(stderr,"%s:%d: (%s) %s\n",__FILE__,__LINE__,__FUNCTION__,MSG)
25 #define E(MSG) fprintf(stderr,"%s:%d: (%s) ERROR: %s\n",__FILE__,__LINE__,__FUNCTION__,MSG)
26 #define X(VAR) fprintf(stderr,"%s:%d: (%s) %s=%s\n",__FILE__,__LINE__,__FUNCTION__,#VAR,VAR)
27 #define V(VAR) fprintf(stderr,"%s:%d: (%s) %s=%d\n",__FILE__,__LINE__,__FUNCTION__,#VAR,VAR)
28 #define D(VAR) ospath_debug(VAR,#VAR)
29
30 /**
31 Static function that can be used to retrieve the current users HOME path
32 */
33 struct FilePath *ospath_gethomepath(void);
34
35 /**
36 This function cleans up the path string used to construct the FilePath object:
37 1. Get rid of multiple / 's one after the other...
38
39 ie. "///usr/bin///hello/////there// --> "/usr/bin/hello/there/"
40
41 2. Resolve a leading tilde (~) to the current user's HOME path
42
43 3. Remove redundant /./ in middle of path
44
45 4. Remove reduncant dir/.. in path
46
47 5. Environment substitution??
48
49 6. On windows, drive reference if not specified
50
51 7. What about \\server\path and URLs, gnomefs, etc?
52 */
53 void ospath_cleanup(struct FilePath *);
54
55 void ospath_copy(struct FilePath *dest, struct FilePath *src);
56
57
58 #ifdef WINPATHS
59 /**
60 This function splits out the drive letter in the path string, thus completing
61 the correct construction of a FilePath object under Win32.
62 */
63 void ospath_extractdriveletter(struct FilePath *);
64 #endif
65
66 #ifdef WINPATHS
67 # define PATH_SEPARATOR_STR "\\"
68 # define PATH_SEPARATOR_CHAR '\\'
69 #else
70 # define PATH_SEPARATOR_STR "/"
71 # define PATH_SEPARATOR_CHAR '/'
72 #endif
73
74 /**
75 Create a new path structure from a string
76 */
77 struct FilePath *ospath_new(const char *path){
78 struct FilePath *fp;
79 fp = MALLOC(sizeof(struct FilePath));
80 X(path);
81 strcpy(fp->path, path);
82
83 #ifdef WINPATHS
84 X(fp->path);
85 ospath_extractdriveletter(fp);
86 #endif
87
88 ospath_cleanup(fp);
89
90 return fp;
91 }
92
93 /**
94 This function will serve to allow #include-style file paths
95 to be specified with platform-independent forward slashes then
96 translated into the local filesystem format for subsequent use.
97
98 This method should be identical to ospath_new on posix, right?
99
100 @NOTE: on windows, we also want:
101 C:dir/file --> c:$PWD\dir\file
102 e:/hello --> e:\hello
103 here/i/am --> here\i\am
104
105 @NOTE:
106 A path-search function should create full file paths by
107 appending relative file to each component of the search path
108 then performing a callback on each one to determine if the
109 match is OK or not.
110 */
111 struct FilePath *ospath_new_from_posix(char *posixpath){
112 struct FilePath *fp = MALLOC(sizeof(struct FilePath));
113 char *p;
114 strcpy(fp->path,posixpath);
115 #ifdef WINPATHS
116 X(fp->path);
117 ospath_extractdriveletter(fp);
118 #endif
119
120 char path[PATHMAX];
121 strcpy(path,fp->path);
122
123 //X(path);
124
125 int startslash = (strlen(path) > 0 && path[0] == '/');
126 int endslash = (strlen(path) > 1 && path[strlen(path) - 1] == '/');
127
128 //V(startslash);
129 //V(endslash);
130
131 // reset fp->path as required.
132 strcpy(fp->path, (startslash ? PATH_SEPARATOR_STR : ""));
133
134 for(p = strtok(path, "/");
135 p!=NULL;
136 p = strtok(NULL,"/")
137 ){
138 // add a separator if we've already got some stuff
139 if(
140 strlen(fp->path) > 0
141 && fp->path[strlen(fp->path) - 1] != PATH_SEPARATOR_CHAR
142 ){
143 strcat(fp->path,PATH_SEPARATOR_STR);
144 }
145
146 strcat(fp->path,p);
147 }
148
149 // put / on end as required, according to what the starting path had
150 if(endslash && (strlen(fp->path) > 0 ? (fp->path[strlen(fp->path) - 1] != PATH_SEPARATOR_CHAR) : 1))
151 {
152 //M("adding endslash!");
153
154 strcat(fp->path, PATH_SEPARATOR_STR);
155 }
156
157 //X(fp->path);
158
159 ospath_cleanup(fp);
160
161 return(fp);
162 }
163
164 /**
165 As for ospath_new but the 'cleanup' call is now optional
166 */
167 struct FilePath *ospath_new_noclean(const char *path){
168 struct FilePath *fp = MALLOC(sizeof(struct FilePath));
169 strcpy(fp->path,path);
170
171 #ifdef WINPATHS
172 X(fp->path);
173 ospath_extractdriveletter(fp);
174 #endif
175
176 return fp;
177 }
178
179 /**
180 Use getenv() function to retrieve HOME path, or if not set, use
181 the password database and try to retrieve it that way (???)
182 */
183 struct FilePath *ospath_gethomepath(void){
184
185 const char *pfx = getenv("HOME");
186
187 #ifndef __WIN32__
188 if(pfx==NULL){
189 struct passwd * pw = getpwuid(getuid());
190
191 if(pw){
192 pfx = pw -> pw_dir;
193 }
194 }
195 #endif
196
197 // create path object from HOME, but don't compress it!
198 return ospath_new_noclean(pfx ? pfx : "");
199 }
200
201 #ifdef WINPATHS
202 void ospath_extractdriveletter(struct FilePath *fp)
203 {
204 X(fp->path);
205 // extract the drive the path resides on...
206 if(strlen(fp->path) >= 2 && fp->path[1] == ':')
207 {
208 char driveletter = '\0';
209
210 char firsttwo[2];
211 strncpy(firsttwo,fp->path,2);
212
213 if(sscanf(firsttwo, "%c:", &driveletter) == 1){
214 strncpy(fp->drive,fp->path,2);
215 fp->drive[0]=tolower(fp->drive[0]);
216 strcpy(fp->path, fp->path+2);
217 }else{
218 E("WHY HERE?");
219 }
220 }else{
221 strcpy(fp->drive,"");
222 }
223 X(fp->drive);
224 }
225 #endif
226
227 void ospath_cleanup(struct FilePath *fp){
228 char *pBuff;
229 char path[PATHMAX];
230 char *p;
231 struct FilePath *home;
232 struct FilePath *workingPath;
233 struct FilePath *parent;
234
235 // compress the path, and resolve ~
236 int startslash = (strlen(fp->path) > 0 && fp->path[0] == PATH_SEPARATOR_CHAR);
237 int endslash = (strlen(fp->path) > 1 && fp->path[strlen(fp->path) - 1] == PATH_SEPARATOR_CHAR);
238
239 //fprintf(stderr,"FS ON START = %d\n",startslash);
240 //fprintf(stderr,"FS ON END = %d\n",endslash);
241 //fprintf(stderr,"FIRST CHAR = %c\n",fp->path[0]);
242
243 home = ospath_gethomepath();
244
245 // create a copy of fp->path.
246 strcpy(path, fp->path);
247
248 // reset fp->path as required.
249 strcpy(fp->path, (startslash ? PATH_SEPARATOR_STR : ""));
250
251 //X(fp->path);
252
253 // split path into it tokens, using strtok which is NOT reentrant
254 // so be careful!
255
256 for(p = strtok(path, PATH_SEPARATOR_STR);
257 p!=NULL;
258 p = strtok(NULL,PATH_SEPARATOR_STR)
259 ){
260 //X(p);
261 if(strcmp(p, "~")==0){
262
263 if(p == path){ // check that the ~ is the first character in the path
264 if(ospath_isvalid(home)){
265 ospath_copy(fp,home);
266 continue;
267 }else{
268 E("HOME does not resolve to valid path");
269 }
270 }else{
271 E("A tilde (~) present as a component in a file path must be at the start!");
272 }
273 }else if(strcmp(p, ".") == 0){
274
275 if(p==path){// start of path:
276 M("EXPANDING LEADING '.' IN PATH");
277 // get current working directory
278 pBuff = (char *)getcwd(NULL, 0);
279 //X(pBuff);
280
281 // create new path with resolved working directory
282 workingPath = ospath_new_noclean(pBuff != NULL ? pBuff : ".");
283
284 if(pBuff == NULL){
285 E("Unable to resolve current working directory");
286 }else{
287 FREE(pBuff);
288 }
289
290 ospath_copy(fp,workingPath);
291 FREE(workingPath);
292 continue;
293 }else{// later in the path: just skip it
294 M("SKIPPING '.' IN PATH");
295 continue;
296 }
297
298 }else if(strcmp(p, "..") == 0){
299 M("GOING TO PARENT");
300 parent = ospath_getparent(fp);
301 if(ospath_isvalid(parent)){
302 ospath_copy(fp,parent);
303 }
304 FREE(parent);
305 continue;
306 }
307
308 // add a separator if we've already got some stuff
309 if(
310 strlen(fp->path) > 0
311 && fp->path[strlen(fp->path) - 1] != PATH_SEPARATOR_CHAR
312 ){
313 strcat(fp->path,PATH_SEPARATOR_STR);
314 }
315
316 // add the present path component
317 strcat(fp->path, p);
318 }
319
320 // put / on end as required, according to what the starting path had
321 if(endslash && (strlen(fp->path) > 0 ? (fp->path[strlen(fp->path) - 1] != PATH_SEPARATOR_CHAR) : 1))
322 {
323 strcat(fp->path, PATH_SEPARATOR_STR);
324 }
325
326 FREE(parent);
327 FREE(workingPath);
328 FREE(home);
329 }
330
331
332 int ospath_isvalid(struct FilePath *fp){
333 return strlen(fp->path) > 0 ? 1 : 0;
334 }
335
336
337 char *ospath_str(struct FilePath *fp){
338 char *s;
339 #ifdef WINPATHS
340 s = CALLOC(strlen(fp->drive)+strlen(fp->path),sizeof(char));
341 strcpy(s,fp->drive);
342 strcat(s,fp->path);
343 #else
344 s = CALLOC(strlen(fp->path),sizeof(char));
345 strcpy(s,fp->path);
346 #endif
347 return s;
348 }
349
350 void ospath_fwrite(struct FilePath *fp, FILE *dest){
351 #ifdef WINPATHS
352 fprintf(dest,"%s%s",fp->drive,fp->path);
353 #else
354 fprintf(dest,"%s",fp->path);
355 #endif
356 }
357
358 unsigned ospath_length(struct FilePath *fp){
359 #ifdef WINPATHS
360 // we've already validated this path, so it's on to just add it up
361 // (unless someone has been tinkering with the internal structure here)
362 return (unsigned) (strlen(fp->drive) + strlen(fp->path));
363 #else
364 return (unsigned) (strlen(fp->path));
365 #endif
366 }
367
368 struct FilePath *ospath_getparent(struct FilePath *fp)
369 {
370 if(strlen(fp->path) == 0 || ospath_isroot(fp))
371 {
372 // return empty path.
373 return ospath_new("");
374 }
375
376 // reverse find a / ignoring the end / if it exists.
377 int length = strlen(fp->path);
378 int offset = (
379 fp->path[length - 1] == PATH_SEPARATOR_CHAR
380 && length - 2 > 0
381 ) ? length - 2 : length ;
382 char *pos = strrchr(fp->path,PATH_SEPARATOR_CHAR);
383
384 // create new path object given position of find / and return it.
385 if(pos != fp->path+length)
386 {
387 char temp[PATHMAX];
388 #ifdef WINPATHS
389 strcpy(temp,fp->drive);
390 #endif
391 strncat(temp,fp->path,(pos-fp->path)+1);
392 return ospath_new_noclean(temp);
393 }else{
394 // not parent path avaliable, return an empty path.
395 return ospath_new("");
396 }
397 }
398
399 struct FilePath *ospath_getparentatdepthn(struct FilePath *fp, unsigned depth)
400 {
401 if(
402 !ospath_isvalid(fp)
403 || depth >= ospath_depth(fp)
404 ){
405 return fp;
406 }
407
408 // create FilePath object to parent object at depth N relative to this
409 // path object.
410 int startslash = (strlen(fp->path) > 0 && fp->path[0] == PATH_SEPARATOR_CHAR);
411
412 // create a copy of fp->path.
413 char path[PATHMAX];
414 strcpy(path, fp->path);
415
416 // reset fp->path as required.
417 char *temp = startslash ? PATH_SEPARATOR_STR : "";
418
419 // split path into it tokens.
420 char *p = strtok(path, PATH_SEPARATOR_STR);
421
422 while(p && depth > 0)
423 {
424 if(strlen(temp) > 0 && temp[strlen(temp) - 1] != PATH_SEPARATOR_CHAR)
425 {
426 temp += PATH_SEPARATOR_CHAR;
427 }
428
429 strcat(temp,p);
430 --depth;
431
432 p = strtok(NULL, PATH_SEPARATOR_STR);
433 }
434
435 // put / on end as required
436 if(strlen(temp) > 0 ? (temp[strlen(temp) - 1] != PATH_SEPARATOR_CHAR) : 1)
437 {
438 temp += PATH_SEPARATOR_CHAR;
439 }
440
441 #ifdef WINPATHS
442 char temp2[PATHMAX];
443 strcpy(temp2,fp->drive);
444 strcat(temp2,temp);
445 return ospath_new_noclean(temp2);
446 #else
447 return ospath_new_noclean(temp);
448 #endif
449 }
450
451 char *ospath_getbasefilename(struct FilePath *fp){
452 char *temp;
453
454 if(strlen(fp->path) == 0){
455 // return empty name.
456 return "";
457 }
458
459 // reverse find a / ignoring the end / if it exists.
460 unsigned length = strlen(fp->path);
461 unsigned offset = (
462 fp->path[length - 1] == PATH_SEPARATOR_CHAR
463 && length - 2 > 0
464 ) ? length - 2
465 : length;
466
467 char *pos = strrchr(fp->path, PATH_SEPARATOR_CHAR); /* OFFSET! */
468
469 // extract filename given position of find / and return it.
470 if(pos != fp->path + length){
471 int length1 = length - ((pos - fp->path) + 1) - (offset != length ? 1 : 0);
472 temp = CALLOC(length1,sizeof(char));
473
474 strncpy(temp, pos + 1, length1);
475 return temp;
476 }else{
477 temp = CALLOC(length,sizeof(char));
478 strncpy(temp, fp->path, length);
479 return temp;
480 }
481 }
482
483 char *ospath_getbasefiletitle(struct FilePath *fp){
484 if(!ospath_isvalid(fp)){
485 return NULL;
486 }
487
488 char *temp = ospath_getbasefilename(fp);
489 char *pos = strrchr(temp,'.');
490
491 if(pos != NULL){
492 // remove extension.
493 *pos = '\0';
494 }
495
496 return temp;
497 }
498
499 char *ospath_getbasefileextension(struct FilePath *fp){
500 if(!ospath_isvalid(fp)){
501 return NULL;
502 }
503
504 char *temp = ospath_getbasefilename(fp);
505 char *temp2;
506
507 // make sure there is no / on the end.
508 if(temp[strlen(temp) - 1] == PATH_SEPARATOR_CHAR){
509 temp[strlen(temp)-1] = '\0';
510 }
511
512 char *pos = strrchr(temp,'.');
513
514 if(pos != NULL)
515 {
516 // extract extension.
517 int len1 = temp + strlen(temp) - pos;
518 temp2 = CALLOC(len1, sizeof(char));
519 strncpy(temp2, pos, len1);
520 }else{
521 // no extension
522 temp2 = NULL;
523 }
524 FREE(temp);
525 return temp2;
526 }
527
528 int ospath_isroot(struct FilePath *fp)
529 {
530 if(!ospath_isvalid(fp))
531 {
532 return 0;
533 }
534
535 return fp->path == PATH_SEPARATOR_STR ? 1 : 0;
536 }
537
538 unsigned ospath_depth(struct FilePath *fp){
539 unsigned length;
540 unsigned depth;
541 unsigned i;
542
543 length = strlen(fp->path);
544 depth = 0;
545
546 for(i = 0; i < length; i++){
547 if(fp->path[i] == PATH_SEPARATOR_CHAR){
548 ++depth;
549 }
550 }
551
552 if(
553 depth > 0
554 && length > 0
555 && fp->path[length - 1] == PATH_SEPARATOR_CHAR
556 ){
557 // PATH_SEPARATOR_CHAR on the end, reduce count by 1
558 --depth;
559 }
560
561 return depth;
562 }
563
564 struct FilePath *ospath_root(struct FilePath *fp){
565 #ifdef WINPATHS
566 char *temp;
567 struct FilePath *r;
568 if(strlen(fp->drive)){
569 temp = CALLOC(strlen(fp->drive)+1, sizeof(char));
570 strcpy(temp,fp->drive);
571 strcat(temp,PATH_SEPARATOR_STR);
572 r = ospath_new(temp);
573 FREE(temp);
574 }else{
575 r = ospath_new(fp->drive);
576 }
577 return r;
578 #else
579 return ospath_new(PATH_SEPARATOR_STR);
580 #endif
581 }
582
583 int ospath_cmp(struct FilePath *fp1, struct FilePath *fp2)
584 {
585 if(!ospath_isvalid(fp1)){
586 if(!ospath_isvalid(fp2)){
587 return 0;
588 }else{
589 return -1;
590 }
591 }else if(!ospath_isvalid(fp2)){
592 return 1;
593 }
594
595 // now, both are valid...
596 //M("BOTH ARE VALID");
597
598 char temp[2][PATHMAX];
599 #ifdef WINPATHS
600 X(fp1->drive);
601 strcpy(temp[0],fp1->drive);
602 X(temp[0]);
603 X(fp1->path);
604 strcat(temp[0],fp1->path);
605 X(temp[0]);
606 strcpy(temp[1],fp2->drive);
607 strcat(temp[1],fp2->path);
608 #else
609 strcpy(temp[0], fp1->path);
610 strcpy(temp[1], fp2->path);
611 #endif
612
613 // we will count two paths that different only in a trailing slash to be the *same*
614 // so we add trailing slashes to both now:
615 if(temp[0][strlen(temp[0]) - 1] != PATH_SEPARATOR_CHAR){
616 strcat(temp[0],PATH_SEPARATOR_STR);
617 }
618
619 if(temp[1][strlen(temp[1]) - 1] != PATH_SEPARATOR_CHAR){
620 strcat(temp[1],PATH_SEPARATOR_STR);
621 }
622
623 X(temp[0]);
624 X(temp[1]);
625
626 return strcmp(temp[0],temp[1]);
627 }
628
629 struct FilePath *ospath_concat(struct FilePath *fp1, struct FilePath *fp2){
630
631 struct FilePath *fp;
632 fp = MALLOC(sizeof(struct FilePath));
633
634 if(!ospath_isvalid(fp1)){
635 if(ospath_isvalid(fp2)){
636 ospath_copy(fp2,fp);
637 }else{
638 // both invalid
639 ospath_copy(fp1,fp);
640 }
641 return fp;
642 }
643
644 ospath_copy(fp1,fp);
645
646 if(!ospath_isvalid(fp2)){
647 return fp;
648 }
649
650 // not just a copy of one or the other...
651 FREE(fp);
652
653 // now, both paths are valid...
654
655 char *temp[2];
656 #ifdef WINPATHS
657 temp[0] = CALLOC(strlen(fp1->drive)+strlen(fp1->path), sizeof(char));
658 strcpy(temp[0],fp1->drive);
659 strcat(temp[0],fp1->path);
660 #else
661 temp[0] = CALLOC(strlen(fp1->path), sizeof(char));
662 strcpy(temp[0], fp1->path);
663 #endif
664 temp[1] = CALLOC(strlen(fp2->path), sizeof(char));
665 strcpy(temp[1], fp2->path);
666
667 // make sure temp has a / on the end.
668 if(temp[0][strlen(temp[0]) - 1] != PATH_SEPARATOR_CHAR)
669 {
670 temp[0] += PATH_SEPARATOR_CHAR;
671 }
672
673 // make sure rhs path has NOT got a / at the start.
674 if(temp[1][0] == PATH_SEPARATOR_CHAR){
675 FREE(temp[0]);
676 FREE(temp[1]);
677 return NULL;
678 }
679
680 // create a new path object with the two path strings appended together.
681 char *temp2;
682 temp2 = CALLOC(strlen(temp[0])+strlen(temp[1]), sizeof(char));
683 strcpy(temp2,temp[0]);
684 strcat(temp2,temp[1]);
685 struct FilePath *r;
686 r = ospath_new_noclean(temp2);
687 FREE(temp2);
688 FREE(temp[0]);
689 FREE(temp[1]);
690 return r;
691 }
692
693 void ospath_append(struct FilePath *fp, struct FilePath *fp1){
694 char *p;
695
696 if(!ospath_isvalid(fp1)){
697 M("fp1 invalid");
698 return;
699 }
700
701 if(!ospath_isvalid(fp) && ospath_isvalid(fp1)){
702 // set this object to be the same as the rhs
703 M("fp invalid");
704 ospath_copy(fp,fp1);
705 return;
706 }
707
708 X(fp->path);
709 X(fp1->path);
710
711 // both paths are valid...
712 char *temp[2];
713 temp[0] = CALLOC(1+strlen(fp->path), sizeof(char));
714 strcpy(temp[0], fp->path);
715 temp[1] = CALLOC(strlen(fp1->path), sizeof(char));
716 strcpy(temp[1], fp1->path);
717
718 X(temp[0]);
719 X(temp[1]);
720
721 // make sure temp has a / on the end.
722 if(temp[0][strlen(temp[0]) - 1] != PATH_SEPARATOR_CHAR)
723 {
724 strcat(temp[0],PATH_SEPARATOR_STR);
725 }
726
727 // make sure rhs path has NOT got a / at the start.
728 if(temp[1][0] == PATH_SEPARATOR_CHAR){
729 for(p=temp[1]+1; *p != '\0'; ++p){
730 *(p-1)=*p;
731 }
732 *(p-1)='\0';
733 }
734
735 X(temp[0]);
736 X(temp[1]);
737
738 // create new path string.
739 strcpy(fp->path,temp[0]);
740 strcat(fp->path,temp[1]);
741
742 FREE(temp[0]);
743 FREE(temp[1]);
744 }
745
746 void ospath_copy(struct FilePath *dest, struct FilePath *src){
747 strcpy(dest->path,src->path);
748 #ifdef WINPATHS
749 strcpy(dest->drive,src->drive);
750 #endif
751 }
752
753 void ospath_debug(struct FilePath *fp, char *label){
754 fprintf(stderr,"%s\n---------------------\n",label);
755 fprintf(stderr,"PATH = %s\n",fp->path);
756 #ifdef WINPATHS
757 fprintf(stderr,"DRIVE = %s\n",fp->drive);
758 #endif
759 fprintf(stderr,"\n");
760 }
761
762 /*--------------------------------
763 some simple test routines...
764 */
765 #ifdef TEST
766 #include <assert.h>
767
768 int main(void){
769 struct FilePath *fp1, *fp2, *fp3, *fp4;
770
771 fp1 = ospath_new_from_posix("models/johnpye/extfn/extfntest");
772 D(fp1);
773 fp2 = ospath_new("models\\johnpye\\extfn\\extfntest");
774 D(fp2);
775 assert(ospath_cmp(fp1,fp2)==0);
776 M("Passed 'new_from_posix' test");
777
778 FREE(fp1); FREE(fp2);
779
780 //------------------------
781 fp1 = ospath_new(".\\src\\.\\images\\..\\\\movies\\");
782 fp2 = ospath_new(".\\src\\movies");
783
784 D(fp1);
785 D(fp2);
786
787 assert(ospath_cmp(fp1,fp2)==0);
788 M("Passed 'cleanup' test");
789
790 FREE(fp2);
791
792 fp2 = ospath_new(".\\src\\movies\\kubrick");
793 fp3 = ospath_getparent(fp2);
794
795 assert(ospath_cmp(fp1,fp3)==0);
796 M("Passed 'parent' test");
797
798 FREE(fp1); FREE(fp2); FREE(fp3);
799 //------------------------
800
801 fp2 = ospath_new("\\home\\john");
802 fp3 = ospath_new("where\\mojo");
803
804 D(fp2);
805 D(fp3);
806
807 ospath_append(fp2,fp3);
808
809 fp4 = ospath_new("\\home\\john\\where\\mojo\\");
810
811 D(fp2);
812 assert(ospath_cmp(fp2,fp4)==0);
813 M("Passed 'append' test");
814
815 ospath_append(fp2,fp3);
816 fp4 = ospath_root(fp2);
817 D(fp2);
818 D(fp4);
819
820 assert(ospath_cmp(fp2,fp4)==0);
821 M("Passed 'concat' test");
822
823 D(fp2);
824
825 FREE(fp2);
826
827 fp2 = ospath_new("~/.");
828
829 assert(ospath_cmp(fp1,fp2)==0);
830
831 D(fp2);
832
833 FREE(fp1);
834 FREE(fp2);
835
836 fp1 = ospath_new("/usr/local/include");
837 fp2 = ospath_new("/usr/include/../local/include");
838
839 D(fp1);
840 D(fp2);
841
842
843 }
844
845 #endif

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