be a bit more descriptive about failures. don't try to blindly continue if we fail...
[AROS.git] / tools / dtdesc / createdtdesc.c
bloba20b2ccc8c03ede313f9e31c8a73091a05dc24e7
1 /*
2 Copyright © 2000, 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 FileDTH.dth_Name = (((unsigned int) sizeof(struct FileDataTypeHeader)));
513 FileDTH.dth_BaseName = (((unsigned int) FileDTH.dth_Name) + strlen(TheDTDesc->DTH.dth_Name) + 1);
514 FileDTH.dth_Pattern = (((unsigned int) FileDTH.dth_BaseName) + strlen(TheDTDesc->DTH.dth_BaseName) + 1);
515 FileDTH.dth_Mask = (((unsigned int) FileDTH.dth_Pattern) + strlen(TheDTDesc->DTH.dth_Pattern) + 1);
516 FileDTH.dth_GroupID = TheDTDesc->DTH.dth_GroupID;
517 FileDTH.dth_ID = TheDTDesc->DTH.dth_ID;
518 FileDTH.dth_MaskLen = TheDTDesc->DTH.dth_MaskLen;
519 FileDTH.dth_Pad = TheDTDesc->DTH.dth_Pad;
520 FileDTH.dth_Flags = TheDTDesc->DTH.dth_Flags;
521 FileDTH.dth_Priority = TheDTDesc->DTH.dth_Priority;
523 FileDTH.dth_Name = Swap32IfLE(((uint32_t) FileDTH.dth_Name));
524 FileDTH.dth_BaseName = Swap32IfLE(((uint32_t) FileDTH.dth_BaseName));
525 FileDTH.dth_Pattern = Swap32IfLE(((uint32_t) FileDTH.dth_Pattern));
526 FileDTH.dth_Mask = Swap32IfLE(((uint32_t) FileDTH.dth_Mask));
527 FileDTH.dth_GroupID = Swap32IfLE(FileDTH.dth_GroupID);
528 FileDTH.dth_ID = Swap32IfLE(FileDTH.dth_ID);
529 FileDTH.dth_MaskLen = Swap16IfLE(FileDTH.dth_MaskLen);
530 FileDTH.dth_Pad = Swap16IfLE(FileDTH.dth_Pad);
531 FileDTH.dth_Flags = Swap16IfLE(FileDTH.dth_Flags);
532 FileDTH.dth_Priority = Swap16IfLE(FileDTH.dth_Priority);
534 if(WriteChunkData(IH, (char *) &FileDTH, sizeof(struct FileDataTypeHeader))<=0)
536 EndChunk(IH);
537 CloseIFF(IH);
538 remove(TheDTDesc->Name);
539 return(FALSE);
542 if(WriteChunkData(IH, TheDTDesc->DTH.dth_Name, (strlen(TheDTDesc->DTH.dth_Name)+1))<=0)
544 EndChunk(IH);
545 CloseIFF(IH);
546 remove(TheDTDesc->Name);
547 return(FALSE);
550 if(WriteChunkData(IH, TheDTDesc->DTH.dth_BaseName, (strlen(TheDTDesc->DTH.dth_BaseName)+1))<=0)
552 EndChunk(IH);
553 CloseIFF(IH);
554 remove(TheDTDesc->Name);
555 return(FALSE);
558 if(WriteChunkData(IH, TheDTDesc->DTH.dth_Pattern, (strlen(TheDTDesc->DTH.dth_Pattern)+1))<=0)
560 EndChunk(IH);
561 CloseIFF(IH);
562 remove(TheDTDesc->Name);
563 return(FALSE);
566 for(i=0; i<TheDTDesc->DTH.dth_MaskLen; i++)
568 TheDTDesc->DTH.dth_Mask[i]=Swap16IfLE(TheDTDesc->DTH.dth_Mask[i]);
571 if (TheDTDesc->DTH.dth_MaskLen)
573 if(WriteChunkData(IH, (char *) TheDTDesc->DTH.dth_Mask, TheDTDesc->DTH.dth_MaskLen*sizeof(uint16_t))<=0)
575 EndChunk(IH);
576 CloseIFF(IH);
577 remove(TheDTDesc->Name);
578 return(FALSE);
582 EndChunk(IH);
584 CloseIFF(IH);
586 return(TRUE);
589 int Init(int argc, char **argv, struct DTDesc **TheDTDesc)
591 struct DTDesc *NewDTDesc;
593 if(!(argv && TheDTDesc))
595 return(FALSE);
598 *TheDTDesc=NULL;
600 NewDTDesc=(struct DTDesc *) malloc(sizeof(struct DTDesc));
601 if(!NewDTDesc)
603 return(FALSE);
606 *TheDTDesc=NewDTDesc;
608 memset(NewDTDesc, '\0', sizeof(struct DTDesc));
610 NewDTDesc->ProgName=argv[0];
611 NewDTDesc->Input=stdin;
612 NewDTDesc->OutputName=NewDTDesc->Name;
614 if(!ParseArgs(argc, argv, NewDTDesc))
616 return(FALSE);
619 if(!OpenInput(NewDTDesc))
621 return(FALSE);
624 return(TRUE);
627 int OpenInput(struct DTDesc *TheDTDesc)
630 if(!TheDTDesc)
632 return(FALSE);
635 if(TheDTDesc->InputName)
637 TheDTDesc->Input=fopen(TheDTDesc->InputName, "r");
638 if(!TheDTDesc->Input)
640 TheDTDesc->Input=stdin;
642 return(FALSE);
646 return(TRUE);
649 int ParseArgs(int argc, char **argv, struct DTDesc *TheDTDesc)
651 int i;
653 if(!(argv && TheDTDesc))
655 return(FALSE);
658 for(i=1; i<argc; i++)
660 if(strcmp(argv[i], "-o") == 0)
662 if(++i >= argc)
664 Usage(TheDTDesc->ProgName);
666 return(FALSE);
669 TheDTDesc->OutputName=argv[i];
671 else
673 if(strcmp(argv[i], "-h") == 0)
675 Usage(TheDTDesc->ProgName);
677 return(FALSE);
679 else
681 TheDTDesc->InputName=argv[i];
686 return(TRUE);
689 void Usage(char *ProgName)
691 char DefaultName[]="createdtdesc";
692 char *NamePtr;
694 NamePtr = ProgName ? ProgName : DefaultName;
696 fprintf(stderr, "\n"
697 "usage: %s [-o <Output-Name>] <Input-Name>\n"
698 "\n",
699 NamePtr);
702 void Cleanup(struct DTDesc *TheDTDesc)
704 if(TheDTDesc)
706 if((TheDTDesc->Input!=NULL) && (TheDTDesc->Input!=stdin))
708 fclose(TheDTDesc->Input);
711 free((void *) TheDTDesc);