2 Copyright © 1995-2010, 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 Datatype list?
35 LIST -- This will display a list of current datatypes loaded in
40 Standard DOS error codes.
46 AddDataTypes gif.datatype REFRESH
56 ******************************************************************************/
58 #include <aros/macros.h>
59 #include <aros/bigendianio.h>
60 #include <exec/types.h>
61 #include <exec/memory.h>
62 #include <exec/execbase.h>
64 #include <dos/dosasl.h>
65 #include <dos/dosextens.h>
66 #include <libraries/iffparse.h>
67 #include <utility/name.h>
68 #include <utility/hooks.h>
69 #include <workbench/startup.h>
71 #include <proto/exec.h>
72 #include <proto/dos.h>
73 #include <proto/utility.h>
74 #include <proto/iffparse.h>
75 #include <proto/alib.h>
76 #include <proto/arossupport.h>
80 #include "../libs/datatypes/datatypes_intern.h"
87 /******************************** STRUCTURES *********************************/
89 /* same as datatypes/datatypes.h/struct DataTypeHeader, but always big endian
90 and 32 bit pointers (which in the file are actually offsets) */
92 struct FileDataTypeHeader
94 ULONG fdth_NameOffset
; /* Name of the data type */
95 ULONG fdth_BaseNameOffset
; /* Base name of the data type */
96 ULONG fdth_PatternOffset
; /* File name match pattern */
97 ULONG fdth_MaskOffset
; /* Comparision mask (binary) */
98 ULONG fdth_GroupID
; /* DataType Group */
99 ULONG fdth_ID
; /* DataType ID (same as IFF FORM type) */
100 WORD fdth_MaskLen
; /* Length of the comparision mask */
101 WORD fdth_Pad
; /* Unused at present (must be 0) */
102 UWORD fdth_Flags
; /* Flags -- see below */
106 #define O(x) offsetof(struct FileDataTypeHeader,x)
108 static const IPTR FileDataTypeHeaderDesc
[] =
110 sizeof(struct FileDataTypeHeader
),
111 SDM_ULONG(O(fdth_NameOffset
)),
112 SDM_ULONG(O(fdth_BaseNameOffset
)),
113 SDM_ULONG(O(fdth_PatternOffset
)),
114 SDM_ULONG(O(fdth_MaskOffset
)),
115 SDM_ULONG(O(fdth_GroupID
)),
116 SDM_ULONG(O(fdth_ID
)),
117 SDM_WORD(O(fdth_MaskLen
)),
118 SDM_WORD(O(fdth_Pad
)),
119 SDM_UWORD(O(fdth_Flags
)),
120 SDM_UWORD(O(fdth_Priority
)),
124 /******************************** PROTOTYPES *********************************/
126 struct StackVars
; /* forward declaration */
128 BOOL
DateScan(struct StackVars
*sv
);
129 void ScanDirectory(struct StackVars
*sv
, STRPTR pattern
);
130 struct DataTypesList
*CreateDTList(struct StackVars
*sv
);
131 struct CompoundDatatype
*CreateBasicType(struct StackVars
*sv
,
133 struct List
*globallist
, STRPTR name
,
134 UWORD Flags
, ULONG ID
, ULONG GroupID
);
135 void LoadDatatype(struct StackVars
*sv
, STRPTR name
);
136 struct CompoundDatatype
*CreateDatatype(struct StackVars
*sv
,
137 struct IFFHandle
*iff
);
138 struct CompoundDatatype
*AddDatatype(struct StackVars
*sv
,
139 struct CompoundDatatype
*cdt
);
140 void DeleteDatatype(struct StackVars
*sv
, struct CompoundDatatype
*cdt
);
141 void AlphaInsert(struct StackVars
*sv
, struct List
*list
, struct Node
*node
);
142 void PrioInsert(struct StackVars
*sv
, struct List
*list
,
143 struct CompoundDatatype
*cdt
);
144 struct Node
*__FindNameNoCase(struct StackVars
*sv
, struct List
*list
,
147 AROS_UFP4(LONG
, AROS_SLIB_ENTRY(ReadFunc
, AddDatatypes
, 0),
148 AROS_UFPA(BPTR
, fh
, D1
),
149 AROS_UFPA(void * , buf
, D2
),
150 AROS_UFPA(LONG
, size
, D3
),
151 AROS_UFPA(struct DosLibrary
*, DOSBase
, A6
));
152 AROS_UFP4(LONG
, AROS_SLIB_ENTRY(SeekFunc
, AddDatatypes
, 0),
153 AROS_UFPA(BPTR
, fh
, D1
),
154 AROS_UFPA(LONG
, pos
, D2
),
155 AROS_UFPA(LONG
, mode
, D3
),
156 AROS_UFPA(struct DosLibrary
*, DOSBase
, A6
));
157 AROS_UFP3(UBYTE
*, AROS_SLIB_ENTRY(AllocFunc
, AddDatatypes
, 0),
158 AROS_UFPA(ULONG
, size
, D0
),
159 AROS_UFPA(ULONG
, req
, D1
),
160 AROS_UFPA(struct DosLibrary
*, DOSBase
, A6
));
161 AROS_UFP3(void, AROS_SLIB_ENTRY(FreeFunc
, AddDatatypes
, 0),
162 AROS_UFPA(APTR
, memory
, A1
),
163 AROS_UFPA(ULONG
, size
, D0
),
164 AROS_UFPA(struct DosLibrary
*, DOSBase
, A6
));
166 /********************************* CONSTANTS *********************************/
168 const TEXT Version
[] = "$VER: AddDatatypes 42.1 (8.12.2007)\n";
171 UBYTE ExcludePattern
[] = "#?.(info|backdrop)";
173 UBYTE Template
[] = "FILES/M,QUIET/S,REFRESH/S,LIST/S";
183 #define ID_DTCD MAKE_ID('D','T','C','D')
184 #define ID_DTTL MAKE_ID('D','T','T','L')
188 LONG PropArray
[2*NUM_PROP
]=
196 const LONG
const CollArray
[2*NUM_COLL
]=
202 const LONG_FUNC
const FunctionArray
[]=
204 (LONG_FUNC
)AROS_SLIB_ENTRY(ReadFunc
, AddDatatypes
, 0),
205 (LONG_FUNC
)AROS_SLIB_ENTRY(AllocFunc
, AddDatatypes
, 0),
206 (LONG_FUNC
)AROS_SLIB_ENTRY(FreeFunc
, AddDatatypes
, 0),
207 (LONG_FUNC
)AROS_SLIB_ENTRY(SeekFunc
, AddDatatypes
, 0), /* For ELF */
213 struct DataTypesList
*DTList
;
214 UBYTE ExclPat
[2*EXCL_LEN
+2+1];
222 #define DTList sv->DTList
223 #define ExclPat sv->ExclPat
225 #define HookBuffer sv->HookBuffer
226 #define HookBufSize sv->HookBufSize
227 #define HookPosition sv->HookPosition
229 /****** AddDatatypes/main *****************************************************
232 * main - well... main
246 ******************************************************************************
249 int UtilityBase_version
= 37;
250 int LocaleBase_version
= 37;
251 int IFFParseBase_version
= 37;
253 int __nocommandline
= 1;
257 extern struct WBStartup
*WBenchMsg
;
258 struct StackVars vars
;
259 struct StackVars
*sv
;
260 int result
= RETURN_FAIL
;
262 memset(&vars
, 0, sizeof(struct StackVars
));
265 if((DTList
= CreateDTList(sv
)))
267 ParsePatternNoCase(ExcludePattern
, ExclPat
, sizeof(ExclPat
));
269 ObtainSemaphore(&DTList
->dtl_Lock
);
274 struct WBArg
*wa
= &WBenchMsg
->sm_ArgList
[1];
276 for(num
= 1; num
<WBenchMsg
->sm_NumArgs
; wa
++)
278 BPTR olddir
= CurrentDir(wa
->wa_Lock
);
279 LoadDatatype(sv
, wa
->wa_Name
);
287 struct RDArgs
*RDArgs
;
289 if(!(RDArgs
= ReadArgs(Template
, (SIPTR
*)&AA
, NULL
)))
291 PrintFault(IoErr(), NULL
);
299 ScanDirectory(sv
, "DEVS:DataTypes");
304 UBYTE
**files
= AA
.aa_Files
;
310 ScanDirectory(sv
, *files
);
318 struct DataTypesList
*dtl
= NULL
;
319 struct NamedObject
*no
= NULL
;
320 if((no
= FindNamedObject(NULL
, DATATYPESLIST
, NULL
)))
322 dtl
= (struct DataTypesList
*)no
->no_Object
;
323 ReleaseNamedObject(no
);
326 struct Node
*node
=dtl
->dtl_SortedList
.lh_Head
;
327 while(node
->ln_Succ
!= NULL
)
329 // sorted list points to DT.dtn_Node2 ....
330 struct CompoundDatatype
*cdt
;
331 struct DataTypeHeader
*dth
;
334 if(CheckSignal(SIGBREAKF_CTRL_C
))
337 PrintFault(ERROR_BREAK
,0);
340 cdt
=(struct CompoundDatatype
*)(node
-1);
341 dth
=cdt
->DT
.dtn_Header
;
343 argarray
[0] = dth
->dth_BaseName
;
344 argarray
[1] = dth
->dth_Name
;
346 VPrintf("%s, \"%s\"\n", (IPTR
*)argarray
);
347 node
= node
->ln_Succ
;
359 ReleaseSemaphore(&DTList
->dtl_Lock
);
367 /****** AddDatatypes/DateScan *************************************************
370 * DateScan - See if datatypes descriptors need updating
384 ******************************************************************************
388 BOOL
DateScan(struct StackVars
*sv
)
392 struct FileInfoBlock
*fib
;
394 if((lock
= Lock("DEVS:Datatypes", ACCESS_READ
)))
396 if((fib
= AllocDosObject(DOS_FIB
, NULL
)))
398 if(Examine(lock
, fib
))
400 if(!CompareDates(&fib
->fib_Date
, &DTList
->dtl_DateStamp
))
406 DTList
->dtl_DateStamp
= fib
->fib_Date
;
410 FreeDosObject(DOS_FIB
,fib
);
421 /****** AddDatatypes/ScanDirectory ********************************************
424 * ScanDirectory - Scan a directory recursively for DT descriptors
438 ******************************************************************************
442 void ScanDirectory(struct StackVars
*sv
, STRPTR pattern
)
444 struct AnchorPath
*AnchorPath
;
448 if((AnchorPath
= (struct AnchorPath
*)AllocVec(sizeof(struct AnchorPath
),
451 AnchorPath
->ap_BreakBits
= SIGBREAKF_CTRL_C
;
453 RetVal
= MatchFirst(pattern
, AnchorPath
);
457 if(CheckSignal(SIGBREAKF_CTRL_C
))
461 PrintFault(ERROR_BREAK
, NULL
);
467 if(AnchorPath
->ap_Info
.fib_DirEntryType
> 0L)
469 if(!(AnchorPath
->ap_Flags
& APF_DIDDIR
))
471 AnchorPath
->ap_Flags
|= APF_DODIR
;
474 AnchorPath
->ap_Flags
&= ~APF_DIDDIR
;
478 if(!MatchPatternNoCase(ExclPat
,
479 AnchorPath
->ap_Info
.fib_FileName
))
481 OldDir
= CurrentDir(AnchorPath
->ap_Current
->an_Lock
);
483 LoadDatatype(sv
, AnchorPath
->ap_Info
.fib_FileName
);
489 RetVal
= MatchNext(AnchorPath
);
492 if(RetVal
!= ERROR_NO_MORE_ENTRIES
)
496 PrintFault(RetVal
, NULL
);
500 MatchEnd(AnchorPath
);
502 FreeVec((APTR
)AnchorPath
);
507 /****** AddDatatypes/CreateDTList *********************************************
510 * CreateDTList - Create and initialize the DataTypesList
524 ******************************************************************************
528 struct DataTypesList
*CreateDTList(struct StackVars
*sv
)
530 struct DataTypesList
*dtl
= NULL
;
531 struct NamedObject
*no
= NULL
;
532 struct Library
*DTBase
;
534 /* We do this in order to force datatypes.library to get
535 loaded and initialized. During this process it will
536 create and install datatypes list object in memory. */
537 DTBase
= OpenLibrary("datatypes.library", 0);
539 CloseLibrary(DTBase
);
541 if((no
= FindNamedObject(NULL
, DATATYPESLIST
, NULL
)))
543 dtl
= (struct DataTypesList
*)no
->no_Object
;
548 if(!__FindNameNoCase(sv
, &dtl
->dtl_BinaryList
, "binary"))
552 sv
, &dtl
->dtl_BinaryList
, &dtl
->dtl_SortedList
,
553 "binary", DTF_BINARY
, ID_BINARY
, GID_SYSTEM
557 if(!__FindNameNoCase(sv
, &dtl
->dtl_ASCIIList
, "ascii"))
561 sv
, &dtl
->dtl_ASCIIList
, &dtl
->dtl_SortedList
,
562 "ascii", DTF_ASCII
, ID_ASCII
, GID_TEXT
566 if(!__FindNameNoCase(sv
, &dtl
->dtl_IFFList
, "iff"))
570 sv
, &dtl
->dtl_IFFList
, &dtl
->dtl_SortedList
,
571 "iff", DTF_IFF
, ID_IFF
, GID_SYSTEM
575 if(!__FindNameNoCase(sv
, &dtl
->dtl_MiscList
, "directory"))
579 sv
, &dtl
->dtl_MiscList
, &dtl
->dtl_SortedList
,
580 "directory", DTF_MISC
, ID_DIRECTORY
, GID_SYSTEM
587 ReleaseNamedObject(no
);
596 /****** AddDatatypes/CreateBasicType ******************************************
599 * CreateBasicType - Initialize one of the basic types
613 ******************************************************************************
617 struct CompoundDatatype
*CreateBasicType(struct StackVars
*sv
,
619 struct List
*globallist
, STRPTR name
,
620 UWORD Flags
, ULONG ID
, ULONG GroupID
)
622 struct CompoundDatatype
*cdt
;
623 ULONG AllocLen
= sizeof(struct CompoundDatatype
) + strlen(name
) + 1;
625 if((cdt
= AllocVec(AllocLen
, MEMF_PUBLIC
| MEMF_CLEAR
)))
627 cdt
->DT
.dtn_Header
= &cdt
->DTH
;
629 strcpy((UBYTE
*)(cdt
+ 1), name
);
632 cdt
->DTH
.dth_BaseName
=
633 cdt
->DT
.dtn_Node1
.ln_Name
=
634 cdt
->DT
.dtn_Node2
.ln_Name
=(UBYTE
*)(cdt
+ 1);
636 cdt
->DTH
.dth_GroupID
= GroupID
;
637 cdt
->DTH
.dth_ID
= ID
;
639 cdt
->DTH
.dth_Flags
= Flags
;
641 NewList(&cdt
->DT
.dtn_ToolList
);
643 cdt
->DT
.dtn_Length
= AllocLen
;
645 AddTail(list
, &cdt
->DT
.dtn_Node1
);
647 AlphaInsert(sv
, globallist
, &cdt
->DT
.dtn_Node2
);
655 /****** AddDatatypes/LoadDatatype *********************************************
658 * LoadDatatype - Load and install a single datatype descriptor
672 ******************************************************************************
676 void LoadDatatype(struct StackVars
*sv
, STRPTR name
)
678 struct IFFHandle
*iff
;
680 if((iff
= AllocIFF()))
682 if((iff
->iff_Stream
= (IPTR
)Open(name
, MODE_OLDFILE
))) /* Why IPTR? */
686 if(!OpenIFF(iff
, IFFF_READ
))
688 if(!PropChunks(iff
, PropArray
, NUM_PROP
))
690 if(!CollectionChunks(iff
, CollArray
, NUM_COLL
))
692 if(!StopOnExit(iff
, ID_DTYP
, ID_FORM
))
696 while((error
= ParseIFF(iff
, IFFPARSE_SCAN
)) == IFFERR_EOC
)
698 CreateDatatype(sv
, iff
);
699 /* FIXME: The while ParseIFF loop here crashes the 2nd time inside the loop, therefore the break below as temp fix */
709 Close((BPTR
)iff
->iff_Stream
);
716 SetIoErr(ERROR_NO_FREE_STORE
);
721 /****** AddDatatypes/MemStreamHook *******************************************
724 * MemStreamHook - needed by ReadStruct
738 ******************************************************************************
742 LONG
MemStreamHook(struct Hook
* hook
, UBYTE
**memptr
, Msg msg
)
746 switch (msg
->MethodID
)
761 /****** AddDatatypes/CreateDatatype *******************************************
764 * CreateDatatype - create a datatype from IFF chunks
778 ******************************************************************************
782 struct CompoundDatatype
*CreateDatatype(struct StackVars
*sv
,
783 struct IFFHandle
*iff
)
785 struct CompoundDatatype
*cdt
= NULL
;
786 struct StoredProperty
*prop
;
789 LONG DefaultStack
= AROS_STACKSIZE
, i
;
792 if((prop
= FindProp(iff
, ID_DTYP
, ID_DTHD
)))
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
;
805 UBYTE
*memptr
= (UBYTE
*)prop
->sp_Data
;
808 hook
.h_Entry
= (HOOKFUNC
)HookEntry
;
809 hook
.h_SubEntry
= (HOOKFUNC
)MemStreamHook
;
811 if (ReadStruct(&hook
, (APTR
*) &fdh
, &memptr
, FileDataTypeHeaderDesc
))
813 IPTR extraoffset
= sizeof(struct DataTypeHeader
) - 32;
815 cdt
->DT
.dtn_Header
= &cdt
->DTH
;
817 cdt
->DTH
.dth_Name
= (STRPTR
)(fdh
->fdth_NameOffset
+ extraoffset
+ (IPTR
)&cdt
->DTH
);
818 cdt
->DTH
.dth_BaseName
= (STRPTR
)(fdh
->fdth_BaseNameOffset
+ extraoffset
+ (IPTR
)&cdt
->DTH
);
819 cdt
->DTH
.dth_Pattern
= (STRPTR
)(fdh
->fdth_PatternOffset
+ extraoffset
+ (IPTR
)&cdt
->DTH
);
820 cdt
->DTH
.dth_Mask
= (WORD
*)(fdh
->fdth_MaskOffset
+ extraoffset
+ (IPTR
)&cdt
->DTH
);
821 cdt
->DTH
.dth_GroupID
= fdh
->fdth_GroupID
;
822 cdt
->DTH
.dth_ID
= fdh
->fdth_ID
;
823 cdt
->DTH
.dth_MaskLen
= fdh
->fdth_MaskLen
;
824 cdt
->DTH
.dth_Pad
= fdh
->fdth_Pad
;
825 cdt
->DTH
.dth_Flags
= fdh
->fdth_Flags
;
826 cdt
->DTH
.dth_Priority
= fdh
->fdth_Priority
;
828 CopyMem(prop
->sp_Data
+ 32, cdt
+ 1, prop
->sp_Size
- 32);
830 for(i
= 0; i
< cdt
->DTH
.dth_MaskLen
; i
++)
832 cdt
->DTH
.dth_Mask
[i
] = AROS_BE2WORD(cdt
->DTH
.dth_Mask
[i
]);
834 kprintf("mask[%d] = %04x (%c %c)\n", i
,
835 cdt
->DTH
.dth_Mask
[i
],
836 cdt
->DTH
.dth_Mask
[i
] & 255,
837 (cdt
->DTH
.dth_Mask
[i
] >> 8) & 255);
842 kprintf("groupid = %c%c%c%c\n", cdt
->DTH
.dth_GroupID
>> 24,
843 cdt
->DTH
.dth_GroupID
>> 16,
844 cdt
->DTH
.dth_GroupID
>> 8,
845 cdt
->DTH
.dth_GroupID
);
846 kprintf("id = %c%c%c%c\n", cdt
->DTH
.dth_ID
>> 24,
847 cdt
->DTH
.dth_ID
>> 16,
848 cdt
->DTH
.dth_ID
>> 8,
850 kprintf("flags = %x\n", cdt
->DTH
.dth_Flags
);
851 kprintf("pri = %d\n", cdt
->DTH
.dth_Priority
);
852 kprintf("name = %s\n", cdt
->DTH
.dth_Name
);
853 kprintf("basename = %s\n", cdt
->DTH
.dth_BaseName
);
854 kprintf("pattern = %s\n", cdt
->DTH
.dth_Pattern
);
855 kprintf("masklen = %d\n", cdt
->DTH
.dth_MaskLen
);
858 NewList(&cdt
->DT
.dtn_ToolList
);
860 cdt
->DT
.dtn_Length
= AllocLen
;
862 if((prop
= FindProp(iff
, ID_DTYP
, ID_DTCD
)))
864 if((func
= AllocVec(prop
->sp_Size
, MEMF_PUBLIC
| MEMF_CLEAR
)))
866 cdt
->DTCDChunk
= func
;
867 cdt
->DTCDSize
= prop
->sp_Size
;
869 CopyMem(prop
->sp_Data
,func
,prop
->sp_Size
);
871 HookBuffer
= cdt
->DTCDChunk
;
872 HookBufSize
= cdt
->DTCDSize
;
875 /* We use a cast to BPTR, since sv may not
876 * be ULONG aligned. Since only our ReadFunc
877 * is going to be looking at it, this is ok.
879 if((SegList
= InternalLoadSeg((BPTR
)(sv
), BNULL
,
880 (LONG_FUNC
*)FunctionArray
,
883 cdt
->SegList
= SegList
;
884 cdt
->Function
= BADDR(SegList
) + sizeof(BPTR
);
887 } /* if((func = AllocVec(prop->sp_Size, MEMF_PUBLIC | MEMF_CLEAR))) */
889 } /* if((prop = FindProp(iff, ID_DTYP, ID_DTCD))) */
891 cdt
= AddDatatype(sv
, cdt
);
893 FreeStruct(fdh
, FileDataTypeHeaderDesc
);
895 } /* if (ReadStruct(&hook, &fdh, &memptr, FileDataTypeHeaderDesc)) */
897 } /* cdt AllocVec okay */
899 } /* if((prop = FindProp(iff, ID_DTYP, ID_DTHD))) */
906 /****** AddDatatypes/AddDatatype **********************************************
909 * AddDatatype - add a datatype to the system
915 * This subroutine tries to add a datatype to the system datatypes
916 * list. If the datatype already exists, it will be replaced or
917 * updated. In case of an error, the CompoundDatatype will be deleted
918 * and a NULL pointer is returned.
920 * The CompoundDatatype pointer you passed in will be invalid after
921 * calling this function. Use the returned handle instead.
922 * DO NOT USE THE OLD POINTER IN ANY MORE!
928 * A pointer to a CompoundDatatype in the system datatypes list
929 * or a NULL pointer for failure
935 ******************************************************************************
939 struct CompoundDatatype
*AddDatatype(struct StackVars
*sv
,
940 struct CompoundDatatype
*cdt
)
942 struct List
*typelist
;
943 BOOL Success
= FALSE
;
946 struct CompoundDatatype
*oldcdt
;
948 switch(cdt
->DTH
.dth_Flags
& DTF_TYPE_MASK
)
950 case DTF_BINARY
: typelist
= &DTList
->dtl_BinaryList
; break;
951 case DTF_ASCII
: typelist
= &DTList
->dtl_ASCIIList
; break;
952 case DTF_IFF
: typelist
= &DTList
->dtl_IFFList
; break;
953 case DTF_MISC
: typelist
= &DTList
->dtl_MiscList
; break;
954 default: typelist
= NULL
;
959 cdt
->DT
.dtn_Node1
.ln_Name
= cdt
->DT
.dtn_Node2
.ln_Name
= cdt
->DTH
.dth_Name
;
963 if((!Stricmp(cdt
->DTH
.dth_Pattern
, "#?")) ||
964 (!strlen(cdt
->DTH
.dth_Pattern
)) )
966 cdt
->FlagLong
|= CFLGF_PATTERN_UNUSED
;
970 cdt
->FlagLong
&= ~(CFLGF_PATTERN_UNUSED
);
972 AllocSize
= 2*strlen(cdt
->DTH
.dth_Pattern
) + 2;
974 if(!(cdt
->ParsePatMem
= AllocVec(AllocSize
,
975 MEMF_PUBLIC
| MEMF_CLEAR
)))
981 cdt
->ParsePatSize
= AllocSize
;
983 result
= ParsePatternNoCase(cdt
->DTH
.dth_Pattern
,
984 cdt
->ParsePatMem
, AllocSize
);
988 cdt
->FlagLong
|= CFLGF_IS_WILD
;
992 FreeVec(cdt
->ParsePatMem
);
993 cdt
->ParsePatMem
= NULL
;
994 cdt
->ParsePatSize
= 0;
998 cdt
->FlagLong
&= ~(CFLGF_IS_WILD
);
1010 if((oldcdt
= (struct CompoundDatatype
*)__FindNameNoCase(sv
,
1012 cdt
->DT
.dtn_Node1
.ln_Name
)))
1014 if (oldcdt
->OpenCount
)
1020 if((Stricmp(oldcdt
->DTH
.dth_Name
, cdt
->DTH
.dth_Name
)) ||
1021 (Stricmp(oldcdt
->DTH
.dth_BaseName
, cdt
->DTH
.dth_BaseName
)) ||
1022 (Stricmp(oldcdt
->DTH
.dth_Pattern
, cdt
->DTH
.dth_Pattern
)) ||
1023 (oldcdt
->DTH
.dth_Flags
!= cdt
->DTH
.dth_Flags
) ||
1024 (oldcdt
->DTH
.dth_Priority
!= cdt
->DTH
.dth_Priority
) ||
1025 (oldcdt
->DTH
.dth_MaskLen
!= cdt
->DTH
.dth_MaskLen
))
1027 DeleteDatatype(sv
, oldcdt
);
1032 oldcdt
->DTH
.dth_GroupID
= cdt
->DTH
.dth_GroupID
;
1033 oldcdt
->DTH
.dth_ID
= cdt
->DTH
.dth_ID
;
1034 CopyMem(cdt
->DTH
.dth_Mask
,cdt
->DTH
.dth_Mask
,
1035 (ULONG
)(sizeof(WORD
)*cdt
->DTH
.dth_MaskLen
));
1044 DeleteDatatype(sv
, cdt
);
1049 if(cdt
->DT
.dtn_FunctionName
)
1051 LONG DefaultStack
= 4096;
1056 if((file
= Open(cdt
->DT
.dtn_FunctionName
, MODE_OLDFILE
)))
1058 if(Seek(file
, 0, OFFSET_END
) >= 0)
1060 if((AllocLen
= Seek(file
, 0,
1061 OFFSET_BEGINNING
)) > 0)
1063 if((cdt
->DTCDChunk
= AllocVec(AllocLen
,
1064 MEMF_PUBLIC
| MEMF_CLEAR
)))
1066 cdt
->DTCDSize
= AllocLen
;
1068 if(Read(file
, cdt
->DTCDChunk
, AllocLen
) == AllocLen
)
1070 HookBuffer
= cdt
->DTCDChunk
;
1071 HookBufSize
= cdt
->DTCDSize
;
1074 /* We use a cast to BPTR, since sv may not
1075 * be ULONG aligned. Since only our ReadFunc
1076 * is going to be looking at it, this is ok.
1078 if((SegList
= InternalLoadSeg((BPTR
)(sv
), BNULL
, (LONG_FUNC
*)FunctionArray
, &DefaultStack
)))
1080 cdt
->SegList
= SegList
;
1081 cdt
->Function
= BADDR(SegList
) + sizeof(BPTR
); // FIXME: is this portable?
1086 FreeVec(cdt
->DTCDChunk
);
1087 cdt
->DTCDChunk
= NULL
;
1094 cdt
->DT
.dtn_FunctionName
=NULL
;
1097 if(cdt
->DTH
.dth_MaskLen
> DTList
->dtl_LongestMask
)
1099 DTList
->dtl_LongestMask
= cdt
->DTH
.dth_MaskLen
;
1102 PrioInsert(sv
, typelist
, cdt
);
1104 AlphaInsert(sv
, &DTList
->dtl_SortedList
, &cdt
->DT
.dtn_Node2
);
1112 DeleteDatatype(sv
, cdt
);
1121 /****** AddDatatypes/DeleteDatatype *******************************************
1124 * DeleteDatatype - unlink and deallocate a CompoundDatatype structure
1138 ******************************************************************************
1142 void DeleteDatatype(struct StackVars
*sv
, struct CompoundDatatype
*cdt
)
1146 if(cdt
->ParsePatMem
)
1148 FreeVec(cdt
->ParsePatMem
);
1149 cdt
->ParsePatMem
= NULL
;
1150 cdt
->ParsePatSize
= 0;
1155 FreeVec(cdt
->DTCDChunk
);
1156 cdt
->DTCDChunk
= NULL
;
1162 UnLoadSeg(cdt
->SegList
);
1163 cdt
->SegList
= BNULL
;
1164 cdt
->Function
= NULL
;
1167 if(cdt
->DT
.dtn_Node1
.ln_Succ
&& cdt
->DT
.dtn_Node1
.ln_Pred
)
1169 Remove(&cdt
->DT
.dtn_Node1
);
1170 Remove(&cdt
->DT
.dtn_Node2
);
1171 cdt
->DT
.dtn_Node1
.ln_Succ
= cdt
->DT
.dtn_Node1
.ln_Pred
=
1172 cdt
->DT
.dtn_Node2
.ln_Succ
= cdt
->DT
.dtn_Node2
.ln_Pred
= NULL
;
1181 /****** AddDatatypes/AlphaInsert **********************************************
1184 * AlphaInsert - enqueue a node alphabetically into a list
1198 ******************************************************************************
1202 void AlphaInsert(struct StackVars
*sv
, struct List
*list
, struct Node
*node
)
1204 struct Node
*cur
,*prev
=NULL
;
1206 for(cur
= list
->lh_Head
; cur
->ln_Succ
; prev
= cur
, cur
= cur
->ln_Succ
)
1208 if(Stricmp(cur
->ln_Name
, node
->ln_Name
) > 0)
1212 Insert(list
, node
, prev
);
1217 /****** AddDatatypes/PrioInsert **********************************************
1220 * PrioInsert - enqueue a CompoundDatatype correctly in the type list
1234 ******************************************************************************
1238 void PrioInsert(struct StackVars
*sv
, struct List
*list
,
1239 struct CompoundDatatype
*cdt
)
1241 struct CompoundDatatype
*cur
, *prev
= NULL
;
1244 for(cur
= (struct CompoundDatatype
*)list
->lh_Head
;
1245 cur
->DT
.dtn_Node1
.ln_Succ
;
1246 prev
= cur
, cur
= (struct CompoundDatatype
*)cur
->DT
.dtn_Node1
.ln_Succ
)
1248 diff
= (cdt
->Function
? 1 : 0) - (cur
->Function
? 1 : 0);
1255 UWORD MinMask
= (cdt
->DTH
.dth_MaskLen
< cur
->DTH
.dth_MaskLen
) ?
1256 cdt
->DTH
.dth_MaskLen
: cur
->DTH
.dth_MaskLen
;
1257 WORD
*cdtmask
= cdt
->DTH
.dth_Mask
;
1258 WORD
*curmask
=cur
->DTH
.dth_Mask
;
1260 while(!diff
&& MinMask
--)
1261 diff
= *(curmask
++) - *(cdtmask
++);
1268 diff
= cdt
->DTH
.dth_MaskLen
- cur
->DTH
.dth_MaskLen
;
1275 diff
= (((cdt
->FlagLong
& CFLGF_PATTERN_UNUSED
) || cdt
->DTH
.dth_Pattern
==NULL
) ? 0 : 1) -
1276 (((cur
->FlagLong
& CFLGF_PATTERN_UNUSED
) || cur
->DTH
.dth_Pattern
==NULL
) ? 0 : 1);
1283 diff
= cdt
->DTH
.dth_Priority
- cur
->DTH
.dth_Priority
;
1293 Insert(list
, &cdt
->DT
.dtn_Node1
, (struct Node
*)prev
);
1298 /****** AddDatatypes/__FindNameNoCase *****************************************
1301 * __FindNameNoCase - find a node in a list (case insensitive)
1315 ******************************************************************************
1319 struct Node
*__FindNameNoCase(struct StackVars
*sv
, struct List
*list
,
1323 struct Node
*result
= NULL
;
1325 for(node
= list
->lh_Head
; node
->ln_Succ
; node
= node
->ln_Succ
)
1327 if(!Stricmp(node
->ln_Name
, name
))
1339 /****** AddDatatypes/ReadFunc *************************************************
1342 * ReadFunc - data read hook for InternalLoadSeg
1356 ******************************************************************************
1360 AROS_UFH4(LONG
, AROS_SLIB_ENTRY(ReadFunc
, AddDatatypes
, 0),
1361 AROS_UFHA(BPTR
, fh
, D1
),
1362 AROS_UFHA(void * , buffer
, D2
),
1363 AROS_UFHA(LONG
, length
, D3
),
1364 AROS_UFHA(struct DosLibrary
*, DOSBase
, A6
))
1368 struct StackVars
*sv
= (APTR
)fh
;
1369 LONG maxlen
= HookBufSize
-HookPosition
;
1370 LONG actual
= length
> maxlen
? maxlen
: length
;
1372 CopyMem(HookBuffer
+HookPosition
, buffer
, actual
);
1374 HookPosition
+= actual
;
1381 /****** AddDatatypes/SeekFunc *************************************************
1384 * SeekFunc - seek hook for InternalLoadSeg (ELF only)
1398 ******************************************************************************
1402 AROS_UFH4(LONG
, AROS_SLIB_ENTRY(SeekFunc
, AddDatatypes
, 0),
1403 AROS_UFHA(BPTR
, fh
, D1
),
1404 AROS_UFHA(LONG
, pos
, D2
),
1405 AROS_UFHA(LONG
, mode
, D3
),
1406 AROS_UFHA(struct DosLibrary
*, DOSBase
, A6
))
1410 struct StackVars
*sv
= (APTR
)fh
;
1411 LONG oldpos
= HookPosition
;
1414 case OFFSET_BEGINNING
: break;
1415 case OFFSET_END
: pos
= HookBufSize
- pos
; break;
1416 case OFFSET_CURRENT
: pos
= HookPosition
+ pos
; break;
1420 if (pos
< 0 || pos
>= HookBufSize
)
1430 /****** AddDatatypes/AllocFunc ************************************************
1433 * AllocFunc - memory allocation hook for InternalLoadSeg
1447 ******************************************************************************
1451 AROS_UFH3(UBYTE
*, AROS_SLIB_ENTRY(AllocFunc
, AddDatatypes
, 0),
1452 AROS_UFHA(ULONG
, size
, D0
),
1453 AROS_UFHA(ULONG
, flags
,D1
),
1454 AROS_UFHA(struct DosLibrary
*, DOSBase
, A6
))
1458 return(AllocMem(size
, flags
));
1465 /****** AddDatatypes/FreeFunc *************************************************
1468 * FreeFunc - memory freeing hook for InternalLoadSeg
1482 ******************************************************************************
1486 AROS_UFH3(void, AROS_SLIB_ENTRY(FreeFunc
, AddDatatypes
, 0),
1487 AROS_UFHA(APTR
, memory
, A1
),
1488 AROS_UFHA(ULONG
, size
, D0
),
1489 AROS_UFHA(struct DosLibrary
*, DOSBase
, A6
))
1493 FreeMem(memory
, size
);
1500 /******************************* STUB ROUTINES ********************************/
1502 struct NamedObject
*allocnamedobject(struct StackVars
*sv
, STRPTR name
,
1505 return AllocNamedObjectA(name
, (struct TagItem
*)&FirstTag
);