2 /*****************************************************************
4 ** If you use GoldED or any other text editor featuring folding **
5 ** you may want to set up "///" as fold opening phrase, and **
6 ** "//|" as closing one, as this source is using it. **
10 *****************************************************************/
20 FlexCat.c: The flexible catalog creator
22 This program is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
26 Ok, this is nothing special. It grabs a catalog translation and a
27 catalog description file and produces catalogs and the source to
28 handle them. What is it else than lots of other programs?
30 The difference is, that YOU determine what source FlexCat produces.
31 Another file is scanned by FlexCat to produce code. This file contains
32 some c-string like special characters (%v for version for example)
33 You can edit this file and modify it as you want. So FlexCat can produce
34 C source as well as Assembler, Oberon, Modula 2, E, ...
41 #define VERS "FlexCat 2.4"
46 #define _CPU "[68060]"
49 #define _CPU "[68040]"
52 #define _CPU "[68030]"
55 #define _CPU "[68020]"
58 #define _CPU "[68010]"
60 #define _CPU "[680x0]"
67 #define VSTRING VERS " " _CPU " " __AMIGADATE__
72 #define VERSTAG "$VER: " VSTRING
74 /// Includes and defines
85 #include "flexcat_cat.h"
87 #if ((defined(_DCC) && defined(AMIGA)) || \
88 (defined(__SASC) && defined(_AMIGA))) && \
93 #if defined(__amigados)
94 #include <exec/types.h>
95 #if defined(_DCC) || defined(__SASC) || defined(__GNUC__)
96 #include <proto/exec.h>
97 #include <proto/dos.h>
98 #include <proto/intuition.h>
99 #include <proto/utility.h>
101 #include <clib/exec_protos.h>
102 #include <clib/dos_protos.h>
103 #include <clib/utility_protos.h>
109 #define tolower ToLower
110 #define stricmp(s,t) Stricmp((char *) (s), (char *) (t))
111 #define strnicmp(s,t,l) Strnicmp((char *) (s), (char *) (t), l)
120 #define TRUE (!FALSE)
124 #define MAXPATHLEN 512
125 #define FLEXCAT_SDDIR "FLEXCAT_SDDIR"
126 #if defined(__amigados)
127 #define DEFAULT_FLEXCAT_SDDIR "PROGDIR:lib"
129 #define DEFAULT_FLEXCAT_SDDIR "lib"
132 #if defined(__amigados)
133 #define MAX_PREFS_LEN 512
134 #define FLEXCAT_PREFS "flexcat.prefs"
135 char prefs_sddir
[MAXPATHLEN
] = "\0";
140 #define MAKE_ID(a,b,c,d) \
141 ((ULONG) (a)<<24 | (ULONG) (b)<<16 | (ULONG) (c)<<8 | (ULONG) (d))
145 #define ULONG unsigned int
152 TYPE_C
, /* Produce C strings */
153 TYPE_ASSEMBLER
, /* Produce Assembler strings */
154 TYPE_OBERON
, /* Produce Oberon strings */
155 TYPE_E
, /* Produce E strings. (Oops, thought */
156 /* it allows only 32 bit integers? ;-) */
157 TYPE_NONE
/* Simple strings */
162 OutputMode_None
, /* Nothing written yet */
163 OutputMode_Bin
, /* Last character written was binary */
164 OutputMode_Ascii
/* Last character written was Ascii */
168 { struct CatString
*Next
;
172 int MinLen
, MaxLen
, ID
, Nr
;
173 int NotInCT
; /* If string is not present we write NEW */
174 /* while updating CT file, for easier work. */
179 { struct CDLine
*Next
;
184 { struct CatalogChunk
*Next
; /* struct CatalogChunk *Next */
189 struct CatString
*FirstCatString
= NULL
; /* First catalog string */
190 struct CDLine
*FirstCDLine
= NULL
; /* First catalog description line */
191 struct CatalogChunk
*FirstChunk
= NULL
; /* List of catalog chunks */
193 char *BaseName
= ""; /* Basename of catalog description */
194 char *Language
= "english"; /* Language of catalog description */
195 int CatVersion
= 0; /* Version of catalog to be opened */
196 int LengthBytes
= 0; /* Number of bytes to preceed a */
197 /* created string and containing */
199 char *CatLanguage
= NULL
; /* Language of catalog translation */
200 char *CatVersionString
= NULL
; /* version string of catalog */
201 /* translation (## version) */
202 char *CatRcsId
= NULL
; /* rcs ID of catalog translation */
204 char *CatName
= NULL
; /* name of catalog translation */
205 int CodeSet
= 0; /* Codeset of catalog translation */
206 int NumStrings
= 0; /* Number of catalog strings */
207 int LongStrings
= TRUE
; /* Generate long or short strings */
209 char *ScanFile
; /* File currently scanned */
210 int ScanLine
; /* Line currently scanned */
212 int GlobalReturnCode
= 0; /* Will be 5, if warnings appear */
213 int WarnCTGaps
= FALSE
; /* Warn missing symbols in CT */
215 int NoOptim
= FALSE
; /* Put string into catalog even */
216 /* if translation is equal to */
218 int Fill
= FALSE
; /* It translation of given string */
219 /* is missing or it's empty, write */
220 /* string descriptor from #?.cd */
222 int DoExpunge
= FALSE
; /* If TRUE FlexCat will do AVAIL */
223 /* FLUSH alike after catalog save */
224 int NoBeep
= FALSE
; /* if TRUE, FlexCat won't call */
225 /* DisplayBeep() any longer */
226 int Quiet
= FALSE
; /* Forces FlexCat to shut up */
228 int NumberOfWarnings
= 0; /* We count warnings to be smart */
229 /* and not to do Beep bombing, but */
230 /* call DisplayBeep() only once */
231 int CT_Scanned
= FALSE
; /* If TRUE, and we are going to */
232 /* write new #?.ct file, then user */
233 /* surely updates own #?.ct file */
234 /* so we should write ***NEW*** */
235 /* whenever necessary. */
236 int LANGToLower
= TRUE
; /* Shall we do ToLower() on lang's */
237 /* name? Some #?.language seems to */
238 /* be broken, so we allow workaround */
239 int NoBufferedIO
= FALSE
; /* Shall we do buffered IO */
240 int buffer_size
= 2048; /* Size of the IO buffer */
241 int Modified
= FALSE
; /* Shall we write the catalog ONLY */
242 /* if #?.catalog is younger than */
243 /* #?.c(d|t) files? */
245 #define MAX_NEW_STR_LEN 25
246 char Msg_New
[MAX_NEW_STR_LEN
] = "***NEW***";
247 /* new strings in updated #?.ct */
249 int CopyNEWs
= FALSE
;
250 char Old_Msg_New
[MAX_NEW_STR_LEN
] = "; ***NEW***";
252 /* old newstring (above) used in old */
253 /* CT file. Now we look if it's present */
254 /* and copy it into new CT if user does */
255 /* upgrade (flexcat CD CT newctfile CT */
257 int NoSpace
= FALSE
; /* do want to strip the space usually */
258 /* placed between ';' and original */
262 char VersTag
[] = VERSTAG
;
263 char VString
[] = VSTRING
" by Jochen Wiedmann and Marcin Orlowski";
264 char EString
[] = "E-mail: carlos@amiga.com.pl WWW: http://amiga.com.pl/flexcat/";
268 #if defined(__amigados)
290 char template[] = "SDDIR/K,MSG_NEW/K,WARNCTGAPS/S,NOOPTIM/S,FILL/S,FLUSH/S,NOBEEP/S,QUIET/S,NOLANGTOLOWER/S,NOBUFFEREDIO/S,MODIFIED/S,COPYMSGNEW/S,OLDMSGNEW/K,NOSPACE/S";
291 LONG Results
[ARGS_COUNT
] = {0};
295 struct RDArgs
*rdargs
;
297 if(prefs
= getenv(FLEXCAT_PREFS
))
299 prefs
= realloc(prefs
, strlen(prefs
)+1);
302 if(rda
= AllocDosObject(DOS_RDARGS
, TAG_DONE
))
304 rda
->RDA_Source
.CS_Buffer
= prefs
;
305 rda
->RDA_Source
.CS_Length
= strlen(prefs
);
306 rda
->RDA_Source
.CS_CurChr
= 0;
307 rda
->RDA_Flags
|= RDAF_NOPROMPT
;
309 if(rdargs
= ReadArgs(template, Results
, rda
))
312 strncpy(prefs_sddir
, (char *)Results
[SDDIR
], MAXPATHLEN
);
315 strncpy(Msg_New
, (char *)Results
[MSG_NEW
], MAX_NEW_STR_LEN
);
317 WarnCTGaps
= Results
[WARNCTGAPS
];
318 NoOptim
= Results
[NOOPTIM
];
319 Fill
= Results
[FILL
];
320 DoExpunge
= Results
[FLUSH
];
321 NoBeep
= Results
[NOBEEP
];
322 Quiet
= Results
[QUIET
];
323 LANGToLower
= Results
[NOLANGTOLOWER
];
324 Modified
= Results
[MODIFIED
];
325 NoBufferedIO
= Results
[NOBUFFEREDIO
];
326 CopyNEWs
= Results
[COPYMSGNEW
];
327 NoSpace
= Results
[NOSPACE
];
328 if(Results
[OLDMSGNEW
])
329 sprintf(Old_Msg_New
, "; %s", (char *)Results
[OLDMSGNEW
]);
337 fputs((char *)msgPrefsError
, stderr
);
338 fputs((char *)template, stderr
);
339 fputs((char *)"\n", stderr
);
343 FreeDosObject(DOS_RDARGS
, rda
);
347 fputs("Error processing prefs.\nCan't AllocDosObject()\n", stderr
);
360 void MyExit (int Code
)
363 #if defined(__amigados)
365 if(((NumberOfWarnings
> 0) ||(Code
!=0)) && (!NoBeep
))
372 //STATIC __autoexit VOID _STDCloseFlexCatCatalog(VOID)
373 #elif defined(__SASC)
374 //VOID _STDCloseFlexCatCatalog(VOID)
375 #elif defined(__GNUC__)
376 //STATIC VOID _STDCloseFlexCatCatalog(VOID)
377 #elif defined(__INTEL_COMPILER)
378 //STATIC VOID _STDCloseFlexCatCatalog(VOID)
380 CloseFlexCatCatalog(); /* we need to close something... */
392 #if !defined(__amigados) && !defined(__CYGWIN32__)
393 # define stricmp strcasecmp
397 int stricmp( const char *str1
, const char *str2
)
403 int a
= tolower( (int)*str1
);
404 int b
= tolower( (int)*str2
);
425 #if !defined(__amigados) && !defined(__CYGWIN32__)
426 int strnicmp( const char *str1
, const char *str2
, size_t len
)
430 for(i
= 0; i
< len
; i
++)
432 int a
= tolower( (int)*str1
);
433 int b
= tolower( (int)*str2
);
451 /// FUNC: Swappers...
454 unsigned short (*SwapWord
)(unsigned short r
) = NULL
;
455 unsigned long (*SwapLong
)(unsigned long r
) = NULL
;
458 unsigned short SwapWord21(unsigned short r
)
460 return (unsigned short)((r
>>8) + (r
<<8));
462 unsigned short SwapWord12(unsigned short r
)
466 unsigned long SwapLong4321(unsigned long r
)
468 return ((r
>>24) & 0xFF) + (r
<<24) + ((r
>>8) & 0xFF00) + ((r
<<8) & 0xFF0000);
470 unsigned long SwapLong1234(unsigned long r
)
482 strncpy((char *)&w
, "\1\2", 2);
483 strncpy((char *)&d
, "\1\2\3\4", 4);
486 SwapWord
= SwapWord21
;
487 else if (w
== 0x0102)
488 SwapWord
= SwapWord12
;
493 SwapLong
= SwapLong4321
;
494 else if (d
== 0x01020304)
495 SwapLong
= SwapLong1234
;
506 This shows an error message and terminates
508 void ShowError(const char *msg
, ...)
515 vfprintf(stderr
, msg
, ptr
);
520 #if defined(__amigados)
530 This shows the message: Memory error.
535 ShowError(msgMemoryError
, NULL
);
543 void ShowWarn(const char *msg
, ...)
550 fprintf(stderr
, (char *) msgWarning
, ScanFile
, ScanLine
);
551 #warning the following line produces segfault on x86_64
552 vfprintf(stderr
, msg
, ptr
);
558 GlobalReturnCode
= 5;
561 /// FUNC: AllocString
564 This allocates a string
566 char *AllocString(const char *str
)
570 if (!(ptr
= malloc(strlen(str
)+1)))
577 /// FUNC: Add catalog chunk
580 This adds a new catalog chunk to the list of catalog
583 char *AddCatalogChunk(char *ID
, const char *string
)
585 struct CatalogChunk
*cc
, **ccptr
;
587 if (!(cc
= malloc(sizeof(*cc
))))
591 cc
->ID
= *((ULONG
*) ID
);
592 cc
->ChunkStr
= AllocString(string
);
595 Put the new chunk to the end of the chunk list.
597 for (ccptr
= &FirstChunk
; *ccptr
!= NULL
; ccptr
= &(*ccptr
)->Next
)
601 return(cc
->ChunkStr
);
606 This translates a hex character.
610 if (c
>= '0' && c
<= '9')
613 else if (c
>= 'a' && c
<= 'f')
614 { return(c
- 'a' + 10);
616 else if (c
>= 'A' && c
<= 'F')
617 { return(c
- 'A' + 10);
619 ShowWarn(msgExpectedHex
);
626 This translates an octal digit.
631 if (c
>= '0' && c
<= '7')
636 ShowWarn(msgExpectedOctal
);
644 Reading a line is somewhat complicated in order to allow lines of any
647 Inputs: fp - the file, where the input comes from
648 AllowComment - TRUE, if a leading semicolon should force to
649 interpret the line as a comment line
652 char *ReadLine(FILE *fp
, int AllowComment
)
655 char *OldLine
, *NewLine
= NULL
;
657 int Len
= 0, LineLen
= 0;
658 int FirstChar
= TRUE
;
659 int BackslashSeen
= FALSE
;
660 int BackslashSeenOn
= 0; /* position the last backslash was seen on */
661 int CommentLine
= FALSE
; /* if TRUE we should ignore normally treat trailing \'s */
668 if(!(NewLine
= malloc(LineLen
+BUFSIZE
)))
671 strncpy(NewLine
, OldLine
, LineLen
);
706 BackslashSeen
= FALSE
;
714 /* Let's check for trailing \\ */
721 if(BackslashSeenOn
== (Len
-1))
723 BackslashSeen
= FALSE
;
729 BackslashSeen
= TRUE
;
730 BackslashSeenOn
= Len
;
739 BackslashSeen
= FALSE
;
753 This removes trailing blanks.
755 void OverSpace(char **strptr
)
759 while ((c
= **strptr
) == ' ' || c
== '\t')
769 #if defined(__amigados)
774 #ifdef __EXPUNGE_ALL__
777 if(Memory
= AllocMem(-1, NULL
))
778 FreeMem(Memory
, -1); // just in case ;-)
781 #pragma libcall LocaleBase localeExpunge 12 00
782 VOID
localeExpunge(VOID
);
784 struct Library
*LocaleBase
;
786 if(LocaleBase
= OpenLibrary("locale.library", 0))
789 CloseLibrary(LocaleBase
);
803 ReadChar scans an input line translating the backslash characters.
805 Inputs: char * - a pointer to a stringpointer; the latter points to the
806 next character to be read and points behind the read
807 bytes after executing ReadChar
808 dest - a pointer to a buffer, where the read bytes should be
811 Result: number of bytes that are written to dest (between 0 and 2)
813 int ReadChar(char **strptr
, char *dest
)
818 switch(c
= *((*strptr
)++))
822 switch(c
= tolower((int) *((*strptr
)++)))
854 *dest
= gethex((int) **strptr
);
856 if (((c
= **strptr
) >= '0' && c
<= '9') ||
857 (c
>= 'a' && c
<= 'f') || (c
>= 'A' && c
<= 'F'))
858 { *dest
= (*dest
<< 4) + gethex((int) c
);
871 *dest
= getoctal((int)c
);
873 for(i
= 0; i
< 2; i
++)
875 if((c
= **strptr
) >= '0' && c
<= '7')
877 *dest
= (*dest
<< 3) + getoctal((int) c
);
901 This scans the catalog description file.
903 Inputs: cdfile - name of the catalog description file
905 Result: TRUE, if successful, FALSE otherwise
907 int ScanCDFile(char *cdfile
)
910 struct CDLine
*cdline
, **cdptr
= &FirstCDLine
;
911 struct CatString
*cs
, **csptr
= &FirstCatString
;
912 char *line
, *newline
;
920 if(!(fp
= fopen(cdfile
, "r")))
922 ShowError(msgNoCatalogDescription
, cdfile
);
926 setvbuf(fp
, NULL
, _IOFBF
, buffer_size
);
931 if ((ptr
= strchr(cdfile
, ':')))
934 if ((ptr
= strrchr(cdfile
, '/')))
937 if ((ptr
= strrchr(cdfile
, '.')))
941 { len
= strlen(cdfile
);
943 if (!(BaseName
= malloc(len
+1)))
946 strncpy(BaseName
, cdfile
, len
);
947 BaseName
[len
] = '\0';
949 while(!feof(fp
) && (line
= newline
= ReadLine(fp
, TRUE
)))
951 if(!(cdline
= malloc(sizeof(*cdline
))))
957 cdptr
= &cdline
->Next
;
959 cdline
->Line
= line
= AllocString(newline
);
969 int CheckExtra
= TRUE
;
971 if (strnicmp(line
+1, "language", 8) == 0)
977 Language
= AllocString(line
);
981 for (ptr
= Language
; *ptr
; ptr
++)
983 *ptr
= tolower((int) *ptr
);
990 if(strnicmp(line
+1, "version", 7) == 0)
992 CatVersion
= strtol(line
+8, &line
, 0);
996 if(strnicmp(line
+1, "basename", 8) == 0)
1001 BaseName
= AllocString(line
);
1006 ShowWarn(msgUnknownCDCommand
);
1017 ShowWarn(msgExtraCharacters
);
1026 if(*line
== ' ' || *line
== '\t')
1028 ShowWarn(msgUnexpectedBlanks
);
1034 while ((*line
>= 'a' && *line
<= 'z') ||
1035 (*line
>= 'A' && *line
<= 'Z') ||
1036 (*line
>= '0' && *line
<= '9') ||
1044 ShowWarn(msgNoIdentifier
);
1051 if(!(cs
= malloc(sizeof(*cs
))))
1058 struct CatString
*scs
;
1061 for(scs
= FirstCatString
; scs
!= NULL
; scs
= scs
->Next
)
1063 if(scs
->ID
== NextID
)
1081 if(!(cs
->ID_Str
= malloc((line
-idstr
)+1)))
1085 strncpy(cs
->ID_Str
, idstr
, line
-idstr
);
1086 cs
->ID_Str
[line
-idstr
] = '\0';
1092 ShowWarn(msgNoLeadingBracket
);
1098 struct CatString
*scs
;
1100 int bytesread
, reallen
;
1108 NextID
= cs
->ID
= NextID
+ strtol(line
, &line
, 0);
1112 cs
->ID
= NextID
= strtol(line
, &line
, 0);
1118 for(scs
= FirstCatString
; scs
!= NULL
; scs
= scs
->Next
)
1119 { if (scs
->ID
== cs
->ID
)
1120 { ShowWarn(msgDoubleID
);
1123 if (strcmp(cs
->ID_Str
, scs
->ID_Str
) == 0)
1124 { ShowWarn(msgDoubleIdentifier
);
1130 { ShowWarn(msgNoMinLen
);
1137 { cs
->MinLen
= strtol(line
, &line
, 0);
1141 { ShowWarn(msgNoMaxLen
);
1148 { cs
->MaxLen
= strtol(line
, &line
, 0);
1152 { ShowWarn(msgNoTrailingBracket
);
1159 { ShowWarn(msgExtraCharacters
);
1164 if (!(newline
= ReadLine(fp
, FALSE
)))
1165 { ShowWarn(msgNoString
);
1170 { cs
->CD_Str
= AllocString(newline
);
1177 oldstr
= cs
->CD_Str
;
1180 { bytesread
= ReadChar(&oldstr
, bytes
);
1184 reallen
+= bytesread
;
1187 if (cs
->MinLen
> 0 && reallen
< cs
->MinLen
)
1188 { ShowWarn(msgShortString
);
1190 if (cs
->MaxLen
> 0 && reallen
> cs
->MaxLen
)
1191 { ShowWarn(msgLongString
);
1194 cs
->Nr
= NumStrings
;
1207 /// FUNC: ScanCTFile
1210 This scans a catalog translation file.
1212 Inputs: ctfile - name of the translation file to scan.
1214 Result: TRUE, if successful, FALSE otherwise.
1216 int ScanCTFile(char *ctfile
)
1219 char *newline
, *line
, *idstr
, *newidstr
, *newstr
;
1220 struct CatString
*cs
=NULL
;
1226 if (!(fp
= fopen(ctfile
, "r")))
1228 ShowError(msgNoCatalogTranslation
, ctfile
);
1232 setvbuf(fp
, NULL
, _IOFBF
, buffer_size
);
1235 while (!feof(fp
) && (line
= newline
= ReadLine(fp
, TRUE
)))
1240 if( CopyNEWs
== TRUE
)
1242 if(strnicmp( line
, Old_Msg_New
, strlen(Old_Msg_New
) ) == 0)
1250 /// looking for command;
1251 if(*(++line
) != '#')
1253 ShowWarn(msgNoCTCommand
);
1257 if (strnicmp(line
, "version", 7) == 0)
1258 { if (CatVersionString
|| CatRcsId
|| CatName
)
1259 { ShowWarn(msgDoubleCTVersion
);
1263 CatVersionString
= AllocString(line
);
1265 else if (strnicmp(line
, "codeset", 7) == 0)
1267 CodeSet
= strtol(line
, &line
, 0);
1270 { ShowWarn(msgExtraCharacters
);
1273 else if (strnicmp(line
, "language", 8) == 0)
1277 { ShowWarn(msgDoubleCTLanguage
);
1281 CatLanguage
= AddCatalogChunk("LANG", line
);
1284 for (ptr
= CatLanguage
; *ptr
; ptr
++)
1285 *ptr
= tolower((int) *ptr
);
1287 else if (strnicmp(line
, "chunk", 5) == 0)
1293 line
+= sizeof(ULONG
);
1296 AddCatalogChunk(ID
, AllocString(line
));
1298 else if (strnicmp(line
, "rcsid", 5) == 0)
1299 { if (CatVersionString
|| CatRcsId
)
1300 { ShowWarn(msgDoubleCTVersion
);
1304 CatRcsId
= AllocString(line
);
1306 else if (strnicmp(line
, "name", 5) == 0)
1307 { if (CatVersionString
|| CatName
)
1308 { ShowWarn(msgDoubleCTVersion
);
1312 CatName
= AllocString(line
);
1314 else if (strnicmp(line
+1, "lengthbytes", 11) == 0)
1316 if ((LengthBytes
= strtol(line
, &line
, 0))
1318 { ShowWarn(msgNoLengthBytes
, sizeof(long));
1319 LengthBytes
= sizeof(long);
1324 ShowWarn(msgUnknownCTCommand
);
1330 if(*line
== ' ' || *line
== '\t')
1332 ShowWarn( msgUnexpectedBlanks
);
1337 while ((*line
>= 'a' && *line
<= 'z') ||
1338 (*line
>= 'A' && *line
<= 'Z') ||
1339 (*line
>= '0' && *line
<= '9') ||
1345 ShowWarn(msgNoIdentifier
);
1349 if(!(newidstr
= malloc(line
-idstr
+1)))
1354 strncpy(newidstr
, idstr
, line
-idstr
);
1355 newidstr
[line
-idstr
] = '\0';
1360 ShowWarn(msgExtraCharacters
);
1363 if((newstr
= ReadLine(fp
, FALSE
)))
1365 for(cs
= FirstCatString
; cs
!= NULL
; cs
= cs
->Next
)
1367 if(strcmp(cs
->ID_Str
, newidstr
) == 0)
1374 ShowWarn(msgUnknownIdentifier
, newidstr
);
1380 int bytesread
, reallen
;
1384 ShowWarn(msgDoubleIdentifier
);
1388 cs
->CT_Str
= AllocString(newstr
);
1389 cs
->NotInCT
= FALSE
;
1394 oldstr
= cs
->CT_Str
;
1398 bytesread
= ReadChar(&oldstr
, bytes
);
1403 reallen
+= bytesread
;
1406 if(cs
->MinLen
> 0 && reallen
< cs
->MinLen
)
1408 ShowWarn(msgShortString
);
1410 if(cs
->MaxLen
> 0 && reallen
> cs
->MaxLen
)
1412 ShowWarn(msgLongString
);
1416 // checking for trailing ellipsis...
1420 long cd_len
= strlen( cs
->CD_Str
);
1424 if( strcmp( &cs
->CD_Str
[ cd_len
- 2 ], "..." ) == 0 )
1425 if( strcmp( &cs
->CT_Str
[ reallen
- 2 ], "..." ) != 0 )
1427 // printf("ORG: '%s'\nNEW: '%s'\n", cs->CD_Str, cs->CT_Str);
1428 ShowWarn(msgTrailingEllipsis
);
1434 // checking for trailing spaces
1438 long cd_len
= strlen( cs
->CD_Str
);
1442 if( strcmp( &cs
->CD_Str
[ cd_len
- 1 ], " " ) == 0 )
1443 if( strcmp( &cs
->CT_Str
[ reallen
- 1 ], " " ) != 0 )
1444 ShowWarn(msgTrailingSpaces
);
1454 ShowWarn(msgNoString
);
1466 { for (cs
= FirstCatString
; cs
!= NULL
; cs
= cs
->Next
)
1467 { if (cs
->CT_Str
== NULL
)
1468 { ShowWarn(msgCTGap
, cs
->ID_Str
);
1483 CatPuts prints a string to a catalog. (The string is preceded by a
1484 long integer containing its length and probably padded up to word
1485 boundary or longword boundary, depending on the argument padbytes.)
1486 The arguments countnul should be TRUE if the NUL byte at the end of
1487 the string should be counted.
1489 int CatPuts(FILE *fp
, char *str
, int padbytes
, int countnul
)
1491 unsigned int reallen
, virtuallen
, chunklen
, swapped_long
;
1496 /* Get Length of string.
1504 bytesread
= ReadChar(&oldstr
, bytes
);
1509 reallen
+= bytesread
;
1512 virtuallen
= chunklen
= reallen
+ LengthBytes
;
1513 if(countnul
|| chunklen
% padbytes
== 0)
1518 swapped_long
= SwapLong( virtuallen
);
1520 fwrite(&swapped_long
, sizeof(virtuallen
), 1, fp
);
1523 fwrite(((char *) &reallen
)+sizeof(reallen
)-LengthBytes
, LengthBytes
, 1, fp
);
1528 bytesread
= ReadChar(&str
, bytes
);
1531 fwrite(bytes
+bytesread
-1, 1, 1, fp
);
1539 while(++chunklen
% padbytes
);
1541 return((int) chunklen
+4);
1544 /// FUNC: PutCatalogChunk
1547 This puts a string chunk into the catalog
1549 int PutCatalogChunk(FILE *fp
, struct CatalogChunk
*cc
)
1551 fwrite(&cc
->ID
, sizeof(cc
->ID
), 1, fp
);
1552 return(4 + CatPuts(fp
, cc
->ChunkStr
, 2, TRUE
));
1555 /// FUNC: CalcRealLength
1557 This function measures the real (binary) length of source
1558 string. It correctly process 'slash chars' (\n, \000 etc),
1559 and gives the real length such source string have.
1561 Inputs: source - pointer to null terminated source string
1566 int CalcRealLength(char *source
)
1574 count
+= ReadChar(&src
, bytes
);
1577 // printf("%ld: '%s'\n", count, source);
1584 /// FUNC: CreateCatalog
1587 This creates a catalog.
1589 void CreateCat(char *CatFile
)
1592 int CatLen
, HeadLen
;
1593 struct CatString
*cs
;
1594 struct CatalogChunk
*cc
;
1597 if(!CatVersionString
&& !CatRcsId
)
1599 ShowError(msgNoCTVersion
);
1604 ShowError(msgNoCTLanguage
);
1607 if(strlen(CatLanguage
) == 0)
1609 ShowError(msgNoCTLanguage
);
1612 if(!(fp
= fopen(CatFile
, "w")))
1614 ShowError(msgNoCatalog
, CatFile
);
1618 setvbuf(fp
, NULL
, _IOFBF
, buffer_size
);
1621 fputs("FORM0000CTLG", fp
);
1624 if(CatVersionString
)
1626 struct CatalogChunk cc
;
1627 char *verStr
= NULL
;
1629 cc
.ID
= MAKE_ID('F','V','E','R');
1631 if( strstr(CatVersionString
, "$TODAY") )
1634 if(verStr
= malloc(strlen(CatVersionString
)+128))
1636 char *found
= strstr(CatVersionString
, "$TODAY");
1646 strftime(dateStr
, sizeof(dateStr
), "%d.%m.%y", t
);
1648 sprintf(verStr
, "%s%s%s", CatVersionString
, dateStr
, found
+strlen("$TODAY"));
1649 cc
.ChunkStr
= verStr
;
1657 cc
.ChunkStr
= CatVersionString
;
1660 cc
.ID
= SwapLong( cc
.ID
);
1661 CatLen
+= PutCatalogChunk(fp
, &cc
);
1668 struct CatalogChunk cc
;
1670 int year
= 0, month
= 0, day
= 0;
1671 int version
= 0, revision
= 0;
1677 ShowError(msgNoCTVersion
);
1681 if(!(ptr
= strstr(CatRcsId
, "$Date:"))
1682 || sscanf(ptr
+6, " %d/%d/%d", &year
, &month
, &day
) != 3
1683 || !(ptr
= strstr(CatRcsId
, "$Revision:"))
1684 || sscanf(ptr
+10, " %d.%d", &version
, &revision
) != 2)
1686 ShowError(msgWrongRcsId
);
1688 if ((ptr
= strstr(CatRcsId
, "$Id:")))
1696 while(*ptr
&& *ptr
!= '$' && *ptr
!= ' ' && *ptr
!= '\t')
1701 if(!(name
= malloc(len
+1)))
1705 strncpy(name
, found
, len
);
1714 ShowError(msgNoCTVersion
);
1717 if (!(verStr
= malloc(strlen(name
) + 256)))
1722 sprintf(verStr
, "$V");
1723 sprintf(verStr
, "ER: %s %ld.%ld (%ld.%ld.%ld)", name
, version
, revision
, day
, month
, year
);
1725 cc
.ID
= MAKE_ID('F','V','E','R');
1726 cc
.ID
= SwapLong( cc
.ID
);
1727 cc
.ChunkStr
= verStr
;
1728 CatLen
+= PutCatalogChunk(fp
, &cc
);
1732 for (cc
= FirstChunk
; cc
!= NULL
; cc
= cc
->Next
)
1734 CatLen
+= PutCatalogChunk(fp
, cc
);
1741 int i_tmp
= SwapLong( i
);
1743 fwrite(&i_tmp
, sizeof(i_tmp
), 1, fp
);
1752 fprintf(fp
, "STRS0000");
1756 for(cs
= FirstCatString
; cs
!= NULL
; cs
= cs
->Next
)
1758 int FillUsed
= FALSE
;
1759 int tmp_ID
= SwapLong( cs
->ID
);
1766 if(strlen(cs
->CT_Str
) == 0)
1768 fwrite(&tmp_ID
, sizeof(tmp_ID
), 1, fp
);
1769 CatLen
+= 4 + CatPuts(fp
, cs
->CD_Str
, 4, FALSE
);
1775 fwrite(&tmp_ID
, sizeof(cs
->ID
), 1, fp
);
1776 CatLen
+= 4 + CatPuts(fp
, cs
->CD_Str
, 4, FALSE
);
1781 if((!FillUsed
) && cs
->CT_Str
&& (NoOptim
? TRUE
: strcmp(cs
->CT_Str
, cs
->CD_Str
)))
1783 fwrite(&tmp_ID
, sizeof( tmp_ID
), 1, fp
);
1784 CatLen
+= 4 + CatPuts(fp
, cs
->CT_Str
, 4, FALSE
);
1792 fseek(fp
, 4, SEEK_SET
);
1794 tmp_Len
= SwapLong( CatLen
);
1795 fwrite(&tmp_Len
, sizeof(tmp_Len
), 1, fp
);
1796 fseek(fp
, HeadLen
-4, SEEK_CUR
);
1799 tmp_Len
= SwapLong( CatLen
);
1800 fwrite(&tmp_Len
, sizeof(CatLen
), 1, fp
);
1809 /// FUNC: CreateCTFile
1812 This creates a new catalog translation file.
1814 void CreateCTFile(char *NewCTFile
)
1818 struct CatString
*cs
;
1819 struct CatalogChunk
*cc
;
1822 if(!CatVersionString
&& !CatRcsId
)
1825 ShowWarn(msgNoCTVersion
);
1828 if(!(fp
= fopen(NewCTFile
, "w")))
1830 ShowError(msgNoNewCTFile
);
1835 setvbuf(fp
, NULL
, _IOFBF
, buffer_size
);
1840 fprintf(fp
, "## rcsid %s\n",
1841 CatRcsId
? CatRcsId
: "");
1843 fprintf(fp
, "## name %s\n", CatName
);
1847 if(CatVersionString
)
1848 fprintf(fp
, "## version %s\n", CatVersionString
);
1851 fprintf(fp
, "## version $V");
1852 fprintf(fp
, "%c", 50+19); // E
1853 fprintf(fp
, "R: XX.catalog XX.XX ($TODAY)\n");
1861 if(CatLanguage
== NULL
)
1862 if(lang
= getenv("ENV:language"))
1866 for(i
=0;i
<strlen(lang
); i
++)
1876 fprintf(fp
, "## language %s\n## codeset %d\n;\n",
1877 CatLanguage
? CatLanguage
: "X", CodeSet
);
1888 for (cc
= FirstChunk
; cc
!= NULL
; cc
= cc
->Next
)
1890 if (cc
->ChunkStr
!= CatLanguage
)
1892 fprintf(fp
, "## chunk ");
1893 fwrite((char *) &cc
->ID
, sizeof(cc
->ID
), 1, fp
);
1894 fprintf(fp
, " %s\n", cc
->ChunkStr
);
1898 for(cd
= FirstCDLine
, cs
= FirstCatString
;
1908 fprintf(fp
, "%s\n", cd
->Line
);
1915 fprintf(fp, "%s\n", cs->ID_Str);
1916 fprintf(fp, "%s\n", cs->CT_Str ? cs->CT_Str : "");
1920 fprintf(fp
, "%s\n%s\n;", cs
->ID_Str
, cs
->CT_Str
? cs
->CT_Str
: "");
1927 for (line
= cs
->CD_Str
; *line
; ++line
)
1929 putc((int) *line
, fp
);
1939 if(cs
->NotInCT
&& CT_Scanned
)
1940 fprintf(fp
, ";\n; %s\n", Msg_New
);
1951 /// FUNC: InitCatStringOutput
1954 InitCatStringOutput gets called before writing a catalog string as
1957 Inputs: fp = file pointer to the output file
1958 type = one of TYPE_C create C strings
1959 TYPE_ASSEMBLER create Assembler strings
1960 TYPE_OBERON create Oberon strings
1961 TYPE_E create E strings
1962 TYPE_NONE create simple strings
1964 int OutputMode
= OutputMode_None
;
1965 int OutputType
= TYPE_C
;
1969 void InitCatStringOutput(FILE *fp
)
1973 OutputMode
= OutputMode_None
;
1978 OutputMode
= OutputMode_Ascii
;
1982 case TYPE_ASSEMBLER
:
1988 /// FUNC: SeparateCatStringOutput
1991 SeparateCatStringOutput gets called to split a catalog into separate
1994 void SeparateCatStringOutput(void)
1999 { fputs("\"\\\n\t\"", OutputFile
);
2004 { fputs("\' +\n\t\'", OutputFile
);
2009 { fputs("\"\n\t\"", OutputFile
);
2012 case TYPE_ASSEMBLER
:
2014 { if (OutputMode
== OutputMode_Ascii
)
2015 { putc('\'', OutputFile
);
2017 putc('\n', OutputFile
);
2018 OutputMode
= OutputMode_None
;
2026 /// FUNC: WriteBinChar
2029 WriteBinChar writes one binary character into the source file
2031 void WriteBinChar(int c
)
2040 fputs("\\b", OutputFile
);
2043 fputs("\\n", OutputFile
);
2046 fputs("\\r", OutputFile
);
2049 fputs("\\t", OutputFile
);
2052 fputs("\\f", OutputFile
);
2055 fputs("\\000", OutputFile
);
2058 if(OutputType
== TYPE_E
&& c
== '\033')
2060 fputs("\\e", OutputFile
);
2064 fprintf(OutputFile
, "\\%c%c%c", ((c
>> 6) & 3) + '0',
2065 ((c
>> 3) & 7) + '0', (c
& 7) + '0');
2070 OutputMode
= OutputMode_Bin
;
2072 case TYPE_ASSEMBLER
:
2074 { case OutputMode_None
:
2075 fprintf(OutputFile
, "\tdc.b\t$%02x", c
& 0xff);
2077 case OutputMode_Ascii
:
2078 putc('\'', OutputFile
);
2079 case OutputMode_Bin
:
2080 fprintf(OutputFile
, ",$%02x", c
& 0xff);
2084 OutputMode
= OutputMode_Bin
;
2087 ShowWarn(msgNoBinChars
);
2092 /// FUNC: WriteAsciiChar
2095 WriteAsciiChar writes one ascii character into the source file.
2097 void WriteAsciiChar(int c
)
2105 fputs("\\\"", OutputFile
);
2108 putc(c
, OutputFile
);
2112 OutputMode
= OutputMode_Ascii
;
2117 fputs("''", OutputFile
);
2120 putc(c
, OutputFile
);
2124 OutputMode
= OutputMode_Ascii
;
2126 case TYPE_ASSEMBLER
:
2131 { switch (OutputMode
)
2132 { case OutputMode_None
:
2133 fprintf(OutputFile
, "\tdc.b\t\'%c", c
);
2135 case OutputMode_Ascii
:
2136 putc(c
, OutputFile
);
2138 case OutputMode_Bin
:
2139 fprintf(OutputFile
, ",\'%c", c
);
2143 OutputMode
= OutputMode_Ascii
;
2147 putc(c
, OutputFile
);
2152 /// FUNC: TerminateCatStringOutput
2155 TerminateCatStringOutput finishs the output of a catalog string.
2157 void TerminateCatStringOutput(void)
2162 putc('\"', OutputFile
);
2165 putc('\'', OutputFile
);
2167 case TYPE_ASSEMBLER
:
2169 { case OutputMode_Ascii
:
2170 putc('\'', OutputFile
);
2171 case OutputMode_Bin
:
2173 case OutputMode_None
:
2182 /// FUNC: WriteString
2184 This writes a sourcestring.
2186 void WriteString(FILE *fpout
, char *str
, long Len
)
2190 int needseparate
= FALSE
;
2192 InitCatStringOutput(fpout
);
2196 for(i
= LengthBytes
; i
>= 1; i
--)
2197 { WriteBinChar((int) ((char *) &Len
)[sizeof(Len
)-i
]);
2202 { bytesread
= ReadChar(&str
, bytes
);
2207 { SeparateCatStringOutput();
2208 needseparate
= FALSE
;
2211 c
= bytes
[bytesread
-1];
2212 if ((c
>= 0x20 && c
< 0x7f) || c
>= 0xa0)
2213 { WriteAsciiChar((int) c
);
2216 { WriteBinChar((int) c
);
2220 { needseparate
= TRUE
;
2223 TerminateCatStringOutput();
2226 /// FUNC: AllocFileName
2228 This function creates a copy of a filename, removes an
2229 optional ending and pathname components, if desired.
2231 Inputs: filename - the filename to copy
2232 howto - a set of bits
2233 bit 0: 1 = remove ending, 0 = leave it
2234 bit 1: 1 = remove pathname, 0 = leave it
2236 Result: The copy of the filename
2238 char *AllocFileName(char *filename
, int howto
)
2240 char *tempstr
, *ptr
;
2242 if (!(tempstr
= strdup(filename
)))
2247 /* Remove pathname components, if desired */
2249 { if ((ptr
= strchr(tempstr
, ':')))
2252 if ((ptr
= strrchr(tempstr
, '/')))
2257 /* Remove ending, if desired. */
2259 { if ((ptr
= strrchr(tempstr
, '.')))
2267 /// FUNC: AddFileName
2269 This function adds a pathname and a filename to a full
2272 Inputs: pathname - the leading pathname
2273 filename - the filename
2275 Result: The new filename
2277 char *AddFileName(char *pathname
, char *filename
)
2280 int size
= strlen(pathname
) + strlen(filename
) + 2;
2282 if (!(buffer
= malloc(size
)))
2287 #if defined(__amigados)
2288 strcpy(buffer
, pathname
);
2289 AddPart((char *) buffer
, (char *) filename
, size
);
2291 sprintf(buffer
, "%s/%s", pathname
, filename
);
2298 /// FUNC: CreateSourceFile
2301 Finally the source creation.
2303 void CreateSourceFile(char *SourceFile
, char *TemplateFile
, char *CDFile
)
2308 char *OrigTemplateFile
= TemplateFile
;
2310 ScanFile
= SourceFile
;
2314 Open the source file. This may be found in various places
2316 if(!(fpin
= fopen(TemplateFile
, "r")))
2319 if(*prefs_sddir
!= 0)
2321 TemplateFile
= AddFileName(prefs_sddir
, OrigTemplateFile
);
2322 fpin
= fopen(TemplateFile
, "r");
2331 if((sddir
= getenv(FLEXCAT_SDDIR
)))
2333 TemplateFile
= AddFileName(sddir
, OrigTemplateFile
);
2334 fpin
= fopen(TemplateFile
, "r");
2339 { TemplateFile
= AddFileName(DEFAULT_FLEXCAT_SDDIR
, OrigTemplateFile
);
2340 fpin
= fopen(TemplateFile
, "r");
2345 ShowError(msgNoSourceDescription
, OrigTemplateFile
);
2349 if (!(fpout
= fopen(SourceFile
, "w")))
2351 ShowError(msgNoSource
, SourceFile
);
2356 setvbuf(fpin
, NULL
, _IOFBF
, buffer_size
);
2358 setvbuf(fpout
, NULL
, _IOFBF
, buffer_size
);
2361 while(!feof(fpin
) && (line
= ReadLine(fpin
, FALSE
)))
2362 { struct CatString
*cs
;
2367 cs
= FirstCatString
;
2369 { char *currentline
= line
;
2372 if (*currentline
== '#' && *(++currentline
) == '#')
2374 OverSpace(¤tline
);
2376 if(strnicmp( currentline
, "rem", 3 ) == 0)
2378 // we just skip this line
2382 if (strnicmp(currentline
, "stringtype", 10) == 0)
2383 { currentline
+= 10;
2384 OverSpace(¤tline
);
2385 if (strnicmp(currentline
, "c", 1) == 0)
2386 { OutputType
= TYPE_C
;
2389 else if (strnicmp(currentline
, "assembler", 9) == 0)
2390 { OutputType
= TYPE_ASSEMBLER
;
2393 else if (strnicmp(currentline
, "oberon", 6) == 0)
2394 { OutputType
= TYPE_OBERON
;
2397 else if (strnicmp(currentline
, "e", 1) == 0)
2398 { OutputType
= TYPE_E
;
2401 else if (strnicmp(currentline
, "none", 4) == 0)
2402 { OutputType
= TYPE_NONE
;
2406 { ShowWarn(msgUnknownStringType
);
2407 currentline
+= strlen(currentline
);
2409 OverSpace(¤tline
);
2411 { ShowWarn(msgExtraCharacters
);
2415 else if (strnicmp(currentline
, "shortstrings", 12) == 0)
2416 { currentline
+= 12;
2417 LongStrings
= FALSE
;
2418 OverSpace(¤tline
);
2420 { ShowWarn(msgExtraCharacters
);
2428 { bytesread
= ReadChar(¤tline
, bytes
);
2430 { if (*bytes
== '%')
2433 switch(c
= *(currentline
++))
2435 fputs(BaseName
, fpout
);
2438 fprintf(fpout
, "%d", NumStrings
);
2441 fprintf(fpout
, "%d", CatVersion
);
2444 WriteString(fpout
, Language
, -1);
2449 if ((c
= *currentline
++) == 'v')
2450 { fputs(VERS
, fpout
);
2453 { tempstr
= AllocFileName(CDFile
, c
- '0');
2454 fputs(tempstr
, fpout
);
2461 tempstr
= AllocFileName(SourceFile
, *currentline
++ - '0');
2462 fputs(tempstr
, fpout
);
2467 if (cs
) fputs(cs
->ID_Str
, fpout
);
2489 while(c
>= '0' && c
<= '9')
2491 len
= (c
- '0') + len
* 10;
2498 int _len
= len
? len
: 4;
2500 char _StrLen
[20 + 1];
2502 sprintf(_StrLen
, "%020lx", cs
->ID
);
2504 start
= &_StrLen
[20-_len
*2];
2507 fprintf(fpout
, "\\x%.2s", start
);
2515 int _len
= len
? len
: 4;
2517 char _StrLen
[20 + 1];
2519 sprintf(_StrLen
, "%020lx", ((CalcRealLength(cs
->CD_Str
) + 1) & 0xfffffe));
2521 start
= &_StrLen
[20-_len
*2];
2524 fprintf(fpout
, "\\x%.2s", start
);
2530 if(c
== 'c' || c
== 'd' || c
== 'x')
2534 if(c
== 'c') c
= 'o';
2537 sprintf(buffer
, "%%0%d%c", len
, c
);
2539 sprintf(buffer
, "%%%c", c
);
2541 if(cs
) fprintf(fpout
, buffer
, cs
->ID
);
2551 if (cs
) fprintf(fpout
, "%d", cs
->Nr
);
2557 unsigned long len
= 0;
2560 { idstr
= cs
->CD_Str
;
2562 { bytesread
= ReadChar(&idstr
, bytes
);
2568 WriteString(fpout
, cs
->CD_Str
, LengthBytes
? len
: -1);
2573 while(*currentline
&& *currentline
!= ')')
2574 { bytesread
= ReadChar(¤tline
, bytes
);
2575 if (bytesread
&& cs
&& cs
->Next
)
2576 { putc((int) bytes
[bytesread
-1], fpout
);
2580 { ShowWarn(msgNoTerminateBracket
);
2591 int diff
= (((CalcRealLength(cs
->CD_Str
) + 1) & 0xfffffe) - (CalcRealLength(cs
->CD_Str
)));
2597 fprintf(fpout
, "\\x00");
2605 { int c
= *currentline
++;
2612 { putc((int) bytes
[bytesread
-1], fpout
);
2618 while(NeedRepeat
&& cs
&& (cs
= cs
->Next
));
2630 The Usage function describes the programs calling syntax.
2635 fputs((char *) msgUsageHead
, stderr
);
2636 fprintf(stderr
, ": FlexCat CDFILE/A,CTFILE,CATALOG/K,NEWCTFILE/K,SOURCES/M,\n WARNCTGAPS/S,NOOPTIM/S,FILL/S,FLUSH/S,NOBEEP/S,\n QUIET/S,NOLANGTOLOWER/S,NOBUFFEREDIO/S,\n MODIFIED/S,COPYMSGNEW/S,OLDMSGNEW/K, NOSPACE/S\n\n", VString
);
2637 fprintf(stderr
, "%s\n%s\n%s\n%s\n", msgUsage
, msgUsage_2
, msgUsage_3
, msgUsage_4
);
2638 fprintf(stderr
, "\n\n%s"
2663 fprintf(stderr
, "%s\n", EString
);
2669 Finally the main function. Does nothing special except for scanning
2672 int main(int argc
, char *argv
[])
2674 char *cdfile
, *ctfile
, *newctfile
, *catalog
;
2675 char *source
, *template;
2678 if(argc
== 0) /* Aztec's entry point for workbench programs */
2680 fprintf(stderr
, "FlexCat can't be run from Workbench!\n\n");
2681 fprintf(stderr
, "Open a Shell session and type FlexCat ?\n");
2682 fprintf(stderr
, "for more information\n");
2686 cdfile
= ctfile
= newctfile
= catalog
= NULL
;
2689 /* let's open catalog files by hand if necessary */
2690 /* should be done automatically anyway for most */
2691 /* cases, but, that depends on compiler... */
2694 // STATIC __autoinit VOID _STIOpenFlexCatCatalog(VOID)
2695 #elif defined(__SASC)
2696 // VOID _STIOpenFlexCatCatalog(VOID)
2697 #elif defined(__GNUC__)
2698 // VOID _STIOpenFlexCatCatalog(VOID)
2699 #elif defined(__INTEL_COMPILER)
2700 // VOID _STIOpenFlexCatCatalog(VOID)
2702 OpenFlexCatCatalog(); /* no autoopen. we do it then */
2706 // Big Endian vs Little Endian (both supported ;-)
2709 fprintf(stderr
, "FlexCat is unable to determine the\n");
2710 fprintf(stderr
, "the byte order used by your system.\n");
2711 fprintf(stderr
, "It's neither Little nor Big Endian?!.\n");
2717 #if defined(__amigados)
2726 for (i
= 1; i
< argc
; i
++)
2728 if(strnicmp (argv
[i
], "catalog=", 8) == 0)
2730 catalog
= argv
[i
] + 8;
2733 if(stricmp (argv
[i
], "catalog") == 0)
2737 catalog
= argv
[++i
];
2740 if(stricmp(argv
[i
], "nooptim") == 0)
2745 if(stricmp(argv
[i
], "fill") == 0)
2750 if(stricmp(argv
[i
], "quiet") == 0)
2755 if(stricmp(argv
[i
], "flush") == 0)
2760 if(stricmp(argv
[i
], "nobeep") == 0)
2765 if(stricmp(argv
[i
], "nobufferedio") == 0)
2767 NoBufferedIO
= TRUE
;
2770 if (strnicmp (argv
[i
], "newctfile=", 10) == 0)
2772 newctfile
= argv
[i
] + 10;
2775 if(strnicmp (argv
[i
], "newctfile", 9) == 0)
2779 newctfile
= argv
[++i
];
2782 if(stricmp(argv
[i
], "nolangtolower") == 0)
2784 LANGToLower
= FALSE
;
2787 if(stricmp(argv
[i
], "modified") == 0)
2792 if(stricmp(argv
[i
], "warnctgaps") == 0)
2797 if(stricmp(argv
[i
], "copymsgnew") == 0)
2802 if(stricmp(argv
[i
], "nospace") == 0)
2807 if(stricmp(argv
[i
], "oldmsgnew") == 0)
2809 sprintf( Old_Msg_New
, "; %s", argv
[++i
] );
2814 if(stricmp(argv
[i
], "?") == 0 || stricmp(argv
[i
], "-h") == 0 || stricmp(argv
[i
], "help") == 0 || stricmp(argv
[i
], "--help") == 0)
2818 if(!ScanCDFile(cdfile
= argv
[i
]))
2824 if(strchr(argv
[i
], '='))
2826 source
= AllocString(argv
[i
]);
2827 *(template = strchr(source
, '=')) = '\0';
2830 CreateSourceFile(source
, template, cdfile
);
2843 #if defined(__amigados)
2846 if(cdfile
&& ctfile
&& catalog
)
2848 long cd_time
, ct_time
, cat_time
;
2850 if((cd_time
= getft(cdfile
)) != -1)
2852 if((ct_time
= getft(ctfile
)) != -1)
2854 if((cat_time
= getft(catalog
)) == -1)
2857 if((cat_time
> ct_time
) &&
2858 (cat_time
> cd_time
))
2862 fprintf(stderr
, (char *) msgUpToDate
, catalog
);
2866 MyExit(GlobalReturnCode
);
2872 fprintf(stderr
, "--> %s", catalog
);
2879 ShowError(msgCantCheckDate
, ctfile
);
2884 ShowError(msgCantCheckDate
, cdfile
);
2892 if(!ScanCTFile(ctfile
))
2900 fprintf(stderr
, (char *) msgNoCTArgument
);
2908 CreateCTFile(newctfile
);
2911 MyExit(GlobalReturnCode
);
2917 Dice's entry point for workbench programs
2919 #if defined(__amigados) && defined(_DCC)
2920 void wbmain(struct WBStartup
*wbmsg
)
2922 fprintf(stderr
, "FlexCat can't be run from Workbench!\n\n");
2923 fprintf(stderr
, "Open a Shell session and type FlexCat\n");
2924 fprintf(stderr
, "for syntax and more information\n");