New bitmap method SetRGBConversionFunction which can be used to
[tangerine.git] / workbench / c / AddDatatypes.c
blobf3bab675ac131282ae5a1270b7460eabeb8f3098
1 /*
2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
3 $Id$
4 */
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>
11 #include <dos/dos.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>
26 #include <string.h>
27 #include <stdio.h>
29 #include "../libs/datatypes/datatypes_intern.h"
30 #undef DOSBase
31 #undef UtilityBase
32 #undef IFFParseBase
33 #undef LocaleBase
34 #undef DTList
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 */
52 UWORD fdth_Priority;
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)),
70 SDM_END
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,
81 struct List *list,
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,
94 STRPTR name);
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";
104 #define EXCL_LEN 18
105 UBYTE ExcludePattern[] = "#?.(info|backdrop)";
107 UBYTE Template[] = "FILES/M,QUIET/S,REFRESH/S,LIST/S";
109 struct ArgArray
111 UBYTE **aa_Files;
112 IPTR aa_Quiet;
113 IPTR aa_Refresh;
114 IPTR aa_List;
117 #define ID_DTCD MAKE_ID('D','T','C','D')
118 #define ID_DTTL MAKE_ID('D','T','T','L')
120 #define NUM_PROP 2
122 LONG PropArray[2*NUM_PROP]=
124 ID_DTYP, ID_DTHD,
125 ID_DTYP, ID_DTCD
128 #define NUM_COLL 1
130 LONG CollArray[2*NUM_COLL]=
132 ID_DTYP, ID_DTTL
136 LONG_FUNC FunctionArray[]=
137 { /* Note! */
138 (LONG_FUNC)&ReadFunc,
139 (LONG_FUNC)&AllocFunc,
140 (LONG_FUNC)&FreeFunc
144 struct StackVars
146 struct DataTypesList *DTList;
147 UBYTE ExclPat[2*EXCL_LEN+2+1];
148 struct ArgArray AA;
149 UBYTE *HookBuffer;
150 ULONG HookBufSize;
151 ULONG HookPosition;
152 BOOL DidCreateDTList;
155 #undef SysBase
156 #define DTList sv->DTList
157 #define ExclPat sv->ExclPat
158 #define AA sv->AA
159 #define HookBuffer sv->HookBuffer
160 #define HookBufSize sv->HookBufSize
161 #define HookPosition sv->HookPosition
162 #define DidCreateDTList sv->DidCreateDTList
164 /****** AddDatatypes/main *****************************************************
166 * NAME
167 * main - well... main
169 * SYNOPSIS
171 * FUNCTION
173 * INPUTS
175 * RETURNS
177 * EXAMPLE
179 * SEE ALSO
181 ******************************************************************************
184 int UtilityBase_version = 37;
185 int LocaleBase_version = 37;
186 int IFFParseBase_version = 37;
188 int __nocommandline = 1;
190 int main(void)
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));
198 sv = &vars;
200 if((DTList = CreateDTList(sv)))
202 ParsePatternNoCase(ExcludePattern, ExclPat, sizeof(ExclPat));
204 ObtainSemaphore(&DTList->dtl_Lock);
206 if(WBenchMsg)
208 UWORD num;
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);
215 CurrentDir(olddir);
218 result = RETURN_OK;
220 else
222 struct RDArgs *RDArgs;
224 if(!(RDArgs = ReadArgs(Template, (LONG*)&AA, NULL)))
226 PrintFault(IoErr(), NULL);
228 else
230 if(AA.aa_Refresh)
232 if(DidCreateDTList || DateScan(sv))
234 ScanDirectory(sv, "DEVS:DataTypes");
237 else
239 UBYTE **files = AA.aa_Files;
241 if(files)
243 while(*files)
245 ScanDirectory(sv, *files);
246 files++;
251 if(AA.aa_List)
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);
259 if(dtl != NULL)
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;
267 STRPTR argarray[2];
269 if(CheckSignal(SIGBREAKF_CTRL_C))
271 Flush(Output());
272 PrintFault(ERROR_BREAK,0);
273 break;
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;
289 result = RETURN_OK;
290 FreeArgs(RDArgs);
294 ReleaseSemaphore(&DTList->dtl_Lock);
297 return result;
302 /****** AddDatatypes/DateScan *************************************************
304 * NAME
305 * DateScan - See if datatypes descriptors need updating
307 * SYNOPSIS
309 * FUNCTION
311 * INPUTS
313 * RETURNS
315 * EXAMPLE
317 * SEE ALSO
319 ******************************************************************************
323 BOOL DateScan(struct StackVars *sv)
325 BOOL result = TRUE;
326 BPTR lock;
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))
337 result = FALSE;
339 else
341 DTList->dtl_DateStamp = fib->fib_Date;
345 FreeDosObject(DOS_FIB,fib);
348 UnLock(lock);
351 return result;
356 /****** AddDatatypes/ScanDirectory ********************************************
358 * NAME
359 * ScanDirectory - Scan a directory recursively for DT descriptors
361 * SYNOPSIS
363 * FUNCTION
365 * INPUTS
367 * RETURNS
369 * EXAMPLE
371 * SEE ALSO
373 ******************************************************************************
377 void ScanDirectory(struct StackVars *sv, STRPTR pattern)
379 struct AnchorPath *AnchorPath;
380 LONG RetVal;
381 BPTR OldDir;
383 if((AnchorPath = (struct AnchorPath *)AllocVec(sizeof(struct AnchorPath),
384 MEMF_CLEAR)))
386 AnchorPath->ap_BreakBits = SIGBREAKF_CTRL_C;
388 RetVal = MatchFirst(pattern, AnchorPath);
390 while(!RetVal)
392 if(CheckSignal(SIGBREAKF_CTRL_C))
394 if(!AA.aa_Quiet)
396 PrintFault(ERROR_BREAK, NULL);
399 break;
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;
411 else
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);
420 CurrentDir(OldDir);
424 RetVal = MatchNext(AnchorPath);
427 if(RetVal != ERROR_NO_MORE_ENTRIES)
429 if(!AA.aa_Quiet)
431 PrintFault(RetVal, NULL);
435 MatchEnd(AnchorPath);
437 FreeVec((APTR)AnchorPath);
442 /****** AddDatatypes/CreateDTList *********************************************
444 * NAME
445 * CreateDTList - Create and initialize the DataTypesList
447 * SYNOPSIS
449 * FUNCTION
451 * INPUTS
453 * RETURNS
455 * EXAMPLE
457 * SEE ALSO
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;
473 if(!dtl)
475 struct TagItem tags[] =
477 {ANO_NameSpace , TRUE },
478 {ANO_UserSpace , sizeof(struct DataTypesList) },
479 {ANO_Flags , NSF_NODUPS | NSF_CASE },
480 {TAG_DONE }
483 if((no = AllocNamedObjectA(DATATYPESLIST, tags)))
485 if(!(dtl = (struct DataTypesList*)no->no_Object))
487 FreeNamedObject(no);
488 no = NULL;
492 if(dtl)
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))
506 FreeNamedObject(no);
507 no = NULL;
508 dtl = NULL;
513 if(dtl)
515 if(!__FindNameNoCase(sv, &dtl->dtl_BinaryList, "binary"))
517 CreateBasicType
519 sv, &dtl->dtl_BinaryList, &dtl->dtl_SortedList,
520 "binary", DTF_BINARY, ID_BINARY, GID_SYSTEM
524 if(!__FindNameNoCase(sv, &dtl->dtl_ASCIIList, "ascii"))
526 CreateBasicType
528 sv, &dtl->dtl_ASCIIList, &dtl->dtl_SortedList,
529 "ascii", DTF_ASCII, ID_ASCII, GID_TEXT
533 if(!__FindNameNoCase(sv, &dtl->dtl_IFFList, "iff"))
535 CreateBasicType
537 sv, &dtl->dtl_IFFList, &dtl->dtl_SortedList,
538 "iff", DTF_IFF, ID_IFF, GID_SYSTEM
542 if(!__FindNameNoCase(sv, &dtl->dtl_MiscList, "directory"))
544 CreateBasicType
546 sv, &dtl->dtl_MiscList, &dtl->dtl_SortedList,
547 "directory", DTF_MISC, ID_DIRECTORY, GID_SYSTEM
552 if(no)
554 ReleaseNamedObject(no);
558 return dtl;
563 /****** AddDatatypes/CreateBasicType ******************************************
565 * NAME
566 * CreateBasicType - Initialize one of the basic types
568 * SYNOPSIS
570 * FUNCTION
572 * INPUTS
574 * RETURNS
576 * EXAMPLE
578 * SEE ALSO
580 ******************************************************************************
584 struct CompoundDatatype *CreateBasicType(struct StackVars *sv,
585 struct List *list,
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);
598 cdt->DTH.dth_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);
617 return cdt;
622 /****** AddDatatypes/LoadDatatype *********************************************
624 * NAME
625 * LoadDatatype - Load and install a single datatype descriptor
627 * SYNOPSIS
629 * FUNCTION
631 * INPUTS
633 * RETURNS
635 * EXAMPLE
637 * SEE ALSO
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? */
651 InitIFFasDOS(iff);
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))
661 LONG error;
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
667 break;
673 CloseIFF(iff);
676 Close((BPTR)iff->iff_Stream);
679 FreeIFF(iff);
681 else
683 SetIoErr(ERROR_NO_FREE_STORE);
688 /****** AddDatatypes/MemStreamHook *******************************************
690 * NAME
691 * MemStreamHook - needed by ReadStruct
693 * SYNOPSIS
695 * FUNCTION
697 * INPUTS
699 * RETURNS
701 * EXAMPLE
703 * SEE ALSO
705 ******************************************************************************
709 LONG MemStreamHook(struct Hook * hook, UBYTE **memptr, Msg msg)
711 LONG rc;
713 switch (msg->MethodID)
715 case BEIO_READ:
716 rc = **memptr;
717 (*memptr)++;
718 break;
720 default:
721 rc = EOF;
722 break;
725 return rc;
728 /****** AddDatatypes/CreateDatatype *******************************************
730 * NAME
731 * CreateDatatype - create a datatype from IFF chunks
733 * SYNOPSIS
735 * FUNCTION
737 * INPUTS
739 * RETURNS
741 * EXAMPLE
743 * SEE ALSO
745 ******************************************************************************
749 struct CompoundDatatype *CreateDatatype(struct StackVars *sv,
750 struct IFFHandle *iff)
752 struct CompoundDatatype *cdt = NULL;
753 struct StoredProperty *prop;
754 ULONG AllocLen;
755 UBYTE *func;
756 LONG DefaultStack = AROS_STACKSIZE, i;
757 BPTR SegList;
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 */
763 prop->sp_Size;
765 if(!(cdt = AllocVec(AllocLen, MEMF_PUBLIC | MEMF_CLEAR)))
767 SetIoErr(ERROR_NO_FREE_STORE);
769 else
771 struct FileDataTypeHeader *fdh;
772 UBYTE *memptr = (UBYTE *)prop->sp_Data;
773 struct Hook hook;
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]);
800 #if 0
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);
805 #endif
808 #if 0
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,
816 cdt->DTH.dth_ID);
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);
823 #endif
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;
840 HookPosition = 0;
842 if((SegList = InternalLoadSeg((BPTR)sv, NULL,
843 (LONG_FUNC)FunctionArray,
844 &DefaultStack)))
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))) */
864 return cdt;
869 /****** AddDatatypes/AddDatatype **********************************************
871 * NAME
872 * AddDatatype - add a datatype to the system
874 * SYNOPSIS
876 * FUNCTION
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!
887 * INPUTS
889 * RETURNS
891 * A pointer to a CompoundDatatype in the system datatypes list
892 * or a NULL pointer for failure
894 * EXAMPLE
896 * SEE ALSO
898 ******************************************************************************
902 struct CompoundDatatype *AddDatatype(struct StackVars *sv,
903 struct CompoundDatatype *cdt)
905 struct List *typelist;
906 BOOL Success = FALSE;
907 ULONG AllocSize;
908 ULONG result;
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;
920 if(typelist)
922 cdt->DT.dtn_Node1.ln_Name = cdt->DT.dtn_Node2.ln_Name = cdt->DTH.dth_Name;
924 Success = TRUE;
926 if((!Stricmp(cdt->DTH.dth_Pattern, "#?")) ||
927 (!strlen(cdt->DTH.dth_Pattern)) )
929 cdt->FlagLong |= CFLGF_PATTERN_UNUSED;
931 else
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)))
940 Success = FALSE;
942 else
944 cdt->ParsePatSize = AllocSize;
946 result = ParsePatternNoCase(cdt->DTH.dth_Pattern,
947 cdt->ParsePatMem, AllocSize);
949 if(result == 1)
951 cdt->FlagLong |= CFLGF_IS_WILD;
953 else
955 FreeVec(cdt->ParsePatMem);
956 cdt->ParsePatMem = NULL;
957 cdt->ParsePatSize = 0;
959 if(result == 0)
961 cdt->FlagLong &= ~(CFLGF_IS_WILD);
963 else
965 Success = FALSE;
971 if (Success)
973 if((oldcdt = (struct CompoundDatatype*)__FindNameNoCase(sv,
974 typelist,
975 cdt->DT.dtn_Node1.ln_Name)))
977 if (oldcdt->OpenCount)
979 Success = FALSE;
981 else
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);
991 oldcdt = NULL;
993 else
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));
1003 if(Success)
1005 if(oldcdt)
1007 DeleteDatatype(sv, cdt);
1008 cdt = oldcdt;
1010 else
1012 if(cdt->DT.dtn_FunctionName)
1014 LONG DefaultStack = 4096;
1015 BPTR file;
1016 ULONG AllocLen;
1017 BPTR SegList;
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;
1035 HookPosition = 0;
1037 if((SegList = InternalLoadSeg((BPTR)sv, NULL, (LONG_FUNC)FunctionArray, &DefaultStack)))
1039 cdt->SegList = SegList;
1040 cdt->Function = (APTR)((((ULONG)SegList)<<2)+4);
1043 else
1045 FreeVec(cdt->DTCDChunk);
1046 cdt->DTCDChunk = NULL;
1047 cdt->DTCDSize = 0;
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);
1069 if(!Success)
1071 DeleteDatatype(sv, cdt);
1072 cdt = NULL;
1075 return cdt;
1080 /****** AddDatatypes/DeleteDatatype *******************************************
1082 * NAME
1083 * DeleteDatatype - unlink and deallocate a CompoundDatatype structure
1085 * SYNOPSIS
1087 * FUNCTION
1089 * INPUTS
1091 * RETURNS
1093 * EXAMPLE
1095 * SEE ALSO
1097 ******************************************************************************
1101 void DeleteDatatype(struct StackVars *sv, struct CompoundDatatype *cdt)
1103 if(cdt)
1105 if(cdt->ParsePatMem)
1107 FreeVec(cdt->ParsePatMem);
1108 cdt->ParsePatMem = NULL;
1109 cdt->ParsePatSize = 0;
1112 if(cdt->DTCDChunk)
1114 FreeVec(cdt->DTCDChunk);
1115 cdt->DTCDChunk = NULL;
1116 cdt->DTCDSize = 0;
1119 if(cdt->SegList)
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;
1134 FreeVec(cdt);
1140 /****** AddDatatypes/AlphaInsert **********************************************
1142 * NAME
1143 * AlphaInsert - enqueue a node alphabetically into a list
1145 * SYNOPSIS
1147 * FUNCTION
1149 * INPUTS
1151 * RETURNS
1153 * EXAMPLE
1155 * SEE ALSO
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)
1168 break;
1171 Insert(list, node, prev);
1176 /****** AddDatatypes/PrioInsert **********************************************
1178 * NAME
1179 * PrioInsert - enqueue a CompoundDatatype correctly in the type list
1181 * SYNOPSIS
1183 * FUNCTION
1185 * INPUTS
1187 * RETURNS
1189 * EXAMPLE
1191 * SEE ALSO
1193 ******************************************************************************
1197 void PrioInsert(struct StackVars *sv, struct List *list,
1198 struct CompoundDatatype *cdt)
1200 struct CompoundDatatype *cur, *prev = NULL;
1201 WORD diff;
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);
1209 if(diff > 0)
1210 break;
1212 if(!diff)
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++);
1222 if(diff > 0)
1223 break;
1225 if(!diff)
1227 diff = cdt->DTH.dth_MaskLen - cur->DTH.dth_MaskLen;
1229 if(diff > 0)
1230 break;
1232 if(!diff)
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);
1237 if(diff > 0)
1238 break;
1240 if(!diff)
1242 diff = cdt->DTH.dth_Priority - cur->DTH.dth_Priority;
1244 if(diff > 0)
1245 break;
1252 Insert(list, &cdt->DT.dtn_Node1, (struct Node *)prev);
1257 /****** AddDatatypes/__FindNameNoCase *****************************************
1259 * NAME
1260 * __FindNameNoCase - find a node in a list (case insensitive)
1262 * SYNOPSIS
1264 * FUNCTION
1266 * INPUTS
1268 * RETURNS
1270 * EXAMPLE
1272 * SEE ALSO
1274 ******************************************************************************
1278 struct Node *__FindNameNoCase(struct StackVars *sv, struct List *list,
1279 STRPTR name)
1281 struct Node *node;
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))
1288 result = node;
1289 break;
1293 return result;
1298 /****** AddDatatypes/ReadFunc *************************************************
1300 * NAME
1301 * ReadFunc - data read hook for InternalLoadSeg
1303 * SYNOPSIS
1305 * FUNCTION
1307 * INPUTS
1309 * RETURNS
1311 * EXAMPLE
1313 * SEE ALSO
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;
1328 return actual;
1333 /****** AddDatatypes/AllocFunc ************************************************
1335 * NAME
1336 * AllocFunc - memory allocation hook for InternalLoadSeg
1338 * SYNOPSIS
1340 * FUNCTION
1342 * INPUTS
1344 * RETURNS
1346 * EXAMPLE
1348 * SEE ALSO
1350 ******************************************************************************
1354 UBYTE *AllocFunc(ULONG size, ULONG flags)
1356 return(AllocMem(size, flags));
1361 /****** AddDatatypes/FreeFunc *************************************************
1363 * NAME
1364 * FreeFunc - memory freeing hook for InternalLoadSeg
1366 * SYNOPSIS
1368 * FUNCTION
1370 * INPUTS
1372 * RETURNS
1374 * EXAMPLE
1376 * SEE ALSO
1378 ******************************************************************************
1382 void FreeFunc(UBYTE *memory, ULONG size)
1384 FreeMem(memory, size);
1389 /******************************* STUB ROUTINES ********************************/
1391 struct NamedObject *allocnamedobject(struct StackVars *sv, STRPTR name,
1392 Tag FirstTag, ...)
1394 return AllocNamedObjectA(name, (struct TagItem*)&FirstTag);