Restructuring

This was SVN commit r1453.
This commit is contained in:
Ykkrosh 2004-12-05 17:59:29 +00:00
parent 0d270c968c
commit ec3452679c
204 changed files with 17116 additions and 46 deletions

BIN
build/bin/perl58.dll Normal file

Binary file not shown.

Binary file not shown.

View File

@ -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;
}

BIN
build/linefix/linefix.exe Normal file

Binary file not shown.

7
build/premake/functions.lua Executable file
View File

@ -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

View File

@ -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/<libraryname>/lib' and '/include' to the includepaths and libpaths
-- Add '<libraries root>/<libraryname>/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 = {

View File

@ -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.

View File

@ -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.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 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.
<signature of Ty Coon>, 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.

View File

@ -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

View File

@ -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

View File

@ -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>
{{{
}}}
###############################################################################

View File

@ -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)

View File

@ -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

View File

@ -0,0 +1,314 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="Premake"
ProjectGUID="{D240CFA2-A134-D147-8EF3-30B485E4E25F}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".."
IntermediateDirectory="obj\Debug\"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
IgnoreImportLibrary="TRUE"
AdditionalOptions=""
AdditionalDependencies=""
OutputFile="$(OutDir)\premake.exe"
LinkIncremental="2"
AdditionalLibraryDirectories=".\"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="obj\Debug\premake.pdb"
SubSystem="1"
EntryPointSymbol="mainCRTStartup"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\"
IntermediateDirectory="obj\Release\"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="1"
InlineFunctionExpansion="1"
OmitFramePointers="TRUE"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
StringPooling="TRUE"
MinimalRebuild="FALSE"
BasicRuntimeChecks="0"
RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE"
RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
IgnoreImportLibrary="TRUE"
AdditionalOptions=""
AdditionalDependencies=""
OutputFile="$(OutDir)\premake.exe"
LinkIncremental="1"
AdditionalLibraryDirectories=".\"
GenerateDebugInformation="FALSE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
EntryPointSymbol="mainCRTStartup"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Src"
Filter="">
<File
RelativePath="Src\clean.c">
</File>
<File
RelativePath="Src\gnu.c">
</File>
<File
RelativePath="Src\premake.c">
</File>
<File
RelativePath="Src\project.c">
</File>
<File
RelativePath="Src\project.h">
</File>
<File
RelativePath="Src\sharpdev.c">
</File>
<File
RelativePath="Src\util.c">
</File>
<File
RelativePath="Src\util.h">
</File>
<File
RelativePath="Src\vs6.c">
</File>
<File
RelativePath="Src\vs7.c">
</File>
<File
RelativePath="Src\windows.c">
</File>
<Filter
Name="Lua"
Filter="">
<File
RelativePath="Src\Lua\lapi.c">
</File>
<File
RelativePath="Src\Lua\lapi.h">
</File>
<File
RelativePath="Src\Lua\lauxlib.c">
</File>
<File
RelativePath="Src\Lua\lauxlib.h">
</File>
<File
RelativePath="Src\Lua\lbaselib.c">
</File>
<File
RelativePath="Src\Lua\lcode.c">
</File>
<File
RelativePath="Src\Lua\lcode.h">
</File>
<File
RelativePath="Src\Lua\ldebug.c">
</File>
<File
RelativePath="Src\Lua\ldebug.h">
</File>
<File
RelativePath="Src\Lua\ldo.c">
</File>
<File
RelativePath="Src\Lua\ldo.h">
</File>
<File
RelativePath="Src\Lua\lfunc.c">
</File>
<File
RelativePath="Src\Lua\lfunc.h">
</File>
<File
RelativePath="Src\Lua\lgc.c">
</File>
<File
RelativePath="Src\Lua\lgc.h">
</File>
<File
RelativePath="Src\Lua\liolib.c">
</File>
<File
RelativePath="Src\Lua\llex.c">
</File>
<File
RelativePath="Src\Lua\llex.h">
</File>
<File
RelativePath="Src\Lua\llimits.h">
</File>
<File
RelativePath="Src\Lua\lmathlib.c">
</File>
<File
RelativePath="Src\Lua\lmem.c">
</File>
<File
RelativePath="Src\Lua\lmem.h">
</File>
<File
RelativePath="Src\Lua\lobject.c">
</File>
<File
RelativePath="Src\Lua\lobject.h">
</File>
<File
RelativePath="Src\Lua\lopcodes.h">
</File>
<File
RelativePath="Src\Lua\lparser.c">
</File>
<File
RelativePath="Src\Lua\lparser.h">
</File>
<File
RelativePath="Src\Lua\lstate.c">
</File>
<File
RelativePath="Src\Lua\lstate.h">
</File>
<File
RelativePath="Src\Lua\lstring.c">
</File>
<File
RelativePath="Src\Lua\lstring.h">
</File>
<File
RelativePath="Src\Lua\lstrlib.c">
</File>
<File
RelativePath="Src\Lua\ltable.c">
</File>
<File
RelativePath="Src\Lua\ltable.h">
</File>
<File
RelativePath="Src\Lua\ltests.c">
</File>
<File
RelativePath="Src\Lua\ltm.c">
</File>
<File
RelativePath="Src\Lua\ltm.h">
</File>
<File
RelativePath="Src\Lua\lua.h">
</File>
<File
RelativePath="Src\Lua\luadebug.h">
</File>
<File
RelativePath="Src\Lua\lualib.h">
</File>
<File
RelativePath="Src\Lua\lundump.c">
</File>
<File
RelativePath="Src\Lua\lundump.h">
</File>
<File
RelativePath="Src\Lua\lvm.c">
</File>
<File
RelativePath="Src\Lua\lvm.h">
</File>
<File
RelativePath="Src\Lua\lzio.c">
</File>
<File
RelativePath="Src\Lua\lzio.h">
</File>
</Filter>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -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/

