2 Copyright © 1995-2001, 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 succeed, 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");
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 *****************************************************************************/
77 AROS_LIBBASE_EXT_DECL(struct DosLibrary
*,DOSBase
)
80 /* stegerg: a bit simple, but since the other code does not
81 work correctly. And then even AmigaOS AddPart()
82 does not seem to do things like eliminating
83 "dead" path components like:
85 "test/test2//test3" --> "test/test3"
87 It just makes sure that the path is correct
92 WORD mustaddslash
= 0;
94 stringpos
= strchr(filename
, ':');
97 if (stringpos
== (char *)filename
)
99 /* The first char of filename is a ':' */
101 /* Find dirname position to where we copy filename later */
103 stringpos
= strchr(dirname
, ':');
104 if (!stringpos
) stringpos
= dirname
;
108 /* Filename is a fully qualified path including
109 volume/device name -> replace dirname with filename */
116 /* filename did not contain ':' */
118 stringlen
= strlen(dirname
);
119 stringpos
= dirname
+ stringlen
;
121 /* Check if we must add a slash */
125 if ((stringpos
[-1] != ':') && (stringpos
[-1] != '/'))
130 /* Check if dirname buffer is big enough */
132 stringlen
= ((LONG
)(stringpos
- (char *)dirname
)) + strlen(filename
) + 1 + mustaddslash
;
133 if (stringlen
<= size
)
135 if (mustaddslash
) *stringpos
++ = '/';
136 strcpy(stringpos
, filename
);
146 /* stegerg: this is buggy, because in some places it accesses
147 chars in dirname behind the (initial) string in
148 there (after the 0 char). For example:
152 strcpy(buffer, "LOCALE:Catalogs");
153 AddPart(buffer, "deutsch", 256);
155 gives correct "LOCALE:Catalogs/deutsch"
157 but: exactly the same, but buffer before was used for
162 strcpy(buffer, "PROGDIR:Catalogs");
163 AddPart(buffer, "deutsch", 256);
165 gives correct "PROGDIR:Catalogs/deutsch"
167 strcpy(buffer, "LOCALE:Catalogs");
168 AddPart(buffer, "deutsch", 256);
170 gives wrong "LOCALE:Catalogs//deutsch"
176 BOOL gotfull
= FALSE
;
179 Make sure the buffer wouldn't overflow, also finds the ends
185 while(dirname
[didx
]) didx
++;
186 while(filename
[fidx
])
189 If this has a colon, and its not the first char,
190 then this is probably a FQ path.
192 if((filename
[fidx
] == ':') && (fidx
!= 0))
198 /* If we got a fully qualified path, then just do a copy. */
201 /* +1 for NULL byte */
202 if( fidx
+ 1 > size
)
207 *dirname
++ = *filename
++;
213 /* Otherwise correctly add the subpath on to the end */
216 /* +1 for NULL byte, +1 for '/' */
217 if((didx
+ fidx
+ 2) > size
)
221 Add a '/' onto the end of the current path, unless of course
222 the new path has a ':' or '/' on it already or current path
223 is emtpy (stegerg) ...
225 if( (*filename
!= '/')
227 && (dirname
[didx
- 1] != ':')
228 && (dirname
[didx
- 1] != '/')
231 dirname
[didx
++] = '/';
237 while (*filename
== '/')
240 while ((dirname
[didx
] != '/') && (dirname
[didx
] != ':') && didx
)
244 if we are at start of dirname buf then break even
245 if there are more leading '/'s
251 Another leading '/' ?.
252 Only move up a dir if we are not at the root
254 if ((*filename
== '/') && (dirname
[didx
] != ':'))
258 /* If at root, don't overwrite the ':' */
259 if (dirname
[didx
] == ':')
262 if filename not only was a number of '/'s but also contained
263 a subpath, then be sure to skip the found '/' of dirname.
265 else if ((dirname
[didx
] == '/') && *filename
)
268 /* Now add the parts, making sure to do any backtracking... */
274 Search back for a ':' or the start of the buffer
275 do the ':' test first, so we test for didx = 0 after...
277 while( (dirname
[didx
] != ':') && didx
)
281 dirname
[didx
++] = *filename
++;
284 dirname
[didx
++] = *filename
++;
285 } /* while(*filename) */
287 dirname
[didx
] = '\0';