summaryrefslogtreecommitdiff
path: root/app/help/genmessages.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/help/genmessages.c')
-rw-r--r--app/help/genmessages.c339
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;
+}