aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/cleantree.py84
-rw-r--r--tools/genruntimemanifest.py53
-rw-r--r--tools/mhmake/CMakeLists.txt51
-rw-r--r--tools/mhmake/COPYING674
-rw-r--r--tools/mhmake/MHMake extensions to GNU make.url3
-rw-r--r--tools/mhmake/Makefile.am5
-rw-r--r--tools/mhmake/Makefile.cvs8
-rw-r--r--tools/mhmake/addstdafxh.py33
-rw-r--r--tools/mhmake/bison++.exebin0 -> 110592 bytes
-rw-r--r--tools/mhmake/config.guess1363
-rw-r--r--tools/mhmake/config.sub1470
-rw-r--r--tools/mhmake/configure.in20
-rw-r--r--tools/mhmake/cygwin1.dllbin0 -> 2608311 bytes
-rw-r--r--tools/mhmake/depcomp441
-rw-r--r--tools/mhmake/flex++.exebin0 -> 485280 bytes
-rwxr-xr-xtools/mhmake/genkdev4.sh12
-rw-r--r--tools/mhmake/install-sh276
-rw-r--r--tools/mhmake/ltmain.sh6343
-rw-r--r--tools/mhmake/m4.exebin0 -> 158208 bytes
-rw-r--r--tools/mhmake/makebison.bat4
-rw-r--r--tools/mhmake/makefile25
-rw-r--r--tools/mhmake/makelex.bat11
-rw-r--r--tools/mhmake/mhmake.kdev44
-rw-r--r--tools/mhmake/mhmake.kdevelop247
-rw-r--r--tools/mhmake/mhmake.sln31
-rw-r--r--tools/mhmake/mhmake.vcproj1012
-rw-r--r--tools/mhmake/mhmake.vcxproj478
-rw-r--r--tools/mhmake/mhmake.vcxproj.filters109
-rw-r--r--tools/mhmake/mhmakevc10.sln31
-rw-r--r--tools/mhmake/missing336
-rw-r--r--tools/mhmake/readme.txt26
-rw-r--r--tools/mhmake/src/Makefile.am62
-rw-r--r--tools/mhmake/src/bison.cc1025
-rw-r--r--tools/mhmake/src/bison.h249
-rw-r--r--tools/mhmake/src/build.cpp1819
-rw-r--r--tools/mhmake/src/commandqueue.cpp410
-rw-r--r--tools/mhmake/src/commandqueue.h73
-rw-r--r--tools/mhmake/src/curdir.cpp37
-rw-r--r--tools/mhmake/src/curdir.h47
-rw-r--r--tools/mhmake/src/fileinfo.cpp363
-rw-r--r--tools/mhmake/src/fileinfo.h437
-rw-r--r--tools/mhmake/src/flex.skl3426
-rw-r--r--tools/mhmake/src/flexint.h63
-rw-r--r--tools/mhmake/src/flexlexer.h260
-rw-r--r--tools/mhmake/src/functions.cpp842
-rw-r--r--tools/mhmake/src/md5.cpp455
-rw-r--r--tools/mhmake/src/md5.h58
-rw-r--r--tools/mhmake/src/mhmake.cpp158
-rw-r--r--tools/mhmake/src/mhmakefileparser.cpp1451
-rw-r--r--tools/mhmake/src/mhmakefileparser.h383
-rw-r--r--tools/mhmake/src/mhmakelexer.l987
-rw-r--r--tools/mhmake/src/mhmakeparser.y255
-rw-r--r--tools/mhmake/src/refptr.h124
-rw-r--r--tools/mhmake/src/rule.cpp301
-rw-r--r--tools/mhmake/src/rule.h110
-rw-r--r--tools/mhmake/src/stdafx.cpp24
-rw-r--r--tools/mhmake/src/stdafx.h86
-rw-r--r--tools/mhmake/src/util.cpp780
-rw-r--r--tools/mhmake/src/util.h238
-rw-r--r--tools/mhmake/ylwrap0
60 files changed, 27673 insertions, 0 deletions
diff --git a/tools/cleantree.py b/tools/cleantree.py
new file mode 100644
index 000000000..a02eebcc0
--- /dev/null
+++ b/tools/cleantree.py
@@ -0,0 +1,84 @@
+#!/usr/bin/python
+__doc__="""%prog [options] [<directory>]
+
+Removes all unversioned files from a subversion working copy directory
+<directory>.
+When <directory> is not specified the current directory is used.
+<directory can also be a white space seperated list of directories.
+"""
+import os,sys,re,shutil
+from optparse import OptionParser
+
+parser = OptionParser(__doc__)
+parser.add_option("-r", "--recursive", action='store_true', dest="Recursive", default=False, help="Also clean subdirectories.")
+parser.add_option("-s", "--skiputil", action='store_true', dest="SkipUtil", default=False, help="Skip util and tools directory.")
+parser.add_option("-v", "--noverbose", action='store_true', dest="NoVerbose", default=False, help="No output.")
+
+(g_Options, g_Args) = parser.parse_args()
+
+if g_Args:
+ for i in range(len(g_Args)):
+ g_Args[i]=os.path.abspath(g_Args[i])
+ if not os.path.isdir(g_Args[i]):
+ parser.error("%s is not a valid directory"%g_Args[i])
+
+################################################################################
+
+def Print (Message,NoVerbose=None,Append='\n'):
+ if NoVerbose!=1:
+ Message+=Append
+ sys.stdout.write(Message)
+
+################################################################################
+def RunCommand(Command,NoVerbose=None):
+ #Print(Command)
+ StdIn,StdOut=os.popen4(Command)
+ while 1:
+ line=StdOut.readline()
+ if not line:
+ break
+ Print(line,NoVerbose,'')
+
+################################################################################
+def CleanTree(Dir, NoVerbose=None):
+ Print("Cleaning '"+Dir+"'")
+ if g_Options.Recursive:
+ Command='svn st --no-ignore'
+ else:
+ Command='svn st -N --no-ignore'
+ StdIn,StdOut=os.popen4(Command)
+ NotWorkRe=re.compile("'\.' is not a working copy")
+ while 1:
+ line=StdOut.readline()
+ if not line:
+ break
+ if NotWorkRe.search(line):
+ Print(NotWorkRe.sub("'%s' is not a working copy directory. Not cleaning this directory."%(re.sub(r"\\",r"\\\\",Dir)),line))
+ sys.exit(1)
+ if line[0]=='?' or line[0]=='I':
+ Item=re.sub("^\s+","",line[2:-1])
+ if g_Options.SkipUtil:
+ if Item[:5]=='util'+os.sep:
+ continue
+ if Item[:6]=='tools'+os.sep:
+ continue
+ if os.path.isdir(Item):
+ Print('Deleting directory %s'%(os.path.abspath(Item)),NoVerbose)
+ try:
+ shutil.rmtree(Item)
+ except:
+ print "Error deleting directory %s. Contains read-only files?"%Item
+ else:
+ Print('Deleting file %s'%(os.path.abspath(Item)),NoVerbose)
+ try:
+ os.remove(Item)
+ except:
+ print "Error deleting file %s. Is read-only?"%Item
+
+################################################################################
+if not g_Args:
+ g_Args=["."]
+
+for Dir in g_Args:
+ os.chdir(Dir)
+ CleanTree(Dir, g_Options.NoVerbose)
diff --git a/tools/genruntimemanifest.py b/tools/genruntimemanifest.py
new file mode 100644
index 000000000..ba0352525
--- /dev/null
+++ b/tools/genruntimemanifest.py
@@ -0,0 +1,53 @@
+Template=r"""<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
+<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level='asInvoker' uiAccess='false' />
+ </requestedPrivileges>
+ </security>
+ </trustInfo>
+ <dependency>
+ <dependentAssembly>
+ <assemblyIdentity type="win32" name="Microsoft.VC90.<DEBUG>CRT" version="9.0.<VERSION>" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b" />
+ </dependentAssembly>
+ </dependency>
+</assembly>
+"""
+
+import glob,re,sys
+
+if len(sys.argv)==3 and sys.argv[2]=="1":
+ Files=glob.glob(r"c:\windows\winsxs\x86_Microsoft.VC90.DebugCRT_1fc8b3b9a1e18e3b_9.0.*")
+ SearchRe=re.compile(r"c:\\windows\\winsxs\\x86_Microsoft\.VC90\.DebugCRT_1fc8b3b9a1e18e3b_9\.0\.([0-9]+)\.([0-9]+)_",re.I)
+else:
+ Files=glob.glob(r"c:\windows\winsxs\x86_Microsoft.VC90.CRT_1fc8b3b9a1e18e3b_9.0.*")
+ SearchRe=re.compile(r"c:\\windows\\winsxs\\x86_Microsoft\.VC90\.CRT_1fc8b3b9a1e18e3b_9\.0\.([0-9]+)\.([0-9]+)_",re.I)
+
+
+MajorVersion=0
+MinorVersion=0
+LatestFile=None
+#Now Select the one with the latest version
+for File in Files:
+ # Extract version
+ Search=SearchRe.search(File)
+ Major=int(Search.group(1))
+ Minor=int(Search.group(2))
+ if Major>MajorVersion:
+ MajorVersion=Major
+ MinorVersion=Minor
+ LatestFile=File
+ elif Major==MajorVersion and Minor>MinorVersion:
+ MinorVersion=Minor
+ LatestFile=File
+
+
+Template=re.sub("<VERSION>","%d.%d"%(MajorVersion,MinorVersion),Template)
+
+if len(sys.argv)==3 and sys.argv[2]=="1":
+ Template=re.sub("<DEBUG>","Debug",Template)
+else:
+ Template=re.sub("<DEBUG>","",Template)
+
+open(sys.argv[1],"w").write(Template)
diff --git a/tools/mhmake/CMakeLists.txt b/tools/mhmake/CMakeLists.txt
new file mode 100644
index 000000000..8af73f6db
--- /dev/null
+++ b/tools/mhmake/CMakeLists.txt
@@ -0,0 +1,51 @@
+cmake_minimum_required(VERSION 2.8)
+
+IF(CMAKE_BUILD_TYPE MATCHES "Release")
+SET(PROGRAM_NAME mhmake)
+ELSE(CMAKE_BUILD_TYPE MATCHES "Release")
+SET(PROGRAM_NAME mhmake_dbg)
+ENDIF(CMAKE_BUILD_TYPE MATCHES "Release")
+
+PROJECT(${PROGRAM_NAME})
+
+SET( CMAKE_CXX_FLAGS_DEBUG "-D _DEBUG")
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/mhmakelexer.cpp
+ COMMAND flex++ -S${CMAKE_CURRENT_SOURCE_DIR}/src/flex.skl -o${CMAKE_CURRENT_BINARY_DIR}/mhmakelexer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/mhmakelexer.l
+ COMMAND mv ${CMAKE_CURRENT_BINARY_DIR}/mhmakelexer.cpp ${CMAKE_CURRENT_BINARY_DIR}/temp1234.456
+ COMMAND echo '\#include \"stdafx.h\"' > ${CMAKE_CURRENT_BINARY_DIR}/mhmakelexer.cpp
+ COMMAND cat ${CMAKE_CURRENT_BINARY_DIR}/temp1234.456 >> ${CMAKE_CURRENT_BINARY_DIR}/mhmakelexer.cpp
+ COMMAND rm ${CMAKE_CURRENT_BINARY_DIR}/temp1234.456
+ COMMAND cp ${CMAKE_CURRENT_SOURCE_DIR}/src/flexlexer.h ${CMAKE_CURRENT_BINARY_DIR}/FlexLexer.h
+
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/src/mhmakelexer.l ${CMAKE_CURRENT_SOURCE_DIR}/src/flex.skl ${CMAKE_CURRENT_BINARY_DIR}/mhmakeparser.h
+)
+ADD_CUSTOM_COMMAND(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/mhmakeparser.cpp ${CMAKE_CURRENT_BINARY_DIR}/mhmakeparser.h
+ COMMAND bison++ -d -S${CMAKE_CURRENT_SOURCE_DIR}/src/bison.cc -H${CMAKE_CURRENT_SOURCE_DIR}/src/bison.h -h${CMAKE_CURRENT_BINARY_DIR}/mhmakeparser.h -otemp1234.456 ${CMAKE_CURRENT_SOURCE_DIR}/src/mhmakeparser.y
+ COMMAND echo '\#include \"stdafx.h\"' > ${CMAKE_CURRENT_BINARY_DIR}/mhmakeparser.cpp
+ COMMAND cat temp1234.456 >> ${CMAKE_CURRENT_BINARY_DIR}/mhmakeparser.cpp
+ COMMAND rm temp1234.456
+
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/src/mhmakeparser.y
+)
+INCLUDE_DIRECTORIES(src ${CMAKE_CURRENT_BINARY_DIR})
+LINK_LIBRARIES(/usr/lib/libpopt.a)
+
+ADD_EXECUTABLE(${PROGRAM_NAME}
+ ${CMAKE_CURRENT_BINARY_DIR}/mhmakeparser.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/mhmakelexer.cpp
+ src/mhmake.cpp
+ src/mhmakefileparser.cpp
+ src/util.cpp
+ src/functions.cpp
+ src/fileinfo.cpp
+ src/rule.cpp
+ src/md5.cpp
+ src/build.cpp
+ src/curdir.cpp
+ src/commandqueue.cpp
+ )
+
+INSTALL_TARGETS( /bin ${PROGRAM_NAME} )
diff --git a/tools/mhmake/COPYING b/tools/mhmake/COPYING
new file mode 100644
index 000000000..818433ecc
--- /dev/null
+++ b/tools/mhmake/COPYING
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/tools/mhmake/MHMake extensions to GNU make.url b/tools/mhmake/MHMake extensions to GNU make.url
new file mode 100644
index 000000000..ebd1a729c
--- /dev/null
+++ b/tools/mhmake/MHMake extensions to GNU make.url
@@ -0,0 +1,3 @@
+[InternetShortcut]
+URL=http://dspbeast/mydms/out/out.ViewDocument.php?folderdocid=385
+Modified=00A348C8283BC301DA
diff --git a/tools/mhmake/Makefile.am b/tools/mhmake/Makefile.am
new file mode 100644
index 000000000..02520f201
--- /dev/null
+++ b/tools/mhmake/Makefile.am
@@ -0,0 +1,5 @@
+# not a GNU package. You can remove this line, if
+# have all needed files, that a GNU package needs
+AUTOMAKE_OPTIONS = foreign 1.4
+
+SUBDIRS = src
diff --git a/tools/mhmake/Makefile.cvs b/tools/mhmake/Makefile.cvs
new file mode 100644
index 000000000..d16070234
--- /dev/null
+++ b/tools/mhmake/Makefile.cvs
@@ -0,0 +1,8 @@
+default: all
+
+all:
+ aclocal
+ autoheader
+ automake
+ autoconf
+
diff --git a/tools/mhmake/addstdafxh.py b/tools/mhmake/addstdafxh.py
new file mode 100644
index 000000000..45413a474
--- /dev/null
+++ b/tools/mhmake/addstdafxh.py
@@ -0,0 +1,33 @@
+import sys,re,os
+
+try:
+ InputFile=sys.argv[1]
+except:
+ print "No input file specified"
+ sys.exit(1)
+
+try:
+ InputFile=sys.argv[1]
+ pIN=open(InputFile,"r")
+ data=pIN.read()
+ pIN.close()
+except:
+ print "Error reading input file",InputFile
+ sys.exit(1)
+
+try:
+ pOUT=open(InputFile,"w")
+except:
+ print "Error opening",InputFile,"for writing"
+ sys.exit(1)
+
+pOUT.write("""#include "stdafx.h"\n""")
+#since we are going to add one line we need to update all line statements
+def IncrementLine(matchobj):
+ return "#line %d%s"%(int(matchobj.group(1))+1,matchobj.group(2))
+
+data=re.sub(r"#\s*line\s+(\d+)(.*%s)"%os.path.split(InputFile)[1],IncrementLine,data)
+
+pOUT.write(data)
+pOUT.close()
+
diff --git a/tools/mhmake/bison++.exe b/tools/mhmake/bison++.exe
new file mode 100644
index 000000000..a8d48fcfe
--- /dev/null
+++ b/tools/mhmake/bison++.exe
Binary files differ
diff --git a/tools/mhmake/config.guess b/tools/mhmake/config.guess
new file mode 100644
index 000000000..5145e3571
--- /dev/null
+++ b/tools/mhmake/config.guess
@@ -0,0 +1,1363 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002 Free Software Foundation, Inc.
+
+timestamp='2002-10-21'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub. If it succeeds, it prints the system name on stdout, and
+# exits with 0. Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit 0 ;;
+ --version | -v )
+ echo "$version" ; exit 0 ;;
+ --help | --h* | -h )
+ echo "$usage"; exit 0 ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help" >&2
+ exit 1 ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# != 0; then
+ echo "$me: too many arguments$help" >&2
+ exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# This shell variable is my proudest work .. or something. --bje
+
+set_cc_for_build='tmpdir=${TMPDIR-/tmp}/config-guess-$$ ;
+(old=`umask` && umask 077 && mkdir $tmpdir && umask $old && unset old)
+ || (echo "$me: cannot create $tmpdir" >&2 && exit 1) ;
+dummy=$tmpdir/dummy ;
+files="$dummy.c $dummy.o $dummy.rel $dummy" ;
+trap '"'"'rm -f $files; rmdir $tmpdir; exit 1'"'"' 1 2 15 ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int x;" > $dummy.c ;
+ for c in cc gcc c89 c99 ; do
+ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+ CC_FOR_BUILD="$c"; break ;
+ fi ;
+ done ;
+ rm -f $files ;
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found ;
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac ;
+unset files'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+ # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ #
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+ UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+ case "${UNAME_MACHINE_ARCH}" in
+ armeb) machine=armeb-unknown ;;
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+ # to ELF recently, or will in the future.
+ case "${UNAME_MACHINE_ARCH}" in
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ eval $set_cc_for_build
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep __ELF__ >/dev/null
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ ;;
+ *)
+ os=netbsd
+ ;;
+ esac
+ # The OS release
+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}"
+ exit 0 ;;
+ amiga:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ arc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ hp300:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mac68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ macppc:OpenBSD:*:*)
+ echo powerpc-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme88k:OpenBSD:*:*)
+ echo m88k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvmeppc:OpenBSD:*:*)
+ echo powerpc-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ pmax:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sgi:OpenBSD:*:*)
+ echo mipseb-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sun3:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ wgrisc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:OpenBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ alpha:OSF1:*:*)
+ if test $UNAME_RELEASE = "V4.0"; then
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ fi
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ eval $set_cc_for_build
+ cat <<EOF >$dummy.s
+ .data
+\$Lformat:
+ .byte 37,100,45,37,120,10,0 # "%d-%x\n"
+
+ .text
+ .globl main
+ .align 4
+ .ent main
+main:
+ .frame \$30,16,\$26,0
+ ldgp \$29,0(\$27)
+ .prologue 1
+ .long 0x47e03d80 # implver \$0
+ lda \$2,-1
+ .long 0x47e20c21 # amask \$2,\$1
+ lda \$16,\$Lformat
+ mov \$0,\$17
+ not \$1,\$18
+ jsr \$26,printf
+ ldgp \$29,0(\$26)
+ mov 0,\$16
+ jsr \$26,exit
+ .end main
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.s 2>/dev/null
+ if test "$?" = 0 ; then
+ case `$dummy` in
+ 0-0)
+ UNAME_MACHINE="alpha"
+ ;;
+ 1-0)
+ UNAME_MACHINE="alphaev5"
+ ;;
+ 1-1)
+ UNAME_MACHINE="alphaev56"
+ ;;
+ 1-101)
+ UNAME_MACHINE="alphapca56"
+ ;;
+ 2-303)
+ UNAME_MACHINE="alphaev6"
+ ;;
+ 2-307)
+ UNAME_MACHINE="alphaev67"
+ ;;
+ 2-1307)
+ UNAME_MACHINE="alphaev68"
+ ;;
+ 3-1307)
+ UNAME_MACHINE="alphaev7"
+ ;;
+ esac
+ fi
+ rm -f $dummy.s $dummy && rmdir $tmpdir
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ exit 0 ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit 0 ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit 0 ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit 0;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit 0 ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
+ exit 0 ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit 0 ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit 0;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit 0;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit 0 ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit 0 ;;
+ DRS?6000:UNIX_SV:4.2*:7*)
+ case `/usr/bin/uname -p` in
+ sparc) echo sparc-icl-nx7 && exit 0 ;;
+ esac ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ i86pc:SunOS:5.*:*)
+ echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit 0 ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit 0 ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit 0 ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit 0 ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit 0 ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit 0 ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit 0 ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit 0 ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c \
+ && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+ && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0
+ rm -f $dummy.c $dummy && rmdir $tmpdir
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit 0 ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit 0 ;;
+ Motorola:*:4.3:PL8-*)
+ echo powerpc-harris-powermax
+ exit 0 ;;
+ Night_Hawk:*:*:PowerMAX_OS)
+ echo powerpc-harris-powermax
+ exit 0 ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit 0 ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit 0 ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit 0 ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit 0 ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit 0 ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit 0 ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit 0 ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit 0 ;;
+ ia64:AIX:*:*)
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ exit 0 ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0
+ rm -f $dummy.c $dummy && rmdir $tmpdir
+ echo rs6000-ibm-aix3.2.5
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit 0 ;;
+ *:AIX:*:[45])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit 0 ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit 0 ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit 0 ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit 0 ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit 0 ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit 0 ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit 0 ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit 0 ;;
+ 9000/[34678]??:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+ esac ;;
+ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
+ rm -f $dummy.c $dummy && rmdir $tmpdir
+ fi ;;
+ esac
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit 0 ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit 0 ;;
+ 3050*:HI-UX:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0
+ rm -f $dummy.c $dummy && rmdir $tmpdir
+ echo unknown-hitachi-hiuxwe2
+ exit 0 ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit 0 ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit 0 ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit 0 ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit 0 ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit 0 ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit 0 ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit 0 ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*T3D:*:*:*)
+ echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit 0 ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:FreeBSD:*:*)
+ # Determine whether the default compiler uses glibc.
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <features.h>
+ #if __GLIBC__ >= 2
+ LIBC=gnu
+ #else
+ LIBC=
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+ rm -f $dummy.c && rmdir $tmpdir
+ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC}
+ exit 0 ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit 0 ;;
+ i*:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit 0 ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit 0 ;;
+ x86:Interix*:3*)
+ echo i386-pc-interix3
+ exit 0 ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i386-pc-interix
+ exit 0 ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit 0 ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit 0 ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ *:GNU:*:*)
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit 0 ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit 0 ;;
+ arm*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ mips:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef mips
+ #undef mipsel
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=mipsel
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=mips
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+ rm -f $dummy.c && rmdir $tmpdir
+ test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0
+ ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-gnu
+ exit 0 ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-gnu
+ exit 0 ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+ if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+ exit 0 ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) echo hppa1.1-unknown-linux-gnu ;;
+ PA8*) echo hppa2.0-unknown-linux-gnu ;;
+ *) echo hppa-unknown-linux-gnu ;;
+ esac
+ exit 0 ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-gnu
+ exit 0 ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux
+ exit 0 ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ x86_64:Linux:*:*)
+ echo x86_64-unknown-linux-gnu
+ exit 0 ;;
+ i*86:Linux:*:*)
+ # The BFD linker knows what the default object file format is, so
+ # first see if it will tell us. cd to the root directory to prevent
+ # problems with other programs or directories called `ld' in the path.
+ # Set LC_ALL=C to ensure ld outputs messages in English.
+ ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+ | sed -ne '/supported targets:/!d
+ s/[ ][ ]*/ /g
+ s/.*supported targets: *//
+ s/ .*//
+ p'`
+ case "$ld_supported_targets" in
+ elf32-i386)
+ TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+ ;;
+ a.out-i386-linux)
+ echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+ exit 0 ;;
+ coff-i386)
+ echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+ exit 0 ;;
+ "")
+ # Either a pre-BFD a.out linker (linux-gnuoldld) or
+ # one that does not give us useful --help.
+ echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+ exit 0 ;;
+ esac
+ # Determine whether the default compiler is a.out or elf
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <features.h>
+ #ifdef __ELF__
+ # ifdef __GLIBC__
+ # if __GLIBC__ >= 2
+ LIBC=gnu
+ # else
+ LIBC=gnulibc1
+ # endif
+ # else
+ LIBC=gnulibc1
+ # endif
+ #else
+ #ifdef __INTEL_COMPILER
+ LIBC=gnu
+ #else
+ LIBC=gnuaout
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+ rm -f $dummy.c && rmdir $tmpdir
+ test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
+ test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+ ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ # earlier versions are messed up and put the nodename in both
+ # sysname and nodename.
+ echo i386-sequent-sysv4
+ exit 0 ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit 0 ;;
+ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit 0 ;;
+ i*86:*:5:[78]*)
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+ *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ esac
+ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ exit 0 ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit 0 ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit 0 ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i386.
+ echo i386-pc-msdosdjgpp
+ exit 0 ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit 0 ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit 0 ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit 0 ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit 0 ;;
+ mc68k:UNIX:SYSTEM5:3.51m)
+ echo m68k-convergent-sysv
+ exit 0 ;;
+ M68*:*:R3V[567]*:*)
+ test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+ 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4 && exit 0 ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit 0 ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit 0 ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit 0 ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit 0 ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit 0 ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit 0 ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit 0 ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit 0 ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit 0 ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit 0 ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit 0 ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit 0 ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit 0 ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit 0 ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit 0 ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit 0 ;;
+ *:Darwin:*:*)
+ echo `uname -p`-apple-darwin${UNAME_RELEASE}
+ exit 0 ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ UNAME_PROCESSOR=`uname -p`
+ if test "$UNAME_PROCESSOR" = "x86"; then
+ UNAME_PROCESSOR=i386
+ UNAME_MACHINE=pc
+ fi
+ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ exit 0 ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit 0 ;;
+ NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit 0 ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit 0 ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit 0 ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit 0 ;;
+ *:Plan9:*:*)
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+ if test "$cputype" = "386"; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+ fi
+ echo ${UNAME_MACHINE}-unknown-plan9
+ exit 0 ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit 0 ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit 0 ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit 0 ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit 0 ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit 0 ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit 0 ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit 0 ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit 0 ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+ printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+ printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ if (version < 4)
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ else
+ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+# include <sys/param.h>
+# if defined (BSD)
+# if BSD == 43
+ printf ("vax-dec-bsd4.3\n"); exit (0);
+# else
+# if BSD == 199006
+ printf ("vax-dec-bsd4.3reno\n"); exit (0);
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# endif
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# else
+ printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0
+rm -f $dummy.c $dummy && rmdir $tmpdir
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+ case `getsysinfo -f cpu_type` in
+ c1*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ c34*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ c38*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ c4*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+ ftp://ftp.gnu.org/pub/gnu/config/
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/tools/mhmake/config.sub b/tools/mhmake/config.sub
new file mode 100644
index 000000000..1dea9b79d
--- /dev/null
+++ b/tools/mhmake/config.sub
@@ -0,0 +1,1470 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002 Free Software Foundation, Inc.
+
+timestamp='2002-09-05'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine. It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+ $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit 0 ;;
+ --version | -v )
+ echo "$version" ; exit 0 ;;
+ --help | --h* | -h )
+ echo "$usage"; exit 0 ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo $1
+ exit 0;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | freebsd*-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis)
+ os=
+ basic_machine=$1
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+ | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+ | fr30 | frv \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k \
+ | m32r | m68000 | m68k | m88k | mcore \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64vr | mips64vrel \
+ | mips64orion | mips64orionel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | ns16k | ns32k \
+ | openrisc | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+ | pyramid \
+ | sh | sh[1234] | sh3e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
+ | strongarm \
+ | tahoe | thumb | tic80 | tron \
+ | v850 | v850e \
+ | we32k \
+ | x86 | xscale | xstormy16 | xtensa \
+ | z8k)
+ basic_machine=$basic_machine-unknown
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12)
+ # Motorola 68HC11/12.
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* \
+ | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* \
+ | clipper-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | elxsi-* \
+ | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* \
+ | m32r-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | mcore-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipstx39 | mipstx39el \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+ | pyramid-* \
+ | romp-* | rs6000-* \
+ | sh-* | sh[1234]-* | sh3e-* | sh[34]eb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
+ | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+ | tahoe-* | thumb-* | tic30-* | tic4x-* | tic54x-* | tic80-* | tron-* \
+ | v850-* | v850e-* | vax-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
+ | xtensa-* \
+ | ymp-* \
+ | z8k-*)
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | j90)
+ basic_machine=j90-cray
+ os=-unicos
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+# I'm not sure what "Sysv32" means. Should this be sysv3.2?
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ mingw32)
+ basic_machine=i386-pc
+ os=-mingw32
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ mmix*)
+ basic_machine=mmix-knuth
+ os=-mmixware
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ or32 | or32-*)
+ basic_machine=or32-unknown
+ os=-coff
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pentium | p5 | k5 | k6 | nexgen | viac3)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2)
+ basic_machine=i686-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc) basic_machine=powerpc-unknown
+ ;;
+ ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sparclite-wrs | simso-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3d)
+ basic_machine=alpha-cray
+ os=-unicos
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+ tic4x | c4x*)
+ basic_machine=tic4x-unknown
+ os=-coff
+ ;;
+ tic54x | c54x*)
+ basic_machine=tic54x-unknown
+ os=-coff
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ windows32)
+ basic_machine=i386-pc
+ os=-windows32-msvcrt
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp10)
+ # there are many clones, so DEC is not a safe bet
+ basic_machine=pdp10-unknown
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh3 | sh4 | sh3eb | sh4eb | sh[1234]le | sh3ele)
+ basic_machine=sh-unknown
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparc | sparcv9 | sparcv9b)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* \
+ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* | -powermax*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto*)
+ os=-nto-qnx
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -atheos*)
+ os=-atheos
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ # This also exists in the configure program, but was not the
+ # default.
+ # os=-sunos4
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or32-*)
+ os=-coff
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/tools/mhmake/configure.in b/tools/mhmake/configure.in
new file mode 100644
index 000000000..ca6a5389b
--- /dev/null
+++ b/tools/mhmake/configure.in
@@ -0,0 +1,20 @@
+AC_INIT(configure.in)
+
+AM_CONFIG_HEADER(config.h)
+AM_INIT_AUTOMAKE(mhmake, 0.1)
+
+AC_ARG_ENABLE(debug,
+[ --enable-debug Turn on debugging],
+[case "${enableval}" in
+ yes) debug=true ;;
+ full) debug=true ;;
+ no) debug=false ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for --enable-debug) ;;
+esac],[debug=false])
+AM_CONDITIONAL(DEBUG, test x$debug = xtrue)
+
+AC_LANG_CPLUSPLUS
+AC_PROG_CXX
+AC_PROG_CC
+
+AC_OUTPUT(Makefile src/Makefile)
diff --git a/tools/mhmake/cygwin1.dll b/tools/mhmake/cygwin1.dll
new file mode 100644
index 000000000..116037f1b
--- /dev/null
+++ b/tools/mhmake/cygwin1.dll
Binary files differ
diff --git a/tools/mhmake/depcomp b/tools/mhmake/depcomp
new file mode 100644
index 000000000..4c20c6c94
--- /dev/null
+++ b/tools/mhmake/depcomp
@@ -0,0 +1,441 @@
+#! /bin/sh
+
+# depcomp - compile a program generating dependencies as side-effects
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+
+# 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, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+ echo "depcomp: Variables source, object and depmode must be set" 1>&2
+ exit 1
+fi
+# `libtool' can also be set to `yes' or `no'.
+
+depfile=${depfile-`echo "$object" | sed 's,\([^/]*\)$,.deps/\1,;s/\.\([^.]*\)$/.P\1/'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags. We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write. Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+ # HP compiler uses -M and no extra arg.
+ gccflag=-M
+ depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+ # This is just like dashmstdout with a different argument.
+ dashmflag=-xM
+ depmode=dashmstdout
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want. Yay! Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff. Hmm.
+ "$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ mv "$tmpdepfile" "$depfile"
+ ;;
+
+gcc)
+## There are various ways to get dependency output from gcc. Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+## up in a subdir. Having to rename by hand is ugly.
+## (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+## -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+## than renaming).
+ if test -z "$gccflag"; then
+ gccflag=-MD,
+ fi
+ "$@" -Wp,"$gccflag$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+ sed -e 's/^[^:]*: / /' \
+ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header). We avoid this by adding
+## dummy dependencies for each header file. Too bad gcc doesn't do
+## this for us directly.
+ tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'. On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+sgi)
+ if test "$libtool" = yes; then
+ "$@" "-Wp,-MDupdate,$tmpdepfile"
+ else
+ "$@" -MDupdate "$tmpdepfile"
+ fi
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+
+ if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
+ echo "$object : \\" > "$depfile"
+
+ # Clip off the initial element (the dependent). Don't try to be
+ # clever and replace this with sed code, as IRIX sed won't handle
+ # lines with more than a fixed number of characters (4096 in
+ # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
+ # the IRIX cc adds comments like `#:fec' to the end of the
+ # dependency line.
+ tr ' ' '
+' < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+ tr '
+' ' ' >> $depfile
+ echo >> $depfile
+
+ # The second pass generates a dummy entry for each header file.
+ tr ' ' '
+' < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+ >> $depfile
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+aix)
+ # The C for AIX Compiler uses -M and outputs the dependencies
+ # in a .u file. This file always lives in the current directory.
+ # Also, the AIX compiler puts `$object:' at the start of each line;
+ # $object doesn't have directory information.
+ stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'`
+ tmpdepfile="$stripped.u"
+ outname="$stripped.o"
+ if test "$libtool" = yes; then
+ "$@" -Wc,-M
+ else
+ "$@" -M
+ fi
+
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+
+ if test -f "$tmpdepfile"; then
+ # Each line is of the form `foo.o: dependent.h'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
+ sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+icc)
+ # Must come before tru64.
+
+ # Intel's C compiler understands `-MD -MF file'. However
+ # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+ # will fill foo.d with something like
+ # foo.o: sub/foo.c
+ # foo.o: sub/foo.h
+ # which is wrong. We want:
+ # sub/foo.o: sub/foo.c
+ # sub/foo.o: sub/foo.h
+ # sub/foo.c:
+ # sub/foo.h:
+
+ "$@" -MD -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ # Each line is of the form `foo.o: dependent.h'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed -e "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+ sed -e "s,^[^:]*: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+tru64)
+ # The Tru64 AIX compiler uses -MD to generate dependencies as a side
+ # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+ # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+ # dependencies in `foo.d' instead, so we check for that too.
+ # Subdirectories are respected.
+
+ tmpdepfile1="$object.d"
+ tmpdepfile2=`echo "$object" | sed -e 's/.o$/.d/'`
+ if test "$libtool" = yes; then
+ "$@" -Wc,-MD
+ else
+ "$@" -MD
+ fi
+
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2"
+ exit $stat
+ fi
+
+ if test -f "$tmpdepfile1"; then
+ tmpdepfile="$tmpdepfile1"
+ else
+ tmpdepfile="$tmpdepfile2"
+ fi
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+ # That's a space and a tab in the [].
+ sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+ else
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+#nosideeffect)
+ # This comment above is used by automake to tell side-effect
+ # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the proprocessed file to stdout, regardless of -o,
+ # because we must use -o when running libtool.
+ test -z "$dashmflag" && dashmflag=-M
+ ( IFS=" "
+ case " $* " in
+ *" --mode=compile "*) # this is libtool, let us make it quiet
+ for arg
+ do # cycle over the arguments
+ case "$arg" in
+ "--mode=compile")
+ # insert --quiet before "--mode=compile"
+ set fnord "$@" --quiet
+ shift # fnord
+ ;;
+ esac
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # "$arg"
+ done
+ ;;
+ esac
+ "$@" $dashmflag | sed 's:^[^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
+ ) &
+ proc=$!
+ "$@"
+ stat=$?
+ wait "$proc"
+ if test "$stat" != 0; then exit $stat; fi
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+dashXmstdout)
+ # This case only exists to satisfy depend.m4. It is never actually
+ # run, as this mode is specially recognized in the preamble.
+ exit 1
+ ;;
+
+makedepend)
+ # X makedepend
+ (
+ shift
+ cleared=no
+ for arg in "$@"; do
+ case $cleared in no)
+ set ""; shift
+ cleared=yes
+ esac
+ case "$arg" in
+ -D*|-I*)
+ set fnord "$@" "$arg"; shift;;
+ -*)
+ ;;
+ *)
+ set fnord "$@" "$arg"; shift;;
+ esac
+ done
+ obj_suffix="`echo $object | sed 's/^.*\././'`"
+ touch "$tmpdepfile"
+ ${MAKEDEPEND-makedepend} 2>/dev/null -o"$obj_suffix" -f"$tmpdepfile" "$@"
+ ) &
+ proc=$!
+ "$@"
+ stat=$?
+ wait "$proc"
+ if test "$stat" != 0; then exit $stat; fi
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ tail +3 "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile" "$tmpdepfile".bak
+ ;;
+
+cpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the proprocessed file to stdout, regardless of -o,
+ # because we must use -o when running libtool.
+ ( IFS=" "
+ case " $* " in
+ *" --mode=compile "*)
+ for arg
+ do # cycle over the arguments
+ case $arg in
+ "--mode=compile")
+ # insert --quiet before "--mode=compile"
+ set fnord "$@" --quiet
+ shift # fnord
+ ;;
+ esac
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # "$arg"
+ done
+ ;;
+ esac
+ "$@" -E |
+ sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+ sed '$ s: \\$::' > "$tmpdepfile"
+ ) &
+ proc=$!
+ "$@"
+ stat=$?
+ wait "$proc"
+ if test "$stat" != 0; then exit $stat; fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ cat < "$tmpdepfile" >> "$depfile"
+ sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvisualcpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the proprocessed file to stdout, regardless of -o,
+ # because we must use -o when running libtool.
+ ( IFS=" "
+ case " $* " in
+ *" --mode=compile "*)
+ for arg
+ do # cycle over the arguments
+ case $arg in
+ "--mode=compile")
+ # insert --quiet before "--mode=compile"
+ set fnord "$@" --quiet
+ shift # fnord
+ ;;
+ esac
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # "$arg"
+ done
+ ;;
+ esac
+ "$@" -E |
+ sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
+ ) &
+ proc=$!
+ "$@"
+ stat=$?
+ wait "$proc"
+ if test "$stat" != 0; then exit $stat; fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
+ echo " " >> "$depfile"
+ . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+none)
+ exec "$@"
+ ;;
+
+*)
+ echo "Unknown depmode $depmode" 1>&2
+ exit 1
+ ;;
+esac
+
+exit 0
diff --git a/tools/mhmake/flex++.exe b/tools/mhmake/flex++.exe
new file mode 100644
index 000000000..14da34eb0
--- /dev/null
+++ b/tools/mhmake/flex++.exe
Binary files differ
diff --git a/tools/mhmake/genkdev4.sh b/tools/mhmake/genkdev4.sh
new file mode 100755
index 000000000..1acfe13b4
--- /dev/null
+++ b/tools/mhmake/genkdev4.sh
@@ -0,0 +1,12 @@
+mkdir build
+cd build
+cmake -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_BUILD_TYPE=Release ..
+cd ..
+mkdir build.dbg
+cd build.dbg
+cmake -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_BUILD_TYPE=Debug ..
+cd ..
+mkdir .kdev4
+echo [CMake] > .kdev4/mhmake.kdev4
+echo BuildDirs[\$e]=$PWD/build,$PWD/build.dbg >> .kdev4/mhmake.kdev4
+
diff --git a/tools/mhmake/install-sh b/tools/mhmake/install-sh
new file mode 100644
index 000000000..36f96f3e0
--- /dev/null
+++ b/tools/mhmake/install-sh
@@ -0,0 +1,276 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission. M.I.T. makes no representations about the
+# suitability of this software for any purpose. It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch. It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c) instcmd=$cpprog
+ shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd=$stripprog
+ shift
+ continue;;
+
+ -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+ shift
+ continue;;
+
+ -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+ shift
+ continue;;
+
+ *) if [ x"$src" = x ]
+ then
+ src=$1
+ else
+ # this colon is to work around a 386BSD /bin/sh bug
+ :
+ dst=$1
+ fi
+ shift
+ continue;;
+ esac
+done
+
+if [ x"$src" = x ]
+then
+ echo "$0: no input file specified" >&2
+ exit 1
+else
+ :
+fi
+
+if [ x"$dir_arg" != x ]; then
+ dst=$src
+ src=""
+
+ if [ -d "$dst" ]; then
+ instcmd=:
+ chmodcmd=""
+ else
+ instcmd=$mkdirprog
+ fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+ if [ -f "$src" ] || [ -d "$src" ]
+ then
+ :
+ else
+ echo "$0: $src does not exist" >&2
+ exit 1
+ fi
+
+ if [ x"$dst" = x ]
+ then
+ echo "$0: no destination specified" >&2
+ exit 1
+ else
+ :
+ fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+ if [ -d "$dst" ]
+ then
+ dst=$dst/`basename "$src"`
+ else
+ :
+ fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+# this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+ '
+IFS="${IFS-$defaultIFS}"
+
+oIFS=$IFS
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS=$oIFS
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+ pathcomp=$pathcomp$1
+ shift
+
+ if [ ! -d "$pathcomp" ] ;
+ then
+ $mkdirprog "$pathcomp"
+ else
+ :
+ fi
+
+ pathcomp=$pathcomp/
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+ $doit $instcmd "$dst" &&
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+ if [ x"$transformarg" = x ]
+ then
+ dstfile=`basename "$dst"`
+ else
+ dstfile=`basename "$dst" $transformbasename |
+ sed $transformarg`$transformbasename
+ fi
+
+# don't allow the sed command to completely eliminate the filename
+
+ if [ x"$dstfile" = x ]
+ then
+ dstfile=`basename "$dst"`
+ else
+ :
+ fi
+
+# Make a couple of temp file names in the proper directory.
+
+ dsttmp=$dstdir/#inst.$$#
+ rmtmp=$dstdir/#rm.$$#
+
+# Trap to clean up temp files at exit.
+
+ trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
+ trap '(exit $?); exit' 1 2 13 15
+
+# Move or copy the file name to the temp name
+
+ $doit $instcmd "$src" "$dsttmp" &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing. If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi &&
+
+# Now remove or move aside any old file at destination location. We try this
+# two ways since rm can't unlink itself on some systems and the destination
+# file might be busy for other reasons. In this case, the final cleanup
+# might fail but the new file should still install successfully.
+
+{
+ if [ -f "$dstdir/$dstfile" ]
+ then
+ $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null ||
+ $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null ||
+ {
+ echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
+ (exit 1); exit
+ }
+ else
+ :
+ fi
+} &&
+
+# Now rename the file to the real destination.
+
+ $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
+
+fi &&
+
+# The final little trick to "correctly" pass the exit status to the exit trap.
+
+{
+ (exit 0); exit
+}
diff --git a/tools/mhmake/ltmain.sh b/tools/mhmake/ltmain.sh
new file mode 100644
index 000000000..b36e997fe
--- /dev/null
+++ b/tools/mhmake/ltmain.sh
@@ -0,0 +1,6343 @@
+# ltmain.sh - Provide generalized library-building support services.
+# NOTE: Changing this file will not affect anything until you rerun configure.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003
+# Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Check that we have a working $echo.
+if test "X$1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X$1" = X--fallback-echo; then
+ # Avoid inline document here, it may be left over
+ :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+ # Yippee, $echo works!
+ :
+else
+ # Restart under the correct shell, and then maybe $echo will work.
+ exec $SHELL "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<EOF
+$*
+EOF
+ exit 0
+fi
+
+# The name of this program.
+progname=`$echo "$0" | ${SED} 's%^.*/%%'`
+modename="$progname"
+
+# Constants.
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION=1.5a
+TIMESTAMP=" (1.1240 2003/06/26 06:55:19)"
+
+default_mode=
+help="Try \`$progname --help' for more information."
+magic="%%%MAGIC variable%%%"
+mkdir="mkdir"
+mv="mv -f"
+rm="rm -f"
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed="${SED}"' -e 1s/^X//'
+sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
+# test EBCDIC or ASCII
+case `echo A|tr A '\301'` in
+ A) # EBCDIC based system
+ SP2NL="tr '\100' '\n'"
+ NL2SP="tr '\r\n' '\100\100'"
+ ;;
+ *) # Assume ASCII based system
+ SP2NL="tr '\040' '\012'"
+ NL2SP="tr '\015\012' '\040\040'"
+ ;;
+esac
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+# We save the old values to restore during execute mode.
+if test "${LC_ALL+set}" = set; then
+ save_LC_ALL="$LC_ALL"; LC_ALL=C; export LC_ALL
+fi
+if test "${LANG+set}" = set; then
+ save_LANG="$LANG"; LANG=C; export LANG
+fi
+
+# Make sure IFS has a sensible default
+: ${IFS=" "}
+
+if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+ $echo "$modename: not configured to build any kind of library" 1>&2
+ $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
+ exit 1
+fi
+
+# Global variables.
+mode=$default_mode
+nonopt=
+prev=
+prevopt=
+run=
+show="$echo"
+show_help=
+execute_dlfiles=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+
+#####################################
+# Shell function definitions:
+# This seems to be the best place for them
+
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+win32_libid () {
+ win32_libid_type="unknown"
+ win32_fileres=`file -L $1 2>/dev/null`
+ case $win32_fileres in
+ *ar\ archive\ import\ library*) # definitely import
+ win32_libid_type="x86 archive import"
+ ;;
+ *ar\ archive*) # could be an import, or static
+ if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \
+ grep -E 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then
+ win32_nmres=`eval $NM -f posix -A $1 | \
+ sed -n -e '1,100{/ I /{x;/import/!{s/^/import/;h;p;};x;};}'`
+ if test "X$win32_nmres" = "Ximport" ; then
+ win32_libid_type="x86 archive import"
+ else
+ win32_libid_type="x86 archive static"
+ fi
+ fi
+ ;;
+ *DLL*)
+ win32_libid_type="x86 DLL"
+ ;;
+ *executable*) # but shell scripts are "executable" too...
+ case $win32_fileres in
+ *MS\ Windows\ PE\ Intel*)
+ win32_libid_type="x86 DLL"
+ ;;
+ esac
+ ;;
+ esac
+ $echo $win32_libid_type
+}
+
+# End of Shell function definitions
+#####################################
+
+# Parse our command line options once, thoroughly.
+while test "$#" -gt 0
+do
+ arg="$1"
+ shift
+
+ case $arg in
+ -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) optarg= ;;
+ esac
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case $prev in
+ execute_dlfiles)
+ execute_dlfiles="$execute_dlfiles $arg"
+ ;;
+ tag)
+ tagname="$arg"
+
+ # Check whether tagname contains only valid characters
+ case $tagname in
+ *[!-_A-Za-z0-9,/]*)
+ $echo "$progname: invalid tag name: $tagname" 1>&2
+ exit 1
+ ;;
+ esac
+
+ case $tagname in
+ CC)
+ # Don't test for the "default" C tag, as we know, it's there, but
+ # not specially marked.
+ ;;
+ *)
+ if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$0" > /dev/null; then
+ taglist="$taglist $tagname"
+ # Evaluate the configuration.
+ eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $0`"
+ else
+ $echo "$progname: ignoring unknown tag $tagname" 1>&2
+ fi
+ ;;
+ esac
+ ;;
+ *)
+ eval "$prev=\$arg"
+ ;;
+ esac
+
+ prev=
+ prevopt=
+ continue
+ fi
+
+ # Have we seen a non-optional argument yet?
+ case $arg in
+ --help)
+ show_help=yes
+ ;;
+
+ --version)
+ $echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"
+ $echo
+ $echo "Copyright (C) 2003 Free Software Foundation, Inc."
+ $echo "This is free software; see the source for copying conditions. There is NO"
+ $echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+ exit 0
+ ;;
+
+ --config)
+ ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $0
+ # Now print the configurations for the tags.
+ for tagname in $taglist; do
+ ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$0"
+ done
+ exit 0
+ ;;
+
+ --debug)
+ $echo "$progname: enabling shell trace mode"
+ set -x
+ ;;
+
+ --dry-run | -n)
+ run=:
+ ;;
+
+ --features)
+ $echo "host: $host"
+ if test "$build_libtool_libs" = yes; then
+ $echo "enable shared libraries"
+ else
+ $echo "disable shared libraries"
+ fi
+ if test "$build_old_libs" = yes; then
+ $echo "enable static libraries"
+ else
+ $echo "disable static libraries"
+ fi
+ exit 0
+ ;;
+
+ --finish) mode="finish" ;;
+
+ --mode) prevopt="--mode" prev=mode ;;
+ --mode=*) mode="$optarg" ;;
+
+ --preserve-dup-deps) duplicate_deps="yes" ;;
+
+ --quiet | --silent)
+ show=:
+ ;;
+
+ --tag) prevopt="--tag" prev=tag ;;
+ --tag=*)
+ set tag "$optarg" ${1+"$@"}
+ shift
+ prev=tag
+ ;;
+
+ -dlopen)
+ prevopt="-dlopen"
+ prev=execute_dlfiles
+ ;;
+
+ -*)
+ $echo "$modename: unrecognized option \`$arg'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+
+ *)
+ nonopt="$arg"
+ break
+ ;;
+ esac
+done
+
+if test -n "$prevopt"; then
+ $echo "$modename: option \`$prevopt' requires an argument" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+fi
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end. This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+if test -z "$show_help"; then
+
+ # Infer the operation mode.
+ if test -z "$mode"; then
+ $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2
+ $echo "*** Future versions of Libtool will require -mode=MODE be specified." 1>&2
+ case $nonopt in
+ *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*)
+ mode=link
+ for arg
+ do
+ case $arg in
+ -c)
+ mode=compile
+ break
+ ;;
+ esac
+ done
+ ;;
+ *db | *dbx | *strace | *truss)
+ mode=execute
+ ;;
+ *install*|cp|mv)
+ mode=install
+ ;;
+ *rm)
+ mode=uninstall
+ ;;
+ *)
+ # If we have no mode, but dlfiles were specified, then do execute mode.
+ test -n "$execute_dlfiles" && mode=execute
+
+ # Just use the default operation mode.
+ if test -z "$mode"; then
+ if test -n "$nonopt"; then
+ $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2
+ else
+ $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2
+ fi
+ fi
+ ;;
+ esac
+ fi
+
+ # Only execute mode is allowed to have -dlopen flags.
+ if test -n "$execute_dlfiles" && test "$mode" != execute; then
+ $echo "$modename: unrecognized option \`-dlopen'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Change the help message to a mode-specific one.
+ generic_help="$help"
+ help="Try \`$modename --help --mode=$mode' for more information."
+
+ # These modes are in order of execution frequency so that they run quickly.
+ case $mode in
+ # libtool compile mode
+ compile)
+ modename="$modename: compile"
+ # Get the compilation command and the source file.
+ base_compile=
+ srcfile="$nonopt" # always keep a non-empty value in "srcfile"
+ suppress_output=
+ arg_mode=normal
+ libobj=
+
+ for arg
+ do
+ case "$arg_mode" in
+ arg )
+ # do not "continue". Instead, add this to base_compile
+ lastarg="$arg"
+ arg_mode=normal
+ ;;
+
+ target )
+ libobj="$arg"
+ arg_mode=normal
+ continue
+ ;;
+
+ normal )
+ # Accept any command-line options.
+ case $arg in
+ -o)
+ if test -n "$libobj" ; then
+ $echo "$modename: you cannot specify \`-o' more than once" 1>&2
+ exit 1
+ fi
+ arg_mode=target
+ continue
+ ;;
+
+ -static)
+ build_old_libs=yes
+ continue
+ ;;
+
+ -prefer-pic)
+ pic_mode=yes
+ continue
+ ;;
+
+ -prefer-non-pic)
+ pic_mode=no
+ continue
+ ;;
+
+ -Xcompiler)
+ arg_mode=arg # the next one goes into the "base_compile" arg list
+ continue # The current "srcfile" will either be retained or
+ ;; # replaced later. I would guess that would be a bug.
+
+ -Wc,*)
+ args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"`
+ lastarg=
+ save_ifs="$IFS"; IFS=','
+ for arg in $args; do
+ IFS="$save_ifs"
+
+ # Double-quote args containing other shell metacharacters.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ case $arg in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ arg="\"$arg\""
+ ;;
+ esac
+ lastarg="$lastarg $arg"
+ done
+ IFS="$save_ifs"
+ lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"`
+
+ # Add the arguments to base_compile.
+ base_compile="$base_compile $lastarg"
+ continue
+ ;;
+
+ * )
+ # Accept the current argument as the source file.
+ # The previous "srcfile" becomes the current argument.
+ #
+ lastarg="$srcfile"
+ srcfile="$arg"
+ ;;
+ esac # case $arg
+ ;;
+ esac # case $arg_mode
+
+ # Aesthetically quote the previous argument.
+ lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"`
+
+ case $lastarg in
+ # Double-quote args containing other shell metacharacters.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ lastarg="\"$lastarg\""
+ ;;
+ esac
+
+ base_compile="$base_compile $lastarg"
+ done # for arg
+
+ case $arg_mode in
+ arg)
+ $echo "$modename: you must specify an argument for -Xcompile"
+ exit 1
+ ;;
+ target)
+ $echo "$modename: you must specify a target with \`-o'" 1>&2
+ exit 1
+ ;;
+ *)
+ # Get the name of the library object.
+ [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
+ ;;
+ esac
+
+ # Recognize several different file suffixes.
+ # If the user specifies -o file.o, it is replaced with file.lo
+ xform='[cCFSifmso]'
+ case $libobj in
+ *.ada) xform=ada ;;
+ *.adb) xform=adb ;;
+ *.ads) xform=ads ;;
+ *.asm) xform=asm ;;
+ *.c++) xform=c++ ;;
+ *.cc) xform=cc ;;
+ *.ii) xform=ii ;;
+ *.class) xform=class ;;
+ *.cpp) xform=cpp ;;
+ *.cxx) xform=cxx ;;
+ *.f90) xform=f90 ;;
+ *.for) xform=for ;;
+ *.java) xform=java ;;
+ esac
+
+ libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
+
+ case $libobj in
+ *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;;
+ *)
+ $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2
+ exit 1
+ ;;
+ esac
+
+ # Infer tagged configuration to use if any are available and
+ # if one wasn't chosen via the "--tag" command line option.
+ # Only attempt this if the compiler in the base compile
+ # command doesn't match the default compiler.
+ if test -n "$available_tags" && test -z "$tagname"; then
+ case $base_compile in
+ # Blanks in the command may have been stripped by the calling shell,
+ # but not from the CC environment variable when configure was run.
+ " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "*) ;;
+ # Blanks at the start of $base_compile will cause this to fail
+ # if we don't check for them as well.
+ *)
+ for z in $available_tags; do
+ if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$0" > /dev/null; then
+ # Evaluate the configuration.
+ eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $0`"
+ case "$base_compile " in
+ "$CC "* | " $CC "* | "`$echo $CC` "* | " `$echo $CC` "*)
+ # The compiler in the base compile command matches
+ # the one in the tagged configuration.
+ # Assume this is the tagged configuration we want.
+ tagname=$z
+ break
+ ;;
+ esac
+ fi
+ done
+ # If $tagname still isn't set, then no tagged configuration
+ # was found and let the user know that the "--tag" command
+ # line option must be used.
+ if test -z "$tagname"; then
+ $echo "$modename: unable to infer tagged configuration"
+ $echo "$modename: specify a tag with \`--tag'" 1>&2
+ exit 1
+# else
+# $echo "$modename: using $tagname tagged configuration"
+ fi
+ ;;
+ esac
+ fi
+
+ objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
+ xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$xdir" = "X$obj"; then
+ xdir=
+ else
+ xdir=$xdir/
+ fi
+ lobj=${xdir}$objdir/$objname
+
+ if test -z "$base_compile"; then
+ $echo "$modename: you must specify a compilation command" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Delete any leftover library objects.
+ if test "$build_old_libs" = yes; then
+ removelist="$obj $lobj $libobj ${libobj}T"
+ else
+ removelist="$lobj $libobj ${libobj}T"
+ fi
+
+ $run $rm $removelist
+ trap "$run $rm $removelist; exit 1" 1 2 15
+
+ # On Cygwin there's no "real" PIC flag so we must build both object types
+ case $host_os in
+ cygwin* | mingw* | pw32* | os2*)
+ pic_mode=default
+ ;;
+ esac
+ if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
+ # non-PIC code in shared libraries is not supported
+ pic_mode=default
+ fi
+
+ # Calculate the filename of the output object if compiler does
+ # not support -o with -c
+ if test "$compiler_c_o" = no; then
+ output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext}
+ lockfile="$output_obj.lock"
+ removelist="$removelist $output_obj $lockfile"
+ trap "$run $rm $removelist; exit 1" 1 2 15
+ else
+ output_obj=
+ need_locks=no
+ lockfile=
+ fi
+
+ # Lock this critical section if it is needed
+ # We use this script file to make the link, it avoids creating a new file
+ if test "$need_locks" = yes; then
+ until $run ln "$0" "$lockfile" 2>/dev/null; do
+ $show "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ elif test "$need_locks" = warn; then
+ if test -f "$lockfile"; then
+ $echo "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $run $rm $removelist
+ exit 1
+ fi
+ $echo $srcfile > "$lockfile"
+ fi
+
+ if test -n "$fix_srcfile_path"; then
+ eval srcfile=\"$fix_srcfile_path\"
+ fi
+
+ $run $rm "$libobj" "${libobj}T"
+
+ # Create a libtool object file (analogous to a ".la" file),
+ # but don't create it if we're doing a dry run.
+ test -z "$run" && cat > ${libobj}T <<EOF
+# $libobj - a libtool object file
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+EOF
+
+ # Only build a PIC object if we are building libtool libraries.
+ if test "$build_libtool_libs" = yes; then
+ # Without this assignment, base_compile gets emptied.
+ fbsd_hideous_sh_bug=$base_compile
+
+ if test "$pic_mode" != no; then
+ command="$base_compile $srcfile $pic_flag"
+ else
+ # Don't build PIC code
+ command="$base_compile $srcfile"
+ fi
+
+ if test ! -d "${xdir}$objdir"; then
+ $show "$mkdir ${xdir}$objdir"
+ $run $mkdir ${xdir}$objdir
+ status=$?
+ if test "$status" -ne 0 && test ! -d "${xdir}$objdir"; then
+ exit $status
+ fi
+ fi
+
+ if test -z "$output_obj"; then
+ # Place PIC objects in $objdir
+ command="$command -o $lobj"
+ fi
+
+ $run $rm "$lobj" "$output_obj"
+
+ $show "$command"
+ if $run eval "$command"; then :
+ else
+ test -n "$output_obj" && $run $rm $removelist
+ exit 1
+ fi
+
+ if test "$need_locks" = warn &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $run $rm $removelist
+ exit 1
+ fi
+
+ # Just move the object if needed, then go on to compile the next one
+ if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+ $show "$mv $output_obj $lobj"
+ if $run $mv $output_obj $lobj; then :
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+
+ # Append the name of the PIC object to the libtool object file.
+ test -z "$run" && cat >> ${libobj}T <<EOF
+pic_object='$objdir/$objname'
+
+EOF
+
+ # Allow error messages only from the first compilation.
+ suppress_output=' >/dev/null 2>&1'
+ else
+ # No PIC object so indicate it doesn't exist in the libtool
+ # object file.
+ test -z "$run" && cat >> ${libobj}T <<EOF
+pic_object=none
+
+EOF
+ fi
+
+ # Only build a position-dependent object if we build old libraries.
+ if test "$build_old_libs" = yes; then
+ if test "$pic_mode" != yes; then
+ # Don't build PIC code
+ command="$base_compile $srcfile"
+ else
+ command="$base_compile $srcfile $pic_flag"
+ fi
+ if test "$compiler_c_o" = yes; then
+ command="$command -o $obj"
+ fi
+
+ # Suppress compiler output if we already did a PIC compilation.
+ command="$command$suppress_output"
+ $run $rm "$obj" "$output_obj"
+ $show "$command"
+ if $run eval "$command"; then :
+ else
+ $run $rm $removelist
+ exit 1
+ fi
+
+ if test "$need_locks" = warn &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $run $rm $removelist
+ exit 1
+ fi
+
+ # Just move the object if needed
+ if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+ $show "$mv $output_obj $obj"
+ if $run $mv $output_obj $obj; then :
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+
+ # Append the name of the non-PIC object the libtool object file.
+ # Only append if the libtool object file exists.
+ test -z "$run" && cat >> ${libobj}T <<EOF
+# Name of the non-PIC object.
+non_pic_object='$objname'
+
+EOF
+ else
+ # Append the name of the non-PIC object the libtool object file.
+ # Only append if the libtool object file exists.
+ test -z "$run" && cat >> ${libobj}T <<EOF
+# Name of the non-PIC object.
+non_pic_object=none
+
+EOF
+ fi
+
+ $run $mv "${libobj}T" "${libobj}"
+
+ # Unlock the critical section if it was locked
+ if test "$need_locks" != no; then
+ $run $rm "$lockfile"
+ fi
+
+ exit 0
+ ;;
+
+ # libtool link mode
+ link | relink)
+ modename="$modename: link"
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+ # It is impossible to link a dll without this setting, and
+ # we shouldn't force the makefile maintainer to figure out
+ # which system we are compiling for in order to pass an extra
+ # flag for every libtool invocation.
+ # allow_undefined=no
+
+ # FIXME: Unfortunately, there are problems with the above when trying
+ # to make a dll which has undefined symbols, in which case not
+ # even a static library is built. For now, we need to specify
+ # -no-undefined on the libtool link line when we can be certain
+ # that all symbols are satisfied, otherwise we get a static library.
+ allow_undefined=yes
+ ;;
+ *)
+ allow_undefined=yes
+ ;;
+ esac
+ libtool_args="$nonopt"
+ base_compile="$nonopt"
+ compile_command="$nonopt"
+ finalize_command="$nonopt"
+
+ compile_rpath=
+ finalize_rpath=
+ compile_shlibpath=
+ finalize_shlibpath=
+ convenience=
+ old_convenience=
+ deplibs=
+ old_deplibs=
+ add_flags=
+ compiler_flags=
+ linker_flags=
+ dllsearchpath=
+ lib_search_path=`pwd`
+ inst_prefix_dir=
+
+ avoid_version=no
+ dlfiles=
+ dlprefiles=
+ dlself=no
+ export_dynamic=no
+ export_symbols=
+ export_symbols_regex=
+ generated=
+ libobjs=
+ ltlibs=
+ module=no
+ no_install=no
+ objs=
+ non_pic_objects=
+ prefer_static_libs=no
+ preload=no
+ prev=
+ prevarg=
+ release=
+ rpath=
+ xrpath=
+ perm_rpath=
+ temp_rpath=
+ thread_safe=no
+ vinfo=
+ vinfo_number=no
+
+ # We need to know -static, to get the right output filenames.
+ for arg
+ do
+ case $arg in
+ -all-static | -static)
+ if test "X$arg" = "X-all-static"; then
+ if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+ $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
+ fi
+ if test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ else
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ fi
+ build_libtool_libs=no
+ build_old_libs=yes
+ prefer_static_libs=yes
+ break
+ ;;
+ esac
+ done
+
+ # See if our shared archives depend on static archives.
+ test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+ # Go through the arguments, transforming them on the way.
+ while test "$#" -gt 0; do
+ arg="$1"
+ base_compile="$base_compile $arg"
+ shift
+ case $arg in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test
+ ;;
+ *) qarg=$arg ;;
+ esac
+ libtool_args="$libtool_args $qarg"
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case $prev in
+ output)
+ compile_command="$compile_command @OUTPUT@"
+ finalize_command="$finalize_command @OUTPUT@"
+ ;;
+ esac
+
+ case $prev in
+ dlfiles|dlprefiles)
+ if test "$preload" = no; then
+ # Add the symbol object into the linking commands.
+ compile_command="$compile_command @SYMFILE@"
+ finalize_command="$finalize_command @SYMFILE@"
+ preload=yes
+ fi
+ case $arg in
+ *.la | *.lo) ;; # We handle these cases below.
+ force)
+ if test "$dlself" = no; then
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ self)
+ if test "$prev" = dlprefiles; then
+ dlself=yes
+ elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+ dlself=yes
+ else
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ *)
+ if test "$prev" = dlfiles; then
+ dlfiles="$dlfiles $arg"
+ else
+ dlprefiles="$dlprefiles $arg"
+ fi
+ prev=
+ continue
+ ;;
+ esac
+ ;;
+ expsyms)
+ export_symbols="$arg"
+ if test ! -f "$arg"; then
+ $echo "$modename: symbol file \`$arg' does not exist"
+ exit 1
+ fi
+ prev=
+ continue
+ ;;
+ expsyms_regex)
+ export_symbols_regex="$arg"
+ prev=
+ continue
+ ;;
+ inst_prefix)
+ inst_prefix_dir="$arg"
+ prev=
+ continue
+ ;;
+ release)
+ release="-$arg"
+ prev=
+ continue
+ ;;
+ objectlist)
+ if test -f "$arg"; then
+ save_arg=$arg
+ moreargs=
+ for fil in `cat $save_arg`
+ do
+# moreargs="$moreargs $fil"
+ arg=$fil
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ # If there is no directory component, then add one.
+ case $arg in
+ */* | *\\*) . $arg ;;
+ *) . ./$arg ;;
+ esac
+
+ if test -z "$pic_object" || \
+ test -z "$non_pic_object" ||
+ test "$pic_object" = none && \
+ test "$non_pic_object" = none; then
+ $echo "$modename: cannot find name of object for \`$arg'" 1>&2
+ exit 1
+ fi
+
+ # Extract subdirectory from the argument.
+ xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$xdir" = "X$arg"; then
+ xdir=
+ else
+ xdir="$xdir/"
+ fi
+
+ if test "$pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ pic_object="$xdir$pic_object"
+
+ if test "$prev" = dlfiles; then
+ if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+ dlfiles="$dlfiles $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ dlprefiles="$dlprefiles $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ libobjs="$libobjs $pic_object"
+ arg="$pic_object"
+ fi
+
+ # Non-PIC object.
+ if test "$non_pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object="$xdir$non_pic_object"
+
+ # A standard non-PIC object
+ non_pic_objects="$non_pic_objects $non_pic_object"
+ if test -z "$pic_object" || test "$pic_object" = none ; then
+ arg="$non_pic_object"
+ fi
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if test -z "$run"; then
+ $echo "$modename: \`$arg' is not a valid libtool object" 1>&2
+ exit 1
+ else
+ # Dry-run case.
+
+ # Extract subdirectory from the argument.
+ xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$xdir" = "X$arg"; then
+ xdir=
+ else
+ xdir="$xdir/"
+ fi
+
+ pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"`
+ non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"`
+ libobjs="$libobjs $pic_object"
+ non_pic_objects="$non_pic_objects $non_pic_object"
+ fi
+ fi
+ done
+ else
+ $echo "$modename: link input file \`$save_arg' does not exist"
+ exit 1
+ fi
+ arg=$save_arg
+ prev=
+ continue
+ ;;
+ rpath | xrpath)
+ # We need an absolute path.
+ case $arg in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ $echo "$modename: only absolute run-paths are allowed" 1>&2
+ exit 1
+ ;;
+ esac
+ if test "$prev" = rpath; then
+ case "$rpath " in
+ *" $arg "*) ;;
+ *) rpath="$rpath $arg" ;;
+ esac
+ else
+ case "$xrpath " in
+ *" $arg "*) ;;
+ *) xrpath="$xrpath $arg" ;;
+ esac
+ fi
+ prev=
+ continue
+ ;;
+ xcompiler)
+ compiler_flags="$compiler_flags $qarg"
+ prev=
+ compile_command="$compile_command $qarg"
+ finalize_command="$finalize_command $qarg"
+ continue
+ ;;
+ xlinker)
+ linker_flags="$linker_flags $qarg"
+ compiler_flags="$compiler_flags $wl$qarg"
+ prev=
+ compile_command="$compile_command $wl$qarg"
+ finalize_command="$finalize_command $wl$qarg"
+ continue
+ ;;
+ xcclinker)
+ linker_flags="$linker_flags $qarg"
+ compiler_flags="$compiler_flags $qarg"
+ prev=
+ compile_command="$compile_command $qarg"
+ finalize_command="$finalize_command $qarg"
+ continue
+ ;;
+ *)
+ eval "$prev=\"\$arg\""
+ prev=
+ continue
+ ;;
+ esac
+ fi # test -n "$prev"
+
+ prevarg="$arg"
+
+ case $arg in
+ -all-static)
+ if test -n "$link_static_flag"; then
+ compile_command="$compile_command $link_static_flag"
+ finalize_command="$finalize_command $link_static_flag"
+ fi
+ continue
+ ;;
+
+ -allow-undefined)
+ # FIXME: remove this flag sometime in the future.
+ $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2
+ continue
+ ;;
+
+ -avoid-version)
+ avoid_version=yes
+ continue
+ ;;
+
+ -dlopen)
+ prev=dlfiles
+ continue
+ ;;
+
+ -dlpreopen)
+ prev=dlprefiles
+ continue
+ ;;
+
+ -export-dynamic)
+ export_dynamic=yes
+ continue
+ ;;
+
+ -export-symbols | -export-symbols-regex)
+ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+ $echo "$modename: more than one -exported-symbols argument is not allowed"
+ exit 1
+ fi
+ if test "X$arg" = "X-export-symbols"; then
+ prev=expsyms
+ else
+ prev=expsyms_regex
+ fi
+ continue
+ ;;
+
+ -inst-prefix-dir)
+ prev=inst_prefix
+ continue
+ ;;
+
+ # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+ # so, if we see these flags be careful not to treat them like -L
+ -L[A-Z][A-Z]*:*)
+ case $with_gcc/$host in
+ no/*-*-irix* | /*-*-irix*)
+ compile_command="$compile_command $arg"
+ finalize_command="$finalize_command $arg"
+ ;;
+ esac
+ continue
+ ;;
+
+ -L*)
+ dir=`$echo "X$arg" | $Xsed -e 's/^-L//'`
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2
+ exit 1
+ fi
+ dir="$absdir"
+ ;;
+ esac
+ case "$deplibs " in
+ *" -L$dir "*) ;;
+ *)
+ deplibs="$deplibs -L$dir"
+ lib_search_path="$lib_search_path $dir"
+ ;;
+ esac
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+ case :$dllsearchpath: in
+ *":$dir:"*) ;;
+ *) dllsearchpath="$dllsearchpath:$dir";;
+ esac
+ ;;
+ esac
+ continue
+ ;;
+
+ -l*)
+ if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
+ case $host in
+ *-*-cygwin* | *-*-pw32* | *-*-beos*)
+ # These systems don't actually have a C or math library (as such)
+ continue
+ ;;
+ *-*-freebsd*-gnu*)
+ # prevent being parsed by the freebsd regexp below
+ ;;
+ *-*-mingw* | *-*-os2*)
+ # These systems don't actually have a C library (as such)
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-openbsd* | *-*-freebsd*)
+ # Do not include libc due to us having libc/libc_r.
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C and math libraries are in the System framework
+ deplibs="$deplibs -framework System"
+ continue
+ esac
+ elif test "X$arg" = "X-lc_r"; then
+ case $host in
+ *-*-freebsd*-gnu*)
+ # prevent being parsed by the freebsd regexp below
+ ;;
+ *-*-openbsd*)
+ # Do not include libc_r directly, use -pthread flag.
+ continue
+ ;;
+ esac
+ fi
+ deplibs="$deplibs $arg"
+ continue
+ ;;
+
+ -module)
+ module=yes
+ continue
+ ;;
+
+ # gcc -m* arguments should be passed to the linker via $compiler_flags
+ # in order to pass architecture information to the linker
+ # (e.g. 32 vs 64-bit). This may also be accomplished via -Wl,-mfoo
+ # but this is not reliable with gcc because gcc may use -mfoo to
+ # select a different linker, different libraries, etc, while
+ # -Wl,-mfoo simply passes -mfoo to the linker.
+ -m*)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case $arg in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ arg="\"$arg\""
+ ;;
+ esac
+ compile_command="$compile_command $arg"
+ finalize_command="$finalize_command $arg"
+ if test "$with_gcc" = "yes" ; then
+ compiler_flags="$compiler_flags $arg"
+ fi
+ continue
+ ;;
+
+ -shrext)
+ prev=shrext
+ continue
+ ;;
+
+ -no-fast-install)
+ fast_install=no
+ continue
+ ;;
+
+ -no-install)
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+ # The PATH hackery in wrapper scripts is required on Windows
+ # in order for the loader to find any dlls it needs.
+ $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2
+ $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2
+ fast_install=no
+ ;;
+ *) no_install=yes ;;
+ esac
+ continue
+ ;;
+
+ -no-undefined)
+ allow_undefined=no
+ continue
+ ;;
+
+ -objectlist)
+ prev=objectlist
+ continue
+ ;;
+
+ -o) prev=output ;;
+
+ -release)
+ prev=release
+ continue
+ ;;
+
+ -rpath)
+ prev=rpath
+ continue
+ ;;
+
+ -R)
+ prev=xrpath
+ continue
+ ;;
+
+ -R*)
+ dir=`$echo "X$arg" | $Xsed -e 's/^-R//'`
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ $echo "$modename: only absolute run-paths are allowed" 1>&2
+ exit 1
+ ;;
+ esac
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) xrpath="$xrpath $dir" ;;
+ esac
+ continue
+ ;;
+
+ -static)
+ # The effects of -static are defined in a previous loop.
+ # We used to do the same as -all-static on platforms that
+ # didn't have a PIC flag, but the assumption that the effects
+ # would be equivalent was wrong. It would break on at least
+ # Digital Unix and AIX.
+ continue
+ ;;
+
+ -thread-safe)
+ thread_safe=yes
+ continue
+ ;;
+
+ -version-info)
+ prev=vinfo
+ continue
+ ;;
+ -version-number)
+ prev=vinfo
+ vinfo_number=yes
+ continue
+ ;;
+
+ -Wc,*)
+ args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'`
+ arg=
+ save_ifs="$IFS"; IFS=','
+ for flag in $args; do
+ IFS="$save_ifs"
+ case $flag in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ flag="\"$flag\""
+ ;;
+ esac
+ arg="$arg $wl$flag"
+ compiler_flags="$compiler_flags $flag"
+ done
+ IFS="$save_ifs"
+ arg=`$echo "X$arg" | $Xsed -e "s/^ //"`
+ ;;
+
+ -Wl,*)
+ args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'`
+ arg=
+ save_ifs="$IFS"; IFS=','
+ for flag in $args; do
+ IFS="$save_ifs"
+ case $flag in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ flag="\"$flag\""
+ ;;
+ esac
+ arg="$arg $wl$flag"
+ compiler_flags="$compiler_flags $wl$flag"
+ linker_flags="$linker_flags $flag"
+ done
+ IFS="$save_ifs"
+ arg=`$echo "X$arg" | $Xsed -e "s/^ //"`
+ ;;
+
+ -Xcompiler)
+ prev=xcompiler
+ continue
+ ;;
+
+ -Xlinker)
+ prev=xlinker
+ continue
+ ;;
+
+ -XCClinker)
+ prev=xcclinker
+ continue
+ ;;
+
+ # Some other compiler flag.
+ -* | +*)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case $arg in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ arg="\"$arg\""
+ ;;
+ esac
+ add_flags="$add_flags $arg"
+ ;;
+
+ *.$objext)
+ # A standard object.
+ objs="$objs $arg"
+ ;;
+
+ *.lo)
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ # If there is no directory component, then add one.
+ case $arg in
+ */* | *\\*) . $arg ;;
+ *) . ./$arg ;;
+ esac
+
+ if test -z "$pic_object" || \
+ test -z "$non_pic_object" ||
+ test "$pic_object" = none && \
+ test "$non_pic_object" = none; then
+ $echo "$modename: cannot find name of object for \`$arg'" 1>&2
+ exit 1
+ fi
+
+ # Extract subdirectory from the argument.
+ xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$xdir" = "X$arg"; then
+ xdir=
+ else
+ xdir="$xdir/"
+ fi
+
+ if test "$pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ pic_object="$xdir$pic_object"
+
+ if test "$prev" = dlfiles; then
+ if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+ dlfiles="$dlfiles $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ dlprefiles="$dlprefiles $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ libobjs="$libobjs $pic_object"
+ arg="$pic_object"
+ fi
+
+ # Non-PIC object.
+ if test "$non_pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object="$xdir$non_pic_object"
+
+ # A standard non-PIC object
+ non_pic_objects="$non_pic_objects $non_pic_object"
+ if test -z "$pic_object" || test "$pic_object" = none ; then
+ arg="$non_pic_object"
+ fi
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if test -z "$run"; then
+ $echo "$modename: \`$arg' is not a valid libtool object" 1>&2
+ exit 1
+ else
+ # Dry-run case.
+
+ # Extract subdirectory from the argument.
+ xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$xdir" = "X$arg"; then
+ xdir=
+ else
+ xdir="$xdir/"
+ fi
+
+ pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"`
+ non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"`
+ libobjs="$libobjs $pic_object"
+ non_pic_objects="$non_pic_objects $non_pic_object"
+ fi
+ fi
+ ;;
+
+ *.$libext)
+ # An archive.
+ deplibs="$deplibs $arg"
+ old_deplibs="$old_deplibs $arg"
+ continue
+ ;;
+
+ *.la)
+ # A libtool-controlled library.
+
+ if test "$prev" = dlfiles; then
+ # This library was specified with -dlopen.
+ dlfiles="$dlfiles $arg"
+ prev=
+ elif test "$prev" = dlprefiles; then
+ # The library was specified with -dlpreopen.
+ dlprefiles="$dlprefiles $arg"
+ prev=
+ else
+ deplibs="$deplibs $arg"
+ fi
+ continue
+ ;;
+
+ # Some other compiler argument.
+ *)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case $arg in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ arg="\"$arg\""
+ ;;
+ esac
+ add_flags="$add_flags $arg"
+ ;;
+ esac # arg
+
+ # Now actually substitute the argument into the commands.
+ if test -n "$arg"; then
+ compile_command="$compile_command $arg"
+ finalize_command="$finalize_command $arg"
+ fi
+ done # argument parsing loop
+
+ if test -n "$prev"; then
+ $echo "$modename: the \`$prevarg' option requires an argument" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Infer tagged configuration to use if any are available and
+ # if one wasn't chosen via the "--tag" command line option.
+ # Only attempt this if the compiler in the base link
+ # command doesn't match the default compiler.
+ if test -n "$available_tags" && test -z "$tagname"; then
+ case $base_compile in
+ # Blanks in the command may have been stripped by the calling shell,
+ # but not from the CC environment variable when configure was run.
+ "$CC "* | " $CC "* | "`$echo $CC` "* | " `$echo $CC` "*) ;;
+ # Blanks at the start of $base_compile will cause this to fail
+ # if we don't check for them as well.
+ *)
+ for z in $available_tags; do
+ if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$0" > /dev/null; then
+ # Evaluate the configuration.
+ eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $0`"
+ case $base_compile in
+ "$CC "* | " $CC "* | "`$echo $CC` "* | " `$echo $CC` "*)
+ # The compiler in $compile_command matches
+ # the one in the tagged configuration.
+ # Assume this is the tagged configuration we want.
+ tagname=$z
+ break
+ ;;
+ esac
+ fi
+ done
+ # If $tagname still isn't set, then no tagged configuration
+ # was found and let the user know that the "--tag" command
+ # line option must be used.
+ if test -z "$tagname"; then
+ $echo "$modename: unable to infer tagged configuration"
+ $echo "$modename: specify a tag with \`--tag'" 1>&2
+ exit 1
+# else
+# $echo "$modename: using $tagname tagged configuration"
+ fi
+ ;;
+ esac
+ fi
+
+ if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+ eval arg=\"$export_dynamic_flag_spec\"
+ compile_command="$compile_command $arg"
+ finalize_command="$finalize_command $arg"
+ fi
+
+ oldlibs=
+ # calculate the name of the file, without its directory
+ outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'`
+ libobjs_save="$libobjs"
+
+ if test -n "$shlibpath_var"; then
+ # get the directories listed in $shlibpath_var
+ eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
+ else
+ shlib_search_path=
+ fi
+ eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+ eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+ output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$output_objdir" = "X$output"; then
+ output_objdir="$objdir"
+ else
+ output_objdir="$output_objdir/$objdir"
+ fi
+ # Create the object directory.
+ if test ! -d "$output_objdir"; then
+ $show "$mkdir $output_objdir"
+ $run $mkdir $output_objdir
+ status=$?
+ if test "$status" -ne 0 && test ! -d "$output_objdir"; then
+ exit $status
+ fi
+ fi
+
+ # Determine the type of output
+ case $output in
+ "")
+ $echo "$modename: you must specify an output file" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+ *.$libext) linkmode=oldlib ;;
+ *.lo | *.$objext) linkmode=obj ;;
+ *.la) linkmode=lib ;;
+ *) linkmode=prog ;; # Anything else should be a program.
+ esac
+
+ case $host in
+ *cygwin* | *mingw* | *pw32*)
+ # don't eliminate duplcations in $postdeps and $predeps
+ duplicate_compiler_generated_deps=yes
+ ;;
+ *)
+ duplicate_compiler_generated_deps=$duplicate_deps
+ ;;
+ esac
+ specialdeplibs=
+
+ libs=
+ # Find all interdependent deplibs by searching for libraries
+ # that are linked more than once (e.g. -la -lb -la)
+ for deplib in $deplibs; do
+ if test "X$duplicate_deps" = "Xyes" ; then
+ case "$libs " in
+ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ esac
+ fi
+ libs="$libs $deplib"
+ done
+
+ if test "$linkmode" = lib; then
+ libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+ # Compute libraries that are listed more than once in $predeps
+ # $postdeps and mark them as special (i.e., whose duplicates are
+ # not to be eliminated).
+ pre_post_deps=
+ if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then
+ for pre_post_dep in $predeps $postdeps; do
+ case "$pre_post_deps " in
+ *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;;
+ esac
+ pre_post_deps="$pre_post_deps $pre_post_dep"
+ done
+ fi
+ pre_post_deps=
+ fi
+
+ deplibs=
+ newdependency_libs=
+ newlib_search_path=
+ need_relink=no # whether we're linking any uninstalled libtool libraries
+ notinst_deplibs= # not-installed libtool libraries
+ notinst_path= # paths that contain not-installed libtool libraries
+ case $linkmode in
+ lib)
+ passes="conv link"
+ for file in $dlfiles $dlprefiles; do
+ case $file in
+ *.la) ;;
+ *)
+ $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+ ;;
+ prog)
+ compile_deplibs=
+ finalize_deplibs=
+ alldeplibs=no
+ newdlfiles=
+ newdlprefiles=
+ passes="conv scan dlopen dlpreopen link"
+ ;;
+ *) passes="conv"
+ ;;
+ esac
+ for pass in $passes; do
+ if test "$linkmode,$pass" = "lib,link" ||
+ test "$linkmode,$pass" = "prog,scan"; then
+ libs="$deplibs"
+ deplibs=
+ fi
+ if test "$linkmode" = prog; then
+ case $pass in
+ dlopen) libs="$dlfiles" ;;
+ dlpreopen) libs="$dlprefiles" ;;
+ link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
+ esac
+ fi
+ if test "$pass" = dlopen; then
+ # Collect dlpreopened libraries
+ save_deplibs="$deplibs"
+ deplibs=
+ fi
+ for deplib in $libs; do
+ lib=
+ found=no
+ case $deplib in
+ -l*)
+ if test "$linkmode" != lib && test "$linkmode" != prog; then
+ $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2
+ continue
+ fi
+ if test "$pass" = conv && test "$allow_undefined" = yes; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ name=`$echo "X$deplib" | $Xsed -e 's/^-l//'`
+ for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ for search_ext in .la $shrext .so .a; do
+ # Search the libtool library
+ lib="$searchdir/lib${name}${search_ext}"
+ if test -f "$lib"; then
+ if test "$search_ext" = ".la"; then
+ found=yes
+ else
+ found=no
+ fi
+ break 2
+ fi
+ done
+ done
+ if test "$found" != yes; then
+ # deplib doesn't seem to be a libtool library
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ else # deplib is a libtool library
+ # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+ # We need to do some special things here, and not later.
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $deplib "*)
+ if (${SED} -e '2q' $lib |
+ grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ library_names=
+ old_library=
+ case $lib in
+ */* | *\\*) . $lib ;;
+ *) . ./$lib ;;
+ esac
+ for l in $old_library $library_names; do
+ ll="$l"
+ done
+ if test "X$ll" = "X$old_library" ; then # only static version available
+ found=no
+ ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$ladir" = "X$lib" && ladir="."
+ lib=$ladir/$old_library
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ fi
+ fi
+ ;;
+ *) ;;
+ esac
+ fi
+ fi
+ ;; # -l
+ -L*)
+ case $linkmode in
+ lib)
+ deplibs="$deplib $deplibs"
+ test "$pass" = conv && continue
+ newdependency_libs="$deplib $newdependency_libs"
+ newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
+ ;;
+ prog)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ if test "$pass" = scan; then
+ deplibs="$deplib $deplibs"
+ newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ ;;
+ *)
+ $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2
+ ;;
+ esac # linkmode
+ continue
+ ;; # -L
+ -R*)
+ if test "$pass" = link; then
+ dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'`
+ # Make sure the xrpath contains only unique directories.
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) xrpath="$xrpath $dir" ;;
+ esac
+ fi
+ deplibs="$deplib $deplibs"
+ continue
+ ;;
+ *.la) lib="$deplib" ;;
+ *.$libext)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ case $linkmode in
+ lib)
+ if test "$deplibs_check_method" != pass_all; then
+ $echo
+ $echo "*** Warning: Trying to link with static lib archive $deplib."
+ $echo "*** I have the capability to make that library automatically link in when"
+ $echo "*** you link to this library. But I can only do this if you have a"
+ $echo "*** shared version of the library, which you do not appear to have"
+ $echo "*** because the file extensions .$libext of this argument makes me believe"
+ $echo "*** that it is just a static archive that I should not used here."
+ else
+ $echo
+ $echo "*** Warning: Linking the shared library $output against the"
+ $echo "*** static library $deplib is not portable!"
+ deplibs="$deplib $deplibs"
+ fi
+ continue
+ ;;
+ prog)
+ if test "$pass" != link; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ continue
+ ;;
+ esac # linkmode
+ ;; # *.$libext
+ *.lo | *.$objext)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ elif test "$linkmode" = prog; then
+ if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+ # If there is no dlopen support or we're linking statically,
+ # we need to preload.
+ newdlprefiles="$newdlprefiles $deplib"
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ newdlfiles="$newdlfiles $deplib"
+ fi
+ fi
+ continue
+ ;;
+ %DEPLIBS%)
+ alldeplibs=yes
+ continue
+ ;;
+ esac # case $deplib
+ if test "$found" = yes || test -f "$lib"; then :
+ else
+ $echo "$modename: cannot find the library \`$lib'" 1>&2
+ exit 1
+ fi
+
+ # Check to see that this really is a libtool archive.
+ if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+ else
+ $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+ exit 1
+ fi
+
+ ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$ladir" = "X$lib" && ladir="."
+
+ dlname=
+ dlopen=
+ dlpreopen=
+ libdir=
+ library_names=
+ old_library=
+ # If the library was installed with an old release of libtool,
+ # it will not redefine variables installed, or shouldnotlink
+ installed=yes
+ shouldnotlink=no
+
+ # Read the .la file
+ case $lib in
+ */* | *\\*) . $lib ;;
+ *) . ./$lib ;;
+ esac
+
+ if test "$linkmode,$pass" = "lib,link" ||
+ test "$linkmode,$pass" = "prog,scan" ||
+ { test "$linkmode" != prog && test "$linkmode" != lib; }; then
+ test -n "$dlopen" && dlfiles="$dlfiles $dlopen"
+ test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen"
+ fi
+
+ if test "$pass" = conv; then
+ # Only check for convenience libraries
+ deplibs="$lib $deplibs"
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ #echo "Adding $deplib to \$deplibs"
+ deplibs="$deplib $deplibs"
+ if test "X$duplicate_deps" = "Xyes" ; then
+ case "$tmp_libs " in
+ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ esac
+ fi
+ tmp_libs="$tmp_libs $deplib"
+ done
+ if test -z "$libdir"; then
+ if test -z "$old_library"; then
+ $echo "$modename: cannot find name of link library for \`$lib'" 1>&2
+ exit 1
+ fi
+ # It is a libtool convenience library, so add in its objects.
+ convenience="$convenience $ladir/$objdir/$old_library"
+ old_convenience="$old_convenience $ladir/$objdir/$old_library"
+ elif test "$linkmode" != prog && test "$linkmode" != lib; then
+ $echo "$modename: \`$lib' is not a convenience library" 1>&2
+ exit 1
+ fi
+ continue
+ fi # $pass = conv
+
+
+ # Get the name of the library we link against.
+ linklib=
+ for l in $old_library $library_names; do
+ linklib="$l"
+ done
+ if test -z "$linklib"; then
+ $echo "$modename: cannot find name of link library for \`$lib'" 1>&2
+ exit 1
+ fi
+
+ # This library was specified with -dlopen.
+ if test "$pass" = dlopen; then
+ if test -z "$libdir"; then
+ $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2
+ exit 1
+ fi
+ if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+ # If there is no dlname, no dlopen support or we're linking
+ # statically, we need to preload. We also need to preload any
+ # dependent libraries so libltdl's deplib preloader doesn't
+ # bomb out in the load deplibs phase.
+ dlprefiles="$dlprefiles $lib $dependency_libs"
+ else
+ newdlfiles="$newdlfiles $lib"
+ fi
+ continue
+ fi # $pass = dlopen
+
+ # We need an absolute path.
+ case $ladir in
+ [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
+ *)
+ abs_ladir=`cd "$ladir" && pwd`
+ if test -z "$abs_ladir"; then
+ $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2
+ $echo "$modename: passing it literally to the linker, although it might fail" 1>&2
+ abs_ladir="$ladir"
+ fi
+ ;;
+ esac
+ laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+
+ # Find the relevant object directory and library name.
+ if test "X$installed" = Xyes; then
+ if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ $echo "$modename: warning: library \`$lib' was moved." 1>&2
+ dir="$ladir"
+ absdir="$abs_ladir"
+ libdir="$abs_ladir"
+ else
+ dir="$libdir"
+ absdir="$libdir"
+ fi
+ else
+ dir="$ladir/$objdir"
+ absdir="$abs_ladir/$objdir"
+ # Remove this search path later
+ notinst_path="$notinst_path $abs_ladir"
+ fi # $installed = yes
+ name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+
+ # This library was specified with -dlpreopen.
+ if test "$pass" = dlpreopen; then
+ if test -z "$libdir"; then
+ $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2
+ exit 1
+ fi
+ # Prefer using a static library (so that no silly _DYNAMIC symbols
+ # are required to link).
+ if test -n "$old_library"; then
+ newdlprefiles="$newdlprefiles $dir/$old_library"
+ # Otherwise, use the dlname, so that lt_dlopen finds it.
+ elif test -n "$dlname"; then
+ newdlprefiles="$newdlprefiles $dir/$dlname"
+ else
+ newdlprefiles="$newdlprefiles $dir/$linklib"
+ fi
+ fi # $pass = dlpreopen
+
+ if test -z "$libdir"; then
+ # Link the convenience library
+ if test "$linkmode" = lib; then
+ deplibs="$dir/$old_library $deplibs"
+ elif test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$dir/$old_library $compile_deplibs"
+ finalize_deplibs="$dir/$old_library $finalize_deplibs"
+ else
+ deplibs="$lib $deplibs" # used for prog,scan pass
+ fi
+ continue
+ fi
+
+
+ if test "$linkmode" = prog && test "$pass" != link; then
+ newlib_search_path="$newlib_search_path $ladir"
+ deplibs="$lib $deplibs"
+
+ linkalldeplibs=no
+ if test "$link_all_deplibs" != no || test -z "$library_names" ||
+ test "$build_libtool_libs" = no; then
+ linkalldeplibs=yes
+ fi
+
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test
+ esac
+ # Need to link against all dependency_libs?
+ if test "$linkalldeplibs" = yes; then
+ deplibs="$deplib $deplibs"
+ else
+ # Need to hardcode shared library paths
+ # or/and link against static libraries
+ newdependency_libs="$deplib $newdependency_libs"
+ fi
+ if test "X$duplicate_deps" = "Xyes" ; then
+ case "$tmp_libs " in
+ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ esac
+ fi
+ tmp_libs="$tmp_libs $deplib"
+ done # for deplib
+ continue
+ fi # $linkmode = prog...
+
+ if test "$linkmode,$pass" = "prog,link"; then
+ if test -n "$library_names" &&
+ { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
+ # We need to hardcode the library path
+ if test -n "$shlibpath_var"; then
+ # Make sure the rpath contains only unique directories.
+ case "$temp_rpath " in
+ *" $dir "*) ;;
+ *" $absdir "*) ;;
+ *) temp_rpath="$temp_rpath $dir" ;;
+ esac
+ fi
+
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) compile_rpath="$compile_rpath $absdir"
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir"
+ esac
+ ;;
+ esac
+ fi # $linkmode,$pass = prog,link...
+
+ if test "$alldeplibs" = yes &&
+ { test "$deplibs_check_method" = pass_all ||
+ { test "$build_libtool_libs" = yes &&
+ test -n "$library_names"; }; }; then
+ # We only need to search for static libraries
+ continue
+ fi
+ fi
+
+ link_static=no # Whether the deplib will be linked statically
+ if test -n "$library_names" &&
+ { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
+ if test "$installed" = no; then
+ notinst_deplibs="$notinst_deplibs $lib"
+ need_relink=yes
+ fi
+ # This is a shared library
+
+ # Warn about portability, can't link against -module's on some systems (darwin)
+ if test "$shouldnotlink" = yes && test "$pass" = link ; then
+ $echo
+ if test "$linkmode" = prog; then
+ $echo "*** Warning: Linking the executable $output against the loadable module"
+ else
+ $echo "*** Warning: Linking the shared library $output against the loadable module"
+ fi
+ $echo "*** $linklib is not portable!"
+ fi
+ if test "$linkmode" = lib &&
+ test "$hardcode_into_libs" = yes; then
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) compile_rpath="$compile_rpath $absdir"
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir"
+ esac
+ ;;
+ esac
+ fi
+
+ if test -n "$old_archive_from_expsyms_cmds"; then
+ # figure out the soname
+ set dummy $library_names
+ realname="$2"
+ shift; shift
+ libname=`eval \\$echo \"$libname_spec\"`
+ # use dlname if we got it. it's perfectly good, no?
+ if test -n "$dlname"; then
+ soname="$dlname"
+ elif test -n "$soname_spec"; then
+ # bleh windows
+ case $host in
+ *cygwin* | mingw*)
+ major=`expr $current - $age`
+ versuffix="-$major"
+ ;;
+ esac
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+
+ # Make a new name for the extract_expsyms_cmds to use
+ soroot="$soname"
+ soname=`$echo $soroot | ${SED} -e 's/^.*\///'`
+ newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a"
+
+ # If the library has no export list, then create one now
+ if test -f "$output_objdir/$soname-def"; then :
+ else
+ $show "extracting exported symbol list from \`$soname'"
+ save_ifs="$IFS"; IFS='~'
+ eval cmds=\"$extract_expsyms_cmds\"
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ fi
+
+ # Create $newlib
+ if test -f "$output_objdir/$newlib"; then :; else
+ $show "generating import library for \`$soname'"
+ save_ifs="$IFS"; IFS='~'
+ eval cmds=\"$old_archive_from_expsyms_cmds\"
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ fi
+ # make sure the library variables are pointing to the new library
+ dir=$output_objdir
+ linklib=$newlib
+ fi # test -n "$old_archive_from_expsyms_cmds"
+
+ if test "$linkmode" = prog || test "$mode" != relink; then
+ add_shlibpath=
+ add_dir=
+ add=
+ lib_linked=yes
+ case $hardcode_action in
+ immediate | unsupported)
+ if test "$hardcode_direct" = no; then
+ add="$dir/$linklib"
+ case $host in
+ *-*-sco3.2v5* ) add_dir="-L$dir" ;;
+ *-*-darwin* )
+ # if the lib is a module then we can not link against it, someone
+ # is ignoring the new warnings I added
+ if /usr/bin/file -L $add 2> /dev/null | grep "bundle" >/dev/null ; then
+ $echo "** Warning, lib $linklib is a module, not a shared library"
+ if test -z "$old_library" ; then
+ $echo
+ $echo "** And there doesn't seem to be a static archive available"
+ $echo "** The link will probably fail, sorry"
+ else
+ add="$dir/$old_library"
+ fi
+ fi
+ esac
+ elif test "$hardcode_minus_L" = no; then
+ case $host in
+ *-*-sunos*) add_shlibpath="$dir" ;;
+ esac
+ add_dir="-L$dir"
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = no; then
+ add_shlibpath="$dir"
+ add="-l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+ relink)
+ if test "$hardcode_direct" = yes; then
+ add="$dir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ add_dir="-L$dir"
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case "$libdir" in
+ [\\/]*)
+ add_dir="-L$inst_prefix_dir$libdir $add_dir"
+ ;;
+ esac
+ fi
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ add_shlibpath="$dir"
+ add="-l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+ *) lib_linked=no ;;
+ esac
+
+ if test "$lib_linked" != yes; then
+ $echo "$modename: configuration error: unsupported hardcode properties"
+ exit 1
+ fi
+
+ if test -n "$add_shlibpath"; then
+ case :$compile_shlibpath: in
+ *":$add_shlibpath:"*) ;;
+ *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;;
+ esac
+ fi
+ if test "$linkmode" = prog; then
+ test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+ test -n "$add" && compile_deplibs="$add $compile_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ if test "$hardcode_direct" != yes && \
+ test "$hardcode_minus_L" != yes && \
+ test "$hardcode_shlibpath_var" = yes; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+ esac
+ fi
+ fi
+ fi
+
+ if test "$linkmode" = prog || test "$mode" = relink; then
+ add_shlibpath=
+ add_dir=
+ add=
+ # Finalize command for both is simple: just hardcode it.
+ if test "$hardcode_direct" = yes; then
+ add="$libdir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ add_dir="-L$libdir"
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+ esac
+ add="-l$name"
+ elif test "$hardcode_automatic" = yes; then
+ if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib" ; then
+ add="$inst_prefix_dir$libdir/$linklib"
+ else
+ add="$libdir/$linklib"
+ fi
+ else
+ # We cannot seem to hardcode it, guess we'll fake it.
+ add_dir="-L$libdir"
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case "$libdir" in
+ [\\/]*)
+ add_dir="-L$inst_prefix_dir$libdir $add_dir"
+ ;;
+ esac
+ fi
+ add="-l$name"
+ fi
+
+ if test "$linkmode" = prog; then
+ test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+ test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ fi
+ fi
+ elif test "$linkmode" = prog; then
+ # Here we assume that one of hardcode_direct or hardcode_minus_L
+ # is not unsupported. This is valid on all known static and
+ # shared platforms.
+ if test "$hardcode_direct" != unsupported; then
+ test -n "$old_library" && linklib="$old_library"
+ compile_deplibs="$dir/$linklib $compile_deplibs"
+ finalize_deplibs="$dir/$linklib $finalize_deplibs"
+ else
+ compile_deplibs="-l$name -L$dir $compile_deplibs"
+ finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+ fi
+ elif test "$build_libtool_libs" = yes; then
+ # Not a shared library
+ if test "$deplibs_check_method" != pass_all; then
+ # We're trying link a shared library against a static one
+ # but the system doesn't support it.
+
+ # Just print a warning and add the library to dependency_libs so
+ # that the program can be linked against the static library.
+ $echo
+ $echo "*** Warning: This system can not link to static lib archive $lib."
+ $echo "*** I have the capability to make that library automatically link in when"
+ $echo "*** you link to this library. But I can only do this if you have a"
+ $echo "*** shared version of the library, which you do not appear to have."
+ if test "$module" = yes; then
+ $echo "*** But as you try to build a module library, libtool will still create "
+ $echo "*** a static module, that should work as long as the dlopening application"
+ $echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
+ if test -z "$global_symbol_pipe"; then
+ $echo
+ $echo "*** However, this would only work if libtool was able to extract symbol"
+ $echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ $echo "*** not find such a program. So, this module is probably useless."
+ $echo "*** \`nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test "$build_old_libs" = no; then
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ else
+ convenience="$convenience $dir/$old_library"
+ old_convenience="$old_convenience $dir/$old_library"
+ deplibs="$dir/$old_library $deplibs"
+ link_static=yes
+ fi
+ fi # link shared/static library?
+
+ if test "$linkmode" = lib; then
+ #if test -n "$dependency_libs" &&
+ # { test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes ||
+ # test "$link_static" = yes; }; then
+ # Extract -R from dependency_libs
+ temp_deplibs=
+ for libdir in $dependency_libs; do
+ case $libdir in
+ -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'`
+ case " $xrpath " in
+ *" $temp_xrpath "*) ;;
+ *) xrpath="$xrpath $temp_xrpath";;
+ esac;;
+ *) temp_deplibs="$temp_deplibs $libdir";;
+ esac
+ done
+ dependency_libs="$temp_deplibs"
+ #fi
+
+ newlib_search_path="$newlib_search_path $absdir"
+ # Link against this library
+ test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+ # ... and its dependency_libs
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ newdependency_libs="$deplib $newdependency_libs"
+ if test "X$duplicate_deps" = "Xyes" ; then
+ case "$tmp_libs " in
+ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ esac
+ fi
+ tmp_libs="$tmp_libs $deplib"
+ done
+
+ if test "$link_all_deplibs" != no; then
+ # Add the search paths of all dependency libraries
+ for deplib in $dependency_libs; do
+ case $deplib in
+ -L*) path="$deplib" ;;
+ *.la)
+ dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$dir" = "X$deplib" && dir="."
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
+ absdir="$dir"
+ fi
+ ;;
+ esac
+ if grep "^installed=no" $deplib > /dev/null; then
+ path="$absdir/$objdir"
+ else
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+ if test -z "$libdir"; then
+ $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
+ exit 1
+ fi
+ if test "$absdir" != "$libdir"; then
+ # Sure, some shells/systems don't implement the -ef.
+ # Those will have to live with the warning.
+ test "$absdir" -ef "$libdir" > /dev/null 2>&1 ||
+ $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2
+ fi
+ path="$absdir"
+ fi
+ depdepl=
+ case $host in
+ *-*-darwin*)
+ # we do not want to link against static libs, but need to link against shared
+ eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+ if test -n "$deplibrary_names" ; then
+ for tmp in $deplibrary_names ; do
+ depdepl=$tmp
+ done
+ if test -f "$path/$depdepl" ; then
+ depdepl="$path/$depdepl"
+ fi
+ # do not add paths which are already there
+ case " $newlib_search_path " in
+ *" $path "*) ;;
+ *) newlib_search_path="$newlib_search_path $path";;
+ esac
+ path=""
+ fi
+ ;;
+ *)
+ path="-L$path"
+ ;;
+ esac
+
+ ;;
+ -l*)
+ case $host in
+ *-*-darwin*)
+ # Again, we only want to link against shared libraries
+ eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"`
+ for tmp in $newlib_search_path ; do
+ if test -f "$tmp/lib$tmp_libs.dylib" ; then
+ eval depdepl="$tmp/lib$tmp_libs.dylib"
+ break
+ fi
+ done
+ path=""
+ ;;
+ *) continue ;;
+ esac
+ ;;
+ *) continue ;;
+ esac
+ case " $deplibs " in
+ *" $depdepl "*) ;;
+ *) deplibs="$deplibs $depdepl" ;;
+ esac
+ case " $deplibs " in
+ *" $path "*) ;;
+ *) deplibs="$deplibs $path" ;;
+ esac
+ done
+ fi # link_all_deplibs != no
+ fi # linkmode = lib
+ done # for deplib in $libs
+ dependency_libs="$newdependency_libs"
+ if test "$pass" = dlpreopen; then
+ # Link the dlpreopened libraries before other libraries
+ for deplib in $save_deplibs; do
+ deplibs="$deplib $deplibs"
+ done
+ fi
+ if test "$pass" != dlopen; then
+ if test "$pass" != conv; then
+ # Make sure lib_search_path contains only unique directories.
+ lib_search_path=
+ for dir in $newlib_search_path; do
+ case "$lib_search_path " in
+ *" $dir "*) ;;
+ *) lib_search_path="$lib_search_path $dir" ;;
+ esac
+ done
+ newlib_search_path=
+ fi
+
+ if test "$linkmode,$pass" != "prog,link"; then
+ vars="deplibs"
+ else
+ vars="compile_deplibs finalize_deplibs"
+ fi
+ for var in $vars dependency_libs; do
+ # Add libraries to $var in reverse order
+ eval tmp_libs=\"\$$var\"
+ new_libs=
+ for deplib in $tmp_libs; do
+ # FIXME: Pedantically, this is the right thing to do, so
+ # that some nasty dependency loop isn't accidentally
+ # broken:
+ #new_libs="$deplib $new_libs"
+ # Pragmatically, this seems to cause very few problems in
+ # practice:
+ case $deplib in
+ -L*) new_libs="$deplib $new_libs" ;;
+ -R*) ;;
+ *)
+ # And here is the reason: when a library appears more
+ # than once as an explicit dependence of a library, or
+ # is implicitly linked in more than once by the
+ # compiler, it is considered special, and multiple
+ # occurrences thereof are not removed. Compare this
+ # with having the same library being listed as a
+ # dependency of multiple other libraries: in this case,
+ # we know (pedantically, we assume) the library does not
+ # need to be listed more than once, so we keep only the
+ # last copy. This is not always right, but it is rare
+ # enough that we require users that really mean to play
+ # such unportable linking tricks to link the library
+ # using -Wl,-lname, so that libtool does not consider it
+ # for duplicate removal.
+ case " $specialdeplibs " in
+ *" $deplib "*) new_libs="$deplib $new_libs" ;;
+ *)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) new_libs="$deplib $new_libs" ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+ done
+ tmp_libs=
+ for deplib in $new_libs; do
+ case $deplib in
+ -L*)
+ case " $tmp_libs " in
+ *" $deplib "*) ;;
+ *) tmp_libs="$tmp_libs $deplib" ;;
+ esac
+ ;;
+ *) tmp_libs="$tmp_libs $deplib" ;;
+ esac
+ done
+ eval $var=\"$tmp_libs\"
+ done # for var
+ fi
+ # Last step: remove runtime libs from dependency_libs (they stay in deplibs)
+ tmp_libs=
+ for i in $dependency_libs ; do
+ case " $predeps $postdeps $compiler_lib_search_path " in
+ *" $i "*)
+ i=""
+ ;;
+ esac
+ if test -n "$i" ; then
+ tmp_libs="$tmp_libs $i"
+ fi
+ done
+ dependency_libs=$tmp_libs
+ done # for pass
+ if test "$linkmode" = prog; then
+ dlfiles="$newdlfiles"
+ dlprefiles="$newdlprefiles"
+ fi
+
+ case $linkmode in
+ oldlib)
+ if test -n "$deplibs"; then
+ $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2
+ fi
+
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$rpath"; then
+ $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$xrpath"; then
+ $echo "$modename: warning: \`-R' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+ $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2
+ fi
+
+ # Now set the variables for building old libraries.
+ build_libtool_libs=no
+ oldlibs="$output"
+ objs="$objs$old_deplibs"
+ ;;
+
+ lib)
+ # Make sure we only generate libraries of the form `libNAME.la'.
+ case $outputname in
+ lib*)
+ name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+ eval shared_ext=\"$shrext\"
+ eval libname=\"$libname_spec\"
+ ;;
+ *)
+ if test "$module" = no; then
+ $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+ if test "$need_lib_prefix" != no; then
+ # Add the "lib" prefix for modules if required
+ name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+ eval shared_ext=\"$shrext\"
+ eval libname=\"$libname_spec\"
+ else
+ libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+ fi
+ ;;
+ esac
+
+ if test -n "$objs"; then
+ if test "$deplibs_check_method" != pass_all; then
+ $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1
+ exit 1
+ else
+ $echo
+ $echo "*** Warning: Linking the shared library $output against the non-libtool"
+ $echo "*** objects $objs is not portable!"
+ libobjs="$libobjs $objs"
+ fi
+ fi
+
+ if test "$dlself" != no; then
+ $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2
+ fi
+
+ set dummy $rpath
+ if test "$#" -gt 2; then
+ $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
+ fi
+ install_libdir="$2"
+
+ oldlibs=
+ if test -z "$rpath"; then
+ if test "$build_libtool_libs" = yes; then
+ # Building a libtool convenience library.
+ # Some compilers have problems with a `.al' extension so
+ # convenience libraries should have the same extension an
+ # archive normally would.
+ oldlibs="$output_objdir/$libname.$libext $oldlibs"
+ build_libtool_libs=convenience
+ build_old_libs=yes
+ fi
+
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2
+ fi
+ else
+
+ # Parse the version information argument.
+ save_ifs="$IFS"; IFS=':'
+ set dummy $vinfo 0 0 0
+ IFS="$save_ifs"
+
+ if test -n "$8"; then
+ $echo "$modename: too many parameters to \`-version-info'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # convert absolute version numbers to libtool ages
+ # this retains compatibility with .la files and attempts
+ # to make the code below a bit more comprehensible
+
+ case $vinfo_number in
+ yes)
+ number_major="$2"
+ number_minor="$3"
+ number_revision="$4"
+ #
+ # There are really only two kinds -- those that
+ # use the current revision as the major version
+ # and those that subtract age and use age as
+ # a minor version. But, then there is irix
+ # which has an extra 1 added just for fun
+ #
+ case $version_type in
+ darwin|linux|osf|windows)
+ current=`expr $number_major + $number_minor`
+ age="$number_minor"
+ revision="$number_revision"
+ ;;
+ freebsd-aout|freebsd-elf|sunos)
+ current="$number_major"
+ revision="$number_minor"
+ age="0"
+ ;;
+ irix|nonstopux)
+ current=`expr $number_major + $number_minor - 1`
+ age="$number_minor"
+ revision="$number_minor"
+ ;;
+ esac
+ ;;
+ no)
+ current="$2"
+ revision="$3"
+ age="$4"
+ ;;
+ esac
+
+ # Check that each of the things are valid numbers.
+ case $current in
+ 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;;
+ *)
+ $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ ;;
+ esac
+
+ case $revision in
+ 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;;
+ *)
+ $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ ;;
+ esac
+
+ case $age in
+ 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;;
+ *)
+ $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ ;;
+ esac
+
+ if test "$age" -gt "$current"; then
+ $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ fi
+
+ # Calculate the version variables.
+ major=
+ versuffix=
+ verstring=
+ case $version_type in
+ none) ;;
+
+ darwin)
+ # Like Linux, but with the current version available in
+ # verstring for coding it into the library header
+ major=.`expr $current - $age`
+ versuffix="$major.$age.$revision"
+ # Darwin ld doesn't like 0 for these options...
+ minor_current=`expr $current + 1`
+ verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+ ;;
+
+ freebsd-aout)
+ major=".$current"
+ versuffix=".$current.$revision";
+ ;;
+
+ freebsd-elf)
+ major=".$current"
+ versuffix=".$current";
+ ;;
+
+ irix | nonstopux)
+ major=`expr $current - $age + 1`
+
+ case $version_type in
+ nonstopux) verstring_prefix=nonstopux ;;
+ *) verstring_prefix=sgi ;;
+ esac
+ verstring="$verstring_prefix$major.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$revision
+ while test "$loop" -ne 0; do
+ iface=`expr $revision - $loop`
+ loop=`expr $loop - 1`
+ verstring="$verstring_prefix$major.$iface:$verstring"
+ done
+
+ # Before this point, $major must not contain `.'.
+ major=.$major
+ versuffix="$major.$revision"
+ ;;
+
+ linux)
+ major=.`expr $current - $age`
+ versuffix="$major.$age.$revision"
+ ;;
+
+ osf)
+ major=.`expr $current - $age`
+ versuffix=".$current.$age.$revision"
+ verstring="$current.$age.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$age
+ while test "$loop" -ne 0; do
+ iface=`expr $current - $loop`
+ loop=`expr $loop - 1`
+ verstring="$verstring:${iface}.0"
+ done
+
+ # Make executables depend on our current version.
+ verstring="$verstring:${current}.0"
+ ;;
+
+ sunos)
+ major=".$current"
+ versuffix=".$current.$revision"
+ ;;
+
+ windows)
+ # Use '-' rather than '.', since we only want one
+ # extension on DOS 8.3 filesystems.
+ major=`expr $current - $age`
+ versuffix="-$major"
+ ;;
+
+ *)
+ $echo "$modename: unknown library version type \`$version_type'" 1>&2
+ $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
+ exit 1
+ ;;
+ esac
+
+ # Clear the version info if we defaulted, and they specified a release.
+ if test -z "$vinfo" && test -n "$release"; then
+ major=
+ case $version_type in
+ darwin)
+ # we can't check for "0.0" in archive_cmds due to quoting
+ # problems, so we reset it completely
+ verstring=
+ ;;
+ *)
+ verstring="0.0"
+ ;;
+ esac
+ if test "$need_version" = no; then
+ versuffix=
+ else
+ versuffix=".0.0"
+ fi
+ fi
+
+ # Remove version info from name if versioning should be avoided
+ if test "$avoid_version" = yes && test "$need_version" = no; then
+ major=
+ versuffix=
+ verstring=""
+ fi
+
+ # Check to see if the archive will have undefined symbols.
+ if test "$allow_undefined" = yes; then
+ if test "$allow_undefined_flag" = unsupported; then
+ $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2
+ build_libtool_libs=no
+ build_old_libs=yes
+ fi
+ else
+ # Don't allow undefined symbols.
+ allow_undefined_flag="$no_undefined_flag"
+ fi
+ fi
+
+ if test "$mode" != relink; then
+ # Remove our outputs, but don't remove object files since they
+ # may have been created when compiling PIC objects.
+ removelist=
+ tempremovelist=`$echo "$output_objdir/*"`
+ for p in $tempremovelist; do
+ case $p in
+ *.$objext)
+ ;;
+ $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
+ removelist="$removelist $p"
+ ;;
+ *) ;;
+ esac
+ done
+ if test -n "$removelist"; then
+ $show "${rm}r $removelist"
+ $run ${rm}r $removelist
+ fi
+ fi
+
+ # Now set the variables for building old libraries.
+ if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+ oldlibs="$oldlibs $output_objdir/$libname.$libext"
+
+ # Transform .lo files to .o files.
+ oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
+ fi
+
+ # Eliminate all temporary directories.
+ for path in $notinst_path; do
+ lib_search_path=`$echo "$lib_search_path " | ${SED} -e 's% $path % %g'`
+ deplibs=`$echo "$deplibs " | ${SED} -e 's% -L$path % %g'`
+ dependency_libs=`$echo "$dependency_libs " | ${SED} -e 's% -L$path % %g'`
+ done
+
+ if test -n "$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ temp_xrpath=
+ for libdir in $xrpath; do
+ temp_xrpath="$temp_xrpath -R$libdir"
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir" ;;
+ esac
+ done
+ if true || test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
+ dependency_libs="$temp_xrpath $dependency_libs"
+ fi
+ fi
+
+ # Make sure dlfiles contains only unique files that won't be dlpreopened
+ old_dlfiles="$dlfiles"
+ dlfiles=
+ for lib in $old_dlfiles; do
+ case " $dlprefiles $dlfiles " in
+ *" $lib "*) ;;
+ *) dlfiles="$dlfiles $lib" ;;
+ esac
+ done
+
+ # Make sure dlprefiles contains only unique files
+ old_dlprefiles="$dlprefiles"
+ dlprefiles=
+ for lib in $old_dlprefiles; do
+ case "$dlprefiles " in
+ *" $lib "*) ;;
+ *) dlprefiles="$dlprefiles $lib" ;;
+ esac
+ done
+
+ if test "$build_libtool_libs" = yes; then
+ if test -n "$rpath"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*)
+ # these systems don't actually have a c library (as such)!
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C library is in the System framework
+ deplibs="$deplibs -framework System"
+ ;;
+ *-*-netbsd*)
+ # Don't link with libc until the a.out ld.so is fixed.
+ ;;
+ *-*-freebsd*-gnu*)
+ # Prevent $arg from being parsed by the freebsd regexp below.
+ if test "$build_libtool_need_lc" = "yes"; then
+ deplibs="$deplibs -lc"
+ fi
+ ;;
+ *-*-openbsd* | *-*-freebsd*)
+ # Do not include libc due to us having libc/libc_r.
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *)
+ # Add libc to deplibs on all other systems if necessary.
+ if test "$build_libtool_need_lc" = "yes"; then
+ deplibs="$deplibs -lc"
+ fi
+ ;;
+ esac
+ fi
+
+ # Transform deplibs into only deplibs that can be linked in shared.
+ name_save=$name
+ libname_save=$libname
+ release_save=$release
+ versuffix_save=$versuffix
+ major_save=$major
+ # I'm not sure if I'm treating the release correctly. I think
+ # release should show up in the -l (ie -lgmp5) so we don't want to
+ # add it in twice. Is that correct?
+ release=""
+ versuffix=""
+ major=""
+ newdeplibs=
+ droppeddeps=no
+ case $deplibs_check_method in
+ pass_all)
+ # Don't check for shared/static. Everything works.
+ # This might be a little naive. We might want to check
+ # whether the library exists or not. But this is on
+ # osf3 & osf4 and I'm not really sure... Just
+ # implementing what was already the behavior.
+ newdeplibs=$deplibs
+ ;;
+ test_compile)
+ # This code stresses the "libraries are programs" paradigm to its
+ # limits. Maybe even breaks it. We compile a program, linking it
+ # against the deplibs as a proxy for the library. Then we can check
+ # whether they linked in statically or dynamically with ldd.
+ $rm conftest.c
+ cat > conftest.c <<EOF
+ int main() { return 0; }
+EOF
+ $rm conftest
+ $LTCC -o conftest conftest.c $deplibs
+ if test "$?" -eq 0 ; then
+ ldd_output=`ldd conftest`
+ for i in $deplibs; do
+ name="`expr $i : '-l\(.*\)'`"
+ # If $name is empty we are operating on a -L argument.
+ if test "$name" != "" && test "$name" -ne "0"; then
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ newdeplibs="$newdeplibs $i"
+ i=""
+ ;;
+ esac
+ fi
+ if test -n "$i" ; then
+ libname=`eval \\$echo \"$libname_spec\"`
+ deplib_matches=`eval \\$echo \"$library_names_spec\"`
+ set dummy $deplib_matches
+ deplib_match=$2
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ newdeplibs="$newdeplibs $i"
+ else
+ droppeddeps=yes
+ $echo
+ $echo "*** Warning: dynamic linker does not accept needed library $i."
+ $echo "*** I have the capability to make that library automatically link in when"
+ $echo "*** you link to this library. But I can only do this if you have a"
+ $echo "*** shared version of the library, which I believe you do not have"
+ $echo "*** because a test_compile did reveal that the linker did not use it for"
+ $echo "*** its dynamic dependency list that programs get resolved with at runtime."
+ fi
+ fi
+ else
+ newdeplibs="$newdeplibs $i"
+ fi
+ done
+ else
+ # Error occurred in the first compile. Let's try to salvage
+ # the situation: Compile a separate program for each library.
+ for i in $deplibs; do
+ name="`expr $i : '-l\(.*\)'`"
+ # If $name is empty we are operating on a -L argument.
+ if test "$name" != "" && test "$name" != "0"; then
+ $rm conftest
+ $LTCC -o conftest conftest.c $i
+ # Did it work?
+ if test "$?" -eq 0 ; then
+ ldd_output=`ldd conftest`
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ newdeplibs="$newdeplibs $i"
+ i=""
+ ;;
+ esac
+ fi
+ if test -n "$i" ; then
+ libname=`eval \\$echo \"$libname_spec\"`
+ deplib_matches=`eval \\$echo \"$library_names_spec\"`
+ set dummy $deplib_matches
+ deplib_match=$2
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ newdeplibs="$newdeplibs $i"
+ else
+ droppeddeps=yes
+ $echo
+ $echo "*** Warning: dynamic linker does not accept needed library $i."
+ $echo "*** I have the capability to make that library automatically link in when"
+ $echo "*** you link to this library. But I can only do this if you have a"
+ $echo "*** shared version of the library, which you do not appear to have"
+ $echo "*** because a test_compile did reveal that the linker did not use this one"
+ $echo "*** as a dynamic dependency that programs can get resolved with at runtime."
+ fi
+ fi
+ else
+ droppeddeps=yes
+ $echo
+ $echo "*** Warning! Library $i is needed by this library but I was not able to"
+ $echo "*** make it link in! You will probably need to install it or some"
+ $echo "*** library that it depends on before this library will be fully"
+ $echo "*** functional. Installing it before continuing would be even better."
+ fi
+ else
+ newdeplibs="$newdeplibs $i"
+ fi
+ done
+ fi
+ ;;
+ file_magic*)
+ set dummy $deplibs_check_method
+ file_magic_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
+ for a_deplib in $deplibs; do
+ name="`expr $a_deplib : '-l\(.*\)'`"
+ # If $name is empty we are operating on a -L argument.
+ if test "$name" != "" && test "$name" != "0"; then
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib" ; then
+ libname=`eval \\$echo \"$libname_spec\"`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ # Follow soft links.
+ if ls -lLd "$potent_lib" 2>/dev/null \
+ | grep " -> " >/dev/null; then
+ continue
+ fi
+ # The statement above tries to avoid entering an
+ # endless loop below, in case of cyclic links.
+ # We might still enter an endless loop, since a link
+ # loop can be closed while we follow links,
+ # but so what?
+ potlib="$potent_lib"
+ while test -h "$potlib" 2>/dev/null; do
+ potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
+ case $potliblink in
+ [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+ *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
+ esac
+ done
+ if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \
+ | ${SED} 10q \
+ | $EGREP "$file_magic_regex" > /dev/null; then
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib" ; then
+ droppeddeps=yes
+ $echo
+ $echo "*** Warning: linker path does not have real file for library $a_deplib."
+ $echo "*** I have the capability to make that library automatically link in when"
+ $echo "*** you link to this library. But I can only do this if you have a"
+ $echo "*** shared version of the library, which you do not appear to have"
+ $echo "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib" ; then
+ $echo "*** with $libname but no candidates were found. (...for file magic test)"
+ else
+ $echo "*** with $libname and none of the candidates passed a file format test"
+ $echo "*** using a file magic. Last file checked: $potlib"
+ fi
+ fi
+ else
+ # Add a -L argument.
+ newdeplibs="$newdeplibs $a_deplib"
+ fi
+ done # Gone through all deplibs.
+ ;;
+ match_pattern*)
+ set dummy $deplibs_check_method
+ match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
+ for a_deplib in $deplibs; do
+ name="`expr $a_deplib : '-l\(.*\)'`"
+ # If $name is empty we are operating on a -L argument.
+ if test -n "$name" && test "$name" != "0"; then
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib" ; then
+ libname=`eval \\$echo \"$libname_spec\"`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ potlib="$potent_lib" # see symlink-check above in file_magic test
+ if eval $echo \"$potent_lib\" 2>/dev/null \
+ | ${SED} 10q \
+ | $EGREP "$match_pattern_regex" > /dev/null; then
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib" ; then
+ droppeddeps=yes
+ $echo
+ $echo "*** Warning: linker path does not have real file for library $a_deplib."
+ $echo "*** I have the capability to make that library automatically link in when"
+ $echo "*** you link to this library. But I can only do this if you have a"
+ $echo "*** shared version of the library, which you do not appear to have"
+ $echo "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib" ; then
+ $echo "*** with $libname but no candidates were found. (...for regex pattern test)"
+ else
+ $echo "*** with $libname and none of the candidates passed a file format test"
+ $echo "*** using a regex pattern. Last file checked: $potlib"
+ fi
+ fi
+ else
+ # Add a -L argument.
+ newdeplibs="$newdeplibs $a_deplib"
+ fi
+ done # Gone through all deplibs.
+ ;;
+ none | unknown | *)
+ newdeplibs=""
+ tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \
+ -e 's/ -[LR][^ ]*//g'`
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ for i in $predeps $postdeps ; do
+ # can't use Xsed below, because $i might contain '/'
+ tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"`
+ done
+ fi
+ if $echo "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' \
+ | grep . >/dev/null; then
+ $echo
+ if test "X$deplibs_check_method" = "Xnone"; then
+ $echo "*** Warning: inter-library dependencies are not supported in this platform."
+ else
+ $echo "*** Warning: inter-library dependencies are not known to be supported."
+ fi
+ $echo "*** All declared inter-library dependencies are being dropped."
+ droppeddeps=yes
+ fi
+ ;;
+ esac
+ versuffix=$versuffix_save
+ major=$major_save
+ release=$release_save
+ libname=$libname_save
+ name=$name_save
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library is the System framework
+ newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'`
+ ;;
+ esac
+
+ if test "$droppeddeps" = yes; then
+ if test "$module" = yes; then
+ $echo
+ $echo "*** Warning: libtool could not satisfy all declared inter-library"
+ $echo "*** dependencies of module $libname. Therefore, libtool will create"
+ $echo "*** a static module, that should work as long as the dlopening"
+ $echo "*** application is linked with the -dlopen flag."
+ if test -z "$global_symbol_pipe"; then
+ $echo
+ $echo "*** However, this would only work if libtool was able to extract symbol"
+ $echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ $echo "*** not find such a program. So, this module is probably useless."
+ $echo "*** \`nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ else
+ $echo "*** The inter-library dependencies that have been dropped here will be"
+ $echo "*** automatically added whenever a program is linked with this library"
+ $echo "*** or is declared to -dlopen it."
+
+ if test "$allow_undefined" = no; then
+ $echo
+ $echo "*** Since this library must not contain undefined symbols,"
+ $echo "*** because either the platform does not support them or"
+ $echo "*** it was explicitly requested with -no-undefined,"
+ $echo "*** libtool will only create a static version of it."
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ fi
+ fi
+ # Done checking deplibs!
+ deplibs=$newdeplibs
+ fi
+
+ # All the library-specific variables (install_libdir is set above).
+ library_names=
+ old_library=
+ dlname=
+
+ # Test again, we may have decided not to build it any more
+ if test "$build_libtool_libs" = yes; then
+ if test "$hardcode_into_libs" = yes; then
+ # Hardcode the library paths
+ hardcode_libdirs=
+ dep_rpath=
+ rpath="$finalize_rpath"
+ test "$mode" != relink && test "$fast_install" = no && rpath="$compile_rpath$rpath"
+ for libdir in $rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ dep_rpath="$dep_rpath $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) perm_rpath="$perm_rpath $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ if test -n "$hardcode_libdir_flag_spec_ld"; then
+ eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\"
+ else
+ eval dep_rpath=\"$hardcode_libdir_flag_spec\"
+ fi
+ fi
+ if test -n "$runpath_var" && test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+ fi
+ test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+ fi
+
+ shlibpath="$finalize_shlibpath"
+ test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
+ if test -n "$shlibpath"; then
+ eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+ fi
+
+ # Get the real and link names of the library.
+ eval shared_ext=\"$shrext\"
+ eval library_names=\"$library_names_spec\"
+ set dummy $library_names
+ realname="$2"
+ shift; shift
+
+ if test -n "$soname_spec"; then
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+ if test -z "$dlname"; then
+ dlname=$soname
+ fi
+
+ lib="$output_objdir/$realname"
+ for link
+ do
+ linknames="$linknames $link"
+ done
+
+ # Use standard objects if they are pic
+ test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+ $show "generating symbol list for \`$libname.la'"
+ export_symbols="$output_objdir/$libname.exp"
+ $run $rm $export_symbols
+ eval cmds=\"$export_symbols_cmds\"
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ if len=`expr "X$cmd" : ".*"` &&
+ test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ skipped_export=false
+ else
+ # The command line is too long to execute in one step.
+ $show "using reloadable object file for export list..."
+ skipped_export=:
+ fi
+ done
+ IFS="$save_ifs"
+ if test -n "$export_symbols_regex"; then
+ $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\""
+ $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ $show "$mv \"${export_symbols}T\" \"$export_symbols\""
+ $run eval '$mv "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+ fi
+
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"'
+ fi
+
+ tmp_deplibs=
+ for test_deplib in $deplibs; do
+ case " $convenience " in
+ *" $test_deplib "*) ;;
+ *)
+ tmp_deplibs="$tmp_deplibs $test_deplib"
+ ;;
+ esac
+ done
+ deplibs="$tmp_deplibs"
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ else
+ gentop="$output_objdir/${outputname}x"
+ $show "${rm}r $gentop"
+ $run ${rm}r "$gentop"
+ $show "$mkdir $gentop"
+ $run $mkdir "$gentop"
+ status=$?
+ if test "$status" -ne 0 && test ! -d "$gentop"; then
+ exit $status
+ fi
+ generated="$generated $gentop"
+
+ for xlib in $convenience; do
+ # Extract the objects.
+ case $xlib in
+ [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+ *) xabs=`pwd`"/$xlib" ;;
+ esac
+ xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+ xdir="$gentop/$xlib"
+
+ $show "${rm}r $xdir"
+ $run ${rm}r "$xdir"
+ $show "$mkdir $xdir"
+ $run $mkdir "$xdir"
+ status=$?
+ if test "$status" -ne 0 && test ! -d "$xdir"; then
+ exit $status
+ fi
+ # We will extract separately just the conflicting names and we will no
+ # longer touch any unique names. It is faster to leave these extract
+ # automatically by $AR in one run.
+ $show "(cd $xdir && $AR x $xabs)"
+ $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+ if ($AR t "$xabs" | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ $echo "$modename: warning: object name conflicts; renaming object files" 1>&2
+ $echo "$modename: warning: to ensure that they will not overwrite" 1>&2
+ $AR t "$xabs" | sort | uniq -cd | while read -r count name
+ do
+ i=1
+ while test "$i" -le "$count"
+ do
+ # Put our $i before any first dot (extension)
+ # Never overwrite any file
+ name_to="$name"
+ while test "X$name_to" = "X$name" || test -f "$xdir/$name_to"
+ do
+ name_to=`$echo "X$name_to" | $Xsed -e "s/\([^.]*\)/\1-$i/"`
+ done
+ $show "(cd $xdir && $AR xN $i $xabs '$name' && $mv '$name' '$name_to')"
+ $run eval "(cd \$xdir && $AR xN $i \$xabs '$name' && $mv '$name' '$name_to')" || exit $?
+ i=`expr $i + 1`
+ done
+ done
+ fi
+
+ libobjs="$libobjs "`find $xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
+ done
+ fi
+ fi
+
+ if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+ eval flag=\"$thread_safe_flag_spec\"
+ linker_flags="$linker_flags $flag"
+ fi
+
+ # Make a backup of the uninstalled library when relinking
+ if test "$mode" = relink; then
+ $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $?
+ fi
+
+ # Add all flags from the command line. We here create a library,
+ # but those flags were only added to compile_command and
+ # finalize_command, which are only used when creating executables.
+ # So do it by hand here.
+ compiler_flags="$compiler_flags $add_flags"
+ # Only add it to commands which use CC, instead of LD, i.e.
+ # only to $compiler_flags
+ #linker_flags="$linker_flags $add_flags"
+
+ # Do each of the archive commands.
+ if test "$module" = yes && test -n "$module_cmds" ; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ eval cmds=\"$module_expsym_cmds\"
+ else
+ eval cmds=\"$module_cmds\"
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ eval cmds=\"$archive_expsym_cmds\"
+ else
+ eval cmds=\"$archive_cmds\"
+ fi
+ fi
+
+ if test "X$skipped_export" != "X:" && len=`expr "X$cmds" : ".*"` &&
+ test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ :
+ else
+ # The command line is too long to link in one step, link piecewise.
+ $echo "creating reloadable object files..."
+
+ # Save the value of $output and $libobjs because we want to
+ # use them later. If we have whole_archive_flag_spec, we
+ # want to use save_libobjs as it was before
+ # whole_archive_flag_spec was expanded, because we can't
+ # assume the linker understands whole_archive_flag_spec.
+ # This may have to be revisited, in case too many
+ # convenience libraries get linked in and end up exceeding
+ # the spec.
+ if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ fi
+ save_output=$output
+
+ # Clear the reloadable object creation command queue and
+ # initialize k to one.
+ test_cmds=
+ concat_cmds=
+ objlist=
+ delfiles=
+ last_robj=
+ k=1
+ output=$output_objdir/$save_output-${k}.$objext
+ # Loop over the list of objects to be linked.
+ for obj in $save_libobjs
+ do
+ eval test_cmds=\"$reload_cmds $objlist $last_robj\"
+ if test "X$objlist" = X ||
+ { len=`expr "X$test_cmds" : ".*"` &&
+ test "$len" -le "$max_cmd_len"; }; then
+ objlist="$objlist $obj"
+ else
+ # The command $test_cmds is almost too long, add a
+ # command to the queue.
+ if test "$k" -eq 1 ; then
+ # The first file doesn't have a previous command to add.
+ eval concat_cmds=\"$reload_cmds $objlist $last_robj\"
+ else
+ # All subsequent reloadable object files will link in
+ # the last one created.
+ eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\"
+ fi
+ last_robj=$output_objdir/$save_output-${k}.$objext
+ k=`expr $k + 1`
+ output=$output_objdir/$save_output-${k}.$objext
+ objlist=$obj
+ len=1
+ fi
+ done
+ # Handle the remaining objects by creating one last
+ # reloadable object file. All subsequent reloadable object
+ # files will link in the last one created.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\"
+
+ if ${skipped_export-false}; then
+ $show "generating symbol list for \`$libname.la'"
+ export_symbols="$output_objdir/$libname.exp"
+ $run $rm $export_symbols
+ libobjs=$output
+ # Append the command to create the export file.
+ eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\"
+ fi
+
+ # Set up a command to remove the reloadale object files
+ # after they are used.
+ i=0
+ while test "$i" -lt "$k"
+ do
+ i=`expr $i + 1`
+ delfiles="$delfiles $output_objdir/$save_output-${i}.$objext"
+ done
+
+ $echo "creating a temporary reloadable object file: $output"
+
+ # Loop through the commands generated above and execute them.
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $concat_cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+
+ libobjs=$output
+ # Restore the value of output.
+ output=$save_output
+
+ if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ fi
+ # Expand the library linking commands again to reset the
+ # value of $libobjs for piecewise linking.
+
+ # Do each of the archive commands.
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ eval cmds=\"$archive_expsym_cmds\"
+ else
+ eval cmds=\"$archive_cmds\"
+ fi
+
+ # Append the command to remove the reloadable object files
+ # to the just-reset $cmds.
+ eval cmds=\"\$cmds~$rm $delfiles\"
+ fi
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+
+ # Restore the uninstalled library and exit
+ if test "$mode" = relink; then
+ $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $?
+ exit 0
+ fi
+
+ # Create links to the real library.
+ for linkname in $linknames; do
+ if test "$realname" != "$linkname"; then
+ $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)"
+ $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $?
+ fi
+ done
+
+ # If -module or -export-dynamic was specified, set the dlname.
+ if test "$module" = yes || test "$export_dynamic" = yes; then
+ # On all known operating systems, these are identical.
+ dlname="$soname"
+ fi
+ fi
+ ;;
+
+ obj)
+ if test -n "$deplibs"; then
+ $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2
+ fi
+
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$rpath"; then
+ $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$xrpath"; then
+ $echo "$modename: warning: \`-R' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for objects" 1>&2
+ fi
+
+ case $output in
+ *.lo)
+ if test -n "$objs$old_deplibs"; then
+ $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2
+ exit 1
+ fi
+ libobj="$output"
+ obj=`$echo "X$output" | $Xsed -e "$lo2o"`
+ ;;
+ *)
+ libobj=
+ obj="$output"
+ ;;
+ esac
+
+ # Delete the old objects.
+ $run $rm $obj $libobj
+
+ # Objects from convenience libraries. This assumes
+ # single-version convenience libraries. Whenever we create
+ # different ones for PIC/non-PIC, this we'll have to duplicate
+ # the extraction.
+ reload_conv_objs=
+ gentop=
+ # reload_cmds runs $LD directly, so let us get rid of
+ # -Wl from whole_archive_flag_spec
+ wl=
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec"; then
+ eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\"
+ else
+ gentop="$output_objdir/${obj}x"
+ $show "${rm}r $gentop"
+ $run ${rm}r "$gentop"
+ $show "$mkdir $gentop"
+ $run $mkdir "$gentop"
+ status=$?
+ if test "$status" -ne 0 && test ! -d "$gentop"; then
+ exit $status
+ fi
+ generated="$generated $gentop"
+
+ for xlib in $convenience; do
+ # Extract the objects.
+ case $xlib in
+ [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+ *) xabs=`pwd`"/$xlib" ;;
+ esac
+ xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+ xdir="$gentop/$xlib"
+
+ $show "${rm}r $xdir"
+ $run ${rm}r "$xdir"
+ $show "$mkdir $xdir"
+ $run $mkdir "$xdir"
+ status=$?
+ if test "$status" -ne 0 && test ! -d "$xdir"; then
+ exit $status
+ fi
+ # We will extract separately just the conflicting names and we will no
+ # longer touch any unique names. It is faster to leave these extract
+ # automatically by $AR in one run.
+ $show "(cd $xdir && $AR x $xabs)"
+ $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+ if ($AR t "$xabs" | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ $echo "$modename: warning: object name conflicts; renaming object files" 1>&2
+ $echo "$modename: warning: to ensure that they will not overwrite" 1>&2
+ $AR t "$xabs" | sort | uniq -cd | while read -r count name
+ do
+ i=1
+ while test "$i" -le "$count"
+ do
+ # Put our $i before any first dot (extension)
+ # Never overwrite any file
+ name_to="$name"
+ while test "X$name_to" = "X$name" || test -f "$xdir/$name_to"
+ do
+ name_to=`$echo "X$name_to" | $Xsed -e "s/\([^.]*\)/\1-$i/"`
+ done
+ $show "(cd $xdir && $AR xN $i $xabs '$name' && $mv '$name' '$name_to')"
+ $run eval "(cd \$xdir && $AR xN $i \$xabs '$name' && $mv '$name' '$name_to')" || exit $?
+ i=`expr $i + 1`
+ done
+ done
+ fi
+
+ reload_conv_objs="$reload_objs "`find $xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
+ done
+ fi
+ fi
+
+ # Create the old-style object.
+ reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
+
+ output="$obj"
+ eval cmds=\"$reload_cmds\"
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+
+ # Exit if we aren't doing a library object file.
+ if test -z "$libobj"; then
+ if test -n "$gentop"; then
+ $show "${rm}r $gentop"
+ $run ${rm}r $gentop
+ fi
+
+ exit 0
+ fi
+
+ if test "$build_libtool_libs" != yes; then
+ if test -n "$gentop"; then
+ $show "${rm}r $gentop"
+ $run ${rm}r $gentop
+ fi
+
+ # Create an invalid libtool object if no PIC, so that we don't
+ # accidentally link it into a program.
+ # $show "echo timestamp > $libobj"
+ # $run eval "echo timestamp > $libobj" || exit $?
+ exit 0
+ fi
+
+ if test -n "$pic_flag" || test "$pic_mode" != default; then
+ # Only do commands if we really have different PIC objects.
+ reload_objs="$libobjs $reload_conv_objs"
+ output="$libobj"
+ eval cmds=\"$reload_cmds\"
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ fi
+
+ if test -n "$gentop"; then
+ $show "${rm}r $gentop"
+ $run ${rm}r $gentop
+ fi
+
+ exit 0
+ ;;
+
+ prog)
+ case $host in
+ *cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;;
+ esac
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for programs" 1>&2
+ fi
+
+ if test "$preload" = yes; then
+ if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown &&
+ test "$dlopen_self_static" = unknown; then
+ $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support."
+ fi
+ fi
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library is the System framework
+ compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'`
+ finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'`
+ ;;
+ esac
+
+ case $host in
+ *darwin*)
+ # Don't allow lazy linking, it breaks C++ global constructors
+ if test "$tagname" = CXX ; then
+ compile_command="$compile_command ${wl}-bind_at_load"
+ finalize_command="$finalize_command ${wl}-bind_at_load"
+ fi
+ ;;
+ esac
+
+ compile_command="$compile_command $compile_deplibs"
+ finalize_command="$finalize_command $finalize_deplibs"
+
+ if test -n "$rpath$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ for libdir in $rpath $xrpath; do
+ # This is the magic to use -rpath.
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir" ;;
+ esac
+ done
+ fi
+
+ # Now hardcode the library paths
+ rpath=
+ hardcode_libdirs=
+ for libdir in $compile_rpath $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ rpath="$rpath $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) perm_rpath="$perm_rpath $libdir" ;;
+ esac
+ fi
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+ case :$dllsearchpath: in
+ *":$libdir:"*) ;;
+ *) dllsearchpath="$dllsearchpath:$libdir";;
+ esac
+ ;;
+ esac
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ compile_rpath="$rpath"
+
+ rpath=
+ hardcode_libdirs=
+ for libdir in $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ rpath="$rpath $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$finalize_perm_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ finalize_rpath="$rpath"
+
+ if test -n "$libobjs" && test "$build_old_libs" = yes; then
+ # Transform all the library objects into standard objects.
+ compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ fi
+
+ dlsyms=
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ if test -n "$NM" && test -n "$global_symbol_pipe"; then
+ dlsyms="${outputname}S.c"
+ else
+ $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2
+ fi
+ fi
+
+ if test -n "$dlsyms"; then
+ case $dlsyms in
+ "") ;;
+ *.c)
+ # Discover the nlist of each of the dlfiles.
+ nlist="$output_objdir/${outputname}.nm"
+
+ $show "$rm $nlist ${nlist}S ${nlist}T"
+ $run $rm "$nlist" "${nlist}S" "${nlist}T"
+
+ # Parse the name list into a source file.
+ $show "creating $output_objdir/$dlsyms"
+
+ test -z "$run" && $echo > "$output_objdir/$dlsyms" "\
+/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */
+/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+/* Prevent the only kind of declaration conflicts we can make. */
+#define lt_preloaded_symbols some_other_symbol
+
+/* External symbol declarations for the compiler. */\
+"
+
+ if test "$dlself" = yes; then
+ $show "generating symbol list for \`$output'"
+
+ test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist"
+
+ # Add our own program objects to the symbol list.
+ progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ for arg in $progfiles; do
+ $show "extracting global C symbols from \`$arg'"
+ $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -n "$exclude_expsyms"; then
+ $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+ $run eval '$mv "$nlist"T "$nlist"'
+ fi
+
+ if test -n "$export_symbols_regex"; then
+ $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+ $run eval '$mv "$nlist"T "$nlist"'
+ fi
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ export_symbols="$output_objdir/$output.exp"
+ $run $rm $export_symbols
+ $run eval "${SED} -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+ else
+ $run eval "${SED} -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"'
+ $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T'
+ $run eval 'mv "$nlist"T "$nlist"'
+ fi
+ fi
+
+ for arg in $dlprefiles; do
+ $show "extracting global C symbols from \`$arg'"
+ name=`$echo "$arg" | ${SED} -e 's%^.*/%%'`
+ $run eval '$echo ": $name " >> "$nlist"'
+ $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -z "$run"; then
+ # Make sure we have at least an empty file.
+ test -f "$nlist" || : > "$nlist"
+
+ if test -n "$exclude_expsyms"; then
+ $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+ $mv "$nlist"T "$nlist"
+ fi
+
+ # Try sorting and uniquifying the output.
+ if grep -v "^: " < "$nlist" |
+ if sort -k 3 </dev/null >/dev/null 2>&1; then
+ sort -k 3
+ else
+ sort +2
+ fi |
+ uniq > "$nlist"S; then
+ :
+ else
+ grep -v "^: " < "$nlist" > "$nlist"S
+ fi
+
+ if test -f "$nlist"S; then
+ eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"'
+ else
+ $echo '/* NONE */' >> "$output_objdir/$dlsyms"
+ fi
+
+ $echo >> "$output_objdir/$dlsyms" "\
+
+#undef lt_preloaded_symbols
+
+#if defined (__STDC__) && __STDC__
+# define lt_ptr void *
+#else
+# define lt_ptr char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ lt_ptr address;
+}
+lt_preloaded_symbols[] =
+{\
+"
+
+ eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms"
+
+ $echo >> "$output_objdir/$dlsyms" "\
+ {0, (lt_ptr) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+ fi
+
+ pic_flag_for_symtable=
+ case $host in
+ # compiling the symbol table file with pic_flag works around
+ # a FreeBSD bug that causes programs to crash when -lm is
+ # linked before any other PIC object. But we must not use
+ # pic_flag when linking with -static. The problem exists in
+ # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+ *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+ case "$compile_command " in
+ *" -static "*) ;;
+ *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";;
+ esac;;
+ *-*-hpux*)
+ case "$compile_command " in
+ *" -static "*) ;;
+ *) pic_flag_for_symtable=" $pic_flag";;
+ esac
+ esac
+
+ # Now compile the dynamic symbol file.
+ $show "(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
+ $run eval '(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
+
+ # Clean up the generated files.
+ $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T"
+ $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T"
+
+ # Transform the symbol file into the correct name.
+ compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+ ;;
+ *)
+ $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
+ exit 1
+ ;;
+ esac
+ else
+ # We keep going just in case the user didn't refer to
+ # lt_preloaded_symbols. The linker will fail if global_symbol_pipe
+ # really was required.
+
+ # Nullify the symbol file.
+ compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+ fi
+
+ # AIX runtime linking requires linking programs with -Wl,-brtl and libs with -Wl,-G
+ # Also add -bnolibpath to the beginning of the link line, to clear the hardcoded runpath.
+ # Otherwise, things like the -L path to libgcc.a are accidentally hardcoded by ld.
+ # This does not apply on AIX for ia64, which uses a SysV linker.
+ case "$host" in
+ ia64-*-aix5*) ;;
+ *-*-aix4* | *-*-aix5*)
+ compile_command=`$echo "X$compile_command $wl-brtl" | $Xsed -e "s/\$CC/\$CC $wl-bnolibpath/1"`
+ finalize_command=`$echo "X$finalize_command $wl-brtl" | $Xsed -e "s/\$CC/\$CC $wl-bnolibpath/1"` ;;
+ esac
+
+ if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
+ # Replace the output file specification.
+ compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+ link_command="$compile_command$compile_rpath"
+
+ # We have no uninstalled library dependencies, so finalize right now.
+ $show "$link_command"
+ $run eval "$link_command"
+ status=$?
+
+ # Delete the generated files.
+ if test -n "$dlsyms"; then
+ $show "$rm $output_objdir/${outputname}S.${objext}"
+ $run $rm "$output_objdir/${outputname}S.${objext}"
+ fi
+
+ exit $status
+ fi
+
+ if test -n "$shlibpath_var"; then
+ # We should set the shlibpath_var
+ rpath=
+ for dir in $temp_rpath; do
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*)
+ # Absolute path.
+ rpath="$rpath$dir:"
+ ;;
+ *)
+ # Relative path: add a thisdir entry.
+ rpath="$rpath\$thisdir/$dir:"
+ ;;
+ esac
+ done
+ temp_rpath="$rpath"
+ fi
+
+ if test -n "$compile_shlibpath$finalize_shlibpath"; then
+ compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+ fi
+ if test -n "$finalize_shlibpath"; then
+ finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+ fi
+
+ compile_var=
+ finalize_var=
+ if test -n "$runpath_var"; then
+ if test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ if test -n "$finalize_perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $finalize_perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ fi
+
+ if test "$no_install" = yes; then
+ # We don't need to create a wrapper script.
+ link_command="$compile_var$compile_command$compile_rpath"
+ # Replace the output file specification.
+ link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+ # Delete the old output file.
+ $run $rm $output
+ # Link the executable and exit
+ $show "$link_command"
+ $run eval "$link_command" || exit $?
+ exit 0
+ fi
+
+ if test "$hardcode_action" = relink; then
+ # Fast installation is not supported
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+ $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2
+ $echo "$modename: \`$output' will be relinked during installation" 1>&2
+ else
+ if test "$fast_install" != no; then
+ link_command="$finalize_var$compile_command$finalize_rpath"
+ if test "$fast_install" = yes; then
+ relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
+ else
+ # fast_install is set to needless
+ relink_command=
+ fi
+ else
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+ fi
+ fi
+
+ # Replace the output file specification.
+ link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+ # Delete the old output files.
+ $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+ $show "$link_command"
+ $run eval "$link_command" || exit $?
+
+ # Now create the wrapper script.
+ $show "creating $output"
+
+ # Quote the relink command for shipping.
+ if test -n "$relink_command"; then
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"`
+ relink_command="$var=\"$var_value\"; export $var; $relink_command"
+ fi
+ done
+ relink_command="(cd `pwd`; $relink_command)"
+ relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+ fi
+
+ # Quote $echo for shipping.
+ if test "X$echo" = "X$SHELL $0 --fallback-echo"; then
+ case $0 in
+ [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";;
+ *) qecho="$SHELL `pwd`/$0 --fallback-echo";;
+ esac
+ qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"`
+ else
+ qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"`
+ fi
+
+ # Only actually do things if our run command is non-null.
+ if test -z "$run"; then
+ # win32 will think the script is a binary if it has
+ # a .exe suffix, so we strip it off here.
+ case $output in
+ *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;;
+ esac
+ # test for cygwin because mv fails w/o .exe extensions
+ case $host in
+ *cygwin*)
+ exeext=.exe
+ outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;;
+ *) exeext= ;;
+ esac
+ case $host in
+ *cygwin* | *mingw* )
+ cwrappersource=`$echo ${objdir}/lt-${output}.c`
+ cwrapper=`$echo ${output}.exe`
+ $rm $cwrappersource $cwrapper
+ trap "$rm $cwrappersource $cwrapper; exit 1" 1 2 15
+
+ cat > $cwrappersource <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+ Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+
+ The $output program cannot be directly executed until all the libtool
+ libraries that it depends on are installed.
+
+ This wrapper executable should never be moved out of the build directory.
+ If it is, it will not operate correctly.
+
+ Currently, it simply execs the wrapper *script* "/bin/sh $output",
+ but could eventually absorb all of the scripts functionality and
+ exec $objdir/$outputname directly.
+*/
+EOF
+ cat >> $cwrappersource<<"EOF"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+
+#if defined(PATH_MAX)
+# define LT_PATHMAX PATH_MAX
+#elif defined(MAXPATHLEN)
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef DIR_SEPARATOR
+#define DIR_SEPARATOR '/'
+#endif
+
+#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
+ defined (__OS2__)
+#define HAVE_DOS_BASED_FILE_SYSTEM
+#ifndef DIR_SEPARATOR_2
+#define DIR_SEPARATOR_2 '\\'
+#endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+ if (stale) { free ((void *) stale); stale = 0; } \
+} while (0)
+
+const char *program_name = NULL;
+
+void * xmalloc (size_t num);
+char * xstrdup (const char *string);
+char * basename (const char *name);
+char * fnqualify(const char *path);
+char * strendzap(char *str, const char *pat);
+void lt_fatal (const char *message, ...);
+
+int
+main (int argc, char *argv[])
+{
+ char **newargz;
+ int i;
+
+ program_name = (char *) xstrdup ((char *) basename (argv[0]));
+ newargz = XMALLOC(char *, argc+2);
+EOF
+
+ cat >> $cwrappersource <<EOF
+ newargz[0] = "$SHELL";
+EOF
+
+ cat >> $cwrappersource <<"EOF"
+ newargz[1] = fnqualify(argv[0]);
+ /* we know the script has the same name, without the .exe */
+ /* so make sure newargz[1] doesn't end in .exe */
+ strendzap(newargz[1],".exe");
+ for (i = 1; i < argc; i++)
+ newargz[i+1] = xstrdup(argv[i]);
+ newargz[argc+1] = NULL;
+EOF
+
+ cat >> $cwrappersource <<EOF
+ execv("$SHELL",newargz);
+EOF
+
+ cat >> $cwrappersource <<"EOF"
+}
+
+void *
+xmalloc (size_t num)
+{
+ void * p = (void *) malloc (num);
+ if (!p)
+ lt_fatal ("Memory exhausted");
+
+ return p;
+}
+
+char *
+xstrdup (const char *string)
+{
+ return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL
+;
+}
+
+char *
+basename (const char *name)
+{
+ const char *base;
+
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ /* Skip over the disk name in MSDOS pathnames. */
+ if (isalpha (name[0]) && name[1] == ':')
+ name += 2;
+#endif
+
+ for (base = name; *name; name++)
+ if (IS_DIR_SEPARATOR (*name))
+ base = name + 1;
+ return (char *) base;
+}
+
+char *
+fnqualify(const char *path)
+{
+ size_t size;
+ char *p;
+ char tmp[LT_PATHMAX + 1];
+
+ assert(path != NULL);
+
+ /* Is it qualified already? */
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ if (isalpha (path[0]) && path[1] == ':')
+ return xstrdup (path);
+#endif
+ if (IS_DIR_SEPARATOR (path[0]))
+ return xstrdup (path);
+
+ /* prepend the current directory */
+ /* doesn't handle '~' */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal ("getcwd failed");
+ size = strlen(tmp) + 1 + strlen(path) + 1; /* +2 for '/' and '\0' */
+ p = XMALLOC(char, size);
+ sprintf(p, "%s%c%s", tmp, DIR_SEPARATOR, path);
+ return p;
+}
+
+char *
+strendzap(char *str, const char *pat)
+{
+ size_t len, patlen;
+
+ assert(str != NULL);
+ assert(pat != NULL);
+
+ len = strlen(str);
+ patlen = strlen(pat);
+
+ if (patlen <= len)
+ {
+ str += len - patlen;
+ if (strcmp(str, pat) == 0)
+ *str = '\0';
+ }
+ return str;
+}
+
+static void
+lt_error_core (int exit_status, const char * mode,
+ const char * message, va_list ap)
+{
+ fprintf (stderr, "%s: %s: ", program_name, mode);
+ vfprintf (stderr, message, ap);
+ fprintf (stderr, ".\n");
+
+ if (exit_status >= 0)
+ exit (exit_status);
+}
+
+void
+lt_fatal (const char *message, ...)
+{
+ va_list ap;
+ va_start (ap, message);
+ lt_error_core (EXIT_FAILURE, "FATAL", message, ap);
+ va_end (ap);
+}
+EOF
+ # we should really use a build-platform specific compiler
+ # here, but OTOH, the wrappers (shell script and this C one)
+ # are only useful if you want to execute the "real" binary.
+ # Since the "real" binary is built for $host, then this
+ # wrapper might as well be built for $host, too.
+ $run $LTCC -s -o $cwrapper $cwrappersource
+ ;;
+ esac
+ $rm $output
+ trap "$rm $output; exit 1" 1 2 15
+
+ $echo > $output "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='${SED} -e 1s/^X//'
+sed_quote_subst='$sed_quote_subst'
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test \"\${CDPATH+set}\" = set; then CDPATH=:; export CDPATH; fi
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+ # install mode needs the following variable:
+ notinst_deplibs='$notinst_deplibs'
+else
+ # When we are sourced in execute mode, \$file and \$echo are already set.
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ echo=\"$qecho\"
+ file=\"\$0\"
+ # Make sure echo works.
+ if test \"X\$1\" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+ elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then
+ # Yippee, \$echo works!
+ :
+ else
+ # Restart under the correct shell, and then maybe \$echo will work.
+ exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
+ fi
+ fi\
+"
+ $echo >> $output "\
+
+ # Find the directory that this script lives in.
+ thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
+ test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\`
+ while test -n \"\$file\"; do
+ destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+
+ # If there was a directory component, then change thisdir.
+ if test \"x\$destdir\" != \"x\$file\"; then
+ case \"\$destdir\" in
+ [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+ *) thisdir=\"\$thisdir/\$destdir\" ;;
+ esac
+ fi
+
+ file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
+ file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\`
+ done
+
+ # Try to get the absolute directory name.
+ absdir=\`cd \"\$thisdir\" && pwd\`
+ test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+ if test "$fast_install" = yes; then
+ $echo >> $output "\
+ program=lt-'$outputname'$exeext
+ progdir=\"\$thisdir/$objdir\"
+
+ if test ! -f \"\$progdir/\$program\" || \\
+ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
+ test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+ file=\"\$\$-\$program\"
+
+ if test ! -d \"\$progdir\"; then
+ $mkdir \"\$progdir\"
+ else
+ $rm \"\$progdir/\$file\"
+ fi"
+
+ $echo >> $output "\
+
+ # relink executable if necessary
+ if test -n \"\$relink_command\"; then
+ if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+ else
+ $echo \"\$relink_command_output\" >&2
+ $rm \"\$progdir/\$file\"
+ exit 1
+ fi
+ fi
+
+ $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+ { $rm \"\$progdir/\$program\";
+ $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+ $rm \"\$progdir/\$file\"
+ fi"
+ else
+ $echo >> $output "\
+ program='$outputname'
+ progdir=\"\$thisdir/$objdir\"
+"
+ fi
+
+ $echo >> $output "\
+
+ if test -f \"\$progdir/\$program\"; then"
+
+ # Export our shlibpath_var if we have one.
+ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ $echo >> $output "\
+ # Add our own library path to $shlibpath_var
+ $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+ # Some systems cannot cope with colon-terminated $shlibpath_var
+ # The second colon is a workaround for a bug in BeOS R4 sed
+ $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
+
+ export $shlibpath_var
+"
+ fi
+
+ # fixup the dll searchpath if we need to.
+ if test -n "$dllsearchpath"; then
+ $echo >> $output "\
+ # Add the dll search path components to the executable PATH
+ PATH=$dllsearchpath:\$PATH
+"
+ fi
+
+ $echo >> $output "\
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ # Run the actual program with our arguments.
+"
+ case $host in
+ # Backslashes separate directories on plain windows
+ *-*-mingw | *-*-os2*)
+ $echo >> $output "\
+ exec \$progdir\\\\\$program \${1+\"\$@\"}
+"
+ ;;
+
+ *)
+ $echo >> $output "\
+ exec \$progdir/\$program \${1+\"\$@\"}
+"
+ ;;
+ esac
+ $echo >> $output "\
+ \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\"
+ exit 1
+ fi
+ else
+ # The program doesn't exist.
+ \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2
+ \$echo \"This script is just a wrapper for \$program.\" 1>&2
+ $echo \"See the $PACKAGE documentation for more information.\" 1>&2
+ exit 1
+ fi
+fi\
+"
+ chmod +x $output
+ fi
+ exit 0
+ ;;
+ esac
+
+ # See if we need to build an old-fashioned archive.
+ for oldlib in $oldlibs; do
+
+ if test "$build_libtool_libs" = convenience; then
+ oldobjs="$libobjs_save"
+ addlibs="$convenience"
+ build_libtool_libs=no
+ else
+ if test "$build_libtool_libs" = module; then
+ oldobjs="$libobjs_save"
+ build_libtool_libs=no
+ else
+ oldobjs="$old_deplibs $non_pic_objects"
+ fi
+ addlibs="$old_convenience"
+ fi
+
+ if test -n "$addlibs"; then
+ gentop="$output_objdir/${outputname}x"
+ $show "${rm}r $gentop"
+ $run ${rm}r "$gentop"
+ $show "$mkdir $gentop"
+ $run $mkdir "$gentop"
+ status=$?
+ if test "$status" -ne 0 && test ! -d "$gentop"; then
+ exit $status
+ fi
+ generated="$generated $gentop"
+
+ # Add in members from convenience archives.
+ for xlib in $addlibs; do
+ # Extract the objects.
+ case $xlib in
+ [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+ *) xabs=`pwd`"/$xlib" ;;
+ esac
+ xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+ xdir="$gentop/$xlib"
+
+ $show "${rm}r $xdir"
+ $run ${rm}r "$xdir"
+ $show "$mkdir $xdir"
+ $run $mkdir "$xdir"
+ status=$?
+ if test "$status" -ne 0 && test ! -d "$xdir"; then
+ exit $status
+ fi
+ # We will extract separately just the conflicting names and we will no
+ # longer touch any unique names. It is faster to leave these extract
+ # automatically by $AR in one run.
+ $show "(cd $xdir && $AR x $xabs)"
+ $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+ if ($AR t "$xabs" | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ $echo "$modename: warning: object name conflicts; renaming object files" 1>&2
+ $echo "$modename: warning: to ensure that they will not overwrite" 1>&2
+ $AR t "$xabs" | sort | uniq -cd | while read -r count name
+ do
+ i=1
+ while test "$i" -le "$count"
+ do
+ # Put our $i before any first dot (extension)
+ # Never overwrite any file
+ name_to="$name"
+ while test "X$name_to" = "X$name" || test -f "$xdir/$name_to"
+ do
+ name_to=`$echo "X$name_to" | $Xsed -e "s/\([^.]*\)/\1-$i/"`
+ done
+ $show "(cd $xdir && $AR xN $i $xabs '$name' && $mv '$name' '$name_to')"
+ $run eval "(cd \$xdir && $AR xN $i \$xabs '$name' && $mv '$name' '$name_to')" || exit $?
+ i=`expr $i + 1`
+ done
+ done
+ fi
+
+ oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP`
+ done
+ fi
+
+ compiler_flags="$compiler_flags $add_flags"
+
+ # Do each command in the archive commands.
+ if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+ eval cmds=\"$old_archive_from_new_cmds\"
+ else
+ eval cmds=\"$old_archive_cmds\"
+
+ if len=`expr "X$cmds" : ".*"` &&
+ test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ :
+ else
+ # the command line is too long to link in one step, link in parts
+ $echo "using piecewise archive linking..."
+ save_RANLIB=$RANLIB
+ RANLIB=:
+ objlist=
+ concat_cmds=
+ save_oldobjs=$oldobjs
+ # GNU ar 2.10+ was changed to match POSIX; thus no paths are
+ # encoded into archives. This makes 'ar r' malfunction in
+ # this piecewise linking case whenever conflicting object
+ # names appear in distinct ar calls; check, warn and compensate.
+ if (for obj in $save_oldobjs
+ do
+ $echo "X$obj" | $Xsed -e 's%^.*/%%'
+ done | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ $echo "$modename: warning: object name conflicts; overriding AR_FLAGS to 'cq'" 1>&2
+ $echo "$modename: warning: to ensure that POSIX-compatible ar will work" 1>&2
+ AR_FLAGS=cq
+ fi
+ # Is there a better way of finding the last object in the list?
+ for obj in $save_oldobjs
+ do
+ last_oldobj=$obj
+ done
+ for obj in $save_oldobjs
+ do
+ oldobjs="$objlist $obj"
+ objlist="$objlist $obj"
+ eval test_cmds=\"$old_archive_cmds\"
+ if len=`expr "X$test_cmds" : ".*"` &&
+ test "$len" -le "$max_cmd_len"; then
+ :
+ else
+ # the above command should be used before it gets too long
+ oldobjs=$objlist
+ if test "$obj" = "$last_oldobj" ; then
+ RANLIB=$save_RANLIB
+ fi
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
+ objlist=
+ fi
+ done
+ RANLIB=$save_RANLIB
+ oldobjs=$objlist
+ if test "X$oldobjs" = "X" ; then
+ eval cmds=\"\$concat_cmds\"
+ else
+ eval cmds=\"\$concat_cmds~$old_archive_cmds\"
+ fi
+ fi
+ fi
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ done
+
+ if test -n "$generated"; then
+ $show "${rm}r$generated"
+ $run ${rm}r$generated
+ fi
+
+ # Now create the libtool archive.
+ case $output in
+ *.la)
+ old_library=
+ test "$build_old_libs" = yes && old_library="$libname.$libext"
+ $show "creating $output"
+
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"`
+ relink_command="$var=\"$var_value\"; export $var; $relink_command"
+ fi
+ done
+ # Quote the link command for shipping.
+ relink_command="(cd `pwd`; $SHELL $0 --mode=relink $libtool_args @inst_prefix_dir@)"
+ relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+ if test "$hardcode_automatic" = yes ; then
+ relink_command=
+ fi
+ # Only create the output if not a dry run.
+ if test -z "$run"; then
+ for installed in no yes; do
+ if test "$installed" = yes; then
+ if test -z "$install_libdir"; then
+ break
+ fi
+ output="$output_objdir/$outputname"i
+ # Replace all uninstalled libtool libraries with the installed ones
+ newdependency_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ *.la)
+ name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'`
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+ if test -z "$libdir"; then
+ $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
+ exit 1
+ fi
+ newdependency_libs="$newdependency_libs $libdir/$name"
+ ;;
+ *) newdependency_libs="$newdependency_libs $deplib" ;;
+ esac
+ done
+ dependency_libs="$newdependency_libs"
+ newdlfiles=
+ for lib in $dlfiles; do
+ name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ if test -z "$libdir"; then
+ $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+ exit 1
+ fi
+ newdlfiles="$newdlfiles $libdir/$name"
+ done
+ dlfiles="$newdlfiles"
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ if test -z "$libdir"; then
+ $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+ exit 1
+ fi
+ newdlprefiles="$newdlprefiles $libdir/$name"
+ done
+ dlprefiles="$newdlprefiles"
+ fi
+ $rm $output
+ # place dlname in correct position for cygwin
+ tdlname=$dlname
+ case $host,$output,$installed,$module,$dlname in
+ *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;;
+ esac
+ $echo > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+ if test "$installed" = no && test "$need_relink" = yes && test "$fast_install" = no; then
+ $echo >> $output "\
+relink_command=\"$relink_command\""
+ fi
+ done
+ fi
+
+ # Do a symbolic link so that the libtool archive can be found in
+ # LD_LIBRARY_PATH before the program is installed.
+ $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)"
+ $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $?
+ ;;
+ esac
+ exit 0
+ ;;
+
+ # libtool install mode
+ install)
+ modename="$modename: install"
+
+ # There may be an optional sh(1) argument at the beginning of
+ # install_prog (especially on Windows NT).
+ if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
+ # Allow the use of GNU shtool's install command.
+ $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; then
+ # Aesthetically quote it.
+ arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
+ case $arg in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ install_prog="$arg "
+ arg="$1"
+ shift
+ else
+ install_prog=
+ arg="$nonopt"
+ fi
+
+ # The real first argument should be the name of the installation program.
+ # Aesthetically quote it.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case $arg in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ install_prog="$install_prog$arg"
+
+ # We need to accept at least all the BSD install flags.
+ dest=
+ files=
+ opts=
+ prev=
+ install_type=
+ isdir=no
+ stripme=
+ for arg
+ do
+ if test -n "$dest"; then
+ files="$files $dest"
+ dest="$arg"
+ continue
+ fi
+
+ case $arg in
+ -d) isdir=yes ;;
+ -f) prev="-f" ;;
+ -g) prev="-g" ;;
+ -m) prev="-m" ;;
+ -o) prev="-o" ;;
+ -s)
+ stripme=" -s"
+ continue
+ ;;
+ -*) ;;
+
+ *)
+ # If the previous option needed an argument, then skip it.
+ if test -n "$prev"; then
+ prev=
+ else
+ dest="$arg"
+ continue
+ fi
+ ;;
+ esac
+
+ # Aesthetically quote the argument.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case $arg in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ install_prog="$install_prog $arg"
+ done
+
+ if test -z "$install_prog"; then
+ $echo "$modename: you must specify an install program" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ if test -n "$prev"; then
+ $echo "$modename: the \`$prev' option requires an argument" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ if test -z "$files"; then
+ if test -z "$dest"; then
+ $echo "$modename: no file or destination specified" 1>&2
+ else
+ $echo "$modename: you must specify a destination" 1>&2
+ fi
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Strip any trailing slash from the destination.
+ dest=`$echo "X$dest" | $Xsed -e 's%/$%%'`
+
+ # Check to see that the destination is a directory.
+ test -d "$dest" && isdir=yes
+ if test "$isdir" = yes; then
+ destdir="$dest"
+ destname=
+ else
+ destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$destdir" = "X$dest" && destdir=.
+ destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'`
+
+ # Not a directory, so check to see that there is only one file specified.
+ set dummy $files
+ if test "$#" -gt 2; then
+ $echo "$modename: \`$dest' is not a directory" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+ fi
+ case $destdir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ for file in $files; do
+ case $file in
+ *.lo) ;;
+ *)
+ $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ staticlibs=
+ future_libdirs=
+ current_libdirs=
+ for file in $files; do
+
+ # Do each installation.
+ case $file in
+ *.$libext)
+ # Do the static libraries later.
+ staticlibs="$staticlibs $file"
+ ;;
+
+ *.la)
+ # Check to see that this really is a libtool archive.
+ if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+ else
+ $echo "$modename: \`$file' is not a valid libtool archive" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ library_names=
+ old_library=
+ relink_command=
+ # If there is no directory component, then add one.
+ case $file in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Add the libdir to current_libdirs if it is the destination.
+ if test "X$destdir" = "X$libdir"; then
+ case "$current_libdirs " in
+ *" $libdir "*) ;;
+ *) current_libdirs="$current_libdirs $libdir" ;;
+ esac
+ else
+ # Note the libdir as a future libdir.
+ case "$future_libdirs " in
+ *" $libdir "*) ;;
+ *) future_libdirs="$future_libdirs $libdir" ;;
+ esac
+ fi
+
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/
+ test "X$dir" = "X$file/" && dir=
+ dir="$dir$objdir"
+
+ if test -n "$relink_command"; then
+ # Determine the prefix the user has applied to our future dir.
+ inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"`
+
+ # Don't allow the user to place us outside of our expected
+ # location b/c this prevents finding dependent libraries that
+ # are installed to the same prefix.
+ # At present, this check doesn't affect windows .dll's that
+ # are installed into $libdir/../bin (currently, that works fine)
+ # but it's something to keep an eye on.
+ if test "$inst_prefix_dir" = "$destdir"; then
+ $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2
+ exit 1
+ fi
+
+ if test -n "$inst_prefix_dir"; then
+ # Stick the inst_prefix_dir data into the link command.
+ relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+ else
+ relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
+ fi
+
+ $echo "$modename: warning: relinking \`$file'" 1>&2
+ $show "$relink_command"
+ if $run eval "$relink_command"; then :
+ else
+ $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+ exit 1
+ fi
+ fi
+
+ # See the names of the shared library.
+ set dummy $library_names
+ if test -n "$2"; then
+ realname="$2"
+ shift
+ shift
+
+ srcname="$realname"
+ test -n "$relink_command" && srcname="$realname"T
+
+ # Install the shared library and build the symlinks.
+ $show "$install_prog $dir/$srcname $destdir/$realname"
+ $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $?
+ if test -n "$stripme" && test -n "$striplib"; then
+ $show "$striplib $destdir/$realname"
+ $run eval "$striplib $destdir/$realname" || exit $?
+ fi
+
+ if test "$#" -gt 0; then
+ # Delete the old symlinks, and create new ones.
+ for linkname
+ do
+ if test "$linkname" != "$realname"; then
+ $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+ $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+ fi
+ done
+ fi
+
+ # Do each command in the postinstall commands.
+ lib="$destdir/$realname"
+ eval cmds=\"$postinstall_cmds\"
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ fi
+
+ # Install the pseudo-library for information purposes.
+ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ instname="$dir/$name"i
+ $show "$install_prog $instname $destdir/$name"
+ $run eval "$install_prog $instname $destdir/$name" || exit $?
+
+ # Maybe install the static library, too.
+ test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+ ;;
+
+ *.lo)
+ # Install (i.e. copy) a libtool object.
+
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ destfile="$destdir/$destfile"
+ fi
+
+ # Deduce the name of the destination old-style object file.
+ case $destfile in
+ *.lo)
+ staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"`
+ ;;
+ *.$objext)
+ staticdest="$destfile"
+ destfile=
+ ;;
+ *)
+ $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+ esac
+
+ # Install the libtool object if requested.
+ if test -n "$destfile"; then
+ $show "$install_prog $file $destfile"
+ $run eval "$install_prog $file $destfile" || exit $?
+ fi
+
+ # Install the old object if enabled.
+ if test "$build_old_libs" = yes; then
+ # Deduce the name of the old-style object file.
+ staticobj=`$echo "X$file" | $Xsed -e "$lo2o"`
+
+ $show "$install_prog $staticobj $staticdest"
+ $run eval "$install_prog \$staticobj \$staticdest" || exit $?
+ fi
+ exit 0
+ ;;
+
+ *)
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ destfile="$destdir/$destfile"
+ fi
+
+ # If the file is missing, and there is a .exe on the end, strip it
+ # because it is most likely a libtool script we actually want to
+ # install
+ stripped_ext=""
+ case $file in
+ *.exe)
+ if test ! -f "$file"; then
+ file=`$echo $file|${SED} 's,.exe$,,'`
+ stripped_ext=".exe"
+ fi
+ ;;
+ esac
+
+ # Do a test to see if this is really a libtool program.
+ case $host in
+ *cygwin*|*mingw*)
+ wrapper=`$echo $file | ${SED} -e 's,.exe$,,'`
+ ;;
+ *)
+ wrapper=$file
+ ;;
+ esac
+ if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then
+ notinst_deplibs=
+ relink_command=
+
+ # To insure that "foo" is sourced, and not "foo.exe",
+ # finese the cygwin/MSYS system by explicitly sourcing "foo."
+ # which disallows the automatic-append-.exe behavior.
+ case $build in
+ *cygwin* | *mingw*) wrapperdot=${wrapper}. ;;
+ *) wrapperdot=${wrapper} ;;
+ esac
+ # If there is no directory component, then add one.
+ case $file in
+ */* | *\\*) . ${wrapperdot} ;;
+ *) . ./${wrapperdot} ;;
+ esac
+
+ # Check the variables that should have been set.
+ if test -z "$notinst_deplibs"; then
+ $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2
+ exit 1
+ fi
+
+ finalize=yes
+ for lib in $notinst_deplibs; do
+ # Check to see that each library is installed.
+ libdir=
+ if test -f "$lib"; then
+ # If there is no directory component, then add one.
+ case $lib in
+ */* | *\\*) . $lib ;;
+ *) . ./$lib ;;
+ esac
+ fi
+ libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test
+ if test -n "$libdir" && test ! -f "$libfile"; then
+ $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2
+ finalize=no
+ fi
+ done
+
+ relink_command=
+ # To insure that "foo" is sourced, and not "foo.exe",
+ # finese the cygwin/MSYS system by explicitly sourcing "foo."
+ # which disallows the automatic-append-.exe behavior.
+ case $build in
+ *cygwin* | *mingw*) wrapperdot=${wrapper}. ;;
+ *) wrapperdot=${wrapper} ;;
+ esac
+ # If there is no directory component, then add one.
+ case $file in
+ */* | *\\*) . ${wrapperdot} ;;
+ *) . ./${wrapperdot} ;;
+ esac
+
+ outputname=
+ if test "$fast_install" = no && test -n "$relink_command"; then
+ if test "$finalize" = yes && test -z "$run"; then
+ tmpdir="/tmp"
+ test -n "$TMPDIR" && tmpdir="$TMPDIR"
+ tmpdir="$tmpdir/libtool-$$"
+ if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then :
+ else
+ $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2
+ continue
+ fi
+ file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'`
+ outputname="$tmpdir/$file"
+ # Replace the output file specification.
+ relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
+
+ $show "$relink_command"
+ if $run eval "$relink_command"; then :
+ else
+ $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+ ${rm}r "$tmpdir"
+ continue
+ fi
+ file="$outputname"
+ else
+ $echo "$modename: warning: cannot relink \`$file'" 1>&2
+ fi
+ else
+ # Install the binary that we compiled earlier.
+ file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+ fi
+ fi
+
+ # remove .exe since cygwin /usr/bin/install will append another
+ # one anyways
+ case $install_prog,$host in
+ */usr/bin/install*,*cygwin*)
+ case $file:$destfile in
+ *.exe:*.exe)
+ # this is ok
+ ;;
+ *.exe:*)
+ destfile=$destfile.exe
+ ;;
+ *:*.exe)
+ destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'`
+ ;;
+ esac
+ ;;
+ esac
+ $show "$install_prog$stripme $file $destfile"
+ $run eval "$install_prog\$stripme \$file \$destfile" || exit $?
+ test -n "$outputname" && ${rm}r "$tmpdir"
+ ;;
+ esac
+ done
+
+ for file in $staticlibs; do
+ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+ # Set up the ranlib parameters.
+ oldlib="$destdir/$name"
+
+ $show "$install_prog $file $oldlib"
+ $run eval "$install_prog \$file \$oldlib" || exit $?
+
+ if test -n "$stripme" && test -n "$striplib"; then
+ $show "$old_striplib $oldlib"
+ $run eval "$old_striplib $oldlib" || exit $?
+ fi
+
+ # Do each command in the postinstall commands.
+ eval cmds=\"$old_postinstall_cmds\"
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ done
+
+ if test -n "$future_libdirs"; then
+ $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2
+ fi
+
+ if test -n "$current_libdirs"; then
+ # Maybe just do a dry run.
+ test -n "$run" && current_libdirs=" -n$current_libdirs"
+ exec_cmd='$SHELL $0 --finish$current_libdirs'
+ else
+ exit 0
+ fi
+ ;;
+
+ # libtool finish mode
+ finish)
+ modename="$modename: finish"
+ libdirs="$nonopt"
+ admincmds=
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ for dir
+ do
+ libdirs="$libdirs $dir"
+ done
+
+ for libdir in $libdirs; do
+ if test -n "$finish_cmds"; then
+ # Do each command in the finish commands.
+ eval cmds=\"$finish_cmds\"
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || admincmds="$admincmds
+ $cmd"
+ done
+ IFS="$save_ifs"
+ fi
+ if test -n "$finish_eval"; then
+ # Do the single finish_eval.
+ eval cmds=\"$finish_eval\"
+ $run eval "$cmds" || admincmds="$admincmds
+ $cmds"
+ fi
+ done
+ fi
+
+ # Exit here if they wanted silent mode.
+ exit 0
+
+ $echo "----------------------------------------------------------------------"
+ $echo "Libraries have been installed in:"
+ for libdir in $libdirs; do
+ $echo " $libdir"
+ done
+ $echo
+ $echo "If you ever happen to want to link against installed libraries"
+ $echo "in a given directory, LIBDIR, you must either use libtool, and"
+ $echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
+ $echo "flag during linking and do at least one of the following:"
+ if test -n "$shlibpath_var"; then
+ $echo " - add LIBDIR to the \`$shlibpath_var' environment variable"
+ $echo " during execution"
+ fi
+ if test -n "$runpath_var"; then
+ $echo " - add LIBDIR to the \`$runpath_var' environment variable"
+ $echo " during linking"
+ fi
+ if test -n "$hardcode_libdir_flag_spec"; then
+ libdir=LIBDIR
+ eval flag=\"$hardcode_libdir_flag_spec\"
+
+ $echo " - use the \`$flag' linker flag"
+ fi
+ if test -n "$admincmds"; then
+ $echo " - have your system administrator run these commands:$admincmds"
+ fi
+ if test -f /etc/ld.so.conf; then
+ $echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+ fi
+ $echo
+ $echo "See any operating system documentation about shared libraries for"
+ $echo "more information, such as the ld(1) and ld.so(8) manual pages."
+ $echo "----------------------------------------------------------------------"
+ exit 0
+ ;;
+
+ # libtool execute mode
+ execute)
+ modename="$modename: execute"
+
+ # The first argument is the command name.
+ cmd="$nonopt"
+ if test -z "$cmd"; then
+ $echo "$modename: you must specify a COMMAND" 1>&2
+ $echo "$help"
+ exit 1
+ fi
+
+ # Handle -dlopen flags immediately.
+ for file in $execute_dlfiles; do
+ if test ! -f "$file"; then
+ $echo "$modename: \`$file' is not a file" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ dir=
+ case $file in
+ *.la)
+ # Check to see that this really is a libtool archive.
+ if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+ else
+ $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Read the libtool library.
+ dlname=
+ library_names=
+
+ # If there is no directory component, then add one.
+ case $file in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Skip this library if it cannot be dlopened.
+ if test -z "$dlname"; then
+ # Warn if it was a shared library.
+ test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'"
+ continue
+ fi
+
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$dir" = "X$file" && dir=.
+
+ if test -f "$dir/$objdir/$dlname"; then
+ dir="$dir/$objdir"
+ else
+ $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
+ exit 1
+ fi
+ ;;
+
+ *.lo)
+ # Just add the directory containing the .lo file.
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$dir" = "X$file" && dir=.
+ ;;
+
+ *)
+ $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2
+ continue
+ ;;
+ esac
+
+ # Get the absolute pathname.
+ absdir=`cd "$dir" && pwd`
+ test -n "$absdir" && dir="$absdir"
+
+ # Now add the directory to shlibpath_var.
+ if eval "test -z \"\$$shlibpath_var\""; then
+ eval "$shlibpath_var=\"\$dir\""
+ else
+ eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+ fi
+ done
+
+ # This variable tells wrapper scripts just to set shlibpath_var
+ # rather than running their programs.
+ libtool_execute_magic="$magic"
+
+ # Check if any of the arguments is a wrapper script.
+ args=
+ for file
+ do
+ case $file in
+ -*) ;;
+ *)
+ # Do a test to see if this is really a libtool program.
+ if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ # If there is no directory component, then add one.
+ case $file in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Transform arg to wrapped name.
+ file="$progdir/$program"
+ fi
+ ;;
+ esac
+ # Quote arguments (to preserve shell metacharacters).
+ file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"`
+ args="$args \"$file\""
+ done
+
+ if test -z "$run"; then
+ if test -n "$shlibpath_var"; then
+ # Export the shlibpath_var.
+ eval "export $shlibpath_var"
+ fi
+
+ # Restore saved environment variables
+ if test "${save_LC_ALL+set}" = set; then
+ LC_ALL="$save_LC_ALL"; export LC_ALL
+ fi
+ if test "${save_LANG+set}" = set; then
+ LANG="$save_LANG"; export LANG
+ fi
+
+ # Now prepare to actually exec the command.
+ exec_cmd="\$cmd$args"
+ else
+ # Display what would be done.
+ if test -n "$shlibpath_var"; then
+ eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\""
+ $echo "export $shlibpath_var"
+ fi
+ $echo "$cmd$args"
+ exit 0
+ fi
+ ;;
+
+ # libtool clean and uninstall mode
+ clean | uninstall)
+ modename="$modename: $mode"
+ rm="$nonopt"
+ files=
+ rmforce=
+ exit_status=0
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ for arg
+ do
+ case $arg in
+ -f) rm="$rm $arg"; rmforce=yes ;;
+ -*) rm="$rm $arg" ;;
+ *) files="$files $arg" ;;
+ esac
+ done
+
+ if test -z "$rm"; then
+ $echo "$modename: you must specify an RM program" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ rmdirs=
+
+ origobjdir="$objdir"
+ for file in $files; do
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$dir" = "X$file"; then
+ dir=.
+ objdir="$origobjdir"
+ else
+ objdir="$dir/$origobjdir"
+ fi
+ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ test "$mode" = uninstall && objdir="$dir"
+
+ # Remember objdir for removal later, being careful to avoid duplicates
+ if test "$mode" = clean; then
+ case " $rmdirs " in
+ *" $objdir "*) ;;
+ *) rmdirs="$rmdirs $objdir" ;;
+ esac
+ fi
+
+ # Don't error if the file doesn't exist and rm -f was used.
+ if (test -L "$file") >/dev/null 2>&1 \
+ || (test -h "$file") >/dev/null 2>&1 \
+ || test -f "$file"; then
+ :
+ elif test -d "$file"; then
+ exit_status=1
+ continue
+ elif test "$rmforce" = yes; then
+ continue
+ fi
+
+ rmfiles="$file"
+
+ case $name in
+ *.la)
+ # Possibly a libtool archive, so verify it.
+ if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ . $dir/$name
+
+ # Delete the libtool libraries and symlinks.
+ for n in $library_names; do
+ rmfiles="$rmfiles $objdir/$n"
+ done
+ test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library"
+ test "$mode" = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
+
+ if test "$mode" = uninstall; then
+ if test -n "$library_names"; then
+ # Do each command in the postuninstall commands.
+ eval cmds=\"$postuninstall_cmds\"
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd"
+ if test "$?" -ne 0 && test "$rmforce" != yes; then
+ exit_status=1
+ fi
+ done
+ IFS="$save_ifs"
+ fi
+
+ if test -n "$old_library"; then
+ # Do each command in the old_postuninstall commands.
+ eval cmds=\"$old_postuninstall_cmds\"
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd"
+ if test "$?" -ne 0 && test "$rmforce" != yes; then
+ exit_status=1
+ fi
+ done
+ IFS="$save_ifs"
+ fi
+ # FIXME: should reinstall the best remaining shared library.
+ fi
+ fi
+ ;;
+
+ *.lo)
+ # Possibly a libtool object, so verify it.
+ if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+
+ # Read the .lo file
+ . $dir/$name
+
+ # Add PIC object to the list of files to remove.
+ if test -n "$pic_object" \
+ && test "$pic_object" != none; then
+ rmfiles="$rmfiles $dir/$pic_object"
+ fi
+
+ # Add non-PIC object to the list of files to remove.
+ if test -n "$non_pic_object" \
+ && test "$non_pic_object" != none; then
+ rmfiles="$rmfiles $dir/$non_pic_object"
+ fi
+ fi
+ ;;
+
+ *)
+ if test "$mode" = clean ; then
+ noexename=$name
+ case $file in
+ *.exe)
+ file=`$echo $file|${SED} 's,.exe$,,'`
+ noexename=`$echo $name|${SED} 's,.exe$,,'`
+ # $file with .exe has already been added to rmfiles,
+ # add $file without .exe
+ rmfiles="$rmfiles $file"
+ ;;
+ esac
+ # Do a test to see if this is a libtool program.
+ if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ relink_command=
+ . $dir/$noexename
+
+ # note $name still contains .exe if it was in $file originally
+ # as does the version of $file that was added into $rmfiles
+ rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}"
+ if test "$fast_install" = yes && test -n "$relink_command"; then
+ rmfiles="$rmfiles $objdir/lt-$name"
+ fi
+ if test "X$noexename" != "X$name" ; then
+ rmfiles="$rmfiles $objdir/lt-${noexename}.c"
+ fi
+ fi
+ fi
+ ;;
+ esac
+ $show "$rm $rmfiles"
+ $run $rm $rmfiles || exit_status=1
+ done
+ objdir="$origobjdir"
+
+ # Try to remove the ${objdir}s in the directories where we deleted files
+ for dir in $rmdirs; do
+ if test -d "$dir"; then
+ $show "rmdir $dir"
+ $run rmdir $dir >/dev/null 2>&1
+ fi
+ done
+
+ exit $exit_status
+ ;;
+
+ "")
+ $echo "$modename: you must specify a MODE" 1>&2
+ $echo "$generic_help" 1>&2
+ exit 1
+ ;;
+ esac
+
+ if test -z "$exec_cmd"; then
+ $echo "$modename: invalid operation mode \`$mode'" 1>&2
+ $echo "$generic_help" 1>&2
+ exit 1
+ fi
+fi # test -z "$show_help"
+
+if test -n "$exec_cmd"; then
+ eval exec $exec_cmd
+ exit 1
+fi
+
+# We need to display help for each of the modes.
+case $mode in
+"") $echo \
+"Usage: $modename [OPTION]... [MODE-ARG]...
+
+Provide generalized library-building support services.
+
+ --config show all configuration variables
+ --debug enable verbose shell tracing
+-n, --dry-run display commands without modifying any files
+ --features display basic configuration information and exit
+ --finish same as \`--mode=finish'
+ --help display this help message and exit
+ --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS]
+ --quiet same as \`--silent'
+ --silent don't print informational messages
+ --tag=TAG use configuration variables from tag TAG
+ --version print version information
+
+MODE must be one of the following:
+
+ clean remove files from the build directory
+ compile compile a source file into a libtool object
+ execute automatically set library path, then run a program
+ finish complete the installation of libtool libraries
+ install install libraries or executables
+ link create a library or an executable
+ uninstall remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for
+a more detailed description of MODE.
+
+Report bugs to <bug-libtool@gnu.org>."
+ exit 0
+ ;;
+
+clean)
+ $echo \
+"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+compile)
+ $echo \
+"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+ -o OUTPUT-FILE set the output file name to OUTPUT-FILE
+ -prefer-pic try to building PIC objects only
+ -prefer-non-pic try to building non-PIC objects only
+ -static always build a \`.o' file suitable for static linking
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+ ;;
+
+execute)
+ $echo \
+"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+ -dlopen FILE add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+ ;;
+
+finish)
+ $echo \
+"Usage: $modename [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges. Use
+the \`--dry-run' option if you just want to see what would be executed."
+ ;;
+
+install)
+ $echo \
+"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command. The first component should be
+either the \`install' or \`cp' program.
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+ ;;
+
+link)
+ $echo \
+"Usage: $modename [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+ -all-static do not do any dynamic linking at all
+ -avoid-version do not add a version suffix if possible
+ -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime
+ -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols
+ -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+ -export-symbols SYMFILE
+ try to export only the symbols listed in SYMFILE
+ -export-symbols-regex REGEX
+ try to export only the symbols matching REGEX
+ -LLIBDIR search LIBDIR for required installed libraries
+ -lNAME OUTPUT-FILE requires the installed library libNAME
+ -module build a library that can dlopened
+ -no-fast-install disable the fast-install mode
+ -no-install link a not-installable executable
+ -no-undefined declare that a library does not refer to external symbols
+ -o OUTPUT-FILE create OUTPUT-FILE from the specified objects
+ -objectlist FILE Use a list of object files found in FILE to specify objects
+ -release RELEASE specify package release information
+ -rpath LIBDIR the created library will eventually be installed in LIBDIR
+ -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries
+ -static do not do any dynamic linking of libtool libraries
+ -version-info CURRENT[:REVISION[:AGE]]
+ specify library version info [each variable defaults to 0]
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename. Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+ ;;
+
+uninstall)
+ $echo \
+"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+*)
+ $echo "$modename: invalid operation mode \`$mode'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+esac
+
+$echo
+$echo "Try \`$modename --help' for more information about other modes."
+
+exit 0
+
+# The TAGs below are defined such that we never get into a situation
+# in which we disable both kinds of libraries. Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them. This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration. But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+build_libtool_libs=no
+build_old_libs=yes
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+build_old_libs=`case $build_libtool_libs in yes) $echo no;; *) $echo yes;; esac`
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/tools/mhmake/m4.exe b/tools/mhmake/m4.exe
new file mode 100644
index 000000000..20bb51625
--- /dev/null
+++ b/tools/mhmake/m4.exe
Binary files differ
diff --git a/tools/mhmake/makebison.bat b/tools/mhmake/makebison.bat
new file mode 100644
index 000000000..9d46f535a
--- /dev/null
+++ b/tools/mhmake/makebison.bat
@@ -0,0 +1,4 @@
+@echo off
+"bison++" -d -Ssrc/bison.cc -Hsrc/bison.h -h%1/mhmakeparser.h -o%1/mhmakeparser.cpp src\mhmakeParser.y
+python addstdafxh.py %1\mhmakeparser.cpp
+
diff --git a/tools/mhmake/makefile b/tools/mhmake/makefile
new file mode 100644
index 000000000..b9aa0998b
--- /dev/null
+++ b/tools/mhmake/makefile
@@ -0,0 +1,25 @@
+ifdef VS2008
+MHMAKESLNFILE=mhmake.sln
+BUILDCMD=vcbuild $(MHMAKESLNFILE)
+else
+MHMAKESLNFILE=mhmakevc10.sln
+BUILDCMD=devenv.com $(MHMAKESLNFILE) /build
+endif
+
+.PHONY: all mhmake_dbg mhmake cleanthis
+
+all: debug\mhmake_dbg.exe release\mhmake.exe
+
+DEPS=$(wildcard src\*)
+
+debug\mhmake_dbg.exe: $(DEPS)
+ $(BUILDCMD) "Debug|Win32"
+
+release\mhmake.exe: $(DEPS)
+ $(BUILDCMD) "Release|Win32"
+
+clean: cleanthis
+
+cleanthis:
+ del -e Debug
+ del -e Release
diff --git a/tools/mhmake/makelex.bat b/tools/mhmake/makelex.bat
new file mode 100644
index 000000000..66d9255fa
--- /dev/null
+++ b/tools/mhmake/makelex.bat
@@ -0,0 +1,11 @@
+@echo off
+setlocal
+
+set M4=.\m4.exe
+
+"flex++" --nounistd -Ssrc/flex.skl -o%1/mhmakelexer.cpp src/mhmakelexer.l
+
+python addstdafxh.py %1\mhmakelexer.cpp
+
+endlocal
+
diff --git a/tools/mhmake/mhmake.kdev4 b/tools/mhmake/mhmake.kdev4
new file mode 100644
index 000000000..4eef88a1e
--- /dev/null
+++ b/tools/mhmake/mhmake.kdev4
@@ -0,0 +1,4 @@
+[Project]
+Name=mhmake
+Manager=KDevCMakeManager
+VersionControl=
diff --git a/tools/mhmake/mhmake.kdevelop b/tools/mhmake/mhmake.kdevelop
new file mode 100644
index 000000000..003b7032d
--- /dev/null
+++ b/tools/mhmake/mhmake.kdevelop
@@ -0,0 +1,247 @@
+<?xml version = '1.0'?>
+<kdevelop>
+ <general>
+ <author>marha</author>
+ <email>marc@hc-consult.be</email>
+ <version>1.1.12</version>
+ <projectmanagement>KDevAutoProject</projectmanagement>
+ <primarylanguage>C++</primarylanguage>
+ <keywords>
+ <keyword>C++</keyword>
+ <keyword>Code</keyword>
+ </keywords>
+ <versioncontrol>kdevsubversion</versioncontrol>
+ <ignoreparts/>
+ <projectdirectory>.</projectdirectory>
+ <absoluteprojectpath>false</absoluteprojectpath>
+ <description/>
+ <projectname>mhmake</projectname>
+ </general>
+ <kdevautoproject>
+ <general>
+ <activetarget>src/mhmake</activetarget>
+ <useconfiguration>debug</useconfiguration>
+ </general>
+ <run>
+ <mainprogram>/usr/local/bin/mhmake_dbg</mainprogram>
+ <terminal>false</terminal>
+ <directoryradio>custom</directoryradio>
+ <customdirectory>~/cm/tldtp/softdtp/common/</customdirectory>
+ <programargs/>
+ <autocompile>false</autocompile>
+ <envvars>
+ <envvar value="linux" name="BASEAUTOMAK" />
+ <envvar value="LINESIM" name="CONFIG" />
+ <envvar value="~/cm" name="MHMAKECONF" />
+ <envvar value="/bin/bash" name="SHELL" />
+ </envvars>
+ </run>
+ <configurations>
+ <optimized>
+ <builddir>release</builddir>
+ <ccompiler>kdevgccoptions</ccompiler>
+ <cxxcompiler>kdevgppoptions</cxxcompiler>
+ <f77compiler>kdevg77options</f77compiler>
+ <cxxflags>-O2 -g0</cxxflags>
+ <envvars/>
+ <configargs/>
+ <topsourcedir/>
+ <cppflags>-I. </cppflags>
+ <ldflags/>
+ <ccompilerbinary/>
+ <cxxcompilerbinary/>
+ <f77compilerbinary/>
+ <cflags/>
+ <f77flags/>
+ </optimized>
+ <debug>
+ <configargs>--enable-debug=full</configargs>
+ <builddir>debug</builddir>
+ <ccompiler>kdevgccoptions</ccompiler>
+ <cxxcompiler>kdevgppoptions</cxxcompiler>
+ <f77compiler>kdevg77options</f77compiler>
+ <cxxflags>-O0 -g3</cxxflags>
+ <envvars/>
+ <topsourcedir/>
+ <cppflags>-I. -D_DEBUG</cppflags>
+ <ldflags/>
+ <ccompilerbinary/>
+ <cxxcompilerbinary/>
+ <f77compilerbinary/>
+ <cflags/>
+ <f77flags/>
+ </debug>
+ </configurations>
+ <make>
+ <envvars>
+ <envvar value="1" name="WANT_AUTOCONF_2_5" />
+ <envvar value="1" name="WANT_AUTOMAKE_1_6" />
+ </envvars>
+ <abortonerror>true</abortonerror>
+ <numberofjobs>1</numberofjobs>
+ <dontact>false</dontact>
+ <makebin/>
+ <prio>0</prio>
+ </make>
+ </kdevautoproject>
+ <kdevdoctreeview>
+ <ignoretocs>
+ <toc>ada</toc>
+ <toc>ada_bugs_gcc</toc>
+ <toc>bash</toc>
+ <toc>bash_bugs</toc>
+ <toc>clanlib</toc>
+ <toc>w3c-dom-level2-html</toc>
+ <toc>fortran_bugs_gcc</toc>
+ <toc>gnome1</toc>
+ <toc>gnustep</toc>
+ <toc>gtk</toc>
+ <toc>gtk_bugs</toc>
+ <toc>haskell</toc>
+ <toc>haskell_bugs_ghc</toc>
+ <toc>java_bugs_gcc</toc>
+ <toc>java_bugs_sun</toc>
+ <toc>kde2book</toc>
+ <toc>opengl</toc>
+ <toc>pascal_bugs_fp</toc>
+ <toc>php</toc>
+ <toc>php_bugs</toc>
+ <toc>perl</toc>
+ <toc>perl_bugs</toc>
+ <toc>python</toc>
+ <toc>python_bugs</toc>
+ <toc>qt-kdev3</toc>
+ <toc>ruby</toc>
+ <toc>ruby_bugs</toc>
+ <toc>sdl</toc>
+ <toc>w3c-svg</toc>
+ <toc>sw</toc>
+ <toc>w3c-uaag10</toc>
+ <toc>wxwidgets_bugs</toc>
+ </ignoretocs>
+ <ignoreqt_xml>
+ <toc>Guide to the Qt Translation Tools</toc>
+ <toc>Qt Assistant Manual</toc>
+ <toc>Qt Designer Manual</toc>
+ <toc>Qt Reference Documentation</toc>
+ <toc>qmake User Guide</toc>
+ </ignoreqt_xml>
+ <ignoredoxygen>
+ <toc>KDE Libraries (Doxygen)</toc>
+ </ignoredoxygen>
+ </kdevdoctreeview>
+ <kdevfilecreate>
+ <filetypes/>
+ <useglobaltypes>
+ <type ext="cpp" />
+ <type ext="h" />
+ </useglobaltypes>
+ </kdevfilecreate>
+ <kdevfileview>
+ <groups>
+ <group pattern="*.h" name="Header files" />
+ <group pattern="*.cpp;*.c;*.cc" name="Source files" />
+ <group pattern="*.l" name="Lex Files" />
+ <group pattern="*.y" name="Bison Files" />
+ <hidenonprojectfiles>false</hidenonprojectfiles>
+ <hidenonlocation>false</hidenonlocation>
+ </groups>
+ <tree>
+ <hidepatterns>*.o,*.lo,CVS</hidepatterns>
+ <hidenonprojectfiles>false</hidenonprojectfiles>
+ <showvcsfields>false</showvcsfields>
+ </tree>
+ </kdevfileview>
+ <kdevdocumentation>
+ <projectdoc>
+ <docsystem>Doxygen Documentation Collection</docsystem>
+ <docurl>mhmake.tag</docurl>
+ <usermanualurl/>
+ </projectdoc>
+ </kdevdocumentation>
+ <substmap>
+ <APPNAME>mhmake</APPNAME>
+ <APPNAMELC>mhmake</APPNAMELC>
+ <APPNAMESC>Mhmake</APPNAMESC>
+ <APPNAMEUC>MHMAKE</APPNAMEUC>
+ <AUTHOR>marha</AUTHOR>
+ <EMAIL>marc@hc-consult.be</EMAIL>
+ <LICENSE>Custom</LICENSE>
+ <VERSION>0.1</VERSION>
+ <YEAR>2006</YEAR>
+ </substmap>
+ <cppsupportpart>
+ <filetemplates>
+ <interfacesuffix>.h</interfacesuffix>
+ <implementationsuffix>.cpp</implementationsuffix>
+ </filetemplates>
+ </cppsupportpart>
+ <kdevcppsupport>
+ <codecompletion>
+ <includeGlobalFunctions>true</includeGlobalFunctions>
+ <includeTypes>true</includeTypes>
+ <includeEnums>true</includeEnums>
+ <includeTypedefs>false</includeTypedefs>
+ <automaticCodeCompletion>true</automaticCodeCompletion>
+ <automaticArgumentsHint>true</automaticArgumentsHint>
+ <automaticHeaderCompletion>true</automaticHeaderCompletion>
+ <codeCompletionDelay>250</codeCompletionDelay>
+ <argumentsHintDelay>400</argumentsHintDelay>
+ <headerCompletionDelay>250</headerCompletionDelay>
+ <showOnlyAccessibleItems>false</showOnlyAccessibleItems>
+ <completionBoxItemOrder>0</completionBoxItemOrder>
+ <howEvaluationContextMenu>true</howEvaluationContextMenu>
+ <showCommentWithArgumentHint>true</showCommentWithArgumentHint>
+ <statusBarTypeEvaluation>false</statusBarTypeEvaluation>
+ <namespaceAliases>std=_GLIBCXX_STD;__gnu_cxx=std</namespaceAliases>
+ <processPrimaryTypes>true</processPrimaryTypes>
+ <processFunctionArguments>false</processFunctionArguments>
+ <preProcessAllHeaders>false</preProcessAllHeaders>
+ <parseMissingHeaders>false</parseMissingHeaders>
+ <resolveIncludePaths>true</resolveIncludePaths>
+ <alwaysParseInBackground>true</alwaysParseInBackground>
+ <usePermanentCaching>true</usePermanentCaching>
+ <alwaysIncludeNamespaces>false</alwaysIncludeNamespaces>
+ <includePaths>.;</includePaths>
+ <parseMissingHeadersExperimental>false</parseMissingHeadersExperimental>
+ <resolveIncludePathsUsingMakeExperimental>false</resolveIncludePathsUsingMakeExperimental>
+ </codecompletion>
+ <creategettersetter>
+ <prefixGet/>
+ <prefixSet>set</prefixSet>
+ <prefixVariable>m_,_</prefixVariable>
+ <parameterName>theValue</parameterName>
+ <inlineGet>true</inlineGet>
+ <inlineSet>true</inlineSet>
+ </creategettersetter>
+ <references/>
+ <qt>
+ <used>false</used>
+ <version>3</version>
+ <includestyle>3</includestyle>
+ <root></root>
+ <designerintegration>EmbeddedKDevDesigner</designerintegration>
+ <qmake>/usr/bin/qmake-qt3</qmake>
+ <designer>/usr/bin/designer</designer>
+ <designerpluginpaths/>
+ </qt>
+ </kdevcppsupport>
+ <kdevdebugger>
+ <general>
+ <programargs/>
+ <gdbpath/>
+ <dbgshell>libtool</dbgshell>
+ <configGdbScript/>
+ <runShellScript/>
+ <runGdbScript/>
+ <breakonloadinglibs>true</breakonloadinglibs>
+ <separatetty>false</separatetty>
+ <floatingtoolbar>false</floatingtoolbar>
+ </general>
+ <display>
+ <staticmembers>false</staticmembers>
+ <demanglenames>true</demanglenames>
+ <outputradix>10</outputradix>
+ </display>
+ </kdevdebugger>
+</kdevelop>
diff --git a/tools/mhmake/mhmake.sln b/tools/mhmake/mhmake.sln
new file mode 100644
index 000000000..7121b8286
--- /dev/null
+++ b/tools/mhmake/mhmake.sln
@@ -0,0 +1,31 @@
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mhmake", "mhmake.vcproj", "{7F1669C8-7974-45DF-9B71-0E2A8DC44C06}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Profile|Win32 = Profile|Win32
+ Profile|x64 = Profile|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {7F1669C8-7974-45DF-9B71-0E2A8DC44C06}.Debug|Win32.ActiveCfg = Debug|Win32
+ {7F1669C8-7974-45DF-9B71-0E2A8DC44C06}.Debug|Win32.Build.0 = Debug|Win32
+ {7F1669C8-7974-45DF-9B71-0E2A8DC44C06}.Debug|x64.ActiveCfg = Debug|x64
+ {7F1669C8-7974-45DF-9B71-0E2A8DC44C06}.Debug|x64.Build.0 = Debug|x64
+ {7F1669C8-7974-45DF-9B71-0E2A8DC44C06}.Profile|Win32.ActiveCfg = Profile|Win32
+ {7F1669C8-7974-45DF-9B71-0E2A8DC44C06}.Profile|Win32.Build.0 = Profile|Win32
+ {7F1669C8-7974-45DF-9B71-0E2A8DC44C06}.Profile|x64.ActiveCfg = Profile|x64
+ {7F1669C8-7974-45DF-9B71-0E2A8DC44C06}.Profile|x64.Build.0 = Profile|x64
+ {7F1669C8-7974-45DF-9B71-0E2A8DC44C06}.Release|Win32.ActiveCfg = Release|Win32
+ {7F1669C8-7974-45DF-9B71-0E2A8DC44C06}.Release|Win32.Build.0 = Release|Win32
+ {7F1669C8-7974-45DF-9B71-0E2A8DC44C06}.Release|x64.ActiveCfg = Release|x64
+ {7F1669C8-7974-45DF-9B71-0E2A8DC44C06}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/tools/mhmake/mhmake.vcproj b/tools/mhmake/mhmake.vcproj
new file mode 100644
index 000000000..9d8ad1db2
--- /dev/null
+++ b/tools/mhmake/mhmake.vcproj
@@ -0,0 +1,1012 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="mhmake"
+ ProjectGUID="{7F1669C8-7974-45DF-9B71-0E2A8DC44C06}"
+ RootNamespace="mhmake"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TypeLibraryName=".\Release/mhmake.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="1"
+ OmitFramePointers="true"
+ AdditionalIncludeDirectories=".,src,$(OutDir)"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE"
+ StringPooling="true"
+ ExceptionHandling="2"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="false"
+ EnableEnhancedInstructionSet="1"
+ RuntimeTypeInfo="false"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="stdafx.h"
+ AssemblerListingLocation="$(IntDir)"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ CallingConvention="1"
+ CompileAs="0"
+ DisableSpecificWarnings="4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ ProgramDatabaseFile=""
+ SubSystem="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release64"
+ IntermediateDirectory="Release64"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ TypeLibraryName=".\Release/mhmake.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="1"
+ OmitFramePointers="true"
+ AdditionalIncludeDirectories=".,src,$(OutDir)"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE"
+ StringPooling="true"
+ ExceptionHandling="2"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="false"
+ EnableEnhancedInstructionSet="0"
+ RuntimeTypeInfo="false"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="stdafx.h"
+ AssemblerListingLocation="$(IntDir)"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ CallingConvention="1"
+ CompileAs="0"
+ DisableSpecificWarnings="4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ SubSystem="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TypeLibraryName=".\Debug/mhmake.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=".,src,$(OutDir)"
+ PreprocessorDefinitions="_DEBUG;_CRTDBG_MAP_ALLOC;WIN32;_CONSOLE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="stdafx.h"
+ AssemblerListingLocation="$(IntDir)"
+ XMLDocumentationFileName="$(IntDir)"
+ BrowseInformation="1"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="3"
+ CompileAs="0"
+ DisableSpecificWarnings="4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(ConfigurationName)/mhmake_dbg.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="Debug64"
+ IntermediateDirectory="Debug64"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ TypeLibraryName=".\Debug/mhmake.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=".,src,$(OutDir)"
+ PreprocessorDefinitions="_DEBUG;_CRTDBG_MAP_ALLOC;WIN32;_CONSOLE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="stdafx.h"
+ AssemblerListingLocation="$(IntDir)"
+ XMLDocumentationFileName="$(IntDir)"
+ BrowseInformation="1"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="3"
+ CompileAs="0"
+ DisableSpecificWarnings="4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(ConfigurationName)/mhmake_dbg.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile=".\Debug/mhmake.pdb"
+ SubSystem="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Profile|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TypeLibraryName=".\Release/mhmake.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="1"
+ OmitFramePointers="true"
+ AdditionalIncludeDirectories=".,src,$(OutDir)"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE"
+ StringPooling="true"
+ ExceptionHandling="0"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="false"
+ EnableEnhancedInstructionSet="1"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="stdafx.h"
+ PrecompiledHeaderFile="$(ConfigurationName)/mhmake.pch"
+ ProgramDataBaseFileName="$(IntDir)/"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="3"
+ CallingConvention="1"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(ConfigurationName)/mhmake.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"
+ GenerateMapFile="true"
+ MapExports="true"
+ SubSystem="1"
+ RandomizedBaseAddress="1"
+ FixedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Profile|x64"
+ OutputDirectory="Profile64"
+ IntermediateDirectory="Profile64"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ TypeLibraryName=".\Release/mhmake.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="1"
+ OmitFramePointers="true"
+ AdditionalIncludeDirectories=".,src,$(OutDir)"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE"
+ StringPooling="true"
+ ExceptionHandling="0"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="false"
+ EnableEnhancedInstructionSet="1"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="stdafx.h"
+ PrecompiledHeaderFile="$(ConfigurationName)/mhmake.pch"
+ ProgramDataBaseFileName="$(IntDir)/"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="3"
+ CallingConvention="1"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(ConfigurationName)/mhmake.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"
+ GenerateMapFile="true"
+ MapExports="true"
+ SubSystem="1"
+ RandomizedBaseAddress="1"
+ FixedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+ >
+ <File
+ RelativePath=".\src\build.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\src\commandqueue.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\src\curdir.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\src\fileinfo.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\src\functions.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\src\md5.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\src\mhmake.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\src\mhmakefileparser.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\src\rule.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\src\stdafx.cpp"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Profile|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Profile|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug 64|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug 64|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release 64|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release 64|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\util.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl"
+ >
+ <File
+ RelativePath=".\src\commandqueue.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\curdir.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\fileinfo.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\md5.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\mhmakefileparser.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\refptr.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\rule.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\stdafx.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\util.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Parser Files"
+ Filter="l;y;cpp;h"
+ >
+ <File
+ RelativePath=".\src\mhmakeLexer.l"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="cmd.exe /c makelex.bat Release&#x0D;&#x0A;"
+ AdditionalDependencies=".\src\flexint.h;.\src\flex.skl;.\src\flexlexer.h;"
+ Outputs="$(OutDir)\$(InputName).cpp"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="cmd.exe /c makelex.bat Release64&#x0D;&#x0A;"
+ AdditionalDependencies=".\src\flexint.h;.\src\flex.skl;.\src\flexlexer.h;"
+ Outputs="$(OutDir)\$(InputName).cpp"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="cmd.exe /c makelex.bat Debug&#x0D;&#x0A;"
+ AdditionalDependencies=".\src\flexint.h;.\src\flex.skl;.\src\flexlexer.h;"
+ Outputs="$(OutDir)\$(InputName).cpp"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="cmd.exe /c makelex.bat Debug64&#x0D;&#x0A;"
+ AdditionalDependencies=".\src\flexint.h;.\src\flex.skl;.\src\flexlexer.h;"
+ Outputs="$(OutDir)\$(InputName).cpp"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Profile|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="cmd.exe /c makelex.bat Profile&#x0D;&#x0A;"
+ AdditionalDependencies=".\src\flexint.h;.\src\flex.skl;.\src\flexlexer.h;"
+ Outputs="$(OutDir)\$(InputName).cpp"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Profile|x64"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="cmd.exe /c makelex.bat Profile64&#x0D;&#x0A;"
+ AdditionalDependencies=".\src\flexint.h;.\src\flex.skl;.\src\flexlexer.h;"
+ Outputs="$(OutDir)\$(InputName).cpp"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug 64|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="cmd.exe /c makelex.bat Debug64&#x0D;&#x0A;"
+ AdditionalDependencies=".\src\flexint.h;.\src\flex.skl;.\src\flexlexer.h;"
+ Outputs="$(OutDir)\$(InputName).cpp"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug 64|x64"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="cmd.exe /c makelex.bat Debug64&#x0D;&#x0A;"
+ AdditionalDependencies=".\src\flexint.h;.\src\flex.skl;.\src\flexlexer.h;"
+ Outputs="$(OutDir)\$(InputName).cpp"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release 64|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="cmd.exe /c makelex.bat Release64&#x0D;&#x0A;"
+ AdditionalDependencies=".\src\flexint.h;.\src\flex.skl;.\src\flexlexer.h;"
+ Outputs="$(OutDir)\$(InputName).cpp"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release 64|x64"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="cmd.exe /c makelex.bat Release64&#x0D;&#x0A;"
+ AdditionalDependencies=".\src\flexint.h;.\src\flex.skl;.\src\flexlexer.h;"
+ Outputs="$(OutDir)\$(InputName).cpp"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\mhmakeParser.y"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="cmd.exe /c makebison.bat Release&#x0D;&#x0A;"
+ AdditionalDependencies=".\src\bison.cc;.\src\bison.h;"
+ Outputs="$(OutDir)\$(InputName).cpp;$(OutDir)\$(InputName).h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="cmd.exe /c makebison.bat Release64&#x0D;&#x0A;"
+ AdditionalDependencies=".\src\bison.cc;.\src\bison.h;"
+ Outputs="$(OutDir)\$(InputName).cpp;$(OutDir)\$(InputName).h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="cmd.exe /c makebison.bat Debug&#x0D;&#x0A;"
+ AdditionalDependencies=".\src\bison.cc;.\src\bison.h;"
+ Outputs="$(OutDir)\$(InputName).cpp;$(OutDir)\$(InputName).h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="cmd.exe /c makebison.bat Debug64&#x0D;&#x0A;"
+ AdditionalDependencies=".\src\bison.cc;.\src\bison.h;"
+ Outputs="$(OutDir)\$(InputName).cpp;$(OutDir)\$(InputName).h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Profile|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="cmd.exe /c makebison.bat Profile&#x0D;&#x0A;"
+ AdditionalDependencies=".\src\bison.cc;.\src\bison.h;"
+ Outputs="$(OutDir)\$(InputName).cpp;$(OutDir)\$(InputName).h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Profile|x64"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="cmd.exe /c makebison.bat Profile64&#x0D;&#x0A;"
+ AdditionalDependencies=".\src\bison.cc;.\src\bison.h;"
+ Outputs="$(OutDir)\$(InputName).cpp;$(OutDir)\$(InputName).h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug 64|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="cmd.exe /c makebison.bat Debug64&#x0D;&#x0A;"
+ AdditionalDependencies=".\src\bison.cc;.\src\bison.h;"
+ Outputs="$(OutDir)\$(InputName).cpp;$(OutDir)\$(InputName).h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug 64|x64"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="cmd.exe /c makebison.bat Debug64&#x0D;&#x0A;"
+ AdditionalDependencies=".\src\bison.cc;.\src\bison.h;"
+ Outputs="$(OutDir)\$(InputName).cpp;$(OutDir)\$(InputName).h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release 64|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="cmd.exe /c makebison.bat Release64&#x0D;&#x0A;"
+ AdditionalDependencies=".\src\bison.cc;.\src\bison.h;"
+ Outputs="$(OutDir)\$(InputName).cpp;$(OutDir)\$(InputName).h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release 64|x64"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ CommandLine="cmd.exe /c makebison.bat Release64&#x0D;&#x0A;"
+ AdditionalDependencies=".\src\bison.cc;.\src\bison.h;"
+ Outputs="$(OutDir)\$(InputName).cpp;$(OutDir)\$(InputName).h"
+ />
+ </FileConfiguration>
+ </File>
+ <Filter
+ Name="Auto"
+ Filter="cpp;h"
+ >
+ <File
+ RelativePath="$(OutDir)\mhmakelexer.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(OutDir)\mhmakeparser.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(OutDir)\mhmakeparser.h"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+ >
+ </Filter>
+ <File
+ RelativePath=".\src\bison.h"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/tools/mhmake/mhmake.vcxproj b/tools/mhmake/mhmake.vcxproj
new file mode 100644
index 000000000..c5c548c77
--- /dev/null
+++ b/tools/mhmake/mhmake.vcxproj
@@ -0,0 +1,478 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Profile|Win32">
+ <Configuration>Profile</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Profile|x64">
+ <Configuration>Profile</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{7F1669C8-7974-45DF-9B71-0E2A8DC44C06}</ProjectGuid>
+ <RootNamespace>mhmake</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Release64\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Release64\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Debug64\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Debug64\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">Profile64\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">Profile64\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">false</LinkIncremental>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">mhmake_dbg</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">mhmake_dbg</TargetName>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Midl>
+ <TypeLibraryName>.\Release/mhmake.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>.;src;$(OutDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>NDEBUG;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>false</FunctionLevelLinking>
+ <EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <CallingConvention>FastCall</CallingConvention>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <ProgramDatabaseFile>
+ </ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ <TypeLibraryName>.\Release/mhmake.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>.;src;$(OutDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>NDEBUG;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>Async</ExceptionHandling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>false</FunctionLevelLinking>
+ <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <CallingConvention>FastCall</CallingConvention>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <SubSystem>Console</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Midl>
+ <TypeLibraryName>.\Debug/mhmake.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>.;src;$(OutDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_DEBUG;_CRTDBG_MAP_ALLOC;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <XMLDocumentationFileName>$(IntDir)</XMLDocumentationFileName>
+ <BrowseInformation>true</BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ <TypeLibraryName>.\Debug/mhmake.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>.;src;$(OutDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_DEBUG;_CRTDBG_MAP_ALLOC;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <XMLDocumentationFileName>$(IntDir)</XMLDocumentationFileName>
+ <BrowseInformation>true</BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Link>
+ <OutputFile>$(OutDir)\mhmake_dbg.exe</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>.\Debug/mhmake.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">
+ <Midl>
+ <TypeLibraryName>.\Release/mhmake.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>.;src;$(OutDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>NDEBUG;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>false</FunctionLevelLinking>
+ <EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
+ <PrecompiledHeaderOutputFile>$(Configuration)/mhmake.pch</PrecompiledHeaderOutputFile>
+ <ProgramDataBaseFileName>$(IntDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CallingConvention>FastCall</CallingConvention>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)\$(ProjectName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapExports>true</MapExports>
+ <SubSystem>Console</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <FixedBaseAddress>false</FixedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ <TypeLibraryName>.\Release/mhmake.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>.;src;$(OutDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>NDEBUG;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>false</FunctionLevelLinking>
+ <EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
+ <PrecompiledHeaderOutputFile>$(Configuration)/mhmake.pch</PrecompiledHeaderOutputFile>
+ <ProgramDataBaseFileName>$(IntDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CallingConvention>FastCall</CallingConvention>
+ <CompileAs>Default</CompileAs>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Link>
+ <OutputFile>$(Configuration)/mhmake.exe</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)\$(ProjectName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapExports>true</MapExports>
+ <SubSystem>Console</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <FixedBaseAddress>false</FixedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="src\build.cpp" />
+ <ClCompile Include="src\commandqueue.cpp" />
+ <ClCompile Include="src\curdir.cpp" />
+ <ClCompile Include="src\fileinfo.cpp" />
+ <ClCompile Include="src\functions.cpp" />
+ <ClCompile Include="src\md5.cpp" />
+ <ClCompile Include="src\mhmake.cpp" />
+ <ClCompile Include="src\mhmakefileparser.cpp" />
+ <ClCompile Include="src\rule.cpp" />
+ <ClCompile Include="src\stdafx.cpp">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\util.cpp" />
+ <ClCompile Include="$(OutDir)\mhmakelexer.cpp" />
+ <ClCompile Include="$(OutDir)\mhmakeparser.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="src\commandqueue.h" />
+ <ClInclude Include="src\curdir.h" />
+ <ClInclude Include="src\fileinfo.h" />
+ <ClInclude Include="src\md5.h" />
+ <ClInclude Include="src\mhmakefileparser.h" />
+ <ClInclude Include="src\refptr.h" />
+ <ClInclude Include="src\rule.h" />
+ <ClInclude Include="src\stdafx.h" />
+ <ClInclude Include="src\util.h" />
+ <ClInclude Include="$(OutDir)\mhmakeparser.h" />
+ <ClInclude Include="src\bison.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="src\mhmakeLexer.l">
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">cmd.exe /c makelex.bat Debug
+</Command>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\src\flexint.h;.\src\flex.skl;.\src\flexlexer.h;%(AdditionalInputs)</AdditionalInputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(OutDir)%(Filename).cpp;%(Outputs)</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">cmd.exe /c makelex.bat Debug64
+</Command>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\src\flexint.h;.\src\flex.skl;.\src\flexlexer.h;%(AdditionalInputs)</AdditionalInputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)%(Filename).cpp;%(Outputs)</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">cmd.exe /c makelex.bat Profile
+</Command>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">.\src\flexint.h;.\src\flex.skl;.\src\flexlexer.h;%(AdditionalInputs)</AdditionalInputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">$(OutDir)%(Filename).cpp;%(Outputs)</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">cmd.exe /c makelex.bat Profile64
+</Command>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">.\src\flexint.h;.\src\flex.skl;.\src\flexlexer.h;%(AdditionalInputs)</AdditionalInputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">$(OutDir)%(Filename).cpp;%(Outputs)</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">cmd.exe /c makelex.bat Release
+</Command>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\src\flexint.h;.\src\flex.skl;.\src\flexlexer.h;%(AdditionalInputs)</AdditionalInputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(OutDir)%(Filename).cpp;%(Outputs)</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">cmd.exe /c makelex.bat Release64</Command>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\src\flexint.h;.\src\flex.skl;.\src\flexlexer.h;%(AdditionalInputs)</AdditionalInputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)%(Filename).cpp;%(Outputs)</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="src\mhmakeParser.y">
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">cmd.exe /c makebison.bat Debug
+</Command>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\src\bison.cc;.\src\bison.h;%(AdditionalInputs)</AdditionalInputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(OutDir)%(Filename).cpp;$(OutDir)%(Filename).h;%(Outputs)</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">cmd.exe /c makebison.bat Debug64
+</Command>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\src\bison.cc;.\src\bison.h;%(AdditionalInputs)</AdditionalInputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)%(Filename).cpp;$(OutDir)%(Filename).h;%(Outputs)</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">cmd.exe /c makebison.bat Profile
+</Command>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">.\src\bison.cc;.\src\bison.h;%(AdditionalInputs)</AdditionalInputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">$(OutDir)%(Filename).cpp;$(OutDir)%(Filename).h;%(Outputs)</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">cmd.exe /c makebison.bat Profile64</Command>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">.\src\bison.cc;.\src\bison.h;%(AdditionalInputs)</AdditionalInputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">$(OutDir)%(Filename).cpp;$(OutDir)%(Filename).h;%(Outputs)</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">cmd.exe /c makebison.bat Release
+</Command>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\src\bison.cc;.\src\bison.h;%(AdditionalInputs)</AdditionalInputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(OutDir)%(Filename).cpp;$(OutDir)%(Filename).h;%(Outputs)</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">cmd.exe /c makebison.bat Release64</Command>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\src\bison.cc;.\src\bison.h;%(AdditionalInputs)</AdditionalInputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)%(Filename).cpp;$(OutDir)%(Filename).h;%(Outputs)</Outputs>
+ </CustomBuild>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/tools/mhmake/mhmake.vcxproj.filters b/tools/mhmake/mhmake.vcxproj.filters
new file mode 100644
index 000000000..72f6cf675
--- /dev/null
+++ b/tools/mhmake/mhmake.vcxproj.filters
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{e9db2f40-4c63-488d-bb89-1eee3e458055}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{bf259917-974f-4378-94e5-126d6d1889e9}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl</Extensions>
+ </Filter>
+ <Filter Include="Parser Files">
+ <UniqueIdentifier>{5c6c4864-cd40-427e-825a-4a3028933fe0}</UniqueIdentifier>
+ <Extensions>l;y;cpp;h</Extensions>
+ </Filter>
+ <Filter Include="Parser Files\Auto">
+ <UniqueIdentifier>{06532204-d72c-459e-be81-db8b0725c996}</UniqueIdentifier>
+ <Extensions>cpp;h</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{c4505c11-9108-48e9-8d61-6247b696335e}</UniqueIdentifier>
+ <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="src\build.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\commandqueue.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\curdir.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\fileinfo.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\functions.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\md5.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\mhmake.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\mhmakefileparser.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\rule.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\stdafx.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\util.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="$(OutDir)mhmakelexer.cpp">
+ <Filter>Parser Files\Auto</Filter>
+ </ClCompile>
+ <ClCompile Include="$(OutDir)mhmakeparser.cpp">
+ <Filter>Parser Files\Auto</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="src\commandqueue.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\curdir.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\fileinfo.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\md5.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\mhmakefileparser.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\refptr.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\rule.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\stdafx.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\util.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\bison.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="$(OutDir)\mhmakeparser.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="src\mhmakeLexer.l">
+ <Filter>Parser Files</Filter>
+ </CustomBuild>
+ <CustomBuild Include="src\mhmakeParser.y">
+ <Filter>Parser Files</Filter>
+ </CustomBuild>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/tools/mhmake/mhmakevc10.sln b/tools/mhmake/mhmakevc10.sln
new file mode 100644
index 000000000..aa927ed5f
--- /dev/null
+++ b/tools/mhmake/mhmakevc10.sln
@@ -0,0 +1,31 @@
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mhmake", "mhmake.vcxproj", "{7F1669C8-7974-45DF-9B71-0E2A8DC44C06}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Profile|Win32 = Profile|Win32
+ Profile|x64 = Profile|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {7F1669C8-7974-45DF-9B71-0E2A8DC44C06}.Debug|Win32.ActiveCfg = Debug|Win32
+ {7F1669C8-7974-45DF-9B71-0E2A8DC44C06}.Debug|Win32.Build.0 = Debug|Win32
+ {7F1669C8-7974-45DF-9B71-0E2A8DC44C06}.Debug|x64.ActiveCfg = Debug|x64
+ {7F1669C8-7974-45DF-9B71-0E2A8DC44C06}.Debug|x64.Build.0 = Debug|x64
+ {7F1669C8-7974-45DF-9B71-0E2A8DC44C06}.Profile|Win32.ActiveCfg = Profile|Win32
+ {7F1669C8-7974-45DF-9B71-0E2A8DC44C06}.Profile|Win32.Build.0 = Profile|Win32
+ {7F1669C8-7974-45DF-9B71-0E2A8DC44C06}.Profile|x64.ActiveCfg = Profile|x64
+ {7F1669C8-7974-45DF-9B71-0E2A8DC44C06}.Profile|x64.Build.0 = Profile|x64
+ {7F1669C8-7974-45DF-9B71-0E2A8DC44C06}.Release|Win32.ActiveCfg = Release|Win32
+ {7F1669C8-7974-45DF-9B71-0E2A8DC44C06}.Release|Win32.Build.0 = Release|Win32
+ {7F1669C8-7974-45DF-9B71-0E2A8DC44C06}.Release|x64.ActiveCfg = Release|x64
+ {7F1669C8-7974-45DF-9B71-0E2A8DC44C06}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/tools/mhmake/missing b/tools/mhmake/missing
new file mode 100644
index 000000000..6a37006e8
--- /dev/null
+++ b/tools/mhmake/missing
@@ -0,0 +1,336 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+# Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# 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, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+fi
+
+run=:
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+ configure_ac=configure.ac
+else
+ configure_ac=configure.in
+fi
+
+case "$1" in
+--run)
+ # Try to run requested program, and just exit if it succeeds.
+ run=
+ shift
+ "$@" && exit 0
+ ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case "$1" in
+
+ -h|--h|--he|--hel|--help)
+ echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+ -h, --help display this help and exit
+ -v, --version output version information and exit
+ --run try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+ aclocal touch file \`aclocal.m4'
+ autoconf touch file \`configure'
+ autoheader touch file \`config.h.in'
+ automake touch all \`Makefile.in' files
+ bison create \`y.tab.[ch]', if possible, from existing .[ch]
+ flex create \`lex.yy.c', if possible, from existing .c
+ help2man touch the output file
+ lex create \`lex.yy.c', if possible, from existing .c
+ makeinfo touch the output file
+ tar try tar, gnutar, gtar, then tar without non-portable flags
+ yacc create \`y.tab.[ch]', if possible, from existing .[ch]"
+ ;;
+
+ -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+ echo "missing 0.4 - GNU automake"
+ ;;
+
+ -*)
+ echo 1>&2 "$0: Unknown \`$1' option"
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+ ;;
+
+ aclocal*)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ fi
+
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`acinclude.m4' or \`${configure_ac}'. You might want
+ to install the \`Automake' and \`Perl' packages. Grab them from
+ any GNU archive site."
+ touch aclocal.m4
+ ;;
+
+ autoconf)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ fi
+
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`${configure_ac}'. You might want to install the
+ \`Autoconf' and \`GNU m4' packages. Grab them from any GNU
+ archive site."
+ touch configure
+ ;;
+
+ autoheader)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ fi
+
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`acconfig.h' or \`${configure_ac}'. You might want
+ to install the \`Autoconf' and \`GNU m4' packages. Grab them
+ from any GNU archive site."
+ files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+ test -z "$files" && files="config.h"
+ touch_files=
+ for f in $files; do
+ case "$f" in
+ *:*) touch_files="$touch_files "`echo "$f" |
+ sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+ *) touch_files="$touch_files $f.in";;
+ esac
+ done
+ touch $touch_files
+ ;;
+
+ automake*)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ fi
+
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+ You might want to install the \`Automake' and \`Perl' packages.
+ Grab them from any GNU archive site."
+ find . -type f -name Makefile.am -print |
+ sed 's/\.am$/.in/' |
+ while read f; do touch "$f"; done
+ ;;
+
+ autom4te)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ fi
+
+ echo 1>&2 "\
+WARNING: \`$1' is needed, and you do not seem to have it handy on your
+ system. You might have modified some files without having the
+ proper tools for further handling them.
+ You can get \`$1Help2man' as part of \`Autoconf' from any GNU
+ archive site."
+
+ file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
+ test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
+ if test -f "$file"; then
+ touch $file
+ else
+ test -z "$file" || exec >$file
+ echo "#! /bin/sh"
+ echo "# Created by GNU Automake missing as a replacement of"
+ echo "# $ $@"
+ echo "exit 0"
+ chmod +x $file
+ exit 1
+ fi
+ ;;
+
+ bison|yacc)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified a \`.y' file. You may need the \`Bison' package
+ in order for those modifications to take effect. You can get
+ \`Bison' from any GNU archive site."
+ rm -f y.tab.c y.tab.h
+ if [ $# -ne 1 ]; then
+ eval LASTARG="\${$#}"
+ case "$LASTARG" in
+ *.y)
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" y.tab.c
+ fi
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" y.tab.h
+ fi
+ ;;
+ esac
+ fi
+ if [ ! -f y.tab.h ]; then
+ echo >y.tab.h
+ fi
+ if [ ! -f y.tab.c ]; then
+ echo 'main() { return 0; }' >y.tab.c
+ fi
+ ;;
+
+ lex|flex)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified a \`.l' file. You may need the \`Flex' package
+ in order for those modifications to take effect. You can get
+ \`Flex' from any GNU archive site."
+ rm -f lex.yy.c
+ if [ $# -ne 1 ]; then
+ eval LASTARG="\${$#}"
+ case "$LASTARG" in
+ *.l)
+ SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" lex.yy.c
+ fi
+ ;;
+ esac
+ fi
+ if [ ! -f lex.yy.c ]; then
+ echo 'main() { return 0; }' >lex.yy.c
+ fi
+ ;;
+
+ help2man)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ fi
+
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified a dependency of a manual page. You may need the
+ \`Help2man' package in order for those modifications to take
+ effect. You can get \`Help2man' from any GNU archive site."
+
+ file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+ if test -z "$file"; then
+ file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
+ fi
+ if [ -f "$file" ]; then
+ touch $file
+ else
+ test -z "$file" || exec >$file
+ echo ".ab help2man is required to generate this page"
+ exit 1
+ fi
+ ;;
+
+ makeinfo)
+ if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then
+ # We have makeinfo, but it failed.
+ exit 1
+ fi
+
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified a \`.texi' or \`.texinfo' file, or any other file
+ indirectly affecting the aspect of the manual. The spurious
+ call might also be the consequence of using a buggy \`make' (AIX,
+ DU, IRIX). You might want to install the \`Texinfo' package or
+ the \`GNU make' package. Grab either from any GNU archive site."
+ file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+ if test -z "$file"; then
+ file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+ file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
+ fi
+ touch $file
+ ;;
+
+ tar)
+ shift
+ if test -n "$run"; then
+ echo 1>&2 "ERROR: \`tar' requires --run"
+ exit 1
+ fi
+
+ # We have already tried tar in the generic part.
+ # Look for gnutar/gtar before invocation to avoid ugly error
+ # messages.
+ if (gnutar --version > /dev/null 2>&1); then
+ gnutar "$@" && exit 0
+ fi
+ if (gtar --version > /dev/null 2>&1); then
+ gtar "$@" && exit 0
+ fi
+ firstarg="$1"
+ if shift; then
+ case "$firstarg" in
+ *o*)
+ firstarg=`echo "$firstarg" | sed s/o//`
+ tar "$firstarg" "$@" && exit 0
+ ;;
+ esac
+ case "$firstarg" in
+ *h*)
+ firstarg=`echo "$firstarg" | sed s/h//`
+ tar "$firstarg" "$@" && exit 0
+ ;;
+ esac
+ fi
+
+ echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+ You may want to install GNU tar or Free paxutils, or check the
+ command line arguments."
+ exit 1
+ ;;
+
+ *)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, and you do not seem to have it handy on your
+ system. You might have modified some files without having the
+ proper tools for further handling them. Check the \`README' file,
+ it often tells you about the needed prerequirements for installing
+ this package. You may also peek at any GNU archive site, in case
+ some other package would contain this missing \`$1' program."
+ exit 1
+ ;;
+esac
+
+exit 0
diff --git a/tools/mhmake/readme.txt b/tools/mhmake/readme.txt
new file mode 100644
index 000000000..bee2372e0
--- /dev/null
+++ b/tools/mhmake/readme.txt
@@ -0,0 +1,26 @@
+To build this tool you first need to install Visaul C++ Studio .NET 2003,
+Visual Studio 2008 or Visual Studio 2010.
+
+Open the mhmake.sln, mhmakevc6.sln or mhmakevc10.sln file in Visual Studio
+depending on the version of Visual Studio and compile for Debug and for
+Release.
+2 executables are generated by this process:
+- Release\mhmake.exe : gnu make compatible make program with some specific
+ extension is make the build process faster.
+
+- Debug\mhmake_dbg.exe : Has the same functionality but does extra
+ error checking on makefiles and has extra debugging options. This one
+ is advised to be used when creating makefiles. When the makefiles are
+ fully debugging mhmake.exe is a better choise because here the build
+ process will be faster. mhmake.exe is more likely to crash when badly
+ written makefiles are passed as input.
+
+To build with kdevelop3 on linux
+- Open mhmake.kdevelop and build configurations Debug and Optimized
+- run 'make install' in the deubg and release directories (as root)
+
+To build with kdevelop4 on linux
+- run genkdev4.sh
+- open mhmake.kdev4 and build configuration build and build.dbg
+- run 'make install' in the build and build.dbg directories (as root)
+
diff --git a/tools/mhmake/src/Makefile.am b/tools/mhmake/src/Makefile.am
new file mode 100644
index 000000000..0478f1645
--- /dev/null
+++ b/tools/mhmake/src/Makefile.am
@@ -0,0 +1,62 @@
+SRCS = mhmakeparser.y mhmakelexer.l mhmake.cpp mhmakefileparser.cpp util.cpp \
+ functions.cpp fileinfo.cpp rule.cpp md5.c build.cpp curdir.cpp \
+ commandqueue.cpp
+
+if DEBUG
+bin_PROGRAMS=mhmake_dbg
+mhmake_dbg_SOURCES = $(SRCS)
+else
+bin_PROGRAMS=mhmake
+mhmake_SOURCES = $(SRCS)
+endif
+
+LEX=flex++
+AM_LFLAGS=-8
+
+YACC=bison++
+AM_YFLAGS=-d
+
+mhmakelexer.o: mhmakelexer.cpp mhmakelexer.h
+mhmakelexer.cpp: mhmakelexer.l
+mhmakelexer.h: mhmakelexer.l
+
+mhmakeparser.o: mhmakeparser.cpp mhmakeparser.h
+mhmakeparser.cpp: mhmakeparser.y
+mhmakeparser.h: mhmakeparser.y
+
+.l.cpp:
+ $(LEXCOMPILE) -S$(srcdir)/flexskel.cc -H$(srcdir)/flexskel.h -h$(@:%.cpp=%.h) -otemp1234.456 $<
+ echo '#include "stdafx.h"' > $@
+ cat temp1234.456 >> $@
+ rm temp1234.456
+
+.y.cpp:
+ $(YACCCOMPILE) -S$(srcdir)/bison.cc -H$(srcdir)/bison.h -h$(@:%.cpp=%.h) -otemp1234.456 $<
+ echo '#include "stdafx.h"' > $@
+ cat temp1234.456 >> $@
+ rm temp1234.456
+
+
+.l.h:
+ $(LEXCOMPILE) -S$(srcdir)/flexskel.cc -H$(srcdir)/flexskel.h -h$@ -otemp1234.456 $<
+ echo '#include "stdafx.h"' > $(@:%.h=%.cpp)
+ cat temp1234.456 >> $(@:%.h=%.cpp)
+ rm temp1234.456
+
+.y.h:
+ $(YACCCOMPILE) -S$(srcdir)/bison.cc -H$(srcdir)/bison.h -h$@ -otemp1234.456 $<
+ echo '#include "stdafx.h"' > $(@:%.h=%.cpp)
+ cat temp1234.456 >> $(@:%.h=%.cpp)
+ rm temp1234.456
+
+# set the include path found by configure
+INCLUDES= $(all_includes)
+
+LDADD = /usr/lib/libpopt.a
+
+# the library search path.
+if DEBUG
+mhmake_dbg_LDFLAGS = $(all_libraries)
+else
+mhmake_LDFLAGS = $(all_libraries)
+endif
diff --git a/tools/mhmake/src/bison.cc b/tools/mhmake/src/bison.cc
new file mode 100644
index 000000000..5a203f719
--- /dev/null
+++ b/tools/mhmake/src/bison.cc
@@ -0,0 +1,1025 @@
+/* This file is part of mhmake.
+ *
+ * Copyright (C) 2001-2010 marha@sourceforge.net
+ *
+ * Mhmake 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Mhmake 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 Mhmake. If not, see <http://www.gnu.org/licenses/>.
+*/
+/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
+/* Skeleton output parser for bison,
+ Copyright (C) 1984, 1989, 1990 Bob Corbett and Richard Stallman
+
+ 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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* HEADER SECTION */
+#if defined( _MSDOS ) || defined(MSDOS) || defined(__MSDOS__)
+#define __MSDOS_AND_ALIKE
+#endif
+#if defined(_WINDOWS) && defined(_MSC_VER)
+#define __HAVE_NO_ALLOCA
+#define __MSDOS_AND_ALIKE
+#endif
+
+#ifndef alloca
+#if defined( __GNUC__)
+#define alloca __builtin_alloca
+
+#elif (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
+#include <alloca.h>
+
+#elif defined (__MSDOS_AND_ALIKE)
+#include <malloc.h>
+#ifndef __TURBOC__
+/* MS C runtime lib */
+#define alloca _alloca
+#endif
+
+#elif defined(_AIX)
+#include <malloc.h>
+#pragma alloca
+
+#elif defined(__hpux)
+#ifdef __cplusplus
+extern "C" {
+void *alloca (unsigned int);
+};
+#else /* not __cplusplus */
+void *alloca ();
+#endif /* not __cplusplus */
+
+#endif /* not _AIX not MSDOS, or __TURBOC__ or _AIX, not sparc. */
+#endif /* alloca not defined. */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+#ifdef __cplusplus
+#ifndef YY_USE_CLASS
+#define YY_USE_CLASS
+#endif
+#else
+#ifndef __STDC__
+#define const
+#endif
+#endif
+#include <stdio.h>
+#define YYBISON 1
+$/* %{ and %header{ and %union, during decl */
+#define YY_@_BISON 1
+#ifndef YY_@_COMPATIBILITY
+#ifndef YY_USE_CLASS
+#define YY_@_COMPATIBILITY 1
+#else
+#define YY_@_COMPATIBILITY 0
+#endif
+#endif
+
+#if YY_@_COMPATIBILITY != 0
+/* backward compatibility */
+#ifdef YYLTYPE
+#ifndef YY_@_LTYPE
+#define YY_@_LTYPE YYLTYPE
+#endif
+#endif
+#ifdef YYSTYPE
+#ifndef YY_@_STYPE
+#define YY_@_STYPE YYSTYPE
+#endif
+#endif
+#ifdef YYDEBUG
+#ifndef YY_@_DEBUG
+#define YY_@_DEBUG YYDEBUG
+#endif
+#endif
+#ifdef YY_@_STYPE
+#ifndef yystype
+#define yystype YY_@_STYPE
+#endif
+#endif
+/* use goto to be compatible */
+#ifndef YY_@_USE_GOTO
+#define YY_@_USE_GOTO 1
+#endif
+#endif
+
+/* use no goto to be clean in C++ */
+#ifndef YY_@_USE_GOTO
+#define YY_@_USE_GOTO 0
+#endif
+
+#ifndef YY_@_PURE
+$/* YY_@_PURE */
+#endif
+
+/* section apres lecture def, avant lecture grammaire S2 */
+$/* prefix */
+#ifndef YY_@_DEBUG
+$/* YY_@_DEBUG */
+#endif
+
+
+#ifndef YY_@_LSP_NEEDED
+$ /* YY_@_LSP_NEEDED*/
+#endif
+
+
+
+/* DEFAULT LTYPE*/
+#ifdef YY_@_LSP_NEEDED
+#ifndef YY_@_LTYPE
+typedef struct yyltype
+{
+ int timestamp;
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+ char *text;
+}
+yyltype;
+
+#define YY_@_LTYPE yyltype
+#endif
+#endif
+/* DEFAULT STYPE*/
+ /* We used to use `unsigned long' as YY_@_STYPE on MSDOS,
+ but it seems better to be consistent.
+ Most programs should declare their own type anyway. */
+
+#ifndef YY_@_STYPE
+#define YY_@_STYPE int
+#endif
+/* DEFAULT MISCELANEOUS */
+#ifndef YY_@_PARSE
+#define YY_@_PARSE yyparse
+#endif
+#ifndef YY_@_LEX
+#define YY_@_LEX yylex
+#endif
+#ifndef YY_@_LVAL
+#define YY_@_LVAL yylval
+#endif
+#ifndef YY_@_LLOC
+#define YY_@_LLOC yylloc
+#endif
+#ifndef YY_@_CHAR
+#define YY_@_CHAR yychar
+#endif
+#ifndef YY_@_NERRS
+#define YY_@_NERRS yynerrs
+#endif
+#ifndef YY_@_DEBUG_FLAG
+#define YY_@_DEBUG_FLAG yydebug
+#endif
+#ifndef YY_@_ERROR
+#define YY_@_ERROR yyerror
+#endif
+#ifndef YY_@_PARSE_PARAM
+#ifndef __STDC__
+#ifndef __cplusplus
+#ifndef YY_USE_CLASS
+#define YY_@_PARSE_PARAM
+#ifndef YY_@_PARSE_PARAM_DEF
+#define YY_@_PARSE_PARAM_DEF
+#endif
+#endif
+#endif
+#endif
+#ifndef YY_@_PARSE_PARAM
+#define YY_@_PARSE_PARAM void
+#endif
+#endif
+#if YY_@_COMPATIBILITY != 0
+/* backward compatibility */
+#ifdef YY_@_LTYPE
+#ifndef YYLTYPE
+#define YYLTYPE YY_@_LTYPE
+#else
+/* WARNING obsolete !!! user defined YYLTYPE not reported into generated header */
+#endif
+#endif
+#ifndef YYSTYPE
+#define YYSTYPE YY_@_STYPE
+#else
+/* WARNING obsolete !!! user defined YYSTYPE not reported into generated header */
+#endif
+#ifdef YY_@_PURE
+#ifndef YYPURE
+#define YYPURE YY_@_PURE
+#endif
+#endif
+#ifdef YY_@_DEBUG
+#ifndef YYDEBUG
+#define YYDEBUG YY_@_DEBUG
+#endif
+#endif
+#ifndef YY_@_ERROR_VERBOSE
+#ifdef YYERROR_VERBOSE
+#define YY_@_ERROR_VERBOSE YYERROR_VERBOSE
+#endif
+#endif
+#ifndef YY_@_LSP_NEEDED
+#ifdef YYLSP_NEEDED
+#define YY_@_LSP_NEEDED YYLSP_NEEDED
+#endif
+#endif
+#endif
+#ifndef YY_USE_CLASS
+/* TOKEN C */
+$ /* #defines tokens */
+#else
+/* CLASS */
+#ifndef YY_@_CLASS
+#define YY_@_CLASS @
+#endif
+#ifndef YY_@_INHERIT
+#define YY_@_INHERIT
+#endif
+#ifndef YY_@_MEMBERS
+#define YY_@_MEMBERS
+#endif
+#ifndef YY_@_LEX_BODY
+#define YY_@_LEX_BODY
+#endif
+#ifndef YY_@_ERROR_BODY
+#define YY_@_ERROR_BODY
+#endif
+#ifndef YY_@_CONSTRUCTOR_PARAM
+#define YY_@_CONSTRUCTOR_PARAM
+#endif
+#ifndef YY_@_CONSTRUCTOR_CODE
+#define YY_@_CONSTRUCTOR_CODE
+#endif
+#ifndef YY_@_CONSTRUCTOR_INIT
+#define YY_@_CONSTRUCTOR_INIT
+#endif
+/* choose between enum and const */
+#ifndef YY_@_USE_CONST_TOKEN
+#define YY_@_USE_CONST_TOKEN 0
+/* yes enum is more compatible with flex, */
+/* so by default we use it */
+#endif
+#if YY_@_USE_CONST_TOKEN != 0
+#ifndef YY_@_ENUM_TOKEN
+#define YY_@_ENUM_TOKEN yy_@_enum_token
+#endif
+#endif
+
+class YY_@_CLASS YY_@_INHERIT
+{
+public:
+#if YY_@_USE_CONST_TOKEN != 0
+/* static const int token ... */
+$ /* decl const */
+#else
+enum YY_@_ENUM_TOKEN { YY_@_NULL_TOKEN=0
+$ /* enum token */
+ }; /* end of enum declaration */
+#endif
+public:
+ int YY_@_PARSE (YY_@_PARSE_PARAM);
+#ifdef YY_@_PURE
+#else
+#ifdef YY_@_LSP_NEEDED
+ YY_@_LTYPE YY_@_LLOC;
+#endif
+ int YY_@_NERRS;
+ int YY_@_CHAR;
+#endif
+#if YY_@_DEBUG != 0
+ int YY_@_DEBUG_FLAG; /* nonzero means print parse trace */
+#endif
+public:
+ YY_@_CLASS(YY_@_CONSTRUCTOR_PARAM);
+public:
+ YY_@_MEMBERS
+};
+/* other declare folow */
+#if YY_@_USE_CONST_TOKEN != 0
+$ /* const YY_@_CLASS::token */
+#endif
+/*apres const */
+YY_@_CLASS::YY_@_CLASS(YY_@_CONSTRUCTOR_PARAM) YY_@_CONSTRUCTOR_INIT
+{
+#if YY_@_DEBUG != 0
+YY_@_DEBUG_FLAG=0;
+#endif
+YY_@_CONSTRUCTOR_CODE;
+};
+#endif
+$ /* fattrs + tables */
+
+/* parser code folow */
+
+
+/* This is the parser code that is written into each bison parser
+ when the %semantic_parser declaration is not specified in the grammar.
+ It was written by Richard Stallman by simplifying the hairy parser
+ used when %semantic_parser is specified. */
+
+/* Note: dollar marks section change
+ the next is replaced by the list of actions, each action
+ as one case of the switch. */
+
+#if YY_@_USE_GOTO != 0
+/*
+ SUPRESSION OF GOTO : on some C++ compiler (sun c++)
+ the goto is strictly forbidden if any constructor/destructor
+ is used in the whole function (very stupid isn't it ?)
+ so goto are to be replaced with a 'while/switch/case construct'
+ here are the macro to keep some apparent compatibility
+*/
+#define YYGOTO(lb) {yy_gotostate=lb;continue;}
+#define YYBEGINGOTO enum yy_labels yy_gotostate=yygotostart; \
+ for(;;) switch(yy_gotostate) { case yygotostart: {
+#define YYLABEL(lb) } case lb: {
+#define YYENDGOTO } }
+#define YYBEGINDECLARELABEL enum yy_labels {yygotostart
+#define YYDECLARELABEL(lb) ,lb
+#define YYENDDECLARELABEL };
+#else
+/* macro to keep goto */
+#define YYGOTO(lb) goto lb
+#define YYBEGINGOTO
+#define YYLABEL(lb) lb:
+#define YYENDGOTO
+#define YYBEGINDECLARELABEL
+#define YYDECLARELABEL(lb)
+#define YYENDDECLARELABEL
+#endif
+/* LABEL DECLARATION */
+YYBEGINDECLARELABEL
+ YYDECLARELABEL(yynewstate)
+ YYDECLARELABEL(yybackup)
+/* YYDECLARELABEL(yyresume) */
+ YYDECLARELABEL(yydefault)
+ YYDECLARELABEL(yyreduce)
+ YYDECLARELABEL(yyerrlab) /* here on detecting error */
+ YYDECLARELABEL(yyerrlab1) /* here on error raised explicitly by an action */
+ YYDECLARELABEL(yyerrdefault) /* current state does not do anything special for the error token. */
+ YYDECLARELABEL(yyerrpop) /* pop the current state because it cannot handle the error token */
+ YYDECLARELABEL(yyerrhandle)
+YYENDDECLARELABEL
+/* ALLOCA SIMULATION */
+/* __HAVE_NO_ALLOCA */
+#ifdef __HAVE_NO_ALLOCA
+int __alloca_free_ptr(char *ptr,char *ref)
+{if(ptr!=ref) free(ptr);
+ return 0;}
+
+#define __ALLOCA_alloca(size) malloc(size)
+#define __ALLOCA_free(ptr,ref) __alloca_free_ptr((char *)ptr,(char *)ref)
+
+#ifdef YY_@_LSP_NEEDED
+#define __ALLOCA_return(num) \
+ return( __ALLOCA_free(yyss,yyssa)+\
+ __ALLOCA_free(yyvs,yyvsa)+\
+ __ALLOCA_free(yyls,yylsa)+\
+ (num))
+#else
+#define __ALLOCA_return(num) \
+ return( __ALLOCA_free(yyss,yyssa)+\
+ __ALLOCA_free(yyvs,yyvsa)+\
+ (num))
+#endif
+#else
+#define __ALLOCA_return(num) return(num)
+#define __ALLOCA_alloca(size) alloca(size)
+#define __ALLOCA_free(ptr,ref)
+#endif
+
+/* ENDALLOCA SIMULATION */
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (YY_@_CHAR = YYEMPTY)
+#define YYEMPTY -2
+#define YYEOF 0
+#define YYACCEPT __ALLOCA_return(0)
+#define YYABORT __ALLOCA_return(1)
+#define YYERROR YYGOTO(yyerrlab1)
+/* Like YYERROR except do call yyerror.
+ This remains here temporarily to ease the
+ transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+#define YYFAIL YYGOTO(yyerrlab)
+#define YYRECOVERING() (!!yyerrstatus)
+#define YYBACKUP(token, value) \
+do\
+ if (YY_@_CHAR == YYEMPTY && yylen == 1)\
+ {\
+ YY_@_CHAR = (token), YY_@_LVAL = (value);\
+ yychar1 = YYTRANSLATE (YY_@_CHAR);\
+ YYPOPSTACK;\
+ YYGOTO(yybackup);\
+ }\
+ else\
+ {\
+ YY_@_ERROR ("syntax error: cannot back up"); YYERROR;\
+ }\
+while (0)
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+#ifndef YY_@_PURE
+/* UNPURE */
+#define YYLEX YY_@_LEX()
+#ifndef YY_USE_CLASS
+/* If nonreentrant, and not class , generate the variables here */
+int YY_@_CHAR; /* the lookahead symbol */
+ /* lookahead symbol */
+int YY_@_NERRS; /* number of parse errors so far */
+#ifdef YY_@_LSP_NEEDED
+YY_@_LTYPE YY_@_LLOC; /* location data for the lookahead */
+ /* symbol */
+#endif
+#endif
+
+
+#else
+/* PURE */
+#ifdef YY_@_LSP_NEEDED
+#define YYLEX YY_@_LEX(&YY_@_LVAL, &YY_@_LLOC)
+#else
+#define YYLEX YY_@_LEX(&YY_@_LVAL)
+#endif
+#endif
+#ifndef YY_USE_CLASS
+#if YY_@_DEBUG != 0
+int YY_@_DEBUG_FLAG; /* nonzero means print parse trace */
+/* Since this is uninitialized, it does not stop multiple parsers
+ from coexisting. */
+#endif
+#endif
+
+
+
+/* YYINITDEPTH indicates the initial size of the parser's stacks */
+
+#ifndef YYINITDEPTH
+#define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH is the maximum size the stacks can grow to
+ (effective only if the built-in stack extension method is used). */
+
+#if YYMAXDEPTH == 0
+#undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+#define YYMAXDEPTH 10000
+#endif
+
+
+#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
+#define __yy_bcopy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT)
+#else /* not GNU C or C++ */
+
+/* This is the most reliable way to avoid incompatibilities
+ in available built-in functions on various systems. */
+
+#ifdef __cplusplus
+static void __yy_bcopy (char *from, char *to, size_t count)
+#else
+#ifdef __STDC__
+static void __yy_bcopy (char *from, char *to, int count)
+#else
+static void __yy_bcopy (from, to, count)
+ char *from;
+ char *to;
+ int count;
+#endif
+#endif
+{
+ register char *f = from;
+ register char *t = to;
+ register size_t i = count;
+
+ while (i-- > 0)
+ *t++ = *f++;
+}
+#endif
+
+int
+#ifdef YY_USE_CLASS
+ YY_@_CLASS::
+#endif
+ YY_@_PARSE(YY_@_PARSE_PARAM)
+#ifndef __STDC__
+#ifndef __cplusplus
+#ifndef YY_USE_CLASS
+/* parameter definition without protypes */
+YY_@_PARSE_PARAM_DEF
+#endif
+#endif
+#endif
+{
+ register int yystate;
+ register int yyn;
+ register short *yyssp;
+ register YY_@_STYPE *yyvsp;
+ int yyerrstatus; /* number of tokens to shift before error messages enabled */
+ int yychar1=0; /* lookahead token as an internal (translated) token number */
+
+ short yyssa[YYINITDEPTH]; /* the state stack */
+ YY_@_STYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
+
+ short *yyss = yyssa; /* refer to the stacks thru separate pointers */
+ YY_@_STYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
+
+#ifdef YY_@_LSP_NEEDED
+ YY_@_LTYPE yylsa[YYINITDEPTH]; /* the location stack */
+ YY_@_LTYPE *yyls = yylsa;
+ YY_@_LTYPE *yylsp;
+
+#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
+#else
+#define YYPOPSTACK (yyvsp--, yyssp--)
+#endif
+
+ int yystacksize = YYINITDEPTH;
+
+#ifdef YY_@_PURE
+ int YY_@_CHAR;
+ YY_@_STYPE YY_@_LVAL;
+ int YY_@_NERRS;
+#ifdef YY_@_LSP_NEEDED
+ YY_@_LTYPE YY_@_LLOC;
+#endif
+#endif
+
+ YY_@_STYPE yyval; /* the variable used to return */
+ /* semantic values from the action */
+ /* routines */
+
+ int yylen;
+/* start loop, in which YYGOTO may be used. */
+YYBEGINGOTO
+
+#if YY_@_DEBUG != 0
+ if (YY_@_DEBUG_FLAG)
+ fprintf(stderr, "Starting parse\n");
+#endif
+ yystate = 0;
+ yyerrstatus = 0;
+ YY_@_NERRS = 0;
+ YY_@_CHAR = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+
+ yyssp = yyss - 1;
+ yyvsp = yyvs;
+#ifdef YY_@_LSP_NEEDED
+ yylsp = yyls;
+#endif
+
+/* Push a new state, which is found in yystate . */
+/* In all cases, when you get here, the value and location stacks
+ have just been pushed. so pushing a state here evens the stacks. */
+YYLABEL(yynewstate)
+
+ *++yyssp = yystate;
+
+ if (yyssp >= yyss + yystacksize - 1)
+ {
+ /* Give user a chance to reallocate the stack */
+ /* Use copies of these so that the &'s don't force the real ones into memory. */
+ YY_@_STYPE *yyvs1 = yyvs;
+ short *yyss1 = yyss;
+#ifdef YY_@_LSP_NEEDED
+ YY_@_LTYPE *yyls1 = yyls;
+#endif
+
+ /* Get the current used size of the three stacks, in elements. */
+ size_t size = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ /* Each stack pointer address is followed by the size of
+ the data in use in that stack, in bytes. */
+#ifdef YY_@_LSP_NEEDED
+ /* This used to be a conditional around just the two extra args,
+ but that might be undefined if yyoverflow is a macro. */
+ yyoverflow("parser stack overflow",
+ &yyss1, size * sizeof (*yyssp),
+ &yyvs1, size * sizeof (*yyvsp),
+ &yyls1, size * sizeof (*yylsp),
+ &yystacksize);
+#else
+ yyoverflow("parser stack overflow",
+ &yyss1, size * sizeof (*yyssp),
+ &yyvs1, size * sizeof (*yyvsp),
+ &yystacksize);
+#endif
+
+ yyss = yyss1; yyvs = yyvs1;
+#ifdef YY_@_LSP_NEEDED
+ yyls = yyls1;
+#endif
+#else /* no yyoverflow */
+ /* Extend the stack our own way. */
+ if (yystacksize >= YYMAXDEPTH)
+ {
+ YY_@_ERROR("parser stack overflow");
+ __ALLOCA_return(2);
+ }
+ yystacksize *= 2;
+ if (yystacksize > YYMAXDEPTH)
+ yystacksize = YYMAXDEPTH;
+ yyss = (short *) __ALLOCA_alloca (yystacksize * sizeof (*yyssp));
+ __yy_bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp));
+ __ALLOCA_free(yyss1,yyssa);
+ yyvs = (YY_@_STYPE *) __ALLOCA_alloca (yystacksize * sizeof (*yyvsp));
+ __yy_bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp));
+ __ALLOCA_free(yyvs1,yyvsa);
+#ifdef YY_@_LSP_NEEDED
+ yyls = (YY_@_LTYPE *) __ALLOCA_alloca (yystacksize * sizeof (*yylsp));
+ __yy_bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp));
+ __ALLOCA_free(yyls1,yylsa);
+#endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + size - 1;
+ yyvsp = yyvs + size - 1;
+#ifdef YY_@_LSP_NEEDED
+ yylsp = yyls + size - 1;
+#endif
+
+#if YY_@_DEBUG != 0
+ if (YY_@_DEBUG_FLAG)
+ fprintf(stderr, "Stack size increased to %d\n", yystacksize);
+#endif
+
+ if (yyssp >= yyss + yystacksize - 1)
+ YYABORT;
+ }
+
+#if YY_@_DEBUG != 0
+ if (YY_@_DEBUG_FLAG)
+ fprintf(stderr, "Entering state %d\n", yystate);
+#endif
+
+ YYGOTO(yybackup);
+YYLABEL(yybackup)
+
+/* Do appropriate processing given the current state. */
+/* Read a lookahead token if we need one and don't already have one. */
+/* YYLABEL(yyresume) */
+
+ /* First try to decide what to do without reference to lookahead token. */
+
+ yyn = yypact[yystate];
+ if (yyn == YYFLAG)
+ YYGOTO(yydefault);
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* yychar is either YYEMPTY or YYEOF
+ or a valid token in external form. */
+
+ if (YY_@_CHAR == YYEMPTY)
+ {
+#if YY_@_DEBUG != 0
+ if (YY_@_DEBUG_FLAG)
+ fprintf(stderr, "Reading a token: ");
+#endif
+ YY_@_CHAR = YYLEX;
+ }
+
+ /* Convert token to internal form (in yychar1) for indexing tables with */
+
+ if (YY_@_CHAR <= 0) /* This means end of input. */
+ {
+ yychar1 = 0;
+ YY_@_CHAR = YYEOF; /* Don't call YYLEX any more */
+
+#if YY_@_DEBUG != 0
+ if (YY_@_DEBUG_FLAG)
+ fprintf(stderr, "Now at end of input.\n");
+#endif
+ }
+ else
+ {
+ yychar1 = YYTRANSLATE(YY_@_CHAR);
+
+#if YY_@_DEBUG != 0
+ if (YY_@_DEBUG_FLAG)
+ {
+ fprintf (stderr, "Next token is %d (%s", YY_@_CHAR, yytname[yychar1]);
+ /* Give the individual parser a way to print the precise meaning
+ of a token, for further debugging info. */
+#ifdef YYPRINT
+ YYPRINT (stderr, YY_@_CHAR, YY_@_LVAL);
+#endif
+ fprintf (stderr, ")\n");
+ }
+#endif
+ }
+
+ yyn += yychar1;
+ if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
+ YYGOTO(yydefault);
+
+ yyn = yytable[yyn];
+
+ /* yyn is what to do for this token type in this state.
+ Negative => reduce, -yyn is rule number.
+ Positive => shift, yyn is new state.
+ New state is final state => don't bother to shift,
+ just return success.
+ 0, or most negative number => error. */
+
+ if (yyn < 0)
+ {
+ if (yyn == YYFLAG)
+ YYGOTO(yyerrlab);
+ yyn = -yyn;
+ YYGOTO(yyreduce);
+ }
+ else if (yyn == 0)
+ YYGOTO(yyerrlab);
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ /* Shift the lookahead token. */
+
+#if YY_@_DEBUG != 0
+ if (YY_@_DEBUG_FLAG)
+ fprintf(stderr, "Shifting token %d (%s), ", YY_@_CHAR, yytname[yychar1]);
+#endif
+
+ /* Discard the token being shifted unless it is eof. */
+ if (YY_@_CHAR != YYEOF)
+ YY_@_CHAR = YYEMPTY;
+
+ *++yyvsp = YY_@_LVAL;
+#ifdef YY_@_LSP_NEEDED
+ *++yylsp = YY_@_LLOC;
+#endif
+
+ /* count tokens shifted since error; after three, turn off error status. */
+ if (yyerrstatus) yyerrstatus--;
+
+ yystate = yyn;
+ YYGOTO(yynewstate);
+
+/* Do the default action for the current state. */
+YYLABEL(yydefault)
+
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ YYGOTO(yyerrlab);
+
+/* Do a reduction. yyn is the number of a rule to reduce with. */
+YYLABEL(yyreduce)
+ yylen = yyr2[yyn];
+ if (yylen > 0)
+ yyval = yyvsp[1-yylen]; /* implement default value of the action */
+
+#if YY_@_DEBUG != 0
+ if (YY_@_DEBUG_FLAG)
+ {
+ int i;
+
+ fprintf (stderr, "Reducing via rule %d (line %d), ",
+ yyn, yyrline[yyn]);
+
+ /* Print the symbols being reduced, and their result. */
+ for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
+ fprintf (stderr, "%s ", yytname[yyrhs[i]]);
+ fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
+ }
+#endif
+
+$ /* the action file gets copied in in place of this dollarsign */
+ yyvsp -= yylen;
+ yyssp -= yylen;
+#ifdef YY_@_LSP_NEEDED
+ yylsp -= yylen;
+#endif
+
+#if YY_@_DEBUG != 0
+ if (YY_@_DEBUG_FLAG)
+ {
+ short *ssp1 = yyss - 1;
+ fprintf (stderr, "state stack now");
+ while (ssp1 != yyssp)
+ fprintf (stderr, " %d", *++ssp1);
+ fprintf (stderr, "\n");
+ }
+#endif
+
+ *++yyvsp = yyval;
+
+#ifdef YY_@_LSP_NEEDED
+ yylsp++;
+ if (yylen == 0)
+ {
+ *yylsp= YY_@_LLOC;
+ //yylsp->first_line = YY_@_LLOC.first_line;
+ //yylsp->first_column = YY_@_LLOC.first_column;
+ //yylsp->last_line = (yylsp-1)->last_line;
+ //yylsp->last_column = (yylsp-1)->last_column;
+ //yylsp->text = 0;
+ }
+ else
+ {
+ *yylsp = *(yylsp+yylen-1);
+ //yylsp->last_line = (yylsp+yylen-1)->last_line;
+ //yylsp->last_column = (yylsp+yylen-1)->last_column;
+ }
+#endif
+
+ /* Now "shift" the result of the reduction.
+ Determine what state that goes to,
+ based on the state we popped back to
+ and the rule number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
+ if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTBASE];
+
+ YYGOTO(yynewstate);
+
+YYLABEL(yyerrlab) /* here on detecting error */
+
+ if (! yyerrstatus)
+ /* If not already recovering from an error, report this error. */
+ {
+ ++YY_@_NERRS;
+
+#ifdef YY_@_ERROR_VERBOSE
+ yyn = yypact[yystate];
+
+ if (yyn > YYFLAG && yyn < YYLAST)
+ {
+ size_t size = 0;
+ char *msg;
+ int x, count;
+
+ count = 0;
+ /* Start X at -yyn if nec to avoid negative indexes in yycheck. */
+ for (x = (yyn < 0 ? -yyn : 0);
+ x < (sizeof(yytname) / sizeof(char *)); x++)
+ if (yycheck[x + yyn] == x)
+ size += strlen(yytname[x]) + 15, count++;
+ msg = (char *) malloc(size + 15);
+ if (msg != 0)
+ {
+ strcpy(msg, "parse error");
+
+ if (count < 5)
+ {
+ count = 0;
+ for (x = (yyn < 0 ? -yyn : 0);
+ x < (sizeof(yytname) / sizeof(char *)); x++)
+ if (yycheck[x + yyn] == x)
+ {
+ strcat(msg, count == 0 ? ", expecting `" : " or `");
+ strcat(msg, yytname[x]);
+ strcat(msg, "'");
+ count++;
+ }
+ }
+ YY_@_ERROR(msg);
+ free(msg);
+ }
+ else
+ YY_@_ERROR ("parse error; also virtual memory exceeded");
+ }
+ else
+#endif /* YY_@_ERROR_VERBOSE */
+ YY_@_ERROR("parse error");
+ }
+
+ YYGOTO(yyerrlab1);
+YYLABEL(yyerrlab1) /* here on error raised explicitly by an action */
+
+ if (yyerrstatus == 3)
+ {
+ /* if just tried and failed to reuse lookahead token after an error, discard it. */
+
+ /* return failure if at end of input */
+ if (YY_@_CHAR == YYEOF)
+ YYABORT;
+
+#if YY_@_DEBUG != 0
+ if (YY_@_DEBUG_FLAG)
+ fprintf(stderr, "Discarding token %d (%s).\n", YY_@_CHAR, yytname[yychar1]);
+#endif
+
+ YY_@_CHAR = YYEMPTY;
+ }
+
+ /* Else will try to reuse lookahead token
+ after shifting the error token. */
+
+ yyerrstatus = 3; /* Each real token shifted decrements this */
+
+ YYGOTO(yyerrhandle);
+
+YYLABEL(yyerrdefault) /* current state does not do anything special for the error token. */
+
+#if 0
+ /* This is wrong; only states that explicitly want error tokens
+ should shift them. */
+ yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
+ if (yyn) YYGOTO(yydefault);
+#endif
+
+YYLABEL(yyerrpop) /* pop the current state because it cannot handle the error token */
+
+ if (yyssp == yyss) YYABORT;
+ yyvsp--;
+ yystate = *--yyssp;
+#ifdef YY_@_LSP_NEEDED
+ yylsp--;
+#endif
+
+#if YY_@_DEBUG != 0
+ if (YY_@_DEBUG_FLAG)
+ {
+ short *ssp1 = yyss - 1;
+ fprintf (stderr, "Error: state stack now");
+ while (ssp1 != yyssp)
+ fprintf (stderr, " %d", *++ssp1);
+ fprintf (stderr, "\n");
+ }
+#endif
+
+YYLABEL(yyerrhandle)
+
+ yyn = yypact[yystate];
+ if (yyn == YYFLAG)
+ YYGOTO(yyerrdefault);
+
+ yyn += YYTERROR;
+ if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
+ YYGOTO(yyerrdefault);
+
+ yyn = yytable[yyn];
+ if (yyn < 0)
+ {
+ if (yyn == YYFLAG)
+ YYGOTO(yyerrpop);
+ yyn = -yyn;
+ YYGOTO(yyreduce);
+ }
+ else if (yyn == 0)
+ YYGOTO(yyerrpop);
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+#if YY_@_DEBUG != 0
+ if (YY_@_DEBUG_FLAG)
+ fprintf(stderr, "Shifting error token, ");
+#endif
+
+ *++yyvsp = YY_@_LVAL;
+#ifdef YY_@_LSP_NEEDED
+ *++yylsp = YY_@_LLOC;
+#endif
+
+ yystate = yyn;
+ YYGOTO(yynewstate);
+/* end loop, in which YYGOTO may be used. */
+ YYENDGOTO
+}
+
+/* END */
+$ /* section 3 */
+
+/* AFTER END , NEVER READ !!! */
+
diff --git a/tools/mhmake/src/bison.h b/tools/mhmake/src/bison.h
new file mode 100644
index 000000000..0724ae112
--- /dev/null
+++ b/tools/mhmake/src/bison.h
@@ -0,0 +1,249 @@
+/* This file is part of mhmake.
+ *
+ * Copyright (C) 2001-2010 marha@sourceforge.net
+ *
+ * Mhmake 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Mhmake 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 Mhmake. If not, see <http://www.gnu.org/licenses/>.
+*/
+/* before anything */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+#ifdef __cplusplus
+#ifndef YY_USE_CLASS
+#define YY_USE_CLASS
+#endif
+#else
+#endif
+#include <stdio.h>
+$ /* %{ and %header{ and %union, during decl */
+#ifndef YY_@_COMPATIBILITY
+#ifndef YY_USE_CLASS
+#define YY_@_COMPATIBILITY 1
+#else
+#define YY_@_COMPATIBILITY 0
+#endif
+#endif
+
+#if YY_@_COMPATIBILITY != 0
+/* backward compatibility */
+#ifdef YYLTYPE
+#ifndef YY_@_LTYPE
+#define YY_@_LTYPE YYLTYPE
+/* WARNING obsolete !!! user defined YYLTYPE not reported into generated header */
+/* use %define LTYPE */
+#endif
+#endif
+#ifdef YYSTYPE
+#ifndef YY_@_STYPE
+#define YY_@_STYPE YYSTYPE
+/* WARNING obsolete !!! user defined YYSTYPE not reported into generated header */
+/* use %define STYPE */
+#endif
+#endif
+#ifdef YYDEBUG
+#ifndef YY_@_DEBUG
+#define YY_@_DEBUG YYDEBUG
+/* WARNING obsolete !!! user defined YYDEBUG not reported into generated header */
+/* use %define DEBUG */
+#endif
+#endif
+#ifdef YY_@_STYPE
+#ifndef yystype
+#define yystype YY_@_STYPE
+#endif
+#endif
+/* use goto to be compatible */
+#ifndef YY_@_USE_GOTO
+#define YY_@_USE_GOTO 1
+#endif
+#endif
+
+/* use no goto to be clean in C++ */
+#ifndef YY_@_USE_GOTO
+#define YY_@_USE_GOTO 0
+#endif
+
+#ifndef YY_@_PURE
+$/* YY_@_PURE */
+#endif
+$/* prefix */
+#ifndef YY_@_DEBUG
+$/* YY_@_DEBUG */
+#endif
+#ifndef YY_@_LSP_NEEDED
+$ /* YY_@_LSP_NEEDED*/
+#endif
+/* DEFAULT LTYPE*/
+#ifdef YY_@_LSP_NEEDED
+#ifndef YY_@_LTYPE
+typedef
+ struct yyltype
+ {
+ int timestamp;
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+ char *text;
+ }
+ yyltype;
+
+#define YY_@_LTYPE yyltype
+#endif
+#endif
+/* DEFAULT STYPE*/
+#ifndef YY_@_STYPE
+#define YY_@_STYPE int
+#endif
+/* DEFAULT MISCELANEOUS */
+#ifndef YY_@_PARSE
+#define YY_@_PARSE yyparse
+#endif
+#ifndef YY_@_LEX
+#define YY_@_LEX yylex
+#endif
+#ifndef YY_@_LVAL
+#define YY_@_LVAL yylval
+#endif
+#ifndef YY_@_LLOC
+#define YY_@_LLOC yylloc
+#endif
+#ifndef YY_@_CHAR
+#define YY_@_CHAR yychar
+#endif
+#ifndef YY_@_NERRS
+#define YY_@_NERRS yynerrs
+#endif
+#ifndef YY_@_DEBUG_FLAG
+#define YY_@_DEBUG_FLAG yydebug
+#endif
+#ifndef YY_@_ERROR
+#define YY_@_ERROR yyerror
+#endif
+
+#ifndef YY_@_PARSE_PARAM
+#ifndef __STDC__
+#ifndef __cplusplus
+#ifndef YY_USE_CLASS
+#define YY_@_PARSE_PARAM
+#ifndef YY_@_PARSE_PARAM_DEF
+#define YY_@_PARSE_PARAM_DEF
+#endif
+#endif
+#endif
+#endif
+#ifndef YY_@_PARSE_PARAM
+#define YY_@_PARSE_PARAM void
+#endif
+#endif
+
+/* TOKEN C */
+#ifndef YY_USE_CLASS
+
+#ifndef YY_@_PURE
+extern YY_@_STYPE YY_@_LVAL;
+#endif
+
+$ /* #defines token */
+/* after #define tokens, before const tokens S5*/
+#else
+#ifndef YY_@_CLASS
+#define YY_@_CLASS @
+#endif
+
+#ifndef YY_@_INHERIT
+#define YY_@_INHERIT
+#endif
+#ifndef YY_@_MEMBERS
+#define YY_@_MEMBERS
+#endif
+#ifndef YY_@_LEX_BODY
+#define YY_@_LEX_BODY
+#endif
+#ifndef YY_@_ERROR_BODY
+#define YY_@_ERROR_BODY
+#endif
+#ifndef YY_@_CONSTRUCTOR_PARAM
+#define YY_@_CONSTRUCTOR_PARAM
+#endif
+/* choose between enum and const */
+#ifndef YY_@_USE_CONST_TOKEN
+#define YY_@_USE_CONST_TOKEN 0
+/* yes enum is more compatible with flex, */
+/* so by default we use it */
+#endif
+#if YY_@_USE_CONST_TOKEN != 0
+#ifndef YY_@_ENUM_TOKEN
+#define YY_@_ENUM_TOKEN yy_@_enum_token
+#endif
+#endif
+
+class YY_@_CLASS YY_@_INHERIT
+{
+public:
+#if YY_@_USE_CONST_TOKEN != 0
+/* static const int token ... */
+$ /* decl const */
+#else
+enum YY_@_ENUM_TOKEN { YY_@_NULL_TOKEN=0
+$ /* enum token */
+ }; /* end of enum declaration */
+#endif
+public:
+ int YY_@_PARSE(YY_@_PARSE_PARAM);
+#ifdef YY_@_PURE
+#else
+#ifdef YY_@_LSP_NEEDED
+ YY_@_LTYPE YY_@_LLOC;
+#endif
+ int YY_@_NERRS;
+ int YY_@_CHAR;
+#endif
+#if YY_@_DEBUG != 0
+public:
+ int YY_@_DEBUG_FLAG; /* nonzero means print parse trace */
+#endif
+public:
+ YY_@_CLASS(YY_@_CONSTRUCTOR_PARAM);
+public:
+ YY_@_MEMBERS
+};
+/* other declare folow */
+#endif
+
+
+#if YY_@_COMPATIBILITY != 0
+/* backward compatibility */
+#ifndef YYSTYPE
+#define YYSTYPE YY_@_STYPE
+#endif
+
+#ifndef YYLTYPE
+#define YYLTYPE YY_@_LTYPE
+#endif
+#ifndef YYDEBUG
+#ifdef YY_@_DEBUG
+#define YYDEBUG YY_@_DEBUG
+#endif
+#endif
+
+#endif
+/* END */
+$ /* section 3 %header{ */
+ /* AFTER END , NEVER READ !!! */
+
+
+
diff --git a/tools/mhmake/src/build.cpp b/tools/mhmake/src/build.cpp
new file mode 100644
index 000000000..9efa90932
--- /dev/null
+++ b/tools/mhmake/src/build.cpp
@@ -0,0 +1,1819 @@
+/* This file is part of mhmake.
+ *
+ * Copyright (C) 2001-2010 marha@sourceforge.net
+ *
+ * Mhmake 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Mhmake 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 Mhmake. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* $Rev$ */
+
+#include "stdafx.h"
+
+#include "mhmakefileparser.h"
+#include "mhmakeparser.h"
+#include "rule.h"
+#include "util.h"
+
+/* Calling py2exe is only implemented on windows for now. */
+#ifdef WIN32
+
+/* Python exe create script in parts:
+import zipfile,tempfile,shutil,os
+
+def UpdateZipFile(SrcZip,DestZip):
+ NewZip=tempfile.mktemp('.zip')
+
+ Src=zipfile.ZipFile(SrcZip)
+
+ New=zipfile.ZipFile(NewZip,'w')
+
+ InFile={}
+ for name in Src.namelist():
+ InFile[name]=1
+ New.writestr(name,Src.read(name))
+ Src.close()
+
+ try:
+ Dest=zipfile.ZipFile(DestZip)
+
+ for name in Dest.namelist():
+ if not InFile.has_key(name):
+ New.writestr(name,Dest.read(name))
+ Dest.close()
+ except IOError:
+ pass
+ New.close()
+
+ shutil.move(NewZip,DestZip)
+
+OutFileName=tempfile.mktemp('.py')
+pOut=open(OutFileName,'w')
+
+Script=r'<PYTHONSCRIPT>'
+DirScript=os.path.split(Script)[0]
+pOut.write(r'''
+
+from distutils.core import setup
+import py2exe
+import sys
+sys.path.append(r'%s')
+setup(zipfile=None, console=[r'%s'])
+'''%(DirScript,Script))
+
+pOut.close()
+
+import os
+
+stdin,stdout=os.popen4(r'"<PYTHONEXE>" %s py2exe'%OutFileName);
+stdout.read()
+stdout.close()
+stdin.close()
+
+OutDir=os.path.split(Script)[0]
+
+import shutil
+def CopyFiles(Src,Dest):
+ for File in os.listdir(Src):
+ SrcDir=os.path.join(Src,File)
+ if File=='library.zip':
+ UpdateZipFile(os.path.join(Src,File),os.path.join(Dest,File))
+ elif os.path.isdir(SrcDir):
+ DestDir=os.path.join(Dest,File)
+ os.mkdir(DestDir)
+ CopyFiles(SrcDir,DestDir)
+ else:
+ shutil.copy(os.path.join(Src,File),os.path.join(Dest,File))
+
+if os.path.isdir('dist'):
+ CopyFiles('dist',OutDir)
+
+ try:
+ shutil.rmtree('dist')
+ except:
+ pass
+ try:
+ shutil.rmtree('build')
+ except:
+ pass
+os.remove(OutFileName)
+*/
+
+static const string PythonScriptPart1=
+"import zipfile,tempfile,shutil,os\n"
+"\n"
+"def UpdateZipFile(SrcZip,DestZip):\n"
+" NewZip=tempfile.mktemp('.zip')\n"
+"\n"
+" Src=zipfile.ZipFile(SrcZip)\n"
+"\n"
+" New=zipfile.ZipFile(NewZip,'w')\n"
+"\n"
+" InFile={}\n"
+" for name in Src.namelist():\n"
+" InFile[name]=1\n"
+" New.writestr(name,Src.read(name))\n"
+" Src.close()\n"
+"\n"
+" try:\n"
+" Dest=zipfile.ZipFile(DestZip)\n"
+"\n"
+" for name in Dest.namelist():\n"
+" if not InFile.has_key(name):\n"
+" New.writestr(name,Dest.read(name))\n"
+" Dest.close()\n"
+" except IOError:\n"
+" pass\n"
+" New.close()\n"
+"\n"
+" shutil.move(NewZip,DestZip)\n"
+"\n"
+"OutFileName=tempfile.mktemp('.py')\n"
+"pOut=open(OutFileName,'w')\n"
+"\n"
+"Script=r'"
+;
+
+static const string PythonScriptPart2=
+"'\n"
+"DirScript=os.path.split(Script)[0]\n"
+"\n"
+"pOut.write(r'''\n"
+"\n"
+"from distutils.core import setup\n"
+"import py2exe\n"
+"import sys\n"
+"sys.path.append(r'%s')\n"
+"setup(console=[r'%s'])\n"
+"'''%(DirScript,Script))\n"
+"\n"
+"pOut.close()\n"
+"\n"
+"import os\n"
+"\n"
+"stdin,stdout=os.popen4(r'"
+;
+
+static const string PythonScriptPart3=
+"%s py2exe'%OutFileName);\n"
+"stdout.read()\n"
+"stdout.close()\n"
+"stdin.close()\n"
+"\n"
+"OutDir=os.path.split(Script)[0]\n"
+"\n"
+"import shutil\n"
+"def CopyFiles(Src,Dest):\n"
+" for File in os.listdir(Src):\n"
+" SrcDir=os.path.join(Src,File)\n"
+" if File=='library.zip':\n"
+" UpdateZipFile(os.path.join(Src,File),os.path.join(Dest,File))\n"
+" elif os.path.isdir(SrcDir):\n"
+" DestDir=os.path.join(Dest,File)\n"
+" os.mkdir(DestDir)\n"
+" CopyFiles(SrcDir,DestDir)\n"
+" else:\n"
+" shutil.copy(os.path.join(Src,File),os.path.join(Dest,File))\n"
+"\n"
+"if os.path.isdir('dist'):\n"
+" CopyFiles('dist',OutDir)\n"
+"\n"
+" try:\n"
+" shutil.rmtree('dist')\n"
+" except:\n"
+" pass\n"
+" try:\n"
+" shutil.rmtree('build')\n"
+" except:\n"
+" pass\n"
+"os.remove(OutFileName)\n"
+;
+/*****************************************************************************/
+/* Converts a python script to an executable if py2exe is installed */
+
+void mhmakefileparser::CreatePythonExe(const string &FullCommand)
+{
+ /* First create a python script to run */
+ cout << "Converting "<<FullCommand<<endl;
+
+ string PythonScript;
+ PythonScript+=PythonScriptPart1;
+ PythonScript+=FullCommand;
+ PythonScript+=PythonScriptPart2;
+ PythonScript+=GetPythonExe();
+ PythonScript+=PythonScriptPart3;
+
+ char Filename[MAX_PATH];
+ int Nr=0;
+ FILE *pFile=(FILE*)1;
+ while (1)
+ {
+ sprintf(Filename,"%s\\tmp%d.py",m_MakeDir->GetFullFileName().c_str(),Nr);
+ pFile=fopen(Filename,"r");
+ if (!pFile)
+ break;
+ fclose(pFile);
+ Nr++;
+ }
+ pFile=fopen(Filename,"w");
+ fprintf(pFile,"%s",PythonScript.c_str());
+ fclose(pFile);
+
+ string GenExeCommand=GetPythonExe();
+ GenExeCommand+=QuoteFileName(Filename);
+
+ string Output;
+ ExecuteCommand(GenExeCommand,&Output);
+
+ remove(Filename);
+}
+#endif
+
+/*****************************************************************************/
+int mhmakefileparser::SearchPath(const char *szCommand, const char *pExt, size_t Len, char *szFullCommand,char **pFilePart) const
+{
+ static vector< fileinfo* > vSearchPath;
+
+ string Command(szCommand);
+ if (pExt)
+ Command+=pExt;
+ vector< fileinfo* >::iterator It;
+ vector< fileinfo* >::iterator ItEnd;
+
+ fileinfo* pCommandFile=GetFileInfo(Command,m_MakeDir);
+ if (pCommandFile->Exists())
+ {
+ goto found;
+ }
+ pCommandFile->InvalidateDate(); // It could be created in the makefile later
+ if (!vSearchPath.size())
+ {
+ char *pPath=getenv(PATH);
+ if (!pPath)
+ return 0;
+ char *Path=strdup(pPath); // To be able to use strtok
+ char *pTok=strtok(Path,OSPATHENVSEPSTR);
+ while (pTok)
+ {
+ vSearchPath.push_back(GetFileInfo(pTok,m_MakeDir));
+ pTok=strtok(NULL,OSPATHENVSEPSTR);
+ }
+ free(Path);
+ }
+ It=vSearchPath.begin();
+ ItEnd=vSearchPath.end();
+ while (It!=ItEnd)
+ {
+ pCommandFile=GetFileInfo(Command,*It);
+ if (pCommandFile->Exists())
+ goto found;
+ It++;
+ }
+
+ return 0;
+
+found:
+ string FullCommand=pCommandFile->GetFullFileName();
+ size_t CommandLen=FullCommand.size();
+ if (CommandLen>Len-1)
+ {
+ throw string("Command to long: ") + FullCommand;
+ }
+ strcpy(szFullCommand,FullCommand.c_str());
+ return 1;
+}
+
+/*****************************************************************************/
+string mhmakefileparser::SearchCommand(const string &Command, const string &Extension) const
+{
+ char FullCommand[MAX_PATH]="";
+ unsigned long Size=sizeof(FullCommand);
+ const char *pExt;
+ if (Extension.empty())
+ pExt=NULL;
+ else
+ pExt=Extension.c_str();
+ if (SearchPath(UnquoteFileName(Command).c_str(),pExt,MAX_PATH,FullCommand,NULL))
+ return FullCommand;
+#ifdef WIN32
+ /* See if we have a path for python.exe in the registry */
+ HKEY hKey;
+ string RegEntry=Command;
+ if (pExt)
+ {
+ RegEntry+=Extension;
+ }
+ string KeyName=string("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\")+RegEntry;
+ if (ERROR_SUCCESS!=RegOpenKey(HKEY_LOCAL_MACHINE,KeyName.c_str(),&hKey))
+ return FullCommand;
+
+ RegQueryValueEx(hKey,NULL,NULL,NULL,(LPBYTE)FullCommand,&Size);
+
+ RegCloseKey(hKey);
+#endif
+
+ return FullCommand;
+}
+
+/*****************************************************************************/
+/* Deletes a complete directory or files with wildcard. It can be assumed that the Directory passed does exist */
+static bool DeleteDir(const string &Dir,const string WildSearch="*",bool bRemoveDir=true)
+{
+ bool Error=false;
+ string Pattern=Dir+OSPATHSEP+WildSearch;
+#ifdef WIN32
+ WIN32_FIND_DATA FindData;
+ mh_pid_t hFind=FindFirstFile(Pattern.c_str(),&FindData);
+ if (hFind==INVALID_HANDLE_VALUE)
+ {
+ return Error;
+ }
+
+ do
+ {
+ /* Only handle items which are not . and .. */
+ if (FindData.cFileName[0]!='.' || (FindData.cFileName[1] && (FindData.cFileName[1]!='.' || FindData.cFileName[2])) )
+ {
+ string FileName=Dir+OSPATHSEP+FindData.cFileName;
+ if (FindData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
+ {
+ Error = DeleteDir(FileName);
+ }
+ else
+ {
+ Error = (-1==remove(FileName.c_str()));
+ }
+ }
+ } while (FindNextFile(hFind,&FindData));
+
+ FindClose(hFind);
+
+ if (bRemoveDir)
+ Error = (0==RemoveDirectory(Dir.c_str()));
+#else
+ glob_t Res;
+ if (glob (Pattern.c_str(), GLOB_ERR|GLOB_NOSORT|GLOB_MARK, NULL, &Res))
+ return Error;
+
+ for (int i=0; i<Res.gl_pathc; i++)
+ {
+ int Len=strlen(Res.gl_pathv[i])-1;
+ if (Res.gl_pathv[i][Len]=='/')
+ {
+ Res.gl_pathv[i][Len]=0;
+ Error = DeleteDir(Res.gl_pathv[i]);
+ }
+ else
+ {
+ Error = (-1==remove(Res.gl_pathv[i]));
+ }
+ }
+
+ globfree(&Res);
+
+ if (bRemoveDir)
+ Error = (-1==remove(Dir.c_str()));
+#endif
+
+ return Error;
+}
+
+/*****************************************************************************/
+mh_pid_t mhmakefileparser::DeleteFiles(const string &Params) const
+{
+ bool IgnoreError=false;
+ vector<fileinfo*> Files;
+
+ // First check if the first parameter is -e meaning don't give an error when file does not exist
+ if (Params[1]=='-')
+ {
+ if (Params[2]=='e')
+ {
+ IgnoreError=true;
+ SplitToItems(Params.substr(4),Files);
+ }
+ else
+ {
+ cerr << "Invalid option "<<Params[1]<<" in del statement\n";
+ return (mh_pid_t)-1;
+ }
+ }
+ else
+ {
+ SplitToItems(Params,Files);
+ }
+
+ vector<fileinfo*>::const_iterator It=Files.begin();
+ while (It!=Files.end())
+ {
+ fileinfo* pFile=*It++;
+ string DirSearch="*";
+ bool bRemoveDir=true;
+
+ /* Now check if there is a wildcard */
+ if (pFile->GetFullFileName().find('*')!=string::npos)
+ {
+ DirSearch=pFile->GetName();
+ pFile=pFile->GetDir();
+ bRemoveDir=false;
+ }
+
+ pFile->InvalidateDate();
+ if (IgnoreError && !pFile->Exists() && !pFile->IsDir())
+ {
+ continue;
+ }
+
+ const string &FileName=pFile->GetFullFileName();
+ if (pFile->IsDir())
+ {
+ if (DeleteDir(FileName,DirSearch,bRemoveDir) && !IgnoreError)
+ {
+ cerr << "Error deleting "<<FileName<<endl;
+ return (mh_pid_t)-1;
+ }
+ }
+ else
+ {
+ if (-1==remove(FileName.c_str()) && !IgnoreError)
+ {
+ cerr << "Error deleting "<<FileName<<endl;
+ return (mh_pid_t)-1;
+ }
+ }
+ }
+ return (mh_pid_t)0;
+}
+
+/*****************************************************************************/
+/* pDest can be a directory or a file */
+static bool CopyFile(fileinfo* pSrc, fileinfo* pDest)
+{
+ if (pDest->IsDir())
+ {
+ pDest=GetFileInfo(pSrc->GetName(),pDest);
+ }
+ string SrcFileName=pSrc->GetFullFileName();
+ string DestFileName=pDest->GetFullFileName();
+
+ /* Now copy the file */
+ FILE *pSrcFile=fopen(SrcFileName.c_str(),"rb");
+ if (!pSrcFile)
+ {
+ cerr << "copy: error opening file "<<SrcFileName<<endl;
+ return false;
+ }
+ FILE *pDestFile=fopen(DestFileName.c_str(),"wb");
+ if (!pDestFile)
+ {
+ cerr << "copy: error creating file "<<DestFileName<<endl;
+ return false;
+ }
+ char Buf[4096];
+ size_t Ret;
+
+ while ( (Ret=fread(Buf,1,sizeof(Buf),pSrcFile)) > 0)
+ {
+ fwrite(Buf,1,Ret,pDestFile);
+ }
+ fclose(pSrcFile);
+ fclose(pDestFile);
+ pDest->InvalidateDate();
+ return true;
+}
+
+/*****************************************************************************/
+/* Copies a complete directory to a destination (currenlty not recursive */
+static bool CopyDir(fileinfo* pDir, fileinfo* pDest,const string WildSearch="*")
+{
+ bool Error=true;
+ string Pattern=pDir->GetFullFileName()+OSPATHSEP+WildSearch;
+#ifdef WIN32
+ WIN32_FIND_DATA FindData;
+ mh_pid_t hFind=FindFirstFile(Pattern.c_str(),&FindData);
+ if (hFind==INVALID_HANDLE_VALUE)
+ {
+ return false;
+ }
+
+ do
+ {
+ /* Only handle items which are not . and .. */
+ if (FindData.cFileName[0]!='.' || (FindData.cFileName[1] && (FindData.cFileName[1]!='.' || FindData.cFileName[2])) )
+ {
+ if (FindData.dwFileAttributes&FILE_ATTRIBUTE_HIDDEN)
+ continue;
+ fileinfo* pSrc=GetFileInfo(FindData.cFileName,pDir);
+
+ if (pSrc->IsDir())
+ {
+ fileinfo* pNewDest=GetFileInfo(FindData.cFileName,pDest);
+ if (!pNewDest->IsDir())
+ {
+ if (pNewDest->Exists())
+ {
+ cerr << pNewDest->GetFullFileName() << " exists and is not a directory.\n";
+ Error = false;
+ goto exit;
+ }
+ if (!CreateDirectory(pNewDest->GetFullFileName().c_str(),NULL))
+ {
+ cerr << "Error creating directory " << pNewDest->GetFullFileName() << endl;
+ Error = false;
+ goto exit;
+ }
+ pNewDest->InvalidateDate();
+ }
+ Error = CopyDir(pSrc,pNewDest);
+ if (!Error) goto exit;
+ }
+ else
+ {
+ Error = CopyFile(pSrc,pDest);
+ if (!Error) goto exit;
+ }
+ }
+ } while (FindNextFile(hFind,&FindData));
+
+exit:
+ FindClose(hFind);
+#else
+ glob_t Res;
+ if (glob (Pattern.c_str(), GLOB_ERR|GLOB_NOSORT|GLOB_MARK, NULL, &Res))
+ return Error;
+
+ for (int i=0; i<Res.gl_pathc; i++)
+ {
+ fileinfo* pSrc=GetFileInfo(Res.gl_pathv[i],pDir);
+ if (pSrc->IsDir())
+ {
+ *(strrchr(Res.gl_pathv[i],'/'))='\0';
+ const char *SrcDirName=strrchr(Res.gl_pathv[i],'/')+1;
+
+ if (SrcDirName[0]=='.')
+ continue;
+
+ fileinfo* pNewDest=GetFileInfo(SrcDirName,pDest);
+ if (!pNewDest->IsDir())
+ {
+ if (pNewDest->Exists())
+ {
+ cerr << pNewDest->GetQuotedFullFileName() << " exists and is not a directory.\n";
+ Error = false;
+ goto exit;
+ }
+ if (-1==mkdir(pNewDest->GetFullFileName().c_str(),0777))
+ {
+ cerr << "Error creating directory " << pNewDest->GetQuotedFullFileName() << endl;
+ Error = false;
+ goto exit;
+ }
+ pNewDest->InvalidateDate();
+ }
+ Error = CopyDir(pSrc,pNewDest);
+ if (!Error) goto exit;
+ }
+ else
+ {
+ Error = CopyFile(GetFileInfo(Res.gl_pathv[i],pDir),pDest);
+ if (!Error) goto exit;
+ }
+ }
+
+exit:
+ globfree(&Res);
+#endif
+
+ return Error;
+}
+
+/*****************************************************************************/
+mh_pid_t mhmakefileparser::EchoCommand(const string &Params) const
+{
+ // Find the first > character
+ size_t Pos=Params.find_first_of('>');
+ if (Pos==string::npos)
+ {
+ // Just echo it
+ cout << Params << endl;
+ }
+ else
+ {
+ FILE *pfFile;
+ /* Extra the filename */
+ string Filename;
+ if (Params[Pos+1]=='>')
+ {
+ NextItem(Params.substr(Pos+2).c_str(),Filename);
+ fileinfo* pFile=GetFileInfo(Filename,m_MakeDir);
+ // Open file in append
+ pfFile=fopen(pFile->GetFullFileName().c_str(),"a");
+ }
+ else
+ {
+ NextItem(Params.substr(Pos+1).c_str(),Filename);
+ fileinfo* pFile=GetFileInfo(Filename,m_MakeDir);
+ pfFile=fopen(pFile->GetFullFileName().c_str(),"w");
+ }
+ if (!pfFile)
+ {
+ cerr << "Error opening file "<<Filename<<endl;
+ return (mh_pid_t)-1;
+ }
+ int Begin=0;
+ while (Params[Begin]==' ' || Params[Begin] == '\t') Begin++; // Strip leading white space
+ string EchoStr=Params.substr(Begin,Pos-1)+"\n";
+ if (EchoStr.length()!=fwrite(EchoStr.c_str(),1,EchoStr.length(),pfFile))
+ {
+ cerr << "Error writing file "<<Filename<<endl;
+ return (mh_pid_t)-1;
+ }
+ fclose(pfFile);
+ }
+ return (mh_pid_t)0;
+}
+
+/*****************************************************************************/
+mh_pid_t mhmakefileparser::CopyFiles(const string &Params) const
+{
+ vector<fileinfo*> Files;
+
+ SplitToItems(Params,Files);
+
+ size_t NrSrcs=Files.size()-1;
+
+ if (NrSrcs<1)
+ {
+ cerr << "Wrong number of arguments in copy: "<<Params<<endl;
+ return false;
+ }
+
+ fileinfo* pDest=Files[NrSrcs];
+ if (NrSrcs>1 && !pDest->IsDir())
+ {
+ cerr << "copy: Destination must be a directory when more then one source : "<<Params<<endl;
+ return (mh_pid_t)-1;
+ }
+
+ for (size_t i=0; i<NrSrcs; i++)
+ {
+ fileinfo* pSrc=Files[i];
+
+ string SrcFileName=pSrc->GetFullFileName();
+
+ if (pSrc->IsDir())
+ {
+ SrcFileName+=OSPATHSEPSTR"*";
+ pSrc=GetFileInfo(SrcFileName,m_MakeDir);
+ }
+
+ //cerr << "copy "<<pSrc->GetFullFileName()<<" "<<pDest->GetFullFileName()<<endl;
+ /* Now check if there is a wildcard */
+ if (SrcFileName.find('*')!=string::npos)
+ {
+ if (!CopyDir(pSrc->GetDir(), pDest, pSrc->GetName()))
+ {
+ cerr << "copy: Error copying directory: " << Params << endl;
+ return (mh_pid_t)-1;
+ }
+ }
+ else
+ {
+ if (!CopyFile(pSrc,pDest))
+ {
+ cerr << "copy: Error copying file: " << Params << endl;
+ return (mh_pid_t)-1;
+ }
+ }
+ }
+
+ return (mh_pid_t)0;
+
+}
+
+/*****************************************************************************/
+mh_pid_t mhmakefileparser::TouchFiles(const string &Params) const
+{
+ vector<fileinfo*> Files;
+
+ SplitToItems(Params,Files);
+
+ vector<fileinfo*>::const_iterator It=Files.begin();
+ while (It!=Files.end())
+ {
+ fileinfo* pFile=*It++;
+ const string &FileName=pFile->GetFullFileName();
+
+ /* Since this can be part of a list of commands for a certain rule, and it is possible that the file
+ * was generated by one on the previous commands, we first need the invalidate the date so that the
+ * existance checking is done again */
+ pFile->InvalidateDate();
+
+ if (pFile->IsDir())
+ {
+ cerr << "touch: Cannot touch a directory: " << FileName << endl;
+ return (mh_pid_t)-1;
+ }
+ if (pFile->Exists())
+ {
+ int fd;
+ char c;
+ int status = 0;
+ struct stat st;
+ int Ret;
+ int saved_errno = 0;
+
+ fd = open (FileName.c_str(), O_RDWR);
+ if (fd<0)
+ {
+ st.st_size=0;
+ }
+ else
+ {
+ if (fstat (fd, &st) < 0)
+ {
+ cerr << "touch: Cannot stat file " << FileName << endl;
+ return (mh_pid_t)-1;
+ }
+ }
+
+ if (st.st_size == 0)
+ {
+ FILE *pFile;
+ if (fd>=0 && close(fd) < 0)
+ {
+ cerr << "touch: Error closing file " << FileName << endl;
+ return (mh_pid_t)-1;
+ }
+ /*Re-Create an empty file */
+ pFile=fopen(FileName.c_str(),"wb");
+ if (!pFile)
+ {
+ cerr << "touch: Cannot create file: " << FileName << endl;
+ return (mh_pid_t)-1;
+ }
+ fclose(pFile);
+ }
+ else
+ {
+ Ret=read (fd, &c, sizeof(c));
+ if (Ret!=sizeof(c) && Ret!=EOF)
+ {
+ cerr << "touch: Cannot read file " << FileName << ": "<<Ret<<endl;
+ return (mh_pid_t)-1;
+ }
+ if (lseek (fd, (off_t) 0, SEEK_SET) < 0)
+ {
+ cerr << "touch: Error changing file pointer " << FileName << endl;
+ return (mh_pid_t)-1;
+ }
+ if (write (fd, &c, sizeof c) != sizeof(c))
+ {
+ cerr << "touch: Error writing file " << FileName << endl;
+ return (mh_pid_t)-1;
+ }
+ if (close (fd) < 0)
+ {
+ cerr << "touch: Error closing file " << FileName << endl;
+ return (mh_pid_t)-1;
+ }
+ }
+ }
+ else
+ {
+ /* Create an empty file */
+ FILE *pFile=fopen(FileName.c_str(),"wb");
+ if (!pFile)
+ {
+ cerr << "touch: Cannot create file: " << FileName << endl;
+ return (mh_pid_t)-1;
+ }
+ fclose(pFile);
+ }
+ pFile->InvalidateDate();
+ }
+ return (mh_pid_t)0;
+}
+
+/*****************************************************************************/
+const string &mhmakefileparser::GetPythonExe() const
+{
+ static string PythonExe;
+ if (PythonExe.empty())
+ {
+ string FullCommand=SearchCommand(PYTHONEXE);
+ if (!FullCommand.empty())
+ {
+ PythonExe=QuoteFileName(FullCommand)+" ";
+ }
+ else
+ {
+ cerr<<"python executable not found in path and registry.\n";
+ exit(1);
+ }
+ }
+ return PythonExe;
+}
+
+/*****************************************************************************/
+static const string &GetComspec()
+{
+ static string Comspec;
+ if (Comspec.empty())
+ {
+ const char *pComspec=getenv(COMSPEC);
+ if (pComspec)
+ {
+ Comspec=getenv(COMSPEC);
+ #ifdef WIN32
+ Comspec+=" /c ";
+ #else
+ Comspec+=" -c \"";
+ #endif
+ }
+ else
+ {
+ #ifdef WIN32
+ Comspec="cmd.exe /c ";
+ #else
+ Comspec="sh -c \"";
+ #endif
+ }
+ }
+ return Comspec;
+}
+
+/*****************************************************************************/
+string mhmakefileparser::GetFullCommand(string Command)
+{
+ map<string,string>::iterator pFound=m_CommandCache.find(Command);
+ string OriCommand=Command;
+ if (pFound==m_CommandCache.end())
+ {
+ bool Found=false;
+ // Not found in the stack, search in the environment path
+ // Check if an extension is specified
+ const char *pBeg=Command.c_str();
+ const char *pEnd=pBeg+Command.length()-1;
+ bool HasExt=false;
+ while (pEnd>pBeg && *pEnd!='\\' && *pEnd!='/')
+ {
+ if (*pEnd=='.')
+ {
+ HasExt=true;
+ break;
+ }
+ pEnd--;
+ }
+ if (HasExt)
+ {
+ string FullCommand=SearchCommand(Command);
+ if (!FullCommand.empty())
+ {
+ Found=true;
+ Command=FullCommand;
+ }
+ }
+ else
+ {
+ static bool s_Py2ExeInstalled=true;
+ /* First check for special internal commands */
+ if (OriCommand=="del")
+ {
+ m_CommandCache[OriCommand]="del";
+ return Command;
+ }
+ // Try with different extensions
+ string FullCommand=SearchCommand(Command,EXEEXT);
+ if (!FullCommand.empty())
+ {
+ Found=true;
+ #ifdef WIN32
+ /* Check if a python script also exists, is so try generating the executable again. */
+ string PythonFullCommand=SearchCommand(Command,".py");
+ Command=FullCommand;
+ if (!PythonFullCommand.empty()&&s_Py2ExeInstalled)
+ {
+ fileinfo* pExeFile=GetFileInfo(FullCommand,m_MakeDir);
+ fileinfo* pPyFile=GetFileInfo(PythonFullCommand,m_MakeDir);
+ bool bBuild=false;
+ if (pExeFile->GetDate().IsOlder(pPyFile->GetDate()))
+ {
+ bBuild=true;
+ }
+ if (!bBuild)
+ {
+ deps_t Autodeps;
+ GetAutoDeps(pPyFile, Autodeps);
+ deps_t::iterator It=Autodeps.begin();
+ while (It!=Autodeps.end())
+ {
+ if (pExeFile->GetDate().IsOlder((*It)->GetDate()))
+ {
+ bBuild=true;
+ break;
+ }
+ It++;
+ }
+ }
+ if (bBuild)
+ {
+ if (pExeFile->Exists())
+ remove(pExeFile->GetFullFileName().c_str());
+ CreatePythonExe(PythonFullCommand);
+ // Invalidate the exe date since it could have been recreated by the CreatePythonExe
+ pExeFile->InvalidateDate();
+ }
+
+ }
+ #else
+ Command=FullCommand;
+ #endif
+ }
+ else
+ {
+ FullCommand=SearchCommand(Command,".py");
+ if (!FullCommand.empty())
+ {
+ Found=true;
+ #ifdef WIN32
+ /* Now first try to create an executable for it */
+ if (s_Py2ExeInstalled)
+ {
+ fileinfo* pExeFile;
+ CreatePythonExe(FullCommand);
+ string ExeFullCommand=SearchCommand(Command,EXEEXT);
+ if (!ExeFullCommand.empty())
+ {
+ pExeFile=GetFileInfo(ExeFullCommand,m_MakeDir);
+ pExeFile->InvalidateDate(); // The file was just generated, make sure the correct date is taken.
+ }
+ if (ExeFullCommand.empty() || !pExeFile->Exists())
+ {
+ s_Py2ExeInstalled=false;
+ cout << "\nWarning: cannot convert "<<FullCommand<<".\nCompilation will be faster by installing py2exe.\n\n";
+ Command=GetPythonExe()+QuoteFileName(FullCommand);
+ }
+ else
+ Command=ExeFullCommand;
+ }
+ else
+ #endif
+ Command=GetPythonExe()+QuoteFileName(FullCommand);
+ }
+ }
+ }
+ if (!Found)
+ {
+ Command=GetComspec()+QuoteFileName(Command);
+ }
+ m_CommandCache[OriCommand]=Command;
+ return Command;
+ }
+ return pFound->second;
+}
+
+mh_pid_t mhmakefileparser::OsExeCommand(const string &Command, const string &Params, bool IgnoreError, string *pOutput) const
+{
+ string FullCommandLine;
+ string ComSpec=GetComspec();
+#ifdef WIN32
+ STARTUPINFO StartupInfo;
+ memset(&StartupInfo,0,sizeof(StartupInfo));
+ StartupInfo.cb=sizeof(STARTUPINFO);
+ PROCESS_INFORMATION ProcessInfo;
+
+ if (Command.substr(0,ComSpec.size())==ComSpec)
+ {
+ string tmpCommand=Command.substr(ComSpec.size(),Command.size());
+ FullCommandLine=ComSpec;
+ FullCommandLine+=g_QuoteString+QuoteFileName(tmpCommand)+Params+g_QuoteString;
+ }
+ else
+ {
+ const string PythonExe=GetPythonExe();
+ if (!(Command.substr(0,PythonExe.size())==PythonExe))
+ FullCommandLine=QuoteFileName(Command)+Params;
+ else
+ FullCommandLine=Command+Params;
+ }
+ char *pFullCommand=new char[FullCommandLine.length()+1];
+ strcpy(pFullCommand,FullCommandLine.c_str());
+
+ if (pOutput || g_Quiet)
+ {
+ mh_pid_t hChildStdinRd;
+ mh_pid_t hChildStdinWr;
+ mh_pid_t hChildStdoutRd;
+ mh_pid_t hChildStdoutWr;
+ mh_pid_t hChildStdinWrDup;
+ mh_pid_t hChildStdoutRdDup;
+ SECURITY_ATTRIBUTES saAttr;
+ BOOL fSuccess;
+
+ saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
+ saAttr.bInheritHandle = TRUE;
+ saAttr.lpSecurityDescriptor = NULL;
+
+ if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
+ return (mh_pid_t)-1;
+
+ /* Create new output read handle and the input write handle. Set
+ * the inheritance properties to FALSE. Otherwise, the child inherits
+ * the these handles; resulting in non-closeable handles to the pipes
+ * being created. */
+ fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
+ GetCurrentProcess(), &hChildStdinWrDup, 0,
+ FALSE, DUPLICATE_SAME_ACCESS);
+ if (!fSuccess) return (mh_pid_t)-1;
+ /* Close the inheritable version of ChildStdin that we're using. */
+ CloseHandle(hChildStdinWr);
+
+ if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
+ return (mh_pid_t)-1;
+
+ fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
+ GetCurrentProcess(), &hChildStdoutRdDup, 0,
+ FALSE, DUPLICATE_SAME_ACCESS);
+ if (!fSuccess) return (mh_pid_t)-1;
+ CloseHandle(hChildStdoutRd);
+
+ int hStdIn = _open_osfhandle((long)hChildStdinWrDup, _O_WRONLY|_O_TEXT);
+ FILE *pStdIn = _fdopen(hStdIn, "w");
+ int hStdOut = _open_osfhandle((long)hChildStdoutRdDup, _O_RDONLY|_O_TEXT);
+ FILE *pStdOut = _fdopen(hStdOut, "r");
+
+ StartupInfo.dwFlags = STARTF_USESTDHANDLES;
+ StartupInfo.hStdInput = hChildStdinRd;
+ StartupInfo.hStdOutput = hChildStdoutWr;
+ StartupInfo.hStdError = hChildStdoutWr;
+
+ if (!CreateProcess(NULL,pFullCommand,NULL,NULL,TRUE,CREATE_NO_WINDOW,m_pEnv,m_MakeDir->GetFullFileName().c_str(),&StartupInfo,&ProcessInfo))
+ {
+ delete[] pFullCommand;
+ string ErrorMessage=string("Error starting command: ") + FullCommandLine + " : " + stringify(GetLastError());
+ if (IgnoreError)
+ cerr << ErrorMessage << endl;
+ else
+ throw ErrorMessage;
+ }
+ delete[] pFullCommand;
+ if (!CloseHandle(hChildStdinRd)) return (mh_pid_t)-1;
+ if (!CloseHandle(hChildStdoutWr)) return (mh_pid_t)-1;
+
+ CloseHandle(ProcessInfo.hThread);
+ char Buf[256];
+ size_t Nbr;
+ while ( (Nbr=fread(Buf,1,sizeof(Buf)-1,pStdOut)) > 0)
+ {
+ if (pOutput)
+ {
+ Buf[Nbr]=0;
+ *pOutput+=Buf;
+ }
+ }
+ WaitForSingleObject(ProcessInfo.hProcess,INFINITE);
+ fclose(pStdIn);
+ fclose(pStdOut);
+
+ DWORD ExitCode=0;
+ if (!GetExitCodeProcess(ProcessInfo.hProcess,&ExitCode) || ExitCode)
+ {
+ if (IgnoreError)
+ {
+ cerr << "Error running command: "<<Command<<", but ignoring error\n";
+ return (mh_pid_t)0; // Ignore error
+ }
+ else
+ return (mh_pid_t)-1;
+ }
+ CloseHandle(ProcessInfo.hProcess);
+ return (mh_pid_t)0;
+ }
+ else
+ {
+ if (!CreateProcess(NULL,pFullCommand,NULL,NULL,TRUE,0,m_pEnv,m_MakeDir->GetFullFileName().c_str(),&StartupInfo,&ProcessInfo))
+ {
+ delete[] pFullCommand;
+ string ErrorMessage=string("Error starting command: ") + Command + " : " + stringify(GetLastError());
+ if (IgnoreError)
+ cerr << ErrorMessage << endl;
+ else
+ throw ErrorMessage;
+ }
+ delete[] pFullCommand;
+ CloseHandle(ProcessInfo.hThread);
+ return ProcessInfo.hProcess;
+ }
+#else
+ if (Command.substr(0,ComSpec.size())==ComSpec)
+ {
+ string tmpCommand=Command.substr(ComSpec.size(),Command.size());
+ FullCommandLine=ComSpec;
+ FullCommandLine+=QuoteFileName(tmpCommand)+Params;
+ }
+ else
+ {
+ FullCommandLine=Command+Params;
+ }
+
+ if (pOutput || g_Quiet)
+ {
+ int pipeto[2]; /* pipe to feed the exec'ed program input */
+ int pipefrom[2]; /* pipe to get the exec'ed program output */
+
+ pipe( pipeto );
+ pipe( pipefrom );
+
+ pid_t ID=vfork();
+ if (ID==-1)
+ {
+ if (IgnoreError)
+ {
+ cerr << "Error forking when try to run command: "<<Command<<", but ignoring error\n";
+ return (mh_pid_t)0; // Ignore error
+ }
+ else
+ return (mh_pid_t)-1;
+ }
+ else if (ID==0)
+ {
+ int argc;
+ const char **pargv;
+
+ dup2( pipeto[0], STDIN_FILENO );
+ dup2( pipefrom[1], STDOUT_FILENO );
+ /* close unnecessary pipe descriptors for a clean environment */
+ close( pipeto[0] );
+ close( pipeto[1] );
+ close( pipefrom[0] );
+ close( pipefrom[1] );
+
+ poptParseArgvString(FullCommandLine.c_str(), &argc, &pargv);
+ chdir(m_MakeDir->GetFullFileName().c_str());
+ if (m_pEnv)
+ execve(pargv[0],(char *const*)pargv,m_pEnv);
+ else
+ execv(pargv[0],(char *const*)pargv);
+ free(pargv);
+ _exit (EXIT_FAILURE);
+ }
+ else
+ {
+ /* Close unused pipe ends. This is especially important for the
+ * pipefrom[1] write descriptor, otherwise readFromPipe will never
+ * get an EOF. */
+ close( pipeto[0] );
+ close( pipefrom[1] );
+
+ pid_t ID2=vfork();
+ if (ID2==-1)
+ {
+ if (IgnoreError)
+ {
+ cerr << "Error forking when try to run command: "<<Command<<", but ignoring error\n";
+ return (mh_pid_t)0; // Ignore error
+ }
+ else
+ return (mh_pid_t)-1;
+ }
+ else if (ID2==0)
+ {
+ /* Close pipe write descriptor, or we will never know when the
+ * writer process closes its end of the pipe and stops feeding the
+ * exec'ed program. */
+ close( pipeto[1] );
+ char Buf[256];
+ int Nbr;
+ while ( (Nbr=read(pipefrom[0],Buf,sizeof(Buf)-1)) > 0)
+ {
+ if (pOutput)
+ {
+ Buf[Nbr]=0;
+ *pOutput+=Buf;
+ }
+ }
+ close( pipefrom[0]);
+ _exit (EXIT_FAILURE);
+ }
+ else
+ {
+ /* close unused pipe end */
+ close( pipefrom[0] );
+ close( pipeto[1] );
+
+ int Status;
+ waitpid(ID2,&Status,0); // Wait until the reading of the output is finished
+ }
+
+ int Status;
+ int Ret=waitpid(ID,&Status,0);
+ if (Ret!=ID || Status)
+ {
+ if (IgnoreError)
+ {
+ cerr << "Error running command: "<<Command<<", but ignoring error\n";
+ return (mh_pid_t)0; // Ignore error
+ }
+ else
+ return (mh_pid_t)-1;
+ }
+ }
+ }
+ else
+ { // No pOutput
+ pid_t ID=fork();
+ if (ID==-1)
+ {
+ if (IgnoreError)
+ {
+ cerr << "Error forking when try to run command: "<<Command<<", but ignoring error\n";
+ return (mh_pid_t)0; // Ignore error
+ }
+ else
+ return (mh_pid_t)-1;
+ }
+ else if (ID==0)
+ {
+ int argc;
+ const char **pargv;
+
+ poptParseArgvString(FullCommandLine.c_str(), &argc, &pargv);
+ chdir(m_MakeDir->GetFullFileName().c_str());
+ if (m_pEnv)
+ execve(pargv[0],(char *const*)pargv,m_pEnv);
+ else
+ execv(pargv[0],(char *const*)pargv);
+ free(pargv);
+ _exit (EXIT_FAILURE);
+ }
+ else
+ {
+ return (mh_pid_t)ID;
+ }
+ }
+
+ return (mh_pid_t)0;
+#endif
+}
+
+///////////////////////////////////////////////////////////////////////////////
+#ifndef WIN32
+string EscapeQuotes(const string &Params)
+{
+ int OldPos=0;
+ int Pos;
+ string Quote("\\\"");
+ string SemiColon(" ; ");
+ string Ret;
+
+ while (1)
+ {
+ int Pos=Params.find_first_of('"',OldPos);
+ int Pos2=Params.find(" & ",OldPos);
+ string ToReplace(Quote);
+ int Inc=1;
+
+ if (Pos==string::npos)
+ {
+ if (Pos2==string::npos)
+ break;
+ Pos=Pos2;
+ ToReplace=SemiColon;
+ Inc=3;
+ }
+ else
+ {
+ if (Pos2!=string::npos && Pos2<Pos)
+ {
+ Pos=Pos2;
+ ToReplace=SemiColon;
+ Inc=3;
+ }
+ }
+ Ret+=Params.substr(OldPos,Pos-OldPos);
+ Ret+=ToReplace;
+ OldPos=Pos+Inc;
+ }
+ Ret+=Params.substr(OldPos);
+ return Ret;
+}
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+mh_pid_t mhmakefileparser::ExecuteCommand(string Command, bool &IgnoreError, string *pOutput)
+{
+ bool Echo=true;
+ IgnoreError=false;
+ while (Command.length())
+ {
+ if (Command[0]=='@')
+ {
+ Echo=false;
+ Command=Command.substr(1);
+ continue;
+ }
+ if (Command[0]=='-')
+ {
+ IgnoreError=true;
+ Command=Command.substr(1);
+ continue;
+ }
+ break;
+ }
+ if (!Command.length())
+ (mh_pid_t)0;
+ string InCommand=Command;
+ if (g_Quiet)
+ Echo=false;
+
+ const char *pCom=Command.c_str();
+ int StartCommandPos;
+ int EndCommandPos;
+ int BeginParamPos;
+ if (*pCom=='"')
+ {
+ StartCommandPos=1;
+ EndCommandPos=1;
+ while (pCom[EndCommandPos]!='"') EndCommandPos++;
+ }
+ else
+ {
+ StartCommandPos=0;
+ EndCommandPos=0;
+ }
+ while (!strchr(" \t",pCom[EndCommandPos])) EndCommandPos++;
+ BeginParamPos=EndCommandPos;
+ string Params=Command.substr(BeginParamPos);
+ Command=Command.substr(StartCommandPos,EndCommandPos-StartCommandPos);
+
+ // If we have special characters in the params we always call the command via the shell
+ unsigned i;
+ for (i=0; i<Params.size(); i++)
+ {
+ if (strchr("<>|&",Params[i]))
+ {
+ break;
+ }
+ }
+ if (i==Params.size())
+ {
+ if (Command!="del" && Command!="touch" && Command!="copy" && Command!="echo")
+ Command=GetFullCommand(Command);
+#ifndef WIN32
+ if (Command.substr(0,GetComspec().size())==GetComspec())
+ {
+ Params=EscapeQuotes(Params);
+ Params+="\"";
+ }
+#endif
+ }
+ else
+ {
+ if (Command!="echo" || strchr(Params.c_str(),'|')) // the EchoCommand(Params) does not implement piping, only redirecting (>)
+ {
+ string FullCommand=GetFullCommand(Command);
+ string ComSpec=GetComspec();
+ if (FullCommand.substr(0,ComSpec.size())!=ComSpec)
+ Command=FullCommand; // Only use FullCommand when it was found and not prepending by the comspec.
+ Command=ComSpec+Command;
+#ifndef WIN32
+ Params=EscapeQuotes(Params);
+ Params+="\"";
+#endif
+ }
+ }
+ if (Echo
+ #ifdef _DEBUG
+ || g_DoNotExecute
+ #endif
+ )
+ {
+ #ifdef _DEBUG
+ if (g_PrintAdditionalInfo)
+ cout << Command << Params << endl;
+ else
+ cout << InCommand << endl;
+ #endif
+ }
+
+ /* first we check special internal commands */
+ #ifdef _DEBUG
+ if (pOutput || !g_DoNotExecute)
+ {
+ #endif
+ if (Command=="del")
+ {
+ return DeleteFiles(Params);
+ }
+ else if (Command=="touch")
+ {
+ return TouchFiles(Params);
+ }
+ else if (Command=="copy")
+ {
+ return CopyFiles(Params);
+ }
+ else if (Command=="echo")
+ {
+ return EchoCommand(Params);
+ }
+
+ return OsExeCommand(Command,Params,IgnoreError,pOutput);
+ #ifdef _DEBUG
+ }
+ #endif
+ return (mh_pid_t)0; /* No Error */
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void mhmakefileparser::BuildDependencies(const refptr<rule> &pRule, fileinfo* pTarget, mh_time_t TargetDate, mh_time_t &YoungestDate, bool &MakeTarget)
+{
+
+ vector<fileinfo*> &Deps=pTarget->GetDeps();
+ vector<fileinfo*>::iterator pDepIt=Deps.begin();
+ while (pDepIt!=Deps.end())
+ {
+ StartBuildTarget(*pDepIt);
+ pDepIt++;
+ }
+ pDepIt=Deps.begin();
+ while (pDepIt!=Deps.end())
+ {
+ mh_time_t DepDate=WaitBuildTarget(*pDepIt);
+ #ifdef _DEBUG
+ if (!DepDate.DoesExist()&&!(*pDepIt)->IsPhony())
+ {
+ if (!(*pDepIt)->GetDir()->GetDate().DoesExist())
+ cout << "Building of "<<(*pDepIt)->GetFullFileName()<<" failed because directory does not exist (rule defined to create it?)\n";
+ else
+ cout << "Does not known how to create "<<(*pDepIt)->GetFullFileName()<<".\n";
+ }
+ #endif
+ if (DepDate.IsNewer(YoungestDate))
+ YoungestDate=DepDate;
+ if (DepDate.IsNewer(TargetDate))
+ {
+ #ifdef _DEBUG
+ if (pRule&&g_pPrintDependencyCheck && DepDate.IsExistingFile() && TargetDate.IsExistingFile())
+ cout<<"Going to build "<<pTarget->GetQuotedFullFileName()<<" because "<<(*pDepIt)->GetQuotedFullFileName()<<" is more recent\n";
+ #endif
+ MakeTarget=true;
+ }
+ pDepIt++;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+mh_time_t mhmakefileparser::StartBuildTarget(fileinfo* pTarget,bool bCheckTargetDir)
+{
+ #ifdef _DEBUG
+ if (g_CheckCircularDeps)
+ {
+ deque<fileinfo*>::const_iterator pFind=find(m_TargetStack.begin(),m_TargetStack.end(),pTarget);
+ if (pFind!=m_TargetStack.end())
+ {
+ cout << "Circular dependency detected.\n"<<pTarget->GetQuotedFullFileName()<<" depending on itself.\n";
+ cout << "Dependency stack:\n";
+ deque<fileinfo*>::const_iterator pIt=m_TargetStack.begin();
+ while (pIt!=m_TargetStack.end())
+ {
+ cout << " " << (*pIt)->GetQuotedFullFileName() << endl;
+ pIt++;
+ }
+ }
+ if (!pTarget->IsBuildStarted()) m_TargetStack.push_back(pTarget);
+ }
+ #endif
+
+ #ifdef _DEBUG
+ static int Indent;
+ #endif
+
+ if (g_StopCompiling)
+ {
+ throw string("Compilation Interrupted by user.");
+ }
+
+ if (pTarget->IsBuild())
+ {
+ #ifdef _DEBUG
+ if (g_pPrintDependencyCheck)
+ {
+ for (int i=0; i<Indent; i++)
+ cout<<" ";
+ cout<<" Already build "<<pTarget->GetQuotedFullFileName()<<" : "<<pTarget->GetDate()<<endl;
+ }
+ #endif
+ return pTarget->GetDate();
+ }
+ if (pTarget->IsBuilding())
+ return mh_time_t(); // pTarget is still building, so we have to wait
+
+ #ifdef _DEBUG
+ if (g_GenProjectTree)
+ cout << pTarget->GetQuotedFullFileName() << endl;
+
+ Indent++;
+ if (g_pPrintDependencyCheck)
+ {
+ for (int i=0; i<Indent; i++)
+ cout<<" ";
+ cout<<"Building dependencies of "<<pTarget->GetQuotedFullFileName()<<endl;
+ }
+ #endif
+
+ pTarget->SetBuild();
+
+ /* Optimisation: do not build target when target dir does not exist,
+ but first build the target dir, in case there exists a rule for it*/
+ refptr<rule> pRule=pTarget->GetRule();
+
+ if (!pRule && bCheckTargetDir)
+ {
+ fileinfo *pTargetDir=pTarget->GetDir();
+ mh_time_t TargetDirDate=BuildTarget(pTargetDir,false);
+
+ if (!pTargetDir->Exists())
+ {
+ #ifdef _DEBUG
+ Indent--;
+ if (g_CheckCircularDeps)
+ {
+ m_TargetStack.pop_back();
+ }
+ #endif
+ return TargetDirDate;
+ }
+ }
+
+ mh_time_t TargetDate=pTarget->GetDate();
+ bool MakeTarget=false;
+ mh_time_t YoungestDate=TargetDate;
+
+ if (!pRule || !pRule->GetCommands().size())
+ {
+ implicitruledep_t Result;
+
+ IMPLICITRULE::SearchImplicitRule(pTarget,Result);
+
+ implicitruledep_t::iterator ResultIt=Result.begin();
+ while (ResultIt!=Result.end())
+ {
+ if (ResultIt->first.empty())
+ {
+ pRule=ResultIt->second;
+ pTarget->SetRule(pRule);
+ #ifdef _DEBUG
+ if (g_PrintAdditionalInfo)
+ {
+ cout<<"Found implicit rule for "<<pTarget->GetQuotedFullFileName()<<endl;
+ pRule->PrintCommands(pTarget);
+ }
+ #endif
+ break;
+ }
+ else if (!IMPLICITRULE::PushRule(ResultIt->second))
+ {
+ /* We have to check all the implicitrule dependencies, only when they all can be build,
+ the implicit rule matches */
+ #ifdef _DEBUG
+ fileinfo *pYoungestTarget;
+ m_ImplicitSearch++;
+ #endif
+ mh_time_t ThisYoungestDate=YoungestDate;
+ vector<fileinfo*>::iterator ImplicitRuleDepsIt=ResultIt->first.begin();
+ while (ImplicitRuleDepsIt!=ResultIt->first.end())
+ {
+ fileinfo *pNewTarget=*ImplicitRuleDepsIt;
+ mh_time_t DepDate=BuildTarget(pNewTarget);
+ if (!DepDate.DoesExist())
+ {
+ pNewTarget=ResultIt->second->GetMakefile()->SearchvPath(pNewTarget);
+ if (pNewTarget!=NULL)
+ {
+ *ImplicitRuleDepsIt=pNewTarget; /* The file was elsewere so we have to update the dependencies */
+ DepDate=pNewTarget->GetDate();
+ }
+ }
+ if (!DepDate.DoesExist())
+ break;
+ if (DepDate.IsNewer(ThisYoungestDate))
+ {
+ ThisYoungestDate=DepDate;
+ #ifdef _DEBUG
+ pYoungestTarget=pNewTarget;
+ #endif
+ }
+ ImplicitRuleDepsIt++;
+ }
+
+ IMPLICITRULE::PopRule(ResultIt->second);
+ #ifdef _DEBUG
+ m_ImplicitSearch--;
+ #endif
+ if (ImplicitRuleDepsIt==ResultIt->first.end()) // All deps exists
+ {
+ ThisYoungestDate=YoungestDate;
+ pRule=ResultIt->second;
+ pTarget->InsertDeps(ResultIt->first);
+ pTarget->SetRule(pRule); /* This is an implicit rule so do not add the target */
+ #ifdef _DEBUG
+ if (g_PrintAdditionalInfo)
+ {
+ cout<<"Found implicit rule for "<<pTarget->GetQuotedFullFileName()<<". Dependents:\n";
+ vector<fileinfo*>::iterator ImplicitRuleDepsIt=ResultIt->first.begin();
+ while (ImplicitRuleDepsIt!=ResultIt->first.end())
+ {
+ cout<<" "<<(*ImplicitRuleDepsIt)->GetQuotedFullFileName()<<endl;
+ ImplicitRuleDepsIt++;
+ }
+ pRule->PrintCommands(pTarget);
+ }
+ #endif
+ if (ThisYoungestDate.IsNewer(TargetDate))
+ {
+ #ifdef _DEBUG
+ if (pRule,g_pPrintDependencyCheck && ThisYoungestDate.IsExistingFile() && TargetDate.IsExistingFile())
+ cout<<"Going to build "<<pTarget->GetQuotedFullFileName()<<" because "<<pYoungestTarget->GetQuotedFullFileName()<<" is more recent\n";
+ #endif
+ MakeTarget=true;
+ }
+ break;
+ }
+ }
+ #ifdef _DEBUG
+ else if (g_PrintAdditionalInfo)
+ {
+ cout << "Stopping implicit search of "<<pTarget->GetFullFileName()<<" because of implicit rule recursion detected.\n";
+ }
+ #endif
+ ResultIt++;
+ }
+ if (pRule)
+ {
+ #ifdef _DEBUG
+ pTarget->SetBuilding();
+ pTarget->SetRule(pRule);
+ pTarget->ClearBuilding();
+ #else
+ pTarget->SetRule(pRule);
+ #endif
+ }
+ }
+
+ mhmakefileparser *pMakefile=NULL;
+ if (pRule)
+ {
+ pMakefile=pRule->GetMakefile();
+ if (pMakefile->ForceAutoDepRescan()||MakeTarget==true)
+ pMakefile->UpdateAutomaticDependencies(pTarget);
+ }
+ else if (pTarget->GetAutoDepsMakefile())
+ pTarget->GetAutoDepsMakefile()->UpdateNoRuleAutomaticDependencies(pTarget);
+
+ BuildDependencies(pRule,pTarget,TargetDate,YoungestDate,MakeTarget);
+
+ if (pRule)
+ {
+ #ifdef _DEBUG
+ if (g_pPrintDependencyCheck)
+ {
+ for (int i=0; i<Indent; i++)
+ cout<<" ";
+ cout<<"Building "<<pTarget->GetQuotedFullFileName()<<endl;
+ }
+ #endif
+ if (!MakeTarget)
+ {
+ if (!TargetDate.DoesExist() || ( (g_RebuildAll || pMakefile->m_RebuildAll) && TargetDate.IsOlder(m_sBuildTime)))
+ {
+ #ifdef _DEBUG
+ if (g_pPrintDependencyCheck)
+ {
+ if (!TargetDate.DoesExist())
+ {
+ if (!m_ImplicitSearch && !pTarget->IsPhony())
+ cout<<"Building "<<pTarget->GetQuotedFullFileName()<<" because it does not exist yet\n";
+ }
+ else if (TargetDate.IsOlder(m_sBuildTime))
+ {
+ cout<<"Building "<<pTarget->GetQuotedFullFileName()<<" because need to rebuild all (-a)\n";
+ }
+ }
+ #endif
+ MakeTarget=true;
+ }
+ }
+
+ // Now execute the commands
+ vector<string> &Commands=pRule->GetCommands();
+
+ if (!MakeTarget)
+ {
+ vector<string>::iterator CommandIt=Commands.begin();
+
+ md5_context ctx;
+ md5_starts( &ctx );
+ while (CommandIt!=Commands.end())
+ {
+ pMakefile->SetRuleThatIsBuild(pTarget); // Make sure that the command expension is correct
+ string Command=pMakefile->ExpandExpression(*CommandIt);
+ pMakefile->ClearRuleThatIsBuild(); /* Make sure that further expansion is not taking this rule into account.*/
+ md5_update( &ctx, (uint8 *)Command.c_str(), (unsigned long)Command.size());
+ CommandIt++;
+ }
+
+ uint32 Md5_32=md5_finish32( &ctx);
+ if (!pTarget->CompareMd5_32(Md5_32))
+ {
+ if (TargetDate.IsNewerOrSame(m_sBuildTime) || TargetDate.IsDir())
+ {
+ // Only rebuild if it is not yet rebuild in this current run. This may happen for implicit rules that have multiple targets (implicit rules that build more then one target at the same time
+ pTarget->SetCommandsMd5_32(Md5_32);
+ pMakefile->AddTarget(pTarget);
+ pMakefile->SetAutoDepsDirty(); /* We need to update the autodeps file if the md5 has been changed */
+ }
+ else
+ {
+ #ifdef _DEBUG
+ if (!g_GenProjectTree)
+ cout << "Md5 is different for " << pTarget->GetQuotedFullFileName() << " Old:"<<hex<<pTarget->GetCommandsMd5_32()<<", New: "<<Md5_32<<". Commandline must have been changed so recompiling\n";
+ #endif
+
+ #ifdef _DEBUG
+ Indent--;
+ if (g_CheckCircularDeps)
+ {
+ m_TargetStack.pop_back();
+ }
+ #endif
+
+ MakeTarget=true;
+ }
+ }
+ }
+ if (MakeTarget)
+ {
+ // Queue for execution
+ if (sm_CommandQueue.QueueTarget(pTarget))
+ return mh_time_t();
+ mh_time_t NewDate=pTarget->GetDate();
+ if (NewDate.IsNewer(YoungestDate))
+ YoungestDate=NewDate;
+ }
+ }
+
+ #ifdef _DEBUG
+ if (g_pPrintDependencyCheck)
+ {
+ for (int i=0; i<Indent; i++)
+ cout<<" ";
+ cout<<"Building "<<pTarget->GetQuotedFullFileName()<<" finished : "<< YoungestDate << endl;
+ }
+ Indent--;
+ if (g_CheckCircularDeps)
+ {
+ m_TargetStack.pop_back();
+ }
+
+ if (!m_ImplicitSearch && !pTarget->Exists() && !pTarget->IsPhony() && !g_DoNotExecute && !g_GenProjectTree)
+ {
+ // This is only a warning for phony messages
+ cout<<"Warning: don't know how to make "<<pTarget->GetQuotedFullFileName()<<"\nMake the rule a phony rule to avoid this warning (but only do it when it is really phony).\n";;
+ }
+ #endif
+ pTarget->SetDate(YoungestDate); /* This is especially needed for phony targets in between real targets */
+ return YoungestDate;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+mh_time_t mhmakefileparser::WaitBuildTarget(fileinfo* pTarget)
+{
+ return sm_CommandQueue.WaitForTarget(pTarget);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void mhmakefileparser::BuildIncludedMakefiles()
+{
+ vector<fileinfo*>::iterator MakefileIt=m_IncludedMakefiles.begin();
+ while (MakefileIt!=m_IncludedMakefiles.end())
+ {
+ #ifdef _DEBUG
+ if (g_PrintAdditionalInfo)
+ cout<<"Building include file "<<(*MakefileIt)->GetQuotedFullFileName()<<endl;
+ #endif
+ BuildTarget(*MakefileIt);
+ MakefileIt++;
+ }
+}
diff --git a/tools/mhmake/src/commandqueue.cpp b/tools/mhmake/src/commandqueue.cpp
new file mode 100644
index 000000000..6f3fd4d1a
--- /dev/null
+++ b/tools/mhmake/src/commandqueue.cpp
@@ -0,0 +1,410 @@
+/* This file is part of mhmake.
+ *
+ * Copyright (C) 2001-2010 marha@sourceforge.net
+ *
+ * Mhmake 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Mhmake 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 Mhmake. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* $Rev$ */
+
+#include "stdafx.h"
+
+#include "commandqueue.h"
+#include "mhmakeparser.h"
+
+#ifndef WIN32
+
+#define INFINITE 0
+#define FALSE 0
+
+static int Status;
+unsigned WaitForMultipleObjects(int Nbr, mh_pid_t *phProcesses, int, int)
+{
+ mh_pid_t ID=waitpid(0,&Status,0);
+ for (int i=0; i<Nbr; i++)
+ {
+ if (ID==phProcesses[i])
+ return i;
+ }
+ return -1;
+}
+
+typedef unsigned DWORD;
+
+int GetExitCodeProcess(mh_pid_t hProcess, DWORD *pExitCode)
+{
+ *pExitCode=Status;
+ return true;
+}
+
+#define CloseHandle(Handle)
+
+#endif
+
+
+commandqueue::commandqueue() :
+ m_NrActiveEntries(0)
+{
+#ifdef WIN32
+ SYSTEM_INFO SysInfo;
+ GetSystemInfo(&SysInfo);
+ m_MaxNrCommandsInParallel=SysInfo.dwNumberOfProcessors;
+
+ m_DummyWaitHandle=(mh_pid_t)CreateEvent(NULL,TRUE,FALSE,NULL);
+#else
+ FILE *pFile=fopen("/proc/cpuinfo","r");
+ const char *pProc="\nprocessor";
+ int cur=1;
+ int NrProcs=0;
+ while (!feof(pFile))
+ {
+ char In=fgetc(pFile);
+ if (In==pProc[cur])
+ {
+ cur++;
+ if (!pProc[cur])
+ {
+ NrProcs++;
+ cur=0;
+ }
+ }
+ else
+ cur=0;
+ }
+ m_MaxNrCommandsInParallel=NrProcs;
+ m_DummyWaitHandle=(mh_pid_t)-1;
+
+#endif
+
+ m_pActiveProcesses=new mh_pid_t[m_MaxNrCommandsInParallel];
+ m_pActiveEntries= new refptr<activeentry>[m_MaxNrCommandsInParallel];
+}
+
+commandqueue::~commandqueue()
+{
+ delete [] m_pActiveProcesses;
+ delete [] m_pActiveEntries;
+ #ifdef WIN32
+ CloseHandle(m_DummyWaitHandle);
+ #endif
+}
+
+void commandqueue::SetNrParallelBuilds(unsigned NrParallelBuilds)
+{
+ if (m_NrActiveEntries)
+ throw("Changing of number of parallel builds is only allowed when no commands are executing");
+ NrParallelBuilds=max(1u,NrParallelBuilds);
+ m_MaxNrCommandsInParallel=NrParallelBuilds;
+ delete [] m_pActiveProcesses;
+ delete [] m_pActiveEntries;
+ m_pActiveProcesses=new mh_pid_t[NrParallelBuilds];
+ m_pActiveEntries= new refptr<activeentry>[NrParallelBuilds];
+}
+
+void commandqueue::ThrowCommandExecutionError(refptr<activeentry> pActiveEntry)
+{
+ fileinfo* pTarget=pActiveEntry->pTarget;
+ const string &Command=pActiveEntry->Command;
+ mhmakefileparser *pMakefile=pTarget->GetRule()->GetMakefile();
+
+ string ErrorMessage = string("Error running command: ")+ Command +"\n";
+ ErrorMessage += "Command defined in makefile: " + pMakefile->GetMakeDir()->GetQuotedFullFileName();
+ pTarget->SetCommandsMd5_32(0); /* Clear the md5 to make sure that the target is rebuild the next time mhmake is ran */
+ pMakefile->SetAutoDepsDirty(); /* We need to update the autodeps file if the md5 has been changed */
+ throw ErrorMessage;
+}
+
+refptr<commandqueue::activeentry> commandqueue::CreateActiveEntry(void)
+{
+ refptr<activeentry> pRet=new activeentry;
+ m_pActiveEntries[m_NrActiveEntries]=pRet;
+ m_pActiveProcesses[m_NrActiveEntries]=this->m_DummyWaitHandle;
+ m_NrActiveEntries++;
+ return pRet;
+}
+
+unsigned commandqueue::GetActiveEntryId(const refptr<activeentry> pActiveEntry) const
+{
+ unsigned i=0;
+ for (i=0; i<m_NrActiveEntries; i++)
+ if (m_pActiveEntries[i]==pActiveEntry)
+ return i;
+ throw("ActiveEntry not found for "+ pActiveEntry->pTarget->GetFullFileName());
+}
+
+void commandqueue::RemoveActiveEntry(unsigned Entry)
+{
+//cout << "Remove entry "<<Entry<<" of "<<m_NrActiveEntries<<" from queue:"<<m_pActiveEntries[Entry].pTarget->GetQuotedFullFileName()<<<<" ("<<m_pActiveEntries[Entry]<<")\n";
+ unsigned NrToMove=m_NrActiveEntries-Entry-1;
+ if (NrToMove)
+ {
+ for (unsigned i=0; i<NrToMove; i++)
+ {
+ unsigned EntryP1=Entry+1;
+ m_pActiveEntries[Entry]=m_pActiveEntries[EntryP1];
+ m_pActiveProcesses[Entry]=m_pActiveProcesses[EntryP1];
+ Entry=EntryP1;
+ }
+ }
+ m_pActiveEntries[Entry]=NULL;
+ m_pActiveProcesses[Entry]=NULL;
+ m_NrActiveEntries--;
+}
+
+/* Start to execute next command, return true when command is completely executed
+ upon return */
+bool commandqueue::StartExecuteNextCommand(refptr<activeentry> pActiveEntry, mh_pid_t *pActiveProcess)
+{
+ fileinfo* pTarget=pActiveEntry->pTarget;
+ mhmakefileparser *pMakefile=pTarget->GetRule()->GetMakefile();
+
+ pMakefile->SetRuleThatIsBuild(pTarget); // Make sure that the command expension is correct
+ string Command=pMakefile->ExpandExpression(*pActiveEntry->CurrentCommandIt);
+ pMakefile->ClearRuleThatIsBuild(); /* Make sure that further expansion is not taking this rule into account.*/
+ md5_update( &pActiveEntry->md5ctx, (uint8 *)Command.c_str(), (unsigned long)Command.size());
+
+ pActiveEntry->Command=Command;
+
+ #ifdef _DEBUG
+ if (g_pPrintDependencyCheck)
+ {
+ cout<<"-> "<<Command<<endl;
+ }
+ if (!g_GenProjectTree)
+ {
+ #endif
+ mh_pid_t hProcess=pMakefile->ExecuteCommand(Command,pActiveEntry->IgnoreError);
+ if (hProcess==(mh_pid_t)-1)
+ {
+ ThrowCommandExecutionError(pActiveEntry);
+ }
+ else if (!hProcess)
+ {
+ // Command already finished, so execute next command
+ return true;
+ }
+ else
+ {
+ // Command still executing, so add it to the list of handles to wait for
+ *pActiveProcess=hProcess;
+ return false;
+ }
+ #ifdef _DEBUG
+ }
+ #endif
+ return true;
+}
+
+void commandqueue::TargetBuildFinished(refptr<activeentry> pActiveEntry)
+{
+ fileinfo* pTarget=pActiveEntry->pTarget;
+
+ // Building of this target finished
+ uint32 Md5_32=md5_finish32( &pActiveEntry->md5ctx);
+ #ifdef _DEBUG
+ if (g_DoNotExecute||g_GenProjectTree)
+ pTarget->SetDateToNow();
+ else
+ #endif
+ pTarget->InvalidateDate();
+
+ pTarget->SetCommandsMd5_32(Md5_32); /* If the rule of the target was added with an implicit rule the targets in the rule is empty */
+
+ refptr<rule> pRule=pTarget->GetRule();
+ mhmakefileparser *pMakefile=pRule->GetMakefile();
+
+ pMakefile->AddTarget(pTarget);
+ pMakefile->SetAutoDepsDirty();
+ pRule->SetTargetsIsBuild(Md5_32);
+
+ #ifdef _DEBUG
+ if (g_pPrintDependencyCheck)
+ {
+ cout<<"Building "<<pTarget->GetQuotedFullFileName()<<" finished : "<< pTarget->GetDate() << endl;
+ }
+
+ if (!pMakefile->ImplicitSearch() && !pTarget->Exists() && !pTarget->IsPhony() && !g_DoNotExecute && !g_GenProjectTree)
+ {
+ // This is only a warning for phony messages
+ cout<<"Warning: don't know how to make "<<pTarget->GetQuotedFullFileName()<<"\nMake the rule a phony rule to avoid this warning (but only do it when it is really phony).\n";;
+ }
+ #endif
+
+ pTarget->ClearBuilding();
+}
+
+/* Start executing the commands of a target
+*/
+bool commandqueue::StartExecuteCommands(fileinfo* pTarget)
+{
+ cout << "Building " << pTarget->GetQuotedFullFileName()<<endl;
+ // We do not have to put it in the queue, we can start executing directly
+ refptr<rule> pRule=pTarget->GetRule();
+ mhmakefileparser *pMakefile=pRule->GetMakefile();
+ vector<string>::iterator CommandIt=pRule->GetCommands().begin();
+
+ refptr<activeentry> pActiveEntry=CreateActiveEntry();
+ mh_pid_t ActiveProcess;
+
+ md5_starts( &pActiveEntry->md5ctx );
+
+ pActiveEntry->pTarget=pTarget;
+ pActiveEntry->CurrentCommandIt=CommandIt;
+
+ while (1)
+ {
+ if (StartExecuteNextCommand(pActiveEntry, &ActiveProcess))
+ {
+ pActiveEntry->CurrentCommandIt++;
+ if (pActiveEntry->CurrentCommandIt==pRule->GetCommands().end())
+ {
+ // All commands executed
+ break;
+ }
+ }
+ else
+ {
+ m_pActiveProcesses[GetActiveEntryId(pActiveEntry)]=ActiveProcess; // We use GetActiveEntryId to avoid reentrancy problems
+ return false;
+ }
+ }
+ TargetBuildFinished(pActiveEntry);
+ RemoveActiveEntry(pActiveEntry);
+ return true;
+}
+
+
+/* put the target in the execution queue or start executing immediately
+*/
+bool commandqueue::QueueTarget(fileinfo* pTarget)
+{
+ pTarget->SetBuilding();
+ // First check if there is place in the active entries
+ if (m_NrActiveEntries==m_MaxNrCommandsInParallel)
+ {
+ // commands cannot be started yet
+ m_Queue.push(pTarget);
+ return true;
+ }
+ else
+ {
+ return !StartExecuteCommands(pTarget);
+ }
+}
+
+/* Wait for all the commands being executed of a target. In the mean time also continue
+ executing all other commands in the queue
+*/
+mh_time_t commandqueue::WaitForTarget(fileinfo *pTarget)
+{
+ if (!pTarget->IsBuilding())
+ return pTarget->GetDate();
+
+ while (1)
+ {
+ // First wait until one of the processes that are running is finished
+ if (m_NrActiveEntries==1 && m_pActiveProcesses[0]==this->m_DummyWaitHandle)
+ {
+ #ifdef _DEBUG
+ if (pTarget!=m_pActiveEntries[0]->pTarget)
+ throw("Wrong assumption: waiting for target " + pTarget->GetFullFileName() + " but in wait list is " + m_pActiveEntries[0]->pTarget->GetFullFileName());
+ #endif
+ pTarget->SetDateToNow();
+ return pTarget->GetDate(); // This is a reentrancy problem, assume that the target is just build
+ }
+ unsigned Ret=WaitForMultipleObjects(m_NrActiveEntries,m_pActiveProcesses,FALSE,INFINITE);
+ if (Ret>=m_NrActiveEntries)
+ #ifdef WIN32
+ throw("fatal error: unexpected return value of WaitForMultipleObjects " + stringify(Ret) + " " + stringify(GetLastError()));
+ #else
+ throw("fatal error: unexpected return value of WaitForMultipleObjects " + stringify(Ret));
+ #endif
+ refptr<activeentry> pActiveEntry=m_pActiveEntries[Ret];
+ fileinfo* pCurrentTarget=pActiveEntry->pTarget;
+ refptr<rule> pRule=pCurrentTarget->GetRule();
+
+ // First check the error code of the command
+ DWORD ExitCode=0;
+ mh_pid_t hProcess=m_pActiveProcesses[Ret];
+ if (!GetExitCodeProcess(hProcess,&ExitCode) || ExitCode)
+ {
+ if (pActiveEntry->IgnoreError)
+ {
+ cerr << "Error running command: "<<pActiveEntry->Command<<", but ignoring error\n";
+ }
+ else
+ ThrowCommandExecutionError(pActiveEntry);
+ }
+ CloseHandle(hProcess);
+
+ // Now check if we have to execute more commands for this target
+ pActiveEntry->CurrentCommandIt++;
+ while (pActiveEntry->CurrentCommandIt!=pRule->GetCommands().end())
+ {
+ if (!StartExecuteNextCommand(pActiveEntry, &m_pActiveProcesses[Ret]))
+ break; // We have to wait for end of command execution
+ pActiveEntry->CurrentCommandIt++;
+ }
+
+ if (pActiveEntry->CurrentCommandIt==pRule->GetCommands().end())
+ {
+ TargetBuildFinished(pActiveEntry);
+ // Target building finished, so remove it from the list of active entries
+ RemoveActiveEntry(Ret);
+
+ bool Return=false;
+ if (pTarget==pCurrentTarget)
+ {
+ Return = true;
+ }
+ // Check if we have other entries in the queue to start
+ while (1)
+ {
+ if (m_Queue.empty())
+ {
+ // There should still be active entries, otherwise this is a serious bug
+ if (!m_NrActiveEntries && !Return)
+ {
+ // This may happen when having multiple target rules and pTarget was build when on of the other targets
+ // was build. so first check if the pTarget was not build in the mean time. If so, this is not an error
+ if (pTarget->IsBuild())
+ {
+ Return=true;
+ break;
+ }
+ else
+ throw("Fatal error: WaitForTarget "+pTarget->GetQuotedFullFileName()+": no active targets anymore.");
+ }
+ else
+ break;
+ }
+ else
+ {
+ fileinfo* pNewTarget=m_Queue.front();
+ m_Queue.pop();
+ if (StartExecuteCommands(pNewTarget))
+ {
+ if (pNewTarget==pTarget)
+ Return=true;
+ }
+ else
+ break;
+ }
+ }
+ if (Return)
+ return pTarget->GetDate();
+ }
+ }
+
+}
diff --git a/tools/mhmake/src/commandqueue.h b/tools/mhmake/src/commandqueue.h
new file mode 100644
index 000000000..8b327be8c
--- /dev/null
+++ b/tools/mhmake/src/commandqueue.h
@@ -0,0 +1,73 @@
+/* This file is part of mhmake.
+ *
+ * Copyright (C) 2001-2010 marha@sourceforge.net
+ *
+ * Mhmake 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Mhmake 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 Mhmake. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* $Rev$ */
+
+#ifndef __COMMANDQUEUE_H__
+#define __COMMANDQUEUE_H__
+
+#include "fileinfo.h"
+
+#ifdef WIN32
+typedef HANDLE mh_pid_t;
+#else
+typedef pid_t mh_pid_t;
+#endif
+
+class commandqueue
+{
+ struct activeentry : public refbase
+ {
+ fileinfo* pTarget;
+ vector<string>::const_iterator CurrentCommandIt;
+ string Command;
+ md5_context md5ctx;
+ bool IgnoreError;
+ };
+private:
+ queue<fileinfo*> m_Queue;
+ unsigned m_MaxNrCommandsInParallel;
+ mh_pid_t *m_pActiveProcesses;
+ refptr<activeentry> *m_pActiveEntries;
+ unsigned m_NrActiveEntries;
+ mh_pid_t m_DummyWaitHandle;
+
+private:
+ void ThrowCommandExecutionError(refptr<activeentry> pActiveEntry);
+ refptr<activeentry> CreateActiveEntry(void);
+ unsigned GetActiveEntryId(const refptr<activeentry> pActiveEntry) const;
+ void RemoveActiveEntry(unsigned Entry);
+ void RemoveActiveEntry(refptr<activeentry> pActiveEntry)
+ {
+ RemoveActiveEntry(GetActiveEntryId(pActiveEntry));
+ }
+ bool StartExecuteCommands(fileinfo *pTarget);
+ bool StartExecuteNextCommand(refptr<activeentry> pActiveEntry, mh_pid_t *pActiveProcess);
+ void TargetBuildFinished(refptr<activeentry> pActiveEntry);
+
+public:
+ commandqueue();
+ ~commandqueue();
+
+ bool QueueTarget(fileinfo *pTarget); // Returns true if target has been queued, false when commands are executed upon return
+ mh_time_t WaitForTarget(fileinfo *pTarget);
+ void SetNrParallelBuilds(unsigned NrParallelBuilds);
+};
+
+
+#endif
diff --git a/tools/mhmake/src/curdir.cpp b/tools/mhmake/src/curdir.cpp
new file mode 100644
index 000000000..4b905a327
--- /dev/null
+++ b/tools/mhmake/src/curdir.cpp
@@ -0,0 +1,37 @@
+/* This file is part of mhmake.
+ *
+ * Copyright (C) 2001-2010 marha@sourceforge.net
+ *
+ * Mhmake 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Mhmake 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 Mhmake. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* $Rev$ */
+
+#include "stdafx.h"
+
+#include "fileinfo.h"
+#include "curdir.h"
+#include "util.h"
+
+fileinfos g_FileInfos; // declare here since it is important that it is constructed before m_pcurrentdir
+curdir::initcurdir curdir::m_pCurrentDir;
+
+///////////////////////////////////////////////////////////////////////////////
+curdir::initcurdir::initcurdir()
+{
+ char CurDir[MAX_PATH];
+ getcwd(CurDir,MAX_PATH);
+ string strCurDir=CurDir;
+ m_pDir=GetAbsFileInfo(NormalizePathName(strCurDir));
+}
diff --git a/tools/mhmake/src/curdir.h b/tools/mhmake/src/curdir.h
new file mode 100644
index 000000000..138f8f45a
--- /dev/null
+++ b/tools/mhmake/src/curdir.h
@@ -0,0 +1,47 @@
+/* This file is part of mhmake.
+ *
+ * Copyright (C) 2001-2010 marha@sourceforge.net
+ *
+ * Mhmake 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Mhmake 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 Mhmake. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* $Rev$ */
+
+#ifndef __CURDIR_H
+#define __CURDIR_H
+
+class fileinfo;
+
+class curdir
+{
+public:
+ class initcurdir
+ {
+ friend class curdir;
+ const fileinfo *m_pDir;
+ public:
+ initcurdir();
+ };
+private:
+ static initcurdir m_pCurrentDir;
+
+public:
+ static const fileinfo* GetCurDir()
+ {
+ return m_pCurrentDir.m_pDir;
+ }
+};
+
+#endif
+
diff --git a/tools/mhmake/src/fileinfo.cpp b/tools/mhmake/src/fileinfo.cpp
new file mode 100644
index 000000000..7174c49a4
--- /dev/null
+++ b/tools/mhmake/src/fileinfo.cpp
@@ -0,0 +1,363 @@
+/* This file is part of mhmake.
+ *
+ * Copyright (C) 2001-2010 marha@sourceforge.net
+ *
+ * Mhmake 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Mhmake 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 Mhmake. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* $Rev$ */
+
+#include "stdafx.h"
+
+#include "fileinfo.h"
+#include "rule.h"
+#include "util.h"
+#include "mhmakeparser.h"
+
+#ifndef S_ISDIR
+#define S_ISDIR(val) ((val)&_S_IFDIR)
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+string QuoteFileName(const string &Filename)
+{
+ string Ret(Filename);
+#if OSPATHSEP=='\\'
+ /* Put quotes around the string if there are spaces in it */
+ if (Ret.find_first_of(' ')!=string::npos && Ret[0]!='"')
+ {
+ Ret=g_QuoteString+Ret+g_QuoteString;
+ }
+#else
+ int Pos=0;
+ /* Escape the spaces with a backslash */
+ while ((Pos=Ret.find_first_of(' ',Pos))!=string::npos)
+ {
+ Ret=Ret.replace(Pos,1,"\\ ");
+ Pos+=2;
+ }
+#endif
+ return Ret;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string UnquoteFileName(const string &Filename)
+{
+ size_t Pos=0;
+ string Name(Filename);
+#if OSPATHSEP=='\\'
+ /* Remove all the quotes from the filename */
+ while ((Pos=Name.find_first_of('"',Pos))!=string::npos)
+ {
+ Name=Name.replace(Pos,1,"");
+ }
+#else
+ /* Remove the escaped spaces */
+ while ((Pos=Name.find_first_of("\\",Pos))!=string::npos)
+ {
+ if (Name[Pos+1]==' ')
+ Name=Name.replace(Pos,2," ");
+ Pos+=1;
+ }
+#endif
+ return Name;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+fileinfo* fileinfo::GetDir() const
+{
+ return GetAbsFileInfo(m_AbsFileName.substr(0,m_AbsFileName.find_last_of(OSPATHSEP)));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string fileinfo::GetName() const
+{
+ return m_AbsFileName.substr(m_AbsFileName.find_last_of(OSPATHSEP)+1);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+mh_time_t fileinfo::realGetDate() const
+{
+ struct stat Buf;
+ if (-1==stat(m_AbsFileName.c_str(),&Buf))
+ ((fileinfo*)this)->m_Date.SetNotExist();
+ else if (S_ISDIR(Buf.st_mode))
+ ((fileinfo*)this)->m_Date.SetDir();
+ else
+ ((fileinfo*)this)->m_Date=Buf.st_mtime;
+ return m_Date;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool fileinfo::IsDir() const
+{
+#ifdef WIN32
+ WIN32_FIND_DATA FindData;
+ HANDLE hFind=FindFirstFile(m_AbsFileName.c_str(),&FindData);
+ if (hFind==INVALID_HANDLE_VALUE)
+ {
+ return false;
+ }
+ else
+ {
+ FindClose(hFind);
+ if (FindData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+#else
+ struct stat Buf;
+ if (-1==stat(m_AbsFileName.c_str(),&Buf))
+ return false; // File does not exist, so consider this as not a directory
+ else
+ return 0!=S_ISDIR (Buf.st_mode);
+ return true;
+#endif
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void fileinfo::SetDateToNow()
+{
+ m_Date=time(NULL);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string fileinfo::GetPrerequisits() const
+{
+ // Build a string with all prerequisits, but make sure that every dependency
+ // is only in there once (we do this be building a set in parallel
+ vector<fileinfo*>::const_iterator DepIt=m_Deps.begin();
+ deps_t Deps;
+ bool first=true;
+ string Ret=g_EmptyString;
+ while (DepIt!=m_Deps.end())
+ {
+ deps_t::iterator pFound=Deps.find(*DepIt);
+ if (pFound==Deps.end())
+ {
+ if (first)
+ {
+ first=false;
+ }
+ else
+ {
+ Ret+=g_SpaceString;
+ }
+ Ret+=(*DepIt)->GetQuotedFullFileName();
+ }
+ Deps.insert(*DepIt);
+ DepIt++;
+ }
+ return Ret;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void fileinfo::AddDeps(vector<fileinfo*> &Deps)
+{
+ vector<fileinfo*>::iterator It=Deps.begin();
+ vector<fileinfo*>::iterator ItEnd=Deps.end();
+ while (It!=ItEnd)
+ {
+ AddDep(*It++);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool fileinfo::IsAutoDepExtention(void) const
+{
+ const char *pName=GetFullFileName().c_str();
+ const char *pExt=strrchr(pName,'.');
+ if (!pExt)
+ return false;
+ pExt++;
+ if (m_pRule)
+ {
+ string ObjExt=m_pRule->GetMakefile()->ExpandVar(OBJEXTVAR);
+ return ((0==strcmp(pExt,ObjExt.c_str()+1)) || (0==strcmp(pExt,"h")));
+ }
+ else
+ return ((0==strcmp(pExt,"obj")) || (0==strcmp(pExt,"doj")) || (0==strcmp(pExt,"o")) || (0==strcmp(pExt,"h")));
+}
+
+#ifdef _DEBUG
+///////////////////////////////////////////////////////////////////////////////
+string fileinfo::GetErrorMessageDuplicateRule(const refptr<rule>&pRule)
+{
+ string Ret;
+ Ret = GetQuotedFullFileName() + ": rule is defined multiple times\n";
+ Ret += "First (" + m_pRule->GetMakefile()->GetMakeDir()->GetQuotedFullFileName() + ") :\n";
+
+ vector<string>::const_iterator It=m_pRule->GetCommands().begin();
+ while (It!=m_pRule->GetCommands().end())
+ {
+ Ret+= " " + m_pRule->GetMakefile()->ExpandExpression(*It) + "\n";
+ It++;
+ }
+ Ret += "Second (" + pRule->GetMakefile()->GetMakeDir()->GetQuotedFullFileName() + ") :\n";
+ It=pRule->GetCommands().begin();
+ while (It!=pRule->GetCommands().end())
+ {
+ Ret += " " + pRule->GetMakefile()->ExpandExpression(*It) +"\n";
+ It++;
+ }
+ return Ret;
+}
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+string &NormalizePathName(string &Name)
+{
+ const char *pPtr=Name.c_str();
+ const char *pBeg=pPtr;
+ const char *pLastSlash=NULL;
+ char *pWr=(char*)pBeg;
+ char Char=*pPtr++;
+
+ while (Char)
+ {
+ if (Char=='\\' || Char=='/')
+ {
+ char Char2=pPtr[0];
+ if (Char2=='.')
+ {
+ if (pPtr[1]=='.')
+ {
+ pPtr+=2;
+ while ((pPtr[0]=='\\' || pPtr[0]=='/') && pPtr[1]=='.' && pPtr[2]=='.')
+ {
+ pLastSlash--;
+ while (*pLastSlash!='\\' && *pLastSlash!='/') pLastSlash--;
+ if (pLastSlash<pBeg)
+ pLastSlash=pBeg; // This is a fault in the file name, just put it back at the beginning
+ pPtr+=3;
+ }
+ if (pLastSlash)
+ pWr=(char*)pLastSlash;
+ }
+ else
+ {
+ if (pPtr[1]=='\\' || pPtr[1]=='/')
+ {
+ pPtr++;
+ }
+ else
+ {
+ pLastSlash=pWr;
+ *pWr++ = OSPATHSEP;
+ }
+ }
+ }
+ else if (Char2=='\\' || Char2=='/')
+ {
+ }
+ else
+ {
+ pLastSlash=pWr;
+ *pWr++ = OSPATHSEP;
+ }
+ }
+ else
+ {
+ #ifdef WIN32
+ *pWr++ = tolower(Char);
+ #else
+ *pWr++ = Char;
+ #endif
+ }
+ Char=*pPtr++;
+ }
+ *pWr=0;
+ Name.resize(pWr-pBeg);
+
+ return Name;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+fileinfo* GetFileInfo(const string &NameIn,const fileinfo* pRelDir)
+{
+ string Name=UnquoteFileName(NameIn);
+ bool DoesExist=true;
+
+ //Only concatenate if szName is not already a full name
+#ifdef WIN32
+ if (!Name.empty() && (Name.length()==1 || Name[1]!=':'))
+#endif
+ {
+ if (Name[0]!=OSPATHSEP)
+ {
+ Name=pRelDir->GetFullFileName()+OSPATHSEPSTR+Name;
+ if (!pRelDir->Exists()) /* if the directory does not exist, the file will not exist either */
+ DoesExist=false;
+ }
+ #ifdef WIN32
+ else
+ {
+ /* The filename is absolute but does not contain a driver letter. So add it (only on windows) */
+ Name=pRelDir->GetFullFileName().substr(0,2)+Name;
+ }
+ #endif
+ }
+ fileinfo* pRet=GetAbsFileInfo(NormalizePathName(Name));
+ if (!DoesExist)
+ pRet->SetNotExist();
+ return pRet;
+}
+
+#ifdef _DEBUG
+///////////////////////////////////////////////////////////////////////////////
+void PrintFileInfos()
+{
+ fileinfos::iterator pIt=g_FileInfos.begin();
+ while (pIt!=g_FileInfos.end())
+ {
+ cout<<(*pIt)->GetQuotedFullFileName()<<" :";
+ if ((*pIt)->IsPhony())
+ cout<<" (phony)";
+ vector<fileinfo*> &Deps=(*pIt)->GetDeps();
+ vector<fileinfo*>::iterator pDepIt=Deps.begin();
+ while (pDepIt!=Deps.end())
+ {
+ cout<<g_SpaceString<<(*pDepIt)->GetQuotedFullFileName();
+ pDepIt++;
+ }
+ cout<<endl;
+ // Write the commands
+ refptr<rule> pRule=(*pIt)->GetRule();
+ if (pRule)
+ {
+ cout<<g_SpaceString<<"Run in: "<<pRule->GetMakefile()->GetMakeDir()->GetQuotedFullFileName()<<endl;
+ pRule->PrintCommands();
+ }
+ pIt++;
+ }
+
+}
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+fileinfos::~fileinfos()
+{
+ fileinfos::iterator It=begin();
+ while (It!=end())
+ {
+ delete (*It);
+ It++;
+ }
+}
diff --git a/tools/mhmake/src/fileinfo.h b/tools/mhmake/src/fileinfo.h
new file mode 100644
index 000000000..1d70f0df1
--- /dev/null
+++ b/tools/mhmake/src/fileinfo.h
@@ -0,0 +1,437 @@
+/* This file is part of mhmake.
+ *
+ * Copyright (C) 2001-2010 marha@sourceforge.net
+ *
+ * Mhmake 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Mhmake 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 Mhmake. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* $Rev$ */
+
+#ifndef __FILEINFO_H
+#define __FILEINFO_H
+
+#include "curdir.h"
+#include "rule.h"
+#include "md5.h"
+
+#ifdef WIN32
+#define OSPATHSEP '\\'
+#define OSPATHSEPSTR "\\"
+#define OSPATHENVSEP ';'
+#define OSPATHENVSEPSTR ";"
+#else
+#define OSPATHSEP '/'
+#define OSPATHSEPSTR "/"
+#define OSPATHENVSEP ':'
+#define OSPATHENVSEPSTR ":"
+#endif
+
+extern bool g_DumpOnError;
+extern bool g_PrintVarsAndRules;
+extern bool g_DoNotExecute;
+extern bool g_GenProjectTree;
+extern bool g_Quiet;
+extern bool g_RebuildAll;
+extern bool g_PrintAdditionalInfo;
+extern bool g_pPrintDependencyCheck;
+extern bool g_CheckCircularDeps;
+extern bool g_ForceAutoDepRescan;
+extern bool g_PrintLexYacc;
+extern bool g_Clean;
+extern bool g_StopCompiling;
+extern bool g_PrintMultipleDefinedRules;
+
+extern const string g_EmptyString;
+extern const string g_SpaceString;
+extern const string g_QuoteString;
+
+string QuoteFileName(const string &Filename);
+string UnquoteFileName(const string &Filename);
+
+template<typename T>
+inline string stringify(const T& x)
+{
+ ostringstream o;
+ o << x;
+ return o.str();
+}
+
+#define TIMESAFETY 3
+class mh_time
+{
+ enum
+ {
+ DATENOTVALID=0,
+ NOTEXISTTIME=1,
+ DIRTIME =2+TIMESAFETY
+ };
+ unsigned long m_Time;
+
+ bool operator < (const mh_time &Src);
+public:
+ mh_time(){m_Time=DATENOTVALID;}
+ mh_time(time_t Time) : m_Time((unsigned long)Time) {}
+ mh_time(unsigned long Time) : m_Time(Time) {}
+ mh_time(const mh_time &Time) : m_Time(Time.m_Time) {}
+
+ void SetDir(void)
+ {
+ m_Time=DIRTIME;
+ }
+ bool IsDir(void) const
+ {
+ return m_Time==DIRTIME;
+ }
+ void SetNotExist(void)
+ {
+ m_Time=NOTEXISTTIME;
+ }
+ bool IsExistingFile(void) const
+ {
+ return m_Time>DIRTIME;
+ }
+ bool DoesExist(void) const
+ {
+ return m_Time!=NOTEXISTTIME;
+ }
+ void Invalidate(void)
+ {
+ m_Time=DATENOTVALID;
+ }
+ bool IsDateValid(void) const
+ {
+ return m_Time!=DATENOTVALID;
+ }
+ friend ostream& operator<<(ostream& out,const mh_time &Src);
+
+ mh_time &operator = (const mh_time &Src) { m_Time=Src.m_Time; return *this;}
+
+ bool IsOlder(const mh_time &Src) const { return m_Time<Src.m_Time-TIMESAFETY; }
+
+ bool IsNewer(const mh_time &Src) const { return m_Time>Src.m_Time+TIMESAFETY; }
+ bool IsNewerOrSame(const mh_time &Src) const { return m_Time>=Src.m_Time-TIMESAFETY; }
+};
+typedef mh_time mh_time_t;
+
+inline ostream& operator<<(ostream& out,const mh_time &Src)
+{
+ out << hex << (unsigned long)Src.m_Time;
+ return out;
+}
+
+class fileinfo
+{
+ string m_AbsFileName;
+ bool m_IsPhony;
+ int m_BuildStatus; /* Bit 0 means the target built is started, Bit 1 means the target is still building */
+ refptr<rule> m_pRule;
+ mhmakefileparser *m_pAutoDepsMakefile;
+ vector<fileinfo*> m_Deps;
+ mh_time_t m_Date;
+ uint32 m_CommandsMd5_32; // 32-bit Md5 checksum of commands to build this target
+
+ fileinfo(const fileinfo &Src);
+ fileinfo(void);
+
+ void init(const string &AbsFileName,uint32 Md5_32)
+ {
+ m_IsPhony=false;
+ m_pAutoDepsMakefile=NULL;
+ m_BuildStatus=0;
+ m_AbsFileName=UnquoteFileName(AbsFileName);
+ InvalidateDate();
+ m_CommandsMd5_32=Md5_32;
+ #ifdef _DEBUG
+ if (g_PrintAdditionalInfo)
+ cout << "Initialising Md5 of "<<GetQuotedFullFileName().c_str()<<" to 0x"<<hex<<Md5_32<<endl;
+ #endif
+ }
+ fileinfo &operator = (const fileinfo &Src); // Do not allow copying
+public:
+ fileinfo(const string &AbsFileName,uint32 Md5_32)
+ {
+ init(AbsFileName,Md5_32);
+ }
+ fileinfo(const string &AbsFileName)
+ {
+ init(AbsFileName,0);
+ }
+ /* The following constructor is only used for name comparisons, and should only be used for that */
+ fileinfo(int Dummy,const string &AbsFileName)
+ {
+ m_AbsFileName=UnquoteFileName(AbsFileName);
+ }
+
+ fileinfo(const char *szFile)
+ {
+ init(szFile,0);
+ }
+ fileinfo(const char *szFile,uint32 Md5_32)
+ {
+ init(szFile,Md5_32);
+ }
+ const string &GetFullFileName(void) const
+ {
+ return m_AbsFileName;
+ }
+ string GetQuotedFullFileName(void) const
+ {
+ return QuoteFileName(m_AbsFileName);
+ }
+ void SetFullFileName(const string &strAbsName)
+ {
+ m_AbsFileName=UnquoteFileName(strAbsName);
+ // If the last char is path sep strip it
+ if (!m_AbsFileName.empty() && m_AbsFileName[m_AbsFileName.length()-1]==OSPATHSEP)
+ m_AbsFileName.resize(m_AbsFileName.length()-1);
+ }
+
+ fileinfo* GetDir(void) const;
+ string GetName() const;
+ bool IsDir() const;
+
+ string GetErrorMessageDuplicateRule(const refptr<rule> &pRule);
+
+ void SetRule(refptr<rule> &pRule)
+ {
+ #if defined(_DEBUG) && defined(_MSC_VER)
+ if (m_pRule && m_pRule->GetCommands().size() && !IsBuilding()) {
+ DebugBreak();
+ }
+ #endif
+ m_pRule=pRule;
+ }
+
+ void SetRuleIfNotExist(refptr<rule> &pRule)
+ {
+ if (pRule)
+ {
+ if (!m_pRule)
+ {
+ SetRule(pRule);
+ pRule->AddTarget(this);
+ }
+ #ifdef _DEBUG
+ else
+ {
+ if (*m_pRule!=*pRule)
+ {
+ throw(GetErrorMessageDuplicateRule(pRule));
+ }
+ else if (g_PrintMultipleDefinedRules)
+ {
+ cerr<<GetErrorMessageDuplicateRule(pRule);
+ }
+ }
+ #endif
+ }
+ }
+
+ refptr<rule> GetRule(void) const
+ {
+ return m_pRule;
+ }
+ void AddDep(fileinfo *pDep)
+ {
+ if (&*pDep==this)
+ {
+ #ifdef _DEBUG
+ cout << GetQuotedFullFileName()<<" is directly dependent on itself\n";
+ #endif
+ return;
+ }
+ m_Deps.push_back(pDep);
+ }
+ void AddDeps(vector<fileinfo*> &Deps);
+
+ void InsertDeps(vector<fileinfo*> &Deps)
+ {
+ #ifdef _DEBUG
+ vector<fileinfo*> NewDeps;
+ vector<fileinfo*>::const_iterator It=Deps.begin();
+ vector<fileinfo*>::const_iterator ItEnd=Deps.end();
+ while (It!=ItEnd)
+ {
+ if (&**It==this)
+ {
+ #ifdef _DEBUG
+ cout << GetQuotedFullFileName()<<" is directly dependent on itself\n";
+ #endif
+ }
+ else
+ NewDeps.push_back(*It);
+ It++;
+ }
+ if (NewDeps.size())
+ m_Deps.insert(m_Deps.begin(),NewDeps.begin(),NewDeps.end());
+ #else
+ m_Deps.insert(m_Deps.begin(),Deps.begin(),Deps.end());
+ #endif
+ }
+ vector<fileinfo*> &GetDeps(void)
+ {
+ return m_Deps;
+ }
+ string GetPrerequisits(void) const;
+ void SetAutoDepsScan(mhmakefileparser *pMakefile)
+ {
+ #ifdef _DEBUG
+ if (m_pAutoDepsMakefile)
+ throw(string(".AUTODEPS can only defined ones for rule ")+GetFullFileName());
+ #endif
+ m_pAutoDepsMakefile=pMakefile;
+ }
+ mhmakefileparser *GetAutoDepsMakefile(void) const
+ {
+ return m_pAutoDepsMakefile;
+ }
+ void SetPhony(void)
+ {
+ m_IsPhony=true;
+ m_Date.SetNotExist(); // This will sure that this target will always be build (even if a corresponding file exists)
+ }
+ bool IsPhony(void) const
+ {
+ return m_IsPhony;
+ }
+ mh_time_t realGetDate(void) const;
+ void SetDateToNow(void);
+
+ void SetDate(mh_time_t Date)
+ {
+ m_Date=Date;
+ }
+
+ bool IsDateValid() const
+ {
+ return m_Date.IsDateValid();
+ }
+ void InvalidateDate(void)
+ {
+ m_Date.Invalidate();
+ }
+
+ mh_time_t GetDate(void) const
+ {
+ if (m_Date.IsDateValid())
+ return m_Date;
+ else
+ return realGetDate();
+ }
+ void SetNotExist(void)
+ { // this is used to make sure that this item is rebuild, even if it really exists
+ m_Date.SetNotExist();
+ }
+ bool Exists(void) const
+ {
+ return GetDate().DoesExist();
+ }
+ bool IsBuildStarted(void) const
+ {
+ return (m_BuildStatus&1)==1;
+ }
+ bool IsBuild(void) const
+ {
+ return m_BuildStatus==1;
+ }
+ void SetBuild(void)
+ {
+ m_BuildStatus=1;
+ }
+ bool IsBuilding(void) const
+ {
+ return (m_BuildStatus&2)==2;
+ }
+ void SetBuilding(bool Others=true)
+ {
+ m_BuildStatus|=2;
+ /* Check if there are targets build by the rule attached to this target, if so set them also to building */
+ if (Others && m_pRule)
+ {
+ m_pRule->SetTargetsIsBuilding(this);
+ }
+ }
+ void ClearBuilding(void)
+ {
+ m_BuildStatus&=~2;
+ }
+ bool IsAutoDepExtention(void) const;
+
+ void SetCommandsMd5_32(uint32 Md5_32)
+ {
+ #ifdef _DEBUG
+ if (g_PrintAdditionalInfo)
+ cout << "Setting Md5 of "<<GetQuotedFullFileName()<<" to 0x"<<hex<<Md5_32<<endl;
+ #endif
+ m_CommandsMd5_32=Md5_32;
+ }
+#ifdef _DEBUG
+ uint32 GetCommandsMd5_32(void) const
+ {
+ return m_CommandsMd5_32;
+ }
+#endif
+ bool CompareMd5_32(uint32 Md5_32) const
+ {
+ return m_CommandsMd5_32==Md5_32;
+ }
+ void WriteMd5_32(FILE *pFile) const
+ {
+ fwrite(&m_CommandsMd5_32,sizeof(m_CommandsMd5_32),1,pFile);
+ }
+};
+
+struct less_fileinfo : public binary_function <const fileinfo*, const fileinfo*, bool>
+{
+ bool operator()(const fileinfo *_Left, const fileinfo *_Right) const
+ {
+ return less<string>().operator ()(_Left->GetFullFileName(),_Right->GetFullFileName());
+ }
+};
+
+fileinfo *GetFileInfo(const string &szName,const fileinfo* pRelDir);
+
+class fileinfos : public set<fileinfo*,less_fileinfo>
+{
+ public:
+ ~fileinfos();
+};
+
+extern fileinfos g_FileInfos;
+
+inline fileinfo *GetAbsFileInfo(const string &strAbsName)
+{
+ static fileinfo SearchFileInfo("");
+ SearchFileInfo.SetFullFileName(strAbsName);
+ /* Using find is just an optimalisation, you could use insert immediately */
+ fileinfos::const_iterator pFind=g_FileInfos.find(&SearchFileInfo);
+ if (pFind==g_FileInfos.end())
+ {
+ pair <fileinfos::iterator, bool> pPair=g_FileInfos.insert(new fileinfo(SearchFileInfo.GetFullFileName()));
+ return *(pPair.first);
+ }
+ else
+ return *pFind;
+}
+
+inline fileinfo *GetFileInfo(const char *szName,const fileinfo* pRelDir)
+{
+ return GetFileInfo(string(szName),pRelDir);
+}
+
+string &NormalizePathName(string &Name);
+void PrintFileInfos();
+
+#endif
+
diff --git a/tools/mhmake/src/flex.skl b/tools/mhmake/src/flex.skl
new file mode 100644
index 000000000..4d57bac46
--- /dev/null
+++ b/tools/mhmake/src/flex.skl
@@ -0,0 +1,3426 @@
+%# -*-C-*- vi: set ft=c:
+%# This file is processed in several stages.
+%# Here are the stages, as best as I can describe:
+%#
+%# 1. flex.skl is processed through GNU m4 during the
+%# pre-compilation stage of flex. Only macros starting
+%# with `m4preproc_' are processed, and quoting is normal.
+%#
+%# 2. The preprocessed skeleton is translated verbatim into a
+%# C array, saved as "skel.c" and compiled into the flex binary.
+%#
+%# 3. At runtime, the skeleton is generated and filtered (again)
+%# through m4. Macros beginning with `m4_' will be processed.
+%# The quoting is "[[" and "]]" so we don't interfere with
+%# user code.
+%#
+%# All generate macros for the m4 stage contain the text "m4" or "M4"
+%# in them. This is to distinguish them from CPP macros.
+%# The exception to this rule is YY_G, which is an m4 macro,
+%# but it needs to be remain short because it is used everywhere.
+%#
+/* A lexical scanner generated by flex */
+
+%# Macros for preproc stage.
+
+%# Macros for runtime processing stage.
+m4_changecom
+m4_changequote
+m4_changequote([[, ]])
+
+%#
+%# Lines in this skeleton starting with a "%" character are "control lines"
+%# and affect the generation of the scanner. The possible control codes are
+%# listed and processed in misc.c.
+%#
+%# %# - A comment. The current line is omitted from the generated scanner.
+%# %if-c++-only - The following lines are printed for C++ scanners ONLY.
+%# %if-c-only - The following lines are NOT printed for C++ scanners.
+%# %if-c-or-c++ - The following lines are printed in BOTH C and C++ scanners.
+%# %if-reentrant - Print for reentrant scanners.(push)
+%# %if-not-reentrant - Print for non-reentrant scanners. (push)
+%# %if-bison-bridge - Print for bison-bridge. (push)
+%# %if-not-bison-bridge - Print for non-bison-bridge. (push)
+%# %endif - pop from the previous if code.
+%# %% - A stop-point, where code is inserted by flex.
+%# Each stop-point is numbered here and also in the code generator.
+%# (See gen.c, etc. for details.)
+%# %not-for-header - Begin code that should NOT appear in a ".h" file.
+%# %ok-for-header - %c and %e are used for building a header file.
+%# %if-tables-serialization
+%#
+%# All control-lines EXCEPT comment lines ("%#") will be inserted into
+%# the generated scanner as a C-style comment. This is to aid those who
+%# edit the skeleton.
+%#
+
+%not-for-header
+%if-c-only
+%if-not-reentrant
+m4_ifelse(M4_YY_PREFIX,yy,,
+#define yy_create_buffer M4_YY_PREFIX[[_create_buffer]]
+#define yy_delete_buffer M4_YY_PREFIX[[_delete_buffer]]
+#define yy_flex_debug M4_YY_PREFIX[[_flex_debug]]
+#define yy_init_buffer M4_YY_PREFIX[[_init_buffer]]
+#define yy_flush_buffer M4_YY_PREFIX[[_flush_buffer]]
+#define yy_load_buffer_state M4_YY_PREFIX[[_load_buffer_state]]
+#define yy_switch_to_buffer M4_YY_PREFIX[[_switch_to_buffer]]
+#define yyin M4_YY_PREFIX[[in]]
+#define yyleng M4_YY_PREFIX[[leng]]
+#define yylex M4_YY_PREFIX[[lex]]
+#define yylineno M4_YY_PREFIX[[lineno]]
+#define yyout M4_YY_PREFIX[[out]]
+#define yyrestart M4_YY_PREFIX[[restart]]
+#define yytext M4_YY_PREFIX[[text]]
+#define yywrap M4_YY_PREFIX[[wrap]]
+#define yyalloc M4_YY_PREFIX[[alloc]]
+#define yyrealloc M4_YY_PREFIX[[realloc]]
+#define yyfree M4_YY_PREFIX[[free]]
+)
+%endif
+%endif
+%ok-for-header
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION FLEX_MAJOR_VERSION
+#define YY_FLEX_MINOR_VERSION FLEX_MINOR_VERSION
+#define YY_FLEX_SUBMINOR_VERSION FLEX_SUBMINOR_VERSION
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+%# Some negated symbols
+m4_ifdef( [[M4_YY_IN_HEADER]], , [[m4_define([[M4_YY_NOT_IN_HEADER]], [[]])]])
+m4_ifdef( [[M4_YY_REENTRANT]], , [[m4_define([[M4_YY_NOT_REENTRANT]], [[]])]])
+
+%# This is the m4 way to say "(stack_used || is_reentrant)
+m4_ifdef( [[M4_YY_STACK_USED]], [[m4_define([[M4_YY_HAS_START_STACK_VARS]])]])
+m4_ifdef( [[M4_YY_REENTRANT]], [[m4_define([[M4_YY_HAS_START_STACK_VARS]])]])
+
+%# Prefixes.
+%# The complexity here is necessary so that m4 preserves
+%# the argument lists to each C function.
+
+
+m4_ifdef( [[M4_YY_PREFIX]],, [[m4_define([[M4_YY_PREFIX]], [[yy]])]])
+
+%if-c++-only
+ /* The c++ scanner is a mess. The FlexLexer.h header file relies on the
+ * following macro. This is required in order to pass the c++-multiple-scanners
+ * test in the regression suite. We get reports that it breaks inheritance.
+ * We will address this in a future release of flex, or omit the C++ scanner
+ * altogether.
+ */
+ #define yyFlexLexer M4_YY_PREFIX[[FlexLexer]]
+%endif
+
+%if-c-only
+ M4_GEN_PREFIX(`_create_buffer')
+ M4_GEN_PREFIX(`_delete_buffer')
+ M4_GEN_PREFIX(`_scan_buffer')
+ M4_GEN_PREFIX(`_scan_string')
+ M4_GEN_PREFIX(`_scan_bytes')
+ M4_GEN_PREFIX(`_init_buffer')
+ M4_GEN_PREFIX(`_flush_buffer')
+ M4_GEN_PREFIX(`_load_buffer_state')
+ M4_GEN_PREFIX(`_switch_to_buffer')
+ M4_GEN_PREFIX(`push_buffer_state')
+ M4_GEN_PREFIX(`pop_buffer_state')
+ M4_GEN_PREFIX(`ensure_buffer_stack')
+ M4_GEN_PREFIX(`lex')
+ M4_GEN_PREFIX(`restart')
+ M4_GEN_PREFIX(`lex_init')
+ M4_GEN_PREFIX(`lex_init_extra')
+ M4_GEN_PREFIX(`lex_destroy')
+ M4_GEN_PREFIX(`get_debug')
+ M4_GEN_PREFIX(`set_debug')
+ M4_GEN_PREFIX(`get_extra')
+ M4_GEN_PREFIX(`set_extra')
+ M4_GEN_PREFIX(`get_in')
+ M4_GEN_PREFIX(`set_in')
+ M4_GEN_PREFIX(`get_out')
+ M4_GEN_PREFIX(`set_out')
+ M4_GEN_PREFIX(`get_leng')
+ M4_GEN_PREFIX(`get_text')
+ M4_GEN_PREFIX(`get_lineno')
+ M4_GEN_PREFIX(`set_lineno')
+ m4_ifdef( [[M4_YY_REENTRANT]],
+ [[
+ M4_GEN_PREFIX(`get_column')
+ M4_GEN_PREFIX(`set_column')
+ ]])
+ M4_GEN_PREFIX(`wrap')
+%endif
+
+m4_ifdef( [[M4_YY_BISON_LVAL]],
+[[
+ M4_GEN_PREFIX(`get_lval')
+ M4_GEN_PREFIX(`set_lval')
+]])
+
+m4_ifdef( [[<M4_YY_BISON_LLOC>]],
+[[
+ M4_GEN_PREFIX(`get_lloc')
+ M4_GEN_PREFIX(`set_lloc')
+]])
+
+%if-c-only
+m4_ifdef( [[M4_YY_NOT_REENTRANT]],
+[[
+ M4_GEN_PREFIX(`text')
+ M4_GEN_PREFIX(`leng')
+ M4_GEN_PREFIX(`in')
+ M4_GEN_PREFIX(`out')
+ M4_GEN_PREFIX(`_flex_debug')
+ M4_GEN_PREFIX(`lineno')
+]])
+%endif
+
+
+m4_ifdef( [[M4_YY_TABLES_EXTERNAL]],
+[[
+ M4_GEN_PREFIX(`tables_fload')
+ M4_GEN_PREFIX(`tables_destroy')
+ M4_GEN_PREFIX(`TABLES_NAME')
+]])
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+%if-c-only
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+%endif
+
+%if-tables-serialization
+#include <sys/types.h>
+#include <netinet/in.h>
+%endif
+/* end standard C headers. */
+
+%if-c-or-c++
+#include <flexint.h>
+%endif
+
+%if-c++-only
+/* begin standard C++ headers. */
+#include <iostream>
+#include <errno.h>
+#include <cstdlib>
+#include <cstring>
+/* end standard C++ headers. */
+%endif
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif /* defined (__STDC__) */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+%# For compilers that can not handle prototypes.
+%# e.g.,
+%# The function prototype
+%# int foo(int x, char* y);
+%#
+%# ...should be written as
+%# int foo M4_YY_PARAMS(int x, char* y);
+%#
+%# ...which could possibly generate
+%# int foo ();
+%#
+m4_ifdef( [[M4_YY_NO_ANSI_FUNC_PROTOS]],
+[[
+ m4_define( [[M4_YY_PARAMS]], [[()]])
+]],
+[[
+ m4_define( [[M4_YY_PARAMS]], [[($*)]])
+]])
+
+%not-for-header
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+%ok-for-header
+
+%not-for-header
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+%ok-for-header
+
+
+
+%if-reentrant
+
+/* An opaque pointer. */
+#ifndef YY_TYPEDEF_YY_SCANNER_T
+#define YY_TYPEDEF_YY_SCANNER_T
+typedef void* yyscan_t;
+#endif
+
+%# Declare yyguts variable
+m4_define( [[M4_YY_DECL_GUTS_VAR]], [[struct yyguts_t * yyg = (struct yyguts_t*)yyscanner]])
+%# For use wherever a Global is accessed or assigned.
+m4_define( [[YY_G]], [[yyg->$1]])
+
+%# For use in function prototypes to append the additional argument.
+m4_define( [[M4_YY_PROTO_LAST_ARG]], [[, yyscan_t yyscanner]])
+m4_define( [[M4_YY_PROTO_ONLY_ARG]], [[yyscan_t yyscanner]])
+
+%# For use in function definitions to append the additional argument.
+m4_ifdef( [[M4_YY_NO_ANSI_FUNC_DEFS]],
+[[
+ m4_define( [[M4_YY_DEF_LAST_ARG]], [[, yyscanner]])
+ m4_define( [[M4_YY_DEF_ONLY_ARG]], [[yyscanner]])
+]],
+[[
+ m4_define( [[M4_YY_DEF_LAST_ARG]], [[, yyscan_t yyscanner]])
+ m4_define( [[M4_YY_DEF_ONLY_ARG]], [[yyscan_t yyscanner]])
+]])
+m4_define( [[M4_YY_DECL_LAST_ARG]], [[yyscan_t yyscanner;]])
+
+%# For use in function calls to pass the additional argument.
+m4_define( [[M4_YY_CALL_LAST_ARG]], [[, yyscanner]])
+m4_define( [[M4_YY_CALL_ONLY_ARG]], [[yyscanner]])
+
+%# For use in function documentation to adjust for additional argument.
+m4_define( [[M4_YY_DOC_PARAM]], [[@param yyscanner The scanner object.]])
+
+/* For convenience, these vars (plus the bison vars far below)
+ are macros in the reentrant scanner. */
+#define yyin YY_G(yyin_r)
+#define yyout YY_G(yyout_r)
+#define yyextra YY_G(yyextra_r)
+#define yyleng YY_G(yyleng_r)
+#define yytext YY_G(yytext_r)
+#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
+#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
+#define yy_flex_debug YY_G(yy_flex_debug_r)
+
+m4_define( [[M4_YY_INCR_LINENO]],
+[[
+ do{ yylineno++;
+ yycolumn=0;
+ }while(0)
+]])
+
+%endif
+
+
+
+%if-not-reentrant
+
+m4_define( [[M4_YY_INCR_LINENO]],
+[[
+ yylineno++;
+]])
+
+%# Define these macros to be no-ops.
+m4_define( [[M4_YY_DECL_GUTS_VAR]], [[m4_dnl]])
+m4_define( [[YY_G]], [[($1)]])
+m4_define( [[M4_YY_PROTO_LAST_ARG]])
+m4_define( [[M4_YY_PROTO_ONLY_ARG]], [[void]])
+m4_define( [[M4_YY_DEF_LAST_ARG]])
+
+m4_ifdef( [[M4_YY_NO_ANSI_FUNC_DEFS]],
+[[
+ m4_define( [[M4_YY_DEF_ONLY_ARG]])
+]],
+[[
+ m4_define( [[M4_YY_DEF_ONLY_ARG]], [[void]])
+]])
+m4_define([[M4_YY_DECL_LAST_ARG]])
+m4_define([[M4_YY_CALL_LAST_ARG]])
+m4_define([[M4_YY_CALL_ONLY_ARG]])
+m4_define( [[M4_YY_DOC_PARAM]], [[]])
+
+%endif
+
+
+m4_ifdef( [[M4_YY_NO_ANSI_FUNC_DEFS]],
+[[
+%# For compilers that need traditional function definitions.
+%# e.g.,
+%# The function prototype taking 2 arguments
+%# int foo (int x, char* y)
+%#
+%# ...should be written as
+%# int foo YYFARGS2(int,x, char*,y)
+%#
+%# ...which could possibly generate
+%# int foo (x,y,yyscanner)
+%# int x;
+%# char * y;
+%# yyscan_t yyscanner;
+%#
+%# Generate traditional function defs
+ m4_define( [[YYFARGS0]], [[(M4_YY_DEF_ONLY_ARG) [[\]]
+ M4_YY_DECL_LAST_ARG]])
+ m4_define( [[YYFARGS1]], [[($2 M4_YY_DEF_LAST_ARG) [[\]]
+ $1 $2; [[\]]
+ M4_YY_DECL_LAST_ARG]])
+ m4_define( [[YYFARGS2]], [[($2,$4 M4_YY_DEF_LAST_ARG) [[\]]
+ $1 $2; [[\]]
+ $3 $4; [[\]]
+ M4_YY_DECL_LAST_ARG]])
+ m4_define( [[YYFARGS3]], [[($2,$4,$6 M4_YY_DEF_LAST_ARG) [[\]]
+ $1 $2; [[\]]
+ $3 $4; [[\]]
+ $5 $6; [[\]]
+ M4_YY_DECL_LAST_ARG]])
+]],
+[[
+%# Generate C99 function defs.
+ m4_define( [[YYFARGS0]], [[(M4_YY_DEF_ONLY_ARG)]])
+ m4_define( [[YYFARGS1]], [[($1 $2 M4_YY_DEF_LAST_ARG)]])
+ m4_define( [[YYFARGS2]], [[($1 $2, $3 $4 M4_YY_DEF_LAST_ARG)]])
+ m4_define( [[YYFARGS3]], [[($1 $2, $3 $4, $5 $6 M4_YY_DEF_LAST_ARG)]])
+]])
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN YY_G(yy_start) = 1 + 2 *
+]])
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((YY_G(yy_start) - 1) / 2)
+#define YYSTATE YY_START
+]])
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+]])
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin M4_YY_CALL_LAST_ARG )
+]])
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+#define YY_END_OF_BUFFER_CHAR 0
+]])
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+]])
+
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+%if-not-reentrant
+extern int yyleng;
+%endif
+
+%if-c-only
+%if-not-reentrant
+extern FILE *yyin, *yyout;
+%endif
+%endif
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+]])
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+ m4_ifdef( [[M4_YY_USE_LINENO]],
+ [[
+ /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
+ * access to the local variable yy_act. Since yyless() is a macro, it would break
+ * existing scanners that call yyless() from OUTSIDE yylex.
+ * One obvious solution it to make yy_act a global. I tried that, and saw
+ * a 5% performance hit in a non-yylineno scanner, because yy_act is
+ * normally declared as a register variable-- so it is not worth it.
+ */
+ #define YY_LESS_LINENO(n) \
+ do { \
+ int yyl;\
+ for ( yyl = n; yyl < yyleng; ++yyl )\
+ if ( yytext[yyl] == '\n' )\
+ --yylineno;\
+ }while(0)
+ ]],
+ [[
+ #define YY_LESS_LINENO(n)
+ ]])
+]])
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = YY_G(yy_hold_char); \
+ YY_RESTORE_YY_MORE_OFFSET \
+ YY_G(yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+]])
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+#define unput(c) yyunput( c, YY_G(yytext_ptr) M4_YY_CALL_LAST_ARG )
+]])
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+%if-c-only
+ FILE *yy_input_file;
+%endif
+
+%if-c++-only
+ std::istream* yy_input_file;
+%endif
+
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+]])
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+%if-c-only Standard (non-C++) definition
+%not-for-header
+%if-not-reentrant
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+%endif
+%ok-for-header
+%endif
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( YY_G(yy_buffer_stack) \
+ ? YY_G(yy_buffer_stack)[YY_G(yy_buffer_stack_top)] \
+ : NULL)
+]])
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE YY_G(yy_buffer_stack)[YY_G(yy_buffer_stack_top)]
+]])
+
+%if-c-only Standard (non-C++) definition
+
+%if-not-reentrant
+%not-for-header
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 0; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+%ok-for-header
+%endif
+
+void yyrestart M4_YY_PARAMS( FILE *input_file M4_YY_PROTO_LAST_ARG );
+void yy_switch_to_buffer M4_YY_PARAMS( YY_BUFFER_STATE new_buffer M4_YY_PROTO_LAST_ARG );
+YY_BUFFER_STATE yy_create_buffer M4_YY_PARAMS( FILE *file, int size M4_YY_PROTO_LAST_ARG );
+void yy_delete_buffer M4_YY_PARAMS( YY_BUFFER_STATE b M4_YY_PROTO_LAST_ARG );
+void yy_flush_buffer M4_YY_PARAMS( YY_BUFFER_STATE b M4_YY_PROTO_LAST_ARG );
+void yypush_buffer_state M4_YY_PARAMS( YY_BUFFER_STATE new_buffer M4_YY_PROTO_LAST_ARG );
+void yypop_buffer_state M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG );
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+static void yyensure_buffer_stack M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG );
+static void yy_load_buffer_state M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG );
+static void yy_init_buffer M4_YY_PARAMS( YY_BUFFER_STATE b, FILE *file M4_YY_PROTO_LAST_ARG );
+]])
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER M4_YY_CALL_LAST_ARG)
+]])
+
+YY_BUFFER_STATE yy_scan_buffer M4_YY_PARAMS( char *base, yy_size_t size M4_YY_PROTO_LAST_ARG );
+YY_BUFFER_STATE yy_scan_string M4_YY_PARAMS( yyconst char *yy_str M4_YY_PROTO_LAST_ARG );
+YY_BUFFER_STATE yy_scan_bytes M4_YY_PARAMS( yyconst char *bytes, int len M4_YY_PROTO_LAST_ARG );
+
+%endif
+
+void *yyalloc M4_YY_PARAMS( yy_size_t M4_YY_PROTO_LAST_ARG );
+void *yyrealloc M4_YY_PARAMS( void *, yy_size_t M4_YY_PROTO_LAST_ARG );
+void yyfree M4_YY_PARAMS( void * M4_YY_PROTO_LAST_ARG );
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+#define yy_new_buffer yy_create_buffer
+]])
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ yyensure_buffer_stack (M4_YY_CALL_ONLY_ARG); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer( yyin, YY_BUF_SIZE M4_YY_CALL_LAST_ARG); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+]])
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ yyensure_buffer_stack (M4_YY_CALL_ONLY_ARG); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer( yyin, YY_BUF_SIZE M4_YY_CALL_LAST_ARG); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+]])
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+]])
+
+%% [1.0] yytext/yyin/yyout/yy_state_type/yylineno etc. def's & init go here
+
+%if-c-only Standard (non-C++) definition
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+static yy_state_type yy_get_previous_state M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG );
+static yy_state_type yy_try_NUL_trans M4_YY_PARAMS( yy_state_type current_state M4_YY_PROTO_LAST_ARG);
+static int yy_get_next_buffer M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG );
+static void yy_fatal_error M4_YY_PARAMS( yyconst char msg[] M4_YY_PROTO_LAST_ARG );
+]])
+
+%endif
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ YY_G(yytext_ptr) = yy_bp; \
+%% [2.0] code to fiddle yytext and yyleng for yymore() goes here \
+ YY_G(yy_hold_char) = *yy_cp; \
+ *yy_cp = '\0'; \
+%% [3.0] code to copy yytext_ptr to yytext[] goes here, if %array \
+ YY_G(yy_c_buf_p) = yy_cp;
+]])
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+%% [4.0] data tables for the DFA and the user's section 1 definitions go here
+]])
+
+m4_ifdef( [[M4_YY_IN_HEADER]], [[#ifdef YY_HEADER_EXPORT_START_CONDITIONS]])
+M4_YY_SC_DEFS
+m4_ifdef( [[M4_YY_IN_HEADER]], [[#endif]])
+
+m4_ifdef( [[M4_YY_NO_UNISTD_H]],,
+[[
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+%if-c-only
+#include <unistd.h>
+%endif
+%if-c++-only
+#include <unistd.h>
+%endif
+#endif
+]])
+
+m4_ifdef( [[M4_EXTRA_TYPE_DEFS]],
+[[
+#define YY_EXTRA_TYPE M4_EXTRA_TYPE_DEFS
+]],
+[[
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+]]
+)
+
+%if-c-only Reentrant structure and macros (non-C++).
+%if-reentrant
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+/* Holds the entire state of the reentrant scanner. */
+struct yyguts_t
+ {
+
+ /* User-defined. Not touched by flex. */
+ YY_EXTRA_TYPE yyextra_r;
+
+ /* The rest are the same as the globals declared in the non-reentrant scanner. */
+ FILE *yyin_r, *yyout_r;
+ size_t yy_buffer_stack_top; /**< index of top of stack. */
+ size_t yy_buffer_stack_max; /**< capacity of stack. */
+ YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
+ char yy_hold_char;
+ int yy_n_chars;
+ int yyleng_r;
+ char *yy_c_buf_p;
+ int yy_init;
+ int yy_start;
+ int yy_did_buffer_switch_on_eof;
+ int yy_start_stack_ptr;
+ int yy_start_stack_depth;
+ int *yy_start_stack;
+ yy_state_type yy_last_accepting_state;
+ char* yy_last_accepting_cpos;
+
+ int yylineno_r;
+ int yy_flex_debug_r;
+
+m4_ifdef( [[M4_YY_USES_REJECT]],
+[[
+ yy_state_type *yy_state_buf;
+ yy_state_type *yy_state_ptr;
+ char *yy_full_match;
+ int yy_lp;
+
+ /* These are only needed for trailing context rules,
+ * but there's no conditional variable for that yet. */
+ int yy_looking_for_trail_begin;
+ int yy_full_lp;
+ int *yy_full_state;
+]])
+
+m4_ifdef( [[M4_YY_TEXT_IS_ARRAY]],
+[[
+ char yytext_r[YYLMAX];
+ char *yytext_ptr;
+ int yy_more_offset;
+ int yy_prev_more_offset;
+]],
+[[
+ char *yytext_r;
+ int yy_more_flag;
+ int yy_more_len;
+]])
+
+m4_ifdef( [[M4_YY_BISON_LVAL]],
+[[
+ YYSTYPE * yylval_r;
+]])
+
+m4_ifdef( [[<M4_YY_BISON_LLOC>]],
+[[
+ YYLTYPE * yylloc_r;
+]])
+
+ }; /* end struct yyguts_t */
+]])
+
+
+%if-c-only
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+static int yy_init_globals M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG );
+]])
+%endif
+
+%if-reentrant
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+ m4_ifdef( [[M4_YY_BISON_LVAL]],
+ [[
+ /* This must go here because YYSTYPE and YYLTYPE are included
+ * from bison output in section 1.*/
+ # define yylval YY_G(yylval_r)
+ ]])
+
+ m4_ifdef( [[<M4_YY_BISON_LLOC>]],
+ [[
+ # define yylloc YY_G(yylloc_r)
+ ]])
+]])
+
+int yylex_init M4_YY_PARAMS(yyscan_t* scanner);
+
+int yylex_init_extra M4_YY_PARAMS( YY_EXTRA_TYPE user_defined, yyscan_t* scanner);
+
+%endif
+
+%endif End reentrant structures and macros.
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+m4_ifdef( [[M4_YY_NO_DESTROY]],,
+[[
+int yylex_destroy M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG );
+]])
+
+m4_ifdef( [[M4_YY_NO_GET_DEBUG]],,
+[[
+int yyget_debug M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG );
+]])
+
+m4_ifdef( [[M4_YY_NO_SET_DEBUG]],,
+[[
+void yyset_debug M4_YY_PARAMS( int debug_flag M4_YY_PROTO_LAST_ARG );
+]])
+
+m4_ifdef( [[M4_YY_NO_GET_EXTRA]],,
+[[
+YY_EXTRA_TYPE yyget_extra M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG );
+]])
+
+m4_ifdef( [[M4_YY_NO_SET_EXTRA]],,
+[[
+void yyset_extra M4_YY_PARAMS( YY_EXTRA_TYPE user_defined M4_YY_PROTO_LAST_ARG );
+]])
+
+m4_ifdef( [[M4_YY_NO_GET_IN]],,
+[[
+FILE *yyget_in M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG );
+]])
+
+m4_ifdef( [[M4_YY_NO_SET_IN]],,
+[[
+void yyset_in M4_YY_PARAMS( FILE * in_str M4_YY_PROTO_LAST_ARG );
+]])
+
+m4_ifdef( [[M4_YY_NO_GET_OUT]],,
+[[
+FILE *yyget_out M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG );
+]])
+
+m4_ifdef( [[M4_YY_NO_SET_OUT]],,
+[[
+void yyset_out M4_YY_PARAMS( FILE * out_str M4_YY_PROTO_LAST_ARG );
+]])
+
+m4_ifdef( [[M4_YY_NO_GET_LENG]],,
+[[
+int yyget_leng M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG );
+]])
+
+m4_ifdef( [[M4_YY_NO_GET_TEXT]],,
+[[
+char *yyget_text M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG );
+]])
+
+m4_ifdef( [[M4_YY_NO_GET_LINENO]],,
+[[
+int yyget_lineno M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG );
+]])
+
+m4_ifdef( [[M4_YY_NO_SET_LINENO]],,
+[[
+void yyset_lineno M4_YY_PARAMS( int line_number M4_YY_PROTO_LAST_ARG );
+]])
+
+%if-bison-bridge
+m4_ifdef( [[M4_YY_NO_GET_LVAL]],,
+[[
+YYSTYPE * yyget_lval M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG );
+]])
+
+void yyset_lval M4_YY_PARAMS( YYSTYPE * yylval_param M4_YY_PROTO_LAST_ARG );
+
+m4_ifdef( [[<M4_YY_BISON_LLOC>]],
+[[
+ m4_ifdef( [[M4_YY_NO_GET_LLOC]],,
+ [[
+ YYLTYPE *yyget_lloc M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG );
+ ]])
+
+ m4_ifdef( [[M4_YY_NO_SET_LLOC]],,
+ [[
+ void yyset_lloc M4_YY_PARAMS( YYLTYPE * yylloc_param M4_YY_PROTO_LAST_ARG );
+ ]])
+]])
+%endif
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG );
+#else
+extern int yywrap M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG );
+#endif
+#endif
+
+%not-for-header
+ m4_ifdef( [[M4_YY_NO_UNPUT]],,
+ [[
+ static void yyunput M4_YY_PARAMS( int c, char *buf_ptr M4_YY_PROTO_LAST_ARG);
+ ]])
+%ok-for-header
+%endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy M4_YY_PARAMS( char *, yyconst char *, int M4_YY_PROTO_LAST_ARG);
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen M4_YY_PARAMS( yyconst char * M4_YY_PROTO_LAST_ARG);
+#endif
+
+#ifndef YY_NO_INPUT
+%if-c-only Standard (non-C++) definition
+%not-for-header
+#ifdef __cplusplus
+static int yyinput M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG );
+#else
+static int input M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG );
+#endif
+%ok-for-header
+%endif
+#endif
+
+
+%if-c-only
+%# TODO: This is messy.
+m4_ifdef( [[M4_YY_STACK_USED]],
+[[
+
+m4_ifdef( [[M4_YY_NOT_REENTRANT]],
+[[
+ m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+ [[
+ static int yy_start_stack_ptr = 0;
+ static int yy_start_stack_depth = 0;
+ static int *yy_start_stack = NULL;
+ ]])
+]])
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+ m4_ifdef( [[M4_YY_NO_PUSH_STATE]],,
+ [[
+ static void yy_push_state M4_YY_PARAMS( int new_state M4_YY_PROTO_LAST_ARG);
+ ]])
+ m4_ifdef( [[M4_YY_NO_POP_STATE]],,
+ [[
+ static void yy_pop_state M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG );
+ ]])
+ m4_ifdef( [[M4_YY_NO_TOP_STATE]],,
+ [[
+ static int yy_top_state M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG );
+ ]])
+]])
+
+]],
+[[
+m4_define( [[M4_YY_NO_PUSH_STATE]])
+m4_define( [[M4_YY_NO_POP_STATE]])
+m4_define( [[M4_YY_NO_TOP_STATE]])
+]])
+%endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+%if-c-only Standard (non-C++) definition
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO fwrite( yytext, yyleng, 1, yyout )
+%endif
+%if-c++-only C++ definition
+#define ECHO LexerOutput( yytext, yyleng )
+%endif
+#endif
+]])
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+%% [5.0] fread()/read() definition of YY_INPUT goes here unless we're doing C++ \
+\
+%if-c++-only C++ definition \
+ if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" );
+%endif
+
+#endif
+]])
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+]])
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+%if-c-only
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg M4_YY_CALL_LAST_ARG)
+%endif
+%if-c++-only
+#define YY_FATAL_ERROR(msg) LexerError( msg )
+%endif
+#endif
+]])
+
+%if-tables-serialization structures and prototypes
+m4preproc_include(`tables_shared.h')
+
+/* Load the DFA tables from the given stream. */
+int yytables_fload M4_YY_PARAMS(FILE * fp M4_YY_PROTO_LAST_ARG);
+
+/* Unload the tables from memory. */
+int yytables_destroy M4_YY_PARAMS(M4_YY_PROTO_ONLY_ARG);
+%not-for-header
+
+/** Describes a mapping from a serialized table id to its deserialized state in
+ * this scanner. This is the bridge between our "generic" deserialization code
+ * and the specifics of this scanner.
+ */
+struct yytbl_dmap {
+ enum yytbl_id dm_id;/**< table identifier */
+ void **dm_arr; /**< address of pointer to store the deserialized table. */
+ size_t dm_sz; /**< local sizeof() each element in table. */
+};
+
+/** A {0,0,0}-terminated list of structs, forming the map */
+static struct yytbl_dmap yydmap[] =
+{
+%tables-yydmap generated elements
+ {0,0,0}
+};
+
+/** A tables-reader object to maintain some state in the read. */
+struct yytbl_reader {
+ FILE * fp; /**< input stream */
+ flex_uint32_t bread; /**< bytes read since beginning of current tableset */
+};
+
+%endif
+/* end tables serialization structures and prototypes */
+
+%ok-for-header
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+%if-c-only Standard (non-C++) definition
+
+
+m4_define( [[M4_YY_LEX_PROTO]], [[M4_YY_PARAMS(M4_YY_PROTO_ONLY_ARG)]])
+m4_define( [[M4_YY_LEX_DECLARATION]], [[YYFARGS0(void)]])
+
+m4_ifdef( [[M4_YY_BISON_LVAL]],
+[[
+ m4_dnl The bison pure parser is used. Redefine yylex to
+ m4_dnl accept the lval parameter.
+
+ m4_define( [[M4_YY_LEX_PROTO]], [[\]]
+ [[M4_YY_PARAMS(YYSTYPE * yylval_param M4_YY_PROTO_LAST_ARG)]])
+ m4_define( [[M4_YY_LEX_DECLARATION]], [[\]]
+ [[YYFARGS1(YYSTYPE *,yylval_param)]])
+]])
+
+m4_ifdef( [[<M4_YY_BISON_LLOC>]],
+[[
+ m4_dnl Locations are used. yylex should also accept the ylloc parameter.
+
+ m4_define( [[M4_YY_LEX_PROTO]], [[\]]
+ [[M4_YY_PARAMS(YYSTYPE * yylval_param, YYLTYPE * yylloc_param M4_YY_PROTO_LAST_ARG)]])
+ m4_define( [[M4_YY_LEX_DECLARATION]], [[\]]
+ [[YYFARGS2(YYSTYPE *,yylval_param, YYLTYPE *,yylloc_param)]])
+]])
+
+extern int yylex M4_YY_LEX_PROTO;
+
+#define YY_DECL int yylex M4_YY_LEX_DECLARATION
+%endif
+%if-c++-only C++ definition
+#define YY_DECL int yyFlexLexer::yylex()
+%endif
+#endif /* !YY_DECL */
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+]])
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+]])
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+%% [6.0] YY_RULE_SETUP definition goes here
+]])
+
+%not-for-header
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+ M4_YY_DECL_GUTS_VAR();
+
+m4_ifdef( [[M4_YY_NOT_REENTRANT]],
+[[
+ m4_ifdef( [[M4_YY_BISON_LVAL]],
+ [[
+ YYSTYPE * yylval;
+ ]])
+ m4_ifdef( [[<M4_YY_BISON_LLOC>]],
+ [[
+ YYLTYPE * yylloc;
+ ]])
+]])
+
+%% [7.0] user's declarations go here
+
+m4_ifdef( [[M4_YY_BISON_LVAL]],
+[[
+ yylval = yylval_param;
+]])
+
+m4_ifdef( [[<M4_YY_BISON_LLOC>]],
+[[
+ yylloc = yylloc_param;
+]])
+
+ if ( !YY_G(yy_init) )
+ {
+ YY_G(yy_init) = 1;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+m4_ifdef( [[M4_YY_USES_REJECT]],
+[[
+ /* Create the reject buffer large enough to save one state per allowed character. */
+ if ( ! YY_G(yy_state_buf) )
+ YY_G(yy_state_buf) = (yy_state_type *)yyalloc(YY_STATE_BUF_SIZE M4_YY_CALL_LAST_ARG);
+ if ( ! YY_G(yy_state_buf) )
+ YY_FATAL_ERROR( "out of dynamic memory in yylex()" );
+]])
+
+ if ( ! YY_G(yy_start) )
+ YY_G(yy_start) = 1; /* first start state */
+
+ if ( ! yyin )
+%if-c-only
+ yyin = stdin;
+%endif
+%if-c++-only
+ yyin = & std::cin;
+%endif
+
+ if ( ! yyout )
+%if-c-only
+ yyout = stdout;
+%endif
+%if-c++-only
+ yyout = & std::cout;
+%endif
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ yyensure_buffer_stack (M4_YY_CALL_ONLY_ARG);
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer( yyin, YY_BUF_SIZE M4_YY_CALL_LAST_ARG);
+ }
+
+ yy_load_buffer_state( M4_YY_CALL_ONLY_ARG );
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+%% [8.0] yymore()-related code goes here
+ yy_cp = YY_G(yy_c_buf_p);
+
+ /* Support of yytext. */
+ *yy_cp = YY_G(yy_hold_char);
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+%% [9.0] code to set up and find next match goes here
+
+yy_find_action:
+%% [10.0] code to find the action number goes here
+
+ YY_DO_BEFORE_ACTION;
+
+%% [11.0] code for yylineno update goes here
+
+do_action: /* This label is used only to access EOF actions. */
+
+%% [12.0] debug code goes here
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+%% [13.0] actions go here
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - YY_G(yytext_ptr)) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = YY_G(yy_hold_char);
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ YY_G(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( YY_G(yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[YY_G(yy_n_chars)] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ YY_G(yy_c_buf_p) = YY_G(yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( M4_YY_CALL_ONLY_ARG );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state M4_YY_CALL_LAST_ARG);
+
+ yy_bp = YY_G(yytext_ptr) + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++YY_G(yy_c_buf_p);
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+%% [14.0] code to do back-up for compressed tables and set up yy_cp goes here
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( M4_YY_CALL_ONLY_ARG ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ YY_G(yy_did_buffer_switch_on_eof) = 0;
+
+ if ( yywrap( M4_YY_CALL_ONLY_ARG ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ YY_G(yy_c_buf_p) = YY_G(yytext_ptr) + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! YY_G(yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ YY_G(yy_c_buf_p) =
+ YY_G(yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( M4_YY_CALL_ONLY_ARG );
+
+ yy_cp = YY_G(yy_c_buf_p);
+ yy_bp = YY_G(yytext_ptr) + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ YY_G(yy_c_buf_p) =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[YY_G(yy_n_chars)];
+
+ yy_current_state = yy_get_previous_state( M4_YY_CALL_ONLY_ARG );
+
+ yy_cp = YY_G(yy_c_buf_p);
+ yy_bp = YY_G(yytext_ptr) + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+} /* end of yylex */
+%ok-for-header
+
+%if-c++-only
+%not-for-header
+/* The contents of this function are C++ specific, so the YY_G macro is not used.
+ */
+yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout )
+{
+ yyin = arg_yyin;
+ yyout = arg_yyout;
+ yy_c_buf_p = 0;
+ yy_init = 0;
+ yy_start = 0;
+ yy_flex_debug = 0;
+ yylineno = 1; // this will only get updated if %option yylineno
+
+ yy_did_buffer_switch_on_eof = 0;
+
+ yy_looking_for_trail_begin = 0;
+ yy_more_flag = 0;
+ yy_more_len = 0;
+ yy_more_offset = yy_prev_more_offset = 0;
+
+ yy_start_stack_ptr = yy_start_stack_depth = 0;
+ yy_start_stack = NULL;
+
+ yy_buffer_stack = 0;
+ yy_buffer_stack_top = 0;
+ yy_buffer_stack_max = 0;
+
+
+m4_ifdef( [[M4_YY_USES_REJECT]],
+[[
+ yy_state_buf = new yy_state_type[YY_STATE_BUF_SIZE];
+]],
+[[
+ yy_state_buf = 0;
+]])
+}
+
+/* The contents of this function are C++ specific, so the YY_G macro is not used.
+ */
+yyFlexLexer::~yyFlexLexer()
+{
+ mystack::iterator It=m_IncludeStack.begin();
+ while (It!=m_IncludeStack.end())
+ {
+ yy_delete_buffer((*It)->m_BufferState); /* When the stack is deleted, the lexer is not run anymore, so we have to clean up the buffers ourself */
+ It++;
+ }
+ delete [] yy_state_buf;
+ yyfree( yy_start_stack M4_YY_CALL_LAST_ARG );
+ yy_delete_buffer( YY_CURRENT_BUFFER M4_YY_CALL_LAST_ARG);
+ yyfree( yy_buffer_stack M4_YY_CALL_LAST_ARG );
+}
+
+/* The contents of this function are C++ specific, so the YY_G macro is not used.
+ */
+void yyFlexLexer::switch_streams( std::istream* new_in, std::ostream* new_out )
+{
+ if ( new_in )
+ {
+ yy_delete_buffer( YY_CURRENT_BUFFER M4_YY_CALL_LAST_ARG);
+ yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE M4_YY_CALL_LAST_ARG) M4_YY_CALL_LAST_ARG);
+ }
+
+ if ( new_out )
+ yyout = new_out;
+}
+
+#ifdef YY_INTERACTIVE
+int yyFlexLexer::LexerInput( char* buf, int /* max_size */ )
+#else
+int yyFlexLexer::LexerInput( char* buf, int max_size )
+#endif
+{
+ if ( yyin->eof() || yyin->fail() )
+ return 0;
+
+#ifdef YY_INTERACTIVE
+ yyin->get( buf[0] );
+
+ if ( yyin->eof() )
+ return 0;
+
+ if ( yyin->bad() )
+ return -1;
+
+ return 1;
+
+#else
+ (void) yyin->read( buf, max_size );
+
+ if ( yyin->bad() )
+ return -1;
+ else
+ return (int)yyin->gcount();
+#endif
+}
+
+void yyFlexLexer::LexerOutput( const char* buf, int size )
+{
+ (void) yyout->write( buf, size );
+}
+%ok-for-header
+%endif
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+%if-c-only
+static int yy_get_next_buffer YYFARGS0(void)
+%endif
+%if-c++-only
+int yyFlexLexer::yy_get_next_buffer()
+%endif
+{
+ M4_YY_DECL_GUTS_VAR();
+ register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ register char *source = YY_G(yytext_ptr);
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( YY_G(yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[YY_G(yy_n_chars) + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( YY_G(yy_c_buf_p) - YY_G(yytext_ptr) - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) (YY_G(yy_c_buf_p) - YY_G(yytext_ptr)) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = YY_G(yy_n_chars) = 0;
+
+ else
+ {
+ int num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+m4_ifdef( [[M4_YY_USES_REJECT]],
+[[
+ YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+]],
+[[
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+ int yy_c_buf_p_offset =
+ (int) (YY_G(yy_c_buf_p) - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yyrealloc( (void *) b->yy_ch_buf,
+ b->yy_buf_size + 2 M4_YY_CALL_LAST_ARG );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ YY_G(yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+ number_to_move - 1;
+]])
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ YY_G(yy_n_chars), (size_t) num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = YY_G(yy_n_chars);
+ }
+
+ if ( YY_G(yy_n_chars) == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart( yyin M4_YY_CALL_LAST_ARG);
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if ((yy_size_t) (YY_G(yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ /* Extend the array by 50%, plus the number we really need. */
+ yy_size_t new_size = YY_G(yy_n_chars) + number_to_move + (YY_G(yy_n_chars) >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc(
+ (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, new_size M4_YY_CALL_LAST_ARG );
+ if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ }
+
+ YY_G(yy_n_chars) += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[YY_G(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[YY_G(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+ YY_G(yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+]])
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+%if-c-only
+%not-for-header
+ static yy_state_type yy_get_previous_state YYFARGS0(void)
+%endif
+%if-c++-only
+ yy_state_type yyFlexLexer::yy_get_previous_state()
+%endif
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+ M4_YY_DECL_GUTS_VAR();
+
+%% [15.0] code to get the start state into yy_current_state goes here
+
+ for ( yy_cp = YY_G(yytext_ptr) + YY_MORE_ADJ; yy_cp < YY_G(yy_c_buf_p); ++yy_cp )
+ {
+%% [16.0] code to find the next state goes here
+ }
+
+ return yy_current_state;
+}
+
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+%if-c-only
+ static yy_state_type yy_try_NUL_trans YYFARGS1( yy_state_type, yy_current_state)
+%endif
+%if-c++-only
+ yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state )
+%endif
+{
+ register int yy_is_jam;
+ M4_YY_DECL_GUTS_VAR(); /* This var may be unused depending upon options. */
+%% [17.0] code to find the next state, and perhaps do backing up, goes here
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+
+%if-c-only
+m4_ifdef( [[M4_YY_NO_UNPUT]],,
+[[
+ static void yyunput YYFARGS2( int,c, register char *,yy_bp)
+%endif
+%if-c++-only
+ void yyFlexLexer::yyunput( int c, register char* yy_bp)
+%endif
+{
+ register char *yy_cp;
+ M4_YY_DECL_GUTS_VAR();
+
+ yy_cp = YY_G(yy_c_buf_p);
+
+ /* undo effects of setting up yytext */
+ *yy_cp = YY_G(yy_hold_char);
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ register int number_to_move = YY_G(yy_n_chars) + 2;
+ register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+ register char *source =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+ while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+ YY_G(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+%% [18.0] update yylineno here
+m4_ifdef( [[M4_YY_USE_LINENO]],
+[[
+ if ( c == '\n' ){
+ --yylineno;
+ }
+]])
+
+ YY_G(yytext_ptr) = yy_bp;
+ YY_G(yy_hold_char) = *yy_cp;
+ YY_G(yy_c_buf_p) = yy_cp;
+}
+%if-c-only
+]])
+%endif
+
+%if-c-only
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput YYFARGS0(void)
+#else
+ static int input YYFARGS0(void)
+#endif
+
+%endif
+%if-c++-only
+ int yyFlexLexer::yyinput()
+%endif
+{
+ int c;
+ M4_YY_DECL_GUTS_VAR();
+
+ *YY_G(yy_c_buf_p) = YY_G(yy_hold_char);
+
+ if ( *YY_G(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( YY_G(yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[YY_G(yy_n_chars)] )
+ /* This was really a NUL. */
+ *YY_G(yy_c_buf_p) = '\0';
+
+ else
+ { /* need more input */
+ int offset = YY_G(yy_c_buf_p) - YY_G(yytext_ptr);
+ ++YY_G(yy_c_buf_p);
+
+ switch ( yy_get_next_buffer( M4_YY_CALL_ONLY_ARG ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart( yyin M4_YY_CALL_LAST_ARG);
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap( M4_YY_CALL_ONLY_ARG ) )
+ return EOF;
+
+ if ( ! YY_G(yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput(M4_YY_CALL_ONLY_ARG);
+#else
+ return input(M4_YY_CALL_ONLY_ARG);
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ YY_G(yy_c_buf_p) = YY_G(yytext_ptr) + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) YY_G(yy_c_buf_p); /* cast for 8-bit char's */
+ *YY_G(yy_c_buf_p) = '\0'; /* preserve yytext */
+ YY_G(yy_hold_char) = *++YY_G(yy_c_buf_p);
+
+%% [19.0] update BOL and yylineno
+
+ return c;
+}
+%if-c-only
+#endif /* ifndef YY_NO_INPUT */
+%endif
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * M4_YY_DOC_PARAM
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+%if-c-only
+ void yyrestart YYFARGS1( FILE *,input_file)
+%endif
+%if-c++-only
+ void yyFlexLexer::yyrestart( std::istream* input_file )
+%endif
+{
+ M4_YY_DECL_GUTS_VAR();
+
+ if ( ! YY_CURRENT_BUFFER ){
+ yyensure_buffer_stack (M4_YY_CALL_ONLY_ARG);
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer( yyin, YY_BUF_SIZE M4_YY_CALL_LAST_ARG);
+ }
+
+ yy_init_buffer( YY_CURRENT_BUFFER, input_file M4_YY_CALL_LAST_ARG);
+ yy_load_buffer_state( M4_YY_CALL_ONLY_ARG );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * M4_YY_DOC_PARAM
+ */
+%if-c-only
+ void yy_switch_to_buffer YYFARGS1( YY_BUFFER_STATE ,new_buffer)
+%endif
+%if-c++-only
+ void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+%endif
+{
+ M4_YY_DECL_GUTS_VAR();
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * yypop_buffer_state();
+ * yypush_buffer_state(new_buffer);
+ */
+ yyensure_buffer_stack (M4_YY_CALL_ONLY_ARG);
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *YY_G(yy_c_buf_p) = YY_G(yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = YY_G(yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = YY_G(yy_n_chars);
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ yy_load_buffer_state( M4_YY_CALL_ONLY_ARG );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ YY_G(yy_did_buffer_switch_on_eof) = 1;
+}
+
+
+%if-c-only
+static void yy_load_buffer_state YYFARGS0(void)
+%endif
+%if-c++-only
+ void yyFlexLexer::yy_load_buffer_state()
+%endif
+{
+ M4_YY_DECL_GUTS_VAR();
+ YY_G(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_G(yytext_ptr) = YY_G(yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ YY_G(yy_hold_char) = *YY_G(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * M4_YY_DOC_PARAM
+ * @return the allocated buffer state.
+ */
+%if-c-only
+ YY_BUFFER_STATE yy_create_buffer YYFARGS2( FILE *,file, int ,size)
+%endif
+%if-c++-only
+ YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size )
+%endif
+{
+ YY_BUFFER_STATE b;
+ m4_dnl M4_YY_DECL_GUTS_VAR();
+
+ b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) M4_YY_CALL_LAST_ARG );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yyalloc( b->yy_buf_size + 2 M4_YY_CALL_LAST_ARG );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer( b, file M4_YY_CALL_LAST_ARG);
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ * M4_YY_DOC_PARAM
+ */
+%if-c-only
+ void yy_delete_buffer YYFARGS1( YY_BUFFER_STATE ,b)
+%endif
+%if-c++-only
+ void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b )
+%endif
+{
+ M4_YY_DECL_GUTS_VAR();
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ yyfree( (void *) b->yy_ch_buf M4_YY_CALL_LAST_ARG );
+
+ yyfree( (void *) b M4_YY_CALL_LAST_ARG );
+}
+
+
+%if-c-only
+m4_ifdef( [[M4_YY_ALWAYS_INTERACTIVE]],,
+[[
+ m4_ifdef( [[M4_YY_NEVER_INTERACTIVE]],,
+ [[
+#ifndef __cplusplus
+extern int isatty M4_YY_PARAMS( int );
+#endif /* __cplusplus */
+ ]])
+]])
+%endif
+
+%if-c++-only
+m4_ifdef( [[M4_YY_NEVER_INTERACTIVE]],,
+[[
+]])
+%endif
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+%if-c-only
+ static void yy_init_buffer YYFARGS2( YY_BUFFER_STATE ,b, FILE *,file)
+%endif
+%if-c++-only
+ void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream* file )
+%endif
+
+{
+ int oerrno = errno;
+ M4_YY_DECL_GUTS_VAR();
+
+ yy_flush_buffer( b M4_YY_CALL_LAST_ARG);
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then yy_init_buffer was _probably_
+ * called from yyrestart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+%if-c-only
+m4_ifdef( [[M4_YY_ALWAYS_INTERACTIVE]],
+[[
+ b->yy_is_interactive = 1;
+]],
+[[
+ m4_ifdef( [[M4_YY_NEVER_INTERACTIVE]],
+ [[
+ b->yy_is_interactive = 0;
+ ]],
+ [[
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+ ]])
+]])
+%endif
+%if-c++-only
+ b->yy_is_interactive = 0;
+%endif
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * M4_YY_DOC_PARAM
+ */
+%if-c-only
+ void yy_flush_buffer YYFARGS1( YY_BUFFER_STATE ,b)
+%endif
+%if-c++-only
+ void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b )
+%endif
+{
+ M4_YY_DECL_GUTS_VAR();
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ yy_load_buffer_state( M4_YY_CALL_ONLY_ARG );
+}
+
+%if-c-or-c++
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ * M4_YY_DOC_PARAM
+ */
+%if-c-only
+void yypush_buffer_state YYFARGS1(YY_BUFFER_STATE,new_buffer)
+%endif
+%if-c++-only
+void yyFlexLexer::yypush_buffer_state (YY_BUFFER_STATE new_buffer)
+%endif
+{
+ M4_YY_DECL_GUTS_VAR();
+ if (new_buffer == NULL)
+ return;
+
+ yyensure_buffer_stack(M4_YY_CALL_ONLY_ARG);
+
+ /* This block is copied from yy_switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *YY_G(yy_c_buf_p) = YY_G(yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = YY_G(yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = YY_G(yy_n_chars);
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ YY_G(yy_buffer_stack_top)++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from yy_switch_to_buffer. */
+ yy_load_buffer_state( M4_YY_CALL_ONLY_ARG );
+ YY_G(yy_did_buffer_switch_on_eof) = 1;
+}
+%endif
+
+
+%if-c-or-c++
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ * M4_YY_DOC_PARAM
+ */
+%if-c-only
+void yypop_buffer_state YYFARGS0(void)
+%endif
+%if-c++-only
+void yyFlexLexer::yypop_buffer_state (void)
+%endif
+{
+ M4_YY_DECL_GUTS_VAR();
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ yy_delete_buffer(YY_CURRENT_BUFFER M4_YY_CALL_LAST_ARG);
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if (YY_G(yy_buffer_stack_top) > 0)
+ --YY_G(yy_buffer_stack_top);
+
+ if (YY_CURRENT_BUFFER) {
+ yy_load_buffer_state( M4_YY_CALL_ONLY_ARG );
+ YY_G(yy_did_buffer_switch_on_eof) = 1;
+ }
+}
+%endif
+
+
+%if-c-or-c++
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+%if-c-only
+static void yyensure_buffer_stack YYFARGS0(void)
+%endif
+%if-c++-only
+void yyFlexLexer::yyensure_buffer_stack(void)
+%endif
+{
+ int num_to_alloc;
+ M4_YY_DECL_GUTS_VAR();
+
+ if (!YY_G(yy_buffer_stack)) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1;
+ YY_G(yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ M4_YY_CALL_LAST_ARG);
+ if ( ! YY_G(yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+
+ memset(YY_G(yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ YY_G(yy_buffer_stack_max) = num_to_alloc;
+ YY_G(yy_buffer_stack_top) = 0;
+ return;
+ }
+
+ if (YY_G(yy_buffer_stack_top) >= (YY_G(yy_buffer_stack_max)) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ int grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = YY_G(yy_buffer_stack_max) + grow_size;
+ YY_G(yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
+ (YY_G(yy_buffer_stack),
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ M4_YY_CALL_LAST_ARG);
+ if ( ! YY_G(yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ /* zero only the new slots.*/
+ memset(YY_G(yy_buffer_stack) + YY_G(yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+ YY_G(yy_buffer_stack_max) = num_to_alloc;
+ }
+}
+%endif
+
+
+
+
+m4_ifdef( [[M4_YY_NO_SCAN_BUFFER]],,
+[[
+%if-c-only
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ * M4_YY_DOC_PARAM
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_buffer YYFARGS2( char *,base, yy_size_t ,size)
+{
+ YY_BUFFER_STATE b;
+ m4_dnl M4_YY_DECL_GUTS_VAR();
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) M4_YY_CALL_LAST_ARG );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer( b M4_YY_CALL_LAST_ARG );
+
+ return b;
+}
+%endif
+]])
+
+
+m4_ifdef( [[M4_YY_NO_SCAN_STRING]],,
+[[
+%if-c-only
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ * M4_YY_DOC_PARAM
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string YYFARGS1( yyconst char *, yystr)
+{
+ m4_dnl M4_YY_DECL_GUTS_VAR();
+
+ return yy_scan_bytes( yystr, strlen(yystr) M4_YY_CALL_LAST_ARG);
+}
+%endif
+]])
+
+
+m4_ifdef( [[M4_YY_NO_SCAN_BYTES]],,
+[[
+%if-c-only
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param bytes the byte buffer to scan
+ * @param len the number of bytes in the buffer pointed to by @a bytes.
+ * M4_YY_DOC_PARAM
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes YYFARGS2( yyconst char *,yybytes, int ,_yybytes_len)
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+ m4_dnl M4_YY_DECL_GUTS_VAR();
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = _yybytes_len + 2;
+ buf = (char *) yyalloc( n M4_YY_CALL_LAST_ARG );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer( buf, n M4_YY_CALL_LAST_ARG);
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+%endif
+]])
+
+
+m4_ifdef( [[M4_YY_NO_PUSH_STATE]],,
+[[
+%if-c-only
+ static void yy_push_state YYFARGS1( int ,new_state)
+%endif
+%if-c++-only
+ void yyFlexLexer::yy_push_state( int new_state )
+%endif
+{
+ M4_YY_DECL_GUTS_VAR();
+ if ( YY_G(yy_start_stack_ptr) >= YY_G(yy_start_stack_depth) )
+ {
+ yy_size_t new_size;
+
+ YY_G(yy_start_stack_depth) += YY_START_STACK_INCR;
+ new_size = YY_G(yy_start_stack_depth) * sizeof( int );
+
+ if ( ! YY_G(yy_start_stack) )
+ YY_G(yy_start_stack) = (int *) yyalloc( new_size M4_YY_CALL_LAST_ARG );
+
+ else
+ YY_G(yy_start_stack) = (int *) yyrealloc(
+ (void *) YY_G(yy_start_stack), new_size M4_YY_CALL_LAST_ARG );
+
+ if ( ! YY_G(yy_start_stack) )
+ YY_FATAL_ERROR( "out of memory expanding start-condition stack" );
+ }
+
+ YY_G(yy_start_stack)[YY_G(yy_start_stack_ptr)++] = YY_START;
+
+ BEGIN(new_state);
+}
+]])
+
+
+m4_ifdef( [[M4_YY_NO_POP_STATE]],,
+[[
+%if-c-only
+ static void yy_pop_state YYFARGS0(void)
+%endif
+%if-c++-only
+ void yyFlexLexer::yy_pop_state()
+%endif
+{
+ M4_YY_DECL_GUTS_VAR();
+ if ( --YY_G(yy_start_stack_ptr) < 0 )
+ YY_FATAL_ERROR( "start-condition stack underflow" );
+
+ BEGIN(YY_G(yy_start_stack)[YY_G(yy_start_stack_ptr)]);
+}
+]])
+
+
+m4_ifdef( [[M4_YY_NO_TOP_STATE]],,
+[[
+%if-c-only
+ static int yy_top_state YYFARGS0(void)
+%endif
+%if-c++-only
+ int yyFlexLexer::yy_top_state()
+%endif
+{
+ M4_YY_DECL_GUTS_VAR();
+ return YY_G(yy_start_stack)[YY_G(yy_start_stack_ptr) - 1];
+}
+]])
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+%if-c-only
+static void yy_fatal_error YYFARGS1(yyconst char*, msg)
+{
+ m4_dnl M4_YY_DECL_GUTS_VAR();
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+%endif
+%if-c++-only
+void yyFlexLexer::LexerError( yyconst char msg[] )
+{
+ M4_YY_DECL_GUTS_VAR();
+ std::cerr << msg << std::endl;
+ exit( YY_EXIT_FAILURE );
+}
+%endif
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ yytext[yyleng] = YY_G(yy_hold_char); \
+ YY_G(yy_c_buf_p) = yytext + yyless_macro_arg; \
+ YY_G(yy_hold_char) = *YY_G(yy_c_buf_p); \
+ *YY_G(yy_c_buf_p) = '\0'; \
+ yyleng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+
+
+/* Accessor methods (get/set functions) to struct members. */
+
+%if-c-only
+%if-reentrant
+m4_ifdef( [[M4_YY_NO_GET_EXTRA]],,
+[[
+/** Get the user-defined data for this scanner.
+ * M4_YY_DOC_PARAM
+ */
+YY_EXTRA_TYPE yyget_extra YYFARGS0(void)
+{
+ M4_YY_DECL_GUTS_VAR();
+ return yyextra;
+}
+]])
+%endif
+
+m4_ifdef( [[M4_YY_NO_GET_LINENO]],,
+[[
+/** Get the current line number.
+ * M4_YY_DOC_PARAM
+ */
+int yyget_lineno YYFARGS0(void)
+{
+ M4_YY_DECL_GUTS_VAR();
+
+ m4_ifdef( [[M4_YY_REENTRANT]],
+ [[
+ if (! YY_CURRENT_BUFFER)
+ return 0;
+ ]])
+ return yylineno;
+}
+]])
+
+m4_ifdef( [[M4_YY_REENTRANT]],
+[[
+m4_ifdef( [[M4_YY_NO_GET_COLUMN]],,
+[[
+/** Get the current column number.
+ * M4_YY_DOC_PARAM
+ */
+int yyget_column YYFARGS0(void)
+{
+ M4_YY_DECL_GUTS_VAR();
+
+ m4_ifdef( [[M4_YY_REENTRANT]],
+ [[
+ if (! YY_CURRENT_BUFFER)
+ return 0;
+ ]])
+ return yycolumn;
+}
+]])
+]])
+
+m4_ifdef( [[M4_YY_NO_GET_IN]],,
+[[
+/** Get the input stream.
+ * M4_YY_DOC_PARAM
+ */
+FILE *yyget_in YYFARGS0(void)
+{
+ M4_YY_DECL_GUTS_VAR();
+ return yyin;
+}
+]])
+
+m4_ifdef( [[M4_YY_NO_GET_OUT]],,
+[[
+/** Get the output stream.
+ * M4_YY_DOC_PARAM
+ */
+FILE *yyget_out YYFARGS0(void)
+{
+ M4_YY_DECL_GUTS_VAR();
+ return yyout;
+}
+]])
+
+m4_ifdef( [[M4_YY_NO_GET_LENG]],,
+[[
+/** Get the length of the current token.
+ * M4_YY_DOC_PARAM
+ */
+int yyget_leng YYFARGS0(void)
+{
+ M4_YY_DECL_GUTS_VAR();
+ return yyleng;
+}
+]])
+
+/** Get the current token.
+ * M4_YY_DOC_PARAM
+ */
+m4_ifdef( [[M4_YY_NO_GET_TEXT]],,
+[[
+char *yyget_text YYFARGS0(void)
+{
+ M4_YY_DECL_GUTS_VAR();
+ return yytext;
+}
+]])
+
+%if-reentrant
+m4_ifdef( [[M4_YY_NO_SET_EXTRA]],,
+[[
+/** Set the user-defined data. This data is never touched by the scanner.
+ * @param user_defined The data to be associated with this scanner.
+ * M4_YY_DOC_PARAM
+ */
+void yyset_extra YYFARGS1( YY_EXTRA_TYPE ,user_defined)
+{
+ M4_YY_DECL_GUTS_VAR();
+ yyextra = user_defined ;
+}
+]])
+%endif
+
+m4_ifdef( [[M4_YY_NO_SET_LINENO]],,
+[[
+/** Set the current line number.
+ * @param line_number
+ * M4_YY_DOC_PARAM
+ */
+void yyset_lineno YYFARGS1( int ,line_number)
+{
+ M4_YY_DECL_GUTS_VAR();
+
+ m4_ifdef( [[M4_YY_REENTRANT]],
+ [[
+ /* lineno is only valid if an input buffer exists. */
+ if (! YY_CURRENT_BUFFER )
+ yy_fatal_error( "yyset_lineno called with no buffer" M4_YY_CALL_LAST_ARG);
+ ]])
+ yylineno = line_number;
+}
+]])
+
+m4_ifdef( [[M4_YY_REENTRANT]],
+[[
+m4_ifdef( [[M4_YY_NO_SET_COLUMN]],,
+[[
+/** Set the current column.
+ * @param line_number
+ * M4_YY_DOC_PARAM
+ */
+void yyset_column YYFARGS1( int , column_no)
+{
+ M4_YY_DECL_GUTS_VAR();
+
+ m4_ifdef( [[M4_YY_REENTRANT]],
+ [[
+ /* column is only valid if an input buffer exists. */
+ if (! YY_CURRENT_BUFFER )
+ yy_fatal_error( "yyset_column called with no buffer" M4_YY_CALL_LAST_ARG);
+ ]])
+ yycolumn = column_no;
+}
+]])
+]])
+
+
+m4_ifdef( [[M4_YY_NO_SET_IN]],,
+[[
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ * M4_YY_DOC_PARAM
+ * @see yy_switch_to_buffer
+ */
+void yyset_in YYFARGS1( FILE * ,in_str)
+{
+ M4_YY_DECL_GUTS_VAR();
+ yyin = in_str ;
+}
+]])
+
+m4_ifdef( [[M4_YY_NO_SET_OUT]],,
+[[
+void yyset_out YYFARGS1( FILE * ,out_str)
+{
+ M4_YY_DECL_GUTS_VAR();
+ yyout = out_str ;
+}
+]])
+
+
+m4_ifdef( [[M4_YY_NO_GET_DEBUG]],,
+[[
+int yyget_debug YYFARGS0(void)
+{
+ M4_YY_DECL_GUTS_VAR();
+ return yy_flex_debug;
+}
+]])
+
+m4_ifdef( [[M4_YY_NO_SET_DEBUG]],,
+[[
+void yyset_debug YYFARGS1( int ,bdebug)
+{
+ M4_YY_DECL_GUTS_VAR();
+ yy_flex_debug = bdebug ;
+}
+]])
+%endif
+
+%if-reentrant
+/* Accessor methods for yylval and yylloc */
+
+%if-bison-bridge
+m4_ifdef( [[M4_YY_NO_GET_LVAL]],,
+[[
+YYSTYPE * yyget_lval YYFARGS0(void)
+{
+ M4_YY_DECL_GUTS_VAR();
+ return yylval;
+}
+]])
+
+m4_ifdef( [[M4_YY_NO_SET_LVAL]],,
+[[
+void yyset_lval YYFARGS1( YYSTYPE * ,yylval_param)
+{
+ M4_YY_DECL_GUTS_VAR();
+ yylval = yylval_param;
+}
+]])
+
+m4_ifdef( [[<M4_YY_BISON_LLOC>]],
+[[
+ m4_ifdef( [[M4_YY_NO_GET_LLOC]],,
+ [[
+YYLTYPE *yyget_lloc YYFARGS0(void)
+{
+ M4_YY_DECL_GUTS_VAR();
+ return yylloc;
+}
+ ]])
+
+ m4_ifdef( [[M4_YY_NO_SET_LLOC]],,
+ [[
+void yyset_lloc YYFARGS1( YYLTYPE * ,yylloc_param)
+{
+ M4_YY_DECL_GUTS_VAR();
+ yylloc = yylloc_param;
+}
+ ]])
+]])
+
+%endif
+
+
+/* User-visible API */
+
+/* yylex_init is special because it creates the scanner itself, so it is
+ * the ONLY reentrant function that doesn't take the scanner as the last argument.
+ * That's why we explicitly handle the declaration, instead of using our macros.
+ */
+m4_ifdef( [[M4_YY_NO_ANSI_FUNC_DEFS]],
+[[
+int yylex_init( ptr_yy_globals )
+ yyscan_t* ptr_yy_globals;
+]],
+[[
+int yylex_init(yyscan_t* ptr_yy_globals)
+]])
+{
+ if (ptr_yy_globals == NULL){
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL );
+
+ if (*ptr_yy_globals == NULL){
+ errno = ENOMEM;
+ return 1;
+ }
+
+ /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */
+ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+
+ return yy_init_globals ( *ptr_yy_globals );
+}
+
+
+/* yylex_init_extra has the same functionality as yylex_init, but follows the
+ * convention of taking the scanner as the last argument. Note however, that
+ * this is a *pointer* to a scanner, as it will be allocated by this call (and
+ * is the reason, too, why this function also must handle its own declaration).
+ * The user defined value in the first argument will be available to yyalloc in
+ * the yyextra field.
+ */
+m4_ifdef( [[M4_YY_NO_ANSI_FUNC_DEFS]],
+[[
+int yylex_init_extra( yy_user_defined, ptr_yy_globals )
+ YY_EXTRA_TYPE yy_user_defined;
+ yyscan_t* ptr_yy_globals;
+]],
+[[
+int yylex_init_extra( YY_EXTRA_TYPE yy_user_defined, yyscan_t* ptr_yy_globals )
+]])
+{
+ struct yyguts_t dummy_yyguts;
+
+ yyset_extra (yy_user_defined, &dummy_yyguts);
+
+ if (ptr_yy_globals == NULL){
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
+
+ if (*ptr_yy_globals == NULL){
+ errno = ENOMEM;
+ return 1;
+ }
+
+ /* By setting to 0xAA, we expose bugs in
+ yy_init_globals. Leave at 0x00 for releases. */
+ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+
+ yyset_extra (yy_user_defined, *ptr_yy_globals);
+
+ return yy_init_globals ( *ptr_yy_globals );
+}
+
+%endif if-c-only
+
+
+%if-c-only
+static int yy_init_globals YYFARGS0(void)
+{
+ M4_YY_DECL_GUTS_VAR();
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from yylex_destroy(), so don't allocate here.
+ */
+
+m4_ifdef( [[M4_YY_USE_LINENO]],
+[[
+ m4_ifdef( [[M4_YY_NOT_REENTRANT]],
+ [[
+ /* We do not touch yylineno unless the option is enabled. */
+ yylineno = 1;
+ ]])
+]])
+ YY_G(yy_buffer_stack) = 0;
+ YY_G(yy_buffer_stack_top) = 0;
+ YY_G(yy_buffer_stack_max) = 0;
+ YY_G(yy_c_buf_p) = (char *) 0;
+ YY_G(yy_init) = 0;
+ YY_G(yy_start) = 0;
+
+m4_ifdef( [[M4_YY_HAS_START_STACK_VARS]],
+[[
+ YY_G(yy_start_stack_ptr) = 0;
+ YY_G(yy_start_stack_depth) = 0;
+ YY_G(yy_start_stack) = NULL;
+]])
+
+m4_ifdef( [[M4_YY_USES_REJECT]],
+[[
+ YY_G(yy_state_buf) = 0;
+ YY_G(yy_state_ptr) = 0;
+ YY_G(yy_full_match) = 0;
+ YY_G(yy_lp) = 0;
+]])
+
+m4_ifdef( [[M4_YY_TEXT_IS_ARRAY]],
+[[
+ YY_G(yytext_ptr) = 0;
+ YY_G(yy_more_offset) = 0;
+ YY_G(yy_prev_more_offset) = 0;
+]])
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ yyin = stdin;
+ yyout = stdout;
+#else
+ yyin = (FILE *) 0;
+ yyout = (FILE *) 0;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * yylex_init()
+ */
+ return 0;
+}
+%endif
+
+
+%if-c-only SNIP! this currently causes conflicts with the c++ scanner
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy YYFARGS0(void)
+{
+ M4_YY_DECL_GUTS_VAR();
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ yy_delete_buffer( YY_CURRENT_BUFFER M4_YY_CALL_LAST_ARG );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ yypop_buffer_state(M4_YY_CALL_ONLY_ARG);
+ }
+
+ /* Destroy the stack itself. */
+ yyfree(YY_G(yy_buffer_stack) M4_YY_CALL_LAST_ARG);
+ YY_G(yy_buffer_stack) = NULL;
+
+m4_ifdef( [[M4_YY_HAS_START_STACK_VARS]],
+[[
+ /* Destroy the start condition stack. */
+ yyfree( YY_G(yy_start_stack) M4_YY_CALL_LAST_ARG );
+ YY_G(yy_start_stack) = NULL;
+]])
+
+m4_ifdef( [[M4_YY_USES_REJECT]],
+[[
+ yyfree ( YY_G(yy_state_buf) M4_YY_CALL_LAST_ARG);
+ YY_G(yy_state_buf) = NULL;
+]])
+
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * yylex() is called, initialization will occur. */
+ yy_init_globals( M4_YY_CALL_ONLY_ARG);
+
+%if-reentrant
+ /* Destroy the main struct (reentrant only). */
+ yyfree ( yyscanner M4_YY_CALL_LAST_ARG );
+ yyscanner = NULL;
+%endif
+ return 0;
+}
+%endif
+
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+/*
+ * Internal utility routines.
+ */
+]])
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+#ifndef yytext_ptr
+static void yy_flex_strncpy YYFARGS3( char*,s1, yyconst char *,s2, int,n)
+{
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+]])
+
+m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
+[[
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen YYFARGS1( yyconst char *,s)
+{
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+]])
+
+m4_ifdef( [[M4_YY_NO_FLEX_ALLOC]],,
+[[
+void *yyalloc YYFARGS1( yy_size_t ,size)
+{
+ return (void *) malloc( size );
+}
+]])
+
+m4_ifdef( [[M4_YY_NO_FLEX_REALLOC]],,
+[[
+void *yyrealloc YYFARGS2( void *,ptr, yy_size_t ,size)
+{
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+}
+]])
+
+m4_ifdef( [[M4_YY_NO_FLEX_FREE]],,
+[[
+void yyfree YYFARGS1( void *,ptr)
+{
+ free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
+}
+]])
+
+%if-tables-serialization definitions
+m4preproc_include(`tables_shared.c')
+
+static int yytbl_read8 (void *v, struct yytbl_reader * rd)
+{
+ errno = 0;
+ if (fread (v, sizeof (flex_uint8_t), 1, rd->fp) != 1){
+ errno = EIO;
+ return -1;
+ }
+ rd->bread += sizeof(flex_uint8_t);
+ return 0;
+}
+
+static int yytbl_read16 (void *v, struct yytbl_reader * rd)
+{
+ errno = 0;
+ if (fread (v, sizeof (flex_uint16_t), 1, rd->fp) != 1){
+ errno = EIO;
+ return -1;
+ }
+ *((flex_uint16_t *) v) = ntohs (*((flex_uint16_t *) v));
+ rd->bread += sizeof(flex_uint16_t);
+ return 0;
+}
+
+static int yytbl_read32 (void *v, struct yytbl_reader * rd)
+{
+ errno = 0;
+ if (fread (v, sizeof (flex_uint32_t), 1, rd->fp) != 1){
+ errno = EIO;
+ return -1;
+ }
+ *((flex_uint32_t *) v) = ntohl (*((flex_uint32_t *) v));
+ rd->bread += sizeof(flex_uint32_t);
+ return 0;
+}
+
+/** Read the header */
+static int yytbl_hdr_read YYFARGS2(struct yytbl_hdr *, th, struct yytbl_reader *, rd)
+{
+ int bytes;
+ memset (th, 0, sizeof (struct yytbl_hdr));
+
+ if (yytbl_read32 (&(th->th_magic), rd) != 0)
+ return -1;
+
+ if (th->th_magic != YYTBL_MAGIC){
+ yy_fatal_error("bad magic number" /*TODO: not fatal.*/ M4_YY_CALL_LAST_ARG);
+ return -1;
+ }
+
+ if (yytbl_read32 (&(th->th_hsize), rd) != 0
+ || yytbl_read32 (&(th->th_ssize), rd) != 0
+ || yytbl_read16 (&(th->th_flags), rd) != 0)
+ return -1;
+
+ /* Sanity check on header size. Greater than 1k suggests some funny business. */
+ if (th->th_hsize < 16 || th->th_hsize > 1024){
+ yy_fatal_error("insane header size detected" /*TODO: not fatal.*/ M4_YY_CALL_LAST_ARG);
+ return -1;
+ }
+
+ /* Allocate enough space for the version and name fields */
+ bytes = th->th_hsize - 14;
+ th->th_version = (char *) yyalloc (bytes M4_YY_CALL_LAST_ARG);
+ if ( ! th->th_version )
+ YY_FATAL_ERROR( "out of dynamic memory in yytbl_hdr_read()" );
+
+ /* we read it all into th_version, and point th_name into that data */
+ if (fread (th->th_version, 1, bytes, rd->fp) != bytes){
+ errno = EIO;
+ yyfree(th->th_version M4_YY_CALL_LAST_ARG);
+ th->th_version = NULL;
+ return -1;
+ }
+ else
+ rd->bread += bytes;
+
+ th->th_name = th->th_version + strlen (th->th_version) + 1;
+ return 0;
+}
+
+/** lookup id in the dmap list.
+ * @param dmap pointer to first element in list
+ * @return NULL if not found.
+ */
+static struct yytbl_dmap *yytbl_dmap_lookup YYFARGS2(struct yytbl_dmap *, dmap,
+ int, id)
+{
+ while (dmap->dm_id)
+ if (dmap->dm_id == id)
+ return dmap;
+ else
+ dmap++;
+ return NULL;
+}
+
+/** Read a table while mapping its contents to the local array.
+ * @param dmap used to performing mapping
+ * @return 0 on success
+ */
+static int yytbl_data_load YYFARGS2(struct yytbl_dmap *, dmap, struct yytbl_reader*, rd)
+{
+ struct yytbl_data td;
+ struct yytbl_dmap *transdmap=0;
+ int len, i, rv, inner_loop_count;
+ void *p=0;
+
+ memset (&td, 0, sizeof (struct yytbl_data));
+
+ if (yytbl_read16 (&td.td_id, rd) != 0
+ || yytbl_read16 (&td.td_flags, rd) != 0
+ || yytbl_read32 (&td.td_hilen, rd) != 0
+ || yytbl_read32 (&td.td_lolen, rd) != 0)
+ return -1;
+
+ /* Lookup the map for the transition table so we have it in case we need it
+ * inside the loop below. This scanner might not even have a transition
+ * table, which is ok.
+ */
+ transdmap = yytbl_dmap_lookup (dmap, YYTD_ID_TRANSITION M4_YY_CALL_LAST_ARG);
+
+ if ((dmap = yytbl_dmap_lookup (dmap, td.td_id M4_YY_CALL_LAST_ARG)) == NULL){
+ yy_fatal_error("table id not found in map." /*TODO: not fatal.*/ M4_YY_CALL_LAST_ARG);
+ return -1;
+ }
+
+ /* Allocate space for table.
+ * The --full yy_transition table is a special case, since we
+ * need the dmap.dm_sz entry to tell us the sizeof the individual
+ * struct members.
+ */
+ {
+ size_t bytes;
+
+ if ((td.td_flags & YYTD_STRUCT))
+ bytes = sizeof(struct yy_trans_info) * td.td_lolen * (td.td_hilen ? td.td_hilen : 1);
+ else
+ bytes = td.td_lolen * (td.td_hilen ? td.td_hilen : 1) * dmap->dm_sz;
+
+ if(M4_YY_TABLES_VERIFY)
+ /* We point to the array itself */
+ p = dmap->dm_arr;
+ else
+ /* We point to the address of a pointer. */
+ *dmap->dm_arr = p = (void *) yyalloc (bytes M4_YY_CALL_LAST_ARG);
+ if ( ! p )
+ YY_FATAL_ERROR( "out of dynamic memory in yytbl_data_load()" );
+ }
+
+ /* If it's a struct, we read 2 integers to get one element */
+ if ((td.td_flags & YYTD_STRUCT) != 0)
+ inner_loop_count = 2;
+ else
+ inner_loop_count = 1;
+
+ /* read and map each element.
+ * This loop iterates once for each element of the td_data array.
+ * Notice that we increment 'i' in the inner loop.
+ */
+ len = yytbl_calc_total_len (&td);
+ for (i = 0; i < len; ){
+ int j;
+
+
+ /* This loop really executes exactly 1 or 2 times.
+ * The second time is to handle the second member of the
+ * YYTD_STRUCT for the yy_transition array.
+ */
+ for (j = 0; j < inner_loop_count; j++, i++) {
+ flex_int32_t t32;
+
+ /* read into t32 no matter what the real size is. */
+ {
+ flex_int16_t t16;
+ flex_int8_t t8;
+
+ switch (YYTDFLAGS2BYTES (td.td_flags)) {
+ case sizeof (flex_int32_t):
+ rv = yytbl_read32 (&t32, rd);
+ break;
+ case sizeof (flex_int16_t):
+ rv = yytbl_read16 (&t16, rd);
+ t32 = t16;
+ break;
+ case sizeof (flex_int8_t):
+ rv = yytbl_read8 (&t8, rd);
+ t32 = t8;
+ break;
+ default:
+ yy_fatal_error("invalid td_flags" /*TODO: not fatal.*/ M4_YY_CALL_LAST_ARG);
+ return -1;
+ }
+ }
+ if (rv != 0)
+ return -1;
+
+ /* copy into the deserialized array... */
+
+ if ((td.td_flags & YYTD_STRUCT)) {
+ /* t32 is the j'th member of a two-element struct. */
+ void *v;
+
+ v = j == 0 ? &(((struct yy_trans_info *) p)->yy_verify)
+ : &(((struct yy_trans_info *) p)->yy_nxt);
+
+ switch (dmap->dm_sz) {
+ case sizeof (flex_int32_t):
+ if (M4_YY_TABLES_VERIFY){
+ if( ((flex_int32_t *) v)[0] != (flex_int32_t) t32)
+ yy_fatal_error("tables verification failed at YYTD_STRUCT flex_int32_t" M4_YY_CALL_LAST_ARG);
+ }else
+ ((flex_int32_t *) v)[0] = (flex_int32_t) t32;
+ break;
+ case sizeof (flex_int16_t):
+ if (M4_YY_TABLES_VERIFY ){
+ if(((flex_int16_t *) v)[0] != (flex_int16_t) t32)
+ yy_fatal_error("tables verification failed at YYTD_STRUCT flex_int16_t" M4_YY_CALL_LAST_ARG);
+ }else
+ ((flex_int16_t *) v)[0] = (flex_int16_t) t32;
+ break;
+ case sizeof(flex_int8_t):
+ if (M4_YY_TABLES_VERIFY ){
+ if( ((flex_int8_t *) v)[0] != (flex_int8_t) t32)
+ yy_fatal_error("tables verification failed at YYTD_STRUCT flex_int8_t" M4_YY_CALL_LAST_ARG);
+ }else
+ ((flex_int8_t *) v)[0] = (flex_int8_t) t32;
+ break;
+ default:
+ yy_fatal_error("invalid dmap->dm_sz for struct" /*TODO: not fatal.*/ M4_YY_CALL_LAST_ARG);
+ return -1;
+ }
+
+ /* if we're done with j, increment p */
+ if (j == 1)
+ p = (struct yy_trans_info *) p + 1;
+ }
+ else if ((td.td_flags & YYTD_PTRANS)) {
+ /* t32 is an index into the transition array. */
+ struct yy_trans_info *v;
+
+
+ if (!transdmap){
+ yy_fatal_error("transition table not found" /*TODO: not fatal.*/ M4_YY_CALL_LAST_ARG);
+ return -1;
+ }
+
+ if( M4_YY_TABLES_VERIFY)
+ v = &(((struct yy_trans_info *) (transdmap->dm_arr))[t32]);
+ else
+ v = &((*((struct yy_trans_info **) (transdmap->dm_arr)))[t32]);
+
+ if(M4_YY_TABLES_VERIFY ){
+ if( ((struct yy_trans_info **) p)[0] != v)
+ yy_fatal_error("tables verification failed at YYTD_PTRANS" M4_YY_CALL_LAST_ARG);
+ }else
+ ((struct yy_trans_info **) p)[0] = v;
+
+ /* increment p */
+ p = (struct yy_trans_info **) p + 1;
+ }
+ else {
+ /* t32 is a plain int. copy data, then incrememnt p. */
+ switch (dmap->dm_sz) {
+ case sizeof (flex_int32_t):
+ if(M4_YY_TABLES_VERIFY ){
+ if( ((flex_int32_t *) p)[0] != (flex_int32_t) t32)
+ yy_fatal_error("tables verification failed at flex_int32_t" M4_YY_CALL_LAST_ARG);
+ }else
+ ((flex_int32_t *) p)[0] = (flex_int32_t) t32;
+ p = ((flex_int32_t *) p) + 1;
+ break;
+ case sizeof (flex_int16_t):
+ if(M4_YY_TABLES_VERIFY ){
+ if( ((flex_int16_t *) p)[0] != (flex_int16_t) t32)
+ yy_fatal_error("tables verification failed at flex_int16_t" M4_YY_CALL_LAST_ARG);
+ }else
+ ((flex_int16_t *) p)[0] = (flex_int16_t) t32;
+ p = ((flex_int16_t *) p) + 1;
+ break;
+ case sizeof (flex_int8_t):
+ if(M4_YY_TABLES_VERIFY ){
+ if( ((flex_int8_t *) p)[0] != (flex_int8_t) t32)
+ yy_fatal_error("tables verification failed at flex_int8_t" M4_YY_CALL_LAST_ARG);
+ }else
+ ((flex_int8_t *) p)[0] = (flex_int8_t) t32;
+ p = ((flex_int8_t *) p) + 1;
+ break;
+ default:
+ yy_fatal_error("invalid dmap->dm_sz for plain int" /*TODO: not fatal.*/ M4_YY_CALL_LAST_ARG);
+ return -1;
+ }
+ }
+ }
+
+ }
+
+ /* Now eat padding. */
+ {
+ int pad;
+ pad = yypad64(rd->bread);
+ while(--pad >= 0){
+ flex_int8_t t8;
+ if(yytbl_read8(&t8,rd) != 0)
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+%define-yytables The name for this specific scanner's tables.
+
+/* Find the key and load the DFA tables from the given stream. */
+static int yytbl_fload YYFARGS2(FILE *, fp, const char *, key)
+{
+ int rv=0;
+ struct yytbl_hdr th;
+ struct yytbl_reader rd;
+
+ rd.fp = fp;
+ th.th_version = NULL;
+
+ /* Keep trying until we find the right set of tables or end of file. */
+ while (!feof(rd.fp)) {
+ rd.bread = 0;
+ if (yytbl_hdr_read (&th, &rd M4_YY_CALL_LAST_ARG) != 0){
+ rv = -1;
+ goto return_rv;
+ }
+
+ /* A NULL key means choose the first set of tables. */
+ if (key == NULL)
+ break;
+
+ if (strcmp(th.th_name,key) != 0){
+ /* Skip ahead to next set */
+ fseek(rd.fp, th.th_ssize - th.th_hsize, SEEK_CUR);
+ yyfree(th.th_version M4_YY_CALL_LAST_ARG);
+ th.th_version = NULL;
+ }
+ else
+ break;
+ }
+
+ while (rd.bread < th.th_ssize){
+ /* Load the data tables */
+ if(yytbl_data_load (yydmap,&rd M4_YY_CALL_LAST_ARG) != 0){
+ rv = -1;
+ goto return_rv;
+ }
+ }
+
+return_rv:
+ if(th.th_version){
+ yyfree(th.th_version M4_YY_CALL_LAST_ARG);
+ th.th_version = NULL;
+ }
+
+ return rv;
+}
+
+/** Load the DFA tables for this scanner from the given stream. */
+int yytables_fload YYFARGS1(FILE *, fp)
+{
+
+ if( yytbl_fload(fp, YYTABLES_NAME M4_YY_CALL_LAST_ARG) != 0)
+ return -1;
+ return 0;
+}
+
+/** Destroy the loaded tables, freeing memory, etc.. */
+int yytables_destroy YYFARGS0(void)
+{
+ struct yytbl_dmap *dmap=0;
+
+ if(!M4_YY_TABLES_VERIFY){
+ /* Walk the dmap, freeing the pointers */
+ for(dmap=yydmap; dmap->dm_id; dmap++) {
+ void * v;
+ v = dmap->dm_arr;
+ if(v && *(char**)v){
+ yyfree(*(char**)v M4_YY_CALL_LAST_ARG);
+ *(char**)v = NULL;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/* end table serialization code definitions */
+%endif
+
+
+m4_ifdef([[M4_YY_MAIN]], [[
+int main M4_YY_PARAMS(void);
+
+int main ()
+{
+
+%if-reentrant
+ yyscan_t lexer;
+ yylex_init(&lexer);
+ yylex( lexer );
+ yylex_destroy( lexer);
+
+%endif
+%if-not-reentrant
+ yylex();
+%endif
+
+ return 0;
+}
+]])
+
+%ok-for-header
+m4_ifdef( [[M4_YY_IN_HEADER]],
+[[
+#undef YY_NEW_FILE
+#undef YY_FLUSH_BUFFER
+#undef yy_set_bol
+#undef yy_new_buffer
+#undef yy_set_interactive
+#undef YY_DO_BEFORE_ACTION
+
+#ifdef YY_DECL_IS_OURS
+#undef YY_DECL_IS_OURS
+#undef YY_DECL
+#endif
+]])
diff --git a/tools/mhmake/src/flexint.h b/tools/mhmake/src/flexint.h
new file mode 100644
index 000000000..673aa1757
--- /dev/null
+++ b/tools/mhmake/src/flexint.h
@@ -0,0 +1,63 @@
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+
+#endif /* ! FLEXINT_H */
diff --git a/tools/mhmake/src/flexlexer.h b/tools/mhmake/src/flexlexer.h
new file mode 100644
index 000000000..48dab04ae
--- /dev/null
+++ b/tools/mhmake/src/flexlexer.h
@@ -0,0 +1,260 @@
+// -*-C++-*-
+// FlexLexer.h -- define interfaces for lexical analyzer classes generated
+// by flex
+
+// Copyright (c) 1993 The Regents of the University of California.
+// All rights reserved.
+//
+// This code is derived from software contributed to Berkeley by
+// Kent Williams and Tom Epperly.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+
+// Neither the name of the University nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+
+// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+// IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE.
+
+// This file defines FlexLexer, an abstract class which specifies the
+// external interface provided to flex C++ lexer objects, and yyFlexLexer,
+// which defines a particular lexer class.
+//
+// If you want to create multiple lexer classes, you use the -P flag
+// to rename each yyFlexLexer to some other xxFlexLexer. You then
+// include <FlexLexer.h> in your other sources once per lexer class:
+//
+// #undef yyFlexLexer
+// #define yyFlexLexer xxFlexLexer
+// #include <FlexLexer.h>
+//
+// #undef yyFlexLexer
+// #define yyFlexLexer zzFlexLexer
+// #include <FlexLexer.h>
+// ...
+
+#ifndef __FLEX_LEXER_H
+// Never included before - need to define base class.
+#define __FLEX_LEXER_H
+#include "mhmakeparser.h"
+
+#include <iostream>
+# ifndef FLEX_STD
+# define FLEX_STD std::
+# endif
+
+extern "C++" {
+
+struct yy_buffer_state;
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+typedef int yy_state_type;
+
+class FlexLexer {
+public:
+ FlexLexer() : yylineno(1), m_BraceIndent(0) {}
+ virtual ~FlexLexer() { }
+
+ const char* YYText() const { return yytext; }
+ int YYLeng() const { return yyleng; }
+
+ virtual void
+ yy_switch_to_buffer( struct yy_buffer_state* new_buffer ) = 0;
+ virtual struct yy_buffer_state*
+ yy_create_buffer( FLEX_STD istream* s, int size ) = 0;
+ virtual void yy_delete_buffer( struct yy_buffer_state* b ) = 0;
+ virtual void yyrestart( FLEX_STD istream* s ) = 0;
+
+ virtual int yylex(TOKENVALUE &theValue) = 0;
+
+
+ // Switch to new input/output streams. A nil stream pointer
+ // indicates "keep the current one".
+ virtual void switch_streams( FLEX_STD istream* new_in = 0,
+ FLEX_STD ostream* new_out = 0 ) = 0;
+
+ int lineno() const { return yylineno; }
+
+ int debug() const { return yy_flex_debug; }
+ void set_debug( int flag ) { yy_flex_debug = flag; }
+
+protected:
+ char* yytext;
+ int yyleng;
+ int yylineno; // only maintained if you use %option yylineno
+ int yy_flex_debug; // only has effect with -d or "%option debug"
+
+public:
+
+ struct INSTACK
+ {
+ YY_BUFFER_STATE m_BufferState;
+ ifstream m_Stream;
+ string m_FileName;
+ int yylineno;
+ INSTACK(YY_BUFFER_STATE BufferState, const string &FileToOpen, const string &PrevFileName, int Line) :
+ m_BufferState(BufferState),
+ m_FileName(PrevFileName),
+ yylineno(Line),
+ m_Stream(FileToOpen.c_str(), ios_base::in)
+ {
+ }
+ bool fail() const
+ {
+ return m_Stream.fail();
+ }
+ ifstream *GetStream()
+ {
+ return &m_Stream;
+ }
+ };
+ class mystack: public iterstack<INSTACK*>
+ {
+ public:
+ ~mystack()
+ {
+ iterator It=begin();
+ while (It!=end())
+ {
+ delete *It;
+ It++;
+ }
+ }
+ void pop()
+ {
+ INSTACK *pToRemove=top();
+ iterstack<INSTACK*>::pop();
+ delete pToRemove; /* Buffer does not need to be deleted because the lexer does this when it calls the pop */
+ }
+ };
+ int m_BraceIndent;
+ size_t m_IndentSkip;
+ iterstack<int> m_IndentStack;
+ bool m_IgnoreIncludeError;
+ string m_InputFileName;
+ string m_curtoken;
+ mystack m_IncludeStack;
+ mhmakeparser *m_pParser;
+ mhmakeparser *GetParser()
+ {
+ return m_pParser;
+ }
+
+};
+
+}
+#endif // FLEXLEXER_H
+
+#if defined(yyFlexLexer) || ! defined(yyFlexLexerOnce)
+// Either this is the first time through (yyFlexLexerOnce not defined),
+// or this is a repeated include to define a different flavor of
+// yyFlexLexer, as discussed in the flex manual.
+#define yyFlexLexerOnce
+
+extern "C++" {
+
+class mhmakeFlexLexer : public FlexLexer {
+public:
+ // arg_yyin and arg_yyout default to the cin and cout, but we
+ // only make that assignment when initializing in yylex().
+ mhmakeFlexLexer( FLEX_STD istream* arg_yyin = 0, FLEX_STD ostream* arg_yyout = 0 );
+
+ virtual ~mhmakeFlexLexer();
+
+ void yy_switch_to_buffer( struct yy_buffer_state* new_buffer );
+ struct yy_buffer_state* yy_create_buffer( FLEX_STD istream* s, int size );
+ void yy_delete_buffer( struct yy_buffer_state* b );
+ void yyrestart( FLEX_STD istream* s );
+
+ void yypush_buffer_state( struct yy_buffer_state* new_buffer );
+ void yypop_buffer_state();
+
+ virtual int yylex(TOKENVALUE &theValue);
+ virtual void switch_streams( FLEX_STD istream* new_in, FLEX_STD ostream* new_out = 0 );
+
+protected:
+ virtual int LexerInput( char* buf, int max_size );
+ virtual void LexerOutput( const char* buf, int size );
+ virtual void LexerError( const char* msg );
+
+ void yyunput( int c, char* buf_ptr );
+ int yyinput();
+ int yywrap();
+
+ void yy_load_buffer_state();
+ void yy_init_buffer( struct yy_buffer_state* b, FLEX_STD istream* s );
+ void yy_flush_buffer( struct yy_buffer_state* b );
+
+ int yy_start_stack_ptr;
+ int yy_start_stack_depth;
+ int* yy_start_stack;
+
+ void yy_push_state( int new_state );
+ void yy_pop_state();
+ int yy_top_state();
+
+ yy_state_type yy_get_previous_state();
+ yy_state_type yy_try_NUL_trans( yy_state_type current_state );
+ int yy_get_next_buffer();
+
+ FLEX_STD istream* yyin; // input source for default LexerInput
+ FLEX_STD ostream* yyout; // output sink for default LexerOutput
+
+ // yy_hold_char holds the character lost when yytext is formed.
+ char yy_hold_char;
+
+ // Number of characters read into yy_ch_buf.
+ int yy_n_chars;
+
+ // Points to current character in buffer.
+ char* yy_c_buf_p;
+
+ int yy_init; // whether we need to initialize
+ int yy_start; // start state number
+
+ // Flag which is used to allow yywrap()'s to do buffer switches
+ // instead of setting up a fresh yyin. A bit of a hack ...
+ int yy_did_buffer_switch_on_eof;
+
+
+ size_t yy_buffer_stack_top; /**< index of top of stack. */
+ size_t yy_buffer_stack_max; /**< capacity of stack. */
+ struct yy_buffer_state ** yy_buffer_stack; /**< Stack as an array. */
+ void yyensure_buffer_stack(void);
+
+ // The following are not always needed, but may be depending
+ // on use of certain flex features (like REJECT or yymore()).
+
+ yy_state_type yy_last_accepting_state;
+ char* yy_last_accepting_cpos;
+
+ yy_state_type* yy_state_buf;
+ yy_state_type* yy_state_ptr;
+
+ char* yy_full_match;
+ int* yy_full_state;
+ int yy_full_lp;
+
+ int yy_lp;
+ int yy_looking_for_trail_begin;
+
+ int yy_more_flag;
+ int yy_more_len;
+ int yy_more_offset;
+ int yy_prev_more_offset;
+};
+
+}
+
+#endif // yyFlexLexer || ! yyFlexLexerOnce
+
diff --git a/tools/mhmake/src/functions.cpp b/tools/mhmake/src/functions.cpp
new file mode 100644
index 000000000..61ae6c1e4
--- /dev/null
+++ b/tools/mhmake/src/functions.cpp
@@ -0,0 +1,842 @@
+/* This file is part of mhmake.
+ *
+ * Copyright (C) 2001-2010 marha@sourceforge.net
+ *
+ * Mhmake 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Mhmake 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 Mhmake. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* $Rev$ */
+
+#include "stdafx.h"
+
+#include "util.h"
+#include "mhmakefileparser.h"
+#include "rule.h"
+
+static const string s_QuoteString("\"");
+
+funcdef mhmakefileparser::m_FunctionsDef[]= {
+ {"filter", &mhmakefileparser::f_filter}
+ ,{"call", &mhmakefileparser::f_call}
+ ,{"subst", &mhmakefileparser::f_subst}
+ ,{"patsubst", &mhmakefileparser::f_patsubst}
+ ,{"concat", &mhmakefileparser::f_concat}
+ ,{"if", &mhmakefileparser::f_if}
+ ,{"findstring", &mhmakefileparser::f_findstring}
+ ,{"firstword", &mhmakefileparser::f_firstword}
+ ,{"wildcard", &mhmakefileparser::f_wildcard}
+ ,{"basename", &mhmakefileparser::f_basename}
+ ,{"notdir", &mhmakefileparser::f_notdir}
+ ,{"dir", &mhmakefileparser::f_dir}
+ ,{"shell", &mhmakefileparser::f_shell}
+ ,{"relpath", &mhmakefileparser::f_relpath}
+ ,{"toupper", &mhmakefileparser::f_toupper}
+ ,{"tolower", &mhmakefileparser::f_tolower}
+ ,{"exist", &mhmakefileparser::f_exist}
+ ,{"filesindirs",&mhmakefileparser::f_filesindirs}
+ ,{"fullname" ,&mhmakefileparser::f_fullname}
+ ,{"addprefix" ,&mhmakefileparser::f_addprefix}
+ ,{"addsuffix" ,&mhmakefileparser::f_addsuffix}
+ ,{"filter-out" ,&mhmakefileparser::f_filterout}
+ ,{"word" ,&mhmakefileparser::f_word}
+ ,{"words" ,&mhmakefileparser::f_words}
+ ,{"strip" ,&mhmakefileparser::f_strip}
+ ,{"which" ,&mhmakefileparser::f_which}
+ ,{"foreach" ,&mhmakefileparser::f_foreach}
+};
+
+map<string,function_f> mhmakefileparser::m_Functions;
+
+bool mhmakefileparser::m_FunctionsInitialised;
+
+///////////////////////////////////////////////////////////////////////////////
+// Loop over a list of filenames
+static string IterList(const string &List,string (*iterFunc)(const string &FileName,void *pArg), void *pArg=NULL)
+{
+ const char *pTmp=List.c_str();
+ string Ret=g_EmptyString;
+ bool first=true;
+ while (*pTmp)
+ {
+ if (!first)
+ {
+ Ret+=g_SpaceString;
+ }
+ else
+ {
+ first=false;
+ }
+ string Item;
+ pTmp=NextItem(pTmp,Item);
+ Item=iterFunc(Item,pArg);
+ if (Item.empty())
+ first=true; // Do not add space the next iteration
+ else
+ Ret+=Item;
+ }
+
+ return Ret;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void mhmakefileparser::InitFuncs(void)
+{
+ for (int i=0; i<sizeof(m_FunctionsDef)/sizeof(funcdef); i++)
+ m_Functions[m_FunctionsDef[i].szFuncName]=m_FunctionsDef[i].pFunc;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static string TrimString(const string &Input)
+{
+ unsigned Start=0;
+ while (strchr(" \t",Input[Start])) Start++;
+ if (Start>=Input.size())
+ return g_EmptyString;
+ size_t Stop=Input.size()-1;
+ while (strchr(" \t",Input[Stop])) Stop--;
+ return Input.substr(Start,Stop-Start+1);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static string filter(const string &FileName, void *pvFilter)
+{
+ string *pFilter=(string*)pvFilter;
+ if (PercentMatchList(UnquoteFileName(FileName),*pFilter))
+ return FileName;
+ else
+ return g_EmptyString;
+}
+///////////////////////////////////////////////////////////////////////////////
+string mhmakefileparser::f_filter(const string & Arg, const string *pOriExpr) const
+{
+ size_t ipos=Arg.find(',');
+ #ifdef _DEBUG
+ if (ipos==string::npos) {
+ throw string("filter func should have 2 arguments: ")+Arg;
+ }
+ #endif
+ string Str=TrimString(Arg.substr(0,ipos));
+ string List=Arg.substr(ipos+1);
+
+ if (Str.empty())
+ return Str;
+
+ return IterList(List,filter,(void*)&Str);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string mhmakefileparser::f_filterout(const string & Arg, const string *pOriExpr) const
+{
+ size_t ipos=Arg.find(',');
+ #ifdef _DEBUG
+ if (ipos==string::npos) {
+ throw string("filter func should have 2 arguments: ")+Arg;
+ }
+ #endif
+ string Str=TrimString(Arg.substr(0,ipos));
+ string List=Arg.substr(ipos+1);
+
+ if (Str.empty())
+ return Str;
+
+ bool First=true;
+ string Ret;
+ char *pTok=strtok((char*)List.c_str()," \t"); // doing this is changing string, so this is very dangerous
+ while (pTok)
+ {
+ string Item(pTok);
+ if (!PercentMatchList(Item,Str))
+ {
+ if (First)
+ {
+ Ret=Item;
+ First=false;
+ }
+ else
+ {
+ Ret+=g_SpaceString;
+ Ret+=Item;
+ }
+ }
+ pTok=strtok(NULL," \t");
+ }
+ return Ret;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string mhmakefileparser::f_call(const string & Arg, const string *pOriExpr) const
+{
+ const char *pTmp=Arg.c_str();
+
+ bool LastCharIsComma=Arg[Arg.length()-1]==',';
+
+ string Func;
+ pTmp=NextCharItem(pTmp,Func,',');
+ map<string,string>::const_iterator pFunc=m_Variables.find(Func);
+ #ifdef _DEBUG
+ if (pFunc==m_Variables.end())
+ {
+ throw string("call to non existing function ")+Func;
+ }
+ #endif
+ Func=pFunc->second;
+ int i=0;
+ while (*pTmp || LastCharIsComma) {
+ if (!*pTmp)
+ LastCharIsComma=false; /* To stop the loop */
+ string Repl;
+ pTmp=NextCharItem(pTmp,Repl,',');
+ i++;
+ char Tmp[10];
+ ::sprintf(Tmp,"$(%d)",i);
+ size_t Len=::strlen(Tmp);
+ size_t Pos=Func.find(Tmp);
+ while (Func.npos!=Pos)
+ {
+ Func=Func.substr(0,Pos)+Repl+Func.substr(Pos+Len);
+ Pos=Func.find(Tmp,Pos+Len);
+ }
+ }
+
+ return ExpandExpression(Func);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string mhmakefileparser::f_subst(const string & Arg, const string *pOriExpr) const
+{
+ const char *pTmp=Arg.c_str();
+
+ string FromString;
+ pTmp=NextCharItem(pTmp,FromString,',');
+ #ifdef _DEBUG
+ if (!*pTmp) {
+ throw string("Wrong number of arguments in function subst");
+ }
+ #endif
+
+ string ToString;
+ pTmp=NextCharItem(pTmp,ToString,',');
+ string Text;
+ NextCharItem(pTmp,Text,',');
+
+ if (FromString.empty())
+ return Text;
+
+ string Ret;
+ size_t Pos=Text.find(FromString);
+ size_t PrevPos=0;
+ while (Pos!=string::npos)
+ {
+ Ret+=Text.substr(PrevPos,Pos-PrevPos);
+ Ret+=ToString;
+ PrevPos=Pos+FromString.length();
+ Pos=Text.find(FromString,PrevPos);
+ }
+ Ret+=Text.substr(PrevPos);
+
+ return Ret;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string mhmakefileparser::f_patsubst(const string & Arg, const string *pOriExpr) const
+{
+ const char *pTmp=Arg.c_str();
+
+ string FromString;
+ pTmp=NextCharItem(pTmp,FromString,',');
+ #ifdef _DEBUG
+ if (!*pTmp) {
+ throw string("Wrong number of arguments in function subst");
+ }
+ #endif
+
+ string ToString;
+ pTmp=NextCharItem(pTmp,ToString,',');
+ string Text;
+ NextCharItem(pTmp,Text,',');
+
+ if (FromString.empty())
+ return Text;
+
+ return Substitute(Text,FromString,ToString);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string mhmakefileparser::f_concat(const string & Arg, const string *pOriExpr) const
+{
+ const char *pTmp=Arg.c_str();
+
+ string JoinString;
+ pTmp=NextCharItem(pTmp,JoinString,',');
+
+ string List;
+ pTmp=NextCharItem(pTmp,List,',');
+
+ if (JoinString.empty() && List.empty())
+ {
+ /* assume as $(concat ,,items) construct */
+ JoinString=",";
+ pTmp=NextCharItem(pTmp,List,',');
+ }
+
+ bool First=true;
+ string Ret;
+ char *pTok=strtok((char*)List.c_str()," \t"); // doing this is changing string, so this is very dangerous
+ while (pTok)
+ {
+ if (First)
+ {
+ First=false;
+ }
+ else
+ {
+ Ret+=JoinString;
+ }
+ Ret+=pTok;
+ pTok=strtok(NULL," \t");
+ }
+ return Ret;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string mhmakefileparser::f_if(const string & Arg, const string *pOriExpr) const
+{
+ const char *pTmp=Arg.c_str();
+
+ string Cond;
+ pTmp=NextCharItem(pTmp,Cond,',');
+ string Ret;
+ if (Cond.empty())
+ {
+ pTmp=NextCharItem(pTmp,Ret,',');
+ }
+ NextCharItem(pTmp,Ret,',');
+ return Ret;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string mhmakefileparser::f_findstring(const string & Arg, const string *pOriExpr) const
+{
+ const char *pTmp=Arg.c_str();
+ string find;
+ pTmp=NextCharItem(pTmp,find,',');
+ string instr;
+ NextCharItem(pTmp,instr,',');
+
+ if (instr.find(find) != instr.npos)
+ return find;
+ else
+ return g_EmptyString;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string mhmakefileparser::f_firstword(const string & Arg, const string *pOriExpr) const
+{
+ string FirstWord;
+ NextItem(Arg.c_str(),FirstWord);
+ return FirstWord;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static string wildcard(const string &Arg, void *pvVar)
+{
+ mhmakefileparser *pParser=(mhmakefileparser*)pvVar;
+
+ fileinfo *pFileSpec=GetFileInfo(Arg,pParser->GetMakeDir()); /* Use GetFileInfo to make the relative path absolute */
+ fileinfo *pDir=pFileSpec->GetDir();
+#ifdef WIN32
+ struct _finddata_t FileInfo;
+ intptr_t hFile=_findfirst(pFileSpec->GetFullFileName().c_str(),&FileInfo);
+ if (hFile==-1)
+ return g_EmptyString;
+
+ string Ret=g_EmptyString;
+
+ /* We have to verify with percentmatch since the find functions *.ext also matches the functions *.extbrol */
+ string CheckSpec=pFileSpec->GetName();
+ if (PercentMatchNoCase(FileInfo.name,CheckSpec,NULL,'*'))
+ {
+ Ret=GetFileInfo(FileInfo.name,pDir)->GetQuotedFullFileName();
+ }
+ while (-1!=_findnext(hFile,&FileInfo))
+ {
+ if (PercentMatchNoCase(FileInfo.name,CheckSpec,NULL,'*'))
+ {
+ Ret+=g_SpaceString;
+ Ret+=GetFileInfo(FileInfo.name,pDir)->GetQuotedFullFileName();
+ }
+ }
+ _findclose(hFile);
+#else
+ glob_t Res;
+ if (glob (pFileSpec->GetFullFileName().c_str(), GLOB_ERR|GLOB_NOSORT|GLOB_MARK, NULL, &Res))
+ return g_EmptyString;
+
+ string Ret=g_EmptyString;
+ string SepStr=g_EmptyString;
+ string CheckSpec=pFileSpec->GetName();
+ for (int i=0; i<Res.gl_pathc; i++)
+ {
+ if (PercentMatch(Res.gl_pathv[i],CheckSpec,NULL,'*'))
+ {
+ Ret+=SepStr;
+ Ret+=GetFileInfo(Res.gl_pathv[i],pDir)->GetQuotedFullFileName();
+ SepStr=g_SpaceString;
+ }
+ }
+
+ globfree(&Res);
+#endif
+ return Ret;
+}
+///////////////////////////////////////////////////////////////////////////////
+string mhmakefileparser::f_wildcard(const string & Arg, const string *pOriExpr) const
+{
+ return IterList(Arg, wildcard, (void*)this);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string mhmakefileparser::f_exist(const string & Arg, const string *pOriExpr) const
+{
+ string File=TrimString(Arg);
+ fileinfo *pFile=GetFileInfo(File,m_MakeDir);
+ if (pFile->Exists())
+ {
+ return string("1");
+ }
+ else
+ return g_EmptyString;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string mhmakefileparser::f_filesindirs(const string & Arg, const string *pOriExpr) const
+{
+ const char *pTmp=Arg.c_str();
+
+ string strFiles;
+ pTmp=NextCharItem(pTmp,strFiles,',');
+ #ifdef _DEBUG
+ if (!*pTmp) {
+ throw string("Wrong number of arguments in function filesindirs");
+ }
+ #endif
+ string strDirs;
+ NextCharItem(pTmp,strDirs,',');
+
+ vector<fileinfo*> Dirs;
+ SplitToItems(strDirs,Dirs);
+
+ pTmp=strFiles.c_str();
+ string Ret=g_EmptyString;
+ bool first=true;
+ while (*pTmp)
+ {
+ string File;
+ fileinfo *pFile;
+ pTmp=NextItem(pTmp,File);
+
+ vector<fileinfo*>::iterator It=Dirs.begin();
+ vector<fileinfo*>::iterator ItEnd=Dirs.end();
+ while (It!=ItEnd)
+ {
+ pFile=GetFileInfo(File,*It++);
+ if (pFile->Exists())
+ {
+ break;
+ }
+ pFile=NULL;
+ }
+ if (!pFile)
+ continue;
+
+ if (!first)
+ {
+ Ret+=g_SpaceString;
+ }
+ else
+ {
+ first=false;
+ }
+ Ret+=pFile->GetQuotedFullFileName();
+ }
+
+ return Ret;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string mhmakefileparser::f_fullname(const string & Arg, const string *pOriExpr) const
+{
+ string File=TrimString(Arg);
+ fileinfo *pFile=GetFileInfo(File,m_MakeDir);
+ return pFile->GetQuotedFullFileName();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static string basename(const string &FileName,void*)
+{
+ string Ret=UnquoteFileName(FileName);
+ Ret=Ret.substr(0,Ret.find_last_of('.'));
+ return QuoteFileName(Ret);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string mhmakefileparser::f_basename(const string & FileNames, const string *pOriExpr) const
+{
+ return IterList(FileNames,basename);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static string notdir(const string &FileName,void*)
+{
+ string Ret=UnquoteFileName(FileName);
+ size_t Pos=Ret.find_last_of(OSPATHSEP);
+ if (Pos==string::npos)
+ {
+ return FileName;
+ }
+ else
+ {
+ Ret=Ret.substr(Pos+1);
+ return QuoteFileName(Ret);
+ }
+
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string mhmakefileparser::f_notdir(const string & FileNames, const string *pOriExpr) const
+{
+ return IterList(FileNames,notdir);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static string addprefix(const string &FileName,void *pPrefix)
+{
+ return *(const string *)pPrefix+FileName;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string mhmakefileparser::f_addprefix(const string & Arg, const string *pOriExpr) const
+{
+ const char *pTmp=Arg.c_str();
+ string PreFix;
+ pTmp=NextCharItem(pTmp,PreFix,',');
+ #ifdef _DEBUG
+ if (g_PrintAdditionalInfo && PreFix.empty()) {
+ cout << "Warning: empty prefix in expression: " << *pOriExpr << endl;
+ }
+ #endif
+ string FileNames;
+ pTmp=NextCharItem(pTmp,FileNames,',');
+ return IterList(FileNames,addprefix,&PreFix);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static string addsuffix(const string &FileName,void *pSuffix)
+{
+ return FileName+*(const string *)pSuffix;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string mhmakefileparser::f_addsuffix(const string & Arg, const string *pOriExpr) const
+{
+ const char *pTmp=Arg.c_str();
+ string SufFix;
+ pTmp=NextCharItem(pTmp,SufFix,',');
+ #ifdef _DEBUG
+ if (!*pTmp) {
+ throw string("Wrong number of arguments in function addsuffix");
+ }
+ #endif
+ string FileNames;
+ pTmp=NextCharItem(pTmp,FileNames,',');
+ return IterList(FileNames,addsuffix,&SufFix);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Returns the n-th word number
+string mhmakefileparser::f_word(const string & Arg, const string *pOriExpr) const
+{
+ const char *pTmp=Arg.c_str();
+
+ string strNum;
+ pTmp=NextCharItem(pTmp,strNum,',');
+
+ int WordNbr=atoi(strNum.c_str());
+
+ #ifdef _DEBUG
+ if (!WordNbr)
+ {
+ if (!WordNbr) {
+ throw string ("Expecting a number bigger then 0 for the word function");
+ }
+ }
+ #endif
+
+ int CurWord=0;
+ while (*pTmp)
+ {
+ string Word;
+ pTmp=NextItem(pTmp,Word);
+ CurWord++;
+ if (CurWord==WordNbr)
+ return Word;
+ }
+
+ return g_EmptyString;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Returns the number of words
+string mhmakefileparser::f_words(const string & Arg, const string *pOriExpr) const
+{
+ const char *pTmp=Arg.c_str();
+ int NrWords=0;
+ char szNumber[10];
+ while (*pTmp)
+ {
+ string Word;
+ pTmp=NextItem(pTmp,Word);
+ NrWords++;
+ }
+ sprintf(szNumber,"%d",NrWords);
+
+ return szNumber;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Search for a command in the enivornment path
+string mhmakefileparser::f_which(const string & Arg, const string *pOriExpr) const
+{
+ return SearchCommand(Arg);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Removes leading and trailing space
+string mhmakefileparser::f_strip(const string & Arg, const string *pOriExpr) const
+{
+ string::const_iterator pFirst=Arg.begin();
+ string::const_iterator pLast=Arg.end();
+ while (strchr(" \t\r\n",*pFirst) && pFirst!=pLast) pFirst++;
+ if (pFirst==pLast)
+ return "";
+ while (strchr(" \t\r\n",*(--pLast)));
+ pLast++;
+ return Arg.substr(pFirst-Arg.begin(),pLast-pFirst);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static string dir(const string &FileName, void *)
+{
+ size_t Pos=FileName.find_last_of(OSPATHSEP);
+ if (Pos==string::npos)
+ {
+ return g_EmptyString;
+ }
+ else
+ {
+ string Ret=g_EmptyString;
+ Ret+=FileName.substr(0,Pos+1);
+ if (FileName[0]=='"' && FileName.end()[-1]=='"')
+ Ret+=s_QuoteString;
+ return Ret;
+ }
+
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string mhmakefileparser::f_dir(const string & FileNames, const string *pOriExpr) const
+{
+ return IterList(FileNames,dir);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string mhmakefileparser::f_shell(const string & Command, const string *pOriExpr) const
+{
+ string Output;
+
+#ifdef _DEBUG
+ if (g_PrintAdditionalInfo)
+ cout << "shell: executing: Command '"<<Command<<"'"<<endl;
+#endif
+
+ ((mhmakefileparser*)this)->ExecuteCommand(string("@")+Command,&Output); // Make sure that the command is not echoed
+#ifdef _DEBUG
+ if (g_PrintAdditionalInfo)
+ cout << "shell returned '"<<Output<<"'"<<endl;
+#endif
+ return Output;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static string relpath(const string &FileName,void *pvDir)
+{
+ const fileinfo *pDir=*(const fileinfo **)pvDir;
+ const fileinfo *pPath=GetFileInfo(FileName,pDir);
+ const char *pCur=pDir->GetFullFileName().c_str();
+ const char *pszPath=pPath->GetFullFileName().c_str();
+
+ const char *pLast=pszPath;
+ while (*pCur==*pszPath)
+ {
+ char Char=*pszPath;
+ if (!Char)
+ {
+ return "."; // Means that FileName is the same as the current directory
+ }
+ if (Char==OSPATHSEP)
+ pLast=pszPath+1;
+ pCur++;
+ pszPath++;
+ }
+ if (*pszPath==OSPATHSEP && !*pCur)
+ pLast=pszPath+1;
+ string retPath;
+ if (*pCur==OSPATHSEP) {
+ bool first=true;
+ pCur++;
+ retPath="..";
+ while (*pCur)
+ {
+ if (*pCur==OSPATHSEP)
+ retPath+=OSPATHSEPSTR"..";
+ pCur++;
+ }
+ if (pszPath)
+ retPath=retPath+OSPATHSEPSTR+pLast;
+ }
+ else
+ {
+ if (*pCur)
+ retPath=".."OSPATHSEPSTR;
+ while (*pCur)
+ {
+ if (*pCur==OSPATHSEP)
+ retPath+=".."OSPATHSEPSTR;
+ pCur++;
+ }
+ retPath+=pLast;
+ }
+ return QuoteFileName(retPath);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Make a path name relative to the current directory
+string mhmakefileparser::f_relpath(const string & FileNames, const string *pOriExpr) const
+{
+ return IterList(FileNames,relpath,(void*)&m_MakeDir);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static string makeupper(const string &FileName,void *)
+{
+ string Ret=FileName;
+ string::const_iterator pSrc=FileName.begin();
+ string::iterator pDest=Ret.begin();
+ while (pSrc!=FileName.end())
+ {
+ *pDest++ = toupper(*pSrc++);
+ }
+ return Ret;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string mhmakefileparser::f_toupper(const string & FileNames, const string *pOriExpr) const
+{
+ return IterList(FileNames,makeupper);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static string makelower(const string &FileName, void *)
+{
+ string Ret=FileName;
+ string::const_iterator pSrc=FileName.begin();
+ string::iterator pDest=Ret.begin();
+ while (pSrc!=FileName.end())
+ {
+ *pDest++ = tolower(*pSrc++);
+ }
+ return Ret;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string mhmakefileparser::f_tolower(const string & FileNames, const string *pOriExpr) const
+{
+ return IterList(FileNames,makelower);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+struct expanedexpr_arg
+{
+ string Var;
+ mhmakefileparser *pParser;
+ string Expr;
+};
+
+static string expandexpr(const string &VarVal, void *pvVar)
+{
+ expanedexpr_arg *pArg=(expanedexpr_arg*)pvVar;
+ pArg->pParser->SetVariable(pArg->Var,VarVal);
+ return pArg->pParser->ExpandExpression(pArg->Expr);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string mhmakefileparser::f_foreach(const string & ExpandedArg, const string *pOriExpr) const
+{
+#ifdef _DEBUG
+ if (pOriExpr->substr(0,8)!="foreach ")
+ throw(string("wrong assumption in foreach expression: ")+*pOriExpr);
+#endif
+ const char *pTmp=ExpandedArg.c_str();
+
+ expanedexpr_arg Args;
+ Args.pParser=(mhmakefileparser*)this;
+ pTmp=NextCharItem(pTmp,Args.Var,',');
+
+ if (Args.Var.empty())
+ throw(string("Wrong syntax in foreach instruction. Should give the variable a name."));
+
+ string Items;
+ pTmp=NextCharItem(pTmp,Items,',');
+
+ if (Items.empty())
+ return g_EmptyString; /* No items specified, so nothing needs to be done */
+
+ /* for the next item we need to use the original expression because we need to re-expand it using Var for each entry
+ in Items */
+ int Pos=pOriExpr->find_first_of(',',0);
+ if (Pos==string::npos)
+ throw(string("expected , in ")+*pOriExpr);
+ Pos=pOriExpr->find_first_of(',',Pos+1);
+ if (Pos==string::npos)
+ throw(string("expected two ,'s in ")+*pOriExpr);
+ Args.Expr=pOriExpr->substr(Pos+1);
+
+ /* Save the variable to be able to restore it after the foreach expansion */
+ string VarVal;
+ map<string,string>::const_iterator pVal=m_Variables.find(Args.Var);
+ if (pVal!=m_Variables.end())
+ VarVal=pVal->second;
+
+ string Ret=IterList(Items,expandexpr,(void*)&Args);
+
+ /* Restore the variable to it's original value */
+ if (pVal!=m_Variables.end())
+ Args.pParser->SetVariable(Args.Var,VarVal);
+ else
+ Args.pParser->DeleteVariable(Args.Var);
+
+ return Ret;
+}
+
diff --git a/tools/mhmake/src/md5.cpp b/tools/mhmake/src/md5.cpp
new file mode 100644
index 000000000..0ffba0d48
--- /dev/null
+++ b/tools/mhmake/src/md5.cpp
@@ -0,0 +1,455 @@
+/* This file is part of mhmake.
+ *
+ * Copyright (C) 2001-2010 marha@sourceforge.net
+ *
+ * Mhmake 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Mhmake 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 Mhmake. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* $Rev$ */
+
+/*
+ * RFC 1321 compliant MD5 implementation
+ *
+ * Copyright (C) 2001-2003 Christophe Devine
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "stdafx.h"
+#include "md5.h"
+
+#ifdef _MSC_VER
+#pragma warning (disable:4005) /* macro redefinition */
+#endif
+
+#ifdef _DEBUG
+map<uint32,string> g_Md5Database;
+#endif
+
+#define GET_UINT32(n,b,i) \
+{ \
+ (n) = ( (uint32) (b)[(i) ] ) \
+ | ( (uint32) (b)[(i) + 1] << 8 ) \
+ | ( (uint32) (b)[(i) + 2] << 16 ) \
+ | ( (uint32) (b)[(i) + 3] << 24 ); \
+}
+
+#define PUT_UINT32(n,b,i) \
+{ \
+ (b)[(i) ] = (uint8) ( (n) ); \
+ (b)[(i) + 1] = (uint8) ( (n) >> 8 ); \
+ (b)[(i) + 2] = (uint8) ( (n) >> 16 ); \
+ (b)[(i) + 3] = (uint8) ( (n) >> 24 ); \
+}
+
+void md5_starts( md5_context *ctx )
+{
+ ctx->total[0] = 0;
+ ctx->total[1] = 0;
+
+ ctx->state[0] = 0x67452301;
+ ctx->state[1] = 0xEFCDAB89;
+ ctx->state[2] = 0x98BADCFE;
+ ctx->state[3] = 0x10325476;
+#ifdef _DEBUG
+ if (g_BuildMd5Db) ctx->Data="";
+#endif
+}
+
+void md5_process( md5_context *ctx, uint8 data[64] )
+{
+ uint32 X[16], A, B, C, D;
+
+ GET_UINT32( X[0], data, 0 );
+ GET_UINT32( X[1], data, 4 );
+ GET_UINT32( X[2], data, 8 );
+ GET_UINT32( X[3], data, 12 );
+ GET_UINT32( X[4], data, 16 );
+ GET_UINT32( X[5], data, 20 );
+ GET_UINT32( X[6], data, 24 );
+ GET_UINT32( X[7], data, 28 );
+ GET_UINT32( X[8], data, 32 );
+ GET_UINT32( X[9], data, 36 );
+ GET_UINT32( X[10], data, 40 );
+ GET_UINT32( X[11], data, 44 );
+ GET_UINT32( X[12], data, 48 );
+ GET_UINT32( X[13], data, 52 );
+ GET_UINT32( X[14], data, 56 );
+ GET_UINT32( X[15], data, 60 );
+
+#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
+
+#define P(a,b,c,d,k,s,t) \
+{ \
+ a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
+}
+
+ A = ctx->state[0];
+ B = ctx->state[1];
+ C = ctx->state[2];
+ D = ctx->state[3];
+
+#define F(x,y,z) (z ^ (x & (y ^ z)))
+
+ P( A, B, C, D, 0, 7, 0xD76AA478 );
+ P( D, A, B, C, 1, 12, 0xE8C7B756 );
+ P( C, D, A, B, 2, 17, 0x242070DB );
+ P( B, C, D, A, 3, 22, 0xC1BDCEEE );
+ P( A, B, C, D, 4, 7, 0xF57C0FAF );
+ P( D, A, B, C, 5, 12, 0x4787C62A );
+ P( C, D, A, B, 6, 17, 0xA8304613 );
+ P( B, C, D, A, 7, 22, 0xFD469501 );
+ P( A, B, C, D, 8, 7, 0x698098D8 );
+ P( D, A, B, C, 9, 12, 0x8B44F7AF );
+ P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
+ P( B, C, D, A, 11, 22, 0x895CD7BE );
+ P( A, B, C, D, 12, 7, 0x6B901122 );
+ P( D, A, B, C, 13, 12, 0xFD987193 );
+ P( C, D, A, B, 14, 17, 0xA679438E );
+ P( B, C, D, A, 15, 22, 0x49B40821 );
+
+#undef F
+
+#define F(x,y,z) (y ^ (z & (x ^ y)))
+
+ P( A, B, C, D, 1, 5, 0xF61E2562 );
+ P( D, A, B, C, 6, 9, 0xC040B340 );
+ P( C, D, A, B, 11, 14, 0x265E5A51 );
+ P( B, C, D, A, 0, 20, 0xE9B6C7AA );
+ P( A, B, C, D, 5, 5, 0xD62F105D );
+ P( D, A, B, C, 10, 9, 0x02441453 );
+ P( C, D, A, B, 15, 14, 0xD8A1E681 );
+ P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
+ P( A, B, C, D, 9, 5, 0x21E1CDE6 );
+ P( D, A, B, C, 14, 9, 0xC33707D6 );
+ P( C, D, A, B, 3, 14, 0xF4D50D87 );
+ P( B, C, D, A, 8, 20, 0x455A14ED );
+ P( A, B, C, D, 13, 5, 0xA9E3E905 );
+ P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
+ P( C, D, A, B, 7, 14, 0x676F02D9 );
+ P( B, C, D, A, 12, 20, 0x8D2A4C8A );
+
+#undef F
+
+#define F(x,y,z) (x ^ y ^ z)
+
+ P( A, B, C, D, 5, 4, 0xFFFA3942 );
+ P( D, A, B, C, 8, 11, 0x8771F681 );
+ P( C, D, A, B, 11, 16, 0x6D9D6122 );
+ P( B, C, D, A, 14, 23, 0xFDE5380C );
+ P( A, B, C, D, 1, 4, 0xA4BEEA44 );
+ P( D, A, B, C, 4, 11, 0x4BDECFA9 );
+ P( C, D, A, B, 7, 16, 0xF6BB4B60 );
+ P( B, C, D, A, 10, 23, 0xBEBFBC70 );
+ P( A, B, C, D, 13, 4, 0x289B7EC6 );
+ P( D, A, B, C, 0, 11, 0xEAA127FA );
+ P( C, D, A, B, 3, 16, 0xD4EF3085 );
+ P( B, C, D, A, 6, 23, 0x04881D05 );
+ P( A, B, C, D, 9, 4, 0xD9D4D039 );
+ P( D, A, B, C, 12, 11, 0xE6DB99E5 );
+ P( C, D, A, B, 15, 16, 0x1FA27CF8 );
+ P( B, C, D, A, 2, 23, 0xC4AC5665 );
+
+#undef F
+
+#define F(x,y,z) (y ^ (x | ~z))
+
+ P( A, B, C, D, 0, 6, 0xF4292244 );
+ P( D, A, B, C, 7, 10, 0x432AFF97 );
+ P( C, D, A, B, 14, 15, 0xAB9423A7 );
+ P( B, C, D, A, 5, 21, 0xFC93A039 );
+ P( A, B, C, D, 12, 6, 0x655B59C3 );
+ P( D, A, B, C, 3, 10, 0x8F0CCC92 );
+ P( C, D, A, B, 10, 15, 0xFFEFF47D );
+ P( B, C, D, A, 1, 21, 0x85845DD1 );
+ P( A, B, C, D, 8, 6, 0x6FA87E4F );
+ P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
+ P( C, D, A, B, 6, 15, 0xA3014314 );
+ P( B, C, D, A, 13, 21, 0x4E0811A1 );
+ P( A, B, C, D, 4, 6, 0xF7537E82 );
+ P( D, A, B, C, 11, 10, 0xBD3AF235 );
+ P( C, D, A, B, 2, 15, 0x2AD7D2BB );
+ P( B, C, D, A, 9, 21, 0xEB86D391 );
+
+#undef F
+
+ ctx->state[0] += A;
+ ctx->state[1] += B;
+ ctx->state[2] += C;
+ ctx->state[3] += D;
+}
+
+static uint8 md5_padding[64] =
+{
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+void md5_update( md5_context *ctx, uint8 *input, size_t length )
+{
+ uint32 left, fill;
+
+ if( ! length ) return;
+
+#ifdef _DEBUG
+ if (g_BuildMd5Db && md5_padding!=input && ctx->msglen!=input)
+ ctx->Data+=string((char*)input,length);
+#endif
+
+ left = ctx->total[0] & 0x3F;
+ fill = 64 - left;
+
+ ctx->total[0] = (uint32)((ctx->total[0] + length)& 0xFFFFFFFF);
+
+ if( ctx->total[0] < length )
+ ctx->total[1]++;
+
+ if( left && length >= fill )
+ {
+ memcpy( (void *) (ctx->buffer + left),
+ (void *) input, fill );
+ md5_process( ctx, ctx->buffer );
+ length -= fill;
+ input += fill;
+ left = 0;
+ }
+
+ while( length >= 64 )
+ {
+ md5_process( ctx, input );
+ length -= 64;
+ input += 64;
+ }
+
+ if( length )
+ {
+ memcpy( (void *) (ctx->buffer + left),
+ (void *) input, length );
+ }
+}
+
+uint32 *md5_finishbin( md5_context *ctx)
+{
+ uint32 last, padn;
+ uint32 high, low;
+
+ high = ( ctx->total[0] >> 29 )
+ | ( ctx->total[1] << 3 );
+ low = ( ctx->total[0] << 3 );
+
+ PUT_UINT32( low, ctx->msglen, 0 );
+ PUT_UINT32( high, ctx->msglen, 4 );
+
+ last = ctx->total[0] & 0x3F;
+ padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
+
+ md5_update( ctx, md5_padding, padn );
+ md5_update( ctx, ctx->msglen, 8 );
+
+ return ctx->state;
+}
+
+void md5_finish( md5_context *ctx, uint8 digest[16] )
+{
+ md5_finishbin( ctx);
+ PUT_UINT32( ctx->state[0], digest, 0 );
+ PUT_UINT32( ctx->state[1], digest, 4 );
+ PUT_UINT32( ctx->state[2], digest, 8 );
+ PUT_UINT32( ctx->state[3], digest, 12 );
+}
+
+uint32 md5_finish32( md5_context *ctx)
+{
+ md5_finishbin( ctx);
+ uint32 Md5_32=ctx->state[0]+ctx->state[1]+ctx->state[2]+ctx->state[3];
+#ifdef _DEBUG
+ if (g_BuildMd5Db) g_Md5Database[Md5_32]=ctx->Data;
+#endif
+ return Md5_32;
+}
+
+#ifdef _DEBUG
+struct WRITEMD5DB
+{
+ ~WRITEMD5DB()
+ {
+ if (g_BuildMd5Db)
+ {
+ FILE *pFile=fopen("Md5.database","wb");
+ map<uint32,string>::const_iterator It=g_Md5Database.begin();
+ while (It!=g_Md5Database.end())
+ {
+ fprintf(pFile,"%08x: ",It->first);
+ fwrite(It->second.c_str(),It->second.length(),1,pFile);
+ fprintf(pFile,"\n");
+ It++;
+ }
+ fclose(pFile);
+ }
+ }
+};
+static WRITEMD5DB WriteMd5Db;
+#endif
+
+
+#ifdef TEST
+
+#include <stdlib.h>
+#include <stdio.h>
+
+/*
+ * those are the standard RFC 1321 test vectors
+ */
+
+static char *msg[] =
+{
+ "",
+ "a",
+ "abc",
+ "message digest",
+ "abcdefghijklmnopqrstuvwxyz",
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+ "12345678901234567890123456789012345678901234567890123456789012" \
+ "345678901234567890"
+};
+
+static char *val[] =
+{
+ "d41d8cd98f00b204e9800998ecf8427e",
+ "0cc175b9c0f1b6a831c399e269772661",
+ "900150983cd24fb0d6963f7d28e17f72",
+ "f96b697d7cb7938d525a2f31aaf161d0",
+ "c3fcd3d76192e4007dfb496cca67e13b",
+ "d174ab98d277d9f5a5611c2c9f419d9f",
+ "57edf4a22be3c955ac49da2e2107b67a"
+};
+
+int main( int argc, char *argv[] )
+{
+ FILE *f;
+ int i, j;
+ char output[33];
+ md5_context ctx;
+ unsigned char buf[1000];
+ unsigned char md5sum[16];
+
+ if( argc < 2 )
+ {
+ printf( "\n MD5 Validation Tests:\n\n" );
+
+ for( i = 0; i < 7; i++ )
+ {
+ printf( " Test %d ", i + 1 );
+
+ md5_starts( &ctx );
+ md5_update( &ctx, (uint8 *) msg[i], strlen( msg[i] ) );
+ md5_finish( &ctx, md5sum );
+
+ for( j = 0; j < 16; j++ )
+ {
+ sprintf( output + j * 2, "%02x", md5sum[j] );
+ }
+
+ if( memcmp( output, val[i], 32 ) )
+ {
+ printf( "failed!\n" );
+ return( 1 );
+ }
+
+ printf( "passed.\n" );
+ }
+
+ printf( "\n" );
+ }
+ else
+ {
+ if( ! ( f = fopen( argv[1], "rb" ) ) )
+ {
+ perror( "fopen" );
+ return( 1 );
+ }
+
+ md5_starts( &ctx );
+
+ while( ( i = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
+ {
+ md5_update( &ctx, buf, i );
+ }
+
+ md5_finish( &ctx, md5sum );
+
+ for( j = 0; j < 16; j++ )
+ {
+ printf( "%02x", md5sum[j] );
+ }
+
+ printf( " %s\n", argv[1] );
+ }
+
+ return( 0 );
+}
+
+#endif
+
+//#define APP
+#ifdef APP
+#include <stdio.h>
+
+int main( int argc, char *argv[] )
+{
+ unsigned j;
+ unsigned char md5sum[16];
+ md5_context ctx;
+ FILE *pFile=fopen(argv[1],"r");
+
+ if (!pFile)
+ {
+ printf("Error opening file.\n");
+ return 1;
+ }
+
+ md5_starts( &ctx );
+
+ while (1)
+ {
+ char Buf[1024];
+ size_t Ret=fread(Buf,1,sizeof(Buf),pFile);
+ if (!Ret)
+ break;
+ md5_update( &ctx, (uint8 *) Buf, Ret);
+ }
+ md5_finish( &ctx, md5sum );
+
+ for( j = 0; j < 16; j++ )
+ {
+ printf("%02x", md5sum[j] );
+ }
+
+}
+#endif
+
diff --git a/tools/mhmake/src/md5.h b/tools/mhmake/src/md5.h
new file mode 100644
index 000000000..f16c9bd19
--- /dev/null
+++ b/tools/mhmake/src/md5.h
@@ -0,0 +1,58 @@
+/* This file is part of mhmake.
+ *
+ * Copyright (C) 2001-2010 marha@sourceforge.net
+ *
+ * Mhmake 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Mhmake 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 Mhmake. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* $Rev$ */
+
+#ifndef _MD5_H
+#define _MD5_H
+
+#ifndef uint8
+#define uint8 unsigned char
+#endif
+
+#ifndef uint32
+#define uint32 unsigned long int
+#endif
+
+typedef struct
+{
+ uint32 total[2];
+ uint32 state[4];
+ uint8 buffer[64];
+ uint8 msglen[8];
+#ifdef _DEBUG
+ string Data;
+#endif
+}
+md5_context;
+
+typedef uint32 md5_val[4];
+
+void md5_starts( md5_context *ctx );
+void md5_update( md5_context *ctx, uint8 *input, size_t length );
+void md5_finish( md5_context *ctx, uint8 digest[16] );
+uint32 *md5_finishbin( md5_context *ctx);
+uint32 md5_finish32( md5_context *ctx);
+
+#ifdef _DEBUG
+extern bool g_BuildMd5Db;
+#endif
+
+#endif /* md5.h */
+
+
diff --git a/tools/mhmake/src/mhmake.cpp b/tools/mhmake/src/mhmake.cpp
new file mode 100644
index 000000000..6d99e5f3d
--- /dev/null
+++ b/tools/mhmake/src/mhmake.cpp
@@ -0,0 +1,158 @@
+/* This file is part of mhmake.
+ *
+ * Copyright (C) 2001-2010 marha@sourceforge.net
+ *
+ * Mhmake 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Mhmake 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 Mhmake. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* $Rev$ */
+
+#include "stdafx.h"
+#include "fileinfo.h"
+#include "mhmakeparser.h"
+#include "rule.h"
+#include "util.h"
+
+bool g_Clean=false;
+bool g_StopCompiling=false;
+
+#ifdef WIN32
+BOOL WINAPI ControlCHandler(DWORD dwCtrlType)
+{
+ g_StopCompiling=true;
+ return TRUE;
+}
+#endif
+
+int __CDECL main(int argc, char* argv[])
+{
+ //__int64 Freq;
+ //__int64 Start;
+
+ //QueryPerformanceFrequency((LARGE_INTEGER*)&Freq);
+ //QueryPerformanceCounter((LARGE_INTEGER*)&Start);
+
+ #if defined(_DEBUG) && defined(_MSC_VER)
+ int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
+
+ // Turn on leak-checking bit
+ tmpFlag |= _CRTDBG_LEAK_CHECK_DF;
+ // Turn on defer freeing
+ //tmpFlag |= _CRTDBG_DELAY_FREE_MEM_DF;
+ // Turn on heap checking
+ //tmpFlag |= _CRTDBG_CHECK_ALWAYS_DF;
+
+ // Set flag to the new value
+ _CrtSetDbgFlag( tmpFlag );
+
+ //_CrtSetBreakAlloc(44);
+ #endif
+
+ #ifdef WIN32
+ /* Remove the VS_UNICODE_OUTPUT environment variable. This variable is set when running from
+ * the Visual Studio IDE and is causing the output of cl.exe to send the output directly to the IDE instead
+ * of sending it to stdout. This is causing all scripts that are calling cl.exe and intercept the
+ * output to fail.
+ */
+ putenv("VS_UNICODE_OUTPUT=");
+
+ SetConsoleCtrlHandler(ControlCHandler, TRUE);
+
+ #endif
+
+ try
+ {
+ mhmakefileparser::InitBuildTime();
+
+ char PlatformEnv[]="PLATFORM="PLATFORM;
+ putenv(PlatformEnv);
+
+ vector<string> CmdLineArgs;
+ for (int i=1; i<argc; i++)
+ {
+ CmdLineArgs.push_back(argv[i]);
+ }
+
+ refptr<loadedmakefile> pFirstMakefile(new loadedmakefile(curdir::GetCurDir(),CmdLineArgs,"makefile"));
+ // For the first makefile we add the defines passed on the command line to the
+ // environment so that the other load_makefile see the same variables
+ pFirstMakefile->AddCommandLineVarsToEnvironment();
+
+ g_LoadedMakefiles.push_back(pFirstMakefile);
+
+ pFirstMakefile->LoadMakefile();
+
+ #ifdef _DEBUG
+ if (g_PrintVarsAndRules)
+ {
+ DumpVarsAndRules();
+ }
+ #endif
+
+ // Make sure that the included makefiles that have rules are build
+
+ LOADEDMAKEFILES::iterator LoadMakIt=g_LoadedMakefiles.begin();
+ while (LoadMakIt!=g_LoadedMakefiles.end())
+ {
+ (*LoadMakIt)->m_pParser->BuildIncludedMakefiles();
+ (*LoadMakIt)->m_pParser->ParseBuildedIncludeFiles();
+ (*LoadMakIt)->m_pParser->CheckEnv();
+ LoadMakIt++;
+ }
+
+ if (pFirstMakefile->m_CommandLineTargets.size())
+ {
+ vector<string>::iterator It=pFirstMakefile->m_CommandLineTargets.begin();
+ while (It!=pFirstMakefile->m_CommandLineTargets.end())
+ {
+ if (*It=="clean" || *It=="cleanall")
+ {
+ g_Clean=true;
+ }
+ fileinfo *pTarget=GetFileInfo(*It,pFirstMakefile->m_MakeDir);
+ pFirstMakefile->m_pParser->BuildTarget(pTarget);
+ It++;
+ }
+ }
+ else
+ {
+ fileinfo *pFirstTarget=pFirstMakefile->m_pParser->GetFirstTarget();
+ if (pFirstTarget)
+ {
+ pFirstMakefile->m_pParser->BuildTarget(pFirstTarget);
+ }
+ else
+ cout << "Warning: no targets in makefile. Nothing to be build.\nMHMAKECONF defined?\n";
+ }
+
+ }
+ catch (string Message)
+ {
+ cerr << "Error occured: " << Message << endl;
+ #ifdef _DEBUG
+ if (g_DumpOnError)
+ {
+ DumpVarsAndRules();
+ }
+ #endif
+ return 1;
+ }
+
+ //__int64 Stop;
+ //QueryPerformanceCounter((LARGE_INTEGER*)&Stop);
+ //cout << (Stop-Start)*1000/Freq << endl;
+
+ return 0;
+}
+
diff --git a/tools/mhmake/src/mhmakefileparser.cpp b/tools/mhmake/src/mhmakefileparser.cpp
new file mode 100644
index 000000000..f281bc7dd
--- /dev/null
+++ b/tools/mhmake/src/mhmakefileparser.cpp
@@ -0,0 +1,1451 @@
+/* This file is part of mhmake.
+ *
+ * Copyright (C) 2001-2010 marha@sourceforge.net
+ *
+ * Mhmake 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Mhmake 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 Mhmake. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* $Rev$ */
+
+#include "stdafx.h"
+#include "util.h"
+#include "md5.h"
+
+#include "mhmakefileparser.h"
+#include "rule.h"
+#include "flexlexer.h"
+
+commandqueue mhmakefileparser::sm_CommandQueue;
+
+///////////////////////////////////////////////////////////////////////////////
+int mhmakefileparser::yylex(void)
+{
+ m_yyloc=m_ptheLexer->lineno();
+ return m_ptheLexer->yylex(m_theTokenValue);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void mhmakefileparser::yyerror(const char *m)
+{
+ cerr << this->m_ptheLexer->m_InputFileName<< " ("<<m_yyloc<<"): "<<m<<endl;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+int mhmakefileparser::ParseFile(const fileinfo *pFileInfo, const fileinfo *pMakeDir)
+{
+ if (pMakeDir)
+ {
+ m_MakeDir=pMakeDir;
+ m_Variables[CURDIR]=m_MakeDir->GetQuotedFullFileName();
+ }
+
+ ifstream yyin(pFileInfo->GetFullFileName().c_str(),ios_base::in);
+ if (yyin.fail())
+ {
+ cerr << "Error opening makefile: "<<pFileInfo->GetQuotedFullFileName()<<endl;
+ return 1;
+ }
+
+ mhmakeFlexLexer theLexer(&yyin);
+ m_ptheLexer=&theLexer;
+ theLexer.m_InputFileName=pFileInfo->GetFullFileName();
+ theLexer.m_pParser=(mhmakeparser*)this;
+ int Ret=yyparse();
+ return Ret;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+bool mhmakefileparser::IsDefined(const string &Var) const
+{
+ bool Ret = m_Variables.find(Var)!=m_Variables.end();
+ if (!Ret)
+ {
+ string Env=GetFromEnv(Var);
+ if (!Env.empty())
+ {
+ Ret=true;
+ }
+ }
+ return Ret;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static inline size_t SkipUntilQuote(const string &Expr,size_t i,char Char)
+{
+ while (Expr[i++]!=Char) ;
+ return i;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static inline size_t SkipMakeExpr(const string &Expr,size_t i)
+{
+ char Char=Expr[i++];
+ if (Char!='(')
+ return i;
+ Char=Expr[i++];
+ while (Char!=')')
+ {
+ if (Char=='$')
+ {
+ i=SkipMakeExpr(Expr,i);
+ }
+#ifdef _DEBUG
+ if (i>=Expr.length())
+ throw(string(") not found in ")+Expr);
+#endif
+ Char=Expr[i++];
+ }
+ return i;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Splits expression on the Item, but the item may not occur within
+// a macro or quoted string
+static pair<string,string> SplitExpr(const string &Expr,char Item)
+{
+ size_t i=0;
+ char Char=Expr[i++];
+ while (Char!=Item)
+ {
+ if (Char=='"' || Char=='\'')
+ {
+ i=SkipUntilQuote(Expr,i,Char);
+ }
+ else if (Char=='$')
+ {
+ i=SkipMakeExpr(Expr,i);
+ }
+ Char=Expr[i++];
+ }
+ return pair<string,string>(Expr.substr(0,i-1),Expr.substr(i));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool mhmakefileparser::IsEqual(const string &EqualExpr) const
+{
+ string Expr=ExpandExpression(EqualExpr);
+ const char *pStr=Expr.c_str();
+ const char *pTmp=pStr;
+ while (*pTmp && *pTmp!=',') pTmp++;
+ ptrdiff_t Pos=pTmp-pStr;
+ size_t Size=Expr.size();
+ pTmp=pStr+Size-1;
+ while (pTmp>pStr && strchr(" \t",*pTmp))
+ {
+ pTmp--;
+ }
+ if (2*Pos != pTmp-pStr)
+ {
+ return false;
+ }
+ pTmp=pStr;
+ const char *pTmp2=pTmp+Pos+1;
+ if (*pTmp=='(')
+ {
+ pTmp++;
+ Pos--;
+ }
+ for (int i=0; i<Pos; i++)
+ {
+ if (pTmp[i]!=pTmp2[i])
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string mhmakefileparser::ExpandExpression(const string &Expr) const
+{
+ bool Recurse;
+ string Ret(Expr);
+ do
+ {
+ Recurse=false;
+ Ret=ExpandExpressionRecurse(Ret,Recurse);
+ }
+ while (Recurse);
+ return Ret;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string mhmakefileparser::ExpandExpressionRecurse(const string &Expr, bool &Recurse) const
+{
+ //((mhmakefileparser*)this)->m_InExpandExpression++;
+ size_t i=0;
+ size_t Length=Expr.size();
+ string Ret;
+ string ToAdd;
+ while (i<Length)
+ {
+ char Char=Expr[i++];
+ if (Char=='$')
+ {
+ char CharNext=Expr[i];
+ if (CharNext=='$')
+ {
+ ToAdd="$";
+ i++;
+ }
+ else
+ {
+ size_t inew=SkipMakeExpr(Expr,i);
+ i++;
+ if (inew>i)
+ {
+ ToAdd=ExpandMacro(Expr.substr(i,inew-i-1),Recurse);
+ i=inew;
+ }
+ else
+ {
+ // This is a single character expression
+ ToAdd=ExpandMacro(string(1,Expr[i-1]),Recurse);
+ }
+ }
+ Ret+=ToAdd;
+ }
+ else
+ {
+ Ret+=Char;
+ }
+ }
+
+ return Ret;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string mhmakefileparser::ExpandMacro(const string &Expr, bool &Recurse) const
+{
+ string ExpandedExpr=ExpandExpressionRecurse(Expr,Recurse);
+
+ const char *pTmp=ExpandedExpr.c_str();
+ /* First remove leading spaces */
+ while (*pTmp==' ' || *pTmp=='\t') pTmp++;
+ const char *pVar=pTmp;
+ while (*pTmp && *pTmp!=' ' && *pTmp!='\t' && *pTmp!=':') pTmp++;
+ const char *pVarEnd=pTmp;
+ char Type=*pTmp++;
+ while (*pTmp && (*pTmp==' ' || *pTmp=='\t')) pTmp++;
+ if (Type&&*pTmp)
+ { // We have a match for the regular expression ^([^ \\t:]+)([: \\t])[ \\t]*(.+)
+ if (Type==':')
+ {
+ #ifdef WIN32
+ bool IsFileName=false;
+ if (pVarEnd-pVar == 1 && (*pVar=='<' || *pVar =='@'))
+ IsFileName=true;
+ #endif
+ string ToSubst=ExpandExpression(ExpandVar(string(pVar,pVarEnd)));
+ const char *pSrc=pTmp;
+ const char *pStop=pSrc;
+ while (*pStop!='=') pStop++;
+ const char *pTo=pStop+1;
+ string SrcStr(pSrc,pStop);
+ string ToStr(pTo);
+ #ifdef WIN32
+ if (IsFileName)
+ {
+ matchres Res;
+ string FileName(UnquoteFileName(ToSubst));
+ if (PercentMatch(FileName,UnquoteFileName(SrcStr),&Res))
+ {
+ FileName=ReplaceWithStem(UnquoteFileName(ToStr),Res.m_Stem);
+ }
+ return QuoteFileName(FileName);
+ }
+ #endif
+ return Substitute(ToSubst,SrcStr,ToStr);
+ }
+ else if (Type==' ' || Type == '\t')
+ {
+ string Func(pVar,pVarEnd);
+ string Arg(pTmp);
+ if (Recurse)
+ {
+ #ifdef _DEBUG
+ if (!(Arg.find('%')!=string::npos && Arg.find('$')!=string::npos))
+ throw(string("Bug in mhmake: expected a % and $ sign: ")+Arg);
+ #endif
+ return string("$(")+ExpandedExpr+")"; // we cannot call the function yet since there is still a $(*%*) macro to resolve. so
+ // return it a a macro again so it can be resolved when the % is resolved
+ // remark that the current test is not completely safe because the % could be out of
+ // the $ macro
+ }
+ function_f pFunc=m_Functions[Func];
+ #ifdef _DEBUG
+ if (pFunc)
+ {
+ return (this->*pFunc)(Arg, &Expr);
+ }
+ else
+ {
+ throw string("Unknown function specified in macro: ")+Func;
+ }
+ #else
+ return (this->*pFunc)(Arg, &Expr);
+ #endif
+ }
+ else
+ {
+ #ifdef _DEBUG
+ throw string("Fatal error in ExpandMacro (bug in mhmake ? ? ?)");
+ #else
+ return g_EmptyString;
+ #endif
+ }
+ }
+ else
+ {
+ if (ExpandedExpr.find('%')!=string::npos)
+ {
+ // we have encountered a *%* macro. This means a previous subst is not yet finished. so return
+ // it back as a macro so it can be expanded again later when the % is replaced
+ Recurse=true;
+ return string("$(")+ExpandedExpr+")";
+ }
+ #ifdef _DEBUG
+ else if (ExpandedExpr.find('$')!=string::npos)
+ throw(string("Bug in mhmake: wasn't expecting a $ sign in: ")+ExpandedExpr);
+ #endif
+ else
+ {
+ return ExpandExpression(ExpandVar(ExpandedExpr));
+ }
+}
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string mhmakefileparser::ExpandVar(const string &Var) const
+{
+ map<string,string>::const_iterator pIt=m_Variables.find(Var);
+ if (pIt==m_Variables.end())
+ {
+ if (Var.size()==1)
+ {
+ char Char=Var[0];
+ if (m_RuleThatIsBuild)
+ {
+ switch (Char)
+ {
+ case '<': // return first prerequisit
+#ifdef _DEBUG
+ if (!m_RuleThatIsBuild->GetDeps().size())
+ {
+ return "<No Dependencies defined.>";
+ }
+#endif
+ return m_RuleThatIsBuild->GetDeps()[0]->GetQuotedFullFileName();
+ case '@': // return full target file name
+ return m_RuleThatIsBuild->GetQuotedFullFileName();
+ case '*': // return stem
+ return m_RuleThatIsBuild->GetRule()->GetStem();
+ case '^': // return all prerequisits
+ return m_RuleThatIsBuild->GetPrerequisits();
+ case '/':
+ return OSPATHSEPSTR;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ switch (Char)
+ {
+ case '<': // return first prerequisit
+ case '@': // return full target file name
+ case '*': // return stem
+ case '^': // return all prerequisits
+ return Var; // To make comparing of rules more accurate
+ case '/':
+ return OSPATHSEPSTR;
+ default:
+ break;
+ }
+ }
+ }
+ string Env=GetFromEnv(Var);
+ if (Env.empty())
+ {
+ #ifdef _DEBUG
+ if (g_PrintAdditionalInfo)
+ {
+ cout<<"Warning: Variable "<<Var<<" not found\n";
+ }
+ #endif
+ return g_EmptyString;
+ }
+ else
+ return Env;
+ }
+ else
+ return pIt->second;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void mhmakefileparser::SplitToItems(const string &String,vector<fileinfo*> &Items) const
+{
+ const char *pTmp=String.c_str();
+ while (*pTmp)
+ {
+ string Item;
+ pTmp=NextItem(pTmp,Item);
+ if (!Item.empty())
+ {
+ Items.push_back(GetFileInfo(Item,m_MakeDir));
+ }
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void mhmakefileparser::ParseBuildedIncludeFiles()
+{
+ vector<string>::iterator It=m_ToBeIncludeAfterBuild.begin();
+ while (It!=m_ToBeIncludeAfterBuild.end())
+ {
+ int result=ParseFile(GetFileInfo(*It,m_MakeDir));
+ if (result)
+ {
+ throw string("Error parsing ")+*It;
+ }
+ It++;
+ }
+}
+
+#ifdef _DEBUG
+///////////////////////////////////////////////////////////////////////////////
+void mhmakefileparser::PrintVariables(bool Expand) const
+{
+ map<string,string>::const_iterator It=m_Variables.begin();
+ while (It!=m_Variables.end())
+ {
+ if (Expand)
+ {
+ try
+ {
+ cout<<It->first<<" : "<<ExpandExpression(It->second)<<endl;
+ }
+ catch (...)
+ {
+ cout<<endl;
+ }
+ }
+ else
+ {
+ cout<<It->first<<" : "<<It->second<<endl;
+ }
+ It++;
+ }
+ if (m_pEnv)
+ {
+ cout << "Environment overruled:\n";
+#ifdef WIN32
+ char *pEnv=m_pEnv;
+ while (*pEnv)
+ {
+ cout<<pEnv<<endl;
+ pEnv+=strlen(pEnv)+1;
+ }
+#else
+ char **pEnv=m_pEnv;
+ while (*pEnv)
+ {
+ cout<<*pEnv<<endl;
+ pEnv++;
+ }
+#endif
+ }
+}
+#endif
+
+//#define PAGETOSTRING(Nr) #Nr
+//#define PAGETONBR(Nr) PAGETOSTRING(##Nr)
+//#pragma message("ar=" PAGETONBR(NULL) ";")
+
+///////////////////////////////////////////////////////////////////////////////
+void mhmakefileparser::AddRule()
+{
+ fileinfoarray::iterator pIt=m_pCurrentItems->begin();
+ while (pIt!=m_pCurrentItems->end())
+ {
+ if ((*pIt)->GetFullFileName().find('%')!=string::npos)
+ {
+ IMPLICITRULE::AddImplicitRule(*pIt,*m_pCurrentDeps,m_pCurrentRule);
+ }
+ else
+ {
+ // If we had a double colon we must make sure that the target is always build
+ if (m_DoubleColonRule)
+ {
+ (*pIt)->SetNotExist();
+ }
+ (*pIt)->SetRuleIfNotExist(m_pCurrentRule);
+ if (!m_pCurrentRule)
+ (*pIt)->AddDeps(*m_pCurrentDeps);
+ else
+ (*pIt)->InsertDeps(*m_pCurrentDeps);
+ if (!m_FirstTarget)
+ { // Only check this if the rule is not an implicit rule
+ m_FirstTarget=(*m_pCurrentItems)[0];
+ }
+ }
+ pIt++;
+ }
+ m_pCurrentItems=NULL;
+ m_pCurrentRule=NullRule;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void mhmakefileparser::GetAutoDeps(const fileinfo *pFirstDep, deps_t &Autodeps)
+{
+ /* Here we have to scan only c/c++ headers so skip certain extensions */
+ const char *pFullName=pFirstDep->GetFullFileName().c_str();
+ const char *pExt=strrchr(pFullName,'.');
+ bool bPython=false;
+ if (pExt)
+ {
+ if (!_stricmp(pExt+1,"py"))
+ bPython=true;
+ }
+
+ FILE *pIn=fopen(pFullName,"r");
+ if (!pIn)
+ return;
+
+ char IncludeList[255];
+ int PrevRet=0;
+ int Ret=fgetc(pIn);
+ while(Ret!=EOF)
+ {
+ char Type[2];
+ bool bFound=false;
+ if (bPython)
+ {
+ Type[0]='"';
+ if (Ret=='i')
+ {
+ Ret=fscanf(pIn,"mport %254[^\"\n]",IncludeList);
+ if (Ret==1)
+ {
+ if (IncludeList[0]!='*')
+ bFound=true;
+ }
+ }
+ }
+ else
+ {
+ if (PrevRet=='/')
+ {
+ if (Ret=='/')
+ {
+ /* This is a C++ command so read until the next line-feed */
+ do
+ {
+ Ret=fgetc(pIn);
+ } while (Ret!='\n' && Ret!=EOF);
+ }
+ else if (Ret=='*')
+ {
+ /* This is a standard C comment, so read until then end of the command */
+ do
+ {
+ PrevRet=Ret;
+ Ret=fgetc(pIn);
+ } while ((PrevRet!='*' || Ret!='/') && Ret!=EOF);
+ }
+ }
+ else if (Ret=='#' || Ret=='.')
+ {
+ if (Ret=='#')
+ {
+ fscanf(pIn,"%*[ \t]");
+ Ret=fscanf(pIn,"include %1[\"<]%254[^>\"]%*[\">]",&Type,IncludeList);
+ }
+ else
+ Ret=fscanf(pIn,"import %1[\"<]%254[^>\"]%*[\">]",&Type,IncludeList);
+ if (Ret==2)
+ {
+ bFound=true;
+ }
+ }
+ }
+ if (bFound)
+ {
+ const char *pTmp=IncludeList;
+ while (*pTmp)
+ {
+ string IncludeFile;
+ pTmp=NextItem(pTmp,IncludeFile," \t,");
+ if (bPython)
+ IncludeFile+=".py";
+
+ if (SkipHeaderFile(IncludeFile))
+ continue;
+ #ifdef _DEBUG
+ m_ImplicitSearch++; // This is to avoid warnings of targets that does not exist
+ #endif
+ if (Type[0]=='"')
+ {
+ fileinfo *pInclude=GetFileInfo(IncludeFile,pFirstDep->GetDir());
+ /* Add the dependency when the file alrady exist or there is a rule available to be build */
+ mh_time_t Date=BuildTarget(pInclude);
+ if (Date.DoesExist()) // Try to build the target, and add it if it exists after building
+ {
+ deps_t::const_iterator pFind=Autodeps.find(pInclude);
+ if (pFind==Autodeps.end())
+ {
+ Autodeps.insert(pInclude);
+ GetAutoDepsIfNeeded(pInclude,pInclude);
+ }
+ }
+ }
+ const refptr<fileinfoarray> IncludeDirs=GetIncludeDirs();
+ fileinfoarray::const_iterator It=IncludeDirs->begin();
+ while (It<IncludeDirs->end())
+ {
+ fileinfo *pInclude=GetFileInfo(IncludeFile,*It);
+ mh_time_t Date=BuildTarget(pInclude);
+ if (Date.DoesExist()) // Try to build the target, and add it if it exists after building
+ {
+ deps_t::const_iterator pFind=Autodeps.find(pInclude);
+ if (pFind==Autodeps.end())
+ {
+ Autodeps.insert(pInclude);
+ GetAutoDepsIfNeeded(pInclude,pInclude);
+ }
+ break;
+ }
+ It++;
+ }
+ #ifdef _DEBUG
+ m_ImplicitSearch--;
+ #endif
+ }
+ }
+ PrevRet=Ret;
+ Ret=fgetc(pIn);
+ }
+ fclose(pIn);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void mhmakefileparser::GetAutoDepsIfNeeded(fileinfo *pTarget, const fileinfo *pFirstDep)
+{
+ autodeps_entry_t &Autodeps=m_AutoDeps[pTarget];
+ if (!Autodeps.first)
+ {
+ Autodeps.first=true;
+ /* We are going to rescan, so throw away the old. */
+ Autodeps.second.clear();
+ GetAutoDeps(pFirstDep,Autodeps.second);
+ // Now add these dependencies also to the rules
+ deps_t::iterator It=Autodeps.second.begin();
+ while (It!=Autodeps.second.end())
+ {
+ pTarget->AddDep(*It);
+ It++;
+ }
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void mhmakefileparser::UpdateAutomaticDependencies(fileinfo *pTarget)
+{
+ if (pTarget->IsAutoDepExtention())
+ {
+ // we have to search for the include files in the first dependency of Target
+ vector<fileinfo*> &Deps=pTarget->GetDeps();
+ if (!Deps.size())
+ return; // There is no first dep
+ fileinfo *pFirstDep=Deps[0];
+ GetAutoDepsIfNeeded(pTarget,pFirstDep);
+ SetAutoDepsDirty();
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void mhmakefileparser::UpdateNoRuleAutomaticDependencies(fileinfo *pTarget)
+{
+ // we have to search for the include files in the Target
+ deps_t Autodeps;
+ GetAutoDeps(pTarget,Autodeps);
+ // Now add these dependencies also to the rules
+ deps_t::iterator It=Autodeps.begin();
+ while (It!=Autodeps.end())
+ {
+ pTarget->AddDep(*It);
+ It++;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+const refptr<fileinfoarray> mhmakefileparser::GetIncludeDirs() const
+{
+ string Includes=ExpandExpression("$(INCLUDES)");
+ if (!m_pIncludeDirs || Includes != m_IncludeDirs)
+ {
+ ((mhmakefileparser*)this)->m_IncludeDirs=Includes;
+ ((mhmakefileparser*)this)->m_pIncludeDirs=refptr<fileinfoarray>(new fileinfoarray);
+ if (Includes.empty()) // If not defined try a default path
+ Includes="include inc .."OSPATHSEPSTR"include .."OSPATHSEPSTR"inc";
+ const char *pTmp=Includes.c_str();
+ while (*pTmp)
+ {
+ string Item;
+ pTmp=NextItem(pTmp,Item);
+ fileinfo *pIncDir=GetFileInfo(Item,m_MakeDir);
+ if (pIncDir->Exists() || pIncDir->GetRule())
+ ((mhmakefileparser*)this)->m_pIncludeDirs->push_back(pIncDir);
+ }
+ }
+ return m_pIncludeDirs;
+}
+
+static void ReadStr(FILE *pFile,char *Str)
+{
+ int i=0;
+ while (1)
+ {
+ Str[i]=fgetc(pFile);
+#ifdef _DEBUG
+ if (Str[i]==EOF)
+ {
+ cout<<"Premature end of depency file.\n";
+ Str[i]=0;
+ return;
+ }
+#endif
+ if (Str[i]=='\n')
+ break;
+ i++;
+ }
+ Str[i]='\0';
+}
+
+void mhmakefileparser::LoadAutoDepsFile(fileinfo *pDepFile)
+{
+ if (m_AutoDepFileLoaded && m_AutoDepFileLoaded==pDepFile)
+ return; /* This autodep file is already loaded. */
+
+ m_AutoDepFileLoaded=pDepFile;
+
+ FILE *pIn=fopen(pDepFile->GetFullFileName().c_str(),"rb");
+#ifdef _DEBUG
+ if (!pIn)
+ {
+ cerr << "Error opening autodep file "<<pDepFile->GetQuotedFullFileName()<<endl;
+ return;
+ }
+#endif
+ fread(&m_EnvMd5_32,sizeof(m_EnvMd5_32),1,pIn);
+#ifdef _DEBUG
+ if (g_PrintAdditionalInfo)
+ cout << "Reading Env Md5 from "<<pDepFile->GetQuotedFullFileName()<<": "<<hex<<m_EnvMd5_32<<endl;
+#endif
+ char UsedEnvVars[1024];
+ ReadStr(pIn,UsedEnvVars);
+ SetVariable(USED_ENVVARS,UsedEnvVars);
+
+ char FileName[MAX_PATH];
+ ReadStr(pIn,FileName);
+ while (FileName[0])
+ {
+ fileinfo *pTarget=GetFileInfo(FileName,m_MakeDir);
+ autodeps_entry_t &Autodeps=m_AutoDeps[pTarget];
+ ReadStr(pIn,FileName);
+ while (FileName[0])
+ {
+ if (!g_ForceAutoDepRescan) /* If we are forcing the autodepscan we do not have to load the dependencies. */
+ {
+ fileinfo *pDep=GetFileInfo(FileName,m_MakeDir);
+ Autodeps.second.insert(pDep);
+ pTarget->AddDep(pDep);
+ }
+ ReadStr(pIn,FileName);
+ }
+ ReadStr(pIn,FileName);
+ }
+
+ uint32 Md5_32;
+ bool MakeNotDirty=true;
+ while (fread(&Md5_32,sizeof(Md5_32),1,pIn))
+ {
+ ReadStr(pIn,FileName);
+
+ fileinfo *pTarget=GetAbsFileInfo(FileName);
+
+ if (!pTarget->CompareMd5_32(0) && !pTarget->CompareMd5_32(Md5_32))
+ {
+ MakeNotDirty=false; /* BuildTarget had set the dirty flag, but since the md5 did not change it was a false dirty. This is for BuildTargets called before this routine */
+ #ifdef _DEBUG
+ cout << "Warning: trying to set to different md5's for Target "<<pTarget->GetQuotedFullFileName()<<" Old: "<<hex<<pTarget->GetCommandsMd5_32()<<" New: "<<Md5_32<<endl;
+ #endif
+ }
+ #ifdef _DEBUG
+ if (g_PrintAdditionalInfo)
+ cout << "Setting Md5 for Target "<<pTarget->GetQuotedFullFileName()<<" to "<<hex<<Md5_32<<endl;
+ #endif
+ pTarget->SetCommandsMd5_32(Md5_32); // If it was already there, just update the md5 value
+
+ AddTarget(pTarget);
+ }
+ if (MakeNotDirty)
+ ClearAutoDepsDirty();
+
+ fclose(pIn);
+}
+
+static void MakeDirs(const fileinfo *pDir)
+{
+ fileinfo *pParentDir=pDir->GetDir();
+ if (!pParentDir->GetDate().DoesExist())
+ { /* First make parent dirs */
+ MakeDirs(pParentDir);
+ }
+ if (!pDir->GetDate().DoesExist())
+ { /* Create directory */
+ mkdir(pDir->GetFullFileName().c_str(),S_IRWXU);
+ }
+}
+
+void mhmakefileparser::SaveAutoDepsFile()
+{
+ if (!IsAutoDepsDirty())
+ return;
+
+ if (g_Clean
+#ifdef _DEBUG
+ || g_DoNotExecute || g_GenProjectTree
+#endif
+ )
+ return; // do not save on clean or if no commands are executed
+
+ string DepFile=ExpandVar(AUTODEPFILE);
+ if (!DepFile.size())
+ {
+ return;
+ }
+ fileinfo *pDepFile=GetFileInfo(DepFile,m_MakeDir);
+
+#ifdef _DEBUG
+ if (g_PrintAdditionalInfo)
+ cout<<"Saving automatic dependency file "<<DepFile<<endl;
+#endif
+
+ FILE *pOut=fopen(pDepFile->GetFullFileName().c_str(),"wb");
+ if (!pOut)
+ {
+ /* Maybe it is because the directory does not exist, so try to create this first */
+ MakeDirs(pDepFile->GetDir());
+ pOut=fopen(pDepFile->GetFullFileName().c_str(),"wb");
+
+ if (!pOut)
+ {
+ #ifdef _DEBUG
+ if (!g_DoNotExecute)
+ #endif
+ cerr << "Error creating file "<<DepFile<<endl;
+ return;
+ }
+ }
+ // First update the USER_ENVVARS variable and then save it to the dep file together with the md5 string
+ CreateUSED_ENVVARS();
+ uint32 Md5_32=CreateEnvMd5_32();
+ fwrite(&Md5_32,sizeof(Md5_32),1,pOut);
+ fprintf(pOut,"%s\n",m_Variables[USED_ENVVARS].c_str());
+
+ autodeps_t::const_iterator It=m_AutoDeps.begin();
+ while (It!=m_AutoDeps.end())
+ {
+ if (!It->second.second.empty())
+ {
+ fprintf(pOut,"%s\n",It->first->GetFullFileName().c_str());
+ deps_t::const_iterator DepIt=It->second.second.begin();
+ while (DepIt!=It->second.second.end())
+ {
+ fprintf(pOut,"%s\n",(*DepIt)->GetFullFileName().c_str());
+ DepIt++;
+ }
+ fprintf(pOut,"\n");
+ }
+ It++;
+ }
+ /* Now save the Md5 strings */
+ fprintf(pOut,"\n");
+
+ set<const fileinfo *>::iterator pIt=m_Targets.begin();
+ while (pIt!=m_Targets.end())
+ {
+ if (!(*pIt)->CompareMd5_32(0))
+ {
+ (*pIt)->WriteMd5_32(pOut);
+ string FileName=(*pIt)->GetFullFileName();
+ fwrite(FileName.c_str(),FileName.size(),1,pOut);
+ fputc('\n',pOut);
+ }
+ pIt++;
+ }
+
+ fclose(pOut);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Uses the SKIPHEADERS variable to check if we have to skip the header in
+// the automatic dependency scanning
+
+bool mhmakefileparser::SkipHeaderFile(const string &FileName)
+{
+ if (!m_SkipHeadersInitialized)
+ {
+ m_SkipHeadersInitialized=true;
+ string HeadersToSkip=ExpandVar(SKIPHEADERS);
+ const char *pTmp=HeadersToSkip.c_str();
+ while (*pTmp)
+ {
+ string Item;
+ pTmp=NextItem(pTmp,Item);
+ if (Item.find('%')==string::npos)
+ {
+ m_SkipHeaders.insert(Item);
+ }
+ else
+ {
+ m_PercentHeaders.push_back(Item);
+ }
+ }
+ }
+ if (m_SkipHeaders.find(FileName)!=m_SkipHeaders.end())
+ return true;
+
+ vector<string>::const_iterator It=m_PercentHeaders.begin();
+ vector<string>::const_iterator ItEnd=m_PercentHeaders.end();
+ while (It!=ItEnd)
+ {
+ if (PercentMatch(FileName,*It++))
+ return true;
+ }
+
+ return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void mhmakefileparser::SetExport(const string &Var, const string &Val)
+{
+ m_Exports.insert(Var);
+#ifdef WIN32
+ if (!m_pEnv)
+ {
+ /* Environment not created yet, so create one */
+ char *pEnv=GetEnvironmentStrings();
+ char *pEnd=pEnv;
+ while (*pEnd)
+ {
+ while (*pEnd++);
+ }
+ size_t Len=pEnd-pEnv+1;
+ m_pEnv=(char*)malloc(Len);
+ memcpy(m_pEnv,pEnv,Len);
+ m_EnvLen=Len;
+ FreeEnvironmentStrings(pEnv);
+ }
+ /* First check if the variable is in the environment, if so remove it first */
+ char *pEnv=m_pEnv;
+ while (*pEnv)
+ {
+ const char *pVar=Var.c_str();
+ char *pStart=pEnv;
+ while (*pEnv!='=' && *pEnv==*pVar)
+ {
+ pEnv++; pVar++;
+ }
+ if (*pEnv=='=' && !*pVar)
+ {
+ /* Variable found, remove it */
+ while (*pEnv++);
+ m_EnvLen-=pEnv-pStart;
+ while (*pEnv)
+ {
+ while (*pEnv)
+ {
+ *pStart=*pEnv++;
+ pStart++;
+ }
+ *pStart=*pEnv++;
+ pStart++;
+ }
+ *pStart=*pEnv;
+ break;
+ }
+ while (*pEnv++);
+ }
+ size_t VarLen=Var.length();
+ size_t ValLen=Val.length();
+ size_t Extra=VarLen+ValLen+2;
+ /* Add the variable at the end */
+ m_pEnv=(char*)realloc(m_pEnv,m_EnvLen+Extra);
+ pEnv=m_pEnv+m_EnvLen-1;
+ memcpy(pEnv,Var.c_str(),VarLen);
+ pEnv+=VarLen;
+ *pEnv++='=';
+ memcpy(pEnv,Val.c_str(),ValLen);
+ pEnv+=ValLen;
+ *pEnv++='\0';
+ *pEnv++='\0';
+ m_EnvLen+=Extra;
+#else
+ if (!m_pEnv)
+ {
+ /* Environment not created yet, so create one */
+ char **pEnv=environ;
+ char **pEnd=pEnv;
+ int Len=1;
+ while (*pEnd)
+ {
+ Len++;
+ pEnd++;
+ }
+ m_EnvLen=Len;
+ m_pEnv=(char**)malloc(Len*sizeof(pEnv));
+ int i=0;
+ while (*pEnv)
+ {
+ m_pEnv[i]=strdup(*pEnv);
+ i++;
+ pEnv++;
+ }
+ m_pEnv[i]=NULL;
+ }
+ /* First check if the variable is in the environment, if so replace it */
+ char **pEnv=m_pEnv;
+ while (*pEnv)
+ {
+ const char *pVar=Var.c_str();
+ char *pStart=*pEnv;
+ char *pTmp=pStart;
+ while (*pTmp!='=' && *pTmp==*pVar)
+ {
+ pTmp++; pVar++;
+ }
+ if (*pTmp=='=' && !*pVar)
+ {
+ free(*pEnv);
+ *pEnv=strdup((Var+"="+Val).c_str());
+ break;
+ }
+ pEnv++;
+ }
+ if (!*pEnv)
+ {
+ // Add it at the end of the list
+ m_pEnv=(char**)realloc(m_pEnv,(m_EnvLen+1)*sizeof(*pEnv));
+ m_pEnv[m_EnvLen-1]=strdup((Var+"="+Val).c_str());
+ m_pEnv[m_EnvLen++]=NULL;
+ }
+
+#endif
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void mhmakefileparser::SetvPath(const string &Pattern, const string &Path)
+{
+ // First create the array of directory from the Path parameter. For now all entries need to
+ // be valid directories (extra checking). This could be improved by checking if there
+ // is a rule for creating the directory entry, but like first said, not for now.
+ refptr<fileinfoarray> pDirArray=new fileinfoarray;
+
+ const char *pTmp=Path.c_str();
+ while (*pTmp)
+ {
+ string Item;
+ pTmp=NextItem(pTmp,Item," \t:;");
+ if (!Item.empty())
+ {
+ fileinfo *pDir=GetFileInfo(Item,m_MakeDir);
+ if (!pDir->IsDir())
+ {
+ #ifdef WIN32
+ // On windows this could happen if a full pathname was specified, so we try together
+ // with the next item to check if this is not a valid directories
+ // but only if the the length of the item was 1 namely the driver letter
+ if (Item.length()==1)
+ {
+ string Rest;
+ pTmp=NextItem(pTmp,Rest," \t:;");
+ pDir=GetFileInfo(Item+":"+Rest,m_MakeDir);
+ #ifdef _DEBUG
+ if (g_PrintAdditionalInfo && !pDir->IsDir())
+ throw(pDir->GetFullFileName()+" is not a valid directory.");
+ #endif
+ }
+ #ifdef _DEBUG
+ else if (g_PrintAdditionalInfo)
+ cout << pDir->GetFullFileName() << " is not a valid directory.\n";
+ #endif
+ #else
+ #ifdef _DEBUG
+ if (g_PrintAdditionalInfo)
+ cout << pDir->GetFullFileName() << " is not a valid directory.\n";
+ #endif
+ #endif
+ }
+ pDirArray->push_back(pDir);
+ }
+ }
+ m_vPath.push_back(pair<string, refptr<fileinfoarray> >(Pattern,pDirArray));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Search for the target using the vPath
+fileinfo* mhmakefileparser::SearchvPath(const fileinfo* pTarget)
+{
+ string TargetName=pTarget->GetName();
+ vector< pair< string, refptr<fileinfoarray> > >::iterator vPathIt=m_vPath.begin();
+ while (vPathIt!=m_vPath.end())
+ {
+ matchres Res;
+
+ if (PercentMatch(TargetName,vPathIt->first,&Res))
+ {
+ fileinfoarray::iterator pIt=vPathIt->second->begin();
+ while (pIt!=vPathIt->second->end())
+ {
+ fileinfo* pNewTarget=GetFileInfo(TargetName,*pIt);
+ mh_time_t TargetDate=StartBuildTarget(pNewTarget,false);
+ if (!TargetDate.IsDateValid())
+ TargetDate=WaitBuildTarget(pNewTarget);
+ if (pNewTarget->GetDate().DoesExist())
+ return pNewTarget;
+ pIt++;
+ }
+ }
+ vPathIt++;
+ }
+ return NULL;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//Checks if the variables retreived from the environment or command-line have been
+//changed. Do this at late as possible because they can also be changed in theLexer
+//makefiles.
+//
+void mhmakefileparser::CheckEnv(void)
+{
+ if (CompareEnv())
+ {
+ #ifdef _DEBUG
+ if (!g_GenProjectTree)
+ cout << "Rebuilding everything of "<< m_MakeDir->GetQuotedFullFileName() <<" because environment and/or command-line variables have been changed.\n";
+ #endif
+ SetRebuildAll();
+ }
+
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//Create a Md5 string from m_GlobalCommandLineVars and USED_ENVVARS
+//
+
+
+static bool SkipVar(const string &Var)
+{
+ if (Var==WC_REVISION)
+ return true;
+ if (Var==WC_URL)
+ return true;
+ if (Var==MAKE)
+ return true;
+ return false;
+}
+
+#define DBGOUT(stuff)
+
+uint32 mhmakefileparser::CreateEnvMd5_32() const
+{
+ md5_context ctx;
+ string Md5;
+ string EnvVars=ExpandVar(USED_ENVVARS);
+ const char *pTmp=EnvVars.c_str();
+
+ // Now create the md5 string
+ md5_starts( &ctx );
+
+ DBGOUT(cout << "MD5 of " << m_MakeDir->GetQuotedFullFileName() << endl);
+
+ while (*pTmp)
+ {
+ string Var;
+ pTmp=NextItem(pTmp,Var,";");
+ if (!SkipVar(Var))
+ {
+ string Val=ExpandVar(Var);
+ transform(Val.begin(),Val.end(),Val.begin(),(int(__CDECL *)(int))toupper);
+ DBGOUT(cout << GetMakeDir()->GetQuotedFullFileName() << " -> Setting GetFromEnv var " << Var << " to " << Val << endl);
+ md5_update( &ctx, (uint8 *) Var.c_str(), (unsigned long)Var.size());
+ md5_update( &ctx, (uint8 *) "=", 1);
+ md5_update( &ctx, (uint8 *) Val.c_str(), (unsigned long)Val.size());
+ }
+ }
+
+ return md5_finish32( &ctx);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Makes sure that the makefile exports are set in the environment
+
+bool mhmakefileparser::CompareEnv() const
+{
+ uint32 Md5_32=CreateEnvMd5_32();
+#ifdef _DEBUG
+ if (!g_GenProjectTree && Md5_32!=m_EnvMd5_32)
+ cout << "Environment has been changed: "<<hex<<m_EnvMd5_32<<" to "<<Md5_32<<endl;
+#endif
+ return Md5_32!=m_EnvMd5_32;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Makes sure that the makefile exports are set in the environment
+mh_time_t mhmakefileparser::m_sBuildTime;
+
+void mhmakefileparser::InitBuildTime()
+{
+ m_sBuildTime=time(NULL);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Returns a variable from the environment or from the command line and adds it the m_UsedEnvVars
+string mhmakefileparser::GetFromEnv(const string &Var, bool Cache) const
+{
+ /* First we look into the command line variables, before we are looking in the environment */
+ map<string,string>::const_iterator pLineFind=m_CommandLineVars.find(Var);
+ if (pLineFind!=m_CommandLineVars.end())
+ {
+ ((mhmakefileparser*)this)->m_UsedEnvVars.insert(Var);
+ if (Cache)
+ ((mhmakefileparser*)this)->m_Variables[Var]=pLineFind->second;
+ return pLineFind->second;
+ }
+
+ const char *pEnv=getenv(Var.c_str());
+ if (!pEnv)
+ {
+ return g_EmptyString;
+ }
+ ((mhmakefileparser*)this)->m_UsedEnvVars.insert(Var);
+
+ if (Cache)
+ ((mhmakefileparser*)this)->m_Variables[Var]=pEnv;
+ return pEnv;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Creates the variable USER_ENVVARS to be saved in the autodeps file
+//
+
+void mhmakefileparser::CreateUSED_ENVVARS()
+{
+
+ set<string> Variables;
+
+ set<string>::const_iterator It=m_UsedEnvVars.begin();
+ set<string>::const_iterator ItEnd=m_UsedEnvVars.end();
+
+ while (It!=ItEnd)
+ {
+ string Var=*It;
+ if (!SkipVar(Var))
+ {
+ transform(Var.begin(),Var.end(),Var.begin(),(int(__CDECL *)(int))toupper);
+ Variables.insert(Var);
+ }
+ It++;
+ }
+
+ It=m_Exports.begin();
+ ItEnd=m_Exports.end();
+
+ while (It!=ItEnd)
+ {
+ string Var=*It;
+ if (!SkipVar(Var))
+ {
+ transform(Var.begin(),Var.end(),Var.begin(),(int(__CDECL *)(int))toupper);
+ Variables.insert(Var);
+ }
+ It++;
+ }
+
+ map<string,string>::const_iterator CLItEnd=loadedmakefile::sm_Statics.m_GlobalCommandLineVars.end();
+ map<string,string>::const_iterator CLIt=loadedmakefile::sm_Statics.m_GlobalCommandLineVars.begin();
+ while (CLIt!=CLItEnd)
+ {
+ string Var=CLIt->first;
+ if (!SkipVar(Var))
+ {
+ transform(Var.begin(),Var.end(),Var.begin(),(int(__CDECL *)(int))toupper);
+ Variables.insert(Var);
+ }
+ CLIt++;
+ }
+
+ It=Variables.begin();
+ ItEnd=Variables.end();
+ string Val;
+ while (It!=ItEnd)
+ {
+ Val+=*It;
+ Val+=";";
+ It++;
+ }
+
+ m_Variables[USED_ENVVARS]=Val;
+}
+
+static string s_TrueString("1");
+static string s_FalseString("0");
+
+static string AndExpression(const string &First, const string &Second)
+{
+ if (First.empty() || First==s_FalseString)
+ {
+ return g_EmptyString;
+ }
+ else
+ {
+ return Second.empty() || Second==s_FalseString ? g_EmptyString : s_TrueString;
+ }
+}
+
+static string OrExpression(const string &First, const string &Second)
+{
+ if (First.empty() || First==s_FalseString)
+ {
+ return Second.empty() || Second==s_FalseString ? g_EmptyString : s_TrueString;
+ }
+ else
+ {
+ return s_TrueString;
+ }
+}
+
+string mhmakefileparser::ResolveExpression(const string &InExpr,string &Rest) const
+{
+ unsigned i=0;
+ string Ret;
+ string Expr=InExpr;
+
+ Rest=g_EmptyString;
+
+ while (i<Expr.length())
+ {
+ while (strchr(" \t\r",Expr[i])) i++;
+ switch (Expr[i])
+ {
+ case '!':
+ if (Expr[i+1]!='=')
+ {
+ Ret=ResolveExpression(Expr.substr(i+1),Expr);
+ Ret = Ret.empty() || Ret==s_FalseString ? s_TrueString : g_EmptyString;
+ i=0;
+ }
+ else
+ {
+ Ret = Ret!=ResolveExpression(Expr.substr(i+2),Expr) ? s_TrueString : g_EmptyString;
+ i=0;
+ }
+ break;
+ case '&':
+ if (Expr[i+1]!='&')
+ {
+ Ret+=Expr[i++];
+ }
+ else
+ {
+ Ret=AndExpression(Ret,ResolveExpression(Expr.substr(i+2),Expr));
+ i=0;
+ }
+ break;
+ case '|':
+ if (Expr[i+1]!='|')
+ {
+ Ret+=Expr[i++];
+ }
+ else
+ {
+ Ret=OrExpression(Ret,ResolveExpression(Expr.substr(i+2),Expr));
+ i=0;
+ }
+ break;
+ case '(':
+ if (Ret=="defined")
+ {
+ Ret=IsDefined(ResolveExpression(Expr.substr(i+1),Expr)) ? s_TrueString : g_EmptyString;
+ }
+ else
+ {
+ Ret+=ResolveExpression(Expr.substr(i+1),Expr);
+ }
+ i=0;
+ break;
+ case ')':
+ Rest=Expr.substr(i+1);
+ return Ret;
+ break;
+ case '"':
+ {
+ i++;
+ while (i<Expr.length())
+ {
+ char Char=Expr[i++];
+ if (Char=='"')
+ break;
+ Ret+=Char;
+ }
+ }
+ break;
+ case '=':
+ if (Expr[i+1]!='=')
+ {
+ Ret+=Expr[i++];
+ }
+ else
+ {
+ Ret = Ret==ResolveExpression(Expr.substr(i+2),Expr) ? s_TrueString : g_EmptyString;
+ i=0;
+ }
+ break;
+ default:
+ Ret+=Expr[i++];
+ break;
+ }
+ }
+ return Ret;
+}
+///////////////////////////////////////////////////////////////////////////////
+bool mhmakefileparser::IsExprTrue(const string &EqualExpr) const
+{
+ string Expr=ExpandExpression(EqualExpr);
+ string Rest;
+ Expr=ResolveExpression(Expr,Rest);
+ if (Expr.empty() || Expr==s_FalseString)
+ return false;
+ else
+ return true;
+}
+
diff --git a/tools/mhmake/src/mhmakefileparser.h b/tools/mhmake/src/mhmakefileparser.h
new file mode 100644
index 000000000..f1c9cb280
--- /dev/null
+++ b/tools/mhmake/src/mhmakefileparser.h
@@ -0,0 +1,383 @@
+/* This file is part of mhmake.
+ *
+ * Copyright (C) 2001-2010 marha@sourceforge.net
+ *
+ * Mhmake 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Mhmake 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 Mhmake. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* $Rev$ */
+
+#ifndef __MHMAKEFILE_PARSER__
+#define __MHMAKEFILE_PARSER__
+
+#include "fileinfo.h"
+#include "util.h"
+#include "commandqueue.h"
+
+class rule;
+
+class mhmakeFlexLexer;
+
+struct TOKENVALUE
+{
+ string theString;
+ int ival;
+};
+
+class mhmakefileparser;
+typedef string (mhmakefileparser::*function_f)(const string &, const string *) const;
+
+struct funcdef
+{
+ const char *szFuncName;
+ function_f pFunc;
+};
+
+class fileinfoarray : public refbase,public vector<fileinfo*>
+{
+};
+
+typedef set<fileinfo*> deps_t;
+typedef pair< bool, deps_t > autodeps_entry_t;
+typedef map<fileinfo*, autodeps_entry_t > autodeps_t;
+
+class mhmakefileparser : public refbase
+{
+
+private:
+ static commandqueue sm_CommandQueue;
+
+ mhmakeFlexLexer *m_ptheLexer;
+ int m_yyloc;
+ fileinfo *m_RuleThatIsBuild;
+ vector<string> m_ToBeIncludeAfterBuild;
+ vector<string> m_MakefilesToLoad;
+ fileinfo* m_AutoDepFileLoaded;
+ mh_time_t m_Date;
+ uint32 m_EnvMd5_32; /* Cached Md5_32 value of the userd environment variables */
+#ifdef _DEBUG
+ int m_ImplicitSearch;
+#endif
+ map<string,string> m_CommandCache;
+
+protected:
+ map<string,string> m_Variables;
+ map<string,string> m_CommandLineVars;
+ TOKENVALUE m_theTokenValue;
+ const fileinfo *m_MakeDir;
+ refptr<rule> m_pCurrentRule;
+ refptr<fileinfoarray> m_pCurrentItems;
+ refptr<fileinfoarray> m_pCurrentDeps;
+ fileinfo* m_FirstTarget;
+ fileinfoarray m_IncludedMakefiles;
+ refptr<fileinfoarray> m_pIncludeDirs;
+ string m_IncludeDirs;
+
+ bool m_DoubleColonRule;
+ bool m_AutoDepsDirty;
+ bool m_ForceAutoDepRescan;
+ set<string> m_SkipHeaders; // Headers to skip
+ vector<string> m_PercentHeaders; // Percent specification of headers to skip
+ bool m_SkipHeadersInitialized; // true when previous 2 variables are initialized
+
+ bool m_RebuildAll; /* true when to rebuild all targets of this makefile */
+
+ set<string> m_UsedEnvVars; // Array containing a list of variables that are taken from the environment (This is used for rebuild checking)
+ set<string> m_Exports; // Array containing a list of exported variables in the makefile (This is used for rebuild checking)
+ vector< pair< string, refptr<fileinfoarray> > > m_vPath;
+#ifdef WIN32
+ char *m_pEnv; // New environment in case the makefile exports variables
+#else
+ char **m_pEnv; // New environment in case the makefile exports variables
+#endif
+ size_t m_EnvLen; // Current length of m_pEnv
+
+ autodeps_t m_AutoDeps;
+ set< const fileinfo* > m_Targets; // List of targets that are build by this makefile
+
+ static mh_time_t m_sBuildTime;
+private:
+ string ResolveExpression(const string &InExpr,string &Rest) const;
+
+public:
+#ifdef _DEBUG
+ deque<fileinfo*> m_TargetStack; /* Used to detect circular dependencies */
+#endif
+
+ mhmakefileparser(const map<string,string> &CommandLineVars)
+ : m_CommandLineVars(CommandLineVars)
+ ,m_AutoDepsDirty(false)
+ ,m_ForceAutoDepRescan(false)
+ ,m_SkipHeadersInitialized(false)
+ ,m_RebuildAll(false)
+ ,m_EnvMd5_32(0)
+ ,m_pEnv(NULL)
+ ,m_FirstTarget(NULL)
+ ,m_RuleThatIsBuild(NULL)
+ ,m_AutoDepFileLoaded(NULL)
+ #ifdef _DEBUG
+ ,m_ImplicitSearch(0)
+ #endif
+ {
+ if (!m_FunctionsInitialised) InitFuncs();
+ SetVariable("MAKE_VERSION",MHMAKEVER);
+ SetVariable(OBJEXTVAR,OBJEXT);
+ SetVariable(EXEEXTVAR,EXEEXT);
+ }
+
+ /* Needed if you only want to use the searchcommand and execommand functions */
+ mhmakefileparser(const fileinfo *pMakeDir) :
+ m_MakeDir(pMakeDir)
+ , m_AutoDepsDirty(false)
+ , m_pEnv(NULL)
+ {}
+
+ static void SetNrParallelBuilds(int NrParallelBuilds)
+ {
+ sm_CommandQueue.SetNrParallelBuilds(NrParallelBuilds);
+ }
+
+ bool CompareEnv() const;
+ uint32 CreateEnvMd5_32() const;
+ string GetFromEnv(const string &Var,bool Cache=true) const;
+ void CreateUSED_ENVVARS();
+
+ void SetExport(const string & Var, const string & Val);
+ void SetvPath(const string & Pattern, const string & Path);
+
+ void CheckEnv(void);
+
+ #ifdef _DEBUG
+ int ImplicitSearch() const
+ {
+ return m_ImplicitSearch;
+ }
+ #endif
+
+ void SetAutoDepsDirty()
+ {
+ m_AutoDepsDirty=true;
+ }
+
+ void ClearAutoDepsDirty()
+ {
+ m_AutoDepsDirty=false;
+ }
+ bool IsAutoDepsDirty() const
+ {
+ return m_AutoDepsDirty;
+ }
+
+ void SetRebuildAll()
+ {
+ m_RebuildAll=true;
+ SetAutoDepsDirty(); /* This is to be sure that all new calculated md5 strings are saved. */
+ }
+
+ void SetVariable(string Var,string Val)
+ {
+ m_Variables[Var]=Val;
+ }
+ void DeleteVariable(string Var)
+ {
+ m_Variables.erase(Var);
+ }
+ void EnableAutoDepRescan(void)
+ {
+ m_ForceAutoDepRescan=true;
+ SetAutoDepsDirty();
+ }
+ bool ForceAutoDepRescan(void)
+ {
+ return m_ForceAutoDepRescan;
+ }
+ void SetRuleThatIsBuild(fileinfo *pTarget)
+ {
+ m_RuleThatIsBuild=pTarget;
+ }
+ void ClearRuleThatIsBuild()
+ {
+ m_RuleThatIsBuild=NULL;
+ }
+ void GetAutoDepsIfNeeded(fileinfo *pTarget, const fileinfo *pFirstDep);
+ void UpdateAutomaticDependencies(fileinfo *pTarget);
+ void UpdateNoRuleAutomaticDependencies(fileinfo *pTarget);
+ const refptr<fileinfoarray> GetIncludeDirs() const;
+ void GetAutoDeps(const fileinfo *pFirstDep, deps_t &Autodeps);
+ void SaveAutoDepsFile();
+ void LoadAutoDepsFile(fileinfo *pDepFile);
+ bool SkipHeaderFile(const string &FileName);
+ void InitEnv() const;
+
+ virtual ~mhmakefileparser() /* virtual to be sure the correct destructor is called when we delete with a pointer to this class which in reality is a pointer to a derived class */
+ {
+ SaveAutoDepsFile();
+#ifndef WIN32
+ char **pEnv=m_pEnv;
+ if (pEnv)
+ while (*pEnv) free(*pEnv++);
+#endif
+ free(m_pEnv);
+ }
+ virtual int yylex(void);
+ virtual void yyerror(const char *m);
+ virtual int yyparse()
+ {
+ throw("Please derive if you want to execute yyparse.");
+ }
+
+ int ParseFile(const fileinfo *pFileInfo,const fileinfo *pMakeDir=NULL);
+
+ /* Functions to handle variables */
+ bool IsDefined(const string &Var) const;
+ bool IsEqual(const string &EqualExpr) const;
+ bool IsExprTrue(const string &EqualExpr) const;
+ string ExpandExpression(const string &Expr) const;
+ string ExpandExpressionRecurse(const string &Expr, bool &Recurse) const;
+ string ExpandMacro(const string &Expr, bool &Recurse) const;
+ string ExpandVar(const string &Var) const;
+
+ void PrintVariables(bool Expand=false) const;
+
+ /* Functions for macro functions */
+ static funcdef m_FunctionsDef[];
+ static map<string,function_f> m_Functions;
+ static bool m_FunctionsInitialised;
+ static void InitFuncs(void);
+ string f_filter(const string &, const string *pOriExpr) const;
+ string f_call(const string &, const string *pOriExpr) const;
+ string f_if(const string &, const string *pOriExpr) const;
+ string f_findstring(const string &, const string *pOriExpr) const;
+ string f_firstword(const string &, const string *pOriExpr) const;
+ string f_wildcard(const string &, const string *pOriExpr) const;
+ string f_subst(const string &, const string *pOriExpr) const;
+ string f_patsubst(const string &, const string *pOriExpr) const;
+ string f_concat(const string &, const string *pOriExpr) const;
+ string f_basename(const string & Arg, const string *pOriExpr) const;
+ string f_notdir(const string & Arg, const string *pOriExpr) const;
+ string f_dir(const string & Arg, const string *pOriExpr) const;
+ string f_shell(const string & Arg, const string *pOriExpr) const;
+ string f_relpath(const string & Arg, const string *pOriExpr) const;
+ string f_toupper(const string & Arg, const string *pOriExpr) const;
+ string f_tolower(const string & Arg, const string *pOriExpr) const;
+ string f_exist(const string & Arg, const string *pOriExpr) const;
+ string f_filesindirs(const string & Arg, const string *pOriExpr) const;
+ string f_fullname(const string & Arg, const string *pOriExpr) const;
+ string f_addprefix(const string & Arg, const string *pOriExpr) const;
+ string f_addsuffix(const string & Arg, const string *pOriExpr) const;
+ string f_filterout(const string & Arg, const string *pOriExpr) const;
+ string f_word(const string & Arg, const string *pOriExpr) const;
+ string f_words(const string & Arg, const string *pOriExpr) const;
+ string f_strip(const string & Arg, const string *pOriExpr) const;
+ string f_which(const string & Arg, const string *pOriExpr) const;
+ string f_foreach(const string & Arg, const string *pOriExpr) const;
+
+ fileinfo* GetFirstTarget() const
+ {
+ return m_FirstTarget;
+ }
+
+ const fileinfo *GetMakeDir() const
+ {
+ return m_MakeDir;
+ }
+
+ mh_time_t GetDate(void) const
+ {
+ return m_Date;
+ }
+
+ void UpdateDate(mh_time_t Date)
+ {
+ if (Date.IsNewer(m_Date))
+ m_Date=Date;
+ }
+
+ void AddTarget(const fileinfo* pTarget)
+ {
+ m_Targets.insert(pTarget);
+ }
+ /* Starts building the target,
+ returns 0 when target build is not finished,
+ returns the date of the target when target is build, especially important for phony rules, since this will be the youngest date of all dependencies */
+ mh_time_t StartBuildTarget(fileinfo* pTarget, bool bCheckTargetDir=true);
+ /* Waits for the target being build, returns the date of the target. Not needed to be cald when StartBuildTarget returned a value different from zero */
+ mh_time_t WaitBuildTarget(fileinfo* pTarget);
+
+ fileinfo* SearchvPath(const fileinfo* pTarget); /* Search for the target using the vPath */
+
+ /* Use the following command when you want to wait for the target is built */
+ mh_time_t BuildTarget(fileinfo* pTarget, bool bCheckTargetDir=true)
+ {
+ mh_time_t TargetDate=StartBuildTarget(pTarget,bCheckTargetDir);
+ if (!TargetDate.IsDateValid())
+ TargetDate=WaitBuildTarget(pTarget);
+ return TargetDate;
+ }
+
+ void BuildDependencies(const refptr<rule> &pRule, fileinfo* pTarget, mh_time_t TargetDate, mh_time_t &YoungestDate, bool &MakeTarget);
+
+ void BuildIncludedMakefiles();
+
+ void AddIncludedMakefile(fileinfo* pMakeInfo)
+ {
+ UpdateDate(pMakeInfo->GetDate());
+ m_IncludedMakefiles.push_back(pMakeInfo);
+ }
+ fileinfoarray &GetIncludedMakefiles()
+ {
+ return m_IncludedMakefiles;
+ }
+
+ void IncludeAfterBuild(const string &IncludeFile)
+ {
+ m_ToBeIncludeAfterBuild.push_back(IncludeFile);
+ }
+ void ParseBuildedIncludeFiles();
+
+ void AddMakefileToMakefilesToLoad(const string &Makefile)
+ {
+ m_MakefilesToLoad.push_back(Makefile);
+ }
+ vector<string>& GetMakefilesToLoad()
+ {
+ return m_MakefilesToLoad;
+ }
+ void AddRule();
+
+ mh_pid_t ExecuteCommand(string Command, bool &IgnoreError, string *pOutput=NULL);
+ mh_pid_t ExecuteCommand(string Command, string *pOutput=NULL)
+ {
+ bool IgnoreError;
+ return ExecuteCommand(Command, IgnoreError, pOutput);
+ }
+ string GetFullCommand(string Command);
+ void CreatePythonExe(const string &FullCommand);
+
+ static void InitBuildTime();
+
+ void SplitToItems(const string &String, vector<fileinfo*> &Items) const;
+ mh_pid_t DeleteFiles(const string &Params) const;
+ mh_pid_t CopyFiles(const string &Params) const;
+ mh_pid_t TouchFiles(const string &Params) const;
+ mh_pid_t EchoCommand(const string &Params) const;
+ string SearchCommand(const string &Command, const string &Extension="") const;
+ const string &GetPythonExe() const;
+ int SearchPath(const char *szCommand, const char *pExt, size_t Len, char *szFullCommand,char **pFilePart) const;
+ mh_pid_t OsExeCommand(const string &Command, const string &Params, bool IgnoreError, string *pOutput) const;
+};
+
+
+#endif
+
diff --git a/tools/mhmake/src/mhmakelexer.l b/tools/mhmake/src/mhmakelexer.l
new file mode 100644
index 000000000..8cf0f1680
--- /dev/null
+++ b/tools/mhmake/src/mhmakelexer.l
@@ -0,0 +1,987 @@
+/* This file is part of mhmake.
+ *
+ * Copyright (C) 2001-2010 marha@sourceforge.net
+ *
+ * Mhmake 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Mhmake 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 Mhmake. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* $Rev$ */
+
+/* -------------- declaration section -------------- */
+%{
+
+#include "fileinfo.h"
+#include "rule.h"
+#include "util.h"
+
+static uint32 LoadMakMd5(fileinfo *pTarget)
+{
+ string FileName=pTarget->GetFullFileName();
+ FileName+=".md5_32";
+ FILE *pFile=fopen(FileName.c_str(),"rb");
+ if (!pFile)
+ return 0;
+ uint32 Md5_32=0;
+ fread(&Md5_32,sizeof(Md5_32),1,pFile);
+ fclose(pFile);
+ pTarget->SetCommandsMd5_32(Md5_32);
+ return Md5_32;
+}
+
+static void SaveMakMd5(fileinfo *pTarget)
+{
+ string FileName=pTarget->GetFullFileName();
+ FileName+=".md5_32";
+ FILE *pFile=fopen(FileName.c_str(),"wb");
+ if (!pFile)
+ {
+ throw string("Error creating file ")+FileName;
+ }
+ pTarget->WriteMd5_32(pFile);
+ fclose(pFile);
+}
+
+static void ReplaceCurlyBraces(string &String)
+{
+ int Pos=String.find_first_of('{',0);
+ if (Pos!=string::npos)
+ {
+ /* if not { found, } will not be there eather (or it is a valid syntax, so it may generate an error) */
+ do
+ {
+ String.replace(Pos,1,1,'(');
+ Pos=String.find_first_of('{',Pos);
+ }
+ while (Pos!=string::npos);
+ Pos=0;
+ while ((Pos=String.find_first_of('}',Pos))!=string::npos)
+ String.replace(Pos,1,1,')');
+ }
+}
+
+#define YY_DECL int mhmakeFlexLexer::yylex(TOKENVALUE &theValue)
+
+%}
+
+%option prefix="mhmake"
+%option never-interactive
+%option 8bit
+%option c++
+%option full
+%option noyywrap
+%option warn
+
+/* -------------- rules section -------------- */
+%x INCLUDE IFDEF IF IFNDEF SKIPUNTILELSEORENDIF QUOTE MAKEEXPRES SINGLEQUOTE COMMANDPARSE
+%x IFEQ IFNEQ ERRORMACRO MESSAGEMACRO REPARSEMACRO LOAD_MAKEFILE
+%x DEFINE
+
+%%
+
+ /*---------------------------------------------------------------------------*/
+[ \t\r]*\n[ ][ \t]* {
+ yy_set_bol(1); // Make sure the next rule also matches the ^
+ yylineno++;
+ return mhmakeparser::NEWLINE;
+}
+
+[ \t\r]*\n {
+ PRINTF(("%s %d: NEWLINE:\n",m_InputFileName.c_str(),yylineno));
+ yylineno++;
+ return mhmakeparser::NEWLINE;
+}
+
+ /*---------------------------------------------------------------------------*/
+^[s\-]?include {
+ PRINTF(("%s %d: INCLUDE: ",m_InputFileName.c_str(),yylineno));
+ BEGIN(INCLUDE);
+ unsigned i=0;
+ while (strchr(" \t",yytext[i])) i++;
+ if (strchr("-s",yytext[i]))
+ m_IgnoreIncludeError=true;
+ else
+ m_IgnoreIncludeError=false;
+ return mhmakeparser::INCLUDEMAK; // Return a newline to be sure that the previous line is completely parse by yacc (in case it is a variable definition)
+}
+
+ /*****************************************************************************/
+<INCLUDE>[ \t]* /* eat the whitespace */
+ /*---------------------------------------------------------------------------*/
+<INCLUDE>[^\r\n]+ { /* got the include file name */
+ mhmakeparser *pParser=GetParser();
+
+ /* replace the {} by () before expanding */
+ string IncludeFileNames(yytext);
+ ReplaceCurlyBraces(IncludeFileNames);
+ IncludeFileNames=pParser->ExpandExpression(IncludeFileNames);
+ PRINTF(("%s -> %s\n",yytext,IncludeFileNames.c_str()));
+
+ const char *pTmp=IncludeFileNames.c_str();
+ while (*pTmp)
+ {
+ string IncludeFileName;
+ pTmp=NextItem(pTmp,IncludeFileName);
+ if (!IncludeFileName.empty())
+ {
+ PRINTF(("%s -> %s\n",yytext,IncludeFileName.c_str()));
+ fileinfo *pInclude=GetFileInfo(IncludeFileName,pParser->GetMakeDir());
+ /* Already build the include file, in case we already have a rule for it. */
+ if (pInclude->GetRule())
+ {
+ uint32 Md5_32=LoadMakMd5(pInclude);
+ pParser->BuildTarget(pInclude);
+ if (!pInclude->CompareMd5_32(Md5_32))
+ SaveMakMd5(pInclude);
+ }
+
+ pParser->AddIncludedMakefile(pInclude);
+
+ string strToInclude=pInclude->GetFullFileName();
+ INSTACK *pStackElem=new INSTACK(YY_CURRENT_BUFFER, strToInclude, m_InputFileName, yylineno);
+ if ( pStackElem->fail() )
+ {
+ delete pStackElem;
+ if (!m_IgnoreIncludeError)
+ {
+ mystack::reverse_iterator StackIt=m_IncludeStack.rbegin();
+ while (StackIt!=m_IncludeStack.rend())
+ {
+ cout<<" in "<<(*StackIt)->m_FileName<<" ("<<(*StackIt)->yylineno<<")";
+ StackIt++;
+ }
+ cout<<endl;
+ cout<<"Warning error opening file "<<strToInclude<<" in "<<m_InputFileName<<" ("<<yylineno<<")\n";
+ pParser->IncludeAfterBuild(strToInclude);
+ }
+ else
+ pInclude->SetPhony(); /* To be sure that no message is printed when mhmake is trying to build the file later */
+ }
+ else
+ {
+ m_IncludeStack.push(pStackElem);
+ yylineno=1;
+
+ m_InputFileName=strToInclude;
+
+ yypush_buffer_state(yy_create_buffer( pStackElem->GetStream(), YY_BUF_SIZE ));
+ yyrestart(pStackElem->GetStream());
+ }
+
+ }
+ }
+
+ BEGIN(INITIAL);
+}
+
+ /*---------------------------------------------------------------------------*/
+load_makefile {
+ PRINTF(("%s %d: LOAD_MAKEFILE:\n",m_InputFileName.c_str(),yylineno));
+ BEGIN(LOAD_MAKEFILE);
+ return mhmakeparser::NEWLINE; // Return a newline to be sure that the previous line is completely parse by yacc (in case it is a variable definition)
+}
+
+ /*****************************************************************************/
+<LOAD_MAKEFILE>[^\r\n]+ {
+ string ListOfMakefiles((const char*)yytext);
+ ReplaceCurlyBraces(ListOfMakefiles);
+ ListOfMakefiles=GetParser()->ExpandExpression(ListOfMakefiles);
+ PRINTF(("%s %d: LOAD_MAKEFILE: '%s'\n",m_InputFileName.c_str(),yylineno,ListOfMakefiles.c_str()));
+
+ const char *pTmp=ListOfMakefiles.c_str();
+ while (*pTmp)
+ {
+ string Item;
+ pTmp=NextCharItem(pTmp,Item,';');
+ if (Item.empty())
+ {
+ throw m_InputFileName + "(" + stringify(yylineno) + "): Error in load_makefile statement";
+ }
+ GetParser()->AddMakefileToMakefilesToLoad(Item);
+ }
+
+}
+ /*---------------------------------------------------------------------------*/
+<LOAD_MAKEFILE>\r?\n {
+ yylineno++;
+ BEGIN(INITIAL);
+ return mhmakeparser::NEWLINE;
+}
+
+ /*---------------------------------------------------------------------------*/
+[ \t]+ {
+ PRINTF(("%s %d: SPACE:\n",m_InputFileName.c_str(),yylineno));
+ return mhmakeparser::SPACE;
+}
+
+ /*---------------------------------------------------------------------------*/
+[ \t]*=[ \t]*\\[ \t\r]*\n[ \t]* {
+ PRINTF(("%s %d: EQUAL: %s\n",m_InputFileName.c_str(),yylineno,yytext));
+ yylineno++;
+ theValue.theString=(const char *)yytext;
+ return mhmakeparser::EQUAL;
+}
+
+[ \t]*=[ \t]* {
+ PRINTF(("%s %d: EQUAL: %s\n",m_InputFileName.c_str(),yylineno,yytext));
+ theValue.theString=(const char *)yytext;
+ return mhmakeparser::EQUAL;
+}
+
+ /*---------------------------------------------------------------------------*/
+[ \t]*:=[ \t]*\\[ \t\r]*\n[ \t]* {
+ yylineno++;
+ PRINTF(("%s %d: IMEQUAL: %s\n",m_InputFileName.c_str(),yylineno,yytext));
+ return mhmakeparser::IMEQUAL;
+}
+
+[ \t]*:=[ \t]* {
+ PRINTF(("%s %d: IMEQUAL: %s\n",m_InputFileName.c_str(),yylineno,yytext));
+ return mhmakeparser::IMEQUAL;
+}
+
+ /*---------------------------------------------------------------------------*/
+[ \t]*\?=[ \t]*\\[ \t\r]*\n[ \t]* {
+ yylineno++;
+ PRINTF(("%s %d: OPTEQUAL: %s\n",m_InputFileName.c_str(),yylineno,yytext));
+ return mhmakeparser::OPTEQUAL;
+}
+
+[ \t]*\?=[ \t]* {
+ PRINTF(("%s %d: OPTEQUAL: %s\n",m_InputFileName.c_str(),yylineno,yytext));
+ return mhmakeparser::OPTEQUAL;
+}
+
+ /*---------------------------------------------------------------------------*/
+[ \t]*\+=[ \t]*\\[ \t\r]*\n[ \t]* {
+ PRINTF(("%s %d: PEQUAL: %s\n",m_InputFileName.c_str(),yylineno,yytext));
+ yylineno++;
+ return mhmakeparser::PEQUAL;
+}
+
+[ \t]*\+=[ \t]* {
+ PRINTF(("%s %d: PEQUAL: %s\n",m_InputFileName.c_str(),yylineno,yytext));
+ return mhmakeparser::PEQUAL;
+}
+
+ /*---------------------------------------------------------------------------*/
+[ \t]*;[ \t]*\\[ \t\r]*\n[ \t]* {
+ PRINTF(("%s %d: -SEMICOLON (NEWLINE): %s\n",m_InputFileName.c_str(),yylineno,yytext));
+ m_curtoken=g_EmptyString;
+ yylineno++;
+ BEGIN(COMMANDPARSE);
+ return mhmakeparser::NEWLINE;
+}
+
+[ \t]*;[ \t]* {
+ PRINTF(("%s %d: -SEMICOLON (NEWLINE): %s\n",m_InputFileName.c_str(),yylineno,yytext));
+ m_curtoken=g_EmptyString;
+ BEGIN(COMMANDPARSE);
+ return mhmakeparser::NEWLINE;
+}
+
+ /*---------------------------------------------------------------------------*/
+[ \t]*::[ \t]*\\[ \t\r]*\n[ \t]* {
+ PRINTF(("%s %d: DOUBLECOLON: %s\n",m_InputFileName.c_str(),yylineno,yytext));
+ yylineno++;
+ theValue.theString=(const char *)yytext;
+ return mhmakeparser::DOUBLECOLON;
+}
+
+[ \t]*::[ \t]* {
+ PRINTF(("%s %d: DOUBLECOLON: %s\n",m_InputFileName.c_str(),yylineno,yytext));
+ theValue.theString=(const char *)yytext;
+ return mhmakeparser::DOUBLECOLON;
+}
+
+ /*---------------------------------------------------------------------------*/
+[ \t]*:[ \t]*\\[ \t\r]*\n[ \t]* {
+ PRINTF(("%s %d: COLON: %s\n",m_InputFileName.c_str(),yylineno,yytext));
+ yylineno++;
+ theValue.theString=(const char *)yytext;
+ return mhmakeparser::COLON;
+}
+
+[ \t]*:[ \t]* {
+ PRINTF(("%s %d: COLON: %s\n",m_InputFileName.c_str(),yylineno,yytext));
+ theValue.theString=(const char *)yytext;
+ return mhmakeparser::COLON;
+}
+
+ /*---------------------------------------------------------------------------*/
+, {
+ PRINTF(("%s %d: COMMA: %s\n",m_InputFileName.c_str(),yylineno,yytext));
+ theValue.theString=(const char *)yytext;
+ return mhmakeparser::COMMA;
+}
+
+ /*---------------------------------------------------------------------------*/
+^endif {
+ if (m_IndentStack.size())
+ {
+ m_IndentStack.pop();
+ PRINTF(("%s %d: %s: depth %d\n",m_InputFileName.c_str(),yylineno,yytext,m_IndentStack.size()));
+ }
+ else
+ {
+ throw string("Unexpected endif at line ") + stringify(yylineno) + " of " + m_InputFileName;
+ }
+}
+
+ /*---------------------------------------------------------------------------*/
+^ifdef[ \t]*\\[ \t\r]*\n[ \t]* {
+ BEGIN(IFDEF);
+ yylineno++;
+ return mhmakeparser::NEWLINE;
+}
+
+^ifdef[ \t]+ {
+ BEGIN(IFDEF);
+ return mhmakeparser::NEWLINE;
+}
+
+ /*---------------------------------------------------------------------------*/
+^if[ \t]*\\[ \t\r]*\n[ \t]* {
+ BEGIN(IF);
+ yylineno++;
+ m_curtoken=g_EmptyString;
+ return mhmakeparser::NEWLINE;
+}
+
+^if[ \t]+ {
+ BEGIN(IF);
+ m_curtoken=g_EmptyString;
+ return mhmakeparser::NEWLINE;
+}
+
+ /*---------------------------------------------------------------------------*/
+^ifndef[ \t]*\\[ \t\r]*\n[ \t]* {
+ BEGIN(IFNDEF);
+ yylineno++;
+ return mhmakeparser::NEWLINE;
+}
+
+^ifndef[ \t]+ {
+ BEGIN(IFNDEF);
+ return mhmakeparser::NEWLINE;
+}
+
+ /*---------------------------------------------------------------------------*/
+^ifeq[ \t]*\\[ \t\r]*\n[ \t]* {
+ BEGIN(IFEQ);
+ m_curtoken=g_EmptyString;
+ yylineno++;
+ return mhmakeparser::NEWLINE;
+}
+
+^ifeq[ \t]+ {
+ BEGIN(IFEQ);
+ m_curtoken=g_EmptyString;
+ return mhmakeparser::NEWLINE;
+}
+
+ /*---------------------------------------------------------------------------*/
+^ifneq[ \t]*\\[ \t\r]*\n[ \t]* {
+ BEGIN(IFNEQ);
+ m_curtoken=g_EmptyString;
+ yylineno++;
+ return mhmakeparser::NEWLINE;
+}
+
+^ifneq[ \t]+ {
+ BEGIN(IFNEQ);
+ m_curtoken=g_EmptyString;
+ return mhmakeparser::NEWLINE;
+}
+
+ /*---------------------------------------------------------------------------*/
+^else[ \t]* {
+ if (m_IndentStack.size() && (!m_IndentStack.top()))
+ {
+ PRINTF(("%s %d: skipping else: depth %d\n",m_InputFileName.c_str(),yylineno,m_IndentStack.size()));
+ m_IndentSkip=m_IndentStack.size();
+ m_IndentStack.top()=1;
+ BEGIN(SKIPUNTILELSEORENDIF);
+ }
+ else
+ {
+ throw string("Unexpected else at line ") + stringify(yylineno) + " of file " + m_InputFileName;
+ }
+}
+
+ /*****************************************************************************/
+<IFEQ>\n {
+ yyless(0);
+ m_IndentStack.push(0);
+ if (GetParser()->IsEqual(m_curtoken))
+ {
+ PRINTF(("%s %d: Not Skipping ifeq %s: depth %d\n",m_InputFileName.c_str(),yylineno,m_curtoken.c_str(),m_IndentStack.size()));
+ BEGIN(INITIAL);
+ }
+ else
+ {
+ PRINTF(("%s %d: Skipping ifeq %s: depth %d\n",m_InputFileName.c_str(),yylineno,m_curtoken.c_str(),m_IndentStack.size()));
+ m_IndentSkip=m_IndentStack.size();
+ BEGIN(SKIPUNTILELSEORENDIF);
+ }
+}
+
+<IF,IFEQ,IFNEQ>[ \t]*\\[ \t\r]*\n[ \t]* { yylineno++; m_curtoken += g_SpaceString;}
+
+<IF,IFEQ,IFNEQ>\r /* skip */
+
+<IF,IFEQ,IFNEQ>[^\\\r\n{}\$]+ |
+<IF,IFEQ,IFNEQ>\$ |
+<IF,IFEQ,IFNEQ>\\ { m_curtoken += (const char *)yytext; }
+
+ /*****************************************************************************/
+<IFNEQ>\n {
+ yyless(0);
+ m_IndentStack.push(0);
+ if (!GetParser()->IsEqual(m_curtoken))
+ {
+ PRINTF(("%s %d: Not Skipping ifneq %s: depth %d\n",m_InputFileName.c_str(),yylineno,m_curtoken.c_str(),m_IndentStack.size()));
+ BEGIN(INITIAL);
+ }
+ else
+ {
+ PRINTF(("%s %d: Skipping ifneq %s: depth %d\n",m_InputFileName.c_str(),yylineno,m_curtoken.c_str(),m_IndentStack.size()));
+ m_IndentSkip=m_IndentStack.size();
+ BEGIN(SKIPUNTILELSEORENDIF);
+ }
+}
+
+ /*****************************************************************************/
+<IF>[ \t\r]*[a-zA-Z0-9_]+[ \t\r]*\n {
+ yyless(yyleng-1);
+ m_IndentStack.push(0);
+#ifndef WIN32
+ int lastidx=yyleng-1;
+ if (yytext[lastidx]=='\r')
+ yytext[lastidx]='\0';
+#endif
+ string Val=GetParser()->ExpandVar((const char *)yytext);
+ if (Val.empty() || Val=="0")
+ {
+ PRINTF(("%s %d: Skipping if %s: depth %d\n",m_InputFileName.c_str(),yylineno,yytext,m_IndentStack.size()));
+ m_IndentSkip=m_IndentStack.size();
+ BEGIN(SKIPUNTILELSEORENDIF);
+ }
+ else
+ {
+ PRINTF(("%s %d: Not Skipping if %s: depth %d\n",m_InputFileName.c_str(),yylineno,yytext,m_IndentStack.size()));
+ BEGIN(INITIAL);
+ }
+}
+
+ /*---------------------------------------------------------------------------*/
+<IF>\n {
+ yyless(0);
+ m_IndentStack.push(0);
+ if (GetParser()->IsExprTrue(m_curtoken))
+ {
+ PRINTF(("%s %d: Not Skipping ifeq %s: depth %d\n",m_InputFileName.c_str(),yylineno,m_curtoken.c_str(),m_IndentStack.size()));
+ BEGIN(INITIAL);
+ }
+ else
+ {
+ PRINTF(("%s %d: Skipping ifeq %s: depth %d\n",m_InputFileName.c_str(),yylineno,m_curtoken.c_str(),m_IndentStack.size()));
+ m_IndentSkip=m_IndentStack.size();
+ BEGIN(SKIPUNTILELSEORENDIF);
+ }
+}
+
+ /*****************************************************************************/
+<IFDEF,IFNDEF>[ \t\r]* /* skip */
+
+ /*---------------------------------------------------------------------------*/
+<IFDEF>[a-zA-Z0-9_]+ {
+ m_IndentStack.push(0);
+ if (GetParser()->IsDefined((const char *)yytext))
+ {
+ PRINTF(("%s %d: Not Skipping ifdef %s: depth %d\n",m_InputFileName.c_str(),yylineno,yytext,m_IndentStack.size()));
+ BEGIN(INITIAL);
+ }
+ else
+ {
+ PRINTF(("%s %d: Skipping ifdef %s: depth %d\n",m_InputFileName.c_str(),yylineno,yytext,m_IndentStack.size()));
+ m_IndentSkip=m_IndentStack.size();
+ BEGIN(SKIPUNTILELSEORENDIF);
+ }
+}
+
+ /*****************************************************************************/
+<IFNDEF>[a-zA-Z0-9_]+ {
+ m_IndentStack.push(0);
+ if (!GetParser()->IsDefined((const char *)yytext)) {
+ PRINTF(("%s %d: Not Skipping ifndef %s: depth %d\n",m_InputFileName.c_str(),yylineno,yytext,m_IndentStack.size()));
+ BEGIN(INITIAL);
+ }
+ else
+ {
+ PRINTF(("%s %d: Skipping ifndef %s: depth %d\n",m_InputFileName.c_str(),yylineno,yytext,m_IndentStack.size()));
+ m_IndentSkip=m_IndentStack.size();
+ BEGIN(SKIPUNTILELSEORENDIF);
+ }
+}
+
+ /*****************************************************************************/
+<SKIPUNTILELSEORENDIF>\n[ ]*endif {
+ yylineno++;
+ if (!m_IndentStack.size())
+ {
+ throw string("Unexpected endif at line ") + stringify(yylineno) + " of " + m_InputFileName;
+ }
+ else
+ {
+ m_IndentStack.pop();
+ PRINTF(("%s %d: endif: depth %d\n",m_InputFileName.c_str(),yylineno,m_IndentStack.size()));
+ if (m_IndentStack.size()==m_IndentSkip-1) BEGIN(INITIAL);
+ }
+}
+
+ /*---------------------------------------------------------------------------*/
+<SKIPUNTILELSEORENDIF>\n[ ]*else {
+ yylineno++;
+ PRINTF(("%s %d: else: depth %d\n",m_InputFileName.c_str(),yylineno,m_IndentStack.size()));
+ if (m_IndentStack.top())
+ {
+ throw string("Unexpected else at line ") + stringify(yylineno) + " of file " + m_InputFileName;
+ }
+ m_IndentStack.top()=1;
+ if (m_IndentStack.size()==m_IndentSkip)
+ {
+ BEGIN(INITIAL);
+ }
+}
+
+ /*---------------------------------------------------------------------------*/
+<SKIPUNTILELSEORENDIF>\n[ ]*if(def|ndef|eq|neq)? {
+ yylineno++;
+ m_IndentStack.push(0);
+ PRINTF(("%s %d: %s: depth %d\n",m_InputFileName.c_str(),yylineno,yytext+1,m_IndentStack.size()));
+}
+
+ /*---------------------------------------------------------------------------*/
+<SKIPUNTILELSEORENDIF>[a-zA-Z]+ /* skip */
+ /*---------------------------------------------------------------------------*/
+<SKIPUNTILELSEORENDIF>[^a-zA-Z\n]+ /* skip */
+ /*---------------------------------------------------------------------------*/
+<SKIPUNTILELSEORENDIF>\n[ ]*[a-zA-Z]+ yylineno++;
+ /*---------------------------------------------------------------------------*/
+<SKIPUNTILELSEORENDIF>\n {
+ yylineno++;
+}
+
+ /*---------------------------------------------------------------------------*/
+[ \t]*#[^\n]* {
+ PRINTF(("%s %d: -COMMENT: %s\n",m_InputFileName.c_str(),yylineno,yytext));
+}
+
+ /*---------------------------------------------------------------------------*/
+[ \t]*\\[ \t\r]*\n[ \t]* {
+ PRINTF(("%s %d: SPACE:\n",m_InputFileName.c_str(),yylineno));
+ yylineno++;
+ return mhmakeparser::SPACE;
+}
+
+ /*---------------------------------------------------------------------------*/
+\.PHONY {
+ PRINTF(("%s %d: .PHONY: %s\n",m_InputFileName.c_str(),yylineno,yytext));
+ return mhmakeparser::PHONY;
+}
+
+ /*---------------------------------------------------------------------------*/
+\.AUTODEPS {
+ PRINTF(("%s %d: .AUTODEPS: %s\n",m_InputFileName.c_str(),yylineno,yytext));
+ return mhmakeparser::AUTODEPS;
+}
+
+ /*---------------------------------------------------------------------------*/
+export {
+ PRINTF(("%s %d: export: %s\n",m_InputFileName.c_str(),yylineno,yytext));
+ return mhmakeparser::EXPORT;
+}
+
+ /*---------------------------------------------------------------------------*/
+^vpath {
+ PRINTF(("%s %d: vpath\n",m_InputFileName.c_str(),yylineno));
+ return mhmakeparser::VPATH;
+}
+
+ /*---------------------------------------------------------------------------*/
+[a-zA-Z]:[a-zA-Z0-9\\\._\~\-%\@<&/]+\\[ \t\r]*\n {
+ size_t EndIndex=yyleng;
+ while (strchr(" \t\r\n\\",yytext[--EndIndex]));
+ yyless(EndIndex+1);
+
+ PRINTF(("%s %d: STRING: %s\n",m_InputFileName.c_str(),yylineno,yytext));
+ theValue.theString=(const char *)yytext;
+ return mhmakeparser::STRING;
+}
+
+[a-zA-Z]:[a-zA-Z0-9\\\._\~\-%\@<&/]+ {
+ PRINTF(("%s %d: STRING: %s\n",m_InputFileName.c_str(),yylineno,yytext));
+ theValue.theString=(const char *)yytext;
+ return mhmakeparser::STRING;
+}
+
+ /*---------------------------------------------------------------------------*/
+([a-zA-Z0-9\\\._\~\-\+%\@<&;/\*\|]|\\\ |\\#)+\\[ \t\r]*\n {
+ size_t EndIndex=yyleng;
+ while (strchr(" \t\r\n\\",yytext[--EndIndex]));
+ yyless(EndIndex+1);
+
+ PRINTF(("%s %d: STRING: %s\n",m_InputFileName.c_str(),yylineno,yytext));
+ theValue.theString=(const char *)yytext;
+ return mhmakeparser::STRING;
+}
+
+([a-zA-Z0-9\\\._\~\-\+%\@<&;/\*\|]|\\\ |\\#)+\+= {
+ PRINTF(("%s %d: STRING: %s\n",m_InputFileName.c_str(),yylineno,yytext));
+ yyless(yyleng-2);
+ theValue.theString=(const char *)yytext;
+ return mhmakeparser::STRING;
+}
+
+([a-zA-Z0-9\\\._\~\-\+%\@<&;/\*\|]|\\\ |\\#)+ {
+ PRINTF(("%s %d: STRING: %s\n",m_InputFileName.c_str(),yylineno,yytext));
+ theValue.theString=(const char *)yytext;
+ return mhmakeparser::STRING;
+}
+
+^define[ \t]+[a-zA-Z0-9_\.]+[ \t]*\n {
+ const char *pVar=(const char *)yytext;
+ while (strchr(" \t",*pVar)) pVar++;
+ pVar+=6;
+ theValue.theString=pVar;
+ BEGIN(DEFINE);
+ m_curtoken=g_EmptyString;
+ PRINTF(("%s %d: VARDEF: %s\n",m_InputFileName.c_str(),yylineno,m_curtoken.c_str()));
+ yylineno++;
+ return mhmakeparser::VARDEF;
+}
+
+<DEFINE>[ \t]*\\[ \t\r]*\n[ \t]* {
+ yylineno++;
+ m_curtoken+=g_SpaceString;
+}
+
+<DEFINE>. {
+ m_curtoken+=(const char *)yytext;
+}
+
+<DEFINE>[ \t]*\n[ \t]*endef {
+ yylineno++;
+ theValue.theString=m_curtoken;
+ PRINTF(("%s %d: VARVAL: %s\n",m_InputFileName.c_str(),yylineno,m_curtoken.c_str()));
+ BEGIN(INITIAL);
+ return mhmakeparser::VARVAL;
+}
+
+ /*---------------------------------------------------------------------------*/
+\" {
+ BEGIN(QUOTE);
+ yymore();
+}
+
+ /*---------------------------------------------------------------------------*/
+\' {
+ BEGIN(SINGLEQUOTE);
+ yymore();
+}
+
+ /*---------------------------------------------------------------------------*/
+\$\( {
+ m_BraceIndent++;
+ PRINTF(("%s %d: BEGIN MACRO $(: %d\n",m_InputFileName.c_str(),yylineno,m_BraceIndent));
+ BEGIN(MAKEEXPRES);
+ m_curtoken=(const char *)yytext;
+}
+
+ /*---------------------------------------------------------------------------*/
+\$\([ \t]*error[ \t]+ {
+ m_BraceIndent++;
+ PRINTF(("%s %d: BEGIN ERROR MACRO $(: %d\n",m_InputFileName.c_str(),yylineno,m_BraceIndent));
+ BEGIN(ERRORMACRO);
+ m_curtoken=g_EmptyString;
+ return mhmakeparser::NEWLINE; // Make sure that the previous lines are matched by the bison parser (so that all variables until here are defined)
+}
+
+ /*---------------------------------------------------------------------------*/
+\$\([ \t]*(message|info)[ \t]+ {
+ m_BraceIndent++;
+ PRINTF(("%s %d: BEGIN MESSAGE MACRO $(: %d\n",m_InputFileName.c_str(),yylineno,m_BraceIndent));
+ BEGIN(MESSAGEMACRO);
+ m_curtoken=g_EmptyString;
+ return mhmakeparser::NEWLINE; // Make sure that the previous lines are matched by the bison parser (so that all variables until here are defined)
+}
+
+ /*---------------------------------------------------------------------------*/
+\$\([ \t]*reparse[ \t]+ {
+ m_BraceIndent++;
+ PRINTF(("%s %d: BEGIN REPARSE MACRO $(: %d\n",m_InputFileName.c_str(),yylineno,m_BraceIndent));
+ BEGIN(REPARSEMACRO);
+ m_curtoken=g_EmptyString;
+ return mhmakeparser::NEWLINE;
+}
+
+ /*---------------------------------------------------------------------------*/
+\( {
+ PRINTF(("%s %d: OPENBRACE: %s\n",m_InputFileName.c_str(),yylineno,yytext));
+ return mhmakeparser::OPENBRACE;
+}
+
+ /*---------------------------------------------------------------------------*/
+\) {
+ PRINTF(("%s %d: CLOSEBRACE: %s\n",m_InputFileName.c_str(),yylineno,yytext));
+ return mhmakeparser::CLOSEBRACE;
+}
+
+ /*---------------------------------------------------------------------------*/
+\$[<@/$] {
+ PRINTF(("%s %d: DOLLAREXPR: %s\n",m_InputFileName.c_str(),yylineno,yytext));
+ theValue.theString=(const char *)yytext;
+ return mhmakeparser::DOLLAREXPR;
+}
+
+ /*---------------------------------------------------------------------------*/
+[ \t\r]*\n\t[ \t]* {
+ /* token newline */
+ PRINTF(("%s %d: NEWLINE\n",m_InputFileName.c_str(),yylineno));
+ yylineno++;
+ m_curtoken=g_EmptyString;
+ BEGIN(COMMANDPARSE);
+ return mhmakeparser::NEWLINE;
+}
+
+ /*---------------------------------------------------------------------------*/
+<*>\$\{ {
+ unput('(');
+ unput('$');
+}
+ /*---------------------------------------------------------------------------*/
+<*>\} {
+ unput(')');
+}
+
+ /*---------------------------------------------------------------------------*/
+[^\n] {
+ PRINTF(("%s %d: ANYCHAR: %d: %s\n",m_InputFileName.c_str(),yylineno,yylineno,yytext));
+}
+
+ /*****************************************************************************/
+
+<COMMANDPARSE>[ \t\r]*\n {
+ PRINTF(("%s %d: COMMAND: %d: %s\n",m_InputFileName.c_str(),yylineno,yylineno,m_curtoken.c_str()));
+ theValue.theString=m_curtoken;
+ yylineno++;
+ BEGIN(INITIAL);
+ return mhmakeparser::COMMAND;
+}
+
+ /*---------------------------------------------------------------------------*/
+<COMMANDPARSE>[ \t\r]*\n\t[ \t]* {
+ PRINTF(("%s %d: COMMAND: %s\n",m_InputFileName.c_str(),yylineno,m_curtoken.c_str()));
+ theValue.theString=m_curtoken;
+ yylineno++;
+ m_curtoken=g_EmptyString;
+ return mhmakeparser::COMMAND;
+}
+
+ /*---------------------------------------------------------------------------*/
+<COMMANDPARSE>[ \t]*\\[ \t\r]*\n[ \t]* {
+ yylineno++;
+ m_curtoken+=g_SpaceString;
+}
+
+ /*---------------------------------------------------------------------------*/
+<COMMANDPARSE>[ ]+ {
+ m_curtoken+=g_SpaceString;
+}
+
+ /*---------------------------------------------------------------------------*/
+<COMMANDPARSE>[^ \r\n#\\{}$]+ |
+<COMMANDPARSE>\$ |
+<COMMANDPARSE>\\ {
+ m_curtoken+=(const char *)yytext;
+}
+
+ /*---------------------------------------------------------------------------*/
+<COMMANDPARSE>[ \t]*\\#[^\n]* {
+ int nChars=(int)((strchr((const char *)yytext,'#')-(char*)yytext))+1;
+ yyless(nChars);
+ m_curtoken+=string(yytext,nChars-2);
+ m_curtoken+='#';
+}
+
+ /*---------------------------------------------------------------------------*/
+<COMMANDPARSE>[ \t]*#[^\n]* {
+ PRINTF(("%s %d: -COMMENT: %s\n",m_InputFileName.c_str(),yylineno,yytext));
+}
+
+ /*****************************************************************************/
+<QUOTE>\" {
+ PRINTF(("%s %d: QUOTEDSTRING: %s\n",m_InputFileName.c_str(),yylineno,yytext));
+ BEGIN(INITIAL);
+ theValue.theString=(const char *)yytext;
+ return mhmakeparser::STRING;
+}
+
+ /*---------------------------------------------------------------------------*/
+<QUOTE>\r /* skip */
+
+<QUOTE>[^\\\"\r\n{}$]+ |
+<QUOTE>\$ |
+<QUOTE>\\ |
+<QUOTE>\\\" |
+<QUOTE>\\# {
+ yymore();
+}
+
+ /*****************************************************************************/
+<SINGLEQUOTE>\' {
+ PRINTF(("%s %d: QUOTEDSTRING: %s\n",m_InputFileName.c_str(),yylineno,yytext));
+ BEGIN(INITIAL);
+ theValue.theString=(const char *)yytext;
+ return mhmakeparser::STRING;
+}
+
+ /*---------------------------------------------------------------------------*/
+<SINGLEQUOTE>\r /* skip */
+
+<SINGLEQUOTE>[^\\\'\r\n{}$]+ |
+<SINGLEQUOTE>\$ |
+<SINGLEQUOTE>\\ |
+<SINGLEQUOTE>\\\' |
+<SINGLEQUOTE>\\# {
+ yymore();
+}
+
+ /*****************************************************************************/
+<ERRORMACRO>\) {
+ m_BraceIndent--;
+ PRINTF(("%s %d: CLOSE BRACE ERROR MACRO ): %d\n",m_InputFileName.c_str(),yylineno,m_BraceIndent));
+ if (!m_BraceIndent)
+ {
+ PRINTF(("%s %d: ERRORMACRO: %s\n",m_InputFileName.c_str(),yylineno,m_curtoken.c_str()));
+ throw string("\n-> ")+m_InputFileName.c_str()+"("+stringify(yylineno)+") : "+GetParser()->ExpandExpression(m_curtoken);
+ } else {
+ m_curtoken+=(const char *)yytext;
+}
+}
+
+ /*****************************************************************************/
+<MESSAGEMACRO>\) {
+ m_BraceIndent--;
+ PRINTF(("%s %d: CLOSE BRACE MESSAGE MACRO ): %d\n",m_InputFileName.c_str(),yylineno,m_BraceIndent));
+ if (!m_BraceIndent)
+ {
+ PRINTF(("%s %d: MESSAGEMACRO: %s\n",m_InputFileName.c_str(),yylineno,yytext));
+ cerr<<m_InputFileName.c_str()<<"("<<stringify(yylineno)+") : "<<GetParser()->ExpandExpression(m_curtoken)<<endl;
+ BEGIN(INITIAL);
+ } else {
+ m_curtoken+=(const char *)yytext;
+ }
+}
+
+ /*****************************************************************************/
+<REPARSEMACRO>\) {
+ m_BraceIndent--;
+ PRINTF(("%s %d: CLOSE BRACE REPARSE MACRO ): %d\n",m_InputFileName.c_str(),yylineno,m_BraceIndent));
+ if (!m_BraceIndent)
+ {
+ PRINTF(("%s %d: REPARSEMACRO: %s\n",m_InputFileName.c_str(),yylineno,yytext));
+ string Deps=GetParser()->ExpandExpression(m_curtoken);
+ PRINTF(("%s %d: REPARSEMACRO expanded: %s\n",m_InputFileName.c_str(),yylineno,Deps.c_str()));
+ string::const_reverse_iterator It=Deps.rbegin()+1; // +1 because we don't want the latest brace
+ string::const_reverse_iterator ItBeg=Deps.rend();
+ while (It!= ItBeg)
+ {
+ char Char=*It++;
+ if (Char==';') Char='\n';
+ unput(Char);
+ }
+ BEGIN(INITIAL);
+ }
+ else
+ {
+ m_curtoken+=(const char *)yytext;
+ }
+}
+
+ /*****************************************************************************/
+<MAKEEXPRES>\) {
+ m_BraceIndent--;
+ PRINTF(("%s %d: CLOSE BRACE MAKEEXPRES MACRO ): %d\n",m_InputFileName.c_str(),yylineno,m_BraceIndent));
+ if (!m_BraceIndent)
+ {
+ BEGIN(INITIAL);
+ m_curtoken+=(const char *)yytext;
+ theValue.theString=m_curtoken;
+ PRINTF(("%s %d: DOLLAREXPR: %s\n",m_InputFileName.c_str(),yylineno,m_curtoken.c_str()));
+ return mhmakeparser::DOLLAREXPR;
+ }
+ else
+ {
+ m_curtoken+=(const char *)yytext;
+ }
+}
+
+ /*---------------------------------------------------------------------------*/
+<MAKEEXPRES,ERRORMACRO,MESSAGEMACRO,REPARSEMACRO>\$\( {
+ m_BraceIndent++;
+ PRINTF(("%s %d: MACRO extra $(: %d\n",m_InputFileName.c_str(),yylineno,m_BraceIndent));
+ m_curtoken+=(const char *)yytext;
+}
+
+ /*---------------------------------------------------------------------------*/
+<MAKEEXPRES,ERRORMACRO,MESSAGEMACRO,REPARSEMACRO>[^$\(\){}\r\n\\]+ |
+<MAKEEXPRES,ERRORMACRO,MESSAGEMACRO,REPARSEMACRO>\$ |
+<MAKEEXPRES,ERRORMACRO,MESSAGEMACRO,REPARSEMACRO>\\ |
+<MAKEEXPRES,ERRORMACRO,MESSAGEMACRO,REPARSEMACRO>\( {
+ m_curtoken+=(const char *)yytext;
+}
+<MAKEEXPRES,ERRORMACRO,MESSAGEMACRO,REPARSEMACRO>[ \t\r]*\\[ \t\r]*\n[ \t\r]* {
+ yylineno++;
+ m_curtoken+=g_SpaceString;
+}
+
+<SKIPUNTILELSEORENDIF><<EOF>> {
+ throw string("Missing endif or else statement. #else or #endif used?");
+}
+
+<<EOF>> {
+ if (m_BraceIndent)
+ {
+ throw string("Missing closing ) of macro usage in ") + m_InputFileName;
+ }
+ if (!m_IncludeStack.size())
+ {
+ if (m_IndentStack.size())
+ {
+ throw string("Missing endif or else statement in ") + m_InputFileName + ". #else or #endif used";
+ }
+ yyterminate();
+ }
+ else
+ {
+ INSTACK *pInStack=m_IncludeStack.top();
+ yypop_buffer_state();
+ m_InputFileName=pInStack->m_FileName;
+ yylineno=pInStack->yylineno;
+ m_IncludeStack.pop();
+ }
+}
+%%
+
diff --git a/tools/mhmake/src/mhmakeparser.y b/tools/mhmake/src/mhmakeparser.y
new file mode 100644
index 000000000..515caf6e5
--- /dev/null
+++ b/tools/mhmake/src/mhmakeparser.y
@@ -0,0 +1,255 @@
+/* This file is part of mhmake.
+ *
+ * Copyright (C) 2001-2010 marha@sourceforge.net
+ *
+ * Mhmake 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Mhmake 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 Mhmake. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* $Rev$ */
+
+/* -------------- declaration section -------------- */
+
+%name mhmakeparser
+
+%define LLOC m_yyloc
+%define LTYPE int // This is the type of LLOC (defined in mhmakefileparser)
+
+%define LVAL m_theTokenValue
+%define STYPE TOKENVALUE // This is the type of LVAL (defined in mhmakefileparser)
+
+%define INHERIT : public mhmakefileparser
+
+%define CONSTRUCTOR_PARAM const map<string,string> &CommandLineVariables
+%define CONSTRUCTOR_INIT : mhmakefileparser(CommandLineVariables)
+
+%header{
+#include "mhmakefileparser.h"
+#include "rule.h"
+#include "util.h"
+%}
+
+%token <theString> COMMAND
+%token <theString> COMMA OPENBRACE CLOSEBRACE
+%token <theString> STRING DOLLAREXPR EQUAL COLON DOUBLECOLON VARDEF VARVAL
+%token IMEQUAL PEQUAL OPTEQUAL PHONY AUTODEPS EXPORT NEWLINE INCLUDEMAK SPACE VPATH
+
+%type <theString> expression nonspaceexpression simpleexpression
+%type <theString> maybeemptyexpression
+%type <theString> expression_nocolorequal simpleexpression_nocolorequal nonspaceexpression_nocolorequal
+%type <ival> rulecolon
+
+%start file
+
+/* -------------- rules section -------------- */
+/* Sample parser. Does count Chars in a line, and lines in file */
+%%
+file : statements
+ {
+ if (m_pCurrentItems)
+ {
+ PRINTF(("Adding rule : %s\n",(*m_pCurrentItems)[0]->GetQuotedFullFileName().c_str()));
+ AddRule();
+ }
+ }
+;
+
+statements :
+ | statements statement
+;
+
+statement: NEWLINE |
+ SPACE |
+ includemak |
+ ruledef |
+ phonyrule |
+ autodepsrule |
+ varassignment |
+ imvarassignment |
+ pvarassignment |
+ optvarassignment |
+ exportrule |
+ vpathrule |
+ COMMAND
+ {
+ if (!m_pCurrentRule)
+ {
+ m_pCurrentRule=refptr<rule>(new rule(this));
+ }
+ m_pCurrentRule->AddCommand($1);
+ PRINTF(("Adding command : %s\n",$1.c_str()));
+ }
+;
+
+includemak:
+ {
+ if (m_pCurrentItems)
+ {
+ PRINTF(("Adding rule : %s\n",(*m_pCurrentItems)[0]->GetQuotedFullFileName().c_str()));
+ AddRule();
+ }
+ } INCLUDEMAK
+;
+
+ruledef: expression_nocolorequal rulecolon maybeemptyexpression
+ {
+ if (m_pCurrentItems)
+ {
+ PRINTF(("Adding rule : %s\n",(*m_pCurrentItems)[0]->GetQuotedFullFileName().c_str()));
+ AddRule();
+ }
+
+ m_pCurrentItems=new fileinfoarray;
+ m_pCurrentDeps=new fileinfoarray;
+ #ifdef _DEBUG
+ if (!ExpandExpression($1).size())
+ {
+ throw string("Empty left hand side in rule: ") + $1 + " : " + $3;
+ }
+ #endif
+ SplitToItems(ExpandExpression($1),*m_pCurrentItems);
+ SplitToItems(ExpandExpression($3),*m_pCurrentDeps);
+ m_DoubleColonRule= ($2==1) ;
+ PRINTF(("Defining rule %s : %s\n",$1.c_str(),$3.c_str()));
+ PRINTF((" Expanded to %s : %s\n",ExpandExpression($1).c_str(),ExpandExpression($3).c_str()));
+ }
+;
+
+rulecolon: COLON {$$=0;} |
+ DOUBLECOLON {$$=1;}
+;
+
+phonyrule: PHONY COLON expression
+ {
+ vector<fileinfo*> Items;
+ SplitToItems(ExpandExpression($3),Items);
+ vector<fileinfo*>::iterator pIt=Items.begin();
+ while (pIt!=Items.end())
+ {
+ (*pIt)->SetPhony();
+ pIt++;
+ }
+ PRINTF(("Defining phony rule : %s\n",$3.c_str()));
+ PRINTF((" Expanded to : %s\n",ExpandExpression($3).c_str()));
+ }
+ NEWLINE
+;
+
+autodepsrule: AUTODEPS COLON expression
+ {
+ vector<fileinfo*> Items;
+ SplitToItems(ExpandExpression($3),Items);
+ vector<fileinfo*>::iterator pIt=Items.begin();
+ while (pIt!=Items.end())
+ {
+ (*pIt)->SetAutoDepsScan(this);
+ pIt++;
+ }
+ PRINTF(("Defining autodeps rule : %s\n",$3.c_str()));
+ PRINTF((" Expanded to : %s\n",ExpandExpression($3).c_str()));
+ }
+ NEWLINE
+;
+
+exportrule: EXPORT SPACE exportstrings NEWLINE
+;
+
+exportstrings : exportstring |
+ exportstring SPACE exportstrings
+;
+
+exportstring : STRING
+ {
+ SetExport($1,ExpandExpression(ExpandVar($1)));
+ PRINTF(("Exporting %s : %s\n",$1.c_str(),ExpandExpression(ExpandVar($1)).c_str()));
+ }
+;
+
+vpathrule: VPATH SPACE nonspaceexpression SPACE expression NEWLINE
+ {
+ SetvPath(ExpandExpression($3),ExpandExpression($5));
+ PRINTF(("Setting vpath %s to %s\n",$3.c_str(),ExpandExpression($5).c_str()));
+ }
+;
+
+varassignment: VARDEF VARVAL
+ {
+ m_Variables[f_strip($1,NULL)]=$2;
+ PRINTF(("Defining variable %s to %s\n",f_strip($1,NULL).c_str(), $2.c_str()));
+ }
+ | STRING EQUAL maybeemptyexpression
+ {
+ m_Variables[$1]=$3;
+ PRINTF(("Setting variable %s to %s\n",$1.c_str(), $3.c_str()));
+ }
+;
+
+imvarassignment: STRING IMEQUAL maybeemptyexpression
+ {
+ m_Variables[$1]=ExpandExpression($3);
+ PRINTF(("Setting variable %s to %s\n",$1.c_str(), m_Variables[$1].c_str()));
+ }
+;
+
+pvarassignment: STRING PEQUAL maybeemptyexpression
+ {
+ m_Variables[$1]=m_Variables[$1]+g_SpaceString+$3;
+ PRINTF(("Adding to variable %s: %s\n",$1.c_str(), $3.c_str()));
+ }
+;
+
+optvarassignment: STRING OPTEQUAL maybeemptyexpression
+ {
+ if (!IsDefined($1))
+ {
+ m_Variables[$1]=$3;
+ PRINTF(("Setting variable %s to %s\n",$1.c_str(), $3.c_str()));
+ }
+ }
+;
+
+maybeemptyexpression: NEWLINE {$$=g_EmptyString;} |
+ expression NEWLINE |
+ expression SPACE NEWLINE
+;
+
+expression: nonspaceexpression |
+ expression SPACE nonspaceexpression {$$=$1+g_SpaceString+$3;}
+;
+
+expression_nocolorequal: nonspaceexpression_nocolorequal |
+ expression_nocolorequal SPACE nonspaceexpression_nocolorequal {$$=$1+g_SpaceString+$3;}
+;
+
+nonspaceexpression: simpleexpression |
+ nonspaceexpression simpleexpression {$$=$1+$2;}
+;
+
+nonspaceexpression_nocolorequal: simpleexpression_nocolorequal |
+ nonspaceexpression_nocolorequal simpleexpression_nocolorequal {$$=$1+$2;}
+;
+
+simpleexpression: simpleexpression_nocolorequal |
+ EQUAL |
+ COLON |
+ DOUBLECOLON |
+ COMMA
+;
+
+simpleexpression_nocolorequal: STRING {$$=$1;} |
+ DOLLAREXPR {$$=$1;}
+;
+
+%%
+/* -------------- body section -------------- */
+
diff --git a/tools/mhmake/src/refptr.h b/tools/mhmake/src/refptr.h
new file mode 100644
index 000000000..7223090f9
--- /dev/null
+++ b/tools/mhmake/src/refptr.h
@@ -0,0 +1,124 @@
+/* This file is part of mhmake.
+ *
+ * Copyright (C) 2001-2010 marha@sourceforge.net
+ *
+ * Mhmake 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Mhmake 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 Mhmake. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* $Rev$ */
+
+#ifndef __REFPTR_H__
+#define __REFPTR_H__
+
+#ifdef _DEBUG
+#define PRINTF(arg) if (g_PrintLexYacc) printf arg
+#else
+#define PRINTF(arg)
+#endif
+
+template <class T> class iterstack: public stack<T>
+{
+ public:
+ typedef typename deque<T>::iterator iterator;
+ typedef typename deque<T>::reverse_iterator reverse_iterator;
+
+ iterator begin()
+ {
+ return stack<T>::c.begin();
+ }
+ iterator end()
+ {
+ return stack<T>::c.end();
+ }
+ reverse_iterator rbegin()
+ {
+ return stack<T>::c.rbegin();
+ }
+ reverse_iterator rend()
+ {
+ return stack<T>::c.rend();
+ }
+};
+
+struct refbase
+{
+ int m_Count;
+ refbase()
+ {
+ m_Count=1;
+ }
+};
+
+// Template class T needs to be derived from refbase;
+template <class T> class refptr
+{
+ T *m_RefPtr;
+public:
+ refptr()
+ {
+ m_RefPtr=NULL;
+ }
+ refptr(T *Ptr) {
+ m_RefPtr=Ptr;
+ }
+ refptr(const refptr<T> &RefPtr)
+ {
+ m_RefPtr=RefPtr.m_RefPtr;
+ if (m_RefPtr)
+ m_RefPtr->m_Count++;
+ }
+ ~refptr()
+ {
+ if (m_RefPtr && !--m_RefPtr->m_Count)
+ {
+ delete m_RefPtr;
+ }
+ }
+ refptr<T> &operator=(const refptr<T>& Src)
+ {
+ if (Src.m_RefPtr!=m_RefPtr)
+ {
+ this->~refptr();
+ new (this) refptr<T>(Src);
+ }
+ return *this;
+ }
+
+ refptr<T> &operator=(T *pPtr) // Assumes that T has reference count 1 and has no other users
+ {
+ #if defined(_DEBUG) && defined(_MSC_VER)
+ if (pPtr && pPtr->m_Count!=1)
+ DebugBreak();
+ #endif
+ this->~refptr();
+ m_RefPtr=pPtr;
+ return *this;
+ }
+
+ T & operator*() const
+ {
+ return *m_RefPtr;
+ }
+ T * operator->() const
+ {
+ return m_RefPtr;
+ }
+ operator T*() const
+ {
+ return m_RefPtr;
+ }
+};
+
+#endif
+
diff --git a/tools/mhmake/src/rule.cpp b/tools/mhmake/src/rule.cpp
new file mode 100644
index 000000000..0beb29c39
--- /dev/null
+++ b/tools/mhmake/src/rule.cpp
@@ -0,0 +1,301 @@
+/* This file is part of mhmake.
+ *
+ * Copyright (C) 2001-2010 marha@sourceforge.net
+ *
+ * Mhmake 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Mhmake 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 Mhmake. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* $Rev$ */
+
+#include "stdafx.h"
+
+#include "fileinfo.h"
+#include "rule.h"
+#include "util.h"
+#include "mhmakeparser.h"
+
+refptr<rule> NullRule;
+
+set<rule*> IMPLICITRULE::m_ImplicitRuleRecurseDetStack;
+vector<implicitrule_t> IMPLICITRULE::m_ImplicitRules;
+
+makecommand g_MakeCommand; // Order is important since sm_Statics is using g_MakeCommand
+const string g_QuoteString("\""); // Order is important since sm_Statics is using g_QuoteString
+loadedmakefile::loadedmakefile_statics loadedmakefile::sm_Statics;
+
+///////////////////////////////////////////////////////////////////////////////
+static bool FindDep(fileinfo *pTarget, implicitruledep_t *pImplicitRule,refptr<rule> &Rule)
+{
+ implicitruledep_t::iterator SecIt=pImplicitRule->begin();
+ while (SecIt!=pImplicitRule->end())
+ {
+ if (SecIt->first.empty())
+ {
+ #ifdef _DEBUG
+ // Check if the rule has the same commands
+ vector<string> &OldCommands=SecIt->second->GetCommands();
+ vector<string> &NewCommands=Rule->GetCommands();
+
+ bool bCommandsDifferent=OldCommands.size()!=NewCommands.size();
+ if (g_PrintMultipleDefinedRules || bCommandsDifferent)
+ {
+ string ErrorMessage;
+ if (bCommandsDifferent)
+ ErrorMessage += "Implicit Rule '"+ pTarget->GetFullFileName() + "' defined twice with different commands\n";
+ else
+ ErrorMessage += "Implicit Rule '"+ pTarget->GetFullFileName() + "' defined twice with same commands\n";
+ ErrorMessage += "Command 1: makedir = " + SecIt->second->GetMakefile()->GetMakeDir()->GetQuotedFullFileName()+ "\n";
+
+ vector<string>::const_iterator It;
+ if (bCommandsDifferent)
+ {
+ It=OldCommands.begin();
+ while (It!=OldCommands.end())
+ {
+ ErrorMessage += " " + *It + "\n";
+ }
+ }
+ cerr << "Command 2: makedir = "+ Rule->GetMakefile()->GetMakeDir()->GetQuotedFullFileName()+ "\n";
+ if (bCommandsDifferent)
+ {
+ It=NewCommands.begin();
+ while (It!=NewCommands.end())
+ {
+ ErrorMessage += " " + *It + "\n";
+ }
+ throw ErrorMessage;
+ }
+ else
+ cerr << ErrorMessage << endl;
+ }
+ mhmakefileparser *pOldMakefile=SecIt->second->GetMakefile();
+ mhmakefileparser *pNewMakefile=Rule->GetMakefile();
+ vector<string>::iterator OldIt=OldCommands.begin();
+ vector<string>::iterator NewIt=NewCommands.begin();
+ while (OldIt!=OldCommands.end())
+ {
+ if (pOldMakefile->ExpandExpression(*OldIt)!=pNewMakefile->ExpandExpression(*NewIt))
+ {
+ string ErrorMessage = string("Implicit Rule '") + pTarget->GetFullFileName() + "' defined twice with different commands\n";
+ ErrorMessage += "Command 1: makedir = " + pOldMakefile->GetMakeDir()->GetQuotedFullFileName()+ "\n";
+ ErrorMessage += " " + pOldMakefile->ExpandExpression(*OldIt) + "\n";
+ ErrorMessage += "Command 2: makedir = " + pNewMakefile->GetMakeDir()->GetQuotedFullFileName()+ "\n";
+ ErrorMessage += " " + pNewMakefile->ExpandExpression(*NewIt);
+ throw ErrorMessage;
+ }
+ OldIt++;
+ NewIt++;
+ }
+ #endif
+ return true;
+ }
+ SecIt++;
+ }
+ return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void IMPLICITRULE::AddImplicitRule(fileinfo *pTarget,const vector<fileinfo*> &Deps,refptr<rule> Rule)
+{
+ if (!Rule)
+ {
+ #ifdef _DEBUG
+ if (g_PrintAdditionalInfo)
+ cout << "No commands defined for implicit rule " << pTarget->GetFullFileName()<<endl;
+ #endif
+ return;
+ }
+ // first search if there is already the same target in the current list of implicit rules
+ implicitruledep_t* pImplicitRule=NULL;
+ vector<implicitrule_t>::iterator RuleIt=m_ImplicitRules.begin();
+ while (RuleIt!=m_ImplicitRules.end())
+ {
+ if (pTarget==RuleIt->first)
+ {
+ pImplicitRule=&(RuleIt->second);
+ }
+ RuleIt++;
+ }
+ if (!pImplicitRule)
+ {
+ // Add a new entry
+ m_ImplicitRules.push_back(implicitrule_t(pTarget,implicitruledep_t()));
+ pImplicitRule=&((m_ImplicitRules.end()-1)->second);
+ }
+
+ if (Deps.size())
+ {
+ #ifdef _DEBUG
+ vector<fileinfo*>::const_iterator DepIt=Deps.begin();
+ while (DepIt!=Deps.end())
+ {
+ if (*DepIt==pTarget)
+ throw(string("Implicit rule : ")+pTarget->GetFullFileName()+" is directly dependent on itself. This is not allowed.");
+ DepIt++;
+ }
+ #endif
+ pImplicitRule->push_back(pair<vector<fileinfo*>,refptr<rule> >(Deps,Rule));
+ }
+ else
+ {
+ if (!FindDep(pTarget,pImplicitRule,Rule))
+ pImplicitRule->push_back(pair<vector<fileinfo*>, refptr<rule> >(vector<fileinfo*>(), Rule));
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void IMPLICITRULE::SearchImplicitRule(const fileinfo *pTarget, implicitruledep_t &Result)
+{
+ string TargetFileName=pTarget->GetFullFileName();
+
+ vector<implicitrule_t>::iterator ImpRegExIt=m_ImplicitRules.begin();
+ while (ImpRegExIt!=m_ImplicitRules.end())
+ {
+ matchres Res;
+
+ if (PercentMatch(TargetFileName,ImpRegExIt->first->GetFullFileName(),&Res))
+ {
+ implicitruledep_t::iterator ResIt=ImpRegExIt->second.begin();
+ while (ResIt!=ImpRegExIt->second.end())
+ {
+#ifdef _DEBUG
+ if (!ResIt->second)
+ {
+ throw string("No commands for implicit rule : ") + ImpRegExIt->first->GetFullFileName();
+ }
+#endif
+ ResIt->second->SetStem(Res.m_Stem);
+ vector<fileinfo*> Deps;
+ const fileinfo *pMakeDir=ResIt->second->GetMakefile()->GetMakeDir();
+ vector<fileinfo*>::iterator It=ResIt->first.begin();
+ while (It!=ResIt->first.end())
+ {
+ string Dependent=ReplaceWithStem((*It)->GetFullFileName(),Res.m_Stem);
+ #ifdef _DEBUG
+ if (Dependent.length()>MAX_PATH)
+ {
+ /* File name is getting too long, this is most probable an infinit loop */
+ throw(string("Filename too long in implicit rule search: ")+Dependent+"\nProbably some infinit loop in the implicit rules search.\n");
+ }
+ #endif
+ Deps.push_back(GetFileInfo(Dependent,pMakeDir));
+ It++;
+ }
+ Result.push_back(pair<vector<fileinfo*>,refptr<rule> >(Deps, ResIt->second));
+ ResIt++;
+ }
+ }
+ ImpRegExIt++;
+ }
+ return;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool rule::operator != (const rule &Other)
+{
+ if (m_Commands.size()!=Other.m_Commands.size())
+ return true;
+
+ vector<string>::const_iterator It=m_Commands.begin();
+ vector<string>::const_iterator OtherIt=Other.m_Commands.begin();
+ while (It!=m_Commands.end())
+ {
+ if (m_pMakefile->ExpandExpression(*It)!=Other.m_pMakefile->ExpandExpression(*OtherIt))
+ return true;
+ It++;
+ OtherIt++;
+ }
+ return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void rule::SetTargetsIsBuild(uint32 Md5_32)
+{
+ vector< fileinfo* >::iterator It=m_Targets.begin();
+ while (It!=m_Targets.end())
+ {
+ (*It)->SetCommandsMd5_32(Md5_32);
+ (*It)->SetBuild();
+ m_pMakefile->AddTarget(*It);
+ It++;
+ }
+}
+///////////////////////////////////////////////////////////////////////////////
+void rule::SetTargetsIsBuilding(const fileinfo *pSrc)
+{
+ vector< fileinfo* >::iterator It=m_Targets.begin();
+ while (It!=m_Targets.end())
+ {
+ if ((*It)!=pSrc)
+ (*It)->SetBuilding(false);
+ It++;
+ }
+}
+
+
+#ifdef _DEBUG
+///////////////////////////////////////////////////////////////////////////////
+void IMPLICITRULE::PrintImplicitRules()
+{
+ vector<implicitrule_t>::iterator ImpRegExIt=m_ImplicitRules.begin();
+ while (ImpRegExIt!=m_ImplicitRules.end())
+ {
+ implicitruledep_t::iterator SecIt=ImpRegExIt->second.begin();
+ cout << ImpRegExIt->first->GetFullFileName() << " :\n";
+ while (SecIt!=ImpRegExIt->second.end())
+ {
+ cout << " :";
+ vector<fileinfo*>::iterator DepIt=SecIt->first.begin();
+ while (DepIt!=SecIt->first.end())
+ {
+ cout << " " << (*DepIt)->GetQuotedFullFileName() <<endl;
+ DepIt++;
+ }
+ cout << endl;
+ if (SecIt->second)
+ {
+ SecIt->second->PrintCommands();
+ }
+ else
+ {
+ cout << " No rhs\n";
+ }
+ SecIt++;
+ }
+ ImpRegExIt++;
+ }
+ return;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void rule::PrintCommands(fileinfo *pTarget) const
+{
+ if (pTarget)
+ m_pMakefile->SetRuleThatIsBuild(pTarget);
+
+ vector<string>::const_iterator pCommandIt=m_Commands.begin();
+ while (pCommandIt!=m_Commands.end())
+ {
+ cout<<g_SpaceString<<*pCommandIt<<endl;
+ if (pTarget)
+ {
+ cout<<" ("<<m_pMakefile->ExpandExpression(*pCommandIt)<<")\n";
+ }
+ pCommandIt++;
+ }
+}
+
+#endif
+
+
diff --git a/tools/mhmake/src/rule.h b/tools/mhmake/src/rule.h
new file mode 100644
index 000000000..7cc287600
--- /dev/null
+++ b/tools/mhmake/src/rule.h
@@ -0,0 +1,110 @@
+/* This file is part of mhmake.
+ *
+ * Copyright (C) 2001-2010 marha@sourceforge.net
+ *
+ * Mhmake 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Mhmake 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 Mhmake. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* $Rev$ */
+
+#ifndef __RULE_H__
+#define __RULE_H__
+
+#include "refptr.h"
+#include "md5.h"
+class mhmakefileparser;
+class fileinfo;
+
+class rule: public refbase
+{
+ vector<string> m_Commands;
+ string m_Stem; // Contains the stem in case the rule is part of an implicit rule (filled in in the implicit search)
+ mhmakefileparser* m_pMakefile;
+ vector< fileinfo* > m_Targets; /* Targets that are build with this rule, do not use refptr here because otherwise we get circular references */
+public:
+ rule(mhmakefileparser *pMakefile): m_pMakefile(pMakefile)
+ {
+ }
+
+ void AddCommand(const string &Command)
+ {
+ if (!Command.empty())
+ m_Commands.push_back(Command);
+ }
+ vector<string>& GetCommands()
+ {
+ return m_Commands;
+ }
+ void PrintCommands(fileinfo *pTarget=NULL) const;
+
+ void SetStem(const string &Stem)
+ {
+ m_Stem=Stem;
+ }
+ const string &GetStem() const
+ {
+ return m_Stem;
+ }
+ void SetMakefile(mhmakefileparser *pMakefile)
+ {
+ m_pMakefile=pMakefile;
+ }
+ mhmakefileparser *GetMakefile()
+ {
+ return m_pMakefile;
+ }
+ bool operator != (const rule &Rule);
+
+ void AddTarget(fileinfo *pTarget)
+ {
+ m_Targets.push_back(pTarget);
+ }
+ void SetTargetsIsBuild(uint32 Md5_32);
+ void SetTargetsIsBuilding(const fileinfo *pSrc);
+};
+
+typedef vector<pair<vector<fileinfo*>,refptr<rule> > > implicitruledep_t;
+typedef pair<fileinfo *, implicitruledep_t > implicitrule_t;
+
+class IMPLICITRULE
+{
+ static set<rule*> m_ImplicitRuleRecurseDetStack;
+ static vector<implicitrule_t> m_ImplicitRules; // Use a vector and not a map because the order of the implicit rules is important
+public:
+ static void AddImplicitRule(fileinfo *pTarget,const vector<fileinfo*> &Deps, refptr<rule> pRule);
+ static void SearchImplicitRule(const fileinfo *pTarget, implicitruledep_t &Result);
+ static void PrintImplicitRules();
+ static bool PushRule(rule *pRule)
+ {
+ set<rule*>::iterator pFound=m_ImplicitRuleRecurseDetStack.find(pRule);
+ if (pFound==m_ImplicitRuleRecurseDetStack.end())
+ {
+ m_ImplicitRuleRecurseDetStack.insert(pRule);
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+ }
+ static void PopRule(rule *pRule)
+ {
+ m_ImplicitRuleRecurseDetStack.erase(pRule);
+ }
+};
+
+extern refptr<rule> NullRule;
+
+#endif
+
diff --git a/tools/mhmake/src/stdafx.cpp b/tools/mhmake/src/stdafx.cpp
new file mode 100644
index 000000000..b2168250b
--- /dev/null
+++ b/tools/mhmake/src/stdafx.cpp
@@ -0,0 +1,24 @@
+/* This file is part of mhmake.
+ *
+ * Copyright (C) 2001-2010 marha@sourceforge.net
+ *
+ * Mhmake 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Mhmake 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 Mhmake. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* $Rev$ */
+
+// This file is only used to generate the pre-compiled header files. The stdafx.h file
+// should only contain includes of headers that will not be likely to change (like system header files)
+
+#include "stdafx.h"
diff --git a/tools/mhmake/src/stdafx.h b/tools/mhmake/src/stdafx.h
new file mode 100644
index 000000000..5d1ffedfb
--- /dev/null
+++ b/tools/mhmake/src/stdafx.h
@@ -0,0 +1,86 @@
+/* This file is part of mhmake.
+ *
+ * Copyright (C) 2001-2010 marha@sourceforge.net
+ *
+ * Mhmake 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Mhmake 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 Mhmake. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* $Rev$ */
+
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#if !defined(AFX_STDAFX_H__CDC9F92E_2B83_4EFC_92B5_44861521ED45__INCLUDED_)
+#define AFX_STDAFX_H__CDC9F92E_2B83_4EFC_92B5_44861521ED45__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#pragma warning (disable:4786)
+#pragma warning (disable:4503)
+#pragma warning (disable:4530)
+#endif // _MSC_VER > 1000
+
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <vector>
+#include <queue>
+#include <map>
+#include <set>
+#include <stack>
+#include <algorithm>
+#include <sstream>
+
+#ifdef _MSC_VER
+#include <io.h>
+#define __CDECL __cdecl
+#else
+#define __CDECL
+#define _stricmp strcasecmp
+#define _strnicmp strncasecmp
+#define MAX_PATH 255
+#include <sys/wait.h>
+#include <popt.h>
+#include <glob.h>
+#endif
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <malloc.h>
+#ifdef _MSC_VER
+#include <crtdbg.h>
+#endif
+#include <string.h>
+#ifdef _MSC_VER
+#include <direct.h>
+#define mkdir(name,mode) _mkdir(name)
+#endif
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+using namespace std;
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_STDAFX_H__CDC9F92E_2B83_4EFC_92B5_44861521ED45__INCLUDED_)
+
diff --git a/tools/mhmake/src/util.cpp b/tools/mhmake/src/util.cpp
new file mode 100644
index 000000000..63bdb767b
--- /dev/null
+++ b/tools/mhmake/src/util.cpp
@@ -0,0 +1,780 @@
+/* This file is part of mhmake.
+ *
+ * Copyright (C) 2001-2010 marha@sourceforge.net
+ *
+ * Mhmake 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Mhmake 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 Mhmake. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* $Rev$ */
+
+#include "stdafx.h"
+
+#include "rule.h"
+#include "util.h"
+#include "mhmakeparser.h"
+
+#ifdef WIN32
+
+#include <WinIoCtl.h>
+
+#define REPARSE_MOUNTPOINT_HEADER_SIZE 8
+
+typedef struct {
+ DWORD ReparseTag;
+ DWORD ReparseDataLength;
+ WORD Reserved;
+ WORD ReparseTargetLength;
+ WORD ReparseTargetMaximumLength;
+ WORD Reserved1;
+ WCHAR ReparseTarget[1];
+} REPARSE_MOUNTPOINT_DATA_BUFFER, *PREPARSE_MOUNTPOINT_DATA_BUFFER;
+#endif
+
+static char s_UsageString[]=
+"\
+Usage: mhmake [-f <Makefile>] [-[c|C] <RunDir>] [<Var>=<Value>]\n\
+ [-a] [-q] [-s] [-v] [-P <Nr Parallel Builds>] [targets]+\n"
+#ifdef _DEBUG
+"\
+ [-p] [-n] [-e] [-l] [-w] [-d] [-CD] [-m] [-b]\n"
+#endif
+"\n\
+ <Makefile> : Makefile to load (if not specified 'makefile' is used\n\
+ <RunDir> : Make is setting the current directory to this directory at the\n\
+ start.\n\
+ <Var> : Defines a variable\n\
+ <Value> : Value of the variable\n\
+ -a : Rebuild all targets\n\
+ -s : Rescan automatic dependencies\n\
+ -v : Print version information\n\
+ -q : Quiet. Disable all output \n\
+ -P <Nr Parallel Builds> :\n\
+ Number of parallel build commands executed at the \n\
+ same time. Default is this the number of processor \n\
+ cores. 1 disables parallel builds.\n"
+#ifdef _DEBUG
+"\n\
+ The following options are additional options in mhmake_dbg which are not\n\
+ available in mhmake. These are mainly options for debugging purposes.\n\
+ -e : Dump Vars and Rules on error\n\
+ -w : Print additional information\n\
+ -p : Prints the variables and the rules before building\n\
+ -n : Only prints the commands, but does not execute them\n\
+ -l : Print parser debug information\n\
+ -d : Print the dependency checking\n\
+ -CD : Do circular dependency checking (targets depending on itself)\n\
+ -m : Create md5 database in md5.database in start directory. \n\
+ -b : Print build tree. \n\
+ -D : Print all double defined rules (even if commands are the same) \n\
+"
+#else
+"\
+\n\
+It is adviced during creation of makefiles to use mhmake_dbg. It has additional\n\
+debugging options and does some extra error checking.\n\
+For a description of the additional options: run mhmake_dbg -h\n\
+"
+#endif
+;
+
+#ifdef _DEBUG
+bool g_PrintVarsAndRules=false;
+bool g_DoNotExecute=false;
+bool g_BuildMd5Db=false;
+bool g_GenProjectTree=false;
+bool g_DumpOnError=false;
+bool g_PrintAdditionalInfo=false;
+bool g_pPrintDependencyCheck=false;
+bool g_CheckCircularDeps=false;
+bool g_PrintLexYacc=false;
+bool g_PrintMultipleDefinedRules=false;
+#endif
+
+bool g_Quiet=false;
+bool g_RebuildAll=false;
+bool g_ForceAutoDepRescan=false;
+
+const string g_EmptyString;
+const string g_SpaceString(" ");
+
+///////////////////////////////////////////////////////////////////////////////
+void PrintVersionInfo(void)
+{
+ static const char VersionStr[]="\
+mhmake : GNU compatible make tool with extensions\n\
+version: "MHMAKEVER"\n\
+Remarks and bug reports -> marha@sourceforge.net\n\
+";
+ cerr << VersionStr;
+ exit(1);
+}
+///////////////////////////////////////////////////////////////////////////////
+makecommand::makecommand()
+{
+ char ExeName[MAX_PATH];
+#ifdef WIN32
+ GetModuleFileName(NULL,ExeName,sizeof(ExeName));
+ m_BuildCommand=ExeName;
+ transform(m_BuildCommand.begin(),m_BuildCommand.end(),m_BuildCommand.begin(),(int(__CDECL *)(int))tolower);
+#else
+ int NrChars=readlink ("/proc/self/exe", ExeName, sizeof(ExeName));
+ ExeName[NrChars]=0;
+ m_BuildCommand=ExeName;
+#endif
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string Substitute(const string &ToSubst,const string &iSrcStr,const string &iToStr)
+{
+ string Ret=g_EmptyString;
+ matchres Res;
+ string SrcStr=iSrcStr;
+ string ToStr=iToStr;
+
+ if (string::npos==SrcStr.find('%'))
+ {
+ string PerStr("%");
+ SrcStr=PerStr+SrcStr;
+ ToStr=PerStr+ToStr;
+ }
+ const char *pTmp=ToSubst.c_str();
+ bool first=true;
+ while (*pTmp)
+ {
+ if (!first)
+ {
+ Ret+=g_SpaceString;
+ }
+ else
+ {
+ first=false;
+ }
+ string Item;
+ pTmp=NextItem(pTmp,Item);
+
+ if (PercentMatch(Item,SrcStr,&Res))
+ {
+ Ret+=ReplaceWithStem(ToStr,Res.m_Stem);
+ }
+ else
+ {
+ Ret+=Item;
+ }
+ }
+
+ return Ret;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool PercentMatch(const string &String,const string &Expr,matchres *pRes,const char Char)
+{
+ const char *pFirst=String.c_str();
+ const char *pFirstExpr=Expr.c_str();
+ while (*pFirstExpr && *pFirstExpr!=Char)
+ {
+ if (*pFirst!=*pFirstExpr)
+ return false;
+ pFirst++;
+ pFirstExpr++;
+ }
+
+ if (!*pFirstExpr)
+ {
+ if (!*pFirst)
+ {
+ if (pRes)
+ {
+ pRes->m_First=String;
+ pRes->m_Stem=pRes->m_Last=g_EmptyString;
+ }
+ return true;
+ } else
+ return false;
+ }
+ else if (!*pFirst)
+ return false;
+
+ const char *pEnd=pFirst+strlen(pFirst);
+
+ const char *pLast=pEnd;
+ const char *pLastExpr=pFirstExpr+strlen(pFirstExpr)-1;
+ if (pLastExpr!=pFirstExpr)
+ {
+ pLast--;
+
+ while (pLastExpr>pFirstExpr)
+ {
+ if (*pLastExpr!=*pLast)
+ return false;
+ pLastExpr--;
+ pLast--;
+ }
+ pLast++;
+ }
+ string Stem=string(pFirst,pLast-pFirst);
+
+ if (pRes)
+ {
+ pRes->m_First=string(String.c_str(),pFirst-String.c_str());
+
+ pRes->m_Stem=Stem;
+
+ pRes->m_Last=string(pLast,pEnd-pLast);
+ }
+ return true;
+}
+///////////////////////////////////////////////////////////////////////////////
+bool PercentMatchNoCase(const string &String,const string &Expr,matchres *pRes,const char Char)
+{
+ const char *pFirst=String.c_str();
+ const char *pFirstExpr=Expr.c_str();
+ while (*pFirstExpr && *pFirstExpr!=Char)
+ {
+ if (tolower(*pFirst)!=tolower(*pFirstExpr))
+ return false;
+ pFirst++;
+ pFirstExpr++;
+ }
+
+ if (!*pFirstExpr)
+ {
+ if (!*pFirst)
+ {
+ if (pRes)
+ {
+ pRes->m_First=String;
+ pRes->m_Stem=pRes->m_Last=g_EmptyString;
+ }
+ return true;
+ } else
+ return false;
+ }
+ else if (!*pFirst)
+ return false;
+
+ const char *pEnd=pFirst+strlen(pFirst);
+
+ const char *pLast=pEnd;
+ const char *pLastExpr=pFirstExpr+strlen(pFirstExpr)-1;
+ if (pLastExpr!=pFirstExpr)
+ {
+ pLast--;
+
+ while (pLastExpr>pFirstExpr)
+ {
+ if (tolower(*pLastExpr)!=tolower(*pLast))
+ return false;
+ pLastExpr--;
+ pLast--;
+ }
+ pLast++;
+ }
+ string Stem=string(pFirst,pLast-pFirst);
+
+ if (pRes)
+ {
+ pRes->m_First=string(String.c_str(),pFirst-String.c_str());
+
+ pRes->m_Stem=Stem;
+
+ pRes->m_Last=string(pLast,pEnd-pLast);
+ }
+ return true;
+}
+///////////////////////////////////////////////////////////////////////////////
+bool PercentMatchList(const string &String,const string &ExprList,matchres *pRes)
+{
+ const char *pTmp=ExprList.c_str();
+ while (*pTmp)
+ {
+ string Expr;
+ pTmp=NextItem(pTmp,Expr);
+ if (PercentMatch(String,Expr,pRes))
+ return true;
+ }
+ return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+string ReplaceWithStem(const string &String,const string &Stem)
+{
+ string Ret=String;
+ size_t Pos=Ret.find('%');
+ while (Pos!=string::npos)
+ {
+ Ret=Ret.substr(0,Pos)+Stem+Ret.substr(Pos+1);
+ Pos=Ret.find('%');
+ }
+ return Ret;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+refptr<loadedmakefile> LOADEDMAKEFILES::find(const loadedmakefile &ToSearch)
+{
+ vector<refptr<loadedmakefile> >::const_iterator It=begin();
+ while (It!=end())
+ {
+ if (*(*It)==ToSearch)
+ return *It;
+ It++;
+ }
+ return refptr<loadedmakefile>();
+}
+
+LOADEDMAKEFILES g_LoadedMakefiles;
+
+///////////////////////////////////////////////////////////////////////////////
+loadedmakefile::loadedmakefile_statics::loadedmakefile_statics()
+{
+ m_GlobalCommandLineVars[MAKE]=g_MakeCommand;
+ const char *pEnv=getenv(MHMAKECONF);
+ if (pEnv)
+ {
+ string Env(QuoteFileName(pEnv));
+ m_GlobalCommandLineVars[MHMAKECONF]=Env;
+ m_MhMakeConf=GetAbsFileInfo(Env);
+
+ // Get the revision of the working copy
+ // We do it with the svn info command
+
+ string Output;
+ try
+ {
+ mhmakefileparser Dummy(curdir::GetCurDir());
+ string SvnCommand=Dummy.SearchCommand("svn",EXEEXT);
+ #ifdef WIN32
+ if (GetFileAttributes(m_MhMakeConf->GetFullFileName().c_str())&FILE_ATTRIBUTE_REPARSE_POINT)
+ {
+ WIN32_FIND_DATA FindData;
+ HANDLE hFind=FindFirstFile(m_MhMakeConf->GetFullFileName().c_str(),&FindData);
+ if (hFind!=INVALID_HANDLE_VALUE)
+ {
+ if (FindData.dwReserved0==IO_REPARSE_TAG_MOUNT_POINT)
+ {
+ HANDLE hDir = ::CreateFile(m_MhMakeConf->GetFullFileName().c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL);
+
+ BYTE buf[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; // We need a large buffer
+ REPARSE_MOUNTPOINT_DATA_BUFFER& ReparseBuffer = (REPARSE_MOUNTPOINT_DATA_BUFFER&)buf;
+ DWORD dwRet;
+
+ if (::DeviceIoControl(hDir, FSCTL_GET_REPARSE_POINT, NULL, 0, &ReparseBuffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &dwRet, NULL))
+ {
+ // Success
+ ::CloseHandle(hDir);
+
+ LPCWSTR pPath = ReparseBuffer.ReparseTarget;
+ if (wcsncmp(pPath, L"\\??\\", 4) == 0) pPath += 4; // Skip 'non-parsed' prefix
+ char szPath[MAX_PATH];
+ ::WideCharToMultiByte(CP_ACP, 0, pPath, -1, szPath, MAX_PATH, NULL, NULL);
+ Dummy.OsExeCommand(SvnCommand,string(" info ")+GetFileInfo(szPath,m_MhMakeConf->GetDir())->GetQuotedFullFileName(),false,&Output);
+ }
+ else
+ { // Error
+ ::CloseHandle(hDir);
+ }
+ }
+ FindClose(hFind);
+ }
+ }
+ #else
+ struct stat Stat;
+ lstat(m_MhMakeConf->GetFullFileName().c_str(),&Stat);
+ if (S_ISLNK(Stat.st_mode))
+ {
+ char FileName[1024];
+ int len=readlink(m_MhMakeConf->GetFullFileName().c_str(),FileName,sizeof(FileName));
+ FileName[len]=0;
+ Dummy.OsExeCommand(SvnCommand,string(" info ")+GetFileInfo(FileName,m_MhMakeConf->GetDir())->GetQuotedFullFileName(),false,&Output);
+ }
+ #endif
+ else
+ Dummy.OsExeCommand(SvnCommand,string(" info ")+m_MhMakeConf->GetQuotedFullFileName(),false,&Output);
+ }
+ catch (string Message)
+ {
+ }
+
+ char *pTok=strtok((char*)Output.c_str(),"\n"); // doing this is changing string, so this is very dangerous !!!
+ while (pTok)
+ {
+ if (!strncmp(pTok,"URL: ",5))
+ {
+ m_GlobalCommandLineVars[WC_URL]=pTok+5+7;
+ }
+ else if (!strncmp(pTok,"Revision: ",10))
+ {
+ m_GlobalCommandLineVars[WC_REVISION]=pTok+10;
+ break;
+ }
+ pTok=strtok(NULL,"\n");
+ }
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+loadedmakefile::loadedmakefile(const fileinfo *pDir, vector<string> &Args,const string&Makefile)
+{
+ m_Makefile=NULL;
+ m_CommandLineVars=sm_Statics.m_GlobalCommandLineVars;
+
+ m_MakeDir=NULL;
+ vector<string>::iterator ArgIt=Args.begin();
+ while (ArgIt!=Args.end())
+ {
+ size_t EqPos=ArgIt->find('=');
+ if (EqPos!=string::npos)
+ {
+ string Var=ArgIt->substr(0,EqPos);
+ string Val=ArgIt->substr(EqPos+1);
+ m_CommandLineVars[Var]=Val;
+ }
+ else if ((*ArgIt)[0]=='-')
+ {
+ switch ((*ArgIt)[1])
+ {
+ case 'f':
+ if (ArgIt->size()>2)
+ {
+ if (!m_MakeDir)
+ {
+ m_Makefile=GetFileInfo(ArgIt->substr(2),pDir);
+ }
+ else
+ {
+ m_Makefile=GetFileInfo(ArgIt->substr(2),m_MakeDir);
+ }
+ }
+ else
+ {
+ ArgIt++;
+ if (!m_MakeDir)
+ {
+ m_Makefile=GetFileInfo(*ArgIt,pDir);
+ }
+ else
+ {
+ m_Makefile=GetFileInfo(*ArgIt,m_MakeDir);
+ }
+ }
+ break;
+ case 'C':
+#ifdef _DEBUG
+ if (ArgIt->size()>2 && (*ArgIt)[2]=='D')
+ {
+ g_CheckCircularDeps=true;
+ break;
+ }
+#endif
+ /* Fall through */
+ case 'c':
+ if (ArgIt->size()>2)
+ m_MakeDir=GetFileInfo(ArgIt->substr(2),pDir);
+ else
+ {
+ ArgIt++;
+ m_MakeDir=GetFileInfo(*ArgIt,pDir);
+ }
+ break;
+ case 'a':
+ g_RebuildAll=true;
+ break;
+ case 'q':
+ g_Quiet=true;
+ break;
+ case 's':
+ g_ForceAutoDepRescan=true;
+ break;
+ case 'v':
+ PrintVersionInfo();
+ break;
+ case 'P':
+ if (ArgIt->size()>2)
+ mhmakefileparser::SetNrParallelBuilds(atoi(ArgIt->substr(2).c_str()));
+ else
+ {
+ ArgIt++;
+ mhmakefileparser::SetNrParallelBuilds(atoi((*ArgIt).c_str()));
+ }
+ break;
+#ifdef _DEBUG
+ case 'p':
+ g_PrintVarsAndRules=true;
+ break;
+ case 'n':
+ g_DoNotExecute=true;
+ break;
+ case 'w':
+ g_PrintAdditionalInfo=true;
+ break;
+ case 'd':
+ g_pPrintDependencyCheck=true;
+ break;
+ case 'D':
+ g_PrintMultipleDefinedRules=true;
+ break;
+ case 'l':
+ g_PrintLexYacc=true;
+ break;
+ case 'e':
+ g_DumpOnError=true;
+ break;
+ case 'm':
+ g_BuildMd5Db=true;
+ break;
+ case 'b':
+ g_GenProjectTree=true;
+ break;
+#endif
+ default:
+ throw string("\nUnknown option: ")+*ArgIt+"\n\n"+ s_UsageString;
+ }
+ }
+ else
+ {
+ m_CommandLineTargets.push_back(*ArgIt);
+ }
+ ArgIt++;
+ }
+ if (!m_Makefile)
+ {
+ if (!Makefile.empty())
+ {
+ if (!m_MakeDir)
+ m_Makefile=GetFileInfo(Makefile,pDir);
+ else
+ m_Makefile=GetFileInfo(Makefile,m_MakeDir);
+ }
+ }
+ if (!m_Makefile)
+ {
+ if (!m_MakeDir)
+ m_Makefile=GetFileInfo(m_CommandLineTargets[0],pDir);
+ else
+ m_Makefile=GetFileInfo(m_CommandLineTargets[0],m_MakeDir);
+
+ m_CommandLineTargets.erase(m_CommandLineTargets.begin());
+ }
+ if (!m_MakeDir)
+ {
+ if (Makefile==g_EmptyString)
+ m_MakeDir=m_Makefile->GetDir(); /* This is one from load_makefile, so we take the directory of the makefile itself. */
+ else
+ m_MakeDir=curdir::GetCurDir(); /* This means that this is the main makefile given on the command line, so we take the current directory */
+ }
+
+ if (loadedmakefile::sm_Statics.m_MhMakeConf)
+ {
+ const string &RootDir=loadedmakefile::sm_Statics.m_MhMakeConf->GetFullFileName();
+ string MakeDir=m_MakeDir->GetFullFileName();
+ if (RootDir.length()>MakeDir.length() || _strnicmp(RootDir.c_str(),MakeDir.c_str(),RootDir.length()))
+ {
+ cerr<<"mhmake needs to run in a directory that is a subdirectory of the directory specified with %MHMAKECONF : "<<RootDir<<", make dir : "<<m_MakeDir->GetFullFileName()<<endl;
+ exit(1);
+ }
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void loadedmakefile::LoadMakefile()
+{
+ #ifdef _DEBUG
+ if (g_PrintAdditionalInfo)
+ cout << "Loading makefile "<<m_Makefile->GetQuotedFullFileName()<<endl;
+ #endif
+
+ m_pParser=refptr<mhmakefileparser>(new mhmakeparser(m_CommandLineVars));
+
+ // Add the MAKECMDGOALS environment variable
+ string MakeCmdGoals;
+ bool First=true;
+ vector<string>::iterator TarIt=m_CommandLineTargets.begin();
+ while (TarIt!=m_CommandLineTargets.end())
+ {
+ if (First)
+ First=false;
+ else
+ MakeCmdGoals+=g_SpaceString;
+ MakeCmdGoals+=*TarIt;
+ TarIt++;
+ }
+ m_pParser->SetVariable("MAKECMDGOALS",MakeCmdGoals);
+
+ string BaseAutoMak;
+
+ // First parse the makefile.before makefile which is in the directory $(MHMAKECONF) environment variable
+ fileinfo *pDepFile;
+ if (sm_Statics.m_MhMakeConf)
+ {
+ BaseAutoMak=m_pParser->ExpandVar(BASEAUTOMAK);
+ if (BaseAutoMak.empty())
+ {
+ BaseAutoMak="makefile";
+ m_pParser->SetVariable(BASEAUTOMAK,BaseAutoMak);
+ }
+ const fileinfo *pBeforeMakefile=GetFileInfo(BaseAutoMak+".before",sm_Statics.m_MhMakeConf);
+
+ int result=m_pParser->ParseFile(pBeforeMakefile,m_MakeDir);
+ if (result)
+ {
+ throw string("Error parsing ")+pBeforeMakefile->GetQuotedFullFileName();
+ }
+ m_pParser->UpdateDate(pBeforeMakefile->GetDate());
+
+ // Now parse the automaticly generated dependency file, which needs to be in the objdir directory
+ string ObjDirName=m_pParser->ExpandExpression("$(OBJDIR)");
+ if (!ObjDirName.size())
+ {
+ throw string("When making use of MHMAKECONF, you have to define OBJDIR in makefile.before");
+ }
+ pDepFile=GetFileInfo(ObjDirName+OSPATHSEPSTR "." + m_Makefile->GetName()+ ".dep",m_MakeDir);
+ m_pParser->SetVariable(AUTODEPFILE,pDepFile->GetQuotedFullFileName());
+ }
+ else
+ {
+ /* Create a file that is depending on the makefile name and the arguments */
+ md5_context ctx;
+
+ md5_starts( &ctx );
+
+ map<string,string>::const_iterator pIt=m_CommandLineVars.begin();
+ while (pIt!=m_CommandLineVars.end())
+ {
+ if (pIt->first!="MAKE")
+ {
+ md5_update(&ctx, (uint8*)pIt->first.c_str(), pIt->first.size());
+ md5_update(&ctx, (uint8*)pIt->second.c_str(), pIt->second.size());
+ }
+ pIt++;
+ }
+ md5_update(&ctx, (uint8*)m_Makefile->GetFullFileName().c_str(), m_Makefile->GetFullFileName().size());
+
+ char ID[10];
+ sprintf(ID,"_%x",md5_finish32( &ctx));
+
+ pDepFile=GetFileInfo(string(".") + m_Makefile->GetName()+ ".dep"+ID,m_MakeDir);
+ m_pParser->SetVariable(AUTODEPFILE,pDepFile->GetQuotedFullFileName());
+ }
+
+ if (pDepFile->Exists())
+ m_pParser->LoadAutoDepsFile(pDepFile); /* Already load this autodep file before parsing of the makefile to avoid needless rebuilds. */
+
+ //m_pParser->yydebug=1;
+ int result=m_pParser->ParseFile(m_Makefile,m_MakeDir);
+ if (result)
+ {
+ throw string("Error parsing ")+m_Makefile->GetQuotedFullFileName();
+ }
+ #ifdef _DEBUG
+ /* Check if the makefile has changed the AUTODEPFILE variable, if so generate a warning that a
+ * rebuild could happen for the rules defined for making included makefiles */
+ if (m_pParser->ExpandVar(AUTODEPFILE)!=pDepFile->GetQuotedFullFileName())
+ {
+ cout << "\n\nWARNING:\n makefile '"<< m_Makefile->GetQuotedFullFileName() <<"' re-defines AUTODEPFILE\n from '"<< pDepFile->GetQuotedFullFileName() <<"'\n to '"<<
+ m_pParser->ExpandVar(AUTODEPFILE) << "'\n (may cause needless rebuilds when having rules for included makefiles!!!!!)\n\n\n";
+ }
+
+ if (g_PrintAdditionalInfo)
+ {
+ if (m_pParser->GetFirstTarget())
+ cout<<"First target of "<<m_Makefile->GetQuotedFullFileName()<<" is "<<m_pParser->GetFirstTarget()->GetQuotedFullFileName()<<endl;
+ else
+ cout<<"No First target for "<<m_Makefile->GetQuotedFullFileName()<<endl;
+ }
+ #endif
+ m_pParser->UpdateDate(m_Makefile->GetDate());
+
+ if (sm_Statics.m_MhMakeConf)
+ {
+ fileinfo *pAfterMakefile=GetFileInfo(BaseAutoMak+".after",sm_Statics.m_MhMakeConf);
+ int result=m_pParser->ParseFile(pAfterMakefile);
+ if (result) {
+ throw string("Error parsing ")+pAfterMakefile->GetQuotedFullFileName();
+ }
+ m_pParser->UpdateDate(pAfterMakefile->GetDate());
+ }
+ bool ForceAutoDepRescan=g_ForceAutoDepRescan;
+ if (pDepFile->Exists())
+ m_pParser->LoadAutoDepsFile(pDepFile);
+ else
+ ForceAutoDepRescan=true;
+ if (ForceAutoDepRescan)
+ m_pParser->EnableAutoDepRescan();
+
+ vector<string> &MakefilesToLoad=m_pParser->GetMakefilesToLoad();
+ vector<string>::iterator It=MakefilesToLoad.begin();
+ while (It!=MakefilesToLoad.end())
+ {
+ // First split the command into arguments
+ const char *pTmp=It->c_str();
+ vector<string> Args;
+ while (*pTmp)
+ {
+ string Item;
+ pTmp=NextItem(pTmp,Item);
+ Args.push_back(Item);
+ }
+
+ refptr<loadedmakefile> pLoadedMakefile(new loadedmakefile(m_MakeDir,Args));
+ refptr<loadedmakefile> Found=g_LoadedMakefiles.find(*pLoadedMakefile);
+ if (Found)
+ {
+ #ifdef _DEBUG
+ if (g_PrintAdditionalInfo)
+ cout << "Makefile already loaded: "<<Found->m_Makefile->GetQuotedFullFileName()<<endl;
+ #endif
+ }
+ else
+ {
+ g_LoadedMakefiles.push_back(pLoadedMakefile);
+
+ /* If there is a rule to build the makefile, first check if it needs to be rebuild */
+ m_pParser->BuildTarget(pLoadedMakefile->m_Makefile);
+ pLoadedMakefile->LoadMakefile();
+ }
+ It++;
+ }
+}
+
+#ifdef _DEBUG
+///////////////////////////////////////////////////////////////////////////////
+void DumpVarsAndRules()
+{
+ int i;
+ LOADEDMAKEFILES::iterator LoadMakIt=g_LoadedMakefiles.begin();
+ while (LoadMakIt!=g_LoadedMakefiles.end())
+ {
+ for (i=0; i<80; i++) cout << "_";
+ cout << endl;
+ cout << "Variables of makefile " << (*LoadMakIt)->m_Makefile->GetQuotedFullFileName() << endl;
+ for (i=0; i<80; i++) cout << "_";
+ cout << endl;
+ (*LoadMakIt)->m_pParser->PrintVariables(true);
+ cout << endl;
+ LoadMakIt++;
+ }
+ for (i=0; i<80; i++) cout << "_";
+ cout << endl;
+ cout << "All Rules\n";
+ for (i=0; i<80; i++) cout << "_";
+ cout << endl;
+ PrintFileInfos();
+ for (i=0; i<80; i++) cout << "_";
+ cout << endl;
+ cout << "All Implicit Rules\n";
+ for (i=0; i<80; i++) cout << "_";
+ cout << endl;
+ IMPLICITRULE::PrintImplicitRules();
+}
+#endif
+
diff --git a/tools/mhmake/src/util.h b/tools/mhmake/src/util.h
new file mode 100644
index 000000000..8676bd0d6
--- /dev/null
+++ b/tools/mhmake/src/util.h
@@ -0,0 +1,238 @@
+/* This file is part of mhmake.
+ *
+ * Copyright (C) 2001-2010 marha@sourceforge.net
+ *
+ * Mhmake 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Mhmake 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 Mhmake. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* $Rev$ */
+
+#ifndef __UTIL_H__
+#define __UTIL_H__
+
+#include "fileinfo.h"
+
+// List of pre-defined variables
+#define WC_REVISION "WC_REVISION"
+#define WC_URL "WC_URL"
+#define AUTODEPFILE "AUTODEPFILE"
+#define OBJEXTVAR "OBJEXT"
+#define EXEEXTVAR "EXEEXT"
+#define SKIPHEADERS "SKIPHEADERS"
+#define MAKE "MAKE"
+#define MHMAKECONF "MHMAKECONF"
+#define BASEAUTOMAK "BASEAUTOMAK"
+#define CURDIR "CURDIR"
+#define USED_ENVVARS "USED_ENVVARS"
+#define PATH "PATH"
+#ifdef WIN32
+#define COMSPEC "COMSPEC"
+#define PYTHONEXE "python.exe"
+#define EXEEXT ".exe"
+#define OBJEXT ".obj"
+#define PLATFORM "win32"
+#else
+#define COMSPEC "SHELL"
+#define PYTHONEXE "python"
+#define EXEEXT ""
+#define OBJEXT ".o"
+#define PLATFORM "linux"
+#endif
+
+#define MHMAKEVER "2.3.17"
+
+class makecommand
+{
+ string m_BuildCommand;
+public:
+ makecommand();
+ operator string()
+ {
+ return m_BuildCommand;
+ }
+};
+
+extern makecommand g_MakeCommand;
+
+///////////////////////////////////////////////////////////////////////////////
+inline const char *NextItem(const char *pTmp,string &Output, const char *pToks=" \t")
+{
+ const char *pStart;
+ const char *pStop;
+ while (strchr(pToks,*pTmp)&&*pTmp) pTmp++;
+ pStart=pTmp;
+ while (1)
+ {
+ if (*pTmp=='"')
+ {
+ pTmp++;
+ while (*pTmp && *pTmp!='"') pTmp++;
+ if (*pTmp) pTmp++;
+ pStop=pTmp;
+ if (!*pTmp || strchr(pToks,*pTmp))
+ break;
+ }
+ else if (*pTmp=='\'')
+ {
+ pTmp++;
+ while (*pTmp && *pTmp!='\'') pTmp++;
+ if (*pTmp) pTmp++;
+ pStop=pTmp;
+ if (!*pTmp || strchr(pToks,*pTmp))
+ break;
+ }
+ else if (!*pTmp)
+ {
+ pStop=pTmp;
+ break;
+ }
+ else
+ {
+ pTmp++;
+ #if OSPATHSEP=='/'
+ while (*pTmp)
+ {
+ if (!strchr(pToks,*pTmp) || (*(pTmp-1)=='\\'))
+ pTmp++;
+ else
+ break;
+ }
+ #else
+ while (!strchr(pToks,*pTmp)) pTmp++;
+ #endif
+ pStop=pTmp;
+ break;
+ }
+ }
+ Output=string(pStart,pStop);
+ // skip trailing space
+ while (strchr(pToks,*pTmp)&&*pTmp) pTmp++;
+ return pTmp;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+inline const char *NextCharItem(const char *pTmp,string &Output,char Char)
+{
+ const char *pStart=pTmp;
+ while (*pTmp && *pTmp!=Char) pTmp++;
+ const char *pStop=pTmp;
+ if (*pTmp) pTmp++;
+
+ while (pStart<pStop && (*pStart==' ' || *pStart == '\t')) pStart++;
+ pStop--;
+ while (pStart<=pStop && (*pStop==' ' || *pStop == '\t')) pStop--;
+ pStop++;
+
+ Output=string(pStart,pStop);
+ return pTmp;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+string Substitute(const string &ToSubst,const string &SrcStr,const string &ToStr);
+
+struct matchres
+{
+ string m_First;
+ string m_Stem;
+ string m_Last;
+};
+
+bool PercentMatch(const string &String,const string &Expr,matchres *pRes=NULL,const char Char='%');
+bool PercentMatchNoCase(const string &String,const string &Expr,matchres *pRes=NULL,const char Char='%');
+bool PercentMatchList(const string &String,const string &ExprList,matchres *pRes=NULL);
+string ReplaceWithStem(const string &String,const string &Stem);
+
+struct loadedmakefile : public refbase
+{
+ struct loadedmakefile_statics
+ {
+ map<string,string> m_GlobalCommandLineVars;
+ fileinfo *m_MhMakeConf;
+
+ loadedmakefile_statics();
+ };
+ static loadedmakefile_statics sm_Statics;
+
+ fileinfo *m_Makefile;
+ const fileinfo *m_MakeDir;
+ map<string,string> m_CommandLineVars;
+
+ vector<string> m_CommandLineTargets;
+ refptr<mhmakefileparser> m_pParser;
+
+ loadedmakefile(const fileinfo *pDir, vector<string> &Args,const string &Makefile=g_EmptyString);
+
+ void LoadMakefile();
+ void AddCommandLineVarsToEnvironment()
+ {
+ map<string,string>::const_iterator It=m_CommandLineVars.begin();
+ map<string,string>::const_iterator ItEnd=m_CommandLineVars.end();
+ while (It!=ItEnd)
+ {
+ sm_Statics.m_GlobalCommandLineVars.insert(*It++);
+ }
+ }
+
+ int operator==(const loadedmakefile &Other)
+ {
+ if (m_Makefile!=Other.m_Makefile)
+ return 0;
+ if (m_MakeDir!=Other.m_MakeDir)
+ return 0;
+ if (m_CommandLineTargets.size()!=Other.m_CommandLineTargets.size())
+ return 0;
+ if (m_CommandLineVars.size()!=Other.m_CommandLineVars.size())
+ return 0;
+ map<string,string>::iterator VarIt=m_CommandLineVars.begin();
+ while (VarIt!=m_CommandLineVars.end())
+ {
+ map<string,string>::const_iterator pFound=Other.m_CommandLineVars.find(VarIt->first);
+ if (pFound==Other.m_CommandLineVars.end())
+ return 0;
+ if (pFound->second!=VarIt->second)
+ return 0;
+ VarIt++;
+ }
+ vector<string>::iterator TarIt=m_CommandLineTargets.begin();
+ while (TarIt!=m_CommandLineTargets.end())
+ {
+ vector<string>::const_iterator OtherIt=Other.m_CommandLineTargets.begin();
+ while (OtherIt!=Other.m_CommandLineTargets.begin())
+ {
+ if (*TarIt==*OtherIt)
+ break;
+ OtherIt++;
+ }
+ if (OtherIt==Other.m_CommandLineTargets.end())
+ return 0;
+ TarIt++;
+ }
+ return 1;
+ }
+};
+
+class LOADEDMAKEFILES : public vector<refptr<loadedmakefile> >
+{
+public:
+ refptr<loadedmakefile> find(const loadedmakefile &pToSearch);
+ typedef vector<refptr<loadedmakefile> >::iterator iterator;
+};
+
+extern LOADEDMAKEFILES g_LoadedMakefiles;
+
+void DumpVarsAndRules();
+
+#endif
+
diff --git a/tools/mhmake/ylwrap b/tools/mhmake/ylwrap
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tools/mhmake/ylwrap