mirror of
https://github.com/cwbaker/lalr.git
synced 2026-09-26 16:33:18 +03:00
sweet_parser-2012.08.14
This commit is contained in:
parent
8fd418086d
commit
80b907b34e
203 changed files with 4130 additions and 1622 deletions
|
|
@ -2,7 +2,7 @@
|
|||
Library {
|
||||
id = "assert";
|
||||
|
||||
Cc {
|
||||
Source {
|
||||
pch = "stdafx.hpp";
|
||||
"assert.cpp"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,17 @@
|
|||
//
|
||||
// assert.cpp
|
||||
// Copyright (c) 2008 - 2011 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2008 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#include "stdafx.hpp"
|
||||
#include "assert.hpp"
|
||||
#include <sweet/build.hpp>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(BUILD_OS_WINDOWS)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
namespace sweet
|
||||
{
|
||||
|
|
@ -12,6 +19,16 @@ namespace sweet
|
|||
namespace assert
|
||||
{
|
||||
|
||||
/**
|
||||
// Break in the debugger.
|
||||
*/
|
||||
void sweet_break()
|
||||
{
|
||||
#if defined(BUILD_OS_WINDOWS)
|
||||
DebugBreak();
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
// If \e expression isn't true then print \e file, \e line, and
|
||||
// \e description to the debug console and stderr.
|
||||
|
|
@ -27,18 +44,17 @@ namespace assert
|
|||
*/
|
||||
void sweet_assert( bool expression, const char* description, const char* file, int line )
|
||||
{
|
||||
#if defined(BUILD_OS_WINDOWS)
|
||||
int error = ::GetLastError();
|
||||
|
||||
if ( !expression )
|
||||
{
|
||||
char message [1024];
|
||||
_snprintf( message, sizeof(message), "%s(%i) : %s\n", file, line, description );
|
||||
message[sizeof(message) - 1] = 0;
|
||||
::OutputDebugStringA( message );
|
||||
::fputs( message, stderr );
|
||||
}
|
||||
|
||||
::SetLastError( error );
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// assert.hpp
|
||||
// Copyright (c) 2006 - 2011 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2006 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef SWEET_ASSERT_ASSERT_HPP_INCLUDED
|
||||
|
|
@ -38,12 +38,19 @@ namespace sweet
|
|||
namespace assert
|
||||
{
|
||||
|
||||
SWEET_ASSERT_DECLSPEC void sweet_break();
|
||||
SWEET_ASSERT_DECLSPEC void sweet_assert( bool expression, const char* description, const char* file, int line );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define SWEET_BREAK() __debugbreak()
|
||||
#else
|
||||
#define SWEET_BREAK() sweet::assert::sweet_break()
|
||||
#endif
|
||||
|
||||
#ifdef SWEET_ASSERT_ENABLED
|
||||
|
||||
#define SWEET_ASSERT( x ) \
|
||||
|
|
@ -51,7 +58,7 @@ do { \
|
|||
if ( !(x) ) \
|
||||
{ \
|
||||
sweet::assert::sweet_assert( false, #x, __FILE__, __LINE__ ); \
|
||||
__debugbreak(); \
|
||||
SWEET_BREAK(); \
|
||||
} \
|
||||
} while ( false )
|
||||
|
||||
|
|
|
|||
|
|
@ -7,9 +7,3 @@
|
|||
#define NOMINMAX
|
||||
#define _WIN32_WINNT 0x500
|
||||
#define WINVER 0x500
|
||||
|
||||
#include <sweet/build.hpp>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <dbghelp.h>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// atomic.hpp
|
||||
// Copyright (c) 2008 - 2011 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2008 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef SWEET_ATOMIC_ATOMIC_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// atomic.ipp
|
||||
// Copyright (c) 2008 - 2011 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2008 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef SWEET_ATOMIC_ATOMIC_IPP_INCLUDED
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include <sweet/assert/assert.hpp>
|
||||
|
||||
#if defined(BUILD_PLATFORM_MSVC)
|
||||
#if defined(BUILD_OS_WINDOWS)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
|
|
@ -29,11 +29,13 @@ namespace atomic
|
|||
*/
|
||||
inline int atomic_increment( volatile int* destination )
|
||||
{
|
||||
#if defined(BUILD_PLATFORM_MSVC)
|
||||
#if defined(BUILD_OS_WINDOWS)
|
||||
SWEET_ASSERT( destination );
|
||||
return static_cast<int>( ::InterlockedIncrement(reinterpret_cast<volatile long*>(destination)) );
|
||||
#elif defined(BUILD_OS_MACOSX)
|
||||
return static_cast<int>( __sync_add_and_fetch(destination, 1) );
|
||||
#else
|
||||
#error "The function 'sweet::atomic::atomic_increment()' is not implemened for this platform."
|
||||
#error "The function 'sweet::atomic::atomic_increment()' is not implemented for this platform."
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -48,11 +50,13 @@ inline int atomic_increment( volatile int* destination )
|
|||
*/
|
||||
inline int atomic_decrement( volatile int* destination )
|
||||
{
|
||||
#if defined(BUILD_PLATFORM_MSVC)
|
||||
#if defined(BUILD_OS_WINDOWS)
|
||||
SWEET_ASSERT( destination );
|
||||
return static_cast<int>( ::InterlockedDecrement(reinterpret_cast<volatile long*>(destination)) );
|
||||
#elif defined(BUILD_OS_MACOSX)
|
||||
return static_cast<int>( __sync_sub_and_fetch(destination, 1) );
|
||||
#else
|
||||
#error "The function 'sweet::atomic::atomic_decrement()' is not implemened for this platform."
|
||||
#error "The function 'sweet::atomic::atomic_decrement()' is not implemented for this platform."
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -70,11 +74,15 @@ inline int atomic_decrement( volatile int* destination )
|
|||
*/
|
||||
inline int atomic_exchange( volatile int* destination, int exchange )
|
||||
{
|
||||
#if defined(BUILD_PLATFORM_MSVC)
|
||||
#if defined(BUILD_OS_WINDOWS)
|
||||
SWEET_ASSERT( destination );
|
||||
return static_cast<int>( ::InterlockedExchange(reinterpret_cast<volatile long*>(destination), exchange) );
|
||||
#elif defined(BUILD_OS_MACOSX)
|
||||
int result = static_cast<int>( __sync_lock_test_and_set(destination, exchange) );
|
||||
__sync_lock_release( destination );
|
||||
return result;
|
||||
#else
|
||||
#error "The function 'sweet::atomic::atomic_exchange()' is not implemened for this platform."
|
||||
#error "The function 'sweet::atomic::atomic_exchange()' is not implemented for this platform."
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -85,12 +93,12 @@ inline int atomic_exchange( volatile int* destination, int exchange )
|
|||
// \e destination is exchanged with \e exchange.
|
||||
//
|
||||
@code
|
||||
int original_value = *value;
|
||||
int original = *value;
|
||||
if ( *value == comparand )
|
||||
{
|
||||
*value = exchange;
|
||||
}
|
||||
return original_value;
|
||||
return original;
|
||||
@endcode
|
||||
//
|
||||
// The \e destination pointer is assumed not to be null and to be aligned on
|
||||
|
|
@ -110,11 +118,13 @@ return original_value;
|
|||
*/
|
||||
inline int atomic_compare_exchange( volatile int* destination, int exchange, int comparand )
|
||||
{
|
||||
#if defined(BUILD_PLATFORM_MSVC)
|
||||
#if defined(BUILD_OS_WINDOWS)
|
||||
SWEET_ASSERT( destination );
|
||||
return static_cast<int>( ::InterlockedCompareExchange(reinterpret_cast<volatile long*>(destination), exchange, comparand) );
|
||||
#elif defined(BUILD_OS_MACOSX)
|
||||
return static_cast<int>( __sync_val_compare_and_swap(destination, comparand, exchange) );
|
||||
#else
|
||||
#error "The function 'sweet::atomic::atomic_compare_exchange()' is not implemened for this platform."
|
||||
#error "The function 'sweet::atomic::atomic_compare_exchange()' is not implemented for this platform."
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,45 +1,68 @@
|
|||
|
||||
command = command or "build";
|
||||
platform = platform or "msvc";
|
||||
source = source or "";
|
||||
target = target or "";
|
||||
variant = variant or "debug";
|
||||
version = version or os.date( "%Y.%m.%d %H:%M:%S "..platform.." "..variant );
|
||||
jobs = jobs or 4;
|
||||
|
||||
package.path = root("build/lua/?.lua")..";"..root("build/lua/?/init.lua");
|
||||
require "build";
|
||||
require "build/llvmgcc";
|
||||
require "build/mingw";
|
||||
require "build/msvc";
|
||||
require "build/boost";
|
||||
require "build/Parser";
|
||||
require "build/visual_studio";
|
||||
require "build/xcode";
|
||||
|
||||
setup {
|
||||
bin = root( "../bin" );
|
||||
lib = root( "../lib" );
|
||||
obj = root( "../obj" );
|
||||
include_directories = {
|
||||
root( ".." ),
|
||||
"C:/boost/include/boost-1_43"
|
||||
function initialize()
|
||||
platform = platform or build.switch { operating_system(); windows = "msvc"; macosx = "llvmgcc" };
|
||||
variant = variant or "debug";
|
||||
version = version or os.date( "%Y.%m.%d %H:%M:%S "..platform.." "..variant );
|
||||
goal = goal or "";
|
||||
jobs = jobs or 4;
|
||||
|
||||
local boost_include_directory, boost_library_directory;
|
||||
if operating_system() == "windows" then
|
||||
boost_include_directory = "C:/boost/include/boost-1_43";
|
||||
boost_library_directory = "C:/boost/lib";
|
||||
elseif operating_system() == "macosx" then
|
||||
boost_include_directory = home( "boost/include/boost-1_43" );
|
||||
boost_library_directory = home( "boost/lib" );
|
||||
end
|
||||
|
||||
local settings = build.initialize {
|
||||
bin = root( "../bin" );
|
||||
lib = root( "../lib" );
|
||||
obj = root( "../obj" );
|
||||
include_directories = {
|
||||
root( ".." ),
|
||||
boost_include_directory
|
||||
};
|
||||
library_directories = {
|
||||
boost_library_directory
|
||||
};
|
||||
sln = root( "../sweet_parser.sln" );
|
||||
xcodeproj = root( "../sweet_parser.xcodeproj" );
|
||||
};
|
||||
library_directories = {
|
||||
"C:/boost/lib"
|
||||
};
|
||||
};
|
||||
|
||||
buildfile "assert/assert.build";
|
||||
buildfile "atomic/atomic.build";
|
||||
buildfile "cmdline/cmdline.build";
|
||||
buildfile "debug/debug.build";
|
||||
buildfile "error/error.build";
|
||||
buildfile "lexer/lexer.build";
|
||||
buildfile "lua/lua.build";
|
||||
buildfile "parser/parser.build";
|
||||
buildfile "pointer/pointer.build";
|
||||
buildfile "rtti/rtti.build";
|
||||
buildfile "traits/traits.build";
|
||||
buildfile "utility/utility.build";
|
||||
buildfile "unit/unit.build";
|
||||
if operating_system() == "windows" then
|
||||
mingw.initialize( settings );
|
||||
msvc.initialize( settings );
|
||||
visual_studio.initialize( settings );
|
||||
elseif operating_system() == "macosx" then
|
||||
llvmgcc.initialize( settings );
|
||||
xcode.initialize( settings );
|
||||
end
|
||||
boost.initialize( settings );
|
||||
parser.initialize( settings );
|
||||
end
|
||||
|
||||
AsciiDoc {
|
||||
id = "parser.html";
|
||||
"parser.txt"
|
||||
}
|
||||
|
||||
build {};
|
||||
function buildfiles()
|
||||
buildfile( "assert/assert.build" );
|
||||
buildfile( "atomic/atomic.build" );
|
||||
buildfile( "cmdline/cmdline.build" );
|
||||
buildfile( "error/error.build" );
|
||||
buildfile( "lexer/lexer.build" );
|
||||
buildfile( "lua/lua.build" );
|
||||
buildfile( "parser/parser.build" );
|
||||
buildfile( "pointer/pointer.build" );
|
||||
buildfile( "rtti/rtti.build" );
|
||||
buildfile( "traits/traits.build" );
|
||||
buildfile( "utility/utility.build" );
|
||||
buildfile( "unit/unit.build" );
|
||||
end
|
||||
|
|
|
|||
BIN
sweet/build/build
Normal file
BIN
sweet/build/build
Normal file
Binary file not shown.
46
sweet/build/lua/build/Archive.lua
Normal file
46
sweet/build/lua/build/Archive.lua
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
|
||||
ArchivePrototype = TargetPrototype { "Archive", BIND_GENERATED_FILE };
|
||||
|
||||
function ArchivePrototype.load( archive )
|
||||
local definition = archive.definition;
|
||||
if build.built_for_platform_and_variant(definition) then
|
||||
archive.architecture = archive.architecture or "";
|
||||
archive:set_filename( archive:path() );
|
||||
end
|
||||
end;
|
||||
|
||||
function ArchivePrototype.static_depend( archive )
|
||||
local definition = archive.definition;
|
||||
if build.built_for_platform_and_variant(definition) then
|
||||
archive:add_dependency( Directory(branch(archive:get_filename())) );
|
||||
|
||||
for _, value in ipairs(definition) do
|
||||
if type(value) == "table" then
|
||||
assert( value.clone and type(value.clone) == "function", "Tables with integer keys in Archives must be clonable targets" );
|
||||
local target = value:clone();
|
||||
target.architecture = archive.architecture;
|
||||
target.module = archive.module;
|
||||
archive:add_dependency( target );
|
||||
end
|
||||
end
|
||||
end
|
||||
end;
|
||||
|
||||
function ArchivePrototype.build( archive )
|
||||
local definition = archive.definition;
|
||||
if archive:is_outdated() and build.built_for_platform_and_variant(definition) then
|
||||
build_library( archive, definition );
|
||||
end
|
||||
end;
|
||||
|
||||
function ArchivePrototype.clean( archive )
|
||||
local definition = archive.definition;
|
||||
if build.built_for_platform_and_variant(definition) then
|
||||
clean_library( archive, definition );
|
||||
end
|
||||
end;
|
||||
|
||||
function Archive( id, definition )
|
||||
assert( type(definition) == "table" );
|
||||
return target( id, ArchivePrototype, {definition = definition} );
|
||||
end
|
||||
|
|
@ -1,21 +1,24 @@
|
|||
|
||||
CcScanner = Scanner {
|
||||
[ [[^#include "([^"\n\r]*)"]] ] = function( target, match )
|
||||
local header = HeaderFile( target:directory()..match );
|
||||
local function local_include( target, match )
|
||||
local header = HeaderFile( "%s%s" % {target:directory(), match} );
|
||||
target:add_dependency( header );
|
||||
if header:get_bind_type() ~= BIND_INTERMEDIATE_FILE then
|
||||
scan( header, CcScanner );
|
||||
end
|
||||
end
|
||||
|
||||
local function global_include( target, match )
|
||||
local filename = root( "../%s" % match );
|
||||
if exists(filename) then
|
||||
local header = HeaderFile( filename );
|
||||
target:add_dependency( header );
|
||||
if header:get_bind_type() ~= BIND_INTERMEDIATE_FILE then
|
||||
scan( header, CcScanner );
|
||||
end
|
||||
end;
|
||||
end
|
||||
end
|
||||
|
||||
[ [[^#include <([^>\n\r]*)>]] ] = function( target, match )
|
||||
local filename = root( "../"..match );
|
||||
if exists(filename) then
|
||||
local header = HeaderFile( filename );
|
||||
target:add_dependency( header );
|
||||
if header:get_bind_type() ~= BIND_INTERMEDIATE_FILE then
|
||||
scan( header, CcScanner );
|
||||
end
|
||||
end
|
||||
end;
|
||||
CcScanner = Scanner {
|
||||
[ [[^#include "([^"\n\r]*)"]] ] = local_include;
|
||||
[ [[^#include <([^>\n\r]*)>]] ] = global_include;
|
||||
}
|
||||
|
|
|
|||
66
sweet/build/lua/build/Compile.lua
Normal file
66
sweet/build/lua/build/Compile.lua
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
|
||||
CompilePrototype = TargetPrototype { "Compile", BIND_PHONY };
|
||||
|
||||
function CompilePrototype.static_depend( compile )
|
||||
local definition = compile.definition;
|
||||
if build.built_for_platform_and_variant(definition) then
|
||||
local directory = Directory( obj_directory(definition) );
|
||||
|
||||
local pch = nil;
|
||||
-- if compile.pch then
|
||||
-- precompiled_header = PrecompiledHeader( obj_directory(compile)..obj_name(compile.pch) );
|
||||
-- precompiled_header.header = compile.pch;
|
||||
-- precompiled_header.unit = compile;
|
||||
-- precompiled_header:add_dependency( directory );
|
||||
-- compile:add_dependency( precompiled_header );
|
||||
-- compile.precompiled_header = precompiled_header;
|
||||
-- end
|
||||
|
||||
for _, value in ipairs(definition) do
|
||||
local source = SourceFile( value );
|
||||
source:set_required_to_exist( true );
|
||||
source.unit = compile;
|
||||
local object = File( "%s/%s" % {obj_directory(definition), obj_name(value, compile.architecture)} );
|
||||
object.source = value;
|
||||
source.object = object;
|
||||
object:add_dependency( source );
|
||||
object:add_dependency( directory );
|
||||
object:add_dependency( pch );
|
||||
compile:add_dependency( object );
|
||||
end
|
||||
end
|
||||
end;
|
||||
|
||||
function CompilePrototype.depend( compile )
|
||||
local definition = compile.definition;
|
||||
if build.built_for_platform_and_variant(definition) then
|
||||
for _, value in ipairs(definition) do
|
||||
local source = SourceFile( value );
|
||||
assert( source, "Failed to find source file '%s' for scanning" % tostring(value) );
|
||||
scan( source, CcScanner );
|
||||
end
|
||||
end
|
||||
end;
|
||||
|
||||
function CompilePrototype.build( compile )
|
||||
local definition = compile.definition;
|
||||
if compile:is_outdated() and build.built_for_platform_and_variant(definition) then
|
||||
cc( compile, definition );
|
||||
end
|
||||
end;
|
||||
|
||||
function CompilePrototype.clean( compile )
|
||||
local definition = compile.definition;
|
||||
if build.built_for_platform_and_variant(definition) then
|
||||
for dependency in compile:get_dependencies() do
|
||||
if dependency:prototype() == FilePrototype then
|
||||
rm( dependency:path() );
|
||||
end
|
||||
end
|
||||
end
|
||||
end;
|
||||
|
||||
function Compile( source )
|
||||
assert( type(source) == "table" and source:prototype() == SourcePrototype );
|
||||
return target( "", CompilePrototype, {definition = source} );
|
||||
end
|
||||
|
|
@ -1,8 +1,12 @@
|
|||
|
||||
Directory = Rule( "Directory", BIND_DIRECTORY );
|
||||
DirectoryPrototype = TargetPrototype { "Directory", BIND_DIRECTORY };
|
||||
|
||||
function Directory:build()
|
||||
if self:is_outdated() then
|
||||
mkdir( self:get_filename() );
|
||||
function DirectoryPrototype.build( directory )
|
||||
if directory:is_outdated() then
|
||||
mkdir( directory:get_filename() );
|
||||
end
|
||||
end
|
||||
|
||||
function Directory( directory )
|
||||
return target( directory, DirectoryPrototype );
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,39 +1,36 @@
|
|||
|
||||
DynamicLibrary = Rule( "DynamicLibrary", BIND_GENERATED_FILE );
|
||||
DynamicLibraryPrototype = TargetPrototype { "DynamicLibrary", BIND_PHONY };
|
||||
|
||||
function DynamicLibrary:load()
|
||||
load_module( self );
|
||||
self:set_filename( self.settings.bin.."/"..dll_name(self:id()) );
|
||||
end
|
||||
|
||||
function DynamicLibrary:static_depend()
|
||||
if built_for_platform_and_variant(self) then
|
||||
self:add_dependency( Directory(self.settings.lib) );
|
||||
self:add_dependency( Directory(self.settings.bin) );
|
||||
|
||||
local libraries = {};
|
||||
if self.libraries then
|
||||
for _, value in ipairs(self.libraries) do
|
||||
local library = find_target( root(value) );
|
||||
assert( library, "Failed to find library '"..value.."'" );
|
||||
if built_for_platform_and_variant(library) then
|
||||
table.insert( libraries, library );
|
||||
self:add_dependency( library );
|
||||
end
|
||||
end
|
||||
function DynamicLibraryPrototype.load_windows( dynamic_library )
|
||||
if build.load_target(dynamic_library) then
|
||||
if build.built_for_platform_and_variant(dynamic_library) then
|
||||
local link = Link( dll_name("%s/%s" % {dynamic_library.settings.bin, dynamic_library:id()}), dynamic_library );
|
||||
link.architecture = "";
|
||||
link.module = dynamic_library;
|
||||
link:add_dependency( Directory(dynamic_library.settings.lib) );
|
||||
dynamic_library:add_dependency( link );
|
||||
end
|
||||
self.libraries = libraries;
|
||||
end
|
||||
end
|
||||
|
||||
function DynamicLibrary:build()
|
||||
if self:is_outdated() and built_for_platform_and_variant(self) then
|
||||
build_executable( self );
|
||||
end
|
||||
end
|
||||
|
||||
function DynamicLibrary:clean()
|
||||
if built_for_platform_and_variant(self) then
|
||||
clean_executable( self );
|
||||
function DynamicLibraryPrototype.load_macosx( dynamic_library )
|
||||
if build.load_target(dynamic_library) then
|
||||
if build.built_for_platform_and_variant(dynamic_library) then
|
||||
local lipo = Lipo( dll_name("%s/%s" % {dynamic_library.settings.bin, dynamic_library:id()}), dynamic_library );
|
||||
lipo.module = dynamic_library;
|
||||
dynamic_library:add_dependency( lipo );
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function DynamicLibrary( dynamic_library )
|
||||
local id = dynamic_library.id;
|
||||
dynamic_library.id = nil;
|
||||
return target( id, DynamicLibraryPrototype, dynamic_library );
|
||||
end
|
||||
|
||||
if operating_system() == "macosx" then
|
||||
DynamicLibraryPrototype.load = DynamicLibraryPrototype.load_macosx;
|
||||
else
|
||||
DynamicLibraryPrototype.load = DynamicLibraryPrototype.load_windows;
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,43 +1,35 @@
|
|||
|
||||
Executable = Rule( "Executable", BIND_GENERATED_FILE );
|
||||
ExecutablePrototype = TargetPrototype { "Executable", BIND_PHONY };
|
||||
|
||||
function Executable:load()
|
||||
load_module( self );
|
||||
self:set_filename( self.settings.bin.."/"..exe_name(self:id()) );
|
||||
end
|
||||
|
||||
function Executable:static_depend()
|
||||
if built_for_platform_and_variant(self) then
|
||||
self:add_dependency( Directory(self.settings.bin) );
|
||||
|
||||
local libraries = {};
|
||||
if self.libraries then
|
||||
for _, value in ipairs(self.libraries) do
|
||||
local library = find_target( root(value) );
|
||||
assert( library, "Failed to find library '"..value.."'" );
|
||||
if built_for_platform_and_variant(library) then
|
||||
table.insert( libraries, library );
|
||||
self:add_dependency( library );
|
||||
end
|
||||
end
|
||||
function ExecutablePrototype.load_windows( executable )
|
||||
if build.load_target(executable) then
|
||||
if build.built_for_platform_and_variant(executable) then
|
||||
local link = Link( exe_name("%s/%s" % {executable.settings.bin, executable:id()}), executable );
|
||||
link.architecture = "";
|
||||
link.module = executable;
|
||||
executable:add_dependency( link );
|
||||
end
|
||||
self.libraries = libraries;
|
||||
end
|
||||
end
|
||||
|
||||
function Executable:build()
|
||||
if self:is_outdated() and built_for_platform_and_variant(self) then
|
||||
build_executable( self );
|
||||
function ExecutablePrototype.load_macosx( executable )
|
||||
if build.load_target(executable) then
|
||||
if build.built_for_platform_and_variant(executable) then
|
||||
local lipo = Lipo( exe_name("%s/%s" % {settings.bin, executable:id()}), executable );
|
||||
lipo.module = executable;
|
||||
executable:add_dependency( lipo );
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Executable:clean()
|
||||
if built_for_platform_and_variant(self) then
|
||||
clean_executable( self );
|
||||
end
|
||||
function Executable( executable )
|
||||
local id = executable.id;
|
||||
executable.id = nil;
|
||||
return target( id, ExecutablePrototype, executable );
|
||||
end
|
||||
|
||||
function Executable:project()
|
||||
generate_visual_studio_project( self );
|
||||
if operating_system() == "macosx" then
|
||||
ExecutablePrototype.load = ExecutablePrototype.load_macosx;
|
||||
else
|
||||
ExecutablePrototype.load = ExecutablePrototype.load_windows;
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,2 +1,9 @@
|
|||
|
||||
File = Rule( "File", BIND_GENERATED_FILE );
|
||||
FilePrototype = TargetPrototype {
|
||||
"File", BIND_GENERATED_FILE
|
||||
}
|
||||
|
||||
function File( file )
|
||||
assert( type(file) == "string" );
|
||||
return target( file, FilePrototype );
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,2 +1,9 @@
|
|||
|
||||
HeaderFile = Rule( "HeaderFile", BIND_SOURCE_FILE );
|
||||
HeaderFilePrototype = TargetPrototype {
|
||||
"HeaderFile", BIND_SOURCE_FILE
|
||||
}
|
||||
|
||||
function HeaderFile( header_file )
|
||||
assert( type(header_file) == "string" );
|
||||
return target( header_file, HeaderFilePrototype );
|
||||
end
|
||||
|
|
|
|||
63
sweet/build/lua/build/Link.lua
Normal file
63
sweet/build/lua/build/Link.lua
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
|
||||
LinkPrototype = TargetPrototype { "Link", BIND_GENERATED_FILE };
|
||||
|
||||
function LinkPrototype.load( link )
|
||||
local definition = link.definition;
|
||||
if build.built_for_platform_and_variant(definition) then
|
||||
link.architecture = link.architecture or "";
|
||||
link:set_filename( link:path() );
|
||||
end
|
||||
end;
|
||||
|
||||
function LinkPrototype.static_depend( link )
|
||||
local definition = link.definition;
|
||||
if build.built_for_platform_and_variant(definition) then
|
||||
link:add_dependency( Directory(branch(link:get_filename())) );
|
||||
|
||||
local libraries = {};
|
||||
if definition.libraries then
|
||||
for _, value in ipairs(definition.libraries) do
|
||||
local library = find_target( root(value) );
|
||||
assert( library, "Failed to find library '%s'" % value );
|
||||
if build.built_for_platform_and_variant(library) then
|
||||
for archive in library:get_dependencies() do
|
||||
if archive.architecture == link.architecture then
|
||||
table.insert( libraries, archive );
|
||||
link:add_dependency( archive );
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
link.libraries = libraries;
|
||||
|
||||
for _, value in ipairs(definition) do
|
||||
if type(value) == "table" then
|
||||
assert( value.clone and type(value.clone) == "function", "Tables with integer keys in Archives must be clonable targets" );
|
||||
local target = value:clone();
|
||||
target.architecture = link.architecture;
|
||||
target.module = link.module;
|
||||
link:add_dependency( target );
|
||||
end
|
||||
end
|
||||
end
|
||||
end;
|
||||
|
||||
function LinkPrototype.build( link )
|
||||
local definition = link.definition;
|
||||
if link:is_outdated() and build.built_for_platform_and_variant(definition) then
|
||||
build_executable( link, definition );
|
||||
end
|
||||
end;
|
||||
|
||||
function LinkPrototype.clean( link )
|
||||
local definition = link.definition;
|
||||
if build.built_for_platform_and_variant(definition) then
|
||||
clean_executable( link, definition );
|
||||
end
|
||||
end;
|
||||
|
||||
function Link( id, definition )
|
||||
assert( type(definition) == "table" );
|
||||
return target( id, LinkPrototype, {definition = definition} );
|
||||
end
|
||||
42
sweet/build/lua/build/Lipo.lua
Normal file
42
sweet/build/lua/build/Lipo.lua
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
|
||||
LipoPrototype = TargetPrototype { "Lipo", BIND_GENERATED_FILE };
|
||||
|
||||
function LipoPrototype.load( lipo )
|
||||
local definition = lipo.definition;
|
||||
if build.built_for_platform_and_variant(definition) then
|
||||
lipo:set_filename( lipo:path() );
|
||||
local architectures = definition.architectures or definition.settings.architectures;
|
||||
for _, architecture in ipairs(architectures) do
|
||||
local link = Link( "%s/%s_%s" % {definition.settings.obj, lipo:id(), architecture}, definition );
|
||||
link.architecture = architecture;
|
||||
link.module = lipo.module;
|
||||
lipo:add_dependency( link );
|
||||
end
|
||||
end
|
||||
end;
|
||||
|
||||
function LipoPrototype.static_depend( lipo )
|
||||
local definition = lipo.definition;
|
||||
if build.built_for_platform_and_variant(definition) then
|
||||
lipo:add_dependency( Directory(branch(lipo:get_filename())) );
|
||||
end
|
||||
end;
|
||||
|
||||
function LipoPrototype.build( lipo )
|
||||
local definition = lipo.definition;
|
||||
if lipo:is_outdated() and build.built_for_platform_and_variant(definition) then
|
||||
lipo_executable( lipo, definition );
|
||||
end
|
||||
end;
|
||||
|
||||
function LipoPrototype.clean( lipo )
|
||||
local definition = lipo.definition;
|
||||
if build.built_for_platform_and_variant(definition) then
|
||||
clean_executable( lipo );
|
||||
end
|
||||
end;
|
||||
|
||||
function Lipo( id, definition )
|
||||
assert( type(definition) == "table" );
|
||||
return target( id, LipoPrototype, {definition = definition} );
|
||||
end
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
|
||||
Parser = Rule( "Parser", BIND_PHONY );
|
||||
ParserPrototype = TargetPrototype { "Parser", BIND_PHONY };
|
||||
|
||||
function parser( settings )
|
||||
putenv( "LUA_PATH", settings.parser.lua_path );
|
||||
function ParserPrototype.clone( self )
|
||||
return self;
|
||||
end
|
||||
|
||||
function Parser:static_depend()
|
||||
if built_for_platform_and_variant(self) then
|
||||
function ParserPrototype.static_depend( self )
|
||||
if build.built_for_platform_and_variant(self) then
|
||||
for _, value in ipairs(self) do
|
||||
local grammar = SourceFile( value );
|
||||
grammar:set_required_to_exist( true );
|
||||
|
|
@ -21,8 +21,8 @@ function Parser:static_depend()
|
|||
end
|
||||
end
|
||||
|
||||
function Parser:build()
|
||||
if self:is_outdated() and built_for_platform_and_variant(self) then
|
||||
function ParserPrototype.build( self )
|
||||
if self:is_outdated() and build.built_for_platform_and_variant(self) then
|
||||
local parser = self.settings.parser.executable;
|
||||
for dependency in self:get_dependencies() do
|
||||
if dependency:is_outdated() then
|
||||
|
|
@ -36,12 +36,46 @@ function Parser:build()
|
|||
end
|
||||
end
|
||||
|
||||
function Parser:clean()
|
||||
if built_for_platform_and_variant(self) then
|
||||
function ParserPrototype.generate( self )
|
||||
self:build();
|
||||
end
|
||||
|
||||
function ParserPrototype.clean( self )
|
||||
if build.built_for_platform_and_variant(self) and exists(settings.parser.executable) then
|
||||
for dependency in self:get_dependencies() do
|
||||
if dependency:rule() == HeaderFile then
|
||||
if dependency:prototype() == HeaderFilePrototype then
|
||||
rm( dependency:path() );
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Parser( parser )
|
||||
assert( type(parser) == "table" );
|
||||
return target( "", ParserPrototype, parser );
|
||||
end
|
||||
|
||||
parser = {};
|
||||
|
||||
function parser.configure( settings )
|
||||
local local_settings = build.local_settings;
|
||||
if not local_settings.parser then
|
||||
local_settings.updated = true;
|
||||
if operating_system() == "windows" then
|
||||
local_settings.parser = {
|
||||
executable = "d:/usr/local/bin/parser.exe";
|
||||
lua_path = "d:/usr/local/lua/?.lua";
|
||||
};
|
||||
else
|
||||
local_settings.parser = {
|
||||
executable = "/usr/local/bin/parser.exe";
|
||||
lua_path = "/usr/local/lua/?.lua";
|
||||
};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function parser.initialize( settings )
|
||||
parser.configure( settings );
|
||||
putenv( "LUA_PATH", settings.parser.lua_path );
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,14 +1,21 @@
|
|||
|
||||
PrecompiledHeader = Rule( "PrecompiledHeader", BIND_GENERATED_FILE );
|
||||
PrecompiledHeaderPrototype = TargetPrototype {
|
||||
"PrecompiledHeader", BIND_GENERATED_FILE,
|
||||
|
||||
function PrecompiledHeader:depend()
|
||||
local source = SourceFile( cxx_name(self.header) );
|
||||
source:set_required_to_exist( true );
|
||||
source.unit = self.unit;
|
||||
source.object_file = self;
|
||||
scan( source, CcScanner );
|
||||
|
||||
self.source = source:id();
|
||||
self:add_dependency( source );
|
||||
self:add_dependency( directory );
|
||||
depend = function( self )
|
||||
local source = SourceFile( cxx_name(self.header) );
|
||||
source:set_required_to_exist( true );
|
||||
source.unit = self.unit;
|
||||
source.object_file = self;
|
||||
scan( source, CcScanner );
|
||||
|
||||
self.source = source:id();
|
||||
self:add_dependency( source );
|
||||
self:add_dependency( directory );
|
||||
end;
|
||||
}
|
||||
|
||||
function PrecompiledHeader( precompiled_header )
|
||||
assert( type(precompiled_header) == "string" );
|
||||
return target( precompiled_header, PrecompiledHeaderPrototype );
|
||||
end
|
||||
|
|
|
|||
11
sweet/build/lua/build/Source.lua
Normal file
11
sweet/build/lua/build/Source.lua
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
SourcePrototype = TargetPrototype { "Source", BIND_PHONY };
|
||||
|
||||
function SourcePrototype.clone( source )
|
||||
return Compile( source );
|
||||
end
|
||||
|
||||
function Source( source )
|
||||
assert( source == nil or type(source) == "table" );
|
||||
return target( "", SourcePrototype, source );
|
||||
end
|
||||
|
|
@ -1,2 +1,9 @@
|
|||
|
||||
SourceFile = Rule( "SourceFile", BIND_SOURCE_FILE );
|
||||
SourceFilePrototype = TargetPrototype {
|
||||
"SourceFile", BIND_SOURCE_FILE
|
||||
}
|
||||
|
||||
function SourceFile( source_file )
|
||||
assert( type(source_file) == "string" );
|
||||
return target( source_file, SourceFilePrototype );
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,25 +1,39 @@
|
|||
|
||||
StaticLibrary = Rule( "StaticLibrary", BIND_GENERATED_FILE );
|
||||
StaticLibraryPrototype = TargetPrototype { "StaticLibrary", BIND_PHONY };
|
||||
|
||||
function StaticLibrary:load()
|
||||
load_module( self );
|
||||
self:set_filename( self.settings.lib.."/"..lib_name(self:id()) );
|
||||
end
|
||||
|
||||
function StaticLibrary:static_depend()
|
||||
if built_for_platform_and_variant(self) then
|
||||
self:add_dependency( Directory(self.settings.lib) );
|
||||
function StaticLibraryPrototype.load_windows( static_library )
|
||||
if build.load_target(static_library) then
|
||||
if build.built_for_platform_and_variant(static_library) then
|
||||
local archive = Archive( "%s/%s" % {static_library.settings.lib, lib_name(static_library:id())}, static_library );
|
||||
archive.architecture = "";
|
||||
archive.module = static_library;
|
||||
static_library:add_dependency( archive );
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function StaticLibrary:build()
|
||||
if self:is_outdated() and built_for_platform_and_variant(self) then
|
||||
build_library( self );
|
||||
end
|
||||
end
|
||||
|
||||
function StaticLibrary:clean()
|
||||
if built_for_platform_and_variant(self) then
|
||||
clean_library( self );
|
||||
function StaticLibraryPrototype.load_macosx( static_library )
|
||||
if build.load_target(static_library) then
|
||||
if build.built_for_platform_and_variant(static_library) then
|
||||
local architectures = static_library.architectures or static_library.settings.architectures;
|
||||
for _, architecture in ipairs(architectures) do
|
||||
local archive = Archive( "%s/%s" % {static_library.settings.lib, lib_name("%s_%s" % {static_library:id(), architecture})}, static_library );
|
||||
archive.architecture = architecture;
|
||||
archive.module = static_library;
|
||||
static_library:add_dependency( archive );
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function StaticLibrary( static_library )
|
||||
local id = static_library.id;
|
||||
static_library.id = nil;
|
||||
return target( id, StaticLibraryPrototype, static_library );
|
||||
end
|
||||
|
||||
if operating_system() == "macosx" then
|
||||
StaticLibraryPrototype.load = StaticLibraryPrototype.load_macosx;
|
||||
else
|
||||
StaticLibraryPrototype.load = StaticLibraryPrototype.load_windows;
|
||||
end
|
||||
|
|
|
|||
83
sweet/build/lua/build/boost.lua
Normal file
83
sweet/build/lua/build/boost.lua
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
|
||||
boost = {};
|
||||
|
||||
function boost.configure( settings )
|
||||
local local_settings = build.local_settings;
|
||||
if not local_settings.boost then
|
||||
local_settings.updated = true;
|
||||
local_settings.boost = {
|
||||
boost_directory = "";
|
||||
version = "1.43";
|
||||
};
|
||||
if operating_system() == "windows" then
|
||||
local_settings.boost.boost_directory = "C:/boost";
|
||||
else
|
||||
local_settings.boost.boost_directory = home( "boost" );
|
||||
end
|
||||
end
|
||||
end;
|
||||
|
||||
function boost.initialize( settings )
|
||||
boost.configure(settings);
|
||||
local boost_library_by_platform = {
|
||||
llvmgcc = boost.llvmgcc_boost_library;
|
||||
msvc = boost.msvc_boost_library;
|
||||
mingw = boost.mingw_boost_library;
|
||||
};
|
||||
assert( boost_library_by_platform[platform], "No boost_library() implementation for the platform '%s'!" % platform );
|
||||
boost_library = boost_library_by_platform[platform];
|
||||
end;
|
||||
|
||||
function boost.msvc_boost_library( name )
|
||||
local toolset = "vc90";
|
||||
local runtime;
|
||||
local version = string.gsub( settings.boost.version, "%.", "_" );
|
||||
|
||||
if settings.runtime_library == "static" then
|
||||
runtime = "mt-s";
|
||||
elseif settings.runtime_library == "static_debug" then
|
||||
runtime = "mt-sgd";
|
||||
elseif settings.runtime_library == "dynamic" then
|
||||
runtime = "mt";
|
||||
elseif settings.runtime_library == "dynamic_debug" then
|
||||
runtime = "mt-gd";
|
||||
end
|
||||
|
||||
return "lib%s-%s-%s-%s.lib" % { name, toolset, runtime, version };
|
||||
end;
|
||||
|
||||
function boost.mingw_boost_library( name )
|
||||
local toolset = "mgw46";
|
||||
local runtime;
|
||||
local version = string.gsub( settings.boost.version, "%.", "_" );
|
||||
|
||||
if settings.runtime_library == "static" then
|
||||
runtime = "mt-s";
|
||||
elseif settings.runtime_library == "static_debug" then
|
||||
runtime = "mt-sd";
|
||||
elseif settings.runtime_library == "dynamic" then
|
||||
runtime = "mt";
|
||||
elseif settings.runtime_library == "dynamic_debug" then
|
||||
runtime = "mt-d";
|
||||
end
|
||||
|
||||
return "%s-%s-%s-%s" % { name, toolset, runtime, version };
|
||||
end;
|
||||
|
||||
function boost.llvmgcc_boost_library( name )
|
||||
local toolset = "xgcc42";
|
||||
local runtime;
|
||||
local version = string.gsub( settings.boost.version, "%.", "_" );
|
||||
|
||||
if settings.runtime_library == "static" then
|
||||
runtime = "mt-s";
|
||||
elseif settings.runtime_library == "static_debug" then
|
||||
runtime = "mt-sd";
|
||||
elseif settings.runtime_library == "dynamic" then
|
||||
runtime = "mt";
|
||||
elseif settings.runtime_library == "dynamic_debug" then
|
||||
runtime = "mt-d";
|
||||
end
|
||||
|
||||
return "%s-%s-%s-%s" % { name, toolset, runtime, version };
|
||||
end;
|
||||
86
sweet/build/lua/build/commands.lua
Normal file
86
sweet/build/lua/build/commands.lua
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
|
||||
function default()
|
||||
build.load();
|
||||
local all = all or find_target( initial(goal) );
|
||||
assert( all, "No target found at '"..tostring(initial(goal)).."'" );
|
||||
postorder( build.visit("build"), all );
|
||||
build.save();
|
||||
print( "build: default (build)=%sms" % tostring(math.ceil(ticks())) );
|
||||
end
|
||||
|
||||
function clean()
|
||||
build.load();
|
||||
local all = all or find_target( initial(goal) );
|
||||
assert( all, "No target found at '"..tostring(initial(goal)).."'" );
|
||||
postorder( build.visit("clean"), all );
|
||||
rm( settings.cache );
|
||||
print( "build: clean=%sms" % tostring(math.ceil(ticks())) );
|
||||
end
|
||||
|
||||
function generate()
|
||||
build.load();
|
||||
local all = all or find_target( initial(goal) );
|
||||
assert( all, "No target found at '"..tostring(initial(goal)).."'" );
|
||||
postorder( build.visit("generate"), all );
|
||||
print( "build: generate=%sms" % tostring(math.ceil(ticks())) );
|
||||
end
|
||||
|
||||
function compile()
|
||||
assert( source, "The 'source' variable must be specified for the 'compile' command" );
|
||||
local source_file = find_target( initial(source) );
|
||||
assert( source_file, "No compilable source file found at '"..initial(source).."'" );
|
||||
local object_file = source_file.object;
|
||||
assert( object_file, "No object file found at '"..obj_directory(source_file.unit)..obj_name(source_file:id()).."'" );
|
||||
local unit = source_file.unit;
|
||||
for dependency in unit:get_dependencies() do
|
||||
if dependency:prototype() == FilePrototype and dependency ~= unit.precompiled_header then
|
||||
dependency:set_outdated( false );
|
||||
end
|
||||
end
|
||||
unit:set_outdated( true );
|
||||
object_file:set_outdated( true );
|
||||
postorder( build.visit("build"), unit );
|
||||
end
|
||||
|
||||
function reconfigure()
|
||||
build.load();
|
||||
rm( build.settings.local_settings_filename );
|
||||
build.load();
|
||||
build.save();
|
||||
end
|
||||
|
||||
function dependencies()
|
||||
build.load();
|
||||
local all = all or find_target( initial(goal) );
|
||||
assert( all, "No target found at '"..tostring(initial(goal)).."'" );
|
||||
print_dependencies( all );
|
||||
end
|
||||
|
||||
function namespace()
|
||||
build.load();
|
||||
local all = all or find_target( initial(goal) );
|
||||
assert( all, "No target found at '"..tostring(initial(goal)).."'" );
|
||||
print_namespace( all );
|
||||
end
|
||||
|
||||
function install()
|
||||
local platforms = build.switch {
|
||||
operating_system();
|
||||
windows = { "msvc" };
|
||||
macosx = { "llvmgcc" };
|
||||
};
|
||||
|
||||
local variants = build.switch {
|
||||
operating_system();
|
||||
windows = { "debug", "debug_dll", "release", "release_dll", "shipping", "shipping_dll" };
|
||||
macosx = { "debug", "release", "shipping" };
|
||||
};
|
||||
|
||||
for _, platform in ipairs(platforms) do
|
||||
for _, variant in ipairs(variants) do
|
||||
_G.platform = platform;
|
||||
_G.variant = variant;
|
||||
default();
|
||||
end
|
||||
end
|
||||
end
|
||||
207
sweet/build/lua/build/default_settings.lua
Normal file
207
sweet/build/lua/build/default_settings.lua
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
|
||||
return {
|
||||
bin = root();
|
||||
lib = root();
|
||||
obj = root();
|
||||
root = root();
|
||||
|
||||
user_settings_filename = home( "user_settings.lua" );
|
||||
|
||||
local_settings_filename = root( "local_settings.lua" );
|
||||
|
||||
include_directories = {
|
||||
};
|
||||
|
||||
library_directories = {
|
||||
};
|
||||
|
||||
platforms = build.switch {
|
||||
operating_system();
|
||||
windows = { "msvc", "mingw" };
|
||||
macosx = { "llvmgcc" };
|
||||
};
|
||||
|
||||
variants = {
|
||||
};
|
||||
|
||||
settings_by_platform = {
|
||||
["llvmgcc"] = {
|
||||
architectures = {
|
||||
"x86_64"
|
||||
};
|
||||
variants = {
|
||||
"debug", "release", "shipping"
|
||||
};
|
||||
};
|
||||
|
||||
["mingw"] = {
|
||||
architectures = {
|
||||
"x86_64"
|
||||
};
|
||||
variants = {
|
||||
"debug", "debug_dll", "release", "release_dll", "shipping", "shipping_dll"
|
||||
};
|
||||
};
|
||||
|
||||
["msvc"] = {
|
||||
architectures = {
|
||||
"x86_64"
|
||||
};
|
||||
variants = {
|
||||
"debug", "debug_dll", "release", "release_dll", "shipping", "shipping_dll"
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
settings_by_variant = {
|
||||
["debug"] = {
|
||||
compile_as_c = false;
|
||||
debug = true;
|
||||
exceptions = true;
|
||||
fast_floating_point = false;
|
||||
generate_map_file = true;
|
||||
incremental_linking = true;
|
||||
library_type = "static";
|
||||
link_time_code_generation = false;
|
||||
minimal_rebuild = true;
|
||||
optimization = false;
|
||||
pre_compiled_headers = true;
|
||||
preprocess = false;
|
||||
profiling = false;
|
||||
run_time_checks = true;
|
||||
runtime_library = "static_debug";
|
||||
run_time_type_info = true;
|
||||
sse2 = true;
|
||||
stack_size = 1048576;
|
||||
string_pooling = false;
|
||||
strip = false;
|
||||
subsystem = "CONSOLE";
|
||||
verbose_linking = false;
|
||||
};
|
||||
|
||||
["debug_dll"] = {
|
||||
compile_as_c = false;
|
||||
debug = true;
|
||||
exceptions = true;
|
||||
fast_floating_point = false;
|
||||
generate_map_file = true;
|
||||
incremental_linking = true;
|
||||
library_type = "dynamic";
|
||||
link_time_code_generation = false;
|
||||
minimal_rebuild = true;
|
||||
optimization = false;
|
||||
pre_compiled_headers = true;
|
||||
preprocess = false;
|
||||
profiling = false;
|
||||
run_time_checks = true;
|
||||
runtime_library = "dynamic_debug";
|
||||
run_time_type_info = true;
|
||||
sse2 = true;
|
||||
stack_size = 1048576;
|
||||
string_pooling = false;
|
||||
strip = false;
|
||||
subsystem = "CONSOLE";
|
||||
verbose_linking = false;
|
||||
};
|
||||
|
||||
["release"] = {
|
||||
compile_as_c = false;
|
||||
debug = true;
|
||||
exceptions = true;
|
||||
fast_floating_point = true;
|
||||
generate_map_file = true;
|
||||
incremental_linking = false;
|
||||
library_type = "static";
|
||||
link_time_code_generation = true;
|
||||
minimal_rebuild = false;
|
||||
optimization = true;
|
||||
pre_compiled_headers = true;
|
||||
preprocess = false;
|
||||
profiling = false;
|
||||
run_time_checks = false;
|
||||
runtime_library = "static";
|
||||
run_time_type_info = true;
|
||||
sse2 = true;
|
||||
stack_size = 1048576;
|
||||
string_pooling = false;
|
||||
strip = false;
|
||||
subsystem = "CONSOLE";
|
||||
verbose_linking = false;
|
||||
};
|
||||
|
||||
["release_dll"] = {
|
||||
compile_as_c = false;
|
||||
debug = true;
|
||||
exceptions = true;
|
||||
fast_floating_point = true;
|
||||
generate_map_file = true;
|
||||
incremental_linking = false;
|
||||
library_type = "dynamic";
|
||||
link_time_code_generation = true;
|
||||
minimal_rebuild = false;
|
||||
optimization = true;
|
||||
pre_compiled_headers = true;
|
||||
preprocess = false;
|
||||
profiling = false;
|
||||
run_time_checks = false;
|
||||
runtime_library = "dynamic";
|
||||
run_time_type_info = true;
|
||||
sse2 = true;
|
||||
stack_size = 1048576;
|
||||
string_pooling = false;
|
||||
strip = false;
|
||||
subsystem = "CONSOLE";
|
||||
verbose_linking = false;
|
||||
};
|
||||
|
||||
["shipping"] = {
|
||||
compile_as_c = false;
|
||||
debug = true;
|
||||
exceptions = true;
|
||||
fast_floating_point = true;
|
||||
generate_map_file = true;
|
||||
incremental_linking = false;
|
||||
library_type = "static";
|
||||
link_time_code_generation = true;
|
||||
minimal_rebuild = false;
|
||||
optimization = true;
|
||||
pre_compiled_headers = true;
|
||||
preprocess = false;
|
||||
profiling = true;
|
||||
run_time_checks = false;
|
||||
runtime_library = "static";
|
||||
run_time_type_info = true;
|
||||
sse2 = true;
|
||||
stack_size = 1048576;
|
||||
string_pooling = false;
|
||||
strip = true;
|
||||
subsystem = "CONSOLE";
|
||||
verbose_linking = false;
|
||||
};
|
||||
|
||||
["shipping_dll"] = {
|
||||
compile_as_c = false;
|
||||
debug = true;
|
||||
exceptions = true;
|
||||
fast_floating_point = true;
|
||||
generate_map_file = true;
|
||||
incremental_linking = false;
|
||||
library_type = "dynamic";
|
||||
link_time_code_generation = true;
|
||||
minimal_rebuild = false;
|
||||
optimization = true;
|
||||
pre_compiled_headers = true;
|
||||
preprocess = false;
|
||||
profiling = true;
|
||||
run_time_checks = false;
|
||||
runtime_library = "dynamic";
|
||||
run_time_type_info = true;
|
||||
sse2 = true;
|
||||
stack_size = 1048576;
|
||||
string_pooling = false;
|
||||
strip = true;
|
||||
subsystem = "CONSOLE";
|
||||
verbose_linking = false;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -1,21 +1,4 @@
|
|||
|
||||
require "build/Cc";
|
||||
require "build/Parser";
|
||||
require "build/File";
|
||||
require "build/SourceFile";
|
||||
require "build/HeaderFile";
|
||||
require "build/PrecompiledHeader";
|
||||
require "build/Directory";
|
||||
require "build/StaticLibrary";
|
||||
require "build/DynamicLibrary";
|
||||
require "build/Executable";
|
||||
require "build/CcScanner";
|
||||
require "build/QtMoc";
|
||||
require "build/AsciiDoc";
|
||||
require "build/Project";
|
||||
require "build/msvc";
|
||||
require "build/visual_studio";
|
||||
|
||||
-- Provide python like syntax for string interpolation.
|
||||
getmetatable("").__mod = function( format, args )
|
||||
if args then
|
||||
|
|
@ -29,199 +12,61 @@ getmetatable("").__mod = function( format, args )
|
|||
end
|
||||
end
|
||||
|
||||
-- Setup the build system.
|
||||
function setup( settings )
|
||||
command = command or "build";
|
||||
platform = platform or "msvc";
|
||||
source = source or "";
|
||||
target = target or "";
|
||||
require "build/File";
|
||||
require "build/SourceFile";
|
||||
require "build/HeaderFile";
|
||||
require "build/PrecompiledHeader";
|
||||
require "build/Directory";
|
||||
require "build/Compile";
|
||||
require "build/Archive";
|
||||
require "build/Link";
|
||||
require "build/Lipo";
|
||||
require "build/Source";
|
||||
require "build/StaticLibrary";
|
||||
require "build/DynamicLibrary";
|
||||
require "build/Executable";
|
||||
require "build/CcScanner";
|
||||
require "build/commands";
|
||||
|
||||
build = {};
|
||||
|
||||
-- Perform per run initialization of the build system.
|
||||
function build.initialize( project_settings )
|
||||
platform = platform or build.switch { operating_system(); windows = "msvc"; macosx = "llvmgcc" };
|
||||
variant = variant or "debug";
|
||||
version = version or os.date( "%Y.%m.%d %H:%M:%S "..platform.." "..variant );
|
||||
version = version or "%s %s %s" % { os.date("%Y.%m.%d %H:%M:%S"), platform, variant };
|
||||
goal = goal or "";
|
||||
jobs = jobs or 4;
|
||||
|
||||
set_maximum_parallel_jobs( jobs );
|
||||
|
||||
local default_settings = {
|
||||
bin = root();
|
||||
lib = root();
|
||||
obj = root();
|
||||
local default_settings = build.default_settings;
|
||||
build.merge_settings( default_settings, project_settings );
|
||||
|
||||
msvc = {
|
||||
visual_studio_directory = autodetect_visual_studio_directory() or "C:/Program Files/Microsoft Visual Studio 9.0";
|
||||
windows_sdk_directory = autodetect_windows_sdk_directory() or "C:/Program Files/Microsoft SDKs/Windows/v6.0A";
|
||||
};
|
||||
local local_settings = {};
|
||||
setmetatable( local_settings, {__index = default_settings} );
|
||||
|
||||
parser = {
|
||||
executable = "d:/usr/local/bin/parser.exe";
|
||||
lua_path = "d:/usr/local/lua/?.lua";
|
||||
};
|
||||
|
||||
python = {
|
||||
executable = "c:/Python26/python.exe";
|
||||
};
|
||||
|
||||
asciidoc = {
|
||||
executable = "c:/asciidoc/asciidoc.py";
|
||||
conf_file = root( "build/lua/build/sweet.conf" );
|
||||
};
|
||||
|
||||
include_directories = {
|
||||
};
|
||||
|
||||
library_directories = {
|
||||
};
|
||||
|
||||
platforms = {
|
||||
"msvc"
|
||||
};
|
||||
|
||||
variants = {
|
||||
["debug"] = {
|
||||
compile_as_c = false;
|
||||
debug = true;
|
||||
exceptions = true;
|
||||
generate_map_file = true;
|
||||
incremental_linking = true;
|
||||
library_type = "static";
|
||||
link_time_code_generation = false;
|
||||
minimal_rebuild = true;
|
||||
optimization = false;
|
||||
pre_compiled_headers = true;
|
||||
preprocess = false;
|
||||
profiling = false;
|
||||
run_time_checks = true;
|
||||
runtime_library = "static_debug";
|
||||
run_time_type_info = true;
|
||||
stack_size = 1048576;
|
||||
string_pooling = false;
|
||||
subsystem = "CONSOLE";
|
||||
verbose_linking = false;
|
||||
};
|
||||
|
||||
["debug_dll"] = {
|
||||
compile_as_c = false;
|
||||
debug = true;
|
||||
exceptions = true;
|
||||
generate_map_file = true;
|
||||
incremental_linking = true;
|
||||
library_type = "dynamic";
|
||||
link_time_code_generation = false;
|
||||
minimal_rebuild = true;
|
||||
optimization = false;
|
||||
pre_compiled_headers = true;
|
||||
preprocess = false;
|
||||
profiling = false;
|
||||
run_time_checks = true;
|
||||
runtime_library = "dynamic_debug";
|
||||
run_time_type_info = true;
|
||||
stack_size = 1048576;
|
||||
string_pooling = false;
|
||||
subsystem = "CONSOLE";
|
||||
verbose_linking = false;
|
||||
};
|
||||
|
||||
["release"] = {
|
||||
compile_as_c = false;
|
||||
debug = true;
|
||||
exceptions = true;
|
||||
generate_map_file = true;
|
||||
incremental_linking = false;
|
||||
library_type = "static";
|
||||
link_time_code_generation = true;
|
||||
minimal_rebuild = false;
|
||||
optimization = true;
|
||||
pre_compiled_headers = true;
|
||||
preprocess = false;
|
||||
profiling = false;
|
||||
run_time_checks = false;
|
||||
runtime_library = "static";
|
||||
run_time_type_info = true;
|
||||
stack_size = 1048576;
|
||||
string_pooling = false;
|
||||
subsystem = "CONSOLE";
|
||||
verbose_linking = false;
|
||||
};
|
||||
|
||||
["release_dll"] = {
|
||||
compile_as_c = false;
|
||||
debug = true;
|
||||
exceptions = true;
|
||||
generate_map_file = true;
|
||||
incremental_linking = false;
|
||||
library_type = "dynamic";
|
||||
link_time_code_generation = true;
|
||||
minimal_rebuild = false;
|
||||
optimization = true;
|
||||
pre_compiled_headers = true;
|
||||
preprocess = false;
|
||||
profiling = false;
|
||||
run_time_checks = false;
|
||||
runtime_library = "dynamic";
|
||||
run_time_type_info = true;
|
||||
stack_size = 1048576;
|
||||
string_pooling = false;
|
||||
subsystem = "CONSOLE";
|
||||
verbose_linking = false;
|
||||
};
|
||||
|
||||
["shipping"] = {
|
||||
compile_as_c = false;
|
||||
debug = true;
|
||||
exceptions = true;
|
||||
generate_map_file = true;
|
||||
incremental_linking = false;
|
||||
library_type = "static";
|
||||
link_time_code_generation = true;
|
||||
minimal_rebuild = false;
|
||||
optimization = true;
|
||||
pre_compiled_headers = true;
|
||||
preprocess = false;
|
||||
profiling = true;
|
||||
run_time_checks = false;
|
||||
runtime_library = "static";
|
||||
run_time_type_info = true;
|
||||
stack_size = 1048576;
|
||||
string_pooling = false;
|
||||
subsystem = "CONSOLE";
|
||||
verbose_linking = false;
|
||||
};
|
||||
|
||||
["shipping_dll"] = {
|
||||
compile_as_c = false;
|
||||
debug = true;
|
||||
exceptions = true;
|
||||
generate_map_file = true;
|
||||
incremental_linking = false;
|
||||
library_type = "dynamic";
|
||||
link_time_code_generation = true;
|
||||
minimal_rebuild = false;
|
||||
optimization = true;
|
||||
pre_compiled_headers = true;
|
||||
preprocess = false;
|
||||
profiling = true;
|
||||
run_time_checks = false;
|
||||
runtime_library = "dynamic";
|
||||
run_time_type_info = true;
|
||||
stack_size = 1048576;
|
||||
string_pooling = false;
|
||||
subsystem = "CONSOLE";
|
||||
verbose_linking = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
if settings then
|
||||
setmetatable( settings, {__index = default_settings} );
|
||||
else
|
||||
settings = default_settings;
|
||||
local user_settings_filename = default_settings.user_settings_filename;
|
||||
if exists(user_settings_filename) then
|
||||
build.merge_settings( local_settings, dofile(user_settings_filename) );
|
||||
end
|
||||
|
||||
local variant_settings = settings.variants[variant];
|
||||
assert( variant_settings, "The variant '"..tostring(variant).."' is not supported" );
|
||||
for key, value in pairs(variant_settings) do
|
||||
settings[key] = value;
|
||||
local local_settings_filename = default_settings.local_settings_filename;
|
||||
if exists(local_settings_filename) then
|
||||
build.merge_settings( local_settings, dofile(local_settings_filename) );
|
||||
end
|
||||
|
||||
local settings = {};
|
||||
setmetatable( settings, {__index = local_settings} );
|
||||
|
||||
local platform_settings = settings.settings_by_platform[platform];
|
||||
assert( platform_settings, "The platform '%s' is not supported" % platform );
|
||||
build.merge_settings( settings, platform_settings );
|
||||
|
||||
local variant_settings = settings.settings_by_variant[variant];
|
||||
assert( variant_settings, "The variant '%s' is not supported" % variant );
|
||||
build.merge_settings( settings, variant_settings );
|
||||
|
||||
if settings.library_type == "static" then
|
||||
Library = StaticLibrary;
|
||||
elseif settings.library_type == "dynamic" then
|
||||
|
|
@ -230,70 +75,16 @@ function setup( settings )
|
|||
error( string.format("The library type '%s' is not 'static' or 'dynamic'", settings.library_type) );
|
||||
end
|
||||
|
||||
default_settings.root = root();
|
||||
default_settings.cache = root( "%s/%s_%s.cache" % {settings.obj, platform, variant} );
|
||||
|
||||
load_binary( settings.cache, initial(target) );
|
||||
build.default_settings.cache = root( "%s/%s_%s.cache" % {settings.obj, platform, variant} );
|
||||
_G.settings = settings;
|
||||
end
|
||||
|
||||
function build()
|
||||
local total_start = 0;
|
||||
|
||||
parser( settings );
|
||||
msvc( settings );
|
||||
|
||||
local load_start = ticks();
|
||||
load_project( project );
|
||||
local load_finish = ticks();
|
||||
|
||||
local bind_start = ticks();
|
||||
local all = find_target( initial(target) );
|
||||
assert( all, "No target found at '"..tostring(initial(target)).."'" );
|
||||
preorder( visit("depend"), all );
|
||||
bind( all );
|
||||
local bind_finish = ticks();
|
||||
|
||||
local build_start = ticks();
|
||||
if command == "build" then
|
||||
postorder( visit("build"), all );
|
||||
elseif command == "generate" then
|
||||
postorder( visit("generate"), all );
|
||||
elseif command == "document" then
|
||||
postorder( visit("document"), all );
|
||||
elseif command == "clean" then
|
||||
postorder( visit("clean"), all );
|
||||
rm( settings.cache );
|
||||
elseif command == "compile" then
|
||||
compile( source );
|
||||
elseif command == "projects" then
|
||||
postorder( visit("projects"), all );
|
||||
elseif command == "dependencies" then
|
||||
print_dependencies( all );
|
||||
elseif command == "namespace" then
|
||||
print_namespace( all );
|
||||
end
|
||||
local build_finish = ticks();
|
||||
|
||||
local save_start = ticks();
|
||||
if command == "build" then
|
||||
mkdir( branch(settings.cache) );
|
||||
save_binary( settings.cache );
|
||||
end
|
||||
local save_finish = ticks();
|
||||
|
||||
local total_finish = ticks();
|
||||
local load_time = load_finish - load_start;
|
||||
local bind_time = bind_finish - bind_start;
|
||||
local build_time = build_finish - build_start;
|
||||
local save_time = save_finish - save_start;
|
||||
local total_time = total_finish - total_start;
|
||||
local unknown_time = total_time - (load_time + bind_time + build_time + save_time);
|
||||
print( "build: load="..tostring(load_time).."ms, bind="..tostring(bind_time).."ms, build="..tostring(build_time).."ms, save="..tostring(save_time).."ms, unknown="..tostring(unknown_time).."ms, total="..tostring(total_time).."ms" );
|
||||
build.default_settings = default_settings;
|
||||
build.local_settings = local_settings;
|
||||
build.settings = settings;
|
||||
return settings;
|
||||
end
|
||||
|
||||
-- Visit a target by calling a member function /pass/ if it has one.
|
||||
function visit( pass, ... )
|
||||
function build.visit( pass, ... )
|
||||
local args = {...};
|
||||
return function( target )
|
||||
local fn = target[pass];
|
||||
|
|
@ -309,7 +100,7 @@ end
|
|||
--
|
||||
-- @return
|
||||
-- True if \e target should be built otherwise false.
|
||||
function built_for_platform_and_variant( target )
|
||||
function build.built_for_platform_and_variant( target )
|
||||
function contains( value, values )
|
||||
for _, v in ipairs(values) do
|
||||
if v == value then
|
||||
|
|
@ -318,36 +109,24 @@ function built_for_platform_and_variant( target )
|
|||
end
|
||||
return false;
|
||||
end
|
||||
return (target.settings.platforms == nil or contains(platform, target.settings.platforms)) and (target.settings.variants == nil or target.settings.variants[variant]);
|
||||
end
|
||||
|
||||
-- Compile the single source file /source/ in /graph/.
|
||||
function compile( source )
|
||||
local source_file = find_target( initial(source) );
|
||||
assert( source_file, "No compilable source file found at '"..initial(source).."'" );
|
||||
local object_file = source_file.object;
|
||||
assert( object_file, "No object file found at '"..obj_directory(source_file.unit)..obj_name(source_file:id()).."'" );
|
||||
local unit = source_file.unit;
|
||||
for dependency in unit:get_dependencies() do
|
||||
if dependency:rule() == File and dependency ~= unit.precompiled_header then
|
||||
dependency:set_outdated( false );
|
||||
end
|
||||
end
|
||||
unit:set_outdated( true );
|
||||
object_file:set_outdated( true );
|
||||
postorder( visit("build"), unit );
|
||||
return (target.settings.platforms == nil or contains(platform, target.settings.platforms)) and (target.settings.variants == nil or contains(variant, target.settings.variants));
|
||||
end
|
||||
|
||||
-- Execute command with arguments and optional filter and raise an error if
|
||||
-- it doesn't return 0.
|
||||
function system( command, arguments, filter )
|
||||
function build.system( command, arguments, filter )
|
||||
if execute(command, arguments, filter) ~= 0 then
|
||||
error( arguments.." failed" );
|
||||
error( arguments.." failed", 0 );
|
||||
end
|
||||
end
|
||||
|
||||
-- Return a value from a table using the first key as a lookup.
|
||||
function build.switch( values )
|
||||
return values[values[1]];
|
||||
end
|
||||
|
||||
-- Dump the keys, values, and prototype of a table for debugging.
|
||||
function dump( t )
|
||||
function build.dump( t )
|
||||
print( tostring(t) );
|
||||
if t ~= nil then
|
||||
if getmetatable(t) ~= nil then
|
||||
|
|
@ -359,64 +138,151 @@ function dump( t )
|
|||
end
|
||||
end
|
||||
|
||||
-- Load a project.
|
||||
function load_project( project )
|
||||
local root_target = find_target( root() );
|
||||
assert( root_target , "No root target found at '"..tostring(root()).."'" );
|
||||
if not root_target.loaded then
|
||||
root_target.loaded = true;
|
||||
preorder( visit("load"), root_target );
|
||||
preorder( visit("static_depend"), root_target );
|
||||
|
||||
local cache = find_target( settings.cache );
|
||||
cache.loaded = true;
|
||||
cache:add_dependency( SourceFile("build.lua") );
|
||||
cache:add_dependency( SourceFile("build/lua/build/Cc.lua") );
|
||||
cache:add_dependency( SourceFile("build/lua/build/CcScanner.lua") );
|
||||
cache:add_dependency( SourceFile("build/lua/build/settings.lua") );
|
||||
cache:add_dependency( SourceFile("build/lua/build/Directory.lua") );
|
||||
cache:add_dependency( SourceFile("build/lua/build/Executable.lua") );
|
||||
cache:add_dependency( SourceFile("build/lua/build/File.lua") );
|
||||
cache:add_dependency( SourceFile("build/lua/build/HeaderFile.lua") );
|
||||
cache:add_dependency( SourceFile("build/lua/build/init.lua") );
|
||||
cache:add_dependency( SourceFile("build/lua/build/StaticLibrary.lua") );
|
||||
cache:add_dependency( SourceFile("build/lua/build/DynamicLibrary.lua") );
|
||||
cache:add_dependency( SourceFile("build/lua/build/Parser.lua") );
|
||||
cache:add_dependency( SourceFile("build/lua/build/Project.lua") );
|
||||
cache:add_dependency( SourceFile("build/lua/build/SourceFile.lua") );
|
||||
cache:add_dependency( SourceFile("build/lua/build/QtMoc.lua") );
|
||||
cache:add_dependency( SourceFile("build/lua/build/AsciiDoc.lua") );
|
||||
cache:add_dependency( SourceFile("build/lua/build/msvc.lua") );
|
||||
cache:add_dependency( SourceFile("build/lua/build/visual_studio.lua") );
|
||||
local user_settings = home( "user_settings.lua" );
|
||||
if exists(user_settings) then
|
||||
cache:add_dependency( SourceFile(user_settings) );
|
||||
-- Serialize values to to a Lua file (typically the local settings table).
|
||||
function build.serialize( file, value, level )
|
||||
local function indent( level )
|
||||
for i = 0, level - 1 do
|
||||
file:write( " " );
|
||||
end
|
||||
end
|
||||
|
||||
if type(value) == "boolean" then
|
||||
file:write( tostring(value) );
|
||||
elseif type(value) == "number" then
|
||||
file:write( value );
|
||||
elseif type(value) == "string" then
|
||||
file:write( string.format("%q", value) );
|
||||
elseif type(value) == "table" then
|
||||
file:write( "{\n" );
|
||||
for _, v in ipairs(value) do
|
||||
build.serialize( file, v, level + 1 );
|
||||
file:write( ", " );
|
||||
end
|
||||
for k, v in pairs(value) do
|
||||
if type(k) == "string" then
|
||||
indent( level + 1 );
|
||||
file:write( "%s = " % k );
|
||||
build.serialize( file, v, level + 1 );
|
||||
file:write( ";\n" );
|
||||
end
|
||||
end
|
||||
indent( level );
|
||||
file:write( "}" );
|
||||
end
|
||||
end
|
||||
|
||||
-- Load a module.
|
||||
function load_module( module )
|
||||
if module.settings then
|
||||
setmetatable( module.settings, {__index = settings} );
|
||||
-- Save a settings table to a file.
|
||||
function build.save_settings( settings, filename )
|
||||
local file = io.open( filename, "wb" );
|
||||
assert( file, "Opening %s to write settings failed" % filename );
|
||||
file:write( "\nreturn " );
|
||||
build.serialize( file, settings, 0 );
|
||||
file:write( "\n" );
|
||||
file:close();
|
||||
end
|
||||
|
||||
-- Merge settings from /source_settings/ into /settings/.
|
||||
function build.merge_settings( settings, source_settings )
|
||||
settings = settings or {};
|
||||
for _, v in ipairs(source_settings) do
|
||||
table.insert( settings, v );
|
||||
end
|
||||
for k, v in pairs(source_settings) do
|
||||
if type(k) == "string" then
|
||||
if type(v) == "table" then
|
||||
settings[k] = build.merge_settings( settings[k], v );
|
||||
else
|
||||
settings[k] = v;
|
||||
end
|
||||
end
|
||||
end
|
||||
return settings;
|
||||
end
|
||||
|
||||
-- Inherit settings from /settings/ to /target/.
|
||||
function build.inherit_settings( target, settings )
|
||||
local inherited = false;
|
||||
if target.settings then
|
||||
if not getmetatable(target.settings) then
|
||||
setmetatable( target.settings, {__index = settings} );
|
||||
inherited = true;
|
||||
end
|
||||
else
|
||||
module.settings = settings;
|
||||
target.settings = settings;
|
||||
inherited = true;
|
||||
end
|
||||
|
||||
local settings = module.settings;
|
||||
for _, unit in ipairs(module) do
|
||||
if unit.settings then
|
||||
setmetatable( unit.settings, {__index = settings} );
|
||||
else
|
||||
unit.settings = settings;
|
||||
return inherited;
|
||||
end
|
||||
|
||||
-- Load a target.
|
||||
function build.load_target( target )
|
||||
local inherited = build.inherit_settings( target, build.settings );
|
||||
for _, value in ipairs(target) do
|
||||
if type(value) == "table" then
|
||||
build.inherit_settings( value, target.settings );
|
||||
end
|
||||
module:add_dependency( unit );
|
||||
unit.module = module;
|
||||
end
|
||||
return inherited;
|
||||
end
|
||||
|
||||
-- Load the dependency graph from the file specified by /settings.cache/.
|
||||
function build.load()
|
||||
assert( initialize and type(initialize) == "function", "The 'initialize' function is not defined" );
|
||||
assert( buildfiles and type(buildfiles) == "function", "The 'buildfiles' function is not defined" );
|
||||
|
||||
initialize();
|
||||
|
||||
local cache_target = load_binary( settings.cache, initial(goal) );
|
||||
if cache_target == nil or cache_target:is_outdated() or build.local_settings.updated then
|
||||
clear();
|
||||
buildfiles();
|
||||
|
||||
local root_target = find_target( root() );
|
||||
assert( root_target , "No root target found at '"..tostring(root()).."'" );
|
||||
preorder( build.visit("load"), root_target );
|
||||
preorder( build.visit("static_depend"), root_target );
|
||||
bind( root_target );
|
||||
|
||||
cache_target = find_target( settings.cache );
|
||||
assert( cache_target, "No cache target found at '%s' after loading buildfiles" % settings.cache );
|
||||
cache_target:add_dependency( SourceFile(root("build.lua")) );
|
||||
cache_target:add_dependency( SourceFile(root("local_settings.lua")) );
|
||||
cache_target:add_dependency( SourceFile(root("build/lua/build/init.lua")) );
|
||||
cache_target:add_dependency( SourceFile(root("build/lua/build/File.lua")) );
|
||||
cache_target:add_dependency( SourceFile(root("build/lua/build/SourceFile.lua")) );
|
||||
cache_target:add_dependency( SourceFile(root("build/lua/build/HeaderFile.lua")) );
|
||||
cache_target:add_dependency( SourceFile(root("build/lua/build/PrecompiledHeader.lua")) );
|
||||
cache_target:add_dependency( SourceFile(root("build/lua/build/Directory.lua")) );
|
||||
cache_target:add_dependency( SourceFile(root("build/lua/build/Compile.lua")) );
|
||||
cache_target:add_dependency( SourceFile(root("build/lua/build/Archive.lua")) );
|
||||
cache_target:add_dependency( SourceFile(root("build/lua/build/Link.lua")) );
|
||||
cache_target:add_dependency( SourceFile(root("build/lua/build/Lipo.lua")) );
|
||||
cache_target:add_dependency( SourceFile(root("build/lua/build/Source.lua")) );
|
||||
cache_target:add_dependency( SourceFile(root("build/lua/build/StaticLibrary.lua")) );
|
||||
cache_target:add_dependency( SourceFile(root("build/lua/build/DynamicLibrary.lua")) );
|
||||
cache_target:add_dependency( SourceFile(root("build/lua/build/Executable.lua")) );
|
||||
cache_target:add_dependency( SourceFile(root("build/lua/build/CcScanner.lua")) );
|
||||
cache_target:add_dependency( SourceFile(root("build/lua/build/ObjCScanner.lua")) );
|
||||
cache_target:add_dependency( SourceFile(root("build/lua/build/default_settings.lua")) );
|
||||
cache_target:add_dependency( SourceFile(root("build/lua/build/commands.lua")) );
|
||||
end
|
||||
|
||||
local project = Project( absolute(string.format("%s.project", module.project_name or module:id())) );
|
||||
project.module = module;
|
||||
|
||||
local working_directory = module:get_working_directory();
|
||||
working_directory:add_dependency( project );
|
||||
local all = find_target( initial(goal) );
|
||||
assert( all, "No target found at '"..tostring(initial(goal)).."'" );
|
||||
bind( all );
|
||||
preorder( build.visit("depend"), all );
|
||||
bind( all );
|
||||
end
|
||||
|
||||
-- Save the dependency graph to the file specified by /settings.cache/.
|
||||
function build.save()
|
||||
if build.local_settings.updated then
|
||||
build.local_settings.updated = nil;
|
||||
build.save_settings( build.local_settings, build.settings.local_settings_filename );
|
||||
end
|
||||
mkdir( branch(settings.cache) );
|
||||
save_binary( settings.cache );
|
||||
end
|
||||
|
||||
-- Set default settings (all other settings inherit from this table).
|
||||
build.default_settings = dofile( root("build/lua/build/default_settings.lua") );
|
||||
|
|
|
|||
296
sweet/build/lua/build/llvmgcc.lua
Normal file
296
sweet/build/lua/build/llvmgcc.lua
Normal file
|
|
@ -0,0 +1,296 @@
|
|||
|
||||
llvmgcc = {};
|
||||
|
||||
function llvmgcc.configure( settings )
|
||||
local local_settings = build.local_settings;
|
||||
if not local_settings.llvmgcc then
|
||||
local_settings.updated = true;
|
||||
local_settings.llvmgcc = {
|
||||
xcrun = "/usr/bin/xcrun";
|
||||
};
|
||||
end
|
||||
end;
|
||||
|
||||
function llvmgcc.initialize( settings )
|
||||
llvmgcc.configure( settings );
|
||||
|
||||
if platform == "llvmgcc" then
|
||||
cc = llvmgcc.cc;
|
||||
objc = llvmgcc.objc;
|
||||
build_library = llvmgcc.build_library;
|
||||
clean_library = llvmgcc.clean_library;
|
||||
build_executable = llvmgcc.build_executable;
|
||||
clean_executable = llvmgcc.clean_executable;
|
||||
lipo_executable = llvmgcc.lipo_executable;
|
||||
obj_directory = llvmgcc.obj_directory;
|
||||
cc_name = llvmgcc.cc_name;
|
||||
cxx_name = llvmgcc.cxx_name;
|
||||
obj_name = llvmgcc.obj_name;
|
||||
lib_name = llvmgcc.lib_name;
|
||||
dll_name = llvmgcc.dll_name;
|
||||
exe_name = llvmgcc.exe_name;
|
||||
end
|
||||
end;
|
||||
|
||||
function llvmgcc.cc( target, definition )
|
||||
local cppdefines = "";
|
||||
cppdefines = cppdefines.." -DBUILD_OS_MACOSX";
|
||||
cppdefines = cppdefines.." -DBUILD_PLATFORM_"..upper(platform);
|
||||
cppdefines = cppdefines.." -DBUILD_VARIANT_"..upper(variant);
|
||||
cppdefines = cppdefines.." -DBUILD_LIBRARY_SUFFIX=\"\\\"_"..platform.."_"..variant..".lib\\\"\"";
|
||||
cppdefines = cppdefines.." -DBUILD_MODULE_"..upper(string.gsub(target.module:id(), "-", "_"))
|
||||
cppdefines = cppdefines.." -DBUILD_LIBRARY_TYPE_"..upper(definition.settings.library_type);
|
||||
|
||||
if definition.settings.defines then
|
||||
for _, define in ipairs(definition.settings.defines) do
|
||||
cppdefines = cppdefines.." -D"..define;
|
||||
end
|
||||
end
|
||||
|
||||
if definition.defines then
|
||||
for _, define in ipairs(definition.defines) do
|
||||
cppdefines = cppdefines.." -D"..define;
|
||||
end
|
||||
end
|
||||
|
||||
local cppdirs = "";
|
||||
if definition.include_directories then
|
||||
for _, directory in ipairs(definition.include_directories) do
|
||||
cppdirs = cppdirs.." -I\""..relative(directory).."\"";
|
||||
end
|
||||
end
|
||||
|
||||
if definition.settings.include_directories then
|
||||
for _, directory in ipairs(definition.settings.include_directories) do
|
||||
cppdirs = cppdirs.." -I\""..directory.."\"";
|
||||
end
|
||||
end
|
||||
|
||||
local ccflags = "";
|
||||
ccflags = [["%s -c]] % ccflags;
|
||||
ccflags = [["%s -arch %s]] % { ccflags, target.architecture };
|
||||
|
||||
if definition.settings.compile_as_c then
|
||||
ccflags = ccflags.." -x c";
|
||||
else
|
||||
ccflags = ccflags.." -fpermissive -Wno-deprecated -x c++";
|
||||
end
|
||||
|
||||
if definition.settings.runtime_library == "static" or definition.settings.runtime_library == "static_debug" then
|
||||
ccflags = ccflags.." -static-libstdc++";
|
||||
end
|
||||
|
||||
if definition.settings.debug then
|
||||
ccflags = ccflags.." -g";
|
||||
end
|
||||
|
||||
if definition.settings.optimization then
|
||||
ccflags = ccflags.." -O2";
|
||||
end
|
||||
|
||||
if definition.settings.preprocess then
|
||||
ccflags = ccflags.." -E";
|
||||
end
|
||||
|
||||
if definition.settings.exceptions and not definition.settings.compile_as_c then
|
||||
ccflags = ccflags.." -fexceptions";
|
||||
end
|
||||
|
||||
if definition.settings.run_time_type_info and not definition.settings.compile_as_c then
|
||||
ccflags = ccflags.." -frtti";
|
||||
end
|
||||
|
||||
if definition.settings.runtime_checks then
|
||||
ccflags = [[%s -fstack-protector]] % ccflags;
|
||||
else
|
||||
ccflags = [[%s -fno-stack-protector]] % ccflags;
|
||||
end
|
||||
|
||||
if target.precompiled_header ~= nil then
|
||||
if target.precompiled_header:is_outdated() then
|
||||
print( leaf(target.precompiled_header.source) );
|
||||
local xcrun = definition.settings.llvmgcc.xcrun;
|
||||
build.system( xcrun, "xcrun g++ %s %s %s -o %s %s" % {cppdirs, cppdefines, ccflags, target.precompiled_header:get_filename(), target.precompiled_header.source} );
|
||||
end
|
||||
end
|
||||
|
||||
cppdefines = cppdefines.." -DBUILD_VERSION=\"\\\""..version.."\\\"\"";
|
||||
for dependency in target:get_dependencies() do
|
||||
if dependency:is_outdated() and dependency ~= target.precompiled_header then
|
||||
if dependency:prototype() == FilePrototype then
|
||||
print( leaf(dependency.source) );
|
||||
local xcrun = definition.settings.llvmgcc.xcrun;
|
||||
build.system( xcrun, "xcrun g++ %s %s %s -o %s %s" % {cppdirs, cppdefines, ccflags, dependency:get_filename(), absolute(dependency.source)} );
|
||||
elseif dependency.results then
|
||||
for _, result in ipairs(dependency.results) do
|
||||
if result:is_outdated() then
|
||||
print( leaf(result.source) );
|
||||
local xcrun = definition.settings.llvmgcc.xcrun;
|
||||
build.system( xcrun, "xcrun g++ %s %s %s -o %s %s" % {cppdirs, cppdefines, ccflags, result:get_filename(), absolute(result.source)} );
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end;
|
||||
|
||||
function llvmgcc.build_library( target, definition )
|
||||
local arflags = "";
|
||||
arflags = [[%s -static]] % arflags;
|
||||
|
||||
local objects = "";
|
||||
for compile in target:get_dependencies() do
|
||||
if compile:prototype() == CompilePrototype then
|
||||
if compile.precompiled_header then
|
||||
objects = [[%s %s]] % { objects, leaf(compile.precompiled_header:get_filename()) };
|
||||
end
|
||||
|
||||
for object in compile:get_dependencies() do
|
||||
if object:prototype() == FilePrototype and object ~= compile.precompiled_header then
|
||||
objects = [[%s %s]] % { objects, leaf(object:get_filename()) };
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if objects ~= "" then
|
||||
print( leaf(target:get_filename()) );
|
||||
pushd( obj_directory(target.module) );
|
||||
local xcrun = definition.settings.llvmgcc.xcrun;
|
||||
build.system( xcrun, [[xcrun libtool %s -o %s %s]] % {arflags, native(target:get_filename()), objects} );
|
||||
popd();
|
||||
end
|
||||
end;
|
||||
|
||||
function llvmgcc.clean_library( target, definition )
|
||||
rm( target:get_filename() );
|
||||
rmdir( obj_directory(target.module) );
|
||||
end;
|
||||
|
||||
function llvmgcc.build_executable( target, definition )
|
||||
local ldlibs = " ";
|
||||
|
||||
local lddirs = " -L \""..definition.settings.lib.."\"";
|
||||
|
||||
if definition.settings.library_directories then
|
||||
for _, directory in ipairs(definition.settings.library_directories) do
|
||||
lddirs = lddirs.." -L \""..directory.."\"";
|
||||
end
|
||||
end
|
||||
|
||||
local architecture = target.architecture;
|
||||
|
||||
local ldflags = "";
|
||||
ldflags = [[%s -arch %s]] % { ldflags, architecture };
|
||||
|
||||
ldflags = [[%s -o %s]] % { ldflags, native(target:get_filename()) };
|
||||
if target:prototype() == ArchivePrototype then
|
||||
ldflags = ldflags.." -shared -Wl,--out-implib,"..native( definition.settings.lib.."/"..lib_name(target:id()) );
|
||||
end
|
||||
|
||||
if definition.settings.verbose_linking then
|
||||
ldflags = ldflags.." -Wl,--verbose=31";
|
||||
end
|
||||
|
||||
if definition.settings.runtime_library == "static" or definition.settings.runtime_library == "static_debug" then
|
||||
ldflags = ldflags.." -static-libstdc++";
|
||||
end
|
||||
|
||||
if definition.settings.debug then
|
||||
ldflags = ldflags.." -debug";
|
||||
end
|
||||
|
||||
if definition.settings.strip then
|
||||
ldflags = ldflags.." -Wl,-dead_strip";
|
||||
end
|
||||
|
||||
local libraries = "";
|
||||
if target.libraries then
|
||||
for _, library in ipairs(target.libraries) do
|
||||
libraries = "%s -l%s" % { libraries, string.gsub(basename(library:id()), "lib", "", 1) };
|
||||
end
|
||||
end
|
||||
if definition.third_party_libraries then
|
||||
for _, library in ipairs(definition.third_party_libraries) do
|
||||
libraries = "%s -l%s" % { libraries, library };
|
||||
end
|
||||
end
|
||||
if definition.system_libraries then
|
||||
for _, library in ipairs(definition.system_libraries) do
|
||||
libraries = "%s -l%s" % { libraries, library };
|
||||
end
|
||||
end
|
||||
if definition.frameworks then
|
||||
for _, framework in ipairs(definition.frameworks) do
|
||||
libraries = "%s -framework %s" % { libraries, framework };
|
||||
end
|
||||
end
|
||||
|
||||
local objects = "";
|
||||
for dependency in target:get_dependencies() do
|
||||
if dependency:prototype() == CompilePrototype then
|
||||
if dependency.precompiled_header then
|
||||
objects = [[%s %s]] % { objects, leaf(dependency.precompiled_header:get_filename()) };
|
||||
end
|
||||
|
||||
for object in dependency:get_dependencies() do
|
||||
if object:prototype() == FilePrototype and object ~= dependency.precompiled_header then
|
||||
objects = [[%s %s]] % { objects, leaf(object:get_filename()) };
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if objects ~= "" then
|
||||
print( leaf(target:get_filename()) );
|
||||
pushd( obj_directory(target.module) );
|
||||
local xcrun = definition.settings.llvmgcc.xcrun;
|
||||
build.system( xcrun, "xcrun g++"..ldflags..lddirs..objects..libraries..ldlibs );
|
||||
popd();
|
||||
end
|
||||
end;
|
||||
|
||||
function llvmgcc.clean_executable( target, definition )
|
||||
rm( target:get_filename() );
|
||||
rmdir( obj_directory(target.module) );
|
||||
end;
|
||||
|
||||
function llvmgcc.lipo_executable( target, definition )
|
||||
local executables = "";
|
||||
for executable in target:get_dependencies() do
|
||||
if executable:prototype() == LinkPrototype then
|
||||
executables = [[%s %s]] % { executables, executable:get_filename() };
|
||||
end
|
||||
end
|
||||
print( leaf(target:get_filename()) );
|
||||
local xcrun = definition.settings.llvmgcc.xcrun;
|
||||
build.system( xcrun, [[xcrun lipo -create %s -output %s]] % {executables, target:get_filename()} );
|
||||
end
|
||||
|
||||
function llvmgcc.obj_directory( target )
|
||||
return "%s/%s_%s/%s" % { target.settings.obj, platform, variant, relative(target:directory(), root()) };
|
||||
end;
|
||||
|
||||
function llvmgcc.cc_name( name )
|
||||
return "%s.c" % basename( name );
|
||||
end;
|
||||
|
||||
function llvmgcc.cxx_name( name )
|
||||
return "%s.cpp" % basename( name );
|
||||
end;
|
||||
|
||||
function llvmgcc.obj_name( name, architecture )
|
||||
return "%s_%s.o" % { basename(name), architecture };
|
||||
end;
|
||||
|
||||
function llvmgcc.lib_name( name )
|
||||
return "lib%s_%s.a" % { name, variant };
|
||||
end;
|
||||
|
||||
function llvmgcc.dll_name( name )
|
||||
return "%s_%s.dylib" % { name, variant };
|
||||
end;
|
||||
|
||||
function llvmgcc.exe_name( name )
|
||||
return "%s_%s" % { name, variant };
|
||||
end;
|
||||
319
sweet/build/lua/build/mingw.lua
Normal file
319
sweet/build/lua/build/mingw.lua
Normal file
|
|
@ -0,0 +1,319 @@
|
|||
|
||||
mingw = {};
|
||||
|
||||
function mingw.configure( settings )
|
||||
function autodetect_mingw_directory()
|
||||
local mingw_directory = "C:/MinGW";
|
||||
return mingw_directory;
|
||||
end
|
||||
|
||||
local local_settings = build.local_settings;
|
||||
if not local_settings.mingw then
|
||||
local_settings.updated = true;
|
||||
local_settings.mingw = {
|
||||
mingw_directory = autodetect_mingw_directory() or "C:/MinGW";
|
||||
};
|
||||
end
|
||||
end
|
||||
|
||||
function mingw.initialize( settings )
|
||||
mingw.configure( settings );
|
||||
if platform == "mingw" then
|
||||
-- Make sure that the environment variable VS_UNICODE_OUTPUT is not set.
|
||||
-- Visual Studio sets this to signal its tools to communicate back to
|
||||
-- Visual Studio using named pipes rather than stdout so that unicode output
|
||||
-- works better but this then prevents the build tool from intercepting
|
||||
-- and collating this output.
|
||||
-- See http://blogs.msdn.com/freik/archive/2006/04/05/569025.aspx.
|
||||
putenv( "VS_UNICODE_OUTPUT", "" );
|
||||
|
||||
local mingw_directory = settings.mingw.mingw_directory;
|
||||
|
||||
local path = {
|
||||
"%s/bin" % mingw_directory,
|
||||
getenv("PATH")
|
||||
};
|
||||
putenv( "PATH", table.concat(path, ";") );
|
||||
|
||||
local include = {
|
||||
"%s/include" % mingw_directory,
|
||||
getenv("INCLUDE")
|
||||
};
|
||||
putenv( "INCLUDE", table.concat(include, ";") );
|
||||
|
||||
local lib = {
|
||||
"%s/lib" % mingw_directory,
|
||||
getenv("LIB")
|
||||
};
|
||||
putenv( "LIB", table.concat(lib, ";") );
|
||||
|
||||
cc = mingw.cc;
|
||||
build_library = mingw.build_library;
|
||||
clean_library = mingw.clean_library;
|
||||
build_executable = mingw.build_executable;
|
||||
clean_executable = mingw.clean_executable;
|
||||
obj_directory = mingw.obj_directory;
|
||||
cc_name = mingw.cc_name;
|
||||
cxx_name = mingw.cxx_name;
|
||||
pch_name = mingw.pch_name;
|
||||
pdb_name = mingw.pdb_name;
|
||||
obj_name = mingw.obj_name;
|
||||
lib_name = mingw.lib_name;
|
||||
exp_name = mingw.exp_name;
|
||||
dll_name = mingw.dll_name;
|
||||
exe_name = mingw.exe_name;
|
||||
ilk_name = mingw.ilk_name;
|
||||
end
|
||||
end
|
||||
|
||||
function mingw.cc( target, definition )
|
||||
local gcc = "%s/bin/gcc.exe" % definition.settings.mingw.mingw_directory;
|
||||
|
||||
local cppdefines = "";
|
||||
cppdefines = cppdefines.." -DBUILD_OS_"..upper(operating_system());
|
||||
cppdefines = cppdefines.." -DBUILD_PLATFORM_"..upper(platform);
|
||||
cppdefines = cppdefines.." -DBUILD_VARIANT_"..upper(variant);
|
||||
cppdefines = cppdefines.." -DBUILD_LIBRARY_SUFFIX=\"\\\"_"..platform.."_"..variant..".lib\\\"\"";
|
||||
cppdefines = cppdefines.." -DBUILD_MODULE_"..upper(string.gsub(target.module:id(), "-", "_"))
|
||||
cppdefines = cppdefines.." -DBUILD_LIBRARY_TYPE_"..upper(definition.settings.library_type);
|
||||
|
||||
if definition.settings.defines then
|
||||
for _, define in ipairs(definition.settings.defines) do
|
||||
cppdefines = cppdefines.." -D"..define;
|
||||
end
|
||||
end
|
||||
|
||||
if target.defines then
|
||||
for _, define in ipairs(target.defines) do
|
||||
cppdefines = cppdefines.." -D"..define;
|
||||
end
|
||||
end
|
||||
|
||||
local cppdirs = "";
|
||||
if target.include_directories then
|
||||
for _, directory in ipairs(target.include_directories) do
|
||||
cppdirs = cppdirs.." -I\""..relative(directory).."\"";
|
||||
end
|
||||
end
|
||||
|
||||
if definition.settings.include_directories then
|
||||
for _, directory in ipairs(definition.settings.include_directories) do
|
||||
cppdirs = cppdirs.." -I\""..directory.."\"";
|
||||
end
|
||||
end
|
||||
|
||||
local ccflags = " -c";
|
||||
|
||||
if definition.settings.compile_as_c then
|
||||
ccflags = ccflags.." -x c";
|
||||
else
|
||||
ccflags = ccflags.." -fpermissive -Wno-deprecated -x c++";
|
||||
end
|
||||
|
||||
if definition.settings.runtime_library == "static" or definition.settings.runtime_library == "static_debug" then
|
||||
ccflags = ccflags.." -static-libstdc++";
|
||||
end
|
||||
|
||||
if definition.settings.debug then
|
||||
ccflags = ccflags.." -g";
|
||||
end
|
||||
|
||||
if definition.settings.optimization then
|
||||
ccflags = ccflags.." -O2";
|
||||
end
|
||||
|
||||
if definition.settings.preprocess then
|
||||
ccflags = ccflags.." -E";
|
||||
end
|
||||
|
||||
if definition.settings.exceptions and not definition.settings.compile_as_c then
|
||||
ccflags = ccflags.." -fexceptions";
|
||||
end
|
||||
|
||||
if definition.settings.run_time_type_info and not definition.settings.compile_as_c then
|
||||
ccflags = ccflags.." -frtti";
|
||||
end
|
||||
|
||||
if target.precompiled_header ~= nil then
|
||||
if target.precompiled_header:is_outdated() then
|
||||
print( leaf(target.precompiled_header.source) );
|
||||
build.system( gcc, "gcc"..cppdirs..cppdefines..ccflags.." -o"..obj_directory(definition)..obj_name(target.precompiled_header.source).." "..target.precompiled_header.source, GccScanner );
|
||||
end
|
||||
end
|
||||
|
||||
local GccScanner = Scanner {
|
||||
[ [[((?:[A-Z]\:)?[^\:]+)\:([0-9]+)\:[0-9]+\: ([^\:]+)\:(.*)]] ] = function( filename, line, class, message )
|
||||
print( "%s(%s): %s: %s" % {filename, line, class, message} );
|
||||
end;
|
||||
};
|
||||
|
||||
cppdefines = cppdefines.." -DBUILD_VERSION=\"\\\""..version.."\\\"\"";
|
||||
for dependency in target:get_dependencies() do
|
||||
if dependency:is_outdated() and dependency ~= target.precompiled_header then
|
||||
if dependency:prototype() == FilePrototype then
|
||||
print( leaf(dependency.source) );
|
||||
build.system( gcc, "gcc"..cppdirs..cppdefines..ccflags.." -o"..obj_directory(definition)..obj_name(dependency.source).." "..dependency.source, GccScanner );
|
||||
elseif dependency.results then
|
||||
for _, result in ipairs(dependency.results) do
|
||||
if result:is_outdated() then
|
||||
print( leaf(result.source) );
|
||||
build.system( gcc, "gcc"..cppdirs..cppdefines..ccflags.." -o"..obj_directory(definition)..obj_name(result.source).." "..result.source, GccScanner );
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mingw.build_library( target, definition )
|
||||
local ar = "%s/bin/ar.exe" % definition.settings.mingw.mingw_directory;
|
||||
|
||||
local arflags = " ";
|
||||
|
||||
local objects = "";
|
||||
for dependency in target:get_dependencies() do
|
||||
if dependency:prototype() == CompilePrototype then
|
||||
if dependency.precompiled_header ~= nil then
|
||||
objects = objects.." "..obj_name( dependency.precompiled_header:id() );
|
||||
end
|
||||
|
||||
for object in dependency:get_dependencies() do
|
||||
if object:prototype() == FilePrototype and object ~= dependency.precompiled_header then
|
||||
objects = objects.." "..obj_name( object:id() );
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if objects ~= "" then
|
||||
print( leaf(target:get_filename()) );
|
||||
pushd( obj_directory(target.module) );
|
||||
build.system( ar, "ar"..arflags.." -rcs "..native(target:get_filename())..objects );
|
||||
popd();
|
||||
end
|
||||
end
|
||||
|
||||
function mingw.clean_library( target, definition )
|
||||
rm( target:get_filename() );
|
||||
rmdir( obj_directory(target.module) );
|
||||
end
|
||||
|
||||
function mingw.build_executable( target, definition )
|
||||
local gxx = "%s/bin/g++.exe" % definition.settings.mingw.mingw_directory;
|
||||
|
||||
local ldlibs = " ";
|
||||
|
||||
local lddirs = " -L \""..definition.settings.lib.."\"";
|
||||
|
||||
if definition.settings.library_directories then
|
||||
for _, directory in ipairs(definition.settings.library_directories) do
|
||||
lddirs = lddirs.." -L \""..directory.."\"";
|
||||
end
|
||||
end
|
||||
|
||||
local ldflags = " ";
|
||||
|
||||
ldflags = ldflags.." -o "..native( target:get_filename() );
|
||||
if target.module:prototype() == DynamicLibraryPrototype then
|
||||
ldflags = ldflags.." -shared -Wl,--out-implib,"..native( "%s/%s.lib" % {definition.settings.lib, basename(target:id())} );
|
||||
end
|
||||
|
||||
if definition.settings.verbose_linking then
|
||||
ldflags = ldflags.." -Wl,--verbose=31";
|
||||
end
|
||||
|
||||
if definition.settings.runtime_library == "static" or definition.settings.runtime_library == "static_debug" then
|
||||
ldflags = ldflags.." -static-libstdc++";
|
||||
end
|
||||
|
||||
if definition.settings.debug then
|
||||
ldflags = ldflags.." -debug";
|
||||
end
|
||||
|
||||
if definition.settings.generate_map_file then
|
||||
ldflags = ldflags.." -Wl,-Map,"..native(obj_directory(target.module)..target:id()..".map");
|
||||
end
|
||||
|
||||
if definition.settings.stack_size then
|
||||
ldflags = ldflags.." -Wl,--stack,"..tostring(definition.settings.stack_size);
|
||||
end
|
||||
|
||||
if definition.settings.strip then
|
||||
ldflags = ldflags.." -Wl,--strip-all";
|
||||
end
|
||||
|
||||
local libraries = "";
|
||||
if target.libraries then
|
||||
for _, library in ipairs(target.libraries) do
|
||||
libraries = "%s -l%s" % { libraries, basename(library:id()) };
|
||||
end
|
||||
end
|
||||
if definition.third_party_libraries then
|
||||
for _, library in ipairs(definition.third_party_libraries) do
|
||||
libraries = "%s -l%s" % { libraries, library };
|
||||
end
|
||||
end
|
||||
|
||||
local objects = "";
|
||||
for dependency in target:get_dependencies() do
|
||||
if dependency:prototype() == CompilePrototype then
|
||||
if dependency.precompiled_header ~= nil then
|
||||
objects = objects.." "..obj_name( dependency.precompiled_header:id() );
|
||||
end
|
||||
|
||||
for object in dependency:get_dependencies() do
|
||||
if object:prototype() == FilePrototype and object ~= dependency.precompiled_header then
|
||||
objects = objects.." "..obj_name( object:id() );
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if objects ~= "" then
|
||||
print( leaf(target:get_filename()) );
|
||||
pushd( obj_directory(target.module) );
|
||||
build.system( gxx, "g++"..ldflags..lddirs..objects..libraries..ldlibs );
|
||||
popd();
|
||||
end
|
||||
end
|
||||
|
||||
function mingw.clean_executable( target, definition )
|
||||
rm( target:get_filename() );
|
||||
rmdir( obj_directory(target.module) );
|
||||
end
|
||||
|
||||
function mingw.obj_directory( target )
|
||||
return "%s/%s_%s/%s/" % { target.settings.obj, platform, variant, relative(target:directory(), root()) };
|
||||
end
|
||||
|
||||
function mingw.cc_name( name )
|
||||
return "%s.c" % basename( name );
|
||||
end
|
||||
|
||||
function mingw.cxx_name( name )
|
||||
return "%s.cpp" % basename( name );
|
||||
end
|
||||
|
||||
function mingw.obj_name( name )
|
||||
return "%s.o" % basename( name );
|
||||
end
|
||||
|
||||
function mingw.lib_name( name )
|
||||
return "%s_%s_%s.lib" % { name, platform, variant };
|
||||
end
|
||||
|
||||
function mingw.exp_name( name )
|
||||
return "%s_%s_%s.exp" % { name, platform, variant };
|
||||
end
|
||||
|
||||
function mingw.dll_name( name )
|
||||
return "%s_%s_%s.dll" % { name, platform, variant };
|
||||
end
|
||||
|
||||
function mingw.exe_name( name )
|
||||
return "%s_%s_%s.exe" % { name, platform, variant };
|
||||
end
|
||||
|
||||
function mingw.ilk_name( name )
|
||||
return "%s_%s_%s.ilk" % { name, platform, variant };
|
||||
end
|
||||
|
|
@ -1,161 +1,213 @@
|
|||
|
||||
function autodetect_visual_studio_directory()
|
||||
local visual_studio_directory = os.getenv( "VS90COMNTOOLS" ) or os.getenv( "VS100COMNTOOLS" );
|
||||
if visual_studio_directory then
|
||||
visual_studio_directory = string.gsub( visual_studio_directory, "\\Common7\\Tools\\", "" );
|
||||
end
|
||||
return visual_studio_directory;
|
||||
end
|
||||
msvc = {};
|
||||
|
||||
function autodetect_windows_sdk_directory()
|
||||
local windows_sdk_directory = os.getenv( "WindowsSdkDir" );
|
||||
return windows_sdk_directory;
|
||||
end
|
||||
function msvc.configure( settings )
|
||||
local function registry( key )
|
||||
local values = {};
|
||||
local RegQueryScanner = Scanner {
|
||||
[ [[[ ]* ([A-Za-z0-9_]+) [ ]* ([A-Za-z0-9_]+) [ ]* ([A-Za-z0-9_\\\:\. ]+)]] ] = function( key, type, value )
|
||||
values[key] = value;
|
||||
end;
|
||||
|
||||
[ [[.*]] ] = function()
|
||||
end;
|
||||
};
|
||||
local reg = "C:/Windows/system32/reg.exe";
|
||||
local arguments = [[reg query "%s"]] % key;
|
||||
build.system( reg, arguments, RegQueryScanner );
|
||||
return values;
|
||||
end
|
||||
|
||||
function msvc( settings )
|
||||
-- Make sure that the environment variable VS_UNICODE_OUTPUT is not set.
|
||||
-- Visual Studio sets this to signal its tools to communicate back to
|
||||
-- Visual Studio using named pipes rather than stdout so that unicode output
|
||||
-- works better but this then prevents the build tool from intercepting
|
||||
-- and collating this output.
|
||||
-- See http://blogs.msdn.com/freik/archive/2006/04/05/569025.aspx.
|
||||
putenv( "VS_UNICODE_OUTPUT", "" );
|
||||
local function autodetect_visual_studio_directory()
|
||||
local visual_studio_directory = os.getenv( "VS90COMNTOOLS" ) or os.getenv( "VS100COMNTOOLS" );
|
||||
if visual_studio_directory then
|
||||
visual_studio_directory = string.gsub( visual_studio_directory, "\\Common7\\Tools\\", "" );
|
||||
end
|
||||
return visual_studio_directory;
|
||||
end
|
||||
|
||||
local visual_studio_directory = settings.msvc.visual_studio_directory;
|
||||
local windows_sdk_directory = settings.msvc.windows_sdk_directory;
|
||||
|
||||
local path = {
|
||||
visual_studio_directory..[[\Common7\IDE]],
|
||||
visual_studio_directory..[[\VC\BIN]],
|
||||
visual_studio_directory..[[\Common7\Tools]],
|
||||
visual_studio_directory..[[\VC\VCPackages]],
|
||||
windows_sdk_directory..[[\bin]],
|
||||
getenv("PATH")
|
||||
};
|
||||
putenv( "PATH", table.concat(path, ";") );
|
||||
|
||||
local include = {
|
||||
visual_studio_directory..[[\VC\ATLMFC\INCLUDE]],
|
||||
visual_studio_directory..[[\VC\INCLUDE]],
|
||||
windows_sdk_directory..[[\include]],
|
||||
getenv("INCLUDE")
|
||||
};
|
||||
putenv( "INCLUDE", table.concat(include, ";") );
|
||||
|
||||
local lib = {
|
||||
visual_studio_directory..[[\VC\ATLMFC\LIB]],
|
||||
visual_studio_directory..[[\VC\LIB]],
|
||||
windows_sdk_directory..[[\lib]],
|
||||
getenv("LIB")
|
||||
};
|
||||
putenv( "LIB", table.concat(lib, ";") );
|
||||
local function autodetect_windows_sdk_directory()
|
||||
local windows_sdk = registry( [[HKLM\SOFTWARE\Microsoft\Microsoft SDKs\Windows]] );
|
||||
assert( windows_sdk.CurrentInstallFolder, "Windows SDK not found!" );
|
||||
return windows_sdk.CurrentInstallFolder;
|
||||
end
|
||||
|
||||
local libpath = {
|
||||
visual_studio_directory..[[\VC\ATLMFC\LIB]],
|
||||
visual_studio_directory..[[\VC\LIB]],
|
||||
getenv("LIBPATH")
|
||||
};
|
||||
putenv( "LIBPATH", table.concat(libpath, ";") );
|
||||
end
|
||||
local local_settings = build.local_settings;
|
||||
if not local_settings.msvc then
|
||||
local_settings.updated = true;
|
||||
local_settings.msvc = {
|
||||
visual_studio_directory = autodetect_visual_studio_directory() or "C:/Program Files/Microsoft Visual Studio 9.0";
|
||||
windows_sdk_directory = autodetect_windows_sdk_directory() or "C:/Program Files/Microsoft SDKs/Windows/v6.0A";
|
||||
};
|
||||
end
|
||||
end;
|
||||
|
||||
function cc( target )
|
||||
local mscc = target.settings.msvc.visual_studio_directory.."/VC/bin/cl.exe";
|
||||
function msvc.initialize( settings )
|
||||
msvc.configure( settings );
|
||||
if platform == "msvc" then
|
||||
-- Make sure that the environment variable VS_UNICODE_OUTPUT is not set.
|
||||
-- Visual Studio sets this to signal its tools to communicate back to
|
||||
-- Visual Studio using named pipes rather than stdout so that unicode output
|
||||
-- works better but this then prevents the build tool from intercepting
|
||||
-- and collating this output.
|
||||
-- See http://blogs.msdn.com/freik/archive/2006/04/05/569025.aspx.
|
||||
putenv( "VS_UNICODE_OUTPUT", "" );
|
||||
|
||||
local visual_studio_directory = settings.msvc.visual_studio_directory;
|
||||
local windows_sdk_directory = settings.msvc.windows_sdk_directory;
|
||||
|
||||
local path = {
|
||||
visual_studio_directory..[[\Common7\IDE]],
|
||||
visual_studio_directory..[[\VC\BIN]],
|
||||
visual_studio_directory..[[\Common7\Tools]],
|
||||
visual_studio_directory..[[\VC\VCPackages]],
|
||||
windows_sdk_directory..[[\bin]],
|
||||
getenv("PATH")
|
||||
};
|
||||
putenv( "PATH", table.concat(path, ";") );
|
||||
|
||||
local include = {
|
||||
visual_studio_directory..[[\VC\ATLMFC\INCLUDE]],
|
||||
visual_studio_directory..[[\VC\INCLUDE]],
|
||||
windows_sdk_directory..[[\include]],
|
||||
getenv("INCLUDE")
|
||||
};
|
||||
putenv( "INCLUDE", table.concat(include, ";") );
|
||||
|
||||
local lib = {
|
||||
visual_studio_directory..[[\VC\ATLMFC\LIB]],
|
||||
visual_studio_directory..[[\VC\LIB]],
|
||||
windows_sdk_directory..[[\lib]],
|
||||
getenv("LIB")
|
||||
};
|
||||
putenv( "LIB", table.concat(lib, ";") );
|
||||
|
||||
local libpath = {
|
||||
visual_studio_directory..[[\VC\ATLMFC\LIB]],
|
||||
visual_studio_directory..[[\VC\LIB]],
|
||||
getenv("LIBPATH")
|
||||
};
|
||||
putenv( "LIBPATH", table.concat(libpath, ";") );
|
||||
|
||||
cc = msvc.cc;
|
||||
build_library = msvc.build_library;
|
||||
clean_library = msvc.clean_library;
|
||||
build_executable = msvc.build_executable;
|
||||
clean_executable = msvc.clean_executable;
|
||||
lipo_executable = msvc.lipo_executable;
|
||||
obj_directory = msvc.obj_directory;
|
||||
cc_name = msvc.cc_name;
|
||||
cxx_name = msvc.cxx_name;
|
||||
pch_name = msvc.pch_name;
|
||||
pdb_name = msvc.pdb_name;
|
||||
obj_name = msvc.obj_name;
|
||||
lib_name = msvc.lib_name;
|
||||
exp_name = msvc.exp_name;
|
||||
dll_name = msvc.dll_name;
|
||||
exe_name = msvc.exe_name;
|
||||
ilk_name = msvc.ilk_name;
|
||||
end
|
||||
end;
|
||||
|
||||
function msvc.cc( target, definition )
|
||||
local mscc = definition.settings.msvc.visual_studio_directory.."/VC/bin/cl.exe";
|
||||
|
||||
local cppdefines = "";
|
||||
cppdefines = cppdefines.." /DBUILD_OS_"..upper(operating_system());
|
||||
cppdefines = cppdefines.." /DBUILD_PLATFORM_"..upper(platform);
|
||||
cppdefines = cppdefines.." /DBUILD_VARIANT_"..upper(variant);
|
||||
cppdefines = cppdefines.." /DBUILD_LIBRARY_SUFFIX=\"\\\"_"..platform.."_"..variant..".lib\\\"\"";
|
||||
cppdefines = cppdefines.." /DBUILD_MODULE_"..upper(string.gsub(target.module:id(), "-", "_"))
|
||||
cppdefines = cppdefines.." /DBUILD_LIBRARY_TYPE_"..upper(target.settings.library_type);
|
||||
cppdefines = cppdefines.." /DBUILD_LIBRARY_TYPE_"..upper(definition.settings.library_type);
|
||||
|
||||
if target.settings.defines then
|
||||
for _, define in ipairs(target.settings.defines) do
|
||||
if definition.settings.defines then
|
||||
for _, define in ipairs(definition.settings.defines) do
|
||||
cppdefines = cppdefines.." /D"..define;
|
||||
end
|
||||
end
|
||||
|
||||
if target.defines then
|
||||
for _, define in ipairs(target.defines) do
|
||||
if definition.defines then
|
||||
for _, define in ipairs(definition.defines) do
|
||||
cppdefines = cppdefines.." /D"..define;
|
||||
end
|
||||
end
|
||||
|
||||
local cppdirs = "";
|
||||
if target.include_directories then
|
||||
for _, directory in ipairs(target.include_directories) do
|
||||
if definition.include_directories then
|
||||
for _, directory in ipairs(definition.include_directories) do
|
||||
cppdirs = cppdirs.." /I\""..relative(directory).."\"";
|
||||
end
|
||||
end
|
||||
|
||||
if target.settings.include_directories then
|
||||
for _, directory in ipairs(target.settings.include_directories) do
|
||||
if definition.settings.include_directories then
|
||||
for _, directory in ipairs(definition.settings.include_directories) do
|
||||
cppdirs = cppdirs.." /I\""..directory.."\"";
|
||||
end
|
||||
end
|
||||
|
||||
local ccflags = " /nologo /c";
|
||||
|
||||
if target.settings.compile_as_c then
|
||||
if definition.settings.compile_as_c then
|
||||
ccflags = ccflags.." /TC";
|
||||
else
|
||||
ccflags = ccflags.." /TP";
|
||||
end
|
||||
|
||||
if target.settings.runtime_library == "static" then
|
||||
if definition.settings.runtime_library == "static" then
|
||||
ccflags = ccflags.." /MT";
|
||||
elseif target.settings.runtime_library == "static_debug" then
|
||||
elseif definition.settings.runtime_library == "static_debug" then
|
||||
ccflags = ccflags.." /MTd";
|
||||
elseif target.settings.runtime_library == "dynamic" then
|
||||
elseif definition.settings.runtime_library == "dynamic" then
|
||||
ccflags = ccflags.." /MD";
|
||||
elseif target.settings.runtime_library == "dynamic_debug" then
|
||||
elseif definition.settings.runtime_library == "dynamic_debug" then
|
||||
ccflags = ccflags.." /MDd";
|
||||
end
|
||||
|
||||
if target.settings.debug then
|
||||
local pdb = obj_directory(target)..pdb_name( "msvc.pdb" );
|
||||
if definition.settings.debug then
|
||||
local pdb = obj_directory(definition)..pdb_name( "msvc.pdb" );
|
||||
ccflags = ccflags.." /Zi /Fd"..pdb;
|
||||
end
|
||||
|
||||
if target.settings.exceptions then
|
||||
if definition.settings.exceptions then
|
||||
ccflags = ccflags.." /EHsc";
|
||||
end
|
||||
|
||||
if target.settings.link_time_code_generation then
|
||||
if definition.settings.link_time_code_generation then
|
||||
ccflags = ccflags.." /GL";
|
||||
end
|
||||
|
||||
if target.settings.minimal_rebuild then
|
||||
if definition.settings.minimal_rebuild then
|
||||
ccflags = ccflags.." /Gm";
|
||||
end
|
||||
|
||||
if target.settings.optimization then
|
||||
if definition.settings.optimization then
|
||||
ccflags = ccflags.." /GF /O2 /Ot /Oi /GS-";
|
||||
end
|
||||
|
||||
if target.settings.preprocess then
|
||||
if definition.settings.preprocess then
|
||||
ccflags = ccflags.." /P /C";
|
||||
end
|
||||
|
||||
if target.settings.run_time_type_info then
|
||||
if definition.settings.run_time_type_info then
|
||||
ccflags = ccflags.." /GR";
|
||||
end
|
||||
|
||||
if target.settings.run_time_checks then
|
||||
if definition.settings.run_time_checks then
|
||||
ccflags = ccflags.." /RTC1";
|
||||
end
|
||||
|
||||
if target.precompiled_header ~= nil then
|
||||
if target.precompiled_header:is_outdated() then
|
||||
system( mscc, "cl"..cppdirs..cppdefines..ccflags.." /Fp"..obj_directory(target)..pch_name( target.precompiled_header:id() ).." /Yc"..target.precompiled_header.header.." /Fo"..obj_directory(target).." ".." "..target.precompiled_header.source );
|
||||
build.system( mscc, "cl"..cppdirs..cppdefines..ccflags.." /Fp"..obj_directory(definition)..pch_name( target.precompiled_header:id() ).." /Yc"..target.precompiled_header.header.." /Fo"..obj_directory(definition).." ".." "..target.precompiled_header.source );
|
||||
end
|
||||
ccflags = ccflags.." /Fp"..obj_directory(target)..pch_name( target.precompiled_header:id() );
|
||||
ccflags = ccflags.." /Fp"..obj_directory(definition)..pch_name( target.precompiled_header:id() );
|
||||
ccflags = ccflags.." /Yu"..target.precompiled_header.header;
|
||||
end
|
||||
|
||||
ccsource = "";
|
||||
for dependency in target:get_dependencies() do
|
||||
if dependency:is_outdated() and dependency ~= target.precompiled_header then
|
||||
if dependency:rule() == File then
|
||||
if dependency:is_outdated() and dependency ~= target.precompiled_header then
|
||||
if dependency:prototype() == FilePrototype then
|
||||
ccsource = ccsource.." "..dependency.source;
|
||||
elseif dependency.results then
|
||||
for _, result in ipairs(dependency.results) do
|
||||
|
|
@ -169,28 +221,28 @@ function cc( target )
|
|||
|
||||
if ccsource ~= "" then
|
||||
cppdefines = cppdefines.." /DBUILD_VERSION=\"\\\""..version.."\\\"\"";
|
||||
system( mscc, "cl"..cppdirs..cppdefines..ccflags.." /Fo"..obj_directory(target).." "..ccsource );
|
||||
build.system( mscc, "cl"..cppdirs..cppdefines..ccflags.." /Fo"..obj_directory(definition).." "..ccsource );
|
||||
end
|
||||
end
|
||||
end;
|
||||
|
||||
function build_library( target )
|
||||
local msar = target.settings.msvc.visual_studio_directory.."/VC/bin/lib.exe";
|
||||
function msvc.build_library( target, definition )
|
||||
local msar = definition.settings.msvc.visual_studio_directory.."/VC/bin/lib.exe";
|
||||
|
||||
local arflags = " /nologo";
|
||||
|
||||
if target.settings.link_time_code_generation then
|
||||
if definition.settings.link_time_code_generation then
|
||||
arflags = arflags.." /ltcg";
|
||||
end
|
||||
|
||||
local objects = "";
|
||||
for dependency in target:get_dependencies() do
|
||||
if dependency:rule() == Cc then
|
||||
if dependency:prototype() == CompilePrototype then
|
||||
if dependency.precompiled_header ~= nil then
|
||||
objects = objects.." "..obj_name( dependency.precompiled_header:id() );
|
||||
end
|
||||
|
||||
for object in dependency:get_dependencies() do
|
||||
if object:rule() == File and object ~= dependency.precompiled_header then
|
||||
if object:prototype() == FilePrototype and object ~= dependency.precompiled_header then
|
||||
objects = objects.." "..obj_name( object:id() );
|
||||
end
|
||||
end
|
||||
|
|
@ -198,92 +250,92 @@ function build_library( target )
|
|||
end
|
||||
|
||||
if objects ~= "" then
|
||||
print( lib_name(target:id()) );
|
||||
pushd( obj_directory(target) );
|
||||
system( msar, "lib"..arflags.." /out:"..native(target:get_filename())..objects );
|
||||
print( leaf(target:get_filename()) );
|
||||
pushd( obj_directory(target.module) );
|
||||
build.system( msar, "lib"..arflags.." /out:"..native(target:get_filename())..objects );
|
||||
popd();
|
||||
end
|
||||
end
|
||||
end;
|
||||
|
||||
function clean_library( target )
|
||||
rm( target.settings.lib.."/"..lib_name(target:id()) );
|
||||
rmdir( obj_directory(target) );
|
||||
end
|
||||
function msvc.clean_library( target, definition )
|
||||
rm( target:get_filename() );
|
||||
rmdir( obj_directory(target.module) );
|
||||
end;
|
||||
|
||||
function build_executable( target )
|
||||
local msld = target.settings.msvc.visual_studio_directory.."/VC/bin/link.exe";
|
||||
local msmt = target.settings.msvc.windows_sdk_directory.."/bin/mt.exe";
|
||||
local msrc = target.settings.msvc.windows_sdk_directory.."/bin/rc.exe";
|
||||
function msvc.build_executable( target, definition )
|
||||
local msld = definition.settings.msvc.visual_studio_directory.."/VC/bin/link.exe";
|
||||
local msmt = definition.settings.msvc.windows_sdk_directory.."/bin/mt.exe";
|
||||
local msrc = definition.settings.msvc.windows_sdk_directory.."/bin/rc.exe";
|
||||
|
||||
local ldlibs = " advapi32.lib gdi32.lib kernel32.lib user32.lib msimg32.lib ws2_32.lib version.lib odbc32.lib odbccp32.lib";
|
||||
|
||||
local lddirs = " /libpath:\""..target.settings.lib.."\"";
|
||||
local lddirs = " /libpath:\""..definition.settings.lib.."\"";
|
||||
|
||||
if target.settings.library_directories then
|
||||
for _, directory in ipairs(target.settings.library_directories) do
|
||||
if definition.settings.library_directories then
|
||||
for _, directory in ipairs(definition.settings.library_directories) do
|
||||
lddirs = lddirs.." /libpath:\""..directory.."\"";
|
||||
end
|
||||
end
|
||||
|
||||
local ldflags = " /nologo";
|
||||
|
||||
local intermediate_manifest = obj_directory(target)..target:id().."_intermediate.manifest";
|
||||
local intermediate_manifest = obj_directory(target.module)..target:id().."_intermediate.manifest";
|
||||
ldflags = ldflags.." /manifest /manifestfile:"..intermediate_manifest;
|
||||
|
||||
if target.settings.subsystem then
|
||||
ldflags = ldflags.." /subsystem:"..target.settings.subsystem;
|
||||
if definition.settings.subsystem then
|
||||
ldflags = ldflags.." /subsystem:"..definition.settings.subsystem;
|
||||
end
|
||||
|
||||
local out = "";
|
||||
if target:rule() == Executable then
|
||||
out = native( target:get_filename() );
|
||||
ldflags = ldflags.." /out:"..out;
|
||||
elseif target:rule() == Library then
|
||||
out = native( target.settings.bin.."/"..dll_name(target:id()) );
|
||||
ldflags = ldflags.." /out:"..out;
|
||||
ldflags = ldflags.." /dll /implib:"..native( target.settings.lib.."/"..lib_name(target:id()) );
|
||||
ldflags = ldflags.." /out:"..native( target:get_filename() );
|
||||
if target.module:prototype() == DynamicLibraryPrototype then
|
||||
ldflags = ldflags.." /dll /implib:"..native( "%s/%s.lib" % {definition.settings.lib, basename(target:id())} );
|
||||
end
|
||||
|
||||
if target.settings.verbose_linking then
|
||||
if definition.settings.verbose_linking then
|
||||
ldflags = ldflags.." /verbose";
|
||||
end
|
||||
|
||||
if target.settings.debug then
|
||||
ldflags = ldflags.." /debug /pdb:"..obj_directory(target)..pdb_name( target:id() );
|
||||
if definition.settings.debug then
|
||||
ldflags = ldflags.." /debug /pdb:"..obj_directory(target.module)..pdb_name( target:id() );
|
||||
end
|
||||
|
||||
if target.settings.link_time_code_generation then
|
||||
if definition.settings.link_time_code_generation then
|
||||
ldflags = ldflags.." /ltcg";
|
||||
end
|
||||
|
||||
if target.settings.generate_map_file then
|
||||
ldflags = ldflags.." /map:"..native(obj_directory(target)..target:id()..".map");
|
||||
if definition.settings.generate_map_file then
|
||||
ldflags = ldflags.." /map:"..native(obj_directory(target.module)..target:id()..".map");
|
||||
end
|
||||
|
||||
if target.settings.optimization then
|
||||
if definition.settings.optimization then
|
||||
ldflags = ldflags.." /opt:ref /opt:icf";
|
||||
end
|
||||
|
||||
if target.settings.stack_size then
|
||||
ldflags = ldflags.." /stack:"..tostring(target.settings.stack_size);
|
||||
if definition.settings.stack_size then
|
||||
ldflags = ldflags.." /stack:"..tostring(definition.settings.stack_size);
|
||||
end
|
||||
|
||||
local libraries = "";
|
||||
if target.libraries then
|
||||
for _, library in ipairs(target.libraries) do
|
||||
libraries = libraries.." "..lib_name( library:id() );
|
||||
libraries = "%s %s.lib" % { libraries, basename(library:id()) };
|
||||
end
|
||||
end
|
||||
if definition.third_party_libraries then
|
||||
for _, library in ipairs(definition.third_party_libraries) do
|
||||
libraries = "%s %s" % { libraries, library };
|
||||
end
|
||||
end
|
||||
|
||||
local objects = "";
|
||||
for dependency in target:get_dependencies() do
|
||||
if dependency:rule() == Cc then
|
||||
if dependency:prototype() == CompilePrototype then
|
||||
if dependency.precompiled_header ~= nil then
|
||||
objects = objects.." "..obj_name( dependency.precompiled_header:id() );
|
||||
end
|
||||
|
||||
for object in dependency:get_dependencies() do
|
||||
if object:rule() == File and object ~= dependency.precompiled_header then
|
||||
if object:prototype() == FilePrototype and object ~= dependency.precompiled_header then
|
||||
objects = objects.." "..obj_name( object:id() );
|
||||
end
|
||||
end
|
||||
|
|
@ -291,14 +343,10 @@ function build_executable( target )
|
|||
end
|
||||
|
||||
if objects ~= "" then
|
||||
if target:rule() == Executable then
|
||||
print( exe_name(target:id()) );
|
||||
else
|
||||
print( dll_name(target:id()) );
|
||||
end
|
||||
print( leaf(target:get_filename()) );
|
||||
|
||||
pushd( obj_directory(target) );
|
||||
if target.settings.incremental_linking then
|
||||
pushd( obj_directory(target.module) );
|
||||
if definition.settings.incremental_linking then
|
||||
local embedded_manifest = target:id().."_embedded.manifest";
|
||||
local embedded_manifest_rc = target:id().."_embedded_manifest.rc";
|
||||
local embedded_manifest_res = target:id().."_embedded_manifest.res";
|
||||
|
|
@ -306,7 +354,7 @@ function build_executable( target )
|
|||
if exists(embedded_manifest_rc) ~= true then
|
||||
local rc = io.open( absolute(embedded_manifest_rc), "wb" );
|
||||
assert( rc, string.format("Opening '%s' to write manifest failed", absolute(embedded_manifest_rc)) );
|
||||
if target:rule() == Executable then
|
||||
if target:prototype() == ExecutablePrototype then
|
||||
rc:write( "1 /* CREATEPROCESS_MANIFEST_RESOURCE_ID */ 24 /* RT_MANIFEST */ \""..target:id().."_embedded.manifest\"" );
|
||||
else
|
||||
rc:write( "2 /* CREATEPROCESS_MANIFEST_RESOURCE_ID */ 24 /* RT_MANIFEST */ \""..target:id().."_embedded.manifest\"" );
|
||||
|
|
@ -314,83 +362,91 @@ function build_executable( target )
|
|||
rc:close();
|
||||
end
|
||||
|
||||
IgnoreOutputScanner = Scanner {
|
||||
[ [[.*]] ] = function()
|
||||
end;
|
||||
};
|
||||
|
||||
if exists(embedded_manifest) ~= true then
|
||||
system( msld, "link"..ldflags..lddirs..objects..libraries..ldlibs );
|
||||
system( msmt, "mt /nologo /out:\""..embedded_manifest.."\" /manifest "..intermediate_manifest );
|
||||
system( msrc, "rc /Fo\""..embedded_manifest_res.."\" "..embedded_manifest_rc );
|
||||
build.system( msld, "link"..ldflags..lddirs..objects..libraries..ldlibs );
|
||||
build.system( msmt, "mt /nologo /out:\""..embedded_manifest.."\" /manifest "..intermediate_manifest );
|
||||
build.system( msrc, "rc /Fo\""..embedded_manifest_res.."\" "..embedded_manifest_rc, IgnoreOutputScanner );
|
||||
end
|
||||
|
||||
objects = objects.." "..embedded_manifest_res;
|
||||
ldflags = ldflags.." /incremental";
|
||||
|
||||
system( msld, "link"..ldflags..lddirs..objects..libraries..ldlibs );
|
||||
system( msmt, "mt /nologo /out:\""..embedded_manifest.."\" /manifest "..intermediate_manifest );
|
||||
system( msrc, "rc /Fo\""..embedded_manifest_res.."\" "..embedded_manifest_rc );
|
||||
system( msld, "link"..ldflags..lddirs..objects..libraries..ldlibs );
|
||||
build.system( msld, "link"..ldflags..lddirs..objects..libraries..ldlibs );
|
||||
build.system( msmt, "mt /nologo /out:\""..embedded_manifest.."\" /manifest "..intermediate_manifest );
|
||||
build.system( msrc, "rc /Fo\""..embedded_manifest_res.."\" "..embedded_manifest_rc, IgnoreOutputScanner );
|
||||
build.system( msld, "link"..ldflags..lddirs..objects..libraries..ldlibs );
|
||||
else
|
||||
ldflags = ldflags.." /incremental:no";
|
||||
system( msld, "link"..ldflags..lddirs..objects..libraries..ldlibs );
|
||||
build.system( msld, "link"..ldflags..lddirs..objects..libraries..ldlibs );
|
||||
sleep( 100 );
|
||||
system( msmt, "mt /nologo -outputresource:"..out..";#1 -manifest "..intermediate_manifest );
|
||||
build.system( msmt, "mt /nologo -outputresource:"..native(target:get_filename())..";#1 -manifest "..intermediate_manifest );
|
||||
end
|
||||
popd();
|
||||
end
|
||||
end
|
||||
end;
|
||||
|
||||
function clean_executable( target )
|
||||
if target:rule() == Executable then
|
||||
rm( target.settings.bin.."/"..exe_name(target:id()) );
|
||||
rm( target.settings.bin.."/"..ilk_name(target:id()) );
|
||||
rmdir( obj_directory(target) );
|
||||
function msvc.clean_executable( target, definition )
|
||||
if target.module:prototype() == ExecutablePrototype then
|
||||
rm( definition.settings.bin.."/"..exe_name(target:id()) );
|
||||
rm( definition.settings.bin.."/"..ilk_name(target:id()) );
|
||||
rmdir( obj_directory(target.module) );
|
||||
else
|
||||
rm( target.settings.bin.."/"..dll_name(target:id()) );
|
||||
rm( target.settings.bin.."/"..ilk_name(target:id()) );
|
||||
rm( target.settings.lib.."/"..lib_name(target:id()) );
|
||||
rm( target.settings.lib.."/"..exp_name(target:id()) );
|
||||
rmdir( obj_directory(target) );
|
||||
rm( definition.settings.bin.."/"..dll_name(target:id()) );
|
||||
rm( definition.settings.bin.."/"..ilk_name(target:id()) );
|
||||
rm( definition.settings.lib.."/"..lib_name(target:id()) );
|
||||
rm( definition.settings.lib.."/"..exp_name(target:id()) );
|
||||
rmdir( obj_directory(target.module) );
|
||||
end
|
||||
end;
|
||||
|
||||
function msvc.lipo_executable( target )
|
||||
end
|
||||
|
||||
function obj_directory( target )
|
||||
return target.settings.obj.."/"..platform.."_"..variant.."/"..relative( target:directory(), root() ).."/";
|
||||
function msvc.obj_directory( target )
|
||||
return "%s/%s_%s/%s/" % { target.settings.obj, platform, variant, relative(target:directory(), root()) };
|
||||
end
|
||||
|
||||
function cc_name( name )
|
||||
return basename( name )..".c";
|
||||
function msvc.cc_name( name )
|
||||
return "%s.c" % basename( name );
|
||||
end
|
||||
|
||||
function cxx_name( name )
|
||||
return basename( name )..".cpp";
|
||||
function msvc.cxx_name( name )
|
||||
return "%s.cpp" % basename( name );
|
||||
end
|
||||
|
||||
function pch_name( name )
|
||||
return basename( name )..".pch";
|
||||
function msvc.pch_name( name )
|
||||
return "%s.pch" % basename( name );
|
||||
end
|
||||
|
||||
function pdb_name( name )
|
||||
return basename( name )..".pdb";
|
||||
function msvc.pdb_name( name )
|
||||
return "%s.pdb" % basename( name );
|
||||
end
|
||||
|
||||
function obj_name( name )
|
||||
return basename( name )..".obj";
|
||||
function msvc.obj_name( name )
|
||||
return "%s.obj" % basename( name );
|
||||
end
|
||||
|
||||
function lib_name( name )
|
||||
return name.."_"..platform.."_"..variant..".lib";
|
||||
function msvc.lib_name( name )
|
||||
return "%s_%s_%s.lib" % { name, platform, variant };
|
||||
end
|
||||
|
||||
function exp_name( name )
|
||||
return name.."_"..platform.."_"..variant..".exp";
|
||||
function msvc.exp_name( name )
|
||||
return "%s_%s_%s.exp" % { name, platform, variant };
|
||||
end
|
||||
|
||||
function dll_name( name )
|
||||
return name.."_"..platform.."_"..variant..".dll";
|
||||
function msvc.dll_name( name )
|
||||
return "%s_%s_%s.dll" % { name, platform, variant };
|
||||
end
|
||||
|
||||
function exe_name( name )
|
||||
return name.."_"..platform.."_"..variant..".exe";
|
||||
function msvc.exe_name( name )
|
||||
return "%s_%s_%s.exe" % { name, platform, variant };
|
||||
end
|
||||
|
||||
function ilk_name( name )
|
||||
return name.."_"..platform.."_"..variant..".ilk";
|
||||
function msvc.ilk_name( name )
|
||||
return "%s_%s_%s.ilk" % { name, platform, variant };
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
|
||||
[footer-text]
|
||||
Copyright (C) 2006 - 2011 Charles Baker. All rights reserved.
|
||||
Copyright (C) 2006 - 2012 Charles Baker. All rights reserved.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,22 @@
|
|||
|
||||
--
|
||||
visual_studio = {};
|
||||
|
||||
-- Generate a UUID by calling the uuidgen tool.
|
||||
local function uuid()
|
||||
local uuids = {};
|
||||
local UuidScanner = Scanner {
|
||||
[ [[([A-Za-z0-9\-]+)]] ] = function( uuid )
|
||||
table.insert( uuids, uuid );
|
||||
end;
|
||||
};
|
||||
local uuidgen = "%s/Common7/Tools/uuidgen.exe" % settings.msvc.visual_studio_directory;
|
||||
local arguments = "uuidgen";
|
||||
build.system( uuidgen, arguments, UuidScanner );
|
||||
assert( uuids[1], "UUID generation failed!" );
|
||||
return upper( uuids[1] );
|
||||
end
|
||||
|
||||
-- Generate the header of the vcproj.
|
||||
--
|
||||
local function header( vcproj, target )
|
||||
local name = target.project_name or target:id();
|
||||
vcproj:write( [[
|
||||
|
|
@ -19,9 +34,7 @@ local function header( vcproj, target )
|
|||
);
|
||||
end
|
||||
|
||||
--
|
||||
-- Generate the footer of the vcproj.
|
||||
--
|
||||
local function footer( vcproj )
|
||||
vcproj:write( [[
|
||||
</VisualStudioProject>
|
||||
|
|
@ -29,62 +42,67 @@ local function footer( vcproj )
|
|||
);
|
||||
end
|
||||
|
||||
--
|
||||
-- Generate the configurations.
|
||||
--
|
||||
local function configurations( vcproj, target, include_directories )
|
||||
vcproj:write( [[
|
||||
<Configurations>
|
||||
]]
|
||||
);
|
||||
|
||||
pushd( target:directory() );
|
||||
local module = target:id();
|
||||
for variant, variant_settings in pairs(target.settings.variants) do
|
||||
local output = "";
|
||||
if target:rule() == Executable then
|
||||
output = relative( target.settings.bin.."/"..module.."_"..platform.."_"..variant..".exe" );
|
||||
end
|
||||
|
||||
local defines = "";
|
||||
defines = defines.."BUILD_PLATFORM_"..upper(platform)..";";
|
||||
defines = defines.."BUILD_VARIANT_"..upper(variant)..";";
|
||||
defines = defines.."BUILD_MODULE_"..upper(string.gsub(module, "-", "_"))..";"
|
||||
defines = defines.."BUILD_LIBRARY_TYPE_"..upper(variant_settings.library_type)..";";
|
||||
if target.settings.defines then
|
||||
for _, define in ipairs(target.settings.defines) do
|
||||
defines = defines..define..";";
|
||||
for _, platform in ipairs(target.settings.platforms) do
|
||||
for _, variant in pairs(target.settings.variants) do
|
||||
local variant_settings = target.settings.settings_by_variant[variant];
|
||||
|
||||
local output = "";
|
||||
if target:prototype() == ExecutablePrototype then
|
||||
output = relative( target.settings.bin.."/"..module.."_"..platform.."_"..variant..".exe" );
|
||||
end
|
||||
end
|
||||
if target.defines then
|
||||
for _, define in ipairs(target.defines) do
|
||||
defines = defines..define..";";
|
||||
|
||||
local defines = "";
|
||||
defines = defines.."BUILD_PLATFORM_"..upper(platform)..";";
|
||||
defines = defines.."BUILD_VARIANT_"..upper(variant)..";";
|
||||
defines = defines.."BUILD_MODULE_"..upper(string.gsub(module, "-", "_"))..";"
|
||||
defines = defines.."BUILD_LIBRARY_TYPE_"..upper(variant_settings.library_type)..";";
|
||||
if target.settings.defines then
|
||||
for _, define in ipairs(target.settings.defines) do
|
||||
defines = defines..define..";";
|
||||
end
|
||||
end
|
||||
if target.defines then
|
||||
for _, define in ipairs(target.defines) do
|
||||
defines = defines..define..";";
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
vcproj:write( [[
|
||||
<Configuration
|
||||
Name="]]..variant..[[|Win32"
|
||||
OutputDirectory="../../../../obj/]]..platform..[[_]]..variant..[[/]]..relative(target:directory(), root())..[["
|
||||
IntermediateDirectory="../../../../obj/]]..platform..[[_]]..variant..[[/]]..relative(target:directory(), root())..[["
|
||||
ConfigurationType="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCNMakeTool"
|
||||
BuildCommandLine="build command=build variant=]]..variant..[[ platform=]]..platform..[[ target=]]..target:id()..[["
|
||||
ReBuildCommandLine="build command=clean variant=]]..variant..[[ platform=]]..platform..[[ target=]]..target:id()..[[ 
 build command=build variant=]]..variant..[[ platform=]]..platform..[[ target=]]..target:id()..[["
|
||||
CleanCommandLine="build command=clean variant=]]..variant..[[ platform=]]..platform..[[ target=]]..target:id()..[["
|
||||
Output="]]..output..[["
|
||||
PreprocessorDefinitions="]]..defines..[["
|
||||
IncludeSearchPath="]]..include_directories..[["
|
||||
ForcedIncludes=""
|
||||
AssemblySearchPath=""
|
||||
ForcedUsingAssemblies=""
|
||||
CompileAsManaged=""
|
||||
/>
|
||||
</Configuration>
|
||||
]]
|
||||
);
|
||||
end
|
||||
local build_tool = native( relative(root("build/build.exe")) );
|
||||
vcproj:write( [[
|
||||
<Configuration
|
||||
Name="]]..platform..[[_]]..variant..[[|Win32"
|
||||
OutputDirectory="../../../../obj/]]..platform..[[_]]..variant..[[/]]..relative(target:directory(), root())..[["
|
||||
IntermediateDirectory="../../../../obj/]]..platform..[[_]]..variant..[[/]]..relative(target:directory(), root())..[["
|
||||
ConfigurationType="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCNMakeTool"
|
||||
BuildCommandLine="]]..build_tool..[[ variant=]]..variant..[[ platform=]]..platform..[[ goal=]]..target:id()..[["
|
||||
ReBuildCommandLine="]]..build_tool..[[ clean default variant=]]..variant..[[ platform=]]..platform..[[ goal=]]..target:id()..[["
|
||||
CleanCommandLine="]]..build_tool..[[ clean variant=]]..variant..[[ platform=]]..platform..[[ goal=]]..target:id()..[["
|
||||
Output="]]..output..[["
|
||||
PreprocessorDefinitions="]]..defines..[["
|
||||
IncludeSearchPath="]]..include_directories..[["
|
||||
ForcedIncludes=""
|
||||
AssemblySearchPath=""
|
||||
ForcedUsingAssemblies=""
|
||||
CompileAsManaged=""
|
||||
/>
|
||||
</Configuration>
|
||||
]]
|
||||
);
|
||||
end
|
||||
end
|
||||
popd();
|
||||
|
||||
vcproj:write( [[
|
||||
</Configurations>
|
||||
|
|
@ -92,9 +110,7 @@ local function configurations( vcproj, target, include_directories )
|
|||
);
|
||||
end
|
||||
|
||||
--
|
||||
-- Write the beginning of the Files element.
|
||||
--
|
||||
local function begin_files( vcproj )
|
||||
vcproj:write( [[
|
||||
<Files>
|
||||
|
|
@ -102,9 +118,7 @@ local function begin_files( vcproj )
|
|||
);
|
||||
end
|
||||
|
||||
--
|
||||
-- Write the end of the Files element.
|
||||
--
|
||||
local function end_files( vcproj, module )
|
||||
vcproj:write( [[
|
||||
<File RelativePath=".\]]..leaf(module:directory())..[[.build" />
|
||||
|
|
@ -113,58 +127,49 @@ local function end_files( vcproj, module )
|
|||
);
|
||||
end
|
||||
|
||||
--
|
||||
-- Generate files in the project that match \e include_patterns and not
|
||||
-- \e exclude_patterns.
|
||||
--
|
||||
local function files( vcproj, directory, include_patterns, exclude_patterns, level )
|
||||
function match_( filename, patterns )
|
||||
for _, pattern in ipairs(patterns) do
|
||||
if string.match(filename, pattern) then
|
||||
return true;
|
||||
end
|
||||
end
|
||||
return false;
|
||||
-- Generate files in the project.
|
||||
local function generate_files( vcproj, directory, files, level )
|
||||
pushd( directory );
|
||||
for _, file in ipairs(files) do
|
||||
vcproj:write( string.rep(" ", level) );
|
||||
vcproj:write( "<File RelativePath=\""..native(relative(file:get_filename())).."\" />\n" );
|
||||
end
|
||||
|
||||
vcproj:write( string.rep(" ", level) );
|
||||
vcproj:write( "<Filter Name=\""..basename(directory).."\" Filter=\"\">\n" );
|
||||
|
||||
for entry in ls(directory) do
|
||||
if is_file(entry) and match_(entry, include_patterns) and not match_(entry, exclude_patterns) then
|
||||
vcproj:write( string.rep(" ", level + 1) );
|
||||
vcproj:write( "<File RelativePath=\""..native(relative(entry)).."\" />\n" );
|
||||
end
|
||||
end
|
||||
|
||||
vcproj:write( string.rep(" ", level) );
|
||||
vcproj:write( "</Filter>\n" );
|
||||
popd();
|
||||
end
|
||||
|
||||
--
|
||||
-- Write out a Microsoft Visual Studio project for an Executable or Library.
|
||||
--
|
||||
function generate_visual_studio_project( filename, module )
|
||||
-- Generate a Visual Studio project for /module/ to /filename/.
|
||||
local function generate_project( filename, module )
|
||||
print( filename );
|
||||
|
||||
local function populate_files( files, directory )
|
||||
return function( target )
|
||||
if target:directory() == directory and (target:prototype() == SourceFilePrototype or target:prototype() == HeaderFilePrototype) then
|
||||
table.insert( files, target );
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local include_directories = "";
|
||||
for _, directory in ipairs(module.settings.include_directories) do
|
||||
include_directories = include_directories..native(directory)..";";
|
||||
end
|
||||
|
||||
local files = {};
|
||||
preorder( populate_files(files, module:directory()), module );
|
||||
|
||||
local vcproj = io.open( absolute(filename), "wb" );
|
||||
header( vcproj, module );
|
||||
configurations( vcproj, module, include_directories );
|
||||
begin_files( vcproj );
|
||||
local include_patterns = { ".*%.c$", ".*%.cpp$", ".*%.h$", ".*%.hpp$", ".*%.ipp$", ".*%.lua$", ".*%.g$" };
|
||||
local exclude_patterns = { "/moc_.*" };
|
||||
files( vcproj, absolute("."), include_patterns, exclude_patterns, 2 );
|
||||
generate_files( vcproj, module:directory(), files, 2 );
|
||||
end_files( vcproj, module );
|
||||
footer( vcproj );
|
||||
vcproj:close();
|
||||
end
|
||||
|
||||
function generate_visual_studio_solution( filename, solution )
|
||||
-- Generate a Visual Studio solution for /solution/, containing /modules/
|
||||
-- and /directories/ to /filename/.
|
||||
local function generate_solution( filename, solution, modules, directories )
|
||||
print( filename );
|
||||
|
||||
local sln = io.open( absolute(filename), "wb" );
|
||||
|
|
@ -174,25 +179,204 @@ Microsoft Visual Studio Solution File, Format Version 10.00
|
|||
]]
|
||||
);
|
||||
|
||||
for target in solution:get_dependencies() do
|
||||
if target:rule() == Project then
|
||||
sln:write( string.format([[
|
||||
Project("{}") = "%s", "%s.vcproj", "{}"
|
||||
pushd( branch(absolute(filename)) );
|
||||
local project_uuid = "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942";
|
||||
for path, module in pairs(modules) do
|
||||
local name = module.target.project_name or module.target:id();
|
||||
local filename = "%s%s.vcproj" % { module.target:directory(), name };
|
||||
sln:write( string.format([[
|
||||
Project("{%s}") = "%s", "%s", "{%s}"
|
||||
EndProject
|
||||
]], basename(target:get_id()), native(relative(target:path())))
|
||||
);
|
||||
end
|
||||
]], project_uuid, name, native(relative(filename)), module.uuid)
|
||||
);
|
||||
end;
|
||||
|
||||
sln:write( [[
|
||||
Project("{}") = "Solution Items", "Solution Items", "{}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
build.hpp = build.hpp
|
||||
build.lua = build.lua
|
||||
EndProjectSection
|
||||
local folder_uuid = "2150E333-8FDC-42A3-9474-1A3956D46DE8";
|
||||
local function generate_directories( directories )
|
||||
for _, directory in ipairs(directories) do
|
||||
if directory.children then
|
||||
sln:write([[
|
||||
Project("{%s}") = "%s", "%s", "{%s}"
|
||||
EndProject
|
||||
]]
|
||||
% {folder_uuid, directory.target:id(), directory.target:id(), directory.uuid}
|
||||
);
|
||||
generate_directories( directory.children );
|
||||
end
|
||||
end
|
||||
end
|
||||
generate_directories( directories );
|
||||
|
||||
local build_hpp = native( relative(root("build.hpp")) );
|
||||
local build_lua = native( relative(root("build.lua")) );
|
||||
local local_settings_lua = native( relative(root("local_settings.lua")) );
|
||||
sln:write( [[
|
||||
Project("{%s}") = "Solution Items", "Solution Items", "{%s}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
%s = %s
|
||||
%s = %s
|
||||
%s = %s
|
||||
EndProjectSection
|
||||
EndProject
|
||||
]] % {folder_uuid, uuid(), build_hpp, build_hpp, build_lua, build_lua, local_settings_lua, local_settings_lua }
|
||||
);
|
||||
popd();
|
||||
|
||||
sln:write([[
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
]]
|
||||
);
|
||||
for _, platform in ipairs(build.settings.platforms) do
|
||||
for _, variant in ipairs(build.settings.variants) do
|
||||
sln:write([[
|
||||
%s_%s|Win32 = %s_%s|Win32
|
||||
]]
|
||||
% {platform, variant, platform, variant}
|
||||
);
|
||||
end
|
||||
end
|
||||
|
||||
sln:write([[
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
]]
|
||||
);
|
||||
|
||||
for _, module in pairs(modules) do
|
||||
for _, platform in ipairs(module.target.settings.platforms) do
|
||||
for _, variant in ipairs(module.target.settings.variants) do
|
||||
sln:write([[
|
||||
{%s}.%s_%s|Win32.ActiveCfg = %s_%s|Win32
|
||||
{%s}.%s_%s|Win32.Build.0 = %s_%s|Win32
|
||||
]]
|
||||
% {module.uuid, platform, variant, platform, variant, module.uuid, platform, variant, platform, variant}
|
||||
);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
sln:write([[
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
]]
|
||||
);
|
||||
|
||||
local function generate_nested_projects( directory )
|
||||
if directory and directory.children then
|
||||
for _, child in ipairs(directory.children) do
|
||||
sln:write([[
|
||||
{%s} = {%s}
|
||||
]]
|
||||
% {child.uuid, directory.uuid}
|
||||
);
|
||||
end
|
||||
for _, directory in ipairs(directory.children) do
|
||||
generate_nested_projects( directory );
|
||||
end
|
||||
end
|
||||
end
|
||||
for _, directory in ipairs(directories) do
|
||||
generate_nested_projects( directory );
|
||||
end
|
||||
|
||||
sln:write([[
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
]]
|
||||
);
|
||||
|
||||
sln:close();
|
||||
end
|
||||
|
||||
-- Configure the Visual Studio module.
|
||||
function visual_studio.configure()
|
||||
end
|
||||
|
||||
-- Initiailize Visual Studio module.
|
||||
function visual_studio.initialize()
|
||||
end
|
||||
|
||||
-- Generate a Visual Studio solution and projects for the project and modules
|
||||
-- that are dependencies of /root_target/ to /filename/.
|
||||
function visual_studio.generate_solution_and_projects( filename, root_target )
|
||||
local function populate( modules, directories )
|
||||
local function add_directory( target )
|
||||
local directory = directories[target:path()];
|
||||
if directory == nil then
|
||||
directory = { target = target; children = {} };
|
||||
directories[target:path()] = directory;
|
||||
if target:parent() then
|
||||
local parent = add_directory( target:parent() );
|
||||
table.insert( parent.children, directory );
|
||||
end
|
||||
end
|
||||
return directory;
|
||||
end
|
||||
|
||||
local function add_module( target )
|
||||
local module = modules[target:path()];
|
||||
if module == nil then
|
||||
module = { target = target };
|
||||
modules[target:path()] = module;
|
||||
if target:parent() then
|
||||
local parent = add_directory( target:parent() );
|
||||
table.insert( parent.children, module );
|
||||
end
|
||||
end
|
||||
return module;
|
||||
end
|
||||
|
||||
return function( target )
|
||||
if target:prototype() == ExecutablePrototype or target:prototype() == StaticLibraryPrototype or target:prototype() == DynamicLibraryPrototype then
|
||||
add_module( target );
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function prune( directory )
|
||||
if directory and directory.children then
|
||||
if #directory.children == 1 then
|
||||
local pruned_child = directory.children[1];
|
||||
directory.uuid = pruned_child.uuid;
|
||||
directory.target = pruned_child.target;
|
||||
directory.children = pruned_child.children;
|
||||
else
|
||||
for _, child in ipairs(directory.children) do
|
||||
prune( child );
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function generate_uuids( objects )
|
||||
for _, object in pairs(objects) do
|
||||
object.uuid = uuid();
|
||||
end
|
||||
end
|
||||
|
||||
local modules = {};
|
||||
local directories = {};
|
||||
preorder( populate(modules, directories), root_target );
|
||||
generate_uuids( modules );
|
||||
generate_uuids( directories );
|
||||
prune( directories[root_target:path()] );
|
||||
|
||||
for path, module in pairs(modules) do
|
||||
local name = module.target.project_name or module.target:id();
|
||||
generate_project( "%s%s.vcproj" % {module.target:directory(), name}, module.target );
|
||||
end
|
||||
generate_solution( filename, root_target, modules, directories[root_target:path()].children );
|
||||
end
|
||||
|
||||
-- The "sln" command entry point (global).
|
||||
function sln()
|
||||
build.load();
|
||||
local all = all or find_target( root() );
|
||||
assert( all, "No target found at '"..tostring(root()).."'" );
|
||||
assert( settings.sln, "The solution filename is not specified by settings.sln" );
|
||||
visual_studio.generate_solution_and_projects( settings.sln, all );
|
||||
end
|
||||
|
|
|
|||
375
sweet/build/lua/build/xcode.lua
Normal file
375
sweet/build/lua/build/xcode.lua
Normal file
|
|
@ -0,0 +1,375 @@
|
|||
|
||||
local id = 256;
|
||||
local function uuid()
|
||||
id = id + 1;
|
||||
return "%08x%08x%08x" % { id, id, id };
|
||||
end
|
||||
|
||||
local files = {};
|
||||
local groups = {};
|
||||
local targets = {};
|
||||
local project_root = "";
|
||||
local project_uuid = "";
|
||||
|
||||
local function add_group( target )
|
||||
assert( target );
|
||||
|
||||
local path = target:path();
|
||||
local group = groups[path];
|
||||
if not group then
|
||||
group = {
|
||||
uuid = uuid();
|
||||
target = target;
|
||||
children = {};
|
||||
};
|
||||
groups[path] = group;
|
||||
|
||||
if target:parent() and target:path() ~= root() then
|
||||
local parent = add_group( target:parent() );
|
||||
table.insert( parent.children, group );
|
||||
end
|
||||
end
|
||||
return group;
|
||||
end
|
||||
|
||||
local function add_file( target )
|
||||
assert( target );
|
||||
|
||||
if target:parent() then
|
||||
local path = target:path();
|
||||
local file = files[path];
|
||||
if not file then
|
||||
file = {
|
||||
uuid = uuid();
|
||||
target = target
|
||||
};
|
||||
files[path] = file;
|
||||
|
||||
local group = add_group( target:parent() );
|
||||
table.insert( group.children, file );
|
||||
end
|
||||
end
|
||||
return file;
|
||||
end
|
||||
|
||||
local function add_target( module )
|
||||
assert( module );
|
||||
|
||||
local path = module:path();
|
||||
local target = targets[path];
|
||||
if not target then
|
||||
target = {
|
||||
uuid = uuid();
|
||||
target = module;
|
||||
configurations = {};
|
||||
configuration_list_uuid = uuid();
|
||||
};
|
||||
targets[path] = target;
|
||||
|
||||
local buildfile = absolute("%s.build" % module:id(), module:get_working_directory():path());
|
||||
if exists(buildfile) then
|
||||
add_file( File(buildfile) );
|
||||
end
|
||||
|
||||
for _, variant in pairs(module.settings.variants) do
|
||||
local configuration = {
|
||||
uuid = uuid();
|
||||
target = module;
|
||||
variant = variant;
|
||||
};
|
||||
table.insert( target.configurations, configuration );
|
||||
end
|
||||
end
|
||||
return target;
|
||||
end
|
||||
|
||||
local function header( xcodeproj, project )
|
||||
xcodeproj:write([[
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
]]
|
||||
);
|
||||
end;
|
||||
|
||||
local function generate_files( xcodeproj, files )
|
||||
for path, file in pairs(files) do
|
||||
xcodeproj:write([[
|
||||
%s /* %s */ = { isa = PBXFileReference; lastKnownFileType = text; path = %s; sourceTree = "<group>"; };
|
||||
]]
|
||||
% { file.uuid, file.target:id(), file.target:id() }
|
||||
);
|
||||
end
|
||||
end
|
||||
|
||||
local function generate_groups( xcodeproj, groups )
|
||||
|
||||
local sorted_groups = {};
|
||||
for path, group in pairs(groups) do
|
||||
table.insert( sorted_groups, group );
|
||||
end
|
||||
table.sort( sorted_groups, function(lhs, rhs) return lhs.target:id() < rhs.target:id() end );
|
||||
|
||||
for _, group in pairs(sorted_groups) do
|
||||
xcodeproj:write([[
|
||||
%s /* %s */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
]]
|
||||
% { group.uuid, group.target:path() }
|
||||
);
|
||||
|
||||
table.sort( group.children, function(lhs, rhs)
|
||||
local lhs_file = 0;
|
||||
if is_file(lhs.target:path()) then
|
||||
lhs_file = 1;
|
||||
end
|
||||
local rhs_file = 0;
|
||||
if is_file(rhs.target:path()) then
|
||||
rhs_file = 1;
|
||||
end
|
||||
return
|
||||
lhs_file < rhs_file or
|
||||
(lhs_file == rhs_file and lhs.target:id() < rhs.target:id())
|
||||
;
|
||||
end);
|
||||
for _, child in ipairs(group.children) do
|
||||
xcodeproj:write([[
|
||||
%s /* %s */,
|
||||
]]
|
||||
% { child.uuid, child.target:id() }
|
||||
);
|
||||
end;
|
||||
local base;
|
||||
if group.target:parent() then
|
||||
base = group.target:parent():path();
|
||||
else
|
||||
base = project_root;
|
||||
end
|
||||
xcodeproj:write([[
|
||||
);
|
||||
name = %s;
|
||||
path = %s;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
]] % { group.target:id(), relative(group.target:path(), base) }
|
||||
);
|
||||
end
|
||||
end
|
||||
|
||||
local function generate_targets( xcodeproj, targets )
|
||||
|
||||
local sorted_targets = {};
|
||||
for path, target in pairs(targets) do
|
||||
table.insert( sorted_targets, target );
|
||||
end
|
||||
table.sort( sorted_targets, function(lhs, rhs) return lhs.target:id() < rhs.target:id() end );
|
||||
|
||||
for _, target in ipairs(sorted_targets) do
|
||||
local name = target.target:id();
|
||||
xcodeproj:write([[
|
||||
%s /* %s */ = {
|
||||
isa = PBXLegacyTarget;
|
||||
buildArgumentsString = "variant=$(CONFIGURATION) action=$(ACTION) xcode_build";
|
||||
buildConfigurationList = %s /* Build configuration list for PBXLegacyTarget "%s" */;
|
||||
buildPhases = (
|
||||
);
|
||||
buildToolPath = %s;
|
||||
buildWorkingDirectory = %s;
|
||||
dependencies = (
|
||||
);
|
||||
name = %s;
|
||||
passBuildSettingsInEnvironment = 1;
|
||||
productName = %s;
|
||||
};
|
||||
]]
|
||||
% { target.uuid, name, target.configuration_list_uuid, name, home("bin/build"), target.target:get_working_directory():path(), name, name }
|
||||
);
|
||||
end
|
||||
end
|
||||
|
||||
local function generate_project( xcodeproj, groups )
|
||||
local main_group = groups[root()];
|
||||
assert( main_group, "The main group for the Xcode project wasn't found" );
|
||||
|
||||
project_uuid = uuid();
|
||||
|
||||
xcodeproj:write([[
|
||||
%s /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0430;
|
||||
};
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = %s;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
]]
|
||||
% { project_uuid, main_group.uuid }
|
||||
);
|
||||
|
||||
local sorted_targets = {};
|
||||
for path, target in pairs(targets) do
|
||||
table.insert( sorted_targets, target );
|
||||
end
|
||||
table.sort( sorted_targets, function(lhs, rhs) return lhs.target:id() < rhs.target:id() end );
|
||||
|
||||
for _, target in ipairs(sorted_targets) do
|
||||
xcodeproj:write([[
|
||||
%s /* %s */,
|
||||
]]
|
||||
% { target.uuid, target.target:id() }
|
||||
);
|
||||
end
|
||||
xcodeproj:write([[
|
||||
);
|
||||
};
|
||||
]]
|
||||
);
|
||||
end
|
||||
|
||||
local function generate_configurations( xcodeproj, targets )
|
||||
local sorted_targets = {};
|
||||
for path, target in pairs(targets) do
|
||||
table.insert( sorted_targets, target );
|
||||
end
|
||||
table.sort( sorted_targets, function(lhs, rhs) return lhs.target:id() < rhs.target:id() end );
|
||||
|
||||
for _, target in pairs(sorted_targets) do
|
||||
table.sort( target.configurations, function(lhs, rhs) return lhs.variant < rhs.variant end );
|
||||
for _, configuration in ipairs(target.configurations) do
|
||||
local archs = table.concat( target.target.settings.architectures or {}, " " );
|
||||
xcodeproj:write([[
|
||||
%s /* %s */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "%s";
|
||||
VALID_ARCHS = "%s";
|
||||
};
|
||||
name = %s;
|
||||
};
|
||||
]]
|
||||
% { configuration.uuid, target.target:id(), archs, archs, configuration.variant }
|
||||
);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function generate_configuration_lists( xcodeproj, targets )
|
||||
local sorted_targets = {};
|
||||
for path, target in pairs(targets) do
|
||||
table.insert( sorted_targets, target );
|
||||
end
|
||||
table.sort( sorted_targets, function(lhs, rhs) return lhs.target:id() < rhs.target:id() end );
|
||||
|
||||
for _, target in pairs(sorted_targets) do
|
||||
xcodeproj:write([[
|
||||
%s /* Build configuration list for PBXLegacyTarget "%s" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
]]
|
||||
% { target.configuration_list_uuid, target.target:id() }
|
||||
);
|
||||
for _, configuration in ipairs(target.configurations) do
|
||||
xcodeproj:write([[
|
||||
%s /* %s */,
|
||||
]]
|
||||
% { configuration.uuid, configuration.variant }
|
||||
);
|
||||
end
|
||||
xcodeproj:write([[
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
};
|
||||
]]
|
||||
);
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function footer( xcodeproj, project )
|
||||
xcodeproj:write([[
|
||||
};
|
||||
rootObject = %s /* Project object */;
|
||||
}
|
||||
]]
|
||||
% project_uuid
|
||||
);
|
||||
end;
|
||||
|
||||
local function populate( target )
|
||||
if target:prototype() == SourceFilePrototype or target:prototype() == HeaderFilePrototype then
|
||||
add_file( target );
|
||||
elseif target:prototype() == Directory then
|
||||
add_group( target );
|
||||
elseif target:prototype() == ExecutablePrototype then
|
||||
add_target( target );
|
||||
end
|
||||
end
|
||||
|
||||
xcode = {};
|
||||
|
||||
function xcode.configure( settings )
|
||||
end
|
||||
|
||||
function xcode.initialize( settings )
|
||||
xcode.configure( settings );
|
||||
end
|
||||
|
||||
function xcode.generate_project( name, project )
|
||||
project_root = branch( name );
|
||||
preorder( populate, project );
|
||||
if exists(root("build.lua")) then
|
||||
add_file( find_target(root("build.lua")) );
|
||||
end
|
||||
|
||||
local xcodeproj_directory = "%s" % name;
|
||||
if not exists(xcodeproj_directory) then
|
||||
mkdir( xcodeproj_directory );
|
||||
end
|
||||
assert( is_directory(xcodeproj_directory), "The file '%s' already exists but is not a directory as expected" % xcodeproj_directory );
|
||||
|
||||
local xcodeproj = io.open( absolute("project.pbxproj", xcodeproj_directory), "wb" );
|
||||
assert( xcodeproj, "Opening '%s' to write Xcode project file failed" % filename );
|
||||
header( xcodeproj, project );
|
||||
generate_files( xcodeproj, files );
|
||||
generate_groups( xcodeproj, groups );
|
||||
generate_targets( xcodeproj, targets );
|
||||
generate_project( xcodeproj, groups );
|
||||
generate_configurations( xcodeproj, targets );
|
||||
generate_configuration_lists( xcodeproj, targets );
|
||||
footer( xcodeproj, project );
|
||||
xcodeproj:close();
|
||||
end
|
||||
|
||||
-- The "xcodeproj" command entry point (global).
|
||||
function xcodeproj()
|
||||
build.load();
|
||||
local all = all or find_target( root() );
|
||||
assert( all, "No target found at '%s'" % root() );
|
||||
assert( settings.xcodeproj, "The project filename is not specified by settings.xcodeproj" );
|
||||
xcode.generate_project( settings.xcodeproj, all );
|
||||
end
|
||||
|
||||
-- The "xcode_build" command entry point (global) this is used by generated
|
||||
-- Xcode projects to trigger a build or clean.
|
||||
function xcode_build()
|
||||
action = action or "build";
|
||||
if action == "" or action == "build" then
|
||||
default();
|
||||
elseif action == "clean" then
|
||||
clean();
|
||||
else
|
||||
error( "Unable to map the Xcode action '%s' to a build command" % tostring(action) );
|
||||
end
|
||||
end
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// AddOption.cpp
|
||||
// Copyright (c) 2008 - 2011 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2008 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#include "AddOption.hpp"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// AddOption.hpp
|
||||
// Copyright (c) 2008 - 2011 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2008 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef SWEET_CMDLINE_ADDOPTION_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// Error.cpp
|
||||
// Copyright (c) 2008 - 2011 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2008 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#include "Error.hpp"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// Error.hpp
|
||||
// Copyright (c) 2008 - 2011 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2008 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef SWEET_CMDLINE_ERROR_HPP_INCLUDED
|
||||
|
|
@ -23,8 +23,8 @@ namespace cmdline
|
|||
*/
|
||||
enum ErrorCodes
|
||||
{
|
||||
CMDLINE_ERROR_NONE, ///< No error has occured.
|
||||
CMDLINE_ERROR_INVALID_OPTION, ///< An option on the command line is not recognized or expects an argument and is grouped with other options.
|
||||
CMDLINE_ERROR_NONE, ///< No error has occured.
|
||||
CMDLINE_ERROR_INVALID_OPTION, ///< An option on the command line is not recognized or expects an argument and is grouped with other options.
|
||||
CMDLINE_ERROR_INVALID_ARGUMENT ///< An option on the command line that requires an argument doesn't have one.
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// Option.cpp
|
||||
// Copyright (c) 2008 - 2011 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2008 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#include "Option.hpp"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// Option.hpp
|
||||
// Copyright (c) 2008 - 2011 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2008 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef SWEET_CMDLINE_OPTION_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
//
|
||||
// Parser.cpp
|
||||
// Copyright (c) 2008 - 2011 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2008 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#include "Parser.hpp"
|
||||
#include "Error.hpp"
|
||||
#include <sweet/assert/assert.hpp>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
using std::vector;
|
||||
using namespace sweet::cmdline;
|
||||
|
|
@ -17,6 +21,10 @@ Parser::Parser()
|
|||
{
|
||||
}
|
||||
|
||||
void Parser::parse( int argc, char** argv ) const
|
||||
{
|
||||
parse( argc, const_cast<const char**>(argv) );
|
||||
}
|
||||
|
||||
/**
|
||||
// Parse a command line using the Options that have been added to this
|
||||
|
|
@ -31,8 +39,7 @@ Parser::Parser()
|
|||
// @return
|
||||
// True if parsing the command line succeeded otherwise false.
|
||||
*/
|
||||
void
|
||||
Parser::parse( int argc, char** argv ) const
|
||||
void Parser::parse( int argc, const char** argv ) const
|
||||
{
|
||||
int argi = 1;
|
||||
while ( argi < argc )
|
||||
|
|
@ -96,7 +103,6 @@ Parser::parse( int argc, char** argv ) const
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
// Print the Options that this Parser recognises to a stream.
|
||||
//
|
||||
|
|
@ -109,8 +115,7 @@ Parser::parse( int argc, char** argv ) const
|
|||
// @return
|
||||
// Nothing.
|
||||
*/
|
||||
void
|
||||
Parser::print( FILE* stream, int width ) const
|
||||
void Parser::print( FILE* stream, int width ) const
|
||||
{
|
||||
SWEET_ASSERT( stream );
|
||||
|
||||
|
|
@ -138,7 +143,6 @@ Parser::print( FILE* stream, int width ) const
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
// Add Options to this Parser.
|
||||
//
|
||||
|
|
@ -146,13 +150,11 @@ Parser::print( FILE* stream, int width ) const
|
|||
// An AddOption helper object that provides a convenient syntax for adding
|
||||
// Options to this Parser.
|
||||
*/
|
||||
AddOption
|
||||
Parser::add_options()
|
||||
AddOption Parser::add_options()
|
||||
{
|
||||
return AddOption( &options_, &operands_ );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
// Is a command line argument a short option?
|
||||
//
|
||||
|
|
@ -162,14 +164,12 @@ Parser::add_options()
|
|||
// @return
|
||||
// True if \e argument is a short option otherwise false.
|
||||
*/
|
||||
bool
|
||||
Parser::is_short_option( const char* argument ) const
|
||||
bool Parser::is_short_option( const char* argument ) const
|
||||
{
|
||||
SWEET_ASSERT( argument != 0 );
|
||||
return argument[0] == '-' && argument[1] != '-';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
// Is a command line argument a long option?
|
||||
//
|
||||
|
|
@ -179,14 +179,12 @@ Parser::is_short_option( const char* argument ) const
|
|||
// @return
|
||||
// True if \e argument is a long option otherwise false.
|
||||
*/
|
||||
bool
|
||||
Parser::is_long_option( const char* argument ) const
|
||||
bool Parser::is_long_option( const char* argument ) const
|
||||
{
|
||||
SWEET_ASSERT( argument != 0 );
|
||||
return argument[0] == '-' && argument[1] == '-';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
// Find an Option by name.
|
||||
//
|
||||
|
|
@ -196,8 +194,7 @@ Parser::is_long_option( const char* argument ) const
|
|||
// @return
|
||||
// The Option or null if no matching Option was found.
|
||||
*/
|
||||
const Option*
|
||||
Parser::find_option_by_name( const std::string& name ) const
|
||||
const Option* Parser::find_option_by_name( const std::string& name ) const
|
||||
{
|
||||
vector<Option>::const_iterator option = options_.begin();
|
||||
while ( option != options_.end() && option->get_name() != name )
|
||||
|
|
@ -208,7 +205,6 @@ Parser::find_option_by_name( const std::string& name ) const
|
|||
return option != options_.end() ? &(*option) : 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
// Find an Option by its short name.
|
||||
//
|
||||
|
|
@ -218,8 +214,7 @@ Parser::find_option_by_name( const std::string& name ) const
|
|||
// @return
|
||||
// The Option or null if no matching Option was found.
|
||||
*/
|
||||
const Option*
|
||||
Parser::find_option_by_short_name( const std::string& short_name ) const
|
||||
const Option* Parser::find_option_by_short_name( const std::string& short_name ) const
|
||||
{
|
||||
vector<Option>::const_iterator option = options_.begin();
|
||||
while ( option != options_.end() && option->get_short_name() != short_name )
|
||||
|
|
@ -230,7 +225,6 @@ Parser::find_option_by_short_name( const std::string& short_name ) const
|
|||
return option != options_.end() ? &(*option) : 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
// Find the end of a name in a command line argument.
|
||||
//
|
||||
|
|
@ -243,10 +237,9 @@ Parser::find_option_by_short_name( const std::string& short_name ) const
|
|||
// @return
|
||||
// The end of the name in \e name.
|
||||
*/
|
||||
const char*
|
||||
Parser::find_end_of_name( const char* name ) const
|
||||
const char* Parser::find_end_of_name( const char* name ) const
|
||||
{
|
||||
SWEET_ASSERT( name != 0 );
|
||||
SWEET_ASSERT( name );
|
||||
|
||||
while ( *name != 0 && *name != '=' )
|
||||
{
|
||||
|
|
@ -256,7 +249,6 @@ Parser::find_end_of_name( const char* name ) const
|
|||
return name;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
// Find the beginning of the argument (if there is one) in a command line
|
||||
// argument.
|
||||
|
|
@ -270,10 +262,9 @@ Parser::find_end_of_name( const char* name ) const
|
|||
// @return
|
||||
// The beginning of the argument after \e name_end.
|
||||
*/
|
||||
const char*
|
||||
Parser::find_argument( const char* name_end ) const
|
||||
const char* Parser::find_argument( const char* name_end ) const
|
||||
{
|
||||
SWEET_ASSERT( name_end != 0 );
|
||||
SWEET_ASSERT( name_end );
|
||||
|
||||
if ( *name_end != '=' )
|
||||
{
|
||||
|
|
@ -283,7 +274,6 @@ Parser::find_argument( const char* name_end ) const
|
|||
return name_end;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
// Parse an Option.
|
||||
//
|
||||
|
|
@ -306,12 +296,11 @@ Parser::find_argument( const char* name_end ) const
|
|||
// argument that was contained within the argument following the argument
|
||||
// that the Option was in).
|
||||
*/
|
||||
int
|
||||
Parser::parse_option( const Option* option, const char* argument, const char* next_argument ) const
|
||||
int Parser::parse_option( const Option* option, const char* argument, const char* next_argument ) const
|
||||
{
|
||||
SWEET_ASSERT( option != 0 );
|
||||
SWEET_ASSERT( option->get_address() != 0 );
|
||||
SWEET_ASSERT( argument != 0 );
|
||||
SWEET_ASSERT( option );
|
||||
SWEET_ASSERT( option->get_address() );
|
||||
SWEET_ASSERT( argument );
|
||||
|
||||
//
|
||||
// If the Option is not a boolean option then it must have an argument that
|
||||
|
|
|
|||
|
|
@ -1,15 +1,17 @@
|
|||
//
|
||||
// Parser.hpp
|
||||
// Copyright (c) 2008 - 2011 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2008 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef SWEET_CMDLINE_PARSER_HPP_INCLUDED
|
||||
#define SWEET_CMDLINE_PARSER_HPP_INCLUDED
|
||||
|
||||
#include "cmdline.hpp"
|
||||
#include "declspec.hpp"
|
||||
#include "Option.hpp"
|
||||
#include "AddOption.hpp"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace sweet
|
||||
{
|
||||
|
|
@ -22,27 +24,23 @@ namespace cmdline
|
|||
*/
|
||||
class SWEET_CMDLINE_DECLSPEC Parser
|
||||
{
|
||||
std::vector<Option> options_; ///< The Options that this Parser will parse from the command line.
|
||||
std::vector<std::string>* operands_; ///< The vector of strings that this Parser will parse operands from the command line into.
|
||||
std::vector<Option> options_; ///< The Options that this Parser will parse from the command line.
|
||||
std::vector<std::string>* operands_; ///< The vector of strings that this Parser will parse operands from the command line into.
|
||||
|
||||
public:
|
||||
Parser();
|
||||
|
||||
AddOption add_options();
|
||||
|
||||
void parse( int argc, char** argv ) const;
|
||||
void parse( int argc, const char** argv ) const;
|
||||
void print( FILE* stream, int width = 12 ) const;
|
||||
|
||||
private:
|
||||
bool is_short_option( const char* argument ) const;
|
||||
bool is_long_option( const char* argument ) const;
|
||||
|
||||
const Option* find_option_by_name( const std::string& name ) const;
|
||||
const Option* find_option_by_short_name( const std::string& short_name ) const;
|
||||
|
||||
const char* find_end_of_name( const char* name ) const;
|
||||
const char* find_argument( const char* name_end ) const;
|
||||
|
||||
int parse_option( const Option* option, const char* argument, const char* next_argument ) const;
|
||||
};
|
||||
|
||||
|
|
|
|||
125
sweet/cmdline/Splitter.cpp
Normal file
125
sweet/cmdline/Splitter.cpp
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
|
||||
#include "Splitter.hpp"
|
||||
#include <sweet/assert/assert.hpp>
|
||||
#include <string.h>
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using namespace sweet::cmdline;
|
||||
|
||||
/**
|
||||
// Constructor.
|
||||
//
|
||||
// @param command_line
|
||||
// The string to split into arguments at whitespace characters while
|
||||
// combining arguments surrounded by single or double quotes (assumed not
|
||||
// null).
|
||||
*/
|
||||
Splitter::Splitter( const char* command_line )
|
||||
: command_line_( command_line ),
|
||||
arguments_()
|
||||
{
|
||||
SWEET_ASSERT( command_line );
|
||||
|
||||
const char DOUBLE_QUOTE = '"';
|
||||
const char SINGLE_QUOTE = '\'';
|
||||
const char BACKSLASH = '\\';
|
||||
|
||||
bool ended = true;
|
||||
char quote = 0;
|
||||
unsigned int length = strlen( command_line );
|
||||
command_line_.insert( command_line_.end(), 0, length );
|
||||
char* destination = &command_line_[0];
|
||||
const char* i = command_line;
|
||||
const char* end = i + length;
|
||||
while ( i != end )
|
||||
{
|
||||
if ( !quote )
|
||||
{
|
||||
while ( i != end && isspace(*i) )
|
||||
{
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
if ( i != end )
|
||||
{
|
||||
if ( *i == SINGLE_QUOTE || *i == DOUBLE_QUOTE )
|
||||
{
|
||||
quote = *i;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
if ( i != end && ended )
|
||||
{
|
||||
ended = false;
|
||||
arguments_.push_back( destination );
|
||||
}
|
||||
|
||||
if ( i != end && quote )
|
||||
{
|
||||
while ( i != end && *i != quote )
|
||||
{
|
||||
if ( *i == BACKSLASH )
|
||||
{
|
||||
++i;
|
||||
}
|
||||
if ( i != end )
|
||||
{
|
||||
*destination = *i;
|
||||
++i;
|
||||
++destination;
|
||||
}
|
||||
}
|
||||
quote = 0;
|
||||
if ( i != end )
|
||||
{
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
while ( i != end && !quote && !isspace(*i) )
|
||||
{
|
||||
if ( *i == DOUBLE_QUOTE || *i == SINGLE_QUOTE )
|
||||
{
|
||||
quote = *i;
|
||||
++i;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( i != end && *i == BACKSLASH )
|
||||
{
|
||||
++i;
|
||||
}
|
||||
if ( i != end )
|
||||
{
|
||||
*destination = *i;
|
||||
++i;
|
||||
++destination;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !quote )
|
||||
{
|
||||
ended = true;
|
||||
*destination = 0;
|
||||
++destination;
|
||||
}
|
||||
}
|
||||
|
||||
arguments_.push_back( NULL );
|
||||
}
|
||||
|
||||
/**
|
||||
// Get the arguments that the command line was split into.
|
||||
//
|
||||
// @return
|
||||
// The arguments (including a NULL terminator as the last element as required
|
||||
// by posix_spawn() etc).
|
||||
*/
|
||||
const std::vector<char*>& Splitter::arguments()
|
||||
{
|
||||
return arguments_;
|
||||
}
|
||||
32
sweet/cmdline/Splitter.hpp
Normal file
32
sweet/cmdline/Splitter.hpp
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef SWEET_CMDLINE_SPLITTER_HPP_INCLUDED
|
||||
#define SWEET_CMDLINE_SPLITTER_HPP_INCLUDED
|
||||
|
||||
#include "declspec.hpp"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace sweet
|
||||
{
|
||||
|
||||
namespace cmdline
|
||||
{
|
||||
|
||||
/**
|
||||
// Split a string into an array of const char* suitable for passing to
|
||||
// exec(), posix_spawn(), etc.
|
||||
*/
|
||||
class SWEET_CMDLINE_DECLSPEC Splitter
|
||||
{
|
||||
std::string command_line_;
|
||||
std::vector<char*> arguments_;
|
||||
|
||||
public:
|
||||
Splitter( const char* command_line );
|
||||
const std::vector<char*>& arguments();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -9,10 +9,11 @@ Library {
|
|||
"error/error"
|
||||
};
|
||||
|
||||
Cc {
|
||||
Source {
|
||||
"AddOption.cpp",
|
||||
"Error.cpp",
|
||||
"Option.cpp",
|
||||
"Parser.cpp"
|
||||
"Parser.cpp",
|
||||
"Splitter.cpp"
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,11 @@
|
|||
//
|
||||
// cmdline.hpp
|
||||
// Copyright (c) 2008 - 2011 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2008 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef SWEET_CMDLINE_HPP_INCLUDED
|
||||
#define SWEET_CMDLINE_HPP_INCLUDED
|
||||
|
||||
#include <sweet/build.hpp>
|
||||
#include <vector>
|
||||
#include <sweet/assert/assert.hpp>
|
||||
#include <sweet/error/Error.hpp>
|
||||
|
||||
#ifndef BUILD_MODULE_CMDLINE
|
||||
#pragma comment( lib, "cmdline" BUILD_LIBRARY_SUFFIX )
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,10 +1,6 @@
|
|||
//
|
||||
// TestParser.cpp
|
||||
// Copyright (c) 2008 - 2011 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#include <sweet/unit/UnitTest.h>
|
||||
#include <sweet/cmdline/cmdline.hpp>
|
||||
#include <sweet/cmdline/Parser.hpp>
|
||||
|
||||
using namespace sweet::cmdline;
|
||||
|
||||
|
|
@ -14,8 +10,8 @@ SUITE( TestParser )
|
|||
{
|
||||
bool boolean = false;
|
||||
|
||||
int argc = 2;
|
||||
char* argv[] = { "", "-b" };
|
||||
int argc = 2;
|
||||
const char* argv[] = { "", "-b" };
|
||||
|
||||
Parser command_line_parser;
|
||||
command_line_parser.add_options()
|
||||
|
|
@ -30,8 +26,8 @@ SUITE( TestParser )
|
|||
{
|
||||
bool boolean = false;
|
||||
|
||||
int argc = 2;
|
||||
char* argv[] = { "", "--boolean" };
|
||||
int argc = 2;
|
||||
const char* argv[] = { "", "--boolean" };
|
||||
|
||||
Parser command_line_parser;
|
||||
command_line_parser.add_options()
|
||||
|
|
@ -46,8 +42,8 @@ SUITE( TestParser )
|
|||
{
|
||||
int integer = 0;
|
||||
|
||||
int argc = 2;
|
||||
char* argv[] = { "", "-i1" };
|
||||
int argc = 2;
|
||||
const char* argv[] = { "", "-i1" };
|
||||
|
||||
Parser command_line_parser;
|
||||
command_line_parser.add_options()
|
||||
|
|
@ -62,8 +58,8 @@ SUITE( TestParser )
|
|||
{
|
||||
int integer = 0;
|
||||
|
||||
int argc = 2;
|
||||
char* argv[] = { "", "--integer=1" };
|
||||
int argc = 2;
|
||||
const char* argv[] = { "", "--integer=1" };
|
||||
|
||||
Parser command_line_parser;
|
||||
command_line_parser.add_options()
|
||||
|
|
@ -78,8 +74,8 @@ SUITE( TestParser )
|
|||
{
|
||||
float real = 0.0f;
|
||||
|
||||
int argc = 2;
|
||||
char* argv[] = { "", "-r1.0" };
|
||||
int argc = 2;
|
||||
const char* argv[] = { "", "-r1.0" };
|
||||
|
||||
Parser command_line_parser;
|
||||
command_line_parser.add_options()
|
||||
|
|
@ -94,8 +90,8 @@ SUITE( TestParser )
|
|||
{
|
||||
float real = 0.0f;
|
||||
|
||||
int argc = 2;
|
||||
char* argv[] = { "", "--real=1.0" };
|
||||
int argc = 2;
|
||||
const char* argv[] = { "", "--real=1.0" };
|
||||
|
||||
Parser command_line_parser;
|
||||
command_line_parser.add_options()
|
||||
|
|
@ -110,8 +106,8 @@ SUITE( TestParser )
|
|||
{
|
||||
std::string string;
|
||||
|
||||
int argc = 2;
|
||||
char* argv[] = { "", "-sfoo" };
|
||||
int argc = 2;
|
||||
const char* argv[] = { "", "-sfoo" };
|
||||
|
||||
Parser command_line_parser;
|
||||
command_line_parser.add_options()
|
||||
|
|
@ -126,8 +122,8 @@ SUITE( TestParser )
|
|||
{
|
||||
std::string string;
|
||||
|
||||
int argc = 2;
|
||||
char* argv[] = { "", "--string=foo" };
|
||||
int argc = 2;
|
||||
const char* argv[] = { "", "--string=foo" };
|
||||
|
||||
Parser command_line_parser;
|
||||
command_line_parser.add_options()
|
||||
|
|
|
|||
188
sweet/cmdline/cmdline_test/TestSplitter.cpp
Normal file
188
sweet/cmdline/cmdline_test/TestSplitter.cpp
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
|
||||
#include <sweet/unit/UnitTest.h>
|
||||
#include <sweet/cmdline/Splitter.hpp>
|
||||
#include <sweet/assert/assert.hpp>
|
||||
#include <string.h>
|
||||
|
||||
using namespace sweet::cmdline;
|
||||
|
||||
SUITE( TestSplitter )
|
||||
{
|
||||
static void test(const char* command_line, const char **arguments)
|
||||
{
|
||||
SWEET_ASSERT( command_line );
|
||||
|
||||
Splitter splitter( command_line );
|
||||
int i = 0;
|
||||
while ( i < int(splitter.arguments().size()) && splitter.arguments()[i] && arguments[i] )
|
||||
{
|
||||
CHECK( strcmp(splitter.arguments()[i], arguments[i]) == 0 );
|
||||
++i;
|
||||
}
|
||||
CHECK( i == int(splitter.arguments().size()) - 1 );
|
||||
CHECK( !splitter.arguments()[i] );
|
||||
CHECK( !arguments[i] );
|
||||
}
|
||||
|
||||
TEST( SpacedDoubleQuotes )
|
||||
{
|
||||
const char* COMMAND_LINE =
|
||||
"-a \"foo bar baz\" blah"
|
||||
;
|
||||
const char* ARGUMENTS[] =
|
||||
{
|
||||
"-a",
|
||||
"foo bar baz",
|
||||
"blah",
|
||||
NULL
|
||||
};
|
||||
test( COMMAND_LINE, ARGUMENTS );
|
||||
}
|
||||
|
||||
TEST( NonSpacedDoubleQuotes )
|
||||
{
|
||||
const char* COMMAND_LINE =
|
||||
"-a\"foo bar baz\" blah"
|
||||
;
|
||||
const char* ARGUMENTS[] =
|
||||
{
|
||||
"-afoo bar baz",
|
||||
"blah",
|
||||
NULL
|
||||
};
|
||||
test( COMMAND_LINE, ARGUMENTS );
|
||||
}
|
||||
|
||||
TEST( SpacedSingleQuotes )
|
||||
{
|
||||
const char* COMMAND_LINE =
|
||||
"-a 'foo bar baz' blah"
|
||||
;
|
||||
const char* ARGUMENTS[] =
|
||||
{
|
||||
"-a",
|
||||
"foo bar baz",
|
||||
"blah",
|
||||
NULL
|
||||
};
|
||||
test( COMMAND_LINE, ARGUMENTS );
|
||||
}
|
||||
|
||||
TEST( NonSpacedSingleQuotes )
|
||||
{
|
||||
const char* COMMAND_LINE =
|
||||
"-a'foo bar baz' blah"
|
||||
;
|
||||
const char* ARGUMENTS[] =
|
||||
{
|
||||
"-afoo bar baz",
|
||||
"blah",
|
||||
NULL
|
||||
};
|
||||
test( COMMAND_LINE, ARGUMENTS );
|
||||
}
|
||||
|
||||
TEST( GxxCommandLineWithNonSpacedDoubleQuotesAndEscapedDoubleQuotes )
|
||||
{
|
||||
const char* COMMAND_LINE =
|
||||
"g++ -I\"/Users/charles/sweet/sweet_build_tool\" -I\"C:/boost/include/boost-1_43\" -DBUILD_PLATFORM_GCC -DBUILD_VARIANT_DEBUG "
|
||||
"-DBUILD_LIBRARY_SUFFIX=\"\\\"_gcc_debug.lib\\\"\" -DBUILD_MODULE_ASSERT -DBUILD_LIBRARY_TYPE_STATIC -c -fpermissive "
|
||||
"-Wno-deprecated -x c++ -static-libstdc++ -g -fexceptions -frtti "
|
||||
"-o/Users/charles/sweet/sweet_build_tool/obj/gcc_debug/assert/stdafx.o stdafx.cpp"
|
||||
;
|
||||
const char* ARGUMENTS[] =
|
||||
{
|
||||
"g++",
|
||||
"-I/Users/charles/sweet/sweet_build_tool",
|
||||
"-IC:/boost/include/boost-1_43",
|
||||
"-DBUILD_PLATFORM_GCC",
|
||||
"-DBUILD_VARIANT_DEBUG",
|
||||
"-DBUILD_LIBRARY_SUFFIX=\"_gcc_debug.lib\"",
|
||||
"-DBUILD_MODULE_ASSERT",
|
||||
"-DBUILD_LIBRARY_TYPE_STATIC",
|
||||
"-c",
|
||||
"-fpermissive",
|
||||
"-Wno-deprecated",
|
||||
"-x",
|
||||
"c++",
|
||||
"-static-libstdc++",
|
||||
"-g",
|
||||
"-fexceptions",
|
||||
"-frtti",
|
||||
"-o/Users/charles/sweet/sweet_build_tool/obj/gcc_debug/assert/stdafx.o",
|
||||
"stdafx.cpp",
|
||||
NULL
|
||||
};
|
||||
test( COMMAND_LINE, ARGUMENTS );
|
||||
}
|
||||
|
||||
TEST( GxxCommandLineWithSpacedDoubleQuotes )
|
||||
{
|
||||
const char *COMMAND_LINE =
|
||||
"g++ -lbuild_tool_gcc_debug -lcmdline_gcc_debug -llua_gcc_debug -lliblua_gcc_debug "
|
||||
"-lprocess_gcc_debug -lrtti_gcc_debug -lthread_gcc_debug -lpersist_gcc_debug "
|
||||
"-lpath_gcc_debug -lpointer_gcc_debug -lerror_gcc_debug -lassert_gcc_debug "
|
||||
"-llibboost_filesystem.a -llibboost_regex.a -llibboost_system.a -llibboost_thread.a "
|
||||
"stdafx.o Application.o main.o "
|
||||
"-o /Users/charles/sweet/sweet_build_tool/bin/build_gcc_debug "
|
||||
"-static-libstdc++ -debug "
|
||||
"-L \"/Users/charles/sweet/sweet_build_tool/lib\" "
|
||||
"-L \"/Users/charles/boost/boost_1_43_0/stage/lib\""
|
||||
;
|
||||
const char* ARGUMENTS[] =
|
||||
{
|
||||
"g++",
|
||||
"-lbuild_tool_gcc_debug",
|
||||
"-lcmdline_gcc_debug",
|
||||
"-llua_gcc_debug",
|
||||
"-lliblua_gcc_debug",
|
||||
"-lprocess_gcc_debug",
|
||||
"-lrtti_gcc_debug",
|
||||
"-lthread_gcc_debug",
|
||||
"-lpersist_gcc_debug",
|
||||
"-lpath_gcc_debug",
|
||||
"-lpointer_gcc_debug",
|
||||
"-lerror_gcc_debug",
|
||||
"-lassert_gcc_debug",
|
||||
"-llibboost_filesystem.a",
|
||||
"-llibboost_regex.a",
|
||||
"-llibboost_system.a",
|
||||
"-llibboost_thread.a",
|
||||
"stdafx.o",
|
||||
"Application.o",
|
||||
"main.o",
|
||||
"-o",
|
||||
"/Users/charles/sweet/sweet_build_tool/bin/build_gcc_debug",
|
||||
"-static-libstdc++",
|
||||
"-debug",
|
||||
"-L",
|
||||
"/Users/charles/sweet/sweet_build_tool/lib",
|
||||
"-L",
|
||||
"/Users/charles/boost/boost_1_43_0/stage/lib",
|
||||
NULL
|
||||
};
|
||||
test( COMMAND_LINE, ARGUMENTS );
|
||||
}
|
||||
|
||||
TEST( UnterminatedSingleQuotedString )
|
||||
{
|
||||
const char* COMMAND_LINE = "'This is an unterminated string";
|
||||
const char* ARGUMENTS[] =
|
||||
{
|
||||
"This is an unterminated string",
|
||||
NULL
|
||||
};
|
||||
test( COMMAND_LINE, ARGUMENTS );
|
||||
}
|
||||
|
||||
TEST( UnterminatedDoubleQuotedString )
|
||||
{
|
||||
const char* COMMAND_LINE = "\"This is an unterminated string";
|
||||
const char* ARGUMENTS[] =
|
||||
{
|
||||
"This is an unterminated string",
|
||||
NULL
|
||||
};
|
||||
test( COMMAND_LINE, ARGUMENTS );
|
||||
}
|
||||
}
|
||||
|
|
@ -3,13 +3,15 @@ Executable {
|
|||
id = "cmdline_test";
|
||||
|
||||
libraries = {
|
||||
"assert/assert",
|
||||
"cmdline/cmdline",
|
||||
"error/error",
|
||||
"assert/assert",
|
||||
"unit/libUnitTest"
|
||||
};
|
||||
|
||||
Cc {
|
||||
Source {
|
||||
"main.cpp",
|
||||
"TestParser.cpp"
|
||||
"TestParser.cpp",
|
||||
"TestSplitter.cpp"
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// declspec.hpp
|
||||
// Copyright (c) 2011 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2011 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef SWEET_CMDLINE_DECLSPEC_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -1,13 +1,17 @@
|
|||
//
|
||||
// Error.cpp
|
||||
// Copyright (c) 2001 - 2011 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2001 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#include "stdafx.hpp"
|
||||
#include <sweet/error/Error.hpp>
|
||||
#include <sweet/assert/assert.hpp>
|
||||
#include <memory.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(BUILD_OS_WINDOWS)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
using namespace sweet::error;
|
||||
|
||||
|
|
@ -46,7 +50,7 @@ Error::Error( int error, const char* format, ... )
|
|||
/**
|
||||
// Destructor.
|
||||
*/
|
||||
Error::~Error()
|
||||
Error::~Error() throw ()
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -67,7 +71,7 @@ int Error::error() const
|
|||
// @return
|
||||
// The text.
|
||||
*/
|
||||
const char* Error::what() const
|
||||
const char* Error::what() const throw ()
|
||||
{
|
||||
return text_;
|
||||
}
|
||||
|
|
@ -82,7 +86,7 @@ const char* Error::what() const
|
|||
// A variable length argument list that matches that arguments in @e
|
||||
// format.
|
||||
*/
|
||||
void Error::append( const char* format, va_list& args )
|
||||
void Error::append( const char* format, va_list args )
|
||||
{
|
||||
if ( format )
|
||||
{
|
||||
|
|
@ -93,7 +97,7 @@ void Error::append( const char* format, va_list& args )
|
|||
++pos;
|
||||
}
|
||||
|
||||
_vsnprintf( pos, end - pos, format, args );
|
||||
vsnprintf( pos, end - pos, format, args );
|
||||
text_[sizeof(text_) - 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
|
@ -115,7 +119,7 @@ void Error::append( const char* text )
|
|||
++pos;
|
||||
}
|
||||
|
||||
_snprintf( pos, end - pos, text );
|
||||
strncpy( pos, text, end - pos );
|
||||
text_[sizeof(text_) - 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
|
@ -135,15 +139,18 @@ void Error::append( const char* text )
|
|||
// @return
|
||||
// The buffer.
|
||||
*/
|
||||
const char* Error::format( int oserror, char* buffer, size_t length )
|
||||
const char* Error::format( int oserror, char* buffer, unsigned int length )
|
||||
{
|
||||
SWEET_ASSERT( buffer );
|
||||
SWEET_ASSERT( length > 0 );
|
||||
#if defined(BUILD_OS_WINDOWS)
|
||||
int actual_length = ::FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM, 0, oserror, 0, buffer, static_cast<int>(length), 0 );
|
||||
while ( actual_length > 0 && (buffer[actual_length] == '\n' || buffer[actual_length] == '\r' || buffer[actual_length] == '.' || buffer[actual_length] == 0) )
|
||||
{
|
||||
buffer[actual_length] = 0;
|
||||
--actual_length;
|
||||
}
|
||||
#elif defined(BUILD_OS_MACOSX)
|
||||
strerror_r( oserror, buffer, length );
|
||||
#endif
|
||||
return buffer;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// Error.hpp
|
||||
// Copyright (c) 2001 - 2011 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2001 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef SWEET_ERROR_ERROR_HPP_INCLUDED
|
||||
|
|
@ -9,8 +9,7 @@
|
|||
#include "declspec.hpp"
|
||||
#include "macros.hpp"
|
||||
#include <exception>
|
||||
|
||||
typedef char* va_list;
|
||||
#include <stdarg.h>
|
||||
|
||||
namespace sweet
|
||||
{
|
||||
|
|
@ -29,13 +28,13 @@ class SWEET_ERROR_DECLSPEC Error : virtual public std::exception
|
|||
public:
|
||||
explicit Error( int error );
|
||||
Error( int error, const char* format, ... );
|
||||
virtual ~Error();
|
||||
virtual ~Error() throw ();
|
||||
int error() const;
|
||||
const char* what() const;
|
||||
static const char* format( int oserror, char* buffer, size_t length );
|
||||
const char* what() const throw ();
|
||||
static const char* format( int oserror, char* buffer, unsigned int length );
|
||||
|
||||
protected:
|
||||
void append( const char* format, va_list& args );
|
||||
void append( const char* format, va_list args );
|
||||
void append( const char* text );
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// ErrorPolicy.cpp
|
||||
// Copyright (c) 2001 - 2011 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2001 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#include "stdafx.hpp"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// ErrorPolicy.hpp
|
||||
// Copyright (c) 2001 - 2011 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2001 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef SWEET_ERROR_ERRORPOLICY_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// ErrorTemplate.hpp
|
||||
// Copyright (c) 2008 - 2011 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2008 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef SWEET_ERROR_ERRORTEMPLATE_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// ErrorTemplate.ipp
|
||||
// Copyright (c) 2008 - 2011 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2008 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef SWEET_ERROR_ERRORTEMPLATE_IPP_INCLUDED
|
||||
|
|
@ -30,7 +30,7 @@ ErrorTemplate<ERRNO, Base>::ErrorTemplate( const char* format, ... )
|
|||
{
|
||||
va_list args;
|
||||
va_start( args, format );
|
||||
append( format, args );
|
||||
Error::append( format, args );
|
||||
va_end( args );
|
||||
}
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ template <int ERRNO, class Base>
|
|||
ErrorTemplate<ERRNO, Base>::ErrorTemplate( const char* format, va_list args )
|
||||
: Base( ERRNO )
|
||||
{
|
||||
append( format, args );
|
||||
Error::append( format, args );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// boost-integration.cpp
|
||||
// Copyright (c) 2008 - 2011 Charles Baker. All rights reserved.
|
||||
// boost_integration.cpp
|
||||
// Copyright (c) 2008 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#include "stdafx.hpp"
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
//
|
||||
// declspec.hpp
|
||||
// Copyright (c) 2001 - 2011 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2001 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef SWEET_ERROR_DECLSPEC_HPP_INCLUDED
|
||||
#define SWEET_ERROR_DECLSPEC_HPP_INCLUDED
|
||||
|
||||
#if defined(BUILD_MODULE_ERROR) && defined(BUILD_LIBRARY_TYPE_DYNAMIC)
|
||||
#if defined(BUILD_OS_WINDOWS) && defined(BUILD_MODULE_ERROR) && defined(BUILD_LIBRARY_TYPE_DYNAMIC)
|
||||
#define SWEET_ERROR_DECLSPEC __declspec(dllexport)
|
||||
#elif defined(BUILD_LIBRARY_TYPE_DYNAMIC)
|
||||
#elif defined(BUILD_OS_WINDOWS) && defined(BUILD_LIBRARY_TYPE_DYNAMIC)
|
||||
#define SWEET_ERROR_DECLSPEC __declspec(dllimport)
|
||||
#else
|
||||
#define SWEET_ERROR_DECLSPEC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// dinkumware_integration.cpp
|
||||
// Copyright (c) 2008 - 2011 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2008 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#include "stdafx.hpp"
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ Library {
|
|||
"assert/assert"
|
||||
};
|
||||
|
||||
Cc {
|
||||
Source {
|
||||
pch = "stdafx.hpp";
|
||||
"boost_integration.cpp",
|
||||
"dinkumware_integration.cpp",
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ Executable {
|
|||
"unit/libUnitTest"
|
||||
};
|
||||
|
||||
Cc {
|
||||
Source {
|
||||
pch = "stdafx.hpp";
|
||||
"main.cpp"
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// error_functions.cpp
|
||||
// Copyright (c) 2001 - 2011 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2001 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#include "stdafx.hpp"
|
||||
|
|
@ -68,9 +68,9 @@ void error( const Error& error )
|
|||
}
|
||||
else
|
||||
{
|
||||
::fputs( error.what(), stderr );
|
||||
::fputs( ".\n", stderr );
|
||||
::exit( EXIT_FAILURE );
|
||||
fputs( error.what(), stderr );
|
||||
fputs( ".\n", stderr );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -93,9 +93,9 @@ void error( const std::exception& exception )
|
|||
}
|
||||
else
|
||||
{
|
||||
::fputs( exception.what(), stderr );
|
||||
::fputs( ".\n", stderr );
|
||||
::exit( EXIT_FAILURE );
|
||||
fputs( exception.what(), stderr );
|
||||
fputs( ".\n", stderr );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,4 +6,6 @@
|
|||
#define _SCL_SECURE_NO_DEPRECATE
|
||||
#define NOMINMAX
|
||||
|
||||
#include <windows.h>
|
||||
#if defined(BUILD_OS_WINDOWS)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -6,7 +6,11 @@
|
|||
#ifndef SWEET_LEXER_LEXER_HPP_INCLUDED
|
||||
#define SWEET_LEXER_LEXER_HPP_INCLUDED
|
||||
|
||||
#if defined(BUILD_PLATFORM_MSVC)
|
||||
#include <functional>
|
||||
#else
|
||||
#include <tr1/functional>
|
||||
#endif
|
||||
|
||||
namespace sweet
|
||||
{
|
||||
|
|
@ -22,7 +26,7 @@ class LexerErrorPolicy;
|
|||
/**
|
||||
// A lexical analyzer.
|
||||
*/
|
||||
template <class Iterator, class Char = std::iterator_traits<Iterator>::value_type, class Traits = std::char_traits<Char>, class Allocator = std::allocator<Char>>
|
||||
template <class Iterator, class Char = typename std::iterator_traits<Iterator>::value_type, class Traits = typename std::char_traits<Char>, class Allocator = typename std::allocator<Char> >
|
||||
class Lexer
|
||||
{
|
||||
typedef std::tr1::function<void (Iterator* begin, Iterator end, std::basic_string<Char, Traits, Allocator>* lexeme, const void** symbol)> LexerActionFunction;
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ Lexer<Iterator, Char, Traits, Allocator>::Lexer( const LexerStateMachine* state_
|
|||
if ( state_machine_ )
|
||||
{
|
||||
action_handlers_.reserve( state_machine_->actions().size() );
|
||||
for ( std::vector<ptr<LexerAction>>::const_iterator i = state_machine_->actions().begin(); i != state_machine_->actions().end(); ++i )
|
||||
for ( std::vector<ptr<LexerAction> >::const_iterator i = state_machine_->actions().begin(); i != state_machine_->actions().end(); ++i )
|
||||
{
|
||||
LexerAction* action = i->get();
|
||||
SWEET_ASSERT( action );
|
||||
|
|
@ -90,7 +90,7 @@ void Lexer<Iterator, Char, Traits, Allocator>::set_action_handler( const char* i
|
|||
{
|
||||
SWEET_ASSERT( identifier );
|
||||
|
||||
std::vector<LexerActionHandler>::iterator action_handler = action_handlers_.begin();
|
||||
typename std::vector<LexerActionHandler>::iterator action_handler = action_handlers_.begin();
|
||||
while ( action_handler != action_handlers_.end() && action_handler->action_->get_identifier() != identifier )
|
||||
{
|
||||
++action_handler;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include "LexerErrorPolicy.hpp"
|
||||
#include "RegexNode.hpp"
|
||||
#include "RegexParser.hpp"
|
||||
#include <limits.h>
|
||||
|
||||
using std::pair;
|
||||
using std::vector;
|
||||
|
|
@ -63,7 +64,7 @@ LexerGenerator::LexerGenerator( const std::vector<LexerToken>& tokens, const std
|
|||
// @return
|
||||
// The actions.
|
||||
*/
|
||||
std::vector<ptr<LexerAction>>& LexerGenerator::actions()
|
||||
std::vector<ptr<LexerAction> >& LexerGenerator::actions()
|
||||
{
|
||||
return actions_;
|
||||
}
|
||||
|
|
@ -74,7 +75,7 @@ std::vector<ptr<LexerAction>>& LexerGenerator::actions()
|
|||
// @return
|
||||
// The generated states.
|
||||
*/
|
||||
std::set<ptr<LexerState>, ptr_less<LexerState>>& LexerGenerator::states()
|
||||
std::set<ptr<LexerState>, ptr_less<LexerState> >& LexerGenerator::states()
|
||||
{
|
||||
return states_;
|
||||
}
|
||||
|
|
@ -85,7 +86,7 @@ std::set<ptr<LexerState>, ptr_less<LexerState>>& LexerGenerator::states()
|
|||
// @return
|
||||
// The generated whitespace states.
|
||||
*/
|
||||
std::set<ptr<LexerState>, ptr_less<LexerState>>& LexerGenerator::whitespace_states()
|
||||
std::set<ptr<LexerState>, ptr_less<LexerState> >& LexerGenerator::whitespace_states()
|
||||
{
|
||||
return whitespace_states_;
|
||||
}
|
||||
|
|
@ -135,7 +136,7 @@ const lexer::LexerAction* LexerGenerator::add_lexer_action( const std::string& i
|
|||
|
||||
if ( !identifier.empty() )
|
||||
{
|
||||
std::vector<ptr<lexer::LexerAction>>::const_iterator i = actions_.begin();
|
||||
std::vector<ptr<lexer::LexerAction> >::const_iterator i = actions_.begin();
|
||||
while ( i != actions_.end() && (*i)->get_identifier() != identifier )
|
||||
{
|
||||
++i;
|
||||
|
|
@ -247,7 +248,7 @@ ptr<LexerState> LexerGenerator::goto_( const LexerState* state, int begin, int e
|
|||
// A variable to receive the starting state for the lexical analyzer
|
||||
// (assumed not null).
|
||||
*/
|
||||
void LexerGenerator::generate_states( const RegexParser& regex_parser, std::set<ptr<LexerState>, ptr_less<LexerState>>* states, const LexerState** start_state )
|
||||
void LexerGenerator::generate_states( const RegexParser& regex_parser, std::set<ptr<LexerState>, ptr_less<LexerState> >* states, const LexerState** start_state )
|
||||
{
|
||||
SWEET_ASSERT( states );
|
||||
SWEET_ASSERT( states->empty() );
|
||||
|
|
@ -266,7 +267,7 @@ void LexerGenerator::generate_states( const RegexParser& regex_parser, std::set<
|
|||
while ( added > 0 )
|
||||
{
|
||||
added = 0;
|
||||
for ( std::set<ptr<LexerState>, ptr_less<LexerState>>::const_iterator i = states->begin(); i != states->end(); ++i )
|
||||
for ( std::set<ptr<LexerState>, ptr_less<LexerState> >::const_iterator i = states->begin(); i != states->end(); ++i )
|
||||
{
|
||||
LexerState* state = i->get();
|
||||
SWEET_ASSERT( state );
|
||||
|
|
@ -299,7 +300,7 @@ void LexerGenerator::generate_states( const RegexParser& regex_parser, std::set<
|
|||
// Create a goto state and a transition from the current
|
||||
// state for each distinct range.
|
||||
//
|
||||
vector<pair<int, bool>>::const_iterator j = ranges_.begin();
|
||||
vector<pair<int, bool> >::const_iterator j = ranges_.begin();
|
||||
while ( j != ranges_.end() )
|
||||
{
|
||||
int begin = (j + 0)->first;
|
||||
|
|
@ -340,7 +341,7 @@ void LexerGenerator::generate_indices_for_states()
|
|||
{
|
||||
int index = 0;
|
||||
|
||||
for ( std::set<ptr<LexerState>, ptr_less<LexerState>>::iterator i = states_.begin(); i != states_.end(); ++i )
|
||||
for ( std::set<ptr<LexerState>, ptr_less<LexerState> >::iterator i = states_.begin(); i != states_.end(); ++i )
|
||||
{
|
||||
LexerState* state = i->get();
|
||||
SWEET_ASSERT( state );
|
||||
|
|
@ -348,7 +349,7 @@ void LexerGenerator::generate_indices_for_states()
|
|||
++index;
|
||||
}
|
||||
|
||||
for ( std::set<ptr<LexerState>, ptr_less<LexerState>>::iterator i = whitespace_states_.begin(); i != whitespace_states_.end(); ++i )
|
||||
for ( std::set<ptr<LexerState>, ptr_less<LexerState> >::iterator i = whitespace_states_.begin(); i != whitespace_states_.end(); ++i )
|
||||
{
|
||||
LexerState* state = i->get();
|
||||
SWEET_ASSERT( state );
|
||||
|
|
@ -443,7 +444,7 @@ void LexerGenerator::insert( int begin, int end )
|
|||
{
|
||||
bool in = false;
|
||||
|
||||
vector<pair<int, bool>>::iterator i = ranges_.begin();
|
||||
vector<pair<int, bool> >::iterator i = ranges_.begin();
|
||||
while ( i != ranges_.end() && i->first < begin )
|
||||
{
|
||||
in = i->second;
|
||||
|
|
|
|||
|
|
@ -38,20 +38,20 @@ class RegexParser;
|
|||
class LexerGenerator
|
||||
{
|
||||
LexerErrorPolicy* event_sink_; ///< The event sink to report errors and debug information to or null to ignore errors and debug information.
|
||||
std::vector<ptr<LexerAction>> actions_; ///< The lexical analyzer actions.
|
||||
std::set<ptr<LexerState>, ptr_less<LexerState>> states_; ///< The states generated for the lexical analyzer.
|
||||
std::set<ptr<LexerState>, ptr_less<LexerState>> whitespace_states_; ///< The states generated for the whitespace lexical analyzer.
|
||||
std::vector<ptr<LexerAction> > actions_; ///< The lexical analyzer actions.
|
||||
std::set<ptr<LexerState>, ptr_less<LexerState> > states_; ///< The states generated for the lexical analyzer.
|
||||
std::set<ptr<LexerState>, ptr_less<LexerState> > whitespace_states_; ///< The states generated for the whitespace lexical analyzer.
|
||||
const LexerState* start_state_; ///< The starting state for the lexical analyzer.
|
||||
const LexerState* whitespace_start_state_; ///< The starting state for the whitespace lexical analyzer.
|
||||
std::vector<std::pair<int, bool>> ranges_; ///< Ranges generated for the current transition while generating.
|
||||
std::vector<std::pair<int, bool> > ranges_; ///< Ranges generated for the current transition while generating.
|
||||
|
||||
public:
|
||||
LexerGenerator( const LexerToken& token, LexerErrorPolicy* event_sink );
|
||||
LexerGenerator( const std::vector<LexerToken>& tokens, const std::vector<LexerToken>& whitespace_tokens, LexerErrorPolicy* event_sink );
|
||||
|
||||
std::vector<ptr<LexerAction>>& actions();
|
||||
std::set<ptr<LexerState>, ptr_less<LexerState>>& states();
|
||||
std::set<ptr<LexerState>, ptr_less<LexerState>>& whitespace_states();
|
||||
std::vector<ptr<LexerAction> >& actions();
|
||||
std::set<ptr<LexerState>, ptr_less<LexerState> >& states();
|
||||
std::set<ptr<LexerState>, ptr_less<LexerState> >& whitespace_states();
|
||||
const LexerState* start_state() const;
|
||||
const LexerState* whitespace_start_state() const;
|
||||
const lexer::LexerAction* add_lexer_action( const std::string& identifier );
|
||||
|
|
@ -61,7 +61,7 @@ class LexerGenerator
|
|||
|
||||
private:
|
||||
ptr<LexerState> goto_( const LexerState* state, int begin, int end );
|
||||
void generate_states( const RegexParser& regular_expression_parser, std::set<ptr<LexerState>, ptr_less<LexerState>>* states, const LexerState** start_state );
|
||||
void generate_states( const RegexParser& regular_expression_parser, std::set<ptr<LexerState>, ptr_less<LexerState> >* states, const LexerState** start_state );
|
||||
void generate_indices_for_states();
|
||||
void generate_symbol_for_state( LexerState* state ) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -6,10 +6,16 @@
|
|||
#include "stdafx.hpp"
|
||||
#include "LexerItem.hpp"
|
||||
#include "RegexNode.hpp"
|
||||
#include <string>
|
||||
#include <stdio.h>
|
||||
|
||||
using namespace sweet;
|
||||
using namespace sweet::lexer;
|
||||
|
||||
#if defined(BUILD_PLATFORM_MSVC)
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
/**
|
||||
// Constructor.
|
||||
*/
|
||||
|
|
@ -159,7 +165,7 @@ void LexerItem::describe( std::string* description ) const
|
|||
const RegexNode* node = *i;
|
||||
SWEET_ASSERT( node );
|
||||
char buffer [32];
|
||||
_snprintf( buffer, sizeof(buffer), "%d ", node->get_index() );
|
||||
snprintf( buffer, sizeof(buffer), "%d ", node->get_index() );
|
||||
buffer [sizeof(buffer) - 1] = '\0';
|
||||
description->append( buffer );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include "declspec.hpp"
|
||||
#include "RegexNodeLess.hpp"
|
||||
#include <sweet/pointer/ptr.hpp>
|
||||
#include <string>
|
||||
#include <set>
|
||||
|
||||
namespace sweet
|
||||
|
|
|
|||
|
|
@ -7,10 +7,15 @@
|
|||
#include "LexerState.hpp"
|
||||
#include "LexerItem.hpp"
|
||||
#include "LexerTransition.hpp"
|
||||
#include <stdio.h>
|
||||
|
||||
using namespace sweet;
|
||||
using namespace sweet::lexer;
|
||||
|
||||
#if defined(BUILD_PLATFORM_MSVC)
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
/**
|
||||
// Constructor.
|
||||
*/
|
||||
|
|
@ -201,7 +206,7 @@ void LexerState::describe( std::string* description ) const
|
|||
SWEET_ASSERT( description );
|
||||
|
||||
char buffer [512];
|
||||
_snprintf( buffer, sizeof(buffer), "%d (0x%08x):\n", index_, symbol_ );
|
||||
snprintf( buffer, sizeof(buffer), "%d (%p):\n", index_, symbol_ );
|
||||
buffer [sizeof(buffer) - 1] = '\0';
|
||||
description->append( buffer );
|
||||
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ const std::string& LexerStateMachine::identifier() const
|
|||
// @return
|
||||
// The actions.
|
||||
*/
|
||||
const std::vector<ptr<LexerAction>>& LexerStateMachine::actions() const
|
||||
const std::vector<ptr<LexerAction> >& LexerStateMachine::actions() const
|
||||
{
|
||||
return actions_;
|
||||
}
|
||||
|
|
@ -112,7 +112,7 @@ const std::vector<ptr<LexerAction>>& LexerStateMachine::actions() const
|
|||
// @return
|
||||
// The states.
|
||||
*/
|
||||
const std::vector<ptr<LexerState>>& LexerStateMachine::states() const
|
||||
const std::vector<ptr<LexerState> >& LexerStateMachine::states() const
|
||||
{
|
||||
return states_;
|
||||
}
|
||||
|
|
@ -123,7 +123,7 @@ const std::vector<ptr<LexerState>>& LexerStateMachine::states() const
|
|||
// @return
|
||||
// The whitespace states.
|
||||
*/
|
||||
const std::vector<ptr<LexerState>>& LexerStateMachine::whitespace_states() const
|
||||
const std::vector<ptr<LexerState> >& LexerStateMachine::whitespace_states() const
|
||||
{
|
||||
return whitespace_states_;
|
||||
}
|
||||
|
|
@ -159,7 +159,7 @@ const LexerState* LexerStateMachine::whitespace_start_state() const
|
|||
void LexerStateMachine::describe( std::string* description ) const
|
||||
{
|
||||
SWEET_ASSERT( description );
|
||||
std::vector<ptr<LexerState>>::const_iterator i = states_.begin();
|
||||
std::vector<ptr<LexerState> >::const_iterator i = states_.begin();
|
||||
while ( i != states_.end() )
|
||||
{
|
||||
const LexerState* state = i->get();
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@ class LexerErrorPolicy;
|
|||
class SWEET_LEXER_DECLSPEC LexerStateMachine
|
||||
{
|
||||
std::string identifier_; ///< The identifier of this LexerStateMachine.
|
||||
std::vector<ptr<lexer::LexerAction>> actions_; ///< The lexer actions for this ParserStateMachine.
|
||||
std::vector<ptr<LexerState>> states_; ///< The states that make up the state machine for this LexerStateMachine.
|
||||
std::vector<ptr<LexerState>> whitespace_states_; ///< The states that make up the state machine for whitespace in this LexerStateMachine.
|
||||
std::vector<ptr<lexer::LexerAction> > actions_; ///< The lexer actions for this ParserStateMachine.
|
||||
std::vector<ptr<LexerState> > states_; ///< The states that make up the state machine for this LexerStateMachine.
|
||||
std::vector<ptr<LexerState> > whitespace_states_; ///< The states that make up the state machine for whitespace in this LexerStateMachine.
|
||||
const LexerState* start_state_; ///< The starting state for the state machine.
|
||||
const LexerState* whitespace_start_state_; ///< The starting state for the whitespace state machine.
|
||||
|
||||
|
|
@ -40,9 +40,9 @@ class SWEET_LEXER_DECLSPEC LexerStateMachine
|
|||
LexerStateMachine( const std::string& identifier, const std::vector<LexerToken>& tokens, const std::vector<LexerToken>& whitespace_tokens = std::vector<LexerToken>(), LexerErrorPolicy* event_sink = NULL );
|
||||
|
||||
const std::string& identifier() const;
|
||||
const std::vector<ptr<LexerAction>>& actions() const;
|
||||
const std::vector<ptr<LexerState>>& states() const;
|
||||
const std::vector<ptr<LexerState>>& whitespace_states() const;
|
||||
const std::vector<ptr<LexerAction> >& actions() const;
|
||||
const std::vector<ptr<LexerState> >& states() const;
|
||||
const std::vector<ptr<LexerState> >& whitespace_states() const;
|
||||
const LexerState* start_state() const;
|
||||
const LexerState* whitespace_start_state() const;
|
||||
void describe( std::string* description ) const;
|
||||
|
|
|
|||
|
|
@ -8,9 +8,14 @@
|
|||
#include "LexerAction.hpp"
|
||||
#include "LexerState.hpp"
|
||||
#include <sweet/assert/assert.hpp>
|
||||
#include <stdio.h>
|
||||
|
||||
using namespace sweet::lexer;
|
||||
|
||||
#if defined(BUILD_PLATFORM_MSVC)
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
/**
|
||||
// Constructor.
|
||||
//
|
||||
|
|
@ -109,7 +114,7 @@ void LexerTransition::describe( std::string* description ) const
|
|||
SWEET_ASSERT( state_ );
|
||||
|
||||
char buffer [512];
|
||||
_snprintf( buffer, sizeof(buffer), "to %d on ['%c' %d, '%c' %d) %s",
|
||||
snprintf( buffer, sizeof(buffer), "to %d on ['%c' %d, '%c' %d) %s",
|
||||
state_->get_index(),
|
||||
begin_ > 32 && begin_ < 128 ? begin_ : '.',
|
||||
begin_,
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include "RegexNode.hpp"
|
||||
#include "LexerAction.hpp"
|
||||
#include <algorithm>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
|
||||
using std::find;
|
||||
|
|
@ -323,7 +324,7 @@ RegexNode* RegexNode::get_node( int n ) const
|
|||
// @return
|
||||
// The child nodes.
|
||||
*/
|
||||
const std::vector<ptr<RegexNode>>& RegexNode::get_nodes() const
|
||||
const std::vector<ptr<RegexNode> >& RegexNode::get_nodes() const
|
||||
{
|
||||
return nodes_;
|
||||
}
|
||||
|
|
@ -393,7 +394,7 @@ const std::set<RegexNode*, RegexNodeLess>& RegexNode::get_next_positions() const
|
|||
*/
|
||||
void RegexNode::calculate_nullable()
|
||||
{
|
||||
for ( std::vector<ptr<RegexNode>>::const_iterator i = nodes_.begin(); i != nodes_.end(); ++i )
|
||||
for ( std::vector<ptr<RegexNode> >::const_iterator i = nodes_.begin(); i != nodes_.end(); ++i )
|
||||
{
|
||||
RegexNode* node = i->get();
|
||||
SWEET_ASSERT( node );
|
||||
|
|
@ -446,7 +447,7 @@ void RegexNode::calculate_nullable()
|
|||
*/
|
||||
void RegexNode::calculate_first_positions()
|
||||
{
|
||||
for ( std::vector<ptr<RegexNode>>::const_iterator i = nodes_.begin(); i != nodes_.end(); ++i )
|
||||
for ( std::vector<ptr<RegexNode> >::const_iterator i = nodes_.begin(); i != nodes_.end(); ++i )
|
||||
{
|
||||
RegexNode* node = i->get();
|
||||
SWEET_ASSERT( node );
|
||||
|
|
@ -498,7 +499,7 @@ void RegexNode::calculate_first_positions()
|
|||
*/
|
||||
void RegexNode::calculate_last_positions()
|
||||
{
|
||||
for ( std::vector<ptr<RegexNode>>::const_iterator i = nodes_.begin(); i != nodes_.end(); ++i )
|
||||
for ( std::vector<ptr<RegexNode> >::const_iterator i = nodes_.begin(); i != nodes_.end(); ++i )
|
||||
{
|
||||
RegexNode* node = i->get();
|
||||
SWEET_ASSERT( node );
|
||||
|
|
@ -550,7 +551,7 @@ void RegexNode::calculate_last_positions()
|
|||
*/
|
||||
void RegexNode::calculate_follow_positions()
|
||||
{
|
||||
for ( std::vector<ptr<RegexNode>>::const_iterator i = nodes_.begin(); i != nodes_.end(); ++i )
|
||||
for ( std::vector<ptr<RegexNode> >::const_iterator i = nodes_.begin(); i != nodes_.end(); ++i )
|
||||
{
|
||||
RegexNode* node = i->get();
|
||||
SWEET_ASSERT( node );
|
||||
|
|
@ -662,7 +663,7 @@ void RegexNode::print( const std::set<RegexNode*>& dot_nodes ) const
|
|||
printf( "%s", action_ != NULL ? action_->get_identifier().c_str() : "null" );
|
||||
}
|
||||
|
||||
for ( std::vector<ptr<RegexNode>>::const_iterator i = nodes_.begin(); i != nodes_.end(); ++i )
|
||||
for ( std::vector<ptr<RegexNode> >::const_iterator i = nodes_.begin(); i != nodes_.end(); ++i )
|
||||
{
|
||||
const ptr<RegexNode>& node = *i;
|
||||
node->print( dot_nodes );
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ class RegexNode : public pointer::enable_ptr_from_this<RegexNode>
|
|||
int end_character_; ///< One past the last character in the interval of characters represented by the node.
|
||||
const LexerToken* token_; ///< The token recognized at the node or null if the node doesn't recognize a token.
|
||||
const LexerAction* action_; ///< The action taken at the node or null if no action is taken at the node.
|
||||
std::vector<ptr<RegexNode>> nodes_; ///< The child nodes.
|
||||
std::vector<ptr<RegexNode> > nodes_; ///< The child nodes.
|
||||
bool nullable_; ///< True if the node is nullable otherwise false.
|
||||
std::set<RegexNode*, RegexNodeLess> first_positions_; ///< The first positions at the node.
|
||||
std::set<RegexNode*, RegexNodeLess> last_positions_; ///< The last positions at the node.
|
||||
|
|
@ -96,7 +96,7 @@ class RegexNode : public pointer::enable_ptr_from_this<RegexNode>
|
|||
|
||||
void add_node( const ptr<RegexNode>& node );
|
||||
RegexNode* get_node( int index ) const;
|
||||
const std::vector<ptr<RegexNode>>& get_nodes() const;
|
||||
const std::vector<ptr<RegexNode> >& get_nodes() const;
|
||||
|
||||
bool is_nullable() const;
|
||||
const std::set<RegexNode*, RegexNodeLess>& get_first_positions() const;
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ namespace lexer
|
|||
// ParserGrammar for regular expressions.
|
||||
*/
|
||||
template <class Iterator>
|
||||
class RegexGrammar : public boost::spirit::grammar<RegexGrammar<Iterator>>
|
||||
class RegexGrammar : public boost::spirit::grammar<RegexGrammar<Iterator> >
|
||||
{
|
||||
public:
|
||||
typedef Iterator iterator;
|
||||
|
|
@ -1037,9 +1037,9 @@ void RegexParser::print_positions( const std::set<RegexNode*, RegexNodeLess>& po
|
|||
// @param level
|
||||
// The recursion level to use when identing lines.
|
||||
*/
|
||||
void RegexParser::print_nodes( const vector<ptr<RegexNode>>& nodes, int level ) const
|
||||
void RegexParser::print_nodes( const vector<ptr<RegexNode> >& nodes, int level ) const
|
||||
{
|
||||
for ( vector<ptr<RegexNode>>::const_iterator i = nodes.begin(); i != nodes.end(); ++i )
|
||||
for ( vector<ptr<RegexNode> >::const_iterator i = nodes.begin(); i != nodes.end(); ++i )
|
||||
{
|
||||
static const char* LEXER_NODE_TYPES [LEXER_NODE_COUNT] =
|
||||
{
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ class RegexParser
|
|||
LexerGenerator* lexer_generator_; ///< The LexerGenerator to retrieve actions from and report errors and debug information to.
|
||||
std::set<RegexCharacter> bracket_expression_characters_; ///< The characters in the current bracket expression.
|
||||
int index_; ///< The current node index.
|
||||
std::vector<ptr<RegexNode>> nodes_; ///< The current nodes.
|
||||
std::vector<ptr<RegexNode> > nodes_; ///< The current nodes.
|
||||
int errors_; ///< The number of errors that have occured.
|
||||
|
||||
public:
|
||||
|
|
@ -96,7 +96,7 @@ class RegexParser
|
|||
ptr<RegexNode> regex_node( const LexerAction* action );
|
||||
|
||||
void print_positions( const std::set<RegexNode*, RegexNodeLess>& positions ) const;
|
||||
void print_nodes( const std::vector<ptr<RegexNode>>& nodes, int level ) const;
|
||||
void print_nodes( const std::vector<ptr<RegexNode> >& nodes, int level ) const;
|
||||
|
||||
void calculate_symbols_for_characters_start_and_end();
|
||||
void calculate_combined_parse_tree( const std::vector<LexerToken>& tokens );
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ Library {
|
|||
"pointer/pointer"
|
||||
};
|
||||
|
||||
Cc {
|
||||
Source {
|
||||
pch = "stdafx.hpp";
|
||||
"Error.cpp",
|
||||
"LexerAction.cpp",
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <sweet/lexer/LexerStateMachine.hpp>
|
||||
#include <sweet/lexer/Lexer.ipp>
|
||||
#include <sweet/lexer/PositionIterator.hpp>
|
||||
#include <string.h>
|
||||
|
||||
using namespace sweet::lexer;
|
||||
|
||||
|
|
@ -1219,7 +1220,7 @@ SUITE( RegularExpressions )
|
|||
{
|
||||
void* whitespace;
|
||||
LexerStateMachine lexer_state_machine( "[ \\t\\r\\n]", &whitespace );
|
||||
Lexer<PositionIterator<const char*>> lexer( &lexer_state_machine, NULL );
|
||||
Lexer<PositionIterator<const char*> > lexer( &lexer_state_machine, NULL );
|
||||
|
||||
const char* regex = "\n \r\n \r \r\n";
|
||||
lexer.reset( PositionIterator<const char*>(regex, regex + strlen(regex)), PositionIterator<const char*>() );
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ Executable {
|
|||
"unit/libUnitTest"
|
||||
};
|
||||
|
||||
Cc {
|
||||
Source {
|
||||
pch = "stdafx.hpp";
|
||||
"main.cpp",
|
||||
"TestRegularExpressions.cpp"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// AddGlobal.hpp
|
||||
// Copyright (c) 2007 - 2011 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2007 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef SWEET_LUA_ADDGLOBAL_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// AddGlobal.ipp
|
||||
// Copyright (c) 2007 - 2010 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2007 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef SWEET_LUA_ADDGLOBAL_IPP_INCLUDED
|
||||
|
|
@ -9,6 +9,11 @@
|
|||
#include "AddGlobal.hpp"
|
||||
#include "LuaPosition.hpp"
|
||||
#include "LuaPolicyWrapper.ipp"
|
||||
#include "LuaRawWrapper.hpp"
|
||||
#include "LuaThunker.hpp"
|
||||
#include "LuaReturner.hpp"
|
||||
#include "LuaConverter.hpp"
|
||||
#include "LuaStackGuard.hpp"
|
||||
#include <sweet/assert/assert.hpp>
|
||||
|
||||
/**
|
||||
|
|
@ -66,7 +71,7 @@ sweet::lua::AddGlobal::operator()( const char* name, const Function& function, c
|
|||
void* copied_function = lua_newuserdata( lua_state_, sizeof(Function) );
|
||||
*reinterpret_cast<Function*>(copied_function) = function;
|
||||
LuaConverter<P0>::push( lua_state_, p0 );
|
||||
lua_pushcclosure( lua_state_, &LuaThunker<Function, LuaReturner<traits<Function>::return_type>, LuaPosition<P0, 2>::position, 1, 2, 3, 4, 5, 6>::function, 2 );
|
||||
lua_pushcclosure( lua_state_, &LuaThunker<Function, LuaReturner<typename traits<Function>::return_type>, LuaPosition<P0, 2>::position, 1, 2, 3, 4, 5, 6>::function, 2 );
|
||||
lua_setglobal( lua_state_, name );
|
||||
|
||||
return *this;
|
||||
|
|
@ -105,7 +110,7 @@ sweet::lua::AddGlobal::operator()( const char* name, const Function& function, c
|
|||
*reinterpret_cast<Function*>(copied_function) = function;
|
||||
LuaConverter<P0>::push( lua_state_, p0 );
|
||||
LuaConverter<P1>::push( lua_state_, p1 );
|
||||
lua_pushcclosure( lua_state_, &LuaThunker<Function, LuaReturner<traits<Function>::return_type>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, 1, 2, 3, 4, 5>::function, 3 );
|
||||
lua_pushcclosure( lua_state_, &LuaThunker<Function, LuaReturner<typename traits<Function>::return_type>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, 1, 2, 3, 4, 5>::function, 3 );
|
||||
lua_setglobal( lua_state_, name );
|
||||
|
||||
return *this;
|
||||
|
|
@ -148,7 +153,7 @@ sweet::lua::AddGlobal::operator()( const char* name, const Function& function, c
|
|||
LuaConverter<P0>::push( lua_state_, p0 );
|
||||
LuaConverter<P1>::push( lua_state_, p1 );
|
||||
LuaConverter<P2>::push( lua_state_, p2 );
|
||||
lua_pushcclosure( lua_state_, &LuaThunker<Function, LuaReturner<traits<Function>::return_type>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, 1, 2, 3, 4>::function, 4 );
|
||||
lua_pushcclosure( lua_state_, &LuaThunker<Function, LuaReturner<typename traits<Function>::return_type>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, 1, 2, 3, 4>::function, 4 );
|
||||
lua_setglobal( lua_state_, name );
|
||||
|
||||
return *this;
|
||||
|
|
@ -195,7 +200,7 @@ sweet::lua::AddGlobal::operator()( const char* name, const Function& function, c
|
|||
LuaConverter<P1>::push( lua_state_, p1 );
|
||||
LuaConverter<P2>::push( lua_state_, p2 );
|
||||
LuaConverter<P3>::push( lua_state_, p3 );
|
||||
lua_pushcclosure( lua_state_, &LuaThunker<Function, LuaReturner<traits<Function>::return_type>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, LuaPosition<P3, 5>::position, 1, 2, 3>::function, 5 );
|
||||
lua_pushcclosure( lua_state_, &LuaThunker<Function, LuaReturner<typename traits<Function>::return_type>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, LuaPosition<P3, 5>::position, 1, 2, 3>::function, 5 );
|
||||
lua_setglobal( lua_state_, name );
|
||||
|
||||
return *this;
|
||||
|
|
@ -246,7 +251,7 @@ sweet::lua::AddGlobal::operator()( const char* name, const Function& function, c
|
|||
LuaConverter<P2>::push( lua_state_, p2 );
|
||||
LuaConverter<P3>::push( lua_state_, p3 );
|
||||
LuaConverter<P4>::push( lua_state_, p4 );
|
||||
lua_pushcclosure( lua_state_, &LuaThunker<Function, LuaReturner<traits<Function>::return_type>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, LuaPosition<P3, 5>::position, LuaPosition<P4, 6>::position, 1, 2>::function, 6 );
|
||||
lua_pushcclosure( lua_state_, &LuaThunker<Function, LuaReturner<typename traits<Function>::return_type>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, LuaPosition<P3, 5>::position, LuaPosition<P4, 6>::position, 1, 2>::function, 6 );
|
||||
lua_setglobal( lua_state_, name );
|
||||
|
||||
return *this;
|
||||
|
|
@ -301,7 +306,7 @@ sweet::lua::AddGlobal::operator()( const char* name, const Function& function, c
|
|||
LuaConverter<P3>::push( lua_state_, p3 );
|
||||
LuaConverter<P4>::push( lua_state_, p4 );
|
||||
LuaConverter<P5>::push( lua_state_, p5 );
|
||||
lua_pushcclosure( lua_state_, &LuaThunker<Function, LuaReturner<traits<Function>::return_type>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, LuaPosition<P3, 5>::position, LuaPosition<P4, 6>::position, LuaPosition<P5, 7>::position, 1>::function, 7 );
|
||||
lua_pushcclosure( lua_state_, &LuaThunker<Function, LuaReturner<typename traits<Function>::return_type>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, LuaPosition<P3, 5>::position, LuaPosition<P4, 6>::position, LuaPosition<P5, 7>::position, 1>::function, 7 );
|
||||
lua_setglobal( lua_state_, name );
|
||||
|
||||
return *this;
|
||||
|
|
@ -360,7 +365,7 @@ sweet::lua::AddGlobal::operator()( const char* name, const Function& function, c
|
|||
LuaConverter<P4>::push( lua_state_, p4 );
|
||||
LuaConverter<P5>::push( lua_state_, p5 );
|
||||
LuaConverter<P6>::push( lua_state_, p6 );
|
||||
lua_pushcclosure( lua_state_, &LuaThunker<Function, LuaReturner<traits<Function>::return_type>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, LuaPosition<P3, 5>::position, LuaPosition<P4, 6>::position, LuaPosition<P5, 7>::position, LuaPosition<P6, 8>::position>::function, 8 );
|
||||
lua_pushcclosure( lua_state_, &LuaThunker<Function, LuaReturner<typename traits<Function>::return_type>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, LuaPosition<P3, 5>::position, LuaPosition<P4, 6>::position, LuaPosition<P5, 7>::position, LuaPosition<P6, 8>::position>::function, 8 );
|
||||
lua_setglobal( lua_state_, name );
|
||||
|
||||
return *this;
|
||||
|
|
@ -390,7 +395,7 @@ sweet::lua::AddGlobal::operator()( const char* name, const LuaPolicyWrapper<Func
|
|||
LuaStackGuard guard( lua_state_ );
|
||||
void* copied_function = lua_newuserdata( lua_state_, sizeof(Function) );
|
||||
*reinterpret_cast<Function*>(copied_function) = policy_wrapper.get_function();
|
||||
lua_pushcclosure( lua_state_, &LuaThunker<Function, LuaReturner<traits<Function>::return_type, POLICY>, 1, 2, 3, 4, 5, 6, 7>::function, 1 );
|
||||
lua_pushcclosure( lua_state_, &LuaThunker<Function, LuaReturner<typename traits<Function>::return_type, POLICY>, 1, 2, 3, 4, 5, 6, 7>::function, 1 );
|
||||
lua_setglobal( lua_state_, name );
|
||||
|
||||
return *this;
|
||||
|
|
@ -424,7 +429,7 @@ sweet::lua::AddGlobal::operator()( const char* name, const LuaPolicyWrapper<Func
|
|||
void* copied_function = lua_newuserdata( lua_state_, sizeof(Function) );
|
||||
*reinterpret_cast<Function*>(copied_function) = policy_wrapper.get_function();
|
||||
LuaConverter<P0>::push( lua_state_, p0 );
|
||||
lua_pushcclosure( lua_state_, &LuaThunker<Function, LuaReturner<traits<Function>::return_type, POLICY>, LuaPosition<P0, 2>::position, 1, 2, 3, 4, 5, 6>::function, 2 );
|
||||
lua_pushcclosure( lua_state_, &LuaThunker<Function, LuaReturner<typename traits<Function>::return_type, POLICY>, LuaPosition<P0, 2>::position, 1, 2, 3, 4, 5, 6>::function, 2 );
|
||||
lua_setglobal( lua_state_, name );
|
||||
|
||||
return *this;
|
||||
|
|
@ -462,7 +467,7 @@ sweet::lua::AddGlobal::operator()( const char* name, const LuaPolicyWrapper<Func
|
|||
*reinterpret_cast<Function*>(copied_function) = policy_wrapper.get_function();
|
||||
LuaConverter<P0>::push( lua_state_, p0 );
|
||||
LuaConverter<P1>::push( lua_state_, p1 );
|
||||
lua_pushcclosure( lua_state_, &LuaThunker<Function, LuaReturner<traits<Function>::return_type, POLICY>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, 1, 2, 3, 4, 5>::function, 3 );
|
||||
lua_pushcclosure( lua_state_, &LuaThunker<Function, LuaReturner<typename traits<Function>::return_type, POLICY>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, 1, 2, 3, 4, 5>::function, 3 );
|
||||
lua_setglobal( lua_state_, name );
|
||||
|
||||
return *this;
|
||||
|
|
@ -504,7 +509,7 @@ sweet::lua::AddGlobal::operator()( const char* name, const LuaPolicyWrapper<Func
|
|||
LuaConverter<P0>::push( lua_state_, p0 );
|
||||
LuaConverter<P1>::push( lua_state_, p1 );
|
||||
LuaConverter<P2>::push( lua_state_, p2 );
|
||||
lua_pushcclosure( lua_state_, &LuaThunker<Function, LuaReturner<traits<Function>::return_type, POLICY>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, 1, 2, 3, 4>::function, 4 );
|
||||
lua_pushcclosure( lua_state_, &LuaThunker<Function, LuaReturner<typename traits<Function>::return_type, POLICY>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, 1, 2, 3, 4>::function, 4 );
|
||||
lua_setglobal( lua_state_, name );
|
||||
|
||||
return *this;
|
||||
|
|
@ -550,7 +555,7 @@ sweet::lua::AddGlobal::operator()( const char* name, const LuaPolicyWrapper<Func
|
|||
LuaConverter<P1>::push( lua_state_, p1 );
|
||||
LuaConverter<P2>::push( lua_state_, p2 );
|
||||
LuaConverter<P3>::push( lua_state_, p3 );
|
||||
lua_pushcclosure( lua_state_, &LuaThunker<Function, LuaReturner<traits<Function>::return_type, POLICY>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, LuaPosition<P3, 5>::position, 1, 2, 3>::function, 5 );
|
||||
lua_pushcclosure( lua_state_, &LuaThunker<Function, LuaReturner<typename traits<Function>::return_type, POLICY>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, LuaPosition<P3, 5>::position, 1, 2, 3>::function, 5 );
|
||||
lua_setglobal( lua_state_, name );
|
||||
|
||||
return *this;
|
||||
|
|
@ -600,7 +605,7 @@ sweet::lua::AddGlobal::operator()( const char* name, const LuaPolicyWrapper<Func
|
|||
LuaConverter<P2>::push( lua_state_, p2 );
|
||||
LuaConverter<P3>::push( lua_state_, p3 );
|
||||
LuaConverter<P4>::push( lua_state_, p4 );
|
||||
lua_pushcclosure( lua_state_, &LuaThunker<Function, LuaReturner<traits<Function>::return_type, POLICY>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, LuaPosition<P3, 5>::position, LuaPosition<P4, 6>::position, 1, 2>::function, 6 );
|
||||
lua_pushcclosure( lua_state_, &LuaThunker<Function, LuaReturner<typename traits<Function>::return_type, POLICY>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, LuaPosition<P3, 5>::position, LuaPosition<P4, 6>::position, 1, 2>::function, 6 );
|
||||
lua_setglobal( lua_state_, name );
|
||||
|
||||
return *this;
|
||||
|
|
@ -654,7 +659,7 @@ sweet::lua::AddGlobal::operator()( const char* name, const LuaPolicyWrapper<Func
|
|||
LuaConverter<P3>::push( lua_state_, p3 );
|
||||
LuaConverter<P4>::push( lua_state_, p4 );
|
||||
LuaConverter<P5>::push( lua_state_, p5 );
|
||||
lua_pushcclosure( lua_state_, &LuaThunker<Function, LuaReturner<traits<Function>::return_type, POLICY>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, LuaPosition<P3, 5>::position, LuaPosition<P4, 6>::position, LuaPosition<P5, 7>::position, 1>::function, 7 );
|
||||
lua_pushcclosure( lua_state_, &LuaThunker<Function, LuaReturner<typename traits<Function>::return_type, POLICY>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, LuaPosition<P3, 5>::position, LuaPosition<P4, 6>::position, LuaPosition<P5, 7>::position, 1>::function, 7 );
|
||||
lua_setglobal( lua_state_, name );
|
||||
|
||||
return *this;
|
||||
|
|
@ -712,7 +717,7 @@ sweet::lua::AddGlobal::operator()( const char* name, const LuaPolicyWrapper<Func
|
|||
LuaConverter<P4>::push( lua_state_, p4 );
|
||||
LuaConverter<P5>::push( lua_state_, p5 );
|
||||
LuaConverter<P6>::push( lua_state_, p6 );
|
||||
lua_pushcclosure( lua_state_, &LuaThunker<Function, LuaReturner<traits<Function>::return_type, POLICY>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, LuaPosition<P3, 5>::position, LuaPosition<P4, 6>::position, LuaPosition<P5, 7>::position, LuaPosition<P6, 8>::position>::function, 8 );
|
||||
lua_pushcclosure( lua_state_, &LuaThunker<Function, LuaReturner<typename traits<Function>::return_type, POLICY>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, LuaPosition<P3, 5>::position, LuaPosition<P4, 6>::position, LuaPosition<P5, 7>::position, LuaPosition<P6, 8>::position>::function, 8 );
|
||||
lua_setglobal( lua_state_, name );
|
||||
|
||||
return *this;
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
//
|
||||
// AddMember.cpp
|
||||
// Copyright (c) 2007 - 2011 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2007 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#include "AddMember.hpp"
|
||||
#include "AddMemberHelper.hpp"
|
||||
#include "LuaStackGuard.hpp"
|
||||
#include "lua_types.hpp"
|
||||
#include "lua_functions.hpp"
|
||||
#include "lua_functions.ipp"
|
||||
#include <sweet/assert/assert.hpp>
|
||||
|
||||
using namespace sweet;
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ sweet::lua::AddMember::operator()( const char* name, const Function& function, c
|
|||
void* copied_function = lua_newuserdata( lua_state, sizeof(Function) );
|
||||
*reinterpret_cast<Function*>(copied_function) = function;
|
||||
LuaConverter<P0>::push( lua_state, p0 );
|
||||
lua_pushcclosure( lua_state, &LuaThunker<Function, LuaReturner<traits<Function>::return_type>, LuaPosition<P0, 2>::position, 1, 2, 3, 4, 5, 6>::function, 2 );
|
||||
lua_pushcclosure( lua_state, &LuaThunker<Function, LuaReturner<typename traits<Function>::return_type>, LuaPosition<P0, 2>::position, 1, 2, 3, 4, 5, 6>::function, 2 );
|
||||
lua_setfield( lua_state, -2, name );
|
||||
|
||||
return *this;
|
||||
|
|
@ -172,7 +172,7 @@ sweet::lua::AddMember::operator()( const char* name, const Function& function, c
|
|||
*reinterpret_cast<Function*>(copied_function) = function;
|
||||
LuaConverter<P0>::push( lua_state, p0 );
|
||||
LuaConverter<P1>::push( lua_state, p1 );
|
||||
lua_pushcclosure( lua_state, &LuaThunker<Function, LuaReturner<traits<Function>::return_type>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, 1, 2, 3, 4, 5>::function, 3 );
|
||||
lua_pushcclosure( lua_state, &LuaThunker<Function, LuaReturner<typename traits<Function>::return_type>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, 1, 2, 3, 4, 5>::function, 3 );
|
||||
lua_setfield( lua_state, -2, name );
|
||||
|
||||
return *this;
|
||||
|
|
@ -216,7 +216,7 @@ sweet::lua::AddMember::operator()( const char* name, const Function& function, c
|
|||
LuaConverter<P0>::push( lua_state, p0 );
|
||||
LuaConverter<P1>::push( lua_state, p1 );
|
||||
LuaConverter<P2>::push( lua_state, p2 );
|
||||
lua_pushcclosure( lua_state, &LuaThunker<Function, LuaReturner<traits<Function>::return_type>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, 1, 2, 3, 4>::function, 4 );
|
||||
lua_pushcclosure( lua_state, &LuaThunker<Function, LuaReturner<typename traits<Function>::return_type>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, 1, 2, 3, 4>::function, 4 );
|
||||
lua_setfield( lua_state, -2, name );
|
||||
|
||||
return *this;
|
||||
|
|
@ -264,7 +264,7 @@ sweet::lua::AddMember::operator()( const char* name, const Function& function, c
|
|||
LuaConverter<P1>::push( lua_state, p1 );
|
||||
LuaConverter<P2>::push( lua_state, p2 );
|
||||
LuaConverter<P3>::push( lua_state, p3 );
|
||||
lua_pushcclosure( lua_state, &LuaThunker<Function, LuaReturner<traits<Function>::return_type>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, LuaPosition<P3, 5>::position, 1, 2, 3>::function, 5 );
|
||||
lua_pushcclosure( lua_state, &LuaThunker<Function, LuaReturner<typename traits<Function>::return_type>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, LuaPosition<P3, 5>::position, 1, 2, 3>::function, 5 );
|
||||
lua_setfield( lua_state, -2, name );
|
||||
|
||||
return *this;
|
||||
|
|
@ -316,7 +316,7 @@ sweet::lua::AddMember::operator()( const char* name, const Function& function, c
|
|||
LuaConverter<P2>::push( lua_state, p2 );
|
||||
LuaConverter<P3>::push( lua_state, p3 );
|
||||
LuaConverter<P4>::push( lua_state, p4 );
|
||||
lua_pushcclosure( lua_state, &LuaThunker<Function, LuaReturner<traits<Function>::return_type>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, LuaPosition<P3, 5>::position, LuaPosition<P4, 6>::position, 1, 2>::function, 6 );
|
||||
lua_pushcclosure( lua_state, &LuaThunker<Function, LuaReturner<typename traits<Function>::return_type>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, LuaPosition<P3, 5>::position, LuaPosition<P4, 6>::position, 1, 2>::function, 6 );
|
||||
lua_setfield( lua_state, -2, name );
|
||||
|
||||
return *this;
|
||||
|
|
@ -372,7 +372,7 @@ sweet::lua::AddMember::operator()( const char* name, const Function& function, c
|
|||
LuaConverter<P3>::push( lua_state, p3 );
|
||||
LuaConverter<P4>::push( lua_state, p4 );
|
||||
LuaConverter<P5>::push( lua_state, p5 );
|
||||
lua_pushcclosure( lua_state, &LuaThunker<Function, LuaReturner<traits<Function>::return_type>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, LuaPosition<P3, 5>::position, LuaPosition<P4, 6>::position, LuaPosition<P5, 7>::position, 1>::function, 7 );
|
||||
lua_pushcclosure( lua_state, &LuaThunker<Function, LuaReturner<typename traits<Function>::return_type>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, LuaPosition<P3, 5>::position, LuaPosition<P4, 6>::position, LuaPosition<P5, 7>::position, 1>::function, 7 );
|
||||
lua_setfield( lua_state, -2, name );
|
||||
|
||||
return *this;
|
||||
|
|
@ -432,7 +432,7 @@ sweet::lua::AddMember::operator()( const char* name, const Function& function, c
|
|||
LuaConverter<P4>::push( lua_state, p4 );
|
||||
LuaConverter<P5>::push( lua_state, p5 );
|
||||
LuaConverter<P6>::push( lua_state, p6 );
|
||||
lua_pushcclosure( lua_state, &LuaThunker<Function, LuaReturner<traits<Function>::return_type>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, LuaPosition<P3, 5>::position, LuaPosition<P4, 6>::position, LuaPosition<P5, 7>::position, LuaPosition<P6, 8>::position>::function, 8 );
|
||||
lua_pushcclosure( lua_state, &LuaThunker<Function, LuaReturner<typename traits<Function>::return_type>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, LuaPosition<P3, 5>::position, LuaPosition<P4, 6>::position, LuaPosition<P5, 7>::position, LuaPosition<P6, 8>::position>::function, 8 );
|
||||
lua_setfield( lua_state, -2, name );
|
||||
|
||||
return *this;
|
||||
|
|
@ -464,7 +464,7 @@ sweet::lua::AddMember::operator()( const char* name, const LuaPolicyWrapper<Func
|
|||
LuaStackGuard guard( lua_state );
|
||||
void* copied_function = lua_newuserdata( lua_state, sizeof(Function) );
|
||||
*reinterpret_cast<Function*>(copied_function) = policy_wrapper.get_function();
|
||||
lua_pushcclosure( lua_state, &LuaThunker<Function, LuaReturner<traits<Function>::return_type, POLICY>, 1, 2, 3, 4, 5, 6, 7>::function, 1 );
|
||||
lua_pushcclosure( lua_state, &LuaThunker<Function, LuaReturner<typename traits<Function>::return_type, POLICY>, 1, 2, 3, 4, 5, 6, 7>::function, 1 );
|
||||
lua_setfield( lua_state, -2, name );
|
||||
|
||||
return *this;
|
||||
|
|
@ -500,7 +500,7 @@ sweet::lua::AddMember::operator()( const char* name, const LuaPolicyWrapper<Func
|
|||
void* copied_function = lua_newuserdata( lua_state, sizeof(Function) );
|
||||
*reinterpret_cast<Function*>(copied_function) = policy_wrapper.get_function();
|
||||
LuaConverter<P0>::push( lua_state, p0 );
|
||||
lua_pushcclosure( lua_state, &LuaThunker<Function, LuaReturner<traits<Function>::return_type, POLICY>, LuaPosition<P0, 2>::position, 1, 2, 3, 4, 5, 6>::function, 2 );
|
||||
lua_pushcclosure( lua_state, &LuaThunker<Function, LuaReturner<typename traits<Function>::return_type, POLICY>, LuaPosition<P0, 2>::position, 1, 2, 3, 4, 5, 6>::function, 2 );
|
||||
lua_setfield( lua_state, -2, name );
|
||||
|
||||
return *this;
|
||||
|
|
@ -540,7 +540,7 @@ sweet::lua::AddMember::operator()( const char* name, const LuaPolicyWrapper<Func
|
|||
*reinterpret_cast<Function*>(copied_function) = policy_wrapper.get_function();
|
||||
LuaConverter<P0>::push( lua_state, p0 );
|
||||
LuaConverter<P1>::push( lua_state, p1 );
|
||||
lua_pushcclosure( lua_state, &LuaThunker<Function, LuaReturner<traits<Function>::return_type, POLICY>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, 1, 2, 3, 4, 5>::function, 3 );
|
||||
lua_pushcclosure( lua_state, &LuaThunker<Function, LuaReturner<typename traits<Function>::return_type, POLICY>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, 1, 2, 3, 4, 5>::function, 3 );
|
||||
lua_setfield( lua_state, -2, name );
|
||||
|
||||
return *this;
|
||||
|
|
@ -584,7 +584,7 @@ sweet::lua::AddMember::operator()( const char* name, const LuaPolicyWrapper<Func
|
|||
LuaConverter<P0>::push( lua_state, p0 );
|
||||
LuaConverter<P1>::push( lua_state, p1 );
|
||||
LuaConverter<P2>::push( lua_state, p2 );
|
||||
lua_pushcclosure( lua_state, &LuaThunker<Function, LuaReturner<traits<Function>::return_type, POLICY>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, 1, 2, 3, 4>::function, 4 );
|
||||
lua_pushcclosure( lua_state, &LuaThunker<Function, LuaReturner<typename traits<Function>::return_type, POLICY>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, 1, 2, 3, 4>::function, 4 );
|
||||
lua_setfield( lua_state, -2, name );
|
||||
|
||||
return *this;
|
||||
|
|
@ -632,7 +632,7 @@ sweet::lua::AddMember::operator()( const char* name, const LuaPolicyWrapper<Func
|
|||
LuaConverter<P1>::push( lua_state, p1 );
|
||||
LuaConverter<P2>::push( lua_state, p2 );
|
||||
LuaConverter<P3>::push( lua_state, p3 );
|
||||
lua_pushcclosure( lua_state, &LuaThunker<Function, LuaReturner<traits<Function>::return_type, POLICY>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, LuaPosition<P3, 5>::position, 1, 2, 3>::function, 5 );
|
||||
lua_pushcclosure( lua_state, &LuaThunker<Function, LuaReturner<typename traits<Function>::return_type, POLICY>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, LuaPosition<P3, 5>::position, 1, 2, 3>::function, 5 );
|
||||
lua_setfield( lua_state, -2, name );
|
||||
|
||||
return *this;
|
||||
|
|
@ -684,7 +684,7 @@ sweet::lua::AddMember::operator()( const char* name, const LuaPolicyWrapper<Func
|
|||
LuaConverter<P2>::push( lua_state, p2 );
|
||||
LuaConverter<P3>::push( lua_state, p3 );
|
||||
LuaConverter<P4>::push( lua_state, p4 );
|
||||
lua_pushcclosure( lua_state, &LuaThunker<Function, LuaReturner<traits<Function>::return_type, POLICY>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, LuaPosition<P3, 5>::position, LuaPosition<P4, 6>::position, 1, 2>::function, 6 );
|
||||
lua_pushcclosure( lua_state, &LuaThunker<Function, LuaReturner<typename traits<Function>::return_type, POLICY>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, LuaPosition<P3, 5>::position, LuaPosition<P4, 6>::position, 1, 2>::function, 6 );
|
||||
lua_setfield( lua_state, -2, name );
|
||||
|
||||
return *this;
|
||||
|
|
@ -740,7 +740,7 @@ sweet::lua::AddMember::operator()( const char* name, const LuaPolicyWrapper<Func
|
|||
LuaConverter<P3>::push( lua_state, p3 );
|
||||
LuaConverter<P4>::push( lua_state, p4 );
|
||||
LuaConverter<P5>::push( lua_state, p5 );
|
||||
lua_pushcclosure( lua_state, &LuaThunker<Function, LuaReturner<traits<Function>::return_type, POLICY>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, LuaPosition<P3, 5>::position, LuaPosition<P4, 6>::position, LuaPosition<P5, 7>::position, 1>::function, 7 );
|
||||
lua_pushcclosure( lua_state, &LuaThunker<Function, LuaReturner<typename traits<Function>::return_type, POLICY>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, LuaPosition<P3, 5>::position, LuaPosition<P4, 6>::position, LuaPosition<P5, 7>::position, 1>::function, 7 );
|
||||
lua_setfield( lua_state, -2, name );
|
||||
|
||||
return *this;
|
||||
|
|
@ -800,7 +800,7 @@ sweet::lua::AddMember::operator()( const char* name, const LuaPolicyWrapper<Func
|
|||
LuaConverter<P4>::push( lua_state, p4 );
|
||||
LuaConverter<P5>::push( lua_state, p5 );
|
||||
LuaConverter<P6>::push( lua_state, p6 );
|
||||
lua_pushcclosure( lua_state, &LuaThunker<Function, LuaReturner<traits<Function>::return_type, POLICY>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, LuaPosition<P3, 5>::position, LuaPosition<P4, 6>::position, LuaPosition<P5, 7>::position, LuaPosition<P6, 8>::position>::function, 8 );
|
||||
lua_pushcclosure( lua_state, &LuaThunker<Function, LuaReturner<typename traits<Function>::return_type, POLICY>, LuaPosition<P0, 2>::position, LuaPosition<P1, 3>::position, LuaPosition<P2, 4>::position, LuaPosition<P3, 5>::position, LuaPosition<P4, 6>::position, LuaPosition<P5, 7>::position, LuaPosition<P6, 8>::position>::function, 8 );
|
||||
lua_setfield( lua_state, -2, name );
|
||||
|
||||
return *this;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// AddMemberHelper.hpp
|
||||
// Copyright (c) 2009 - 2011 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2009 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef SWEET_LUA_ADDMEMBERHELPER_HPP_INCLUDED
|
||||
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#include "declspec.hpp"
|
||||
|
||||
struct lua_State;
|
||||
|
||||
namespace sweet
|
||||
{
|
||||
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ AddParameter& AddParameter::operator()( bool value )
|
|||
*/
|
||||
AddParameter& AddParameter::operator()( int value )
|
||||
{
|
||||
add_parameter_helper_->push( static_cast<lua_Integer>(value) );
|
||||
add_parameter_helper_->push( value );
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
//
|
||||
// AddParameter.ipp
|
||||
// Copyright (c) 2007 - 2010 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2007 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef SWEET_LUA_ADDPARAMETER_IPP_INCLUDED
|
||||
#define SWEET_LUA_ADDPARAMETER_IPP_INCLUDED
|
||||
|
||||
#include "AddParameter.hpp"
|
||||
#include "AddParameterHelper.hpp"
|
||||
|
||||
/**
|
||||
// Push an arbitrary value onto the Lua stack.
|
||||
|
|
@ -28,8 +29,8 @@ sweet::lua::AddParameter& sweet::lua::AddParameter::operator()( const Type& valu
|
|||
/**
|
||||
// Call the function and retrieve an arbitrary return value.
|
||||
//
|
||||
// This is done in a separate function (instead of the destructor) because
|
||||
// calling the function can throw an exception.
|
||||
// This is done in this function instead of the destructor because calling
|
||||
// the function can throw an exception.
|
||||
//
|
||||
// @param return_value
|
||||
// A pointer to the variable to place the return value into (assumed not
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@
|
|||
#include "LuaValue.hpp"
|
||||
#include "Lua.hpp"
|
||||
#include <sweet/error/macros.hpp>
|
||||
#include <memory.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(BUILD_OS_WINDOWS)
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
using namespace sweet::lua;
|
||||
|
||||
|
|
@ -755,15 +761,14 @@ const char* AddParameterHelper::stack_trace_for_resume( lua_State* lua_state, bo
|
|||
|
||||
size_t written = 0;
|
||||
memset( message, 0, length );
|
||||
|
||||
written += _snprintf( message + written, length - written, "%s", lua_isstring(lua_state, -1) ? lua_tostring(lua_state, -1) : "Unknown error" );
|
||||
written += snprintf( message + written, length - written, "%s", lua_isstring(lua_state, -1) ? lua_tostring(lua_state, -1) : "Unknown error" );
|
||||
|
||||
if ( stack_trace_enabled )
|
||||
{
|
||||
static const int STACK_TRACE_BEGIN = 0;
|
||||
static const int STACK_TRACE_END = 6;
|
||||
|
||||
written += _snprintf( message + written, length - written, ".\nstack trace:" );
|
||||
written += snprintf( message + written, length - written, ".\nstack trace:" );
|
||||
|
||||
lua_Debug debug;
|
||||
memset( &debug, 0, sizeof(debug) );
|
||||
|
|
@ -776,14 +781,14 @@ const char* AddParameterHelper::stack_trace_for_resume( lua_State* lua_state, bo
|
|||
//
|
||||
// Source and line number.
|
||||
//
|
||||
written += _snprintf( message + written, length - written, "\n " );
|
||||
written += snprintf( message + written, length - written, "\n " );
|
||||
if ( debug.currentline > 0 )
|
||||
{
|
||||
written += _snprintf( message + written, length - written, "%s(%d) : ", debug.source, debug.currentline );
|
||||
written += snprintf( message + written, length - written, "%s(%d) : ", debug.source, debug.currentline );
|
||||
}
|
||||
else
|
||||
{
|
||||
written += _snprintf( message + written, length - written, "%s(1) : ", debug.source, debug.currentline );
|
||||
written += snprintf( message + written, length - written, "%s(1) : ", debug.source, debug.currentline );
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -791,18 +796,18 @@ const char* AddParameterHelper::stack_trace_for_resume( lua_State* lua_state, bo
|
|||
//
|
||||
if ( *debug.namewhat != '\0' )
|
||||
{
|
||||
written += _snprintf( message + written, length - written, "in function " LUA_QS, debug.name );
|
||||
written += snprintf( message + written, length - written, "in function " LUA_QS, debug.name );
|
||||
}
|
||||
else
|
||||
{
|
||||
switch ( *debug.what )
|
||||
{
|
||||
case 'm':
|
||||
written += _snprintf( message + written, length - written, "main");
|
||||
written += snprintf( message + written, length - written, "main");
|
||||
break;
|
||||
|
||||
default:
|
||||
written += _snprintf( message + written, length - written, "in function <%s(%d)>", debug.source, debug.linedefined );
|
||||
written += snprintf( message + written, length - written, "in function <%s(%d)>", debug.source, debug.linedefined );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// AddParameterHelper.ipp
|
||||
// Copyright (c) 2007 - 2010 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2007 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef SWEET_LUA_ADDPARAMETERHELPER_IPP_INCLUDED
|
||||
|
|
@ -8,7 +8,9 @@
|
|||
|
||||
#include "AddParameterHelper.hpp"
|
||||
#include "LuaStackGuard.hpp"
|
||||
#include "LuaConverter.hpp"
|
||||
#include "Error.hpp"
|
||||
#include "Lua.hpp"
|
||||
#include <sweet/traits/traits.hpp>
|
||||
#include <sweet/assert/assert.hpp>
|
||||
|
||||
|
|
@ -78,7 +80,7 @@ void AddParameterHelper::end( Type* return_value )
|
|||
SWEET_ASSERT( return_value );
|
||||
LuaStackGuard guard( lua_state_, error_handler_ == 0 ? parameters_ + 1 : parameters_ + 2 );
|
||||
internal_end( 1 );
|
||||
*return_value = LuaConverter<traits::traits<Type>::value_type>::to( lua_state_, -1 );
|
||||
*return_value = LuaConverter<typename traits::traits<Type>::value_type>::to( lua_state_, -1 );
|
||||
lua_pop( lua_state_, 1 );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
//
|
||||
// Lua.hpp
|
||||
// Copyright (c) 2007 - 2011 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2007 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef SWEET_LUA_LUA_HPP_INCLUDED
|
||||
#define SWEET_LUA_LUA_HPP_INCLUDED
|
||||
|
||||
#include "declspec.hpp"
|
||||
#include "AddParameterHelper.ipp"
|
||||
#include "AddMemberHelper.hpp"
|
||||
#include "AddGlobal.ipp"
|
||||
#include "AddMember.ipp"
|
||||
|
|
@ -87,5 +86,7 @@ class SWEET_LUA_DECLSPEC Lua
|
|||
}
|
||||
|
||||
#include "Lua.ipp"
|
||||
#include "AddParameterHelper.ipp"
|
||||
#include "lua_functions.ipp"
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// Lua.ipp
|
||||
// Copyright (c) 2009 - 2011 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2009 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef SWEET_LUA_LUA_IPP_INCLUDED
|
||||
|
|
@ -27,8 +27,8 @@ namespace lua
|
|||
template <class Type>
|
||||
void Lua::create( const Type& object )
|
||||
{
|
||||
typedef traits::traits<Type>::base_type base_type;
|
||||
LuaObjectConverter<Type, LuaTraits<base_type>::storage_type>::create( lua_state_, object );
|
||||
typedef typename traits::traits<Type>::base_type base_type;
|
||||
LuaObjectConverter<Type, typename LuaTraits<base_type>::storage_type>::create( lua_state_, object );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -43,8 +43,8 @@ void Lua::create( const Type& object )
|
|||
template <class Type>
|
||||
void Lua::create_with_existing_table( const Type& object )
|
||||
{
|
||||
typedef traits::traits<Type>::base_type base_type;
|
||||
LuaObjectConverter<Type, LuaTraits<base_type>::storage_type>::create_with_existing_table( lua_state_, object );
|
||||
typedef typename traits::traits<Type>::base_type base_type;
|
||||
LuaObjectConverter<Type, typename LuaTraits<base_type>::storage_type>::create_with_existing_table( lua_state_, object );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -56,8 +56,8 @@ void Lua::create_with_existing_table( const Type& object )
|
|||
template <class Type>
|
||||
void Lua::destroy( const Type& object )
|
||||
{
|
||||
typedef traits::traits<Type>::base_type base_type;
|
||||
LuaObjectConverter<Type, LuaTraits<base_type>::storage_type>::destroy( lua_state_, object );
|
||||
typedef typename traits::traits<Type>::base_type base_type;
|
||||
LuaObjectConverter<Type, typename LuaTraits<base_type>::storage_type>::destroy( lua_state_, object );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -70,8 +70,8 @@ void Lua::destroy( const Type& object )
|
|||
template <class Type>
|
||||
AddMember Lua::members( const Type& object )
|
||||
{
|
||||
typedef traits::traits<Type>::base_type base_type;
|
||||
LuaObjectConverter<Type, LuaTraits<base_type>::storage_type>::push( lua_state_, object );
|
||||
typedef typename traits::traits<Type>::base_type base_type;
|
||||
LuaObjectConverter<Type, typename LuaTraits<base_type>::storage_type>::push( lua_state_, object );
|
||||
return AddMember( &add_member_helper_ );
|
||||
}
|
||||
|
||||
|
|
@ -94,8 +94,8 @@ bool Lua::is_value( const Type& object, const char* field ) const
|
|||
SWEET_ASSERT( field );
|
||||
|
||||
LuaStackGuard guard( lua_state_ );
|
||||
typedef traits::traits<Type>::base_type base_type;
|
||||
LuaObjectConverter<Type, LuaTraits<base_type>::storage_type>::push( lua_state_, object );
|
||||
typedef typename traits::traits<Type>::base_type base_type;
|
||||
LuaObjectConverter<Type, typename LuaTraits<base_type>::storage_type>::push( lua_state_, object );
|
||||
lua_getfield( lua_state_, -1, field );
|
||||
return !lua_isnil( lua_state_, -1 ) ? true : false;
|
||||
}
|
||||
|
|
@ -118,8 +118,8 @@ bool Lua::is_boolean( const Type& object, const char* field ) const
|
|||
SWEET_ASSERT( field );
|
||||
|
||||
LuaStackGuard guard( lua_state_ );
|
||||
typedef traits::traits<Type>::base_type base_type;
|
||||
LuaObjectConverter<Type, LuaTraits<base_type>::storage_type>::push( lua_state_, object );
|
||||
typedef typename traits::traits<Type>::base_type base_type;
|
||||
LuaObjectConverter<Type, typename LuaTraits<base_type>::storage_type>::push( lua_state_, object );
|
||||
lua_getfield( lua_state_, -1, field );
|
||||
return lua_isboolean( lua_state_, -1 ) ? true : false;
|
||||
}
|
||||
|
|
@ -143,8 +143,8 @@ bool Lua::is_number( const Type& object, const char* field ) const
|
|||
SWEET_ASSERT( field );
|
||||
|
||||
LuaStackGuard guard( lua_state_ );
|
||||
typedef traits::traits<Type>::base_type base_type;
|
||||
LuaObjectConverter<Type, LuaTraits<base_type>::storage_type>::push( lua_state_, object );
|
||||
typedef typename traits::traits<Type>::base_type base_type;
|
||||
LuaObjectConverter<Type, typename LuaTraits<base_type>::storage_type>::push( lua_state_, object );
|
||||
lua_getfield( lua_state_, -1, field );
|
||||
return lua_isnumber( lua_state_, -1 ) ? true : false;
|
||||
}
|
||||
|
|
@ -169,8 +169,8 @@ bool Lua::is_string( const Type& object, const char* field ) const
|
|||
SWEET_ASSERT( field );
|
||||
|
||||
LuaStackGuard guard( lua_state_ );
|
||||
typedef traits::traits<Type>::base_type base_type;
|
||||
LuaObjectConverter<Type, LuaTraits<base_type>::storage_type>::push( lua_state_, object );
|
||||
typedef typename traits::traits<Type>::base_type base_type;
|
||||
LuaObjectConverter<Type, typename LuaTraits<base_type>::storage_type>::push( lua_state_, object );
|
||||
lua_getfield( lua_state_, -1, field );
|
||||
return lua_isstring( lua_state_, -1 ) ? true : false;
|
||||
}
|
||||
|
|
@ -194,8 +194,8 @@ bool Lua::is_function( const Type& object, const char* field ) const
|
|||
SWEET_ASSERT( field );
|
||||
|
||||
LuaStackGuard guard( lua_state_ );
|
||||
typedef traits::traits<Type>::base_type base_type;
|
||||
LuaObjectConverter<Type, LuaTraits<base_type>::storage_type>::push( lua_state_, object );
|
||||
typedef typename traits::traits<Type>::base_type base_type;
|
||||
LuaObjectConverter<Type, typename LuaTraits<base_type>::storage_type>::push( lua_state_, object );
|
||||
lua_getfield( lua_state_, -1, field );
|
||||
return lua_isfunction( lua_state_, -1 ) ? true : false;
|
||||
}
|
||||
|
|
@ -219,8 +219,8 @@ bool Lua::boolean( const Type& object, const char* field ) const
|
|||
SWEET_ASSERT( field );
|
||||
|
||||
LuaStackGuard guard( lua_state_ );
|
||||
typedef traits::traits<Type>::base_type base_type;
|
||||
LuaObjectConverter<Type, LuaTraits<base_type>::storage_type>::push( lua_state_, object );
|
||||
typedef typename traits::traits<Type>::base_type base_type;
|
||||
LuaObjectConverter<Type, typename LuaTraits<base_type>::storage_type>::push( lua_state_, object );
|
||||
lua_getfield( lua_state_, -1, field );
|
||||
return lua_toboolean( lua_state_, -1 ) ? true : false;
|
||||
}
|
||||
|
|
@ -244,8 +244,8 @@ int Lua::integer( const Type& object, const char* field ) const
|
|||
SWEET_ASSERT( field );
|
||||
|
||||
LuaStackGuard guard( lua_state_ );
|
||||
typedef traits::traits<Type>::base_type base_type;
|
||||
LuaObjectConverter<Type, LuaTraits<base_type>::storage_type>::push( lua_state_, object );
|
||||
typedef typename traits::traits<Type>::base_type base_type;
|
||||
LuaObjectConverter<Type, typename LuaTraits<base_type>::storage_type>::push( lua_state_, object );
|
||||
lua_getfield( lua_state_, -1, field );
|
||||
return lua_tointeger( lua_state_, -1 );
|
||||
}
|
||||
|
|
@ -270,8 +270,8 @@ Lua::number( const Type& object, const char* field ) const
|
|||
SWEET_ASSERT( field );
|
||||
|
||||
LuaStackGuard guard( lua_state_ );
|
||||
typedef traits::traits<Type>::base_type base_type;
|
||||
LuaObjectConverter<Type, LuaTraits<base_type>::storage_type>::push( lua_state_, object );
|
||||
typedef typename traits::traits<Type>::base_type base_type;
|
||||
LuaObjectConverter<Type, typename LuaTraits<base_type>::storage_type>::push( lua_state_, object );
|
||||
lua_getfield( lua_state_, -1, field );
|
||||
return static_cast<float>( lua_tonumber(lua_state_, -1) );
|
||||
}
|
||||
|
|
@ -295,8 +295,8 @@ std::string Lua::string( const Type& object, const char* field ) const
|
|||
SWEET_ASSERT( field );
|
||||
|
||||
LuaStackGuard guard( lua_state_ );
|
||||
typedef traits::traits<Type>::base_type base_type;
|
||||
LuaObjectConverter<Type, LuaTraits<base_type>::storage_type>::push( lua_state_, object );
|
||||
typedef typename traits::traits<Type>::base_type base_type;
|
||||
LuaObjectConverter<Type, typename LuaTraits<base_type>::storage_type>::push( lua_state_, object );
|
||||
lua_getfield( lua_state_, -1, field );
|
||||
return lua_tostring( lua_state_, -1 );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,11 @@
|
|||
//
|
||||
|
||||
#include "LuaAllocator.hpp"
|
||||
#if defined(BUILD_OS_WINDOWS)
|
||||
#include <malloc.h>
|
||||
#elif defined(BUILD_OS_MACOSX)
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
using namespace sweet::lua;
|
||||
|
||||
|
|
@ -26,11 +30,11 @@ void* LuaAllocator::allocate( void* context, void* ptr, size_t osize, size_t nsi
|
|||
{
|
||||
if ( nsize == 0 )
|
||||
{
|
||||
::free( ptr );
|
||||
free( ptr );
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ::realloc( ptr, nsize );
|
||||
return realloc( ptr, nsize );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
//
|
||||
// LuaAllocator.hpp
|
||||
// Copyright (c) 2007 - 2010 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2007 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef SWEET_LUA_LUAALLOCATOR_HPP_INCLUDED
|
||||
#define SWEET_LUA_LUAALLOCATOR_HPP_INCLUDED
|
||||
|
||||
#include "declspec.hpp"
|
||||
#include <sys/types.h>
|
||||
|
||||
namespace sweet
|
||||
{
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ struct LuaConverter
|
|||
};
|
||||
|
||||
template <class Type>
|
||||
struct LuaConverter<LuaValueWrapper<Type>>
|
||||
struct LuaConverter<LuaValueWrapper<Type> >
|
||||
{
|
||||
static void push( lua_State* lua_state, const LuaValueWrapper<Type>& value );
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#define SWEET_LUA_LUACONVERTER_IPP_INCLUDED
|
||||
|
||||
#include "LuaConverter.hpp"
|
||||
#include "LuaObjectConverter.hpp"
|
||||
#include "LuaThunker.ipp"
|
||||
|
||||
namespace sweet
|
||||
|
|
@ -16,36 +17,35 @@ namespace lua
|
|||
{
|
||||
|
||||
template <class Type>
|
||||
void
|
||||
sweet::lua::LuaConverter<Type>::create( lua_State* lua_state, typename traits::traits<Type>::parameter_type value )
|
||||
void sweet::lua::LuaConverter<Type>::create( lua_State* lua_state, typename traits::traits<Type>::parameter_type value )
|
||||
{
|
||||
typedef traits::traits<Type>::base_type base_type;
|
||||
LuaObjectConverter<Type, LuaTraits<base_type>::storage_type>::create( lua_state, value );
|
||||
typedef typename traits::traits<Type>::base_type base_type;
|
||||
LuaObjectConverter<Type, typename LuaTraits<base_type>::storage_type>::create( lua_state, value );
|
||||
}
|
||||
|
||||
template <class Type>
|
||||
void sweet::lua::LuaConverter<Type>::destroy( lua_State* lua_state, typename traits::traits<Type>::parameter_type value )
|
||||
{
|
||||
typedef traits::traits<Type>::base_type base_type;
|
||||
LuaObjectConverter<Type, LuaTraits<base_type>::storage_type>::destroy( lua_state, value );
|
||||
typedef typename traits::traits<Type>::base_type base_type;
|
||||
LuaObjectConverter<Type, typename LuaTraits<base_type>::storage_type>::destroy( lua_state, value );
|
||||
}
|
||||
|
||||
template <class Type>
|
||||
void LuaConverter<Type>::push( lua_State* lua_state, typename traits::traits<Type>::parameter_type value )
|
||||
{
|
||||
typedef traits::traits<Type>::base_type base_type;
|
||||
LuaObjectConverter<Type, LuaTraits<base_type>::storage_type>::push( lua_state, value );
|
||||
typedef typename traits::traits<Type>::base_type base_type;
|
||||
LuaObjectConverter<Type, typename LuaTraits<base_type>::storage_type>::push( lua_state, value );
|
||||
}
|
||||
|
||||
template <class Type>
|
||||
Type LuaConverter<Type>::to( lua_State* lua_state, int position )
|
||||
{
|
||||
typedef traits::traits<Type>::base_type base_type;
|
||||
return LuaObjectConverter<Type, LuaTraits<base_type>::storage_type>::to( lua_state, position );
|
||||
typedef typename traits::traits<Type>::base_type base_type;
|
||||
return LuaObjectConverter<Type, typename LuaTraits<base_type>::storage_type>::to( lua_state, position );
|
||||
}
|
||||
|
||||
template <class Type>
|
||||
void LuaConverter<sweet::lua::LuaValueWrapper<Type>>::push( lua_State* lua_state, const LuaValueWrapper<Type>& value )
|
||||
void LuaConverter<sweet::lua::LuaValueWrapper<Type> >::push( lua_State* lua_state, const LuaValueWrapper<Type>& value )
|
||||
{
|
||||
LuaObjectConverter<Type, LuaByValue>::push( lua_state, value.get_value() );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,17 @@
|
|||
//
|
||||
// LuaGlobalEnvironment.cpp
|
||||
// Copyright (c) 2008 - 2010 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2008 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#include "LuaGlobalEnvironment.hpp"
|
||||
|
||||
using namespace sweet::lua;
|
||||
|
||||
/**
|
||||
// Represents the %Lua global environment when adding globals or members.
|
||||
*/
|
||||
const sweet::lua::LuaGlobalEnvironment sweet::lua::global_environment;
|
||||
|
||||
LuaGlobalEnvironment::LuaGlobalEnvironment()
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ namespace lua
|
|||
*/
|
||||
class SWEET_LUA_DECLSPEC LuaGlobalEnvironment
|
||||
{
|
||||
public:
|
||||
LuaGlobalEnvironment();
|
||||
};
|
||||
|
||||
SWEET_LUA_DECLSPEC extern const LuaGlobalEnvironment global_environment;
|
||||
|
|
|
|||
|
|
@ -1,12 +1,18 @@
|
|||
//
|
||||
// LuaNil.cpp
|
||||
// Copyright (c) 2008 - 2010 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2008 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#include "stdafx.hpp"
|
||||
#include "LuaNil.hpp"
|
||||
|
||||
using namespace sweet::lua;
|
||||
|
||||
/**
|
||||
// Represents a %Lua nil value when adding globals or members.
|
||||
*/
|
||||
const sweet::lua::LuaNil sweet::lua::nil;
|
||||
const sweet::lua::LuaNil sweet::lua::nil;
|
||||
|
||||
LuaNil::LuaNil()
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ namespace lua
|
|||
*/
|
||||
class SWEET_LUA_DECLSPEC LuaNil
|
||||
{
|
||||
public:
|
||||
LuaNil();
|
||||
};
|
||||
|
||||
SWEET_LUA_DECLSPEC extern const LuaNil nil;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// LuaObject.hpp
|
||||
// Copyright (c) 2007 - 2011 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2007 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef SWEET_LUA_LUAOBJECT_HPP_INCLUDED
|
||||
|
|
@ -52,34 +52,4 @@ class SWEET_LUA_DECLSPEC LuaObject
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
// Persist this LuaObject in an Archive.
|
||||
//
|
||||
// @param archive
|
||||
// The Archive to persist this LuaObject in.
|
||||
*/
|
||||
template <class Archive>
|
||||
void sweet::lua::LuaObject::persist( Archive& archive )
|
||||
{
|
||||
lua_ = reinterpret_cast<Lua*>( archive.get_context(SWEET_STATIC_TYPEID(Lua)) );
|
||||
SWEET_ASSERT( lua_ );
|
||||
|
||||
lua_State* lua_state = lua_->get_lua_state();
|
||||
SWEET_ASSERT( lua_state );
|
||||
|
||||
LuaStackGuard stack_guard( lua_state );
|
||||
|
||||
if ( archive.is_writing() )
|
||||
{
|
||||
lua_push_object( lua_state, this );
|
||||
}
|
||||
|
||||
sweet::persist::persist_lua_table( archive, "table", lua_state, false );
|
||||
|
||||
if ( archive.is_reading() )
|
||||
{
|
||||
lua_create_object_with_existing_table( lua_state, this );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// LuaObjectConverter.hpp
|
||||
// Copyright (c) 2009 - 2010 Charles Baker. All rights reserved.
|
||||
// Copyright (c) 2009 - 2012 Charles Baker. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef SWEET_LUA_LUAOBJECTCONVERTER_HPP_INCLUDED
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "LuaTraits.hpp"
|
||||
#include "lua_functions.hpp"
|
||||
#include <sweet/assert/assert.hpp>
|
||||
|
||||
namespace sweet
|
||||
{
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue