Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / workbench / classes / zune / betterstring / mcc / FileNameCompl.c
blob09f0d4009226dbe78ee60ede5e8c97872f2edf69
1 /***************************************************************************
3 BetterString.mcc - A better String gadget MUI Custom Class
4 Copyright (C) 1997-2000 Allan Odgaard
5 Copyright (C) 2005 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 <stdio.h>
24 #include <string.h>
26 #include <proto/dos.h>
27 #include <proto/exec.h>
28 #include <proto/intuition.h>
29 #include <proto/utility.h>
31 #include "BetterString_mcc.h"
32 #include "private.h"
34 BOOL OverwriteA (STRPTR text, UWORD x, UWORD length, UWORD ptrn_length, struct InstData *data)
36 BOOL result = TRUE;
38 if(length < ptrn_length)
40 UWORD expand = ptrn_length-length;
42 if(data->MaxLength && strlen(data->Contents)+expand > data->MaxLength-1)
44 ptrn_length -= expand;
45 ptrn_length += (data->MaxLength-1)-strlen(data->Contents);
46 result = FALSE;
48 data->Contents = (STRPTR)ExpandPool(data->Pool, data->Contents, expand);
49 strcpyback(data->Contents+x+ptrn_length, data->Contents+x+length);
51 else
53 strcpy(data->Contents+x+ptrn_length, data->Contents+x+length);
55 CopyMem(text, data->Contents+x, ptrn_length);
57 if(data->BufferPos >= x)
59 data->BufferPos += ptrn_length-length;
60 if(data->BufferPos < x)
61 data->BufferPos = x;
64 if(!result)
65 DisplayBeep(NULL);
67 return(result);
70 BOOL Overwrite (STRPTR text, UWORD x, UWORD length, struct InstData *data)
72 return(OverwriteA(text, x, length, strlen(text), data));
75 WORD VolumeStart (STRPTR text, WORD pos)
77 BOOL searching = TRUE;
79 while(pos > 0 && searching)
81 switch(*(text+pos-1))
83 case '"':
84 case '>':
85 case ' ':
86 case '=':
87 searching = FALSE;
88 break;
89 default:
90 pos--;
93 return(pos);
96 LONG FileNameStart (struct MUIP_BetterString_FileNameStart *msg)
98 STRPTR buffer = msg->buffer;
99 LONG pos = msg->pos;
101 while(pos && buffer[pos] != ':')
102 pos--;
104 if(buffer[pos] == ':')
105 pos = VolumeStart(buffer, pos);
106 else pos = MUIR_BetterString_FileNameStart_Volume;
108 return(pos);
111 VOID InsertFileName (UWORD namestart, struct InstData *data)
113 struct ExAllData *ead1 = &data->FNCBuffer->buffer;
114 struct ExAllData *ead2;
115 struct FNCData *fncframe;
116 struct FNCData *fncframe1 = data->FNCBuffer;
117 UWORD entrynum;
118 UWORD findnum = data->FileNumber;
119 UBYTE tmpname[32];
121 do {
123 entrynum = 0;
124 fncframe = data->FNCBuffer;
125 ead2 = &fncframe->buffer;
126 while(ead2)
128 //if(CmpStrings(ead1->ed_Name, ead2->ed_Name) > 0)
129 if(strcmp(ead1->ed_Name, ead2->ed_Name) > 0)
130 entrynum++;
132 ead2 = ead2->ed_Next;
133 if(!ead2 && fncframe->next)
135 fncframe = fncframe->next;
136 ead2 = &fncframe->buffer;
140 if(entrynum != findnum)
141 ead1 = ead1->ed_Next;
142 if(!ead1 && fncframe1->next)
144 fncframe1 = fncframe1->next;
145 ead1 = &fncframe1->buffer;
147 } while(entrynum != findnum);
149 strcpy(tmpname, ead1->ed_Name);
150 strcat(tmpname, ead1->ed_Type == 2 ? "/" : " ");
152 Overwrite(tmpname, namestart, data->BufferPos-namestart, data);
155 BOOL FileNameComplete (Object *obj, BOOL backwards, struct InstData *data)
157 BOOL edited = FALSE;
158 if(data->FNCBuffer)
160 if(data->FileEntries == 1)
162 DisplayBeep(NULL);
164 else
166 if(backwards)
168 if(--data->FileNumber < 0)
169 data->FileNumber = data->FileEntries-1;
171 else
173 if(++data->FileNumber >= data->FileEntries)
174 data->FileNumber = 0;
177 InsertFileName(data->FileNameStart, data);
178 edited = TRUE;
180 else
182 LONG pos;
183 switch(pos = DoMethod(obj, MUIM_BetterString_FileNameStart, data->Contents, data->BufferPos))
185 case MUIR_BetterString_FileNameStart_Volume:
187 struct DosList *dl;
188 STRPTR VolumeName = NULL;
189 UWORD cut;
191 pos = VolumeStart(data->Contents, data->BufferPos);
192 if((cut = data->BufferPos-pos))
194 dl = LockDosList(LDF_READ|LDF_DEVICES|LDF_VOLUMES|LDF_ASSIGNS);
195 while((dl = NextDosEntry(dl, LDF_READ|LDF_DEVICES|LDF_VOLUMES|LDF_ASSIGNS)))
197 #ifdef __AROS__
198 STRPTR NodeName = dl->dol_Ext.dol_AROS.dol_DevName;
199 #else
200 STRPTR NodeName = (STRPTR)((dl->dol_Name << 2)+1);
201 #endif
202 if(!Strnicmp(NodeName, data->Contents+pos, cut))
204 VolumeName = NodeName;
205 break;
209 if(VolumeName)
211 #ifdef __AROS__
212 if(OverwriteA(VolumeName, pos, cut, strlen(VolumeName)+1, data))
213 data->Contents[data->BufferPos-1] = ':';
214 #else
215 if(OverwriteA(VolumeName, pos, cut, *(VolumeName-1)+1, data))
216 data->Contents[data->BufferPos-1] = ':';
217 #endif
218 edited = TRUE;
220 UnLockDosList(LDF_READ|LDF_DEVICES|LDF_VOLUMES|LDF_ASSIGNS);
223 break;
225 default:
227 struct FNCData *fncbuffer;
228 struct FNCData *fncframe;
229 struct ExAllControl *control;
230 BPTR dirlock;
231 UBYTE pattern[42];
232 UWORD namestart = data->BufferPos;
233 UBYTE oldletter;
234 BOOL filename = TRUE;
236 while(filename)
238 switch(*(data->Contents+namestart-1))
240 case '/':
241 case ':':
242 filename = FALSE;
243 break;
245 default:
246 namestart--;
247 break;
250 if((data->BufferPos-namestart) < 32)
252 strncpy(pattern, data->Contents+namestart, data->BufferPos-namestart);
253 oldletter = data->Contents[namestart];
254 strcpy(pattern+(data->BufferPos-namestart), "~(#?.info)");
255 data->Contents[namestart] = '\0';
257 if((fncbuffer = (struct FNCData *)MyAllocPooled(data->Pool, 4100)))
259 fncbuffer->next = NULL;
261 if((control = (struct ExAllControl *)AllocDosObject(DOS_EXALLCONTROL, NULL)))
263 UBYTE tokenized[80];
265 if(ParsePatternNoCase(pattern, tokenized, 40) != -1)
266 control->eac_MatchString = tokenized;
268 if((dirlock = Lock(data->Contents+pos, ACCESS_READ)))
270 UWORD entries = 0;
272 fncframe = fncbuffer;
273 while(fncframe && ExAll(dirlock, &fncframe->buffer, 4096, ED_TYPE, control))
275 entries += control->eac_Entries;
277 if((fncframe->next = (struct FNCData *)MyAllocPooled(data->Pool, 4100)))
278 fncframe->next->next = NULL;
280 fncframe = fncframe->next;
282 control->eac_Entries += entries;
284 data->FileNumber = backwards ? control->eac_Entries-1 : 0;
285 data->FileEntries = control->eac_Entries;
286 data->FileNameStart = namestart;
287 data->FNCBuffer = fncbuffer;
289 if(control->eac_Entries)
291 data->Contents[namestart] = oldletter;
292 InsertFileName(namestart, data);
293 edited = TRUE;
295 UnLock(dirlock);
297 FreeDosObject(DOS_EXALLCONTROL, (APTR)control);
301 if(!edited)
302 data->Contents[namestart] = oldletter;
304 break;
307 return(edited);