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)"
1724 , name
, (long)version
, (long)revision
, (long)day
, (long)month
, (long)year
);
1726 cc
.ID
= MAKE_ID('F','V','E','R');
1727 cc
.ID
= SwapLong( cc
.ID
);
1728 cc
.ChunkStr
= verStr
;
1729 CatLen
+= PutCatalogChunk(fp
, &cc
);
1733 for (cc
= FirstChunk
; cc
!= NULL
; cc
= cc
->Next
)
1735 CatLen
+= PutCatalogChunk(fp
, cc
);
1742 int i_tmp
= SwapLong( i
);
1744 fwrite(&i_tmp
, sizeof(i_tmp
), 1, fp
);
1753 fprintf(fp
, "STRS0000");
1757 for(cs
= FirstCatString
; cs
!= NULL
; cs
= cs
->Next
)
1759 int FillUsed
= FALSE
;
1760 int tmp_ID
= SwapLong( cs
->ID
);
1767 if(strlen(cs
->CT_Str
) == 0)
1769 fwrite(&tmp_ID
, sizeof(tmp_ID
), 1, fp
);
1770 CatLen
+= 4 + CatPuts(fp
, cs
->CD_Str
, 4, FALSE
);
1776 fwrite(&tmp_ID
, sizeof(cs
->ID
), 1, fp
);
1777 CatLen
+= 4 + CatPuts(fp
, cs
->CD_Str
, 4, FALSE
);
1782 if((!FillUsed
) && cs
->CT_Str
&& (NoOptim
? TRUE
: strcmp(cs
->CT_Str
, cs
->CD_Str
)))
1784 fwrite(&tmp_ID
, sizeof( tmp_ID
), 1, fp
);
1785 CatLen
+= 4 + CatPuts(fp
, cs
->CT_Str
, 4, FALSE
);
1793 fseek(fp
, 4, SEEK_SET
);
1795 tmp_Len
= SwapLong( CatLen
);
1796 fwrite(&tmp_Len
, sizeof(tmp_Len
), 1, fp
);
1797 fseek(fp
, HeadLen
-4, SEEK_CUR
);
1800 tmp_Len
= SwapLong( CatLen
);
1801 fwrite(&tmp_Len
, sizeof(CatLen
), 1, fp
);
1810 /// FUNC: CreateCTFile
1813 This creates a new catalog translation file.
1815 void CreateCTFile(char *NewCTFile
)
1819 struct CatString
*cs
;
1820 struct CatalogChunk
*cc
;
1823 if(!CatVersionString
&& !CatRcsId
)
1826 ShowWarn(msgNoCTVersion
);
1829 if(!(fp
= fopen(NewCTFile
, "w")))
1831 ShowError(msgNoNewCTFile
);
1836 setvbuf(fp
, NULL
, _IOFBF
, buffer_size
);
1841 fprintf(fp
, "## rcsid %s\n",
1842 CatRcsId
? CatRcsId
: "");
1844 fprintf(fp
, "## name %s\n", CatName
);
1848 if(CatVersionString
)
1849 fprintf(fp
, "## version %s\n", CatVersionString
);
1852 fprintf(fp
, "## version $V");
1853 fprintf(fp
, "%c", 50+19); // E
1854 fprintf(fp
, "R: XX.catalog XX.XX ($TODAY)\n");
1862 if(CatLanguage
== NULL
)
1863 if(lang
= getenv("ENV:language"))
1867 for(i
=0;i
<strlen(lang
); i
++)
1877 fprintf(fp
, "## language %s\n## codeset %d\n;\n",
1878 CatLanguage
? CatLanguage
: "X", CodeSet
);
1889 for (cc
= FirstChunk
; cc
!= NULL
; cc
= cc
->Next
)
1891 if (cc
->ChunkStr
!= CatLanguage
)
1893 fprintf(fp
, "## chunk ");
1894 fwrite((char *) &cc
->ID
, sizeof(cc
->ID
), 1, fp
);
1895 fprintf(fp
, " %s\n", cc
->ChunkStr
);
1899 for(cd
= FirstCDLine
, cs
= FirstCatString
;
1909 fprintf(fp
, "%s\n", cd
->Line
);
1916 fprintf(fp, "%s\n", cs->ID_Str);
1917 fprintf(fp, "%s\n", cs->CT_Str ? cs->CT_Str : "");
1921 fprintf(fp
, "%s\n%s\n;", cs
->ID_Str
, cs
->CT_Str
? cs
->CT_Str
: "");
1928 for (line
= cs
->CD_Str
; *line
; ++line
)
1930 putc((int) *line
, fp
);
1940 if(cs
->NotInCT
&& CT_Scanned
)
1941 fprintf(fp
, ";\n; %s\n", Msg_New
);
1952 /// FUNC: InitCatStringOutput
1955 InitCatStringOutput gets called before writing a catalog string as
1958 Inputs: fp = file pointer to the output file
1959 type = one of TYPE_C create C strings
1960 TYPE_ASSEMBLER create Assembler strings
1961 TYPE_OBERON create Oberon strings
1962 TYPE_E create E strings
1963 TYPE_NONE create simple strings
1965 int OutputMode
= OutputMode_None
;
1966 int OutputType
= TYPE_C
;
1970 void InitCatStringOutput(FILE *fp
)
1974 OutputMode
= OutputMode_None
;
1979 OutputMode
= OutputMode_Ascii
;
1983 case TYPE_ASSEMBLER
:
1989 /// FUNC: SeparateCatStringOutput
1992 SeparateCatStringOutput gets called to split a catalog into separate
1995 void SeparateCatStringOutput(void)
2000 { fputs("\"\\\n\t\"", OutputFile
);
2005 { fputs("\' +\n\t\'", OutputFile
);
2010 { fputs("\"\n\t\"", OutputFile
);
2013 case TYPE_ASSEMBLER
:
2015 { if (OutputMode
== OutputMode_Ascii
)
2016 { putc('\'', OutputFile
);
2018 putc('\n', OutputFile
);
2019 OutputMode
= OutputMode_None
;
2027 /// FUNC: WriteBinChar
2030 WriteBinChar writes one binary character into the source file
2032 void WriteBinChar(int c
)
2041 fputs("\\b", OutputFile
);
2044 fputs("\\n", OutputFile
);
2047 fputs("\\r", OutputFile
);
2050 fputs("\\t", OutputFile
);
2053 fputs("\\f", OutputFile
);
2056 fputs("\\000", OutputFile
);
2059 if(OutputType
== TYPE_E
&& c
== '\033')
2061 fputs("\\e", OutputFile
);
2065 fprintf(OutputFile
, "\\%c%c%c", ((c
>> 6) & 3) + '0',
2066 ((c
>> 3) & 7) + '0', (c
& 7) + '0');
2071 OutputMode
= OutputMode_Bin
;
2073 case TYPE_ASSEMBLER
:
2075 { case OutputMode_None
:
2076 fprintf(OutputFile
, "\tdc.b\t$%02x", c
& 0xff);
2078 case OutputMode_Ascii
:
2079 putc('\'', OutputFile
);
2080 case OutputMode_Bin
:
2081 fprintf(OutputFile
, ",$%02x", c
& 0xff);
2085 OutputMode
= OutputMode_Bin
;
2088 ShowWarn(msgNoBinChars
);
2093 /// FUNC: WriteAsciiChar
2096 WriteAsciiChar writes one ascii character into the source file.
2098 void WriteAsciiChar(int c
)
2106 fputs("\\\"", OutputFile
);
2109 putc(c
, OutputFile
);
2113 OutputMode
= OutputMode_Ascii
;
2118 fputs("''", OutputFile
);
2121 putc(c
, OutputFile
);
2125 OutputMode
= OutputMode_Ascii
;
2127 case TYPE_ASSEMBLER
:
2132 { switch (OutputMode
)
2133 { case OutputMode_None
:
2134 fprintf(OutputFile
, "\tdc.b\t\'%c", c
);
2136 case OutputMode_Ascii
:
2137 putc(c
, OutputFile
);
2139 case OutputMode_Bin
:
2140 fprintf(OutputFile
, ",\'%c", c
);
2144 OutputMode
= OutputMode_Ascii
;
2148 putc(c
, OutputFile
);
2153 /// FUNC: TerminateCatStringOutput
2156 TerminateCatStringOutput finishs the output of a catalog string.
2158 void TerminateCatStringOutput(void)
2163 putc('\"', OutputFile
);
2166 putc('\'', OutputFile
);
2168 case TYPE_ASSEMBLER
:
2170 { case OutputMode_Ascii
:
2171 putc('\'', OutputFile
);
2172 case OutputMode_Bin
:
2174 case OutputMode_None
:
2183 /// FUNC: WriteString
2185 This writes a sourcestring.
2187 void WriteString(FILE *fpout
, char *str
, long Len
)
2191 int needseparate
= FALSE
;
2193 InitCatStringOutput(fpout
);
2197 for(i
= LengthBytes
; i
>= 1; i
--)
2198 { WriteBinChar((int) ((char *) &Len
)[sizeof(Len
)-i
]);
2203 { bytesread
= ReadChar(&str
, bytes
);
2208 { SeparateCatStringOutput();
2209 needseparate
= FALSE
;
2212 c
= bytes
[bytesread
-1];
2213 if ((c
>= 0x20 && c
< 0x7f) || c
>= 0xa0)
2214 { WriteAsciiChar((int) c
);
2217 { WriteBinChar((int) c
);
2221 { needseparate
= TRUE
;
2224 TerminateCatStringOutput();
2227 /// FUNC: AllocFileName
2229 This function creates a copy of a filename, removes an
2230 optional ending and pathname components, if desired.
2232 Inputs: filename - the filename to copy
2233 howto - a set of bits
2234 bit 0: 1 = remove ending, 0 = leave it
2235 bit 1: 1 = remove pathname, 0 = leave it
2237 Result: The copy of the filename
2239 char *AllocFileName(char *filename
, int howto
)
2241 char *tempstr
, *ptr
;
2243 if (!(tempstr
= strdup(filename
)))
2248 /* Remove pathname components, if desired */
2250 { if ((ptr
= strchr(tempstr
, ':')))
2253 if ((ptr
= strrchr(tempstr
, '/')))
2258 /* Remove ending, if desired. */
2260 { if ((ptr
= strrchr(tempstr
, '.')))
2268 /// FUNC: AddFileName
2270 This function adds a pathname and a filename to a full
2273 Inputs: pathname - the leading pathname
2274 filename - the filename
2276 Result: The new filename
2278 char *AddFileName(char *pathname
, char *filename
)
2281 int size
= strlen(pathname
) + strlen(filename
) + 2;
2283 if (!(buffer
= malloc(size
)))
2288 #if defined(__amigados)
2289 strcpy(buffer
, pathname
);
2290 AddPart((char *) buffer
, (char *) filename
, size
);
2292 sprintf(buffer
, "%s/%s", pathname
, filename
);
2299 /// FUNC: CreateSourceFile
2302 Finally the source creation.
2304 void CreateSourceFile(char *SourceFile
, char *TemplateFile
, char *CDFile
)
2309 char *OrigTemplateFile
= TemplateFile
;
2311 ScanFile
= SourceFile
;
2315 Open the source file. This may be found in various places
2317 if(!(fpin
= fopen(TemplateFile
, "r")))
2320 if(*prefs_sddir
!= 0)
2322 TemplateFile
= AddFileName(prefs_sddir
, OrigTemplateFile
);
2323 fpin
= fopen(TemplateFile
, "r");
2332 if((sddir
= getenv(FLEXCAT_SDDIR
)))
2334 TemplateFile
= AddFileName(sddir
, OrigTemplateFile
);
2335 fpin
= fopen(TemplateFile
, "r");
2340 { TemplateFile
= AddFileName(DEFAULT_FLEXCAT_SDDIR
, OrigTemplateFile
);
2341 fpin
= fopen(TemplateFile
, "r");
2346 ShowError(msgNoSourceDescription
, OrigTemplateFile
);
2350 if (!(fpout
= fopen(SourceFile
, "w")))
2352 ShowError(msgNoSource
, SourceFile
);
2357 setvbuf(fpin
, NULL
, _IOFBF
, buffer_size
);
2359 setvbuf(fpout
, NULL
, _IOFBF
, buffer_size
);
2362 while(!feof(fpin
) && (line
= ReadLine(fpin
, FALSE
)))
2363 { struct CatString
*cs
;
2368 cs
= FirstCatString
;
2370 { char *currentline
= line
;
2373 if (*currentline
== '#' && *(++currentline
) == '#')
2375 OverSpace(¤tline
);
2377 if(strnicmp( currentline
, "rem", 3 ) == 0)
2379 // we just skip this line
2383 if (strnicmp(currentline
, "stringtype", 10) == 0)
2384 { currentline
+= 10;
2385 OverSpace(¤tline
);
2386 if (strnicmp(currentline
, "c", 1) == 0)
2387 { OutputType
= TYPE_C
;
2390 else if (strnicmp(currentline
, "assembler", 9) == 0)
2391 { OutputType
= TYPE_ASSEMBLER
;
2394 else if (strnicmp(currentline
, "oberon", 6) == 0)
2395 { OutputType
= TYPE_OBERON
;
2398 else if (strnicmp(currentline
, "e", 1) == 0)
2399 { OutputType
= TYPE_E
;
2402 else if (strnicmp(currentline
, "none", 4) == 0)
2403 { OutputType
= TYPE_NONE
;
2407 { ShowWarn(msgUnknownStringType
);
2408 currentline
+= strlen(currentline
);
2410 OverSpace(¤tline
);
2412 { ShowWarn(msgExtraCharacters
);
2416 else if (strnicmp(currentline
, "shortstrings", 12) == 0)
2417 { currentline
+= 12;
2418 LongStrings
= FALSE
;
2419 OverSpace(¤tline
);
2421 { ShowWarn(msgExtraCharacters
);
2429 { bytesread
= ReadChar(¤tline
, bytes
);
2431 { if (*bytes
== '%')
2434 switch(c
= *(currentline
++))
2436 fputs(BaseName
, fpout
);
2439 fprintf(fpout
, "%d", NumStrings
);
2442 fprintf(fpout
, "%d", CatVersion
);
2445 WriteString(fpout
, Language
, -1);
2450 if ((c
= *currentline
++) == 'v')
2451 { fputs(VERS
, fpout
);
2454 { tempstr
= AllocFileName(CDFile
, c
- '0');
2455 fputs(tempstr
, fpout
);
2462 tempstr
= AllocFileName(SourceFile
, *currentline
++ - '0');
2463 fputs(tempstr
, fpout
);
2468 if (cs
) fputs(cs
->ID_Str
, fpout
);
2490 while(c
>= '0' && c
<= '9')
2492 len
= (c
- '0') + len
* 10;
2499 int _len
= len
? len
: 4;
2501 char _StrLen
[20 + 1];
2503 sprintf(_StrLen
, "%020lx", (long)(cs
->ID
));
2505 start
= &_StrLen
[20-_len
*2];
2508 fprintf(fpout
, "\\x%.2s", start
);
2516 int _len
= len
? len
: 4;
2518 char _StrLen
[20 + 1];
2520 sprintf(_StrLen
, "%020lx", (long)((CalcRealLength(cs
->CD_Str
) + 1) & 0xfffffe));
2522 start
= &_StrLen
[20-_len
*2];
2525 fprintf(fpout
, "\\x%.2s", start
);
2531 if(c
== 'c' || c
== 'd' || c
== 'x')
2535 if(c
== 'c') c
= 'o';
2538 sprintf(buffer
, "%%0%d%c", len
, c
);
2540 sprintf(buffer
, "%%%c", c
);
2542 if(cs
) fprintf(fpout
, buffer
, cs
->ID
);
2552 if (cs
) fprintf(fpout
, "%d", cs
->Nr
);
2558 unsigned long len
= 0;
2561 { idstr
= cs
->CD_Str
;
2563 { bytesread
= ReadChar(&idstr
, bytes
);
2569 WriteString(fpout
, cs
->CD_Str
, LengthBytes
? len
: -1);
2574 while(*currentline
&& *currentline
!= ')')
2575 { bytesread
= ReadChar(¤tline
, bytes
);
2576 if (bytesread
&& cs
&& cs
->Next
)
2577 { putc((int) bytes
[bytesread
-1], fpout
);
2581 { ShowWarn(msgNoTerminateBracket
);
2592 int diff
= (((CalcRealLength(cs
->CD_Str
) + 1) & 0xfffffe) - (CalcRealLength(cs
->CD_Str
)));
2598 fprintf(fpout
, "\\x00");
2606 { int c
= *currentline
++;
2613 { putc((int) bytes
[bytesread
-1], fpout
);
2619 while(NeedRepeat
&& cs
&& (cs
= cs
->Next
));
2631 The Usage function describes the programs calling syntax.
2636 fputs((char *) msgUsageHead
, stderr
);
2637 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
);
2638 fprintf(stderr
, "%s\n%s\n%s\n%s\n", msgUsage
, msgUsage_2
, msgUsage_3
, msgUsage_4
);
2639 fprintf(stderr
, "\n\n%s"
2664 fprintf(stderr
, "%s\n", EString
);
2670 Finally the main function. Does nothing special except for scanning
2673 int main(int argc
, char *argv
[])
2675 char *cdfile
, *ctfile
, *newctfile
, *catalog
;
2676 char *source
, *template;
2679 if(argc
== 0) /* Aztec's entry point for workbench programs */
2681 fprintf(stderr
, "FlexCat can't be run from Workbench!\n\n");
2682 fprintf(stderr
, "Open a Shell session and type FlexCat ?\n");
2683 fprintf(stderr
, "for more information\n");
2687 cdfile
= ctfile
= newctfile
= catalog
= NULL
;
2690 /* let's open catalog files by hand if necessary */
2691 /* should be done automatically anyway for most */
2692 /* cases, but, that depends on compiler... */
2695 // STATIC __autoinit VOID _STIOpenFlexCatCatalog(VOID)
2696 #elif defined(__SASC)
2697 // VOID _STIOpenFlexCatCatalog(VOID)
2698 #elif defined(__GNUC__)
2699 // VOID _STIOpenFlexCatCatalog(VOID)
2700 #elif defined(__INTEL_COMPILER)
2701 // VOID _STIOpenFlexCatCatalog(VOID)
2703 OpenFlexCatCatalog(); /* no autoopen. we do it then */
2707 // Big Endian vs Little Endian (both supported ;-)
2710 fprintf(stderr
, "FlexCat is unable to determine the\n");
2711 fprintf(stderr
, "the byte order used by your system.\n");
2712 fprintf(stderr
, "It's neither Little nor Big Endian?!.\n");
2718 #if defined(__amigados)
2727 for (i
= 1; i
< argc
; i
++)
2729 if(strnicmp (argv
[i
], "catalog=", 8) == 0)
2731 catalog
= argv
[i
] + 8;
2734 if(stricmp (argv
[i
], "catalog") == 0)
2738 catalog
= argv
[++i
];
2741 if(stricmp(argv
[i
], "nooptim") == 0)
2746 if(stricmp(argv
[i
], "fill") == 0)
2751 if(stricmp(argv
[i
], "quiet") == 0)
2756 if(stricmp(argv
[i
], "flush") == 0)
2761 if(stricmp(argv
[i
], "nobeep") == 0)
2766 if(stricmp(argv
[i
], "nobufferedio") == 0)
2768 NoBufferedIO
= TRUE
;
2771 if (strnicmp (argv
[i
], "newctfile=", 10) == 0)
2773 newctfile
= argv
[i
] + 10;
2776 if(strnicmp (argv
[i
], "newctfile", 9) == 0)
2780 newctfile
= argv
[++i
];
2783 if(stricmp(argv
[i
], "nolangtolower") == 0)
2785 LANGToLower
= FALSE
;
2788 if(stricmp(argv
[i
], "modified") == 0)
2793 if(stricmp(argv
[i
], "warnctgaps") == 0)
2798 if(stricmp(argv
[i
], "copymsgnew") == 0)
2803 if(stricmp(argv
[i
], "nospace") == 0)
2808 if(stricmp(argv
[i
], "oldmsgnew") == 0)
2810 sprintf( Old_Msg_New
, "; %s", argv
[++i
] );
2815 if(stricmp(argv
[i
], "?") == 0 || stricmp(argv
[i
], "-h") == 0 || stricmp(argv
[i
], "help") == 0 || stricmp(argv
[i
], "--help") == 0)
2819 if(!ScanCDFile(cdfile
= argv
[i
]))
2825 if(strchr(argv
[i
], '='))
2827 source
= AllocString(argv
[i
]);
2828 *(template = strchr(source
, '=')) = '\0';
2831 CreateSourceFile(source
, template, cdfile
);
2844 #if defined(__amigados)
2847 if(cdfile
&& ctfile
&& catalog
)
2849 long cd_time
, ct_time
, cat_time
;
2851 if((cd_time
= getft(cdfile
)) != -1)
2853 if((ct_time
= getft(ctfile
)) != -1)
2855 if((cat_time
= getft(catalog
)) == -1)
2858 if((cat_time
> ct_time
) &&
2859 (cat_time
> cd_time
))
2863 fprintf(stderr
, (char *) msgUpToDate
, catalog
);
2867 MyExit(GlobalReturnCode
);
2873 fprintf(stderr
, "--> %s", catalog
);
2880 ShowError(msgCantCheckDate
, ctfile
);
2885 ShowError(msgCantCheckDate
, cdfile
);
2893 if(!ScanCTFile(ctfile
))
2901 fprintf(stderr
, "%s\n", (char *) msgNoCTArgument
);
2909 CreateCTFile(newctfile
);
2912 MyExit(GlobalReturnCode
);
2918 Dice's entry point for workbench programs
2920 #if defined(__amigados) && defined(_DCC)
2921 void wbmain(struct WBStartup
*wbmsg
)
2923 fprintf(stderr
, "FlexCat can't be run from Workbench!\n\n");
2924 fprintf(stderr
, "Open a Shell session and type FlexCat\n");
2925 fprintf(stderr
, "for syntax and more information\n");