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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 535 - (hide annotations) (download) (as text)
Tue Apr 25 14:55:48 2006 UTC (13 years, 11 months 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 johnpye 534 #include <stdio.h>
2 johnpye 535 #include <ctype.h>
3 johnpye 534
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 johnpye 535 #define V(VAR) fprintf(stderr,"%s:%d: (%s) %s=%d\n",__FILE__,__LINE__,__FUNCTION__,#VAR,VAR)
28 johnpye 534 #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 johnpye 535 2. Resolve a leading tilde (~) to the current user's HOME path
42 johnpye 534
43 johnpye 535 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 johnpye 534 */
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 johnpye 535 X(fp->path);
85 johnpye 534 ospath_extractdriveletter(fp);
86     #endif
87    
88     ospath_cleanup(fp);
89    
90     return fp;
91     }
92    
93     /**
94 johnpye 535 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 johnpye 534 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 johnpye 535 X(fp->path);
173 johnpye 534 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 johnpye 535 X(fp->path);
205 johnpye 534 // 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 johnpye 535 if(sscanf(firsttwo, "%c:", &driveletter) == 1){
214 johnpye 534 strncpy(fp->drive,fp->path,2);
215 johnpye 535 fp->drive[0]=tolower(fp->drive[0]);
216 johnpye 534 strcpy(fp->path, fp->path+2);
217 johnpye 535 }else{
218     E("WHY HERE?");
219 johnpye 534 }
220 johnpye 535 }else{
221     strcpy(fp->drive,"");
222 johnpye 534 }
223 johnpye 535 X(fp->drive);
224 johnpye 534 }
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 johnpye 535 //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 johnpye 534
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 johnpye 535 //X(fp->path);
252 johnpye 534
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 johnpye 535 //X(p);
261 johnpye 534 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 johnpye 535 //X(pBuff);
280 johnpye 534
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 johnpye 535 //M("BOTH ARE VALID");
597 johnpye 534
598 johnpye 535 char temp[2][PATHMAX];
599 johnpye 534 #ifdef WINPATHS
600 johnpye 535 X(fp1->drive);
601 johnpye 534 strcpy(temp[0],fp1->drive);
602 johnpye 535 X(temp[0]);
603     X(fp1->path);
604 johnpye 534 strcat(temp[0],fp1->path);
605 johnpye 535 X(temp[0]);
606 johnpye 534 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 johnpye 535 X(temp[0]);
624     X(temp[1]);
625 johnpye 534
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 johnpye 535 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 johnpye 534 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 johnpye 535 FREE(fp1); FREE(fp2); FREE(fp3);
799     //------------------------
800 johnpye 534
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 johnpye 535 fp4 = ospath_new("\\home\\john\\where\\mojo\\");
810 johnpye 534
811     D(fp2);
812 johnpye 535 assert(ospath_cmp(fp2,fp4)==0);
813     M("Passed 'append' test");
814 johnpye 534
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 johnpye 535
823 johnpye 534 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 johnpye 535
843 johnpye 534 }
844    
845     #endif

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