View File

@ -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)

View File

@ -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)

View File

@ -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 <string.h>
#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;
}

View File

@ -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

View File

@ -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 <stdarg.h>
#include <stdio.h>
#include <string.h>
/* 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; i<n; i++)
lua_register(L, l[i].name, l[i].func);
}
LUALIB_API void luaL_verror (lua_State *L, const char *fmt, ...) {
char buff[500];
va_list argp;
va_start(argp, fmt);
vsprintf(buff, fmt, argp);
va_end(argp);
lua_error(L, buff);
}
/*
** {======================================================
** Generic Buffer manipulation
** =======================================================
*/
#define buffempty(B) ((B)->p == (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;
}
/* }====================================================== */

View File

@ -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 <stddef.h>
#include <stdio.h>
#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

View File

@ -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 <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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<n; i++) /* push arg[1...n] */
lua_rawgeti(L, 2, i+1);
status = lua_call(L, n, LUA_MULTRET);
if (err != 0) { /* restore old error method */
lua_pushvalue(L, err);
lua_setglobal(L, LUA_ERRORMESSAGE);
}
if (status != 0) { /* error in call? */
if (strchr(options, 'x'))
lua_pushnil(L); /* return nil to signal the error */
else
lua_error(L, NULL); /* propagate error without additional messages */
return 1;
}
if (strchr(options, 'p')) /* pack results? */
lua_error(L, "deprecated option `p' in `call'");
return lua_gettop(L) - oldtop; /* results are already on the stack */
}
static int luaB_tostring (lua_State *L) {
char buff[64];
switch (lua_type(L, 1)) {
case LUA_TNUMBER:
lua_pushstring(L, lua_tostring(L, 1));
return 1;
case LUA_TSTRING:
lua_pushvalue(L, 1);
return 1;
case LUA_TTABLE:
sprintf(buff, "table: %p", lua_topointer(L, 1));
break;
case LUA_TFUNCTION:
sprintf(buff, "function: %p", lua_topointer(L, 1));
break;
case LUA_TUSERDATA:
sprintf(buff, "userdata(%d): %p", lua_tag(L, 1), lua_touserdata(L, 1));
break;
case LUA_TNIL:
lua_pushstring(L, "nil");
return 1;
default:
luaL_argerror(L, 1, "value expected");
}
lua_pushstring(L, buff);
return 1;
}
static int luaB_foreachi (lua_State *L) {
int n, i;
luaL_checktype(L, 1, LUA_TTABLE);
luaL_checktype(L, 2, LUA_TFUNCTION);
n = lua_getn(L, 1);
for (i=1; i<=n; i++) {
lua_pushvalue(L, 2); /* function */
lua_pushnumber(L, i); /* 1st argument */
lua_rawgeti(L, 1, i); /* 2nd argument */
lua_rawcall(L, 2, 1);
if (!lua_isnil(L, -1))
return 1;
lua_pop(L, 1); /* remove nil result */
}
return 0;
}
static int luaB_foreach (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
luaL_checktype(L, 2, LUA_TFUNCTION);
lua_pushnil(L); /* first index */
for (;;) {
if (lua_next(L, 1) == 0)
return 0;
lua_pushvalue(L, 2); /* function */
lua_pushvalue(L, -3); /* key */
lua_pushvalue(L, -3); /* value */
lua_rawcall(L, 2, 1);
if (!lua_isnil(L, -1))
return 1;
lua_pop(L, 2); /* remove value and result */
}
}
static int luaB_assert (lua_State *L) {
luaL_checkany(L, 1);
if (lua_isnil(L, 1))
luaL_verror(L, "assertion failed! %.90s", luaL_opt_string(L, 2, ""));
return 0;
}
static int luaB_getn (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
lua_pushnumber(L, lua_getn(L, 1));
return 1;
}
static int luaB_tinsert (lua_State *L) {
int v = lua_gettop(L); /* last argument: to be inserted */
int n, pos;
luaL_checktype(L, 1, LUA_TTABLE);
n = lua_getn(L, 1);
if (v == 2) /* called with only 2 arguments */
pos = n+1;
else
pos = luaL_check_int(L, 2); /* 2nd argument is the position */
lua_pushstring(L, "n");
lua_pushnumber(L, n+1);
lua_rawset(L, 1); /* t.n = n+1 */
for (; n>=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<n; pos++) {
lua_rawgeti(L, 1, pos+1);
lua_rawseti(L, 1, pos); /* a[pos] = a[pos+1] */
}
lua_pushstring(L, "n");
lua_pushnumber(L, n-1);
lua_rawset(L, 1); /* t.n = n-1 */
lua_pushnil(L);
lua_rawseti(L, 1, n); /* t[n] = nil */
return 1;
}
/*
** {======================================================
** Quicksort
** (based on `Algorithms in MODULA-3', Robert Sedgewick;
** Addison-Wesley, 1993.)
*/
static void set2 (lua_State *L, int i, int j) {
lua_rawseti(L, 1, i);
lua_rawseti(L, 1, j);
}
static int sort_comp (lua_State *L, int a, int b) {
/* WARNING: the caller (auxsort) must ensure stack space */
if (!lua_isnil(L, 2)) { /* function? */
int res;
lua_pushvalue(L, 2);
lua_pushvalue(L, a-1); /* -1 to compensate function */
lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */
lua_rawcall(L, 2, 1);
res = !lua_isnil(L, -1);
lua_pop(L, 1);
return res;
}
else /* a < b? */
return lua_lessthan(L, a, b);
}
static void auxsort (lua_State *L, int l, int u) {
while (l < u) { /* for tail recursion */
int i, j;
/* sort elements a[l], a[(l+u)/2] and a[u] */
lua_rawgeti(L, 1, l);
lua_rawgeti(L, 1, u);
if (sort_comp(L, -1, -2)) /* a[u] < a[l]? */
set2(L, l, u); /* swap a[l] - a[u] */
else
lua_pop(L, 2);
if (u-l == 1) break; /* only 2 elements */
i = (l+u)/2;
lua_rawgeti(L, 1, i);
lua_rawgeti(L, 1, l);
if (sort_comp(L, -2, -1)) /* a[i]<a[l]? */
set2(L, i, l);
else {
lua_pop(L, 1); /* remove a[l] */
lua_rawgeti(L, 1, u);
if (sort_comp(L, -1, -2)) /* a[u]<a[i]? */
set2(L, i, u);
else
lua_pop(L, 2);
}
if (u-l == 2) break; /* only 3 elements */
lua_rawgeti(L, 1, i); /* Pivot */
lua_pushvalue(L, -1);
lua_rawgeti(L, 1, u-1);
set2(L, i, u-1);
/* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */
i = l; j = u-1;
for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */
/* repeat ++i until a[i] >= 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 (j<l) lua_error(L, "invalid order function for sorting");
lua_pop(L, 1); /* remove a[j] */
}
if (j<i) {
lua_pop(L, 3); /* pop pivot, a[i], a[j] */
break;
}
set2(L, i, j);
}
lua_rawgeti(L, 1, u-1);
lua_rawgeti(L, 1, i);
set2(L, u-1, i); /* swap pivot (a[u-1]) with a[i] */
/* a[l..i-1] <= a[i] == P <= a[i+1..u] */
/* adjust so that smaller "half" is in [j..i] and larger one in [l..u] */
if (i-l < u-i) {
j=l; i=i-1; l=i+2;
}
else {
j=i+1; i=u; u=j-2;
}
auxsort(L, j, i); /* call recursively the smaller one */
} /* repeat the routine for the larger one */
}
static int luaB_sort (lua_State *L) {
int n;
luaL_checktype(L, 1, LUA_TTABLE);
n = lua_getn(L, 1);
if (!lua_isnull(L, 2)) /* is there a 2nd argument? */
luaL_checktype(L, 2, LUA_TFUNCTION);
lua_settop(L, 2); /* make sure there is two arguments */
auxsort(L, 1, n);
return 0;
}
/* }====================================================== */
/*
** {======================================================
** Deprecated functions to manipulate global environment.
** =======================================================
*/
#define num_deprecated 4
static const struct luaL_reg deprecated_names [num_deprecated] = {
{"foreachvar", luaB_foreach},
{"nextvar", luaB_next},
{"rawgetglobal", luaB_rawget},
{"rawsetglobal", luaB_rawset}
};
#ifdef LUA_DEPRECATEDFUNCS
/*
** call corresponding function inserting `globals' as first argument
*/
static int deprecated_func (lua_State *L) {
lua_insert(L, 1); /* upvalue is the function to be called */
lua_getglobals(L);
lua_insert(L, 2); /* table of globals is 1o argument */
lua_rawcall(L, lua_gettop(L)-1, LUA_MULTRET);
return lua_gettop(L); /* return all results */
}
static void deprecated_funcs (lua_State *L) {
int i;
for (i=0; i<num_deprecated; i++) {
lua_pushcfunction(L, deprecated_names[i].func);
lua_pushcclosure(L, deprecated_func, 1);
lua_setglobal(L, deprecated_names[i].name);
}
}
#else
/*
** gives an explicit error in any attempt to call a deprecated function
*/
static int deprecated_func (lua_State *L) {
luaL_verror(L, "function `%.20s' is deprecated", lua_tostring(L, -1));
return 0; /* to avoid warnings */
}
static void deprecated_funcs (lua_State *L) {
int i;
for (i=0; i<num_deprecated; i++) {
lua_pushstring(L, deprecated_names[i].name);
lua_pushcclosure(L, deprecated_func, 1);
lua_setglobal(L, deprecated_names[i].name);
}
}
#endif
/* }====================================================== */
static const struct luaL_reg base_funcs[] = {
{LUA_ALERT, luaB__ALERT},
{LUA_ERRORMESSAGE, luaB__ERRORMESSAGE},
{"call", luaB_call},
{"collectgarbage", luaB_collectgarbage},
{"copytagmethods", luaB_copytagmethods},
{"dofile", luaB_dofile},
{"dostring", luaB_dostring},
{"error", luaB_error},
{"foreach", luaB_foreach},
{"foreachi", luaB_foreachi},
{"gcinfo", luaB_gcinfo},
{"getglobal", luaB_getglobal},
{"gettagmethod", luaB_gettagmethod},
{"globals", luaB_globals},
{"newtag", luaB_newtag},
{"next", luaB_next},
{"print", luaB_print},
{"rawget", luaB_rawget},
{"rawset", luaB_rawset},
{"rawgettable", luaB_rawget}, /* for compatibility */
{"rawsettable", luaB_rawset}, /* for compatibility */
{"setglobal", luaB_setglobal},
{"settag", luaB_settag},
{"settagmethod", luaB_settagmethod},
{"tag", luaB_tag},
{"tonumber", luaB_tonumber},
{"tostring", luaB_tostring},
{"type", luaB_type},
{"assert", luaB_assert},
{"getn", luaB_getn},
{"sort", luaB_sort},
{"tinsert", luaB_tinsert},
{"tremove", luaB_tremove}
};
LUALIB_API void lua_baselibopen (lua_State *L) {
luaL_openl(L, base_funcs);
lua_pushstring(L, LUA_VERSION);
lua_setglobal(L, "_VERSION");
deprecated_funcs(L);
}

