diff --git a/build/bin/perl58.dll b/build/bin/perl58.dll new file mode 100644 index 0000000000..12ee9e490e Binary files /dev/null and b/build/bin/perl58.dll differ diff --git a/build/errorlist/errorlist.exe b/build/errorlist/errorlist.exe new file mode 100644 index 0000000000..1308953ff8 Binary files /dev/null and b/build/errorlist/errorlist.exe differ diff --git a/build/errorlist/errorlist.pl b/build/errorlist/errorlist.pl new file mode 100644 index 0000000000..efe51bd4dc --- /dev/null +++ b/build/errorlist/errorlist.pl @@ -0,0 +1,197 @@ +#!perl -w + +use strict; +use warnings; + +my (%topgroups, %groups, %types); + +my @files = cpp_files('.'); + +for (@files) { + open my $f, $_ or die "Error opening file '$_' ($!)"; + while (<$f>) { + if (/^ERROR_/) { + if (/^ERROR_GROUP\((.+?)\)/) { + $topgroups{$1} = 1; + } elsif (/^ERROR_SUBGROUP\((.+?)\)/) { + $groups{join '~', split /,\s*/, $1} = 1; + } elsif (/^ERROR_TYPE\((.+?)\)/) { + $types{join '~', split /,\s*/, $1} = 1; + } + } + } +} + +# Add "PSERROR_Error_InvalidError", so that an error to throw when being +# told to throw an error that doesn't exist exists. +$topgroups{Error} = 1; +$types{'Error~InvalidError'} = 1; + +open my $out, '>', 'ps/Errors.cpp' or die "Error opening ps/Errors.cpp ($!)"; + +print $out <<'.'; +// Auto-generated by errorlist.pl - do not edit. + +#include "precompiled.h" + +#include "Errors.h" + +. + +for (sort keys %topgroups) { + print $out "class PSERROR_$_ : public PSERROR {};\n"; +} + +print $out "\n"; + +for (sort { $a->[1] cmp $b->[1] } map [$_, do{(my $c=$_)=~s/~/_/;$c} ], keys %groups) { + my ($base, $name) = split /~/, $_->[0]; + print $out "class PSERROR_${base}_$name : public PSERROR_$base {};\n"; +} + +print $out "\n"; + +for (sort { $a->[1] cmp $b->[1] } map [$_, do{(my $c=$_)=~s/~/_/;$c} ], keys %types) { + my ($base, $name) = split /~/, $_->[0]; + print $out "class PSERROR_${base}_$name : public PSERROR_$base { public: PSERROR_${base}_$name(); };\n"; +} + +print $out "\n"; + +# The difficult bit: + +=pod + +mask +**** PSERROR +0001 PSERROR_ Err1 +1*** PSERROR_Sec1 +1001 PSERROR_Sec1_ Err1 +1002 PSERROR_Sec1_ Err2 +1003 PSERROR_Sec1_ Err3 +11** PSERROR_Sec1_Sec1 +1101 PSERROR_Sec1_Sec1_Err1 +1102 PSERROR_Sec1_Sec1_Err2 +2*** PSERROR_Sec2 +2001 PSERROR_Sec2_ Err1 + +...so split into three sections (0 if null) plus final code... + +=cut + +my @sec_codes; +$sec_codes[$_]{''} = 1 for 0..2; + +for (keys %types) { + my (@secs) = split /[~_]/; + my $err = pop @secs; + $sec_codes[$_]{$secs[$_] || ''} = 1 for 0..2; +} + +for my $n (0..2) { + @{$sec_codes[$n]}{sort keys %{$sec_codes[$n]}} = 0 .. keys(%{$sec_codes[$n]})-1; +} + +my ($last_sec, $last_err) = ('', 0); +for (sort keys %types) { + my (@secs) = split /[~_]/; + my $err = pop @secs; + my $id = join '', map chr $sec_codes[$_]{$secs[$_] || ''}, 0..2; + if ($id eq $last_sec) { + $id .= chr(++$last_err); + } else { + $last_sec = $id; + $id .= chr($last_err=1); + } + $types{$_} = $id; +} + +for (sort keys %types) { + my ($base, $name) = split /~/; + print $out "extern const PSRETURN PSRETURN_${base}_${name} = 0x".unpack('H*', $types{$_}).";\n"; +} + +print $out "\n"; + +for (sort keys %topgroups) { + my (@secs) = $_; + my $id = join '', map chr $sec_codes[$_]{$secs[$_] || ''}, 0..2; + my $code = unpack 'H*', $id; + (my $mask = $code) =~ s/(\d\d)/$1+0 ? 'ff' : '00'/ge; + print $out "extern const PSRETURN MASK__PSRETURN_".join('_', @secs)." = 0x${mask}00;\n"; + print $out "extern const PSRETURN CODE__PSRETURN_".join('_', @secs)." = 0x${code}00;\n"; +} + +for (sort keys %groups) { + my (@secs) = split /[_~]/; + my $id = join '', map chr $sec_codes[$_]{$secs[$_] || ''}, 0..2; + my $code = unpack 'H*', $id; + (my $mask = $code) =~ s/(\d\d)/$1+0 ? 'ff' : '00'/ge; + print $out "extern const PSRETURN MASK__PSRETURN_".join('_', @secs)." = 0x${mask}00;\n"; + print $out "extern const PSRETURN CODE__PSRETURN_".join('_', @secs)." = 0x${code}00;\n"; +} + +print $out "\n"; + +for (sort keys %types) { + my $code = unpack 'H*', $types{$_}; + s/~/_/; + print $out "extern const PSRETURN MASK__PSRETURN_$_ = 0xffffffff;\n"; + print $out "extern const PSRETURN CODE__PSRETURN_$_ = 0x$code;\n"; +} + +# End of difficult bit. + +print $out "\n"; + + +for (sort keys %types) { + my ($base, $name) = split /~/; + print $out qq~PSERROR_${base}_${name}::PSERROR_${base}_${name}() { magic=0x45725221; code=0x~.unpack('H*',$types{$_}).qq~; }\n~; +} + +print $out <<"."; + +const wchar_t* GetErrorString(PSRETURN code) +{ +\tswitch (code) +\t{ +. + +for (sort keys %types) { + (my $name = $_) =~ s/~/_/; + print $out qq{\tcase 0x}.unpack('H*',$types{$_}).qq{: return L"$name";\n}; +} + +print $out <<"."; + +\tdefault: return L"Unrecognised error"; +\t} +} + +void ThrowError(PSRETURN code) +{ +\tswitch (code) // Use 'break' in case someone tries to continue from the exception +\t{ +. + +for (sort keys %types) { + (my $name = $_) =~ s/~/_/; + print $out qq{\tcase 0x}.unpack('H*',$types{$_}).qq{: throw PSERROR_$name(); break;\n}; +} + +print $out <<"."; + +\tdefault: throw PSERROR_Error_InvalidError(); // Hmm... +\t} +} +. + + +sub cpp_files { + opendir my $d, $_[0] or die "Error opening directory '$_[0]' ($!)"; + my @f = readdir $d; + my @files = map "$_[0]/$_", grep /\.(?:cpp|h)$/, @f; + push @files, cpp_files("$_[0]/$_") for grep { !/^(?:workspaces|tools|ape|sced)$/ and /^[a-zA-Z0-9]+$/ and -d "$_[0]/$_" } @f; + return @files; +} diff --git a/build/linefix/linefix.exe b/build/linefix/linefix.exe new file mode 100644 index 0000000000..1755ad395a Binary files /dev/null and b/build/linefix/linefix.exe differ diff --git a/build/premake/functions.lua b/build/premake/functions.lua new file mode 100755 index 0000000000..26da9fec39 --- /dev/null +++ b/build/premake/functions.lua @@ -0,0 +1,7 @@ +function sourcesfromdirs(root, ...) + local res = {} + for i=1, getn(arg) do + res[i]=matchfiles(root..arg[i].."/*.cpp", root..arg[i].."/*.h") + end + return res +end \ No newline at end of file diff --git a/source/workspaces/premake/premake.exe b/build/premake/premake.exe similarity index 100% rename from source/workspaces/premake/premake.exe rename to build/premake/premake.exe diff --git a/source/workspaces/premake/premake.lua b/build/premake/premake.lua similarity index 71% rename from source/workspaces/premake/premake.lua rename to build/premake/premake.lua index 808a3af68f..44e66143eb 100755 --- a/source/workspaces/premake/premake.lua +++ b/build/premake/premake.lua @@ -1,4 +1,4 @@ -dofile("functions.lua") +dofile("../functions.lua") -- Set up the Project project.name = "pyrogenesis" @@ -19,59 +19,71 @@ package.config["Debug"].target = "ps_dbg" package.config["Release"].target = "ps" package.config["Testing"].target = "ps_test" +sourceroot = "../../../source/" +librariesroot = "../../../libraries/" + -- Files package.files = { - sourcesfromdirs( + sourcesfromdirs(sourceroot, + + "ps", + "ps/scripting", + "ps/Network", - "../../ps", - "../../ps/scripting", - "../../ps/Network", + "simulation", + "simulation/scripting", - "../../simulation", - "../../simulation/scripting", + "lib", + "lib/sysdep", + "lib/res", - "../../lib", - "../../lib/sysdep", - "../../lib/res", + "graphics", + "graphics/scripting", - "../../graphics", - "../../graphics/scripting", + "maths", + "maths/scripting", - "../../maths", - "../../maths/scripting", + "renderer", - "../../renderer", + "gui", + "gui/scripting", - "../../gui", - "../../gui/scripting", + "terrain", - "../../terrain", + "sound", - "../../sound", + "scripting", - "../../scripting", + "i18n", - "../../i18n", - - "../../tests" + "tests" ), - "../../main.cpp" + sourceroot.."main.cpp" } -package.includepaths = { - "../../ps", - "../../simulation", - "../../lib", - "../../graphics", - "../../maths", - "../../renderer", - "../../terrain", - "../.." + +include_dirs = { + "ps", + "simulation", + "lib", + "graphics", + "maths", + "renderer", + "terrain", + "" } +package.includepaths = {} + +foreach(include_dirs, function (i,v) + tinsert(package.includepaths, sourceroot .. v) +end) + + package.libpaths = {} + package.buildflags = { "no-rtti" } package.config["Testing"].buildflags = { "with-symbols", "no-runtime-checks", "no-edit-and-continue" } @@ -96,16 +108,16 @@ if (OS == "windows") then "vorbis" } - -- Add '../../../libraries//lib' and '/include' to the includepaths and libpaths + -- Add '//lib' and '/include' to the includepaths and libpaths foreach(external_libraries, function (i,v) - tinsert(package.includepaths, "../../../libraries/" .. v .. "/include") - tinsert(package.libpaths, "../../../libraries/" .. v .. "/lib") + tinsert(package.includepaths, librariesroot..v.."/include") + tinsert(package.libpaths, librariesroot..v.."/lib") end) -- Libraries package.links = { "opengl32" } - tinsert(package.files, sourcesfromdirs("../../lib/sysdep/win")) - tinsert(package.files, {"../../lib/sysdep/win/assert_dlg.rc"}) + tinsert(package.files, sourcesfromdirs(sourceroot, "lib/sysdep/win")) + tinsert(package.files, {sourceroot.."lib/sysdep/win/assert_dlg.rc"}) package.linkoptions = { "/ENTRY:entry", "/DELAYLOAD:opengl32.dll", @@ -143,7 +155,7 @@ if (OS == "windows") then else -- Non-Windows, = Unix - tinsert(package.files, sourcesfromdirs("../../lib/sysdep/unix")) + tinsert(package.files, sourcesfromdirs(sourceroot.."lib/sysdep/unix")) -- Libraries package.links = { diff --git a/build/premake/src/CHANGES.txt b/build/premake/src/CHANGES.txt new file mode 100644 index 0000000000..232e342519 --- /dev/null +++ b/build/premake/src/CHANGES.txt @@ -0,0 +1,103 @@ +Premake Changelog +----------------- + +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.1 +* VS7 generator crashed if a package was built before one of its + dependencies. Now immediately assigns UUID before processing. + +1.6 +* 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. + +0.9.2 +* Added --with-mono and --with-pnet options. +* VS7 C# projects will now properly use the configured library paths. + +0.9.1 +* 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.0 +* Initial public release. diff --git a/build/premake/src/LICENSE.txt b/build/premake/src/LICENSE.txt new file mode 100644 index 0000000000..5b6e7c66c2 --- /dev/null +++ b/build/premake/src/LICENSE.txt @@ -0,0 +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. diff --git a/build/premake/src/Makefile b/build/premake/src/Makefile new file mode 100644 index 0000000000..91aa71865b --- /dev/null +++ b/build/premake/src/Makefile @@ -0,0 +1,24 @@ +# Makefile autogenerated by premake +# Options: +# CONFIG=[Debug|Release] + +ifndef CONFIG + CONFIG=Debug +endif + +export CONFIG + +.PHONY: all clean Premake + +all: Premake + +Makefile: ./premake.lua + @echo ==== Regenerating Makefiles ==== + @premake --target gnu + +Premake: + @echo ==== Building Premake ==== + @$(MAKE) --no-print-directory -C ./ -f Premake.make + +clean: + @$(MAKE) --no-print-directory -C ./ -f Premake.make clean diff --git a/build/premake/src/Premake.dsp b/build/premake/src/Premake.dsp new file mode 100644 index 0000000000..92be5d2ad7 --- /dev/null +++ b/build/premake/src/Premake.dsp @@ -0,0 +1,325 @@ +# Microsoft Developer Studio Project File - Name="Premake" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=Premake - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Premake.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Premake.mak" CFG="Premake - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Premake - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "Premake - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Premake - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug\" +# PROP BASE Intermediate_Dir "Debug\" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir ".\" +# PROP Intermediate_Dir "obj\Debug\" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /ZI /Od /GX /GR /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /debug /pdbtype:sept +# ADD LINK32 /nologo /subsystem:console /out:".\premake.exe" /machine:I386 /pdbtype:sept /libpath:".\" /pdb:".\premake.pdb" /debug +!ELSEIF "$(CFG)" == "Premake - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release\" +# PROP BASE Intermediate_Dir "Release\" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir ".\" +# PROP Intermediate_Dir "obj\Release\" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "NDEBUG" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /GR /O1 /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 /nologo /subsystem:console /out:".\premake.exe" /machine:I386 /pdbtype:sept /libpath:".\" +!ENDIF + +# Begin Target + +# Name "Premake - Win32 Debug" +# Name "Premake - Win32 Release" +# Begin Group "Src" + +# PROP Default_Filter "" +# Begin Group "Lua" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\Src\Lua\lapi.c +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\lauxlib.c +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\lbaselib.c +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\lcode.c +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\ldebug.c +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\ldo.c +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\lfunc.c +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\lgc.c +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\liolib.c +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\llex.c +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\lmathlib.c +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\lmem.c +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\lobject.c +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\lparser.c +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\lstate.c +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\lstring.c +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\lstrlib.c +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\ltable.c +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\ltests.c +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\ltm.c +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\lundump.c +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\lvm.c +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\lzio.c +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\lapi.h +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\lauxlib.h +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\lcode.h +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\ldebug.h +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\ldo.h +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\lfunc.h +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\lgc.h +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\llex.h +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\llimits.h +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\lmem.h +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\lobject.h +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\lopcodes.h +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\lparser.h +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\lstate.h +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\lstring.h +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\ltable.h +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\ltm.h +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\lua.h +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\luadebug.h +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\lualib.h +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\lundump.h +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\lvm.h +# End Source File +# Begin Source File + +SOURCE=.\Src\Lua\lzio.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\Src\premake.c +# End Source File +# Begin Source File + +SOURCE=.\Src\project.h +# End Source File +# Begin Source File + +SOURCE=.\Src\project.c +# End Source File +# Begin Source File + +SOURCE=.\Src\util.h +# End Source File +# Begin Source File + +SOURCE=.\Src\util.c +# End Source File +# Begin Source File + +SOURCE=.\Src\clean.c +# End Source File +# Begin Source File + +SOURCE=.\Src\gnu.c +# End Source File +# Begin Source File + +SOURCE=.\Src\sharpdev.c +# End Source File +# Begin Source File + +SOURCE=.\Src\vs7.c +# End Source File +# Begin Source File + +SOURCE=.\Src\vs6.c +# End Source File +# Begin Source File + +SOURCE=.\Src\windows.c +# End Source File +# End Group +# End Target +# End Project diff --git a/build/premake/src/Premake.dsw b/build/premake/src/Premake.dsw new file mode 100644 index 0000000000..62663c6e50 --- /dev/null +++ b/build/premake/src/Premake.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Premake"=.\Premake.dsp + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/build/premake/src/Premake.make b/build/premake/src/Premake.make new file mode 100644 index 0000000000..bc5fab873e --- /dev/null +++ b/build/premake/src/Premake.make @@ -0,0 +1,112 @@ +# Sub-makefile autogenerated by premake + +BINDIR = . +LIBDIR = . + +CFLAGS = +LDFLAGS = -L$(BINDIR) -L$(LIBDIR) +TARGET = + +ifeq ($(CONFIG),Debug) + CFLAGS += + CXXFLAGS = $(CFLAGS) + LDFLAGS += + TARGET = premake +endif +ifeq ($(CONFIG),Release) + CFLAGS += -Os + CXXFLAGS = $(CFLAGS) -Os + LDFLAGS += + TARGET = premake +endif + +obj/%.o : %.cc + -@if [ ! -d obj ]; then mkdir obj; fi + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -MD -o $@ -c $< + -@if [ -f $*.d ]; then mv $*.d obj/$*.d; fi + @cp obj/$*.d obj/$*.P; \ + sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ + -e '/^$$/ d' -e 's/$$/ :/' < obj/$*.d >> obj/$*.P; \ + rm -f obj/$*.d + +obj/%.o : %.cpp + -@if [ ! -d obj ]; then mkdir obj; fi + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -MD -o $@ -c $< + -@if [ -f $*.d ]; then mv $*.d obj/$*.d; fi + @cp obj/$*.d obj/$*.P; \ + sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ + -e '/^$$/ d' -e 's/$$/ :/' < obj/$*.d >> obj/$*.P; \ + rm -f obj/$*.d + +obj/%.o : %.cxx + -@if [ ! -d obj ]; then mkdir obj; fi + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -MD -o $@ -c $< + -@if [ -f $*.d ]; then mv $*.d obj/$*.d; fi + @cp obj/$*.d obj/$*.P; \ + sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ + -e '/^$$/ d' -e 's/$$/ :/' < obj/$*.d >> obj/$*.P; \ + rm -f obj/$*.d + +obj/%.o : %.c + -@if [ ! -d obj ]; then mkdir obj; fi + @echo $(notdir $<) + @$(CC) $(CFLAGS) -MD -o $@ -c $< + -@if [ -f $*.d ]; then mv $*.d obj/$*.d; fi + @cp obj/$*.d obj/$*.P; \ + sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ + -e '/^$$/ d' -e 's/$$/ :/' < obj/$*.d >> obj/$*.P; \ + rm -f obj/$*.d + +OBJECTS = \ + obj/premake.o \ + obj/project.o \ + obj/util.o \ + obj/clean.o \ + obj/gnu.o \ + obj/sharpdev.o \ + obj/vs7.o \ + obj/vs6.o \ + obj/lapi.o \ + obj/lauxlib.o \ + obj/lbaselib.o \ + obj/lcode.o \ + obj/ldebug.o \ + obj/ldo.o \ + obj/lfunc.o \ + obj/lgc.o \ + obj/liolib.o \ + obj/llex.o \ + obj/lmathlib.o \ + obj/lmem.o \ + obj/lobject.o \ + obj/lparser.o \ + obj/lstate.o \ + obj/lstring.o \ + obj/lstrlib.o \ + obj/ltable.o \ + obj/ltests.o \ + obj/ltm.o \ + obj/lundump.o \ + obj/lvm.o \ + obj/lzio.o \ + obj/posix.o \ + +VPATH = Src Src/Lua + +.PHONY: clean + +$(BINDIR)/$(TARGET): $(OBJECTS) + @echo Linking Premake + -@if [ ! -d $(BINDIR) ]; then mkdir $(BINDIR); fi + -@if [ ! -d $(LIBDIR) ]; then mkdir $(LIBDIR); fi + @$(CXX) -o $@ $(filter-out %.so, $^) $(LDFLAGS) + +clean: + @echo Cleaning Premake + -@rm -rf $(BINDIR)/$(TARGET) obj/* + +-include $(OBJECTS:%.o=%.P) + diff --git a/build/premake/src/Premake.sln b/build/premake/src/Premake.sln new file mode 100644 index 0000000000..1059c874a0 --- /dev/null +++ b/build/premake/src/Premake.sln @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Premake", "Premake.vcproj", "{D240CFA2-A134-D147-8EF3-30B485E4E25F}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {D240CFA2-A134-D147-8EF3-30B485E4E25F}.Debug.ActiveCfg = Debug|Win32 + {D240CFA2-A134-D147-8EF3-30B485E4E25F}.Debug.Build.0 = Debug|Win32 + {D240CFA2-A134-D147-8EF3-30B485E4E25F}.Release.ActiveCfg = Release|Win32 + {D240CFA2-A134-D147-8EF3-30B485E4E25F}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/build/premake/src/Premake.vcproj b/build/premake/src/Premake.vcproj new file mode 100644 index 0000000000..e6da3a8e88 --- /dev/null +++ b/build/premake/src/Premake.vcproj @@ -0,0 +1,314 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/premake/src/README.txt b/build/premake/src/README.txt new file mode 100644 index 0000000000..718d495ae4 --- /dev/null +++ b/build/premake/src/README.txt @@ -0,0 +1,20 @@ +PREMAKE v1.8 + +Copyright (C) 2002-2004 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 + + GNU make: type 'make' + + MS Visual C++ v6: open Premake.dsw and build. + + MS Visual C++ v7: open Premake.sln and build. + + +For questions, comments, or more information, visit the project +website at http://premake.sourceforge.net/ diff --git a/build/premake/src/Src/Lua/COPYRIGHT b/build/premake/src/Src/Lua/COPYRIGHT new file mode 100644 index 0000000000..eef88b050c --- /dev/null +++ b/build/premake/src/Src/Lua/COPYRIGHT @@ -0,0 +1,54 @@ +Lua Copyright Notice +-------------------- + +Lua is free and non-proprietary. +It can be used for both academic and commercial purposes at absolutely no cost. +There are no royalties or GNU-like "copyleft" restrictions. +Lua (probably) qualifies as Open Source software. +Nevertheless, Lua is not in the public domain and TeCGraf keeps its copyright. + +If you use Lua, please give us credit (a nice way to do this is to include a +Lua logo in a web page for your product), but we would appreciate *not* +receiving lengthy legal documents to sign. + +The legal details are below. + +=============================================================================== + +Copyright (C) 1994-2000 TeCGraf, PUC-Rio. All rights reserved. + +Permission is hereby granted, without written agreement and without license +or royalty fees, to use, copy, modify, translate, and distribute +this software and its documentation (hereby called the "package") +for any purpose, including commercial applications, subject to +the following conditions: + + * The above copyright notice and this permission notice shall appear in all + copies or substantial portions of this package. + + * The origin of this package must not be misrepresented; you must not + claim that you wrote the original package. If you use this package in a + product, an acknowledgment in the product documentation would be greatly + appreciated (but it is not required). + + * Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original package. + +The authors specifically disclaim any warranties, including, but not limited +to, the implied warranties of merchantability and fitness for a particular +purpose. The package provided hereunder is on an "as is" basis, and the +authors have no obligation to provide maintenance, support, updates, +enhancements, or modifications. In no event shall TeCGraf, PUC-Rio, or the +authors be held liable to any party for direct, indirect, special, +incidental, or consequential damages arising out of the use of this package +and its documentation. + +The Lua language and this implementation have been entirely designed and written +by Waldemar Celes, Roberto Ierusalimschy, and Luiz Henrique de Figueiredo +at TeCGraf, PUC-Rio in Brazil. + +This implementation contains no third-party code. + +=============================================================================== + +(end of COPYRIGHT) diff --git a/build/premake/src/Src/Lua/README b/build/premake/src/Src/Lua/README new file mode 100644 index 0000000000..81f767aee8 --- /dev/null +++ b/build/premake/src/Src/Lua/README @@ -0,0 +1,72 @@ +This is Lua 4.0. +See HISTORY for a summary of changes since the last version. + +* What is Lua? + ------------ + Lua is a powerful, light-weight programming language designed for extending + applications. Lua is also frequently used as a general-purpose, stand-alone + language. + + Lua combines simple procedural syntax (similar to Pascal) with powerful + data description constructs based on associative arrays and extensible + semantics. Lua is dynamically typed, interpreted from bytecodes, and has + automatic memory management, making it ideal for configuration, scripting, + and rapid prototyping. + + Lua is a language engine that you can embed into your application. + This means that, besides syntax and semantics, Lua has an API that + allows the application to exchange data with Lua programs and also to + extend Lua with C functions. In this sense, Lua can be regarded as a + language framework for building domain-specific languages. + + Lua is implemented as a small library of C functions, written in ANSI C, + and compiles unmodified in all known platforms. The implementation goals + are simplicity, efficiency, portability, and low embedding cost. + The result is a fast language engine with small footprint, making it + ideal in embedded systems too. + + Lua was awarded the first prize (technological category) in the + Second Compaq Award for Research and Development in Computer Science in 1997. + This award was a joint venture of Compaq Computer in Brazil, the Brazilian + Ministry of Science and Technology, and the Brazilian Academy of Sciences. + + Lua has been used in many different projects around the world. + For a short list, see http://www.tecgraf.puc-rio.br/lua/uses.html . + +* Availability + ------------ + Lua is freely available for both academic and commercial purposes and + can be downloaded from the sites below. See COPYRIGHT for details. + + Home page: http://www.tecgraf.puc-rio.br/lua/ + http://csg.uwaterloo.ca/~lhf/lua/ + In Brazil: ftp://ftp.tecgraf.puc-rio.br/pub/lua/ + In Canada: ftp://csg.uwaterloo.ca/pub/lhf/lua/ + In the US: ftp://ftp.freesoftware.com/pub/languages/lua/ + In Germany: ftp://ftp.uni-trier.de/pub/languages/lua/ + In Germany: ftp://ftp.gwdg.de/pub/languages/lua/ + In Greece: ftp://ftp.ntua.gr/pub/lang/lua/ + In Japan: ftp://ftp.u-aizu.ac.jp/pub/lang/lua/ + In Denmark: ftp://ftp.ucore.com/lua/dist + +* Installation + ------------ + See INSTALL. + +* Contacting the authors + ---------------------- + Lua was designed and implemented by Waldemar Celes, Roberto Ierusalimschy + and Luiz Henrique de Figueiredo. + They can be contacted by email at lua@tecgraf.puc-rio.br. + + Send your comments, questions, and bug reports to lua@tecgraf.puc-rio.br. + For reporting bugs, try also the mailing list: lua-l@tecgraf.puc-rio.br. + For more information about this list, including instructions on how to + subscribe, see http://www.tecgraf.puc-rio.br/lua/lua-l.html . + + Lua is developed at TeCGraf, the Computer Graphics Technology Group + of PUC-Rio (the Pontifical Catholic University of Rio de Janeiro in Brazil). + TeCGraf is a laboratory of the Department of Computer Science. + Dozens of industrial products developed by TeCGraf use Lua. + +(end of README) diff --git a/build/premake/src/Src/Lua/lapi.c b/build/premake/src/Src/Lua/lapi.c new file mode 100644 index 0000000000..ffda86ed7f --- /dev/null +++ b/build/premake/src/Src/Lua/lapi.c @@ -0,0 +1,494 @@ +/* +** $Id: lapi.c,v 1.1 2003/01/24 16:25:58 jason379 Exp $ +** Lua API +** See Copyright Notice in lua.h +*/ + + +#include + +#include "lua.h" + +#include "lapi.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lvm.h" + + +const char lua_ident[] = "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n" + "$Authors: " LUA_AUTHORS " $"; + + + +#define Index(L,i) ((i) >= 0 ? (L->Cbase+((i)-1)) : (L->top+(i))) + +#define api_incr_top(L) incr_top + + + + +TObject *luaA_index (lua_State *L, int index) { + return Index(L, index); +} + + +static TObject *luaA_indexAcceptable (lua_State *L, int index) { + if (index >= 0) { + TObject *o = L->Cbase+(index-1); + if (o >= L->top) return NULL; + else return o; + } + else return L->top+index; +} + + +void luaA_pushobject (lua_State *L, const TObject *o) { + *L->top = *o; + incr_top; +} + +LUA_API int lua_stackspace (lua_State *L) { + return (L->stack_last - L->top); +} + + + +/* +** basic stack manipulation +*/ + + +LUA_API int lua_gettop (lua_State *L) { + return (L->top - L->Cbase); +} + + +LUA_API void lua_settop (lua_State *L, int index) { + if (index >= 0) + luaD_adjusttop(L, L->Cbase, index); + else + L->top = L->top+index+1; /* index is negative */ +} + + +LUA_API void lua_remove (lua_State *L, int index) { + StkId p = luaA_index(L, index); + while (++p < L->top) *(p-1) = *p; + L->top--; +} + + +LUA_API void lua_insert (lua_State *L, int index) { + StkId p = luaA_index(L, index); + StkId q; + for (q = L->top; q>p; q--) + *q = *(q-1); + *p = *L->top; +} + + +LUA_API void lua_pushvalue (lua_State *L, int index) { + *L->top = *luaA_index(L, index); + api_incr_top(L); +} + + + +/* +** access functions (stack -> C) +*/ + + +LUA_API int lua_type (lua_State *L, int index) { + StkId o = luaA_indexAcceptable(L, index); + return (o == NULL) ? LUA_TNONE : ttype(o); +} + +LUA_API const char *lua_typename (lua_State *L, int t) { + UNUSED(L); + return (t == LUA_TNONE) ? "no value" : luaO_typenames[t]; +} + + +LUA_API int lua_iscfunction (lua_State *L, int index) { + StkId o = luaA_indexAcceptable(L, index); + return (o == NULL) ? 0 : iscfunction(o); +} + +LUA_API int lua_isnumber (lua_State *L, int index) { + TObject *o = luaA_indexAcceptable(L, index); + return (o == NULL) ? 0 : (tonumber(o) == 0); +} + +LUA_API int lua_isstring (lua_State *L, int index) { + int t = lua_type(L, index); + return (t == LUA_TSTRING || t == LUA_TNUMBER); +} + + +LUA_API int lua_tag (lua_State *L, int index) { + StkId o = luaA_indexAcceptable(L, index); + return (o == NULL) ? LUA_NOTAG : luaT_tag(o); +} + +LUA_API int lua_equal (lua_State *L, int index1, int index2) { + StkId o1 = luaA_indexAcceptable(L, index1); + StkId o2 = luaA_indexAcceptable(L, index2); + if (o1 == NULL || o2 == NULL) return 0; /* index out-of-range */ + else return luaO_equalObj(o1, o2); +} + +LUA_API int lua_lessthan (lua_State *L, int index1, int index2) { + StkId o1 = luaA_indexAcceptable(L, index1); + StkId o2 = luaA_indexAcceptable(L, index2); + if (o1 == NULL || o2 == NULL) return 0; /* index out-of-range */ + else return luaV_lessthan(L, o1, o2, L->top); +} + + + +LUA_API double lua_tonumber (lua_State *L, int index) { + StkId o = luaA_indexAcceptable(L, index); + return (o == NULL || tonumber(o)) ? 0 : nvalue(o); +} + +LUA_API const char *lua_tostring (lua_State *L, int index) { + StkId o = luaA_indexAcceptable(L, index); + return (o == NULL || tostring(L, o)) ? NULL : svalue(o); +} + +LUA_API size_t lua_strlen (lua_State *L, int index) { + StkId o = luaA_indexAcceptable(L, index); + return (o == NULL || tostring(L, o)) ? 0 : tsvalue(o)->len; +} + +LUA_API lua_CFunction lua_tocfunction (lua_State *L, int index) { + StkId o = luaA_indexAcceptable(L, index); + return (o == NULL || !iscfunction(o)) ? NULL : clvalue(o)->f.c; +} + +LUA_API void *lua_touserdata (lua_State *L, int index) { + StkId o = luaA_indexAcceptable(L, index); + return (o == NULL || ttype(o) != LUA_TUSERDATA) ? NULL : + tsvalue(o)->u.d.value; +} + +LUA_API const void *lua_topointer (lua_State *L, int index) { + StkId o = luaA_indexAcceptable(L, index); + if (o == NULL) return NULL; + switch (ttype(o)) { + case LUA_TTABLE: + return hvalue(o); + case LUA_TFUNCTION: + return clvalue(o); + default: return NULL; + } +} + + + +/* +** push functions (C -> stack) +*/ + + +LUA_API void lua_pushnil (lua_State *L) { + ttype(L->top) = LUA_TNIL; + api_incr_top(L); +} + + +LUA_API void lua_pushnumber (lua_State *L, double n) { + nvalue(L->top) = n; + ttype(L->top) = LUA_TNUMBER; + api_incr_top(L); +} + + +LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) { + tsvalue(L->top) = luaS_newlstr(L, s, len); + ttype(L->top) = LUA_TSTRING; + api_incr_top(L); +} + + +LUA_API void lua_pushstring (lua_State *L, const char *s) { + if (s == NULL) + lua_pushnil(L); + else + lua_pushlstring(L, s, strlen(s)); +} + + +LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { + luaV_Cclosure(L, fn, n); +} + + +LUA_API void lua_pushusertag (lua_State *L, void *u, int tag) { + /* ORDER LUA_T */ + if (!(tag == LUA_ANYTAG || tag == LUA_TUSERDATA || validtag(tag))) + luaO_verror(L, "invalid tag for a userdata (%d)", tag); + tsvalue(L->top) = luaS_createudata(L, u, tag); + ttype(L->top) = LUA_TUSERDATA; + api_incr_top(L); +} + + + +/* +** get functions (Lua -> stack) +*/ + + +LUA_API void lua_getglobal (lua_State *L, const char *name) { + StkId top = L->top; + *top = *luaV_getglobal(L, luaS_new(L, name)); + L->top = top; + api_incr_top(L); +} + + +LUA_API void lua_gettable (lua_State *L, int index) { + StkId t = Index(L, index); + StkId top = L->top; + *(top-1) = *luaV_gettable(L, t); + L->top = top; /* tag method may change top */ +} + + +LUA_API void lua_rawget (lua_State *L, int index) { + StkId t = Index(L, index); + LUA_ASSERT(ttype(t) == LUA_TTABLE, "table expected"); + *(L->top - 1) = *luaH_get(L, hvalue(t), L->top - 1); +} + + +LUA_API void lua_rawgeti (lua_State *L, int index, int n) { + StkId o = Index(L, index); + LUA_ASSERT(ttype(o) == LUA_TTABLE, "table expected"); + *L->top = *luaH_getnum(hvalue(o), n); + api_incr_top(L); +} + + +LUA_API void lua_getglobals (lua_State *L) { + hvalue(L->top) = L->gt; + ttype(L->top) = LUA_TTABLE; + api_incr_top(L); +} + + +LUA_API int lua_getref (lua_State *L, int ref) { + if (ref == LUA_REFNIL) + ttype(L->top) = LUA_TNIL; + else if (0 <= ref && ref < L->refSize && + (L->refArray[ref].st == LOCK || L->refArray[ref].st == HOLD)) + *L->top = L->refArray[ref].o; + else + return 0; + api_incr_top(L); + return 1; +} + + +LUA_API void lua_newtable (lua_State *L) { + hvalue(L->top) = luaH_new(L, 0); + ttype(L->top) = LUA_TTABLE; + api_incr_top(L); +} + + + +/* +** set functions (stack -> Lua) +*/ + + +LUA_API void lua_setglobal (lua_State *L, const char *name) { + StkId top = L->top; + luaV_setglobal(L, luaS_new(L, name)); + L->top = top-1; /* remove element from the top */ +} + + +LUA_API void lua_settable (lua_State *L, int index) { + StkId t = Index(L, index); + StkId top = L->top; + luaV_settable(L, t, top-2); + L->top = top-2; /* pop index and value */ +} + + +LUA_API void lua_rawset (lua_State *L, int index) { + StkId t = Index(L, index); + LUA_ASSERT(ttype(t) == LUA_TTABLE, "table expected"); + *luaH_set(L, hvalue(t), L->top-2) = *(L->top-1); + L->top -= 2; +} + + +LUA_API void lua_rawseti (lua_State *L, int index, int n) { + StkId o = Index(L, index); + LUA_ASSERT(ttype(o) == LUA_TTABLE, "table expected"); + *luaH_setint(L, hvalue(o), n) = *(L->top-1); + L->top--; +} + + +LUA_API void lua_setglobals (lua_State *L) { + StkId newtable = --L->top; + LUA_ASSERT(ttype(newtable) == LUA_TTABLE, "table expected"); + L->gt = hvalue(newtable); +} + + +LUA_API int lua_ref (lua_State *L, int lock) { + int ref; + if (ttype(L->top-1) == LUA_TNIL) + ref = LUA_REFNIL; + else { + if (L->refFree != NONEXT) { /* is there a free place? */ + ref = L->refFree; + L->refFree = L->refArray[ref].st; + } + else { /* no more free places */ + luaM_growvector(L, L->refArray, L->refSize, 1, struct Ref, + "reference table overflow", MAX_INT); + L->nblocks += sizeof(struct Ref); + ref = L->refSize++; + } + L->refArray[ref].o = *(L->top-1); + L->refArray[ref].st = lock ? LOCK : HOLD; + } + L->top--; + return ref; +} + + +/* +** "do" functions (run Lua code) +** (most of them are in ldo.c) +*/ + +LUA_API void lua_rawcall (lua_State *L, int nargs, int nresults) { + luaD_call(L, L->top-(nargs+1), nresults); +} + + +/* +** Garbage-collection functions +*/ + +/* GC values are expressed in Kbytes: #bytes/2^10 */ +#define GCscale(x) ((int)((x)>>10)) +#define GCunscale(x) ((unsigned long)(x)<<10) + +LUA_API int lua_getgcthreshold (lua_State *L) { + return GCscale(L->GCthreshold); +} + +LUA_API int lua_getgccount (lua_State *L) { + return GCscale(L->nblocks); +} + +LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold) { + if (newthreshold > GCscale(ULONG_MAX)) + L->GCthreshold = ULONG_MAX; + else + L->GCthreshold = GCunscale(newthreshold); + luaC_checkGC(L); +} + + +/* +** miscellaneous functions +*/ + +LUA_API void lua_settag (lua_State *L, int tag) { + luaT_realtag(L, tag); + switch (ttype(L->top-1)) { + case LUA_TTABLE: + hvalue(L->top-1)->htag = tag; + break; + case LUA_TUSERDATA: + tsvalue(L->top-1)->u.d.tag = tag; + break; + default: + luaO_verror(L, "cannot change the tag of a %.20s", + luaO_typename(L->top-1)); + } +} + + +LUA_API void lua_unref (lua_State *L, int ref) { + if (ref >= 0) { + LUA_ASSERT(ref < L->refSize && L->refArray[ref].st < 0, "invalid ref"); + L->refArray[ref].st = L->refFree; + L->refFree = ref; + } +} + + +LUA_API int lua_next (lua_State *L, int index) { + StkId t = luaA_index(L, index); + Node *n; + LUA_ASSERT(ttype(t) == LUA_TTABLE, "table expected"); + n = luaH_next(L, hvalue(t), luaA_index(L, -1)); + if (n) { + *(L->top-1) = *key(n); + *L->top = *val(n); + api_incr_top(L); + return 1; + } + else { /* no more elements */ + L->top -= 1; /* remove key */ + return 0; + } +} + + +LUA_API int lua_getn (lua_State *L, int index) { + Hash *h = hvalue(luaA_index(L, index)); + const TObject *value = luaH_getstr(h, luaS_new(L, "n")); /* value = h.n */ + if (ttype(value) == LUA_TNUMBER) + return (int)nvalue(value); + else { + Number max = 0; + int i = h->size; + Node *n = h->node; + while (i--) { + if (ttype(key(n)) == LUA_TNUMBER && + ttype(val(n)) != LUA_TNIL && + nvalue(key(n)) > max) + max = nvalue(key(n)); + n++; + } + return (int)max; + } +} + + +LUA_API void lua_concat (lua_State *L, int n) { + StkId top = L->top; + luaV_strconc(L, n, top); + L->top = top-(n-1); + luaC_checkGC(L); +} + + +LUA_API void *lua_newuserdata (lua_State *L, size_t size) { + TString *ts = luaS_newudata(L, (size==0) ? 1 : size, NULL); + tsvalue(L->top) = ts; + ttype(L->top) = LUA_TUSERDATA; + api_incr_top(L); + return ts->u.d.value; +} + diff --git a/build/premake/src/Src/Lua/lapi.h b/build/premake/src/Src/Lua/lapi.h new file mode 100644 index 0000000000..fab2278615 --- /dev/null +++ b/build/premake/src/Src/Lua/lapi.h @@ -0,0 +1,17 @@ +/* +** $Id: lapi.h,v 1.1 2003/01/24 16:25:58 jason379 Exp $ +** Auxiliary functions from Lua API +** See Copyright Notice in lua.h +*/ + +#ifndef lapi_h +#define lapi_h + + +#include "lobject.h" + + +TObject *luaA_index (lua_State *L, int index); +void luaA_pushobject (lua_State *L, const TObject *o); + +#endif diff --git a/build/premake/src/Src/Lua/lauxlib.c b/build/premake/src/Src/Lua/lauxlib.c new file mode 100644 index 0000000000..8076230213 --- /dev/null +++ b/build/premake/src/Src/Lua/lauxlib.c @@ -0,0 +1,216 @@ +/* +** $Id: lauxlib.c,v 1.2 2003/04/23 12:16:05 jason379 Exp $ +** Auxiliary functions for building Lua libraries +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include + +/* This file uses only the official API of Lua. +** Any function declared here could be written as an application function. +** With care, these functions can be used by other libraries. +*/ + +#include "lua.h" + +#include "lauxlib.h" +#include "luadebug.h" + + + +LUALIB_API int luaL_findstring (const char *name, const char *const list[]) { + int i; + for (i=0; list[i]; i++) + if (strcmp(list[i], name) == 0) + return i; + return -1; /* name not found */ +} + +LUALIB_API void luaL_argerror (lua_State *L, int narg, const char *extramsg) { + lua_Debug ar; + lua_getstack(L, 0, &ar); + lua_getinfo(L, "n", &ar); + if (ar.name == NULL) + ar.name = "?"; + luaL_verror(L, "bad argument #%d to `%.50s' (%.100s)", + narg, ar.name, extramsg); +} + + +static void type_error (lua_State *L, int narg, int t) { + char buff[50]; + sprintf(buff, "%.8s expected, got %.8s", lua_typename(L, t), + lua_typename(L, lua_type(L, narg))); + luaL_argerror(L, narg, buff); +} + + +LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) { + if (space > lua_stackspace(L)) + luaL_verror(L, "stack overflow (%.30s)", mes); +} + + +LUALIB_API void luaL_checktype(lua_State *L, int narg, int t) { + if (lua_type(L, narg) != t) + type_error(L, narg, t); +} + + +LUALIB_API void luaL_checkany (lua_State *L, int narg) { + if (lua_type(L, narg) == LUA_TNONE) + luaL_argerror(L, narg, "value expected"); +} + + +LUALIB_API const char *luaL_check_lstr (lua_State *L, int narg, size_t *len) { + const char *s = lua_tostring(L, narg); + if (!s) type_error(L, narg, LUA_TSTRING); + if (len) *len = lua_strlen(L, narg); + return s; +} + + +LUALIB_API const char *luaL_opt_lstr (lua_State *L, int narg, const char *def, size_t *len) { + if (lua_isnull(L, narg)) { + if (len) + *len = (def ? strlen(def) : 0); + return def; + } + else return luaL_check_lstr(L, narg, len); +} + + +LUALIB_API double luaL_check_number (lua_State *L, int narg) { + double d = lua_tonumber(L, narg); + if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ + type_error(L, narg, LUA_TNUMBER); + return d; +} + + +LUALIB_API double luaL_opt_number (lua_State *L, int narg, double def) { + if (lua_isnull(L, narg)) return def; + else return luaL_check_number(L, narg); +} + + +LUALIB_API void luaL_openlib (lua_State *L, const struct luaL_reg *l, int n) { + int i; + for (i=0; ip == (B)->buffer) +#define bufflen(B) ((B)->p - (B)->buffer) +#define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B))) + +#define LIMIT (LUA_MINSTACK/2) + + +static int emptybuffer (luaL_Buffer *B) { + size_t l = bufflen(B); + if (l == 0) return 0; /* put nothing on stack */ + else { + lua_pushlstring(B->L, B->buffer, l); + B->p = B->buffer; + B->level++; + return 1; + } +} + + +static void adjuststack (luaL_Buffer *B) { + if (B->level > 1) { + lua_State *L = B->L; + int toget = 1; /* number of levels to concat */ + size_t toplen = lua_strlen(L, -1); + do { + size_t l = lua_strlen(L, -(toget+1)); + if (B->level - toget + 1 >= LIMIT || toplen > l) { + toplen += l; + toget++; + } + else break; + } while (toget < B->level); + if (toget >= 2) { + lua_concat(L, toget); + B->level = B->level - toget + 1; + } + } +} + + +LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) { + if (emptybuffer(B)) + adjuststack(B); + return B->buffer; +} + + +LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { + while (l--) + luaL_putchar(B, *s++); +} + + +LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) { + luaL_addlstring(B, s, strlen(s)); +} + + +LUALIB_API void luaL_pushresult (luaL_Buffer *B) { + emptybuffer(B); + if (B->level == 0) + lua_pushlstring(B->L, NULL, 0); + else if (B->level > 1) + lua_concat(B->L, B->level); + B->level = 1; +} + + +LUALIB_API void luaL_addvalue (luaL_Buffer *B) { + lua_State *L = B->L; + size_t vl = lua_strlen(L, -1); + if (vl <= bufffree(B)) { /* fit into buffer? */ + memcpy(B->p, lua_tostring(L, -1), vl); /* put it there */ + B->p += vl; + lua_pop(L, 1); /* remove from stack */ + } + else { + if (emptybuffer(B)) + lua_insert(L, -2); /* put buffer before new value */ + B->level++; /* add new value into B stack */ + adjuststack(B); + } +} + + +LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) { + B->L = L; + B->p = B->buffer; + B->level = 0; +} + +/* }====================================================== */ diff --git a/build/premake/src/Src/Lua/lauxlib.h b/build/premake/src/Src/Lua/lauxlib.h new file mode 100644 index 0000000000..d87b209c48 --- /dev/null +++ b/build/premake/src/Src/Lua/lauxlib.h @@ -0,0 +1,100 @@ +/* +** $Id: lauxlib.h,v 1.1 2003/01/24 16:25:59 jason379 Exp $ +** Auxiliary functions for building Lua libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lauxlib_h +#define lauxlib_h + + +#include +#include + +#include "lua.h" + + +#ifndef LUALIB_API +#define LUALIB_API extern +#endif + + +struct luaL_reg { + const char *name; + lua_CFunction func; +}; + + +LUALIB_API void luaL_openlib (lua_State *L, const struct luaL_reg *l, int n); +LUALIB_API void luaL_argerror (lua_State *L, int numarg, const char *extramsg); +LUALIB_API const char *luaL_check_lstr (lua_State *L, int numArg, size_t *len); +LUALIB_API const char *luaL_opt_lstr (lua_State *L, int numArg, const char *def, size_t *len); +LUALIB_API double luaL_check_number (lua_State *L, int numArg); +LUALIB_API double luaL_opt_number (lua_State *L, int numArg, double def); + +LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg); +LUALIB_API void luaL_checktype (lua_State *L, int narg, int t); +LUALIB_API void luaL_checkany (lua_State *L, int narg); + +LUALIB_API void luaL_verror (lua_State *L, const char *fmt, ...); +LUALIB_API int luaL_findstring (const char *name, const char *const list[]); + + + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ + +#define luaL_arg_check(L, cond,numarg,extramsg) if (!(cond)) \ + luaL_argerror(L, numarg,extramsg) +#define luaL_check_string(L,n) (luaL_check_lstr(L, (n), NULL)) +#define luaL_opt_string(L,n,d) (luaL_opt_lstr(L, (n), (d), NULL)) +#define luaL_check_int(L,n) ((int)luaL_check_number(L, n)) +#define luaL_check_long(L,n) ((long)luaL_check_number(L, n)) +#define luaL_opt_int(L,n,d) ((int)luaL_opt_number(L, n,d)) +#define luaL_opt_long(L,n,d) ((long)luaL_opt_number(L, n,d)) +#define luaL_openl(L,a) luaL_openlib(L, a, (sizeof(a)/sizeof(a[0]))) + + +/* +** {====================================================== +** Generic Buffer manipulation +** ======================================================= +*/ + + +#ifndef LUAL_BUFFERSIZE +#define LUAL_BUFFERSIZE BUFSIZ +#endif + + +typedef struct luaL_Buffer { + char *p; /* current position in buffer */ + int level; + lua_State *L; + char buffer[LUAL_BUFFERSIZE]; +} luaL_Buffer; + +#define luaL_putchar(B,c) \ + ((void)((B)->p < &(B)->buffer[LUAL_BUFFERSIZE] || luaL_prepbuffer(B)), \ + (*(B)->p++ = (char)(c))) + +#define luaL_addsize(B,n) ((B)->p += (n)) + +LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B); +LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B); +LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l); +LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s); +LUALIB_API void luaL_addvalue (luaL_Buffer *B); +LUALIB_API void luaL_pushresult (luaL_Buffer *B); + + +/* }====================================================== */ + + +#endif + + diff --git a/build/premake/src/Src/Lua/lbaselib.c b/build/premake/src/Src/Lua/lbaselib.c new file mode 100644 index 0000000000..23c0e919f6 --- /dev/null +++ b/build/premake/src/Src/Lua/lbaselib.c @@ -0,0 +1,651 @@ +/* +** $Id: lbaselib.c,v 1.2 2003/04/23 12:16:05 jason379 Exp $ +** Basic library +** See Copyright Notice in lua.h +*/ + + + +#include +#include +#include +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "luadebug.h" +#include "lualib.h" + + + +/* +** If your system does not support `stderr', redefine this function, or +** redefine _ERRORMESSAGE so that it won't need _ALERT. +*/ +static int luaB__ALERT (lua_State *L) { + fputs(luaL_check_string(L, 1), stderr); + return 0; +} + + +/* +** Basic implementation of _ERRORMESSAGE. +** The library `liolib' redefines _ERRORMESSAGE for better error information. +*/ +static int luaB__ERRORMESSAGE (lua_State *L) { + luaL_checktype(L, 1, LUA_TSTRING); + lua_getglobal(L, LUA_ALERT); + if (lua_isfunction(L, -1)) { /* avoid error loop if _ALERT is not defined */ + lua_Debug ar; + lua_pushstring(L, "error: "); + lua_pushvalue(L, 1); + if (lua_getstack(L, 1, &ar)) { + lua_getinfo(L, "Sl", &ar); + if (ar.source && ar.currentline > 0) { + char buff[100]; + sprintf(buff, "\n <%.70s: line %d>", ar.short_src, ar.currentline); + lua_pushstring(L, buff); + lua_concat(L, 2); + } + } + lua_pushstring(L, "\n"); + lua_concat(L, 3); + lua_rawcall(L, 1, 0); + } + return 0; +} + + +/* +** If your system does not support `stdout', you can just remove this function. +** If you need, you can define your own `print' function, following this +** model but changing `fputs' to put the strings at a proper place +** (a console window or a log file, for instance). +*/ +static int luaB_print (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + int i; + lua_getglobal(L, "tostring"); + for (i=1; i<=n; i++) { + const char *s; + lua_pushvalue(L, -1); /* function to be called */ + lua_pushvalue(L, i); /* value to print */ + lua_rawcall(L, 1, 1); + s = lua_tostring(L, -1); /* get result */ + if (s == NULL) + lua_error(L, "`tostring' must return a string to `print'"); + if (i>1) fputs("\t", stdout); + fputs(s, stdout); + lua_pop(L, 1); /* pop result */ + } + fputs("\n", stdout); + return 0; +} + + +static int luaB_tonumber (lua_State *L) { + int base = luaL_opt_int(L, 2, 10); + if (base == 10) { /* standard conversion */ + luaL_checkany(L, 1); + if (lua_isnumber(L, 1)) { + lua_pushnumber(L, lua_tonumber(L, 1)); + return 1; + } + } + else { + const char *s1 = luaL_check_string(L, 1); + char *s2; + unsigned long n; + luaL_arg_check(L, 2 <= base && base <= 36, 2, "base out of range"); + n = strtoul(s1, &s2, base); + if (s1 != s2) { /* at least one valid digit? */ + while (isspace((unsigned char)*s2)) s2++; /* skip trailing spaces */ + if (*s2 == '\0') { /* no invalid trailing characters? */ + lua_pushnumber(L, n); + return 1; + } + } + } + lua_pushnil(L); /* else not a number */ + return 1; +} + + +static int luaB_error (lua_State *L) { + lua_error(L, luaL_opt_string(L, 1, NULL)); + return 0; /* to avoid warnings */ +} + +static int luaB_setglobal (lua_State *L) { + luaL_checkany(L, 2); + lua_setglobal(L, luaL_check_string(L, 1)); + return 0; +} + +static int luaB_getglobal (lua_State *L) { + lua_getglobal(L, luaL_check_string(L, 1)); + return 1; +} + +static int luaB_tag (lua_State *L) { + luaL_checkany(L, 1); + lua_pushnumber(L, lua_tag(L, 1)); + return 1; +} + +static int luaB_settag (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + lua_pushvalue(L, 1); /* push table */ + lua_settag(L, luaL_check_int(L, 2)); + return 1; /* return table */ +} + +static int luaB_newtag (lua_State *L) { + lua_pushnumber(L, lua_newtag(L)); + return 1; +} + +static int luaB_copytagmethods (lua_State *L) { + lua_pushnumber(L, lua_copytagmethods(L, luaL_check_int(L, 1), + luaL_check_int(L, 2))); + return 1; +} + +static int luaB_globals (lua_State *L) { + lua_getglobals(L); /* value to be returned */ + if (!lua_isnull(L, 1)) { + luaL_checktype(L, 1, LUA_TTABLE); + lua_pushvalue(L, 1); /* new table of globals */ + lua_setglobals(L); + } + return 1; +} + +static int luaB_rawget (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 2); + lua_rawget(L, 1); + return 1; +} + +static int luaB_rawset (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 2); + luaL_checkany(L, 3); + lua_rawset(L, 1); + return 1; +} + +static int luaB_settagmethod (lua_State *L) { + int tag = luaL_check_int(L, 1); + const char *event = luaL_check_string(L, 2); + luaL_arg_check(L, lua_isfunction(L, 3) || lua_isnil(L, 3), 3, + "function or nil expected"); + if (strcmp(event, "gc") == 0) + lua_error(L, "deprecated use: cannot set the `gc' tag method from Lua"); + lua_gettagmethod(L, tag, event); + lua_pushvalue(L, 3); + lua_settagmethod(L, tag, event); + return 1; +} + + +static int luaB_gettagmethod (lua_State *L) { + int tag = luaL_check_int(L, 1); + const char *event = luaL_check_string(L, 2); + if (strcmp(event, "gc") == 0) + lua_error(L, "deprecated use: cannot get the `gc' tag method from Lua"); + lua_gettagmethod(L, tag, event); + return 1; +} + + +static int luaB_gcinfo (lua_State *L) { + lua_pushnumber(L, lua_getgccount(L)); + lua_pushnumber(L, lua_getgcthreshold(L)); + return 2; +} + + +static int luaB_collectgarbage (lua_State *L) { + lua_setgcthreshold(L, luaL_opt_int(L, 1, 0)); + return 0; +} + + +static int luaB_type (lua_State *L) { + luaL_checkany(L, 1); + lua_pushstring(L, lua_typename(L, lua_type(L, 1))); + return 1; +} + + +static int luaB_next (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 2); /* create a 2nd argument if there isn't one */ + if (lua_next(L, 1)) + return 2; + else { + lua_pushnil(L); + return 1; + } +} + + +static int passresults (lua_State *L, int status, int oldtop) { + static const char *const errornames[] = + {"ok", "run-time error", "file error", "syntax error", + "memory error", "error in error handling"}; + if (status == 0) { + int nresults = lua_gettop(L) - oldtop; + if (nresults > 0) + return nresults; /* results are already on the stack */ + else { + lua_pushuserdata(L, NULL); /* at least one result to signal no errors */ + return 1; + } + } + else { /* error */ + lua_pushnil(L); + lua_pushstring(L, errornames[status]); /* error code */ + return 2; + } +} + +static int luaB_dostring (lua_State *L) { + int oldtop = lua_gettop(L); + size_t l; + const char *s = luaL_check_lstr(L, 1, &l); + if (*s == '\33') /* binary files start with ESC... */ + lua_error(L, "`dostring' cannot run pre-compiled code"); + return passresults(L, lua_dobuffer(L, s, l, luaL_opt_string(L, 2, s)), oldtop); +} + + +static int luaB_dofile (lua_State *L) { + int oldtop = lua_gettop(L); + const char *fname = luaL_opt_string(L, 1, NULL); + return passresults(L, lua_dofile(L, fname), oldtop); +} + + +static int luaB_call (lua_State *L) { + int oldtop; + const char *options = luaL_opt_string(L, 3, ""); + int err = 0; /* index of old error method */ + int i, status; + int n; + luaL_checktype(L, 2, LUA_TTABLE); + n = lua_getn(L, 2); + if (!lua_isnull(L, 4)) { /* set new error method */ + lua_getglobal(L, LUA_ERRORMESSAGE); + err = lua_gettop(L); /* get index */ + lua_pushvalue(L, 4); + lua_setglobal(L, LUA_ERRORMESSAGE); + } + oldtop = lua_gettop(L); /* top before function-call preparation */ + /* push function */ + lua_pushvalue(L, 1); + luaL_checkstack(L, n, "too many arguments"); + for (i=0; i=pos; n--) { + lua_rawgeti(L, 1, n); + lua_rawseti(L, 1, n+1); /* t[n+1] = t[n] */ + } + lua_pushvalue(L, v); + lua_rawseti(L, 1, pos); /* t[pos] = v */ + return 0; +} + + +static int luaB_tremove (lua_State *L) { + int pos, n; + luaL_checktype(L, 1, LUA_TTABLE); + n = lua_getn(L, 1); + pos = luaL_opt_int(L, 2, n); + if (n <= 0) return 0; /* table is "empty" */ + lua_rawgeti(L, 1, pos); /* result = t[pos] */ + for ( ;pos= P */ + while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) { + if (i>u) lua_error(L, "invalid order function for sorting"); + lua_pop(L, 1); /* remove a[i] */ + } + /* repeat --j until a[j] <= P */ + while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) { + if (jt.token); +} + + +/* +** Returns the the previous instruction, for optimizations. +** If there is a jump target between this and the current instruction, +** returns a dummy instruction to avoid wrong optimizations. +*/ +static Instruction previous_instruction (FuncState *fs) { + if (fs->pc > fs->lasttarget) /* no jumps to current position? */ + return fs->f->code[fs->pc-1]; /* returns previous instruction */ + else + return CREATE_0(OP_END); /* no optimizations after an `END' */ +} + + +int luaK_jump (FuncState *fs) { + int j = luaK_code1(fs, OP_JMP, NO_JUMP); + if (j == fs->lasttarget) { /* possible jumps to this jump? */ + luaK_concat(fs, &j, fs->jlt); /* keep them on hold */ + fs->jlt = NO_JUMP; + } + return j; +} + + +static void luaK_fixjump (FuncState *fs, int pc, int dest) { + Instruction *jmp = &fs->f->code[pc]; + if (dest == NO_JUMP) + SETARG_S(*jmp, NO_JUMP); /* point to itself to represent end of list */ + else { /* jump is relative to position following jump instruction */ + int offset = dest-(pc+1); + if (abs(offset) > MAXARG_S) + luaK_error(fs->ls, "control structure too long"); + SETARG_S(*jmp, offset); + } +} + + +static int luaK_getjump (FuncState *fs, int pc) { + int offset = GETARG_S(fs->f->code[pc]); + if (offset == NO_JUMP) /* point to itself represents end of list */ + return NO_JUMP; /* end of list */ + else + return (pc+1)+offset; /* turn offset into absolute position */ +} + + +/* +** returns current `pc' and marks it as a jump target (to avoid wrong +** optimizations with consecutive instructions not in the same basic block). +** discharge list of jumps to last target. +*/ +int luaK_getlabel (FuncState *fs) { + if (fs->pc != fs->lasttarget) { + int lasttarget = fs->lasttarget; + fs->lasttarget = fs->pc; + luaK_patchlist(fs, fs->jlt, lasttarget); /* discharge old list `jlt' */ + fs->jlt = NO_JUMP; /* nobody jumps to this new label (yet) */ + } + return fs->pc; +} + + +void luaK_deltastack (FuncState *fs, int delta) { + fs->stacklevel += delta; + if (fs->stacklevel > fs->f->maxstacksize) { + if (fs->stacklevel > MAXSTACK) + luaK_error(fs->ls, "function or expression too complex"); + fs->f->maxstacksize = fs->stacklevel; + } +} + + +void luaK_kstr (LexState *ls, int c) { + luaK_code1(ls->fs, OP_PUSHSTRING, c); +} + + +static int number_constant (FuncState *fs, Number r) { + /* check whether `r' has appeared within the last LOOKBACKNUMS entries */ + Proto *f = fs->f; + int c = f->nknum; + int lim = c < LOOKBACKNUMS ? 0 : c-LOOKBACKNUMS; + while (--c >= lim) + if (f->knum[c] == r) return c; + /* not found; create a new entry */ + luaM_growvector(fs->L, f->knum, f->nknum, 1, Number, + "constant table overflow", MAXARG_U); + c = f->nknum++; + f->knum[c] = r; + return c; +} + + +void luaK_number (FuncState *fs, Number f) { + if (f <= (Number)MAXARG_S && (Number)(int)f == f) + luaK_code1(fs, OP_PUSHINT, (int)f); /* f has a short integer value */ + else + luaK_code1(fs, OP_PUSHNUM, number_constant(fs, f)); +} + + +void luaK_adjuststack (FuncState *fs, int n) { + if (n > 0) + luaK_code1(fs, OP_POP, n); + else + luaK_code1(fs, OP_PUSHNIL, -n); +} + + +int luaK_lastisopen (FuncState *fs) { + /* check whether last instruction is an open function call */ + Instruction i = previous_instruction(fs); + if (GET_OPCODE(i) == OP_CALL && GETARG_B(i) == MULT_RET) + return 1; + else return 0; +} + + +void luaK_setcallreturns (FuncState *fs, int nresults) { + if (luaK_lastisopen(fs)) { /* expression is an open function call? */ + SETARG_B(fs->f->code[fs->pc-1], nresults); /* set number of results */ + luaK_deltastack(fs, nresults); /* push results */ + } +} + + +static int discharge (FuncState *fs, expdesc *var) { + switch (var->k) { + case VLOCAL: + luaK_code1(fs, OP_GETLOCAL, var->u.index); + break; + case VGLOBAL: + luaK_code1(fs, OP_GETGLOBAL, var->u.index); + break; + case VINDEXED: + luaK_code0(fs, OP_GETTABLE); + break; + case VEXP: + return 0; /* nothing to do */ + } + var->k = VEXP; + var->u.l.t = var->u.l.f = NO_JUMP; + return 1; +} + + +static void discharge1 (FuncState *fs, expdesc *var) { + discharge(fs, var); + /* if it has jumps then it is already discharged */ + if (var->u.l.t == NO_JUMP && var->u.l.f == NO_JUMP) + luaK_setcallreturns(fs, 1); /* call must return 1 value */ +} + + +void luaK_storevar (LexState *ls, const expdesc *var) { + FuncState *fs = ls->fs; + switch (var->k) { + case VLOCAL: + luaK_code1(fs, OP_SETLOCAL, var->u.index); + break; + case VGLOBAL: + luaK_code1(fs, OP_SETGLOBAL, var->u.index); + break; + case VINDEXED: /* table is at top-3; pop 3 elements after operation */ + luaK_code2(fs, OP_SETTABLE, 3, 3); + break; + default: + LUA_INTERNALERROR("invalid var kind to store"); + } +} + + +static OpCode invertjump (OpCode op) { + switch (op) { + case OP_JMPNE: return OP_JMPEQ; + case OP_JMPEQ: return OP_JMPNE; + case OP_JMPLT: return OP_JMPGE; + case OP_JMPLE: return OP_JMPGT; + case OP_JMPGT: return OP_JMPLE; + case OP_JMPGE: return OP_JMPLT; + case OP_JMPT: case OP_JMPONT: return OP_JMPF; + case OP_JMPF: case OP_JMPONF: return OP_JMPT; + default: + LUA_INTERNALERROR("invalid jump instruction"); + return OP_END; /* to avoid warnings */ + } +} + + +static void luaK_patchlistaux (FuncState *fs, int list, int target, + OpCode special, int special_target) { + Instruction *code = fs->f->code; + while (list != NO_JUMP) { + int next = luaK_getjump(fs, list); + Instruction *i = &code[list]; + OpCode op = GET_OPCODE(*i); + if (op == special) /* this `op' already has a value */ + luaK_fixjump(fs, list, special_target); + else { + luaK_fixjump(fs, list, target); /* do the patch */ + if (op == OP_JMPONT) /* remove eventual values */ + SET_OPCODE(*i, OP_JMPT); + else if (op == OP_JMPONF) + SET_OPCODE(*i, OP_JMPF); + } + list = next; + } +} + + +void luaK_patchlist (FuncState *fs, int list, int target) { + if (target == fs->lasttarget) /* same target that list `jlt'? */ + luaK_concat(fs, &fs->jlt, list); /* delay fixing */ + else + luaK_patchlistaux(fs, list, target, OP_END, 0); +} + + +static int need_value (FuncState *fs, int list, OpCode hasvalue) { + /* check whether list has a jump without a value */ + for (; list != NO_JUMP; list = luaK_getjump(fs, list)) + if (GET_OPCODE(fs->f->code[list]) != hasvalue) return 1; + return 0; /* not found */ +} + + +void luaK_concat (FuncState *fs, int *l1, int l2) { + if (*l1 == NO_JUMP) + *l1 = l2; + else { + int list = *l1; + for (;;) { /* traverse `l1' */ + int next = luaK_getjump(fs, list); + if (next == NO_JUMP) { /* end of list? */ + luaK_fixjump(fs, list, l2); + return; + } + list = next; + } + } +} + + +static void luaK_testgo (FuncState *fs, expdesc *v, int invert, OpCode jump) { + int prevpos; /* position of last instruction */ + Instruction *previous; + int *golist, *exitlist; + if (!invert) { + golist = &v->u.l.f; /* go if false */ + exitlist = &v->u.l.t; /* exit if true */ + } + else { + golist = &v->u.l.t; /* go if true */ + exitlist = &v->u.l.f; /* exit if false */ + } + discharge1(fs, v); + prevpos = fs->pc-1; + previous = &fs->f->code[prevpos]; + LUA_ASSERT(*previous==previous_instruction(fs), "no jump allowed here"); + if (!ISJUMP(GET_OPCODE(*previous))) + prevpos = luaK_code1(fs, jump, NO_JUMP); + else { /* last instruction is already a jump */ + if (invert) + SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous))); + } + luaK_concat(fs, exitlist, prevpos); /* insert last jump in `exitlist' */ + luaK_patchlist(fs, *golist, luaK_getlabel(fs)); + *golist = NO_JUMP; +} + + +void luaK_goiftrue (FuncState *fs, expdesc *v, int keepvalue) { + luaK_testgo(fs, v, 1, keepvalue ? OP_JMPONF : OP_JMPF); +} + + +static void luaK_goiffalse (FuncState *fs, expdesc *v, int keepvalue) { + luaK_testgo(fs, v, 0, keepvalue ? OP_JMPONT : OP_JMPT); +} + + +static int code_label (FuncState *fs, OpCode op, int arg) { + luaK_getlabel(fs); /* those instructions may be jump targets */ + return luaK_code1(fs, op, arg); +} + + +void luaK_tostack (LexState *ls, expdesc *v, int onlyone) { + FuncState *fs = ls->fs; + if (!discharge(fs, v)) { /* `v' is an expression? */ + OpCode previous = GET_OPCODE(fs->f->code[fs->pc-1]); + if (!ISJUMP(previous) && v->u.l.f == NO_JUMP && v->u.l.t == NO_JUMP) { + /* expression has no jumps */ + if (onlyone) + luaK_setcallreturns(fs, 1); /* call must return 1 value */ + } + else { /* expression has jumps */ + int final; /* position after whole expression */ + int j = NO_JUMP; /* eventual jump over values */ + int p_nil = NO_JUMP; /* position of an eventual PUSHNIL */ + int p_1 = NO_JUMP; /* position of an eventual PUSHINT */ + if (ISJUMP(previous) || need_value(fs, v->u.l.f, OP_JMPONF) + || need_value(fs, v->u.l.t, OP_JMPONT)) { + /* expression needs values */ + if (ISJUMP(previous)) + luaK_concat(fs, &v->u.l.t, fs->pc-1); /* put `previous' in t. list */ + else { + j = code_label(fs, OP_JMP, NO_JUMP); /* to jump over both pushes */ + /* correct stack for compiler and symbolic execution */ + luaK_adjuststack(fs, 1); + } + p_nil = code_label(fs, OP_PUSHNILJMP, 0); + p_1 = code_label(fs, OP_PUSHINT, 1); + luaK_patchlist(fs, j, luaK_getlabel(fs)); + } + final = luaK_getlabel(fs); + luaK_patchlistaux(fs, v->u.l.f, p_nil, OP_JMPONF, final); + luaK_patchlistaux(fs, v->u.l.t, p_1, OP_JMPONT, final); + v->u.l.f = v->u.l.t = NO_JUMP; + } + } +} + + +void luaK_prefix (LexState *ls, UnOpr op, expdesc *v) { + FuncState *fs = ls->fs; + if (op == OPR_MINUS) { + luaK_tostack(ls, v, 1); + luaK_code0(fs, OP_MINUS); + } + else { /* op == NOT */ + Instruction *previous; + discharge1(fs, v); + previous = &fs->f->code[fs->pc-1]; + if (ISJUMP(GET_OPCODE(*previous))) + SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous))); + else + luaK_code0(fs, OP_NOT); + /* interchange true and false lists */ + { int temp = v->u.l.f; v->u.l.f = v->u.l.t; v->u.l.t = temp; } + } +} + + +void luaK_infix (LexState *ls, BinOpr op, expdesc *v) { + FuncState *fs = ls->fs; + switch (op) { + case OPR_AND: + luaK_goiftrue(fs, v, 1); + break; + case OPR_OR: + luaK_goiffalse(fs, v, 1); + break; + default: + luaK_tostack(ls, v, 1); /* all other binary operators need a value */ + } +} + + + +static const struct { + OpCode opcode; /* opcode for each binary operator */ + int arg; /* default argument for the opcode */ +} codes[] = { /* ORDER OPR */ + {OP_ADD, 0}, {OP_SUB, 0}, {OP_MULT, 0}, {OP_DIV, 0}, + {OP_POW, 0}, {OP_CONCAT, 2}, + {OP_JMPNE, NO_JUMP}, {OP_JMPEQ, NO_JUMP}, + {OP_JMPLT, NO_JUMP}, {OP_JMPLE, NO_JUMP}, + {OP_JMPGT, NO_JUMP}, {OP_JMPGE, NO_JUMP} +}; + + +void luaK_posfix (LexState *ls, BinOpr op, expdesc *v1, expdesc *v2) { + FuncState *fs = ls->fs; + switch (op) { + case OPR_AND: { + LUA_ASSERT(v1->u.l.t == NO_JUMP, "list must be closed"); + discharge1(fs, v2); + v1->u.l.t = v2->u.l.t; + luaK_concat(fs, &v1->u.l.f, v2->u.l.f); + break; + } + case OPR_OR: { + LUA_ASSERT(v1->u.l.f == NO_JUMP, "list must be closed"); + discharge1(fs, v2); + v1->u.l.f = v2->u.l.f; + luaK_concat(fs, &v1->u.l.t, v2->u.l.t); + break; + } + default: { + luaK_tostack(ls, v2, 1); /* `v2' must be a value */ + luaK_code1(fs, codes[op].opcode, codes[op].arg); + } + } +} + + +static void codelineinfo (FuncState *fs) { + Proto *f = fs->f; + LexState *ls = fs->ls; + if (ls->lastline > fs->lastline) { + luaM_growvector(fs->L, f->lineinfo, f->nlineinfo, 2, int, + "line info overflow", MAX_INT); + if (ls->lastline > fs->lastline+1) + f->lineinfo[f->nlineinfo++] = -(ls->lastline - (fs->lastline+1)); + f->lineinfo[f->nlineinfo++] = fs->pc; + fs->lastline = ls->lastline; + } +} + + +int luaK_code0 (FuncState *fs, OpCode o) { + return luaK_code2(fs, o, 0, 0); +} + + +int luaK_code1 (FuncState *fs, OpCode o, int arg1) { + return luaK_code2(fs, o, arg1, 0); +} + + +int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { + Instruction i = previous_instruction(fs); + int delta = luaK_opproperties[o].push - luaK_opproperties[o].pop; + int optm = 0; /* 1 when there is an optimization */ + switch (o) { + case OP_CLOSURE: { + delta = -arg2+1; + break; + } + case OP_SETTABLE: { + delta = -arg2; + break; + } + case OP_SETLIST: { + if (arg2 == 0) return NO_JUMP; /* nothing to do */ + delta = -arg2; + break; + } + case OP_SETMAP: { + if (arg1 == 0) return NO_JUMP; /* nothing to do */ + delta = -2*arg1; + break; + } + case OP_RETURN: { + if (GET_OPCODE(i) == OP_CALL && GETARG_B(i) == MULT_RET) { + SET_OPCODE(i, OP_TAILCALL); + SETARG_B(i, arg1); + optm = 1; + } + break; + } + case OP_PUSHNIL: { + if (arg1 == 0) return NO_JUMP; /* nothing to do */ + delta = arg1; + switch(GET_OPCODE(i)) { + case OP_PUSHNIL: SETARG_U(i, GETARG_U(i)+arg1); optm = 1; break; + default: break; + } + break; + } + case OP_POP: { + if (arg1 == 0) return NO_JUMP; /* nothing to do */ + delta = -arg1; + switch(GET_OPCODE(i)) { + case OP_SETTABLE: SETARG_B(i, GETARG_B(i)+arg1); optm = 1; break; + default: break; + } + break; + } + case OP_GETTABLE: { + switch(GET_OPCODE(i)) { + case OP_PUSHSTRING: /* `t.x' */ + SET_OPCODE(i, OP_GETDOTTED); + optm = 1; + break; + case OP_GETLOCAL: /* `t[i]' */ + SET_OPCODE(i, OP_GETINDEXED); + optm = 1; + break; + default: break; + } + break; + } + case OP_ADD: { + switch(GET_OPCODE(i)) { + case OP_PUSHINT: SET_OPCODE(i, OP_ADDI); optm = 1; break; /* `a+k' */ + default: break; + } + break; + } + case OP_SUB: { + switch(GET_OPCODE(i)) { + case OP_PUSHINT: /* `a-k' */ + i = CREATE_S(OP_ADDI, -GETARG_S(i)); + optm = 1; + break; + default: break; + } + break; + } + case OP_CONCAT: { + delta = -arg1+1; + switch(GET_OPCODE(i)) { + case OP_CONCAT: /* `a..b..c' */ + SETARG_U(i, GETARG_U(i)+1); + optm = 1; + break; + default: break; + } + break; + } + case OP_MINUS: { + switch(GET_OPCODE(i)) { + case OP_PUSHINT: /* `-k' */ + SETARG_S(i, -GETARG_S(i)); + optm = 1; + break; + case OP_PUSHNUM: /* `-k' */ + SET_OPCODE(i, OP_PUSHNEGNUM); + optm = 1; + break; + default: break; + } + break; + } + case OP_JMPNE: { + if (i == CREATE_U(OP_PUSHNIL, 1)) { /* `a~=nil' */ + i = CREATE_S(OP_JMPT, NO_JUMP); + optm = 1; + } + break; + } + case OP_JMPEQ: { + if (i == CREATE_U(OP_PUSHNIL, 1)) { /* `a==nil' */ + i = CREATE_0(OP_NOT); + delta = -1; /* just undo effect of previous PUSHNIL */ + optm = 1; + } + break; + } + case OP_JMPT: + case OP_JMPONT: { + switch (GET_OPCODE(i)) { + case OP_NOT: { + i = CREATE_S(OP_JMPF, NO_JUMP); + optm = 1; + break; + } + case OP_PUSHINT: { + if (o == OP_JMPT) { /* JMPONT must keep original integer value */ + i = CREATE_S(OP_JMP, NO_JUMP); + optm = 1; + } + break; + } + case OP_PUSHNIL: { + if (GETARG_U(i) == 1) { + fs->pc--; /* erase previous instruction */ + luaK_deltastack(fs, -1); /* correct stack */ + return NO_JUMP; + } + break; + } + default: break; + } + break; + } + case OP_JMPF: + case OP_JMPONF: { + switch (GET_OPCODE(i)) { + case OP_NOT: { + i = CREATE_S(OP_JMPT, NO_JUMP); + optm = 1; + break; + } + case OP_PUSHINT: { /* `while 1 do ...' */ + fs->pc--; /* erase previous instruction */ + luaK_deltastack(fs, -1); /* correct stack */ + return NO_JUMP; + } + case OP_PUSHNIL: { /* `repeat ... until nil' */ + if (GETARG_U(i) == 1) { + i = CREATE_S(OP_JMP, NO_JUMP); + optm = 1; + } + break; + } + default: break; + } + break; + } + case OP_GETDOTTED: + case OP_GETINDEXED: + case OP_TAILCALL: + case OP_ADDI: { + LUA_INTERNALERROR("instruction used only for optimizations"); + break; + } + default: { + LUA_ASSERT(delta != VD, "invalid delta"); + break; + } + } + luaK_deltastack(fs, delta); + if (optm) { /* optimize: put instruction in place of last one */ + fs->f->code[fs->pc-1] = i; /* change previous instruction */ + return fs->pc-1; /* do not generate new instruction */ + } + /* else build new instruction */ + switch ((enum Mode)luaK_opproperties[o].mode) { + case iO: i = CREATE_0(o); break; + case iU: i = CREATE_U(o, arg1); break; + case iS: i = CREATE_S(o, arg1); break; + case iAB: i = CREATE_AB(o, arg1, arg2); break; + } + codelineinfo(fs); + /* put new instruction in code array */ + luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction, + "code size overflow", MAX_INT); + fs->f->code[fs->pc] = i; + return fs->pc++; +} + + +const struct OpProperties luaK_opproperties[NUM_OPCODES] = { + {iO, 0, 0}, /* OP_END */ + {iU, 0, 0}, /* OP_RETURN */ + {iAB, 0, 0}, /* OP_CALL */ + {iAB, 0, 0}, /* OP_TAILCALL */ + {iU, VD, 0}, /* OP_PUSHNIL */ + {iU, VD, 0}, /* OP_POP */ + {iS, 1, 0}, /* OP_PUSHINT */ + {iU, 1, 0}, /* OP_PUSHSTRING */ + {iU, 1, 0}, /* OP_PUSHNUM */ + {iU, 1, 0}, /* OP_PUSHNEGNUM */ + {iU, 1, 0}, /* OP_PUSHUPVALUE */ + {iU, 1, 0}, /* OP_GETLOCAL */ + {iU, 1, 0}, /* OP_GETGLOBAL */ + {iO, 1, 2}, /* OP_GETTABLE */ + {iU, 1, 1}, /* OP_GETDOTTED */ + {iU, 1, 1}, /* OP_GETINDEXED */ + {iU, 2, 1}, /* OP_PUSHSELF */ + {iU, 1, 0}, /* OP_CREATETABLE */ + {iU, 0, 1}, /* OP_SETLOCAL */ + {iU, 0, 1}, /* OP_SETGLOBAL */ + {iAB, VD, 0}, /* OP_SETTABLE */ + {iAB, VD, 0}, /* OP_SETLIST */ + {iU, VD, 0}, /* OP_SETMAP */ + {iO, 1, 2}, /* OP_ADD */ + {iS, 1, 1}, /* OP_ADDI */ + {iO, 1, 2}, /* OP_SUB */ + {iO, 1, 2}, /* OP_MULT */ + {iO, 1, 2}, /* OP_DIV */ + {iO, 1, 2}, /* OP_POW */ + {iU, VD, 0}, /* OP_CONCAT */ + {iO, 1, 1}, /* OP_MINUS */ + {iO, 1, 1}, /* OP_NOT */ + {iS, 0, 2}, /* OP_JMPNE */ + {iS, 0, 2}, /* OP_JMPEQ */ + {iS, 0, 2}, /* OP_JMPLT */ + {iS, 0, 2}, /* OP_JMPLE */ + {iS, 0, 2}, /* OP_JMPGT */ + {iS, 0, 2}, /* OP_JMPGE */ + {iS, 0, 1}, /* OP_JMPT */ + {iS, 0, 1}, /* OP_JMPF */ + {iS, 0, 1}, /* OP_JMPONT */ + {iS, 0, 1}, /* OP_JMPONF */ + {iS, 0, 0}, /* OP_JMP */ + {iO, 0, 0}, /* OP_PUSHNILJMP */ + {iS, 0, 0}, /* OP_FORPREP */ + {iS, 0, 3}, /* OP_FORLOOP */ + {iS, 2, 0}, /* OP_LFORPREP */ + {iS, 0, 3}, /* OP_LFORLOOP */ + {iAB, VD, 0} /* OP_CLOSURE */ +}; + diff --git a/build/premake/src/Src/Lua/lcode.h b/build/premake/src/Src/Lua/lcode.h new file mode 100644 index 0000000000..f30ba3ac11 --- /dev/null +++ b/build/premake/src/Src/Lua/lcode.h @@ -0,0 +1,70 @@ +/* +** $Id: lcode.h,v 1.1 2003/01/24 16:26:01 jason379 Exp $ +** Code generator for Lua +** See Copyright Notice in lua.h +*/ + +#ifndef lcode_h +#define lcode_h + +#include "llex.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" + + +/* +** Marks the end of a patch list. It is an invalid value both as an absolute +** address, and as a list link (would link an element to itself). +*/ +#define NO_JUMP (-1) + + +/* +** grep "ORDER OPR" if you change these enums +*/ +typedef enum BinOpr { + OPR_ADD, OPR_SUB, OPR_MULT, OPR_DIV, OPR_POW, + OPR_CONCAT, + OPR_NE, OPR_EQ, OPR_LT, OPR_LE, OPR_GT, OPR_GE, + OPR_AND, OPR_OR, + OPR_NOBINOPR +} BinOpr; + +typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_NOUNOPR } UnOpr; + + +enum Mode {iO, iU, iS, iAB}; /* instruction format */ + +#define VD 100 /* flag for variable delta */ + +extern const struct OpProperties { + char mode; + unsigned char push; + unsigned char pop; +} luaK_opproperties[]; + + +void luaK_error (LexState *ls, const char *msg); +int luaK_code0 (FuncState *fs, OpCode o); +int luaK_code1 (FuncState *fs, OpCode o, int arg1); +int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2); +int luaK_jump (FuncState *fs); +void luaK_patchlist (FuncState *fs, int list, int target); +void luaK_concat (FuncState *fs, int *l1, int l2); +void luaK_goiftrue (FuncState *fs, expdesc *v, int keepvalue); +int luaK_getlabel (FuncState *fs); +void luaK_deltastack (FuncState *fs, int delta); +void luaK_kstr (LexState *ls, int c); +void luaK_number (FuncState *fs, Number f); +void luaK_adjuststack (FuncState *fs, int n); +int luaK_lastisopen (FuncState *fs); +void luaK_setcallreturns (FuncState *fs, int nresults); +void luaK_tostack (LexState *ls, expdesc *v, int onlyone); +void luaK_storevar (LexState *ls, const expdesc *var); +void luaK_prefix (LexState *ls, UnOpr op, expdesc *v); +void luaK_infix (LexState *ls, BinOpr op, expdesc *v); +void luaK_posfix (LexState *ls, BinOpr op, expdesc *v1, expdesc *v2); + + +#endif diff --git a/build/premake/src/Src/Lua/ldebug.c b/build/premake/src/Src/Lua/ldebug.c new file mode 100644 index 0000000000..22836a4cc4 --- /dev/null +++ b/build/premake/src/Src/Lua/ldebug.c @@ -0,0 +1,466 @@ +/* +** $Id: ldebug.c,v 1.1 2003/01/24 16:26:01 jason379 Exp $ +** Debug Interface +** See Copyright Notice in lua.h +*/ + + +#include + +#include "lua.h" + +#include "lapi.h" +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "luadebug.h" + + + +static const char *getfuncname (lua_State *L, StkId f, const char **name); + + +static void setnormalized (TObject *d, const TObject *s) { + if (ttype(s) == LUA_TMARK) { + clvalue(d) = infovalue(s)->func; + ttype(d) = LUA_TFUNCTION; + } + else *d = *s; +} + + +static int isLmark (StkId o) { + return (o && ttype(o) == LUA_TMARK && !infovalue(o)->func->isC); +} + + +LUA_API lua_Hook lua_setcallhook (lua_State *L, lua_Hook func) { + lua_Hook oldhook = L->callhook; + L->callhook = func; + return oldhook; +} + + +LUA_API lua_Hook lua_setlinehook (lua_State *L, lua_Hook func) { + lua_Hook oldhook = L->linehook; + L->linehook = func; + return oldhook; +} + + +static StkId aux_stackedfunction (lua_State *L, int level, StkId top) { + int i; + for (i = (top-1) - L->stack; i>=0; i--) { + if (is_T_MARK(L->stack[i].ttype)) { + if (level == 0) + return L->stack+i; + level--; + } + } + return NULL; +} + + +LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { + StkId f = aux_stackedfunction(L, level, L->top); + if (f == NULL) return 0; /* there is no such level */ + else { + ar->_func = f; + return 1; + } +} + + +static int nups (StkId f) { + switch (ttype(f)) { + case LUA_TFUNCTION: + return clvalue(f)->nupvalues; + case LUA_TMARK: + return infovalue(f)->func->nupvalues; + default: + return 0; + } +} + + +int luaG_getline (int *lineinfo, int pc, int refline, int *prefi) { + int refi; + if (lineinfo == NULL || pc == -1) + return -1; /* no line info or function is not active */ + refi = prefi ? *prefi : 0; + if (lineinfo[refi] < 0) + refline += -lineinfo[refi++]; + LUA_ASSERT(lineinfo[refi] >= 0, "invalid line info"); + while (lineinfo[refi] > pc) { + refline--; + refi--; + if (lineinfo[refi] < 0) + refline -= -lineinfo[refi--]; + LUA_ASSERT(lineinfo[refi] >= 0, "invalid line info"); + } + for (;;) { + int nextline = refline + 1; + int nextref = refi + 1; + if (lineinfo[nextref] < 0) + nextline += -lineinfo[nextref++]; + LUA_ASSERT(lineinfo[nextref] >= 0, "invalid line info"); + if (lineinfo[nextref] > pc) + break; + refline = nextline; + refi = nextref; + } + if (prefi) *prefi = refi; + return refline; +} + + +static int currentpc (StkId f) { + CallInfo *ci = infovalue(f); + LUA_ASSERT(isLmark(f), "function has no pc"); + if (ci->pc) + return (*ci->pc - ci->func->f.l->code) - 1; + else + return -1; /* function is not active */ +} + + +static int currentline (StkId f) { + if (!isLmark(f)) + return -1; /* only active lua functions have current-line information */ + else { + CallInfo *ci = infovalue(f); + int *lineinfo = ci->func->f.l->lineinfo; + return luaG_getline(lineinfo, currentpc(f), 1, NULL); + } +} + + + +static Proto *getluaproto (StkId f) { + return (isLmark(f) ? infovalue(f)->func->f.l : NULL); +} + + +LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { + const char *name; + StkId f = ar->_func; + Proto *fp = getluaproto(f); + if (!fp) return NULL; /* `f' is not a Lua function? */ + name = luaF_getlocalname(fp, n, currentpc(f)); + if (!name) return NULL; + luaA_pushobject(L, (f+1)+(n-1)); /* push value */ + return name; +} + + +LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { + const char *name; + StkId f = ar->_func; + Proto *fp = getluaproto(f); + L->top--; /* pop new value */ + if (!fp) return NULL; /* `f' is not a Lua function? */ + name = luaF_getlocalname(fp, n, currentpc(f)); + if (!name || name[0] == '(') return NULL; /* `(' starts private locals */ + *((f+1)+(n-1)) = *L->top; + return name; +} + + +static void infoLproto (lua_Debug *ar, Proto *f) { + ar->source = f->source->str; + ar->linedefined = f->lineDefined; + ar->what = "Lua"; +} + + +static void funcinfo (lua_State *L, lua_Debug *ar, StkId func) { + Closure *cl = NULL; + switch (ttype(func)) { + case LUA_TFUNCTION: + cl = clvalue(func); + break; + case LUA_TMARK: + cl = infovalue(func)->func; + break; + default: + lua_error(L, "value for `lua_getinfo' is not a function"); + } + if (cl->isC) { + ar->source = "=C"; + ar->linedefined = -1; + ar->what = "C"; + } + else + infoLproto(ar, cl->f.l); + luaO_chunkid(ar->short_src, ar->source, sizeof(ar->short_src)); + if (ar->linedefined == 0) + ar->what = "main"; +} + + +static const char *travtagmethods (lua_State *L, const TObject *o) { + if (ttype(o) == LUA_TFUNCTION) { + int e; + for (e=0; elast_tag; t++) + if (clvalue(o) == luaT_gettm(L, t, e)) + return luaT_eventname[e]; + } + } + return NULL; +} + + +static const char *travglobals (lua_State *L, const TObject *o) { + Hash *g = L->gt; + int i; + for (i=0; isize; i++) { + if (luaO_equalObj(o, val(node(g, i))) && + ttype(key(node(g, i))) == LUA_TSTRING) + return tsvalue(key(node(g, i)))->str; + } + return NULL; +} + + +static void getname (lua_State *L, StkId f, lua_Debug *ar) { + TObject o; + setnormalized(&o, f); + /* try to find a name for given function */ + if ((ar->name = travglobals(L, &o)) != NULL) + ar->namewhat = "global"; + /* not found: try tag methods */ + else if ((ar->name = travtagmethods(L, &o)) != NULL) + ar->namewhat = "tag-method"; + else ar->namewhat = ""; /* not found at all */ +} + + +LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { + StkId func; + int isactive = (*what != '>'); + if (isactive) + func = ar->_func; + else { + what++; /* skip the '>' */ + func = L->top - 1; + } + for (; *what; what++) { + switch (*what) { + case 'S': { + funcinfo(L, ar, func); + break; + } + case 'l': { + ar->currentline = currentline(func); + break; + } + case 'u': { + ar->nups = nups(func); + break; + } + case 'n': { + ar->namewhat = (isactive) ? getfuncname(L, func, &ar->name) : NULL; + if (ar->namewhat == NULL) + getname(L, func, ar); + break; + } + case 'f': { + setnormalized(L->top, func); + incr_top; /* push function */ + break; + } + default: return 0; /* invalid option */ + } + } + if (!isactive) L->top--; /* pop function */ + return 1; +} + + +/* +** {====================================================== +** Symbolic Execution +** ======================================================= +*/ + + +static int pushpc (int *stack, int pc, int top, int n) { + while (n--) + stack[top++] = pc-1; + return top; +} + + +static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos) { + int stack[MAXSTACK]; /* stores last instruction that changed a stack entry */ + const Instruction *code = pt->code; + int top = pt->numparams; + int pc = 0; + if (pt->is_vararg) /* varargs? */ + top++; /* `arg' */ + while (pc < lastpc) { + const Instruction i = code[pc++]; + LUA_ASSERT(0 <= top && top <= pt->maxstacksize, "wrong stack"); + switch (GET_OPCODE(i)) { + case OP_RETURN: { + LUA_ASSERT(top >= GETARG_U(i), "wrong stack"); + top = GETARG_U(i); + break; + } + case OP_TAILCALL: { + LUA_ASSERT(top >= GETARG_A(i), "wrong stack"); + top = GETARG_B(i); + break; + } + case OP_CALL: { + int nresults = GETARG_B(i); + if (nresults == MULT_RET) nresults = 1; + LUA_ASSERT(top >= GETARG_A(i), "wrong stack"); + top = pushpc(stack, pc, GETARG_A(i), nresults); + break; + } + case OP_PUSHNIL: { + top = pushpc(stack, pc, top, GETARG_U(i)); + break; + } + case OP_POP: { + top -= GETARG_U(i); + break; + } + case OP_SETTABLE: + case OP_SETLIST: { + top -= GETARG_B(i); + break; + } + case OP_SETMAP: { + top -= 2*GETARG_U(i); + break; + } + case OP_CONCAT: { + top -= GETARG_U(i); + stack[top++] = pc-1; + break; + } + case OP_CLOSURE: { + top -= GETARG_B(i); + stack[top++] = pc-1; + break; + } + case OP_JMPONT: + case OP_JMPONF: { + int newpc = pc + GETARG_S(i); + /* jump is forward and do not skip `lastpc'? */ + if (pc < newpc && newpc <= lastpc) { + stack[top-1] = pc-1; /* value comes from `and'/`or' */ + pc = newpc; /* do the jump */ + } + else + top--; /* do not jump; pop value */ + break; + } + default: { + OpCode op = GET_OPCODE(i); + LUA_ASSERT(luaK_opproperties[op].push != VD, + "invalid opcode for default"); + top -= luaK_opproperties[op].pop; + LUA_ASSERT(top >= 0, "wrong stack"); + top = pushpc(stack, pc, top, luaK_opproperties[op].push); + } + } + } + return code[stack[stackpos]]; +} + + +static const char *getobjname (lua_State *L, StkId obj, const char **name) { + StkId func = aux_stackedfunction(L, 0, obj); + if (!isLmark(func)) + return NULL; /* not an active Lua function */ + else { + Proto *p = infovalue(func)->func->f.l; + int pc = currentpc(func); + int stackpos = obj - (func+1); /* func+1 == function base */ + Instruction i = luaG_symbexec(p, pc, stackpos); + LUA_ASSERT(pc != -1, "function must be active"); + switch (GET_OPCODE(i)) { + case OP_GETGLOBAL: { + *name = p->kstr[GETARG_U(i)]->str; + return "global"; + } + case OP_GETLOCAL: { + *name = luaF_getlocalname(p, GETARG_U(i)+1, pc); + LUA_ASSERT(*name, "local must exist"); + return "local"; + } + case OP_PUSHSELF: + case OP_GETDOTTED: { + *name = p->kstr[GETARG_U(i)]->str; + return "field"; + } + default: + return NULL; /* no useful name found */ + } + } +} + + +static const char *getfuncname (lua_State *L, StkId f, const char **name) { + StkId func = aux_stackedfunction(L, 0, f); /* calling function */ + if (!isLmark(func)) + return NULL; /* not an active Lua function */ + else { + Proto *p = infovalue(func)->func->f.l; + int pc = currentpc(func); + Instruction i; + if (pc == -1) return NULL; /* function is not activated */ + i = p->code[pc]; + switch (GET_OPCODE(i)) { + case OP_CALL: case OP_TAILCALL: + return getobjname(L, (func+1)+GETARG_A(i), name); + default: + return NULL; /* no useful name found */ + } + } +} + + +/* }====================================================== */ + + +void luaG_typeerror (lua_State *L, StkId o, const char *op) { + const char *name; + const char *kind = getobjname(L, o, &name); + const char *t = luaO_typename(o); + if (kind) + luaO_verror(L, "attempt to %.30s %.20s `%.40s' (a %.10s value)", + op, kind, name, t); + else + luaO_verror(L, "attempt to %.30s a %.10s value", op, t); +} + + +void luaG_binerror (lua_State *L, StkId p1, int t, const char *op) { + if (ttype(p1) == t) p1++; + LUA_ASSERT(ttype(p1) != t, "must be an error"); + luaG_typeerror(L, p1, op); +} + + +void luaG_ordererror (lua_State *L, StkId top) { + const char *t1 = luaO_typename(top-2); + const char *t2 = luaO_typename(top-1); + if (t1[2] == t2[2]) + luaO_verror(L, "attempt to compare two %.10s values", t1); + else + luaO_verror(L, "attempt to compare %.10s with %.10s", t1, t2); +} + diff --git a/build/premake/src/Src/Lua/ldebug.h b/build/premake/src/Src/Lua/ldebug.h new file mode 100644 index 0000000000..90db8a1745 --- /dev/null +++ b/build/premake/src/Src/Lua/ldebug.h @@ -0,0 +1,21 @@ +/* +** $Id: ldebug.h,v 1.1 2003/01/24 16:26:01 jason379 Exp $ +** Auxiliary functions from Debug Interface module +** See Copyright Notice in lua.h +*/ + +#ifndef ldebug_h +#define ldebug_h + + +#include "lstate.h" +#include "luadebug.h" + + +void luaG_typeerror (lua_State *L, StkId o, const char *op); +void luaG_binerror (lua_State *L, StkId p1, int t, const char *op); +int luaG_getline (int *lineinfo, int pc, int refline, int *refi); +void luaG_ordererror (lua_State *L, StkId top); + + +#endif diff --git a/build/premake/src/Src/Lua/ldo.c b/build/premake/src/Src/Lua/ldo.c new file mode 100644 index 0000000000..a37f988a8c --- /dev/null +++ b/build/premake/src/Src/Lua/ldo.c @@ -0,0 +1,388 @@ +/* +** $Id: ldo.c,v 1.1 2003/01/24 16:26:02 jason379 Exp $ +** Stack and Call structure of Lua +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lundump.h" +#include "lvm.h" +#include "lzio.h" + + +/* space to handle stack overflow errors */ +#define EXTRA_STACK (2*LUA_MINSTACK) + + +void luaD_init (lua_State *L, int stacksize) { + L->stack = luaM_newvector(L, stacksize+EXTRA_STACK, TObject); + L->nblocks += stacksize*sizeof(TObject); + L->stack_last = L->stack+(stacksize-1); + L->stacksize = stacksize; + L->Cbase = L->top = L->stack; +} + + +void luaD_checkstack (lua_State *L, int n) { + if (L->stack_last - L->top <= n) { /* stack overflow? */ + if (L->stack_last-L->stack > (L->stacksize-1)) { + /* overflow while handling overflow */ + luaD_breakrun(L, LUA_ERRERR); /* break run without error message */ + } + else { + L->stack_last += EXTRA_STACK; /* to be used by error message */ + lua_error(L, "stack overflow"); + } + } +} + + +static void restore_stack_limit (lua_State *L) { + if (L->top - L->stack < L->stacksize - 1) + L->stack_last = L->stack + (L->stacksize-1); +} + + +/* +** Adjust stack. Set top to base+extra, pushing NILs if needed. +** (we cannot add base+extra unless we are sure it fits in the stack; +** otherwise the result of such operation on pointers is undefined) +*/ +void luaD_adjusttop (lua_State *L, StkId base, int extra) { + int diff = extra-(L->top-base); + if (diff <= 0) + L->top = base+extra; + else { + luaD_checkstack(L, diff); + while (diff--) + ttype(L->top++) = LUA_TNIL; + } +} + + +/* +** Open a hole inside the stack at `pos' +*/ +static void luaD_openstack (lua_State *L, StkId pos) { + int i = L->top-pos; + while (i--) pos[i+1] = pos[i]; + incr_top; +} + + +static void dohook (lua_State *L, lua_Debug *ar, lua_Hook hook) { + StkId old_Cbase = L->Cbase; + StkId old_top = L->Cbase = L->top; + luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ + L->allowhooks = 0; /* cannot call hooks inside a hook */ + (*hook)(L, ar); + LUA_ASSERT(L->allowhooks == 0, "invalid allow"); + L->allowhooks = 1; + L->top = old_top; + L->Cbase = old_Cbase; +} + + +void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook) { + if (L->allowhooks) { + lua_Debug ar; + ar._func = func; + ar.event = "line"; + ar.currentline = line; + dohook(L, &ar, linehook); + } +} + + +static void luaD_callHook (lua_State *L, StkId func, lua_Hook callhook, + const char *event) { + if (L->allowhooks) { + lua_Debug ar; + ar._func = func; + ar.event = event; + infovalue(func)->pc = NULL; /* function is not active */ + dohook(L, &ar, callhook); + } +} + + +static StkId callCclosure (lua_State *L, const struct Closure *cl, StkId base) { + int nup = cl->nupvalues; /* number of upvalues */ + StkId old_Cbase = L->Cbase; + int n; + L->Cbase = base; /* new base for C function */ + luaD_checkstack(L, nup+LUA_MINSTACK); /* ensure minimum stack size */ + for (n=0; ntop++) = cl->upvalue[n]; + n = (*cl->f.c)(L); /* do the actual call */ + L->Cbase = old_Cbase; /* restore old C base */ + return L->top - n; /* return index of first result */ +} + + +void luaD_callTM (lua_State *L, Closure *f, int nParams, int nResults) { + StkId base = L->top - nParams; + luaD_openstack(L, base); + clvalue(base) = f; + ttype(base) = LUA_TFUNCTION; + luaD_call(L, base, nResults); +} + + +/* +** Call a function (C or Lua). The function to be called is at *func. +** The arguments are on the stack, right after the function. +** When returns, the results are on the stack, starting at the original +** function position. +** The number of results is nResults, unless nResults=LUA_MULTRET. +*/ +void luaD_call (lua_State *L, StkId func, int nResults) { + lua_Hook callhook; + StkId firstResult; + CallInfo ci; + Closure *cl; + if (ttype(func) != LUA_TFUNCTION) { + /* `func' is not a function; check the `function' tag method */ + Closure *tm = luaT_gettmbyObj(L, func, TM_FUNCTION); + if (tm == NULL) + luaG_typeerror(L, func, "call"); + luaD_openstack(L, func); + clvalue(func) = tm; /* tag method is the new function to be called */ + ttype(func) = LUA_TFUNCTION; + } + cl = clvalue(func); + ci.func = cl; + infovalue(func) = &ci; + ttype(func) = LUA_TMARK; + callhook = L->callhook; + if (callhook) + luaD_callHook(L, func, callhook, "call"); + firstResult = (cl->isC ? callCclosure(L, cl, func+1) : + luaV_execute(L, cl, func+1)); + if (callhook) /* same hook that was active at entry */ + luaD_callHook(L, func, callhook, "return"); + LUA_ASSERT(ttype(func) == LUA_TMARK, "invalid tag"); + /* move results to `func' (to erase parameters and function) */ + if (nResults == LUA_MULTRET) { + while (firstResult < L->top) /* copy all results */ + *func++ = *firstResult++; + L->top = func; + } + else { /* copy at most `nResults' */ + for (; nResults > 0 && firstResult < L->top; nResults--) + *func++ = *firstResult++; + L->top = func; + for (; nResults > 0; nResults--) { /* if there are not enough results */ + ttype(L->top) = LUA_TNIL; /* adjust the stack */ + incr_top; /* must check stack space */ + } + } + luaC_checkGC(L); +} + + +/* +** Execute a protected call. +*/ +struct CallS { /* data to `f_call' */ + StkId func; + int nresults; +}; + +static void f_call (lua_State *L, void *ud) { + struct CallS *c = (struct CallS *)ud; + luaD_call(L, c->func, c->nresults); +} + + +LUA_API int lua_call (lua_State *L, int nargs, int nresults) { + StkId func = L->top - (nargs+1); /* function to be called */ + struct CallS c; + int status; + c.func = func; c.nresults = nresults; + status = luaD_runprotected(L, f_call, &c); + if (status != 0) /* an error occurred? */ + L->top = func; /* remove parameters from the stack */ + return status; +} + + +/* +** Execute a protected parser. +*/ +struct ParserS { /* data to `f_parser' */ + ZIO *z; + int bin; +}; + +static void f_parser (lua_State *L, void *ud) { + struct ParserS *p = (struct ParserS *)ud; + Proto *tf = p->bin ? luaU_undump(L, p->z) : luaY_parser(L, p->z); + luaV_Lclosure(L, tf, 0); +} + + +static int protectedparser (lua_State *L, ZIO *z, int bin) { + struct ParserS p; + unsigned long old_blocks; + int status; + p.z = z; p.bin = bin; + /* before parsing, give a (good) chance to GC */ + if (L->nblocks/8 >= L->GCthreshold/10) + luaC_collectgarbage(L); + old_blocks = L->nblocks; + status = luaD_runprotected(L, f_parser, &p); + if (status == 0) { + /* add new memory to threshold (as it probably will stay) */ + L->GCthreshold += (L->nblocks - old_blocks); + } + else if (status == LUA_ERRRUN) /* an error occurred: correct error code */ + status = LUA_ERRSYNTAX; + return status; +} + + +static int parse_file (lua_State *L, const char *filename) { + ZIO z; + int status; + int bin; /* flag for file mode */ + int c; /* look ahead char */ + FILE *f = (filename == NULL) ? stdin : fopen(filename, "r"); + if (f == NULL) return LUA_ERRFILE; /* unable to open file */ + c = fgetc(f); + ungetc(c, f); + bin = (c == ID_CHUNK); + if (bin && f != stdin) { + f = freopen(filename, "rb", f); /* set binary mode */ + if (f == NULL) return LUA_ERRFILE; /* unable to reopen file */ + } + lua_pushstring(L, "@"); + lua_pushstring(L, (filename == NULL) ? "(stdin)" : filename); + lua_concat(L, 2); + c = lua_gettop(L); + filename = lua_tostring(L, c); /* filename = '@'..filename */ + luaZ_Fopen(&z, f, filename); + status = protectedparser(L, &z, bin); + lua_remove(L, c); /* remove `filename' from the stack */ + if (f != stdin) + fclose(f); + return status; +} + + +LUA_API int lua_dofile (lua_State *L, const char *filename) { + int status = parse_file(L, filename); + if (status == 0) /* parse OK? */ + status = lua_call(L, 0, LUA_MULTRET); /* call main */ + return status; +} + + +static int parse_buffer (lua_State *L, const char *buff, size_t size, + const char *name) { + ZIO z; + if (!name) name = "?"; + luaZ_mopen(&z, buff, size, name); + return protectedparser(L, &z, buff[0]==ID_CHUNK); +} + + +LUA_API int lua_dobuffer (lua_State *L, const char *buff, size_t size, const char *name) { + int status = parse_buffer(L, buff, size, name); + if (status == 0) /* parse OK? */ + status = lua_call(L, 0, LUA_MULTRET); /* call main */ + return status; +} + + +LUA_API int lua_dostring (lua_State *L, const char *str) { + return lua_dobuffer(L, str, strlen(str), str); +} + + +/* +** {====================================================== +** Error-recover functions (based on long jumps) +** ======================================================= +*/ + +/* chain list of long jump buffers */ +struct lua_longjmp { + jmp_buf b; + struct lua_longjmp *previous; + volatile int status; /* error code */ +}; + + +static void message (lua_State *L, const char *s) { + const TObject *em = luaH_getglobal(L, LUA_ERRORMESSAGE); + if (ttype(em) == LUA_TFUNCTION) { + *L->top = *em; + incr_top; + lua_pushstring(L, s); + luaD_call(L, L->top-2, 0); + } +} + + +/* +** Reports an error, and jumps up to the available recovery label +*/ +LUA_API void lua_error (lua_State *L, const char *s) { + if (s) message(L, s); + luaD_breakrun(L, LUA_ERRRUN); +} + + +void luaD_breakrun (lua_State *L, int errcode) { + if (L->errorJmp) { + L->errorJmp->status = errcode; + longjmp(L->errorJmp->b, 1); + } + else { + if (errcode != LUA_ERRMEM) + message(L, "unable to recover; exiting\n"); + exit(EXIT_FAILURE); + } +} + + +int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud) { + StkId oldCbase = L->Cbase; + StkId oldtop = L->top; + struct lua_longjmp lj; + int allowhooks = L->allowhooks; + lj.status = 0; + lj.previous = L->errorJmp; /* chain new error handler */ + L->errorJmp = &lj; + if (setjmp(lj.b) == 0) + (*f)(L, ud); + else { /* an error occurred: restore the state */ + L->allowhooks = allowhooks; + L->Cbase = oldCbase; + L->top = oldtop; + restore_stack_limit(L); + } + L->errorJmp = lj.previous; /* restore old error handler */ + return lj.status; +} + +/* }====================================================== */ + diff --git a/build/premake/src/Src/Lua/ldo.h b/build/premake/src/Src/Lua/ldo.h new file mode 100644 index 0000000000..ef1c4db099 --- /dev/null +++ b/build/premake/src/Src/Lua/ldo.h @@ -0,0 +1,33 @@ +/* +** $Id: ldo.h,v 1.1 2003/01/24 16:26:03 jason379 Exp $ +** Stack and Call structure of Lua +** See Copyright Notice in lua.h +*/ + +#ifndef ldo_h +#define ldo_h + + +#include "lobject.h" +#include "lstate.h" + + +/* +** macro to increment stack top. +** There must be always an empty slot at the L->stack.top +*/ +#define incr_top {if (L->top == L->stack_last) luaD_checkstack(L, 1); L->top++;} + + +void luaD_init (lua_State *L, int stacksize); +void luaD_adjusttop (lua_State *L, StkId base, int extra); +void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook); +void luaD_call (lua_State *L, StkId func, int nResults); +void luaD_callTM (lua_State *L, Closure *f, int nParams, int nResults); +void luaD_checkstack (lua_State *L, int n); + +void luaD_breakrun (lua_State *L, int errcode); +int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud); + + +#endif diff --git a/build/premake/src/Src/Lua/lfunc.c b/build/premake/src/Src/Lua/lfunc.c new file mode 100644 index 0000000000..a73759503a --- /dev/null +++ b/build/premake/src/Src/Lua/lfunc.c @@ -0,0 +1,109 @@ +/* +** $Id: lfunc.c,v 1.1 2003/01/24 16:26:03 jason379 Exp $ +** Auxiliary functions to manipulate prototypes and closures +** See Copyright Notice in lua.h +*/ + + +#include + +#include "lua.h" + +#include "lfunc.h" +#include "lmem.h" +#include "lstate.h" + + +#define sizeclosure(n) ((int)sizeof(Closure) + (int)sizeof(TObject)*((n)-1)) + + +Closure *luaF_newclosure (lua_State *L, int nelems) { + int size = sizeclosure(nelems); + Closure *c = (Closure *)luaM_malloc(L, size); + c->next = L->rootcl; + L->rootcl = c; + c->mark = c; + c->nupvalues = nelems; + L->nblocks += size; + return c; +} + + +Proto *luaF_newproto (lua_State *L) { + Proto *f = luaM_new(L, Proto); + f->knum = NULL; + f->nknum = 0; + f->kstr = NULL; + f->nkstr = 0; + f->kproto = NULL; + f->nkproto = 0; + f->code = NULL; + f->ncode = 0; + f->numparams = 0; + f->is_vararg = 0; + f->maxstacksize = 0; + f->marked = 0; + f->lineinfo = NULL; + f->nlineinfo = 0; + f->nlocvars = 0; + f->locvars = NULL; + f->lineDefined = 0; + f->source = NULL; + f->next = L->rootproto; /* chain in list of protos */ + L->rootproto = f; + return f; +} + + +static size_t protosize (Proto *f) { + return sizeof(Proto) + + f->nknum*sizeof(Number) + + f->nkstr*sizeof(TString *) + + f->nkproto*sizeof(Proto *) + + f->ncode*sizeof(Instruction) + + f->nlocvars*sizeof(struct LocVar) + + f->nlineinfo*sizeof(int); +} + + +void luaF_protook (lua_State *L, Proto *f, int pc) { + f->ncode = pc; /* signal that proto was properly created */ + L->nblocks += protosize(f); +} + + +void luaF_freeproto (lua_State *L, Proto *f) { + if (f->ncode > 0) /* function was properly created? */ + L->nblocks -= protosize(f); + luaM_free(L, f->code); + luaM_free(L, f->locvars); + luaM_free(L, f->kstr); + luaM_free(L, f->knum); + luaM_free(L, f->kproto); + luaM_free(L, f->lineinfo); + luaM_free(L, f); +} + + +void luaF_freeclosure (lua_State *L, Closure *c) { + L->nblocks -= sizeclosure(c->nupvalues); + luaM_free(L, c); +} + + +/* +** Look for n-th local variable at line `line' in function `func'. +** Returns NULL if not found. +*/ +const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { + int i; + for (i = 0; inlocvars && f->locvars[i].startpc <= pc; i++) { + if (pc < f->locvars[i].endpc) { /* is variable active? */ + local_number--; + if (local_number == 0) + return f->locvars[i].varname->str; + } + } + return NULL; /* not found */ +} + diff --git a/build/premake/src/Src/Lua/lfunc.h b/build/premake/src/Src/Lua/lfunc.h new file mode 100644 index 0000000000..3b68b7bb3c --- /dev/null +++ b/build/premake/src/Src/Lua/lfunc.h @@ -0,0 +1,24 @@ +/* +** $Id: lfunc.h,v 1.1 2003/01/24 16:26:04 jason379 Exp $ +** Auxiliary functions to manipulate prototypes and closures +** See Copyright Notice in lua.h +*/ + +#ifndef lfunc_h +#define lfunc_h + + +#include "lobject.h" + + + +Proto *luaF_newproto (lua_State *L); +void luaF_protook (lua_State *L, Proto *f, int pc); +Closure *luaF_newclosure (lua_State *L, int nelems); +void luaF_freeproto (lua_State *L, Proto *f); +void luaF_freeclosure (lua_State *L, Closure *c); + +const char *luaF_getlocalname (const Proto *func, int local_number, int pc); + + +#endif diff --git a/build/premake/src/Src/Lua/lgc.c b/build/premake/src/Src/Lua/lgc.c new file mode 100644 index 0000000000..e556fe30b7 --- /dev/null +++ b/build/premake/src/Src/Lua/lgc.c @@ -0,0 +1,353 @@ +/* +** $Id: lgc.c,v 1.1 2003/01/24 16:26:05 jason379 Exp $ +** Garbage Collector +** See Copyright Notice in lua.h +*/ + +#include "lua.h" + +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" + + +typedef struct GCState { + Hash *tmark; /* list of marked tables to be visited */ + Closure *cmark; /* list of marked closures to be visited */ +} GCState; + + + +static void markobject (GCState *st, TObject *o); + + +/* mark a string; marks larger than 1 cannot be changed */ +#define strmark(s) {if ((s)->marked == 0) (s)->marked = 1;} + + + +static void protomark (Proto *f) { + if (!f->marked) { + int i; + f->marked = 1; + strmark(f->source); + for (i=0; inkstr; i++) + strmark(f->kstr[i]); + for (i=0; inkproto; i++) + protomark(f->kproto[i]); + for (i=0; inlocvars; i++) /* mark local-variable names */ + strmark(f->locvars[i].varname); + } +} + + +static void markstack (lua_State *L, GCState *st) { + StkId o; + for (o=L->stack; otop; o++) + markobject(st, o); +} + + +static void marklock (lua_State *L, GCState *st) { + int i; + for (i=0; irefSize; i++) { + if (L->refArray[i].st == LOCK) + markobject(st, &L->refArray[i].o); + } +} + + +static void markclosure (GCState *st, Closure *cl) { + if (!ismarked(cl)) { + if (!cl->isC) + protomark(cl->f.l); + cl->mark = st->cmark; /* chain it for later traversal */ + st->cmark = cl; + } +} + + +static void marktagmethods (lua_State *L, GCState *st) { + int e; + for (e=0; elast_tag; t++) { + Closure *cl = luaT_gettm(L, t, e); + if (cl) markclosure(st, cl); + } + } +} + + +static void markobject (GCState *st, TObject *o) { + switch (ttype(o)) { + case LUA_TUSERDATA: case LUA_TSTRING: + strmark(tsvalue(o)); + break; + case LUA_TMARK: + markclosure(st, infovalue(o)->func); + break; + case LUA_TFUNCTION: + markclosure(st, clvalue(o)); + break; + case LUA_TTABLE: { + if (!ismarked(hvalue(o))) { + hvalue(o)->mark = st->tmark; /* chain it in list of marked */ + st->tmark = hvalue(o); + } + break; + } + default: break; /* numbers, etc */ + } +} + + +static void markall (lua_State *L) { + GCState st; + st.cmark = NULL; + st.tmark = L->gt; /* put table of globals in mark list */ + L->gt->mark = NULL; + marktagmethods(L, &st); /* mark tag methods */ + markstack(L, &st); /* mark stack objects */ + marklock(L, &st); /* mark locked objects */ + for (;;) { /* mark tables and closures */ + if (st.cmark) { + int i; + Closure *f = st.cmark; /* get first closure from list */ + st.cmark = f->mark; /* remove it from list */ + for (i=0; inupvalues; i++) /* mark its upvalues */ + markobject(&st, &f->upvalue[i]); + } + else if (st.tmark) { + int i; + Hash *h = st.tmark; /* get first table from list */ + st.tmark = h->mark; /* remove it from list */ + for (i=0; isize; i++) { + Node *n = node(h, i); + if (ttype(key(n)) != LUA_TNIL) { + if (ttype(val(n)) == LUA_TNIL) + luaH_remove(h, key(n)); /* dead element; try to remove it */ + markobject(&st, &n->key); + markobject(&st, &n->val); + } + } + } + else break; /* nothing else to mark */ + } +} + + +static int hasmark (const TObject *o) { + /* valid only for locked objects */ + switch (o->ttype) { + case LUA_TSTRING: case LUA_TUSERDATA: + return tsvalue(o)->marked; + case LUA_TTABLE: + return ismarked(hvalue(o)); + case LUA_TFUNCTION: + return ismarked(clvalue(o)); + default: /* number */ + return 1; + } +} + + +/* macro for internal debugging; check if a link of free refs is valid */ +#define VALIDLINK(L, st,n) (NONEXT <= (st) && (st) < (n)) + +static void invalidaterefs (lua_State *L) { + int n = L->refSize; + int i; + for (i=0; irefArray[i]; + if (r->st == HOLD && !hasmark(&r->o)) + r->st = COLLECTED; + LUA_ASSERT((r->st == LOCK && hasmark(&r->o)) || + (r->st == HOLD && hasmark(&r->o)) || + r->st == COLLECTED || + r->st == NONEXT || + (r->st < n && VALIDLINK(L, L->refArray[r->st].st, n)), + "inconsistent ref table"); + } + LUA_ASSERT(VALIDLINK(L, L->refFree, n), "inconsistent ref table"); +} + + + +static void collectproto (lua_State *L) { + Proto **p = &L->rootproto; + Proto *next; + while ((next = *p) != NULL) { + if (next->marked) { + next->marked = 0; + p = &next->next; + } + else { + *p = next->next; + luaF_freeproto(L, next); + } + } +} + + +static void collectclosure (lua_State *L) { + Closure **p = &L->rootcl; + Closure *next; + while ((next = *p) != NULL) { + if (ismarked(next)) { + next->mark = next; /* unmark */ + p = &next->next; + } + else { + *p = next->next; + luaF_freeclosure(L, next); + } + } +} + + +static void collecttable (lua_State *L) { + Hash **p = &L->roottable; + Hash *next; + while ((next = *p) != NULL) { + if (ismarked(next)) { + next->mark = next; /* unmark */ + p = &next->next; + } + else { + *p = next->next; + luaH_free(L, next); + } + } +} + + +static void checktab (lua_State *L, stringtable *tb) { + if (tb->nuse < (lint32)(tb->size/4) && tb->size > 10) + luaS_resize(L, tb, tb->size/2); /* table is too big */ +} + + +static void collectstrings (lua_State *L, int all) { + int i; + for (i=0; istrt.size; i++) { /* for each list */ + TString **p = &L->strt.hash[i]; + TString *next; + while ((next = *p) != NULL) { + if (next->marked && !all) { /* preserve? */ + if (next->marked < FIXMARK) /* does not change FIXMARKs */ + next->marked = 0; + p = &next->nexthash; + } + else { /* collect */ + *p = next->nexthash; + L->strt.nuse--; + L->nblocks -= sizestring(next->len); + luaM_free(L, next); + } + } + } + checktab(L, &L->strt); +} + + +static void collectudata (lua_State *L, int all) { + int i; + for (i=0; iudt.size; i++) { /* for each list */ + TString **p = &L->udt.hash[i]; + TString *next; + while ((next = *p) != NULL) { + LUA_ASSERT(next->marked <= 1, "udata cannot be fixed"); + if (next->marked && !all) { /* preserve? */ + next->marked = 0; + p = &next->nexthash; + } + else { /* collect */ + int tag = next->u.d.tag; + *p = next->nexthash; + next->nexthash = L->TMtable[tag].collected; /* chain udata */ + L->TMtable[tag].collected = next; + L->nblocks -= sizestring(next->len); + L->udt.nuse--; + } + } + } + checktab(L, &L->udt); +} + + +#define MINBUFFER 256 +static void checkMbuffer (lua_State *L) { + if (L->Mbuffsize > MINBUFFER*2) { /* is buffer too big? */ + size_t newsize = L->Mbuffsize/2; /* still larger than MINBUFFER */ + L->nblocks += (newsize - L->Mbuffsize)*sizeof(char); + L->Mbuffsize = newsize; + luaM_reallocvector(L, L->Mbuffer, newsize, char); + } +} + + +static void callgcTM (lua_State *L, const TObject *o) { + Closure *tm = luaT_gettmbyObj(L, o, TM_GC); + if (tm != NULL) { + int oldah = L->allowhooks; + L->allowhooks = 0; /* stop debug hooks during GC tag methods */ + luaD_checkstack(L, 2); + clvalue(L->top) = tm; + ttype(L->top) = LUA_TFUNCTION; + *(L->top+1) = *o; + L->top += 2; + luaD_call(L, L->top-2, 0); + L->allowhooks = oldah; /* restore hooks */ + } +} + + +static void callgcTMudata (lua_State *L) { + int tag; + TObject o; + ttype(&o) = LUA_TUSERDATA; + L->GCthreshold = 2*L->nblocks; /* avoid GC during tag methods */ + for (tag=L->last_tag; tag>=0; tag--) { /* for each tag (in reverse order) */ + TString *udata; + while ((udata = L->TMtable[tag].collected) != NULL) { + L->TMtable[tag].collected = udata->nexthash; /* remove it from list */ + tsvalue(&o) = udata; + callgcTM(L, &o); + luaM_free(L, udata); + } + } +} + + +void luaC_collect (lua_State *L, int all) { + collectudata(L, all); + callgcTMudata(L); + collectstrings(L, all); + collecttable(L); + collectproto(L); + collectclosure(L); +} + + +void luaC_collectgarbage (lua_State *L) { + markall(L); + invalidaterefs(L); /* check unlocked references */ + luaC_collect(L, 0); + checkMbuffer(L); + L->GCthreshold = 2*L->nblocks; /* set new threshold */ + callgcTM(L, &luaO_nilobject); +} + + +void luaC_checkGC (lua_State *L) { + if (L->nblocks >= L->GCthreshold) + luaC_collectgarbage(L); +} + diff --git a/build/premake/src/Src/Lua/lgc.h b/build/premake/src/Src/Lua/lgc.h new file mode 100644 index 0000000000..58d94ce5da --- /dev/null +++ b/build/premake/src/Src/Lua/lgc.h @@ -0,0 +1,19 @@ +/* +** $Id: lgc.h,v 1.1 2003/01/24 16:26:06 jason379 Exp $ +** Garbage Collector +** See Copyright Notice in lua.h +*/ + +#ifndef lgc_h +#define lgc_h + + +#include "lobject.h" + + +void luaC_collect (lua_State *L, int all); +void luaC_collectgarbage (lua_State *L); +void luaC_checkGC (lua_State *L); + + +#endif diff --git a/build/premake/src/Src/Lua/liolib.c b/build/premake/src/Src/Lua/liolib.c new file mode 100644 index 0000000000..c389dc61f8 --- /dev/null +++ b/build/premake/src/Src/Lua/liolib.c @@ -0,0 +1,718 @@ +/* +** $Id: liolib.c,v 1.1 2003/04/23 12:16:05 jason379 Exp $ +** Standard I/O (and system) library +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "luadebug.h" +#include "lualib.h" + + +#ifndef OLD_ANSI +#include +#include +#define realloc(b,s) ((b) == NULL ? malloc(s) : (realloc)(b, s)) +#define free(b) if (b) (free)(b) +#else +/* no support for locale and for strerror: fake them */ +#define setlocale(a,b) ((void)a, strcmp((b),"C")==0?"C":NULL) +#define LC_ALL 0 +#define LC_COLLATE 0 +#define LC_CTYPE 0 +#define LC_MONETARY 0 +#define LC_NUMERIC 0 +#define LC_TIME 0 +#define strerror(e) "generic I/O error" +#define errno (-1) +#endif + + + +#ifdef POPEN +/* FILE *popen(); +int pclose(); */ +#define CLOSEFILE(L, f) ((pclose(f) == -1) ? fclose(f) : 0) +#else +/* no support for popen */ +#define popen(x,y) NULL /* that is, popen always fails */ +#define CLOSEFILE(L, f) (fclose(f)) +#endif + + +#define INFILE 0 +#define OUTFILE 1 + +typedef struct IOCtrl { + int ref[2]; /* ref for strings _INPUT/_OUTPUT */ + int iotag; /* tag for file handles */ + int closedtag; /* tag for closed handles */ +} IOCtrl; + + + +static const char *const filenames[] = {"_INPUT", "_OUTPUT"}; + + +static int pushresult (lua_State *L, int i) { + if (i) { + lua_pushuserdata(L, NULL); + return 1; + } + else { + lua_pushnil(L); + lua_pushstring(L, strerror(errno)); + lua_pushnumber(L, errno); + return 3;; + } +} + + +/* +** {====================================================== +** FILE Operations +** ======================================================= +*/ + + +static FILE *gethandle (lua_State *L, IOCtrl *ctrl, int f) { + void *p = lua_touserdata(L, f); + if (p != NULL) { /* is `f' a userdata ? */ + int ftag = lua_tag(L, f); + if (ftag == ctrl->iotag) /* does it have the correct tag? */ + return (FILE *)p; + else if (ftag == ctrl->closedtag) + lua_error(L, "cannot access a closed file"); + /* else go through */ + } + return NULL; +} + + +static FILE *getnonullfile (lua_State *L, IOCtrl *ctrl, int arg) { + FILE *f = gethandle(L, ctrl, arg); + luaL_arg_check(L, f, arg, "invalid file handle"); + return f; +} + + +static FILE *getfilebyref (lua_State *L, IOCtrl *ctrl, int inout) { + FILE *f; + lua_getglobals(L); + lua_getref(L, ctrl->ref[inout]); + lua_rawget(L, -2); + f = gethandle(L, ctrl, -1); + if (f == NULL) + luaL_verror(L, "global variable `%.10s' is not a file handle", + filenames[inout]); + return f; +} + + +static void setfilebyname (lua_State *L, IOCtrl *ctrl, FILE *f, + const char *name) { + lua_pushusertag(L, f, ctrl->iotag); + lua_setglobal(L, name); +} + + +#define setfile(L,ctrl,f,inout) (setfilebyname(L,ctrl,f,filenames[inout])) + + +static int setreturn (lua_State *L, IOCtrl *ctrl, FILE *f, int inout) { + if (f == NULL) + return pushresult(L, 0); + else { + setfile(L, ctrl, f, inout); + lua_pushusertag(L, f, ctrl->iotag); + return 1; + } +} + + +static int closefile (lua_State *L, IOCtrl *ctrl, FILE *f) { + if (f == stdin || f == stdout || f == stderr) + return 1; + else { + lua_pushusertag(L, f, ctrl->iotag); + lua_settag(L, ctrl->closedtag); + return (CLOSEFILE(L, f) == 0); + } +} + + +static int io_close (lua_State *L) { + IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); + lua_pop(L, 1); /* remove upvalue */ + return pushresult(L, closefile(L, ctrl, getnonullfile(L, ctrl, 1))); +} + + +static int file_collect (lua_State *L) { + IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); + FILE *f = getnonullfile(L, ctrl, 1); + if (f != stdin && f != stdout && f != stderr) + CLOSEFILE(L, f); + return 0; +} + + +static int io_open (lua_State *L) { + IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); + FILE *f; + lua_pop(L, 1); /* remove upvalue */ + f = fopen(luaL_check_string(L, 1), luaL_check_string(L, 2)); + if (f) { + lua_pushusertag(L, f, ctrl->iotag); + return 1; + } + else + return pushresult(L, 0); +} + + + +static int io_fromto (lua_State *L, int inout, const char *mode) { + IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); + FILE *current; + lua_pop(L, 1); /* remove upvalue */ + if (lua_isnull(L, 1)) { + closefile(L, ctrl, getfilebyref(L, ctrl, inout)); + current = (inout == 0) ? stdin : stdout; + } + else if (lua_tag(L, 1) == ctrl->iotag) /* deprecated option */ + current = (FILE *)lua_touserdata(L, 1); + else { + const char *s = luaL_check_string(L, 1); + current = (*s == '|') ? popen(s+1, mode) : fopen(s, mode); + } + return setreturn(L, ctrl, current, inout); +} + + +static int io_readfrom (lua_State *L) { + return io_fromto(L, INFILE, "r"); +} + + +static int io_writeto (lua_State *L) { + return io_fromto(L, OUTFILE, "w"); +} + + +static int io_appendto (lua_State *L) { + IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); + FILE *current; + lua_pop(L, 1); /* remove upvalue */ + current = fopen(luaL_check_string(L, 1), "a"); + return setreturn(L, ctrl, current, OUTFILE); +} + + + +/* +** {====================================================== +** READ +** ======================================================= +*/ + + + +#ifdef LUA_COMPAT_READPATTERN + +/* +** We cannot lookahead without need, because this can lock stdin. +** This flag signals when we need to read a next char. +*/ +#define NEED_OTHER (EOF-1) /* just some flag different from EOF */ + + +static int read_pattern (lua_State *L, FILE *f, const char *p) { + int inskip = 0; /* {skip} level */ + int c = NEED_OTHER; + luaL_Buffer b; + luaL_buffinit(L, &b); + while (*p != '\0') { + switch (*p) { + case '{': + inskip++; + p++; + continue; + case '}': + if (!inskip) lua_error(L, "unbalanced braces in read pattern"); + inskip--; + p++; + continue; + default: { + const char *ep = luaI_classend(L, p); /* get what is next */ + int m; /* match result */ + if (c == NEED_OTHER) c = getc(f); + m = (c==EOF) ? 0 : luaI_singlematch(c, p, ep); + if (m) { + if (!inskip) luaL_putchar(&b, c); + c = NEED_OTHER; + } + switch (*ep) { + case '+': /* repetition (1 or more) */ + if (!m) goto break_while; /* pattern fails? */ + /* else go through */ + case '*': /* repetition (0 or more) */ + while (m) { /* reads the same item until it fails */ + c = getc(f); + m = (c==EOF) ? 0 : luaI_singlematch(c, p, ep); + if (m && !inskip) luaL_putchar(&b, c); + } + /* go through to continue reading the pattern */ + case '?': /* optional */ + p = ep+1; /* continues reading the pattern */ + continue; + default: + if (!m) goto break_while; /* pattern fails? */ + p = ep; /* else continues reading the pattern */ + } + } + } + } break_while: + if (c != NEED_OTHER) ungetc(c, f); + luaL_pushresult(&b); /* close buffer */ + return (*p == '\0'); +} + +#else + +#define read_pattern(L, f, p) (lua_error(L, "read patterns are deprecated"), 0) + +#endif + + +static int read_number (lua_State *L, FILE *f) { + double d; + if (fscanf(f, "%lf", &d) == 1) { + lua_pushnumber(L, d); + return 1; + } + else return 0; /* read fails */ +} + + +static int read_word (lua_State *L, FILE *f) { + int c; + luaL_Buffer b; + luaL_buffinit(L, &b); + do { c = fgetc(f); } while (isspace(c)); /* skip spaces */ + while (c != EOF && !isspace(c)) { + luaL_putchar(&b, c); + c = fgetc(f); + } + ungetc(c, f); + luaL_pushresult(&b); /* close buffer */ + return (lua_strlen(L, -1) > 0); +} + + +static int read_line (lua_State *L, FILE *f) { + int n = 0; + luaL_Buffer b; + luaL_buffinit(L, &b); + for (;;) { + char *p = luaL_prepbuffer(&b); + if (!fgets(p, LUAL_BUFFERSIZE, f)) /* read fails? */ + break; + n = strlen(p); + if (p[n-1] != '\n') + luaL_addsize(&b, n); + else { + luaL_addsize(&b, n-1); /* do not add the `\n' */ + break; + } + } + luaL_pushresult(&b); /* close buffer */ + return (n > 0); /* read something? */ +} + + +static void read_file (lua_State *L, FILE *f) { + size_t len = 0; + size_t size = BUFSIZ; + char *buffer = NULL; + for (;;) { + char *newbuffer = (char *)realloc(buffer, size); + if (newbuffer == NULL) { + free(buffer); + lua_error(L, "not enough memory to read a file"); + } + buffer = newbuffer; + len += fread(buffer+len, sizeof(char), size-len, f); + if (len < size) break; /* did not read all it could */ + size *= 2; + } + lua_pushlstring(L, buffer, len); + free(buffer); +} + + +static int read_chars (lua_State *L, FILE *f, size_t n) { + char *buffer; + size_t n1; + char statbuff[BUFSIZ]; + if (n <= BUFSIZ) + buffer = statbuff; + else { + buffer = (char *)malloc(n); + if (buffer == NULL) + lua_error(L, "not enough memory to read a file"); + } + n1 = fread(buffer, sizeof(char), n, f); + lua_pushlstring(L, buffer, n1); + if (buffer != statbuff) free(buffer); + return (n1 > 0 || n == 0); +} + + +static int io_read (lua_State *L) { + IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); + int lastarg = lua_gettop(L) - 1; + int firstarg = 1; + FILE *f = gethandle(L, ctrl, firstarg); + int n; + if (f) firstarg++; + else f = getfilebyref(L, ctrl, INFILE); /* get _INPUT */ + lua_pop(L, 1); + if (firstarg > lastarg) { /* no arguments? */ + lua_settop(L, 0); /* erase upvalue and other eventual garbage */ + firstarg = lastarg = 1; /* correct indices */ + lua_pushstring(L, "*l"); /* push default argument */ + } + else /* ensure stack space for all results and for auxlib's buffer */ + luaL_checkstack(L, lastarg-firstarg+1+LUA_MINSTACK, "too many arguments"); + for (n = firstarg; n<=lastarg; n++) { + int success; + if (lua_isnumber(L, n)) + success = read_chars(L, f, (size_t)lua_tonumber(L, n)); + else { + const char *p = luaL_check_string(L, n); + if (p[0] != '*') + success = read_pattern(L, f, p); /* deprecated! */ + else { + switch (p[1]) { + case 'n': /* number */ + if (!read_number(L, f)) goto endloop; /* read fails */ + continue; /* number is already pushed; avoid the "pushstring" */ + case 'l': /* line */ + success = read_line(L, f); + break; + case 'a': /* file */ + read_file(L, f); + success = 1; /* always success */ + break; + case 'w': /* word */ + success = read_word(L, f); + break; + default: + luaL_argerror(L, n, "invalid format"); + success = 0; /* to avoid warnings */ + } + } + } + if (!success) { + lua_pop(L, 1); /* remove last result */ + break; /* read fails */ + } + } endloop: + return n - firstarg; +} + +/* }====================================================== */ + + +static int io_write (lua_State *L) { + int lastarg = lua_gettop(L) - 1; + IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); + int arg = 1; + int status = 1; + FILE *f = gethandle(L, ctrl, arg); + if (f) arg++; + else f = getfilebyref(L, ctrl, OUTFILE); /* get _OUTPUT */ + for (; arg <= lastarg; arg++) { + if (lua_type(L, arg) == LUA_TNUMBER) { /* LUA_NUMBER */ + /* optimization: could be done exactly as for strings */ + status = status && fprintf(f, "%.16g", lua_tonumber(L, arg)) > 0; + } + else { + size_t l; + const char *s = luaL_check_lstr(L, arg, &l); + status = status && (fwrite(s, sizeof(char), l, f) == l); + } + } + pushresult(L, status); + return 1; +} + + +static int io_seek (lua_State *L) { + static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; + static const char *const modenames[] = {"set", "cur", "end", NULL}; + IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); + FILE *f; + int op; + long offset; + lua_pop(L, 1); /* remove upvalue */ + f = getnonullfile(L, ctrl, 1); + op = luaL_findstring(luaL_opt_string(L, 2, "cur"), modenames); + offset = luaL_opt_long(L, 3, 0); + luaL_arg_check(L, op != -1, 2, "invalid mode"); + op = fseek(f, offset, mode[op]); + if (op) + return pushresult(L, 0); /* error */ + else { + lua_pushnumber(L, ftell(f)); + return 1; + } +} + + +static int io_flush (lua_State *L) { + IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); + FILE *f; + lua_pop(L, 1); /* remove upvalue */ + f = gethandle(L, ctrl, 1); + luaL_arg_check(L, f || lua_isnull(L, 1), 1, "invalid file handle"); + return pushresult(L, fflush(f) == 0); +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Other O.S. Operations +** ======================================================= +*/ + +static int io_execute (lua_State *L) { + lua_pushnumber(L, system(luaL_check_string(L, 1))); + return 1; +} + + +static int io_remove (lua_State *L) { + return pushresult(L, remove(luaL_check_string(L, 1)) == 0); +} + + +static int io_rename (lua_State *L) { + return pushresult(L, rename(luaL_check_string(L, 1), + luaL_check_string(L, 2)) == 0); +} + + +static int io_tmpname (lua_State *L) { + lua_pushstring(L, tmpnam(NULL)); + return 1; +} + + + +static int io_getenv (lua_State *L) { + lua_pushstring(L, getenv(luaL_check_string(L, 1))); /* if NULL push nil */ + return 1; +} + + +static int io_clock (lua_State *L) { + lua_pushnumber(L, ((double)clock())/CLOCKS_PER_SEC); + return 1; +} + + +static int io_date (lua_State *L) { + char b[256]; + const char *s = luaL_opt_string(L, 1, "%c"); + struct tm *stm; + time_t t; + time(&t); stm = localtime(&t); + if (strftime(b, sizeof(b), s, stm)) + lua_pushstring(L, b); + else + lua_error(L, "invalid `date' format"); + return 1; +} + + +static int setloc (lua_State *L) { + static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, + LC_NUMERIC, LC_TIME}; + static const char *const catnames[] = {"all", "collate", "ctype", "monetary", + "numeric", "time", NULL}; + int op = luaL_findstring(luaL_opt_string(L, 2, "all"), catnames); + luaL_arg_check(L, op != -1, 2, "invalid option"); + lua_pushstring(L, setlocale(cat[op], luaL_check_string(L, 1))); + return 1; +} + + +static int io_exit (lua_State *L) { + exit(luaL_opt_int(L, 1, EXIT_SUCCESS)); + return 0; /* to avoid warnings */ +} + +/* }====================================================== */ + + + +static int io_debug (lua_State *L) { + for (;;) { + char buffer[250]; + fprintf(stderr, "lua_debug> "); + if (fgets(buffer, sizeof(buffer), stdin) == 0 || + strcmp(buffer, "cont\n") == 0) + return 0; + lua_dostring(L, buffer); + lua_settop(L, 0); /* remove eventual returns */ + } +} + + +#define LEVELS1 12 /* size of the first part of the stack */ +#define LEVELS2 10 /* size of the second part of the stack */ + +static int errorfb (lua_State *L) { + int level = 1; /* skip level 0 (it's this function) */ + int firstpart = 1; /* still before eventual `...' */ + lua_Debug ar; + luaL_Buffer b; + luaL_buffinit(L, &b); + luaL_addstring(&b, "error: "); + luaL_addstring(&b, luaL_check_string(L, 1)); + luaL_addstring(&b, "\n"); + while (lua_getstack(L, level++, &ar)) { + char buff[120]; /* enough to fit following `sprintf's */ + if (level == 2) + luaL_addstring(&b, "stack traceback:\n"); + else if (level > LEVELS1 && firstpart) { + /* no more than `LEVELS2' more levels? */ + if (!lua_getstack(L, level+LEVELS2, &ar)) + level--; /* keep going */ + else { + luaL_addstring(&b, " ...\n"); /* too many levels */ + while (lua_getstack(L, level+LEVELS2, &ar)) /* find last levels */ + level++; + } + firstpart = 0; + continue; + } + sprintf(buff, "%4d: ", level-1); + luaL_addstring(&b, buff); + lua_getinfo(L, "Snl", &ar); + switch (*ar.namewhat) { + case 'g': case 'l': /* global, local */ + sprintf(buff, "function `%.50s'", ar.name); + break; + case 'f': /* field */ + sprintf(buff, "method `%.50s'", ar.name); + break; + case 't': /* tag method */ + sprintf(buff, "`%.50s' tag method", ar.name); + break; + default: { + if (*ar.what == 'm') /* main? */ + sprintf(buff, "main of %.70s", ar.short_src); + else if (*ar.what == 'C') /* C function? */ + sprintf(buff, "%.70s", ar.short_src); + else + sprintf(buff, "function <%d:%.70s>", ar.linedefined, ar.short_src); + ar.source = NULL; /* do not print source again */ + } + } + luaL_addstring(&b, buff); + if (ar.currentline > 0) { + sprintf(buff, " at line %d", ar.currentline); + luaL_addstring(&b, buff); + } + if (ar.source) { + sprintf(buff, " [%.70s]", ar.short_src); + luaL_addstring(&b, buff); + } + luaL_addstring(&b, "\n"); + } + luaL_pushresult(&b); + lua_getglobal(L, LUA_ALERT); + if (lua_isfunction(L, -1)) { /* avoid loop if _ALERT is not defined */ + lua_pushvalue(L, -2); /* error message */ + lua_rawcall(L, 1, 0); + } + return 0; +} + + + +static const struct luaL_reg iolib[] = { + {LUA_ERRORMESSAGE, errorfb}, + {"clock", io_clock}, + {"date", io_date}, + {"debug", io_debug}, + {"execute", io_execute}, + {"exit", io_exit}, + {"getenv", io_getenv}, + {"remove", io_remove}, + {"rename", io_rename}, + {"setlocale", setloc}, + {"tmpname", io_tmpname} +}; + + +static const struct luaL_reg iolibtag[] = { + {"appendto", io_appendto}, + {"closefile", io_close}, + {"flush", io_flush}, + {"openfile", io_open}, + {"read", io_read}, + {"readfrom", io_readfrom}, + {"seek", io_seek}, + {"write", io_write}, + {"writeto", io_writeto} +}; + + +static void openwithcontrol (lua_State *L) { + IOCtrl *ctrl = (IOCtrl *)lua_newuserdata(L, sizeof(IOCtrl)); + unsigned int i; + ctrl->iotag = lua_newtag(L); + ctrl->closedtag = lua_newtag(L); + for (i=0; iref[INFILE] = lua_ref(L, 1); + lua_pushstring(L, filenames[OUTFILE]); + ctrl->ref[OUTFILE] = lua_ref(L, 1); + /* predefined file handles */ + setfile(L, ctrl, stdin, INFILE); + setfile(L, ctrl, stdout, OUTFILE); + setfilebyname(L, ctrl, stdin, "_STDIN"); + setfilebyname(L, ctrl, stdout, "_STDOUT"); + setfilebyname(L, ctrl, stderr, "_STDERR"); + /* close files when collected */ + lua_pushcclosure(L, file_collect, 1); /* pops `ctrl' from stack */ + lua_settagmethod(L, ctrl->iotag, "gc"); +} + + +LUALIB_API void lua_iolibopen (lua_State *L) { + luaL_openl(L, iolib); + openwithcontrol(L); +} + diff --git a/build/premake/src/Src/Lua/llex.c b/build/premake/src/Src/Lua/llex.c new file mode 100644 index 0000000000..1057552c79 --- /dev/null +++ b/build/premake/src/Src/Lua/llex.c @@ -0,0 +1,380 @@ +/* +** $Id: llex.c,v 1.1 2003/01/24 16:26:06 jason379 Exp $ +** Lexical Analyzer +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include + +#include "lua.h" + +#include "llex.h" +#include "lmem.h" +#include "lobject.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "luadebug.h" +#include "lzio.h" + + + +#define next(LS) (LS->current = zgetc(LS->z)) + + + +/* ORDER RESERVED */ +static const char *const token2string [] = { + "and", "break", "do", "else", "elseif", "end", "for", + "function", "if", "local", "nil", "not", "or", "repeat", "return", "then", + "until", "while", "", "..", "...", "==", ">=", "<=", "~=", "", "", ""}; + + +void luaX_init (lua_State *L) { + int i; + for (i=0; imarked = (unsigned char)(RESERVEDMARK+i); /* reserved word */ + } +} + + +#define MAXSRC 80 + + +void luaX_checklimit (LexState *ls, int val, int limit, const char *msg) { + if (val > limit) { + char buff[100]; + sprintf(buff, "too many %.50s (limit=%d)", msg, limit); + luaX_error(ls, buff, ls->t.token); + } +} + + +void luaX_syntaxerror (LexState *ls, const char *s, const char *token) { + char buff[MAXSRC]; + luaO_chunkid(buff, ls->source->str, sizeof(buff)); + luaO_verror(ls->L, "%.99s;\n last token read: `%.30s' at line %d in %.80s", + s, token, ls->linenumber, buff); +} + + +void luaX_error (LexState *ls, const char *s, int token) { + char buff[TOKEN_LEN]; + luaX_token2str(token, buff); + if (buff[0] == '\0') + luaX_syntaxerror(ls, s, ls->L->Mbuffer); + else + luaX_syntaxerror(ls, s, buff); +} + + +void luaX_token2str (int token, char *s) { + if (token < 256) { + s[0] = (char)token; + s[1] = '\0'; + } + else + strcpy(s, token2string[token-FIRST_RESERVED]); +} + + +static void luaX_invalidchar (LexState *ls, int c) { + char buff[8]; + sprintf(buff, "0x%02X", c); + luaX_syntaxerror(ls, "invalid control char", buff); +} + + +static void inclinenumber (LexState *LS) { + next(LS); /* skip '\n' */ + ++LS->linenumber; + luaX_checklimit(LS, LS->linenumber, MAX_INT, "lines in a chunk"); +} + + +void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source) { + LS->L = L; + LS->lookahead.token = TK_EOS; /* no look-ahead token */ + LS->z = z; + LS->fs = NULL; + LS->linenumber = 1; + LS->lastline = 1; + LS->source = source; + next(LS); /* read first char */ + if (LS->current == '#') { + do { /* skip first line */ + next(LS); + } while (LS->current != '\n' && LS->current != EOZ); + } +} + + + +/* +** ======================================================= +** LEXICAL ANALYZER +** ======================================================= +*/ + + +/* use Mbuffer to store names, literal strings and numbers */ + +#define EXTRABUFF 128 +#define checkbuffer(L, n, len) if ((len)+(n) > L->Mbuffsize) \ + luaO_openspace(L, (len)+(n)+EXTRABUFF) + +#define save(L, c, l) (L->Mbuffer[l++] = (char)c) +#define save_and_next(L, LS, l) (save(L, LS->current, l), next(LS)) + + +static const char *readname (LexState *LS) { + lua_State *L = LS->L; + size_t l = 0; + checkbuffer(L, 10, l); + do { + checkbuffer(L, 10, l); + save_and_next(L, LS, l); + } while (isalnum(LS->current) || LS->current == '_'); + save(L, '\0', l); + return L->Mbuffer; +} + + +/* LUA_NUMBER */ +static void read_number (LexState *LS, int comma, SemInfo *seminfo) { + lua_State *L = LS->L; + size_t l = 0; + checkbuffer(L, 10, l); + if (comma) save(L, '.', l); + while (isdigit(LS->current)) { + checkbuffer(L, 10, l); + save_and_next(L, LS, l); + } + if (LS->current == '.') { + save_and_next(L, LS, l); + if (LS->current == '.') { + save_and_next(L, LS, l); + save(L, '\0', l); + luaX_error(LS, "ambiguous syntax" + " (decimal point x string concatenation)", TK_NUMBER); + } + } + while (isdigit(LS->current)) { + checkbuffer(L, 10, l); + save_and_next(L, LS, l); + } + if (LS->current == 'e' || LS->current == 'E') { + save_and_next(L, LS, l); /* read 'E' */ + if (LS->current == '+' || LS->current == '-') + save_and_next(L, LS, l); /* optional exponent sign */ + while (isdigit(LS->current)) { + checkbuffer(L, 10, l); + save_and_next(L, LS, l); + } + } + save(L, '\0', l); + if (!luaO_str2d(L->Mbuffer, &seminfo->r)) + luaX_error(LS, "malformed number", TK_NUMBER); +} + + +static void read_long_string (LexState *LS, SemInfo *seminfo) { + lua_State *L = LS->L; + int cont = 0; + size_t l = 0; + checkbuffer(L, 10, l); + save(L, '[', l); /* save first '[' */ + save_and_next(L, LS, l); /* pass the second '[' */ + for (;;) { + checkbuffer(L, 10, l); + switch (LS->current) { + case EOZ: + save(L, '\0', l); + luaX_error(LS, "unfinished long string", TK_STRING); + break; /* to avoid warnings */ + case '[': + save_and_next(L, LS, l); + if (LS->current == '[') { + cont++; + save_and_next(L, LS, l); + } + continue; + case ']': + save_and_next(L, LS, l); + if (LS->current == ']') { + if (cont == 0) goto endloop; + cont--; + save_and_next(L, LS, l); + } + continue; + case '\n': + save(L, '\n', l); + inclinenumber(LS); + continue; + default: + save_and_next(L, LS, l); + } + } endloop: + save_and_next(L, LS, l); /* skip the second ']' */ + save(L, '\0', l); + seminfo->ts = luaS_newlstr(L, L->Mbuffer+2, l-5); +} + + +static void read_string (LexState *LS, int del, SemInfo *seminfo) { + lua_State *L = LS->L; + size_t l = 0; + checkbuffer(L, 10, l); + save_and_next(L, LS, l); + while (LS->current != del) { + checkbuffer(L, 10, l); + switch (LS->current) { + case EOZ: case '\n': + save(L, '\0', l); + luaX_error(LS, "unfinished string", TK_STRING); + break; /* to avoid warnings */ + case '\\': + next(LS); /* do not save the '\' */ + switch (LS->current) { + case 'a': save(L, '\a', l); next(LS); break; + case 'b': save(L, '\b', l); next(LS); break; + case 'f': save(L, '\f', l); next(LS); break; + case 'n': save(L, '\n', l); next(LS); break; + case 'r': save(L, '\r', l); next(LS); break; + case 't': save(L, '\t', l); next(LS); break; + case 'v': save(L, '\v', l); next(LS); break; + case '\n': save(L, '\n', l); inclinenumber(LS); break; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': { + int c = 0; + int i = 0; + do { + c = 10*c + (LS->current-'0'); + next(LS); + } while (++i<3 && isdigit(LS->current)); + if (c != (unsigned char)c) { + save(L, '\0', l); + luaX_error(LS, "escape sequence too large", TK_STRING); + } + save(L, c, l); + break; + } + default: /* handles \\, \", \', and \? */ + save_and_next(L, LS, l); + } + break; + default: + save_and_next(L, LS, l); + } + } + save_and_next(L, LS, l); /* skip delimiter */ + save(L, '\0', l); + seminfo->ts = luaS_newlstr(L, L->Mbuffer+1, l-3); +} + + +int luaX_lex (LexState *LS, SemInfo *seminfo) { + for (;;) { + switch (LS->current) { + + case ' ': case '\t': case '\r': /* `\r' to avoid problems with DOS */ + next(LS); + continue; + + case '\n': + inclinenumber(LS); + continue; + + case '$': + luaX_error(LS, "unexpected `$' (pragmas are no longer supported)", '$'); + break; + + case '-': + next(LS); + if (LS->current != '-') return '-'; + do { next(LS); } while (LS->current != '\n' && LS->current != EOZ); + continue; + + case '[': + next(LS); + if (LS->current != '[') return '['; + else { + read_long_string(LS, seminfo); + return TK_STRING; + } + + case '=': + next(LS); + if (LS->current != '=') return '='; + else { next(LS); return TK_EQ; } + + case '<': + next(LS); + if (LS->current != '=') return '<'; + else { next(LS); return TK_LE; } + + case '>': + next(LS); + if (LS->current != '=') return '>'; + else { next(LS); return TK_GE; } + + case '~': + next(LS); + if (LS->current != '=') return '~'; + else { next(LS); return TK_NE; } + + case '"': + case '\'': + read_string(LS, LS->current, seminfo); + return TK_STRING; + + case '.': + next(LS); + if (LS->current == '.') { + next(LS); + if (LS->current == '.') { + next(LS); + return TK_DOTS; /* ... */ + } + else return TK_CONCAT; /* .. */ + } + else if (!isdigit(LS->current)) return '.'; + else { + read_number(LS, 1, seminfo); + return TK_NUMBER; + } + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + read_number(LS, 0, seminfo); + return TK_NUMBER; + + case EOZ: + return TK_EOS; + + case '_': goto tname; + + default: + if (!isalpha(LS->current)) { + int c = LS->current; + if (iscntrl(c)) + luaX_invalidchar(LS, c); + next(LS); + return c; + } + tname: { /* identifier or reserved word */ + TString *ts = luaS_new(LS->L, readname(LS)); + if (ts->marked >= RESERVEDMARK) /* reserved word? */ + return ts->marked-RESERVEDMARK+FIRST_RESERVED; + seminfo->ts = ts; + return TK_NAME; + } + } + } +} + diff --git a/build/premake/src/Src/Lua/llex.h b/build/premake/src/Src/Lua/llex.h new file mode 100644 index 0000000000..042f435e90 --- /dev/null +++ b/build/premake/src/Src/Lua/llex.h @@ -0,0 +1,72 @@ +/* +** $Id: llex.h,v 1.1 2003/01/24 16:26:06 jason379 Exp $ +** Lexical Analyzer +** See Copyright Notice in lua.h +*/ + +#ifndef llex_h +#define llex_h + +#include "lobject.h" +#include "lzio.h" + + +#define FIRST_RESERVED 257 + +/* maximum length of a reserved word (+1 for final 0) */ +#define TOKEN_LEN 15 + + +/* +* WARNING: if you change the order of this enumeration, +* grep "ORDER RESERVED" +*/ +enum RESERVED { + /* terminal symbols denoted by reserved words */ + TK_AND = FIRST_RESERVED, TK_BREAK, + TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FOR, TK_FUNCTION, TK_IF, TK_LOCAL, + TK_NIL, TK_NOT, TK_OR, TK_REPEAT, TK_RETURN, TK_THEN, TK_UNTIL, TK_WHILE, + /* other terminal symbols */ + TK_NAME, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER, + TK_STRING, TK_EOS +}; + +/* number of reserved words */ +#define NUM_RESERVED ((int)(TK_WHILE-FIRST_RESERVED+1)) + + +typedef union { + Number r; + TString *ts; +} SemInfo; /* semantics information */ + + +typedef struct Token { + int token; + SemInfo seminfo; +} Token; + + +typedef struct LexState { + int current; /* current character */ + Token t; /* current token */ + Token lookahead; /* look ahead token */ + struct FuncState *fs; /* `FuncState' is private to the parser */ + struct lua_State *L; + struct zio *z; /* input stream */ + int linenumber; /* input line counter */ + int lastline; /* line of last token `consumed' */ + TString *source; /* current source name */ +} LexState; + + +void luaX_init (lua_State *L); +void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source); +int luaX_lex (LexState *LS, SemInfo *seminfo); +void luaX_checklimit (LexState *ls, int val, int limit, const char *msg); +void luaX_syntaxerror (LexState *ls, const char *s, const char *token); +void luaX_error (LexState *ls, const char *s, int token); +void luaX_token2str (int token, char *s); + + +#endif diff --git a/build/premake/src/Src/Lua/llimits.h b/build/premake/src/Src/Lua/llimits.h new file mode 100644 index 0000000000..05e8fabdfd --- /dev/null +++ b/build/premake/src/Src/Lua/llimits.h @@ -0,0 +1,204 @@ +/* +** $Id: llimits.h,v 1.1 2003/01/24 16:26:06 jason379 Exp $ +** Limits, basic types, and some other "installation-dependent" definitions +** See Copyright Notice in lua.h +*/ + +#ifndef llimits_h +#define llimits_h + + +#include +#include + + + +/* +** try to find number of bits in an integer +*/ +#ifndef BITS_INT +/* avoid overflows in comparison */ +#if INT_MAX-20 < 32760 +#define BITS_INT 16 +#else +#if INT_MAX > 2147483640L +/* machine has at least 32 bits */ +#define BITS_INT 32 +#else +#error "you must define BITS_INT with number of bits in an integer" +#endif +#endif +#endif + + +/* +** Define the type `number' of Lua +** GREP LUA_NUMBER to change that +*/ +#ifndef LUA_NUM_TYPE +#define LUA_NUM_TYPE double +#endif + +typedef LUA_NUM_TYPE Number; + +/* function to convert a Number to a string */ +#define NUMBER_FMT "%.16g" /* LUA_NUMBER */ +#define lua_number2str(s,n) sprintf((s), NUMBER_FMT, (n)) + +/* function to convert a string to a Number */ +#define lua_str2number(s,p) strtod((s), (p)) + + + +typedef unsigned long lint32; /* unsigned int with at least 32 bits */ + + +#define MAX_SIZET ((size_t)(~(size_t)0)-2) + + +#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */ + +/* +** conversion of pointer to int (for hashing only) +** (the shift removes bits that are usually 0 because of alignment) +*/ +#define IntPoint(p) (((unsigned long)(p)) >> 3) + + + +#define MINPOWER2 4 /* minimum size for "growing" vectors */ + + + +#ifndef DEFAULT_STACK_SIZE +#define DEFAULT_STACK_SIZE 1024 +#endif + + + +/* type to ensure maximum alignment */ +union L_Umaxalign { double d; char *s; long l; }; + + + +/* +** type for virtual-machine instructions +** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) +** For a very small machine, you may change that to 2 bytes (and adjust +** the following limits accordingly) +*/ +typedef unsigned long Instruction; + + +/* +** size and position of opcode arguments. +** For an instruction with 2 bytes, size is 16, and size_b can be 5 +** (accordingly, size_u will be 10, and size_a will be 5) +*/ +#define SIZE_INSTRUCTION 32 +#define SIZE_B 9 + +#define SIZE_OP 6 +#define SIZE_U (SIZE_INSTRUCTION-SIZE_OP) +#define POS_U SIZE_OP +#define POS_B SIZE_OP +#define SIZE_A (SIZE_INSTRUCTION-(SIZE_OP+SIZE_B)) +#define POS_A (SIZE_OP+SIZE_B) + + +/* +** limits for opcode arguments. +** we use (signed) int to manipulate most arguments, +** so they must fit in BITS_INT-1 bits (-1 for sign) +*/ +#if SIZE_U < BITS_INT-1 +#define MAXARG_U ((1<>1) /* `S' is signed */ +#else +#define MAXARG_U MAX_INT +#define MAXARG_S MAX_INT +#endif + +#if SIZE_A < BITS_INT-1 +#define MAXARG_A ((1< MAXARG_B +#undef MAXSTACK +#define MAXSTACK MAXARG_B +#endif + + +/* maximum number of local variables */ +#ifndef MAXLOCALS +#define MAXLOCALS 200 /* arbitrary limit (=MAXSTACK +#undef MAXLOCALS +#define MAXLOCALS (MAXSTACK-1) +#endif + + +/* maximum number of upvalues */ +#ifndef MAXUPVALUES +#define MAXUPVALUES 32 /* arbitrary limit (<=MAXARG_B) */ +#endif +#if MAXUPVALUES>MAXARG_B +#undef MAXUPVALUES +#define MAXUPVALUES MAXARG_B +#endif + + +/* maximum number of variables in the left side of an assignment */ +#ifndef MAXVARSLH +#define MAXVARSLH 100 /* arbitrary limit (=MULT_RET +#undef MAXVARSLH +#define MAXVARSLH (MULT_RET-1) +#endif + + +/* maximum number of parameters in a function */ +#ifndef MAXPARAMS +#define MAXPARAMS 100 /* arbitrary limit (=MAXLOCALS +#undef MAXPARAMS +#define MAXPARAMS (MAXLOCALS-1) +#endif + + +/* number of list items to accumulate before a SETLIST instruction */ +#define LFIELDS_PER_FLUSH 64 +#if LFIELDS_PER_FLUSH>(MAXSTACK/4) +#undef LFIELDS_PER_FLUSH +#define LFIELDS_PER_FLUSH (MAXSTACK/4) +#endif + +/* number of record items to accumulate before a SETMAP instruction */ +/* (each item counts 2 elements on the stack: an index and a value) */ +#define RFIELDS_PER_FLUSH (LFIELDS_PER_FLUSH/2) + + +/* maximum lookback to find a real constant (for code generation) */ +#ifndef LOOKBACKNUMS +#define LOOKBACKNUMS 20 /* arbitrary constant */ +#endif + + +#endif diff --git a/build/premake/src/Src/Lua/lmathlib.c b/build/premake/src/Src/Lua/lmathlib.c new file mode 100644 index 0000000000..b893644557 --- /dev/null +++ b/build/premake/src/Src/Lua/lmathlib.c @@ -0,0 +1,238 @@ +/* +** $Id: lmathlib.c,v 1.1 2003/04/23 12:16:05 jason379 Exp $ +** Standard mathematical library +** See Copyright Notice in lua.h +*/ + + +#include +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +#undef PI +#define PI (3.14159265358979323846) +#define RADIANS_PER_DEGREE (PI/180.0) + + + +/* +** If you want Lua to operate in radians (instead of degrees), +** define RADIANS +*/ +#ifdef RADIANS +#define FROMRAD(a) (a) +#define TORAD(a) (a) +#else +#define FROMRAD(a) ((a)/RADIANS_PER_DEGREE) +#define TORAD(a) ((a)*RADIANS_PER_DEGREE) +#endif + + +static int math_abs (lua_State *L) { + lua_pushnumber(L, fabs(luaL_check_number(L, 1))); + return 1; +} + +static int math_sin (lua_State *L) { + lua_pushnumber(L, sin(TORAD(luaL_check_number(L, 1)))); + return 1; +} + +static int math_cos (lua_State *L) { + lua_pushnumber(L, cos(TORAD(luaL_check_number(L, 1)))); + return 1; +} + +static int math_tan (lua_State *L) { + lua_pushnumber(L, tan(TORAD(luaL_check_number(L, 1)))); + return 1; +} + +static int math_asin (lua_State *L) { + lua_pushnumber(L, FROMRAD(asin(luaL_check_number(L, 1)))); + return 1; +} + +static int math_acos (lua_State *L) { + lua_pushnumber(L, FROMRAD(acos(luaL_check_number(L, 1)))); + return 1; +} + +static int math_atan (lua_State *L) { + lua_pushnumber(L, FROMRAD(atan(luaL_check_number(L, 1)))); + return 1; +} + +static int math_atan2 (lua_State *L) { + lua_pushnumber(L, FROMRAD(atan2(luaL_check_number(L, 1), luaL_check_number(L, 2)))); + return 1; +} + +static int math_ceil (lua_State *L) { + lua_pushnumber(L, ceil(luaL_check_number(L, 1))); + return 1; +} + +static int math_floor (lua_State *L) { + lua_pushnumber(L, floor(luaL_check_number(L, 1))); + return 1; +} + +static int math_mod (lua_State *L) { + lua_pushnumber(L, fmod(luaL_check_number(L, 1), luaL_check_number(L, 2))); + return 1; +} + +static int math_sqrt (lua_State *L) { + lua_pushnumber(L, sqrt(luaL_check_number(L, 1))); + return 1; +} + +static int math_pow (lua_State *L) { + lua_pushnumber(L, pow(luaL_check_number(L, 1), luaL_check_number(L, 2))); + return 1; +} + +static int math_log (lua_State *L) { + lua_pushnumber(L, log(luaL_check_number(L, 1))); + return 1; +} + +static int math_log10 (lua_State *L) { + lua_pushnumber(L, log10(luaL_check_number(L, 1))); + return 1; +} + +static int math_exp (lua_State *L) { + lua_pushnumber(L, exp(luaL_check_number(L, 1))); + return 1; +} + +static int math_deg (lua_State *L) { + lua_pushnumber(L, luaL_check_number(L, 1)/RADIANS_PER_DEGREE); + return 1; +} + +static int math_rad (lua_State *L) { + lua_pushnumber(L, luaL_check_number(L, 1)*RADIANS_PER_DEGREE); + return 1; +} + +static int math_frexp (lua_State *L) { + int e; + lua_pushnumber(L, frexp(luaL_check_number(L, 1), &e)); + lua_pushnumber(L, e); + return 2; +} + +static int math_ldexp (lua_State *L) { + lua_pushnumber(L, ldexp(luaL_check_number(L, 1), luaL_check_int(L, 2))); + return 1; +} + + + +static int math_min (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + double dmin = luaL_check_number(L, 1); + int i; + for (i=2; i<=n; i++) { + double d = luaL_check_number(L, i); + if (d < dmin) + dmin = d; + } + lua_pushnumber(L, dmin); + return 1; +} + + +static int math_max (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + double dmax = luaL_check_number(L, 1); + int i; + for (i=2; i<=n; i++) { + double d = luaL_check_number(L, i); + if (d > dmax) + dmax = d; + } + lua_pushnumber(L, dmax); + return 1; +} + + +static int math_random (lua_State *L) { + /* the '%' avoids the (rare) case of r==1, and is needed also because on + some systems (SunOS!) "rand()" may return a value larger than RAND_MAX */ + double r = (double)(rand()%RAND_MAX) / (double)RAND_MAX; + switch (lua_gettop(L)) { /* check number of arguments */ + case 0: { /* no arguments */ + lua_pushnumber(L, r); /* Number between 0 and 1 */ + break; + } + case 1: { /* only upper limit */ + int u = luaL_check_int(L, 1); + luaL_arg_check(L, 1<=u, 1, "interval is empty"); + lua_pushnumber(L, (int)(r*u)+1); /* integer between 1 and `u' */ + break; + } + case 2: { /* lower and upper limits */ + int l = luaL_check_int(L, 1); + int u = luaL_check_int(L, 2); + luaL_arg_check(L, l<=u, 2, "interval is empty"); + lua_pushnumber(L, (int)(r*(u-l+1))+l); /* integer between `l' and `u' */ + break; + } + default: lua_error(L, "wrong number of arguments"); + } + return 1; +} + + +static int math_randomseed (lua_State *L) { + srand(luaL_check_int(L, 1)); + return 0; +} + + +static const struct luaL_reg mathlib[] = { +{"abs", math_abs}, +{"sin", math_sin}, +{"cos", math_cos}, +{"tan", math_tan}, +{"asin", math_asin}, +{"acos", math_acos}, +{"atan", math_atan}, +{"atan2", math_atan2}, +{"ceil", math_ceil}, +{"floor", math_floor}, +{"mod", math_mod}, +{"frexp", math_frexp}, +{"ldexp", math_ldexp}, +{"sqrt", math_sqrt}, +{"min", math_min}, +{"max", math_max}, +{"log", math_log}, +{"log10", math_log10}, +{"exp", math_exp}, +{"deg", math_deg}, +{"rad", math_rad}, +{"random", math_random}, +{"randomseed", math_randomseed} +}; + +/* +** Open math library +*/ +LUALIB_API void lua_mathlibopen (lua_State *L) { + luaL_openl(L, mathlib); + lua_pushcfunction(L, math_pow); + lua_settagmethod(L, LUA_TNUMBER, "pow"); + lua_pushnumber(L, PI); + lua_setglobal(L, "PI"); +} + diff --git a/build/premake/src/Src/Lua/lmem.c b/build/premake/src/Src/Lua/lmem.c new file mode 100644 index 0000000000..60fe29477b --- /dev/null +++ b/build/premake/src/Src/Lua/lmem.c @@ -0,0 +1,150 @@ +/* +** $Id: lmem.c,v 1.1 2003/01/24 16:26:06 jason379 Exp $ +** Interface to Memory Manager +** See Copyright Notice in lua.h +*/ + + +#include + +#include "lua.h" + +#include "ldo.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" + + + + +#ifdef LUA_DEBUG +/* +** {====================================================================== +** Controlled version for realloc. +** ======================================================================= +*/ + + +#include +#include +#include + +#define realloc(b, s) debug_realloc(b, s) +#define malloc(b) debug_realloc(NULL, b) +#define free(b) debug_realloc(b, 0) + + +/* ensures maximum alignment for HEADER */ +#define HEADER (sizeof(union L_Umaxalign)) + +#define MARKSIZE 16 +#define MARK 0x55 /* 01010101 (a nice pattern) */ + + +#define blocksize(b) ((unsigned long *)((char *)(b) - HEADER)) + +unsigned long memdebug_numblocks = 0; +unsigned long memdebug_total = 0; +unsigned long memdebug_maxmem = 0; +unsigned long memdebug_memlimit = LONG_MAX; + + +static void *checkblock (void *block) { + unsigned long *b = blocksize(block); + unsigned long size = *b; + int i; + for (i=0;i memdebug_memlimit) + return NULL; /* to test memory allocation errors */ + else { + size_t realsize = HEADER+size+MARKSIZE; + char *newblock = (char *)(malloc)(realsize); /* alloc a new block */ + int i; + if (realsize < size) return NULL; /* overflow! */ + if (newblock == NULL) return NULL; + if (block) { + size_t oldsize = *blocksize(block); + if (oldsize > size) oldsize = size; + memcpy(newblock+HEADER, block, oldsize); + freeblock(block); /* erase (and check) old copy */ + } + memdebug_total += size; + if (memdebug_total > memdebug_maxmem) memdebug_maxmem = memdebug_total; + memdebug_numblocks++; + *(unsigned long *)newblock = size; + for (i=0;i= limit-inc) lua_error(L, errormsg); + if ((newn ^ nelems) <= nelems || /* still the same power-of-2 limit? */ + (nelems > 0 && newn < MINPOWER2)) /* or block already is MINPOWER2? */ + return block; /* do not need to reallocate */ + else /* it crossed a power-of-2 boundary; grow to next power */ + return luaM_realloc(L, block, luaO_power2(newn)*size); +} + + +/* +** generic allocation routine. +*/ +void *luaM_realloc (lua_State *L, void *block, lint32 size) { + if (size == 0) { + free(block); /* block may be NULL; that is OK for free */ + return NULL; + } + else if (size >= MAX_SIZET) + lua_error(L, "memory allocation error: block too big"); + block = realloc(block, size); + if (block == NULL) { + if (L) + luaD_breakrun(L, LUA_ERRMEM); /* break run without error message */ + else return NULL; /* error before creating state! */ + } + return block; +} + + diff --git a/build/premake/src/Src/Lua/lmem.h b/build/premake/src/Src/Lua/lmem.h new file mode 100644 index 0000000000..14ae7bc643 --- /dev/null +++ b/build/premake/src/Src/Lua/lmem.h @@ -0,0 +1,42 @@ +/* +** $Id: lmem.h,v 1.1 2003/01/24 16:26:07 jason379 Exp $ +** Interface to Memory Manager +** See Copyright Notice in lua.h +*/ + +#ifndef lmem_h +#define lmem_h + + +#include + +#include "llimits.h" +#include "lua.h" + +void *luaM_realloc (lua_State *L, void *oldblock, lint32 size); +void *luaM_growaux (lua_State *L, void *block, size_t nelems, + int inc, size_t size, const char *errormsg, + size_t limit); + +#define luaM_free(L, b) luaM_realloc(L, (b), 0) +#define luaM_malloc(L, t) luaM_realloc(L, NULL, (t)) +#define luaM_new(L, t) ((t *)luaM_malloc(L, sizeof(t))) +#define luaM_newvector(L, n,t) ((t *)luaM_malloc(L, (n)*(lint32)sizeof(t))) + +#define luaM_growvector(L, v,nelems,inc,t,e,l) \ + ((v)=(t *)luaM_growaux(L, v,nelems,inc,sizeof(t),e,l)) + +#define luaM_reallocvector(L, v,n,t) \ + ((v)=(t *)luaM_realloc(L, v,(n)*(lint32)sizeof(t))) + + +#ifdef LUA_DEBUG +extern unsigned long memdebug_numblocks; +extern unsigned long memdebug_total; +extern unsigned long memdebug_maxmem; +extern unsigned long memdebug_memlimit; +#endif + + +#endif + diff --git a/build/premake/src/Src/Lua/lobject.c b/build/premake/src/Src/Lua/lobject.c new file mode 100644 index 0000000000..de8438285c --- /dev/null +++ b/build/premake/src/Src/Lua/lobject.c @@ -0,0 +1,125 @@ +/* +** $Id: lobject.c,v 1.1 2003/01/24 16:26:09 jason379 Exp $ +** Some generic functions over Lua objects +** See Copyright Notice in lua.h +*/ + +#include +#include +#include +#include +#include + +#include "lua.h" + +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" + + + +const TObject luaO_nilobject = {LUA_TNIL, {NULL}}; + + +const char *const luaO_typenames[] = { + "userdata", "nil", "number", "string", "table", "function" +}; + + + +/* +** returns smaller power of 2 larger than `n' (minimum is MINPOWER2) +*/ +lint32 luaO_power2 (lint32 n) { + lint32 p = MINPOWER2; + while (p<=n) p<<=1; + return p; +} + + +int luaO_equalObj (const TObject *t1, const TObject *t2) { + if (ttype(t1) != ttype(t2)) return 0; + switch (ttype(t1)) { + case LUA_TNUMBER: + return nvalue(t1) == nvalue(t2); + case LUA_TSTRING: case LUA_TUSERDATA: + return tsvalue(t1) == tsvalue(t2); + case LUA_TTABLE: + return hvalue(t1) == hvalue(t2); + case LUA_TFUNCTION: + return clvalue(t1) == clvalue(t2); + default: + LUA_ASSERT(ttype(t1) == LUA_TNIL, "invalid type"); + return 1; /* LUA_TNIL */ + } +} + + +char *luaO_openspace (lua_State *L, size_t n) { + if (n > L->Mbuffsize) { + luaM_reallocvector(L, L->Mbuffer, n, char); + L->nblocks += (n - L->Mbuffsize)*sizeof(char); + L->Mbuffsize = n; + } + return L->Mbuffer; +} + + +int luaO_str2d (const char *s, Number *result) { /* LUA_NUMBER */ + char *endptr; + Number res = lua_str2number(s, &endptr); + if (endptr == s) return 0; /* no conversion */ + while (isspace((unsigned char)*endptr)) endptr++; + if (*endptr != '\0') return 0; /* invalid trailing characters? */ + *result = res; + return 1; +} + + +/* maximum length of a string format for `luaO_verror' */ +#define MAX_VERROR 280 + +/* this function needs to handle only '%d' and '%.XXs' formats */ +void luaO_verror (lua_State *L, const char *fmt, ...) { + va_list argp; + char buff[MAX_VERROR]; /* to hold formatted message */ + va_start(argp, fmt); + vsprintf(buff, fmt, argp); + va_end(argp); + lua_error(L, buff); +} + + +void luaO_chunkid (char *out, const char *source, int bufflen) { + if (*source == '=') { + strncpy(out, source+1, bufflen); /* remove first char */ + out[bufflen-1] = '\0'; /* ensures null termination */ + } + else { + if (*source == '@') { + int l; + source++; /* skip the `@' */ + bufflen -= sizeof("file `...%s'"); + l = strlen(source); + if (l>bufflen) { + source += (l-bufflen); /* get last part of file name */ + sprintf(out, "file `...%.99s'", source); + } + else + sprintf(out, "file `%.99s'", source); + } + else { + int len = strcspn(source, "\n"); /* stop at first newline */ + bufflen -= sizeof("string \"%.*s...\""); + if (len > bufflen) len = bufflen; + if (source[len] != '\0') { /* must truncate? */ + strcpy(out, "string \""); + out += strlen(out); + strncpy(out, source, len); + strcpy(out+len, "...\""); + } + else + sprintf(out, "string \"%.99s\"", source); + } + } +} diff --git a/build/premake/src/Src/Lua/lobject.h b/build/premake/src/Src/Lua/lobject.h new file mode 100644 index 0000000000..8d46d5ee18 --- /dev/null +++ b/build/premake/src/Src/Lua/lobject.h @@ -0,0 +1,204 @@ +/* +** $Id: lobject.h,v 1.1 2003/01/24 16:26:09 jason379 Exp $ +** Type definitions for Lua objects +** See Copyright Notice in lua.h +*/ + +#ifndef lobject_h +#define lobject_h + + +#include "llimits.h" +#include "lua.h" + + +#ifdef LUA_DEBUG +#undef NDEBUG +#include +#define LUA_INTERNALERROR(s) assert(((void)s,0)) +#define LUA_ASSERT(c,s) assert(((void)s,(c))) +#else +#define LUA_INTERNALERROR(s) /* empty */ +#define LUA_ASSERT(c,s) /* empty */ +#endif + + +#ifdef LUA_DEBUG +/* to avoid warnings, and make sure value is really unused */ +#define UNUSED(x) (x=0, (void)(x)) +#else +#define UNUSED(x) ((void)(x)) /* to avoid warnings */ +#endif + + +/* mark for closures active in the stack */ +#define LUA_TMARK 6 + + +/* tags for values visible from Lua == first user-created tag */ +#define NUM_TAGS 6 + + +/* check whether `t' is a mark */ +#define is_T_MARK(t) ((t) == LUA_TMARK) + + +typedef union { + struct TString *ts; /* LUA_TSTRING, LUA_TUSERDATA */ + struct Closure *cl; /* LUA_TFUNCTION */ + struct Hash *a; /* LUA_TTABLE */ + struct CallInfo *i; /* LUA_TLMARK */ + Number n; /* LUA_TNUMBER */ +} Value; + + +/* Macros to access values */ +#define ttype(o) ((o)->ttype) +#define nvalue(o) ((o)->value.n) +#define tsvalue(o) ((o)->value.ts) +#define clvalue(o) ((o)->value.cl) +#define hvalue(o) ((o)->value.a) +#define infovalue(o) ((o)->value.i) +#define svalue(o) (tsvalue(o)->str) + + +typedef struct lua_TObject { + int ttype; + Value value; +} TObject; + + +/* +** String headers for string table +*/ + +/* +** most `malloc' libraries allocate memory in blocks of 8 bytes. TSPACK +** tries to make sizeof(TString) a multiple of this granularity, to reduce +** waste of space. +*/ +#define TSPACK ((int)sizeof(int)) + +typedef struct TString { + union { + struct { /* for strings */ + unsigned long hash; + int constindex; /* hint to reuse constants */ + } s; + struct { /* for userdata */ + int tag; + void *value; + } d; + } u; + size_t len; + struct TString *nexthash; /* chain for hash table */ + int marked; + char str[TSPACK]; /* variable length string!! must be the last field! */ +} TString; + + +/* +** Function Prototypes +*/ +typedef struct Proto { + Number *knum; /* Number numbers used by the function */ + int nknum; /* size of `knum' */ + struct TString **kstr; /* strings used by the function */ + int nkstr; /* size of `kstr' */ + struct Proto **kproto; /* functions defined inside the function */ + int nkproto; /* size of `kproto' */ + Instruction *code; + int ncode; /* size of `code'; when 0 means an incomplete `Proto' */ + short numparams; + short is_vararg; + short maxstacksize; + short marked; + struct Proto *next; + /* debug information */ + int *lineinfo; /* map from opcodes to source lines */ + int nlineinfo; /* size of `lineinfo' */ + int nlocvars; + struct LocVar *locvars; /* information about local variables */ + int lineDefined; + TString *source; +} Proto; + + +typedef struct LocVar { + TString *varname; + int startpc; /* first point where variable is active */ + int endpc; /* first point where variable is dead */ +} LocVar; + + +/* +** Closures +*/ +typedef struct Closure { + union { + lua_CFunction c; /* C functions */ + struct Proto *l; /* Lua functions */ + } f; + struct Closure *next; + struct Closure *mark; /* marked closures (point to itself when not marked) */ + short isC; /* 0 for Lua functions, 1 for C functions */ + short nupvalues; + TObject upvalue[1]; +} Closure; + + +#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->isC) + + +typedef struct Node { + TObject key; + TObject val; + struct Node *next; /* for chaining */ +} Node; + +typedef struct Hash { + Node *node; + int htag; + int size; + Node *firstfree; /* this position is free; all positions after it are full */ + struct Hash *next; + struct Hash *mark; /* marked tables (point to itself when not marked) */ +} Hash; + + +/* unmarked tables and closures are represented by pointing `mark' to +** themselves +*/ +#define ismarked(x) ((x)->mark != (x)) + + +/* +** informations about a call (for debugging) +*/ +typedef struct CallInfo { + struct Closure *func; /* function being called */ + const Instruction **pc; /* current pc of called function */ + int lastpc; /* last pc traced */ + int line; /* current line */ + int refi; /* current index in `lineinfo' */ +} CallInfo; + + +extern const TObject luaO_nilobject; +extern const char *const luaO_typenames[]; + + +#define luaO_typename(o) (luaO_typenames[ttype(o)]) + + +lint32 luaO_power2 (lint32 n); +char *luaO_openspace (lua_State *L, size_t n); + +int luaO_equalObj (const TObject *t1, const TObject *t2); +int luaO_str2d (const char *s, Number *result); + +void luaO_verror (lua_State *L, const char *fmt, ...); +void luaO_chunkid (char *out, const char *source, int len); + + +#endif diff --git a/build/premake/src/Src/Lua/lopcodes.h b/build/premake/src/Src/Lua/lopcodes.h new file mode 100644 index 0000000000..9213c26918 --- /dev/null +++ b/build/premake/src/Src/Lua/lopcodes.h @@ -0,0 +1,168 @@ +/* +** $Id: lopcodes.h,v 1.1 2003/01/24 16:26:10 jason379 Exp $ +** Opcodes for Lua virtual machine +** See Copyright Notice in lua.h +*/ + +#ifndef lopcodes_h +#define lopcodes_h + +#include "llimits.h" + + +/*=========================================================================== + We assume that instructions are unsigned numbers. + All instructions have an opcode in the first 6 bits. Moreover, + an instruction can have 0, 1, or 2 arguments. Instructions can + have the following types: + type 0: no arguments + type 1: 1 unsigned argument in the higher bits (called `U') + type 2: 1 signed argument in the higher bits (`S') + type 3: 1st unsigned argument in the higher bits (`A') + 2nd unsigned argument in the middle bits (`B') + + A signed argument is represented in excess K; that is, the number + value is the unsigned value minus K. K is exactly the maximum value + for that argument (so that -max is represented by 0, and +max is + represented by 2*max), which is half the maximum for the corresponding + unsigned argument. + + The size of each argument is defined in `llimits.h'. The usual is an + instruction with 32 bits, U arguments with 26 bits (32-6), B arguments + with 9 bits, and A arguments with 17 bits (32-6-9). For small + installations, the instruction size can be 16, so U has 10 bits, + and A and B have 5 bits each. +===========================================================================*/ + + + + +/* creates a mask with `n' 1 bits at position `p' */ +#define MASK1(n,p) ((~((~(Instruction)0)<>POS_U)) +#define SETARG_U(i,u) ((i) = (((i)&MASK0(SIZE_U,POS_U)) | \ + ((Instruction)(u)<>POS_A)) +#define SETARG_A(i,a) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \ + ((Instruction)(a)<>POS_B) & MASK1(SIZE_B,0))) +#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \ + ((Instruction)(b)<y)? PC+=s */ +OP_JMPGE,/* J y x - (x>=y)? PC+=s */ + +OP_JMPT,/* J x - (x~=nil)? PC+=s */ +OP_JMPF,/* J x - (x==nil)? PC+=s */ +OP_JMPONT,/* J x (x~=nil)? x : - (x~=nil)? PC+=s */ +OP_JMPONF,/* J x (x==nil)? x : - (x==nil)? PC+=s */ +OP_JMP,/* J - - PC+=s */ + +OP_PUSHNILJMP,/* - - nil PC++; */ + +OP_FORPREP,/* J */ +OP_FORLOOP,/* J */ + +OP_LFORPREP,/* J */ +OP_LFORLOOP,/* J */ + +OP_CLOSURE/* A B v_b-v_1 closure(KPROTO[a], v_1-v_b) */ + +} OpCode; + +#define NUM_OPCODES ((int)OP_CLOSURE+1) + + +#define ISJUMP(o) (OP_JMPNE <= (o) && (o) <= OP_JMP) + + + +/* special code to fit a LUA_MULTRET inside an argB */ +#define MULT_RET 255 /* (<=MAXARG_B) */ +#if MULT_RET>MAXARG_B +#undef MULT_RET +#define MULT_RET MAXARG_B +#endif + + +#endif diff --git a/build/premake/src/Src/Lua/lparser.c b/build/premake/src/Src/Lua/lparser.c new file mode 100644 index 0000000000..faf9f2d475 --- /dev/null +++ b/build/premake/src/Src/Lua/lparser.c @@ -0,0 +1,1124 @@ +/* +** $Id: lparser.c,v 1.1 2003/01/24 16:26:11 jason379 Exp $ +** LL(1) Parser and code generator for Lua +** See Copyright Notice in lua.h +*/ + + +#include +#include + +#include "lua.h" + +#include "lcode.h" +#include "lfunc.h" +#include "llex.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" + + +/* +** Constructors descriptor: +** `n' indicates number of elements, and `k' signals whether +** it is a list constructor (k = 0) or a record constructor (k = 1) +** or empty (k = ';' or '}') +*/ +typedef struct Constdesc { + int n; + int k; +} Constdesc; + + +typedef struct Breaklabel { + struct Breaklabel *previous; /* chain */ + int breaklist; + int stacklevel; +} Breaklabel; + + + + +/* +** prototypes for recursive non-terminal functions +*/ +static void body (LexState *ls, int needself, int line); +static void chunk (LexState *ls); +static void constructor (LexState *ls); +static void expr (LexState *ls, expdesc *v); +static void exp1 (LexState *ls); + + + +static void next (LexState *ls) { + ls->lastline = ls->linenumber; + if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */ + ls->t = ls->lookahead; /* use this one */ + ls->lookahead.token = TK_EOS; /* and discharge it */ + } + else + ls->t.token = luaX_lex(ls, &ls->t.seminfo); /* read next token */ +} + + +static void lookahead (LexState *ls) { + LUA_ASSERT(ls->lookahead.token == TK_EOS, "two look-aheads"); + ls->lookahead.token = luaX_lex(ls, &ls->lookahead.seminfo); +} + + +static void error_expected (LexState *ls, int token) { + char buff[100], t[TOKEN_LEN]; + luaX_token2str(token, t); + sprintf(buff, "`%.20s' expected", t); + luaK_error(ls, buff); +} + + +static void check (LexState *ls, int c) { + if (ls->t.token != c) + error_expected(ls, c); + next(ls); +} + + +static void check_condition (LexState *ls, int c, const char *msg) { + if (!c) luaK_error(ls, msg); +} + + +static int optional (LexState *ls, int c) { + if (ls->t.token == c) { + next(ls); + return 1; + } + else return 0; +} + + +static void check_match (LexState *ls, int what, int who, int where) { + if (ls->t.token != what) { + if (where == ls->linenumber) + error_expected(ls, what); + else { + char buff[100]; + char t_what[TOKEN_LEN], t_who[TOKEN_LEN]; + luaX_token2str(what, t_what); + luaX_token2str(who, t_who); + sprintf(buff, "`%.20s' expected (to close `%.20s' at line %d)", + t_what, t_who, where); + luaK_error(ls, buff); + } + } + next(ls); +} + + +static int string_constant (FuncState *fs, TString *s) { + Proto *f = fs->f; + int c = s->u.s.constindex; + if (c >= f->nkstr || f->kstr[c] != s) { + luaM_growvector(fs->L, f->kstr, f->nkstr, 1, TString *, + "constant table overflow", MAXARG_U); + c = f->nkstr++; + f->kstr[c] = s; + s->u.s.constindex = c; /* hint for next time */ + } + return c; +} + + +static void code_string (LexState *ls, TString *s) { + luaK_kstr(ls, string_constant(ls->fs, s)); +} + + +static TString *str_checkname (LexState *ls) { + TString *ts; + check_condition(ls, (ls->t.token == TK_NAME), " expected"); + ts = ls->t.seminfo.ts; + next(ls); + return ts; +} + + +static int checkname (LexState *ls) { + return string_constant(ls->fs, str_checkname(ls)); +} + + +static int luaI_registerlocalvar (LexState *ls, TString *varname) { + Proto *f = ls->fs->f; + luaM_growvector(ls->L, f->locvars, f->nlocvars, 1, LocVar, "", MAX_INT); + f->locvars[f->nlocvars].varname = varname; + return f->nlocvars++; +} + + +static void new_localvar (LexState *ls, TString *name, int n) { + FuncState *fs = ls->fs; + luaX_checklimit(ls, fs->nactloc+n+1, MAXLOCALS, "local variables"); + fs->actloc[fs->nactloc+n] = luaI_registerlocalvar(ls, name); +} + + +static void adjustlocalvars (LexState *ls, int nvars) { + FuncState *fs = ls->fs; + while (nvars--) + fs->f->locvars[fs->actloc[fs->nactloc++]].startpc = fs->pc; +} + + +static void removelocalvars (LexState *ls, int nvars) { + FuncState *fs = ls->fs; + while (nvars--) + fs->f->locvars[fs->actloc[--fs->nactloc]].endpc = fs->pc; +} + + +static void new_localvarstr (LexState *ls, const char *name, int n) { + new_localvar(ls, luaS_newfixed(ls->L, name), n); +} + + +static int search_local (LexState *ls, TString *n, expdesc *var) { + FuncState *fs; + int level = 0; + for (fs=ls->fs; fs; fs=fs->prev) { + int i; + for (i=fs->nactloc-1; i >= 0; i--) { + if (n == fs->f->locvars[fs->actloc[i]].varname) { + var->k = VLOCAL; + var->u.index = i; + return level; + } + } + level++; /* `var' not found; check outer level */ + } + var->k = VGLOBAL; /* not found in any level; must be global */ + return -1; +} + + +static void singlevar (LexState *ls, TString *n, expdesc *var) { + int level = search_local(ls, n, var); + if (level >= 1) /* neither local (0) nor global (-1)? */ + luaX_syntaxerror(ls, "cannot access a variable in outer scope", n->str); + else if (level == -1) /* global? */ + var->u.index = string_constant(ls->fs, n); +} + + +static int indexupvalue (LexState *ls, expdesc *v) { + FuncState *fs = ls->fs; + int i; + for (i=0; inupvalues; i++) { + if (fs->upvalues[i].k == v->k && fs->upvalues[i].u.index == v->u.index) + return i; + } + /* new one */ + luaX_checklimit(ls, fs->nupvalues+1, MAXUPVALUES, "upvalues"); + fs->upvalues[fs->nupvalues] = *v; + return fs->nupvalues++; +} + + +static void pushupvalue (LexState *ls, TString *n) { + FuncState *fs = ls->fs; + expdesc v; + int level = search_local(ls, n, &v); + if (level == -1) { /* global? */ + if (fs->prev == NULL) + luaX_syntaxerror(ls, "cannot access upvalue in main", n->str); + v.u.index = string_constant(fs->prev, n); + } + else if (level != 1) + luaX_syntaxerror(ls, + "upvalue must be global or local to immediately outer scope", n->str); + luaK_code1(fs, OP_PUSHUPVALUE, indexupvalue(ls, &v)); +} + + +static void adjust_mult_assign (LexState *ls, int nvars, int nexps) { + FuncState *fs = ls->fs; + int diff = nexps - nvars; + if (nexps > 0 && luaK_lastisopen(fs)) { /* list ends in a function call */ + diff--; /* do not count function call itself */ + if (diff <= 0) { /* more variables than values? */ + luaK_setcallreturns(fs, -diff); /* function call provide extra values */ + diff = 0; /* no more difference */ + } + else /* more values than variables */ + luaK_setcallreturns(fs, 0); /* call should provide no value */ + } + /* push or pop eventual difference between list lengths */ + luaK_adjuststack(fs, diff); +} + + +static void code_params (LexState *ls, int nparams, int dots) { + FuncState *fs = ls->fs; + adjustlocalvars(ls, nparams); + luaX_checklimit(ls, fs->nactloc, MAXPARAMS, "parameters"); + fs->f->numparams = fs->nactloc; /* `self' could be there already */ + fs->f->is_vararg = dots; + if (dots) { + new_localvarstr(ls, "arg", 0); + adjustlocalvars(ls, 1); + } + luaK_deltastack(fs, fs->nactloc); /* count parameters in the stack */ +} + + +static void enterbreak (FuncState *fs, Breaklabel *bl) { + bl->stacklevel = fs->stacklevel; + bl->breaklist = NO_JUMP; + bl->previous = fs->bl; + fs->bl = bl; +} + + +static void leavebreak (FuncState *fs, Breaklabel *bl) { + fs->bl = bl->previous; + LUA_ASSERT(bl->stacklevel == fs->stacklevel, "wrong levels"); + luaK_patchlist(fs, bl->breaklist, luaK_getlabel(fs)); +} + + +static void pushclosure (LexState *ls, FuncState *func) { + FuncState *fs = ls->fs; + Proto *f = fs->f; + int i; + for (i=0; inupvalues; i++) + luaK_tostack(ls, &func->upvalues[i], 1); + luaM_growvector(ls->L, f->kproto, f->nkproto, 1, Proto *, + "constant table overflow", MAXARG_A); + f->kproto[f->nkproto++] = func->f; + luaK_code2(fs, OP_CLOSURE, f->nkproto-1, func->nupvalues); +} + + +static void open_func (LexState *ls, FuncState *fs) { + Proto *f = luaF_newproto(ls->L); + fs->prev = ls->fs; /* linked list of funcstates */ + fs->ls = ls; + fs->L = ls->L; + ls->fs = fs; + fs->stacklevel = 0; + fs->nactloc = 0; + fs->nupvalues = 0; + fs->bl = NULL; + fs->f = f; + f->source = ls->source; + fs->pc = 0; + fs->lasttarget = 0; + fs->lastline = 0; + fs->jlt = NO_JUMP; + f->code = NULL; + f->maxstacksize = 0; + f->numparams = 0; /* default for main chunk */ + f->is_vararg = 0; /* default for main chunk */ +} + + +static void close_func (LexState *ls) { + lua_State *L = ls->L; + FuncState *fs = ls->fs; + Proto *f = fs->f; + luaK_code0(fs, OP_END); + luaK_getlabel(fs); /* close eventual list of pending jumps */ + luaM_reallocvector(L, f->code, fs->pc, Instruction); + luaM_reallocvector(L, f->kstr, f->nkstr, TString *); + luaM_reallocvector(L, f->knum, f->nknum, Number); + luaM_reallocvector(L, f->kproto, f->nkproto, Proto *); + removelocalvars(ls, fs->nactloc); + luaM_reallocvector(L, f->locvars, f->nlocvars, LocVar); + luaM_reallocvector(L, f->lineinfo, f->nlineinfo+1, int); + f->lineinfo[f->nlineinfo++] = MAX_INT; /* end flag */ + luaF_protook(L, f, fs->pc); /* proto is ok now */ + ls->fs = fs->prev; + LUA_ASSERT(fs->bl == NULL, "wrong list end"); +} + + +Proto *luaY_parser (lua_State *L, ZIO *z) { + struct LexState lexstate; + struct FuncState funcstate; + luaX_setinput(L, &lexstate, z, luaS_new(L, zname(z))); + open_func(&lexstate, &funcstate); + next(&lexstate); /* read first token */ + chunk(&lexstate); + check_condition(&lexstate, (lexstate.t.token == TK_EOS), " expected"); + close_func(&lexstate); + LUA_ASSERT(funcstate.prev == NULL, "wrong list end"); + LUA_ASSERT(funcstate.nupvalues == 0, "no upvalues in main"); + return funcstate.f; +} + + + +/*============================================================*/ +/* GRAMMAR RULES */ +/*============================================================*/ + + +static int explist1 (LexState *ls) { + /* explist1 -> expr { ',' expr } */ + int n = 1; /* at least one expression */ + expdesc v; + expr(ls, &v); + while (ls->t.token == ',') { + luaK_tostack(ls, &v, 1); /* gets only 1 value from previous expression */ + next(ls); /* skip comma */ + expr(ls, &v); + n++; + } + luaK_tostack(ls, &v, 0); /* keep open number of values of last expression */ + return n; +} + + +static void funcargs (LexState *ls, int slf) { + FuncState *fs = ls->fs; + int slevel = fs->stacklevel - slf - 1; /* where is func in the stack */ + switch (ls->t.token) { + case '(': { /* funcargs -> '(' [ explist1 ] ')' */ + int line = ls->linenumber; + int nargs = 0; + next(ls); + if (ls->t.token != ')') /* arg list not empty? */ + nargs = explist1(ls); + check_match(ls, ')', '(', line); +#ifdef LUA_COMPAT_ARGRET + if (nargs > 0) /* arg list is not empty? */ + luaK_setcallreturns(fs, 1); /* last call returns only 1 value */ +#else + UNUSED(nargs); /* to avoid warnings */ +#endif + break; + } + case '{': { /* funcargs -> constructor */ + constructor(ls); + break; + } + case TK_STRING: { /* funcargs -> STRING */ + code_string(ls, ls->t.seminfo.ts); /* must use `seminfo' before `next' */ + next(ls); + break; + } + default: { + luaK_error(ls, "function arguments expected"); + break; + } + } + fs->stacklevel = slevel; /* call will remove function and arguments */ + luaK_code2(fs, OP_CALL, slevel, MULT_RET); +} + + +static void var_or_func_tail (LexState *ls, expdesc *v) { + for (;;) { + switch (ls->t.token) { + case '.': { /* var_or_func_tail -> '.' NAME */ + next(ls); + luaK_tostack(ls, v, 1); /* `v' must be on stack */ + luaK_kstr(ls, checkname(ls)); + v->k = VINDEXED; + break; + } + case '[': { /* var_or_func_tail -> '[' exp1 ']' */ + next(ls); + luaK_tostack(ls, v, 1); /* `v' must be on stack */ + v->k = VINDEXED; + exp1(ls); + check(ls, ']'); + break; + } + case ':': { /* var_or_func_tail -> ':' NAME funcargs */ + int name; + next(ls); + name = checkname(ls); + luaK_tostack(ls, v, 1); /* `v' must be on stack */ + luaK_code1(ls->fs, OP_PUSHSELF, name); + funcargs(ls, 1); + v->k = VEXP; + v->u.l.t = v->u.l.f = NO_JUMP; + break; + } + case '(': case TK_STRING: case '{': { /* var_or_func_tail -> funcargs */ + luaK_tostack(ls, v, 1); /* `v' must be on stack */ + funcargs(ls, 0); + v->k = VEXP; + v->u.l.t = v->u.l.f = NO_JUMP; + break; + } + default: return; /* should be follow... */ + } + } +} + + +static void var_or_func (LexState *ls, expdesc *v) { + /* var_or_func -> ['%'] NAME var_or_func_tail */ + if (optional(ls, '%')) { /* upvalue? */ + pushupvalue(ls, str_checkname(ls)); + v->k = VEXP; + v->u.l.t = v->u.l.f = NO_JUMP; + } + else /* variable name */ + singlevar(ls, str_checkname(ls), v); + var_or_func_tail(ls, v); +} + + + +/* +** {====================================================================== +** Rules for Constructors +** ======================================================================= +*/ + + +static void recfield (LexState *ls) { + /* recfield -> (NAME | '['exp1']') = exp1 */ + switch (ls->t.token) { + case TK_NAME: { + luaK_kstr(ls, checkname(ls)); + break; + } + case '[': { + next(ls); + exp1(ls); + check(ls, ']'); + break; + } + default: luaK_error(ls, " or `[' expected"); + } + check(ls, '='); + exp1(ls); +} + + +static int recfields (LexState *ls) { + /* recfields -> recfield { ',' recfield } [','] */ + FuncState *fs = ls->fs; + int n = 1; /* at least one element */ + recfield(ls); + while (ls->t.token == ',') { + next(ls); + if (ls->t.token == ';' || ls->t.token == '}') + break; + recfield(ls); + n++; + if (n%RFIELDS_PER_FLUSH == 0) + luaK_code1(fs, OP_SETMAP, RFIELDS_PER_FLUSH); + } + luaK_code1(fs, OP_SETMAP, n%RFIELDS_PER_FLUSH); + return n; +} + + +static int listfields (LexState *ls) { + /* listfields -> exp1 { ',' exp1 } [','] */ + FuncState *fs = ls->fs; + int n = 1; /* at least one element */ + exp1(ls); + while (ls->t.token == ',') { + next(ls); + if (ls->t.token == ';' || ls->t.token == '}') + break; + exp1(ls); + n++; + luaX_checklimit(ls, n/LFIELDS_PER_FLUSH, MAXARG_A, + "`item groups' in a list initializer"); + if (n%LFIELDS_PER_FLUSH == 0) + luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH); + } + luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH, n%LFIELDS_PER_FLUSH); + return n; +} + + + +static void constructor_part (LexState *ls, Constdesc *cd) { + switch (ls->t.token) { + case ';': case '}': { /* constructor_part -> empty */ + cd->n = 0; + cd->k = ls->t.token; + break; + } + case TK_NAME: { /* may be listfields or recfields */ + lookahead(ls); + if (ls->lookahead.token != '=') /* expression? */ + goto case_default; + /* else go through to recfields */ + } + case '[': { /* constructor_part -> recfields */ + cd->n = recfields(ls); + cd->k = 1; /* record */ + break; + } + default: { /* constructor_part -> listfields */ + case_default: + cd->n = listfields(ls); + cd->k = 0; /* list */ + break; + } + } +} + + +static void constructor (LexState *ls) { + /* constructor -> '{' constructor_part [';' constructor_part] '}' */ + FuncState *fs = ls->fs; + int line = ls->linenumber; + int pc = luaK_code1(fs, OP_CREATETABLE, 0); + int nelems; + Constdesc cd; + check(ls, '{'); + constructor_part(ls, &cd); + nelems = cd.n; + if (optional(ls, ';')) { + Constdesc other_cd; + constructor_part(ls, &other_cd); + check_condition(ls, (cd.k != other_cd.k), "invalid constructor syntax"); + nelems += other_cd.n; + } + check_match(ls, '}', '{', line); + luaX_checklimit(ls, nelems, MAXARG_U, "elements in a table constructor"); + SETARG_U(fs->f->code[pc], nelems); /* set initial table size */ +} + +/* }====================================================================== */ + + + + +/* +** {====================================================================== +** Expression parsing +** ======================================================================= +*/ + + +static void simpleexp (LexState *ls, expdesc *v) { + FuncState *fs = ls->fs; + switch (ls->t.token) { + case TK_NUMBER: { /* simpleexp -> NUMBER */ + Number r = ls->t.seminfo.r; + next(ls); + luaK_number(fs, r); + break; + } + case TK_STRING: { /* simpleexp -> STRING */ + code_string(ls, ls->t.seminfo.ts); /* must use `seminfo' before `next' */ + next(ls); + break; + } + case TK_NIL: { /* simpleexp -> NIL */ + luaK_adjuststack(fs, -1); + next(ls); + break; + } + case '{': { /* simpleexp -> constructor */ + constructor(ls); + break; + } + case TK_FUNCTION: { /* simpleexp -> FUNCTION body */ + next(ls); + body(ls, 0, ls->linenumber); + break; + } + case '(': { /* simpleexp -> '(' expr ')' */ + next(ls); + expr(ls, v); + check(ls, ')'); + return; + } + case TK_NAME: case '%': { + var_or_func(ls, v); + return; + } + default: { + luaK_error(ls, " expected"); + return; + } + } + v->k = VEXP; + v->u.l.t = v->u.l.f = NO_JUMP; +} + + +static void exp1 (LexState *ls) { + expdesc v; + expr(ls, &v); + luaK_tostack(ls, &v, 1); +} + + +static UnOpr getunopr (int op) { + switch (op) { + case TK_NOT: return OPR_NOT; + case '-': return OPR_MINUS; + default: return OPR_NOUNOPR; + } +} + + +static BinOpr getbinopr (int op) { + switch (op) { + case '+': return OPR_ADD; + case '-': return OPR_SUB; + case '*': return OPR_MULT; + case '/': return OPR_DIV; + case '^': return OPR_POW; + case TK_CONCAT: return OPR_CONCAT; + case TK_NE: return OPR_NE; + case TK_EQ: return OPR_EQ; + case '<': return OPR_LT; + case TK_LE: return OPR_LE; + case '>': return OPR_GT; + case TK_GE: return OPR_GE; + case TK_AND: return OPR_AND; + case TK_OR: return OPR_OR; + default: return OPR_NOBINOPR; + } +} + + +static const struct { + char left; /* left priority for each binary operator */ + char right; /* right priority */ +} priority[] = { /* ORDER OPR */ + {5, 5}, {5, 5}, {6, 6}, {6, 6}, /* arithmetic */ + {9, 8}, {4, 3}, /* power and concat (right associative) */ + {2, 2}, {2, 2}, /* equality */ + {2, 2}, {2, 2}, {2, 2}, {2, 2}, /* order */ + {1, 1}, {1, 1} /* logical */ +}; + +#define UNARY_PRIORITY 7 /* priority for unary operators */ + + +/* +** subexpr -> (simplexep | unop subexpr) { binop subexpr } +** where `binop' is any binary operator with a priority higher than `limit' +*/ +static BinOpr subexpr (LexState *ls, expdesc *v, int limit) { + BinOpr op; + UnOpr uop = getunopr(ls->t.token); + if (uop != OPR_NOUNOPR) { + next(ls); + subexpr(ls, v, UNARY_PRIORITY); + luaK_prefix(ls, uop, v); + } + else simpleexp(ls, v); + /* expand while operators have priorities higher than `limit' */ + op = getbinopr(ls->t.token); + while (op != OPR_NOBINOPR && priority[op].left > limit) { + expdesc v2; + BinOpr nextop; + next(ls); + luaK_infix(ls, op, v); + /* read sub-expression with higher priority */ + nextop = subexpr(ls, &v2, priority[op].right); + luaK_posfix(ls, op, v, &v2); + op = nextop; + } + return op; /* return first untreated operator */ +} + + +static void expr (LexState *ls, expdesc *v) { + subexpr(ls, v, -1); +} + +/* }==================================================================== */ + + +/* +** {====================================================================== +** Rules for Statements +** ======================================================================= +*/ + + +static int block_follow (int token) { + switch (token) { + case TK_ELSE: case TK_ELSEIF: case TK_END: + case TK_UNTIL: case TK_EOS: + return 1; + default: return 0; + } +} + + +static void block (LexState *ls) { + /* block -> chunk */ + FuncState *fs = ls->fs; + int nactloc = fs->nactloc; + chunk(ls); + luaK_adjuststack(fs, fs->nactloc - nactloc); /* remove local variables */ + removelocalvars(ls, fs->nactloc - nactloc); +} + + +static int assignment (LexState *ls, expdesc *v, int nvars) { + int left = 0; /* number of values left in the stack after assignment */ + luaX_checklimit(ls, nvars, MAXVARSLH, "variables in a multiple assignment"); + if (ls->t.token == ',') { /* assignment -> ',' NAME assignment */ + expdesc nv; + next(ls); + var_or_func(ls, &nv); + check_condition(ls, (nv.k != VEXP), "syntax error"); + left = assignment(ls, &nv, nvars+1); + } + else { /* assignment -> '=' explist1 */ + int nexps; + check(ls, '='); + nexps = explist1(ls); + adjust_mult_assign(ls, nvars, nexps); + } + if (v->k != VINDEXED) + luaK_storevar(ls, v); + else { /* there may be garbage between table-index and value */ + luaK_code2(ls->fs, OP_SETTABLE, left+nvars+2, 1); + left += 2; + } + return left; +} + + +static void cond (LexState *ls, expdesc *v) { + /* cond -> exp */ + expr(ls, v); /* read condition */ + luaK_goiftrue(ls->fs, v, 0); +} + + +static void whilestat (LexState *ls, int line) { + /* whilestat -> WHILE cond DO block END */ + FuncState *fs = ls->fs; + int while_init = luaK_getlabel(fs); + expdesc v; + Breaklabel bl; + enterbreak(fs, &bl); + next(ls); + cond(ls, &v); + check(ls, TK_DO); + block(ls); + luaK_patchlist(fs, luaK_jump(fs), while_init); + luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs)); + check_match(ls, TK_END, TK_WHILE, line); + leavebreak(fs, &bl); +} + + +static void repeatstat (LexState *ls, int line) { + /* repeatstat -> REPEAT block UNTIL cond */ + FuncState *fs = ls->fs; + int repeat_init = luaK_getlabel(fs); + expdesc v; + Breaklabel bl; + enterbreak(fs, &bl); + next(ls); + block(ls); + check_match(ls, TK_UNTIL, TK_REPEAT, line); + cond(ls, &v); + luaK_patchlist(fs, v.u.l.f, repeat_init); + leavebreak(fs, &bl); +} + + +static void forbody (LexState *ls, int nvar, OpCode prepfor, OpCode loopfor) { + /* forbody -> DO block END */ + FuncState *fs = ls->fs; + int prep = luaK_code1(fs, prepfor, NO_JUMP); + int blockinit = luaK_getlabel(fs); + check(ls, TK_DO); + adjustlocalvars(ls, nvar); /* scope for control variables */ + block(ls); + luaK_patchlist(fs, luaK_code1(fs, loopfor, NO_JUMP), blockinit); + luaK_patchlist(fs, prep, luaK_getlabel(fs)); + removelocalvars(ls, nvar); +} + + +static void fornum (LexState *ls, TString *varname) { + /* fornum -> NAME = exp1,exp1[,exp1] forbody */ + FuncState *fs = ls->fs; + check(ls, '='); + exp1(ls); /* initial value */ + check(ls, ','); + exp1(ls); /* limit */ + if (optional(ls, ',')) + exp1(ls); /* optional step */ + else + luaK_code1(fs, OP_PUSHINT, 1); /* default step */ + new_localvar(ls, varname, 0); + new_localvarstr(ls, "(limit)", 1); + new_localvarstr(ls, "(step)", 2); + forbody(ls, 3, OP_FORPREP, OP_FORLOOP); +} + + +static void forlist (LexState *ls, TString *indexname) { + /* forlist -> NAME,NAME IN exp1 forbody */ + TString *valname; + check(ls, ','); + valname = str_checkname(ls); + /* next test is dirty, but avoids `in' being a reserved word */ + check_condition(ls, + (ls->t.token == TK_NAME && ls->t.seminfo.ts == luaS_new(ls->L, "in")), + "`in' expected"); + next(ls); /* skip `in' */ + exp1(ls); /* table */ + new_localvarstr(ls, "(table)", 0); + new_localvar(ls, indexname, 1); + new_localvar(ls, valname, 2); + forbody(ls, 3, OP_LFORPREP, OP_LFORLOOP); +} + + +static void forstat (LexState *ls, int line) { + /* forstat -> fornum | forlist */ + FuncState *fs = ls->fs; + TString *varname; + Breaklabel bl; + enterbreak(fs, &bl); + next(ls); /* skip `for' */ + varname = str_checkname(ls); /* first variable name */ + switch (ls->t.token) { + case '=': fornum(ls, varname); break; + case ',': forlist(ls, varname); break; + default: luaK_error(ls, "`=' or `,' expected"); + } + check_match(ls, TK_END, TK_FOR, line); + leavebreak(fs, &bl); +} + + +static void test_then_block (LexState *ls, expdesc *v) { + /* test_then_block -> [IF | ELSEIF] cond THEN block */ + next(ls); /* skip IF or ELSEIF */ + cond(ls, v); + check(ls, TK_THEN); + block(ls); /* `then' part */ +} + + +static void ifstat (LexState *ls, int line) { + /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ + FuncState *fs = ls->fs; + expdesc v; + int escapelist = NO_JUMP; + test_then_block(ls, &v); /* IF cond THEN block */ + while (ls->t.token == TK_ELSEIF) { + luaK_concat(fs, &escapelist, luaK_jump(fs)); + luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs)); + test_then_block(ls, &v); /* ELSEIF cond THEN block */ + } + if (ls->t.token == TK_ELSE) { + luaK_concat(fs, &escapelist, luaK_jump(fs)); + luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs)); + next(ls); /* skip ELSE */ + block(ls); /* `else' part */ + } + else + luaK_concat(fs, &escapelist, v.u.l.f); + luaK_patchlist(fs, escapelist, luaK_getlabel(fs)); + check_match(ls, TK_END, TK_IF, line); +} + + +static void localstat (LexState *ls) { + /* stat -> LOCAL NAME {',' NAME} ['=' explist1] */ + int nvars = 0; + int nexps; + do { + next(ls); /* skip LOCAL or ',' */ + new_localvar(ls, str_checkname(ls), nvars++); + } while (ls->t.token == ','); + if (optional(ls, '=')) + nexps = explist1(ls); + else + nexps = 0; + adjust_mult_assign(ls, nvars, nexps); + adjustlocalvars(ls, nvars); +} + + +static int funcname (LexState *ls, expdesc *v) { + /* funcname -> NAME [':' NAME | '.' NAME] */ + int needself = 0; + singlevar(ls, str_checkname(ls), v); + if (ls->t.token == ':' || ls->t.token == '.') { + needself = (ls->t.token == ':'); + next(ls); + luaK_tostack(ls, v, 1); + luaK_kstr(ls, checkname(ls)); + v->k = VINDEXED; + } + return needself; +} + + +static void funcstat (LexState *ls, int line) { + /* funcstat -> FUNCTION funcname body */ + int needself; + expdesc v; + next(ls); /* skip FUNCTION */ + needself = funcname(ls, &v); + body(ls, needself, line); + luaK_storevar(ls, &v); +} + + +static void namestat (LexState *ls) { + /* stat -> func | ['%'] NAME assignment */ + FuncState *fs = ls->fs; + expdesc v; + var_or_func(ls, &v); + if (v.k == VEXP) { /* stat -> func */ + check_condition(ls, luaK_lastisopen(fs), "syntax error"); /* an upvalue? */ + luaK_setcallreturns(fs, 0); /* call statement uses no results */ + } + else { /* stat -> ['%'] NAME assignment */ + int left = assignment(ls, &v, 1); + luaK_adjuststack(fs, left); /* remove eventual garbage left on stack */ + } +} + + +static void retstat (LexState *ls) { + /* stat -> RETURN explist */ + FuncState *fs = ls->fs; + next(ls); /* skip RETURN */ + if (!block_follow(ls->t.token) && ls->t.token != ';') + explist1(ls); /* optional return values */ + luaK_code1(fs, OP_RETURN, ls->fs->nactloc); + fs->stacklevel = fs->nactloc; /* removes all temp values */ +} + + +static void breakstat (LexState *ls) { + /* stat -> BREAK [NAME] */ + FuncState *fs = ls->fs; + int currentlevel = fs->stacklevel; + Breaklabel *bl = fs->bl; + if (!bl) + luaK_error(ls, "no loop to break"); + next(ls); /* skip BREAK */ + luaK_adjuststack(fs, currentlevel - bl->stacklevel); + luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); + /* correct stack for compiler and symbolic execution */ + luaK_adjuststack(fs, bl->stacklevel - currentlevel); +} + + +static int stat (LexState *ls) { + int line = ls->linenumber; /* may be needed for error messages */ + switch (ls->t.token) { + case TK_IF: { /* stat -> ifstat */ + ifstat(ls, line); + return 0; + } + case TK_WHILE: { /* stat -> whilestat */ + whilestat(ls, line); + return 0; + } + case TK_DO: { /* stat -> DO block END */ + next(ls); /* skip DO */ + block(ls); + check_match(ls, TK_END, TK_DO, line); + return 0; + } + case TK_FOR: { /* stat -> forstat */ + forstat(ls, line); + return 0; + } + case TK_REPEAT: { /* stat -> repeatstat */ + repeatstat(ls, line); + return 0; + } + case TK_FUNCTION: { /* stat -> funcstat */ + funcstat(ls, line); + return 0; + } + case TK_LOCAL: { /* stat -> localstat */ + localstat(ls); + return 0; + } + case TK_NAME: case '%': { /* stat -> namestat */ + namestat(ls); + return 0; + } + case TK_RETURN: { /* stat -> retstat */ + retstat(ls); + return 1; /* must be last statement */ + } + case TK_BREAK: { /* stat -> breakstat */ + breakstat(ls); + return 1; /* must be last statement */ + } + default: { + luaK_error(ls, " expected"); + return 0; /* to avoid warnings */ + } + } +} + + +static void parlist (LexState *ls) { + /* parlist -> [ param { ',' param } ] */ + int nparams = 0; + int dots = 0; + if (ls->t.token != ')') { /* is `parlist' not empty? */ + do { + switch (ls->t.token) { + case TK_DOTS: next(ls); dots = 1; break; + case TK_NAME: new_localvar(ls, str_checkname(ls), nparams++); break; + default: luaK_error(ls, " or `...' expected"); + } + } while (!dots && optional(ls, ',')); + } + code_params(ls, nparams, dots); +} + + +static void body (LexState *ls, int needself, int line) { + /* body -> '(' parlist ')' chunk END */ + FuncState new_fs; + open_func(ls, &new_fs); + new_fs.f->lineDefined = line; + check(ls, '('); + if (needself) { + new_localvarstr(ls, "self", 0); + adjustlocalvars(ls, 1); + } + parlist(ls); + check(ls, ')'); + chunk(ls); + check_match(ls, TK_END, TK_FUNCTION, line); + close_func(ls); + pushclosure(ls, &new_fs); +} + + +/* }====================================================================== */ + + +static void chunk (LexState *ls) { + /* chunk -> { stat [';'] } */ + int islast = 0; + while (!islast && !block_follow(ls->t.token)) { + islast = stat(ls); + optional(ls, ';'); + LUA_ASSERT(ls->fs->stacklevel == ls->fs->nactloc, + "stack size != # local vars"); + } +} + diff --git a/build/premake/src/Src/Lua/lparser.h b/build/premake/src/Src/Lua/lparser.h new file mode 100644 index 0000000000..eb3b057ed8 --- /dev/null +++ b/build/premake/src/Src/Lua/lparser.h @@ -0,0 +1,60 @@ +/* +** $Id: lparser.h,v 1.1 2003/01/24 16:26:12 jason379 Exp $ +** LL(1) Parser and code generator for Lua +** See Copyright Notice in lua.h +*/ + +#ifndef lparser_h +#define lparser_h + +#include "lobject.h" +#include "lzio.h" + + +/* +** Expression descriptor +*/ + +typedef enum { + VGLOBAL, + VLOCAL, + VINDEXED, + VEXP +} expkind; + +typedef struct expdesc { + expkind k; + union { + int index; /* VGLOBAL: `kstr' index of global name; VLOCAL: stack index */ + struct { + int t; /* patch list of `exit when true' */ + int f; /* patch list of `exit when false' */ + } l; + } u; +} expdesc; + + + +/* state needed to generate code for a given function */ +typedef struct FuncState { + Proto *f; /* current function header */ + struct FuncState *prev; /* enclosing function */ + struct LexState *ls; /* lexical state */ + struct lua_State *L; /* copy of the Lua state */ + int pc; /* next position to code */ + int lasttarget; /* `pc' of last `jump target' */ + int jlt; /* list of jumps to `lasttarget' */ + short stacklevel; /* number of values on activation register */ + short nactloc; /* number of active local variables */ + short nupvalues; /* number of upvalues */ + int lastline; /* line where last `lineinfo' was generated */ + struct Breaklabel *bl; /* chain of breakable blocks */ + expdesc upvalues[MAXUPVALUES]; /* upvalues */ + int actloc[MAXLOCALS]; /* local-variable stack (indices to locvars) */ +} FuncState; + + +Proto *luaY_parser (lua_State *L, ZIO *z); + + +#endif diff --git a/build/premake/src/Src/Lua/lstate.c b/build/premake/src/Src/Lua/lstate.c new file mode 100644 index 0000000000..64197c7af5 --- /dev/null +++ b/build/premake/src/Src/Lua/lstate.c @@ -0,0 +1,121 @@ +/* +** $Id: lstate.c,v 1.1 2003/01/24 16:26:12 jason379 Exp $ +** Global State +** See Copyright Notice in lua.h +*/ + + +#include + +#include "lua.h" + +#include "ldo.h" +#include "lgc.h" +#include "llex.h" +#include "lmem.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" + + +#ifdef LUA_DEBUG +static lua_State *lua_state = NULL; +void luaB_opentests (lua_State *L); +#endif + + +/* +** built-in implementation for ERRORMESSAGE. In a "correct" environment +** ERRORMESSAGE should have an external definition, and so this function +** would not be used. +*/ +static int errormessage (lua_State *L) { + const char *s = lua_tostring(L, 1); + if (s == NULL) s = "(no message)"; + fprintf(stderr, "error: %s\n", s); + return 0; +} + + +/* +** open parts that may cause memory-allocation errors +*/ +static void f_luaopen (lua_State *L, void *ud) { + int stacksize = *(int *)ud; + if (stacksize == 0) + stacksize = DEFAULT_STACK_SIZE; + else + stacksize += LUA_MINSTACK; + L->gt = luaH_new(L, 10); /* table of globals */ + luaD_init(L, stacksize); + luaS_init(L); + luaX_init(L); + luaT_init(L); + lua_newtable(L); + lua_ref(L, 1); /* create registry */ + lua_register(L, LUA_ERRORMESSAGE, errormessage); +#ifdef LUA_DEBUG + luaB_opentests(L); + if (lua_state == NULL) lua_state = L; /* keep first state to be opened */ +#endif + LUA_ASSERT(lua_gettop(L) == 0, "wrong API stack"); +} + + +LUA_API lua_State *lua_open (int stacksize) { + lua_State *L = luaM_new(NULL, lua_State); + if (L == NULL) return NULL; /* memory allocation error */ + L->stack = NULL; + L->strt.size = L->udt.size = 0; + L->strt.nuse = L->udt.nuse = 0; + L->strt.hash = NULL; + L->udt.hash = NULL; + L->Mbuffer = NULL; + L->Mbuffsize = 0; + L->rootproto = NULL; + L->rootcl = NULL; + L->roottable = NULL; + L->TMtable = NULL; + L->last_tag = -1; + L->refArray = NULL; + L->refSize = 0; + L->refFree = NONEXT; + L->nblocks = sizeof(lua_State); + L->GCthreshold = MAX_INT; /* to avoid GC during pre-definitions */ + L->callhook = NULL; + L->linehook = NULL; + L->allowhooks = 1; + L->errorJmp = NULL; + if (luaD_runprotected(L, f_luaopen, &stacksize) != 0) { + /* memory allocation error: free partial state */ + lua_close(L); + return NULL; + } + L->GCthreshold = 2*L->nblocks; + return L; +} + + +LUA_API void lua_close (lua_State *L) { + LUA_ASSERT(L != lua_state || lua_gettop(L) == 0, "garbage in C stack"); + luaC_collect(L, 1); /* collect all elements */ + LUA_ASSERT(L->rootproto == NULL, "list should be empty"); + LUA_ASSERT(L->rootcl == NULL, "list should be empty"); + LUA_ASSERT(L->roottable == NULL, "list should be empty"); + luaS_freeall(L); + if (L->stack) + L->nblocks -= (L->stack_last - L->stack + 1)*sizeof(TObject); + luaM_free(L, L->stack); + L->nblocks -= (L->last_tag+1)*sizeof(struct TM); + luaM_free(L, L->TMtable); + L->nblocks -= (L->refSize)*sizeof(struct Ref); + luaM_free(L, L->refArray); + L->nblocks -= (L->Mbuffsize)*sizeof(char); + luaM_free(L, L->Mbuffer); + LUA_ASSERT(L->nblocks == sizeof(lua_State), "wrong count for nblocks"); + luaM_free(L, L); + LUA_ASSERT(L != lua_state || memdebug_numblocks == 0, "memory leak!"); + LUA_ASSERT(L != lua_state || memdebug_total == 0,"memory leak!"); +} + diff --git a/build/premake/src/Src/Lua/lstate.h b/build/premake/src/Src/Lua/lstate.h new file mode 100644 index 0000000000..2470a0cd3d --- /dev/null +++ b/build/premake/src/Src/Lua/lstate.h @@ -0,0 +1,77 @@ +/* +** $Id: lstate.h,v 1.1 2003/01/24 16:26:12 jason379 Exp $ +** Global State +** See Copyright Notice in lua.h +*/ + +#ifndef lstate_h +#define lstate_h + +#include "lobject.h" +#include "lua.h" +#include "luadebug.h" + + + +typedef TObject *StkId; /* index to stack elements */ + + +/* +** marks for Reference array +*/ +#define NONEXT -1 /* to end the free list */ +#define HOLD -2 +#define COLLECTED -3 +#define LOCK -4 + + +struct Ref { + TObject o; + int st; /* can be LOCK, HOLD, COLLECTED, or next (for free list) */ +}; + + +struct lua_longjmp; /* defined in ldo.c */ +struct TM; /* defined in ltm.h */ + + +typedef struct stringtable { + int size; + lint32 nuse; /* number of elements */ + TString **hash; +} stringtable; + + + +struct lua_State { + /* thread-specific state */ + StkId top; /* first free slot in the stack */ + StkId stack; /* stack base */ + StkId stack_last; /* last free slot in the stack */ + int stacksize; + StkId Cbase; /* base for current C function */ + struct lua_longjmp *errorJmp; /* current error recover point */ + char *Mbuffer; /* global buffer */ + size_t Mbuffsize; /* size of Mbuffer */ + /* global state */ + Proto *rootproto; /* list of all prototypes */ + Closure *rootcl; /* list of all closures */ + Hash *roottable; /* list of all tables */ + stringtable strt; /* hash table for strings */ + stringtable udt; /* hash table for udata */ + Hash *gt; /* table for globals */ + struct TM *TMtable; /* table for tag methods */ + int last_tag; /* last used tag in TMtable */ + struct Ref *refArray; /* locked objects */ + int refSize; /* size of refArray */ + int refFree; /* list of free positions in refArray */ + unsigned long GCthreshold; + unsigned long nblocks; /* number of `bytes' currently allocated */ + lua_Hook callhook; + lua_Hook linehook; + int allowhooks; +}; + + +#endif + diff --git a/build/premake/src/Src/Lua/lstring.c b/build/premake/src/Src/Lua/lstring.c new file mode 100644 index 0000000000..62fc183d83 --- /dev/null +++ b/build/premake/src/Src/Lua/lstring.c @@ -0,0 +1,155 @@ +/* +** $Id: lstring.c,v 1.1 2003/01/24 16:26:12 jason379 Exp $ +** String table (keeps all strings handled by Lua) +** See Copyright Notice in lua.h +*/ + + +#include + +#include "lua.h" + +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" + + +/* +** type equivalent to TString, but with maximum alignment requirements +*/ +union L_UTString { + TString ts; + union L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */ +}; + + + +void luaS_init (lua_State *L) { + L->strt.hash = luaM_newvector(L, 1, TString *); + L->udt.hash = luaM_newvector(L, 1, TString *); + L->nblocks += 2*sizeof(TString *); + L->strt.size = L->udt.size = 1; + L->strt.nuse = L->udt.nuse = 0; + L->strt.hash[0] = L->udt.hash[0] = NULL; +} + + +void luaS_freeall (lua_State *L) { + LUA_ASSERT(L->strt.nuse==0, "non-empty string table"); + L->nblocks -= (L->strt.size + L->udt.size)*sizeof(TString *); + luaM_free(L, L->strt.hash); + LUA_ASSERT(L->udt.nuse==0, "non-empty udata table"); + luaM_free(L, L->udt.hash); +} + + +static unsigned long hash_s (const char *s, size_t l) { + unsigned long h = l; /* seed */ + size_t step = (l>>5)|1; /* if string is too long, don't hash all its chars */ + for (; l>=step; l-=step) + h = h ^ ((h<<5)+(h>>2)+(unsigned char)*(s++)); + return h; +} + + +void luaS_resize (lua_State *L, stringtable *tb, int newsize) { + TString **newhash = luaM_newvector(L, newsize, TString *); + int i; + for (i=0; isize; i++) { + TString *p = tb->hash[i]; + while (p) { /* for each node in the list */ + TString *next = p->nexthash; /* save next */ + unsigned long h = (tb == &L->strt) ? p->u.s.hash : IntPoint(p->u.d.value); + int h1 = h&(newsize-1); /* new position */ + LUA_ASSERT(h%newsize == (h&(newsize-1)), + "a&(x-1) == a%x, for x power of 2"); + p->nexthash = newhash[h1]; /* chain it in new position */ + newhash[h1] = p; + p = next; + } + } + luaM_free(L, tb->hash); + L->nblocks += (newsize - tb->size)*sizeof(TString *); + tb->size = newsize; + tb->hash = newhash; +} + + +static void newentry (lua_State *L, stringtable *tb, TString *ts, int h) { + ts->nexthash = tb->hash[h]; /* chain new entry */ + tb->hash[h] = ts; + tb->nuse++; + if (tb->nuse > (lint32)tb->size && tb->size < MAX_INT/2) /* too crowded? */ + luaS_resize(L, tb, tb->size*2); +} + + + +TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { + unsigned long h = hash_s(str, l); + int h1 = h & (L->strt.size-1); + TString *ts; + for (ts = L->strt.hash[h1]; ts; ts = ts->nexthash) { + if (ts->len == l && (memcmp(str, ts->str, l) == 0)) + return ts; + } + /* not found */ + ts = (TString *)luaM_malloc(L, sizestring(l)); + ts->marked = 0; + ts->nexthash = NULL; + ts->len = l; + ts->u.s.hash = h; + ts->u.s.constindex = 0; + memcpy(ts->str, str, l); + ts->str[l] = 0; /* ending 0 */ + L->nblocks += sizestring(l); + newentry(L, &L->strt, ts, h1); /* insert it on table */ + return ts; +} + + +TString *luaS_newudata (lua_State *L, size_t s, void *udata) { + union L_UTString *uts = (union L_UTString *)luaM_malloc(L, + (lint32)sizeof(union L_UTString)+s); + TString *ts = &uts->ts; + ts->marked = 0; + ts->nexthash = NULL; + ts->len = s; + ts->u.d.tag = 0; + ts->u.d.value = (s > 0) ? uts+1 : udata; + L->nblocks += sizestring(s); + /* insert it on table */ + newentry(L, &L->udt, ts, IntPoint(ts->u.d.value) & (L->udt.size-1)); + return ts; +} + + +TString *luaS_createudata (lua_State *L, void *udata, int tag) { + int h1 = IntPoint(udata) & (L->udt.size-1); + TString *ts; + for (ts = L->udt.hash[h1]; ts; ts = ts->nexthash) { + if (udata == ts->u.d.value && (tag == ts->u.d.tag || tag == LUA_ANYTAG)) + return ts; + } + /* not found */ + ts = luaS_newudata(L, 0, udata); + if (tag != LUA_ANYTAG) + ts->u.d.tag = tag; + return ts; +} + + +TString *luaS_new (lua_State *L, const char *str) { + return luaS_newlstr(L, str, strlen(str)); +} + + +TString *luaS_newfixed (lua_State *L, const char *str) { + TString *ts = luaS_new(L, str); + if (ts->marked == 0) ts->marked = FIXMARK; /* avoid GC */ + return ts; +} + diff --git a/build/premake/src/Src/Lua/lstring.h b/build/premake/src/Src/Lua/lstring.h new file mode 100644 index 0000000000..fe1eb79215 --- /dev/null +++ b/build/premake/src/Src/Lua/lstring.h @@ -0,0 +1,37 @@ +/* +** $Id: lstring.h,v 1.1 2003/01/24 16:26:13 jason379 Exp $ +** String table (keep all strings handled by Lua) +** See Copyright Notice in lua.h +*/ + +#ifndef lstring_h +#define lstring_h + + +#include "lobject.h" +#include "lstate.h" + + +/* +** any TString with mark>=FIXMARK is never collected. +** Marks>=RESERVEDMARK are used to identify reserved words. +*/ +#define FIXMARK 2 +#define RESERVEDMARK 3 + + +#define sizestring(l) ((long)sizeof(TString) + \ + ((long)(l+1)-TSPACK)*(long)sizeof(char)) + + +void luaS_init (lua_State *L); +void luaS_resize (lua_State *L, stringtable *tb, int newsize); +TString *luaS_newudata (lua_State *L, size_t s, void *udata); +TString *luaS_createudata (lua_State *L, void *udata, int tag); +void luaS_freeall (lua_State *L); +TString *luaS_newlstr (lua_State *L, const char *str, size_t l); +TString *luaS_new (lua_State *L, const char *str); +TString *luaS_newfixed (lua_State *L, const char *str); + + +#endif diff --git a/build/premake/src/Src/Lua/lstrlib.c b/build/premake/src/Src/Lua/lstrlib.c new file mode 100644 index 0000000000..2340171a86 --- /dev/null +++ b/build/premake/src/Src/Lua/lstrlib.c @@ -0,0 +1,621 @@ +/* +** $Id: lstrlib.c,v 1.1 2003/04/23 12:16:05 jason379 Exp $ +** Standard library for string operations and pattern-matching +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + + +static int str_len (lua_State *L) { + size_t l; + luaL_check_lstr(L, 1, &l); + lua_pushnumber(L, l); + return 1; +} + + +static long posrelat (long pos, size_t len) { + /* relative string position: negative means back from end */ + return (pos>=0) ? pos : (long)len+pos+1; +} + + +static int str_sub (lua_State *L) { + size_t l; + const char *s = luaL_check_lstr(L, 1, &l); + long start = posrelat(luaL_check_long(L, 2), l); + long end = posrelat(luaL_opt_long(L, 3, -1), l); + if (start < 1) start = 1; + if (end > (long)l) end = l; + if (start <= end) + lua_pushlstring(L, s+start-1, end-start+1); + else lua_pushstring(L, ""); + return 1; +} + + +static int str_lower (lua_State *L) { + size_t l; + size_t i; + luaL_Buffer b; + const char *s = luaL_check_lstr(L, 1, &l); + luaL_buffinit(L, &b); + for (i=0; i 0) + luaL_addlstring(&b, s, l); + luaL_pushresult(&b); + return 1; +} + + +static int str_byte (lua_State *L) { + size_t l; + const char *s = luaL_check_lstr(L, 1, &l); + long pos = posrelat(luaL_opt_long(L, 2, 1), l); + luaL_arg_check(L, 0level && cap->capture[l].len != -1)) + lua_error(L, "invalid capture index"); + return l; +} + + +static int capture_to_close (lua_State *L, struct Capture *cap) { + int level = cap->level; + for (level--; level>=0; level--) + if (cap->capture[level].len == -1) return level; + lua_error(L, "invalid pattern capture"); + return 0; /* to avoid warnings */ +} + + +const char *luaI_classend (lua_State *L, const char *p) { + switch (*p++) { + case ESC: + if (*p == '\0') lua_error(L, "malformed pattern (ends with `%')"); + return p+1; + case '[': + if (*p == '^') p++; + do { /* look for a ']' */ + if (*p == '\0') lua_error(L, "malformed pattern (missing `]')"); + if (*(p++) == ESC && *p != '\0') p++; /* skip escapes (e.g. '%]') */ + } while (*p != ']'); + return p+1; + default: + return p; + } +} + + +static int match_class (int c, int cl) { + int res; + switch (tolower(cl)) { + case 'a' : res = isalpha(c); break; + case 'c' : res = iscntrl(c); break; + case 'd' : res = isdigit(c); break; + case 'l' : res = islower(c); break; + case 'p' : res = ispunct(c); break; + case 's' : res = isspace(c); break; + case 'u' : res = isupper(c); break; + case 'w' : res = isalnum(c); break; + case 'x' : res = isxdigit(c); break; + case 'z' : res = (c == '\0'); break; + default: return (cl == c); + } + return (islower(cl) ? res : !res); +} + + + +static int matchbracketclass (int c, const char *p, const char *endclass) { + int sig = 1; + if (*(p+1) == '^') { + sig = 0; + p++; /* skip the '^' */ + } + while (++p < endclass) { + if (*p == ESC) { + p++; + if (match_class(c, (unsigned char)*p)) + return sig; + } + else if ((*(p+1) == '-') && (p+2 < endclass)) { + p+=2; + if ((int)(unsigned char)*(p-2) <= c && c <= (int)(unsigned char)*p) + return sig; + } + else if ((int)(unsigned char)*p == c) return sig; + } + return !sig; +} + + + +int luaI_singlematch (int c, const char *p, const char *ep) { + switch (*p) { + case '.': /* matches any char */ + return 1; + case ESC: + return match_class(c, (unsigned char)*(p+1)); + case '[': + return matchbracketclass(c, p, ep-1); + default: + return ((unsigned char)*p == c); + } +} + + +static const char *match (lua_State *L, const char *s, const char *p, + struct Capture *cap); + + +static const char *matchbalance (lua_State *L, const char *s, const char *p, + struct Capture *cap) { + if (*p == 0 || *(p+1) == 0) + lua_error(L, "unbalanced pattern"); + if (*s != *p) return NULL; + else { + int b = *p; + int e = *(p+1); + int cont = 1; + while (++s < cap->src_end) { + if (*s == e) { + if (--cont == 0) return s+1; + } + else if (*s == b) cont++; + } + } + return NULL; /* string ends out of balance */ +} + + +static const char *max_expand (lua_State *L, const char *s, const char *p, + const char *ep, struct Capture *cap) { + long i = 0; /* counts maximum expand for item */ + while ((s+i)src_end && luaI_singlematch((unsigned char)*(s+i), p, ep)) + i++; + /* keeps trying to match with the maximum repetitions */ + while (i>=0) { + const char *res = match(L, (s+i), ep+1, cap); + if (res) return res; + i--; /* else didn't match; reduce 1 repetition to try again */ + } + return NULL; +} + + +static const char *min_expand (lua_State *L, const char *s, const char *p, + const char *ep, struct Capture *cap) { + for (;;) { + const char *res = match(L, s, ep+1, cap); + if (res != NULL) + return res; + else if (ssrc_end && luaI_singlematch((unsigned char)*s, p, ep)) + s++; /* try with one more repetition */ + else return NULL; + } +} + + +static const char *start_capture (lua_State *L, const char *s, const char *p, + struct Capture *cap) { + const char *res; + int level = cap->level; + if (level >= MAX_CAPTURES) lua_error(L, "too many captures"); + cap->capture[level].init = s; + cap->capture[level].len = -1; + cap->level = level+1; + if ((res=match(L, s, p+1, cap)) == NULL) /* match failed? */ + cap->level--; /* undo capture */ + return res; +} + + +static const char *end_capture (lua_State *L, const char *s, const char *p, + struct Capture *cap) { + int l = capture_to_close(L, cap); + const char *res; + cap->capture[l].len = s - cap->capture[l].init; /* close capture */ + if ((res = match(L, s, p+1, cap)) == NULL) /* match failed? */ + cap->capture[l].len = -1; /* undo capture */ + return res; +} + + +static const char *match_capture (lua_State *L, const char *s, int level, + struct Capture *cap) { + int l = check_capture(L, level, cap); + size_t len = cap->capture[l].len; + if ((size_t)(cap->src_end-s) >= len && + memcmp(cap->capture[l].init, s, len) == 0) + return s+len; + else return NULL; +} + + +static const char *match (lua_State *L, const char *s, const char *p, + struct Capture *cap) { + init: /* using goto's to optimize tail recursion */ + switch (*p) { + case '(': /* start capture */ + return start_capture(L, s, p, cap); + case ')': /* end capture */ + return end_capture(L, s, p, cap); + case ESC: /* may be %[0-9] or %b */ + if (isdigit((unsigned char)(*(p+1)))) { /* capture? */ + s = match_capture(L, s, *(p+1), cap); + if (s == NULL) return NULL; + p+=2; goto init; /* else return match(L, s, p+2, cap) */ + } + else if (*(p+1) == 'b') { /* balanced string? */ + s = matchbalance(L, s, p+2, cap); + if (s == NULL) return NULL; + p+=4; goto init; /* else return match(L, s, p+4, cap); */ + } + else goto dflt; /* case default */ + case '\0': /* end of pattern */ + return s; /* match succeeded */ + case '$': + if (*(p+1) == '\0') /* is the '$' the last char in pattern? */ + return (s == cap->src_end) ? s : NULL; /* check end of string */ + else goto dflt; + default: dflt: { /* it is a pattern item */ + const char *ep = luaI_classend(L, p); /* points to what is next */ + int m = ssrc_end && luaI_singlematch((unsigned char)*s, p, ep); + switch (*ep) { + case '?': { /* optional */ + const char *res; + if (m && ((res=match(L, s+1, ep+1, cap)) != NULL)) + return res; + p=ep+1; goto init; /* else return match(L, s, ep+1, cap); */ + } + case '*': /* 0 or more repetitions */ + return max_expand(L, s, p, ep, cap); + case '+': /* 1 or more repetitions */ + return (m ? max_expand(L, s+1, p, ep, cap) : NULL); + case '-': /* 0 or more repetitions (minimum) */ + return min_expand(L, s, p, ep, cap); + default: + if (!m) return NULL; + s++; p=ep; goto init; /* else return match(L, s+1, ep, cap); */ + } + } + } +} + + + +static const char *lmemfind (const char *s1, size_t l1, + const char *s2, size_t l2) { + if (l2 == 0) return s1; /* empty strings are everywhere */ + else if (l2 > l1) return NULL; /* avoids a negative `l1' */ + else { + const char *init; /* to search for a `*s2' inside `s1' */ + l2--; /* 1st char will be checked by `memchr' */ + l1 = l1-l2; /* `s2' cannot be found after that */ + while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) { + init++; /* 1st char is already checked */ + if (memcmp(init, s2+1, l2) == 0) + return init-1; + else { /* correct `l1' and `s1' to try again */ + l1 -= init-s1; + s1 = init; + } + } + return NULL; /* not found */ + } +} + + +static int push_captures (lua_State *L, struct Capture *cap) { + int i; + luaL_checkstack(L, cap->level, "too many captures"); + for (i=0; ilevel; i++) { + int l = cap->capture[i].len; + if (l == -1) lua_error(L, "unfinished capture"); + lua_pushlstring(L, cap->capture[i].init, l); + } + return cap->level; /* number of strings pushed */ +} + + +static int str_find (lua_State *L) { + size_t l1, l2; + const char *s = luaL_check_lstr(L, 1, &l1); + const char *p = luaL_check_lstr(L, 2, &l2); + long init = posrelat(luaL_opt_long(L, 3, 1), l1) - 1; + struct Capture cap; + luaL_arg_check(L, 0 <= init && (size_t)init <= l1, 3, "out of range"); + if (lua_gettop(L) > 3 || /* extra argument? */ + strpbrk(p, SPECIALS) == NULL) { /* or no special characters? */ + const char *s2 = lmemfind(s+init, l1-init, p, l2); + if (s2) { + lua_pushnumber(L, s2-s+1); + lua_pushnumber(L, s2-s+l2); + return 2; + } + } + else { + int anchor = (*p == '^') ? (p++, 1) : 0; + const char *s1=s+init; + cap.src_end = s+l1; + do { + const char *res; + cap.level = 0; + if ((res=match(L, s1, p, &cap)) != NULL) { + lua_pushnumber(L, s1-s+1); /* start */ + lua_pushnumber(L, res-s); /* end */ + return push_captures(L, &cap) + 2; + } + } while (s1++capture[level].init, cap->capture[level].len); + } + } + } + } + else { /* is a function */ + int n; + lua_pushvalue(L, 3); + n = push_captures(L, cap); + lua_rawcall(L, n, 1); + if (lua_isstring(L, -1)) + luaL_addvalue(b); /* add return to accumulated result */ + else + lua_pop(L, 1); /* function result is not a string: pop it */ + } +} + + +static int str_gsub (lua_State *L) { + size_t srcl; + const char *src = luaL_check_lstr(L, 1, &srcl); + const char *p = luaL_check_string(L, 2); + int max_s = luaL_opt_int(L, 4, srcl+1); + int anchor = (*p == '^') ? (p++, 1) : 0; + int n = 0; + struct Capture cap; + luaL_Buffer b; + luaL_arg_check(L, + lua_gettop(L) >= 3 && (lua_isstring(L, 3) || lua_isfunction(L, 3)), + 3, "string or function expected"); + luaL_buffinit(L, &b); + cap.src_end = src+srcl; + while (n < max_s) { + const char *e; + cap.level = 0; + e = match(L, src, p, &cap); + if (e) { + n++; + add_s(L, &b, &cap); + } + if (e && e>src) /* non empty match? */ + src = e; /* skip it */ + else if (src < cap.src_end) + luaL_putchar(&b, *src++); + else break; + if (anchor) break; + } + luaL_addlstring(&b, src, cap.src_end-src); + luaL_pushresult(&b); + lua_pushnumber(L, n); /* number of substitutions */ + return 2; +} + +/* }====================================================== */ + + +static void luaI_addquoted (lua_State *L, luaL_Buffer *b, int arg) { + size_t l; + const char *s = luaL_check_lstr(L, arg, &l); + luaL_putchar(b, '"'); + while (l--) { + switch (*s) { + case '"': case '\\': case '\n': + luaL_putchar(b, '\\'); + luaL_putchar(b, *s); + break; + case '\0': luaL_addlstring(b, "\\000", 4); break; + default: luaL_putchar(b, *s); + } + s++; + } + luaL_putchar(b, '"'); +} + +/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */ +#define MAX_ITEM 512 +/* maximum size of each format specification (such as '%-099.99d') */ +#define MAX_FORMAT 20 + +static int str_format (lua_State *L) { + int arg = 1; + const char *strfrmt = luaL_check_string(L, arg); + luaL_Buffer b; + luaL_buffinit(L, &b); + while (*strfrmt) { + if (*strfrmt != '%') + luaL_putchar(&b, *strfrmt++); + else if (*++strfrmt == '%') + luaL_putchar(&b, *strfrmt++); /* %% */ + else { /* format item */ + struct Capture cap; + char form[MAX_FORMAT]; /* to store the format ('%...') */ + char buff[MAX_ITEM]; /* to store the formatted item */ + const char *initf = strfrmt; + form[0] = '%'; + if (isdigit((unsigned char)*initf) && *(initf+1) == '$') { + arg = *initf - '0'; + initf += 2; /* skip the 'n$' */ + } + arg++; + cap.src_end = strfrmt+strlen(strfrmt)+1; + cap.level = 0; + strfrmt = match(L, initf, "[-+ #0]*(%d*)%.?(%d*)", &cap); + if (cap.capture[0].len > 2 || cap.capture[1].len > 2 || /* < 100? */ + strfrmt-initf > MAX_FORMAT-2) + lua_error(L, "invalid format (width or precision too long)"); + strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */ + form[strfrmt-initf+2] = 0; + switch (*strfrmt++) { + case 'c': case 'd': case 'i': + sprintf(buff, form, luaL_check_int(L, arg)); + break; + case 'o': case 'u': case 'x': case 'X': + sprintf(buff, form, (unsigned int)luaL_check_number(L, arg)); + break; + case 'e': case 'E': case 'f': case 'g': case 'G': + sprintf(buff, form, luaL_check_number(L, arg)); + break; + case 'q': + luaI_addquoted(L, &b, arg); + continue; /* skip the "addsize" at the end */ + case 's': { + size_t l; + const char *s = luaL_check_lstr(L, arg, &l); + if (cap.capture[1].len == 0 && l >= 100) { + /* no precision and string is too long to be formatted; + keep original string */ + lua_pushvalue(L, arg); + luaL_addvalue(&b); + continue; /* skip the "addsize" at the end */ + } + else { + sprintf(buff, form, s); + break; + } + } + default: /* also treat cases 'pnLlh' */ + lua_error(L, "invalid option in `format'"); + } + luaL_addlstring(&b, buff, strlen(buff)); + } + } + luaL_pushresult(&b); + return 1; +} + + +static const struct luaL_reg strlib[] = { +{"strlen", str_len}, +{"strsub", str_sub}, +{"strlower", str_lower}, +{"strupper", str_upper}, +{"strchar", str_char}, +{"strrep", str_rep}, +{"ascii", str_byte}, /* for compatibility with 3.0 and earlier */ +{"strbyte", str_byte}, +{"format", str_format}, +{"strfind", str_find}, +{"gsub", str_gsub} +}; + + +/* +** Open string library +*/ +LUALIB_API void lua_strlibopen (lua_State *L) { + luaL_openl(L, strlib); +} diff --git a/build/premake/src/Src/Lua/ltable.c b/build/premake/src/Src/Lua/ltable.c new file mode 100644 index 0000000000..51e6dfe626 --- /dev/null +++ b/build/premake/src/Src/Lua/ltable.c @@ -0,0 +1,303 @@ +/* +** $Id: ltable.c,v 1.1 2003/01/24 16:26:13 jason379 Exp $ +** Lua tables (hash) +** See Copyright Notice in lua.h +*/ + + +/* +** Implementation of tables (aka arrays, objects, or hash tables); +** uses a mix of chained scatter table with Brent's variation. +** A main invariant of these tables is that, if an element is not +** in its main position (i.e. the `original' position that its hash gives +** to it), then the colliding element is in its own main position. +** In other words, there are collisions only when two elements have the +** same main position (i.e. the same hash values for that table size). +** Because of that, the load factor of these tables can be 100% without +** performance penalties. +*/ + + +#include "lua.h" + +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" + + +#define gcsize(L, n) (sizeof(Hash)+(n)*sizeof(Node)) + + + +#define TagDefault LUA_TTABLE + + + +/* +** returns the `main' position of an element in a table (that is, the index +** of its hash value) +*/ +Node *luaH_mainposition (const Hash *t, const TObject *key) { + unsigned long h; + switch (ttype(key)) { + case LUA_TNUMBER: + h = (unsigned long)(long)nvalue(key); + break; + case LUA_TSTRING: + h = tsvalue(key)->u.s.hash; + break; + case LUA_TUSERDATA: + h = IntPoint(tsvalue(key)); + break; + case LUA_TTABLE: + h = IntPoint(hvalue(key)); + break; + case LUA_TFUNCTION: + h = IntPoint(clvalue(key)); + break; + default: + return NULL; /* invalid key */ + } + LUA_ASSERT(h%(unsigned int)t->size == (h&((unsigned int)t->size-1)), + "a&(x-1) == a%x, for x power of 2"); + return &t->node[h&(t->size-1)]; +} + + +static const TObject *luaH_getany (lua_State *L, const Hash *t, + const TObject *key) { + Node *n = luaH_mainposition(t, key); + if (!n) + lua_error(L, "table index is nil"); + else do { + if (luaO_equalObj(key, &n->key)) + return &n->val; + n = n->next; + } while (n); + return &luaO_nilobject; /* key not found */ +} + + +/* specialized version for numbers */ +const TObject *luaH_getnum (const Hash *t, Number key) { + Node *n = &t->node[(unsigned long)(long)key&(t->size-1)]; + do { + if (ttype(&n->key) == LUA_TNUMBER && nvalue(&n->key) == key) + return &n->val; + n = n->next; + } while (n); + return &luaO_nilobject; /* key not found */ +} + + +/* specialized version for strings */ +const TObject *luaH_getstr (const Hash *t, TString *key) { + Node *n = &t->node[key->u.s.hash&(t->size-1)]; + do { + if (ttype(&n->key) == LUA_TSTRING && tsvalue(&n->key) == key) + return &n->val; + n = n->next; + } while (n); + return &luaO_nilobject; /* key not found */ +} + + +const TObject *luaH_get (lua_State *L, const Hash *t, const TObject *key) { + switch (ttype(key)) { + case LUA_TNUMBER: return luaH_getnum(t, nvalue(key)); + case LUA_TSTRING: return luaH_getstr(t, tsvalue(key)); + default: return luaH_getany(L, t, key); + } +} + + +Node *luaH_next (lua_State *L, const Hash *t, const TObject *key) { + int i; + if (ttype(key) == LUA_TNIL) + i = 0; /* first iteration */ + else { + const TObject *v = luaH_get(L, t, key); + if (v == &luaO_nilobject) + lua_error(L, "invalid key for `next'"); + i = (int)(((const char *)v - + (const char *)(&t->node[0].val)) / sizeof(Node)) + 1; + } + for (; isize; i++) { + Node *n = node(t, i); + if (ttype(val(n)) != LUA_TNIL) + return n; + } + return NULL; /* no more elements */ +} + + +/* +** try to remove a key without value from a table. To avoid problems with +** hash, change `key' for a number with the same hash. +*/ +void luaH_remove (Hash *t, TObject *key) { + if (ttype(key) == LUA_TNUMBER || + (ttype(key) == LUA_TSTRING && tsvalue(key)->len <= 30)) + return; /* do not remove numbers nor small strings */ + else { + /* try to find a number `n' with the same hash as `key' */ + Node *mp = luaH_mainposition(t, key); + int n = mp - &t->node[0]; + /* make sure `n' is not in `t' */ + while (luaH_getnum(t, n) != &luaO_nilobject) { + if (n >= MAX_INT - t->size) + return; /* give up; (to avoid overflow) */ + n += t->size; + } + ttype(key) = LUA_TNUMBER; + nvalue(key) = n; + LUA_ASSERT(luaH_mainposition(t, key) == mp, "cannot change hash"); + } +} + + +static void setnodevector (lua_State *L, Hash *t, lint32 size) { + int i; + if (size > MAX_INT) + lua_error(L, "table overflow"); + t->node = luaM_newvector(L, size, Node); + for (i=0; i<(int)size; i++) { + ttype(&t->node[i].key) = ttype(&t->node[i].val) = LUA_TNIL; + t->node[i].next = NULL; + } + L->nblocks += gcsize(L, size) - gcsize(L, t->size); + t->size = size; + t->firstfree = &t->node[size-1]; /* first free position to be used */ +} + + +Hash *luaH_new (lua_State *L, int size) { + Hash *t = luaM_new(L, Hash); + t->htag = TagDefault; + t->next = L->roottable; + L->roottable = t; + t->mark = t; + t->size = 0; + L->nblocks += gcsize(L, 0); + t->node = NULL; + setnodevector(L, t, luaO_power2(size)); + return t; +} + + +void luaH_free (lua_State *L, Hash *t) { + L->nblocks -= gcsize(L, t->size); + luaM_free(L, t->node); + luaM_free(L, t); +} + + +static int numuse (const Hash *t) { + Node *v = t->node; + int size = t->size; + int realuse = 0; + int i; + for (i=0; isize; + Node *nold = t->node; + int nelems = numuse(t); + int i; + LUA_ASSERT(nelems<=oldsize, "wrong count"); + if (nelems >= oldsize-oldsize/4) /* using more than 3/4? */ + setnodevector(L, t, (lint32)oldsize*2); + else if (nelems <= oldsize/4 && /* less than 1/4? */ + oldsize > MINPOWER2) + setnodevector(L, t, oldsize/2); + else + setnodevector(L, t, oldsize); + for (i=0; ival) != LUA_TNIL) + *luaH_set(L, t, &old->key) = old->val; + } + luaM_free(L, nold); /* free old array */ +} + + +/* +** inserts a key into a hash table; first, check whether key is +** already present; if not, check whether key's main position is free; +** if not, check whether colliding node is in its main position or not; +** if it is not, move colliding node to an empty place and put new key +** in its main position; otherwise (colliding node is in its main position), +** new key goes to an empty position. +*/ +TObject *luaH_set (lua_State *L, Hash *t, const TObject *key) { + Node *mp = luaH_mainposition(t, key); + Node *n = mp; + if (!mp) + lua_error(L, "table index is nil"); + do { /* check whether `key' is somewhere in the chain */ + if (luaO_equalObj(key, &n->key)) + return &n->val; /* that's all */ + else n = n->next; + } while (n); + /* `key' not found; must insert it */ + if (ttype(&mp->key) != LUA_TNIL) { /* main position is not free? */ + Node *othern; /* main position of colliding node */ + n = t->firstfree; /* get a free place */ + /* is colliding node out of its main position? (can only happens if + its position is after "firstfree") */ + if (mp > n && (othern=luaH_mainposition(t, &mp->key)) != mp) { + /* yes; move colliding node into free position */ + while (othern->next != mp) othern = othern->next; /* find previous */ + othern->next = n; /* redo the chain with `n' in place of `mp' */ + *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */ + mp->next = NULL; /* now `mp' is free */ + } + else { /* colliding node is in its own main position */ + /* new node will go into free position */ + n->next = mp->next; /* chain new position */ + mp->next = n; + mp = n; + } + } + mp->key = *key; + for (;;) { /* correct `firstfree' */ + if (ttype(&t->firstfree->key) == LUA_TNIL) + return &mp->val; /* OK; table still has a free place */ + else if (t->firstfree == t->node) break; /* cannot decrement from here */ + else (t->firstfree)--; + } + rehash(L, t); /* no more free places */ + return luaH_set(L, t, key); /* `rehash' invalidates this insertion */ +} + + +TObject *luaH_setint (lua_State *L, Hash *t, int key) { + TObject index; + ttype(&index) = LUA_TNUMBER; + nvalue(&index) = key; + return luaH_set(L, t, &index); +} + + +void luaH_setstrnum (lua_State *L, Hash *t, TString *key, Number val) { + TObject *value, index; + ttype(&index) = LUA_TSTRING; + tsvalue(&index) = key; + value = luaH_set(L, t, &index); + ttype(value) = LUA_TNUMBER; + nvalue(value) = val; +} + + +const TObject *luaH_getglobal (lua_State *L, const char *name) { + return luaH_getstr(L->gt, luaS_new(L, name)); +} + diff --git a/build/premake/src/Src/Lua/ltable.h b/build/premake/src/Src/Lua/ltable.h new file mode 100644 index 0000000000..f7c6bbae23 --- /dev/null +++ b/build/premake/src/Src/Lua/ltable.h @@ -0,0 +1,34 @@ +/* +** $Id: ltable.h,v 1.1 2003/01/24 16:26:15 jason379 Exp $ +** Lua tables (hash) +** See Copyright Notice in lua.h +*/ + +#ifndef ltable_h +#define ltable_h + +#include "lobject.h" + + +#define node(t,i) (&(t)->node[i]) +#define key(n) (&(n)->key) +#define val(n) (&(n)->val) + +Hash *luaH_new (lua_State *L, int nhash); +void luaH_free (lua_State *L, Hash *t); +const TObject *luaH_get (lua_State *L, const Hash *t, const TObject *key); +const TObject *luaH_getnum (const Hash *t, Number key); +const TObject *luaH_getstr (const Hash *t, TString *key); +void luaH_remove (Hash *t, TObject *key); +TObject *luaH_set (lua_State *L, Hash *t, const TObject *key); +Node * luaH_next (lua_State *L, const Hash *t, const TObject *r); +TObject *luaH_setint (lua_State *L, Hash *t, int key); +void luaH_setstrnum (lua_State *L, Hash *t, TString *key, Number val); +unsigned long luaH_hash (lua_State *L, const TObject *key); +const TObject *luaH_getglobal (lua_State *L, const char *name); + +/* exported only for debugging */ +Node *luaH_mainposition (const Hash *t, const TObject *key); + + +#endif diff --git a/build/premake/src/Src/Lua/ltests.c b/build/premake/src/Src/Lua/ltests.c new file mode 100644 index 0000000000..18e51ca9ce --- /dev/null +++ b/build/premake/src/Src/Lua/ltests.c @@ -0,0 +1,543 @@ +/* +** $Id: ltests.c,v 1.1 2003/01/24 16:26:16 jason379 Exp $ +** Internal Module for Debugging of the Lua Implementation +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include + + +#include "lua.h" + +#include "lapi.h" +#include "lauxlib.h" +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lmem.h" +#include "lopcodes.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "luadebug.h" +#include "lualib.h" + + +void luaB_opentests (lua_State *L); + + +/* +** The whole module only makes sense with LUA_DEBUG on +*/ +#ifdef LUA_DEBUG + + + +static void setnameval (lua_State *L, const char *name, int val) { + lua_pushstring(L, name); + lua_pushnumber(L, val); + lua_settable(L, -3); +} + + +/* +** {====================================================== +** Disassembler +** ======================================================= +*/ + + +static const char *const instrname[NUM_OPCODES] = { + "END", "RETURN", "CALL", "TAILCALL", "PUSHNIL", "POP", "PUSHINT", + "PUSHSTRING", "PUSHNUM", "PUSHNEGNUM", "PUSHUPVALUE", "GETLOCAL", + "GETGLOBAL", "GETTABLE", "GETDOTTED", "GETINDEXED", "PUSHSELF", + "CREATETABLE", "SETLOCAL", "SETGLOBAL", "SETTABLE", "SETLIST", "SETMAP", + "ADD", "ADDI", "SUB", "MULT", "DIV", "POW", "CONCAT", "MINUS", "NOT", + "JMPNE", "JMPEQ", "JMPLT", "JMPLE", "JMPGT", "JMPGE", "JMPT", "JMPF", + "JMPONT", "JMPONF", "JMP", "PUSHNILJMP", "FORPREP", "FORLOOP", "LFORPREP", + "LFORLOOP", "CLOSURE" +}; + + +static int pushop (lua_State *L, Proto *p, int pc) { + char buff[100]; + Instruction i = p->code[pc]; + OpCode o = GET_OPCODE(i); + const char *name = instrname[o]; + sprintf(buff, "%5d - ", luaG_getline(p->lineinfo, pc, 1, NULL)); + switch ((enum Mode)luaK_opproperties[o].mode) { + case iO: + sprintf(buff+8, "%-12s", name); + break; + case iU: + sprintf(buff+8, "%-12s%4u", name, GETARG_U(i)); + break; + case iS: + sprintf(buff+8, "%-12s%4d", name, GETARG_S(i)); + break; + case iAB: + sprintf(buff+8, "%-12s%4d %4d", name, GETARG_A(i), GETARG_B(i)); + break; + } + lua_pushstring(L, buff); + return (o != OP_END); +} + + +static int listcode (lua_State *L) { + int pc; + Proto *p; + int res; + luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), + 1, "Lua function expected"); + p = clvalue(luaA_index(L, 1))->f.l; + lua_newtable(L); + setnameval(L, "maxstack", p->maxstacksize); + setnameval(L, "numparams", p->numparams); + pc = 0; + do { + lua_pushnumber(L, pc+1); + res = pushop(L, p, pc++); + lua_settable(L, -3); + } while (res); + return 1; +} + + +static int liststrings (lua_State *L) { + Proto *p; + int i; + luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), + 1, "Lua function expected"); + p = clvalue(luaA_index(L, 1))->f.l; + lua_newtable(L); + for (i=0; inkstr; i++) { + lua_pushnumber(L, i+1); + lua_pushstring(L, p->kstr[i]->str); + lua_settable(L, -3); + } + return 1; +} + + +static int listlocals (lua_State *L) { + Proto *p; + int pc = luaL_check_int(L, 2) - 1; + int i = 0; + const char *name; + luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), + 1, "Lua function expected"); + p = clvalue(luaA_index(L, 1))->f.l; + while ((name = luaF_getlocalname(p, ++i, pc)) != NULL) + lua_pushstring(L, name); + return i-1; +} + +/* }====================================================== */ + + + +static int get_limits (lua_State *L) { + lua_newtable(L); + setnameval(L, "BITS_INT", BITS_INT); + setnameval(L, "LFPF", LFIELDS_PER_FLUSH); + setnameval(L, "MAXARG_A", MAXARG_A); + setnameval(L, "MAXARG_B", MAXARG_B); + setnameval(L, "MAXARG_S", MAXARG_S); + setnameval(L, "MAXARG_U", MAXARG_U); + setnameval(L, "MAXLOCALS", MAXLOCALS); + setnameval(L, "MAXPARAMS", MAXPARAMS); + setnameval(L, "MAXSTACK", MAXSTACK); + setnameval(L, "MAXUPVALUES", MAXUPVALUES); + setnameval(L, "MAXVARSLH", MAXVARSLH); + setnameval(L, "RFPF", RFIELDS_PER_FLUSH); + setnameval(L, "SIZE_A", SIZE_A); + setnameval(L, "SIZE_B", SIZE_B); + setnameval(L, "SIZE_OP", SIZE_OP); + setnameval(L, "SIZE_U", SIZE_U); + return 1; +} + + +static int mem_query (lua_State *L) { + if (lua_isnull(L, 1)) { + lua_pushnumber(L, memdebug_total); + lua_pushnumber(L, memdebug_numblocks); + lua_pushnumber(L, memdebug_maxmem); + return 3; + } + else { + memdebug_memlimit = luaL_check_int(L, 1); + return 0; + } +} + + +static int hash_query (lua_State *L) { + if (lua_isnull(L, 2)) { + luaL_arg_check(L, lua_tag(L, 1) == LUA_TSTRING, 1, "string expected"); + lua_pushnumber(L, tsvalue(luaA_index(L, 1))->u.s.hash); + } + else { + Hash *t; + luaL_checktype(L, 2, LUA_TTABLE); + t = hvalue(luaA_index(L, 2)); + lua_pushnumber(L, luaH_mainposition(t, luaA_index(L, 1)) - t->node); + } + return 1; +} + + +static int table_query (lua_State *L) { + const Hash *t; + int i = luaL_opt_int(L, 2, -1); + luaL_checktype(L, 1, LUA_TTABLE); + t = hvalue(luaA_index(L, 1)); + if (i == -1) { + lua_pushnumber(L, t->size); + lua_pushnumber(L, t->firstfree - t->node); + return 2; + } + else if (i < t->size) { + luaA_pushobject(L, &t->node[i].key); + luaA_pushobject(L, &t->node[i].val); + if (t->node[i].next) { + lua_pushnumber(L, t->node[i].next - t->node); + return 3; + } + else + return 2; + } + return 0; +} + + +static int string_query (lua_State *L) { + stringtable *tb = (*luaL_check_string(L, 1) == 's') ? &L->strt : &L->udt; + int s = luaL_opt_int(L, 2, 0) - 1; + if (s==-1) { + lua_pushnumber(L ,tb->nuse); + lua_pushnumber(L ,tb->size); + return 2; + } + else if (s < tb->size) { + TString *ts; + int n = 0; + for (ts = tb->hash[s]; ts; ts = ts->nexthash) { + ttype(L->top) = LUA_TSTRING; + tsvalue(L->top) = ts; + incr_top; + n++; + } + return n; + } + return 0; +} + + +static int tref (lua_State *L) { + luaL_checkany(L, 1); + lua_pushvalue(L, 1); + lua_pushnumber(L, lua_ref(L, luaL_opt_int(L, 2, 1))); + return 1; +} + +static int getref (lua_State *L) { + if (lua_getref(L, luaL_check_int(L, 1))) + return 1; + else + return 0; +} + +static int unref (lua_State *L) { + lua_unref(L, luaL_check_int(L, 1)); + return 0; +} + +static int newuserdata (lua_State *L) { + if (lua_isnumber(L, 2)) + lua_pushusertag(L, (void *)luaL_check_int(L, 1), luaL_check_int(L, 2)); + else + lua_newuserdata(L, luaL_check_int(L, 1)); + return 1; +} + +static int udataval (lua_State *L) { + luaL_checktype(L, 1, LUA_TUSERDATA); + lua_pushnumber(L, (int)lua_touserdata(L, 1)); + return 1; +} + +static int newstate (lua_State *L) { + lua_State *L1 = lua_open(luaL_check_int(L, 1)); + if (L1) + lua_pushuserdata(L, L1); + else + lua_pushnil(L); + return 1; +} + +static int loadlib (lua_State *L) { + lua_State *L1 = (lua_State *)lua_touserdata(L, 1); + switch (*luaL_check_string(L, 2)) { + case 'm': lua_mathlibopen(L1); break; + case 's': lua_strlibopen(L1); break; + case 'i': lua_iolibopen(L1); break; + case 'd': lua_dblibopen(L1); break; + case 'b': lua_baselibopen(L1); break; + default: luaL_argerror(L, 2, "invalid option"); + } + return 0; +} + +static int closestate (lua_State *L) { + luaL_checktype(L, 1, LUA_TUSERDATA); + lua_close((lua_State *)lua_touserdata(L, 1)); + return 0; +} + +static int doremote (lua_State *L) { + lua_State *L1; + const char *code = luaL_check_string(L, 2); + int status; + luaL_checktype(L, 1, LUA_TUSERDATA); + L1 = (lua_State *)lua_touserdata(L, 1); + status = lua_dostring(L1, code); + if (status != 0) { + lua_pushnil(L); + lua_pushnumber(L, status); + return 2; + } + else { + int i = 0; + while (!lua_isnull(L1, ++i)) + lua_pushstring(L, lua_tostring(L1, i)); + return i-1; + } +} + +static int settagmethod (lua_State *L) { + int tag = luaL_check_int(L, 1); + const char *event = luaL_check_string(L, 2); + luaL_checkany(L, 3); + lua_gettagmethod(L, tag, event); + lua_pushvalue(L, 3); + lua_settagmethod(L, tag, event); + return 1; +} + +static int pushbool (lua_State *L, int b) { + if (b) lua_pushnumber(L, 1); + else lua_pushnil(L); + return 1; +} + +static int equal (lua_State *L) { + return pushbool(L, lua_equal(L, 1, 2)); +} + + + +/* +** {====================================================== +** function to test the API with C. It interprets a kind of "assembler" +** language with calls to the API, so the test can be driven by Lua code +** ======================================================= +*/ + +static const char *const delimits = " \t\n,;"; + +static void skip (const char **pc) { + while (**pc != '\0' && strchr(delimits, **pc)) (*pc)++; +} + +static int getnum (lua_State *L, const char **pc) { + int res = 0; + int sig = 1; + skip(pc); + if (**pc == '.') { + res = (int)lua_tonumber(L, -1); + lua_pop(L, 1); + (*pc)++; + return res; + } + else if (**pc == '-') { + sig = -1; + (*pc)++; + } + while (isdigit(**pc)) res = res*10 + (*(*pc)++) - '0'; + return sig*res; +} + +static const char *getname (char *buff, const char **pc) { + int i = 0; + skip(pc); + while (**pc != '\0' && !strchr(delimits, **pc)) + buff[i++] = *(*pc)++; + buff[i] = '\0'; + return buff; +} + + +#define EQ(s1) (strcmp(s1, inst) == 0) + +#define getnum ((getnum)(L, &pc)) +#define getname ((getname)(buff, &pc)) + + +static int testC (lua_State *L) { + char buff[30]; + const char *pc = luaL_check_string(L, 1); + for (;;) { + const char *inst = getname; + if EQ("") return 0; + else if EQ("isnumber") { + lua_pushnumber(L, lua_isnumber(L, getnum)); + } + else if EQ("isstring") { + lua_pushnumber(L, lua_isstring(L, getnum)); + } + else if EQ("istable") { + lua_pushnumber(L, lua_istable(L, getnum)); + } + else if EQ("iscfunction") { + lua_pushnumber(L, lua_iscfunction(L, getnum)); + } + else if EQ("isfunction") { + lua_pushnumber(L, lua_isfunction(L, getnum)); + } + else if EQ("isuserdata") { + lua_pushnumber(L, lua_isuserdata(L, getnum)); + } + else if EQ("isnil") { + lua_pushnumber(L, lua_isnil(L, getnum)); + } + else if EQ("isnull") { + lua_pushnumber(L, lua_isnull(L, getnum)); + } + else if EQ("tonumber") { + lua_pushnumber(L, lua_tonumber(L, getnum)); + } + else if EQ("tostring") { + lua_pushstring(L, lua_tostring(L, getnum)); + } + else if EQ("tonumber") { + lua_pushnumber(L, lua_tonumber(L, getnum)); + } + else if EQ("strlen") { + lua_pushnumber(L, lua_strlen(L, getnum)); + } + else if EQ("tocfunction") { + lua_pushcfunction(L, lua_tocfunction(L, getnum)); + } + else if EQ("return") { + return getnum; + } + else if EQ("gettop") { + lua_pushnumber(L, lua_gettop(L)); + } + else if EQ("settop") { + lua_settop(L, getnum); + } + else if EQ("pop") { + lua_pop(L, getnum); + } + else if EQ("pushnum") { + lua_pushnumber(L, getnum); + } + else if EQ("pushvalue") { + lua_pushvalue(L, getnum); + } + else if EQ("remove") { + lua_remove(L, getnum); + } + else if EQ("insert") { + lua_insert(L, getnum); + } + else if EQ("gettable") { + lua_gettable(L, getnum); + } + else if EQ("settable") { + lua_settable(L, getnum); + } + else if EQ("next") { + lua_next(L, -2); + } + else if EQ("concat") { + lua_concat(L, getnum); + } + else if EQ("rawcall") { + int narg = getnum; + int nres = getnum; + lua_rawcall(L, narg, nres); + } + else if EQ("call") { + int narg = getnum; + int nres = getnum; + lua_call(L, narg, nres); + } + else if EQ("dostring") { + lua_dostring(L, luaL_check_string(L, getnum)); + } + else if EQ("settagmethod") { + int tag = getnum; + const char *event = getname; + lua_settagmethod(L, tag, event); + } + else if EQ("gettagmethod") { + int tag = getnum; + const char *event = getname; + lua_gettagmethod(L, tag, event); + } + else if EQ("type") { + lua_pushstring(L, lua_typename(L, lua_type(L, getnum))); + } + else luaL_verror(L, "unknown instruction %.30s", buff); + } + return 0; +} + +/* }====================================================== */ + + + +static const struct luaL_reg tests_funcs[] = { + {"hash", hash_query}, + {"limits", get_limits}, + {"listcode", listcode}, + {"liststrings", liststrings}, + {"listlocals", listlocals}, + {"loadlib", loadlib}, + {"querystr", string_query}, + {"querytab", table_query}, + {"testC", testC}, + {"ref", tref}, + {"getref", getref}, + {"unref", unref}, + {"newuserdata", newuserdata}, + {"udataval", udataval}, + {"newstate", newstate}, + {"closestate", closestate}, + {"doremote", doremote}, + {"settagmethod", settagmethod}, + {"equal", equal}, + {"totalmem", mem_query} +}; + + +void luaB_opentests (lua_State *L) { + lua_newtable(L); + lua_getglobals(L); + lua_pushvalue(L, -2); + lua_setglobals(L); + luaL_openl(L, tests_funcs); /* open functions inside new table */ + lua_setglobals(L); /* restore old table of globals */ + lua_setglobal(L, "T"); /* set new table as global T */ +} + +#endif diff --git a/build/premake/src/Src/Lua/ltm.c b/build/premake/src/Src/Lua/ltm.c new file mode 100644 index 0000000000..25b26ccbba --- /dev/null +++ b/build/premake/src/Src/Lua/ltm.c @@ -0,0 +1,163 @@ +/* +** $Id: ltm.c,v 1.1 2003/01/24 16:26:16 jason379 Exp $ +** Tag methods +** See Copyright Notice in lua.h +*/ + + +#include +#include + +#include "lua.h" + +#include "ldo.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "ltm.h" + + +const char *const luaT_eventname[] = { /* ORDER TM */ + "gettable", "settable", "index", "getglobal", "setglobal", "add", "sub", + "mul", "div", "pow", "unm", "lt", "concat", "gc", "function", + "le", "gt", "ge", /* deprecated options!! */ + NULL +}; + + +static int findevent (const char *name) { + int i; + for (i=0; luaT_eventname[i]; i++) + if (strcmp(luaT_eventname[i], name) == 0) + return i; + return -1; /* name not found */ +} + + +static int luaI_checkevent (lua_State *L, const char *name, int t) { + int e = findevent(name); + if (e >= TM_N) + luaO_verror(L, "event `%.50s' is deprecated", name); + if (e == TM_GC && t == LUA_TTABLE) + luaO_verror(L, "event `gc' for tables is deprecated"); + if (e < 0) + luaO_verror(L, "`%.50s' is not a valid event name", name); + return e; +} + + + +/* events in LUA_TNIL are all allowed, since this is used as a +* 'placeholder' for "default" fallbacks +*/ +/* ORDER LUA_T, ORDER TM */ +static const char luaT_validevents[NUM_TAGS][TM_N] = { + {1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_TUSERDATA */ + {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* LUA_TNIL */ + {1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, /* LUA_TNUMBER */ + {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_TSTRING */ + {0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_TTABLE */ + {1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0} /* LUA_TFUNCTION */ +}; + +int luaT_validevent (int t, int e) { /* ORDER LUA_T */ + return (t >= NUM_TAGS) ? 1 : luaT_validevents[t][e]; +} + + +static void init_entry (lua_State *L, int tag) { + int i; + for (i=0; iTMtable[tag].collected = NULL; +} + + +void luaT_init (lua_State *L) { + int t; + luaM_growvector(L, L->TMtable, 0, NUM_TAGS, struct TM, "", MAX_INT); + L->nblocks += NUM_TAGS*sizeof(struct TM); + L->last_tag = NUM_TAGS-1; + for (t=0; t<=L->last_tag; t++) + init_entry(L, t); +} + + +LUA_API int lua_newtag (lua_State *L) { + luaM_growvector(L, L->TMtable, L->last_tag, 1, struct TM, + "tag table overflow", MAX_INT); + L->nblocks += sizeof(struct TM); + L->last_tag++; + init_entry(L, L->last_tag); + return L->last_tag; +} + + +static void checktag (lua_State *L, int tag) { + if (!(0 <= tag && tag <= L->last_tag)) + luaO_verror(L, "%d is not a valid tag", tag); +} + +void luaT_realtag (lua_State *L, int tag) { + if (!validtag(tag)) + luaO_verror(L, "tag %d was not created by `newtag'", tag); +} + + +LUA_API int lua_copytagmethods (lua_State *L, int tagto, int tagfrom) { + int e; + checktag(L, tagto); + checktag(L, tagfrom); + for (e=0; eu.d.tag; + case LUA_TTABLE: return hvalue(o)->htag; + default: return t; + } +} + + +LUA_API void lua_gettagmethod (lua_State *L, int t, const char *event) { + int e; + e = luaI_checkevent(L, event, t); + checktag(L, t); + if (luaT_validevent(t, e) && luaT_gettm(L, t, e)) { + clvalue(L->top) = luaT_gettm(L, t, e); + ttype(L->top) = LUA_TFUNCTION; + } + else + ttype(L->top) = LUA_TNIL; + incr_top; +} + + +LUA_API void lua_settagmethod (lua_State *L, int t, const char *event) { + int e = luaI_checkevent(L, event, t); + checktag(L, t); + if (!luaT_validevent(t, e)) + luaO_verror(L, "cannot change `%.20s' tag method for type `%.20s'%.20s", + luaT_eventname[e], luaO_typenames[t], + (t == LUA_TTABLE || t == LUA_TUSERDATA) ? + " with default tag" : ""); + switch (ttype(L->top - 1)) { + case LUA_TNIL: + luaT_gettm(L, t, e) = NULL; + break; + case LUA_TFUNCTION: + luaT_gettm(L, t, e) = clvalue(L->top - 1); + break; + default: + lua_error(L, "tag method must be a function (or nil)"); + } + L->top--; +} + diff --git a/build/premake/src/Src/Lua/ltm.h b/build/premake/src/Src/Lua/ltm.h new file mode 100644 index 0000000000..86edd8d215 --- /dev/null +++ b/build/premake/src/Src/Lua/ltm.h @@ -0,0 +1,59 @@ +/* +** $Id: ltm.h,v 1.1 2003/01/24 16:26:16 jason379 Exp $ +** Tag methods +** See Copyright Notice in lua.h +*/ + +#ifndef ltm_h +#define ltm_h + + +#include "lobject.h" +#include "lstate.h" + +/* +* WARNING: if you change the order of this enumeration, +* grep "ORDER TM" +*/ +typedef enum { + TM_GETTABLE = 0, + TM_SETTABLE, + TM_INDEX, + TM_GETGLOBAL, + TM_SETGLOBAL, + TM_ADD, + TM_SUB, + TM_MUL, + TM_DIV, + TM_POW, + TM_UNM, + TM_LT, + TM_CONCAT, + TM_GC, + TM_FUNCTION, + TM_N /* number of elements in the enum */ +} TMS; + + +struct TM { + Closure *method[TM_N]; + TString *collected; /* list of garbage-collected udata with this tag */ +}; + + +#define luaT_gettm(L,tag,event) (L->TMtable[tag].method[event]) +#define luaT_gettmbyObj(L,o,e) (luaT_gettm((L),luaT_tag(o),(e))) + + +#define validtag(t) (NUM_TAGS <= (t) && (t) <= L->last_tag) + +extern const char *const luaT_eventname[]; + + +void luaT_init (lua_State *L); +void luaT_realtag (lua_State *L, int tag); +int luaT_tag (const TObject *o); +int luaT_validevent (int t, int e); /* used by compatibility module */ + + +#endif diff --git a/build/premake/src/Src/Lua/lua.h b/build/premake/src/Src/Lua/lua.h new file mode 100644 index 0000000000..47e69d4ce0 --- /dev/null +++ b/build/premake/src/Src/Lua/lua.h @@ -0,0 +1,248 @@ +/* +** $Id: lua.h,v 1.1 2003/01/24 16:26:17 jason379 Exp $ +** Lua - An Extensible Extension Language +** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil +** e-mail: lua@tecgraf.puc-rio.br +** www: http://www.tecgraf.puc-rio.br/lua/ +** See Copyright Notice at the end of this file +*/ + + +#ifndef lua_h +#define lua_h + + +/* definition of `size_t' */ +#include + + +/* mark for all API functions */ +#ifndef LUA_API +#define LUA_API extern +#endif + + +#define LUA_VERSION "Lua 4.0.1" +#define LUA_COPYRIGHT "Copyright (C) 1994-2000 TeCGraf, PUC-Rio" +#define LUA_AUTHORS "W. Celes, R. Ierusalimschy & L. H. de Figueiredo" + + +/* name of global variable with error handler */ +#define LUA_ERRORMESSAGE "_ERRORMESSAGE" + + +/* pre-defined references */ +#define LUA_NOREF (-2) +#define LUA_REFNIL (-1) +#define LUA_REFREGISTRY 0 + +/* pre-defined tags */ +#define LUA_ANYTAG (-1) +#define LUA_NOTAG (-2) + + +/* option for multiple returns in lua_call */ +#define LUA_MULTRET (-1) + + +/* minimum stack available for a C function */ +#define LUA_MINSTACK 20 + + +/* error codes for lua_do* */ +#define LUA_ERRRUN 1 +#define LUA_ERRFILE 2 +#define LUA_ERRSYNTAX 3 +#define LUA_ERRMEM 4 +#define LUA_ERRERR 5 + + +typedef struct lua_State lua_State; + +typedef int (*lua_CFunction) (lua_State *L); + +/* +** types returned by `lua_type' +*/ +#define LUA_TNONE (-1) + +#define LUA_TUSERDATA 0 +#define LUA_TNIL 1 +#define LUA_TNUMBER 2 +#define LUA_TSTRING 3 +#define LUA_TTABLE 4 +#define LUA_TFUNCTION 5 + + + +/* +** state manipulation +*/ +LUA_API lua_State *lua_open (int stacksize); +LUA_API void lua_close (lua_State *L); + + +/* +** basic stack manipulation +*/ +LUA_API int lua_gettop (lua_State *L); +LUA_API void lua_settop (lua_State *L, int index); +LUA_API void lua_pushvalue (lua_State *L, int index); +LUA_API void lua_remove (lua_State *L, int index); +LUA_API void lua_insert (lua_State *L, int index); +LUA_API int lua_stackspace (lua_State *L); + + +/* +** access functions (stack -> C) +*/ + +LUA_API int lua_type (lua_State *L, int index); +LUA_API const char *lua_typename (lua_State *L, int t); +LUA_API int lua_isnumber (lua_State *L, int index); +LUA_API int lua_isstring (lua_State *L, int index); +LUA_API int lua_iscfunction (lua_State *L, int index); +LUA_API int lua_tag (lua_State *L, int index); + +LUA_API int lua_equal (lua_State *L, int index1, int index2); +LUA_API int lua_lessthan (lua_State *L, int index1, int index2); + +LUA_API double lua_tonumber (lua_State *L, int index); +LUA_API const char *lua_tostring (lua_State *L, int index); +LUA_API size_t lua_strlen (lua_State *L, int index); +LUA_API lua_CFunction lua_tocfunction (lua_State *L, int index); +LUA_API void *lua_touserdata (lua_State *L, int index); +LUA_API const void *lua_topointer (lua_State *L, int index); + + +/* +** push functions (C -> stack) +*/ +LUA_API void lua_pushnil (lua_State *L); +LUA_API void lua_pushnumber (lua_State *L, double n); +LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len); +LUA_API void lua_pushstring (lua_State *L, const char *s); +LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n); +LUA_API void lua_pushusertag (lua_State *L, void *u, int tag); + + +/* +** get functions (Lua -> stack) +*/ +LUA_API void lua_getglobal (lua_State *L, const char *name); +LUA_API void lua_gettable (lua_State *L, int index); +LUA_API void lua_rawget (lua_State *L, int index); +LUA_API void lua_rawgeti (lua_State *L, int index, int n); +LUA_API void lua_getglobals (lua_State *L); +LUA_API void lua_gettagmethod (lua_State *L, int tag, const char *event); +LUA_API int lua_getref (lua_State *L, int ref); +LUA_API void lua_newtable (lua_State *L); + + +/* +** set functions (stack -> Lua) +*/ +LUA_API void lua_setglobal (lua_State *L, const char *name); +LUA_API void lua_settable (lua_State *L, int index); +LUA_API void lua_rawset (lua_State *L, int index); +LUA_API void lua_rawseti (lua_State *L, int index, int n); +LUA_API void lua_setglobals (lua_State *L); +LUA_API void lua_settagmethod (lua_State *L, int tag, const char *event); +LUA_API int lua_ref (lua_State *L, int lock); + + +/* +** "do" functions (run Lua code) +*/ +LUA_API int lua_call (lua_State *L, int nargs, int nresults); +LUA_API void lua_rawcall (lua_State *L, int nargs, int nresults); +LUA_API int lua_dofile (lua_State *L, const char *filename); +LUA_API int lua_dostring (lua_State *L, const char *str); +LUA_API int lua_dobuffer (lua_State *L, const char *buff, size_t size, const char *name); + +/* +** Garbage-collection functions +*/ +LUA_API int lua_getgcthreshold (lua_State *L); +LUA_API int lua_getgccount (lua_State *L); +LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold); + +/* +** miscellaneous functions +*/ +LUA_API int lua_newtag (lua_State *L); +LUA_API int lua_copytagmethods (lua_State *L, int tagto, int tagfrom); +LUA_API void lua_settag (lua_State *L, int tag); + +LUA_API void lua_error (lua_State *L, const char *s); + +LUA_API void lua_unref (lua_State *L, int ref); + +LUA_API int lua_next (lua_State *L, int index); +LUA_API int lua_getn (lua_State *L, int index); + +LUA_API void lua_concat (lua_State *L, int n); + +LUA_API void *lua_newuserdata (lua_State *L, size_t size); + + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ + +#define lua_pop(L,n) lua_settop(L, -(n)-1) + +#define lua_register(L,n,f) (lua_pushcfunction(L, f), lua_setglobal(L, n)) +#define lua_pushuserdata(L,u) lua_pushusertag(L, u, 0) +#define lua_pushcfunction(L,f) lua_pushcclosure(L, f, 0) +#define lua_clonetag(L,t) lua_copytagmethods(L, lua_newtag(L), (t)) + +#define lua_isfunction(L,n) (lua_type(L,n) == LUA_TFUNCTION) +#define lua_istable(L,n) (lua_type(L,n) == LUA_TTABLE) +#define lua_isuserdata(L,n) (lua_type(L,n) == LUA_TUSERDATA) +#define lua_isnil(L,n) (lua_type(L,n) == LUA_TNIL) +#define lua_isnull(L,n) (lua_type(L,n) == LUA_TNONE) + +#define lua_getregistry(L) lua_getref(L, LUA_REFREGISTRY) + +#endif + + + +/****************************************************************************** +* Copyright (C) 1994-2000 TeCGraf, PUC-Rio. All rights reserved. +* +* Permission is hereby granted, without written agreement and without license +* or royalty fees, to use, copy, modify, and distribute this software and its +* documentation for any purpose, including commercial applications, subject to +* the following conditions: +* +* - The above copyright notice and this permission notice shall appear in all +* copies or substantial portions of this software. +* +* - The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software in a +* product, an acknowledgment in the product documentation would be greatly +* appreciated (but it is not required). +* +* - Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* +* The authors specifically disclaim any warranties, including, but not limited +* to, the implied warranties of merchantability and fitness for a particular +* purpose. The software provided hereunder is on an "as is" basis, and the +* authors have no obligation to provide maintenance, support, updates, +* enhancements, or modifications. In no event shall TeCGraf, PUC-Rio, or the +* authors be held liable to any party for direct, indirect, special, +* incidental, or consequential damages arising out of the use of this software +* and its documentation. +* +* The Lua language and this implementation have been entirely designed and +* written by Waldemar Celes Filho, Roberto Ierusalimschy and +* Luiz Henrique de Figueiredo at TeCGraf, PUC-Rio. +* +* This implementation contains no third-party code. +******************************************************************************/ + diff --git a/build/premake/src/Src/Lua/luadebug.h b/build/premake/src/Src/Lua/luadebug.h new file mode 100644 index 0000000000..a244e72438 --- /dev/null +++ b/build/premake/src/Src/Lua/luadebug.h @@ -0,0 +1,46 @@ +/* +** $Id: luadebug.h,v 1.1 2003/01/24 16:26:17 jason379 Exp $ +** Debugging API +** See Copyright Notice in lua.h +*/ + + +#ifndef luadebug_h +#define luadebug_h + + +#include "lua.h" + +typedef struct lua_Debug lua_Debug; /* activation record */ +typedef struct lua_Localvar lua_Localvar; + +typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); + + +LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar); +LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar); +LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n); + +LUA_API lua_Hook lua_setcallhook (lua_State *L, lua_Hook func); +LUA_API lua_Hook lua_setlinehook (lua_State *L, lua_Hook func); + + +#define LUA_IDSIZE 60 + +struct lua_Debug { + const char *event; /* `call', `return' */ + int currentline; /* (l) */ + const char *name; /* (n) */ + const char *namewhat; /* (n) `global', `tag method', `local', `field' */ + int nups; /* (u) number of upvalues */ + int linedefined; /* (S) */ + const char *what; /* (S) `Lua' function, `C' function, Lua `main' */ + const char *source; /* (S) */ + char short_src[LUA_IDSIZE]; /* (S) */ + /* private part */ + struct lua_TObject *_func; /* active function */ +}; + + +#endif diff --git a/build/premake/src/Src/Lua/lualib.h b/build/premake/src/Src/Lua/lualib.h new file mode 100644 index 0000000000..1bf2ca91fa --- /dev/null +++ b/build/premake/src/Src/Lua/lualib.h @@ -0,0 +1,34 @@ +/* +** $Id: lualib.h,v 1.1 2003/01/24 16:26:18 jason379 Exp $ +** Lua standard libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lualib_h +#define lualib_h + +#include "lua.h" + + +#ifndef LUALIB_API +#define LUALIB_API extern +#endif + + +#define LUA_ALERT "_ALERT" + +LUALIB_API void lua_baselibopen (lua_State *L); +LUALIB_API void lua_iolibopen (lua_State *L); +LUALIB_API void lua_strlibopen (lua_State *L); +LUALIB_API void lua_mathlibopen (lua_State *L); +LUALIB_API void lua_dblibopen (lua_State *L); + + + +/* Auxiliary functions (private) */ + +const char *luaI_classend (lua_State *L, const char *p); +int luaI_singlematch (int c, const char *p, const char *ep); + +#endif diff --git a/build/premake/src/Src/Lua/lundump.c b/build/premake/src/Src/Lua/lundump.c new file mode 100644 index 0000000000..39dc3d8d56 --- /dev/null +++ b/build/premake/src/Src/Lua/lundump.c @@ -0,0 +1,244 @@ +/* +** $Id: lundump.c,v 1.1 2003/01/24 16:26:18 jason379 Exp $ +** load bytecodes from files +** See Copyright Notice in lua.h +*/ + +#include +#include + +#include "lfunc.h" +#include "lmem.h" +#include "lopcodes.h" +#include "lstring.h" +#include "lundump.h" + +#define LoadByte ezgetc + +static const char* ZNAME (ZIO* Z) +{ + const char* s=zname(Z); + return (*s=='@') ? s+1 : s; +} + +static void unexpectedEOZ (lua_State* L, ZIO* Z) +{ + luaO_verror(L,"unexpected end of file in `%.99s'",ZNAME(Z)); +} + +static int ezgetc (lua_State* L, ZIO* Z) +{ + int c=zgetc(Z); + if (c==EOZ) unexpectedEOZ(L,Z); + return c; +} + +static void ezread (lua_State* L, ZIO* Z, void* b, int n) +{ + int r=zread(Z,b,n); + if (r!=0) unexpectedEOZ(L,Z); +} + +static void LoadBlock (lua_State* L, void* b, size_t size, ZIO* Z, int swap) +{ + if (swap) + { + char *p=(char *) b+size-1; + int n=size; + while (n--) *p--=(char)ezgetc(L,Z); + } + else + ezread(L,Z,b,size); +} + +static void LoadVector (lua_State* L, void* b, int m, size_t size, ZIO* Z, int swap) +{ + if (swap) + { + char *q=(char *) b; + while (m--) + { + char *p=q+size-1; + int n=size; + while (n--) *p--=(char)ezgetc(L,Z); + q+=size; + } + } + else + ezread(L,Z,b,m*size); +} + +static int LoadInt (lua_State* L, ZIO* Z, int swap) +{ + int x; + LoadBlock(L,&x,sizeof(x),Z,swap); + return x; +} + +static size_t LoadSize (lua_State* L, ZIO* Z, int swap) +{ + size_t x; + LoadBlock(L,&x,sizeof(x),Z,swap); + return x; +} + +static Number LoadNumber (lua_State* L, ZIO* Z, int swap) +{ + Number x; + LoadBlock(L,&x,sizeof(x),Z,swap); + return x; +} + +static TString* LoadString (lua_State* L, ZIO* Z, int swap) +{ + size_t size=LoadSize(L,Z,swap); + if (size==0) + return NULL; + else + { + char* s=luaO_openspace(L,size); + LoadBlock(L,s,size,Z,0); + return luaS_newlstr(L,s,size-1); /* remove trailing '\0' */ + } +} + +static void LoadCode (lua_State* L, Proto* tf, ZIO* Z, int swap) +{ + int size=LoadInt(L,Z,swap); + tf->code=luaM_newvector(L,size,Instruction); + LoadVector(L,tf->code,size,sizeof(*tf->code),Z,swap); + if (tf->code[size-1]!=OP_END) luaO_verror(L,"bad code in `%.99s'",ZNAME(Z)); + luaF_protook(L,tf,size); +} + +static void LoadLocals (lua_State* L, Proto* tf, ZIO* Z, int swap) +{ + int i,n; + tf->nlocvars=n=LoadInt(L,Z,swap); + tf->locvars=luaM_newvector(L,n,LocVar); + for (i=0; ilocvars[i].varname=LoadString(L,Z,swap); + tf->locvars[i].startpc=LoadInt(L,Z,swap); + tf->locvars[i].endpc=LoadInt(L,Z,swap); + } +} + +static void LoadLines (lua_State* L, Proto* tf, ZIO* Z, int swap) +{ + int n; + tf->nlineinfo=n=LoadInt(L,Z,swap); + tf->lineinfo=luaM_newvector(L,n,int); + LoadVector(L,tf->lineinfo,n,sizeof(*tf->lineinfo),Z,swap); +} + +static Proto* LoadFunction (lua_State* L, ZIO* Z, int swap); + +static void LoadConstants (lua_State* L, Proto* tf, ZIO* Z, int swap) +{ + int i,n; + tf->nkstr=n=LoadInt(L,Z,swap); + tf->kstr=luaM_newvector(L,n,TString*); + for (i=0; ikstr[i]=LoadString(L,Z,swap); + tf->nknum=n=LoadInt(L,Z,swap); + tf->knum=luaM_newvector(L,n,Number); + LoadVector(L,tf->knum,n,sizeof(*tf->knum),Z,swap); + tf->nkproto=n=LoadInt(L,Z,swap); + tf->kproto=luaM_newvector(L,n,Proto*); + for (i=0; ikproto[i]=LoadFunction(L,Z,swap); +} + +static Proto* LoadFunction (lua_State* L, ZIO* Z, int swap) +{ + Proto* tf=luaF_newproto(L); + tf->source=LoadString(L,Z,swap); + tf->lineDefined=LoadInt(L,Z,swap); + tf->numparams=LoadInt(L,Z,swap); + tf->is_vararg=LoadByte(L,Z); + tf->maxstacksize=LoadInt(L,Z,swap); + LoadLocals(L,tf,Z,swap); + LoadLines(L,tf,Z,swap); + LoadConstants(L,tf,Z,swap); + LoadCode(L,tf,Z,swap); + return tf; +} + +static void LoadSignature (lua_State* L, ZIO* Z) +{ + const char* s=SIGNATURE; + while (*s!=0 && ezgetc(L,Z)==*s) + ++s; + if (*s!=0) luaO_verror(L,"bad signature in `%.99s'",ZNAME(Z)); +} + +static void TestSize (lua_State* L, int s, const char* what, ZIO* Z) +{ + int r=ezgetc(L,Z); + if (r!=s) + luaO_verror(L,"virtual machine mismatch in `%.99s':\n" + " %.20s is %d but read %d",ZNAME(Z),what,s,r); +} + +#define TESTSIZE(s) TestSize(L,s,#s,Z) +#define V(v) v/16,v%16 + +static int LoadHeader (lua_State* L, ZIO* Z) +{ + int version,swap; + Number f=0,tf=TEST_NUMBER; + LoadSignature(L,Z); + version=ezgetc(L,Z); + if (version>VERSION) + luaO_verror(L,"`%.99s' too new:\n" + " read version %d.%d; expected at most %d.%d", + ZNAME(Z),V(version),V(VERSION)); + if (version" +#define SOURCE tf->lineDefined,tf->source->str +#define IN_FMT " in %p " SOURCE_FMT +#define IN tf,SOURCE + +/* a multiple of PI for testing native format */ +/* multiplying by 1E8 gives non-trivial integer values */ +#define TEST_NUMBER 3.14159265358979323846E8 + +#endif diff --git a/build/premake/src/Src/Lua/lvm.c b/build/premake/src/Src/Lua/lvm.c new file mode 100644 index 0000000000..2243d3e745 --- /dev/null +++ b/build/premake/src/Src/Lua/lvm.c @@ -0,0 +1,710 @@ +/* +** $Id: lvm.c,v 1.1 2003/01/24 16:26:18 jason379 Exp $ +** Lua virtual machine +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include + +#include "lua.h" + +#include "lapi.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lvm.h" + + +#ifdef OLD_ANSI +#define strcoll(a,b) strcmp(a,b) +#endif + + + +/* +** Extra stack size to run a function: +** TAG_LINE(1), NAME(1), TM calls(3) (plus some extra...) +*/ +#define EXTRA_STACK 8 + + + +int luaV_tonumber (TObject *obj) { + if (ttype(obj) != LUA_TSTRING) + return 1; + else { + if (!luaO_str2d(svalue(obj), &nvalue(obj))) + return 2; + ttype(obj) = LUA_TNUMBER; + return 0; + } +} + + +int luaV_tostring (lua_State *L, TObject *obj) { /* LUA_NUMBER */ + if (ttype(obj) != LUA_TNUMBER) + return 1; + else { + char s[32]; /* 16 digits, sign, point and \0 (+ some extra...) */ + lua_number2str(s, nvalue(obj)); /* convert `s' to number */ + tsvalue(obj) = luaS_new(L, s); + ttype(obj) = LUA_TSTRING; + return 0; + } +} + + +static void traceexec (lua_State *L, StkId base, StkId top, lua_Hook linehook) { + CallInfo *ci = infovalue(base-1); + int *lineinfo = ci->func->f.l->lineinfo; + int pc = (*ci->pc - ci->func->f.l->code) - 1; + int newline; + if (pc == 0) { /* may be first time? */ + ci->line = 1; + ci->refi = 0; + ci->lastpc = pc+1; /* make sure it will call linehook */ + } + newline = luaG_getline(lineinfo, pc, ci->line, &ci->refi); + /* calls linehook when enters a new line or jumps back (loop) */ + if (newline != ci->line || pc <= ci->lastpc) { + ci->line = newline; + L->top = top; + luaD_lineHook(L, base-1, newline, linehook); + } + ci->lastpc = pc; +} + + +static Closure *luaV_closure (lua_State *L, int nelems) { + Closure *c = luaF_newclosure(L, nelems); + L->top -= nelems; + while (nelems--) + c->upvalue[nelems] = *(L->top+nelems); + clvalue(L->top) = c; + ttype(L->top) = LUA_TFUNCTION; + incr_top; + return c; +} + + +void luaV_Cclosure (lua_State *L, lua_CFunction c, int nelems) { + Closure *cl = luaV_closure(L, nelems); + cl->f.c = c; + cl->isC = 1; +} + + +void luaV_Lclosure (lua_State *L, Proto *l, int nelems) { + Closure *cl = luaV_closure(L, nelems); + cl->f.l = l; + cl->isC = 0; +} + + +/* +** Function to index a table. +** Receives the table at `t' and the key at top. +*/ +const TObject *luaV_gettable (lua_State *L, StkId t) { + Closure *tm; + int tg; + if (ttype(t) == LUA_TTABLE && /* `t' is a table? */ + ((tg = hvalue(t)->htag) == LUA_TTABLE || /* with default tag? */ + luaT_gettm(L, tg, TM_GETTABLE) == NULL)) { /* or no TM? */ + /* do a primitive get */ + const TObject *h = luaH_get(L, hvalue(t), L->top-1); + /* result is no nil or there is no `index' tag method? */ + if (ttype(h) != LUA_TNIL || ((tm=luaT_gettm(L, tg, TM_INDEX)) == NULL)) + return h; /* return result */ + /* else call `index' tag method */ + } + else { /* try a `gettable' tag method */ + tm = luaT_gettmbyObj(L, t, TM_GETTABLE); + } + if (tm != NULL) { /* is there a tag method? */ + luaD_checkstack(L, 2); + *(L->top+1) = *(L->top-1); /* key */ + *L->top = *t; /* table */ + clvalue(L->top-1) = tm; /* tag method */ + ttype(L->top-1) = LUA_TFUNCTION; + L->top += 2; + luaD_call(L, L->top - 3, 1); + return L->top - 1; /* call result */ + } + else { /* no tag method */ + luaG_typeerror(L, t, "index"); + return NULL; /* to avoid warnings */ + } +} + + +/* +** Receives table at `t', key at `key' and value at top. +*/ +void luaV_settable (lua_State *L, StkId t, StkId key) { + int tg; + if (ttype(t) == LUA_TTABLE && /* `t' is a table? */ + ((tg = hvalue(t)->htag) == LUA_TTABLE || /* with default tag? */ + luaT_gettm(L, tg, TM_SETTABLE) == NULL)) /* or no TM? */ + *luaH_set(L, hvalue(t), key) = *(L->top-1); /* do a primitive set */ + else { /* try a `settable' tag method */ + Closure *tm = luaT_gettmbyObj(L, t, TM_SETTABLE); + if (tm != NULL) { + luaD_checkstack(L, 3); + *(L->top+2) = *(L->top-1); + *(L->top+1) = *key; + *(L->top) = *t; + clvalue(L->top-1) = tm; + ttype(L->top-1) = LUA_TFUNCTION; + L->top += 3; + luaD_call(L, L->top - 4, 0); /* call `settable' tag method */ + } + else /* no tag method... */ + luaG_typeerror(L, t, "index"); + } +} + + +const TObject *luaV_getglobal (lua_State *L, TString *s) { + const TObject *value = luaH_getstr(L->gt, s); + Closure *tm = luaT_gettmbyObj(L, value, TM_GETGLOBAL); + if (tm == NULL) /* is there a tag method? */ + return value; /* default behavior */ + else { /* tag method */ + luaD_checkstack(L, 3); + clvalue(L->top) = tm; + ttype(L->top) = LUA_TFUNCTION; + tsvalue(L->top+1) = s; /* global name */ + ttype(L->top+1) = LUA_TSTRING; + *(L->top+2) = *value; + L->top += 3; + luaD_call(L, L->top - 3, 1); + return L->top - 1; + } +} + + +void luaV_setglobal (lua_State *L, TString *s) { + const TObject *oldvalue = luaH_getstr(L->gt, s); + Closure *tm = luaT_gettmbyObj(L, oldvalue, TM_SETGLOBAL); + if (tm == NULL) { /* is there a tag method? */ + if (oldvalue != &luaO_nilobject) { + /* cast to remove `const' is OK, because `oldvalue' != luaO_nilobject */ + *(TObject *)oldvalue = *(L->top - 1); + } + else { + TObject key; + ttype(&key) = LUA_TSTRING; + tsvalue(&key) = s; + *luaH_set(L, L->gt, &key) = *(L->top - 1); + } + } + else { + luaD_checkstack(L, 3); + *(L->top+2) = *(L->top-1); /* new value */ + *(L->top+1) = *oldvalue; + ttype(L->top) = LUA_TSTRING; + tsvalue(L->top) = s; + clvalue(L->top-1) = tm; + ttype(L->top-1) = LUA_TFUNCTION; + L->top += 3; + luaD_call(L, L->top - 4, 0); + } +} + + +static int call_binTM (lua_State *L, StkId top, TMS event) { + /* try first operand */ + Closure *tm = luaT_gettmbyObj(L, top-2, event); + L->top = top; + if (tm == NULL) { + tm = luaT_gettmbyObj(L, top-1, event); /* try second operand */ + if (tm == NULL) { + tm = luaT_gettm(L, 0, event); /* try a `global' method */ + if (tm == NULL) + return 0; /* error */ + } + } + lua_pushstring(L, luaT_eventname[event]); + luaD_callTM(L, tm, 3, 1); + return 1; +} + + +static void call_arith (lua_State *L, StkId top, TMS event) { + if (!call_binTM(L, top, event)) + luaG_binerror(L, top-2, LUA_TNUMBER, "perform arithmetic on"); +} + + +static int luaV_strcomp (const TString *ls, const TString *rs) { + const char *l = ls->str; + size_t ll = ls->len; + const char *r = rs->str; + size_t lr = rs->len; + for (;;) { + int temp = strcoll(l, r); + if (temp != 0) return temp; + else { /* strings are equal up to a '\0' */ + size_t len = strlen(l); /* index of first '\0' in both strings */ + if (len == ll) /* l is finished? */ + return (len == lr) ? 0 : -1; /* l is equal or smaller than r */ + else if (len == lr) /* r is finished? */ + return 1; /* l is greater than r (because l is not finished) */ + /* both strings longer than `len'; go on comparing (after the '\0') */ + len++; + l += len; ll -= len; r += len; lr -= len; + } + } +} + + +int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top) { + if (ttype(l) == LUA_TNUMBER && ttype(r) == LUA_TNUMBER) + return (nvalue(l) < nvalue(r)); + else if (ttype(l) == LUA_TSTRING && ttype(r) == LUA_TSTRING) + return (luaV_strcomp(tsvalue(l), tsvalue(r)) < 0); + else { /* call TM */ + luaD_checkstack(L, 2); + *top++ = *l; + *top++ = *r; + if (!call_binTM(L, top, TM_LT)) + luaG_ordererror(L, top-2); + L->top--; + return (ttype(L->top) != LUA_TNIL); + } +} + + +void luaV_strconc (lua_State *L, int total, StkId top) { + do { + int n = 2; /* number of elements handled in this pass (at least 2) */ + if (tostring(L, top-2) || tostring(L, top-1)) { + if (!call_binTM(L, top, TM_CONCAT)) + luaG_binerror(L, top-2, LUA_TSTRING, "concat"); + } + else if (tsvalue(top-1)->len > 0) { /* if len=0, do nothing */ + /* at least two string values; get as many as possible */ + lint32 tl = (lint32)tsvalue(top-1)->len + + (lint32)tsvalue(top-2)->len; + char *buffer; + int i; + while (n < total && !tostring(L, top-n-1)) { /* collect total length */ + tl += tsvalue(top-n-1)->len; + n++; + } + if (tl > MAX_SIZET) lua_error(L, "string size overflow"); + buffer = luaO_openspace(L, tl); + tl = 0; + for (i=n; i>0; i--) { /* concat all strings */ + size_t l = tsvalue(top-i)->len; + memcpy(buffer+tl, tsvalue(top-i)->str, l); + tl += l; + } + tsvalue(top-n) = luaS_newlstr(L, buffer, tl); + } + total -= n-1; /* got `n' strings to create 1 new */ + top -= n-1; + } while (total > 1); /* repeat until only 1 result left */ +} + + +static void luaV_pack (lua_State *L, StkId firstelem) { + int i; + Hash *htab = luaH_new(L, 0); + for (i=0; firstelem+itop; i++) + *luaH_setint(L, htab, i+1) = *(firstelem+i); + /* store counter in field `n' */ + luaH_setstrnum(L, htab, luaS_new(L, "n"), i); + L->top = firstelem; /* remove elements from the stack */ + ttype(L->top) = LUA_TTABLE; + hvalue(L->top) = htab; + incr_top; +} + + +static void adjust_varargs (lua_State *L, StkId base, int nfixargs) { + int nvararg = (L->top-base) - nfixargs; + if (nvararg < 0) + luaD_adjusttop(L, base, nfixargs); + luaV_pack(L, base+nfixargs); +} + + + +#define dojump(pc, i) { int d = GETARG_S(i); pc += d; } + +/* +** Executes the given Lua function. Parameters are between [base,top). +** Returns n such that the the results are between [n,top). +*/ +StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { + const Proto *const tf = cl->f.l; + StkId top; /* keep top local, for performance */ + const Instruction *pc = tf->code; + TString **const kstr = tf->kstr; + const lua_Hook linehook = L->linehook; + infovalue(base-1)->pc = &pc; + luaD_checkstack(L, tf->maxstacksize+EXTRA_STACK); + if (tf->is_vararg) /* varargs? */ + adjust_varargs(L, base, tf->numparams); + else + luaD_adjusttop(L, base, tf->numparams); + top = L->top; + /* main loop of interpreter */ + for (;;) { + const Instruction i = *pc++; + if (linehook) + traceexec(L, base, top, linehook); + switch (GET_OPCODE(i)) { + case OP_END: { + L->top = top; + return top; + } + case OP_RETURN: { + L->top = top; + return base+GETARG_U(i); + } + case OP_CALL: { + int nres = GETARG_B(i); + if (nres == MULT_RET) nres = LUA_MULTRET; + L->top = top; + luaD_call(L, base+GETARG_A(i), nres); + top = L->top; + break; + } + case OP_TAILCALL: { + L->top = top; + luaD_call(L, base+GETARG_A(i), LUA_MULTRET); + return base+GETARG_B(i); + } + case OP_PUSHNIL: { + int n = GETARG_U(i); + LUA_ASSERT(n>0, "invalid argument"); + do { + ttype(top++) = LUA_TNIL; + } while (--n > 0); + break; + } + case OP_POP: { + top -= GETARG_U(i); + break; + } + case OP_PUSHINT: { + ttype(top) = LUA_TNUMBER; + nvalue(top) = (Number)GETARG_S(i); + top++; + break; + } + case OP_PUSHSTRING: { + ttype(top) = LUA_TSTRING; + tsvalue(top) = kstr[GETARG_U(i)]; + top++; + break; + } + case OP_PUSHNUM: { + ttype(top) = LUA_TNUMBER; + nvalue(top) = tf->knum[GETARG_U(i)]; + top++; + break; + } + case OP_PUSHNEGNUM: { + ttype(top) = LUA_TNUMBER; + nvalue(top) = -tf->knum[GETARG_U(i)]; + top++; + break; + } + case OP_PUSHUPVALUE: { + *top++ = cl->upvalue[GETARG_U(i)]; + break; + } + case OP_GETLOCAL: { + *top++ = *(base+GETARG_U(i)); + break; + } + case OP_GETGLOBAL: { + L->top = top; + *top = *luaV_getglobal(L, kstr[GETARG_U(i)]); + top++; + break; + } + case OP_GETTABLE: { + L->top = top; + top--; + *(top-1) = *luaV_gettable(L, top-1); + break; + } + case OP_GETDOTTED: { + ttype(top) = LUA_TSTRING; + tsvalue(top) = kstr[GETARG_U(i)]; + L->top = top+1; + *(top-1) = *luaV_gettable(L, top-1); + break; + } + case OP_GETINDEXED: { + *top = *(base+GETARG_U(i)); + L->top = top+1; + *(top-1) = *luaV_gettable(L, top-1); + break; + } + case OP_PUSHSELF: { + TObject receiver; + receiver = *(top-1); + ttype(top) = LUA_TSTRING; + tsvalue(top++) = kstr[GETARG_U(i)]; + L->top = top; + *(top-2) = *luaV_gettable(L, top-2); + *(top-1) = receiver; + break; + } + case OP_CREATETABLE: { + L->top = top; + luaC_checkGC(L); + hvalue(top) = luaH_new(L, GETARG_U(i)); + ttype(top) = LUA_TTABLE; + top++; + break; + } + case OP_SETLOCAL: { + *(base+GETARG_U(i)) = *(--top); + break; + } + case OP_SETGLOBAL: { + L->top = top; + luaV_setglobal(L, kstr[GETARG_U(i)]); + top--; + break; + } + case OP_SETTABLE: { + StkId t = top-GETARG_A(i); + L->top = top; + luaV_settable(L, t, t+1); + top -= GETARG_B(i); /* pop values */ + break; + } + case OP_SETLIST: { + int aux = GETARG_A(i) * LFIELDS_PER_FLUSH; + int n = GETARG_B(i); + Hash *arr = hvalue(top-n-1); + L->top = top-n; /* final value of `top' (in case of errors) */ + for (; n; n--) + *luaH_setint(L, arr, n+aux) = *(--top); + break; + } + case OP_SETMAP: { + int n = GETARG_U(i); + StkId finaltop = top-2*n; + Hash *arr = hvalue(finaltop-1); + L->top = finaltop; /* final value of `top' (in case of errors) */ + for (; n; n--) { + top-=2; + *luaH_set(L, arr, top) = *(top+1); + } + break; + } + case OP_ADD: { + if (tonumber(top-2) || tonumber(top-1)) + call_arith(L, top, TM_ADD); + else + nvalue(top-2) += nvalue(top-1); + top--; + break; + } + case OP_ADDI: { + if (tonumber(top-1)) { + ttype(top) = LUA_TNUMBER; + nvalue(top) = (Number)GETARG_S(i); + call_arith(L, top+1, TM_ADD); + } + else + nvalue(top-1) += (Number)GETARG_S(i); + break; + } + case OP_SUB: { + if (tonumber(top-2) || tonumber(top-1)) + call_arith(L, top, TM_SUB); + else + nvalue(top-2) -= nvalue(top-1); + top--; + break; + } + case OP_MULT: { + if (tonumber(top-2) || tonumber(top-1)) + call_arith(L, top, TM_MUL); + else + nvalue(top-2) *= nvalue(top-1); + top--; + break; + } + case OP_DIV: { + if (tonumber(top-2) || tonumber(top-1)) + call_arith(L, top, TM_DIV); + else + nvalue(top-2) /= nvalue(top-1); + top--; + break; + } + case OP_POW: { + if (!call_binTM(L, top, TM_POW)) + lua_error(L, "undefined operation"); + top--; + break; + } + case OP_CONCAT: { + int n = GETARG_U(i); + luaV_strconc(L, n, top); + top -= n-1; + L->top = top; + luaC_checkGC(L); + break; + } + case OP_MINUS: { + if (tonumber(top-1)) { + ttype(top) = LUA_TNIL; + call_arith(L, top+1, TM_UNM); + } + else + nvalue(top-1) = -nvalue(top-1); + break; + } + case OP_NOT: { + ttype(top-1) = + (ttype(top-1) == LUA_TNIL) ? LUA_TNUMBER : LUA_TNIL; + nvalue(top-1) = 1; + break; + } + case OP_JMPNE: { + top -= 2; + if (!luaO_equalObj(top, top+1)) dojump(pc, i); + break; + } + case OP_JMPEQ: { + top -= 2; + if (luaO_equalObj(top, top+1)) dojump(pc, i); + break; + } + case OP_JMPLT: { + top -= 2; + if (luaV_lessthan(L, top, top+1, top+2)) dojump(pc, i); + break; + } + case OP_JMPLE: { /* a <= b === !(b b === (b= b === !(a 0 ? + nvalue(top-3) > nvalue(top-2) : + nvalue(top-3) < nvalue(top-2)) { /* `empty' loop? */ + top -= 3; /* remove control variables */ + dojump(pc, i); /* jump to loop end */ + } + break; + } + case OP_FORLOOP: { + LUA_ASSERT(ttype(top-1) == LUA_TNUMBER, "invalid step"); + LUA_ASSERT(ttype(top-2) == LUA_TNUMBER, "invalid limit"); + if (ttype(top-3) != LUA_TNUMBER) + lua_error(L, "`for' index must be a number"); + nvalue(top-3) += nvalue(top-1); /* increment index */ + if (nvalue(top-1) > 0 ? + nvalue(top-3) > nvalue(top-2) : + nvalue(top-3) < nvalue(top-2)) + top -= 3; /* end loop: remove control variables */ + else + dojump(pc, i); /* repeat loop */ + break; + } + case OP_LFORPREP: { + Node *node; + if (ttype(top-1) != LUA_TTABLE) + lua_error(L, "`for' table must be a table"); + node = luaH_next(L, hvalue(top-1), &luaO_nilobject); + if (node == NULL) { /* `empty' loop? */ + top--; /* remove table */ + dojump(pc, i); /* jump to loop end */ + } + else { + top += 2; /* index,value */ + *(top-2) = *key(node); + *(top-1) = *val(node); + } + break; + } + case OP_LFORLOOP: { + Node *node; + LUA_ASSERT(ttype(top-3) == LUA_TTABLE, "invalid table"); + node = luaH_next(L, hvalue(top-3), top-2); + if (node == NULL) /* end loop? */ + top -= 3; /* remove table, key, and value */ + else { + *(top-2) = *key(node); + *(top-1) = *val(node); + dojump(pc, i); /* repeat loop */ + } + break; + } + case OP_CLOSURE: { + L->top = top; + luaV_Lclosure(L, tf->kproto[GETARG_A(i)], GETARG_B(i)); + top = L->top; + luaC_checkGC(L); + break; + } + } + } +} diff --git a/build/premake/src/Src/Lua/lvm.h b/build/premake/src/Src/Lua/lvm.h new file mode 100644 index 0000000000..4425fcce12 --- /dev/null +++ b/build/premake/src/Src/Lua/lvm.h @@ -0,0 +1,32 @@ +/* +** $Id: lvm.h,v 1.1 2003/01/24 16:26:18 jason379 Exp $ +** Lua virtual machine +** See Copyright Notice in lua.h +*/ + +#ifndef lvm_h +#define lvm_h + + +#include "ldo.h" +#include "lobject.h" +#include "ltm.h" + + +#define tonumber(o) ((ttype(o) != LUA_TNUMBER) && (luaV_tonumber(o) != 0)) +#define tostring(L,o) ((ttype(o) != LUA_TSTRING) && (luaV_tostring(L, o) != 0)) + + +int luaV_tonumber (TObject *obj); +int luaV_tostring (lua_State *L, TObject *obj); +const TObject *luaV_gettable (lua_State *L, StkId t); +void luaV_settable (lua_State *L, StkId t, StkId key); +const TObject *luaV_getglobal (lua_State *L, TString *s); +void luaV_setglobal (lua_State *L, TString *s); +StkId luaV_execute (lua_State *L, const Closure *cl, StkId base); +void luaV_Cclosure (lua_State *L, lua_CFunction c, int nelems); +void luaV_Lclosure (lua_State *L, Proto *l, int nelems); +int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top); +void luaV_strconc (lua_State *L, int total, StkId top); + +#endif diff --git a/build/premake/src/Src/Lua/lzio.c b/build/premake/src/Src/Lua/lzio.c new file mode 100644 index 0000000000..e21f354516 --- /dev/null +++ b/build/premake/src/Src/Lua/lzio.c @@ -0,0 +1,84 @@ +/* +** $Id: lzio.c,v 1.1 2003/01/24 16:26:18 jason379 Exp $ +** a generic input stream interface +** See Copyright Notice in lua.h +*/ + + + +#include +#include + +#include "lua.h" + +#include "lzio.h" + + + +/* ----------------------------------------------------- memory buffers --- */ + +static int zmfilbuf (ZIO* z) { + (void)z; /* to avoid warnings */ + return EOZ; +} + + +ZIO* zmopen (ZIO* z, const char* b, size_t size, const char *name) { + if (b==NULL) return NULL; + z->n = size; + z->p = (const unsigned char *)b; + z->filbuf = zmfilbuf; + z->u = NULL; + z->name = name; + return z; +} + +/* ------------------------------------------------------------ strings --- */ + +ZIO* zsopen (ZIO* z, const char* s, const char *name) { + if (s==NULL) return NULL; + return zmopen(z, s, strlen(s), name); +} + +/* -------------------------------------------------------------- FILEs --- */ + +static int zffilbuf (ZIO* z) { + size_t n; + if (feof((FILE *)z->u)) return EOZ; + n = fread(z->buffer, 1, ZBSIZE, (FILE *)z->u); + if (n==0) return EOZ; + z->n = n-1; + z->p = z->buffer; + return *(z->p++); +} + + +ZIO* zFopen (ZIO* z, FILE* f, const char *name) { + if (f==NULL) return NULL; + z->n = 0; + z->p = z->buffer; + z->filbuf = zffilbuf; + z->u = f; + z->name = name; + return z; +} + + +/* --------------------------------------------------------------- read --- */ +size_t zread (ZIO *z, void *b, size_t n) { + while (n) { + size_t m; + if (z->n == 0) { + if (z->filbuf(z) == EOZ) + return n; /* return number of missing bytes */ + zungetc(z); /* put result from `filbuf' in the buffer */ + } + m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ + memcpy(b, z->p, m); + z->n -= m; + z->p += m; + b = (char *)b + m; + n -= m; + } + return 0; +} diff --git a/build/premake/src/Src/Lua/lzio.h b/build/premake/src/Src/Lua/lzio.h new file mode 100644 index 0000000000..5c318873b8 --- /dev/null +++ b/build/premake/src/Src/Lua/lzio.h @@ -0,0 +1,53 @@ +/* +** $Id: lzio.h,v 1.1 2003/01/24 16:26:18 jason379 Exp $ +** Buffered streams +** See Copyright Notice in lua.h +*/ + + +#ifndef lzio_h +#define lzio_h + +#include + + + +/* For Lua only */ +#define zFopen luaZ_Fopen +#define zsopen luaZ_sopen +#define zmopen luaZ_mopen +#define zread luaZ_read + +#define EOZ (-1) /* end of stream */ + +typedef struct zio ZIO; + +ZIO* zFopen (ZIO* z, FILE* f, const char *name); /* open FILEs */ +ZIO* zsopen (ZIO* z, const char* s, const char *name); /* string */ +ZIO* zmopen (ZIO* z, const char* b, size_t size, const char *name); /* memory */ + +size_t zread (ZIO* z, void* b, size_t n); /* read next n bytes */ + +#define zgetc(z) (((z)->n--)>0 ? ((int)*(z)->p++): (z)->filbuf(z)) +#define zungetc(z) (++(z)->n,--(z)->p) +#define zname(z) ((z)->name) + + + +/* --------- Private Part ------------------ */ + +#ifndef ZBSIZE +#define ZBSIZE 256 /* buffer size */ +#endif + +struct zio { + size_t n; /* bytes still unread */ + const unsigned char* p; /* current position in buffer */ + int (*filbuf)(ZIO* z); + void* u; /* additional data */ + const char *name; + unsigned char buffer[ZBSIZE]; /* buffer */ +}; + + +#endif diff --git a/build/premake/src/Src/clean.c b/build/premake/src/Src/clean.c new file mode 100644 index 0000000000..dec4bb71ef --- /dev/null +++ b/build/premake/src/Src/clean.c @@ -0,0 +1,74 @@ +//----------------------------------------------------------------------------- +// Premake - clean.c +// +// Remove all project and intermediate files. +// +// Copyright (C) 2002-2003 by Jason Perkins +// Source code licensed under the GPL, see LICENSE.txt for details. +// +// $Id: clean.c,v 1.6 2004/03/27 13:42:24 jason379 Exp $ +//----------------------------------------------------------------------------- + +#include +#include +#include "project.h" +#include "util.h" + +//----------------------------------------------------------------------------- + +int makeClean() +{ + int i, j; + const char* binaries = project->binaries; + const char* libraries = project->libraries; + + puts("Removing all project and intermediate files..."); + + deleteFile(project->path, project->name, ".sln"); // VS200x + deleteFile(project->path, project->name, ".suo"); // VS200x + deleteFile(project->path, project->name, ".ncb"); // VS6/200x + deleteFile(project->path, project->name, ".dsw"); // VS6 + deleteFile(project->path, project->name, ".opt"); // VS6 + deleteFile(project->path, "Makefile", ""); // GNU + deleteFile(project->path, project->name, ".cmbx"); // SharpDevelop + + for (i = 0; i < project->numPackages; ++i) + { + Package* package = project->package[i]; + const char* name = package->name; + const char* path = package->path; + + for (j = 0; j < package->numConfigs; ++j) + { + char buffer[256]; + Config* config = package->config[j]; + const char* target = config->target; + + strcpy(buffer, "lib"); // posix shared lib + strcat(buffer, target); + deleteFile(binaries, buffer, ".so"); + + deleteFile(binaries, target, ""); // posix executable + deleteFile(binaries, target, ".exe"); // windows executable + deleteFile(binaries, target, ".dll"); // windows or .NET shared lib + deleteFile(binaries, target, ".pdb"); // VS symbol file + deleteFile(binaries, target, ".ilk"); // VS incremental link + deleteFile(libraries, target, ".pdb"); // VS symbol file + deleteFile(libraries, target, ".exp"); // VS export lib + deleteFile(libraries, target, ".lib"); // windows static lib + } + + deleteFile(path, name, ".csproj"); // VS200x + deleteFile(path, name, ".csproj.user"); // VS200x + deleteFile(path, name, ".csproj.webinfo"); // VS200x + deleteFile(path, name, ".vcproj"); // VS200x + deleteFile(path, name, ".dsp"); // VS6 + deleteFile(path, name, ".plg"); // VS6 + deleteFile(path, name, ".make"); // GNU + deleteFile(path, name, ".prjx"); // SharpDevelop + + deleteDirectory(path, "obj"); // intermediates directory + } + + return 1; +} diff --git a/build/premake/src/Src/gnu.c b/build/premake/src/Src/gnu.c new file mode 100644 index 0000000000..0147db3888 --- /dev/null +++ b/build/premake/src/Src/gnu.c @@ -0,0 +1,568 @@ +//----------------------------------------------------------------------------- +// Premake - gnu.c +// +// GNU tool target. +// +// Copyright (C) 2002-2004 by Jason Perkins +// Source code licensed under the GPL, see LICENSE.txt for details. +// +// $Id: gnu.c,v 1.26 2004/05/05 23:23:44 jason379 Exp $ +//----------------------------------------------------------------------------- + +#include +#include +#include "project.h" +#include "util.h" + +#define MAKEFILE_EXT ".make" +#define OBJECTS_DIR "obj" +#define OBJECTS_EXT ".o" + +extern const char** commandLineArgs; +extern const char* rootProjectFile; +extern const char* cc; +extern const char* dotnet; +extern int verbose; + +static int writeRootMakefile(); +static int writeCppPackage(Package* package); +static int writeCsPackage(Package* package); + +//----------------------------------------------------------------------------- + +int makeGnuScripts() +{ + int i; + + puts("Generating GNU makefiles:"); + + if (!writeRootMakefile()) + return 0; + + for (i = 0; i < project->numPackages; ++i) + { + int result; + Package* package = project->package[i]; + const char* language = package->language; + + printf("...%s\n", package->name); + + if (strcmp(language, "c#") == 0) + result = writeCsPackage(package); + else if (strcmp(language, "c++") == 0 || strcmp(language, "c") == 0) + result = writeCppPackage(package); + else + { + printf("** Error: unrecognized language '%s'\n", language); + return 0; + } + + if (!result) return 0; + } + + return 1; +} + +//----------------------------------------------------------------------------- + +static const char* checkDeps(const char* ref, void* data) +{ + int i; + for (i = 0; i < project->numPackages; ++i) + { + if (strcmp(project->package[i]->name, ref) == 0) + return project->package[i]->name; + } + return NULL; +} + +static int writeRootMakefile() +{ + int i; + FILE* file; + + file = openFile(project->path, "Makefile", ""); + if (file == NULL) + { + puts("Error: unable to open Makefile\n"); + return 0; + } + + // Print the header, showing the possible build configurations + + fprintf(file, "# Makefile autogenerated by premake\n"); + fprintf(file, "# Options:\n"); + fprintf(file, "# CONFIG=["); + for (i = 0; i < project->package[0]->numConfigs; ++i) + { + if (i > 0) fprintf(file, "|"); + fprintf(file, project->package[0]->config[i]->name); + } + + fprintf(file, "]\n\n"); + + // Set a default build config if none specified + + fprintf(file, "ifndef CONFIG\n"); + fprintf(file, " CONFIG=%s\n", project->package[0]->config[0]->name); + fprintf(file, "endif\n\n"); + fprintf(file, "export CONFIG\n\n"); + + // List all of the available make targets + + fprintf(file, ".PHONY: all clean"); + for (i = 0; i < project->numPackages; ++i) + fprintf(file, " %s", project->package[i]->name); + fprintf(file, "\n\n"); + + // Make rules + + fprintf(file, "all:"); + for (i = 0; i < project->numPackages; ++i) + fprintf(file, " %s", project->package[i]->name); + fprintf(file, "\n\n"); + + // Target to regenerate the makefiles when the premake scripts change + + fprintf(file, "Makefile: %s%s", reversePath(project->path, ".", UNIX), rootProjectFile); + for (i = 0; i < project->numPackages; ++i) + { + if (project->package[i]->script != NULL) + fprintf(file, " %s%s", reversePath(project->path, ".", UNIX), project->package[i]->script); + } + fprintf(file, "\n"); + fprintf(file, "\t@echo ==== Regenerating Makefiles ====\n"); + fprintf(file, "\t@premake"); + for (i = 1; args[i] != NULL; ++i) + fprintf(file, " %s", args[i]); + fprintf(file, "\n\n"); + + // Individual package targets + + for (i = 0; i < project->numPackages; ++i) + { + Package* package = project->package[i]; + + fprintf(file, "%s:", package->name); + writeList(file, package->config[0]->links, " ", "", "", checkDeps, NULL); + fprintf(file, "\n"); + + fprintf(file, "\t@echo ==== Building %s ====\n", package->name); + fprintf(file, "\t@$(MAKE) "); + fprintf(file, "--no-print-directory -C %s ", reversePath(project->path, package->path, UNIX)); + fprintf(file, "-f %s%s\n", package->name, MAKEFILE_EXT); + fprintf(file, "\n"); + } + + fprintf(file, "clean:\n"); + for (i = 0; i < project->numPackages; ++i) + { + Package* package = project->package[i]; + + fprintf(file, "\t@$(MAKE) "); + fprintf(file, "--no-print-directory -C %s ", reversePath(project->path, package->path, UNIX)); + fprintf(file, "-f %s%s clean\n", package->name, MAKEFILE_EXT); + } + + fclose(file); + return 1; +} + +//----------------------------------------------------------------------------- + +static const char* checkCppSources(const char* file, void* data) +{ + if (isCppFile(file)) + return replaceExtension(getFilename(file,0), OBJECTS_EXT); + return NULL; +} + +static const char* checkCppFlags(const char* flag, void* data) +{ + char* cc = (char*)data; + + if (strcmp(flag, "with-symbols") == 0) + return "-g"; + else if (strcmp(flag, "optimize-size") == 0) + return "-Os"; + else if (strcmp(flag, "optimize-speed") == 0) + return "-O3"; + else if (strcmp(flag, "no-rtti") == 0 && strcmp(cc, "C++") == 0) + return "--no-rtti"; + else if (strcmp(flag, "no-exceptions") == 0 && strcmp(cc, "C++") == 0) + return "--no-exceptions"; + else + return NULL; +} + +static void writeSourcePaths(FILE* file, const char* path, int stage) +{ + if (stage == WST_OPENGROUP && strlen(path) > 0) + fprintf(file, " %s", path); +} + +static const char* checkLink(const char* path, void* data) +{ + Package* package = getPackage(path); + if (package == NULL) return path; + + if (strcmp(package->language, "c++") == 0 || strcmp(package->language, "c") == 0) + return package->config[*((int*)data)]->target; + + return NULL; +} + +static int writeCppPackage(Package* package) +{ + const char* prefix = (verbose) ? "" : "@"; + + char buffer[4096]; + const char* cflags; + const char* ldflags; + FILE* file; + int i; + + const char* name = package->name; + const char* path = package->path; + const char* kind = package->kind; + + const char* location; + + // Set up the flags specific to the type of binary being built + + cflags = ""; + ldflags = ""; + location = "$(BINDIR)"; + + if (strcmp(kind, "exe") == 0 || strcmp(kind, "winexe") == 0) + { + /* defaults are fine */ + } + else if (strcmp(kind, "dll") == 0) + { + if (strcmp(osIdent, "windows") != 0) + cflags = " -fPIC"; + if (cc == NULL || strcmp(cc, "gcc") == 0) + ldflags = " -shared"; + } + else if (strcmp(kind, "lib") == 0) + { + location = "$(LIBDIR)"; + } + else + { + printf("** Error: unknown package type '%s'\n", kind); + return 0; + } + + // Open package makefile and write the header + + file = openFile(path, name, MAKEFILE_EXT); + if (file == NULL) return 0; + + fprintf(file, "# Sub-makefile autogenerated by premake\n\n"); + + // Build bin and lib paths, trim off trailing slash + strcpy(buffer, reversePath(path, project->binaries, UNIX)); + buffer[strlen(buffer)-1] = '\0'; + fprintf(file, "BINDIR = %s\n", buffer); + + strcpy(buffer, reversePath(path, project->libraries, UNIX)); + buffer[strlen(buffer)-1] = '\0'; + fprintf(file, "LIBDIR = %s\n\n", buffer); + + fprintf(file, "CFLAGS =%s\n", cflags); + fprintf(file, "LDFLAGS = -L$(BINDIR) -L$(LIBDIR)%s\n", ldflags); + fprintf(file, "TARGET =\n"); + if (strcmp(osIdent, "macosx") == 0 && strcmp(kind, "winexe") == 0) + fprintf(file, "MACAPP = \n"); + fprintf(file, "\n"); + + // Process the build configurations + + for (i = 0; i < package->numConfigs; ++i) + { + Config* config = package->config[i]; + fprintf(file, "ifeq ($(CONFIG),%s)\n", config->name); + + fprintf(file, " CFLAGS +="); + writeList(file, config->buildOptions, " ", "", "", NULL, "C"); + writeList(file, config->buildFlags, " ", "", "", checkCppFlags, "C"); + + if (strcmp(osIdent, "windows") == 0) + fprintf(file, " -D_WIN32"); + writeList(file, config->defines, " -D \"", "\"", "", NULL, NULL); + writeList(file, config->includePaths, " -I ", "", "", NULL, NULL); + fprintf(file, "\n"); + + fprintf(file, " CXXFLAGS = $(CFLAGS)"); + writeList(file, config->buildOptions, " ", "", "", NULL, "C++"); + writeList(file, config->buildFlags, " ", "", "", checkCppFlags, "C++"); + fprintf(file, "\n"); + + fprintf(file, " LDFLAGS +="); + writeList(file, config->linkOptions, " ", "", "", NULL, NULL); + writeList(file, config->linkFlags, " ", "", "", NULL, NULL); + writeList(file, config->libPaths, " -L ", "", "", NULL, NULL); + writeList(file, config->links, " -l", "", "", checkLink, &i); + fprintf(file, "\n"); + + fprintf(file, " TARGET = "); + if (strcmp(kind, "winexe") == 0 || strcmp(kind, "exe") == 0) + { + if (strcmp(kind, "winexe") == 0 && strcmp(osIdent, "macosx") == 0) + { + fprintf(file, "%s.app/Contents/MacOS/%s\n", config->target, config->target); + fprintf(file, " MACAPP = %s\n", config->target); + } + else + { + fprintf(file, "%s\n", config->target); + } + } + else + { + fprintf(file, "%s/", getDirectory(config->target)); + if (strcmp(kind, "lib") == 0) + { + fprintf(file, "lib%s.a\n", getFilename(config->target, 0)); + } + else + { + if (strcmp(osIdent, "windows") == 0) + fprintf(file, "%s.dll\n", getFilename(config->target, 0)); + else + fprintf(file, "lib%s.so\n", getFilename(config->target, 0)); + } + } + + fprintf(file, "endif\n"); + } + + fprintf(file, "\n"); + + // These rules auto-create dependency lists (see "Advanced Auto-Dependency + // Generation at http://www.paulandlesley.org/gmake/autodep.html) and place + // the *.P and *.o files in $(OBJ_DIR) + + // Note all of these targets do the same thing. Is there a way to reuse the + // command block? Didn't see anything in the make manual, though it would + // seem this is something people would want to do. + + for (i = 0; CPP_EXT[i]; ++i) + { + fprintf(file, "%s/%%.o : %%%s\n", OBJECTS_DIR, CPP_EXT[i]); + fprintf(file, "\t-%sif [ ! -d %s ]; then mkdir %s; fi\n", prefix, OBJECTS_DIR, OBJECTS_DIR); + if (!verbose) + fprintf(file, "\t@echo $(notdir $<)\n"); + + if (cc != NULL && strcmp(cc, "dmc") == 0) + { + if (strcmp(CPP_EXT[i], ".c") == 0) + fprintf(file, "\t%sdmc $(CFLAGS) -o $@ -c $<\n", prefix); + else + fprintf(file, "\t%sdmc -cpp -Ae -Ar -mn -D_WINDOWS $(CXXFLAGS) -o $@ -c $<\n", prefix); + } + else + { + if (strcmp(CPP_EXT[i], ".c") == 0) + fprintf(file, "\t%s$(CC) $(CFLAGS) -MD -o $@ -c $<\n", prefix); + else + fprintf(file, "\t%s$(CXX) $(CXXFLAGS) -MD -o $@ -c $<\n", prefix); + } + + fprintf(file, "\t-%sif [ -f $*.d ]; then mv $*.d obj/$*.d; fi\n", prefix); + fprintf(file, "\t%scp %s/$*.d %s/$*.P; \\\n", prefix, OBJECTS_DIR, OBJECTS_DIR); + fprintf(file, "\t sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\\\$$//' \\\n"); + fprintf(file, "\t -e '/^$$/ d' -e 's/$$/ :/' < %s/$*.d >> %s/$*.P; \\\n", OBJECTS_DIR, OBJECTS_DIR); + fprintf(file, "\trm -f %s/$*.d\n\n", OBJECTS_DIR); + } + + // Write out the list of object file targets for all C/C++ sources + + fprintf(file, "OBJECTS = \\\n"); + writeList(file, package->files, "\tobj/", " \\\n", "", checkCppSources, NULL); + fprintf(file, "\n"); + + // Write out the list of source directories + + fprintf(file, "VPATH ="); + walkSourceList(file, package, "", writeSourcePaths); + fprintf(file, "\n\n"); + + fprintf(file, ".PHONY: clean\n"); + fprintf(file, "\n"); + + if (strcmp(osIdent, "macosx") == 0 && strcmp(kind, "winexe") == 0) + { + fprintf(file, "all: $(BINDIR)/$(MACAPP).app/Contents/PkgInfo $(BINDIR)/$(MACAPP).app/Contents/Info.plist $(BINDIR)/$(TARGET)\n\n"); + } + + fprintf(file, "%s/$(TARGET): $(OBJECTS)\n", location); + fprintf(file, "\t@echo Linking %s\n", package->name); + fprintf(file, "\t-%sif [ ! -d $(BINDIR) ]; then mkdir -p $(BINDIR); fi\n", prefix); + fprintf(file, "\t-%sif [ ! -d $(LIBDIR) ]; then mkdir -p $(LIBDIR); fi\n", prefix); + if (strcmp(osIdent, "macosx") == 0 && strcmp(kind, "winexe") == 0) + fprintf(file, "\t-%sif [ ! -d $(BINDIR)/$(MACAPP).app/Contents/MacOS ]; then mkdir -p $(BINDIR)/$(MACAPP).app/Contents/MacOS; fi\n", prefix); + + if (strcmp(kind, "lib") == 0) + { + fprintf(file, "\t%sar -cr $@ $^\n", prefix); + fprintf(file, "\t%sranlib $@\n", prefix); + } + else + { + fprintf(file, "\t%s$(CXX) -o $@ $(filter-out %%.so, $^) $(LDFLAGS)\n", prefix); + } + fprintf(file, "\n"); + + if (strcmp(osIdent, "macosx") == 0 && strcmp(kind, "winexe") == 0) + { + fprintf(file, "$(BINDIR)/$(MACAPP).app/Contents/PkgInfo:\n"); + fprintf(file, "\n"); + + fprintf(file, "$(BINDIR)/$(MACAPP).app/Contents/Info.plist:\n"); + fprintf(file, "\n"); + } + + fprintf(file, "clean:\n"); + fprintf(file, "\t@echo Cleaning %s\n", package->name); + if (strcmp(osIdent, "macosx") == 0 && strcmp(kind, "winexe") == 0) + { + fprintf(file, "\t-%srm -rf %s/$(MACAPP).app %s/*\n", prefix, location, OBJECTS_DIR); + } + else + { + fprintf(file, "\t-%srm -rf %s/$(TARGET) %s/*\n", prefix, location, OBJECTS_DIR); + } + fprintf(file, "\n"); + + fprintf(file, "-include $(OBJECTS:%%.o=%%.P)\n\n"); + + fclose(file); + return 1; +} + +//----------------------------------------------------------------------------- + +static const char* checkReferences(const char* file, void* data) +{ + Package* package = getPackage(file); + if (package == NULL) return file; + if (strcmp(package->language, "c#") != 0) return NULL; + return package->config[*((int*)data)]->target; +} + +static const char* checkCsSources(const char* file, void* data) +{ + if (strcmp(getExtension(file), ".cs") == 0) + return file; + return NULL; +} + +static int writeCsPackage(Package* package) +{ + const char* extension; + const char* csc; + FILE* file; + int i; + + // Figure out what I'm building + + const char* name = package->name; + const char* path = package->path; + const char* kind = package->kind; + + if (strcmp(kind, "dll") == 0 || strcmp(kind, "aspnet") == 0) + { + extension = ".dll"; + kind = "library"; + } + else if (strcmp(kind, "winexe") == 0 || strcmp(kind, "exe") == 0) + { + extension = ".exe"; + } + else + { + printf("** Error: unknown package type '%s'\n", kind); + return 0; + } + + // Figure out what I'm building it with + + if (dotnet == NULL) + { + if (strcmp(osIdent, "windows") == 0) + csc = "csc /nologo"; + else + csc = "mcs"; + } + else if (strcmp(dotnet, "ms") == 0) + csc = "csc"; + else if (strcmp(dotnet, "pnet") == 0) + csc = "cscc"; + else if (strcmp(dotnet, "mono") == 0) + csc = "mcs"; + else + { + printf("** Error: unknown .NET runtime '%s'\n", dotnet); + return 0; + } + + // Open the package Makefile and write the header + + file = openFile(path, name, MAKEFILE_EXT); + if (file == NULL) + return 0; + + fprintf(file, "# Sub-makefile autogenerated by premake\n\n"); + + fprintf(file, "BINDIR = %s\n\n", reversePath(path, project->binaries, UNIX)); + + fprintf(file, "FLAGS =\n"); + fprintf(file, "TARGET =\n\n"); + + // Process the build configurations + + for (i = 0; i < package->numConfigs; ++i) + { + Config* config = package->config[i]; + int symbols = !inArray(config->buildFlags,"no-symbols"); + int optimize = inArray(config->buildFlags,"optimize")||inArray(config->buildFlags,"optimize-size")||inArray(config->buildFlags,"optimize-speed"); + int unsafe = inArray(config->buildFlags,"unsafe"); + + fprintf(file, "ifeq ($(CONFIG),%s)\n", config->name); + + fprintf(file, " FLAGS +="); + if (symbols) fprintf(file, " /debug"); + if (unsafe) fprintf(file, " /unsafe"); + writeList(file, config->defines, " /d:", "", "", NULL, NULL); + writeList(file, config->libPaths, " /lib:", "", "", NULL, NULL); + writeList(file, config->links, " /r:", ".dll", "", checkReferences, &i); + fprintf(file, "\n"); + + fprintf(file, " TARGET = %s%s\n", config->target, extension); + fprintf(file, "endif\n"); + } + + // Create the list of files + + fprintf(file, "\nSOURCES = \\\n"); + writeList(file, package->files, "\t", " \\\n", "", checkCsSources, NULL); + fprintf(file, "\n"); + + // Build targets + + fprintf(file, "\n.PHONY: clean\n\n"); + + fprintf(file, "$(BINDIR)/$(TARGET): $(SOURCES)\n"); + fprintf(file, "\t-@if [ ! -d $(BINDIR) ]; then mkdir -p $(BINDIR); fi\n"); + fprintf(file, "\t@%s /out:$@ /t:%s -lib:$(BINDIR) $(FLAGS) $^\n\n", csc, kind); + + fprintf(file, "clean:\n"); + fprintf(file, "\t@echo Cleaning %s\n", name); + fprintf(file, "\t-@rm -f $(BINDIR)/$(TARGET)\n"); + + fclose(file); + return 1; +} diff --git a/build/premake/src/Src/posix.c b/build/premake/src/Src/posix.c new file mode 100644 index 0000000000..3de028dff1 --- /dev/null +++ b/build/premake/src/Src/posix.c @@ -0,0 +1,179 @@ +//----------------------------------------------------------------------------- +// Premake - posix.c +// +// POSIX file and directory manipulation functions. +// +// Written by Jason Perkins (jason@379.com) +// Copyright (C) 2002 by 379, Inc. +// Source code licensed under the GPL, see LICENSE.txt for details. +// +// $Id: posix.c,v 1.10 2004/04/16 22:18:38 jason379 Exp $ +//----------------------------------------------------------------------------- + +#include +#include +#include +#include +#include + +char nativePathSep = '/'; + +#if defined(__linux__) +const char* osIdent = "linux"; +#elif defined(__FreeBSD__) +const char* osIdent = "freebsd"; +#elif defined(__NetBSD__) +const char* osIdent = "netbsd"; +#elif defined(__OpenBSD__) +const char* osIdent = "openbsd"; +#elif defined(__APPLE__) && defined(__MACH__) +const char* osIdent = "macosx"; +#else +#error Unknown OS type. +#endif + +static glob_t globbuf; +static int iGlob; + +//----------------------------------------------------------------------------- + +int plat_chdir(const char* path) +{ + return !chdir(path); +} + +//----------------------------------------------------------------------------- + +int plat_copyFile(const char* src, const char* dest) +{ + char buffer[4096]; + sprintf(buffer, "cp %s %s", src, dest); + return (system(buffer) == 0); +} + +//----------------------------------------------------------------------------- + +void plat_deleteDir(const char* path) +{ + char buffer[1024]; + strcpy(buffer, "rm -rf "); + strcat(buffer, path); + system(buffer); +} + +//----------------------------------------------------------------------------- + +void plat_deleteFile(const char* path) +{ + unlink(path); +} + +//----------------------------------------------------------------------------- + +int findLib(const char* lib, const char* path) +{ + char buffer[2048]; + struct stat sb; + + sprintf(buffer, "%s/lib%s.so", path, lib); + if (stat(buffer, &sb) == 0 && !S_ISDIR(sb.st_mode)) return 1; + + sprintf(buffer, "%s/%s.so", path, lib); + if (stat(buffer, &sb) == 0 && !S_ISDIR(sb.st_mode)) return 1; + + sprintf(buffer, "%s/%s", path, lib); + if (stat(buffer, &sb) == 0 && !S_ISDIR(sb.st_mode)) return 1; + + return 0; +} + +int plat_findLib(const char* lib, char* buffer, int size) +{ + FILE* file; + + if (findLib(lib, "/usr/lib")) + { + strcpy(buffer, "/usr/lib"); + return 1; + } + + file = fopen("/etc/ld.so.conf", "rt"); + if (file == NULL) return 0; + + while (!feof(file)) + { + // Read a line and trim off any trailing whitespace + char linebuffer[2048]; + char* ptr; + + fgets(buffer, 2048, file); + ptr = &buffer[strlen(buffer) - 1]; + while (isspace(*ptr)) + *(ptr--) = '\0'; + + if (findLib(lib, buffer)) + { + fclose(file); + return 1; + } + } + + fclose(file); + return 0; +} + +//----------------------------------------------------------------------------- + +int plat_generateUUID(char* uuid) +{ + FILE* rnd = fopen("/dev/random", "rb"); + fread(uuid, 16, 1, rnd); + fclose(rnd); +} + +//----------------------------------------------------------------------------- + +void plat_getcwd(char* buffer, int size) +{ + getcwd(buffer, size); +} + +//----------------------------------------------------------------------------- + +int plat_isAbsPath(const char* buffer) +{ + return (buffer[0] == '/'); +} + +//----------------------------------------------------------------------------- + +int plat_dirOpen(const char* mask) +{ + globbuf.gl_offs = 0; + globbuf.gl_pathc = 0; + globbuf.gl_pathv = NULL; + glob(mask, GLOB_DOOFFS | GLOB_APPEND, NULL, &globbuf); + iGlob = -1; +} + +void plat_dirClose() +{ + globfree(&globbuf); +} + +int plat_dirGetNext() +{ + return (++iGlob < globbuf.gl_pathc); +} + +const char* plat_dirGetName() +{ + char* ptr = strrchr(globbuf.gl_pathv[iGlob], '/'); + ptr = (ptr == NULL) ? globbuf.gl_pathv[iGlob] : ptr + 1; + return ptr; +} + +int plat_dirIsFile() +{ + return 1; +} diff --git a/build/premake/src/Src/premake.c b/build/premake/src/Src/premake.c new file mode 100644 index 0000000000..58a6a27b27 --- /dev/null +++ b/build/premake/src/Src/premake.c @@ -0,0 +1,218 @@ +//----------------------------------------------------------------------------- +// Premake - premake.c +// +// Program entry point and project/package file parsing. +// +// Copyright (C) 2002-2004 by Jason Perkins +// Source code licensed under the GPL, see LICENSE.txt for details. +// +// $Id: premake.c,v 1.46 2004/05/05 23:23:44 jason379 Exp $ +//----------------------------------------------------------------------------- + +#include +#include +#include "project.h" +#include "util.h" +#include "Lua/lua.h" + +#define VERSION "1.9" +#define COPYRIGHT "Copyright (C) 2002-2004 Jason Perkins" + +extern int makeGnuScripts(); +extern int makeSharpDevScripts(); +extern int makeVs6Scripts(); +extern int makeVsXmlScripts(int version); +extern int makeClean(); + +static void showCompilers(); +static void showOptions(); +static void showTargets(); +static void showUsage(); +static void showCredits(); + +const char** commandLineArgs; +const char* rootProjectFile = NULL; +const char* cc = NULL; +const char* dotnet = NULL; +int verbose = 0; + +//----------------------------------------------------------------------------- + +int main(int argc, char* argv[]) +{ + int i; + + char* filename = "premake.lua"; + args = argv; + + if (argc == 1) + { + puts("Type 'premake --help' for help"); + return 1; + } + + // Look for a '--file' command to override the default + for (i = 0; argv[i] != NULL; ++i) + { + if (strcmp(argv[i], "--file") == 0) + { + if (argv[i + 1] == NULL || strncmp(argv[i + 1], "--", 2) == 0) + { + fprintf(stderr, "Usage: --file filename"); + return 0; + } + + filename = argv[i + 1]; + break; + } + } + + // chdir() to the directory containing the project, so that relative + // paths to the packages will work + setCwd(getDirectory(filename)); + + // Remember the root project filename. This is used by the gmake generator + // to rebuild the makefiles when the premake files change + rootProjectFile = filename; + + createProject(argv); + if (!loadProject(filename)) + return 1; + + // Project must have at least one package + if (project->numPackages == 0) + { + puts("** Error: project must have at least one package."); + closeProject(); + return 0; + } + + // Process the command-line options + for (i = 0; argv[i] != NULL; ++i) + { + if (strncmp(argv[i], "--", 2) == 0) + { + if (strcmp(argv[i], "--file") == 0) + { + /* Already handled above */ ; + } + else if (strcmp(argv[i], "--help") == 0) + { + showUsage(); + } + else if (strcmp(argv[i], "--version") == 0) + { + printf("premake (Premake Build Script Generator) %s\n", VERSION); + } + else if (strcmp(argv[i], "--show-options") == 0 || + strcmp(argv[i], "--show-compilers") == 0 || + strcmp(argv[i], "--show-targets") == 0) + { + /* deprecated commands */ + printf("The option '%s' has been deprecated.\n", argv[i]); + printf("Type 'premake --help' for help.\n"); + } + else + { + handleCommand(argv, i); + } + } + } + + closeProject(); + return 0; +} + +//----------------------------------------------------------------------------- + +void defaultCommand(int argc, const char* argv[]) +{ + int result, i; + + if (strcmp(argv[0], "target") == 0) + { + for (i = 1; i < argc; ++i) + { + if (strcmp(argv[i], "gnu") == 0) + result = makeGnuScripts(); + else if (strcmp(argv[i], "sd") == 0) + result = makeSharpDevScripts(); + else if (strcmp(argv[i], "vs6") == 0) + result = makeVs6Scripts(); + else if (strcmp(argv[i], "vs7") == 0 || strcmp(argv[i], "vs2002") == 0) + result = makeVsXmlScripts(7); + else if (strcmp(argv[i], "vs2003") == 0) + result = makeVsXmlScripts(2003); + else + { + printf("** Unrecognized target '%s'\n", argv[i]); + return; + } + + if (!result) break; + } + } + else if (strcmp(argv[0], "clean") == 0) + { + makeClean(); + } + else if (strcmp(argv[0], "cc") == 0) + { + cc = argv[1]; + } + else if (strcmp(argv[0], "dotnet") == 0) + { + dotnet = argv[1]; + } + else if (strcmp(argv[0], "verbose") == 0) + { + verbose = 1; + } +} + +//----------------------------------------------------------------------------- + +static void showUsage() +{ + int i; + + printf("Premake %s, a build script generator\n", VERSION); + puts(COPYRIGHT); + printf("%s %s\n", LUA_VERSION, LUA_COPYRIGHT); + puts(""); + puts(" --file name Process the specified premake script file"); + puts(""); + puts(" --clean Remove all binaries and build scripts"); + puts(" --verbose Generate verbose makefiles (where applicable)"); + puts(""); + puts(" --cc name Choose a C/C++ compiler, if supported by target; one of:"); + puts(" gcc GNU gcc compiler"); + puts(" dmc Digital Mars C/C+ compiler"); + puts(""); + puts(" --dotnet name Choose a .NET compiler set, if supported by target; one of:"); + puts(" ms Microsoft (csc)"); + puts(" mono Mono (msc)"); + puts(" pnet Portable.NET (cscc)"); + puts(""); + puts(" --target name Generate input files for the specified toolset; one of:"); + puts(" gnu GNU Makefile for POSIX, MinGW, and Cygwin"); + puts(" sd ICSharpCode SharpDevelop"); + puts(" vs6 Microsoft Visual Studio 6"); + puts(" vs7 Microsoft Visual Studio 7"); + puts(" vs2003 Microsoft Visual Studio 2003"); + puts(""); + puts(" --help Display this information"); + puts(" --version Display version information"); + puts(""); + + if (project != NULL && project->numOptions > 0) + { + puts("This premake configuration also supports the following custom options:"); + puts(""); + + for (i = 0; i < project->numOptions; ++i) + printf(" --%-14s %s\n", project->option[i]->flag, project->option[i]->description); + } + + puts(""); +} diff --git a/build/premake/src/Src/project.c b/build/premake/src/Src/project.c new file mode 100644 index 0000000000..8644269c7b --- /dev/null +++ b/build/premake/src/Src/project.c @@ -0,0 +1,898 @@ +//----------------------------------------------------------------------------- +// Premake - project.c +// +// Functions to load and access the project data, along with all of the helper +// functions used by the project scripts. +// +// Copyright (C) 2002-2004 by Jason Perkins +// Source code licensed under the GPL, see LICENSE.txt for details. +// +// $Id: project.c,v 1.18 2004/04/14 00:15:26 jason379 Exp $ +//----------------------------------------------------------------------------- + +#include +#include +#include +#include "Lua/lua.h" +#include "Lua/lualib.h" +#include "Lua/lauxlib.h" +#include "Lua/ldebug.h" +#include "project.h" +#include "util.h" + +extern void defaultCommand(int argc, const char** argv); + +Project* project = NULL; + +static lua_State* L; +static const char* currentScript = NULL; + +static int finishProject(); + +static int getArray(int ref, const char* name); +static int getArraySize(int ref); +static int getDeepArraySize(int ref); +static int getObjectFromArray(int ref, int i); +static const char* getString(int ref, char* name); +static const char* getStringFromArray(int ref, int index); + +static int addoption(lua_State* L); +static int copyfile(lua_State* L); +static int docommand(lua_State* L); +static int dopackage(lua_State* L); +static int ERRORMESSAGE(lua_State* L); +static int getglobal(lua_State* L); +static int findlib(lua_State* L); +static int matchfiles(lua_State* L); +static int newpackage(lua_State* L); + +//----------------------------------------------------------------------------- + +void createProject(char* argv[]) +{ + int argIndex, i; + + // Create a script environment and install the standard libraries + + L = lua_open(0); + + lua_baselibopen(L); + lua_iolibopen(L); + lua_strlibopen(L); + lua_mathlibopen(L); + + // Install the helper functions for the scripts + + lua_pushcfunction(L, addoption); + lua_setglobal(L, "option"); + + lua_pushcfunction(L, addoption); + lua_setglobal(L, "addoption"); + + lua_pushcfunction(L, copyfile); + lua_setglobal(L, "copyfile"); + + lua_pushcfunction(L, docommand); + lua_setglobal(L, "docommand"); + + lua_pushcfunction(L, dopackage); + lua_setglobal(L, "dopackage"); + + lua_pushcfunction(L, ERRORMESSAGE); + lua_setglobal(L, "_ERRORMESSAGE"); + + lua_pushcfunction(L, getglobal); + lua_settagmethod(L, LUA_TNIL, "getglobal"); + + lua_pushcfunction(L, dopackage); + lua_setglobal(L, "include"); + + lua_pushcfunction(L, findlib); + lua_setglobal(L, "findlib"); + + lua_pushcfunction(L, matchfiles); + lua_setglobal(L, "matchfiles"); + + lua_pushcfunction(L, newpackage); + lua_setglobal(L, "newpackage"); + + // Set up the registry + + lua_getregistry(L); + + lua_pushstring(L, "packages"); + lua_newtable(L); + lua_settable(L, -3); + + lua_pushstring(L, "options"); + lua_newtable(L); + lua_settable(L, -3); + + lua_pop(L, 1); + + // Set the OS variable + + lua_pushstring(L, osIdent); + lua_setglobal(L, "OS"); + + // Create and populate the options table + + lua_newtable(L); + argIndex = 0; + for (i = 1; argv[i] != NULL; ++i) + { + if (strncmp(argv[i], "--", 2) == 0) + { + if (argIndex > 0) lua_settable(L, -3); + lua_pushstring(L, argv[i] + 2); + lua_newtable(L); + argIndex = 1; + } + else if (argIndex > 0) + { + lua_pushnumber(L, argIndex++); + lua_pushstring(L, argv[i]); + lua_settable(L, -3); + } + } + if (argIndex > 0) lua_settable(L, -3); + lua_setglobal(L, "options"); + + // Create an empty project object + + lua_newtable(L); + + lua_pushstring(L, "name"); + lua_pushstring(L, "MyProject"); + lua_settable(L, -3); + + lua_pushstring(L, "path"); + lua_pushstring(L, getDirectory(currentScript)); + lua_settable(L, -3); + + lua_pushstring(L, "bindir"); + lua_pushstring(L, "."); + lua_settable(L, -3); + + lua_pushstring(L, "libdir"); + lua_pushstring(L, "."); + lua_settable(L, -3); + + lua_pushstring(L, "configs"); + lua_newtable(L); + lua_pushstring(L, "Debug"); + lua_rawseti(L, -2, 1); + lua_pushstring(L, "Release"); + lua_rawseti(L, -2, 2); + lua_settable(L, -3); + + lua_setglobal(L, "project"); +} + +//----------------------------------------------------------------------------- + +int loadProject(char* project) +{ + int result; + result = lua_dofile(L, project); + if (result == LUA_ERRFILE) + { + /* Try "${project}.lua" */ + char buffer[4096]; + strcpy(buffer, project); + strcat(buffer, ".lua"); + result = lua_dofile(L, buffer); + } + + if (result == 0) + result = finishProject(); + + if (result != 0) + lua_close(L); + + return (result == 0); +} + +//----------------------------------------------------------------------------- + +void handleCommand(char* args[], int i) +{ + int j; + + // Try to find a command processor + lua_getglobal(L, "docommand"); + if (!lua_isfunction(L, -1)) + return; + + // Push the command and it's arguments onto the stack + lua_pushstring(L, args[i] + 2); + for (j = i + 1; args[j] != NULL && strncmp(args[j], "--", 2) != 0; ++j) + lua_pushstring(L, args[j]); + + // Call the command processor + lua_call(L, j - i, 0); +} + +//----------------------------------------------------------------------------- + +int getProject() +{ + lua_getglobal(L, "project"); + return lua_ref(L, 0); +} + +//----------------------------------------------------------------------------- + +Package* getPackage(const char* name) +{ + int i; + for (i = 0; i < project->numPackages; ++i) + { + if (strcmp(project->package[i]->name, name) == 0) + return project->package[i]; + } + return NULL; +} + +//----------------------------------------------------------------------------- + +void configureProject() +{ + int top = lua_gettop(L); + lua_getglobal(L, "project"); + lua_pushstring(L, "configure"); + lua_gettable(L, -2); + if (!lua_isnil(L, -1)) + lua_call(L, 0, 0); + lua_settop(L, top); +} + +//----------------------------------------------------------------------------- + +static void getConfigList(int package, int config, const char* list, const char*** array, int* length) +{ + const char** buffer; + int size, i; + + int pkgRef = getArray(package, list); + int pkgLen = getDeepArraySize(pkgRef); + int cfgRef = getArray(config, list); + int cfgLen = getDeepArraySize(cfgRef); + + size = pkgLen + cfgLen; + buffer = (const char**)malloc(sizeof(char**) * (size + 1)); + buffer[size] = NULL; + + for (i = 0; i < pkgLen; ++i) + buffer[i] = getStringFromArray(pkgRef, i); + for (i = 0; i < cfgLen; ++i) + buffer[i + pkgLen] = getStringFromArray(cfgRef, i); + + *array = buffer; + *length = size; +} + +static int finishProject() +{ + int i, optlist, packages; + + project = (Project*)malloc(sizeof(Project)); + + project->name = getString(getProject(), "name"); + if (strchr(project->name, ' ') != NULL) + puts("** Warning: not all generators allow spaces in the project name."); + + project->path = getString(getProject(), "path"); + project->binaries = getString(getProject(), "bindir"); + project->libraries = getString(getProject(), "libdir"); + + optlist = getArray(-1, "options"); + project->numOptions = getArraySize(optlist); + project->option = (Option**)malloc(sizeof(Option*) * (project->numOptions + 1)); + project->option[project->numOptions] = NULL; + for (i = 0; i < project->numOptions; ++i) + { + int opt = getObjectFromArray(optlist, i); + Option* option = (Option*)malloc(sizeof(Option)); + project->option[i] = option; + option->flag = (char*)getStringFromArray(opt, 0); + option->description = (char*)getStringFromArray(opt, 1); + } + + packages = getArray(-1, "packages"); + project->numPackages = getArraySize(packages); + project->package = (Package**)malloc(sizeof(Package**) * (project->numPackages + 1)); + project->package[project->numPackages] = NULL; + + for (i = 0; i < project->numPackages; ++i) + { + int pkg, files, configs, j; + + Package* package = (Package*)malloc(sizeof(Package)); + project->package[i] = package; + + pkg = getObjectFromArray(packages, i); + + files = getArray(pkg, "files"); + package->numFiles = getDeepArraySize(files); + package->files = (const char**)malloc(sizeof(char**) * (package->numFiles + 1)); + package->files[package->numFiles] = NULL; + for (j = 0; j < package->numFiles; ++j) + package->files[j] = getStringFromArray(files, j); + + package->name = getString(pkg, "name"); + package->script = getString(pkg, "script"); + package->path = getString(pkg, "path"); + package->language = getString(pkg, "language"); + package->kind = getString(pkg, "kind"); + package->url = getString(pkg, "url"); + package->data = NULL; + + configs = getArray(pkg, "config"); + package->numConfigs = getArraySize(configs); + package->config = (Config**)malloc(sizeof(Config*) * (package->numConfigs + 1)); + package->config[package->numConfigs] = NULL; + + for (j = 0; j < package->numConfigs; ++j) + { + int cfg; + + Config* config = (Config*)malloc(sizeof(Config)); + package->config[j] = config; + + cfg = getObjectFromArray(configs, j); + + config->name = getString(cfg, "name"); + + config->target = getString(cfg, "target"); + if (config->target == NULL) config->target = getString(pkg, "target"); + if (config->target == NULL) config->target = package->name; + + config->pchHeader = getString(cfg, "pchHeader"); + if (!config->pchHeader) + config->pchHeader = getString(pkg, "pchHeader"); + + config->pchSource = getString(cfg, "pchSource"); + if (!config->pchSource) + config->pchSource = getString(pkg, "pchSource"); + + getConfigList(pkg, cfg, "buildflags", &config->buildFlags, &config->numBuildFlags); + getConfigList(pkg, cfg, "buildoptions", &config->buildOptions, &config->numBuildOptions); + getConfigList(pkg, cfg, "defines", &config->defines, &config->numDefines); + getConfigList(pkg, cfg, "includepaths", &config->includePaths, &config->numIncludePaths); + getConfigList(pkg, cfg, "libpaths", &config->libPaths, &config->numLibPaths); + getConfigList(pkg, cfg, "linkflags", &config->linkFlags, &config->numLinkFlags); + getConfigList(pkg, cfg, "linkoptions", &config->linkOptions, &config->numLinkOptions); + getConfigList(pkg, cfg, "links", &config->links, &config->numLinks); + } + } + + return 0; +} + +//----------------------------------------------------------------------------- + +void closeProject() +{ + int i, j; + + for (i = 0; i < project->numPackages; ++i) + { + Package* package = project->package[i]; + + for (j = 0; j < package->numConfigs; ++j) + { + Config* config = package->config[j]; + free((char**)config->buildFlags); + free((char**)config->buildOptions); + free((char**)config->defines); + free((char**)config->includePaths); + free((char**)config->libPaths); + free((char**)config->linkFlags); + free((char**)config->linkOptions); + free((char**)config->links); + free(package->config[j]); + } + free(package->config); + if (package->data) free(package->data); + free(package); + } + + free(project->package); + free(project); + project = NULL; +} + +//----------------------------------------------------------------------------- + +static int getArray(int ref, const char* name) +{ + if (ref == -1) + ref = LUA_REFREGISTRY; + + lua_getref(L, ref); + lua_pushstring(L, name); + lua_gettable(L, -2); + ref = lua_ref(L, -1); + + lua_pop(L, 1); + return ref; +} + +//----------------------------------------------------------------------------- + +static int getArraySize(int ref) +{ + if (ref > 0) + { + int size; + lua_getref(L, ref); + size = lua_getn(L, -1); + lua_pop(L, 1); + return size; + } + + return 0; +} + +static int getDeepArraySize(int ref) +{ + int i, size = 0; + if (ref == 0) return 0; + + lua_getref(L, ref); + for (i = 1; i <= lua_getn(L,-1); ++i) + { + lua_rawgeti(L, -1, i); + if (lua_istable(L, -1)) + { + size += getDeepArraySize(lua_ref(L,0)); + } + else + { + lua_pop(L, 1); + ++size; + } + } + + lua_pop(L, 1); + return size; +} + +//----------------------------------------------------------------------------- + +static int getObjectFromArray(int ref, int i) +{ + lua_getref(L, ref); + lua_rawgeti(L, -1, i + 1); + ref = lua_ref(L, -1); + lua_pop(L, 1); + return ref; +} + +//----------------------------------------------------------------------------- + +static const char* getString(int ref, char* name) +{ + const char* str; + lua_getref(L, ref); + lua_pushstring(L, name); + lua_gettable(L, -2); + str = lua_tostring(L, -1); + lua_pop(L, 2); + + return str; +} + +//----------------------------------------------------------------------------- + +static const char* goDeep(int ref, int* index) +{ + int i; + const char* str = NULL; + + lua_getref(L, ref); + for (i = 1; i <= lua_getn(L,-1) && *index >= 0; ++i) + { + lua_rawgeti(L, -1, i); + if (lua_istable(L, -1)) + { + str = goDeep(lua_ref(L,0), index); + if (str != NULL) + return str; + } + else if (*index == 0) + { + str = lua_tostring(L, -1); + lua_pop(L, 1); + break; + } + else + { + lua_pop(L, 1); + --(*index); + } + } + + lua_pop(L, 1); + return str; +} + +static const char* getStringFromArray(int ref, int index) +{ + return goDeep(ref, &index); +} + +//----------------------------------------------------------------------------- + +void setProjectOption(char* option) +{ + lua_getglobal(L, "options"); + lua_pushstring(L, option); + lua_pushnumber(L, 1); + lua_settable(L, -3); + lua_pop(L, 1); +} + +//----------------------------------------------------------------------------- + +static void createEmptyConfig(lua_State* L, const char* name) +{ + lua_newtable(L); + + if (name != NULL) + { + lua_pushstring(L, "name"); + lua_pushstring(L, name); + lua_settable(L, -3); + } + + lua_pushstring(L, "buildflags"); + lua_newtable(L); + if (name != NULL && strcmp(name, "Release") == 0) { + lua_pushstring(L, "no-symbols"); + lua_rawseti(L, -2, 1); + lua_pushstring(L, "optimize"); + lua_rawseti(L, -2, 2); + } + lua_settable(L, -3); + + lua_pushstring(L, "buildoptions"); + lua_newtable(L); + lua_settable(L, -3); + + lua_pushstring(L, "defines"); + lua_newtable(L); + lua_settable(L, -3); + + lua_pushstring(L, "includepaths"); + lua_newtable(L); + lua_settable(L, -3); + + lua_pushstring(L, "libpaths"); + lua_newtable(L); + lua_settable(L, -3); + + lua_pushstring(L, "linkflags"); + lua_newtable(L); + lua_settable(L, -3); + + lua_pushstring(L, "linkoptions"); + lua_newtable(L); + lua_settable(L, -3); + + lua_pushstring(L, "links"); + lua_newtable(L); + lua_settable(L, -3); +} + +/*----------------------------------------------------------------------------- + * The registry stores the list of projects and packages. This function will + * add the table at the top of the stack to one of these lists. */ + +static void registerTable(lua_State* L, char* listname) +{ + int n; + + lua_getregistry(L); + + lua_pushstring(L, listname); + lua_gettable(L, -2); + lua_pushvalue(L, -3); + + n = lua_getn(L, -2); + lua_rawseti(L, -2, n + 1); + + lua_pop(L, 2); // remove list and registry +} + +//----------------------------------------------------------------------------- + +static int addoption(lua_State* L) +{ + lua_getregistry(L); + lua_pushstring(L, "options"); + lua_gettable(L, -2); + + lua_newtable(L); + lua_pushvalue(L, 1); + lua_rawseti(L, -2, lua_getn(L,-2) + 1); + + lua_pushvalue(L, 2); + lua_rawseti(L, -2, lua_getn(L,-2) + 1); + + lua_rawseti(L, -2, lua_getn(L,-2) + 1); + + lua_pop(L, 2); + return 0; +} + +//----------------------------------------------------------------------------- + +static int copyfile(lua_State* L) +{ + const char* src = luaL_check_string(L, 1); + const char* dest = luaL_check_string(L, 2); + if (copyFile(src, dest)) + lua_pushnumber(L, 1); + else + lua_pushnil(L); + return 1; +} + +//----------------------------------------------------------------------------- + +static int docommand(lua_State* L) +{ + int argc, i; + const char** argv; + + /* If this function is overriden in Lua, the second parameter will be a + * table. Otherwise there will be zero or more string parameters. */ + if (lua_gettop(L) > 1 && !lua_isnil(L,2)) + { + if (lua_istable(L, 2)) + { + argc = lua_getn(L, 2) + 1; + argv = (const char**)malloc(sizeof(char*) * argc); + argv[0] = luaL_check_string(L, 1); + for (i = 1; i < argc; ++i) + { + lua_rawgeti(L, 2, i); + argv[i] = luaL_check_string(L, -1); + lua_pop(L, 1); + } + } + else + { + argc = lua_gettop(L); + argv = (const char**)malloc(sizeof(char*) * argc); + for (i = 0; i < lua_gettop(L); ++i) + argv[i] = luaL_check_string(L, i + 1); + } + } + else + { + argc = 1; + argv = (const char**)malloc(sizeof(char*)); + argv[0] = luaL_check_string(L, 1); + } + + defaultCommand(argc, argv); + + free((char*)argv); + return 0; +} + +//----------------------------------------------------------------------------- + +static int dopackage(lua_State* L) +{ + int result; + currentScript = luaL_check_string(L, 1); + + lua_pushnil(L); + lua_setglobal(L, "package"); + + lua_pushvalue(L, 1); + lua_pushstring(L, "/premake.lua"); + lua_concat(L, 2); + currentScript = lua_tostring(L, -1); + result = lua_dofile(L, currentScript); + if (result == LUA_ERRFILE) + { + currentScript = lua_tostring(L, 1); + result = lua_dofile(L, currentScript); + } + + currentScript = NULL; + return 0; +} + +//----------------------------------------------------------------------------- + +static int ERRORMESSAGE(lua_State* L) +{ + lua_Debug ar; + int stack; + + const char* msg = lua_tostring(L, 1); + printf("\n** Error: %s\n", msg); + + for (stack = 0; lua_getstack(L, stack, &ar); ++stack) + { + lua_getinfo(L, "S1", &ar); + if (ar.source && ar.currentline > 0) + { + printf("<%.70s: line %d>\n\n", ar.short_src, ar.currentline); + break; + } + } + + return 0; +} + +//----------------------------------------------------------------------------- + +static int findlib(lua_State* L) +{ + const char* libname = luaL_check_string(L, 1); + const char* result = findSharedLib(libname); + if (result) + lua_pushstring(L, result); + else + lua_pushnil(L); + return 1; +} + +//----------------------------------------------------------------------------- + +static int getglobal(lua_State* L) +{ + const char* name = lua_tostring(L, 1); + if (strcmp(name, "package") == 0) + { + + newpackage(L); + lua_pushvalue(L, -1); + lua_setglobal(L, "package"); + return 1; + } + + return 0; +} + +//----------------------------------------------------------------------------- + +static int matchfiles(lua_State* L) +{ + const char* path; + int i, numArgs; + + /* How many masks were passed in? */ + numArgs = lua_gettop(L); + + /* Get the current package path */ + lua_getglobal(L, "package"); + lua_pushstring(L, "path"); + lua_gettable(L, -2); + if (lua_isstring(L, -1)) + { + path = lua_tostring(L, -1); + } + else + { + if (currentScript != NULL) + path = currentScript; + else + path = "."; + } + lua_pop(L, 2); + + lua_newtable(L); + for (i = 1; i <= numArgs; ++i) + { + const char* mask = luaL_check_string(L, i); + int usePrefix = strcmp(getDirectory(mask), ".") != 0; + + dirOpen(path, mask); + while (dirGetNext()) + { + if (dirIsFile()) + { + if (usePrefix) + { + const char* result; + lua_pushstring(L, getDirectory(mask)); + lua_pushstring(L, dirGetName()); + lua_concat(L, 2); + result = lua_tostring(L, -1); + } + else + { + lua_pushstring(L, dirGetName()); + } + + lua_rawseti(L, -2, lua_getn(L,-2) + 1); + } + } + dirClose(); + } + + return 1; +} + +//----------------------------------------------------------------------------- + +static int newpackage(lua_State* L) +{ + int configs; + int n; + + createEmptyConfig(L, NULL); + + // Add the package to the master list in the registry + + lua_getregistry(L); + lua_pushstring(L, "packages"); + lua_gettable(L, -2); + n = lua_getn(L, -1); + + lua_pushvalue(L, -3); + lua_rawseti(L, -2, n + 1); + lua_pop(L, 2); + + // Set default values + + lua_pushstring(L, "name"); + if (n == 0) + lua_pushstring(L, getString(getProject(), "name")); + else + { + lua_pushstring(L, "Package"); + lua_pushnumber(L, n + 1); + lua_concat(L, 2); + } + lua_settable(L, -3); + + lua_pushstring(L, "script"); + lua_pushstring(L, currentScript); + lua_settable(L, -3); + + lua_pushstring(L, "path"); + lua_pushstring(L, getDirectory(currentScript)); + lua_settable(L, -3); + + lua_pushstring(L, "language"); + lua_pushstring(L, "c++"); + lua_settable(L, -3); + + lua_pushstring(L, "kind"); + lua_pushstring(L, "winexe"); + lua_settable(L, -3); + + lua_pushstring(L, "files"); + lua_newtable(L); + lua_settable(L, -3); + + /* Build list of configurations that can be indexed by name or number */ + lua_pushstring(L, "config"); + lua_newtable(L); + + configs = getArray(getProject(), "configs"); + for (n = 0; n < getArraySize(configs); ++n) + { + const char* name = getStringFromArray(configs, n); + lua_pushstring(L, name); + createEmptyConfig(L, name); + lua_settable(L, -3); + + lua_pushstring(L, name); + lua_gettable(L, -2); + lua_rawseti(L, -2, n + 1); + } + + lua_settable(L, -3); + + return 1; +} diff --git a/build/premake/src/Src/project.h b/build/premake/src/Src/project.h new file mode 100644 index 0000000000..c10b3549c3 --- /dev/null +++ b/build/premake/src/Src/project.h @@ -0,0 +1,81 @@ +//----------------------------------------------------------------------------- +// Premake - project.h +// +// An interface to the project settings. +// +// Copyright (C) 2002-2004 by Jason Perkins +// Source code licensed under the GPL, see LICENSE.txt for details. +// +// $Id: project.h,v 1.10 2004/03/27 13:42:24 jason379 Exp $ +//----------------------------------------------------------------------------- + +typedef struct _Config +{ + const char* name; + const char* target; + const char** buildFlags; + const char** buildOptions; + const char** defines; + const char** includePaths; + const char** libPaths; + const char** linkFlags; + const char** linkOptions; + const char** links; + const char* pchHeader; + const char* pchSource; + int numBuildFlags; + int numBuildOptions; + int numDefines; + int numIncludePaths; + int numLibPaths; + int numLinkFlags; + int numLinkOptions; + int numLinks; +} Config; + +typedef struct _Package +{ + const char* name; + const char* script; + const char* path; + const char* language; + const char* kind; + const char* url; + const char** files; + int numFiles; + Config** config; + int numConfigs; + void* data; +} Package; + +typedef struct _Option +{ + char* flag; + char* description; + struct _Option* next; +} Option; + +typedef struct _Project +{ + const char* name; + const char* binaries; + const char* libraries; + const char* path; + Package** package; + Option** option; + int numPackages; + int numOptions; +} Project; + + +extern Project* project; + +extern void createProject(char* argv[]); +extern int loadProject(char* project); +extern void closeProject(); +extern void handleCommand(char* args[], int i); + +// Deprecated? +extern Package* getPackage(const char* name); +extern void configureProject(); +extern void setProjectOption(char* option); diff --git a/build/premake/src/Src/sharpdev.c b/build/premake/src/Src/sharpdev.c new file mode 100644 index 0000000000..faacd65e8e --- /dev/null +++ b/build/premake/src/Src/sharpdev.c @@ -0,0 +1,356 @@ +//----------------------------------------------------------------------------- +// Premake - sharpdev.c +// +// ICSharpCode SharpDevelop tool target. +// Source code licensed under the GPL, see LICENSE.txt for details. +// +// Written by Chris McGuirk (leedgitar@latenitegames.com) +// Modified by Jason Perkins +//----------------------------------------------------------------------------- + +#include +#include +#include +#include "project.h" +#include "util.h" + +static char buffer[4096]; + +static int writeCombine(); +static int writeCsProject(Package* package); + +extern const char* dotnet; + +//----------------------------------------------------------------------------- + +int makeSharpDevScripts() +{ + int i; + + puts("Generating SharpDevelop combine and project files:"); + + for (i = 0; i < project->numPackages; ++i) + { + Package* package = project->package[i]; + + printf("...%s\n", package->name); + + if (strcmp(package->language, "c#") == 0) + { + if (!writeCsProject(package)) + return 0; + } + + else if (strcmp(package->language, "c++") == 0 || strcmp(package->language, "c") == 0) + { + printf("** Error: SharpDevelop does not support C/C++ development.\n"); + return 0; + } + + else + { + printf("** Error: unrecognized language '%s'\n", package->language); + return 0; + } + } + + if (!writeCombine()) + return 0; + + return 1; +} + +//----------------------------------------------------------------------------- + +static int writeCombine() +{ + int i, j, k; + + FILE* file; + file = openFile(project->path, project->name, ".cmbx"); + if (file == NULL) + return 0; + + fprintf(file, "\n", project->name); + + // TODO: select the first executable project + // pick the first project as the startup by default in the meantime + if(project->numPackages != 0) + { + fprintf(file, " \n", project->package[0]->name); + } + + // first write out the startup entries + for (i = 0; i < project->numPackages; ++i) + { + Package* package = project->package[i]; + const char* name = package->name; + fprintf(file, " \n", name); + } + + fprintf(file, " \n"); + fprintf(file, " \n"); + + // now write out the project entries + for (i = 0; i < project->numPackages; ++i) + { + Package* package = project->package[i]; + const char* name = package->name; + const char* path = reversePath(project->path, package->path, NATIVE); + fprintf(file, " \n", path, name, "prjx"); + } + + fprintf(file, " \n"); + fprintf(file, " \n"); + + // write out the entries for each build configuration + for (i = 0; i < project->package[0]->numConfigs; ++i) + { + const char* configName = project->package[0]->config[i]->name; + + fprintf(file, " \n", configName); + + // loop through each package. if has a configuration matching the curent one, write an entry + for(j = 0; j < project->numPackages; j++) + { + Package* package = project->package[j]; + const char* name = package->name; + + int isIncluded = 0; + + // look at each of this projects configs + for(k = 0; k < package->numConfigs; k++) + { + if(strcmp(configName, package->config[k]->name) != 0) + { + isIncluded = 1; + break; + } + } + + // write the entry for the current project in this build configuration + fprintf(file, " \n", package->name, configName, isIncluded ? "True" : "False"); + } + + fprintf(file, " \n"); + } + + fprintf(file, " \n"); + fprintf(file, ""); + + // Finish + fclose(file); + return 1; +} + +//----------------------------------------------------------------------------- + +static const char* checkDir(const char* path, void* data) +{ + return translatePath(path, WIN32); +} + +static const char* checkLibs(const char* file, void* data) +{ + Package* package = getPackage(file); + if (package == NULL) return file; + if (strcmp(package->language, "c#") != 0) return NULL; + return package->config[*((int*)data)]->target; +} + +//----------------------------------------------------------------------------- + +static const char* checkRefs(const char* ref, void* data) +{ + int i; + int isSibling = 0; + const char* fileName = getFilename(ref, 0); + + strcpy(buffer," type=\""); + + // Is this a sibling project? + for (i = 0; i < project->numPackages; ++i) + { + if (strcmp(project->package[i]->name, ref) == 0) + { + isSibling = 1; + break; + } + } + + if(isSibling) + { + strcat(buffer, "Project\""); + strcat(buffer, " refto=\""); + strcat(buffer, fileName); + strcat(buffer, "\" localcopy=\"True\""); + } + else + { + const char* ext = strchr(ref,',') ? "" : ".dll"; + + // See if this assembly exists on one of the link paths + Package* package = (Package*)data; + if (fileExists(project->binaries, ref, ext)) + { + strcat(buffer, "Assembly\" refto=\""); + strcat(buffer, reversePath(package->path, project->binaries, NATIVE)); + strcat(buffer, "/"); + strcat(buffer, ref); + strcat(buffer, ".dll\" localcopy=\"False\""); + } + else + { + strcat(buffer, "Gac\" refto=\""); + strcat(buffer, ref); + strcat(buffer, ext); + strcat(buffer, "\" localcopy=\"False\""); + } + } + + return buffer; +} + +static const char* checkRefPaths(const char* ref, void* data) +{ + const char* projPath = (const char*)data; + return makeAbsolute(projPath, ref); +} + +static const char* checkSrcFileType(const char* file, void* data) +{ + const char* ext; + + strcpy(buffer, translatePath(file, WIN32)); + strcat(buffer, "\" subtype=\"Code\" "); + + ext = getExtension(file); + if (strcmp(ext, ".cs") == 0) + { + strcat(buffer, "BuildAction=\"Compile\""); + } + else if (strcmp(ext, ".resx") == 0) + { + strcat(buffer, "BuildAction=\"EmbedAsResource\""); + } + else + { + strcat(buffer, "BuildAction=\"Nothing\""); + } + + return buffer; +} + +static int writeCsProject(Package* package) +{ + FILE* file; + const char* runtime; + const char* csc; + int i; + + const char* name = package->name; + const char* path = package->path; + const char* kind = package->kind; + + if (strcmp(kind, "winexe") == 0) + kind = "WinExe"; + else if (strcmp(kind, "exe") == 0) + kind = "Exe"; + else if (strcmp(kind, "dll") == 0 || strcmp(kind, "aspnet") == 0) + kind = "Library"; + else + { + printf("** Error: unknown package kind '%s'\n", kind); + return 0; + } + + // Figure out what .net environment I'm using + if (dotnet == NULL) + dotnet = (strcmp(osIdent, "windows") == 0) ? "ms" : "mono"; + + if (strcmp(dotnet, "ms") == 0) + { + runtime = "MsNet"; + csc = "Csc"; + } + else if (strcmp(dotnet, "mono") == 0) + { + runtime = "Mono"; + csc = "Mcs"; + } + else if (strcmp(dotnet, "pnet") == 0) + { + printf("** Error: SharpDevelop does not yet support Portable.NET\n"); + return 0; + } + else + { + printf("** Error: unknown .NET runtime '%s'\n", dotnet); + return 0; + } + + + // Open the project file and write the header + file = openFile(path, name, ".prjx"); + if (file == NULL) + return 0; + + // Project Header + fprintf(file, "\n", name); + + // File List + fprintf(file, " \n"); + writeList(file, package->files, " \n", "", checkSrcFileType, NULL); + fprintf(file, " \n"); + + // References + fprintf(file, " \n"); + writeList(file, package->config[0]->links, " \n", "", checkRefs, package); + fprintf(file, " \n"); + + // Configurations + fprintf(file, " \n", package->config[0]->name); + + for (i = 0; i < package->numConfigs; ++i) + { + Config* config = package->config[i]; + + int symbols = !inArray(config->buildFlags, "no-symbols"); + int optimize = inArray(config->buildFlags, "optimize") || inArray(config->buildFlags, "optimize-size") || inArray(config->buildFlags, "optimize-speed"); + int unsafe = inArray(config->buildFlags, "unsafe"); + + fprintf(file, " \n", config->name); + fprintf(file, " defines, "", "", ";", NULL, NULL); + fprintf(file, "\" "); + fprintf(file, "generatexmldocumentation=\"False\" "); + fprintf(file, "/>\n"); + + fprintf(file, " binaries, NATIVE)); + insertPath(file, getDirectory(config->target), NATIVE); + fprintf(file, "\" "); + fprintf(file, "assembly=\"%s\" ", getFilename(config->target,0)); + fprintf(file, "executeScript=\"\" "); + fprintf(file, "executeBeforeBuild=\"\" "); + fprintf(file, "executeAfterBuild=\"\" "); + fprintf(file, "/>\n"); + + fprintf(file, " \n", config->name); + } + + fprintf(file, " \n"); + fprintf(file, "\n"); + + fclose(file); + return 1; +} diff --git a/build/premake/src/Src/util.c b/build/premake/src/Src/util.c new file mode 100644 index 0000000000..7130cf31af --- /dev/null +++ b/build/premake/src/Src/util.c @@ -0,0 +1,566 @@ +//----------------------------------------------------------------------------- +// Premake - util.c +// +// Premake utility functions +// +// Copyright (C) 2002-2003 by Jason Perkins +// Source code licensed under the GPL, see LICENSE.txt for details. +// +// $Id: util.c,v 1.19 2004/03/27 13:42:24 jason379 Exp $ +//----------------------------------------------------------------------------- + +#include +#include +#include +#include "project.h" +#include "util.h" + +char** args; + +static char buffer[4096]; +static char buffer2[4096]; + +static char pathseps[] = { '/', '\\' }; + +extern int plat_chdir(const char* path); +extern int plat_copyFile(const char* src, const char* dest); +extern void plat_deleteDir(const char* path); +extern void plat_deleteFile(const char* path); +extern int plat_findLib(const char* lib, char* buffer, int size); +extern void plat_generateUUID(const char* uuid); +extern void plat_getcwd(char* buffer, int size); +extern int plat_isAbsPath(const char* path); + +extern int plat_dirOpen(const char* mask); +extern void plat_dirClose(); +extern int plat_dirGetNext(); +extern const char* plat_dirGetName(); +extern int plat_dirIsFile(); + +//----------------------------------------------------------------------------- + +int copyFile(const char* src, const char* dest) +{ + translatePath(src, NATIVE); // copies into buffer2 + strcpy(buffer, buffer2); + translatePath(dest, NATIVE); + return plat_copyFile(buffer, buffer2); +} + +//----------------------------------------------------------------------------- + +void deleteDirectory(const char* directory, const char* name) +{ + strcpy(buffer, directory); + if (strlen(directory) > 0) strcat(buffer, "/"); + strcat(buffer, name); + plat_deleteDir(translatePath(buffer, NATIVE)); +} + +//----------------------------------------------------------------------------- + +void deleteFile(const char* directory, const char* name, const char* extension) +{ + strcpy(buffer, directory); + if (strlen(buffer) > 0) strcat(buffer, "/"); + strcat(buffer, name); + strcat(buffer, extension); + plat_deleteFile(buffer); +} + +//----------------------------------------------------------------------------- + +int endsWith(const char* haystack, const char* needle) +{ + if (strlen(haystack) < strlen(needle)) + return 0; + + haystack = haystack + strlen(haystack) - strlen(needle); + return (strcmp(haystack, needle) == 0); +} + +//----------------------------------------------------------------------------- + +int fileExists(const char* path, const char* name, const char* extension) +{ + FILE* file; + char buffer[512]; + + strcpy(buffer, path); + if (path && strlen(path) > 0) + strcat(buffer, "/"); + strcat(buffer, name); + strcat(buffer, extension); + + file = fopen(buffer, "r"); + if (file != NULL) + { + fclose(file); + return 1; + } + + return 0; +} + +//----------------------------------------------------------------------------- + +const char* findSharedLib(const char* lib) +{ + if (plat_findLib(lib, buffer, 4096)) + return buffer; + return NULL; +} + +//----------------------------------------------------------------------------- + +static void stringify(unsigned char* src, char* dst, int count) +{ + char buffer[4]; + int i; + + for (i = 0; i < count; ++i) + { + sprintf(buffer, "%X", (int)src[i]); + + if (src[i] >= 0x10) + { + *(dst++) = buffer[0]; + *(dst++) = buffer[1]; + } + else + { + *(dst++) = '0'; + *(dst++) = buffer[0]; + } + } +} + +void generateUUID(char* uuid) +{ + plat_generateUUID(buffer); + + stringify(buffer, uuid, 4); + uuid[8] = '-'; + stringify(buffer + 4, uuid + 9, 2); + uuid[13] = '-'; + stringify(buffer + 6, uuid + 14, 2); + uuid[18] = '-'; + stringify(buffer + 8, uuid + 19, 2); + uuid[23] = '-'; + stringify(buffer + 10, uuid + 24, 6); + uuid[36] = '\0'; +} + +//----------------------------------------------------------------------------- + +const char* getDirectory(const char* path) +{ + char* ptr; + if (path != NULL) + { + strcpy(buffer, path); + for (ptr = buffer; *ptr; ptr++) + { + if (*ptr == '\\') + *ptr = '/'; + } + + ptr = strrchr(buffer, '/'); + if (ptr != NULL) + { + *(++ptr) = '\0'; + return buffer; + } + } + + return "."; +} + +//----------------------------------------------------------------------------- + +const char* getExtension(const char* path) +{ + if (path != NULL) + { + const char* ptr = strrchr(path, '.'); + return ptr; + } + + return NULL; +} + +//----------------------------------------------------------------------------- + +const char* getFilename(const char* path, int trim) +{ + if (path != NULL) + { + char* ptr = strrchr(path, '/'); + ptr = (ptr != NULL) ? ++ptr : (char*)path; + strcpy(buffer, ptr); + + if (trim) + { + ptr = strrchr(buffer, '.'); + if (ptr != NULL) *ptr = '\0'; + } + + return buffer; + } + + return NULL; +} + +//----------------------------------------------------------------------------- + +int hasOption(char* option) +{ + char** arg; + for (arg = args; *arg != NULL; ++arg) + { + if (strlen(*arg) == strlen(option) + 2 && strcmp((*arg) + 2, option) == 0) + { + return 1; + } + } + + return 0; +} + +//----------------------------------------------------------------------------- + +int inArray(const char** list, const char* value) +{ + while (*list) + { + if (strcmp(*list, value) == 0) + return 1; + ++list; + } + return 0; +} + +//----------------------------------------------------------------------------- + +void insertPath(FILE* file, const char* path, int type) +{ + if (strcmp(path, ".") != 0) + fprintf(file, translatePath(path, type)); +} + +//----------------------------------------------------------------------------- + +int isCppFile(const char* file) +{ + int i; + const char* ext = getExtension(file); + for (i = 0; CPP_EXT[i] != NULL; ++i) + { + if (strcmp(ext, CPP_EXT[i]) == 0) + return 1; + } + + return 0; +} + +//----------------------------------------------------------------------------- +// This function does some gyrations to handle the case where the requested +// directory doesn't actually exist. It tries to still give a reasonable path. + +const char* makeAbsolute(const char* base, const char* path) +{ + const char* ptr; + + // If the directory is already absolute I don't have to do anything + if (plat_isAbsPath(path)) + return translatePath(path, NATIVE); + + // chdir() to the package directory + plat_getcwd(buffer, 4096); + if (!plat_chdir(translatePath(base, NATIVE))) + { + plat_chdir(buffer); + return NULL; + } + + // Back my way up the tree + ptr = path; + while (*ptr == '.' || *ptr == '/') + { + if (strncmp(ptr, "..", 2) == 0) + { + plat_chdir(".."); + ptr += 2; + } + else + { + ptr++; + } + } + + +/* OBSOLETE + while (*ptr == '.') + { + if (strncmp(ptr, "../", 3) == 0) + { + plat_chdir(".."); + ptr += 3; + } + else if (strncmp(ptr, "./", 2) == 0) + { + ptr += 2; + } + else if (*(ptr + 1) == '\0') + { + ptr++; + } + } +*/ + + // Tack the remained of the path onto my current location + plat_getcwd(buffer2, 4096); + strcat(buffer2, "/"); + strcat(buffer2, ptr); + + for (ptr = buffer2; *ptr; ++ptr) + { + if (*ptr == '/') + *((char*)ptr) = nativePathSep; + } + + plat_chdir(buffer); + return buffer2; +} + +//----------------------------------------------------------------------------- + +FILE* openFile(const char* path, const char* name, const char* extension) +{ + FILE* file; + char buffer[512]; + + strcpy(buffer, path); + if (path && strlen(path) > 0) + strcat(buffer, "/"); + strcat(buffer, name); + strcat(buffer, extension); + + file = fopen(buffer, "wt"); + if (file == NULL) + printf("** Error: unable to open file '%s'\n", buffer); + + return file; +} + +//----------------------------------------------------------------------------- + +const char* replaceChars(const char* str, const char* replace) +{ + int i; + for (i = 0; i < (int)strlen(str); ++i) + buffer[i] = (strchr(replace, str[i]) == NULL) ? str[i] : '_'; + buffer[strlen(str)] = '\0'; + return buffer; +} + +//----------------------------------------------------------------------------- + +const char* replaceExtension(const char* path, const char* extension) +{ + char* ptr = strrchr(path, '.'); + if (ptr != NULL) + { + strncpy(buffer, path, ptr - path); + buffer[ptr - path] = '\0'; + } + else + strcpy(buffer, path); + strcat(buffer, extension); + return buffer; +} + +//----------------------------------------------------------------------------- + +const char* reversePath(const char* path, const char* subdir, int type) +{ + char origin[2048]; + char destination[2048]; + int start, i; + + // Get the full path to both locations + strcpy(origin, makeAbsolute(".", path)); + strcpy(destination, makeAbsolute(".", subdir)); + + // Trim off common directories + start = 0; + i = 0; + while (origin[i] && destination[i] && origin[i] == destination[i]) + { + if (origin[i] == nativePathSep) + start = i + 1; + ++i; + } + + // Build the return path + if (strlen(origin) - start > 0) + { + int i = start; + strcpy(buffer, ".."); + for ( ; origin[i]; ++i) + { + if (origin[i] == nativePathSep && origin[i+1] != '\0') + strcat(buffer, "/.."); + } + } + else + { + strcpy(buffer, "."); + } + + if (strlen(destination) - start > 0) + { + strcat(buffer, "/"); + strcat(buffer, destination + start); + } + + // It must end with a separator + if (buffer[strlen(buffer)-1] != '/' && buffer[strlen(buffer)-1] != '\\') strcat(buffer, "/"); + + return translatePath(buffer, type); +} + +//----------------------------------------------------------------------------- + +const char* translatePath(const char* path, int type) +{ + char* ptr; + char sep = (type == NATIVE) ? type = nativePathSep : pathseps[type]; + + strcpy(buffer2, path); + for (ptr = buffer2; *ptr != '\0'; ++ptr) + { + if (*ptr == '/' || *ptr == '\\') + *ptr = sep; + } + + return buffer2; +} + +//----------------------------------------------------------------------------- + +void walkSourceList(FILE* file, Package* package, const char* path, void (*cb)(FILE*, const char*, int)) +{ + const char** i; + + // Open the group + strcpy(buffer, path); + if (buffer[strlen(buffer)-1] == '/') buffer[strlen(buffer)-1] = '\0'; + cb(file, buffer, WST_OPENGROUP); + + for (i = package->files; *i; ++i) + { + const char* source = (*i); + + // For each file in the target directory... + if (strlen(source) > strlen(path) && strncmp(source, path, strlen(path)) == 0) + { + // Look for a subdirectory... + const char* ptr = strchr(source + strlen(path), '/'); + if (ptr != NULL) + { + // Have I processed this subdirectory already? + const char** j; + strncpy(buffer, source, ptr - source + 1); + buffer[ptr - source + 1] = '\0'; + for (j = package->files; *j; ++j) + { + if (strncmp(buffer, *j, strlen(buffer)) == 0) + break; + } + + if (i == j) + { + char* newpath = (char*)malloc(strlen(buffer) + 1); + strcpy(newpath, buffer); + walkSourceList(file, package, newpath, cb); + free(newpath); + } + } + } + } + + // Send the source files + for (i = package->files; *i; ++i) + { + const char* source = (*i); + const char* ptr = strrchr(source, '/'); + if (strncmp(path, source, strlen(path)) == 0 && ptr <= source + strlen(path)) + cb(file, source, WST_SOURCEFILE); + } + + // Close the group + strcpy(buffer, path); + if (buffer[strlen(buffer)-1] == '/') buffer[strlen(buffer)-1] = '\0'; + cb(file, buffer, WST_CLOSEGROUP); +} + +//----------------------------------------------------------------------------- + +void writeList(FILE* file, const char** list, const char* prefix, const char* postfix, const char* infix, const char* (*check)(const char*,void*), void* data) +{ + int i = 0; + while (*list) + { + const char* value = (check != NULL) ? check(*list, data) : *list; + if (value != NULL) + { + if (i++ > 0) fprintf(file, infix); + fprintf(file, "%s%s%s", prefix, value, postfix); + } + ++list; + } +} + +//----------------------------------------------------------------------------- + +const char* getCwd() +{ + plat_getcwd(buffer, 4096); + return buffer; +} + +int setCwd(const char* path) +{ + return plat_chdir(path); +} + +//----------------------------------------------------------------------------- + +int dirOpen(const char* base, const char* mask) +{ + strcpy(buffer, base); + strcat(buffer, "/"); + strcat(buffer, mask); + return plat_dirOpen(translatePath(buffer, NATIVE)); +} + +void dirClose() +{ + plat_dirClose(); +} + +int dirGetNext() +{ + return plat_dirGetNext(); +} + +const char* dirGetName() +{ + return plat_dirGetName(); +} + +int dirIsFile() +{ + return plat_dirIsFile(); +} diff --git a/build/premake/src/Src/util.h b/build/premake/src/Src/util.h new file mode 100644 index 0000000000..7cb737584d --- /dev/null +++ b/build/premake/src/Src/util.h @@ -0,0 +1,51 @@ +//----------------------------------------------------------------------------- +// Premake - util.h +// +// Premake utility functions +// +// Copyright (C) 2002-2003 by Jason Perkins +// Source code licensed under the GPL, see LICENSE.txt for details. +// +// $Id: util.h,v 1.13 2004/03/27 13:42:24 jason379 Exp $ +//----------------------------------------------------------------------------- + +static char* CPP_EXT[] = { ".cc", ".cpp", ".cxx", ".c", NULL }; + +enum { UNIX, WIN32, NATIVE }; +extern char nativePathSep; +extern const char* osIdent; + +enum { WST_OPENGROUP, WST_CLOSEGROUP, WST_SOURCEFILE }; + +extern char** args; + +extern int copyFile(const char* src, const char* dest); +extern void deleteDirectory(const char* path, const char* name); +extern void deleteFile(const char* path, const char* name, const char* extension); +extern int endsWith(const char* haystack, const char* needle); +extern int fileExists(const char* path, const char* name, const char* extension); +extern const char* findSharedLib(const char* lib); +extern void generateUUID(char* uuid); +extern const char* getDirectory(const char* path); +extern const char* getExtension(const char* path); +extern const char* getFilename(const char* path, int trim); +extern int hasOption(char* option); +extern int inArray(const char** list, const char* value); +extern void insertPath(FILE* file, const char* path, int type); +extern int isCppFile(const char* file); +extern const char* makeAbsolute(const char* base, const char* path); +extern FILE* openFile(const char* path, const char* name, const char* extension); +extern const char* replaceChars(const char* str, const char* replace); +extern const char* replaceExtension(const char* path, const char* extension); +extern const char* reversePath(const char* path, const char* subdir, int type); +extern const char* translatePath(const char* buffer, int type); +extern void walkSourceList(FILE* file, Package* package, const char* path, void (*cb)(FILE*, const char*, int)); +extern void writeList(FILE* file, const char** list, const char* prefix, const char* postfix, const char* infix, const char* (*check)(const char*,void*), void* data); +extern const char* getCwd(); +extern int setCwd(const char* path); + +extern int dirOpen(const char* base, const char* mask); +extern void dirClose(); +extern int dirGetNext(); +extern const char* dirGetName(); +extern int dirIsFile(); diff --git a/build/premake/src/Src/vs6.c b/build/premake/src/Src/vs6.c new file mode 100644 index 0000000000..e5112025cb --- /dev/null +++ b/build/premake/src/Src/vs6.c @@ -0,0 +1,614 @@ +//----------------------------------------------------------------------------- +// Premake - vs6.c +// +// MS Visual Studio 6 tool target. +// +// Copyright (C) 2002-2004 by Jason Perkins +// Source code licensed under the GPL, see LICENSE.txt for details. +// +// $Id: vs6.c,v 1.20 2004/05/07 00:12:29 jason379 Exp $ +//----------------------------------------------------------------------------- + +#include +#include +#include +#include "project.h" +#include "util.h" + +extern const char* dotnet; + +static int writeWorkspace(); +static int writeCsProject(Package* package); +static int writeVcProject(Package* package); +static int writeProjectHeader(FILE* file, Package* package); + +#if VS6_DOTNET +static char* csc; +#endif + +//----------------------------------------------------------------------------- + +int makeVs6Scripts() +{ + int i, csharp = 0; + + puts("Generating Visual Studio 6 workspace and project files:"); + +#if VS6_DOTNET + if (dotnet == NULL) + csc = "csc.exe"; + else if (strcmp(dotnet, "mono") == 0) + csc = "mcs.exe"; + else if (strcmp(dotnet, "pnet") == 0) + csc = "cscc.exe"; + else + csc = "csc.exe"; +#endif + + for (i = 0; i < project->numPackages; ++i) + { + Package* package = project->package[i]; + const char* language = package->language; + printf("...%s\n", package->name); + + if (strcmp(language, "c++") == 0 || strcmp(language, "c") == 0) + { + writeVcProject(package); + } + else if (strcmp(language, "c#") == 0) + { +#if VS6_DOTNET + csharp = 1; + writeCsProject(package); +#else + printf("** Error: C# projects are not supported by Visual Studio 6\n"); + return 0; +#endif + } + else + { + printf("** Error: unrecognized language '%s'\n", language); + return 0; + } + } + +#if VS6_DOTNET + if (csharp && getenv("DOTNET_PATH") == NULL) + { + printf("\nBEFORE USING THESE PROJECT FILES you must set the environment variable\n"); + printf("DOTNET_PATH to the directory containing %s.\n\n", csc); + + if (strcmp(csc, "csc.exe") == 0) + printf("This will be something like C:\\WinNT\\Microsoft.NET\\Framework\\v1.0.3705.\n\n"); + } +#endif + + return writeWorkspace(); +} + +//----------------------------------------------------------------------------- + +static int writeWorkspace() +{ + int i, j, k; + + FILE* file = openFile(project->path, project->name, ".dsw"); + if (file == NULL) + return 0; + + fprintf(file, "Microsoft Developer Studio Workspace File, Format Version 6.00\n"); + fprintf(file, "# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\n"); + fprintf(file, "\n"); + + for (i = 0; i < project->numPackages; ++i) + { + Package* package = project->package[i]; + + fprintf(file, "###############################################################################\n"); + fprintf(file, "\n"); + fprintf(file, "Project: \"%s\"=%s%s.dsp\n", replaceChars(package->name,"-"), reversePath(project->path,package->path,WIN32), package->name); + fprintf(file, "\n"); + fprintf(file, "Package=<5>\n"); + fprintf(file, "{{{\n"); + fprintf(file, "}}}\n"); + fprintf(file, "\n"); + fprintf(file, "Package=<4>\n"); + fprintf(file, "{{{\n"); + + // List package dependencies on sibling projects + for (j = 0; j < package->config[0]->numLinks; ++j) + { + const char* link = package->config[0]->links[j]; + for (k = 0; k < project->numPackages; k++) + { + if (strcmp(project->package[k]->name, link) == 0) + { + fprintf(file, " Begin Project Dependency\n"); + fprintf(file, " Project_Dep_Name %s\n", replaceChars(link, "-")); + fprintf(file, " End Project Dependency\n"); + } + } + } + + fprintf(file, "}}}\n"); + fprintf(file, "\n"); + } + + fprintf(file, "###############################################################################\n"); + fprintf(file, "\n"); + fprintf(file, "Global:\n"); + fprintf(file, "\n"); + fprintf(file, "Package=<5>\n"); + fprintf(file, "{{{\n"); + fprintf(file, "}}}\n"); + fprintf(file, "\n"); + fprintf(file, "Package=<3>\n"); + fprintf(file, "{{{\n"); + fprintf(file, "}}}\n"); + fprintf(file, "\n"); + fprintf(file, "###############################################################################\n"); + fprintf(file, "\n"); + + fclose(file); + return 1; +} + +//----------------------------------------------------------------------------- + +static void vcFiles(FILE* file, const char* path, int stage) +{ + const char* ptr = strrchr(path, '/'); + int i,j; + ptr = (ptr == NULL) ? path : ptr + 1; + + switch (stage) + { + case WST_OPENGROUP: + if (strlen(path) > 0 && strcmp(ptr, "..") != 0) { + fprintf(file, "# Begin Group \"%s\"\n\n", ptr); + fprintf(file, "# PROP Default_Filter \"\"\n"); + } + break; + case WST_CLOSEGROUP: + if (strlen(path) > 0 && strcmp(ptr, "..") != 0) + fprintf(file, "# End Group\n"); + break; + case WST_SOURCEFILE: + fprintf(file, "# Begin Source File\n\n"); + fprintf(file, "SOURCE=.\\%s\n", translatePath(path,WIN32)); + for (i=0;inumPackages;i++) + { + Package *package=project->package[i]; + for (j=0;jnumConfigs;j++) + { + Config *config=package->config[j]; + + fprintf(file, "!%s \"$(CFG)\" == \"%s - Win32 %s\"\n", (i == 0 ? "IF" : "ELSEIF"), replaceChars(package->name,"-"), config->name); + fprintf(file, "\n"); + + if (config->pchSource && strcmp(ptr, config->pchSource)==0) + { + fprintf(file, "# ADD CPP /Yc\"%s\"\n", config->pchHeader); + } + } + fprintf(file, "!ENDIF\n"); + } + fprintf(file, "# End Source File\n"); + break; + } +} + +static const char* checkLink(const char* path, void* data) +{ + Package* package = getPackage(path); + if (package == NULL) return path; + + if (strcmp(package->language, "c++") == 0) + return package->config[*((int*)data)]->target; + + return NULL; +} + +static int writeVcProject(Package* package) +{ + const char* ldflags; + const char* extension; + const char* outdir; + FILE* file; + int i; + + // Some target type specific info... + if (strcmp(package->kind, "winexe") == 0) + { + ldflags = "/subsystem:windows"; + extension = "exe"; + outdir = project->binaries; + } + else if (strcmp(package->kind, "exe") == 0) + { + ldflags = "/subsystem:console"; + extension = "exe"; + outdir = project->binaries; + } + else if (strcmp(package->kind, "dll") == 0) + { + ldflags = "/dll"; + extension = "dll"; + outdir = project->binaries; + } + else if (strcmp(package->kind, "lib") == 0) + { + ldflags = + extension = "lib"; + outdir = project->libraries; + } + else + { + printf("** Error: unknown package type '%s'\n", package->kind); + return 0; + } + + // Open the file and write the header + file = openFile(package->path, package->name, ".dsp"); + if (file == NULL) + return 0; + writeProjectHeader(file, package); + + fprintf(file, "CPP=cl.exe\n"); + fprintf(file, "MTL=midl.exe\n"); + fprintf(file, "RSC=rc.exe\n"); + fprintf(file, "\n"); + + for (i = 0; i < package->numConfigs; ++i) + { + char* runtime; + + Config* config = package->config[i]; + + int size = inArray(config->buildFlags, "optimize-size"); + int speed = inArray(config->buildFlags, "optimize-speed") || inArray(config->buildFlags, "optimize"); + int debug = !size && !speed; + int importlib = !inArray(config->buildFlags, "no-import-lib"); + int noMain = inArray(config->buildFlags, "no-main"); + int exceptions = !inArray(config->buildFlags, "no-exceptions"); + + int rtti = !inArray(config->buildFlags, "no-rtti"); + + if (inArray(config->linkFlags, "static-runtime") || inArray(config->buildFlags, "static-runtime")) + runtime = (debug) ? "/MTd" : "/MT"; + else + runtime = (debug) ? "/MDd" : "/MD"; + + fprintf(file, "!%s \"$(CFG)\" == \"%s - Win32 %s\"\n", (i == 0 ? "IF" : "ELSEIF"), replaceChars(package->name,"-"), config->name); + fprintf(file, "\n"); + fprintf(file, "# PROP BASE Use_MFC 0\n"); + fprintf(file, "# PROP BASE Use_Debug_Libraries %d\n", debug ? 1 : 0); + fprintf(file, "# PROP BASE Output_Dir \"%s\\\"\n", debug ? "Debug" : "Release"); + fprintf(file, "# PROP BASE Intermediate_Dir \"%s\\\"\n", debug ? "Debug" : "Release"); + fprintf(file, "# PROP BASE Target_Dir \"\"\n"); + fprintf(file, "# PROP Use_MFC 0\n"); + fprintf(file, "# PROP Use_Debug_Libraries %d\n", debug ? 1 : 0); + fprintf(file, "# PROP Output_Dir \""); + fprintf(file, reversePath(package->path, outdir, WIN32)); + insertPath(file, getDirectory(config->target), WIN32); + fprintf(file, "\"\n"); + fprintf(file, "# PROP Intermediate_Dir \"obj\\%s\\\"\n", config->name); + if (strcmp(package->kind, "lib") != 0) + fprintf(file, "# PROP Ignore_Export_Lib %d\n", importlib ? 0 : 1); + fprintf(file, "# PROP Target_Dir \"\"\n"); + + fprintf(file, "# ADD BASE CPP /nologo /W3"); + if (debug) + fprintf(file, " /Gm /GX /ZI /Od /D \"_DEBUG\" /YX /FD /GZ /c\n"); + else + fprintf(file, " /GX /O2 /D \"NDEBUG\" /YX /FD /c\n"); + + fprintf(file, "# ADD CPP /nologo %s /W3", runtime); + if (debug) fprintf(file, " /Gm /ZI /Od"); + + if (exceptions) fprintf(file, " /GX"); + + if (rtti) fprintf(file, " /GR"); + + if (size) fprintf(file, " /O1"); + if (speed) fprintf(file, " /O2"); + writeList(file, config->defines, " /D \"", "\"", "", NULL, NULL); + writeList(file, config->includePaths, " /I \"", "\"", "", NULL, NULL); + writeList(file, config->buildOptions, "", "", " ", NULL, NULL); + + if (config->pchHeader) + fprintf(file, " /Yu\"%s\"", config->pchHeader); + else + fprintf(file, " /YX"); + + if (debug) + fprintf(file, " /FD /GZ /c\n"); + else + fprintf(file, " /FD /c\n"); + + if (strcmp(package->kind, "lib") != 0) + { + fprintf(file, "# ADD BASE MTL /nologo /D \"NDEBUG\" /mktyplib203 /win32\n"); + fprintf(file, "# ADD MTL /nologo /D \"NDEBUG\" /mktyplib203 /win32\n"); + } + + fprintf(file, "# ADD BASE RSC /l 0x409 /d \"NDEBUG\"\n"); + fprintf(file, "# ADD RSC /l 0x409 /d \"NDEBUG\"\n"); + fprintf(file, "BSC32=bscmake.exe\n"); + fprintf(file, "# ADD BASE BSC32 /nologo\n"); + fprintf(file, "# ADD BSC32 /nologo\n"); + + if (strcmp(package->kind, "lib") != 0) + { + fprintf(file, "LINK32=link.exe\n"); + fprintf(file, "# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo %s /machine:I386 %s\n", + ldflags, debug ? "/debug /pdbtype:sept" : ""); + + fprintf(file, "# ADD LINK32"); + writeList(file, config->links, " ", ".lib", "", checkLink, &i); + fprintf(file, " /nologo %s", ldflags); + if (strcmp(package->kind, "winexe") == 0 && !noMain) + fprintf(file, " /entry:\"mainCRTStartup\""); + fprintf(file, " /out:\"%s", reversePath(package->path, project->binaries, WIN32)); + fprintf(file, "%s.%s\"", translatePath(config->target,WIN32), extension); + fprintf(file, " /machine:I386"); + if (strcmp(package->kind, "dll") == 0) + { + fprintf(file, " /implib:\""); + if (importlib) + fprintf(file, reversePath(package->path, project->libraries, WIN32)); + else + fprintf(file, "$(IntDir)\\"); + fprintf(file, "%s.lib\"", translatePath(config->target, WIN32)); + } + fprintf(file, " /pdbtype:sept /libpath:\"%s\"", reversePath(package->path, project->libraries, WIN32)); + if (debug) { + fprintf(file, " /pdb:\"%s", reversePath(package->path,project->binaries,WIN32)); + fprintf(file, "%s.pdb\" /debug", translatePath(config->target,WIN32)); + } + writeList(file, config->linkOptions, " ", "", "", NULL, NULL); + fprintf(file, "\n"); + } + else + { + fprintf(file, "LIB32=link.exe -lib\n"); + fprintf(file, "# ADD BASE LIB32 /nologo\n"); + fprintf(file, "# ADD LIB32 /nologo /out:\"%s", reversePath(package->path, project->libraries, WIN32)); + fprintf(file, "%s.%s\"\n", translatePath(config->target,WIN32), extension); + } + } + + fprintf(file, "!ENDIF \n"); + fprintf(file, "\n"); + fprintf(file, "# Begin Target\n"); + fprintf(file, "\n"); + + for (i = 0; i < package->numConfigs; ++i) + fprintf(file, "# Name \"%s - Win32 %s\"\n", replaceChars(package->name,"-"), package->config[i]->name); + walkSourceList(file, package, "", vcFiles); + + fprintf(file, "# End Target\n"); + fprintf(file, "# End Project\n"); + + fclose(file); + return 1; +} + +//----------------------------------------------------------------------------- + +#if VS6_DOTNET + +static const char* checkRef(const char* path, void* data) +{ + Package* package = getPackage(path); + if (package == NULL) return path; + + if (strcmp(package->language, "c#") == 0) + return package->config[*((int*)data)]->target; + + return NULL; +} + +static int writeCsProject(Package* package) +{ + const char* extension; + FILE* file; + int i, j; + + const char* kind = package->kind; + + // .NET requires all configurations use the same assembly filespec + const char* target = package->config[0]->target; + + // Figure out the object type + if (strcmp(kind, "winexe") == 0) + { + extension = "exe"; + } + else if (strcmp(kind, "exe") == 0) + { + extension = "exe"; + } + else if (strcmp(kind, "dll") == 0) + { + extension = "dll"; + kind = "library"; + } + else + { + printf("** Error: unknown package type '%s'\n", kind); + return 0; + } + + // Open the project file and write the header + + file = openFile(package->path, package->name, ".dsp"); + if (file == NULL) return 0; + if (!writeProjectHeader(file, package)) return 0; + + fprintf(file, "MTL=midl.exe\n"); + fprintf(file, "\n"); + + for (i = 0; i < package->numConfigs; ++i) + { + Config* config = package->config[i]; + + int symbols = !inArray(config->buildFlags, "no-symbols"); + int optimize = inArray(config->buildFlags,"optimize") || inArray(config->buildFlags,"optimize-size") && inArray(config->buildFlags,"optimize-speed"); + int unsafe = inArray(config->buildFlags, "unsafe"); + + fprintf(file, "!%s \"$(CFG)\" == \"%s - Win32 %s\"\n", i == 0 ? "IF" : "ELSEIF", replaceChars(package->name,"-"), config->name); + fprintf(file, "\n"); + fprintf(file, "# PROP BASE Use_MFC 0\n"); + fprintf(file, "# PROP BASE Use_Debug_Libraries 1\n"); + fprintf(file, "# PROP BASE Output_Dir \"Release\"\n"); + fprintf(file, "# PROP BASE Intermediate_Dir \"Release\"\n"); + fprintf(file, "# PROP BASE Target_Dir \"\"\n"); + fprintf(file, "# PROP Use_MFC 0\n"); + fprintf(file, "# PROP Use_Debug_Libraries 0\n"); + fprintf(file, "# PROP Output_Dir \""); + fprintf(file, reversePath(package->path, project->binaries, WIN32)); + insertPath(file, getDirectory(config->target), WIN32); + fprintf(file, "\"\n"); + fprintf(file, "# PROP Intermediate_Dir \"obj\\%s\"\n", config->name); + fprintf(file, "# PROP Target_Dir \"\"\n"); + fprintf(file, "# Begin Special Build Tool\n"); + fprintf(file, "SOURCE=\"$(InputPath)\"\n"); + + fprintf(file, "PostBuild_Cmds=$(DOTNET_PATH)\\%s /nologo", csc); + fprintf(file, " /out:\"%s", reversePath(package->path,project->binaries,WIN32)); + fprintf(file, "\\%s.%s\"", translatePath(config->target,WIN32), extension); + fprintf(file, " /target:%s", kind); + if (symbols) fprintf(file, " /debug"); + if (optimize) fprintf(file, " /optimize"); + if (unsafe) fprintf(file, " /unsafe"); + fprintf(file, " /lib:\"%s\"", reversePath(package->path, project->binaries, WIN32)); + writeList(file, config->links, " /r:", ".dll", "", checkRef, &i); + fprintf(file, " obj\\%s\\*.cs\n", config->name); + + fprintf(file, "# End Special Build Tool\n"); + fprintf(file, "\n"); + } + + fprintf(file, "!ENDIF\n"); + fprintf(file, "\n"); + fprintf(file, "# Begin Target\n"); + fprintf(file, "\n"); + for (i = 0; i < package->numConfigs; ++i) + fprintf(file, "# Name \"%s - Win32 %s\"\n", replaceChars(package->name,"-"), package->config[i]->name); + for (i = 0; i < package->numFiles; ++i) + { + const char* source = package->files[i]; + + fprintf(file, "# Begin Source File\n"); + fprintf(file, "\n"); + fprintf(file, "SOURCE=.\\%s\n", translatePath(source, WIN32)); + fprintf(file, "\n"); + + for (j = 0; j < package->numConfigs; ++j) + { + Config* config = package->config[j]; + + fprintf(file, "!%s \"$(CFG)\" == \"%s - Win32 %s\"", (i == 0 ? "IF" : "ELSEIF"), replaceChars(package->name,"-"), config->name); + fprintf(file, "\n"); + fprintf(file, "# Begin Custom Build - %s\n", source); + fprintf(file, "IntDir=.\\obj\\%s\n", config->name); + fprintf(file, "InputPath=.\\%s\n", translatePath(source, WIN32)); + fprintf(file, "\n"); + fprintf(file, "\"$(INTDIR)\\%s\" : $(SOURCE) \"$(INTDIR)\" \"$(OUTDIR)\"\n", translatePath(source, WIN32)); + fprintf(file, "\tcopy $(InputPath) $(IntDir)\\%s > out\n", translatePath(source, WIN32)); + fprintf(file, "\terase out\n"); + fprintf(file, "\n"); + fprintf(file, "# End Custom Build\n"); + fprintf(file, "\n"); + } + + fprintf(file, "!ENDIF \n"); + fprintf(file, "\n"); + fprintf(file, "# End Source File\n"); + } + + fprintf(file, "# End Target\n"); + fprintf(file, "# End Project\n"); + fprintf(file, "\n"); + + fclose(file); + return 1; +} + +#endif + +//----------------------------------------------------------------------------- + +static int writeProjectHeader(FILE* file, Package* package) +{ + int i; + const char* tag; + const char* num; + + const char* name = replaceChars(package->name, "-"); + + if (strcmp(package->language, "c#") == 0) + { + tag = "Win32 (x86) Generic Project"; + num = "0x010a"; + } + else + { + if (strcmp(package->kind, "winexe") == 0) + { + tag = "Win32 (x86) Application"; + num = "0x0101"; + } + else if (strcmp(package->kind, "exe") == 0) + { + tag = "Win32 (x86) Console Application"; + num = "0x0103"; + } + else if (strcmp(package->kind, "dll") == 0) + { + tag = "Win32 (x86) Dynamic-Link Library"; + num = "0x0102"; + } + else if (strcmp(package->kind, "lib") == 0) + { + tag = "Win32 (x86) Static Library"; + num = "0x0104"; + } + else + { + puts("** Error: unrecognized package type"); + return 0; + } + } + + fprintf(file, "# Microsoft Developer Studio Project File - Name=\"%s\" - Package Owner=<4>\n", name); + fprintf(file, "# Microsoft Developer Studio Generated Build File, Format Version 6.00\n"); + fprintf(file, "# ** DO NOT EDIT **\n"); + fprintf(file, "\n"); + fprintf(file, "# TARGTYPE \"%s\" %s\n", tag, num); + fprintf(file, "\n"); + fprintf(file, "CFG=%s - Win32 Debug\n", name); + fprintf(file, "!MESSAGE This is not a valid makefile. To build this project using NMAKE,\n"); + fprintf(file, "!MESSAGE use the Export Makefile command and run\n"); + fprintf(file, "!MESSAGE \n"); + fprintf(file, "!MESSAGE NMAKE /f \"%s.mak\".\n", package->name); + fprintf(file, "!MESSAGE \n"); + fprintf(file, "!MESSAGE You can specify a configuration when running NMAKE\n"); + fprintf(file, "!MESSAGE by defining the macro CFG on the command line. For example:\n"); + fprintf(file, "!MESSAGE \n"); + fprintf(file, "!MESSAGE NMAKE /f \"%s.mak\" CFG=\"%s - Win32 Debug\"\n", package->name, name); + fprintf(file, "!MESSAGE \n"); + fprintf(file, "!MESSAGE Possible choices for configuration are:\n"); + fprintf(file, "!MESSAGE \n"); + for (i = 0; i < package->numConfigs; ++i) + fprintf(file, "!MESSAGE \"%s - Win32 %s\" (based on \"%s\")\n", name, package->config[i]->name, tag); + fprintf(file, "!MESSAGE \n"); + fprintf(file, "\n"); + fprintf(file, "# Begin Project\n"); + fprintf(file, "# PROP AllowPerConfigDependencies 0\n"); + fprintf(file, "# PROP Scc_ProjName \"\"\n"); + fprintf(file, "# PROP Scc_LocalPath \"\"\n"); + + return 1; +} diff --git a/build/premake/src/Src/vs7.c b/build/premake/src/Src/vs7.c new file mode 100644 index 0000000000..f1e60826ee --- /dev/null +++ b/build/premake/src/Src/vs7.c @@ -0,0 +1,897 @@ +//----------------------------------------------------------------------------- +// Premake - vs_xml.c +// +// MS Visual Studio XML projects files (v7.0-2003) +// +// Copyright (C) 2002-2004 by Jason Perkins +// Source code licensed under the GPL, see LICENSE.txt for details. +// +// $Id: vs7.c,v 1.34 2004/05/11 00:38:58 jason379 Exp $ +//----------------------------------------------------------------------------- + +#include +#include +#include +#include "project.h" +#include "util.h" + +typedef struct _PkgData +{ + char projGuid[38]; + char toolGuid[38]; + char projExt[8]; + char projType[8]; +} PkgData; + +static char buffer[4096]; + +static int writeSolution(int version); +static int writeVcProject(int version, Package* package); +static int writeCsProject(int version, Package* package); + +//----------------------------------------------------------------------------- + +int makeVsXmlScripts(int version) +{ + int i; + printf("Generating Visual Studio %d solution and project files:\n", version); + + // Assign UUIDs to all packages + for (i = 0; i < project->numPackages; ++i) + { + Package* package = project->package[i]; + PkgData* data = (PkgData*)malloc(sizeof(PkgData)); + package->data = data; + generateUUID(data->projGuid); + if (strcmp(package->language, "c++") == 0 || strcmp(package->language, "c") == 0) + { + strcpy(data->toolGuid, "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942"); + } + else if (strcmp(package->language, "c#") == 0) + { + strcpy(data->toolGuid, "FAE04EC0-301F-11D3-BF4B-00C04F79EFBC"); + } + else + { + printf("** Error: unrecognized language '%s'\n", package->language); + return 0; + } + } + + // Generate the project files + for (i = 0; i < project->numPackages; ++i) + { + Package* package = project->package[i]; + PkgData* data = (PkgData*)package->data; + + printf("...%s\n", package->name); + + if (strcmp(package->language, "c++") == 0 || strcmp(package->language, "c") == 0) + { + strcpy(data->projExt, "vcproj"); + strcpy(data->projType, "Win32"); + if (!writeVcProject(version, package)) + return 0; + } + + else if (strcmp(package->language, "c#") == 0) + { + strcpy(data->projExt, "csproj"); + strcpy(data->projType, ".NET"); + if (!writeCsProject(version, package)) + return 0; + } + } + + if (!writeSolution(version)) + return 0; + + return 1; +} + +//----------------------------------------------------------------------------- + +static int numDeps = 0; /* Use by the project dependency writer */ + +/* Look for a package with the same name as 'name' and if found, return a + * dependency description to be included in the solution file */ +static const char* checkProjectDependencies(const char* name, void* data) +{ + int i; + int version = (int)data; + for (i = 0; i < project->numPackages; ++i) + { + if (strcmp(project->package[i]->name, name) == 0) + { + PkgData* data = (PkgData*)project->package[i]->data; + if (version == 7) + { + sprintf(buffer, "%d = {%s}", numDeps++, data->projGuid); + } + else + { + sprintf(buffer, "{%s} = {%s}", data->projGuid, data->projGuid); + } + return buffer; + } + } + return NULL; +} + +static int writeSolution(int version) +{ + int i, j; + FILE* file; + + file = openFile(project->path, project->name, ".sln"); + if (file == NULL) + return 0; + + /* Line 1: Format identification string */ + fprintf(file, "Microsoft Visual Studio Solution File, Format Version "); + switch (version) + { + case 7: + fprintf(file, "7.00\n"); + break; + case 2003: + fprintf(file, "8.00\n"); + break; + } + + /* List of projects that make up the solution */ + for (i = 0; i < project->numPackages; ++i) + { + Package* package = project->package[i]; + PkgData* data = package->data; + const char* name = package->name; + const char* path = reversePath(project->path, package->path, WIN32); + + /* VS.NET doesn't write out the leading '.\' on solution-relative + * paths. Not really necessary, but I'm trying to match the original */ + if (strncmp(path, ".\\", 2) == 0) + path = path + 2; + + fprintf(file, "Project(\"{%s}\") = \"%s\", \"%s%s.%s\", \"{%s}\"\n", data->toolGuid, name, path, name, data->projExt, data->projGuid); + if (version == 2003) + { + fprintf(file, "\tProjectSection(ProjectDependencies) = postProject\n"); + writeList(file, package->config[0]->links, "\t\t", "\n", "", checkProjectDependencies, (void*)version); + fprintf(file, "\tEndProjectSection\n"); + } + fprintf(file, "EndProject\n"); + } + + fprintf(file, "Global\n"); + fprintf(file, "\tGlobalSection(SolutionConfiguration) = preSolution\n"); + for (i = 0; i < project->package[0]->numConfigs; ++i) + { + if (version == 7) + { + fprintf(file, "\t\tConfigName.%d = %s\n", i, project->package[0]->config[i]->name); + } + else + { + fprintf(file, "\t\t%s = %s\n", project->package[0]->config[i]->name, project->package[0]->config[i]->name); + } + } + fprintf(file, "\tEndGlobalSection\n"); + + /* Find package dependencies for VS7 */ + if (version == 7) + { + fprintf(file, "\tGlobalSection(ProjectDependencies) = postSolution\n"); + for (i = 0; i < project->numPackages; ++i) + { + char prefix[128]; + Package* package = project->package[i]; + PkgData* data = (PkgData*)package->data; + Config* config = package->config[0]; + + numDeps = 0; + sprintf(prefix, "\t\t{%s}.", data->projGuid); + writeList(file, config->links, prefix, "\n", "", checkProjectDependencies, (void*)version); + } + fprintf(file, "\tEndGlobalSection\n"); + } + + // Write configuration for each project + fprintf(file, "\tGlobalSection(ProjectConfiguration) = postSolution\n"); + for (i = 0; i < project->numPackages; ++i) + { + Package* package = project->package[i]; + for (j = 0; j < package->numConfigs; ++j) + { + Config* config = package->config[j]; + PkgData* data = (PkgData*)package->data; + fprintf(file, "\t\t{%s}.%s.ActiveCfg = %s|%s\n", data->projGuid, config->name, config->name, data->projType); + fprintf(file, "\t\t{%s}.%s.Build.0 = %s|%s\n", data->projGuid, config->name, config->name, data->projType); + } + } + fprintf(file, "\tEndGlobalSection\n"); + + // Finish + + fprintf(file, "\tGlobalSection(ExtensibilityGlobals) = postSolution\n"); + fprintf(file, "\tEndGlobalSection\n"); + fprintf(file, "\tGlobalSection(ExtensibilityAddIns) = postSolution\n"); + fprintf(file, "\tEndGlobalSection\n"); + fprintf(file, "EndGlobal\n"); + + fclose(file); + return 1; +} + +//----------------------------------------------------------------------------- + +static const char* checkDir(const char* path, void* data) +{ + return translatePath(path, WIN32); +} + +static const char* checkLibs(const char* file, void* data) +{ + Package* package = getPackage(file); + if (package == NULL) return file; + if (strcmp(package->language, "c++") != 0) return NULL; + return package->config[*((int*)data)]->target; +} + +static void vcFiles(FILE* file, const char* path, int stage) +{ + char indent[128]; + char* ptr; + int i=0, j=0; + + strcpy(indent, " "); + if (strlen(path) > 0) strcat(indent, " "); + ptr = strchr(path, '/'); + while (ptr != NULL) { + strcat(indent, " "); + ptr = strchr(ptr + 1, '/'); + } + + ptr = strrchr(path, '/'); + ptr = (ptr == NULL) ? (char*)path : ptr + 1; + + switch (stage) + { + case WST_OPENGROUP: + if (strlen(path) > 0 && strcmp(ptr, "..") != 0) + { + fprintf(file, "%s\n", indent); + } + break; + + case WST_CLOSEGROUP: + if (strlen(path) > 0 && strcmp(ptr, "..") != 0) + fprintf(file, "%s\n", indent); + break; + + case WST_SOURCEFILE: + fprintf(file, "%s\n", indent, translatePath(path, WIN32)); + for (i=0;inumPackages;i++) + { + Package *package=project->package[i]; + for (j=0;jnumConfigs;j++) + { + Config *config=package->config[j]; + + if (config->pchSource && strcmp(ptr, config->pchSource)==0) + { + fprintf(file, "%s \n", indent, config->name); + fprintf(file, "%s \n", indent); + fprintf(file, "%s ", indent); + } + } + } + fprintf(file, "%s\n", indent); + break; + } +} + +static int writeVcProject(int version, Package* package) +{ + int configType, subsystem, managed, i; + const char* extension; + FILE* file; + + const char* name = package->name; + const char* path = package->path; + const char* kind = package->kind; + PkgData* data = (PkgData*)package->data; + + // Set up target type information + + if (strcmp(kind, "winexe") == 0 || strcmp(kind, "exe") == 0) + { + configType = 1; + extension = "exe"; + } + else if (strcmp(kind, "dll") == 0) + { + configType = 2; + extension = "dll"; + } + else if (strcmp(kind, "lib") == 0) + { + configType = 4; + extension = "lib"; + } + else if (strcmp(kind, "aspnet") == 0) + { + puts("** Error: C++ ASP.NET projects are not supported"); + return 0; + } + else + { + printf("** Error: unknown package kind '%s'\n", kind); + return 0; + } + + // Check the build subsystem...must be the same for all configs + + subsystem = (strcmp(kind, "exe") == 0) ? 1 : 2; + managed = inArray(package->config[0]->buildFlags, "managed"); + + // Open the file and write the header + + file = openFile(path, name, ".vcproj"); + if (file == NULL) + return 0; + + fprintf(file, "\n"); + fprintf(file, "projGuid); + fprintf(file, " Keyword=\"%s\">\n", managed ? "ManagedCProj" : "Win32Proj"); + fprintf(file, " \n"); + fprintf(file, " \n"); + fprintf(file, " \n"); + + // Write configurations + + fprintf(file, " \n"); + for (i = 0; i < package->numConfigs; ++i) + { + int optLevel, debug, symbols, runtime, noMain; + Config* config = package->config[i]; + + int optimize = inArray(config->buildFlags, "optimize"); + int size = inArray(config->buildFlags, "optimize-size"); + int speed = inArray(config->buildFlags, "optimize-speed"); + + int check64bit = !inArray(config->buildFlags, "no-64bit-checks"); + int importlib = !inArray(config->buildFlags, "no-import-lib"); + int exceptions = !inArray(config->buildFlags, "no-exceptions"); + int rtti = !inArray(config->buildFlags, "no-rtti"); + int rtc = !inArray(config->buildFlags, "no-runtime-checks"); + + if (speed) + optLevel = 2; + else if (size) + optLevel = 1; + else if (optimize) + optLevel = 3; + else + optLevel = 0; + debug = (optLevel == 0); + + if (!inArray(config->buildFlags, "no-symbols")) + symbols = (managed || inArray(config->buildFlags, "no-edit-and-continue")) ? 3 : 4; + else + symbols = 0; + + if (inArray(config->linkFlags, "static-runtime") || inArray(config->buildFlags, "static-runtime")) + runtime = (debug) ? 1 : 0; + else + runtime = (debug) ? 3 : 2; + + noMain = inArray(config->buildFlags, "no-main"); + + fprintf(file, " name); + fprintf(file, " OutputDirectory=\""); + fprintf(file, reversePath(path, (configType != 4 ? project->binaries : project->libraries), WIN32)); + insertPath(file, getDirectory(config->target), WIN32); + fprintf(file, "\"\n"); + fprintf(file, " IntermediateDirectory=\"obj\\%s\\\"\n", config->name); + fprintf(file, " ConfigurationType=\"%d\"\n", configType); + fprintf(file, " CharacterSet=\"2\""); + if (managed) fprintf(file, "\n ManagedExtensions=\"TRUE\""); + fprintf(file, ">\n"); + + fprintf(file, " buildOptions, "", "", " ", NULL, NULL); + fprintf(file, "\"\n"); + fprintf(file, " AdditionalIncludeDirectories=\""); + writeList(file, config->includePaths, "", "", ",", checkDir, NULL); + fprintf(file, "\"\n"); + if (managed) + { + fprintf(file, " AdditionalUsingDirectories=\""); + fprintf(file, reversePath(path, project->binaries, WIN32)); + fprintf(file, "\"\n"); + } + fprintf(file, " PreprocessorDefinitions=\""); + writeList(file, config->defines, "", "", ";", NULL, NULL); + fprintf(file, "\"\n"); + fprintf(file, " MinimalRebuild=\"%s\"\n", (debug && !managed) ? "TRUE" : "FALSE"); + if (!exceptions) fprintf(file, " ExceptionHandling=\"FALSE\"\n"); + fprintf(file, " BasicRuntimeChecks=\"%d\"\n", (debug && !managed && rtc) ? 3 : 0); + if (!debug) fprintf(file, " StringPooling=\"TRUE\"\n"); + if (!debug) fprintf(file, " EnableFunctionLevelLinking=\"TRUE\"\n"); + fprintf(file, " RuntimeLibrary=\"%d\"\n", runtime); + if (rtti) + fprintf(file, " RuntimeTypeInfo=\"TRUE\"\n"); + + if (config->pchHeader) + { + fprintf(file, " UsePrecompiledHeader=\"3\"\n"); + fprintf(file, " PrecompiledHeaderThrough=\"%s\"\n", config->pchHeader); + } + else + fprintf(file, " UsePrecompiledHeader=\"0\"\n"); + + fprintf(file, " WarningLevel=\"3\"\n"); + if (!managed) fprintf(file, " Detect64BitPortabilityProblems=\"%s\"\n", check64bit ? "TRUE" : "FALSE"); + fprintf(file, " DebugInformationFormat=\"%d\"/>\n", symbols); + + fprintf(file, " \n"); + + if (configType != 4) + { + fprintf(file, " linkOptions, " ", "", "", NULL, NULL); + fprintf(file, "\"\n"); + fprintf(file, " AdditionalDependencies=\""); + writeList(file, config->links, "", ".lib", " ", checkLibs, &i); + fprintf(file, "\"\n"); + fprintf(file, " OutputFile=\"$(OutDir)\\%s.%s\"\n", getFilename(config->target, 0), extension); + fprintf(file, " LinkIncremental=\"%d\"\n", debug ? 2 : 1); + fprintf(file, " AdditionalLibraryDirectories=\""); + fprintf(file, reversePath(path, project->libraries, WIN32)); + writeList(file, config->libPaths, ";", "", "", checkDir, NULL); + fprintf(file, "\"\n"); + fprintf(file, " GenerateDebugInformation=\"%s\"\n", symbols ? "TRUE" : "FALSE"); + if (symbols) fprintf(file, " ProgramDatabaseFile=\"obj\\%s\\%s.pdb\"\n", config->name, getFilename(config->target, 0)); + fprintf(file, " SubSystem=\"%d\"\n", subsystem); + if (!debug) fprintf(file, " OptimizeReferences=\"2\"\n"); + if (!debug) fprintf(file, " EnableCOMDATFolding=\"2\"\n"); + if ((strcmp(kind, "winexe") == 0 || strcmp(kind, "exe") == 0) && !noMain) + fprintf(file, " EntryPointSymbol=\"mainCRTStartup\"\n"); + else if (strcmp(kind, "dll") == 0) { + fprintf(file, " ImportLibrary=\""); + if (importlib) + fprintf(file, reversePath(path, project->libraries, WIN32)); + else + fprintf(file, "$(IntDir)"); + fprintf(file, "%s.lib\"\n", getFilename(config->target, 1)); + } + fprintf(file, " TargetMachine=\"1\"/>\n"); + } + else + { + fprintf(file, " \n", config->target); + } + + fprintf(file, " \n"); + + fprintf(file, " \n"); + + fprintf(file, " \n"); + + fprintf(file, " \n"); + + fprintf(file, " \n"); + + fprintf(file, " \n"); + + fprintf(file, " \n"); + fprintf(file, " \n"); + } + + fprintf(file, " \n"); + + fprintf(file, " \n"); + walkSourceList(file, package, "", vcFiles); + fprintf(file, " \n"); + + fprintf(file, " \n"); + fprintf(file, " \n"); + fprintf(file, "\n"); + + fclose(file); + return 1; +} + +//----------------------------------------------------------------------------- + +static const char* checkRefs(const char* ref, void* data) +{ + int i; + char* comma; + char tmp[1024]; + + // Pull the name out of the full reference + strcpy(tmp, ref); + comma = strchr(tmp, ','); + if (comma != NULL) + *comma = '\0'; + + // Write the reference name + strcpy(buffer, " Name = \""); + strcat(buffer, tmp); + strcat(buffer, "\"\n"); + + // Is this a sibling project? + for (i = 0; i < project->numPackages; ++i) + { + if (strcmp(project->package[i]->name, ref) == 0) + { + PkgData* data = (PkgData*)project->package[i]->data; + strcat(buffer, " Project = \"{"); + strcat(buffer, data->projGuid); + strcat(buffer, "}\"\n"); + strcat(buffer, " Package = \"{"); + strcat(buffer, data->toolGuid); + strcat(buffer, "}\"\n"); + return buffer; + } + } + + strcat(buffer, " AssemblyName = \""); + strcat(buffer, getFilename(tmp, 0)); + strcat(buffer, "\"\n"); + if (strlen(tmp) != strlen(getFilename(tmp, 0))) { + strcat(buffer, " HintPath = \""); + strcat(buffer, tmp); + strcat(buffer, ".dll\"\n"); + } + + // Tack on any extra information about the assembly + while (comma != NULL) + { + char* start; + for (start = comma + 1; *start == ' '; ++start); + comma = strchr(start, '='); + *comma = '\0'; + strcat(buffer, " "); + strcat(buffer, start); + strcat(buffer, " = \""); + + start = comma + 1; + comma = strchr(start, ','); + if (comma != NULL) *comma = '\0'; + strcat(buffer, start); + strcat(buffer, "\"\n"); + } + + return buffer; +} + +static const char* checkRefPaths(const char* ref, void* data) +{ + const char* projPath = (const char*)data; + return makeAbsolute(projPath, ref); +} + +static const char* checkSrcFileType(const char* file, void* data) +{ + Package* package = (Package*)data; + + strcpy(buffer, translatePath(file, WIN32)); + strcat(buffer, "\"\n"); + + if (endsWith(file, ".aspx.cs") || endsWith(file, ".asax.cs")) + { + /* The path to the parent .aspx file is relative to the .cs file. + * I assume that they are in the same directory and strip off all + * path information, then cut off the '.cs' */ + char* ptr = strrchr(file, '/'); + if (ptr == NULL) + ptr = (char*)file; + else + ptr++; + + strcat(buffer, "\t\t\t\t\tDependentUpon = \""); + strncat(buffer, ptr, strlen(ptr) - 3); + strcat(buffer, "\"\n"); + strcat(buffer, "\t\t\t\t\tSubType = \"ASPXCodeBehind\"\n"); + strcat(buffer, "\t\t\t\t\tBuildAction = \"Compile\"\n"); + } +/* obsolete, handled by ".resx" block below + else if (endsWith(file, ".aspx.resx") || endsWith(file, ".asax.resx")) + { + strcat(buffer, "\t\t\t\t\tDependentUpon = \""); + strncat(buffer, file, strlen(file) - 5); + strcat(buffer, ".cs\"\n"); + strcat(buffer, "\t\t\t\t\tBuildAction = \"EmbeddedResource\"\n"); + } +*/ + else if (endsWith(file, ".cs")) + { + strcat(buffer, "\t\t\t\t\tSubType = \"Code\"\n"); + strcat(buffer, "\t\t\t\t\tBuildAction = \"Compile\"\n"); + } + else if (endsWith(file, ".aspx")) + { + strcat(buffer, "\t\t\t\t\tSubType = \"Form\"\n"); + strcat(buffer, "\t\t\t\t\tBuildAction = \"Content\"\n"); + } + else if (endsWith(file, ".asax")) + { + strcat(buffer, "\t\t\t\t\tSubType = \"Component\"\n"); + strcat(buffer, "\t\t\t\t\tBuildAction = \"Content\"\n"); + } + else if (endsWith(file, ".resx")) + { + /* If a matching .cs file exists, link it */ + char depname[2048]; + strcpy(depname, file); + strcpy(depname + strlen(file) - 5, ".cs"); + if (inArray(package->files, depname)) + { + /* Path is relative to .resx file, I assume both are in same + * directory and cut off path information */ + char* ptr = strrchr(depname, '/'); + ptr = (ptr != NULL) ? ptr+1 : depname; + strcat(buffer, "\t\t\t\t\tDependentUpon = \""); + strcat(buffer, ptr); + strcat(buffer, "\"\n"); + } + strcat(buffer, "\t\t\t\t\tBuildAction = \"EmbeddedResource\"\n"); + } + else + { + strcat(buffer, "\t\t\t\t\tBuildAction = \""); + strcat(buffer, strcmp(package->kind, "aspnet") == 0 ? "Content" : "None"); + strcat(buffer, "\"\n"); + } + + return buffer; +} + +static int writeCsProject(int version, Package* package) +{ + FILE* file; + const char* target; + const char* outputType; + int i; + + const char* name = package->name; + const char* path = package->path; + const char* kind = package->kind; + PkgData* data = (PkgData*)package->data; + + if (strcmp(kind, "winexe") == 0) + outputType = "WinExe"; + else if (strcmp(kind, "exe") == 0) + outputType = "Exe"; + else if (strcmp(kind, "dll") == 0 || strcmp(kind, "aspnet") == 0) + outputType = "Library"; + else + { + printf("** Error: unknown package kind '%s'\n", kind); + return 0; + } + + // Open the project file and write the header + file = openFile(path, name, ".csproj"); + if (file == NULL) + return 0; + + fprintf(file, "\n"); + fprintf(file, " projGuid); + fprintf(file, " >\n"); + fprintf(file, " \n"); + fprintf(file, " config[0]->target, 0)); + fprintf(file, " AssemblyOriginatorKeyFile = \"\"\n"); + fprintf(file, " DefaultClientScript = \"JScript\"\n"); + fprintf(file, " DefaultHTMLPageLayout = \"Grid\"\n"); + fprintf(file, " DefaultTargetSchema = \"IE50\"\n"); + fprintf(file, " DelaySign = \"false\"\n"); + if (version == 7) + { + fprintf(file, " NoStandardLibraries = \"false\"\n"); + } + fprintf(file, " OutputType = \"%s\"\n", outputType); + if (version == 2003) + { + fprintf(file, " PreBuildEvent = \"\"\n"); + fprintf(file, " PostBuildEvent = \"\"\n"); + } + fprintf(file, " RootNamespace = \"%s\"\n", getFilename(package->config[0]->target, 0)); + if (version == 2003) + { + fprintf(file, " RunPostBuildEvent = \"OnBuildSuccess\"\n"); + } + + fprintf(file, " StartupObject = \"\"\n"); + fprintf(file, " >\n"); + + for (i = 0; i < package->numConfigs; ++i) + { + Config* config = package->config[i]; + + int symbols = !inArray(config->buildFlags, "no-symbols"); + int optimize = inArray(config->buildFlags, "optimize") || inArray(config->buildFlags, "optimize-size") || inArray(config->buildFlags, "optimize-speed"); + int unsafe = inArray(config->buildFlags, "unsafe"); + + fprintf(file, " name); + fprintf(file, " AllowUnsafeBlocks = \"%s\"\n", unsafe ? "true" : "false"); + fprintf(file, " BaseAddress = \"285212672\"\n"); + fprintf(file, " CheckForOverflowUnderflow = \"false\"\n"); + fprintf(file, " ConfigurationOverrideFile = \"\"\n"); + fprintf(file, " DefineConstants = \""); + writeList(file, config->defines, "", "", ";", NULL, NULL); + fprintf(file, "\"\n"); + fprintf(file, " DocumentationFile = \"\"\n"); + fprintf(file, " DebugSymbols = \"%s\"\n", symbols ? "true" : "false"); + fprintf(file, " FileAlignment = \"4096\"\n"); + fprintf(file, " IncrementalBuild = \""); + fprintf(file, strcmp(kind, "aspnet") == 0 ? "false" : "true"); + fprintf(file, "\"\n"); + if (version == 2003) + { + fprintf(file, " NoStdLib = \"false\"\n"); + fprintf(file, " NoWarn = \"\"\n"); + } + fprintf(file, " Optimize = \"%s\"\n", optimize ? "true" : "false"); + + fprintf(file, " OutputPath = \""); + fprintf(file, reversePath(path, project->binaries, WIN32)); + insertPath(file, getDirectory(config->target), WIN32); + fprintf(file, "\"\n"); + + fprintf(file, " RegisterForComInterop = \"false\"\n"); + fprintf(file, " RemoveIntegerChecks = \"false\"\n"); + fprintf(file, " TreatWarningsAsErrors = \"false\"\n"); + fprintf(file, " WarningLevel = \"4\"\n"); + fprintf(file, " />\n"); + } + + fprintf(file, " \n"); + + // VS7 requires same references for all configurations + fprintf(file, " \n"); + writeList(file, package->config[0]->links, " \n", "", checkRefs, package); + fprintf(file, " \n"); + fprintf(file, " \n"); + + fprintf(file, " \n"); + fprintf(file, " \n"); + writeList(file, package->files, " \n", "", checkSrcFileType, package); + fprintf(file, " \n"); + fprintf(file, " \n"); + fprintf(file, " \n"); + fprintf(file, "\n"); + + fclose(file); + + // Now write the .csproj.user file for non-web applications or + // .csproj.webinfo for web applications + + if (strcmp(kind, "aspnet") != 0) + { + file = openFile(path, name, ".csproj.user"); + if (file == NULL) + return 0; + + fprintf(file, "\n"); + fprintf(file, " \n"); + fprintf(file, " \n"); + fprintf(file, " config[0]->libPaths, "", ";", "", checkRefPaths, (void*)path); + target = makeAbsolute(".", project->binaries); + if (target != NULL) fprintf(file, target); + fprintf(file, "\" >\n"); + + for (i = 0; i < package->numConfigs; ++i) + { + fprintf(file, " config[i]->name); + fprintf(file, " EnableASPDebugging = \"false\"\n"); + fprintf(file, " EnableASPXDebugging = \"false\"\n"); + fprintf(file, " EnableUnmanagedDebugging = \"false\"\n"); + fprintf(file, " EnableSQLServerDebugging = \"false\"\n"); + fprintf(file, " RemoteDebugEnabled = \"false\"\n"); + fprintf(file, " RemoteDebugMachine = \"\"\n"); + fprintf(file, " StartAction = \"Project\"\n"); + fprintf(file, " StartArguments = \"\"\n"); + fprintf(file, " StartPage = \"\"\n"); + fprintf(file, " StartProgram = \"\"\n"); + fprintf(file, " StartURL = \"\"\n"); + fprintf(file, " StartWorkingDirectory = \"\"\n"); + fprintf(file, " StartWithIE = \"false\"\n"); + fprintf(file, " />\n"); + } + + fprintf(file, " \n"); + fprintf(file, " \n"); + fprintf(file, " \n"); + fprintf(file, " \n"); + fprintf(file, "\n"); + + fclose(file); + } + else + { + if (package->url == NULL) + { + sprintf(buffer, "http://localhost/%s", package->name); + package->url = buffer; + } + + file = openFile(path, name, ".csproj.webinfo"); + if (file == NULL) + return 0; + + fprintf(file, "\n"); + fprintf(file, " \n", package->url, package->name); + fprintf(file, "\n"); + + fclose(file); + } + + return 1; +} diff --git a/build/premake/src/Src/windows.c b/build/premake/src/Src/windows.c new file mode 100644 index 0000000000..64057ac2a3 --- /dev/null +++ b/build/premake/src/Src/windows.c @@ -0,0 +1,169 @@ +//----------------------------------------------------------------------------- +// Premake - windows.c +// +// MS Windows file and directory manipulation functions. +// +// Copyright (C) 2002-2004 by Jason Perkins +// Source code licensed under the GPL, see LICENSE.txt for details. +// +// $Id: windows.c,v 1.10 2004/01/09 20:48:02 jason379 Exp $ +//----------------------------------------------------------------------------- + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include + +char nativePathSep = '\\'; +const char* osIdent = "windows"; + +static int (__stdcall *CoCreateGuid)(char*) = NULL; +static HANDLE hDir; +static WIN32_FIND_DATA entry; +static int first; + +//----------------------------------------------------------------------------- + +int plat_chdir(const char* path) +{ + return SetCurrentDirectory(path); +} + +//----------------------------------------------------------------------------- + +int plat_copyFile(const char* src, const char* dest) +{ + return CopyFile(src, dest, FALSE); +} + +//----------------------------------------------------------------------------- + +void plat_deleteDir(const char* path) +{ + WIN32_FIND_DATA data; + HANDLE hDir; + + char* buffer = (char*)malloc(strlen(path) + 6); + strcpy(buffer, path); + strcat(buffer, "\\*.*"); + hDir = FindFirstFile(buffer, &data); + if (hDir == INVALID_HANDLE_VALUE) + return; + free(buffer); + + do + { + if (strcmp(data.cFileName, ".") == 0) continue; + if (strcmp(data.cFileName, "..") == 0) continue; + + buffer = (char*)malloc(strlen(path) + strlen(data.cFileName) + 2); + strcpy(buffer, path); + strcat(buffer, "\\"); + strcat(buffer, data.cFileName); + + if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + plat_deleteDir(buffer); + else + DeleteFile(buffer); + + free(buffer); + } while (FindNextFile(hDir, &data)); + FindClose(hDir); + + RemoveDirectory(path); +} + +//----------------------------------------------------------------------------- + +void plat_deleteFile(const char* path) +{ + DeleteFile(path); +} + +//----------------------------------------------------------------------------- + +int plat_findLib(const char* lib, char* buffer, int size) +{ + HMODULE hLib = LoadLibrary(lib); + if (hLib != NULL) + { + char* ptr; + + GetModuleFileName(hLib, buffer, size); + for (ptr = buffer; *ptr != '\0'; ++ptr) + if (*ptr == '\\') *ptr = '/'; + + ptr = strrchr(buffer, '/'); + if (ptr) *ptr = '\0'; + + FreeLibrary(hLib); + return 1; + } + return 0; +} + +//----------------------------------------------------------------------------- + +void plat_generateUUID(char* uuid) +{ + if (CoCreateGuid == NULL) + { + HMODULE hOleDll = LoadLibrary("OLE32.DLL"); + *((void**)&CoCreateGuid) = GetProcAddress(hOleDll, "CoCreateGuid"); + } + + CoCreateGuid(uuid); +} + +//----------------------------------------------------------------------------- + +void plat_getcwd(char* buffer, int size) +{ + GetCurrentDirectory(size, buffer); +} + +//----------------------------------------------------------------------------- + +int plat_isAbsPath(const char* buffer) +{ + return (buffer[0] == '/' || buffer[0] == '\\' || buffer[1] == ':'); +} + +//----------------------------------------------------------------------------- + +int plat_dirOpen(const char* mask) +{ + hDir = FindFirstFile(mask, &entry); + first = 1; + return (hDir != INVALID_HANDLE_VALUE); +} + +void plat_dirClose() +{ + if (hDir != INVALID_HANDLE_VALUE) + FindClose(hDir); +} + +int plat_dirGetNext() +{ + if (hDir == INVALID_HANDLE_VALUE) return 0; + if (first) + { + first = !first; + return 1; + } + else + { + return FindNextFile(hDir, &entry); + } +} + +const char* plat_dirGetName() +{ + return entry.cFileName; +} + +int plat_dirIsFile() +{ + return (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0; +} diff --git a/build/premake/src/premake.lua b/build/premake/src/premake.lua new file mode 100644 index 0000000000..4cc408bf58 --- /dev/null +++ b/build/premake/src/premake.lua @@ -0,0 +1,30 @@ +project.name = "Premake" + +package.language = "c++" +package.kind = "exe" +package.target = "premake" + +package.buildflags = { "no-64bit-checks", "static-runtime" } +package.config["Release"].buildflags = { "no-symbols", "optimize-size" } + +package.files = +{ + "Src/premake.c", + "Src/project.h", + "Src/project.c", + "Src/util.h", + "Src/util.c", + "Src/clean.c", + "Src/gnu.c", + "Src/sharpdev.c", + "Src/vs7.c", + "Src/vs6.c", + matchfiles("Src/Lua/*.c", "Src/Lua/*.h") +} + +if (OS == "windows") then + tinsert(package.files, "Src/windows.c") +else + tinsert(package.files, "Src/posix.c") +end + diff --git a/source/workspaces/required-libraries-linux.txt b/build/workspaces/required-libraries-linux.txt similarity index 100% rename from source/workspaces/required-libraries-linux.txt rename to build/workspaces/required-libraries-linux.txt diff --git a/source/workspaces/required-libraries.txt b/build/workspaces/required-libraries.txt similarity index 100% rename from source/workspaces/required-libraries.txt rename to build/workspaces/required-libraries.txt diff --git a/source/workspaces/update-workspaces.bat b/build/workspaces/update-workspaces.bat similarity index 100% rename from source/workspaces/update-workspaces.bat rename to build/workspaces/update-workspaces.bat diff --git a/source/workspaces/update-workspaces.sh b/build/workspaces/update-workspaces.sh similarity index 100% rename from source/workspaces/update-workspaces.sh rename to build/workspaces/update-workspaces.sh diff --git a/source/ape/ape.dsp b/source/tools/ape/ape.dsp similarity index 100% rename from source/ape/ape.dsp rename to source/tools/ape/ape.dsp diff --git a/source/ape/ape.dsw b/source/tools/ape/ape.dsw similarity index 100% rename from source/ape/ape.dsw rename to source/tools/ape/ape.dsw diff --git a/source/ape/ext/MathUtil.h b/source/tools/ape/ext/MathUtil.h similarity index 100% rename from source/ape/ext/MathUtil.h rename to source/tools/ape/ext/MathUtil.h diff --git a/source/ape/ext/Particle.cpp b/source/tools/ape/ext/Particle.cpp similarity index 100% rename from source/ape/ext/Particle.cpp rename to source/tools/ape/ext/Particle.cpp diff --git a/source/ape/ext/Particle.h b/source/tools/ape/ext/Particle.h similarity index 100% rename from source/ape/ext/Particle.h rename to source/tools/ape/ext/Particle.h diff --git a/source/ape/ext/ParticleEmitter.cpp b/source/tools/ape/ext/ParticleEmitter.cpp similarity index 100% rename from source/ape/ext/ParticleEmitter.cpp rename to source/tools/ape/ext/ParticleEmitter.cpp diff --git a/source/ape/ext/ParticleEmitter.h b/source/tools/ape/ext/ParticleEmitter.h similarity index 100% rename from source/ape/ext/ParticleEmitter.h rename to source/tools/ape/ext/ParticleEmitter.h diff --git a/source/ape/ext/ParticleSystem.cpp b/source/tools/ape/ext/ParticleSystem.cpp similarity index 100% rename from source/ape/ext/ParticleSystem.cpp rename to source/tools/ape/ext/ParticleSystem.cpp diff --git a/source/ape/ext/ParticleSystem.h b/source/tools/ape/ext/ParticleSystem.h similarity index 100% rename from source/ape/ext/ParticleSystem.h rename to source/tools/ape/ext/ParticleSystem.h diff --git a/source/ape/ext/Sprite.cpp b/source/tools/ape/ext/Sprite.cpp similarity index 100% rename from source/ape/ext/Sprite.cpp rename to source/tools/ape/ext/Sprite.cpp diff --git a/source/ape/ext/Sprite.h b/source/tools/ape/ext/Sprite.h similarity index 100% rename from source/ape/ext/Sprite.h rename to source/tools/ape/ext/Sprite.h diff --git a/source/ape/ext/Types.h b/source/tools/ape/ext/Types.h similarity index 100% rename from source/ape/ext/Types.h rename to source/tools/ape/ext/Types.h diff --git a/source/ape/ext/Vector3D.cpp b/source/tools/ape/ext/Vector3D.cpp similarity index 100% rename from source/ape/ext/Vector3D.cpp rename to source/tools/ape/ext/Vector3D.cpp diff --git a/source/ape/ext/Vector3D.h b/source/tools/ape/ext/Vector3D.h similarity index 100% rename from source/ape/ext/Vector3D.h rename to source/tools/ape/ext/Vector3D.h diff --git a/source/ape/ext/tex_.cpp b/source/tools/ape/ext/tex_.cpp similarity index 100% rename from source/ape/ext/tex_.cpp rename to source/tools/ape/ext/tex_.cpp diff --git a/source/ape/ext/tex_.h b/source/tools/ape/ext/tex_.h similarity index 100% rename from source/ape/ext/tex_.h rename to source/tools/ape/ext/tex_.h diff --git a/source/ape/ext/timer_.cpp b/source/tools/ape/ext/timer_.cpp similarity index 100% rename from source/ape/ext/timer_.cpp rename to source/tools/ape/ext/timer_.cpp diff --git a/source/ape/ext/timer_.h b/source/tools/ape/ext/timer_.h similarity index 100% rename from source/ape/ext/timer_.h rename to source/tools/ape/ext/timer_.h diff --git a/source/ape/main.cpp b/source/tools/ape/main.cpp similarity index 100% rename from source/ape/main.cpp rename to source/tools/ape/main.cpp diff --git a/source/ape/readme.txt b/source/tools/ape/readme.txt similarity index 100% rename from source/ape/readme.txt rename to source/tools/ape/readme.txt diff --git a/source/sced/AlterElevationCommand.cpp b/source/tools/sced/AlterElevationCommand.cpp similarity index 100% rename from source/sced/AlterElevationCommand.cpp rename to source/tools/sced/AlterElevationCommand.cpp diff --git a/source/sced/AlterElevationCommand.h b/source/tools/sced/AlterElevationCommand.h similarity index 100% rename from source/sced/AlterElevationCommand.h rename to source/tools/sced/AlterElevationCommand.h diff --git a/source/sced/AlterLightEnvCommand.cpp b/source/tools/sced/AlterLightEnvCommand.cpp similarity index 100% rename from source/sced/AlterLightEnvCommand.cpp rename to source/tools/sced/AlterLightEnvCommand.cpp diff --git a/source/sced/AlterLightEnvCommand.h b/source/tools/sced/AlterLightEnvCommand.h similarity index 100% rename from source/sced/AlterLightEnvCommand.h rename to source/tools/sced/AlterLightEnvCommand.h diff --git a/source/sced/Array2D.h b/source/tools/sced/Array2D.h similarity index 100% rename from source/sced/Array2D.h rename to source/tools/sced/Array2D.h diff --git a/source/sced/BrushShapeEditorTool.cpp b/source/tools/sced/BrushShapeEditorTool.cpp similarity index 100% rename from source/sced/BrushShapeEditorTool.cpp rename to source/tools/sced/BrushShapeEditorTool.cpp diff --git a/source/sced/BrushShapeEditorTool.h b/source/tools/sced/BrushShapeEditorTool.h similarity index 100% rename from source/sced/BrushShapeEditorTool.h rename to source/tools/sced/BrushShapeEditorTool.h diff --git a/source/sced/BrushTool.cpp b/source/tools/sced/BrushTool.cpp similarity index 100% rename from source/sced/BrushTool.cpp rename to source/tools/sced/BrushTool.cpp diff --git a/source/sced/BrushTool.h b/source/tools/sced/BrushTool.h similarity index 100% rename from source/sced/BrushTool.h rename to source/tools/sced/BrushTool.h diff --git a/source/sced/Command.h b/source/tools/sced/Command.h similarity index 100% rename from source/sced/Command.h rename to source/tools/sced/Command.h diff --git a/source/sced/CommandManager.cpp b/source/tools/sced/CommandManager.cpp similarity index 100% rename from source/sced/CommandManager.cpp rename to source/tools/sced/CommandManager.cpp diff --git a/source/sced/CommandManager.h b/source/tools/sced/CommandManager.h similarity index 100% rename from source/sced/CommandManager.h rename to source/tools/sced/CommandManager.h diff --git a/source/sced/EditorData.cpp b/source/tools/sced/EditorData.cpp similarity index 100% rename from source/sced/EditorData.cpp rename to source/tools/sced/EditorData.cpp diff --git a/source/sced/EditorData.h b/source/tools/sced/EditorData.h similarity index 100% rename from source/sced/EditorData.h rename to source/tools/sced/EditorData.h diff --git a/source/sced/InfoBox.cpp b/source/tools/sced/InfoBox.cpp similarity index 100% rename from source/sced/InfoBox.cpp rename to source/tools/sced/InfoBox.cpp diff --git a/source/sced/InfoBox.h b/source/tools/sced/InfoBox.h similarity index 100% rename from source/sced/InfoBox.h rename to source/tools/sced/InfoBox.h diff --git a/source/sced/MiniMap.cpp b/source/tools/sced/MiniMap.cpp similarity index 100% rename from source/sced/MiniMap.cpp rename to source/tools/sced/MiniMap.cpp diff --git a/source/sced/MiniMap.h b/source/tools/sced/MiniMap.h similarity index 100% rename from source/sced/MiniMap.h rename to source/tools/sced/MiniMap.h diff --git a/source/sced/NaviCam.cpp b/source/tools/sced/NaviCam.cpp similarity index 100% rename from source/sced/NaviCam.cpp rename to source/tools/sced/NaviCam.cpp diff --git a/source/sced/NaviCam.h b/source/tools/sced/NaviCam.h similarity index 100% rename from source/sced/NaviCam.h rename to source/tools/sced/NaviCam.h diff --git a/source/sced/PaintObjectCommand.cpp b/source/tools/sced/PaintObjectCommand.cpp similarity index 100% rename from source/sced/PaintObjectCommand.cpp rename to source/tools/sced/PaintObjectCommand.cpp diff --git a/source/sced/PaintObjectCommand.h b/source/tools/sced/PaintObjectCommand.h similarity index 100% rename from source/sced/PaintObjectCommand.h rename to source/tools/sced/PaintObjectCommand.h diff --git a/source/sced/PaintObjectTool.cpp b/source/tools/sced/PaintObjectTool.cpp similarity index 100% rename from source/sced/PaintObjectTool.cpp rename to source/tools/sced/PaintObjectTool.cpp diff --git a/source/sced/PaintObjectTool.h b/source/tools/sced/PaintObjectTool.h similarity index 100% rename from source/sced/PaintObjectTool.h rename to source/tools/sced/PaintObjectTool.h diff --git a/source/sced/PaintTextureCommand.cpp b/source/tools/sced/PaintTextureCommand.cpp similarity index 100% rename from source/sced/PaintTextureCommand.cpp rename to source/tools/sced/PaintTextureCommand.cpp diff --git a/source/sced/PaintTextureCommand.h b/source/tools/sced/PaintTextureCommand.h similarity index 100% rename from source/sced/PaintTextureCommand.h rename to source/tools/sced/PaintTextureCommand.h diff --git a/source/sced/PaintTextureTool.cpp b/source/tools/sced/PaintTextureTool.cpp similarity index 100% rename from source/sced/PaintTextureTool.cpp rename to source/tools/sced/PaintTextureTool.cpp diff --git a/source/sced/PaintTextureTool.h b/source/tools/sced/PaintTextureTool.h similarity index 100% rename from source/sced/PaintTextureTool.h rename to source/tools/sced/PaintTextureTool.h diff --git a/source/sced/RaiseElevationCommand.cpp b/source/tools/sced/RaiseElevationCommand.cpp similarity index 100% rename from source/sced/RaiseElevationCommand.cpp rename to source/tools/sced/RaiseElevationCommand.cpp diff --git a/source/sced/RaiseElevationCommand.h b/source/tools/sced/RaiseElevationCommand.h similarity index 100% rename from source/sced/RaiseElevationCommand.h rename to source/tools/sced/RaiseElevationCommand.h diff --git a/source/sced/RaiseElevationTool.cpp b/source/tools/sced/RaiseElevationTool.cpp similarity index 100% rename from source/sced/RaiseElevationTool.cpp rename to source/tools/sced/RaiseElevationTool.cpp diff --git a/source/sced/RaiseElevationTool.h b/source/tools/sced/RaiseElevationTool.h similarity index 100% rename from source/sced/RaiseElevationTool.h rename to source/tools/sced/RaiseElevationTool.h diff --git a/source/sced/ScEd.clw b/source/tools/sced/ScEd.clw similarity index 100% rename from source/sced/ScEd.clw rename to source/tools/sced/ScEd.clw diff --git a/source/sced/ScEd.dep b/source/tools/sced/ScEd.dep similarity index 100% rename from source/sced/ScEd.dep rename to source/tools/sced/ScEd.dep diff --git a/source/sced/ScEd.dsp b/source/tools/sced/ScEd.dsp similarity index 100% rename from source/sced/ScEd.dsp rename to source/tools/sced/ScEd.dsp diff --git a/source/sced/ScEd.mak b/source/tools/sced/ScEd.mak similarity index 100% rename from source/sced/ScEd.mak rename to source/tools/sced/ScEd.mak diff --git a/source/sced/SelectObjectTool.cpp b/source/tools/sced/SelectObjectTool.cpp similarity index 100% rename from source/sced/SelectObjectTool.cpp rename to source/tools/sced/SelectObjectTool.cpp diff --git a/source/sced/SelectObjectTool.h b/source/tools/sced/SelectObjectTool.h similarity index 100% rename from source/sced/SelectObjectTool.h rename to source/tools/sced/SelectObjectTool.h diff --git a/source/sced/SmoothElevationCommand.cpp b/source/tools/sced/SmoothElevationCommand.cpp similarity index 100% rename from source/sced/SmoothElevationCommand.cpp rename to source/tools/sced/SmoothElevationCommand.cpp diff --git a/source/sced/SmoothElevationCommand.h b/source/tools/sced/SmoothElevationCommand.h similarity index 100% rename from source/sced/SmoothElevationCommand.h rename to source/tools/sced/SmoothElevationCommand.h diff --git a/source/sced/SmoothElevationTool.cpp b/source/tools/sced/SmoothElevationTool.cpp similarity index 100% rename from source/sced/SmoothElevationTool.cpp rename to source/tools/sced/SmoothElevationTool.cpp diff --git a/source/sced/SmoothElevationTool.h b/source/tools/sced/SmoothElevationTool.h similarity index 100% rename from source/sced/SmoothElevationTool.h rename to source/tools/sced/SmoothElevationTool.h diff --git a/source/sced/Tool.h b/source/tools/sced/Tool.h similarity index 100% rename from source/sced/Tool.h rename to source/tools/sced/Tool.h diff --git a/source/sced/ToolManager.cpp b/source/tools/sced/ToolManager.cpp similarity index 100% rename from source/sced/ToolManager.cpp rename to source/tools/sced/ToolManager.cpp diff --git a/source/sced/ToolManager.h b/source/tools/sced/ToolManager.h similarity index 100% rename from source/sced/ToolManager.h rename to source/tools/sced/ToolManager.h diff --git a/source/sced/UserConfig.cpp b/source/tools/sced/UserConfig.cpp similarity index 100% rename from source/sced/UserConfig.cpp rename to source/tools/sced/UserConfig.cpp diff --git a/source/sced/UserConfig.h b/source/tools/sced/UserConfig.h similarity index 100% rename from source/sced/UserConfig.h rename to source/tools/sced/UserConfig.h diff --git a/source/sced/ui/BrushShapeEditorDlgBar.cpp b/source/tools/sced/ui/BrushShapeEditorDlgBar.cpp similarity index 100% rename from source/sced/ui/BrushShapeEditorDlgBar.cpp rename to source/tools/sced/ui/BrushShapeEditorDlgBar.cpp diff --git a/source/sced/ui/BrushShapeEditorDlgBar.h b/source/tools/sced/ui/BrushShapeEditorDlgBar.h similarity index 100% rename from source/sced/ui/BrushShapeEditorDlgBar.h rename to source/tools/sced/ui/BrushShapeEditorDlgBar.h diff --git a/source/sced/ui/ColorButton.cpp b/source/tools/sced/ui/ColorButton.cpp similarity index 100% rename from source/sced/ui/ColorButton.cpp rename to source/tools/sced/ui/ColorButton.cpp diff --git a/source/sced/ui/ColorButton.h b/source/tools/sced/ui/ColorButton.h similarity index 100% rename from source/sced/ui/ColorButton.h rename to source/tools/sced/ui/ColorButton.h diff --git a/source/sced/ui/DirectionButton.cpp b/source/tools/sced/ui/DirectionButton.cpp similarity index 100% rename from source/sced/ui/DirectionButton.cpp rename to source/tools/sced/ui/DirectionButton.cpp diff --git a/source/sced/ui/DirectionButton.h b/source/tools/sced/ui/DirectionButton.h similarity index 100% rename from source/sced/ui/DirectionButton.h rename to source/tools/sced/ui/DirectionButton.h diff --git a/source/sced/ui/ElevToolsDlgBar.cpp b/source/tools/sced/ui/ElevToolsDlgBar.cpp similarity index 100% rename from source/sced/ui/ElevToolsDlgBar.cpp rename to source/tools/sced/ui/ElevToolsDlgBar.cpp diff --git a/source/sced/ui/ElevToolsDlgBar.h b/source/tools/sced/ui/ElevToolsDlgBar.h similarity index 100% rename from source/sced/ui/ElevToolsDlgBar.h rename to source/tools/sced/ui/ElevToolsDlgBar.h diff --git a/source/sced/ui/ElevationButton.cpp b/source/tools/sced/ui/ElevationButton.cpp similarity index 100% rename from source/sced/ui/ElevationButton.cpp rename to source/tools/sced/ui/ElevationButton.cpp diff --git a/source/sced/ui/ElevationButton.h b/source/tools/sced/ui/ElevationButton.h similarity index 100% rename from source/sced/ui/ElevationButton.h rename to source/tools/sced/ui/ElevationButton.h diff --git a/source/sced/ui/ImageListCtrl.cpp b/source/tools/sced/ui/ImageListCtrl.cpp similarity index 100% rename from source/sced/ui/ImageListCtrl.cpp rename to source/tools/sced/ui/ImageListCtrl.cpp diff --git a/source/sced/ui/ImageListCtrl.h b/source/tools/sced/ui/ImageListCtrl.h similarity index 100% rename from source/sced/ui/ImageListCtrl.h rename to source/tools/sced/ui/ImageListCtrl.h diff --git a/source/sced/ui/LightSettingsDlg.cpp b/source/tools/sced/ui/LightSettingsDlg.cpp similarity index 100% rename from source/sced/ui/LightSettingsDlg.cpp rename to source/tools/sced/ui/LightSettingsDlg.cpp diff --git a/source/sced/ui/LightSettingsDlg.h b/source/tools/sced/ui/LightSettingsDlg.h similarity index 100% rename from source/sced/ui/LightSettingsDlg.h rename to source/tools/sced/ui/LightSettingsDlg.h diff --git a/source/sced/ui/MainFrameDlgBar.cpp b/source/tools/sced/ui/MainFrameDlgBar.cpp similarity index 100% rename from source/sced/ui/MainFrameDlgBar.cpp rename to source/tools/sced/ui/MainFrameDlgBar.cpp diff --git a/source/sced/ui/MainFrameDlgBar.h b/source/tools/sced/ui/MainFrameDlgBar.h similarity index 100% rename from source/sced/ui/MainFrameDlgBar.h rename to source/tools/sced/ui/MainFrameDlgBar.h diff --git a/source/sced/ui/MainFrm.cpp b/source/tools/sced/ui/MainFrm.cpp similarity index 100% rename from source/sced/ui/MainFrm.cpp rename to source/tools/sced/ui/MainFrm.cpp diff --git a/source/sced/ui/MainFrm.h b/source/tools/sced/ui/MainFrm.h similarity index 100% rename from source/sced/ui/MainFrm.h rename to source/tools/sced/ui/MainFrm.h diff --git a/source/sced/ui/MapSizeDlg.cpp b/source/tools/sced/ui/MapSizeDlg.cpp similarity index 100% rename from source/sced/ui/MapSizeDlg.cpp rename to source/tools/sced/ui/MapSizeDlg.cpp diff --git a/source/sced/ui/MapSizeDlg.h b/source/tools/sced/ui/MapSizeDlg.h similarity index 100% rename from source/sced/ui/MapSizeDlg.h rename to source/tools/sced/ui/MapSizeDlg.h diff --git a/source/sced/ui/NavigatePropPage.cpp b/source/tools/sced/ui/NavigatePropPage.cpp similarity index 100% rename from source/sced/ui/NavigatePropPage.cpp rename to source/tools/sced/ui/NavigatePropPage.cpp diff --git a/source/sced/ui/NavigatePropPage.h b/source/tools/sced/ui/NavigatePropPage.h similarity index 100% rename from source/sced/ui/NavigatePropPage.h rename to source/tools/sced/ui/NavigatePropPage.h diff --git a/source/sced/ui/OptionsDlg.cpp b/source/tools/sced/ui/OptionsDlg.cpp similarity index 100% rename from source/sced/ui/OptionsDlg.cpp rename to source/tools/sced/ui/OptionsDlg.cpp diff --git a/source/sced/ui/OptionsDlg.h b/source/tools/sced/ui/OptionsDlg.h similarity index 100% rename from source/sced/ui/OptionsDlg.h rename to source/tools/sced/ui/OptionsDlg.h diff --git a/source/sced/ui/OptionsPropSheet.cpp b/source/tools/sced/ui/OptionsPropSheet.cpp similarity index 100% rename from source/sced/ui/OptionsPropSheet.cpp rename to source/tools/sced/ui/OptionsPropSheet.cpp diff --git a/source/sced/ui/OptionsPropSheet.h b/source/tools/sced/ui/OptionsPropSheet.h similarity index 100% rename from source/sced/ui/OptionsPropSheet.h rename to source/tools/sced/ui/OptionsPropSheet.h diff --git a/source/sced/ui/ScEd.cpp b/source/tools/sced/ui/ScEd.cpp similarity index 100% rename from source/sced/ui/ScEd.cpp rename to source/tools/sced/ui/ScEd.cpp diff --git a/source/sced/ui/ScEd.h b/source/tools/sced/ui/ScEd.h similarity index 100% rename from source/sced/ui/ScEd.h rename to source/tools/sced/ui/ScEd.h diff --git a/source/sced/ui/ScEd.rc b/source/tools/sced/ui/ScEd.rc similarity index 100% rename from source/sced/ui/ScEd.rc rename to source/tools/sced/ui/ScEd.rc diff --git a/source/sced/ui/ScEdDoc.cpp b/source/tools/sced/ui/ScEdDoc.cpp similarity index 100% rename from source/sced/ui/ScEdDoc.cpp rename to source/tools/sced/ui/ScEdDoc.cpp diff --git a/source/sced/ui/ScEdDoc.h b/source/tools/sced/ui/ScEdDoc.h similarity index 100% rename from source/sced/ui/ScEdDoc.h rename to source/tools/sced/ui/ScEdDoc.h diff --git a/source/sced/ui/ScEdView.cpp b/source/tools/sced/ui/ScEdView.cpp similarity index 100% rename from source/sced/ui/ScEdView.cpp rename to source/tools/sced/ui/ScEdView.cpp diff --git a/source/sced/ui/ScEdView.h b/source/tools/sced/ui/ScEdView.h similarity index 100% rename from source/sced/ui/ScEdView.h rename to source/tools/sced/ui/ScEdView.h diff --git a/source/sced/ui/ShadowsPropPage.cpp b/source/tools/sced/ui/ShadowsPropPage.cpp similarity index 100% rename from source/sced/ui/ShadowsPropPage.cpp rename to source/tools/sced/ui/ShadowsPropPage.cpp diff --git a/source/sced/ui/ShadowsPropPage.h b/source/tools/sced/ui/ShadowsPropPage.h similarity index 100% rename from source/sced/ui/ShadowsPropPage.h rename to source/tools/sced/ui/ShadowsPropPage.h diff --git a/source/sced/ui/SimpleEdit.cpp b/source/tools/sced/ui/SimpleEdit.cpp similarity index 100% rename from source/sced/ui/SimpleEdit.cpp rename to source/tools/sced/ui/SimpleEdit.cpp diff --git a/source/sced/ui/SimpleEdit.h b/source/tools/sced/ui/SimpleEdit.h similarity index 100% rename from source/sced/ui/SimpleEdit.h rename to source/tools/sced/ui/SimpleEdit.h diff --git a/source/sced/ui/StdAfx.h b/source/tools/sced/ui/StdAfx.h similarity index 100% rename from source/sced/ui/StdAfx.h rename to source/tools/sced/ui/StdAfx.h diff --git a/source/sced/ui/TexToolsDlgBar.cpp b/source/tools/sced/ui/TexToolsDlgBar.cpp similarity index 100% rename from source/sced/ui/TexToolsDlgBar.cpp rename to source/tools/sced/ui/TexToolsDlgBar.cpp diff --git a/source/sced/ui/TexToolsDlgBar.h b/source/tools/sced/ui/TexToolsDlgBar.h similarity index 100% rename from source/sced/ui/TexToolsDlgBar.h rename to source/tools/sced/ui/TexToolsDlgBar.h diff --git a/source/sced/ui/UIGlobals.cpp b/source/tools/sced/ui/UIGlobals.cpp similarity index 100% rename from source/sced/ui/UIGlobals.cpp rename to source/tools/sced/ui/UIGlobals.cpp diff --git a/source/sced/ui/UIGlobals.h b/source/tools/sced/ui/UIGlobals.h similarity index 100% rename from source/sced/ui/UIGlobals.h rename to source/tools/sced/ui/UIGlobals.h diff --git a/source/sced/ui/UnitPropertiesAnimationsTab.cpp b/source/tools/sced/ui/UnitPropertiesAnimationsTab.cpp similarity index 100% rename from source/sced/ui/UnitPropertiesAnimationsTab.cpp rename to source/tools/sced/ui/UnitPropertiesAnimationsTab.cpp diff --git a/source/sced/ui/UnitPropertiesAnimationsTab.h b/source/tools/sced/ui/UnitPropertiesAnimationsTab.h similarity index 100% rename from source/sced/ui/UnitPropertiesAnimationsTab.h rename to source/tools/sced/ui/UnitPropertiesAnimationsTab.h diff --git a/source/sced/ui/UnitPropertiesDlgBar.cpp b/source/tools/sced/ui/UnitPropertiesDlgBar.cpp similarity index 100% rename from source/sced/ui/UnitPropertiesDlgBar.cpp rename to source/tools/sced/ui/UnitPropertiesDlgBar.cpp diff --git a/source/sced/ui/UnitPropertiesDlgBar.h b/source/tools/sced/ui/UnitPropertiesDlgBar.h similarity index 100% rename from source/sced/ui/UnitPropertiesDlgBar.h rename to source/tools/sced/ui/UnitPropertiesDlgBar.h diff --git a/source/sced/ui/UnitPropertiesTabCtrl.cpp b/source/tools/sced/ui/UnitPropertiesTabCtrl.cpp similarity index 100% rename from source/sced/ui/UnitPropertiesTabCtrl.cpp rename to source/tools/sced/ui/UnitPropertiesTabCtrl.cpp diff --git a/source/sced/ui/UnitPropertiesTabCtrl.h b/source/tools/sced/ui/UnitPropertiesTabCtrl.h similarity index 100% rename from source/sced/ui/UnitPropertiesTabCtrl.h rename to source/tools/sced/ui/UnitPropertiesTabCtrl.h diff --git a/source/sced/ui/UnitPropertiesTexturesTab.cpp b/source/tools/sced/ui/UnitPropertiesTexturesTab.cpp similarity index 100% rename from source/sced/ui/UnitPropertiesTexturesTab.cpp rename to source/tools/sced/ui/UnitPropertiesTexturesTab.cpp diff --git a/source/sced/ui/UnitPropertiesTexturesTab.h b/source/tools/sced/ui/UnitPropertiesTexturesTab.h similarity index 100% rename from source/sced/ui/UnitPropertiesTexturesTab.h rename to source/tools/sced/ui/UnitPropertiesTexturesTab.h diff --git a/source/sced/ui/UnitToolsDlgBar.cpp b/source/tools/sced/ui/UnitToolsDlgBar.cpp similarity index 100% rename from source/sced/ui/UnitToolsDlgBar.cpp rename to source/tools/sced/ui/UnitToolsDlgBar.cpp diff --git a/source/sced/ui/UnitToolsDlgBar.h b/source/tools/sced/ui/UnitToolsDlgBar.h similarity index 100% rename from source/sced/ui/UnitToolsDlgBar.h rename to source/tools/sced/ui/UnitToolsDlgBar.h diff --git a/source/sced/ui/WebLinkButton.cpp b/source/tools/sced/ui/WebLinkButton.cpp similarity index 100% rename from source/sced/ui/WebLinkButton.cpp rename to source/tools/sced/ui/WebLinkButton.cpp diff --git a/source/sced/ui/WebLinkButton.h b/source/tools/sced/ui/WebLinkButton.h similarity index 100% rename from source/sced/ui/WebLinkButton.h rename to source/tools/sced/ui/WebLinkButton.h diff --git a/source/sced/ui/resource.h b/source/tools/sced/ui/resource.h similarity index 100% rename from source/sced/ui/resource.h rename to source/tools/sced/ui/resource.h diff --git a/source/workspaces/premake/functions.lua b/source/workspaces/premake/functions.lua deleted file mode 100755 index 912c4f5039..0000000000 --- a/source/workspaces/premake/functions.lua +++ /dev/null @@ -1,7 +0,0 @@ -function sourcesfromdirs(...) - local res = {} - for i=1, getn(arg) do - res[i]=matchfiles(arg[i].."/*.cpp", arg[i].."/*.h") - end - return res -end \ No newline at end of file