home *** CD-ROM | disk | FTP | other *** search
- /*
- FlexCat.c: The flexible catalog creator V 1.2
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-
-
- Ok, this is nothing special. It grabs a catalog translation and a
- catalog description file and produces catalogs and the source to
- handle 'em. What is it else than lots of other programs?
-
- The difference is, that YOU determine what source FlexCat produces.
- Another file is scanned by FlexCat to produce code. This file contains
- some c-string like special characters (%v for version for example)
- You can edit this file and modify it as you want. So FlexCat can produce
- C source as well as Assembler, Oberon, Modula 2, E, ...
-
- Command line syntax:
-
- FlexCat CDFILE/A,CTFILE,NEWCTFILE/K,CATALOG/K,ASSEMBLER/S,SOURCES/M
-
- CDFILE - the name of the catalog description file; see CatComp for
- syntax
- CTFILE - the name of a catalog translation file; see CatComp for
- syntax
- NEWCTFILE - the name of a catalog transcription file to be created
- (will be a copy of CDFILE except that the strings remain
- empty and will be put as comments behind the string
- definition)
- CATALOG - the name of the catalog to be created; default is the
- basename of the CDFILE and .catalog appended
- SOURCES - the sourcefiles to be created. These arguments take a special
- form: sourcefile=templatefile where sourcefile is the
- name of the file to create and templatefile is the name of
- a template file containing some special patterns. The
- template file will be scanned and written to the source
- file with these special patterns replaced by certain
- strings. Possible patterns are:
-
- %b basename of CDFILE (for example "file", if
- CDFILE is "file.cd")
- %v version
- %l language (of CDFILE)
- %n number of catalog strings
- %% the percent sign itself
-
- The following patterns indicate, that the line should be
- repeated for each catalog string.
- %i the string's ID descriptor
- %d the string's ID
- %s the string itself
- %(...) indicates that anything between the brackets
- should appear for any line except the last
- (Oberon and Modula need a "," to separate array
- entries, but the last entry must not be
- terminated by a ",". So you would terminate an
- array entry by a %(,).)
-
- Example: Let the string description be
-
- MSG_HELLO (5//)
- Hello!
-
- Then the special characters produce
- %i = MSG_HELLO
- %d = 5
- %s = "Hello!"
-
- Additionally the following characters may appear (as well as in the
- catalog description and catalog translation file)
- \b = Backspace (Ascii 8)
- \c = Control sequence introducer (Ascii 155)
- \e = Escape (Ascii 27)
- \f = Form feed (Ascii 12)
- \g = Display beep (Ascii 7)
- \n = line feed, newline (Ascii 10)
- \r = carriage return (Ascii 13)
- \t = Tab (Ascii 9)
- \v = Vertical tab (Ascii 11)
- \) = the character ')' (Needed inside %(..))
- \\ = the backslash itself
- \xHH = Ascii code HH (where HH are hex digits)
- \OOO = Ascii code OOO (where OOO are octal digits)
-
- A backslash at the end of a line indicates that the line should be
- concatenated with the next one.
-
-
- Computer: Amiga 1200 Compiler: Dice, 2.07.54R
-
- Author: V 1.0 31.06.1993 Jochen Wiedmann
- Am Eisteich 9
- 72555 Metzingen
- Tel. 07123 / 14881
-
- Internet: wiedmann@mailserv.zdv.uni-tuebingen.de
-
- V1.01 Fixed a bug: The length of the source string
- was used to check for the stringlen instead of
- the real stringlen.
-
- V1.1 Fixed two bugs: FlexCat didn't notice, if an
- ID was defined twice (C-Compiler did later.) and
- using language strings like français did not work
- because of the the accented char. Introduced E
- support. (Thanks Lionel Vintenat)
-
- V1.2 Fixed a bug in the E source generator: " was
- converted into \" and ' was not converted.
- */
-
-
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- #ifdef AMIGA
- #include <exec/types.h>
- #include <clib/exec_protos.h>
- #include <clib/utility_protos.h>
- #include "FlexCat_cat.h"
-
- #ifdef AZTEC_C
- #include <pragmas/exec_lib.h>
- #include <pragmas/utility_lib.h>
- #endif
-
- #if defined(_DCC) || defined(__SASC) || defined(__MAXON__)
- #include <pragmas/exec_pragmas.h>
- #include <pragmas/utility_pragmas.h>
- #endif
-
- #ifdef __GNUC__
- #include <inline/exec.h>
- #include <inline/utility.h>
- #endif
-
- #define tolower ToLower
-
- #endif
-
-
- #ifndef FALSE
- #define FALSE 0
- #endif
- #ifndef TRUE
- #define TRUE (!FALSE)
- #endif
-
-
- enum StringTypes {
- TYPE_C, /* Produce C strings */
- TYPE_ASSEMBLER, /* Produce Assembler strings */
- TYPE_OBERON, /* Produce Oberon strings */
- TYPE_E, /* Produce E strings. (Oops, thought */
- /* it allows only 32 bit integers? ;-) */
- TYPE_NONE /* Simple strings */
- };
-
-
- enum OutputModes {
- OutputMode_None, /* Nothing written yet */
- OutputMode_Bin, /* Last character written was binary */
- OutputMode_Ascii /* Last character written was Ascii */
- };
-
- struct CatString
- { struct CatString *Next;
- char *CD_Str;
- char *CT_Str;
- char *ID_Str;
- int MinLen, MaxLen, ID;
- };
-
- struct CDLine
- { struct CDLine *Next;
- char *Line;
- };
-
-
- struct CatString *FirstCatString = NULL; /* First catalog string */
- struct CDLine *FirstCDLine = NULL; /* First catalog description line */
-
- char *BaseName = ""; /* Basename of catalog description */
- char *Language = "english"; /* Language of catalog description */
- int CatVersion = 0; /* Version of catalog to be opened */
- int LengthBytes = 0; /* Number of bytes to preceed a */
- /* created string and containing */
- /* its length. */
- char *CatLanguage = NULL; /* Language of catalog translation */
- char *CatVersionString = NULL; /* version string of catalog */
- /* translation */
- int CodeSet = 0; /* Codeset of catalog translation */
- int NumStrings = 0; /* Number of catalog strings */
- int LongStrings = TRUE; /* Generate long or short strings */
-
-
- char *ScanFile; /* File currently scanned */
- int ScanLine; /* Line currently scanned */
-
- struct Library *LocaleBase = NULL;
- struct Library *UtilityBase = NULL;
- extern struct ExecBase *SysBase;
-
-
-
-
-
- const UBYTE VERSION[] = "$VER: FlexCat 1.2 (19.04.94) by Jochen Wiedmann";
-
-
-
-
- /*
- This terminates the program.
- */
- void Cleanup(int result)
-
- {
- #ifdef AMIGA
- CloseFlexCatCatalog();
- if (LocaleBase)
- { CloseLibrary(LocaleBase);
- }
- if (UtilityBase)
- { CloseLibrary(UtilityBase);
- }
- #endif
- exit(result);
- }
-
- /*
- This shows an error message and terminates
- */
- struct RDArgs *Args;
- void ShowError(const STRPTR msg, ...)
-
- { fprintf(stderr, (char *) msg, (&msg)[1], (&msg)[2], (&msg)[3], (&msg)[4]);
- putc('\n', stderr);
- Cleanup(10);
- }
-
-
-
- /*
- This shows the message: Memory error.
- */
- void MemError(void)
-
- { ShowError(GetFlexCatString(msgMemoryError), NULL);
- }
-
-
-
-
- /*
- This shows a warning
- */
- void ShowWarn(STRPTR msg, ...)
-
- { fprintf(stderr, (char *) GetFlexCatString(msgWarning), ScanFile, ScanLine);
- fprintf(stderr, (char *) msg, (&msg)[1], (&msg)[2], (&msg)[3], (&msg)[4]);
- putc('\n', stderr);
- }
-
-
-
-
- /*
- This allocates a string
- */
- char *AllocString(const char *str)
-
- { char *ptr;
-
- if (!(ptr = malloc(strlen(str)+1)))
- { MemError();
- }
- strcpy(ptr, str);
- return(ptr);
- }
-
-
-
-
- /*
- This translates a hex character.
- */
- int gethex(int c)
-
- {
- if (c >= '0' && c <= '9')
- { return(c - '0');
- }
- else if (c >= 'a' && c <= 'f')
- { return(c - 'a' + 10);
- }
- else if (c >= 'A' && c <= 'F')
- { return(c - 'A' + 10);
- }
- ShowWarn(GetFlexCatString(msgExpectedHex));
- return(0);
- }
-
-
-
-
- /*
- This translates an octal digit.
- */
- int getoctal(int c)
-
- {
- if (c >= '0' && c <= '7')
- { return(c - '0');
- }
- ShowWarn(GetFlexCatString(msgExpectedOctal));
- return(0);
- }
-
-
-
-
- /*
- Reading a line is somewhat compicated in order to allow lines of any
- length.
-
- Inputs: fp - the file, where the input comes from
- AllowComment - TRUE, if a leading semicolon should force to
- interpret the line as a comment line
- */
- #define BUFSIZE 4096
- char *ReadLine(FILE *fp, int AllowComment)
-
- { char *OldLine, *NewLine = NULL;
- int c = '\0';
- int Len = 0, LineLen = 0;
- int CommentLine = FALSE, FirstChar = TRUE;
- int BackslashSeen = FALSE;
-
- while (c != EOF)
- { if (Len+10 > LineLen)
- { OldLine = NewLine;
- if (!(NewLine = malloc(LineLen+BUFSIZE)))
- { MemError();
- }
- strncpy(NewLine, OldLine, LineLen);
- if (OldLine)
- { free(OldLine);
- }
- LineLen += BUFSIZE;
- }
-
- c = getc(fp);
- if (FirstChar)
- { if (c == ';')
- { CommentLine = TRUE;
- }
- if (c == EOF)
- { free(NewLine);
- return(NULL);
- }
- FirstChar = FALSE;
- }
-
- switch(c)
- { case '\r':
- break;
- case '\n':
- ++ScanLine;
- if (BackslashSeen)
- { NewLine[Len++] = c;
- BackslashSeen = FALSE;
- break;
- }
- c = EOF;
- case EOF:
- break;
- case '\\':
- BackslashSeen = TRUE;
- NewLine[Len++] = c;
- break;
- default:
- BackslashSeen = FALSE;
- NewLine[Len++] = c;
- }
- }
- NewLine[Len++] = '\0';
-
- return(NewLine);
- }
-
-
-
-
- /*
- This removes trailing blanks.
- */
- void OverSpace(char **strptr)
-
- { int c;
-
- while ((c = **strptr) == ' ' || c == '\t')
- { (*strptr)++;
- }
- }
-
-
-
-
-
-
-
-
- /*
- ReadChar scans an input line translating the backslash characters.
-
- Inputs: strptr - a pointer to a stringpointer; the latter points to the
- next character to be read and points behind the read
- bytes after executing ReadChar
- dest - a pointer to a buffer, where the read bytes should be
- stored
-
- Result: number of bytes that are written to dest (between 0 and 2)
- */
- int ReadChar(char **strptr, char *dest)
-
- { char c;
- int i;
-
- switch(c = *((*strptr)++))
- { case '\\':
- switch(c = tolower((int) *((*strptr)++)))
- { case '\n':
- return(0);
- case 'b':
- *dest = '\b';
- break;
- case 'c':
- *dest = '\233';
- break;
- case 'e':
- *dest = '\033';
- break;
- case 'f':
- *dest = '\f';
- break;
- case 'g':
- *dest = '\007';
- break;
- case 'n':
- *dest = '\n';
- break;
- case 'r':
- *dest = '\r';
- break;
- case 't':
- *dest = '\t';
- break;
- case 'v':
- *dest = '\013';
- break;
- case 'x':
- *dest = gethex((int) **strptr);
- (*strptr)++;
- if (((c = **strptr) >= '0' && c <= '9') ||
- (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))
- { *dest = (*dest << 4) + gethex((int) c);
- (*strptr)++;
- }
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- *dest = getoctal((int) **strptr);
- (*strptr)++;
- for (i = 0; i < 2; i++)
- { if ((c = **strptr) >= '0' && c <= '7')
- { *dest = (*dest << 3) + getoctal((int) c);
- (*strptr)++;
- }
- }
- break;
- case ')':
- case '\\':
- *(dest++) = '\\';
- *dest = c;
- return(2);
- default:
- *dest = c;
- }
- break;
- default:
- *dest = c;
- }
- return(1);
- }
-
-
-
-
- /*
- This scans the catalog description file.
-
- Inputs: cdfile - name of the catalog description file
-
- Result: TRUE, if successfull, FALSE otherwise
- */
- int ScanCDFile(char *cdfile)
-
- { FILE *fp;
- struct CDLine *cdline, **cdptr = &FirstCDLine;
- struct CatString *cs, **csptr = &FirstCatString;
- char *line, *newline;
- char *ptr;
- int NextID = 0, len;
- int Result = TRUE;
-
- ScanFile = cdfile;
- ScanLine = 0;
-
- if (!(fp = fopen(cdfile, "r")))
- { ShowError(GetFlexCatString(msgNoCatalogDescription), cdfile);
- }
-
- /*
- Get the basename
- */
- if ((ptr = strchr(cdfile, ':')))
- { cdfile = ptr;
- }
- if ((ptr = strrchr(cdfile, '/')))
- { cdfile = ptr+1;
- }
- if ((ptr = strrchr(cdfile, '.')))
- { len = ptr-cdfile;
- }
- else
- { len = strlen(cdfile);
- }
- if (!(BaseName = malloc(len+1)))
- { MemError();
- }
- strncpy(BaseName, cdfile, len);
- BaseName[len] = '\0';
-
- while(!feof(fp) && (line = newline = ReadLine(fp, TRUE)))
- { if (!(cdline = malloc(sizeof(*cdline))))
- { MemError();
- }
- *cdptr = cdline;
- cdptr = &cdline->Next;
- cdline->Next = NULL;
- cdline->Line = line = AllocString(newline);
- free(newline);
-
- if (*line == ';')
- { continue;
- }
- if (*line == '#')
- { int CheckExtra = TRUE;
-
- if (strnicmp(line+1, "language", 8) == 0)
- { char *ptr;
-
- line += 9;
- OverSpace(&line);
- Language = AllocString(line);
- for (ptr = Language; *ptr; ptr++)
- { *ptr = tolower((int) *ptr);
- }
- CheckExtra = FALSE;
- }
- else if (strnicmp(line+1, "version", 7) == 0)
- { CatVersion = strtol(line+8, &line, 10);
- }
- else if (strnicmp(line+1, "lengthbytes", 11) == 0)
- { line += 12;
- if ((LengthBytes = strtol(line, &line, 10))
- > sizeof(long))
- { ShowWarn(GetFlexCatString(msgNoLengthBytes), sizeof(long));
- LengthBytes = sizeof(long);
- }
- }
- else if (strnicmp(line+1, "basename", 8) == 0)
- { line += 9;
- OverSpace(&line);
- free(BaseName);
- BaseName = AllocString(line);
- CheckExtra = FALSE;
- }
- else
- { ShowWarn(GetFlexCatString(msgUnknownCDCommand));
- Result = FALSE;
- CheckExtra = FALSE;
- }
- if (CheckExtra)
- { OverSpace(&line);
- if (*line)
- { ShowWarn(GetFlexCatString(msgExtraCharacters));
- Result = FALSE;
- }
- }
- }
- else
- { char *idstr;
-
- if (*line == ' ' || *line == '\t')
- { ShowWarn(GetFlexCatString(msgUnexpectedBlanks));
- Result = FALSE;
- OverSpace(&line);
- }
-
- idstr = line;
- while ((*line >= 'a' && *line <= 'z') ||
- (*line >= 'A' && *line <= 'Z') ||
- (*line >= '0' && *line <= '9') ||
- *line == '_')
- { ++line;
- }
-
- if (idstr == line)
- { ShowWarn(GetFlexCatString(msgNoIdentifier));
- Result = FALSE;
- }
- else
- { int found;
-
- if (!(cs = malloc(sizeof(*cs))))
- { MemError();
- }
-
- do
- { struct CatString *scs;
-
- found = TRUE;
- for (scs = FirstCatString; scs != NULL; scs = scs->Next)
- { if (scs->ID == NextID)
- { found = FALSE;
- ++NextID;
- break;
- }
- }
- }
- while (!found);
-
- cs->Next = NULL;
- cs->ID = NextID;
- cs->MinLen = 0;
- cs->MaxLen = -1;
- cs->CD_Str = "";
- cs->CT_Str = NULL;
-
- if (!(cs->ID_Str = malloc((line-idstr)+1)))
- { MemError();
- }
- strncpy(cs->ID_Str, idstr, line-idstr);
- cs->ID_Str[line-idstr] = '\0';
-
- OverSpace(&line);
-
- if (*line != '(')
- { ShowWarn(GetFlexCatString(msgNoLeadingBracket));
- Result = FALSE;
- }
- else
- { char *oldstr;
- struct CatString *scs;
- char bytes[10];
- int bytesread, reallen;
-
- ++line;
- OverSpace(&line);
- if (*line != '/')
- {
- cs->ID = NextID = strtol(line, &line, 10);
- OverSpace(&line);
- }
-
- for(scs = FirstCatString; scs != NULL; scs = scs->Next)
- { if (scs->ID == cs->ID)
- { ShowWarn(GetFlexCatString(msgDoubleID));
- Result = FALSE;
- }
- if (strcmp(cs->ID_Str, scs->ID_Str) == 0)
- { ShowWarn(GetFlexCatString(msgDoubleIdentifier));
- Result = FALSE;
- }
- }
-
- if (*line != '/')
- { ShowWarn(GetFlexCatString(msgNoMinLen));
- Result = FALSE;
- }
- else
- { ++line;
- OverSpace(&line);
- if (*line != '/')
- { cs->MinLen = strtol(line, &line, 10);
- OverSpace(&line);
- }
- if (*line != '/')
- { ShowWarn(GetFlexCatString(msgNoMaxLen));
- Result = FALSE;
- }
- else
- { ++line;
- OverSpace(&line);
- if (*line != ')')
- { cs->MaxLen = strtol(line, &line, 10);
- OverSpace(&line);
- }
- if (*line != ')')
- { ShowWarn(GetFlexCatString(msgNoTrailingBracket));
- Result = FALSE;
- }
- else
- { ++line;
- OverSpace(&line);
- if (*line)
- { ShowWarn(GetFlexCatString(msgExtraCharacters));
- }
- }
- }
- }
- if (!(newline = ReadLine(fp, FALSE)))
- { ShowWarn(GetFlexCatString(msgNoString));
- Result = FALSE;
- cs->CD_Str = "";
- }
- else
- { cs->CD_Str = AllocString(newline);
- free(newline);
- }
-
- /*
- Get stringlen
- */
- oldstr = cs->CD_Str;
- reallen = 0;
- while (*oldstr)
- { bytesread = ReadChar(&oldstr, bytes);
- if (bytesread == 2)
- { bytesread--;
- }
- reallen += bytesread;
- }
-
- if (cs->MinLen > 0 && reallen < cs->MinLen)
- { ShowWarn(GetFlexCatString(msgShortString));
- }
- if (cs->MaxLen > 0 && reallen > cs->MaxLen)
- { ShowWarn(GetFlexCatString(msgLongString));
- }
-
- *csptr = cs;
- csptr = &cs->Next;
- ++NumStrings;
- }
- }
- }
- }
- fclose(fp);
- return(Result);
- }
-
-
-
-
- /*
- This scans a catalog translation file.
-
- Inputs: ctfile - name of the translation file to scan.
- CreateNew - TRUE, if a new translation file should be created.
-
- Result: TRUE, if successfull, FALSE otherwise.
- */
- int ScanCTFile(char *ctfile, int CreateNew)
-
- { FILE *fp;
- char *newline, *line, *idstr, *newidstr, *newstr;
- struct CatString *cs;
- int Result = TRUE;
-
- ScanFile = ctfile;
- ScanLine = 0;
-
- if (!(fp = fopen(ctfile, "r")))
- { ShowError(GetFlexCatString(msgNoCatalogTranslation), ctfile);
- }
-
-
- while (!feof(fp) && (line = newline = ReadLine(fp, TRUE)))
- { switch(*line)
- { case ';':
- break;
- case '#':
- if (*(++line) != '#')
- { ShowWarn(GetFlexCatString(msgNoCTCommand));
- }
- ++line;
- OverSpace(&line);
- if (strnicmp(line, "version", 7) == 0)
- { line += 7;
- OverSpace(&line);
- CatVersionString = AllocString(line);
- }
- else if (strnicmp(line, "codeset", 7) == 0)
- { line += 7;
- CodeSet = strtol(line, &line, 10);
- OverSpace(&line);
- if (*line)
- { ShowWarn(GetFlexCatString(msgExtraCharacters));
- }
- }
- else if (strnicmp(line, "language", 8) == 0)
- { char *ptr;
-
- line += 8;
- OverSpace(&line);
- CatLanguage = AllocString(line);
- for (ptr = CatLanguage; *ptr; ptr++)
- { *ptr = tolower((int) *ptr);
- }
- }
- else
- { ShowWarn(GetFlexCatString(msgUnknownCTCommand));
- }
- break;
- default:
- if (*line == ' ' || *line == '\t')
- { ShowWarn(GetFlexCatString(msgUnexpectedBlanks));
- OverSpace(&line);
- }
- idstr = line;
- while ((*line >= 'a' && *line <= 'z') ||
- (*line >= 'A' && *line <= 'Z') ||
- (*line >= '0' && *line <= '9') ||
- *line == '_')
- { ++line;
- }
- if (idstr == line)
- { ShowWarn(GetFlexCatString(msgNoIdentifier));
- break;
- }
- if (!(newidstr = malloc(line-idstr+1)))
- { MemError();
- }
- strncpy(newidstr, idstr, line-idstr);
- newidstr[line-idstr] = '\0';
- OverSpace(&line);
- if (*line)
- { ShowWarn(GetFlexCatString(msgExtraCharacters));
- }
- if (!(newstr = ReadLine(fp, FALSE)))
- { ShowWarn(GetFlexCatString(msgNoString));
- cs->CT_Str = "";
- }
- else
- { for(cs = FirstCatString; cs != NULL; cs = cs->Next)
- { if (strcmp(cs->ID_Str, newidstr) == 0)
- { break;
- }
- }
- if (cs == NULL && !CreateNew)
- { ShowWarn(GetFlexCatString(msgUnknownIdentifier), newidstr);
- }
- else
- { char *oldstr;
- char bytes[10];
- int bytesread, reallen;
-
- if (cs->CT_Str)
- { ShowWarn(GetFlexCatString(msgDoubleIdentifier));
- Result = FALSE;
- free (cs->CT_Str);
- }
- cs->CT_Str = AllocString(newstr);
-
- /*
- Get stringlen
- */
- oldstr = cs->CT_Str;
- reallen = 0;
- while (*oldstr)
- { bytesread = ReadChar(&oldstr, bytes);
- if (bytesread == 2)
- { bytesread--;
- }
- reallen += bytesread;
- }
-
- if (cs->MinLen > 0 && reallen < cs->MinLen)
- { ShowWarn(GetFlexCatString(msgShortString));
- }
- if (cs->MaxLen > 0 && reallen > cs->MaxLen)
- { ShowWarn(GetFlexCatString(msgLongString));
- }
- }
- free(newstr);
- }
- free(newidstr);
- }
- free(newline);
- }
-
- fclose(fp);
- return(Result);
- }
- /*
- CatPuts prints a string to a catalog. (The string is preceded by a
- long integer containing its length and probably padded up to word
- boundary or longword boundary, depending on the argument padbytes.)
- */
- int CatPuts(FILE *fp, char *str, int padbytes)
-
- { unsigned long reallen, virtuallen, chunklen;
- int bytesread;
- char *oldstr;
- char bytes[10];
-
- /*
- Get Length of string.
- */
- oldstr = str;
- reallen = 0;
- while (*oldstr)
- { bytesread = ReadChar(&oldstr, bytes);
- if (bytesread == 2)
- { bytesread--;
- }
- reallen += bytesread;
- }
- chunklen = reallen + LengthBytes;
- if (((virtuallen = chunklen) % 4) == 0)
- { virtuallen++;
- }
-
- fwrite(&virtuallen, sizeof(virtuallen), 1, fp);
- if (LengthBytes)
- { fwrite(((char *) &reallen)+sizeof(reallen)-LengthBytes,
- LengthBytes, 1, fp);
- }
- while(*str)
- { bytesread = ReadChar(&str, bytes);
- if (bytesread)
- { fwrite(bytes+bytesread-1, 1, 1, fp);
- }
- }
-
- do
- { putc('\0', fp);
- }
- while(++chunklen % padbytes);
-
- return(chunklen+4);
- }
-
-
-
-
- /*
- This creates a catalog.
- */
- void CreateCat(char *CatFile)
-
- { FILE *fp;
- int CatLen, HeadLen;
- struct CatString *cs;
- int i;
-
- if (!CatVersionString)
- { ShowError(GetFlexCatString(msgNoCTVersion));
- }
- if (!CatLanguage)
- { ShowError(GetFlexCatString(msgNoCTLanguage));
- }
-
- if (!(fp = fopen(CatFile, "w")))
- { ShowError(GetFlexCatString(msgNoCatalog), CatFile);
- }
-
- fputs("FORM0000CTLGFVER", fp);
- CatLen = 8 + CatPuts(fp, CatVersionString, 2);
- fputs("LANG", fp);
- CatLen += 4 + CatPuts(fp, CatLanguage, 2);
- fputs("CSET", fp);
- i = 32;
- fwrite(&i, sizeof(i), 1, fp);
- while(i-- > 0)
- { putc('\0', fp);
- }
- CatLen += 48;
- fprintf(fp, "STRS0000");
- HeadLen = CatLen;
-
- for (cs = FirstCatString; cs != NULL; cs = cs->Next)
- { if (strcmp(cs->CT_Str, cs->CD_Str))
- { fwrite(&cs->ID, sizeof(cs->ID), 1, fp);
- CatLen += 4 + CatPuts(fp, cs->CT_Str, 4);
- }
- }
-
- fseek(fp, 4, SEEK_SET);
- fwrite(&CatLen, sizeof(CatLen), 1, fp);
- fseek(fp, HeadLen-4, SEEK_CUR);
- CatLen -= HeadLen;
- fwrite(&CatLen, sizeof(CatLen), 1, fp);
- fclose(fp);
- }
-
-
-
-
- /*
- This creates a new catalog translation file.
- */
- void CreateCTFile(char *NewCTFile)
-
- { FILE *fp;
- struct CDLine *cd;
- struct CatString *cs;
- char *line;
-
- if (!(fp = fopen(NewCTFile, "w")))
- { ShowError(GetFlexCatString(msgNoNewCTFile));
- }
-
- fprintf(fp, "## version %s\n## language %s\n## codeset %d\n",
- CatVersionString, CatLanguage, CodeSet);
-
- for(cd = FirstCDLine, cs = FirstCatString;
- cd != NULL;
- cd = cd->Next)
- { switch(*cd->Line)
- { case '#':
- break;
- case ';':
- fprintf(fp, "%s\n", cd->Line);
- break;
- default:
- if(cs)
- { fprintf(fp, "%s\n", cs->ID_Str);
- fprintf(fp, "%s\n", cs->CT_Str ? cs->CT_Str : "");
- putc(';', fp);
- for (line = cs->CD_Str; *line; ++line)
- { putc((int) *line, fp);
- if(*line == '\n')
- { putc(';', fp);
- }
- }
- putc('\n', fp);
- cs = cs->Next;
- }
- }
- }
-
- fclose(fp);
- }
-
-
-
-
- /*
- InitCatStringOutput gets called before writing a catalog string as
- source.
-
- Inputs: fp = file pointer to the output file
- type = one of TYPE_C create C strings
- TYPE_ASSEMBLER create Assembler strings
- TYPE_OBERON create Oberon strings
- TYPE_E create E strings
- TYPE_NONE create simple strings
- */
- int OutputMode = OutputMode_None;
- int OutputType = TYPE_C;
- FILE *OutputFile;
- int OutputLen;
- void InitCatStringOutput(FILE *fp)
-
- {
- OutputLen = 0;
- OutputFile = fp;
- OutputMode = OutputMode_None;
- switch(OutputType)
- { case TYPE_C:
- case TYPE_OBERON:
- putc('\"', fp);
- OutputMode = OutputMode_Ascii;
- break;
- case TYPE_E:
- putc('\'', fp);
- case TYPE_ASSEMBLER:
- case TYPE_NONE:
- break;
- }
- }
-
-
-
- /*
- SeparateCatStringOutput gets called to split a catalog into separate
- lines.
- */
- void SeparateCatStringOutput(void)
-
- {
- switch(OutputType)
- { case TYPE_C:
- if (!LongStrings)
- { fputs("\"\\\n\t\"", OutputFile);
- }
- break;
- case TYPE_E:
- if (!LongStrings)
- { fputs("\' +\n\t\'", OutputFile);
- }
- break;
- case TYPE_OBERON:
- if (!LongStrings)
- { fputs("\"\n\t\"", OutputFile);
- }
- break;
- case TYPE_ASSEMBLER:
- if (!LongStrings)
- { if (OutputMode == OutputMode_Ascii)
- { putc('\'', OutputFile);
- }
- putc('\n', OutputFile);
- OutputMode = OutputMode_None;
- }
- break;
- case TYPE_NONE:
- break;
- }
- }
-
-
-
-
- /*
- WriteBinChar writes one binary character into the source file
- */
- void WriteBinChar(int c)
-
- {
- switch(OutputType)
- { case TYPE_C:
- case TYPE_E:
- case TYPE_OBERON:
- switch(c)
- { case '\b':
- fputs("\\b", OutputFile);
- break;
- case '\n':
- fputs("\\n", OutputFile);
- break;
- case '\r':
- fputs("\\r", OutputFile);
- break;
- case '\t':
- fputs("\\t", OutputFile);
- break;
- case '\f':
- fputs("\\f", OutputFile);
- break;
- case '\0':
- fputs("\\0", OutputFile);
- break;
- default:
- fprintf(OutputFile, "\\%c%c%c", ((c >> 6) & 3) + '0',
- ((c >> 3) & 7) + '0', (c & 7) + '0');
- break;
- }
- ++OutputLen;
- OutputMode = OutputMode_Bin;
- break;
- case TYPE_ASSEMBLER:
- switch(OutputMode)
- { case OutputMode_None:
- fprintf(OutputFile, "\tdc.b\t$%02x", c & 0xff);
- break;
- case OutputMode_Ascii:
- putc('\'', OutputFile);
- case OutputMode_Bin:
- fprintf(OutputFile, ",$%02x", c & 0xff);
- break;
- }
- ++OutputLen;
- OutputMode = OutputMode_Bin;
- break;
- case TYPE_NONE:
- ShowWarn(GetFlexCatString(msgNoBinChars));
- break;
- }
- }
-
-
-
-
- /*
- WriteAsciiChar writes one ascii character into the source file.
- */
- void WriteAsciiChar(int c)
-
- {
- switch(OutputType)
- { case TYPE_C:
- case TYPE_OBERON:
- switch(c)
- { case '\"':
- fputs("\\\"", OutputFile);
- break;
- default:
- putc(c, OutputFile);
- break;
- }
- ++OutputLen;
- OutputMode = OutputMode_Ascii;
- break;
- case TYPE_E:
- switch(c)
- { case '\'':
- fputs("''", OutputFile);
- break;
- default:
- putc(c, OutputFile);
- break;
- }
- ++OutputLen;
- OutputMode = OutputMode_Ascii;
- break;
- case TYPE_ASSEMBLER:
- if (c == '\'')
- { WriteBinChar(c);
- }
- else
- { switch (OutputMode)
- { case OutputMode_None:
- fprintf(OutputFile, "\tdc.b\t\'%c", c);
- break;
- case OutputMode_Ascii:
- putc(c, OutputFile);
- break;
- case OutputMode_Bin:
- fprintf(OutputFile, ",\'%c", c);
- break;
- }
- ++OutputLen;
- OutputMode = OutputMode_Ascii;
- }
- break;
- case TYPE_NONE:
- putc(c, OutputFile);
- break;
- }
- }
-
-
-
-
- /*
- TerminateCatStringOutput finishs the output of a catalog string.
- */
- void TerminateCatStringOutput(void)
-
- {
- switch(OutputType)
- { case TYPE_C:
- case TYPE_OBERON:
- putc('\"', OutputFile);
- break;
- case TYPE_E:
- putc('\'', OutputFile);
- break;
- case TYPE_ASSEMBLER:
- switch(OutputMode)
- { case OutputMode_Ascii:
- putc('\'', OutputFile);
- case OutputMode_Bin:
- break;
- case OutputMode_None:
- break;
- }
- case TYPE_NONE:
- break;
- }
- }
-
-
-
-
- /*
- This writes a sourcestring.
- */
- void WriteString(FILE *fpout, char *str, long Len)
-
- { char bytes[10];
- int bytesread;
-
- InitCatStringOutput(fpout);
- if (Len >= 0)
- { int i;
-
- for(i = LengthBytes; i >= 1; i--)
- { WriteBinChar((int) ((char *) &Len)[sizeof(Len)-i]);
- }
- }
- while (*str)
- { bytesread = ReadChar(&str, bytes);
- if (bytesread)
- { unsigned char c;
-
- c = bytes[bytesread-1];
- if ((c >= 0x20 && c < 0x7f) || c >= 0xa0)
- { WriteAsciiChar((int) c);
- }
- else
- { WriteBinChar((int) c);
- }
- }
- else
- { SeparateCatStringOutput();
- }
- }
- TerminateCatStringOutput();
- }
-
-
-
-
- /*
- Finally the source creation.
- */
- void CreateSourceFile(char *SourceFile, char *TemplateFile)
-
- { FILE *fpin, *fpout;
- char *line;
-
- if (!(fpin = fopen(TemplateFile, "r")))
- { ShowError(GetFlexCatString(msgNoSourceDescription), TemplateFile);
- }
- if (!(fpout = fopen(SourceFile, "w")))
- { ShowError(GetFlexCatString(msgNoSource), SourceFile);
- }
-
- while(!feof(fpin) && (line = ReadLine(fpin, FALSE)))
- { struct CatString *cs;
- int NeedRepeat;
- char bytes[10];
- int bytesread;
-
- cs = FirstCatString;
- do
- { char *currentline = line;
- NeedRepeat = FALSE;
-
- if (*currentline == '#' && *(++currentline) == '#')
- { ++currentline;
- OverSpace(¤tline);
- if (strnicmp(currentline, "stringtype", 10) == 0)
- { currentline += 10;
- OverSpace(¤tline);
- if (strnicmp(currentline, "c", 1) == 0)
- { OutputType = TYPE_C;
- ++currentline;
- }
- else if (strnicmp(currentline, "assembler", 9) == 0)
- { OutputType = TYPE_ASSEMBLER;
- currentline += 9;
- }
- else if (strnicmp(currentline, "oberon", 6) == 0)
- { OutputType = TYPE_OBERON;
- currentline += 6;
- }
- else if (strnicmp(currentline, "e", 1) == 0)
- { OutputType = TYPE_E;
- ++currentline;
- }
- else if (strnicmp(currentline, "none", 4) == 0)
- { OutputType = TYPE_NONE;
- currentline += 4;
- }
- else
- { ShowWarn(GetFlexCatString(msgUnknownStringType));
- currentline += strlen(currentline);
- }
- OverSpace(¤tline);
- if (*currentline)
- { ShowWarn(GetFlexCatString(msgExtraCharacters));
- }
- continue;
- }
- else if (strnicmp(currentline, "shortstrings", 12) == 0)
- { currentline += 12;
- LongStrings = FALSE;
- OverSpace(¤tline);
- if (*currentline)
- { ShowWarn(GetFlexCatString(msgExtraCharacters));
- }
- continue;
- }
- }
-
- currentline = line;
- while(*currentline)
- { bytesread = ReadChar(¤tline, bytes);
- if (bytesread)
- { if (*bytes == '%')
- { switch(*(currentline++))
- { case 'b':
- fputs(BaseName, fpout);
- break;
- case 'n':
- fprintf(fpout, "%d", NumStrings);
- break;
- case 'v':
- fprintf(fpout, "%d", CatVersion);
- break;
- case 'l':
- WriteString(fpout, Language, -1);
- break;
- case 'i':
- NeedRepeat = TRUE;
- if (cs) fputs(cs->ID_Str, fpout);
- break;
- case 'd':
- NeedRepeat = TRUE;
- if (cs) fprintf(fpout, "%d", cs->ID);
- break;
- case 's':
- NeedRepeat = TRUE;
- if (cs)
- { char *idstr;
- unsigned long len;
-
- if (LengthBytes)
- { idstr = cs->CD_Str;
- while(*idstr)
- { bytesread = ReadChar(&idstr, bytes);
- if (bytesread)
- { ++len;
- }
- }
- }
- WriteString(fpout, cs->CD_Str, LengthBytes ? len : -1);
- }
- break;
- case '(':
- NeedRepeat = TRUE;
- while(*currentline && *currentline != ')')
- { bytesread = ReadChar(¤tline, bytes);
- if (bytesread && cs && cs->Next)
- { putc((int) bytes[bytesread-1], fpout);
- }
- }
- if (!*currentline)
- { ShowWarn(GetFlexCatString(msgNoTerminateBracket));
- }
- else
- { ++currentline;
- }
- break;
- default:
- putc((int) *(currentline++), fpout);
- }
- }
- else
- { putc((int) bytes[bytesread-1], fpout);
- }
- }
- }
- putc('\n', fpout);
- }
- while(NeedRepeat && cs && (cs = cs->Next));
-
- free(line);
- }
-
- fclose(fpin);
- fclose(fpout);
- }
-
-
-
-
- /*
- The Usage function describes the programs calling syntax.
- */
- void Usage(void)
-
- {
- fputs((char *) GetFlexCatString(msgUsage), stderr);
- fprintf(stderr, "\n%s\n", VERSION+6);
- Cleanup(5);
- }
-
- /*
- Finally the main function. Does nothing special except for scanning
- the arguments.
- */
- void main (int argc, char *argv [])
-
- { char *cdfile, *ctfile, *newctfile, *catalog;
- char *source, *template;
- int i, assembler;
-
- if (argc == 0) /* Aztec's entry point for workbench programs */
- { exit(5);
- }
-
- #ifdef AMIGA
- LocaleBase = OpenLibrary((STRPTR) "locale.library", 38);
- if (!(UtilityBase = OpenLibrary((STRPTR) "utility.library", 37)))
- { fprintf(stderr, "Need utility.library, V37.\n");
- exit(20);
- }
- OpenFlexCatCatalog(NULL, NULL);
- #endif
-
- cdfile = ctfile = newctfile = catalog = NULL;
- assembler = FALSE;
-
- if (argc == 1)
- { Usage();
- }
-
- for (i = 1; i < argc; i++)
- { if (strnicmp (argv[i], "catalog=", 8) == 0)
- { catalog = argv[i] + 8;
- }
- else if (stricmp (argv[i], "catalog") == 0)
- { if (i+1 == argc)
- { Usage();
- }
- catalog = argv[++i];
- }
- else if (strnicmp (argv[i], "newctfile=", 10) == 0)
- { newctfile = argv[i] + 10;
- }
- else if (strnicmp (argv[i], "newctfile", 10) == 0)
- { if (i+1 == argc)
- { Usage();
- }
- newctfile = argv[++i];
- }
- else if (cdfile == NULL)
- { if (stricmp(argv[i], "?") == 0 || stricmp(argv[i], "-h") == 0 ||
- stricmp(argv[i], "help") == 0)
- { Usage();
- }
- if (!ScanCDFile(cdfile = argv[i]))
- { Cleanup(10);
- }
- }
- else if (strchr(argv[i], '='))
- { source = AllocString(argv[i]);
- *(template = strchr(source, '=')) = '\0';
- ++template;
-
- CreateSourceFile(source, template);
- }
- else
- { if (ctfile)
- { Usage();
- }
- ctfile = argv[i];
- }
- }
-
- if (ctfile)
- { if(!ScanCTFile(ctfile, newctfile ? TRUE : FALSE))
- { Cleanup(10);
- }
- }
- if (catalog)
- { if (!ctfile)
- { fprintf(stderr, (char *) GetFlexCatString(msgNoCTArgument));
- Usage();
- }
- CreateCat(catalog);
- }
- if (newctfile)
- { CreateCTFile(newctfile);
- }
-
- Cleanup(0);
- }
-
-
-
-
- /*
- Dice's entry point for workbench programs
- */
- void wbmain(struct WBStartup *wbmsg)
-
- { exit(5);
- }
-