2 Copyright © 1995-2019, The AROS Development Team. All rights reserved.
10 /******************************************************************************
14 AddDataTypes (files) [QUIET] [REFRESH] [LIST]
18 FILES/M, QUIET/S, REFRESH/S, LIST/S
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.
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
40 Standard DOS error codes.
46 AddDataTypes gif.datatype REFRESH
56 ******************************************************************************/
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>
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>
84 #include "../libs/datatypes/datatypes_intern.h"
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 */
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
)),
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
,
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
,
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";
173 UBYTE ExcludePattern
[] = "#?.(info|dbg|backdrop|ppc|arm|i386|x86_64)";
175 UBYTE Template
[] = "FILES/M,QUIET/S,REFRESH/S,LIST/S";
185 #define ID_DTCD MAKE_ID('D','T','C','D')
186 #define ID_DTTL MAKE_ID('D','T','T','L')
190 LONG PropArray
[2*NUM_PROP
]=
198 const LONG CollArray
[2*NUM_COLL
]=
204 const LONG_FUNC FunctionArray
[]=
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 */
215 struct DataTypesList
*DTList
;
216 UBYTE ExclPat
[2*EXCL_LEN
+2+1];
224 #define DTList sv->DTList
225 #define ExclPat sv->ExclPat
227 #define HookBuffer sv->HookBuffer
228 #define HookBufSize sv->HookBufSize
229 #define HookPosition sv->HookPosition
231 /****** AddDataTypes/main *****************************************************
234 * main - well... main
248 ******************************************************************************
251 int UtilityBase_version
= 37;
252 int LocaleBase_version
= 37;
253 int IFFParseBase_version
= 37;
255 int __nocommandline
= 1;
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
));
267 if((DTList
= CreateDTList(sv
)))
269 ParsePatternNoCase(ExcludePattern
, ExclPat
, sizeof(ExclPat
));
271 ObtainSemaphore(&DTList
->dtl_Lock
);
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
);
289 struct RDArgs
*RDArgs
;
291 if(!(RDArgs
= ReadArgs(Template
, (SIPTR
*)&AA
, NULL
)))
293 PrintFault(IoErr(), NULL
);
301 ScanDirectory(sv
, "DEVS:DataTypes");
306 UBYTE
**files
= AA
.aa_Files
;
312 ScanDirectory(sv
, *files
);
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
);
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
))
338 PrintFault(ERROR_BREAK
,0);
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
;
355 ReleaseSemaphore(&DTList
->dtl_Lock
);
363 /****** AddDataTypes/DateScan *************************************************
366 * DateScan - See if DataTypes descriptors need updating
380 ******************************************************************************
384 BOOL
DateScan(struct StackVars
*sv
)
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
))
402 DTList
->dtl_DateStamp
= fib
->fib_Date
;
406 FreeDosObject(DOS_FIB
,fib
);
417 /****** AddDataTypes/ScanDirectory ********************************************
420 * ScanDirectory - Scan a directory recursively for DT descriptors
434 ******************************************************************************
438 void ScanDirectory(struct StackVars
*sv
, STRPTR pattern
)
440 struct AnchorPath
*AnchorPath
;
444 if((AnchorPath
= (struct AnchorPath
*)AllocVec(sizeof(struct AnchorPath
),
447 AnchorPath
->ap_BreakBits
= SIGBREAKF_CTRL_C
;
449 RetVal
= MatchFirst(pattern
, AnchorPath
);
453 if(CheckSignal(SIGBREAKF_CTRL_C
))
457 PrintFault(ERROR_BREAK
, NULL
);
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
;
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
);
485 RetVal
= MatchNext(AnchorPath
);
488 if(RetVal
!= ERROR_NO_MORE_ENTRIES
)
492 PrintFault(RetVal
, NULL
);
496 MatchEnd(AnchorPath
);
498 FreeVec((APTR
)AnchorPath
);
503 /****** AddDataTypes/CreateDTList *********************************************
506 * CreateDTList - Create and initialize the DataTypesList
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);
535 CloseLibrary(DTBase
);
537 if((no
= FindNamedObject(NULL
, DATATYPESLIST
, NULL
)))
539 dtl
= (struct DataTypesList
*)no
->no_Object
;
544 if(!__FindNameNoCase(sv
, &dtl
->dtl_BinaryList
, "binary"))
548 sv
, &dtl
->dtl_BinaryList
, &dtl
->dtl_SortedList
,
549 "binary", DTF_BINARY
, ID_BINARY
, GID_SYSTEM
553 if(!__FindNameNoCase(sv
, &dtl
->dtl_ASCIIList
, "ascii"))
557 sv
, &dtl
->dtl_ASCIIList
, &dtl
->dtl_SortedList
,
558 "ascii", DTF_ASCII
, ID_ASCII
, GID_TEXT
562 if(!__FindNameNoCase(sv
, &dtl
->dtl_IFFList
, "iff"))
566 sv
, &dtl
->dtl_IFFList
, &dtl
->dtl_SortedList
,
567 "iff", DTF_IFF
, ID_IFF
, GID_SYSTEM
571 if(!__FindNameNoCase(sv
, &dtl
->dtl_MiscList
, "directory"))
575 sv
, &dtl
->dtl_MiscList
, &dtl
->dtl_SortedList
,
576 "directory", DTF_MISC
, ID_DIRECTORY
, GID_SYSTEM
583 ReleaseNamedObject(no
);
592 /****** AddDataTypes/CreateBasicType ******************************************
595 * CreateBasicType - Initialize one of the basic types
609 ******************************************************************************
613 struct CompoundDataType
*CreateBasicType(struct StackVars
*sv
,
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
);
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
);
652 /****** AddDataTypes/LoadDataType *********************************************
655 * LoadDataType - Load and install a single DataType descriptor
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? */
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
))
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 */
706 Close((BPTR
)iff
->iff_Stream
);
713 SetIoErr(ERROR_NO_FREE_STORE
);
718 /****** AddDataTypes/MemStreamHook *******************************************
721 * MemStreamHook - needed by ReadStruct
735 ******************************************************************************
739 LONG
MemStreamHook(struct Hook
* hook
, UBYTE
**memptr
, Msg msg
)
743 switch (msg
->MethodID
)
758 /****** AddDataTypes/CreateDataType *******************************************
761 * CreateDataType - create a DataType from IFF chunks
775 ******************************************************************************
779 struct CompoundDataType
*CreateDataType(struct StackVars
*sv
,
780 struct IFFHandle
*iff
, STRPTR name
)
782 struct CompoundDataType
*cdt
= NULL
;
783 struct StoredProperty
*prop
;
785 LONG DefaultStack
= AROS_STACKSIZE
;
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 */
798 if(!(cdt
= AllocVec(AllocLen
, MEMF_PUBLIC
| MEMF_CLEAR
)))
800 SetIoErr(ERROR_NO_FREE_STORE
);
804 struct FileDataTypeHeader
*fdh
= NULL
;
805 UBYTE
*memptr
= (UBYTE
*)prop
->sp_Data
;
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,
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
;
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
;
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
,
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))) */
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
);)
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))) */
920 /****** AddDataTypes/AddDataType **********************************************
923 * AddDataType - add a DataType to the system
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!
942 * A pointer to a CompoundDataType in the system DataTypes list
943 * or a NULL pointer for failure
949 ******************************************************************************
953 struct CompoundDataType
*AddDataType(struct StackVars
*sv
,
954 struct CompoundDataType
*cdt
)
956 struct List
*typelist
;
957 BOOL Success
= FALSE
;
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
;
973 cdt
->DT
.dtn_Node1
.ln_Name
= cdt
->DT
.dtn_Node2
.ln_Name
= cdt
->DTH
.dth_Name
;
977 if((!Stricmp(cdt
->DTH
.dth_Pattern
, "#?")) ||
978 (!strlen(cdt
->DTH
.dth_Pattern
)) )
980 cdt
->FlagLong
|= CFLGF_PATTERN_UNUSED
;
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
)))
995 cdt
->ParsePatSize
= AllocSize
;
997 result
= ParsePatternNoCase(cdt
->DTH
.dth_Pattern
,
998 cdt
->ParsePatMem
, AllocSize
);
1002 cdt
->FlagLong
|= CFLGF_IS_WILD
;
1006 FreeVec(cdt
->ParsePatMem
);
1007 cdt
->ParsePatMem
= NULL
;
1008 cdt
->ParsePatSize
= 0;
1012 cdt
->FlagLong
&= ~(CFLGF_IS_WILD
);
1024 if((oldcdt
= (struct CompoundDataType
*)__FindNameNoCase(sv
,
1026 cdt
->DT
.dtn_Node1
.ln_Name
)))
1028 if (oldcdt
->OpenCount
)
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
);
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
));
1058 DeleteDataType(sv
, cdt
);
1063 if(cdt
->DT
.dtn_FunctionName
)
1065 LONG DefaultStack
= 4096;
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
;
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?
1100 FreeVec(cdt
->DTCDChunk
);
1101 cdt
->DTCDChunk
= NULL
;
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
);
1127 DeleteDataType(sv
, cdt
);
1136 /****** AddDataTypes/DeleteDataType *******************************************
1139 * DeleteDataType - unlink and deallocate a CompoundDataType structure
1153 ******************************************************************************
1157 void DeleteDataType(struct StackVars
*sv
, struct CompoundDataType
*cdt
)
1161 if(cdt
->ParsePatMem
)
1163 FreeVec(cdt
->ParsePatMem
);
1164 cdt
->ParsePatMem
= NULL
;
1165 cdt
->ParsePatSize
= 0;
1170 FreeVec(cdt
->DTCDChunk
);
1171 cdt
->DTCDChunk
= NULL
;
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
;
1196 /****** AddDataTypes/AlphaInsert **********************************************
1199 * AlphaInsert - enqueue a node alphabetically into a list
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)
1227 Insert(list
, node
, prev
);
1232 /****** AddDataTypes/__FindNameNoCase *****************************************
1235 * __FindNameNoCase - find a node in a list (case insensitive)
1249 ******************************************************************************
1253 struct Node
*__FindNameNoCase(struct StackVars
*sv
, struct List
*list
,
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
))
1273 /****** AddDataTypes/ReadFunc *************************************************
1276 * ReadFunc - data read hook for InternalLoadSeg
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
))
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
;
1315 /****** AddDataTypes/SeekFunc *************************************************
1318 * SeekFunc - seek hook for InternalLoadSeg (ELF only)
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
))
1344 struct StackVars
*sv
= (APTR
)fh
;
1345 LONG oldpos
= HookPosition
;
1348 case OFFSET_BEGINNING
: break;
1349 case OFFSET_END
: pos
= HookBufSize
- pos
; break;
1350 case OFFSET_CURRENT
: pos
= HookPosition
+ pos
; break;
1354 if (pos
< 0 || pos
>= HookBufSize
)
1364 /****** AddDataTypes/AllocFunc ************************************************
1367 * AllocFunc - memory allocation hook for InternalLoadSeg
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
))
1392 return(AllocMem(size
, flags
));
1399 /****** AddDataTypes/FreeFunc *************************************************
1402 * FreeFunc - memory freeing hook for InternalLoadSeg
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
))
1427 FreeMem(memory
, size
);
1434 /******************************* STUB ROUTINES ********************************/
1436 struct NamedObject
*allocnamedobject(struct StackVars
*sv
, STRPTR name
,
1439 return AllocNamedObjectA(name
, (struct TagItem
*)&FirstTag
);