]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/tools/build/src/engine/pathsys.c
2 * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
4 * This file is part of Jam - see jam.c for Copyright information.
8 * Copyright 2001-2004 David Abrahams.
9 * Copyright 2005 Rene Rivera.
10 * Distributed under the Boost Software License, Version 1.0.
11 * (See accompanying file LICENSE_1_0.txt or copy at
12 * http://www.boost.org/LICENSE_1_0.txt)
16 * pathsys.c - platform independent path manipulation support
19 * path_build() - build a filename given dir/base/suffix/member
20 * path_parent() - make a PATHNAME point to its parent dir
21 * path_parse() - split a file name into dir/base/suffix/member
22 * path_tmpdir() - returns the system dependent temporary folder path
23 * path_tmpfile() - returns a new temporary path
24 * path_tmpnam() - returns a new temporary name
26 * File_parse() and path_build() just manipulate a string and a structure;
27 * they do not make system calls.
39 /* Internal OS specific implementation details - have names ending with an
40 * underscore and are expected to be implemented in an OS specific pathXXX.c
43 unsigned long path_get_process_id_( void );
44 void path_get_temp_path_( string
* buffer
);
45 int path_translate_to_os_( char const * f
, string
* file
);
49 * path_parse() - split a file name into dir/base/suffix/member
52 void path_parse( char const * file
, PATHNAME
* f
)
58 memset( (char *)f
, 0, sizeof( *f
) );
60 /* Look for '<grist>'. */
62 if ( ( file
[ 0 ] == '<' ) && ( p
= strchr( file
, '>' ) ) )
64 f
->f_grist
.ptr
= file
;
65 f
->f_grist
.len
= p
- file
;
69 /* Look for 'dir/'. */
71 p
= strrchr( file
, '/' );
73 #if PATH_DELIM == '\\'
74 /* On NT, look for dir\ as well */
76 char * const p1
= strrchr( p
? p
+ 1 : file
, '\\' );
84 f
->f_dir
.len
= p
- file
;
86 /* Special case for / - dirname is /, not "" */
90 #if PATH_DELIM == '\\'
91 /* Special case for D:/ - dirname is D:/, not "D:" */
92 if ( f
->f_dir
.len
== 2 && file
[ 1 ] == ':' )
99 end
= file
+ strlen( file
);
101 /* Look for '(member)'. */
102 if ( ( p
= strchr( file
, '(' ) ) && ( end
[ -1 ] == ')' ) )
104 f
->f_member
.ptr
= p
+ 1;
105 f
->f_member
.len
= end
- p
- 2;
109 /* Look for '.suffix'. This would be memrchr(). */
111 for ( q
= file
; ( q
= (char *)memchr( q
, '.', end
- q
) ); ++q
)
116 f
->f_suffix
.len
= end
- p
;
121 f
->f_base
.ptr
= file
;
122 f
->f_base
.len
= end
- file
;
127 * is_path_delim() - true iff c is a path delimiter
130 static int is_path_delim( char const c
)
132 return c
== PATH_DELIM
133 #if PATH_DELIM == '\\'
141 * as_path_delim() - convert c to a path delimiter if it is not one already
144 static char as_path_delim( char const c
)
146 return is_path_delim( c
) ? c
: PATH_DELIM
;
151 * path_build() - build a filename given dir/base/suffix/member
153 * To avoid changing slash direction on NT when reconstituting paths, instead of
154 * unconditionally appending PATH_DELIM we check the past-the-end character of
155 * the previous path element. If it is a path delimiter, we append that, and
156 * only append PATH_DELIM as a last resort. This heuristic is based on the fact
157 * that PATHNAME objects are usually the result of calling path_parse, which
158 * leaves the original slashes in the past-the-end position. Correctness depends
159 * on the assumption that all strings are zero terminated, so a past-the-end
160 * character will always be available.
162 * As an attendant patch, we had to ensure that backslashes are used explicitly
166 void path_build( PATHNAME
* f
, string
* file
)
171 file_build1( f
, file
);
173 /* Do not prepend root if it is '.' or the directory is rooted. */
174 check_f
= (f
->f_root
.len
175 && !( f
->f_root
.len
== 1 && f
->f_root
.ptr
[ 0 ] == '.')
176 && !( f
->f_dir
.len
&& f
->f_dir
.ptr
[ 0 ] == '/' ));
177 #if PATH_DELIM == '\\'
179 && !( f
->f_dir
.len
&& f
->f_dir
.ptr
[ 0 ] == '\\' )
180 && !( f
->f_dir
.len
&& f
->f_dir
.ptr
[ 1 ] == ':' ));
184 string_append_range( file
, f
->f_root
.ptr
, f
->f_root
.ptr
+ f
->f_root
.len
186 /* If 'root' already ends with a path delimeter, do not add another one.
188 if ( !is_path_delim( f
->f_root
.ptr
[ f
->f_root
.len
- 1 ] ) )
189 string_push_back( file
, as_path_delim( f
->f_root
.ptr
[ f
->f_root
.len
194 string_append_range( file
, f
->f_dir
.ptr
, f
->f_dir
.ptr
+ f
->f_dir
.len
);
196 /* Put path separator between dir and file. */
197 /* Special case for root dir: do not add another path separator. */
198 check_f_pos
= (f
->f_dir
.len
&& ( f
->f_base
.len
|| f
->f_suffix
.len
));
199 #if PATH_DELIM == '\\'
200 check_f_pos
= (check_f_pos
&& !( f
->f_dir
.len
== 3 && f
->f_dir
.ptr
[ 1 ] == ':' ));
202 check_f_pos
= (check_f_pos
&& !( f
->f_dir
.len
== 1 && is_path_delim( f
->f_dir
.ptr
[ 0 ])));
204 string_push_back( file
, as_path_delim( f
->f_dir
.ptr
[ f
->f_dir
.len
] ) );
207 string_append_range( file
, f
->f_base
.ptr
, f
->f_base
.ptr
+ f
->f_base
.len
210 if ( f
->f_suffix
.len
)
211 string_append_range( file
, f
->f_suffix
.ptr
, f
->f_suffix
.ptr
+
214 if ( f
->f_member
.len
)
216 string_push_back( file
, '(' );
217 string_append_range( file
, f
->f_member
.ptr
, f
->f_member
.ptr
+
219 string_push_back( file
, ')' );
225 * path_parent() - make a PATHNAME point to its parent dir
228 void path_parent( PATHNAME
* f
)
230 f
->f_base
.ptr
= f
->f_suffix
.ptr
= f
->f_member
.ptr
= "";
231 f
->f_base
.len
= f
->f_suffix
.len
= f
->f_member
.len
= 0;
236 * path_tmpdir() - returns the system dependent temporary folder path
238 * Returned value is stored inside a static buffer and should not be modified.
239 * Returned value does *not* include a trailing path separator.
242 string
const * path_tmpdir()
244 static string buffer
[ 1 ];
245 static int have_result
;
248 string_new( buffer
);
249 path_get_temp_path_( buffer
);
257 * path_tmpnam() - returns a new temporary name
260 OBJECT
* path_tmpnam( void )
262 char name_buffer
[ 64 ];
263 unsigned long const pid
= path_get_process_id_();
264 static unsigned long t
;
265 if ( !t
) t
= time( 0 ) & 0xffff;
267 sprintf( name_buffer
, "jam%lx%lx.000", pid
, t
);
268 return object_new( name_buffer
);
273 * path_tmpfile() - returns a new temporary path
276 OBJECT
* path_tmpfile( void )
281 string file_path
[ 1 ];
282 string_copy( file_path
, path_tmpdir()->value
);
283 string_push_back( file_path
, PATH_DELIM
);
284 tmpnam
= path_tmpnam();
285 string_append( file_path
, object_str( tmpnam
) );
286 object_free( tmpnam
);
287 result
= object_new( file_path
->value
);
288 string_free( file_path
);
295 * path_translate_to_os() - translate filename to OS-native path
299 int path_translate_to_os( char const * f
, string
* file
)
301 return path_translate_to_os_( f
, file
);