grub2: bring back build of aros-side grub2 tools
[AROS.git] / workbench / classes / zune / betterstring / mcc / FileNameCompl.c
blob904578b15910efbf88b0729c30894f78f280877e
1 /***************************************************************************
3 BetterString.mcc - A better String gadget MUI Custom Class
4 Copyright (C) 1997-2000 Allan Odgaard
5 Copyright (C) 2005-2013 by BetterString.mcc Open Source Team
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 BetterString class Support Site: http://www.sf.net/projects/bstring-mcc/
19 $Id$
21 ***************************************************************************/
23 #include <string.h>
24 #include <stdio.h>
26 #include <dos/dosextens.h>
27 #include <clib/alib_protos.h>
28 #include <proto/exec.h>
29 #include <proto/intuition.h>
30 #include <proto/utility.h>
31 #include <proto/dos.h>
33 #if defined(__amigaos4__)
34 #include <dos/obsolete.h>
35 #endif
37 #ifdef AROS_ABI_V1
38 #include <aros/config.h>
39 #endif
41 #include "private.h"
43 #include "Debug.h"
45 BOOL OverwriteA(STRPTR text, UWORD x, UWORD length, UWORD ptrn_length, struct InstData *data)
47 BOOL result = TRUE;
49 ENTER();
51 if(length < ptrn_length)
53 ULONG expand = ptrn_length-length;
55 if(data->MaxLength && strlen(data->Contents)+expand > (unsigned int)(data->MaxLength-1))
57 ptrn_length -= expand;
58 ptrn_length += (data->MaxLength-1)-strlen(data->Contents);
59 result = FALSE;
61 if(ExpandContentString(&data->Contents, expand) == TRUE)
62 memmove(data->Contents+x+ptrn_length, data->Contents+x+length, strlen(data->Contents+x+length)+1);
63 else
64 E(DBF_ALWAYS, "content expansion by %ld bytes failed", expand);
66 else
68 memmove(data->Contents+x+ptrn_length, data->Contents+x+length, strlen(data->Contents+x+length)+1);
70 CopyMem(text, data->Contents+x, ptrn_length);
72 if(data->BufferPos >= x)
74 data->BufferPos += ptrn_length-length;
75 if(data->BufferPos < x)
76 data->BufferPos = x;
79 if(result == FALSE)
80 DisplayBeep(NULL);
82 RETURN(result);
83 return result;
86 BOOL Overwrite(STRPTR text, UWORD x, UWORD length, struct InstData *data)
88 BOOL result;
90 ENTER();
92 result = OverwriteA(text, x, length, strlen(text), data);
94 RETURN(result);
95 return result;
98 WORD VolumeStart(STRPTR text, WORD pos)
100 BOOL searching = TRUE;
102 ENTER();
104 while(pos > 0 && searching)
106 switch(*(text+pos-1))
108 case '"':
109 case '>':
110 case ' ':
111 case '=':
112 searching = FALSE;
113 break;
115 default:
116 pos--;
117 break;
121 RETURN(pos);
122 return pos;
125 LONG mFileNameStart(struct MUIP_BetterString_FileNameStart *msg)
127 STRPTR buffer = msg->buffer;
128 LONG pos = msg->pos;
130 ENTER();
132 while(pos && buffer[pos] != ':')
133 pos--;
135 if(buffer[pos] == ':')
136 pos = VolumeStart(buffer, pos);
137 else
138 pos = MUIR_BetterString_FileNameStart_Volume;
140 RETURN(pos);
141 return pos;
144 VOID InsertFileName(UWORD namestart, struct InstData *data)
146 struct ExAllData *ead1 = &data->FNCBuffer->buffer;
147 struct ExAllData *ead2;
148 struct FNCData *fncframe;
149 struct FNCData *fncframe1 = data->FNCBuffer;
150 UWORD entrynum;
151 UWORD findnum = data->FileNumber;
152 char tmpname[32];
154 ENTER();
158 entrynum = 0;
159 fncframe = data->FNCBuffer;
160 ead2 = &fncframe->buffer;
161 while(ead2 != NULL)
163 //if(CmpStrings(ead1->ed_Name, ead2->ed_Name) > 0)
164 if(strcmp((const char *)ead1->ed_Name, (const char *)ead2->ed_Name) > 0)
165 entrynum++;
167 ead2 = ead2->ed_Next;
168 if(ead2 == NULL && fncframe->next != NULL)
170 fncframe = fncframe->next;
171 ead2 = &fncframe->buffer;
175 if(entrynum != findnum)
176 ead1 = ead1->ed_Next;
177 if(ead1 == NULL && fncframe1->next != NULL)
179 fncframe1 = fncframe1->next;
180 ead1 = &fncframe1->buffer;
183 while(entrynum != findnum);
185 snprintf(tmpname, sizeof(tmpname), "%s%s", ead1->ed_Name, ead1->ed_Type == 2 ? "/" : " ");
187 Overwrite(tmpname, namestart, data->BufferPos-namestart, data);
189 LEAVE();
192 BOOL FileNameComplete(Object *obj, BOOL backwards, struct InstData *data)
194 BOOL edited = FALSE;
196 ENTER();
198 if(data->FNCBuffer != NULL)
200 if(data->FileEntries == 1)
202 DisplayBeep(NULL);
204 else
206 if(backwards)
208 if(--data->FileNumber < 0)
209 data->FileNumber = data->FileEntries-1;
211 else
213 if(++data->FileNumber >= data->FileEntries)
214 data->FileNumber = 0;
217 InsertFileName(data->FileNameStart, data);
218 edited = TRUE;
220 else
222 LONG pos = DoMethod(obj, MUIM_BetterString_FileNameStart, data->Contents, data->BufferPos);
224 switch(pos)
226 case MUIR_BetterString_FileNameStart_Volume:
228 struct DosList *dl;
229 STRPTR volumeName = NULL;
230 char tmpBuffer[256];
231 UWORD cut;
233 pos = VolumeStart(data->Contents, data->BufferPos);
234 if((cut = data->BufferPos-pos) != 0)
236 dl = LockDosList(LDF_READ|LDF_DEVICES|LDF_VOLUMES|LDF_ASSIGNS);
237 while((dl = NextDosEntry(dl, LDF_READ|LDF_DEVICES|LDF_VOLUMES|LDF_ASSIGNS)) != NULL)
239 #ifdef __AROS__
240 #ifdef AROS_ABI_V1
241 strlcpy(tmpBuffer, AROS_BSTR_ADDR(dl->dol_Name), AROS_BSTR_strlen(dl->dol_Name));
242 #else
243 strlcpy(tmpBuffer, dl->dol_Ext.dol_AROS.dol_DevName, sizeof tmpBuffer);
244 #endif
245 #else
246 // dol_Name is a BSTR, we have to convert it to a regular C string
247 char *bstr = BADDR(dl->dol_Name);
249 // a BSTR cannot exceed 255 characters, hence the buffer size of 256 is enough in any case
250 strlcpy(tmpBuffer, &bstr[1], (unsigned char)bstr[0]);
251 #endif
253 if(Strnicmp(tmpBuffer, data->Contents+pos, cut) == 0)
255 volumeName = tmpBuffer;
256 break;
260 if(volumeName != NULL)
262 if(OverwriteA(volumeName, pos, cut, strlen(volumeName)+1, data))
263 data->Contents[data->BufferPos-1] = ':';
264 edited = TRUE;
266 UnLockDosList(LDF_READ|LDF_DEVICES|LDF_VOLUMES|LDF_ASSIGNS);
269 break;
271 default:
273 struct FNCData *fncbuffer;
274 struct FNCData *fncframe;
275 struct ExAllControl *control;
276 BPTR dirlock;
277 char pattern[42];
278 UWORD namestart = data->BufferPos;
279 char oldletter = '\0';
280 BOOL filename = TRUE;
282 while(filename)
284 switch(*(data->Contents+namestart-1))
286 case '/':
287 case ':':
288 filename = FALSE;
289 break;
291 default:
292 namestart--;
293 break;
297 if((data->BufferPos-namestart) < 32)
299 strlcpy(pattern, data->Contents+namestart, sizeof(pattern));
300 strlcat(pattern, "~(#?.info)", sizeof(pattern));
302 oldletter = data->Contents[namestart];
303 data->Contents[namestart] = '\0';
305 if((fncbuffer = (struct FNCData *)SharedPoolAlloc(4100)) != NULL)
307 fncbuffer->next = NULL;
309 if((control = (struct ExAllControl *)AllocDosObject(DOS_EXALLCONTROL, NULL)))
311 char tokenized[sizeof(pattern) * 2 + 2];
313 if(ParsePatternNoCase(pattern, tokenized, sizeof(tokenized)) != -1)
314 control->eac_MatchString = tokenized;
316 if((dirlock = Lock(data->Contents+pos, ACCESS_READ)))
318 UWORD entries = 0;
320 fncframe = fncbuffer;
321 while(fncframe && ExAll(dirlock, &fncframe->buffer, 4096, ED_TYPE, control))
323 entries += control->eac_Entries;
325 if((fncframe->next = (struct FNCData *)SharedPoolAlloc(4100)))
326 fncframe->next->next = NULL;
328 fncframe = fncframe->next;
330 control->eac_Entries += entries;
332 data->FileNumber = backwards ? control->eac_Entries-1 : 0;
333 data->FileEntries = control->eac_Entries;
334 data->FileNameStart = namestart;
335 data->FNCBuffer = fncbuffer;
337 if(control->eac_Entries)
339 data->Contents[namestart] = oldletter;
340 InsertFileName(namestart, data);
341 edited = TRUE;
343 UnLock(dirlock);
345 else
347 SharedPoolFree(fncbuffer);
350 FreeDosObject(DOS_EXALLCONTROL, (APTR)control);
355 if(edited == FALSE)
356 data->Contents[namestart] = oldletter;
358 break;
362 RETURN(edited);
363 return edited;