revert between 56095 -> 55830 in arch
[AROS.git] / workbench / c / AddDataTypes.c
blob2978e5a4190e7f79abd5affe9bef1f31c6c665ba
1 /*
2 Copyright © 1995-2019, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English
7 */
10 /******************************************************************************
12 NAME
14 AddDataTypes (files) [QUIET] [REFRESH] [LIST]
16 SYNOPSIS
18 FILES/M, QUIET/S, REFRESH/S, LIST/S
20 LOCATION
24 FUNCTION
26 AddDataTypes allows you to activate a set of specific DataTypes.
27 This might be necessary if new DataTypes were installed on your
28 system or were not activated on startup.
30 INPUTS
32 FILES -- The name of the file(s) of the corresponding DataType.
33 QUIET -- Won't output any messages
34 REFRESH -- Refreshes the DataTypes list?
35 LIST -- This will display a list of current DataTypes loaded in
36 memory
38 RESULT
40 Standard DOS error codes.
42 NOTES
44 EXAMPLE
46 AddDataTypes gif.datatype REFRESH
48 BUGS
50 SEE ALSO
52 INTERNALS
54 HISTORY
56 ******************************************************************************/
58 #define DEBUG 0
59 #include <aros/debug.h>
61 #include <aros/macros.h>
62 #include <aros/bigendianio.h>
63 #include <exec/types.h>
64 #include <exec/memory.h>
65 #include <exec/execbase.h>
66 #include <dos/dos.h>
67 #include <dos/dosasl.h>
68 #include <dos/dosextens.h>
69 #include <libraries/iffparse.h>
70 #include <utility/name.h>
71 #include <utility/hooks.h>
72 #include <workbench/startup.h>
74 #include <proto/exec.h>
75 #include <proto/alib.h>
76 #include <proto/dos.h>
77 #include <proto/utility.h>
78 #include <proto/iffparse.h>
79 #include <proto/alib.h>
80 #include <proto/arossupport.h>
82 #include <string.h>
84 #include "../libs/datatypes/datatypes_intern.h"
85 #undef DOSBase
86 #undef UtilityBase
87 #undef IFFParseBase
88 #undef LocaleBase
89 #undef DTList
91 /******************************** STRUCTURES *********************************/
93 /* same as datatypes/datatypes.h/struct DataTypeHeader, but always big endian
94 and 32 bit pointers (which in the file are actually offsets) */
96 struct FileDataTypeHeader
98 ULONG fdth_NameOffset; /* Name of the data type */
99 ULONG fdth_BaseNameOffset; /* Base name of the data type */
100 ULONG fdth_PatternOffset; /* File name match pattern */
101 ULONG fdth_MaskOffset; /* Comparision mask (binary) */
102 ULONG fdth_GroupID; /* DataType Group */
103 ULONG fdth_ID; /* DataType ID (same as IFF FORM type) */
104 WORD fdth_MaskLen; /* Length of the comparision mask */
105 WORD fdth_Pad; /* Unused at present (must be 0) */
106 UWORD fdth_Flags; /* Flags -- see below */
107 UWORD fdth_Priority;
110 #define O(x) offsetof(struct FileDataTypeHeader,x)
112 static const IPTR FileDataTypeHeaderDesc[] =
114 sizeof(struct FileDataTypeHeader),
115 SDM_ULONG(O(fdth_NameOffset)),
116 SDM_ULONG(O(fdth_BaseNameOffset)),
117 SDM_ULONG(O(fdth_PatternOffset)),
118 SDM_ULONG(O(fdth_MaskOffset)),
119 SDM_ULONG(O(fdth_GroupID)),
120 SDM_ULONG(O(fdth_ID)),
121 SDM_WORD(O(fdth_MaskLen)),
122 SDM_WORD(O(fdth_Pad)),
123 SDM_UWORD(O(fdth_Flags)),
124 SDM_UWORD(O(fdth_Priority)),
125 SDM_END
128 /******************************** PROTOTYPES *********************************/
130 struct StackVars; /* forward declaration */
132 BOOL DateScan(struct StackVars *sv);
133 void ScanDirectory(struct StackVars *sv, STRPTR pattern);
134 struct DataTypesList *CreateDTList(struct StackVars *sv);
135 struct CompoundDataType *CreateBasicType(struct StackVars *sv,
136 struct List *list,
137 struct List *globallist, STRPTR name,
138 UWORD Flags, ULONG ID, ULONG GroupID);
139 void LoadDataType(struct StackVars *sv, STRPTR name);
140 struct CompoundDataType *CreateDataType(struct StackVars *sv,
141 struct IFFHandle *iff, STRPTR name);
142 struct CompoundDataType *AddDataType(struct StackVars *sv,
143 struct CompoundDataType *cdt);
144 void DeleteDataType(struct StackVars *sv, struct CompoundDataType *cdt);
145 void AlphaInsert(struct StackVars *sv, struct List *list, struct Node *node);
146 struct Node *__FindNameNoCase(struct StackVars *sv, struct List *list,
147 STRPTR name);
149 AROS_UFP4(LONG, AROS_SLIB_ENTRY(ReadFunc, AddDataTypes, 0),
150 AROS_UFPA(BPTR , fh , D1),
151 AROS_UFPA(void * , buf , D2),
152 AROS_UFPA(LONG , size , D3),
153 AROS_UFPA(struct DosLibrary *, DOSBase, A6));
154 AROS_UFP4(LONG, AROS_SLIB_ENTRY(SeekFunc, AddDataTypes, 0),
155 AROS_UFPA(BPTR , fh , D1),
156 AROS_UFPA(LONG , pos , D2),
157 AROS_UFPA(LONG , mode , D3),
158 AROS_UFPA(struct DosLibrary *, DOSBase, A6));
159 AROS_UFP3(UBYTE *, AROS_SLIB_ENTRY(AllocFunc, AddDataTypes, 0),
160 AROS_UFPA(ULONG, size, D0),
161 AROS_UFPA(ULONG, req, D1),
162 AROS_UFPA(struct DosLibrary *, DOSBase, A6));
163 AROS_UFP3(void, AROS_SLIB_ENTRY(FreeFunc, AddDataTypes, 0),
164 AROS_UFPA(APTR , memory, A1),
165 AROS_UFPA(ULONG, size , D0),
166 AROS_UFPA(struct DosLibrary *, DOSBase, A6));
168 /********************************* CONSTANTS *********************************/
170 const TEXT Version[] = "$VER: AddDataTypes 42.2 (20.02.2019)\n";
172 #define EXCL_LEN 18
173 UBYTE ExcludePattern[] = "#?.(info|dbg|backdrop|ppc|arm|i386|x86_64)";
175 UBYTE Template[] = "FILES/M,QUIET/S,REFRESH/S,LIST/S";
177 struct ArgArray
179 UBYTE **aa_Files;
180 IPTR aa_Quiet;
181 IPTR aa_Refresh;
182 IPTR aa_List;
185 #define ID_DTCD MAKE_ID('D','T','C','D')
186 #define ID_DTTL MAKE_ID('D','T','T','L')
188 #define NUM_PROP 2
190 LONG PropArray[2*NUM_PROP]=
192 ID_DTYP, ID_DTHD,
193 ID_DTYP, ID_DTCD
196 #define NUM_COLL 1
198 const LONG CollArray[2*NUM_COLL]=
200 ID_DTYP, ID_DTTL
204 const LONG_FUNC FunctionArray[]=
205 { /* Note! */
206 (LONG_FUNC)AROS_SLIB_ENTRY(ReadFunc, AddDataTypes, 0),
207 (LONG_FUNC)AROS_SLIB_ENTRY(AllocFunc, AddDataTypes, 0),
208 (LONG_FUNC)AROS_SLIB_ENTRY(FreeFunc, AddDataTypes, 0),
209 (LONG_FUNC)AROS_SLIB_ENTRY(SeekFunc, AddDataTypes, 0), /* For ELF */
213 struct StackVars
215 struct DataTypesList *DTList;
216 UBYTE ExclPat[2*EXCL_LEN+2+1];
217 struct ArgArray AA;
218 UBYTE *HookBuffer;
219 ULONG HookBufSize;
220 ULONG HookPosition;
223 #undef SysBase
224 #define DTList sv->DTList
225 #define ExclPat sv->ExclPat
226 #define AA sv->AA
227 #define HookBuffer sv->HookBuffer
228 #define HookBufSize sv->HookBufSize
229 #define HookPosition sv->HookPosition
231 /****** AddDataTypes/main *****************************************************
233 * NAME
234 * main - well... main
236 * SYNOPSIS
238 * FUNCTION
240 * INPUTS
242 * RETURNS
244 * EXAMPLE
246 * SEE ALSO
248 ******************************************************************************
251 int UtilityBase_version = 37;
252 int LocaleBase_version = 37;
253 int IFFParseBase_version = 37;
255 int __nocommandline = 1;
257 int main(void)
259 extern struct WBStartup *WBenchMsg;
260 struct StackVars vars;
261 struct StackVars *sv;
262 int result = RETURN_FAIL;
264 memset(&vars, 0, sizeof(struct StackVars));
265 sv = &vars;
267 if((DTList = CreateDTList(sv)))
269 ParsePatternNoCase(ExcludePattern, ExclPat, sizeof(ExclPat));
271 ObtainSemaphore(&DTList->dtl_Lock);
273 if(WBenchMsg)
275 UWORD num;
276 struct WBArg *wa = &WBenchMsg->sm_ArgList[1];
278 for(num = 1; num<WBenchMsg->sm_NumArgs; wa++)
280 BPTR olddir = CurrentDir(wa->wa_Lock);
281 LoadDataType(sv, wa->wa_Name);
282 CurrentDir(olddir);
285 result = RETURN_OK;
287 else
289 struct RDArgs *RDArgs;
291 if(!(RDArgs = ReadArgs(Template, (SIPTR*)&AA, NULL)))
293 PrintFault(IoErr(), NULL);
295 else
297 if(AA.aa_Refresh)
299 if(DateScan(sv))
301 ScanDirectory(sv, "DEVS:DataTypes");
304 else
306 UBYTE **files = AA.aa_Files;
308 if(files)
310 while(*files)
312 ScanDirectory(sv, *files);
313 files++;
318 if(AA.aa_List)
320 struct DataTypesList *dtl = NULL;
321 struct NamedObject *no = NULL;
322 if((no = FindNamedObject(NULL, DATATYPESLIST, NULL)))
324 dtl = (struct DataTypesList*)no->no_Object;
325 ReleaseNamedObject(no);
326 if(dtl != NULL)
328 struct Node *node=dtl->dtl_SortedList.lh_Head;
329 while(node->ln_Succ != NULL)
331 // sorted list points to DT.dtn_Node2 ....
332 struct CompoundDataType *cdt;
333 struct DataTypeHeader *dth;
335 if(CheckSignal(SIGBREAKF_CTRL_C))
337 Flush(Output());
338 PrintFault(ERROR_BREAK,0);
339 break;
341 cdt=(struct CompoundDataType *)(node-1);
342 dth=cdt->DT.dtn_Header;
344 Printf("%s, \"%s\"\n", dth->dth_BaseName, dth->dth_Name);
345 node = node->ln_Succ;
350 result = RETURN_OK;
351 FreeArgs(RDArgs);
355 ReleaseSemaphore(&DTList->dtl_Lock);
358 return result;
363 /****** AddDataTypes/DateScan *************************************************
365 * NAME
366 * DateScan - See if DataTypes descriptors need updating
368 * SYNOPSIS
370 * FUNCTION
372 * INPUTS
374 * RETURNS
376 * EXAMPLE
378 * SEE ALSO
380 ******************************************************************************
384 BOOL DateScan(struct StackVars *sv)
386 BOOL result = TRUE;
387 BPTR lock;
388 struct FileInfoBlock *fib;
390 if((lock = Lock("DEVS:DataTypes", ACCESS_READ)))
392 if((fib = AllocDosObject(DOS_FIB, NULL)))
394 if(Examine(lock, fib))
396 if(!CompareDates(&fib->fib_Date, &DTList->dtl_DateStamp))
398 result = FALSE;
400 else
402 DTList->dtl_DateStamp = fib->fib_Date;
406 FreeDosObject(DOS_FIB,fib);
409 UnLock(lock);
412 return result;
417 /****** AddDataTypes/ScanDirectory ********************************************
419 * NAME
420 * ScanDirectory - Scan a directory recursively for DT descriptors
422 * SYNOPSIS
424 * FUNCTION
426 * INPUTS
428 * RETURNS
430 * EXAMPLE
432 * SEE ALSO
434 ******************************************************************************
438 void ScanDirectory(struct StackVars *sv, STRPTR pattern)
440 struct AnchorPath *AnchorPath;
441 LONG RetVal;
442 BPTR OldDir;
444 if((AnchorPath = (struct AnchorPath *)AllocVec(sizeof(struct AnchorPath),
445 MEMF_CLEAR)))
447 AnchorPath->ap_BreakBits = SIGBREAKF_CTRL_C;
449 RetVal = MatchFirst(pattern, AnchorPath);
451 while(!RetVal)
453 if(CheckSignal(SIGBREAKF_CTRL_C))
455 if(!AA.aa_Quiet)
457 PrintFault(ERROR_BREAK, NULL);
460 break;
463 if(AnchorPath->ap_Info.fib_DirEntryType > 0L)
465 if(!(AnchorPath->ap_Flags & APF_DIDDIR))
467 AnchorPath->ap_Flags |= APF_DODIR;
470 AnchorPath->ap_Flags &= ~APF_DIDDIR;
472 else
474 if(!MatchPatternNoCase(ExclPat,
475 AnchorPath->ap_Info.fib_FileName))
477 OldDir = CurrentDir(AnchorPath->ap_Current->an_Lock);
479 LoadDataType(sv, AnchorPath->ap_Info.fib_FileName);
481 CurrentDir(OldDir);
485 RetVal = MatchNext(AnchorPath);
488 if(RetVal != ERROR_NO_MORE_ENTRIES)
490 if(!AA.aa_Quiet)
492 PrintFault(RetVal, NULL);
496 MatchEnd(AnchorPath);
498 FreeVec((APTR)AnchorPath);
503 /****** AddDataTypes/CreateDTList *********************************************
505 * NAME
506 * CreateDTList - Create and initialize the DataTypesList
508 * SYNOPSIS
510 * FUNCTION
512 * INPUTS
514 * RETURNS
516 * EXAMPLE
518 * SEE ALSO
520 ******************************************************************************
524 struct DataTypesList *CreateDTList(struct StackVars *sv)
526 struct DataTypesList *dtl = NULL;
527 struct NamedObject *no = NULL;
528 struct Library *DTBase;
530 /* We do this in order to force datatypes.library to get
531 loaded and initialized. During this process it will
532 create and install DataTypes list object in memory. */
533 DTBase = OpenLibrary("datatypes.library", 0);
534 if (DTBase)
535 CloseLibrary(DTBase);
537 if((no = FindNamedObject(NULL, DATATYPESLIST, NULL)))
539 dtl = (struct DataTypesList*)no->no_Object;
542 if(dtl)
544 if(!__FindNameNoCase(sv, &dtl->dtl_BinaryList, "binary"))
546 CreateBasicType
548 sv, &dtl->dtl_BinaryList, &dtl->dtl_SortedList,
549 "binary", DTF_BINARY, ID_BINARY, GID_SYSTEM
553 if(!__FindNameNoCase(sv, &dtl->dtl_ASCIIList, "ascii"))
555 CreateBasicType
557 sv, &dtl->dtl_ASCIIList, &dtl->dtl_SortedList,
558 "ascii", DTF_ASCII, ID_ASCII, GID_TEXT
562 if(!__FindNameNoCase(sv, &dtl->dtl_IFFList, "iff"))
564 CreateBasicType
566 sv, &dtl->dtl_IFFList, &dtl->dtl_SortedList,
567 "iff", DTF_IFF, ID_IFF, GID_SYSTEM
571 if(!__FindNameNoCase(sv, &dtl->dtl_MiscList, "directory"))
573 CreateBasicType
575 sv, &dtl->dtl_MiscList, &dtl->dtl_SortedList,
576 "directory", DTF_MISC, ID_DIRECTORY, GID_SYSTEM
581 if(no)
583 ReleaseNamedObject(no);
587 return dtl;
592 /****** AddDataTypes/CreateBasicType ******************************************
594 * NAME
595 * CreateBasicType - Initialize one of the basic types
597 * SYNOPSIS
599 * FUNCTION
601 * INPUTS
603 * RETURNS
605 * EXAMPLE
607 * SEE ALSO
609 ******************************************************************************
613 struct CompoundDataType *CreateBasicType(struct StackVars *sv,
614 struct List *list,
615 struct List *globallist, STRPTR name,
616 UWORD Flags, ULONG ID, ULONG GroupID)
618 struct CompoundDataType *cdt;
619 ULONG AllocLen = sizeof(struct CompoundDataType) + strlen(name) + 1;
621 if((cdt = AllocVec(AllocLen, MEMF_PUBLIC | MEMF_CLEAR)))
623 cdt->DT.dtn_Header = &cdt->DTH;
625 strcpy((UBYTE*)(cdt + 1), name);
627 cdt->DTH.dth_Name=
628 cdt->DTH.dth_BaseName=
629 cdt->DT.dtn_Node1.ln_Name=
630 cdt->DT.dtn_Node2.ln_Name=(UBYTE*)(cdt + 1);
632 cdt->DTH.dth_GroupID = GroupID;
633 cdt->DTH.dth_ID = ID;
635 cdt->DTH.dth_Flags = Flags;
637 NewList(&cdt->DT.dtn_ToolList);
639 cdt->DT.dtn_Length = AllocLen;
641 cdt->DT.dtn_Node1.ln_Pri = -128;
642 Enqueue(list, &cdt->DT.dtn_Node1);
644 AlphaInsert(sv, globallist, &cdt->DT.dtn_Node2);
647 return cdt;
652 /****** AddDataTypes/LoadDataType *********************************************
654 * NAME
655 * LoadDataType - Load and install a single DataType descriptor
657 * SYNOPSIS
659 * FUNCTION
661 * INPUTS
663 * RETURNS
665 * EXAMPLE
667 * SEE ALSO
669 ******************************************************************************
673 void LoadDataType(struct StackVars *sv, STRPTR name)
675 struct IFFHandle *iff;
677 if((iff = AllocIFF()))
679 if((iff->iff_Stream = (IPTR)Open(name, MODE_OLDFILE))) /* Why IPTR? */
681 InitIFFasDOS(iff);
683 if(!OpenIFF(iff, IFFF_READ))
685 if(!PropChunks(iff, PropArray, NUM_PROP))
687 if(!CollectionChunks(iff, CollArray, NUM_COLL))
689 if(!StopOnExit(iff, ID_DTYP, ID_FORM))
691 LONG error;
693 while((error = ParseIFF(iff, IFFPARSE_SCAN)) == IFFERR_EOC)
695 CreateDataType(sv, iff, name);
696 /* FIXME: The while ParseIFF loop here crashes the 2nd time inside the loop, therefore the break below as temp fix */
697 break;
703 CloseIFF(iff);
706 Close((BPTR)iff->iff_Stream);
709 FreeIFF(iff);
711 else
713 SetIoErr(ERROR_NO_FREE_STORE);
718 /****** AddDataTypes/MemStreamHook *******************************************
720 * NAME
721 * MemStreamHook - needed by ReadStruct
723 * SYNOPSIS
725 * FUNCTION
727 * INPUTS
729 * RETURNS
731 * EXAMPLE
733 * SEE ALSO
735 ******************************************************************************
739 LONG MemStreamHook(struct Hook * hook, UBYTE **memptr, Msg msg)
741 LONG rc;
743 switch (msg->MethodID)
745 case BEIO_READ:
746 rc = **memptr;
747 (*memptr)++;
748 break;
750 default:
751 rc = -1;
752 break;
755 return rc;
758 /****** AddDataTypes/CreateDataType *******************************************
760 * NAME
761 * CreateDataType - create a DataType from IFF chunks
763 * SYNOPSIS
765 * FUNCTION
767 * INPUTS
769 * RETURNS
771 * EXAMPLE
773 * SEE ALSO
775 ******************************************************************************
779 struct CompoundDataType *CreateDataType(struct StackVars *sv,
780 struct IFFHandle *iff, STRPTR name)
782 struct CompoundDataType *cdt = NULL;
783 struct StoredProperty *prop;
784 #if __mc68000
785 LONG DefaultStack = AROS_STACKSIZE;
786 UBYTE *func;
787 #endif
788 ULONG AllocLen, i;
789 BPTR SegList;
791 if((prop = FindProp(iff, ID_DTYP, ID_DTHD)))
793 D(bug("[AddDataTypes] sp_Size = %d", prop->sp_Size));
794 AllocLen = sizeof(struct CompoundDataType) -
795 32 + /* was sizeof(struct DataTypeHeader), but we must use struct size as it would be on Amiga */
796 prop->sp_Size;
798 if(!(cdt = AllocVec(AllocLen, MEMF_PUBLIC | MEMF_CLEAR)))
800 SetIoErr(ERROR_NO_FREE_STORE);
802 else
804 struct FileDataTypeHeader *fdh = NULL;
805 UBYTE *memptr = (UBYTE *)prop->sp_Data;
806 struct Hook hook;
808 D(bug("[AddDataTypes] CDT @ 0x%p\n", cdt));
809 hook.h_Entry = (HOOKFUNC)HookEntry;
810 hook.h_SubEntry = (HOOKFUNC)MemStreamHook;
812 if (ReadStruct(&hook, (APTR *) &fdh, &memptr, FileDataTypeHeaderDesc))
814 IPTR extraoffset = sizeof(struct DataTypeHeader) - 32;
816 D(bug("[AddDataTypes] fdth_MaskOffset = %d\n", fdh->fdth_MaskOffset));
818 cdt->DT.dtn_Header= &cdt->DTH;
820 cdt->DTH.dth_Name = (STRPTR)(fdh->fdth_NameOffset + extraoffset + (IPTR)&cdt->DTH);
821 cdt->DTH.dth_BaseName = (STRPTR)(fdh->fdth_BaseNameOffset + extraoffset + (IPTR)&cdt->DTH);
822 cdt->DTH.dth_Pattern = (STRPTR)(fdh->fdth_PatternOffset + extraoffset + (IPTR)&cdt->DTH);
823 cdt->DTH.dth_Mask = (WORD *)(fdh->fdth_MaskOffset + extraoffset + (IPTR)&cdt->DTH);
824 cdt->DTH.dth_GroupID = fdh->fdth_GroupID;
825 cdt->DTH.dth_ID = fdh->fdth_ID;
826 cdt->DTH.dth_MaskLen = fdh->fdth_MaskLen;
827 cdt->DTH.dth_Pad = fdh->fdth_Pad;
828 cdt->DTH.dth_Flags = fdh->fdth_Flags;
829 cdt->DTH.dth_Priority = fdh->fdth_Priority;
831 CopyMem(prop->sp_Data + 32, cdt + 1, prop->sp_Size - 32);
834 bug("[AddDataTypes] groupid = %c%c%c%c\n", cdt->DTH.dth_GroupID >> 24,
835 cdt->DTH.dth_GroupID >> 16,
836 cdt->DTH.dth_GroupID >> 8,
837 cdt->DTH.dth_GroupID);
838 bug("[AddDataTypes] id = %c%c%c%c\n", cdt->DTH.dth_ID >> 24,
839 cdt->DTH.dth_ID >> 16,
840 cdt->DTH.dth_ID >> 8,
841 cdt->DTH.dth_ID);
842 bug("[AddDataTypes] flags = %x\n", cdt->DTH.dth_Flags);
843 bug("[AddDataTypes] pri = %d\n", cdt->DTH.dth_Priority);
844 bug("[AddDataTypes] name = %s\n", cdt->DTH.dth_Name);
845 bug("[AddDataTypes] basename = %s\n", cdt->DTH.dth_BaseName);
846 bug("[AddDataTypes] pattern = %s\n", cdt->DTH.dth_Pattern);
847 bug("[AddDataTypes] masklen = %d\n", cdt->DTH.dth_MaskLen);
849 for(i = 0; i < cdt->DTH.dth_MaskLen; i++)
851 cdt->DTH.dth_Mask[i] = AROS_BE2WORD(cdt->DTH.dth_Mask[i]);
852 D(bug("[AddDataTypes] mask[%d] = %04x (%c %c)\n", i,
853 cdt->DTH.dth_Mask[i],
854 cdt->DTH.dth_Mask[i] & 255,
855 (cdt->DTH.dth_Mask[i] >> 8) & 255);)
858 NewList(&cdt->DT.dtn_ToolList);
860 cdt->DT.dtn_Length = AllocLen;
862 #if __mc68000
863 if((prop = FindProp(iff, ID_DTYP, ID_DTCD)))
865 if((func = AllocVec(prop->sp_Size, MEMF_PUBLIC | MEMF_CLEAR)))
867 cdt->DTCDChunk = func;
868 cdt->DTCDSize = prop->sp_Size;
870 CopyMem(prop->sp_Data,func,prop->sp_Size);
872 HookBuffer = cdt->DTCDChunk;
873 HookBufSize = cdt->DTCDSize;
874 HookPosition = 0;
876 /* We use a cast to BPTR, since sv may not
877 * be ULONG aligned. Since only our ReadFunc
878 * is going to be looking at it, this is ok.
880 if((SegList = InternalLoadSeg((BPTR)(sv), BNULL,
881 (LONG_FUNC *)FunctionArray,
882 &DefaultStack)))
884 cdt->SegList = SegList;
885 cdt->Function = BADDR(SegList) + sizeof(BPTR);
888 } /* if((func = AllocVec(prop->sp_Size, MEMF_PUBLIC | MEMF_CLEAR))) */
890 } /* if((prop = FindProp(iff, ID_DTYP, ID_DTCD))) */
891 #else
892 TEXT CDname[256];
894 __sprintf(CDname,"%s.%s", name, TARGETCPU);
895 D(bug("[AddDataTypes] Checking for '%s'\n", CDname);)
897 if((SegList = LoadSeg(CDname)))
899 D(bug("[AddDataTypes] Found!\n");)
900 cdt->SegList = SegList;
901 cdt->Function = BADDR(SegList) + sizeof(BPTR);
902 D(bug("[AddDataTypes] Entry @ 0x%p\n", cdt->Function);)
904 #endif
905 cdt = AddDataType(sv, cdt);
907 FreeStruct(fdh, FileDataTypeHeaderDesc);
909 } /* if (ReadStruct(&hook, &fdh, &memptr, FileDataTypeHeaderDesc)) */
911 } /* cdt AllocVec okay */
913 } /* if((prop = FindProp(iff, ID_DTYP, ID_DTHD))) */
915 return cdt;
920 /****** AddDataTypes/AddDataType **********************************************
922 * NAME
923 * AddDataType - add a DataType to the system
925 * SYNOPSIS
927 * FUNCTION
929 * This subroutine tries to add a DataType to the system DataTypes
930 * list. If the DataType already exists, it will be replaced or
931 * updated. In case of an error, the CompoundDataType will be deleted
932 * and a NULL pointer is returned.
934 * The CompoundDataType pointer you passed in will be invalid after
935 * calling this function. Use the returned handle instead.
936 * DO NOT USE THE OLD POINTER IN ANY MORE!
938 * INPUTS
940 * RETURNS
942 * A pointer to a CompoundDataType in the system DataTypes list
943 * or a NULL pointer for failure
945 * EXAMPLE
947 * SEE ALSO
949 ******************************************************************************
953 struct CompoundDataType *AddDataType(struct StackVars *sv,
954 struct CompoundDataType *cdt)
956 struct List *typelist;
957 BOOL Success = FALSE;
958 ULONG AllocSize;
959 ULONG result;
960 struct CompoundDataType *oldcdt;
962 switch(cdt->DTH.dth_Flags & DTF_TYPE_MASK)
964 case DTF_BINARY: typelist= &DTList->dtl_BinaryList; break;
965 case DTF_ASCII: typelist= &DTList->dtl_ASCIIList; break;
966 case DTF_IFF: typelist= &DTList->dtl_IFFList; break;
967 case DTF_MISC: typelist= &DTList->dtl_MiscList; break;
968 default: typelist= NULL;
971 if(typelist)
973 cdt->DT.dtn_Node1.ln_Name = cdt->DT.dtn_Node2.ln_Name = cdt->DTH.dth_Name;
975 Success = TRUE;
977 if((!Stricmp(cdt->DTH.dth_Pattern, "#?")) ||
978 (!strlen(cdt->DTH.dth_Pattern)) )
980 cdt->FlagLong |= CFLGF_PATTERN_UNUSED;
982 else
984 cdt->FlagLong &= ~(CFLGF_PATTERN_UNUSED);
986 AllocSize = 2*strlen(cdt->DTH.dth_Pattern) + 2;
988 if(!(cdt->ParsePatMem = AllocVec(AllocSize,
989 MEMF_PUBLIC | MEMF_CLEAR)))
991 Success = FALSE;
993 else
995 cdt->ParsePatSize = AllocSize;
997 result = ParsePatternNoCase(cdt->DTH.dth_Pattern,
998 cdt->ParsePatMem, AllocSize);
1000 if(result == 1)
1002 cdt->FlagLong |= CFLGF_IS_WILD;
1004 else
1006 FreeVec(cdt->ParsePatMem);
1007 cdt->ParsePatMem = NULL;
1008 cdt->ParsePatSize = 0;
1010 if(result == 0)
1012 cdt->FlagLong &= ~(CFLGF_IS_WILD);
1014 else
1016 Success = FALSE;
1022 if (Success)
1024 if((oldcdt = (struct CompoundDataType*)__FindNameNoCase(sv,
1025 typelist,
1026 cdt->DT.dtn_Node1.ln_Name)))
1028 if (oldcdt->OpenCount)
1030 Success = FALSE;
1032 else
1034 if((Stricmp(oldcdt->DTH.dth_Name, cdt->DTH.dth_Name)) ||
1035 (Stricmp(oldcdt->DTH.dth_BaseName, cdt->DTH.dth_BaseName)) ||
1036 (Stricmp(oldcdt->DTH.dth_Pattern, cdt->DTH.dth_Pattern)) ||
1037 (oldcdt->DTH.dth_Flags != cdt->DTH.dth_Flags) ||
1038 (oldcdt->DTH.dth_Priority != cdt->DTH.dth_Priority) ||
1039 (oldcdt->DTH.dth_MaskLen != cdt->DTH.dth_MaskLen))
1041 DeleteDataType(sv, oldcdt);
1042 oldcdt = NULL;
1044 else
1046 oldcdt->DTH.dth_GroupID = cdt->DTH.dth_GroupID;
1047 oldcdt->DTH.dth_ID = cdt->DTH.dth_ID;
1048 CopyMem(cdt->DTH.dth_Mask, oldcdt->DTH.dth_Mask,
1049 (ULONG)(sizeof(WORD)*cdt->DTH.dth_MaskLen));
1054 if(Success)
1056 if(oldcdt)
1058 DeleteDataType(sv, cdt);
1059 cdt = oldcdt;
1061 else
1063 if(cdt->DT.dtn_FunctionName)
1065 LONG DefaultStack = 4096;
1066 BPTR file;
1067 ULONG AllocLen;
1068 BPTR SegList;
1070 if((file = Open(cdt->DT.dtn_FunctionName, MODE_OLDFILE)))
1072 if(Seek(file, 0, OFFSET_END) >= 0)
1074 if((AllocLen = Seek(file, 0,
1075 OFFSET_BEGINNING)) > 0)
1077 if((cdt->DTCDChunk = AllocVec(AllocLen,
1078 MEMF_PUBLIC | MEMF_CLEAR)))
1080 cdt->DTCDSize = AllocLen;
1082 if(Read(file, cdt->DTCDChunk, AllocLen) == AllocLen)
1084 HookBuffer = cdt->DTCDChunk;
1085 HookBufSize = cdt->DTCDSize;
1086 HookPosition = 0;
1088 /* We use a cast to BPTR, since sv may not
1089 * be ULONG aligned. Since only our ReadFunc
1090 * is going to be looking at it, this is ok.
1092 if((SegList = InternalLoadSeg((BPTR)(sv), BNULL, (LONG_FUNC *)FunctionArray, &DefaultStack)))
1094 cdt->SegList = SegList;
1095 cdt->Function = BADDR(SegList) + sizeof(BPTR); // FIXME: is this portable?
1098 else
1100 FreeVec(cdt->DTCDChunk);
1101 cdt->DTCDChunk = NULL;
1102 cdt->DTCDSize = 0;
1108 cdt->DT.dtn_FunctionName=NULL;
1111 if(cdt->DTH.dth_MaskLen > DTList->dtl_LongestMask)
1113 DTList->dtl_LongestMask = cdt->DTH.dth_MaskLen;
1116 cdt->DT.dtn_Node1.ln_Pri = cdt->DTH.dth_Priority;
1117 Enqueue(typelist, &cdt->DT.dtn_Node1);
1119 AlphaInsert(sv, &DTList->dtl_SortedList, &cdt->DT.dtn_Node2);
1125 if(!Success)
1127 DeleteDataType(sv, cdt);
1128 cdt = NULL;
1131 return cdt;
1136 /****** AddDataTypes/DeleteDataType *******************************************
1138 * NAME
1139 * DeleteDataType - unlink and deallocate a CompoundDataType structure
1141 * SYNOPSIS
1143 * FUNCTION
1145 * INPUTS
1147 * RETURNS
1149 * EXAMPLE
1151 * SEE ALSO
1153 ******************************************************************************
1157 void DeleteDataType(struct StackVars *sv, struct CompoundDataType *cdt)
1159 if(cdt)
1161 if(cdt->ParsePatMem)
1163 FreeVec(cdt->ParsePatMem);
1164 cdt->ParsePatMem = NULL;
1165 cdt->ParsePatSize = 0;
1168 if(cdt->DTCDChunk)
1170 FreeVec(cdt->DTCDChunk);
1171 cdt->DTCDChunk = NULL;
1172 cdt->DTCDSize = 0;
1175 if(cdt->SegList)
1177 UnLoadSeg(cdt->SegList);
1178 cdt->SegList = BNULL;
1179 cdt->Function = NULL;
1182 if(cdt->DT.dtn_Node1.ln_Succ && cdt->DT.dtn_Node1.ln_Pred)
1184 Remove(&cdt->DT.dtn_Node1);
1185 Remove(&cdt->DT.dtn_Node2);
1186 cdt->DT.dtn_Node1.ln_Succ = cdt->DT.dtn_Node1.ln_Pred =
1187 cdt->DT.dtn_Node2.ln_Succ = cdt->DT.dtn_Node2.ln_Pred = NULL;
1190 FreeVec(cdt);
1196 /****** AddDataTypes/AlphaInsert **********************************************
1198 * NAME
1199 * AlphaInsert - enqueue a node alphabetically into a list
1201 * SYNOPSIS
1203 * FUNCTION
1205 * INPUTS
1207 * RETURNS
1209 * EXAMPLE
1211 * SEE ALSO
1213 ******************************************************************************
1217 void AlphaInsert(struct StackVars *sv, struct List *list, struct Node *node)
1219 struct Node *cur,*prev=NULL;
1221 for(cur = list->lh_Head; cur->ln_Succ; prev = cur, cur = cur->ln_Succ)
1223 if(Stricmp(cur->ln_Name, node->ln_Name) > 0)
1224 break;
1227 Insert(list, node, prev);
1232 /****** AddDataTypes/__FindNameNoCase *****************************************
1234 * NAME
1235 * __FindNameNoCase - find a node in a list (case insensitive)
1237 * SYNOPSIS
1239 * FUNCTION
1241 * INPUTS
1243 * RETURNS
1245 * EXAMPLE
1247 * SEE ALSO
1249 ******************************************************************************
1253 struct Node *__FindNameNoCase(struct StackVars *sv, struct List *list,
1254 STRPTR name)
1256 struct Node *node;
1257 struct Node *result = NULL;
1259 for(node = list->lh_Head; node->ln_Succ; node = node->ln_Succ)
1261 if(!Stricmp(node->ln_Name, name))
1263 result = node;
1264 break;
1268 return result;
1273 /****** AddDataTypes/ReadFunc *************************************************
1275 * NAME
1276 * ReadFunc - data read hook for InternalLoadSeg
1278 * SYNOPSIS
1280 * FUNCTION
1282 * INPUTS
1284 * RETURNS
1286 * EXAMPLE
1288 * SEE ALSO
1290 ******************************************************************************
1294 AROS_UFH4(LONG, AROS_SLIB_ENTRY(ReadFunc, AddDataTypes, 0),
1295 AROS_UFHA(BPTR , fh , D1),
1296 AROS_UFHA(void * , buffer , D2),
1297 AROS_UFHA(LONG , length , D3),
1298 AROS_UFHA(struct DosLibrary *, DOSBase, A6))
1300 AROS_USERFUNC_INIT
1302 struct StackVars *sv = (APTR)fh;
1303 LONG maxlen = HookBufSize-HookPosition;
1304 LONG actual = length > maxlen ? maxlen : length;
1306 CopyMem(HookBuffer+HookPosition, buffer, actual);
1308 HookPosition += actual;
1310 return actual;
1312 AROS_USERFUNC_EXIT
1315 /****** AddDataTypes/SeekFunc *************************************************
1317 * NAME
1318 * SeekFunc - seek hook for InternalLoadSeg (ELF only)
1320 * SYNOPSIS
1322 * FUNCTION
1324 * INPUTS
1326 * RETURNS
1328 * EXAMPLE
1330 * SEE ALSO
1332 ******************************************************************************
1336 AROS_UFH4(LONG, AROS_SLIB_ENTRY(SeekFunc, AddDataTypes, 0),
1337 AROS_UFHA(BPTR , fh , D1),
1338 AROS_UFHA(LONG , pos , D2),
1339 AROS_UFHA(LONG , mode , D3),
1340 AROS_UFHA(struct DosLibrary *, DOSBase, A6))
1342 AROS_USERFUNC_INIT
1344 struct StackVars *sv = (APTR)fh;
1345 LONG oldpos = HookPosition;
1347 switch (mode) {
1348 case OFFSET_BEGINNING: break;
1349 case OFFSET_END: pos = HookBufSize - pos; break;
1350 case OFFSET_CURRENT: pos = HookPosition + pos; break;
1351 default: return -1;
1354 if (pos < 0 || pos >= HookBufSize)
1355 return -1;
1357 HookPosition = pos;
1359 return oldpos;
1361 AROS_USERFUNC_EXIT
1364 /****** AddDataTypes/AllocFunc ************************************************
1366 * NAME
1367 * AllocFunc - memory allocation hook for InternalLoadSeg
1369 * SYNOPSIS
1371 * FUNCTION
1373 * INPUTS
1375 * RETURNS
1377 * EXAMPLE
1379 * SEE ALSO
1381 ******************************************************************************
1385 AROS_UFH3(UBYTE *, AROS_SLIB_ENTRY(AllocFunc, AddDataTypes, 0),
1386 AROS_UFHA(ULONG, size, D0),
1387 AROS_UFHA(ULONG, flags,D1),
1388 AROS_UFHA(struct DosLibrary *, DOSBase, A6))
1390 AROS_USERFUNC_INIT
1392 return(AllocMem(size, flags));
1394 AROS_USERFUNC_EXIT
1399 /****** AddDataTypes/FreeFunc *************************************************
1401 * NAME
1402 * FreeFunc - memory freeing hook for InternalLoadSeg
1404 * SYNOPSIS
1406 * FUNCTION
1408 * INPUTS
1410 * RETURNS
1412 * EXAMPLE
1414 * SEE ALSO
1416 ******************************************************************************
1420 AROS_UFH3(void, AROS_SLIB_ENTRY(FreeFunc, AddDataTypes, 0),
1421 AROS_UFHA(APTR , memory, A1),
1422 AROS_UFHA(ULONG, size , D0),
1423 AROS_UFHA(struct DosLibrary *, DOSBase, A6))
1425 AROS_USERFUNC_INIT
1427 FreeMem(memory, size);
1429 AROS_USERFUNC_EXIT
1434 /******************************* STUB ROUTINES ********************************/
1436 struct NamedObject *allocnamedobject(struct StackVars *sv, STRPTR name,
1437 Tag FirstTag, ...)
1439 return AllocNamedObjectA(name, (struct TagItem*)&FirstTag);