Added locale item (sysmon.cd)
[AROS.git] / workbench / c / AddDataTypes.c
blob325dd7e0cb494c485821e3af71b7205c2a1a8f2c
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;
331 if(CheckSignal(SIGBREAKF_CTRL_C))
333 Flush(Output());
334 PrintFault(ERROR_BREAK,0);
335 break;
337 cdt=(struct CompoundDataType *)(node-1);
338 dth=cdt->DT.dtn_Header;
341 Printf("%s, \"%s\"\n", dth->dth_BaseName, dth->dth_Name);
342 node = node->ln_Succ;
349 result = RETURN_OK;
350 FreeArgs(RDArgs);
354 ReleaseSemaphore(&DTList->dtl_Lock);
357 return result;
362 /****** AddDataTypes/DateScan *************************************************
364 * NAME
365 * DateScan - See if DataTypes descriptors need updating
367 * SYNOPSIS
369 * FUNCTION
371 * INPUTS
373 * RETURNS
375 * EXAMPLE
377 * SEE ALSO
379 ******************************************************************************
383 BOOL DateScan(struct StackVars *sv)
385 BOOL result = TRUE;
386 BPTR lock;
387 struct FileInfoBlock *fib;
389 if((lock = Lock("DEVS:DataTypes", ACCESS_READ)))
391 if((fib = AllocDosObject(DOS_FIB, NULL)))
393 if(Examine(lock, fib))
395 if(!CompareDates(&fib->fib_Date, &DTList->dtl_DateStamp))
397 result = FALSE;
399 else
401 DTList->dtl_DateStamp = fib->fib_Date;
405 FreeDosObject(DOS_FIB,fib);
408 UnLock(lock);
411 return result;
416 /****** AddDataTypes/ScanDirectory ********************************************
418 * NAME
419 * ScanDirectory - Scan a directory recursively for DT descriptors
421 * SYNOPSIS
423 * FUNCTION
425 * INPUTS
427 * RETURNS
429 * EXAMPLE
431 * SEE ALSO
433 ******************************************************************************
437 void ScanDirectory(struct StackVars *sv, STRPTR pattern)
439 struct AnchorPath *AnchorPath;
440 LONG RetVal;
441 BPTR OldDir;
443 if((AnchorPath = (struct AnchorPath *)AllocVec(sizeof(struct AnchorPath),
444 MEMF_CLEAR)))
446 AnchorPath->ap_BreakBits = SIGBREAKF_CTRL_C;
448 RetVal = MatchFirst(pattern, AnchorPath);
450 while(!RetVal)
452 if(CheckSignal(SIGBREAKF_CTRL_C))
454 if(!AA.aa_Quiet)
456 PrintFault(ERROR_BREAK, NULL);
459 break;
462 if(AnchorPath->ap_Info.fib_DirEntryType > 0L)
464 if(!(AnchorPath->ap_Flags & APF_DIDDIR))
466 AnchorPath->ap_Flags |= APF_DODIR;
469 AnchorPath->ap_Flags &= ~APF_DIDDIR;
471 else
473 if(!MatchPatternNoCase(ExclPat,
474 AnchorPath->ap_Info.fib_FileName))
476 OldDir = CurrentDir(AnchorPath->ap_Current->an_Lock);
478 LoadDataType(sv, AnchorPath->ap_Info.fib_FileName);
480 CurrentDir(OldDir);
484 RetVal = MatchNext(AnchorPath);
487 if(RetVal != ERROR_NO_MORE_ENTRIES)
489 if(!AA.aa_Quiet)
491 PrintFault(RetVal, NULL);
495 MatchEnd(AnchorPath);
497 FreeVec((APTR)AnchorPath);
502 /****** AddDataTypes/CreateDTList *********************************************
504 * NAME
505 * CreateDTList - Create and initialize the DataTypesList
507 * SYNOPSIS
509 * FUNCTION
511 * INPUTS
513 * RETURNS
515 * EXAMPLE
517 * SEE ALSO
519 ******************************************************************************
523 struct DataTypesList *CreateDTList(struct StackVars *sv)
525 struct DataTypesList *dtl = NULL;
526 struct NamedObject *no = NULL;
527 struct Library *DTBase;
529 /* We do this in order to force datatypes.library to get
530 loaded and initialized. During this process it will
531 create and install DataTypes list object in memory. */
532 DTBase = OpenLibrary("datatypes.library", 0);
533 if (DTBase)
534 CloseLibrary(DTBase);
536 if((no = FindNamedObject(NULL, DATATYPESLIST, NULL)))
538 dtl = (struct DataTypesList*)no->no_Object;
541 if(dtl)
543 if(!__FindNameNoCase(sv, &dtl->dtl_BinaryList, "binary"))
545 CreateBasicType
547 sv, &dtl->dtl_BinaryList, &dtl->dtl_SortedList,
548 "binary", DTF_BINARY, ID_BINARY, GID_SYSTEM
552 if(!__FindNameNoCase(sv, &dtl->dtl_ASCIIList, "ascii"))
554 CreateBasicType
556 sv, &dtl->dtl_ASCIIList, &dtl->dtl_SortedList,
557 "ascii", DTF_ASCII, ID_ASCII, GID_TEXT
561 if(!__FindNameNoCase(sv, &dtl->dtl_IFFList, "iff"))
563 CreateBasicType
565 sv, &dtl->dtl_IFFList, &dtl->dtl_SortedList,
566 "iff", DTF_IFF, ID_IFF, GID_SYSTEM
570 if(!__FindNameNoCase(sv, &dtl->dtl_MiscList, "directory"))
572 CreateBasicType
574 sv, &dtl->dtl_MiscList, &dtl->dtl_SortedList,
575 "directory", DTF_MISC, ID_DIRECTORY, GID_SYSTEM
580 if(no)
582 ReleaseNamedObject(no);
586 return dtl;
591 /****** AddDataTypes/CreateBasicType ******************************************
593 * NAME
594 * CreateBasicType - Initialize one of the basic types
596 * SYNOPSIS
598 * FUNCTION
600 * INPUTS
602 * RETURNS
604 * EXAMPLE
606 * SEE ALSO
608 ******************************************************************************
612 struct CompoundDataType *CreateBasicType(struct StackVars *sv,
613 struct List *list,
614 struct List *globallist, STRPTR name,
615 UWORD Flags, ULONG ID, ULONG GroupID)
617 struct CompoundDataType *cdt;
618 ULONG AllocLen = sizeof(struct CompoundDataType) + strlen(name) + 1;
620 if((cdt = AllocVec(AllocLen, MEMF_PUBLIC | MEMF_CLEAR)))
622 cdt->DT.dtn_Header = &cdt->DTH;
624 strcpy((UBYTE*)(cdt + 1), name);
626 cdt->DTH.dth_Name=
627 cdt->DTH.dth_BaseName=
628 cdt->DT.dtn_Node1.ln_Name=
629 cdt->DT.dtn_Node2.ln_Name=(UBYTE*)(cdt + 1);
631 cdt->DTH.dth_GroupID = GroupID;
632 cdt->DTH.dth_ID = ID;
634 cdt->DTH.dth_Flags = Flags;
636 NewList(&cdt->DT.dtn_ToolList);
638 cdt->DT.dtn_Length = AllocLen;
640 cdt->DT.dtn_Node1.ln_Pri = -128;
641 Enqueue(list, &cdt->DT.dtn_Node1);
643 AlphaInsert(sv, globallist, &cdt->DT.dtn_Node2);
646 return cdt;
651 /****** AddDataTypes/LoadDataType *********************************************
653 * NAME
654 * LoadDataType - Load and install a single DataType descriptor
656 * SYNOPSIS
658 * FUNCTION
660 * INPUTS
662 * RETURNS
664 * EXAMPLE
666 * SEE ALSO
668 ******************************************************************************
672 void LoadDataType(struct StackVars *sv, STRPTR name)
674 struct IFFHandle *iff;
676 if((iff = AllocIFF()))
678 if((iff->iff_Stream = (IPTR)Open(name, MODE_OLDFILE))) /* Why IPTR? */
680 InitIFFasDOS(iff);
682 if(!OpenIFF(iff, IFFF_READ))
684 if(!PropChunks(iff, PropArray, NUM_PROP))
686 if(!CollectionChunks(iff, CollArray, NUM_COLL))
688 if(!StopOnExit(iff, ID_DTYP, ID_FORM))
690 LONG error;
692 while((error = ParseIFF(iff, IFFPARSE_SCAN)) == IFFERR_EOC)
694 CreateDataType(sv, iff);
695 /* FIXME: The while ParseIFF loop here crashes the 2nd time inside the loop, therefore the break below as temp fix */
696 break;
702 CloseIFF(iff);
705 Close((BPTR)iff->iff_Stream);
708 FreeIFF(iff);
710 else
712 SetIoErr(ERROR_NO_FREE_STORE);
717 /****** AddDataTypes/MemStreamHook *******************************************
719 * NAME
720 * MemStreamHook - needed by ReadStruct
722 * SYNOPSIS
724 * FUNCTION
726 * INPUTS
728 * RETURNS
730 * EXAMPLE
732 * SEE ALSO
734 ******************************************************************************
738 LONG MemStreamHook(struct Hook * hook, UBYTE **memptr, Msg msg)
740 LONG rc;
742 switch (msg->MethodID)
744 case BEIO_READ:
745 rc = **memptr;
746 (*memptr)++;
747 break;
749 default:
750 rc = -1;
751 break;
754 return rc;
757 /****** AddDataTypes/CreateDataType *******************************************
759 * NAME
760 * CreateDataType - create a DataType from IFF chunks
762 * SYNOPSIS
764 * FUNCTION
766 * INPUTS
768 * RETURNS
770 * EXAMPLE
772 * SEE ALSO
774 ******************************************************************************
778 struct CompoundDataType *CreateDataType(struct StackVars *sv,
779 struct IFFHandle *iff)
781 struct CompoundDataType *cdt = NULL;
782 struct StoredProperty *prop;
783 ULONG AllocLen;
784 UBYTE *func;
785 LONG DefaultStack = AROS_STACKSIZE, i;
786 BPTR SegList;
788 if((prop = FindProp(iff, ID_DTYP, ID_DTHD)))
790 AllocLen = sizeof(struct CompoundDataType) -
791 32 + /* was sizeof(struct DataTypeHeader), but we must use struct size as it would be on Amiga */
792 prop->sp_Size;
794 if(!(cdt = AllocVec(AllocLen, MEMF_PUBLIC | MEMF_CLEAR)))
796 SetIoErr(ERROR_NO_FREE_STORE);
798 else
800 struct FileDataTypeHeader *fdh = NULL;
801 UBYTE *memptr = (UBYTE *)prop->sp_Data;
802 struct Hook hook;
804 hook.h_Entry = (HOOKFUNC)HookEntry;
805 hook.h_SubEntry = (HOOKFUNC)MemStreamHook;
807 if (ReadStruct(&hook, (APTR *) &fdh, &memptr, FileDataTypeHeaderDesc))
809 IPTR extraoffset = sizeof(struct DataTypeHeader) - 32;
811 cdt->DT.dtn_Header= &cdt->DTH;
813 cdt->DTH.dth_Name = (STRPTR)(fdh->fdth_NameOffset + extraoffset + (IPTR)&cdt->DTH);
814 cdt->DTH.dth_BaseName = (STRPTR)(fdh->fdth_BaseNameOffset + extraoffset + (IPTR)&cdt->DTH);
815 cdt->DTH.dth_Pattern = (STRPTR)(fdh->fdth_PatternOffset + extraoffset + (IPTR)&cdt->DTH);
816 cdt->DTH.dth_Mask = (WORD *)(fdh->fdth_MaskOffset + extraoffset + (IPTR)&cdt->DTH);
817 cdt->DTH.dth_GroupID = fdh->fdth_GroupID;
818 cdt->DTH.dth_ID = fdh->fdth_ID;
819 cdt->DTH.dth_MaskLen = fdh->fdth_MaskLen;
820 cdt->DTH.dth_Pad = fdh->fdth_Pad;
821 cdt->DTH.dth_Flags = fdh->fdth_Flags;
822 cdt->DTH.dth_Priority = fdh->fdth_Priority;
824 CopyMem(prop->sp_Data + 32, cdt + 1, prop->sp_Size - 32);
826 for(i = 0; i < cdt->DTH.dth_MaskLen; i++)
828 cdt->DTH.dth_Mask[i] = AROS_BE2WORD(cdt->DTH.dth_Mask[i]);
829 #if 0
830 kprintf("mask[%d] = %04x (%c %c)\n", i,
831 cdt->DTH.dth_Mask[i],
832 cdt->DTH.dth_Mask[i] & 255,
833 (cdt->DTH.dth_Mask[i] >> 8) & 255);
834 #endif
837 #if 0
838 kprintf("groupid = %c%c%c%c\n", cdt->DTH.dth_GroupID >> 24,
839 cdt->DTH.dth_GroupID >> 16,
840 cdt->DTH.dth_GroupID >> 8,
841 cdt->DTH.dth_GroupID);
842 kprintf("id = %c%c%c%c\n", cdt->DTH.dth_ID >> 24,
843 cdt->DTH.dth_ID >> 16,
844 cdt->DTH.dth_ID >> 8,
845 cdt->DTH.dth_ID);
846 kprintf("flags = %x\n", cdt->DTH.dth_Flags);
847 kprintf("pri = %d\n", cdt->DTH.dth_Priority);
848 kprintf("name = %s\n", cdt->DTH.dth_Name);
849 kprintf("basename = %s\n", cdt->DTH.dth_BaseName);
850 kprintf("pattern = %s\n", cdt->DTH.dth_Pattern);
851 kprintf("masklen = %d\n", cdt->DTH.dth_MaskLen);
852 #endif
854 NewList(&cdt->DT.dtn_ToolList);
856 cdt->DT.dtn_Length = AllocLen;
858 if((prop = FindProp(iff, ID_DTYP, ID_DTCD)))
860 if((func = AllocVec(prop->sp_Size, MEMF_PUBLIC | MEMF_CLEAR)))
862 cdt->DTCDChunk = func;
863 cdt->DTCDSize = prop->sp_Size;
865 CopyMem(prop->sp_Data,func,prop->sp_Size);
867 HookBuffer = cdt->DTCDChunk;
868 HookBufSize = cdt->DTCDSize;
869 HookPosition = 0;
871 /* We use a cast to BPTR, since sv may not
872 * be ULONG aligned. Since only our ReadFunc
873 * is going to be looking at it, this is ok.
875 if((SegList = InternalLoadSeg((BPTR)(sv), BNULL,
876 (LONG_FUNC *)FunctionArray,
877 &DefaultStack)))
879 cdt->SegList = SegList;
880 cdt->Function = BADDR(SegList) + sizeof(BPTR);
883 } /* if((func = AllocVec(prop->sp_Size, MEMF_PUBLIC | MEMF_CLEAR))) */
885 } /* if((prop = FindProp(iff, ID_DTYP, ID_DTCD))) */
887 cdt = AddDataType(sv, cdt);
889 FreeStruct(fdh, FileDataTypeHeaderDesc);
891 } /* if (ReadStruct(&hook, &fdh, &memptr, FileDataTypeHeaderDesc)) */
893 } /* cdt AllocVec okay */
895 } /* if((prop = FindProp(iff, ID_DTYP, ID_DTHD))) */
897 return cdt;
902 /****** AddDataTypes/AddDataType **********************************************
904 * NAME
905 * AddDataType - add a DataType to the system
907 * SYNOPSIS
909 * FUNCTION
911 * This subroutine tries to add a DataType to the system DataTypes
912 * list. If the DataType already exists, it will be replaced or
913 * updated. In case of an error, the CompoundDataType will be deleted
914 * and a NULL pointer is returned.
916 * The CompoundDataType pointer you passed in will be invalid after
917 * calling this function. Use the returned handle instead.
918 * DO NOT USE THE OLD POINTER IN ANY MORE!
920 * INPUTS
922 * RETURNS
924 * A pointer to a CompoundDataType in the system DataTypes list
925 * or a NULL pointer for failure
927 * EXAMPLE
929 * SEE ALSO
931 ******************************************************************************
935 struct CompoundDataType *AddDataType(struct StackVars *sv,
936 struct CompoundDataType *cdt)
938 struct List *typelist;
939 BOOL Success = FALSE;
940 ULONG AllocSize;
941 ULONG result;
942 struct CompoundDataType *oldcdt;
944 switch(cdt->DTH.dth_Flags & DTF_TYPE_MASK)
946 case DTF_BINARY: typelist= &DTList->dtl_BinaryList; break;
947 case DTF_ASCII: typelist= &DTList->dtl_ASCIIList; break;
948 case DTF_IFF: typelist= &DTList->dtl_IFFList; break;
949 case DTF_MISC: typelist= &DTList->dtl_MiscList; break;
950 default: typelist= NULL;
953 if(typelist)
955 cdt->DT.dtn_Node1.ln_Name = cdt->DT.dtn_Node2.ln_Name = cdt->DTH.dth_Name;
957 Success = TRUE;
959 if((!Stricmp(cdt->DTH.dth_Pattern, "#?")) ||
960 (!strlen(cdt->DTH.dth_Pattern)) )
962 cdt->FlagLong |= CFLGF_PATTERN_UNUSED;
964 else
966 cdt->FlagLong &= ~(CFLGF_PATTERN_UNUSED);
968 AllocSize = 2*strlen(cdt->DTH.dth_Pattern) + 2;
970 if(!(cdt->ParsePatMem = AllocVec(AllocSize,
971 MEMF_PUBLIC | MEMF_CLEAR)))
973 Success = FALSE;
975 else
977 cdt->ParsePatSize = AllocSize;
979 result = ParsePatternNoCase(cdt->DTH.dth_Pattern,
980 cdt->ParsePatMem, AllocSize);
982 if(result == 1)
984 cdt->FlagLong |= CFLGF_IS_WILD;
986 else
988 FreeVec(cdt->ParsePatMem);
989 cdt->ParsePatMem = NULL;
990 cdt->ParsePatSize = 0;
992 if(result == 0)
994 cdt->FlagLong &= ~(CFLGF_IS_WILD);
996 else
998 Success = FALSE;
1004 if (Success)
1006 if((oldcdt = (struct CompoundDataType*)__FindNameNoCase(sv,
1007 typelist,
1008 cdt->DT.dtn_Node1.ln_Name)))
1010 if (oldcdt->OpenCount)
1012 Success = FALSE;
1014 else
1016 if((Stricmp(oldcdt->DTH.dth_Name, cdt->DTH.dth_Name)) ||
1017 (Stricmp(oldcdt->DTH.dth_BaseName, cdt->DTH.dth_BaseName)) ||
1018 (Stricmp(oldcdt->DTH.dth_Pattern, cdt->DTH.dth_Pattern)) ||
1019 (oldcdt->DTH.dth_Flags != cdt->DTH.dth_Flags) ||
1020 (oldcdt->DTH.dth_Priority != cdt->DTH.dth_Priority) ||
1021 (oldcdt->DTH.dth_MaskLen != cdt->DTH.dth_MaskLen))
1023 DeleteDataType(sv, oldcdt);
1024 oldcdt = NULL;
1026 else
1028 oldcdt->DTH.dth_GroupID = cdt->DTH.dth_GroupID;
1029 oldcdt->DTH.dth_ID = cdt->DTH.dth_ID;
1030 CopyMem(cdt->DTH.dth_Mask,cdt->DTH.dth_Mask,
1031 (ULONG)(sizeof(WORD)*cdt->DTH.dth_MaskLen));
1036 if(Success)
1038 if(oldcdt)
1040 DeleteDataType(sv, cdt);
1041 cdt = oldcdt;
1043 else
1045 if(cdt->DT.dtn_FunctionName)
1047 LONG DefaultStack = 4096;
1048 BPTR file;
1049 ULONG AllocLen;
1050 BPTR SegList;
1052 if((file = Open(cdt->DT.dtn_FunctionName, MODE_OLDFILE)))
1054 if(Seek(file, 0, OFFSET_END) >= 0)
1056 if((AllocLen = Seek(file, 0,
1057 OFFSET_BEGINNING)) > 0)
1059 if((cdt->DTCDChunk = AllocVec(AllocLen,
1060 MEMF_PUBLIC | MEMF_CLEAR)))
1062 cdt->DTCDSize = AllocLen;
1064 if(Read(file, cdt->DTCDChunk, AllocLen) == AllocLen)
1066 HookBuffer = cdt->DTCDChunk;
1067 HookBufSize = cdt->DTCDSize;
1068 HookPosition = 0;
1070 /* We use a cast to BPTR, since sv may not
1071 * be ULONG aligned. Since only our ReadFunc
1072 * is going to be looking at it, this is ok.
1074 if((SegList = InternalLoadSeg((BPTR)(sv), BNULL, (LONG_FUNC *)FunctionArray, &DefaultStack)))
1076 cdt->SegList = SegList;
1077 cdt->Function = BADDR(SegList) + sizeof(BPTR); // FIXME: is this portable?
1080 else
1082 FreeVec(cdt->DTCDChunk);
1083 cdt->DTCDChunk = NULL;
1084 cdt->DTCDSize = 0;
1090 cdt->DT.dtn_FunctionName=NULL;
1093 if(cdt->DTH.dth_MaskLen > DTList->dtl_LongestMask)
1095 DTList->dtl_LongestMask = cdt->DTH.dth_MaskLen;
1098 cdt->DT.dtn_Node1.ln_Pri = cdt->DTH.dth_Priority;
1099 Enqueue(typelist, &cdt->DT.dtn_Node1);
1101 AlphaInsert(sv, &DTList->dtl_SortedList, &cdt->DT.dtn_Node2);
1107 if(!Success)
1109 DeleteDataType(sv, cdt);
1110 cdt = NULL;
1113 return cdt;
1118 /****** AddDataTypes/DeleteDataType *******************************************
1120 * NAME
1121 * DeleteDataType - unlink and deallocate a CompoundDataType structure
1123 * SYNOPSIS
1125 * FUNCTION
1127 * INPUTS
1129 * RETURNS
1131 * EXAMPLE
1133 * SEE ALSO
1135 ******************************************************************************
1139 void DeleteDataType(struct StackVars *sv, struct CompoundDataType *cdt)
1141 if(cdt)
1143 if(cdt->ParsePatMem)
1145 FreeVec(cdt->ParsePatMem);
1146 cdt->ParsePatMem = NULL;
1147 cdt->ParsePatSize = 0;
1150 if(cdt->DTCDChunk)
1152 FreeVec(cdt->DTCDChunk);
1153 cdt->DTCDChunk = NULL;
1154 cdt->DTCDSize = 0;
1157 if(cdt->SegList)
1159 UnLoadSeg(cdt->SegList);
1160 cdt->SegList = BNULL;
1161 cdt->Function = NULL;
1164 if(cdt->DT.dtn_Node1.ln_Succ && cdt->DT.dtn_Node1.ln_Pred)
1166 Remove(&cdt->DT.dtn_Node1);
1167 Remove(&cdt->DT.dtn_Node2);
1168 cdt->DT.dtn_Node1.ln_Succ = cdt->DT.dtn_Node1.ln_Pred =
1169 cdt->DT.dtn_Node2.ln_Succ = cdt->DT.dtn_Node2.ln_Pred = NULL;
1172 FreeVec(cdt);
1178 /****** AddDataTypes/AlphaInsert **********************************************
1180 * NAME
1181 * AlphaInsert - enqueue a node alphabetically into a list
1183 * SYNOPSIS
1185 * FUNCTION
1187 * INPUTS
1189 * RETURNS
1191 * EXAMPLE
1193 * SEE ALSO
1195 ******************************************************************************
1199 void AlphaInsert(struct StackVars *sv, struct List *list, struct Node *node)
1201 struct Node *cur,*prev=NULL;
1203 for(cur = list->lh_Head; cur->ln_Succ; prev = cur, cur = cur->ln_Succ)
1205 if(Stricmp(cur->ln_Name, node->ln_Name) > 0)
1206 break;
1209 Insert(list, node, prev);
1214 /****** AddDataTypes/__FindNameNoCase *****************************************
1216 * NAME
1217 * __FindNameNoCase - find a node in a list (case insensitive)
1219 * SYNOPSIS
1221 * FUNCTION
1223 * INPUTS
1225 * RETURNS
1227 * EXAMPLE
1229 * SEE ALSO
1231 ******************************************************************************
1235 struct Node *__FindNameNoCase(struct StackVars *sv, struct List *list,
1236 STRPTR name)
1238 struct Node *node;
1239 struct Node *result = NULL;
1241 for(node = list->lh_Head; node->ln_Succ; node = node->ln_Succ)
1243 if(!Stricmp(node->ln_Name, name))
1245 result = node;
1246 break;
1250 return result;
1255 /****** AddDataTypes/ReadFunc *************************************************
1257 * NAME
1258 * ReadFunc - data read hook for InternalLoadSeg
1260 * SYNOPSIS
1262 * FUNCTION
1264 * INPUTS
1266 * RETURNS
1268 * EXAMPLE
1270 * SEE ALSO
1272 ******************************************************************************
1276 AROS_UFH4(LONG, AROS_SLIB_ENTRY(ReadFunc, AddDataTypes, 0),
1277 AROS_UFHA(BPTR , fh , D1),
1278 AROS_UFHA(void * , buffer , D2),
1279 AROS_UFHA(LONG , length , D3),
1280 AROS_UFHA(struct DosLibrary *, DOSBase, A6))
1282 AROS_USERFUNC_INIT
1284 struct StackVars *sv = (APTR)fh;
1285 LONG maxlen = HookBufSize-HookPosition;
1286 LONG actual = length > maxlen ? maxlen : length;
1288 CopyMem(HookBuffer+HookPosition, buffer, actual);
1290 HookPosition += actual;
1292 return actual;
1294 AROS_USERFUNC_EXIT
1297 /****** AddDataTypes/SeekFunc *************************************************
1299 * NAME
1300 * SeekFunc - seek hook for InternalLoadSeg (ELF only)
1302 * SYNOPSIS
1304 * FUNCTION
1306 * INPUTS
1308 * RETURNS
1310 * EXAMPLE
1312 * SEE ALSO
1314 ******************************************************************************
1318 AROS_UFH4(LONG, AROS_SLIB_ENTRY(SeekFunc, AddDataTypes, 0),
1319 AROS_UFHA(BPTR , fh , D1),
1320 AROS_UFHA(LONG , pos , D2),
1321 AROS_UFHA(LONG , mode , D3),
1322 AROS_UFHA(struct DosLibrary *, DOSBase, A6))
1324 AROS_USERFUNC_INIT
1326 struct StackVars *sv = (APTR)fh;
1327 LONG oldpos = HookPosition;
1329 switch (mode) {
1330 case OFFSET_BEGINNING: break;
1331 case OFFSET_END: pos = HookBufSize - pos; break;
1332 case OFFSET_CURRENT: pos = HookPosition + pos; break;
1333 default: return -1;
1336 if (pos < 0 || pos >= HookBufSize)
1337 return -1;
1339 HookPosition = pos;
1341 return oldpos;
1343 AROS_USERFUNC_EXIT
1346 /****** AddDataTypes/AllocFunc ************************************************
1348 * NAME
1349 * AllocFunc - memory allocation hook for InternalLoadSeg
1351 * SYNOPSIS
1353 * FUNCTION
1355 * INPUTS
1357 * RETURNS
1359 * EXAMPLE
1361 * SEE ALSO
1363 ******************************************************************************
1367 AROS_UFH3(UBYTE *, AROS_SLIB_ENTRY(AllocFunc, AddDataTypes, 0),
1368 AROS_UFHA(ULONG, size, D0),
1369 AROS_UFHA(ULONG, flags,D1),
1370 AROS_UFHA(struct DosLibrary *, DOSBase, A6))
1372 AROS_USERFUNC_INIT
1374 return(AllocMem(size, flags));
1376 AROS_USERFUNC_EXIT
1381 /****** AddDataTypes/FreeFunc *************************************************
1383 * NAME
1384 * FreeFunc - memory freeing hook for InternalLoadSeg
1386 * SYNOPSIS
1388 * FUNCTION
1390 * INPUTS
1392 * RETURNS
1394 * EXAMPLE
1396 * SEE ALSO
1398 ******************************************************************************
1402 AROS_UFH3(void, AROS_SLIB_ENTRY(FreeFunc, AddDataTypes, 0),
1403 AROS_UFHA(APTR , memory, A1),
1404 AROS_UFHA(ULONG, size , D0),
1405 AROS_UFHA(struct DosLibrary *, DOSBase, A6))
1407 AROS_USERFUNC_INIT
1409 FreeMem(memory, size);
1411 AROS_USERFUNC_EXIT
1416 /******************************* STUB ROUTINES ********************************/
1418 struct NamedObject *allocnamedobject(struct StackVars *sv, STRPTR name,
1419 Tag FirstTag, ...)
1421 return AllocNamedObjectA(name, (struct TagItem*)&FirstTag);