2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
6 #include <aros/macros.h>
7 #include <aros/bigendianio.h>
8 #include <exec/types.h>
9 #include <exec/memory.h>
10 #include <exec/execbase.h>
12 #include <dos/dosasl.h>
13 #include <dos/dosextens.h>
14 #include <libraries/iffparse.h>
15 #include <utility/name.h>
16 #include <utility/hooks.h>
17 #include <workbench/startup.h>
19 #include <proto/exec.h>
20 #include <proto/dos.h>
21 #include <proto/utility.h>
22 #include <proto/iffparse.h>
23 #include <proto/alib.h>
24 #include <proto/arossupport.h>
29 #include "../libs/datatypes/datatypes_intern.h"
36 /******************************** STRUCTURES *********************************/
38 /* same as datatypes/datatypes.h/struct DataTypeHeader, but always big endian
39 and 32 bit pointers (which in the file are actually offsets) */
41 struct FileDataTypeHeader
43 ULONG fdth_NameOffset
; /* Name of the data type */
44 ULONG fdth_BaseNameOffset
; /* Base name of the data type */
45 ULONG fdth_PatternOffset
; /* File name match pattern */
46 ULONG fdth_MaskOffset
; /* Comparision mask (binary) */
47 ULONG fdth_GroupID
; /* DataType Group */
48 ULONG fdth_ID
; /* DataType ID (same as IFF FORM type) */
49 WORD fdth_MaskLen
; /* Length of the comparision mask */
50 WORD fdth_Pad
; /* Unused at present (must be 0) */
51 UWORD fdth_Flags
; /* Flags -- see below */
55 #define O(x) offsetof(struct FileDataTypeHeader,x)
57 static const IPTR FileDataTypeHeaderDesc
[] =
59 sizeof(struct FileDataTypeHeader
),
60 SDM_ULONG(O(fdth_NameOffset
)),
61 SDM_ULONG(O(fdth_BaseNameOffset
)),
62 SDM_ULONG(O(fdth_PatternOffset
)),
63 SDM_ULONG(O(fdth_MaskOffset
)),
64 SDM_ULONG(O(fdth_GroupID
)),
65 SDM_ULONG(O(fdth_ID
)),
66 SDM_WORD(O(fdth_MaskLen
)),
67 SDM_WORD(O(fdth_Pad
)),
68 SDM_UWORD(O(fdth_Flags
)),
69 SDM_UWORD(O(fdth_Priority
)),
73 /******************************** PROTOTYPES *********************************/
75 struct StackVars
; /* forward declaration */
77 BOOL
DateScan(struct StackVars
*sv
);
78 void ScanDirectory(struct StackVars
*sv
, STRPTR pattern
);
79 struct DataTypesList
*CreateDTList(struct StackVars
*sv
);
80 struct CompoundDatatype
*CreateBasicType(struct StackVars
*sv
,
82 struct List
*globallist
, STRPTR name
,
83 UWORD Flags
, ULONG ID
, ULONG GroupID
);
84 void LoadDatatype(struct StackVars
*sv
, STRPTR name
);
85 struct CompoundDatatype
*CreateDatatype(struct StackVars
*sv
,
86 struct IFFHandle
*iff
);
87 struct CompoundDatatype
*AddDatatype(struct StackVars
*sv
,
88 struct CompoundDatatype
*cdt
);
89 void DeleteDatatype(struct StackVars
*sv
, struct CompoundDatatype
*cdt
);
90 void AlphaInsert(struct StackVars
*sv
, struct List
*list
, struct Node
*node
);
91 void PrioInsert(struct StackVars
*sv
, struct List
*list
,
92 struct CompoundDatatype
*cdt
);
93 struct Node
*__FindNameNoCase(struct StackVars
*sv
, struct List
*list
,
95 LONG
ReadFunc(struct StackVars
*sv
, UBYTE
*buffer
, ULONG length
);
96 UBYTE
*AllocFunc(ULONG size
, ULONG flags
);
97 void FreeFunc(UBYTE
*memory
, ULONG size
);
100 /********************************* CONSTANTS *********************************/
102 UBYTE Version
[]="$VER: AddDatatypes 42.0";
105 UBYTE ExcludePattern
[] = "#?.(info|backdrop)";
107 UBYTE Template
[] = "FILES/M,QUIET/S,REFRESH/S,LIST/S";
117 #define ID_DTCD MAKE_ID('D','T','C','D')
118 #define ID_DTTL MAKE_ID('D','T','T','L')
122 LONG PropArray
[2*NUM_PROP
]=
130 LONG CollArray
[2*NUM_COLL
]=
136 LONG_FUNC FunctionArray
[]=
138 (LONG_FUNC
)&ReadFunc
,
139 (LONG_FUNC
)&AllocFunc
,
146 struct DataTypesList
*DTList
;
147 UBYTE ExclPat
[2*EXCL_LEN
+2+1];
152 BOOL DidCreateDTList
;
156 #define DTList sv->DTList
157 #define ExclPat sv->ExclPat
159 #define HookBuffer sv->HookBuffer
160 #define HookBufSize sv->HookBufSize
161 #define HookPosition sv->HookPosition
162 #define DidCreateDTList sv->DidCreateDTList
164 /****** AddDatatypes/main *****************************************************
167 * main - well... main
181 ******************************************************************************
184 int UtilityBase_version
= 37;
185 int LocaleBase_version
= 37;
186 int IFFParseBase_version
= 37;
188 int __nocommandline
= 1;
192 extern struct WBStartup
*WBenchMsg
;
193 struct StackVars vars
;
194 struct StackVars
*sv
;
195 int result
= RETURN_FAIL
;
197 memset(&vars
, 0, sizeof(struct StackVars
));
200 if((DTList
= CreateDTList(sv
)))
202 ParsePatternNoCase(ExcludePattern
, ExclPat
, sizeof(ExclPat
));
204 ObtainSemaphore(&DTList
->dtl_Lock
);
209 struct WBArg
*wa
= &WBenchMsg
->sm_ArgList
[1];
211 for(num
= 1; num
<WBenchMsg
->sm_NumArgs
; wa
++)
213 BPTR olddir
= CurrentDir(wa
->wa_Lock
);
214 LoadDatatype(sv
, wa
->wa_Name
);
222 struct RDArgs
*RDArgs
;
224 if(!(RDArgs
= ReadArgs(Template
, (LONG
*)&AA
, NULL
)))
226 PrintFault(IoErr(), NULL
);
232 if(DidCreateDTList
|| DateScan(sv
))
234 ScanDirectory(sv
, "DEVS:DataTypes");
239 UBYTE
**files
= AA
.aa_Files
;
245 ScanDirectory(sv
, *files
);
253 struct DataTypesList
*dtl
= NULL
;
254 struct NamedObject
*no
= NULL
;
255 if((no
= FindNamedObject(NULL
, DATATYPESLIST
, NULL
)))
257 dtl
= (struct DataTypesList
*)no
->no_Object
;
258 ReleaseNamedObject(no
);
261 struct Node
*node
=dtl
->dtl_SortedList
.lh_Head
;
262 while(node
->ln_Succ
!= NULL
)
264 // sorted list points to DT.dtn_Node2 ....
265 struct CompoundDatatype
*cdt
;
266 struct DataTypeHeader
*dth
;
269 if(CheckSignal(SIGBREAKF_CTRL_C
))
272 PrintFault(ERROR_BREAK
,0);
275 cdt
=(struct CompoundDatatype
*)(node
-1);
276 dth
=cdt
->DT
.dtn_Header
;
278 argarray
[0] = dth
->dth_BaseName
;
279 argarray
[1] = dth
->dth_Name
;
281 VPrintf("%s, \"%s\"\n",argarray
);
282 node
= node
->ln_Succ
;
294 ReleaseSemaphore(&DTList
->dtl_Lock
);
302 /****** AddDatatypes/DateScan *************************************************
305 * DateScan - See if datatypes descriptors need updating
319 ******************************************************************************
323 BOOL
DateScan(struct StackVars
*sv
)
327 struct FileInfoBlock
*fib
;
329 if((lock
= Lock("DEVS:Datatypes", ACCESS_READ
)))
331 if((fib
= AllocDosObject(DOS_FIB
, NULL
)))
333 if(Examine(lock
, fib
))
335 if(!CompareDates(&fib
->fib_Date
, &DTList
->dtl_DateStamp
))
341 DTList
->dtl_DateStamp
= fib
->fib_Date
;
345 FreeDosObject(DOS_FIB
,fib
);
356 /****** AddDatatypes/ScanDirectory ********************************************
359 * ScanDirectory - Scan a directory recursively for DT descriptors
373 ******************************************************************************
377 void ScanDirectory(struct StackVars
*sv
, STRPTR pattern
)
379 struct AnchorPath
*AnchorPath
;
383 if((AnchorPath
= (struct AnchorPath
*)AllocVec(sizeof(struct AnchorPath
),
386 AnchorPath
->ap_BreakBits
= SIGBREAKF_CTRL_C
;
388 RetVal
= MatchFirst(pattern
, AnchorPath
);
392 if(CheckSignal(SIGBREAKF_CTRL_C
))
396 PrintFault(ERROR_BREAK
, NULL
);
402 if(AnchorPath
->ap_Info
.fib_DirEntryType
> 0L)
404 if(!(AnchorPath
->ap_Flags
& APF_DIDDIR
))
406 AnchorPath
->ap_Flags
|= APF_DODIR
;
409 AnchorPath
->ap_Flags
&= ~APF_DIDDIR
;
413 if(!MatchPatternNoCase(ExclPat
,
414 AnchorPath
->ap_Info
.fib_FileName
))
416 OldDir
= CurrentDir(AnchorPath
->ap_Current
->an_Lock
);
418 LoadDatatype(sv
, AnchorPath
->ap_Info
.fib_FileName
);
424 RetVal
= MatchNext(AnchorPath
);
427 if(RetVal
!= ERROR_NO_MORE_ENTRIES
)
431 PrintFault(RetVal
, NULL
);
435 MatchEnd(AnchorPath
);
437 FreeVec((APTR
)AnchorPath
);
442 /****** AddDatatypes/CreateDTList *********************************************
445 * CreateDTList - Create and initialize the DataTypesList
459 ******************************************************************************
463 struct DataTypesList
*CreateDTList(struct StackVars
*sv
)
465 struct DataTypesList
*dtl
= NULL
;
466 struct NamedObject
*no
= NULL
;
468 if((no
= FindNamedObject(NULL
, DATATYPESLIST
, NULL
)))
470 dtl
= (struct DataTypesList
*)no
->no_Object
;
475 struct TagItem tags
[] =
477 {ANO_NameSpace
, TRUE
},
478 {ANO_UserSpace
, sizeof(struct DataTypesList
) },
479 {ANO_Flags
, NSF_NODUPS
| NSF_CASE
},
483 if((no
= AllocNamedObjectA(DATATYPESLIST
, tags
)))
485 if(!(dtl
= (struct DataTypesList
*)no
->no_Object
))
494 InitSemaphore(&dtl
->dtl_Lock
);
496 DidCreateDTList
= TRUE
;
498 NewList(&dtl
->dtl_SortedList
);
499 NewList(&dtl
->dtl_BinaryList
);
500 NewList(&dtl
->dtl_ASCIIList
);
501 NewList(&dtl
->dtl_IFFList
);
502 NewList(&dtl
->dtl_MiscList
);
504 if(!AddNamedObject(NULL
, no
))
515 if(!__FindNameNoCase(sv
, &dtl
->dtl_BinaryList
, "binary"))
519 sv
, &dtl
->dtl_BinaryList
, &dtl
->dtl_SortedList
,
520 "binary", DTF_BINARY
, ID_BINARY
, GID_SYSTEM
524 if(!__FindNameNoCase(sv
, &dtl
->dtl_ASCIIList
, "ascii"))
528 sv
, &dtl
->dtl_ASCIIList
, &dtl
->dtl_SortedList
,
529 "ascii", DTF_ASCII
, ID_ASCII
, GID_TEXT
533 if(!__FindNameNoCase(sv
, &dtl
->dtl_IFFList
, "iff"))
537 sv
, &dtl
->dtl_IFFList
, &dtl
->dtl_SortedList
,
538 "iff", DTF_IFF
, ID_IFF
, GID_SYSTEM
542 if(!__FindNameNoCase(sv
, &dtl
->dtl_MiscList
, "directory"))
546 sv
, &dtl
->dtl_MiscList
, &dtl
->dtl_SortedList
,
547 "directory", DTF_MISC
, ID_DIRECTORY
, GID_SYSTEM
554 ReleaseNamedObject(no
);
563 /****** AddDatatypes/CreateBasicType ******************************************
566 * CreateBasicType - Initialize one of the basic types
580 ******************************************************************************
584 struct CompoundDatatype
*CreateBasicType(struct StackVars
*sv
,
586 struct List
*globallist
, STRPTR name
,
587 UWORD Flags
, ULONG ID
, ULONG GroupID
)
589 struct CompoundDatatype
*cdt
;
590 ULONG AllocLen
= sizeof(struct CompoundDatatype
) + strlen(name
) + 1;
592 if((cdt
= AllocVec(AllocLen
, MEMF_PUBLIC
| MEMF_CLEAR
)))
594 cdt
->DT
.dtn_Header
= &cdt
->DTH
;
596 strcpy((UBYTE
*)(cdt
+ 1), name
);
599 cdt
->DTH
.dth_BaseName
=
600 cdt
->DT
.dtn_Node1
.ln_Name
=
601 cdt
->DT
.dtn_Node2
.ln_Name
=(UBYTE
*)(cdt
+ 1);
603 cdt
->DTH
.dth_GroupID
= GroupID
;
604 cdt
->DTH
.dth_ID
= ID
;
606 cdt
->DTH
.dth_Flags
= Flags
;
608 NewList(&cdt
->DT
.dtn_ToolList
);
610 cdt
->DT
.dtn_Length
= AllocLen
;
612 AddTail(list
, &cdt
->DT
.dtn_Node1
);
614 AlphaInsert(sv
, globallist
, &cdt
->DT
.dtn_Node2
);
622 /****** AddDatatypes/LoadDatatype *********************************************
625 * LoadDatatype - Load and install a single datatype descriptor
639 ******************************************************************************
643 void LoadDatatype(struct StackVars
*sv
, STRPTR name
)
645 struct IFFHandle
*iff
;
647 if((iff
= AllocIFF()))
649 if((iff
->iff_Stream
= (IPTR
)Open(name
, MODE_OLDFILE
))) /* Why IPTR? */
653 if(!OpenIFF(iff
, IFFF_READ
))
655 if(!PropChunks(iff
, PropArray
, NUM_PROP
))
657 if(!CollectionChunks(iff
, CollArray
, NUM_COLL
))
659 if(!StopOnExit(iff
, ID_DTYP
, ID_FORM
))
663 while((error
= ParseIFF(iff
, IFFPARSE_SCAN
)) == IFFERR_EOC
)
665 CreateDatatype(sv
, iff
);
666 #warning The while ParseIFF loop here crashes the 2nd time inside the loop, therefore the break below as temp fix
676 Close((BPTR
)iff
->iff_Stream
);
683 SetIoErr(ERROR_NO_FREE_STORE
);
688 /****** AddDatatypes/MemStreamHook *******************************************
691 * MemStreamHook - needed by ReadStruct
705 ******************************************************************************
709 LONG
MemStreamHook(struct Hook
* hook
, UBYTE
**memptr
, Msg msg
)
713 switch (msg
->MethodID
)
728 /****** AddDatatypes/CreateDatatype *******************************************
731 * CreateDatatype - create a datatype from IFF chunks
745 ******************************************************************************
749 struct CompoundDatatype
*CreateDatatype(struct StackVars
*sv
,
750 struct IFFHandle
*iff
)
752 struct CompoundDatatype
*cdt
= NULL
;
753 struct StoredProperty
*prop
;
756 LONG DefaultStack
= AROS_STACKSIZE
, i
;
759 if((prop
= FindProp(iff
, ID_DTYP
, ID_DTHD
)))
761 AllocLen
= sizeof(struct CompoundDatatype
) -
762 32 + /* was sizeof(struct DataTypeHeader), but we must use struct size as it would be on Amiga */
765 if(!(cdt
= AllocVec(AllocLen
, MEMF_PUBLIC
| MEMF_CLEAR
)))
767 SetIoErr(ERROR_NO_FREE_STORE
);
771 struct FileDataTypeHeader
*fdh
;
772 UBYTE
*memptr
= (UBYTE
*)prop
->sp_Data
;
775 hook
.h_Entry
= (HOOKFUNC
)HookEntry
;
776 hook
.h_SubEntry
= (HOOKFUNC
)MemStreamHook
;
778 if (ReadStruct(&hook
, (APTR
*) &fdh
, &memptr
, FileDataTypeHeaderDesc
))
780 IPTR extraoffset
= sizeof(struct DataTypeHeader
) - 32;
782 cdt
->DT
.dtn_Header
= &cdt
->DTH
;
784 cdt
->DTH
.dth_Name
= (STRPTR
)(fdh
->fdth_NameOffset
+ extraoffset
+ (IPTR
)&cdt
->DTH
);
785 cdt
->DTH
.dth_BaseName
= (STRPTR
)(fdh
->fdth_BaseNameOffset
+ extraoffset
+ (IPTR
)&cdt
->DTH
);
786 cdt
->DTH
.dth_Pattern
= (STRPTR
)(fdh
->fdth_PatternOffset
+ extraoffset
+ (IPTR
)&cdt
->DTH
);
787 cdt
->DTH
.dth_Mask
= (WORD
*)(fdh
->fdth_MaskOffset
+ extraoffset
+ (IPTR
)&cdt
->DTH
);
788 cdt
->DTH
.dth_GroupID
= fdh
->fdth_GroupID
;
789 cdt
->DTH
.dth_ID
= fdh
->fdth_ID
;
790 cdt
->DTH
.dth_MaskLen
= fdh
->fdth_MaskLen
;
791 cdt
->DTH
.dth_Pad
= fdh
->fdth_Pad
;
792 cdt
->DTH
.dth_Flags
= fdh
->fdth_Flags
;
793 cdt
->DTH
.dth_Priority
= fdh
->fdth_Priority
;
795 CopyMem(prop
->sp_Data
+ 32, cdt
+ 1, prop
->sp_Size
- 32);
797 for(i
= 0; i
< cdt
->DTH
.dth_MaskLen
; i
++)
799 cdt
->DTH
.dth_Mask
[i
] = AROS_BE2WORD(cdt
->DTH
.dth_Mask
[i
]);
801 kprintf("mask[%d] = %04x (%c %c)\n", i
,
802 cdt
->DTH
.dth_Mask
[i
],
803 cdt
->DTH
.dth_Mask
[i
] & 255,
804 (cdt
->DTH
.dth_Mask
[i
] >> 8) & 255);
809 kprintf("groupid = %c%c%c%c\n", cdt
->DTH
.dth_GroupID
>> 24,
810 cdt
->DTH
.dth_GroupID
>> 16,
811 cdt
->DTH
.dth_GroupID
>> 8,
812 cdt
->DTH
.dth_GroupID
);
813 kprintf("id = %c%c%c%c\n", cdt
->DTH
.dth_ID
>> 24,
814 cdt
->DTH
.dth_ID
>> 16,
815 cdt
->DTH
.dth_ID
>> 8,
817 kprintf("flags = %x\n", cdt
->DTH
.dth_Flags
);
818 kprintf("pri = %d\n", cdt
->DTH
.dth_Priority
);
819 kprintf("name = %s\n", cdt
->DTH
.dth_Name
);
820 kprintf("basename = %s\n", cdt
->DTH
.dth_BaseName
);
821 kprintf("pattern = %s\n", cdt
->DTH
.dth_Pattern
);
822 kprintf("masklen = %d\n", cdt
->DTH
.dth_MaskLen
);
825 NewList(&cdt
->DT
.dtn_ToolList
);
827 cdt
->DT
.dtn_Length
= AllocLen
;
829 if((prop
= FindProp(iff
, ID_DTYP
, ID_DTCD
)))
831 if((func
= AllocVec(prop
->sp_Size
, MEMF_PUBLIC
| MEMF_CLEAR
)))
833 cdt
->DTCDChunk
= func
;
834 cdt
->DTCDSize
= prop
->sp_Size
;
836 CopyMem(prop
->sp_Data
,func
,prop
->sp_Size
);
838 HookBuffer
= cdt
->DTCDChunk
;
839 HookBufSize
= cdt
->DTCDSize
;
842 if((SegList
= InternalLoadSeg((BPTR
)sv
, NULL
,
843 (LONG_FUNC
)FunctionArray
,
846 cdt
->SegList
= SegList
;
847 cdt
->Function
= (APTR
)((((ULONG
)SegList
) << 2) + 4);
850 } /* if((func = AllocVec(prop->sp_Size, MEMF_PUBLIC | MEMF_CLEAR))) */
852 } /* if((prop = FindProp(iff, ID_DTYP, ID_DTCD))) */
854 cdt
= AddDatatype(sv
, cdt
);
856 FreeStruct(fdh
, FileDataTypeHeaderDesc
);
858 } /* if (ReadStruct(&hook, &fdh, &memptr, FileDataTypeHeaderDesc)) */
860 } /* cdt AllocVec okay */
862 } /* if((prop = FindProp(iff, ID_DTYP, ID_DTHD))) */
869 /****** AddDatatypes/AddDatatype **********************************************
872 * AddDatatype - add a datatype to the system
878 * This subroutine tries to add a datatype to the system datatypes
879 * list. If the datatype already exists, it will be replaced or
880 * updated. In case of an error, the CompoundDatatype will be deleted
881 * and a NULL pointer is returned.
883 * The CompoundDatatype pointer you passed in will be invalid after
884 * calling this function. Use the returned handle instead.
885 * DO NOT USE THE OLD POINTER IN ANY MORE!
891 * A pointer to a CompoundDatatype in the system datatypes list
892 * or a NULL pointer for failure
898 ******************************************************************************
902 struct CompoundDatatype
*AddDatatype(struct StackVars
*sv
,
903 struct CompoundDatatype
*cdt
)
905 struct List
*typelist
;
906 BOOL Success
= FALSE
;
909 struct CompoundDatatype
*oldcdt
;
911 switch(cdt
->DTH
.dth_Flags
& DTF_TYPE_MASK
)
913 case DTF_BINARY
: typelist
= &DTList
->dtl_BinaryList
; break;
914 case DTF_ASCII
: typelist
= &DTList
->dtl_ASCIIList
; break;
915 case DTF_IFF
: typelist
= &DTList
->dtl_IFFList
; break;
916 case DTF_MISC
: typelist
= &DTList
->dtl_MiscList
; break;
917 default: typelist
= NULL
;
922 cdt
->DT
.dtn_Node1
.ln_Name
= cdt
->DT
.dtn_Node2
.ln_Name
= cdt
->DTH
.dth_Name
;
926 if((!Stricmp(cdt
->DTH
.dth_Pattern
, "#?")) ||
927 (!strlen(cdt
->DTH
.dth_Pattern
)) )
929 cdt
->FlagLong
|= CFLGF_PATTERN_UNUSED
;
933 cdt
->FlagLong
&= ~(CFLGF_PATTERN_UNUSED
);
935 AllocSize
= 2*strlen(cdt
->DTH
.dth_Pattern
) + 2;
937 if(!(cdt
->ParsePatMem
= AllocVec(AllocSize
,
938 MEMF_PUBLIC
| MEMF_CLEAR
)))
944 cdt
->ParsePatSize
= AllocSize
;
946 result
= ParsePatternNoCase(cdt
->DTH
.dth_Pattern
,
947 cdt
->ParsePatMem
, AllocSize
);
951 cdt
->FlagLong
|= CFLGF_IS_WILD
;
955 FreeVec(cdt
->ParsePatMem
);
956 cdt
->ParsePatMem
= NULL
;
957 cdt
->ParsePatSize
= 0;
961 cdt
->FlagLong
&= ~(CFLGF_IS_WILD
);
973 if((oldcdt
= (struct CompoundDatatype
*)__FindNameNoCase(sv
,
975 cdt
->DT
.dtn_Node1
.ln_Name
)))
977 if (oldcdt
->OpenCount
)
983 if((Stricmp(oldcdt
->DTH
.dth_Name
, cdt
->DTH
.dth_Name
)) ||
984 (Stricmp(oldcdt
->DTH
.dth_BaseName
, cdt
->DTH
.dth_BaseName
)) ||
985 (Stricmp(oldcdt
->DTH
.dth_Pattern
, cdt
->DTH
.dth_Pattern
)) ||
986 (oldcdt
->DTH
.dth_Flags
!= cdt
->DTH
.dth_Flags
) ||
987 (oldcdt
->DTH
.dth_Priority
!= cdt
->DTH
.dth_Priority
) ||
988 (oldcdt
->DTH
.dth_MaskLen
!= cdt
->DTH
.dth_MaskLen
))
990 DeleteDatatype(sv
, oldcdt
);
995 oldcdt
->DTH
.dth_GroupID
= cdt
->DTH
.dth_GroupID
;
996 oldcdt
->DTH
.dth_ID
= cdt
->DTH
.dth_ID
;
997 CopyMem(cdt
->DTH
.dth_Mask
,cdt
->DTH
.dth_Mask
,
998 (ULONG
)(sizeof(WORD
)*cdt
->DTH
.dth_MaskLen
));
1007 DeleteDatatype(sv
, cdt
);
1012 if(cdt
->DT
.dtn_FunctionName
)
1014 LONG DefaultStack
= 4096;
1019 if((file
= Open(cdt
->DT
.dtn_FunctionName
, MODE_OLDFILE
)))
1021 if(Seek(file
, 0, OFFSET_END
) >= 0)
1023 if((AllocLen
= Seek(file
, 0,
1024 OFFSET_BEGINNING
)) > 0)
1026 if((cdt
->DTCDChunk
= AllocVec(AllocLen
,
1027 MEMF_PUBLIC
| MEMF_CLEAR
)))
1029 cdt
->DTCDSize
= AllocLen
;
1031 if(Read(file
, cdt
->DTCDChunk
, AllocLen
) == AllocLen
)
1033 HookBuffer
= cdt
->DTCDChunk
;
1034 HookBufSize
= cdt
->DTCDSize
;
1037 if((SegList
= InternalLoadSeg((BPTR
)sv
, NULL
, (LONG_FUNC
)FunctionArray
, &DefaultStack
)))
1039 cdt
->SegList
= SegList
;
1040 cdt
->Function
= (APTR
)((((ULONG
)SegList
)<<2)+4);
1045 FreeVec(cdt
->DTCDChunk
);
1046 cdt
->DTCDChunk
= NULL
;
1053 cdt
->DT
.dtn_FunctionName
=NULL
;
1056 if(cdt
->DTH
.dth_MaskLen
> DTList
->dtl_LongestMask
)
1058 DTList
->dtl_LongestMask
= cdt
->DTH
.dth_MaskLen
;
1061 PrioInsert(sv
, typelist
, cdt
);
1063 AlphaInsert(sv
, &DTList
->dtl_SortedList
, &cdt
->DT
.dtn_Node2
);
1071 DeleteDatatype(sv
, cdt
);
1080 /****** AddDatatypes/DeleteDatatype *******************************************
1083 * DeleteDatatype - unlink and deallocate a CompoundDatatype structure
1097 ******************************************************************************
1101 void DeleteDatatype(struct StackVars
*sv
, struct CompoundDatatype
*cdt
)
1105 if(cdt
->ParsePatMem
)
1107 FreeVec(cdt
->ParsePatMem
);
1108 cdt
->ParsePatMem
= NULL
;
1109 cdt
->ParsePatSize
= 0;
1114 FreeVec(cdt
->DTCDChunk
);
1115 cdt
->DTCDChunk
= NULL
;
1121 UnLoadSeg(cdt
->SegList
);
1122 cdt
->SegList
= NULL
;
1123 cdt
->Function
= NULL
;
1126 if(cdt
->DT
.dtn_Node1
.ln_Succ
&& cdt
->DT
.dtn_Node1
.ln_Pred
)
1128 Remove(&cdt
->DT
.dtn_Node1
);
1129 Remove(&cdt
->DT
.dtn_Node2
);
1130 cdt
->DT
.dtn_Node1
.ln_Succ
= cdt
->DT
.dtn_Node1
.ln_Pred
=
1131 cdt
->DT
.dtn_Node2
.ln_Succ
= cdt
->DT
.dtn_Node2
.ln_Pred
= NULL
;
1140 /****** AddDatatypes/AlphaInsert **********************************************
1143 * AlphaInsert - enqueue a node alphabetically into a list
1157 ******************************************************************************
1161 void AlphaInsert(struct StackVars
*sv
, struct List
*list
, struct Node
*node
)
1163 struct Node
*cur
,*prev
=NULL
;
1165 for(cur
= list
->lh_Head
; cur
->ln_Succ
; prev
= cur
, cur
= cur
->ln_Succ
)
1167 if(Stricmp(cur
->ln_Name
, node
->ln_Name
) > 0)
1171 Insert(list
, node
, prev
);
1176 /****** AddDatatypes/PrioInsert **********************************************
1179 * PrioInsert - enqueue a CompoundDatatype correctly in the type list
1193 ******************************************************************************
1197 void PrioInsert(struct StackVars
*sv
, struct List
*list
,
1198 struct CompoundDatatype
*cdt
)
1200 struct CompoundDatatype
*cur
, *prev
= NULL
;
1203 for(cur
= (struct CompoundDatatype
*)list
->lh_Head
;
1204 cur
->DT
.dtn_Node1
.ln_Succ
;
1205 prev
= cur
, cur
= (struct CompoundDatatype
*)cur
->DT
.dtn_Node1
.ln_Succ
)
1207 diff
= (cdt
->Function
? 1 : 0) - (cur
->Function
? 1 : 0);
1214 UWORD MinMask
= (cdt
->DTH
.dth_MaskLen
< cur
->DTH
.dth_MaskLen
) ?
1215 cdt
->DTH
.dth_MaskLen
: cur
->DTH
.dth_MaskLen
;
1216 WORD
*cdtmask
= cdt
->DTH
.dth_Mask
;
1217 WORD
*curmask
=cur
->DTH
.dth_Mask
;
1219 while(!diff
&& MinMask
--)
1220 diff
= *(curmask
++) - *(cdtmask
++);
1227 diff
= cdt
->DTH
.dth_MaskLen
- cur
->DTH
.dth_MaskLen
;
1234 diff
= (((cdt
->FlagLong
& CFLGF_PATTERN_UNUSED
) || cdt
->DTH
.dth_Pattern
==NULL
) ? 0 : 1) -
1235 (((cur
->FlagLong
& CFLGF_PATTERN_UNUSED
) || cur
->DTH
.dth_Pattern
==NULL
) ? 0 : 1);
1242 diff
= cdt
->DTH
.dth_Priority
- cur
->DTH
.dth_Priority
;
1252 Insert(list
, &cdt
->DT
.dtn_Node1
, (struct Node
*)prev
);
1257 /****** AddDatatypes/__FindNameNoCase *****************************************
1260 * __FindNameNoCase - find a node in a list (case insensitive)
1274 ******************************************************************************
1278 struct Node
*__FindNameNoCase(struct StackVars
*sv
, struct List
*list
,
1282 struct Node
*result
= NULL
;
1284 for(node
= list
->lh_Head
; node
->ln_Succ
; node
= node
->ln_Succ
)
1286 if(!Stricmp(node
->ln_Name
, name
))
1298 /****** AddDatatypes/ReadFunc *************************************************
1301 * ReadFunc - data read hook for InternalLoadSeg
1315 ******************************************************************************
1319 LONG
ReadFunc(struct StackVars
*sv
, UBYTE
*buffer
, ULONG length
)
1321 LONG maxlen
= HookBufSize
-HookPosition
;
1322 LONG actual
= length
> maxlen
? maxlen
: length
;
1324 CopyMem(HookBuffer
+HookPosition
, buffer
, actual
);
1326 HookPosition
+= actual
;
1333 /****** AddDatatypes/AllocFunc ************************************************
1336 * AllocFunc - memory allocation hook for InternalLoadSeg
1350 ******************************************************************************
1354 UBYTE
*AllocFunc(ULONG size
, ULONG flags
)
1356 return(AllocMem(size
, flags
));
1361 /****** AddDatatypes/FreeFunc *************************************************
1364 * FreeFunc - memory freeing hook for InternalLoadSeg
1378 ******************************************************************************
1382 void FreeFunc(UBYTE
*memory
, ULONG size
)
1384 FreeMem(memory
, size
);
1389 /******************************* STUB ROUTINES ********************************/
1391 struct NamedObject
*allocnamedobject(struct StackVars
*sv
, STRPTR name
,
1394 return AllocNamedObjectA(name
, (struct TagItem
*)&FirstTag
);