Commit 30855917 authored by Bertho Stultiens's avatar Bertho Stultiens Committed by Alexandre Julliard

Initial release of the message compiler.

parent 13d74c5f
......@@ -58,6 +58,7 @@ BUILD = $(TOPOBJDIR)/tools/build@PROGEXT@
MAKEDEP = $(TOPOBJDIR)/tools/makedep@PROGEXT@
WRC = $(TOPOBJDIR)/tools/wrc/wrc@PROGEXT@
WRCFLAGS = -c -s -p $*
WMC = $(TOPOBJDIR)/tools/wmc/wmc@PROGEXT@
DLLDIR = $(TOPOBJDIR)/dlls
@SET_MAKE@
......@@ -200,6 +201,11 @@ all: Makefile
$(WRC) check_wrc:
cd $(TOPOBJDIR)/tools/wrc && $(MAKE) wrc@PROGEXT@
# Rule to rebuild the message compiler
$(WMC) check_wmc:
cd $(TOPOBJDIR)/tools/wmc && $(MAKE) wmc@PROGEXT@
# Rule to rebuild the 'makedep' program
$(MAKEDEP) check_makedep:
......
......@@ -6300,6 +6300,7 @@ server/Makefile
tools/Makefile
tools/cvdump/Makefile
tools/wrc/Makefile
tools/wmc/Makefile
tsx11/Makefile
unicode/Makefile
win32/Makefile
......@@ -6534,6 +6535,7 @@ server/Makefile
tools/Makefile
tools/cvdump/Makefile
tools/wrc/Makefile
tools/wmc/Makefile
tsx11/Makefile
unicode/Makefile
win32/Makefile
......
......@@ -1094,6 +1094,7 @@ server/Makefile
tools/Makefile
tools/cvdump/Makefile
tools/wrc/Makefile
tools/wmc/Makefile
tsx11/Makefile
unicode/Makefile
win32/Makefile
......
......@@ -11,6 +11,7 @@ C_SRCS = build.c makedep.c fnt2bdf.c bin2res.c
SUBDIRS = \
cvdump \
wmc \
wrc
EXTRASUBDIRS = \
......@@ -19,7 +20,7 @@ EXTRASUBDIRS = \
winapi_check/win32 \
wineconf.libs
all: $(PROGRAMS) wrc
all: $(PROGRAMS) wmc wrc
@MAKE_RULES@
......
Makefile
wmc
y.tab.c
y.tab.h
---------------------------------------------------------------------------
Version 1.0.0 (12-Jun-2000)
Bertho Stultiens <bertho@akhphd.au.dk>
- Initial release
DEFS = -D__WINE__
TOPSRCDIR = @top_srcdir@
TOPOBJDIR = ../..
SRCDIR = @srcdir@
VPATH = @srcdir@
YACCOPT = #-v
PROGRAMS = wmc@PROGEXT@
MODULE = none
C_SRCS = \
lang.c \
mcl.c \
utils.c \
wmc.c \
write.c
EXTRA_SRCS = mcy.y
EXTRA_OBJS = y.tab.o
all: check_unicode $(PROGRAMS)
depend: y.tab.h
@MAKE_RULES@
wmc@PROGEXT@: $(OBJS) $(TOPOBJDIR)/unicode/unicode.o
$(CC) $(CFLAGS) -o wmc@PROGEXT@ $(OBJS) $(TOPOBJDIR)/unicode/unicode.o $(LEXLIB)
$(TOPOBJDIR)/unicode/unicode.o check_unicode:
cd $(TOPSRCDIR)/unicode && $(MAKE)
y.tab.c y.tab.h: mcy.y
$(YACC) $(YACCOPT) -d -t $(SRCDIR)/mcy.y
clean::
$(RM) y.tab.c y.tab.h y.output
install:: $(PROGRAMS)
[ -d $(bindir) ] || $(MKDIR) $(bindir)
[ -d $(mandir)/man$(prog_manext) ] || $(MKDIR) $(mandir)/man$(prog_manext)
$(INSTALL_DATA) wmc.man $(mandir)/man$(prog_manext)/wmc.$(prog_manext)
$(INSTALL_PROGRAM) wmc $(bindir)/wmc
uninstall::
$(RM) $(bindir)/wmc $(mandir)/man$(prog_manext)/wmc.$(prog_manext)
### Dependencies:
/*
* Wine Message Compiler language and codepage support
*
* Copyright 2000 Bertho A. Stultiens (BS)
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "wmc.h"
#include "lang.h"
/*
* Languages supported
*
* MUST be sorting ascending on language ID
*/
static const language_t languages[] = {
{0x0402, 866, 1251, "Bulgarian", "Bulgaria"},
{0x0403, 850, 1252, "Catalan", "Spain"},
{0x0405, 852, 1250, "Czech", "Czech Republic"},
{0x0406, 850, 1252, "Danish", "Denmark"},
{0x0407, 850, 1252, "German", "Germany"},
{0x0408, 737, 1253, "Greek", "Greece"},
{0x0409, 437, 1252, "English", "United States"},
{0x040A, 850, 1252, "Spanish - Traditional Sort", "Spain"},
{0x040B, 850, 1252, "Finnish", "Finland"},
{0x040C, 850, 1252, "French", "France"},
{0x040E, 852, 1250, "Hungarian", "Hungary"},
{0x040F, 850, 1252, "Icelandic", "Iceland"},
{0x0410, 850, 1252, "Italian", "Italy"},
{0x0411, 932, 932, "Japanese", "Japan"},
{0x0412, 949, 949, "Korean", "Korea (south)"},
{0x0413, 850, 1252, "Dutch", "Netherlands"},
{0x0414, 850, 1252, "Norwegian (Bokml)", "Norway"},
{0x0415, 852, 1250, "Polish", "Poland"},
{0x0416, 850, 1252, "Portuguese", "Brazil"},
{0x0418, 852, 1250, "Romanian", "Romania"},
{0x0419, 866, 1251, "Russian", "Russia"},
{0x041A, 852, 1250, "Croatian", "Croatia"},
{0x041B, 852, 1250, "Slovak", "Slovakia"},
{0x041C, 852, 1250, "Albanian", "Albania"},
{0x041D, 850, 1252, "Swedish", "Sweden"},
{0x041F, 857, 1254, "Turkish", "Turkey"},
{0x0421, 850, 1252, "Indonesian", "Indonesia"},
{0x0422, 866, 1251, "Ukrainian", "Ukraine"},
{0x0423, 866, 1251, "Belarusian", "Belarus"},
{0x0424, 852, 1250, "Slovene", "Slovenia"},
{0x0425, 775, 1257, "Estonian", "Estonia"},
{0x0426, 775, 1257, "Latvian", "Latvia"},
{0x0427, 775, 1257, "Lithuanian", "Lithuania"},
/* {0x042A, ?, ?, "Vietnamese", "Vietnam"},*/
{0x042D, 850, 1252, "Basque", "Spain"},
{0x042F, 866, 1251, "Macedonian", "Former Yugoslav Republic of Macedonia"},
{0x0436, 850, 1252, "Afrikaans", "South Africa"},
/* {0x0438, 852, 1252, "Faroese", "Faroe Islands"}, FIXME: Not sure about codepages */
{0x043C, 437, 1252, "Irish", "Ireland"},
/* {0x048F, ?, ?, "Esperanto", "<none>"},*/
/* {0x0804, ?, ?, "Chinese (People's replublic of China)", People's republic of China"},*/
{0x0807, 850, 1252, "German", "Switzerland"},
{0x0809, 850, 1252, "English", "United Kingdom"},
{0x080A, 850, 1252, "Spanish", "Mexico"},
{0x080C, 850, 1252, "French", "Belgium"},
{0x0810, 850, 1252, "Italian", "Switzerland"},
{0x0813, 850, 1252, "Dutch", "Belgium"},
{0x0814, 850, 1252, "Norwegian (Nynorsk)", "Norway"},
{0x0816, 850, 1252, "Portuguese", "Portugal"},
/* {0x081A, ?, ?, "Serbian (latin)", "Yugoslavia"},*/
{0x081D, 850, 1252, "Swedish (Finland)", "Finland"},
{0x0C07, 850, 1252, "German", "Austria"},
{0x0C09, 850, 1252, "English", "Australia"},
{0x0C0A, 850, 1252, "Spanish - International Sort", "Spain"},
{0x0C0C, 850, 1252, "French", "Canada"},
{0x0C1A, 855, 1251, "Serbian (Cyrillic)", "Serbia"},
{0x1007, 850, 1252, "German", "Luxembourg"},
{0x1009, 850, 1252, "English", "Canada"},
{0x100A, 850, 1252, "Spanish", "Guatemala"},
{0x100C, 850, 1252, "French", "Switzerland"},
{0x1407, 850, 1252, "German", "Liechtenstein"},
{0x1409, 850, 1252, "English", "New Zealand"},
{0x140A, 850, 1252, "Spanish", "Costa Rica"},
{0x140C, 850, 1252, "French", "Luxembourg"},
{0x1809, 850, 1252, "English", "Ireland"},
{0x180A, 850, 1252, "Spanish", "Panama"},
{0x1C09, 437, 1252, "English", "South Africa"},
{0x1C0A, 850, 1252, "Spanish", "Dominican Republic"},
{0x2009, 850, 1252, "English", "Jamaica"},
{0x200A, 850, 1252, "Spanish", "Venezuela"},
{0x2409, 850, 1252, "English", "Caribbean"},
{0x240A, 850, 1252, "Spanish", "Colombia"},
{0x2809, 850, 1252, "English", "Belize"},
{0x280A, 850, 1252, "Spanish", "Peru"},
{0x2C09, 437, 1252, "English", "Trinidad & Tobago"},
{0x2C0A, 850, 1252, "Spanish", "Argentina"},
{0x300A, 850, 1252, "Spanish", "Ecuador"},
{0x340A, 850, 1252, "Spanish", "Chile"},
{0x380A, 850, 1252, "Spanish", "Uruguay"},
{0x3C0A, 850, 1252, "Spanish", "Paraguay"},
{0x400A, 850, 1252, "Spanish", "Bolivia"},
{0x440A, 850, 1252, "Spanish", "El Salvador"},
{0x480A, 850, 1252, "Spanish", "Honduras"},
{0x4C0A, 850, 1252, "Spanish", "Nicaragua"},
{0x500A, 850, 1252, "Spanish", "Puerto Rico"}
};
#define NLAN (sizeof(languages)/sizeof(languages[0]))
void show_languages(void)
{
int i;
printf(" Code | DOS-cp | WIN-cp | Language | Country\n");
printf("-------+--------+--------+--------------+---------\n");
for(i = 0; i < NLAN; i++)
printf("0x%04x | %5d | %5d | %-12s | %s\n",
languages[i].id,
languages[i].doscp,
languages[i].wincp,
languages[i].name,
languages[i].country);
}
static int langcmp(const void *p1, const void *p2)
{
return *(unsigned *)p1 - ((language_t *)p2)->id;
}
const language_t *find_language(unsigned id)
{
return (const language_t *)bsearch(&id, languages, NLAN, sizeof(languages[0]), langcmp);
}
void show_codepages(void)
{
unsigned i;
const union cptable *cpp;
printf("Codepages:\n");
for(i = 0; (cpp = cp_enum_table(i)); i++)
{
printf("%-5d %s\n", cpp->info.codepage, cpp->info.name);
}
}
const union cptable *find_codepage(int id)
{
return cp_get_table(id);
}
/*
* Wine Message Compiler language and codepage support
*
* Copyright 2000 Bertho A. Stultiens (BS)
*
*/
#ifndef __WMC_LANG_H
#define __WMC_LANG_H
#include "wine/unicode.h"
typedef struct language {
unsigned id;
unsigned doscp;
unsigned wincp;
char *name;
char *country;
} language_t;
void show_languages(void);
const language_t *find_language(unsigned id);
void show_codepages(void);
const union cptable *find_codepage(int id);
#endif
{"South Africa", 0x0436, 1252},
{"Saudi Arabia", 0x0401, 1256},
{"Lebanon", 0x0401, 1256},
{"Egypt", 0x0401, 1256},
{"Algeria", 0x0401, 1256},
{"Iraq", 0x0401, 1256},
{"Kuwait", 0x0401, 1256},
{"Marocco", 0x0401, 1256},
{"Oman", 0x0401, 1256},
{"Quatar", 0x0401, 1256},
{"Syria", 0x0401, 1256},
{"Tunisia", 0x0401, 1256},
{"United Arab Emirates",0x0401, 1256},
{"Belaruss", 0x0423, 1251},
{"Bulgaria", 0x0402
{"France", 0x040c, 1252},
{"Spain", 0x0403, 1252},
{"China (Taiwan)", 0x0404
{"United Kingdom", 0x0409, 1252},
{"Wales", 0x0409, 1252}, /* FIXME */
{"Czech Republic", 0x0405, 1250},
{"Denmark", 0x0406, 1252},
{"Austria", 0x0407, 1252},
{"Liechtenstein", 0x0407, 1252},
{"Luxemburg", 0x0407, 1252},
{"Switzerland", 0x0807, 1252},
{"Germany", 0x0407, 1252},
{"Australia", 0x0c09, 1252},
{"Caribbean", 0x2409, 1252},
{"Canada", 0x1009, 1252},
{"United Kingdom", 0x0809, 1252},
{"Ireland", 0x1809, 1252},
{"Jamaica", 0x2009, 1252},
{"Belize", 0x2809, 1252},
{"South Africa", 0x1c09, 1252},
{"Trinidad & Tobago", 0x2c09, 1252},
{"United States", 0x0409, 1252},
{"New Zealand", 0x1409, 1252},
{"Panama", 0x040a, 1252},
{"Bolivia", 0x040a, 1252},
{"Costa Rica", 0x140a, 1252},
{"Dominican Republic", 0x040a, 1252},
{"El Salvador", 0x040a, 1252},
{"Ecuador", 0x040a, 1252},
{"Guatemala", 0x040a, 1252},
{"Honduras", 0x040a, 1252},
{"Nicaragua", 0x040a, 1252},
{"Chile", 0x040a, 1252},
{"Mexico", 0x040a, 1252},
{"Spain", 0x040a, 1252},
{"Colombia", 0x040a, 1252},
{"Spain", 0x040a, 1252},
{"Peru", 0x040a, 1252},
{"Argentina", 0x040a, 1252},
{"Estonia", 0x0425, 1252},
{"Puerto Rico", 0x040a, 1252},
{"Venezuela", 0x040a, 1252},
{"Uruguay", 0x380a, 1252},
{"Paraguay", 0x040a, 1252},
{"Spain (Basque)", 0x04d2, 1252},
{"Finland", 0x040b, 1252},
{"Faroe Islands", 0x0438, 1252},
{"France", 0x040c, 1252},
{"Belgium", 0x040c, 1252},
{"Canada", 0x040c, 1252},
{"Luxemburg", 0x040c, 1252},
{"Switzerland", 0x040c, 1252},
{"Ireland", 0x0000, 1252},
{"United Kingdom", 0x0409, 1252},
{"Isle of Man", 0x0409, 1252},
{"Greece", 0x0408, 1253},
{"Croatia", 0x041a, 1250},
{"Hungary", 0x040e, 1250},
{"Indonesia", 0x0421, 1252},
{"Iceland", 0x040f, 1252},
{"Italy", 0x0410, 1252},
{"Switzerand", 0x0410, 1252},
{"Japan", 0x0411, 0},
{"Korea", 0x0000, 0},
{"Korea (South)", 0x0412, 0},
{"Lithuania", 0x0427, 1257},
{"Latvia", 0x0426, 1257},
{"Belgium", 0x0413, 1252},
{"Netherlands", 0x0413, 1252},
{"Suriname", 0x0413, 1252},
{"Norway", 0x0814, 1252},
{"Norway", 0x0414, 1252},
{"Poland", 0x0415, 1250},
{"Brazil", 0x0416, 1252},
{"Portugal", 0x0416, 1252},
{"Romania", 0x0418, 1250},
{"Russia", 0x0000, 1251},
{"Slovakia", 0x041b, 1250},
{"Slovenia", 0x0424, 1250},
{"Albania", 0x041c, 0},
{"Yugoslavia", 0x0c1a, 0},
{"Yugoslavia", 0x081a, 1250},
{"Sweden", 0x041d, 1252},
{"Finland", 0x081d, 1252},
{"Thailand", 0x041e, 0},
{"Turkey", 0x041f, 1254},
{"Ukrainia", 0x0422, 1251},
{"Vietnam", 0x042a, 0},
{"Belgium", 0x0490, 1252},
{"Hong Kong", 0x0404, 0},
{"People's republic of China", 0x0804, 0},
{"Singapore", 0x0404, 0}
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
/*
* Utility routines
*
* Copyright 1998,2000 Bertho A. Stultiens
*
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>
#include "wmctypes.h"
#include "utils.h"
#include "wmc.h"
#define SUPPRESS_YACC_ERROR_MESSAGE
static void generic_msg(const char *s, const char *t, va_list ap)
{
fprintf(stderr, "%s %s: %d, %d: ", t, input_name ? input_name : "stdin", line_number, char_number);
vfprintf(stderr, s, ap);
fprintf(stderr, "\n");
}
/*
* The yyerror routine should not exit because we use the error-token
* to determine the syntactic error in the source. However, YACC
* uses the same routine to print an error just before the error
* token is reduced.
* The extra routine 'xyyerror' is used to exit after giving a real
* message.
*/
int yyerror(const char *s, ...)
{
#ifndef SUPPRESS_YACC_ERROR_MESSAGE
va_list ap;
va_start(ap, s);
generic_msg(s, "Yacc error", ap);
va_end(ap);
#endif
return 1;
}
int xyyerror(const char *s, ...)
{
va_list ap;
va_start(ap, s);
generic_msg(s, "Error", ap);
va_end(ap);
exit(1);
return 1;
}
int yywarning(const char *s, ...)
{
va_list ap;
va_start(ap, s);
generic_msg(s, "Warning", ap);
va_end(ap);
return 0;
}
void internal_error(const char *file, int line, const char *s, ...)
{
va_list ap;
va_start(ap, s);
fprintf(stderr, "Internal error (please report) %s %d: ", file, line);
vfprintf(stderr, s, ap);
fprintf(stderr, "\n");
va_end(ap);
exit(3);
}
void error(const char *s, ...)
{
va_list ap;
va_start(ap, s);
fprintf(stderr, "Error: ");
vfprintf(stderr, s, ap);
fprintf(stderr, "\n");
va_end(ap);
exit(2);
}
void warning(const char *s, ...)
{
va_list ap;
va_start(ap, s);
fprintf(stderr, "Warning: ");
vfprintf(stderr, s, ap);
fprintf(stderr, "\n");
va_end(ap);
}
char *dup_basename(const char *name, const char *ext)
{
int namelen;
int extlen = strlen(ext);
char *base;
char *slash;
if(!name)
name = "wmc.tab";
slash = strrchr(name, '/');
if (slash)
name = slash + 1;
namelen = strlen(name);
/* +4 for later extension and +1 for '\0' */
base = (char *)xmalloc(namelen +4 +1);
strcpy(base, name);
if(!strcasecmp(name + namelen-extlen, ext))
{
base[namelen - extlen] = '\0';
}
return base;
}
void *xmalloc(size_t size)
{
void *res;
assert(size > 0);
assert(size < 102400);
res = malloc(size);
if(res == NULL)
{
error("Virtual memory exhausted.\n");
}
/*
* We set it to 0.
* This is *paramount* because we depend on it
* just about everywhere in the rest of the code.
*/
memset(res, 0, size);
return res;
}
void *xrealloc(void *p, size_t size)
{
void *res;
assert(size > 0);
assert(size < 102400);
res = realloc(p, size);
if(res == NULL)
{
error("Virtual memory exhausted.\n");
}
return res;
}
char *xstrdup(const char *str)
{
char *s;
assert(str != NULL);
s = (char *)xmalloc(strlen(str)+1);
return strcpy(s, str);
}
int unistrlen(const WCHAR *s)
{
int n;
for(n = 0; *s; n++, s++)
;
return n;
}
WCHAR *unistrcpy(WCHAR *dst, const WCHAR *src)
{
WCHAR *t = dst;
while(*src)
*t++ = *src++;
*t = 0;
return dst;
}
WCHAR *xunistrdup(const WCHAR * str)
{
WCHAR *s;
assert(str != NULL);
s = (WCHAR *)xmalloc((unistrlen(str)+1) * sizeof(WCHAR));
return unistrcpy(s, str);
}
int unistricmp(const WCHAR *s1, const WCHAR *s2)
{
int i;
int once = 0;
static char warn[] = "Don't know the uppercase equivalent of non acsii characters;"
"comparison might yield wrong results";
while(*s1 && *s2)
{
if((*s1 & 0xffff) > 0x7f || (*s2 & 0xffff) > 0x7f)
{
if(!once)
{
once++;
yywarning(warn);
}
i = *s1++ - *s2++;
}
else
i = toupper(*s1++) - toupper(*s2++);
if(i)
return i;
}
if((*s1 & 0xffff) > 0x7f || (*s2 & 0xffff) > 0x7f)
{
if(!once)
yywarning(warn);
return *s1 - *s2;
}
else
return toupper(*s1) - toupper(*s2);
}
int unistrcmp(const WCHAR *s1, const WCHAR *s2)
{
int i;
while(*s1 && *s2)
{
i = *s1++ - *s2++;
if(i)
return i;
}
return *s1 - *s2;
}
/*
* Utility routines' prototypes etc.
*
* Copyright 1998,2000 Bertho A. Stultiens (BS)
*
*/
#ifndef __WMC_UTILS_H
#define __WMC_UTILS_H
#ifndef __WMC_WMCTYPES_H
#include "wmctypes.h"
#endif
#include <stddef.h> /* size_t */
void *xmalloc(size_t);
void *xrealloc(void *, size_t);
char *xstrdup(const char *str);
int yyerror(const char *s, ...) __attribute__((format (printf, 1, 2)));
int xyyerror(const char *s, ...) __attribute__((format (printf, 1, 2)));
int yywarning(const char *s, ...) __attribute__((format (printf, 1, 2)));
void internal_error(const char *file, int line, const char *s, ...) __attribute__((format (printf, 3, 4)));
void error(const char *s, ...) __attribute__((format (printf, 1, 2)));
void warning(const char *s, ...) __attribute__((format (printf, 1, 2)));
char *dup_basename(const char *name, const char *ext);
WCHAR *xunistrdup(const WCHAR * str);
WCHAR *unistrcpy(WCHAR *dst, const WCHAR *src);
int unistrlen(const WCHAR *s);
int unistricmp(const WCHAR *s1, const WCHAR *s2);
int unistrcmp(const WCHAR *s1, const WCHAR *s2);
#endif
/*
* Wine Message Compiler main program
*
* Copyright 2000 Bertho A. Stultiens (BS)
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include "config.h"
#include "wmc.h"
#include "utils.h"
#include "lang.h"
#include "write.h"
static char usage[] =
"Usage: wmc [options...] [inputfile.mc]\n"
" -B x Set output byte-order x={n[ative], l[ittle], b[ig]}\n"
" (default is n[ative] which equals "
#ifdef WORDS_BIGENDIAN
"big"
#else
"little"
#endif
"-endian)\n"
" -c Set 'custom-bit' in values\n"
" -d Use decimal values in output\n"
" -D Set debug flag\n"
" -h This message\n"
" -H file Write headerfile to file (default is inputfile.h)\n"
" -i Inline messagetable(s)\n"
" -o file Output to file (default is inputfile.rc)\n"
" -u Inputfile is in unicode\n"
" -U Output unicode messagetable(s)\n"
" -v Show supported codepages and languages\n"
" -V Print version end exit\n"
" -W Enable pedantic warnings\n"
"Input is taken from stdin if no inputfile is specified.\n"
"Byteorder of unicode input is based upon the first couple of\n"
"bytes read, which should be 0x0000..0x00ff.\n"
;
static char version_string[] =
"Wine Message Compiler Version " WMC_FULLVERSION "\n"
"Copyright 2000 Bertho A. Stultiens\n"
;
/*
* The output byte-order of resources (set with -B)
*/
int byteorder = WMC_BO_NATIVE;
/*
* Custom bit (bit 29) in output values must be set (-c option)
*/
int custombit = 0;
/*
* Output decimal values (-d option)
*/
int decimal = 0;
/*
* Enable pedantic warnings; check arg references (-W option)
*/
int pedantic = 0;
/*
* Unicode input (-u option)
*/
int unicodein = 0;
/*
* Unicode output (-U option)
*/
int unicodeout = 0;
/*
* Inline the messagetables (don't write *.bin files; -i option)
*/
int rcinline = 0;
/*
* Debugging flag (-D option)
*/
int dodebug = 0;
char *output_name = NULL; /* The name given by the -o option */
char *input_name = NULL; /* The name given on the command-line */
char *header_name = NULL; /* The name given by the -H option */
int line_number = 1; /* The current line */
int char_number = 1; /* The current char pos within the line */
char *cmdline; /* The entire commandline */
time_t now; /* The time of start of wmc */
int getopt (int argc, char *const *argv, const char *optstring);
static void segvhandler(int sig);
int main(int argc,char *argv[])
{
extern char* optarg;
extern int optind;
int optc;
int lose = 0;
int ret;
int i;
int cmdlen;
signal(SIGSEGV, segvhandler);
now = time(NULL);
/* First rebuild the commandline to put in destination */
/* Could be done through env[], but not all OS-es support it */
cmdlen = 4; /* for "wmc " */
for(i = 1; i < argc; i++)
cmdlen += strlen(argv[i]) + 1;
cmdline = (char *)xmalloc(cmdlen);
strcpy(cmdline, "wmc ");
for(i = 1; i < argc; i++)
{
strcat(cmdline, argv[i]);
if(i < argc-1)
strcat(cmdline, " ");
}
while((optc = getopt(argc, argv, "B:cdDhH:io:p:uUvVW")) != EOF)
{
switch(optc)
{
case 'B':
switch(optarg[0])
{
case 'n':
case 'N':
byteorder = WMC_BO_NATIVE;
break;
case 'l':
case 'L':
byteorder = WMC_BO_LITTLE;
break;
case 'b':
case 'B':
byteorder = WMC_BO_BIG;
break;
default:
fprintf(stderr, "Byteordering must be n[ative], l[ittle] or b[ig]\n");
lose++;
}
break;
case 'c':
custombit = 1;
break;
case 'd':
decimal = 1;
break;
case 'D':
dodebug = 1;
break;
case 'h':
printf("%s", usage);
exit(0);
/* No return */
case 'H':
header_name = xstrdup(optarg);
break;
case 'i':
rcinline = 1;
break;
case 'o':
output_name = xstrdup(optarg);
break;
case 'u':
unicodein = 1;
break;
case 'U':
unicodeout = 1;
break;
case 'v':
show_languages();
show_codepages();
exit(0);
/* No return */
case 'V':
printf(version_string);
exit(0);
/* No return */
case 'W':
pedantic = 1;
break;
default:
lose++;
break;
}
}
if(lose)
{
fprintf(stderr, "%s", usage);
return 1;
}
yydebug = dodebug;
if(dodebug)
{
setbuf(stdout, 0);
setbuf(stderr, 0);
}
/* Check for input file on command-line */
if(optind < argc)
{
input_name = argv[optind];
}
/* Generate appropriate outfile names */
if(!output_name)
{
output_name = dup_basename(input_name, ".mc");
strcat(output_name, ".rc");
}
if(!header_name)
{
header_name = dup_basename(input_name, ".mc");
strcat(header_name, ".h");
}
if(input_name)
{
if(!(yyin = fopen(input_name, "rb")))
error("Could not open %s for input\n", input_name);
}
else
yyin = stdin;
ret = yyparse();
if(input_name)
fclose(yyin);
if(ret)
{
/* Error during parse */
exit(1);
}
write_h_file(header_name);
write_rc_file(output_name);
if(!rcinline)
write_bin_files();
return 0;
}
static void segvhandler(int sig)
{
fprintf(stderr, "\n%s:%d: Oops, segment violation\n", input_name, line_number);
fflush(stdout);
fflush(stderr);
abort();
}
/*
* Main definitions and externals
*
* Copyright 2000 Bertho A. Stultiens (BS)
*
*/
#ifndef __WMC_WMC_H
#define __WMC_WMC_H
#ifndef __WMC_WMCTYPES_H
#include "wmctypes.h"
#endif
#include <time.h> /* For time_t */
#define WMC_MAJOR_VERSION 1
#define WMC_MINOR_VERSION 0
#define WMC_MICRO_VERSION 0
#define WMC_RELEASEDATE "(12-Jun-2000)"
#define WMC_STRINGIZE(a) #a
#define WMC_VERSIONIZE(a,b,c) WMC_STRINGIZE(a) "." WMC_STRINGIZE(b) "." WMC_STRINGIZE(c)
#define WMC_VERSION WMC_VERSIONIZE(WMC_MAJOR_VERSION, WMC_MINOR_VERSION, WMC_MICRO_VERSION)
#define WMC_FULLVERSION WMC_VERSION " " WMC_RELEASEDATE
/*
* The default codepage setting is only to
* read and convert input which is non-message
* text. It doesn't really matter that much because
* all codepages map 0x00-0x7f to 0x0000-0x007f from
* char to unicode and all non-message text should
* be plain ASCII.
* However, we do implement iso-8859-1 for 1-to-1
* mapping for all other chars, so this is very close
* to what we really want.
*/
#define WMC_DEFAULT_CODEPAGE 28591
extern int pedantic;
extern int leave_case;
extern int byteorder;
extern int decimal;
extern int custombit;
extern int unicodein;
extern int unicodeout;
extern int rcinline;
extern char *output_name;
extern char *input_name;
extern char *header_name;
extern char *cmdline;
extern time_t now;
extern int line_number;
extern int char_number;
int yyparse(void);
extern int yydebug;
extern int want_nl;
extern int want_line;
extern int want_file;
extern node_t *nodehead;
extern lan_blk_t *lanblockhead;
int yylex(void);
FILE *yyin;
void set_codepage(int cp);
void add_token(tok_e type, const WCHAR *name, int tok, int cp, const WCHAR *alias, int fix);
token_t *lookup_token(const WCHAR *s);
void get_tokentable(token_t **tab, int *len);
#endif
.TH WMC 1 "June 12, 2000" "Version 1.0.0" "Wine Message Compiler"
.SH NAME
wrc \- Wine Message Compiler
.SH SYNOPSIS
.BI "wmc " "[options] " "[inputfile]"
.SH DESCRIPTION
.B wmc
compiles messages from
.B inputfile
into FormatMessage[AW] compatible format encapsulated in a resourcescript
format.
.B wmc
outputs the data either in a standard \fB.bin\fR formatted binary
file, or can generated inline resource data.
.PP
.B wmc
takes only one \fBinputfile\fR as argument (see \fBBUGS\fR). The
\fBinputfile\fR normally has extension \fB.mc\fR. The messages are read from
standard input if no inputfile is given. If the outputfile is not specified
with \fI-o\fR, then \fBwmc\fR will write the output to \fBinputfile.{rc,h}\fR.
The outputfile is named \fBwmc.tab.{rc,h}\fR if no inputfile was given.
.SH OPTIONS
.TP
.I \-B x
Set output byte-order x={n[ative], l[ittle], b[ig]}. Default is n[ative].
.TP
.I \-c
Set 'custom-bit' in message-code values.
.TP
.I \-d
NON-FUNCTIONAL; Use decimal values in output
.TP
.I \-D
Set debug flag. This results is a parser trace and a lot of extra messages.
.TP
.I \-h
Print an informative usage message.
.TP
.I \-H file
Write headerfile to \fIfile\fR. Default is \fIinputfile.h\fR.
.TP
.I \-i
Inline messagetable(s). This option skips the generation of all \fI.bin\fR files
and writes all output into the \fI.rc\fR file. This encoding is parsable with
wrc(1).
.TP
.I \-o file
Output to \fIfile\fR. Default is \fIinputfile.rc\fR.
.TP
.I \-u
Assume that the inputfile is in unicode.
.TP
.I \-U
Write resource output in unicode formatted messagetable(s).
.TP
.I \-v
Show all supported codepages and languages.
.TP
.I \-V
Print version end exit.
.TP
.I \-W
Enable pedantic warnings.
.SH EXTENSIONS
The original syntax is extended to support codepages more smoothly. Normally,
codepages are based on the DOS\-codepage from the language setting. The
original syntax only allows the destination codepage to be set. However, this
is not enough for non\-DOS systems which do not use unicode source-files.
.PP
A new keyword \fICodepages\fR is introduced to set both input and output
codepages to anything one wants for each language. The syntax is similar to
the other constructs:
.PP
Codepages '=' '(' language '=' cpin ':' cpout ... ')'
.PP
The \fIlanguage\fR is the numerical language\-ID or the alias set with
LanguageNames. The input\-codepage \fIcpin\fR and output\-codepage
\fIcpout\fR are the numerical codepage\-IDs. There can be multiple mapping
within the definition and the definition may occur more than once.
.SH AUTHORS
.B wmc
was written by Bertho A. Stultiens.
.SH BUGS
The message compiler should be able to have multiple inputfiles and combine
them into one outputfile. This would enable the splitting of languages into
separate files.
.PP
Unicode detection of the input is suboptimal, to say the least. It should
recognize byte\-order\-marks (BOM) and decide what to do.
.PP
Decimal output is completely lacking. Don't know whether it should be
implemented because it is a, well, non-informative format change. It is
recognized on the commandline for some form of compatibility.
.SH AVAILABILITY
.B wmc
is part of the wine distribution, which is available through
WineHQ, the
.B wine
development headquarters, at
.I http://www.winehq.com/.
.SH "SEE ALSO"
.BR wine (1),
.BR wrc (1)
/*
* Main definitions and externals
*
* Copyright 2000 Bertho A. Stultiens (BS)
*
*/
#ifndef __WMC_WMCTYPES_H
#define __WMC_WMCTYPES_H
#ifndef __WINE_WINDEF_H
#include "windef.h"
#endif
/* Byteordering defines */
#define WMC_BO_NATIVE 0x00
#define WMC_BO_LITTLE 0x01
#define WMC_BO_BIG 0x02
#define WMC_LOBYTE(w) ((WORD)(w) & 0xff)
#define WMC_HIBYTE(w) (((WORD)(w) >> 8) & 0xff)
#define WMC_LOWORD(d) ((DWORD)(d) & 0xffff)
#define WMC_HIWORD(d) (((DWORD)(d) >> 16) & 0xffff)
#define BYTESWAP_WORD(w) ((WORD)(((WORD)WMC_LOBYTE(w) << 8) + (WORD)WMC_HIBYTE(w)))
#define BYTESWAP_DWORD(d) ((DWORD)(((DWORD)BYTESWAP_WORD(WMC_LOWORD(d)) << 16) + ((DWORD)BYTESWAP_WORD(WMC_HIWORD(d)))))
/*
* Tokenizer types
*/
typedef enum tok_enum {
tok_null = 0,
tok_keyword,
tok_severity,
tok_facility,
tok_language
} tok_e;
typedef struct token {
tok_e type;
const WCHAR *name; /* Parsed name of token */
int token; /* Tokenvalue or language code */
int codepage;
const WCHAR *alias; /* Alias or filename */
int fixed; /* Cleared if token may change */
} token_t;
typedef struct lan_cp {
int language;
int codepage;
} lan_cp_t;
typedef struct cp_xlat {
int lan;
int cpin;
int cpout;
} cp_xlat_t;
typedef struct lanmsg {
int lan; /* Language code of message */
int cp; /* Codepage of message */
WCHAR *msg; /* Message text */
int len; /* Message length including trailing '\0' */
} lanmsg_t;
typedef struct msg {
int id; /* Message ID */
unsigned realid; /* Combined message ID */
WCHAR *sym; /* Symbolic name */
int sev; /* Severity code */
int fac; /* Facility code */
lanmsg_t **msgs; /* Array message texts */
int nmsgs; /* Number of message texts in array */
int base; /* Base of number to print */
WCHAR *cast; /* Typecase to use */
} msg_t;
typedef enum {
nd_msg,
nd_comment
} node_e;
typedef struct node {
struct node *next;
struct node *prev;
node_e type;
union {
void *all;
WCHAR *comment;
msg_t *msg;
} u;
} node_t;
typedef struct block {
unsigned idlo; /* Lowest ID in this set */
unsigned idhi; /* Highest ID in this set */
int size; /* Size of this set */
lanmsg_t **msgs; /* Array of messages in this set */
int nmsg; /* Number of array entries */
} block_t;
typedef struct lan_blk {
struct lan_blk *next; /* Linkage for languages */
struct lan_blk *prev;
int lan; /* The language of this block */
block_t *blks; /* Array of blocks for this language */
int nblk; /* Nr of blocks in array */
} lan_blk_t;
#endif
/*
* Wine Message Compiler outpur generation
*
* Copyright 2000 Bertho A. Stultiens (BS)
*
*/
#ifndef __WMC_WRITE_H
#define __WMC_WRITE_H
void write_h_file(const char *fname);
void write_rc_file(const char *fname);
void write_bin_files(void);
#endif
......@@ -208,6 +208,6 @@ int cp_wcstombs( const union cptable *table, int flags,
if (flags || defchar || used)
return wcstombs_dbcs_slow( &table->dbcs, flags, src, srclen,
dst, dstlen, defchar, used );
return wcstombs_sbcs( &table->sbcs, src, srclen, dst, dstlen );
return wcstombs_dbcs( &table->dbcs, src, srclen, dst, dstlen );
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment