Fixed missing fprintf argument.
[AROS.git] / rom / dos / addpart.c
blobeb1909bc5f721a29cabf84f68bde68ff21844e8c
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: english
7 */
8 #include "dos_intern.h"
10 #include <string.h>
12 /*****************************************************************************
14 NAME */
15 #include <proto/dos.h>
17 AROS_LH3(BOOL, AddPart,
19 /* SYNOPSIS */
20 AROS_LHA(STRPTR, dirname, D1),
21 AROS_LHA(CONST_STRPTR, filename, D2),
22 AROS_LHA(ULONG, size, D3),
24 /* LOCATION */
25 struct DosLibrary *, DOSBase, 147, Dos)
27 /* FUNCTION
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.
35 INPUTS
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
40 RESULT
41 non-zero if everything succeed, FALSE if the buffer would have
42 overflowed.
44 If the buffer would have overflowed, then dirname will not have
45 been changed.
47 NOTES
49 EXAMPLE
50 UBYTE buffer[128];
51 buffer[0]='\0';
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
67 BUGS
69 SEE ALSO
70 FilePart(), PathPart()
72 INTERNALS
74 *****************************************************************************/
76 AROS_LIBFUNC_INIT
77 AROS_LIBBASE_EXT_DECL(struct DosLibrary *,DOSBase)
79 #if 1
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
90 char *stringpos;
91 LONG stringlen;
92 WORD mustaddslash = 0;
94 stringpos = strchr(filename, ':');
95 if (stringpos)
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;
106 else
108 /* Filename is a fully qualified path including
109 volume/device name -> replace dirname with filename */
111 stringpos = dirname;
114 else
116 /* filename did not contain ':' */
118 stringlen = strlen(dirname);
119 stringpos = dirname + stringlen;
121 /* Check if we must add a slash */
123 if (stringlen > 0)
125 if ((stringpos[-1] != ':') && (stringpos[-1] != '/'))
126 mustaddslash = 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);
137 return DOSTRUE;
139 else
141 return DOSFALSE;
144 #else
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:
150 char buffer[256];
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
158 something else:
160 char buffer[256];
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"
175 LONG didx, fidx;
176 BOOL gotfull = FALSE;
179 Make sure the buffer wouldn't overflow, also finds the ends
180 of the strings...
183 didx = fidx = 0;
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))
193 gotfull = TRUE;
195 fidx++;
198 /* If we got a fully qualified path, then just do a copy. */
199 if(gotfull == TRUE)
201 /* +1 for NULL byte */
202 if( fidx + 1 > size )
203 return DOSFALSE;
205 while(*filename)
207 *dirname++ = *filename++;
209 *dirname = '\0';
210 return DOSTRUE;
213 /* Otherwise correctly add the subpath on to the end */
214 else
216 /* +1 for NULL byte, +1 for '/' */
217 if((didx + fidx + 2) > size)
218 return DOSFALSE;
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 != '/')
226 && (didx != 0 )
227 && (dirname[didx - 1] != ':')
228 && (dirname[didx - 1] != '/')
231 dirname[didx++] = '/';
235 Handle leading '/'s
237 while (*filename == '/')
239 filename ++;
240 while ((dirname[didx] != '/') && (dirname[didx] != ':') && didx)
241 didx --;
244 if we are at start of dirname buf then break even
245 if there are more leading '/'s
247 if (!didx)
248 break;
251 Another leading '/' ?.
252 Only move up a dir if we are not at the root
254 if ((*filename== '/') && (dirname[didx] != ':'))
255 didx --;
258 /* If at root, don't overwrite the ':' */
259 if (dirname[didx] == ':')
260 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)
266 didx ++;
268 /* Now add the parts, making sure to do any backtracking... */
269 while(*filename)
271 if(*filename == ':')
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)
279 didx--;
281 dirname[didx++] = *filename++;
283 else
284 dirname[didx++] = *filename++;
285 } /* while(*filename) */
287 dirname[didx] = '\0';
289 return DOSTRUE;
290 #endif
292 AROS_LIBFUNC_EXIT
293 } /* AddPart */