2 Copyright © 1995-2012, 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 ******************************************************************************/
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 struct Node
*__FindNameNoCase(struct StackVars
*sv
, struct List
*list
,
145 AROS_UFP4(LONG
, AROS_SLIB_ENTRY(ReadFunc
, AddDataTypes
, 0),
146 AROS_UFPA(BPTR
, fh
, D1
),
147 AROS_UFPA(void * , buf
, D2
),
148 AROS_UFPA(LONG
, size
, D3
),
149 AROS_UFPA(struct DosLibrary
*, DOSBase
, A6
));
150 AROS_UFP4(LONG
, AROS_SLIB_ENTRY(SeekFunc
, AddDataTypes
, 0),
151 AROS_UFPA(BPTR
, fh
, D1
),
152 AROS_UFPA(LONG
, pos
, D2
),
153 AROS_UFPA(LONG
, mode
, D3
),
154 AROS_UFPA(struct DosLibrary
*, DOSBase
, A6
));
155 AROS_UFP3(UBYTE
*, AROS_SLIB_ENTRY(AllocFunc
, AddDataTypes
, 0),
156 AROS_UFPA(ULONG
, size
, D0
),
157 AROS_UFPA(ULONG
, req
, D1
),
158 AROS_UFPA(struct DosLibrary
*, DOSBase
, A6
));
159 AROS_UFP3(void, AROS_SLIB_ENTRY(FreeFunc
, AddDataTypes
, 0),
160 AROS_UFPA(APTR
, memory
, A1
),
161 AROS_UFPA(ULONG
, size
, D0
),
162 AROS_UFPA(struct DosLibrary
*, DOSBase
, A6
));
164 /********************************* CONSTANTS *********************************/
166 const TEXT Version
[] = "$VER: AddDataTypes 42.1 (8.12.2007)\n";
169 UBYTE ExcludePattern
[] = "#?.(info|backdrop)";
171 UBYTE Template
[] = "FILES/M,QUIET/S,REFRESH/S,LIST/S";
181 #define ID_DTCD MAKE_ID('D','T','C','D')
182 #define ID_DTTL MAKE_ID('D','T','T','L')
186 LONG PropArray
[2*NUM_PROP
]=
194 const LONG
const CollArray
[2*NUM_COLL
]=
200 const LONG_FUNC
const FunctionArray
[]=
202 (LONG_FUNC
)AROS_SLIB_ENTRY(ReadFunc
, AddDataTypes
, 0),
203 (LONG_FUNC
)AROS_SLIB_ENTRY(AllocFunc
, AddDataTypes
, 0),
204 (LONG_FUNC
)AROS_SLIB_ENTRY(FreeFunc
, AddDataTypes
, 0),
205 (LONG_FUNC
)AROS_SLIB_ENTRY(SeekFunc
, AddDataTypes
, 0), /* For ELF */
211 struct DataTypesList
*DTList
;
212 UBYTE ExclPat
[2*EXCL_LEN
+2+1];
220 #define DTList sv->DTList
221 #define ExclPat sv->ExclPat
223 #define HookBuffer sv->HookBuffer
224 #define HookBufSize sv->HookBufSize
225 #define HookPosition sv->HookPosition
227 /****** AddDataTypes/main *****************************************************
230 * main - well... main
244 ******************************************************************************
247 int UtilityBase_version
= 37;
248 int LocaleBase_version
= 37;
249 int IFFParseBase_version
= 37;
251 int __nocommandline
= 1;
255 extern struct WBStartup
*WBenchMsg
;
256 struct StackVars vars
;
257 struct StackVars
*sv
;
258 int result
= RETURN_FAIL
;
260 memset(&vars
, 0, sizeof(struct StackVars
));
263 if((DTList
= CreateDTList(sv
)))
265 ParsePatternNoCase(ExcludePattern
, ExclPat
, sizeof(ExclPat
));
267 ObtainSemaphore(&DTList
->dtl_Lock
);
272 struct WBArg
*wa
= &WBenchMsg
->sm_ArgList
[1];
274 for(num
= 1; num
<WBenchMsg
->sm_NumArgs
; wa
++)
276 BPTR olddir
= CurrentDir(wa
->wa_Lock
);
277 LoadDataType(sv
, wa
->wa_Name
);
285 struct RDArgs
*RDArgs
;
287 if(!(RDArgs
= ReadArgs(Template
, (SIPTR
*)&AA
, NULL
)))
289 PrintFault(IoErr(), NULL
);
297 ScanDirectory(sv
, "DEVS:DataTypes");
302 UBYTE
**files
= AA
.aa_Files
;
308 ScanDirectory(sv
, *files
);
316 struct DataTypesList
*dtl
= NULL
;
317 struct NamedObject
*no
= NULL
;
318 if((no
= FindNamedObject(NULL
, DATATYPESLIST
, NULL
)))
320 dtl
= (struct DataTypesList
*)no
->no_Object
;
321 ReleaseNamedObject(no
);
324 struct Node
*node
=dtl
->dtl_SortedList
.lh_Head
;
325 while(node
->ln_Succ
!= NULL
)
327 // sorted list points to DT.dtn_Node2 ....
328 struct CompoundDataType
*cdt
;
329 struct DataTypeHeader
*dth
;
331 if(CheckSignal(SIGBREAKF_CTRL_C
))
334 PrintFault(ERROR_BREAK
,0);
337 cdt
=(struct CompoundDataType
*)(node
-1);
338 dth
=cdt
->DT
.dtn_Header
;
341 Printf("%s, \"%s\"\n", dth
->dth_BaseName
, dth
->dth_Name
);
342 node
= node
->ln_Succ
;
354 ReleaseSemaphore(&DTList
->dtl_Lock
);
362 /****** AddDataTypes/DateScan *************************************************
365 * DateScan - See if DataTypes descriptors need updating
379 ******************************************************************************
383 BOOL
DateScan(struct StackVars
*sv
)
387 struct FileInfoBlock
*fib
;
389 if((lock
= Lock("DEVS:DataTypes", ACCESS_READ
)))
391 if((fib
= AllocDosObject(DOS_FIB
, NULL
)))
393 if(Examine(lock
, fib
))
395 if(!CompareDates(&fib
->fib_Date
, &DTList
->dtl_DateStamp
))
401 DTList
->dtl_DateStamp
= fib
->fib_Date
;
405 FreeDosObject(DOS_FIB
,fib
);
416 /****** AddDataTypes/ScanDirectory ********************************************
419 * ScanDirectory - Scan a directory recursively for DT descriptors
433 ******************************************************************************
437 void ScanDirectory(struct StackVars
*sv
, STRPTR pattern
)
439 struct AnchorPath
*AnchorPath
;
443 if((AnchorPath
= (struct AnchorPath
*)AllocVec(sizeof(struct AnchorPath
),
446 AnchorPath
->ap_BreakBits
= SIGBREAKF_CTRL_C
;
448 RetVal
= MatchFirst(pattern
, AnchorPath
);
452 if(CheckSignal(SIGBREAKF_CTRL_C
))
456 PrintFault(ERROR_BREAK
, NULL
);
462 if(AnchorPath
->ap_Info
.fib_DirEntryType
> 0L)
464 if(!(AnchorPath
->ap_Flags
& APF_DIDDIR
))
466 AnchorPath
->ap_Flags
|= APF_DODIR
;
469 AnchorPath
->ap_Flags
&= ~APF_DIDDIR
;
473 if(!MatchPatternNoCase(ExclPat
,
474 AnchorPath
->ap_Info
.fib_FileName
))
476 OldDir
= CurrentDir(AnchorPath
->ap_Current
->an_Lock
);
478 LoadDataType(sv
, AnchorPath
->ap_Info
.fib_FileName
);
484 RetVal
= MatchNext(AnchorPath
);
487 if(RetVal
!= ERROR_NO_MORE_ENTRIES
)
491 PrintFault(RetVal
, NULL
);
495 MatchEnd(AnchorPath
);
497 FreeVec((APTR
)AnchorPath
);
502 /****** AddDataTypes/CreateDTList *********************************************
505 * CreateDTList - Create and initialize the DataTypesList
519 ******************************************************************************
523 struct DataTypesList
*CreateDTList(struct StackVars
*sv
)
525 struct DataTypesList
*dtl
= NULL
;
526 struct NamedObject
*no
= NULL
;
527 struct Library
*DTBase
;
529 /* We do this in order to force datatypes.library to get
530 loaded and initialized. During this process it will
531 create and install DataTypes list object in memory. */
532 DTBase
= OpenLibrary("datatypes.library", 0);
534 CloseLibrary(DTBase
);
536 if((no
= FindNamedObject(NULL
, DATATYPESLIST
, NULL
)))
538 dtl
= (struct DataTypesList
*)no
->no_Object
;
543 if(!__FindNameNoCase(sv
, &dtl
->dtl_BinaryList
, "binary"))
547 sv
, &dtl
->dtl_BinaryList
, &dtl
->dtl_SortedList
,
548 "binary", DTF_BINARY
, ID_BINARY
, GID_SYSTEM
552 if(!__FindNameNoCase(sv
, &dtl
->dtl_ASCIIList
, "ascii"))
556 sv
, &dtl
->dtl_ASCIIList
, &dtl
->dtl_SortedList
,
557 "ascii", DTF_ASCII
, ID_ASCII
, GID_TEXT
561 if(!__FindNameNoCase(sv
, &dtl
->dtl_IFFList
, "iff"))
565 sv
, &dtl
->dtl_IFFList
, &dtl
->dtl_SortedList
,
566 "iff", DTF_IFF
, ID_IFF
, GID_SYSTEM
570 if(!__FindNameNoCase(sv
, &dtl
->dtl_MiscList
, "directory"))
574 sv
, &dtl
->dtl_MiscList
, &dtl
->dtl_SortedList
,
575 "directory", DTF_MISC
, ID_DIRECTORY
, GID_SYSTEM
582 ReleaseNamedObject(no
);
591 /****** AddDataTypes/CreateBasicType ******************************************
594 * CreateBasicType - Initialize one of the basic types
608 ******************************************************************************
612 struct CompoundDataType
*CreateBasicType(struct StackVars
*sv
,
614 struct List
*globallist
, STRPTR name
,
615 UWORD Flags
, ULONG ID
, ULONG GroupID
)
617 struct CompoundDataType
*cdt
;
618 ULONG AllocLen
= sizeof(struct CompoundDataType
) + strlen(name
) + 1;
620 if((cdt
= AllocVec(AllocLen
, MEMF_PUBLIC
| MEMF_CLEAR
)))
622 cdt
->DT
.dtn_Header
= &cdt
->DTH
;
624 strcpy((UBYTE
*)(cdt
+ 1), name
);
627 cdt
->DTH
.dth_BaseName
=
628 cdt
->DT
.dtn_Node1
.ln_Name
=
629 cdt
->DT
.dtn_Node2
.ln_Name
=(UBYTE
*)(cdt
+ 1);
631 cdt
->DTH
.dth_GroupID
= GroupID
;
632 cdt
->DTH
.dth_ID
= ID
;
634 cdt
->DTH
.dth_Flags
= Flags
;
636 NewList(&cdt
->DT
.dtn_ToolList
);
638 cdt
->DT
.dtn_Length
= AllocLen
;
640 cdt
->DT
.dtn_Node1
.ln_Pri
= -128;
641 Enqueue(list
, &cdt
->DT
.dtn_Node1
);
643 AlphaInsert(sv
, globallist
, &cdt
->DT
.dtn_Node2
);
651 /****** AddDataTypes/LoadDataType *********************************************
654 * LoadDataType - Load and install a single DataType descriptor
668 ******************************************************************************
672 void LoadDataType(struct StackVars
*sv
, STRPTR name
)
674 struct IFFHandle
*iff
;
676 if((iff
= AllocIFF()))
678 if((iff
->iff_Stream
= (IPTR
)Open(name
, MODE_OLDFILE
))) /* Why IPTR? */
682 if(!OpenIFF(iff
, IFFF_READ
))
684 if(!PropChunks(iff
, PropArray
, NUM_PROP
))
686 if(!CollectionChunks(iff
, CollArray
, NUM_COLL
))
688 if(!StopOnExit(iff
, ID_DTYP
, ID_FORM
))
692 while((error
= ParseIFF(iff
, IFFPARSE_SCAN
)) == IFFERR_EOC
)
694 CreateDataType(sv
, iff
);
695 /* FIXME: The while ParseIFF loop here crashes the 2nd time inside the loop, therefore the break below as temp fix */
705 Close((BPTR
)iff
->iff_Stream
);
712 SetIoErr(ERROR_NO_FREE_STORE
);
717 /****** AddDataTypes/MemStreamHook *******************************************
720 * MemStreamHook - needed by ReadStruct
734 ******************************************************************************
738 LONG
MemStreamHook(struct Hook
* hook
, UBYTE
**memptr
, Msg msg
)
742 switch (msg
->MethodID
)
757 /****** AddDataTypes/CreateDataType *******************************************
760 * CreateDataType - create a DataType from IFF chunks
774 ******************************************************************************
778 struct CompoundDataType
*CreateDataType(struct StackVars
*sv
,
779 struct IFFHandle
*iff
)
781 struct CompoundDataType
*cdt
= NULL
;
782 struct StoredProperty
*prop
;
785 LONG DefaultStack
= AROS_STACKSIZE
, i
;
788 if((prop
= FindProp(iff
, ID_DTYP
, ID_DTHD
)))
790 AllocLen
= sizeof(struct CompoundDataType
) -
791 32 + /* was sizeof(struct DataTypeHeader), but we must use struct size as it would be on Amiga */
794 if(!(cdt
= AllocVec(AllocLen
, MEMF_PUBLIC
| MEMF_CLEAR
)))
796 SetIoErr(ERROR_NO_FREE_STORE
);
800 struct FileDataTypeHeader
*fdh
= NULL
;
801 UBYTE
*memptr
= (UBYTE
*)prop
->sp_Data
;
804 hook
.h_Entry
= (HOOKFUNC
)HookEntry
;
805 hook
.h_SubEntry
= (HOOKFUNC
)MemStreamHook
;
807 if (ReadStruct(&hook
, (APTR
*) &fdh
, &memptr
, FileDataTypeHeaderDesc
))
809 IPTR extraoffset
= sizeof(struct DataTypeHeader
) - 32;
811 cdt
->DT
.dtn_Header
= &cdt
->DTH
;
813 cdt
->DTH
.dth_Name
= (STRPTR
)(fdh
->fdth_NameOffset
+ extraoffset
+ (IPTR
)&cdt
->DTH
);
814 cdt
->DTH
.dth_BaseName
= (STRPTR
)(fdh
->fdth_BaseNameOffset
+ extraoffset
+ (IPTR
)&cdt
->DTH
);
815 cdt
->DTH
.dth_Pattern
= (STRPTR
)(fdh
->fdth_PatternOffset
+ extraoffset
+ (IPTR
)&cdt
->DTH
);
816 cdt
->DTH
.dth_Mask
= (WORD
*)(fdh
->fdth_MaskOffset
+ extraoffset
+ (IPTR
)&cdt
->DTH
);
817 cdt
->DTH
.dth_GroupID
= fdh
->fdth_GroupID
;
818 cdt
->DTH
.dth_ID
= fdh
->fdth_ID
;
819 cdt
->DTH
.dth_MaskLen
= fdh
->fdth_MaskLen
;
820 cdt
->DTH
.dth_Pad
= fdh
->fdth_Pad
;
821 cdt
->DTH
.dth_Flags
= fdh
->fdth_Flags
;
822 cdt
->DTH
.dth_Priority
= fdh
->fdth_Priority
;
824 CopyMem(prop
->sp_Data
+ 32, cdt
+ 1, prop
->sp_Size
- 32);
826 for(i
= 0; i
< cdt
->DTH
.dth_MaskLen
; i
++)
828 cdt
->DTH
.dth_Mask
[i
] = AROS_BE2WORD(cdt
->DTH
.dth_Mask
[i
]);
830 kprintf("mask[%d] = %04x (%c %c)\n", i
,
831 cdt
->DTH
.dth_Mask
[i
],
832 cdt
->DTH
.dth_Mask
[i
] & 255,
833 (cdt
->DTH
.dth_Mask
[i
] >> 8) & 255);
838 kprintf("groupid = %c%c%c%c\n", cdt
->DTH
.dth_GroupID
>> 24,
839 cdt
->DTH
.dth_GroupID
>> 16,
840 cdt
->DTH
.dth_GroupID
>> 8,
841 cdt
->DTH
.dth_GroupID
);
842 kprintf("id = %c%c%c%c\n", cdt
->DTH
.dth_ID
>> 24,
843 cdt
->DTH
.dth_ID
>> 16,
844 cdt
->DTH
.dth_ID
>> 8,
846 kprintf("flags = %x\n", cdt
->DTH
.dth_Flags
);
847 kprintf("pri = %d\n", cdt
->DTH
.dth_Priority
);
848 kprintf("name = %s\n", cdt
->DTH
.dth_Name
);
849 kprintf("basename = %s\n", cdt
->DTH
.dth_BaseName
);
850 kprintf("pattern = %s\n", cdt
->DTH
.dth_Pattern
);
851 kprintf("masklen = %d\n", cdt
->DTH
.dth_MaskLen
);
854 NewList(&cdt
->DT
.dtn_ToolList
);
856 cdt
->DT
.dtn_Length
= AllocLen
;
858 if((prop
= FindProp(iff
, ID_DTYP
, ID_DTCD
)))
860 if((func
= AllocVec(prop
->sp_Size
, MEMF_PUBLIC
| MEMF_CLEAR
)))
862 cdt
->DTCDChunk
= func
;
863 cdt
->DTCDSize
= prop
->sp_Size
;
865 CopyMem(prop
->sp_Data
,func
,prop
->sp_Size
);
867 HookBuffer
= cdt
->DTCDChunk
;
868 HookBufSize
= cdt
->DTCDSize
;
871 /* We use a cast to BPTR, since sv may not
872 * be ULONG aligned. Since only our ReadFunc
873 * is going to be looking at it, this is ok.
875 if((SegList
= InternalLoadSeg((BPTR
)(sv
), BNULL
,
876 (LONG_FUNC
*)FunctionArray
,
879 cdt
->SegList
= SegList
;
880 cdt
->Function
= BADDR(SegList
) + sizeof(BPTR
);
883 } /* if((func = AllocVec(prop->sp_Size, MEMF_PUBLIC | MEMF_CLEAR))) */
885 } /* if((prop = FindProp(iff, ID_DTYP, ID_DTCD))) */
887 cdt
= AddDataType(sv
, cdt
);
889 FreeStruct(fdh
, FileDataTypeHeaderDesc
);
891 } /* if (ReadStruct(&hook, &fdh, &memptr, FileDataTypeHeaderDesc)) */
893 } /* cdt AllocVec okay */
895 } /* if((prop = FindProp(iff, ID_DTYP, ID_DTHD))) */
902 /****** AddDataTypes/AddDataType **********************************************
905 * AddDataType - add a DataType to the system
911 * This subroutine tries to add a DataType to the system DataTypes
912 * list. If the DataType already exists, it will be replaced or
913 * updated. In case of an error, the CompoundDataType will be deleted
914 * and a NULL pointer is returned.
916 * The CompoundDataType pointer you passed in will be invalid after
917 * calling this function. Use the returned handle instead.
918 * DO NOT USE THE OLD POINTER IN ANY MORE!
924 * A pointer to a CompoundDataType in the system DataTypes list
925 * or a NULL pointer for failure
931 ******************************************************************************
935 struct CompoundDataType
*AddDataType(struct StackVars
*sv
,
936 struct CompoundDataType
*cdt
)
938 struct List
*typelist
;
939 BOOL Success
= FALSE
;
942 struct CompoundDataType
*oldcdt
;
944 switch(cdt
->DTH
.dth_Flags
& DTF_TYPE_MASK
)
946 case DTF_BINARY
: typelist
= &DTList
->dtl_BinaryList
; break;
947 case DTF_ASCII
: typelist
= &DTList
->dtl_ASCIIList
; break;
948 case DTF_IFF
: typelist
= &DTList
->dtl_IFFList
; break;
949 case DTF_MISC
: typelist
= &DTList
->dtl_MiscList
; break;
950 default: typelist
= NULL
;
955 cdt
->DT
.dtn_Node1
.ln_Name
= cdt
->DT
.dtn_Node2
.ln_Name
= cdt
->DTH
.dth_Name
;
959 if((!Stricmp(cdt
->DTH
.dth_Pattern
, "#?")) ||
960 (!strlen(cdt
->DTH
.dth_Pattern
)) )
962 cdt
->FlagLong
|= CFLGF_PATTERN_UNUSED
;
966 cdt
->FlagLong
&= ~(CFLGF_PATTERN_UNUSED
);
968 AllocSize
= 2*strlen(cdt
->DTH
.dth_Pattern
) + 2;
970 if(!(cdt
->ParsePatMem
= AllocVec(AllocSize
,
971 MEMF_PUBLIC
| MEMF_CLEAR
)))
977 cdt
->ParsePatSize
= AllocSize
;
979 result
= ParsePatternNoCase(cdt
->DTH
.dth_Pattern
,
980 cdt
->ParsePatMem
, AllocSize
);
984 cdt
->FlagLong
|= CFLGF_IS_WILD
;
988 FreeVec(cdt
->ParsePatMem
);
989 cdt
->ParsePatMem
= NULL
;
990 cdt
->ParsePatSize
= 0;
994 cdt
->FlagLong
&= ~(CFLGF_IS_WILD
);
1006 if((oldcdt
= (struct CompoundDataType
*)__FindNameNoCase(sv
,
1008 cdt
->DT
.dtn_Node1
.ln_Name
)))
1010 if (oldcdt
->OpenCount
)
1016 if((Stricmp(oldcdt
->DTH
.dth_Name
, cdt
->DTH
.dth_Name
)) ||
1017 (Stricmp(oldcdt
->DTH
.dth_BaseName
, cdt
->DTH
.dth_BaseName
)) ||
1018 (Stricmp(oldcdt
->DTH
.dth_Pattern
, cdt
->DTH
.dth_Pattern
)) ||
1019 (oldcdt
->DTH
.dth_Flags
!= cdt
->DTH
.dth_Flags
) ||
1020 (oldcdt
->DTH
.dth_Priority
!= cdt
->DTH
.dth_Priority
) ||
1021 (oldcdt
->DTH
.dth_MaskLen
!= cdt
->DTH
.dth_MaskLen
))
1023 DeleteDataType(sv
, oldcdt
);
1028 oldcdt
->DTH
.dth_GroupID
= cdt
->DTH
.dth_GroupID
;
1029 oldcdt
->DTH
.dth_ID
= cdt
->DTH
.dth_ID
;
1030 CopyMem(cdt
->DTH
.dth_Mask
,cdt
->DTH
.dth_Mask
,
1031 (ULONG
)(sizeof(WORD
)*cdt
->DTH
.dth_MaskLen
));
1040 DeleteDataType(sv
, cdt
);
1045 if(cdt
->DT
.dtn_FunctionName
)
1047 LONG DefaultStack
= 4096;
1052 if((file
= Open(cdt
->DT
.dtn_FunctionName
, MODE_OLDFILE
)))
1054 if(Seek(file
, 0, OFFSET_END
) >= 0)
1056 if((AllocLen
= Seek(file
, 0,
1057 OFFSET_BEGINNING
)) > 0)
1059 if((cdt
->DTCDChunk
= AllocVec(AllocLen
,
1060 MEMF_PUBLIC
| MEMF_CLEAR
)))
1062 cdt
->DTCDSize
= AllocLen
;
1064 if(Read(file
, cdt
->DTCDChunk
, AllocLen
) == AllocLen
)
1066 HookBuffer
= cdt
->DTCDChunk
;
1067 HookBufSize
= cdt
->DTCDSize
;
1070 /* We use a cast to BPTR, since sv may not
1071 * be ULONG aligned. Since only our ReadFunc
1072 * is going to be looking at it, this is ok.
1074 if((SegList
= InternalLoadSeg((BPTR
)(sv
), BNULL
, (LONG_FUNC
*)FunctionArray
, &DefaultStack
)))
1076 cdt
->SegList
= SegList
;
1077 cdt
->Function
= BADDR(SegList
) + sizeof(BPTR
); // FIXME: is this portable?
1082 FreeVec(cdt
->DTCDChunk
);
1083 cdt
->DTCDChunk
= NULL
;
1090 cdt
->DT
.dtn_FunctionName
=NULL
;
1093 if(cdt
->DTH
.dth_MaskLen
> DTList
->dtl_LongestMask
)
1095 DTList
->dtl_LongestMask
= cdt
->DTH
.dth_MaskLen
;
1098 cdt
->DT
.dtn_Node1
.ln_Pri
= cdt
->DTH
.dth_Priority
;
1099 Enqueue(typelist
, &cdt
->DT
.dtn_Node1
);
1101 AlphaInsert(sv
, &DTList
->dtl_SortedList
, &cdt
->DT
.dtn_Node2
);
1109 DeleteDataType(sv
, cdt
);
1118 /****** AddDataTypes/DeleteDataType *******************************************
1121 * DeleteDataType - unlink and deallocate a CompoundDataType structure
1135 ******************************************************************************
1139 void DeleteDataType(struct StackVars
*sv
, struct CompoundDataType
*cdt
)
1143 if(cdt
->ParsePatMem
)
1145 FreeVec(cdt
->ParsePatMem
);
1146 cdt
->ParsePatMem
= NULL
;
1147 cdt
->ParsePatSize
= 0;
1152 FreeVec(cdt
->DTCDChunk
);
1153 cdt
->DTCDChunk
= NULL
;
1159 UnLoadSeg(cdt
->SegList
);
1160 cdt
->SegList
= BNULL
;
1161 cdt
->Function
= NULL
;
1164 if(cdt
->DT
.dtn_Node1
.ln_Succ
&& cdt
->DT
.dtn_Node1
.ln_Pred
)
1166 Remove(&cdt
->DT
.dtn_Node1
);
1167 Remove(&cdt
->DT
.dtn_Node2
);
1168 cdt
->DT
.dtn_Node1
.ln_Succ
= cdt
->DT
.dtn_Node1
.ln_Pred
=
1169 cdt
->DT
.dtn_Node2
.ln_Succ
= cdt
->DT
.dtn_Node2
.ln_Pred
= NULL
;
1178 /****** AddDataTypes/AlphaInsert **********************************************
1181 * AlphaInsert - enqueue a node alphabetically into a list
1195 ******************************************************************************
1199 void AlphaInsert(struct StackVars
*sv
, struct List
*list
, struct Node
*node
)
1201 struct Node
*cur
,*prev
=NULL
;
1203 for(cur
= list
->lh_Head
; cur
->ln_Succ
; prev
= cur
, cur
= cur
->ln_Succ
)
1205 if(Stricmp(cur
->ln_Name
, node
->ln_Name
) > 0)
1209 Insert(list
, node
, prev
);
1214 /****** AddDataTypes/__FindNameNoCase *****************************************
1217 * __FindNameNoCase - find a node in a list (case insensitive)
1231 ******************************************************************************
1235 struct Node
*__FindNameNoCase(struct StackVars
*sv
, struct List
*list
,
1239 struct Node
*result
= NULL
;
1241 for(node
= list
->lh_Head
; node
->ln_Succ
; node
= node
->ln_Succ
)
1243 if(!Stricmp(node
->ln_Name
, name
))
1255 /****** AddDataTypes/ReadFunc *************************************************
1258 * ReadFunc - data read hook for InternalLoadSeg
1272 ******************************************************************************
1276 AROS_UFH4(LONG
, AROS_SLIB_ENTRY(ReadFunc
, AddDataTypes
, 0),
1277 AROS_UFHA(BPTR
, fh
, D1
),
1278 AROS_UFHA(void * , buffer
, D2
),
1279 AROS_UFHA(LONG
, length
, D3
),
1280 AROS_UFHA(struct DosLibrary
*, DOSBase
, A6
))
1284 struct StackVars
*sv
= (APTR
)fh
;
1285 LONG maxlen
= HookBufSize
-HookPosition
;
1286 LONG actual
= length
> maxlen
? maxlen
: length
;
1288 CopyMem(HookBuffer
+HookPosition
, buffer
, actual
);
1290 HookPosition
+= actual
;
1297 /****** AddDataTypes/SeekFunc *************************************************
1300 * SeekFunc - seek hook for InternalLoadSeg (ELF only)
1314 ******************************************************************************
1318 AROS_UFH4(LONG
, AROS_SLIB_ENTRY(SeekFunc
, AddDataTypes
, 0),
1319 AROS_UFHA(BPTR
, fh
, D1
),
1320 AROS_UFHA(LONG
, pos
, D2
),
1321 AROS_UFHA(LONG
, mode
, D3
),
1322 AROS_UFHA(struct DosLibrary
*, DOSBase
, A6
))
1326 struct StackVars
*sv
= (APTR
)fh
;
1327 LONG oldpos
= HookPosition
;
1330 case OFFSET_BEGINNING
: break;
1331 case OFFSET_END
: pos
= HookBufSize
- pos
; break;
1332 case OFFSET_CURRENT
: pos
= HookPosition
+ pos
; break;
1336 if (pos
< 0 || pos
>= HookBufSize
)
1346 /****** AddDataTypes/AllocFunc ************************************************
1349 * AllocFunc - memory allocation hook for InternalLoadSeg
1363 ******************************************************************************
1367 AROS_UFH3(UBYTE
*, AROS_SLIB_ENTRY(AllocFunc
, AddDataTypes
, 0),
1368 AROS_UFHA(ULONG
, size
, D0
),
1369 AROS_UFHA(ULONG
, flags
,D1
),
1370 AROS_UFHA(struct DosLibrary
*, DOSBase
, A6
))
1374 return(AllocMem(size
, flags
));
1381 /****** AddDataTypes/FreeFunc *************************************************
1384 * FreeFunc - memory freeing hook for InternalLoadSeg
1398 ******************************************************************************
1402 AROS_UFH3(void, AROS_SLIB_ENTRY(FreeFunc
, AddDataTypes
, 0),
1403 AROS_UFHA(APTR
, memory
, A1
),
1404 AROS_UFHA(ULONG
, size
, D0
),
1405 AROS_UFHA(struct DosLibrary
*, DOSBase
, A6
))
1409 FreeMem(memory
, size
);
1416 /******************************* STUB ROUTINES ********************************/
1418 struct NamedObject
*allocnamedobject(struct StackVars
*sv
, STRPTR name
,
1421 return AllocNamedObjectA(name
, (struct TagItem
*)&FirstTag
);