2 Copyright © 1995-2012, 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 an absolute path 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
);
140 SetIoErr(ERROR_LINE_TOO_LONG
);
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
) {
203 SetIoErr(ERROR_LINE_TOO_LONG
);
208 *dirname
++ = *filename
++;
214 /* Otherwise correctly add the subpath on to the end */
217 /* +1 for NULL byte, +1 for '/' */
218 if((didx
+ fidx
+ 2) > size
) {
219 SetIoErr(ERROR_LINE_TOO_LONG
);
224 Add a '/' onto the end of the current path, unless of course
225 the new path has a ':' or '/' on it already or current path
226 is emtpy (stegerg) ...
228 if( (*filename
!= '/')
230 && (dirname
[didx
- 1] != ':')
231 && (dirname
[didx
- 1] != '/')
234 dirname
[didx
++] = '/';
240 while (*filename
== '/')
243 while ((dirname
[didx
] != '/') && (dirname
[didx
] != ':') && didx
)
247 if we are at start of dirname buf then break even
248 if there are more leading '/'s
254 Another leading '/' ?.
255 Only move up a dir if we are not at the root
257 if ((*filename
== '/') && (dirname
[didx
] != ':'))
261 /* If at root, don't overwrite the ':' */
262 if (dirname
[didx
] == ':')
265 if filename not only was a number of '/'s but also contained
266 a subpath, then be sure to skip the found '/' of dirname.
268 else if ((dirname
[didx
] == '/') && *filename
)
271 /* Now add the parts, making sure to do any backtracking... */
277 Search back for a ':' or the start of the buffer
278 do the ':' test first, so we test for didx = 0 after...
280 while( (dirname
[didx
] != ':') && didx
)
284 dirname
[didx
++] = *filename
++;
287 dirname
[didx
++] = *filename
++;
288 } /* while(*filename) */
290 dirname
[didx
] = '\0';