2 Copyright © 1995-2007, 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>
81 #include "../libs/datatypes/datatypes_intern.h"
88 /******************************** STRUCTURES *********************************/
90 /* same as datatypes/datatypes.h/struct DataTypeHeader, but always big endian
91 and 32 bit pointers (which in the file are actually offsets) */
93 struct FileDataTypeHeader
95 ULONG fdth_NameOffset
; /* Name of the data type */
96 ULONG fdth_BaseNameOffset
; /* Base name of the data type */
97 ULONG fdth_PatternOffset
; /* File name match pattern */
98 ULONG fdth_MaskOffset
; /* Comparision mask (binary) */
99 ULONG fdth_GroupID
; /* DataType Group */
100 ULONG fdth_ID
; /* DataType ID (same as IFF FORM type) */
101 WORD fdth_MaskLen
; /* Length of the comparision mask */
102 WORD fdth_Pad
; /* Unused at present (must be 0) */
103 UWORD fdth_Flags
; /* Flags -- see below */
107 #define O(x) offsetof(struct FileDataTypeHeader,x)
109 static const IPTR FileDataTypeHeaderDesc
[] =
111 sizeof(struct FileDataTypeHeader
),
112 SDM_ULONG(O(fdth_NameOffset
)),
113 SDM_ULONG(O(fdth_BaseNameOffset
)),
114 SDM_ULONG(O(fdth_PatternOffset
)),
115 SDM_ULONG(O(fdth_MaskOffset
)),
116 SDM_ULONG(O(fdth_GroupID
)),
117 SDM_ULONG(O(fdth_ID
)),
118 SDM_WORD(O(fdth_MaskLen
)),
119 SDM_WORD(O(fdth_Pad
)),
120 SDM_UWORD(O(fdth_Flags
)),
121 SDM_UWORD(O(fdth_Priority
)),
125 /******************************** PROTOTYPES *********************************/
127 struct StackVars
; /* forward declaration */
129 BOOL
DateScan(struct StackVars
*sv
);
130 void ScanDirectory(struct StackVars
*sv
, STRPTR pattern
);
131 struct DataTypesList
*CreateDTList(struct StackVars
*sv
);
132 struct CompoundDatatype
*CreateBasicType(struct StackVars
*sv
,
134 struct List
*globallist
, STRPTR name
,
135 UWORD Flags
, ULONG ID
, ULONG GroupID
);
136 void LoadDatatype(struct StackVars
*sv
, STRPTR name
);
137 struct CompoundDatatype
*CreateDatatype(struct StackVars
*sv
,
138 struct IFFHandle
*iff
);
139 struct CompoundDatatype
*AddDatatype(struct StackVars
*sv
,
140 struct CompoundDatatype
*cdt
);
141 void DeleteDatatype(struct StackVars
*sv
, struct CompoundDatatype
*cdt
);
142 void AlphaInsert(struct StackVars
*sv
, struct List
*list
, struct Node
*node
);
143 void PrioInsert(struct StackVars
*sv
, struct List
*list
,
144 struct CompoundDatatype
*cdt
);
145 struct Node
*__FindNameNoCase(struct StackVars
*sv
, struct List
*list
,
147 LONG
ReadFunc(struct StackVars
*sv
, UBYTE
*buffer
, ULONG length
);
148 UBYTE
*AllocFunc(ULONG size
, ULONG flags
);
149 void FreeFunc(UBYTE
*memory
, ULONG size
);
152 /********************************* CONSTANTS *********************************/
154 const TEXT Version
[] = "$VER: AddDatatypes 42.1 (8.12.2007)\n";
157 UBYTE ExcludePattern
[] = "#?.(info|backdrop)";
159 UBYTE Template
[] = "FILES/M,QUIET/S,REFRESH/S,LIST/S";
169 #define ID_DTCD MAKE_ID('D','T','C','D')
170 #define ID_DTTL MAKE_ID('D','T','T','L')
174 LONG PropArray
[2*NUM_PROP
]=
182 LONG CollArray
[2*NUM_COLL
]=
188 LONG_FUNC FunctionArray
[]=
190 (LONG_FUNC
)&ReadFunc
,
191 (LONG_FUNC
)&AllocFunc
,
198 struct DataTypesList
*DTList
;
199 UBYTE ExclPat
[2*EXCL_LEN
+2+1];
207 #define DTList sv->DTList
208 #define ExclPat sv->ExclPat
210 #define HookBuffer sv->HookBuffer
211 #define HookBufSize sv->HookBufSize
212 #define HookPosition sv->HookPosition
214 /****** AddDatatypes/main *****************************************************
217 * main - well... main
231 ******************************************************************************
234 int UtilityBase_version
= 37;
235 int LocaleBase_version
= 37;
236 int IFFParseBase_version
= 37;
238 int __nocommandline
= 1;
242 extern struct WBStartup
*WBenchMsg
;
243 struct StackVars vars
;
244 struct StackVars
*sv
;
245 int result
= RETURN_FAIL
;
247 memset(&vars
, 0, sizeof(struct StackVars
));
250 if((DTList
= CreateDTList(sv
)))
252 ParsePatternNoCase(ExcludePattern
, ExclPat
, sizeof(ExclPat
));
254 ObtainSemaphore(&DTList
->dtl_Lock
);
259 struct WBArg
*wa
= &WBenchMsg
->sm_ArgList
[1];
261 for(num
= 1; num
<WBenchMsg
->sm_NumArgs
; wa
++)
263 BPTR olddir
= CurrentDir(wa
->wa_Lock
);
264 LoadDatatype(sv
, wa
->wa_Name
);
272 struct RDArgs
*RDArgs
;
274 if(!(RDArgs
= ReadArgs(Template
, (SIPTR
*)&AA
, NULL
)))
276 PrintFault(IoErr(), NULL
);
284 ScanDirectory(sv
, "DEVS:DataTypes");
289 UBYTE
**files
= AA
.aa_Files
;
295 ScanDirectory(sv
, *files
);
303 struct DataTypesList
*dtl
= NULL
;
304 struct NamedObject
*no
= NULL
;
305 if((no
= FindNamedObject(NULL
, DATATYPESLIST
, NULL
)))
307 dtl
= (struct DataTypesList
*)no
->no_Object
;
308 ReleaseNamedObject(no
);
311 struct Node
*node
=dtl
->dtl_SortedList
.lh_Head
;
312 while(node
->ln_Succ
!= NULL
)
314 // sorted list points to DT.dtn_Node2 ....
315 struct CompoundDatatype
*cdt
;
316 struct DataTypeHeader
*dth
;
319 if(CheckSignal(SIGBREAKF_CTRL_C
))
322 PrintFault(ERROR_BREAK
,0);
325 cdt
=(struct CompoundDatatype
*)(node
-1);
326 dth
=cdt
->DT
.dtn_Header
;
328 argarray
[0] = dth
->dth_BaseName
;
329 argarray
[1] = dth
->dth_Name
;
331 VPrintf("%s, \"%s\"\n", (IPTR
*)argarray
);
332 node
= node
->ln_Succ
;
344 ReleaseSemaphore(&DTList
->dtl_Lock
);
352 /****** AddDatatypes/DateScan *************************************************
355 * DateScan - See if datatypes descriptors need updating
369 ******************************************************************************
373 BOOL
DateScan(struct StackVars
*sv
)
377 struct FileInfoBlock
*fib
;
379 if((lock
= Lock("DEVS:Datatypes", ACCESS_READ
)))
381 if((fib
= AllocDosObject(DOS_FIB
, NULL
)))
383 if(Examine(lock
, fib
))
385 if(!CompareDates(&fib
->fib_Date
, &DTList
->dtl_DateStamp
))
391 DTList
->dtl_DateStamp
= fib
->fib_Date
;
395 FreeDosObject(DOS_FIB
,fib
);
406 /****** AddDatatypes/ScanDirectory ********************************************
409 * ScanDirectory - Scan a directory recursively for DT descriptors
423 ******************************************************************************
427 void ScanDirectory(struct StackVars
*sv
, STRPTR pattern
)
429 struct AnchorPath
*AnchorPath
;
433 if((AnchorPath
= (struct AnchorPath
*)AllocVec(sizeof(struct AnchorPath
),
436 AnchorPath
->ap_BreakBits
= SIGBREAKF_CTRL_C
;
438 RetVal
= MatchFirst(pattern
, AnchorPath
);
442 if(CheckSignal(SIGBREAKF_CTRL_C
))
446 PrintFault(ERROR_BREAK
, NULL
);
452 if(AnchorPath
->ap_Info
.fib_DirEntryType
> 0L)
454 if(!(AnchorPath
->ap_Flags
& APF_DIDDIR
))
456 AnchorPath
->ap_Flags
|= APF_DODIR
;
459 AnchorPath
->ap_Flags
&= ~APF_DIDDIR
;
463 if(!MatchPatternNoCase(ExclPat
,
464 AnchorPath
->ap_Info
.fib_FileName
))
466 OldDir
= CurrentDir(AnchorPath
->ap_Current
->an_Lock
);
468 LoadDatatype(sv
, AnchorPath
->ap_Info
.fib_FileName
);
474 RetVal
= MatchNext(AnchorPath
);
477 if(RetVal
!= ERROR_NO_MORE_ENTRIES
)
481 PrintFault(RetVal
, NULL
);
485 MatchEnd(AnchorPath
);
487 FreeVec((APTR
)AnchorPath
);
492 /****** AddDatatypes/CreateDTList *********************************************
495 * CreateDTList - Create and initialize the DataTypesList
509 ******************************************************************************
513 struct DataTypesList
*CreateDTList(struct StackVars
*sv
)
515 struct DataTypesList
*dtl
= NULL
;
516 struct NamedObject
*no
= NULL
;
517 struct Library
*DTBase
;
519 /* We do this in order to force datatypes.library to get
520 loaded and initialized. During this process it will
521 create and install datatypes list object in memory. */
522 DTBase
= OpenLibrary("datatypes.library", 0);
524 CloseLibrary(DTBase
);
526 if((no
= FindNamedObject(NULL
, DATATYPESLIST
, NULL
)))
528 dtl
= (struct DataTypesList
*)no
->no_Object
;
533 if(!__FindNameNoCase(sv
, &dtl
->dtl_BinaryList
, "binary"))
537 sv
, &dtl
->dtl_BinaryList
, &dtl
->dtl_SortedList
,
538 "binary", DTF_BINARY
, ID_BINARY
, GID_SYSTEM
542 if(!__FindNameNoCase(sv
, &dtl
->dtl_ASCIIList
, "ascii"))
546 sv
, &dtl
->dtl_ASCIIList
, &dtl
->dtl_SortedList
,
547 "ascii", DTF_ASCII
, ID_ASCII
, GID_TEXT
551 if(!__FindNameNoCase(sv
, &dtl
->dtl_IFFList
, "iff"))
555 sv
, &dtl
->dtl_IFFList
, &dtl
->dtl_SortedList
,
556 "iff", DTF_IFF
, ID_IFF
, GID_SYSTEM
560 if(!__FindNameNoCase(sv
, &dtl
->dtl_MiscList
, "directory"))
564 sv
, &dtl
->dtl_MiscList
, &dtl
->dtl_SortedList
,
565 "directory", DTF_MISC
, ID_DIRECTORY
, GID_SYSTEM
572 ReleaseNamedObject(no
);
581 /****** AddDatatypes/CreateBasicType ******************************************
584 * CreateBasicType - Initialize one of the basic types
598 ******************************************************************************
602 struct CompoundDatatype
*CreateBasicType(struct StackVars
*sv
,
604 struct List
*globallist
, STRPTR name
,
605 UWORD Flags
, ULONG ID
, ULONG GroupID
)
607 struct CompoundDatatype
*cdt
;
608 ULONG AllocLen
= sizeof(struct CompoundDatatype
) + strlen(name
) + 1;
610 if((cdt
= AllocVec(AllocLen
, MEMF_PUBLIC
| MEMF_CLEAR
)))
612 cdt
->DT
.dtn_Header
= &cdt
->DTH
;
614 strcpy((UBYTE
*)(cdt
+ 1), name
);
617 cdt
->DTH
.dth_BaseName
=
618 cdt
->DT
.dtn_Node1
.ln_Name
=
619 cdt
->DT
.dtn_Node2
.ln_Name
=(UBYTE
*)(cdt
+ 1);
621 cdt
->DTH
.dth_GroupID
= GroupID
;
622 cdt
->DTH
.dth_ID
= ID
;
624 cdt
->DTH
.dth_Flags
= Flags
;
626 NewList(&cdt
->DT
.dtn_ToolList
);
628 cdt
->DT
.dtn_Length
= AllocLen
;
630 AddTail(list
, &cdt
->DT
.dtn_Node1
);
632 AlphaInsert(sv
, globallist
, &cdt
->DT
.dtn_Node2
);
640 /****** AddDatatypes/LoadDatatype *********************************************
643 * LoadDatatype - Load and install a single datatype descriptor
657 ******************************************************************************
661 void LoadDatatype(struct StackVars
*sv
, STRPTR name
)
663 struct IFFHandle
*iff
;
665 if((iff
= AllocIFF()))
667 if((iff
->iff_Stream
= (IPTR
)Open(name
, MODE_OLDFILE
))) /* Why IPTR? */
671 if(!OpenIFF(iff
, IFFF_READ
))
673 if(!PropChunks(iff
, PropArray
, NUM_PROP
))
675 if(!CollectionChunks(iff
, CollArray
, NUM_COLL
))
677 if(!StopOnExit(iff
, ID_DTYP
, ID_FORM
))
681 while((error
= ParseIFF(iff
, IFFPARSE_SCAN
)) == IFFERR_EOC
)
683 CreateDatatype(sv
, iff
);
684 #warning The while ParseIFF loop here crashes the 2nd time inside the loop, therefore the break below as temp fix
694 Close((BPTR
)iff
->iff_Stream
);
701 SetIoErr(ERROR_NO_FREE_STORE
);
706 /****** AddDatatypes/MemStreamHook *******************************************
709 * MemStreamHook - needed by ReadStruct
723 ******************************************************************************
727 LONG
MemStreamHook(struct Hook
* hook
, UBYTE
**memptr
, Msg msg
)
731 switch (msg
->MethodID
)
746 /****** AddDatatypes/CreateDatatype *******************************************
749 * CreateDatatype - create a datatype from IFF chunks
763 ******************************************************************************
767 struct CompoundDatatype
*CreateDatatype(struct StackVars
*sv
,
768 struct IFFHandle
*iff
)
770 struct CompoundDatatype
*cdt
= NULL
;
771 struct StoredProperty
*prop
;
774 LONG DefaultStack
= AROS_STACKSIZE
, i
;
777 if((prop
= FindProp(iff
, ID_DTYP
, ID_DTHD
)))
779 AllocLen
= sizeof(struct CompoundDatatype
) -
780 32 + /* was sizeof(struct DataTypeHeader), but we must use struct size as it would be on Amiga */
783 if(!(cdt
= AllocVec(AllocLen
, MEMF_PUBLIC
| MEMF_CLEAR
)))
785 SetIoErr(ERROR_NO_FREE_STORE
);
789 struct FileDataTypeHeader
*fdh
;
790 UBYTE
*memptr
= (UBYTE
*)prop
->sp_Data
;
793 hook
.h_Entry
= (HOOKFUNC
)HookEntry
;
794 hook
.h_SubEntry
= (HOOKFUNC
)MemStreamHook
;
796 if (ReadStruct(&hook
, (APTR
*) &fdh
, &memptr
, FileDataTypeHeaderDesc
))
798 IPTR extraoffset
= sizeof(struct DataTypeHeader
) - 32;
800 cdt
->DT
.dtn_Header
= &cdt
->DTH
;
802 cdt
->DTH
.dth_Name
= (STRPTR
)(fdh
->fdth_NameOffset
+ extraoffset
+ (IPTR
)&cdt
->DTH
);
803 cdt
->DTH
.dth_BaseName
= (STRPTR
)(fdh
->fdth_BaseNameOffset
+ extraoffset
+ (IPTR
)&cdt
->DTH
);
804 cdt
->DTH
.dth_Pattern
= (STRPTR
)(fdh
->fdth_PatternOffset
+ extraoffset
+ (IPTR
)&cdt
->DTH
);
805 cdt
->DTH
.dth_Mask
= (WORD
*)(fdh
->fdth_MaskOffset
+ extraoffset
+ (IPTR
)&cdt
->DTH
);
806 cdt
->DTH
.dth_GroupID
= fdh
->fdth_GroupID
;
807 cdt
->DTH
.dth_ID
= fdh
->fdth_ID
;
808 cdt
->DTH
.dth_MaskLen
= fdh
->fdth_MaskLen
;
809 cdt
->DTH
.dth_Pad
= fdh
->fdth_Pad
;
810 cdt
->DTH
.dth_Flags
= fdh
->fdth_Flags
;
811 cdt
->DTH
.dth_Priority
= fdh
->fdth_Priority
;
813 CopyMem(prop
->sp_Data
+ 32, cdt
+ 1, prop
->sp_Size
- 32);
815 for(i
= 0; i
< cdt
->DTH
.dth_MaskLen
; i
++)
817 cdt
->DTH
.dth_Mask
[i
] = AROS_BE2WORD(cdt
->DTH
.dth_Mask
[i
]);
819 kprintf("mask[%d] = %04x (%c %c)\n", i
,
820 cdt
->DTH
.dth_Mask
[i
],
821 cdt
->DTH
.dth_Mask
[i
] & 255,
822 (cdt
->DTH
.dth_Mask
[i
] >> 8) & 255);
827 kprintf("groupid = %c%c%c%c\n", cdt
->DTH
.dth_GroupID
>> 24,
828 cdt
->DTH
.dth_GroupID
>> 16,
829 cdt
->DTH
.dth_GroupID
>> 8,
830 cdt
->DTH
.dth_GroupID
);
831 kprintf("id = %c%c%c%c\n", cdt
->DTH
.dth_ID
>> 24,
832 cdt
->DTH
.dth_ID
>> 16,
833 cdt
->DTH
.dth_ID
>> 8,
835 kprintf("flags = %x\n", cdt
->DTH
.dth_Flags
);
836 kprintf("pri = %d\n", cdt
->DTH
.dth_Priority
);
837 kprintf("name = %s\n", cdt
->DTH
.dth_Name
);
838 kprintf("basename = %s\n", cdt
->DTH
.dth_BaseName
);
839 kprintf("pattern = %s\n", cdt
->DTH
.dth_Pattern
);
840 kprintf("masklen = %d\n", cdt
->DTH
.dth_MaskLen
);
843 NewList(&cdt
->DT
.dtn_ToolList
);
845 cdt
->DT
.dtn_Length
= AllocLen
;
847 if((prop
= FindProp(iff
, ID_DTYP
, ID_DTCD
)))
849 if((func
= AllocVec(prop
->sp_Size
, MEMF_PUBLIC
| MEMF_CLEAR
)))
851 cdt
->DTCDChunk
= func
;
852 cdt
->DTCDSize
= prop
->sp_Size
;
854 CopyMem(prop
->sp_Data
,func
,prop
->sp_Size
);
856 HookBuffer
= cdt
->DTCDChunk
;
857 HookBufSize
= cdt
->DTCDSize
;
860 if((SegList
= InternalLoadSeg((BPTR
)sv
, NULL
,
861 (LONG_FUNC
)FunctionArray
,
864 cdt
->SegList
= SegList
;
865 cdt
->Function
= (APTR
)((((ULONG
)SegList
) << 2) + 4);
868 } /* if((func = AllocVec(prop->sp_Size, MEMF_PUBLIC | MEMF_CLEAR))) */
870 } /* if((prop = FindProp(iff, ID_DTYP, ID_DTCD))) */
872 cdt
= AddDatatype(sv
, cdt
);
874 FreeStruct(fdh
, FileDataTypeHeaderDesc
);
876 } /* if (ReadStruct(&hook, &fdh, &memptr, FileDataTypeHeaderDesc)) */
878 } /* cdt AllocVec okay */
880 } /* if((prop = FindProp(iff, ID_DTYP, ID_DTHD))) */
887 /****** AddDatatypes/AddDatatype **********************************************
890 * AddDatatype - add a datatype to the system
896 * This subroutine tries to add a datatype to the system datatypes
897 * list. If the datatype already exists, it will be replaced or
898 * updated. In case of an error, the CompoundDatatype will be deleted
899 * and a NULL pointer is returned.
901 * The CompoundDatatype pointer you passed in will be invalid after
902 * calling this function. Use the returned handle instead.
903 * DO NOT USE THE OLD POINTER IN ANY MORE!
909 * A pointer to a CompoundDatatype in the system datatypes list
910 * or a NULL pointer for failure
916 ******************************************************************************
920 struct CompoundDatatype
*AddDatatype(struct StackVars
*sv
,
921 struct CompoundDatatype
*cdt
)
923 struct List
*typelist
;
924 BOOL Success
= FALSE
;
927 struct CompoundDatatype
*oldcdt
;
929 switch(cdt
->DTH
.dth_Flags
& DTF_TYPE_MASK
)
931 case DTF_BINARY
: typelist
= &DTList
->dtl_BinaryList
; break;
932 case DTF_ASCII
: typelist
= &DTList
->dtl_ASCIIList
; break;
933 case DTF_IFF
: typelist
= &DTList
->dtl_IFFList
; break;
934 case DTF_MISC
: typelist
= &DTList
->dtl_MiscList
; break;
935 default: typelist
= NULL
;
940 cdt
->DT
.dtn_Node1
.ln_Name
= cdt
->DT
.dtn_Node2
.ln_Name
= cdt
->DTH
.dth_Name
;
944 if((!Stricmp(cdt
->DTH
.dth_Pattern
, "#?")) ||
945 (!strlen(cdt
->DTH
.dth_Pattern
)) )
947 cdt
->FlagLong
|= CFLGF_PATTERN_UNUSED
;
951 cdt
->FlagLong
&= ~(CFLGF_PATTERN_UNUSED
);
953 AllocSize
= 2*strlen(cdt
->DTH
.dth_Pattern
) + 2;
955 if(!(cdt
->ParsePatMem
= AllocVec(AllocSize
,
956 MEMF_PUBLIC
| MEMF_CLEAR
)))
962 cdt
->ParsePatSize
= AllocSize
;
964 result
= ParsePatternNoCase(cdt
->DTH
.dth_Pattern
,
965 cdt
->ParsePatMem
, AllocSize
);
969 cdt
->FlagLong
|= CFLGF_IS_WILD
;
973 FreeVec(cdt
->ParsePatMem
);
974 cdt
->ParsePatMem
= NULL
;
975 cdt
->ParsePatSize
= 0;
979 cdt
->FlagLong
&= ~(CFLGF_IS_WILD
);
991 if((oldcdt
= (struct CompoundDatatype
*)__FindNameNoCase(sv
,
993 cdt
->DT
.dtn_Node1
.ln_Name
)))
995 if (oldcdt
->OpenCount
)
1001 if((Stricmp(oldcdt
->DTH
.dth_Name
, cdt
->DTH
.dth_Name
)) ||
1002 (Stricmp(oldcdt
->DTH
.dth_BaseName
, cdt
->DTH
.dth_BaseName
)) ||
1003 (Stricmp(oldcdt
->DTH
.dth_Pattern
, cdt
->DTH
.dth_Pattern
)) ||
1004 (oldcdt
->DTH
.dth_Flags
!= cdt
->DTH
.dth_Flags
) ||
1005 (oldcdt
->DTH
.dth_Priority
!= cdt
->DTH
.dth_Priority
) ||
1006 (oldcdt
->DTH
.dth_MaskLen
!= cdt
->DTH
.dth_MaskLen
))
1008 DeleteDatatype(sv
, oldcdt
);
1013 oldcdt
->DTH
.dth_GroupID
= cdt
->DTH
.dth_GroupID
;
1014 oldcdt
->DTH
.dth_ID
= cdt
->DTH
.dth_ID
;
1015 CopyMem(cdt
->DTH
.dth_Mask
,cdt
->DTH
.dth_Mask
,
1016 (ULONG
)(sizeof(WORD
)*cdt
->DTH
.dth_MaskLen
));
1025 DeleteDatatype(sv
, cdt
);
1030 if(cdt
->DT
.dtn_FunctionName
)
1032 LONG DefaultStack
= 4096;
1037 if((file
= Open(cdt
->DT
.dtn_FunctionName
, MODE_OLDFILE
)))
1039 if(Seek(file
, 0, OFFSET_END
) >= 0)
1041 if((AllocLen
= Seek(file
, 0,
1042 OFFSET_BEGINNING
)) > 0)
1044 if((cdt
->DTCDChunk
= AllocVec(AllocLen
,
1045 MEMF_PUBLIC
| MEMF_CLEAR
)))
1047 cdt
->DTCDSize
= AllocLen
;
1049 if(Read(file
, cdt
->DTCDChunk
, AllocLen
) == AllocLen
)
1051 HookBuffer
= cdt
->DTCDChunk
;
1052 HookBufSize
= cdt
->DTCDSize
;
1055 if((SegList
= InternalLoadSeg((BPTR
)sv
, NULL
, (LONG_FUNC
)FunctionArray
, &DefaultStack
)))
1057 cdt
->SegList
= SegList
;
1058 cdt
->Function
= (APTR
)((((ULONG
)SegList
)<<2)+4);
1063 FreeVec(cdt
->DTCDChunk
);
1064 cdt
->DTCDChunk
= NULL
;
1071 cdt
->DT
.dtn_FunctionName
=NULL
;
1074 if(cdt
->DTH
.dth_MaskLen
> DTList
->dtl_LongestMask
)
1076 DTList
->dtl_LongestMask
= cdt
->DTH
.dth_MaskLen
;
1079 PrioInsert(sv
, typelist
, cdt
);
1081 AlphaInsert(sv
, &DTList
->dtl_SortedList
, &cdt
->DT
.dtn_Node2
);
1089 DeleteDatatype(sv
, cdt
);
1098 /****** AddDatatypes/DeleteDatatype *******************************************
1101 * DeleteDatatype - unlink and deallocate a CompoundDatatype structure
1115 ******************************************************************************
1119 void DeleteDatatype(struct StackVars
*sv
, struct CompoundDatatype
*cdt
)
1123 if(cdt
->ParsePatMem
)
1125 FreeVec(cdt
->ParsePatMem
);
1126 cdt
->ParsePatMem
= NULL
;
1127 cdt
->ParsePatSize
= 0;
1132 FreeVec(cdt
->DTCDChunk
);
1133 cdt
->DTCDChunk
= NULL
;
1139 UnLoadSeg(cdt
->SegList
);
1140 cdt
->SegList
= NULL
;
1141 cdt
->Function
= NULL
;
1144 if(cdt
->DT
.dtn_Node1
.ln_Succ
&& cdt
->DT
.dtn_Node1
.ln_Pred
)
1146 Remove(&cdt
->DT
.dtn_Node1
);
1147 Remove(&cdt
->DT
.dtn_Node2
);
1148 cdt
->DT
.dtn_Node1
.ln_Succ
= cdt
->DT
.dtn_Node1
.ln_Pred
=
1149 cdt
->DT
.dtn_Node2
.ln_Succ
= cdt
->DT
.dtn_Node2
.ln_Pred
= NULL
;
1158 /****** AddDatatypes/AlphaInsert **********************************************
1161 * AlphaInsert - enqueue a node alphabetically into a list
1175 ******************************************************************************
1179 void AlphaInsert(struct StackVars
*sv
, struct List
*list
, struct Node
*node
)
1181 struct Node
*cur
,*prev
=NULL
;
1183 for(cur
= list
->lh_Head
; cur
->ln_Succ
; prev
= cur
, cur
= cur
->ln_Succ
)
1185 if(Stricmp(cur
->ln_Name
, node
->ln_Name
) > 0)
1189 Insert(list
, node
, prev
);
1194 /****** AddDatatypes/PrioInsert **********************************************
1197 * PrioInsert - enqueue a CompoundDatatype correctly in the type list
1211 ******************************************************************************
1215 void PrioInsert(struct StackVars
*sv
, struct List
*list
,
1216 struct CompoundDatatype
*cdt
)
1218 struct CompoundDatatype
*cur
, *prev
= NULL
;
1221 for(cur
= (struct CompoundDatatype
*)list
->lh_Head
;
1222 cur
->DT
.dtn_Node1
.ln_Succ
;
1223 prev
= cur
, cur
= (struct CompoundDatatype
*)cur
->DT
.dtn_Node1
.ln_Succ
)
1225 diff
= (cdt
->Function
? 1 : 0) - (cur
->Function
? 1 : 0);
1232 UWORD MinMask
= (cdt
->DTH
.dth_MaskLen
< cur
->DTH
.dth_MaskLen
) ?
1233 cdt
->DTH
.dth_MaskLen
: cur
->DTH
.dth_MaskLen
;
1234 WORD
*cdtmask
= cdt
->DTH
.dth_Mask
;
1235 WORD
*curmask
=cur
->DTH
.dth_Mask
;
1237 while(!diff
&& MinMask
--)
1238 diff
= *(curmask
++) - *(cdtmask
++);
1245 diff
= cdt
->DTH
.dth_MaskLen
- cur
->DTH
.dth_MaskLen
;
1252 diff
= (((cdt
->FlagLong
& CFLGF_PATTERN_UNUSED
) || cdt
->DTH
.dth_Pattern
==NULL
) ? 0 : 1) -
1253 (((cur
->FlagLong
& CFLGF_PATTERN_UNUSED
) || cur
->DTH
.dth_Pattern
==NULL
) ? 0 : 1);
1260 diff
= cdt
->DTH
.dth_Priority
- cur
->DTH
.dth_Priority
;
1270 Insert(list
, &cdt
->DT
.dtn_Node1
, (struct Node
*)prev
);
1275 /****** AddDatatypes/__FindNameNoCase *****************************************
1278 * __FindNameNoCase - find a node in a list (case insensitive)
1292 ******************************************************************************
1296 struct Node
*__FindNameNoCase(struct StackVars
*sv
, struct List
*list
,
1300 struct Node
*result
= NULL
;
1302 for(node
= list
->lh_Head
; node
->ln_Succ
; node
= node
->ln_Succ
)
1304 if(!Stricmp(node
->ln_Name
, name
))
1316 /****** AddDatatypes/ReadFunc *************************************************
1319 * ReadFunc - data read hook for InternalLoadSeg
1333 ******************************************************************************
1337 LONG
ReadFunc(struct StackVars
*sv
, UBYTE
*buffer
, ULONG length
)
1339 LONG maxlen
= HookBufSize
-HookPosition
;
1340 LONG actual
= length
> maxlen
? maxlen
: length
;
1342 CopyMem(HookBuffer
+HookPosition
, buffer
, actual
);
1344 HookPosition
+= actual
;
1351 /****** AddDatatypes/AllocFunc ************************************************
1354 * AllocFunc - memory allocation hook for InternalLoadSeg
1368 ******************************************************************************
1372 UBYTE
*AllocFunc(ULONG size
, ULONG flags
)
1374 return(AllocMem(size
, flags
));
1379 /****** AddDatatypes/FreeFunc *************************************************
1382 * FreeFunc - memory freeing hook for InternalLoadSeg
1396 ******************************************************************************
1400 void FreeFunc(UBYTE
*memory
, ULONG size
)
1402 FreeMem(memory
, size
);
1407 /******************************* STUB ROUTINES ********************************/
1409 struct NamedObject
*allocnamedobject(struct StackVars
*sv
, STRPTR name
,
1412 return AllocNamedObjectA(name
, (struct TagItem
*)&FirstTag
);