Add new strings.
[AROS.git] / rom / dos / addpart.c
blobd7fd87bfcc88a09f50353b2e92547dfb84a55fc5
1 /*
2 Copyright © 1995-2008, 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 succeeded, 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[80];
51 buffer[0]='\0';
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
67 BUGS
69 SEE ALSO
70 FilePart(), PathPart()
72 INTERNALS
74 *****************************************************************************/
76 AROS_LIBFUNC_INIT
78 #if 1
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
89 char *stringpos;
90 LONG stringlen;
91 WORD mustaddslash = 0;
93 stringpos = strchr(filename, ':');
94 if (stringpos)
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;
105 else
107 /* Filename is a fully qualified path including
108 volume/device name -> replace dirname with filename */
110 stringpos = dirname;
113 else
115 /* filename did not contain ':' */
117 stringlen = strlen(dirname);
118 stringpos = dirname + stringlen;
120 /* Check if we must add a slash */
122 if (stringlen > 0)
124 if ((stringpos[-1] != ':') && (stringpos[-1] != '/'))
125 mustaddslash = 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);
136 return DOSTRUE;
138 else
140 return DOSFALSE;
143 #else
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:
149 char buffer[256];
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
157 something else:
159 char buffer[256];
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"
174 LONG didx, fidx;
175 BOOL gotfull = FALSE;
178 Make sure the buffer wouldn't overflow, also finds the ends
179 of the strings...
182 didx = fidx = 0;
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))
192 gotfull = TRUE;
194 fidx++;
197 /* If we got a fully qualified path, then just do a copy. */
198 if(gotfull == TRUE)
200 /* +1 for NULL byte */
201 if( fidx + 1 > size )
202 return DOSFALSE;
204 while(*filename)
206 *dirname++ = *filename++;
208 *dirname = '\0';
209 return DOSTRUE;
212 /* Otherwise correctly add the subpath on to the end */
213 else
215 /* +1 for NULL byte, +1 for '/' */
216 if((didx + fidx + 2) > size)
217 return DOSFALSE;
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 != '/')
225 && (didx != 0 )
226 && (dirname[didx - 1] != ':')
227 && (dirname[didx - 1] != '/')
230 dirname[didx++] = '/';
234 Handle leading '/'s
236 while (*filename == '/')
238 filename ++;
239 while ((dirname[didx] != '/') && (dirname[didx] != ':') && didx)
240 didx --;
243 if we are at start of dirname buf then break even
244 if there are more leading '/'s
246 if (!didx)
247 break;
250 Another leading '/' ?.
251 Only move up a dir if we are not at the root
253 if ((*filename== '/') && (dirname[didx] != ':'))
254 didx --;
257 /* If at root, don't overwrite the ':' */
258 if (dirname[didx] == ':')
259 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)
265 didx ++;
267 /* Now add the parts, making sure to do any backtracking... */
268 while(*filename)
270 if(*filename == ':')
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)
278 didx--;
280 dirname[didx++] = *filename++;
282 else
283 dirname[didx++] = *filename++;
284 } /* while(*filename) */
286 dirname[didx] = '\0';
288 return DOSTRUE;
289 #endif
291 AROS_LIBFUNC_EXIT
292 } /* AddPart */