use the override options if specified
[AROS.git] / tools / dtdesc / createdtdesc.c
blob840f01219dc71eae1dc65679489bf55802a529a8
1 /*
2 Copyright © 2000-2019, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: DataTypesDescriptorCreator
6 Lang: English.
7 */
9 #include "createdtdesc.h"
10 #include "parser.h"
12 int main(int argc, char **argv)
14 struct DTDesc *TheDTDesc;
16 if(Init(argc, argv, &TheDTDesc))
18 Work(TheDTDesc);
21 Cleanup(TheDTDesc);
23 return(0);
26 int HandleName(struct DTDesc *TheDTDesc)
28 uint8_t *DataPtr;
30 if(!TheDTDesc)
32 return(FALSE);
35 TheDTDesc->ReadBuffer[READBUFFERSIZE-1]='\0';
37 DataPtr=TheDTDesc->ReadBuffer+KeywordLength[Name];
40 * What, who yells buffer-overflow here?
43 strcpy(TheDTDesc->Name, DataPtr);
45 TheDTDesc->DTH.dth_Name=TheDTDesc->Name;
47 return(TRUE);
50 int HandleVersion(struct DTDesc *TheDTDesc)
52 uint8_t *DataPtr;
54 if(!TheDTDesc)
56 return(FALSE);
59 TheDTDesc->ReadBuffer[READBUFFERSIZE-1]='\0';
61 DataPtr=TheDTDesc->ReadBuffer+KeywordLength[Version];
64 * What, who yells buffer-overflow here?
67 strcpy(TheDTDesc->Version, DataPtr);
69 return(TRUE);
72 int HandleBaseName(struct DTDesc *TheDTDesc)
74 uint8_t *DataPtr;
76 if(!TheDTDesc)
78 return(FALSE);
81 TheDTDesc->ReadBuffer[READBUFFERSIZE-1]='\0';
83 DataPtr=TheDTDesc->ReadBuffer+KeywordLength[BaseName];
86 * What, who yells buffer-overflow here?
89 strcpy(TheDTDesc->BaseName, DataPtr);
91 TheDTDesc->DTH.dth_BaseName=TheDTDesc->BaseName;
93 return(TRUE);
96 int HandlePattern(struct DTDesc *TheDTDesc)
98 uint8_t *DataPtr;
100 if(!TheDTDesc)
102 return(FALSE);
105 TheDTDesc->ReadBuffer[READBUFFERSIZE-1]='\0';
107 DataPtr=TheDTDesc->ReadBuffer+KeywordLength[Pattern];
110 * What, who yells buffer-overflow here?
113 strcpy(TheDTDesc->Pattern, DataPtr);
115 TheDTDesc->DTH.dth_Pattern=TheDTDesc->Pattern;
117 return(TRUE);
120 int HandleMask(struct DTDesc *TheDTDesc)
122 uint8_t *DataPtr;
123 int i;
125 if(!TheDTDesc)
127 return(FALSE);
130 TheDTDesc->ReadBuffer[READBUFFERSIZE-1]='\0';
132 DataPtr=TheDTDesc->ReadBuffer+KeywordLength[Mask];
134 #if 1
136 uint8_t *NewDataPtr;
137 int done = 0;
139 TheDTDesc->DTH.dth_MaskLen = 0;
141 while(!done)
143 uint8_t c = *DataPtr++;
145 switch(c)
147 case '\0':
148 done = 1;
149 break;
151 case '\'':
152 c = *DataPtr++;
153 TheDTDesc->Mask[TheDTDesc->DTH.dth_MaskLen++] = c;
154 if (c) c = *DataPtr++;
155 if (!c) done = 1;
156 break;
158 case 'A':
159 c = *DataPtr++;
160 if (!c) done = 1;
161 if (c != 'N') break;
162 c = *DataPtr++;
163 if (!c) done = 1;
164 if (c != 'Y') break;
165 TheDTDesc->Mask[TheDTDesc->DTH.dth_MaskLen++] = 0xFFFF;
166 break;
168 case ' ':
169 case '\t':
170 break;
172 default:
173 DataPtr--;
174 i = strtol(DataPtr, (char **)(&NewDataPtr), 0);
175 if (DataPtr != NewDataPtr)
177 DataPtr = NewDataPtr;
178 TheDTDesc->Mask[TheDTDesc->DTH.dth_MaskLen++] = i;
180 else
182 DataPtr++;
184 break;
190 #else
191 TheDTDesc->DTH.dth_MaskLen=(uint16_t) strlen(DataPtr);
192 if(!TheDTDesc->DTH.dth_MaskLen)
194 return(TRUE);
197 for(i=0; i<TheDTDesc->DTH.dth_MaskLen; i++)
199 TheDTDesc->Mask[i] = (DataPtr[i]==0xFF) ? 0xFFFF : (uint16_t) DataPtr[i];
201 #endif
203 TheDTDesc->DTH.dth_Mask=TheDTDesc->Mask;
205 return(TRUE);
208 int HandleGroupID(struct DTDesc *TheDTDesc)
210 uint8_t *DataPtr;
212 if(!TheDTDesc)
214 return(FALSE);
217 TheDTDesc->ReadBuffer[READBUFFERSIZE-1]='\0';
219 DataPtr=TheDTDesc->ReadBuffer+KeywordLength[GroupID];
221 if(strlen(DataPtr)<4)
223 return(FALSE);
226 TheDTDesc->DTH.dth_GroupID=MAKE_ID(DataPtr[0], DataPtr[1], DataPtr[2], DataPtr[3]);
228 return(TRUE);
231 int HandleID(struct DTDesc *TheDTDesc)
233 uint8_t *DataPtr;
235 if(!TheDTDesc)
237 return(FALSE);
240 TheDTDesc->ReadBuffer[READBUFFERSIZE-1]='\0';
242 DataPtr=TheDTDesc->ReadBuffer+KeywordLength[ID];
244 if(strlen(DataPtr)<4)
246 return(FALSE);
249 TheDTDesc->DTH.dth_ID=MAKE_ID(DataPtr[0], DataPtr[1], DataPtr[2], DataPtr[3]);
251 return(TRUE);
254 int HandleFlags(struct DTDesc *TheDTDesc)
256 uint8_t *DataPtr;
257 long Len;
258 int i;
260 const char *TheFlags[] =
262 "DTF_BINARY",
263 "DTF_ASCII",
264 "DTF_IFF",
265 "DTF_MISC",
266 "DTF_CASE",
267 "DTF_SYSTEM1"
270 const int FlagLength[] =
280 const int NumFlags=6;
282 const uint16_t FlagValues[] =
284 0x0000,
285 0x0001,
286 0x0002,
287 0x0003,
288 0x0010,
289 0x1000
292 if(!TheDTDesc)
294 return(FALSE);
297 TheDTDesc->ReadBuffer[READBUFFERSIZE-1]='\0';
299 DataPtr=TheDTDesc->ReadBuffer+KeywordLength[Flags];
301 TheDTDesc->DTH.dth_Flags=0;
303 Len=strlen(DataPtr);
304 if(!Len)
306 return(TRUE);
309 while(Len>0)
311 for(i=0; i<NumFlags; i++)
313 if(Len<FlagLength[i])
315 continue;
318 if(strncmp(TheFlags[i], DataPtr, FlagLength[i])==0)
320 TheDTDesc->DTH.dth_Flags |= FlagValues[i];
322 Len-=(FlagLength[i]-1);
323 DataPtr+=(FlagLength[i]-1);
325 break;
329 Len--;
330 DataPtr++;
333 return(TRUE);
336 int HandlePriority(struct DTDesc *TheDTDesc)
338 uint8_t *DataPtr;
339 unsigned long Pri;
341 if(!TheDTDesc)
343 return(FALSE);
346 TheDTDesc->ReadBuffer[READBUFFERSIZE-1]='\0';
348 DataPtr=TheDTDesc->ReadBuffer+KeywordLength[Priority];
350 Pri=strtoul(DataPtr, NULL, 10);
352 TheDTDesc->DTH.dth_Priority=(uint16_t) Pri;
354 return(TRUE);
357 int HandleLine(struct DTDesc *TheDTDesc)
359 int RetVal;
360 int i;
362 if(!TheDTDesc)
364 return(FALSE);
367 RetVal=TRUE;
369 for(i=0; i<NumKeywords; i++)
371 if(strncmp(TheDTDesc->ReadBuffer, Keywords[i], KeywordLength[i])==0)
373 RetVal=KeywordHandler[i](TheDTDesc);
375 break;
379 return(RetVal);
382 int RemoveNewLine(struct DTDesc *TheDTDesc)
384 int Len;
386 if(!TheDTDesc)
388 return(FALSE);
391 Len=strlen(TheDTDesc->ReadBuffer);
393 if(TheDTDesc->ReadBuffer[Len-1]=='\n')
395 TheDTDesc->ReadBuffer[Len-1]='\0';
398 return(TRUE);
401 void Work(struct DTDesc *TheDTDesc)
404 if(!TheDTDesc)
406 return;
409 memset(TheDTDesc->ReadBuffer, '\0', READBUFFERSIZE);
411 while(fgets(TheDTDesc->ReadBuffer, READBUFFERSIZE, TheDTDesc->Input))
413 RemoveNewLine(TheDTDesc);
415 if(!HandleLine(TheDTDesc))
417 break;
420 memset(TheDTDesc->ReadBuffer, '\0', READBUFFERSIZE);
423 WriteOutDTD(TheDTDesc);
427 int WriteOutDTD(struct DTDesc *TheDTDesc)
429 struct IFFHandle *IH;
430 struct FileDataTypeHeader FileDTH;
431 int i;
433 if(!TheDTDesc)
435 return(FALSE);
438 if(strlen(TheDTDesc->Name)==0)
440 return(FALSE);
443 if(strlen(TheDTDesc->BaseName)==0)
445 return(FALSE);
448 #if 0
449 if(TheDTDesc->DTH.dth_MaskLen==0)
451 return(FALSE);
453 #endif
455 if(strlen(TheDTDesc->Pattern)==0)
457 TheDTDesc->Pattern[0]='#';
458 TheDTDesc->Pattern[1]='?';
459 TheDTDesc->Pattern[2]='\0';
462 IH=NewIFF(TheDTDesc->OutputName, MAKE_ID('D','T','Y','P'));
463 if(!IH)
465 return(FALSE);
468 if(!NewChunk(IH, MAKE_ID('N','A','M','E')))
470 CloseIFF(IH);
471 remove(TheDTDesc->Name);
472 return(FALSE);
475 if(WriteChunkData(IH, TheDTDesc->Name, (strlen(TheDTDesc->Name)+1))<=0)
477 EndChunk(IH);
478 CloseIFF(IH);
479 remove(TheDTDesc->Name);
480 return(FALSE);
483 EndChunk(IH);
485 if(strlen(TheDTDesc->Version) > 0)
487 if(!NewChunk(IH, MAKE_ID('F','V','E','R')))
489 CloseIFF(IH);
490 remove(TheDTDesc->Name);
491 return(FALSE);
494 if(WriteChunkData(IH, TheDTDesc->Version, (strlen(TheDTDesc->Version)+1))<=0)
496 EndChunk(IH);
497 CloseIFF(IH);
498 remove(TheDTDesc->Name);
499 return(FALSE);
502 EndChunk(IH);
505 if(!NewChunk(IH, MAKE_ID('D','T','H','D')))
507 CloseIFF(IH);
508 remove(TheDTDesc->Name);
509 return(FALSE);
512 //ASSERT((sizeof(struct FileDataTypeHeader) & 1) == 0);
513 if (TheDTDesc->DTH.dth_MaskLen > 0)
515 // Write the mask directly after the header to preserve its word alignment.
516 FileDTH.dth_Mask = (((unsigned int) sizeof(struct FileDataTypeHeader)));
517 FileDTH.dth_Name = (((unsigned int) FileDTH.dth_Mask) + (TheDTDesc->DTH.dth_MaskLen << 1));
518 FileDTH.dth_Mask = Swap32IfLE(((uint32_t) FileDTH.dth_Mask));
520 else
522 FileDTH.dth_Mask = 0;
523 FileDTH.dth_Name = (((unsigned int) sizeof(struct FileDataTypeHeader)));
525 FileDTH.dth_BaseName = (((unsigned int) FileDTH.dth_Name) + strlen(TheDTDesc->DTH.dth_Name) + 1);
526 FileDTH.dth_Pattern = (((unsigned int) FileDTH.dth_BaseName) + strlen(TheDTDesc->DTH.dth_BaseName) + 1);
527 FileDTH.dth_GroupID = TheDTDesc->DTH.dth_GroupID;
528 FileDTH.dth_ID = TheDTDesc->DTH.dth_ID;
529 FileDTH.dth_MaskLen = TheDTDesc->DTH.dth_MaskLen;
530 FileDTH.dth_Pad = TheDTDesc->DTH.dth_Pad;
531 FileDTH.dth_Flags = TheDTDesc->DTH.dth_Flags;
532 FileDTH.dth_Priority = TheDTDesc->DTH.dth_Priority;
534 FileDTH.dth_Name = Swap32IfLE(((uint32_t) FileDTH.dth_Name));
535 FileDTH.dth_BaseName = Swap32IfLE(((uint32_t) FileDTH.dth_BaseName));
536 FileDTH.dth_Pattern = Swap32IfLE(((uint32_t) FileDTH.dth_Pattern));
537 FileDTH.dth_GroupID = Swap32IfLE(FileDTH.dth_GroupID);
538 FileDTH.dth_ID = Swap32IfLE(FileDTH.dth_ID);
539 FileDTH.dth_MaskLen = Swap16IfLE(FileDTH.dth_MaskLen);
540 FileDTH.dth_Pad = Swap16IfLE(FileDTH.dth_Pad);
541 FileDTH.dth_Flags = Swap16IfLE(FileDTH.dth_Flags);
542 FileDTH.dth_Priority = Swap16IfLE(FileDTH.dth_Priority);
544 if(WriteChunkData(IH, (char *) &FileDTH, sizeof(struct FileDataTypeHeader))<=0)
546 EndChunk(IH);
547 CloseIFF(IH);
548 remove(TheDTDesc->Name);
549 return(FALSE);
552 if (TheDTDesc->DTH.dth_MaskLen)
554 for(i=0; i<TheDTDesc->DTH.dth_MaskLen; i++)
556 TheDTDesc->DTH.dth_Mask[i]=Swap16IfLE(TheDTDesc->DTH.dth_Mask[i]);
559 if(WriteChunkData(IH, (char *) TheDTDesc->DTH.dth_Mask, TheDTDesc->DTH.dth_MaskLen << 1)<=0)
561 EndChunk(IH);
562 CloseIFF(IH);
563 remove(TheDTDesc->Name);
564 return(FALSE);
568 if(WriteChunkData(IH, TheDTDesc->DTH.dth_Name, (strlen(TheDTDesc->DTH.dth_Name) + 1))<=0)
570 EndChunk(IH);
571 CloseIFF(IH);
572 remove(TheDTDesc->Name);
573 return(FALSE);
576 if(WriteChunkData(IH, TheDTDesc->DTH.dth_BaseName, (strlen(TheDTDesc->DTH.dth_BaseName) + 1))<=0)
578 EndChunk(IH);
579 CloseIFF(IH);
580 remove(TheDTDesc->Name);
581 return(FALSE);
584 if(WriteChunkData(IH, TheDTDesc->DTH.dth_Pattern, (strlen(TheDTDesc->DTH.dth_Pattern) + 1))<=0)
586 EndChunk(IH);
587 CloseIFF(IH);
588 remove(TheDTDesc->Name);
589 return(FALSE);
592 EndChunk(IH);
594 CloseIFF(IH);
596 return(TRUE);
599 int Init(int argc, char **argv, struct DTDesc **TheDTDesc)
601 struct DTDesc *NewDTDesc;
603 if(!(argv && TheDTDesc))
605 return(FALSE);
608 *TheDTDesc=NULL;
610 NewDTDesc=(struct DTDesc *) malloc(sizeof(struct DTDesc));
611 if(!NewDTDesc)
613 return(FALSE);
616 *TheDTDesc=NewDTDesc;
618 memset(NewDTDesc, '\0', sizeof(struct DTDesc));
620 NewDTDesc->ProgName=argv[0];
621 NewDTDesc->Input=stdin;
622 NewDTDesc->OutputName=NewDTDesc->Name;
624 if(!ParseArgs(argc, argv, NewDTDesc))
626 return(FALSE);
629 if(!OpenInput(NewDTDesc))
631 return(FALSE);
634 return(TRUE);
637 int OpenInput(struct DTDesc *TheDTDesc)
640 if(!TheDTDesc)
642 return(FALSE);
645 if(TheDTDesc->InputName)
647 TheDTDesc->Input=fopen(TheDTDesc->InputName, "r");
648 if(!TheDTDesc->Input)
650 TheDTDesc->Input=stdin;
652 return(FALSE);
656 return(TRUE);
659 int ParseArgs(int argc, char **argv, struct DTDesc *TheDTDesc)
661 int i;
663 if(!(argv && TheDTDesc))
665 return(FALSE);
668 for(i=1; i<argc; i++)
670 if(strcmp(argv[i], "-o") == 0)
672 if(++i >= argc)
674 Usage(TheDTDesc->ProgName);
676 return(FALSE);
679 TheDTDesc->OutputName=argv[i];
681 else
683 if(strcmp(argv[i], "-h") == 0)
685 Usage(TheDTDesc->ProgName);
687 return(FALSE);
689 else
691 TheDTDesc->InputName=argv[i];
696 return(TRUE);
699 void Usage(char *ProgName)
701 char DefaultName[]="createdtdesc";
702 char *NamePtr;
704 NamePtr = ProgName ? ProgName : DefaultName;
706 fprintf(stderr, "\n"
707 "usage: %s [-o <Output-Name>] <Input-Name>\n"
708 "\n",
709 NamePtr);
712 void Cleanup(struct DTDesc *TheDTDesc)
714 if(TheDTDesc)
716 if((TheDTDesc->Input!=NULL) && (TheDTDesc->Input!=stdin))
718 fclose(TheDTDesc->Input);
721 free((void *) TheDTDesc);