View File

@ -0,0 +1,701 @@
/*
** $Id: lcode.c,v 1.1 2003/01/24 16:26:00 jason379 Exp $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
#include "stdlib.h"
#include "lua.h"
#include "lcode.h"
#include "ldo.h"
#include "llex.h"
#include "lmem.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lparser.h"
void luaK_error (LexState *ls, const char *msg) {
luaX_error(ls, msg, ls->t.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 */
};

View File

@ -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

View File

@ -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 <stdlib.h>
#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; e<TM_N; e++) {
int t;
for (t=0; t<=L->last_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; i<g->size; 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);
}

View File

@ -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

View File

@ -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 <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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; n<nup; n++) /* copy upvalues as extra arguments */
*(L->top++) = 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;
}
/* }====================================================== */

View File

@ -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

View File

@ -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 <stdlib.h>
#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; i<f->nlocvars && 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 */
}

View File

@ -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

View File

@ -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; i<f->nkstr; i++)
strmark(f->kstr[i]);
for (i=0; i<f->nkproto; i++)
protomark(f->kproto[i]);
for (i=0; i<f->nlocvars; i++) /* mark local-variable names */
strmark(f->locvars[i].varname);
}
}
static void markstack (lua_State *L, GCState *st) {
StkId o;
for (o=L->stack; o<L->top; o++)
markobject(st, o);
}
static void marklock (lua_State *L, GCState *st) {
int i;
for (i=0; i<L->refSize; 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; e<TM_N; e++) {
int t;
for (t=0; t<=L->last_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; i<f->nupvalues; 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; i<h->size; 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; i<n; i++) {
struct Ref *r = &L->refArray[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; i<L->strt.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; i<L->udt.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);
}

View File

@ -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

View File

@ -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 <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "lua.h"
#include "lauxlib.h"
#include "luadebug.h"
#include "lualib.h"
#ifndef OLD_ANSI
#include <errno.h>
#include <locale.h>
#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; i<sizeof(iolibtag)/sizeof(iolibtag[0]); i++) {
/* put `ctrl' as upvalue for these functions */
lua_pushvalue(L, -1);
lua_pushcclosure(L, iolibtag[i].func, 1);
lua_setglobal(L, iolibtag[i].name);
}
/* create references to variable names */
lua_pushstring(L, filenames[INFILE]);
ctrl->ref[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);
}

