Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/tools/jam/src/pathmac.c @ 29

Last change on this file since 29 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 6.1 KB
Line 
1/*
2 * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
3 *
4 * This file is part of Jam - see jam.c for Copyright information.
5 */
6
7/*  This file is ALSO:
8 *  Copyright 2001-2004 David Abrahams.
9 *  Distributed under the Boost Software License, Version 1.0.
10 *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
11 */
12
13# include "jam.h"
14# include "pathsys.h"
15
16# ifdef OS_MAC
17
18# define DELIM ':'
19
20/*
21 * pathunix.c - manipulate file names on UNIX, NT, OS2
22 *
23 * External routines:
24 *
25 *      path_parse() - split a file name into dir/base/suffix/member
26 *      path_build() - build a filename given dir/base/suffix/member
27 *      path_parent() - make a PATHNAME point to its parent dir
28 *
29 * File_parse() and path_build() just manipuate a string and a structure;
30 * they do not make system calls.
31 *
32 * 04/08/94 (seiwald) - Coherent/386 support added.
33 * 12/26/93 (seiwald) - handle dir/.suffix properly in path_build()
34 * 12/19/94 (mikem) - solaris string table insanity support
35 * 12/21/94 (wingerd) Use backslashes for pathnames - the NT way.
36 * 02/14/95 (seiwald) - parse and build /xxx properly
37 * 02/23/95 (wingerd) Compilers on NT can handle "/" in pathnames, so we
38 *                    should expect hdr searches to come up with strings
39 *                    like "thing/thing.h". So we need to test for "/" as
40 *                    well as "\" when parsing pathnames.
41 * 03/16/95 (seiwald) - fixed accursed typo on line 69.
42 * 05/03/96 (seiwald) - split from filent.c, fileunix.c
43 * 12/20/96 (seiwald) - when looking for the rightmost . in a file name,
44 *                    don't include the archive member name.
45 * 01/10/01 (seiwald) - path_parse now strips the trailing : from the
46 *                      directory name, unless the directory name is all
47 *                      :'s, so that $(d:P) works.
48 */
49
50/*
51 * path_parse() - split a file name into dir/base/suffix/member
52 */
53
54void
55path_parse( 
56        char    *file,
57        PATHNAME *f )
58{
59        char *p, *q;
60        char *end;
61       
62        memset( (char *)f, 0, sizeof( *f ) );
63
64        /* Look for <grist> */
65
66        if( file[0] == '<' && ( p = strchr( file, '>' ) ) )
67        {
68            f->f_grist.ptr = file;
69            f->f_grist.len = p - file;
70            file = p + 1;
71        }
72
73        /* Look for dir: */
74
75        if( p = strrchr( file, DELIM ) )
76        {
77            f->f_dir.ptr = file;
78            f->f_dir.len = p - file;
79            file = p + 1;
80
81            /* All :'s? Include last : as part of directory name */
82
83            while( p > f->f_dir.ptr && *--p == DELIM )
84                ;
85           
86            if( p == f->f_dir.ptr )
87            f->f_dir.len++;
88        }
89
90        end = file + strlen( file );
91
92        /* Look for (member) */
93
94        if( ( p = strchr( file, '(' ) ) && end[-1] == ')' )
95        {
96            f->f_member.ptr = p + 1;
97            f->f_member.len = end - p - 2;
98            end = p;
99        } 
100
101        /* Look for .suffix */
102        /* This would be memrchr() */
103
104        p = 0;
105        q = file;
106
107        while( q = memchr( q, '.', end - q ) )
108            p = q++;
109
110        if( p )
111        {
112            f->f_suffix.ptr = p;
113            f->f_suffix.len = end - p;
114            end = p;
115        }
116
117        /* Leaves base */
118
119        f->f_base.ptr = file;
120        f->f_base.len = end - file;
121}
122
123/*
124 * path_build() - build a filename given dir/base/suffix/member
125 */
126 
127# define DIR_EMPTY      0       /* "" */
128# define DIR_DOT        1       /* : */
129# define DIR_DOTDOT     2       /* :: */
130# define DIR_ABS        3       /* dira:dirb: */
131# define DIR_REL        4       /* :dira:dirb: */
132
133# define G_DIR          0       /* take dir */
134# define G_ROOT         1       /* take root */
135# define G_CAT          2       /* prepend root to dir */
136# define G_DTDR         3       /* :: of rel dir */
137# define G_DDDD         4       /* make it ::: (../..) */
138# define G_MT           5       /* leave it empty */
139
140char grid[5][5] = {
141/*              EMPTY   DOT     DOTDOT  ABS     REL */
142/* EMPTY */   { G_MT,   G_DIR,  G_DIR,  G_DIR,  G_DIR },
143/* DOT */     { G_ROOT, G_DIR,  G_DIR,  G_DIR,  G_DIR },
144/* DOTDOT */  { G_ROOT, G_ROOT, G_DDDD, G_DIR,  G_DTDR },
145/* ABS */     { G_ROOT, G_ROOT, G_ROOT, G_DIR,  G_CAT },
146/* REL */     { G_ROOT, G_ROOT, G_ROOT, G_DIR,  G_CAT }
147} ;
148
149static int
150file_flags( 
151        char    *ptr,
152        int     len )
153{
154        if( !len )
155            return DIR_EMPTY;
156        if( len == 1 && ptr[0] == DELIM )
157            return DIR_DOT;
158        if( len == 2 && ptr[0] == DELIM && ptr[1] == DELIM )
159            return DIR_DOTDOT;
160        if( ptr[0] == DELIM )
161            return DIR_REL;
162        return DIR_ABS;
163}
164
165void
166path_build(
167        PATHNAME *f,
168        string* file,
169        int     binding )
170{
171    int dflag, rflag, act;
172
173    file_build1( f, file );
174       
175    /* Combine root & directory, according to the grid. */
176       
177    dflag = file_flags( f->f_dir.ptr, f->f_dir.len );
178    rflag = file_flags( f->f_root.ptr, f->f_root.len );
179       
180    switch( act = grid[ rflag ][ dflag ] )
181    {
182    case G_DTDR:
183        {
184            /* :: of rel dir */
185            string_push_back( file, DELIM );
186        }
187        /* fall through */
188               
189    case G_DIR:         
190        /* take dir */
191        string_append_range( file, f->f_dir.ptr, f->f_dir.ptr + f->f_dir.len  );
192        break;
193               
194    case G_ROOT:       
195        /* take root */
196        string_append_range( file, f->f_root.ptr, f->f_root.ptr + f->f_root.len  );
197        break;
198           
199    case G_CAT: 
200        /* prepend root to dir */
201        string_append_range( file, f->f_root.ptr, f->f_root.ptr + f->f_root.len  );
202        if( file->value[file->size - 1] == DELIM )
203            string_pop_back( file );
204        string_append_range( file, f->f_dir.ptr, f->f_dir.ptr + f->f_dir.len  );
205        break;
206       
207    case G_DDDD:       
208        /* make it ::: (../..) */
209        string_append( file, ":::" );
210        break;
211    }
212
213    /* Put : between dir and file (if none already) */
214       
215    if( act != G_MT && 
216        file->value[file->size - 1] != DELIM && 
217        ( f->f_base.len || f->f_suffix.len ) )
218    {
219        string_push_back( file, DELIM );
220    }
221
222    if( f->f_base.len )
223    {
224        string_append_range( file, f->f_base.ptr, f->f_base.ptr + f->f_base.len  );
225    }
226
227    if( f->f_suffix.len )
228    {
229        string_append_range( file, f->f_suffix.ptr, f->f_suffix.ptr + f->f_suffix.len  );
230    }
231
232    if( f->f_member.len )
233    {
234        string_push_back( file, '(' );
235        string_append_range( file, f->f_member.ptr, f->f_member.ptr + f->f_member.len  );
236        string_push_back( file, ')' );
237    }
238       
239    if( DEBUG_SEARCH )
240        printf(" -> '%s'\n", file->value);
241}
242
243/*
244 *      path_parent() - make a PATHNAME point to its parent dir
245 */
246
247void
248path_parent( PATHNAME *f )
249{
250        /* just set everything else to nothing */
251
252        f->f_base.ptr =
253        f->f_suffix.ptr =
254        f->f_member.ptr = "";
255
256        f->f_base.len = 
257        f->f_suffix.len = 
258        f->f_member.len = 0;
259}
260
261# endif /* OS_MAC */
Note: See TracBrowser for help on using the repository browser.