summaryrefslogtreecommitdiff
path: root/binutils
diff options
context:
space:
mode:
Diffstat (limited to 'binutils')
-rw-r--r--binutils/ChangeLog17
-rw-r--r--binutils/Makefile.am42
-rw-r--r--binutils/Makefile.in101
-rw-r--r--binutils/NEWS10
-rwxr-xr-xbinutils/configure19
-rw-r--r--binutils/configure.in16
-rw-r--r--binutils/doc/Makefile.am8
-rw-r--r--binutils/doc/Makefile.in13
-rw-r--r--binutils/doc/binutils.texi167
-rw-r--r--binutils/mclex.c441
-rw-r--r--binutils/mcparse.y356
-rw-r--r--binutils/windmc.c1197
-rw-r--r--binutils/windmc.h99
13 files changed, 2443 insertions, 43 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 18568bbea6..c210ccc956 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,18 @@
+2007-06-19 Kai Tietz <kai.tietz@onevision.com>
+
+ * Makefile.am: Add windmc tool.
+ * Makefile.in: Regenerate.
+ * configure.in: Add windmc tool.
+ * configure: Regenerate.
+ * mclex.c: New.
+ * mcparse.y: New.
+ * windmc.c: New.
+ * windmc.h: New.
+ * doc/Makefile.am: Add windmc tool.
+ * doc/Makefile.in: Regenerate.
+ * doc/binutils.texi: Add windmc documentation.
+ * NEWS: Mention new tool.
+
2007-06-18 Andi Kleen <ak@suse.de>
* objdump.c: Include sys/mman.h
@@ -28,7 +43,7 @@
* winduni.h: (wind_default_codepage, wind_current_codepage):
Export.
* doc/binutils.texi: Document new option.
- * NEWS: Mention new feature.
+ * NEWS: Mention new features of windres.
2007-06-18 Brian D. Watt <bwatt@us.ibm.com>
diff --git a/binutils/Makefile.am b/binutils/Makefile.am
index 3b36d1578a..24a34fd73e 100644
--- a/binutils/Makefile.am
+++ b/binutils/Makefile.am
@@ -48,18 +48,19 @@ ADDR2LINE_PROG=addr2line
NLMCONV_PROG=nlmconv
DLLTOOL_PROG=dlltool
WINDRES_PROG=windres
+WINDMC_PROG=windmc
DLLWRAP_PROG=dllwrap
SRCONV_PROG=srconv$(EXEEXT) sysdump$(EXEEXT) coffdump$(EXEEXT)
-bin_PROGRAMS = $(SIZE_PROG) $(OBJDUMP_PROG) $(AR_PROG) $(STRINGS_PROG) $(RANLIB_PROG) $(OBJCOPY_PROG) @BUILD_NLMCONV@ @BUILD_SRCONV@ @BUILD_DLLTOOL@ @BUILD_WINDRES@ $(ADDR2LINE_PROG) $(READELF_PROG) @BUILD_DLLWRAP@ @BUILD_INSTALL_MISC@
+bin_PROGRAMS = $(SIZE_PROG) $(OBJDUMP_PROG) $(AR_PROG) $(STRINGS_PROG) $(RANLIB_PROG) $(OBJCOPY_PROG) @BUILD_NLMCONV@ @BUILD_SRCONV@ @BUILD_DLLTOOL@ @BUILD_WINDRES@ @BUILD_WINDMC@ $(ADDR2LINE_PROG) $(READELF_PROG) @BUILD_DLLWRAP@ @BUILD_INSTALL_MISC@
## We need a special rule to install the programs which are built with
## -new, and to rename cxxfilt to c++filt.
RENAMED_PROGS = $(NM_PROG) $(STRIP_PROG) $(DEMANGLER_PROG)
noinst_PROGRAMS = $(RENAMED_PROGS) @BUILD_MISC@
-EXTRA_PROGRAMS = $(NLMCONV_PROG) srconv sysdump coffdump $(DLLTOOL_PROG) $(WINDRES_PROG) $(DLLWRAP_PROG)
+EXTRA_PROGRAMS = $(NLMCONV_PROG) srconv sysdump coffdump $(DLLTOOL_PROG) $(WINDRES_PROG) $(WINDMC_PROG) $(DLLWRAP_PROG)
# Stuff that goes in tooldir/ if appropriate.
TOOL_PROGS = nm-new strip-new ar ranlib dlltool objdump objcopy
@@ -80,9 +81,10 @@ INCLUDES = -D_GNU_SOURCE \
HFILES = \
arsup.h binemul.h bucomm.h budbg.h \
coffgrok.h debug.h dlltool.h nlmconv.h \
- windres.h winduni.h windint.h
+ windres.h winduni.h windint.h \
+ windmc.h
-GENERATED_HFILES = arparse.h sysroff.h sysinfo.h defparse.h rcparse.h
+GENERATED_HFILES = arparse.h sysroff.h sysinfo.h defparse.h rcparse.h mcparse.h
CFILES = \
addr2line.c ar.c arsup.c bin2c.c binemul.c bucomm.c \
@@ -95,11 +97,12 @@ CFILES = \
rclex.c rdcoff.c rddbg.c readelf.c rename.c \
resbin.c rescoff.c resrc.c resres.c \
size.c srconv.c stabs.c strings.c sysdump.c version.c \
- windres.c winduni.c wrstabs.c
+ windres.c winduni.c wrstabs.c \
+ windmc.c mclex.c
GENERATED_CFILES = \
arparse.c arlex.c sysroff.c sysinfo.c syslex.c \
- defparse.c deflex.c nlmheader.c rcparse.c
+ defparse.c deflex.c nlmheader.c rcparse.c mcparse.c
DEBUG_SRCS = rddbg.c debug.c stabs.c ieee.c rdcoff.c
WRITE_DEBUG_SRCS = $(DEBUG_SRCS) wrstabs.c
@@ -198,6 +201,7 @@ sysdump_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
coffdump_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
dlltool_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
windres_DEPENDENCIES = $(LIBINTL_DEP) $(LIBICONV) $(LIBIBERTY) $(BFDLIB)
+windmc_DEPENDENCIES = $(LIBINTL_DEP) $(LIBICONV) $(LIBIBERTY) $(BFDLIB)
addr2line_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
readelf_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY)
dllwrap_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY)
@@ -290,6 +294,7 @@ arparse.h: arparse.c
defparse.h: defparse.c
nlmheader.h: nlmheader.c
rcparse.h: rcparse.c
+mcparse.h: mcparse.c
sysinfo.h: sysinfo.c
# Disable -Werror, if it has been enabled, since old versions of bison/
@@ -308,8 +313,12 @@ nlmheader.o:
$(COMPILE) -c $< $(NO_WERROR)
rcparse.o:
$(COMPILE) -c $< $(NO_WERROR)
+mcparse.o:
+ $(COMPILE) -c $< $(NO_WERROR)
rclex.o:
$(COMPILE) -c $< $(NO_WERROR)
+mclex.o:
+ $(COMPILE) -c $< $(NO_WERROR)
srconv_SOURCES = srconv.c coffgrok.c $(BULIBS)
@@ -338,12 +347,17 @@ windres_SOURCES = windres.c resrc.c rescoff.c resbin.c rcparse.y rclex.c \
winduni.c resres.c $(BULIBS)
windres_LDADD = $(BFDLIB) $(LIBIBERTY) @LEXLIB@ $(LIBINTL)
+windmc_SOURCES = windmc.c mcparse.y mclex.c \
+ winduni.c $(BULIBS)
+windmc_LDADD = $(BFDLIB) $(LIBIBERTY) @LEXLIB@ $(LIBINTL)
+
dllwrap_SOURCES = dllwrap.c version.c
dllwrap_LDADD = $(LIBIBERTY) $(LIBINTL)
EXTRA_DIST = arparse.c arparse.h arlex.c nlmheader.c sysinfo.c sysinfo.h \
- syslex.c deflex.c defparse.h defparse.c rcparse.h rcparse.c
+ syslex.c deflex.c defparse.h defparse.c rcparse.h rcparse.c \
+ mcparse.h mcparse.c
diststuff: $(EXTRA_DIST) info
all: info
@@ -626,6 +640,11 @@ windres.o: windres.c sysdep.h $(INCDIR)/ansidecl.h \
$(INCDIR)/ansidecl.h $(INCDIR)/symcat.h $(INCDIR)/libiberty.h \
$(INCDIR)/ansidecl.h $(INCDIR)/safe-ctype.h $(INCDIR)/obstack.h \
bucomm.h windres.h winduni.h windint.h
+windmc.o: windmc.c sysdep.h $(INCDIR)/ansidecl.h \
+ ../bfd/bfdver.h config.h $(INCDIR)/fopen-same.h ../bfd/bfd.h \
+ $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h $(INCDIR)/libiberty.h \
+ $(INCDIR)/ansidecl.h $(INCDIR)/safe-ctype.h $(INCDIR)/obstack.h \
+ bucomm.h windmc.h winduni.h windint.h
winduni.o: winduni.c sysdep.h $(INCDIR)/ansidecl.h \
../bfd/bfdver.h config.h $(INCDIR)/fopen-same.h ../bfd/bfd.h \
$(INCDIR)/ansidecl.h $(INCDIR)/symcat.h winduni.h $(INCDIR)/safe-ctype.h
@@ -659,8 +678,17 @@ rcparse.o: rcparse.c sysdep.h $(INCDIR)/ansidecl.h \
$(INCDIR)/ansidecl.h $(INCDIR)/symcat.h $(INCDIR)/libiberty.h \
$(INCDIR)/ansidecl.h windres.h winduni.h windint.h \
$(INCDIR)/safe-ctype.h
+mcparse.o: mcparse.c sysdep.h $(INCDIR)/ansidecl.h \
+ ../bfd/bfdver.h config.h $(INCDIR)/fopen-same.h ../bfd/bfd.h \
+ $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h $(INCDIR)/libiberty.h \
+ $(INCDIR)/ansidecl.h windmc.h winduni.h \
+ $(INCDIR)/safe-ctype.h
rclex.o: rclex.c sysdep.h $(INCDIR)/ansidecl.h ../bfd/bfdver.h \
config.h $(INCDIR)/fopen-same.h ../bfd/bfd.h $(INCDIR)/ansidecl.h \
$(INCDIR)/symcat.h $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h \
$(INCDIR)/safe-ctype.h windres.h winduni.h windint.h rcparse.h
+mclex.o: mclex.c sysdep.h $(INCDIR)/ansidecl.h ../bfd/bfdver.h \
+ config.h $(INCDIR)/fopen-same.h ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/symcat.h $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/safe-ctype.h windmc.h winduni.h mcparse.h
# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
diff --git a/binutils/Makefile.in b/binutils/Makefile.in
index f43cfc07fe..6ce70d5ffc 100644
--- a/binutils/Makefile.in
+++ b/binutils/Makefile.in
@@ -37,23 +37,23 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
-bin_PROGRAMS = $(am__EXEEXT_5) $(am__EXEEXT_6) $(am__EXEEXT_7) \
- $(am__EXEEXT_8) $(am__EXEEXT_9) $(am__EXEEXT_10) \
+bin_PROGRAMS = $(am__EXEEXT_6) $(am__EXEEXT_7) $(am__EXEEXT_8) \
+ $(am__EXEEXT_9) $(am__EXEEXT_10) $(am__EXEEXT_11) \
@BUILD_NLMCONV@ @BUILD_SRCONV@ @BUILD_DLLTOOL@ @BUILD_WINDRES@ \
- $(am__EXEEXT_11) $(am__EXEEXT_12) @BUILD_DLLWRAP@ \
- @BUILD_INSTALL_MISC@ $(am__empty)
-noinst_PROGRAMS = $(am__EXEEXT_16) @BUILD_MISC@
+ @BUILD_WINDMC@ $(am__EXEEXT_12) $(am__EXEEXT_13) \
+ @BUILD_DLLWRAP@ @BUILD_INSTALL_MISC@ $(am__empty)
+noinst_PROGRAMS = $(am__EXEEXT_17) @BUILD_MISC@
EXTRA_PROGRAMS = $(am__EXEEXT_1) srconv$(EXEEXT) sysdump$(EXEEXT) \
coffdump$(EXEEXT) $(am__EXEEXT_2) $(am__EXEEXT_3) \
- $(am__EXEEXT_4)
+ $(am__EXEEXT_4) $(am__EXEEXT_5)
DIST_COMMON = $(srcdir)/../config.guess $(srcdir)/../config.sub NEWS \
README ChangeLog $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/configure $(am__configure_deps) \
$(srcdir)/config.in $(srcdir)/../mkinstalldirs \
$(top_srcdir)/po/Make-in arparse.h arparse.c arlex.c \
defparse.h defparse.c deflex.c nlmheader.h nlmheader.c \
- arparse.h arparse.c arlex.c rcparse.h rcparse.c \
- $(srcdir)/../ylwrap $(srcdir)/../ltmain.sh \
+ arparse.h arparse.c arlex.c mcparse.h mcparse.c rcparse.h \
+ rcparse.c $(srcdir)/../ylwrap $(srcdir)/../ltmain.sh \
$(srcdir)/../config.guess $(srcdir)/../config.sub
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -81,21 +81,22 @@ CONFIG_CLEAN_FILES = po/Makefile.in
am__EXEEXT_1 = nlmconv$(EXEEXT)
am__EXEEXT_2 = dlltool$(EXEEXT)
am__EXEEXT_3 = windres$(EXEEXT)
-am__EXEEXT_4 = dllwrap$(EXEEXT)
-am__EXEEXT_5 = size$(EXEEXT)
-am__EXEEXT_6 = objdump$(EXEEXT)
-am__EXEEXT_7 = ar$(EXEEXT)
-am__EXEEXT_8 = strings$(EXEEXT)
-am__EXEEXT_9 = ranlib$(EXEEXT)
-am__EXEEXT_10 = objcopy$(EXEEXT)
-am__EXEEXT_11 = addr2line$(EXEEXT)
-am__EXEEXT_12 = readelf$(EXEEXT)
+am__EXEEXT_4 = windmc$(EXEEXT)
+am__EXEEXT_5 = dllwrap$(EXEEXT)
+am__EXEEXT_6 = size$(EXEEXT)
+am__EXEEXT_7 = objdump$(EXEEXT)
+am__EXEEXT_8 = ar$(EXEEXT)
+am__EXEEXT_9 = strings$(EXEEXT)
+am__EXEEXT_10 = ranlib$(EXEEXT)
+am__EXEEXT_11 = objcopy$(EXEEXT)
+am__EXEEXT_12 = addr2line$(EXEEXT)
+am__EXEEXT_13 = readelf$(EXEEXT)
am__installdirs = "$(DESTDIR)$(bindir)"
binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
-am__EXEEXT_13 = nm-new$(EXEEXT)
-am__EXEEXT_14 = strip-new$(EXEEXT)
-am__EXEEXT_15 = cxxfilt$(EXEEXT)
-am__EXEEXT_16 = $(am__EXEEXT_13) $(am__EXEEXT_14) $(am__EXEEXT_15)
+am__EXEEXT_14 = nm-new$(EXEEXT)
+am__EXEEXT_15 = strip-new$(EXEEXT)
+am__EXEEXT_16 = cxxfilt$(EXEEXT)
+am__EXEEXT_17 = $(am__EXEEXT_14) $(am__EXEEXT_15) $(am__EXEEXT_16)
PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
am__objects_1 = bucomm.$(OBJEXT) version.$(OBJEXT) filemode.$(OBJEXT)
am_addr2line_OBJECTS = addr2line.$(OBJEXT) $(am__objects_1)
@@ -162,6 +163,9 @@ strip_new_LDADD = $(LDADD)
am_sysdump_OBJECTS = sysdump.$(OBJEXT) $(am__objects_1)
sysdump_OBJECTS = $(am_sysdump_OBJECTS)
sysdump_LDADD = $(LDADD)
+am_windmc_OBJECTS = windmc.$(OBJEXT) mcparse.$(OBJEXT) mclex.$(OBJEXT) \
+ winduni.$(OBJEXT) $(am__objects_1)
+windmc_OBJECTS = $(am_windmc_OBJECTS)
am_windres_OBJECTS = windres.$(OBJEXT) resrc.$(OBJEXT) \
rescoff.$(OBJEXT) resbin.$(OBJEXT) rcparse.$(OBJEXT) \
rclex.$(OBJEXT) winduni.$(OBJEXT) resres.$(OBJEXT) \
@@ -189,7 +193,8 @@ SOURCES = $(addr2line_SOURCES) $(ar_SOURCES) $(coffdump_SOURCES) \
$(nlmconv_SOURCES) $(nm_new_SOURCES) $(objcopy_SOURCES) \
$(objdump_SOURCES) $(ranlib_SOURCES) $(readelf_SOURCES) \
$(size_SOURCES) $(srconv_SOURCES) $(strings_SOURCES) \
- $(strip_new_SOURCES) $(sysdump_SOURCES) $(windres_SOURCES)
+ $(strip_new_SOURCES) $(sysdump_SOURCES) $(windmc_SOURCES) \
+ $(windres_SOURCES)
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
install-exec-recursive install-info-recursive \
@@ -217,6 +222,7 @@ BUILD_INSTALL_MISC = @BUILD_INSTALL_MISC@
BUILD_MISC = @BUILD_MISC@
BUILD_NLMCONV = @BUILD_NLMCONV@
BUILD_SRCONV = @BUILD_SRCONV@
+BUILD_WINDMC = @BUILD_WINDMC@
BUILD_WINDRES = @BUILD_WINDRES@
CATALOGS = @CATALOGS@
CATOBJEXT = @CATOBJEXT@
@@ -375,6 +381,7 @@ ADDR2LINE_PROG = addr2line
NLMCONV_PROG = nlmconv
DLLTOOL_PROG = dlltool
WINDRES_PROG = windres
+WINDMC_PROG = windmc
DLLWRAP_PROG = dllwrap
SRCONV_PROG = srconv$(EXEEXT) sysdump$(EXEEXT) coffdump$(EXEEXT)
RENAMED_PROGS = $(NM_PROG) $(STRIP_PROG) $(DEMANGLER_PROG)
@@ -395,9 +402,10 @@ INCLUDES = -D_GNU_SOURCE \
HFILES = \
arsup.h binemul.h bucomm.h budbg.h \
coffgrok.h debug.h dlltool.h nlmconv.h \
- windres.h winduni.h windint.h
+ windres.h winduni.h windint.h \
+ windmc.h
-GENERATED_HFILES = arparse.h sysroff.h sysinfo.h defparse.h rcparse.h
+GENERATED_HFILES = arparse.h sysroff.h sysinfo.h defparse.h rcparse.h mcparse.h
CFILES = \
addr2line.c ar.c arsup.c bin2c.c binemul.c bucomm.c \
coffdump.c coffgrok.c cxxfilt.c \
@@ -409,11 +417,12 @@ CFILES = \
rclex.c rdcoff.c rddbg.c readelf.c rename.c \
resbin.c rescoff.c resrc.c resres.c \
size.c srconv.c stabs.c strings.c sysdump.c version.c \
- windres.c winduni.c wrstabs.c
+ windres.c winduni.c wrstabs.c \
+ windmc.c mclex.c
GENERATED_CFILES = \
arparse.c arlex.c sysroff.c sysinfo.c syslex.c \
- defparse.c deflex.c nlmheader.c rcparse.c
+ defparse.c deflex.c nlmheader.c rcparse.c mcparse.c
DEBUG_SRCS = rddbg.c debug.c stabs.c ieee.c rdcoff.c
WRITE_DEBUG_SRCS = $(DEBUG_SRCS) wrstabs.c
@@ -460,6 +469,7 @@ sysdump_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
coffdump_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
dlltool_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
windres_DEPENDENCIES = $(LIBINTL_DEP) $(LIBICONV) $(LIBIBERTY) $(BFDLIB)
+windmc_DEPENDENCIES = $(LIBINTL_DEP) $(LIBICONV) $(LIBIBERTY) $(BFDLIB)
addr2line_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
readelf_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY)
dllwrap_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY)
@@ -493,10 +503,15 @@ windres_SOURCES = windres.c resrc.c rescoff.c resbin.c rcparse.y rclex.c \
winduni.c resres.c $(BULIBS)
windres_LDADD = $(BFDLIB) $(LIBIBERTY) @LEXLIB@ $(LIBINTL)
+windmc_SOURCES = windmc.c mcparse.y mclex.c \
+ winduni.c $(BULIBS)
+
+windmc_LDADD = $(BFDLIB) $(LIBIBERTY) @LEXLIB@ $(LIBINTL)
dllwrap_SOURCES = dllwrap.c version.c
dllwrap_LDADD = $(LIBIBERTY) $(LIBINTL)
EXTRA_DIST = arparse.c arparse.h arlex.c nlmheader.c sysinfo.c sysinfo.h \
- syslex.c deflex.c defparse.h defparse.c rcparse.h rcparse.c
+ syslex.c deflex.c defparse.h defparse.c rcparse.h rcparse.c \
+ mcparse.h mcparse.c
DISTCLEANFILES = sysroff.c sysroff.h site.exp site.bak
@@ -516,15 +531,15 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- echo ' cd $(srcdir) && $(AUTOMAKE) --cygnus '; \
- cd $(srcdir) && $(AUTOMAKE) --cygnus \
+ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign '; \
+ cd $(srcdir) && $(AUTOMAKE) --foreign \
&& exit 0; \
exit 1;; \
esac; \
done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --cygnus Makefile'; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
cd $(top_srcdir) && \
- $(AUTOMAKE) --cygnus Makefile
+ $(AUTOMAKE) --foreign Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
@@ -648,6 +663,9 @@ strip-new$(EXEEXT): $(strip_new_OBJECTS) $(strip_new_DEPENDENCIES)
sysdump$(EXEEXT): $(sysdump_OBJECTS) $(sysdump_DEPENDENCIES)
@rm -f sysdump$(EXEEXT)
$(LINK) $(sysdump_LDFLAGS) $(sysdump_OBJECTS) $(sysdump_LDADD) $(LIBS)
+windmc$(EXEEXT): $(windmc_OBJECTS) $(windmc_DEPENDENCIES)
+ @rm -f windmc$(EXEEXT)
+ $(LINK) $(windmc_LDFLAGS) $(windmc_OBJECTS) $(windmc_LDADD) $(LIBS)
windres$(EXEEXT): $(windres_OBJECTS) $(windres_DEPENDENCIES)
@rm -f windres$(EXEEXT)
$(LINK) $(windres_LDFLAGS) $(windres_OBJECTS) $(windres_LDADD) $(LIBS)
@@ -879,6 +897,8 @@ maintainer-clean-generic:
-rm -f deflex.c
-rm -f defparse.c
-rm -f defparse.h
+ -rm -f mcparse.c
+ -rm -f mcparse.h
-rm -f nlmheader.c
-rm -f nlmheader.h
-rm -f rcparse.c
@@ -1060,6 +1080,7 @@ arparse.h: arparse.c
defparse.h: defparse.c
nlmheader.h: nlmheader.c
rcparse.h: rcparse.c
+mcparse.h: mcparse.c
sysinfo.h: sysinfo.c
# Disable -Werror, if it has been enabled, since old versions of bison/
@@ -1078,8 +1099,12 @@ nlmheader.o:
$(COMPILE) -c $< $(NO_WERROR)
rcparse.o:
$(COMPILE) -c $< $(NO_WERROR)
+mcparse.o:
+ $(COMPILE) -c $< $(NO_WERROR)
rclex.o:
$(COMPILE) -c $< $(NO_WERROR)
+mclex.o:
+ $(COMPILE) -c $< $(NO_WERROR)
dlltool.o:
$(COMPILE) -c $(DLLTOOL_DEFS) $(srcdir)/dlltool.c
@@ -1365,6 +1390,11 @@ windres.o: windres.c sysdep.h $(INCDIR)/ansidecl.h \
$(INCDIR)/ansidecl.h $(INCDIR)/symcat.h $(INCDIR)/libiberty.h \
$(INCDIR)/ansidecl.h $(INCDIR)/safe-ctype.h $(INCDIR)/obstack.h \
bucomm.h windres.h winduni.h windint.h
+windmc.o: windmc.c sysdep.h $(INCDIR)/ansidecl.h \
+ ../bfd/bfdver.h config.h $(INCDIR)/fopen-same.h ../bfd/bfd.h \
+ $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h $(INCDIR)/libiberty.h \
+ $(INCDIR)/ansidecl.h $(INCDIR)/safe-ctype.h $(INCDIR)/obstack.h \
+ bucomm.h windmc.h winduni.h windint.h
winduni.o: winduni.c sysdep.h $(INCDIR)/ansidecl.h \
../bfd/bfdver.h config.h $(INCDIR)/fopen-same.h ../bfd/bfd.h \
$(INCDIR)/ansidecl.h $(INCDIR)/symcat.h winduni.h $(INCDIR)/safe-ctype.h
@@ -1398,10 +1428,19 @@ rcparse.o: rcparse.c sysdep.h $(INCDIR)/ansidecl.h \
$(INCDIR)/ansidecl.h $(INCDIR)/symcat.h $(INCDIR)/libiberty.h \
$(INCDIR)/ansidecl.h windres.h winduni.h windint.h \
$(INCDIR)/safe-ctype.h
+mcparse.o: mcparse.c sysdep.h $(INCDIR)/ansidecl.h \
+ ../bfd/bfdver.h config.h $(INCDIR)/fopen-same.h ../bfd/bfd.h \
+ $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h $(INCDIR)/libiberty.h \
+ $(INCDIR)/ansidecl.h windmc.h winduni.h \
+ $(INCDIR)/safe-ctype.h
rclex.o: rclex.c sysdep.h $(INCDIR)/ansidecl.h ../bfd/bfdver.h \
config.h $(INCDIR)/fopen-same.h ../bfd/bfd.h $(INCDIR)/ansidecl.h \
$(INCDIR)/symcat.h $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h \
$(INCDIR)/safe-ctype.h windres.h winduni.h windint.h rcparse.h
+mclex.o: mclex.c sysdep.h $(INCDIR)/ansidecl.h ../bfd/bfdver.h \
+ config.h $(INCDIR)/fopen-same.h ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/symcat.h $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/safe-ctype.h windmc.h winduni.h mcparse.h
# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/binutils/NEWS b/binutils/NEWS
index 3eceac03a0..ad6058f75b 100644
--- a/binutils/NEWS
+++ b/binutils/NEWS
@@ -1,6 +1,14 @@
-*- text -*-
-* Add codepage support to the windres tool.
+* A new tool "windmc" has been added for some targets. This is a message
+ compiler which attempts to be compatible with the MS version.
+
+* Add codepage support to the windres tool. It now supports many new
+ resource types (e.g. MANIFEST, TOOLBAR, etc). The output generation
+ for binary files is done now via bfd itself. The endianess problems
+ for different hosts are solved. Dumps of .res files can now be
+ re-compiled by windres without lossing resources or compilation errors.
+ Some problems on dialog resource translations are corrected.
* Add --extract-symbol command line option to objcopy, which will
strip everything out of an ordinary object file or executable except
diff --git a/binutils/configure b/binutils/configure
index 288004f18d..a10a8adcc0 100755
--- a/binutils/configure
+++ b/binutils/configure
@@ -458,7 +458,7 @@ ac_includes_default="\
# include <unistd.h>
#endif"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE LIBTOOL SED EGREP FGREP GREP LD DUMPBIN ac_ct_DUMPBIN NM LN_S AR ac_ct_AR RANLIB ac_ct_RANLIB lt_ECHO CPP WARN_CFLAGS NO_WERROR YACC LEX LEXLIB LEX_OUTPUT_ROOT USE_NLS LIBINTL LIBINTL_DEP INCINTL XGETTEXT GMSGFMT POSUB CATALOGS DATADIRNAME INSTOBJEXT GENCAT CATOBJEXT MKINSTALLDIRS MSGFMT MSGMERGE MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT GENINSRC_NEVER_TRUE GENINSRC_NEVER_FALSE HDEFINES CC_FOR_BUILD EXEEXT_FOR_BUILD DEMANGLER_NAME ALLOCA LIBICONV LTLIBICONV NLMCONV_DEFS BUILD_NLMCONV BUILD_SRCONV BUILD_DLLTOOL DLLTOOL_DEFS BUILD_WINDRES BUILD_DLLWRAP BUILD_MISC BUILD_INSTALL_MISC OBJDUMP_DEFS EMULATION EMULATION_VECTOR datarootdir docdir htmldir LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE LIBTOOL SED EGREP FGREP GREP LD DUMPBIN ac_ct_DUMPBIN NM LN_S AR ac_ct_AR RANLIB ac_ct_RANLIB lt_ECHO CPP WARN_CFLAGS NO_WERROR YACC LEX LEXLIB LEX_OUTPUT_ROOT USE_NLS LIBINTL LIBINTL_DEP INCINTL XGETTEXT GMSGFMT POSUB CATALOGS DATADIRNAME INSTOBJEXT GENCAT CATOBJEXT MKINSTALLDIRS MSGFMT MSGMERGE MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT GENINSRC_NEVER_TRUE GENINSRC_NEVER_FALSE HDEFINES CC_FOR_BUILD EXEEXT_FOR_BUILD DEMANGLER_NAME ALLOCA LIBICONV LTLIBICONV NLMCONV_DEFS BUILD_NLMCONV BUILD_SRCONV BUILD_DLLTOOL DLLTOOL_DEFS BUILD_WINDRES BUILD_WINDMC BUILD_DLLWRAP BUILD_MISC BUILD_INSTALL_MISC OBJDUMP_DEFS EMULATION EMULATION_VECTOR datarootdir docdir htmldir LIBOBJS LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
@@ -14417,6 +14417,7 @@ BUILD_DLLTOOL=
DLLTOOL_DEFS=
DLLTOOL_DEFAULT=
BUILD_WINDRES=
+BUILD_WINDMC=
BUILD_DLLWRAP=
BUILD_MISC=
BUILD_INSTALL_MISC=
@@ -14460,6 +14461,7 @@ do
fi
DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_ARM_EPOC -DDLLTOOL_ARM"
BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
+ BUILD_WINDMC='$(WINDMC_PROG)$(EXEEXT)'
;;
arm-wince-pe* | arm-*-wince)
BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)'
@@ -14468,6 +14470,7 @@ do
fi
DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_ARM_WINCE -DDLLTOOL_ARM"
BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
+ BUILD_WINDMC='$(WINDMC_PROG)$(EXEEXT)'
;;
arm-*-pe*)
BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)'
@@ -14476,6 +14479,7 @@ do
fi
DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_ARM"
BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
+ BUILD_WINDMC='$(WINDMC_PROG)$(EXEEXT)'
;;
thumb-*-pe*)
BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)'
@@ -14484,6 +14488,7 @@ do
fi
DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_ARM"
BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
+ BUILD_WINDMC='$(WINDMC_PROG)$(EXEEXT)'
;;
x86_64-*-mingw*)
BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)'
@@ -14492,6 +14497,7 @@ do
fi
DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_MX86_64"
BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
+ BUILD_WINDMC='$(WINDMC_PROG)$(EXEEXT)'
BUILD_DLLWRAP='$(DLLWRAP_PROG)$(EXEEXT)'
;;
i[3-7]86-*-pe* | i[3-7]86-*-cygwin* | i[3-7]86-*-mingw32** | i[3-7]86-*-netbsdpe*)
@@ -14501,6 +14507,7 @@ do
fi
DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_I386"
BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
+ BUILD_WINDMC='$(WINDMC_PROG)$(EXEEXT)'
BUILD_DLLWRAP='$(DLLWRAP_PROG)$(EXEEXT)'
;;
i[3-7]86-*-interix)
@@ -14522,6 +14529,7 @@ do
fi
DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_PPC"
BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
+ BUILD_WINDMC='$(WINDMC_PROG)$(EXEEXT)'
;;
powerpc*-*-linux* | powerpc*-*-elf*)
BUILD_INSTALL_MISC="${BUILD_INSTALL_MISC} embedspu"
@@ -14533,6 +14541,7 @@ do
fi
DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_SH"
BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
+ BUILD_WINDMC='$(WINDMC_PROG)$(EXEEXT)'
;;
spu-*-*)
BUILD_MISC="${BUILD_MISC} "'bin2c$(EXEEXT_FOR_BUILD)'
@@ -14544,6 +14553,7 @@ do
fi
DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_MIPS"
BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
+ BUILD_WINDMC='$(WINDMC_PROG)$(EXEEXT)'
;;
mcore-*-pe)
BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)'
@@ -14552,6 +14562,7 @@ do
fi
DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_MCORE"
BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
+ BUILD_WINDMC='$(WINDMC_PROG)$(EXEEXT)'
;;
mcore-*-elf)
BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)'
@@ -14573,6 +14584,11 @@ if test "${with_windres+set}" = set; then
BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
fi
+if test "${with_windmc+set}" = set; then
+ BUILD_WINDMC='$(WINDMC_PROG)$(EXEEXT)'
+fi
+
+
@@ -15637,6 +15653,7 @@ s,@BUILD_SRCONV@,$BUILD_SRCONV,;t t
s,@BUILD_DLLTOOL@,$BUILD_DLLTOOL,;t t
s,@DLLTOOL_DEFS@,$DLLTOOL_DEFS,;t t
s,@BUILD_WINDRES@,$BUILD_WINDRES,;t t
+s,@BUILD_WINDMC@,$BUILD_WINDMC,;t t
s,@BUILD_DLLWRAP@,$BUILD_DLLWRAP,;t t
s,@BUILD_MISC@,$BUILD_MISC,;t t
s,@BUILD_INSTALL_MISC@,$BUILD_INSTALL_MISC,;t t
diff --git a/binutils/configure.in b/binutils/configure.in
index fe1bb9fe83..19aaabc867 100644
--- a/binutils/configure.in
+++ b/binutils/configure.in
@@ -211,6 +211,7 @@ BUILD_DLLTOOL=
DLLTOOL_DEFS=
DLLTOOL_DEFAULT=
BUILD_WINDRES=
+BUILD_WINDMC=
BUILD_DLLWRAP=
BUILD_MISC=
BUILD_INSTALL_MISC=
@@ -256,6 +257,7 @@ changequote([,])dnl
fi
DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_ARM_EPOC -DDLLTOOL_ARM"
BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
+ BUILD_WINDMC='$(WINDMC_PROG)$(EXEEXT)'
;;
arm-wince-pe* | arm-*-wince)
BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)'
@@ -264,6 +266,7 @@ changequote([,])dnl
fi
DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_ARM_WINCE -DDLLTOOL_ARM"
BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
+ BUILD_WINDMC='$(WINDMC_PROG)$(EXEEXT)'
;;
arm-*-pe*)
BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)'
@@ -272,6 +275,7 @@ changequote([,])dnl
fi
DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_ARM"
BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
+ BUILD_WINDMC='$(WINDMC_PROG)$(EXEEXT)'
;;
thumb-*-pe*)
BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)'
@@ -280,6 +284,7 @@ changequote([,])dnl
fi
DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_ARM"
BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
+ BUILD_WINDMC='$(WINDMC_PROG)$(EXEEXT)'
;;
x86_64-*-mingw*)
BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)'
@@ -288,6 +293,7 @@ changequote([,])dnl
fi
DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_MX86_64"
BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
+ BUILD_WINDMC='$(WINDMC_PROG)$(EXEEXT)'
BUILD_DLLWRAP='$(DLLWRAP_PROG)$(EXEEXT)'
;;
changequote(,)dnl
@@ -299,6 +305,7 @@ changequote([,])dnl
fi
DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_I386"
BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
+ BUILD_WINDMC='$(WINDMC_PROG)$(EXEEXT)'
BUILD_DLLWRAP='$(DLLWRAP_PROG)$(EXEEXT)'
;;
changequote(,)dnl
@@ -324,6 +331,7 @@ changequote([,])dnl
fi
DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_PPC"
BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
+ BUILD_WINDMC='$(WINDMC_PROG)$(EXEEXT)'
;;
powerpc*-*-linux* | powerpc*-*-elf*)
BUILD_INSTALL_MISC="${BUILD_INSTALL_MISC} embedspu"
@@ -335,6 +343,7 @@ changequote([,])dnl
fi
DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_SH"
BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
+ BUILD_WINDMC='$(WINDMC_PROG)$(EXEEXT)'
;;
spu-*-*)
BUILD_MISC="${BUILD_MISC} "'bin2c$(EXEEXT_FOR_BUILD)'
@@ -346,6 +355,7 @@ changequote([,])dnl
fi
DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_MIPS"
BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
+ BUILD_WINDMC='$(WINDMC_PROG)$(EXEEXT)'
;;
mcore-*-pe)
BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)'
@@ -354,6 +364,7 @@ changequote([,])dnl
fi
DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_MCORE"
BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
+ BUILD_WINDMC='$(WINDMC_PROG)$(EXEEXT)'
;;
mcore-*-elf)
BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)'
@@ -375,12 +386,17 @@ if test "${with_windres+set}" = set; then
BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
fi
+if test "${with_windmc+set}" = set; then
+ BUILD_WINDMC='$(WINDMC_PROG)$(EXEEXT)'
+fi
+
AC_SUBST(NLMCONV_DEFS)
AC_SUBST(BUILD_NLMCONV)
AC_SUBST(BUILD_SRCONV)
AC_SUBST(BUILD_DLLTOOL)
AC_SUBST(DLLTOOL_DEFS)
AC_SUBST(BUILD_WINDRES)
+AC_SUBST(BUILD_WINDMC)
AC_SUBST(BUILD_DLLWRAP)
AC_SUBST(BUILD_MISC)
AC_SUBST(BUILD_INSTALL_MISC)
diff --git a/binutils/doc/Makefile.am b/binutils/doc/Makefile.am
index 5d8520cf52..ceeda41b00 100644
--- a/binutils/doc/Makefile.am
+++ b/binutils/doc/Makefile.am
@@ -28,6 +28,7 @@ man_MANS = \
strings.1 \
strip.1 \
windres.1 \
+ windmc.1 \
$(DEMANGLER_NAME).1
info_TEXINFOS = binutils.texi
@@ -130,6 +131,13 @@ windres.1: $(binutils_TEXI) $(binutils_TEXINFOS)
mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1)
rm -f windres.pod
+windmc.1: $(binutils_TEXI) $(binutils_TEXINFOS)
+ touch $@
+ -$(TEXI2POD) $(MANCONF) -Dwindmc < $(binutils_TEXI) > windmc.pod
+ -($(POD2MAN) windmc.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \
+ mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1)
+ rm -f windmc.pod
+
cxxfilt.man: $(binutils_TEXI) $(binutils_TEXINFOS)
touch $@
-$(TEXI2POD) $(MANCONF) -Dcxxfilt < $(binutils_TEXI) > $(DEMANGLER_NAME).pod
diff --git a/binutils/doc/Makefile.in b/binutils/doc/Makefile.in
index 12928a138f..2455745999 100644
--- a/binutils/doc/Makefile.in
+++ b/binutils/doc/Makefile.in
@@ -93,6 +93,7 @@ BUILD_INSTALL_MISC = @BUILD_INSTALL_MISC@
BUILD_MISC = @BUILD_MISC@
BUILD_NLMCONV = @BUILD_NLMCONV@
BUILD_SRCONV = @BUILD_SRCONV@
+BUILD_WINDMC = @BUILD_WINDMC@
BUILD_WINDRES = @BUILD_WINDRES@
CATALOGS = @CATALOGS@
CATOBJEXT = @CATOBJEXT@
@@ -249,6 +250,7 @@ man_MANS = \
strings.1 \
strip.1 \
windres.1 \
+ windmc.1 \
$(DEMANGLER_NAME).1
info_TEXINFOS = binutils.texi
@@ -280,9 +282,9 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
exit 1;; \
esac; \
done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --cygnus doc/Makefile'; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/Makefile'; \
cd $(top_srcdir) && \
- $(AUTOMAKE) --cygnus doc/Makefile
+ $(AUTOMAKE) --foreign doc/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
@@ -679,6 +681,13 @@ windres.1: $(binutils_TEXI) $(binutils_TEXINFOS)
mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1)
rm -f windres.pod
+windmc.1: $(binutils_TEXI) $(binutils_TEXINFOS)
+ touch $@
+ -$(TEXI2POD) $(MANCONF) -Dwindmc < $(binutils_TEXI) > windmc.pod
+ -($(POD2MAN) windmc.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \
+ mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1)
+ rm -f windmc.pod
+
cxxfilt.man: $(binutils_TEXI) $(binutils_TEXINFOS)
touch $@
-$(TEXI2POD) $(MANCONF) -Dcxxfilt < $(binutils_TEXI) > $(DEMANGLER_NAME).pod
diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi
index 9591fe9e9c..da49e1f521 100644
--- a/binutils/doc/binutils.texi
+++ b/binutils/doc/binutils.texi
@@ -25,6 +25,7 @@ START-INFO-DIR-ENTRY
* addr2line: (binutils)addr2line. Convert addresses to file and line
* nlmconv: (binutils)nlmconv. Converts object code into an NLM
* windres: (binutils)windres. Manipulate Windows resources
+* windmc: (binutils)windmc. Generator for Windows message resources
* dlltool: (binutils)dlltool. Create files needed to build and use DLLs
END-INFO-DIR-ENTRY
@end format
@@ -145,6 +146,9 @@ Convert object code into a Netware Loadable Module
@item windres
Manipulate Windows resources
+@item windmc
+Genertor for Windows message resources
+
@item dlltool
Create the files needed to build and use Dynamic Link Libraries
@end table
@@ -169,6 +173,7 @@ section entitled "GNU Free Documentation License".
* addr2line:: Convert addresses to file and line
* nlmconv:: Converts object code into an NLM
* windres:: Manipulate Windows resources
+* windmc:: Generator for Windows message resources
* dlltool:: Create files needed to build and use DLLs
* Common Options:: Command-line options for all utilities
* Selecting The Target System:: How these utilities determine the target.
@@ -2869,6 +2874,168 @@ the Info entries for @file{binutils}.
@c man end
@end ignore
+@node windmc
+@chapter windmc
+
+@command{windmc} may be used to generator Windows message resources.
+
+@quotation
+@emph{Warning:} @command{windmc} is not always built as part of the binary
+utilities, since it is only useful for Windows targets.
+@end quotation
+
+@c man title windmc generates Windows message resources.
+
+@smallexample
+@c man begin SYNOPSIS windres
+windmc [options] input-file
+@c man end
+@end smallexample
+
+@c man begin DESCRIPTION windmc
+
+@command{windmc} reads message definitions from an input file (.mc) and
+translate them into a set of output files. The output files may be of
+four kinds:
+
+@table @code
+@item h
+A C header file containing the message definitions.
+
+@item rc
+A resource file compilable by the @command{windres} tool.
+
+@item bin
+One or more binary files containing the resource data for a specific
+message language.
+
+@item dbg
+A C include file that maps message id's to their symbolic name.
+@end table
+
+The exact description of these different formats is available in
+documentation from Microsoft.
+
+When @command{windmc} converts from the @code{mc} format to the @code{bin}
+format, @code{rc}, @code{h}, and optional @code{dbg} it is acting like the
+Windows Message Compiler.
+
+@c man end
+
+@c man begin OPTIONS windmc
+
+@table @env
+@item -a
+@itemx --ascii_in
+Specifies that the input file specified is ANSI. This is the default
+behaviour.
+
+@item -A
+@itemx --ascii_out
+Specifies that messages in the output @code{bin} files should be in ANSI
+format.
+
+@item -b
+@itemx --binprefix
+Specifies that @code{bin} filenames should have to be prefixed by the
+basename of the source file.
+
+@item -c
+@itemx --customflag
+Sets the customer bit in all message id's.
+
+@item -C @var{codepage}
+@itemx --codepage_in @var{codepage}
+Sets the default codepage to be used to convert input file to UTF16. The
+default is ocdepage 1252.
+
+@item -d
+@itemx --decimal_values
+Outputs the constants in the header file in decimal. Default is using
+hexadecimal output.
+
+@item -e @var{ext}
+@itemx --extension @var{ext}
+The extension for the header file. The default is .h extension.
+
+@item -F @var{target}
+@itemx --target @var{target}
+Specify the BFD format to use for a bin file as output. This
+is a BFD target name; you can use the @option{--help} option to see a list
+of supported targets. Normally @command{windmc} will use the default
+format, which is the first one listed by the @option{--help} option.
+@ifclear man
+@ref{Target Selection}.
+@end ifclear
+
+@item -h @var{path}
+@itemx --headerdir @var{path}
+The target directory of the generated header file. The default is the
+current directory.
+
+@item -H
+@itemx --help
+Displays a list of command line options and then exits.
+
+@item -m @var{characters}
+@itemx --maxlength @var{characters}
+Instructs @command{windmc} to generate a warning if the length
+of any message exceeds the number specified.
+
+@item -n
+@itemx --nullterminate
+Terminate message text in @code{bin} files by zero. By default they are
+terminated by CR/LF.
+
+@item -o
+@itemx --hresult_use
+Not yet implemented. Instructs @code{windmc} to generate an OLE2 header
+file, using HRESULT definitions. Status codes are used if the flag is not
+specified.
+
+@item -O @var{codepage}
+@itemx --codepage_out @var{codepage}
+Sets the default codepage to be used to output text files. The default
+is ocdepage 1252.
+
+@item -r @var{path}
+@itemx --rcdir @var{path}
+The target directory for the generated @code{rc} script and the generated
+@code{bin} files that the resource compiler script includes. The default
+is the current directory.
+
+@item -u
+@itemx --unicode_in
+Specifies that the input file is UTF16.
+
+@item -U
+@itemx --unicode_out
+Specifies that messages in the output @code{bin} file should be in UTF16
+format. This is the default behaviour.
+
+@item -v
+@item --verbose
+Enable verbose mode. This tells you what the preprocessor is if you
+didn't specify one.
+
+@item -V
+@item --version
+Prints the version number for @command{windres}.
+
+@item -x @var{path}
+@itemx --xdgb @var{path}
+The path of the @code{dbg} C include file that maps message id's to the
+symbolic name. No such file is generated without specifying the switch.
+@end table
+
+@c man end
+
+@ignore
+@c man begin SEEALSO windmc
+the Info entries for @file{binutils}.
+@c man end
+@end ignore
+
@node windres
@chapter windres
diff --git a/binutils/mclex.c b/binutils/mclex.c
new file mode 100644
index 0000000000..f6cedd9efd
--- /dev/null
+++ b/binutils/mclex.c
@@ -0,0 +1,441 @@
+/* mclex.c -- lexer for Windows mc files parser.
+ Copyright 2007
+ Free Software Foundation, Inc.
+
+ Written by Kai Tietz, Onevision.
+
+ This file is part of GNU Binutils.
+
+ 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., 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+/* This is a lexer used by the Windows rc file parser.
+ It basically just recognized a bunch of keywords. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bucomm.h"
+#include "libiberty.h"
+#include "safe-ctype.h"
+#include "windmc.h"
+#include "mcparse.h"
+
+#include <assert.h>
+
+/* Exported globals. */
+bfd_boolean mclex_want_nl = FALSE;
+bfd_boolean mclex_want_line = FALSE;
+bfd_boolean mclex_want_filename = FALSE;
+
+/* Local globals. */
+static unichar *input_stream = NULL;
+static unichar *input_stream_pos = NULL;
+static int input_line = 1;
+static const char *input_filename = NULL;
+
+void
+mc_set_content (const unichar *src)
+{
+ if (!src)
+ return;
+ input_stream = input_stream_pos = unichar_dup (src);
+}
+
+void
+mc_set_inputfile (const char *name)
+{
+ if (! name || *name == 0)
+ input_filename = "-";
+ else
+ {
+ const char *s1 = strrchr (name, '/');
+ const char *s2 = strrchr (name, '\\');
+
+ if (! s1)
+ s1 = s2;
+ if (s1 && s2 && s1 < s2)
+ s1 = s2;
+ if (! s1)
+ s1 = name;
+ else
+ s1++;
+ s1 = xstrdup (s1);
+ input_filename = s1;
+ }
+}
+
+static void
+show_msg (const char *kind, const char *msg, va_list argp)
+{
+ fprintf (stderr, "In %s at line %d: %s: ", input_filename, input_line, kind);
+ vfprintf (stderr, msg, argp);
+ fprintf (stderr, ".\n");
+}
+
+void
+mc_warn (const char *s, ...)
+{
+ va_list argp;
+ va_start (argp, s);
+ show_msg ("warning", s, argp);
+ va_end (argp);
+}
+
+void
+mc_fatal (const char *s, ...)
+{
+ va_list argp;
+ va_start (argp, s);
+ show_msg ("fatal", s, argp);
+ va_end (argp);
+ xexit (1);
+}
+
+
+int
+yyerror (const char *s, ...)
+{
+ va_list argp;
+ va_start (argp, s);
+ show_msg ("parser", s, argp);
+ va_end (argp);
+ return 1;
+}
+
+static unichar *
+get_diff (unichar *end, unichar *start)
+{
+ unichar *ret;
+ unichar save = *end;
+
+ *end = 0;
+ ret = unichar_dup (start);
+ *end = save;
+ return ret;
+}
+
+static rc_uint_type
+parse_digit (unichar ch)
+{
+ rc_uint_type base = 10, v = 0, c;
+
+ if (ch == '0')
+ {
+ base = 8;
+ switch (input_stream_pos[0])
+ {
+ case 'x': case 'X': base = 16; input_stream_pos++; break;
+ case 'o': case 'O': base = 8; input_stream_pos++; break;
+ case 'b': case 'B': base = 2; input_stream_pos++; break;
+ }
+ }
+ else
+ v = (rc_uint_type) (ch - '0');
+
+ while ((ch = input_stream_pos[0]) != 0)
+ {
+ if (ch >= 'A' && ch <= 'F')
+ c = (rc_uint_type) (ch - 'A') + 10;
+ else if (ch >= 'a' && ch <= 'f')
+ c = (rc_uint_type) (ch - 'a') + 10;
+ else if (ch >= '0' && ch <= '9')
+ c = (rc_uint_type) (ch - '0');
+ else
+ break;
+ v *= base;
+ v += c;
+ ++input_stream_pos;
+ }
+ if (input_stream_pos[0] == 'U' || input_stream_pos[0] == 'u')
+ input_stream_pos++;
+ if (input_stream_pos[0] == 'L' || input_stream_pos[0] == 'l')
+ input_stream_pos++;
+ if (input_stream_pos[0] == 'L' || input_stream_pos[0] == 'l')
+ input_stream_pos++;
+ return v;
+}
+
+static mc_keyword *keyword_top = NULL;
+
+const mc_keyword *
+enum_facility (int e)
+{
+ mc_keyword *h = keyword_top;
+
+ while (h != NULL)
+ {
+ while (h && strcmp (h->group_name, "facility") != 0)
+ h = h->next;
+ if (e == 0)
+ return h;
+ --e;
+ if (h)
+ h = h->next;
+ }
+ return h;
+}
+
+const mc_keyword *
+enum_severity (int e)
+{
+ mc_keyword *h = keyword_top;
+
+ while (h != NULL)
+ {
+ while (h && strcmp (h->group_name, "severity") != 0)
+ h = h->next;
+ if (e == 0)
+ return h;
+ --e;
+ if (h)
+ h = h->next;
+ }
+ return h;
+}
+
+static void
+mc_add_keyword_ascii (const char *sz, int rid, const char *grp, rc_uint_type nv, const char *sv)
+{
+ unichar *usz, *usv = NULL;
+ rc_uint_type usz_len;
+
+ unicode_from_codepage (&usz_len, &usz, sz, CP_ACP);
+ if (sv)
+ unicode_from_codepage (&usz_len, &usv, sv, CP_ACP);
+ mc_add_keyword (usz, rid, grp, nv, usv);
+}
+
+void
+mc_add_keyword (unichar *usz, int rid, const char *grp, rc_uint_type nv, unichar *sv)
+{
+ mc_keyword *p, *c, *n;
+ size_t len = unichar_len (usz);
+
+ c = keyword_top;
+ p = NULL;
+ while (c != NULL)
+ {
+ if (c->len > len)
+ break;
+ if (c->len == len)
+ {
+ int e = memcmp (usz, c->usz, len * sizeof (unichar));
+
+ if (e < 0)
+ break;
+ if (! e)
+ {
+ if (! strcmp (grp, "keyword") || strcmp (c->group_name, grp) != 0)
+ fatal (_("Duplicate symbol entered into keyword list."));
+ c->rid = rid;
+ c->nval = nv;
+ c->sval = (!sv ? NULL : unichar_dup (sv));
+ if (! strcmp (grp, "language"))
+ {
+ const wind_language_t *lag = wind_find_language_by_id ((unsigned) nv);
+
+ if (lag == NULL)
+ fatal ("Language ident 0x%lx is not resolvable.\n", (long) nv);
+ memcpy (&c->lang_info, lag, sizeof (*lag));
+ }
+ return;
+ }
+ }
+ c = (p = c)->next;
+ }
+ n = xmalloc (sizeof (mc_keyword));
+ n->next = c;
+ n->len = len;
+ n->group_name = grp;
+ n->usz = usz;
+ n->rid = rid;
+ n->nval = nv;
+ n->sval = (!sv ? NULL : unichar_dup (sv));
+ if (! strcmp (grp, "language"))
+ {
+ const wind_language_t *lag = wind_find_language_by_id ((unsigned) nv);
+ if (lag == NULL)
+ fatal ("Language ident 0x%lx is not resolvable.\n", (long) nv);
+ memcpy (&n->lang_info, lag, sizeof (*lag));
+ }
+ if (! p)
+ keyword_top = n;
+ else
+ p->next = n;
+}
+
+static int
+mc_token (const unichar *t, size_t len)
+{
+ static int was_init = 0;
+ mc_keyword *k;
+
+ if (! was_init)
+ {
+ was_init = 1;
+ mc_add_keyword_ascii ("OutputBase", MCOUTPUTBASE, "keyword", 0, NULL);
+ mc_add_keyword_ascii ("MessageIdTypedef", MCMESSAGEIDTYPEDEF, "keyword", 0, NULL);
+ mc_add_keyword_ascii ("SeverityNames", MCSEVERITYNAMES, "keyword", 0, NULL);
+ mc_add_keyword_ascii ("FacilityNames", MCFACILITYNAMES, "keyword", 0, NULL);
+ mc_add_keyword_ascii ("LanguageNames", MCLANGUAGENAMES, "keyword", 0, NULL);
+ mc_add_keyword_ascii ("MessageId", MCMESSAGEID, "keyword", 0, NULL);
+ mc_add_keyword_ascii ("Severity", MCSEVERITY, "keyword", 0, NULL);
+ mc_add_keyword_ascii ("Facility", MCFACILITY, "keyword", 0, NULL);
+ mc_add_keyword_ascii ("SymbolicName", MCSYMBOLICNAME, "keyword", 0, NULL);
+ mc_add_keyword_ascii ("Language", MCLANGUAGE, "keyword", 0, NULL);
+ mc_add_keyword_ascii ("Success", MCTOKEN, "severity", 0, NULL);
+ mc_add_keyword_ascii ("Informational", MCTOKEN, "severity", 1, NULL);
+ mc_add_keyword_ascii ("Warning", MCTOKEN, "severity", 2, NULL);
+ mc_add_keyword_ascii ("Error", MCTOKEN, "severity", 3, NULL);
+ mc_add_keyword_ascii ("System", MCTOKEN, "facility", 0xff, NULL);
+ mc_add_keyword_ascii ("Application", MCTOKEN, "facility", 0xfff, NULL);
+ mc_add_keyword_ascii ("English", MCTOKEN, "language", 0x409, "MSG00001");
+ }
+ k = keyword_top;
+ if (!len || !t || *t == 0)
+ return -1;
+ while (k != NULL)
+ {
+ if (k->len > len)
+ break;
+ if (k->len == len)
+ {
+ if (! memcmp (k->usz, t, len * sizeof (unichar)))
+ {
+ if (k->rid == MCTOKEN)
+ yylval.tok = k;
+ return k->rid;
+ }
+ }
+ k = k->next;
+ }
+ return -1;
+}
+
+int
+yylex (void)
+{
+ unichar *start_token;
+ unichar ch;
+
+ if (! input_stream_pos)
+ {
+ fatal ("Input stream not setuped.\n");
+ return -1;
+ }
+ if (mclex_want_line)
+ {
+ start_token = input_stream_pos;
+ if (input_stream_pos[0] == '.'
+ && (input_stream_pos[1] == '\n'
+ || (input_stream_pos[1] == '\r' && input_stream_pos[2] == '\n')))
+ {
+ mclex_want_line = FALSE;
+ while (input_stream_pos[0] != 0 && input_stream_pos[0] != '\n')
+ ++input_stream_pos;
+ if (input_stream_pos[0] == '\n')
+ ++input_stream_pos;
+ return MCENDLINE;
+ }
+ while (input_stream_pos[0] != 0 && input_stream_pos[0] != '\n')
+ ++input_stream_pos;
+ if (input_stream_pos[0] == '\n')
+ ++input_stream_pos;
+ yylval.ustr = get_diff (input_stream_pos, start_token);
+ return MCLINE;
+ }
+ while ((ch = input_stream_pos[0]) <= 0x20)
+ {
+ if (ch == 0)
+ return -1;
+ ++input_stream_pos;
+ if (ch == '\n')
+ input_line += 1;
+ if (mclex_want_nl && ch == '\n')
+ {
+ mclex_want_nl = FALSE;
+ return NL;
+ }
+ }
+ start_token = input_stream_pos;
+ ++input_stream_pos;
+ if (mclex_want_filename)
+ {
+ mclex_want_filename = FALSE;
+ if (ch == '"')
+ {
+ start_token++;
+ while ((ch = input_stream_pos[0]) != 0)
+ {
+ if (ch == '"')
+ break;
+ ++input_stream_pos;
+ }
+ yylval.ustr = get_diff (input_stream_pos, start_token);
+ if (ch == '"')
+ ++input_stream_pos;
+ }
+ else
+ {
+ while ((ch = input_stream_pos[0]) != 0)
+ {
+ if (ch <= 0x20 || ch == ')')
+ break;
+ ++input_stream_pos;
+ }
+ yylval.ustr = get_diff (input_stream_pos, start_token);
+ }
+ return MCFILENAME;
+ }
+ switch (ch)
+ {
+ case ';':
+ ++start_token;
+ while (input_stream_pos[0] != '\n' && input_stream_pos[0] != 0)
+ ++input_stream_pos;
+ if (input_stream_pos[0] == '\n')
+ input_stream_pos++;
+ yylval.ustr = get_diff (input_stream_pos, start_token);
+ return MCCOMMENT;
+ case '=':
+ return '=';
+ case '(':
+ return '(';
+ case ')':
+ return ')';
+ case '+':
+ return '+';
+ case ':':
+ return ':';
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ yylval.ival = parse_digit (ch);
+ return MCNUMBER;
+ default:
+ if (ch >= 0x40)
+ {
+ int ret;
+ while (input_stream_pos[0] >= 0x40 || (input_stream_pos[0] >= '0' && input_stream_pos[0] <= '9'))
+ ++input_stream_pos;
+ ret = mc_token (start_token, (size_t) (input_stream_pos - start_token));
+ if (ret != -1)
+ return ret;
+ yylval.ustr = get_diff (input_stream_pos, start_token);
+ return MCIDENT;
+ }
+ yyerror ("illegal character 0x%x.", ch);
+ }
+ return -1;
+}
diff --git a/binutils/mcparse.y b/binutils/mcparse.y
new file mode 100644
index 0000000000..9aaba9b8d4
--- /dev/null
+++ b/binutils/mcparse.y
@@ -0,0 +1,356 @@
+%{ /* mcparse.y -- parser for Windows mc files
+ Copyright 2007
+ Free Software Foundation, Inc.
+
+ Parser for Windows mc files
+ Written by Kai Tietz, Onevision.
+
+ This file is part of GNU Binutils.
+
+ 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., 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+/* This is a parser for Windows rc files. It is based on the parser
+ by Gunther Ebert <gunther.ebert@ixos-leipzig.de>. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bucomm.h"
+#include "libiberty.h"
+#include "windmc.h"
+#include "safe-ctype.h"
+
+static rc_uint_type mc_last_id = 0;
+static rc_uint_type mc_sefa_val = 0;
+static unichar *mc_last_symbol = NULL;
+static const mc_keyword *mc_cur_severity = NULL;
+static const mc_keyword *mc_cur_facility = NULL;
+static mc_node *cur_node = NULL;
+
+%}
+
+%union
+{
+ rc_uint_type ival;
+ unichar *ustr;
+ const mc_keyword *tok;
+ mc_node *nod;
+};
+
+%start input
+
+%token NL
+%token<ustr> MCIDENT MCFILENAME MCLINE MCCOMMENT
+%token<tok> MCTOKEN
+%token MCENDLINE
+%token MCLANGUAGENAMES MCFACILITYNAMES MCSEVERITYNAMES MCOUTPUTBASE MCMESSAGEIDTYPEDEF
+%token MCLANGUAGE MCMESSAGEID MCSEVERITY MCFACILITY MCSYMBOLICNAME
+%token <ival> MCNUMBER
+
+%type<ival> id vid sefasy_def
+%type<ustr> alias_name token lines comments
+%type<tok> lang
+
+%%
+input: entities
+ ;
+
+entities:
+ /* empty */
+ | entities entity
+ ;
+entity: global_section
+ | message
+ | comments
+ {
+ cur_node = mc_add_node ();
+ cur_node->user_text = $1;
+ }
+ | error { mc_fatal ("syntax error"); }
+;
+
+global_section:
+ MCSEVERITYNAMES '=' '(' severitymaps ')'
+ | MCSEVERITYNAMES '=' '(' severitymaps error { mc_fatal ("missing ')' in SeverityNames"); }
+ | MCSEVERITYNAMES '=' error { mc_fatal ("missing '(' in SeverityNames"); }
+ | MCSEVERITYNAMES error { mc_fatal ("missing '=' for SeverityNames"); }
+ | MCLANGUAGENAMES '=' '(' langmaps ')'
+ | MCLANGUAGENAMES '=' '(' langmaps error { mc_fatal ("missing ')' in LanguageNames"); }
+ | MCLANGUAGENAMES '=' error { mc_fatal ("missing '(' in LanguageNames"); }
+ | MCLANGUAGENAMES error { mc_fatal ("missing '=' for LanguageNames"); }
+ | MCFACILITYNAMES '=' '(' facilitymaps ')'
+ | MCFACILITYNAMES '=' '(' facilitymaps error { mc_fatal ("missing ')' in FacilityNames"); }
+ | MCFACILITYNAMES '=' error { mc_fatal ("missing '(' in FacilityNames"); }
+ | MCFACILITYNAMES error { mc_fatal ("missing '=' for FacilityNames"); }
+ | MCOUTPUTBASE '=' MCNUMBER
+ {
+ if ($3 != 10 && $3 != 16)
+ mc_fatal ("OutputBase allows 10 or 16 as value");
+ mcset_out_values_are_decimal = ($3 == 10 ? 1 : 0);
+ }
+ | MCMESSAGEIDTYPEDEF '=' MCIDENT
+ {
+ mcset_msg_id_typedef = $3;
+ }
+ | MCMESSAGEIDTYPEDEF '=' error
+ {
+ mc_fatal ("MessageIdTypedef expects an identifier");
+ }
+ | MCMESSAGEIDTYPEDEF error
+ {
+ mc_fatal ("missing '=' for MessageIdTypedef");
+ }
+;
+
+severitymaps:
+ severitymap
+ | severitymaps severitymap
+ | error { mc_fatal ("severity ident missing"); }
+;
+
+severitymap:
+ token '=' MCNUMBER alias_name
+ {
+ mc_add_keyword ($1, MCTOKEN, "severity", $3, $4);
+ }
+ | token '=' error { mc_fatal ("severity number missing"); }
+ | token error { mc_fatal ("severity missing '='"); }
+;
+
+facilitymaps:
+ facilitymap
+ | facilitymaps facilitymap
+ | error { mc_fatal ("missing ident in FacilityNames"); }
+;
+
+facilitymap:
+ token '=' MCNUMBER alias_name
+ {
+ mc_add_keyword ($1, MCTOKEN, "facility", $3, $4);
+ }
+ | token '=' error { mc_fatal ("facility number missing"); }
+ | token error { mc_fatal ("facility missing '='"); }
+;
+
+langmaps:
+ langmap
+ | langmaps langmap
+ | error { mc_fatal ("missing ident in LanguageNames"); }
+;
+
+langmap:
+ token '=' MCNUMBER lex_want_filename ':' MCFILENAME
+ {
+ mc_add_keyword ($1, MCTOKEN, "language", $3, $6);
+ }
+ | token '=' MCNUMBER lex_want_filename ':' error { mc_fatal ("missing filename in LanguageNames"); }
+ | token '=' MCNUMBER error { mc_fatal ("missing ':' in LanguageNames"); }
+ | token '=' error { mc_fatal ("missing language code in LanguageNames"); }
+ | token error { mc_fatal ("missing '=' for LanguageNames"); }
+;
+
+alias_name:
+ /* empty */
+ {
+ $$ = NULL;
+ }
+ | ':' MCIDENT
+ {
+ $$ = $2;
+ }
+ | ':' error { mc_fatal ("illegal token in identifier"); $$ = NULL; }
+;
+
+message:
+ id sefasy_def
+ {
+ cur_node = mc_add_node ();
+ cur_node->symbol = mc_last_symbol;
+ cur_node->facility = mc_cur_facility;
+ cur_node->severity = mc_cur_severity;
+ cur_node->id = ($1 & 0xffffUL);
+ cur_node->vid = ($1 & 0xffffUL) | mc_sefa_val;
+ mc_last_id = $1;
+ }
+ lang_entities
+;
+
+id: MCMESSAGEID '=' vid { $$ = $3; }
+ | MCMESSAGEID '=' error { mc_fatal ("missing number in MessageId"); $$ = 0; }
+ | MCMESSAGEID error { mc_fatal ("missing '=' for MessageId"); $$ = 0; }
+;
+
+vid: /* empty */
+ {
+ $$ = ++mc_last_id;
+ }
+ | MCNUMBER
+ {
+ $$ = $1;
+ }
+ | '+' MCNUMBER
+ {
+ $$ = mc_last_id + $2;
+ }
+ | '+' error { mc_fatal ("missing number after MessageId '+'"); }
+;
+
+sefasy_def:
+ /* empty */
+ {
+ $$ = 0;
+ mc_sefa_val = (mcset_custom_bit ? 1 : 0) << 29;
+ mc_last_symbol = NULL;
+ mc_cur_severity = NULL;
+ mc_cur_facility = NULL;
+ }
+ | sefasy_def severity
+ {
+ if ($1 & 1)
+ mc_warn (_("duplicate definition of Severity"));
+ $$ = $1 | 1;
+ }
+ | sefasy_def facility
+ {
+ if ($1 & 2)
+ mc_warn (_("duplicate definition of Facility"));
+ $$ = $1 | 2;
+ }
+ | sefasy_def symbol
+ {
+ if ($1 & 4)
+ mc_warn (_("duplicate definition of SymbolicName"));
+ $$ = $1 | 4;
+ }
+;
+
+severity: MCSEVERITY '=' MCTOKEN
+ {
+ mc_sefa_val &= ~ (0x3UL << 30);
+ mc_sefa_val |= (($3->nval & 0x3UL) << 30);
+ mc_cur_severity = $3;
+ }
+;
+
+facility: MCFACILITY '=' MCTOKEN
+ {
+ mc_sefa_val &= ~ (0xfffUL << 16);
+ mc_sefa_val |= (($3->nval & 0xfffUL) << 16);
+ mc_cur_facility = $3;
+ }
+;
+
+symbol: MCSYMBOLICNAME '=' MCIDENT
+ {
+ mc_last_symbol = $3;
+ }
+;
+
+lang_entities:
+ lang_entity
+ | lang_entities lang_entity
+;
+
+lang_entity:
+ lang lex_want_line lines MCENDLINE
+ {
+ mc_node_lang *h;
+ h = mc_add_node_lang (cur_node, $1, cur_node->vid);
+ h->message = $3;
+ if (mcset_max_message_length != 0 && unichar_len (h->message) > mcset_max_message_length)
+ mc_warn ("message length to long");
+ }
+;
+
+lines: MCLINE
+ {
+ $$ = $1;
+ }
+ | lines MCLINE
+ {
+ unichar *h;
+ rc_uint_type l1,l2;
+ l1 = unichar_len ($1);
+ l2 = unichar_len ($2);
+ h = (unichar *) res_alloc ((l1 + l2 + 1) * sizeof (unichar));
+ if (l1) memcpy (h, $1, l1 * sizeof (unichar));
+ if (l2) memcpy (&h[l1], $2, l2 * sizeof (unichar));
+ h[l1 + l2] = 0;
+ $$ = h;
+ }
+ | error { mc_fatal ("missing end of message text"); $$ = NULL; }
+ | lines error { mc_fatal ("missing end of message text"); $$ = $1; }
+;
+
+comments: MCCOMMENT { $$ = $1; }
+ | comments MCCOMMENT
+ {
+ unichar *h;
+ rc_uint_type l1,l2;
+ l1 = unichar_len ($1);
+ l2 = unichar_len ($2);
+ h = (unichar *) res_alloc ((l1 + l2 + 1) * sizeof (unichar));
+ if (l1) memcpy (h, $1, l1 * sizeof (unichar));
+ if (l2) memcpy (&h[l1], $2, l2 * sizeof (unichar));
+ h[l1 + l2] = 0;
+ $$ = h;
+ }
+;
+
+lang: MCLANGUAGE lex_want_nl '=' MCTOKEN NL
+ {
+ $$ = $4;
+ }
+ | MCLANGUAGE lex_want_nl '=' MCIDENT NL
+ {
+ $$ = NULL;
+ mc_fatal (_("undeclared language identifier"));
+ }
+ | MCLANGUAGE lex_want_nl '=' token error
+ {
+ $$ = NULL;
+ mc_fatal ("missing newline after Language");
+ }
+ | MCLANGUAGE lex_want_nl '=' error
+ {
+ $$ = NULL;
+ mc_fatal ("missing ident for Language");
+ }
+ | MCLANGUAGE error
+ {
+ $$ = NULL;
+ mc_fatal ("missing '=' for Language");
+ }
+;
+
+token: MCIDENT { $$ = $1; }
+ | MCTOKEN { $$ = $1->usz; }
+;
+
+lex_want_nl:
+ /* Empty */ { mclex_want_nl = 1; }
+;
+
+lex_want_line:
+ /* Empty */ { mclex_want_line = 1; }
+;
+
+lex_want_filename:
+ /* Empty */ { mclex_want_filename = 1; }
+;
+
+%%
+
+/* Something else. */
diff --git a/binutils/windmc.c b/binutils/windmc.c
new file mode 100644
index 0000000000..5465b351cd
--- /dev/null
+++ b/binutils/windmc.c
@@ -0,0 +1,1197 @@
+/* windmc.c -- a program to compile Windows message files.
+ Copyright 2007
+ Free Software Foundation, Inc.
+ Written by Kai Tietz, Onevision.
+
+ This file is part of GNU Binutils.
+
+ 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., 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+/* This program can read and comile Windows message format.
+
+ It is based on information taken from the following sources:
+
+ * Microsoft documentation.
+
+ * The wmc program, written by Bertho A. Stultiens (BS). */
+
+#include "sysdep.h"
+#include <assert.h>
+#include <time.h>
+#include "bfd.h"
+#include "getopt.h"
+#include "bucomm.h"
+#include "libiberty.h"
+#include "safe-ctype.h"
+#include "obstack.h"
+
+#include "windmc.h"
+#include "windint.h"
+
+/* Defines a message compiler element item with length and offset
+ information. */
+typedef struct mc_msg_item
+{
+ rc_uint_type res_len;
+ rc_uint_type res_off;
+ struct bin_messagetable_item *res;
+} mc_msg_item;
+
+/* Defined in bfd/binary.c. Used to set architecture and machine of input
+ binary files. */
+extern enum bfd_architecture bfd_external_binary_architecture;
+extern unsigned long bfd_external_machine;
+
+int target_is_bigendian = 0;
+const char *def_target_arch;
+
+/* Globals and static variable definitions. */
+
+/* bfd global helper struct variable. */
+static struct
+{
+ bfd *abfd;
+ asection *sec;
+} mc_bfd;
+
+/* Memory list. */
+mc_node *mc_nodes = NULL;
+static mc_node_lang **mc_nodes_lang = NULL;
+static int mc_nodes_lang_count = 0;
+static mc_keyword **mc_severity_codes = NULL;
+static int mc_severity_codes_count = 0;
+static mc_keyword **mc_facility_codes = NULL;
+static int mc_facility_codes_count = 0;
+
+/* When we are building a resource tree, we allocate everything onto
+ an obstack, so that we can free it all at once if we want. */
+#define obstack_chunk_alloc xmalloc
+#define obstack_chunk_free free
+
+/* The resource building obstack. */
+static struct obstack res_obstack;
+
+/* Flag variables. */
+/* Set by -C. Set the default code page to be used for input text file. */
+static rc_uint_type mcset_codepage_in = 0;
+
+/* Set by -O. Set the default code page to be used for output text files. */
+static rc_uint_type mcset_codepage_out = 0;
+
+/* Set by -b. .BIN filename should have .mc filename_ included for uniqueness. */
+static int mcset_prefix_bin = 0;
+
+/* The base name of the .mc file. */
+static const char *mcset_mc_basename = "unknown";
+
+/* Set by -e <ext>. Specify the extension for the header file. */
+static const char *mcset_header_ext = ".h";
+
+/* Set by -h <path>. Gives the path of where to create the C include file. */
+static const char *mcset_header_dir = "./";
+
+/* Set by -r <path>. Gives the path of where to create the RC include file
+ and the binary message resource files it includes. */
+static const char *mcset_rc_dir = "./";
+
+/* Modified by -a & -u. By -u input file is unicode, by -a is ASCII (default). */
+static int mcset_text_in_is_unicode = 0;
+
+/* Modified by -A & -U. By -U bin file is unicode (default), by -A is ASCII. */
+static int mcset_bin_out_is_unicode = 1;
+
+/* Set by -c. Sets the Customer bit in all the message ID's. */
+int mcset_custom_bit = 0;
+
+/* Set by -o. Generate OLE2 header file. Use HRESULT definition instead of
+ status code definition. */
+static int mcset_use_hresult = 0;
+
+/* Set by -m <msglen>. Generate a warning if the size of any message exceeds
+ maxmsglen characters. */
+rc_uint_type mcset_max_message_length = 0;
+
+/* Set by -d. Sets message values in header to decimal initially. */
+int mcset_out_values_are_decimal = 0;
+
+/* Set by -n. terminates all strings with null's in the message tables. */
+static int mcset_automatic_null_termination = 0;
+
+/* The type used for message id output in header. */
+unichar *mcset_msg_id_typedef = NULL;
+
+/* Set by -x path. Geberated debug C file for mapping ID's to text. */
+static const char *mcset_dbg_dir = NULL;
+
+/* getopt long name definitions. */
+static const struct option long_options[] =
+{
+ {"binprefix", no_argument, 0, 'b'},
+ {"target", required_argument, 0, 'F'},
+ {"extension", required_argument, 0, 'e'},
+ {"headerdir", required_argument, 0, 'h'},
+ {"rcdir", required_argument, 0, 'r'},
+ {"verbose", no_argument, 0, 'v'},
+ {"codepage_in", required_argument, 0, 'C'},
+ {"codepage_out", required_argument, 0, 'O'},
+ {"maxlength", required_argument, 0, 'm'},
+ {"ascii_in", no_argument, 0, 'a'},
+ {"ascii_out", no_argument, 0, 'A'},
+ {"unicode_in", no_argument, 0, 'u'},
+ {"unicode_out", no_argument, 0, 'U'},
+ {"customflag", no_argument, 0, 'c'},
+ {"decimal_values", no_argument, 0, 'd'},
+ {"hresult_use", no_argument, 0, 'o'},
+ {"nullterminate", no_argument, 0, 'n'},
+ {"xdbg", required_argument, 0, 'x'},
+ {"version", no_argument, 0, 'V'},
+ {"help", no_argument, 0, 'H'},
+ {0, no_argument, 0, 0}
+};
+
+
+/* Initialize the resource building obstack. */
+static void
+res_init (void)
+{
+ obstack_init (&res_obstack);
+}
+
+/* Allocate space on the resource building obstack. */
+void *
+res_alloc (rc_uint_type bytes)
+{
+ return (void *) obstack_alloc (&res_obstack, (size_t) bytes);
+}
+
+static FILE *
+mc_create_path_text_file (const char *path, const char *ext)
+{
+ FILE *ret;
+ size_t len = 1;
+ char *hsz;
+
+ len += (path != NULL ? strlen (path) : 0);
+ len += strlen (mcset_mc_basename);
+ len += (ext != NULL ? strlen (ext) : 0);
+ hsz = xmalloc (len);
+ sprintf (hsz, "%s%s%s", (path != NULL ? path : ""), mcset_mc_basename,
+ (ext != NULL ? ext : ""));
+ if ((ret = fopen (hsz, "wb")) == NULL)
+ fatal (_("can't create %s file ,%s' for output.\n"), (ext ? ext : "text"), hsz);
+ free (hsz);
+ return ret;
+}
+
+static void
+usage (FILE *stream, int status)
+{
+ fprintf (stream, _("Usage: %s [option(s)] [input-file]\n"),
+ program_name);
+ fprintf (stream, _(" The options are:\n\
+ -a --ascii_in Read input file as ASCII file\n\
+ -A --ascii_out Write binary messages as ASCII\n\
+ -b --binprefix .bin filename is prefixed by .mc filename_ for uniqueness.\n\
+ -c --customflag Set custom flags for messages\n\
+ -C --codepage_in=<val> Set codepage when reading mc text file\n\
+ -d --decimal_values Print values to text files decimal\n\
+ -e --extension=<extension> Set header extension used on export header file\n\
+ -F --target <target> Specify output target for endianess.\n\
+ -h --headerdir=<directory> Set the export directory for headers\n\
+ -u --unicode_in Read input file as UTF16 file\n\
+ -U --unicode_out Write binary messages as UFT16\n\
+ -m --maxlength=<val> Set the maximal allowed message length\n\
+ -n --nullterminate Automatic add a zero termination to strings\n\
+ -o --hresult_use Use HRESULT definition instead of status code definition\n\
+ -O --codepage_out=<val> Set codepage used for writing text file\n\
+ -r --rcdir=<directory> Set the export directory for rc files\n\
+ -x --xdbg=<directory> Where to create the .dbg C include file\n\
+ that maps message ID's to their symbolic name.\n\
+"));
+ fprintf (stream, _("\
+ -H --help Print this help message\n\
+ -v --verbose Verbose - tells you what it's doing\n\
+ -V --version Print version information\n"));
+
+ list_supported_targets (program_name, stream);
+
+ if (REPORT_BUGS_TO[0] && status == 0)
+ fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
+
+ exit (status);
+}
+
+static void
+set_endianess (bfd *abfd, const char *target)
+{
+ const bfd_target *target_vec;
+
+ def_target_arch = NULL;
+ target_vec = bfd_find_target (target, abfd);
+ if (! target_vec)
+ fatal ("Can't detect target endianess and architecture.");
+ target_is_bigendian = ((target_vec->byteorder == BFD_ENDIAN_BIG) ? 1 : 0);
+ {
+ const char *tname = target_vec->name;
+ const char **arch = bfd_arch_list ();
+
+ if (arch && tname)
+ {
+ if (strchr (tname, '-') != NULL)
+ tname = strchr (tname, '-') + 1;
+ while (*arch != NULL)
+ {
+ const char *in_a = strstr (*arch, tname);
+ char end_ch = (in_a ? in_a[strlen (tname)] : 0);
+ if (in_a && (in_a == *arch || in_a[-1] == ':')
+ && end_ch == 0)
+ {
+ def_target_arch = *arch;
+ break;
+ }
+ arch++;
+ }
+ }
+ if (! def_target_arch)
+ fatal ("Can't detect architecture.");
+ }
+}
+
+static int
+probe_codepage (rc_uint_type *cp, int *is_uni, const char *pswitch, int defmode)
+{
+ if (*is_uni == -1)
+ {
+ if (*cp != CP_UTF16)
+ *is_uni = defmode;
+ else
+ *is_uni = 1;
+ }
+ if (*is_uni)
+ {
+ if (*cp != 0 && *cp != CP_UTF16)
+ {
+ fprintf (stderr, _("%s: warning: "), program_name);
+ fprintf (stderr, _("A codepage was specified switch ,%s' and UTF16.\n"), pswitch);
+ fprintf (stderr, _("\tcodepage settings are ignored.\n"));
+ }
+ *cp = CP_UTF16;
+ return 1;
+ }
+ if (*cp == CP_UTF16)
+ {
+ *is_uni = 1;
+ return 1;
+ }
+ if (*cp == 0)
+ *cp = 1252;
+ if (! unicode_is_valid_codepage (*cp))
+ fatal ("Code page 0x%x is unknown.", (unsigned int) *cp);
+ *is_uni = 0;
+ return 1;
+}
+
+mc_node *
+mc_add_node (void)
+{
+ mc_node *ret;
+
+ ret = res_alloc (sizeof (mc_node));
+ memset (ret, 0, sizeof (mc_node));
+ if (! mc_nodes)
+ mc_nodes = ret;
+ else
+ {
+ mc_node *h = mc_nodes;
+
+ while (h->next != NULL)
+ h = h->next;
+ h->next = ret;
+ }
+ return ret;
+}
+
+mc_node_lang *
+mc_add_node_lang (mc_node *root, const mc_keyword *lang, rc_uint_type vid)
+{
+ mc_node_lang *ret, *h, *p;
+
+ if (! lang || ! root)
+ fatal (_("try to add a ill language."));
+ ret = res_alloc (sizeof (mc_node_lang));
+ memset (ret, 0, sizeof (mc_node_lang));
+ ret->lang = lang;
+ ret->vid = vid;
+ if ((h = root->sub) == NULL)
+ root->sub = ret;
+ else
+ {
+ p = NULL;
+ while (h != NULL)
+ {
+ if (h->lang->nval > lang->nval)
+ break;
+ if (h->lang->nval == lang->nval)
+ {
+ if (h->vid > vid)
+ break;
+ if (h->vid == vid)
+ fatal ("double defined message id %ld.\n", (long) vid);
+ }
+ h = (p = h)->next;
+ }
+ ret->next = h;
+ if (! p)
+ root->sub = ret;
+ else
+ p->next = ret;
+ }
+ return ret;
+}
+
+static char *
+convert_unicode_to_ACP (const unichar *usz)
+{
+ char *s;
+ rc_uint_type l;
+
+ if (! usz)
+ return NULL;
+ codepage_from_unicode (&l, usz, &s, mcset_codepage_out);
+ if (! s)
+ fatal ("unicode string not mappable to ASCII codepage 0x%lx.\n", (long) mcset_codepage_out);
+ return s;
+}
+
+static void
+write_dbg_define (FILE *fp, const unichar *sym_name, const unichar *typecast)
+{
+ char *sym;
+
+ if (!sym_name || sym_name[0] == 0)
+ return;
+ sym = convert_unicode_to_ACP (sym_name);
+ fprintf (fp, " {(");
+ if (typecast)
+ unicode_print (fp, typecast, unichar_len (typecast));
+ else
+ fprintf (fp, "DWORD");
+ fprintf (fp, ") %s, \"%s\" },\n", sym, sym);
+}
+
+static void
+write_header_define (FILE *fp, const unichar *sym_name, rc_uint_type vid, const unichar *typecast, mc_node_lang *nl)
+{
+ char *sym;
+ char *tdef = NULL;
+
+ if (!sym_name || sym_name[0] == 0)
+ {
+ if (nl != NULL)
+ {
+ if (mcset_out_values_are_decimal)
+ fprintf (fp, "//\n// MessageId: 0x%lu\n//\n", (unsigned long) vid);
+ else
+ fprintf (fp, "//\n// MessageId: 0x%lx\n//\n", (unsigned long) vid);
+ }
+ return;
+ }
+ sym = convert_unicode_to_ACP (sym_name);
+ if (typecast && typecast[0] != 0)
+ tdef = convert_unicode_to_ACP (typecast);
+ fprintf (fp, "//\n// MessageId: %s\n//\n", sym);
+ if (! mcset_out_values_are_decimal)
+ fprintf (fp, "#define %s %s%s%s 0x%lx\n\n", sym,
+ (tdef ? "(" : ""), (tdef ? tdef : ""), (tdef ? ")" : ""),
+ (unsigned long) vid);
+ else
+ fprintf (fp, "#define %s %s%s%s 0x%lu\n\n", sym,
+ (tdef ? "(" : ""), (tdef ? tdef : ""), (tdef ? ")" : ""),
+ (unsigned long) vid);
+}
+
+static int
+sort_mc_node_lang (const void *l, const void *r)
+{
+ const mc_node_lang *l1 = *((const mc_node_lang **)l);
+ const mc_node_lang *r1 = *((const mc_node_lang **)r);
+
+ if (l == r)
+ return 0;
+ if (l1->lang != r1->lang)
+ {
+ if (l1->lang->nval < r1->lang->nval)
+ return -1;
+ return 1;
+ }
+ if (l1->vid == r1->vid)
+ return 0;
+ if (l1->vid < r1->vid)
+ return -1;
+ return 1;
+}
+
+static int
+sort_keyword_by_nval (const void *l, const void *r)
+{
+ const mc_keyword *l1 = *((const mc_keyword **)l);
+ const mc_keyword *r1 = *((const mc_keyword **)r);
+ rc_uint_type len1, len2;
+ int e;
+
+ if (l == r)
+ return 0;
+ if (l1->nval != r1->nval)
+ {
+ if (l1->nval < r1->nval)
+ return -1;
+ return 1;
+ }
+ len1 = unichar_len (l1->usz);
+ len2 = unichar_len (r1->usz);
+ if (len1 <= len2)
+ e = memcmp (l1->usz, r1->usz, sizeof (unichar) * len1);
+ else
+ e = memcmp (l1->usz, r1->usz, sizeof (unichar) * len2);
+ if (e)
+ return e;
+ if (len1 < len2)
+ return -1;
+ else if (len1 > len2)
+ return 1;
+ return 0;
+}
+
+static void
+do_sorts (void)
+{
+ mc_node *h;
+ mc_node_lang *n;
+ const mc_keyword *k;
+ int i;
+
+ /* Sort message by their language and id ascending. */
+ mc_nodes_lang_count = 0;
+
+ h = mc_nodes;
+ while (h != NULL)
+ {
+ n = h->sub;
+ while (n != NULL)
+ {
+ mc_nodes_lang_count +=1;
+ n = n->next;
+ }
+ h = h->next;
+ }
+
+ if (mc_nodes_lang_count != 0)
+ {
+ h = mc_nodes;
+ i = 0;
+ mc_nodes_lang = xmalloc (sizeof (mc_node_lang *) * mc_nodes_lang_count);
+
+ while (h != NULL)
+ {
+ n = h->sub;
+ while (n != NULL)
+ {
+ mc_nodes_lang[i++] = n;
+ n = n->next;
+ }
+ h = h->next;
+ }
+ qsort (mc_nodes_lang, (size_t) mc_nodes_lang_count, sizeof (mc_node_lang *), sort_mc_node_lang);
+ }
+ /* Sort facility code definitions by there id ascending. */
+ i = 0;
+ while ((k = enum_facility (i)) != NULL)
+ ++i;
+ mc_facility_codes_count = i;
+ if (i != 0)
+ {
+ mc_facility_codes = xmalloc (sizeof (mc_keyword *) * i);
+ i = 0;
+ while ((k = enum_facility (i)) != NULL)
+ mc_facility_codes[i++] = (mc_keyword *) k;
+ qsort (mc_facility_codes, (size_t) mc_facility_codes_count, sizeof (mc_keyword *), sort_keyword_by_nval);
+ }
+
+ /* Sort severity code definitions by there id ascending. */
+ i = 0;
+ while ((k = enum_severity (i)) != NULL)
+ ++i;
+ mc_severity_codes_count = i;
+ if (i != 0)
+ {
+ mc_severity_codes = xmalloc (sizeof (mc_keyword *) * i);
+ i = 0;
+ while ((k = enum_severity (i)) != NULL)
+ mc_severity_codes[i++] = (mc_keyword *) k;
+ qsort (mc_severity_codes, (size_t) mc_severity_codes_count, sizeof (mc_keyword *), sort_keyword_by_nval);
+ }
+}
+
+static int
+mc_get_block_count (mc_node_lang **nl, int elems)
+{
+ rc_uint_type exid;
+ int i, ret;
+
+ if (! nl)
+ return 0;
+ i = 0;
+ ret = 0;
+ while (i < elems)
+ {
+ ret++;
+ exid = nl[i++]->vid;
+ while (i < elems && nl[i]->vid == exid + 1)
+ exid = nl[i++]->vid;
+ }
+ return ret;
+}
+
+static bfd *
+windmc_open_as_binary (const char *filename)
+{
+ bfd *abfd;
+
+ abfd = bfd_openw (filename, "binary");
+ if (! abfd)
+ fatal ("can't open `%s' for output", filename);
+
+ return abfd;
+}
+
+static void
+target_put_16 (void *p, rc_uint_type value)
+{
+ assert (!! p);
+
+ if (target_is_bigendian)
+ bfd_putb16 (value, p);
+ else
+ bfd_putl16 (value, p);
+}
+
+static void
+target_put_32 (void *p, rc_uint_type value)
+{
+ assert (!! p);
+
+ if (target_is_bigendian)
+ bfd_putb32 (value, p);
+ else
+ bfd_putl32 (value, p);
+}
+
+static struct bin_messagetable_item *
+mc_generate_bin_item (mc_node_lang *n, rc_uint_type *res_len)
+{
+ struct bin_messagetable_item *ret = NULL;
+ rc_uint_type len;
+
+ *res_len = 0;
+ if (mcset_bin_out_is_unicode == 1)
+ {
+ unichar *ht = n->message;
+ rc_uint_type txt_len;
+
+ txt_len = unichar_len (n->message);
+ if (mcset_automatic_null_termination && txt_len != 0)
+ {
+ while (txt_len > 0 && ht[txt_len - 1] > 0 && ht[txt_len - 1] < 0x20)
+ ht[--txt_len] = 0;
+ }
+ txt_len *= sizeof (unichar);
+ len = BIN_MESSAGETABLE_ITEM_SIZE + txt_len + sizeof (unichar);
+ ret = res_alloc ((len + 3) & ~3);
+ memset (ret, 0, (len + 3) & ~3);
+ target_put_16 (ret->length, (len + 3) & ~3);
+ target_put_16 (ret->flags, MESSAGE_RESOURCE_UNICODE);
+ txt_len = 0;
+ while (*ht != 0)
+ {
+ target_put_16 (ret->data + txt_len, *ht++);
+ txt_len += 2;
+ }
+ }
+ else
+ {
+ rc_uint_type txt_len, l;
+ char *cvt_txt;
+
+ codepage_from_unicode( &l, n->message, &cvt_txt, n->lang->lang_info.wincp);
+ if (! cvt_txt)
+ fatal ("Failed to convert message to language codepage.\n");
+ txt_len = strlen (cvt_txt);
+ if (mcset_automatic_null_termination && txt_len > 0)
+ {
+ while (txt_len > 0 && cvt_txt[txt_len - 1] > 0 && cvt_txt[txt_len - 1] < 0x20)
+ cvt_txt[--txt_len] = 0;
+ }
+ len = BIN_MESSAGETABLE_ITEM_SIZE + txt_len + 1;
+ ret = res_alloc ((len + 3) & ~3);
+ memset (ret, 0, (len + 3) & ~3);
+ target_put_16 (ret->length, (len + 3) & ~3);
+ target_put_16 (ret->flags, 0);
+ strcpy ((char *) ret->data, cvt_txt);
+ }
+ *res_len = (len + 3) & ~3;
+ return ret;
+}
+
+static void
+mc_write_blocks (struct bin_messagetable *mtbl, mc_node_lang **nl, mc_msg_item *ml, int elems)
+{
+ int i, idx = 0;
+ rc_uint_type exid;
+
+ if (! nl)
+ return;
+ i = 0;
+ while (i < elems)
+ {
+ target_put_32 (mtbl->items[idx].lowid, nl[i]->vid);
+ target_put_32 (mtbl->items[idx].highid, nl[i]->vid);
+ target_put_32 (mtbl->items[idx].offset, ml[i].res_off);
+ exid = nl[i++]->vid;
+ while (i < elems && nl[i]->vid == exid + 1)
+ {
+ target_put_32 (mtbl->items[idx].highid, nl[i]->vid);
+ exid = nl[i++]->vid;
+ }
+ ++idx;
+ }
+}
+
+static void
+set_windmc_bfd_content (const void *data, rc_uint_type off, rc_uint_type length)
+{
+ if (! bfd_set_section_contents (mc_bfd.abfd, mc_bfd.sec, data, off, length))
+ bfd_fatal ("bfd_set_section_contents");
+}
+
+static void
+windmc_write_bin (const char *filename, mc_node_lang **nl, int elems)
+{
+ unsigned long sec_length = 1;
+ int block_count, i;
+ mc_msg_item *mi;
+ struct bin_messagetable *mtbl;
+ rc_uint_type dta_off, dta_start;
+
+ if (elems <= 0)
+ return;
+ mc_bfd.abfd = windmc_open_as_binary (filename);
+ mc_bfd.sec = bfd_make_section (mc_bfd.abfd, ".data");
+ if (mc_bfd.sec == NULL)
+ bfd_fatal ("bfd_make_section");
+ if (! bfd_set_section_flags (mc_bfd.abfd, mc_bfd.sec,
+ (SEC_HAS_CONTENTS | SEC_ALLOC
+ | SEC_LOAD | SEC_DATA)))
+ bfd_fatal ("bfd_set_section_flags");
+ /* Requiring this is probably a bug in BFD. */
+ mc_bfd.sec->output_section = mc_bfd.sec;
+
+ block_count = mc_get_block_count (nl, elems);
+
+ dta_off = (rc_uint_type) ((BIN_MESSAGETABLE_BLOCK_SIZE * block_count) + BIN_MESSAGETABLE_SIZE - 4);
+ dta_start = dta_off = (dta_off + 3) & ~3;
+ mi = xmalloc (sizeof (mc_msg_item) * elems);
+ mtbl = xmalloc (dta_start);
+
+ /* Clear header region. */
+ memset (mtbl, 0, dta_start);
+ target_put_32 (mtbl->cblocks, block_count);
+ /* Prepare items section for output. */
+ for (i = 0; i < elems; i++)
+ {
+ mi[i].res_off = dta_off;
+ mi[i].res = mc_generate_bin_item (nl[i], &mi[i].res_len);
+ dta_off += mi[i].res_len;
+ }
+ sec_length = (dta_off + 3) & ~3;
+ if (! bfd_set_section_size (mc_bfd.abfd, mc_bfd.sec, sec_length))
+ bfd_fatal ("bfd_set_section_size");
+ /* Make sure we write the complete block. */
+ set_windmc_bfd_content ("\0", sec_length - 1, 1);
+
+ /* Write block information. */
+ mc_write_blocks (mtbl, nl, mi, elems);
+
+ set_windmc_bfd_content (mtbl, 0, dta_start);
+
+ /* Write items. */
+ for (i = 0; i < elems; i++)
+ set_windmc_bfd_content (mi[i].res, mi[i].res_off, mi[i].res_len);
+
+ free (mtbl);
+ free (mi);
+ bfd_close (mc_bfd.abfd);
+ mc_bfd.abfd = NULL;
+ mc_bfd.sec = NULL;
+}
+
+static void
+write_bin (void)
+{
+ mc_node_lang *n = NULL;
+ int i, c;
+
+ if (! mc_nodes_lang_count)
+ return;
+
+ i = 0;
+ while (i < mc_nodes_lang_count)
+ {
+ char *nd;
+ char *filename;
+
+ if (n && n->lang == mc_nodes_lang[i]->lang)
+ {
+ i++;
+ continue;
+ }
+ n = mc_nodes_lang[i];
+ c = i + 1;
+ while (c < mc_nodes_lang_count && n->lang == mc_nodes_lang[c]->lang)
+ c++;
+ nd = convert_unicode_to_ACP (n->lang->sval);
+
+ /* Prepare filename for binary output. */
+ filename = xmalloc (strlen (nd) + 4 + 1 + strlen (mcset_mc_basename) + 1 + strlen (mcset_rc_dir));
+ strcpy (filename, mcset_rc_dir);
+ if (mcset_prefix_bin)
+ sprintf (filename + strlen (filename), "%s_", mcset_mc_basename);
+ strcat (filename, nd);
+ strcat (filename, ".bin");
+
+ /* Write message file. */
+ windmc_write_bin (filename, &mc_nodes_lang[i], (c - i));
+
+ free (filename);
+ i = c;
+ }
+}
+
+static void
+write_rc (FILE *fp)
+{
+ mc_node_lang *n;
+ int i, l;
+
+ fprintf (fp,
+ "/* Do not edit this file manually.\n"
+ " This file is autogenerated by windmc. */\n\n");
+ if (! mc_nodes_lang_count)
+ return;
+ n = NULL;
+ i = 0;
+ for (l = 0; l < mc_nodes_lang_count; l++)
+ {
+ if (n && n->lang == mc_nodes_lang[l]->lang)
+ continue;
+ ++i;
+ n = mc_nodes_lang[l];
+ fprintf (fp, "\n// Country: %s\n// Language: %s\n#pragma code_page(%u)\n",
+ n->lang->lang_info.country, n->lang->lang_info.name,
+ (unsigned) n->lang->lang_info.wincp);
+ fprintf (fp, "LANGUAGE 0x%lx, 0x%lx\n", (long) (n->lang->nval & 0x3ff),
+ (long) ((n->lang->nval & 0xffff) >> 10));
+ fprintf (fp, "1 MESSAGETABLE \"");
+ if (mcset_prefix_bin)
+ fprintf (fp, "%s_", mcset_mc_basename);
+ unicode_print (fp, n->lang->sval, unichar_len (n->lang->sval));
+ fprintf (fp, ".bin\"\n");
+ }
+}
+
+static void
+write_dbg (FILE *fp)
+{
+ mc_node *h;
+
+ fprintf (fp,
+ "/* Do not edit this file manually.\n"
+ " This file is autogenerated by windmc.\n\n"
+ " This file maps each message ID value in to a text string that contains\n"
+ " the symbolic name used for it. */\n\n");
+
+ fprintf (fp,
+ "struct %sSymbolicName\n"
+ "{\n ", mcset_mc_basename);
+ if (mcset_msg_id_typedef)
+ unicode_print (fp, mcset_msg_id_typedef, unichar_len (mcset_msg_id_typedef));
+ else
+ fprintf (fp, "DWORD");
+ fprintf (fp,
+ " MessageId;\n"
+ " char *SymbolicName;\n"
+ "} %sSymbolicNames[] =\n"
+ "{\n", mcset_mc_basename);
+ h = mc_nodes;
+ while (h != NULL)
+ {
+ if (h->symbol)
+ write_dbg_define (fp, h->symbol, mcset_msg_id_typedef);
+ h = h->next;
+ }
+ fprintf (fp, " { (");
+ if (mcset_msg_id_typedef)
+ unicode_print (fp, mcset_msg_id_typedef, unichar_len (mcset_msg_id_typedef));
+ else
+ fprintf (fp, "DWORD");
+ fprintf (fp,
+ ") 0xffffffff, NULL }\n"
+ "};\n");
+}
+
+static void
+write_header (FILE *fp)
+{
+ char *s;
+ int i;
+ const mc_keyword *key;
+ mc_node *h;
+
+ fprintf (fp,
+ "/* Do not edit this file manually.\n"
+ " This file is autogenerated by windmc. */\n\n"
+ "//\n// The values are 32 bit layed out as follows:\n//\n"
+ "// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1\n"
+ "// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0\n"
+ "// +---+-+-+-----------------------+-------------------------------+\n"
+ "// |Sev|C|R| Facility | Code |\n"
+ "// +---+-+-+-----------------------+-------------------------------+\n//\n"
+ "// where\n//\n"
+ "// C - is the Customer code flag\n//\n"
+ "// R - is a reserved bit\n//\n"
+ "// Code - is the facility's status code\n//\n");
+
+ h = mc_nodes;
+
+ fprintf (fp, "// Sev - is the severity code\n//\n");
+ if (mc_severity_codes_count != 0)
+ {
+ for (i = 0; i < mc_severity_codes_count; i++)
+ {
+ key = mc_severity_codes[i];
+ fprintf (fp, "// %s - %02lx\n", convert_unicode_to_ACP (key->usz),
+ (unsigned long) key->nval);
+ if (key->sval && key->sval[0] != 0)
+ {
+ if (! mcset_out_values_are_decimal)
+ fprintf (fp, "#define %s 0x%lx\n", convert_unicode_to_ACP (key->sval),
+ (unsigned long) key->nval);
+ else
+ fprintf (fp, "#define %s 0x%lu\n", convert_unicode_to_ACP (key->sval),
+ (unsigned long) key->nval);
+ }
+ }
+ fprintf (fp, "//\n");
+ }
+ fprintf (fp, "// Facility - is the facility code\n//\n");
+ if (mc_facility_codes_count != 0)
+ {
+ for (i = 0; i < mc_facility_codes_count; i++)
+ {
+ key = mc_facility_codes[i];
+ fprintf (fp, "// %s - %04lx\n", convert_unicode_to_ACP (key->usz),
+ (unsigned long) key->nval);
+ if (key->sval && key->sval[0] != 0)
+ {
+ if (! mcset_out_values_are_decimal)
+ fprintf (fp, "#define %s 0x%lx\n", convert_unicode_to_ACP (key->sval),
+ (unsigned long) key->nval);
+ else
+ fprintf (fp, "#define %s 0x%lu\n", convert_unicode_to_ACP (key->sval),
+ (unsigned long) key->nval);
+ }
+ }
+ fprintf (fp, "//\n");
+ }
+ fprintf (fp, "\n");
+ while (h != NULL)
+ {
+ if (h->user_text)
+ {
+ s = convert_unicode_to_ACP (h->user_text);
+ if (s)
+ fprintf (fp, "%s", s);
+ }
+ if (h->symbol)
+ write_header_define (fp, h->symbol, h->vid, mcset_msg_id_typedef, h->sub);
+ h = h->next;
+ }
+}
+
+static const char *
+mc_unify_path (const char *path)
+{
+ char *end;
+ char *hsz;
+
+ if (! path || *path == 0)
+ return "./";
+ hsz = xmalloc (strlen (path) + 2);
+ strcpy (hsz, path);
+ end = hsz + strlen (hsz);
+ if (hsz[-1] != '/' && hsz[-1] != '\\')
+ strcpy (end, "/");
+ while ((end = strchr (hsz, '\\')) != NULL)
+ *end = '/';
+ return hsz;
+}
+
+int main (int, char **);
+
+int
+main (int argc, char **argv)
+{
+ FILE *h_fp;
+ int c;
+ char *target, *input_filename;
+ int verbose;
+
+#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
+ setlocale (LC_MESSAGES, "");
+#endif
+#if defined (HAVE_SETLOCALE)
+ setlocale (LC_CTYPE, "");
+#endif
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ program_name = argv[0];
+ xmalloc_set_program_name (program_name);
+
+ expandargv (&argc, &argv);
+
+ bfd_init ();
+ set_default_bfd_target ();
+
+ target = NULL;
+ verbose = 0;
+ input_filename = NULL;
+
+ res_init ();
+
+ while ((c = getopt_long (argc, argv, "C:F:O:h:e:m:r:x:aAbcdHunoUvV", long_options,
+ (int *) 0)) != EOF)
+ {
+ switch (c)
+ {
+ case 'b':
+ mcset_prefix_bin = 1;
+ break;
+ case 'e':
+ {
+ mcset_header_ext = optarg;
+ if (mcset_header_ext[0] != '.' && mcset_header_ext[0] != 0)
+ {
+ char *hsz = xmalloc (strlen (mcset_header_ext) + 2);
+
+ sprintf (hsz, ".%s", mcset_header_ext);
+ mcset_header_ext = hsz;
+ }
+ }
+ break;
+ case 'h':
+ mcset_header_dir = mc_unify_path (optarg);
+ break;
+ case 'r':
+ mcset_rc_dir = mc_unify_path (optarg);
+ break;
+ case 'a':
+ mcset_text_in_is_unicode = 0;
+ break;
+ case 'x':
+ if (*optarg != 0)
+ mcset_dbg_dir = mc_unify_path (optarg);
+ break;
+ case 'A':
+ mcset_bin_out_is_unicode = 0;
+ break;
+ case 'd':
+ mcset_out_values_are_decimal = 1;
+ break;
+ case 'u':
+ mcset_text_in_is_unicode = 1;
+ break;
+ case 'U':
+ mcset_bin_out_is_unicode = 1;
+ break;
+ case 'c':
+ mcset_custom_bit = 1;
+ break;
+ case 'n':
+ mcset_automatic_null_termination = 1;
+ break;
+ case 'o':
+ mcset_use_hresult = 1;
+ fatal ("option -o is not implemented until yet.\n");
+ break;
+ case 'F':
+ target = optarg;
+ break;
+ case 'v':
+ verbose ++;
+ break;
+ case 'm':
+ mcset_max_message_length = strtol (optarg, (char **) NULL, 10);
+ break;
+ case 'C':
+ mcset_codepage_in = strtol (optarg, (char **) NULL, 10);
+ break;
+ case 'O':
+ mcset_codepage_out = strtol (optarg, (char **) NULL, 10);
+ break;
+ case '?':
+ case 'H':
+ usage (stdout, 0);
+ break;
+ case 'V':
+ print_version ("windmc");
+ break;
+
+ default:
+ usage (stderr, 1);
+ break;
+ }
+ }
+ if (input_filename == NULL && optind < argc)
+ {
+ input_filename = argv[optind];
+ ++optind;
+ }
+
+ set_endianess (NULL, target);
+
+ if (input_filename == NULL)
+ {
+ fprintf (stderr, "Error: No input file was specified.\n");
+ usage (stderr, 1);
+ }
+ mc_set_inputfile (input_filename);
+
+ if (!probe_codepage (&mcset_codepage_in, &mcset_text_in_is_unicode, "codepage_in", 0))
+ usage (stderr, 1);
+ if (mcset_codepage_out == 0)
+ mcset_codepage_out = 1252;
+ if (! unicode_is_valid_codepage (mcset_codepage_out))
+ fatal ("Code page 0x%x is unknown.", (unsigned int) mcset_codepage_out);
+ if (mcset_codepage_out == CP_UTF16)
+ fatal ("UTF16 is no valid text output code page.");
+ if (verbose)
+ {
+ fprintf (stderr, "// Default target is %s and it is %s endian.\n",
+ def_target_arch, (target_is_bigendian ? "big" : "little"));
+ fprintf (stderr, "// Input codepage: 0x%x\n", (unsigned int) mcset_codepage_in);
+ fprintf (stderr, "// Output codepage: 0x%x\n", (unsigned int) mcset_codepage_out);
+ }
+
+ if (argc != optind)
+ usage (stderr, 1);
+
+ /* Initialize mcset_mc_basename. */
+ {
+ const char *bn, *bn2;
+ char *hsz;
+
+ bn = strrchr (input_filename, '/');
+ bn2 = strrchr (input_filename, '\\');
+ if (! bn)
+ bn = bn2;
+ if (bn && bn2 && bn < bn2)
+ bn = bn2;
+ if (! bn)
+ bn = input_filename;
+ else
+ bn++;
+ mcset_mc_basename = hsz = xstrdup (bn);
+
+ /* Cut of right-hand extension. */
+ if ((hsz = strrchr (hsz, '.')) != NULL)
+ *hsz = 0;
+ }
+
+ /* Load the input file and do code page transformations to UTF16. */
+ {
+ unichar *u;
+ rc_uint_type ul;
+ char *buff;
+ long flen;
+ FILE *fp = fopen (input_filename, "rb");
+
+ if (!fp)
+ fatal (_("unable to open file ,%s' for input.\n"), input_filename);
+
+ fseek (fp, 0, SEEK_END);
+ flen = ftell (fp);
+ fseek (fp, 0, SEEK_SET);
+ buff = malloc (flen + 3);
+ memset (buff, 0, flen + 3);
+ fread (buff, 1, flen, fp);
+ fclose (fp);
+ if (mcset_text_in_is_unicode != 1)
+ {
+ unicode_from_codepage (&ul, &u, buff, mcset_codepage_in);
+ if (! u)
+ fatal ("Failed to convert input to UFT16\n");
+ mc_set_content (u);
+ }
+ else
+ {
+ if ((flen & 1) != 0)
+ fatal (_("input file does not seems to be UFT16.\n"));
+ mc_set_content ((unichar *) buff);
+ }
+ free (buff);
+ }
+
+ while (yyparse ())
+ ;
+
+ do_sorts ();
+
+ h_fp = mc_create_path_text_file (mcset_header_dir, mcset_header_ext);
+ write_header (h_fp);
+ fclose (h_fp);
+
+ h_fp = mc_create_path_text_file (mcset_rc_dir, ".rc");
+ write_rc (h_fp);
+ fclose (h_fp);
+
+ if (mcset_dbg_dir != NULL)
+ {
+ h_fp = mc_create_path_text_file (mcset_dbg_dir, ".dbg");
+ write_dbg (h_fp);
+ fclose (h_fp);
+ }
+ write_bin ();
+
+ if (mc_nodes_lang)
+ free (mc_nodes_lang);
+ if (mc_severity_codes)
+ free (mc_severity_codes);
+ if (mc_facility_codes)
+ free (mc_facility_codes);
+
+ xexit (0);
+ return 0;
+}
diff --git a/binutils/windmc.h b/binutils/windmc.h
new file mode 100644
index 0000000000..08a7706260
--- /dev/null
+++ b/binutils/windmc.h
@@ -0,0 +1,99 @@
+/* windmc.h -- header file for windmc program.
+ Copyright 2007
+ Free Software Foundation, Inc.
+ Written by Kai Tietz, Onevision.
+
+ This file is part of GNU Binutils.
+
+ 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., 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include "ansidecl.h"
+
+/* This is the header file for the windmc program. It defines
+ structures and declares functions used within the program. */
+
+#include "winduni.h"
+
+#ifndef WINDMC_HXX
+#define WINDMC_HXX
+
+/* Global flag variables (set by windmc.c file. */
+extern int mcset_custom_bit;
+extern int mcset_out_values_are_decimal;
+extern rc_uint_type mcset_max_message_length;
+extern unichar *mcset_msg_id_typedef;
+
+/* Lexer keyword definition and internal memory structures. */
+
+typedef struct mc_keyword
+{
+ struct mc_keyword *next;
+ const char *group_name;
+ size_t len;
+ unichar *usz;
+ int rid;
+ rc_uint_type nval;
+ unichar *sval;
+ wind_language_t lang_info;
+} mc_keyword;
+
+typedef struct mc_node_lang
+{
+ struct mc_node_lang *next;
+ rc_uint_type vid;
+ const mc_keyword *lang;
+ unichar *message;
+} mc_node_lang;
+
+typedef struct mc_node
+{
+ struct mc_node *next;
+ unichar *user_text;
+ const mc_keyword *facility;
+ const mc_keyword *severity;
+ unichar *symbol;
+ rc_uint_type id;
+ rc_uint_type vid;
+ mc_node_lang *sub;
+} mc_node;
+
+extern mc_node *mc_nodes;
+
+void mc_add_keyword (unichar *, int, const char *, rc_uint_type, unichar *);
+const mc_keyword *enum_facility (int);
+const mc_keyword *enum_severity (int);
+
+mc_node_lang *mc_add_node_lang (mc_node *, const mc_keyword *, rc_uint_type);
+mc_node *mc_add_node (void);
+
+/* Standard yacc/flex stuff. */
+int yyerror (const char *, ...);
+int yylex (void);
+int yyparse (void);
+
+/* mclex.c */
+void mc_set_inputfile (const char *);
+void mc_set_content (const unichar *);
+
+/* Lexer control variables. Used by mcparser.y file. */
+extern bfd_boolean mclex_want_nl;
+extern bfd_boolean mclex_want_line;
+extern bfd_boolean mclex_want_filename;
+
+void mc_fatal (const char *, ...);
+void mc_warn (const char *, ...);
+
+#endif