View File

@ -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 <ctype.h>
#include <stdio.h>
#include <string.h>
#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", "", "..", "...", "==", ">=", "<=", "~=", "", "", "<eof>"};
void luaX_init (lua_State *L) {
int i;
for (i=0; i<NUM_RESERVED; i++) {
TString *ts = luaS_new(L, token2string[i]);
ts->marked = (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;
}
}
}
}

View File

@ -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

View File

@ -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 <limits.h>
#include <stddef.h>
/*
** 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<<SIZE_U)-1)
#define MAXARG_S (MAXARG_U>>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<<SIZE_A)-1)
#else
#define MAXARG_A MAX_INT
#endif
#if SIZE_B < BITS_INT-1
#define MAXARG_B ((1<<SIZE_B)-1)
#else
#define MAXARG_B MAX_INT
#endif
/* maximum stack size in a function */
#ifndef MAXSTACK
#define MAXSTACK 250
#endif
#if MAXSTACK > MAXARG_B
#undef MAXSTACK
#define MAXSTACK MAXARG_B
#endif
/* maximum number of local variables */
#ifndef MAXLOCALS
#define MAXLOCALS 200 /* arbitrary limit (<MAXSTACK) */
#endif
#if MAXLOCALS>=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) */
#endif
#if MAXVARSLH>=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) */
#endif
#if MAXPARAMS>=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

View File

@ -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 <stdlib.h>
#include <math.h>
#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");
}

View File

@ -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 <stdlib.h>
#include "lua.h"
#include "ldo.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
#ifdef LUA_DEBUG
/*
** {======================================================================
** Controlled version for realloc.
** =======================================================================
*/
#include <assert.h>
#include <limits.h>
#include <string.h>
#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<MARKSIZE;i++)
assert(*(((char *)b)+HEADER+size+i) == MARK+i); /* corrupted block? */
memdebug_numblocks--;
memdebug_total -= size;
return b;
}
static void freeblock (void *block) {
if (block) {
size_t size = *blocksize(block);
block = checkblock(block);
memset(block, -1, size+HEADER+MARKSIZE); /* erase block */
(free)(block); /* free original block */
}
}
static void *debug_realloc (void *block, size_t size) {
if (size == 0) {
freeblock(block);
return NULL;
}
else if (memdebug_total+size > 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<MARKSIZE;i++)
*(newblock+HEADER+size+i) = (char)(MARK+i);
return newblock+HEADER;
}
}
/* }====================================================================== */
#endif
/*
** Real ISO (ANSI) systems do not need these tests;
** but some systems (Sun OS) are not that ISO...
*/
#ifdef OLD_ANSI
#define realloc(b,s) ((b) == NULL ? malloc(s) : (realloc)(b, s))
#define free(b) if (b) (free)(b)
#endif
void *luaM_growaux (lua_State *L, void *block, size_t nelems,
int inc, size_t size, const char *errormsg, size_t limit) {
size_t newn = nelems+inc;
if (nelems >= 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;
}

View File

@ -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 <stddef.h>
#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

View File

@ -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 <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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);
}
}
}

View File

@ -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 <assert.h>
#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

View File

@ -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)<<n))<<p)
/* creates a mask with `n' 0 bits at position `p' */
#define MASK0(n,p) (~MASK1(n,p))
/*
** the following macros help to manipulate instructions
*/
#define CREATE_0(o) ((Instruction)(o))
#define GET_OPCODE(i) ((OpCode)((i)&MASK1(SIZE_OP,0)))
#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,0)) | (Instruction)(o)))
#define CREATE_U(o,u) ((Instruction)(o) | ((Instruction)(u)<<POS_U))
#define GETARG_U(i) ((int)((i)>>POS_U))
#define SETARG_U(i,u) ((i) = (((i)&MASK0(SIZE_U,POS_U)) | \
((Instruction)(u)<<POS_U)))
#define CREATE_S(o,s) CREATE_U((o),(s)+MAXARG_S)
#define GETARG_S(i) (GETARG_U(i)-MAXARG_S)
#define SETARG_S(i,s) SETARG_U((i),(s)+MAXARG_S)
#define CREATE_AB(o,a,b) ((Instruction)(o) | ((Instruction)(a)<<POS_A) \
| ((Instruction)(b)<<POS_B))
#define GETARG_A(i) ((int)((i)>>POS_A))
#define SETARG_A(i,a) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \
((Instruction)(a)<<POS_A)))
#define GETARG_B(i) ((int)(((i)>>POS_B) & MASK1(SIZE_B,0)))
#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \
((Instruction)(b)<<POS_B)))
/*
** K = U argument used as index to `kstr'
** J = S argument used as jump offset (relative to pc of next instruction)
** L = unsigned argument used as index of local variable
** N = U argument used as index to `knum'
*/
typedef enum {
/*----------------------------------------------------------------------
name args stack before stack after side effects
------------------------------------------------------------------------*/
OP_END,/* - - (return) no results */
OP_RETURN,/* U v_n-v_x(at u) (return) returns v_x-v_n */
OP_CALL,/* A B v_n-v_1 f(at a) r_b-r_1 f(v1,...,v_n) */
OP_TAILCALL,/* A B v_n-v_1 f(at a) (return) f(v1,...,v_n) */
OP_PUSHNIL,/* U - nil_1-nil_u */
OP_POP,/* U a_u-a_1 - */
OP_PUSHINT,/* S - (Number)s */
OP_PUSHSTRING,/* K - KSTR[k] */
OP_PUSHNUM,/* N - KNUM[n] */
OP_PUSHNEGNUM,/* N - -KNUM[n] */
OP_PUSHUPVALUE,/* U - Closure[u] */
OP_GETLOCAL,/* L - LOC[l] */
OP_GETGLOBAL,/* K - VAR[KSTR[k]] */
OP_GETTABLE,/* - i t t[i] */
OP_GETDOTTED,/* K t t[KSTR[k]] */
OP_GETINDEXED,/* L t t[LOC[l]] */
OP_PUSHSELF,/* K t t t[KSTR[k]] */
OP_CREATETABLE,/* U - newarray(size = u) */
OP_SETLOCAL,/* L x - LOC[l]=x */
OP_SETGLOBAL,/* K x - VAR[KSTR[k]]=x */
OP_SETTABLE,/* A B v a_a-a_1 i t (pops b values) t[i]=v */
OP_SETLIST,/* A B v_b-v_1 t t t[i+a*FPF]=v_i */
OP_SETMAP,/* U v_u k_u - v_1 k_1 t t t[k_i]=v_i */
OP_ADD,/* - y x x+y */
OP_ADDI,/* S x x+s */
OP_SUB,/* - y x x-y */
OP_MULT,/* - y x x*y */
OP_DIV,/* - y x x/y */
OP_POW,/* - y x x^y */
OP_CONCAT,/* U v_u-v_1 v1..-..v_u */
OP_MINUS,/* - x -x */
OP_NOT,/* - x (x==nil)? 1 : nil */
OP_JMPNE,/* J y x - (x~=y)? PC+=s */
OP_JMPEQ,/* J y x - (x==y)? PC+=s */
OP_JMPLT,/* J y x - (x<y)? PC+=s */
OP_JMPLE,/* J y x - (x<y)? PC+=s */
OP_JMPGT,/* J y x - (x>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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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 <stdio.h>
#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!");
}

View File

@ -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

View File

@ -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 <string.h>
#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; i<newsize; i++) newhash[i] = NULL;
/* rehash */
for (i=0; i<tb->size; 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;
}

View File

@ -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

View File

@ -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 <ctype.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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<l; i++)
luaL_putchar(&b, tolower((unsigned char)(s[i])));
luaL_pushresult(&b);
return 1;
}
static int str_upper (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<l; i++)
luaL_putchar(&b, toupper((unsigned char)(s[i])));
luaL_pushresult(&b);
return 1;
}
static int str_rep (lua_State *L) {
size_t l;
luaL_Buffer b;
const char *s = luaL_check_lstr(L, 1, &l);
int n = luaL_check_int(L, 2);
luaL_buffinit(L, &b);
while (n-- > 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, 0<pos && (size_t)pos<=l, 2, "out of range");
lua_pushnumber(L, (unsigned char)s[pos-1]);
return 1;
}
static int str_char (lua_State *L) {
int n = lua_gettop(L); /* number of arguments */
int i;
luaL_Buffer b;
luaL_buffinit(L, &b);
for (i=1; i<=n; i++) {
int c = luaL_check_int(L, i);
luaL_arg_check(L, (unsigned char)c == c, i, "invalid value");
luaL_putchar(&b, (unsigned char)c);
}
luaL_pushresult(&b);
return 1;
}
/*
** {======================================================
** PATTERN MATCHING
** =======================================================
*/
#ifndef MAX_CAPTURES
#define MAX_CAPTURES 32 /* arbitrary limit */
#endif
struct Capture {
const char *src_end; /* end ('\0') of source string */
int level; /* total number of captures (finished or unfinished) */
struct {
const char *init;
long len; /* -1 signals unfinished capture */
} capture[MAX_CAPTURES];
};
#define ESC '%'
#define SPECIALS "^$*+?.([%-"
static int check_capture (lua_State *L, int l, struct Capture *cap) {
l -= '1';
if (!(0 <= l && l < cap->level && 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)<cap->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 (s<cap->src_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 = s<cap->src_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; i<cap->level; 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++<cap.src_end && !anchor);
}
lua_pushnil(L); /* not found */
return 1;
}
static void add_s (lua_State *L, luaL_Buffer *b, struct Capture *cap) {
if (lua_isstring(L, 3)) {
const char *news = lua_tostring(L, 3);
size_t l = lua_strlen(L, 3);
size_t i;
for (i=0; i<l; i++) {
if (news[i] != ESC)
luaL_putchar(b, news[i]);
else {
i++; /* skip ESC */
if (!isdigit((unsigned char)news[i]))
luaL_putchar(b, news[i]);
else {
int level = check_capture(L, news[i], cap);
luaL_addlstring(b, cap->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);
}

View File

@ -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 (; i<t->size; 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; i<size; i++) {
if (ttype(&v[i].val) != LUA_TNIL)
realuse++;
}
return realuse;
}
static void rehash (lua_State *L, Hash *t) {
int oldsize = t->size;
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; i<oldsize; i++) {
Node *old = nold+i;
if (ttype(&old->val) != 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));
}

View File

@ -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

View File

@ -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 <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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; i<p->nkstr; 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

View File

@ -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 <stdio.h>
#include <string.h>
#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; i<TM_N; i++)
luaT_gettm(L, tag, i) = NULL;
L->TMtable[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; e<TM_N; e++) {
if (luaT_validevent(tagto, e))
luaT_gettm(L, tagto, e) = luaT_gettm(L, tagfrom, e);
}
return tagto;
}
int luaT_tag (const TObject *o) {
int t = ttype(o);
switch (t) {
case LUA_TUSERDATA: return tsvalue(o)->u.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--;
}

View File

@ -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

View File

@ -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 <stddef.h>
/* 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.
******************************************************************************/

View File

@ -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

View File

@ -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

View File

@ -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 <stdio.h>
#include <string.h>
#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; i<n; i++)
{
tf->locvars[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; i<n; i++)
tf->kstr[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; i<n; i++)
tf->kproto[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<VERSION0) /* check last major change */
luaO_verror(L,"`%.99s' too old:\n"
" read version %d.%d; expected at least %d.%d",
ZNAME(Z),V(version),V(VERSION));
swap=(luaU_endianess()!=ezgetc(L,Z)); /* need to swap bytes? */
TESTSIZE(sizeof(int));
TESTSIZE(sizeof(size_t));
TESTSIZE(sizeof(Instruction));
TESTSIZE(SIZE_INSTRUCTION);
TESTSIZE(SIZE_OP);
TESTSIZE(SIZE_B);
TESTSIZE(sizeof(Number));
f=LoadNumber(L,Z,swap);
if ((long)f!=(long)tf) /* disregard errors in last bit of fraction */
luaO_verror(L,"unknown number format in `%.99s':\n"
" read " NUMBER_FMT "; expected " NUMBER_FMT, ZNAME(Z),f,tf);
return swap;
}
static Proto* LoadChunk (lua_State* L, ZIO* Z)
{
return LoadFunction(L,Z,LoadHeader(L,Z));
}
/*
** load one chunk from a file or buffer
** return main if ok and NULL at EOF
*/
Proto* luaU_undump (lua_State* L, ZIO* Z)
{
Proto* tf=NULL;
int c=zgetc(Z);
if (c==ID_CHUNK)
tf=LoadChunk(L,Z);
c=zgetc(Z);
if (c!=EOZ)
luaO_verror(L,"`%.99s' apparently contains more than one chunk",ZNAME(Z));
return tf;
}
/*
** find byte order
*/
int luaU_endianess (void)
{
int x=1;
return *(char*)&x;
}

View File

@ -0,0 +1,35 @@
/*
** $Id: lundump.h,v 1.1 2003/01/24 16:26:18 jason379 Exp $
** load pre-compiled Lua chunks
** See Copyright Notice in lua.h
*/
#ifndef lundump_h
#define lundump_h
#include "lobject.h"
#include "lzio.h"
/* load one chunk */
Proto* luaU_undump (lua_State* L, ZIO* Z);
/* find byte order */
int luaU_endianess (void);
/* definitions for headers of binary files */
#define VERSION 0x40 /* last format change was in 4.0 */
#define VERSION0 0x40 /* last major change was in 4.0 */
#define ID_CHUNK 27 /* binary files start with ESC... */
#define SIGNATURE "Lua" /* ...followed by this signature */
/* formats for error messages */
#define SOURCE_FMT "<%d:%.99s>"
#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

View File

@ -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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#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+i<L->top; 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<a) */
top -= 2;
if (!luaV_lessthan(L, top+1, top, top+2)) dojump(pc, i);
break;
}
case OP_JMPGT: { /* a > b === (b<a) */
top -= 2;
if (luaV_lessthan(L, top+1, top, top+2)) dojump(pc, i);
break;
}
case OP_JMPGE: { /* a >= b === !(a<b) */
top -= 2;
if (!luaV_lessthan(L, top, top+1, top+2)) dojump(pc, i);
break;
}
case OP_JMPT: {
if (ttype(--top) != LUA_TNIL) dojump(pc, i);
break;
}
case OP_JMPF: {
if (ttype(--top) == LUA_TNIL) dojump(pc, i);
break;
}
case OP_JMPONT: {
if (ttype(top-1) == LUA_TNIL) top--;
else dojump(pc, i);
break;
}
case OP_JMPONF: {
if (ttype(top-1) != LUA_TNIL) top--;
else dojump(pc, i);
break;
}
case OP_JMP: {
dojump(pc, i);
break;
}
case OP_PUSHNILJMP: {
ttype(top++) = LUA_TNIL;
pc++;
break;
}
case OP_FORPREP: {
if (tonumber(top-1))
lua_error(L, "`for' step must be a number");
if (tonumber(top-2))
lua_error(L, "`for' limit must be a number");
if (tonumber(top-3))
lua_error(L, "`for' initial value must be a number");
if (nvalue(top-1) > 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;
}
}
}
}

