The Machine Perception Toolbox

[Introduction]- [News]- [Download]- [Screenshots]- [Manual (pdf)]- [Forums]- [API Reference]- [Repository ]

 

Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

pathmac.c

Go to the documentation of this file.
00001 /*
00002  * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
00003  *
00004  * This file is part of Jam - see jam.c for Copyright information.
00005  */
00006 
00007 /*  This file is ALSO:
00008  *  (C) Copyright David Abrahams 2001. Permission to copy, use,
00009  *  modify, sell and distribute this software is granted provided this
00010  *  copyright notice appears in all copies. This software is provided
00011  *  "as is" without express or implied warranty, and with no claim as
00012  *  to its suitability for any purpose.
00013  */
00014 
00015 # include "jam.h"
00016 # include "pathsys.h"
00017 
00018 # ifdef OS_MAC
00019 
00020 # define DELIM ':'
00021 
00022 /*
00023  * pathunix.c - manipulate file names on UNIX, NT, OS2
00024  *
00025  * External routines:
00026  *
00027  *      path_parse() - split a file name into dir/base/suffix/member
00028  *      path_build() - build a filename given dir/base/suffix/member
00029  *      path_parent() - make a PATHNAME point to its parent dir
00030  *
00031  * File_parse() and path_build() just manipuate a string and a structure;
00032  * they do not make system calls.
00033  *
00034  * 04/08/94 (seiwald) - Coherent/386 support added.
00035  * 12/26/93 (seiwald) - handle dir/.suffix properly in path_build()
00036  * 12/19/94 (mikem) - solaris string table insanity support
00037  * 12/21/94 (wingerd) Use backslashes for pathnames - the NT way.
00038  * 02/14/95 (seiwald) - parse and build /xxx properly
00039  * 02/23/95 (wingerd) Compilers on NT can handle "/" in pathnames, so we
00040  *                    should expect hdr searches to come up with strings
00041  *                    like "thing/thing.h". So we need to test for "/" as
00042  *                    well as "\" when parsing pathnames.
00043  * 03/16/95 (seiwald) - fixed accursed typo on line 69.
00044  * 05/03/96 (seiwald) - split from filent.c, fileunix.c
00045  * 12/20/96 (seiwald) - when looking for the rightmost . in a file name,
00046  *                    don't include the archive member name.
00047  * 01/10/01 (seiwald) - path_parse now strips the trailing : from the
00048  *                      directory name, unless the directory name is all
00049  *                      :'s, so that $(d:P) works.
00050  */
00051 
00052 /*
00053  * path_parse() - split a file name into dir/base/suffix/member
00054  */
00055 
00056 void
00057 path_parse( 
00058         char    *file,
00059         PATHNAME *f )
00060 {
00061         char *p, *q;
00062         char *end;
00063         
00064         memset( (char *)f, 0, sizeof( *f ) );
00065 
00066         /* Look for <grist> */
00067 
00068         if( file[0] == '<' && ( p = strchr( file, '>' ) ) )
00069         {
00070             f->f_grist.ptr = file;
00071             f->f_grist.len = p - file;
00072             file = p + 1;
00073         }
00074 
00075         /* Look for dir: */
00076 
00077         if( p = strrchr( file, DELIM ) )
00078         {
00079             f->f_dir.ptr = file;
00080             f->f_dir.len = p - file;
00081             file = p + 1;
00082 
00083             /* All :'s? Include last : as part of directory name */
00084 
00085             while( p > f->f_dir.ptr && *--p == DELIM )
00086                 ;
00087             
00088             if( p == f->f_dir.ptr )
00089             f->f_dir.len++;
00090         }
00091 
00092         end = file + strlen( file );
00093 
00094         /* Look for (member) */
00095 
00096         if( ( p = strchr( file, '(' ) ) && end[-1] == ')' )
00097         {
00098             f->f_member.ptr = p + 1;
00099             f->f_member.len = end - p - 2;
00100             end = p;
00101         } 
00102 
00103         /* Look for .suffix */
00104         /* This would be memrchr() */
00105 
00106         p = 0;
00107         q = file;
00108 
00109         while( q = memchr( q, '.', end - q ) )
00110             p = q++;
00111 
00112         if( p )
00113         {
00114             f->f_suffix.ptr = p;
00115             f->f_suffix.len = end - p;
00116             end = p;
00117         }
00118 
00119         /* Leaves base */
00120 
00121         f->f_base.ptr = file;
00122         f->f_base.len = end - file;
00123 }
00124 
00125 /*
00126  * path_build() - build a filename given dir/base/suffix/member
00127  */
00128  
00129 # define DIR_EMPTY      0       /* "" */
00130 # define DIR_DOT        1       /* : */
00131 # define DIR_DOTDOT     2       /* :: */
00132 # define DIR_ABS        3       /* dira:dirb: */
00133 # define DIR_REL        4       /* :dira:dirb: */
00134 
00135 # define G_DIR          0       /* take dir */
00136 # define G_ROOT         1       /* take root */
00137 # define G_CAT          2       /* prepend root to dir */
00138 # define G_DTDR         3       /* :: of rel dir */
00139 # define G_DDDD         4       /* make it ::: (../..) */
00140 # define G_MT           5       /* leave it empty */
00141 
00142 char grid[5][5] = {
00143 /*              EMPTY   DOT     DOTDOT  ABS     REL */
00144 /* EMPTY */   { G_MT,   G_DIR,  G_DIR,  G_DIR,  G_DIR },
00145 /* DOT */     { G_ROOT, G_DIR,  G_DIR,  G_DIR,  G_DIR },
00146 /* DOTDOT */  { G_ROOT, G_ROOT, G_DDDD, G_DIR,  G_DTDR },
00147 /* ABS */     { G_ROOT, G_ROOT, G_ROOT, G_DIR,  G_CAT },
00148 /* REL */     { G_ROOT, G_ROOT, G_ROOT, G_DIR,  G_CAT }
00149 } ;
00150 
00151 static int
00152 file_flags( 
00153         char    *ptr,
00154         int     len )
00155 {
00156         if( !len )
00157             return DIR_EMPTY;
00158         if( len == 1 && ptr[0] == DELIM )
00159             return DIR_DOT;
00160         if( len == 2 && ptr[0] == DELIM && ptr[1] == DELIM )
00161             return DIR_DOTDOT;
00162         if( ptr[0] == DELIM )
00163             return DIR_REL;
00164         return DIR_ABS;
00165 }
00166 
00167 void
00168 path_build(
00169         PATHNAME *f,
00170         string* file,
00171         int     binding )
00172 {
00173     int dflag, rflag, act;
00174 
00175     file_build1( f, file );
00176         
00177     /* Combine root & directory, according to the grid. */
00178         
00179     dflag = file_flags( f->f_dir.ptr, f->f_dir.len );
00180     rflag = file_flags( f->f_root.ptr, f->f_root.len );
00181         
00182     switch( act = grid[ rflag ][ dflag ] )
00183     {
00184     case G_DTDR:
00185         {
00186             /* :: of rel dir */
00187             string_push_back( file, DELIM );
00188         }
00189         /* fall through */
00190                 
00191     case G_DIR:         
00192         /* take dir */
00193         string_append_range( file, f->f_dir.ptr, f->f_dir.ptr + f->f_dir.len  );
00194         break;
00195                 
00196     case G_ROOT:        
00197         /* take root */
00198         string_append_range( file, f->f_root.ptr, f->f_root.ptr + f->f_root.len  );
00199         break;
00200             
00201     case G_CAT: 
00202         /* prepend root to dir */
00203         string_append_range( file, f->f_root.ptr, f->f_root.ptr + f->f_root.len  );
00204         if( file->value[file->size - 1] == DELIM )
00205             string_pop_back( file );
00206         string_append_range( file, f->f_dir.ptr, f->f_dir.ptr + f->f_dir.len  );
00207         break;
00208         
00209     case G_DDDD:        
00210         /* make it ::: (../..) */
00211         string_append( file, ":::" );
00212         break;
00213     }
00214 
00215     /* Put : between dir and file (if none already) */
00216         
00217     if( act != G_MT && 
00218         file->value[file->size - 1] != DELIM && 
00219         ( f->f_base.len || f->f_suffix.len ) )
00220     {
00221         string_push_back( file, DELIM );
00222     }
00223 
00224     if( f->f_base.len )
00225     {
00226         string_append_range( file, f->f_base.ptr, f->f_base.ptr + f->f_base.len  );
00227     }
00228 
00229     if( f->f_suffix.len )
00230     {
00231         string_append_range( file, f->f_suffix.ptr, f->f_suffix.ptr + f->f_suffix.len  );
00232     }
00233 
00234     if( f->f_member.len )
00235     {
00236         string_push_back( file, '(' );
00237         string_append_range( file, f->f_member.ptr, f->f_member.ptr + f->f_member.len  );
00238         string_push_back( file, ')' );
00239     }
00240         
00241     if( DEBUG_SEARCH )
00242         printf(" -> '%s'\n", file->value);
00243 }
00244 
00245 /*
00246  *      path_parent() - make a PATHNAME point to its parent dir
00247  */
00248 
00249 void
00250 path_parent( PATHNAME *f )
00251 {
00252         /* just set everything else to nothing */
00253 
00254         f->f_base.ptr =
00255         f->f_suffix.ptr =
00256         f->f_member.ptr = "";
00257 
00258         f->f_base.len = 
00259         f->f_suffix.len = 
00260         f->f_member.len = 0;
00261 }
00262 
00263 # endif /* OS_MAC */

Generated on Mon Nov 8 17:07:46 2004 for MPT by  doxygen 1.3.9.1