From 6fad26645869006e47b94da4c3f4285dfaaf023c Mon Sep 17 00:00:00 2001 From: starkos Date: Tue, 17 Jun 2008 18:45:11 +0000 Subject: Merged configuration check logic and global eol-settings (r405:413) --- CHANGES.txt | 490 +++++------ LICENSE.txt | 680 +++++++-------- README.txt | 62 +- premake.lua | 322 +++---- premake4.lua | 20 +- src/action/action.c | 230 ++--- src/action/action.h | 114 +-- src/action/make/gmake.c | 176 ++-- src/action/make/gmake_project.c | 98 +-- src/action/make/gmake_solution.c | 432 +++++----- src/action/make/make.c | 306 +++---- src/action/make/make.h | 32 +- src/action/make/make_project.c | 640 +++++++------- src/action/make/make_project.h | 70 +- src/action/make/make_solution.c | 68 +- src/action/make/make_solution.h | 40 +- src/action/make/tests/gmake_project_tests.cpp | 498 +++++------ src/action/make/tests/gmake_solution_tests.cpp | 242 +++--- .../make_solution_tests.cpp | 56 -- src/action/make/tests/make_tests.cpp | 196 ++--- src/action/tests/action_tests.h | 126 +-- src/action/vs200x/tests/vs2002_config_tests.cpp | 58 +- src/action/vs200x/tests/vs2002_project_tests.cpp | 176 ++-- src/action/vs200x/tests/vs2002_solution_tests.cpp | 216 ++--- src/action/vs200x/tests/vs2003_config_tests.cpp | 58 +- src/action/vs200x/tests/vs2003_project_tests.cpp | 180 ++-- src/action/vs200x/tests/vs2003_solution_tests.cpp | 90 +- src/action/vs200x/tests/vs2005_config_tests.cpp | 58 +- src/action/vs200x/tests/vs2005_project_tests.cpp | 190 ++--- src/action/vs200x/tests/vs2005_solution_tests.cpp | 160 ++-- src/action/vs200x/tests/vs2008_config_tests.cpp | 58 +- src/action/vs200x/tests/vs2008_project_tests.cpp | 190 ++--- src/action/vs200x/tests/vs2008_solution_tests.cpp | 60 +- src/action/vs200x/tests/vs200x_project_tests.cpp | 588 ++++++------- src/action/vs200x/tests/vs200x_tests.cpp | 98 +-- src/action/vs200x/tests/vs200x_xml_tests.cpp | 188 ++-- src/action/vs200x/vs2002.c | 170 ++-- src/action/vs200x/vs2002_solution.c | 338 ++++---- src/action/vs200x/vs2003.c | 168 ++-- src/action/vs200x/vs2003_solution.c | 110 +-- src/action/vs200x/vs2005.c | 184 ++-- src/action/vs200x/vs2005_solution.c | 220 ++--- src/action/vs200x/vs2008.c | 182 ++-- src/action/vs200x/vs2008_solution.c | 58 +- src/action/vs200x/vs200x.c | 326 +++---- src/action/vs200x/vs200x.h | 40 +- src/action/vs200x/vs200x_config.c | 96 +-- src/action/vs200x/vs200x_config.h | 32 +- src/action/vs200x/vs200x_project.c | 946 ++++++++++----------- src/action/vs200x/vs200x_project.h | 82 +- src/action/vs200x/vs200x_solution.c | 66 +- src/action/vs200x/vs200x_solution.h | 60 +- src/base/array.c | 222 ++--- src/base/array.h | 54 +- src/base/base.h | 24 +- src/base/buffers.c | 170 ++-- src/base/buffers.h | 50 +- src/base/cstr.c | 248 +++--- src/base/cstr.h | 48 +- src/base/dir.c | 212 ++--- src/base/dir.h | 44 +- src/base/error.c | 102 +-- src/base/error.h | 42 +- src/base/guid.c | 218 ++--- src/base/guid.h | 40 +- src/base/path.c | 708 +++++++-------- src/base/path.h | 58 +- src/base/stream.c | 578 ++++++------- src/base/stream.h | 74 +- src/base/string.c | 134 +-- src/base/string.h | 46 +- src/base/strings.c | 194 ++--- src/base/strings.h | 56 +- src/base/tests/base_tests.cpp | 46 +- src/base/tests/cstr_tests.cpp | 298 +++---- src/base/tests/dir_tests.cpp | 54 +- src/base/tests/guid_tests.cpp | 172 ++-- src/base/tests/path_tests.cpp | 532 ++++++------ src/base/tests/stream_tests.cpp | 214 ++--- src/base/tests/string_tests.cpp | 92 +- src/host/host.c | 344 ++++---- src/host/host.h | 86 +- src/host/tests/host_args_tests.cpp | 88 +- src/host/tests/host_help_tests.cpp | 154 ++-- src/host/tests/host_results_tests.cpp | 96 +-- src/host/tests/host_run_tests.cpp | 250 +++--- src/host/tests/host_tests.cpp | 52 +- src/platform/platform.c | 68 +- src/platform/platform.h | 242 +++--- src/platform/posix.c | 272 +++--- src/platform/windows.c | 210 ++--- src/premake.c | 116 +-- src/premake.h | 86 +- src/premake.lua | 202 ++--- src/project/fields.c | 332 ++++---- src/project/fields.h | 116 +-- src/project/project.c | 716 ++++++++-------- src/project/project.h | 128 +-- src/project/solution.c | 660 +++++++------- src/project/solution.h | 122 +-- src/project/tests/fields_tests.cpp | 128 +-- src/project/tests/project_tests.cpp | 468 +++++----- src/project/tests/solution_tests.cpp | 412 ++++----- src/script/fn_accessor.c | 455 +++++----- src/script/fn_configurations.c | 43 + src/script/fn_dofile.c | 152 ++-- src/script/fn_error.c | 42 +- src/script/fn_getcwd.c | 40 +- src/script/fn_include.c | 52 +- src/script/fn_project.c | 153 ++-- src/script/fn_solution.c | 124 +-- src/script/lua-5.1.2/PREMAKE_CHANGES.txt | 4 +- src/script/script.c | 529 ++++++------ src/script/script.h | 58 +- src/script/script_internal.c | 336 ++++---- src/script/script_internal.h | 148 ++-- src/script/tests/fn_accessor_tests.cpp | 226 ++--- src/script/tests/fn_configurations_tests.cpp | 20 +- src/script/tests/fn_dofile_tests.cpp | 146 ++-- src/script/tests/fn_error_tests.cpp | 50 +- src/script/tests/fn_files_tests.cpp | 70 +- src/script/tests/fn_getcwd_tests.cpp | 58 +- src/script/tests/fn_guid_tests.cpp | 90 +- src/script/tests/fn_include_tests.cpp | 72 +- src/script/tests/fn_language_tests.cpp | 84 +- src/script/tests/fn_project_tests.cpp | 243 +++--- src/script/tests/fn_solution_tests.cpp | 240 +++--- src/script/tests/script_tests.cpp | 104 +-- src/script/tests/script_tests.h | 79 +- src/script/tests/unload_project_tests.cpp | 171 ++-- src/script/tests/unload_solution_tests.cpp | 130 +-- src/script/tests/unload_tests.cpp | 349 ++++---- src/script/unload.c | 312 +++---- src/session/session.c | 726 ++++++++-------- src/session/session.h | 194 ++--- src/session/tests/session_tests.cpp | 794 ++++++++--------- src/testing/UnitTest++/PREMAKE_CHANGES.txt | 6 +- src/testing/test_files/_FILE.lua | 4 +- src/testing/test_files/dofile.lua | 4 +- src/testing/test_files/dofile_getcwd.lua | 8 +- src/testing/test_files/error.lua | 2 +- src/testing/test_files/getcwd.lua | 2 +- src/testing/test_files/nested/getcwd.lua | 2 +- src/testing/test_files/premake4.lua | 6 +- src/testing/test_files/true.lua | 4 +- src/testing/testing.cpp | 44 +- src/testing/testing.h | 18 +- 147 files changed, 13419 insertions(+), 13397 deletions(-) delete mode 100644 src/action/make/tests/make_solution_tests.cpp/make_solution_tests.cpp create mode 100644 src/script/fn_configurations.c diff --git a/CHANGES.txt b/CHANGES.txt index 4505c0e..e01b308 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,245 +1,245 @@ - 4.0 (in progress) --------------------- -This version is a complete rewrite of Premake. - -- New, more readable syntax for project information -- Better validation of command-line arguments -- Standardized path handling across all project settings -- Upgraded to Lua 5.1.2 - - 3.5 --------------------- -- Prevent creation of import libraries on OS X -- Improved handling of dylibs on OS X -- Patch 1771977: Ability to compile C source as C++ in Code::Blocks (Ryan Pusztai) -- Patch 1771168: luaL_getn speed optimization (Richard O'Grady) -- Bug 1804810: out-implib not present in linux gnu compler toolchain -- Bug 1806949: .Net reference paths are broken when bindir is specified -- Bug 1806960: Make clean does not remove .mdb files -- Bug 1831389: Makefiles stored in subdirs contain no targets on first run - - 3.4 --------------------- -- Added `no-pch` flag to suppress precompiled headers -- Added App.config support to GNU makefiles -- Add os.mkdir() to script environment -- Makefile now creates target directory before copying .NET references -- Feature 1520182: Enhanced file-handling functions -- Bug 531878: Problems with relative paths -- Bug 1723867: Config-specific post-build on GNU target (Benoit Miller) -- Bug 1596826: XML targets doesn't escape xml entities -- Bug 1600155: Core dump due to newpackage() and matchfiles() -- Bug 1608895: resgen command shown -- Bug 1639730: Output filename is not set -- Bug 1729227: non-portable executable with relative library path -- Bug 1559951: default clean rule removes package dir -- Patch 1733674: PCH support for Code::Block targets (Ryan Pusztai) -- Patch 1746563: Ability to specify GUID for VS targets (Ryan Pusztai) -- Patch 1754867: Creating import lib of different name (Ryan Pusztai) - - 3.3 --------------------- -- Added support for prebuild, prelink, and postbuild commands -- Added `target` global variable to script environment -- Added build flag `no-edit-and-continue` -- Added build flags `native-wchar` and `no-native-wchar` -- Added build flag `no-manifest` -- Added build flag `seh-exceptions` (VS2005 only) -- Added `resdefines`, `respaths`, and `resoptions` -- Added `prebuildcommands`, `prelinkcommands`, and `postbuildcommands` -- Added `pchheader` and `pchsource` (Visual Studio only) -- Feature 1337547: Package-level bindir and libdir -- Bug 1565755: Generated makefiles do not work with MSYS -- Bug 1587955: Target path ignored for libs -- Bug 1574725: Static library extension for "gnu" target -- Bug 1522861: Fixed by using "ar -rcs" instead of "ar -cr && ranlib" -- Bug 1656816: Mkdir set wrong directory rights -- Bug 1655595: Compile/build problem on FreeBSD -- Bug: "gnu" clean rule doesn't work in cmd.exe -- Improved behavior of Linux findlib() -- Updated Code::Blocks support to latest project version (major="1" minor="6") -- Patch 1681666: GNU targets always show the console if kind = 'winexe' - - 3.2 --------------------- -- Added support for Code::Blocks -- Updated MonoDevelop support -- Upgraded Lua to 5.0.3 -- Added new matchdirs() to Lua script environment -- Expose list of packages as _PACKAGES global in Lua -- Turn off edit-and-continue in release builds with symbols -- Bug 1559873: libpaths inserts extra space after -L - - 3.1 --------------------- -- Added support for Visual Studio 2005 -- Added support for Windows resources to GNU make target -- Added path handling functions to Lua environment -- Added matchrecursive() for recursive file searches -- Added os.fileexists() function to Lua environment -- Added os.appendfile() function to Lua environment -- Changed `monoresgen` to `resgen` to keep up with Mono project -- Added `mono2` .NET compiler set for Mono .NET 2.0 support -- Feature 1096677: exclude files from matchfiles (package.excludes) -- Bug 1439463: VS2003 RTTI problem -- Bug 1439446: GNU Makefile problem under Mingw32 -- Bug 1422068: package.path="." causes bad makefiles -- Bug 1431530: makefile target fails when project path specified - - 3.0 --------------------- -- Upgraded Lua interpreter to version 5.0.1 -- The options table now stores simple values, rather than tables -- Completed MonoDevelop support -- Improved .NET resource handling for GNU generator -- Added unit test suite -- Merged Scott Graham unicode build flag patch -- Removed package.warninglevel in favor of extra-warnings flag -- Added package.targetprefix -- Overhauled structure of generated GNU makefiles -- Added --os command line option -- Fixed bug 1268588: Use gcc to link C packages -- Fixed bug 1363306: GNU C# should copy referenced DLLs - - 2.4 --------------------- -- Added chdir() to Lua script environment -- Merged Thomas Harning's patch for .NET resources on GNU -- Fixed bug 1194702: Can't put multiple packages in same directory -- Fixed bug in GNU shared library builds (doh!) -- Added target 'vs2002' to replace 'vs7' - - 2.3 --------------------- -- Added 'project.config[]' with 'bindir' and 'libdir' -- Merged Scott Graham's "warninglevel" patch. -- Fixed bug 1153484: Import lib in wrong directory. -- Fixed bug 1013352: Stack overflow with large projects. -- Fixed bug 945406: package.files, bad value = crash - - 2.2 --------------------- -- Worked around VS.NET bug for .NET assemblies > 64K. -- Added --very-verbose flag to GNU generator. -- GNU generator now supports assembly sources. - - 2.1 --------------------- -- File extension of generated binaries can now be set - with config.targetextension. -- Windows targets now handle .def files for DLLs. - - 2.0 --------------------- -- Can now specify build actions per file -- Include paths are now passed to VC7 resource compiler -- Removed _WIN32 define from Cygwin makefiles -- Added package.objdir to set intermediates directory -- Added rmdir() to Lua script environment -- A big bag of bug fixes - - 1.9 --------------------- -- Made verbose mode even more verbose. -- posix.c now builds properly as C. -- Fixed package dependency generation for GNU and VS2003. -- Display Lua version number in usage text. -- Fixed VS link between *.aspx and *.aspx.cs files. -- Fixed VS link between *.resx and *.cs files. -- Fixed *.d file generation for gcc 2.9x. -- Unified various help options under '--help'. -- Bin and Lib paths can now be arbitrarily long. -- linkoptions are now applied in VC6 and VC7 projects. - - 1.8 --------------------- -- Added support for ASP.NET projects. -- Fixed a bug in VC6 support for static libraries. -- matchfiles() now uses package path instead of script path. -- Added --verbose option. -- No longer apply no-rtti and no-exceptions to *.c files. - - 1.7 --------------------- -- Location of generated project files can now be specified with - the project.path variable. -- Inter-package dependencies are fixed for GNU makefiles. -- No longer need to execute in same directory as project script. -- Added "c" language specifier. -- Added support for .resx and .config files to C# projects. -- Added support for full assembly names in .NET references. -- Fixed handling of paths in package.target variable. -- Improved support for SharpDevelop. -- Started support for OS X. -- Added support for Digital Mars compiler. - - 1.6 --------------------- -- VS7 generator crashed if a package was built before one of its - dependencies. Now immediately assigns UUID before processing. -- Added support for Visual Studio 2003 and SharpDevelop. -- Added binaries directory as a reference path for VS7. - - 1.5 --------------------- -- Added initial support for building static libraries. -- Added "no-main" flag, prevents overriding WinMain() on - Windows builds. -- Added "--no-rtti" and "no-exceptions" build flags to - disable those C++ features. -- Display error message when project has no packages. -- Moved VC7 *.pdb files into intermediates directory. - - 1.4 --------------------- -- Bug fixes to the path manipulation routines. -- GNU makefiles are regenerated when premake scripts change. - - 1.3 --------------------- -- Added support for the Cygwin environment. -- Added "static-runtime" build flag to statically link against C/C++ - standard runtime libraries. -- Bug fixes to Visual Studio 6 and 7 generators and path reversing - algorithm. - - 1.2 --------------------- -- Standardized format of command-line options. -- Can now handle custom command-line options in script. -- Added new function findlib(). -- Added new C++ build flag "managed" for writing C++ .NET code. -- Can now use open-source C# compilers in VS6 generator. -- Several bug fixes to the VS7 generator. - - 1.1 --------------------- -- Added support for custom build configurations. Added "optimize", - "optimize-size", "optimize-speed", and "no-symbols" flags to control - build settings. -- Added matchfiles() to select files using wildcards. -- Added "unsafe" flag for C# projects. -- Added newpackage() function for creating new package objects inline, - instead of creating separate scripts. -- Changed include() to dopackage() and option() to addoption(). The old - versions have been kept for compatibility, but will be deprecated - eventually. -- Major cleanup of the source code. - - 1.0 --------------------- -- Fixed a bug related to the reference paths in VS7 C# projects. -- Display a warning message if a reference path can't be found. -- Automatically create bin and lib directories if they do not exist. -- GNU C# projects will now properly use the configured library paths. -- Added --with-mono and --with-pnet options. -- VS7 C# projects will now properly use the configured library paths. -- Switched to Lua (http://www.lua.org/) for project script parsing. -- Add support for custom project options. -- Changed 'type' to 'kind' to avoid conflict with Lua function of the same name. -- Changed 'conexe' to 'exe' because I liked it better. -- Changed 'library' to 'dll' for C# projects to keep things consistent. - - 0.9 --------------------- -- Initial public release. + 4.0 (in progress) +-------------------- +This version is a complete rewrite of Premake. + +- New, more readable syntax for project information +- Better validation of command-line arguments +- Standardized path handling across all project settings +- Upgraded to Lua 5.1.2 + + 3.5 +-------------------- +- Prevent creation of import libraries on OS X +- Improved handling of dylibs on OS X +- Patch 1771977: Ability to compile C source as C++ in Code::Blocks (Ryan Pusztai) +- Patch 1771168: luaL_getn speed optimization (Richard O'Grady) +- Bug 1804810: out-implib not present in linux gnu compler toolchain +- Bug 1806949: .Net reference paths are broken when bindir is specified +- Bug 1806960: Make clean does not remove .mdb files +- Bug 1831389: Makefiles stored in subdirs contain no targets on first run + + 3.4 +-------------------- +- Added `no-pch` flag to suppress precompiled headers +- Added App.config support to GNU makefiles +- Add os.mkdir() to script environment +- Makefile now creates target directory before copying .NET references +- Feature 1520182: Enhanced file-handling functions +- Bug 531878: Problems with relative paths +- Bug 1723867: Config-specific post-build on GNU target (Benoit Miller) +- Bug 1596826: XML targets doesn't escape xml entities +- Bug 1600155: Core dump due to newpackage() and matchfiles() +- Bug 1608895: resgen command shown +- Bug 1639730: Output filename is not set +- Bug 1729227: non-portable executable with relative library path +- Bug 1559951: default clean rule removes package dir +- Patch 1733674: PCH support for Code::Block targets (Ryan Pusztai) +- Patch 1746563: Ability to specify GUID for VS targets (Ryan Pusztai) +- Patch 1754867: Creating import lib of different name (Ryan Pusztai) + + 3.3 +-------------------- +- Added support for prebuild, prelink, and postbuild commands +- Added `target` global variable to script environment +- Added build flag `no-edit-and-continue` +- Added build flags `native-wchar` and `no-native-wchar` +- Added build flag `no-manifest` +- Added build flag `seh-exceptions` (VS2005 only) +- Added `resdefines`, `respaths`, and `resoptions` +- Added `prebuildcommands`, `prelinkcommands`, and `postbuildcommands` +- Added `pchheader` and `pchsource` (Visual Studio only) +- Feature 1337547: Package-level bindir and libdir +- Bug 1565755: Generated makefiles do not work with MSYS +- Bug 1587955: Target path ignored for libs +- Bug 1574725: Static library extension for "gnu" target +- Bug 1522861: Fixed by using "ar -rcs" instead of "ar -cr && ranlib" +- Bug 1656816: Mkdir set wrong directory rights +- Bug 1655595: Compile/build problem on FreeBSD +- Bug: "gnu" clean rule doesn't work in cmd.exe +- Improved behavior of Linux findlib() +- Updated Code::Blocks support to latest project version (major="1" minor="6") +- Patch 1681666: GNU targets always show the console if kind = 'winexe' + + 3.2 +-------------------- +- Added support for Code::Blocks +- Updated MonoDevelop support +- Upgraded Lua to 5.0.3 +- Added new matchdirs() to Lua script environment +- Expose list of packages as _PACKAGES global in Lua +- Turn off edit-and-continue in release builds with symbols +- Bug 1559873: libpaths inserts extra space after -L + + 3.1 +-------------------- +- Added support for Visual Studio 2005 +- Added support for Windows resources to GNU make target +- Added path handling functions to Lua environment +- Added matchrecursive() for recursive file searches +- Added os.fileexists() function to Lua environment +- Added os.appendfile() function to Lua environment +- Changed `monoresgen` to `resgen` to keep up with Mono project +- Added `mono2` .NET compiler set for Mono .NET 2.0 support +- Feature 1096677: exclude files from matchfiles (package.excludes) +- Bug 1439463: VS2003 RTTI problem +- Bug 1439446: GNU Makefile problem under Mingw32 +- Bug 1422068: package.path="." causes bad makefiles +- Bug 1431530: makefile target fails when project path specified + + 3.0 +-------------------- +- Upgraded Lua interpreter to version 5.0.1 +- The options table now stores simple values, rather than tables +- Completed MonoDevelop support +- Improved .NET resource handling for GNU generator +- Added unit test suite +- Merged Scott Graham unicode build flag patch +- Removed package.warninglevel in favor of extra-warnings flag +- Added package.targetprefix +- Overhauled structure of generated GNU makefiles +- Added --os command line option +- Fixed bug 1268588: Use gcc to link C packages +- Fixed bug 1363306: GNU C# should copy referenced DLLs + + 2.4 +-------------------- +- Added chdir() to Lua script environment +- Merged Thomas Harning's patch for .NET resources on GNU +- Fixed bug 1194702: Can't put multiple packages in same directory +- Fixed bug in GNU shared library builds (doh!) +- Added target 'vs2002' to replace 'vs7' + + 2.3 +-------------------- +- Added 'project.config[]' with 'bindir' and 'libdir' +- Merged Scott Graham's "warninglevel" patch. +- Fixed bug 1153484: Import lib in wrong directory. +- Fixed bug 1013352: Stack overflow with large projects. +- Fixed bug 945406: package.files, bad value = crash + + 2.2 +-------------------- +- Worked around VS.NET bug for .NET assemblies > 64K. +- Added --very-verbose flag to GNU generator. +- GNU generator now supports assembly sources. + + 2.1 +-------------------- +- File extension of generated binaries can now be set + with config.targetextension. +- Windows targets now handle .def files for DLLs. + + 2.0 +-------------------- +- Can now specify build actions per file +- Include paths are now passed to VC7 resource compiler +- Removed _WIN32 define from Cygwin makefiles +- Added package.objdir to set intermediates directory +- Added rmdir() to Lua script environment +- A big bag of bug fixes + + 1.9 +-------------------- +- Made verbose mode even more verbose. +- posix.c now builds properly as C. +- Fixed package dependency generation for GNU and VS2003. +- Display Lua version number in usage text. +- Fixed VS link between *.aspx and *.aspx.cs files. +- Fixed VS link between *.resx and *.cs files. +- Fixed *.d file generation for gcc 2.9x. +- Unified various help options under '--help'. +- Bin and Lib paths can now be arbitrarily long. +- linkoptions are now applied in VC6 and VC7 projects. + + 1.8 +-------------------- +- Added support for ASP.NET projects. +- Fixed a bug in VC6 support for static libraries. +- matchfiles() now uses package path instead of script path. +- Added --verbose option. +- No longer apply no-rtti and no-exceptions to *.c files. + + 1.7 +-------------------- +- Location of generated project files can now be specified with + the project.path variable. +- Inter-package dependencies are fixed for GNU makefiles. +- No longer need to execute in same directory as project script. +- Added "c" language specifier. +- Added support for .resx and .config files to C# projects. +- Added support for full assembly names in .NET references. +- Fixed handling of paths in package.target variable. +- Improved support for SharpDevelop. +- Started support for OS X. +- Added support for Digital Mars compiler. + + 1.6 +-------------------- +- VS7 generator crashed if a package was built before one of its + dependencies. Now immediately assigns UUID before processing. +- Added support for Visual Studio 2003 and SharpDevelop. +- Added binaries directory as a reference path for VS7. + + 1.5 +-------------------- +- Added initial support for building static libraries. +- Added "no-main" flag, prevents overriding WinMain() on + Windows builds. +- Added "--no-rtti" and "no-exceptions" build flags to + disable those C++ features. +- Display error message when project has no packages. +- Moved VC7 *.pdb files into intermediates directory. + + 1.4 +-------------------- +- Bug fixes to the path manipulation routines. +- GNU makefiles are regenerated when premake scripts change. + + 1.3 +-------------------- +- Added support for the Cygwin environment. +- Added "static-runtime" build flag to statically link against C/C++ + standard runtime libraries. +- Bug fixes to Visual Studio 6 and 7 generators and path reversing + algorithm. + + 1.2 +-------------------- +- Standardized format of command-line options. +- Can now handle custom command-line options in script. +- Added new function findlib(). +- Added new C++ build flag "managed" for writing C++ .NET code. +- Can now use open-source C# compilers in VS6 generator. +- Several bug fixes to the VS7 generator. + + 1.1 +-------------------- +- Added support for custom build configurations. Added "optimize", + "optimize-size", "optimize-speed", and "no-symbols" flags to control + build settings. +- Added matchfiles() to select files using wildcards. +- Added "unsafe" flag for C# projects. +- Added newpackage() function for creating new package objects inline, + instead of creating separate scripts. +- Changed include() to dopackage() and option() to addoption(). The old + versions have been kept for compatibility, but will be deprecated + eventually. +- Major cleanup of the source code. + + 1.0 +-------------------- +- Fixed a bug related to the reference paths in VS7 C# projects. +- Display a warning message if a reference path can't be found. +- Automatically create bin and lib directories if they do not exist. +- GNU C# projects will now properly use the configured library paths. +- Added --with-mono and --with-pnet options. +- VS7 C# projects will now properly use the configured library paths. +- Switched to Lua (http://www.lua.org/) for project script parsing. +- Add support for custom project options. +- Changed 'type' to 'kind' to avoid conflict with Lua function of the same name. +- Changed 'conexe' to 'exe' because I liked it better. +- Changed 'library' to 'dll' for C# projects to keep things consistent. + + 0.9 +-------------------- +- Initial public release. diff --git a/LICENSE.txt b/LICENSE.txt index 45645b4..5b6e7c6 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,340 +1,340 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/README.txt b/README.txt index 50e4ca4..3130143 100644 --- a/README.txt +++ b/README.txt @@ -1,31 +1,31 @@ -PREMAKE -A build configuration tool - - Copyright (C) 2002-2008 by Jason Perkins - Distributed under the GNU General Public License, see LICENSE.txt - - The Lua language and runtime library is (C) TeCGraf, PUC-Rio. - See their website at http://www.lua.org/ - - -BUILDING PREMAKE - - Until an official release is made you will need to use an existing - Premake 3.x executable to generate the project files. Grab a binary - or source package from the project site at: - - http://premake.sourceforge.net/ - - Then use it to create the project files for your particular toolset. - - $ cd premake-4.0 - $ premake --target vs2005 # For Visual Studio 2005 files - $ premake --target gnu # For GNU makefile - - Run `premake --help` for a complete list of supported toolsets. - - -SUPPORT - - For questions, comments, or more information, visit the project - website at http://industriousone.com/premake +PREMAKE +A build configuration tool + + Copyright (C) 2002-2008 by Jason Perkins + Distributed under the GNU General Public License, see LICENSE.txt + + The Lua language and runtime library is (C) TeCGraf, PUC-Rio. + See their website at http://www.lua.org/ + + +BUILDING PREMAKE + + Until an official release is made you will need to use an existing + Premake 3.x executable to generate the project files. Grab a binary + or source package from the project site at: + + http://premake.sourceforge.net/ + + Then use it to create the project files for your particular toolset. + + $ cd premake-4.0 + $ premake --target vs2005 # For Visual Studio 2005 files + $ premake --target gnu # For GNU makefile + + Run `premake --help` for a complete list of supported toolsets. + + +SUPPORT + + For questions, comments, or more information, visit the project + website at http://industriousone.com/premake diff --git a/premake.lua b/premake.lua index 9074afd..afc12bc 100644 --- a/premake.lua +++ b/premake.lua @@ -1,161 +1,161 @@ -project.name = "Premake4" - --- Project options - - addoption("no-tests", "Build without automated tests") - - --- Output directories - - project.config["Debug"].bindir = "bin/debug" - project.config["Release"].bindir = "bin/release" - - --- Packages - - dopackage("src") - - --- Cleanup code - - function doclean(cmd, arg) - docommand(cmd, arg) - os.rmdir("bin") - os.rmdir("doc") - end - - --- Release code - - REPOS = "https://premake.svn.sourceforge.net/svnroot/premake" - TRUNK = "/trunk" - BRANCHES = "/branches/4.0-alpha/" - - function dorelease(cmd, arg) - - if (not arg) then - error "You must specify a version" - end - - ------------------------------------------------------------------- - -- Make sure everything is good before I start - ------------------------------------------------------------------- - print("") - print("PRE-FLIGHT CHECKLIST") - print(" * is README up-to-date?") - print(" * is CHANGELOG up-to-date?") - print(" * did you test build with GCC?") - print(" * did you test build with Doxygen?") - print(" * are 'svn' (all) and '7z' (Windows) available?") - print("") - print("Press [Enter] to continue or [^C] to quit.") - io.stdin:read("*l") - - ------------------------------------------------------------------- - -- Set up environment - ------------------------------------------------------------------- - local version = arg - - os.mkdir("releases") - - local folder = "premake-"..version - local trunk = REPOS..TRUNK - local branch = REPOS..BRANCHES..version - - ------------------------------------------------------------------- - -- Build and run all automated tests on working copy - ------------------------------------------------------------------- - print("Building tests on working copy...") - os.execute("premake --target gnu >releases/release.log") - result = os.execute("make CONFIG=Release >releases/release.log") - if (result ~= 0) then - error("Test build failed; see release.log for details") - end - - ------------------------------------------------------------------- - -- Look for a release branch in SVN, and create one from trunk if necessary - ------------------------------------------------------------------- - print("Checking for release branch...") - os.chdir("releases") - result = os.execute(string.format("svn ls %s >release.log 2>&1", branch)) - if (result ~= 0) then - print("Creating release branch...") - result = os.execute(string.format('svn copy %s %s -m "Creating release branch for %s" >release.log', trunk, branch, version)) - if (result ~= 0) then - error("Failed to create release branch at "..branch) - end - end - - ------------------------------------------------------------------- - -- Checkout a local copy of the release branch - ------------------------------------------------------------------- - print("Getting source code from release branch...") - os.execute(string.format("svn co %s %s >release.log", branch, folder)) - if (not os.fileexists(folder.."/README.txt")) then - error("Unable to checkout from repository at "..branch) - end - - ------------------------------------------------------------------- - -- Embed version numbers into the files - ------------------------------------------------------------------- - -- (embed version #s) - -- (check into branch) - - ------------------------------------------------------------------- - -- Build the release binary for this platform - ------------------------------------------------------------------- - print("Building release version...") - os.chdir(folder) - os.execute("premake --clean --no-tests --target gnu >../release.log") - - if (windows) then - os.execute("make CONFIG=Release >../release.log") - os.chdir("bin/release") - result = os.execute(string.format("7z a -tzip ..\\..\\..\\premake-win32-%s.zip premake4.exe >../release.log", version)) - elseif (macosx) then - os.execute('TARGET_ARCH="-arch i386 -arch ppc" make CONFIG=Release >../release.log') - os.chdir("bin/release") - result = os.execute(string.format("tar czvf ../../../premake-macosx-%s.tar.gz premake4 >../release.log", version)) - else - os.execute("make CONFIG=Release >../release.log") - os.chdir("bin/release") - result = os.execute(string.format("tar czvf ../../../premake-linux-%s.tar.gz bin/release/premake4 >../release.log", version)) - end - - if (result ~= 0) then - error("Failed to build binary package; see release.log for details") - end - - os.chdir("../../..") - - ------------------------------------------------------------------- - -- Build the source code package (MacOSX only) - ------------------------------------------------------------------- - if (macosx) then - result = os.execute(string.format("zip -r9 premake-src-%s.zip %s/* >release.log", version, folder)) - if (result ~= 0) then - error("Failed to build source code package; see release.log for details") - end - end - - ------------------------------------------------------------------- - -- Clean up - ------------------------------------------------------------------- - print("Cleaning up...") - os.rmdir(folder) - os.remove("release.log") - - - ------------------------------------------------------------------- - -- Next steps - ------------------------------------------------------------------- - if (windows) then - print("DONE - now run release script under Linux") - elseif (linux) then - print("DONE - now run release script under Mac OS X") - else - print("DONE - really this time") - end - - end - +project.name = "Premake4" + +-- Project options + + addoption("no-tests", "Build without automated tests") + + +-- Output directories + + project.config["Debug"].bindir = "bin/debug" + project.config["Release"].bindir = "bin/release" + + +-- Packages + + dopackage("src") + + +-- Cleanup code + + function doclean(cmd, arg) + docommand(cmd, arg) + os.rmdir("bin") + os.rmdir("doc") + end + + +-- Release code + + REPOS = "https://premake.svn.sourceforge.net/svnroot/premake" + TRUNK = "/trunk" + BRANCHES = "/branches/4.0-alpha/" + + function dorelease(cmd, arg) + + if (not arg) then + error "You must specify a version" + end + + ------------------------------------------------------------------- + -- Make sure everything is good before I start + ------------------------------------------------------------------- + print("") + print("PRE-FLIGHT CHECKLIST") + print(" * is README up-to-date?") + print(" * is CHANGELOG up-to-date?") + print(" * did you test build with GCC?") + print(" * did you test build with Doxygen?") + print(" * are 'svn' (all) and '7z' (Windows) available?") + print("") + print("Press [Enter] to continue or [^C] to quit.") + io.stdin:read("*l") + + ------------------------------------------------------------------- + -- Set up environment + ------------------------------------------------------------------- + local version = arg + + os.mkdir("releases") + + local folder = "premake-"..version + local trunk = REPOS..TRUNK + local branch = REPOS..BRANCHES..version + + ------------------------------------------------------------------- + -- Build and run all automated tests on working copy + ------------------------------------------------------------------- + print("Building tests on working copy...") + os.execute("premake --target gnu >releases/release.log") + result = os.execute("make CONFIG=Release >releases/release.log") + if (result ~= 0) then + error("Test build failed; see release.log for details") + end + + ------------------------------------------------------------------- + -- Look for a release branch in SVN, and create one from trunk if necessary + ------------------------------------------------------------------- + print("Checking for release branch...") + os.chdir("releases") + result = os.execute(string.format("svn ls %s >release.log 2>&1", branch)) + if (result ~= 0) then + print("Creating release branch...") + result = os.execute(string.format('svn copy %s %s -m "Creating release branch for %s" >release.log', trunk, branch, version)) + if (result ~= 0) then + error("Failed to create release branch at "..branch) + end + end + + ------------------------------------------------------------------- + -- Checkout a local copy of the release branch + ------------------------------------------------------------------- + print("Getting source code from release branch...") + os.execute(string.format("svn co %s %s >release.log", branch, folder)) + if (not os.fileexists(folder.."/README.txt")) then + error("Unable to checkout from repository at "..branch) + end + + ------------------------------------------------------------------- + -- Embed version numbers into the files + ------------------------------------------------------------------- + -- (embed version #s) + -- (check into branch) + + ------------------------------------------------------------------- + -- Build the release binary for this platform + ------------------------------------------------------------------- + print("Building release version...") + os.chdir(folder) + os.execute("premake --clean --no-tests --target gnu >../release.log") + + if (windows) then + os.execute("make CONFIG=Release >../release.log") + os.chdir("bin/release") + result = os.execute(string.format("7z a -tzip ..\\..\\..\\premake-win32-%s.zip premake4.exe >../release.log", version)) + elseif (macosx) then + os.execute('TARGET_ARCH="-arch i386 -arch ppc" make CONFIG=Release >../release.log') + os.chdir("bin/release") + result = os.execute(string.format("tar czvf ../../../premake-macosx-%s.tar.gz premake4 >../release.log", version)) + else + os.execute("make CONFIG=Release >../release.log") + os.chdir("bin/release") + result = os.execute(string.format("tar czvf ../../../premake-linux-%s.tar.gz bin/release/premake4 >../release.log", version)) + end + + if (result ~= 0) then + error("Failed to build binary package; see release.log for details") + end + + os.chdir("../../..") + + ------------------------------------------------------------------- + -- Build the source code package (MacOSX only) + ------------------------------------------------------------------- + if (macosx) then + result = os.execute(string.format("zip -r9 premake-src-%s.zip %s/* >release.log", version, folder)) + if (result ~= 0) then + error("Failed to build source code package; see release.log for details") + end + end + + ------------------------------------------------------------------- + -- Clean up + ------------------------------------------------------------------- + print("Cleaning up...") + os.rmdir(folder) + os.remove("release.log") + + + ------------------------------------------------------------------- + -- Next steps + ------------------------------------------------------------------- + if (windows) then + print("DONE - now run release script under Linux") + elseif (linux) then + print("DONE - now run release script under Mac OS X") + else + print("DONE - really this time") + end + + end + diff --git a/premake4.lua b/premake4.lua index 8a975d8..e300f47 100644 --- a/premake4.lua +++ b/premake4.lua @@ -1,10 +1,10 @@ ---------------------------------------------------------------------------- --- Premake4 solution script for Premake4 --- Copyright (c) 2002-2008 Jason Perkins and the Premake project ---------------------------------------------------------------------------- - -solution "Premake4" - - - - +--------------------------------------------------------------------------- +-- Premake4 solution script for Premake4 +-- Copyright (c) 2002-2008 Jason Perkins and the Premake project +--------------------------------------------------------------------------- + +solution "Premake4" + + + + diff --git a/src/action/action.c b/src/action/action.c index f8bdacf..9a10740 100644 --- a/src/action/action.c +++ b/src/action/action.c @@ -1,115 +1,115 @@ -/** - * \file action.c - * \brief Built-in engine actions. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include -#include "premake.h" -#include "action/action.h" -#include "base/buffers.h" -#include "base/cstr.h" - -SessionAction Actions[] = -{ - { "gmake", "GNU Makefiles for POSIX, MinGW, and Cygwin", gmake_action }, - { "vs2002", "Microsoft Visual Studio 2002", vs2002_action }, - { "vs2003", "Microsoft Visual Studio 2003", vs2003_action }, - { "vs2005", "Microsoft Visual Studio 2005 (includes Express editions)", vs2005_action }, - { "vs2008", "Microsoft Visual Studio 2008 (includes Express editions)", vs2008_action }, - { 0, 0, 0 } -}; - -static int action_source_tree_do(Session sess, Project prj, Stream strm, ActionSourceCallback handler, const char* group); - - -/** - * Walk a list of source files and pass them off, in nesting order, to - * the specified callback. Handles the grouping of related files info - * groups (by directory currently). - * \param sess The current execution session context. - * \param prj The project containing the files to enumerate. - * \param strm The active output stream. - * \param handler The per-file handler function. - * \returns OKAY on success. - */ -int action_source_tree(Session sess, Project prj, Stream strm, ActionSourceCallback handler) -{ - return action_source_tree_do(sess, prj, strm, handler, ""); -} - - -static int action_source_tree_do(Session sess, Project prj, Stream strm, ActionSourceCallback handler, const char* group) -{ - int i, n, group_len; - Strings files; - char* buffer = buffers_next(); - - /* open an enclosing group */ - group_len = strlen(group); - strcpy(buffer, group); - if (cstr_ends_with(buffer, "/")) /* Trim off trailing path separator */ - { - buffer[strlen(buffer)-1] = '\0'; - } - handler(sess, prj, strm, buffer, GroupStart); - - /* scan all files in this group and process any subdirectories (subgroups) */ - files = project_get_files(prj); - n = strings_size(files); - for (i = 0; i < n; ++i) - { - const char* filename = strings_item(files, i); - - /* is this file in the group that I am currently processing? */ - if (cstr_starts_with(filename, group)) - { - /* see if this file contains an additional directory level (a new group) */ - const char* ptr = strchr(filename + group_len, '/'); - if (ptr) - { - int j; - - /* pull out the name of this new group */ - size_t len = ptr - filename + 1; - strncpy(buffer, filename, len); - buffer[len] = '\0'; - - /* have I processed this subdirectory already? See if it appears earlier in the list */ - for (j = 0; j < i; ++j) - { - if (cstr_starts_with(strings_item(files, j), buffer)) - break; - } - - if (i == j) - { - /* a new group, process it now */ - if (action_source_tree_do(sess, prj, strm, handler, buffer) != OKAY) - return !OKAY; - } - } - } - } - - /* now process all files that belong to this current group (and not a subgroup) */ - for (i = 0; i < n; ++i) - { - const char* filename = strings_item(files, i); - if (!strchr(filename + group_len, '/')) - { - if (handler(sess, prj, strm, filename, SourceFile) != OKAY) - return !OKAY; - } - } - - /* close the group */ - strcpy(buffer, group); - if (cstr_ends_with(buffer, "/")) /* Trim off trailing path separator */ - { - buffer[strlen(buffer)-1] = '\0'; - } - handler(sess, prj, strm, buffer, GroupEnd); - return OKAY; -} - +/** + * \file action.c + * \brief Built-in engine actions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include +#include "premake.h" +#include "action/action.h" +#include "base/buffers.h" +#include "base/cstr.h" + +SessionAction Actions[] = +{ + { "gmake", "GNU Makefiles for POSIX, MinGW, and Cygwin", gmake_action }, + { "vs2002", "Microsoft Visual Studio 2002", vs2002_action }, + { "vs2003", "Microsoft Visual Studio 2003", vs2003_action }, + { "vs2005", "Microsoft Visual Studio 2005 (includes Express editions)", vs2005_action }, + { "vs2008", "Microsoft Visual Studio 2008 (includes Express editions)", vs2008_action }, + { 0, 0, 0 } +}; + +static int action_source_tree_do(Session sess, Project prj, Stream strm, ActionSourceCallback handler, const char* group); + + +/** + * Walk a list of source files and pass them off, in nesting order, to + * the specified callback. Handles the grouping of related files info + * groups (by directory currently). + * \param sess The current execution session context. + * \param prj The project containing the files to enumerate. + * \param strm The active output stream. + * \param handler The per-file handler function. + * \returns OKAY on success. + */ +int action_source_tree(Session sess, Project prj, Stream strm, ActionSourceCallback handler) +{ + return action_source_tree_do(sess, prj, strm, handler, ""); +} + + +static int action_source_tree_do(Session sess, Project prj, Stream strm, ActionSourceCallback handler, const char* group) +{ + int i, n, group_len; + Strings files; + char* buffer = buffers_next(); + + /* open an enclosing group */ + group_len = strlen(group); + strcpy(buffer, group); + if (cstr_ends_with(buffer, "/")) /* Trim off trailing path separator */ + { + buffer[strlen(buffer)-1] = '\0'; + } + handler(sess, prj, strm, buffer, GroupStart); + + /* scan all files in this group and process any subdirectories (subgroups) */ + files = project_get_files(prj); + n = strings_size(files); + for (i = 0; i < n; ++i) + { + const char* filename = strings_item(files, i); + + /* is this file in the group that I am currently processing? */ + if (cstr_starts_with(filename, group)) + { + /* see if this file contains an additional directory level (a new group) */ + const char* ptr = strchr(filename + group_len, '/'); + if (ptr) + { + int j; + + /* pull out the name of this new group */ + size_t len = ptr - filename + 1; + strncpy(buffer, filename, len); + buffer[len] = '\0'; + + /* have I processed this subdirectory already? See if it appears earlier in the list */ + for (j = 0; j < i; ++j) + { + if (cstr_starts_with(strings_item(files, j), buffer)) + break; + } + + if (i == j) + { + /* a new group, process it now */ + if (action_source_tree_do(sess, prj, strm, handler, buffer) != OKAY) + return !OKAY; + } + } + } + } + + /* now process all files that belong to this current group (and not a subgroup) */ + for (i = 0; i < n; ++i) + { + const char* filename = strings_item(files, i); + if (!strchr(filename + group_len, '/')) + { + if (handler(sess, prj, strm, filename, SourceFile) != OKAY) + return !OKAY; + } + } + + /* close the group */ + strcpy(buffer, group); + if (cstr_ends_with(buffer, "/")) /* Trim off trailing path separator */ + { + buffer[strlen(buffer)-1] = '\0'; + } + handler(sess, prj, strm, buffer, GroupEnd); + return OKAY; +} + diff --git a/src/action/action.h b/src/action/action.h index 097546d..0f0e190 100644 --- a/src/action/action.h +++ b/src/action/action.h @@ -1,57 +1,57 @@ -/** - * \file action.h - * \brief Built-in engine actions. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - * - * \defgroup action Actions - * - * The actions component contains the implementation of all of the built-in - * Premake actions, along with a few common support functions. - * - * @{ - */ -#if !defined(PREMAKE_ACTION_H) -#define PREMAKE_ACTION_H - -#include "session/session.h" - - -/** - * State values for the source tree enumeration functions. - */ -enum ActionSourceState -{ - GroupStart, - GroupEnd, - SourceFile -}; - - -/** - * Per-file callback signature for action_source_tree. - * \param sess The current execution state context. - * \param prj The current project; contains the file being enumerated. - * \param strm The active output stream; for writing the file markup. - * \param filename The name of the file to process. - * \param state One of the ActionSourceStates, enabling file grouping. - * \returns OKAY if successful. - */ -typedef int (*ActionSourceCallback)(Session sess, Project prj, Stream strm, const char* filename, int state); - - -/* the list of built-in Premake actions */ -extern SessionAction Actions[]; - -int gmake_action(Session sess); -int vs2002_action(Session sess); -int vs2003_action(Session sess); -int vs2005_action(Session sess); -int vs2008_action(Session sess); - - -/* support functions */ -int action_source_tree(Session sess, Project prj, Stream strm, ActionSourceCallback handler); - - -#endif -/** @} */ +/** + * \file action.h + * \brief Built-in engine actions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + * + * \defgroup action Actions + * + * The actions component contains the implementation of all of the built-in + * Premake actions, along with a few common support functions. + * + * @{ + */ +#if !defined(PREMAKE_ACTION_H) +#define PREMAKE_ACTION_H + +#include "session/session.h" + + +/** + * State values for the source tree enumeration functions. + */ +enum ActionSourceState +{ + GroupStart, + GroupEnd, + SourceFile +}; + + +/** + * Per-file callback signature for action_source_tree. + * \param sess The current execution state context. + * \param prj The current project; contains the file being enumerated. + * \param strm The active output stream; for writing the file markup. + * \param filename The name of the file to process. + * \param state One of the ActionSourceStates, enabling file grouping. + * \returns OKAY if successful. + */ +typedef int (*ActionSourceCallback)(Session sess, Project prj, Stream strm, const char* filename, int state); + + +/* the list of built-in Premake actions */ +extern SessionAction Actions[]; + +int gmake_action(Session sess); +int vs2002_action(Session sess); +int vs2003_action(Session sess); +int vs2005_action(Session sess); +int vs2008_action(Session sess); + + +/* support functions */ +int action_source_tree(Session sess, Project prj, Stream strm, ActionSourceCallback handler); + + +#endif +/** @} */ diff --git a/src/action/make/gmake.c b/src/action/make/gmake.c index 46ecead..e6c4721 100644 --- a/src/action/make/gmake.c +++ b/src/action/make/gmake.c @@ -1,88 +1,88 @@ -/** - * \file gmake.c - * \brief GNU makefile generation action. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include -#include "premake.h" -#include "action/action.h" -#include "make.h" -#include "make_solution.h" -#include "make_project.h" - - -/** The project features supported by this action */ -static SessionFeatures Features = -{ - { "c", "c++", NULL }, -}; - - -/** The GNU make solution writing process, for session_enumerate_objects() */ -static SessionSolutionCallback SolutionCallbacks[] = -{ - make_solution_create, - gmake_solution_signature, - gmake_solution_default_config, - gmake_solution_phony_rule, - gmake_solution_all_rule, - gmake_solution_projects, - gmake_solution_clean_rule, - NULL -}; - -/** The GNU make project writing process, for session_enumerate_objects() */ -static SessionProjectCallback ProjectCallbacks[] = -{ - make_project_create, - make_project_signature, - session_enumerate_configurations, - make_project_objects, - make_project_resources, - gmake_project_shell_detect, - make_project_phony_rule, - make_project_target, - make_project_mkdir_rules, - make_project_clean_rules, - make_project_source_rules, - make_project_include_dependencies, - NULL -}; - - -/** The GNU make configuration writing process, for session_enumerate_configurations() */ -static SessionProjectCallback ConfigCallbacks[] = -{ - make_project_config_conditional, - make_project_config_outdir, - make_project_config_outfile, - make_project_config_objdir, - make_project_config_cppflags, - make_project_config_cflags, - make_project_config_cxxflags, - make_project_config_ldflags, - make_project_config_lddeps, - make_project_config_resflags, - make_project_config_end, - NULL -}; - - -/** - * The GNU make action handler. - * \param sess The active session object. - * \returns OKAY if successful. - */ -int gmake_action(Session sess) -{ - /* make sure I can support all of the features used in the session */ - if (session_validate(sess, &Features) != OKAY) - { - return !OKAY; - } - - stream_writeline(Console, "Generating project files for GNU make..."); - return session_enumerate_objects(sess, SolutionCallbacks, ProjectCallbacks, ConfigCallbacks); -} - +/** + * \file gmake.c + * \brief GNU makefile generation action. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include +#include "premake.h" +#include "action/action.h" +#include "make.h" +#include "make_solution.h" +#include "make_project.h" + + +/** The project features supported by this action */ +static SessionFeatures Features = +{ + { "c", "c++", NULL }, +}; + + +/** The GNU make solution writing process, for session_enumerate_objects() */ +static SessionSolutionCallback SolutionCallbacks[] = +{ + make_solution_create, + gmake_solution_signature, + gmake_solution_default_config, + gmake_solution_phony_rule, + gmake_solution_all_rule, + gmake_solution_projects, + gmake_solution_clean_rule, + NULL +}; + +/** The GNU make project writing process, for session_enumerate_objects() */ +static SessionProjectCallback ProjectCallbacks[] = +{ + make_project_create, + make_project_signature, + session_enumerate_configurations, + make_project_objects, + make_project_resources, + gmake_project_shell_detect, + make_project_phony_rule, + make_project_target, + make_project_mkdir_rules, + make_project_clean_rules, + make_project_source_rules, + make_project_include_dependencies, + NULL +}; + + +/** The GNU make configuration writing process, for session_enumerate_configurations() */ +static SessionProjectCallback ConfigCallbacks[] = +{ + make_project_config_conditional, + make_project_config_outdir, + make_project_config_outfile, + make_project_config_objdir, + make_project_config_cppflags, + make_project_config_cflags, + make_project_config_cxxflags, + make_project_config_ldflags, + make_project_config_lddeps, + make_project_config_resflags, + make_project_config_end, + NULL +}; + + +/** + * The GNU make action handler. + * \param sess The active session object. + * \returns OKAY if successful. + */ +int gmake_action(Session sess) +{ + /* make sure I can support all of the features used in the session */ + if (session_validate(sess, &Features) != OKAY) + { + return !OKAY; + } + + stream_writeline(Console, "Generating project files for GNU make..."); + return session_enumerate_objects(sess, SolutionCallbacks, ProjectCallbacks, ConfigCallbacks); +} + diff --git a/src/action/make/gmake_project.c b/src/action/make/gmake_project.c index adb5660..3788e2d 100644 --- a/src/action/make/gmake_project.c +++ b/src/action/make/gmake_project.c @@ -1,49 +1,49 @@ -/** - * \file gmake_project.c - * \brief GNU makefile project generation functions. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "make_project.h" - - -/** - * Write the shell detection block, which is used while building on Windows in - * order to detect the enclosing shell type: MS-DOS, Cygwin, or MinGW. The shell - * determines how directories and files should be created and removed. - * - * While the detection in important only on Windows, I write for all platforms. - * This simplifies the code generation, and makes portable makefiles possible - * (even though most will have platform-specific bits in them). - */ -int gmake_project_shell_detect(Session sess, Project prj, Stream strm) -{ - int z = OKAY; - - UNUSED(sess); - UNUSED(prj); - - z |= stream_writeline(strm, "SHELLTYPE := msdos"); - z |= stream_writeline(strm, "ifeq (,$(ComSpec)$(COMSPEC))"); - z |= stream_writeline(strm, " SHELLTYPE := posix"); - z |= stream_writeline(strm, "endif"); - z |= stream_writeline(strm, "ifeq (/bin,$(findstring /bin,$(SHELL)))"); - z |= stream_writeline(strm, " SHELLTYPE := posix"); - z |= stream_writeline(strm, "endif"); - z |= stream_writeline(strm, ""); - z |= stream_writeline(strm, "ifeq (posix,$(SHELLTYPE))"); - z |= stream_writeline(strm, " MKDIR := mkdir -p"); - z |= stream_writeline(strm, " PATHSEP := /"); - z |= stream_writeline(strm, "else"); - z |= stream_writeline(strm, " MKDIR := mkdir"); - z |= stream_writeline(strm, " PATHSEP := \\\\"); - z |= stream_writeline(strm, "endif"); - z |= stream_writeline(strm, ""); - z |= stream_writeline(strm, "SYS_OUTDIR := $(subst /,$(PATHSEP),$(OUTDIR))"); - z |= stream_writeline(strm, "SYS_OUTFILE := $(subst /,$(PATHSEP),$(OUTFILE))"); - z |= stream_writeline(strm, "SYS_OBJDIR := $(subst /,$(PATHSEP),$(OBJDIR))"); - z |= stream_writeline(strm, ""); - return z; -} - +/** + * \file gmake_project.c + * \brief GNU makefile project generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "make_project.h" + + +/** + * Write the shell detection block, which is used while building on Windows in + * order to detect the enclosing shell type: MS-DOS, Cygwin, or MinGW. The shell + * determines how directories and files should be created and removed. + * + * While the detection in important only on Windows, I write for all platforms. + * This simplifies the code generation, and makes portable makefiles possible + * (even though most will have platform-specific bits in them). + */ +int gmake_project_shell_detect(Session sess, Project prj, Stream strm) +{ + int z = OKAY; + + UNUSED(sess); + UNUSED(prj); + + z |= stream_writeline(strm, "SHELLTYPE := msdos"); + z |= stream_writeline(strm, "ifeq (,$(ComSpec)$(COMSPEC))"); + z |= stream_writeline(strm, " SHELLTYPE := posix"); + z |= stream_writeline(strm, "endif"); + z |= stream_writeline(strm, "ifeq (/bin,$(findstring /bin,$(SHELL)))"); + z |= stream_writeline(strm, " SHELLTYPE := posix"); + z |= stream_writeline(strm, "endif"); + z |= stream_writeline(strm, ""); + z |= stream_writeline(strm, "ifeq (posix,$(SHELLTYPE))"); + z |= stream_writeline(strm, " MKDIR := mkdir -p"); + z |= stream_writeline(strm, " PATHSEP := /"); + z |= stream_writeline(strm, "else"); + z |= stream_writeline(strm, " MKDIR := mkdir"); + z |= stream_writeline(strm, " PATHSEP := \\\\"); + z |= stream_writeline(strm, "endif"); + z |= stream_writeline(strm, ""); + z |= stream_writeline(strm, "SYS_OUTDIR := $(subst /,$(PATHSEP),$(OUTDIR))"); + z |= stream_writeline(strm, "SYS_OUTFILE := $(subst /,$(PATHSEP),$(OUTFILE))"); + z |= stream_writeline(strm, "SYS_OBJDIR := $(subst /,$(PATHSEP),$(OBJDIR))"); + z |= stream_writeline(strm, ""); + return z; +} + diff --git a/src/action/make/gmake_solution.c b/src/action/make/gmake_solution.c index 77da051..50c7415 100644 --- a/src/action/make/gmake_solution.c +++ b/src/action/make/gmake_solution.c @@ -1,216 +1,216 @@ -/** - * \file gmake_solution.c - * \brief GNU makefile solution generation functions. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include -#include -#include -#include "premake.h" -#include "make.h" -#include "make_solution.h" -#include "base/buffers.h" -#include "base/cstr.h" -#include "base/path.h" -#include "base/strings.h" - -const char* gmake_solution_project_rule(Session sess, Solution sln, Project prj); - - -/** - * Write the GNU makefile all rule. - * \param sess The execution session context. - * \param sln The current solution. - * \param strm The currently active stream; set with session_set_active_stream(). - * \returns OKAY if successful. - */ -int gmake_solution_all_rule(Session sess, Solution sln, Stream strm) -{ - Strings prj_names; - int z; - - UNUSED(sess); - assert(sln); - assert(strm); - - prj_names = make_get_project_names(sln); - z = stream_writeline_strings(strm, prj_names, "all:", " ", "", ""); - z |= stream_writeline(strm, ""); - strings_destroy(prj_names); - return z; -} - - -/** - * Write the GNU solution makefile clean rules. - * \param sess The execution session context. - * \param sln The current solution. - * \param strm The currently active stream; set with session_set_active_stream(). - * \returns OKAY if successful. - */ -int gmake_solution_clean_rule(Session sess, Solution sln, Stream strm) -{ - int i, n, z; - - assert(sess); - assert(sln); - assert(strm); - - z = stream_writeline(strm, "clean:"); - n = solution_num_projects(sln); - for (i = 0; i < n; ++i) - { - Project prj = solution_get_project(sln, i); - const char* rule = gmake_solution_project_rule(sess, sln, prj); - z |= stream_writeline(strm, "%s clean", rule); - } - - return z; -} - - -/** - * Write makefile rules to set a default build configuration. - * \param sess The execution session context. - * \param sln The current solution. - * \param strm The currently active stream; set with session_set_active_stream(). - * \returns OKAY if successful. - */ -int gmake_solution_default_config(Session sess, Solution sln, Stream strm) -{ - const char* default_config_name; - int z; - - UNUSED(sess); - assert(sln); - assert(strm); - - default_config_name = solution_get_config_name(sln, 0); - z = stream_writeline(strm, "ifndef CONFIG"); - z |= stream_writeline(strm, " CONFIG=%s", default_config_name); - z |= stream_writeline(strm, "endif"); - z |= stream_writeline(strm, "export CONFIG"); - z |= stream_writeline(strm, ""); - return z; -} - - -/** - * Write the GNU makefile .PHONY rule. - * \param sess The execution session context. - * \param sln The current solution. - * \param strm The currently active stream; set with session_set_active_stream(). - * \returns OKAY if successful. - */ -int gmake_solution_phony_rule(Session sess, Solution sln, Stream strm) -{ - Strings prj_names; - int z; - - UNUSED(sess); - assert(sln); - assert(strm); - - prj_names = make_get_project_names(sln); - z = stream_writeline_strings(strm, prj_names, ".PHONY: all clean", " ", "", ""); - z |= stream_writeline(strm, ""); - strings_destroy(prj_names); - return z; -} - - -/** - * Build the makefile rule to call an individual project. - * \param sess The current session context. - * \param sln The solution containing the project. - * \param prj The project to be built. - * \returns The makefile rule to trigger the project build. - */ -const char* gmake_solution_project_rule(Session sess, Solution sln, Project prj) -{ - char* buffer = buffers_next(); - - /* project file paths are specified relative to the solution */ - const char* sln_path = path_directory(solution_get_filename(sln, NULL, NULL)); - - const char* prj_file = make_get_project_makefile(sess, prj); - const char* prj_file_dir = path_directory(prj_file); - const char* prj_file_name = path_filename(prj_file); - prj_file_dir = path_relative(sln_path, prj_file_dir); - - strcpy(buffer, "\t@$(MAKE)"); - if (!cstr_eq(".", prj_file_dir)) - { - strcat(buffer, " --no-print-directory -C "); - strcat(buffer, prj_file_dir); - } - if (!cstr_eq("Makefile", prj_file_name)) - { - strcat(buffer, " -f "); - strcat(buffer, prj_file_name); - } - - return buffer; -} - - - -/** - * Write the GNU solution makefile project entry. - * \param sess The execution session context. - * \param sln The current solution. - * \param strm The currently active stream; set with session_set_active_stream(). - * \returns OKAY if successful. - */ -int gmake_solution_projects(Session sess, Solution sln, Stream strm) -{ - int i, n, z = OKAY; - - assert(sess); - assert(sln); - assert(strm); - - n = solution_num_projects(sln); - for (i = 0; i < n; ++i) - { - Project prj = solution_get_project(sln, i); - const char* prj_name = project_get_name(prj); - const char* rule = gmake_solution_project_rule(sess, sln, prj); - - z |= stream_writeline(strm, "%s:", prj_name); - z |= stream_writeline(strm, "\t@echo ==== Building %s ====", prj_name); - z |= stream_writeline(strm, rule); - z |= stream_writeline(strm, ""); - } - - return z; -} - - -/** - * Write the GNU makefile solution file signature block. - * \param sess The execution session context. - * \param sln The current solution. - * \param strm The currently active stream; set with session_set_active_stream(). - * \returns OKAY if successful. - */ -int gmake_solution_signature(Session sess, Solution sln, Stream strm) -{ - Strings config_names; - int z; - - UNUSED(sess); - assert(sln); - assert(strm); - - z = stream_writeline(strm, "# GNU Makefile autogenerated by Premake"); - z |= stream_writeline(strm, "# Usage: make [ CONFIG=config_name ]"); - z |= stream_writeline(strm, "# Where {config_name} is one of:"); - - config_names = solution_get_config_names(sln); - z |= stream_writeline_strings(strm, config_names, "# ", " ", "", ","); - z |= stream_writeline(strm, ""); - - return z; -} +/** + * \file gmake_solution.c + * \brief GNU makefile solution generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include +#include +#include +#include "premake.h" +#include "make.h" +#include "make_solution.h" +#include "base/buffers.h" +#include "base/cstr.h" +#include "base/path.h" +#include "base/strings.h" + +const char* gmake_solution_project_rule(Session sess, Solution sln, Project prj); + + +/** + * Write the GNU makefile all rule. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int gmake_solution_all_rule(Session sess, Solution sln, Stream strm) +{ + Strings prj_names; + int z; + + UNUSED(sess); + assert(sln); + assert(strm); + + prj_names = make_get_project_names(sln); + z = stream_writeline_strings(strm, prj_names, "all:", " ", "", ""); + z |= stream_writeline(strm, ""); + strings_destroy(prj_names); + return z; +} + + +/** + * Write the GNU solution makefile clean rules. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int gmake_solution_clean_rule(Session sess, Solution sln, Stream strm) +{ + int i, n, z; + + assert(sess); + assert(sln); + assert(strm); + + z = stream_writeline(strm, "clean:"); + n = solution_num_projects(sln); + for (i = 0; i < n; ++i) + { + Project prj = solution_get_project(sln, i); + const char* rule = gmake_solution_project_rule(sess, sln, prj); + z |= stream_writeline(strm, "%s clean", rule); + } + + return z; +} + + +/** + * Write makefile rules to set a default build configuration. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int gmake_solution_default_config(Session sess, Solution sln, Stream strm) +{ + const char* default_config_name; + int z; + + UNUSED(sess); + assert(sln); + assert(strm); + + default_config_name = solution_get_config_name(sln, 0); + z = stream_writeline(strm, "ifndef CONFIG"); + z |= stream_writeline(strm, " CONFIG=%s", default_config_name); + z |= stream_writeline(strm, "endif"); + z |= stream_writeline(strm, "export CONFIG"); + z |= stream_writeline(strm, ""); + return z; +} + + +/** + * Write the GNU makefile .PHONY rule. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int gmake_solution_phony_rule(Session sess, Solution sln, Stream strm) +{ + Strings prj_names; + int z; + + UNUSED(sess); + assert(sln); + assert(strm); + + prj_names = make_get_project_names(sln); + z = stream_writeline_strings(strm, prj_names, ".PHONY: all clean", " ", "", ""); + z |= stream_writeline(strm, ""); + strings_destroy(prj_names); + return z; +} + + +/** + * Build the makefile rule to call an individual project. + * \param sess The current session context. + * \param sln The solution containing the project. + * \param prj The project to be built. + * \returns The makefile rule to trigger the project build. + */ +const char* gmake_solution_project_rule(Session sess, Solution sln, Project prj) +{ + char* buffer = buffers_next(); + + /* project file paths are specified relative to the solution */ + const char* sln_path = path_directory(solution_get_filename(sln, NULL, NULL)); + + const char* prj_file = make_get_project_makefile(sess, prj); + const char* prj_file_dir = path_directory(prj_file); + const char* prj_file_name = path_filename(prj_file); + prj_file_dir = path_relative(sln_path, prj_file_dir); + + strcpy(buffer, "\t@$(MAKE)"); + if (!cstr_eq(".", prj_file_dir)) + { + strcat(buffer, " --no-print-directory -C "); + strcat(buffer, prj_file_dir); + } + if (!cstr_eq("Makefile", prj_file_name)) + { + strcat(buffer, " -f "); + strcat(buffer, prj_file_name); + } + + return buffer; +} + + + +/** + * Write the GNU solution makefile project entry. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int gmake_solution_projects(Session sess, Solution sln, Stream strm) +{ + int i, n, z = OKAY; + + assert(sess); + assert(sln); + assert(strm); + + n = solution_num_projects(sln); + for (i = 0; i < n; ++i) + { + Project prj = solution_get_project(sln, i); + const char* prj_name = project_get_name(prj); + const char* rule = gmake_solution_project_rule(sess, sln, prj); + + z |= stream_writeline(strm, "%s:", prj_name); + z |= stream_writeline(strm, "\t@echo ==== Building %s ====", prj_name); + z |= stream_writeline(strm, rule); + z |= stream_writeline(strm, ""); + } + + return z; +} + + +/** + * Write the GNU makefile solution file signature block. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int gmake_solution_signature(Session sess, Solution sln, Stream strm) +{ + Strings config_names; + int z; + + UNUSED(sess); + assert(sln); + assert(strm); + + z = stream_writeline(strm, "# GNU Makefile autogenerated by Premake"); + z |= stream_writeline(strm, "# Usage: make [ CONFIG=config_name ]"); + z |= stream_writeline(strm, "# Where {config_name} is one of:"); + + config_names = solution_get_config_names(sln); + z |= stream_writeline_strings(strm, config_names, "# ", " ", "", ","); + z |= stream_writeline(strm, ""); + + return z; +} diff --git a/src/action/make/make.c b/src/action/make/make.c index 9b7541d..e2a1d7f 100644 --- a/src/action/make/make.c +++ b/src/action/make/make.c @@ -1,153 +1,153 @@ -/** - * \file make.c - * \brief Support functions for the makefile action. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include -#include -#include "premake.h" -#include "make.h" -#include "base/cstr.h" -#include "base/error.h" -#include "base/path.h" - - -/** - * Given a source file filename, returns the name of the corresponding .o file. - * \param filename The source code filename. - * \returns The filename of the .o file. - */ -const char* make_get_obj_filename(const char* filename) -{ - const char* basename = path_basename(filename); - const char* obj_name = cstr_format("$(OBJDIR)/%s.o", basename); - return obj_name; -} - - -/** - * Get the name of the project makefile for a particular project. - * \param sess The current execution session context. - * \param prj The project being requested. - * \returns If this project is the only object which will generate output to - * its target location, then this function will return "Makefile" as - * the filename. If any other object shares this output location, it - * will return "ProjectName.make" instead, so that both objects may - * coexist in the same directory. - */ -const char* make_get_project_makefile(Session sess, Project prj) -{ - const char* my_path; - const char* their_path; - int si, sn; - - assert(sess); - assert(prj); - - /* get the full makefile path for this project */ - my_path = project_get_filename(prj, "Makefile", NULL); - - /* see if any other solution wants to use this same path */ - sn = session_num_solutions(sess); - for (si = 0; si < sn; ++si) - { - int pi, pn; - - Solution sln2 = session_get_solution(sess, si); - their_path = solution_get_filename(sln2, "Makefile", NULL); - if (cstr_eq(my_path, their_path)) - { - /* conflict; use the alternate name */ - my_path = project_get_filename(prj, NULL, ".make"); - return my_path; - } - - /* check any projects contained by this solution */ - pn = solution_num_projects(sln2); - for (pi = 0; pi < pn; ++pi) - { - Project prj2 = solution_get_project(sln2, pi); - if (prj != prj2) - { - their_path = project_get_filename(prj2, "Makefile", NULL); - if (cstr_eq(my_path, their_path)) - { - /* conflict; use the alternate name */ - my_path = project_get_filename(prj, NULL, ".make"); - return my_path; - } - } - } - } - - /* all good */ - return my_path; -} - - -/** - * Build a list of project names contained by the solution. - * \param sln The solution to query. - * \returns A list of project names. The caller owns this list and must destroy it when done. - */ -Strings make_get_project_names(Solution sln) -{ - Strings result; - int i, n; - - result = strings_create(); - n = solution_num_projects(sln); - for (i = 0; i < n; ++i) - { - Project prj = solution_get_project(sln, i); - const char* name = project_get_name(prj); - strings_add(result, name); - } - - return result; -} - - -/** - * Get the name of the solution makefile for a particular solution. - * \param sess The current execution session context. - * \param sln The solution being requested. - * \returns If this solution is the only object which will generate output to - * its target location, then this function will return "Makefile" as - * the filename. If any other solution shares this output location, it - * will return "SolutionName.make" instead, so that both objects may - * coexist in the same directory. - */ -const char* make_get_solution_makefile(Session sess, Solution sln) -{ - const char* my_path; - const char* their_path; - int i, n; - - assert(sess); - assert(sln); - - /* get the full makefile path for this solution */ - my_path = solution_get_filename(sln, "Makefile", NULL); - - /* see if any other solution wants to use this same path */ - n = session_num_solutions(sess); - for (i = 0; i < n; ++i) - { - Solution them = session_get_solution(sess, i); - if (them != sln) - { - their_path = solution_get_filename(them, "Makefile", NULL); - if (cstr_eq(my_path, their_path)) - { - /* conflict; use the alternate name */ - my_path = solution_get_filename(sln, NULL, ".make"); - return my_path; - } - } - } - - /* all good */ - return my_path; -} +/** + * \file make.c + * \brief Support functions for the makefile action. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include +#include +#include "premake.h" +#include "make.h" +#include "base/cstr.h" +#include "base/error.h" +#include "base/path.h" + + +/** + * Given a source file filename, returns the name of the corresponding .o file. + * \param filename The source code filename. + * \returns The filename of the .o file. + */ +const char* make_get_obj_filename(const char* filename) +{ + const char* basename = path_basename(filename); + const char* obj_name = cstr_format("$(OBJDIR)/%s.o", basename); + return obj_name; +} + + +/** + * Get the name of the project makefile for a particular project. + * \param sess The current execution session context. + * \param prj The project being requested. + * \returns If this project is the only object which will generate output to + * its target location, then this function will return "Makefile" as + * the filename. If any other object shares this output location, it + * will return "ProjectName.make" instead, so that both objects may + * coexist in the same directory. + */ +const char* make_get_project_makefile(Session sess, Project prj) +{ + const char* my_path; + const char* their_path; + int si, sn; + + assert(sess); + assert(prj); + + /* get the full makefile path for this project */ + my_path = project_get_filename(prj, "Makefile", NULL); + + /* see if any other solution wants to use this same path */ + sn = session_num_solutions(sess); + for (si = 0; si < sn; ++si) + { + int pi, pn; + + Solution sln2 = session_get_solution(sess, si); + their_path = solution_get_filename(sln2, "Makefile", NULL); + if (cstr_eq(my_path, their_path)) + { + /* conflict; use the alternate name */ + my_path = project_get_filename(prj, NULL, ".make"); + return my_path; + } + + /* check any projects contained by this solution */ + pn = solution_num_projects(sln2); + for (pi = 0; pi < pn; ++pi) + { + Project prj2 = solution_get_project(sln2, pi); + if (prj != prj2) + { + their_path = project_get_filename(prj2, "Makefile", NULL); + if (cstr_eq(my_path, their_path)) + { + /* conflict; use the alternate name */ + my_path = project_get_filename(prj, NULL, ".make"); + return my_path; + } + } + } + } + + /* all good */ + return my_path; +} + + +/** + * Build a list of project names contained by the solution. + * \param sln The solution to query. + * \returns A list of project names. The caller owns this list and must destroy it when done. + */ +Strings make_get_project_names(Solution sln) +{ + Strings result; + int i, n; + + result = strings_create(); + n = solution_num_projects(sln); + for (i = 0; i < n; ++i) + { + Project prj = solution_get_project(sln, i); + const char* name = project_get_name(prj); + strings_add(result, name); + } + + return result; +} + + +/** + * Get the name of the solution makefile for a particular solution. + * \param sess The current execution session context. + * \param sln The solution being requested. + * \returns If this solution is the only object which will generate output to + * its target location, then this function will return "Makefile" as + * the filename. If any other solution shares this output location, it + * will return "SolutionName.make" instead, so that both objects may + * coexist in the same directory. + */ +const char* make_get_solution_makefile(Session sess, Solution sln) +{ + const char* my_path; + const char* their_path; + int i, n; + + assert(sess); + assert(sln); + + /* get the full makefile path for this solution */ + my_path = solution_get_filename(sln, "Makefile", NULL); + + /* see if any other solution wants to use this same path */ + n = session_num_solutions(sess); + for (i = 0; i < n; ++i) + { + Solution them = session_get_solution(sess, i); + if (them != sln) + { + their_path = solution_get_filename(them, "Makefile", NULL); + if (cstr_eq(my_path, their_path)) + { + /* conflict; use the alternate name */ + my_path = solution_get_filename(sln, NULL, ".make"); + return my_path; + } + } + } + + /* all good */ + return my_path; +} diff --git a/src/action/make/make.h b/src/action/make/make.h index 8e757d2..4ac8e43 100644 --- a/src/action/make/make.h +++ b/src/action/make/make.h @@ -1,16 +1,16 @@ -/** - * \file make.h - * \brief Support functions for the makefile action. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ -#if !defined(PREMAKE_MAKE_H) -#define PREMAKE_MAKE_H - -#include "session/session.h" - -const char* make_get_obj_filename(const char* filename); -const char* make_get_project_makefile(Session sess, Project prj); -Strings make_get_project_names(Solution sln); -const char* make_get_solution_makefile(Session sess, Solution sln); - -#endif +/** + * \file make.h + * \brief Support functions for the makefile action. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ +#if !defined(PREMAKE_MAKE_H) +#define PREMAKE_MAKE_H + +#include "session/session.h" + +const char* make_get_obj_filename(const char* filename); +const char* make_get_project_makefile(Session sess, Project prj); +Strings make_get_project_names(Solution sln); +const char* make_get_solution_makefile(Session sess, Solution sln); + +#endif diff --git a/src/action/make/make_project.c b/src/action/make/make_project.c index 8487e55..8bdac0a 100644 --- a/src/action/make/make_project.c +++ b/src/action/make/make_project.c @@ -1,320 +1,320 @@ -/** - * \file make_project.c - * \brief Makefile project generation functions. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include -#include "premake.h" -#include "action/make/make.h" -#include "action/make/make_project.h" -#include "base/error.h" -#include "base/path.h" - - -/** - * Write the rules to clean up output files on a `make clean`. - */ -int make_project_clean_rules(Session sess, Project prj, Stream strm) -{ - int z = OKAY; - UNUSED(sess); - z |= stream_writeline(strm, "clean:"); - z |= stream_writeline(strm, "\t@echo Cleaning %s", project_get_name(prj)); - z |= stream_writeline(strm, "ifeq (posix, $(SHELLTYPE))"); - z |= stream_writeline(strm, "\t@rm -f $(SYS_OUTFILE)"); - z |= stream_writeline(strm, "\t@rm -rf $(SYS_OBJDIR)"); - z |= stream_writeline(strm, "else"); - z |= stream_writeline(strm, "\t@if exist $(SYS_OUTFILE) del $(SYS_OUTFILE)"); - z |= stream_writeline(strm, "\t@if exist $(SYS_OBJDIR) rmdir /s /q $(SYS_OBJDIR)"); - z |= stream_writeline(strm, "endif"); - z |= stream_writeline(strm, ""); - return OKAY; -} - - -/** - * Write the opening conditional for a configuration block. - */ -int make_project_config_conditional(Session sess, Project prj, Stream strm) -{ - const char* cfg_name = project_get_configuration_filter(prj); - UNUSED(sess); - return stream_writeline(strm, "ifeq ($(CONFIG),%s)", cfg_name); -} - - -/** - * Write the CFLAGS configuration variable. - */ -int make_project_config_cflags(Session sess, Project prj, Stream strm) -{ - UNUSED(sess); - UNUSED(prj); - return stream_writeline(strm, " CFLAGS += $(CPPFLAGS) $(ARCHFLAGS)"); -} - - -/** - * Write the CPPFLAGS configuration variable. - */ -int make_project_config_cppflags(Session sess, Project prj, Stream strm) -{ - UNUSED(sess); - UNUSED(prj); - return stream_writeline(strm, " CPPFLAGS += -MMD"); -} - - -/** - * Write the CXXFLAGS configuration variable. - */ -int make_project_config_cxxflags(Session sess, Project prj, Stream strm) -{ - UNUSED(sess); - UNUSED(prj); - return stream_writeline(strm, " CXXFLAGS += $(CFLAGS)"); -} - - -/** - * Write the opening conditional for a configuration block. - */ -int make_project_config_end(Session sess, Project prj, Stream strm) -{ - int z; - UNUSED(sess); - UNUSED(prj); - z = stream_writeline(strm, "endif"); - z |= stream_writeline(strm, ""); - return z; -} - - -/** - * Write the LDDEPS configuration variable. - */ -int make_project_config_lddeps(Session sess, Project prj, Stream strm) -{ - UNUSED(sess); - UNUSED(prj); - return stream_writeline(strm, " LDDEPS :="); -} - - -/** - * Write the LDFLAGS configuration variable. - */ -int make_project_config_ldflags(Session sess, Project prj, Stream strm) -{ - UNUSED(sess); - UNUSED(prj); - return stream_writeline(strm, " LDFLAGS +="); -} - - -/** - * Write the OBJDIR configuration variable. - */ -int make_project_config_objdir(Session sess, Project prj, Stream strm) -{ - const char* cfg_name = project_get_configuration_filter(prj); - UNUSED(sess); - return stream_writeline(strm, " OBJDIR := obj/%s", cfg_name); -} - - -/** - * Write the OUTDIR configuration variable. - */ -int make_project_config_outdir(Session sess, Project prj, Stream strm) -{ - UNUSED(sess); - UNUSED(prj); - return stream_writeline(strm, " OUTDIR := ."); -} - - -/** - * Write the OUTFILE configuration variable. - */ -int make_project_config_outfile(Session sess, Project prj, Stream strm) -{ - const char* outfile = project_get_outfile(prj); - UNUSED(sess); - return stream_writeline(strm, " OUTFILE := $(OUTDIR)/%s", outfile); -} - - -/** - * Write the RESFLAGS configuration variable. - */ -int make_project_config_resflags(Session sess, Project prj, Stream strm) -{ - UNUSED(sess); - UNUSED(prj); - return stream_writeline(strm, " RESFLAGS +="); -} - - -/** - * Create a new output stream for a project , and make it active for subsequent writes. - */ -int make_project_create(Session sess, Project prj, Stream strm) -{ - /* create the makefile */ - const char* filename = make_get_project_makefile(sess, prj); - strm = stream_create_file(filename); - if (!strm) - { - return !OKAY; - } - - /* make the stream active for the functions that come after */ - session_set_active_stream(sess, strm); - return OKAY; -} - - -/** - * Include the auto-generated dependencies into the project makefile. - */ -int make_project_include_dependencies(Session sess, Project prj, Stream strm) -{ - UNUSED(sess); - UNUSED(prj); - return stream_writeline(strm, "-include $(OBJECTS:%%.o=%%.d)"); -} - - -/** - * Write the rules to create the output and object directories. - */ -int make_project_mkdir_rules(Session sess, Project prj, Stream strm) -{ - int z = OKAY; - UNUSED(sess); - UNUSED(prj); - z |= stream_writeline(strm, "$(OUTDIR):"); - z |= stream_writeline(strm, "\t@echo Creating $(OUTDIR)"); - z |= stream_writeline(strm, "\t@$(MKDIR) $(SYS_OUTDIR)"); - z |= stream_writeline(strm, ""); - z |= stream_writeline(strm, "$(OBJDIR):"); - z |= stream_writeline(strm, "\t@echo Creating $(OBJDIR)"); - z |= stream_writeline(strm, "\t@$(MKDIR) $(SYS_OBJDIR)"); - z |= stream_writeline(strm, ""); - return z; -} - - -/** - * Write the OBJECTS project variable. - */ -int make_project_objects(Session sess, Project prj, Stream strm) -{ - Strings files; - int i, n, z; - UNUSED(sess); - - z = stream_writeline(strm, "OBJECTS := \\"); - - files = project_get_files(prj); - n = strings_size(files); - for (i = 0; i < n; ++i) - { - const char* filename = strings_item(files, i); - if (path_is_cpp_source(filename)) - { - const char* obj_name = make_get_obj_filename(filename); - z |= stream_writeline(strm, "\t%s \\", obj_name); - } - } - - z |= stream_writeline(strm, ""); - return z; -} - - -/** - * Write the .PHONY rule for a project. - */ -int make_project_phony_rule(Session sess, Project prj, Stream strm) -{ - int z; - UNUSED(sess); - UNUSED(prj); - z = stream_writeline(strm, ".PHONY: clean"); - z |= stream_writeline(strm, ""); - return z; -} - - -/** - * Write the RESOURCES project variable. - */ -int make_project_resources(Session sess, Project prj, Stream strm) -{ - int z; - UNUSED(sess); - UNUSED(prj); - z = stream_writeline(strm, "RESOURCES := \\"); - z |= stream_writeline(strm, ""); - return z; -} - - -/** - * Write the project makefile signature. - */ -int make_project_signature(Session sess, Project prj, Stream strm) -{ - int z; - UNUSED(sess); - UNUSED(prj); - z = stream_writeline(strm, "# GNU Makefile autogenerated by Premake"); - z |= stream_writeline(strm, ""); - return z; -} - - -/** - * Write makefile rules for each source code file. - */ -int make_project_source_rules(Session sess, Project prj, Stream strm) -{ - Strings files; - int i, n, z = OKAY; - UNUSED(sess); - - files = project_get_files(prj); - n = strings_size(files); - for (i = 0; i < n; ++i) - { - const char* filename = strings_item(files, i); - if (path_is_cpp_source(filename)) - { - const char* obj_name = make_get_obj_filename(filename); - z |= stream_writeline(strm, "%s: %s", obj_name, filename); - z |= stream_writeline(strm, "\t@echo $(notdir $<)"); - z |= stream_writeline(strm, "\t@$(CXX) $(CXXFLAGS) -o $@ -c $<"); - z |= stream_writeline(strm, ""); - } - } - - return z; -} - - -/** - * Write the project output target rule. - */ -int make_project_target(Session sess, Project prj, Stream strm) -{ - int z = OKAY; - UNUSED(sess); - z |= stream_writeline(strm, "$(OUTFILE): $(OUTDIR) $(OBJDIR) $(OBJECTS) $(LDDEPS) $(RESOURCES)"); - z |= stream_writeline(strm, "\t@echo Linking %s", project_get_name(prj)); - z |= stream_writeline(strm, "\t@$(CXX) -o $@ $(LDFLAGS) $(ARCHFLAGS) $(OBJECTS) $(RESOURCES)"); - z |= stream_writeline(strm, ""); - return z; -} +/** + * \file make_project.c + * \brief Makefile project generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include +#include "premake.h" +#include "action/make/make.h" +#include "action/make/make_project.h" +#include "base/error.h" +#include "base/path.h" + + +/** + * Write the rules to clean up output files on a `make clean`. + */ +int make_project_clean_rules(Session sess, Project prj, Stream strm) +{ + int z = OKAY; + UNUSED(sess); + z |= stream_writeline(strm, "clean:"); + z |= stream_writeline(strm, "\t@echo Cleaning %s", project_get_name(prj)); + z |= stream_writeline(strm, "ifeq (posix, $(SHELLTYPE))"); + z |= stream_writeline(strm, "\t@rm -f $(SYS_OUTFILE)"); + z |= stream_writeline(strm, "\t@rm -rf $(SYS_OBJDIR)"); + z |= stream_writeline(strm, "else"); + z |= stream_writeline(strm, "\t@if exist $(SYS_OUTFILE) del $(SYS_OUTFILE)"); + z |= stream_writeline(strm, "\t@if exist $(SYS_OBJDIR) rmdir /s /q $(SYS_OBJDIR)"); + z |= stream_writeline(strm, "endif"); + z |= stream_writeline(strm, ""); + return OKAY; +} + + +/** + * Write the opening conditional for a configuration block. + */ +int make_project_config_conditional(Session sess, Project prj, Stream strm) +{ + const char* cfg_name = project_get_configuration_filter(prj); + UNUSED(sess); + return stream_writeline(strm, "ifeq ($(CONFIG),%s)", cfg_name); +} + + +/** + * Write the CFLAGS configuration variable. + */ +int make_project_config_cflags(Session sess, Project prj, Stream strm) +{ + UNUSED(sess); + UNUSED(prj); + return stream_writeline(strm, " CFLAGS += $(CPPFLAGS) $(ARCHFLAGS)"); +} + + +/** + * Write the CPPFLAGS configuration variable. + */ +int make_project_config_cppflags(Session sess, Project prj, Stream strm) +{ + UNUSED(sess); + UNUSED(prj); + return stream_writeline(strm, " CPPFLAGS += -MMD"); +} + + +/** + * Write the CXXFLAGS configuration variable. + */ +int make_project_config_cxxflags(Session sess, Project prj, Stream strm) +{ + UNUSED(sess); + UNUSED(prj); + return stream_writeline(strm, " CXXFLAGS += $(CFLAGS)"); +} + + +/** + * Write the opening conditional for a configuration block. + */ +int make_project_config_end(Session sess, Project prj, Stream strm) +{ + int z; + UNUSED(sess); + UNUSED(prj); + z = stream_writeline(strm, "endif"); + z |= stream_writeline(strm, ""); + return z; +} + + +/** + * Write the LDDEPS configuration variable. + */ +int make_project_config_lddeps(Session sess, Project prj, Stream strm) +{ + UNUSED(sess); + UNUSED(prj); + return stream_writeline(strm, " LDDEPS :="); +} + + +/** + * Write the LDFLAGS configuration variable. + */ +int make_project_config_ldflags(Session sess, Project prj, Stream strm) +{ + UNUSED(sess); + UNUSED(prj); + return stream_writeline(strm, " LDFLAGS +="); +} + + +/** + * Write the OBJDIR configuration variable. + */ +int make_project_config_objdir(Session sess, Project prj, Stream strm) +{ + const char* cfg_name = project_get_configuration_filter(prj); + UNUSED(sess); + return stream_writeline(strm, " OBJDIR := obj/%s", cfg_name); +} + + +/** + * Write the OUTDIR configuration variable. + */ +int make_project_config_outdir(Session sess, Project prj, Stream strm) +{ + UNUSED(sess); + UNUSED(prj); + return stream_writeline(strm, " OUTDIR := ."); +} + + +/** + * Write the OUTFILE configuration variable. + */ +int make_project_config_outfile(Session sess, Project prj, Stream strm) +{ + const char* outfile = project_get_outfile(prj); + UNUSED(sess); + return stream_writeline(strm, " OUTFILE := $(OUTDIR)/%s", outfile); +} + + +/** + * Write the RESFLAGS configuration variable. + */ +int make_project_config_resflags(Session sess, Project prj, Stream strm) +{ + UNUSED(sess); + UNUSED(prj); + return stream_writeline(strm, " RESFLAGS +="); +} + + +/** + * Create a new output stream for a project , and make it active for subsequent writes. + */ +int make_project_create(Session sess, Project prj, Stream strm) +{ + /* create the makefile */ + const char* filename = make_get_project_makefile(sess, prj); + strm = stream_create_file(filename); + if (!strm) + { + return !OKAY; + } + + /* make the stream active for the functions that come after */ + session_set_active_stream(sess, strm); + return OKAY; +} + + +/** + * Include the auto-generated dependencies into the project makefile. + */ +int make_project_include_dependencies(Session sess, Project prj, Stream strm) +{ + UNUSED(sess); + UNUSED(prj); + return stream_writeline(strm, "-include $(OBJECTS:%%.o=%%.d)"); +} + + +/** + * Write the rules to create the output and object directories. + */ +int make_project_mkdir_rules(Session sess, Project prj, Stream strm) +{ + int z = OKAY; + UNUSED(sess); + UNUSED(prj); + z |= stream_writeline(strm, "$(OUTDIR):"); + z |= stream_writeline(strm, "\t@echo Creating $(OUTDIR)"); + z |= stream_writeline(strm, "\t@$(MKDIR) $(SYS_OUTDIR)"); + z |= stream_writeline(strm, ""); + z |= stream_writeline(strm, "$(OBJDIR):"); + z |= stream_writeline(strm, "\t@echo Creating $(OBJDIR)"); + z |= stream_writeline(strm, "\t@$(MKDIR) $(SYS_OBJDIR)"); + z |= stream_writeline(strm, ""); + return z; +} + + +/** + * Write the OBJECTS project variable. + */ +int make_project_objects(Session sess, Project prj, Stream strm) +{ + Strings files; + int i, n, z; + UNUSED(sess); + + z = stream_writeline(strm, "OBJECTS := \\"); + + files = project_get_files(prj); + n = strings_size(files); + for (i = 0; i < n; ++i) + { + const char* filename = strings_item(files, i); + if (path_is_cpp_source(filename)) + { + const char* obj_name = make_get_obj_filename(filename); + z |= stream_writeline(strm, "\t%s \\", obj_name); + } + } + + z |= stream_writeline(strm, ""); + return z; +} + + +/** + * Write the .PHONY rule for a project. + */ +int make_project_phony_rule(Session sess, Project prj, Stream strm) +{ + int z; + UNUSED(sess); + UNUSED(prj); + z = stream_writeline(strm, ".PHONY: clean"); + z |= stream_writeline(strm, ""); + return z; +} + + +/** + * Write the RESOURCES project variable. + */ +int make_project_resources(Session sess, Project prj, Stream strm) +{ + int z; + UNUSED(sess); + UNUSED(prj); + z = stream_writeline(strm, "RESOURCES := \\"); + z |= stream_writeline(strm, ""); + return z; +} + + +/** + * Write the project makefile signature. + */ +int make_project_signature(Session sess, Project prj, Stream strm) +{ + int z; + UNUSED(sess); + UNUSED(prj); + z = stream_writeline(strm, "# GNU Makefile autogenerated by Premake"); + z |= stream_writeline(strm, ""); + return z; +} + + +/** + * Write makefile rules for each source code file. + */ +int make_project_source_rules(Session sess, Project prj, Stream strm) +{ + Strings files; + int i, n, z = OKAY; + UNUSED(sess); + + files = project_get_files(prj); + n = strings_size(files); + for (i = 0; i < n; ++i) + { + const char* filename = strings_item(files, i); + if (path_is_cpp_source(filename)) + { + const char* obj_name = make_get_obj_filename(filename); + z |= stream_writeline(strm, "%s: %s", obj_name, filename); + z |= stream_writeline(strm, "\t@echo $(notdir $<)"); + z |= stream_writeline(strm, "\t@$(CXX) $(CXXFLAGS) -o $@ -c $<"); + z |= stream_writeline(strm, ""); + } + } + + return z; +} + + +/** + * Write the project output target rule. + */ +int make_project_target(Session sess, Project prj, Stream strm) +{ + int z = OKAY; + UNUSED(sess); + z |= stream_writeline(strm, "$(OUTFILE): $(OUTDIR) $(OBJDIR) $(OBJECTS) $(LDDEPS) $(RESOURCES)"); + z |= stream_writeline(strm, "\t@echo Linking %s", project_get_name(prj)); + z |= stream_writeline(strm, "\t@$(CXX) -o $@ $(LDFLAGS) $(ARCHFLAGS) $(OBJECTS) $(RESOURCES)"); + z |= stream_writeline(strm, ""); + return z; +} diff --git a/src/action/make/make_project.h b/src/action/make/make_project.h index 65482c1..e8a3ef8 100644 --- a/src/action/make/make_project.h +++ b/src/action/make/make_project.h @@ -1,35 +1,35 @@ -/** - * \file make_project.h - * \brief Makefile project generation functions. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ -#if !defined(PREMAKE_MAKE_PROJECT_H) -#define PREMAKE_MAKE_PROJECT_H - -#include "session/session.h" - -int gmake_project_shell_detect(Session sess, Project prj, Stream strm); - -int make_project_clean_rules(Session sess, Project prj, Stream strm); -int make_project_config_conditional(Session sess, Project prj, Stream strm); -int make_project_config_cflags(Session sess, Project prj, Stream strm); -int make_project_config_cppflags(Session sess, Project prj, Stream strm); -int make_project_config_cxxflags(Session sess, Project prj, Stream strm); -int make_project_config_end(Session sess, Project prj, Stream strm); -int make_project_config_lddeps(Session sess, Project prj, Stream strm); -int make_project_config_ldflags(Session sess, Project prj, Stream strm); -int make_project_config_objdir(Session sess, Project prj, Stream strm); -int make_project_config_outdir(Session sess, Project prj, Stream strm); -int make_project_config_outfile(Session sess, Project prj, Stream strm); -int make_project_config_resflags(Session sess, Project prj, Stream strm); -int make_project_create(Session sess, Project prj, Stream strm); -int make_project_include_dependencies(Session sess, Project prj, Stream strm); -int make_project_mkdir_rules(Session sess, Project prj, Stream strm); -int make_project_objects(Session sess, Project prj, Stream strm); -int make_project_phony_rule(Session sess, Project prj, Stream strm); -int make_project_resources(Session sess, Project prj, Stream strm); -int make_project_signature(Session sess, Project prj, Stream strm); -int make_project_source_rules(Session sess, Project prj, Stream strm); -int make_project_target(Session sess, Project prj, Stream strm); - -#endif +/** + * \file make_project.h + * \brief Makefile project generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ +#if !defined(PREMAKE_MAKE_PROJECT_H) +#define PREMAKE_MAKE_PROJECT_H + +#include "session/session.h" + +int gmake_project_shell_detect(Session sess, Project prj, Stream strm); + +int make_project_clean_rules(Session sess, Project prj, Stream strm); +int make_project_config_conditional(Session sess, Project prj, Stream strm); +int make_project_config_cflags(Session sess, Project prj, Stream strm); +int make_project_config_cppflags(Session sess, Project prj, Stream strm); +int make_project_config_cxxflags(Session sess, Project prj, Stream strm); +int make_project_config_end(Session sess, Project prj, Stream strm); +int make_project_config_lddeps(Session sess, Project prj, Stream strm); +int make_project_config_ldflags(Session sess, Project prj, Stream strm); +int make_project_config_objdir(Session sess, Project prj, Stream strm); +int make_project_config_outdir(Session sess, Project prj, Stream strm); +int make_project_config_outfile(Session sess, Project prj, Stream strm); +int make_project_config_resflags(Session sess, Project prj, Stream strm); +int make_project_create(Session sess, Project prj, Stream strm); +int make_project_include_dependencies(Session sess, Project prj, Stream strm); +int make_project_mkdir_rules(Session sess, Project prj, Stream strm); +int make_project_objects(Session sess, Project prj, Stream strm); +int make_project_phony_rule(Session sess, Project prj, Stream strm); +int make_project_resources(Session sess, Project prj, Stream strm); +int make_project_signature(Session sess, Project prj, Stream strm); +int make_project_source_rules(Session sess, Project prj, Stream strm); +int make_project_target(Session sess, Project prj, Stream strm); + +#endif diff --git a/src/action/make/make_solution.c b/src/action/make/make_solution.c index 2fa5cec..5f31087 100644 --- a/src/action/make/make_solution.c +++ b/src/action/make/make_solution.c @@ -1,34 +1,34 @@ -/** - * \file make_solution.c - * \brief Makefile solution generation functions. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include -#include "premake.h" -#include "action/make/make.h" -#include "action/make/make_solution.h" -#include "base/error.h" - - -/** - * Create a new output stream for a solution, and make it active for subsequent writes. - * \param sess The execution session context. - * \param sln The current solution. - * \param strm The currently active stream; set with session_set_active_stream(). - * \returns OKAY if successful. - */ -int make_solution_create(Session sess, Solution sln, Stream strm) -{ - /* create the makefile */ - const char* filename = make_get_solution_makefile(sess, sln); - strm = stream_create_file(filename); - if (!strm) - { - return !OKAY; - } - - /* make the stream active for the functions that come after */ - session_set_active_stream(sess, strm); - return OKAY; -} +/** + * \file make_solution.c + * \brief Makefile solution generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include +#include "premake.h" +#include "action/make/make.h" +#include "action/make/make_solution.h" +#include "base/error.h" + + +/** + * Create a new output stream for a solution, and make it active for subsequent writes. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int make_solution_create(Session sess, Solution sln, Stream strm) +{ + /* create the makefile */ + const char* filename = make_get_solution_makefile(sess, sln); + strm = stream_create_file(filename); + if (!strm) + { + return !OKAY; + } + + /* make the stream active for the functions that come after */ + session_set_active_stream(sess, strm); + return OKAY; +} diff --git a/src/action/make/make_solution.h b/src/action/make/make_solution.h index e7ae51b..01a5989 100644 --- a/src/action/make/make_solution.h +++ b/src/action/make/make_solution.h @@ -1,20 +1,20 @@ -/** - * \file make_solution.h - * \brief Makefile solution generation functions. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ -#if !defined(PREMAKE_MAKE_SOLUTION_H) -#define PREMAKE_MAKE_SOLUTION_H - -#include "session/session.h" - -int make_solution_create(Session sess, Solution sln, Stream strm); - -int gmake_solution_all_rule(Session sess, Solution sln, Stream strm); -int gmake_solution_clean_rule(Session sess, Solution sln, Stream strm); -int gmake_solution_default_config(Session sess, Solution sln, Stream strm); -int gmake_solution_phony_rule(Session sess, Solution sln, Stream strm); -int gmake_solution_projects(Session sess, Solution sln, Stream strm); -int gmake_solution_signature(Session sess, Solution sln, Stream strm); - -#endif +/** + * \file make_solution.h + * \brief Makefile solution generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ +#if !defined(PREMAKE_MAKE_SOLUTION_H) +#define PREMAKE_MAKE_SOLUTION_H + +#include "session/session.h" + +int make_solution_create(Session sess, Solution sln, Stream strm); + +int gmake_solution_all_rule(Session sess, Solution sln, Stream strm); +int gmake_solution_clean_rule(Session sess, Solution sln, Stream strm); +int gmake_solution_default_config(Session sess, Solution sln, Stream strm); +int gmake_solution_phony_rule(Session sess, Solution sln, Stream strm); +int gmake_solution_projects(Session sess, Solution sln, Stream strm); +int gmake_solution_signature(Session sess, Solution sln, Stream strm); + +#endif diff --git a/src/action/make/tests/gmake_project_tests.cpp b/src/action/make/tests/gmake_project_tests.cpp index 55646d3..ba0821a 100644 --- a/src/action/make/tests/gmake_project_tests.cpp +++ b/src/action/make/tests/gmake_project_tests.cpp @@ -1,249 +1,249 @@ -/** - * \file gmake_project_tests.cpp - * \brief Automated tests for GNU makefile project processing. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "action/tests/action_tests.h" -extern "C" { -#include "action/make/make_project.h" -#include "platform/platform.h" -} - -SUITE(action) -{ - TEST_FIXTURE(FxAction, MakeProject_Signature) - { - make_project_signature(sess, prj, strm); - CHECK_EQUAL( - "# GNU Makefile autogenerated by Premake\n" - "\n", - buffer); - } - - TEST_FIXTURE(FxAction, MakeProject_Config_Conditional) - { - make_project_config_conditional(sess, prj, strm); - CHECK_EQUAL( - "ifeq ($(CONFIG),Debug)\n", - buffer); - } - - TEST_FIXTURE(FxAction, MakeProject_Config_End) - { - make_project_config_end(sess, prj, strm); - CHECK_EQUAL( - "endif\n" - "\n", - buffer); - } - - TEST_FIXTURE(FxAction, MakeProject_Config_CFlags) - { - make_project_config_cflags(sess, prj, strm); - CHECK_EQUAL( - " CFLAGS += $(CPPFLAGS) $(ARCHFLAGS)\n", - buffer); - } - - TEST_FIXTURE(FxAction, MakeProject_Config_CppFlags) - { - make_project_config_cppflags(sess, prj, strm); - CHECK_EQUAL( - " CPPFLAGS += -MMD\n", - buffer); - } - - TEST_FIXTURE(FxAction, MakeProject_Config_CxxFlags) - { - make_project_config_cxxflags(sess, prj, strm); - CHECK_EQUAL( - " CXXFLAGS += $(CFLAGS)\n", - buffer); - } - - TEST_FIXTURE(FxAction, MakeProject_Config_LdDeps) - { - make_project_config_lddeps(sess, prj, strm); - CHECK_EQUAL( - " LDDEPS :=\n", - buffer); - } - - TEST_FIXTURE(FxAction, MakeProject_Config_LdFlags) - { - make_project_config_ldflags(sess, prj, strm); - CHECK_EQUAL( - " LDFLAGS +=\n", - buffer); - } - - TEST_FIXTURE(FxAction, MakeProject_Config_ObjDir) - { - make_project_config_objdir(sess, prj, strm); - CHECK_EQUAL( - " OBJDIR := obj/Debug\n", - buffer); - } - - TEST_FIXTURE(FxAction, MakeProject_Config_OutFile) - { - platform_set(MacOSX); - make_project_config_outfile(sess, prj, strm); - CHECK_EQUAL( - " OUTFILE := $(OUTDIR)/MyProject\n", - buffer); - } - - TEST_FIXTURE(FxAction, MakeProject_Config_OutDir) - { - make_project_config_outdir(sess, prj, strm); - CHECK_EQUAL( - " OUTDIR := .\n", - buffer); - } - - TEST_FIXTURE(FxAction, MakeProject_Config_ResFlags) - { - make_project_config_resflags(sess, prj, strm); - CHECK_EQUAL( - " RESFLAGS +=\n", - buffer); - } - - - /********************************************************************** - * Object file list tests - **********************************************************************/ - - TEST_FIXTURE(FxAction, MakeProject_Objects_ConvertsFileExtension) - { - char* files[] = { "Hello.cpp", "Goodbye.cpp", NULL }; - SetField(prj, ProjectFiles, files); - make_project_objects(sess, prj, strm); - CHECK_EQUAL( - "OBJECTS := \\\n" - "\t$(OBJDIR)/Hello.o \\\n" - "\t$(OBJDIR)/Goodbye.o \\\n" - "\n", - buffer); - } - - - /********************************************************************** - * Resource file list tests - **********************************************************************/ - - TEST_FIXTURE(FxAction, MakeProject_Resources) - { - make_project_resources(sess, prj, strm); - CHECK_EQUAL( - "RESOURCES := \\\n" - "\n", - buffer); - } - - - /********************************************************************** - * .PHONY rule tests - **********************************************************************/ - - TEST_FIXTURE(FxAction, MakeProject_PhonyRule) - { - make_project_phony_rule(sess, prj, strm); - CHECK_EQUAL( - ".PHONY: clean\n" - "\n", - buffer); - } - - - /********************************************************************** - * Output target tests - **********************************************************************/ - - TEST_FIXTURE(FxAction, MakeProject_OutputTarget) - { - make_project_target(sess, prj, strm); - CHECK_EQUAL( - "$(OUTFILE): $(OUTDIR) $(OBJDIR) $(OBJECTS) $(LDDEPS) $(RESOURCES)\n" - "\t@echo Linking MyProject\n" - "\t@$(CXX) -o $@ $(LDFLAGS) $(ARCHFLAGS) $(OBJECTS) $(RESOURCES)\n" - "\n", - buffer); - } - - - /********************************************************************** - * Directory creation rules - **********************************************************************/ - - TEST_FIXTURE(FxAction, MakeProject_MkdirRules) - { - make_project_mkdir_rules(sess, prj, strm); - CHECK_EQUAL( - "$(OUTDIR):\n" - "\t@echo Creating $(OUTDIR)\n" - "\t@$(MKDIR) $(SYS_OUTDIR)\n" - "\n" - "$(OBJDIR):\n" - "\t@echo Creating $(OBJDIR)\n" - "\t@$(MKDIR) $(SYS_OBJDIR)\n" - "\n", - buffer); - } - - - /********************************************************************** - * Clean rules - **********************************************************************/ - - TEST_FIXTURE(FxAction, MakeProject_CleanRules) - { - make_project_clean_rules(sess, prj, strm); - CHECK_EQUAL( - "clean:\n" - "\t@echo Cleaning MyProject\n" - "ifeq (posix, $(SHELLTYPE))\n" - "\t@rm -f $(SYS_OUTFILE)\n" - "\t@rm -rf $(SYS_OBJDIR)\n" - "else\n" - "\t@if exist $(SYS_OUTFILE) del $(SYS_OUTFILE)\n" - "\t@if exist $(SYS_OBJDIR) rmdir /s /q $(SYS_OBJDIR)\n" - "endif\n" - "\n", - buffer); - } - - - /********************************************************************** - * Source rule tests - **********************************************************************/ - - TEST_FIXTURE(FxAction, MakeProject_SourceRules) - { - char* files[] = { "Hello.cpp", NULL }; - SetField(prj, ProjectFiles, files); - make_project_source_rules(sess, prj, strm); - CHECK_EQUAL( - "$(OBJDIR)/Hello.o: Hello.cpp\n" - "\t@echo $(notdir $<)\n" - "\t@$(CXX) $(CXXFLAGS) -o $@ -c $<\n" - "\n", - buffer); - } - - - /********************************************************************** - * File dependency generation tests - **********************************************************************/ - - TEST_FIXTURE(FxAction, MakeProject_IncludeDependencies) - { - make_project_include_dependencies(sess, prj, strm); - CHECK_EQUAL( - "-include $(OBJECTS:%.o=%.d)\n", - buffer); - } -} +/** + * \file gmake_project_tests.cpp + * \brief Automated tests for GNU makefile project processing. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "action/tests/action_tests.h" +extern "C" { +#include "action/make/make_project.h" +#include "platform/platform.h" +} + +SUITE(action) +{ + TEST_FIXTURE(FxAction, MakeProject_Signature) + { + make_project_signature(sess, prj, strm); + CHECK_EQUAL( + "# GNU Makefile autogenerated by Premake\n" + "\n", + buffer); + } + + TEST_FIXTURE(FxAction, MakeProject_Config_Conditional) + { + make_project_config_conditional(sess, prj, strm); + CHECK_EQUAL( + "ifeq ($(CONFIG),Debug)\n", + buffer); + } + + TEST_FIXTURE(FxAction, MakeProject_Config_End) + { + make_project_config_end(sess, prj, strm); + CHECK_EQUAL( + "endif\n" + "\n", + buffer); + } + + TEST_FIXTURE(FxAction, MakeProject_Config_CFlags) + { + make_project_config_cflags(sess, prj, strm); + CHECK_EQUAL( + " CFLAGS += $(CPPFLAGS) $(ARCHFLAGS)\n", + buffer); + } + + TEST_FIXTURE(FxAction, MakeProject_Config_CppFlags) + { + make_project_config_cppflags(sess, prj, strm); + CHECK_EQUAL( + " CPPFLAGS += -MMD\n", + buffer); + } + + TEST_FIXTURE(FxAction, MakeProject_Config_CxxFlags) + { + make_project_config_cxxflags(sess, prj, strm); + CHECK_EQUAL( + " CXXFLAGS += $(CFLAGS)\n", + buffer); + } + + TEST_FIXTURE(FxAction, MakeProject_Config_LdDeps) + { + make_project_config_lddeps(sess, prj, strm); + CHECK_EQUAL( + " LDDEPS :=\n", + buffer); + } + + TEST_FIXTURE(FxAction, MakeProject_Config_LdFlags) + { + make_project_config_ldflags(sess, prj, strm); + CHECK_EQUAL( + " LDFLAGS +=\n", + buffer); + } + + TEST_FIXTURE(FxAction, MakeProject_Config_ObjDir) + { + make_project_config_objdir(sess, prj, strm); + CHECK_EQUAL( + " OBJDIR := obj/Debug\n", + buffer); + } + + TEST_FIXTURE(FxAction, MakeProject_Config_OutFile) + { + platform_set(MacOSX); + make_project_config_outfile(sess, prj, strm); + CHECK_EQUAL( + " OUTFILE := $(OUTDIR)/MyProject\n", + buffer); + } + + TEST_FIXTURE(FxAction, MakeProject_Config_OutDir) + { + make_project_config_outdir(sess, prj, strm); + CHECK_EQUAL( + " OUTDIR := .\n", + buffer); + } + + TEST_FIXTURE(FxAction, MakeProject_Config_ResFlags) + { + make_project_config_resflags(sess, prj, strm); + CHECK_EQUAL( + " RESFLAGS +=\n", + buffer); + } + + + /********************************************************************** + * Object file list tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, MakeProject_Objects_ConvertsFileExtension) + { + char* files[] = { "Hello.cpp", "Goodbye.cpp", NULL }; + SetField(prj, ProjectFiles, files); + make_project_objects(sess, prj, strm); + CHECK_EQUAL( + "OBJECTS := \\\n" + "\t$(OBJDIR)/Hello.o \\\n" + "\t$(OBJDIR)/Goodbye.o \\\n" + "\n", + buffer); + } + + + /********************************************************************** + * Resource file list tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, MakeProject_Resources) + { + make_project_resources(sess, prj, strm); + CHECK_EQUAL( + "RESOURCES := \\\n" + "\n", + buffer); + } + + + /********************************************************************** + * .PHONY rule tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, MakeProject_PhonyRule) + { + make_project_phony_rule(sess, prj, strm); + CHECK_EQUAL( + ".PHONY: clean\n" + "\n", + buffer); + } + + + /********************************************************************** + * Output target tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, MakeProject_OutputTarget) + { + make_project_target(sess, prj, strm); + CHECK_EQUAL( + "$(OUTFILE): $(OUTDIR) $(OBJDIR) $(OBJECTS) $(LDDEPS) $(RESOURCES)\n" + "\t@echo Linking MyProject\n" + "\t@$(CXX) -o $@ $(LDFLAGS) $(ARCHFLAGS) $(OBJECTS) $(RESOURCES)\n" + "\n", + buffer); + } + + + /********************************************************************** + * Directory creation rules + **********************************************************************/ + + TEST_FIXTURE(FxAction, MakeProject_MkdirRules) + { + make_project_mkdir_rules(sess, prj, strm); + CHECK_EQUAL( + "$(OUTDIR):\n" + "\t@echo Creating $(OUTDIR)\n" + "\t@$(MKDIR) $(SYS_OUTDIR)\n" + "\n" + "$(OBJDIR):\n" + "\t@echo Creating $(OBJDIR)\n" + "\t@$(MKDIR) $(SYS_OBJDIR)\n" + "\n", + buffer); + } + + + /********************************************************************** + * Clean rules + **********************************************************************/ + + TEST_FIXTURE(FxAction, MakeProject_CleanRules) + { + make_project_clean_rules(sess, prj, strm); + CHECK_EQUAL( + "clean:\n" + "\t@echo Cleaning MyProject\n" + "ifeq (posix, $(SHELLTYPE))\n" + "\t@rm -f $(SYS_OUTFILE)\n" + "\t@rm -rf $(SYS_OBJDIR)\n" + "else\n" + "\t@if exist $(SYS_OUTFILE) del $(SYS_OUTFILE)\n" + "\t@if exist $(SYS_OBJDIR) rmdir /s /q $(SYS_OBJDIR)\n" + "endif\n" + "\n", + buffer); + } + + + /********************************************************************** + * Source rule tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, MakeProject_SourceRules) + { + char* files[] = { "Hello.cpp", NULL }; + SetField(prj, ProjectFiles, files); + make_project_source_rules(sess, prj, strm); + CHECK_EQUAL( + "$(OBJDIR)/Hello.o: Hello.cpp\n" + "\t@echo $(notdir $<)\n" + "\t@$(CXX) $(CXXFLAGS) -o $@ -c $<\n" + "\n", + buffer); + } + + + /********************************************************************** + * File dependency generation tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, MakeProject_IncludeDependencies) + { + make_project_include_dependencies(sess, prj, strm); + CHECK_EQUAL( + "-include $(OBJECTS:%.o=%.d)\n", + buffer); + } +} diff --git a/src/action/make/tests/gmake_solution_tests.cpp b/src/action/make/tests/gmake_solution_tests.cpp index 531289d..f9e918b 100644 --- a/src/action/make/tests/gmake_solution_tests.cpp +++ b/src/action/make/tests/gmake_solution_tests.cpp @@ -1,121 +1,121 @@ -/** - * \file gmake_solution_tests.cpp - * \brief Automated tests for GNU makefile solution processing. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "action/tests/action_tests.h" -extern "C" { -#include "action/make/make_solution.h" -} - - -SUITE(action) -{ - /********************************************************************** - * Signature tests - **********************************************************************/ - - TEST_FIXTURE(FxAction, Gmake_SolutionSignature_IsCorrect) - { - gmake_solution_signature(sess, sln, strm); - CHECK_EQUAL( - "# GNU Makefile autogenerated by Premake\n" - "# Usage: make [ CONFIG=config_name ]\n" - "# Where {config_name} is one of:\n" - "# Debug, Release\n" - "\n", - buffer); - } - - - /********************************************************************** - * Default configuration tests - **********************************************************************/ - - TEST_FIXTURE(FxAction, Gmake_SolutionDefaultConfig_IsCorrect) - { - gmake_solution_default_config(sess, sln, strm); - CHECK_EQUAL( - "ifndef CONFIG\n" - " CONFIG=Debug\n" - "endif\n" - "export CONFIG\n" - "\n", - buffer); - } - - - /********************************************************************** - * Phony rule tests - **********************************************************************/ - - TEST_FIXTURE(FxAction, Gmake_SolutionPhonyRule_IsCorrect) - { - gmake_solution_phony_rule(sess, sln, strm); - CHECK_EQUAL( - ".PHONY: all clean MyProject\n" - "\n", - buffer); - } - - - /********************************************************************** - * All rule tests - **********************************************************************/ - - TEST_FIXTURE(FxAction, Gmake_SolutionAllRule_IsCorrect) - { - gmake_solution_all_rule(sess, sln, strm); - CHECK_EQUAL( - "all: MyProject\n" - "\n", - buffer); - } - - - /********************************************************************** - * Project entry tests - **********************************************************************/ - - TEST_FIXTURE(FxAction, Gmake_ProjectEntry_InSameDirectory) - { - project_set_location(prj, ""); - gmake_solution_projects(sess, sln, strm); - CHECK_EQUAL( - "MyProject:\n" - "\t@echo ==== Building MyProject ====\n" - "\t@$(MAKE) -f MyProject.make\n" - "\n", - buffer); - } - - TEST_FIXTURE(FxAction, Gmake_ProjectEntry_InDifferentDirectory) - { - project_set_location(prj, "MyProject"); - gmake_solution_projects(sess, sln, strm); - CHECK_EQUAL( - "MyProject:\n" - "\t@echo ==== Building MyProject ====\n" - "\t@$(MAKE) --no-print-directory -C MyProject\n" - "\n", - buffer); - } - - - /********************************************************************** - * Clean rule tests - **********************************************************************/ - - TEST_FIXTURE(FxAction, Gmake_CleanRule_IsCorrect) - { - project_set_location(prj, ""); - gmake_solution_clean_rule(sess, sln, strm); - CHECK_EQUAL( - "clean:\n" - "\t@$(MAKE) -f MyProject.make clean\n", - buffer); - } - -} +/** + * \file gmake_solution_tests.cpp + * \brief Automated tests for GNU makefile solution processing. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "action/tests/action_tests.h" +extern "C" { +#include "action/make/make_solution.h" +} + + +SUITE(action) +{ + /********************************************************************** + * Signature tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Gmake_SolutionSignature_IsCorrect) + { + gmake_solution_signature(sess, sln, strm); + CHECK_EQUAL( + "# GNU Makefile autogenerated by Premake\n" + "# Usage: make [ CONFIG=config_name ]\n" + "# Where {config_name} is one of:\n" + "# Debug, Release\n" + "\n", + buffer); + } + + + /********************************************************************** + * Default configuration tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Gmake_SolutionDefaultConfig_IsCorrect) + { + gmake_solution_default_config(sess, sln, strm); + CHECK_EQUAL( + "ifndef CONFIG\n" + " CONFIG=Debug\n" + "endif\n" + "export CONFIG\n" + "\n", + buffer); + } + + + /********************************************************************** + * Phony rule tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Gmake_SolutionPhonyRule_IsCorrect) + { + gmake_solution_phony_rule(sess, sln, strm); + CHECK_EQUAL( + ".PHONY: all clean MyProject\n" + "\n", + buffer); + } + + + /********************************************************************** + * All rule tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Gmake_SolutionAllRule_IsCorrect) + { + gmake_solution_all_rule(sess, sln, strm); + CHECK_EQUAL( + "all: MyProject\n" + "\n", + buffer); + } + + + /********************************************************************** + * Project entry tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Gmake_ProjectEntry_InSameDirectory) + { + project_set_location(prj, ""); + gmake_solution_projects(sess, sln, strm); + CHECK_EQUAL( + "MyProject:\n" + "\t@echo ==== Building MyProject ====\n" + "\t@$(MAKE) -f MyProject.make\n" + "\n", + buffer); + } + + TEST_FIXTURE(FxAction, Gmake_ProjectEntry_InDifferentDirectory) + { + project_set_location(prj, "MyProject"); + gmake_solution_projects(sess, sln, strm); + CHECK_EQUAL( + "MyProject:\n" + "\t@echo ==== Building MyProject ====\n" + "\t@$(MAKE) --no-print-directory -C MyProject\n" + "\n", + buffer); + } + + + /********************************************************************** + * Clean rule tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Gmake_CleanRule_IsCorrect) + { + project_set_location(prj, ""); + gmake_solution_clean_rule(sess, sln, strm); + CHECK_EQUAL( + "clean:\n" + "\t@$(MAKE) -f MyProject.make clean\n", + buffer); + } + +} diff --git a/src/action/make/tests/make_solution_tests.cpp/make_solution_tests.cpp b/src/action/make/tests/make_solution_tests.cpp/make_solution_tests.cpp deleted file mode 100644 index 62ff1fc..0000000 --- a/src/action/make/tests/make_solution_tests.cpp/make_solution_tests.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/** - * \file make_solution_tests.cpp - * \brief Automated tests for makefile solution processing. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "testing/testing.h" -extern "C" { -#include "action/make/make_solution.h" -} - -struct FxMakeSln -{ - Session sess; - Stream strm; - Solution sln; - char buffer[8192]; - - FxMakeSln() - { - sess = session_create(); - - strm = stream_create_null(); - stream_set_buffer(strm, buffer); - - sln = solution_create(); - } - - ~FxMakeSln() - { - solution_destroy(sln); - stream_destroy(strm); - session_destroy(sess); - } -}; - - -SUITE(action) -{ - /********************************************************************** - * Signature tests - **********************************************************************/ - - TEST_FIXTURE(FxMakeSln, Signature_IsCorrect_OnGnuMake) - { - session_set_action(sess, "gmake"); - make_solution_signature(sess, sln, strm); - CHECK_EQUAL( - "# GNU Makefile autogenerated by Premake\n" - "# Usage: make [ CONFIG=config_name ]\n" - "# Where {config_name} is one of:\n", - buffer); - } - -} diff --git a/src/action/make/tests/make_tests.cpp b/src/action/make/tests/make_tests.cpp index 10c6ac6..789fd53 100644 --- a/src/action/make/tests/make_tests.cpp +++ b/src/action/make/tests/make_tests.cpp @@ -1,98 +1,98 @@ -/** - * \file make_tests.cpp - * \brief Automated tests for the makefile generator support functions. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "testing/testing.h" -extern "C" { -#include "action/make/make.h" -#include "base/error.h" -} - - -struct FxMake -{ - Session sess; - Solution sln1; - Solution sln2; - Project prj1; - Project prj2; - - FxMake() - { - sess = session_create(); - sln1 = AddSolution("MySolution1"); - sln2 = AddSolution("MySolution2"); - prj1 = AddProject("MyProject1"); - prj2 = AddProject("MyProject2"); - } - - ~FxMake() - { - session_destroy(sess); - error_clear(); - } - - Solution AddSolution(const char* name) - { - Solution sln = solution_create(); - session_add_solution(sess, sln); - solution_set_name(sln, name); - solution_set_base_dir(sln, "."); - return sln; - } - - Project AddProject(const char* name) - { - Project prj = project_create(); - solution_add_project(sln1, prj); - project_set_name(prj, name); - project_set_base_dir(prj, "."); - return prj; - } -}; - - -SUITE(action) -{ - /********************************************************************** - * Makefile naming tests - **********************************************************************/ - - TEST_FIXTURE(FxMake, GetSolutionMakefile_ReturnsMakefile_OnUniqueLocation) - { - solution_set_location(sln1, "MySolution"); - const char* result = make_get_solution_makefile(sess, sln1); - CHECK_EQUAL("./MySolution/Makefile", result); - } - - TEST_FIXTURE(FxMake, GetSolutionMakefile_ReturnsDotMake_OnSharedLocation) - { - const char* result = make_get_solution_makefile(sess, sln1); - CHECK_EQUAL("./MySolution1.make", result); - } - - TEST_FIXTURE(FxMake, GetProjectMakefile_ReturnsMakefile_OnUniqueLocation) - { - project_set_location(prj1, "MyProject"); - const char* result = make_get_project_makefile(sess, prj1); - CHECK_EQUAL("./MyProject/Makefile", result); - } - - TEST_FIXTURE(FxMake, GetProjectMakefile_ReturnsDotMake_OnSharedWithSolution) - { - project_set_location(prj2, "MyProject"); - const char* result = make_get_project_makefile(sess, prj1); - CHECK_EQUAL("./MyProject1.make", result); - } - - TEST_FIXTURE(FxMake, GetProjectMakefile_ReturnsDotMake_OnSharedWithProject) - { - project_set_location(prj1, "MyProject"); - project_set_location(prj2, "MyProject"); - const char* result = make_get_project_makefile(sess, prj1); - CHECK_EQUAL("./MyProject/MyProject1.make", result); - } -} +/** + * \file make_tests.cpp + * \brief Automated tests for the makefile generator support functions. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "testing/testing.h" +extern "C" { +#include "action/make/make.h" +#include "base/error.h" +} + + +struct FxMake +{ + Session sess; + Solution sln1; + Solution sln2; + Project prj1; + Project prj2; + + FxMake() + { + sess = session_create(); + sln1 = AddSolution("MySolution1"); + sln2 = AddSolution("MySolution2"); + prj1 = AddProject("MyProject1"); + prj2 = AddProject("MyProject2"); + } + + ~FxMake() + { + session_destroy(sess); + error_clear(); + } + + Solution AddSolution(const char* name) + { + Solution sln = solution_create(); + session_add_solution(sess, sln); + solution_set_name(sln, name); + solution_set_base_dir(sln, "."); + return sln; + } + + Project AddProject(const char* name) + { + Project prj = project_create(); + solution_add_project(sln1, prj); + project_set_name(prj, name); + project_set_base_dir(prj, "."); + return prj; + } +}; + + +SUITE(action) +{ + /********************************************************************** + * Makefile naming tests + **********************************************************************/ + + TEST_FIXTURE(FxMake, GetSolutionMakefile_ReturnsMakefile_OnUniqueLocation) + { + solution_set_location(sln1, "MySolution"); + const char* result = make_get_solution_makefile(sess, sln1); + CHECK_EQUAL("./MySolution/Makefile", result); + } + + TEST_FIXTURE(FxMake, GetSolutionMakefile_ReturnsDotMake_OnSharedLocation) + { + const char* result = make_get_solution_makefile(sess, sln1); + CHECK_EQUAL("./MySolution1.make", result); + } + + TEST_FIXTURE(FxMake, GetProjectMakefile_ReturnsMakefile_OnUniqueLocation) + { + project_set_location(prj1, "MyProject"); + const char* result = make_get_project_makefile(sess, prj1); + CHECK_EQUAL("./MyProject/Makefile", result); + } + + TEST_FIXTURE(FxMake, GetProjectMakefile_ReturnsDotMake_OnSharedWithSolution) + { + project_set_location(prj2, "MyProject"); + const char* result = make_get_project_makefile(sess, prj1); + CHECK_EQUAL("./MyProject1.make", result); + } + + TEST_FIXTURE(FxMake, GetProjectMakefile_ReturnsDotMake_OnSharedWithProject) + { + project_set_location(prj1, "MyProject"); + project_set_location(prj2, "MyProject"); + const char* result = make_get_project_makefile(sess, prj1); + CHECK_EQUAL("./MyProject/MyProject1.make", result); + } +} diff --git a/src/action/tests/action_tests.h b/src/action/tests/action_tests.h index 3e8a1fe..2765cda 100644 --- a/src/action/tests/action_tests.h +++ b/src/action/tests/action_tests.h @@ -1,63 +1,63 @@ -/** - * \file action_tests.h - * \brief Common test fixtures for all action tests. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "testing/testing.h" -extern "C" { -#include "session/session.h" -#include "project/project.h" -} - -struct FxAction -{ - Session sess; - Stream strm; - Solution sln; - Project prj; - char buffer[8192]; - - FxAction() - { - sess = session_create(); - - strm = stream_create_null(); - stream_set_buffer(strm, buffer); - session_set_active_stream(sess, strm); - - sln = solution_create(); - session_add_solution(sess, sln); - solution_set_name(sln, "MySolution"); - solution_set_base_dir(sln, "/Root"); - solution_add_config_name(sln, "Debug"); - solution_add_config_name(sln, "Release"); - - prj = project_create(); - solution_add_project(sln, prj); - project_set_name(prj, "MyProject"); - project_set_base_dir(prj, "/Root"); - project_set_location(prj, "ProjectFolder"); - project_set_guid(prj, "AE2461B7-236F-4278-81D3-F0D476F9A4C0"); - project_set_language(prj, "c++"); - project_set_configuration_filter(prj, "Debug"); - } - - ~FxAction() - { - stream_destroy(strm); - session_destroy(sess); - } - - - void SetField(Project prj, enum ProjectField index, char** values) - { - Strings strs = strings_create(); - for (char** value = values; (*value) != NULL; ++value) - { - strings_add(strs, *value); - } - - project_set_values(prj, index, strs); - } -}; +/** + * \file action_tests.h + * \brief Common test fixtures for all action tests. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "testing/testing.h" +extern "C" { +#include "session/session.h" +#include "project/project.h" +} + +struct FxAction +{ + Session sess; + Stream strm; + Solution sln; + Project prj; + char buffer[8192]; + + FxAction() + { + sess = session_create(); + + strm = stream_create_null(); + stream_set_buffer(strm, buffer); + session_set_active_stream(sess, strm); + + sln = solution_create(); + session_add_solution(sess, sln); + solution_set_name(sln, "MySolution"); + solution_set_base_dir(sln, "/Root"); + solution_add_config_name(sln, "Debug"); + solution_add_config_name(sln, "Release"); + + prj = project_create(); + solution_add_project(sln, prj); + project_set_name(prj, "MyProject"); + project_set_base_dir(prj, "/Root"); + project_set_location(prj, "ProjectFolder"); + project_set_guid(prj, "AE2461B7-236F-4278-81D3-F0D476F9A4C0"); + project_set_language(prj, "c++"); + project_set_configuration_filter(prj, "Debug"); + } + + ~FxAction() + { + stream_destroy(strm); + session_destroy(sess); + } + + + void SetField(Project prj, enum ProjectField index, char** values) + { + Strings strs = strings_create(); + for (char** value = values; (*value) != NULL; ++value) + { + strings_add(strs, *value); + } + + project_set_values(prj, index, strs); + } +}; diff --git a/src/action/vs200x/tests/vs2002_config_tests.cpp b/src/action/vs200x/tests/vs2002_config_tests.cpp index 8cfafe6..e3fe0d1 100644 --- a/src/action/vs200x/tests/vs2002_config_tests.cpp +++ b/src/action/vs200x/tests/vs2002_config_tests.cpp @@ -1,29 +1,29 @@ -/** - * \file vs2002_config_tests.cpp - * \brief Automated tests for VS2002 configuration processing. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "action/tests/action_tests.h" -extern "C" { -#include "action/vs200x/vs200x_config.h" -} - -struct Fx2002Config : FxAction -{ - Fx2002Config() - { - session_set_action(sess, "vs2002"); - } -}; - - -SUITE(action) -{ - TEST_FIXTURE(Fx2002Config, CharacterSet_Default) - { - vs200x_config_character_set(sess, strm); - CHECK_EQUAL("\n\t\t\tCharacterSet=\"2\"", buffer); - } -} +/** + * \file vs2002_config_tests.cpp + * \brief Automated tests for VS2002 configuration processing. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "action/tests/action_tests.h" +extern "C" { +#include "action/vs200x/vs200x_config.h" +} + +struct Fx2002Config : FxAction +{ + Fx2002Config() + { + session_set_action(sess, "vs2002"); + } +}; + + +SUITE(action) +{ + TEST_FIXTURE(Fx2002Config, CharacterSet_Default) + { + vs200x_config_character_set(sess, strm); + CHECK_EQUAL("\n\t\t\tCharacterSet=\"2\"", buffer); + } +} diff --git a/src/action/vs200x/tests/vs2002_project_tests.cpp b/src/action/vs200x/tests/vs2002_project_tests.cpp index aeb2006..e4704a0 100644 --- a/src/action/vs200x/tests/vs2002_project_tests.cpp +++ b/src/action/vs200x/tests/vs2002_project_tests.cpp @@ -1,88 +1,88 @@ -/** - * \file vs2002_project_tests.cpp - * \brief Automated tests for VS2002 project processing. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "action/tests/action_tests.h" -extern "C" { -#include "action/vs200x/vs200x_project.h" -} - -struct Fx2002Project : FxAction -{ - Fx2002Project() - { - session_set_action(sess, "vs2002"); - } -}; - - -SUITE(action) -{ - TEST_FIXTURE(Fx2002Project, Vs2002_VisualStudioProject) - { - vs200x_project_element(sess, prj, strm); - CHECK_EQUAL( - "\n", - buffer); - } - - - TEST_FIXTURE(Fx2002Project, Vs2002_ToolFiles) - { - vs200x_project_tool_files(sess, prj, strm); - CHECK_EQUAL( - "\t\n", - buffer); - } - - - TEST_FIXTURE(Fx2002Project, VCCLCompilerTool) - { - vs200x_project_vc_cl_compiler_tool(sess, prj, strm); - CHECK_EQUAL( - "\t\t\t\n", - buffer); - } - - - TEST_FIXTURE(Fx2002Project, VCLinkerTool) - { - vs200x_project_vc_linker_tool(sess, prj, strm); - CHECK_EQUAL( - "\t\t\t\n", - buffer); - } - - - TEST_FIXTURE(Fx2002Project, References) - { - vs200x_project_references(sess, prj, strm); - CHECK_EQUAL( - "\t\n", - buffer); - } -} +/** + * \file vs2002_project_tests.cpp + * \brief Automated tests for VS2002 project processing. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "action/tests/action_tests.h" +extern "C" { +#include "action/vs200x/vs200x_project.h" +} + +struct Fx2002Project : FxAction +{ + Fx2002Project() + { + session_set_action(sess, "vs2002"); + } +}; + + +SUITE(action) +{ + TEST_FIXTURE(Fx2002Project, Vs2002_VisualStudioProject) + { + vs200x_project_element(sess, prj, strm); + CHECK_EQUAL( + "\n", + buffer); + } + + + TEST_FIXTURE(Fx2002Project, Vs2002_ToolFiles) + { + vs200x_project_tool_files(sess, prj, strm); + CHECK_EQUAL( + "\t\n", + buffer); + } + + + TEST_FIXTURE(Fx2002Project, VCCLCompilerTool) + { + vs200x_project_vc_cl_compiler_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t\n", + buffer); + } + + + TEST_FIXTURE(Fx2002Project, VCLinkerTool) + { + vs200x_project_vc_linker_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t\n", + buffer); + } + + + TEST_FIXTURE(Fx2002Project, References) + { + vs200x_project_references(sess, prj, strm); + CHECK_EQUAL( + "\t\n", + buffer); + } +} diff --git a/src/action/vs200x/tests/vs2002_solution_tests.cpp b/src/action/vs200x/tests/vs2002_solution_tests.cpp index 97c352f..fb51c39 100644 --- a/src/action/vs200x/tests/vs2002_solution_tests.cpp +++ b/src/action/vs200x/tests/vs2002_solution_tests.cpp @@ -1,108 +1,108 @@ -/** - * \file vs2002_solution_tests.cpp - * \brief Automated tests for VS2002 solution processing. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "action/tests/action_tests.h" -extern "C" { -#include "action/vs200x/vs200x_solution.h" -} - - -SUITE(action) -{ - /********************************************************************** - * Signature tests - **********************************************************************/ - - TEST_FIXTURE(FxAction, Vs2002_Signature_IsCorrect) - { - vs2002_solution_signature(sess, sln, strm); - CHECK_EQUAL( - "Microsoft Visual Studio Solution File, Format Version 7.00\r\n", - buffer); - } - - - /********************************************************************** - * Project entry tests - **********************************************************************/ - - TEST_FIXTURE(FxAction, Vs2002_ProjectEntry_UsesRelativePath) - { - vs2002_solution_projects(sess, sln, strm); - CHECK_EQUAL( - "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"MyProject\", \"ProjectFolder\\MyProject.vcproj\", \"{AE2461B7-236F-4278-81D3-F0D476F9A4C0}\"\n" - "EndProject\n", - buffer); - } - - - /********************************************************************** - * Solution configuration tests - **********************************************************************/ - - TEST_FIXTURE(FxAction, Vs2002_SolutionConfiguration_IsCorrect) - { - vs2002_solution_configuration(sess, sln, strm); - CHECK_EQUAL( - "Global\n" - "\tGlobalSection(SolutionConfiguration) = preSolution\n" - "\t\tConfigName.0 = Debug\n" - "\t\tConfigName.1 = Release\n" - "\tEndGlobalSection\n", - buffer); - } - - - /********************************************************************** - * Project dependencies tests - **********************************************************************/ - - TEST_FIXTURE(FxAction, Vs2002_ProjectDependencies_IsCorrect) - { - vs2002_solution_dependencies(sess, sln, strm); - CHECK_EQUAL( - "\tGlobalSection(ProjectDependencies) = postSolution\n" - "\tEndGlobalSection\n", - buffer); - } - - - /********************************************************************** - * Project configuration tests - **********************************************************************/ - - TEST_FIXTURE(FxAction, Vs2002_ProjectConfiguration_IsCorrect) - { - vs2002_solution_project_configuration(sess, sln, strm); - CHECK_EQUAL( - "\tGlobalSection(ProjectConfiguration) = postSolution\n" - "\t\t{AE2461B7-236F-4278-81D3-F0D476F9A4C0}.Debug.ActiveCfg = Debug|Win32\n" - "\t\t{AE2461B7-236F-4278-81D3-F0D476F9A4C0}.Debug.Build.0 = Debug|Win32\n" - "\t\t{AE2461B7-236F-4278-81D3-F0D476F9A4C0}.Release.ActiveCfg = Release|Win32\n" - "\t\t{AE2461B7-236F-4278-81D3-F0D476F9A4C0}.Release.Build.0 = Release|Win32\n" - "\tEndGlobalSection\n", - buffer); - } - - - /********************************************************************** - * Solution extensibility tests - **********************************************************************/ - - TEST_FIXTURE(FxAction, Vs2002_Extensibility_IsCorrect) - { - vs2002_solution_extensibility(sess, sln, strm); - CHECK_EQUAL( - "\tGlobalSection(ExtensibilityGlobals) = postSolution\n" - "\tEndGlobalSection\n" - "\tGlobalSection(ExtensibilityAddIns) = postSolution\n" - "\tEndGlobalSection\n" - "EndGlobal\n", - buffer); - } - -} +/** + * \file vs2002_solution_tests.cpp + * \brief Automated tests for VS2002 solution processing. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "action/tests/action_tests.h" +extern "C" { +#include "action/vs200x/vs200x_solution.h" +} + + +SUITE(action) +{ + /********************************************************************** + * Signature tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Vs2002_Signature_IsCorrect) + { + vs2002_solution_signature(sess, sln, strm); + CHECK_EQUAL( + "Microsoft Visual Studio Solution File, Format Version 7.00\r\n", + buffer); + } + + + /********************************************************************** + * Project entry tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Vs2002_ProjectEntry_UsesRelativePath) + { + vs2002_solution_projects(sess, sln, strm); + CHECK_EQUAL( + "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"MyProject\", \"ProjectFolder\\MyProject.vcproj\", \"{AE2461B7-236F-4278-81D3-F0D476F9A4C0}\"\n" + "EndProject\n", + buffer); + } + + + /********************************************************************** + * Solution configuration tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Vs2002_SolutionConfiguration_IsCorrect) + { + vs2002_solution_configuration(sess, sln, strm); + CHECK_EQUAL( + "Global\n" + "\tGlobalSection(SolutionConfiguration) = preSolution\n" + "\t\tConfigName.0 = Debug\n" + "\t\tConfigName.1 = Release\n" + "\tEndGlobalSection\n", + buffer); + } + + + /********************************************************************** + * Project dependencies tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Vs2002_ProjectDependencies_IsCorrect) + { + vs2002_solution_dependencies(sess, sln, strm); + CHECK_EQUAL( + "\tGlobalSection(ProjectDependencies) = postSolution\n" + "\tEndGlobalSection\n", + buffer); + } + + + /********************************************************************** + * Project configuration tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Vs2002_ProjectConfiguration_IsCorrect) + { + vs2002_solution_project_configuration(sess, sln, strm); + CHECK_EQUAL( + "\tGlobalSection(ProjectConfiguration) = postSolution\n" + "\t\t{AE2461B7-236F-4278-81D3-F0D476F9A4C0}.Debug.ActiveCfg = Debug|Win32\n" + "\t\t{AE2461B7-236F-4278-81D3-F0D476F9A4C0}.Debug.Build.0 = Debug|Win32\n" + "\t\t{AE2461B7-236F-4278-81D3-F0D476F9A4C0}.Release.ActiveCfg = Release|Win32\n" + "\t\t{AE2461B7-236F-4278-81D3-F0D476F9A4C0}.Release.Build.0 = Release|Win32\n" + "\tEndGlobalSection\n", + buffer); + } + + + /********************************************************************** + * Solution extensibility tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Vs2002_Extensibility_IsCorrect) + { + vs2002_solution_extensibility(sess, sln, strm); + CHECK_EQUAL( + "\tGlobalSection(ExtensibilityGlobals) = postSolution\n" + "\tEndGlobalSection\n" + "\tGlobalSection(ExtensibilityAddIns) = postSolution\n" + "\tEndGlobalSection\n" + "EndGlobal\n", + buffer); + } + +} diff --git a/src/action/vs200x/tests/vs2003_config_tests.cpp b/src/action/vs200x/tests/vs2003_config_tests.cpp index 2b9b1a1..3c8e251 100644 --- a/src/action/vs200x/tests/vs2003_config_tests.cpp +++ b/src/action/vs200x/tests/vs2003_config_tests.cpp @@ -1,29 +1,29 @@ -/** - * \file vs2003_config_tests.cpp - * \brief Automated tests for VS2003 configuration processing. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "action/tests/action_tests.h" -extern "C" { -#include "action/vs200x/vs200x_config.h" -} - -struct Fx2003Config : FxAction -{ - Fx2003Config() - { - session_set_action(sess, "vs2003"); - } -}; - - -SUITE(action) -{ - TEST_FIXTURE(Fx2003Config, CharacterSet_Default) - { - vs200x_config_character_set(sess, strm); - CHECK_EQUAL("\n\t\t\tCharacterSet=\"2\"", buffer); - } -} +/** + * \file vs2003_config_tests.cpp + * \brief Automated tests for VS2003 configuration processing. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "action/tests/action_tests.h" +extern "C" { +#include "action/vs200x/vs200x_config.h" +} + +struct Fx2003Config : FxAction +{ + Fx2003Config() + { + session_set_action(sess, "vs2003"); + } +}; + + +SUITE(action) +{ + TEST_FIXTURE(Fx2003Config, CharacterSet_Default) + { + vs200x_config_character_set(sess, strm); + CHECK_EQUAL("\n\t\t\tCharacterSet=\"2\"", buffer); + } +} diff --git a/src/action/vs200x/tests/vs2003_project_tests.cpp b/src/action/vs200x/tests/vs2003_project_tests.cpp index c86043e..0cbb999 100644 --- a/src/action/vs200x/tests/vs2003_project_tests.cpp +++ b/src/action/vs200x/tests/vs2003_project_tests.cpp @@ -1,90 +1,90 @@ -/** - * \file vs2003_project_tests.cpp - * \brief Automated tests for VS2003 project processing. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "action/tests/action_tests.h" -extern "C" { -#include "action/vs200x/vs200x_project.h" -} - -struct Fx2003Project : FxAction -{ - Fx2003Project() - { - session_set_action(sess, "vs2003"); - } -}; - - -SUITE(action) -{ - TEST_FIXTURE(Fx2003Project, Vs2003_VisualStudioProject) - { - vs200x_project_element(sess, prj, strm); - CHECK_EQUAL( - "\n", - buffer); - } - - - TEST_FIXTURE(Fx2003Project, Vs2003_ToolFiles) - { - vs200x_project_tool_files(sess, prj, strm); - CHECK_EQUAL( - "\t\n", - buffer); - } - - - TEST_FIXTURE(Fx2003Project, VCCLCompilerTool) - { - vs200x_project_vc_cl_compiler_tool(sess, prj, strm); - CHECK_EQUAL( - "\t\t\t\n", - buffer); - } - - - TEST_FIXTURE(Fx2003Project, VCLinkerTool) - { - vs200x_project_vc_linker_tool(sess, prj, strm); - CHECK_EQUAL( - "\t\t\t\n", - buffer); - } - - - TEST_FIXTURE(Fx2003Project, References) - { - vs200x_project_references(sess, prj, strm); - CHECK_EQUAL( - "\t\n" - "\t\n" - "\t\n", - buffer); - } -} +/** + * \file vs2003_project_tests.cpp + * \brief Automated tests for VS2003 project processing. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "action/tests/action_tests.h" +extern "C" { +#include "action/vs200x/vs200x_project.h" +} + +struct Fx2003Project : FxAction +{ + Fx2003Project() + { + session_set_action(sess, "vs2003"); + } +}; + + +SUITE(action) +{ + TEST_FIXTURE(Fx2003Project, Vs2003_VisualStudioProject) + { + vs200x_project_element(sess, prj, strm); + CHECK_EQUAL( + "\n", + buffer); + } + + + TEST_FIXTURE(Fx2003Project, Vs2003_ToolFiles) + { + vs200x_project_tool_files(sess, prj, strm); + CHECK_EQUAL( + "\t\n", + buffer); + } + + + TEST_FIXTURE(Fx2003Project, VCCLCompilerTool) + { + vs200x_project_vc_cl_compiler_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t\n", + buffer); + } + + + TEST_FIXTURE(Fx2003Project, VCLinkerTool) + { + vs200x_project_vc_linker_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t\n", + buffer); + } + + + TEST_FIXTURE(Fx2003Project, References) + { + vs200x_project_references(sess, prj, strm); + CHECK_EQUAL( + "\t\n" + "\t\n" + "\t\n", + buffer); + } +} diff --git a/src/action/vs200x/tests/vs2003_solution_tests.cpp b/src/action/vs200x/tests/vs2003_solution_tests.cpp index ee4fa2b..f545e95 100644 --- a/src/action/vs200x/tests/vs2003_solution_tests.cpp +++ b/src/action/vs200x/tests/vs2003_solution_tests.cpp @@ -1,45 +1,45 @@ -/** - * \file vs2003_solution_tests.cpp - * \brief Automated tests for VS2003 solution processing. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "action/tests/action_tests.h" -extern "C" { -#include "action/vs200x/vs200x_solution.h" -} - - -SUITE(action) -{ - /********************************************************************** - * Signature tests - **********************************************************************/ - - TEST_FIXTURE(FxAction, Vs2003_Signature_IsCorrect) - { - vs2003_solution_signature(sess, sln, strm); - CHECK_EQUAL( - "Microsoft Visual Studio Solution File, Format Version 8.00\r\n", - buffer); - } - - - /********************************************************************** - * Solution configuration tests - **********************************************************************/ - - TEST_FIXTURE(FxAction, Vs2003_SolutionConfiguration_IsCorrect) - { - vs2003_solution_configuration(sess, sln, strm); - CHECK_EQUAL( - "Global\n" - "\tGlobalSection(SolutionConfiguration) = preSolution\n" - "\t\tDebug = Debug\n" - "\t\tRelease = Release\n" - "\tEndGlobalSection\n", - buffer); - } - -} +/** + * \file vs2003_solution_tests.cpp + * \brief Automated tests for VS2003 solution processing. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "action/tests/action_tests.h" +extern "C" { +#include "action/vs200x/vs200x_solution.h" +} + + +SUITE(action) +{ + /********************************************************************** + * Signature tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Vs2003_Signature_IsCorrect) + { + vs2003_solution_signature(sess, sln, strm); + CHECK_EQUAL( + "Microsoft Visual Studio Solution File, Format Version 8.00\r\n", + buffer); + } + + + /********************************************************************** + * Solution configuration tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Vs2003_SolutionConfiguration_IsCorrect) + { + vs2003_solution_configuration(sess, sln, strm); + CHECK_EQUAL( + "Global\n" + "\tGlobalSection(SolutionConfiguration) = preSolution\n" + "\t\tDebug = Debug\n" + "\t\tRelease = Release\n" + "\tEndGlobalSection\n", + buffer); + } + +} diff --git a/src/action/vs200x/tests/vs2005_config_tests.cpp b/src/action/vs200x/tests/vs2005_config_tests.cpp index 68f6404..7711643 100644 --- a/src/action/vs200x/tests/vs2005_config_tests.cpp +++ b/src/action/vs200x/tests/vs2005_config_tests.cpp @@ -1,29 +1,29 @@ -/** - * \file vs2005_config_tests.cpp - * \brief Automated tests for VS2005 configuration processing. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "action/tests/action_tests.h" -extern "C" { -#include "action/vs200x/vs200x_config.h" -} - -struct Fx2005Config : FxAction -{ - Fx2005Config() - { - session_set_action(sess, "vs2005"); - } -}; - - -SUITE(action) -{ - TEST_FIXTURE(Fx2005Config, CharacterSet_Default) - { - vs200x_config_character_set(sess, strm); - CHECK_EQUAL("\n\t\t\tCharacterSet=\"1\"", buffer); - } -} +/** + * \file vs2005_config_tests.cpp + * \brief Automated tests for VS2005 configuration processing. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "action/tests/action_tests.h" +extern "C" { +#include "action/vs200x/vs200x_config.h" +} + +struct Fx2005Config : FxAction +{ + Fx2005Config() + { + session_set_action(sess, "vs2005"); + } +}; + + +SUITE(action) +{ + TEST_FIXTURE(Fx2005Config, CharacterSet_Default) + { + vs200x_config_character_set(sess, strm); + CHECK_EQUAL("\n\t\t\tCharacterSet=\"1\"", buffer); + } +} diff --git a/src/action/vs200x/tests/vs2005_project_tests.cpp b/src/action/vs200x/tests/vs2005_project_tests.cpp index 8729316..2568c35 100644 --- a/src/action/vs200x/tests/vs2005_project_tests.cpp +++ b/src/action/vs200x/tests/vs2005_project_tests.cpp @@ -1,95 +1,95 @@ -/** - * \file vs2005_project_tests.cpp - * \brief Automated tests for VS2005 project processing. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "action/tests/action_tests.h" -extern "C" { -#include "action/vs200x/vs200x_project.h" -} - -struct Fx2005Project : FxAction -{ - Fx2005Project() - { - session_set_action(sess, "vs2005"); - } -}; - - -SUITE(action) -{ - TEST_FIXTURE(Fx2005Project, Vs2005_VisualStudioProject) - { - vs200x_project_element(sess, prj, strm); - CHECK_EQUAL( - "\n", - buffer); - } - - - TEST_FIXTURE(Fx2005Project, Vs2005_ToolFiles) - { - vs200x_project_tool_files(sess, prj, strm); - CHECK_EQUAL( - "\t\n" - "\t\n" - "\t\n", - buffer); - } - - - TEST_FIXTURE(Fx2005Project, VCCLCompilerTool) - { - vs200x_project_vc_cl_compiler_tool(sess, prj, strm); - CHECK_EQUAL( - "\t\t\t\n", - buffer); - } - - - TEST_FIXTURE(Fx2005Project, VCLinkerTool) - { - vs200x_project_vc_linker_tool(sess, prj, strm); - CHECK_EQUAL( - "\t\t\t\n", - buffer); - } - - - TEST_FIXTURE(Fx2005Project, References) - { - vs200x_project_references(sess, prj, strm); - CHECK_EQUAL( - "\t\n" - "\t\n" - "\t\n", - buffer); - } -} +/** + * \file vs2005_project_tests.cpp + * \brief Automated tests for VS2005 project processing. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "action/tests/action_tests.h" +extern "C" { +#include "action/vs200x/vs200x_project.h" +} + +struct Fx2005Project : FxAction +{ + Fx2005Project() + { + session_set_action(sess, "vs2005"); + } +}; + + +SUITE(action) +{ + TEST_FIXTURE(Fx2005Project, Vs2005_VisualStudioProject) + { + vs200x_project_element(sess, prj, strm); + CHECK_EQUAL( + "\n", + buffer); + } + + + TEST_FIXTURE(Fx2005Project, Vs2005_ToolFiles) + { + vs200x_project_tool_files(sess, prj, strm); + CHECK_EQUAL( + "\t\n" + "\t\n" + "\t\n", + buffer); + } + + + TEST_FIXTURE(Fx2005Project, VCCLCompilerTool) + { + vs200x_project_vc_cl_compiler_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t\n", + buffer); + } + + + TEST_FIXTURE(Fx2005Project, VCLinkerTool) + { + vs200x_project_vc_linker_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t\n", + buffer); + } + + + TEST_FIXTURE(Fx2005Project, References) + { + vs200x_project_references(sess, prj, strm); + CHECK_EQUAL( + "\t\n" + "\t\n" + "\t\n", + buffer); + } +} diff --git a/src/action/vs200x/tests/vs2005_solution_tests.cpp b/src/action/vs200x/tests/vs2005_solution_tests.cpp index 416572a..5cfcbee 100644 --- a/src/action/vs200x/tests/vs2005_solution_tests.cpp +++ b/src/action/vs200x/tests/vs2005_solution_tests.cpp @@ -1,80 +1,80 @@ -/** - * \file vs2005_solution_tests.cpp - * \brief Automated tests for VS2005 solution processing. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "action/tests/action_tests.h" -extern "C" { -#include "action/vs200x/vs200x_solution.h" -} - - -SUITE(action) -{ - /********************************************************************** - * Signature tests - **********************************************************************/ - - TEST_FIXTURE(FxAction, Vs2005_Signature_IsCorrect) - { - vs2005_solution_signature(sess, sln, strm); - CHECK_EQUAL( - "\357\273\277\r\n" - "Microsoft Visual Studio Solution File, Format Version 9.00\r\n" - "# Visual Studio 2005\r\n", - buffer); - } - - - /********************************************************************** - * Solution Configuration Platforms tests - **********************************************************************/ - - TEST_FIXTURE(FxAction, Platforms_IsCorrect) - { - vs2005_solution_platforms(sess, sln, strm); - CHECK_EQUAL( - "Global\n" - "\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n" - "\t\tDebug|Win32 = Debug|Win32\n" - "\t\tRelease|Win32 = Release|Win32\n" - "\tEndGlobalSection\n", - buffer); - } - - - /********************************************************************** - * Project Configuration Platforms tests - **********************************************************************/ - - TEST_FIXTURE(FxAction, ProjectPlatforms_IsCorrect) - { - vs2005_solution_project_platforms(sess, sln, strm); - CHECK_EQUAL( - "\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n" - "\t\t{AE2461B7-236F-4278-81D3-F0D476F9A4C0}.Debug|Win32.ActiveCfg = Debug|Win32\n" - "\t\t{AE2461B7-236F-4278-81D3-F0D476F9A4C0}.Debug|Win32.Build.0 = Debug|Win32\n" - "\t\t{AE2461B7-236F-4278-81D3-F0D476F9A4C0}.Release|Win32.ActiveCfg = Release|Win32\n" - "\t\t{AE2461B7-236F-4278-81D3-F0D476F9A4C0}.Release|Win32.Build.0 = Release|Win32\n" - "\tEndGlobalSection\n", - buffer); - } - - - /********************************************************************** - * Solution Project tests - **********************************************************************/ - - TEST_FIXTURE(FxAction, Properties_IsCorrect) - { - vs2005_solution_properties(sess, sln, strm); - CHECK_EQUAL( - "\tGlobalSection(SolutionProperties) = preSolution\n" - "\t\tHideSolutionNode = FALSE\n" - "\tEndGlobalSection\n" - "EndGlobal\n", - buffer); - } -} +/** + * \file vs2005_solution_tests.cpp + * \brief Automated tests for VS2005 solution processing. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "action/tests/action_tests.h" +extern "C" { +#include "action/vs200x/vs200x_solution.h" +} + + +SUITE(action) +{ + /********************************************************************** + * Signature tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Vs2005_Signature_IsCorrect) + { + vs2005_solution_signature(sess, sln, strm); + CHECK_EQUAL( + "\357\273\277\r\n" + "Microsoft Visual Studio Solution File, Format Version 9.00\r\n" + "# Visual Studio 2005\r\n", + buffer); + } + + + /********************************************************************** + * Solution Configuration Platforms tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Platforms_IsCorrect) + { + vs2005_solution_platforms(sess, sln, strm); + CHECK_EQUAL( + "Global\n" + "\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n" + "\t\tDebug|Win32 = Debug|Win32\n" + "\t\tRelease|Win32 = Release|Win32\n" + "\tEndGlobalSection\n", + buffer); + } + + + /********************************************************************** + * Project Configuration Platforms tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, ProjectPlatforms_IsCorrect) + { + vs2005_solution_project_platforms(sess, sln, strm); + CHECK_EQUAL( + "\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n" + "\t\t{AE2461B7-236F-4278-81D3-F0D476F9A4C0}.Debug|Win32.ActiveCfg = Debug|Win32\n" + "\t\t{AE2461B7-236F-4278-81D3-F0D476F9A4C0}.Debug|Win32.Build.0 = Debug|Win32\n" + "\t\t{AE2461B7-236F-4278-81D3-F0D476F9A4C0}.Release|Win32.ActiveCfg = Release|Win32\n" + "\t\t{AE2461B7-236F-4278-81D3-F0D476F9A4C0}.Release|Win32.Build.0 = Release|Win32\n" + "\tEndGlobalSection\n", + buffer); + } + + + /********************************************************************** + * Solution Project tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Properties_IsCorrect) + { + vs2005_solution_properties(sess, sln, strm); + CHECK_EQUAL( + "\tGlobalSection(SolutionProperties) = preSolution\n" + "\t\tHideSolutionNode = FALSE\n" + "\tEndGlobalSection\n" + "EndGlobal\n", + buffer); + } +} diff --git a/src/action/vs200x/tests/vs2008_config_tests.cpp b/src/action/vs200x/tests/vs2008_config_tests.cpp index 2a9a7fd..e2c45a3 100644 --- a/src/action/vs200x/tests/vs2008_config_tests.cpp +++ b/src/action/vs200x/tests/vs2008_config_tests.cpp @@ -1,29 +1,29 @@ -/** - * \file vs2008_config_tests.cpp - * \brief Automated tests for VS2008 configuration processing. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "action/tests/action_tests.h" -extern "C" { -#include "action/vs200x/vs200x_config.h" -} - -struct Fx2008Config : FxAction -{ - Fx2008Config() - { - session_set_action(sess, "vs2008"); - } -}; - - -SUITE(action) -{ - TEST_FIXTURE(Fx2008Config, CharacterSet_Default) - { - vs200x_config_character_set(sess, strm); - CHECK_EQUAL("\n\t\t\tCharacterSet=\"1\"", buffer); - } -} +/** + * \file vs2008_config_tests.cpp + * \brief Automated tests for VS2008 configuration processing. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "action/tests/action_tests.h" +extern "C" { +#include "action/vs200x/vs200x_config.h" +} + +struct Fx2008Config : FxAction +{ + Fx2008Config() + { + session_set_action(sess, "vs2008"); + } +}; + + +SUITE(action) +{ + TEST_FIXTURE(Fx2008Config, CharacterSet_Default) + { + vs200x_config_character_set(sess, strm); + CHECK_EQUAL("\n\t\t\tCharacterSet=\"1\"", buffer); + } +} diff --git a/src/action/vs200x/tests/vs2008_project_tests.cpp b/src/action/vs200x/tests/vs2008_project_tests.cpp index 8b665c6..ffcdad1 100644 --- a/src/action/vs200x/tests/vs2008_project_tests.cpp +++ b/src/action/vs200x/tests/vs2008_project_tests.cpp @@ -1,95 +1,95 @@ -/** - * \file vs2008_project_tests.cpp - * \brief Automated tests for VS2008 project processing. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "action/tests/action_tests.h" -extern "C" { -#include "action/vs200x/vs200x_project.h" -} - -struct Fx2008Project : FxAction -{ - Fx2008Project() - { - session_set_action(sess, "vs2008"); - } -}; - - -SUITE(action) -{ - TEST_FIXTURE(Fx2008Project, Vs2008_VisualStudioProject) - { - vs200x_project_element(sess, prj, strm); - CHECK_EQUAL( - "\n", - buffer); - } - - - TEST_FIXTURE(Fx2008Project, Vs2008_ToolFiles) - { - vs200x_project_tool_files(sess, prj, strm); - CHECK_EQUAL( - "\t\n" - "\t\n" - "\t\n", - buffer); - } - - - TEST_FIXTURE(Fx2008Project, VCCLCompilerTool) - { - vs200x_project_vc_cl_compiler_tool(sess, prj, strm); - CHECK_EQUAL( - "\t\t\t\n", - buffer); - } - - - TEST_FIXTURE(Fx2008Project, VCLinkerTool) - { - vs200x_project_vc_linker_tool(sess, prj, strm); - CHECK_EQUAL( - "\t\t\t\n", - buffer); - } - - - TEST_FIXTURE(Fx2008Project, References) - { - vs200x_project_references(sess, prj, strm); - CHECK_EQUAL( - "\t\n" - "\t\n" - "\t\n", - buffer); - } -} +/** + * \file vs2008_project_tests.cpp + * \brief Automated tests for VS2008 project processing. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "action/tests/action_tests.h" +extern "C" { +#include "action/vs200x/vs200x_project.h" +} + +struct Fx2008Project : FxAction +{ + Fx2008Project() + { + session_set_action(sess, "vs2008"); + } +}; + + +SUITE(action) +{ + TEST_FIXTURE(Fx2008Project, Vs2008_VisualStudioProject) + { + vs200x_project_element(sess, prj, strm); + CHECK_EQUAL( + "\n", + buffer); + } + + + TEST_FIXTURE(Fx2008Project, Vs2008_ToolFiles) + { + vs200x_project_tool_files(sess, prj, strm); + CHECK_EQUAL( + "\t\n" + "\t\n" + "\t\n", + buffer); + } + + + TEST_FIXTURE(Fx2008Project, VCCLCompilerTool) + { + vs200x_project_vc_cl_compiler_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t\n", + buffer); + } + + + TEST_FIXTURE(Fx2008Project, VCLinkerTool) + { + vs200x_project_vc_linker_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t\n", + buffer); + } + + + TEST_FIXTURE(Fx2008Project, References) + { + vs200x_project_references(sess, prj, strm); + CHECK_EQUAL( + "\t\n" + "\t\n" + "\t\n", + buffer); + } +} diff --git a/src/action/vs200x/tests/vs2008_solution_tests.cpp b/src/action/vs200x/tests/vs2008_solution_tests.cpp index aefb249..dd324c2 100644 --- a/src/action/vs200x/tests/vs2008_solution_tests.cpp +++ b/src/action/vs200x/tests/vs2008_solution_tests.cpp @@ -1,30 +1,30 @@ -/** - * \file vs2008_solution_tests.cpp - * \brief Automated tests for VS2008 solution processing. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "action/tests/action_tests.h" -extern "C" { -#include "action/vs200x/vs200x_solution.h" -} - - -SUITE(action) -{ - /********************************************************************** - * Signature tests - **********************************************************************/ - - TEST_FIXTURE(FxAction, Vs2008_Signature_IsCorrect) - { - vs2008_solution_signature(sess, sln, strm); - CHECK_EQUAL( - "\357\273\277\r\n" - "Microsoft Visual Studio Solution File, Format Version 10.00\r\n" - "# Visual Studio 2008\r\n", - buffer); - } - -} +/** + * \file vs2008_solution_tests.cpp + * \brief Automated tests for VS2008 solution processing. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "action/tests/action_tests.h" +extern "C" { +#include "action/vs200x/vs200x_solution.h" +} + + +SUITE(action) +{ + /********************************************************************** + * Signature tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Vs2008_Signature_IsCorrect) + { + vs2008_solution_signature(sess, sln, strm); + CHECK_EQUAL( + "\357\273\277\r\n" + "Microsoft Visual Studio Solution File, Format Version 10.00\r\n" + "# Visual Studio 2008\r\n", + buffer); + } + +} diff --git a/src/action/vs200x/tests/vs200x_project_tests.cpp b/src/action/vs200x/tests/vs200x_project_tests.cpp index 8cded2a..f919b81 100644 --- a/src/action/vs200x/tests/vs200x_project_tests.cpp +++ b/src/action/vs200x/tests/vs200x_project_tests.cpp @@ -1,294 +1,294 @@ -/** - * \file vs200x_project_tests.cpp - * \brief Automated tests for Visual Studio project processing. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "action/tests/action_tests.h" -extern "C" { -#include "action/vs200x/vs200x_project.h" -} - - -struct FxVsProject : FxAction -{ - FxVsProject() - { - session_set_action(sess, "vs2002"); - } -}; - - -SUITE(action) -{ - /********************************************************************** - * Configuration element tests - **********************************************************************/ - - TEST_FIXTURE(FxVsProject, Vs200x_Configuration) - { - vs200x_project_config_element(sess, prj, strm); - CHECK_EQUAL( - "\t\t\n", - buffer); - } - - - /********************************************************************** - * Encoding tests - **********************************************************************/ - - TEST_FIXTURE(FxAction, Vs200x_Encoding) - { - vs200x_project_encoding(sess, prj, strm); - CHECK_EQUAL( - "\r\n", - buffer); - } - - - /********************************************************************** - * Platforms tests - **********************************************************************/ - - TEST_FIXTURE(FxVsProject, Vs200x_Platforms) - { - vs200x_project_platforms(sess, prj, strm); - CHECK_EQUAL( - "\t\n" - "\t\t\n" - "\t\n", - buffer); - } - - - /********************************************************************** - * Tool element tests - **********************************************************************/ - - TEST_FIXTURE(FxVsProject, Vs200x_VCALinkTool) - { - vs200x_project_vc_alink_tool(sess, prj, strm); - CHECK_EQUAL( - "\t\t\t\n", - buffer); - } - - TEST_FIXTURE(FxVsProject, Vs200x_VCAppVerifierTool) - { - vs200x_project_vc_app_verifier_tool(sess, prj, strm); - CHECK_EQUAL( - "\t\t\t\n", - buffer); - } - - TEST_FIXTURE(FxVsProject, Vs200x_VCBscMakeTool) - { - vs200x_project_vc_bsc_make_tool(sess, prj, strm); - CHECK_EQUAL( - "\t\t\t\n", - buffer); - } - - TEST_FIXTURE(FxVsProject, Vs200x_VCCustomBuildTool) - { - vs200x_project_vc_custom_build_tool(sess, prj, strm); - CHECK_EQUAL( - "\t\t\t\n", - buffer); - } - - TEST_FIXTURE(FxVsProject, Vs200x_VCFxCopTool) - { - vs200x_project_vc_fx_cop_tool(sess, prj, strm); - CHECK_EQUAL( - "\t\t\t\n", - buffer); - } - - TEST_FIXTURE(FxVsProject, Vs200x_VCManagedResourceCompilerTool) - { - vs200x_project_vc_managed_resource_compiler_tool(sess, prj, strm); - CHECK_EQUAL( - "\t\t\t\n", - buffer); - } - - TEST_FIXTURE(FxVsProject, Vs200x_VCManifestTool) - { - vs200x_project_vc_manifest_tool(sess, prj, strm); - CHECK_EQUAL( - "\t\t\t\n", - buffer); - } - - TEST_FIXTURE(FxVsProject, Vs200x_VCMIDLTool) - { - vs200x_project_vc_midl_tool(sess, prj, strm); - CHECK_EQUAL( - "\t\t\t\n", - buffer); - } - - TEST_FIXTURE(FxVsProject, Vs200x_VCPreBuildEventTool) - { - vs200x_project_vc_pre_build_event_tool(sess, prj, strm); - CHECK_EQUAL( - "\t\t\t\n", - buffer); - } - - TEST_FIXTURE(FxVsProject, Vs200x_VCPreLinkEventTool) - { - vs200x_project_vc_pre_link_event_tool(sess, prj, strm); - CHECK_EQUAL( - "\t\t\t\n", - buffer); - } - - TEST_FIXTURE(FxVsProject, Vs200x_VCPostBuildEventTool) - { - vs200x_project_vc_post_build_event_tool(sess, prj, strm); - CHECK_EQUAL( - "\t\t\t\n", - buffer); - } - - TEST_FIXTURE(FxVsProject, Vs200x_VCResourceCompilerTool) - { - vs200x_project_vc_resource_compiler_tool(sess, prj, strm); - CHECK_EQUAL( - "\t\t\t\n", - buffer); - } - - TEST_FIXTURE(FxVsProject, Vs200x_VCWebDeploymentTool) - { - vs200x_project_vc_web_deployment_tool(sess, prj, strm); - CHECK_EQUAL( - "\t\t\t\n", - buffer); - } - - TEST_FIXTURE(FxVsProject, Vs200x_VCWebServiceProxyGeneratorTool) - { - vs200x_project_vc_web_service_proxy_generator_tool(sess, prj, strm); - CHECK_EQUAL( - "\t\t\t\n", - buffer); - } - - TEST_FIXTURE(FxVsProject, Vs200x_VCXDCMakeTool) - { - vs200x_project_vc_xdc_make_tool(sess, prj, strm); - CHECK_EQUAL( - "\t\t\t\n", - buffer); - } - - TEST_FIXTURE(FxVsProject, Vs200x_VCXMLDataGeneratorTool) - { - vs200x_project_vc_xml_data_generator_tool(sess, prj, strm); - CHECK_EQUAL( - "\t\t\t\n", - buffer); - } - - - /********************************************************************** - * Files section tests - **********************************************************************/ - - TEST_FIXTURE(FxVsProject, Vs200x_Files_OnNoFiles) - { - vs200x_project_files(sess, prj, strm); - CHECK_EQUAL( - "\t\n" - "\t\n", - buffer); - } - - TEST_FIXTURE(FxVsProject, Vs200x_Files_OnSingleCppFile) - { - char* values[] = { "Hello.cpp", 0 }; - SetField(prj, ProjectFiles, values); - vs200x_project_files(sess, prj, strm); - CHECK_EQUAL( - "\t\n" - "\t\t\n" - "\t\t\n" - "\t\n", - buffer); - } - - TEST_FIXTURE(FxVsProject, Vs200x_Files_OnUpperDirectory) - { - char* values[] = { "../../Hello.cpp", 0 }; - SetField(prj, ProjectFiles, values); - vs200x_project_files(sess, prj, strm); - CHECK_EQUAL( - "\t\n" - "\t\t\n" - "\t\t\n" - "\t\n", - buffer); - } - - TEST_FIXTURE(FxVsProject, Vs200x_Files_OnGroupedCppFile) - { - char* values[] = { "Src/Hello.cpp", 0 }; - SetField(prj, ProjectFiles, values); - vs200x_project_files(sess, prj, strm); - CHECK_EQUAL( - "\t\n" - "\t\t\n" - "\t\t\t\n" - "\t\t\t\n" - "\t\t\n" - "\t\n", - buffer); - } - - - /********************************************************************** - * Globals section tests - **********************************************************************/ - - TEST_FIXTURE(FxVsProject, Vs200x_Globals) - { - vs200x_project_globals(sess, prj, strm); - CHECK_EQUAL( - "\t\n" - "\t\n" - "\n", - buffer); - } -} +/** + * \file vs200x_project_tests.cpp + * \brief Automated tests for Visual Studio project processing. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "action/tests/action_tests.h" +extern "C" { +#include "action/vs200x/vs200x_project.h" +} + + +struct FxVsProject : FxAction +{ + FxVsProject() + { + session_set_action(sess, "vs2002"); + } +}; + + +SUITE(action) +{ + /********************************************************************** + * Configuration element tests + **********************************************************************/ + + TEST_FIXTURE(FxVsProject, Vs200x_Configuration) + { + vs200x_project_config_element(sess, prj, strm); + CHECK_EQUAL( + "\t\t\n", + buffer); + } + + + /********************************************************************** + * Encoding tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Vs200x_Encoding) + { + vs200x_project_encoding(sess, prj, strm); + CHECK_EQUAL( + "\r\n", + buffer); + } + + + /********************************************************************** + * Platforms tests + **********************************************************************/ + + TEST_FIXTURE(FxVsProject, Vs200x_Platforms) + { + vs200x_project_platforms(sess, prj, strm); + CHECK_EQUAL( + "\t\n" + "\t\t\n" + "\t\n", + buffer); + } + + + /********************************************************************** + * Tool element tests + **********************************************************************/ + + TEST_FIXTURE(FxVsProject, Vs200x_VCALinkTool) + { + vs200x_project_vc_alink_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t\n", + buffer); + } + + TEST_FIXTURE(FxVsProject, Vs200x_VCAppVerifierTool) + { + vs200x_project_vc_app_verifier_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t\n", + buffer); + } + + TEST_FIXTURE(FxVsProject, Vs200x_VCBscMakeTool) + { + vs200x_project_vc_bsc_make_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t\n", + buffer); + } + + TEST_FIXTURE(FxVsProject, Vs200x_VCCustomBuildTool) + { + vs200x_project_vc_custom_build_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t\n", + buffer); + } + + TEST_FIXTURE(FxVsProject, Vs200x_VCFxCopTool) + { + vs200x_project_vc_fx_cop_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t\n", + buffer); + } + + TEST_FIXTURE(FxVsProject, Vs200x_VCManagedResourceCompilerTool) + { + vs200x_project_vc_managed_resource_compiler_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t\n", + buffer); + } + + TEST_FIXTURE(FxVsProject, Vs200x_VCManifestTool) + { + vs200x_project_vc_manifest_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t\n", + buffer); + } + + TEST_FIXTURE(FxVsProject, Vs200x_VCMIDLTool) + { + vs200x_project_vc_midl_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t\n", + buffer); + } + + TEST_FIXTURE(FxVsProject, Vs200x_VCPreBuildEventTool) + { + vs200x_project_vc_pre_build_event_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t\n", + buffer); + } + + TEST_FIXTURE(FxVsProject, Vs200x_VCPreLinkEventTool) + { + vs200x_project_vc_pre_link_event_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t\n", + buffer); + } + + TEST_FIXTURE(FxVsProject, Vs200x_VCPostBuildEventTool) + { + vs200x_project_vc_post_build_event_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t\n", + buffer); + } + + TEST_FIXTURE(FxVsProject, Vs200x_VCResourceCompilerTool) + { + vs200x_project_vc_resource_compiler_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t\n", + buffer); + } + + TEST_FIXTURE(FxVsProject, Vs200x_VCWebDeploymentTool) + { + vs200x_project_vc_web_deployment_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t\n", + buffer); + } + + TEST_FIXTURE(FxVsProject, Vs200x_VCWebServiceProxyGeneratorTool) + { + vs200x_project_vc_web_service_proxy_generator_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t\n", + buffer); + } + + TEST_FIXTURE(FxVsProject, Vs200x_VCXDCMakeTool) + { + vs200x_project_vc_xdc_make_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t\n", + buffer); + } + + TEST_FIXTURE(FxVsProject, Vs200x_VCXMLDataGeneratorTool) + { + vs200x_project_vc_xml_data_generator_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t\n", + buffer); + } + + + /********************************************************************** + * Files section tests + **********************************************************************/ + + TEST_FIXTURE(FxVsProject, Vs200x_Files_OnNoFiles) + { + vs200x_project_files(sess, prj, strm); + CHECK_EQUAL( + "\t\n" + "\t\n", + buffer); + } + + TEST_FIXTURE(FxVsProject, Vs200x_Files_OnSingleCppFile) + { + char* values[] = { "Hello.cpp", 0 }; + SetField(prj, ProjectFiles, values); + vs200x_project_files(sess, prj, strm); + CHECK_EQUAL( + "\t\n" + "\t\t\n" + "\t\t\n" + "\t\n", + buffer); + } + + TEST_FIXTURE(FxVsProject, Vs200x_Files_OnUpperDirectory) + { + char* values[] = { "../../Hello.cpp", 0 }; + SetField(prj, ProjectFiles, values); + vs200x_project_files(sess, prj, strm); + CHECK_EQUAL( + "\t\n" + "\t\t\n" + "\t\t\n" + "\t\n", + buffer); + } + + TEST_FIXTURE(FxVsProject, Vs200x_Files_OnGroupedCppFile) + { + char* values[] = { "Src/Hello.cpp", 0 }; + SetField(prj, ProjectFiles, values); + vs200x_project_files(sess, prj, strm); + CHECK_EQUAL( + "\t\n" + "\t\t\n" + "\t\t\t\n" + "\t\t\t\n" + "\t\t\n" + "\t\n", + buffer); + } + + + /********************************************************************** + * Globals section tests + **********************************************************************/ + + TEST_FIXTURE(FxVsProject, Vs200x_Globals) + { + vs200x_project_globals(sess, prj, strm); + CHECK_EQUAL( + "\t\n" + "\t\n" + "\n", + buffer); + } +} diff --git a/src/action/vs200x/tests/vs200x_tests.cpp b/src/action/vs200x/tests/vs200x_tests.cpp index 54e385b..2f3d62f 100644 --- a/src/action/vs200x/tests/vs200x_tests.cpp +++ b/src/action/vs200x/tests/vs200x_tests.cpp @@ -1,49 +1,49 @@ -/** - * \file vs200x_tests.cpp - * \brief Automated tests for VS200x support functions. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "action/tests/action_tests.h" -extern "C" { -#include "action/vs200x/vs200x.h" -} - - -SUITE(action) -{ - /********************************************************************** - * Language GUID tests - **********************************************************************/ - - TEST(ToolGuid_ReturnsCorrectGUID_OnC) - { - const char* result = vs200x_tool_guid("c"); - CHECK_EQUAL("8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942", result); - } - - TEST(ToolGuid_ReturnsCorrectGUID_OnCpp) - { - const char* result = vs200x_tool_guid("c++"); - CHECK_EQUAL("8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942", result); - } - - TEST(ToolGuid_ReturnsCorrectGUID_OnCSharp) - { - const char* result = vs200x_tool_guid("c#"); - CHECK_EQUAL("FAE04EC0-301F-11D3-BF4B-00C04F79EFBC", result); - } - - - /********************************************************************** - * Language file extensions - **********************************************************************/ - - TEST_FIXTURE(FxAction, ProjectExtension_IsVcproj_ForC) - { - project_set_language(prj, "c"); - const char* result = vs200x_project_file_extension(prj); - CHECK_EQUAL(".vcproj", result); - } -} +/** + * \file vs200x_tests.cpp + * \brief Automated tests for VS200x support functions. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "action/tests/action_tests.h" +extern "C" { +#include "action/vs200x/vs200x.h" +} + + +SUITE(action) +{ + /********************************************************************** + * Language GUID tests + **********************************************************************/ + + TEST(ToolGuid_ReturnsCorrectGUID_OnC) + { + const char* result = vs200x_tool_guid("c"); + CHECK_EQUAL("8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942", result); + } + + TEST(ToolGuid_ReturnsCorrectGUID_OnCpp) + { + const char* result = vs200x_tool_guid("c++"); + CHECK_EQUAL("8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942", result); + } + + TEST(ToolGuid_ReturnsCorrectGUID_OnCSharp) + { + const char* result = vs200x_tool_guid("c#"); + CHECK_EQUAL("FAE04EC0-301F-11D3-BF4B-00C04F79EFBC", result); + } + + + /********************************************************************** + * Language file extensions + **********************************************************************/ + + TEST_FIXTURE(FxAction, ProjectExtension_IsVcproj_ForC) + { + project_set_language(prj, "c"); + const char* result = vs200x_project_file_extension(prj); + CHECK_EQUAL(".vcproj", result); + } +} diff --git a/src/action/vs200x/tests/vs200x_xml_tests.cpp b/src/action/vs200x/tests/vs200x_xml_tests.cpp index 28b8115..dfde57a 100644 --- a/src/action/vs200x/tests/vs200x_xml_tests.cpp +++ b/src/action/vs200x/tests/vs200x_xml_tests.cpp @@ -1,94 +1,94 @@ -/** - * \file vs200x_xml_tests.cpp - * \brief Automated tests for Visual Studio XML output functions. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "action/tests/action_tests.h" -extern "C" { -#include "action/vs200x/vs200x.h" -} - - -SUITE(action) -{ - /********************************************************************** - * Element end tests - **********************************************************************/ - - TEST_FIXTURE(FxAction, ElementEnd_SlashBracket_Vs2002) - { - session_set_action(sess, "vs2002"); - vs200x_element_end(sess, strm, 0, "/>"); - CHECK_EQUAL("/>\n", buffer); - } - - TEST_FIXTURE(FxAction, ElementEnd_SlashBracket_Vs2003) - { - session_set_action(sess, "vs2003"); - vs200x_element_end(sess, strm, 0, "/>"); - CHECK_EQUAL("/>\n", buffer); - } - - TEST_FIXTURE(FxAction, ElementEnd_SlashBracket_Vs2005) - { - session_set_action(sess, "vs2005"); - vs200x_element_end(sess, strm, 0, "/>"); - CHECK_EQUAL("\n/>\n", buffer); - } - - TEST_FIXTURE(FxAction, ElementEnd_SlashBracket_Vs2008) - { - session_set_action(sess, "vs2008"); - vs200x_element_end(sess, strm, 0, "/>"); - CHECK_EQUAL("\n/>\n", buffer); - } - - TEST_FIXTURE(FxAction, ElementEnd_Bracket_Vs2002) - { - session_set_action(sess, "vs2002"); - vs200x_element_end(sess, strm, 0, ">"); - CHECK_EQUAL(">\n", buffer); - } - - TEST_FIXTURE(FxAction, ElementEnd_Bracket_Vs2003) - { - session_set_action(sess, "vs2003"); - vs200x_element_end(sess, strm, 0, ">"); - CHECK_EQUAL(">\n", buffer); - } - - TEST_FIXTURE(FxAction, ElementEnd_Bracket_Vs2005) - { - session_set_action(sess, "vs2005"); - vs200x_element_end(sess, strm, 0, ">"); - CHECK_EQUAL("\n\t>\n", buffer); - } - - TEST_FIXTURE(FxAction, ElementEnd_Bracket_Vs2008) - { - session_set_action(sess, "vs2008"); - vs200x_element_end(sess, strm, 0, ">"); - CHECK_EQUAL("\n\t>\n", buffer); - } - - - /********************************************************************** - * Attribute tests - **********************************************************************/ - - TEST_FIXTURE(FxAction, Attribute_OnLevel0) - { - session_set_action(sess, "vs2002"); - vs200x_attribute(strm, 0, "ProjectType", "Visual C++"); - CHECK_EQUAL("\nProjectType=\"Visual C++\"", buffer); - } - - TEST_FIXTURE(FxAction, Attribute_OnLevel3) - { - session_set_action(sess, "vs2002"); - vs200x_attribute(strm, 3, "ProjectType", "Visual C++"); - CHECK_EQUAL("\n\t\t\tProjectType=\"Visual C++\"", buffer); - } -} +/** + * \file vs200x_xml_tests.cpp + * \brief Automated tests for Visual Studio XML output functions. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "action/tests/action_tests.h" +extern "C" { +#include "action/vs200x/vs200x.h" +} + + +SUITE(action) +{ + /********************************************************************** + * Element end tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, ElementEnd_SlashBracket_Vs2002) + { + session_set_action(sess, "vs2002"); + vs200x_element_end(sess, strm, 0, "/>"); + CHECK_EQUAL("/>\n", buffer); + } + + TEST_FIXTURE(FxAction, ElementEnd_SlashBracket_Vs2003) + { + session_set_action(sess, "vs2003"); + vs200x_element_end(sess, strm, 0, "/>"); + CHECK_EQUAL("/>\n", buffer); + } + + TEST_FIXTURE(FxAction, ElementEnd_SlashBracket_Vs2005) + { + session_set_action(sess, "vs2005"); + vs200x_element_end(sess, strm, 0, "/>"); + CHECK_EQUAL("\n/>\n", buffer); + } + + TEST_FIXTURE(FxAction, ElementEnd_SlashBracket_Vs2008) + { + session_set_action(sess, "vs2008"); + vs200x_element_end(sess, strm, 0, "/>"); + CHECK_EQUAL("\n/>\n", buffer); + } + + TEST_FIXTURE(FxAction, ElementEnd_Bracket_Vs2002) + { + session_set_action(sess, "vs2002"); + vs200x_element_end(sess, strm, 0, ">"); + CHECK_EQUAL(">\n", buffer); + } + + TEST_FIXTURE(FxAction, ElementEnd_Bracket_Vs2003) + { + session_set_action(sess, "vs2003"); + vs200x_element_end(sess, strm, 0, ">"); + CHECK_EQUAL(">\n", buffer); + } + + TEST_FIXTURE(FxAction, ElementEnd_Bracket_Vs2005) + { + session_set_action(sess, "vs2005"); + vs200x_element_end(sess, strm, 0, ">"); + CHECK_EQUAL("\n\t>\n", buffer); + } + + TEST_FIXTURE(FxAction, ElementEnd_Bracket_Vs2008) + { + session_set_action(sess, "vs2008"); + vs200x_element_end(sess, strm, 0, ">"); + CHECK_EQUAL("\n\t>\n", buffer); + } + + + /********************************************************************** + * Attribute tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Attribute_OnLevel0) + { + session_set_action(sess, "vs2002"); + vs200x_attribute(strm, 0, "ProjectType", "Visual C++"); + CHECK_EQUAL("\nProjectType=\"Visual C++\"", buffer); + } + + TEST_FIXTURE(FxAction, Attribute_OnLevel3) + { + session_set_action(sess, "vs2002"); + vs200x_attribute(strm, 3, "ProjectType", "Visual C++"); + CHECK_EQUAL("\n\t\t\tProjectType=\"Visual C++\"", buffer); + } +} diff --git a/src/action/vs200x/vs2002.c b/src/action/vs200x/vs2002.c index 4bbb759..ad34a95 100644 --- a/src/action/vs200x/vs2002.c +++ b/src/action/vs200x/vs2002.c @@ -1,85 +1,85 @@ -/** - * \file vs2002.c - * \brief Visual Studio 2002 project file generation action. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include -#include "premake.h" -#include "action/action.h" -#include "vs200x.h" -#include "vs200x_solution.h" -#include "vs200x_project.h" - - -/** The project features supported by this action */ -static SessionFeatures Features = -{ - { "c", "c++", NULL }, -}; - - -/** The VS2002 solution writing process, for session_enumerate_objects() */ -static SessionSolutionCallback SolutionCallbacks[] = -{ - vs200x_solution_create, - vs2002_solution_signature, - vs2002_solution_projects, - vs2002_solution_configuration, - vs2002_solution_dependencies, - vs2002_solution_project_configuration, - vs2002_solution_extensibility, - NULL -}; - -/** The VS2002 project writing process, for session_enumerate_objects() */ -static SessionProjectCallback ProjectCallbacks[] = -{ - vs200x_project_create, - vs200x_project_encoding, - vs200x_project_element, - vs200x_project_platforms, - vs200x_project_tool_files, - session_enumerate_configurations, - vs200x_project_references, - vs200x_project_files, - vs200x_project_globals, - NULL -}; - -/** The VS2002 configuration writing process, for session_enumerate_configurations() */ -static SessionProjectCallback ConfigCallbacks[] = -{ - vs200x_project_config_element, - vs200x_project_vc_cl_compiler_tool, - vs200x_project_vc_custom_build_tool, - vs200x_project_vc_linker_tool, - vs200x_project_vc_midl_tool, - vs200x_project_vc_post_build_event_tool, - vs200x_project_vc_pre_build_event_tool, - vs200x_project_vc_pre_link_event_tool, - vs200x_project_vc_resource_compiler_tool, - vs200x_project_vc_web_service_proxy_generator_tool, - vs200x_project_vc_web_deployment_tool, - vs200x_project_config_end, - NULL -}; - - -/** - * The Visual Studio 2002 action handler. - * \param sess The active session object. - * \returns OKAY if successful. - */ -int vs2002_action(Session sess) -{ - /* make sure I can support all of the features used in the session */ - if (session_validate(sess, &Features) != OKAY) - { - return !OKAY; - } - - stream_writeline(Console, "Generating project files for Visual Studio 2002..."); - return session_enumerate_objects(sess, SolutionCallbacks, ProjectCallbacks, ConfigCallbacks); -} - +/** + * \file vs2002.c + * \brief Visual Studio 2002 project file generation action. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include +#include "premake.h" +#include "action/action.h" +#include "vs200x.h" +#include "vs200x_solution.h" +#include "vs200x_project.h" + + +/** The project features supported by this action */ +static SessionFeatures Features = +{ + { "c", "c++", NULL }, +}; + + +/** The VS2002 solution writing process, for session_enumerate_objects() */ +static SessionSolutionCallback SolutionCallbacks[] = +{ + vs200x_solution_create, + vs2002_solution_signature, + vs2002_solution_projects, + vs2002_solution_configuration, + vs2002_solution_dependencies, + vs2002_solution_project_configuration, + vs2002_solution_extensibility, + NULL +}; + +/** The VS2002 project writing process, for session_enumerate_objects() */ +static SessionProjectCallback ProjectCallbacks[] = +{ + vs200x_project_create, + vs200x_project_encoding, + vs200x_project_element, + vs200x_project_platforms, + vs200x_project_tool_files, + session_enumerate_configurations, + vs200x_project_references, + vs200x_project_files, + vs200x_project_globals, + NULL +}; + +/** The VS2002 configuration writing process, for session_enumerate_configurations() */ +static SessionProjectCallback ConfigCallbacks[] = +{ + vs200x_project_config_element, + vs200x_project_vc_cl_compiler_tool, + vs200x_project_vc_custom_build_tool, + vs200x_project_vc_linker_tool, + vs200x_project_vc_midl_tool, + vs200x_project_vc_post_build_event_tool, + vs200x_project_vc_pre_build_event_tool, + vs200x_project_vc_pre_link_event_tool, + vs200x_project_vc_resource_compiler_tool, + vs200x_project_vc_web_service_proxy_generator_tool, + vs200x_project_vc_web_deployment_tool, + vs200x_project_config_end, + NULL +}; + + +/** + * The Visual Studio 2002 action handler. + * \param sess The active session object. + * \returns OKAY if successful. + */ +int vs2002_action(Session sess) +{ + /* make sure I can support all of the features used in the session */ + if (session_validate(sess, &Features) != OKAY) + { + return !OKAY; + } + + stream_writeline(Console, "Generating project files for Visual Studio 2002..."); + return session_enumerate_objects(sess, SolutionCallbacks, ProjectCallbacks, ConfigCallbacks); +} + diff --git a/src/action/vs200x/vs2002_solution.c b/src/action/vs200x/vs2002_solution.c index 28d3c88..2cb1ac3 100644 --- a/src/action/vs200x/vs2002_solution.c +++ b/src/action/vs200x/vs2002_solution.c @@ -1,169 +1,169 @@ -/** - * \file vs2002_solution.c - * \brief Visual Studio 2002 solution generation functions. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include -#include -#include "premake.h" -#include "vs200x.h" -#include "vs200x_solution.h" -#include "vs200x_project.h" -#include "base/path.h" - - -/** - * Create the Visual Studio 2002 solution configuration block. - * \param sess The execution session context. - * \param sln The current solution. - * \param strm The currently active stream; set with session_set_active_stream(). - * \returns OKAY if successful. - */ -int vs2002_solution_configuration(Session sess, Solution sln, Stream strm) -{ - int i, n, z; - UNUSED(sess); - - z = stream_writeline(strm, "Global"); - z |= stream_writeline(strm, "\tGlobalSection(SolutionConfiguration) = preSolution"); - - n = solution_num_configs(sln); - for (i = 0; i < n; ++i) - { - const char* config_name = solution_get_config_name(sln, i); - z |= stream_writeline(strm, "\t\tConfigName.%d = %s", i, config_name); - } - - z |= stream_writeline(strm, "\tEndGlobalSection"); - return z; -} - - -/** - * Create the Visual Studio 2002 project dependencies block. - * \param sess The execution session context. - * \param sln The current solution. - * \param strm The currently active stream; set with session_set_active_stream(). - * \returns OKAY if successful. - */ -int vs2002_solution_dependencies(Session sess, Solution sln, Stream strm) -{ - int z; - UNUSED(sess); - UNUSED(sln); - z = stream_writeline(strm, "\tGlobalSection(ProjectDependencies) = postSolution"); - z |= stream_writeline(strm, "\tEndGlobalSection"); - return z; -} - - -/** - * Write out the Visual Studio 2002 solution extensibility block. - * \param sess The execution session context. - * \param sln The current solution. - * \param strm The currently active stream; set with session_set_active_stream(). - * \returns OKAY if successful. - */ -int vs2002_solution_extensibility(Session sess, Solution sln, Stream strm) -{ - int z; - UNUSED(sess); - UNUSED(sln); - z = stream_writeline(strm, "\tGlobalSection(ExtensibilityGlobals) = postSolution"); - z |= stream_writeline(strm, "\tEndGlobalSection"); - z |= stream_writeline(strm, "\tGlobalSection(ExtensibilityAddIns) = postSolution"); - z |= stream_writeline(strm, "\tEndGlobalSection"); - z |= stream_writeline(strm, "EndGlobal"); - return z; -} - - -/** - * Write out the Visual Studio 2002 project configurations block. - * \param sess The execution session context. - * \param sln The current solution. - * \param strm The currently active stream; set with session_set_active_stream(). - * \returns OKAY if successful. - */ -int vs2002_solution_project_configuration(Session sess, Solution sln, Stream strm) -{ - int pi, pn, z; - UNUSED(sess); - z = stream_writeline(strm, "\tGlobalSection(ProjectConfiguration) = postSolution"); - pn = solution_num_projects(sln); - for (pi = 0; pi < pn; ++pi) - { - int ci, cn; - Project prj = solution_get_project(sln, pi); - const char* prj_id = project_get_guid(prj); - - cn = solution_num_configs(sln); - for (ci = 0; ci < cn; ++ci) - { - const char* config_name = solution_get_config_name(sln, ci); - z |= stream_writeline(strm, "\t\t{%s}.%s.ActiveCfg = %s|Win32", prj_id, config_name, config_name); - z |= stream_writeline(strm, "\t\t{%s}.%s.Build.0 = %s|Win32", prj_id, config_name, config_name); - } - } - z |= stream_writeline(strm, "\tEndGlobalSection"); - return z; -} - - -/** - * Write out the list of projects contained by the solution. - * \param sess The execution session context. - * \param sln The current solution. - * \param strm The currently active stream; set with session_set_active_stream(). - * \returns OKAY if successful. - */ -int vs2002_solution_projects(Session sess, Solution sln, Stream strm) -{ - const char* sln_path; - int i, n, z = OKAY; - - UNUSED(sess); - - /* project file paths are specified relative to the solution */ - sln_path = path_directory(solution_get_filename(sln, NULL, NULL)); - - n = solution_num_projects(sln); - for (i = 0; i < n; ++i) - { - Project prj = solution_get_project(sln, i); - const char* prj_name = project_get_name(prj); - const char* prj_id = project_get_guid(prj); - const char* prj_lang = project_get_language(prj); - const char* prj_ext = vs200x_project_file_extension(prj); - const char* prj_file = project_get_filename(prj, prj_name, prj_ext); - const char* tool_id = vs200x_tool_guid(prj_lang); - - /* convert absolute project file name to be relative to solution */ - prj_file = path_relative(sln_path, prj_file); - prj_file = path_translate(prj_file, "\\"); - - z |= stream_writeline(strm, "Project(\"{%s}\") = \"%s\", \"%s\", \"{%s}\"", tool_id, prj_name, prj_file, prj_id); - z |= stream_writeline(strm, "EndProject"); - } - - return z; -} - - -/** - * Write the Visual Studio 2002 solution file signature. - * \param sess The execution session context. - * \param sln The current solution. - * \param strm The currently active stream; set with session_set_active_stream(). - * \returns OKAY if successful. - */ -int vs2002_solution_signature(Session sess, Solution sln, Stream strm) -{ - int z; - UNUSED(sess); - UNUSED(sln); - stream_set_newline(strm, "\r\n"); - z = stream_writeline(strm, "Microsoft Visual Studio Solution File, Format Version 7.00"); - return z; -} +/** + * \file vs2002_solution.c + * \brief Visual Studio 2002 solution generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include +#include +#include "premake.h" +#include "vs200x.h" +#include "vs200x_solution.h" +#include "vs200x_project.h" +#include "base/path.h" + + +/** + * Create the Visual Studio 2002 solution configuration block. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int vs2002_solution_configuration(Session sess, Solution sln, Stream strm) +{ + int i, n, z; + UNUSED(sess); + + z = stream_writeline(strm, "Global"); + z |= stream_writeline(strm, "\tGlobalSection(SolutionConfiguration) = preSolution"); + + n = solution_num_configs(sln); + for (i = 0; i < n; ++i) + { + const char* config_name = solution_get_config_name(sln, i); + z |= stream_writeline(strm, "\t\tConfigName.%d = %s", i, config_name); + } + + z |= stream_writeline(strm, "\tEndGlobalSection"); + return z; +} + + +/** + * Create the Visual Studio 2002 project dependencies block. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int vs2002_solution_dependencies(Session sess, Solution sln, Stream strm) +{ + int z; + UNUSED(sess); + UNUSED(sln); + z = stream_writeline(strm, "\tGlobalSection(ProjectDependencies) = postSolution"); + z |= stream_writeline(strm, "\tEndGlobalSection"); + return z; +} + + +/** + * Write out the Visual Studio 2002 solution extensibility block. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int vs2002_solution_extensibility(Session sess, Solution sln, Stream strm) +{ + int z; + UNUSED(sess); + UNUSED(sln); + z = stream_writeline(strm, "\tGlobalSection(ExtensibilityGlobals) = postSolution"); + z |= stream_writeline(strm, "\tEndGlobalSection"); + z |= stream_writeline(strm, "\tGlobalSection(ExtensibilityAddIns) = postSolution"); + z |= stream_writeline(strm, "\tEndGlobalSection"); + z |= stream_writeline(strm, "EndGlobal"); + return z; +} + + +/** + * Write out the Visual Studio 2002 project configurations block. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int vs2002_solution_project_configuration(Session sess, Solution sln, Stream strm) +{ + int pi, pn, z; + UNUSED(sess); + z = stream_writeline(strm, "\tGlobalSection(ProjectConfiguration) = postSolution"); + pn = solution_num_projects(sln); + for (pi = 0; pi < pn; ++pi) + { + int ci, cn; + Project prj = solution_get_project(sln, pi); + const char* prj_id = project_get_guid(prj); + + cn = solution_num_configs(sln); + for (ci = 0; ci < cn; ++ci) + { + const char* config_name = solution_get_config_name(sln, ci); + z |= stream_writeline(strm, "\t\t{%s}.%s.ActiveCfg = %s|Win32", prj_id, config_name, config_name); + z |= stream_writeline(strm, "\t\t{%s}.%s.Build.0 = %s|Win32", prj_id, config_name, config_name); + } + } + z |= stream_writeline(strm, "\tEndGlobalSection"); + return z; +} + + +/** + * Write out the list of projects contained by the solution. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int vs2002_solution_projects(Session sess, Solution sln, Stream strm) +{ + const char* sln_path; + int i, n, z = OKAY; + + UNUSED(sess); + + /* project file paths are specified relative to the solution */ + sln_path = path_directory(solution_get_filename(sln, NULL, NULL)); + + n = solution_num_projects(sln); + for (i = 0; i < n; ++i) + { + Project prj = solution_get_project(sln, i); + const char* prj_name = project_get_name(prj); + const char* prj_id = project_get_guid(prj); + const char* prj_lang = project_get_language(prj); + const char* prj_ext = vs200x_project_file_extension(prj); + const char* prj_file = project_get_filename(prj, prj_name, prj_ext); + const char* tool_id = vs200x_tool_guid(prj_lang); + + /* convert absolute project file name to be relative to solution */ + prj_file = path_relative(sln_path, prj_file); + prj_file = path_translate(prj_file, "\\"); + + z |= stream_writeline(strm, "Project(\"{%s}\") = \"%s\", \"%s\", \"{%s}\"", tool_id, prj_name, prj_file, prj_id); + z |= stream_writeline(strm, "EndProject"); + } + + return z; +} + + +/** + * Write the Visual Studio 2002 solution file signature. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int vs2002_solution_signature(Session sess, Solution sln, Stream strm) +{ + int z; + UNUSED(sess); + UNUSED(sln); + stream_set_newline(strm, "\r\n"); + z = stream_writeline(strm, "Microsoft Visual Studio Solution File, Format Version 7.00"); + return z; +} diff --git a/src/action/vs200x/vs2003.c b/src/action/vs200x/vs2003.c index 655aa46..6c9ec3c 100644 --- a/src/action/vs200x/vs2003.c +++ b/src/action/vs200x/vs2003.c @@ -1,84 +1,84 @@ -/** - * \file vs2003.c - * \brief Visual Studio 2003 project file generation action. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include -#include "premake.h" -#include "action/action.h" -#include "vs200x.h" -#include "vs200x_solution.h" -#include "vs200x_project.h" - - -/** The project features supported by this action */ -static SessionFeatures Features = -{ - { "c", "c++", NULL }, -}; - - -/** The VS2003 solution writing process, for session_enumerate_objects() */ -static SessionSolutionCallback SolutionCallbacks[] = -{ - vs200x_solution_create, - vs2003_solution_signature, - vs2002_solution_projects, - vs2003_solution_configuration, - vs2002_solution_project_configuration, - vs2002_solution_extensibility, - NULL -}; - -/** The VS2003 project writing process, for session_enumerate_objects() */ -static SessionProjectCallback ProjectCallbacks[] = -{ - vs200x_project_create, - vs200x_project_encoding, - vs200x_project_element, - vs200x_project_platforms, - vs200x_project_tool_files, - session_enumerate_configurations, - vs200x_project_references, - vs200x_project_files, - vs200x_project_globals, - NULL -}; - -/** The VS2003 configuration writing process, for session_enumerate_configurations() */ -static SessionProjectCallback ConfigCallbacks[] = -{ - vs200x_project_config_element, - vs200x_project_vc_cl_compiler_tool, - vs200x_project_vc_custom_build_tool, - vs200x_project_vc_linker_tool, - vs200x_project_vc_midl_tool, - vs200x_project_vc_post_build_event_tool, - vs200x_project_vc_pre_build_event_tool, - vs200x_project_vc_pre_link_event_tool, - vs200x_project_vc_resource_compiler_tool, - vs200x_project_vc_web_service_proxy_generator_tool, - vs200x_project_vc_xml_data_generator_tool, - vs200x_project_vc_web_deployment_tool, - vs200x_project_config_end, - NULL -}; - - -/** - * The Visual Studio 2003 action handler. - * \param sess The active session object. - * \returns OKAY if successful. - */ -int vs2003_action(Session sess) -{ - /* make sure I can support all of the features used in the session */ - if (session_validate(sess, &Features) != OKAY) - { - return !OKAY; - } - - stream_writeline(Console, "Generating project files for Visual Studio 2003..."); - return session_enumerate_objects(sess, SolutionCallbacks, ProjectCallbacks, ConfigCallbacks); -} +/** + * \file vs2003.c + * \brief Visual Studio 2003 project file generation action. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include +#include "premake.h" +#include "action/action.h" +#include "vs200x.h" +#include "vs200x_solution.h" +#include "vs200x_project.h" + + +/** The project features supported by this action */ +static SessionFeatures Features = +{ + { "c", "c++", NULL }, +}; + + +/** The VS2003 solution writing process, for session_enumerate_objects() */ +static SessionSolutionCallback SolutionCallbacks[] = +{ + vs200x_solution_create, + vs2003_solution_signature, + vs2002_solution_projects, + vs2003_solution_configuration, + vs2002_solution_project_configuration, + vs2002_solution_extensibility, + NULL +}; + +/** The VS2003 project writing process, for session_enumerate_objects() */ +static SessionProjectCallback ProjectCallbacks[] = +{ + vs200x_project_create, + vs200x_project_encoding, + vs200x_project_element, + vs200x_project_platforms, + vs200x_project_tool_files, + session_enumerate_configurations, + vs200x_project_references, + vs200x_project_files, + vs200x_project_globals, + NULL +}; + +/** The VS2003 configuration writing process, for session_enumerate_configurations() */ +static SessionProjectCallback ConfigCallbacks[] = +{ + vs200x_project_config_element, + vs200x_project_vc_cl_compiler_tool, + vs200x_project_vc_custom_build_tool, + vs200x_project_vc_linker_tool, + vs200x_project_vc_midl_tool, + vs200x_project_vc_post_build_event_tool, + vs200x_project_vc_pre_build_event_tool, + vs200x_project_vc_pre_link_event_tool, + vs200x_project_vc_resource_compiler_tool, + vs200x_project_vc_web_service_proxy_generator_tool, + vs200x_project_vc_xml_data_generator_tool, + vs200x_project_vc_web_deployment_tool, + vs200x_project_config_end, + NULL +}; + + +/** + * The Visual Studio 2003 action handler. + * \param sess The active session object. + * \returns OKAY if successful. + */ +int vs2003_action(Session sess) +{ + /* make sure I can support all of the features used in the session */ + if (session_validate(sess, &Features) != OKAY) + { + return !OKAY; + } + + stream_writeline(Console, "Generating project files for Visual Studio 2003..."); + return session_enumerate_objects(sess, SolutionCallbacks, ProjectCallbacks, ConfigCallbacks); +} diff --git a/src/action/vs200x/vs2003_solution.c b/src/action/vs200x/vs2003_solution.c index d2ee82b..0b744ed 100644 --- a/src/action/vs200x/vs2003_solution.c +++ b/src/action/vs200x/vs2003_solution.c @@ -1,55 +1,55 @@ -/** - * \file vs2003_solution.c - * \brief Visual Studio 2003 solution generation functions. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include -#include -#include "premake.h" -#include "vs200x_solution.h" - - -/** - * Create the Visual Studio 2003 solution configuration block. - * \param sess The execution session context. - * \param sln The current solution. - * \param strm The currently active stream; set with session_set_active_stream(). - * \returns OKAY if successful. - */ -int vs2003_solution_configuration(Session sess, Solution sln, Stream strm) -{ - int i, n, z; - UNUSED(sess); - - z = stream_writeline(strm, "Global"); - z |= stream_writeline(strm, "\tGlobalSection(SolutionConfiguration) = preSolution"); - - n = solution_num_configs(sln); - for (i = 0; i < n; ++i) - { - const char* config_name = solution_get_config_name(sln, i); - z |= stream_writeline(strm, "\t\t%s = %s", config_name, config_name); - } - - z |= stream_writeline(strm, "\tEndGlobalSection"); - return z; -} - - -/** - * Write the Visual Studio 2003 solution file signature. - * \param sess The execution session context. - * \param sln The current solution. - * \param strm The currently active stream; set with session_set_active_stream(). - * \returns OKAY if successful. - */ -int vs2003_solution_signature(Session sess, Solution sln, Stream strm) -{ - int z; - UNUSED(sess); - UNUSED(sln); - stream_set_newline(strm, "\r\n"); - z = stream_writeline(strm, "Microsoft Visual Studio Solution File, Format Version 8.00"); - return z; -} +/** + * \file vs2003_solution.c + * \brief Visual Studio 2003 solution generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include +#include +#include "premake.h" +#include "vs200x_solution.h" + + +/** + * Create the Visual Studio 2003 solution configuration block. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int vs2003_solution_configuration(Session sess, Solution sln, Stream strm) +{ + int i, n, z; + UNUSED(sess); + + z = stream_writeline(strm, "Global"); + z |= stream_writeline(strm, "\tGlobalSection(SolutionConfiguration) = preSolution"); + + n = solution_num_configs(sln); + for (i = 0; i < n; ++i) + { + const char* config_name = solution_get_config_name(sln, i); + z |= stream_writeline(strm, "\t\t%s = %s", config_name, config_name); + } + + z |= stream_writeline(strm, "\tEndGlobalSection"); + return z; +} + + +/** + * Write the Visual Studio 2003 solution file signature. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int vs2003_solution_signature(Session sess, Solution sln, Stream strm) +{ + int z; + UNUSED(sess); + UNUSED(sln); + stream_set_newline(strm, "\r\n"); + z = stream_writeline(strm, "Microsoft Visual Studio Solution File, Format Version 8.00"); + return z; +} diff --git a/src/action/vs200x/vs2005.c b/src/action/vs200x/vs2005.c index ab0a831..8b4175a 100644 --- a/src/action/vs200x/vs2005.c +++ b/src/action/vs200x/vs2005.c @@ -1,92 +1,92 @@ -/** - * \file vs2005.c - * \brief Visual Studio 2005 project file generation action. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include -#include "premake.h" -#include "action/action.h" -#include "vs200x.h" -#include "vs200x_solution.h" -#include "vs200x_project.h" - - -/** The project features supported by this action */ -static SessionFeatures Features = -{ - { "c", "c++", NULL }, -}; - - -/** The VS2005 solution writing process, for session_enumerate_objects() */ -static SessionSolutionCallback SolutionCallbacks[] = -{ - vs200x_solution_create, - vs2005_solution_signature, - vs2002_solution_projects, - vs2005_solution_platforms, - vs2005_solution_project_platforms, - vs2005_solution_properties, - NULL -}; - -/** The VS2005 project writing process, for session_enumerate_objects() */ -static SessionProjectCallback ProjectCallbacks[] = -{ - vs200x_project_create, - vs200x_project_encoding, - vs200x_project_element, - vs200x_project_platforms, - vs200x_project_tool_files, - session_enumerate_configurations, - vs200x_project_references, - vs200x_project_files, - vs200x_project_globals, - NULL -}; - -/** The VS2005 configuration writing process, for session_enumerate_configurations() */ -static SessionProjectCallback ConfigCallbacks[] = -{ - vs200x_project_config_element, - vs200x_project_vc_pre_build_event_tool, - vs200x_project_vc_custom_build_tool, - vs200x_project_vc_xml_data_generator_tool, - vs200x_project_vc_web_service_proxy_generator_tool, - vs200x_project_vc_midl_tool, - vs200x_project_vc_cl_compiler_tool, - vs200x_project_vc_managed_resource_compiler_tool, - vs200x_project_vc_resource_compiler_tool, - vs200x_project_vc_pre_link_event_tool, - vs200x_project_vc_linker_tool, - vs200x_project_vc_alink_tool, - vs200x_project_vc_manifest_tool, - vs200x_project_vc_xdc_make_tool, - vs200x_project_vc_bsc_make_tool, - vs200x_project_vc_fx_cop_tool, - vs200x_project_vc_app_verifier_tool, - vs200x_project_vc_web_deployment_tool, - vs200x_project_vc_post_build_event_tool, - vs200x_project_config_end, - NULL -}; - - -/** - * The Visual Studio 2005 action handler. - * \param sess The active session object. - * \returns OKAY if successful. - */ -int vs2005_action(Session sess) -{ - /* make sure I can support all of the features used in the session */ - if (session_validate(sess, &Features) != OKAY) - { - return !OKAY; - } - - stream_writeline(Console, "Generating project files for Visual Studio 2005..."); - return session_enumerate_objects(sess, SolutionCallbacks, ProjectCallbacks, ConfigCallbacks); -} - +/** + * \file vs2005.c + * \brief Visual Studio 2005 project file generation action. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include +#include "premake.h" +#include "action/action.h" +#include "vs200x.h" +#include "vs200x_solution.h" +#include "vs200x_project.h" + + +/** The project features supported by this action */ +static SessionFeatures Features = +{ + { "c", "c++", NULL }, +}; + + +/** The VS2005 solution writing process, for session_enumerate_objects() */ +static SessionSolutionCallback SolutionCallbacks[] = +{ + vs200x_solution_create, + vs2005_solution_signature, + vs2002_solution_projects, + vs2005_solution_platforms, + vs2005_solution_project_platforms, + vs2005_solution_properties, + NULL +}; + +/** The VS2005 project writing process, for session_enumerate_objects() */ +static SessionProjectCallback ProjectCallbacks[] = +{ + vs200x_project_create, + vs200x_project_encoding, + vs200x_project_element, + vs200x_project_platforms, + vs200x_project_tool_files, + session_enumerate_configurations, + vs200x_project_references, + vs200x_project_files, + vs200x_project_globals, + NULL +}; + +/** The VS2005 configuration writing process, for session_enumerate_configurations() */ +static SessionProjectCallback ConfigCallbacks[] = +{ + vs200x_project_config_element, + vs200x_project_vc_pre_build_event_tool, + vs200x_project_vc_custom_build_tool, + vs200x_project_vc_xml_data_generator_tool, + vs200x_project_vc_web_service_proxy_generator_tool, + vs200x_project_vc_midl_tool, + vs200x_project_vc_cl_compiler_tool, + vs200x_project_vc_managed_resource_compiler_tool, + vs200x_project_vc_resource_compiler_tool, + vs200x_project_vc_pre_link_event_tool, + vs200x_project_vc_linker_tool, + vs200x_project_vc_alink_tool, + vs200x_project_vc_manifest_tool, + vs200x_project_vc_xdc_make_tool, + vs200x_project_vc_bsc_make_tool, + vs200x_project_vc_fx_cop_tool, + vs200x_project_vc_app_verifier_tool, + vs200x_project_vc_web_deployment_tool, + vs200x_project_vc_post_build_event_tool, + vs200x_project_config_end, + NULL +}; + + +/** + * The Visual Studio 2005 action handler. + * \param sess The active session object. + * \returns OKAY if successful. + */ +int vs2005_action(Session sess) +{ + /* make sure I can support all of the features used in the session */ + if (session_validate(sess, &Features) != OKAY) + { + return !OKAY; + } + + stream_writeline(Console, "Generating project files for Visual Studio 2005..."); + return session_enumerate_objects(sess, SolutionCallbacks, ProjectCallbacks, ConfigCallbacks); +} + diff --git a/src/action/vs200x/vs2005_solution.c b/src/action/vs200x/vs2005_solution.c index 09aef76..27c89be 100644 --- a/src/action/vs200x/vs2005_solution.c +++ b/src/action/vs200x/vs2005_solution.c @@ -1,110 +1,110 @@ -/** - * \file vs2005_solution.c - * \brief Visual Studio 2005 solution generation functions. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include -#include -#include "premake.h" -#include "vs200x_solution.h" - - -/** - * Write out the Visual Studio solution-level platform configuration block. - * \param sess The execution session context. - * \param sln The current solution. - * \param strm The currently active stream; set with session_set_active_stream(). - * \returns OKAY if successful. - */ -int vs2005_solution_platforms(Session sess, Solution sln, Stream strm) -{ - int i, n, z; - UNUSED(sess); - - z = stream_writeline(strm, "Global"); - z |= stream_writeline(strm, "\tGlobalSection(SolutionConfigurationPlatforms) = preSolution"); - - n = solution_num_configs(sln); - for (i = 0; i < n; ++i) - { - const char* config_name = solution_get_config_name(sln, i); - z |= stream_writeline(strm, "\t\t%s|Win32 = %s|Win32", config_name, config_name); - } - - z |= stream_writeline(strm, "\tEndGlobalSection"); - return z; -} - - -/** - * Write out the Visual Studio 2005 project-level platform configurations block. - * \param sess The execution session context. - * \param sln The current solution. - * \param strm The currently active stream; set with session_set_active_stream(). - * \returns OKAY if successful. - */ -int vs2005_solution_project_platforms(Session sess, Solution sln, Stream strm) -{ - int pi, pn, z; - UNUSED(sess); - z = stream_writeline(strm, "\tGlobalSection(ProjectConfigurationPlatforms) = postSolution"); - pn = solution_num_projects(sln); - for (pi = 0; pi < pn; ++pi) - { - int ci, cn; - Project prj = solution_get_project(sln, pi); - const char* prj_id = project_get_guid(prj); - - cn = solution_num_configs(sln); - for (ci = 0; ci < cn; ++ci) - { - const char* config_name = solution_get_config_name(sln, ci); - z |= stream_writeline(strm, "\t\t{%s}.%s|Win32.ActiveCfg = %s|Win32", prj_id, config_name, config_name); - z |= stream_writeline(strm, "\t\t{%s}.%s|Win32.Build.0 = %s|Win32", prj_id, config_name, config_name); - } - } - z |= stream_writeline(strm, "\tEndGlobalSection"); - return z; -} - - -/** - * Write out the Visual Studio 2005 solution properties block. - * \param sess The execution session context. - * \param sln The current solution. - * \param strm The currently active stream; set with session_set_active_stream(). - * \returns OKAY if successful. - */ -int vs2005_solution_properties(Session sess, Solution sln, Stream strm) -{ - int z; - UNUSED(sess); - UNUSED(sln); - z = stream_writeline(strm, "\tGlobalSection(SolutionProperties) = preSolution"); - z |= stream_writeline(strm, "\t\tHideSolutionNode = FALSE"); - z |= stream_writeline(strm, "\tEndGlobalSection"); - z |= stream_writeline(strm, "EndGlobal"); - return z; -} - - -/** - * Write the Visual Studio 2005 solution file signature. - * \param sess The execution session context. - * \param sln The current solution. - * \param strm The currently active stream; set with session_set_active_stream(). - * \returns OKAY if successful. - */ -int vs2005_solution_signature(Session sess, Solution sln, Stream strm) -{ - int z; - UNUSED(sess); - UNUSED(sln); - stream_set_newline(strm, "\r\n"); - z = stream_write_unicode_marker(strm); - z |= stream_writeline(strm, ""); - z |= stream_writeline(strm, "Microsoft Visual Studio Solution File, Format Version 9.00"); - z |= stream_writeline(strm, "# Visual Studio 2005"); - return z; -} +/** + * \file vs2005_solution.c + * \brief Visual Studio 2005 solution generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include +#include +#include "premake.h" +#include "vs200x_solution.h" + + +/** + * Write out the Visual Studio solution-level platform configuration block. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int vs2005_solution_platforms(Session sess, Solution sln, Stream strm) +{ + int i, n, z; + UNUSED(sess); + + z = stream_writeline(strm, "Global"); + z |= stream_writeline(strm, "\tGlobalSection(SolutionConfigurationPlatforms) = preSolution"); + + n = solution_num_configs(sln); + for (i = 0; i < n; ++i) + { + const char* config_name = solution_get_config_name(sln, i); + z |= stream_writeline(strm, "\t\t%s|Win32 = %s|Win32", config_name, config_name); + } + + z |= stream_writeline(strm, "\tEndGlobalSection"); + return z; +} + + +/** + * Write out the Visual Studio 2005 project-level platform configurations block. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int vs2005_solution_project_platforms(Session sess, Solution sln, Stream strm) +{ + int pi, pn, z; + UNUSED(sess); + z = stream_writeline(strm, "\tGlobalSection(ProjectConfigurationPlatforms) = postSolution"); + pn = solution_num_projects(sln); + for (pi = 0; pi < pn; ++pi) + { + int ci, cn; + Project prj = solution_get_project(sln, pi); + const char* prj_id = project_get_guid(prj); + + cn = solution_num_configs(sln); + for (ci = 0; ci < cn; ++ci) + { + const char* config_name = solution_get_config_name(sln, ci); + z |= stream_writeline(strm, "\t\t{%s}.%s|Win32.ActiveCfg = %s|Win32", prj_id, config_name, config_name); + z |= stream_writeline(strm, "\t\t{%s}.%s|Win32.Build.0 = %s|Win32", prj_id, config_name, config_name); + } + } + z |= stream_writeline(strm, "\tEndGlobalSection"); + return z; +} + + +/** + * Write out the Visual Studio 2005 solution properties block. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int vs2005_solution_properties(Session sess, Solution sln, Stream strm) +{ + int z; + UNUSED(sess); + UNUSED(sln); + z = stream_writeline(strm, "\tGlobalSection(SolutionProperties) = preSolution"); + z |= stream_writeline(strm, "\t\tHideSolutionNode = FALSE"); + z |= stream_writeline(strm, "\tEndGlobalSection"); + z |= stream_writeline(strm, "EndGlobal"); + return z; +} + + +/** + * Write the Visual Studio 2005 solution file signature. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int vs2005_solution_signature(Session sess, Solution sln, Stream strm) +{ + int z; + UNUSED(sess); + UNUSED(sln); + stream_set_newline(strm, "\r\n"); + z = stream_write_unicode_marker(strm); + z |= stream_writeline(strm, ""); + z |= stream_writeline(strm, "Microsoft Visual Studio Solution File, Format Version 9.00"); + z |= stream_writeline(strm, "# Visual Studio 2005"); + return z; +} diff --git a/src/action/vs200x/vs2008.c b/src/action/vs200x/vs2008.c index 88cbe8d..20f191f 100644 --- a/src/action/vs200x/vs2008.c +++ b/src/action/vs200x/vs2008.c @@ -1,91 +1,91 @@ -/** - * \file vs2008.c - * \brief Visual Studio 2008 project file generation action. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include -#include "premake.h" -#include "action/action.h" -#include "vs200x.h" -#include "vs200x_solution.h" -#include "vs200x_project.h" - - -/** The project features supported by this action */ -static SessionFeatures Features = -{ - { "c", "c++", NULL }, -}; - - -/** The VS2008 solution writing process, for session_enumerate_objects() */ -static SessionSolutionCallback SolutionCallbacks[] = -{ - vs200x_solution_create, - vs2008_solution_signature, - vs2002_solution_projects, - vs2005_solution_platforms, - vs2005_solution_project_platforms, - vs2005_solution_properties, - NULL -}; - -/** The VS2008 project writing process, for session_enumerate_objects() */ -static SessionProjectCallback ProjectCallbacks[] = -{ - vs200x_project_create, - vs200x_project_encoding, - vs200x_project_element, - vs200x_project_platforms, - vs200x_project_tool_files, - session_enumerate_configurations, - vs200x_project_references, - vs200x_project_files, - vs200x_project_globals, - NULL -}; - -/** The VS2008 configuration writing process, for session_enumerate_configurations() */ -static SessionProjectCallback ConfigCallbacks[] = -{ - vs200x_project_config_element, - vs200x_project_vc_pre_build_event_tool, - vs200x_project_vc_custom_build_tool, - vs200x_project_vc_xml_data_generator_tool, - vs200x_project_vc_web_service_proxy_generator_tool, - vs200x_project_vc_midl_tool, - vs200x_project_vc_cl_compiler_tool, - vs200x_project_vc_managed_resource_compiler_tool, - vs200x_project_vc_resource_compiler_tool, - vs200x_project_vc_pre_link_event_tool, - vs200x_project_vc_linker_tool, - vs200x_project_vc_alink_tool, - vs200x_project_vc_manifest_tool, - vs200x_project_vc_xdc_make_tool, - vs200x_project_vc_bsc_make_tool, - vs200x_project_vc_fx_cop_tool, - vs200x_project_vc_app_verifier_tool, - vs200x_project_vc_post_build_event_tool, - vs200x_project_config_end, - NULL -}; - - -/** - * The Visual Studio 2008 action handler. - * \param sess The active session object. - * \returns OKAY if successful. - */ -int vs2008_action(Session sess) -{ - /* make sure I can support all of the features used in the session */ - if (session_validate(sess, &Features) != OKAY) - { - return !OKAY; - } - - stream_writeline(Console, "Generating project files for Visual Studio 2008..."); - return session_enumerate_objects(sess, SolutionCallbacks, ProjectCallbacks, ConfigCallbacks); -} - +/** + * \file vs2008.c + * \brief Visual Studio 2008 project file generation action. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include +#include "premake.h" +#include "action/action.h" +#include "vs200x.h" +#include "vs200x_solution.h" +#include "vs200x_project.h" + + +/** The project features supported by this action */ +static SessionFeatures Features = +{ + { "c", "c++", NULL }, +}; + + +/** The VS2008 solution writing process, for session_enumerate_objects() */ +static SessionSolutionCallback SolutionCallbacks[] = +{ + vs200x_solution_create, + vs2008_solution_signature, + vs2002_solution_projects, + vs2005_solution_platforms, + vs2005_solution_project_platforms, + vs2005_solution_properties, + NULL +}; + +/** The VS2008 project writing process, for session_enumerate_objects() */ +static SessionProjectCallback ProjectCallbacks[] = +{ + vs200x_project_create, + vs200x_project_encoding, + vs200x_project_element, + vs200x_project_platforms, + vs200x_project_tool_files, + session_enumerate_configurations, + vs200x_project_references, + vs200x_project_files, + vs200x_project_globals, + NULL +}; + +/** The VS2008 configuration writing process, for session_enumerate_configurations() */ +static SessionProjectCallback ConfigCallbacks[] = +{ + vs200x_project_config_element, + vs200x_project_vc_pre_build_event_tool, + vs200x_project_vc_custom_build_tool, + vs200x_project_vc_xml_data_generator_tool, + vs200x_project_vc_web_service_proxy_generator_tool, + vs200x_project_vc_midl_tool, + vs200x_project_vc_cl_compiler_tool, + vs200x_project_vc_managed_resource_compiler_tool, + vs200x_project_vc_resource_compiler_tool, + vs200x_project_vc_pre_link_event_tool, + vs200x_project_vc_linker_tool, + vs200x_project_vc_alink_tool, + vs200x_project_vc_manifest_tool, + vs200x_project_vc_xdc_make_tool, + vs200x_project_vc_bsc_make_tool, + vs200x_project_vc_fx_cop_tool, + vs200x_project_vc_app_verifier_tool, + vs200x_project_vc_post_build_event_tool, + vs200x_project_config_end, + NULL +}; + + +/** + * The Visual Studio 2008 action handler. + * \param sess The active session object. + * \returns OKAY if successful. + */ +int vs2008_action(Session sess) +{ + /* make sure I can support all of the features used in the session */ + if (session_validate(sess, &Features) != OKAY) + { + return !OKAY; + } + + stream_writeline(Console, "Generating project files for Visual Studio 2008..."); + return session_enumerate_objects(sess, SolutionCallbacks, ProjectCallbacks, ConfigCallbacks); +} + diff --git a/src/action/vs200x/vs2008_solution.c b/src/action/vs200x/vs2008_solution.c index 73e4e8e..856bd51 100644 --- a/src/action/vs200x/vs2008_solution.c +++ b/src/action/vs200x/vs2008_solution.c @@ -1,29 +1,29 @@ -/** - * \file vs2008_solution.c - * \brief Visual Studio 2008 solution generation functions. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "vs200x_solution.h" - - -/** - * Write the Visual Studio 2008 solution file signature. - * \param sess The execution session context. - * \param sln The current solution. - * \param strm The currently active stream; set with session_set_active_stream(). - * \returns OKAY if successful. - */ -int vs2008_solution_signature(Session sess, Solution sln, Stream strm) -{ - int z; - UNUSED(sess); - UNUSED(sln); - stream_set_newline(strm, "\r\n"); - z = stream_write_unicode_marker(strm); - z |= stream_writeline(strm, ""); - z |= stream_writeline(strm, "Microsoft Visual Studio Solution File, Format Version 10.00"); - z |= stream_writeline(strm, "# Visual Studio 2008"); - return z; -} +/** + * \file vs2008_solution.c + * \brief Visual Studio 2008 solution generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "vs200x_solution.h" + + +/** + * Write the Visual Studio 2008 solution file signature. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int vs2008_solution_signature(Session sess, Solution sln, Stream strm) +{ + int z; + UNUSED(sess); + UNUSED(sln); + stream_set_newline(strm, "\r\n"); + z = stream_write_unicode_marker(strm); + z |= stream_writeline(strm, ""); + z |= stream_writeline(strm, "Microsoft Visual Studio Solution File, Format Version 10.00"); + z |= stream_writeline(strm, "# Visual Studio 2008"); + return z; +} diff --git a/src/action/vs200x/vs200x.c b/src/action/vs200x/vs200x.c index 2d19a0b..21b60ff 100644 --- a/src/action/vs200x/vs200x.c +++ b/src/action/vs200x/vs200x.c @@ -1,163 +1,163 @@ -/** - * \file vs200x.c - * \brief General purpose Visual Studio support functions. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include -#include -#include "premake.h" -#include "vs200x.h" -#include "base/cstr.h" -#include "base/error.h" - - -/** - * Write an XML attribute, adjusting for the differing Visual Studio formats. - * \param strm The output stream, the attribute will be written here. - * \param indent_size How far to indent (with tabs) the attribute. - * \param name The attribute name. - * \param value The attribute value; may contain printf-style formatting codes. - * \returns OKAY if successful. - */ -int vs200x_attribute(Stream strm, int indent_size, const char* name, const char* value, ...) -{ - va_list args; - int z = OKAY; - - va_start(args, value); - z |= stream_writeline(strm, ""); - z |= stream_write_n(strm, "\t", indent_size); - z |= stream_write(strm, "%s=\"", name); - z |= stream_vprintf(strm, value, args); - z |= stream_write(strm, "\""); - va_end(args); - return z; -} - - -/** - * Write the ending part of an XML tag, adjust for the differing Visual Studio formats. - * \param sess The current execution session. - * \param strm The output stream. - * \param level The XML element nesting level. - * \param markup The end tag markup. - * \returns OKAY if successful. - */ -int vs200x_element_end(Session sess, Stream strm, int level, const char* markup) -{ - int z; - int version = vs200x_get_target_version(sess); - if (version >= 2005) - { - z = stream_writeline(strm, ""); - if (markup[0] == '>') - { - level++; - } - z |= stream_write_n(strm, "\t", level); - z |= stream_writeline(strm, "%s", markup); - } - else - { - z = stream_writeline(strm, markup); - } - return z; -} - - -/** - * Return the Visual Studio version appropriate version of the string for a false - * value. Before 2005 this was "FALSE", after it is "false". - */ -const char* vs200x_false(Session sess) -{ - int version = vs200x_get_target_version(sess); - return (version < 2005) ? "FALSE" : "false"; -} - - -/** - * Converts the session action string to a Visual Studio version number. - * \param sess The current execution session. - * \returns The Visual Studio version number corresponding to the current action. - */ -int vs200x_get_target_version(Session sess) -{ - const char* action = session_get_action(sess); - if (cstr_eq(action, "vs2002")) - { - return 2002; - } - else if (cstr_eq(action, "vs2003")) - { - return 2003; - } - else if (cstr_eq(action, "vs2005")) - { - return 2005; - } - else if (cstr_eq(action, "vs2008")) - { - return 2008; - } - else - { - assert(0); - return 0; - } -} - - -/** - * Return the appropriate file extension for a particular project. - * \param prj The project object. - * \returns The appropriate project file extension, based on the project settings. - */ -const char* vs200x_project_file_extension(Project prj) -{ - const char* language = project_get_language(prj); - if (cstr_eq(language, "c") || cstr_eq(language, "c++")) - { - return ".vcproj"; - } - else - { - error_set("unsupported language '%s'", language); - return NULL; - } -} - - -/** - * Returns the Visual Studio GUID for a particular project type. - * \param language The programming language used in the project. - * \returns The GUID corresponding the programming language. - */ -const char* vs200x_tool_guid(const char* language) -{ - if (cstr_eq(language, "c") || cstr_eq(language, "c++")) - { - return "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942"; - } - else if (cstr_eq(language, "c#")) - { - return "FAE04EC0-301F-11D3-BF4B-00C04F79EFBC"; - } - else - { - error_set("unsupported language '%s'", language); - return NULL; - } -} - - -/** - * Return the Visual Studio version appropriate version of the string for a true - * value. Before 2005 this was "TRUE", after it is "true". - */ -const char* vs200x_true(Session sess) -{ - int version = vs200x_get_target_version(sess); - return (version < 2005) ? "TRUE" : "true"; -} +/** + * \file vs200x.c + * \brief General purpose Visual Studio support functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include +#include +#include "premake.h" +#include "vs200x.h" +#include "base/cstr.h" +#include "base/error.h" + + +/** + * Write an XML attribute, adjusting for the differing Visual Studio formats. + * \param strm The output stream, the attribute will be written here. + * \param indent_size How far to indent (with tabs) the attribute. + * \param name The attribute name. + * \param value The attribute value; may contain printf-style formatting codes. + * \returns OKAY if successful. + */ +int vs200x_attribute(Stream strm, int indent_size, const char* name, const char* value, ...) +{ + va_list args; + int z = OKAY; + + va_start(args, value); + z |= stream_writeline(strm, ""); + z |= stream_write_n(strm, "\t", indent_size); + z |= stream_write(strm, "%s=\"", name); + z |= stream_vprintf(strm, value, args); + z |= stream_write(strm, "\""); + va_end(args); + return z; +} + + +/** + * Write the ending part of an XML tag, adjust for the differing Visual Studio formats. + * \param sess The current execution session. + * \param strm The output stream. + * \param level The XML element nesting level. + * \param markup The end tag markup. + * \returns OKAY if successful. + */ +int vs200x_element_end(Session sess, Stream strm, int level, const char* markup) +{ + int z; + int version = vs200x_get_target_version(sess); + if (version >= 2005) + { + z = stream_writeline(strm, ""); + if (markup[0] == '>') + { + level++; + } + z |= stream_write_n(strm, "\t", level); + z |= stream_writeline(strm, "%s", markup); + } + else + { + z = stream_writeline(strm, markup); + } + return z; +} + + +/** + * Return the Visual Studio version appropriate version of the string for a false + * value. Before 2005 this was "FALSE", after it is "false". + */ +const char* vs200x_false(Session sess) +{ + int version = vs200x_get_target_version(sess); + return (version < 2005) ? "FALSE" : "false"; +} + + +/** + * Converts the session action string to a Visual Studio version number. + * \param sess The current execution session. + * \returns The Visual Studio version number corresponding to the current action. + */ +int vs200x_get_target_version(Session sess) +{ + const char* action = session_get_action(sess); + if (cstr_eq(action, "vs2002")) + { + return 2002; + } + else if (cstr_eq(action, "vs2003")) + { + return 2003; + } + else if (cstr_eq(action, "vs2005")) + { + return 2005; + } + else if (cstr_eq(action, "vs2008")) + { + return 2008; + } + else + { + assert(0); + return 0; + } +} + + +/** + * Return the appropriate file extension for a particular project. + * \param prj The project object. + * \returns The appropriate project file extension, based on the project settings. + */ +const char* vs200x_project_file_extension(Project prj) +{ + const char* language = project_get_language(prj); + if (cstr_eq(language, "c") || cstr_eq(language, "c++")) + { + return ".vcproj"; + } + else + { + error_set("unsupported language '%s'", language); + return NULL; + } +} + + +/** + * Returns the Visual Studio GUID for a particular project type. + * \param language The programming language used in the project. + * \returns The GUID corresponding the programming language. + */ +const char* vs200x_tool_guid(const char* language) +{ + if (cstr_eq(language, "c") || cstr_eq(language, "c++")) + { + return "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942"; + } + else if (cstr_eq(language, "c#")) + { + return "FAE04EC0-301F-11D3-BF4B-00C04F79EFBC"; + } + else + { + error_set("unsupported language '%s'", language); + return NULL; + } +} + + +/** + * Return the Visual Studio version appropriate version of the string for a true + * value. Before 2005 this was "TRUE", after it is "true". + */ +const char* vs200x_true(Session sess) +{ + int version = vs200x_get_target_version(sess); + return (version < 2005) ? "TRUE" : "true"; +} diff --git a/src/action/vs200x/vs200x.h b/src/action/vs200x/vs200x.h index ef3b39d..6035cd8 100644 --- a/src/action/vs200x/vs200x.h +++ b/src/action/vs200x/vs200x.h @@ -1,20 +1,20 @@ -/** - * \file vs200x.h - * \brief General purpose Visual Studio support functions. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ -#if !defined(PREMAKE_VS200X_H) -#define PREMAKE_VS200X_H - -#include "session/session.h" - -int vs200x_attribute(Stream strm, int indent_size, const char* name, const char* value, ...); -int vs200x_element_end(Session sess, Stream strm, int level, const char* markup); -const char* vs200x_false(Session sess); -int vs200x_get_target_version(Session sess); -const char* vs200x_project_file_extension(Project prj); -const char* vs200x_tool_guid(const char* language); -const char* vs200x_true(Session sess); - -#endif - +/** + * \file vs200x.h + * \brief General purpose Visual Studio support functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ +#if !defined(PREMAKE_VS200X_H) +#define PREMAKE_VS200X_H + +#include "session/session.h" + +int vs200x_attribute(Stream strm, int indent_size, const char* name, const char* value, ...); +int vs200x_element_end(Session sess, Stream strm, int level, const char* markup); +const char* vs200x_false(Session sess); +int vs200x_get_target_version(Session sess); +const char* vs200x_project_file_extension(Project prj); +const char* vs200x_tool_guid(const char* language); +const char* vs200x_true(Session sess); + +#endif + diff --git a/src/action/vs200x/vs200x_config.c b/src/action/vs200x/vs200x_config.c index 85afb07..24e4493 100644 --- a/src/action/vs200x/vs200x_config.c +++ b/src/action/vs200x/vs200x_config.c @@ -1,48 +1,48 @@ -/** - * \file vs200x_config.c - * \brief Visual Studio 200x configuration generation functions. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "vs200x.h" -#include "vs200x_config.h" - - -int vs200x_config_character_set(Session sess, Stream strm) -{ - int version = vs200x_get_target_version(sess); - return vs200x_attribute(strm, 3, "CharacterSet", version > 2003 ? "1" : "2"); -} - - -int vs200x_config_detect_64bit_portability(Session sess, Stream strm, Project prj) -{ - int version = vs200x_get_target_version(sess); - UNUSED(prj); - if (version < 2008) - { - return vs200x_attribute(strm, 4, "Detect64BitPortabilityProblems", vs200x_true(sess)); - } - return OKAY; -} - - -int vs200x_config_runtime_type_info(Session sess, Stream strm, Project prj) -{ - int version = vs200x_get_target_version(sess); - UNUSED(prj); - if (version < 2005) - { - return vs200x_attribute(strm, 4, "RuntimeTypeInfo", vs200x_true(sess)); - } - return OKAY; -} - - -int vs200x_config_use_precompiled_header(Session sess, Stream strm, Project prj) -{ - int version = vs200x_get_target_version(sess); - UNUSED(prj); - return vs200x_attribute(strm, 4, "UsePrecompiledHeader", (version > 2003) ? "0" : "2"); -} +/** + * \file vs200x_config.c + * \brief Visual Studio 200x configuration generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "vs200x.h" +#include "vs200x_config.h" + + +int vs200x_config_character_set(Session sess, Stream strm) +{ + int version = vs200x_get_target_version(sess); + return vs200x_attribute(strm, 3, "CharacterSet", version > 2003 ? "1" : "2"); +} + + +int vs200x_config_detect_64bit_portability(Session sess, Stream strm, Project prj) +{ + int version = vs200x_get_target_version(sess); + UNUSED(prj); + if (version < 2008) + { + return vs200x_attribute(strm, 4, "Detect64BitPortabilityProblems", vs200x_true(sess)); + } + return OKAY; +} + + +int vs200x_config_runtime_type_info(Session sess, Stream strm, Project prj) +{ + int version = vs200x_get_target_version(sess); + UNUSED(prj); + if (version < 2005) + { + return vs200x_attribute(strm, 4, "RuntimeTypeInfo", vs200x_true(sess)); + } + return OKAY; +} + + +int vs200x_config_use_precompiled_header(Session sess, Stream strm, Project prj) +{ + int version = vs200x_get_target_version(sess); + UNUSED(prj); + return vs200x_attribute(strm, 4, "UsePrecompiledHeader", (version > 2003) ? "0" : "2"); +} diff --git a/src/action/vs200x/vs200x_config.h b/src/action/vs200x/vs200x_config.h index 939eae6..54c1c03 100644 --- a/src/action/vs200x/vs200x_config.h +++ b/src/action/vs200x/vs200x_config.h @@ -1,16 +1,16 @@ -/** - * \file vs200x_config.h - * \brief Visual Studio 200x configuration generation functions. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ -#if !defined(PREMAKE_VS200X_CONFIG_H) -#define PREMAKE_VS200X_CONFIG_H - -#include "session/session.h" - -int vs200x_config_character_set(Session sess, Stream strm); -int vs200x_config_detect_64bit_portability(Session sess, Stream strm, Project prj); -int vs200x_config_runtime_type_info(Session sess, Stream strm, Project prj); -int vs200x_config_use_precompiled_header(Session sess, Stream strm, Project prj); - -#endif +/** + * \file vs200x_config.h + * \brief Visual Studio 200x configuration generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ +#if !defined(PREMAKE_VS200X_CONFIG_H) +#define PREMAKE_VS200X_CONFIG_H + +#include "session/session.h" + +int vs200x_config_character_set(Session sess, Stream strm); +int vs200x_config_detect_64bit_portability(Session sess, Stream strm, Project prj); +int vs200x_config_runtime_type_info(Session sess, Stream strm, Project prj); +int vs200x_config_use_precompiled_header(Session sess, Stream strm, Project prj); + +#endif diff --git a/src/action/vs200x/vs200x_project.c b/src/action/vs200x/vs200x_project.c index 9c73cbf..5c5f2a2 100644 --- a/src/action/vs200x/vs200x_project.c +++ b/src/action/vs200x/vs200x_project.c @@ -1,473 +1,473 @@ -/** - * \file vs200x_project.c - * \brief Visual Studio multiple-version project generation functions. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include -#include -#include "premake.h" -#include "action/action.h" -#include "vs200x.h" -#include "vs200x_project.h" -#include "vs200x_config.h" -#include "base/cstr.h" -#include "base/path.h" - - -/** - * Write the opening [Configuration] element and attributes. - */ -int vs200x_project_config_element(Session sess, Project prj, Stream strm) -{ - int z = OKAY; - const char* cfg_name = project_get_configuration_filter(prj); - z |= stream_write(strm, "\t\t"); - return z; -} - - -/** - * Write the closing [Configuration] element. - */ -int vs200x_project_config_end(Session sess, Project prj, Stream strm) -{ - UNUSED(sess); - UNUSED(prj); - return stream_writeline(strm, "\t\t"); -} - - -/** - * Create a new output stream for a project, and make it active for subsequent writes. - */ -int vs200x_project_create(Session sess, Project prj, Stream strm) -{ - /* create the project file */ - const char* extension = vs200x_project_file_extension(prj); - const char* filename = project_get_filename(prj, NULL, extension); - strm = stream_create_file(filename); - if (!strm) - { - return !OKAY; - } - - /* make the stream active for the functions that come after */ - session_set_active_stream(sess, strm); - return OKAY; -} - - -/** - * Write the root [VisualStudioProject] element and attributes. - */ -int vs200x_project_element(Session sess, Project prj, Stream strm) -{ - int version, z; - const char* prj_ver; - const char* prj_name = project_get_name(prj); - const char* prj_guid = project_get_guid(prj); - - version = vs200x_get_target_version(sess); - switch (version) - { - default: - prj_ver = "7.00"; break; - case 2003: - prj_ver = "7.10"; break; - case 2005: - prj_ver = "8.00"; break; - case 2008: - prj_ver = "9.00"; break; - } - - z = stream_write(strm, " 2003) - { - z |= vs200x_attribute(strm, 1, "RootNamespace", prj_name); - } - z |= vs200x_attribute(strm, 1, "Keyword", "Win32Proj"); - if (version > 2005) - { - z |= vs200x_attribute(strm, 1, "TargetFrameworkVersion", "196613"); - } - z |= vs200x_element_end(sess, strm, 0, ">"); - return z; -} - - -/** - * Write the file encoding at the start of the project file. - */ -int vs200x_project_encoding(Session sess, Project prj, Stream strm) -{ - UNUSED(sess); - UNUSED(prj); - stream_set_newline(strm, "\r\n"); - return stream_writeline(strm, ""); -} - - -/** - * Write an individual file entry to the project file; callback for action_source_tree(). - * \param sess The current execution session context. - * \param prj The current project; contains the file being enumerated. - * \param strm The active output stream; for writing the file markup. - * \param filename The name of the file to process. - * \param state One of the ActionSourceStates, enabling file grouping. - * \returns OKAY if successful. - */ -int vs200x_project_file(Session sess, Project prj, Stream strm, const char* filename, int state) -{ - const char* name; - const char* ptr; - int depth, z = OKAY; - - /* figure out the grouping depth, skipping over any leading dot directories */ - depth = 2; - - ptr = filename; - while (cstr_starts_with(ptr, "../")) - { - ptr += 3; - } - - ptr = strchr(ptr, '/'); - while (ptr != NULL) - { - depth++; - ptr = strchr(ptr + 1, '/'); - } - - /* group name is just the last bit of the path */ - name = path_filename(filename); - - /* use the Windows path separator */ - filename = path_translate(filename, "\\"); - - switch (state) - { - case GroupStart: - if (strlen(filename) > 0 && !cstr_eq(name, "..")) - { - z |= stream_write_n(strm, "\t", depth); - z |= stream_write(strm, ""); - } - break; - - case GroupEnd: - if (strlen(filename) > 0 && !cstr_eq(name, "..")) - { - z |= stream_write_n(strm, "\t", depth); - z |= stream_writeline(strm, ""); - } - break; - - case SourceFile: - z |= stream_write_n(strm, "\t", depth); - z |= stream_write(strm, ""); - z |= stream_write_n(strm, "\t", depth); - z |= stream_writeline(strm, ""); - break; - } - - UNUSED(prj); - return z; -} - - -/** - * Write out the [Files] element. - */ -int vs200x_project_files(Session sess, Project prj, Stream strm) -{ - int z = OKAY; - z |= stream_writeline(strm, "\t"); - z |= action_source_tree(sess, prj, strm, vs200x_project_file); - z |= stream_writeline(strm, "\t"); - return z; -} - - -/** - * Write out the [Globals] element. - */ -int vs200x_project_globals(Session sess, Project prj, Stream strm) -{ - int z = OKAY; - UNUSED(sess); - UNUSED(prj); - z |= stream_writeline(strm, "\t"); - z |= stream_writeline(strm, "\t"); - z |= stream_writeline(strm, ""); - return z; -} - - -/** - * Write out the platforms section of a project file. - */ -int vs200x_project_platforms(Session sess, Project prj, Stream strm) -{ - int z = OKAY; - UNUSED(prj); - z |= stream_writeline(strm, "\t"); - z |= stream_write(strm, "\t\t"); - z |= stream_writeline(strm, "\t"); - return OKAY; -} - - -/** - * Write out the [References] element and attributes. - */ -int vs200x_project_references(Session sess, Project prj, Stream strm) -{ - int z; - UNUSED(prj); - z = stream_writeline(strm, "\t"); - if (vs200x_get_target_version(sess) > 2002) - { - z |= stream_writeline(strm, "\t"); - z |= stream_writeline(strm, "\t"); - } - return z; -} - - -/** - * Write out the [ToolFiles] section of a Visual Studio project. - */ -int vs200x_project_tool_files(Session sess, Project prj, Stream strm) -{ - int version, z = OKAY; - UNUSED(prj); - - version = vs200x_get_target_version(sess); - if (version > 2003) - { - z |= stream_writeline(strm, "\t"); - z |= stream_writeline(strm, "\t"); - } - z |= stream_writeline(strm, "\t"); - return z; -} - - -/** - * Common function to write an empty [Tool] element. - */ -static int vs200x_project_vc_empty_tool(Session sess, Project prj, Stream strm, const char* name) -{ - int z; - UNUSED(prj); - z = stream_write(strm, "\t\t\t"); - return z; -} - - -/** - * Write the VCALinkTool [Tool] element and attributes. - */ -int vs200x_project_vc_alink_tool(Session sess, Project prj, Stream strm) -{ - return vs200x_project_vc_empty_tool(sess, prj, strm, "VCALinkTool"); -} - - -/** - * Write the VCAppVerifierTool [Tool] element and attributes. - */ -int vs200x_project_vc_app_verifier_tool(Session sess, Project prj, Stream strm) -{ - return vs200x_project_vc_empty_tool(sess, prj, strm, "VCAppVerifierTool"); -} - - -/** - * Write the VCBscMakeTool [Tool] element and attributes. - */ -int vs200x_project_vc_bsc_make_tool(Session sess, Project prj, Stream strm) -{ - return vs200x_project_vc_empty_tool(sess, prj, strm, "VCBscMakeTool"); -} - - -/** - * Write the VCCLCompilerTool [Tool] element and attributes. - */ -int vs200x_project_vc_cl_compiler_tool(Session sess, Project prj, Stream strm) -{ - int version, z; - UNUSED(prj); - version = vs200x_get_target_version(sess); - z = stream_write(strm, "\t\t\t"); - return z; -} - - -/** - * Write the VCCustomBuildTool [Tool] element and attributes. - */ -int vs200x_project_vc_custom_build_tool(Session sess, Project prj, Stream strm) -{ - return vs200x_project_vc_empty_tool(sess, prj, strm, "VCCustomBuildTool"); -} - - -/** - * Write the VCFxCopTool [Tool] element and attributes. - */ -int vs200x_project_vc_fx_cop_tool(Session sess, Project prj, Stream strm) -{ - return vs200x_project_vc_empty_tool(sess, prj, strm, "VCFxCopTool"); -} - - -/** - * Write the VCLinkerTool [Tool] element and attributes. - */ -int vs200x_project_vc_linker_tool(Session sess, Project prj, Stream strm) -{ - int z; - UNUSED(prj); - z = stream_write(strm, "\t\t\t"); - return z; -} - - -/** - * Write the VCManagedResourceCompilerTool [Tool] element and attributes. - */ -int vs200x_project_vc_managed_resource_compiler_tool(Session sess, Project prj, Stream strm) -{ - return vs200x_project_vc_empty_tool(sess, prj, strm, "VCManagedResourceCompilerTool"); -} - - -/** - * Write the VCManifestTool [Tool] element and attributes. - */ -int vs200x_project_vc_manifest_tool(Session sess, Project prj, Stream strm) -{ - return vs200x_project_vc_empty_tool(sess, prj, strm, "VCManifestTool"); -} - - -/** - * Write the VCMIDLTool [Tool] element and attributes. - */ -int vs200x_project_vc_midl_tool(Session sess, Project prj, Stream strm) -{ - return vs200x_project_vc_empty_tool(sess, prj, strm, "VCMIDLTool"); -} - - -/** - * Write the VCPreBuildEventTool [Tool] element and attributes. - */ -int vs200x_project_vc_pre_build_event_tool(Session sess, Project prj, Stream strm) -{ - return vs200x_project_vc_empty_tool(sess, prj, strm, "VCPreBuildEventTool"); -} - - -/** - * Write the VCPreLinkEventTool [Tool] element and attributes. - */ -int vs200x_project_vc_pre_link_event_tool(Session sess, Project prj, Stream strm) -{ - return vs200x_project_vc_empty_tool(sess, prj, strm, "VCPreLinkEventTool"); -} - - -/** - * Write the VCPostBuildEventTool [Tool] element and attributes. - */ -int vs200x_project_vc_post_build_event_tool(Session sess, Project prj, Stream strm) -{ - return vs200x_project_vc_empty_tool(sess, prj, strm, "VCPostBuildEventTool"); -} - - -/** - * Write the VCResourceCompiler [Tool] element and attributes. - */ -int vs200x_project_vc_resource_compiler_tool(Session sess, Project prj, Stream strm) -{ - return vs200x_project_vc_empty_tool(sess, prj, strm, "VCResourceCompilerTool"); -} - - -/** - * Write the VCWebDeploymentTool [Tool] element and attributes. - */ -int vs200x_project_vc_web_deployment_tool(Session sess, Project prj, Stream strm) -{ - return vs200x_project_vc_empty_tool(sess, prj, strm, "VCWebDeploymentTool"); -} - - -/** - * Write the VCWebServiceProxyGeneratorTool [Tool] element and attributes. - */ -int vs200x_project_vc_web_service_proxy_generator_tool(Session sess, Project prj, Stream strm) -{ - return vs200x_project_vc_empty_tool(sess, prj, strm, "VCWebServiceProxyGeneratorTool"); -} - - -/** - * Write the VCXDCMakeTool [Tool] element and attributes. - */ -int vs200x_project_vc_xdc_make_tool(Session sess, Project prj, Stream strm) -{ - return vs200x_project_vc_empty_tool(sess, prj, strm, "VCXDCMakeTool"); -} - - -/** - * Write the VCXMLDataGeneratorTool [Tool] element and attributes. - */ -int vs200x_project_vc_xml_data_generator_tool(Session sess, Project prj, Stream strm) -{ - return vs200x_project_vc_empty_tool(sess, prj, strm, "VCXMLDataGeneratorTool"); -} +/** + * \file vs200x_project.c + * \brief Visual Studio multiple-version project generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include +#include +#include "premake.h" +#include "action/action.h" +#include "vs200x.h" +#include "vs200x_project.h" +#include "vs200x_config.h" +#include "base/cstr.h" +#include "base/path.h" + + +/** + * Write the opening [Configuration] element and attributes. + */ +int vs200x_project_config_element(Session sess, Project prj, Stream strm) +{ + int z = OKAY; + const char* cfg_name = project_get_configuration_filter(prj); + z |= stream_write(strm, "\t\t"); + return z; +} + + +/** + * Write the closing [Configuration] element. + */ +int vs200x_project_config_end(Session sess, Project prj, Stream strm) +{ + UNUSED(sess); + UNUSED(prj); + return stream_writeline(strm, "\t\t"); +} + + +/** + * Create a new output stream for a project, and make it active for subsequent writes. + */ +int vs200x_project_create(Session sess, Project prj, Stream strm) +{ + /* create the project file */ + const char* extension = vs200x_project_file_extension(prj); + const char* filename = project_get_filename(prj, NULL, extension); + strm = stream_create_file(filename); + if (!strm) + { + return !OKAY; + } + + /* make the stream active for the functions that come after */ + session_set_active_stream(sess, strm); + return OKAY; +} + + +/** + * Write the root [VisualStudioProject] element and attributes. + */ +int vs200x_project_element(Session sess, Project prj, Stream strm) +{ + int version, z; + const char* prj_ver; + const char* prj_name = project_get_name(prj); + const char* prj_guid = project_get_guid(prj); + + version = vs200x_get_target_version(sess); + switch (version) + { + default: + prj_ver = "7.00"; break; + case 2003: + prj_ver = "7.10"; break; + case 2005: + prj_ver = "8.00"; break; + case 2008: + prj_ver = "9.00"; break; + } + + z = stream_write(strm, " 2003) + { + z |= vs200x_attribute(strm, 1, "RootNamespace", prj_name); + } + z |= vs200x_attribute(strm, 1, "Keyword", "Win32Proj"); + if (version > 2005) + { + z |= vs200x_attribute(strm, 1, "TargetFrameworkVersion", "196613"); + } + z |= vs200x_element_end(sess, strm, 0, ">"); + return z; +} + + +/** + * Write the file encoding at the start of the project file. + */ +int vs200x_project_encoding(Session sess, Project prj, Stream strm) +{ + UNUSED(sess); + UNUSED(prj); + stream_set_newline(strm, "\r\n"); + return stream_writeline(strm, ""); +} + + +/** + * Write an individual file entry to the project file; callback for action_source_tree(). + * \param sess The current execution session context. + * \param prj The current project; contains the file being enumerated. + * \param strm The active output stream; for writing the file markup. + * \param filename The name of the file to process. + * \param state One of the ActionSourceStates, enabling file grouping. + * \returns OKAY if successful. + */ +int vs200x_project_file(Session sess, Project prj, Stream strm, const char* filename, int state) +{ + const char* name; + const char* ptr; + int depth, z = OKAY; + + /* figure out the grouping depth, skipping over any leading dot directories */ + depth = 2; + + ptr = filename; + while (cstr_starts_with(ptr, "../")) + { + ptr += 3; + } + + ptr = strchr(ptr, '/'); + while (ptr != NULL) + { + depth++; + ptr = strchr(ptr + 1, '/'); + } + + /* group name is just the last bit of the path */ + name = path_filename(filename); + + /* use the Windows path separator */ + filename = path_translate(filename, "\\"); + + switch (state) + { + case GroupStart: + if (strlen(filename) > 0 && !cstr_eq(name, "..")) + { + z |= stream_write_n(strm, "\t", depth); + z |= stream_write(strm, ""); + } + break; + + case GroupEnd: + if (strlen(filename) > 0 && !cstr_eq(name, "..")) + { + z |= stream_write_n(strm, "\t", depth); + z |= stream_writeline(strm, ""); + } + break; + + case SourceFile: + z |= stream_write_n(strm, "\t", depth); + z |= stream_write(strm, ""); + z |= stream_write_n(strm, "\t", depth); + z |= stream_writeline(strm, ""); + break; + } + + UNUSED(prj); + return z; +} + + +/** + * Write out the [Files] element. + */ +int vs200x_project_files(Session sess, Project prj, Stream strm) +{ + int z = OKAY; + z |= stream_writeline(strm, "\t"); + z |= action_source_tree(sess, prj, strm, vs200x_project_file); + z |= stream_writeline(strm, "\t"); + return z; +} + + +/** + * Write out the [Globals] element. + */ +int vs200x_project_globals(Session sess, Project prj, Stream strm) +{ + int z = OKAY; + UNUSED(sess); + UNUSED(prj); + z |= stream_writeline(strm, "\t"); + z |= stream_writeline(strm, "\t"); + z |= stream_writeline(strm, ""); + return z; +} + + +/** + * Write out the platforms section of a project file. + */ +int vs200x_project_platforms(Session sess, Project prj, Stream strm) +{ + int z = OKAY; + UNUSED(prj); + z |= stream_writeline(strm, "\t"); + z |= stream_write(strm, "\t\t"); + z |= stream_writeline(strm, "\t"); + return OKAY; +} + + +/** + * Write out the [References] element and attributes. + */ +int vs200x_project_references(Session sess, Project prj, Stream strm) +{ + int z; + UNUSED(prj); + z = stream_writeline(strm, "\t"); + if (vs200x_get_target_version(sess) > 2002) + { + z |= stream_writeline(strm, "\t"); + z |= stream_writeline(strm, "\t"); + } + return z; +} + + +/** + * Write out the [ToolFiles] section of a Visual Studio project. + */ +int vs200x_project_tool_files(Session sess, Project prj, Stream strm) +{ + int version, z = OKAY; + UNUSED(prj); + + version = vs200x_get_target_version(sess); + if (version > 2003) + { + z |= stream_writeline(strm, "\t"); + z |= stream_writeline(strm, "\t"); + } + z |= stream_writeline(strm, "\t"); + return z; +} + + +/** + * Common function to write an empty [Tool] element. + */ +static int vs200x_project_vc_empty_tool(Session sess, Project prj, Stream strm, const char* name) +{ + int z; + UNUSED(prj); + z = stream_write(strm, "\t\t\t"); + return z; +} + + +/** + * Write the VCALinkTool [Tool] element and attributes. + */ +int vs200x_project_vc_alink_tool(Session sess, Project prj, Stream strm) +{ + return vs200x_project_vc_empty_tool(sess, prj, strm, "VCALinkTool"); +} + + +/** + * Write the VCAppVerifierTool [Tool] element and attributes. + */ +int vs200x_project_vc_app_verifier_tool(Session sess, Project prj, Stream strm) +{ + return vs200x_project_vc_empty_tool(sess, prj, strm, "VCAppVerifierTool"); +} + + +/** + * Write the VCBscMakeTool [Tool] element and attributes. + */ +int vs200x_project_vc_bsc_make_tool(Session sess, Project prj, Stream strm) +{ + return vs200x_project_vc_empty_tool(sess, prj, strm, "VCBscMakeTool"); +} + + +/** + * Write the VCCLCompilerTool [Tool] element and attributes. + */ +int vs200x_project_vc_cl_compiler_tool(Session sess, Project prj, Stream strm) +{ + int version, z; + UNUSED(prj); + version = vs200x_get_target_version(sess); + z = stream_write(strm, "\t\t\t"); + return z; +} + + +/** + * Write the VCCustomBuildTool [Tool] element and attributes. + */ +int vs200x_project_vc_custom_build_tool(Session sess, Project prj, Stream strm) +{ + return vs200x_project_vc_empty_tool(sess, prj, strm, "VCCustomBuildTool"); +} + + +/** + * Write the VCFxCopTool [Tool] element and attributes. + */ +int vs200x_project_vc_fx_cop_tool(Session sess, Project prj, Stream strm) +{ + return vs200x_project_vc_empty_tool(sess, prj, strm, "VCFxCopTool"); +} + + +/** + * Write the VCLinkerTool [Tool] element and attributes. + */ +int vs200x_project_vc_linker_tool(Session sess, Project prj, Stream strm) +{ + int z; + UNUSED(prj); + z = stream_write(strm, "\t\t\t"); + return z; +} + + +/** + * Write the VCManagedResourceCompilerTool [Tool] element and attributes. + */ +int vs200x_project_vc_managed_resource_compiler_tool(Session sess, Project prj, Stream strm) +{ + return vs200x_project_vc_empty_tool(sess, prj, strm, "VCManagedResourceCompilerTool"); +} + + +/** + * Write the VCManifestTool [Tool] element and attributes. + */ +int vs200x_project_vc_manifest_tool(Session sess, Project prj, Stream strm) +{ + return vs200x_project_vc_empty_tool(sess, prj, strm, "VCManifestTool"); +} + + +/** + * Write the VCMIDLTool [Tool] element and attributes. + */ +int vs200x_project_vc_midl_tool(Session sess, Project prj, Stream strm) +{ + return vs200x_project_vc_empty_tool(sess, prj, strm, "VCMIDLTool"); +} + + +/** + * Write the VCPreBuildEventTool [Tool] element and attributes. + */ +int vs200x_project_vc_pre_build_event_tool(Session sess, Project prj, Stream strm) +{ + return vs200x_project_vc_empty_tool(sess, prj, strm, "VCPreBuildEventTool"); +} + + +/** + * Write the VCPreLinkEventTool [Tool] element and attributes. + */ +int vs200x_project_vc_pre_link_event_tool(Session sess, Project prj, Stream strm) +{ + return vs200x_project_vc_empty_tool(sess, prj, strm, "VCPreLinkEventTool"); +} + + +/** + * Write the VCPostBuildEventTool [Tool] element and attributes. + */ +int vs200x_project_vc_post_build_event_tool(Session sess, Project prj, Stream strm) +{ + return vs200x_project_vc_empty_tool(sess, prj, strm, "VCPostBuildEventTool"); +} + + +/** + * Write the VCResourceCompiler [Tool] element and attributes. + */ +int vs200x_project_vc_resource_compiler_tool(Session sess, Project prj, Stream strm) +{ + return vs200x_project_vc_empty_tool(sess, prj, strm, "VCResourceCompilerTool"); +} + + +/** + * Write the VCWebDeploymentTool [Tool] element and attributes. + */ +int vs200x_project_vc_web_deployment_tool(Session sess, Project prj, Stream strm) +{ + return vs200x_project_vc_empty_tool(sess, prj, strm, "VCWebDeploymentTool"); +} + + +/** + * Write the VCWebServiceProxyGeneratorTool [Tool] element and attributes. + */ +int vs200x_project_vc_web_service_proxy_generator_tool(Session sess, Project prj, Stream strm) +{ + return vs200x_project_vc_empty_tool(sess, prj, strm, "VCWebServiceProxyGeneratorTool"); +} + + +/** + * Write the VCXDCMakeTool [Tool] element and attributes. + */ +int vs200x_project_vc_xdc_make_tool(Session sess, Project prj, Stream strm) +{ + return vs200x_project_vc_empty_tool(sess, prj, strm, "VCXDCMakeTool"); +} + + +/** + * Write the VCXMLDataGeneratorTool [Tool] element and attributes. + */ +int vs200x_project_vc_xml_data_generator_tool(Session sess, Project prj, Stream strm) +{ + return vs200x_project_vc_empty_tool(sess, prj, strm, "VCXMLDataGeneratorTool"); +} diff --git a/src/action/vs200x/vs200x_project.h b/src/action/vs200x/vs200x_project.h index accb053..a4950f9 100644 --- a/src/action/vs200x/vs200x_project.h +++ b/src/action/vs200x/vs200x_project.h @@ -1,41 +1,41 @@ -/** - * \file vs200x_project.h - * \brief Visual Studio 200x project generation functions. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ -#if !defined(PREMAKE_VS200X_PROJECT_H) -#define PREMAKE_VS200X_PROJECT_H - -#include "session/session.h" - -int vs200x_project_config_element(Session sess, Project prj, Stream strm); -int vs200x_project_config_end(Session sess, Project prj, Stream strm); -int vs200x_project_create(Session sess, Project prj, Stream strm); -int vs200x_project_element(Session sess, Project prj, Stream strm); -int vs200x_project_encoding(Session sess, Project prj, Stream strm); -int vs200x_project_file(Session sess, Project prj, Stream strm, const char* filename, int state); -int vs200x_project_files(Session sess, Project prj, Stream strm); -int vs200x_project_globals(Session sess, Project prj, Stream strm); -int vs200x_project_platforms(Session sess, Project prj, Stream strm); -int vs200x_project_references(Session sess, Project prj, Stream strm); -int vs200x_project_tool_files(Session sess, Project prj, Stream strm); -int vs200x_project_vc_alink_tool(Session sess, Project prj, Stream strm); -int vs200x_project_vc_app_verifier_tool(Session sess, Project prj, Stream strm); -int vs200x_project_vc_bsc_make_tool(Session sess, Project prj, Stream strm); -int vs200x_project_vc_cl_compiler_tool(Session sess, Project prj, Stream strm); -int vs200x_project_vc_custom_build_tool(Session sess, Project prj, Stream strm); -int vs200x_project_vc_fx_cop_tool(Session sess, Project prj, Stream strm); -int vs200x_project_vc_midl_tool(Session sess, Project prj, Stream strm); -int vs200x_project_vc_linker_tool(Session sess, Project prj, Stream strm); -int vs200x_project_vc_managed_resource_compiler_tool(Session sess, Project prj, Stream strm); -int vs200x_project_vc_manifest_tool(Session sess, Project prj, Stream strm); -int vs200x_project_vc_pre_build_event_tool(Session sess, Project prj, Stream strm); -int vs200x_project_vc_pre_link_event_tool(Session sess, Project prj, Stream strm); -int vs200x_project_vc_post_build_event_tool(Session sess, Project prj, Stream strm); -int vs200x_project_vc_resource_compiler_tool(Session sess, Project prj, Stream strm); -int vs200x_project_vc_web_deployment_tool(Session sess, Project prj, Stream strm); -int vs200x_project_vc_web_service_proxy_generator_tool(Session sess, Project prj, Stream strm); -int vs200x_project_vc_xdc_make_tool(Session sess, Project prj, Stream strm); -int vs200x_project_vc_xml_data_generator_tool(Session sess, Project prj, Stream strm); - -#endif +/** + * \file vs200x_project.h + * \brief Visual Studio 200x project generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ +#if !defined(PREMAKE_VS200X_PROJECT_H) +#define PREMAKE_VS200X_PROJECT_H + +#include "session/session.h" + +int vs200x_project_config_element(Session sess, Project prj, Stream strm); +int vs200x_project_config_end(Session sess, Project prj, Stream strm); +int vs200x_project_create(Session sess, Project prj, Stream strm); +int vs200x_project_element(Session sess, Project prj, Stream strm); +int vs200x_project_encoding(Session sess, Project prj, Stream strm); +int vs200x_project_file(Session sess, Project prj, Stream strm, const char* filename, int state); +int vs200x_project_files(Session sess, Project prj, Stream strm); +int vs200x_project_globals(Session sess, Project prj, Stream strm); +int vs200x_project_platforms(Session sess, Project prj, Stream strm); +int vs200x_project_references(Session sess, Project prj, Stream strm); +int vs200x_project_tool_files(Session sess, Project prj, Stream strm); +int vs200x_project_vc_alink_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_app_verifier_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_bsc_make_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_cl_compiler_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_custom_build_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_fx_cop_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_midl_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_linker_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_managed_resource_compiler_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_manifest_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_pre_build_event_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_pre_link_event_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_post_build_event_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_resource_compiler_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_web_deployment_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_web_service_proxy_generator_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_xdc_make_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_xml_data_generator_tool(Session sess, Project prj, Stream strm); + +#endif diff --git a/src/action/vs200x/vs200x_solution.c b/src/action/vs200x/vs200x_solution.c index 577155e..6578bd4 100644 --- a/src/action/vs200x/vs200x_solution.c +++ b/src/action/vs200x/vs200x_solution.c @@ -1,33 +1,33 @@ -/** - * \file vs200x_solution.c - * \brief Visual Studio multiple-version solution generation functions. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include -#include "premake.h" -#include "vs200x.h" -#include "vs200x_solution.h" - - -/** - * Create a new output stream for a solution, and make it active for subsequent writes. - * \param sess The execution session context. - * \param sln The current solution. - * \param strm The currently active stream; set with session_set_active_stream(). - * \returns OKAY if successful. - */ -int vs200x_solution_create(Session sess, Solution sln, Stream strm) -{ - /* create the solution file */ - const char* filename = solution_get_filename(sln, NULL, ".sln"); - strm = stream_create_file(filename); - if (!strm) - { - return !OKAY; - } - - /* make the stream active for the functions that come after */ - session_set_active_stream(sess, strm); - return OKAY; -} +/** + * \file vs200x_solution.c + * \brief Visual Studio multiple-version solution generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include +#include "premake.h" +#include "vs200x.h" +#include "vs200x_solution.h" + + +/** + * Create a new output stream for a solution, and make it active for subsequent writes. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int vs200x_solution_create(Session sess, Solution sln, Stream strm) +{ + /* create the solution file */ + const char* filename = solution_get_filename(sln, NULL, ".sln"); + strm = stream_create_file(filename); + if (!strm) + { + return !OKAY; + } + + /* make the stream active for the functions that come after */ + session_set_active_stream(sess, strm); + return OKAY; +} diff --git a/src/action/vs200x/vs200x_solution.h b/src/action/vs200x/vs200x_solution.h index d52a474..18683c4 100644 --- a/src/action/vs200x/vs200x_solution.h +++ b/src/action/vs200x/vs200x_solution.h @@ -1,30 +1,30 @@ -/** - * \file vs200x_solution.h - * \brief Visual Studio 200x solution generation functions. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ -#if !defined(PREMAKE_VS200X_SOLUTION_H) -#define PREMAKE_VS200X_SOLUTION_H - -#include "session/session.h" - -int vs2002_solution_configuration(Session sess, Solution sln, Stream strm); -int vs2002_solution_dependencies(Session sess, Solution sln, Stream strm); -int vs2002_solution_extensibility(Session sess, Solution sln, Stream strm); -int vs2002_solution_project_configuration(Session sess, Solution sln, Stream strm); -int vs2002_solution_projects(Session sess, Solution sln, Stream strm); -int vs2002_solution_signature(Session sess, Solution sln, Stream strm); - -int vs2003_solution_configuration(Session sess, Solution sln, Stream strm); -int vs2003_solution_signature(Session sess, Solution sln, Stream strm); - -int vs2005_solution_platforms(Session sess, Solution sln, Stream strm); -int vs2005_solution_project_platforms(Session sess, Solution sln, Stream strm); -int vs2005_solution_properties(Session sess, Solution sln, Stream strm); -int vs2005_solution_signature(Session sess, Solution sln, Stream strm); - -int vs2008_solution_signature(Session sess, Solution sln, Stream strm); - -int vs200x_solution_create(Session sess, Solution sln, Stream strm); - -#endif +/** + * \file vs200x_solution.h + * \brief Visual Studio 200x solution generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ +#if !defined(PREMAKE_VS200X_SOLUTION_H) +#define PREMAKE_VS200X_SOLUTION_H + +#include "session/session.h" + +int vs2002_solution_configuration(Session sess, Solution sln, Stream strm); +int vs2002_solution_dependencies(Session sess, Solution sln, Stream strm); +int vs2002_solution_extensibility(Session sess, Solution sln, Stream strm); +int vs2002_solution_project_configuration(Session sess, Solution sln, Stream strm); +int vs2002_solution_projects(Session sess, Solution sln, Stream strm); +int vs2002_solution_signature(Session sess, Solution sln, Stream strm); + +int vs2003_solution_configuration(Session sess, Solution sln, Stream strm); +int vs2003_solution_signature(Session sess, Solution sln, Stream strm); + +int vs2005_solution_platforms(Session sess, Solution sln, Stream strm); +int vs2005_solution_project_platforms(Session sess, Solution sln, Stream strm); +int vs2005_solution_properties(Session sess, Solution sln, Stream strm); +int vs2005_solution_signature(Session sess, Solution sln, Stream strm); + +int vs2008_solution_signature(Session sess, Solution sln, Stream strm); + +int vs200x_solution_create(Session sess, Solution sln, Stream strm); + +#endif diff --git a/src/base/array.c b/src/base/array.c index e000257..e6747b1 100644 --- a/src/base/array.c +++ b/src/base/array.c @@ -1,111 +1,111 @@ -/** - * \file array.c - * \brief Dynamic array object. - * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project - */ - -#include -#include "premake.h" -#include "base/array.h" - -#define INITIAL_SIZE 16 - -DEFINE_CLASS(Array) -{ - void** contents; - int size; - int capacity; -}; - - -/** - * Create a new, empty array object. - * \returns A new array object. - */ -Array array_create() -{ - Array arr = ALLOC_CLASS(Array); - arr->contents = (void**)malloc(sizeof(void*) * INITIAL_SIZE); - arr->size = 0; - arr->capacity = INITIAL_SIZE; - return arr; -} - - -/** - * Destroy an array object and release the associated memory. - * \param arr The array to destroy. - */ -void array_destroy(Array arr) -{ - free(arr->contents); - free(arr); -} - - -/** - * Get the number of item in the array. - * \param arr The array to query. - * \returns The number elements currently in the array. - */ -int array_size(Array arr) -{ - return arr->size; -} - - -/** - * Add a new item to the end of the array, growing the array if necessary. - * \param arr The array object. - * \param item The item to add. - */ -void array_add(Array arr, void* item) -{ - if (arr->size == arr->capacity) - { - arr->capacity *= 2; - arr->contents = (void**)realloc(arr->contents, arr->capacity); - } - - arr->contents[arr->size] = item; - arr->size++; -} - - -/** - * Retrieve the item at the specified index in the array. - * \param arr The array to query. - * \param index The index of the item to retrieve. - * \returns A pointer to the item. - */ -void* array_item(Array arr, int index) -{ - return arr->contents[index]; -} - - -/** - * Store an item at a particular index in the array, overwriting any existing value. - * \param arr The array. - * \param index The index at which to store the item - * \param item The new item. - */ -void array_set(Array arr, int index, void* item) -{ - arr->contents[index] = item; -} - - -/** - * Append the contents of one array to another. - * \param dest The destination array. - * \param src The source array. - */ -void array_append(Array dest, Array src) -{ - int i; - for (i = 0; i < src->size; ++i) - { - array_add(dest, src->contents[i]); - } -} +/** + * \file array.c + * \brief Dynamic array object. + * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project + */ + +#include +#include "premake.h" +#include "base/array.h" + +#define INITIAL_SIZE 16 + +DEFINE_CLASS(Array) +{ + void** contents; + int size; + int capacity; +}; + + +/** + * Create a new, empty array object. + * \returns A new array object. + */ +Array array_create() +{ + Array arr = ALLOC_CLASS(Array); + arr->contents = (void**)malloc(sizeof(void*) * INITIAL_SIZE); + arr->size = 0; + arr->capacity = INITIAL_SIZE; + return arr; +} + + +/** + * Destroy an array object and release the associated memory. + * \param arr The array to destroy. + */ +void array_destroy(Array arr) +{ + free(arr->contents); + free(arr); +} + + +/** + * Get the number of item in the array. + * \param arr The array to query. + * \returns The number elements currently in the array. + */ +int array_size(Array arr) +{ + return arr->size; +} + + +/** + * Add a new item to the end of the array, growing the array if necessary. + * \param arr The array object. + * \param item The item to add. + */ +void array_add(Array arr, void* item) +{ + if (arr->size == arr->capacity) + { + arr->capacity *= 2; + arr->contents = (void**)realloc(arr->contents, arr->capacity); + } + + arr->contents[arr->size] = item; + arr->size++; +} + + +/** + * Retrieve the item at the specified index in the array. + * \param arr The array to query. + * \param index The index of the item to retrieve. + * \returns A pointer to the item. + */ +void* array_item(Array arr, int index) +{ + return arr->contents[index]; +} + + +/** + * Store an item at a particular index in the array, overwriting any existing value. + * \param arr The array. + * \param index The index at which to store the item + * \param item The new item. + */ +void array_set(Array arr, int index, void* item) +{ + arr->contents[index] = item; +} + + +/** + * Append the contents of one array to another. + * \param dest The destination array. + * \param src The source array. + */ +void array_append(Array dest, Array src) +{ + int i; + for (i = 0; i < src->size; ++i) + { + array_add(dest, src->contents[i]); + } +} diff --git a/src/base/array.h b/src/base/array.h index e128779..e4deea2 100644 --- a/src/base/array.h +++ b/src/base/array.h @@ -1,27 +1,27 @@ -/** - * \file array.h - * \brief Dynamic array object. - * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project - * - * \defgroup array Array - * \ingroup base - * - * A dynamic array class. - * - * @{ - */ -#if !defined(PREMAKE_ARRAY_H) -#define PREMAKE_ARRAY_H - -DECLARE_CLASS(Array); - -Array array_create(void); -void array_destroy(Array arr); -int array_size(Array arr); -void array_add(Array arr, void* item); -void* array_item(Array arr, int index); -void array_set(Array arr, int index, void* item); -void array_append(Array dest, Array src); - -#endif -/** @} */ +/** + * \file array.h + * \brief Dynamic array object. + * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project + * + * \defgroup array Array + * \ingroup base + * + * A dynamic array class. + * + * @{ + */ +#if !defined(PREMAKE_ARRAY_H) +#define PREMAKE_ARRAY_H + +DECLARE_CLASS(Array); + +Array array_create(void); +void array_destroy(Array arr); +int array_size(Array arr); +void array_add(Array arr, void* item); +void* array_item(Array arr, int index); +void array_set(Array arr, int index, void* item); +void array_append(Array dest, Array src); + +#endif +/** @} */ diff --git a/src/base/base.h b/src/base/base.h index 6f5d82f..bed7f27 100644 --- a/src/base/base.h +++ b/src/base/base.h @@ -1,12 +1,12 @@ -/** - * \file base.h - * \brief Premake base library API. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - * - * \defgroup base Base - * - * This component defines all of the base classes required by the higher-level - * functions of Premake. - */ - -int base_tests(); +/** + * \file base.h + * \brief Premake base library API. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + * + * \defgroup base Base + * + * This component defines all of the base classes required by the higher-level + * functions of Premake. + */ + +int base_tests(); diff --git a/src/base/buffers.c b/src/base/buffers.c index 9e14092..42edd58 100644 --- a/src/base/buffers.c +++ b/src/base/buffers.c @@ -1,85 +1,85 @@ -/** - * \file buffers.c - * \brief Shared working buffer system. - * \author Copyright (c) 2007-2007 Jason Perkins and the Premake project - * - * \note I need to do a lot of string building operations in Premake. Rather than - * constantly creating, resizing, and releasing (and forgetting to release) - * dynamic string buffers, I use this shared buffer pool instead. Each request - * to buffer_next() returns the next buffer in the list. Pointers to the buffers - * can be safely passed around, and I don't need to remember to release anything - * when I'm done. The buffers should only be used for transient values, obviously. - * If you need to keep a value around for any length of time copy it to a string. - * - * \note The size and number of the buffers is arbitrary; I just picked some numbers - * that seemed big enough. - */ - -#include -#include "premake.h" -#include "base/buffers.h" - -/** The size of an individual buffer, in bytes. */ -const int BUFFER_SIZE = 0x4000; - -/** The number of buffers stored in the pool */ -static const int NUM_BUFFERS = 64; - -/** The pool of buffers */ -static char** buffers = NULL; - -/** The index of the next available buffer */ -static int next = 0; - - -/** - * Clean up after the buffer system. Called by atexit(). - */ -static void buffers_destroy(void) -{ - if (buffers != NULL) - { - int i; - for (i = 0; i < NUM_BUFFERS; ++i) - { - free(buffers[i]); - } - free(buffers); - } -} - - -/** - * Initialize the buffer system. - */ -static void buffers_create(void) -{ - int i; - buffers = (char**)malloc(sizeof(char*) * NUM_BUFFERS); - for (i = 0; i < NUM_BUFFERS; ++i) - { - buffers[i] = (char*)malloc(BUFFER_SIZE); - } - next = 0; - atexit(buffers_destroy); -} - - -/** - * Get a clean buffer. - * \returns An empty buffer. - */ -char * buffers_next() -{ - /* if this is the first call, initialize the buffer system */ - if (buffers == NULL) - buffers_create(); - - next++; - if (next == NUM_BUFFERS) - next = 0; - - /* initialize new buffers to empty string */ - buffers[next][0] = '\0'; - return buffers[next]; -} +/** + * \file buffers.c + * \brief Shared working buffer system. + * \author Copyright (c) 2007-2007 Jason Perkins and the Premake project + * + * \note I need to do a lot of string building operations in Premake. Rather than + * constantly creating, resizing, and releasing (and forgetting to release) + * dynamic string buffers, I use this shared buffer pool instead. Each request + * to buffer_next() returns the next buffer in the list. Pointers to the buffers + * can be safely passed around, and I don't need to remember to release anything + * when I'm done. The buffers should only be used for transient values, obviously. + * If you need to keep a value around for any length of time copy it to a string. + * + * \note The size and number of the buffers is arbitrary; I just picked some numbers + * that seemed big enough. + */ + +#include +#include "premake.h" +#include "base/buffers.h" + +/** The size of an individual buffer, in bytes. */ +const int BUFFER_SIZE = 0x4000; + +/** The number of buffers stored in the pool */ +static const int NUM_BUFFERS = 64; + +/** The pool of buffers */ +static char** buffers = NULL; + +/** The index of the next available buffer */ +static int next = 0; + + +/** + * Clean up after the buffer system. Called by atexit(). + */ +static void buffers_destroy(void) +{ + if (buffers != NULL) + { + int i; + for (i = 0; i < NUM_BUFFERS; ++i) + { + free(buffers[i]); + } + free(buffers); + } +} + + +/** + * Initialize the buffer system. + */ +static void buffers_create(void) +{ + int i; + buffers = (char**)malloc(sizeof(char*) * NUM_BUFFERS); + for (i = 0; i < NUM_BUFFERS; ++i) + { + buffers[i] = (char*)malloc(BUFFER_SIZE); + } + next = 0; + atexit(buffers_destroy); +} + + +/** + * Get a clean buffer. + * \returns An empty buffer. + */ +char * buffers_next() +{ + /* if this is the first call, initialize the buffer system */ + if (buffers == NULL) + buffers_create(); + + next++; + if (next == NUM_BUFFERS) + next = 0; + + /* initialize new buffers to empty string */ + buffers[next][0] = '\0'; + return buffers[next]; +} diff --git a/src/base/buffers.h b/src/base/buffers.h index 7fff300..5bb058c 100644 --- a/src/base/buffers.h +++ b/src/base/buffers.h @@ -1,25 +1,25 @@ -/** - * \file buffers.h - * \brief Shared working buffer system. - * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project - * - * \defgroup buffers Buffers - * \ingroup base - * - * A shared working buffer collection. A buffer can be requested from the system, filled, - * and passed around for a short period of time. This system allows transient string values - * to be returned from functions and immediately used without having to resort to - * full-blown string objects, and the ownership issues that would entail. - * - * @{ - */ -#if !defined(PREMAKE_BUFFER_H) -#define PREMAKE_BUFFER_H - -extern const int BUFFER_SIZE; - -char* buffers_next(void); - -#endif -/** @} */ - +/** + * \file buffers.h + * \brief Shared working buffer system. + * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project + * + * \defgroup buffers Buffers + * \ingroup base + * + * A shared working buffer collection. A buffer can be requested from the system, filled, + * and passed around for a short period of time. This system allows transient string values + * to be returned from functions and immediately used without having to resort to + * full-blown string objects, and the ownership issues that would entail. + * + * @{ + */ +#if !defined(PREMAKE_BUFFER_H) +#define PREMAKE_BUFFER_H + +extern const int BUFFER_SIZE; + +char* buffers_next(void); + +#endif +/** @} */ + diff --git a/src/base/cstr.c b/src/base/cstr.c index 517e8fe..ea3bd30 100644 --- a/src/base/cstr.c +++ b/src/base/cstr.c @@ -1,124 +1,124 @@ -/** - * \file cstr.c - * \brief C string handling. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include -#include -#include -#include -#include "premake.h" -#include "base/buffers.h" -#include "base/cstr.h" - - -/** - * Determines if the sequence appears anywhere in the target string. - * \param str The string to test. - * \param expected The sequence to search for. - * \returns True if the sequence is contained in the string. - */ -int cstr_contains(const char* str, const char* expected) -{ - return (strstr(str, expected) != NULL); -} - - -/** - * Determines if the string ends with a particular sequence. - * \param str The string to test. - * \param expected The sequence for which to look. - * \returns True if the string ends with the sequence, false otherwise. - */ -int cstr_ends_with(const char* str, const char* expected) -{ - if (str != NULL && expected != NULL) - { - int str_len = strlen(str); - int exp_len = strlen(expected); - if (str_len >= exp_len) - { - const char* start = str + str_len - exp_len; - return (strcmp(start, expected) == 0); - } - } - return 0; -} - - -/** - * Compares two C strings for equality. - * \param str The string to compare. - * \param expected The value to compare against. - * \returns True if the strings match, zero otherwise. - */ -int cstr_eq(const char* str, const char* expected) -{ - if (str != NULL && expected != NULL) - { - return (strcmp(str, expected) == 0); - } - return 0; -} - - -/** - * Performs a case-insensitive comparasion on two C strings for equality. - * \param str The string to compare. - * \param expected The value to compare against. - * \returns True if the strings match, zero otherwise. - */ -int cstr_eqi(const char* str, const char* expected) -{ - if (str != NULL && expected != NULL) - { - while (*str && *expected) - { - if (tolower(*str) != tolower(*expected)) - { - return 0; - } - - str++; - expected++; - } - - return (*str == *expected); - } - return 0; -} - - -/** - * Builds a string using printf-style formatting codes. - * \param format The format string, which may contain printf-style formatting codes. - * \returns The formatted string. - */ -char* cstr_format(const char* format, ...) -{ - va_list args; - char* buffer = buffers_next(); - - va_start(args, format); - vsprintf(buffer, format, args); - va_end(args); - - return buffer; -} - - -/** - * Determines if the given C string starts with a particular sequence. - * \param str The string to test. - * \param expected The sequence for which to look. - * \returns True if the string starts with the sequence, false otherwise. - */ -int cstr_starts_with(const char* str, const char* expected) -{ - if (str != NULL && expected != NULL) - { - return (strncmp(str, expected, strlen(expected)) == 0); - } - return 0; -} +/** + * \file cstr.c + * \brief C string handling. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include +#include +#include +#include +#include "premake.h" +#include "base/buffers.h" +#include "base/cstr.h" + + +/** + * Determines if the sequence appears anywhere in the target string. + * \param str The string to test. + * \param expected The sequence to search for. + * \returns True if the sequence is contained in the string. + */ +int cstr_contains(const char* str, const char* expected) +{ + return (strstr(str, expected) != NULL); +} + + +/** + * Determines if the string ends with a particular sequence. + * \param str The string to test. + * \param expected The sequence for which to look. + * \returns True if the string ends with the sequence, false otherwise. + */ +int cstr_ends_with(const char* str, const char* expected) +{ + if (str != NULL && expected != NULL) + { + int str_len = strlen(str); + int exp_len = strlen(expected); + if (str_len >= exp_len) + { + const char* start = str + str_len - exp_len; + return (strcmp(start, expected) == 0); + } + } + return 0; +} + + +/** + * Compares two C strings for equality. + * \param str The string to compare. + * \param expected The value to compare against. + * \returns True if the strings match, zero otherwise. + */ +int cstr_eq(const char* str, const char* expected) +{ + if (str != NULL && expected != NULL) + { + return (strcmp(str, expected) == 0); + } + return 0; +} + + +/** + * Performs a case-insensitive comparasion on two C strings for equality. + * \param str The string to compare. + * \param expected The value to compare against. + * \returns True if the strings match, zero otherwise. + */ +int cstr_eqi(const char* str, const char* expected) +{ + if (str != NULL && expected != NULL) + { + while (*str && *expected) + { + if (tolower(*str) != tolower(*expected)) + { + return 0; + } + + str++; + expected++; + } + + return (*str == *expected); + } + return 0; +} + + +/** + * Builds a string using printf-style formatting codes. + * \param format The format string, which may contain printf-style formatting codes. + * \returns The formatted string. + */ +char* cstr_format(const char* format, ...) +{ + va_list args; + char* buffer = buffers_next(); + + va_start(args, format); + vsprintf(buffer, format, args); + va_end(args); + + return buffer; +} + + +/** + * Determines if the given C string starts with a particular sequence. + * \param str The string to test. + * \param expected The sequence for which to look. + * \returns True if the string starts with the sequence, false otherwise. + */ +int cstr_starts_with(const char* str, const char* expected) +{ + if (str != NULL && expected != NULL) + { + return (strncmp(str, expected, strlen(expected)) == 0); + } + return 0; +} diff --git a/src/base/cstr.h b/src/base/cstr.h index 2d6f032..3904126 100644 --- a/src/base/cstr.h +++ b/src/base/cstr.h @@ -1,24 +1,24 @@ -/** - * \file cstr.h - * \brief C string handling. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - * - * \defgroup cstr C Strings - * \ingroup base - * - * Functions to handle C strings (zero-terminated byte arrays). - * - * @{ - */ -#if !defined(PREMAKE_CSTR_H) -#define PREMAKE_CSTR_H - -int cstr_contains(const char* str, const char* expected); -int cstr_ends_with(const char* str, const char* expected); -int cstr_eq(const char* str, const char* expected); -int cstr_eqi(const char* str, const char* expected); -char* cstr_format(const char* format, ...); -int cstr_starts_with(const char* str, const char* expected); - -#endif -/** @} */ +/** + * \file cstr.h + * \brief C string handling. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + * + * \defgroup cstr C Strings + * \ingroup base + * + * Functions to handle C strings (zero-terminated byte arrays). + * + * @{ + */ +#if !defined(PREMAKE_CSTR_H) +#define PREMAKE_CSTR_H + +int cstr_contains(const char* str, const char* expected); +int cstr_ends_with(const char* str, const char* expected); +int cstr_eq(const char* str, const char* expected); +int cstr_eqi(const char* str, const char* expected); +char* cstr_format(const char* format, ...); +int cstr_starts_with(const char* str, const char* expected); + +#endif +/** @} */ diff --git a/src/base/dir.c b/src/base/dir.c index 7cad797..dba85f0 100644 --- a/src/base/dir.c +++ b/src/base/dir.c @@ -1,106 +1,106 @@ -/** - * \file dir.c - * \brief Directory handling. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include -#include -#include -#include "premake.h" -#include "base/buffers.h" -#include "base/dir.h" -#include "base/error.h" -#include "base/path.h" -#include "platform/platform.h" - - -/** - * Create a directory, if it doesn't exist already. - * \returns OKAY if successful. - */ -int dir_create(const char* path) -{ - char* parent; - - assert(path); - - if (dir_exists(path)) - return OKAY; - - /* make sure the parent directory exists */ - parent = path_directory(path); - if (strlen(parent) > 0) - { - if (dir_create(parent) != OKAY) - return !OKAY; - } - - if (platform_create_dir(path) != OKAY) - { - error_set("Unable to create directory %s", path); - return !OKAY; - } - - return OKAY; -} - - -/** - * Determine if a particular directory exists on the filesystem. - * \returns True if the directory exists. - */ -int dir_exists(const char* path) -{ - struct stat buf; - - assert(path); - - /* empty path is equivalent to ".", must be true */ - if (strlen(path) == 0) - { - return 1; - } - - if (stat(path, &buf) == 0) - { - return (buf.st_mode & S_IFDIR); - } - else - { - return 0; - } -} - - -/** - * Get the current working directory. - * \returns The current working directory, or NULL on error. Path separators - * are converted to forward slashes, regardless of platform. - */ -char* dir_get_current() -{ - char* buffer = buffers_next(); - - int result = platform_dir_get_current(buffer, BUFFER_SIZE); - if (result == OKAY) - { - return path_translate(buffer, "/"); - } - else - { - return NULL; - } -} - - -/** - * Set the current working directory. - * \param path The new working directory. - * \returns OKAY if successful. - */ -int dir_set_current(const char* path) -{ - assert(path); - return platform_dir_set_current(path); -} +/** + * \file dir.c + * \brief Directory handling. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include +#include +#include +#include "premake.h" +#include "base/buffers.h" +#include "base/dir.h" +#include "base/error.h" +#include "base/path.h" +#include "platform/platform.h" + + +/** + * Create a directory, if it doesn't exist already. + * \returns OKAY if successful. + */ +int dir_create(const char* path) +{ + char* parent; + + assert(path); + + if (dir_exists(path)) + return OKAY; + + /* make sure the parent directory exists */ + parent = path_directory(path); + if (strlen(parent) > 0) + { + if (dir_create(parent) != OKAY) + return !OKAY; + } + + if (platform_create_dir(path) != OKAY) + { + error_set("Unable to create directory %s", path); + return !OKAY; + } + + return OKAY; +} + + +/** + * Determine if a particular directory exists on the filesystem. + * \returns True if the directory exists. + */ +int dir_exists(const char* path) +{ + struct stat buf; + + assert(path); + + /* empty path is equivalent to ".", must be true */ + if (strlen(path) == 0) + { + return 1; + } + + if (stat(path, &buf) == 0) + { + return (buf.st_mode & S_IFDIR); + } + else + { + return 0; + } +} + + +/** + * Get the current working directory. + * \returns The current working directory, or NULL on error. Path separators + * are converted to forward slashes, regardless of platform. + */ +char* dir_get_current() +{ + char* buffer = buffers_next(); + + int result = platform_dir_get_current(buffer, BUFFER_SIZE); + if (result == OKAY) + { + return path_translate(buffer, "/"); + } + else + { + return NULL; + } +} + + +/** + * Set the current working directory. + * \param path The new working directory. + * \returns OKAY if successful. + */ +int dir_set_current(const char* path) +{ + assert(path); + return platform_dir_set_current(path); +} diff --git a/src/base/dir.h b/src/base/dir.h index 45f2604..856a414 100644 --- a/src/base/dir.h +++ b/src/base/dir.h @@ -1,22 +1,22 @@ -/** - * \file dir.h - * \brief Directory handling. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - * - * \defgroup dir Directory Management - * \ingroup base - * - * Directory management functions. - * - * @{ - */ -#if !defined(PREMAKE_DIR_H) -#define PREMAKE_DIR_H - -int dir_create(const char* path); -int dir_exists(const char* path); -char* dir_get_current(void); -int dir_set_current(const char* path); - -#endif -/** @} */ +/** + * \file dir.h + * \brief Directory handling. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + * + * \defgroup dir Directory Management + * \ingroup base + * + * Directory management functions. + * + * @{ + */ +#if !defined(PREMAKE_DIR_H) +#define PREMAKE_DIR_H + +int dir_create(const char* path); +int dir_exists(const char* path); +char* dir_get_current(void); +int dir_set_current(const char* path); + +#endif +/** @} */ diff --git a/src/base/error.c b/src/base/error.c index fac6b31..a53eff2 100644 --- a/src/base/error.c +++ b/src/base/error.c @@ -1,51 +1,51 @@ -/** - * \file error.c - * \brief Application-wide error reporting. - * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project - */ - -#include -#include -#include -#include -#include "premake.h" -#include "error.h" - -static char error_message[8192] = { 0 }; - - -/** - * Clear any existing error state. - */ -void error_clear(void) -{ - error_message[0] = 0; -} - - -/** - * Returns the most recent error message set by error_set(). - * \returns The error message, or NULL if no error message has been set. - */ -const char* error_get(void) -{ - return (strlen(error_message) > 0) ? error_message : NULL; -} - - -/** - * Set the description of an error condition, which may be retrieved with session_get_error(). - * The session uses a fixed length (around 8K) buffer for storing the error message, so make - * sure the final size of the formatted message will fall under that limit. - * \param message A description of the error condition. - */ -void error_set(const char* message, ...) -{ - va_list args; - - assert(message); - - va_start(args, message); - vsprintf(error_message, message, args); - va_end(args); -} +/** + * \file error.c + * \brief Application-wide error reporting. + * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project + */ + +#include +#include +#include +#include +#include "premake.h" +#include "error.h" + +static char error_message[8192] = { 0 }; + + +/** + * Clear any existing error state. + */ +void error_clear(void) +{ + error_message[0] = 0; +} + + +/** + * Returns the most recent error message set by error_set(). + * \returns The error message, or NULL if no error message has been set. + */ +const char* error_get(void) +{ + return (strlen(error_message) > 0) ? error_message : NULL; +} + + +/** + * Set the description of an error condition, which may be retrieved with session_get_error(). + * The session uses a fixed length (around 8K) buffer for storing the error message, so make + * sure the final size of the formatted message will fall under that limit. + * \param message A description of the error condition. + */ +void error_set(const char* message, ...) +{ + va_list args; + + assert(message); + + va_start(args, message); + vsprintf(error_message, message, args); + va_end(args); +} diff --git a/src/base/error.h b/src/base/error.h index 46da099..dbccda0 100644 --- a/src/base/error.h +++ b/src/base/error.h @@ -1,21 +1,21 @@ -/** - * \file error.h - * \brief Application-wide error reporting. - * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project - * - * \defgroup array Array - * \ingroup base - * - * Application-wide error reporting. - * - * @{ - */ -#if !defined(PREMAKE_ERROR_H) -#define PREMAKE_ERROR_H - -void error_clear(void); -const char* error_get(void); -void error_set(const char* message, ...); - -#endif -/** @} */ +/** + * \file error.h + * \brief Application-wide error reporting. + * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project + * + * \defgroup array Array + * \ingroup base + * + * Application-wide error reporting. + * + * @{ + */ +#if !defined(PREMAKE_ERROR_H) +#define PREMAKE_ERROR_H + +void error_clear(void); +const char* error_get(void); +void error_set(const char* message, ...); + +#endif +/** @} */ diff --git a/src/base/guid.c b/src/base/guid.c index b2bc442..f6da2e6 100644 --- a/src/base/guid.c +++ b/src/base/guid.c @@ -1,109 +1,109 @@ -/** - * \file guid.c - * \brief GUID creation and validation. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include -#include -#include "premake.h" -#include "guid.h" -#include "platform/platform.h" -#include "base/buffers.h" - - -static void stringify(char* src, char* dst, int count); - - -/** - * Create a new GUID, with the format "4E67EBCE-BC8B-4058-9AA9-48EE5E003683". - * \returns The new GUID. - */ -const char* guid_create() -{ - char guid[16]; - char* result = buffers_next(); - - /* get a GUID as an array of 16 bytes */ - platform_create_guid(guid); - - /* convert that array to a string in the usual format */ - stringify(guid, result, 4); - result[8] = '-'; - stringify(guid + 4, result + 9, 2); - result[13] = '-'; - stringify(guid + 6, result + 14, 2); - result[18] = '-'; - stringify(guid + 8, result + 19, 2); - result[23] = '-'; - stringify(guid + 10, result + 24, 6); - result[36] = '\0'; - return result; -} - - -/** - * Validate the format of a GUID, which should use the form "4E67EBCE-BC8B-4058-9AA9-48EE5E003683". - * \param value The guid to validate. - * \returns True if valid, zero otherwise. - */ -int guid_is_valid(const char* value) -{ - int i, n; - - /* make sure it is the right size */ - if (strlen(value) != 36) - return 0; - - /* check for dashes in the right places */ - if (value[8] != '-' || - value[13] != '-' || - value[18] != '-' || - value[23] != '-') - { - return 0; - } - - /* make sure only [0-9A-F-] are present; count the number of dashes on the way */ - n = 0; - for (i = 0; i < 36; ++i) - { - if (value[i] == '-') - { - ++n; - } - else if ((value[i] < '0' || value[i] > '9') && - (value[i] < 'A' || value[i] > 'F') && - (value[i] < 'a' || value[i] > 'f')) - { - return 0; - } - } - - /* make sure I've got the right number of dashes */ - if (n != 4) - { - return 0; - } - - return 1; -} - - -/** - * Convert an array of bytes to a string. - * \param src The source array of bytes. - * \param dst The destination string buffer. - * \param count The number of bytes to convert. - */ -static void stringify(char* src, char* dst, int count) -{ - int i; - for (i = 0; i < count; ++i) - { - unsigned value = (unsigned char)src[i]; - sprintf(dst, "%02X", value); - dst += 2; - } -} - +/** + * \file guid.c + * \brief GUID creation and validation. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include +#include +#include "premake.h" +#include "guid.h" +#include "platform/platform.h" +#include "base/buffers.h" + + +static void stringify(char* src, char* dst, int count); + + +/** + * Create a new GUID, with the format "4E67EBCE-BC8B-4058-9AA9-48EE5E003683". + * \returns The new GUID. + */ +const char* guid_create() +{ + char guid[16]; + char* result = buffers_next(); + + /* get a GUID as an array of 16 bytes */ + platform_create_guid(guid); + + /* convert that array to a string in the usual format */ + stringify(guid, result, 4); + result[8] = '-'; + stringify(guid + 4, result + 9, 2); + result[13] = '-'; + stringify(guid + 6, result + 14, 2); + result[18] = '-'; + stringify(guid + 8, result + 19, 2); + result[23] = '-'; + stringify(guid + 10, result + 24, 6); + result[36] = '\0'; + return result; +} + + +/** + * Validate the format of a GUID, which should use the form "4E67EBCE-BC8B-4058-9AA9-48EE5E003683". + * \param value The guid to validate. + * \returns True if valid, zero otherwise. + */ +int guid_is_valid(const char* value) +{ + int i, n; + + /* make sure it is the right size */ + if (strlen(value) != 36) + return 0; + + /* check for dashes in the right places */ + if (value[8] != '-' || + value[13] != '-' || + value[18] != '-' || + value[23] != '-') + { + return 0; + } + + /* make sure only [0-9A-F-] are present; count the number of dashes on the way */ + n = 0; + for (i = 0; i < 36; ++i) + { + if (value[i] == '-') + { + ++n; + } + else if ((value[i] < '0' || value[i] > '9') && + (value[i] < 'A' || value[i] > 'F') && + (value[i] < 'a' || value[i] > 'f')) + { + return 0; + } + } + + /* make sure I've got the right number of dashes */ + if (n != 4) + { + return 0; + } + + return 1; +} + + +/** + * Convert an array of bytes to a string. + * \param src The source array of bytes. + * \param dst The destination string buffer. + * \param count The number of bytes to convert. + */ +static void stringify(char* src, char* dst, int count) +{ + int i; + for (i = 0; i < count; ++i) + { + unsigned value = (unsigned char)src[i]; + sprintf(dst, "%02X", value); + dst += 2; + } +} + diff --git a/src/base/guid.h b/src/base/guid.h index 94091ae..c6e6753 100644 --- a/src/base/guid.h +++ b/src/base/guid.h @@ -1,20 +1,20 @@ -/** - * \file guid.h - * \brief GUID creation and validation. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - * - * \defgroup guid GUIDs - * \ingroup base - * - * GUID creation and validation functions. - * - * @{ - */ -#if !defined(PREMAKE_GUID_H) -#define PREMAKE_GUID_H - -const char* guid_create(); -int guid_is_valid(const char* value); - -#endif -/** @} */ +/** + * \file guid.h + * \brief GUID creation and validation. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + * + * \defgroup guid GUIDs + * \ingroup base + * + * GUID creation and validation functions. + * + * @{ + */ +#if !defined(PREMAKE_GUID_H) +#define PREMAKE_GUID_H + +const char* guid_create(); +int guid_is_valid(const char* value); + +#endif +/** @} */ diff --git a/src/base/path.c b/src/base/path.c index a170960..1648aa7 100644 --- a/src/base/path.c +++ b/src/base/path.c @@ -1,354 +1,354 @@ -/** - * \file path.c - * \brief Path handling. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include -#include -#include -#include "premake.h" -#include "base/path.h" -#include "platform/platform.h" -#include "base/buffers.h" -#include "base/cstr.h" -#include "base/dir.h" - -static char* CppFileExtensions[] = { ".cc", ".cpp", ".cxx", ".c", ".s", NULL }; - - -/** - * Create an absolute path from a relative one. - * \param path The relative path to convert. - * \returns An absolute version of the relative path. - */ -char* path_absolute(const char* path) -{ - char* source; - char* result; - - assert(path); - - /* normalize the target path */ - source = path_translate(path, "/"); - if (strlen(source) == 0) - strcpy(source, "."); - - /* If the directory is already absolute I don't have to do anything */ - if (path_is_absolute(source)) - return source; - - /* start from the current location */ - result = dir_get_current(); - - /* split up the supplied relative path and tackle it bit by bit */ - while (source) - { - char* end = strchr(source, '/'); - if (end) - *end = 0; - - if (cstr_eq(source, "..")) - { - char* up = strrchr(result, '/'); - if (up) - *up = 0; - } - else if (!cstr_eq(source, ".")) - { - strcat(result, "/"); - strcat(result, source); - } - - source = end ? end + 1 : NULL; - } - - return result; -} - - -/** - * Assemble a complete file path from its component parts. - * \param dir The directory portion of the path. - * \param filename The file name portion of the path. - * \param ext The extension portion of the path. - * \returns The assembled file path. - */ -char* path_assemble(const char* dir, const char* filename, const char* ext) -{ - char* buffer; - - assert(dir); - assert(filename); - assert(ext); - - buffer = path_join(dir, filename); - if (ext) - { - strcat(buffer, ext); - } - return buffer; -} - - -/** - * Returns the base name in a path: the filename, without the directory or - * file extension. - * \param path The path to split. - * \returns The base name part of the path. - */ -char* path_basename(const char* path) -{ - char* buffer = path_filename(path); - char* ptr = strrchr(buffer, '.'); - if (ptr) - { - *ptr = '\0'; - } - return buffer; -} - - -/** - * Retrieve the directory portion of a path. - * \param path The path to split. - * \returns The directory portion of the path. Returns an empty string ("") if - * the path does not contain any directory information. - */ -char* path_directory(const char* path) -{ - char* ptr; - char* buffer = buffers_next(); - - assert(path); - strcpy(buffer, path); - - ptr = strrchr(buffer, '/'); - if (ptr) - *ptr = '\0'; - else - *buffer = '\0'; - - return buffer; -} - - -/** - * Retrieve the file extension portion of a path. If the path has multiple - * dots in the filename (ie. filename.my.ext) only the last bit (.ext) will - * be returned. The dot is included in the extension. - * \param path The path to split. - * \returns The extension portion of the path, or an empty string if no extension is present. - */ -char* path_extension(const char* path) -{ - char* ptr; - char* buffer = buffers_next(); - - assert(path); - strcpy(buffer, path); - ptr = strrchr(buffer, '.'); - return (ptr) ? ptr : ""; -} - - -/** - * Retrieve the fileame (filename.ext) portion of a path. - * \param path The path to split. - * \returns The filename portion of the path. Returns an empty string ("") if - * the path is empty. - */ -char* path_filename(const char* path) -{ - char* ptr; - char* buffer = buffers_next(); - - assert(path); - - ptr = strrchr(path, '/'); - if (ptr) - { - strcpy(buffer, ptr + 1); - } - else - { - strcpy(buffer, path); - } - - return buffer; -} - - -/** - * Determine is a path is absolute (rooted at base of filesystem). - * \param path The path to check. - * \returns True if the path is absolute. - */ -int path_is_absolute(const char* path) -{ - assert(path); - - if (path[0] == '/' || path[0] == '\\') - return 1; - if (path[1] == ':') - return 1; - return 0; -} - - -/** - * Returns true if the path represents a C++ source code file; by checking - * the file extension. - * \param path The path to check. - * \returns True if the path uses a known C++ file extension. - */ -int path_is_cpp_source(const char* path) -{ - int i; - - char* ext = path_extension(path); - if (cstr_eq(ext, "")) - { - return 0; - } - - for (i = 0; CppFileExtensions[i] != NULL; ++i) - { - if (cstr_eqi(CppFileExtensions[i], ext)) - return 1; - } - - return 0; -} - - -/** - * Join two paths togethers. - * \param leading The leading path. - * \param trailing The trailing path. - * \returns A unified path. - * \note If the trailing path is absolute, that will be the return value. - * A join is only performed if the trailing path is relative. - */ -char* path_join(const char* leading, const char* trailing) -{ - char* buffer = buffers_next(); - - /* treat nulls like empty paths */ - leading = (leading != NULL) ? leading : ""; - trailing = (trailing != NULL) ? trailing : ""; - - if (!trailing) - { - strcpy(buffer, leading); - return buffer; - } - - if (!leading || path_is_absolute(trailing)) - { - strcpy(buffer, trailing); - return buffer; - } - - if (leading) - { - strcat(buffer, leading); - } - - if (strlen(buffer) > 0 && !cstr_ends_with(buffer, "/")) - { - strcat(buffer, "/"); - } - - strcat(buffer, trailing); - return buffer; -} - - -/** - * \brief Compute the relative path between two locations. - * \param base The base path. - * \param target The target path. - * \returns A relative path from the base to the target. - */ -char* path_relative(const char* base, const char* target) -{ - int start, i; - char* result; - - /* normalize the two paths */ - char* full_base = path_absolute(base); - char* full_targ = path_absolute(target); - - strcat(full_base, "/"); - strcat(full_targ, "/"); - - /* trim off the common directories from the start */ - for (start = 0, i = 0; full_base[i] && full_targ[i] && full_base[i] == full_targ[i]; ++i) - { - if (full_base[i] == '/') - start = i + 1; - } - - /* same directory? */ - if (full_base[i] == 0 && full_targ[i] == 0) - return "."; - - /* build a connecting path */ - result = buffers_next(); - if (strlen(full_base) - start > 0) - { - strcpy(result, "../"); - for (i = start; full_base[i]; ++i) - { - if (full_base[i] == '/' && full_base[i + 1]) - strcat(result, "../"); - } - } - - if (strlen(full_targ) - start > 0) - { - strcat(result, full_targ + start); - } - - /* remove the trailing slash */ - result[strlen(result) - 1] = 0; - - if (strlen(result) == 0) - strcpy(result, "."); - return result; -} - - -/** - * Replace all path separator characters in a path. - * \param path The path to translate. - * \param sep The desired separator, or NULL for the platform's native separator. - * \returns The translated path. - */ -char* path_translate(const char* path, const char* sep) -{ - char* ptr; - char* buffer; - - assert(path); - - buffer = buffers_next(); - if (sep == NULL) - { -#if defined(PLATFORM_WINDOWS) - sep = "\\"; -#else - sep = "/"; -#endif - } - - strcpy(buffer, path); - for (ptr = buffer; *ptr; ++ptr) - { - if (*ptr == '/' || *ptr == '\\') - *ptr = *sep; - } - - return buffer; -} +/** + * \file path.c + * \brief Path handling. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include +#include +#include +#include "premake.h" +#include "base/path.h" +#include "platform/platform.h" +#include "base/buffers.h" +#include "base/cstr.h" +#include "base/dir.h" + +static char* CppFileExtensions[] = { ".cc", ".cpp", ".cxx", ".c", ".s", NULL }; + + +/** + * Create an absolute path from a relative one. + * \param path The relative path to convert. + * \returns An absolute version of the relative path. + */ +char* path_absolute(const char* path) +{ + char* source; + char* result; + + assert(path); + + /* normalize the target path */ + source = path_translate(path, "/"); + if (strlen(source) == 0) + strcpy(source, "."); + + /* If the directory is already absolute I don't have to do anything */ + if (path_is_absolute(source)) + return source; + + /* start from the current location */ + result = dir_get_current(); + + /* split up the supplied relative path and tackle it bit by bit */ + while (source) + { + char* end = strchr(source, '/'); + if (end) + *end = 0; + + if (cstr_eq(source, "..")) + { + char* up = strrchr(result, '/'); + if (up) + *up = 0; + } + else if (!cstr_eq(source, ".")) + { + strcat(result, "/"); + strcat(result, source); + } + + source = end ? end + 1 : NULL; + } + + return result; +} + + +/** + * Assemble a complete file path from its component parts. + * \param dir The directory portion of the path. + * \param filename The file name portion of the path. + * \param ext The extension portion of the path. + * \returns The assembled file path. + */ +char* path_assemble(const char* dir, const char* filename, const char* ext) +{ + char* buffer; + + assert(dir); + assert(filename); + assert(ext); + + buffer = path_join(dir, filename); + if (ext) + { + strcat(buffer, ext); + } + return buffer; +} + + +/** + * Returns the base name in a path: the filename, without the directory or + * file extension. + * \param path The path to split. + * \returns The base name part of the path. + */ +char* path_basename(const char* path) +{ + char* buffer = path_filename(path); + char* ptr = strrchr(buffer, '.'); + if (ptr) + { + *ptr = '\0'; + } + return buffer; +} + + +/** + * Retrieve the directory portion of a path. + * \param path The path to split. + * \returns The directory portion of the path. Returns an empty string ("") if + * the path does not contain any directory information. + */ +char* path_directory(const char* path) +{ + char* ptr; + char* buffer = buffers_next(); + + assert(path); + strcpy(buffer, path); + + ptr = strrchr(buffer, '/'); + if (ptr) + *ptr = '\0'; + else + *buffer = '\0'; + + return buffer; +} + + +/** + * Retrieve the file extension portion of a path. If the path has multiple + * dots in the filename (ie. filename.my.ext) only the last bit (.ext) will + * be returned. The dot is included in the extension. + * \param path The path to split. + * \returns The extension portion of the path, or an empty string if no extension is present. + */ +char* path_extension(const char* path) +{ + char* ptr; + char* buffer = buffers_next(); + + assert(path); + strcpy(buffer, path); + ptr = strrchr(buffer, '.'); + return (ptr) ? ptr : ""; +} + + +/** + * Retrieve the fileame (filename.ext) portion of a path. + * \param path The path to split. + * \returns The filename portion of the path. Returns an empty string ("") if + * the path is empty. + */ +char* path_filename(const char* path) +{ + char* ptr; + char* buffer = buffers_next(); + + assert(path); + + ptr = strrchr(path, '/'); + if (ptr) + { + strcpy(buffer, ptr + 1); + } + else + { + strcpy(buffer, path); + } + + return buffer; +} + + +/** + * Determine is a path is absolute (rooted at base of filesystem). + * \param path The path to check. + * \returns True if the path is absolute. + */ +int path_is_absolute(const char* path) +{ + assert(path); + + if (path[0] == '/' || path[0] == '\\') + return 1; + if (path[1] == ':') + return 1; + return 0; +} + + +/** + * Returns true if the path represents a C++ source code file; by checking + * the file extension. + * \param path The path to check. + * \returns True if the path uses a known C++ file extension. + */ +int path_is_cpp_source(const char* path) +{ + int i; + + char* ext = path_extension(path); + if (cstr_eq(ext, "")) + { + return 0; + } + + for (i = 0; CppFileExtensions[i] != NULL; ++i) + { + if (cstr_eqi(CppFileExtensions[i], ext)) + return 1; + } + + return 0; +} + + +/** + * Join two paths togethers. + * \param leading The leading path. + * \param trailing The trailing path. + * \returns A unified path. + * \note If the trailing path is absolute, that will be the return value. + * A join is only performed if the trailing path is relative. + */ +char* path_join(const char* leading, const char* trailing) +{ + char* buffer = buffers_next(); + + /* treat nulls like empty paths */ + leading = (leading != NULL) ? leading : ""; + trailing = (trailing != NULL) ? trailing : ""; + + if (!trailing) + { + strcpy(buffer, leading); + return buffer; + } + + if (!leading || path_is_absolute(trailing)) + { + strcpy(buffer, trailing); + return buffer; + } + + if (leading) + { + strcat(buffer, leading); + } + + if (strlen(buffer) > 0 && !cstr_ends_with(buffer, "/")) + { + strcat(buffer, "/"); + } + + strcat(buffer, trailing); + return buffer; +} + + +/** + * \brief Compute the relative path between two locations. + * \param base The base path. + * \param target The target path. + * \returns A relative path from the base to the target. + */ +char* path_relative(const char* base, const char* target) +{ + int start, i; + char* result; + + /* normalize the two paths */ + char* full_base = path_absolute(base); + char* full_targ = path_absolute(target); + + strcat(full_base, "/"); + strcat(full_targ, "/"); + + /* trim off the common directories from the start */ + for (start = 0, i = 0; full_base[i] && full_targ[i] && full_base[i] == full_targ[i]; ++i) + { + if (full_base[i] == '/') + start = i + 1; + } + + /* same directory? */ + if (full_base[i] == 0 && full_targ[i] == 0) + return "."; + + /* build a connecting path */ + result = buffers_next(); + if (strlen(full_base) - start > 0) + { + strcpy(result, "../"); + for (i = start; full_base[i]; ++i) + { + if (full_base[i] == '/' && full_base[i + 1]) + strcat(result, "../"); + } + } + + if (strlen(full_targ) - start > 0) + { + strcat(result, full_targ + start); + } + + /* remove the trailing slash */ + result[strlen(result) - 1] = 0; + + if (strlen(result) == 0) + strcpy(result, "."); + return result; +} + + +/** + * Replace all path separator characters in a path. + * \param path The path to translate. + * \param sep The desired separator, or NULL for the platform's native separator. + * \returns The translated path. + */ +char* path_translate(const char* path, const char* sep) +{ + char* ptr; + char* buffer; + + assert(path); + + buffer = buffers_next(); + if (sep == NULL) + { +#if defined(PLATFORM_WINDOWS) + sep = "\\"; +#else + sep = "/"; +#endif + } + + strcpy(buffer, path); + for (ptr = buffer; *ptr; ++ptr) + { + if (*ptr == '/' || *ptr == '\\') + *ptr = *sep; + } + + return buffer; +} diff --git a/src/base/path.h b/src/base/path.h index 1600951..caf8b3c 100644 --- a/src/base/path.h +++ b/src/base/path.h @@ -1,29 +1,29 @@ -/** - * \file path.h - * \brief Path handling. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - * - * \defgroup path Path - * \ingroup base - * - * Path manipulation functions. - * - * @{ - */ -#if !defined(PREMAKE_PATH_H) -#define PREMAKE_PATH_H - -char* path_absolute(const char* path); -char* path_assemble(const char* dir, const char* filename, const char* ext); -char* path_basename(const char* path); -char* path_directory(const char* path); -char* path_extension(const char* path); -char* path_filename(const char* path); -int path_is_absolute(const char* path); -int path_is_cpp_source(const char* path); -char* path_join(const char* leading, const char* trailing); -char* path_relative(const char* base, const char* target); -char* path_translate(const char* path, const char* sep); - -#endif -/** @} */ +/** + * \file path.h + * \brief Path handling. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + * + * \defgroup path Path + * \ingroup base + * + * Path manipulation functions. + * + * @{ + */ +#if !defined(PREMAKE_PATH_H) +#define PREMAKE_PATH_H + +char* path_absolute(const char* path); +char* path_assemble(const char* dir, const char* filename, const char* ext); +char* path_basename(const char* path); +char* path_directory(const char* path); +char* path_extension(const char* path); +char* path_filename(const char* path); +int path_is_absolute(const char* path); +int path_is_cpp_source(const char* path); +char* path_join(const char* leading, const char* trailing); +char* path_relative(const char* base, const char* target); +char* path_translate(const char* path, const char* sep); + +#endif +/** @} */ diff --git a/src/base/stream.c b/src/base/stream.c index b93a517..ebe7247 100644 --- a/src/base/stream.c +++ b/src/base/stream.c @@ -1,289 +1,289 @@ -/** - * \file stream.c - * \brief Output stream handling. - * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project - */ - -#include -#include -#include -#include -#include "premake.h" -#include "base/error.h" -#include "base/dir.h" -#include "base/path.h" -#include "base/stream.h" - - -DEFINE_CLASS(Stream) -{ - FILE* file; - const char* newline; - char* buffer; -}; - - -static struct Stream_impl Console_impl = { NULL, "\n", NULL }; - - -/** - * The console output stream. - * Use the stream_write() functions and this stream object instead - * of the usual C functions like printf(). The stream functions have - * more features -- such as setting the line ending sequence -- and - * can be captured for automated testing. - */ -Stream Console = &Console_impl; - - -/** - * Create a new file output stream, overwriting any existing file. - * \param filename The name of the file to create. - * \returns A new file stream. - */ -Stream stream_create_file(const char* filename) -{ - Stream strm; - const char* dirname; - FILE* file; - - /* make sure the directory exists before writing to it */ - dirname = path_directory(filename); - if (dir_create(dirname) != OKAY) - { - return NULL; - } - - /* create the file */ - file = fopen(filename, "wb"); - if (file == NULL) - { - error_set("Unable to open file %s", filename); - return NULL; - } - - /* build the stream object */ - strm = stream_create_null(); - strm->file = file; - return strm; -} - - -/** - * Create a "null" stream, which discards any writes; intended for automated testing. - * \returns A new stream object. - */ -Stream stream_create_null() -{ - Stream strm = ALLOC_CLASS(Stream); - strm->file = NULL; - strm->newline = "\n"; - strm->buffer = NULL; - return strm; -} - - -/** - * Close a stream and release the associated memory. - * \param strm The stream to close. - */ -void stream_destroy(Stream strm) -{ - assert(strm); - if (strm != Console) - { - if (strm->file != NULL) - { - fclose(strm->file); - } - free(strm); - } -} - - -/** - * Capture the text written to a stream into a buffer. - * When a stream is captured all text is written to the buffer, and - * output to the associated file is blocked. - * \param strm The stream to capture. - * \param buffer The buffer to contain the captured text. No checks are made - * on the size of the buffer while writing, so use carefully. - * May be NULL to disable buffering. - */ -void stream_set_buffer(Stream strm, char* buffer) -{ - assert(strm); - strm->buffer = buffer; - strm->buffer[0] = '\0'; -} - - -/** - * Set the newline character sequence. - * \param strm The stream to set. - * \param newline The EOL sequence. - */ -void stream_set_newline(Stream strm, const char* newline) -{ - assert(strm); - strm->newline = newline; -} - - -/** - * Write a formatted list of strings. - * \param strm The stream to which to write. - * \param strs The list of strings to write. - * \param start The start string, always written first, even if there are no items in the list. - * \param prefix A prefix string, to be written before each item. - * \param postfix A postfix string, to be written after each item. - * \param infix An infix strings, to write between items, after the - * previous postfix string and before the next prefix. - * \param end The end string, always written last, even if there are no items in the list. - * \returns OKAY if successful. - */ -int stream_write_strings(Stream strm, Strings strs, const char* start, const char* prefix, const char* postfix, const char* infix, const char* end) -{ - int i, n, z; - - z = stream_write(strm, start); - - n = strings_size(strs); - for (i = 0; i < n; ++i) - { - const char* value = strings_item(strs, i); - if (i > 0) z |= stream_write(strm, infix); - z |= stream_write(strm, prefix); - z |= stream_write(strm, value); - z |= stream_write(strm, postfix); - } - - z |= stream_write(strm, end); - return z; -} - - -/** - * Write a formatted list of strings, followed by a newline. - * \param strm The stream to which to write. - * \param strs The list of strings to write. - * \param start The start string, always written first, even if there are no items in the list. - * \param prefix A prefix string, to be written before each item. - * \param postfix A postfix string, to be written after each item. - * \param infix An infix strings, to write between items, after the - * previous postfix string and before the next prefix. - * \returns OKAY if successful. - */ -int stream_writeline_strings(Stream strm, Strings strs, const char* start, const char* prefix, const char* postfix, const char* infix) -{ - int i, n, z; - - z = stream_write(strm, start); - - n = strings_size(strs); - for (i = 0; i < n; ++i) - { - const char* value = strings_item(strs, i); - if (i > 0) z |= stream_write(strm, infix); - z |= stream_write(strm, prefix); - z |= stream_write(strm, value); - z |= stream_write(strm, postfix); - } - - z |= stream_writeline(strm, ""); - return z; -} - - -/** - * Format and print a string using printf-style codes and a variable argument list. - * \param strm The stream to which to write. - * \param value The value to print; may contain printf-style formatting codes. - * \param args A variable argument list to populate the printf-style codes in `value`. - * \returns OKAY if successful. - */ -int stream_vprintf(Stream strm, const char* value, va_list args) -{ - if (strm->buffer) - { - /* write to the end of the current contents of the buffer */ - char* start = strm->buffer + strlen(strm->buffer); - vsprintf(start, value, args); - } - else if (strm == Console) - { - vfprintf(stdout, value, args); - } - else if (strm->file) - { - vfprintf(strm->file, value, args); - } - return OKAY; -} - - -/** - * Write a string value to a stream. - * \param strm The stream. - * \param value The value to append to the stream. - * \returns OKAY is successful. - */ -int stream_write(Stream strm, const char* value, ...) -{ - int status; - va_list args; - - va_start(args, value); - status = stream_vprintf(strm, value, args); - va_end(args); - - return status; -} - - -/** - * Write N copies of a string to a stream. - * \param strm The stream to which to write. - * \param value The string to write. - * \param n The number of copies to write. - * \returns OKAY if successful. - */ -int stream_write_n(Stream strm, const char* value, int n) -{ - int i, z = OKAY; - for (i = 0; i < n; ++i) - { - z |= stream_write(strm, value); - } - return z; -} - - -/** - * Writes the Unicode encoding marker sequence into the stream. - * \param strm The stream to which to write. - */ -int stream_write_unicode_marker(Stream strm) -{ - return stream_write(strm, "\357\273\277"); -} - - -/** - * Write a string value, followed by a newline, to a stream. - * \param strm The stream. - * \param value The value to append to the stream. - * \returns OKAY if successful. - */ -int stream_writeline(Stream strm, const char* value, ...) -{ - int status; - va_list args; - - va_start(args, value); - status = stream_vprintf(strm, value, args); - status |= stream_write(strm, strm->newline); - va_end(args); - - return status; -} +/** + * \file stream.c + * \brief Output stream handling. + * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project + */ + +#include +#include +#include +#include +#include "premake.h" +#include "base/error.h" +#include "base/dir.h" +#include "base/path.h" +#include "base/stream.h" + + +DEFINE_CLASS(Stream) +{ + FILE* file; + const char* newline; + char* buffer; +}; + + +static struct Stream_impl Console_impl = { NULL, "\n", NULL }; + + +/** + * The console output stream. + * Use the stream_write() functions and this stream object instead + * of the usual C functions like printf(). The stream functions have + * more features -- such as setting the line ending sequence -- and + * can be captured for automated testing. + */ +Stream Console = &Console_impl; + + +/** + * Create a new file output stream, overwriting any existing file. + * \param filename The name of the file to create. + * \returns A new file stream. + */ +Stream stream_create_file(const char* filename) +{ + Stream strm; + const char* dirname; + FILE* file; + + /* make sure the directory exists before writing to it */ + dirname = path_directory(filename); + if (dir_create(dirname) != OKAY) + { + return NULL; + } + + /* create the file */ + file = fopen(filename, "wb"); + if (file == NULL) + { + error_set("Unable to open file %s", filename); + return NULL; + } + + /* build the stream object */ + strm = stream_create_null(); + strm->file = file; + return strm; +} + + +/** + * Create a "null" stream, which discards any writes; intended for automated testing. + * \returns A new stream object. + */ +Stream stream_create_null() +{ + Stream strm = ALLOC_CLASS(Stream); + strm->file = NULL; + strm->newline = "\n"; + strm->buffer = NULL; + return strm; +} + + +/** + * Close a stream and release the associated memory. + * \param strm The stream to close. + */ +void stream_destroy(Stream strm) +{ + assert(strm); + if (strm != Console) + { + if (strm->file != NULL) + { + fclose(strm->file); + } + free(strm); + } +} + + +/** + * Capture the text written to a stream into a buffer. + * When a stream is captured all text is written to the buffer, and + * output to the associated file is blocked. + * \param strm The stream to capture. + * \param buffer The buffer to contain the captured text. No checks are made + * on the size of the buffer while writing, so use carefully. + * May be NULL to disable buffering. + */ +void stream_set_buffer(Stream strm, char* buffer) +{ + assert(strm); + strm->buffer = buffer; + strm->buffer[0] = '\0'; +} + + +/** + * Set the newline character sequence. + * \param strm The stream to set. + * \param newline The EOL sequence. + */ +void stream_set_newline(Stream strm, const char* newline) +{ + assert(strm); + strm->newline = newline; +} + + +/** + * Write a formatted list of strings. + * \param strm The stream to which to write. + * \param strs The list of strings to write. + * \param start The start string, always written first, even if there are no items in the list. + * \param prefix A prefix string, to be written before each item. + * \param postfix A postfix string, to be written after each item. + * \param infix An infix strings, to write between items, after the + * previous postfix string and before the next prefix. + * \param end The end string, always written last, even if there are no items in the list. + * \returns OKAY if successful. + */ +int stream_write_strings(Stream strm, Strings strs, const char* start, const char* prefix, const char* postfix, const char* infix, const char* end) +{ + int i, n, z; + + z = stream_write(strm, start); + + n = strings_size(strs); + for (i = 0; i < n; ++i) + { + const char* value = strings_item(strs, i); + if (i > 0) z |= stream_write(strm, infix); + z |= stream_write(strm, prefix); + z |= stream_write(strm, value); + z |= stream_write(strm, postfix); + } + + z |= stream_write(strm, end); + return z; +} + + +/** + * Write a formatted list of strings, followed by a newline. + * \param strm The stream to which to write. + * \param strs The list of strings to write. + * \param start The start string, always written first, even if there are no items in the list. + * \param prefix A prefix string, to be written before each item. + * \param postfix A postfix string, to be written after each item. + * \param infix An infix strings, to write between items, after the + * previous postfix string and before the next prefix. + * \returns OKAY if successful. + */ +int stream_writeline_strings(Stream strm, Strings strs, const char* start, const char* prefix, const char* postfix, const char* infix) +{ + int i, n, z; + + z = stream_write(strm, start); + + n = strings_size(strs); + for (i = 0; i < n; ++i) + { + const char* value = strings_item(strs, i); + if (i > 0) z |= stream_write(strm, infix); + z |= stream_write(strm, prefix); + z |= stream_write(strm, value); + z |= stream_write(strm, postfix); + } + + z |= stream_writeline(strm, ""); + return z; +} + + +/** + * Format and print a string using printf-style codes and a variable argument list. + * \param strm The stream to which to write. + * \param value The value to print; may contain printf-style formatting codes. + * \param args A variable argument list to populate the printf-style codes in `value`. + * \returns OKAY if successful. + */ +int stream_vprintf(Stream strm, const char* value, va_list args) +{ + if (strm->buffer) + { + /* write to the end of the current contents of the buffer */ + char* start = strm->buffer + strlen(strm->buffer); + vsprintf(start, value, args); + } + else if (strm == Console) + { + vfprintf(stdout, value, args); + } + else if (strm->file) + { + vfprintf(strm->file, value, args); + } + return OKAY; +} + + +/** + * Write a string value to a stream. + * \param strm The stream. + * \param value The value to append to the stream. + * \returns OKAY is successful. + */ +int stream_write(Stream strm, const char* value, ...) +{ + int status; + va_list args; + + va_start(args, value); + status = stream_vprintf(strm, value, args); + va_end(args); + + return status; +} + + +/** + * Write N copies of a string to a stream. + * \param strm The stream to which to write. + * \param value The string to write. + * \param n The number of copies to write. + * \returns OKAY if successful. + */ +int stream_write_n(Stream strm, const char* value, int n) +{ + int i, z = OKAY; + for (i = 0; i < n; ++i) + { + z |= stream_write(strm, value); + } + return z; +} + + +/** + * Writes the Unicode encoding marker sequence into the stream. + * \param strm The stream to which to write. + */ +int stream_write_unicode_marker(Stream strm) +{ + return stream_write(strm, "\357\273\277"); +} + + +/** + * Write a string value, followed by a newline, to a stream. + * \param strm The stream. + * \param value The value to append to the stream. + * \returns OKAY if successful. + */ +int stream_writeline(Stream strm, const char* value, ...) +{ + int status; + va_list args; + + va_start(args, value); + status = stream_vprintf(strm, value, args); + status |= stream_write(strm, strm->newline); + va_end(args); + + return status; +} diff --git a/src/base/stream.h b/src/base/stream.h index 719e77e..89925ea 100644 --- a/src/base/stream.h +++ b/src/base/stream.h @@ -1,37 +1,37 @@ -/** - * \file stream.h - * \brief Output stream handling. - * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project - * - * \defgroup stream Streams - * \ingroup base - * - * An output stream class. - * - * @{ - */ -#if !defined(PREMAKE_STREAM_H) -#define PREMAKE_STREAM_H - -#include -#include "strings.h" - -DECLARE_CLASS(Stream); - -extern Stream Console; - -Stream stream_create_file(const char* filename); -Stream stream_create_null(void); -void stream_destroy(Stream stream); -void stream_set_buffer(Stream strm, char* buffer); -void stream_set_newline(Stream strm, const char* newline); -int stream_vprintf(Stream strm, const char* value, va_list args); -int stream_write(Stream strm, const char* value, ...); -int stream_write_n(Stream strm, const char* value, int n); -int stream_write_strings(Stream strm, Strings strs, const char* start, const char* prefix, const char* postfix, const char* infix, const char* end); -int stream_write_unicode_marker(Stream strm); -int stream_writeline(Stream strm, const char* value, ...); -int stream_writeline_strings(Stream strm, Strings strs, const char* start, const char* prefix, const char* postfix, const char* infix); - -#endif -/** @} */ +/** + * \file stream.h + * \brief Output stream handling. + * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project + * + * \defgroup stream Streams + * \ingroup base + * + * An output stream class. + * + * @{ + */ +#if !defined(PREMAKE_STREAM_H) +#define PREMAKE_STREAM_H + +#include +#include "strings.h" + +DECLARE_CLASS(Stream); + +extern Stream Console; + +Stream stream_create_file(const char* filename); +Stream stream_create_null(void); +void stream_destroy(Stream stream); +void stream_set_buffer(Stream strm, char* buffer); +void stream_set_newline(Stream strm, const char* newline); +int stream_vprintf(Stream strm, const char* value, va_list args); +int stream_write(Stream strm, const char* value, ...); +int stream_write_n(Stream strm, const char* value, int n); +int stream_write_strings(Stream strm, Strings strs, const char* start, const char* prefix, const char* postfix, const char* infix, const char* end); +int stream_write_unicode_marker(Stream strm); +int stream_writeline(Stream strm, const char* value, ...); +int stream_writeline_strings(Stream strm, Strings strs, const char* start, const char* prefix, const char* postfix, const char* infix); + +#endif +/** @} */ diff --git a/src/base/string.c b/src/base/string.c index 5868b1f..09db9c9 100644 --- a/src/base/string.c +++ b/src/base/string.c @@ -1,67 +1,67 @@ -/** - * \file string.c - * \brief Dynamic string handling. - * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project - */ - -#include -#include -#include "premake.h" -#include "base/string.h" - - -DEFINE_CLASS(String) -{ - char* contents; - int capacity; -}; - - -/** - * Create a new dynamic string object from an existing C string. - * \param value The C string value. - * \returns A new dynamic string object containing a copy of the string. - */ -String string_create(const char* value) -{ - if (value != NULL) - { - String str = ALLOC_CLASS(String); - str->capacity = strlen(value) + 1; - str->contents = (char*)malloc(str->capacity); - strcpy(str->contents, value); - return str; - } - else - { - return NULL; - } -} - - -/** - * Destroy a dynamic string object and free the associated memory. - * \param str The string to destroy. - */ -void string_destroy(String str) -{ - if (str != NULL) - { - free(str->contents); - free(str); - } -} - - -/** - * Return the contents of a dynamic string as a C string. - * \param str The string to query. - * \returns The C string value. - */ -const char* string_cstr(String str) -{ - if (str != NULL) - return str->contents; - else - return NULL; -} +/** + * \file string.c + * \brief Dynamic string handling. + * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project + */ + +#include +#include +#include "premake.h" +#include "base/string.h" + + +DEFINE_CLASS(String) +{ + char* contents; + int capacity; +}; + + +/** + * Create a new dynamic string object from an existing C string. + * \param value The C string value. + * \returns A new dynamic string object containing a copy of the string. + */ +String string_create(const char* value) +{ + if (value != NULL) + { + String str = ALLOC_CLASS(String); + str->capacity = strlen(value) + 1; + str->contents = (char*)malloc(str->capacity); + strcpy(str->contents, value); + return str; + } + else + { + return NULL; + } +} + + +/** + * Destroy a dynamic string object and free the associated memory. + * \param str The string to destroy. + */ +void string_destroy(String str) +{ + if (str != NULL) + { + free(str->contents); + free(str); + } +} + + +/** + * Return the contents of a dynamic string as a C string. + * \param str The string to query. + * \returns The C string value. + */ +const char* string_cstr(String str) +{ + if (str != NULL) + return str->contents; + else + return NULL; +} diff --git a/src/base/string.h b/src/base/string.h index 8b8ba33..47c6281 100644 --- a/src/base/string.h +++ b/src/base/string.h @@ -1,23 +1,23 @@ -/** - * \file string.h - * \brief Dynamic string handling. - * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project - * - * \defgroup string Strings - * \ingroup base - * - * A dynamic string class. - * - * @{ - */ -#if !defined(PREMAKE_STRING_H) -#define PREMAKE_STRING_H - -DECLARE_CLASS(String); - -String string_create(const char* value); -void string_destroy(String str); -const char* string_cstr(String str); - -#endif -/** @} */ +/** + * \file string.h + * \brief Dynamic string handling. + * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project + * + * \defgroup string Strings + * \ingroup base + * + * A dynamic string class. + * + * @{ + */ +#if !defined(PREMAKE_STRING_H) +#define PREMAKE_STRING_H + +DECLARE_CLASS(String); + +String string_create(const char* value); +void string_destroy(String str); +const char* string_cstr(String str); + +#endif +/** @} */ diff --git a/src/base/strings.c b/src/base/strings.c index 8222cc3..7862b68 100644 --- a/src/base/strings.c +++ b/src/base/strings.c @@ -1,97 +1,97 @@ -/** - * \file strings.c - * \brief A dynamic array of C strings. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include -#include "premake.h" -#include "strings.h" -#include "base/array.h" - -DEFINE_CLASS(Strings) -{ - Array contents; -}; - - - -/** - * Create a new dynamic array of C strings. - * \returns A new string array. - */ -Strings strings_create() -{ - Strings strs = ALLOC_CLASS(Strings); - strs->contents = array_create(); - return strs; -} - - -/** - * Destroy a strings array and free the associated memory. - * \param strs The string array to destroy. - */ -void strings_destroy(Strings strs) -{ - array_destroy(strs->contents); - free(strs); -} - - -/** - * Add a new item to the end of an array of strings. - * \param strs The array of strings. - * \param item The C string item to add. - */ -void strings_add(Strings strs, const char* item) -{ - array_add(strs->contents, (void*)item); -} - - -/** - * Append the contents of one string vector to another. - * \param dest The destination vector. - * \param src The source vector. - */ -void strings_append(Strings dest, Strings src) -{ - array_append(dest->contents, src->contents); -} - - -/** - * Retrieve an C string item from an array of strings. - * \param strs The string array to query. - * \param index The index of the item to retrieve. - * \returns A pointer to the C string item. - */ -const char* strings_item(Strings strs, int index) -{ - return (const char*)array_item(strs->contents, index); -} - - -/** - * Set the value at a particular index of the array. - * \param strs The string array. - * \param index The index of the item to set. - * \param item The new item. - */ -void strings_set(Strings strs, int index, const char* item) -{ - array_set(strs->contents, index, (void*)item); -} - - -/** - * Get the number of items in the string array. - * \param strs The string array to query. - * \returns The number elements currently in the array. - */ -int strings_size(Strings strs) -{ - return array_size(strs->contents); -} - +/** + * \file strings.c + * \brief A dynamic array of C strings. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include +#include "premake.h" +#include "strings.h" +#include "base/array.h" + +DEFINE_CLASS(Strings) +{ + Array contents; +}; + + + +/** + * Create a new dynamic array of C strings. + * \returns A new string array. + */ +Strings strings_create() +{ + Strings strs = ALLOC_CLASS(Strings); + strs->contents = array_create(); + return strs; +} + + +/** + * Destroy a strings array and free the associated memory. + * \param strs The string array to destroy. + */ +void strings_destroy(Strings strs) +{ + array_destroy(strs->contents); + free(strs); +} + + +/** + * Add a new item to the end of an array of strings. + * \param strs The array of strings. + * \param item The C string item to add. + */ +void strings_add(Strings strs, const char* item) +{ + array_add(strs->contents, (void*)item); +} + + +/** + * Append the contents of one string vector to another. + * \param dest The destination vector. + * \param src The source vector. + */ +void strings_append(Strings dest, Strings src) +{ + array_append(dest->contents, src->contents); +} + + +/** + * Retrieve an C string item from an array of strings. + * \param strs The string array to query. + * \param index The index of the item to retrieve. + * \returns A pointer to the C string item. + */ +const char* strings_item(Strings strs, int index) +{ + return (const char*)array_item(strs->contents, index); +} + + +/** + * Set the value at a particular index of the array. + * \param strs The string array. + * \param index The index of the item to set. + * \param item The new item. + */ +void strings_set(Strings strs, int index, const char* item) +{ + array_set(strs->contents, index, (void*)item); +} + + +/** + * Get the number of items in the string array. + * \param strs The string array to query. + * \returns The number elements currently in the array. + */ +int strings_size(Strings strs) +{ + return array_size(strs->contents); +} + diff --git a/src/base/strings.h b/src/base/strings.h index 832cb1e..d75daa2 100644 --- a/src/base/strings.h +++ b/src/base/strings.h @@ -1,28 +1,28 @@ -/** - * \file strings.h - * \brief A dynamic array of C strings. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - * - * \defgroup strings String Collection - * \ingroup base - * - * A dynamic array of C strings. - * - * @{ - */ -#if !defined(PREMAKE_STRINGS_H) -#define PREMAKE_STRINGS_H - -DECLARE_CLASS(Strings); - -Strings strings_create(void); -void strings_destroy(Strings strs); - -void strings_add(Strings strs, const char* item); -void strings_append(Strings dest, Strings src); -const char* strings_item(Strings strs, int index); -void strings_set(Strings strs, int index, const char* item); -int strings_size(Strings strs); - -#endif -/** @} */ +/** + * \file strings.h + * \brief A dynamic array of C strings. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + * + * \defgroup strings String Collection + * \ingroup base + * + * A dynamic array of C strings. + * + * @{ + */ +#if !defined(PREMAKE_STRINGS_H) +#define PREMAKE_STRINGS_H + +DECLARE_CLASS(Strings); + +Strings strings_create(void); +void strings_destroy(Strings strs); + +void strings_add(Strings strs, const char* item); +void strings_append(Strings dest, Strings src); +const char* strings_item(Strings strs, int index); +void strings_set(Strings strs, int index, const char* item); +int strings_size(Strings strs); + +#endif +/** @} */ diff --git a/src/base/tests/base_tests.cpp b/src/base/tests/base_tests.cpp index efdd646..58368ec 100644 --- a/src/base/tests/base_tests.cpp +++ b/src/base/tests/base_tests.cpp @@ -1,23 +1,23 @@ -/** - * \file base_tests.cpp - * \brief Automated tests for Premake base library. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "testing/testing.h" -extern "C" { -#include "base/base.h" -} - - -/** - * \brief Run the base library automated tests. - * \returns OKAY if all tests completed successfully. - */ -int base_tests() -{ - int status = tests_run_suite("cstr"); - if (status == OKAY) status = tests_run_suite("base"); - return status; -} +/** + * \file base_tests.cpp + * \brief Automated tests for Premake base library. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "testing/testing.h" +extern "C" { +#include "base/base.h" +} + + +/** + * \brief Run the base library automated tests. + * \returns OKAY if all tests completed successfully. + */ +int base_tests() +{ + int status = tests_run_suite("cstr"); + if (status == OKAY) status = tests_run_suite("base"); + return status; +} diff --git a/src/base/tests/cstr_tests.cpp b/src/base/tests/cstr_tests.cpp index 3a3f456..bf7a996 100644 --- a/src/base/tests/cstr_tests.cpp +++ b/src/base/tests/cstr_tests.cpp @@ -1,149 +1,149 @@ -/** - * \file cstr_tests.cpp - * \brief C string automated tests. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "testing/testing.h" -extern "C" { -#include "base/cstr.h" -} - -SUITE(cstr) -{ - /************************************************************************** - * cstr_contains() tests - **************************************************************************/ - - TEST(CStrContains_ReturnsTrue_OnMatch) - { - CHECK(cstr_contains("Abcdef", "cd")); - } - - TEST(CStrContains_ReturnsFalse_OnMismatch) - { - CHECK(!cstr_contains("Abcdef", "xy")); - } - - - /************************************************************************** - * cstr_ends_with() tests - **************************************************************************/ - - TEST(CStrEndsWith_ReturnsTrue_OnMatch) - { - CHECK(cstr_ends_with("Abcdef", "def")); - } - - TEST(CStrEndsWith_ReturnsFalse_OnMismatch) - { - CHECK(!cstr_ends_with("Abcdef", "ghi")); - } - - TEST(CStrEndsWith_ReturnsFalse_OnLongerNeedle) - { - CHECK(!cstr_ends_with("Abc", "Abcdef")); - } - - TEST(CStrEndsWith_ReturnsFalse_OnNullHaystack) - { - CHECK(!cstr_ends_with(NULL, "ghi")); - } - - TEST(CStrEndsWith_ReturnsFalse_OnNullNeedle) - { - CHECK(!cstr_ends_with("Abc", NULL)); - } - - - /************************************************************************** - * cstr_eq() tests - **************************************************************************/ - - TEST(CStrEq_ReturnsTrue_OnMatch) - { - CHECK(cstr_eq("A string", "A string")); - } - - TEST(CStrEq_ReturnsFalse_OnMismatch) - { - CHECK(!cstr_eq("A string", "A different string")); - } - - TEST(CStrEq_ReturnsFalse_OnNullTarget) - { - CHECK(!cstr_eq(NULL, "something")); - } - - TEST(CStrEq_ReturnsFalse_OnNullPattern) - { - CHECK(!cstr_eq("something", NULL)); - } - - - /************************************************************************** - * cstr_eqi() tests - **************************************************************************/ - - TEST(CStrEqi_ReturnsTrue_OnMatch) - { - CHECK(cstr_eqi("A string", "a String")); - } - - TEST(CStrEqi_ReturnsFalse_OnMismatch) - { - CHECK(!cstr_eqi("A string", "a different string")); - } - - TEST(CStrEqi_ReturnsFalse_OnNullTarget) - { - CHECK(!cstr_eqi(NULL, "something")); - } - - TEST(CStrEqi_ReturnsFalse_OnNullPattern) - { - CHECK(!cstr_eqi("something", NULL)); - } - - - /************************************************************************** - * cstr_format() tests - **************************************************************************/ - - TEST(CstrFormat_ReturnsFormatted) - { - char* result = cstr_format("$(OBJDIR)/%s.o", "hello"); - CHECK_EQUAL("$(OBJDIR)/hello.o", result); - } - - - /************************************************************************** - * cstr_starts_with() tests - **************************************************************************/ - - TEST(CStrStartsWith_ReturnsTrue_OnMatch) - { - CHECK(cstr_starts_with("Abcdef", "Abc")); - } - - TEST(CStrStartsWith_ReturnsFalse_OnMismatch) - { - CHECK(!cstr_starts_with("Abcdef", "ghi")); - } - - TEST(CStrStartsWith_ReturnsFalse_OnLongerNeedle) - { - CHECK(!cstr_starts_with("Abc", "Abcdef")); - } - - TEST(CStrStartsWith_ReturnsFalse_OnNullHaystack) - { - CHECK(!cstr_starts_with(NULL, "ghi")); - } - - TEST(CStrStartsWith_ReturnsFalse_OnNullNeedle) - { - CHECK(!cstr_starts_with("Abc", NULL)); - } -} +/** + * \file cstr_tests.cpp + * \brief C string automated tests. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "testing/testing.h" +extern "C" { +#include "base/cstr.h" +} + +SUITE(cstr) +{ + /************************************************************************** + * cstr_contains() tests + **************************************************************************/ + + TEST(CStrContains_ReturnsTrue_OnMatch) + { + CHECK(cstr_contains("Abcdef", "cd")); + } + + TEST(CStrContains_ReturnsFalse_OnMismatch) + { + CHECK(!cstr_contains("Abcdef", "xy")); + } + + + /************************************************************************** + * cstr_ends_with() tests + **************************************************************************/ + + TEST(CStrEndsWith_ReturnsTrue_OnMatch) + { + CHECK(cstr_ends_with("Abcdef", "def")); + } + + TEST(CStrEndsWith_ReturnsFalse_OnMismatch) + { + CHECK(!cstr_ends_with("Abcdef", "ghi")); + } + + TEST(CStrEndsWith_ReturnsFalse_OnLongerNeedle) + { + CHECK(!cstr_ends_with("Abc", "Abcdef")); + } + + TEST(CStrEndsWith_ReturnsFalse_OnNullHaystack) + { + CHECK(!cstr_ends_with(NULL, "ghi")); + } + + TEST(CStrEndsWith_ReturnsFalse_OnNullNeedle) + { + CHECK(!cstr_ends_with("Abc", NULL)); + } + + + /************************************************************************** + * cstr_eq() tests + **************************************************************************/ + + TEST(CStrEq_ReturnsTrue_OnMatch) + { + CHECK(cstr_eq("A string", "A string")); + } + + TEST(CStrEq_ReturnsFalse_OnMismatch) + { + CHECK(!cstr_eq("A string", "A different string")); + } + + TEST(CStrEq_ReturnsFalse_OnNullTarget) + { + CHECK(!cstr_eq(NULL, "something")); + } + + TEST(CStrEq_ReturnsFalse_OnNullPattern) + { + CHECK(!cstr_eq("something", NULL)); + } + + + /************************************************************************** + * cstr_eqi() tests + **************************************************************************/ + + TEST(CStrEqi_ReturnsTrue_OnMatch) + { + CHECK(cstr_eqi("A string", "a String")); + } + + TEST(CStrEqi_ReturnsFalse_OnMismatch) + { + CHECK(!cstr_eqi("A string", "a different string")); + } + + TEST(CStrEqi_ReturnsFalse_OnNullTarget) + { + CHECK(!cstr_eqi(NULL, "something")); + } + + TEST(CStrEqi_ReturnsFalse_OnNullPattern) + { + CHECK(!cstr_eqi("something", NULL)); + } + + + /************************************************************************** + * cstr_format() tests + **************************************************************************/ + + TEST(CstrFormat_ReturnsFormatted) + { + char* result = cstr_format("$(OBJDIR)/%s.o", "hello"); + CHECK_EQUAL("$(OBJDIR)/hello.o", result); + } + + + /************************************************************************** + * cstr_starts_with() tests + **************************************************************************/ + + TEST(CStrStartsWith_ReturnsTrue_OnMatch) + { + CHECK(cstr_starts_with("Abcdef", "Abc")); + } + + TEST(CStrStartsWith_ReturnsFalse_OnMismatch) + { + CHECK(!cstr_starts_with("Abcdef", "ghi")); + } + + TEST(CStrStartsWith_ReturnsFalse_OnLongerNeedle) + { + CHECK(!cstr_starts_with("Abc", "Abcdef")); + } + + TEST(CStrStartsWith_ReturnsFalse_OnNullHaystack) + { + CHECK(!cstr_starts_with(NULL, "ghi")); + } + + TEST(CStrStartsWith_ReturnsFalse_OnNullNeedle) + { + CHECK(!cstr_starts_with("Abc", NULL)); + } +} diff --git a/src/base/tests/dir_tests.cpp b/src/base/tests/dir_tests.cpp index 0fc7a21..baf3ce3 100644 --- a/src/base/tests/dir_tests.cpp +++ b/src/base/tests/dir_tests.cpp @@ -1,27 +1,27 @@ -/** - * \file dir_tests.cpp - * \brief Directory handling automated tests. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "testing/testing.h" -extern "C" { -#include "base/dir.h" -#include "base/cstr.h" -} - -SUITE(base) -{ - TEST(DirExists_ReturnsOkay_OnEmptyPath) - { - int result = dir_exists(""); - CHECK(result); - } - - TEST(DirGetCurrent_ReturnsCurrent_WithSlashes) - { - const char* result = dir_get_current(); - CHECK(cstr_ends_with(result, "/src")); - } -} +/** + * \file dir_tests.cpp + * \brief Directory handling automated tests. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "testing/testing.h" +extern "C" { +#include "base/dir.h" +#include "base/cstr.h" +} + +SUITE(base) +{ + TEST(DirExists_ReturnsOkay_OnEmptyPath) + { + int result = dir_exists(""); + CHECK(result); + } + + TEST(DirGetCurrent_ReturnsCurrent_WithSlashes) + { + const char* result = dir_get_current(); + CHECK(cstr_ends_with(result, "/src")); + } +} diff --git a/src/base/tests/guid_tests.cpp b/src/base/tests/guid_tests.cpp index 77d8b18..4d89b17 100644 --- a/src/base/tests/guid_tests.cpp +++ b/src/base/tests/guid_tests.cpp @@ -1,86 +1,86 @@ -/** - * \file guid_tests.cpp - * \brief Automated tests for GUID generation and validation. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "testing/testing.h" -extern "C" { -#include "base/guid.h" -} - - -SUITE(base) -{ - TEST(GuidCreate_ReturnsCorrectSize) - { - const char* guid = guid_create(); - CHECK(guid != NULL && strlen(guid) == 36); - } - - TEST(GuidCreate_CorrectDashes) - { - const char* guid = guid_create(); - CHECK(guid[8]=='-' && guid[13]=='-' && guid[18]=='-' && guid[23]=='-'); - } - - TEST(GuidCreate_CorrectSymbols) - { - for (const char* guid = guid_create(); *guid; ++guid) - { - const char ch = *guid; - CHECK((ch>='0' && ch<='9') || (ch>='A' && ch<='F') || (ch=='-')); - } - } - - TEST(GuidCreate_CorrectNumOfDashes) - { - int num = 0; - for (const char* guid = guid_create(); *guid; ++guid) - { - if (*guid=='-') ++num; - } - CHECK(num == 4); - } - - TEST(GuidIsValid_ReturnsTrue_OnNoBraces) - { - CHECK(guid_is_valid("4E67EBCE-BC8B-4058-9AA9-48EE5E003683")); - } - - TEST(GuidIsValid_ReturnsFalse_OnTooShort) - { - CHECK(!guid_is_valid("4E67EBCE-BC8B-4058-9AA9-48EE")); - } - - TEST(GuidIsValid_ReturnsFalse_OnMissingFirstDash) - { - CHECK(!guid_is_valid("4E67EBCE BC8B-4058-9AA9-48EE5E003683")); - } - - TEST(GuidIsValid_ReturnsFalse_OnMissingSecondDash) - { - CHECK(!guid_is_valid("4E67EBCE-BC8B 4058-9AA9-48EE5E003683")); - } - - TEST(GuidIsValid_ReturnsFalse_OnMissingThirdDash) - { - CHECK(!guid_is_valid("4E67EBCE-BC8B-4058 9AA9-48EE5E003683")); - } - - TEST(GuidIsValid_ReturnsFalse_OnMissingLastDash) - { - CHECK(!guid_is_valid("4E67EBCE-BC8B-4058-9AA9 48EE5E003683")); - } - - TEST(GuidIsValid_ReturnsFalse_OnTooManyDashes) - { - CHECK(!guid_is_valid("4E67EBCE-BC8B-4058-9AA9-48EE5-003683")); - } - - TEST(GuidIsValid_ReturnsFalse_OnInvalidChar) - { - CHECK(!guid_is_valid("XE67EBCE-BC8B-4058-9AA9-48EE5X003683")); - } -} +/** + * \file guid_tests.cpp + * \brief Automated tests for GUID generation and validation. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "testing/testing.h" +extern "C" { +#include "base/guid.h" +} + + +SUITE(base) +{ + TEST(GuidCreate_ReturnsCorrectSize) + { + const char* guid = guid_create(); + CHECK(guid != NULL && strlen(guid) == 36); + } + + TEST(GuidCreate_CorrectDashes) + { + const char* guid = guid_create(); + CHECK(guid[8]=='-' && guid[13]=='-' && guid[18]=='-' && guid[23]=='-'); + } + + TEST(GuidCreate_CorrectSymbols) + { + for (const char* guid = guid_create(); *guid; ++guid) + { + const char ch = *guid; + CHECK((ch>='0' && ch<='9') || (ch>='A' && ch<='F') || (ch=='-')); + } + } + + TEST(GuidCreate_CorrectNumOfDashes) + { + int num = 0; + for (const char* guid = guid_create(); *guid; ++guid) + { + if (*guid=='-') ++num; + } + CHECK(num == 4); + } + + TEST(GuidIsValid_ReturnsTrue_OnNoBraces) + { + CHECK(guid_is_valid("4E67EBCE-BC8B-4058-9AA9-48EE5E003683")); + } + + TEST(GuidIsValid_ReturnsFalse_OnTooShort) + { + CHECK(!guid_is_valid("4E67EBCE-BC8B-4058-9AA9-48EE")); + } + + TEST(GuidIsValid_ReturnsFalse_OnMissingFirstDash) + { + CHECK(!guid_is_valid("4E67EBCE BC8B-4058-9AA9-48EE5E003683")); + } + + TEST(GuidIsValid_ReturnsFalse_OnMissingSecondDash) + { + CHECK(!guid_is_valid("4E67EBCE-BC8B 4058-9AA9-48EE5E003683")); + } + + TEST(GuidIsValid_ReturnsFalse_OnMissingThirdDash) + { + CHECK(!guid_is_valid("4E67EBCE-BC8B-4058 9AA9-48EE5E003683")); + } + + TEST(GuidIsValid_ReturnsFalse_OnMissingLastDash) + { + CHECK(!guid_is_valid("4E67EBCE-BC8B-4058-9AA9 48EE5E003683")); + } + + TEST(GuidIsValid_ReturnsFalse_OnTooManyDashes) + { + CHECK(!guid_is_valid("4E67EBCE-BC8B-4058-9AA9-48EE5-003683")); + } + + TEST(GuidIsValid_ReturnsFalse_OnInvalidChar) + { + CHECK(!guid_is_valid("XE67EBCE-BC8B-4058-9AA9-48EE5X003683")); + } +} diff --git a/src/base/tests/path_tests.cpp b/src/base/tests/path_tests.cpp index b18a12a..0a9fe1e 100644 --- a/src/base/tests/path_tests.cpp +++ b/src/base/tests/path_tests.cpp @@ -1,266 +1,266 @@ -/** - * \file path_tests.cpp - * \brief Path handling automated tests. - * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "testing/testing.h" -extern "C" { -#include "base/path.h" -#include "base/cstr.h" -#include "base/dir.h" -#include "platform/platform.h" -} - -SUITE(base) -{ - /************************************************************************** - * path_absolute() tests - **************************************************************************/ - - TEST(PathAbsolute_ReturnsCorrectPath_OnMissingSubdir) - { - char* cwd = dir_get_current(); - strcat(cwd, "/a/b/c"); - char* result = path_absolute("a/b/c"); - CHECK_EQUAL(cwd, result); - } - - - /************************************************************************** - * path_assemble() tests - **************************************************************************/ - - TEST(PathAssemble_ReturnsAssembledPath_OnValidParts) - { - char* result = path_assemble("directory", "filename", ".ext"); - CHECK_EQUAL("directory/filename.ext", result); - } - - TEST(PathAssemble_ReturnsAssembledPath_OnNoDirectory) - { - char* result = path_assemble("", "filename", ".ext"); - CHECK_EQUAL("filename.ext", result); - } - - - /************************************************************************** - * path_basename() tests - **************************************************************************/ - - TEST(PathBaseName_ReturnsBase_OnDirAndExt) - { - char* result = path_basename("folder/filename.ext"); - CHECK_EQUAL("filename", result); - } - - - /************************************************************************** - * path_directory() tests - **************************************************************************/ - - TEST(PathDirectory_ReturnsEmptyString_OnNoDirectory) - { - char* result = path_directory("filename.ext"); - CHECK_EQUAL("", result); - } - - - TEST(PathDirectory_ReturnsDirectory_OnSingleLevelPath) - { - char* result = path_directory("dir0/filename.ext"); - CHECK_EQUAL("dir0", result); - } - - - TEST(PathDirectory_ReturnsDirectory_OnMultiLeveLPath) - { - char* result = path_directory("dir0/dir1/dir2/filename.ext"); - CHECK_EQUAL("dir0/dir1/dir2", result); - } - - - /************************************************************************** - * path_extension() tests - **************************************************************************/ - - TEST(PathExt_ReturnsEmptyString_OnNoExtension) - { - char* result = path_extension("filename"); - CHECK_EQUAL("", result); - } - - TEST(PathExt_ReturnsExtension) - { - char* result = path_extension("filename.txt"); - CHECK_EQUAL(".txt", result); - } - - TEST(PathExt_ReturnsLastExtension_OnMultipleDots) - { - char* result = path_extension("filename.mod.txt"); - CHECK_EQUAL(".txt", result); - } - - - /************************************************************************** - * path_filename() tests - **************************************************************************/ - - TEST(PathFileName_ReturnsAll_OnNoDirectory) - { - char* result = path_filename("filename.ext"); - CHECK_EQUAL("filename.ext", result); - } - - TEST(PathFileName_ReturnsEmptyString_OnNoName) - { - char* result = path_filename("dir0/dir1/"); - CHECK_EQUAL("", result); - } - - TEST(PathFileName_ReturnsOnlyName_OnFullPath) - { - char* result = path_filename("dir0/dir1/filename.ext"); - CHECK_EQUAL("filename.ext", result); - } - - - /************************************************************************** - * path_is_absolute() tests - **************************************************************************/ - - TEST(PathIsAbsolute_ReturnsTrue_OnAbsolutePosixPath) - { - CHECK(path_is_absolute("/a/b/c")); - } - - - TEST(PathIsAbsolute_ReturnsTrue_OnAbsoluteWindowsPathWithDrive) - { - CHECK(path_is_absolute("c:/a/b/c")); - } - - - TEST(PathIsAbsolute_ReturnsFalse_OnRelativePath) - { - CHECK(!path_is_absolute("a/b/c")); - } - - - /************************************************************************** - * path_is_absolute() tests - **************************************************************************/ - - TEST(PathIsCpp_ReturnsFalse_OnNotCpp) - { - CHECK(!path_is_cpp_source("filename.XXX")); - } - - TEST(PathIsCpp_ReturnsTrue_OnC) - { - CHECK(path_is_cpp_source("filename.c")); - } - - TEST(PathIsCpp_ReturnsTrue_OnCC) - { - CHECK(path_is_cpp_source("filename.cc")); - } - - TEST(PathIsCpp_ReturnsTrue_OnCpp) - { - CHECK(path_is_cpp_source("filename.cpp")); - } - - TEST(PathIsCpp_ReturnsTrue_OnCxx) - { - CHECK(path_is_cpp_source("filename.cxx")); - } - - TEST(PathIsCpp_ReturnsTrue_OnS) - { - CHECK(path_is_cpp_source("filename.s")); - } - - TEST(PathIsCpp_ReturnsTrue_OnUpperCase) - { - CHECK(path_is_cpp_source("filename.C")); - } - - - /************************************************************************** - * path_join() tests - **************************************************************************/ - - TEST(PathJoin_ReturnsJoinedPath_OnValidParts) - { - char* result = path_join("leading", "trailing"); - CHECK_EQUAL("leading/trailing", result); - } - - TEST(PathJoin_ReturnsAbsPath_OnAbsUnixPath) - { - char* result = path_join("leading", "/trailing"); - CHECK_EQUAL("/trailing", result); - } - - TEST(PathJoin_ReturnsAbsPath_OnAbsWindowsPath) - { - char* result = path_join("leading", "C:/trailing"); - CHECK_EQUAL("C:/trailing", result); - } - - - /************************************************************************** - * path_relative() tests - **************************************************************************/ - - TEST(PathRelative_ReturnsDot_OnMatchingPaths) - { - char* result = path_relative("/a/b/c", "/a/b/c"); - CHECK_EQUAL(".", result); - } - - - TEST(PathRelative_ReturnsDoubleDot_OnChildToParent) - { - char* result = path_relative("/a/b/c", "/a/b"); - CHECK_EQUAL("..", result); - } - - - TEST(PathRelative_ReturnsDoubleDotPath_OnSiblingToSibling) - { - char* result = path_relative("/a/b/c", "/a/b/d"); - CHECK_EQUAL("../d", result); - } - - - TEST(PathRelative_ReturnsChildPath_OnParentToChild) - { - char* result = path_relative("/a/b/c", "/a/b/c/d"); - CHECK_EQUAL("d", result); - } - - - /************************************************************************** - * path_translate() tests - **************************************************************************/ - - TEST(PathTranslate_ReturnsTranslatedPath_OnValidPath) - { - char* result = path_translate("dir\\dir\\file", "/"); - CHECK_EQUAL("dir/dir/file", result); - } - - TEST(PathTranslate_ReturnsCorrectSeparator_OnMixedPath) - { - char* result = path_translate("dir\\dir/file", NULL); - #if defined(PLATFORM_WINDOWS) - CHECK_EQUAL("dir\\dir\\file", result); - #else - CHECK_EQUAL("dir/dir/file", result); - #endif - } -} +/** + * \file path_tests.cpp + * \brief Path handling automated tests. + * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "testing/testing.h" +extern "C" { +#include "base/path.h" +#include "base/cstr.h" +#include "base/dir.h" +#include "platform/platform.h" +} + +SUITE(base) +{ + /************************************************************************** + * path_absolute() tests + **************************************************************************/ + + TEST(PathAbsolute_ReturnsCorrectPath_OnMissingSubdir) + { + char* cwd = dir_get_current(); + strcat(cwd, "/a/b/c"); + char* result = path_absolute("a/b/c"); + CHECK_EQUAL(cwd, result); + } + + + /************************************************************************** + * path_assemble() tests + **************************************************************************/ + + TEST(PathAssemble_ReturnsAssembledPath_OnValidParts) + { + char* result = path_assemble("directory", "filename", ".ext"); + CHECK_EQUAL("directory/filename.ext", result); + } + + TEST(PathAssemble_ReturnsAssembledPath_OnNoDirectory) + { + char* result = path_assemble("", "filename", ".ext"); + CHECK_EQUAL("filename.ext", result); + } + + + /************************************************************************** + * path_basename() tests + **************************************************************************/ + + TEST(PathBaseName_ReturnsBase_OnDirAndExt) + { + char* result = path_basename("folder/filename.ext"); + CHECK_EQUAL("filename", result); + } + + + /************************************************************************** + * path_directory() tests + **************************************************************************/ + + TEST(PathDirectory_ReturnsEmptyString_OnNoDirectory) + { + char* result = path_directory("filename.ext"); + CHECK_EQUAL("", result); + } + + + TEST(PathDirectory_ReturnsDirectory_OnSingleLevelPath) + { + char* result = path_directory("dir0/filename.ext"); + CHECK_EQUAL("dir0", result); + } + + + TEST(PathDirectory_ReturnsDirectory_OnMultiLeveLPath) + { + char* result = path_directory("dir0/dir1/dir2/filename.ext"); + CHECK_EQUAL("dir0/dir1/dir2", result); + } + + + /************************************************************************** + * path_extension() tests + **************************************************************************/ + + TEST(PathExt_ReturnsEmptyString_OnNoExtension) + { + char* result = path_extension("filename"); + CHECK_EQUAL("", result); + } + + TEST(PathExt_ReturnsExtension) + { + char* result = path_extension("filename.txt"); + CHECK_EQUAL(".txt", result); + } + + TEST(PathExt_ReturnsLastExtension_OnMultipleDots) + { + char* result = path_extension("filename.mod.txt"); + CHECK_EQUAL(".txt", result); + } + + + /************************************************************************** + * path_filename() tests + **************************************************************************/ + + TEST(PathFileName_ReturnsAll_OnNoDirectory) + { + char* result = path_filename("filename.ext"); + CHECK_EQUAL("filename.ext", result); + } + + TEST(PathFileName_ReturnsEmptyString_OnNoName) + { + char* result = path_filename("dir0/dir1/"); + CHECK_EQUAL("", result); + } + + TEST(PathFileName_ReturnsOnlyName_OnFullPath) + { + char* result = path_filename("dir0/dir1/filename.ext"); + CHECK_EQUAL("filename.ext", result); + } + + + /************************************************************************** + * path_is_absolute() tests + **************************************************************************/ + + TEST(PathIsAbsolute_ReturnsTrue_OnAbsolutePosixPath) + { + CHECK(path_is_absolute("/a/b/c")); + } + + + TEST(PathIsAbsolute_ReturnsTrue_OnAbsoluteWindowsPathWithDrive) + { + CHECK(path_is_absolute("c:/a/b/c")); + } + + + TEST(PathIsAbsolute_ReturnsFalse_OnRelativePath) + { + CHECK(!path_is_absolute("a/b/c")); + } + + + /************************************************************************** + * path_is_absolute() tests + **************************************************************************/ + + TEST(PathIsCpp_ReturnsFalse_OnNotCpp) + { + CHECK(!path_is_cpp_source("filename.XXX")); + } + + TEST(PathIsCpp_ReturnsTrue_OnC) + { + CHECK(path_is_cpp_source("filename.c")); + } + + TEST(PathIsCpp_ReturnsTrue_OnCC) + { + CHECK(path_is_cpp_source("filename.cc")); + } + + TEST(PathIsCpp_ReturnsTrue_OnCpp) + { + CHECK(path_is_cpp_source("filename.cpp")); + } + + TEST(PathIsCpp_ReturnsTrue_OnCxx) + { + CHECK(path_is_cpp_source("filename.cxx")); + } + + TEST(PathIsCpp_ReturnsTrue_OnS) + { + CHECK(path_is_cpp_source("filename.s")); + } + + TEST(PathIsCpp_ReturnsTrue_OnUpperCase) + { + CHECK(path_is_cpp_source("filename.C")); + } + + + /************************************************************************** + * path_join() tests + **************************************************************************/ + + TEST(PathJoin_ReturnsJoinedPath_OnValidParts) + { + char* result = path_join("leading", "trailing"); + CHECK_EQUAL("leading/trailing", result); + } + + TEST(PathJoin_ReturnsAbsPath_OnAbsUnixPath) + { + char* result = path_join("leading", "/trailing"); + CHECK_EQUAL("/trailing", result); + } + + TEST(PathJoin_ReturnsAbsPath_OnAbsWindowsPath) + { + char* result = path_join("leading", "C:/trailing"); + CHECK_EQUAL("C:/trailing", result); + } + + + /************************************************************************** + * path_relative() tests + **************************************************************************/ + + TEST(PathRelative_ReturnsDot_OnMatchingPaths) + { + char* result = path_relative("/a/b/c", "/a/b/c"); + CHECK_EQUAL(".", result); + } + + + TEST(PathRelative_ReturnsDoubleDot_OnChildToParent) + { + char* result = path_relative("/a/b/c", "/a/b"); + CHECK_EQUAL("..", result); + } + + + TEST(PathRelative_ReturnsDoubleDotPath_OnSiblingToSibling) + { + char* result = path_relative("/a/b/c", "/a/b/d"); + CHECK_EQUAL("../d", result); + } + + + TEST(PathRelative_ReturnsChildPath_OnParentToChild) + { + char* result = path_relative("/a/b/c", "/a/b/c/d"); + CHECK_EQUAL("d", result); + } + + + /************************************************************************** + * path_translate() tests + **************************************************************************/ + + TEST(PathTranslate_ReturnsTranslatedPath_OnValidPath) + { + char* result = path_translate("dir\\dir\\file", "/"); + CHECK_EQUAL("dir/dir/file", result); + } + + TEST(PathTranslate_ReturnsCorrectSeparator_OnMixedPath) + { + char* result = path_translate("dir\\dir/file", NULL); + #if defined(PLATFORM_WINDOWS) + CHECK_EQUAL("dir\\dir\\file", result); + #else + CHECK_EQUAL("dir/dir/file", result); + #endif + } +} diff --git a/src/base/tests/stream_tests.cpp b/src/base/tests/stream_tests.cpp index 0504207..1339f68 100644 --- a/src/base/tests/stream_tests.cpp +++ b/src/base/tests/stream_tests.cpp @@ -1,107 +1,107 @@ -/** - * \file stream_tests.cpp - * \brief Output stream automated tests. - * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "testing/testing.h" -extern "C" { -#include "base/stream.h" -} - -struct FxStream -{ - Stream strm; - char buffer[1024]; - - FxStream() - { - strm = stream_create_null(); - stream_set_buffer(strm, buffer); - } - - ~FxStream() - { - stream_destroy(strm); - } -}; - -struct FxStreamStrings : FxStream -{ - Strings strs; - - FxStreamStrings() - { - strs = strings_create(); - } - - ~FxStreamStrings() - { - strings_destroy(strs); - } -}; - - - -SUITE(base) -{ - TEST_FIXTURE(FxStream, Write_WritesValue_OnSimpleValue) - { - stream_write(strm, "Hi there!"); - CHECK_EQUAL("Hi there!", buffer); - } - - TEST_FIXTURE(FxStream, Write_WritesValue_OnFormattedValue) - { - stream_write(strm, "Hi there, %s!", "Mr. Bill"); - CHECK_EQUAL("Hi there, Mr. Bill!", buffer); - } - - TEST_FIXTURE(FxStream, WriteLine_AppendsNewLine_OnSimpleValue) - { - stream_writeline(strm, "Hi there!"); - CHECK_EQUAL("Hi there!\n", buffer); - } - - TEST_FIXTURE(FxStream, WriteLine_AppendsNewLine_OnFormattedValue) - { - stream_writeline(strm, "Hi there, %s!", "Mr. Bill"); - CHECK_EQUAL("Hi there, Mr. Bill!\n", buffer); - } - - TEST_FIXTURE(FxStream, WriteLine_AppendsNewLine_OnModifiedNewline) - { - stream_set_newline(strm, "\r\n"); - stream_writeline(strm, "Hi there!"); - CHECK_EQUAL("Hi there!\r\n", buffer); - } - - - /********************************************************************** - * stream_write_strings() tests - **********************************************************************/ - - TEST_FIXTURE(FxStreamStrings, WriteStrings_WritesStartEnd_OnEmptyList) - { - stream_write_strings(strm, strs, "^", "<", ">", ",", "$"); - CHECK_EQUAL("^$", buffer); - } - - TEST_FIXTURE(FxStreamStrings, WriteStrings_WriteSingleItem_OnSingleItem) - { - strings_add(strs, "AAA"); - stream_write_strings(strm, strs, "^", "<", ">", ",", "$"); - CHECK_EQUAL("^$", buffer); - } - - TEST_FIXTURE(FxStreamStrings, WriteStrings_WriteMultipleItems_OnMultipleItems) - { - strings_add(strs, "AAA"); - strings_add(strs, "BBB"); - strings_add(strs, "CCC"); - stream_write_strings(strm, strs, "^", "<", ">", ",", "$"); - CHECK_EQUAL("^,,$", buffer); - } - -} +/** + * \file stream_tests.cpp + * \brief Output stream automated tests. + * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "testing/testing.h" +extern "C" { +#include "base/stream.h" +} + +struct FxStream +{ + Stream strm; + char buffer[1024]; + + FxStream() + { + strm = stream_create_null(); + stream_set_buffer(strm, buffer); + } + + ~FxStream() + { + stream_destroy(strm); + } +}; + +struct FxStreamStrings : FxStream +{ + Strings strs; + + FxStreamStrings() + { + strs = strings_create(); + } + + ~FxStreamStrings() + { + strings_destroy(strs); + } +}; + + + +SUITE(base) +{ + TEST_FIXTURE(FxStream, Write_WritesValue_OnSimpleValue) + { + stream_write(strm, "Hi there!"); + CHECK_EQUAL("Hi there!", buffer); + } + + TEST_FIXTURE(FxStream, Write_WritesValue_OnFormattedValue) + { + stream_write(strm, "Hi there, %s!", "Mr. Bill"); + CHECK_EQUAL("Hi there, Mr. Bill!", buffer); + } + + TEST_FIXTURE(FxStream, WriteLine_AppendsNewLine_OnSimpleValue) + { + stream_writeline(strm, "Hi there!"); + CHECK_EQUAL("Hi there!\n", buffer); + } + + TEST_FIXTURE(FxStream, WriteLine_AppendsNewLine_OnFormattedValue) + { + stream_writeline(strm, "Hi there, %s!", "Mr. Bill"); + CHECK_EQUAL("Hi there, Mr. Bill!\n", buffer); + } + + TEST_FIXTURE(FxStream, WriteLine_AppendsNewLine_OnModifiedNewline) + { + stream_set_newline(strm, "\r\n"); + stream_writeline(strm, "Hi there!"); + CHECK_EQUAL("Hi there!\r\n", buffer); + } + + + /********************************************************************** + * stream_write_strings() tests + **********************************************************************/ + + TEST_FIXTURE(FxStreamStrings, WriteStrings_WritesStartEnd_OnEmptyList) + { + stream_write_strings(strm, strs, "^", "<", ">", ",", "$"); + CHECK_EQUAL("^$", buffer); + } + + TEST_FIXTURE(FxStreamStrings, WriteStrings_WriteSingleItem_OnSingleItem) + { + strings_add(strs, "AAA"); + stream_write_strings(strm, strs, "^", "<", ">", ",", "$"); + CHECK_EQUAL("^$", buffer); + } + + TEST_FIXTURE(FxStreamStrings, WriteStrings_WriteMultipleItems_OnMultipleItems) + { + strings_add(strs, "AAA"); + strings_add(strs, "BBB"); + strings_add(strs, "CCC"); + stream_write_strings(strm, strs, "^", "<", ">", ",", "$"); + CHECK_EQUAL("^,,$", buffer); + } + +} diff --git a/src/base/tests/string_tests.cpp b/src/base/tests/string_tests.cpp index 6ddd304..ad6fd8a 100644 --- a/src/base/tests/string_tests.cpp +++ b/src/base/tests/string_tests.cpp @@ -1,46 +1,46 @@ -/** - * \file string_tests.cpp - * \brief Dynamic string automated tests. - * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "testing/testing.h" -extern "C" { -#include "base/string.h" -} - -SUITE(base) -{ - /************************************************************************** - * string_create() tests - **************************************************************************/ - - TEST(StringCreate_ReturnsNull_OnNull) - { - String str = string_create(NULL); - CHECK(str == NULL); - } - - - /************************************************************************** - * string_destroy() tests - **************************************************************************/ - - TEST(StringDestroy_DoesNoOp_OnNull) - { - string_destroy(NULL); - CHECK(1); - } - - - /************************************************************************** - * string_cstr() tests - **************************************************************************/ - - TEST(StringCStr_ReturnsNull_OnNullString) - { - CHECK(string_cstr(NULL) == NULL); - } -} - +/** + * \file string_tests.cpp + * \brief Dynamic string automated tests. + * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "testing/testing.h" +extern "C" { +#include "base/string.h" +} + +SUITE(base) +{ + /************************************************************************** + * string_create() tests + **************************************************************************/ + + TEST(StringCreate_ReturnsNull_OnNull) + { + String str = string_create(NULL); + CHECK(str == NULL); + } + + + /************************************************************************** + * string_destroy() tests + **************************************************************************/ + + TEST(StringDestroy_DoesNoOp_OnNull) + { + string_destroy(NULL); + CHECK(1); + } + + + /************************************************************************** + * string_cstr() tests + **************************************************************************/ + + TEST(StringCStr_ReturnsNull_OnNullString) + { + CHECK(string_cstr(NULL) == NULL); + } +} + diff --git a/src/host/host.c b/src/host/host.c index 6fb542b..8226c7b 100644 --- a/src/host/host.c +++ b/src/host/host.c @@ -1,172 +1,172 @@ -/** - * \file host.c - * \brief Main executable API. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include -#include -#include "premake.h" -#include "host/host.h" -#include "action/action.h" -#include "base/cstr.h" -#include "base/error.h" -#include "base/file.h" - - -/** argv, as passed into main(), stored here to be accessible to all host functions. */ -static const char** Args = NULL; - - -/** - * Initial processing and validation of the command line arguments. - * \param sess The current execution session. - * \returns OKAY on success. - */ -int host_parse_argv(Session sess) -{ - session_set_action(sess, Args[0]); - return OKAY; -} - - -/** - * Display the results of the application run. - * Any errors returned during the run will be written to stderr; otherwise, a - * success message is written to stdout. - * \param sess The current execution session. - * \returns OKAY. - */ -int host_report_results(Session sess) -{ - const char* error = error_get(); - if (error) - { - stream_writeline(Console, "Error: %s", error); - } - - sess = 0; /* unused */ - return OKAY; -} - - -/** - * Run the action specified by the user on the command line. - * \param sess The execution session context. - * \returns OKAY on success. - */ -int host_run_action(Session sess) -{ - const char* action; - int i; - - assert(sess); - - /* there must be a project file defined or I can go no further */ - if (!file_exists(DEFAULT_SCRIPT_NAME)) - { - error_set("script file '%s' not found", DEFAULT_SCRIPT_NAME); - return !OKAY; - } - - /* find the action in the master list and execute the associated callback */ - action = Args[0]; - for (i = 0; Actions[i].name != NULL; ++i) - { - if (cstr_eq(Actions[i].name, action)) - { - return Actions[i].callback(sess); - } - } - - /* an invalid action was specified */ - error_set("invalid action '%s'", action); - return !OKAY; -} - - -/** - * Find and execute the project script file. - * \param sess The session object. - * \returns OKAY on success. - */ -int host_run_script(Session sess) -{ - assert(sess); - - /* run the default file for now. If the script file doesn't exist let execution - * continue so I can display help, etc. */ - if (file_exists(DEFAULT_SCRIPT_NAME)) - { - session_run_file(sess, DEFAULT_SCRIPT_NAME); - return (error_get() == NULL) ? OKAY : !OKAY; - } - else - { - return OKAY; - } -} - - -/** - * Run a list of steps, in order, checking status at each step. - * \param sess The current session state. - * \param steps A null-terminated list of step functions. - * \returns OKAY on success. - */ -int host_run_steps(Session sess, HostExecutionStep* steps) -{ - int i, status; - - assert(sess); - assert(steps); - - status = OKAY; - for (i = 0; status == OKAY && steps[i] != NULL; ++i) - { - status = steps[i](sess); - } - - return status; -} - - -/** - * Remember the list of command-line parameters for subsequent calls - * to the other host functions later in the processing steps. - * \param argv The argv variable is passed to main(). - */ -void host_set_argv(const char** argv) -{ - /* skip over the progam name in argv[0] and just store the arguments */ - Args = &argv[1]; -} - - -/** - * Display help and version messages as appropriate. If any messages are - * shown, execution of the main step loop will be stopped and the application - * will exit (this seems to be the standard behavior of POSIX apps when - * help is requested). - * \param sess The current execution session context. - * \returns OKAY is no help information was required, !OKAY to stop the loop. - */ -int host_show_help(Session sess) -{ - assert(Args); - - sess = 0; /* unused */ - - /* while (arg is option) { */ - /* if (/version) ... */ - /* if (/help) ... */ - - /* if no action was specified give the user a clue */ - if (Args[0] == NULL) - { - stream_writeline(Console, HOST_SHORT_HELP); - return !OKAY; - } - - return OKAY; -} +/** + * \file host.c + * \brief Main executable API. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include +#include +#include "premake.h" +#include "host/host.h" +#include "action/action.h" +#include "base/cstr.h" +#include "base/error.h" +#include "base/file.h" + + +/** argv, as passed into main(), stored here to be accessible to all host functions. */ +static const char** Args = NULL; + + +/** + * Initial processing and validation of the command line arguments. + * \param sess The current execution session. + * \returns OKAY on success. + */ +int host_parse_argv(Session sess) +{ + session_set_action(sess, Args[0]); + return OKAY; +} + + +/** + * Display the results of the application run. + * Any errors returned during the run will be written to stderr; otherwise, a + * success message is written to stdout. + * \param sess The current execution session. + * \returns OKAY. + */ +int host_report_results(Session sess) +{ + const char* error = error_get(); + if (error) + { + stream_writeline(Console, "Error: %s", error); + } + + sess = 0; /* unused */ + return OKAY; +} + + +/** + * Run the action specified by the user on the command line. + * \param sess The execution session context. + * \returns OKAY on success. + */ +int host_run_action(Session sess) +{ + const char* action; + int i; + + assert(sess); + + /* there must be a project file defined or I can go no further */ + if (!file_exists(DEFAULT_SCRIPT_NAME)) + { + error_set("script file '%s' not found", DEFAULT_SCRIPT_NAME); + return !OKAY; + } + + /* find the action in the master list and execute the associated callback */ + action = Args[0]; + for (i = 0; Actions[i].name != NULL; ++i) + { + if (cstr_eq(Actions[i].name, action)) + { + return Actions[i].callback(sess); + } + } + + /* an invalid action was specified */ + error_set("invalid action '%s'", action); + return !OKAY; +} + + +/** + * Find and execute the project script file. + * \param sess The session object. + * \returns OKAY on success. + */ +int host_run_script(Session sess) +{ + assert(sess); + + /* run the default file for now. If the script file doesn't exist let execution + * continue so I can display help, etc. */ + if (file_exists(DEFAULT_SCRIPT_NAME)) + { + session_run_file(sess, DEFAULT_SCRIPT_NAME); + return (error_get() == NULL) ? OKAY : !OKAY; + } + else + { + return OKAY; + } +} + + +/** + * Run a list of steps, in order, checking status at each step. + * \param sess The current session state. + * \param steps A null-terminated list of step functions. + * \returns OKAY on success. + */ +int host_run_steps(Session sess, HostExecutionStep* steps) +{ + int i, status; + + assert(sess); + assert(steps); + + status = OKAY; + for (i = 0; status == OKAY && steps[i] != NULL; ++i) + { + status = steps[i](sess); + } + + return status; +} + + +/** + * Remember the list of command-line parameters for subsequent calls + * to the other host functions later in the processing steps. + * \param argv The argv variable is passed to main(). + */ +void host_set_argv(const char** argv) +{ + /* skip over the progam name in argv[0] and just store the arguments */ + Args = &argv[1]; +} + + +/** + * Display help and version messages as appropriate. If any messages are + * shown, execution of the main step loop will be stopped and the application + * will exit (this seems to be the standard behavior of POSIX apps when + * help is requested). + * \param sess The current execution session context. + * \returns OKAY is no help information was required, !OKAY to stop the loop. + */ +int host_show_help(Session sess) +{ + assert(Args); + + sess = 0; /* unused */ + + /* while (arg is option) { */ + /* if (/version) ... */ + /* if (/help) ... */ + + /* if no action was specified give the user a clue */ + if (Args[0] == NULL) + { + stream_writeline(Console, HOST_SHORT_HELP); + return !OKAY; + } + + return OKAY; +} diff --git a/src/host/host.h b/src/host/host.h index 2e5d007..6849d11 100644 --- a/src/host/host.h +++ b/src/host/host.h @@ -1,43 +1,43 @@ -/** - * \file host.h - * \brief Main executable API. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - * - * \defgroup host Host - * - * The "host" part of the application, which is responsible for parsing the command - * line arguments, and the overall flow of the application. - * - * @{ - */ -#if !defined(PREMAKE_HOST_H) -#define PREMAKE_HOST_H - -#include "session/session.h" - -/** - * The short help message, displayed if Premake is run with no arguments. - */ -#define HOST_SHORT_HELP "Type 'premake --help' for help." - - -/** - * Abstract out one step in the process, so I can treat them all identically. - * This lets me unit test the higher-level logic. - * \param sess The current session state. - * \returns OKAY if successful. - */ -typedef int (*HostExecutionStep)(Session sess); - - -int host_parse_argv(Session sess); -int host_report_results(Session sess); -int host_run_action(Session sess); -int host_run_script(Session sess); -int host_run_steps(Session sess, HostExecutionStep* steps); -void host_set_argv(const char** argv); -int host_show_help(Session sess); -int host_tests(void); - -#endif -/** @} */ +/** + * \file host.h + * \brief Main executable API. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + * + * \defgroup host Host + * + * The "host" part of the application, which is responsible for parsing the command + * line arguments, and the overall flow of the application. + * + * @{ + */ +#if !defined(PREMAKE_HOST_H) +#define PREMAKE_HOST_H + +#include "session/session.h" + +/** + * The short help message, displayed if Premake is run with no arguments. + */ +#define HOST_SHORT_HELP "Type 'premake --help' for help." + + +/** + * Abstract out one step in the process, so I can treat them all identically. + * This lets me unit test the higher-level logic. + * \param sess The current session state. + * \returns OKAY if successful. + */ +typedef int (*HostExecutionStep)(Session sess); + + +int host_parse_argv(Session sess); +int host_report_results(Session sess); +int host_run_action(Session sess); +int host_run_script(Session sess); +int host_run_steps(Session sess, HostExecutionStep* steps); +void host_set_argv(const char** argv); +int host_show_help(Session sess); +int host_tests(void); + +#endif +/** @} */ diff --git a/src/host/tests/host_args_tests.cpp b/src/host/tests/host_args_tests.cpp index b13e970..8e47d5d 100644 --- a/src/host/tests/host_args_tests.cpp +++ b/src/host/tests/host_args_tests.cpp @@ -1,44 +1,44 @@ -/** - * \file host_args_tests.cpp - * \brief Automated tests for application command line argument processing. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "testing/testing.h" -extern "C" { -#include "host/host.h" -#include "base/error.h" -#include "base/stream.h" -} - -struct FxHostArgs -{ - Session sess; - char buffer[8192]; - - FxHostArgs() - { - sess = session_create(); - stream_set_buffer(Console, buffer); - } - - ~FxHostArgs() - { - session_destroy(sess); - error_clear(); - host_set_argv(NULL); - } -}; - - -SUITE(host) -{ - TEST_FIXTURE(FxHostArgs, ParseArgv_SetsAction_OnAction) - { - const char* argv[] = { "premake", "action", NULL }; - host_set_argv(argv); - host_parse_argv(sess); - CHECK_EQUAL("action", session_get_action(sess)); - } -} +/** + * \file host_args_tests.cpp + * \brief Automated tests for application command line argument processing. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "testing/testing.h" +extern "C" { +#include "host/host.h" +#include "base/error.h" +#include "base/stream.h" +} + +struct FxHostArgs +{ + Session sess; + char buffer[8192]; + + FxHostArgs() + { + sess = session_create(); + stream_set_buffer(Console, buffer); + } + + ~FxHostArgs() + { + session_destroy(sess); + error_clear(); + host_set_argv(NULL); + } +}; + + +SUITE(host) +{ + TEST_FIXTURE(FxHostArgs, ParseArgv_SetsAction_OnAction) + { + const char* argv[] = { "premake", "action", NULL }; + host_set_argv(argv); + host_parse_argv(sess); + CHECK_EQUAL("action", session_get_action(sess)); + } +} diff --git a/src/host/tests/host_help_tests.cpp b/src/host/tests/host_help_tests.cpp index 8e81525..20fd77e 100644 --- a/src/host/tests/host_help_tests.cpp +++ b/src/host/tests/host_help_tests.cpp @@ -1,77 +1,77 @@ -/** - * \file host_help_tests.cpp - * \brief Automated test for application help and version display. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "testing/testing.h" -extern "C" { -#include "host/host.h" -#include "base/error.h" -#include "base/stream.h" -} - -struct FxHostHelp -{ - Session sess; - char buffer[8192]; - - FxHostHelp() - { - sess = session_create(); - stream_set_buffer(Console, buffer); - } - - ~FxHostHelp() - { - session_destroy(sess); - error_clear(); - host_set_argv(NULL); - } -}; - - -SUITE(host) -{ - /********************************************************************** - * Do nothing if an action is set. - **********************************************************************/ - - TEST_FIXTURE(FxHostHelp, Help_ReturnsOkay_OnAction) - { - const char* argv[] = { "premake", "vs2005", NULL }; - host_set_argv(argv); - int result = host_show_help(sess); - CHECK(result == OKAY); - } - - TEST_FIXTURE(FxHostHelp, Help_PrintsNothing_OnAction) - { - const char* argv[] = { "premake", "vs2005", NULL }; - host_set_argv(argv); - host_show_help(sess); - CHECK_EQUAL("", buffer); - } - - - /********************************************************************** - * Should display short help (and end loop) if there is no action set. - **********************************************************************/ - - TEST_FIXTURE(FxHostHelp, Help_ReturnsNotOkay_OnNoAction) - { - const char* argv[] = { "premake", NULL }; - host_set_argv(argv); - int result = host_show_help(sess); - CHECK(result != OKAY); - } - - TEST_FIXTURE(FxHostHelp, Help_ShowsShortHelp_OnNoAction) - { - const char* argv[] = { "premake", NULL }; - host_set_argv(argv); - host_show_help(sess); - CHECK_EQUAL(HOST_SHORT_HELP "\n", buffer); - } -} +/** + * \file host_help_tests.cpp + * \brief Automated test for application help and version display. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "testing/testing.h" +extern "C" { +#include "host/host.h" +#include "base/error.h" +#include "base/stream.h" +} + +struct FxHostHelp +{ + Session sess; + char buffer[8192]; + + FxHostHelp() + { + sess = session_create(); + stream_set_buffer(Console, buffer); + } + + ~FxHostHelp() + { + session_destroy(sess); + error_clear(); + host_set_argv(NULL); + } +}; + + +SUITE(host) +{ + /********************************************************************** + * Do nothing if an action is set. + **********************************************************************/ + + TEST_FIXTURE(FxHostHelp, Help_ReturnsOkay_OnAction) + { + const char* argv[] = { "premake", "vs2005", NULL }; + host_set_argv(argv); + int result = host_show_help(sess); + CHECK(result == OKAY); + } + + TEST_FIXTURE(FxHostHelp, Help_PrintsNothing_OnAction) + { + const char* argv[] = { "premake", "vs2005", NULL }; + host_set_argv(argv); + host_show_help(sess); + CHECK_EQUAL("", buffer); + } + + + /********************************************************************** + * Should display short help (and end loop) if there is no action set. + **********************************************************************/ + + TEST_FIXTURE(FxHostHelp, Help_ReturnsNotOkay_OnNoAction) + { + const char* argv[] = { "premake", NULL }; + host_set_argv(argv); + int result = host_show_help(sess); + CHECK(result != OKAY); + } + + TEST_FIXTURE(FxHostHelp, Help_ShowsShortHelp_OnNoAction) + { + const char* argv[] = { "premake", NULL }; + host_set_argv(argv); + host_show_help(sess); + CHECK_EQUAL(HOST_SHORT_HELP "\n", buffer); + } +} diff --git a/src/host/tests/host_results_tests.cpp b/src/host/tests/host_results_tests.cpp index ba646fc..64ca4e1 100644 --- a/src/host/tests/host_results_tests.cpp +++ b/src/host/tests/host_results_tests.cpp @@ -1,48 +1,48 @@ -/** - * \file host_results_tests.cpp - * \brief Automated test for application status reporting. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "testing/testing.h" -extern "C" { -#include "host/host.h" -#include "base/error.h" -#include "base/stream.h" -} - -struct FxResults -{ - Session sess; - char buffer[1024]; - - FxResults() - { - sess = session_create(); - stream_set_buffer(Console, buffer); - } - - ~FxResults() - { - session_destroy(sess); - error_clear(); - } -}; - - -SUITE(host) -{ - TEST_FIXTURE(FxResults, ReportResults_NoMessage_OnNoError) - { - host_report_results(sess); - CHECK_EQUAL("", buffer); - } - - TEST_FIXTURE(FxResults, ReportResults_ErrorMessage_OnError) - { - error_set("an error occurred"); - host_report_results(sess); - CHECK_EQUAL("Error: an error occurred\n", buffer); - } -} +/** + * \file host_results_tests.cpp + * \brief Automated test for application status reporting. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "testing/testing.h" +extern "C" { +#include "host/host.h" +#include "base/error.h" +#include "base/stream.h" +} + +struct FxResults +{ + Session sess; + char buffer[1024]; + + FxResults() + { + sess = session_create(); + stream_set_buffer(Console, buffer); + } + + ~FxResults() + { + session_destroy(sess); + error_clear(); + } +}; + + +SUITE(host) +{ + TEST_FIXTURE(FxResults, ReportResults_NoMessage_OnNoError) + { + host_report_results(sess); + CHECK_EQUAL("", buffer); + } + + TEST_FIXTURE(FxResults, ReportResults_ErrorMessage_OnError) + { + error_set("an error occurred"); + host_report_results(sess); + CHECK_EQUAL("Error: an error occurred\n", buffer); + } +} diff --git a/src/host/tests/host_run_tests.cpp b/src/host/tests/host_run_tests.cpp index 338b62f..f3635d8 100644 --- a/src/host/tests/host_run_tests.cpp +++ b/src/host/tests/host_run_tests.cpp @@ -1,125 +1,125 @@ -/** - * \file host_run_tests.cpp - * \brief Automated test for the host script execution logic. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "testing/testing.h" -extern "C" { -#include "host/host.h" -#include "base/dir.h" -#include "base/error.h" -} - -/* Mock steps for testing host_run_steps */ - -static int num_step_calls; - -static int MockStepOkay(Session sess) -{ - sess = 0; - num_step_calls++; - return OKAY; -} - -static int MockStepFail(Session sess) -{ - sess = 0; - return !OKAY; -} - - -struct FxHostRun -{ - Session sess; - - FxHostRun() - { - num_step_calls = 0; - sess = session_create(); - dir_set_current("testing/test_files"); - } - - ~FxHostRun() - { - dir_set_current("../.."); - session_destroy(sess); - error_clear(); - } -}; - -SUITE(host) -{ - /********************************************************************** - * host_run_script() tests - **********************************************************************/ - - TEST_FIXTURE(FxHostRun, HostRunScript_ReturnsOkay_OnSuccess) - { - int result = host_run_script(sess); - CHECK(result == OKAY); - } - - TEST_FIXTURE(FxHostRun, HostRunScript_RunsDefaultFile_OnNoFileArg) - { - host_run_script(sess); - const char* result = session_run_string(sess, - "return script_has_run"); - CHECK_EQUAL("true", result); - } - - - /********************************************************************** - * host_run_steps() tests - **********************************************************************/ - - TEST_FIXTURE(FxHostRun, HostRunSteps_ReturnsOkay_OnAllStepsSucceed) - { - HostExecutionStep steps[] = { MockStepOkay, NULL }; - int result = host_run_steps(sess, steps); - CHECK(result == OKAY); - } - - TEST_FIXTURE(FxHostRun, HostRunSteps_RunsAllSteps) - { - HostExecutionStep steps[] = { MockStepOkay, MockStepOkay, MockStepOkay, NULL }; - host_run_steps(sess, steps); - CHECK(num_step_calls == 3); - } - - TEST_FIXTURE(FxHostRun, HostRunSteps_ReturnsNotOkay_OnError) - { - HostExecutionStep steps[] = { MockStepFail, NULL }; - int result = host_run_steps(sess, steps); - CHECK(result != OKAY); - } - - TEST_FIXTURE(FxHostRun, HostRunSteps_StopsRunning_OnError) - { - HostExecutionStep steps[] = { MockStepOkay, MockStepFail, MockStepOkay, NULL }; - host_run_steps(sess, steps); - CHECK(num_step_calls == 1); - } - - - /********************************************************************** - * host_run_action() tests - **********************************************************************/ - - TEST_FIXTURE(FxHostRun, HostRunAction_ReturnsNotOkay_OnInvalidAction) - { - const char* argv[] = { "premake", "nonesuch", NULL }; - host_set_argv(argv); - int result = host_run_action(sess); - CHECK(result != OKAY); - } - - TEST_FIXTURE(FxHostRun, HostRunAction_SetsError_OnInvalidAction) - { - const char* argv[] = { "premake", "nonesuch", NULL }; - host_set_argv(argv); - host_run_action(sess); - CHECK_EQUAL("invalid action 'nonesuch'", error_get()); - } -} +/** + * \file host_run_tests.cpp + * \brief Automated test for the host script execution logic. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "testing/testing.h" +extern "C" { +#include "host/host.h" +#include "base/dir.h" +#include "base/error.h" +} + +/* Mock steps for testing host_run_steps */ + +static int num_step_calls; + +static int MockStepOkay(Session sess) +{ + sess = 0; + num_step_calls++; + return OKAY; +} + +static int MockStepFail(Session sess) +{ + sess = 0; + return !OKAY; +} + + +struct FxHostRun +{ + Session sess; + + FxHostRun() + { + num_step_calls = 0; + sess = session_create(); + dir_set_current("testing/test_files"); + } + + ~FxHostRun() + { + dir_set_current("../.."); + session_destroy(sess); + error_clear(); + } +}; + +SUITE(host) +{ + /********************************************************************** + * host_run_script() tests + **********************************************************************/ + + TEST_FIXTURE(FxHostRun, HostRunScript_ReturnsOkay_OnSuccess) + { + int result = host_run_script(sess); + CHECK(result == OKAY); + } + + TEST_FIXTURE(FxHostRun, HostRunScript_RunsDefaultFile_OnNoFileArg) + { + host_run_script(sess); + const char* result = session_run_string(sess, + "return script_has_run"); + CHECK_EQUAL("true", result); + } + + + /********************************************************************** + * host_run_steps() tests + **********************************************************************/ + + TEST_FIXTURE(FxHostRun, HostRunSteps_ReturnsOkay_OnAllStepsSucceed) + { + HostExecutionStep steps[] = { MockStepOkay, NULL }; + int result = host_run_steps(sess, steps); + CHECK(result == OKAY); + } + + TEST_FIXTURE(FxHostRun, HostRunSteps_RunsAllSteps) + { + HostExecutionStep steps[] = { MockStepOkay, MockStepOkay, MockStepOkay, NULL }; + host_run_steps(sess, steps); + CHECK(num_step_calls == 3); + } + + TEST_FIXTURE(FxHostRun, HostRunSteps_ReturnsNotOkay_OnError) + { + HostExecutionStep steps[] = { MockStepFail, NULL }; + int result = host_run_steps(sess, steps); + CHECK(result != OKAY); + } + + TEST_FIXTURE(FxHostRun, HostRunSteps_StopsRunning_OnError) + { + HostExecutionStep steps[] = { MockStepOkay, MockStepFail, MockStepOkay, NULL }; + host_run_steps(sess, steps); + CHECK(num_step_calls == 1); + } + + + /********************************************************************** + * host_run_action() tests + **********************************************************************/ + + TEST_FIXTURE(FxHostRun, HostRunAction_ReturnsNotOkay_OnInvalidAction) + { + const char* argv[] = { "premake", "nonesuch", NULL }; + host_set_argv(argv); + int result = host_run_action(sess); + CHECK(result != OKAY); + } + + TEST_FIXTURE(FxHostRun, HostRunAction_SetsError_OnInvalidAction) + { + const char* argv[] = { "premake", "nonesuch", NULL }; + host_set_argv(argv); + host_run_action(sess); + CHECK_EQUAL("invalid action 'nonesuch'", error_get()); + } +} diff --git a/src/host/tests/host_tests.cpp b/src/host/tests/host_tests.cpp index 18d6a7a..6b3535c 100644 --- a/src/host/tests/host_tests.cpp +++ b/src/host/tests/host_tests.cpp @@ -1,26 +1,26 @@ -/** - * \file host_tests.cpp - * \brief Main executable automated tests. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "testing/testing.h" -extern "C" { -#include "host/host.h" -} - - -/** - * Run the automated host tests. - * \returns OKAY if all tests completed successfully. - * \note Also runs the tests for all dependencies, which for the host is everything. - */ -int host_tests() -{ - int z = OKAY; - if (z == OKAY) z = session_tests(); - if (z == OKAY) z = tests_run_suite("action"); - if (z == OKAY) z = tests_run_suite("host"); - return z; -} +/** + * \file host_tests.cpp + * \brief Main executable automated tests. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "testing/testing.h" +extern "C" { +#include "host/host.h" +} + + +/** + * Run the automated host tests. + * \returns OKAY if all tests completed successfully. + * \note Also runs the tests for all dependencies, which for the host is everything. + */ +int host_tests() +{ + int z = OKAY; + if (z == OKAY) z = session_tests(); + if (z == OKAY) z = tests_run_suite("action"); + if (z == OKAY) z = tests_run_suite("host"); + return z; +} diff --git a/src/platform/platform.c b/src/platform/platform.c index cf20a3a..a98987c 100644 --- a/src/platform/platform.c +++ b/src/platform/platform.c @@ -1,34 +1,34 @@ -/** - * \file platform.c - * \brief Platform abstraction API. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "platform.h" - -static enum Platform CurrentPlatform = Unknown; - - -enum Platform platform_get() -{ - if (CurrentPlatform == Unknown) - { -#if defined(PLATFORM_BSD) - CurrentPlatform = BSD; -#elif defined(PLATFORM_LINUX) - CurrentPlatform = Linux; -#elif defined(PLATFORM_MACOSX) - CurrentPlatform = MacOSX; -#else - CurrentPlatform = Windows; -#endif - } - return CurrentPlatform; -} - - -void platform_set(enum Platform id) -{ - CurrentPlatform = id; -} +/** + * \file platform.c + * \brief Platform abstraction API. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "platform.h" + +static enum Platform CurrentPlatform = Unknown; + + +enum Platform platform_get() +{ + if (CurrentPlatform == Unknown) + { +#if defined(PLATFORM_BSD) + CurrentPlatform = BSD; +#elif defined(PLATFORM_LINUX) + CurrentPlatform = Linux; +#elif defined(PLATFORM_MACOSX) + CurrentPlatform = MacOSX; +#else + CurrentPlatform = Windows; +#endif + } + return CurrentPlatform; +} + + +void platform_set(enum Platform id) +{ + CurrentPlatform = id; +} diff --git a/src/platform/platform.h b/src/platform/platform.h index 64eccc0..d899401 100644 --- a/src/platform/platform.h +++ b/src/platform/platform.h @@ -1,121 +1,121 @@ -/** - * \file platform.h - * \brief Platform abstraction API. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - * - * \defgroup platform Platform - * - * Platform abstraction; primarily file system and directory management. - * - * @{ - */ -#if !defined(PREMAKE_PLATFORM_H) -#define PREMAKE_PLATFORM_H - - -/** - * The currently support platforms. If you add to this list be sure to - * also update the platform detection logic below, and the platform - * identifier initialization in platform.c. - */ -enum Platform -{ - Unknown, - BSD, - Linux, - MacOSX, - Windows -}; - - -#if defined(__linux__) -#define PLATFORM_LINUX (1) -#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) -#define PLATFORM_BSD (1) -#elif defined(__APPLE__) && defined(__MACH__) -#define PLATFORM_MACOSX (1) -#else -#define PLATFORM_WINDOWS (1) -#endif - -DECLARE_CLASS(PlatformSearch) - - -/** - * Create a directory, if it doesn't exist already. - * \returns OKAY if successful. - */ -int platform_create_dir(const char* path); - - -/** - * Create a GUID and copy it into the supplied buffer. - * \param buffer The buffer to hold the new GUID; must hold at least 36 characters. - */ -void platform_create_guid(char* buffer); - - -/** - * Get the current working directory. - * \param buffer A buffer to hold the directory. - * \param size The size of the buffer. - * \returns OKAY if successful. - */ -int platform_dir_get_current(char* buffer, int size); - - -/** - * Set the current working directory. - * \param path The new working directory. - * \returns OKAY if successful. - */ -int platform_dir_set_current(const char* path); - - -/** - * Retrieve the current platform identifier. - */ -enum Platform platform_get(void); - - -/** - * Create a new platform file search context. - */ -PlatformSearch platform_search_create(const char* mask); - - -/** - * Destroy a platform search context. - */ -void platform_search_destroy(PlatformSearch search); - - -/** - * Retrieve the name of the current match in the search. - */ -const char* platform_search_get_name(PlatformSearch search); - - -/** - * Determine if the current match is a file or a directory. - */ -int platform_search_is_file(PlatformSearch search); - - -/** - * Retrieve the next match in a file system search. - * \returns True if another match is available. - */ -int platform_search_next(PlatformSearch search); - - -/** - * Set the platform identification string, forcing a platform-specific - * behavior regardless of the actual current platform. - * \param id One of the platform identifiers. - */ -void platform_set(enum Platform id); - - -#endif -/** @} */ +/** + * \file platform.h + * \brief Platform abstraction API. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + * + * \defgroup platform Platform + * + * Platform abstraction; primarily file system and directory management. + * + * @{ + */ +#if !defined(PREMAKE_PLATFORM_H) +#define PREMAKE_PLATFORM_H + + +/** + * The currently support platforms. If you add to this list be sure to + * also update the platform detection logic below, and the platform + * identifier initialization in platform.c. + */ +enum Platform +{ + Unknown, + BSD, + Linux, + MacOSX, + Windows +}; + + +#if defined(__linux__) +#define PLATFORM_LINUX (1) +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +#define PLATFORM_BSD (1) +#elif defined(__APPLE__) && defined(__MACH__) +#define PLATFORM_MACOSX (1) +#else +#define PLATFORM_WINDOWS (1) +#endif + +DECLARE_CLASS(PlatformSearch) + + +/** + * Create a directory, if it doesn't exist already. + * \returns OKAY if successful. + */ +int platform_create_dir(const char* path); + + +/** + * Create a GUID and copy it into the supplied buffer. + * \param buffer The buffer to hold the new GUID; must hold at least 36 characters. + */ +void platform_create_guid(char* buffer); + + +/** + * Get the current working directory. + * \param buffer A buffer to hold the directory. + * \param size The size of the buffer. + * \returns OKAY if successful. + */ +int platform_dir_get_current(char* buffer, int size); + + +/** + * Set the current working directory. + * \param path The new working directory. + * \returns OKAY if successful. + */ +int platform_dir_set_current(const char* path); + + +/** + * Retrieve the current platform identifier. + */ +enum Platform platform_get(void); + + +/** + * Create a new platform file search context. + */ +PlatformSearch platform_search_create(const char* mask); + + +/** + * Destroy a platform search context. + */ +void platform_search_destroy(PlatformSearch search); + + +/** + * Retrieve the name of the current match in the search. + */ +const char* platform_search_get_name(PlatformSearch search); + + +/** + * Determine if the current match is a file or a directory. + */ +int platform_search_is_file(PlatformSearch search); + + +/** + * Retrieve the next match in a file system search. + * \returns True if another match is available. + */ +int platform_search_next(PlatformSearch search); + + +/** + * Set the platform identification string, forcing a platform-specific + * behavior regardless of the actual current platform. + * \param id One of the platform identifiers. + */ +void platform_set(enum Platform id); + + +#endif +/** @} */ diff --git a/src/platform/posix.c b/src/platform/posix.c index 5f595fe..e1cecf1 100644 --- a/src/platform/posix.c +++ b/src/platform/posix.c @@ -1,136 +1,136 @@ -/** - * \file posix.c - * \brief POSIX implementation of Premake platform abstraction. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "platform/platform.h" -#include "base/path.h" -#include "base/string.h" - -#if !defined(PLATFORM_WINDOWS) - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -DEFINE_CLASS(PlatformSearch) -{ - String directory; - String mask; - DIR* handle; - struct dirent* entry; -}; - - -int platform_create_dir(const char* path) -{ - return mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); -} - - -void platform_create_guid(char* buffer) -{ - /* not sure how to get a UUID here, so I fake it */ - FILE* rnd = fopen("/dev/random", "rb"); - fread(buffer, 16, 1, rnd); - fclose(rnd); -} - - -int platform_dir_get_current(char* buffer, int size) -{ - char* result = getcwd(buffer, size); - return (result != NULL) ? OKAY : !OKAY; -} - - -int platform_dir_set_current(const char* path) -{ - return chdir(path); -} - - -PlatformSearch platform_search_create(const char* mask) -{ - PlatformSearch search; - const char* dir; - - dir = path_directory(mask); - mask = path_filename(mask); - if (strlen(dir) == 0) - { - dir = "."; - } - - search = ALLOC_CLASS(PlatformSearch); - search->directory = string_create(dir); - search->mask = string_create(mask); - search->handle = opendir(dir); - search->entry = NULL; - return search; -} - - -void platform_search_destroy(PlatformSearch search) -{ - if (search->handle != NULL) - { - closedir(search->handle); - } - free(search); -} - - -const char* platform_search_get_name(PlatformSearch search) -{ - return search->entry->d_name; -} - - -int platform_search_is_file(PlatformSearch search) -{ - struct stat info; - - const char* dir = string_cstr(search->directory); - const char* path = path_join(dir, search->entry->d_name); - if (stat(path, &info) == 0) - { - return S_ISREG(info.st_mode); - } - - return 0; -} - - -int platform_search_next(PlatformSearch search) -{ - const char* mask = string_cstr(search->mask); - - if (search->handle == NULL) - { - return 0; - } - - search->entry = readdir(search->handle); - while (search->entry != NULL) - { - if (fnmatch(mask, search->entry->d_name, 0) == 0) - { - return 1; - } - search->entry = readdir(search->handle); - } - - return 0; -} - -#endif - +/** + * \file posix.c + * \brief POSIX implementation of Premake platform abstraction. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "platform/platform.h" +#include "base/path.h" +#include "base/string.h" + +#if !defined(PLATFORM_WINDOWS) + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DEFINE_CLASS(PlatformSearch) +{ + String directory; + String mask; + DIR* handle; + struct dirent* entry; +}; + + +int platform_create_dir(const char* path) +{ + return mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); +} + + +void platform_create_guid(char* buffer) +{ + /* not sure how to get a UUID here, so I fake it */ + FILE* rnd = fopen("/dev/random", "rb"); + fread(buffer, 16, 1, rnd); + fclose(rnd); +} + + +int platform_dir_get_current(char* buffer, int size) +{ + char* result = getcwd(buffer, size); + return (result != NULL) ? OKAY : !OKAY; +} + + +int platform_dir_set_current(const char* path) +{ + return chdir(path); +} + + +PlatformSearch platform_search_create(const char* mask) +{ + PlatformSearch search; + const char* dir; + + dir = path_directory(mask); + mask = path_filename(mask); + if (strlen(dir) == 0) + { + dir = "."; + } + + search = ALLOC_CLASS(PlatformSearch); + search->directory = string_create(dir); + search->mask = string_create(mask); + search->handle = opendir(dir); + search->entry = NULL; + return search; +} + + +void platform_search_destroy(PlatformSearch search) +{ + if (search->handle != NULL) + { + closedir(search->handle); + } + free(search); +} + + +const char* platform_search_get_name(PlatformSearch search) +{ + return search->entry->d_name; +} + + +int platform_search_is_file(PlatformSearch search) +{ + struct stat info; + + const char* dir = string_cstr(search->directory); + const char* path = path_join(dir, search->entry->d_name); + if (stat(path, &info) == 0) + { + return S_ISREG(info.st_mode); + } + + return 0; +} + + +int platform_search_next(PlatformSearch search) +{ + const char* mask = string_cstr(search->mask); + + if (search->handle == NULL) + { + return 0; + } + + search->entry = readdir(search->handle); + while (search->entry != NULL) + { + if (fnmatch(mask, search->entry->d_name, 0) == 0) + { + return 1; + } + search->entry = readdir(search->handle); + } + + return 0; +} + +#endif + diff --git a/src/platform/windows.c b/src/platform/windows.c index 40de7c6..1a1ae6d 100644 --- a/src/platform/windows.c +++ b/src/platform/windows.c @@ -1,105 +1,105 @@ -/** - * \file windows.c - * \brief Windows implementation of Premake platform abstraction. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include -#include "premake.h" -#include "platform/platform.h" -#if defined(PLATFORM_WINDOWS) - -#define WIN32_LEAN_AND_MEAN -#include - - -DEFINE_CLASS(PlatformSearch) -{ - HANDLE handle; - int is_first; - WIN32_FIND_DATA entry; -}; - - -int platform_create_dir(const char* path) -{ - return CreateDirectory(path, NULL) ? OKAY : !OKAY; -} - - -void platform_create_guid(char* buffer) -{ - static int (__stdcall *CoCreateGuid)(char*) = NULL; - if (CoCreateGuid == NULL) - { - HMODULE hOleDll = LoadLibrary("OLE32.DLL"); - CoCreateGuid = (int(__stdcall*)(char*))GetProcAddress(hOleDll, "CoCreateGuid"); - } - CoCreateGuid(buffer); -} - - -int platform_dir_get_current(char* buffer, int size) -{ - DWORD result = GetCurrentDirectory(size, buffer); - return (result != 0) ? OKAY : !OKAY; -} - - -int platform_dir_set_current(const char* path) -{ - DWORD result = SetCurrentDirectory(path); - return (result != 0) ? OKAY : !OKAY; -} - - -PlatformSearch platform_search_create(const char* mask) -{ - PlatformSearch search = ALLOC_CLASS(PlatformSearch); - search->handle = FindFirstFile(mask, &search->entry); - search->is_first = 1; - return search; -} - - -void platform_search_destroy(PlatformSearch search) -{ - if (search->handle != INVALID_HANDLE_VALUE) - { - FindClose(search->handle); - } - free(search); -} - - -const char* platform_search_get_name(PlatformSearch search) -{ - return search->entry.cFileName; -} - - -int platform_search_is_file(PlatformSearch search) -{ - return (search->entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0; -} - - -int platform_search_next(PlatformSearch search) -{ - if (search->handle == INVALID_HANDLE_VALUE) - { - return 0; - } - - if (search->is_first) - { - search->is_first = 0; - return 1; - } - else - { - return FindNextFile(search->handle, &search->entry); - } -} - -#endif +/** + * \file windows.c + * \brief Windows implementation of Premake platform abstraction. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include +#include "premake.h" +#include "platform/platform.h" +#if defined(PLATFORM_WINDOWS) + +#define WIN32_LEAN_AND_MEAN +#include + + +DEFINE_CLASS(PlatformSearch) +{ + HANDLE handle; + int is_first; + WIN32_FIND_DATA entry; +}; + + +int platform_create_dir(const char* path) +{ + return CreateDirectory(path, NULL) ? OKAY : !OKAY; +} + + +void platform_create_guid(char* buffer) +{ + static int (__stdcall *CoCreateGuid)(char*) = NULL; + if (CoCreateGuid == NULL) + { + HMODULE hOleDll = LoadLibrary("OLE32.DLL"); + CoCreateGuid = (int(__stdcall*)(char*))GetProcAddress(hOleDll, "CoCreateGuid"); + } + CoCreateGuid(buffer); +} + + +int platform_dir_get_current(char* buffer, int size) +{ + DWORD result = GetCurrentDirectory(size, buffer); + return (result != 0) ? OKAY : !OKAY; +} + + +int platform_dir_set_current(const char* path) +{ + DWORD result = SetCurrentDirectory(path); + return (result != 0) ? OKAY : !OKAY; +} + + +PlatformSearch platform_search_create(const char* mask) +{ + PlatformSearch search = ALLOC_CLASS(PlatformSearch); + search->handle = FindFirstFile(mask, &search->entry); + search->is_first = 1; + return search; +} + + +void platform_search_destroy(PlatformSearch search) +{ + if (search->handle != INVALID_HANDLE_VALUE) + { + FindClose(search->handle); + } + free(search); +} + + +const char* platform_search_get_name(PlatformSearch search) +{ + return search->entry.cFileName; +} + + +int platform_search_is_file(PlatformSearch search) +{ + return (search->entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0; +} + + +int platform_search_next(PlatformSearch search) +{ + if (search->handle == INVALID_HANDLE_VALUE) + { + return 0; + } + + if (search->is_first) + { + search->is_first = 0; + return 1; + } + else + { + return FindNextFile(search->handle, &search->entry); + } +} + +#endif diff --git a/src/premake.c b/src/premake.c index 084471f..8c57761 100644 --- a/src/premake.c +++ b/src/premake.c @@ -1,58 +1,58 @@ -/** - * \file premake.c - * \brief Program entry point. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include -#include "premake.h" -#include "host/host.h" -#include "action/action.h" - - -/** - * These are the steps in the process; each function runs one part of the whole. - */ -static HostExecutionStep Steps[] = -{ - host_parse_argv, /* process the command line arguments */ - host_run_script, /* run the main script (i.e. premake4.lua) */ - session_unload, /* unload the objects built by the script into more accessible C data structures */ - host_show_help, /* show help and version messages as appropriate; may end processing here */ - host_run_action, /* run the action specified on the command line */ - NULL /* all done! */ -}; - - -/** - * \brief Program entry point. - */ -int main(int argc, const char** argv) -{ - Session sess; - - /* If testing is enabled, calling premake.exe with no arguments will - * trigger a call to the automated tests. This is used by a post-build - * step to run the tests after every successful build. */ -#if defined(TESTING_ENABLED) - if (argc == 1) - { - return host_tests(); - } -#else - UNUSED(argc); -#endif - - /* initialize */ - host_set_argv(argv); - sess = session_create(); - - /* run */ - host_run_steps(sess, Steps); - - /* report back to the user and clean up */ - host_report_results(sess); - session_destroy(sess); - return OKAY; -} - +/** + * \file premake.c + * \brief Program entry point. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include +#include "premake.h" +#include "host/host.h" +#include "action/action.h" + + +/** + * These are the steps in the process; each function runs one part of the whole. + */ +static HostExecutionStep Steps[] = +{ + host_parse_argv, /* process the command line arguments */ + host_run_script, /* run the main script (i.e. premake4.lua) */ + session_unload, /* unload the objects built by the script into more accessible C data structures */ + host_show_help, /* show help and version messages as appropriate; may end processing here */ + host_run_action, /* run the action specified on the command line */ + NULL /* all done! */ +}; + + +/** + * \brief Program entry point. + */ +int main(int argc, const char** argv) +{ + Session sess; + + /* If testing is enabled, calling premake.exe with no arguments will + * trigger a call to the automated tests. This is used by a post-build + * step to run the tests after every successful build. */ +#if defined(TESTING_ENABLED) + if (argc == 1) + { + return host_tests(); + } +#else + UNUSED(argc); +#endif + + /* initialize */ + host_set_argv(argv); + sess = session_create(); + + /* run */ + host_run_steps(sess, Steps); + + /* report back to the user and clean up */ + host_report_results(sess); + session_destroy(sess); + return OKAY; +} + diff --git a/src/premake.h b/src/premake.h index 88f09ef..c5adb88 100644 --- a/src/premake.h +++ b/src/premake.h @@ -1,43 +1,43 @@ -/** - * \file premake.h - * \brief Global program definitions. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - - -/** - * The default filename for Premake scripts. - */ -#define DEFAULT_SCRIPT_NAME "premake4.lua" - - -/** - * The success return code; the symbol avoids confusion about zero == false. - */ -#define OKAY (0) - - -/** - * Macro to declare new "classes" - just opaque struct pointers. The macro - * ensures that they all get defined consistently. - */ -#define DECLARE_CLASS(n) typedef struct n##_impl* n; - - -/** - * Macro to define new "classes" - just structs with a special name. - */ -#define DEFINE_CLASS(n) struct n##_impl - - -/** - * Macro to allocate memory for a "class" - just a struct with a special name. - */ -#define ALLOC_CLASS(n) (n)malloc(sizeof(struct n##_impl)) - - -/** - * Mark a variable as unused, so the compiler won't complain about it. I suspect - * there is a better way to do this. - */ -#define UNUSED(var) var = 0 +/** + * \file premake.h + * \brief Global program definitions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + + +/** + * The default filename for Premake scripts. + */ +#define DEFAULT_SCRIPT_NAME "premake4.lua" + + +/** + * The success return code; the symbol avoids confusion about zero == false. + */ +#define OKAY (0) + + +/** + * Macro to declare new "classes" - just opaque struct pointers. The macro + * ensures that they all get defined consistently. + */ +#define DECLARE_CLASS(n) typedef struct n##_impl* n; + + +/** + * Macro to define new "classes" - just structs with a special name. + */ +#define DEFINE_CLASS(n) struct n##_impl + + +/** + * Macro to allocate memory for a "class" - just a struct with a special name. + */ +#define ALLOC_CLASS(n) (n)malloc(sizeof(struct n##_impl)) + + +/** + * Mark a variable as unused, so the compiler won't complain about it. I suspect + * there is a better way to do this. + */ +#define UNUSED(var) var = 0 diff --git a/src/premake.lua b/src/premake.lua index 16062c1..0754881 100644 --- a/src/premake.lua +++ b/src/premake.lua @@ -1,101 +1,101 @@ -package.name = "Premake" -package.target = "premake4" -package.language = "c" -package.kind = "exe" - -local subsystems = -{ - "platform", - "base", - "project", - "action", - "action/make", - "action/vs200x", - "script", - "session", - "host" -} - - --- Build settings - - package.buildflags = - { - "no-64bit-checks", - "extra-warnings", - "fatal-warnings" - } - - package.config["Debug"].defines = - { - "_DEBUG" - } - - package.config["Release"].buildflags = - { - "no-symbols", - "optimize-size", - "no-frame-pointers" - } - - package.config["Release"].defines = - { - "NDEBUG" - } - - package.defines = - { - "_CRT_SECURE_NO_WARNINGS" - } - - package.includepaths = - { - "." - } - - --- Files - - package.files = matchfiles("*.h", "*.c") - for k,m in subsystems do - table.insert(package.files, matchfiles(m.."/*.h", m.."/*.c")) - end - - --- Lua scripting engine - - local lua = "script/lua-5.1.2/src" - table.insert(package.includepaths, lua) - table.insert(package.files, matchfiles(lua.."/*.h", lua.."/*.c")) - table.insert(package.excludes, {lua.."/lua.c", lua.."/luac.c"}) - - --- Automated tests - - if (not options["no-tests"]) then - local unittest = "testing/UnitTest++/src" - - -- UnitTest++ is a C++ system - package.language = "c++" - - -- Define a symbol so I can compile in the testing calls - table.insert(package.defines, "TESTING_ENABLED") - - table.insert(package.files, matchfiles("testing/*.h", "testing/*.cpp", unittest.."/*")) - - for k,m in subsystems do - table.insert(package.files, matchfiles(m.."/tests/*.h", m.."/tests/*.cpp")) - end - - if (windows) then - table.insert(package.files, matchfiles(unittest.."/Win32/*")) - package.config["Debug"].postbuildcommands = { "..\\bin\\debug\\premake4.exe" } - package.config["Release"].postbuildcommands = { "..\\bin\\release\\premake4.exe" } - else - table.insert(package.files, matchfiles(unittest.."/Posix/*")) - package.config["Debug"].postbuildcommands = { "../bin/debug/premake4" } - package.config["Release"].postbuildcommands = { "../bin/release/premake4" } - end - - end - +package.name = "Premake" +package.target = "premake4" +package.language = "c" +package.kind = "exe" + +local subsystems = +{ + "platform", + "base", + "project", + "action", + "action/make", + "action/vs200x", + "script", + "session", + "host" +} + + +-- Build settings + + package.buildflags = + { + "no-64bit-checks", + "extra-warnings", + "fatal-warnings" + } + + package.config["Debug"].defines = + { + "_DEBUG" + } + + package.config["Release"].buildflags = + { + "no-symbols", + "optimize-size", + "no-frame-pointers" + } + + package.config["Release"].defines = + { + "NDEBUG" + } + + package.defines = + { + "_CRT_SECURE_NO_WARNINGS" + } + + package.includepaths = + { + "." + } + + +-- Files + + package.files = matchfiles("*.h", "*.c") + for k,m in subsystems do + table.insert(package.files, matchfiles(m.."/*.h", m.."/*.c")) + end + + +-- Lua scripting engine + + local lua = "script/lua-5.1.2/src" + table.insert(package.includepaths, lua) + table.insert(package.files, matchfiles(lua.."/*.h", lua.."/*.c")) + table.insert(package.excludes, {lua.."/lua.c", lua.."/luac.c"}) + + +-- Automated tests + + if (not options["no-tests"]) then + local unittest = "testing/UnitTest++/src" + + -- UnitTest++ is a C++ system + package.language = "c++" + + -- Define a symbol so I can compile in the testing calls + table.insert(package.defines, "TESTING_ENABLED") + + table.insert(package.files, matchfiles("testing/*.h", "testing/*.cpp", unittest.."/*")) + + for k,m in subsystems do + table.insert(package.files, matchfiles(m.."/tests/*.h", m.."/tests/*.cpp")) + end + + if (windows) then + table.insert(package.files, matchfiles(unittest.."/Win32/*")) + package.config["Debug"].postbuildcommands = { "..\\bin\\debug\\premake4.exe" } + package.config["Release"].postbuildcommands = { "..\\bin\\release\\premake4.exe" } + else + table.insert(package.files, matchfiles(unittest.."/Posix/*")) + package.config["Debug"].postbuildcommands = { "../bin/debug/premake4" } + package.config["Release"].postbuildcommands = { "../bin/release/premake4" } + end + + end + diff --git a/src/project/fields.c b/src/project/fields.c index 7c5c312..7ee178d 100644 --- a/src/project/fields.c +++ b/src/project/fields.c @@ -1,166 +1,166 @@ -/** - * \file fields.c - * \brief Project object fields enumeration and handling. - * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project - */ - -#include -#include -#include "premake.h" -#include "fields.h" -#include "base/strings.h" - - -DEFINE_CLASS(Fields) -{ - Strings* values; - int count; -}; - - -/** - * Create a new, empty collection of fields. - * \param info Metadata about the field collection. - * \returns A new collection of fields. - */ -Fields fields_create(struct FieldInfo* info) -{ - int i; - Fields fields; - - assert(info); - - fields = ALLOC_CLASS(Fields); - - /* figure out how many fields are in the collection */ - for (i = 0; info[i].name != NULL; ++i); - fields->count = i; - - /* initialize the values */ - fields->values = (Strings*)malloc(sizeof(Strings) * fields->count); - for (i = 0; i < fields->count; ++i) - { - fields->values[i] = strings_create(); - } - - return fields; -} - - -/** - * Destroy a collection of fields and release the associated memory. - * \param fields The collection of fields to destroy. - */ -void fields_destroy(Fields fields) -{ - int i; - - assert(fields); - - for (i = 0; i < fields->count; ++i) - { - strings_destroy(fields->values[i]); - } - free(fields->values); - free(fields); -} - - -/** - * Add a new value to the end of an existing list. - * \param fields The collection of fields. - * \param index The index of the list to contain the new value. - * \param value The value to add. - */ -void fields_add_value(Fields fields, int index, const char* value) -{ - assert(fields); - assert(index >= 0 && index < fields->count); - strings_add(fields->values[index], value); -} - - -/** - * Retrieve the value of a string (single value) field. - * \param fields The collection of fields. - * \param index The index of the field to query. - * \returns The field value if set, or NULL. - */ -const char* fields_get_value(Fields fields, int index) -{ - Strings values; - assert(fields); - assert(index >= 0 && index < fields->count); - - values = fields->values[index]; - if (strings_size(values) > 0) - { - return strings_item(values, 0); - } - else - { - return NULL; - } -} - - -/** - * Retrieve the list of values for a field. - * \param fields The collection of fields. - * \param index The index of fields to query. - * \returns The list of values stored in the field. - */ -Strings fields_get_values(Fields fields, int index) -{ - assert(fields); - assert(index >= 0 && index < fields->count); - return fields->values[index]; -} - - -/** - * Sets the value of a string (single value) field. - * \param fields The collection of fields. - * \param index The index of the field to set. - * \param value The new value of the field. - */ -void fields_set_value(Fields fields, int index, const char* value) -{ - Strings values; - - assert(fields); - assert(index >= 0 && index < fields->count); - assert(value); - - values = fields->values[index]; - if (strings_size(values) == 0) - { - strings_add(values, value); - } - else - { - strings_set(values, 0, value); - } -} - - -/** - * Sets the list of values associated with a field. The field will subsequently - * "own" the list, and take responsibility to destroying it with the field set. - * \param fields The collection of fields. - * \param index The index of the field to set. - * \param values The list of new values for the field. - */ -void fields_set_values(Fields fields, int index, Strings values) -{ - assert(fields); - assert(index >= 0 && index < fields->count); - assert(values); - - if (fields->values[index] != NULL) - { - strings_destroy(fields->values[index]); - } - - fields->values[index] = values; -} +/** + * \file fields.c + * \brief Project object fields enumeration and handling. + * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project + */ + +#include +#include +#include "premake.h" +#include "fields.h" +#include "base/strings.h" + + +DEFINE_CLASS(Fields) +{ + Strings* values; + int count; +}; + + +/** + * Create a new, empty collection of fields. + * \param info Metadata about the field collection. + * \returns A new collection of fields. + */ +Fields fields_create(struct FieldInfo* info) +{ + int i; + Fields fields; + + assert(info); + + fields = ALLOC_CLASS(Fields); + + /* figure out how many fields are in the collection */ + for (i = 0; info[i].name != NULL; ++i); + fields->count = i; + + /* initialize the values */ + fields->values = (Strings*)malloc(sizeof(Strings) * fields->count); + for (i = 0; i < fields->count; ++i) + { + fields->values[i] = strings_create(); + } + + return fields; +} + + +/** + * Destroy a collection of fields and release the associated memory. + * \param fields The collection of fields to destroy. + */ +void fields_destroy(Fields fields) +{ + int i; + + assert(fields); + + for (i = 0; i < fields->count; ++i) + { + strings_destroy(fields->values[i]); + } + free(fields->values); + free(fields); +} + + +/** + * Add a new value to the end of an existing list. + * \param fields The collection of fields. + * \param index The index of the list to contain the new value. + * \param value The value to add. + */ +void fields_add_value(Fields fields, int index, const char* value) +{ + assert(fields); + assert(index >= 0 && index < fields->count); + strings_add(fields->values[index], value); +} + + +/** + * Retrieve the value of a string (single value) field. + * \param fields The collection of fields. + * \param index The index of the field to query. + * \returns The field value if set, or NULL. + */ +const char* fields_get_value(Fields fields, int index) +{ + Strings values; + assert(fields); + assert(index >= 0 && index < fields->count); + + values = fields->values[index]; + if (strings_size(values) > 0) + { + return strings_item(values, 0); + } + else + { + return NULL; + } +} + + +/** + * Retrieve the list of values for a field. + * \param fields The collection of fields. + * \param index The index of fields to query. + * \returns The list of values stored in the field. + */ +Strings fields_get_values(Fields fields, int index) +{ + assert(fields); + assert(index >= 0 && index < fields->count); + return fields->values[index]; +} + + +/** + * Sets the value of a string (single value) field. + * \param fields The collection of fields. + * \param index The index of the field to set. + * \param value The new value of the field. + */ +void fields_set_value(Fields fields, int index, const char* value) +{ + Strings values; + + assert(fields); + assert(index >= 0 && index < fields->count); + assert(value); + + values = fields->values[index]; + if (strings_size(values) == 0) + { + strings_add(values, value); + } + else + { + strings_set(values, 0, value); + } +} + + +/** + * Sets the list of values associated with a field. The field will subsequently + * "own" the list, and take responsibility to destroying it with the field set. + * \param fields The collection of fields. + * \param index The index of the field to set. + * \param values The list of new values for the field. + */ +void fields_set_values(Fields fields, int index, Strings values) +{ + assert(fields); + assert(index >= 0 && index < fields->count); + assert(values); + + if (fields->values[index] != NULL) + { + strings_destroy(fields->values[index]); + } + + fields->values[index] = values; +} diff --git a/src/project/fields.h b/src/project/fields.h index 645d5fa..1f4f416 100644 --- a/src/project/fields.h +++ b/src/project/fields.h @@ -1,58 +1,58 @@ -/** - * \file fields.h - * \brief Project object fields enumeration and handling. - * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project - * - * \addtogroup project - * @{ - */ -#if !defined(PREMAKE_FIELDS_H) -#define PREMAKE_FIELDS_H - -#include "base/strings.h" - - -/** - * Field types. - */ -enum FieldKind -{ - StringField, - ListField, - FilesField -}; - - -/** - * Field validation function signature. - * \param value The value to validate. - * \returns True if the value is considered valid. - */ -typedef int (*FieldValidator)(const char* value); - - -/** - * Metadata about a project object field. - */ -struct FieldInfo -{ - const char* name; /**< The name of the field. */ - enum FieldKind kind; /**< StringField, ListField, etc. */ - FieldValidator validator; /**< The field validation function */ -}; - - -DECLARE_CLASS(Fields) - - -Fields fields_create(struct FieldInfo* info); -void fields_destroy(Fields fields); - -void fields_add_value(Fields fields, int index, const char* value); -const char* fields_get_value(Fields fields, int index); -Strings fields_get_values(Fields fields, int index); -void fields_set_value(Fields fields, int index, const char* value); -void fields_set_values(Fields fields, int index, Strings values); - -#endif -/* @} */ +/** + * \file fields.h + * \brief Project object fields enumeration and handling. + * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project + * + * \addtogroup project + * @{ + */ +#if !defined(PREMAKE_FIELDS_H) +#define PREMAKE_FIELDS_H + +#include "base/strings.h" + + +/** + * Field types. + */ +enum FieldKind +{ + StringField, + ListField, + FilesField +}; + + +/** + * Field validation function signature. + * \param value The value to validate. + * \returns True if the value is considered valid. + */ +typedef int (*FieldValidator)(const char* value); + + +/** + * Metadata about a project object field. + */ +struct FieldInfo +{ + const char* name; /**< The name of the field. */ + enum FieldKind kind; /**< StringField, ListField, etc. */ + FieldValidator validator; /**< The field validation function */ +}; + + +DECLARE_CLASS(Fields) + + +Fields fields_create(struct FieldInfo* info); +void fields_destroy(Fields fields); + +void fields_add_value(Fields fields, int index, const char* value); +const char* fields_get_value(Fields fields, int index); +Strings fields_get_values(Fields fields, int index); +void fields_set_value(Fields fields, int index, const char* value); +void fields_set_values(Fields fields, int index, Strings values); + +#endif +/* @} */ diff --git a/src/project/project.c b/src/project/project.c index 1f8aae2..f8c1d6a 100644 --- a/src/project/project.c +++ b/src/project/project.c @@ -1,358 +1,358 @@ -/** - * \file project.c - * \brief The project class. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include -#include -#include -#include "premake.h" -#include "project/project.h" -#include "project/solution.h" -#include "base/buffers.h" -#include "base/cstr.h" -#include "base/guid.h" -#include "base/path.h" -#include "base/strings.h" -#include "platform/platform.h" - - -struct FieldInfo ProjectFieldInfo[] = -{ - { "basedir", StringField, NULL }, - { "files", FilesField, NULL }, - { "guid", StringField, guid_is_valid }, - { "language", StringField, NULL }, - { "location", StringField, NULL }, - { "name", StringField, NULL }, - { 0, 0, NULL } -}; - - -DEFINE_CLASS(Project) -{ - Solution solution; - Fields fields; - const char* config_filter; -}; - - -/** - * Create and initialize a new project object. - * \returns A new project object. - */ -Project project_create() -{ - Project prj = ALLOC_CLASS(Project); - prj->solution = NULL; - prj->fields = fields_create(ProjectFieldInfo); - prj->config_filter = NULL; - return prj; -} - - -/** - * Destroy a project object and release the associated memory. - * \param prj The project object to destroy. - */ -void project_destroy(Project prj) -{ - assert(prj); - fields_destroy(prj->fields); - free(prj); -} - - -/** - * Get the base directory for the project; any properties containing relative - * paths are relative to this location. - * \param prj The project object to query. - * \returns The base directory, or NULL if no directory has been set. - */ -const char* project_get_base_dir(Project prj) -{ - return project_get_value(prj, ProjectBaseDirectory); -} - - -/** - * Retrieve the current configuration filter. All subsequent requests for configuration - * values will return settings from this configuration only. - * \param prj The project object to query. - * \returns The current configuration filter, or NULL if no filter has been set. - */ -const char* project_get_configuration_filter(Project prj) -{ - assert(prj); - return prj->config_filter; -} - - -/** - * Retrieve the fields object for this solution; used to unload values from the script. - */ -Fields project_get_fields(Project prj) -{ - assert(prj); - return prj->fields; -} - - -/** - * Get the path to the project output file, using the provided file extension. - * \param prj The project object to query. - * \param basename The base filename; if NULL the project name will be used. - * \param ext The file extension to be used on the filename; may be NULL. - * \returns The path to the project file. - */ -const char* project_get_filename(Project prj, const char* basename, const char* ext) -{ - const char* base_dir; - const char* location; - const char* directory; - const char* result; - - assert(prj); - - if (!basename) - { - basename = project_get_name(prj); - } - - - if (!ext) - { - ext = ""; - } - - base_dir = project_get_base_dir(prj); - location = project_get_location(prj); - directory = path_join(base_dir, location); - - result = path_assemble(directory, basename, ext); - return result; -} - - -/** - * Retrieve the list of source files associated with a project. - */ -Strings project_get_files(Project prj) -{ - assert(prj); - return fields_get_values(prj->fields, ProjectFiles); -} - - -/** - * Retrieve the GUID associated with a project. - */ -const char* project_get_guid(Project prj) -{ - assert(prj); - return project_get_value(prj, ProjectGuid); -} - - -/** - * Get the programming language used by the project. - * \param prj The project object to query. - * \returns The language used by the project, or NULL if no language has been set. - */ -const char* project_get_language(Project prj) -{ - const char* result = project_get_value(prj, ProjectLanguage); - if (result == NULL && prj->solution != NULL) - { - result = solution_get_language(prj->solution); - } - return result; -} - - -/** - * Retrieve the output location (the relative path from the base directory to the - * target output directory) for this project. - * \param prj The project object to modify. - * \returns The project output location, or NULL if no location has been set. - */ -const char* project_get_location(Project prj) -{ - return project_get_value(prj, ProjectLocation); -} - - -/** - * Get the name of the project. - * \returns The name, if set, NULL otherwise. - */ -const char* project_get_name(Project prj) -{ - return project_get_value(prj, ProjectName); -} - - -/** - * Retrieve the output filename for this project, taking into account platform-specific - * naming conventions. For instance, for a project named "MyProject" this function would - * return "MyProject.exe" on Windows. No path information is included, use the function - * project_get_outdir() for that. - */ -const char* project_get_outfile(Project prj) -{ - char* buffer = buffers_next(); - strcpy(buffer, project_get_name(prj)); - if (platform_get() == Windows) - { - strcat(buffer, ".exe"); - } - return buffer; -} - - -/** - * Retrieve the solution associated with this project (internal). - * \param prj The project to query. - * \returns The associated solution, or NULL if no association has been made. - */ -Solution project_get_solution(Project prj) -{ - return prj->solution; -} - - -/** - * Retrieve a string (single value) fields from a project, using the field indices. - * \param prj The project object to query. - * \param field The index of the field to query. - * \returns The value of the field if set, of NULL. - */ -const char* project_get_value(Project prj, enum ProjectField field) -{ - assert(prj); - return fields_get_value(prj->fields, field); -} - - -/** - * Returns true if the specified language is recognized. Current valid language strings - * are 'c', 'c++', and 'c#'. - * \param language The language string. - * \returns True if the language string is recognized. - */ -int project_is_valid_language(const char* language) -{ - return (cstr_eq(language, "c") || - cstr_eq(language, "c++") || - cstr_eq(language, "c#")); -} - - -/** - * Set the base directory of the project. - * \param prj The project object to modify. - * \param base_dir The new base directory. - */ -void project_set_base_dir(Project prj, const char* base_dir) -{ - project_set_value(prj, ProjectBaseDirectory, base_dir); -} - - -/** - * Set the current configuration filter. All subsequent requests for configuration - * values will return settings from this configuration only. - * \param prj The project object to query. - * \param cfg_name The name of the configuration on which to filter. - */ -void project_set_configuration_filter(Project prj, const char* cfg_name) -{ - assert(prj); - prj->config_filter = cfg_name; -} - - -/** - * Set the GUID associated with a project. The GUID is required by the Visual - * Studio generators, and must be unique per project. - * \param prj The project to modify. - * \param guid The new project GUID. - */ -void project_set_guid(Project prj, const char* guid) -{ - project_set_value(prj, ProjectGuid, guid); -} - - -/** - * Set the programming language used by a project. - * \param prj The project to modify. - * \param language The programming language used by the project. - */ -void project_set_language(Project prj, const char* language) -{ - project_set_value(prj, ProjectLanguage, language); -} - - -/** - * Set the output location (the relative path from the base directory to the - * target output directory) for this project. - * \param prj The project object to modify. - * \param location The new output location. - */ -void project_set_location(Project prj, const char* location) -{ - project_set_value(prj, ProjectLocation, location); -} - - -/** - * Set the name of the project. - * \param prj The project object. - * \param name The new for the project. - */ -void project_set_name(Project prj, const char* name) -{ - project_set_value(prj, ProjectName, name); -} - - -/** - * Associate a solution with this project (internal). - * \param prj The project to modify. - * \param sln The solution to associate with this project. - */ -void project_set_solution(Project prj, Solution sln) -{ - assert(prj); - prj->solution = sln; -} - - -/** - * Set a string (single value) field on a project, using the field indices. - * \param prj The project object. - * \param field The field to set. - * \param value The new value for the field. - */ -void project_set_value(Project prj, enum ProjectField field, const char* value) -{ - assert(prj); - fields_set_value(prj->fields, field, value); -} - - -/** - * Sets the list of values associated with a field. The field will subsequently - * "own" the list, and take responsibility to destroying it with the field set. - * \param prj The project object. - * \param field The index of the field to set. - * \param values The list of new values for the field. - */ -void project_set_values(Project prj, enum ProjectField field, Strings values) -{ - assert(prj); - fields_set_values(prj->fields, field, values); -} +/** + * \file project.c + * \brief The project class. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include +#include +#include +#include "premake.h" +#include "project/project.h" +#include "project/solution.h" +#include "base/buffers.h" +#include "base/cstr.h" +#include "base/guid.h" +#include "base/path.h" +#include "base/strings.h" +#include "platform/platform.h" + + +struct FieldInfo ProjectFieldInfo[] = +{ + { "basedir", StringField, NULL }, + { "files", FilesField, NULL }, + { "guid", StringField, guid_is_valid }, + { "language", StringField, NULL }, + { "location", StringField, NULL }, + { "name", StringField, NULL }, + { 0, 0, NULL } +}; + + +DEFINE_CLASS(Project) +{ + Solution solution; + Fields fields; + const char* config_filter; +}; + + +/** + * Create and initialize a new project object. + * \returns A new project object. + */ +Project project_create() +{ + Project prj = ALLOC_CLASS(Project); + prj->solution = NULL; + prj->fields = fields_create(ProjectFieldInfo); + prj->config_filter = NULL; + return prj; +} + + +/** + * Destroy a project object and release the associated memory. + * \param prj The project object to destroy. + */ +void project_destroy(Project prj) +{ + assert(prj); + fields_destroy(prj->fields); + free(prj); +} + + +/** + * Get the base directory for the project; any properties containing relative + * paths are relative to this location. + * \param prj The project object to query. + * \returns The base directory, or NULL if no directory has been set. + */ +const char* project_get_base_dir(Project prj) +{ + return project_get_value(prj, ProjectBaseDirectory); +} + + +/** + * Retrieve the current configuration filter. All subsequent requests for configuration + * values will return settings from this configuration only. + * \param prj The project object to query. + * \returns The current configuration filter, or NULL if no filter has been set. + */ +const char* project_get_configuration_filter(Project prj) +{ + assert(prj); + return prj->config_filter; +} + + +/** + * Retrieve the fields object for this solution; used to unload values from the script. + */ +Fields project_get_fields(Project prj) +{ + assert(prj); + return prj->fields; +} + + +/** + * Get the path to the project output file, using the provided file extension. + * \param prj The project object to query. + * \param basename The base filename; if NULL the project name will be used. + * \param ext The file extension to be used on the filename; may be NULL. + * \returns The path to the project file. + */ +const char* project_get_filename(Project prj, const char* basename, const char* ext) +{ + const char* base_dir; + const char* location; + const char* directory; + const char* result; + + assert(prj); + + if (!basename) + { + basename = project_get_name(prj); + } + + + if (!ext) + { + ext = ""; + } + + base_dir = project_get_base_dir(prj); + location = project_get_location(prj); + directory = path_join(base_dir, location); + + result = path_assemble(directory, basename, ext); + return result; +} + + +/** + * Retrieve the list of source files associated with a project. + */ +Strings project_get_files(Project prj) +{ + assert(prj); + return fields_get_values(prj->fields, ProjectFiles); +} + + +/** + * Retrieve the GUID associated with a project. + */ +const char* project_get_guid(Project prj) +{ + assert(prj); + return project_get_value(prj, ProjectGuid); +} + + +/** + * Get the programming language used by the project. + * \param prj The project object to query. + * \returns The language used by the project, or NULL if no language has been set. + */ +const char* project_get_language(Project prj) +{ + const char* result = project_get_value(prj, ProjectLanguage); + if (result == NULL && prj->solution != NULL) + { + result = solution_get_language(prj->solution); + } + return result; +} + + +/** + * Retrieve the output location (the relative path from the base directory to the + * target output directory) for this project. + * \param prj The project object to modify. + * \returns The project output location, or NULL if no location has been set. + */ +const char* project_get_location(Project prj) +{ + return project_get_value(prj, ProjectLocation); +} + + +/** + * Get the name of the project. + * \returns The name, if set, NULL otherwise. + */ +const char* project_get_name(Project prj) +{ + return project_get_value(prj, ProjectName); +} + + +/** + * Retrieve the output filename for this project, taking into account platform-specific + * naming conventions. For instance, for a project named "MyProject" this function would + * return "MyProject.exe" on Windows. No path information is included, use the function + * project_get_outdir() for that. + */ +const char* project_get_outfile(Project prj) +{ + char* buffer = buffers_next(); + strcpy(buffer, project_get_name(prj)); + if (platform_get() == Windows) + { + strcat(buffer, ".exe"); + } + return buffer; +} + + +/** + * Retrieve the solution associated with this project (internal). + * \param prj The project to query. + * \returns The associated solution, or NULL if no association has been made. + */ +Solution project_get_solution(Project prj) +{ + return prj->solution; +} + + +/** + * Retrieve a string (single value) fields from a project, using the field indices. + * \param prj The project object to query. + * \param field The index of the field to query. + * \returns The value of the field if set, of NULL. + */ +const char* project_get_value(Project prj, enum ProjectField field) +{ + assert(prj); + return fields_get_value(prj->fields, field); +} + + +/** + * Returns true if the specified language is recognized. Current valid language strings + * are 'c', 'c++', and 'c#'. + * \param language The language string. + * \returns True if the language string is recognized. + */ +int project_is_valid_language(const char* language) +{ + return (cstr_eq(language, "c") || + cstr_eq(language, "c++") || + cstr_eq(language, "c#")); +} + + +/** + * Set the base directory of the project. + * \param prj The project object to modify. + * \param base_dir The new base directory. + */ +void project_set_base_dir(Project prj, const char* base_dir) +{ + project_set_value(prj, ProjectBaseDirectory, base_dir); +} + + +/** + * Set the current configuration filter. All subsequent requests for configuration + * values will return settings from this configuration only. + * \param prj The project object to query. + * \param cfg_name The name of the configuration on which to filter. + */ +void project_set_configuration_filter(Project prj, const char* cfg_name) +{ + assert(prj); + prj->config_filter = cfg_name; +} + + +/** + * Set the GUID associated with a project. The GUID is required by the Visual + * Studio generators, and must be unique per project. + * \param prj The project to modify. + * \param guid The new project GUID. + */ +void project_set_guid(Project prj, const char* guid) +{ + project_set_value(prj, ProjectGuid, guid); +} + + +/** + * Set the programming language used by a project. + * \param prj The project to modify. + * \param language The programming language used by the project. + */ +void project_set_language(Project prj, const char* language) +{ + project_set_value(prj, ProjectLanguage, language); +} + + +/** + * Set the output location (the relative path from the base directory to the + * target output directory) for this project. + * \param prj The project object to modify. + * \param location The new output location. + */ +void project_set_location(Project prj, const char* location) +{ + project_set_value(prj, ProjectLocation, location); +} + + +/** + * Set the name of the project. + * \param prj The project object. + * \param name The new for the project. + */ +void project_set_name(Project prj, const char* name) +{ + project_set_value(prj, ProjectName, name); +} + + +/** + * Associate a solution with this project (internal). + * \param prj The project to modify. + * \param sln The solution to associate with this project. + */ +void project_set_solution(Project prj, Solution sln) +{ + assert(prj); + prj->solution = sln; +} + + +/** + * Set a string (single value) field on a project, using the field indices. + * \param prj The project object. + * \param field The field to set. + * \param value The new value for the field. + */ +void project_set_value(Project prj, enum ProjectField field, const char* value) +{ + assert(prj); + fields_set_value(prj->fields, field, value); +} + + +/** + * Sets the list of values associated with a field. The field will subsequently + * "own" the list, and take responsibility to destroying it with the field set. + * \param prj The project object. + * \param field The index of the field to set. + * \param values The list of new values for the field. + */ +void project_set_values(Project prj, enum ProjectField field, Strings values) +{ + assert(prj); + fields_set_values(prj->fields, field, values); +} diff --git a/src/project/project.h b/src/project/project.h index fa75dce..e8a96c1 100644 --- a/src/project/project.h +++ b/src/project/project.h @@ -1,64 +1,64 @@ -/** - * \file project.h - * \brief Project objects API. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - * - * \defgroup project Project Objects - * - * Project objects: solutions, projects, and configurations. - * - * @{ - */ -#if !defined(PREMAKE_PROJECT_H) -#define PREMAKE_PROJECT_H - -#include "fields.h" - - -/** - * Project field index. - * \note If you modify this list, you must also update SolutionFieldInfo[]. - */ -enum ProjectField -{ - ProjectBaseDirectory, - ProjectFiles, - ProjectGuid, - ProjectLanguage, - ProjectLocation, - ProjectName, - NumProjectFields -}; - -extern struct FieldInfo ProjectFieldInfo[]; - - -DECLARE_CLASS(Project) - -Project project_create(void); -void project_destroy(Project prj); - -const char* project_get_base_dir(Project prj); -const char* project_get_configuration_filter(Project prj); -Fields project_get_fields(Project prj); -const char* project_get_filename(Project prj, const char* basename, const char* ext); -Strings project_get_files(Project prj); -const char* project_get_guid(Project prj); -const char* project_get_language(Project prj); -const char* project_get_location(Project prj); -const char* project_get_name(Project prj); -const char* project_get_outfile(Project prj); -const char* project_get_value(Project prj, enum ProjectField field); -int project_is_valid_language(const char* language); -void project_set_base_dir(Project prj, const char* base_dir); -void project_set_configuration_filter(Project prj, const char* cfg_name); -void project_set_guid(Project prj, const char* guid); -void project_set_language(Project prj, const char* language); -void project_set_location(Project prj, const char* location); -void project_set_name(Project prj, const char* name); -void project_set_value(Project prj, enum ProjectField field, const char* value); -void project_set_values(Project prj, enum ProjectField field, Strings values); -int project_tests(void); - -#endif -/** @} */ +/** + * \file project.h + * \brief Project objects API. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + * + * \defgroup project Project Objects + * + * Project objects: solutions, projects, and configurations. + * + * @{ + */ +#if !defined(PREMAKE_PROJECT_H) +#define PREMAKE_PROJECT_H + +#include "fields.h" + + +/** + * Project field index. + * \note If you modify this list, you must also update SolutionFieldInfo[]. + */ +enum ProjectField +{ + ProjectBaseDirectory, + ProjectFiles, + ProjectGuid, + ProjectLanguage, + ProjectLocation, + ProjectName, + NumProjectFields +}; + +extern struct FieldInfo ProjectFieldInfo[]; + + +DECLARE_CLASS(Project) + +Project project_create(void); +void project_destroy(Project prj); + +const char* project_get_base_dir(Project prj); +const char* project_get_configuration_filter(Project prj); +Fields project_get_fields(Project prj); +const char* project_get_filename(Project prj, const char* basename, const char* ext); +Strings project_get_files(Project prj); +const char* project_get_guid(Project prj); +const char* project_get_language(Project prj); +const char* project_get_location(Project prj); +const char* project_get_name(Project prj); +const char* project_get_outfile(Project prj); +const char* project_get_value(Project prj, enum ProjectField field); +int project_is_valid_language(const char* language); +void project_set_base_dir(Project prj, const char* base_dir); +void project_set_configuration_filter(Project prj, const char* cfg_name); +void project_set_guid(Project prj, const char* guid); +void project_set_language(Project prj, const char* language); +void project_set_location(Project prj, const char* location); +void project_set_name(Project prj, const char* name); +void project_set_value(Project prj, enum ProjectField field, const char* value); +void project_set_values(Project prj, enum ProjectField field, Strings values); +int project_tests(void); + +#endif +/** @} */ diff --git a/src/project/solution.c b/src/project/solution.c index c2e616a..c67a31c 100644 --- a/src/project/solution.c +++ b/src/project/solution.c @@ -1,330 +1,330 @@ -/** - * \file solution.c - * \brief The Solution class, representing the top-level container for projects. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include -#include -#include "premake.h" -#include "project/solution.h" -#include "project/project_internal.h" -#include "base/array.h" -#include "base/path.h" -#include "base/strings.h" - -#include "base/string.h" /* <-- remove this? */ - - -struct FieldInfo SolutionFieldInfo[] = -{ - { "basedir", StringField, NULL }, - { "configurations", ListField, NULL }, - { "language", StringField, project_is_valid_language }, - { "location", StringField, NULL }, - { "name", StringField, NULL }, - { 0, 0, NULL } -}; - - -DEFINE_CLASS(Solution) -{ - Fields fields; - Array projects; -}; - - -/** - * Create and initialize a new solution object. - * \returns A new solution object. - */ -Solution solution_create() -{ - Solution sln = ALLOC_CLASS(Solution); - sln->fields = fields_create(SolutionFieldInfo); - sln->projects = array_create(); - return sln; -} - - -/** - * Destroy a solution object and release the associated memory. - * \param sln The solution object to destroy. - */ -void solution_destroy(Solution sln) -{ - int i, n; - - assert(sln); - fields_destroy(sln->fields); - - n = solution_num_projects(sln); - for (i = 0; i < n; ++i) - { - Project prj = solution_get_project(sln, i); - project_destroy(prj); - } - array_destroy(sln->projects); - - free(sln); -} - - -/** - * Add a configuration name to a solution. - * \param sln The solution to contain the project. - * \param config_name The name of the configuration add. - */ -void solution_add_config_name(Solution sln, const char* config_name) -{ - assert(sln); - assert(config_name); - fields_add_value(sln->fields, SolutionConfigurations, config_name); -} - - -/** - * Add a project to a solution. - * \param sln The solution to contain the project. - * \param prj The project to add. - */ -void solution_add_project(Solution sln, Project prj) -{ - assert(sln); - assert(prj); - array_add(sln->projects, prj); - project_set_solution(prj, sln); -} - - -/** - * Get the base directory for the solution; any properties containing relative - * paths are relative to this location. - * \param sln The solution object to query. - * \returns The base directory, or NULL if no directory has been set. - */ -const char* solution_get_base_dir(Solution sln) -{ - return solution_get_value(sln, SolutionBaseDirectory); -} - - -/** - * Get the configuration name at a given index. - * \param sln The solution to query. - * \param index The configuration index to query. - * \returns The configuration name at the given index. - */ -const char* solution_get_config_name(Solution sln, int index) -{ - Strings names; - const char* name; - assert(sln); - names = fields_get_values(sln->fields, SolutionConfigurations); - name = strings_item(names, index); - return name; -} - - -/** - * Get the list of configuration names. - * \param sln The solution to query. - * \returns The configuration name at the given index. - */ -Strings solution_get_config_names(Solution sln) -{ - assert(sln); - return fields_get_values(sln->fields, SolutionConfigurations); -} - - -/** - * Retrieve the fields object for this solution; used to unload values from the script. - */ -Fields solution_get_fields(Solution sln) -{ - assert(sln); - return sln->fields; -} - - -/** - * Get the path to the solution output file, using the provided file extension. - * \param sln The solution object to query. - * \param basename The base filename; if NULL the solution name will be used. - * \param ext The file extension to be used on the filename; may be NULL. - * \returns The path to the solution file. - */ -const char* solution_get_filename(Solution sln, const char* basename, const char* ext) -{ - const char* base_dir; - const char* location; - const char* directory; - const char* result; - - assert(sln); - - if (!basename) - { - basename = solution_get_name(sln); - } - - if (!ext) - { - ext = ""; - } - - base_dir = solution_get_base_dir(sln); - location = solution_get_location(sln); - directory = path_join(base_dir, location); - - result = path_assemble(directory, basename, ext); - return result; -} - - -/** - * Get the programming language set globally for the solution. - * \param sln The solution object to modify. - * \returns The language set for the solution, or NULL if no language has been set. - */ -const char* solution_get_language(Solution sln) -{ - return solution_get_value(sln, SolutionLanguage); -} - - -/** - * Retrieve the output location (the relative path from the base directory to the - * target output directory) for this solution. - * \param sln The solution object to modify. - * \returns The solution output location, or NULL if no location has been set. - */ -const char* solution_get_location(Solution sln) -{ - return solution_get_value(sln, SolutionLocation); -} - - -/** - * Get the name of the solution. - * \returns The name, if set, NULL otherwise. - */ -const char* solution_get_name(Solution sln) -{ - return solution_get_value(sln, SolutionName); -} - - -/** - * Retrieve a project from the solution. - * \param sln The solution to query. - * \param index The index of the project to retreive. - * \returns The project at the given index within the solution. - */ -Project solution_get_project(Solution sln, int index) -{ - Project prj; - - assert(sln); - - prj = (Project)array_item(sln->projects, index); - return prj; -} - - -/** - * Retrieve a string (single value) fields from a solution, using the field indices. - * \param sln The solution object to query. - * \param field The index of the field to query. - * \returns The value of the field if set, of NULL. - */ -const char* solution_get_value(Solution sln, enum SolutionField field) -{ - assert(sln); - return fields_get_value(sln->fields, field); -} - - -/** - * Return the number of configurations contained by this solution. - * \param sln The solution to query. - * \returns The number of configurations contained by the solution. - */ -int solution_num_configs(Solution sln) -{ - Strings names; - assert(sln); - names = fields_get_values(sln->fields, SolutionConfigurations); - return strings_size(names); -} - - -/** - * Return the number of projects contained by this solution. - * \param sln The solution to query. - * \returns The number of projects contained by the solution. - */ -int solution_num_projects(Solution sln) -{ - assert(sln); - return array_size(sln->projects); -} - - -/** - * Set the base directory of the solution. - * \param sln The solution object to modify. - * \param base_dir The new base directory. - */ -void solution_set_base_dir(Solution sln, const char* base_dir) -{ - solution_set_value(sln, SolutionBaseDirectory, base_dir); -} - - -/** - * Set the global programming language for the solution. - * \param sln The solution to modify. - * \param language The programming language to set globally for the solution. - */ -void solution_set_language(Solution sln, const char* language) -{ - solution_set_value(sln, SolutionLanguage, language); -} - - -/* - * Set the output location (the relative path from the base directory to the - * target output directory) for this solution. - * \param sln The solution object to modify. - * \param location The new output location. - */ -void solution_set_location(Solution sln, const char* location) -{ - solution_set_value(sln, SolutionLocation, location); -} - - -/** - * Set the name of the solution. - * \param sln The solution object. - * \param name The new for the solution. - */ -void solution_set_name(Solution sln, const char* name) -{ - solution_set_value(sln, SolutionName, name); -} - - -/** - * Set a string (single value) field on a solution, using the field indices. - * \param sln The solution object. - * \param field The field to set. - * \param value The new value for the field. - */ -void solution_set_value(Solution sln, enum SolutionField field, const char* value) -{ - assert(sln); - fields_set_value(sln->fields, field, value); -} +/** + * \file solution.c + * \brief The Solution class, representing the top-level container for projects. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include +#include +#include "premake.h" +#include "project/solution.h" +#include "project/project_internal.h" +#include "base/array.h" +#include "base/path.h" +#include "base/strings.h" + +#include "base/string.h" /* <-- remove this? */ + + +struct FieldInfo SolutionFieldInfo[] = +{ + { "basedir", StringField, NULL }, + { "configurations", ListField, NULL }, + { "language", StringField, project_is_valid_language }, + { "location", StringField, NULL }, + { "name", StringField, NULL }, + { 0, 0, NULL } +}; + + +DEFINE_CLASS(Solution) +{ + Fields fields; + Array projects; +}; + + +/** + * Create and initialize a new solution object. + * \returns A new solution object. + */ +Solution solution_create() +{ + Solution sln = ALLOC_CLASS(Solution); + sln->fields = fields_create(SolutionFieldInfo); + sln->projects = array_create(); + return sln; +} + + +/** + * Destroy a solution object and release the associated memory. + * \param sln The solution object to destroy. + */ +void solution_destroy(Solution sln) +{ + int i, n; + + assert(sln); + fields_destroy(sln->fields); + + n = solution_num_projects(sln); + for (i = 0; i < n; ++i) + { + Project prj = solution_get_project(sln, i); + project_destroy(prj); + } + array_destroy(sln->projects); + + free(sln); +} + + +/** + * Add a configuration name to a solution. + * \param sln The solution to contain the project. + * \param config_name The name of the configuration add. + */ +void solution_add_config_name(Solution sln, const char* config_name) +{ + assert(sln); + assert(config_name); + fields_add_value(sln->fields, SolutionConfigurations, config_name); +} + + +/** + * Add a project to a solution. + * \param sln The solution to contain the project. + * \param prj The project to add. + */ +void solution_add_project(Solution sln, Project prj) +{ + assert(sln); + assert(prj); + array_add(sln->projects, prj); + project_set_solution(prj, sln); +} + + +/** + * Get the base directory for the solution; any properties containing relative + * paths are relative to this location. + * \param sln The solution object to query. + * \returns The base directory, or NULL if no directory has been set. + */ +const char* solution_get_base_dir(Solution sln) +{ + return solution_get_value(sln, SolutionBaseDirectory); +} + + +/** + * Get the configuration name at a given index. + * \param sln The solution to query. + * \param index The configuration index to query. + * \returns The configuration name at the given index. + */ +const char* solution_get_config_name(Solution sln, int index) +{ + Strings names; + const char* name; + assert(sln); + names = fields_get_values(sln->fields, SolutionConfigurations); + name = strings_item(names, index); + return name; +} + + +/** + * Get the list of configuration names. + * \param sln The solution to query. + * \returns The configuration name at the given index. + */ +Strings solution_get_config_names(Solution sln) +{ + assert(sln); + return fields_get_values(sln->fields, SolutionConfigurations); +} + + +/** + * Retrieve the fields object for this solution; used to unload values from the script. + */ +Fields solution_get_fields(Solution sln) +{ + assert(sln); + return sln->fields; +} + + +/** + * Get the path to the solution output file, using the provided file extension. + * \param sln The solution object to query. + * \param basename The base filename; if NULL the solution name will be used. + * \param ext The file extension to be used on the filename; may be NULL. + * \returns The path to the solution file. + */ +const char* solution_get_filename(Solution sln, const char* basename, const char* ext) +{ + const char* base_dir; + const char* location; + const char* directory; + const char* result; + + assert(sln); + + if (!basename) + { + basename = solution_get_name(sln); + } + + if (!ext) + { + ext = ""; + } + + base_dir = solution_get_base_dir(sln); + location = solution_get_location(sln); + directory = path_join(base_dir, location); + + result = path_assemble(directory, basename, ext); + return result; +} + + +/** + * Get the programming language set globally for the solution. + * \param sln The solution object to modify. + * \returns The language set for the solution, or NULL if no language has been set. + */ +const char* solution_get_language(Solution sln) +{ + return solution_get_value(sln, SolutionLanguage); +} + + +/** + * Retrieve the output location (the relative path from the base directory to the + * target output directory) for this solution. + * \param sln The solution object to modify. + * \returns The solution output location, or NULL if no location has been set. + */ +const char* solution_get_location(Solution sln) +{ + return solution_get_value(sln, SolutionLocation); +} + + +/** + * Get the name of the solution. + * \returns The name, if set, NULL otherwise. + */ +const char* solution_get_name(Solution sln) +{ + return solution_get_value(sln, SolutionName); +} + + +/** + * Retrieve a project from the solution. + * \param sln The solution to query. + * \param index The index of the project to retreive. + * \returns The project at the given index within the solution. + */ +Project solution_get_project(Solution sln, int index) +{ + Project prj; + + assert(sln); + + prj = (Project)array_item(sln->projects, index); + return prj; +} + + +/** + * Retrieve a string (single value) fields from a solution, using the field indices. + * \param sln The solution object to query. + * \param field The index of the field to query. + * \returns The value of the field if set, of NULL. + */ +const char* solution_get_value(Solution sln, enum SolutionField field) +{ + assert(sln); + return fields_get_value(sln->fields, field); +} + + +/** + * Return the number of configurations contained by this solution. + * \param sln The solution to query. + * \returns The number of configurations contained by the solution. + */ +int solution_num_configs(Solution sln) +{ + Strings names; + assert(sln); + names = fields_get_values(sln->fields, SolutionConfigurations); + return strings_size(names); +} + + +/** + * Return the number of projects contained by this solution. + * \param sln The solution to query. + * \returns The number of projects contained by the solution. + */ +int solution_num_projects(Solution sln) +{ + assert(sln); + return array_size(sln->projects); +} + + +/** + * Set the base directory of the solution. + * \param sln The solution object to modify. + * \param base_dir The new base directory. + */ +void solution_set_base_dir(Solution sln, const char* base_dir) +{ + solution_set_value(sln, SolutionBaseDirectory, base_dir); +} + + +/** + * Set the global programming language for the solution. + * \param sln The solution to modify. + * \param language The programming language to set globally for the solution. + */ +void solution_set_language(Solution sln, const char* language) +{ + solution_set_value(sln, SolutionLanguage, language); +} + + +/* + * Set the output location (the relative path from the base directory to the + * target output directory) for this solution. + * \param sln The solution object to modify. + * \param location The new output location. + */ +void solution_set_location(Solution sln, const char* location) +{ + solution_set_value(sln, SolutionLocation, location); +} + + +/** + * Set the name of the solution. + * \param sln The solution object. + * \param name The new for the solution. + */ +void solution_set_name(Solution sln, const char* name) +{ + solution_set_value(sln, SolutionName, name); +} + + +/** + * Set a string (single value) field on a solution, using the field indices. + * \param sln The solution object. + * \param field The field to set. + * \param value The new value for the field. + */ +void solution_set_value(Solution sln, enum SolutionField field, const char* value) +{ + assert(sln); + fields_set_value(sln->fields, field, value); +} diff --git a/src/project/solution.h b/src/project/solution.h index 7ee7dff..47e674e 100644 --- a/src/project/solution.h +++ b/src/project/solution.h @@ -1,61 +1,61 @@ -/** - * \file solution.h - * \brief The Solution class, representing the top-level container for projects. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - * - * \addtogroup project - * @{ - */ -#if !defined(PREMAKE_SOLUTION_H) -#define PREMAKE_SOLUTION_H - -#include "fields.h" -#include "project.h" -#include "base/strings.h" - - -/** - * Solution field index. - * \note If you modify this list, you must also update SolutionFieldInfo[]. - */ -enum SolutionField -{ - SolutionBaseDirectory, - SolutionConfigurations, - SolutionLanguage, - SolutionLocation, - SolutionName, - NumSolutionFields -}; - -extern struct FieldInfo SolutionFieldInfo[]; - - -DECLARE_CLASS(Solution) - -Solution solution_create(void); -void solution_destroy(Solution sln); - -void solution_add_config_name(Solution sln, const char* config_name); -void solution_add_project(Solution sln, Project prj); -const char* solution_get_base_dir(Solution sln); -const char* solution_get_config_name(Solution sln, int index); -Strings solution_get_config_names(Solution sln); -Fields solution_get_fields(Solution sln); -const char* solution_get_filename(Solution sln, const char* basename, const char* ext); -const char* solution_get_language(Solution sln); -const char* solution_get_location(Solution sln); -const char* solution_get_name(Solution sln); -Project solution_get_project(Solution sln, int index); -const char* solution_get_value(Solution sln, enum SolutionField field); -int solution_num_configs(Solution sln); -int solution_num_projects(Solution sln); -void solution_set_base_dir(Solution sln, const char* base_dir); -void solution_set_language(Solution sln, const char* language); -void solution_set_location(Solution sln, const char* location); -void solution_set_name(Solution sln, const char* name); -void solution_set_value(Solution sln, enum SolutionField field, const char* value); - - -#endif -/** @} */ +/** + * \file solution.h + * \brief The Solution class, representing the top-level container for projects. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + * + * \addtogroup project + * @{ + */ +#if !defined(PREMAKE_SOLUTION_H) +#define PREMAKE_SOLUTION_H + +#include "fields.h" +#include "project.h" +#include "base/strings.h" + + +/** + * Solution field index. + * \note If you modify this list, you must also update SolutionFieldInfo[]. + */ +enum SolutionField +{ + SolutionBaseDirectory, + SolutionConfigurations, + SolutionLanguage, + SolutionLocation, + SolutionName, + NumSolutionFields +}; + +extern struct FieldInfo SolutionFieldInfo[]; + + +DECLARE_CLASS(Solution) + +Solution solution_create(void); +void solution_destroy(Solution sln); + +void solution_add_config_name(Solution sln, const char* config_name); +void solution_add_project(Solution sln, Project prj); +const char* solution_get_base_dir(Solution sln); +const char* solution_get_config_name(Solution sln, int index); +Strings solution_get_config_names(Solution sln); +Fields solution_get_fields(Solution sln); +const char* solution_get_filename(Solution sln, const char* basename, const char* ext); +const char* solution_get_language(Solution sln); +const char* solution_get_location(Solution sln); +const char* solution_get_name(Solution sln); +Project solution_get_project(Solution sln, int index); +const char* solution_get_value(Solution sln, enum SolutionField field); +int solution_num_configs(Solution sln); +int solution_num_projects(Solution sln); +void solution_set_base_dir(Solution sln, const char* base_dir); +void solution_set_language(Solution sln, const char* language); +void solution_set_location(Solution sln, const char* location); +void solution_set_name(Solution sln, const char* name); +void solution_set_value(Solution sln, enum SolutionField field, const char* value); + + +#endif +/** @} */ diff --git a/src/project/tests/fields_tests.cpp b/src/project/tests/fields_tests.cpp index ef05136..8d50ba2 100644 --- a/src/project/tests/fields_tests.cpp +++ b/src/project/tests/fields_tests.cpp @@ -1,64 +1,64 @@ -/** - * \file fields_tests.cpp - * \brief Automated tests for the Fields class. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "testing/testing.h" -extern "C" { -#include "project/fields.h" -} - -enum TestFields -{ - TestStringValue, - TestListValue -}; - -static FieldInfo TestFieldInfo[] = -{ - { "stringval", StringField }, - { "listval", ListField }, - { 0, StringField } -}; - - -struct FxFields -{ - Fields fields; - - FxFields() - { - fields = fields_create(TestFieldInfo); - } - - ~FxFields() - { - fields_destroy(fields); - } -}; - - -SUITE(fields) -{ - TEST_FIXTURE(FxFields, GetValue_ReturnsNull_OnUnsetString) - { - const char* result = fields_get_value(fields, TestStringValue); - CHECK(result == NULL); - } - - TEST_FIXTURE(FxFields, SetValue_CanRoundtrip) - { - fields_set_value(fields, TestStringValue, "String Value"); - const char* result = fields_get_value(fields, TestStringValue); - CHECK_EQUAL("String Value", result); - } - - TEST_FIXTURE(FxFields, SetValues_CanRoundtrip) - { - Strings values = strings_create(); - fields_set_values(fields, TestListValue, values); - CHECK(values == fields_get_values(fields, TestListValue)); - } -} +/** + * \file fields_tests.cpp + * \brief Automated tests for the Fields class. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "testing/testing.h" +extern "C" { +#include "project/fields.h" +} + +enum TestFields +{ + TestStringValue, + TestListValue +}; + +static FieldInfo TestFieldInfo[] = +{ + { "stringval", StringField }, + { "listval", ListField }, + { 0, StringField } +}; + + +struct FxFields +{ + Fields fields; + + FxFields() + { + fields = fields_create(TestFieldInfo); + } + + ~FxFields() + { + fields_destroy(fields); + } +}; + + +SUITE(fields) +{ + TEST_FIXTURE(FxFields, GetValue_ReturnsNull_OnUnsetString) + { + const char* result = fields_get_value(fields, TestStringValue); + CHECK(result == NULL); + } + + TEST_FIXTURE(FxFields, SetValue_CanRoundtrip) + { + fields_set_value(fields, TestStringValue, "String Value"); + const char* result = fields_get_value(fields, TestStringValue); + CHECK_EQUAL("String Value", result); + } + + TEST_FIXTURE(FxFields, SetValues_CanRoundtrip) + { + Strings values = strings_create(); + fields_set_values(fields, TestListValue, values); + CHECK(values == fields_get_values(fields, TestListValue)); + } +} diff --git a/src/project/tests/project_tests.cpp b/src/project/tests/project_tests.cpp index 9e178c8..691bc5b 100644 --- a/src/project/tests/project_tests.cpp +++ b/src/project/tests/project_tests.cpp @@ -1,234 +1,234 @@ -/** - * \file project_tests.cpp - * \brief Automated tests for the project objects API. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "testing/testing.h" -extern "C" { -#include "project/solution.h" -#include "project/project.h" -#include "project/project_internal.h" -#include "platform/platform.h" -} - - -/** - * \brief Run the project API automated tests. - * \returns OKAY if all tests completed successfully. - */ -int project_tests() -{ - int status = tests_run_suite("fields"); - if (status == OKAY) status = tests_run_suite("project"); - return status; -} - - -struct FxProject -{ - Solution sln; - Project prj; - - FxProject() - { - sln = solution_create(); - prj = project_create(); - } - - ~FxProject() - { - project_destroy(prj); - solution_destroy(sln); - } -}; - - -SUITE(project) -{ - TEST_FIXTURE(FxProject, Create_ReturnsObject_OnSuccess) - { - CHECK(prj != NULL); - } - - - /********************************************************************** - * Name tests - **********************************************************************/ - - TEST_FIXTURE(FxProject, GetName_ReturnsNull_OnStartup) - { - const char* name = project_get_name(prj); - CHECK(name == NULL); - } - - TEST_FIXTURE(FxProject, SetName_CanRoundtrip) - { - project_set_name(prj, "MyProject"); - const char* name = project_get_name(prj); - CHECK_EQUAL("MyProject", name); - } - - - /********************************************************************** - * Base directory tests - **********************************************************************/ - - TEST_FIXTURE(FxProject, GetBaseDir_ReturnsNull_OnStartup) - { - const char* result = project_get_base_dir(prj); - CHECK(result == NULL); - } - - TEST_FIXTURE(FxProject, SetBaseDir_CanRoundtrip) - { - project_set_base_dir(prj, "BaseDir"); - const char* result = project_get_base_dir(prj); - CHECK_EQUAL("BaseDir", result); - } - - - /********************************************************************** - * Configuration filter tests - **********************************************************************/ - - TEST_FIXTURE(FxProject, ConfigurationFilter_ReturnsNull_OnStartup) - { - const char* result = project_get_configuration_filter(prj); - CHECK(result == NULL); - } - - TEST_FIXTURE(FxProject, ConfigurationFilter_CanRoundtrip) - { - project_set_configuration_filter(prj, "Debug"); - const char* result = project_get_configuration_filter(prj); - CHECK_EQUAL("Debug", result); - } - - - /********************************************************************** - * GUID tests - **********************************************************************/ - - TEST_FIXTURE(FxProject, GetGuid_ReturnsNull_OnStartup) - { - const char* result = project_get_guid(prj); - CHECK(result == NULL); - } - - TEST_FIXTURE(FxProject, SetGuid_CanRoundtrip) - { - project_set_guid(prj, "AE2461B7-236F-4278-81D3-F0D476F9A4C0"); - const char* result = project_get_guid(prj); - CHECK_EQUAL("AE2461B7-236F-4278-81D3-F0D476F9A4C0", result); - } - - - /********************************************************************** - * Language tests - **********************************************************************/ - - TEST_FIXTURE(FxProject, GetLanguage_ReturnsNull_OnStartup) - { - const char* result = project_get_language(prj); - CHECK(result == NULL); - } - - TEST_FIXTURE(FxProject, SetLanguage_CanRoundtrip) - { - project_set_language(prj, "c++"); - const char* result = project_get_language(prj); - CHECK_EQUAL("c++", result); - } - - TEST_FIXTURE(FxProject, GetLanguage_ReturnsSolutionLanguage_OnNoProjectLanguage) - { - project_set_solution(prj, sln); - solution_set_language(sln, "c#"); - const char* result = project_get_language(prj); - CHECK_EQUAL("c#", result); - } - - - /********************************************************************** - * Location tests - **********************************************************************/ - - TEST_FIXTURE(FxProject, GetLocation_ReturnsNull_OnStartup) - { - const char* result = project_get_location(prj); - CHECK(result == NULL); - } - - TEST_FIXTURE(FxProject, SetLocation_CanRoundtrip) - { - project_set_location(prj, "Location"); - const char* result = project_get_location(prj); - CHECK_EQUAL("Location", result); - } - - - /********************************************************************** - * Filename tests - **********************************************************************/ - - TEST_FIXTURE(FxProject, GetFilename_ReturnsFullPath_OnNoLocation) - { - project_set_name(prj, "MyProject"); - project_set_base_dir(prj, "/BaseDir"); - const char* filename = project_get_filename(prj, NULL, ".xyz"); - CHECK_EQUAL("/BaseDir/MyProject.xyz", filename); - } - - TEST_FIXTURE(FxProject, GetFilename_ReturnsFullPath_OnLocation) - { - project_set_name(prj, "MyProject"); - project_set_base_dir(prj, "/BaseDir"); - project_set_location(prj, "Location"); - const char* filename = project_get_filename(prj, NULL, ".xyz"); - CHECK_EQUAL("/BaseDir/Location/MyProject.xyz", filename); - } - - - - /********************************************************************** - * Output file tests - **********************************************************************/ - - TEST_FIXTURE(FxProject, GetOutFile_ReturnsProjectName_OnNoTargetAndNotWindows) - { - platform_set(MacOSX); - project_set_name(prj, "MyProject"); - const char* result = project_get_outfile(prj); - CHECK_EQUAL("MyProject", result); - } - - TEST_FIXTURE(FxProject, GetOutFile_AddsExe_OnNoTargetAndWindows) - { - platform_set(Windows); - project_set_name(prj, "MyProject"); - const char* result = project_get_outfile(prj); - CHECK_EQUAL("MyProject.exe", result); - } - - - /********************************************************************** - * Solution tests - **********************************************************************/ - - TEST_FIXTURE(FxProject, GetSolution_ReturnsNull_OnStartup) - { - Solution result = project_get_solution(prj); - CHECK(result == NULL); - } - - TEST_FIXTURE(FxProject, SetSolution_CanRoundtrip) - { - project_set_solution(prj, sln); - CHECK(sln == project_get_solution(prj)); - } - -} - - +/** + * \file project_tests.cpp + * \brief Automated tests for the project objects API. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "testing/testing.h" +extern "C" { +#include "project/solution.h" +#include "project/project.h" +#include "project/project_internal.h" +#include "platform/platform.h" +} + + +/** + * \brief Run the project API automated tests. + * \returns OKAY if all tests completed successfully. + */ +int project_tests() +{ + int status = tests_run_suite("fields"); + if (status == OKAY) status = tests_run_suite("project"); + return status; +} + + +struct FxProject +{ + Solution sln; + Project prj; + + FxProject() + { + sln = solution_create(); + prj = project_create(); + } + + ~FxProject() + { + project_destroy(prj); + solution_destroy(sln); + } +}; + + +SUITE(project) +{ + TEST_FIXTURE(FxProject, Create_ReturnsObject_OnSuccess) + { + CHECK(prj != NULL); + } + + + /********************************************************************** + * Name tests + **********************************************************************/ + + TEST_FIXTURE(FxProject, GetName_ReturnsNull_OnStartup) + { + const char* name = project_get_name(prj); + CHECK(name == NULL); + } + + TEST_FIXTURE(FxProject, SetName_CanRoundtrip) + { + project_set_name(prj, "MyProject"); + const char* name = project_get_name(prj); + CHECK_EQUAL("MyProject", name); + } + + + /********************************************************************** + * Base directory tests + **********************************************************************/ + + TEST_FIXTURE(FxProject, GetBaseDir_ReturnsNull_OnStartup) + { + const char* result = project_get_base_dir(prj); + CHECK(result == NULL); + } + + TEST_FIXTURE(FxProject, SetBaseDir_CanRoundtrip) + { + project_set_base_dir(prj, "BaseDir"); + const char* result = project_get_base_dir(prj); + CHECK_EQUAL("BaseDir", result); + } + + + /********************************************************************** + * Configuration filter tests + **********************************************************************/ + + TEST_FIXTURE(FxProject, ConfigurationFilter_ReturnsNull_OnStartup) + { + const char* result = project_get_configuration_filter(prj); + CHECK(result == NULL); + } + + TEST_FIXTURE(FxProject, ConfigurationFilter_CanRoundtrip) + { + project_set_configuration_filter(prj, "Debug"); + const char* result = project_get_configuration_filter(prj); + CHECK_EQUAL("Debug", result); + } + + + /********************************************************************** + * GUID tests + **********************************************************************/ + + TEST_FIXTURE(FxProject, GetGuid_ReturnsNull_OnStartup) + { + const char* result = project_get_guid(prj); + CHECK(result == NULL); + } + + TEST_FIXTURE(FxProject, SetGuid_CanRoundtrip) + { + project_set_guid(prj, "AE2461B7-236F-4278-81D3-F0D476F9A4C0"); + const char* result = project_get_guid(prj); + CHECK_EQUAL("AE2461B7-236F-4278-81D3-F0D476F9A4C0", result); + } + + + /********************************************************************** + * Language tests + **********************************************************************/ + + TEST_FIXTURE(FxProject, GetLanguage_ReturnsNull_OnStartup) + { + const char* result = project_get_language(prj); + CHECK(result == NULL); + } + + TEST_FIXTURE(FxProject, SetLanguage_CanRoundtrip) + { + project_set_language(prj, "c++"); + const char* result = project_get_language(prj); + CHECK_EQUAL("c++", result); + } + + TEST_FIXTURE(FxProject, GetLanguage_ReturnsSolutionLanguage_OnNoProjectLanguage) + { + project_set_solution(prj, sln); + solution_set_language(sln, "c#"); + const char* result = project_get_language(prj); + CHECK_EQUAL("c#", result); + } + + + /********************************************************************** + * Location tests + **********************************************************************/ + + TEST_FIXTURE(FxProject, GetLocation_ReturnsNull_OnStartup) + { + const char* result = project_get_location(prj); + CHECK(result == NULL); + } + + TEST_FIXTURE(FxProject, SetLocation_CanRoundtrip) + { + project_set_location(prj, "Location"); + const char* result = project_get_location(prj); + CHECK_EQUAL("Location", result); + } + + + /********************************************************************** + * Filename tests + **********************************************************************/ + + TEST_FIXTURE(FxProject, GetFilename_ReturnsFullPath_OnNoLocation) + { + project_set_name(prj, "MyProject"); + project_set_base_dir(prj, "/BaseDir"); + const char* filename = project_get_filename(prj, NULL, ".xyz"); + CHECK_EQUAL("/BaseDir/MyProject.xyz", filename); + } + + TEST_FIXTURE(FxProject, GetFilename_ReturnsFullPath_OnLocation) + { + project_set_name(prj, "MyProject"); + project_set_base_dir(prj, "/BaseDir"); + project_set_location(prj, "Location"); + const char* filename = project_get_filename(prj, NULL, ".xyz"); + CHECK_EQUAL("/BaseDir/Location/MyProject.xyz", filename); + } + + + + /********************************************************************** + * Output file tests + **********************************************************************/ + + TEST_FIXTURE(FxProject, GetOutFile_ReturnsProjectName_OnNoTargetAndNotWindows) + { + platform_set(MacOSX); + project_set_name(prj, "MyProject"); + const char* result = project_get_outfile(prj); + CHECK_EQUAL("MyProject", result); + } + + TEST_FIXTURE(FxProject, GetOutFile_AddsExe_OnNoTargetAndWindows) + { + platform_set(Windows); + project_set_name(prj, "MyProject"); + const char* result = project_get_outfile(prj); + CHECK_EQUAL("MyProject.exe", result); + } + + + /********************************************************************** + * Solution tests + **********************************************************************/ + + TEST_FIXTURE(FxProject, GetSolution_ReturnsNull_OnStartup) + { + Solution result = project_get_solution(prj); + CHECK(result == NULL); + } + + TEST_FIXTURE(FxProject, SetSolution_CanRoundtrip) + { + project_set_solution(prj, sln); + CHECK(sln == project_get_solution(prj)); + } + +} + + diff --git a/src/project/tests/solution_tests.cpp b/src/project/tests/solution_tests.cpp index 12510d6..e7023c9 100644 --- a/src/project/tests/solution_tests.cpp +++ b/src/project/tests/solution_tests.cpp @@ -1,206 +1,206 @@ -/** - * \file solution_tests.cpp - * \brief Automated tests for the Solution class. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "testing/testing.h" -extern "C" { -#include "project/solution.h" -#include "project/project.h" -#include "project/project_internal.h" -#include "base/strings.h" -} - - -struct FxSolution -{ - Solution sln; - - FxSolution() - { - sln = solution_create(); - } - - ~FxSolution() - { - if (sln) - solution_destroy(sln); - } -}; - - -SUITE(project) -{ - TEST_FIXTURE(FxSolution, Create_ReturnsObject_OnSuccess) - { - CHECK(sln != NULL); - } - - - /********************************************************************** - * Name tests - **********************************************************************/ - - TEST_FIXTURE(FxSolution, GetName_ReturnsNull_OnStartup) - { - const char* name = solution_get_name(sln); - CHECK(name == NULL); - } - - TEST_FIXTURE(FxSolution, SetName_CanRoundtrip) - { - solution_set_name(sln, "MySolution"); - const char* name = solution_get_name(sln); - CHECK_EQUAL("MySolution", name); - } - - - /********************************************************************** - * Base directory tests - **********************************************************************/ - - TEST_FIXTURE(FxSolution, GetBaseDir_ReturnsNull_OnStartup) - { - const char* result = solution_get_base_dir(sln); - CHECK(result == NULL); - } - - TEST_FIXTURE(FxSolution, SetBaseDir_CanRoundtrip) - { - solution_set_base_dir(sln, "BaseDir"); - const char* result = solution_get_base_dir(sln); - CHECK_EQUAL("BaseDir", result); - } - - - /********************************************************************** - * Configuration containment tests - **********************************************************************/ - - TEST_FIXTURE(FxSolution, NumConfigs_IsZero_OnStartup) - { - int result = solution_num_configs(sln); - CHECK(result == 0); - } - - TEST_FIXTURE(FxSolution, AddConfig_IncrementsNumConfigs) - { - solution_add_config_name(sln, "Debug"); - int result = solution_num_configs(sln); - CHECK(result == 1); - } - - TEST_FIXTURE(FxSolution, AddConfig_CanRoundtrip) - { - solution_add_config_name(sln, "Debug"); - const char* result = solution_get_config_name(sln, 0); - CHECK_EQUAL("Debug", result); - } - - TEST_FIXTURE(FxSolution, GetConfigs_ReturnsEmptyList_OnStartup) - { - Strings result = solution_get_config_names(sln); - CHECK(strings_size(result) == 0); - } - - TEST_FIXTURE(FxSolution, GetConfigs_ReturnsList_OnItemsAdded) - { - solution_add_config_name(sln, "Debug"); - Strings result = solution_get_config_names(sln); - CHECK_EQUAL("Debug", strings_item(result, 0)); - } - - - /********************************************************************** - * Language tests - **********************************************************************/ - - TEST_FIXTURE(FxSolution, GetLanguage_ReturnsNull_OnStartup) - { - const char* result = solution_get_language(sln); - CHECK(result == NULL); - } - - TEST_FIXTURE(FxSolution, SetLanguage_CanRoundtrip) - { - solution_set_language(sln, "c++"); - const char* result = solution_get_language(sln); - CHECK_EQUAL("c++", result); - } - - - /********************************************************************** - * Location tests - **********************************************************************/ - - TEST_FIXTURE(FxSolution, GetLocation_ReturnsNull_OnStartup) - { - const char* result = solution_get_location(sln); - CHECK(result == NULL); - } - - TEST_FIXTURE(FxSolution, SetLocation_CanRoundtrip) - { - solution_set_location(sln, "Location"); - const char* result = solution_get_location(sln); - CHECK_EQUAL("Location", result); - } - - - /********************************************************************** - * Filename tests - **********************************************************************/ - - TEST_FIXTURE(FxSolution, GetFilename_ReturnsFullPath_OnNoLocation) - { - solution_set_name(sln, "MySolution"); - solution_set_base_dir(sln, "/BaseDir"); - const char* filename = solution_get_filename(sln, NULL, ".xyz"); - CHECK_EQUAL("/BaseDir/MySolution.xyz", filename); - } - - TEST_FIXTURE(FxSolution, GetFilename_ReturnsFullPath_OnLocation) - { - solution_set_name(sln, "MySolution"); - solution_set_base_dir(sln, "/BaseDir"); - solution_set_location(sln, "Location"); - const char* filename = solution_get_filename(sln, NULL, ".xyz"); - CHECK_EQUAL("/BaseDir/Location/MySolution.xyz", filename); - } - - - /********************************************************************** - * Project containment tests - **********************************************************************/ - - TEST_FIXTURE(FxSolution, NumProjects_IsZero_OnStartup) - { - int result = solution_num_projects(sln); - CHECK(result == 0); - } - - TEST_FIXTURE(FxSolution, AddProject_IncrementsNumProjects) - { - Project prj = project_create(); - solution_add_project(sln, prj); - int result = solution_num_projects(sln); - CHECK(result == 1); - } - - TEST_FIXTURE(FxSolution, AddProject_CanRoundtrip) - { - Project prj = project_create(); - solution_add_project(sln, prj); - Project result = solution_get_project(sln, 0); - CHECK(prj == result); - } - - TEST_FIXTURE(FxSolution, AddProject_SetsProjectSolution) - { - Project prj = project_create(); - solution_add_project(sln, prj); - CHECK(sln == project_get_solution(prj)); - } -} +/** + * \file solution_tests.cpp + * \brief Automated tests for the Solution class. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "testing/testing.h" +extern "C" { +#include "project/solution.h" +#include "project/project.h" +#include "project/project_internal.h" +#include "base/strings.h" +} + + +struct FxSolution +{ + Solution sln; + + FxSolution() + { + sln = solution_create(); + } + + ~FxSolution() + { + if (sln) + solution_destroy(sln); + } +}; + + +SUITE(project) +{ + TEST_FIXTURE(FxSolution, Create_ReturnsObject_OnSuccess) + { + CHECK(sln != NULL); + } + + + /********************************************************************** + * Name tests + **********************************************************************/ + + TEST_FIXTURE(FxSolution, GetName_ReturnsNull_OnStartup) + { + const char* name = solution_get_name(sln); + CHECK(name == NULL); + } + + TEST_FIXTURE(FxSolution, SetName_CanRoundtrip) + { + solution_set_name(sln, "MySolution"); + const char* name = solution_get_name(sln); + CHECK_EQUAL("MySolution", name); + } + + + /********************************************************************** + * Base directory tests + **********************************************************************/ + + TEST_FIXTURE(FxSolution, GetBaseDir_ReturnsNull_OnStartup) + { + const char* result = solution_get_base_dir(sln); + CHECK(result == NULL); + } + + TEST_FIXTURE(FxSolution, SetBaseDir_CanRoundtrip) + { + solution_set_base_dir(sln, "BaseDir"); + const char* result = solution_get_base_dir(sln); + CHECK_EQUAL("BaseDir", result); + } + + + /********************************************************************** + * Configuration containment tests + **********************************************************************/ + + TEST_FIXTURE(FxSolution, NumConfigs_IsZero_OnStartup) + { + int result = solution_num_configs(sln); + CHECK(result == 0); + } + + TEST_FIXTURE(FxSolution, AddConfig_IncrementsNumConfigs) + { + solution_add_config_name(sln, "Debug"); + int result = solution_num_configs(sln); + CHECK(result == 1); + } + + TEST_FIXTURE(FxSolution, AddConfig_CanRoundtrip) + { + solution_add_config_name(sln, "Debug"); + const char* result = solution_get_config_name(sln, 0); + CHECK_EQUAL("Debug", result); + } + + TEST_FIXTURE(FxSolution, GetConfigs_ReturnsEmptyList_OnStartup) + { + Strings result = solution_get_config_names(sln); + CHECK(strings_size(result) == 0); + } + + TEST_FIXTURE(FxSolution, GetConfigs_ReturnsList_OnItemsAdded) + { + solution_add_config_name(sln, "Debug"); + Strings result = solution_get_config_names(sln); + CHECK_EQUAL("Debug", strings_item(result, 0)); + } + + + /********************************************************************** + * Language tests + **********************************************************************/ + + TEST_FIXTURE(FxSolution, GetLanguage_ReturnsNull_OnStartup) + { + const char* result = solution_get_language(sln); + CHECK(result == NULL); + } + + TEST_FIXTURE(FxSolution, SetLanguage_CanRoundtrip) + { + solution_set_language(sln, "c++"); + const char* result = solution_get_language(sln); + CHECK_EQUAL("c++", result); + } + + + /********************************************************************** + * Location tests + **********************************************************************/ + + TEST_FIXTURE(FxSolution, GetLocation_ReturnsNull_OnStartup) + { + const char* result = solution_get_location(sln); + CHECK(result == NULL); + } + + TEST_FIXTURE(FxSolution, SetLocation_CanRoundtrip) + { + solution_set_location(sln, "Location"); + const char* result = solution_get_location(sln); + CHECK_EQUAL("Location", result); + } + + + /********************************************************************** + * Filename tests + **********************************************************************/ + + TEST_FIXTURE(FxSolution, GetFilename_ReturnsFullPath_OnNoLocation) + { + solution_set_name(sln, "MySolution"); + solution_set_base_dir(sln, "/BaseDir"); + const char* filename = solution_get_filename(sln, NULL, ".xyz"); + CHECK_EQUAL("/BaseDir/MySolution.xyz", filename); + } + + TEST_FIXTURE(FxSolution, GetFilename_ReturnsFullPath_OnLocation) + { + solution_set_name(sln, "MySolution"); + solution_set_base_dir(sln, "/BaseDir"); + solution_set_location(sln, "Location"); + const char* filename = solution_get_filename(sln, NULL, ".xyz"); + CHECK_EQUAL("/BaseDir/Location/MySolution.xyz", filename); + } + + + /********************************************************************** + * Project containment tests + **********************************************************************/ + + TEST_FIXTURE(FxSolution, NumProjects_IsZero_OnStartup) + { + int result = solution_num_projects(sln); + CHECK(result == 0); + } + + TEST_FIXTURE(FxSolution, AddProject_IncrementsNumProjects) + { + Project prj = project_create(); + solution_add_project(sln, prj); + int result = solution_num_projects(sln); + CHECK(result == 1); + } + + TEST_FIXTURE(FxSolution, AddProject_CanRoundtrip) + { + Project prj = project_create(); + solution_add_project(sln, prj); + Project result = solution_get_project(sln, 0); + CHECK(prj == result); + } + + TEST_FIXTURE(FxSolution, AddProject_SetsProjectSolution) + { + Project prj = project_create(); + solution_add_project(sln, prj); + CHECK(sln == project_get_solution(prj)); + } +} diff --git a/src/script/fn_accessor.c b/src/script/fn_accessor.c index 840731e..858c51f 100644 --- a/src/script/fn_accessor.c +++ b/src/script/fn_accessor.c @@ -1,229 +1,226 @@ -/** - * \file fn_accessor.c - * \brief A generic getter/setter for project fields. - * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "script_internal.h" -#include "base/cstr.h" -#include "base/error.h" - - -static int fn_accessor(lua_State* L); -static int fn_accessor_object_has_field(struct FieldInfo* fields, const char* field_name); -static int fn_accessor_register(lua_State* L, struct FieldInfo* fields); -static int fn_accessor_register_field(lua_State* L, struct FieldInfo* field); -static int fn_accessor_set_string_value(lua_State* L, struct FieldInfo* field); -static int fn_accessor_set_list_value(lua_State* L, struct FieldInfo* field); -static void fn_accessor_append_value(lua_State* L, struct FieldInfo* field, int tbl, int idx); - - -/** - * Using the field information lists for each of the project objects (solution, project, - * and configuration) register accessor functions in the script environment. Examples of - * accessor functions include location(), language(), kind(), and so on; function that - * get and set the project object properties. - * \returns OKAY if successful. - */ -int fn_accessor_register_all(lua_State* L) -{ - int z = OKAY; - if (z == OKAY) z = fn_accessor_register(L, SolutionFieldInfo); - if (z == OKAY) z = fn_accessor_register(L, ProjectFieldInfo); - return z; -} - - -/** - * Register the accessor functions for a particular set of fields. - * \returns OKAY if successful. - */ -static int fn_accessor_register(lua_State* L, struct FieldInfo* fields) -{ - int i, z = OKAY; - - for (i = 0; z == OKAY && fields[i].name != NULL; ++i) - { - z = fn_accessor_register_field(L, &fields[i]); - } - - return z; -} - - -/** - * Register a single accessor function. - * \returns OKAY if successful. - */ -static int fn_accessor_register_field(lua_State* L, struct FieldInfo* field) -{ - int container_type, z; - - /* has this accessor already been registered? This will happen if two object - * types (ie. solution and project) define the same property. If so, skip it */ - lua_getglobal(L, field->name); - z = lua_isnil(L, -1); - lua_pop(L, 1); - if (!z) return OKAY; - - /* figure out what object types this accessor applies to; may be more than one */ - container_type = 0; - if (fn_accessor_object_has_field(SolutionFieldInfo, field->name)) container_type |= SolutionObject; - if (fn_accessor_object_has_field(ProjectFieldInfo, field->name)) container_type |= ProjectObject; - - /* register the accessor function */ - lua_pushnumber(L, container_type); - lua_pushlightuserdata(L, field); - lua_pushcclosure(L, fn_accessor, 2); - lua_setglobal(L, field->name); - return OKAY; -} - - -/** - * Determine if a field list contains a field with a particular name. - * \returns True if the field is contained by the list. - */ -static int fn_accessor_object_has_field(struct FieldInfo* fields, const char* field_name) -{ - int i; - for (i = 0; fields[i].name != NULL; ++i) - { - if (cstr_eq(fields[i].name, field_name)) - return 1; - } - return 0; -} - - -/** - * The accessor script function; all of the individually registered accessors - * (location(), language(), etc.) point to here, and this is where all of the - * work gets done to get or set an object property or list. - * \returns The current value of the field. - */ -static int fn_accessor(lua_State* L) -{ - struct FieldInfo* field; - int container_type; - - /* get the required container object */ - container_type = lua_tointeger(L, lua_upvalueindex(1)); - if (!script_internal_get_active_object(L, container_type, REQUIRED)) - { - return 0; - } - - /* get information about the field being accessed */ - field = (struct FieldInfo*)lua_touserdata(L, lua_upvalueindex(2)); - - /* if a value is provided, set the field */ - if (lua_gettop(L) > 1) - { - if (field->kind == StringField) - { - fn_accessor_set_string_value(L, field); - } - else - { - fn_accessor_set_list_value(L, field); - } - } - - /* return the current value of the field */ - lua_getfield(L, -1, field->name); - return 1; -} - - -/** - * Sets a string field to the value on the bottom of the Lua stack. - * \returns OKAY if successful. - */ -static int fn_accessor_set_string_value(lua_State* L, struct FieldInfo* field) -{ - /* can't set lists to simple fields */ - if (lua_istable(L, 1)) - { - luaL_error(L, "the field '%s' does not support lists of values", field->name); - return !OKAY; - } - - /* if a validator function is present, call it */ - if (field->validator != NULL) - { - const char* value = luaL_checkstring(L, 1); - if (!field->validator(value)) - { - luaL_error(L, "invalid value '%s'", value); - return !OKAY; - } - } - - /* set the field */ - lua_pushvalue(L, 1); - lua_setfield(L, -2, field->name); - return OKAY; -} - - -/** - * Appends the value or list at the bottom of the Lua stack to the specified list field. - * \returns OKAY if successful. - */ -static int fn_accessor_set_list_value(lua_State* L, struct FieldInfo* field) -{ - /* get the current value of the field */ - lua_getfield(L, -1, field->name); - - /* move the values into the field */ - fn_accessor_append_value(L, field, lua_gettop(L), 1); - - /* remove the field value from the stack */ - lua_pop(L, 1); - return OKAY; -} - - -/** - * Append a value to table. If the value is itself a table, it is "flattened" into the - * destination table by iterating over each of its items and adding each in turn to the - * target table. - * \param L The current Lua state. - * \param field A description of the field being populated. - * \param tbl The table to contain the values. - * \param idx The value to add to the table. - */ -static void fn_accessor_append_value(lua_State* L, struct FieldInfo* field, int tbl, int idx) -{ - int i, n; - if (lua_istable(L, idx)) - { - n = luaL_getn(L, idx); - for (i = 1; i <= n; ++i) - { - lua_rawgeti(L, idx, i); - fn_accessor_append_value(L, field, tbl, lua_gettop(L)); - } - lua_pop(L, 1); - } - else - { - /* if this field contains files, check for and expand wildcards by calling match() */ - const char* value = lua_tostring(L, -1); - if (field->kind == FilesField && cstr_contains(value, "*")) - { - lua_getglobal(L, "match"); - lua_pushvalue(L, -2); - lua_call(L, 1, 1); - fn_accessor_append_value(L, field, tbl, lua_gettop(L)); - lua_pop(L, 1); - } - else - { - n = luaL_getn(L, tbl); - lua_rawseti(L, tbl, n + 1); - } - } -} +/** + * \file fn_accessor.c + * \brief A generic getter/setter for project fields. + * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "script_internal.h" +#include "base/cstr.h" +#include "base/error.h" + + +static int fn_accessor_object_has_field(struct FieldInfo* fields, const char* field_name); +static int fn_accessor_register(lua_State* L, struct FieldInfo* fields); +static int fn_accessor_register_field(lua_State* L, struct FieldInfo* field); +static void fn_accessor_append_value(lua_State* L, struct FieldInfo* field, int tbl, int idx); + + +/** + * Using the field information lists for each of the project objects (solution, project, + * and configuration) register accessor functions in the script environment. Examples of + * accessor functions include location(), language(), kind(), and so on; function that + * get and set the project object properties. + * \returns OKAY if successful. + */ +int fn_accessor_register_all(lua_State* L) +{ + int z = OKAY; + if (z == OKAY) z = fn_accessor_register(L, SolutionFieldInfo); + if (z == OKAY) z = fn_accessor_register(L, ProjectFieldInfo); + return z; +} + + +/** + * Register the accessor functions for a particular set of fields. + * \returns OKAY if successful. + */ +static int fn_accessor_register(lua_State* L, struct FieldInfo* fields) +{ + int i, z = OKAY; + + for (i = 0; z == OKAY && fields[i].name != NULL; ++i) + { + z = fn_accessor_register_field(L, &fields[i]); + } + + return z; +} + + +/** + * Register a single accessor function. + * \returns OKAY if successful. + */ +static int fn_accessor_register_field(lua_State* L, struct FieldInfo* field) +{ + int container_type, z; + + /* has this accessor already been registered? This will happen if two object + * types (ie. solution and project) define the same property. If so, skip it */ + lua_getglobal(L, field->name); + z = lua_isnil(L, -1); + lua_pop(L, 1); + if (!z) return OKAY; + + /* figure out what object types this accessor applies to; may be more than one */ + container_type = 0; + if (fn_accessor_object_has_field(SolutionFieldInfo, field->name)) container_type |= SolutionObject; + if (fn_accessor_object_has_field(ProjectFieldInfo, field->name)) container_type |= ProjectObject; + + /* register the accessor function */ + lua_pushnumber(L, container_type); + lua_pushlightuserdata(L, field); + lua_pushcclosure(L, fn_accessor, 2); + lua_setglobal(L, field->name); + return OKAY; +} + + +/** + * Determine if a field list contains a field with a particular name. + * \returns True if the field is contained by the list. + */ +static int fn_accessor_object_has_field(struct FieldInfo* fields, const char* field_name) +{ + int i; + for (i = 0; fields[i].name != NULL; ++i) + { + if (cstr_eq(fields[i].name, field_name)) + return 1; + } + return 0; +} + + +/** + * The accessor script function; all of the individually registered accessors + * (location(), language(), etc.) point to here, and this is where all of the + * work gets done to get or set an object property or list. + * \returns The current value of the field. + */ +int fn_accessor(lua_State* L) +{ + struct FieldInfo* field; + int container_type; + + /* get the required container object */ + container_type = lua_tointeger(L, lua_upvalueindex(1)); + if (!script_internal_get_active_object(L, container_type, REQUIRED)) + { + return 0; + } + + /* get information about the field being accessed */ + field = (struct FieldInfo*)lua_touserdata(L, lua_upvalueindex(2)); + + /* if a value is provided, set the field */ + if (lua_gettop(L) > 1) + { + if (field->kind == StringField) + { + fn_accessor_set_string_value(L, field); + } + else + { + fn_accessor_set_list_value(L, field); + } + } + + /* return the current value of the field */ + lua_getfield(L, -1, field->name); + return 1; +} + + +/** + * Sets a string field to the value on the bottom of the Lua stack. + * \returns OKAY if successful. + */ +int fn_accessor_set_string_value(lua_State* L, struct FieldInfo* field) +{ + /* can't set lists to simple fields */ + if (lua_istable(L, 1)) + { + luaL_error(L, "the field '%s' does not support lists of values", field->name); + return !OKAY; + } + + /* if a validator function is present, call it */ + if (field->validator != NULL) + { + const char* value = luaL_checkstring(L, 1); + if (!field->validator(value)) + { + luaL_error(L, "invalid value '%s'", value); + return !OKAY; + } + } + + /* set the field */ + lua_pushvalue(L, 1); + lua_setfield(L, -2, field->name); + return OKAY; +} + + +/** + * Appends the value or list at the bottom of the Lua stack to the specified list field. + * \returns OKAY if successful. + */ +int fn_accessor_set_list_value(lua_State* L, struct FieldInfo* field) +{ + /* get the current value of the field */ + lua_getfield(L, -1, field->name); + + /* move the values into the field */ + fn_accessor_append_value(L, field, lua_gettop(L), 1); + + /* remove the field value from the stack */ + lua_pop(L, 1); + return OKAY; +} + + +/** + * Append a value to table. If the value is itself a table, it is "flattened" into the + * destination table by iterating over each of its items and adding each in turn to the + * target table. + * \param L The current Lua state. + * \param field A description of the field being populated. + * \param tbl The table to contain the values. + * \param idx The value to add to the table. + */ +static void fn_accessor_append_value(lua_State* L, struct FieldInfo* field, int tbl, int idx) +{ + int i, n; + if (lua_istable(L, idx)) + { + n = luaL_getn(L, idx); + for (i = 1; i <= n; ++i) + { + lua_rawgeti(L, idx, i); + fn_accessor_append_value(L, field, tbl, lua_gettop(L)); + } + lua_pop(L, 1); + } + else + { + /* if this field contains files, check for and expand wildcards by calling match() */ + const char* value = lua_tostring(L, -1); + if (field->kind == FilesField && cstr_contains(value, "*")) + { + lua_getglobal(L, "match"); + lua_pushvalue(L, -2); + lua_call(L, 1, 1); + fn_accessor_append_value(L, field, tbl, lua_gettop(L)); + lua_pop(L, 1); + } + else + { + n = luaL_getn(L, tbl); + lua_rawseti(L, tbl, n + 1); + } + } +} diff --git a/src/script/fn_configurations.c b/src/script/fn_configurations.c new file mode 100644 index 0000000..249805f --- /dev/null +++ b/src/script/fn_configurations.c @@ -0,0 +1,43 @@ +/** + * \file fn_configurations.c + * \brief Specify the build configurations. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "script_internal.h" + + +/** + * Specify the build configurations for a solution. + */ +int fn_configurations(lua_State* L) +{ + struct FieldInfo* field; + + if (!script_internal_get_active_object(L, SolutionObject, REQUIRED)) + { + return 0; + } + + /* configurations may not be modified once projects are defined */ + lua_getfield(L, -1, PROJECTS_KEY); + if (luaL_getn(L, -1) > 0) + { + luaL_error(L, "configurations may not be modified after projects are defined"); + } + lua_pop(L, 1); + + /* get information about the field being accessed */ + field = (struct FieldInfo*)lua_touserdata(L, lua_upvalueindex(2)); + + /* if a value is provided, set the field */ + if (lua_gettop(L) > 1) + { + fn_accessor_set_list_value(L, &SolutionFieldInfo[SolutionConfigurations]); + } + + /* return the current value of the field */ + lua_getfield(L, -1, SolutionFieldInfo[SolutionConfigurations].name); + return 1; +} diff --git a/src/script/fn_dofile.c b/src/script/fn_dofile.c index f10f324..4d0ffc0 100644 --- a/src/script/fn_dofile.c +++ b/src/script/fn_dofile.c @@ -1,76 +1,76 @@ -/** - * \file fn_dofile.c - * \brief A custom implementation of dofile(). - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "script_internal.h" -#include "base/dir.h" -#include "base/path.h" -#include "base/string.h" - - -/** - * Replacement implementation for Lua's dofile() function; manages Premake specific - * features like the _FILE variable, and makes sure the directory containing the - * running script is kept current. - */ -int fn_dofile(lua_State* L) -{ - const char *filename; - const char* full_path; - const char* script_dir; - String old_file; - String old_working_dir; - int top, result; - - filename = luaL_checkstring(L, 1); - - /* remember the previous file that was being run; will restore after script runs */ - lua_getglobal(L, FILE_KEY); - old_file = string_create(lua_tostring(L, -1)); - lua_pop(L, 1); - - /* remember the current working directory; will restore after script runs */ - old_working_dir = string_create(dir_get_current()); - - /* set the _FILE global to the full path of the script being run */ - full_path = path_absolute(filename); - lua_pushstring(L, full_path); - lua_setglobal(L, FILE_KEY); - - /* make the script directory the current directory */ - script_dir = path_directory(full_path); - dir_set_current(script_dir); - - /* I'll need this to figure the number of return values later */ - top = lua_gettop(L); - - /* use absolute path to run script so full path will be shown in error messages */ - full_path = path_translate(full_path, NULL); - result = luaL_loadfile(L, full_path); - if (result == OKAY) - { - lua_call(L, 0, LUA_MULTRET); - } - - /* restore the previous working directory */ - dir_set_current(string_cstr(old_working_dir)); - - /* restore the previous file value */ - lua_pushstring(L, string_cstr(old_file)); - lua_setglobal(L, FILE_KEY); - - /* clean up */ - string_destroy(old_working_dir); - string_destroy(old_file); - - if (result != OKAY) - { - lua_error(L); - } - - /* return the number of values returned by the script */ - return lua_gettop(L) - top; -} +/** + * \file fn_dofile.c + * \brief A custom implementation of dofile(). + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "script_internal.h" +#include "base/dir.h" +#include "base/path.h" +#include "base/string.h" + + +/** + * Replacement implementation for Lua's dofile() function; manages Premake specific + * features like the _FILE variable, and makes sure the directory containing the + * running script is kept current. + */ +int fn_dofile(lua_State* L) +{ + const char *filename; + const char* full_path; + const char* script_dir; + String old_file; + String old_working_dir; + int top, result; + + filename = luaL_checkstring(L, 1); + + /* remember the previous file that was being run; will restore after script runs */ + lua_getglobal(L, FILE_KEY); + old_file = string_create(lua_tostring(L, -1)); + lua_pop(L, 1); + + /* remember the current working directory; will restore after script runs */ + old_working_dir = string_create(dir_get_current()); + + /* set the _FILE global to the full path of the script being run */ + full_path = path_absolute(filename); + lua_pushstring(L, full_path); + lua_setglobal(L, FILE_KEY); + + /* make the script directory the current directory */ + script_dir = path_directory(full_path); + dir_set_current(script_dir); + + /* I'll need this to figure the number of return values later */ + top = lua_gettop(L); + + /* use absolute path to run script so full path will be shown in error messages */ + full_path = path_translate(full_path, NULL); + result = luaL_loadfile(L, full_path); + if (result == OKAY) + { + lua_call(L, 0, LUA_MULTRET); + } + + /* restore the previous working directory */ + dir_set_current(string_cstr(old_working_dir)); + + /* restore the previous file value */ + lua_pushstring(L, string_cstr(old_file)); + lua_setglobal(L, FILE_KEY); + + /* clean up */ + string_destroy(old_working_dir); + string_destroy(old_file); + + if (result != OKAY) + { + lua_error(L); + } + + /* return the number of values returned by the script */ + return lua_gettop(L) - top; +} diff --git a/src/script/fn_error.c b/src/script/fn_error.c index a63d5b9..0b00add 100644 --- a/src/script/fn_error.c +++ b/src/script/fn_error.c @@ -1,21 +1,21 @@ -/** - * \file fn_error.c - * \brief Script error handler. - * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "script_internal.h" -#include "base/error.h" - - -/** - * Handler for errors reported out the script; copies the error message to - * Premake's global error state. - */ -int fn_error(lua_State* L) -{ - const char* message = lua_tostring(L, 1); - error_set(message); - return 0; -} +/** + * \file fn_error.c + * \brief Script error handler. + * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "script_internal.h" +#include "base/error.h" + + +/** + * Handler for errors reported out the script; copies the error message to + * Premake's global error state. + */ +int fn_error(lua_State* L) +{ + const char* message = lua_tostring(L, 1); + error_set(message); + return 0; +} diff --git a/src/script/fn_getcwd.c b/src/script/fn_getcwd.c index 9d2fa67..47d1a20 100644 --- a/src/script/fn_getcwd.c +++ b/src/script/fn_getcwd.c @@ -1,20 +1,20 @@ -/** - * \file fn_getcwd.c - * \brief os.getcwd() returns the current working directory. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "script_internal.h" -#include "base/dir.h" - - -/** - * Implementation of os.getcwd(): returns the current working directory. - */ -int fn_getcwd(lua_State* L) -{ - const char* cwd = dir_get_current(); - lua_pushstring(L, cwd); - return 1; -} +/** + * \file fn_getcwd.c + * \brief os.getcwd() returns the current working directory. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "script_internal.h" +#include "base/dir.h" + + +/** + * Implementation of os.getcwd(): returns the current working directory. + */ +int fn_getcwd(lua_State* L) +{ + const char* cwd = dir_get_current(); + lua_pushstring(L, cwd); + return 1; +} diff --git a/src/script/fn_include.c b/src/script/fn_include.c index 7208881..f2abc1e 100644 --- a/src/script/fn_include.c +++ b/src/script/fn_include.c @@ -1,26 +1,26 @@ -/** - * \file fn_include.c - * \brief Include an directory in the script, running the contained "premake4.lua". - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "script_internal.h" -#include "base/path.h" - - -/** - * Include a directory into the current script, calling the enclosed "premake4.lua". - * This is a shortcut for `dofile("some_directory/premake4.lua")`. - */ -int fn_include(lua_State* L) -{ - /* append default file name to the passed in path */ - const char* directory = luaL_checkstring(L, 1); - const char* path = path_join(directory, DEFAULT_SCRIPT_NAME); - - /* then pass it to dofile() */ - lua_pop(L, 1); - lua_pushstring(L, path); - return fn_dofile(L); -} +/** + * \file fn_include.c + * \brief Include an directory in the script, running the contained "premake4.lua". + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "script_internal.h" +#include "base/path.h" + + +/** + * Include a directory into the current script, calling the enclosed "premake4.lua". + * This is a shortcut for `dofile("some_directory/premake4.lua")`. + */ +int fn_include(lua_State* L) +{ + /* append default file name to the passed in path */ + const char* directory = luaL_checkstring(L, 1); + const char* path = path_join(directory, DEFAULT_SCRIPT_NAME); + + /* then pass it to dofile() */ + lua_pop(L, 1); + lua_pushstring(L, path); + return fn_dofile(L); +} diff --git a/src/script/fn_project.c b/src/script/fn_project.c index 851154e..c690555 100644 --- a/src/script/fn_project.c +++ b/src/script/fn_project.c @@ -1,72 +1,81 @@ -/** - * \file fn_project.c - * \brief Create or select a project object. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "script_internal.h" -#include "base/guid.h" - - -/** - * Create a new project object, or select an existing one. - */ -int fn_project(lua_State* L) -{ - const char* name; - - /* if there are no parameters, return the active project */ - if (lua_gettop(L) == 0) - { - script_internal_get_active_object(L, ProjectObject, OPTIONAL); - return 1; - } - - /* get the active solution, which will contain this project */ - if (!script_internal_get_active_object(L, SolutionObject, REQUIRED)) - { - return 0; - } - - name = luaL_checkstring(L, 1); - - /* get the projects list from the solution */ - lua_getfield(L, -1, PROJECTS_KEY); - - /* check to see if a project with this name already exists */ - lua_getfield(L, -1, name); - if (lua_isnil(L, -1)) - { - /* project does not exists, create it */ - lua_newtable(L); - - /* set the name */ - lua_pushvalue(L, 1); - lua_setfield(L, -2, ProjectFieldInfo[ProjectName].name); - - /* set the base directory */ - lua_pushstring(L, script_internal_script_dir(L)); - lua_setfield(L, -2, ProjectFieldInfo[ProjectBaseDirectory].name); - - /* set a default GUID */ - lua_pushstring(L, guid_create()); - lua_setfield(L, -2, ProjectFieldInfo[ProjectGuid].name); - - /* use the list of fields to populate the object properties and accessor functions */ - script_internal_populate_object(L, ProjectFieldInfo); - - /* add it to solution's list of projects, keyed by name */ - lua_pushvalue(L, -1); - lua_setfield(L, -4, name); - - /* also add with integer key */ - lua_pushvalue(L, -1); - lua_rawseti(L, -4, luaL_getn(L, -4) + 1); - } - - /* activate and return the solution object */ - script_internal_set_active_object(L, ProjectObject); - return 1; -} - +/** + * \file fn_project.c + * \brief Create or select a project object. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "script_internal.h" +#include "base/guid.h" + + +/** + * Create a new project object, or select an existing one. + */ +int fn_project(lua_State* L) +{ + const char* name; + + /* if there are no parameters, return the active project */ + if (lua_gettop(L) == 0) + { + script_internal_get_active_object(L, ProjectObject, OPTIONAL); + return 1; + } + + /* get the active solution, which will contain this project */ + if (!script_internal_get_active_object(L, SolutionObject, REQUIRED)) + { + return 0; + } + + name = luaL_checkstring(L, 1); + + /* get the projects list from the solution */ + lua_getfield(L, -1, PROJECTS_KEY); + + /* check to see if a project with this name already exists */ + lua_getfield(L, -1, name); + if (lua_isnil(L, -1)) + { + /* this is a new project; check to be sure the configurations have been set */ + lua_getfield(L, -3, SolutionFieldInfo[SolutionConfigurations].name); + if (luaL_getn(L, -1) == 0) + { + luaL_error(L, "no configurations defined"); + return 0; + } + lua_pop(L, 1); + + /* project does not exists, create it */ + lua_newtable(L); + + /* set the name */ + lua_pushvalue(L, 1); + lua_setfield(L, -2, ProjectFieldInfo[ProjectName].name); + + /* set the base directory */ + lua_pushstring(L, script_internal_script_dir(L)); + lua_setfield(L, -2, ProjectFieldInfo[ProjectBaseDirectory].name); + + /* set a default GUID */ + lua_pushstring(L, guid_create()); + lua_setfield(L, -2, ProjectFieldInfo[ProjectGuid].name); + + /* use the list of fields to populate the object properties and accessor functions */ + script_internal_populate_object(L, ProjectFieldInfo); + + /* add it to solution's list of projects, keyed by name */ + lua_pushvalue(L, -1); + lua_setfield(L, -4, name); + + /* also add with integer key */ + lua_pushvalue(L, -1); + lua_rawseti(L, -4, luaL_getn(L, -4) + 1); + } + + /* activate and return the solution object */ + script_internal_set_active_object(L, ProjectObject); + return 1; +} + diff --git a/src/script/fn_solution.c b/src/script/fn_solution.c index 1aaa22c..3d81069 100644 --- a/src/script/fn_solution.c +++ b/src/script/fn_solution.c @@ -1,62 +1,62 @@ -/** - * \file fn_solution.c - * \brief Create or select a solution object. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "script_internal.h" - - -/** - * Create a new solution object, or select an existing one. - */ -int fn_solution(lua_State* L) -{ - const char* name; - - /* if there are no parameters, return the active solution */ - if (lua_gettop(L) == 0) - { - script_internal_get_active_object(L, SolutionObject, OPTIONAL); - return 1; - } - - name = luaL_checkstring(L, 1); - - /* check to see if a solution with this name already exists */ - lua_getglobal(L, SOLUTIONS_KEY); - lua_getfield(L, -1, name); - if (lua_isnil(L, -1)) - { - /* solution does not exists, create it */ - lua_newtable(L); - - /* set the name */ - lua_pushstring(L, name); - lua_setfield(L, -2, SolutionFieldInfo[SolutionName].name); - - /* set the base directory */ - lua_pushstring(L, script_internal_script_dir(L)); - lua_setfield(L, -2, SolutionFieldInfo[SolutionBaseDirectory].name); - - /* create an empty list of projects */ - lua_newtable(L); - lua_setfield(L, -2, PROJECTS_KEY); - - /* use the list of fields to populate the object properties and accessor functions */ - script_internal_populate_object(L, SolutionFieldInfo); - - /* add it to the master list of solutions, keyed by name */ - lua_pushvalue(L, -1); - lua_setfield(L, -4, name); - - /* also add with integer key */ - lua_pushvalue(L, -1); - lua_rawseti(L, -4, luaL_getn(L, -4) + 1); - } - - /* activate and return the solution object */ - script_internal_set_active_object(L, SolutionObject); - return 1; -} +/** + * \file fn_solution.c + * \brief Create or select a solution object. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "script_internal.h" + + +/** + * Create a new solution object, or select an existing one. + */ +int fn_solution(lua_State* L) +{ + const char* name; + + /* if there are no parameters, return the active solution */ + if (lua_gettop(L) == 0) + { + script_internal_get_active_object(L, SolutionObject, OPTIONAL); + return 1; + } + + name = luaL_checkstring(L, 1); + + /* check to see if a solution with this name already exists */ + lua_getglobal(L, SOLUTIONS_KEY); + lua_getfield(L, -1, name); + if (lua_isnil(L, -1)) + { + /* solution does not exists, create it */ + lua_newtable(L); + + /* set the name */ + lua_pushstring(L, name); + lua_setfield(L, -2, SolutionFieldInfo[SolutionName].name); + + /* set the base directory */ + lua_pushstring(L, script_internal_script_dir(L)); + lua_setfield(L, -2, SolutionFieldInfo[SolutionBaseDirectory].name); + + /* create an empty list of projects */ + lua_newtable(L); + lua_setfield(L, -2, PROJECTS_KEY); + + /* use the list of fields to populate the object properties and accessor functions */ + script_internal_populate_object(L, SolutionFieldInfo); + + /* add it to the master list of solutions, keyed by name */ + lua_pushvalue(L, -1); + lua_setfield(L, -4, name); + + /* also add with integer key */ + lua_pushvalue(L, -1); + lua_rawseti(L, -4, luaL_getn(L, -4) + 1); + } + + /* activate and return the solution object */ + script_internal_set_active_object(L, SolutionObject); + return 1; +} diff --git a/src/script/lua-5.1.2/PREMAKE_CHANGES.txt b/src/script/lua-5.1.2/PREMAKE_CHANGES.txt index 840d716..ca2f322 100644 --- a/src/script/lua-5.1.2/PREMAKE_CHANGES.txt +++ b/src/script/lua-5.1.2/PREMAKE_CHANGES.txt @@ -1,2 +1,2 @@ -I added #pragmas to the end of luaconf.h in order to suppress -some (harmless) VS.NET warning messages. +I added #pragmas to the end of luaconf.h in order to suppress +some (harmless) VS.NET warning messages. diff --git a/src/script/script.c b/src/script/script.c index d2eb915..cf6f70a 100644 --- a/src/script/script.c +++ b/src/script/script.c @@ -1,264 +1,265 @@ -/** - * \file script.c - * \brief The project scripting engine. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include -#include -#include -#include "premake.h" -#include "script_internal.h" -#include "base/cstr.h" -#include "base/error.h" - - -/** Functions to add to the global namespace */ -static const luaL_Reg global_funcs[] = { - { "dofile", fn_dofile }, - { "include", fn_include }, - { "match", fn_match }, - { "project", fn_project }, - { "solution", fn_solution }, - { NULL, NULL } -}; - -/** Functions to add to Lua's "os" namespace */ -static const luaL_Reg os_funcs[] = { - { "getcwd", fn_getcwd }, - { NULL, NULL } -}; - - -DEFINE_CLASS(Script) -{ - lua_State* L; -}; - - -/** - * Create a new instance of the project scripting engine. - * \returns A new engine object, or NULL if an error occurred. - */ -Script script_create(void) -{ - Script script; - - /* create a new Lua scripting environment */ - lua_State* L = lua_open(); - if (L == NULL) - { - error_set("failed to start Lua scripting engine"); - return NULL; - } - - /* register all the standard Lua libraries */ - luaL_openlibs(L); - - /* register the Premake non-configuration related functions */ - luaL_register(L, "_G", global_funcs); - luaL_register(L, "os", os_funcs); - - /* create an empty list of solutions in the script environment */ - lua_newtable(L); - lua_setglobal(L, SOLUTIONS_KEY); - - /* register the project object accessor functions */ - fn_accessor_register_all(L); - - script = ALLOC_CLASS(Script); - script->L = L; - return script; -} - - -/** - * Destroy an instance of the project scripting engine, including any contained - * scripting project objects. - * \param script The script engine instance to destroy. - */ -void script_destroy(Script script) -{ - assert(script); - lua_close(script->L); - free(script); -} - - -/** - * Get the current value of the _ACTION global variable. - * \param script The project scripting engine instance. - * \returns The action name if set, or NULL if not. - */ -const char* script_get_action(Script script) -{ - const char* result; - assert(script); - lua_getglobal(script->L, ACTION_KEY); - result = lua_tostring(script->L, -1); - lua_pop(script->L, 1); - return result; -} - - -/** - * Retrieve the Lua scripting environment object from the project scripting engine. - * \param script The script engine instance. - * \returns The Lua scripting environment associated with the script engine instance. - */ -lua_State* script_get_lua(Script script) -{ - assert(script); - return script->L; -} - - -/** - * Internal shared implementation for script_run_file() and script_run_string(). - * \param L The Lua scripting environment. - * \param param The filename, or the code string, to be run. - * \param is_file True if param is a file, false if it is a code string. - * \returns If the script returns a value, it is converted to a string and returned. - * If the script does not return a value, NULL is returned. If an error - * occurs in the script, the error message is returned. - */ -static const char* script_run(lua_State* L, const char* param, int is_file) -{ - const char* result; - int top, status; - - /* set an error handler */ - lua_pushcfunction(L, fn_error); - - /* remember stack top, to figure out how many values were returned by the script */ - top = lua_gettop(L); - - if (is_file) - { - /* call Lua's dofile() function to do the work. I've implemented a - * custom version in fn_dofile.c; routing the call there keeps all - * of the logic in one place. */ - lua_getglobal(L, "dofile"); - lua_pushstring(L, param); - status = lua_pcall(L, 1, LUA_MULTRET, -3); - } - else - { - status = luaL_loadstring(L, param); - if (status == OKAY) - { - /* fake a file name for the _FILE global */ - lua_pushstring(L, "(string)/(string)"); - lua_setglobal(L, FILE_KEY); - - status = lua_pcall(L, 0, LUA_MULTRET, -2); - } - } - - if (status == OKAY) - { - /* if results were returned, pass them back to the caller */ - if (lua_gettop(L) > top) - { - if (lua_isboolean(L, top + 1)) - { - int value = lua_toboolean(L, top + 1); - result = (value) ? "true" : "false"; - } - else - { - result = lua_tostring(L, top + 1); - } - } - else - { - result = NULL; - } - } - else - { - result = error_get(); - } - - return result; -} - - -/** - * Execute a project script stored in a file. - * \param script The project scripting engine instance. - * \param filename The name of the file containing the script code to be executed. - * \returns If the script returns a value, it is converted to a string and returned. - * If the script does not return a value, NULL is returned. If an error - * occurs in the script, the error message is returned. - */ -const char* script_run_file(Script script, const char* filename) -{ - assert(script); - assert(filename); - return script_run(script->L, filename, 1); -} - - -/** - * Execute a project script stored in a string. - * \param script The project scripting engine instance. - * \param code The string containing the script code to be executed. - * \returns If the script returns a value, it is converted to a string and returned. - * If the script does not return a value, NULL is returned. If an error - * occurs in the script, the error message is returned. - */ -const char* script_run_string(Script script, const char* code) -{ - const char* result; - - assert(script); - assert(code); - - result = script_run(script->L, code, 0); - - /* if an error was returned, clean up the message to make it easier to test */ - if (cstr_starts_with(result, "[string ")) - { - result = strstr(result, ":1:") + 4; - } - - return result; -} - - -/** - * Set the value of the _ACTION global variable. - * \param script The project scripting engine instance. - * \param action The name of the action to be performed. - */ -void script_set_action(Script script, const char* action) -{ - assert(script); - lua_pushstring(script->L, action); - lua_setglobal(script->L, ACTION_KEY); -} - - -/** - * Copy project information out of the scripting environment and into C objects that - * can be more easily manipulated by the action code. - * \param script The project scripting engine instance. - * \param slns An array to hold the list of unloaded solutions. - * \returns OKAY if successful. - */ -int script_unload(Script script, Array slns) -{ - struct UnloadFuncs funcs; - int result; - - assert(script); - assert(slns); - - funcs.unload_solution = unload_solution; - funcs.unload_project = unload_project; - result = unload_all(script->L, slns, &funcs); - return result; -} - - +/** + * \file script.c + * \brief The project scripting engine. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include +#include +#include +#include "premake.h" +#include "script_internal.h" +#include "base/cstr.h" +#include "base/error.h" + + +/** Functions to add to the global namespace */ +static const luaL_Reg global_funcs[] = { + { "configurations", fn_configurations }, + { "dofile", fn_dofile }, + { "include", fn_include }, + { "match", fn_match }, + { "project", fn_project }, + { "solution", fn_solution }, + { NULL, NULL } +}; + +/** Functions to add to Lua's "os" namespace */ +static const luaL_Reg os_funcs[] = { + { "getcwd", fn_getcwd }, + { NULL, NULL } +}; + + +DEFINE_CLASS(Script) +{ + lua_State* L; +}; + + +/** + * Create a new instance of the project scripting engine. + * \returns A new engine object, or NULL if an error occurred. + */ +Script script_create(void) +{ + Script script; + + /* create a new Lua scripting environment */ + lua_State* L = lua_open(); + if (L == NULL) + { + error_set("failed to start Lua scripting engine"); + return NULL; + } + + /* register all the standard Lua libraries */ + luaL_openlibs(L); + + /* create an empty list of solutions in the script environment */ + lua_newtable(L); + lua_setglobal(L, SOLUTIONS_KEY); + + /* register the project object accessor functions */ + fn_accessor_register_all(L); + + /* register the Premake non-configuration related functions */ + luaL_register(L, "_G", global_funcs); + luaL_register(L, "os", os_funcs); + + script = ALLOC_CLASS(Script); + script->L = L; + return script; +} + + +/** + * Destroy an instance of the project scripting engine, including any contained + * scripting project objects. + * \param script The script engine instance to destroy. + */ +void script_destroy(Script script) +{ + assert(script); + lua_close(script->L); + free(script); +} + + +/** + * Get the current value of the _ACTION global variable. + * \param script The project scripting engine instance. + * \returns The action name if set, or NULL if not. + */ +const char* script_get_action(Script script) +{ + const char* result; + assert(script); + lua_getglobal(script->L, ACTION_KEY); + result = lua_tostring(script->L, -1); + lua_pop(script->L, 1); + return result; +} + + +/** + * Retrieve the Lua scripting environment object from the project scripting engine. + * \param script The script engine instance. + * \returns The Lua scripting environment associated with the script engine instance. + */ +lua_State* script_get_lua(Script script) +{ + assert(script); + return script->L; +} + + +/** + * Internal shared implementation for script_run_file() and script_run_string(). + * \param L The Lua scripting environment. + * \param param The filename, or the code string, to be run. + * \param is_file True if param is a file, false if it is a code string. + * \returns If the script returns a value, it is converted to a string and returned. + * If the script does not return a value, NULL is returned. If an error + * occurs in the script, the error message is returned. + */ +static const char* script_run(lua_State* L, const char* param, int is_file) +{ + const char* result; + int top, status; + + /* set an error handler */ + lua_pushcfunction(L, fn_error); + + /* remember stack top, to figure out how many values were returned by the script */ + top = lua_gettop(L); + + if (is_file) + { + /* call Lua's dofile() function to do the work. I've implemented a + * custom version in fn_dofile.c; routing the call there keeps all + * of the logic in one place. */ + lua_getglobal(L, "dofile"); + lua_pushstring(L, param); + status = lua_pcall(L, 1, LUA_MULTRET, -3); + } + else + { + status = luaL_loadstring(L, param); + if (status == OKAY) + { + /* fake a file name for the _FILE global */ + lua_pushstring(L, "(string)/(string)"); + lua_setglobal(L, FILE_KEY); + + status = lua_pcall(L, 0, LUA_MULTRET, -2); + } + } + + if (status == OKAY) + { + /* if results were returned, pass them back to the caller */ + if (lua_gettop(L) > top) + { + if (lua_isboolean(L, top + 1)) + { + int value = lua_toboolean(L, top + 1); + result = (value) ? "true" : "false"; + } + else + { + result = lua_tostring(L, top + 1); + } + } + else + { + result = NULL; + } + } + else + { + result = error_get(); + } + + return result; +} + + +/** + * Execute a project script stored in a file. + * \param script The project scripting engine instance. + * \param filename The name of the file containing the script code to be executed. + * \returns If the script returns a value, it is converted to a string and returned. + * If the script does not return a value, NULL is returned. If an error + * occurs in the script, the error message is returned. + */ +const char* script_run_file(Script script, const char* filename) +{ + assert(script); + assert(filename); + return script_run(script->L, filename, 1); +} + + +/** + * Execute a project script stored in a string. + * \param script The project scripting engine instance. + * \param code The string containing the script code to be executed. + * \returns If the script returns a value, it is converted to a string and returned. + * If the script does not return a value, NULL is returned. If an error + * occurs in the script, the error message is returned. + */ +const char* script_run_string(Script script, const char* code) +{ + const char* result; + + assert(script); + assert(code); + + result = script_run(script->L, code, 0); + + /* if an error was returned, clean up the message to make it easier to test */ + if (cstr_starts_with(result, "[string ")) + { + result = strstr(result, ":1:") + 4; + } + + return result; +} + + +/** + * Set the value of the _ACTION global variable. + * \param script The project scripting engine instance. + * \param action The name of the action to be performed. + */ +void script_set_action(Script script, const char* action) +{ + assert(script); + lua_pushstring(script->L, action); + lua_setglobal(script->L, ACTION_KEY); +} + + +/** + * Copy project information out of the scripting environment and into C objects that + * can be more easily manipulated by the action code. + * \param script The project scripting engine instance. + * \param slns An array to hold the list of unloaded solutions. + * \returns OKAY if successful. + */ +int script_unload(Script script, Array slns) +{ + struct UnloadFuncs funcs; + int result; + + assert(script); + assert(slns); + + funcs.unload_solution = unload_solution; + funcs.unload_project = unload_project; + result = unload_all(script->L, slns, &funcs); + return result; +} + + diff --git a/src/script/script.h b/src/script/script.h index f9c9a6c..ace069b 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -1,29 +1,29 @@ -/** - * \file script.h - * \brief The project scripting engine. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - * - * \defgroup script Scripting Engine - * - * The project scripting engine. - * - * @{ - */ -#if !defined(PREMAKE_SCRIPT_H) -#define PREMAKE_SCRIPT_H - -#include "base/array.h" - -DECLARE_CLASS(Script) - -Script script_create(void); -void script_destroy(Script script); -const char* script_get_action(Script script); -const char* script_run_file(Script script, const char* filename); -const char* script_run_string(Script script, const char* code); -void script_set_action(Script script, const char* action); -int script_tests(void); -int script_unload(Script script, Array slns); - -#endif -/** @} */ +/** + * \file script.h + * \brief The project scripting engine. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + * + * \defgroup script Scripting Engine + * + * The project scripting engine. + * + * @{ + */ +#if !defined(PREMAKE_SCRIPT_H) +#define PREMAKE_SCRIPT_H + +#include "base/array.h" + +DECLARE_CLASS(Script) + +Script script_create(void); +void script_destroy(Script script); +const char* script_get_action(Script script); +const char* script_run_file(Script script, const char* filename); +const char* script_run_string(Script script, const char* code); +void script_set_action(Script script, const char* action); +int script_tests(void); +int script_unload(Script script, Array slns); + +#endif +/** @} */ diff --git a/src/script/script_internal.c b/src/script/script_internal.c index 03fc912..3410fce 100644 --- a/src/script/script_internal.c +++ b/src/script/script_internal.c @@ -1,168 +1,168 @@ -/** - * \file script_internal.h - * \brief Project scripting engine internal API. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include -#include "premake.h" -#include "script_internal.h" -#include "base/buffers.h" -#include "base/path.h" - - -/** - * Pushes the active value for the given object type to the top of the stack. - * This function is used to retrieve the current solution, project, etc. - * \param L The Lua state. - * \param type One or more of the script object type enumerations. - * A bitmask may be supplied if more than one object type - * can be valid. If so, the objects will be returned in - * following order: configuration, project, then solution. - * \param is_required If true, will set error if no active object is found. - * \returns The active object, pushed onto the stack. May be nil if there is - * no currently active object. If is_required is true, returns true - * if an active object was found, false otherwise. - */ -int script_internal_get_active_object(lua_State* L, enum ObjectType type, int is_required) -{ - int top; - - lua_getregistry(L); - top = lua_gettop(L); - - if (lua_gettop(L) == top && (type & ConfigObject)) - { - lua_getfield(L, -1, CONFIGURATION_KEY); - if (lua_isnil(L, -1)) - lua_pop(L, 1); - } - - if (lua_gettop(L) == top && (type & ProjectObject)) - { - lua_getfield(L, -1, PROJECT_KEY); - if (lua_isnil(L, -1)) - lua_pop(L, 1); - } - - if (lua_gettop(L) == top && (type & SolutionObject)) - { - lua_getfield(L, -1, SOLUTION_KEY); - if (lua_isnil(L, -1)) - lua_pop(L, 1); - } - - /* if an active object was found, return it */ - if (lua_gettop(L) > top) - { - /* remove the registry table first */ - lua_remove(L, -2); - return 1; - } - - /* if no active object was found, and none is required, return nil */ - else if (!is_required) - { - /* remove the registry table first */ - lua_pop(L, 1); - lua_pushnil(L); - return 1; - } - - /* else set an error */ - else - { - /* build an error message */ - char* buffer = buffers_next(); - strcpy(buffer, "no active "); - switch (type) - { - case SolutionObject: - strcat(buffer, "solution"); - break; - case ProjectObject: - strcat(buffer, "project"); - break; - case ConfigObject: - strcat(buffer, "configuration"); - break; - case SolutionObject | ProjectObject: - strcat(buffer, "solution or project"); - break; - case SolutionObject | ProjectObject | ConfigObject: - strcat(buffer, "solution, project, or configuration"); - break; - default: - strcat(buffer, "object"); - } - luaL_error(L, buffer); - return 0; - } -} - - -/** - * Remembers the object at the top of the stack as active for the given object type. - * This function is used to indicate the current solution, project, etc. - * \param L The Lua state. - * \param type One of the script object type enumerations. - */ -void script_internal_set_active_object(lua_State* L, enum ObjectType type) -{ - lua_getregistry(L); - lua_pushvalue(L, -2); - - if (type == SolutionObject) - { - lua_setfield(L, -2, SOLUTION_KEY); - } - else if (type == ProjectObject) - { - lua_setfield(L, -2, PROJECT_KEY); - } - else - { - lua_setfield(L, -2, CONFIGURATION_KEY); - } - - lua_pop(L, 1); -} - - -/** - * Returns the directory containing the currently executing script file. Used to - * locate external resources (files, etc.) specified relative to the current script. - * \param L The Lua script environment. - * \returns The directory containing the currently executing script file. - */ -const char* script_internal_script_dir(lua_State* L) -{ - const char* result; - lua_getglobal(L, FILE_KEY); - result = lua_tostring(L, -1); - result = path_directory(result); - lua_pop(L, 1); - return result; -} - - -/** - * Uses a list of fields to populate a project object (solution, project, or - * configuration) with a matching set of properties and accessor functions. - * \param L The Lua state. - * \param fields The list of object fields. - */ -void script_internal_populate_object(lua_State* L, struct FieldInfo* fields) -{ - struct FieldInfo* field; - - /* set all list-type configuration values to empty tables */ - for (field = fields; field->name != NULL; ++field) - { - if (field->kind != StringField) - { - lua_newtable(L); - lua_setfield(L, -2, field->name); - } - } -} +/** + * \file script_internal.h + * \brief Project scripting engine internal API. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include +#include "premake.h" +#include "script_internal.h" +#include "base/buffers.h" +#include "base/path.h" + + +/** + * Pushes the active value for the given object type to the top of the stack. + * This function is used to retrieve the current solution, project, etc. + * \param L The Lua state. + * \param type One or more of the script object type enumerations. + * A bitmask may be supplied if more than one object type + * can be valid. If so, the objects will be returned in + * following order: configuration, project, then solution. + * \param is_required If true, will set error if no active object is found. + * \returns The active object, pushed onto the stack. May be nil if there is + * no currently active object. If is_required is true, returns true + * if an active object was found, false otherwise. + */ +int script_internal_get_active_object(lua_State* L, enum ObjectType type, int is_required) +{ + int top; + + lua_getregistry(L); + top = lua_gettop(L); + + if (lua_gettop(L) == top && (type & ConfigObject)) + { + lua_getfield(L, -1, CONFIGURATION_KEY); + if (lua_isnil(L, -1)) + lua_pop(L, 1); + } + + if (lua_gettop(L) == top && (type & ProjectObject)) + { + lua_getfield(L, -1, PROJECT_KEY); + if (lua_isnil(L, -1)) + lua_pop(L, 1); + } + + if (lua_gettop(L) == top && (type & SolutionObject)) + { + lua_getfield(L, -1, SOLUTION_KEY); + if (lua_isnil(L, -1)) + lua_pop(L, 1); + } + + /* if an active object was found, return it */ + if (lua_gettop(L) > top) + { + /* remove the registry table first */ + lua_remove(L, -2); + return 1; + } + + /* if no active object was found, and none is required, return nil */ + else if (!is_required) + { + /* remove the registry table first */ + lua_pop(L, 1); + lua_pushnil(L); + return 1; + } + + /* else set an error */ + else + { + /* build an error message */ + char* buffer = buffers_next(); + strcpy(buffer, "no active "); + switch (type) + { + case SolutionObject: + strcat(buffer, "solution"); + break; + case ProjectObject: + strcat(buffer, "project"); + break; + case ConfigObject: + strcat(buffer, "configuration"); + break; + case SolutionObject | ProjectObject: + strcat(buffer, "solution or project"); + break; + case SolutionObject | ProjectObject | ConfigObject: + strcat(buffer, "solution, project, or configuration"); + break; + default: + strcat(buffer, "object"); + } + luaL_error(L, buffer); + return 0; + } +} + + +/** + * Remembers the object at the top of the stack as active for the given object type. + * This function is used to indicate the current solution, project, etc. + * \param L The Lua state. + * \param type One of the script object type enumerations. + */ +void script_internal_set_active_object(lua_State* L, enum ObjectType type) +{ + lua_getregistry(L); + lua_pushvalue(L, -2); + + if (type == SolutionObject) + { + lua_setfield(L, -2, SOLUTION_KEY); + } + else if (type == ProjectObject) + { + lua_setfield(L, -2, PROJECT_KEY); + } + else + { + lua_setfield(L, -2, CONFIGURATION_KEY); + } + + lua_pop(L, 1); +} + + +/** + * Returns the directory containing the currently executing script file. Used to + * locate external resources (files, etc.) specified relative to the current script. + * \param L The Lua script environment. + * \returns The directory containing the currently executing script file. + */ +const char* script_internal_script_dir(lua_State* L) +{ + const char* result; + lua_getglobal(L, FILE_KEY); + result = lua_tostring(L, -1); + result = path_directory(result); + lua_pop(L, 1); + return result; +} + + +/** + * Uses a list of fields to populate a project object (solution, project, or + * configuration) with a matching set of properties and accessor functions. + * \param L The Lua state. + * \param fields The list of object fields. + */ +void script_internal_populate_object(lua_State* L, struct FieldInfo* fields) +{ + struct FieldInfo* field; + + /* set all list-type configuration values to empty tables */ + for (field = fields; field->name != NULL; ++field) + { + if (field->kind != StringField) + { + lua_newtable(L); + lua_setfield(L, -2, field->name); + } + } +} diff --git a/src/script/script_internal.h b/src/script/script_internal.h index 8290b56..27380c3 100644 --- a/src/script/script_internal.h +++ b/src/script/script_internal.h @@ -1,72 +1,76 @@ -/** - * \file script_internal.h - * \brief Project scripting engine internal API. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ -#if !defined(PREMAKE_SCRIPT_INTERNAL_H) -#define PREMAKE_SCRIPT_INTERNAL_H - -#include "script.h" -#include "session/session.h" - -#define lua_c -#include "lua.h" -#include "lauxlib.h" -#include "lualib.h" - - -/* string constants for script variables and functions */ -#define ACTION_KEY "_ACTION" -#define CONFIGURATION_KEY "configuration" -#define FILE_KEY "_FILE" -#define PROJECT_KEY "project" -#define PROJECTS_KEY "projects" -#define SOLUTION_KEY "solution" -#define SOLUTIONS_KEY "_SOLUTIONS" - - -/** Used to specify type of object for engine_get/set_active_object */ -enum ObjectType -{ - SolutionObject = 0x01, - ProjectObject = 0x02, - ConfigObject = 0x04 -}; - -#define OPTIONAL (0) -#define REQUIRED (1) - -lua_State* script_get_lua(Script script); - -/* internal state management */ -int script_internal_get_active_object(lua_State* L, enum ObjectType type, int is_required); -void script_internal_set_active_object(lua_State* L, enum ObjectType type); -const char* script_internal_script_dir(lua_State* L); -void script_internal_populate_object(lua_State* L, struct FieldInfo* fields); - -/* Generic project object field getter/setter API */ -int fn_accessor_register_all(lua_State* L); - -/* script function handlers */ -int fn_dofile(lua_State* L); -int fn_error(lua_State* L); -int fn_getcwd(lua_State* L); -int fn_include(lua_State* L); -int fn_match(lua_State* L); -int fn_project(lua_State* L); -int fn_solution(lua_State* L); - -/* Project object unloading API. The unload functions "interface" provides an - * opportunity to mock the actual implementation for automated testing */ -struct UnloadFuncs -{ - int (*unload_solution)(lua_State* L, Solution sln); - int (*unload_project)(lua_State* L, Project prj); -}; - -int unload_all(lua_State* L, Array slns, struct UnloadFuncs* funcs); -int unload_solution(lua_State* L, Solution sln); -int unload_project(lua_State* L, Project prj); - - -#endif +/** + * \file script_internal.h + * \brief Project scripting engine internal API. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ +#if !defined(PREMAKE_SCRIPT_INTERNAL_H) +#define PREMAKE_SCRIPT_INTERNAL_H + +#include "script.h" +#include "session/session.h" + +#define lua_c +#include "lua.h" +#include "lauxlib.h" +#include "lualib.h" + + +/* string constants for script variables and functions */ +#define ACTION_KEY "_ACTION" +#define CONFIGURATION_KEY "configuration" +#define FILE_KEY "_FILE" +#define PROJECT_KEY "project" +#define PROJECTS_KEY "projects" +#define SOLUTION_KEY "solution" +#define SOLUTIONS_KEY "_SOLUTIONS" + + +/** Used to specify type of object for engine_get/set_active_object */ +enum ObjectType +{ + SolutionObject = 0x01, + ProjectObject = 0x02, + ConfigObject = 0x04 +}; + +#define OPTIONAL (0) +#define REQUIRED (1) + +lua_State* script_get_lua(Script script); + +/* internal state management */ +int script_internal_get_active_object(lua_State* L, enum ObjectType type, int is_required); +void script_internal_set_active_object(lua_State* L, enum ObjectType type); +const char* script_internal_script_dir(lua_State* L); +void script_internal_populate_object(lua_State* L, struct FieldInfo* fields); + +/* Generic project object field getter/setter API */ +int fn_accessor_register_all(lua_State* L); +int fn_accessor_set_string_value(lua_State* L, struct FieldInfo* field); +int fn_accessor_set_list_value(lua_State* L, struct FieldInfo* field); + +/* script function handlers */ +int fn_accessor(lua_State* L); +int fn_configurations(lua_State* L); +int fn_dofile(lua_State* L); +int fn_error(lua_State* L); +int fn_getcwd(lua_State* L); +int fn_include(lua_State* L); +int fn_match(lua_State* L); +int fn_project(lua_State* L); +int fn_solution(lua_State* L); + +/* Project object unloading API. The unload functions "interface" provides an + * opportunity to mock the actual implementation for automated testing */ +struct UnloadFuncs +{ + int (*unload_solution)(lua_State* L, Solution sln); + int (*unload_project)(lua_State* L, Project prj); +}; + +int unload_all(lua_State* L, Array slns, struct UnloadFuncs* funcs); +int unload_solution(lua_State* L, Solution sln); +int unload_project(lua_State* L, Project prj); + + +#endif diff --git a/src/script/tests/fn_accessor_tests.cpp b/src/script/tests/fn_accessor_tests.cpp index 8cf0438..ce44512 100644 --- a/src/script/tests/fn_accessor_tests.cpp +++ b/src/script/tests/fn_accessor_tests.cpp @@ -1,113 +1,113 @@ -/** - * \file fn_accessor_tests.cpp - * \brief Automated tests for the generic value getter/setter function. - * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "script_tests.h" - - -SUITE(script) -{ - /************************************************************************** - * String field tests - **************************************************************************/ - - TEST_FIXTURE(FxAccessor, Accessor_ReturnsNil_OnEmptyStringValue) - { - const char* result = script_run_string(script, - "return (location() == nil)"); - CHECK_EQUAL("true", result); - } - - TEST_FIXTURE(FxAccessor, Accessor_RaisesError_OnListValueAndStringField) - { - const char* result = script_run_string(script, - "location {}"); - CHECK_EQUAL("the field 'location' does not support lists of values", result); - } - - TEST_FIXTURE(FxAccessor, Accessor_SetsField_OnStringField) - { - const char* result = script_run_string(script, - "location 'MyLocation';" - "return prj.location" ); - CHECK_EQUAL("MyLocation", result); - } - - TEST_FIXTURE(FxAccessor, Accessor_GetsField_OnStringField) - { - const char* result = script_run_string(script, - "prj.location = 'MyLocation';" - "return location()" ); - CHECK_EQUAL("MyLocation", result); - } - - - /************************************************************************** - * List field tests - **************************************************************************/ - - TEST_FIXTURE(FxAccessor, Accessor_ReturnsEmptyTable_OnEmptyListValue) - { - const char* result = script_run_string(script, - "return (#files() == 0)"); - CHECK_EQUAL("true", result); - } - - TEST_FIXTURE(FxAccessor, Accessor_Appends_OnStringValue) - { - const char* result = script_run_string(script, - "files { 'Hello.c' };" - "return (prj.files[1] == 'Hello.c')" ); - CHECK_EQUAL("true", result); - } - - TEST_FIXTURE(FxAccessor, Accessor_Appends_OnListValue) - { - const char* result = script_run_string(script, - "files { 'Hello.c', 'Goodbye.c' };" - "return (prj.files[1] == 'Hello.c' and prj.files[2] == 'Goodbye.c')" ); - CHECK_EQUAL("true", result); - } - - TEST_FIXTURE(FxAccessor, Accessor_Appends_OnTwoCalls) - { - const char* result = script_run_string(script, - "files { 'Hello.c' };" - "files { 'Goodbye.c' };" - "return (prj.files[1] == 'Hello.c' and prj.files[2] == 'Goodbye.c')" ); - CHECK_EQUAL("true", result); - } - - TEST_FIXTURE(FxAccessor, Accessor_ReturnsList_OnNoArgs) - { - const char* result = script_run_string(script, - "files { 'Hello.c', 'Goodbye.c' };" - "lst = files();" - "return (lst[1] == 'Hello.c' and lst[2] == 'Goodbye.c')" ); - CHECK_EQUAL("true", result); - } - - TEST_FIXTURE(FxAccessor, Accessor_FlattensTables_OnNestedLists) - { - const char* result = script_run_string(script, - "files { {'Hello.c'}, {'Goodbye.c'} };" - "return (prj.files[1] == 'Hello.c' and prj.files[2] == 'Goodbye.c')" ); - CHECK_EQUAL("true", result); - } - - - /************************************************************************** - * Files field tests - **************************************************************************/ - - TEST_FIXTURE(FxAccessor, Accessor_ExpandsWildcards) - { - const char* result = script_run_string(script, - "files { 'testing/test_files/*.lua' };" - "return (#prj.files > 0)"); - CHECK_EQUAL("true", result); - } -} +/** + * \file fn_accessor_tests.cpp + * \brief Automated tests for the generic value getter/setter function. + * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "script_tests.h" + + +SUITE(script) +{ + /************************************************************************** + * String field tests + **************************************************************************/ + + TEST_FIXTURE(FxAccessor, Accessor_ReturnsNil_OnEmptyStringValue) + { + const char* result = script_run_string(script, + "return (location() == nil)"); + CHECK_EQUAL("true", result); + } + + TEST_FIXTURE(FxAccessor, Accessor_RaisesError_OnListValueAndStringField) + { + const char* result = script_run_string(script, + "location {}"); + CHECK_EQUAL("the field 'location' does not support lists of values", result); + } + + TEST_FIXTURE(FxAccessor, Accessor_SetsField_OnStringField) + { + const char* result = script_run_string(script, + "location 'MyLocation';" + "return prj.location" ); + CHECK_EQUAL("MyLocation", result); + } + + TEST_FIXTURE(FxAccessor, Accessor_GetsField_OnStringField) + { + const char* result = script_run_string(script, + "prj.location = 'MyLocation';" + "return location()" ); + CHECK_EQUAL("MyLocation", result); + } + + + /************************************************************************** + * List field tests + **************************************************************************/ + + TEST_FIXTURE(FxAccessor, Accessor_ReturnsEmptyTable_OnEmptyListValue) + { + const char* result = script_run_string(script, + "return (#files() == 0)"); + CHECK_EQUAL("true", result); + } + + TEST_FIXTURE(FxAccessor, Accessor_Appends_OnStringValue) + { + const char* result = script_run_string(script, + "files { 'Hello.c' };" + "return (prj.files[1] == 'Hello.c')" ); + CHECK_EQUAL("true", result); + } + + TEST_FIXTURE(FxAccessor, Accessor_Appends_OnListValue) + { + const char* result = script_run_string(script, + "files { 'Hello.c', 'Goodbye.c' };" + "return (prj.files[1] == 'Hello.c' and prj.files[2] == 'Goodbye.c')" ); + CHECK_EQUAL("true", result); + } + + TEST_FIXTURE(FxAccessor, Accessor_Appends_OnTwoCalls) + { + const char* result = script_run_string(script, + "files { 'Hello.c' };" + "files { 'Goodbye.c' };" + "return (prj.files[1] == 'Hello.c' and prj.files[2] == 'Goodbye.c')" ); + CHECK_EQUAL("true", result); + } + + TEST_FIXTURE(FxAccessor, Accessor_ReturnsList_OnNoArgs) + { + const char* result = script_run_string(script, + "files { 'Hello.c', 'Goodbye.c' };" + "lst = files();" + "return (lst[1] == 'Hello.c' and lst[2] == 'Goodbye.c')" ); + CHECK_EQUAL("true", result); + } + + TEST_FIXTURE(FxAccessor, Accessor_FlattensTables_OnNestedLists) + { + const char* result = script_run_string(script, + "files { {'Hello.c'}, {'Goodbye.c'} };" + "return (prj.files[1] == 'Hello.c' and prj.files[2] == 'Goodbye.c')" ); + CHECK_EQUAL("true", result); + } + + + /************************************************************************** + * Files field tests + **************************************************************************/ + + TEST_FIXTURE(FxAccessor, Accessor_ExpandsWildcards) + { + const char* result = script_run_string(script, + "files { 'testing/test_files/*.lua' };" + "return (#prj.files > 0)"); + CHECK_EQUAL("true", result); + } +} diff --git a/src/script/tests/fn_configurations_tests.cpp b/src/script/tests/fn_configurations_tests.cpp index be4f702..b34501f 100644 --- a/src/script/tests/fn_configurations_tests.cpp +++ b/src/script/tests/fn_configurations_tests.cpp @@ -9,14 +9,14 @@ SUITE(script) { - TEST_FIXTURE(FxAccessor, Configurations_Exists_OnStartup) + TEST_FIXTURE(FxScript, Configurations_Exists_OnStartup) { const char* result = script_run_string(script, "return (configurations ~= nil)"); CHECK_EQUAL("true", result); } - TEST_FIXTURE(FxAccessor, Configurations_Error_OnNoActiveSolution) + TEST_FIXTURE(FxScript, Configurations_Error_OnNoActiveSolution) { Script script = script_create(); const char* result = script_run_string(script, "configurations {'Debug'}"); @@ -24,11 +24,23 @@ SUITE(script) script_destroy(script); } - TEST_FIXTURE(FxAccessor, Configurations_CanRoundtrip) + TEST_FIXTURE(FxScript, Configurations_CanRoundtrip) { const char* result = script_run_string(script, - "configurations {'Debug'};" + "solution 'MySolution';" + " configurations {'Debug','Release'};" "return configurations()[1]"); CHECK_EQUAL("Debug", result); } + + TEST_FIXTURE(FxScript, Configurations_RaisesError_OnProjectDefined) + { + const char* result = script_run_string(script, + "solution 'MySolution';" + " configurations {'Debug','Release'};" + "project 'MyProject';" + " configurations {'DebugDLL','ReleaseDLL'}"); + CHECK_EQUAL("configurations may not be modified after projects are defined", result); + } + } diff --git a/src/script/tests/fn_dofile_tests.cpp b/src/script/tests/fn_dofile_tests.cpp index 62bf691..3e814a3 100644 --- a/src/script/tests/fn_dofile_tests.cpp +++ b/src/script/tests/fn_dofile_tests.cpp @@ -1,73 +1,73 @@ -/** - * \file fn_dofile_tests.cpp - * \brief Automated test for the dofile() function. - * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "script_tests.h" -extern "C" { -#include "base/cstr.h" -#include "base/dir.h" -} - - -SUITE(script) -{ - TEST_FIXTURE(FxScript, DoFile_Exists_OnStartup) - { - const char* result = script_run_string(script, - "return (dofile ~= nil)"); - CHECK_EQUAL("true", result); - } - - TEST_FIXTURE(FxScript, DoFile_ReturnsValue_OnValidFile) - { - const char* result = script_run_string(script, - "return dofile('testing/test_files/true.lua')"); - CHECK_EQUAL("true", result); - } - - TEST_FIXTURE(FxScript, DoFile_SetsError_OnFileNotFound) - { - script_run_string(script, - "dofile('nosuchfile.lua')"); - CHECK(cstr_ends_with(error_get(), "No such file or directory")); - } - - TEST_FIXTURE(FxScript, DoFile_SetsCwd_BeforeScript) - { - const char* result = script_run_string(script, - "return dofile('testing/test_files/getcwd.lua')"); - CHECK(cstr_ends_with(result, "testing/test_files")); - } - - TEST_FIXTURE(FxScript, DoFile_SetsCwd_BeforeNestedScript) - { - const char* result = script_run_string(script, - "return dofile('testing/test_files/dofile.lua')"); - CHECK(cstr_ends_with(result, "testing/test_files/nested")); - } - - TEST_FIXTURE(FxScript, DoFile_RestoresCwd_AfterNestedScript) - { - const char* result = script_run_string(script, - "return dofile('testing/test_files/dofile_getcwd.lua')"); - CHECK(cstr_ends_with(result, "testing/test_files")); - } - - TEST_FIXTURE(FxScript, DoFile_RestoresCwd_OnFileNotFound) - { - script_run_string(script, - "dofile('testing/test_files/nosuchfile.lua')"); - const char* cwd = dir_get_current(); - CHECK(cstr_ends_with(cwd, "/src")); - } - - TEST_FIXTURE(FxScript, DoFile_SetsFileGlobal) - { - const char* result = script_run_string(script, - "return dofile('testing/test_files/_FILE.lua')"); - CHECK(cstr_ends_with(result, "testing/test_files/_FILE.lua")); - } -} +/** + * \file fn_dofile_tests.cpp + * \brief Automated test for the dofile() function. + * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "script_tests.h" +extern "C" { +#include "base/cstr.h" +#include "base/dir.h" +} + + +SUITE(script) +{ + TEST_FIXTURE(FxScript, DoFile_Exists_OnStartup) + { + const char* result = script_run_string(script, + "return (dofile ~= nil)"); + CHECK_EQUAL("true", result); + } + + TEST_FIXTURE(FxScript, DoFile_ReturnsValue_OnValidFile) + { + const char* result = script_run_string(script, + "return dofile('testing/test_files/true.lua')"); + CHECK_EQUAL("true", result); + } + + TEST_FIXTURE(FxScript, DoFile_SetsError_OnFileNotFound) + { + script_run_string(script, + "dofile('nosuchfile.lua')"); + CHECK(cstr_ends_with(error_get(), "No such file or directory")); + } + + TEST_FIXTURE(FxScript, DoFile_SetsCwd_BeforeScript) + { + const char* result = script_run_string(script, + "return dofile('testing/test_files/getcwd.lua')"); + CHECK(cstr_ends_with(result, "testing/test_files")); + } + + TEST_FIXTURE(FxScript, DoFile_SetsCwd_BeforeNestedScript) + { + const char* result = script_run_string(script, + "return dofile('testing/test_files/dofile.lua')"); + CHECK(cstr_ends_with(result, "testing/test_files/nested")); + } + + TEST_FIXTURE(FxScript, DoFile_RestoresCwd_AfterNestedScript) + { + const char* result = script_run_string(script, + "return dofile('testing/test_files/dofile_getcwd.lua')"); + CHECK(cstr_ends_with(result, "testing/test_files")); + } + + TEST_FIXTURE(FxScript, DoFile_RestoresCwd_OnFileNotFound) + { + script_run_string(script, + "dofile('testing/test_files/nosuchfile.lua')"); + const char* cwd = dir_get_current(); + CHECK(cstr_ends_with(cwd, "/src")); + } + + TEST_FIXTURE(FxScript, DoFile_SetsFileGlobal) + { + const char* result = script_run_string(script, + "return dofile('testing/test_files/_FILE.lua')"); + CHECK(cstr_ends_with(result, "testing/test_files/_FILE.lua")); + } +} diff --git a/src/script/tests/fn_error_tests.cpp b/src/script/tests/fn_error_tests.cpp index 8710efd..c6b8fea 100644 --- a/src/script/tests/fn_error_tests.cpp +++ b/src/script/tests/fn_error_tests.cpp @@ -1,25 +1,25 @@ -/** - * \file fn_error_tests.cpp - * \brief Automated test for the error() function. - * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "script_tests.h" - -SUITE(script) -{ - TEST_FIXTURE(FxScript, Error_Exists_OnStartup) - { - const char* result = script_run_string(script, - "return (error ~= nil)"); - CHECK_EQUAL("true", result); - } - - TEST_FIXTURE(FxScript, Error_SetsSessionError_OnCall) - { - script_run_string(script, - "error('an error message')"); - CHECK_EQUAL("[string \"error('an error message')\"]:1: an error message", error_get()); - } -} +/** + * \file fn_error_tests.cpp + * \brief Automated test for the error() function. + * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "script_tests.h" + +SUITE(script) +{ + TEST_FIXTURE(FxScript, Error_Exists_OnStartup) + { + const char* result = script_run_string(script, + "return (error ~= nil)"); + CHECK_EQUAL("true", result); + } + + TEST_FIXTURE(FxScript, Error_SetsSessionError_OnCall) + { + script_run_string(script, + "error('an error message')"); + CHECK_EQUAL("[string \"error('an error message')\"]:1: an error message", error_get()); + } +} diff --git a/src/script/tests/fn_files_tests.cpp b/src/script/tests/fn_files_tests.cpp index 3ae5e1a..0fad2b4 100644 --- a/src/script/tests/fn_files_tests.cpp +++ b/src/script/tests/fn_files_tests.cpp @@ -1,35 +1,35 @@ -/** - * \file fn_files_tests.cpp - * \brief Automated tests for the files() function. - * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "script_tests.h" - - -SUITE(script) -{ - TEST_FIXTURE(FxAccessor, Files_Exists_OnStartup) - { - const char* result = script_run_string(script, - "return (files ~= nil)"); - CHECK_EQUAL("true", result); - } - - TEST_FIXTURE(FxAccessor, Files_Error_OnNoActiveProject) - { - Script script = script_create(); - const char* result = script_run_string(script, "files {'hello.c'}"); - CHECK_EQUAL("no active project", result); - script_destroy(script); - } - - TEST_FIXTURE(FxAccessor, Files_CanRoundtrip) - { - const char* result = script_run_string(script, - "files {'hello.c'};" - "return files()[1]"); - CHECK_EQUAL("hello.c", result); - } -} +/** + * \file fn_files_tests.cpp + * \brief Automated tests for the files() function. + * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "script_tests.h" + + +SUITE(script) +{ + TEST_FIXTURE(FxAccessor, Files_Exists_OnStartup) + { + const char* result = script_run_string(script, + "return (files ~= nil)"); + CHECK_EQUAL("true", result); + } + + TEST_FIXTURE(FxAccessor, Files_Error_OnNoActiveProject) + { + Script script = script_create(); + const char* result = script_run_string(script, "files {'hello.c'}"); + CHECK_EQUAL("no active project", result); + script_destroy(script); + } + + TEST_FIXTURE(FxAccessor, Files_CanRoundtrip) + { + const char* result = script_run_string(script, + "files {'hello.c'};" + "return files()[1]"); + CHECK_EQUAL("hello.c", result); + } +} diff --git a/src/script/tests/fn_getcwd_tests.cpp b/src/script/tests/fn_getcwd_tests.cpp index 4903c81..94ea7ce 100644 --- a/src/script/tests/fn_getcwd_tests.cpp +++ b/src/script/tests/fn_getcwd_tests.cpp @@ -1,29 +1,29 @@ -/** - * \file fn_getcwd_tests.cpp - * \brief Automated test for the getcwd() function. - * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "script_tests.h" -extern "C" { -#include "base/cstr.h" -} - - -SUITE(script) -{ - TEST_FIXTURE(FxScript, GetCwd_Exists_OnStartup) - { - const char* result = script_run_string(script, - "return (os.getcwd ~= nil)"); - CHECK_EQUAL("true", result); - } - - TEST_FIXTURE(FxScript, GetCwd_ReturnsCwd) - { - const char* result = script_run_string(script, - "return os.getcwd()"); - CHECK(cstr_ends_with(result, "/src")); - } -} +/** + * \file fn_getcwd_tests.cpp + * \brief Automated test for the getcwd() function. + * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "script_tests.h" +extern "C" { +#include "base/cstr.h" +} + + +SUITE(script) +{ + TEST_FIXTURE(FxScript, GetCwd_Exists_OnStartup) + { + const char* result = script_run_string(script, + "return (os.getcwd ~= nil)"); + CHECK_EQUAL("true", result); + } + + TEST_FIXTURE(FxScript, GetCwd_ReturnsCwd) + { + const char* result = script_run_string(script, + "return os.getcwd()"); + CHECK(cstr_ends_with(result, "/src")); + } +} diff --git a/src/script/tests/fn_guid_tests.cpp b/src/script/tests/fn_guid_tests.cpp index d98cfd6..3650674 100644 --- a/src/script/tests/fn_guid_tests.cpp +++ b/src/script/tests/fn_guid_tests.cpp @@ -1,45 +1,45 @@ -/** - * \file fn_guid_tests.cpp - * \brief Automated tests for the guid() function. - * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "script_tests.h" -extern "C" { -#include "base/guid.h" -} - - -SUITE(script) -{ - TEST_FIXTURE(FxAccessor, Guid_Exists_OnStartup) - { - const char* result = script_run_string(script, - "return (guid ~= nil)"); - CHECK_EQUAL("true", result); - } - - TEST_FIXTURE(FxAccessor, Guid_Error_OnNoActiveProject) - { - Script script = script_create(); - const char* result = script_run_string(script, "guid()"); - CHECK_EQUAL("no active project", result); - script_destroy(script); - } - - TEST_FIXTURE(FxAccessor, Guid_CanRoundtrip) - { - const char* result = script_run_string(script, - "guid '0C202E43-B9AF-4972-822B-5A42F0BF008C';" - "return guid()"); - CHECK_EQUAL("0C202E43-B9AF-4972-822B-5A42F0BF008C", result); - } - - TEST_FIXTURE(FxAccessor, Guid_RaisesError_OnInvalidGuid) - { - const char* result = script_run_string(script, - "guid '0C202E43-XXXX-4972-822B-5A42F0BF008C'"); - CHECK_EQUAL("invalid value '0C202E43-XXXX-4972-822B-5A42F0BF008C'", result); - } -} +/** + * \file fn_guid_tests.cpp + * \brief Automated tests for the guid() function. + * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "script_tests.h" +extern "C" { +#include "base/guid.h" +} + + +SUITE(script) +{ + TEST_FIXTURE(FxAccessor, Guid_Exists_OnStartup) + { + const char* result = script_run_string(script, + "return (guid ~= nil)"); + CHECK_EQUAL("true", result); + } + + TEST_FIXTURE(FxAccessor, Guid_Error_OnNoActiveProject) + { + Script script = script_create(); + const char* result = script_run_string(script, "guid()"); + CHECK_EQUAL("no active project", result); + script_destroy(script); + } + + TEST_FIXTURE(FxAccessor, Guid_CanRoundtrip) + { + const char* result = script_run_string(script, + "guid '0C202E43-B9AF-4972-822B-5A42F0BF008C';" + "return guid()"); + CHECK_EQUAL("0C202E43-B9AF-4972-822B-5A42F0BF008C", result); + } + + TEST_FIXTURE(FxAccessor, Guid_RaisesError_OnInvalidGuid) + { + const char* result = script_run_string(script, + "guid '0C202E43-XXXX-4972-822B-5A42F0BF008C'"); + CHECK_EQUAL("invalid value '0C202E43-XXXX-4972-822B-5A42F0BF008C'", result); + } +} diff --git a/src/script/tests/fn_include_tests.cpp b/src/script/tests/fn_include_tests.cpp index 1c81132..16be83a 100644 --- a/src/script/tests/fn_include_tests.cpp +++ b/src/script/tests/fn_include_tests.cpp @@ -1,36 +1,36 @@ -/** - * \file fn_include_tests.cpp - * \brief Automated test for the include() function. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "script_tests.h" -extern "C" { -#include "base/cstr.h" -} - - -SUITE(script) -{ - TEST_FIXTURE(FxScript, Include_Exists_OnStartup) - { - const char* result = script_run_string(script, - "return (include ~= nil)"); - CHECK_EQUAL("true", result); - } - - TEST_FIXTURE(FxScript, Include_ReturnsValue_OnPremake4Found) - { - const char* result = script_run_string(script, - "return include('testing/test_files')"); - CHECK_EQUAL("true", result); - } - - TEST_FIXTURE(FxScript, Include_SetsError_OnFileNotFound) - { - script_run_string(script, - "include('testing')"); - CHECK(cstr_ends_with(error_get(), "No such file or directory")); - } -} +/** + * \file fn_include_tests.cpp + * \brief Automated test for the include() function. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "script_tests.h" +extern "C" { +#include "base/cstr.h" +} + + +SUITE(script) +{ + TEST_FIXTURE(FxScript, Include_Exists_OnStartup) + { + const char* result = script_run_string(script, + "return (include ~= nil)"); + CHECK_EQUAL("true", result); + } + + TEST_FIXTURE(FxScript, Include_ReturnsValue_OnPremake4Found) + { + const char* result = script_run_string(script, + "return include('testing/test_files')"); + CHECK_EQUAL("true", result); + } + + TEST_FIXTURE(FxScript, Include_SetsError_OnFileNotFound) + { + script_run_string(script, + "include('testing')"); + CHECK(cstr_ends_with(error_get(), "No such file or directory")); + } +} diff --git a/src/script/tests/fn_language_tests.cpp b/src/script/tests/fn_language_tests.cpp index c018598..a2791da 100644 --- a/src/script/tests/fn_language_tests.cpp +++ b/src/script/tests/fn_language_tests.cpp @@ -1,42 +1,42 @@ -/** - * \file fn_language_tests.cpp - * \brief Automated tests for the language() function. - * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "script_tests.h" - - -SUITE(script) -{ - TEST_FIXTURE(FxAccessor, Language_Exists_OnStartup) - { - const char* result = script_run_string(script, - "return (language ~= nil)"); - CHECK_EQUAL("true", result); - } - - TEST_FIXTURE(FxAccessor, Guid_Error_OnNoActiveObject) - { - Script script = script_create(); - const char* result = script_run_string(script, "language()"); - CHECK_EQUAL("no active solution or project", result); - script_destroy(script); - } - - TEST_FIXTURE(FxAccessor, Language_CanRoundtrip) - { - const char* result = script_run_string(script, - "language 'c++';" - "return language()"); - CHECK_EQUAL("c++", result); - } - - TEST_FIXTURE(FxAccessor, Language_RaisesError_OnInvalidLanguage) - { - const char* result = script_run_string(script, - "language 'nosuch'"); - CHECK_EQUAL("invalid value 'nosuch'", result); - } -} +/** + * \file fn_language_tests.cpp + * \brief Automated tests for the language() function. + * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "script_tests.h" + + +SUITE(script) +{ + TEST_FIXTURE(FxAccessor, Language_Exists_OnStartup) + { + const char* result = script_run_string(script, + "return (language ~= nil)"); + CHECK_EQUAL("true", result); + } + + TEST_FIXTURE(FxAccessor, Guid_Error_OnNoActiveObject) + { + Script script = script_create(); + const char* result = script_run_string(script, "language()"); + CHECK_EQUAL("no active solution or project", result); + script_destroy(script); + } + + TEST_FIXTURE(FxAccessor, Language_CanRoundtrip) + { + const char* result = script_run_string(script, + "language 'c++';" + "return language()"); + CHECK_EQUAL("c++", result); + } + + TEST_FIXTURE(FxAccessor, Language_RaisesError_OnInvalidLanguage) + { + const char* result = script_run_string(script, + "language 'nosuch'"); + CHECK_EQUAL("invalid value 'nosuch'", result); + } +} diff --git a/src/script/tests/fn_project_tests.cpp b/src/script/tests/fn_project_tests.cpp index e52ddd3..1c27149 100644 --- a/src/script/tests/fn_project_tests.cpp +++ b/src/script/tests/fn_project_tests.cpp @@ -1,117 +1,126 @@ -/** - * \file fn_project_tests.cpp - * \brief Automated tests for the project() function. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "script_tests.h" - - -struct FnProject : FxScript -{ - FnProject() - { - script_run_string(script, - "sln = solution('MySolution');" - "prj = project('MyProject')"); - } -}; - - -SUITE(script) -{ - /************************************************************************** - * Initial state tests - **************************************************************************/ - - TEST_FIXTURE(FxScript, Project_Exists_OnStartup) - { - const char* result = script_run_string(script, - "return (project ~= nil)"); - CHECK_EQUAL("true", result); - } - - TEST_FIXTURE(FxScript, Project_ReturnsNil_OnNoActiveProject) - { - const char* result = script_run_string(script, - "return (project() == nil)"); - CHECK_EQUAL("true", result); - } - - /************************************************************************** - * Object creation tests - **************************************************************************/ - - TEST_FIXTURE(FxScript, Project_Fails_OnNoActiveSolution) - { - const char* result = script_run_string(script, "project('MyProject')"); - CHECK_EQUAL("no active solution", result); - } - - TEST_FIXTURE(FnProject, Project_ReturnsNewObject_OnNewName) - { - const char* result = script_run_string(script, - "return (prj ~= nil)"); - CHECK_EQUAL("true", result); - } - - TEST_FIXTURE(FnProject, Project_ReturnsObject_OnActiveProject) - { - const char* result = script_run_string(script, - "return (prj == project())"); - CHECK_EQUAL("true", result); - } - - TEST_FIXTURE(FnProject, Project_AddsToKeyList_OnNewName) - { - const char* result = script_run_string(script, - "return (prj == sln.projects['MyProject']);"); - CHECK_EQUAL("true", result); - } - - TEST_FIXTURE(FnProject, Project_AddsToIndexList_OnNewName) - { - const char* result = script_run_string(script, - "return (prj == sln.projects[1]);"); - CHECK_EQUAL("true", result); - } - - TEST_FIXTURE(FnProject, Project_IncrementsTableSize_OnNewName) - { - const char* result = script_run_string(script, - "return #sln.projects"); - CHECK_EQUAL("1", result); - } - - TEST_FIXTURE(FnProject, Project_ReturnsSameObject_OnExistingName) - { - const char* result = script_run_string(script, - "prj1 = project('SecondProject');" - "return (prj == project('MyProject'))"); - CHECK_EQUAL("true", result); - } - - - /************************************************************************** - * Initial object state tests - **************************************************************************/ - - TEST_FIXTURE(FnProject, Project_SetsName) - { - const char* result = script_run_string(script, "return prj.name"); - CHECK_EQUAL("MyProject", result); - } - - TEST_FIXTURE(FnProject, Project_SetsBaseDir) - { - const char* result = script_run_string(script, "return prj.basedir"); - CHECK_EQUAL("(string)", result); - } - - TEST_FIXTURE(FnProject, Project_SetsGuid) - { - const char* result = script_run_string(script, "return prj.guid"); - CHECK(result != NULL && strlen(result) == 36); - } -} +/** + * \file fn_project_tests.cpp + * \brief Automated tests for the project() function. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "script_tests.h" + + +struct FnProject : FxScript +{ + FnProject() + { + script_run_string(script, + "sln = solution('MySolution');" + " configurations {'Debug','Release'};" + "prj = project('MyProject')"); + } +}; + + +SUITE(script) +{ + /************************************************************************** + * Initial state tests + **************************************************************************/ + + TEST_FIXTURE(FxScript, Project_Exists_OnStartup) + { + const char* result = script_run_string(script, + "return (project ~= nil)"); + CHECK_EQUAL("true", result); + } + + TEST_FIXTURE(FxScript, Project_ReturnsNil_OnNoActiveProject) + { + const char* result = script_run_string(script, + "return (project() == nil)"); + CHECK_EQUAL("true", result); + } + + /************************************************************************** + * Object creation tests + **************************************************************************/ + + TEST_FIXTURE(FxScript, Project_Fails_OnNoActiveSolution) + { + const char* result = script_run_string(script, "project('MyProject')"); + CHECK_EQUAL("no active solution", result); + } + + TEST_FIXTURE(FnProject, Project_ReturnsNewObject_OnNewName) + { + const char* result = script_run_string(script, + "return (prj ~= nil)"); + CHECK_EQUAL("true", result); + } + + TEST_FIXTURE(FnProject, Project_ReturnsObject_OnActiveProject) + { + const char* result = script_run_string(script, + "return (prj == project())"); + CHECK_EQUAL("true", result); + } + + TEST_FIXTURE(FnProject, Project_AddsToKeyList_OnNewName) + { + const char* result = script_run_string(script, + "return (prj == sln.projects['MyProject']);"); + CHECK_EQUAL("true", result); + } + + TEST_FIXTURE(FnProject, Project_AddsToIndexList_OnNewName) + { + const char* result = script_run_string(script, + "return (prj == sln.projects[1]);"); + CHECK_EQUAL("true", result); + } + + TEST_FIXTURE(FnProject, Project_IncrementsTableSize_OnNewName) + { + const char* result = script_run_string(script, + "return #sln.projects"); + CHECK_EQUAL("1", result); + } + + TEST_FIXTURE(FnProject, Project_ReturnsSameObject_OnExistingName) + { + const char* result = script_run_string(script, + "prj1 = project('SecondProject');" + "return (prj == project('MyProject'))"); + CHECK_EQUAL("true", result); + } +/* + TEST_FIXTURE(FxScript, Project_RaisesError_OnNoConfigurations) + { + const char* result = script_run_string(script, + "sln = solution('MySolution');" + "prj = project('MyProject')"); + CHECK_EQUAL("no configurations defined", result); + } +*/ + + /************************************************************************** + * Initial object state tests + **************************************************************************/ + + TEST_FIXTURE(FnProject, Project_SetsName) + { + const char* result = script_run_string(script, "return prj.name"); + CHECK_EQUAL("MyProject", result); + } + + TEST_FIXTURE(FnProject, Project_SetsBaseDir) + { + const char* result = script_run_string(script, "return prj.basedir"); + CHECK_EQUAL("(string)", result); + } + + TEST_FIXTURE(FnProject, Project_SetsGuid) + { + const char* result = script_run_string(script, "return prj.guid"); + CHECK(result != NULL && strlen(result) == 36); + } +} diff --git a/src/script/tests/fn_solution_tests.cpp b/src/script/tests/fn_solution_tests.cpp index ff00a26..a26ea41 100644 --- a/src/script/tests/fn_solution_tests.cpp +++ b/src/script/tests/fn_solution_tests.cpp @@ -1,120 +1,120 @@ -/** - * \file fn_solution_tests.cpp - * \brief Automated tests for the solution() function. - * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "script_tests.h" - - -struct FnSolution : FxScript -{ - FnSolution() - { - script_run_string(script, "sln = solution('MySolution');"); - } -}; - - -SUITE(script) -{ - /************************************************************************** - * Initial state tests - **************************************************************************/ - - TEST_FIXTURE(FxScript, Solution_Exists_OnStartup) - { - const char* result = script_run_string(script, - "return (solution ~= nil)"); - CHECK_EQUAL("true", result); - } - - TEST_FIXTURE(FxScript, Solution_ReturnsNil_OnNoActiveSolution) - { - const char* result = script_run_string(script, - "return (solution() == nil)"); - CHECK_EQUAL("true", result); - } - - TEST_FIXTURE(FxScript, Solutions_Exists_OnStartup) - { - const char* result = script_run_string(script, - "return #_SOLUTIONS"); - CHECK_EQUAL("0", result); - } - - - /************************************************************************** - * Object creation tests - **************************************************************************/ - - TEST_FIXTURE(FnSolution, Solution_ReturnsNewObject_OnNewName) - { - const char* result = script_run_string(script, - "return (sln ~= nil)"); - CHECK_EQUAL("true", result); - } - - TEST_FIXTURE(FnSolution, Solution_ReturnsObject_OnActiveSolution) - { - const char* result = script_run_string(script, - "return (sln == solution())"); - CHECK_EQUAL("true", result); - } - - TEST_FIXTURE(FnSolution, Solution_AddsToKeyList_OnNewName) - { - const char* result = script_run_string(script, - "return (sln == _SOLUTIONS['MySolution']);"); - CHECK_EQUAL("true", result); - } - - TEST_FIXTURE(FnSolution, Solution_AddsToIndexList_OnNewName) - { - const char* result = script_run_string(script, - "return (sln == _SOLUTIONS[1]);"); - CHECK_EQUAL("true", result); - } - - TEST_FIXTURE(FnSolution, Solution_IncrementsTableSize_OnNewName) - { - const char* result = script_run_string(script, - "return #_SOLUTIONS;"); - CHECK_EQUAL("1", result); - } - - TEST_FIXTURE(FnSolution, Solution_ReturnsSameObject_OnExistingName) - { - const char* result = script_run_string(script, - "sln1 = solution('SecondSolution');" - "return (sln == solution('MySolution'))"); - CHECK_EQUAL("true", result); - } - - - /************************************************************************** - * Initial object state tests - **************************************************************************/ - - TEST_FIXTURE(FnSolution, Solution_SetsName) - { - const char* result = script_run_string(script, - "return sln.name"); - CHECK_EQUAL("MySolution", result); - } - - TEST_FIXTURE(FnSolution, Solution_SetsBaseDir) - { - const char* result = script_run_string(script, - "return sln.basedir"); - CHECK_EQUAL("(string)", result); - } - - TEST_FIXTURE(FnSolution, Solution_HasEmptyProjectsList) - { - const char* result = script_run_string(script, - "return #sln.projects"); - CHECK_EQUAL("0", result); - } -} +/** + * \file fn_solution_tests.cpp + * \brief Automated tests for the solution() function. + * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "script_tests.h" + + +struct FnSolution : FxScript +{ + FnSolution() + { + script_run_string(script, "sln = solution('MySolution');"); + } +}; + + +SUITE(script) +{ + /************************************************************************** + * Initial state tests + **************************************************************************/ + + TEST_FIXTURE(FxScript, Solution_Exists_OnStartup) + { + const char* result = script_run_string(script, + "return (solution ~= nil)"); + CHECK_EQUAL("true", result); + } + + TEST_FIXTURE(FxScript, Solution_ReturnsNil_OnNoActiveSolution) + { + const char* result = script_run_string(script, + "return (solution() == nil)"); + CHECK_EQUAL("true", result); + } + + TEST_FIXTURE(FxScript, Solutions_Exists_OnStartup) + { + const char* result = script_run_string(script, + "return #_SOLUTIONS"); + CHECK_EQUAL("0", result); + } + + + /************************************************************************** + * Object creation tests + **************************************************************************/ + + TEST_FIXTURE(FnSolution, Solution_ReturnsNewObject_OnNewName) + { + const char* result = script_run_string(script, + "return (sln ~= nil)"); + CHECK_EQUAL("true", result); + } + + TEST_FIXTURE(FnSolution, Solution_ReturnsObject_OnActiveSolution) + { + const char* result = script_run_string(script, + "return (sln == solution())"); + CHECK_EQUAL("true", result); + } + + TEST_FIXTURE(FnSolution, Solution_AddsToKeyList_OnNewName) + { + const char* result = script_run_string(script, + "return (sln == _SOLUTIONS['MySolution']);"); + CHECK_EQUAL("true", result); + } + + TEST_FIXTURE(FnSolution, Solution_AddsToIndexList_OnNewName) + { + const char* result = script_run_string(script, + "return (sln == _SOLUTIONS[1]);"); + CHECK_EQUAL("true", result); + } + + TEST_FIXTURE(FnSolution, Solution_IncrementsTableSize_OnNewName) + { + const char* result = script_run_string(script, + "return #_SOLUTIONS;"); + CHECK_EQUAL("1", result); + } + + TEST_FIXTURE(FnSolution, Solution_ReturnsSameObject_OnExistingName) + { + const char* result = script_run_string(script, + "sln1 = solution('SecondSolution');" + "return (sln == solution('MySolution'))"); + CHECK_EQUAL("true", result); + } + + + /************************************************************************** + * Initial object state tests + **************************************************************************/ + + TEST_FIXTURE(FnSolution, Solution_SetsName) + { + const char* result = script_run_string(script, + "return sln.name"); + CHECK_EQUAL("MySolution", result); + } + + TEST_FIXTURE(FnSolution, Solution_SetsBaseDir) + { + const char* result = script_run_string(script, + "return sln.basedir"); + CHECK_EQUAL("(string)", result); + } + + TEST_FIXTURE(FnSolution, Solution_HasEmptyProjectsList) + { + const char* result = script_run_string(script, + "return #sln.projects"); + CHECK_EQUAL("0", result); + } +} diff --git a/src/script/tests/script_tests.cpp b/src/script/tests/script_tests.cpp index e175906..9a8d792 100644 --- a/src/script/tests/script_tests.cpp +++ b/src/script/tests/script_tests.cpp @@ -1,52 +1,52 @@ -/** - * \file script_tests.cpp - * \brief Automated test for the project scripting engine. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "testing/testing.h" -extern "C" { -#include "script/script.h" -#include "base/error.h" -} - - -/** - * Run the suite of project scripting engine automated tests. - * \returns OKAY if all tests completed successfully. - */ -int script_tests() -{ - int z = OKAY; - if (z == OKAY) z = tests_run_suite("script"); - if (z == OKAY) z = tests_run_suite("unload"); - return z; -} - - -struct FxScript -{ - Script script; - - FxScript() - { - script = script_create(); - } - - ~FxScript() - { - script_destroy(script); - error_clear(); - } -}; - - -SUITE(script) -{ - TEST_FIXTURE(FxScript, ScriptCreate_ReturnsObject) - { - CHECK(script != NULL); - } -} - +/** + * \file script_tests.cpp + * \brief Automated test for the project scripting engine. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "testing/testing.h" +extern "C" { +#include "script/script.h" +#include "base/error.h" +} + + +/** + * Run the suite of project scripting engine automated tests. + * \returns OKAY if all tests completed successfully. + */ +int script_tests() +{ + int z = OKAY; + if (z == OKAY) z = tests_run_suite("script"); + if (z == OKAY) z = tests_run_suite("unload"); + return z; +} + + +struct FxScript +{ + Script script; + + FxScript() + { + script = script_create(); + } + + ~FxScript() + { + script_destroy(script); + error_clear(); + } +}; + + +SUITE(script) +{ + TEST_FIXTURE(FxScript, ScriptCreate_ReturnsObject) + { + CHECK(script != NULL); + } +} + diff --git a/src/script/tests/script_tests.h b/src/script/tests/script_tests.h index 6790e58..5791ccc 100644 --- a/src/script/tests/script_tests.h +++ b/src/script/tests/script_tests.h @@ -1,39 +1,40 @@ -/** - * \file script_tests.h - * \brief Common fixtures for script function tests. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "testing/testing.h" -extern "C" { -#include "script/script.h" -#include "base/error.h" -} - - -struct FxScript -{ - Script script; - - FxScript() - { - script = script_create(); - } - - ~FxScript() - { - script_destroy(script); - error_clear(); - } -}; - - -struct FxAccessor : FxScript -{ - FxAccessor() - { - script_run_string(script, - "sln = solution 'MySolution';" - "prj = project 'MyProject';"); - } -}; +/** + * \file script_tests.h + * \brief Common fixtures for script function tests. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "testing/testing.h" +extern "C" { +#include "script/script.h" +#include "base/error.h" +} + + +struct FxScript +{ + Script script; + + FxScript() + { + script = script_create(); + } + + ~FxScript() + { + script_destroy(script); + error_clear(); + } +}; + + +struct FxAccessor : FxScript +{ + FxAccessor() + { + script_run_string(script, + "sln = solution 'MySolution';" + " configurations {'Debug','Release'};" + "prj = project 'MyProject';"); + } +}; diff --git a/src/script/tests/unload_project_tests.cpp b/src/script/tests/unload_project_tests.cpp index f35c14f..1bc8833 100644 --- a/src/script/tests/unload_project_tests.cpp +++ b/src/script/tests/unload_project_tests.cpp @@ -1,85 +1,86 @@ -/** - * \file unload_project_tests.cpp - * \brief Automated tests for project object unloading from the script environment. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "testing/testing.h" -extern "C" { -#include "script/script_internal.h" -} - - -struct FxUnloadProject -{ - Script script; - lua_State* L; - Project prj; - - FxUnloadProject() - { - script = script_create(); - L = script_get_lua(script); - - prj = project_create(); - - script_run_string(script, - "solution('MySolution');" - "prj = project('MyProject');" - " guid '0C202E43-B9AF-4972-822B-5A42F0BF008C';" - " language 'c++';" - " files { 'Hello.cpp', 'Goodbye.cpp' };" - "return prj"); - } - - ~FxUnloadProject() - { - project_destroy(prj); - script_destroy(script); - } -}; - - -SUITE(unload) -{ - TEST_FIXTURE(FxUnloadProject, UnloadProject_SetsName) - { - unload_project(L, prj); - const char* result = project_get_name(prj); - CHECK_EQUAL("MyProject", result); - } - - TEST_FIXTURE(FxUnloadProject, UnloadProject_SetsBaseDir) - { - unload_project(L, prj); - const char* result = project_get_base_dir(prj); - CHECK_EQUAL("(string)", result); - } - - TEST_FIXTURE(FxUnloadProject, UnloadProject_UnloadsFiles) - { - unload_project(L, prj); - Strings files = project_get_files(prj); - CHECK(strings_size(files) == 2); - if (strings_size(files) == 2) { - CHECK_EQUAL("Hello.cpp", strings_item(files, 0)); - CHECK_EQUAL("Goodbye.cpp", strings_item(files, 1)); - } - } - - TEST_FIXTURE(FxUnloadProject, UnloadProject_SetsGuid) - { - unload_project(L, prj); - const char* result = project_get_guid(prj); - CHECK_EQUAL("0C202E43-B9AF-4972-822B-5A42F0BF008C", result); - } - - TEST_FIXTURE(FxUnloadProject, UnloadProject_SetsLanguage) - { - unload_project(L, prj); - const char* result = project_get_language(prj); - CHECK_EQUAL("c++", result); - } -} - +/** + * \file unload_project_tests.cpp + * \brief Automated tests for project object unloading from the script environment. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "testing/testing.h" +extern "C" { +#include "script/script_internal.h" +} + + +struct FxUnloadProject +{ + Script script; + lua_State* L; + Project prj; + + FxUnloadProject() + { + script = script_create(); + L = script_get_lua(script); + + prj = project_create(); + + script_run_string(script, + "solution('MySolution');" + " configurations {'Debug','Release'};" + "prj = project('MyProject');" + " guid '0C202E43-B9AF-4972-822B-5A42F0BF008C';" + " language 'c++';" + " files { 'Hello.cpp', 'Goodbye.cpp' };" + "return prj"); + } + + ~FxUnloadProject() + { + project_destroy(prj); + script_destroy(script); + } +}; + + +SUITE(unload) +{ + TEST_FIXTURE(FxUnloadProject, UnloadProject_SetsName) + { + unload_project(L, prj); + const char* result = project_get_name(prj); + CHECK_EQUAL("MyProject", result); + } + + TEST_FIXTURE(FxUnloadProject, UnloadProject_SetsBaseDir) + { + unload_project(L, prj); + const char* result = project_get_base_dir(prj); + CHECK_EQUAL("(string)", result); + } + + TEST_FIXTURE(FxUnloadProject, UnloadProject_UnloadsFiles) + { + unload_project(L, prj); + Strings files = project_get_files(prj); + CHECK(strings_size(files) == 2); + if (strings_size(files) == 2) { + CHECK_EQUAL("Hello.cpp", strings_item(files, 0)); + CHECK_EQUAL("Goodbye.cpp", strings_item(files, 1)); + } + } + + TEST_FIXTURE(FxUnloadProject, UnloadProject_SetsGuid) + { + unload_project(L, prj); + const char* result = project_get_guid(prj); + CHECK_EQUAL("0C202E43-B9AF-4972-822B-5A42F0BF008C", result); + } + + TEST_FIXTURE(FxUnloadProject, UnloadProject_SetsLanguage) + { + unload_project(L, prj); + const char* result = project_get_language(prj); + CHECK_EQUAL("c++", result); + } +} + diff --git a/src/script/tests/unload_solution_tests.cpp b/src/script/tests/unload_solution_tests.cpp index 06610b3..3d60f56 100644 --- a/src/script/tests/unload_solution_tests.cpp +++ b/src/script/tests/unload_solution_tests.cpp @@ -1,65 +1,65 @@ -/** - * \file unload_solution_tests.cpp - * \brief Automated tests for solution object unloading from the script environment. - * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "testing/testing.h" -extern "C" { -#include "script/script_internal.h" -} - - -struct FxUnloadSolution -{ - Script script; - lua_State* L; - Solution sln; - - FxUnloadSolution() - { - script = script_create(); - L = script_get_lua(script); - - sln = solution_create(); - - script_run_string(script, - "sln = solution('MySolution');" - " configurations { 'Debug', 'Release' };" - "return sln"); - } - - ~FxUnloadSolution() - { - solution_destroy(sln); - script_destroy(script); - } -}; - - -SUITE(unload) -{ - TEST_FIXTURE(FxUnloadSolution, UnloadSolution_SetsName) - { - unload_solution(L, sln); - const char* result = solution_get_name(sln); - CHECK_EQUAL("MySolution", result); - } - - TEST_FIXTURE(FxUnloadSolution, UnloadSolution_SetsBaseDir) - { - unload_solution(L, sln); - const char* result = solution_get_base_dir(sln); - CHECK_EQUAL("(string)", result); - } - - TEST_FIXTURE(FxUnloadSolution, UnloadSolution_SetsConfigurations) - { - unload_solution(L, sln); - CHECK(solution_num_configs(sln) == 2); - CHECK_EQUAL("Debug", solution_get_config_name(sln, 0)); - CHECK_EQUAL("Release", solution_get_config_name(sln, 1)); - } -} - +/** + * \file unload_solution_tests.cpp + * \brief Automated tests for solution object unloading from the script environment. + * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "testing/testing.h" +extern "C" { +#include "script/script_internal.h" +} + + +struct FxUnloadSolution +{ + Script script; + lua_State* L; + Solution sln; + + FxUnloadSolution() + { + script = script_create(); + L = script_get_lua(script); + + sln = solution_create(); + + script_run_string(script, + "sln = solution('MySolution');" + " configurations { 'Debug', 'Release' };" + "return sln"); + } + + ~FxUnloadSolution() + { + solution_destroy(sln); + script_destroy(script); + } +}; + + +SUITE(unload) +{ + TEST_FIXTURE(FxUnloadSolution, UnloadSolution_SetsName) + { + unload_solution(L, sln); + const char* result = solution_get_name(sln); + CHECK_EQUAL("MySolution", result); + } + + TEST_FIXTURE(FxUnloadSolution, UnloadSolution_SetsBaseDir) + { + unload_solution(L, sln); + const char* result = solution_get_base_dir(sln); + CHECK_EQUAL("(string)", result); + } + + TEST_FIXTURE(FxUnloadSolution, UnloadSolution_SetsConfigurations) + { + unload_solution(L, sln); + CHECK(solution_num_configs(sln) == 2); + CHECK_EQUAL("Debug", solution_get_config_name(sln, 0)); + CHECK_EQUAL("Release", solution_get_config_name(sln, 1)); + } +} + diff --git a/src/script/tests/unload_tests.cpp b/src/script/tests/unload_tests.cpp index 22d9493..cb8b3bc 100644 --- a/src/script/tests/unload_tests.cpp +++ b/src/script/tests/unload_tests.cpp @@ -1,174 +1,175 @@ -/** - * \file unload_tests.cpp - * \brief Automated tests for project object enumeration from the script environment. - * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "testing/testing.h" -extern "C" { -#include "script/script_internal.h" -} - -/* mock interface to object loaders */ - -static int num_solution_calls; -static int num_project_calls; - -static int stub_solution_func(lua_State* L, Solution sln) -{ - UNUSED(L); UNUSED(sln); - num_solution_calls++; - return OKAY; -} - -static int stub_solution_fail_func(lua_State* L, Solution sln) -{ - UNUSED(L); UNUSED(sln); - num_solution_calls++; - return !OKAY; -} - -static int stub_project_func(lua_State* L, Project prj) -{ - UNUSED(L); UNUSED(prj); - num_project_calls++; - return OKAY; -} - -static int stub_project_fail_func(lua_State* L, Project prj) -{ - UNUSED(L); UNUSED(prj); - num_project_calls++; - return !OKAY; -} - - -struct FxUnload -{ - Script script; - lua_State* L; - Array slns; - UnloadFuncs funcs; - - FxUnload() - { - script = script_create(); - L = script_get_lua(script); - - slns = array_create(); - - funcs.unload_solution = stub_solution_func; - funcs.unload_project = stub_project_func; - num_solution_calls = 0; - num_project_calls = 0; - } - - ~FxUnload() - { - array_destroy(slns); - script_destroy(script); - } -}; - - -struct FxUnload2 : FxUnload -{ - FxUnload2() - { - script_run_string(script, - "solution 'MySolution';" - " project 'MyProject';" - " project 'MyProject2';" - "solution 'MySolution2';"); - } -}; - - -SUITE(unload) -{ - TEST_FIXTURE(FxUnload, Unload_ReturnsOkay_OnEmptySession) - { - int result = unload_all(L, slns, &funcs); - CHECK(result == OKAY); - } - - TEST_FIXTURE(FxUnload, Unload_ReturnsEmptySession_OnEmptySession) - { - unload_all(L, slns, &funcs); - int n = array_size(slns); - CHECK(n == 0); - } - - TEST_FIXTURE(FxUnload2, Unload_ReturnsOkay_OnNonEmptySession) - { - int result = unload_all(L, slns, &funcs); - CHECK(result == OKAY); - } - - - /********************************************************************** - * Solution enumeration tests - **********************************************************************/ - - TEST_FIXTURE(FxUnload2, Unload_AddsSolutions_OnNonEmptySession) - { - unload_all(L, slns, &funcs); - int n = array_size(slns); - CHECK(n == 2); - } - - TEST_FIXTURE(FxUnload2, Unload_CallsSolutionFunc_OnEachSolution) - { - unload_all(L, slns, &funcs); - CHECK(num_solution_calls == 2); - } - - TEST_FIXTURE(FxUnload2, Unload_ReturnsNotOkay_OnSolutionFailure) - { - funcs.unload_solution = stub_solution_fail_func; - int result = unload_all(L, slns, &funcs); - CHECK(result != OKAY); - } - - TEST_FIXTURE(FxUnload2, Unload_AbortsSolutionLoop_OnNotOkay) - { - funcs.unload_solution = stub_solution_fail_func; - unload_all(L, slns, &funcs); - CHECK(num_solution_calls == 1); - } - - - /********************************************************************** - * Project enumeration tests - **********************************************************************/ - - TEST_FIXTURE(FxUnload2, Unload_AddsProjects_OnNonEmptySession) - { - unload_all(L, slns, &funcs); - Solution sln = (Solution)array_item(slns, 0); - int n = solution_num_projects(sln); - CHECK(n == 2); - } - - TEST_FIXTURE(FxUnload2, Unload_CallsProjectFunc_OnEachProject) - { - unload_all(L, slns, &funcs); - CHECK(num_project_calls == 2); - } - - TEST_FIXTURE(FxUnload2, Unload_ReturnsNotOkay_OnProjectFailure) - { - funcs.unload_project = stub_project_fail_func; - int result = unload_all(L, slns, &funcs); - CHECK(result != OKAY); - } - - TEST_FIXTURE(FxUnload2, Unload_AbortsProjectLoop_OnNotOkay) - { - funcs.unload_project = stub_project_fail_func; - unload_all(L, slns, &funcs); - CHECK(num_project_calls == 1); - } - -} +/** + * \file unload_tests.cpp + * \brief Automated tests for project object enumeration from the script environment. + * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "testing/testing.h" +extern "C" { +#include "script/script_internal.h" +} + +/* mock interface to object loaders */ + +static int num_solution_calls; +static int num_project_calls; + +static int stub_solution_func(lua_State* L, Solution sln) +{ + UNUSED(L); UNUSED(sln); + num_solution_calls++; + return OKAY; +} + +static int stub_solution_fail_func(lua_State* L, Solution sln) +{ + UNUSED(L); UNUSED(sln); + num_solution_calls++; + return !OKAY; +} + +static int stub_project_func(lua_State* L, Project prj) +{ + UNUSED(L); UNUSED(prj); + num_project_calls++; + return OKAY; +} + +static int stub_project_fail_func(lua_State* L, Project prj) +{ + UNUSED(L); UNUSED(prj); + num_project_calls++; + return !OKAY; +} + + +struct FxUnload +{ + Script script; + lua_State* L; + Array slns; + UnloadFuncs funcs; + + FxUnload() + { + script = script_create(); + L = script_get_lua(script); + + slns = array_create(); + + funcs.unload_solution = stub_solution_func; + funcs.unload_project = stub_project_func; + num_solution_calls = 0; + num_project_calls = 0; + } + + ~FxUnload() + { + array_destroy(slns); + script_destroy(script); + } +}; + + +struct FxUnload2 : FxUnload +{ + FxUnload2() + { + script_run_string(script, + "solution 'MySolution';" + " configurations{'Debug','Release'};" + " project 'MyProject';" + " project 'MyProject2';" + "solution 'MySolution2';"); + } +}; + + +SUITE(unload) +{ + TEST_FIXTURE(FxUnload, Unload_ReturnsOkay_OnEmptySession) + { + int result = unload_all(L, slns, &funcs); + CHECK(result == OKAY); + } + + TEST_FIXTURE(FxUnload, Unload_ReturnsEmptySession_OnEmptySession) + { + unload_all(L, slns, &funcs); + int n = array_size(slns); + CHECK(n == 0); + } + + TEST_FIXTURE(FxUnload2, Unload_ReturnsOkay_OnNonEmptySession) + { + int result = unload_all(L, slns, &funcs); + CHECK(result == OKAY); + } + + + /********************************************************************** + * Solution enumeration tests + **********************************************************************/ + + TEST_FIXTURE(FxUnload2, Unload_AddsSolutions_OnNonEmptySession) + { + unload_all(L, slns, &funcs); + int n = array_size(slns); + CHECK(n == 2); + } + + TEST_FIXTURE(FxUnload2, Unload_CallsSolutionFunc_OnEachSolution) + { + unload_all(L, slns, &funcs); + CHECK(num_solution_calls == 2); + } + + TEST_FIXTURE(FxUnload2, Unload_ReturnsNotOkay_OnSolutionFailure) + { + funcs.unload_solution = stub_solution_fail_func; + int result = unload_all(L, slns, &funcs); + CHECK(result != OKAY); + } + + TEST_FIXTURE(FxUnload2, Unload_AbortsSolutionLoop_OnNotOkay) + { + funcs.unload_solution = stub_solution_fail_func; + unload_all(L, slns, &funcs); + CHECK(num_solution_calls == 1); + } + + + /********************************************************************** + * Project enumeration tests + **********************************************************************/ + + TEST_FIXTURE(FxUnload2, Unload_AddsProjects_OnNonEmptySession) + { + unload_all(L, slns, &funcs); + Solution sln = (Solution)array_item(slns, 0); + int n = solution_num_projects(sln); + CHECK(n == 2); + } + + TEST_FIXTURE(FxUnload2, Unload_CallsProjectFunc_OnEachProject) + { + unload_all(L, slns, &funcs); + CHECK(num_project_calls == 2); + } + + TEST_FIXTURE(FxUnload2, Unload_ReturnsNotOkay_OnProjectFailure) + { + funcs.unload_project = stub_project_fail_func; + int result = unload_all(L, slns, &funcs); + CHECK(result != OKAY); + } + + TEST_FIXTURE(FxUnload2, Unload_AbortsProjectLoop_OnNotOkay) + { + funcs.unload_project = stub_project_fail_func; + unload_all(L, slns, &funcs); + CHECK(num_project_calls == 1); + } + +} diff --git a/src/script/unload.c b/src/script/unload.c index 0f1ad74..9fda9cb 100644 --- a/src/script/unload.c +++ b/src/script/unload.c @@ -1,156 +1,156 @@ -/** - * \file unload.c - * \brief Unload project objects from the scripting environment. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include -#include "premake.h" -#include "script/script_internal.h" - - -static int unload_solution_projects(lua_State* L, struct UnloadFuncs* funcs, Solution sln); - - -/** - * Copy project information out of the scripting environment and into C objects that - * can be more easily manipulated by the action code. - * \param L The Lua scripting engine state. - * \param slns An array to contain the list of unloaded solutions. - * \param funcs The unloading "interface", providing an opportunity to mock for automated testing. - * \returns OKAY if successful. - */ -int unload_all(lua_State* L, Array slns, struct UnloadFuncs* funcs) -{ - int si, sn, z = OKAY; - - assert(L); - assert(slns); - assert(funcs); - assert(funcs->unload_solution); - - /* iterate over the list of solutions */ - lua_getglobal(L, SOLUTIONS_KEY); - sn = luaL_getn(L, -1); - for (si = 1; z == OKAY && si <= sn; ++si) - { - Solution sln = solution_create(); - array_add(slns, sln); - lua_rawgeti(L, -1, si); - - /* hardcoded a standard set of configurations for now */ - solution_add_config_name(sln, "Debug"); - solution_add_config_name(sln, "Release"); - - /* extract the project fields */ - z = funcs->unload_solution(L, sln); - if (z == OKAY) - { - z = unload_solution_projects(L, funcs, sln); - } - - /* remove solution object from stack */ - lua_pop(L, 1); - } - - /* remove list of solutions from stack */ - lua_pop(L, 1); - return z; -} - - -static int unload_solution_projects(lua_State* L, struct UnloadFuncs* funcs, Solution sln) -{ - int pi, pn, z = OKAY; - - /* iterate over list of projects from the solution */ - lua_getfield(L, -1, PROJECTS_KEY); - pn = luaL_getn(L, -1); - for (pi = 1; z == OKAY && pi <= pn; ++pi) - { - Project prj = project_create(); - solution_add_project(sln, prj); - - /* unload the project fields */ - lua_rawgeti(L, -1, pi); - z = funcs->unload_project(L, prj); - - /* remove project object from stack */ - lua_pop(L, 1); - } - - /* remove list of projects from stack */ - lua_pop(L, 1); - return z; -} - - -int unload_fields(lua_State* L, Fields fields, struct FieldInfo* info) -{ - const char* value; - int fi; - - for (fi = 0; info[fi].name != NULL; ++fi) - { - Strings values = strings_create(); - - lua_getfield(L, -1, info[fi].name); - if (lua_istable(L, -1)) - { - int i, n; - n = luaL_getn(L, -1); - for (i = 1; i <= n; ++i) - { - lua_rawgeti(L, -1, i); - value = lua_tostring(L, -1); - if (value != NULL) - { - strings_add(values, value); - } - lua_pop(L, 1); - } - } - else - { - value = lua_tostring(L, -1); - if (value != NULL) - { - strings_add(values, value); - } - } - - /* remove the field value from the top of the stack */ - lua_pop(L, 1); - - /* store the field values */ - fields_set_values(fields, fi, values); - } - - return OKAY; -} - - -/** - * Unload information from the scripting environment for a particular solution. - * \param L The Lua scripting engine state. - * \param sln The solution object to be populated. - * \returns OKAY if successful. - */ -int unload_solution(lua_State* L, Solution sln) -{ - return unload_fields(L, solution_get_fields(sln), SolutionFieldInfo); -} - - -/** - * Unload information from the scripting environment for a particular project. - * \param L The Lua scripting engine state. - * \param prj The project object to be populated. - * \returns OKAY if successful. - */ -int unload_project(lua_State* L, Project prj) -{ - return unload_fields(L, project_get_fields(prj), ProjectFieldInfo); -} - - +/** + * \file unload.c + * \brief Unload project objects from the scripting environment. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include +#include "premake.h" +#include "script/script_internal.h" + + +static int unload_solution_projects(lua_State* L, struct UnloadFuncs* funcs, Solution sln); + + +/** + * Copy project information out of the scripting environment and into C objects that + * can be more easily manipulated by the action code. + * \param L The Lua scripting engine state. + * \param slns An array to contain the list of unloaded solutions. + * \param funcs The unloading "interface", providing an opportunity to mock for automated testing. + * \returns OKAY if successful. + */ +int unload_all(lua_State* L, Array slns, struct UnloadFuncs* funcs) +{ + int si, sn, z = OKAY; + + assert(L); + assert(slns); + assert(funcs); + assert(funcs->unload_solution); + + /* iterate over the list of solutions */ + lua_getglobal(L, SOLUTIONS_KEY); + sn = luaL_getn(L, -1); + for (si = 1; z == OKAY && si <= sn; ++si) + { + Solution sln = solution_create(); + array_add(slns, sln); + lua_rawgeti(L, -1, si); + + /* hardcoded a standard set of configurations for now */ + solution_add_config_name(sln, "Debug"); + solution_add_config_name(sln, "Release"); + + /* extract the project fields */ + z = funcs->unload_solution(L, sln); + if (z == OKAY) + { + z = unload_solution_projects(L, funcs, sln); + } + + /* remove solution object from stack */ + lua_pop(L, 1); + } + + /* remove list of solutions from stack */ + lua_pop(L, 1); + return z; +} + + +static int unload_solution_projects(lua_State* L, struct UnloadFuncs* funcs, Solution sln) +{ + int pi, pn, z = OKAY; + + /* iterate over list of projects from the solution */ + lua_getfield(L, -1, PROJECTS_KEY); + pn = luaL_getn(L, -1); + for (pi = 1; z == OKAY && pi <= pn; ++pi) + { + Project prj = project_create(); + solution_add_project(sln, prj); + + /* unload the project fields */ + lua_rawgeti(L, -1, pi); + z = funcs->unload_project(L, prj); + + /* remove project object from stack */ + lua_pop(L, 1); + } + + /* remove list of projects from stack */ + lua_pop(L, 1); + return z; +} + + +int unload_fields(lua_State* L, Fields fields, struct FieldInfo* info) +{ + const char* value; + int fi; + + for (fi = 0; info[fi].name != NULL; ++fi) + { + Strings values = strings_create(); + + lua_getfield(L, -1, info[fi].name); + if (lua_istable(L, -1)) + { + int i, n; + n = luaL_getn(L, -1); + for (i = 1; i <= n; ++i) + { + lua_rawgeti(L, -1, i); + value = lua_tostring(L, -1); + if (value != NULL) + { + strings_add(values, value); + } + lua_pop(L, 1); + } + } + else + { + value = lua_tostring(L, -1); + if (value != NULL) + { + strings_add(values, value); + } + } + + /* remove the field value from the top of the stack */ + lua_pop(L, 1); + + /* store the field values */ + fields_set_values(fields, fi, values); + } + + return OKAY; +} + + +/** + * Unload information from the scripting environment for a particular solution. + * \param L The Lua scripting engine state. + * \param sln The solution object to be populated. + * \returns OKAY if successful. + */ +int unload_solution(lua_State* L, Solution sln) +{ + return unload_fields(L, solution_get_fields(sln), SolutionFieldInfo); +} + + +/** + * Unload information from the scripting environment for a particular project. + * \param L The Lua scripting engine state. + * \param prj The project object to be populated. + * \returns OKAY if successful. + */ +int unload_project(lua_State* L, Project prj) +{ + return unload_fields(L, project_get_fields(prj), ProjectFieldInfo); +} + + diff --git a/src/session/session.c b/src/session/session.c index 75b551c..6414188 100644 --- a/src/session/session.c +++ b/src/session/session.c @@ -1,363 +1,363 @@ -/** - * \file session.c - * \brief Context for a program execution session. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include -#include -#include -#include -#include -#include "premake.h" -#include "session.h" -#include "script/script.h" -#include "base/array.h" -#include "base/cstr.h" -#include "base/error.h" - - -DEFINE_CLASS(Session) -{ - Script script; - Array solutions; - Stream active_stream; -}; - - -/** - * Create a new session object. - * \returns A new session object, or NULL if the scripting engine fails to start. - */ -Session session_create(void) -{ - Session sess; - - /* create an instance of the project scripting engine */ - Script script = script_create(); - if (script == NULL) - { - return NULL; - } - - /* create and return the session object */ - sess = ALLOC_CLASS(Session); - sess->script = script; - sess->solutions = array_create(); - sess->active_stream = NULL; - return sess; -} - - -/** - * Destroy a session object and release the associated memory. - * \param sess The session object to destroy. - */ -void session_destroy(Session sess) -{ - int i, n; - - assert(sess); - - n = session_num_solutions(sess); - for (i = 0; i < n; ++i) - { - Solution sln = session_get_solution(sess, i); - solution_destroy(sln); - } - - script_destroy(sess->script); - array_destroy(sess->solutions); - free(sess); -} - - -/** - * Adds a new solution to the list of solutions contained by the session. - * \param sess The session object. - * \param sln The new solution to add. - */ -void session_add_solution(Session sess, Solution sln) -{ - assert(sess); - assert(sln); - array_add(sess->solutions, sln); -} - - -/** - * A bit of black magic: this function acts as a special token for the project handler - * function list to indicate where configurations should appear. For more details, see - * the implementation of session_enumerate_objects(). - * \param sess The session object. - * \param prj The target project. - * \param strm The currently active output stream. - * \returns OKAY. - */ -int session_enumerate_configurations(Session sess, Project prj, Stream strm) -{ - UNUSED(sess); - UNUSED(prj); - UNUSED(strm); - return OKAY; -} - - -/** - * Iterate the project objects contained by the session and hand them off to handler callbacks. - * \param sess The session object. - * \param sln_funcs A list of per-solution object callbacks. - * \param prj_funcs A list of per-project object callbacks. - * \param cfg_funcs A list of per-configuration callbacks. - * \returns OKAY if successful. - */ -int session_enumerate_objects(Session sess, SessionSolutionCallback* sln_funcs, SessionProjectCallback* prj_funcs, SessionProjectCallback* cfg_funcs) -{ - int si, sn; - int result = OKAY; - - assert(sess); - assert(sln_funcs); - assert(prj_funcs); - assert(cfg_funcs); - - /* enumerate solutions */ - sn = session_num_solutions(sess); - for (si = 0; si < sn; ++si) - { - /* call all solution functions */ - int fi, pi, pn; - Solution sln = session_get_solution(sess, si); - for (fi = 0; result == OKAY && sln_funcs[fi] != NULL; ++fi) - { - result = sln_funcs[fi](sess, sln, sess->active_stream); - } - - /* enumerate projects */ - pn = solution_num_projects(sln); - for (pi = 0; pi < pn; ++pi) - { - Project prj = solution_get_project(sln, pi); - for (fi = 0; result == OKAY && prj_funcs[fi]; ++fi) - { - /* A bit of black magic here - I use the "session_enumerate_configurations" - * token to indicate where the list of configurations should appear in the - * project file. */ - if (prj_funcs[fi] == session_enumerate_configurations) - { - int ci, cn; - cn = solution_num_configs(sln); - for (ci = 0; result == OKAY && ci < cn; ++ci) - { - int cfi; - const char* cfg_name = solution_get_config_name(sln, ci); - project_set_configuration_filter(prj, cfg_name); - - /* enumerate configurations */ - for (cfi = 0; result == OKAY && cfg_funcs[cfi]; ++cfi) - { - result = cfg_funcs[cfi](sess, prj, sess->active_stream); - } - } - } - else - { - result = prj_funcs[fi](sess, prj, sess->active_stream); - } - } - } - } - - if (sess->active_stream) - { - stream_destroy(sess->active_stream); - sess->active_stream = NULL; - } - - return result; -} - - -/** - * Get the action name to be performed by this execution run. - * \param sess The session object. - * \returns The action name if set, or NULL. - */ -const char* session_get_action(Session sess) -{ - assert(sess); - return script_get_action(sess->script); -} - - -/** - * Retrieve the currently active output stream. - * \param sess The session object. - * \return The currently active stream, or NULL if no stream is active. - */ -Stream session_get_active_stream(Session sess) -{ - assert(sess); - return sess->active_stream; -} - - -/** - * Retrieve the contained solution at the given index in the solution list. - * \param sess The session object. - * \param index The index of the solution to return. - * \returns The solution object at the given index. - */ -Solution session_get_solution(Session sess, int index) -{ - assert(sess); - assert(index >= 0 && array_size(sess->solutions) > 0 && index < array_size(sess->solutions)); - return (Solution)array_item(sess->solutions, index); -} - - -/** - * Return the number of solutions contained by the session. - * \param sess The session object. - */ -int session_num_solutions(Session sess) -{ - assert(sess); - return array_size(sess->solutions); -} - - -/** - * Execute a script stored in a file. - * \param sess The session object. - * \param filename The name of the file containing the script code to be executed. - * \returns If the script returns a value, it is converted to a string and returned. - * If the script does not return a value, NULL is returned. If an error - * occurs in the script, the error message is returned. - */ -const char* session_run_file(Session sess, const char* filename) -{ - assert(sess); - return script_run_file(sess->script, filename); -} - - -/** - * Execute a bit of script stored in a string. - * \param sess The session object. - * \param code The string containing the script code to be executed. - * \returns If the script returns a value, it is converted to a string and returned. - * If the script does not return a value, NULL is returned. If an error - * occurs in the script, the error message is returned. - */ -const char* session_run_string(Session sess, const char* code) -{ - assert(sess); - return script_run_string(sess->script, code); -} - - -/** - * Set the action name to be performed on this execution pass. The action name will - * be placed in the _ACTION script environment global. - * \param sess The current execution session context. - * \param action The name of the action to be performed. - */ -void session_set_action(Session sess, const char* action) -{ - assert(sess); - script_set_action(sess->script, action); -} - - -/** - * Set the active output stream, which will be passed to subsequent callbacks during - * object processing by session_enumerate_objects(). If there is an existing active - * stream it will be released before setting the new stream. - * \param sess The current execution session context. - * \param strm The new active stream. - */ -void session_set_active_stream(Session sess, Stream strm) -{ - assert(sess); - assert(strm); - if (sess->active_stream) - { - stream_destroy(sess->active_stream); - } - sess->active_stream = strm; -} - - -/** - * Copy project information out of the scripting environment and into C objects that - * can be more easily manipulated by the action code. - * \param sess The session object which contains the scripted project objects. - * \returns OKAY if successful. - */ -int session_unload(Session sess) -{ - assert(sess); - return script_unload(sess->script, sess->solutions); -} - - -/** - * Make sure that all required objects and values have been defined by the project script. - * \param sess The session to validate. - * \param features The features (language, kind, etc.) supported by the current action. - * \returns OKAY if the session is valid. - */ -int session_validate(Session sess, SessionFeatures* features) -{ - int si, sn; - - assert(sess); - assert(features); - - sn = session_num_solutions(sess); - for (si = 0; si < sn; ++si) - { - int pi, pn; - Solution sln = session_get_solution(sess, si); - - /* every solution must have at least one project */ - pn = solution_num_projects(sln); - if (pn == 0) - { - error_set("no projects defined for solution '%s'", solution_get_name(sln)); - return !OKAY; - } - - for (pi = 0; pi < pn; ++pi) - { - int i; - - Project prj = solution_get_project(sln, pi); - const char* prj_name = project_get_name(prj); - const char* prj_lang = project_get_language(prj); - - /* every project must have a language defined */ - if (prj_lang == NULL) - { - error_set("no language defined for project '%s'", prj_name); - return !OKAY; - } - - /* action must support the language */ - for (i = 0; features->languages[i] != NULL; ++i) - { - if (cstr_eq(prj_lang, features->languages[i])) - break; - } - - if (features->languages[i] == NULL) - { - error_set("%s language projects are not supported by this action", prj_lang); - return !OKAY; - } - } - } - - return OKAY; -} +/** + * \file session.c + * \brief Context for a program execution session. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include +#include +#include +#include +#include +#include "premake.h" +#include "session.h" +#include "script/script.h" +#include "base/array.h" +#include "base/cstr.h" +#include "base/error.h" + + +DEFINE_CLASS(Session) +{ + Script script; + Array solutions; + Stream active_stream; +}; + + +/** + * Create a new session object. + * \returns A new session object, or NULL if the scripting engine fails to start. + */ +Session session_create(void) +{ + Session sess; + + /* create an instance of the project scripting engine */ + Script script = script_create(); + if (script == NULL) + { + return NULL; + } + + /* create and return the session object */ + sess = ALLOC_CLASS(Session); + sess->script = script; + sess->solutions = array_create(); + sess->active_stream = NULL; + return sess; +} + + +/** + * Destroy a session object and release the associated memory. + * \param sess The session object to destroy. + */ +void session_destroy(Session sess) +{ + int i, n; + + assert(sess); + + n = session_num_solutions(sess); + for (i = 0; i < n; ++i) + { + Solution sln = session_get_solution(sess, i); + solution_destroy(sln); + } + + script_destroy(sess->script); + array_destroy(sess->solutions); + free(sess); +} + + +/** + * Adds a new solution to the list of solutions contained by the session. + * \param sess The session object. + * \param sln The new solution to add. + */ +void session_add_solution(Session sess, Solution sln) +{ + assert(sess); + assert(sln); + array_add(sess->solutions, sln); +} + + +/** + * A bit of black magic: this function acts as a special token for the project handler + * function list to indicate where configurations should appear. For more details, see + * the implementation of session_enumerate_objects(). + * \param sess The session object. + * \param prj The target project. + * \param strm The currently active output stream. + * \returns OKAY. + */ +int session_enumerate_configurations(Session sess, Project prj, Stream strm) +{ + UNUSED(sess); + UNUSED(prj); + UNUSED(strm); + return OKAY; +} + + +/** + * Iterate the project objects contained by the session and hand them off to handler callbacks. + * \param sess The session object. + * \param sln_funcs A list of per-solution object callbacks. + * \param prj_funcs A list of per-project object callbacks. + * \param cfg_funcs A list of per-configuration callbacks. + * \returns OKAY if successful. + */ +int session_enumerate_objects(Session sess, SessionSolutionCallback* sln_funcs, SessionProjectCallback* prj_funcs, SessionProjectCallback* cfg_funcs) +{ + int si, sn; + int result = OKAY; + + assert(sess); + assert(sln_funcs); + assert(prj_funcs); + assert(cfg_funcs); + + /* enumerate solutions */ + sn = session_num_solutions(sess); + for (si = 0; si < sn; ++si) + { + /* call all solution functions */ + int fi, pi, pn; + Solution sln = session_get_solution(sess, si); + for (fi = 0; result == OKAY && sln_funcs[fi] != NULL; ++fi) + { + result = sln_funcs[fi](sess, sln, sess->active_stream); + } + + /* enumerate projects */ + pn = solution_num_projects(sln); + for (pi = 0; pi < pn; ++pi) + { + Project prj = solution_get_project(sln, pi); + for (fi = 0; result == OKAY && prj_funcs[fi]; ++fi) + { + /* A bit of black magic here - I use the "session_enumerate_configurations" + * token to indicate where the list of configurations should appear in the + * project file. */ + if (prj_funcs[fi] == session_enumerate_configurations) + { + int ci, cn; + cn = solution_num_configs(sln); + for (ci = 0; result == OKAY && ci < cn; ++ci) + { + int cfi; + const char* cfg_name = solution_get_config_name(sln, ci); + project_set_configuration_filter(prj, cfg_name); + + /* enumerate configurations */ + for (cfi = 0; result == OKAY && cfg_funcs[cfi]; ++cfi) + { + result = cfg_funcs[cfi](sess, prj, sess->active_stream); + } + } + } + else + { + result = prj_funcs[fi](sess, prj, sess->active_stream); + } + } + } + } + + if (sess->active_stream) + { + stream_destroy(sess->active_stream); + sess->active_stream = NULL; + } + + return result; +} + + +/** + * Get the action name to be performed by this execution run. + * \param sess The session object. + * \returns The action name if set, or NULL. + */ +const char* session_get_action(Session sess) +{ + assert(sess); + return script_get_action(sess->script); +} + + +/** + * Retrieve the currently active output stream. + * \param sess The session object. + * \return The currently active stream, or NULL if no stream is active. + */ +Stream session_get_active_stream(Session sess) +{ + assert(sess); + return sess->active_stream; +} + + +/** + * Retrieve the contained solution at the given index in the solution list. + * \param sess The session object. + * \param index The index of the solution to return. + * \returns The solution object at the given index. + */ +Solution session_get_solution(Session sess, int index) +{ + assert(sess); + assert(index >= 0 && array_size(sess->solutions) > 0 && index < array_size(sess->solutions)); + return (Solution)array_item(sess->solutions, index); +} + + +/** + * Return the number of solutions contained by the session. + * \param sess The session object. + */ +int session_num_solutions(Session sess) +{ + assert(sess); + return array_size(sess->solutions); +} + + +/** + * Execute a script stored in a file. + * \param sess The session object. + * \param filename The name of the file containing the script code to be executed. + * \returns If the script returns a value, it is converted to a string and returned. + * If the script does not return a value, NULL is returned. If an error + * occurs in the script, the error message is returned. + */ +const char* session_run_file(Session sess, const char* filename) +{ + assert(sess); + return script_run_file(sess->script, filename); +} + + +/** + * Execute a bit of script stored in a string. + * \param sess The session object. + * \param code The string containing the script code to be executed. + * \returns If the script returns a value, it is converted to a string and returned. + * If the script does not return a value, NULL is returned. If an error + * occurs in the script, the error message is returned. + */ +const char* session_run_string(Session sess, const char* code) +{ + assert(sess); + return script_run_string(sess->script, code); +} + + +/** + * Set the action name to be performed on this execution pass. The action name will + * be placed in the _ACTION script environment global. + * \param sess The current execution session context. + * \param action The name of the action to be performed. + */ +void session_set_action(Session sess, const char* action) +{ + assert(sess); + script_set_action(sess->script, action); +} + + +/** + * Set the active output stream, which will be passed to subsequent callbacks during + * object processing by session_enumerate_objects(). If there is an existing active + * stream it will be released before setting the new stream. + * \param sess The current execution session context. + * \param strm The new active stream. + */ +void session_set_active_stream(Session sess, Stream strm) +{ + assert(sess); + assert(strm); + if (sess->active_stream) + { + stream_destroy(sess->active_stream); + } + sess->active_stream = strm; +} + + +/** + * Copy project information out of the scripting environment and into C objects that + * can be more easily manipulated by the action code. + * \param sess The session object which contains the scripted project objects. + * \returns OKAY if successful. + */ +int session_unload(Session sess) +{ + assert(sess); + return script_unload(sess->script, sess->solutions); +} + + +/** + * Make sure that all required objects and values have been defined by the project script. + * \param sess The session to validate. + * \param features The features (language, kind, etc.) supported by the current action. + * \returns OKAY if the session is valid. + */ +int session_validate(Session sess, SessionFeatures* features) +{ + int si, sn; + + assert(sess); + assert(features); + + sn = session_num_solutions(sess); + for (si = 0; si < sn; ++si) + { + int pi, pn; + Solution sln = session_get_solution(sess, si); + + /* every solution must have at least one project */ + pn = solution_num_projects(sln); + if (pn == 0) + { + error_set("no projects defined for solution '%s'", solution_get_name(sln)); + return !OKAY; + } + + for (pi = 0; pi < pn; ++pi) + { + int i; + + Project prj = solution_get_project(sln, pi); + const char* prj_name = project_get_name(prj); + const char* prj_lang = project_get_language(prj); + + /* every project must have a language defined */ + if (prj_lang == NULL) + { + error_set("no language defined for project '%s'", prj_name); + return !OKAY; + } + + /* action must support the language */ + for (i = 0; features->languages[i] != NULL; ++i) + { + if (cstr_eq(prj_lang, features->languages[i])) + break; + } + + if (features->languages[i] == NULL) + { + error_set("%s language projects are not supported by this action", prj_lang); + return !OKAY; + } + } + } + + return OKAY; +} diff --git a/src/session/session.h b/src/session/session.h index d8bf62e..ea595c1 100644 --- a/src/session/session.h +++ b/src/session/session.h @@ -1,97 +1,97 @@ -/** - * \file session.h - * \brief Context for a program execution session. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - * - * \defgroup session Session - * - * Premake is essentially a long chain of sequential actions; the Session object - * tracks the application state through this chain, and provides the context - * necessary for actions to do their work. It's a glorified global, essentially. - * - * @{ - */ -#if !defined(PREMAKE_SESSION_H) -#define PREMAKE_SESSION_H - -#include "base/stream.h" -#include "project/solution.h" -#include "project/project.h" - -DECLARE_CLASS(Session) - - -/** - * Callback signature for Premake action handlers, which will get triggered - * if user specifies that action on the command line for processing. - * \param sess The current execution session context. - * \returns OKAY If successful. - */ -typedef int (*SessionActionCallback)(Session sess); - - -/** - * Per-solution object callback signature for session_enumerate_objects(). The - * solution callback will be called once for each solution in the session. - * \param sess The execution session context. - * \param sln The current solution. - * \param strm The currently active stream; set with session_set_active_stream(). May be NULL. - * \returns OKAY if successful. - */ -typedef int (*SessionSolutionCallback)(Session sess, Solution sln, Stream strm); - - -/** - * Per-project object callback signature for session_enumerate_objects(). The - * project callback will be called once for each solution in the session. - * \param sess The execution session context. - * \param prj The current project. - * \param strm The currently active stream; set with session_set_active_stream(). May be NULL. - * \returns OKAY if successful. - */ -typedef int (*SessionProjectCallback)(Session sess, Project prj, Stream strm); - - -/** - * Describe a Premake action, including the handler function and the metadata - * required to list it in the user help. - */ -typedef struct struct_SessionAction -{ - const char* name; - const char* description; - SessionActionCallback callback; -} SessionAction; - - -/** - * Describe the features (languages, project kinds, etc.) supported by an action. Used by - * session_validate() to ensure that action handler functions only get called with data - * that they can handle. - */ -typedef struct struct_SessionFeatures -{ - const char* languages[64]; -} SessionFeatures; - - -Session session_create(void); -void session_destroy(Session sess); -void session_add_solution(Session sess, Solution sln); -int session_enumerate_configurations(Session sess, Project prj, Stream strm); -int session_enumerate_objects(Session sess, SessionSolutionCallback* sln_funcs, SessionProjectCallback* prj_funcs, SessionProjectCallback* cfg_funcs); -const char* session_get_action(Session sess); -Stream session_get_active_stream(Session sess); -Solution session_get_solution(Session sess, int index); -int session_num_solutions(Session sess); -const char* session_run_file(Session sess, const char* filename); -const char* session_run_string(Session sess, const char* code); -void session_set_action(Session sess, const char* action); -void session_set_active_stream(Session sess, Stream strm); -int session_tests(void); -int session_unload(Session sess); -int session_validate(Session sess, SessionFeatures* features); - -#endif -/** @} */ - +/** + * \file session.h + * \brief Context for a program execution session. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + * + * \defgroup session Session + * + * Premake is essentially a long chain of sequential actions; the Session object + * tracks the application state through this chain, and provides the context + * necessary for actions to do their work. It's a glorified global, essentially. + * + * @{ + */ +#if !defined(PREMAKE_SESSION_H) +#define PREMAKE_SESSION_H + +#include "base/stream.h" +#include "project/solution.h" +#include "project/project.h" + +DECLARE_CLASS(Session) + + +/** + * Callback signature for Premake action handlers, which will get triggered + * if user specifies that action on the command line for processing. + * \param sess The current execution session context. + * \returns OKAY If successful. + */ +typedef int (*SessionActionCallback)(Session sess); + + +/** + * Per-solution object callback signature for session_enumerate_objects(). The + * solution callback will be called once for each solution in the session. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). May be NULL. + * \returns OKAY if successful. + */ +typedef int (*SessionSolutionCallback)(Session sess, Solution sln, Stream strm); + + +/** + * Per-project object callback signature for session_enumerate_objects(). The + * project callback will be called once for each solution in the session. + * \param sess The execution session context. + * \param prj The current project. + * \param strm The currently active stream; set with session_set_active_stream(). May be NULL. + * \returns OKAY if successful. + */ +typedef int (*SessionProjectCallback)(Session sess, Project prj, Stream strm); + + +/** + * Describe a Premake action, including the handler function and the metadata + * required to list it in the user help. + */ +typedef struct struct_SessionAction +{ + const char* name; + const char* description; + SessionActionCallback callback; +} SessionAction; + + +/** + * Describe the features (languages, project kinds, etc.) supported by an action. Used by + * session_validate() to ensure that action handler functions only get called with data + * that they can handle. + */ +typedef struct struct_SessionFeatures +{ + const char* languages[64]; +} SessionFeatures; + + +Session session_create(void); +void session_destroy(Session sess); +void session_add_solution(Session sess, Solution sln); +int session_enumerate_configurations(Session sess, Project prj, Stream strm); +int session_enumerate_objects(Session sess, SessionSolutionCallback* sln_funcs, SessionProjectCallback* prj_funcs, SessionProjectCallback* cfg_funcs); +const char* session_get_action(Session sess); +Stream session_get_active_stream(Session sess); +Solution session_get_solution(Session sess, int index); +int session_num_solutions(Session sess); +const char* session_run_file(Session sess, const char* filename); +const char* session_run_string(Session sess, const char* code); +void session_set_action(Session sess, const char* action); +void session_set_active_stream(Session sess, Stream strm); +int session_tests(void); +int session_unload(Session sess); +int session_validate(Session sess, SessionFeatures* features); + +#endif +/** @} */ + diff --git a/src/session/tests/session_tests.cpp b/src/session/tests/session_tests.cpp index ab6a7d9..f1181cd 100644 --- a/src/session/tests/session_tests.cpp +++ b/src/session/tests/session_tests.cpp @@ -1,397 +1,397 @@ -/** - * \file session_tests.cpp - * \brief Automated test for the Session class. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "testing/testing.h" -extern "C" { -#include "session/session.h" -#include "script/script.h" -#include "base/base.h" -#include "base/error.h" -} - - -/** - * \brief Run the engine automated tests. - * \returns OKAY if all tests completed successfully. - * \note Also runs the tests for all dependencies (everything but the host executable). - */ -int session_tests() -{ - int z = base_tests(); - if (z == OKAY) z = project_tests(); - if (z == OKAY) z = script_tests(); - if (z == OKAY) z = tests_run_suite("session"); - return z; -} - - -/************************************************************************** - * Support functions for Session object testing - **************************************************************************/ - -#define FAIL_SLN_PARAM (1) -#define FAIL_PRJ_PARAM (2) - -static SessionFeatures features = { - { "c", "c++", NULL }, -}; - - -static int num_solution_calls; -static int num_project_calls; -static int num_config_calls; -static const char* last_config_filter; - - -static int test_solution_okay(Session sess, Solution sln, Stream strm) -{ - UNUSED(sess); UNUSED(sln); UNUSED(strm); - num_solution_calls++; - return OKAY; -} - -static int test_solution_fail(Session sess, Solution sln, Stream strm) -{ - UNUSED(sess); UNUSED(sln); UNUSED(strm); - return !OKAY; -} - -static int test_project_okay(Session sess, Project prj, Stream strm) -{ - UNUSED(sess); UNUSED(prj); UNUSED(strm); - num_project_calls++; - return OKAY; -} - -static int test_project_fail(Session sess, Project prj, Stream strm) -{ - UNUSED(sess); UNUSED(prj); UNUSED(strm); - return !OKAY; -} - -static int test_config_okay(Session sess, Project prj, Stream strm) -{ - UNUSED(sess); UNUSED(strm); - num_config_calls++; - last_config_filter = project_get_configuration_filter(prj); - return OKAY; -} - - -struct FxSession -{ - Session sess; - Solution sln; - Project prj; - - FxSession() - { - sess = session_create(); - num_solution_calls = 0; - num_project_calls = 0; - num_config_calls = 0; - last_config_filter = NULL; - } - - ~FxSession() - { - session_destroy(sess); - error_clear(); - } - - Solution AddSolution() - { - sln = solution_create(); - session_add_solution(sess, sln); - solution_set_name(sln, "MySolution"); - return sln; - } - - Project AddProject() - { - prj = project_create(); - solution_add_project(sln, prj); - project_set_name(prj, "MyProject"); - return prj; - } -}; - - -SUITE(session) -{ - /********************************************************************** - * Initial state checks - **********************************************************************/ - - TEST_FIXTURE(FxSession, Create_ReturnsObject_OnSuccess) - { - CHECK(sess != NULL); - } - - - /********************************************************************** - * Script execution tests - **********************************************************************/ - - TEST_FIXTURE(FxSession, RunString_ReturnsValue_OnString) - { - const char* result = session_run_string(sess, "return 'string value'"); - CHECK_EQUAL("string value", result); - } - - TEST_FIXTURE(FxSession, RunString_ReturnsValue_OnInteger) - { - const char* result = session_run_string(sess, "return 18"); - CHECK_EQUAL("18", result); - } - - TEST_FIXTURE(FxSession, RunString_ReturnsValue_OnBoolean) - { - const char* result = session_run_string(sess, "return true"); - CHECK_EQUAL("true", result); - } - - TEST_FIXTURE(FxSession, RunFile_ReturnsValue_OnValidFile) - { - const char* result = session_run_file(sess, "testing/test_files/true.lua"); - CHECK_EQUAL("true", result); - } - - - /********************************************************************** - * Action handling tests - **********************************************************************/ - - TEST_FIXTURE(FxSession, SetAction_SetScriptVar) - { - session_set_action(sess, "MyAction"); - const char* result = session_run_string(sess, "return _ACTION"); - CHECK_EQUAL("MyAction", result); - } - - TEST_FIXTURE(FxSession, GetAction_ReturnsNull_OnNoAction) - { - const char* result = session_get_action(sess); - CHECK(result == NULL); - } - - TEST_FIXTURE(FxSession, GetAction_GetsFromScriptVar) - { - session_run_string(sess, "_ACTION = 'SomeAction'"); - const char* result = session_get_action(sess); - CHECK_EQUAL("SomeAction", result); - } - - - /********************************************************************** - * Solution containment tests - **********************************************************************/ - - TEST_FIXTURE(FxSession, NumSolutions_ReturnsZero_OnCreate) - { - int n = session_num_solutions(sess); - CHECK(n == 0); - } - - TEST_FIXTURE(FxSession, NumSolutions_ReturnsOne_OnAddSolution) - { - AddSolution(); - int n = session_num_solutions(sess); - CHECK(n == 1); - } - - TEST_FIXTURE(FxSession, GetSolution_ReturnsSolution_OnAddSolution) - { - Solution sln = AddSolution(); - CHECK(sln == session_get_solution(sess, 0)); - } - - - /********************************************************************** - * Object enumeration tests - **********************************************************************/ - - TEST_FIXTURE(FxSession, Enumerate_ReturnsOkay_OnSuccess) - { - SessionSolutionCallback sln_funcs[] = { NULL }; - SessionProjectCallback prj_funcs[] = { NULL }; - SessionProjectCallback cfg_funcs[] = { NULL }; - int result = session_enumerate_objects(sess, sln_funcs, prj_funcs, cfg_funcs); - CHECK(result == OKAY); - } - - TEST_FIXTURE(FxSession, Enumerate_CallsAllSolutionFuncs_OnSolution) - { - SessionSolutionCallback sln_funcs[] = { test_solution_okay, test_solution_okay, NULL }; - SessionProjectCallback prj_funcs[] = { NULL }; - SessionProjectCallback cfg_funcs[] = { NULL }; - AddSolution(); - session_enumerate_objects(sess, sln_funcs, prj_funcs, cfg_funcs); - CHECK(num_solution_calls == 2); - } - - TEST_FIXTURE(FxSession, Enumerate_CallsSolutionFunc_OnEachSolution) - { - SessionSolutionCallback sln_funcs[] = { test_solution_okay, NULL }; - SessionProjectCallback prj_funcs[] = { NULL }; - SessionProjectCallback cfg_funcs[] = { NULL }; - AddSolution(); - AddSolution(); - session_enumerate_objects(sess, sln_funcs, prj_funcs, cfg_funcs); - CHECK(num_solution_calls == 2); - } - - TEST_FIXTURE(FxSession, Enumerate_ReturnsNotOkay_OnSolutionError) - { - SessionSolutionCallback sln_funcs[] = { test_solution_fail, NULL }; - SessionProjectCallback prj_funcs[] = { NULL }; - SessionProjectCallback cfg_funcs[] = { NULL }; - AddSolution(); - int result = session_enumerate_objects(sess, sln_funcs, prj_funcs, cfg_funcs); - CHECK(result != OKAY); - } - - TEST_FIXTURE(FxSession, Enumerate_StopsProcessing_OnSolutionError) - { - SessionSolutionCallback sln_funcs[] = { test_solution_fail, test_solution_okay, NULL }; - SessionProjectCallback prj_funcs[] = { NULL }; - SessionProjectCallback cfg_funcs[] = { NULL }; - AddSolution(); - AddSolution(); - session_enumerate_objects(sess, sln_funcs, prj_funcs, cfg_funcs); - CHECK(num_solution_calls == 0); - } - - TEST_FIXTURE(FxSession, Enumerate_CallsAllProjectFuncs_OnProject) - { - SessionSolutionCallback sln_funcs[] = { NULL }; - SessionProjectCallback prj_funcs[] = { test_project_okay, test_project_okay, NULL }; - SessionProjectCallback cfg_funcs[] = { NULL }; - AddSolution(); - AddProject(); - session_enumerate_objects(sess, sln_funcs, prj_funcs, cfg_funcs); - CHECK(num_project_calls == 2); - } - - TEST_FIXTURE(FxSession, Enumerate_CallsProjectFunc_OnEachProject) - { - SessionSolutionCallback sln_funcs[] = { NULL }; - SessionProjectCallback prj_funcs[] = { test_project_okay, NULL }; - SessionProjectCallback cfg_funcs[] = { NULL }; - AddSolution(); - AddProject(); - AddProject(); - session_enumerate_objects(sess, sln_funcs, prj_funcs, cfg_funcs); - CHECK(num_project_calls == 2); - } - - TEST_FIXTURE(FxSession, Enumerate_ReturnsNotOkay_OnProjectError) - { - SessionSolutionCallback sln_funcs[] = { NULL }; - SessionProjectCallback prj_funcs[] = { test_project_fail, NULL }; - SessionProjectCallback cfg_funcs[] = { NULL }; - AddSolution(); - AddProject(); - int result = session_enumerate_objects(sess, sln_funcs, prj_funcs, cfg_funcs); - CHECK(result != OKAY); - } - - TEST_FIXTURE(FxSession, Enumerate_StopsProcessing_OnProjectError) - { - SessionSolutionCallback sln_funcs[] = { NULL }; - SessionProjectCallback prj_funcs[] = { test_project_fail, test_project_okay, NULL }; - SessionProjectCallback cfg_funcs[] = { NULL }; - AddSolution(); - AddProject(); - AddProject(); - session_enumerate_objects(sess, sln_funcs, prj_funcs, cfg_funcs); - CHECK(num_project_calls == 0); - } - - TEST_FIXTURE(FxSession, Enumerate_CallsAllConfigFuncs_OnConfig) - { - SessionSolutionCallback sln_funcs[] = { NULL }; - SessionProjectCallback prj_funcs[] = { session_enumerate_configurations, NULL }; - SessionProjectCallback cfg_funcs[] = { test_config_okay, test_config_okay, NULL }; - AddSolution(); - AddProject(); - solution_add_config_name(sln, "Debug"); - session_enumerate_objects(sess, sln_funcs, prj_funcs, cfg_funcs); - CHECK(num_config_calls == 2); - } - - TEST_FIXTURE(FxSession, Enumerate_SetsConfigFilter_OnConfig) - { - SessionSolutionCallback sln_funcs[] = { NULL }; - SessionProjectCallback prj_funcs[] = { session_enumerate_configurations, NULL }; - SessionProjectCallback cfg_funcs[] = { test_config_okay, test_config_okay, NULL }; - AddSolution(); - AddProject(); - solution_add_config_name(sln, "Debug"); - session_enumerate_objects(sess, sln_funcs, prj_funcs, cfg_funcs); - CHECK_EQUAL("Debug", last_config_filter); - } - - - /********************************************************************** - * Unload tests - most unload testing is done elsewhere - **********************************************************************/ - - TEST_FIXTURE(FxSession, Unload_ReturnsOkay_OnNoProjectInfo) - { - int result = session_unload(sess); - CHECK(result == OKAY); - } - - - /********************************************************************** - * Session validation tests - **********************************************************************/ - - TEST_FIXTURE(FxSession, Validate_ReturnsOkay_OnNoSolutions) - { - int result = session_validate(sess, &features); - CHECK(result == OKAY); - } - - TEST_FIXTURE(FxSession, Validate_ReturnsOkay_OnAllsWell) - { - AddSolution(); - AddProject(); - project_set_language(prj, "c++"); - int result = session_validate(sess, &features); - CHECK(result == OKAY); - } - - TEST_FIXTURE(FxSession, Validate_NotOkay_OnEmptySolution) - { - AddSolution(); - int result = session_validate(sess, &features); - CHECK(result != OKAY); - CHECK_EQUAL("no projects defined for solution 'MySolution'", error_get()); - } - - TEST_FIXTURE(FxSession, Validate_NotOkay_OnNullLanguage) - { - AddSolution(); - AddProject(); - int result = session_validate(sess, &features); - CHECK(result != OKAY); - CHECK_EQUAL("no language defined for project 'MyProject'", error_get()); - } - - TEST_FIXTURE(FxSession, Validate_NotOkay_OnUnsupportedLanguage) - { - AddSolution(); - AddProject(); - project_set_language(prj, "nonesuch"); - int result = session_validate(sess, &features); - CHECK(result != OKAY); - CHECK_EQUAL("nonesuch language projects are not supported by this action", error_get()); - } -} - +/** + * \file session_tests.cpp + * \brief Automated test for the Session class. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "testing/testing.h" +extern "C" { +#include "session/session.h" +#include "script/script.h" +#include "base/base.h" +#include "base/error.h" +} + + +/** + * \brief Run the engine automated tests. + * \returns OKAY if all tests completed successfully. + * \note Also runs the tests for all dependencies (everything but the host executable). + */ +int session_tests() +{ + int z = base_tests(); + if (z == OKAY) z = project_tests(); + if (z == OKAY) z = script_tests(); + if (z == OKAY) z = tests_run_suite("session"); + return z; +} + + +/************************************************************************** + * Support functions for Session object testing + **************************************************************************/ + +#define FAIL_SLN_PARAM (1) +#define FAIL_PRJ_PARAM (2) + +static SessionFeatures features = { + { "c", "c++", NULL }, +}; + + +static int num_solution_calls; +static int num_project_calls; +static int num_config_calls; +static const char* last_config_filter; + + +static int test_solution_okay(Session sess, Solution sln, Stream strm) +{ + UNUSED(sess); UNUSED(sln); UNUSED(strm); + num_solution_calls++; + return OKAY; +} + +static int test_solution_fail(Session sess, Solution sln, Stream strm) +{ + UNUSED(sess); UNUSED(sln); UNUSED(strm); + return !OKAY; +} + +static int test_project_okay(Session sess, Project prj, Stream strm) +{ + UNUSED(sess); UNUSED(prj); UNUSED(strm); + num_project_calls++; + return OKAY; +} + +static int test_project_fail(Session sess, Project prj, Stream strm) +{ + UNUSED(sess); UNUSED(prj); UNUSED(strm); + return !OKAY; +} + +static int test_config_okay(Session sess, Project prj, Stream strm) +{ + UNUSED(sess); UNUSED(strm); + num_config_calls++; + last_config_filter = project_get_configuration_filter(prj); + return OKAY; +} + + +struct FxSession +{ + Session sess; + Solution sln; + Project prj; + + FxSession() + { + sess = session_create(); + num_solution_calls = 0; + num_project_calls = 0; + num_config_calls = 0; + last_config_filter = NULL; + } + + ~FxSession() + { + session_destroy(sess); + error_clear(); + } + + Solution AddSolution() + { + sln = solution_create(); + session_add_solution(sess, sln); + solution_set_name(sln, "MySolution"); + return sln; + } + + Project AddProject() + { + prj = project_create(); + solution_add_project(sln, prj); + project_set_name(prj, "MyProject"); + return prj; + } +}; + + +SUITE(session) +{ + /********************************************************************** + * Initial state checks + **********************************************************************/ + + TEST_FIXTURE(FxSession, Create_ReturnsObject_OnSuccess) + { + CHECK(sess != NULL); + } + + + /********************************************************************** + * Script execution tests + **********************************************************************/ + + TEST_FIXTURE(FxSession, RunString_ReturnsValue_OnString) + { + const char* result = session_run_string(sess, "return 'string value'"); + CHECK_EQUAL("string value", result); + } + + TEST_FIXTURE(FxSession, RunString_ReturnsValue_OnInteger) + { + const char* result = session_run_string(sess, "return 18"); + CHECK_EQUAL("18", result); + } + + TEST_FIXTURE(FxSession, RunString_ReturnsValue_OnBoolean) + { + const char* result = session_run_string(sess, "return true"); + CHECK_EQUAL("true", result); + } + + TEST_FIXTURE(FxSession, RunFile_ReturnsValue_OnValidFile) + { + const char* result = session_run_file(sess, "testing/test_files/true.lua"); + CHECK_EQUAL("true", result); + } + + + /********************************************************************** + * Action handling tests + **********************************************************************/ + + TEST_FIXTURE(FxSession, SetAction_SetScriptVar) + { + session_set_action(sess, "MyAction"); + const char* result = session_run_string(sess, "return _ACTION"); + CHECK_EQUAL("MyAction", result); + } + + TEST_FIXTURE(FxSession, GetAction_ReturnsNull_OnNoAction) + { + const char* result = session_get_action(sess); + CHECK(result == NULL); + } + + TEST_FIXTURE(FxSession, GetAction_GetsFromScriptVar) + { + session_run_string(sess, "_ACTION = 'SomeAction'"); + const char* result = session_get_action(sess); + CHECK_EQUAL("SomeAction", result); + } + + + /********************************************************************** + * Solution containment tests + **********************************************************************/ + + TEST_FIXTURE(FxSession, NumSolutions_ReturnsZero_OnCreate) + { + int n = session_num_solutions(sess); + CHECK(n == 0); + } + + TEST_FIXTURE(FxSession, NumSolutions_ReturnsOne_OnAddSolution) + { + AddSolution(); + int n = session_num_solutions(sess); + CHECK(n == 1); + } + + TEST_FIXTURE(FxSession, GetSolution_ReturnsSolution_OnAddSolution) + { + Solution sln = AddSolution(); + CHECK(sln == session_get_solution(sess, 0)); + } + + + /********************************************************************** + * Object enumeration tests + **********************************************************************/ + + TEST_FIXTURE(FxSession, Enumerate_ReturnsOkay_OnSuccess) + { + SessionSolutionCallback sln_funcs[] = { NULL }; + SessionProjectCallback prj_funcs[] = { NULL }; + SessionProjectCallback cfg_funcs[] = { NULL }; + int result = session_enumerate_objects(sess, sln_funcs, prj_funcs, cfg_funcs); + CHECK(result == OKAY); + } + + TEST_FIXTURE(FxSession, Enumerate_CallsAllSolutionFuncs_OnSolution) + { + SessionSolutionCallback sln_funcs[] = { test_solution_okay, test_solution_okay, NULL }; + SessionProjectCallback prj_funcs[] = { NULL }; + SessionProjectCallback cfg_funcs[] = { NULL }; + AddSolution(); + session_enumerate_objects(sess, sln_funcs, prj_funcs, cfg_funcs); + CHECK(num_solution_calls == 2); + } + + TEST_FIXTURE(FxSession, Enumerate_CallsSolutionFunc_OnEachSolution) + { + SessionSolutionCallback sln_funcs[] = { test_solution_okay, NULL }; + SessionProjectCallback prj_funcs[] = { NULL }; + SessionProjectCallback cfg_funcs[] = { NULL }; + AddSolution(); + AddSolution(); + session_enumerate_objects(sess, sln_funcs, prj_funcs, cfg_funcs); + CHECK(num_solution_calls == 2); + } + + TEST_FIXTURE(FxSession, Enumerate_ReturnsNotOkay_OnSolutionError) + { + SessionSolutionCallback sln_funcs[] = { test_solution_fail, NULL }; + SessionProjectCallback prj_funcs[] = { NULL }; + SessionProjectCallback cfg_funcs[] = { NULL }; + AddSolution(); + int result = session_enumerate_objects(sess, sln_funcs, prj_funcs, cfg_funcs); + CHECK(result != OKAY); + } + + TEST_FIXTURE(FxSession, Enumerate_StopsProcessing_OnSolutionError) + { + SessionSolutionCallback sln_funcs[] = { test_solution_fail, test_solution_okay, NULL }; + SessionProjectCallback prj_funcs[] = { NULL }; + SessionProjectCallback cfg_funcs[] = { NULL }; + AddSolution(); + AddSolution(); + session_enumerate_objects(sess, sln_funcs, prj_funcs, cfg_funcs); + CHECK(num_solution_calls == 0); + } + + TEST_FIXTURE(FxSession, Enumerate_CallsAllProjectFuncs_OnProject) + { + SessionSolutionCallback sln_funcs[] = { NULL }; + SessionProjectCallback prj_funcs[] = { test_project_okay, test_project_okay, NULL }; + SessionProjectCallback cfg_funcs[] = { NULL }; + AddSolution(); + AddProject(); + session_enumerate_objects(sess, sln_funcs, prj_funcs, cfg_funcs); + CHECK(num_project_calls == 2); + } + + TEST_FIXTURE(FxSession, Enumerate_CallsProjectFunc_OnEachProject) + { + SessionSolutionCallback sln_funcs[] = { NULL }; + SessionProjectCallback prj_funcs[] = { test_project_okay, NULL }; + SessionProjectCallback cfg_funcs[] = { NULL }; + AddSolution(); + AddProject(); + AddProject(); + session_enumerate_objects(sess, sln_funcs, prj_funcs, cfg_funcs); + CHECK(num_project_calls == 2); + } + + TEST_FIXTURE(FxSession, Enumerate_ReturnsNotOkay_OnProjectError) + { + SessionSolutionCallback sln_funcs[] = { NULL }; + SessionProjectCallback prj_funcs[] = { test_project_fail, NULL }; + SessionProjectCallback cfg_funcs[] = { NULL }; + AddSolution(); + AddProject(); + int result = session_enumerate_objects(sess, sln_funcs, prj_funcs, cfg_funcs); + CHECK(result != OKAY); + } + + TEST_FIXTURE(FxSession, Enumerate_StopsProcessing_OnProjectError) + { + SessionSolutionCallback sln_funcs[] = { NULL }; + SessionProjectCallback prj_funcs[] = { test_project_fail, test_project_okay, NULL }; + SessionProjectCallback cfg_funcs[] = { NULL }; + AddSolution(); + AddProject(); + AddProject(); + session_enumerate_objects(sess, sln_funcs, prj_funcs, cfg_funcs); + CHECK(num_project_calls == 0); + } + + TEST_FIXTURE(FxSession, Enumerate_CallsAllConfigFuncs_OnConfig) + { + SessionSolutionCallback sln_funcs[] = { NULL }; + SessionProjectCallback prj_funcs[] = { session_enumerate_configurations, NULL }; + SessionProjectCallback cfg_funcs[] = { test_config_okay, test_config_okay, NULL }; + AddSolution(); + AddProject(); + solution_add_config_name(sln, "Debug"); + session_enumerate_objects(sess, sln_funcs, prj_funcs, cfg_funcs); + CHECK(num_config_calls == 2); + } + + TEST_FIXTURE(FxSession, Enumerate_SetsConfigFilter_OnConfig) + { + SessionSolutionCallback sln_funcs[] = { NULL }; + SessionProjectCallback prj_funcs[] = { session_enumerate_configurations, NULL }; + SessionProjectCallback cfg_funcs[] = { test_config_okay, test_config_okay, NULL }; + AddSolution(); + AddProject(); + solution_add_config_name(sln, "Debug"); + session_enumerate_objects(sess, sln_funcs, prj_funcs, cfg_funcs); + CHECK_EQUAL("Debug", last_config_filter); + } + + + /********************************************************************** + * Unload tests - most unload testing is done elsewhere + **********************************************************************/ + + TEST_FIXTURE(FxSession, Unload_ReturnsOkay_OnNoProjectInfo) + { + int result = session_unload(sess); + CHECK(result == OKAY); + } + + + /********************************************************************** + * Session validation tests + **********************************************************************/ + + TEST_FIXTURE(FxSession, Validate_ReturnsOkay_OnNoSolutions) + { + int result = session_validate(sess, &features); + CHECK(result == OKAY); + } + + TEST_FIXTURE(FxSession, Validate_ReturnsOkay_OnAllsWell) + { + AddSolution(); + AddProject(); + project_set_language(prj, "c++"); + int result = session_validate(sess, &features); + CHECK(result == OKAY); + } + + TEST_FIXTURE(FxSession, Validate_NotOkay_OnEmptySolution) + { + AddSolution(); + int result = session_validate(sess, &features); + CHECK(result != OKAY); + CHECK_EQUAL("no projects defined for solution 'MySolution'", error_get()); + } + + TEST_FIXTURE(FxSession, Validate_NotOkay_OnNullLanguage) + { + AddSolution(); + AddProject(); + int result = session_validate(sess, &features); + CHECK(result != OKAY); + CHECK_EQUAL("no language defined for project 'MyProject'", error_get()); + } + + TEST_FIXTURE(FxSession, Validate_NotOkay_OnUnsupportedLanguage) + { + AddSolution(); + AddProject(); + project_set_language(prj, "nonesuch"); + int result = session_validate(sess, &features); + CHECK(result != OKAY); + CHECK_EQUAL("nonesuch language projects are not supported by this action", error_get()); + } +} + diff --git a/src/testing/UnitTest++/PREMAKE_CHANGES.txt b/src/testing/UnitTest++/PREMAKE_CHANGES.txt index a61a4b0..bd25432 100644 --- a/src/testing/UnitTest++/PREMAKE_CHANGES.txt +++ b/src/testing/UnitTest++/PREMAKE_CHANGES.txt @@ -1,3 +1,3 @@ -Modified CheckStringsEqual() in checks.cpp to allow for actual==NULL (the -previous behavior was to explode violently). - +Modified CheckStringsEqual() in checks.cpp to allow for actual==NULL (the +previous behavior was to explode violently). + diff --git a/src/testing/test_files/_FILE.lua b/src/testing/test_files/_FILE.lua index 7fae568..54ee3e5 100644 --- a/src/testing/test_files/_FILE.lua +++ b/src/testing/test_files/_FILE.lua @@ -1,2 +1,2 @@ --- Return the _FILE global, to ensure that it has been set properly -return _FILE +-- Return the _FILE global, to ensure that it has been set properly +return _FILE diff --git a/src/testing/test_files/dofile.lua b/src/testing/test_files/dofile.lua index fef47c8..dac2cde 100644 --- a/src/testing/test_files/dofile.lua +++ b/src/testing/test_files/dofile.lua @@ -1,2 +1,2 @@ --- call another script in a different directory, and see what the current directory is when it runs -return dofile("nested/getcwd.lua") +-- call another script in a different directory, and see what the current directory is when it runs +return dofile("nested/getcwd.lua") diff --git a/src/testing/test_files/dofile_getcwd.lua b/src/testing/test_files/dofile_getcwd.lua index 0f6f13e..defe46d 100644 --- a/src/testing/test_files/dofile_getcwd.lua +++ b/src/testing/test_files/dofile_getcwd.lua @@ -1,4 +1,4 @@ --- run a script in a subdir, and check the current directory when it returns --- makes sure that current directory gets restored when a nested script completes -dofile("nested/getcwd.lua") -return os.getcwd() +-- run a script in a subdir, and check the current directory when it returns +-- makes sure that current directory gets restored when a nested script completes +dofile("nested/getcwd.lua") +return os.getcwd() diff --git a/src/testing/test_files/error.lua b/src/testing/test_files/error.lua index 5d118fe..64f079c 100644 --- a/src/testing/test_files/error.lua +++ b/src/testing/test_files/error.lua @@ -1 +1 @@ -error("This script has failed") +error("This script has failed") diff --git a/src/testing/test_files/getcwd.lua b/src/testing/test_files/getcwd.lua index 51c1373..08556c4 100644 --- a/src/testing/test_files/getcwd.lua +++ b/src/testing/test_files/getcwd.lua @@ -1 +1 @@ -return os.getcwd() +return os.getcwd() diff --git a/src/testing/test_files/nested/getcwd.lua b/src/testing/test_files/nested/getcwd.lua index 51c1373..08556c4 100644 --- a/src/testing/test_files/nested/getcwd.lua +++ b/src/testing/test_files/nested/getcwd.lua @@ -1 +1 @@ -return os.getcwd() +return os.getcwd() diff --git a/src/testing/test_files/premake4.lua b/src/testing/test_files/premake4.lua index 530e6c4..5cf4ea6 100644 --- a/src/testing/test_files/premake4.lua +++ b/src/testing/test_files/premake4.lua @@ -1,3 +1,3 @@ --- Used to make sure functions will look for premake4.lua by default -script_has_run = true -return true +-- Used to make sure functions will look for premake4.lua by default +script_has_run = true +return true diff --git a/src/testing/test_files/true.lua b/src/testing/test_files/true.lua index 3694469..12c4f08 100644 --- a/src/testing/test_files/true.lua +++ b/src/testing/test_files/true.lua @@ -1,2 +1,2 @@ --- Just return a simple value, used to ensure that dofile() works as expected -return true +-- Just return a simple value, used to ensure that dofile() works as expected +return true diff --git a/src/testing/testing.cpp b/src/testing/testing.cpp index 1e89d42..2857432 100644 --- a/src/testing/testing.cpp +++ b/src/testing/testing.cpp @@ -1,22 +1,22 @@ -/** - * \file testing.cpp - * \brief Automated testing framework. - * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project - */ - -#include -#include "testing.h" -#include "UnitTest++/src/TestReporterStdout.h" - - -/** - * Run a particular suite of tests. - * \param suite The name of the suite to run. - * \returns OKAY if all tests passed successfully. - */ -int tests_run_suite(const char* suite) -{ - UnitTest::TestReporterStdout reporter; - std::printf("Testing %s...\n", suite); - return UnitTest::RunAllTests(reporter, UnitTest::Test::GetTestList(), suite); -} +/** + * \file testing.cpp + * \brief Automated testing framework. + * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project + */ + +#include +#include "testing.h" +#include "UnitTest++/src/TestReporterStdout.h" + + +/** + * Run a particular suite of tests. + * \param suite The name of the suite to run. + * \returns OKAY if all tests passed successfully. + */ +int tests_run_suite(const char* suite) +{ + UnitTest::TestReporterStdout reporter; + std::printf("Testing %s...\n", suite); + return UnitTest::RunAllTests(reporter, UnitTest::Test::GetTestList(), suite); +} diff --git a/src/testing/testing.h b/src/testing/testing.h index 4f8b122..e68c688 100644 --- a/src/testing/testing.h +++ b/src/testing/testing.h @@ -1,9 +1,9 @@ -/** - * \file testing.h - * \brief Automated testing framework. - * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project - */ - -#include "UnitTest++/src/UnitTest++.h" - -int tests_run_suite(const char* suite); +/** + * \file testing.h + * \brief Automated testing framework. + * \author Copyright (c) 2007-2008 Jason Perkins and the Premake project + */ + +#include "UnitTest++/src/UnitTest++.h" + +int tests_run_suite(const char* suite); -- cgit v1.2.3