View File

@ -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

View File

@ -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 <stdio.h>
#include <string.h>
#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;
}

View File

@ -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 <stdio.h>
/* 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

View File

@ -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 <stdio.h>
#include <string.h>
#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;
}

568
build/premake/src/Src/gnu.c Normal file
View File

@ -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 <stdio.h>
#include <string.h>
#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;
}

View File

@ -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 <stdio.h>
#include <dlfcn.h>
#include <glob.h>
#include <unistd.h>
#include <sys/stat.h>
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;
}

View File

@ -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 <stdio.h>
#include <string.h>
#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("");
}

View File

@ -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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

View File

@ -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);

View File

@ -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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#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, "<Combine fileversion=\"1.0\" name=\"%s\" description=\"\">\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, " <StartMode startupentry=\"%s\" single=\"True\">\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, " <Execute entry=\"%s\" type=\"None\" />\n", name);
}
fprintf(file, " </StartMode>\n");
fprintf(file, " <Entries>\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, " <Entry filename=\"%s%s.%s\" />\n", path, name, "prjx");
}
fprintf(file, " </Entries>\n");
fprintf(file, " <Configurations active=\"Debug\">\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, " <Configuration name=\"%s\">\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, " <Entry name=\"%s\" configurationname=\"%s\" build=\"%s\" />\n", package->name, configName, isIncluded ? "True" : "False");
}
fprintf(file, " </Configuration>\n");
}
fprintf(file, " </Configurations>\n");
fprintf(file, "</Combine>");
// 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, "<Project name=\"%s\" description=\"\" newfilesearch=\"None\" enableviewstate=\"True\" version=\"1.1\" projecttype=\"C#\">\n", name);
// File List
fprintf(file, " <Contents>\n");
writeList(file, package->files, " <File name=\".\\", " dependson=\"\" data=\"\" />\n", "", checkSrcFileType, NULL);
fprintf(file, " </Contents>\n");
// References
fprintf(file, " <References>\n");
writeList(file, package->config[0]->links, " <Reference", " />\n", "", checkRefs, package);
fprintf(file, " </References>\n");
// Configurations
fprintf(file, " <Configurations active=\"%s\">\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, " <Configuration runwithwarnings=\"True\" name=\"%s\">\n", config->name);
fprintf(file, " <CodeGeneration runtime=\"%s\" compiler=\"%s\"", runtime, csc);
fprintf(file, " warninglevel=\"0\" ");
fprintf(file, "includedebuginformation=\"%s\" ", symbols ? "True" : "False");
fprintf(file, "optimize=\"%s\" ", optimize ? "True" : "False");
fprintf(file, "unsafecodeallowed=\"%s\" ", unsafe ? "True" : "False");
fprintf(file, "generateoverflowchecks=\"True\" ");
fprintf(file, "mainclass=\"\" ");
fprintf(file, "target=\"%s\" ", kind);
fprintf(file, "definesymbols=\"");
writeList(file, config->defines, "", "", ";", NULL, NULL);
fprintf(file, "\" ");
fprintf(file, "generatexmldocumentation=\"False\" ");
fprintf(file, "/>\n");
fprintf(file, " <Output ");
fprintf(file, "directory=\"");
fprintf(file, reversePath(path, project->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, " </Configuration>\n", config->name);
}
fprintf(file, " </Configurations>\n");
fprintf(file, "</Project>\n");
fclose(file);
return 1;
}

View File

@ -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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#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();
}

View File

@ -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();

614
build/premake/src/Src/vs6.c Normal file
View File

@ -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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;i<project->numPackages;i++)
{
Package *package=project->package[i];
for (j=0;j<package->numConfigs;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;
}

897
build/premake/src/Src/vs7.c Normal file
View File

@ -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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#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<Filter\n", indent);
fprintf(file, "%s Name=\"%s\"\n", indent, ptr);
fprintf(file, "%s Filter=\"\">\n", indent);
}
break;
case WST_CLOSEGROUP:
if (strlen(path) > 0 && strcmp(ptr, "..") != 0)
fprintf(file, "%s</Filter>\n", indent);
break;
case WST_SOURCEFILE:
fprintf(file, "%s<File\n", indent);
fprintf(file, "%s RelativePath=\"%s\">\n", indent, translatePath(path, WIN32));
for (i=0;i<project->numPackages;i++)
{
Package *package=project->package[i];
for (j=0;j<package->numConfigs;j++)
{
Config *config=package->config[j];
if (config->pchSource && strcmp(ptr, config->pchSource)==0)
{
fprintf(file, "%s <FileConfiguration Name=\"%s|Win32\">\n", indent, config->name);
fprintf(file, "%s <Tool Name=\"VCCLCompilerTool\" UsePrecompiledHeader=\"1\" />\n", indent);
fprintf(file, "%s </FileConfiguration>", indent);
}
}
}
fprintf(file, "%s</File>\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, "<?xml version=\"1.0\" encoding = \"Windows-1252\"?>\n");
fprintf(file, "<VisualStudioProject\n");
fprintf(file, " ProjectType=\"Visual C++\"\n");
fprintf(file, " Version=\"");
switch (version)
{
case 7:
fprintf(file, "7.00");
break;
case 2003:
fprintf(file, "7.10");
break;
}
fprintf(file, "\"\n");
fprintf(file, " Name=\"%s\"\n", name);
fprintf(file, " ProjectGUID=\"{%s}\"\n", data->projGuid);
fprintf(file, " Keyword=\"%s\">\n", managed ? "ManagedCProj" : "Win32Proj");
fprintf(file, " <Platforms>\n");
fprintf(file, " <Platform\n");
fprintf(file, " Name=\"Win32\"/>\n");
fprintf(file, " </Platforms>\n");
// Write configurations
fprintf(file, " <Configurations>\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, " <Configuration\n");
fprintf(file, " Name=\"%s|Win32\"\n", config->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, " <Tool\n");
fprintf(file, " Name=\"VCCLCompilerTool\"\n");
fprintf(file, " Optimization=\"%d\"\n", optLevel);
if (!debug) fprintf(file, " InlineFunctionExpansion=\"1\"\n");
if (!debug) fprintf(file, " OmitFramePointers=\"TRUE\"\n");
fprintf(file, " AdditionalOptions=\"");
writeList(file, config->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, " <Tool\n");
fprintf(file, " Name=\"VCCustomBuildTool\"/>\n");
if (configType != 4)
{
fprintf(file, " <Tool\n");
fprintf(file, " Name=\"VCLinkerTool\"\n");
fprintf(file, " IgnoreImportLibrary=\"%s\"\n", importlib ? "TRUE" : "FALSE");
fprintf(file, " AdditionalOptions=\"");
writeList(file, config->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, " <Tool\n");
fprintf(file, " Name=\"VCLibrarianTool\"\n");
fprintf(file, " OutputFile=\"$(OutDir)\\%s.lib\"/>\n", config->target);
}
fprintf(file, " <Tool\n");
fprintf(file, " Name=\"VCMIDLTool\"/>\n");
fprintf(file, " <Tool\n");
fprintf(file, " Name=\"VCPostBuildEventTool\"/>\n");
fprintf(file, " <Tool\n");
fprintf(file, " Name=\"VCPreBuildEventTool\"/>\n");
fprintf(file, " <Tool\n");
fprintf(file, " Name=\"VCPreLinkEventTool\"/>\n");
fprintf(file, " <Tool\n");
fprintf(file, " Name=\"VCResourceCompilerTool\"/>\n");
fprintf(file, " <Tool\n");
fprintf(file, " Name=\"VCWebServiceProxyGeneratorTool\"/>\n");
fprintf(file, " <Tool\n");
fprintf(file, " Name=\"VCWebDeploymentTool\"/>\n");
fprintf(file, " </Configuration>\n");
}
fprintf(file, " </Configurations>\n");
fprintf(file, " <Files>\n");
walkSourceList(file, package, "", vcFiles);
fprintf(file, " </Files>\n");
fprintf(file, " <Globals>\n");
fprintf(file, " </Globals>\n");
fprintf(file, "</VisualStudioProject>\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, "<VisualStudioProject>\n");
fprintf(file, " <CSHARP\n");
fprintf(file, " ProjectType = \"");
fprintf(file, strcmp(kind, "aspnet") == 0 ? "Web" : "Local");
fprintf(file, "\"\n");
switch (version)
{
case 7:
fprintf(file, " ProductVersion = \"7.0.9254\"\n");
fprintf(file, " SchemaVersion = \"1.0\"\n");
break;
case 2003:
fprintf(file, " ProductVersion = \"7.10.3077\"\n");
fprintf(file, " SchemaVersion = \"2.0\"\n");
break;
}
fprintf(file, " ProjectGuid = \"{%s}\"\n", data->projGuid);
fprintf(file, " >\n");
fprintf(file, " <Build>\n");
fprintf(file, " <Settings\n");
fprintf(file, " ApplicationIcon = \"\"\n");
fprintf(file, " AssemblyKeyContainerName = \"\"\n");
fprintf(file, " AssemblyName = \"%s\"\n", getFilename(package->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, " <Config\n");
fprintf(file, " Name = \"%s\"\n", config->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, " </Settings>\n");
// VS7 requires same references for all configurations
fprintf(file, " <References>\n");
writeList(file, package->config[0]->links, " <Reference\n", " />\n", "", checkRefs, package);
fprintf(file, " </References>\n");
fprintf(file, " </Build>\n");
fprintf(file, " <Files>\n");
fprintf(file, " <Include>\n");
writeList(file, package->files, " <File\n RelPath = \"", " />\n", "", checkSrcFileType, package);
fprintf(file, " </Include>\n");
fprintf(file, " </Files>\n");
fprintf(file, " </CSHARP>\n");
fprintf(file, "</VisualStudioProject>\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, "<VisualStudioProject>\n");
fprintf(file, " <CSHARP>\n");
fprintf(file, " <Build>\n");
fprintf(file, " <Settings ReferencePath = \"");
writeList(file, package->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\n");
fprintf(file, " Name = \"%s\"\n", package->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, " </Settings>\n");
fprintf(file, " </Build>\n");
fprintf(file, " <OtherProjectSettings\n");
fprintf(file, " CopyProjectDestinationFolder = \"\"\n");
fprintf(file, " CopyProjectUncPath = \"\"\n");
fprintf(file, " CopyProjectOption = \"0\"\n");
fprintf(file, " ProjectView = \"ProjectFiles\"\n");
fprintf(file, " ProjectTrust = \"0\"\n");
fprintf(file, " />\n");
fprintf(file, " </CSHARP>\n");
fprintf(file, "</VisualStudioProject>\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, "<VisualStudioUNCWeb>\n");
fprintf(file, " <Web URLPath = \"%s/%s.csproj\" />\n", package->url, package->name);
fprintf(file, "</VisualStudioUNCWeb>\n");
fclose(file);
}
return 1;
}

View File

@ -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 <windows.h>
#include <stdio.h>
#include <stdlib.h>
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;
}

View File

@ -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

Some files were not shown because too many files have changed in this diff Show More