prism2.device: Compiler delint
[AROS.git] / workbench / c / AddDataTypes.c
blob7248f9c136d19c8537e4cfc0a715d3891f04ad35
1 /*
2 Copyright © 1995-2012, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English
7 */
10 /******************************************************************************
12 NAME
14 AddDataTypes (files) [QUIET] [REFRESH] [LIST]
16 SYNOPSIS
18 FILES/M, QUIET/S, REFRESH/S, LIST/S
20 LOCATION
24 FUNCTION
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.
30 INPUTS
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
36 memory
38 RESULT
40 Standard DOS error codes.
42 NOTES
44 EXAMPLE
46 AddDataTypes gif.datatype REFRESH
48 BUGS
50 SEE ALSO
52 INTERNALS
54 HISTORY
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>
63 #include <dos/dos.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>
78 #include <string.h>
80 #include "../libs/datatypes/datatypes_intern.h"
81 #undef DOSBase
82 #undef UtilityBase
83 #undef IFFParseBase
84 #undef LocaleBase
85 #undef DTList
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 */
103 UWORD fdth_Priority;
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)),
121 SDM_END
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,
132 struct List *list,
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,
143 STRPTR name);
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";
168 #define EXCL_LEN 18
169 UBYTE ExcludePattern[] = "#?.(info|backdrop)";
171 UBYTE Template[] = "FILES/M,QUIET/S,REFRESH/S,LIST/S";
173 struct ArgArray
175 UBYTE **aa_Files;
176 IPTR aa_Quiet;
177 IPTR aa_Refresh;
178 IPTR aa_List;
181 #define ID_DTCD MAKE_ID('D','T','C','D')
182 #define ID_DTTL MAKE_ID('D','T','T','L')
184 #define NUM_PROP 2
186 LONG PropArray[2*NUM_PROP]=
188 ID_DTYP, ID_DTHD,
189 ID_DTYP, ID_DTCD
192 #define NUM_COLL 1
194 const LONG const CollArray[2*NUM_COLL]=
196 ID_DTYP, ID_DTTL
200 const LONG_FUNC const FunctionArray[]=
201 { /* Note! */
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 */
209 struct StackVars
211 struct DataTypesList *DTList;
212 UBYTE ExclPat[2*EXCL_LEN+2+1];
213 struct ArgArray AA;
214 UBYTE *HookBuffer;
215 ULONG HookBufSize;
216 ULONG HookPosition;
219 #undef SysBase
220 #define DTList sv->DTList
221 #define ExclPat sv->ExclPat
222 #define AA sv->AA
223 #define HookBuffer sv->HookBuffer
224 #define HookBufSize sv->HookBufSize
225 #define HookPosition sv->HookPosition
227 /****** AddDataTypes/main *****************************************************
229 * NAME
230 * main - well... main
232 * SYNOPSIS
234 * FUNCTION
236 * INPUTS
238 * RETURNS
240 * EXAMPLE
242 * SEE ALSO
244 ******************************************************************************
247 int UtilityBase_version = 37;
248 int LocaleBase_version = 37;
249 int IFFParseBase_version = 37;
251 int __nocommandline = 1;
253 int main(void)
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));
261 sv = &vars;
263 if((DTList = CreateDTList(sv)))
265 ParsePatternNoCase(ExcludePattern, ExclPat, sizeof(ExclPat));
267 ObtainSemaphore(&DTList->dtl_Lock);
269 if(WBenchMsg)
271 UWORD num;
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);
278 CurrentDir(olddir);
281 result = RETURN_OK;
283 else
285 struct RDArgs *RDArgs;
287 if(!(RDArgs = ReadArgs(Template, (SIPTR*)&AA, NULL)))
289 PrintFault(IoErr(), NULL);
291 else
293 if(AA.aa_Refresh)
295 if(DateScan(sv))
297 ScanDirectory(sv, "DEVS:DataTypes");
300 else
302 UBYTE **files = AA.aa_Files;
304 if(files)
306 while(*files)
308 ScanDirectory(sv, *files);
309 files++;
314 if(AA.aa_List)
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);
322 if(dtl != NULL)
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;
330 STRPTR argarray[2];
332 if(CheckSignal(SIGBREAKF_CTRL_C))
334 Flush(Output());
335 PrintFault(ERROR_BREAK,0);
336 break;
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;
352 result = RETURN_OK;
353 FreeArgs(RDArgs);
357 ReleaseSemaphore(&DTList->dtl_Lock);
360 return result;
365 /****** AddDataTypes/DateScan *************************************************
367 * NAME
368 * DateScan - See if DataTypes descriptors need updating
370 * SYNOPSIS
372 * FUNCTION
374 * INPUTS
376 * RETURNS
378 * EXAMPLE
380 * SEE ALSO
382 ******************************************************************************
386 BOOL DateScan(struct StackVars *sv)
388 BOOL result = TRUE;
389 BPTR lock;
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))
400 result = FALSE;
402 else
404 DTList->dtl_DateStamp = fib->fib_Date;
408 FreeDosObject(DOS_FIB,fib);
411 UnLock(lock);
414 return result;
419 /****** AddDataTypes/ScanDirectory ********************************************
421 * NAME
422 * ScanDirectory - Scan a directory recursively for DT descriptors
424 * SYNOPSIS
426 * FUNCTION
428 * INPUTS
430 * RETURNS
432 * EXAMPLE
434 * SEE ALSO
436 ******************************************************************************
440 void ScanDirectory(struct StackVars *sv, STRPTR pattern)
442 struct AnchorPath *AnchorPath;
443 LONG RetVal;
444 BPTR OldDir;
446 if((AnchorPath = (struct AnchorPath *)AllocVec(sizeof(struct AnchorPath),
447 MEMF_CLEAR)))
449 AnchorPath->ap_BreakBits = SIGBREAKF_CTRL_C;
451 RetVal = MatchFirst(pattern, AnchorPath);
453 while(!RetVal)
455 if(CheckSignal(SIGBREAKF_CTRL_C))
457 if(!AA.aa_Quiet)
459 PrintFault(ERROR_BREAK, NULL);
462 break;
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;
474 else
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);
483 CurrentDir(OldDir);
487 RetVal = MatchNext(AnchorPath);
490 if(RetVal != ERROR_NO_MORE_ENTRIES)
492 if(!AA.aa_Quiet)
494 PrintFault(RetVal, NULL);
498 MatchEnd(AnchorPath);
500 FreeVec((APTR)AnchorPath);
505 /****** AddDataTypes/CreateDTList *********************************************
507 * NAME
508 * CreateDTList - Create and initialize the DataTypesList
510 * SYNOPSIS
512 * FUNCTION
514 * INPUTS
516 * RETURNS
518 * EXAMPLE
520 * SEE ALSO
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);
536 if (DTBase)
537 CloseLibrary(DTBase);
539 if((no = FindNamedObject(NULL, DATATYPESLIST, NULL)))
541 dtl = (struct DataTypesList*)no->no_Object;
544 if(dtl)
546 if(!__FindNameNoCase(sv, &dtl->dtl_BinaryList, "binary"))
548 CreateBasicType
550 sv, &dtl->dtl_BinaryList, &dtl->dtl_SortedList,
551 "binary", DTF_BINARY, ID_BINARY, GID_SYSTEM
555 if(!__FindNameNoCase(sv, &dtl->dtl_ASCIIList, "ascii"))
557 CreateBasicType
559 sv, &dtl->dtl_ASCIIList, &dtl->dtl_SortedList,
560 "ascii", DTF_ASCII, ID_ASCII, GID_TEXT
564 if(!__FindNameNoCase(sv, &dtl->dtl_IFFList, "iff"))
566 CreateBasicType
568 sv, &dtl->dtl_IFFList, &dtl->dtl_SortedList,
569 "iff", DTF_IFF, ID_IFF, GID_SYSTEM
573 if(!__FindNameNoCase(sv, &dtl->dtl_MiscList, "directory"))
575 CreateBasicType
577 sv, &dtl->dtl_MiscList, &dtl->dtl_SortedList,
578 "directory", DTF_MISC, ID_DIRECTORY, GID_SYSTEM
583 if(no)
585 ReleaseNamedObject(no);
589 return dtl;
594 /****** AddDataTypes/CreateBasicType ******************************************
596 * NAME
597 * CreateBasicType - Initialize one of the basic types
599 * SYNOPSIS
601 * FUNCTION
603 * INPUTS
605 * RETURNS
607 * EXAMPLE
609 * SEE ALSO
611 ******************************************************************************
615 struct CompoundDataType *CreateBasicType(struct StackVars *sv,
616 struct List *list,
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);
629 cdt->DTH.dth_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);
649 return cdt;
654 /****** AddDataTypes/LoadDataType *********************************************
656 * NAME
657 * LoadDataType - Load and install a single DataType descriptor
659 * SYNOPSIS
661 * FUNCTION
663 * INPUTS
665 * RETURNS
667 * EXAMPLE
669 * SEE ALSO
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? */
683 InitIFFasDOS(iff);
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))
693 LONG error;
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 */
699 break;
705 CloseIFF(iff);
708 Close((BPTR)iff->iff_Stream);
711 FreeIFF(iff);
713 else
715 SetIoErr(ERROR_NO_FREE_STORE);
720 /****** AddDataTypes/MemStreamHook *******************************************
722 * NAME
723 * MemStreamHook - needed by ReadStruct
725 * SYNOPSIS
727 * FUNCTION
729 * INPUTS
731 * RETURNS
733 * EXAMPLE
735 * SEE ALSO
737 ******************************************************************************
741 LONG MemStreamHook(struct Hook * hook, UBYTE **memptr, Msg msg)
743 LONG rc;
745 switch (msg->MethodID)
747 case BEIO_READ:
748 rc = **memptr;
749 (*memptr)++;
750 break;
752 default:
753 rc = -1;
754 break;
757 return rc;
760 /****** AddDataTypes/CreateDataType *******************************************
762 * NAME
763 * CreateDataType - create a DataType from IFF chunks
765 * SYNOPSIS
767 * FUNCTION
769 * INPUTS
771 * RETURNS
773 * EXAMPLE
775 * SEE ALSO
777 ******************************************************************************
781 struct CompoundDataType *CreateDataType(struct StackVars *sv,
782 struct IFFHandle *iff)
784 struct CompoundDataType *cdt = NULL;
785 struct StoredProperty *prop;
786 ULONG AllocLen;
787 UBYTE *func;
788 LONG DefaultStack = AROS_STACKSIZE, i;
789 BPTR SegList;
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 */
795 prop->sp_Size;
797 if(!(cdt = AllocVec(AllocLen, MEMF_PUBLIC | MEMF_CLEAR)))
799 SetIoErr(ERROR_NO_FREE_STORE);
801 else
803 struct FileDataTypeHeader *fdh = NULL;
804 UBYTE *memptr = (UBYTE *)prop->sp_Data;
805 struct Hook hook;
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]);
832 #if 0
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);
837 #endif
840 #if 0
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,
848 cdt->DTH.dth_ID);
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);
855 #endif
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;
872 HookPosition = 0;
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,
880 &DefaultStack)))
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))) */
900 return cdt;
905 /****** AddDataTypes/AddDataType **********************************************
907 * NAME
908 * AddDataType - add a DataType to the system
910 * SYNOPSIS
912 * FUNCTION
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!
923 * INPUTS
925 * RETURNS
927 * A pointer to a CompoundDataType in the system DataTypes list
928 * or a NULL pointer for failure
930 * EXAMPLE
932 * SEE ALSO
934 ******************************************************************************
938 struct CompoundDataType *AddDataType(struct StackVars *sv,
939 struct CompoundDataType *cdt)
941 struct List *typelist;
942 BOOL Success = FALSE;
943 ULONG AllocSize;
944 ULONG result;
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;
956 if(typelist)
958 cdt->DT.dtn_Node1.ln_Name = cdt->DT.dtn_Node2.ln_Name = cdt->DTH.dth_Name;
960 Success = TRUE;
962 if((!Stricmp(cdt->DTH.dth_Pattern, "#?")) ||
963 (!strlen(cdt->DTH.dth_Pattern)) )
965 cdt->FlagLong |= CFLGF_PATTERN_UNUSED;
967 else
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)))
976 Success = FALSE;
978 else
980 cdt->ParsePatSize = AllocSize;
982 result = ParsePatternNoCase(cdt->DTH.dth_Pattern,
983 cdt->ParsePatMem, AllocSize);
985 if(result == 1)
987 cdt->FlagLong |= CFLGF_IS_WILD;
989 else
991 FreeVec(cdt->ParsePatMem);
992 cdt->ParsePatMem = NULL;
993 cdt->ParsePatSize = 0;
995 if(result == 0)
997 cdt->FlagLong &= ~(CFLGF_IS_WILD);
999 else
1001 Success = FALSE;
1007 if (Success)
1009 if((oldcdt = (struct CompoundDataType*)__FindNameNoCase(sv,
1010 typelist,
1011 cdt->DT.dtn_Node1.ln_Name)))
1013 if (oldcdt->OpenCount)
1015 Success = FALSE;
1017 else
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);
1027 oldcdt = NULL;
1029 else
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));
1039 if(Success)
1041 if(oldcdt)
1043 DeleteDataType(sv, cdt);
1044 cdt = oldcdt;
1046 else
1048 if(cdt->DT.dtn_FunctionName)
1050 LONG DefaultStack = 4096;
1051 BPTR file;
1052 ULONG AllocLen;
1053 BPTR SegList;
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;
1071 HookPosition = 0;
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?
1083 else
1085 FreeVec(cdt->DTCDChunk);
1086 cdt->DTCDChunk = NULL;
1087 cdt->DTCDSize = 0;
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);
1110 if(!Success)
1112 DeleteDataType(sv, cdt);
1113 cdt = NULL;
1116 return cdt;
1121 /****** AddDataTypes/DeleteDataType *******************************************
1123 * NAME
1124 * DeleteDataType - unlink and deallocate a CompoundDataType structure
1126 * SYNOPSIS
1128 * FUNCTION
1130 * INPUTS
1132 * RETURNS
1134 * EXAMPLE
1136 * SEE ALSO
1138 ******************************************************************************
1142 void DeleteDataType(struct StackVars *sv, struct CompoundDataType *cdt)
1144 if(cdt)
1146 if(cdt->ParsePatMem)
1148 FreeVec(cdt->ParsePatMem);
1149 cdt->ParsePatMem = NULL;
1150 cdt->ParsePatSize = 0;
1153 if(cdt->DTCDChunk)
1155 FreeVec(cdt->DTCDChunk);
1156 cdt->DTCDChunk = NULL;
1157 cdt->DTCDSize = 0;
1160 if(cdt->SegList)
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;
1175 FreeVec(cdt);
1181 /****** AddDataTypes/AlphaInsert **********************************************
1183 * NAME
1184 * AlphaInsert - enqueue a node alphabetically into a list
1186 * SYNOPSIS
1188 * FUNCTION
1190 * INPUTS
1192 * RETURNS
1194 * EXAMPLE
1196 * SEE ALSO
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)
1209 break;
1212 Insert(list, node, prev);
1217 /****** AddDataTypes/__FindNameNoCase *****************************************
1219 * NAME
1220 * __FindNameNoCase - find a node in a list (case insensitive)
1222 * SYNOPSIS
1224 * FUNCTION
1226 * INPUTS
1228 * RETURNS
1230 * EXAMPLE
1232 * SEE ALSO
1234 ******************************************************************************
1238 struct Node *__FindNameNoCase(struct StackVars *sv, struct List *list,
1239 STRPTR name)
1241 struct Node *node;
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))
1248 result = node;
1249 break;
1253 return result;
1258 /****** AddDataTypes/ReadFunc *************************************************
1260 * NAME
1261 * ReadFunc - data read hook for InternalLoadSeg
1263 * SYNOPSIS
1265 * FUNCTION
1267 * INPUTS
1269 * RETURNS
1271 * EXAMPLE
1273 * SEE ALSO
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))
1285 AROS_USERFUNC_INIT
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;
1295 return actual;
1297 AROS_USERFUNC_EXIT
1300 /****** AddDataTypes/SeekFunc *************************************************
1302 * NAME
1303 * SeekFunc - seek hook for InternalLoadSeg (ELF only)
1305 * SYNOPSIS
1307 * FUNCTION
1309 * INPUTS
1311 * RETURNS
1313 * EXAMPLE
1315 * SEE ALSO
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))
1327 AROS_USERFUNC_INIT
1329 struct StackVars *sv = (APTR)fh;
1330 LONG oldpos = HookPosition;
1332 switch (mode) {
1333 case OFFSET_BEGINNING: break;
1334 case OFFSET_END: pos = HookBufSize - pos; break;
1335 case OFFSET_CURRENT: pos = HookPosition + pos; break;
1336 default: return -1;
1339 if (pos < 0 || pos >= HookBufSize)
1340 return -1;
1342 HookPosition = pos;
1344 return oldpos;
1346 AROS_USERFUNC_EXIT
1349 /****** AddDataTypes/AllocFunc ************************************************
1351 * NAME
1352 * AllocFunc - memory allocation hook for InternalLoadSeg
1354 * SYNOPSIS
1356 * FUNCTION
1358 * INPUTS
1360 * RETURNS
1362 * EXAMPLE
1364 * SEE ALSO
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))
1375 AROS_USERFUNC_INIT
1377 return(AllocMem(size, flags));
1379 AROS_USERFUNC_EXIT
1384 /****** AddDataTypes/FreeFunc *************************************************
1386 * NAME
1387 * FreeFunc - memory freeing hook for InternalLoadSeg
1389 * SYNOPSIS
1391 * FUNCTION
1393 * INPUTS
1395 * RETURNS
1397 * EXAMPLE
1399 * SEE ALSO
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))
1410 AROS_USERFUNC_INIT
1412 FreeMem(memory, size);
1414 AROS_USERFUNC_EXIT
1419 /******************************* STUB ROUTINES ********************************/
1421 struct NamedObject *allocnamedobject(struct StackVars *sv, STRPTR name,
1422 Tag FirstTag, ...)
1424 return AllocNamedObjectA(name, (struct TagItem*)&FirstTag);