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
;
332 if(CheckSignal(SIGBREAKF_CTRL_C
))
335 PrintFault(ERROR_BREAK
,0);
338 cdt
=(struct CompoundDataType
*)(node
-1);
339 dth
=cdt
->DT
.dtn_Header
;
341 argarray
[0] = dth
->dth_BaseName
;
342 argarray
[1] = dth
->dth_Name
;
344 VPrintf("%s, \"%s\"\n", (IPTR
*)argarray
);
345 node
= node
->ln_Succ
;
357 ReleaseSemaphore(&DTList
->dtl_Lock
);
365 /****** AddDataTypes/DateScan *************************************************
368 * DateScan - See if DataTypes descriptors need updating
382 ******************************************************************************
386 BOOL
DateScan(struct StackVars
*sv
)
390 struct FileInfoBlock
*fib
;
392 if((lock
= Lock("DEVS:DataTypes", ACCESS_READ
)))
394 if((fib
= AllocDosObject(DOS_FIB
, NULL
)))
396 if(Examine(lock
, fib
))
398 if(!CompareDates(&fib
->fib_Date
, &DTList
->dtl_DateStamp
))
404 DTList
->dtl_DateStamp
= fib
->fib_Date
;
408 FreeDosObject(DOS_FIB
,fib
);
419 /****** AddDataTypes/ScanDirectory ********************************************
422 * ScanDirectory - Scan a directory recursively for DT descriptors
436 ******************************************************************************
440 void ScanDirectory(struct StackVars
*sv
, STRPTR pattern
)
442 struct AnchorPath
*AnchorPath
;
446 if((AnchorPath
= (struct AnchorPath
*)AllocVec(sizeof(struct AnchorPath
),
449 AnchorPath
->ap_BreakBits
= SIGBREAKF_CTRL_C
;
451 RetVal
= MatchFirst(pattern
, AnchorPath
);
455 if(CheckSignal(SIGBREAKF_CTRL_C
))
459 PrintFault(ERROR_BREAK
, NULL
);
465 if(AnchorPath
->ap_Info
.fib_DirEntryType
> 0L)
467 if(!(AnchorPath
->ap_Flags
& APF_DIDDIR
))
469 AnchorPath
->ap_Flags
|= APF_DODIR
;
472 AnchorPath
->ap_Flags
&= ~APF_DIDDIR
;
476 if(!MatchPatternNoCase(ExclPat
,
477 AnchorPath
->ap_Info
.fib_FileName
))
479 OldDir
= CurrentDir(AnchorPath
->ap_Current
->an_Lock
);
481 LoadDataType(sv
, AnchorPath
->ap_Info
.fib_FileName
);
487 RetVal
= MatchNext(AnchorPath
);
490 if(RetVal
!= ERROR_NO_MORE_ENTRIES
)
494 PrintFault(RetVal
, NULL
);
498 MatchEnd(AnchorPath
);
500 FreeVec((APTR
)AnchorPath
);
505 /****** AddDataTypes/CreateDTList *********************************************
508 * CreateDTList - Create and initialize the DataTypesList
522 ******************************************************************************
526 struct DataTypesList
*CreateDTList(struct StackVars
*sv
)
528 struct DataTypesList
*dtl
= NULL
;
529 struct NamedObject
*no
= NULL
;
530 struct Library
*DTBase
;
532 /* We do this in order to force datatypes.library to get
533 loaded and initialized. During this process it will
534 create and install DataTypes list object in memory. */
535 DTBase
= OpenLibrary("datatypes.library", 0);
537 CloseLibrary(DTBase
);
539 if((no
= FindNamedObject(NULL
, DATATYPESLIST
, NULL
)))
541 dtl
= (struct DataTypesList
*)no
->no_Object
;
546 if(!__FindNameNoCase(sv
, &dtl
->dtl_BinaryList
, "binary"))
550 sv
, &dtl
->dtl_BinaryList
, &dtl
->dtl_SortedList
,
551 "binary", DTF_BINARY
, ID_BINARY
, GID_SYSTEM
555 if(!__FindNameNoCase(sv
, &dtl
->dtl_ASCIIList
, "ascii"))
559 sv
, &dtl
->dtl_ASCIIList
, &dtl
->dtl_SortedList
,
560 "ascii", DTF_ASCII
, ID_ASCII
, GID_TEXT
564 if(!__FindNameNoCase(sv
, &dtl
->dtl_IFFList
, "iff"))
568 sv
, &dtl
->dtl_IFFList
, &dtl
->dtl_SortedList
,
569 "iff", DTF_IFF
, ID_IFF
, GID_SYSTEM
573 if(!__FindNameNoCase(sv
, &dtl
->dtl_MiscList
, "directory"))
577 sv
, &dtl
->dtl_MiscList
, &dtl
->dtl_SortedList
,
578 "directory", DTF_MISC
, ID_DIRECTORY
, GID_SYSTEM
585 ReleaseNamedObject(no
);
594 /****** AddDataTypes/CreateBasicType ******************************************
597 * CreateBasicType - Initialize one of the basic types
611 ******************************************************************************
615 struct CompoundDataType
*CreateBasicType(struct StackVars
*sv
,
617 struct List
*globallist
, STRPTR name
,
618 UWORD Flags
, ULONG ID
, ULONG GroupID
)
620 struct CompoundDataType
*cdt
;
621 ULONG AllocLen
= sizeof(struct CompoundDataType
) + strlen(name
) + 1;
623 if((cdt
= AllocVec(AllocLen
, MEMF_PUBLIC
| MEMF_CLEAR
)))
625 cdt
->DT
.dtn_Header
= &cdt
->DTH
;
627 strcpy((UBYTE
*)(cdt
+ 1), name
);
630 cdt
->DTH
.dth_BaseName
=
631 cdt
->DT
.dtn_Node1
.ln_Name
=
632 cdt
->DT
.dtn_Node2
.ln_Name
=(UBYTE
*)(cdt
+ 1);
634 cdt
->DTH
.dth_GroupID
= GroupID
;
635 cdt
->DTH
.dth_ID
= ID
;
637 cdt
->DTH
.dth_Flags
= Flags
;
639 NewList(&cdt
->DT
.dtn_ToolList
);
641 cdt
->DT
.dtn_Length
= AllocLen
;
643 cdt
->DT
.dtn_Node1
.ln_Pri
= -128;
644 Enqueue(list
, &cdt
->DT
.dtn_Node1
);
646 AlphaInsert(sv
, globallist
, &cdt
->DT
.dtn_Node2
);
654 /****** AddDataTypes/LoadDataType *********************************************
657 * LoadDataType - Load and install a single DataType descriptor
671 ******************************************************************************
675 void LoadDataType(struct StackVars
*sv
, STRPTR name
)
677 struct IFFHandle
*iff
;
679 if((iff
= AllocIFF()))
681 if((iff
->iff_Stream
= (IPTR
)Open(name
, MODE_OLDFILE
))) /* Why IPTR? */
685 if(!OpenIFF(iff
, IFFF_READ
))
687 if(!PropChunks(iff
, PropArray
, NUM_PROP
))
689 if(!CollectionChunks(iff
, CollArray
, NUM_COLL
))
691 if(!StopOnExit(iff
, ID_DTYP
, ID_FORM
))
695 while((error
= ParseIFF(iff
, IFFPARSE_SCAN
)) == IFFERR_EOC
)
697 CreateDataType(sv
, iff
);
698 /* FIXME: The while ParseIFF loop here crashes the 2nd time inside the loop, therefore the break below as temp fix */
708 Close((BPTR
)iff
->iff_Stream
);
715 SetIoErr(ERROR_NO_FREE_STORE
);
720 /****** AddDataTypes/MemStreamHook *******************************************
723 * MemStreamHook - needed by ReadStruct
737 ******************************************************************************
741 LONG
MemStreamHook(struct Hook
* hook
, UBYTE
**memptr
, Msg msg
)
745 switch (msg
->MethodID
)
760 /****** AddDataTypes/CreateDataType *******************************************
763 * CreateDataType - create a DataType from IFF chunks
777 ******************************************************************************
781 struct CompoundDataType
*CreateDataType(struct StackVars
*sv
,
782 struct IFFHandle
*iff
)
784 struct CompoundDataType
*cdt
= NULL
;
785 struct StoredProperty
*prop
;
788 LONG DefaultStack
= AROS_STACKSIZE
, i
;
791 if((prop
= FindProp(iff
, ID_DTYP
, ID_DTHD
)))
793 AllocLen
= sizeof(struct CompoundDataType
) -
794 32 + /* was sizeof(struct DataTypeHeader), but we must use struct size as it would be on Amiga */
797 if(!(cdt
= AllocVec(AllocLen
, MEMF_PUBLIC
| MEMF_CLEAR
)))
799 SetIoErr(ERROR_NO_FREE_STORE
);
803 struct FileDataTypeHeader
*fdh
= NULL
;
804 UBYTE
*memptr
= (UBYTE
*)prop
->sp_Data
;
807 hook
.h_Entry
= (HOOKFUNC
)HookEntry
;
808 hook
.h_SubEntry
= (HOOKFUNC
)MemStreamHook
;
810 if (ReadStruct(&hook
, (APTR
*) &fdh
, &memptr
, FileDataTypeHeaderDesc
))
812 IPTR extraoffset
= sizeof(struct DataTypeHeader
) - 32;
814 cdt
->DT
.dtn_Header
= &cdt
->DTH
;
816 cdt
->DTH
.dth_Name
= (STRPTR
)(fdh
->fdth_NameOffset
+ extraoffset
+ (IPTR
)&cdt
->DTH
);
817 cdt
->DTH
.dth_BaseName
= (STRPTR
)(fdh
->fdth_BaseNameOffset
+ extraoffset
+ (IPTR
)&cdt
->DTH
);
818 cdt
->DTH
.dth_Pattern
= (STRPTR
)(fdh
->fdth_PatternOffset
+ extraoffset
+ (IPTR
)&cdt
->DTH
);
819 cdt
->DTH
.dth_Mask
= (WORD
*)(fdh
->fdth_MaskOffset
+ extraoffset
+ (IPTR
)&cdt
->DTH
);
820 cdt
->DTH
.dth_GroupID
= fdh
->fdth_GroupID
;
821 cdt
->DTH
.dth_ID
= fdh
->fdth_ID
;
822 cdt
->DTH
.dth_MaskLen
= fdh
->fdth_MaskLen
;
823 cdt
->DTH
.dth_Pad
= fdh
->fdth_Pad
;
824 cdt
->DTH
.dth_Flags
= fdh
->fdth_Flags
;
825 cdt
->DTH
.dth_Priority
= fdh
->fdth_Priority
;
827 CopyMem(prop
->sp_Data
+ 32, cdt
+ 1, prop
->sp_Size
- 32);
829 for(i
= 0; i
< cdt
->DTH
.dth_MaskLen
; i
++)
831 cdt
->DTH
.dth_Mask
[i
] = AROS_BE2WORD(cdt
->DTH
.dth_Mask
[i
]);
833 kprintf("mask[%d] = %04x (%c %c)\n", i
,
834 cdt
->DTH
.dth_Mask
[i
],
835 cdt
->DTH
.dth_Mask
[i
] & 255,
836 (cdt
->DTH
.dth_Mask
[i
] >> 8) & 255);
841 kprintf("groupid = %c%c%c%c\n", cdt
->DTH
.dth_GroupID
>> 24,
842 cdt
->DTH
.dth_GroupID
>> 16,
843 cdt
->DTH
.dth_GroupID
>> 8,
844 cdt
->DTH
.dth_GroupID
);
845 kprintf("id = %c%c%c%c\n", cdt
->DTH
.dth_ID
>> 24,
846 cdt
->DTH
.dth_ID
>> 16,
847 cdt
->DTH
.dth_ID
>> 8,
849 kprintf("flags = %x\n", cdt
->DTH
.dth_Flags
);
850 kprintf("pri = %d\n", cdt
->DTH
.dth_Priority
);
851 kprintf("name = %s\n", cdt
->DTH
.dth_Name
);
852 kprintf("basename = %s\n", cdt
->DTH
.dth_BaseName
);
853 kprintf("pattern = %s\n", cdt
->DTH
.dth_Pattern
);
854 kprintf("masklen = %d\n", cdt
->DTH
.dth_MaskLen
);
857 NewList(&cdt
->DT
.dtn_ToolList
);
859 cdt
->DT
.dtn_Length
= AllocLen
;
861 if((prop
= FindProp(iff
, ID_DTYP
, ID_DTCD
)))
863 if((func
= AllocVec(prop
->sp_Size
, MEMF_PUBLIC
| MEMF_CLEAR
)))
865 cdt
->DTCDChunk
= func
;
866 cdt
->DTCDSize
= prop
->sp_Size
;
868 CopyMem(prop
->sp_Data
,func
,prop
->sp_Size
);
870 HookBuffer
= cdt
->DTCDChunk
;
871 HookBufSize
= cdt
->DTCDSize
;
874 /* We use a cast to BPTR, since sv may not
875 * be ULONG aligned. Since only our ReadFunc
876 * is going to be looking at it, this is ok.
878 if((SegList
= InternalLoadSeg((BPTR
)(sv
), BNULL
,
879 (LONG_FUNC
*)FunctionArray
,
882 cdt
->SegList
= SegList
;
883 cdt
->Function
= BADDR(SegList
) + sizeof(BPTR
);
886 } /* if((func = AllocVec(prop->sp_Size, MEMF_PUBLIC | MEMF_CLEAR))) */
888 } /* if((prop = FindProp(iff, ID_DTYP, ID_DTCD))) */
890 cdt
= AddDataType(sv
, cdt
);
892 FreeStruct(fdh
, FileDataTypeHeaderDesc
);
894 } /* if (ReadStruct(&hook, &fdh, &memptr, FileDataTypeHeaderDesc)) */
896 } /* cdt AllocVec okay */
898 } /* if((prop = FindProp(iff, ID_DTYP, ID_DTHD))) */
905 /****** AddDataTypes/AddDataType **********************************************
908 * AddDataType - add a DataType to the system
914 * This subroutine tries to add a DataType to the system DataTypes
915 * list. If the DataType already exists, it will be replaced or
916 * updated. In case of an error, the CompoundDataType will be deleted
917 * and a NULL pointer is returned.
919 * The CompoundDataType pointer you passed in will be invalid after
920 * calling this function. Use the returned handle instead.
921 * DO NOT USE THE OLD POINTER IN ANY MORE!
927 * A pointer to a CompoundDataType in the system DataTypes list
928 * or a NULL pointer for failure
934 ******************************************************************************
938 struct CompoundDataType
*AddDataType(struct StackVars
*sv
,
939 struct CompoundDataType
*cdt
)
941 struct List
*typelist
;
942 BOOL Success
= FALSE
;
945 struct CompoundDataType
*oldcdt
;
947 switch(cdt
->DTH
.dth_Flags
& DTF_TYPE_MASK
)
949 case DTF_BINARY
: typelist
= &DTList
->dtl_BinaryList
; break;
950 case DTF_ASCII
: typelist
= &DTList
->dtl_ASCIIList
; break;
951 case DTF_IFF
: typelist
= &DTList
->dtl_IFFList
; break;
952 case DTF_MISC
: typelist
= &DTList
->dtl_MiscList
; break;
953 default: typelist
= NULL
;
958 cdt
->DT
.dtn_Node1
.ln_Name
= cdt
->DT
.dtn_Node2
.ln_Name
= cdt
->DTH
.dth_Name
;
962 if((!Stricmp(cdt
->DTH
.dth_Pattern
, "#?")) ||
963 (!strlen(cdt
->DTH
.dth_Pattern
)) )
965 cdt
->FlagLong
|= CFLGF_PATTERN_UNUSED
;
969 cdt
->FlagLong
&= ~(CFLGF_PATTERN_UNUSED
);
971 AllocSize
= 2*strlen(cdt
->DTH
.dth_Pattern
) + 2;
973 if(!(cdt
->ParsePatMem
= AllocVec(AllocSize
,
974 MEMF_PUBLIC
| MEMF_CLEAR
)))
980 cdt
->ParsePatSize
= AllocSize
;
982 result
= ParsePatternNoCase(cdt
->DTH
.dth_Pattern
,
983 cdt
->ParsePatMem
, AllocSize
);
987 cdt
->FlagLong
|= CFLGF_IS_WILD
;
991 FreeVec(cdt
->ParsePatMem
);
992 cdt
->ParsePatMem
= NULL
;
993 cdt
->ParsePatSize
= 0;
997 cdt
->FlagLong
&= ~(CFLGF_IS_WILD
);
1009 if((oldcdt
= (struct CompoundDataType
*)__FindNameNoCase(sv
,
1011 cdt
->DT
.dtn_Node1
.ln_Name
)))
1013 if (oldcdt
->OpenCount
)
1019 if((Stricmp(oldcdt
->DTH
.dth_Name
, cdt
->DTH
.dth_Name
)) ||
1020 (Stricmp(oldcdt
->DTH
.dth_BaseName
, cdt
->DTH
.dth_BaseName
)) ||
1021 (Stricmp(oldcdt
->DTH
.dth_Pattern
, cdt
->DTH
.dth_Pattern
)) ||
1022 (oldcdt
->DTH
.dth_Flags
!= cdt
->DTH
.dth_Flags
) ||
1023 (oldcdt
->DTH
.dth_Priority
!= cdt
->DTH
.dth_Priority
) ||
1024 (oldcdt
->DTH
.dth_MaskLen
!= cdt
->DTH
.dth_MaskLen
))
1026 DeleteDataType(sv
, oldcdt
);
1031 oldcdt
->DTH
.dth_GroupID
= cdt
->DTH
.dth_GroupID
;
1032 oldcdt
->DTH
.dth_ID
= cdt
->DTH
.dth_ID
;
1033 CopyMem(cdt
->DTH
.dth_Mask
,cdt
->DTH
.dth_Mask
,
1034 (ULONG
)(sizeof(WORD
)*cdt
->DTH
.dth_MaskLen
));
1043 DeleteDataType(sv
, cdt
);
1048 if(cdt
->DT
.dtn_FunctionName
)
1050 LONG DefaultStack
= 4096;
1055 if((file
= Open(cdt
->DT
.dtn_FunctionName
, MODE_OLDFILE
)))
1057 if(Seek(file
, 0, OFFSET_END
) >= 0)
1059 if((AllocLen
= Seek(file
, 0,
1060 OFFSET_BEGINNING
)) > 0)
1062 if((cdt
->DTCDChunk
= AllocVec(AllocLen
,
1063 MEMF_PUBLIC
| MEMF_CLEAR
)))
1065 cdt
->DTCDSize
= AllocLen
;
1067 if(Read(file
, cdt
->DTCDChunk
, AllocLen
) == AllocLen
)
1069 HookBuffer
= cdt
->DTCDChunk
;
1070 HookBufSize
= cdt
->DTCDSize
;
1073 /* We use a cast to BPTR, since sv may not
1074 * be ULONG aligned. Since only our ReadFunc
1075 * is going to be looking at it, this is ok.
1077 if((SegList
= InternalLoadSeg((BPTR
)(sv
), BNULL
, (LONG_FUNC
*)FunctionArray
, &DefaultStack
)))
1079 cdt
->SegList
= SegList
;
1080 cdt
->Function
= BADDR(SegList
) + sizeof(BPTR
); // FIXME: is this portable?
1085 FreeVec(cdt
->DTCDChunk
);
1086 cdt
->DTCDChunk
= NULL
;
1093 cdt
->DT
.dtn_FunctionName
=NULL
;
1096 if(cdt
->DTH
.dth_MaskLen
> DTList
->dtl_LongestMask
)
1098 DTList
->dtl_LongestMask
= cdt
->DTH
.dth_MaskLen
;
1101 cdt
->DT
.dtn_Node1
.ln_Pri
= cdt
->DTH
.dth_Priority
;
1102 Enqueue(typelist
, &cdt
->DT
.dtn_Node1
);
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/__FindNameNoCase *****************************************
1220 * __FindNameNoCase - find a node in a list (case insensitive)
1234 ******************************************************************************
1238 struct Node
*__FindNameNoCase(struct StackVars
*sv
, struct List
*list
,
1242 struct Node
*result
= NULL
;
1244 for(node
= list
->lh_Head
; node
->ln_Succ
; node
= node
->ln_Succ
)
1246 if(!Stricmp(node
->ln_Name
, name
))
1258 /****** AddDataTypes/ReadFunc *************************************************
1261 * ReadFunc - data read hook for InternalLoadSeg
1275 ******************************************************************************
1279 AROS_UFH4(LONG
, AROS_SLIB_ENTRY(ReadFunc
, AddDataTypes
, 0),
1280 AROS_UFHA(BPTR
, fh
, D1
),
1281 AROS_UFHA(void * , buffer
, D2
),
1282 AROS_UFHA(LONG
, length
, D3
),
1283 AROS_UFHA(struct DosLibrary
*, DOSBase
, A6
))
1287 struct StackVars
*sv
= (APTR
)fh
;
1288 LONG maxlen
= HookBufSize
-HookPosition
;
1289 LONG actual
= length
> maxlen
? maxlen
: length
;
1291 CopyMem(HookBuffer
+HookPosition
, buffer
, actual
);
1293 HookPosition
+= actual
;
1300 /****** AddDataTypes/SeekFunc *************************************************
1303 * SeekFunc - seek hook for InternalLoadSeg (ELF only)
1317 ******************************************************************************
1321 AROS_UFH4(LONG
, AROS_SLIB_ENTRY(SeekFunc
, AddDataTypes
, 0),
1322 AROS_UFHA(BPTR
, fh
, D1
),
1323 AROS_UFHA(LONG
, pos
, D2
),
1324 AROS_UFHA(LONG
, mode
, D3
),
1325 AROS_UFHA(struct DosLibrary
*, DOSBase
, A6
))
1329 struct StackVars
*sv
= (APTR
)fh
;
1330 LONG oldpos
= HookPosition
;
1333 case OFFSET_BEGINNING
: break;
1334 case OFFSET_END
: pos
= HookBufSize
- pos
; break;
1335 case OFFSET_CURRENT
: pos
= HookPosition
+ pos
; break;
1339 if (pos
< 0 || pos
>= HookBufSize
)
1349 /****** AddDataTypes/AllocFunc ************************************************
1352 * AllocFunc - memory allocation hook for InternalLoadSeg
1366 ******************************************************************************
1370 AROS_UFH3(UBYTE
*, AROS_SLIB_ENTRY(AllocFunc
, AddDataTypes
, 0),
1371 AROS_UFHA(ULONG
, size
, D0
),
1372 AROS_UFHA(ULONG
, flags
,D1
),
1373 AROS_UFHA(struct DosLibrary
*, DOSBase
, A6
))
1377 return(AllocMem(size
, flags
));
1384 /****** AddDataTypes/FreeFunc *************************************************
1387 * FreeFunc - memory freeing hook for InternalLoadSeg
1401 ******************************************************************************
1405 AROS_UFH3(void, AROS_SLIB_ENTRY(FreeFunc
, AddDataTypes
, 0),
1406 AROS_UFHA(APTR
, memory
, A1
),
1407 AROS_UFHA(ULONG
, size
, D0
),
1408 AROS_UFHA(struct DosLibrary
*, DOSBase
, A6
))
1412 FreeMem(memory
, size
);
1419 /******************************* STUB ROUTINES ********************************/
1421 struct NamedObject
*allocnamedobject(struct StackVars
*sv
, STRPTR name
,
1424 return AllocNamedObjectA(name
, (struct TagItem
*)&FirstTag
);