diff options
Diffstat (limited to 'app/help/genmessages.c')
-rw-r--r-- | app/help/genmessages.c | 339 |
1 files changed, 339 insertions, 0 deletions
diff --git a/app/help/genmessages.c b/app/help/genmessages.c new file mode 100644 index 0000000..349e81e --- /dev/null +++ b/app/help/genmessages.c @@ -0,0 +1,339 @@ +/* XTrkCad - Model Railroad CAD + * Copyright (C) 2005 Dave Bullis + * 2007 Martin Fischer + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <ctype.h> +#ifdef WINDOWS + #if _MSC_VER >=1400 + #define strdup _strdup + #endif +#endif + +#define I18NHEADERFILE "i18n.h" + +typedef struct helpMsg_t * helpMsg_p; +typedef struct helpMsg_t { + char * key; + char * title; + char * help; + } helpMsg_t; + +helpMsg_t helpMsgs[200]; +int helpMsgCnt = 0; + +struct transTbl { + char *inChar; + char *outChar[]; +}; + +/* ATTENTION: make sure that the characters are in the same order as the equivalent escape sequences below */ + +/* translation table for unicode sequences understood by Halibut */ +struct transTbl toUnicode = { + "\xB0\0", + { "\\u00B0", + "\\0" } +}; + +/* translation table for escape sequences understood by C compiler */ + +struct transTbl toC = { + "\n\\\"\0", + { "\\n", + "\\\\", + "\\\"", + "\\0" } +}; + + +char * +TranslateString( char *srcString, struct transTbl *trTbl ) +{ + char *destString; + char *cp; + char *cp2; + size_t bufLen = strlen( srcString ) + 1; + char *idx; + + /* calculate the expected result length */ + for( cp = srcString; *cp; cp++ ) + if( idx = strchr( trTbl->inChar, *cp )) /* does character need translation ? */ + bufLen += strlen( (trTbl->outChar)[idx - trTbl->inChar ] ) - 1; /* yes, extend buffer accordingly */ + + /* allocate memory for result */ + destString = malloc( bufLen ); + + if( destString ) { + /* copy and translate characters as needed */ + cp2 = destString; + for( cp = srcString; *cp; cp++ ) { + if( idx = strchr( trTbl->inChar, *cp )) { /* does character need translation ? */ + strcpy( cp2, (trTbl->outChar)[idx - trTbl->inChar ] ); /* yes, copy the escaped character sequence */ + cp2 += strlen((trTbl->outChar)[idx - trTbl->inChar ] ); + } else { + *cp2++ = *cp; /* no, just copy the character */ + } + } + /* terminate string */ + *cp2 = '\0'; + } else { + /* memory allocation failed */ + exit(1); + } + + return( destString ); +} + + +int cmpHelpMsg( const void * a, const void * b ) +{ + helpMsg_p aa = (helpMsg_p)a; + helpMsg_p bb = (helpMsg_p)b; + return strcmp( aa->title, bb->title ); +} + +void unescapeString( FILE * f, char * str ) +{ + while (*str) { + if (*str != '\\') + fputc( *str, f ); + str++; + } +} + +/** + * Generate the file in help source format ( ie. the BUT file ) + */ + +void dumpHelp( FILE *hlpsrcF ) +{ + int inx; + char *transStr; + + fputs( "\\#\n * DO NOT EDIT! This file has been automatically created by genmessages.\n * Changes to this file will be overwritten.\n", hlpsrcF ); + + fprintf( hlpsrcF, "\n\n\\H{messageList} Message Explanations\n\n" ); + + /* sort in alphabetical order */ + qsort( helpMsgs, helpMsgCnt, sizeof helpMsgs[0], cmpHelpMsg ); + + /* now save all the help messages */ + for ( inx=0; inx<helpMsgCnt; inx++ ) { + + transStr = TranslateString( helpMsgs[inx].title, &toUnicode ); + fprintf( hlpsrcF, "\\S{%s} %s\n\n", helpMsgs[inx].key, transStr ); + free( transStr ); + + transStr = TranslateString( helpMsgs[inx].help, &toUnicode ); + fprintf( hlpsrcF, "%s\n\n", transStr ); + free( transStr ); + + fprintf( hlpsrcF, "\n\n\\rule\n\n" ); + } + +} + + +int main( int argc, char * argv[] ) +{ + FILE * hdrF; + FILE *inF; + FILE *outF; + + char buff[ 4096 ]; + char * cp; + int inFileIdx; + enum {m_init, m_title, m_alt, m_help } mode = m_init; + char msgName[256]; + char msgAlt[256]; + char msgTitle[1024]; + char msgTitle1[1024]; + char msgHelp[4096]; + char *tName, *tAlt, *tTitle; +#ifndef FLAGS + int flags; +#endif + int i18n = 0; + + /* check argument count */ + if ( argc < 3 || argc > 4 ) { + fprintf( stderr, "Usage: %s [-i18n] INFILE OUTFILE\n\n", argv[0] ); + fprintf( stderr, " -i18n is used to generate a include file with gettext support.\n\n" ); + exit(1); + } + + /* check options */ + if( argc == 4 ) { + if( !strcmp(argv[ 1 ], "-i18n")){ + i18n = 1; + inFileIdx = 2; /* second argument is input file */ + } + /* inFileIdx = 2; skip over option argument */ + } else { + inFileIdx = 1; /* first argument is input file */ + } + + /* open the file for reading */ + inF = fopen( argv[ inFileIdx ], "r" ); + if( !inF ) { + fprintf( stderr, "Could not open %s for reading!\n", argv[ inFileIdx ] ); + exit( 1 ); + } + + /* open the include file to generate */ + hdrF = fopen( "messages.h", "w" ); + if( !hdrF ) { + fprintf( stderr, "Could not open messages.h for writing!\n" ); + exit( 1 ); + } + + fputs( "/*\n * DO NOT EDIT! This file has been automatically created by genmessages.\n * Changes to this file will be overwritten.\n */\n", hdrF ); + + /* open the help file to generate */ + outF = fopen( argv[ inFileIdx + 1 ], "w" ); + if( !inF ) { + fprintf( stderr, "Could not open %s for writing!\n", argv[ inFileIdx ] ); + exit( 1 ); + } + + /* Include i18n header, if needed */ + if (i18n) + fprintf( hdrF, "#include \"" I18NHEADERFILE "\"\n\n" ); + + while ( fgets( buff, sizeof buff, inF ) ) { + + /* skip comment lines */ + if ( buff[0] == '#' ) + continue; + + /* remove trailing whitespaces */ + cp = buff+strlen(buff)-1; + while( cp >= buff && isspace(*cp)) { + *cp = '\0'; + cp--; + } + + if ( strncmp( buff, "MESSAGE ", 8 ) == 0 ) { + + /* skip any spaces */ + cp = strchr( buff+8, ' ' ); + if (cp) + while (*cp == ' ') *cp++ = 0; +#ifndef FLAGS + if ( cp && *cp ) { + flags = atoi(cp); + } +#endif + /* save the name of the message */ + strcpy( msgName, buff + 8 ); + msgAlt[0] = 0; + msgTitle[0] = 0; + msgTitle1[0] = 0; + msgHelp[0] = 0; + mode = m_title; + } else if ( strncmp( buff, "ALT", 3 ) == 0 ) { + mode = m_alt; + msgAlt[0] = 0; + } else if ( strncmp( buff, "HELP", 4 ) == 0 ) { + mode = m_help; + } else if ( strncmp( buff, "END", 3 ) == 0 ) { + /* the whole message has been read */ + + /* create escape sequences */ + tName = TranslateString( msgName, &toC ); + tTitle = TranslateString( msgTitle, &toC ); + tAlt = TranslateString( msgAlt, &toC ); + + if (msgHelp[0]==0) { + /* no help text is included */ + if (i18n) + fprintf( hdrF, "#define %s N_(\"%s\")\n", tName, tTitle ); + else + fprintf( hdrF, "#define %s \"%s\"\n", tName, tTitle ); + } else if (msgAlt[0]) { + /* a help text and an alternate description are included */ + if (i18n) + fprintf( hdrF, "#define %s N_(\"%s\\t%s\\t%s\")\n", tName, tName, tAlt, tTitle ); + else + fprintf( hdrF, "#define %s \"%s\\t%s\\t%s\"\n", tName, tName, tAlt, tTitle ); + } else { + /* a help text but no alternate description are included */ + if (i18n) + fprintf( hdrF, "#define %s N_(\"%s\\t%s\")\n", tName, tName, tTitle ); + else + fprintf( hdrF, "#define %s \"%s\\t%s\"\n", tName, tName, tTitle ); + } + + /*free temp stzrings */ + free( tName ); + free( tTitle ); + free( tAlt ); + + /* save the help text for later use */ + if (msgHelp[0]) { + helpMsgs[helpMsgCnt].key = strdup(msgName); + if ( msgAlt[0] ) + helpMsgs[helpMsgCnt].title = strdup(msgAlt); + else + helpMsgs[helpMsgCnt].title = strdup(msgTitle); + helpMsgs[helpMsgCnt].help = strdup(msgHelp); + helpMsgCnt++; + } + mode = 0; + } else { + /* are we currently reading the message text? */ + if (mode == m_title) { + /* yes, is the message text split over two lines ? */ + if (msgTitle[0]) { + /* if yes, keep the first part as the short text */ + if (msgAlt[0] == 0) { + strcpy( msgAlt, msgTitle ); + strcat( msgAlt, "..." ); + } + /* add a newline to the first part */ + strcat( msgTitle, "\n" ); + } + /* now save the buffer into the message title */ + strcat( msgTitle, buff ); + } else if (mode == m_alt) { + /* an alternate text was explicitly specified, save */ + if( msgAlt[ 0 ] ) { + strcat( msgAlt, " " ); + strcat( msgAlt, buff ); + } else { + strcpy( msgAlt, buff ); + } + } else if (mode == m_help) { + /* we are reading the help text, save in buffer */ + strcat( msgHelp, buff ); + strcat( msgHelp, "\n" ); + } + } + } + dumpHelp( outF ); + + fclose( hdrF ); + fclose( inF ); + fclose( outF ); + + printf( "%d messages\n", helpMsgCnt ); + return 0; +} |