2 Copyright © 1995-2008, The AROS Development Team. All rights reserved.
8 #include "dos_intern.h"
12 /*****************************************************************************
15 #include <proto/dos.h>
17 AROS_LH3(BOOL
, AddPart
,
20 AROS_LHA(STRPTR
, dirname
, D1
),
21 AROS_LHA(CONST_STRPTR
, filename
, D2
),
22 AROS_LHA(ULONG
, size
, D3
),
25 struct DosLibrary
*, DOSBase
, 147, Dos
)
28 AddPart() will add a file, directory or other path name to a
29 directory path. It will take into account any pre-existing
30 separator characters (':','/').
32 If filename is a fully qualified path, then it will replace
33 the current value of dirname.
36 dirname - the path to add the new path to
37 filename - the path you wish added
38 size - The size of the dirname buffer (must NOT be 0)
41 Non-zero if everything succeeded, FALSE if the buffer would have
44 If the buffer would have overflowed, then dirname will not have
52 AddPart(buffer, "Work:", 80);
53 AddPart(buffer, "Programming/Include/exec", 80);
55 FPuts(Output(), buffer);
56 --> Work:Programming/Include/exec
58 AddPart(buffer, "/graphics", 80);
60 FPuts(Output(), buffer);
61 --> Work:Programming/Include/graphics
63 AddPart(buffer, "gfxmacros.h", 80);
64 FPuts(Output(), buffer);
65 --> Work:Programming/Include/graphics/gfxmacros.h
70 FilePart(), PathPart()
74 *****************************************************************************/
79 /* stegerg: a bit simple, but since the other code does not
80 work correctly. And then even AmigaOS AddPart()
81 does not seem to do things like eliminating
82 "dead" path components like:
84 "test/test2//test3" --> "test/test3"
86 It just makes sure that the path is correct
91 WORD mustaddslash
= 0;
93 stringpos
= strchr(filename
, ':');
96 if (stringpos
== (char *)filename
)
98 /* The first char of filename is a ':' */
100 /* Find dirname position to where we copy filename later */
102 stringpos
= strchr(dirname
, ':');
103 if (!stringpos
) stringpos
= dirname
;
107 /* Filename is a fully qualified path including
108 volume/device name -> replace dirname with filename */
115 /* filename did not contain ':' */
117 stringlen
= strlen(dirname
);
118 stringpos
= dirname
+ stringlen
;
120 /* Check if we must add a slash */
124 if ((stringpos
[-1] != ':') && (stringpos
[-1] != '/'))
129 /* Check if dirname buffer is big enough */
131 stringlen
= ((LONG
)(stringpos
- (char *)dirname
)) + strlen(filename
) + 1 + mustaddslash
;
132 if (stringlen
<= size
)
134 if (mustaddslash
) *stringpos
++ = '/';
135 strcpy(stringpos
, filename
);
145 /* stegerg: this is buggy, because in some places it accesses
146 chars in dirname behind the (initial) string in
147 there (after the 0 char). For example:
151 strcpy(buffer, "LOCALE:Catalogs");
152 AddPart(buffer, "deutsch", 256);
154 gives correct "LOCALE:Catalogs/deutsch"
156 but: exactly the same, but buffer before was used for
161 strcpy(buffer, "PROGDIR:Catalogs");
162 AddPart(buffer, "deutsch", 256);
164 gives correct "PROGDIR:Catalogs/deutsch"
166 strcpy(buffer, "LOCALE:Catalogs");
167 AddPart(buffer, "deutsch", 256);
169 gives wrong "LOCALE:Catalogs//deutsch"
175 BOOL gotfull
= FALSE
;
178 Make sure the buffer wouldn't overflow, also finds the ends
184 while(dirname
[didx
]) didx
++;
185 while(filename
[fidx
])
188 If this has a colon, and its not the first char,
189 then this is probably a FQ path.
191 if((filename
[fidx
] == ':') && (fidx
!= 0))
197 /* If we got a fully qualified path, then just do a copy. */
200 /* +1 for NULL byte */
201 if( fidx
+ 1 > size
)
206 *dirname
++ = *filename
++;
212 /* Otherwise correctly add the subpath on to the end */
215 /* +1 for NULL byte, +1 for '/' */
216 if((didx
+ fidx
+ 2) > size
)
220 Add a '/' onto the end of the current path, unless of course
221 the new path has a ':' or '/' on it already or current path
222 is emtpy (stegerg) ...
224 if( (*filename
!= '/')
226 && (dirname
[didx
- 1] != ':')
227 && (dirname
[didx
- 1] != '/')
230 dirname
[didx
++] = '/';
236 while (*filename
== '/')
239 while ((dirname
[didx
] != '/') && (dirname
[didx
] != ':') && didx
)
243 if we are at start of dirname buf then break even
244 if there are more leading '/'s
250 Another leading '/' ?.
251 Only move up a dir if we are not at the root
253 if ((*filename
== '/') && (dirname
[didx
] != ':'))
257 /* If at root, don't overwrite the ':' */
258 if (dirname
[didx
] == ':')
261 if filename not only was a number of '/'s but also contained
262 a subpath, then be sure to skip the found '/' of dirname.
264 else if ((dirname
[didx
] == '/') && *filename
)
267 /* Now add the parts, making sure to do any backtracking... */
273 Search back for a ':' or the start of the buffer
274 do the ':' test first, so we test for didx = 0 after...
276 while( (dirname
[didx
] != ':') && didx
)
280 dirname
[didx
++] = *filename
++;
283 dirname
[didx
++] = *filename
++;
284 } /* while(*filename) */
286 dirname
[didx
] = '\0';