1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
|
/*
* Compile text message files into binary files
*
* Expects any number of files specified on the command line
* and outputs an equivalent number of binary files with the
* same name (with .mtb extension) in the local directory.
*
* Format of input files:
* xxx,yyy,ttttttttttttttttttttttttt
*
* where xxx is errno
* yyy is suberrno
* ttttt is message text
*
* For each file:
* get file size
* allocate this much memory for text strings
* allocate 1000 structs for
* read all lines into memory counting number of rows and putting
* text lines into memory chunk, and mesage lengths into struct
* array, and offsets (0 being start of memory chunk)
* write out number of entries
* iterate through struct arrays, adding file offset of start of
* text messages based on n number of structs
* write out array of structs
* write out memory chuck
*/
#include "rexx.h"
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#include "rexxmsg.h"
/*
* Static pointers to language-specific error messages
* IF THIS EVER CHANGES, ALSO CHANGE THE SAME TABLE IN error.c
*/
static const char *errlang[] =
{
"en", /* english */
"de", /* german */
"es", /* spanish */
"no", /* norwegian */
"pt", /* portuguese */
"pl", /* polish */
#if 0
"en","ca","cs","da","de","el","es","fi","fr","he","hu","is","it","ja","ko",
"lt","nl","no","pl","pt","ru","sk","sl","sv","th","tr","zh",
#endif
} ;
unsigned int getlanguage( char *lang )
{
int i,size;
size = sizeof(errlang) / sizeof(errlang[0]);
for ( i = 0; i < size; i++)
{
if ( strcmp( errlang[i], lang ) == 0 )
return i;
}
return 255;
}
int main( int argc, char *argv[] )
{
struct stat stat_buf;
FILE *infp, *outfp;
char line[512];
int i,j,len,end=0,start=0,text_size;
char *fn;
char *text;
struct textindex *pti,*ti;
unsigned int count,offset,lang;
int last_count=0;
ti = (struct textindex *)malloc( 500*sizeof(struct textindex) );
if ( ti == NULL )
{
fprintf( stderr, "Unable to allocate memory for 500 message structures.\n" );
exit(1);
}
for ( i = 1; i < argc; i++ )
{
fn = argv[i];
infp = fopen( fn, "r" );
if ( infp == NULL )
{
fprintf( stderr, "Unable to open %s for reading.\n", fn );
free(ti);
exit(1);
}
stat( fn, &stat_buf );
text = (char *)malloc( stat_buf.st_size );
if ( text == NULL )
{
fprintf( stderr, "Unable to allocate %d bytes of memory.\n", (int) stat_buf.st_size );
free(ti);
exit(1);
}
/*
* Read each line from the file...
*/
text_size = 0;
pti = ti;
for ( count = 0; ; )
{
if ( fgets( line, 511, infp ) == NULL )
break;
if ( line[0] != '#' )
{
line[3] = '\0';
line[7] = '\0';
pti->errorno = atol( line );
pti->suberrorno = atol( line+4 );
pti->fileoffset = text_size;
pti->textlength = strlen( line+8)-1;
memcpy( text+text_size, line+8, pti->textlength);
text_size += pti->textlength;
count++;
pti++;
}
}
fclose( infp );
if ( last_count != 0 && count != (unsigned) last_count )
{
fprintf( stderr, "Inconsistent numbers of error messages (%d) between this file %s and the previous one (%d).\n", count, fn, last_count );
free(ti);
exit(1);
}
last_count = count;
/* generate output file name */
len = strlen( argv[i] );
for ( j = len-1; j >= 0; j-- )
{
if ( argv[i][j] == '.' )
end = j;
if ( argv[i][j] == '/' || argv[i][j] == '\\')
{
start = j;
break;
}
}
memcpy( line, fn+start+1, end-start );
line[end-start-1] = '\0';
if ( ( lang = getlanguage( line ) ) == 255 )
{
fprintf( stderr, "Unknown language file name %s.\n", line );
free(ti);
exit(1);
}
strcat( line, ".mtb" );
outfp = fopen( line, "wb" );
if ( outfp == NULL )
{
fprintf( stderr, "Unable to open %s for writing.\n", line );
free(ti);
exit(1);
}
if ( fwrite( (void *)&count, sizeof(unsigned int), 1, outfp ) != 1 )
{
fprintf( stderr, "Unable to write message count to %s.\n", line );
free(ti);
exit(1);
}
if ( fwrite( (void *)&lang, sizeof(unsigned int), 1, outfp ) != 1 )
{
fprintf( stderr, "Unable to write message lang to %s.\n", line );
free(ti);
exit(1);
}
/* update the file offsets */
offset = count * sizeof( struct textindex ) + ( 2 * sizeof( unsigned int ) );
pti = ti;
for ( j = 0; (unsigned) j < count; j++ )
{
pti->fileoffset += offset;
pti++;
}
/* write the index structs */
pti = ti;
for ( j = 0; (unsigned) j < count; j++ )
{
if ( fwrite( (void *)pti, sizeof(struct textindex), 1, outfp ) != 1 )
{
fprintf( stderr, "Unable to write index struct %d to %s.\n", j, line );
free(ti);
exit(1);
}
pti++;
}
/* write the text messages */
if ( (int) fwrite( text, sizeof(char), text_size, outfp ) != text_size )
{
fprintf( stderr, "Unable to write text messages to %s.\n", line );
free(ti);
exit(1);
}
fclose( outfp );
free( text );
}
free(ti);
printf( "%d error messages compiled\n", last_count );
return 0;
}
|