* Makefile.am: Add windmc tool.
authorNick Clifton <nickc@redhat.com>
Tue, 19 Jun 2007 13:24:33 +0000 (13:24 +0000)
committerNick Clifton <nickc@redhat.com>
Tue, 19 Jun 2007 13:24:33 +0000 (13:24 +0000)
* 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.

13 files changed:
binutils/ChangeLog
binutils/Makefile.am
binutils/Makefile.in
binutils/NEWS
binutils/configure
binutils/configure.in
binutils/doc/Makefile.am
binutils/doc/Makefile.in
binutils/doc/binutils.texi
binutils/mclex.c [new file with mode: 0644]
binutils/mcparse.y [new file with mode: 0644]
binutils/windmc.c [new file with mode: 0644]
binutils/windmc.h [new file with mode: 0644]

index 18568bb..c210ccc 100644 (file)
@@ -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>
 
index 3b36d15..24a34fd 100644 (file)
@@ -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
index f43cfc0..6ce70d5 100644 (file)
@@ -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.
index 3eceac0..ad6058f 100644 (file)
@@ -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
index 288004f..a10a8ad 100755 (executable)
@@ -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
index fe1bb9f..19aaabc 100644 (file)
@@ -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)
index 5d8520c..ceeda41 100644 (file)
@@ -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
index 12928a1..2455745 100644 (file)
@@ -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
index 9591fe9..da49e1f 100644 (file)
@@ -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 (file)
index 0000000..f6cedd9
--- /dev/null
@@ -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 (file)
index 0000000..9aaba9b
--- /dev/null
@@ -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 (file)
index 0000000..5465b35
--- /dev/null
@@ -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 (file)
index 0000000..08a7706
--- /dev/null
@@ -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