Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / libs / datatypes / helpfuncs.c
blobb7f2da965fec8e6d7fac1d21b31c235d3657c969
1 /*
2 Copyright © 1995-2012, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define USE_BOOPSI_STUBS
7 #include <aros/macros.h>
8 #include <datatypes/datatypes.h>
9 #include <proto/alib.h>
10 #include <proto/utility.h>
11 #include <proto/dos.h>
12 #include <proto/iffparse.h>
13 #include <proto/intuition.h>
14 #include <proto/locale.h>
15 #include <utility/name.h>
16 #include <intuition/cghooks.h>
17 #include <libraries/locale.h>
18 #include <datatypes/datatypesclass.h>
19 #include "datatypes_intern.h"
20 #include <clib/boopsistubs.h>
22 #include <aros/debug.h>
24 /************************** ASCII/BINARY RECOGNITION *************************/
26 UBYTE const ASCIITable[256]=
28 0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,1,0,1,0,0,0,0,0,0,0,1,0,0,0,0,
29 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
30 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
31 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
32 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
33 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
34 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
35 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
39 UBYTE const BinaryTable[256]=
41 1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,0,1,0,1,1,1,1,1,1,1,0,1,1,1,1,
42 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
43 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
44 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
45 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,
46 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
47 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
48 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
53 struct DataTypesList *GetDataTypesList(struct DataTypesBase *DataTypesBase)
55 struct NamedObject *no;
56 struct DataTypesList *dtl = NULL;
58 if((no = FindNamedObject(NULL, DATATYPESLIST, NULL)))
60 dtl = (struct DataTypesList *)no->no_Object;
63 if(!dtl)
65 struct TagItem tags[] =
67 {ANO_NameSpace , TRUE },
68 {ANO_UserSpace , sizeof(struct DataTypesList) },
69 {ANO_Flags , NSF_NODUPS | NSF_CASE },
70 {TAG_DONE }
73 if((no = AllocNamedObjectA(DATATYPESLIST, tags)))
75 if(!(dtl = (struct DataTypesList*)no->no_Object))
77 FreeNamedObject(no);
78 no = NULL;
82 if(dtl)
84 InitSemaphore(&dtl->dtl_Lock);
85 NewList(&dtl->dtl_SortedList);
86 NewList(&dtl->dtl_BinaryList);
87 NewList(&dtl->dtl_ASCIIList);
88 NewList(&dtl->dtl_IFFList);
89 NewList(&dtl->dtl_MiscList);
91 if(!AddNamedObject(NULL, no))
93 FreeNamedObject(no);
94 no = NULL;
95 dtl = NULL;
100 if (no)
101 ReleaseNamedObject(no);
103 return(dtl);
107 struct Node *FindNameNoCase(struct Library *DataTypesBase, struct List *list,
108 STRPTR name)
110 struct Node *node;
111 struct Node *result = NULL;
113 for (node = list->lh_Head; node->ln_Succ; node = node->ln_Succ)
115 if (!Stricmp(node->ln_Name, name))
117 result = node;
118 break;
122 return result;
127 BPTR NewOpen(struct Library *DataTypesBase, STRPTR name, ULONG SourceType,
128 ULONG Length)
130 BPTR returnfh = BNULL;
131 // struct XpkFib *xpkfib=NULL;
132 BPTR dosfile;
134 D(bug("datatypes.library/NewOpen: name = %s\n", name));
136 if((dosfile = Open(name, MODE_OLDFILE)))
138 D(bug("datatypes.library/NewOpen: open okay\n"));
140 returnfh = dosfile;
142 #if 0
143 if(XpkBase)
145 if(xpkfib = AllocVec(sizeof(struct XpkFib),
146 MEMF_PUBLIC|MEMF_CLEAR))
148 if(!xpkexaminetags(DataTypesBase, xpkfib, XPK_InFH, dosfile,
149 TAG_DONE))
151 switch (xpkfib->Type)
153 case XPKTYPE_UNPACKED:
154 returnfh=dosfile;
155 break;
157 case XPKTYPE_PACKED:
158 Message(DataTypesBase,"file is XPK packed","okay");
160 if (xpkfib->Flags&XPKFLAGS_PASSWORD)
161 Message(DataTypesBase,"file needs password","okay");
163 if (xpkfib->Flags&XPKFLAGS_NOSEEK)
164 Message(DataTypesBase,"file does not support seeking",
165 "okay");
166 if (xpkfib->Flags&XPKFLAGS_NONSTD)
167 Message(DataTypesBase,"file is non standard","okay");
169 SetIoErr(ERROR_NOT_IMPLEMENTED);
170 break;
172 case XPKTYPE_ARCHIVE:
173 SetIoErr(ERROR_NOT_IMPLEMENTED);
174 break;
177 FreeVec(xpkfib);
180 if (returnfh != dosfile)
182 Close(dosfile);
184 #endif
188 return returnfh;
194 #define getDTLIST (GPB(DataTypesBase)->dtb_DTList)
196 struct CompoundDataType *ExamineLock(BPTR lock, struct FileInfoBlock *fib,
197 struct Library *DataTypesBase)
199 struct CompoundDataType *cdt = NULL;
201 D(bug("datatypes.library/ExamineLock\n"));
203 ObtainSemaphoreShared(&getDTLIST->dtl_Lock);
205 if(Examine(lock, fib))
207 D(bug("datatypes.library/ExamineLock: Examine okay\n"));
208 if (fib->fib_DirEntryType > 0)
210 D(bug("datatypes.library/ExamineLock: is a directory\n"));
211 cdt = (struct CompoundDataType *)FindNameNoCase(DataTypesBase,
212 &getDTLIST->dtl_MiscList,
213 "directory");
215 else
217 if (fib->fib_DirEntryType < 0)
219 UBYTE namebuf[510];
221 D(bug("datatypes.library/ExamineLock: is a file\n"));
223 if (NameFromLock(lock, namebuf, sizeof(namebuf)))
225 BPTR file;
227 D(bug("datatypes.library/ExamineLock: NameFromLock okay. Name = \"%s\"\n", namebuf));
229 if((file = NewOpen(DataTypesBase, namebuf, DTST_FILE, 0)))
231 UBYTE *CheckArray;
232 UWORD CheckSize = (getDTLIST->dtl_LongestMask > 64) ?
233 getDTLIST->dtl_LongestMask : 64;
235 D(bug("datatypes.library/ExamineLock: NewOpen okay\n"));
237 if((CheckArray = AllocVec((ULONG)(CheckSize)+1,
238 MEMF_CLEAR)))
240 D(bug("datatypes.library/ExamineLock: Alloced CheckArray\n"));
242 if((CheckSize = Read(file, CheckArray,
243 (ULONG)CheckSize)) > 0)
245 struct DTHookContext dthc;
246 struct IFFHandle *iff;
248 D(bug("datatypes.library/ExamineLock: Read in CheckArray size = %d\n", CheckSize));
250 Seek(file, 0, OFFSET_BEGINNING);
252 dthc.dthc_SysBase = (struct Library *)SysBase;
253 dthc.dthc_DOSBase = (struct Library *)DOSBase;
254 dthc.dthc_IFFParseBase = IFFParseBase;
255 dthc.dthc_UtilityBase = (struct Library *)UtilityBase;
256 dthc.dthc_Lock = lock;
257 dthc.dthc_FIB = fib;
258 dthc.dthc_FileHandle = file;
259 dthc.dthc_Buffer = CheckArray;
260 dthc.dthc_BufferLength = CheckSize;
262 if(!(iff=dthc.dthc_IFF = AllocIFF()))
263 SetIoErr(ERROR_NO_FREE_STORE);
264 else
266 D(bug("datatypes.library/ExamineLock: AllocIFF okay: iff = %x\n", iff));
268 iff->iff_Stream = (IPTR)file; /* Hmm? */
269 InitIFFasDOS(iff);
271 if (!OpenIFF(iff, IFFF_READ))
273 D(bug("datatypes.library/ExamineLock: OpenIFF okay. Now calling ExamineData\n"));
275 cdt = ExamineData(DataTypesBase,
276 &dthc,
277 CheckArray,
278 CheckSize,
279 fib->fib_FileName,
280 fib->fib_Size);
282 D(bug("datatypes.library/ExamineLock: ExamineData() returned %x\n", cdt));
284 CloseIFF(iff);
286 } /* OpenIFF okay */
288 FreeIFF(iff); /* AROS BUG FIX: was dthc.dthc_IFF) */
290 } /* AllocIFF okay */
292 } /* if (CheckSize = Read(... */
294 FreeVec(CheckArray);
296 } /* if (CheckArray = AllocVec(... */
298 Close(file);
300 } /* if file opened */
302 } /* if I got the name from the lock */
304 } /* it is a file */
306 } /* it is not a directory */
308 } /* if(Examine(lock, fib)) */
310 ReleaseSemaphore(&getDTLIST->dtl_Lock);
312 return cdt;
316 struct CompoundDataType *FindDtInList(struct Library *DataTypesBase,
317 struct DTHookContext *dthc,
318 struct List *list,
319 UBYTE *CheckArray,
320 UWORD CheckSize,
321 UBYTE *Filename)
323 struct CompoundDataType *cdt = NULL;
324 BOOL found = FALSE;
326 if (list)
328 struct CompoundDataType *cur;
330 for(cur = (struct CompoundDataType *)list->lh_Head;
331 cur->DT.dtn_Node1.ln_Succ;
332 cur = (struct CompoundDataType *)cur->DT.dtn_Node1.ln_Succ)
334 if (!(cur->DTH.dth_MaskLen) && (cur->Function))
336 found = (cur->Function)(dthc);
338 else if(CheckSize >= cur->DTH.dth_MaskLen)
340 WORD *msk = cur->DTH.dth_Mask;
341 UBYTE *cmp = CheckArray;
342 UWORD count;
344 found=TRUE;
346 for(count = cur->DTH.dth_MaskLen; count--; msk++, cmp++)
348 if(*msk >= 0)
350 if(cur->DTH.dth_Flags & DTF_CASE)
352 if (*msk != *cmp)
354 found=FALSE;
355 break;
358 else
360 if(*msk != *cmp &&
361 *msk != ToUpper((ULONG)*cmp) &&
362 *msk != ToLower((ULONG)*cmp))
364 found=FALSE;
365 break;
371 if(found)
373 if((!(cur->FlagLong & CFLGF_PATTERN_UNUSED)) &&
374 cur->DTH.dth_Pattern)
376 if(cur->FlagLong & CFLGF_IS_WILD)
378 if(cur->ParsePatMem)
380 if(!MatchPatternNoCase(cur->ParsePatMem,
381 Filename))
383 found = FALSE;
387 else
389 if(Stricmp(cur->DTH.dth_Pattern, Filename))
391 found = FALSE;
396 if(found)
398 if(cur->Function)
400 found = (cur->Function)(dthc);
402 if (dthc->dthc_IFF)
404 CloseIFF(dthc->dthc_IFF);
405 OpenIFF(dthc->dthc_IFF, IFFF_READ);
407 else
409 Seek(dthc->dthc_FileHandle, 0,
410 OFFSET_BEGINNING);
416 if(found)
418 cdt = cur;
419 break;
423 return cdt;
427 struct CompoundDataType *ExamineData(struct Library *DataTypesBase,
428 struct DTHookContext *dthc,
429 UBYTE *CheckArray, UWORD CheckSize,
430 UBYTE *Filename, ULONG Size)
432 struct CompoundDataType *cdt = NULL;
433 struct CompoundDataType *cdt_bin = NULL;
434 struct CompoundDataType *cdt_asc = NULL;
436 D(UWORD type);
438 ULONG IFF_ID = AROS_BE2LONG(*((ULONG*)CheckArray));
439 ULONG IFF_Size = AROS_BE2LONG(*((ULONG*)(CheckArray+4)));
441 if(((!dthc->dthc_FileHandle) && (dthc->dthc_IFF)) ||
442 (((IFF_Size + 8 == Size) && (Size > 21)) &&
443 (IFF_ID==ID_FORM || IFF_ID==ID_CAT || IFF_ID==ID_LIST)) )
445 D(bug("[ExamineData] IFF detected\n"));
446 D(type = DTF_IFF);
447 cdt = FindDtInList(DataTypesBase, dthc, &getDTLIST->dtl_IFFList, CheckArray, CheckSize, Filename);
449 else
451 UBYTE *ptr;
452 UWORD count;
453 UWORD ascii;
455 dthc->dthc_IFF = NULL;
457 for (ptr=CheckArray,count=CheckSize,ascii=0 ; count-- ; ptr++)
459 if (ASCIITable[*ptr])
460 ascii++;
461 else
463 if (BinaryTable[*ptr])
465 ascii=0;
466 break;
471 D(bug("[ExamineData] ASCII characters: %u of %u\n", ascii, CheckSize));
472 if (ascii > CheckSize*3/4)
474 D(bug("[ExamineData] Recognized as ASCII\n"));
475 D(type = DTF_ASCII);
476 cdt_asc = FindDtInList(DataTypesBase, dthc, &getDTLIST->dtl_ASCIIList, CheckArray, CheckSize, Filename);
477 D(bug("[ExamineData] ASCII datatype: 0x%p\n", cdt_asc));
478 cdt = cdt_asc;
479 /* if the found datatype is 'only' ascii we have to look additionally in the binary list */
480 if (cdt_asc && !strcmp(cdt_asc->DTH.dth_Name, "ascii"))
482 D(bug("[ExamineData] Trying binary list\n"));
483 cdt_bin = FindDtInList(DataTypesBase, dthc, &getDTLIST->dtl_BinaryList, CheckArray, CheckSize, Filename);
484 D(bug("[[ExamineData] Binary datatype: 0x%p\n"));
485 /* if we find in the binary list something which is better than just 'binary' we use it */
486 if (cdt_bin && strcmp(cdt_bin->DTH.dth_Name, "binary"))
488 cdt = cdt_bin;
492 else
494 D(bug("[ExamineData] Recognized as binary\n"));
495 D(type = DTF_BINARY);
496 cdt = FindDtInList(DataTypesBase, dthc, &getDTLIST->dtl_BinaryList, CheckArray, CheckSize, Filename);
500 D(bug("[ExamineData] Found datatype 0x%p, type 0x%u\n", cdt, type));
501 return cdt;
505 #undef getDTLIST
508 /* Putchar procedure needed by RawDoFmt() */
510 AROS_UFH2(void, putchr,
511 AROS_UFHA(UBYTE, chr, D0),
512 AROS_UFHA(STRPTR *, p, A3))
514 AROS_USERFUNC_INIT
515 *(*p)++=chr;
516 AROS_USERFUNC_EXIT
520 /* FIXME: these work only with stack growing downwards and should therefore be fixed to use macros in utility/tagitem.h */
522 ULONG setattrs(struct Library *DataTypesBase, Object *object, Tag firstTag,...)
524 AROS_SLOWSTACKTAGS_PRE_AS(firstTag, ULONG)
525 retval = SetAttrsA(object, (struct TagItem *)&firstTag);
526 AROS_SLOWSTACKTAGS_POST
529 ULONG Do_OM_NOTIFY(struct Library *DataTypesBase, Object *object,
530 struct GadgetInfo *ginfo, ULONG flags, Tag firstTag,...)
532 /* struct opUpdate opu;
534 opu.MethodID = OM_NOTIFY;
535 opu.opu_AttrList = (struct TagItem *)&firstTag;
536 opu.opu_GInfo = ginfo;
537 opu.opu_Flags = flags;
539 return DoMethodA(object, (Msg)&opu); */
541 AROS_SLOWSTACKTAGS_PRE_AS(firstTag, ULONG)
542 retval = DoMethod(object, OM_NOTIFY, (IPTR)AROS_SLOWSTACKTAGS_ARG(firstTag), (IPTR)ginfo, (IPTR)flags);
543 AROS_SLOWSTACKTAGS_POST
547 ULONG DoGad_OM_NOTIFY(struct Library *DataTypesBase, Object *object,
548 struct Window *win, struct Requester *req,
549 ULONG flags, Tag firstTag, ...)
551 // return(dogadgetmethod(DataTypesBase, (struct Gadget*)object, win, req, OM_NOTIFY,
552 // &firstTag, NULL, flags));
553 AROS_SLOWSTACKTAGS_PRE_AS(firstTag, ULONG)
554 retval = DoGadgetMethod((struct Gadget*)object, win, req, OM_NOTIFY, AROS_SLOWSTACKTAGS_ARG(firstTag), NULL, flags);
555 AROS_SLOWSTACKTAGS_POST
559 //ULONG dogadgetmethod(struct Library *DataTypesBase, struct Gadget *gad,
560 // struct Window *win, struct Requester *req,
561 // ULONG MethodID, ...)
563 // return(DoGadgetMethodA(gad, win, req, (Msg)&MethodID));
566 struct Catalog *opencatalog(struct Library *DataTypesBase, struct Locale *locale,
567 STRPTR name, Tag firstTag, ...)
569 // return(OpenCatalogA(locale, name, (struct TagItem *)&firstTag));
570 AROS_SLOWSTACKTAGS_PRE_AS(firstTag, struct Catalog *)
571 retval = OpenCatalogA(locale, name, AROS_SLOWSTACKTAGS_ARG(firstTag));
572 AROS_SLOWSTACKTAGS_POST