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
84 #include "flexcat_cat.h"
86 #if ((defined(_DCC) && defined(AMIGA)) || \
87 (defined(__SASC) && defined(_AMIGA))) && \
92 #if defined(__amigados)
93 #include <exec/types.h>
94 #if defined(_DCC) || defined(__SASC) || defined(__GNUC__)
95 #include <proto/exec.h>
96 #include <proto/dos.h>
97 #include <proto/intuition.h>
98 #include <proto/utility.h>
100 #include <clib/exec_protos.h>
101 #include <clib/dos_protos.h>
102 #include <clib/utility_protos.h>
108 #define tolower ToLower
109 #define stricmp(s,t) Stricmp((char *) (s), (char *) (t))
110 #define strnicmp(s,t,l) Strnicmp((char *) (s), (char *) (t), l)
119 #define TRUE (!FALSE)
123 #define MAXPATHLEN 512
124 #define FLEXCAT_SDDIR "FLEXCAT_SDDIR"
125 #if defined(__amigados)
126 #define DEFAULT_FLEXCAT_SDDIR "PROGDIR:lib"
128 #define DEFAULT_FLEXCAT_SDDIR "lib"
131 #if defined(__amigados)
132 #define MAX_PREFS_LEN 512
133 #define FLEXCAT_PREFS "flexcat.prefs"
134 char prefs_sddir
[MAXPATHLEN
] = "\0";
139 #define MAKE_ID(a,b,c,d) \
140 ((ULONG) (a)<<24 | (ULONG) (b)<<16 | (ULONG) (c)<<8 | (ULONG) (d))
144 #define ULONG unsigned long
151 TYPE_C
, /* Produce C strings */
152 TYPE_ASSEMBLER
, /* Produce Assembler strings */
153 TYPE_OBERON
, /* Produce Oberon strings */
154 TYPE_E
, /* Produce E strings. (Oops, thought */
155 /* it allows only 32 bit integers? ;-) */
156 TYPE_NONE
/* Simple strings */
161 OutputMode_None
, /* Nothing written yet */
162 OutputMode_Bin
, /* Last character written was binary */
163 OutputMode_Ascii
/* Last character written was Ascii */
167 { struct CatString
*Next
;
171 int MinLen
, MaxLen
, ID
, Nr
;
172 int NotInCT
; /* If string is not present we write NEW */
173 /* while updating CT file, for easier work. */
178 { struct CDLine
*Next
;
183 { struct CatalogChunk
*Next
; /* struct CatalogChunk *Next */
188 struct CatString
*FirstCatString
= NULL
; /* First catalog string */
189 struct CDLine
*FirstCDLine
= NULL
; /* First catalog description line */
190 struct CatalogChunk
*FirstChunk
= NULL
; /* List of catalog chunks */
192 char *BaseName
= ""; /* Basename of catalog description */
193 char *Language
= "english"; /* Language of catalog description */
194 int CatVersion
= 0; /* Version of catalog to be opened */
195 int LengthBytes
= 0; /* Number of bytes to preceed a */
196 /* created string and containing */
198 char *CatLanguage
= NULL
; /* Language of catalog translation */
199 char *CatVersionString
= NULL
; /* version string of catalog */
200 /* translation (## version) */
201 char *CatRcsId
= NULL
; /* rcs ID of catalog translation */
203 char *CatName
= NULL
; /* name of catalog translation */
204 int CodeSet
= 0; /* Codeset of catalog translation */
205 int NumStrings
= 0; /* Number of catalog strings */
206 int LongStrings
= TRUE
; /* Generate long or short strings */
208 char *ScanFile
; /* File currently scanned */
209 int ScanLine
; /* Line currently scanned */
211 int GlobalReturnCode
= 0; /* Will be 5, if warnings appear */
212 int WarnCTGaps
= FALSE
; /* Warn missing symbols in CT */
214 int NoOptim
= FALSE
; /* Put string into catalog even */
215 /* if translation is equal to */
217 int Fill
= FALSE
; /* It translation of given string */
218 /* is missing or it's empty, write */
219 /* string descriptor from #?.cd */
221 int DoExpunge
= FALSE
; /* If TRUE FlexCat will do AVAIL */
222 /* FLUSH alike after catalog save */
223 int NoBeep
= FALSE
; /* if TRUE, FlexCat won't call */
224 /* DisplayBeep() any longer */
225 int Quiet
= FALSE
; /* Forces FlexCat to shut up */
227 int NumberOfWarnings
= 0; /* We count warnings to be smart */
228 /* and not to do Beep bombing, but */
229 /* call DisplayBeep() only once */
230 int CT_Scanned
= FALSE
; /* If TRUE, and we are going to */
231 /* write new #?.ct file, then user */
232 /* surely updates own #?.ct file */
233 /* so we should write ***NEW*** */
234 /* whenever necessary. */
235 int LANGToLower
= TRUE
; /* Shall we do ToLower() on lang's */
236 /* name? Some #?.language seems to */
237 /* be broken, so we allow workaround */
238 int NoBufferedIO
= FALSE
; /* Shall we do buffered IO */
239 int buffer_size
= 2048; /* Size of the IO buffer */
240 int Modified
= FALSE
; /* Shall we write the catalog ONLY */
241 /* if #?.catalog is younger than */
242 /* #?.c(d|t) files? */
244 #define MAX_NEW_STR_LEN 25
245 char Msg_New
[MAX_NEW_STR_LEN
] = "***NEW***";
246 /* new strings in updated #?.ct */
248 int CopyNEWs
= FALSE
;
249 char Old_Msg_New
[MAX_NEW_STR_LEN
] = "; ***NEW***";
251 /* old newstring (above) used in old */
252 /* CT file. Now we look if it's present */
253 /* and copy it into new CT if user does */
254 /* upgrade (flexcat CD CT newctfile CT */
256 int NoSpace
= FALSE
; /* do want to strip the space usually */
257 /* placed between ';' and original */
261 char VersTag
[] = VERSTAG
;
262 char VString
[] = VSTRING
" by Jochen Wiedmann and Marcin Orlowski";
263 char EString
[] = "E-mail: carlos@amiga.com.pl WWW: http://amiga.com.pl/flexcat/";
267 #if defined(__amigados)
289 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";
290 LONG Results
[ARGS_COUNT
] = {0};
294 struct RDArgs
*rdargs
;
296 if(prefs
= getenv(FLEXCAT_PREFS
))
298 prefs
= realloc(prefs
, strlen(prefs
)+1);
301 if(rda
= AllocDosObject(DOS_RDARGS
, TAG_DONE
))
303 rda
->RDA_Source
.CS_Buffer
= prefs
;
304 rda
->RDA_Source
.CS_Length
= strlen(prefs
);
305 rda
->RDA_Source
.CS_CurChr
= 0;
306 rda
->RDA_Flags
|= RDAF_NOPROMPT
;
308 if(rdargs
= ReadArgs(template, Results
, rda
))
311 strncpy(prefs_sddir
, (char *)Results
[SDDIR
], MAXPATHLEN
);
314 strncpy(Msg_New
, (char *)Results
[MSG_NEW
], MAX_NEW_STR_LEN
);
316 WarnCTGaps
= Results
[WARNCTGAPS
];
317 NoOptim
= Results
[NOOPTIM
];
318 Fill
= Results
[FILL
];
319 DoExpunge
= Results
[FLUSH
];
320 NoBeep
= Results
[NOBEEP
];
321 Quiet
= Results
[QUIET
];
322 LANGToLower
= Results
[NOLANGTOLOWER
];
323 Modified
= Results
[MODIFIED
];
324 NoBufferedIO
= Results
[NOBUFFEREDIO
];
325 CopyNEWs
= Results
[COPYMSGNEW
];
326 NoSpace
= Results
[NOSPACE
];
327 if(Results
[OLDMSGNEW
])
328 sprintf(Old_Msg_New
, "; %s", (char *)Results
[OLDMSGNEW
]);
336 fputs((char *)msgPrefsError
, stderr
);
337 fputs((char *)template, stderr
);
338 fputs((char *)"\n", stderr
);
342 FreeDosObject(DOS_RDARGS
, rda
);
346 fputs("Error processing prefs.\nCan't AllocDosObject()\n", stderr
);
359 void MyExit (int Code
)
362 #if defined(__amigados)
364 if(((NumberOfWarnings
> 0) ||(Code
!=0)) && (!NoBeep
))
371 //STATIC __autoexit VOID _STDCloseFlexCatCatalog(VOID)
372 #elif defined(__SASC)
373 //VOID _STDCloseFlexCatCatalog(VOID)
374 #elif defined(__GNUC__)
375 //STATIC VOID _STDCloseFlexCatCatalog(VOID)
376 #elif defined(__INTEL_COMPILER)
377 //STATIC VOID _STDCloseFlexCatCatalog(VOID)
379 CloseFlexCatCatalog(); /* we need to close something... */
391 #if !defined(__amigados) && !defined(__CYGWIN32__)
392 # define stricmp strcasecmp
396 int stricmp( const char *str1
, const char *str2
)
402 int a
= tolower( (int)*str1
);
403 int b
= tolower( (int)*str2
);
424 #if !defined(__amigados) && !defined(__CYGWIN32__)
425 int strnicmp( const char *str1
, const char *str2
, size_t len
)
429 for(i
= 0; i
< len
; i
++)
431 int a
= tolower( (int)*str1
);
432 int b
= tolower( (int)*str2
);
450 /// FUNC: Swappers...
453 unsigned short (*SwapWord
)(unsigned short r
) = NULL
;
454 unsigned long (*SwapLong
)(unsigned long r
) = NULL
;
457 unsigned short SwapWord21(unsigned short r
)
459 return (unsigned short)((r
>>8) + (r
<<8));
461 unsigned short SwapWord12(unsigned short r
)
465 unsigned long SwapLong4321(unsigned long r
)
467 return ((r
>>24) & 0xFF) + (r
<<24) + ((r
>>8) & 0xFF00) + ((r
<<8) & 0xFF0000);
469 unsigned long SwapLong1234(unsigned long r
)
481 strncpy((char *)&w
, "\1\2", 2);
482 strncpy((char *)&d
, "\1\2\3\4", 4);
485 SwapWord
= SwapWord21
;
486 else if (w
== 0x0102)
487 SwapWord
= SwapWord12
;
492 SwapLong
= SwapLong4321
;
493 else if (d
== 0x01020304)
494 SwapLong
= SwapLong1234
;
505 This shows an error message and terminates
507 void ShowError(const char *msg
, ...)
509 char **ptr
= (char **) &msg
;
513 fprintf(stderr
, ptr
[0], ptr
[1], ptr
[2], ptr
[3], ptr
[4]);
517 #if defined(__amigados)
527 This shows the message: Memory error.
532 ShowError(msgMemoryError
, NULL
);
540 void ShowWarn(const char *msg
, ...)
542 { char **ptr
= (char **) &msg
;
546 fprintf(stderr
, (char *) msgWarning
, ScanFile
, ScanLine
);
547 fprintf(stderr
, ptr
[0], ptr
[1], ptr
[2], ptr
[3], ptr
[4]);
552 GlobalReturnCode
= 5;
555 /// FUNC: AllocString
558 This allocates a string
560 char *AllocString(const char *str
)
564 if (!(ptr
= malloc(strlen(str
)+1)))
571 /// FUNC: Add catalog chunk
574 This adds a new catalog chunk to the list of catalog
577 char *AddCatalogChunk(char *ID
, const char *string
)
579 struct CatalogChunk
*cc
, **ccptr
;
581 if (!(cc
= malloc(sizeof(*cc
))))
585 cc
->ID
= *((ULONG
*) ID
);
586 cc
->ChunkStr
= AllocString(string
);
589 Put the new chunk to the end of the chunk list.
591 for (ccptr
= &FirstChunk
; *ccptr
!= NULL
; ccptr
= &(*ccptr
)->Next
)
595 return(cc
->ChunkStr
);
600 This translates a hex character.
604 if (c
>= '0' && c
<= '9')
607 else if (c
>= 'a' && c
<= 'f')
608 { return(c
- 'a' + 10);
610 else if (c
>= 'A' && c
<= 'F')
611 { return(c
- 'A' + 10);
613 ShowWarn(msgExpectedHex
);
620 This translates an octal digit.
625 if (c
>= '0' && c
<= '7')
630 ShowWarn(msgExpectedOctal
);
638 Reading a line is somewhat complicated in order to allow lines of any
641 Inputs: fp - the file, where the input comes from
642 AllowComment - TRUE, if a leading semicolon should force to
643 interpret the line as a comment line
646 char *ReadLine(FILE *fp
, int AllowComment
)
649 char *OldLine
, *NewLine
= NULL
;
651 int Len
= 0, LineLen
= 0;
652 int FirstChar
= TRUE
;
653 int BackslashSeen
= FALSE
;
654 int BackslashSeenOn
= 0; /* position the last backslash was seen on */
655 int CommentLine
= FALSE
; /* if TRUE we should ignore normally treat trailing \'s */
662 if(!(NewLine
= malloc(LineLen
+BUFSIZE
)))
665 strncpy(NewLine
, OldLine
, LineLen
);
700 BackslashSeen
= FALSE
;
708 /* Let's check for trailing \\ */
715 if(BackslashSeenOn
== (Len
-1))
717 BackslashSeen
= FALSE
;
723 BackslashSeen
= TRUE
;
724 BackslashSeenOn
= Len
;
733 BackslashSeen
= FALSE
;
747 This removes trailing blanks.
749 void OverSpace(char **strptr
)
753 while ((c
= **strptr
) == ' ' || c
== '\t')
763 #if defined(__amigados)
768 #ifdef __EXPUNGE_ALL__
771 if(Memory
= AllocMem(-1, NULL
))
772 FreeMem(Memory
, -1); // just in case ;-)
775 #pragma libcall LocaleBase localeExpunge 12 00
776 VOID
localeExpunge(VOID
);
778 struct Library
*LocaleBase
;
780 if(LocaleBase
= OpenLibrary("locale.library", 0))
783 CloseLibrary(LocaleBase
);
797 ReadChar scans an input line translating the backslash characters.
799 Inputs: char * - a pointer to a stringpointer; the latter points to the
800 next character to be read and points behind the read
801 bytes after executing ReadChar
802 dest - a pointer to a buffer, where the read bytes should be
805 Result: number of bytes that are written to dest (between 0 and 2)
807 int ReadChar(char **strptr
, char *dest
)
812 switch(c
= *((*strptr
)++))
816 switch(c
= tolower((int) *((*strptr
)++)))
848 *dest
= gethex((int) **strptr
);
850 if (((c
= **strptr
) >= '0' && c
<= '9') ||
851 (c
>= 'a' && c
<= 'f') || (c
>= 'A' && c
<= 'F'))
852 { *dest
= (*dest
<< 4) + gethex((int) c
);
865 *dest
= getoctal((int)c
);
867 for(i
= 0; i
< 2; i
++)
869 if((c
= **strptr
) >= '0' && c
<= '7')
871 *dest
= (*dest
<< 3) + getoctal((int) c
);
895 This scans the catalog description file.
897 Inputs: cdfile - name of the catalog description file
899 Result: TRUE, if successful, FALSE otherwise
901 int ScanCDFile(char *cdfile
)
904 struct CDLine
*cdline
, **cdptr
= &FirstCDLine
;
905 struct CatString
*cs
, **csptr
= &FirstCatString
;
906 char *line
, *newline
;
914 if(!(fp
= fopen(cdfile
, "r")))
916 ShowError(msgNoCatalogDescription
, cdfile
);
920 setvbuf(fp
, NULL
, _IOFBF
, buffer_size
);
925 if ((ptr
= strchr(cdfile
, ':')))
928 if ((ptr
= strrchr(cdfile
, '/')))
931 if ((ptr
= strrchr(cdfile
, '.')))
935 { len
= strlen(cdfile
);
937 if (!(BaseName
= malloc(len
+1)))
940 strncpy(BaseName
, cdfile
, len
);
941 BaseName
[len
] = '\0';
943 while(!feof(fp
) && (line
= newline
= ReadLine(fp
, TRUE
)))
945 if(!(cdline
= malloc(sizeof(*cdline
))))
951 cdptr
= &cdline
->Next
;
953 cdline
->Line
= line
= AllocString(newline
);
963 int CheckExtra
= TRUE
;
965 if (strnicmp(line
+1, "language", 8) == 0)
971 Language
= AllocString(line
);
975 for (ptr
= Language
; *ptr
; ptr
++)
977 *ptr
= tolower((int) *ptr
);
984 if(strnicmp(line
+1, "version", 7) == 0)
986 CatVersion
= strtol(line
+8, &line
, 0);
990 if(strnicmp(line
+1, "basename", 8) == 0)
995 BaseName
= AllocString(line
);
1000 ShowWarn(msgUnknownCDCommand
);
1011 ShowWarn(msgExtraCharacters
);
1020 if(*line
== ' ' || *line
== '\t')
1022 ShowWarn(msgUnexpectedBlanks
);
1028 while ((*line
>= 'a' && *line
<= 'z') ||
1029 (*line
>= 'A' && *line
<= 'Z') ||
1030 (*line
>= '0' && *line
<= '9') ||
1038 ShowWarn(msgNoIdentifier
);
1045 if(!(cs
= malloc(sizeof(*cs
))))
1052 struct CatString
*scs
;
1055 for(scs
= FirstCatString
; scs
!= NULL
; scs
= scs
->Next
)
1057 if(scs
->ID
== NextID
)
1075 if(!(cs
->ID_Str
= malloc((line
-idstr
)+1)))
1079 strncpy(cs
->ID_Str
, idstr
, line
-idstr
);
1080 cs
->ID_Str
[line
-idstr
] = '\0';
1086 ShowWarn(msgNoLeadingBracket
);
1092 struct CatString
*scs
;
1094 int bytesread
, reallen
;
1102 NextID
= cs
->ID
= NextID
+ strtol(line
, &line
, 0);
1106 cs
->ID
= NextID
= strtol(line
, &line
, 0);
1112 for(scs
= FirstCatString
; scs
!= NULL
; scs
= scs
->Next
)
1113 { if (scs
->ID
== cs
->ID
)
1114 { ShowWarn(msgDoubleID
);
1117 if (strcmp(cs
->ID_Str
, scs
->ID_Str
) == 0)
1118 { ShowWarn(msgDoubleIdentifier
);
1124 { ShowWarn(msgNoMinLen
);
1131 { cs
->MinLen
= strtol(line
, &line
, 0);
1135 { ShowWarn(msgNoMaxLen
);
1142 { cs
->MaxLen
= strtol(line
, &line
, 0);
1146 { ShowWarn(msgNoTrailingBracket
);
1153 { ShowWarn(msgExtraCharacters
);
1158 if (!(newline
= ReadLine(fp
, FALSE
)))
1159 { ShowWarn(msgNoString
);
1164 { cs
->CD_Str
= AllocString(newline
);
1171 oldstr
= cs
->CD_Str
;
1174 { bytesread
= ReadChar(&oldstr
, bytes
);
1178 reallen
+= bytesread
;
1181 if (cs
->MinLen
> 0 && reallen
< cs
->MinLen
)
1182 { ShowWarn(msgShortString
);
1184 if (cs
->MaxLen
> 0 && reallen
> cs
->MaxLen
)
1185 { ShowWarn(msgLongString
);
1188 cs
->Nr
= NumStrings
;
1201 /// FUNC: ScanCTFile
1204 This scans a catalog translation file.
1206 Inputs: ctfile - name of the translation file to scan.
1208 Result: TRUE, if successful, FALSE otherwise.
1210 int ScanCTFile(char *ctfile
)
1213 char *newline
, *line
, *idstr
, *newidstr
, *newstr
;
1214 struct CatString
*cs
=NULL
;
1220 if (!(fp
= fopen(ctfile
, "r")))
1222 ShowError(msgNoCatalogTranslation
, ctfile
);
1226 setvbuf(fp
, NULL
, _IOFBF
, buffer_size
);
1229 while (!feof(fp
) && (line
= newline
= ReadLine(fp
, TRUE
)))
1234 if( CopyNEWs
== TRUE
)
1236 if(strnicmp( line
, Old_Msg_New
, strlen(Old_Msg_New
) ) == 0)
1244 /// looking for command;
1245 if(*(++line
) != '#')
1247 ShowWarn(msgNoCTCommand
);
1251 if (strnicmp(line
, "version", 7) == 0)
1252 { if (CatVersionString
|| CatRcsId
|| CatName
)
1253 { ShowWarn(msgDoubleCTVersion
);
1257 CatVersionString
= AllocString(line
);
1259 else if (strnicmp(line
, "codeset", 7) == 0)
1261 CodeSet
= strtol(line
, &line
, 0);
1264 { ShowWarn(msgExtraCharacters
);
1267 else if (strnicmp(line
, "language", 8) == 0)
1271 { ShowWarn(msgDoubleCTLanguage
);
1275 CatLanguage
= AddCatalogChunk("LANG", line
);
1278 for (ptr
= CatLanguage
; *ptr
; ptr
++)
1279 *ptr
= tolower((int) *ptr
);
1281 else if (strnicmp(line
, "chunk", 5) == 0)
1287 line
+= sizeof(ULONG
);
1290 AddCatalogChunk(ID
, AllocString(line
));
1292 else if (strnicmp(line
, "rcsid", 5) == 0)
1293 { if (CatVersionString
|| CatRcsId
)
1294 { ShowWarn(msgDoubleCTVersion
);
1298 CatRcsId
= AllocString(line
);
1300 else if (strnicmp(line
, "name", 5) == 0)
1301 { if (CatVersionString
|| CatName
)
1302 { ShowWarn(msgDoubleCTVersion
);
1306 CatName
= AllocString(line
);
1308 else if (strnicmp(line
+1, "lengthbytes", 11) == 0)
1310 if ((LengthBytes
= strtol(line
, &line
, 0))
1312 { ShowWarn(msgNoLengthBytes
, sizeof(long));
1313 LengthBytes
= sizeof(long);
1318 ShowWarn(msgUnknownCTCommand
);
1324 if(*line
== ' ' || *line
== '\t')
1326 ShowWarn( msgUnexpectedBlanks
);
1331 while ((*line
>= 'a' && *line
<= 'z') ||
1332 (*line
>= 'A' && *line
<= 'Z') ||
1333 (*line
>= '0' && *line
<= '9') ||
1339 ShowWarn(msgNoIdentifier
);
1343 if(!(newidstr
= malloc(line
-idstr
+1)))
1348 strncpy(newidstr
, idstr
, line
-idstr
);
1349 newidstr
[line
-idstr
] = '\0';
1354 ShowWarn(msgExtraCharacters
);
1357 if((newstr
= ReadLine(fp
, FALSE
)))
1359 for(cs
= FirstCatString
; cs
!= NULL
; cs
= cs
->Next
)
1361 if(strcmp(cs
->ID_Str
, newidstr
) == 0)
1368 ShowWarn(msgUnknownIdentifier
, newidstr
);
1374 int bytesread
, reallen
;
1378 ShowWarn(msgDoubleIdentifier
);
1382 cs
->CT_Str
= AllocString(newstr
);
1383 cs
->NotInCT
= FALSE
;
1388 oldstr
= cs
->CT_Str
;
1392 bytesread
= ReadChar(&oldstr
, bytes
);
1397 reallen
+= bytesread
;
1400 if(cs
->MinLen
> 0 && reallen
< cs
->MinLen
)
1402 ShowWarn(msgShortString
);
1404 if(cs
->MaxLen
> 0 && reallen
> cs
->MaxLen
)
1406 ShowWarn(msgLongString
);
1410 // checking for trailing ellipsis...
1414 long cd_len
= strlen( cs
->CD_Str
);
1418 if( strcmp( &cs
->CD_Str
[ cd_len
- 2 ], "..." ) == 0 )
1419 if( strcmp( &cs
->CT_Str
[ reallen
- 2 ], "..." ) != 0 )
1421 // printf("ORG: '%s'\nNEW: '%s'\n", cs->CD_Str, cs->CT_Str);
1422 ShowWarn(msgTrailingEllipsis
);
1428 // checking for trailing spaces
1432 long cd_len
= strlen( cs
->CD_Str
);
1436 if( strcmp( &cs
->CD_Str
[ cd_len
- 1 ], " " ) == 0 )
1437 if( strcmp( &cs
->CT_Str
[ reallen
- 1 ], " " ) != 0 )
1438 ShowWarn(msgTrailingSpaces
);
1448 ShowWarn(msgNoString
);
1460 { for (cs
= FirstCatString
; cs
!= NULL
; cs
= cs
->Next
)
1461 { if (cs
->CT_Str
== NULL
)
1462 { ShowWarn(msgCTGap
, cs
->ID_Str
);
1477 CatPuts prints a string to a catalog. (The string is preceded by a
1478 long integer containing its length and probably padded up to word
1479 boundary or longword boundary, depending on the argument padbytes.)
1480 The arguments countnul should be TRUE if the NUL byte at the end of
1481 the string should be counted.
1483 int CatPuts(FILE *fp
, char *str
, int padbytes
, int countnul
)
1485 unsigned long reallen
, virtuallen
, chunklen
, swapped_long
;
1490 /* Get Length of string.
1498 bytesread
= ReadChar(&oldstr
, bytes
);
1503 reallen
+= bytesread
;
1506 virtuallen
= chunklen
= reallen
+ LengthBytes
;
1507 if(countnul
|| chunklen
% padbytes
== 0)
1512 swapped_long
= SwapLong( virtuallen
);
1514 fwrite(&swapped_long
, sizeof(virtuallen
), 1, fp
);
1517 fwrite(((char *) &reallen
)+sizeof(reallen
)-LengthBytes
, LengthBytes
, 1, fp
);
1522 bytesread
= ReadChar(&str
, bytes
);
1525 fwrite(bytes
+bytesread
-1, 1, 1, fp
);
1533 while(++chunklen
% padbytes
);
1535 return((int) chunklen
+4);
1538 /// FUNC: PutCatalogChunk
1541 This puts a string chunk into the catalog
1543 int PutCatalogChunk(FILE *fp
, struct CatalogChunk
*cc
)
1545 fwrite(&cc
->ID
, sizeof(cc
->ID
), 1, fp
);
1546 return(4 + CatPuts(fp
, cc
->ChunkStr
, 2, TRUE
));
1549 /// FUNC: CalcRealLength
1551 This function measures the real (binary) length of source
1552 string. It correctly process 'slash chars' (\n, \000 etc),
1553 and gives the real length such source string have.
1555 Inputs: source - pointer to null terminated source string
1560 int CalcRealLength(char *source
)
1568 count
+= ReadChar(&src
, bytes
);
1571 // printf("%ld: '%s'\n", count, source);
1578 /// FUNC: CreateCatalog
1581 This creates a catalog.
1583 void CreateCat(char *CatFile
)
1586 int CatLen
, HeadLen
;
1587 struct CatString
*cs
;
1588 struct CatalogChunk
*cc
;
1591 if(!CatVersionString
&& !CatRcsId
)
1593 ShowError(msgNoCTVersion
);
1598 ShowError(msgNoCTLanguage
);
1601 if(strlen(CatLanguage
) == 0)
1603 ShowError(msgNoCTLanguage
);
1606 if(!(fp
= fopen(CatFile
, "w")))
1608 ShowError(msgNoCatalog
, CatFile
);
1612 setvbuf(fp
, NULL
, _IOFBF
, buffer_size
);
1615 fputs("FORM0000CTLG", fp
);
1618 if(CatVersionString
)
1620 struct CatalogChunk cc
;
1621 char *verStr
= NULL
;
1623 cc
.ID
= MAKE_ID('F','V','E','R');
1625 if( strstr(CatVersionString
, "$TODAY") )
1628 if(verStr
= malloc(strlen(CatVersionString
)+128))
1630 char *found
= strstr(CatVersionString
, "$TODAY");
1640 strftime(dateStr
, sizeof(dateStr
), "%d.%m.%y", t
);
1642 sprintf(verStr
, "%s%s%s", CatVersionString
, dateStr
, found
+strlen("$TODAY"));
1643 cc
.ChunkStr
= verStr
;
1651 cc
.ChunkStr
= CatVersionString
;
1654 cc
.ID
= SwapLong( cc
.ID
);
1655 CatLen
+= PutCatalogChunk(fp
, &cc
);
1662 struct CatalogChunk cc
;
1664 int year
= 0, month
= 0, day
= 0;
1665 int version
= 0, revision
= 0;
1671 ShowError(msgNoCTVersion
);
1675 if(!(ptr
= strstr(CatRcsId
, "$Date:"))
1676 || sscanf(ptr
+6, " %d/%d/%d", &year
, &month
, &day
) != 3
1677 || !(ptr
= strstr(CatRcsId
, "$Revision:"))
1678 || sscanf(ptr
+10, " %d.%d", &version
, &revision
) != 2)
1680 ShowError(msgWrongRcsId
);
1682 if ((ptr
= strstr(CatRcsId
, "$Id:")))
1690 while(*ptr
&& *ptr
!= '$' && *ptr
!= ' ' && *ptr
!= '\t')
1695 if(!(name
= malloc(len
+1)))
1699 strncpy(name
, found
, len
);
1708 ShowError(msgNoCTVersion
);
1711 if (!(verStr
= malloc(strlen(name
) + 256)))
1716 sprintf(verStr
, "$V");
1717 sprintf(verStr
, "ER: %s %ld.%ld (%ld.%ld.%ld)", name
, version
, revision
, day
, month
, year
);
1719 cc
.ID
= MAKE_ID('F','V','E','R');
1720 cc
.ID
= SwapLong( cc
.ID
);
1721 cc
.ChunkStr
= verStr
;
1722 CatLen
+= PutCatalogChunk(fp
, &cc
);
1726 for (cc
= FirstChunk
; cc
!= NULL
; cc
= cc
->Next
)
1728 CatLen
+= PutCatalogChunk(fp
, cc
);
1735 int i_tmp
= SwapLong( i
);
1737 fwrite(&i_tmp
, sizeof(i_tmp
), 1, fp
);
1746 fprintf(fp
, "STRS0000");
1750 for(cs
= FirstCatString
; cs
!= NULL
; cs
= cs
->Next
)
1752 int FillUsed
= FALSE
;
1753 int tmp_ID
= SwapLong( cs
->ID
);
1760 if(strlen(cs
->CT_Str
) == 0)
1762 fwrite(&tmp_ID
, sizeof(tmp_ID
), 1, fp
);
1763 CatLen
+= 4 + CatPuts(fp
, cs
->CD_Str
, 4, FALSE
);
1769 fwrite(&tmp_ID
, sizeof(cs
->ID
), 1, fp
);
1770 CatLen
+= 4 + CatPuts(fp
, cs
->CD_Str
, 4, FALSE
);
1775 if((!FillUsed
) && cs
->CT_Str
&& (NoOptim
? TRUE
: strcmp(cs
->CT_Str
, cs
->CD_Str
)))
1777 fwrite(&tmp_ID
, sizeof( tmp_ID
), 1, fp
);
1778 CatLen
+= 4 + CatPuts(fp
, cs
->CT_Str
, 4, FALSE
);
1786 fseek(fp
, 4, SEEK_SET
);
1788 tmp_Len
= SwapLong( CatLen
);
1789 fwrite(&tmp_Len
, sizeof(tmp_Len
), 1, fp
);
1790 fseek(fp
, HeadLen
-4, SEEK_CUR
);
1793 tmp_Len
= SwapLong( CatLen
);
1794 fwrite(&tmp_Len
, sizeof(CatLen
), 1, fp
);
1803 /// FUNC: CreateCTFile
1806 This creates a new catalog translation file.
1808 void CreateCTFile(char *NewCTFile
)
1812 struct CatString
*cs
;
1813 struct CatalogChunk
*cc
;
1816 if(!CatVersionString
&& !CatRcsId
)
1819 ShowWarn(msgNoCTVersion
);
1822 if(!(fp
= fopen(NewCTFile
, "w")))
1824 ShowError(msgNoNewCTFile
);
1829 setvbuf(fp
, NULL
, _IOFBF
, buffer_size
);
1834 fprintf(fp
, "## rcsid %s\n",
1835 CatRcsId
? CatRcsId
: "");
1837 fprintf(fp
, "## name %s\n", CatName
);
1841 if(CatVersionString
)
1842 fprintf(fp
, "## version %s\n", CatVersionString
);
1845 fprintf(fp
, "## version $V");
1846 fprintf(fp
, "%c", 50+19); // E
1847 fprintf(fp
, "R: XX.catalog XX.XX ($TODAY)\n");
1855 if(CatLanguage
== NULL
)
1856 if(lang
= getenv("ENV:language"))
1860 for(i
=0;i
<strlen(lang
); i
++)
1870 fprintf(fp
, "## language %s\n## codeset %d\n;\n",
1871 CatLanguage
? CatLanguage
: "X", CodeSet
);
1882 for (cc
= FirstChunk
; cc
!= NULL
; cc
= cc
->Next
)
1884 if (cc
->ChunkStr
!= CatLanguage
)
1886 fprintf(fp
, "## chunk ");
1887 fwrite((char *) &cc
->ID
, sizeof(cc
->ID
), 1, fp
);
1888 fprintf(fp
, " %s\n", cc
->ChunkStr
);
1892 for(cd
= FirstCDLine
, cs
= FirstCatString
;
1902 fprintf(fp
, "%s\n", cd
->Line
);
1909 fprintf(fp, "%s\n", cs->ID_Str);
1910 fprintf(fp, "%s\n", cs->CT_Str ? cs->CT_Str : "");
1914 fprintf(fp
, "%s\n%s\n;", cs
->ID_Str
, cs
->CT_Str
? cs
->CT_Str
: "");
1921 for (line
= cs
->CD_Str
; *line
; ++line
)
1923 putc((int) *line
, fp
);
1933 if(cs
->NotInCT
&& CT_Scanned
)
1934 fprintf(fp
, ";\n; %s\n", Msg_New
);
1945 /// FUNC: InitCatStringOutput
1948 InitCatStringOutput gets called before writing a catalog string as
1951 Inputs: fp = file pointer to the output file
1952 type = one of TYPE_C create C strings
1953 TYPE_ASSEMBLER create Assembler strings
1954 TYPE_OBERON create Oberon strings
1955 TYPE_E create E strings
1956 TYPE_NONE create simple strings
1958 int OutputMode
= OutputMode_None
;
1959 int OutputType
= TYPE_C
;
1963 void InitCatStringOutput(FILE *fp
)
1967 OutputMode
= OutputMode_None
;
1972 OutputMode
= OutputMode_Ascii
;
1976 case TYPE_ASSEMBLER
:
1982 /// FUNC: SeparateCatStringOutput
1985 SeparateCatStringOutput gets called to split a catalog into separate
1988 void SeparateCatStringOutput(void)
1993 { fputs("\"\\\n\t\"", OutputFile
);
1998 { fputs("\' +\n\t\'", OutputFile
);
2003 { fputs("\"\n\t\"", OutputFile
);
2006 case TYPE_ASSEMBLER
:
2008 { if (OutputMode
== OutputMode_Ascii
)
2009 { putc('\'', OutputFile
);
2011 putc('\n', OutputFile
);
2012 OutputMode
= OutputMode_None
;
2020 /// FUNC: WriteBinChar
2023 WriteBinChar writes one binary character into the source file
2025 void WriteBinChar(int c
)
2034 fputs("\\b", OutputFile
);
2037 fputs("\\n", OutputFile
);
2040 fputs("\\r", OutputFile
);
2043 fputs("\\t", OutputFile
);
2046 fputs("\\f", OutputFile
);
2049 fputs("\\000", OutputFile
);
2052 if(OutputType
== TYPE_E
&& c
== '\033')
2054 fputs("\\e", OutputFile
);
2058 fprintf(OutputFile
, "\\%c%c%c", ((c
>> 6) & 3) + '0',
2059 ((c
>> 3) & 7) + '0', (c
& 7) + '0');
2064 OutputMode
= OutputMode_Bin
;
2066 case TYPE_ASSEMBLER
:
2068 { case OutputMode_None
:
2069 fprintf(OutputFile
, "\tdc.b\t$%02x", c
& 0xff);
2071 case OutputMode_Ascii
:
2072 putc('\'', OutputFile
);
2073 case OutputMode_Bin
:
2074 fprintf(OutputFile
, ",$%02x", c
& 0xff);
2078 OutputMode
= OutputMode_Bin
;
2081 ShowWarn(msgNoBinChars
);
2086 /// FUNC: WriteAsciiChar
2089 WriteAsciiChar writes one ascii character into the source file.
2091 void WriteAsciiChar(int c
)
2099 fputs("\\\"", OutputFile
);
2102 putc(c
, OutputFile
);
2106 OutputMode
= OutputMode_Ascii
;
2111 fputs("''", OutputFile
);
2114 putc(c
, OutputFile
);
2118 OutputMode
= OutputMode_Ascii
;
2120 case TYPE_ASSEMBLER
:
2125 { switch (OutputMode
)
2126 { case OutputMode_None
:
2127 fprintf(OutputFile
, "\tdc.b\t\'%c", c
);
2129 case OutputMode_Ascii
:
2130 putc(c
, OutputFile
);
2132 case OutputMode_Bin
:
2133 fprintf(OutputFile
, ",\'%c", c
);
2137 OutputMode
= OutputMode_Ascii
;
2141 putc(c
, OutputFile
);
2146 /// FUNC: TerminateCatStringOutput
2149 TerminateCatStringOutput finishs the output of a catalog string.
2151 void TerminateCatStringOutput(void)
2156 putc('\"', OutputFile
);
2159 putc('\'', OutputFile
);
2161 case TYPE_ASSEMBLER
:
2163 { case OutputMode_Ascii
:
2164 putc('\'', OutputFile
);
2165 case OutputMode_Bin
:
2167 case OutputMode_None
:
2176 /// FUNC: WriteString
2178 This writes a sourcestring.
2180 void WriteString(FILE *fpout
, char *str
, long Len
)
2184 int needseparate
= FALSE
;
2186 InitCatStringOutput(fpout
);
2190 for(i
= LengthBytes
; i
>= 1; i
--)
2191 { WriteBinChar((int) ((char *) &Len
)[sizeof(Len
)-i
]);
2196 { bytesread
= ReadChar(&str
, bytes
);
2201 { SeparateCatStringOutput();
2202 needseparate
= FALSE
;
2205 c
= bytes
[bytesread
-1];
2206 if ((c
>= 0x20 && c
< 0x7f) || c
>= 0xa0)
2207 { WriteAsciiChar((int) c
);
2210 { WriteBinChar((int) c
);
2214 { needseparate
= TRUE
;
2217 TerminateCatStringOutput();
2220 /// FUNC: AllocFileName
2222 This function creates a copy of a filename, removes an
2223 optional ending and pathname components, if desired.
2225 Inputs: filename - the filename to copy
2226 howto - a set of bits
2227 bit 0: 1 = remove ending, 0 = leave it
2228 bit 1: 1 = remove pathname, 0 = leave it
2230 Result: The copy of the filename
2232 char *AllocFileName(char *filename
, int howto
)
2234 char *tempstr
, *ptr
;
2236 if (!(tempstr
= strdup(filename
)))
2241 /* Remove pathname components, if desired */
2243 { if ((ptr
= strchr(tempstr
, ':')))
2246 if ((ptr
= strrchr(tempstr
, '/')))
2251 /* Remove ending, if desired. */
2253 { if ((ptr
= strrchr(tempstr
, '.')))
2261 /// FUNC: AddFileName
2263 This function adds a pathname and a filename to a full
2266 Inputs: pathname - the leading pathname
2267 filename - the filename
2269 Result: The new filename
2271 char *AddFileName(char *pathname
, char *filename
)
2274 int size
= strlen(pathname
) + strlen(filename
) + 2;
2276 if (!(buffer
= malloc(size
)))
2281 #if defined(__amigados)
2282 strcpy(buffer
, pathname
);
2283 AddPart((char *) buffer
, (char *) filename
, size
);
2285 sprintf(buffer
, "%s/%s", pathname
, filename
);
2292 /// FUNC: CreateSourceFile
2295 Finally the source creation.
2297 void CreateSourceFile(char *SourceFile
, char *TemplateFile
, char *CDFile
)
2302 char *OrigTemplateFile
= TemplateFile
;
2304 ScanFile
= SourceFile
;
2308 Open the source file. This may be found in various places
2310 if(!(fpin
= fopen(TemplateFile
, "r")))
2313 if(*prefs_sddir
!= 0)
2315 TemplateFile
= AddFileName(prefs_sddir
, OrigTemplateFile
);
2316 fpin
= fopen(TemplateFile
, "r");
2325 if((sddir
= getenv(FLEXCAT_SDDIR
)))
2327 TemplateFile
= AddFileName(sddir
, OrigTemplateFile
);
2328 fpin
= fopen(TemplateFile
, "r");
2333 { TemplateFile
= AddFileName(DEFAULT_FLEXCAT_SDDIR
, OrigTemplateFile
);
2334 fpin
= fopen(TemplateFile
, "r");
2339 ShowError(msgNoSourceDescription
, OrigTemplateFile
);
2343 if (!(fpout
= fopen(SourceFile
, "w")))
2345 ShowError(msgNoSource
, SourceFile
);
2350 setvbuf(fpin
, NULL
, _IOFBF
, buffer_size
);
2352 setvbuf(fpout
, NULL
, _IOFBF
, buffer_size
);
2355 while(!feof(fpin
) && (line
= ReadLine(fpin
, FALSE
)))
2356 { struct CatString
*cs
;
2361 cs
= FirstCatString
;
2363 { char *currentline
= line
;
2366 if (*currentline
== '#' && *(++currentline
) == '#')
2368 OverSpace(¤tline
);
2370 if(strnicmp( currentline
, "rem", 3 ) == 0)
2372 // we just skip this line
2376 if (strnicmp(currentline
, "stringtype", 10) == 0)
2377 { currentline
+= 10;
2378 OverSpace(¤tline
);
2379 if (strnicmp(currentline
, "c", 1) == 0)
2380 { OutputType
= TYPE_C
;
2383 else if (strnicmp(currentline
, "assembler", 9) == 0)
2384 { OutputType
= TYPE_ASSEMBLER
;
2387 else if (strnicmp(currentline
, "oberon", 6) == 0)
2388 { OutputType
= TYPE_OBERON
;
2391 else if (strnicmp(currentline
, "e", 1) == 0)
2392 { OutputType
= TYPE_E
;
2395 else if (strnicmp(currentline
, "none", 4) == 0)
2396 { OutputType
= TYPE_NONE
;
2400 { ShowWarn(msgUnknownStringType
);
2401 currentline
+= strlen(currentline
);
2403 OverSpace(¤tline
);
2405 { ShowWarn(msgExtraCharacters
);
2409 else if (strnicmp(currentline
, "shortstrings", 12) == 0)
2410 { currentline
+= 12;
2411 LongStrings
= FALSE
;
2412 OverSpace(¤tline
);
2414 { ShowWarn(msgExtraCharacters
);
2422 { bytesread
= ReadChar(¤tline
, bytes
);
2424 { if (*bytes
== '%')
2427 switch(c
= *(currentline
++))
2429 fputs(BaseName
, fpout
);
2432 fprintf(fpout
, "%d", NumStrings
);
2435 fprintf(fpout
, "%d", CatVersion
);
2438 WriteString(fpout
, Language
, -1);
2443 if ((c
= *currentline
++) == 'v')
2444 { fputs(VERS
, fpout
);
2447 { tempstr
= AllocFileName(CDFile
, c
- '0');
2448 fputs(tempstr
, fpout
);
2455 tempstr
= AllocFileName(SourceFile
, *currentline
++ - '0');
2456 fputs(tempstr
, fpout
);
2461 if (cs
) fputs(cs
->ID_Str
, fpout
);
2483 while(c
>= '0' && c
<= '9')
2485 len
= (c
- '0') + len
* 10;
2492 int _len
= len
? len
: 4;
2494 char _StrLen
[20 + 1];
2496 sprintf(_StrLen
, "%020lx", cs
->ID
);
2498 start
= &_StrLen
[20-_len
*2];
2501 fprintf(fpout
, "\\x%.2s", start
);
2509 int _len
= len
? len
: 4;
2511 char _StrLen
[20 + 1];
2513 sprintf(_StrLen
, "%020lx", ((CalcRealLength(cs
->CD_Str
) + 1) & 0xfffffe));
2515 start
= &_StrLen
[20-_len
*2];
2518 fprintf(fpout
, "\\x%.2s", start
);
2524 if(c
== 'c' || c
== 'd' || c
== 'x')
2528 if(c
== 'c') c
= 'o';
2531 sprintf(buffer
, "%%0%d%c", len
, c
);
2533 sprintf(buffer
, "%%%c", c
);
2535 if(cs
) fprintf(fpout
, buffer
, cs
->ID
);
2545 if (cs
) fprintf(fpout
, "%d", cs
->Nr
);
2551 unsigned long len
= 0;
2554 { idstr
= cs
->CD_Str
;
2556 { bytesread
= ReadChar(&idstr
, bytes
);
2562 WriteString(fpout
, cs
->CD_Str
, LengthBytes
? len
: -1);
2567 while(*currentline
&& *currentline
!= ')')
2568 { bytesread
= ReadChar(¤tline
, bytes
);
2569 if (bytesread
&& cs
&& cs
->Next
)
2570 { putc((int) bytes
[bytesread
-1], fpout
);
2574 { ShowWarn(msgNoTerminateBracket
);
2585 int diff
= (((CalcRealLength(cs
->CD_Str
) + 1) & 0xfffffe) - (CalcRealLength(cs
->CD_Str
)));
2591 fprintf(fpout
, "\\x00");
2599 { int c
= *currentline
++;
2606 { putc((int) bytes
[bytesread
-1], fpout
);
2612 while(NeedRepeat
&& cs
&& (cs
= cs
->Next
));
2624 The Usage function describes the programs calling syntax.
2629 fputs((char *) msgUsageHead
, stderr
);
2630 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
);
2631 fprintf(stderr
, "%s\n%s\n%s\n%s\n", msgUsage
, msgUsage_2
, msgUsage_3
, msgUsage_4
);
2632 fprintf(stderr
, "\n\n%s"
2657 fprintf(stderr
, "%s\n", EString
);
2663 Finally the main function. Does nothing special except for scanning
2666 int main(int argc
, char *argv
[])
2668 char *cdfile
, *ctfile
, *newctfile
, *catalog
;
2669 char *source
, *template;
2672 if(argc
== 0) /* Aztec's entry point for workbench programs */
2674 fprintf(stderr
, "FlexCat can't be run from Workbench!\n\n");
2675 fprintf(stderr
, "Open a Shell session and type FlexCat ?\n");
2676 fprintf(stderr
, "for more information\n");
2680 cdfile
= ctfile
= newctfile
= catalog
= NULL
;
2683 /* let's open catalog files by hand if necessary */
2684 /* should be done automatically anyway for most */
2685 /* cases, but, that depends on compiler... */
2688 // STATIC __autoinit VOID _STIOpenFlexCatCatalog(VOID)
2689 #elif defined(__SASC)
2690 // VOID _STIOpenFlexCatCatalog(VOID)
2691 #elif defined(__GNUC__)
2692 // VOID _STIOpenFlexCatCatalog(VOID)
2693 #elif defined(__INTEL_COMPILER)
2694 // VOID _STIOpenFlexCatCatalog(VOID)
2696 OpenFlexCatCatalog(); /* no autoopen. we do it then */
2700 // Big Endian vs Little Endian (both supported ;-)
2703 fprintf(stderr
, "FlexCat is unable to determine the\n");
2704 fprintf(stderr
, "the byte order used by your system.\n");
2705 fprintf(stderr
, "It's neither Little nor Big Endian?!.\n");
2711 #if defined(__amigados)
2720 for (i
= 1; i
< argc
; i
++)
2722 if(strnicmp (argv
[i
], "catalog=", 8) == 0)
2724 catalog
= argv
[i
] + 8;
2727 if(stricmp (argv
[i
], "catalog") == 0)
2731 catalog
= argv
[++i
];
2734 if(stricmp(argv
[i
], "nooptim") == 0)
2739 if(stricmp(argv
[i
], "fill") == 0)
2744 if(stricmp(argv
[i
], "quiet") == 0)
2749 if(stricmp(argv
[i
], "flush") == 0)
2754 if(stricmp(argv
[i
], "nobeep") == 0)
2759 if(stricmp(argv
[i
], "nobufferedio") == 0)
2761 NoBufferedIO
= TRUE
;
2764 if (strnicmp (argv
[i
], "newctfile=", 10) == 0)
2766 newctfile
= argv
[i
] + 10;
2769 if(strnicmp (argv
[i
], "newctfile", 9) == 0)
2773 newctfile
= argv
[++i
];
2776 if(stricmp(argv
[i
], "nolangtolower") == 0)
2778 LANGToLower
= FALSE
;
2781 if(stricmp(argv
[i
], "modified") == 0)
2786 if(stricmp(argv
[i
], "warnctgaps") == 0)
2791 if(stricmp(argv
[i
], "copymsgnew") == 0)
2796 if(stricmp(argv
[i
], "nospace") == 0)
2801 if(stricmp(argv
[i
], "oldmsgnew") == 0)
2803 sprintf( Old_Msg_New
, "; %s", argv
[++i
] );
2808 if(stricmp(argv
[i
], "?") == 0 || stricmp(argv
[i
], "-h") == 0 || stricmp(argv
[i
], "help") == 0 || stricmp(argv
[i
], "--help") == 0)
2812 if(!ScanCDFile(cdfile
= argv
[i
]))
2818 if(strchr(argv
[i
], '='))
2820 source
= AllocString(argv
[i
]);
2821 *(template = strchr(source
, '=')) = '\0';
2824 CreateSourceFile(source
, template, cdfile
);
2837 #if defined(__amigados)
2840 if(cdfile
&& ctfile
&& catalog
)
2842 long cd_time
, ct_time
, cat_time
;
2844 if((cd_time
= getft(cdfile
)) != -1)
2846 if((ct_time
= getft(ctfile
)) != -1)
2848 if((cat_time
= getft(catalog
)) == -1)
2851 if((cat_time
> ct_time
) &&
2852 (cat_time
> cd_time
))
2856 fprintf(stderr
, (char *) msgUpToDate
, catalog
);
2860 MyExit(GlobalReturnCode
);
2866 fprintf(stderr
, "--> %s", catalog
);
2873 ShowError(msgCantCheckDate
, ctfile
);
2878 ShowError(msgCantCheckDate
, cdfile
);
2886 if(!ScanCTFile(ctfile
))
2894 fprintf(stderr
, (char *) msgNoCTArgument
);
2902 CreateCTFile(newctfile
);
2905 MyExit(GlobalReturnCode
);
2911 Dice's entry point for workbench programs
2913 #if defined(__amigados) && defined(_DCC)
2914 void wbmain(struct WBStartup
*wbmsg
)
2916 fprintf(stderr
, "FlexCat can't be run from Workbench!\n\n");
2917 fprintf(stderr
, "Open a Shell session and type FlexCat\n");
2918 fprintf(stderr
, "for syntax and more information\n");