From 493baf160ca25e3cba685572abe2aecea829faed Mon Sep 17 00:00:00 2001 From: Scott M Anderson Date: Mon, 17 Nov 2025 15:41:52 -0700 Subject: [PATCH 01/14] git mv to src/ directory to match LuaDist, for now https://github.com/externpro/externpro/issues/222#issuecomment-3544105427 --- lapi.c => src/lapi.c | 0 lapi.h => src/lapi.h | 0 lauxlib.c => src/lauxlib.c | 0 lauxlib.h => src/lauxlib.h | 0 lbaselib.c => src/lbaselib.c | 0 lbitlib.c => src/lbitlib.c | 0 lcode.c => src/lcode.c | 0 lcode.h => src/lcode.h | 0 lcorolib.c => src/lcorolib.c | 0 lctype.c => src/lctype.c | 0 lctype.h => src/lctype.h | 0 ldblib.c => src/ldblib.c | 0 ldebug.c => src/ldebug.c | 0 ldebug.h => src/ldebug.h | 0 ldo.c => src/ldo.c | 0 ldo.h => src/ldo.h | 0 ldump.c => src/ldump.c | 0 lfunc.c => src/lfunc.c | 0 lfunc.h => src/lfunc.h | 0 lgc.c => src/lgc.c | 0 lgc.h => src/lgc.h | 0 linit.c => src/linit.c | 0 liolib.c => src/liolib.c | 0 llex.c => src/llex.c | 0 llex.h => src/llex.h | 0 llimits.h => src/llimits.h | 0 lmathlib.c => src/lmathlib.c | 0 lmem.c => src/lmem.c | 0 lmem.h => src/lmem.h | 0 loadlib.c => src/loadlib.c | 0 lobject.c => src/lobject.c | 0 lobject.h => src/lobject.h | 0 lopcodes.c => src/lopcodes.c | 0 lopcodes.h => src/lopcodes.h | 0 loslib.c => src/loslib.c | 0 lparser.c => src/lparser.c | 0 lparser.h => src/lparser.h | 0 lstate.c => src/lstate.c | 0 lstate.h => src/lstate.h | 0 lstring.c => src/lstring.c | 0 lstring.h => src/lstring.h | 0 lstrlib.c => src/lstrlib.c | 0 ltable.c => src/ltable.c | 0 ltable.h => src/ltable.h | 0 ltablib.c => src/ltablib.c | 0 ltests.c => src/ltests.c | 0 ltests.h => src/ltests.h | 0 ltm.c => src/ltm.c | 0 ltm.h => src/ltm.h | 0 lua.c => src/lua.c | 0 lua.h => src/lua.h | 0 luaconf.h => src/luaconf.h | 0 lualib.h => src/lualib.h | 0 lundump.c => src/lundump.c | 0 lundump.h => src/lundump.h | 0 lvm.c => src/lvm.c | 0 lvm.h => src/lvm.h | 0 lzio.c => src/lzio.c | 0 lzio.h => src/lzio.h | 0 makefile => src/makefile | 0 60 files changed, 0 insertions(+), 0 deletions(-) rename lapi.c => src/lapi.c (100%) rename lapi.h => src/lapi.h (100%) rename lauxlib.c => src/lauxlib.c (100%) rename lauxlib.h => src/lauxlib.h (100%) rename lbaselib.c => src/lbaselib.c (100%) rename lbitlib.c => src/lbitlib.c (100%) rename lcode.c => src/lcode.c (100%) rename lcode.h => src/lcode.h (100%) rename lcorolib.c => src/lcorolib.c (100%) rename lctype.c => src/lctype.c (100%) rename lctype.h => src/lctype.h (100%) rename ldblib.c => src/ldblib.c (100%) rename ldebug.c => src/ldebug.c (100%) rename ldebug.h => src/ldebug.h (100%) rename ldo.c => src/ldo.c (100%) rename ldo.h => src/ldo.h (100%) rename ldump.c => src/ldump.c (100%) rename lfunc.c => src/lfunc.c (100%) rename lfunc.h => src/lfunc.h (100%) rename lgc.c => src/lgc.c (100%) rename lgc.h => src/lgc.h (100%) rename linit.c => src/linit.c (100%) rename liolib.c => src/liolib.c (100%) rename llex.c => src/llex.c (100%) rename llex.h => src/llex.h (100%) rename llimits.h => src/llimits.h (100%) rename lmathlib.c => src/lmathlib.c (100%) rename lmem.c => src/lmem.c (100%) rename lmem.h => src/lmem.h (100%) rename loadlib.c => src/loadlib.c (100%) rename lobject.c => src/lobject.c (100%) rename lobject.h => src/lobject.h (100%) rename lopcodes.c => src/lopcodes.c (100%) rename lopcodes.h => src/lopcodes.h (100%) rename loslib.c => src/loslib.c (100%) rename lparser.c => src/lparser.c (100%) rename lparser.h => src/lparser.h (100%) rename lstate.c => src/lstate.c (100%) rename lstate.h => src/lstate.h (100%) rename lstring.c => src/lstring.c (100%) rename lstring.h => src/lstring.h (100%) rename lstrlib.c => src/lstrlib.c (100%) rename ltable.c => src/ltable.c (100%) rename ltable.h => src/ltable.h (100%) rename ltablib.c => src/ltablib.c (100%) rename ltests.c => src/ltests.c (100%) rename ltests.h => src/ltests.h (100%) rename ltm.c => src/ltm.c (100%) rename ltm.h => src/ltm.h (100%) rename lua.c => src/lua.c (100%) rename lua.h => src/lua.h (100%) rename luaconf.h => src/luaconf.h (100%) rename lualib.h => src/lualib.h (100%) rename lundump.c => src/lundump.c (100%) rename lundump.h => src/lundump.h (100%) rename lvm.c => src/lvm.c (100%) rename lvm.h => src/lvm.h (100%) rename lzio.c => src/lzio.c (100%) rename lzio.h => src/lzio.h (100%) rename makefile => src/makefile (100%) diff --git a/lapi.c b/src/lapi.c similarity index 100% rename from lapi.c rename to src/lapi.c diff --git a/lapi.h b/src/lapi.h similarity index 100% rename from lapi.h rename to src/lapi.h diff --git a/lauxlib.c b/src/lauxlib.c similarity index 100% rename from lauxlib.c rename to src/lauxlib.c diff --git a/lauxlib.h b/src/lauxlib.h similarity index 100% rename from lauxlib.h rename to src/lauxlib.h diff --git a/lbaselib.c b/src/lbaselib.c similarity index 100% rename from lbaselib.c rename to src/lbaselib.c diff --git a/lbitlib.c b/src/lbitlib.c similarity index 100% rename from lbitlib.c rename to src/lbitlib.c diff --git a/lcode.c b/src/lcode.c similarity index 100% rename from lcode.c rename to src/lcode.c diff --git a/lcode.h b/src/lcode.h similarity index 100% rename from lcode.h rename to src/lcode.h diff --git a/lcorolib.c b/src/lcorolib.c similarity index 100% rename from lcorolib.c rename to src/lcorolib.c diff --git a/lctype.c b/src/lctype.c similarity index 100% rename from lctype.c rename to src/lctype.c diff --git a/lctype.h b/src/lctype.h similarity index 100% rename from lctype.h rename to src/lctype.h diff --git a/ldblib.c b/src/ldblib.c similarity index 100% rename from ldblib.c rename to src/ldblib.c diff --git a/ldebug.c b/src/ldebug.c similarity index 100% rename from ldebug.c rename to src/ldebug.c diff --git a/ldebug.h b/src/ldebug.h similarity index 100% rename from ldebug.h rename to src/ldebug.h diff --git a/ldo.c b/src/ldo.c similarity index 100% rename from ldo.c rename to src/ldo.c diff --git a/ldo.h b/src/ldo.h similarity index 100% rename from ldo.h rename to src/ldo.h diff --git a/ldump.c b/src/ldump.c similarity index 100% rename from ldump.c rename to src/ldump.c diff --git a/lfunc.c b/src/lfunc.c similarity index 100% rename from lfunc.c rename to src/lfunc.c diff --git a/lfunc.h b/src/lfunc.h similarity index 100% rename from lfunc.h rename to src/lfunc.h diff --git a/lgc.c b/src/lgc.c similarity index 100% rename from lgc.c rename to src/lgc.c diff --git a/lgc.h b/src/lgc.h similarity index 100% rename from lgc.h rename to src/lgc.h diff --git a/linit.c b/src/linit.c similarity index 100% rename from linit.c rename to src/linit.c diff --git a/liolib.c b/src/liolib.c similarity index 100% rename from liolib.c rename to src/liolib.c diff --git a/llex.c b/src/llex.c similarity index 100% rename from llex.c rename to src/llex.c diff --git a/llex.h b/src/llex.h similarity index 100% rename from llex.h rename to src/llex.h diff --git a/llimits.h b/src/llimits.h similarity index 100% rename from llimits.h rename to src/llimits.h diff --git a/lmathlib.c b/src/lmathlib.c similarity index 100% rename from lmathlib.c rename to src/lmathlib.c diff --git a/lmem.c b/src/lmem.c similarity index 100% rename from lmem.c rename to src/lmem.c diff --git a/lmem.h b/src/lmem.h similarity index 100% rename from lmem.h rename to src/lmem.h diff --git a/loadlib.c b/src/loadlib.c similarity index 100% rename from loadlib.c rename to src/loadlib.c diff --git a/lobject.c b/src/lobject.c similarity index 100% rename from lobject.c rename to src/lobject.c diff --git a/lobject.h b/src/lobject.h similarity index 100% rename from lobject.h rename to src/lobject.h diff --git a/lopcodes.c b/src/lopcodes.c similarity index 100% rename from lopcodes.c rename to src/lopcodes.c diff --git a/lopcodes.h b/src/lopcodes.h similarity index 100% rename from lopcodes.h rename to src/lopcodes.h diff --git a/loslib.c b/src/loslib.c similarity index 100% rename from loslib.c rename to src/loslib.c diff --git a/lparser.c b/src/lparser.c similarity index 100% rename from lparser.c rename to src/lparser.c diff --git a/lparser.h b/src/lparser.h similarity index 100% rename from lparser.h rename to src/lparser.h diff --git a/lstate.c b/src/lstate.c similarity index 100% rename from lstate.c rename to src/lstate.c diff --git a/lstate.h b/src/lstate.h similarity index 100% rename from lstate.h rename to src/lstate.h diff --git a/lstring.c b/src/lstring.c similarity index 100% rename from lstring.c rename to src/lstring.c diff --git a/lstring.h b/src/lstring.h similarity index 100% rename from lstring.h rename to src/lstring.h diff --git a/lstrlib.c b/src/lstrlib.c similarity index 100% rename from lstrlib.c rename to src/lstrlib.c diff --git a/ltable.c b/src/ltable.c similarity index 100% rename from ltable.c rename to src/ltable.c diff --git a/ltable.h b/src/ltable.h similarity index 100% rename from ltable.h rename to src/ltable.h diff --git a/ltablib.c b/src/ltablib.c similarity index 100% rename from ltablib.c rename to src/ltablib.c diff --git a/ltests.c b/src/ltests.c similarity index 100% rename from ltests.c rename to src/ltests.c diff --git a/ltests.h b/src/ltests.h similarity index 100% rename from ltests.h rename to src/ltests.h diff --git a/ltm.c b/src/ltm.c similarity index 100% rename from ltm.c rename to src/ltm.c diff --git a/ltm.h b/src/ltm.h similarity index 100% rename from ltm.h rename to src/ltm.h diff --git a/lua.c b/src/lua.c similarity index 100% rename from lua.c rename to src/lua.c diff --git a/lua.h b/src/lua.h similarity index 100% rename from lua.h rename to src/lua.h diff --git a/luaconf.h b/src/luaconf.h similarity index 100% rename from luaconf.h rename to src/luaconf.h diff --git a/lualib.h b/src/lualib.h similarity index 100% rename from lualib.h rename to src/lualib.h diff --git a/lundump.c b/src/lundump.c similarity index 100% rename from lundump.c rename to src/lundump.c diff --git a/lundump.h b/src/lundump.h similarity index 100% rename from lundump.h rename to src/lundump.h diff --git a/lvm.c b/src/lvm.c similarity index 100% rename from lvm.c rename to src/lvm.c diff --git a/lvm.h b/src/lvm.h similarity index 100% rename from lvm.h rename to src/lvm.h diff --git a/lzio.c b/src/lzio.c similarity index 100% rename from lzio.c rename to src/lzio.c diff --git a/lzio.h b/src/lzio.h similarity index 100% rename from lzio.h rename to src/lzio.h diff --git a/makefile b/src/makefile similarity index 100% rename from makefile rename to src/makefile From 37e1ebdde3c11890d48c9421fce818312eeecefb Mon Sep 17 00:00:00 2001 From: Scott M Anderson Date: Mon, 17 Nov 2025 15:54:23 -0700 Subject: [PATCH 02/14] copy cmake from LuaDist fork (externpro-archive/lua) * https://github.com/externpro-archive/lua/blob/5bbd21fbb20ffcea435ae45593f4e7dfac03e0f4/CMakeLists.txt * https://github.com/externpro-archive/lua/tree/5bbd21fbb20ffcea435ae45593f4e7dfac03e0f4/cmake --- CMakeLists.txt | 164 ++++++++++++++++ cmake/FindLua.cmake | 118 ++++++++++++ cmake/FindReadline.cmake | 25 +++ cmake/dist.cmake | 328 ++++++++++++++++++++++++++++++++ cmake/lua.cmake | 390 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 1025 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 cmake/FindLua.cmake create mode 100644 cmake/FindReadline.cmake create mode 100644 cmake/dist.cmake create mode 100644 cmake/lua.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000000..5dd6dbe355 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,164 @@ +# Copyright (C) 2007-2013 LuaDist. +# Created by Peter DrahoÅ¡, Peter Kapec +# Redistribution and use of this file is allowed according to the terms of the MIT license. +# For details see the COPYRIGHT file distributed with LuaDist. +# Please note that the package source code is licensed under its own license. + +cmake_minimum_required ( VERSION 2.8...3.31 ) +project ( lua C ) +include(GNUInstallDirs) +include(xpflags) +include ( cmake/dist.cmake ) + +## CONFIGURATION +# Default configuration (we assume POSIX by default) +set ( LUA_PATH "LUA_PATH" CACHE STRING "Environment variable to use as package.path." ) +set ( LUA_CPATH "LUA_CPATH" CACHE STRING "Environment variable to use as package.cpath." ) +set ( LUA_INIT "LUA_INIT" CACHE STRING "Environment variable for initial script." ) + +option ( LUA_ANSI "Use only ansi features." OFF ) +option ( LUA_USE_RELATIVE_LOADLIB "Use modified loadlib.c with support for relative paths on posix systems." ON ) +option ( LUA_COMPAT_ALL "Enable backwards compatibility options." ON ) +set ( LUA_IDSIZE 60 CACHE STRING "gives the maximum size for the description of the source." ) + +#2DO: LUAI_* and LUAL_* settings, for now defaults are used. +set ( LUA_DIRSEP "/" ) +set ( LUA_MODULE_SUFFIX ${CMAKE_SHARED_MODULE_SUFFIX} ) +set ( LUA_LDIR ${INSTALL_LMOD} ) +set ( LUA_CDIR ${INSTALL_CMOD} ) + +if ( LUA_USE_RELATIVE_LOADLIB ) + # This will set up relative paths to lib + string ( REGEX REPLACE "[^!/]+" ".." LUA_DIR "!/${INSTALL_BIN}/" ) +else ( ) + # Direct path to installation + set ( LUA_DIR ${CMAKE_INSTALL_PREFIX} CACHE STRING "Destination from which modules will be resolved. See INSTALL_LMOD and INSTALL_CMOD." ) +endif ( ) + +set ( LUA_PATH_DEFAULT "./?.lua;${LUA_DIR}${LUA_LDIR}/?.lua;${LUA_DIR}${LUA_LDIR}/?/init.lua" ) +set ( LUA_CPATH_DEFAULT "./?${LUA_MODULE_SUFFIX};${LUA_DIR}${LUA_CDIR}/?${LUA_MODULE_SUFFIX};${LUA_DIR}${LUA_CDIR}/loadall${LUA_MODULE_SUFFIX}" ) + +if ( WIN32 AND NOT CYGWIN ) + # Windows systems + option ( LUA_WIN "Windows specific build." ON ) + option ( LUA_BUILD_WLUA "Build wLua interpretter without console output." ON ) + option ( LUA_BUILD_AS_DLL "Build Lua library as Dll." ${BUILD_SHARED_LIBS} ) + + # Paths (Double escapes ne option needed) + set ( LUA_DIRSEP "\\\\" ) + string ( REPLACE " /" ${LUA_DIRSEP} LUA_DIR "${LUA_DIR}" ) + string ( REPLACE "/" ${LUA_DIRSEP} LUA_LDIR "${LUA_LDIR}" ) + string ( REPLACE "/" ${LUA_DIRSEP} LUA_CDIR "${LUA_CDIR}" ) + string ( REPLACE "/" ${LUA_DIRSEP} LUA_PATH_DEFAULT "${LUA_PATH_DEFAULT}" ) + string ( REPLACE "/" ${LUA_DIRSEP} LUA_CPATH_DEFAULT "${LUA_CPATH_DEFAULT}" ) +else ( ) + # Posix systems (incl. Cygwin) + option ( LUA_USE_POSIX "Use POSIX features." ON ) + option ( LUA_USE_DLOPEN "Use dynamic linker to load modules." ON ) + option ( LUA_USE_MKSTEMP "Use mkstep." ON ) + option ( LUA_USE_ISATTY "Use tty." ON ) + option ( LUA_USE_POPEN "Use popen." ON ) + option ( LUA_USE_ULONGJMP "Use ulongjmp" ON ) + option ( LUA_USE_GMTIME_R "Use GTIME_R" ON ) + # Apple and Linux specific + if ( LINUX OR APPLE ) + option ( LUA_USE_STRTODHEX "Assume 'strtod' handles hexa formats" ON ) + option ( LUA_USE_AFORMAT "Assume 'printf' handles 'aA' specifiers" ON ) + option ( LUA_USE_LONGLONG "Assume support for long long" ON ) + endif ( ) +endif ( ) + +## SETUP +# Optional libraries +find_package ( Readline ) +if ( READLINE_FOUND ) + option ( LUA_USE_READLINE "Use readline in the Lua CLI." ON ) +endif ( ) + +find_package ( Curses ) +if ( CURSES_FOUND ) + option ( LUA_USE_CURSES "Use curses in the Lua CLI." ON ) +endif ( ) + +# Setup needed variables and libraries +if ( LUA_USE_POSIX ) + # On POSIX Lua links to standard math library "m" + list ( APPEND LIBS m ) +endif ( ) + +if ( LUA_USE_DLOPEN ) + # Link to dynamic linker library "dl" + find_library ( DL_LIBRARY NAMES dl ) + if ( DL_LIBRARY ) + list ( APPEND LIBS dl ) + endif ( ) +endif ( ) + +if ( LUA_USE_READLINE ) + # Add readline + include_directories ( ${READLINE_INCLUDE_DIR} ) + list ( APPEND LIBS ${READLINE_LIBRARY} ) +endif ( ) + +if ( LUA_USE_CURSES ) + # Add curses + include_directories ( ${CURSES_INCLUDE_DIR} ) + list ( APPEND LIBS ${CURSES_LIBRARY} ) +endif ( ) + +## SOURCES +# Generate luaconf.h +configure_file ( src/luaconf.h.in ${CMAKE_CURRENT_BINARY_DIR}/luaconf.h ) + +# Sources and headers +include_directories ( src ${CMAKE_CURRENT_BINARY_DIR} ) +set ( SRC_CORE src/lapi.c src/lcode.c src/lctype.c src/ldebug.c src/ldo.c src/ldump.c + src/lfunc.c src/lgc.c src/llex.c src/lmem.c src/lobject.c src/lopcodes.c src/lparser.c + src/lstate.c src/lstring.c src/ltable.c src/ltm.c src/lundump.c src/lvm.c src/lzio.c ) +set ( SRC_LIB src/lauxlib.c src/lbaselib.c src/lbitlib.c src/lcorolib.c src/ldblib.c + src/liolib.c src/lmathlib.c src/loslib.c src/lstrlib.c src/ltablib.c src/linit.c ) +set ( SRC_LUA src/lua.c ) +set ( SRC_LUAC src/luac.c ) + +if ( LUA_USE_RELATIVE_LOADLIB ) + # Use modified loadlib + list ( APPEND SRC_LIB src/loadlib_rel.c ) +else ( ) + list ( APPEND SRC_LIB src/loadlib.c ) +endif ( ) + +## BUILD +# Create lua library +add_library ( liblua ${SRC_CORE} ${SRC_LIB} ${LUA_DLL_RC} ${LUA_DEF} ) +target_include_directories(liblua PUBLIC $) +if(DEFINED LUABRIDGE_INCDIR) + target_include_directories(liblua PUBLIC $) +endif() +target_link_libraries ( liblua ${LIBS} ) +set_target_properties ( liblua PROPERTIES OUTPUT_NAME lua CLEAN_DIRECT_OUTPUT 1 ) +if ( LUA_BUILD_AS_DLL ) + set_target_properties ( liblua PROPERTIES COMPILE_DEFINITIONS LUA_BUILD_AS_DLL ) +endif () + +add_executable ( lua ${SRC_LUA} src/lua.rc ) +target_link_libraries ( lua liblua ) + +add_executable ( luac ${SRC_CORE} ${SRC_LIB} ${SRC_LUAC} src/luac.rc ) +target_link_libraries ( luac ${LIBS} ) + +# On windows a variant of the lua interpreter without console output needs to be built +if ( LUA_BUILD_WLUA ) + add_executable ( wlua WIN32 src/wmain.c ${SRC_LUA} src/lua.rc ) + target_link_libraries ( wlua liblua ) + install_executable ( wlua ) +endif ( ) + +set(targetsFile ${PROJECT_NAME}-targets) +install_executable ( lua luac ) +install_library ( liblua ) +install_data ( README.md ) +#install_lua_module ( strict etc/strict.lua ) +install_header ( src/lua.h src/lualib.h src/lauxlib.h src/lua.hpp ${CMAKE_CURRENT_BINARY_DIR}/luaconf.h INTO ${PROJECT_NAME} ) +install_doc ( doc/ ) +install_foo ( etc/ ) +#install_test ( test/ ) diff --git a/cmake/FindLua.cmake b/cmake/FindLua.cmake new file mode 100644 index 0000000000..7fb7ca3f4f --- /dev/null +++ b/cmake/FindLua.cmake @@ -0,0 +1,118 @@ +# Locate Lua library +# This module defines +# LUA_EXECUTABLE, if found +# LUA_FOUND, if false, do not try to link to Lua +# LUA_LIBRARIES +# LUA_INCLUDE_DIR, where to find lua.h +# LUA_VERSION_STRING, the version of Lua found (since CMake 2.8.8) +# +# Note that the expected include convention is +# #include "lua.h" +# and not +# #include +# This is because, the lua location is not standardized and may exist +# in locations other than lua/ + +#============================================================================= +# Copyright 2007-2009 Kitware, Inc. +# Modified to support Lua 5.2 by LuaDist 2012 +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) +# +# The required version of Lua can be specified using the +# standard syntax, e.g. FIND_PACKAGE(Lua 5.1) +# Otherwise the module will search for any available Lua implementation + +# Always search for non-versioned lua first (recommended) +SET(_POSSIBLE_LUA_INCLUDE include include/lua) +SET(_POSSIBLE_LUA_EXECUTABLE lua) +SET(_POSSIBLE_LUA_LIBRARY lua) + +# Determine possible naming suffixes (there is no standard for this) +IF(Lua_FIND_VERSION_MAJOR AND Lua_FIND_VERSION_MINOR) + SET(_POSSIBLE_SUFFIXES "${Lua_FIND_VERSION_MAJOR}${Lua_FIND_VERSION_MINOR}" "${Lua_FIND_VERSION_MAJOR}.${Lua_FIND_VERSION_MINOR}" "-${Lua_FIND_VERSION_MAJOR}.${Lua_FIND_VERSION_MINOR}") +ELSE(Lua_FIND_VERSION_MAJOR AND Lua_FIND_VERSION_MINOR) + SET(_POSSIBLE_SUFFIXES "52" "5.2" "-5.2" "51" "5.1" "-5.1") +ENDIF(Lua_FIND_VERSION_MAJOR AND Lua_FIND_VERSION_MINOR) + +# Set up possible search names and locations +FOREACH(_SUFFIX ${_POSSIBLE_SUFFIXES}) + LIST(APPEND _POSSIBLE_LUA_INCLUDE "include/lua${_SUFFIX}") + LIST(APPEND _POSSIBLE_LUA_EXECUTABLE "lua${_SUFFIX}") + LIST(APPEND _POSSIBLE_LUA_LIBRARY "lua${_SUFFIX}") +ENDFOREACH(_SUFFIX) + +# Find the lua executable +FIND_PROGRAM(LUA_EXECUTABLE + NAMES ${_POSSIBLE_LUA_EXECUTABLE} +) + +# Find the lua header +FIND_PATH(LUA_INCLUDE_DIR lua.h + HINTS + $ENV{LUA_DIR} + PATH_SUFFIXES ${_POSSIBLE_LUA_INCLUDE} + PATHS + ~/Library/Frameworks + /Library/Frameworks + /usr/local + /usr + /sw # Fink + /opt/local # DarwinPorts + /opt/csw # Blastwave + /opt +) + +# Find the lua library +FIND_LIBRARY(LUA_LIBRARY + NAMES ${_POSSIBLE_LUA_LIBRARY} + HINTS + $ENV{LUA_DIR} + PATH_SUFFIXES lib64 lib + PATHS + ~/Library/Frameworks + /Library/Frameworks + /usr/local + /usr + /sw + /opt/local + /opt/csw + /opt +) + +IF(LUA_LIBRARY) + # include the math library for Unix + IF(UNIX AND NOT APPLE) + FIND_LIBRARY(LUA_MATH_LIBRARY m) + SET( LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}" CACHE STRING "Lua Libraries") + # For Windows and Mac, don't need to explicitly include the math library + ELSE(UNIX AND NOT APPLE) + SET( LUA_LIBRARIES "${LUA_LIBRARY}" CACHE STRING "Lua Libraries") + ENDIF(UNIX AND NOT APPLE) +ENDIF(LUA_LIBRARY) + +# Determine Lua version +IF(LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h") + FILE(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_str REGEX "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua .+\"") + + STRING(REGEX REPLACE "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([^\"]+)\".*" "\\1" LUA_VERSION_STRING "${lua_version_str}") + UNSET(lua_version_str) +ENDIF() + +INCLUDE(FindPackageHandleStandardArgs) +# handle the QUIETLY and REQUIRED arguments and set LUA_FOUND to TRUE if +# all listed variables are TRUE +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua + REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR + VERSION_VAR LUA_VERSION_STRING) + +MARK_AS_ADVANCED(LUA_INCLUDE_DIR LUA_LIBRARIES LUA_LIBRARY LUA_MATH_LIBRARY LUA_EXECUTABLE) + diff --git a/cmake/FindReadline.cmake b/cmake/FindReadline.cmake new file mode 100644 index 0000000000..a0632404b7 --- /dev/null +++ b/cmake/FindReadline.cmake @@ -0,0 +1,25 @@ +# - Try to find Readline +# Once done this will define +# READLINE_FOUND - System has readline +# READLINE_INCLUDE_DIRS - The readline include directories +# READLINE_LIBRARIES - The libraries needed to use readline +# READLINE_DEFINITIONS - Compiler switches required for using readline + +find_package ( PkgConfig ) +pkg_check_modules ( PC_READLINE QUIET readline ) +set ( READLINE_DEFINITIONS ${PC_READLINE_CFLAGS_OTHER} ) + +find_path ( READLINE_INCLUDE_DIR readline/readline.h + HINTS ${PC_READLINE_INCLUDEDIR} ${PC_READLINE_INCLUDE_DIRS} + PATH_SUFFIXES readline ) + +find_library ( READLINE_LIBRARY NAMES readline + HINTS ${PC_READLINE_LIBDIR} ${PC_READLINE_LIBRARY_DIRS} ) + +set ( READLINE_LIBRARIES ${READLINE_LIBRARY} ) +set ( READLINE_INCLUDE_DIRS ${READLINE_INCLUDE_DIR} ) + +include ( FindPackageHandleStandardArgs ) +# handle the QUIETLY and REQUIRED arguments and set READLINE_FOUND to TRUE +# if all listed variables are TRUE +find_package_handle_standard_args ( Readline DEFAULT_MSG READLINE_LIBRARY READLINE_INCLUDE_DIR ) diff --git a/cmake/dist.cmake b/cmake/dist.cmake new file mode 100644 index 0000000000..4b1b77619b --- /dev/null +++ b/cmake/dist.cmake @@ -0,0 +1,328 @@ +# LuaDist CMake utility library. +# Provides sane project defaults and macros common to LuaDist CMake builds. +# +# Copyright (C) 2007-2012 LuaDist. +# by David Manura, Peter DrahoÅ¡ +# Redistribution and use of this file is allowed according to the terms of the MIT license. +# For details see the COPYRIGHT file distributed with LuaDist. +# Please note that the package source code is licensed under its own license. + +## Extract information from dist.info +if ( NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/dist.info ) + message ( FATAL_ERROR + "Missing dist.info file (${CMAKE_CURRENT_SOURCE_DIR}/dist.info)." ) +endif () +file ( READ ${CMAKE_CURRENT_SOURCE_DIR}/dist.info DIST_INFO ) +if ( "${DIST_INFO}" STREQUAL "" ) + message ( FATAL_ERROR "Failed to load dist.info." ) +endif () +# Reads field `name` from dist.info string `DIST_INFO` into variable `var`. +macro ( _parse_dist_field name var ) + string ( REGEX REPLACE ".*${name}[ \t]?=[ \t]?[\"']([^\"']+)[\"'].*" "\\1" + ${var} "${DIST_INFO}" ) + if ( ${var} STREQUAL DIST_INFO ) + message ( FATAL_ERROR "Failed to extract \"${var}\" from dist.info" ) + endif () +endmacro () +# +_parse_dist_field ( name DIST_NAME ) +_parse_dist_field ( version DIST_VERSION ) +_parse_dist_field ( license DIST_LICENSE ) +_parse_dist_field ( author DIST_AUTHOR ) +_parse_dist_field ( maintainer DIST_MAINTAINER ) +_parse_dist_field ( url DIST_URL ) +_parse_dist_field ( desc DIST_DESC ) +message ( "DIST_NAME: ${DIST_NAME}") +message ( "DIST_VERSION: ${DIST_VERSION}") +message ( "DIST_LICENSE: ${DIST_LICENSE}") +message ( "DIST_AUTHOR: ${DIST_AUTHOR}") +message ( "DIST_MAINTAINER: ${DIST_MAINTAINER}") +message ( "DIST_URL: ${DIST_URL}") +message ( "DIST_DESC: ${DIST_DESC}") +string ( REGEX REPLACE ".*depends[ \t]?=[ \t]?[\"']([^\"']+)[\"'].*" "\\1" + DIST_DEPENDS ${DIST_INFO} ) +if ( DIST_DEPENDS STREQUAL DIST_INFO ) + set ( DIST_DEPENDS "" ) +endif () +message ( "DIST_DEPENDS: ${DIST_DEPENDS}") +## 2DO: Parse DIST_DEPENDS and try to install Dependencies with automatically using externalproject_add + + +## INSTALL DEFAULTS (Relative to CMAKE_INSTALL_PREFIX) +# Primary paths +set ( INSTALL_BIN ${CMAKE_INSTALL_BINDIR} CACHE PATH "Where to install binaries to." ) +set ( INSTALL_LIB ${CMAKE_INSTALL_LIBDIR} CACHE PATH "Where to install libraries to." ) +set ( INSTALL_INC ${CMAKE_INSTALL_INCLUDEDIR} CACHE PATH "Where to install headers to." ) +set ( INSTALL_ETC ${CMAKE_INSTALL_SYSCONFDIR} CACHE PATH "Where to store configuration files" ) +set ( INSTALL_SHARE ${CMAKE_INSTALL_DATADIR} CACHE PATH "Directory for shared data." ) + +# Secondary paths +option ( INSTALL_VERSION + "Install runtime libraries and executables with version information." OFF) +set ( INSTALL_DATA ${CMAKE_INSTALL_DOCDIR} CACHE PATH + "Directory the package can store documentation, tests or other data in.") +set ( INSTALL_DOC ${CMAKE_INSTALL_DOCDIR}/doc CACHE PATH + "Recommended directory to install documentation into.") +set ( INSTALL_EXAMPLE ${CMAKE_INSTALL_DOCDIR}/example CACHE PATH + "Recommended directory to install examples into.") +set ( INSTALL_TEST ${CMAKE_INSTALL_DOCDIR}/test CACHE PATH + "Recommended directory to install tests into.") +set ( INSTALL_FOO ${CMAKE_INSTALL_DOCDIR}/etc CACHE PATH + "Where to install additional files") + +# Tweaks and other defaults +# Setting CMAKE to use loose block and search for find modules in source directory +set ( CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true ) +set ( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH} ) +option ( BUILD_SHARED_LIBS "Build shared libraries" ON ) + +# In MSVC, prevent warnings that can occur when using standard libraries. +if ( MSVC ) + add_definitions ( -D_CRT_SECURE_NO_WARNINGS ) +endif () + +# RPath and relative linking +option ( USE_RPATH "Use relative linking." ON) +if ( USE_RPATH ) + string ( REGEX REPLACE "[^!/]+" ".." UP_DIR ${INSTALL_BIN} ) + set ( CMAKE_SKIP_BUILD_RPATH FALSE CACHE STRING "" FORCE ) + set ( CMAKE_BUILD_WITH_INSTALL_RPATH FALSE CACHE STRING "" FORCE ) + set ( CMAKE_INSTALL_RPATH $ORIGIN/${UP_DIR}/${INSTALL_LIB} + CACHE STRING "" FORCE ) + set ( CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE CACHE STRING "" FORCE ) + set ( CMAKE_INSTALL_NAME_DIR @executable_path/${UP_DIR}/${INSTALL_LIB} + CACHE STRING "" FORCE ) +endif () + +## MACROS +# Parser macro +macro ( parse_arguments prefix arg_names option_names) + set ( DEFAULT_ARGS ) + foreach ( arg_name ${arg_names} ) + set ( ${prefix}_${arg_name} ) + endforeach () + foreach ( option ${option_names} ) + set ( ${prefix}_${option} FALSE ) + endforeach () + + set ( current_arg_name DEFAULT_ARGS ) + set ( current_arg_list ) + foreach ( arg ${ARGN} ) + set ( larg_names ${arg_names} ) + list ( FIND larg_names "${arg}" is_arg_name ) + if ( is_arg_name GREATER -1 ) + set ( ${prefix}_${current_arg_name} ${current_arg_list} ) + set ( current_arg_name ${arg} ) + set ( current_arg_list ) + else () + set ( loption_names ${option_names} ) + list ( FIND loption_names "${arg}" is_option ) + if ( is_option GREATER -1 ) + set ( ${prefix}_${arg} TRUE ) + else () + set ( current_arg_list ${current_arg_list} ${arg} ) + endif () + endif () + endforeach () + set ( ${prefix}_${current_arg_name} ${current_arg_list} ) +endmacro () + + +# install_executable ( executable_targets ) +# Installs any executables generated using "add_executable". +# USE: install_executable ( lua ) +# NOTE: subdirectories are NOT supported +set ( CPACK_COMPONENT_RUNTIME_DISPLAY_NAME "${DIST_NAME} Runtime" ) +set ( CPACK_COMPONENT_RUNTIME_DESCRIPTION + "Executables and runtime libraries. Installed into ${INSTALL_BIN}." ) +macro ( install_executable ) + foreach ( _file ${ARGN} ) + if ( INSTALL_VERSION ) + set_target_properties ( ${_file} PROPERTIES VERSION ${DIST_VERSION} + SOVERSION ${DIST_VERSION} ) + endif () + install ( TARGETS ${_file} EXPORT ${targetsFile} RUNTIME DESTINATION ${INSTALL_BIN} + COMPONENT Runtime CONFIGURATIONS Release ) + endforeach() +endmacro () + +# install_library ( library_targets ) +# Installs any libraries generated using "add_library" into apropriate places. +# USE: install_library ( libexpat ) +# NOTE: subdirectories are NOT supported +set ( CPACK_COMPONENT_LIBRARY_DISPLAY_NAME "${DIST_NAME} Development Libraries" ) +set ( CPACK_COMPONENT_LIBRARY_DESCRIPTION + "Static and import libraries needed for development. Installed into ${INSTALL_LIB} or ${INSTALL_BIN}." ) +macro ( install_library ) + foreach ( _file ${ARGN} ) + if ( INSTALL_VERSION ) + set_target_properties ( ${_file} PROPERTIES VERSION ${DIST_VERSION} + SOVERSION ${DIST_VERSION} ) + endif () + install ( TARGETS ${_file} EXPORT ${targetsFile} + RUNTIME DESTINATION ${INSTALL_BIN} COMPONENT Runtime + LIBRARY DESTINATION ${INSTALL_LIB} COMPONENT Runtime + ARCHIVE DESTINATION ${INSTALL_LIB} COMPONENT Library ) + endforeach() + if(DEFINED XP_NAMESPACE) + set(nameSpace NAMESPACE ${XP_NAMESPACE}::) + endif() + if(NOT DEFINED XP_INSTALL_CMAKEDIR) + set(XP_INSTALL_CMAKEDIR ${INSTALL_SHARE}/cmake) + endif() + install(EXPORT ${targetsFile} DESTINATION ${XP_INSTALL_CMAKEDIR} ${nameSpace}) +endmacro () + +# helper function for various install_* functions, for PATTERN/REGEX args. +macro ( _complete_install_args ) + if ( NOT("${_ARG_PATTERN}" STREQUAL "") ) + set ( _ARG_PATTERN PATTERN ${_ARG_PATTERN} ) + endif () + if ( NOT("${_ARG_REGEX}" STREQUAL "") ) + set ( _ARG_REGEX REGEX ${_ARG_REGEX} ) + endif () +endmacro () + +# install_header ( files/directories [INTO destination] ) +# Install a directories or files into header destination. +# USE: install_header ( lua.h luaconf.h ) or install_header ( GL ) +# USE: install_header ( mylib.h INTO mylib ) +# For directories, supports optional PATTERN/REGEX arguments like install(). +set ( CPACK_COMPONENT_HEADER_DISPLAY_NAME "${DIST_NAME} Development Headers" ) +set ( CPACK_COMPONENT_HEADER_DESCRIPTION + "Headers needed for development. Installed into ${INSTALL_INC}." ) +macro ( install_header ) + parse_arguments ( _ARG "INTO;PATTERN;REGEX" "" ${ARGN} ) + _complete_install_args() + foreach ( _file ${_ARG_DEFAULT_ARGS} ) + if ( IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${_file}" ) + install ( DIRECTORY ${_file} DESTINATION ${INSTALL_INC}/${_ARG_INTO} + COMPONENT Header ${_ARG_PATTERN} ${_ARG_REGEX} ) + else () + install ( FILES ${_file} DESTINATION ${INSTALL_INC}/${_ARG_INTO} + COMPONENT Header ) + endif () + endforeach() +endmacro () + +# install_data ( files/directories [INTO destination] ) +# This installs additional data files or directories. +# USE: install_data ( extra data.dat ) +# USE: install_data ( image1.png image2.png INTO images ) +# For directories, supports optional PATTERN/REGEX arguments like install(). +set ( CPACK_COMPONENT_DATA_DISPLAY_NAME "${DIST_NAME} Data" ) +set ( CPACK_COMPONENT_DATA_DESCRIPTION + "Application data. Installed into ${INSTALL_DATA}." ) +macro ( install_data ) + parse_arguments ( _ARG "INTO;PATTERN;REGEX" "" ${ARGN} ) + _complete_install_args() + foreach ( _file ${_ARG_DEFAULT_ARGS} ) + if ( IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${_file}" ) + install ( DIRECTORY ${_file} + DESTINATION ${INSTALL_DATA}/${_ARG_INTO} + COMPONENT Data ${_ARG_PATTERN} ${_ARG_REGEX} ) + else () + install ( FILES ${_file} DESTINATION ${INSTALL_DATA}/${_ARG_INTO} + COMPONENT Data ) + endif () + endforeach() +endmacro () + +# INSTALL_DOC ( files/directories [INTO destination] ) +# This installs documentation content +# USE: install_doc ( doc/ doc.pdf ) +# USE: install_doc ( index.html INTO html ) +# For directories, supports optional PATTERN/REGEX arguments like install(). +set ( CPACK_COMPONENT_DOCUMENTATION_DISPLAY_NAME "${DIST_NAME} Documentation" ) +set ( CPACK_COMPONENT_DOCUMENTATION_DESCRIPTION + "Application documentation. Installed into ${INSTALL_DOC}." ) +macro ( install_doc ) + parse_arguments ( _ARG "INTO;PATTERN;REGEX" "" ${ARGN} ) + _complete_install_args() + foreach ( _file ${_ARG_DEFAULT_ARGS} ) + if ( IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${_file}" ) + install ( DIRECTORY ${_file} DESTINATION ${INSTALL_DOC}/${_ARG_INTO} + COMPONENT Documentation ${_ARG_PATTERN} ${_ARG_REGEX} ) + else () + install ( FILES ${_file} DESTINATION ${INSTALL_DOC}/${_ARG_INTO} + COMPONENT Documentation ) + endif () + endforeach() +endmacro () + +# install_example ( files/directories [INTO destination] ) +# This installs additional examples +# USE: install_example ( examples/ exampleA ) +# USE: install_example ( super_example super_data INTO super) +# For directories, supports optional PATTERN/REGEX argument like install(). +set ( CPACK_COMPONENT_EXAMPLE_DISPLAY_NAME "${DIST_NAME} Examples" ) +set ( CPACK_COMPONENT_EXAMPLE_DESCRIPTION + "Examples and their associated data. Installed into ${INSTALL_EXAMPLE}." ) +macro ( install_example ) + parse_arguments ( _ARG "INTO;PATTERN;REGEX" "" ${ARGN} ) + _complete_install_args() + foreach ( _file ${_ARG_DEFAULT_ARGS} ) + if ( IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${_file}" ) + install ( DIRECTORY ${_file} DESTINATION ${INSTALL_EXAMPLE}/${_ARG_INTO} + COMPONENT Example ${_ARG_PATTERN} ${_ARG_REGEX} ) + else () + install ( FILES ${_file} DESTINATION ${INSTALL_EXAMPLE}/${_ARG_INTO} + COMPONENT Example ) + endif () + endforeach() +endmacro () + +# install_test ( files/directories [INTO destination] ) +# This installs tests and test files, DOES NOT EXECUTE TESTS +# USE: install_test ( my_test data.sql ) +# USE: install_test ( feature_x_test INTO x ) +# For directories, supports optional PATTERN/REGEX argument like install(). +set ( CPACK_COMPONENT_TEST_DISPLAY_NAME "${DIST_NAME} Tests" ) +set ( CPACK_COMPONENT_TEST_DESCRIPTION + "Tests and associated data. Installed into ${INSTALL_TEST}." ) +macro ( install_test ) + parse_arguments ( _ARG "INTO;PATTERN;REGEX" "" ${ARGN} ) + _complete_install_args() + foreach ( _file ${_ARG_DEFAULT_ARGS} ) + if ( IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${_file}" ) + install ( DIRECTORY ${_file} DESTINATION ${INSTALL_TEST}/${_ARG_INTO} + COMPONENT Test ${_ARG_PATTERN} ${_ARG_REGEX} ) + else () + install ( FILES ${_file} DESTINATION ${INSTALL_TEST}/${_ARG_INTO} + COMPONENT Test ) + endif () + endforeach() +endmacro () + +# install_foo ( files/directories [INTO destination] ) +# This installs optional or otherwise unneeded content +# USE: install_foo ( etc/ example.doc ) +# USE: install_foo ( icon.png logo.png INTO icons) +# For directories, supports optional PATTERN/REGEX argument like install(). +set ( CPACK_COMPONENT_OTHER_DISPLAY_NAME "${DIST_NAME} Unspecified Content" ) +set ( CPACK_COMPONENT_OTHER_DESCRIPTION + "Other unspecified content. Installed into ${INSTALL_FOO}." ) +macro ( install_foo ) + parse_arguments ( _ARG "INTO;PATTERN;REGEX" "" ${ARGN} ) + _complete_install_args() + foreach ( _file ${_ARG_DEFAULT_ARGS} ) + if ( IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${_file}" ) + install ( DIRECTORY ${_file} DESTINATION ${INSTALL_FOO}/${_ARG_INTO} + COMPONENT Other ${_ARG_PATTERN} ${_ARG_REGEX} ) + else () + install ( FILES ${_file} DESTINATION ${INSTALL_FOO}/${_ARG_INTO} + COMPONENT Other ) + endif () + endforeach() +endmacro () + +## CTest defaults + +## CPack defaults +set ( CPACK_GENERATOR "ZIP" ) +set ( CPACK_STRIP_FILES TRUE ) +set ( CPACK_PACKAGE_NAME "${DIST_NAME}" ) +set ( CPACK_PACKAGE_VERSION "${DIST_VERSION}") +set ( CPACK_PACKAGE_VENDOR "LuaDist" ) +set ( CPACK_COMPONENTS_ALL Runtime Library Header Data Documentation Example Other ) +include ( CPack ) diff --git a/cmake/lua.cmake b/cmake/lua.cmake new file mode 100644 index 0000000000..a0f3e67d1f --- /dev/null +++ b/cmake/lua.cmake @@ -0,0 +1,390 @@ +# LuaDist CMake utility library for Lua. +# +# Copyright (C) 2007-2012 LuaDist. +# by David Manura, Peter Drahos +# Redistribution and use of this file is allowed according to the terms of the MIT license. +# For details see the COPYRIGHT file distributed with LuaDist. +# Please note that the package source code is licensed under its own license. + +set ( INSTALL_LMOD ${INSTALL_LIB}/lua + CACHE PATH "Directory to install Lua modules." ) +set ( INSTALL_CMOD ${INSTALL_LIB}/lua + CACHE PATH "Directory to install Lua binary modules." ) + +option ( SKIP_LUA_WRAPPER + "Do not build and install Lua executable wrappers." OFF) + +# List of (Lua module name, file path) pairs. +# Used internally by add_lua_test. Built by add_lua_module. +set ( _lua_modules ) + +# utility function: appends path `path` to path `basepath`, properly +# handling cases when `path` may be relative or absolute. +macro ( _append_path basepath path result ) + if ( IS_ABSOLUTE "${path}" ) + set ( ${result} "${path}" ) + else () + set ( ${result} "${basepath}/${path}" ) + endif () +endmacro () + +# install_lua_executable ( target source ) +# Automatically generate a binary wrapper for lua application and install it +# The wrapper and the source of the application will be placed into /bin +# If the application source did not have .lua suffix then it will be added +# USE: lua_executable ( sputnik src/sputnik.lua ) +macro ( install_lua_executable _name _source ) + get_filename_component ( _source_name ${_source} NAME_WE ) + if ( NOT SKIP_LUA_WRAPPER ) + enable_language ( C ) + + find_package ( Lua REQUIRED ) + include_directories ( ${LUA_INCLUDE_DIR} ) + + set ( _wrapper ${CMAKE_CURRENT_BINARY_DIR}/${_name}.c ) + set ( _code +"// Not so simple executable wrapper for Lua apps +#include +#include +#include +#include +#include + +lua_State *L\; + +static int getargs (lua_State *L, char **argv, int n) { +int narg\; +int i\; +int argc = 0\; +while (argv[argc]) argc++\; +narg = argc - (n + 1)\; +luaL_checkstack(L, narg + 3, \"too many arguments to script\")\; +for (i=n+1\; i < argc\; i++) + lua_pushstring(L, argv[i])\; +lua_createtable(L, narg, n + 1)\; +for (i=0\; i < argc\; i++) { + lua_pushstring(L, argv[i])\; + lua_rawseti(L, -2, i - n)\; +} +return narg\; +} + +static void lstop (lua_State *L, lua_Debug *ar) { +(void)ar\; +lua_sethook(L, NULL, 0, 0)\; +luaL_error(L, \"interrupted!\")\; +} + +static void laction (int i) { +signal(i, SIG_DFL)\; +lua_sethook(L, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1)\; +} + +static void l_message (const char *pname, const char *msg) { +if (pname) fprintf(stderr, \"%s: \", pname)\; +fprintf(stderr, \"%s\\n\", msg)\; +fflush(stderr)\; +} + +static int report (lua_State *L, int status) { +if (status && !lua_isnil(L, -1)) { + const char *msg = lua_tostring(L, -1)\; + if (msg == NULL) msg = \"(error object is not a string)\"\; + l_message(\"${_source_name}\", msg)\; + lua_pop(L, 1)\; +} +return status\; +} + +static int traceback (lua_State *L) { +if (!lua_isstring(L, 1)) + return 1\; +lua_getfield(L, LUA_GLOBALSINDEX, \"debug\")\; +if (!lua_istable(L, -1)) { + lua_pop(L, 1)\; + return 1\; +} +lua_getfield(L, -1, \"traceback\")\; +if (!lua_isfunction(L, -1)) { + lua_pop(L, 2)\; + return 1\; +} +lua_pushvalue(L, 1)\; +lua_pushinteger(L, 2)\; +lua_call(L, 2, 1)\; +return 1\; +} + +static int docall (lua_State *L, int narg, int clear) { +int status\; +int base = lua_gettop(L) - narg\; +lua_pushcfunction(L, traceback)\; +lua_insert(L, base)\; +signal(SIGINT, laction)\; +status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base)\; +signal(SIGINT, SIG_DFL)\; +lua_remove(L, base)\; +if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0)\; +return status\; +} + +int main (int argc, char **argv) { +L=lua_open()\; +lua_gc(L, LUA_GCSTOP, 0)\; +luaL_openlibs(L)\; +lua_gc(L, LUA_GCRESTART, 0)\; +int narg = getargs(L, argv, 0)\; +lua_setglobal(L, \"arg\")\; + +// Script +char script[500] = \"./${_source_name}.lua\"\; +lua_getglobal(L, \"_PROGDIR\")\; +if (lua_isstring(L, -1)) { + sprintf( script, \"%s/${_source_name}.lua\", lua_tostring(L, -1))\; +} +lua_pop(L, 1)\; + +// Run +int status = luaL_loadfile(L, script)\; +lua_insert(L, -(narg+1))\; +if (status == 0) + status = docall(L, narg, 0)\; +else + lua_pop(L, narg)\; + +report(L, status)\; +lua_close(L)\; +return status\; +}; +") + file ( WRITE ${_wrapper} ${_code} ) + add_executable ( ${_name} ${_wrapper} ) + target_link_libraries ( ${_name} ${LUA_LIBRARY} ) + install ( TARGETS ${_name} DESTINATION ${INSTALL_BIN} ) + endif() + install ( PROGRAMS ${_source} DESTINATION ${INSTALL_BIN} + RENAME ${_source_name}.lua ) +endmacro () + +macro ( _lua_module_helper is_install _name ) + parse_arguments ( _MODULE "LINK;ALL_IN_ONE" "" ${ARGN} ) + # _target is CMake-compatible target name for module (e.g. socket_core). + # _module is relative path of target (e.g. socket/core), + # without extension (e.g. .lua/.so/.dll). + # _MODULE_SRC is list of module source files (e.g. .lua and .c files). + # _MODULE_NAMES is list of module names (e.g. socket.core). + if ( _MODULE_ALL_IN_ONE ) + string ( REGEX REPLACE "\\..*" "" _target "${_name}" ) + string ( REGEX REPLACE "\\..*" "" _module "${_name}" ) + set ( _target "${_target}_all_in_one") + set ( _MODULE_SRC ${_MODULE_ALL_IN_ONE} ) + set ( _MODULE_NAMES ${_name} ${_MODULE_DEFAULT_ARGS} ) + else () + string ( REPLACE "." "_" _target "${_name}" ) + string ( REPLACE "." "/" _module "${_name}" ) + set ( _MODULE_SRC ${_MODULE_DEFAULT_ARGS} ) + set ( _MODULE_NAMES ${_name} ) + endif () + if ( NOT _MODULE_SRC ) + message ( FATAL_ERROR "no module sources specified" ) + endif () + list ( GET _MODULE_SRC 0 _first_source ) + + get_filename_component ( _ext ${_first_source} EXT ) + if ( _ext STREQUAL ".lua" ) # Lua source module + list ( LENGTH _MODULE_SRC _len ) + if ( _len GREATER 1 ) + message ( FATAL_ERROR "more than one source file specified" ) + endif () + + set ( _module "${_module}.lua" ) + + get_filename_component ( _module_dir ${_module} PATH ) + get_filename_component ( _module_filename ${_module} NAME ) + _append_path ( "${CMAKE_CURRENT_SOURCE_DIR}" "${_first_source}" _module_path ) + list ( APPEND _lua_modules "${_name}" "${_module_path}" ) + + if ( ${is_install} ) + install ( FILES ${_first_source} DESTINATION ${INSTALL_LMOD}/${_module_dir} + RENAME ${_module_filename} ) + endif () + else () # Lua C binary module + enable_language ( C ) + find_package ( Lua REQUIRED ) + include_directories ( ${LUA_INCLUDE_DIR} ) + + set ( _module "${_module}${CMAKE_SHARED_MODULE_SUFFIX}" ) + + get_filename_component ( _module_dir ${_module} PATH ) + get_filename_component ( _module_filenamebase ${_module} NAME_WE ) + foreach ( _thisname ${_MODULE_NAMES} ) + list ( APPEND _lua_modules "${_thisname}" + "${CMAKE_CURRENT_BINARY_DIR}/\${CMAKE_CFG_INTDIR}/${_module}" ) + endforeach () + + add_library( ${_target} MODULE ${_MODULE_SRC}) + target_link_libraries ( ${_target} ${LUA_LIBRARY} ${_MODULE_LINK} ) + set_target_properties ( ${_target} PROPERTIES LIBRARY_OUTPUT_DIRECTORY + "${_module_dir}" PREFIX "" OUTPUT_NAME "${_module_filenamebase}" ) + if ( ${is_install} ) + install ( TARGETS ${_target} DESTINATION ${INSTALL_CMOD}/${_module_dir}) + endif () + endif () +endmacro () + +# add_lua_module +# Builds a Lua source module into a destination locatable by Lua +# require syntax. +# Binary modules are also supported where this function takes sources and +# libraries to compile separated by LINK keyword. +# USE: add_lua_module ( socket.http src/http.lua ) +# USE2: add_lua_module ( mime.core src/mime.c ) +# USE3: add_lua_module ( socket.core ${SRC_SOCKET} LINK ${LIB_SOCKET} ) +# USE4: add_lua_module ( ssl.context ssl.core ALL_IN_ONE src/context.c src/ssl.c ) +# This form builds an "all-in-one" module (e.g. ssl.so or ssl.dll containing +# both modules ssl.context and ssl.core). The CMake target name will be +# ssl_all_in_one. +# Also sets variable _module_path (relative path where module typically +# would be installed). +macro ( add_lua_module ) + _lua_module_helper ( 0 ${ARGN} ) +endmacro () + + +# install_lua_module +# This is the same as `add_lua_module` but also installs the module. +# USE: install_lua_module ( socket.http src/http.lua ) +# USE2: install_lua_module ( mime.core src/mime.c ) +# USE3: install_lua_module ( socket.core ${SRC_SOCKET} LINK ${LIB_SOCKET} ) +macro ( install_lua_module ) + _lua_module_helper ( 1 ${ARGN} ) +endmacro () + +# Builds string representing Lua table mapping Lua modules names to file +# paths. Used internally. +macro ( _make_module_table _outvar ) + set ( ${_outvar} ) + list ( LENGTH _lua_modules _n ) + if ( ${_n} GREATER 0 ) # avoids cmake complaint + foreach ( _i RANGE 1 ${_n} 2 ) + list ( GET _lua_modules ${_i} _path ) + math ( EXPR _ii ${_i}-1 ) + list ( GET _lua_modules ${_ii} _name ) + set ( ${_outvar} "${_table} ['${_name}'] = '${_path}'\;\n") + endforeach () + endif () + set ( ${_outvar} +"local modules = { +${_table}}" ) +endmacro () + +# add_lua_test ( _testfile [ WORKING_DIRECTORY _working_dir ] ) +# Runs Lua script `_testfile` under CTest tester. +# Optional named argument `WORKING_DIRECTORY` is current working directory to +# run test under (defaults to ${CMAKE_CURRENT_BINARY_DIR}). +# Both paths, if relative, are relative to ${CMAKE_CURRENT_SOURCE_DIR}. +# Any modules previously defined with install_lua_module are automatically +# preloaded (via package.preload) prior to running the test script. +# Under LuaDist, set test=true in config.lua to enable testing. +# USE: add_lua_test ( test/test1.lua [args...] [WORKING_DIRECTORY dir]) +macro ( add_lua_test _testfile ) + if ( NOT SKIP_TESTING ) + parse_arguments ( _ARG "WORKING_DIRECTORY" "" ${ARGN} ) + include ( CTest ) + find_program ( LUA NAMES lua lua.bat ) + get_filename_component ( TESTFILEABS ${_testfile} ABSOLUTE ) + get_filename_component ( TESTFILENAME ${_testfile} NAME ) + get_filename_component ( TESTFILEBASE ${_testfile} NAME_WE ) + + # Write wrapper script. + # Note: One simple way to allow the script to find modules is + # to just put them in package.preload. + set ( TESTWRAPPER ${CMAKE_CURRENT_BINARY_DIR}/${TESTFILENAME} ) + _make_module_table ( _table ) + set ( TESTWRAPPERSOURCE +"local CMAKE_CFG_INTDIR = ... or '.' +${_table} +local function preload_modules(modules) + for name, path in pairs(modules) do + if path:match'%.lua' then + package.preload[name] = assert(loadfile(path)) + else + local name = name:gsub('.*%-', '') -- remove any hyphen prefix + local symbol = 'luaopen_' .. name:gsub('%.', '_') + --improve: generalize to support all-in-one loader? + local path = path:gsub('%$%{CMAKE_CFG_INTDIR%}', CMAKE_CFG_INTDIR) + package.preload[name] = assert(package.loadlib(path, symbol)) + end + end +end +preload_modules(modules) +arg[0] = '${TESTFILEABS}' +table.remove(arg, 1) +return assert(loadfile '${TESTFILEABS}')(unpack(arg)) +" ) + if ( _ARG_WORKING_DIRECTORY ) + get_filename_component ( + TESTCURRENTDIRABS ${_ARG_WORKING_DIRECTORY} ABSOLUTE ) + # note: CMake 2.6 (unlike 2.8) lacks WORKING_DIRECTORY parameter. + set ( _pre ${CMAKE_COMMAND} -E chdir "${TESTCURRENTDIRABS}" ) + endif () + file ( WRITE ${TESTWRAPPER} ${TESTWRAPPERSOURCE}) + add_test ( NAME ${TESTFILEBASE} COMMAND ${_pre} ${LUA} + ${TESTWRAPPER} "${CMAKE_CFG_INTDIR}" + ${_ARG_DEFAULT_ARGS} ) + endif () + # see also http://gdcm.svn.sourceforge.net/viewvc/gdcm/Sandbox/CMakeModules/UsePythonTest.cmake + # Note: ${CMAKE_CFG_INTDIR} is a command-line argument to allow proper + # expansion by the native build tool. +endmacro () + + +# Converts Lua source file `_source` to binary string embedded in C source +# file `_target`. Optionally compiles Lua source to byte code (not available +# under LuaJIT2, which doesn't have a bytecode loader). Additionally, Lua +# versions of bin2c [1] and luac [2] may be passed respectively as additional +# arguments. +# +# [1] http://lua-users.org/wiki/BinToCee +# [2] http://lua-users.org/wiki/LuaCompilerInLua +function ( add_lua_bin2c _target _source ) + find_program ( LUA NAMES lua lua.bat ) + execute_process ( COMMAND ${LUA} -e "string.dump(function()end)" + RESULT_VARIABLE _LUA_DUMP_RESULT ERROR_QUIET ) + if ( NOT ${_LUA_DUMP_RESULT} ) + SET ( HAVE_LUA_DUMP true ) + endif () + message ( "-- string.dump=${HAVE_LUA_DUMP}" ) + + if ( ARGV2 ) + get_filename_component ( BIN2C ${ARGV2} ABSOLUTE ) + set ( BIN2C ${LUA} ${BIN2C} ) + else () + find_program ( BIN2C NAMES bin2c bin2c.bat ) + endif () + if ( HAVE_LUA_DUMP ) + if ( ARGV3 ) + get_filename_component ( LUAC ${ARGV3} ABSOLUTE ) + set ( LUAC ${LUA} ${LUAC} ) + else () + find_program ( LUAC NAMES luac luac.bat ) + endif () + endif ( HAVE_LUA_DUMP ) + message ( "-- bin2c=${BIN2C}" ) + message ( "-- luac=${LUAC}" ) + + get_filename_component ( SOURCEABS ${_source} ABSOLUTE ) + if ( HAVE_LUA_DUMP ) + get_filename_component ( SOURCEBASE ${_source} NAME_WE ) + add_custom_command ( + OUTPUT ${_target} DEPENDS ${_source} + COMMAND ${LUAC} -o ${CMAKE_CURRENT_BINARY_DIR}/${SOURCEBASE}.lo + ${SOURCEABS} + COMMAND ${BIN2C} ${CMAKE_CURRENT_BINARY_DIR}/${SOURCEBASE}.lo + ">${_target}" ) + else () + add_custom_command ( + OUTPUT ${_target} DEPENDS ${SOURCEABS} + COMMAND ${BIN2C} ${_source} ">${_target}" ) + endif () +endfunction() From 12f0fd73caf294802b3aad1be38b92fad42d4939 Mon Sep 17 00:00:00 2001 From: Scott M Anderson Date: Mon, 17 Nov 2025 16:05:32 -0700 Subject: [PATCH 03/14] copy etc/ icons from LuaDist fork (externpro-archive/lua) https://github.com/externpro-archive/lua/tree/5bbd21fbb20ffcea435ae45593f4e7dfac03e0f4/etc --- etc/lua.ico | Bin 0 -> 116114 bytes etc/lua_lang.ico | Bin 0 -> 119793 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 etc/lua.ico create mode 100644 etc/lua_lang.ico diff --git a/etc/lua.ico b/etc/lua.ico new file mode 100644 index 0000000000000000000000000000000000000000..1dd0d0d5775e1c50598dbab3e8740102886eb925 GIT binary patch literal 116114 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¤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
  • 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 literal 0 HcmV?d00001 From 87e8435e7b926712911b6addbb0e97e79a082dcf Mon Sep 17 00:00:00 2001 From: Scott M Anderson Date: Mon, 17 Nov 2025 16:07:10 -0700 Subject: [PATCH 04/14] copy src/ files from LuaDist fork (externpro-archive/lua) * source files that aren't in the official lua/lua repo and part of the LuaDist build * https://github.com/externpro-archive/lua/tree/5bbd21fbb20ffcea435ae45593f4e7dfac03e0f4/src --- src/loadlib_rel.c | 799 ++++++++++++++++++++++++++++++++++++++++++++++ src/lua.hpp | 9 + src/lua.rc | 28 ++ src/luac.c | 432 +++++++++++++++++++++++++ src/luac.rc | 28 ++ src/luaconf.h.in | 497 ++++++++++++++++++++++++++++ src/wmain.c | 16 + 7 files changed, 1809 insertions(+) create mode 100644 src/loadlib_rel.c create mode 100644 src/lua.hpp create mode 100644 src/lua.rc create mode 100644 src/luac.c create mode 100644 src/luac.rc create mode 100644 src/luaconf.h.in create mode 100644 src/wmain.c diff --git a/src/loadlib_rel.c b/src/loadlib_rel.c new file mode 100644 index 0000000000..c2e9b950da --- /dev/null +++ b/src/loadlib_rel.c @@ -0,0 +1,799 @@ +/* +** $Id: loadlib.c,v 1.111 2012/05/30 12:33:44 roberto Exp $ +** Dynamic library loader for Lua +** See Copyright Notice in lua.h +** +** This module contains an implementation of loadlib for Unix systems +** that have dlfcn, an implementation for Windows, and a stub for other +** systems. +*/ + + +/* +** if needed, includes windows header before everything else +*/ +#if defined(_WIN32) +#include +#endif + + +#include +#include + + +#define loadlib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* +** LUA_PATH and LUA_CPATH are the names of the environment +** variables that Lua check to set its paths. +*/ +#if !defined(LUA_PATH) +#define LUA_PATH "LUA_PATH" +#endif + +#if !defined(LUA_CPATH) +#define LUA_CPATH "LUA_CPATH" +#endif + +#define LUA_PATHSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR + +#define LUA_PATHVERSION LUA_PATH LUA_PATHSUFFIX +#define LUA_CPATHVERSION LUA_CPATH LUA_PATHSUFFIX + +/* +** LUA_PATH_SEP is the character that separates templates in a path. +** LUA_PATH_MARK is the string that marks the substitution points in a +** template. +** LUA_EXEC_DIR in a Windows path is replaced by the executable's +** directory. +** LUA_IGMARK is a mark to ignore all before it when building the +** luaopen_ function name. +*/ +#if !defined (LUA_PATH_SEP) +#define LUA_PATH_SEP ";" +#endif +#if !defined (LUA_PATH_MARK) +#define LUA_PATH_MARK "?" +#endif +#if !defined (LUA_EXEC_DIR) +#define LUA_EXEC_DIR "!" +#endif +#if !defined (LUA_IGMARK) +#define LUA_IGMARK "-" +#endif + + +/* +** LUA_CSUBSEP is the character that replaces dots in submodule names +** when searching for a C loader. +** LUA_LSUBSEP is the character that replaces dots in submodule names +** when searching for a Lua loader. +*/ +#if !defined(LUA_CSUBSEP) +#define LUA_CSUBSEP LUA_DIRSEP +#endif + +#if !defined(LUA_LSUBSEP) +#define LUA_LSUBSEP LUA_DIRSEP +#endif + + +/* prefix for open functions in C libraries */ +#define LUA_POF "luaopen_" + +/* separator for open functions in C libraries */ +#define LUA_OFSEP "_" + + +/* table (in the registry) that keeps handles for all loaded C libraries */ +#define CLIBS "_CLIBS" + +#define LIB_FAIL "open" + + +/* error codes for ll_loadfunc */ +#define ERRLIB 1 +#define ERRFUNC 2 + +/* +** system-dependent functions +*/ +static void ll_unloadlib (void *lib); +static void *ll_load (lua_State *L, const char *path, int seeglb); +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym); +static void setprogdir (lua_State *L); + +/* +** {========================================================================= +** This determines the location of the executable for relative module loading +** Modified by the LuaDist project for UNIX platforms +** ========================================================================== +*/ +#if defined(_WIN32) + #include + #define _PATH_MAX MAX_PATH +#else + #define _PATH_MAX PATH_MAX +#endif + +#if defined (__CYGWIN__) + #include +#endif + +#if defined(__linux__) || defined(__sun) + #include /* readlink */ +#endif + +#if defined(__APPLE__) + #include + #include +#endif + +#if defined(__FreeBSD__) + #include + #include +#endif + +static void setprogdir(lua_State *L) { + char progdir[_PATH_MAX + 1]; + char *lb; + int nsize = sizeof(progdir)/sizeof(char); + int n = 0; +#if defined(__CYGWIN__) + char win_buff[_PATH_MAX + 1]; + GetModuleFileNameA(NULL, win_buff, nsize); + cygwin_conv_path(CCP_WIN_A_TO_POSIX, win_buff, progdir, nsize); + n = strlen(progdir); +#elif defined(_WIN32) + n = GetModuleFileNameA(NULL, progdir, nsize); +#elif defined(__linux__) + n = readlink("/proc/self/exe", progdir, nsize); + if (n > 0) progdir[n] = 0; +#elif defined(__sun) + pid_t pid = getpid(); + char linkname[256]; + sprintf(linkname, "/proc/%d/path/a.out", pid); + n = readlink(linkname, progdir, nsize); + if (n > 0) progdir[n] = 0; +#elif defined(__FreeBSD__) + int mib[4]; + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PATHNAME; + mib[3] = -1; + size_t cb = nsize; + sysctl(mib, 4, progdir, &cb, NULL, 0); + n = cb; +#elif defined(__BSD__) + n = readlink("/proc/curproc/file", progdir, nsize); + if (n > 0) progdir[n] = 0; +#elif defined(__APPLE__) + uint32_t nsize_apple = nsize; + if (_NSGetExecutablePath(progdir, &nsize_apple) == 0) + n = strlen(progdir); +#else + // FALLBACK + // Use 'lsof' ... should work on most UNIX systems (incl. OSX) + // lsof will list open files, this captures the 1st file listed (usually the executable) + int pid; + FILE* fd; + char cmd[80]; + pid = getpid(); + + sprintf(cmd, "lsof -p %d | awk '{if ($5==\"REG\") { print $9 ; exit}}' 2> /dev/null", pid); + fd = popen(cmd, "r"); + n = fread(progdir, 1, nsize, fd); + pclose(fd); + + // remove newline + if (n > 1) progdir[--n] = '\0'; +#endif + if (n == 0 || n == nsize || (lb = strrchr(progdir, (int)LUA_DIRSEP[0])) == NULL) + luaL_error(L, "unable to get process executable path"); + else { + *lb = '\0'; + + // Replace the relative path placeholder + luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, progdir); + lua_remove(L, -2); + } +} + +#if defined(LUA_USE_DLOPEN) +/* +** {======================================================================== +** This is an implementation of loadlib based on the dlfcn interface. +** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD, +** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least +** as an emulation layer on top of native functions. +** ========================================================================= +*/ + +#include + +static void ll_unloadlib (void *lib) { + dlclose(lib); +} + + +static void *ll_load (lua_State *L, const char *path, int seeglb) { + void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : RTLD_LOCAL)); + if (lib == NULL) lua_pushstring(L, dlerror()); + return lib; +} + + +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { + lua_CFunction f = (lua_CFunction)dlsym(lib, sym); + if (f == NULL) lua_pushstring(L, dlerror()); + return f; +} + +/* }====================================================== */ + + + +#elif defined(LUA_DL_DLL) +/* +** {====================================================================== +** This is an implementation of loadlib for Windows using native functions. +** ======================================================================= +*/ + +/* +** optional flags for LoadLibraryEx +*/ +#if !defined(LUA_LLE_FLAGS) +#define LUA_LLE_FLAGS 0 +#endif + +static void pusherror (lua_State *L) { + int error = GetLastError(); + char buffer[128]; + if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, error, 0, buffer, sizeof(buffer)/sizeof(char), NULL)) + lua_pushstring(L, buffer); + else + lua_pushfstring(L, "system error %d\n", error); +} + +static void ll_unloadlib (void *lib) { + FreeLibrary((HMODULE)lib); +} + + +static void *ll_load (lua_State *L, const char *path, int seeglb) { + HMODULE lib = LoadLibraryExA(path, NULL, LUA_LLE_FLAGS); + (void)(seeglb); /* not used: symbols are 'global' by default */ + if (lib == NULL) pusherror(L); + return lib; +} + + +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { + lua_CFunction f = (lua_CFunction)GetProcAddress((HMODULE)lib, sym); + if (f == NULL) pusherror(L); + return f; +} + +/* }====================================================== */ + + +#else +/* +** {====================================================== +** Fallback for other systems +** ======================================================= +*/ + +#undef LIB_FAIL +#define LIB_FAIL "absent" + + +#define DLMSG "dynamic libraries not enabled; check your Lua installation" + + +static void ll_unloadlib (void *lib) { + (void)(lib); /* not used */ +} + + +static void *ll_load (lua_State *L, const char *path, int seeglb) { + (void)(path); (void)(seeglb); /* not used */ + lua_pushliteral(L, DLMSG); + return NULL; +} + + +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { + (void)(lib); (void)(sym); /* not used */ + lua_pushliteral(L, DLMSG); + return NULL; +} + +/* }====================================================== */ +#endif + + +static void *ll_checkclib (lua_State *L, const char *path) { + void *plib; + lua_getfield(L, LUA_REGISTRYINDEX, CLIBS); + lua_getfield(L, -1, path); + plib = lua_touserdata(L, -1); /* plib = CLIBS[path] */ + lua_pop(L, 2); /* pop CLIBS table and 'plib' */ + return plib; +} + + +static void ll_addtoclib (lua_State *L, const char *path, void *plib) { + lua_getfield(L, LUA_REGISTRYINDEX, CLIBS); + lua_pushlightuserdata(L, plib); + lua_pushvalue(L, -1); + lua_setfield(L, -3, path); /* CLIBS[path] = plib */ + lua_rawseti(L, -2, luaL_len(L, -2) + 1); /* CLIBS[#CLIBS + 1] = plib */ + lua_pop(L, 1); /* pop CLIBS table */ +} + + +/* +** __gc tag method for CLIBS table: calls 'll_unloadlib' for all lib +** handles in list CLIBS +*/ +static int gctm (lua_State *L) { + int n = luaL_len(L, 1); + for (; n >= 1; n--) { /* for each handle, in reverse order */ + lua_rawgeti(L, 1, n); /* get handle CLIBS[n] */ + ll_unloadlib(lua_touserdata(L, -1)); + lua_pop(L, 1); /* pop handle */ + } + return 0; +} + + +static int ll_loadfunc (lua_State *L, const char *path, const char *sym) { + void *reg = ll_checkclib(L, path); /* check loaded C libraries */ + if (reg == NULL) { /* must load library? */ + reg = ll_load(L, path, *sym == '*'); + if (reg == NULL) return ERRLIB; /* unable to load library */ + ll_addtoclib(L, path, reg); + } + if (*sym == '*') { /* loading only library (no function)? */ + lua_pushboolean(L, 1); /* return 'true' */ + return 0; /* no errors */ + } + else { + lua_CFunction f = ll_sym(L, reg, sym); + if (f == NULL) + return ERRFUNC; /* unable to find function */ + lua_pushcfunction(L, f); /* else create new function */ + return 0; /* no errors */ + } +} + + +static int ll_loadlib (lua_State *L) { + const char *path = luaL_checkstring(L, 1); + const char *init = luaL_checkstring(L, 2); + int stat = ll_loadfunc(L, path, init); + if (stat == 0) /* no errors? */ + return 1; /* return the loaded function */ + else { /* error; error message is on stack top */ + lua_pushnil(L); + lua_insert(L, -2); + lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init"); + return 3; /* return nil, error message, and where */ + } +} + + + +/* +** {====================================================== +** 'require' function +** ======================================================= +*/ + + +static int readable (const char *filename) { + FILE *f = fopen(filename, "r"); /* try to open file */ + if (f == NULL) return 0; /* open failed */ + fclose(f); + return 1; +} + + +static const char *pushnexttemplate (lua_State *L, const char *path) { + const char *l; + while (*path == *LUA_PATH_SEP) path++; /* skip separators */ + if (*path == '\0') return NULL; /* no more templates */ + l = strchr(path, *LUA_PATH_SEP); /* find next separator */ + if (l == NULL) l = path + strlen(path); + lua_pushlstring(L, path, l - path); /* template */ + return l; +} + + +static const char *searchpath (lua_State *L, const char *name, + const char *path, + const char *sep, + const char *dirsep) { + luaL_Buffer msg; /* to build error message */ + luaL_buffinit(L, &msg); + if (*sep != '\0') /* non-empty separator? */ + name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */ + while ((path = pushnexttemplate(L, path)) != NULL) { + const char *filename = luaL_gsub(L, lua_tostring(L, -1), + LUA_PATH_MARK, name); + lua_remove(L, -2); /* remove path template */ + if (readable(filename)) /* does file exist and is readable? */ + return filename; /* return that file name */ + lua_pushfstring(L, "\n\tno file " LUA_QS, filename); + lua_remove(L, -2); /* remove file name */ + luaL_addvalue(&msg); /* concatenate error msg. entry */ + } + luaL_pushresult(&msg); /* create error message */ + return NULL; /* not found */ +} + + +static int ll_searchpath (lua_State *L) { + const char *f = searchpath(L, luaL_checkstring(L, 1), + luaL_checkstring(L, 2), + luaL_optstring(L, 3, "."), + luaL_optstring(L, 4, LUA_DIRSEP)); + if (f != NULL) return 1; + else { /* error message is on top of the stack */ + lua_pushnil(L); + lua_insert(L, -2); + return 2; /* return nil + error message */ + } +} + + +static const char *findfile (lua_State *L, const char *name, + const char *pname, + const char *dirsep) { + const char *path; + lua_getfield(L, lua_upvalueindex(1), pname); + path = lua_tostring(L, -1); + if (path == NULL) + luaL_error(L, LUA_QL("package.%s") " must be a string", pname); + return searchpath(L, name, path, ".", dirsep); +} + + +static int checkload (lua_State *L, int stat, const char *filename) { + if (stat) { /* module loaded successfully? */ + lua_pushstring(L, filename); /* will be 2nd argument to module */ + return 2; /* return open function and file name */ + } + else + return luaL_error(L, "error loading module " LUA_QS + " from file " LUA_QS ":\n\t%s", + lua_tostring(L, 1), filename, lua_tostring(L, -1)); +} + + +static int searcher_Lua (lua_State *L) { + const char *filename; + const char *name = luaL_checkstring(L, 1); + filename = findfile(L, name, "path", LUA_LSUBSEP); + if (filename == NULL) return 1; /* module not found in this path */ + return checkload(L, (luaL_loadfile(L, filename) == LUA_OK), filename); +} + + +static int loadfunc (lua_State *L, const char *filename, const char *modname) { + const char *funcname; + const char *mark; + modname = luaL_gsub(L, modname, ".", LUA_OFSEP); + mark = strchr(modname, *LUA_IGMARK); + if (mark) { + int stat; + funcname = lua_pushlstring(L, modname, mark - modname); + funcname = lua_pushfstring(L, LUA_POF"%s", funcname); + stat = ll_loadfunc(L, filename, funcname); + if (stat != ERRFUNC) return stat; + modname = mark + 1; /* else go ahead and try old-style name */ + } + funcname = lua_pushfstring(L, LUA_POF"%s", modname); + return ll_loadfunc(L, filename, funcname); +} + + +static int searcher_C (lua_State *L) { + const char *name = luaL_checkstring(L, 1); + const char *filename = findfile(L, name, "cpath", LUA_CSUBSEP); + if (filename == NULL) return 1; /* module not found in this path */ + return checkload(L, (loadfunc(L, filename, name) == 0), filename); +} + + +static int searcher_Croot (lua_State *L) { + const char *filename; + const char *name = luaL_checkstring(L, 1); + const char *p = strchr(name, '.'); + int stat; + if (p == NULL) return 0; /* is root */ + lua_pushlstring(L, name, p - name); + filename = findfile(L, lua_tostring(L, -1), "cpath", LUA_CSUBSEP); + if (filename == NULL) return 1; /* root not found */ + if ((stat = loadfunc(L, filename, name)) != 0) { + if (stat != ERRFUNC) + return checkload(L, 0, filename); /* real error */ + else { /* open function not found */ + lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS, + name, filename); + return 1; + } + } + lua_pushstring(L, filename); /* will be 2nd argument to module */ + return 2; +} + + +static int searcher_preload (lua_State *L) { + const char *name = luaL_checkstring(L, 1); + lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD"); + lua_getfield(L, -1, name); + if (lua_isnil(L, -1)) /* not found? */ + lua_pushfstring(L, "\n\tno field package.preload['%s']", name); + return 1; +} + + +static void findloader (lua_State *L, const char *name) { + int i; + luaL_Buffer msg; /* to build error message */ + luaL_buffinit(L, &msg); + lua_getfield(L, lua_upvalueindex(1), "searchers"); /* will be at index 3 */ + if (!lua_istable(L, 3)) + luaL_error(L, LUA_QL("package.searchers") " must be a table"); + /* iterate over available searchers to find a loader */ + for (i = 1; ; i++) { + lua_rawgeti(L, 3, i); /* get a searcher */ + if (lua_isnil(L, -1)) { /* no more searchers? */ + lua_pop(L, 1); /* remove nil */ + luaL_pushresult(&msg); /* create error message */ + luaL_error(L, "module " LUA_QS " not found:%s", + name, lua_tostring(L, -1)); + } + lua_pushstring(L, name); + lua_call(L, 1, 2); /* call it */ + if (lua_isfunction(L, -2)) /* did it find a loader? */ + return; /* module loader found */ + else if (lua_isstring(L, -2)) { /* searcher returned error message? */ + lua_pop(L, 1); /* remove extra return */ + luaL_addvalue(&msg); /* concatenate error message */ + } + else + lua_pop(L, 2); /* remove both returns */ + } +} + + +static int ll_require (lua_State *L) { + const char *name = luaL_checkstring(L, 1); + lua_settop(L, 1); /* _LOADED table will be at index 2 */ + lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); + lua_getfield(L, 2, name); /* _LOADED[name] */ + if (lua_toboolean(L, -1)) /* is it there? */ + return 1; /* package is already loaded */ + /* else must load package */ + lua_pop(L, 1); /* remove 'getfield' result */ + findloader(L, name); + lua_pushstring(L, name); /* pass name as argument to module loader */ + lua_insert(L, -2); /* name is 1st argument (before search data) */ + lua_call(L, 2, 1); /* run loader to load module */ + if (!lua_isnil(L, -1)) /* non-nil return? */ + lua_setfield(L, 2, name); /* _LOADED[name] = returned value */ + lua_getfield(L, 2, name); + if (lua_isnil(L, -1)) { /* module did not set a value? */ + lua_pushboolean(L, 1); /* use true as result */ + lua_pushvalue(L, -1); /* extra copy to be returned */ + lua_setfield(L, 2, name); /* _LOADED[name] = true */ + } + return 1; +} + +/* }====================================================== */ + + + +/* +** {====================================================== +** 'module' function +** ======================================================= +*/ +#if defined(LUA_COMPAT_MODULE) + +/* +** changes the environment variable of calling function +*/ +static void set_env (lua_State *L) { + lua_Debug ar; + if (lua_getstack(L, 1, &ar) == 0 || + lua_getinfo(L, "f", &ar) == 0 || /* get calling function */ + lua_iscfunction(L, -1)) + luaL_error(L, LUA_QL("module") " not called from a Lua function"); + lua_pushvalue(L, -2); /* copy new environment table to top */ + lua_setupvalue(L, -2, 1); + lua_pop(L, 1); /* remove function */ +} + + +static void dooptions (lua_State *L, int n) { + int i; + for (i = 2; i <= n; i++) { + if (lua_isfunction(L, i)) { /* avoid 'calling' extra info. */ + lua_pushvalue(L, i); /* get option (a function) */ + lua_pushvalue(L, -2); /* module */ + lua_call(L, 1, 0); + } + } +} + + +static void modinit (lua_State *L, const char *modname) { + const char *dot; + lua_pushvalue(L, -1); + lua_setfield(L, -2, "_M"); /* module._M = module */ + lua_pushstring(L, modname); + lua_setfield(L, -2, "_NAME"); + dot = strrchr(modname, '.'); /* look for last dot in module name */ + if (dot == NULL) dot = modname; + else dot++; + /* set _PACKAGE as package name (full module name minus last part) */ + lua_pushlstring(L, modname, dot - modname); + lua_setfield(L, -2, "_PACKAGE"); +} + + +static int ll_module (lua_State *L) { + const char *modname = luaL_checkstring(L, 1); + int lastarg = lua_gettop(L); /* last parameter */ + luaL_pushmodule(L, modname, 1); /* get/create module table */ + /* check whether table already has a _NAME field */ + lua_getfield(L, -1, "_NAME"); + if (!lua_isnil(L, -1)) /* is table an initialized module? */ + lua_pop(L, 1); + else { /* no; initialize it */ + lua_pop(L, 1); + modinit(L, modname); + } + lua_pushvalue(L, -1); + set_env(L); + dooptions(L, lastarg); + return 1; +} + + +static int ll_seeall (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + if (!lua_getmetatable(L, 1)) { + lua_createtable(L, 0, 1); /* create new metatable */ + lua_pushvalue(L, -1); + lua_setmetatable(L, 1); + } + lua_pushglobaltable(L); + lua_setfield(L, -2, "__index"); /* mt.__index = _G */ + return 0; +} + +#endif +/* }====================================================== */ + + + +/* auxiliary mark (for internal use) */ +#define AUXMARK "\1" + + +/* +** return registry.LUA_NOENV as a boolean +*/ +static int noenv (lua_State *L) { + int b; + lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); + b = lua_toboolean(L, -1); + lua_pop(L, 1); /* remove value */ + return b; +} + + +static void setpath (lua_State *L, const char *fieldname, const char *envname1, + const char *envname2, const char *def) { + const char *path = getenv(envname1); + if (path == NULL) /* no environment variable? */ + path = getenv(envname2); /* try alternative name */ + if (path == NULL || noenv(L)) /* no environment variable? */ + lua_pushstring(L, def); /* use default */ + else { + /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */ + path = luaL_gsub(L, path, LUA_PATH_SEP LUA_PATH_SEP, + LUA_PATH_SEP AUXMARK LUA_PATH_SEP); + luaL_gsub(L, path, AUXMARK, def); + lua_remove(L, -2); + } + setprogdir(L); + lua_setfield(L, -2, fieldname); +} + + +static const luaL_Reg pk_funcs[] = { + {"loadlib", ll_loadlib}, + {"searchpath", ll_searchpath}, +#if defined(LUA_COMPAT_MODULE) + {"seeall", ll_seeall}, +#endif + {NULL, NULL} +}; + + +static const luaL_Reg ll_funcs[] = { +#if defined(LUA_COMPAT_MODULE) + {"module", ll_module}, +#endif + {"require", ll_require}, + {NULL, NULL} +}; + + +static void createsearcherstable (lua_State *L) { + static const lua_CFunction searchers[] = + {searcher_preload, searcher_Lua, searcher_C, searcher_Croot, NULL}; + int i; + /* create 'searchers' table */ + lua_createtable(L, sizeof(searchers)/sizeof(searchers[0]) - 1, 0); + /* fill it with pre-defined searchers */ + for (i=0; searchers[i] != NULL; i++) { + lua_pushvalue(L, -2); /* set 'package' as upvalue for all searchers */ + lua_pushcclosure(L, searchers[i], 1); + lua_rawseti(L, -2, i+1); + } +} + + +LUAMOD_API int luaopen_package (lua_State *L) { + /* create table CLIBS to keep track of loaded C libraries */ + luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS); + lua_createtable(L, 0, 1); /* metatable for CLIBS */ + lua_pushcfunction(L, gctm); + lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */ + lua_setmetatable(L, -2); + /* create `package' table */ + luaL_newlib(L, pk_funcs); + createsearcherstable(L); +#if defined(LUA_COMPAT_LOADERS) + lua_pushvalue(L, -1); /* make a copy of 'searchers' table */ + lua_setfield(L, -3, "loaders"); /* put it in field `loaders' */ +#endif + lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */ + /* set field 'path' */ + setpath(L, "path", LUA_PATHVERSION, LUA_PATH, LUA_PATH_DEFAULT); + /* set field 'cpath' */ + setpath(L, "cpath", LUA_CPATHVERSION, LUA_CPATH, LUA_CPATH_DEFAULT); + /* store config information */ + lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n" + LUA_EXEC_DIR "\n" LUA_IGMARK "\n"); + lua_setfield(L, -2, "config"); + /* set field `loaded' */ + luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); + lua_setfield(L, -2, "loaded"); + /* set field `preload' */ + luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); + lua_setfield(L, -2, "preload"); + lua_pushglobaltable(L); + lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */ + luaL_setfuncs(L, ll_funcs, 1); /* open lib into global table */ + lua_pop(L, 1); /* pop global table */ + return 1; /* return 'package' table */ +} + diff --git a/src/lua.hpp b/src/lua.hpp new file mode 100644 index 0000000000..ec417f5946 --- /dev/null +++ b/src/lua.hpp @@ -0,0 +1,9 @@ +// lua.hpp +// Lua header files for C++ +// <> not supplied automatically because Lua also compiles as C++ + +extern "C" { +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" +} diff --git a/src/lua.rc b/src/lua.rc new file mode 100644 index 0000000000..8e392cc4fc --- /dev/null +++ b/src/lua.rc @@ -0,0 +1,28 @@ +0 ICON "../etc/lua_lang.ico" + +1 VERSIONINFO + FILEVERSION 5,2,3,0 + PRODUCTVERSION 5,2,3,0 +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "www.lua.org\0" + VALUE "CompanyName", "Lua.org\0" + VALUE "FileDescription", "Lua Standalone Interpreter\0" + VALUE "FileVersion", "5.2.3\0" + VALUE "LegalCopyright", "Copyright © 1994-2013 Lua.org, PUC-Rio.\0" + VALUE "OriginalFilename", "lua.exe\0" + VALUE "ProductName", "Lua - The Programming Language\0" + VALUE "ProductVersion", "5.2.3\0" + VALUE "PrivateBuild", "Built using LuaDist\0" + END + END +END + +#ifdef MSVC8 +1 24 "lua_dll8.manifest" +#elif MSVC9 +1 24 "lua_dll9.manifest" +#endif diff --git a/src/luac.c b/src/luac.c new file mode 100644 index 0000000000..7409706ec7 --- /dev/null +++ b/src/luac.c @@ -0,0 +1,432 @@ +/* +** $Id: luac.c,v 1.69 2011/11/29 17:46:33 lhf Exp $ +** Lua compiler (saves bytecodes to files; also list bytecodes) +** See Copyright Notice in lua.h +*/ + +#include +#include +#include +#include + +#define luac_c +#define LUA_CORE + +#include "lua.h" +#include "lauxlib.h" + +#include "lobject.h" +#include "lstate.h" +#include "lundump.h" + +static void PrintFunction(const Proto* f, int full); +#define luaU_print PrintFunction + +#define PROGNAME "luac" /* default program name */ +#define OUTPUT PROGNAME ".out" /* default output file */ + +static int listing=0; /* list bytecodes? */ +static int dumping=1; /* dump bytecodes? */ +static int stripping=0; /* strip debug information? */ +static char Output[]={ OUTPUT }; /* default output file name */ +static const char* output=Output; /* actual output file name */ +static const char* progname=PROGNAME; /* actual program name */ + +static void fatal(const char* message) +{ + fprintf(stderr,"%s: %s\n",progname,message); + exit(EXIT_FAILURE); +} + +static void cannot(const char* what) +{ + fprintf(stderr,"%s: cannot %s %s: %s\n",progname,what,output,strerror(errno)); + exit(EXIT_FAILURE); +} + +static void usage(const char* message) +{ + if (*message=='-') + fprintf(stderr,"%s: unrecognized option " LUA_QS "\n",progname,message); + else + fprintf(stderr,"%s: %s\n",progname,message); + fprintf(stderr, + "usage: %s [options] [filenames]\n" + "Available options are:\n" + " -l list (use -l -l for full listing)\n" + " -o name output to file " LUA_QL("name") " (default is \"%s\")\n" + " -p parse only\n" + " -s strip debug information\n" + " -v show version information\n" + " -- stop handling options\n" + " - stop handling options and process stdin\n" + ,progname,Output); + exit(EXIT_FAILURE); +} + +#define IS(s) (strcmp(argv[i],s)==0) + +static int doargs(int argc, char* argv[]) +{ + int i; + int version=0; + if (argv[0]!=NULL && *argv[0]!=0) progname=argv[0]; + for (i=1; itop+(i)) + +static const Proto* combine(lua_State* L, int n) +{ + if (n==1) + return toproto(L,-1); + else + { + Proto* f; + int i=n; + if (lua_load(L,reader,&i,"=(" PROGNAME ")",NULL)!=LUA_OK) fatal(lua_tostring(L,-1)); + f=toproto(L,-1); + for (i=0; ip[i]=toproto(L,i-n-1); + if (f->p[i]->sizeupvalues>0) f->p[i]->upvalues[0].instack=0; + } + f->sizelineinfo=0; + return f; + } +} + +static int writer(lua_State* L, const void* p, size_t size, void* u) +{ + UNUSED(L); + return (fwrite(p,size,1,(FILE*)u)!=1) && (size!=0); +} + +static int pmain(lua_State* L) +{ + int argc=(int)lua_tointeger(L,1); + char** argv=(char**)lua_touserdata(L,2); + const Proto* f; + int i; + if (!lua_checkstack(L,argc)) fatal("too many input files"); + for (i=0; i1); + if (dumping) + { + FILE* D= (output==NULL) ? stdout : fopen(output,"wb"); + if (D==NULL) cannot("open"); + lua_lock(L); + luaU_dump(L,f,writer,D,stripping); + lua_unlock(L); + if (ferror(D)) cannot("write"); + if (fclose(D)) cannot("close"); + } + return 0; +} + +int main(int argc, char* argv[]) +{ + lua_State* L; + int i=doargs(argc,argv); + argc-=i; argv+=i; + if (argc<=0) usage("no input files given"); + L=luaL_newstate(); + if (L==NULL) fatal("cannot create state: not enough memory"); + lua_pushcfunction(L,&pmain); + lua_pushinteger(L,argc); + lua_pushlightuserdata(L,argv); + if (lua_pcall(L,2,0,0)!=LUA_OK) fatal(lua_tostring(L,-1)); + lua_close(L); + return EXIT_SUCCESS; +} + +/* +** $Id: print.c,v 1.69 2013/07/04 01:03:46 lhf Exp $ +** print bytecodes +** See Copyright Notice in lua.h +*/ + +#include +#include + +#define luac_c +#define LUA_CORE + +#include "ldebug.h" +#include "lobject.h" +#include "lopcodes.h" + +#define VOID(p) ((const void*)(p)) + +static void PrintString(const TString* ts) +{ + const char* s=getstr(ts); + size_t i,n=ts->tsv.len; + printf("%c",'"'); + for (i=0; ik[i]; + switch (ttypenv(o)) + { + case LUA_TNIL: + printf("nil"); + break; + case LUA_TBOOLEAN: + printf(bvalue(o) ? "true" : "false"); + break; + case LUA_TNUMBER: + printf(LUA_NUMBER_FMT,nvalue(o)); + break; + case LUA_TSTRING: + PrintString(rawtsvalue(o)); + break; + default: /* cannot happen */ + printf("? type=%d",ttype(o)); + break; + } +} + +#define UPVALNAME(x) ((f->upvalues[x].name) ? getstr(f->upvalues[x].name) : "-") +#define MYK(x) (-1-(x)) + +static void PrintCode(const Proto* f) +{ + const Instruction* code=f->code; + int pc,n=f->sizecode; + for (pc=0; pc0) printf("[%d]\t",line); else printf("[-]\t"); + printf("%-9s\t",luaP_opnames[o]); + switch (getOpMode(o)) + { + case iABC: + printf("%d",a); + if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (MYK(INDEXK(b))) : b); + if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (MYK(INDEXK(c))) : c); + break; + case iABx: + printf("%d",a); + if (getBMode(o)==OpArgK) printf(" %d",MYK(bx)); + if (getBMode(o)==OpArgU) printf(" %d",bx); + break; + case iAsBx: + printf("%d %d",a,sbx); + break; + case iAx: + printf("%d",MYK(ax)); + break; + } + switch (o) + { + case OP_LOADK: + printf("\t; "); PrintConstant(f,bx); + break; + case OP_GETUPVAL: + case OP_SETUPVAL: + printf("\t; %s",UPVALNAME(b)); + break; + case OP_GETTABUP: + printf("\t; %s",UPVALNAME(b)); + if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); } + break; + case OP_SETTABUP: + printf("\t; %s",UPVALNAME(a)); + if (ISK(b)) { printf(" "); PrintConstant(f,INDEXK(b)); } + if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); } + break; + case OP_GETTABLE: + case OP_SELF: + if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); } + break; + case OP_SETTABLE: + case OP_ADD: + case OP_SUB: + case OP_MUL: + case OP_DIV: + case OP_POW: + case OP_EQ: + case OP_LT: + case OP_LE: + if (ISK(b) || ISK(c)) + { + printf("\t; "); + if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-"); + printf(" "); + if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-"); + } + break; + case OP_JMP: + case OP_FORLOOP: + case OP_FORPREP: + case OP_TFORLOOP: + printf("\t; to %d",sbx+pc+2); + break; + case OP_CLOSURE: + printf("\t; %p",VOID(f->p[bx])); + break; + case OP_SETLIST: + if (c==0) printf("\t; %d",(int)code[++pc]); else printf("\t; %d",c); + break; + case OP_EXTRAARG: + printf("\t; "); PrintConstant(f,ax); + break; + default: + break; + } + printf("\n"); + } +} + +#define SS(x) ((x==1)?"":"s") +#define S(x) (int)(x),SS(x) + +static void PrintHeader(const Proto* f) +{ + const char* s=f->source ? getstr(f->source) : "=?"; + if (*s=='@' || *s=='=') + s++; + else if (*s==LUA_SIGNATURE[0]) + s="(bstring)"; + else + s="(string)"; + printf("\n%s <%s:%d,%d> (%d instruction%s at %p)\n", + (f->linedefined==0)?"main":"function",s, + f->linedefined,f->lastlinedefined, + S(f->sizecode),VOID(f)); + printf("%d%s param%s, %d slot%s, %d upvalue%s, ", + (int)(f->numparams),f->is_vararg?"+":"",SS(f->numparams), + S(f->maxstacksize),S(f->sizeupvalues)); + printf("%d local%s, %d constant%s, %d function%s\n", + S(f->sizelocvars),S(f->sizek),S(f->sizep)); +} + +static void PrintDebug(const Proto* f) +{ + int i,n; + n=f->sizek; + printf("constants (%d) for %p:\n",n,VOID(f)); + for (i=0; isizelocvars; + printf("locals (%d) for %p:\n",n,VOID(f)); + for (i=0; ilocvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1); + } + n=f->sizeupvalues; + printf("upvalues (%d) for %p:\n",n,VOID(f)); + for (i=0; iupvalues[i].instack,f->upvalues[i].idx); + } +} + +static void PrintFunction(const Proto* f, int full) +{ + int i,n=f->sizep; + PrintHeader(f); + PrintCode(f); + if (full) PrintDebug(f); + for (i=0; ip[i],full); +} diff --git a/src/luac.rc b/src/luac.rc new file mode 100644 index 0000000000..c21630e1e5 --- /dev/null +++ b/src/luac.rc @@ -0,0 +1,28 @@ +0 ICON "../etc/lua.ico" + +1 VERSIONINFO + FILEVERSION 5,2,3,0 + PRODUCTVERSION 5,2,3,0 +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "www.lua.org\0" + VALUE "CompanyName", "Lua.org\0" + VALUE "FileDescription", "Lua Compiler\0" + VALUE "FileVersion", "5.2.3\0" + VALUE "LegalCopyright", "Copyright © 1994-2013 Lua.org, PUC-Rio.\0" + VALUE "OriginalFilename", "luac.exe\0" + VALUE "ProductName", "Lua - The Programming Language\0" + VALUE "ProductVersion", "5.2.3\0" + VALUE "PrivateBuild", "Built using LuaDist\0" + END + END +END + +#ifdef MSVC8 +1 24 "lua_dll8.manifest" +#elif MSVC9 +1 24 "lua_dll9.manifest" +#endif diff --git a/src/luaconf.h.in b/src/luaconf.h.in new file mode 100644 index 0000000000..a3f46b353f --- /dev/null +++ b/src/luaconf.h.in @@ -0,0 +1,497 @@ +/* +** $Id: luaconf.h,v 1.176.1.1 2013/04/12 18:48:47 roberto Exp $ +** Configuration file for Lua +** See Copyright Notice in lua.h +*/ + + +#ifndef lconfig_h +#define lconfig_h + +#include +#include + + +/* +** ================================================================== +** Search for "@@" to find all configurable definitions. +** =================================================================== +*/ + + +/* +@@ LUA_ANSI controls the use of non-ansi features. +** CHANGE it (define it) if you want Lua to avoid the use of any +** non-ansi feature or library. +*/ +#cmakedefine LUA_ANSI +#cmakedefine LUA_WIN + +#if defined(LUA_WIN) +#define LUA_DL_DLL +#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */ +#endif + +#cmakedefine LUA_USE_POSIX +#cmakedefine LUA_USE_DLOPEN /* needs an extra library: -ldl */ +#cmakedefine LUA_USE_READLINE /* needs some extra libraries */ +#cmakedefine LUA_USE_STRTODHEX /* assume 'strtod' handles hexa formats */ +#cmakedefine LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */ +#cmakedefine LUA_USE_LONGLONG /* assume support for long long */ +#cmakedefine LUA_USE_MKSTEMP +#cmakedefine LUA_USE_ISATTY +#cmakedefine LUA_USE_POPEN +#cmakedefine LUA_USE_ULONGJMP + + +/* +@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for +@* Lua libraries. +@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for +@* C libraries. +** CHANGE them if your machine has a non-conventional directory +** hierarchy or if you want to install your libraries in +** non-conventional directories. +*/ +#cmakedefine LUA_MODULE_SUFFIX "@LUA_MODULE_SUFFIX@" +#cmakedefine LUA_DIR "@LUA_DIR@" +#cmakedefine LUA_LDIR "@LUA_LDIR@" +#cmakedefine LUA_CDIR "@LUA_CDIR@" + +#define LUA_PATH_DEFAULT "@LUA_PATH_DEFAULT@" +#define LUA_CPATH_DEFAULT "@LUA_CPATH_DEFAULT@" + +/* +@@ LUA_DIRSEP is the directory separator (for submodules). +** CHANGE it if your machine does not use "/" as the directory separator +** and is not Windows. (On Windows Lua automatically uses "\".) +*/ +#cmakedefine LUA_DIRSEP "@LUA_DIRSEP@" + +/* +@@ LUA_ENV is the name of the variable that holds the current +@@ environment, used to access global names. +** CHANGE it if you do not like this name. +*/ +#define LUA_ENV "_ENV" + + +/* +@@ LUA_API is a mark for all core API functions. +@@ LUALIB_API is a mark for all auxiliary library functions. +@@ LUAMOD_API is a mark for all standard library opening functions. +** CHANGE them if you need to define those functions in some special way. +** For instance, if you want to create one Windows DLL with the core and +** the libraries, you may want to use the following definition (define +** LUA_BUILD_AS_DLL to get it). +*/ +#if defined(LUA_BUILD_AS_DLL) /* { */ + +#if defined(LUA_CORE) || defined(LUA_LIB) /* { */ +#define LUA_API __declspec(dllexport) +#else /* }{ */ +#define LUA_API __declspec(dllimport) +#endif /* } */ + +#else /* }{ */ + +#define LUA_API extern + +#endif /* } */ + + +/* more often than not the libs go together with the core */ +#define LUALIB_API LUA_API +#define LUAMOD_API LUALIB_API + + +/* +@@ LUAI_FUNC is a mark for all extern functions that are not to be +@* exported to outside modules. +@@ LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables +@* that are not to be exported to outside modules (LUAI_DDEF for +@* definitions and LUAI_DDEC for declarations). +** CHANGE them if you need to mark them in some special way. Elf/gcc +** (versions 3.2 and later) mark them as "hidden" to optimize access +** when Lua is compiled as a shared library. Not all elf targets support +** this attribute. Unfortunately, gcc does not offer a way to check +** whether the target offers that support, and those without support +** give a warning about it. To avoid these warnings, change to the +** default definition. +*/ +#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ + defined(__ELF__) /* { */ +#define LUAI_FUNC __attribute__((visibility("hidden"))) extern +#define LUAI_DDEC LUAI_FUNC +#define LUAI_DDEF /* empty */ + +#else /* }{ */ +#define LUAI_FUNC extern +#define LUAI_DDEC extern +#define LUAI_DDEF /* empty */ +#endif /* } */ + + + +/* +@@ LUA_QL describes how error messages quote program elements. +** CHANGE it if you want a different appearance. +*/ +#define LUA_QL(x) "'" x "'" +#define LUA_QS LUA_QL("%s") + + +/* +@@ LUA_IDSIZE gives the maximum size for the description of the source +@* of a function in debug information. +** CHANGE it if you want a different size. +*/ +#define LUA_IDSIZE 60 + + +/* +@@ luai_writestring/luai_writeline define how 'print' prints its results. +** They are only used in libraries and the stand-alone program. (The #if +** avoids including 'stdio.h' everywhere.) +*/ +#if defined(LUA_LIB) || defined(lua_c) +#include +#define luai_writestring(s,l) fwrite((s), sizeof(char), (l), stdout) +#define luai_writeline() (luai_writestring("\n", 1), fflush(stdout)) +#endif + +/* +@@ luai_writestringerror defines how to print error messages. +** (A format string with one argument is enough for Lua...) +*/ +#define luai_writestringerror(s,p) \ + (fprintf(stderr, (s), (p)), fflush(stderr)) + + +/* +@@ LUAI_MAXSHORTLEN is the maximum length for short strings, that is, +** strings that are internalized. (Cannot be smaller than reserved words +** or tags for metamethods, as these strings must be internalized; +** #("function") = 8, #("__newindex") = 10.) +*/ +#define LUAI_MAXSHORTLEN 40 + + + +/* +** {================================================================== +** Compatibility with previous versions +** =================================================================== +*/ + +/* +@@ LUA_COMPAT_ALL controls all compatibility options. +** You can define it to get all options, or change specific options +** to fit your specific needs. +*/ +#cmakedefine LUA_COMPAT_ALL +#if defined(LUA_COMPAT_ALL) /* { */ + +/* +@@ LUA_COMPAT_UNPACK controls the presence of global 'unpack'. +** You can replace it with 'table.unpack'. +*/ +#define LUA_COMPAT_UNPACK + +/* +@@ LUA_COMPAT_LOADERS controls the presence of table 'package.loaders'. +** You can replace it with 'package.searchers'. +*/ +#define LUA_COMPAT_LOADERS + +/* +@@ macro 'lua_cpcall' emulates deprecated function lua_cpcall. +** You can call your C function directly (with light C functions). +*/ +#define lua_cpcall(L,f,u) \ + (lua_pushcfunction(L, (f)), \ + lua_pushlightuserdata(L,(u)), \ + lua_pcall(L,1,0,0)) + + +/* +@@ LUA_COMPAT_LOG10 defines the function 'log10' in the math library. +** You can rewrite 'log10(x)' as 'log(x, 10)'. +*/ +#define LUA_COMPAT_LOG10 + +/* +@@ LUA_COMPAT_LOADSTRING defines the function 'loadstring' in the base +** library. You can rewrite 'loadstring(s)' as 'load(s)'. +*/ +#define LUA_COMPAT_LOADSTRING + +/* +@@ LUA_COMPAT_MAXN defines the function 'maxn' in the table library. +*/ +#define LUA_COMPAT_MAXN + +/* +@@ The following macros supply trivial compatibility for some +** changes in the API. The macros themselves document how to +** change your code to avoid using them. +*/ +#define lua_strlen(L,i) lua_rawlen(L, (i)) + +#define lua_objlen(L,i) lua_rawlen(L, (i)) + +#define lua_equal(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPEQ) +#define lua_lessthan(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPLT) + +/* +@@ LUA_COMPAT_MODULE controls compatibility with previous +** module functions 'module' (Lua) and 'luaL_register' (C). +*/ +#define LUA_COMPAT_MODULE + +#endif /* } */ + +/* }================================================================== */ + + + +/* +@@ LUAI_BITSINT defines the number of bits in an int. +** CHANGE here if Lua cannot automatically detect the number of bits of +** your machine. Probably you do not need to change this. +*/ +/* avoid overflows in comparison */ +#if INT_MAX-20 < 32760 /* { */ +#define LUAI_BITSINT 16 +#elif INT_MAX > 2147483640L /* }{ */ +/* int has at least 32 bits */ +#define LUAI_BITSINT 32 +#else /* }{ */ +#error "you must define LUA_BITSINT with number of bits in an integer" +#endif /* } */ + + +/* +@@ LUA_INT32 is an signed integer with exactly 32 bits. +@@ LUAI_UMEM is an unsigned integer big enough to count the total +@* memory used by Lua. +@@ LUAI_MEM is a signed integer big enough to count the total memory +@* used by Lua. +** CHANGE here if for some weird reason the default definitions are not +** good enough for your machine. Probably you do not need to change +** this. +*/ +#if LUAI_BITSINT >= 32 /* { */ +#define LUA_INT32 int +#define LUAI_UMEM size_t +#define LUAI_MEM ptrdiff_t +#else /* }{ */ +/* 16-bit ints */ +#define LUA_INT32 long +#define LUAI_UMEM unsigned long +#define LUAI_MEM long +#endif /* } */ + + +/* +@@ LUAI_MAXSTACK limits the size of the Lua stack. +** CHANGE it if you need a different limit. This limit is arbitrary; +** its only purpose is to stop Lua to consume unlimited stack +** space (and to reserve some numbers for pseudo-indices). +*/ +#if LUAI_BITSINT >= 32 +#define LUAI_MAXSTACK 1000000 +#else +#define LUAI_MAXSTACK 15000 +#endif + +/* reserve some space for error handling */ +#define LUAI_FIRSTPSEUDOIDX (-LUAI_MAXSTACK - 1000) + + + + +/* +@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. +** CHANGE it if it uses too much C-stack space. +*/ +#define LUAL_BUFFERSIZE BUFSIZ + + + + +/* +** {================================================================== +@@ LUA_NUMBER is the type of numbers in Lua. +** CHANGE the following definitions only if you want to build Lua +** with a number type different from double. You may also need to +** change lua_number2int & lua_number2integer. +** =================================================================== +*/ + +#define LUA_NUMBER_DOUBLE +#define LUA_NUMBER double + +/* +@@ LUAI_UACNUMBER is the result of an 'usual argument conversion' +@* over a number. +*/ +#define LUAI_UACNUMBER double + + +/* +@@ LUA_NUMBER_SCAN is the format for reading numbers. +@@ LUA_NUMBER_FMT is the format for writing numbers. +@@ lua_number2str converts a number to a string. +@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion. +*/ +#define LUA_NUMBER_SCAN "%lf" +#define LUA_NUMBER_FMT "%.14g" +#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) +#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ + + +/* +@@ l_mathop allows the addition of an 'l' or 'f' to all math operations +*/ +#define l_mathop(x) (x) + + +/* +@@ lua_str2number converts a decimal numeric string to a number. +@@ lua_strx2number converts an hexadecimal numeric string to a number. +** In C99, 'strtod' does both conversions. C89, however, has no function +** to convert floating hexadecimal strings to numbers. For these +** systems, you can leave 'lua_strx2number' undefined and Lua will +** provide its own implementation. +*/ +#define lua_str2number(s,p) strtod((s), (p)) + +#if defined(LUA_USE_STRTODHEX) +#define lua_strx2number(s,p) strtod((s), (p)) +#endif + + +/* +@@ The luai_num* macros define the primitive operations over numbers. +*/ + +/* the following operations need the math library */ +#if defined(lobject_c) || defined(lvm_c) +#include +#define luai_nummod(L,a,b) ((a) - l_mathop(floor)((a)/(b))*(b)) +#define luai_numpow(L,a,b) (l_mathop(pow)(a,b)) +#endif + +/* these are quite standard operations */ +#if defined(LUA_CORE) +#define luai_numadd(L,a,b) ((a)+(b)) +#define luai_numsub(L,a,b) ((a)-(b)) +#define luai_nummul(L,a,b) ((a)*(b)) +#define luai_numdiv(L,a,b) ((a)/(b)) +#define luai_numunm(L,a) (-(a)) +#define luai_numeq(a,b) ((a)==(b)) +#define luai_numlt(L,a,b) ((a)<(b)) +#define luai_numle(L,a,b) ((a)<=(b)) +#define luai_numisnan(L,a) (!luai_numeq((a), (a))) +#endif + + + +/* +@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger. +** CHANGE that if ptrdiff_t is not adequate on your machine. (On most +** machines, ptrdiff_t gives a good choice between int or long.) +*/ +#define LUA_INTEGER ptrdiff_t + +/* +@@ LUA_UNSIGNED is the integral type used by lua_pushunsigned/lua_tounsigned. +** It must have at least 32 bits. +*/ +#define LUA_UNSIGNED unsigned LUA_INT32 + + + +/* +** Some tricks with doubles +*/ + +#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) /* { */ +/* +** The next definitions activate some tricks to speed up the +** conversion from doubles to integer types, mainly to LUA_UNSIGNED. +** +@@ LUA_MSASMTRICK uses Microsoft assembler to avoid clashes with a +** DirectX idiosyncrasy. +** +@@ LUA_IEEE754TRICK uses a trick that should work on any machine +** using IEEE754 with a 32-bit integer type. +** +@@ LUA_IEEELL extends the trick to LUA_INTEGER; should only be +** defined when LUA_INTEGER is a 32-bit integer. +** +@@ LUA_IEEEENDIAN is the endianness of doubles in your machine +** (0 for little endian, 1 for big endian); if not defined, Lua will +** check it dynamically for LUA_IEEE754TRICK (but not for LUA_NANTRICK). +** +@@ LUA_NANTRICK controls the use of a trick to pack all types into +** a single double value, using NaN values to represent non-number +** values. The trick only works on 32-bit machines (ints and pointers +** are 32-bit values) with numbers represented as IEEE 754-2008 doubles +** with conventional endianess (12345678 or 87654321), in CPUs that do +** not produce signaling NaN values (all NaNs are quiet). +*/ + +/* Microsoft compiler on a Pentium (32 bit) ? */ +#if defined(LUA_WIN) && defined(_MSC_VER) && defined(_M_IX86) /* { */ + +#define LUA_MSASMTRICK +#define LUA_IEEEENDIAN 0 +#define LUA_NANTRICK + + +/* pentium 32 bits? */ +#elif defined(__i386__) || defined(__i386) || defined(__X86__) /* }{ */ + +#define LUA_IEEE754TRICK +#define LUA_IEEELL +#define LUA_IEEEENDIAN 0 +#define LUA_NANTRICK + +/* pentium 64 bits? */ +#elif defined(__x86_64) /* }{ */ + +#define LUA_IEEE754TRICK +#define LUA_IEEEENDIAN 0 + +#elif defined(__POWERPC__) || defined(__ppc__) /* }{ */ + +#define LUA_IEEE754TRICK +#define LUA_IEEEENDIAN 1 + +#else /* }{ */ + +/* assume IEEE754 and a 32-bit integer type */ +#define LUA_IEEE754TRICK + +#endif /* } */ + +#endif /* } */ + +/* }================================================================== */ + + + + +/* =================================================================== */ + +/* +** Local configuration. You can use this space to add your redefinitions +** without modifying the main part of the file. +*/ + + + +#endif + diff --git a/src/wmain.c b/src/wmain.c new file mode 100644 index 0000000000..6cf3e57973 --- /dev/null +++ b/src/wmain.c @@ -0,0 +1,16 @@ +#include +#include /* declaration of __argc and __argv */ + +extern int main(int, char **); + +int PASCAL WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR cmdline, int ncmdshow) +{ + int rc; + + extern int __argc; /* this seems to work for all the compilers we tested, except Watcom compilers */ + extern char** __argv; + + rc = main(__argc, __argv); + + return rc; +} From 72bbfe147d6951ea220a00ec567c825ff4c3a0ec Mon Sep 17 00:00:00 2001 From: Scott M Anderson Date: Mon, 17 Nov 2025 17:16:30 -0700 Subject: [PATCH 05/14] copy doc/ files from LuaDist fork (externpro-archive/lua) https://github.com/externpro-archive/lua/tree/5bbd21fbb20ffcea435ae45593f4e7dfac03e0f4/doc --- doc/contents.html | 533 ++ doc/logo.gif | Bin 0 -> 4232 bytes doc/lua.1 | 116 + doc/lua.css | 96 + doc/luac.1 | 118 + doc/manual.css | 27 + doc/manual.html | 10507 ++++++++++++++++++++++++++++++++++ doc/osi-certified-72x60.png | Bin 0 -> 3774 bytes doc/readme.html | 413 ++ 9 files changed, 11810 insertions(+) create mode 100644 doc/contents.html create mode 100644 doc/logo.gif create mode 100644 doc/lua.1 create mode 100644 doc/lua.css create mode 100644 doc/luac.1 create mode 100644 doc/manual.css create mode 100644 doc/manual.html create mode 100644 doc/osi-certified-72x60.png create mode 100644 doc/readme.html diff --git a/doc/contents.html b/doc/contents.html new file mode 100644 index 0000000000..0ce297da19 --- /dev/null +++ b/doc/contents.html @@ -0,0 +1,533 @@ + + + +Lua 5.2 Reference Manual - contents + + + + + + + +
    +

    + +Lua 5.2 Reference Manual +

    + +

    +The reference manual is the official definition of the Lua language. +For a complete introduction to Lua programming, see the book +Programming in Lua. + +

    +start +· +contents +· +index +


    + +Copyright © 2011–2013 Lua.org, PUC-Rio. +Freely available under the terms of the +Lua license. + + +

    Contents

    + + +

    Index

    + + + + + + + +
    +

    Lua functions

    +

    +_G
    +_VERSION
    + +

    +assert
    +collectgarbage
    +dofile
    +error
    +getmetatable
    +ipairs
    +load
    +loadfile
    +next
    +pairs
    +pcall
    +print
    +rawequal
    +rawget
    +rawlen
    +rawset
    +require
    +select
    +setmetatable
    +tonumber
    +tostring
    +type
    +xpcall
    + +

    +bit32.arshift
    +bit32.band
    +bit32.bnot
    +bit32.bor
    +bit32.btest
    +bit32.bxor
    +bit32.extract
    +bit32.lrotate
    +bit32.lshift
    +bit32.replace
    +bit32.rrotate
    +bit32.rshift
    + +

    +coroutine.create
    +coroutine.resume
    +coroutine.running
    +coroutine.status
    +coroutine.wrap
    +coroutine.yield
    + +

    +debug.debug
    +debug.getuservalue
    +debug.gethook
    +debug.getinfo
    +debug.getlocal
    +debug.getmetatable
    +debug.getregistry
    +debug.getupvalue
    +debug.setuservalue
    +debug.sethook
    +debug.setlocal
    +debug.setmetatable
    +debug.setupvalue
    +debug.traceback
    +debug.upvalueid
    +debug.upvaluejoin
    + +

    +file:close
    +file:flush
    +file:lines
    +file:read
    +file:seek
    +file:setvbuf
    +file:write
    + +

    +io.close
    +io.flush
    +io.input
    +io.lines
    +io.open
    +io.output
    +io.popen
    +io.read
    +io.stderr
    +io.stdin
    +io.stdout
    +io.tmpfile
    +io.type
    +io.write
    + +

    +

     

    +

    +math.abs
    +math.acos
    +math.asin
    +math.atan
    +math.atan2
    +math.ceil
    +math.cos
    +math.cosh
    +math.deg
    +math.exp
    +math.floor
    +math.fmod
    +math.frexp
    +math.huge
    +math.ldexp
    +math.log
    +math.max
    +math.min
    +math.modf
    +math.pi
    +math.pow
    +math.rad
    +math.random
    +math.randomseed
    +math.sin
    +math.sinh
    +math.sqrt
    +math.tan
    +math.tanh
    + +

    +os.clock
    +os.date
    +os.difftime
    +os.execute
    +os.exit
    +os.getenv
    +os.remove
    +os.rename
    +os.setlocale
    +os.time
    +os.tmpname
    + +

    +package.config
    +package.cpath
    +package.loaded
    +package.loadlib
    +package.path
    +package.preload
    +package.searchers
    +package.searchpath
    + +

    +string.byte
    +string.char
    +string.dump
    +string.find
    +string.format
    +string.gmatch
    +string.gsub
    +string.len
    +string.lower
    +string.match
    +string.rep
    +string.reverse
    +string.sub
    +string.upper
    + +

    +table.concat
    +table.insert
    +table.pack
    +table.remove
    +table.sort
    +table.unpack
    + +

    +

    C API

    +

    +lua_Alloc
    +lua_CFunction
    +lua_Debug
    +lua_Hook
    +lua_Integer
    +lua_Number
    +lua_Reader
    +lua_State
    +lua_Unsigned
    +lua_Writer
    + +

    +lua_absindex
    +lua_arith
    +lua_atpanic
    +lua_call
    +lua_callk
    +lua_checkstack
    +lua_close
    +lua_compare
    +lua_concat
    +lua_copy
    +lua_createtable
    +lua_dump
    +lua_error
    +lua_gc
    +lua_getallocf
    +lua_getctx
    +lua_getfield
    +lua_getglobal
    +lua_gethook
    +lua_gethookcount
    +lua_gethookmask
    +lua_getinfo
    +lua_getlocal
    +lua_getmetatable
    +lua_getstack
    +lua_gettable
    +lua_gettop
    +lua_getupvalue
    +lua_getuservalue
    +lua_insert
    +lua_isboolean
    +lua_iscfunction
    +lua_isfunction
    +lua_islightuserdata
    +lua_isnil
    +lua_isnone
    +lua_isnoneornil
    +lua_isnumber
    +lua_isstring
    +lua_istable
    +lua_isthread
    +lua_isuserdata
    +lua_len
    +lua_load
    +lua_newstate
    +lua_newtable
    +lua_newthread
    +lua_newuserdata
    +lua_next
    +lua_pcall
    +lua_pcallk
    +lua_pop
    +lua_pushboolean
    +lua_pushcclosure
    +lua_pushcfunction
    +lua_pushfstring
    +lua_pushglobaltable
    +lua_pushinteger
    +lua_pushlightuserdata
    +lua_pushliteral
    +lua_pushlstring
    +lua_pushnil
    +lua_pushnumber
    +lua_pushstring
    +lua_pushthread
    +lua_pushunsigned
    +lua_pushvalue
    +lua_pushvfstring
    +lua_rawequal
    +lua_rawget
    +lua_rawgeti
    +lua_rawgetp
    +lua_rawlen
    +lua_rawset
    +lua_rawseti
    +lua_rawsetp
    +lua_register
    +lua_remove
    +lua_replace
    +lua_resume
    +lua_setallocf
    +lua_setfield
    +lua_setglobal
    +lua_sethook
    +lua_setlocal
    +lua_setmetatable
    +lua_settable
    +lua_settop
    +lua_setupvalue
    +lua_setuservalue
    +lua_status
    +lua_toboolean
    +lua_tocfunction
    +lua_tointeger
    +lua_tointegerx
    +lua_tolstring
    +lua_tonumber
    +lua_tonumberx
    +lua_topointer
    +lua_tostring
    +lua_tothread
    +lua_tounsigned
    +lua_tounsignedx
    +lua_touserdata
    +lua_type
    +lua_typename
    +lua_upvalueid
    +lua_upvalueindex
    +lua_upvaluejoin
    +lua_version
    +lua_xmove
    +lua_yield
    +lua_yieldk
    + +

    +

    auxiliary library

    +

    +luaL_Buffer
    +luaL_Reg
    + +

    +luaL_addchar
    +luaL_addlstring
    +luaL_addsize
    +luaL_addstring
    +luaL_addvalue
    +luaL_argcheck
    +luaL_argerror
    +luaL_buffinit
    +luaL_buffinitsize
    +luaL_callmeta
    +luaL_checkany
    +luaL_checkint
    +luaL_checkinteger
    +luaL_checklong
    +luaL_checklstring
    +luaL_checknumber
    +luaL_checkoption
    +luaL_checkstack
    +luaL_checkstring
    +luaL_checktype
    +luaL_checkudata
    +luaL_checkunsigned
    +luaL_checkversion
    +luaL_dofile
    +luaL_dostring
    +luaL_error
    +luaL_execresult
    +luaL_fileresult
    +luaL_getmetafield
    +luaL_getmetatable
    +luaL_getsubtable
    +luaL_gsub
    +luaL_len
    +luaL_loadbuffer
    +luaL_loadbufferx
    +luaL_loadfile
    +luaL_loadfilex
    +luaL_loadstring
    +luaL_newlib
    +luaL_newlibtable
    +luaL_newmetatable
    +luaL_newstate
    +luaL_openlibs
    +luaL_optint
    +luaL_optinteger
    +luaL_optlong
    +luaL_optlstring
    +luaL_optnumber
    +luaL_optstring
    +luaL_optunsigned
    +luaL_prepbuffer
    +luaL_prepbuffsize
    +luaL_pushresult
    +luaL_pushresultsize
    +luaL_ref
    +luaL_requiref
    +luaL_setfuncs
    +luaL_setmetatable
    +luaL_testudata
    +luaL_tolstring
    +luaL_traceback
    +luaL_typename
    +luaL_unref
    +luaL_where
    + +

    + +
    + +Last update: +Tue Mar 12 11:22:18 BRT 2013 + + + + + diff --git a/doc/logo.gif b/doc/logo.gif new file mode 100644 index 0000000000000000000000000000000000000000..2f5e4ac2e742fbb7675e739879211553758aea9c GIT binary patch literal 4232 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 PWz_J}_#7St0k8iB@FZjZ literal 0 HcmV?d00001 diff --git a/doc/lua.1 b/doc/lua.1 new file mode 100644 index 0000000000..1dbf04366c --- /dev/null +++ b/doc/lua.1 @@ -0,0 +1,116 @@ +.\" $Id: lua.man,v 1.13 2011/11/16 17:16:53 lhf Exp $ +.TH LUA 1 "$Date: 2011/11/16 17:16:53 $" +.SH NAME +lua \- Lua interpreter +.SH SYNOPSIS +.B lua +[ +.I options +] +[ +.I script +[ +.I args +] +] +.SH DESCRIPTION +.B lua +is the standalone Lua interpreter. +It loads and executes Lua programs, +either in textual source form or +in precompiled binary form. +(Precompiled binaries are output by +.BR luac , +the Lua compiler.) +.B lua +can be used as a batch interpreter and also interactively. +.LP +The given +.I options +are handled in order and then +the Lua program in file +.I script +is loaded and executed. +The given +.I args +are available to +.I script +as strings in a global table named +.BR arg . +If no options or arguments are given, +then +.B "\-v \-i" +is assumed when the standard input is a terminal; +otherwise, +.B "\-" +is assumed. +.LP +In interactive mode, +.B lua +prompts the user, +reads lines from the standard input, +and executes them as they are read. +If a line does not contain a complete statement, +then a secondary prompt is displayed and +lines are read until a complete statement is formed or +a syntax error is found. +If a line starts with +.BR '=' , +then +.B lua +evaluates and displays +the values of the expressions in the remainder of the line. +.LP +At the very start, +before even handling the command line, +.B lua +checks the contents of the environment variables +.B LUA_INIT_5_2 +or +.BR LUA_INIT , +in that order. +If the contents is of the form +.RI '@ filename ', +then +.I filename +is executed. +Otherwise, the string is assumed to be a Lua statement and is executed. +.SH OPTIONS +.TP +.BI \-e " stat" +execute statement +.IR stat . +.TP +.B \-i +enter interactive mode after executing +.IR script . +.TP +.BI \-l " name" +execute the equivalent of +.IB name =require(' name ') +before executing +.IR script . +.TP +.B \-v +show version information. +.TP +.B \-E +ignore environment variables. +.TP +.B \-\- +stop handling options. +.TP +.B \- +stop handling options and execute the standard input as a file. +.SH "SEE ALSO" +.BR luac (1) +.br +The documentation at lua.org, +especially section 7 of the reference manual. +.SH DIAGNOSTICS +Error messages should be self explanatory. +.SH AUTHORS +R. Ierusalimschy, +L. H. de Figueiredo, +W. Celes +.\" EOF diff --git a/doc/lua.css b/doc/lua.css new file mode 100644 index 0000000000..3d2443acff --- /dev/null +++ b/doc/lua.css @@ -0,0 +1,96 @@ +html { + background-color: #F8F8F8 ; +} + +body { + border: solid #a0a0a0 1px ; + border-radius: 20px ; + padding: 26px ; + margin: 16px ; + color: #000000 ; + background-color: #FFFFFF ; + font-family: Helvetica, Arial, sans-serif ; + text-align: justify ; +} + +h1, h2, h3, h4 { + font-family: Verdana, Geneva, sans-serif ; + font-weight: normal ; + font-style: normal ; +} + +h2 { + padding-top: 0.4em ; + padding-bottom: 0.4em ; + padding-left: 0.8em ; + padding-right: 0.8em ; + background-color: #D0D0FF ; + border-radius: 8px ; + border: solid #a0a0a0 1px ; +} + +h3 { + padding-left: 0.5em ; + border-left: solid #D0D0FF 1em ; +} + +table h3 { + padding-left: 0px ; + border-left: none ; +} + +a:link { + color: #000080 ; + background-color: inherit ; + text-decoration: none ; +} + +a:visited { + background-color: inherit ; + text-decoration: none ; +} + +a:link:hover, a:visited:hover { + color: #000080 ; + background-color: #D0D0FF ; +} + +a:link:active, a:visited:active { + color: #FF0000 ; +} + +hr { + border: 0 ; + height: 1px ; + color: #a0a0a0 ; + background-color: #a0a0a0 ; + display: none ; +} + +table hr { + display: block ; +} + +:target { + background-color: #F8F8F8 ; + padding: 8px ; + border: solid #a0a0a0 2px ; + border-radius: 8px ; +} + +.footer { + color: gray ; + font-size: x-small ; +} + +input[type=text] { + border: solid #a0a0a0 2px ; + border-radius: 2em ; + -moz-border-radius: 2em ; + background-image: url('images/search.png') ; + background-repeat: no-repeat; + background-position: 4px center ; + padding-left: 20px ; + height: 2em ; +} + diff --git a/doc/luac.1 b/doc/luac.1 new file mode 100644 index 0000000000..33a4ed00ac --- /dev/null +++ b/doc/luac.1 @@ -0,0 +1,118 @@ +.\" $Id: luac.man,v 1.29 2011/11/16 13:53:40 lhf Exp $ +.TH LUAC 1 "$Date: 2011/11/16 13:53:40 $" +.SH NAME +luac \- Lua compiler +.SH SYNOPSIS +.B luac +[ +.I options +] [ +.I filenames +] +.SH DESCRIPTION +.B luac +is the Lua compiler. +It translates programs written in the Lua programming language +into binary files containing precompiled chunks +that can be later loaded and executed. +.LP +The main advantages of precompiling chunks are: +faster loading, +protecting source code from accidental user changes, +and +off-line syntax checking. +Precompiling does not imply faster execution +because in Lua chunks are always compiled into bytecodes before being executed. +.B luac +simply allows those bytecodes to be saved in a file for later execution. +Precompiled chunks are not necessarily smaller than the corresponding source. +The main goal in precompiling is faster loading. +.LP +In the command line, +you can mix +text files containing Lua source and +binary files containing precompiled chunks. +.B luac +produces a single output file containing the combined bytecodes +for all files given. +Executing the combined file is equivalent to executing the given files. +By default, +the output file is named +.BR luac.out , +but you can change this with the +.B \-o +option. +.LP +Precompiled chunks are +.I not +portable across different architectures. +Moreover, +the internal format of precompiled chunks +is likely to change when a new version of Lua is released. +Make sure you save the source files of all Lua programs that you precompile. +.LP +.SH OPTIONS +.TP +.B \-l +produce a listing of the compiled bytecode for Lua's virtual machine. +Listing bytecodes is useful to learn about Lua's virtual machine. +If no files are given, then +.B luac +loads +.B luac.out +and lists its contents. +Use +.B \-l \-l +for a full listing. +.TP +.BI \-o " file" +output to +.IR file , +instead of the default +.BR luac.out . +(You can use +.B "'\-'" +for standard output, +but not on platforms that open standard output in text mode.) +The output file may be one of the given files because +all files are loaded before the output file is written. +Be careful not to overwrite precious files. +.TP +.B \-p +load files but do not generate any output file. +Used mainly for syntax checking and for testing precompiled chunks: +corrupted files will probably generate errors when loaded. +If no files are given, then +.B luac +loads +.B luac.out +and tests its contents. +No messages are displayed if the file loads without errors. +.TP +.B \-s +strip debug information before writing the output file. +This saves some space in very large chunks, +but if errors occur when running a stripped chunk, +then the error messages may not contain the full information they usually do. +In particular, +line numbers and names of local variables are lost. +.TP +.B \-v +show version information. +.TP +.B \-\- +stop handling options. +.TP +.B \- +stop handling options and process standard input. +.SH "SEE ALSO" +.BR lua (1) +.br +The documentation at lua.org. +.SH DIAGNOSTICS +Error messages should be self explanatory. +.SH AUTHORS +R. Ierusalimschy, +L. H. de Figueiredo, +W. Celes +.\" EOF diff --git a/doc/manual.css b/doc/manual.css new file mode 100644 index 0000000000..ca613cd9fb --- /dev/null +++ b/doc/manual.css @@ -0,0 +1,27 @@ +h3 code { + font-family: inherit ; + font-size: inherit ; +} + +pre, code { + font-size: 12pt ; +} + +span.apii { + float: right ; + font-family: inherit ; + font-style: normal ; + font-size: small ; + color: gray ; +} + +p+h1, ul+h1 { + font-style: normal ; + padding-top: 0.4em ; + padding-bottom: 0.4em ; + padding-left: 16px ; + margin-left: -16px ; + background-color: #D0D0FF ; + border-radius: 8px ; + border: solid #000080 1px ; +} diff --git a/doc/manual.html b/doc/manual.html new file mode 100644 index 0000000000..85365363fb --- /dev/null +++ b/doc/manual.html @@ -0,0 +1,10507 @@ + + + + +Lua 5.2 Reference Manual + + + + + + + +
    +

    + +Lua 5.2 Reference Manual +

    + +by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes +

    + +Copyright © 2011–2013 Lua.org, PUC-Rio. +Freely available under the terms of the +Lua license. + +


    +

    + +contents +· +index + + +

    + + + + + + +

    1 – Introduction

    + +

    +Lua is an extension programming language designed to support +general procedural programming with data description +facilities. +It also offers good support for object-oriented programming, +functional programming, and data-driven programming. +Lua is intended to be used as a powerful, lightweight, +embeddable scripting language for any program that needs one. +Lua is implemented as a library, written in clean C, +the common subset of Standard C and C++. + + +

    +Being an extension language, Lua has no notion of a "main" program: +it only works embedded in a host client, +called the embedding program or simply the host. +The host program can invoke functions to execute a piece of Lua code, +can write and read Lua variables, +and can register C functions to be called by Lua code. +Through the use of C functions, Lua can be augmented to cope with +a wide range of different domains, +thus creating customized programming languages sharing a syntactical framework. +The Lua distribution includes a sample host program called lua, +which uses the Lua library to offer a complete, standalone Lua interpreter, +for interactive or batch use. + + +

    +Lua is free software, +and is provided as usual with no guarantees, +as stated in its license. +The implementation described in this manual is available +at Lua's official web site, www.lua.org. + + +

    +Like any other reference manual, +this document is dry in places. +For a discussion of the decisions behind the design of Lua, +see the technical papers available at Lua's web site. +For a detailed introduction to programming in Lua, +see Roberto's book, Programming in Lua. + + + +

    2 – Basic Concepts

    + +

    +This section describes the basic concepts of the language. + + + +

    2.1 – Values and Types

    + +

    +Lua is a dynamically typed language. +This means that +variables do not have types; only values do. +There are no type definitions in the language. +All values carry their own type. + + +

    +All values in Lua are first-class values. +This means that all values can be stored in variables, +passed as arguments to other functions, and returned as results. + + +

    +There are eight basic types in Lua: +nil, boolean, number, +string, function, userdata, +thread, and table. +Nil is the type of the value nil, +whose main property is to be different from any other value; +it usually represents the absence of a useful value. +Boolean is the type of the values false and true. +Both nil and false make a condition false; +any other value makes it true. +Number represents real (double-precision floating-point) numbers. +Operations on numbers follow the same rules of +the underlying C implementation, +which, in turn, usually follows the IEEE 754 standard. +(It is easy to build Lua interpreters that use other +internal representations for numbers, +such as single-precision floats or long integers; +see file luaconf.h.) +String represents immutable sequences of bytes. + +Lua is 8-bit clean: +strings can contain any 8-bit value, +including embedded zeros ('\0'). + + +

    +Lua can call (and manipulate) functions written in Lua and +functions written in C +(see §3.4.9). + + +

    +The type userdata is provided to allow arbitrary C data to +be stored in Lua variables. +A userdata value is a pointer to a block of raw memory. +There are two kinds of userdata: +full userdata, where the block of memory is managed by Lua, +and light userdata, where the block of memory is managed by the host. +Userdata has no predefined operations in Lua, +except assignment and identity test. +By using metatables, +the programmer can define operations for full userdata values +(see §2.4). +Userdata values cannot be created or modified in Lua, +only through the C API. +This guarantees the integrity of data owned by the host program. + + +

    +The type thread represents independent threads of execution +and it is used to implement coroutines (see §2.6). +Do not confuse Lua threads with operating-system threads. +Lua supports coroutines on all systems, +even those that do not support threads. + + +

    +The type table implements associative arrays, +that is, arrays that can be indexed not only with numbers, +but with any Lua value except nil and NaN +(Not a Number, a special numeric value used to represent +undefined or unrepresentable results, such as 0/0). +Tables can be heterogeneous; +that is, they can contain values of all types (except nil). +Any key with value nil is not considered part of the table. +Conversely, any key that is not part of a table has +an associated value nil. + + +

    +Tables are the sole data structuring mechanism in Lua; +they can be used to represent ordinary arrays, sequences, +symbol tables, sets, records, graphs, trees, etc. +To represent records, Lua uses the field name as an index. +The language supports this representation by +providing a.name as syntactic sugar for a["name"]. +There are several convenient ways to create tables in Lua +(see §3.4.8). + + +

    +We use the term sequence to denote a table where +the set of all positive numeric keys is equal to {1..n} +for some integer n, +which is called the length of the sequence (see §3.4.6). + + +

    +Like indices, +the values of table fields can be of any type. +In particular, +because functions are first-class values, +table fields can contain functions. +Thus tables can also carry methods (see §3.4.10). + + +

    +The indexing of tables follows +the definition of raw equality in the language. +The expressions a[i] and a[j] +denote the same table element +if and only if i and j are raw equal +(that is, equal without metamethods). + + +

    +Tables, functions, threads, and (full) userdata values are objects: +variables do not actually contain these values, +only references to them. +Assignment, parameter passing, and function returns +always manipulate references to such values; +these operations do not imply any kind of copy. + + +

    +The library function type returns a string describing the type +of a given value (see §6.1). + + + + + +

    2.2 – Environments and the Global Environment

    + +

    +As will be discussed in §3.2 and §3.3.3, +any reference to a global name var is syntactically translated +to _ENV.var. +Moreover, every chunk is compiled in the scope of +an external local variable called _ENV (see §3.3.2), +so _ENV itself is never a global name in a chunk. + + +

    +Despite the existence of this external _ENV variable and +the translation of global names, +_ENV is a completely regular name. +In particular, +you can define new variables and parameters with that name. +Each reference to a global name uses the _ENV that is +visible at that point in the program, +following the usual visibility rules of Lua (see §3.5). + + +

    +Any table used as the value of _ENV is called an environment. + + +

    +Lua keeps a distinguished environment called the global environment. +This value is kept at a special index in the C registry (see §4.5). +In Lua, the variable _G is initialized with this same value. + + +

    +When Lua compiles a chunk, +it initializes the value of its _ENV upvalue +with the global environment (see load). +Therefore, by default, +global variables in Lua code refer to entries in the global environment. +Moreover, all standard libraries are loaded in the global environment +and several functions there operate on that environment. +You can use load (or loadfile) +to load a chunk with a different environment. +(In C, you have to load the chunk and then change the value +of its first upvalue.) + + +

    +If you change the global environment in the registry +(through C code or the debug library), +all chunks loaded after the change will get the new environment. +Previously loaded chunks are not affected, however, +as each has its own reference to the environment in its _ENV variable. +Moreover, the variable _G +(which is stored in the original global environment) +is never updated by Lua. + + + + + +

    2.3 – Error Handling

    + +

    +Because Lua is an embedded extension language, +all Lua actions start from C code in the host program +calling a function from the Lua library (see lua_pcall). +Whenever an error occurs during +the compilation or execution of a Lua chunk, +control returns to the host, +which can take appropriate measures +(such as printing an error message). + + +

    +Lua code can explicitly generate an error by calling the +error function. +If you need to catch errors in Lua, +you can use pcall or xpcall +to call a given function in protected mode. + + +

    +Whenever there is an error, +an error object (also called an error message) +is propagated with information about the error. +Lua itself only generates errors where the error object is a string, +but programs may generate errors with +any value for the error object. + + +

    +When you use xpcall or lua_pcall, +you may give a message handler +to be called in case of errors. +This function is called with the original error message +and returns a new error message. +It is called before the error unwinds the stack, +so that it can gather more information about the error, +for instance by inspecting the stack and creating a stack traceback. +This message handler is still protected by the protected call; +so, an error inside the message handler +will call the message handler again. +If this loop goes on, Lua breaks it and returns an appropriate message. + + + + + +

    2.4 – Metatables and Metamethods

    + +

    +Every value in Lua can have a metatable. +This metatable is an ordinary Lua table +that defines the behavior of the original value +under certain special operations. +You can change several aspects of the behavior +of operations over a value by setting specific fields in its metatable. +For instance, when a non-numeric value is the operand of an addition, +Lua checks for a function in the field "__add" of the value's metatable. +If it finds one, +Lua calls this function to perform the addition. + + +

    +The keys in a metatable are derived from the event names; +the corresponding values are called metamethods. +In the previous example, the event is "add" +and the metamethod is the function that performs the addition. + + +

    +You can query the metatable of any value +using the getmetatable function. + + +

    +You can replace the metatable of tables +using the setmetatable function. +You cannot change the metatable of other types from Lua +(except by using the debug library); +you must use the C API for that. + + +

    +Tables and full userdata have individual metatables +(although multiple tables and userdata can share their metatables). +Values of all other types share one single metatable per type; +that is, there is one single metatable for all numbers, +one for all strings, etc. +By default, a value has no metatable, +but the string library sets a metatable for the string type (see §6.4). + + +

    +A metatable controls how an object behaves in arithmetic operations, +order comparisons, concatenation, length operation, and indexing. +A metatable also can define a function to be called +when a userdata or a table is garbage collected. +When Lua performs one of these operations over a value, +it checks whether this value has a metatable with the corresponding event. +If so, the value associated with that key (the metamethod) +controls how Lua will perform the operation. + + +

    +Metatables control the operations listed next. +Each operation is identified by its corresponding name. +The key for each operation is a string with its name prefixed by +two underscores, '__'; +for instance, the key for operation "add" is the +string "__add". + + +

    +The semantics of these operations is better explained by a Lua function +describing how the interpreter executes the operation. +The code shown here in Lua is only illustrative; +the real behavior is hard coded in the interpreter +and it is much more efficient than this simulation. +All functions used in these descriptions +(rawget, tonumber, etc.) +are described in §6.1. +In particular, to retrieve the metamethod of a given object, +we use the expression + +

    +     metatable(obj)[event]
    +

    +This should be read as + +

    +     rawget(getmetatable(obj) or {}, event)
    +

    +This means that the access to a metamethod does not invoke other metamethods, +and access to objects with no metatables does not fail +(it simply results in nil). + + +

    +For the unary - and # operators, +the metamethod is called with a dummy second argument. +This extra argument is only to simplify Lua's internals; +it may be removed in future versions and therefore it is not present +in the following code. +(For most uses this extra argument is irrelevant.) + + + +

      + +
    • "add": +the + operation. + + + +

      +The function getbinhandler below defines how Lua chooses a handler +for a binary operation. +First, Lua tries the first operand. +If its type does not define a handler for the operation, +then Lua tries the second operand. + +

      +     function getbinhandler (op1, op2, event)
      +       return metatable(op1)[event] or metatable(op2)[event]
      +     end
      +

      +By using this function, +the behavior of the op1 + op2 is + +

      +     function add_event (op1, op2)
      +       local o1, o2 = tonumber(op1), tonumber(op2)
      +       if o1 and o2 then  -- both operands are numeric?
      +         return o1 + o2   -- '+' here is the primitive 'add'
      +       else  -- at least one of the operands is not numeric
      +         local h = getbinhandler(op1, op2, "__add")
      +         if h then
      +           -- call the handler with both operands
      +           return (h(op1, op2))
      +         else  -- no handler available: default behavior
      +           error(···)
      +         end
      +       end
      +     end
      +

      +

    • + +
    • "sub": +the - operation. + +Behavior similar to the "add" operation. +
    • + +
    • "mul": +the * operation. + +Behavior similar to the "add" operation. +
    • + +
    • "div": +the / operation. + +Behavior similar to the "add" operation. +
    • + +
    • "mod": +the % operation. + +Behavior similar to the "add" operation, +with the operation +o1 - floor(o1/o2)*o2 as the primitive operation. +
    • + +
    • "pow": +the ^ (exponentiation) operation. + +Behavior similar to the "add" operation, +with the function pow (from the C math library) +as the primitive operation. +
    • + +
    • "unm": +the unary - operation. + + +
      +     function unm_event (op)
      +       local o = tonumber(op)
      +       if o then  -- operand is numeric?
      +         return -o  -- '-' here is the primitive 'unm'
      +       else  -- the operand is not numeric.
      +         -- Try to get a handler from the operand
      +         local h = metatable(op).__unm
      +         if h then
      +           -- call the handler with the operand
      +           return (h(op))
      +         else  -- no handler available: default behavior
      +           error(···)
      +         end
      +       end
      +     end
      +

      +

    • + +
    • "concat": +the .. (concatenation) operation. + + +
      +     function concat_event (op1, op2)
      +       if (type(op1) == "string" or type(op1) == "number") and
      +          (type(op2) == "string" or type(op2) == "number") then
      +         return op1 .. op2  -- primitive string concatenation
      +       else
      +         local h = getbinhandler(op1, op2, "__concat")
      +         if h then
      +           return (h(op1, op2))
      +         else
      +           error(···)
      +         end
      +       end
      +     end
      +

      +

    • + +
    • "len": +the # operation. + + +
      +     function len_event (op)
      +       if type(op) == "string" then
      +         return strlen(op)      -- primitive string length
      +       else
      +         local h = metatable(op).__len
      +         if h then
      +           return (h(op))       -- call handler with the operand
      +         elseif type(op) == "table" then
      +           return #op              -- primitive table length
      +         else  -- no handler available: error
      +           error(···)
      +         end
      +       end
      +     end
      +

      +See §3.4.6 for a description of the length of a table. +

    • + +
    • "eq": +the == operation. + +The function getequalhandler defines how Lua chooses a metamethod +for equality. +A metamethod is selected only when both values +being compared have the same type +and the same metamethod for the selected operation, +and the values are either tables or full userdata. + +
      +     function getequalhandler (op1, op2)
      +       if type(op1) ~= type(op2) or
      +          (type(op1) ~= "table" and type(op1) ~= "userdata") then
      +         return nil     -- different values
      +       end
      +       local mm1 = metatable(op1).__eq
      +       local mm2 = metatable(op2).__eq
      +       if mm1 == mm2 then return mm1 else return nil end
      +     end
      +

      +The "eq" event is defined as follows: + +

      +     function eq_event (op1, op2)
      +       if op1 == op2 then   -- primitive equal?
      +         return true   -- values are equal
      +       end
      +       -- try metamethod
      +       local h = getequalhandler(op1, op2)
      +       if h then
      +         return not not h(op1, op2)
      +       else
      +         return false
      +       end
      +     end
      +

      +Note that the result is always a boolean. +

    • + +
    • "lt": +the < operation. + + +
      +     function lt_event (op1, op2)
      +       if type(op1) == "number" and type(op2) == "number" then
      +         return op1 < op2   -- numeric comparison
      +       elseif type(op1) == "string" and type(op2) == "string" then
      +         return op1 < op2   -- lexicographic comparison
      +       else
      +         local h = getbinhandler(op1, op2, "__lt")
      +         if h then
      +           return not not h(op1, op2)
      +         else
      +           error(···)
      +         end
      +       end
      +     end
      +

      +Note that the result is always a boolean. +

    • + +
    • "le": +the <= operation. + + +
      +     function le_event (op1, op2)
      +       if type(op1) == "number" and type(op2) == "number" then
      +         return op1 <= op2   -- numeric comparison
      +       elseif type(op1) == "string" and type(op2) == "string" then
      +         return op1 <= op2   -- lexicographic comparison
      +       else
      +         local h = getbinhandler(op1, op2, "__le")
      +         if h then
      +           return not not h(op1, op2)
      +         else
      +           h = getbinhandler(op1, op2, "__lt")
      +           if h then
      +             return not h(op2, op1)
      +           else
      +             error(···)
      +           end
      +         end
      +       end
      +     end
      +

      +Note that, in the absence of a "le" metamethod, +Lua tries the "lt", assuming that a <= b is +equivalent to not (b < a). + + +

      +As with the other comparison operators, +the result is always a boolean. +

    • + +
    • "index": +The indexing access table[key]. +Note that the metamethod is tried only +when key is not present in table. +(When table is not a table, +no key is ever present, +so the metamethod is always tried.) + + +
      +     function gettable_event (table, key)
      +       local h
      +       if type(table) == "table" then
      +         local v = rawget(table, key)
      +         -- if key is present, return raw value
      +         if v ~= nil then return v end
      +         h = metatable(table).__index
      +         if h == nil then return nil end
      +       else
      +         h = metatable(table).__index
      +         if h == nil then
      +           error(···)
      +         end
      +       end
      +       if type(h) == "function" then
      +         return (h(table, key))     -- call the handler
      +       else return h[key]           -- or repeat operation on it
      +       end
      +     end
      +

      +

    • + +
    • "newindex": +The indexing assignment table[key] = value. +Note that the metamethod is tried only +when key is not present in table. + + +
      +     function settable_event (table, key, value)
      +       local h
      +       if type(table) == "table" then
      +         local v = rawget(table, key)
      +         -- if key is present, do raw assignment
      +         if v ~= nil then rawset(table, key, value); return end
      +         h = metatable(table).__newindex
      +         if h == nil then rawset(table, key, value); return end
      +       else
      +         h = metatable(table).__newindex
      +         if h == nil then
      +           error(···)
      +         end
      +       end
      +       if type(h) == "function" then
      +         h(table, key,value)           -- call the handler
      +       else h[key] = value             -- or repeat operation on it
      +       end
      +     end
      +

      +

    • + +
    • "call": +called when Lua calls a value. + + +
      +     function function_event (func, ...)
      +       if type(func) == "function" then
      +         return func(...)   -- primitive call
      +       else
      +         local h = metatable(func).__call
      +         if h then
      +           return h(func, ...)
      +         else
      +           error(···)
      +         end
      +       end
      +     end
      +

      +

    • + +
    + + + + +

    2.5 – Garbage Collection

    + +

    +Lua performs automatic memory management. +This means that +you have to worry neither about allocating memory for new objects +nor about freeing it when the objects are no longer needed. +Lua manages memory automatically by running +a garbage collector to collect all dead objects +(that is, objects that are no longer accessible from Lua). +All memory used by Lua is subject to automatic management: +strings, tables, userdata, functions, threads, internal structures, etc. + + +

    +Lua implements an incremental mark-and-sweep collector. +It uses two numbers to control its garbage-collection cycles: +the garbage-collector pause and +the garbage-collector step multiplier. +Both use percentage points as units +(e.g., a value of 100 means an internal value of 1). + + +

    +The garbage-collector pause +controls how long the collector waits before starting a new cycle. +Larger values make the collector less aggressive. +Values smaller than 100 mean the collector will not wait to +start a new cycle. +A value of 200 means that the collector waits for the total memory in use +to double before starting a new cycle. + + +

    +The garbage-collector step multiplier +controls the relative speed of the collector relative to +memory allocation. +Larger values make the collector more aggressive but also increase +the size of each incremental step. +Values smaller than 100 make the collector too slow and +can result in the collector never finishing a cycle. +The default is 200, +which means that the collector runs at "twice" +the speed of memory allocation. + + +

    +If you set the step multiplier to a very large number +(larger than 10% of the maximum number of +bytes that the program may use), +the collector behaves like a stop-the-world collector. +If you then set the pause to 200, +the collector behaves as in old Lua versions, +doing a complete collection every time Lua doubles its +memory usage. + + +

    +You can change these numbers by calling lua_gc in C +or collectgarbage in Lua. +You can also use these functions to control +the collector directly (e.g., stop and restart it). + + +

    +As an experimental feature in Lua 5.2, +you can change the collector's operation mode +from incremental to generational. +A generational collector assumes that most objects die young, +and therefore it traverses only young (recently created) objects. +This behavior can reduce the time used by the collector, +but also increases memory usage (as old dead objects may accumulate). +To mitigate this second problem, +from time to time the generational collector performs a full collection. +Remember that this is an experimental feature; +you are welcome to try it, +but check your gains. + + + +

    2.5.1 – Garbage-Collection Metamethods

    + +

    +You can set garbage-collector metamethods for tables +and, using the C API, +for full userdata (see §2.4). +These metamethods are also called finalizers. +Finalizers allow you to coordinate Lua's garbage collection +with external resource management +(such as closing files, network or database connections, +or freeing your own memory). + + +

    +For an object (table or userdata) to be finalized when collected, +you must mark it for finalization. + +You mark an object for finalization when you set its metatable +and the metatable has a field indexed by the string "__gc". +Note that if you set a metatable without a __gc field +and later create that field in the metatable, +the object will not be marked for finalization. +However, after an object is marked, +you can freely change the __gc field of its metatable. + + +

    +When a marked object becomes garbage, +it is not collected immediately by the garbage collector. +Instead, Lua puts it in a list. +After the collection, +Lua does the equivalent of the following function +for each object in that list: + +

    +     function gc_event (obj)
    +       local h = metatable(obj).__gc
    +       if type(h) == "function" then
    +         h(obj)
    +       end
    +     end
    +
    + +

    +At the end of each garbage-collection cycle, +the finalizers for objects are called in +the reverse order that they were marked for collection, +among those collected in that cycle; +that is, the first finalizer to be called is the one associated +with the object marked last in the program. +The execution of each finalizer may occur at any point during +the execution of the regular code. + + +

    +Because the object being collected must still be used by the finalizer, +it (and other objects accessible only through it) +must be resurrected by Lua. +Usually, this resurrection is transient, +and the object memory is freed in the next garbage-collection cycle. +However, if the finalizer stores the object in some global place +(e.g., a global variable), +then there is a permanent resurrection. +In any case, +the object memory is freed only when it becomes completely inaccessible; +its finalizer will never be called twice. + + +

    +When you close a state (see lua_close), +Lua calls the finalizers of all objects marked for finalization, +following the reverse order that they were marked. +If any finalizer marks new objects for collection during that phase, +these new objects will not be finalized. + + + + + +

    2.5.2 – Weak Tables

    + +

    +A weak table is a table whose elements are +weak references. +A weak reference is ignored by the garbage collector. +In other words, +if the only references to an object are weak references, +then the garbage collector will collect that object. + + +

    +A weak table can have weak keys, weak values, or both. +A table with weak keys allows the collection of its keys, +but prevents the collection of its values. +A table with both weak keys and weak values allows the collection of +both keys and values. +In any case, if either the key or the value is collected, +the whole pair is removed from the table. +The weakness of a table is controlled by the +__mode field of its metatable. +If the __mode field is a string containing the character 'k', +the keys in the table are weak. +If __mode contains 'v', +the values in the table are weak. + + +

    +A table with weak keys and strong values +is also called an ephemeron table. +In an ephemeron table, +a value is considered reachable only if its key is reachable. +In particular, +if the only reference to a key comes through its value, +the pair is removed. + + +

    +Any change in the weakness of a table may take effect only +at the next collect cycle. +In particular, if you change the weakness to a stronger mode, +Lua may still collect some items from that table +before the change takes effect. + + +

    +Only objects that have an explicit construction +are removed from weak tables. +Values, such as numbers and light C functions, +are not subject to garbage collection, +and therefore are not removed from weak tables +(unless its associated value is collected). +Although strings are subject to garbage collection, +they do not have an explicit construction, +and therefore are not removed from weak tables. + + +

    +Resurrected objects +(that is, objects being finalized +and objects accessible only through objects being finalized) +have a special behavior in weak tables. +They are removed from weak values before running their finalizers, +but are removed from weak keys only in the next collection +after running their finalizers, when such objects are actually freed. +This behavior allows the finalizer to access properties +associated with the object through weak tables. + + +

    +If a weak table is among the resurrected objects in a collection cycle, +it may not be properly cleared until the next cycle. + + + + + + + +

    2.6 – Coroutines

    + +

    +Lua supports coroutines, +also called collaborative multithreading. +A coroutine in Lua represents an independent thread of execution. +Unlike threads in multithread systems, however, +a coroutine only suspends its execution by explicitly calling +a yield function. + + +

    +You create a coroutine by calling coroutine.create. +Its sole argument is a function +that is the main function of the coroutine. +The create function only creates a new coroutine and +returns a handle to it (an object of type thread); +it does not start the coroutine. + + +

    +You execute a coroutine by calling coroutine.resume. +When you first call coroutine.resume, +passing as its first argument +a thread returned by coroutine.create, +the coroutine starts its execution, +at the first line of its main function. +Extra arguments passed to coroutine.resume are passed on +to the coroutine main function. +After the coroutine starts running, +it runs until it terminates or yields. + + +

    +A coroutine can terminate its execution in two ways: +normally, when its main function returns +(explicitly or implicitly, after the last instruction); +and abnormally, if there is an unprotected error. +In the first case, coroutine.resume returns true, +plus any values returned by the coroutine main function. +In case of errors, coroutine.resume returns false +plus an error message. + + +

    +A coroutine yields by calling coroutine.yield. +When a coroutine yields, +the corresponding coroutine.resume returns immediately, +even if the yield happens inside nested function calls +(that is, not in the main function, +but in a function directly or indirectly called by the main function). +In the case of a yield, coroutine.resume also returns true, +plus any values passed to coroutine.yield. +The next time you resume the same coroutine, +it continues its execution from the point where it yielded, +with the call to coroutine.yield returning any extra +arguments passed to coroutine.resume. + + +

    +Like coroutine.create, +the coroutine.wrap function also creates a coroutine, +but instead of returning the coroutine itself, +it returns a function that, when called, resumes the coroutine. +Any arguments passed to this function +go as extra arguments to coroutine.resume. +coroutine.wrap returns all the values returned by coroutine.resume, +except the first one (the boolean error code). +Unlike coroutine.resume, +coroutine.wrap does not catch errors; +any error is propagated to the caller. + + +

    +As an example of how coroutines work, +consider the following code: + +

    +     function foo (a)
    +       print("foo", a)
    +       return coroutine.yield(2*a)
    +     end
    +     
    +     co = coroutine.create(function (a,b)
    +           print("co-body", a, b)
    +           local r = foo(a+1)
    +           print("co-body", r)
    +           local r, s = coroutine.yield(a+b, a-b)
    +           print("co-body", r, s)
    +           return b, "end"
    +     end)
    +     
    +     print("main", coroutine.resume(co, 1, 10))
    +     print("main", coroutine.resume(co, "r"))
    +     print("main", coroutine.resume(co, "x", "y"))
    +     print("main", coroutine.resume(co, "x", "y"))
    +

    +When you run it, it produces the following output: + +

    +     co-body 1       10
    +     foo     2
    +     main    true    4
    +     co-body r
    +     main    true    11      -9
    +     co-body x       y
    +     main    true    10      end
    +     main    false   cannot resume dead coroutine
    +
    + +

    +You can also create and manipulate coroutines through the C API: +see functions lua_newthread, lua_resume, +and lua_yield. + + + + + +

    3 – The Language

    + +

    +This section describes the lexis, the syntax, and the semantics of Lua. +In other words, +this section describes +which tokens are valid, +how they can be combined, +and what their combinations mean. + + +

    +Language constructs will be explained using the usual extended BNF notation, +in which +{a} means 0 or more a's, and +[a] means an optional a. +Non-terminals are shown like non-terminal, +keywords are shown like kword, +and other terminal symbols are shown like ‘=’. +The complete syntax of Lua can be found in §9 +at the end of this manual. + + + +

    3.1 – Lexical Conventions

    + +

    +Lua is a free-form language. +It ignores spaces (including new lines) and comments +between lexical elements (tokens), +except as delimiters between names and keywords. + + +

    +Names +(also called identifiers) +in Lua can be any string of letters, +digits, and underscores, +not beginning with a digit. +Identifiers are used to name variables, table fields, and labels. + + +

    +The following keywords are reserved +and cannot be used as names: + + +

    +     and       break     do        else      elseif    end
    +     false     for       function  goto      if        in
    +     local     nil       not       or        repeat    return
    +     then      true      until     while
    +
    + +

    +Lua is a case-sensitive language: +and is a reserved word, but And and AND +are two different, valid names. +As a convention, names starting with an underscore followed by +uppercase letters (such as _VERSION) +are reserved for variables used by Lua. + + +

    +The following strings denote other tokens: + +

    +     +     -     *     /     %     ^     #
    +     ==    ~=    <=    >=    <     >     =
    +     (     )     {     }     [     ]     ::
    +     ;     :     ,     .     ..    ...
    +
    + +

    +Literal strings +can be delimited by matching single or double quotes, +and can contain the following C-like escape sequences: +'\a' (bell), +'\b' (backspace), +'\f' (form feed), +'\n' (newline), +'\r' (carriage return), +'\t' (horizontal tab), +'\v' (vertical tab), +'\\' (backslash), +'\"' (quotation mark [double quote]), +and '\'' (apostrophe [single quote]). +A backslash followed by a real newline +results in a newline in the string. +The escape sequence '\z' skips the following span +of white-space characters, +including line breaks; +it is particularly useful to break and indent a long literal string +into multiple lines without adding the newlines and spaces +into the string contents. + + +

    +A byte in a literal string can also be specified by its numerical value. +This can be done with the escape sequence \xXX, +where XX is a sequence of exactly two hexadecimal digits, +or with the escape sequence \ddd, +where ddd is a sequence of up to three decimal digits. +(Note that if a decimal escape is to be followed by a digit, +it must be expressed using exactly three digits.) +Strings in Lua can contain any 8-bit value, including embedded zeros, +which can be specified as '\0'. + + +

    +Literal strings can also be defined using a long format +enclosed by long brackets. +We define an opening long bracket of level n as an opening +square bracket followed by n equal signs followed by another +opening square bracket. +So, an opening long bracket of level 0 is written as [[, +an opening long bracket of level 1 is written as [=[, +and so on. +A closing long bracket is defined similarly; +for instance, a closing long bracket of level 4 is written as ]====]. +A long literal starts with an opening long bracket of any level and +ends at the first closing long bracket of the same level. +It can contain any text except a closing bracket of the proper level. +Literals in this bracketed form can run for several lines, +do not interpret any escape sequences, +and ignore long brackets of any other level. +Any kind of end-of-line sequence +(carriage return, newline, carriage return followed by newline, +or newline followed by carriage return) +is converted to a simple newline. + + +

    +Any byte in a literal string not +explicitly affected by the previous rules represents itself. +However, Lua opens files for parsing in text mode, +and the system file functions may have problems with +some control characters. +So, it is safer to represent +non-text data as a quoted literal with +explicit escape sequences for non-text characters. + + +

    +For convenience, +when the opening long bracket is immediately followed by a newline, +the newline is not included in the string. +As an example, in a system using ASCII +(in which 'a' is coded as 97, +newline is coded as 10, and '1' is coded as 49), +the five literal strings below denote the same string: + +

    +     a = 'alo\n123"'
    +     a = "alo\n123\""
    +     a = '\97lo\10\04923"'
    +     a = [[alo
    +     123"]]
    +     a = [==[
    +     alo
    +     123"]==]
    +
    + +

    +A numerical constant can be written with an optional fractional part +and an optional decimal exponent, +marked by a letter 'e' or 'E'. +Lua also accepts hexadecimal constants, +which start with 0x or 0X. +Hexadecimal constants also accept an optional fractional part +plus an optional binary exponent, +marked by a letter 'p' or 'P'. +Examples of valid numerical constants are + +

    +     3     3.0     3.1416     314.16e-2     0.31416E1
    +     0xff  0x0.1E  0xA23p-4   0X1.921FB54442D18P+1
    +
    + +

    +A comment starts with a double hyphen (--) +anywhere outside a string. +If the text immediately after -- is not an opening long bracket, +the comment is a short comment, +which runs until the end of the line. +Otherwise, it is a long comment, +which runs until the corresponding closing long bracket. +Long comments are frequently used to disable code temporarily. + + + + + +

    3.2 – Variables

    + +

    +Variables are places that store values. +There are three kinds of variables in Lua: +global variables, local variables, and table fields. + + +

    +A single name can denote a global variable or a local variable +(or a function's formal parameter, +which is a particular kind of local variable): + +

    +	var ::= Name
    +

    +Name denotes identifiers, as defined in §3.1. + + +

    +Any variable name is assumed to be global unless explicitly declared +as a local (see §3.3.7). +Local variables are lexically scoped: +local variables can be freely accessed by functions +defined inside their scope (see §3.5). + + +

    +Before the first assignment to a variable, its value is nil. + + +

    +Square brackets are used to index a table: + +

    +	var ::= prefixexp ‘[’ exp ‘]’
    +

    +The meaning of accesses to table fields can be changed via metatables. +An access to an indexed variable t[i] is equivalent to +a call gettable_event(t,i). +(See §2.4 for a complete description of the +gettable_event function. +This function is not defined or callable in Lua. +We use it here only for explanatory purposes.) + + +

    +The syntax var.Name is just syntactic sugar for +var["Name"]: + +

    +	var ::= prefixexp ‘.’ Name
    +
    + +

    +An access to a global variable x +is equivalent to _ENV.x. +Due to the way that chunks are compiled, +_ENV is never a global name (see §2.2). + + + + + +

    3.3 – Statements

    + +

    +Lua supports an almost conventional set of statements, +similar to those in Pascal or C. +This set includes +assignments, control structures, function calls, +and variable declarations. + + + +

    3.3.1 – Blocks

    + +

    +A block is a list of statements, +which are executed sequentially: + +

    +	block ::= {stat}
    +

    +Lua has empty statements +that allow you to separate statements with semicolons, +start a block with a semicolon +or write two semicolons in sequence: + +

    +	stat ::= ‘;’
    +
    + +

    +Function calls and assignments +can start with an open parenthesis. +This possibility leads to an ambiguity in Lua's grammar. +Consider the following fragment: + +

    +     a = b + c
    +     (print or io.write)('done')
    +

    +The grammar could see it in two ways: + +

    +     a = b + c(print or io.write)('done')
    +     
    +     a = b + c; (print or io.write)('done')
    +

    +The current parser always sees such constructions +in the first way, +interpreting the open parenthesis +as the start of the arguments to a call. +To avoid this ambiguity, +it is a good practice to always precede with a semicolon +statements that start with a parenthesis: + +

    +     ;(print or io.write)('done')
    +
    + +

    +A block can be explicitly delimited to produce a single statement: + +

    +	stat ::= do block end
    +

    +Explicit blocks are useful +to control the scope of variable declarations. +Explicit blocks are also sometimes used to +add a return statement in the middle +of another block (see §3.3.4). + + + + + +

    3.3.2 – Chunks

    + +

    +The unit of compilation of Lua is called a chunk. +Syntactically, +a chunk is simply a block: + +

    +	chunk ::= block
    +
    + +

    +Lua handles a chunk as the body of an anonymous function +with a variable number of arguments +(see §3.4.10). +As such, chunks can define local variables, +receive arguments, and return values. +Moreover, such anonymous function is compiled as in the +scope of an external local variable called _ENV (see §2.2). +The resulting function always has _ENV as its only upvalue, +even if it does not use that variable. + + +

    +A chunk can be stored in a file or in a string inside the host program. +To execute a chunk, +Lua first precompiles the chunk into instructions for a virtual machine, +and then it executes the compiled code +with an interpreter for the virtual machine. + + +

    +Chunks can also be precompiled into binary form; +see program luac for details. +Programs in source and compiled forms are interchangeable; +Lua automatically detects the file type and acts accordingly. + + + + + + +

    3.3.3 – Assignment

    + +

    +Lua allows multiple assignments. +Therefore, the syntax for assignment +defines a list of variables on the left side +and a list of expressions on the right side. +The elements in both lists are separated by commas: + +

    +	stat ::= varlist ‘=’ explist
    +	varlist ::= var {‘,’ var}
    +	explist ::= exp {‘,’ exp}
    +

    +Expressions are discussed in §3.4. + + +

    +Before the assignment, +the list of values is adjusted to the length of +the list of variables. +If there are more values than needed, +the excess values are thrown away. +If there are fewer values than needed, +the list is extended with as many nil's as needed. +If the list of expressions ends with a function call, +then all values returned by that call enter the list of values, +before the adjustment +(except when the call is enclosed in parentheses; see §3.4). + + +

    +The assignment statement first evaluates all its expressions +and only then are the assignments performed. +Thus the code + +

    +     i = 3
    +     i, a[i] = i+1, 20
    +

    +sets a[3] to 20, without affecting a[4] +because the i in a[i] is evaluated (to 3) +before it is assigned 4. +Similarly, the line + +

    +     x, y = y, x
    +

    +exchanges the values of x and y, +and + +

    +     x, y, z = y, z, x
    +

    +cyclically permutes the values of x, y, and z. + + +

    +The meaning of assignments to global variables +and table fields can be changed via metatables. +An assignment to an indexed variable t[i] = val is equivalent to +settable_event(t,i,val). +(See §2.4 for a complete description of the +settable_event function. +This function is not defined or callable in Lua. +We use it here only for explanatory purposes.) + + +

    +An assignment to a global variable x = val +is equivalent to the assignment +_ENV.x = val (see §2.2). + + + + + +

    3.3.4 – Control Structures

    +The control structures +if, while, and repeat have the usual meaning and +familiar syntax: + + + + +

    +	stat ::= while exp do block end
    +	stat ::= repeat block until exp
    +	stat ::= if exp then block {elseif exp then block} [else block] end
    +

    +Lua also has a for statement, in two flavors (see §3.3.5). + + +

    +The condition expression of a +control structure can return any value. +Both false and nil are considered false. +All values different from nil and false are considered true +(in particular, the number 0 and the empty string are also true). + + +

    +In the repeatuntil loop, +the inner block does not end at the until keyword, +but only after the condition. +So, the condition can refer to local variables +declared inside the loop block. + + +

    +The goto statement transfers the program control to a label. +For syntactical reasons, +labels in Lua are considered statements too: + + + +

    +	stat ::= goto Name
    +	stat ::= label
    +	label ::= ‘::’ Name ‘::’
    +
    + +

    +A label is visible in the entire block where it is defined, +except +inside nested blocks where a label with the same name is defined and +inside nested functions. +A goto may jump to any visible label as long as it does not +enter into the scope of a local variable. + + +

    +Labels and empty statements are called void statements, +as they perform no actions. + + +

    +The break statement terminates the execution of a +while, repeat, or for loop, +skipping to the next statement after the loop: + + +

    +	stat ::= break
    +

    +A break ends the innermost enclosing loop. + + +

    +The return statement is used to return values +from a function or a chunk (which is a function in disguise). + +Functions can return more than one value, +so the syntax for the return statement is + +

    +	stat ::= return [explist] [‘;’]
    +
    + +

    +The return statement can only be written +as the last statement of a block. +If it is really necessary to return in the middle of a block, +then an explicit inner block can be used, +as in the idiom do return end, +because now return is the last statement in its (inner) block. + + + + + +

    3.3.5 – For Statement

    + +

    + +The for statement has two forms: +one numeric and one generic. + + +

    +The numeric for loop repeats a block of code while a +control variable runs through an arithmetic progression. +It has the following syntax: + +

    +	stat ::= for Name ‘=’ exp ‘,’ exp [‘,’ exp] do block end
    +

    +The block is repeated for name starting at the value of +the first exp, until it passes the second exp by steps of the +third exp. +More precisely, a for statement like + +

    +     for v = e1, e2, e3 do block end
    +

    +is equivalent to the code: + +

    +     do
    +       local var, limit, step = tonumber(e1), tonumber(e2), tonumber(e3)
    +       if not (var and limit and step) then error() end
    +       while (step > 0 and var <= limit) or (step <= 0 and var >= limit) do
    +         local v = var
    +         block
    +         var = var + step
    +       end
    +     end
    +

    +Note the following: + +

      + +
    • +All three control expressions are evaluated only once, +before the loop starts. +They must all result in numbers. +
    • + +
    • +var, limit, and step are invisible variables. +The names shown here are for explanatory purposes only. +
    • + +
    • +If the third expression (the step) is absent, +then a step of 1 is used. +
    • + +
    • +You can use break to exit a for loop. +
    • + +
    • +The loop variable v is local to the loop; +you cannot use its value after the for ends or is broken. +If you need this value, +assign it to another variable before breaking or exiting the loop. +
    • + +
    + +

    +The generic for statement works over functions, +called iterators. +On each iteration, the iterator function is called to produce a new value, +stopping when this new value is nil. +The generic for loop has the following syntax: + +

    +	stat ::= for namelist in explist do block end
    +	namelist ::= Name {‘,’ Name}
    +

    +A for statement like + +

    +     for var_1, ···, var_n in explist do block end
    +

    +is equivalent to the code: + +

    +     do
    +       local f, s, var = explist
    +       while true do
    +         local var_1, ···, var_n = f(s, var)
    +         if var_1 == nil then break end
    +         var = var_1
    +         block
    +       end
    +     end
    +

    +Note the following: + +

      + +
    • +explist is evaluated only once. +Its results are an iterator function, +a state, +and an initial value for the first iterator variable. +
    • + +
    • +f, s, and var are invisible variables. +The names are here for explanatory purposes only. +
    • + +
    • +You can use break to exit a for loop. +
    • + +
    • +The loop variables var_i are local to the loop; +you cannot use their values after the for ends. +If you need these values, +then assign them to other variables before breaking or exiting the loop. +
    • + +
    + + + + +

    3.3.6 – Function Calls as Statements

    +To allow possible side-effects, +function calls can be executed as statements: + +

    +	stat ::= functioncall
    +

    +In this case, all returned values are thrown away. +Function calls are explained in §3.4.9. + + + + + +

    3.3.7 – Local Declarations

    +Local variables can be declared anywhere inside a block. +The declaration can include an initial assignment: + +

    +	stat ::= local namelist [‘=’ explist]
    +

    +If present, an initial assignment has the same semantics +of a multiple assignment (see §3.3.3). +Otherwise, all variables are initialized with nil. + + +

    +A chunk is also a block (see §3.3.2), +and so local variables can be declared in a chunk outside any explicit block. + + +

    +The visibility rules for local variables are explained in §3.5. + + + + + + + +

    3.4 – Expressions

    + +

    +The basic expressions in Lua are the following: + +

    +	exp ::= prefixexp
    +	exp ::= nil | false | true
    +	exp ::= Number
    +	exp ::= String
    +	exp ::= functiondef
    +	exp ::= tableconstructor
    +	exp ::= ‘...’
    +	exp ::= exp binop exp
    +	exp ::= unop exp
    +	prefixexp ::= var | functioncall | ‘(’ exp ‘)’
    +
    + +

    +Numbers and literal strings are explained in §3.1; +variables are explained in §3.2; +function definitions are explained in §3.4.10; +function calls are explained in §3.4.9; +table constructors are explained in §3.4.8. +Vararg expressions, +denoted by three dots ('...'), can only be used when +directly inside a vararg function; +they are explained in §3.4.10. + + +

    +Binary operators comprise arithmetic operators (see §3.4.1), +relational operators (see §3.4.3), logical operators (see §3.4.4), +and the concatenation operator (see §3.4.5). +Unary operators comprise the unary minus (see §3.4.1), +the unary not (see §3.4.4), +and the unary length operator (see §3.4.6). + + +

    +Both function calls and vararg expressions can result in multiple values. +If a function call is used as a statement (see §3.3.6), +then its return list is adjusted to zero elements, +thus discarding all returned values. +If an expression is used as the last (or the only) element +of a list of expressions, +then no adjustment is made +(unless the expression is enclosed in parentheses). +In all other contexts, +Lua adjusts the result list to one element, +either discarding all values except the first one +or adding a single nil if there are no values. + + +

    +Here are some examples: + +

    +     f()                -- adjusted to 0 results
    +     g(f(), x)          -- f() is adjusted to 1 result
    +     g(x, f())          -- g gets x plus all results from f()
    +     a,b,c = f(), x     -- f() is adjusted to 1 result (c gets nil)
    +     a,b = ...          -- a gets the first vararg parameter, b gets
    +                        -- the second (both a and b can get nil if there
    +                        -- is no corresponding vararg parameter)
    +     
    +     a,b,c = x, f()     -- f() is adjusted to 2 results
    +     a,b,c = f()        -- f() is adjusted to 3 results
    +     return f()         -- returns all results from f()
    +     return ...         -- returns all received vararg parameters
    +     return x,y,f()     -- returns x, y, and all results from f()
    +     {f()}              -- creates a list with all results from f()
    +     {...}              -- creates a list with all vararg parameters
    +     {f(), nil}         -- f() is adjusted to 1 result
    +
    + +

    +Any expression enclosed in parentheses always results in only one value. +Thus, +(f(x,y,z)) is always a single value, +even if f returns several values. +(The value of (f(x,y,z)) is the first value returned by f +or nil if f does not return any values.) + + + +

    3.4.1 – Arithmetic Operators

    +Lua supports the usual arithmetic operators: +the binary + (addition), +- (subtraction), * (multiplication), +/ (division), % (modulo), and ^ (exponentiation); +and unary - (mathematical negation). +If the operands are numbers, or strings that can be converted to +numbers (see §3.4.2), +then all operations have the usual meaning. +Exponentiation works for any exponent. +For instance, x^(-0.5) computes the inverse of the square root of x. +Modulo is defined as + +

    +     a % b == a - math.floor(a/b)*b
    +

    +That is, it is the remainder of a division that rounds +the quotient towards minus infinity. + + + + + +

    3.4.2 – Coercion

    + +

    +Lua provides automatic conversion between +string and number values at run time. +Any arithmetic operation applied to a string tries to convert +this string to a number, following the rules of the Lua lexer. +(The string may have leading and trailing spaces and a sign.) +Conversely, whenever a number is used where a string is expected, +the number is converted to a string, in a reasonable format. +For complete control over how numbers are converted to strings, +use the format function from the string library +(see string.format). + + + + + +

    3.4.3 – Relational Operators

    +The relational operators in Lua are + +

    +     ==    ~=    <     >     <=    >=
    +

    +These operators always result in false or true. + + +

    +Equality (==) first compares the type of its operands. +If the types are different, then the result is false. +Otherwise, the values of the operands are compared. +Numbers and strings are compared in the usual way. +Tables, userdata, and threads +are compared by reference: +two objects are considered equal only if they are the same object. +Every time you create a new object +(a table, userdata, or thread), +this new object is different from any previously existing object. +Closures with the same reference are always equal. +Closures with any detectable difference +(different behavior, different definition) are always different. + + +

    +You can change the way that Lua compares tables and userdata +by using the "eq" metamethod (see §2.4). + + +

    +The conversion rules of §3.4.2 +do not apply to equality comparisons. +Thus, "0"==0 evaluates to false, +and t[0] and t["0"] denote different +entries in a table. + + +

    +The operator ~= is exactly the negation of equality (==). + + +

    +The order operators work as follows. +If both arguments are numbers, then they are compared as such. +Otherwise, if both arguments are strings, +then their values are compared according to the current locale. +Otherwise, Lua tries to call the "lt" or the "le" +metamethod (see §2.4). +A comparison a > b is translated to b < a +and a >= b is translated to b <= a. + + + + + +

    3.4.4 – Logical Operators

    +The logical operators in Lua are +and, or, and not. +Like the control structures (see §3.3.4), +all logical operators consider both false and nil as false +and anything else as true. + + +

    +The negation operator not always returns false or true. +The conjunction operator and returns its first argument +if this value is false or nil; +otherwise, and returns its second argument. +The disjunction operator or returns its first argument +if this value is different from nil and false; +otherwise, or returns its second argument. +Both and and or use short-cut evaluation; +that is, +the second operand is evaluated only if necessary. +Here are some examples: + +

    +     10 or 20            --> 10
    +     10 or error()       --> 10
    +     nil or "a"          --> "a"
    +     nil and 10          --> nil
    +     false and error()   --> false
    +     false and nil       --> false
    +     false or nil        --> nil
    +     10 and 20           --> 20
    +

    +(In this manual, +--> indicates the result of the preceding expression.) + + + + + +

    3.4.5 – Concatenation

    +The string concatenation operator in Lua is +denoted by two dots ('..'). +If both operands are strings or numbers, then they are converted to +strings according to the rules mentioned in §3.4.2. +Otherwise, the __concat metamethod is called (see §2.4). + + + + + +

    3.4.6 – The Length Operator

    + +

    +The length operator is denoted by the unary prefix operator #. +The length of a string is its number of bytes +(that is, the usual meaning of string length when each +character is one byte). + + +

    +A program can modify the behavior of the length operator for +any value but strings through the __len metamethod (see §2.4). + + +

    +Unless a __len metamethod is given, +the length of a table t is only defined if the +table is a sequence, +that is, +the set of its positive numeric keys is equal to {1..n} +for some integer n. +In that case, n is its length. +Note that a table like + +

    +     {10, 20, nil, 40}
    +

    +is not a sequence, because it has the key 4 +but does not have the key 3. +(So, there is no n such that the set {1..n} is equal +to the set of positive numeric keys of that table.) +Note, however, that non-numeric keys do not interfere +with whether a table is a sequence. + + + + + +

    3.4.7 – Precedence

    +Operator precedence in Lua follows the table below, +from lower to higher priority: + +

    +     or
    +     and
    +     <     >     <=    >=    ~=    ==
    +     ..
    +     +     -
    +     *     /     %
    +     not   #     - (unary)
    +     ^
    +

    +As usual, +you can use parentheses to change the precedences of an expression. +The concatenation ('..') and exponentiation ('^') +operators are right associative. +All other binary operators are left associative. + + + + + +

    3.4.8 – Table Constructors

    +Table constructors are expressions that create tables. +Every time a constructor is evaluated, a new table is created. +A constructor can be used to create an empty table +or to create a table and initialize some of its fields. +The general syntax for constructors is + +

    +	tableconstructor ::= ‘{’ [fieldlist] ‘}’
    +	fieldlist ::= field {fieldsep field} [fieldsep]
    +	field ::= ‘[’ exp ‘]’ ‘=’ exp | Name ‘=’ exp | exp
    +	fieldsep ::= ‘,’ | ‘;’
    +
    + +

    +Each field of the form [exp1] = exp2 adds to the new table an entry +with key exp1 and value exp2. +A field of the form name = exp is equivalent to +["name"] = exp. +Finally, fields of the form exp are equivalent to +[i] = exp, where i are consecutive numerical integers, +starting with 1. +Fields in the other formats do not affect this counting. +For example, + +

    +     a = { [f(1)] = g; "x", "y"; x = 1, f(x), [30] = 23; 45 }
    +

    +is equivalent to + +

    +     do
    +       local t = {}
    +       t[f(1)] = g
    +       t[1] = "x"         -- 1st exp
    +       t[2] = "y"         -- 2nd exp
    +       t.x = 1            -- t["x"] = 1
    +       t[3] = f(x)        -- 3rd exp
    +       t[30] = 23
    +       t[4] = 45          -- 4th exp
    +       a = t
    +     end
    +
    + +

    +If the last field in the list has the form exp +and the expression is a function call or a vararg expression, +then all values returned by this expression enter the list consecutively +(see §3.4.9). + + +

    +The field list can have an optional trailing separator, +as a convenience for machine-generated code. + + + + + +

    3.4.9 – Function Calls

    +A function call in Lua has the following syntax: + +

    +	functioncall ::= prefixexp args
    +

    +In a function call, +first prefixexp and args are evaluated. +If the value of prefixexp has type function, +then this function is called +with the given arguments. +Otherwise, the prefixexp "call" metamethod is called, +having as first parameter the value of prefixexp, +followed by the original call arguments +(see §2.4). + + +

    +The form + +

    +	functioncall ::= prefixexp ‘:’ Name args
    +

    +can be used to call "methods". +A call v:name(args) +is syntactic sugar for v.name(v,args), +except that v is evaluated only once. + + +

    +Arguments have the following syntax: + +

    +	args ::= ‘(’ [explist] ‘)’
    +	args ::= tableconstructor
    +	args ::= String
    +

    +All argument expressions are evaluated before the call. +A call of the form f{fields} is +syntactic sugar for f({fields}); +that is, the argument list is a single new table. +A call of the form f'string' +(or f"string" or f[[string]]) +is syntactic sugar for f('string'); +that is, the argument list is a single literal string. + + +

    +A call of the form return functioncall is called +a tail call. +Lua implements proper tail calls +(or proper tail recursion): +in a tail call, +the called function reuses the stack entry of the calling function. +Therefore, there is no limit on the number of nested tail calls that +a program can execute. +However, a tail call erases any debug information about the +calling function. +Note that a tail call only happens with a particular syntax, +where the return has one single function call as argument; +this syntax makes the calling function return exactly +the returns of the called function. +So, none of the following examples are tail calls: + +

    +     return (f(x))        -- results adjusted to 1
    +     return 2 * f(x)
    +     return x, f(x)       -- additional results
    +     f(x); return         -- results discarded
    +     return x or f(x)     -- results adjusted to 1
    +
    + + + + +

    3.4.10 – Function Definitions

    + +

    +The syntax for function definition is + +

    +	functiondef ::= function funcbody
    +	funcbody ::= ‘(’ [parlist] ‘)’ block end
    +
    + +

    +The following syntactic sugar simplifies function definitions: + +

    +	stat ::= function funcname funcbody
    +	stat ::= local function Name funcbody
    +	funcname ::= Name {‘.’ Name} [‘:’ Name]
    +

    +The statement + +

    +     function f () body end
    +

    +translates to + +

    +     f = function () body end
    +

    +The statement + +

    +     function t.a.b.c.f () body end
    +

    +translates to + +

    +     t.a.b.c.f = function () body end
    +

    +The statement + +

    +     local function f () body end
    +

    +translates to + +

    +     local f; f = function () body end
    +

    +not to + +

    +     local f = function () body end
    +

    +(This only makes a difference when the body of the function +contains references to f.) + + +

    +A function definition is an executable expression, +whose value has type function. +When Lua precompiles a chunk, +all its function bodies are precompiled too. +Then, whenever Lua executes the function definition, +the function is instantiated (or closed). +This function instance (or closure) +is the final value of the expression. + + +

    +Parameters act as local variables that are +initialized with the argument values: + +

    +	parlist ::= namelist [‘,’ ‘...’] | ‘...’
    +

    +When a function is called, +the list of arguments is adjusted to +the length of the list of parameters, +unless the function is a vararg function, +which is indicated by three dots ('...') +at the end of its parameter list. +A vararg function does not adjust its argument list; +instead, it collects all extra arguments and supplies them +to the function through a vararg expression, +which is also written as three dots. +The value of this expression is a list of all actual extra arguments, +similar to a function with multiple results. +If a vararg expression is used inside another expression +or in the middle of a list of expressions, +then its return list is adjusted to one element. +If the expression is used as the last element of a list of expressions, +then no adjustment is made +(unless that last expression is enclosed in parentheses). + + +

    +As an example, consider the following definitions: + +

    +     function f(a, b) end
    +     function g(a, b, ...) end
    +     function r() return 1,2,3 end
    +

    +Then, we have the following mapping from arguments to parameters and +to the vararg expression: + +

    +     CALL            PARAMETERS
    +     
    +     f(3)             a=3, b=nil
    +     f(3, 4)          a=3, b=4
    +     f(3, 4, 5)       a=3, b=4
    +     f(r(), 10)       a=1, b=10
    +     f(r())           a=1, b=2
    +     
    +     g(3)             a=3, b=nil, ... -->  (nothing)
    +     g(3, 4)          a=3, b=4,   ... -->  (nothing)
    +     g(3, 4, 5, 8)    a=3, b=4,   ... -->  5  8
    +     g(5, r())        a=5, b=1,   ... -->  2  3
    +
    + +

    +Results are returned using the return statement (see §3.3.4). +If control reaches the end of a function +without encountering a return statement, +then the function returns with no results. + + +

    + +There is a system-dependent limit on the number of values +that a function may return. +This limit is guaranteed to be larger than 1000. + + +

    +The colon syntax +is used for defining methods, +that is, functions that have an implicit extra parameter self. +Thus, the statement + +

    +     function t.a.b.c:f (params) body end
    +

    +is syntactic sugar for + +

    +     t.a.b.c.f = function (self, params) body end
    +
    + + + + + + +

    3.5 – Visibility Rules

    + +

    + +Lua is a lexically scoped language. +The scope of a local variable begins at the first statement after +its declaration and lasts until the last non-void statement +of the innermost block that includes the declaration. +Consider the following example: + +

    +     x = 10                -- global variable
    +     do                    -- new block
    +       local x = x         -- new 'x', with value 10
    +       print(x)            --> 10
    +       x = x+1
    +       do                  -- another block
    +         local x = x+1     -- another 'x'
    +         print(x)          --> 12
    +       end
    +       print(x)            --> 11
    +     end
    +     print(x)              --> 10  (the global one)
    +
    + +

    +Notice that, in a declaration like local x = x, +the new x being declared is not in scope yet, +and so the second x refers to the outside variable. + + +

    +Because of the lexical scoping rules, +local variables can be freely accessed by functions +defined inside their scope. +A local variable used by an inner function is called +an upvalue, or external local variable, +inside the inner function. + + +

    +Notice that each execution of a local statement +defines new local variables. +Consider the following example: + +

    +     a = {}
    +     local x = 20
    +     for i=1,10 do
    +       local y = 0
    +       a[i] = function () y=y+1; return x+y end
    +     end
    +

    +The loop creates ten closures +(that is, ten instances of the anonymous function). +Each of these closures uses a different y variable, +while all of them share the same x. + + + + + +

    4 – The Application Program Interface

    + +

    + +This section describes the C API for Lua, that is, +the set of C functions available to the host program to communicate +with Lua. +All API functions and related types and constants +are declared in the header file lua.h. + + +

    +Even when we use the term "function", +any facility in the API may be provided as a macro instead. +Except where stated otherwise, +all such macros use each of their arguments exactly once +(except for the first argument, which is always a Lua state), +and so do not generate any hidden side-effects. + + +

    +As in most C libraries, +the Lua API functions do not check their arguments for validity or consistency. +However, you can change this behavior by compiling Lua +with the macro LUA_USE_APICHECK defined. + + + +

    4.1 – The Stack

    + +

    +Lua uses a virtual stack to pass values to and from C. +Each element in this stack represents a Lua value +(nil, number, string, etc.). + + +

    +Whenever Lua calls C, the called function gets a new stack, +which is independent of previous stacks and of stacks of +C functions that are still active. +This stack initially contains any arguments to the C function +and it is where the C function pushes its results +to be returned to the caller (see lua_CFunction). + + +

    +For convenience, +most query operations in the API do not follow a strict stack discipline. +Instead, they can refer to any element in the stack +by using an index: +A positive index represents an absolute stack position +(starting at 1); +a negative index represents an offset relative to the top of the stack. +More specifically, if the stack has n elements, +then index 1 represents the first element +(that is, the element that was pushed onto the stack first) +and +index n represents the last element; +index -1 also represents the last element +(that is, the element at the top) +and index -n represents the first element. + + + + + +

    4.2 – Stack Size

    + +

    +When you interact with the Lua API, +you are responsible for ensuring consistency. +In particular, +you are responsible for controlling stack overflow. +You can use the function lua_checkstack +to ensure that the stack has extra slots when pushing new elements. + + +

    +Whenever Lua calls C, +it ensures that the stack has at least LUA_MINSTACK extra slots. +LUA_MINSTACK is defined as 20, +so that usually you do not have to worry about stack space +unless your code has loops pushing elements onto the stack. + + +

    +When you call a Lua function +without a fixed number of results (see lua_call), +Lua ensures that the stack has enough size for all results, +but it does not ensure any extra space. +So, before pushing anything in the stack after such a call +you should use lua_checkstack. + + + + + +

    4.3 – Valid and Acceptable Indices

    + +

    +Any function in the API that receives stack indices +works only with valid indices or acceptable indices. + + +

    +A valid index is an index that refers to a +real position within the stack, that is, +its position lies between 1 and the stack top +(1 ≤ abs(index) ≤ top). + +Usually, functions that can modify the value at an index +require valid indices. + + +

    +Unless otherwise noted, +any function that accepts valid indices also accepts pseudo-indices, +which represent some Lua values that are accessible to C code +but which are not in the stack. +Pseudo-indices are used to access the registry +and the upvalues of a C function (see §4.4). + + +

    +Functions that do not need a specific stack position, +but only a value in the stack (e.g., query functions), +can be called with acceptable indices. +An acceptable index can be any valid index, +including the pseudo-indices, +but it also can be any positive index after the stack top +within the space allocated for the stack, +that is, indices up to the stack size. +(Note that 0 is never an acceptable index.) +Except when noted otherwise, +functions in the API work with acceptable indices. + + +

    +Acceptable indices serve to avoid extra tests +against the stack top when querying the stack. +For instance, a C function can query its third argument +without the need to first check whether there is a third argument, +that is, without the need to check whether 3 is a valid index. + + +

    +For functions that can be called with acceptable indices, +any non-valid index is treated as if it +contains a value of a virtual type LUA_TNONE, +which behaves like a nil value. + + + + + +

    4.4 – C Closures

    + +

    +When a C function is created, +it is possible to associate some values with it, +thus creating a C closure +(see lua_pushcclosure); +these values are called upvalues and are +accessible to the function whenever it is called. + + +

    +Whenever a C function is called, +its upvalues are located at specific pseudo-indices. +These pseudo-indices are produced by the macro +lua_upvalueindex. +The first value associated with a function is at position +lua_upvalueindex(1), and so on. +Any access to lua_upvalueindex(n), +where n is greater than the number of upvalues of the +current function (but not greater than 256), +produces an acceptable but invalid index. + + + + + +

    4.5 – Registry

    + +

    +Lua provides a registry, +a predefined table that can be used by any C code to +store whatever Lua values it needs to store. +The registry table is always located at pseudo-index +LUA_REGISTRYINDEX, +which is a valid index. +Any C library can store data into this table, +but it should take care to choose keys +that are different from those used +by other libraries, to avoid collisions. +Typically, you should use as key a string containing your library name, +or a light userdata with the address of a C object in your code, +or any Lua object created by your code. +As with global names, +string keys starting with an underscore followed by +uppercase letters are reserved for Lua. + + +

    +The integer keys in the registry are used by the reference mechanism, +implemented by the auxiliary library, +and by some predefined values. +Therefore, integer keys should not be used for other purposes. + + +

    +When you create a new Lua state, +its registry comes with some predefined values. +These predefined values are indexed with integer keys +defined as constants in lua.h. +The following constants are defined: + +

      +
    • LUA_RIDX_MAINTHREAD: At this index the registry has +the main thread of the state. +(The main thread is the one created together with the state.) +
    • + +
    • LUA_RIDX_GLOBALS: At this index the registry has +the global environment. +
    • +
    + + + + +

    4.6 – Error Handling in C

    + +

    +Internally, Lua uses the C longjmp facility to handle errors. +(You can also choose to use exceptions if you compile Lua as C++; +search for LUAI_THROW in the source code.) +When Lua faces any error +(such as a memory allocation error, type errors, syntax errors, +and runtime errors) +it raises an error; +that is, it does a long jump. +A protected environment uses setjmp +to set a recovery point; +any error jumps to the most recent active recovery point. + + +

    +If an error happens outside any protected environment, +Lua calls a panic function (see lua_atpanic) +and then calls abort, +thus exiting the host application. +Your panic function can avoid this exit by +never returning +(e.g., doing a long jump to your own recovery point outside Lua). + + +

    +The panic function runs as if it were a message handler (see §2.3); +in particular, the error message is at the top of the stack. +However, there is no guarantees about stack space. +To push anything on the stack, +the panic function should first check the available space (see §4.2). + + +

    +Most functions in the API can throw an error, +for instance due to a memory allocation error. +The documentation for each function indicates whether +it can throw errors. + + +

    +Inside a C function you can throw an error by calling lua_error. + + + + + +

    4.7 – Handling Yields in C

    + +

    +Internally, Lua uses the C longjmp facility to yield a coroutine. +Therefore, if a function foo calls an API function +and this API function yields +(directly or indirectly by calling another function that yields), +Lua cannot return to foo any more, +because the longjmp removes its frame from the C stack. + + +

    +To avoid this kind of problem, +Lua raises an error whenever it tries to yield across an API call, +except for three functions: +lua_yieldk, lua_callk, and lua_pcallk. +All those functions receive a continuation function +(as a parameter called k) to continue execution after a yield. + + +

    +We need to set some terminology to explain continuations. +We have a C function called from Lua which we will call +the original function. +This original function then calls one of those three functions in the C API, +which we will call the callee function, +that then yields the current thread. +(This can happen when the callee function is lua_yieldk, +or when the callee function is either lua_callk or lua_pcallk +and the function called by them yields.) + + +

    +Suppose the running thread yields while executing the callee function. +After the thread resumes, +it eventually will finish running the callee function. +However, +the callee function cannot return to the original function, +because its frame in the C stack was destroyed by the yield. +Instead, Lua calls a continuation function, +which was given as an argument to the callee function. +As the name implies, +the continuation function should continue the task +of the original function. + + +

    +Lua treats the continuation function as if it were the original function. +The continuation function receives the same Lua stack +from the original function, +in the same state it would be if the callee function had returned. +(For instance, +after a lua_callk the function and its arguments are +removed from the stack and replaced by the results from the call.) +It also has the same upvalues. +Whatever it returns is handled by Lua as if it were the return +of the original function. + + +

    +The only difference in the Lua state between the original function +and its continuation is the result of a call to lua_getctx. + + + + + +

    4.8 – Functions and Types

    + +

    +Here we list all functions and types from the C API in +alphabetical order. +Each function has an indicator like this: +[-o, +p, x] + + +

    +The first field, o, +is how many elements the function pops from the stack. +The second field, p, +is how many elements the function pushes onto the stack. +(Any function always pushes its results after popping its arguments.) +A field in the form x|y means the function can push (or pop) +x or y elements, +depending on the situation; +an interrogation mark '?' means that +we cannot know how many elements the function pops/pushes +by looking only at its arguments +(e.g., they may depend on what is on the stack). +The third field, x, +tells whether the function may throw errors: +'-' means the function never throws any error; +'e' means the function may throw errors; +'v' means the function may throw an error on purpose. + + + +


    lua_absindex

    +[-0, +0, –] +

    int lua_absindex (lua_State *L, int idx);
    + +

    +Converts the acceptable index idx into an absolute index +(that is, one that does not depend on the stack top). + + + + + +


    lua_Alloc

    +
    typedef void * (*lua_Alloc) (void *ud,
    +                             void *ptr,
    +                             size_t osize,
    +                             size_t nsize);
    + +

    +The type of the memory-allocation function used by Lua states. +The allocator function must provide a +functionality similar to realloc, +but not exactly the same. +Its arguments are +ud, an opaque pointer passed to lua_newstate; +ptr, a pointer to the block being allocated/reallocated/freed; +osize, the original size of the block or some code about what +is being allocated; +nsize, the new size of the block. + + +

    +When ptr is not NULL, +osize is the size of the block pointed by ptr, +that is, the size given when it was allocated or reallocated. + + +

    +When ptr is NULL, +osize encodes the kind of object that Lua is allocating. +osize is any of +LUA_TSTRING, LUA_TTABLE, LUA_TFUNCTION, +LUA_TUSERDATA, or LUA_TTHREAD when (and only when) +Lua is creating a new object of that type. +When osize is some other value, +Lua is allocating memory for something else. + + +

    +Lua assumes the following behavior from the allocator function: + + +

    +When nsize is zero, +the allocator should behave like free +and return NULL. + + +

    +When nsize is not zero, +the allocator should behave like realloc. +The allocator returns NULL +if and only if it cannot fulfill the request. +Lua assumes that the allocator never fails when +osize >= nsize. + + +

    +Here is a simple implementation for the allocator function. +It is used in the auxiliary library by luaL_newstate. + +

    +     static void *l_alloc (void *ud, void *ptr, size_t osize,
    +                                                size_t nsize) {
    +       (void)ud;  (void)osize;  /* not used */
    +       if (nsize == 0) {
    +         free(ptr);
    +         return NULL;
    +       }
    +       else
    +         return realloc(ptr, nsize);
    +     }
    +

    +Note that Standard C ensures +that free(NULL) has no effect and that +realloc(NULL, size) is equivalent to malloc(size). +This code assumes that realloc does not fail when shrinking a block. +(Although Standard C does not ensure this behavior, +it seems to be a safe assumption.) + + + + + +


    lua_arith

    +[-(2|1), +1, e] +

    void lua_arith (lua_State *L, int op);
    + +

    +Performs an arithmetic operation over the two values +(or one, in the case of negation) +at the top of the stack, +with the value at the top being the second operand, +pops these values, and pushes the result of the operation. +The function follows the semantics of the corresponding Lua operator +(that is, it may call metamethods). + + +

    +The value of op must be one of the following constants: + +

    + + + + +

    lua_atpanic

    +[-0, +0, –] +

    lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);
    + +

    +Sets a new panic function and returns the old one (see §4.6). + + + + + +


    lua_call

    +[-(nargs+1), +nresults, e] +

    void lua_call (lua_State *L, int nargs, int nresults);
    + +

    +Calls a function. + + +

    +To call a function you must use the following protocol: +first, the function to be called is pushed onto the stack; +then, the arguments to the function are pushed +in direct order; +that is, the first argument is pushed first. +Finally you call lua_call; +nargs is the number of arguments that you pushed onto the stack. +All arguments and the function value are popped from the stack +when the function is called. +The function results are pushed onto the stack when the function returns. +The number of results is adjusted to nresults, +unless nresults is LUA_MULTRET. +In this case, all results from the function are pushed. +Lua takes care that the returned values fit into the stack space. +The function results are pushed onto the stack in direct order +(the first result is pushed first), +so that after the call the last result is on the top of the stack. + + +

    +Any error inside the called function is propagated upwards +(with a longjmp). + + +

    +The following example shows how the host program can do the +equivalent to this Lua code: + +

    +     a = f("how", t.x, 14)
    +

    +Here it is in C: + +

    +     lua_getglobal(L, "f");                  /* function to be called */
    +     lua_pushstring(L, "how");                        /* 1st argument */
    +     lua_getglobal(L, "t");                    /* table to be indexed */
    +     lua_getfield(L, -1, "x");        /* push result of t.x (2nd arg) */
    +     lua_remove(L, -2);                  /* remove 't' from the stack */
    +     lua_pushinteger(L, 14);                          /* 3rd argument */
    +     lua_call(L, 3, 1);     /* call 'f' with 3 arguments and 1 result */
    +     lua_setglobal(L, "a");                         /* set global 'a' */
    +

    +Note that the code above is "balanced": +at its end, the stack is back to its original configuration. +This is considered good programming practice. + + + + + +


    lua_callk

    +[-(nargs + 1), +nresults, e] +

    void lua_callk (lua_State *L, int nargs, int nresults, int ctx,
    +                lua_CFunction k);
    + +

    +This function behaves exactly like lua_call, +but allows the called function to yield (see §4.7). + + + + + +


    lua_CFunction

    +
    typedef int (*lua_CFunction) (lua_State *L);
    + +

    +Type for C functions. + + +

    +In order to communicate properly with Lua, +a C function must use the following protocol, +which defines the way parameters and results are passed: +a C function receives its arguments from Lua in its stack +in direct order (the first argument is pushed first). +So, when the function starts, +lua_gettop(L) returns the number of arguments received by the function. +The first argument (if any) is at index 1 +and its last argument is at index lua_gettop(L). +To return values to Lua, a C function just pushes them onto the stack, +in direct order (the first result is pushed first), +and returns the number of results. +Any other value in the stack below the results will be properly +discarded by Lua. +Like a Lua function, a C function called by Lua can also return +many results. + + +

    +As an example, the following function receives a variable number +of numerical arguments and returns their average and sum: + +

    +     static int foo (lua_State *L) {
    +       int n = lua_gettop(L);    /* number of arguments */
    +       lua_Number sum = 0;
    +       int i;
    +       for (i = 1; i <= n; i++) {
    +         if (!lua_isnumber(L, i)) {
    +           lua_pushstring(L, "incorrect argument");
    +           lua_error(L);
    +         }
    +         sum += lua_tonumber(L, i);
    +       }
    +       lua_pushnumber(L, sum/n);        /* first result */
    +       lua_pushnumber(L, sum);         /* second result */
    +       return 2;                   /* number of results */
    +     }
    +
    + + + + +

    lua_checkstack

    +[-0, +0, –] +

    int lua_checkstack (lua_State *L, int extra);
    + +

    +Ensures that there are at least extra free stack slots in the stack. +It returns false if it cannot fulfill the request, +because it would cause the stack to be larger than a fixed maximum size +(typically at least a few thousand elements) or +because it cannot allocate memory for the new stack size. +This function never shrinks the stack; +if the stack is already larger than the new size, +it is left unchanged. + + + + + +


    lua_close

    +[-0, +0, –] +

    void lua_close (lua_State *L);
    + +

    +Destroys all objects in the given Lua state +(calling the corresponding garbage-collection metamethods, if any) +and frees all dynamic memory used by this state. +On several platforms, you may not need to call this function, +because all resources are naturally released when the host program ends. +On the other hand, long-running programs that create multiple states, +such as daemons or web servers, +might need to close states as soon as they are not needed. + + + + + +


    lua_compare

    +[-0, +0, e] +

    int lua_compare (lua_State *L, int index1, int index2, int op);
    + +

    +Compares two Lua values. +Returns 1 if the value at index index1 satisfies op +when compared with the value at index index2, +following the semantics of the corresponding Lua operator +(that is, it may call metamethods). +Otherwise returns 0. +Also returns 0 if any of the indices is non valid. + + +

    +The value of op must be one of the following constants: + +

      + +
    • LUA_OPEQ: compares for equality (==)
    • +
    • LUA_OPLT: compares for less than (<)
    • +
    • LUA_OPLE: compares for less or equal (<=)
    • + +
    + + + + +

    lua_concat

    +[-n, +1, e] +

    void lua_concat (lua_State *L, int n);
    + +

    +Concatenates the n values at the top of the stack, +pops them, and leaves the result at the top. +If n is 1, the result is the single value on the stack +(that is, the function does nothing); +if n is 0, the result is the empty string. +Concatenation is performed following the usual semantics of Lua +(see §3.4.5). + + + + + +


    lua_copy

    +[-0, +0, –] +

    void lua_copy (lua_State *L, int fromidx, int toidx);
    + +

    +Moves the element at index fromidx +into the valid index toidx +without shifting any element +(therefore replacing the value at that position). + + + + + +


    lua_createtable

    +[-0, +1, e] +

    void lua_createtable (lua_State *L, int narr, int nrec);
    + +

    +Creates a new empty table and pushes it onto the stack. +Parameter narr is a hint for how many elements the table +will have as a sequence; +parameter nrec is a hint for how many other elements +the table will have. +Lua may use these hints to preallocate memory for the new table. +This pre-allocation is useful for performance when you know in advance +how many elements the table will have. +Otherwise you can use the function lua_newtable. + + + + + +


    lua_dump

    +[-0, +0, e] +

    int lua_dump (lua_State *L, lua_Writer writer, void *data);
    + +

    +Dumps a function as a binary chunk. +Receives a Lua function on the top of the stack +and produces a binary chunk that, +if loaded again, +results in a function equivalent to the one dumped. +As it produces parts of the chunk, +lua_dump calls function writer (see lua_Writer) +with the given data +to write them. + + +

    +The value returned is the error code returned by the last +call to the writer; +0 means no errors. + + +

    +This function does not pop the Lua function from the stack. + + + + + +


    lua_error

    +[-1, +0, v] +

    int lua_error (lua_State *L);
    + +

    +Generates a Lua error. +The error message (which can actually be a Lua value of any type) +must be on the stack top. +This function does a long jump, +and therefore never returns +(see luaL_error). + + + + + +


    lua_gc

    +[-0, +0, e] +

    int lua_gc (lua_State *L, int what, int data);
    + +

    +Controls the garbage collector. + + +

    +This function performs several tasks, +according to the value of the parameter what: + +

      + +
    • LUA_GCSTOP: +stops the garbage collector. +
    • + +
    • LUA_GCRESTART: +restarts the garbage collector. +
    • + +
    • LUA_GCCOLLECT: +performs a full garbage-collection cycle. +
    • + +
    • LUA_GCCOUNT: +returns the current amount of memory (in Kbytes) in use by Lua. +
    • + +
    • LUA_GCCOUNTB: +returns the remainder of dividing the current amount of bytes of +memory in use by Lua by 1024. +
    • + +
    • LUA_GCSTEP: +performs an incremental step of garbage collection. +The step "size" is controlled by data +(larger values mean more steps) in a non-specified way. +If you want to control the step size +you must experimentally tune the value of data. +The function returns 1 if the step finished a +garbage-collection cycle. +
    • + +
    • LUA_GCSETPAUSE: +sets data as the new value +for the pause of the collector (see §2.5). +The function returns the previous value of the pause. +
    • + +
    • LUA_GCSETSTEPMUL: +sets data as the new value for the step multiplier of +the collector (see §2.5). +The function returns the previous value of the step multiplier. +
    • + +
    • LUA_GCISRUNNING: +returns a boolean that tells whether the collector is running +(i.e., not stopped). +
    • + +
    • LUA_GCGEN: +changes the collector to generational mode +(see §2.5). +
    • + +
    • LUA_GCINC: +changes the collector to incremental mode. +This is the default mode. +
    • + +
    + +

    +For more details about these options, +see collectgarbage. + + + + + +


    lua_getallocf

    +[-0, +0, –] +

    lua_Alloc lua_getallocf (lua_State *L, void **ud);
    + +

    +Returns the memory-allocation function of a given state. +If ud is not NULL, Lua stores in *ud the +opaque pointer passed to lua_newstate. + + + + + +


    lua_getctx

    +[-0, +0, –] +

    int lua_getctx (lua_State *L, int *ctx);
    + +

    +This function is called by a continuation function (see §4.7) +to retrieve the status of the thread and a context information. + + +

    +When called in the original function, +lua_getctx always returns LUA_OK +and does not change the value of its argument ctx. +When called inside a continuation function, +lua_getctx returns LUA_YIELD and sets +the value of ctx to be the context information +(the value passed as the ctx argument +to the callee together with the continuation function). + + +

    +When the callee is lua_pcallk, +Lua may also call its continuation function +to handle errors during the call. +That is, upon an error in the function called by lua_pcallk, +Lua may not return to the original function +but instead may call the continuation function. +In that case, a call to lua_getctx will return the error code +(the value that would be returned by lua_pcallk); +the value of ctx will be set to the context information, +as in the case of a yield. + + + + + +


    lua_getfield

    +[-0, +1, e] +

    void lua_getfield (lua_State *L, int index, const char *k);
    + +

    +Pushes onto the stack the value t[k], +where t is the value at the given index. +As in Lua, this function may trigger a metamethod +for the "index" event (see §2.4). + + + + + +


    lua_getglobal

    +[-0, +1, e] +

    void lua_getglobal (lua_State *L, const char *name);
    + +

    +Pushes onto the stack the value of the global name. + + + + + +


    lua_getmetatable

    +[-0, +(0|1), –] +

    int lua_getmetatable (lua_State *L, int index);
    + +

    +Pushes onto the stack the metatable of the value at the given index. +If the value does not have a metatable, +the function returns 0 and pushes nothing on the stack. + + + + + +


    lua_gettable

    +[-1, +1, e] +

    void lua_gettable (lua_State *L, int index);
    + +

    +Pushes onto the stack the value t[k], +where t is the value at the given index +and k is the value at the top of the stack. + + +

    +This function pops the key from the stack +(putting the resulting value in its place). +As in Lua, this function may trigger a metamethod +for the "index" event (see §2.4). + + + + + +


    lua_gettop

    +[-0, +0, –] +

    int lua_gettop (lua_State *L);
    + +

    +Returns the index of the top element in the stack. +Because indices start at 1, +this result is equal to the number of elements in the stack +(and so 0 means an empty stack). + + + + + +


    lua_getuservalue

    +[-0, +1, –] +

    void lua_getuservalue (lua_State *L, int index);
    + +

    +Pushes onto the stack the Lua value associated with the userdata +at the given index. +This Lua value must be a table or nil. + + + + + +


    lua_insert

    +[-1, +1, –] +

    void lua_insert (lua_State *L, int index);
    + +

    +Moves the top element into the given valid index, +shifting up the elements above this index to open space. +This function cannot be called with a pseudo-index, +because a pseudo-index is not an actual stack position. + + + + + +


    lua_Integer

    +
    typedef ptrdiff_t lua_Integer;
    + +

    +The type used by the Lua API to represent signed integral values. + + +

    +By default it is a ptrdiff_t, +which is usually the largest signed integral type the machine handles +"comfortably". + + + + + +


    lua_isboolean

    +[-0, +0, –] +

    int lua_isboolean (lua_State *L, int index);
    + +

    +Returns 1 if the value at the given index is a boolean, +and 0 otherwise. + + + + + +


    lua_iscfunction

    +[-0, +0, –] +

    int lua_iscfunction (lua_State *L, int index);
    + +

    +Returns 1 if the value at the given index is a C function, +and 0 otherwise. + + + + + +


    lua_isfunction

    +[-0, +0, –] +

    int lua_isfunction (lua_State *L, int index);
    + +

    +Returns 1 if the value at the given index is a function +(either C or Lua), and 0 otherwise. + + + + + +


    lua_islightuserdata

    +[-0, +0, –] +

    int lua_islightuserdata (lua_State *L, int index);
    + +

    +Returns 1 if the value at the given index is a light userdata, +and 0 otherwise. + + + + + +


    lua_isnil

    +[-0, +0, –] +

    int lua_isnil (lua_State *L, int index);
    + +

    +Returns 1 if the value at the given index is nil, +and 0 otherwise. + + + + + +


    lua_isnone

    +[-0, +0, –] +

    int lua_isnone (lua_State *L, int index);
    + +

    +Returns 1 if the given index is not valid, +and 0 otherwise. + + + + + +


    lua_isnoneornil

    +[-0, +0, –] +

    int lua_isnoneornil (lua_State *L, int index);
    + +

    +Returns 1 if the given index is not valid +or if the value at this index is nil, +and 0 otherwise. + + + + + +


    lua_isnumber

    +[-0, +0, –] +

    int lua_isnumber (lua_State *L, int index);
    + +

    +Returns 1 if the value at the given index is a number +or a string convertible to a number, +and 0 otherwise. + + + + + +


    lua_isstring

    +[-0, +0, –] +

    int lua_isstring (lua_State *L, int index);
    + +

    +Returns 1 if the value at the given index is a string +or a number (which is always convertible to a string), +and 0 otherwise. + + + + + +


    lua_istable

    +[-0, +0, –] +

    int lua_istable (lua_State *L, int index);
    + +

    +Returns 1 if the value at the given index is a table, +and 0 otherwise. + + + + + +


    lua_isthread

    +[-0, +0, –] +

    int lua_isthread (lua_State *L, int index);
    + +

    +Returns 1 if the value at the given index is a thread, +and 0 otherwise. + + + + + +


    lua_isuserdata

    +[-0, +0, –] +

    int lua_isuserdata (lua_State *L, int index);
    + +

    +Returns 1 if the value at the given index is a userdata +(either full or light), and 0 otherwise. + + + + + +


    lua_len

    +[-0, +1, e] +

    void lua_len (lua_State *L, int index);
    + +

    +Returns the "length" of the value at the given index; +it is equivalent to the '#' operator in Lua (see §3.4.6). +The result is pushed on the stack. + + + + + +


    lua_load

    +[-0, +1, –] +

    int lua_load (lua_State *L,
    +              lua_Reader reader,
    +              void *data,
    +              const char *source,
    +              const char *mode);
    + +

    +Loads a Lua chunk (without running it). +If there are no errors, +lua_load pushes the compiled chunk as a Lua +function on top of the stack. +Otherwise, it pushes an error message. + + +

    +The return values of lua_load are: + +

      + +
    • LUA_OK: no errors;
    • + +
    • LUA_ERRSYNTAX: +syntax error during precompilation;
    • + +
    • LUA_ERRMEM: +memory allocation error;
    • + +
    • LUA_ERRGCMM: +error while running a __gc metamethod. +(This error has no relation with the chunk being loaded. +It is generated by the garbage collector.) +
    • + +
    + +

    +The lua_load function uses a user-supplied reader function +to read the chunk (see lua_Reader). +The data argument is an opaque value passed to the reader function. + + +

    +The source argument gives a name to the chunk, +which is used for error messages and in debug information (see §4.9). + + +

    +lua_load automatically detects whether the chunk is text or binary +and loads it accordingly (see program luac). +The string mode works as in function load, +with the addition that +a NULL value is equivalent to the string "bt". + + +

    +lua_load uses the stack internally, +so the reader function should always leave the stack +unmodified when returning. + + +

    +If the resulting function has one upvalue, +this upvalue is set to the value of the global environment +stored at index LUA_RIDX_GLOBALS in the registry (see §4.5). +When loading main chunks, +this upvalue will be the _ENV variable (see §2.2). + + + + + +


    lua_newstate

    +[-0, +0, –] +

    lua_State *lua_newstate (lua_Alloc f, void *ud);
    + +

    +Creates a new thread running in a new, independent state. +Returns NULL if cannot create the thread or the state +(due to lack of memory). +The argument f is the allocator function; +Lua does all memory allocation for this state through this function. +The second argument, ud, is an opaque pointer that Lua +passes to the allocator in every call. + + + + + +


    lua_newtable

    +[-0, +1, e] +

    void lua_newtable (lua_State *L);
    + +

    +Creates a new empty table and pushes it onto the stack. +It is equivalent to lua_createtable(L, 0, 0). + + + + + +


    lua_newthread

    +[-0, +1, e] +

    lua_State *lua_newthread (lua_State *L);
    + +

    +Creates a new thread, pushes it on the stack, +and returns a pointer to a lua_State that represents this new thread. +The new thread returned by this function shares with the original thread +its global environment, +but has an independent execution stack. + + +

    +There is no explicit function to close or to destroy a thread. +Threads are subject to garbage collection, +like any Lua object. + + + + + +


    lua_newuserdata

    +[-0, +1, e] +

    void *lua_newuserdata (lua_State *L, size_t size);
    + +

    +This function allocates a new block of memory with the given size, +pushes onto the stack a new full userdata with the block address, +and returns this address. +The host program can freely use this memory. + + + + + +


    lua_next

    +[-1, +(2|0), e] +

    int lua_next (lua_State *L, int index);
    + +

    +Pops a key from the stack, +and pushes a key–value pair from the table at the given index +(the "next" pair after the given key). +If there are no more elements in the table, +then lua_next returns 0 (and pushes nothing). + + +

    +A typical traversal looks like this: + +

    +     /* table is in the stack at index 't' */
    +     lua_pushnil(L);  /* first key */
    +     while (lua_next(L, t) != 0) {
    +       /* uses 'key' (at index -2) and 'value' (at index -1) */
    +       printf("%s - %s\n",
    +              lua_typename(L, lua_type(L, -2)),
    +              lua_typename(L, lua_type(L, -1)));
    +       /* removes 'value'; keeps 'key' for next iteration */
    +       lua_pop(L, 1);
    +     }
    +
    + +

    +While traversing a table, +do not call lua_tolstring directly on a key, +unless you know that the key is actually a string. +Recall that lua_tolstring may change +the value at the given index; +this confuses the next call to lua_next. + + +

    +See function next for the caveats of modifying +the table during its traversal. + + + + + +


    lua_Number

    +
    typedef double lua_Number;
    + +

    +The type of numbers in Lua. +By default, it is double, but that can be changed in luaconf.h. +Through this configuration file you can change +Lua to operate with another type for numbers (e.g., float or long). + + + + + +


    lua_pcall

    +[-(nargs + 1), +(nresults|1), –] +

    int lua_pcall (lua_State *L, int nargs, int nresults, int msgh);
    + +

    +Calls a function in protected mode. + + +

    +Both nargs and nresults have the same meaning as +in lua_call. +If there are no errors during the call, +lua_pcall behaves exactly like lua_call. +However, if there is any error, +lua_pcall catches it, +pushes a single value on the stack (the error message), +and returns an error code. +Like lua_call, +lua_pcall always removes the function +and its arguments from the stack. + + +

    +If msgh is 0, +then the error message returned on the stack +is exactly the original error message. +Otherwise, msgh is the stack index of a +message handler. +(In the current implementation, this index cannot be a pseudo-index.) +In case of runtime errors, +this function will be called with the error message +and its return value will be the message +returned on the stack by lua_pcall. + + +

    +Typically, the message handler is used to add more debug +information to the error message, such as a stack traceback. +Such information cannot be gathered after the return of lua_pcall, +since by then the stack has unwound. + + +

    +The lua_pcall function returns one of the following codes +(defined in lua.h): + +

      + +
    • LUA_OK (0): +success.
    • + +
    • LUA_ERRRUN: +a runtime error. +
    • + +
    • LUA_ERRMEM: +memory allocation error. +For such errors, Lua does not call the message handler. +
    • + +
    • LUA_ERRERR: +error while running the message handler. +
    • + +
    • LUA_ERRGCMM: +error while running a __gc metamethod. +(This error typically has no relation with the function being called. +It is generated by the garbage collector.) +
    • + +
    + + + + +

    lua_pcallk

    +[-(nargs + 1), +(nresults|1), –] +

    int lua_pcallk (lua_State *L,
    +                int nargs,
    +                int nresults,
    +                int errfunc,
    +                int ctx,
    +                lua_CFunction k);
    + +

    +This function behaves exactly like lua_pcall, +but allows the called function to yield (see §4.7). + + + + + +


    lua_pop

    +[-n, +0, –] +

    void lua_pop (lua_State *L, int n);
    + +

    +Pops n elements from the stack. + + + + + +


    lua_pushboolean

    +[-0, +1, –] +

    void lua_pushboolean (lua_State *L, int b);
    + +

    +Pushes a boolean value with value b onto the stack. + + + + + +


    lua_pushcclosure

    +[-n, +1, e] +

    void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
    + +

    +Pushes a new C closure onto the stack. + + +

    +When a C function is created, +it is possible to associate some values with it, +thus creating a C closure (see §4.4); +these values are then accessible to the function whenever it is called. +To associate values with a C function, +first these values should be pushed onto the stack +(when there are multiple values, the first value is pushed first). +Then lua_pushcclosure +is called to create and push the C function onto the stack, +with the argument n telling how many values should be +associated with the function. +lua_pushcclosure also pops these values from the stack. + + +

    +The maximum value for n is 255. + + +

    +When n is zero, +this function creates a light C function, +which is just a pointer to the C function. +In that case, it never throws a memory error. + + + + + +


    lua_pushcfunction

    +[-0, +1, –] +

    void lua_pushcfunction (lua_State *L, lua_CFunction f);
    + +

    +Pushes a C function onto the stack. +This function receives a pointer to a C function +and pushes onto the stack a Lua value of type function that, +when called, invokes the corresponding C function. + + +

    +Any function to be registered in Lua must +follow the correct protocol to receive its parameters +and return its results (see lua_CFunction). + + +

    +lua_pushcfunction is defined as a macro: + +

    +     #define lua_pushcfunction(L,f)  lua_pushcclosure(L,f,0)
    +

    +Note that f is used twice. + + + + + +


    lua_pushfstring

    +[-0, +1, e] +

    const char *lua_pushfstring (lua_State *L, const char *fmt, ...);
    + +

    +Pushes onto the stack a formatted string +and returns a pointer to this string. +It is similar to the ANSI C function sprintf, +but has some important differences: + +

      + +
    • +You do not have to allocate space for the result: +the result is a Lua string and Lua takes care of memory allocation +(and deallocation, through garbage collection). +
    • + +
    • +The conversion specifiers are quite restricted. +There are no flags, widths, or precisions. +The conversion specifiers can only be +'%%' (inserts a '%' in the string), +'%s' (inserts a zero-terminated string, with no size restrictions), +'%f' (inserts a lua_Number), +'%p' (inserts a pointer as a hexadecimal numeral), +'%d' (inserts an int), and +'%c' (inserts an int as a byte). +
    • + +
    + + + + +

    lua_pushglobaltable

    +[-0, +1, –] +

    void lua_pushglobaltable (lua_State *L);
    + +

    +Pushes the global environment onto the stack. + + + + + +


    lua_pushinteger

    +[-0, +1, –] +

    void lua_pushinteger (lua_State *L, lua_Integer n);
    + +

    +Pushes a number with value n onto the stack. + + + + + +


    lua_pushlightuserdata

    +[-0, +1, –] +

    void lua_pushlightuserdata (lua_State *L, void *p);
    + +

    +Pushes a light userdata onto the stack. + + +

    +Userdata represent C values in Lua. +A light userdata represents a pointer, a void*. +It is a value (like a number): +you do not create it, it has no individual metatable, +and it is not collected (as it was never created). +A light userdata is equal to "any" +light userdata with the same C address. + + + + + +


    lua_pushliteral

    +[-0, +1, e] +

    const char *lua_pushliteral (lua_State *L, const char *s);
    + +

    +This macro is equivalent to lua_pushlstring, +but can be used only when s is a literal string. +It automatically provides the string length. + + + + + +


    lua_pushlstring

    +[-0, +1, e] +

    const char *lua_pushlstring (lua_State *L, const char *s, size_t len);
    + +

    +Pushes the string pointed to by s with size len +onto the stack. +Lua makes (or reuses) an internal copy of the given string, +so the memory at s can be freed or reused immediately after +the function returns. +The string can contain any binary data, +including embedded zeros. + + +

    +Returns a pointer to the internal copy of the string. + + + + + +


    lua_pushnil

    +[-0, +1, –] +

    void lua_pushnil (lua_State *L);
    + +

    +Pushes a nil value onto the stack. + + + + + +


    lua_pushnumber

    +[-0, +1, –] +

    void lua_pushnumber (lua_State *L, lua_Number n);
    + +

    +Pushes a number with value n onto the stack. + + + + + +


    lua_pushstring

    +[-0, +1, e] +

    const char *lua_pushstring (lua_State *L, const char *s);
    + +

    +Pushes the zero-terminated string pointed to by s +onto the stack. +Lua makes (or reuses) an internal copy of the given string, +so the memory at s can be freed or reused immediately after +the function returns. + + +

    +Returns a pointer to the internal copy of the string. + + +

    +If s is NULL, pushes nil and returns NULL. + + + + + +


    lua_pushthread

    +[-0, +1, –] +

    int lua_pushthread (lua_State *L);
    + +

    +Pushes the thread represented by L onto the stack. +Returns 1 if this thread is the main thread of its state. + + + + + +


    lua_pushunsigned

    +[-0, +1, –] +

    void lua_pushunsigned (lua_State *L, lua_Unsigned n);
    + +

    +Pushes a number with value n onto the stack. + + + + + +


    lua_pushvalue

    +[-0, +1, –] +

    void lua_pushvalue (lua_State *L, int index);
    + +

    +Pushes a copy of the element at the given index +onto the stack. + + + + + +


    lua_pushvfstring

    +[-0, +1, e] +

    const char *lua_pushvfstring (lua_State *L,
    +                              const char *fmt,
    +                              va_list argp);
    + +

    +Equivalent to lua_pushfstring, except that it receives a va_list +instead of a variable number of arguments. + + + + + +


    lua_rawequal

    +[-0, +0, –] +

    int lua_rawequal (lua_State *L, int index1, int index2);
    + +

    +Returns 1 if the two values in indices index1 and +index2 are primitively equal +(that is, without calling metamethods). +Otherwise returns 0. +Also returns 0 if any of the indices are non valid. + + + + + +


    lua_rawget

    +[-1, +1, –] +

    void lua_rawget (lua_State *L, int index);
    + +

    +Similar to lua_gettable, but does a raw access +(i.e., without metamethods). + + + + + +


    lua_rawgeti

    +[-0, +1, –] +

    void lua_rawgeti (lua_State *L, int index, int n);
    + +

    +Pushes onto the stack the value t[n], +where t is the table at the given index. +The access is raw; +that is, it does not invoke metamethods. + + + + + +


    lua_rawgetp

    +[-0, +1, –] +

    void lua_rawgetp (lua_State *L, int index, const void *p);
    + +

    +Pushes onto the stack the value t[k], +where t is the table at the given index and +k is the pointer p represented as a light userdata. +The access is raw; +that is, it does not invoke metamethods. + + + + + +


    lua_rawlen

    +[-0, +0, –] +

    size_t lua_rawlen (lua_State *L, int index);
    + +

    +Returns the raw "length" of the value at the given index: +for strings, this is the string length; +for tables, this is the result of the length operator ('#') +with no metamethods; +for userdata, this is the size of the block of memory allocated +for the userdata; +for other values, it is 0. + + + + + +


    lua_rawset

    +[-2, +0, e] +

    void lua_rawset (lua_State *L, int index);
    + +

    +Similar to lua_settable, but does a raw assignment +(i.e., without metamethods). + + + + + +


    lua_rawseti

    +[-1, +0, e] +

    void lua_rawseti (lua_State *L, int index, int n);
    + +

    +Does the equivalent of t[n] = v, +where t is the table at the given index +and v is the value at the top of the stack. + + +

    +This function pops the value from the stack. +The assignment is raw; +that is, it does not invoke metamethods. + + + + + +


    lua_rawsetp

    +[-1, +0, e] +

    void lua_rawsetp (lua_State *L, int index, const void *p);
    + +

    +Does the equivalent of t[k] = v, +where t is the table at the given index, +k is the pointer p represented as a light userdata, +and v is the value at the top of the stack. + + +

    +This function pops the value from the stack. +The assignment is raw; +that is, it does not invoke metamethods. + + + + + +


    lua_Reader

    +
    typedef const char * (*lua_Reader) (lua_State *L,
    +                                    void *data,
    +                                    size_t *size);
    + +

    +The reader function used by lua_load. +Every time it needs another piece of the chunk, +lua_load calls the reader, +passing along its data parameter. +The reader must return a pointer to a block of memory +with a new piece of the chunk +and set size to the block size. +The block must exist until the reader function is called again. +To signal the end of the chunk, +the reader must return NULL or set size to zero. +The reader function may return pieces of any size greater than zero. + + + + + +


    lua_register

    +[-0, +0, e] +

    void lua_register (lua_State *L, const char *name, lua_CFunction f);
    + +

    +Sets the C function f as the new value of global name. +It is defined as a macro: + +

    +     #define lua_register(L,n,f) \
    +            (lua_pushcfunction(L, f), lua_setglobal(L, n))
    +
    + + + + +

    lua_remove

    +[-1, +0, –] +

    void lua_remove (lua_State *L, int index);
    + +

    +Removes the element at the given valid index, +shifting down the elements above this index to fill the gap. +This function cannot be called with a pseudo-index, +because a pseudo-index is not an actual stack position. + + + + + +


    lua_replace

    +[-1, +0, –] +

    void lua_replace (lua_State *L, int index);
    + +

    +Moves the top element into the given valid index +without shifting any element +(therefore replacing the value at the given index), +and then pops the top element. + + + + + +


    lua_resume

    +[-?, +?, –] +

    int lua_resume (lua_State *L, lua_State *from, int nargs);
    + +

    +Starts and resumes a coroutine in a given thread. + + +

    +To start a coroutine, +you push onto the thread stack the main function plus any arguments; +then you call lua_resume, +with nargs being the number of arguments. +This call returns when the coroutine suspends or finishes its execution. +When it returns, the stack contains all values passed to lua_yield, +or all values returned by the body function. +lua_resume returns +LUA_YIELD if the coroutine yields, +LUA_OK if the coroutine finishes its execution +without errors, +or an error code in case of errors (see lua_pcall). + + +

    +In case of errors, +the stack is not unwound, +so you can use the debug API over it. +The error message is on the top of the stack. + + +

    +To resume a coroutine, +you remove any results from the last lua_yield, +put on its stack only the values to +be passed as results from yield, +and then call lua_resume. + + +

    +The parameter from represents the coroutine that is resuming L. +If there is no such coroutine, +this parameter can be NULL. + + + + + +


    lua_setallocf

    +[-0, +0, –] +

    void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
    + +

    +Changes the allocator function of a given state to f +with user data ud. + + + + + +


    lua_setfield

    +[-1, +0, e] +

    void lua_setfield (lua_State *L, int index, const char *k);
    + +

    +Does the equivalent to t[k] = v, +where t is the value at the given index +and v is the value at the top of the stack. + + +

    +This function pops the value from the stack. +As in Lua, this function may trigger a metamethod +for the "newindex" event (see §2.4). + + + + + +


    lua_setglobal

    +[-1, +0, e] +

    void lua_setglobal (lua_State *L, const char *name);
    + +

    +Pops a value from the stack and +sets it as the new value of global name. + + + + + +


    lua_setmetatable

    +[-1, +0, –] +

    void lua_setmetatable (lua_State *L, int index);
    + +

    +Pops a table from the stack and +sets it as the new metatable for the value at the given index. + + + + + +


    lua_settable

    +[-2, +0, e] +

    void lua_settable (lua_State *L, int index);
    + +

    +Does the equivalent to t[k] = v, +where t is the value at the given index, +v is the value at the top of the stack, +and k is the value just below the top. + + +

    +This function pops both the key and the value from the stack. +As in Lua, this function may trigger a metamethod +for the "newindex" event (see §2.4). + + + + + +


    lua_settop

    +[-?, +?, –] +

    void lua_settop (lua_State *L, int index);
    + +

    +Accepts any index, or 0, +and sets the stack top to this index. +If the new top is larger than the old one, +then the new elements are filled with nil. +If index is 0, then all stack elements are removed. + + + + + +


    lua_setuservalue

    +[-1, +0, –] +

    void lua_setuservalue (lua_State *L, int index);
    + +

    +Pops a table or nil from the stack and sets it as +the new value associated to the userdata at the given index. + + + + + +


    lua_State

    +
    typedef struct lua_State lua_State;
    + +

    +An opaque structure that points to a thread and indirectly +(through the thread) to the whole state of a Lua interpreter. +The Lua library is fully reentrant: +it has no global variables. +All information about a state is accessible through this structure. + + +

    +A pointer to this structure must be passed as the first argument to +every function in the library, except to lua_newstate, +which creates a Lua state from scratch. + + + + + +


    lua_status

    +[-0, +0, –] +

    int lua_status (lua_State *L);
    + +

    +Returns the status of the thread L. + + +

    +The status can be 0 (LUA_OK) for a normal thread, +an error code if the thread finished the execution +of a lua_resume with an error, +or LUA_YIELD if the thread is suspended. + + +

    +You can only call functions in threads with status LUA_OK. +You can resume threads with status LUA_OK +(to start a new coroutine) or LUA_YIELD +(to resume a coroutine). + + + + + +


    lua_toboolean

    +[-0, +0, –] +

    int lua_toboolean (lua_State *L, int index);
    + +

    +Converts the Lua value at the given index to a C boolean +value (0 or 1). +Like all tests in Lua, +lua_toboolean returns true for any Lua value +different from false and nil; +otherwise it returns false. +(If you want to accept only actual boolean values, +use lua_isboolean to test the value's type.) + + + + + +


    lua_tocfunction

    +[-0, +0, –] +

    lua_CFunction lua_tocfunction (lua_State *L, int index);
    + +

    +Converts a value at the given index to a C function. +That value must be a C function; +otherwise, returns NULL. + + + + + +


    lua_tointeger

    +[-0, +0, –] +

    lua_Integer lua_tointeger (lua_State *L, int index);
    + +

    +Equivalent to lua_tointegerx with isnum equal to NULL. + + + + + +


    lua_tointegerx

    +[-0, +0, –] +

    lua_Integer lua_tointegerx (lua_State *L, int index, int *isnum);
    + +

    +Converts the Lua value at the given index +to the signed integral type lua_Integer. +The Lua value must be a number or a string convertible to a number +(see §3.4.2); +otherwise, lua_tointegerx returns 0. + + +

    +If the number is not an integer, +it is truncated in some non-specified way. + + +

    +If isnum is not NULL, +its referent is assigned a boolean value that +indicates whether the operation succeeded. + + + + + +


    lua_tolstring

    +[-0, +0, e] +

    const char *lua_tolstring (lua_State *L, int index, size_t *len);
    + +

    +Converts the Lua value at the given index to a C string. +If len is not NULL, +it also sets *len with the string length. +The Lua value must be a string or a number; +otherwise, the function returns NULL. +If the value is a number, +then lua_tolstring also +changes the actual value in the stack to a string. +(This change confuses lua_next +when lua_tolstring is applied to keys during a table traversal.) + + +

    +lua_tolstring returns a fully aligned pointer +to a string inside the Lua state. +This string always has a zero ('\0') +after its last character (as in C), +but can contain other zeros in its body. +Because Lua has garbage collection, +there is no guarantee that the pointer returned by lua_tolstring +will be valid after the corresponding value is removed from the stack. + + + + + +


    lua_tonumber

    +[-0, +0, –] +

    lua_Number lua_tonumber (lua_State *L, int index);
    + +

    +Equivalent to lua_tonumberx with isnum equal to NULL. + + + + + +


    lua_tonumberx

    +[-0, +0, –] +

    lua_Number lua_tonumberx (lua_State *L, int index, int *isnum);
    + +

    +Converts the Lua value at the given index +to the C type lua_Number (see lua_Number). +The Lua value must be a number or a string convertible to a number +(see §3.4.2); +otherwise, lua_tonumberx returns 0. + + +

    +If isnum is not NULL, +its referent is assigned a boolean value that +indicates whether the operation succeeded. + + + + + +


    lua_topointer

    +[-0, +0, –] +

    const void *lua_topointer (lua_State *L, int index);
    + +

    +Converts the value at the given index to a generic +C pointer (void*). +The value can be a userdata, a table, a thread, or a function; +otherwise, lua_topointer returns NULL. +Different objects will give different pointers. +There is no way to convert the pointer back to its original value. + + +

    +Typically this function is used only for debug information. + + + + + +


    lua_tostring

    +[-0, +0, e] +

    const char *lua_tostring (lua_State *L, int index);
    + +

    +Equivalent to lua_tolstring with len equal to NULL. + + + + + +


    lua_tothread

    +[-0, +0, –] +

    lua_State *lua_tothread (lua_State *L, int index);
    + +

    +Converts the value at the given index to a Lua thread +(represented as lua_State*). +This value must be a thread; +otherwise, the function returns NULL. + + + + + +


    lua_tounsigned

    +[-0, +0, –] +

    lua_Unsigned lua_tounsigned (lua_State *L, int index);
    + +

    +Equivalent to lua_tounsignedx with isnum equal to NULL. + + + + + +


    lua_tounsignedx

    +[-0, +0, –] +

    lua_Unsigned lua_tounsignedx (lua_State *L, int index, int *isnum);
    + +

    +Converts the Lua value at the given index +to the unsigned integral type lua_Unsigned. +The Lua value must be a number or a string convertible to a number +(see §3.4.2); +otherwise, lua_tounsignedx returns 0. + + +

    +If the number is not an integer, +it is truncated in some non-specified way. +If the number is outside the range of representable values, +it is normalized to the remainder of its division by +one more than the maximum representable value. + + +

    +If isnum is not NULL, +its referent is assigned a boolean value that +indicates whether the operation succeeded. + + + + + +


    lua_touserdata

    +[-0, +0, –] +

    void *lua_touserdata (lua_State *L, int index);
    + +

    +If the value at the given index is a full userdata, +returns its block address. +If the value is a light userdata, +returns its pointer. +Otherwise, returns NULL. + + + + + +


    lua_type

    +[-0, +0, –] +

    int lua_type (lua_State *L, int index);
    + +

    +Returns the type of the value in the given valid index, +or LUA_TNONE for a non-valid (but acceptable) index. +The types returned by lua_type are coded by the following constants +defined in lua.h: +LUA_TNIL, +LUA_TNUMBER, +LUA_TBOOLEAN, +LUA_TSTRING, +LUA_TTABLE, +LUA_TFUNCTION, +LUA_TUSERDATA, +LUA_TTHREAD, +and +LUA_TLIGHTUSERDATA. + + + + + +


    lua_typename

    +[-0, +0, –] +

    const char *lua_typename (lua_State *L, int tp);
    + +

    +Returns the name of the type encoded by the value tp, +which must be one the values returned by lua_type. + + + + + +


    lua_Unsigned

    +
    typedef unsigned long lua_Unsigned;
    + +

    +The type used by the Lua API to represent unsigned integral values. +It must have at least 32 bits. + + +

    +By default it is an unsigned int or an unsigned long, +whichever can hold 32-bit values. + + + + + +


    lua_upvalueindex

    +[-0, +0, –] +

    int lua_upvalueindex (int i);
    + +

    +Returns the pseudo-index that represents the i-th upvalue of +the running function (see §4.4). + + + + + +


    lua_version

    +[-0, +0, v] +

    const lua_Number *lua_version (lua_State *L);
    + +

    +Returns the address of the version number stored in the Lua core. +When called with a valid lua_State, +returns the address of the version used to create that state. +When called with NULL, +returns the address of the version running the call. + + + + + +


    lua_Writer

    +
    typedef int (*lua_Writer) (lua_State *L,
    +                           const void* p,
    +                           size_t sz,
    +                           void* ud);
    + +

    +The type of the writer function used by lua_dump. +Every time it produces another piece of chunk, +lua_dump calls the writer, +passing along the buffer to be written (p), +its size (sz), +and the data parameter supplied to lua_dump. + + +

    +The writer returns an error code: +0 means no errors; +any other value means an error and stops lua_dump from +calling the writer again. + + + + + +


    lua_xmove

    +[-?, +?, –] +

    void lua_xmove (lua_State *from, lua_State *to, int n);
    + +

    +Exchange values between different threads of the same state. + + +

    +This function pops n values from the stack from, +and pushes them onto the stack to. + + + + + +


    lua_yield

    +[-?, +?, –] +

    int lua_yield (lua_State *L, int nresults);
    + +

    +This function is equivalent to lua_yieldk, +but it has no continuation (see §4.7). +Therefore, when the thread resumes, +it returns to the function that called +the function calling lua_yield. + + + + + +


    lua_yieldk

    +[-?, +?, –] +

    int lua_yieldk (lua_State *L, int nresults, int ctx, lua_CFunction k);
    + +

    +Yields a coroutine. + + +

    +This function should only be called as the +return expression of a C function, as follows: + +

    +     return lua_yieldk (L, n, i, k);
    +

    +When a C function calls lua_yieldk in that way, +the running coroutine suspends its execution, +and the call to lua_resume that started this coroutine returns. +The parameter nresults is the number of values from the stack +that are passed as results to lua_resume. + + +

    +When the coroutine is resumed again, +Lua calls the given continuation function k to continue +the execution of the C function that yielded (see §4.7). +This continuation function receives the same stack +from the previous function, +with the results removed and +replaced by the arguments passed to lua_resume. +Moreover, +the continuation function may access the value ctx +by calling lua_getctx. + + + + + + + +

    4.9 – The Debug Interface

    + +

    +Lua has no built-in debugging facilities. +Instead, it offers a special interface +by means of functions and hooks. +This interface allows the construction of different +kinds of debuggers, profilers, and other tools +that need "inside information" from the interpreter. + + + +


    lua_Debug

    +
    typedef struct lua_Debug {
    +  int event;
    +  const char *name;           /* (n) */
    +  const char *namewhat;       /* (n) */
    +  const char *what;           /* (S) */
    +  const char *source;         /* (S) */
    +  int currentline;            /* (l) */
    +  int linedefined;            /* (S) */
    +  int lastlinedefined;        /* (S) */
    +  unsigned char nups;         /* (u) number of upvalues */
    +  unsigned char nparams;      /* (u) number of parameters */
    +  char isvararg;              /* (u) */
    +  char istailcall;            /* (t) */
    +  char short_src[LUA_IDSIZE]; /* (S) */
    +  /* private part */
    +  other fields
    +} lua_Debug;
    + +

    +A structure used to carry different pieces of +information about a function or an activation record. +lua_getstack fills only the private part +of this structure, for later use. +To fill the other fields of lua_Debug with useful information, +call lua_getinfo. + + +

    +The fields of lua_Debug have the following meaning: + +

      + +
    • source: +the source of the chunk that created the function. +If source starts with a '@', +it means that the function was defined in a file where +the file name follows the '@'. +If source starts with a '=', +the remainder of its contents describe the source in a user-dependent manner. +Otherwise, +the function was defined in a string where +source is that string. +
    • + +
    • short_src: +a "printable" version of source, to be used in error messages. +
    • + +
    • linedefined: +the line number where the definition of the function starts. +
    • + +
    • lastlinedefined: +the line number where the definition of the function ends. +
    • + +
    • what: +the string "Lua" if the function is a Lua function, +"C" if it is a C function, +"main" if it is the main part of a chunk. +
    • + +
    • currentline: +the current line where the given function is executing. +When no line information is available, +currentline is set to -1. +
    • + +
    • name: +a reasonable name for the given function. +Because functions in Lua are first-class values, +they do not have a fixed name: +some functions can be the value of multiple global variables, +while others can be stored only in a table field. +The lua_getinfo function checks how the function was +called to find a suitable name. +If it cannot find a name, +then name is set to NULL. +
    • + +
    • namewhat: +explains the name field. +The value of namewhat can be +"global", "local", "method", +"field", "upvalue", or "" (the empty string), +according to how the function was called. +(Lua uses the empty string when no other option seems to apply.) +
    • + +
    • istailcall: +true if this function invocation was called by a tail call. +In this case, the caller of this level is not in the stack. +
    • + +
    • nups: +the number of upvalues of the function. +
    • + +
    • nparams: +the number of fixed parameters of the function +(always 0 for C functions). +
    • + +
    • isvararg: +true if the function is a vararg function +(always true for C functions). +
    • + +
    + + + + +

    lua_gethook

    +[-0, +0, –] +

    lua_Hook lua_gethook (lua_State *L);
    + +

    +Returns the current hook function. + + + + + +


    lua_gethookcount

    +[-0, +0, –] +

    int lua_gethookcount (lua_State *L);
    + +

    +Returns the current hook count. + + + + + +


    lua_gethookmask

    +[-0, +0, –] +

    int lua_gethookmask (lua_State *L);
    + +

    +Returns the current hook mask. + + + + + +


    lua_getinfo

    +[-(0|1), +(0|1|2), e] +

    int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
    + +

    +Gets information about a specific function or function invocation. + + +

    +To get information about a function invocation, +the parameter ar must be a valid activation record that was +filled by a previous call to lua_getstack or +given as argument to a hook (see lua_Hook). + + +

    +To get information about a function you push it onto the stack +and start the what string with the character '>'. +(In that case, +lua_getinfo pops the function from the top of the stack.) +For instance, to know in which line a function f was defined, +you can write the following code: + +

    +     lua_Debug ar;
    +     lua_getglobal(L, "f");  /* get global 'f' */
    +     lua_getinfo(L, ">S", &ar);
    +     printf("%d\n", ar.linedefined);
    +
    + +

    +Each character in the string what +selects some fields of the structure ar to be filled or +a value to be pushed on the stack: + +

      + +
    • 'n': fills in the field name and namewhat; +
    • + +
    • 'S': +fills in the fields source, short_src, +linedefined, lastlinedefined, and what; +
    • + +
    • 'l': fills in the field currentline; +
    • + +
    • 't': fills in the field istailcall; +
    • + +
    • 'u': fills in the fields +nups, nparams, and isvararg; +
    • + +
    • 'f': +pushes onto the stack the function that is +running at the given level; +
    • + +
    • 'L': +pushes onto the stack a table whose indices are the +numbers of the lines that are valid on the function. +(A valid line is a line with some associated code, +that is, a line where you can put a break point. +Non-valid lines include empty lines and comments.) +
    • + +
    + +

    +This function returns 0 on error +(for instance, an invalid option in what). + + + + + +


    lua_getlocal

    +[-0, +(0|1), –] +

    const char *lua_getlocal (lua_State *L, lua_Debug *ar, int n);
    + +

    +Gets information about a local variable of +a given activation record or a given function. + + +

    +In the first case, +the parameter ar must be a valid activation record that was +filled by a previous call to lua_getstack or +given as argument to a hook (see lua_Hook). +The index n selects which local variable to inspect; +see debug.getlocal for details about variable indices +and names. + + +

    +lua_getlocal pushes the variable's value onto the stack +and returns its name. + + +

    +In the second case, ar should be NULL and the function +to be inspected must be at the top of the stack. +In this case, only parameters of Lua functions are visible +(as there is no information about what variables are active) +and no values are pushed onto the stack. + + +

    +Returns NULL (and pushes nothing) +when the index is greater than +the number of active local variables. + + + + + +


    lua_getstack

    +[-0, +0, –] +

    int lua_getstack (lua_State *L, int level, lua_Debug *ar);
    + +

    +Gets information about the interpreter runtime stack. + + +

    +This function fills parts of a lua_Debug structure with +an identification of the activation record +of the function executing at a given level. +Level 0 is the current running function, +whereas level n+1 is the function that has called level n +(except for tail calls, which do not count on the stack). +When there are no errors, lua_getstack returns 1; +when called with a level greater than the stack depth, +it returns 0. + + + + + +


    lua_getupvalue

    +[-0, +(0|1), –] +

    const char *lua_getupvalue (lua_State *L, int funcindex, int n);
    + +

    +Gets information about a closure's upvalue. +(For Lua functions, +upvalues are the external local variables that the function uses, +and that are consequently included in its closure.) +lua_getupvalue gets the index n of an upvalue, +pushes the upvalue's value onto the stack, +and returns its name. +funcindex points to the closure in the stack. +(Upvalues have no particular order, +as they are active through the whole function. +So, they are numbered in an arbitrary order.) + + +

    +Returns NULL (and pushes nothing) +when the index is greater than the number of upvalues. +For C functions, this function uses the empty string "" +as a name for all upvalues. + + + + + +


    lua_Hook

    +
    typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
    + +

    +Type for debugging hook functions. + + +

    +Whenever a hook is called, its ar argument has its field +event set to the specific event that triggered the hook. +Lua identifies these events with the following constants: +LUA_HOOKCALL, LUA_HOOKRET, +LUA_HOOKTAILCALL, LUA_HOOKLINE, +and LUA_HOOKCOUNT. +Moreover, for line events, the field currentline is also set. +To get the value of any other field in ar, +the hook must call lua_getinfo. + + +

    +For call events, event can be LUA_HOOKCALL, +the normal value, or LUA_HOOKTAILCALL, for a tail call; +in this case, there will be no corresponding return event. + + +

    +While Lua is running a hook, it disables other calls to hooks. +Therefore, if a hook calls back Lua to execute a function or a chunk, +this execution occurs without any calls to hooks. + + +

    +Hook functions cannot have continuations, +that is, they cannot call lua_yieldk, +lua_pcallk, or lua_callk with a non-null k. + + +

    +Hook functions can yield under the following conditions: +Only count and line events can yield +and they cannot yield any value; +to yield a hook function must finish its execution +calling lua_yield with nresults equal to zero. + + + + + +


    lua_sethook

    +[-0, +0, –] +

    int lua_sethook (lua_State *L, lua_Hook f, int mask, int count);
    + +

    +Sets the debugging hook function. + + +

    +Argument f is the hook function. +mask specifies on which events the hook will be called: +it is formed by a bitwise or of the constants +LUA_MASKCALL, +LUA_MASKRET, +LUA_MASKLINE, +and LUA_MASKCOUNT. +The count argument is only meaningful when the mask +includes LUA_MASKCOUNT. +For each event, the hook is called as explained below: + +

      + +
    • The call hook: is called when the interpreter calls a function. +The hook is called just after Lua enters the new function, +before the function gets its arguments. +
    • + +
    • The return hook: is called when the interpreter returns from a function. +The hook is called just before Lua leaves the function. +There is no standard way to access the values +to be returned by the function. +
    • + +
    • The line hook: is called when the interpreter is about to +start the execution of a new line of code, +or when it jumps back in the code (even to the same line). +(This event only happens while Lua is executing a Lua function.) +
    • + +
    • The count hook: is called after the interpreter executes every +count instructions. +(This event only happens while Lua is executing a Lua function.) +
    • + +
    + +

    +A hook is disabled by setting mask to zero. + + + + + +


    lua_setlocal

    +[-(0|1), +0, –] +

    const char *lua_setlocal (lua_State *L, lua_Debug *ar, int n);
    + +

    +Sets the value of a local variable of a given activation record. +Parameters ar and n are as in lua_getlocal +(see lua_getlocal). +lua_setlocal assigns the value at the top of the stack +to the variable and returns its name. +It also pops the value from the stack. + + +

    +Returns NULL (and pops nothing) +when the index is greater than +the number of active local variables. + + + + + +


    lua_setupvalue

    +[-(0|1), +0, –] +

    const char *lua_setupvalue (lua_State *L, int funcindex, int n);
    + +

    +Sets the value of a closure's upvalue. +It assigns the value at the top of the stack +to the upvalue and returns its name. +It also pops the value from the stack. +Parameters funcindex and n are as in the lua_getupvalue +(see lua_getupvalue). + + +

    +Returns NULL (and pops nothing) +when the index is greater than the number of upvalues. + + + + + +


    lua_upvalueid

    +[-0, +0, –] +

    void *lua_upvalueid (lua_State *L, int funcindex, int n);
    + +

    +Returns an unique identifier for the upvalue numbered n +from the closure at index funcindex. +Parameters funcindex and n are as in the lua_getupvalue +(see lua_getupvalue) +(but n cannot be greater than the number of upvalues). + + +

    +These unique identifiers allow a program to check whether different +closures share upvalues. +Lua closures that share an upvalue +(that is, that access a same external local variable) +will return identical ids for those upvalue indices. + + + + + +


    lua_upvaluejoin

    +[-0, +0, –] +

    void lua_upvaluejoin (lua_State *L, int funcindex1, int n1,
    +                                    int funcindex2, int n2);
    + +

    +Make the n1-th upvalue of the Lua closure at index funcindex1 +refer to the n2-th upvalue of the Lua closure at index funcindex2. + + + + + + + +

    5 – The Auxiliary Library

    + +

    + +The auxiliary library provides several convenient functions +to interface C with Lua. +While the basic API provides the primitive functions for all +interactions between C and Lua, +the auxiliary library provides higher-level functions for some +common tasks. + + +

    +All functions and types from the auxiliary library +are defined in header file lauxlib.h and +have a prefix luaL_. + + +

    +All functions in the auxiliary library are built on +top of the basic API, +and so they provide nothing that cannot be done with that API. +Nevertheless, the use of the auxiliary library ensures +more consistency to your code. + + +

    +Several functions in the auxiliary library use internally some +extra stack slots. +When a function in the auxiliary library uses less than five slots, +it does not check the stack size; +it simply assumes that there are enough slots. + + +

    +Several functions in the auxiliary library are used to +check C function arguments. +Because the error message is formatted for arguments +(e.g., "bad argument #1"), +you should not use these functions for other stack values. + + +

    +Functions called luaL_check* +always throw an error if the check is not satisfied. + + + +

    5.1 – Functions and Types

    + +

    +Here we list all functions and types from the auxiliary library +in alphabetical order. + + + +


    luaL_addchar

    +[-?, +?, e] +

    void luaL_addchar (luaL_Buffer *B, char c);
    + +

    +Adds the byte c to the buffer B +(see luaL_Buffer). + + + + + +


    luaL_addlstring

    +[-?, +?, e] +

    void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l);
    + +

    +Adds the string pointed to by s with length l to +the buffer B +(see luaL_Buffer). +The string can contain embedded zeros. + + + + + +


    luaL_addsize

    +[-?, +?, e] +

    void luaL_addsize (luaL_Buffer *B, size_t n);
    + +

    +Adds to the buffer B (see luaL_Buffer) +a string of length n previously copied to the +buffer area (see luaL_prepbuffer). + + + + + +


    luaL_addstring

    +[-?, +?, e] +

    void luaL_addstring (luaL_Buffer *B, const char *s);
    + +

    +Adds the zero-terminated string pointed to by s +to the buffer B +(see luaL_Buffer). +The string cannot contain embedded zeros. + + + + + +


    luaL_addvalue

    +[-1, +?, e] +

    void luaL_addvalue (luaL_Buffer *B);
    + +

    +Adds the value at the top of the stack +to the buffer B +(see luaL_Buffer). +Pops the value. + + +

    +This is the only function on string buffers that can (and must) +be called with an extra element on the stack, +which is the value to be added to the buffer. + + + + + +


    luaL_argcheck

    +[-0, +0, v] +

    void luaL_argcheck (lua_State *L,
    +                    int cond,
    +                    int arg,
    +                    const char *extramsg);
    + +

    +Checks whether cond is true. +If not, raises an error with a standard message. + + + + + +


    luaL_argerror

    +[-0, +0, v] +

    int luaL_argerror (lua_State *L, int arg, const char *extramsg);
    + +

    +Raises an error with a standard message +that includes extramsg as a comment. + + +

    +This function never returns, +but it is an idiom to use it in C functions +as return luaL_argerror(args). + + + + + +


    luaL_Buffer

    +
    typedef struct luaL_Buffer luaL_Buffer;
    + +

    +Type for a string buffer. + + +

    +A string buffer allows C code to build Lua strings piecemeal. +Its pattern of use is as follows: + +

      + +
    • First declare a variable b of type luaL_Buffer.
    • + +
    • Then initialize it with a call luaL_buffinit(L, &b).
    • + +
    • +Then add string pieces to the buffer calling any of +the luaL_add* functions. +
    • + +
    • +Finish by calling luaL_pushresult(&b). +This call leaves the final string on the top of the stack. +
    • + +
    + +

    +If you know beforehand the total size of the resulting string, +you can use the buffer like this: + +

      + +
    • First declare a variable b of type luaL_Buffer.
    • + +
    • Then initialize it and preallocate a space of +size sz with a call luaL_buffinitsize(L, &b, sz).
    • + +
    • Then copy the string into that space.
    • + +
    • +Finish by calling luaL_pushresultsize(&b, sz), +where sz is the total size of the resulting string +copied into that space. +
    • + +
    + +

    +During its normal operation, +a string buffer uses a variable number of stack slots. +So, while using a buffer, you cannot assume that you know where +the top of the stack is. +You can use the stack between successive calls to buffer operations +as long as that use is balanced; +that is, +when you call a buffer operation, +the stack is at the same level +it was immediately after the previous buffer operation. +(The only exception to this rule is luaL_addvalue.) +After calling luaL_pushresult the stack is back to its +level when the buffer was initialized, +plus the final string on its top. + + + + + +


    luaL_buffinit

    +[-0, +0, –] +

    void luaL_buffinit (lua_State *L, luaL_Buffer *B);
    + +

    +Initializes a buffer B. +This function does not allocate any space; +the buffer must be declared as a variable +(see luaL_Buffer). + + + + + +


    luaL_buffinitsize

    +[-?, +?, e] +

    char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz);
    + +

    +Equivalent to the sequence +luaL_buffinit, luaL_prepbuffsize. + + + + + +


    luaL_callmeta

    +[-0, +(0|1), e] +

    int luaL_callmeta (lua_State *L, int obj, const char *e);
    + +

    +Calls a metamethod. + + +

    +If the object at index obj has a metatable and this +metatable has a field e, +this function calls this field passing the object as its only argument. +In this case this function returns true and pushes onto the +stack the value returned by the call. +If there is no metatable or no metamethod, +this function returns false (without pushing any value on the stack). + + + + + +


    luaL_checkany

    +[-0, +0, v] +

    void luaL_checkany (lua_State *L, int arg);
    + +

    +Checks whether the function has an argument +of any type (including nil) at position arg. + + + + + +


    luaL_checkint

    +[-0, +0, v] +

    int luaL_checkint (lua_State *L, int arg);
    + +

    +Checks whether the function argument arg is a number +and returns this number cast to an int. + + + + + +


    luaL_checkinteger

    +[-0, +0, v] +

    lua_Integer luaL_checkinteger (lua_State *L, int arg);
    + +

    +Checks whether the function argument arg is a number +and returns this number cast to a lua_Integer. + + + + + +


    luaL_checklong

    +[-0, +0, v] +

    long luaL_checklong (lua_State *L, int arg);
    + +

    +Checks whether the function argument arg is a number +and returns this number cast to a long. + + + + + +


    luaL_checklstring

    +[-0, +0, v] +

    const char *luaL_checklstring (lua_State *L, int arg, size_t *l);
    + +

    +Checks whether the function argument arg is a string +and returns this string; +if l is not NULL fills *l +with the string's length. + + +

    +This function uses lua_tolstring to get its result, +so all conversions and caveats of that function apply here. + + + + + +


    luaL_checknumber

    +[-0, +0, v] +

    lua_Number luaL_checknumber (lua_State *L, int arg);
    + +

    +Checks whether the function argument arg is a number +and returns this number. + + + + + +


    luaL_checkoption

    +[-0, +0, v] +

    int luaL_checkoption (lua_State *L,
    +                      int arg,
    +                      const char *def,
    +                      const char *const lst[]);
    + +

    +Checks whether the function argument arg is a string and +searches for this string in the array lst +(which must be NULL-terminated). +Returns the index in the array where the string was found. +Raises an error if the argument is not a string or +if the string cannot be found. + + +

    +If def is not NULL, +the function uses def as a default value when +there is no argument arg or when this argument is nil. + + +

    +This is a useful function for mapping strings to C enums. +(The usual convention in Lua libraries is +to use strings instead of numbers to select options.) + + + + + +


    luaL_checkstack

    +[-0, +0, v] +

    void luaL_checkstack (lua_State *L, int sz, const char *msg);
    + +

    +Grows the stack size to top + sz elements, +raising an error if the stack cannot grow to that size. +msg is an additional text to go into the error message +(or NULL for no additional text). + + + + + +


    luaL_checkstring

    +[-0, +0, v] +

    const char *luaL_checkstring (lua_State *L, int arg);
    + +

    +Checks whether the function argument arg is a string +and returns this string. + + +

    +This function uses lua_tolstring to get its result, +so all conversions and caveats of that function apply here. + + + + + +


    luaL_checktype

    +[-0, +0, v] +

    void luaL_checktype (lua_State *L, int arg, int t);
    + +

    +Checks whether the function argument arg has type t. +See lua_type for the encoding of types for t. + + + + + +


    luaL_checkudata

    +[-0, +0, v] +

    void *luaL_checkudata (lua_State *L, int arg, const char *tname);
    + +

    +Checks whether the function argument arg is a userdata +of the type tname (see luaL_newmetatable) and +returns the userdata address (see lua_touserdata). + + + + + +


    luaL_checkunsigned

    +[-0, +0, v] +

    lua_Unsigned luaL_checkunsigned (lua_State *L, int arg);
    + +

    +Checks whether the function argument arg is a number +and returns this number cast to a lua_Unsigned. + + + + + +


    luaL_checkversion

    +[-0, +0, –] +

    void luaL_checkversion (lua_State *L);
    + +

    +Checks whether the core running the call, +the core that created the Lua state, +and the code making the call are all using the same version of Lua. +Also checks whether the core running the call +and the core that created the Lua state +are using the same address space. + + + + + +


    luaL_dofile

    +[-0, +?, e] +

    int luaL_dofile (lua_State *L, const char *filename);
    + +

    +Loads and runs the given file. +It is defined as the following macro: + +

    +     (luaL_loadfile(L, filename) || lua_pcall(L, 0, LUA_MULTRET, 0))
    +

    +It returns false if there are no errors +or true in case of errors. + + + + + +


    luaL_dostring

    +[-0, +?, –] +

    int luaL_dostring (lua_State *L, const char *str);
    + +

    +Loads and runs the given string. +It is defined as the following macro: + +

    +     (luaL_loadstring(L, str) || lua_pcall(L, 0, LUA_MULTRET, 0))
    +

    +It returns false if there are no errors +or true in case of errors. + + + + + +


    luaL_error

    +[-0, +0, v] +

    int luaL_error (lua_State *L, const char *fmt, ...);
    + +

    +Raises an error. +The error message format is given by fmt +plus any extra arguments, +following the same rules of lua_pushfstring. +It also adds at the beginning of the message the file name and +the line number where the error occurred, +if this information is available. + + +

    +This function never returns, +but it is an idiom to use it in C functions +as return luaL_error(args). + + + + + +


    luaL_execresult

    +[-0, +3, e] +

    int luaL_execresult (lua_State *L, int stat);
    + +

    +This function produces the return values for +process-related functions in the standard library +(os.execute and io.close). + + + + + +


    luaL_fileresult

    +[-0, +(1|3), e] +

    int luaL_fileresult (lua_State *L, int stat, const char *fname);
    + +

    +This function produces the return values for +file-related functions in the standard library +(io.open, os.rename, file:seek, etc.). + + + + + +


    luaL_getmetafield

    +[-0, +(0|1), e] +

    int luaL_getmetafield (lua_State *L, int obj, const char *e);
    + +

    +Pushes onto the stack the field e from the metatable +of the object at index obj. +If the object does not have a metatable, +or if the metatable does not have this field, +returns false and pushes nothing. + + + + + +


    luaL_getmetatable

    +[-0, +1, –] +

    void luaL_getmetatable (lua_State *L, const char *tname);
    + +

    +Pushes onto the stack the metatable associated with name tname +in the registry (see luaL_newmetatable). + + + + + +


    luaL_getsubtable

    +[-0, +1, e] +

    int luaL_getsubtable (lua_State *L, int idx, const char *fname);
    + +

    +Ensures that the value t[fname], +where t is the value at index idx, +is a table, +and pushes that table onto the stack. +Returns true if it finds a previous table there +and false if it creates a new table. + + + + + +


    luaL_gsub

    +[-0, +1, e] +

    const char *luaL_gsub (lua_State *L,
    +                       const char *s,
    +                       const char *p,
    +                       const char *r);
    + +

    +Creates a copy of string s by replacing +any occurrence of the string p +with the string r. +Pushes the resulting string on the stack and returns it. + + + + + +


    luaL_len

    +[-0, +0, e] +

    int luaL_len (lua_State *L, int index);
    + +

    +Returns the "length" of the value at the given index +as a number; +it is equivalent to the '#' operator in Lua (see §3.4.6). +Raises an error if the result of the operation is not a number. +(This case only can happen through metamethods.) + + + + + +


    luaL_loadbuffer

    +[-0, +1, –] +

    int luaL_loadbuffer (lua_State *L,
    +                     const char *buff,
    +                     size_t sz,
    +                     const char *name);
    + +

    +Equivalent to luaL_loadbufferx with mode equal to NULL. + + + + + +


    luaL_loadbufferx

    +[-0, +1, –] +

    int luaL_loadbufferx (lua_State *L,
    +                      const char *buff,
    +                      size_t sz,
    +                      const char *name,
    +                      const char *mode);
    + +

    +Loads a buffer as a Lua chunk. +This function uses lua_load to load the chunk in the +buffer pointed to by buff with size sz. + + +

    +This function returns the same results as lua_load. +name is the chunk name, +used for debug information and error messages. +The string mode works as in function lua_load. + + + + + +


    luaL_loadfile

    +[-0, +1, e] +

    int luaL_loadfile (lua_State *L, const char *filename);
    + +

    +Equivalent to luaL_loadfilex with mode equal to NULL. + + + + + +


    luaL_loadfilex

    +[-0, +1, e] +

    int luaL_loadfilex (lua_State *L, const char *filename,
    +                                            const char *mode);
    + +

    +Loads a file as a Lua chunk. +This function uses lua_load to load the chunk in the file +named filename. +If filename is NULL, +then it loads from the standard input. +The first line in the file is ignored if it starts with a #. + + +

    +The string mode works as in function lua_load. + + +

    +This function returns the same results as lua_load, +but it has an extra error code LUA_ERRFILE +if it cannot open/read the file or the file has a wrong mode. + + +

    +As lua_load, this function only loads the chunk; +it does not run it. + + + + + +


    luaL_loadstring

    +[-0, +1, –] +

    int luaL_loadstring (lua_State *L, const char *s);
    + +

    +Loads a string as a Lua chunk. +This function uses lua_load to load the chunk in +the zero-terminated string s. + + +

    +This function returns the same results as lua_load. + + +

    +Also as lua_load, this function only loads the chunk; +it does not run it. + + + + + +


    luaL_newlib

    +[-0, +1, e] +

    void luaL_newlib (lua_State *L, const luaL_Reg *l);
    + +

    +Creates a new table and registers there +the functions in list l. +It is implemented as the following macro: + +

    +     (luaL_newlibtable(L,l), luaL_setfuncs(L,l,0))
    +
    + + + + +

    luaL_newlibtable

    +[-0, +1, e] +

    void luaL_newlibtable (lua_State *L, const luaL_Reg l[]);
    + +

    +Creates a new table with a size optimized +to store all entries in the array l +(but does not actually store them). +It is intended to be used in conjunction with luaL_setfuncs +(see luaL_newlib). + + +

    +It is implemented as a macro. +The array l must be the actual array, +not a pointer to it. + + + + + +


    luaL_newmetatable

    +[-0, +1, e] +

    int luaL_newmetatable (lua_State *L, const char *tname);
    + +

    +If the registry already has the key tname, +returns 0. +Otherwise, +creates a new table to be used as a metatable for userdata, +adds it to the registry with key tname, +and returns 1. + + +

    +In both cases pushes onto the stack the final value associated +with tname in the registry. + + + + + +


    luaL_newstate

    +[-0, +0, –] +

    lua_State *luaL_newstate (void);
    + +

    +Creates a new Lua state. +It calls lua_newstate with an +allocator based on the standard C realloc function +and then sets a panic function (see §4.6) that prints +an error message to the standard error output in case of fatal +errors. + + +

    +Returns the new state, +or NULL if there is a memory allocation error. + + + + + +


    luaL_openlibs

    +[-0, +0, e] +

    void luaL_openlibs (lua_State *L);
    + +

    +Opens all standard Lua libraries into the given state. + + + + + +


    luaL_optint

    +[-0, +0, v] +

    int luaL_optint (lua_State *L, int arg, int d);
    + +

    +If the function argument arg is a number, +returns this number cast to an int. +If this argument is absent or is nil, +returns d. +Otherwise, raises an error. + + + + + +


    luaL_optinteger

    +[-0, +0, v] +

    lua_Integer luaL_optinteger (lua_State *L,
    +                             int arg,
    +                             lua_Integer d);
    + +

    +If the function argument arg is a number, +returns this number cast to a lua_Integer. +If this argument is absent or is nil, +returns d. +Otherwise, raises an error. + + + + + +


    luaL_optlong

    +[-0, +0, v] +

    long luaL_optlong (lua_State *L, int arg, long d);
    + +

    +If the function argument arg is a number, +returns this number cast to a long. +If this argument is absent or is nil, +returns d. +Otherwise, raises an error. + + + + + +


    luaL_optlstring

    +[-0, +0, v] +

    const char *luaL_optlstring (lua_State *L,
    +                             int arg,
    +                             const char *d,
    +                             size_t *l);
    + +

    +If the function argument arg is a string, +returns this string. +If this argument is absent or is nil, +returns d. +Otherwise, raises an error. + + +

    +If l is not NULL, +fills the position *l with the result's length. + + + + + +


    luaL_optnumber

    +[-0, +0, v] +

    lua_Number luaL_optnumber (lua_State *L, int arg, lua_Number d);
    + +

    +If the function argument arg is a number, +returns this number. +If this argument is absent or is nil, +returns d. +Otherwise, raises an error. + + + + + +


    luaL_optstring

    +[-0, +0, v] +

    const char *luaL_optstring (lua_State *L,
    +                            int arg,
    +                            const char *d);
    + +

    +If the function argument arg is a string, +returns this string. +If this argument is absent or is nil, +returns d. +Otherwise, raises an error. + + + + + +


    luaL_optunsigned

    +[-0, +0, v] +

    lua_Unsigned luaL_optunsigned (lua_State *L,
    +                               int arg,
    +                               lua_Unsigned u);
    + +

    +If the function argument arg is a number, +returns this number cast to a lua_Unsigned. +If this argument is absent or is nil, +returns u. +Otherwise, raises an error. + + + + + +


    luaL_prepbuffer

    +[-?, +?, e] +

    char *luaL_prepbuffer (luaL_Buffer *B);
    + +

    +Equivalent to luaL_prepbuffsize +with the predefined size LUAL_BUFFERSIZE. + + + + + +


    luaL_prepbuffsize

    +[-?, +?, e] +

    char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz);
    + +

    +Returns an address to a space of size sz +where you can copy a string to be added to buffer B +(see luaL_Buffer). +After copying the string into this space you must call +luaL_addsize with the size of the string to actually add +it to the buffer. + + + + + +


    luaL_pushresult

    +[-?, +1, e] +

    void luaL_pushresult (luaL_Buffer *B);
    + +

    +Finishes the use of buffer B leaving the final string on +the top of the stack. + + + + + +


    luaL_pushresultsize

    +[-?, +1, e] +

    void luaL_pushresultsize (luaL_Buffer *B, size_t sz);
    + +

    +Equivalent to the sequence luaL_addsize, luaL_pushresult. + + + + + +


    luaL_ref

    +[-1, +0, e] +

    int luaL_ref (lua_State *L, int t);
    + +

    +Creates and returns a reference, +in the table at index t, +for the object at the top of the stack (and pops the object). + + +

    +A reference is a unique integer key. +As long as you do not manually add integer keys into table t, +luaL_ref ensures the uniqueness of the key it returns. +You can retrieve an object referred by reference r +by calling lua_rawgeti(L, t, r). +Function luaL_unref frees a reference and its associated object. + + +

    +If the object at the top of the stack is nil, +luaL_ref returns the constant LUA_REFNIL. +The constant LUA_NOREF is guaranteed to be different +from any reference returned by luaL_ref. + + + + + +


    luaL_Reg

    +
    typedef struct luaL_Reg {
    +  const char *name;
    +  lua_CFunction func;
    +} luaL_Reg;
    + +

    +Type for arrays of functions to be registered by +luaL_setfuncs. +name is the function name and func is a pointer to +the function. +Any array of luaL_Reg must end with an sentinel entry +in which both name and func are NULL. + + + + + +


    luaL_requiref

    +[-0, +1, e] +

    void luaL_requiref (lua_State *L, const char *modname,
    +                    lua_CFunction openf, int glb);
    + +

    +Calls function openf with string modname as an argument +and sets the call result in package.loaded[modname], +as if that function has been called through require. + + +

    +If glb is true, +also stores the result into global modname. + + +

    +Leaves a copy of that result on the stack. + + + + + +


    luaL_setfuncs

    +[-nup, +0, e] +

    void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup);
    + +

    +Registers all functions in the array l +(see luaL_Reg) into the table on the top of the stack +(below optional upvalues, see next). + + +

    +When nup is not zero, +all functions are created sharing nup upvalues, +which must be previously pushed on the stack +on top of the library table. +These values are popped from the stack after the registration. + + + + + +


    luaL_setmetatable

    +[-0, +0, –] +

    void luaL_setmetatable (lua_State *L, const char *tname);
    + +

    +Sets the metatable of the object at the top of the stack +as the metatable associated with name tname +in the registry (see luaL_newmetatable). + + + + + +


    luaL_testudata

    +[-0, +0, e] +

    void *luaL_testudata (lua_State *L, int arg, const char *tname);
    + +

    +This function works like luaL_checkudata, +except that, when the test fails, +it returns NULL instead of throwing an error. + + + + + +


    luaL_tolstring

    +[-0, +1, e] +

    const char *luaL_tolstring (lua_State *L, int idx, size_t *len);
    + +

    +Converts any Lua value at the given index to a C string +in a reasonable format. +The resulting string is pushed onto the stack and also +returned by the function. +If len is not NULL, +the function also sets *len with the string length. + + +

    +If the value has a metatable with a "__tostring" field, +then luaL_tolstring calls the corresponding metamethod +with the value as argument, +and uses the result of the call as its result. + + + + + +


    luaL_traceback

    +[-0, +1, e] +

    void luaL_traceback (lua_State *L, lua_State *L1, const char *msg,
    +                     int level);
    + +

    +Creates and pushes a traceback of the stack L1. +If msg is not NULL it is appended +at the beginning of the traceback. +The level parameter tells at which level +to start the traceback. + + + + + +


    luaL_typename

    +[-0, +0, –] +

    const char *luaL_typename (lua_State *L, int index);
    + +

    +Returns the name of the type of the value at the given index. + + + + + +


    luaL_unref

    +[-0, +0, –] +

    void luaL_unref (lua_State *L, int t, int ref);
    + +

    +Releases reference ref from the table at index t +(see luaL_ref). +The entry is removed from the table, +so that the referred object can be collected. +The reference ref is also freed to be used again. + + +

    +If ref is LUA_NOREF or LUA_REFNIL, +luaL_unref does nothing. + + + + + +


    luaL_where

    +[-0, +1, e] +

    void luaL_where (lua_State *L, int lvl);
    + +

    +Pushes onto the stack a string identifying the current position +of the control at level lvl in the call stack. +Typically this string has the following format: + +

    +     chunkname:currentline:
    +

    +Level 0 is the running function, +level 1 is the function that called the running function, +etc. + + +

    +This function is used to build a prefix for error messages. + + + + + + + +

    6 – Standard Libraries

    + +

    +The standard Lua libraries provide useful functions +that are implemented directly through the C API. +Some of these functions provide essential services to the language +(e.g., type and getmetatable); +others provide access to "outside" services (e.g., I/O); +and others could be implemented in Lua itself, +but are quite useful or have critical performance requirements that +deserve an implementation in C (e.g., table.sort). + + +

    +All libraries are implemented through the official C API +and are provided as separate C modules. +Currently, Lua has the following standard libraries: + +

      + +
    • basic library (§6.1);
    • + +
    • coroutine library (§6.2);
    • + +
    • package library (§6.3);
    • + +
    • string manipulation (§6.4);
    • + +
    • table manipulation (§6.5);
    • + +
    • mathematical functions (§6.6) (sin, log, etc.);
    • + +
    • bitwise operations (§6.7);
    • + +
    • input and output (§6.8);
    • + +
    • operating system facilities (§6.9);
    • + +
    • debug facilities (§6.10).
    • + +

    +Except for the basic and the package libraries, +each library provides all its functions as fields of a global table +or as methods of its objects. + + +

    +To have access to these libraries, +the C host program should call the luaL_openlibs function, +which opens all standard libraries. +Alternatively, +the host program can open them individually by using +luaL_requiref to call +luaopen_base (for the basic library), +luaopen_package (for the package library), +luaopen_coroutine (for the coroutine library), +luaopen_string (for the string library), +luaopen_table (for the table library), +luaopen_math (for the mathematical library), +luaopen_bit32 (for the bit library), +luaopen_io (for the I/O library), +luaopen_os (for the Operating System library), +and luaopen_debug (for the debug library). +These functions are declared in lualib.h. + + + +

    6.1 – Basic Functions

    + +

    +The basic library provides core functions to Lua. +If you do not include this library in your application, +you should check carefully whether you need to provide +implementations for some of its facilities. + + +

    +


    assert (v [, message])

    +Issues an error when +the value of its argument v is false (i.e., nil or false); +otherwise, returns all its arguments. +message is an error message; +when absent, it defaults to "assertion failed!" + + + + +

    +


    collectgarbage ([opt [, arg]])

    + + +

    +This function is a generic interface to the garbage collector. +It performs different functions according to its first argument, opt: + +

      + +
    • "collect": +performs a full garbage-collection cycle. +This is the default option. +
    • + +
    • "stop": +stops automatic execution of the garbage collector. +The collector will run only when explicitly invoked, +until a call to restart it. +
    • + +
    • "restart": +restarts automatic execution of the garbage collector. +
    • + +
    • "count": +returns the total memory in use by Lua (in Kbytes) and +a second value with the total memory in bytes modulo 1024. +The first value has a fractional part, +so the following equality is always true: + +
      +     k, b = collectgarbage("count")
      +     assert(k*1024 == math.floor(k)*1024 + b)
      +

      +(The second result is useful when Lua is compiled +with a non floating-point type for numbers.) +

    • + +
    • "step": +performs a garbage-collection step. +The step "size" is controlled by arg +(larger values mean more steps) in a non-specified way. +If you want to control the step size +you must experimentally tune the value of arg. +Returns true if the step finished a collection cycle. +
    • + +
    • "setpause": +sets arg as the new value for the pause of +the collector (see §2.5). +Returns the previous value for pause. +
    • + +
    • "setstepmul": +sets arg as the new value for the step multiplier of +the collector (see §2.5). +Returns the previous value for step. +
    • + +
    • "isrunning": +returns a boolean that tells whether the collector is running +(i.e., not stopped). +
    • + +
    • "generational": +changes the collector to generational mode. +This is an experimental feature (see §2.5). +
    • + +
    • "incremental": +changes the collector to incremental mode. +This is the default mode. +
    • + +
    + + + +

    +


    dofile ([filename])

    +Opens the named file and executes its contents as a Lua chunk. +When called without arguments, +dofile executes the contents of the standard input (stdin). +Returns all values returned by the chunk. +In case of errors, dofile propagates the error +to its caller (that is, dofile does not run in protected mode). + + + + +

    +


    error (message [, level])

    +Terminates the last protected function called +and returns message as the error message. +Function error never returns. + + +

    +Usually, error adds some information about the error position +at the beginning of the message, if the message is a string. +The level argument specifies how to get the error position. +With level 1 (the default), the error position is where the +error function was called. +Level 2 points the error to where the function +that called error was called; and so on. +Passing a level 0 avoids the addition of error position information +to the message. + + + + +

    +


    _G

    +A global variable (not a function) that +holds the global environment (see §2.2). +Lua itself does not use this variable; +changing its value does not affect any environment, +nor vice-versa. + + + + +

    +


    getmetatable (object)

    + + +

    +If object does not have a metatable, returns nil. +Otherwise, +if the object's metatable has a "__metatable" field, +returns the associated value. +Otherwise, returns the metatable of the given object. + + + + +

    +


    ipairs (t)

    + + +

    +If t has a metamethod __ipairs, +calls it with t as argument and returns the first three +results from the call. + + +

    +Otherwise, +returns three values: an iterator function, the table t, and 0, +so that the construction + +

    +     for i,v in ipairs(t) do body end
    +

    +will iterate over the pairs (1,t[1]), (2,t[2]), ..., +up to the first integer key absent from the table. + + + + +

    +


    load (ld [, source [, mode [, env]]])

    + + +

    +Loads a chunk. + + +

    +If ld is a string, the chunk is this string. +If ld is a function, +load calls it repeatedly to get the chunk pieces. +Each call to ld must return a string that concatenates +with previous results. +A return of an empty string, nil, or no value signals the end of the chunk. + + +

    +If there are no syntactic errors, +returns the compiled chunk as a function; +otherwise, returns nil plus the error message. + + +

    +If the resulting function has upvalues, +the first upvalue is set to the value of env, +if that parameter is given, +or to the value of the global environment. +(When you load a main chunk, +the resulting function will always have exactly one upvalue, +the _ENV variable (see §2.2). +When you load a binary chunk created from a function (see string.dump), +the resulting function can have arbitrary upvalues.) + + +

    +source is used as the source of the chunk for error messages +and debug information (see §4.9). +When absent, +it defaults to ld, if ld is a string, +or to "=(load)" otherwise. + + +

    +The string mode controls whether the chunk can be text or binary +(that is, a precompiled chunk). +It may be the string "b" (only binary chunks), +"t" (only text chunks), +or "bt" (both binary and text). +The default is "bt". + + + + +

    +


    loadfile ([filename [, mode [, env]]])

    + + +

    +Similar to load, +but gets the chunk from file filename +or from the standard input, +if no file name is given. + + + + +

    +


    next (table [, index])

    + + +

    +Allows a program to traverse all fields of a table. +Its first argument is a table and its second argument +is an index in this table. +next returns the next index of the table +and its associated value. +When called with nil as its second argument, +next returns an initial index +and its associated value. +When called with the last index, +or with nil in an empty table, +next returns nil. +If the second argument is absent, then it is interpreted as nil. +In particular, +you can use next(t) to check whether a table is empty. + + +

    +The order in which the indices are enumerated is not specified, +even for numeric indices. +(To traverse a table in numeric order, +use a numerical for.) + + +

    +The behavior of next is undefined if, +during the traversal, +you assign any value to a non-existent field in the table. +You may however modify existing fields. +In particular, you may clear existing fields. + + + + +

    +


    pairs (t)

    + + +

    +If t has a metamethod __pairs, +calls it with t as argument and returns the first three +results from the call. + + +

    +Otherwise, +returns three values: the next function, the table t, and nil, +so that the construction + +

    +     for k,v in pairs(t) do body end
    +

    +will iterate over all key–value pairs of table t. + + +

    +See function next for the caveats of modifying +the table during its traversal. + + + + +

    +


    pcall (f [, arg1, ···])

    + + +

    +Calls function f with +the given arguments in protected mode. +This means that any error inside f is not propagated; +instead, pcall catches the error +and returns a status code. +Its first result is the status code (a boolean), +which is true if the call succeeds without errors. +In such case, pcall also returns all results from the call, +after this first result. +In case of any error, pcall returns false plus the error message. + + + + +

    +


    print (···)

    +Receives any number of arguments +and prints their values to stdout, +using the tostring function to convert each argument to a string. +print is not intended for formatted output, +but only as a quick way to show a value, +for instance for debugging. +For complete control over the output, +use string.format and io.write. + + + + +

    +


    rawequal (v1, v2)

    +Checks whether v1 is equal to v2, +without invoking any metamethod. +Returns a boolean. + + + + +

    +


    rawget (table, index)

    +Gets the real value of table[index], +without invoking any metamethod. +table must be a table; +index may be any value. + + + + +

    +


    rawlen (v)

    +Returns the length of the object v, +which must be a table or a string, +without invoking any metamethod. +Returns an integer number. + + + + +

    +


    rawset (table, index, value)

    +Sets the real value of table[index] to value, +without invoking any metamethod. +table must be a table, +index any value different from nil and NaN, +and value any Lua value. + + +

    +This function returns table. + + + + +

    +


    select (index, ···)

    + + +

    +If index is a number, +returns all arguments after argument number index; +a negative number indexes from the end (-1 is the last argument). +Otherwise, index must be the string "#", +and select returns the total number of extra arguments it received. + + + + +

    +


    setmetatable (table, metatable)

    + + +

    +Sets the metatable for the given table. +(You cannot change the metatable of other types from Lua, only from C.) +If metatable is nil, +removes the metatable of the given table. +If the original metatable has a "__metatable" field, +raises an error. + + +

    +This function returns table. + + + + +

    +


    tonumber (e [, base])

    + + +

    +When called with no base, +tonumber tries to convert its argument to a number. +If the argument is already a number or +a string convertible to a number (see §3.4.2), +then tonumber returns this number; +otherwise, it returns nil. + + +

    +When called with base, +then e should be a string to be interpreted as +an integer numeral in that base. +The base may be any integer between 2 and 36, inclusive. +In bases above 10, the letter 'A' (in either upper or lower case) +represents 10, 'B' represents 11, and so forth, +with 'Z' representing 35. +If the string e is not a valid numeral in the given base, +the function returns nil. + + + + +

    +


    tostring (v)

    +Receives a value of any type and +converts it to a string in a reasonable format. +(For complete control of how numbers are converted, +use string.format.) + + +

    +If the metatable of v has a "__tostring" field, +then tostring calls the corresponding value +with v as argument, +and uses the result of the call as its result. + + + + +

    +


    type (v)

    +Returns the type of its only argument, coded as a string. +The possible results of this function are +"nil" (a string, not the value nil), +"number", +"string", +"boolean", +"table", +"function", +"thread", +and "userdata". + + + + +

    +


    _VERSION

    +A global variable (not a function) that +holds a string containing the current interpreter version. +The current contents of this variable is "Lua 5.2". + + + + +

    +


    xpcall (f, msgh [, arg1, ···])

    + + +

    +This function is similar to pcall, +except that it sets a new message handler msgh. + + + + + + + +

    6.2 – Coroutine Manipulation

    + +

    +The operations related to coroutines comprise a sub-library of +the basic library and come inside the table coroutine. +See §2.6 for a general description of coroutines. + + +

    +


    coroutine.create (f)

    + + +

    +Creates a new coroutine, with body f. +f must be a Lua function. +Returns this new coroutine, +an object with type "thread". + + + + +

    +


    coroutine.resume (co [, val1, ···])

    + + +

    +Starts or continues the execution of coroutine co. +The first time you resume a coroutine, +it starts running its body. +The values val1, ... are passed +as the arguments to the body function. +If the coroutine has yielded, +resume restarts it; +the values val1, ... are passed +as the results from the yield. + + +

    +If the coroutine runs without any errors, +resume returns true plus any values passed to yield +(if the coroutine yields) or any values returned by the body function +(if the coroutine terminates). +If there is any error, +resume returns false plus the error message. + + + + +

    +


    coroutine.running ()

    + + +

    +Returns the running coroutine plus a boolean, +true when the running coroutine is the main one. + + + + +

    +


    coroutine.status (co)

    + + +

    +Returns the status of coroutine co, as a string: +"running", +if the coroutine is running (that is, it called status); +"suspended", if the coroutine is suspended in a call to yield, +or if it has not started running yet; +"normal" if the coroutine is active but not running +(that is, it has resumed another coroutine); +and "dead" if the coroutine has finished its body function, +or if it has stopped with an error. + + + + +

    +


    coroutine.wrap (f)

    + + +

    +Creates a new coroutine, with body f. +f must be a Lua function. +Returns a function that resumes the coroutine each time it is called. +Any arguments passed to the function behave as the +extra arguments to resume. +Returns the same values returned by resume, +except the first boolean. +In case of error, propagates the error. + + + + +

    +


    coroutine.yield (···)

    + + +

    +Suspends the execution of the calling coroutine. +Any arguments to yield are passed as extra results to resume. + + + + + + + +

    6.3 – Modules

    + +

    +The package library provides basic +facilities for loading modules in Lua. +It exports one function directly in the global environment: +require. +Everything else is exported in a table package. + + +

    +


    require (modname)

    + + +

    +Loads the given module. +The function starts by looking into the package.loaded table +to determine whether modname is already loaded. +If it is, then require returns the value stored +at package.loaded[modname]. +Otherwise, it tries to find a loader for the module. + + +

    +To find a loader, +require is guided by the package.searchers sequence. +By changing this sequence, +we can change how require looks for a module. +The following explanation is based on the default configuration +for package.searchers. + + +

    +First require queries package.preload[modname]. +If it has a value, +this value (which should be a function) is the loader. +Otherwise require searches for a Lua loader using the +path stored in package.path. +If that also fails, it searches for a C loader using the +path stored in package.cpath. +If that also fails, +it tries an all-in-one loader (see package.searchers). + + +

    +Once a loader is found, +require calls the loader with two arguments: +modname and an extra value dependent on how it got the loader. +(If the loader came from a file, +this extra value is the file name.) +If the loader returns any non-nil value, +require assigns the returned value to package.loaded[modname]. +If the loader does not return a non-nil value and +has not assigned any value to package.loaded[modname], +then require assigns true to this entry. +In any case, require returns the +final value of package.loaded[modname]. + + +

    +If there is any error loading or running the module, +or if it cannot find any loader for the module, +then require raises an error. + + + + +

    +


    package.config

    + + +

    +A string describing some compile-time configurations for packages. +This string is a sequence of lines: + +

      + +
    • The first line is the directory separator string. +Default is '\' for Windows and '/' for all other systems.
    • + +
    • The second line is the character that separates templates in a path. +Default is ';'.
    • + +
    • The third line is the string that marks the +substitution points in a template. +Default is '?'.
    • + +
    • The fourth line is a string that, in a path in Windows, +is replaced by the executable's directory. +Default is '!'.
    • + +
    • The fifth line is a mark to ignore all text before it +when building the luaopen_ function name. +Default is '-'.
    • + +
    + + + +

    +


    package.cpath

    + + +

    +The path used by require to search for a C loader. + + +

    +Lua initializes the C path package.cpath in the same way +it initializes the Lua path package.path, +using the environment variable LUA_CPATH_5_2 +or the environment variable LUA_CPATH +or a default path defined in luaconf.h. + + + + +

    +


    package.loaded

    + + +

    +A table used by require to control which +modules are already loaded. +When you require a module modname and +package.loaded[modname] is not false, +require simply returns the value stored there. + + +

    +This variable is only a reference to the real table; +assignments to this variable do not change the +table used by require. + + + + +

    +


    package.loadlib (libname, funcname)

    + + +

    +Dynamically links the host program with the C library libname. + + +

    +If funcname is "*", +then it only links with the library, +making the symbols exported by the library +available to other dynamically linked libraries. +Otherwise, +it looks for a function funcname inside the library +and returns this function as a C function. +So, funcname must follow the lua_CFunction prototype +(see lua_CFunction). + + +

    +This is a low-level function. +It completely bypasses the package and module system. +Unlike require, +it does not perform any path searching and +does not automatically adds extensions. +libname must be the complete file name of the C library, +including if necessary a path and an extension. +funcname must be the exact name exported by the C library +(which may depend on the C compiler and linker used). + + +

    +This function is not supported by Standard C. +As such, it is only available on some platforms +(Windows, Linux, Mac OS X, Solaris, BSD, +plus other Unix systems that support the dlfcn standard). + + + + +

    +


    package.path

    + + +

    +The path used by require to search for a Lua loader. + + +

    +At start-up, Lua initializes this variable with +the value of the environment variable LUA_PATH_5_2 or +the environment variable LUA_PATH or +with a default path defined in luaconf.h, +if those environment variables are not defined. +Any ";;" in the value of the environment variable +is replaced by the default path. + + + + +

    +


    package.preload

    + + +

    +A table to store loaders for specific modules +(see require). + + +

    +This variable is only a reference to the real table; +assignments to this variable do not change the +table used by require. + + + + +

    +


    package.searchers

    + + +

    +A table used by require to control how to load modules. + + +

    +Each entry in this table is a searcher function. +When looking for a module, +require calls each of these searchers in ascending order, +with the module name (the argument given to require) as its +sole parameter. +The function can return another function (the module loader) +plus an extra value that will be passed to that loader, +or a string explaining why it did not find that module +(or nil if it has nothing to say). + + +

    +Lua initializes this table with four searcher functions. + + +

    +The first searcher simply looks for a loader in the +package.preload table. + + +

    +The second searcher looks for a loader as a Lua library, +using the path stored at package.path. +The search is done as described in function package.searchpath. + + +

    +The third searcher looks for a loader as a C library, +using the path given by the variable package.cpath. +Again, +the search is done as described in function package.searchpath. +For instance, +if the C path is the string + +

    +     "./?.so;./?.dll;/usr/local/?/init.so"
    +

    +the searcher for module foo +will try to open the files ./foo.so, ./foo.dll, +and /usr/local/foo/init.so, in that order. +Once it finds a C library, +this searcher first uses a dynamic link facility to link the +application with the library. +Then it tries to find a C function inside the library to +be used as the loader. +The name of this C function is the string "luaopen_" +concatenated with a copy of the module name where each dot +is replaced by an underscore. +Moreover, if the module name has a hyphen, +its prefix up to (and including) the first hyphen is removed. +For instance, if the module name is a.v1-b.c, +the function name will be luaopen_b_c. + + +

    +The fourth searcher tries an all-in-one loader. +It searches the C path for a library for +the root name of the given module. +For instance, when requiring a.b.c, +it will search for a C library for a. +If found, it looks into it for an open function for +the submodule; +in our example, that would be luaopen_a_b_c. +With this facility, a package can pack several C submodules +into one single library, +with each submodule keeping its original open function. + + +

    +All searchers except the first one (preload) return as the extra value +the file name where the module was found, +as returned by package.searchpath. +The first searcher returns no extra value. + + + + +

    +


    package.searchpath (name, path [, sep [, rep]])

    + + +

    +Searches for the given name in the given path. + + +

    +A path is a string containing a sequence of +templates separated by semicolons. +For each template, +the function replaces each interrogation mark (if any) +in the template with a copy of name +wherein all occurrences of sep +(a dot, by default) +were replaced by rep +(the system's directory separator, by default), +and then tries to open the resulting file name. + + +

    +For instance, if the path is the string + +

    +     "./?.lua;./?.lc;/usr/local/?/init.lua"
    +

    +the search for the name foo.a +will try to open the files +./foo/a.lua, ./foo/a.lc, and +/usr/local/foo/a/init.lua, in that order. + + +

    +Returns the resulting name of the first file that it can +open in read mode (after closing the file), +or nil plus an error message if none succeeds. +(This error message lists all file names it tried to open.) + + + + + + + +

    6.4 – String Manipulation

    + +

    +This library provides generic functions for string manipulation, +such as finding and extracting substrings, and pattern matching. +When indexing a string in Lua, the first character is at position 1 +(not at 0, as in C). +Indices are allowed to be negative and are interpreted as indexing backwards, +from the end of the string. +Thus, the last character is at position -1, and so on. + + +

    +The string library provides all its functions inside the table +string. +It also sets a metatable for strings +where the __index field points to the string table. +Therefore, you can use the string functions in object-oriented style. +For instance, string.byte(s,i) +can be written as s:byte(i). + + +

    +The string library assumes one-byte character encodings. + + +

    +


    string.byte (s [, i [, j]])

    +Returns the internal numerical codes of the characters s[i], +s[i+1], ..., s[j]. +The default value for i is 1; +the default value for j is i. +These indices are corrected +following the same rules of function string.sub. + + +

    +Numerical codes are not necessarily portable across platforms. + + + + +

    +


    string.char (···)

    +Receives zero or more integers. +Returns a string with length equal to the number of arguments, +in which each character has the internal numerical code equal +to its corresponding argument. + + +

    +Numerical codes are not necessarily portable across platforms. + + + + +

    +


    string.dump (function)

    + + +

    +Returns a string containing a binary representation of the given function, +so that a later load on this string returns +a copy of the function (but with new upvalues). + + + + +

    +


    string.find (s, pattern [, init [, plain]])

    + + +

    +Looks for the first match of +pattern in the string s. +If it finds a match, then find returns the indices of s +where this occurrence starts and ends; +otherwise, it returns nil. +A third, optional numerical argument init specifies +where to start the search; +its default value is 1 and can be negative. +A value of true as a fourth, optional argument plain +turns off the pattern matching facilities, +so the function does a plain "find substring" operation, +with no characters in pattern being considered magic. +Note that if plain is given, then init must be given as well. + + +

    +If the pattern has captures, +then in a successful match +the captured values are also returned, +after the two indices. + + + + +

    +


    string.format (formatstring, ···)

    + + +

    +Returns a formatted version of its variable number of arguments +following the description given in its first argument (which must be a string). +The format string follows the same rules as the ANSI C function sprintf. +The only differences are that the options/modifiers +*, h, L, l, n, +and p are not supported +and that there is an extra option, q. +The q option formats a string between double quotes, +using escape sequences when necessary to ensure that +it can safely be read back by the Lua interpreter. +For instance, the call + +

    +     string.format('%q', 'a string with "quotes" and \n new line')
    +

    +may produce the string: + +

    +     "a string with \"quotes\" and \
    +      new line"
    +
    + +

    +Options +A and a (when available), +E, e, f, +G, and g all expect a number as argument. +Options c, d, +i, o, u, X, and x +also expect a number, +but the range of that number may be limited by +the underlying C implementation. +For options o, u, X, and x, +the number cannot be negative. +Option q expects a string; +option s expects a string without embedded zeros. +If the argument to option s is not a string, +it is converted to one following the same rules of tostring. + + + + +

    +


    string.gmatch (s, pattern)

    +Returns an iterator function that, +each time it is called, +returns the next captures from pattern over the string s. +If pattern specifies no captures, +then the whole match is produced in each call. + + +

    +As an example, the following loop +will iterate over all the words from string s, +printing one per line: + +

    +     s = "hello world from Lua"
    +     for w in string.gmatch(s, "%a+") do
    +       print(w)
    +     end
    +

    +The next example collects all pairs key=value from the +given string into a table: + +

    +     t = {}
    +     s = "from=world, to=Lua"
    +     for k, v in string.gmatch(s, "(%w+)=(%w+)") do
    +       t[k] = v
    +     end
    +
    + +

    +For this function, a caret '^' at the start of a pattern does not +work as an anchor, as this would prevent the iteration. + + + + +

    +


    string.gsub (s, pattern, repl [, n])

    +Returns a copy of s +in which all (or the first n, if given) +occurrences of the pattern have been +replaced by a replacement string specified by repl, +which can be a string, a table, or a function. +gsub also returns, as its second value, +the total number of matches that occurred. +The name gsub comes from Global SUBstitution. + + +

    +If repl is a string, then its value is used for replacement. +The character % works as an escape character: +any sequence in repl of the form %d, +with d between 1 and 9, +stands for the value of the d-th captured substring. +The sequence %0 stands for the whole match. +The sequence %% stands for a single %. + + +

    +If repl is a table, then the table is queried for every match, +using the first capture as the key. + + +

    +If repl is a function, then this function is called every time a +match occurs, with all captured substrings passed as arguments, +in order. + + +

    +In any case, +if the pattern specifies no captures, +then it behaves as if the whole pattern was inside a capture. + + +

    +If the value returned by the table query or by the function call +is a string or a number, +then it is used as the replacement string; +otherwise, if it is false or nil, +then there is no replacement +(that is, the original match is kept in the string). + + +

    +Here are some examples: + +

    +     x = string.gsub("hello world", "(%w+)", "%1 %1")
    +     --> x="hello hello world world"
    +     
    +     x = string.gsub("hello world", "%w+", "%0 %0", 1)
    +     --> x="hello hello world"
    +     
    +     x = string.gsub("hello world from Lua", "(%w+)%s*(%w+)", "%2 %1")
    +     --> x="world hello Lua from"
    +     
    +     x = string.gsub("home = $HOME, user = $USER", "%$(%w+)", os.getenv)
    +     --> x="home = /home/roberto, user = roberto"
    +     
    +     x = string.gsub("4+5 = $return 4+5$", "%$(.-)%$", function (s)
    +           return load(s)()
    +         end)
    +     --> x="4+5 = 9"
    +     
    +     local t = {name="lua", version="5.2"}
    +     x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t)
    +     --> x="lua-5.2.tar.gz"
    +
    + + + +

    +


    string.len (s)

    +Receives a string and returns its length. +The empty string "" has length 0. +Embedded zeros are counted, +so "a\000bc\000" has length 5. + + + + +

    +


    string.lower (s)

    +Receives a string and returns a copy of this string with all +uppercase letters changed to lowercase. +All other characters are left unchanged. +The definition of what an uppercase letter is depends on the current locale. + + + + +

    +


    string.match (s, pattern [, init])

    +Looks for the first match of +pattern in the string s. +If it finds one, then match returns +the captures from the pattern; +otherwise it returns nil. +If pattern specifies no captures, +then the whole match is returned. +A third, optional numerical argument init specifies +where to start the search; +its default value is 1 and can be negative. + + + + +

    +


    string.rep (s, n [, sep])

    +Returns a string that is the concatenation of n copies of +the string s separated by the string sep. +The default value for sep is the empty string +(that is, no separator). + + + + +

    +


    string.reverse (s)

    +Returns a string that is the string s reversed. + + + + +

    +


    string.sub (s, i [, j])

    +Returns the substring of s that +starts at i and continues until j; +i and j can be negative. +If j is absent, then it is assumed to be equal to -1 +(which is the same as the string length). +In particular, +the call string.sub(s,1,j) returns a prefix of s +with length j, +and string.sub(s, -i) returns a suffix of s +with length i. + + +

    +If, after the translation of negative indices, +i is less than 1, +it is corrected to 1. +If j is greater than the string length, +it is corrected to that length. +If, after these corrections, +i is greater than j, +the function returns the empty string. + + + + +

    +


    string.upper (s)

    +Receives a string and returns a copy of this string with all +lowercase letters changed to uppercase. +All other characters are left unchanged. +The definition of what a lowercase letter is depends on the current locale. + + + +

    6.4.1 – Patterns

    + + +

    Character Class:

    +A character class is used to represent a set of characters. +The following combinations are allowed in describing a character class: + +

      + +
    • x: +(where x is not one of the magic characters +^$()%.[]*+-?) +represents the character x itself. +
    • + +
    • .: (a dot) represents all characters.
    • + +
    • %a: represents all letters.
    • + +
    • %c: represents all control characters.
    • + +
    • %d: represents all digits.
    • + +
    • %g: represents all printable characters except space.
    • + +
    • %l: represents all lowercase letters.
    • + +
    • %p: represents all punctuation characters.
    • + +
    • %s: represents all space characters.
    • + +
    • %u: represents all uppercase letters.
    • + +
    • %w: represents all alphanumeric characters.
    • + +
    • %x: represents all hexadecimal digits.
    • + +
    • %x: (where x is any non-alphanumeric character) +represents the character x. +This is the standard way to escape the magic characters. +Any punctuation character (even the non magic) +can be preceded by a '%' +when used to represent itself in a pattern. +
    • + +
    • [set]: +represents the class which is the union of all +characters in set. +A range of characters can be specified by +separating the end characters of the range, +in ascending order, with a '-', +All classes %x described above can also be used as +components in set. +All other characters in set represent themselves. +For example, [%w_] (or [_%w]) +represents all alphanumeric characters plus the underscore, +[0-7] represents the octal digits, +and [0-7%l%-] represents the octal digits plus +the lowercase letters plus the '-' character. + + +

      +The interaction between ranges and classes is not defined. +Therefore, patterns like [%a-z] or [a-%%] +have no meaning. +

    • + +
    • [^set]: +represents the complement of set, +where set is interpreted as above. +
    • + +

    +For all classes represented by single letters (%a, %c, etc.), +the corresponding uppercase letter represents the complement of the class. +For instance, %S represents all non-space characters. + + +

    +The definitions of letter, space, and other character groups +depend on the current locale. +In particular, the class [a-z] may not be equivalent to %l. + + + + + +

    Pattern Item:

    +A pattern item can be + +

      + +
    • +a single character class, +which matches any single character in the class; +
    • + +
    • +a single character class followed by '*', +which matches 0 or more repetitions of characters in the class. +These repetition items will always match the longest possible sequence; +
    • + +
    • +a single character class followed by '+', +which matches 1 or more repetitions of characters in the class. +These repetition items will always match the longest possible sequence; +
    • + +
    • +a single character class followed by '-', +which also matches 0 or more repetitions of characters in the class. +Unlike '*', +these repetition items will always match the shortest possible sequence; +
    • + +
    • +a single character class followed by '?', +which matches 0 or 1 occurrence of a character in the class; +
    • + +
    • +%n, for n between 1 and 9; +such item matches a substring equal to the n-th captured string +(see below); +
    • + +
    • +%bxy, where x and y are two distinct characters; +such item matches strings that start with x, end with y, +and where the x and y are balanced. +This means that, if one reads the string from left to right, +counting +1 for an x and -1 for a y, +the ending y is the first y where the count reaches 0. +For instance, the item %b() matches expressions with +balanced parentheses. +
    • + +
    • +%f[set], a frontier pattern; +such item matches an empty string at any position such that +the next character belongs to set +and the previous character does not belong to set. +The set set is interpreted as previously described. +The beginning and the end of the subject are handled as if +they were the character '\0'. +
    • + +
    + + + + +

    Pattern:

    +A pattern is a sequence of pattern items. +A caret '^' at the beginning of a pattern anchors the match at the +beginning of the subject string. +A '$' at the end of a pattern anchors the match at the +end of the subject string. +At other positions, +'^' and '$' have no special meaning and represent themselves. + + + + + +

    Captures:

    +A pattern can contain sub-patterns enclosed in parentheses; +they describe captures. +When a match succeeds, the substrings of the subject string +that match captures are stored (captured) for future use. +Captures are numbered according to their left parentheses. +For instance, in the pattern "(a*(.)%w(%s*))", +the part of the string matching "a*(.)%w(%s*)" is +stored as the first capture (and therefore has number 1); +the character matching "." is captured with number 2, +and the part matching "%s*" has number 3. + + +

    +As a special case, the empty capture () captures +the current string position (a number). +For instance, if we apply the pattern "()aa()" on the +string "flaaap", there will be two captures: 3 and 5. + + + + + + + + + + + +

    6.5 – Table Manipulation

    + +

    +This library provides generic functions for table manipulation. +It provides all its functions inside the table table. + + +

    +Remember that, whenever an operation needs the length of a table, +the table should be a proper sequence +or have a __len metamethod (see §3.4.6). +All functions ignore non-numeric keys +in tables given as arguments. + + +

    +For performance reasons, +all table accesses (get/set) performed by these functions are raw. + + +

    +


    table.concat (list [, sep [, i [, j]]])

    + + +

    +Given a list where all elements are strings or numbers, +returns the string list[i]..sep..list[i+1] ··· sep..list[j]. +The default value for sep is the empty string, +the default for i is 1, +and the default for j is #list. +If i is greater than j, returns the empty string. + + + + +

    +


    table.insert (list, [pos,] value)

    + + +

    +Inserts element value at position pos in list, +shifting up the elements +list[pos], list[pos+1], ···, list[#list]. +The default value for pos is #list+1, +so that a call table.insert(t,x) inserts x at the end +of list t. + + + + +

    +


    table.pack (···)

    + + +

    +Returns a new table with all parameters stored into keys 1, 2, etc. +and with a field "n" with the total number of parameters. +Note that the resulting table may not be a sequence. + + + + +

    +


    table.remove (list [, pos])

    + + +

    +Removes from list the element at position pos, +returning the value of the removed element. +When pos is an integer between 1 and #list, +it shifts down the elements +list[pos+1], list[pos+2], ···, list[#list] +and erases element list[#list]; +The index pos can also be 0 when #list is 0, +or #list + 1; +in those cases, the function erases the element list[pos]. + + +

    +The default value for pos is #list, +so that a call table.remove(t) removes the last element +of list t. + + + + +

    +


    table.sort (list [, comp])

    + + +

    +Sorts list elements in a given order, in-place, +from list[1] to list[#list]. +If comp is given, +then it must be a function that receives two list elements +and returns true when the first element must come +before the second in the final order +(so that not comp(list[i+1],list[i]) will be true after the sort). +If comp is not given, +then the standard Lua operator < is used instead. + + +

    +The sort algorithm is not stable; +that is, elements considered equal by the given order +may have their relative positions changed by the sort. + + + + +

    +


    table.unpack (list [, i [, j]])

    + + +

    +Returns the elements from the given table. +This function is equivalent to + +

    +     return list[i], list[i+1], ···, list[j]
    +

    +By default, i is 1 and j is #list. + + + + + + + +

    6.6 – Mathematical Functions

    + +

    +This library is an interface to the standard C math library. +It provides all its functions inside the table math. + + +

    +


    math.abs (x)

    + + +

    +Returns the absolute value of x. + + + + +

    +


    math.acos (x)

    + + +

    +Returns the arc cosine of x (in radians). + + + + +

    +


    math.asin (x)

    + + +

    +Returns the arc sine of x (in radians). + + + + +

    +


    math.atan (x)

    + + +

    +Returns the arc tangent of x (in radians). + + + + +

    +


    math.atan2 (y, x)

    + + +

    +Returns the arc tangent of y/x (in radians), +but uses the signs of both parameters to find the +quadrant of the result. +(It also handles correctly the case of x being zero.) + + + + +

    +


    math.ceil (x)

    + + +

    +Returns the smallest integer larger than or equal to x. + + + + +

    +


    math.cos (x)

    + + +

    +Returns the cosine of x (assumed to be in radians). + + + + +

    +


    math.cosh (x)

    + + +

    +Returns the hyperbolic cosine of x. + + + + +

    +


    math.deg (x)

    + + +

    +Returns the angle x (given in radians) in degrees. + + + + +

    +


    math.exp (x)

    + + +

    +Returns the value ex. + + + + +

    +


    math.floor (x)

    + + +

    +Returns the largest integer smaller than or equal to x. + + + + +

    +


    math.fmod (x, y)

    + + +

    +Returns the remainder of the division of x by y +that rounds the quotient towards zero. + + + + +

    +


    math.frexp (x)

    + + +

    +Returns m and e such that x = m2e, +e is an integer and the absolute value of m is +in the range [0.5, 1) +(or zero when x is zero). + + + + +

    +


    math.huge

    + + +

    +The value HUGE_VAL, +a value larger than or equal to any other numerical value. + + + + +

    +


    math.ldexp (m, e)

    + + +

    +Returns m2e (e should be an integer). + + + + +

    +


    math.log (x [, base])

    + + +

    +Returns the logarithm of x in the given base. +The default for base is e +(so that the function returns the natural logarithm of x). + + + + +

    +


    math.max (x, ···)

    + + +

    +Returns the maximum value among its arguments. + + + + +

    +


    math.min (x, ···)

    + + +

    +Returns the minimum value among its arguments. + + + + +

    +


    math.modf (x)

    + + +

    +Returns two numbers, +the integral part of x and the fractional part of x. + + + + +

    +


    math.pi

    + + +

    +The value of π. + + + + +

    +


    math.pow (x, y)

    + + +

    +Returns xy. +(You can also use the expression x^y to compute this value.) + + + + +

    +


    math.rad (x)

    + + +

    +Returns the angle x (given in degrees) in radians. + + + + +

    +


    math.random ([m [, n]])

    + + +

    +This function is an interface to the simple +pseudo-random generator function rand provided by Standard C. +(No guarantees can be given for its statistical properties.) + + +

    +When called without arguments, +returns a uniform pseudo-random real number +in the range [0,1). +When called with an integer number m, +math.random returns +a uniform pseudo-random integer in the range [1, m]. +When called with two integer numbers m and n, +math.random returns a uniform pseudo-random +integer in the range [m, n]. + + + + +

    +


    math.randomseed (x)

    + + +

    +Sets x as the "seed" +for the pseudo-random generator: +equal seeds produce equal sequences of numbers. + + + + +

    +


    math.sin (x)

    + + +

    +Returns the sine of x (assumed to be in radians). + + + + +

    +


    math.sinh (x)

    + + +

    +Returns the hyperbolic sine of x. + + + + +

    +


    math.sqrt (x)

    + + +

    +Returns the square root of x. +(You can also use the expression x^0.5 to compute this value.) + + + + +

    +


    math.tan (x)

    + + +

    +Returns the tangent of x (assumed to be in radians). + + + + +

    +


    math.tanh (x)

    + + +

    +Returns the hyperbolic tangent of x. + + + + + + + +

    6.7 – Bitwise Operations

    + +

    +This library provides bitwise operations. +It provides all its functions inside the table bit32. + + +

    +Unless otherwise stated, +all functions accept numeric arguments in the range +(-251,+251); +each argument is normalized to +the remainder of its division by 232 +and truncated to an integer (in some unspecified way), +so that its final value falls in the range [0,232 - 1]. +Similarly, all results are in the range [0,232 - 1]. +Note that bit32.bnot(0) is 0xFFFFFFFF, +which is different from -1. + + +

    +


    bit32.arshift (x, disp)

    + + +

    +Returns the number x shifted disp bits to the right. +The number disp may be any representable integer. +Negative displacements shift to the left. + + +

    +This shift operation is what is called arithmetic shift. +Vacant bits on the left are filled +with copies of the higher bit of x; +vacant bits on the right are filled with zeros. +In particular, +displacements with absolute values higher than 31 +result in zero or 0xFFFFFFFF (all original bits are shifted out). + + + + +

    +


    bit32.band (···)

    + + +

    +Returns the bitwise and of its operands. + + + + +

    +


    bit32.bnot (x)

    + + +

    +Returns the bitwise negation of x. +For any integer x, +the following identity holds: + +

    +     assert(bit32.bnot(x) == (-1 - x) % 2^32)
    +
    + + + +

    +


    bit32.bor (···)

    + + +

    +Returns the bitwise or of its operands. + + + + +

    +


    bit32.btest (···)

    + + +

    +Returns a boolean signaling +whether the bitwise and of its operands is different from zero. + + + + +

    +


    bit32.bxor (···)

    + + +

    +Returns the bitwise exclusive or of its operands. + + + + +

    +


    bit32.extract (n, field [, width])

    + + +

    +Returns the unsigned number formed by the bits +field to field + width - 1 from n. +Bits are numbered from 0 (least significant) to 31 (most significant). +All accessed bits must be in the range [0, 31]. + + +

    +The default for width is 1. + + + + +

    +


    bit32.replace (n, v, field [, width])

    + + +

    +Returns a copy of n with +the bits field to field + width - 1 +replaced by the value v. +See bit32.extract for details about field and width. + + + + +

    +


    bit32.lrotate (x, disp)

    + + +

    +Returns the number x rotated disp bits to the left. +The number disp may be any representable integer. + + +

    +For any valid displacement, +the following identity holds: + +

    +     assert(bit32.lrotate(x, disp) == bit32.lrotate(x, disp % 32))
    +

    +In particular, +negative displacements rotate to the right. + + + + +

    +


    bit32.lshift (x, disp)

    + + +

    +Returns the number x shifted disp bits to the left. +The number disp may be any representable integer. +Negative displacements shift to the right. +In any direction, vacant bits are filled with zeros. +In particular, +displacements with absolute values higher than 31 +result in zero (all bits are shifted out). + + +

    +For positive displacements, +the following equality holds: + +

    +     assert(bit32.lshift(b, disp) == (b * 2^disp) % 2^32)
    +
    + + + +

    +


    bit32.rrotate (x, disp)

    + + +

    +Returns the number x rotated disp bits to the right. +The number disp may be any representable integer. + + +

    +For any valid displacement, +the following identity holds: + +

    +     assert(bit32.rrotate(x, disp) == bit32.rrotate(x, disp % 32))
    +

    +In particular, +negative displacements rotate to the left. + + + + +

    +


    bit32.rshift (x, disp)

    + + +

    +Returns the number x shifted disp bits to the right. +The number disp may be any representable integer. +Negative displacements shift to the left. +In any direction, vacant bits are filled with zeros. +In particular, +displacements with absolute values higher than 31 +result in zero (all bits are shifted out). + + +

    +For positive displacements, +the following equality holds: + +

    +     assert(bit32.rshift(b, disp) == math.floor(b % 2^32 / 2^disp))
    +
    + +

    +This shift operation is what is called logical shift. + + + + + + + +

    6.8 – Input and Output Facilities

    + +

    +The I/O library provides two different styles for file manipulation. +The first one uses implicit file descriptors; +that is, there are operations to set a default input file and a +default output file, +and all input/output operations are over these default files. +The second style uses explicit file descriptors. + + +

    +When using implicit file descriptors, +all operations are supplied by table io. +When using explicit file descriptors, +the operation io.open returns a file descriptor +and then all operations are supplied as methods of the file descriptor. + + +

    +The table io also provides +three predefined file descriptors with their usual meanings from C: +io.stdin, io.stdout, and io.stderr. +The I/O library never closes these files. + + +

    +Unless otherwise stated, +all I/O functions return nil on failure +(plus an error message as a second result and +a system-dependent error code as a third result) +and some value different from nil on success. +On non-Posix systems, +the computation of the error message and error code +in case of errors +may be not thread safe, +because they rely on the global C variable errno. + + +

    +


    io.close ([file])

    + + +

    +Equivalent to file:close(). +Without a file, closes the default output file. + + + + +

    +


    io.flush ()

    + + +

    +Equivalent to io.output():flush(). + + + + +

    +


    io.input ([file])

    + + +

    +When called with a file name, it opens the named file (in text mode), +and sets its handle as the default input file. +When called with a file handle, +it simply sets this file handle as the default input file. +When called without parameters, +it returns the current default input file. + + +

    +In case of errors this function raises the error, +instead of returning an error code. + + + + +

    +


    io.lines ([filename ···])

    + + +

    +Opens the given file name in read mode +and returns an iterator function that +works like file:lines(···) over the opened file. +When the iterator function detects the end of file, +it returns nil (to finish the loop) and automatically closes the file. + + +

    +The call io.lines() (with no file name) is equivalent +to io.input():lines(); +that is, it iterates over the lines of the default input file. +In this case it does not close the file when the loop ends. + + +

    +In case of errors this function raises the error, +instead of returning an error code. + + + + +

    +


    io.open (filename [, mode])

    + + +

    +This function opens a file, +in the mode specified in the string mode. +It returns a new file handle, +or, in case of errors, nil plus an error message. + + +

    +The mode string can be any of the following: + +

      +
    • "r": read mode (the default);
    • +
    • "w": write mode;
    • +
    • "a": append mode;
    • +
    • "r+": update mode, all previous data is preserved;
    • +
    • "w+": update mode, all previous data is erased;
    • +
    • "a+": append update mode, previous data is preserved, + writing is only allowed at the end of file.
    • +

    +The mode string can also have a 'b' at the end, +which is needed in some systems to open the file in binary mode. + + + + +

    +


    io.output ([file])

    + + +

    +Similar to io.input, but operates over the default output file. + + + + +

    +


    io.popen (prog [, mode])

    + + +

    +This function is system dependent and is not available +on all platforms. + + +

    +Starts program prog in a separated process and returns +a file handle that you can use to read data from this program +(if mode is "r", the default) +or to write data to this program +(if mode is "w"). + + + + +

    +


    io.read (···)

    + + +

    +Equivalent to io.input():read(···). + + + + +

    +


    io.tmpfile ()

    + + +

    +Returns a handle for a temporary file. +This file is opened in update mode +and it is automatically removed when the program ends. + + + + +

    +


    io.type (obj)

    + + +

    +Checks whether obj is a valid file handle. +Returns the string "file" if obj is an open file handle, +"closed file" if obj is a closed file handle, +or nil if obj is not a file handle. + + + + +

    +


    io.write (···)

    + + +

    +Equivalent to io.output():write(···). + + + + +

    +


    file:close ()

    + + +

    +Closes file. +Note that files are automatically closed when +their handles are garbage collected, +but that takes an unpredictable amount of time to happen. + + +

    +When closing a file handle created with io.popen, +file:close returns the same values +returned by os.execute. + + + + +

    +


    file:flush ()

    + + +

    +Saves any written data to file. + + + + +

    +


    file:lines (···)

    + + +

    +Returns an iterator function that, +each time it is called, +reads the file according to the given formats. +When no format is given, +uses "*l" as a default. +As an example, the construction + +

    +     for c in file:lines(1) do body end
    +

    +will iterate over all characters of the file, +starting at the current position. +Unlike io.lines, this function does not close the file +when the loop ends. + + +

    +In case of errors this function raises the error, +instead of returning an error code. + + + + +

    +


    file:read (···)

    + + +

    +Reads the file file, +according to the given formats, which specify what to read. +For each format, +the function returns a string (or a number) with the characters read, +or nil if it cannot read data with the specified format. +When called without formats, +it uses a default format that reads the next line +(see below). + + +

    +The available formats are + +

      + +
    • "*n": +reads a number; +this is the only format that returns a number instead of a string. +
    • + +
    • "*a": +reads the whole file, starting at the current position. +On end of file, it returns the empty string. +
    • + +
    • "*l": +reads the next line skipping the end of line, +returning nil on end of file. +This is the default format. +
    • + +
    • "*L": +reads the next line keeping the end of line (if present), +returning nil on end of file. +
    • + +
    • number: +reads a string with up to this number of bytes, +returning nil on end of file. +If number is zero, +it reads nothing and returns an empty string, +or nil on end of file. +
    • + +
    + + + +

    +


    file:seek ([whence [, offset]])

    + + +

    +Sets and gets the file position, +measured from the beginning of the file, +to the position given by offset plus a base +specified by the string whence, as follows: + +

      +
    • "set": base is position 0 (beginning of the file);
    • +
    • "cur": base is current position;
    • +
    • "end": base is end of file;
    • +

    +In case of success, seek returns the final file position, +measured in bytes from the beginning of the file. +If seek fails, it returns nil, +plus a string describing the error. + + +

    +The default value for whence is "cur", +and for offset is 0. +Therefore, the call file:seek() returns the current +file position, without changing it; +the call file:seek("set") sets the position to the +beginning of the file (and returns 0); +and the call file:seek("end") sets the position to the +end of the file, and returns its size. + + + + +

    +


    file:setvbuf (mode [, size])

    + + +

    +Sets the buffering mode for an output file. +There are three available modes: + +

      + +
    • "no": +no buffering; the result of any output operation appears immediately. +
    • + +
    • "full": +full buffering; output operation is performed only +when the buffer is full or when +you explicitly flush the file (see io.flush). +
    • + +
    • "line": +line buffering; output is buffered until a newline is output +or there is any input from some special files +(such as a terminal device). +
    • + +

    +For the last two cases, size +specifies the size of the buffer, in bytes. +The default is an appropriate size. + + + + +

    +


    file:write (···)

    + + +

    +Writes the value of each of its arguments to file. +The arguments must be strings or numbers. + + +

    +In case of success, this function returns file. +Otherwise it returns nil plus a string describing the error. + + + + + + + +

    6.9 – Operating System Facilities

    + +

    +This library is implemented through table os. + + +

    +


    os.clock ()

    + + +

    +Returns an approximation of the amount in seconds of CPU time +used by the program. + + + + +

    +


    os.date ([format [, time]])

    + + +

    +Returns a string or a table containing date and time, +formatted according to the given string format. + + +

    +If the time argument is present, +this is the time to be formatted +(see the os.time function for a description of this value). +Otherwise, date formats the current time. + + +

    +If format starts with '!', +then the date is formatted in Coordinated Universal Time. +After this optional character, +if format is the string "*t", +then date returns a table with the following fields: +year (four digits), month (1–12), day (1–31), +hour (0–23), min (0–59), sec (0–61), +wday (weekday, Sunday is 1), +yday (day of the year), +and isdst (daylight saving flag, a boolean). +This last field may be absent +if the information is not available. + + +

    +If format is not "*t", +then date returns the date as a string, +formatted according to the same rules as the ANSI C function strftime. + + +

    +When called without arguments, +date returns a reasonable date and time representation that depends on +the host system and on the current locale +(that is, os.date() is equivalent to os.date("%c")). + + +

    +On non-Posix systems, +this function may be not thread safe +because of its reliance on C function gmtime and C function localtime. + + + + +

    +


    os.difftime (t2, t1)

    + + +

    +Returns the number of seconds from time t1 to time t2. +In POSIX, Windows, and some other systems, +this value is exactly t2-t1. + + + + +

    +


    os.execute ([command])

    + + +

    +This function is equivalent to the ANSI C function system. +It passes command to be executed by an operating system shell. +Its first result is true +if the command terminated successfully, +or nil otherwise. +After this first result +the function returns a string and a number, +as follows: + +

      + +
    • "exit": +the command terminated normally; +the following number is the exit status of the command. +
    • + +
    • "signal": +the command was terminated by a signal; +the following number is the signal that terminated the command. +
    • + +
    + +

    +When called without a command, +os.execute returns a boolean that is true if a shell is available. + + + + +

    +


    os.exit ([code [, close])

    + + +

    +Calls the ANSI C function exit to terminate the host program. +If code is true, +the returned status is EXIT_SUCCESS; +if code is false, +the returned status is EXIT_FAILURE; +if code is a number, +the returned status is this number. +The default value for code is true. + + +

    +If the optional second argument close is true, +closes the Lua state before exiting. + + + + +

    +


    os.getenv (varname)

    + + +

    +Returns the value of the process environment variable varname, +or nil if the variable is not defined. + + + + +

    +


    os.remove (filename)

    + + +

    +Deletes the file (or empty directory, on POSIX systems) +with the given name. +If this function fails, it returns nil, +plus a string describing the error and the error code. + + + + +

    +


    os.rename (oldname, newname)

    + + +

    +Renames file or directory named oldname to newname. +If this function fails, it returns nil, +plus a string describing the error and the error code. + + + + +

    +


    os.setlocale (locale [, category])

    + + +

    +Sets the current locale of the program. +locale is a system-dependent string specifying a locale; +category is an optional string describing which category to change: +"all", "collate", "ctype", +"monetary", "numeric", or "time"; +the default category is "all". +The function returns the name of the new locale, +or nil if the request cannot be honored. + + +

    +If locale is the empty string, +the current locale is set to an implementation-defined native locale. +If locale is the string "C", +the current locale is set to the standard C locale. + + +

    +When called with nil as the first argument, +this function only returns the name of the current locale +for the given category. + + +

    +This function may be not thread safe +because of its reliance on C function setlocale. + + + + +

    +


    os.time ([table])

    + + +

    +Returns the current time when called without arguments, +or a time representing the date and time specified by the given table. +This table must have fields year, month, and day, +and may have fields +hour (default is 12), +min (default is 0), +sec (default is 0), +and isdst (default is nil). +For a description of these fields, see the os.date function. + + +

    +The returned value is a number, whose meaning depends on your system. +In POSIX, Windows, and some other systems, +this number counts the number +of seconds since some given start time (the "epoch"). +In other systems, the meaning is not specified, +and the number returned by time can be used only as an argument to +os.date and os.difftime. + + + + +

    +


    os.tmpname ()

    + + +

    +Returns a string with a file name that can +be used for a temporary file. +The file must be explicitly opened before its use +and explicitly removed when no longer needed. + + +

    +On POSIX systems, +this function also creates a file with that name, +to avoid security risks. +(Someone else might create the file with wrong permissions +in the time between getting the name and creating the file.) +You still have to open the file to use it +and to remove it (even if you do not use it). + + +

    +When possible, +you may prefer to use io.tmpfile, +which automatically removes the file when the program ends. + + + + + + + +

    6.10 – The Debug Library

    + +

    +This library provides +the functionality of the debug interface (§4.9) to Lua programs. +You should exert care when using this library. +Several of its functions +violate basic assumptions about Lua code +(e.g., that variables local to a function +cannot be accessed from outside; +that userdata metatables cannot be changed by Lua code; +that Lua programs do not crash) +and therefore can compromise otherwise secure code. +Moreover, some functions in this library may be slow. + + +

    +All functions in this library are provided +inside the debug table. +All functions that operate over a thread +have an optional first argument which is the +thread to operate over. +The default is always the current thread. + + +

    +


    debug.debug ()

    + + +

    +Enters an interactive mode with the user, +running each string that the user enters. +Using simple commands and other debug facilities, +the user can inspect global and local variables, +change their values, evaluate expressions, and so on. +A line containing only the word cont finishes this function, +so that the caller continues its execution. + + +

    +Note that commands for debug.debug are not lexically nested +within any function and so have no direct access to local variables. + + + + +

    +


    debug.gethook ([thread])

    + + +

    +Returns the current hook settings of the thread, as three values: +the current hook function, the current hook mask, +and the current hook count +(as set by the debug.sethook function). + + + + +

    +


    debug.getinfo ([thread,] f [, what])

    + + +

    +Returns a table with information about a function. +You can give the function directly +or you can give a number as the value of f, +which means the function running at level f of the call stack +of the given thread: +level 0 is the current function (getinfo itself); +level 1 is the function that called getinfo +(except for tail calls, which do not count on the stack); +and so on. +If f is a number larger than the number of active functions, +then getinfo returns nil. + + +

    +The returned table can contain all the fields returned by lua_getinfo, +with the string what describing which fields to fill in. +The default for what is to get all information available, +except the table of valid lines. +If present, +the option 'f' +adds a field named func with the function itself. +If present, +the option 'L' +adds a field named activelines with the table of +valid lines. + + +

    +For instance, the expression debug.getinfo(1,"n").name returns +a table with a name for the current function, +if a reasonable name can be found, +and the expression debug.getinfo(print) +returns a table with all available information +about the print function. + + + + +

    +


    debug.getlocal ([thread,] f, local)

    + + +

    +This function returns the name and the value of the local variable +with index local of the function at level f of the stack. +This function accesses not only explicit local variables, +but also parameters, temporaries, etc. + + +

    +The first parameter or local variable has index 1, and so on, +until the last active variable. +Negative indices refer to vararg parameters; +-1 is the first vararg parameter. +The function returns nil if there is no variable with the given index, +and raises an error when called with a level out of range. +(You can call debug.getinfo to check whether the level is valid.) + + +

    +Variable names starting with '(' (open parenthesis) +represent internal variables +(loop control variables, temporaries, varargs, and C function locals). + + +

    +The parameter f may also be a function. +In that case, getlocal returns only the name of function parameters. + + + + +

    +


    debug.getmetatable (value)

    + + +

    +Returns the metatable of the given value +or nil if it does not have a metatable. + + + + +

    +


    debug.getregistry ()

    + + +

    +Returns the registry table (see §4.5). + + + + +

    +


    debug.getupvalue (f, up)

    + + +

    +This function returns the name and the value of the upvalue +with index up of the function f. +The function returns nil if there is no upvalue with the given index. + + + + +

    +


    debug.getuservalue (u)

    + + +

    +Returns the Lua value associated to u. +If u is not a userdata, +returns nil. + + + + +

    +


    debug.sethook ([thread,] hook, mask [, count])

    + + +

    +Sets the given function as a hook. +The string mask and the number count describe +when the hook will be called. +The string mask may have the following characters, +with the given meaning: + +

      +
    • 'c': the hook is called every time Lua calls a function;
    • +
    • 'r': the hook is called every time Lua returns from a function;
    • +
    • 'l': the hook is called every time Lua enters a new line of code.
    • +

    +With a count different from zero, +the hook is called after every count instructions. + + +

    +When called without arguments, +debug.sethook turns off the hook. + + +

    +When the hook is called, its first parameter is a string +describing the event that has triggered its call: +"call" (or "tail call"), +"return", +"line", and "count". +For line events, +the hook also gets the new line number as its second parameter. +Inside a hook, +you can call getinfo with level 2 to get more information about +the running function +(level 0 is the getinfo function, +and level 1 is the hook function). + + + + +

    +


    debug.setlocal ([thread,] level, local, value)

    + + +

    +This function assigns the value value to the local variable +with index local of the function at level level of the stack. +The function returns nil if there is no local +variable with the given index, +and raises an error when called with a level out of range. +(You can call getinfo to check whether the level is valid.) +Otherwise, it returns the name of the local variable. + + +

    +See debug.getlocal for more information about +variable indices and names. + + + + +

    +


    debug.setmetatable (value, table)

    + + +

    +Sets the metatable for the given value to the given table +(which can be nil). +Returns value. + + + + +

    +


    debug.setupvalue (f, up, value)

    + + +

    +This function assigns the value value to the upvalue +with index up of the function f. +The function returns nil if there is no upvalue +with the given index. +Otherwise, it returns the name of the upvalue. + + + + +

    +


    debug.setuservalue (udata, value)

    + + +

    +Sets the given value as +the Lua value associated to the given udata. +value must be a table or nil; +udata must be a full userdata. + + +

    +Returns udata. + + + + +

    +


    debug.traceback ([thread,] [message [, level]])

    + + +

    +If message is present but is neither a string nor nil, +this function returns message without further processing. +Otherwise, +it returns a string with a traceback of the call stack. +An optional message string is appended +at the beginning of the traceback. +An optional level number tells at which level +to start the traceback +(default is 1, the function calling traceback). + + + + +

    +


    debug.upvalueid (f, n)

    + + +

    +Returns an unique identifier (as a light userdata) +for the upvalue numbered n +from the given function. + + +

    +These unique identifiers allow a program to check whether different +closures share upvalues. +Lua closures that share an upvalue +(that is, that access a same external local variable) +will return identical ids for those upvalue indices. + + + + +

    +


    debug.upvaluejoin (f1, n1, f2, n2)

    + + +

    +Make the n1-th upvalue of the Lua closure f1 +refer to the n2-th upvalue of the Lua closure f2. + + + + + + + +

    7 – Lua Standalone

    + +

    +Although Lua has been designed as an extension language, +to be embedded in a host C program, +it is also frequently used as a standalone language. +An interpreter for Lua as a standalone language, +called simply lua, +is provided with the standard distribution. +The standalone interpreter includes +all standard libraries, including the debug library. +Its usage is: + +

    +     lua [options] [script [args]]
    +

    +The options are: + +

      +
    • -e stat: executes string stat;
    • +
    • -l mod: "requires" mod;
    • +
    • -i: enters interactive mode after running script;
    • +
    • -v: prints version information;
    • +
    • -E: ignores environment variables;
    • +
    • --: stops handling options;
    • +
    • -: executes stdin as a file and stops handling options.
    • +

    +After handling its options, lua runs the given script, +passing to it the given args as string arguments. +When called without arguments, +lua behaves as lua -v -i +when the standard input (stdin) is a terminal, +and as lua - otherwise. + + +

    +When called without option -E, +the interpreter checks for an environment variable LUA_INIT_5_2 +(or LUA_INIT if it is not defined) +before running any argument. +If the variable content has the format @filename, +then lua executes the file. +Otherwise, lua executes the string itself. + + +

    +When called with option -E, +besides ignoring LUA_INIT, +Lua also ignores +the values of LUA_PATH and LUA_CPATH, +setting the values of +package.path and package.cpath +with the default paths defined in luaconf.h. + + +

    +All options are handled in order, except -i and -E. +For instance, an invocation like + +

    +     $ lua -e'a=1' -e 'print(a)' script.lua
    +

    +will first set a to 1, then print the value of a, +and finally run the file script.lua with no arguments. +(Here $ is the shell prompt. Your prompt may be different.) + + +

    +Before starting to run the script, +lua collects all arguments in the command line +in a global table called arg. +The script name is stored at index 0, +the first argument after the script name goes to index 1, +and so on. +Any arguments before the script name +(that is, the interpreter name plus the options) +go to negative indices. +For instance, in the call + +

    +     $ lua -la b.lua t1 t2
    +

    +the interpreter first runs the file a.lua, +then creates a table + +

    +     arg = { [-2] = "lua", [-1] = "-la",
    +             [0] = "b.lua",
    +             [1] = "t1", [2] = "t2" }
    +

    +and finally runs the file b.lua. +The script is called with arg[1], arg[2], ... +as arguments; +it can also access these arguments with the vararg expression '...'. + + +

    +In interactive mode, +if you write an incomplete statement, +the interpreter waits for its completion +by issuing a different prompt. + + +

    +In case of unprotected errors in the script, +the interpreter reports the error to the standard error stream. +If the error object is a string, +the interpreter adds a stack traceback to it. +Otherwise, if the error object has a metamethod __tostring, +the interpreter calls this metamethod to produce the final message. +Finally, if the error object is nil, +the interpreter does not report the error. + + +

    +When finishing normally, +the interpreter closes its main Lua state +(see lua_close). +The script can avoid this step by +calling os.exit to terminate. + + +

    +To allow the use of Lua as a +script interpreter in Unix systems, +the standalone interpreter skips +the first line of a chunk if it starts with #. +Therefore, Lua scripts can be made into executable programs +by using chmod +x and the #! form, +as in + +

    +     #!/usr/local/bin/lua
    +

    +(Of course, +the location of the Lua interpreter may be different in your machine. +If lua is in your PATH, +then + +

    +     #!/usr/bin/env lua
    +

    +is a more portable solution.) + + + +

    8 – Incompatibilities with the Previous Version

    + +

    +Here we list the incompatibilities that you may find when moving a program +from Lua 5.1 to Lua 5.2. +You can avoid some incompatibilities by compiling Lua with +appropriate options (see file luaconf.h). +However, +all these compatibility options will be removed in the next version of Lua. +Similarly, +all features marked as deprecated in Lua 5.1 +have been removed in Lua 5.2. + + + +

    8.1 – Changes in the Language

    +
      + +
    • +The concept of environment changed. +Only Lua functions have environments. +To set the environment of a Lua function, +use the variable _ENV or the function load. + + +

      +C functions no longer have environments. +Use an upvalue with a shared table if you need to keep +shared state among several C functions. +(You may use luaL_setfuncs to open a C library +with all functions sharing a common upvalue.) + + +

      +To manipulate the "environment" of a userdata +(which is now called user value), +use the new functions +lua_getuservalue and lua_setuservalue. +

    • + +
    • +Lua identifiers cannot use locale-dependent letters. +
    • + +
    • +Doing a step or a full collection in the garbage collector +does not restart the collector if it has been stopped. +
    • + +
    • +Weak tables with weak keys now perform like ephemeron tables. +
    • + +
    • +The event tail return in debug hooks was removed. +Instead, tail calls generate a special new event, +tail call, so that the debugger can know that +there will not be a corresponding return event. +
    • + +
    • +Equality between function values has changed. +Now, a function definition may not create a new value; +it may reuse some previous value if there is no +observable difference to the new function. +
    • + +
    + + + + +

    8.2 – Changes in the Libraries

    +
      + +
    • +Function module is deprecated. +It is easy to set up a module with regular Lua code. +Modules are not expected to set global variables. +
    • + +
    • +Functions setfenv and getfenv were removed, +because of the changes in environments. +
    • + +
    • +Function math.log10 is deprecated. +Use math.log with 10 as its second argument, instead. +
    • + +
    • +Function loadstring is deprecated. +Use load instead; it now accepts string arguments +and are exactly equivalent to loadstring. +
    • + +
    • +Function table.maxn is deprecated. +Write it in Lua if you really need it. +
    • + +
    • +Function os.execute now returns true when command +terminates successfully and nil plus error information +otherwise. +
    • + +
    • +Function unpack was moved into the table library +and therefore must be called as table.unpack. +
    • + +
    • +Character class %z in patterns is deprecated, +as now patterns may contain '\0' as a regular character. +
    • + +
    • +The table package.loaders was renamed package.searchers. +
    • + +
    • +Lua does not have bytecode verification anymore. +So, all functions that load code +(load and loadfile) +are potentially insecure when loading untrusted binary data. +(Actually, those functions were already insecure because +of flaws in the verification algorithm.) +When in doubt, +use the mode argument of those functions +to restrict them to loading textual chunks. +
    • + +
    • +The standard paths in the official distribution may +change between versions. +
    • + +
    + + + + +

    8.3 – Changes in the API

    +
      + +
    • +Pseudoindex LUA_GLOBALSINDEX was removed. +You must get the global environment from the registry +(see §4.5). +
    • + +
    • +Pseudoindex LUA_ENVIRONINDEX +and functions lua_getfenv/lua_setfenv +were removed, +as C functions no longer have environments. +
    • + +
    • +Function luaL_register is deprecated. +Use luaL_setfuncs so that your module does not create globals. +(Modules are not expected to set global variables anymore.) +
    • + +
    • +The osize argument to the allocation function +may not be zero when creating a new block, +that is, when ptr is NULL +(see lua_Alloc). +Use only the test ptr == NULL to check whether +the block is new. +
    • + +
    • +Finalizers (__gc metamethods) for userdata are called in the +reverse order that they were marked for finalization, +not that they were created (see §2.5.1). +(Most userdata are marked immediately after they are created.) +Moreover, +if the metatable does not have a __gc field when set, +the finalizer will not be called, +even if it is set later. +
    • + +
    • +luaL_typerror was removed. +Write your own version if you need it. +
    • + +
    • +Function lua_cpcall is deprecated. +You can simply push the function with lua_pushcfunction +and call it with lua_pcall. +
    • + +
    • +Functions lua_equal and lua_lessthan are deprecated. +Use the new lua_compare with appropriate options instead. +
    • + +
    • +Function lua_objlen was renamed lua_rawlen. +
    • + +
    • +Function lua_load has an extra parameter, mode. +Pass NULL to simulate the old behavior. +
    • + +
    • +Function lua_resume has an extra parameter, from. +Pass NULL or the thread doing the call. +
    • + +
    + + + + +

    9 – The Complete Syntax of Lua

    + +

    +Here is the complete syntax of Lua in extended BNF. +(It does not describe operator precedences.) + + + + +

    +
    +	chunk ::= block
    +
    +	block ::= {stat} [retstat]
    +
    +	stat ::=  ‘;’ | 
    +		 varlist ‘=’ explist | 
    +		 functioncall | 
    +		 label | 
    +		 break | 
    +		 goto Name | 
    +		 do block end | 
    +		 while exp do block end | 
    +		 repeat block until exp | 
    +		 if exp then block {elseif exp then block} [else block] end | 
    +		 for Name ‘=’ exp ‘,’ exp [‘,’ exp] do block end | 
    +		 for namelist in explist do block end | 
    +		 function funcname funcbody | 
    +		 local function Name funcbody | 
    +		 local namelist [‘=’ explist] 
    +
    +	retstat ::= return [explist] [‘;’]
    +
    +	label ::= ‘::’ Name ‘::’
    +
    +	funcname ::= Name {‘.’ Name} [‘:’ Name]
    +
    +	varlist ::= var {‘,’ var}
    +
    +	var ::=  Name | prefixexp ‘[’ exp ‘]’ | prefixexp ‘.’ Name 
    +
    +	namelist ::= Name {‘,’ Name}
    +
    +	explist ::= exp {‘,’ exp}
    +
    +	exp ::=  nil | false | true | Number | String | ‘...’ | functiondef | 
    +		 prefixexp | tableconstructor | exp binop exp | unop exp 
    +
    +	prefixexp ::= var | functioncall | ‘(’ exp ‘)’
    +
    +	functioncall ::=  prefixexp args | prefixexp ‘:’ Name args 
    +
    +	args ::=  ‘(’ [explist] ‘)’ | tableconstructor | String 
    +
    +	functiondef ::= function funcbody
    +
    +	funcbody ::= ‘(’ [parlist] ‘)’ block end
    +
    +	parlist ::= namelist [‘,’ ‘...’] | ‘...’
    +
    +	tableconstructor ::= ‘{’ [fieldlist] ‘}’
    +
    +	fieldlist ::= field {fieldsep field} [fieldsep]
    +
    +	field ::= ‘[’ exp ‘]’ ‘=’ exp | Name ‘=’ exp | exp
    +
    +	fieldsep ::= ‘,’ | ‘;’
    +
    +	binop ::= ‘+’ | ‘-’ | ‘*’ | ‘/’ | ‘^’ | ‘%’ | ‘..’ | 
    +		 ‘<’ | ‘<=’ | ‘>’ | ‘>=’ | ‘==’ | ‘~=’ | 
    +		 and | or
    +
    +	unop ::= ‘-’ | not | ‘#’
    +
    +
    + +

    + + + + + + + +


    + +Last update: +Thu Mar 21 12:58:59 BRT 2013 + + + + + diff --git a/doc/osi-certified-72x60.png b/doc/osi-certified-72x60.png new file mode 100644 index 0000000000000000000000000000000000000000..07df5f6ee7a7a8b2108025dcd815f73f145a83af GIT binary patch literal 3774 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 + + +Lua 5.2 readme + + + + + + + +
    +

    +Lua +Welcome to Lua 5.2 +

    + +

    +about +· +installation +· +changes +· +license +· +reference manual + +

    About Lua

    + +

    +Lua is a powerful, fast, lightweight, embeddable scripting language +developed by a +team +at +PUC-Rio, +the Pontifical Catholic University of Rio de Janeiro in Brazil. +Lua is +free software +used in many products and projects around the world. + +

    +Lua's +official web site +provides complete information +about Lua, +including +an +executive summary +and +updated +documentation, +especially the +reference manual, +which may differ slightly from the +local copy +distributed in this package. + +

    Installing Lua

    + +

    +Lua is distributed in +source +form. +You need to build it before using it. +Building Lua should be straightforward +because +Lua is implemented in pure ANSI C and compiles unmodified in all known +platforms that have an ANSI C compiler. +Lua also compiles unmodified as C++. +The instructions given below for building Lua are for Unix-like platforms. +See also +instructions for other systems +and +customization options. + +

    +If you don't have the time or the inclination to compile Lua yourself, +get a binary from +LuaBinaries. +Try also +Lua for Windows, +an easy-to-use distribution of Lua that includes many useful libraries. + +

    Building Lua

    + +

    +In most Unix-like platforms, simply do "make" with a suitable target. +Here are the details. + +

      +
    1. +Open a terminal window and move to +the top-level directory, which is named lua-5.2.3. +The Makefile there controls both the build process and the installation process. +

      +

    2. + Do "make" and see if your platform is listed. + The platforms currently supported are: +

      +

      + aix ansi bsd freebsd generic linux macosx mingw posix solaris +

      +

      + If your platform is listed, just do "make xxx", where xxx + is your platform name. +

      + If your platform is not listed, try the closest one or posix, generic, + ansi, in this order. +

      +

    3. +The compilation takes only a few moments +and produces three files in the src directory: +lua (the interpreter), +luac (the compiler), +and liblua.a (the library). +

      +

    4. + To check that Lua has been built correctly, do "make test" + after building Lua. This will run the interpreter and print its version string. +
    +

    +If you're running Linux and get compilation errors, +make sure you have installed the readline development package. +If you get link errors after that, +then try "make linux MYLIBS=-ltermcap". + +

    Installing Lua

    +

    + Once you have built Lua, you may want to install it in an official + place in your system. In this case, do "make install". The official + place and the way to install files are defined in the Makefile. You'll + probably need the right permissions to install files. + +

    + To build and install Lua in one step, do "make xxx install", + where xxx is your platform name. + +

    + To install Lua locally, do "make local". + This will create a directory install with subdirectories + bin, include, lib, man, + and install Lua as listed below. + + To install Lua locally, but in some other directory, do + "make install INSTALL_TOP=xxx", where xxx is your chosen directory. + +

    +
    + bin: +
    + lua luac +
    + include: +
    + lua.h luaconf.h lualib.h lauxlib.h lua.hpp +
    + lib: +
    + liblua.a +
    + man/man1: +
    + lua.1 luac.1 +
    + +

    + These are the only directories you need for development. + If you only want to run Lua programs, + you only need the files in bin and man. + The files in include and lib are needed for + embedding Lua in C or C++ programs. + +

    Customization

    +

    + Three kinds of things can be customized by editing a file: +

      +
    • Where and how to install Lua — edit Makefile. +
    • How to build Lua — edit src/Makefile. +
    • Lua features — edit src/luaconf.h. +
    + +

    + You don't actually need to edit the Makefiles because you may set the + relevant variables in the command line when invoking make. + Nevertheless, it's probably best to edit and save the Makefiles to + record the changes you need. + +

    + On the other hand, if you need to customize some Lua features, you'll need + to edit src/luaconf.h before building and installing Lua. + The edited file will be the one installed, and + it will be used by any Lua clients that you build, to ensure consistency. + Further customization is available to experts by editing the Lua sources. + +

    + We strongly recommend that you enable dynamic loading in src/luaconf.h. + This is done automatically for all platforms listed above that have + this feature and also for Windows. + +

    Building Lua on other systems

    + +

    + If you're not using the usual Unix tools, then the instructions for + building Lua depend on the compiler you use. You'll need to create + projects (or whatever your compiler uses) for building the library, + the interpreter, and the compiler, as follows: + +

    +
    +library: +
    +lapi.c lcode.c lctype.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c +lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c ltable.c +ltm.c lundump.c lvm.c lzio.c +lauxlib.c lbaselib.c lbitlib.c lcorolib.c ldblib.c liolib.c +lmathlib.c loslib.c lstrlib.c ltablib.c loadlib.c linit.c +
    +interpreter: +
    + library, lua.c +
    +compiler: +
    + library, luac.c +
    + +

    + To use Lua as a library in your own programs you'll need to know how to + create and use libraries with your compiler. Moreover, to dynamically load + C libraries for Lua you'll need to know how to create dynamic libraries + and you'll need to make sure that the Lua API functions are accessible to + those dynamic libraries — but don't link the Lua library + into each dynamic library. For Unix, we recommend that the Lua library + be linked statically into the host program and its symbols exported for + dynamic linking; src/Makefile does this for the Lua interpreter. + For Windows, we recommend that the Lua library be a DLL. + +

    + As mentioned above, you may edit src/luaconf.h to customize + some features before building Lua. + +

    Changes since Lua 5.1

    + +

    +Here are the main changes introduced in Lua 5.2. +The +reference manual +lists the +incompatibilities that had to be introduced. + +

    Main changes

    +
      +
    • yieldable pcall and metamethods +
    • new lexical scheme for globals +
    • ephemeron tables +
    • new library for bitwise operations +
    • light C functions +
    • emergency garbage collector +
    • goto statement +
    • finalizers for tables +
    + +Here are the other changes introduced in Lua 5.2: +

    Language

    +
      +
    • no more fenv for threads or functions +
    • tables honor the __len metamethod +
    • hex and \z escapes in strings +
    • support for hexadecimal floats +
    • order metamethods work for different types +
    • no more verification of opcode consistency +
    • hook event "tail return" replaced by "tail call" +
    • empty statement +
    • break statement may appear in the middle of a block +
    + +

    Libraries

    +
      +
    • arguments for function called through xpcall +
    • optional 'mode' argument to load and loadfile (to control binary x text) +
    • optional 'env' argument to load and loadfile (environment for loaded chunk) +
    • loadlib may load libraries with global names (RTLD_GLOBAL) +
    • new function package.searchpath +
    • modules receive their paths when loaded +
    • optional base in math.log +
    • optional separator in string.rep +
    • file:write returns file +
    • closing a pipe returns exit status +
    • os.exit may close state +
    • new metamethods __pairs and __ipairs +
    • new option 'isrunning' for collectgarbage and lua_gc +
    • frontier patterns +
    • \0 in patterns +
    • new option *L for io.read +
    • options for io.lines +
    • debug.getlocal can access function varargs +
    + +

    C API

    +
      +
    • main thread predefined in the registry +
    • new functions +lua_absindex, +lua_arith, +lua_compare, +lua_copy, +lua_len, +lua_rawgetp, +lua_rawsetp, +lua_upvalueid, +lua_upvaluejoin, +lua_version. +
    • new functions +luaL_checkversion, +luaL_setmetatable, +luaL_testudata, +luaL_tolstring. +
    • lua_pushstring and pushlstring return string +
    • nparams and isvararg available in debug API +
    • new lua_Unsigned +
    + +

    Implementation

    +
      +
    • max constants per function raised to 226 +
    • generational mode for garbage collection (experimental) +
    • NaN trick (experimental) +
    • internal (immutable) version of ctypes +
    • simpler implementation for string buffers +
    • parser uses much less C-stack space (no more auto arrays) +
    + +

    Lua standalone interpreter

    +
      +
    • new -E option to avoid environment variables +
    • handling of non-string error messages +
    + +

    License

    + +[osi certified] + + +

    +Lua is free software distributed under the terms of the +MIT license +reproduced below; +it may be used for any purpose, including commercial purposes, +at absolutely no cost without having to ask us. + +The only requirement is that if you do use Lua, +then you should give us credit by including the appropriate copyright notice somewhere in your product or its documentation. + +For details, see +this. + +

    +Copyright © 1994–2013 Lua.org, PUC-Rio. + +

    +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +

    +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +

    +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +

    +

    + +


    + +Last update: +Sat Nov 9 22:39:16 BRST 2013 + + + + + From d16462784b52cdbe26f89d7787ef821231ee6a5a Mon Sep 17 00:00:00 2001 From: Scott M Anderson Date: Mon, 17 Nov 2025 17:18:25 -0700 Subject: [PATCH 06/14] copy README dist.info from LuaDist repo (externpro-archive/lua) https://github.com/externpro-archive/lua/tree/5bbd21fbb20ffcea435ae45593f4e7dfac03e0f4 --- README.md | 6 ++++++ dist.info | 15 +++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 README.md create mode 100644 dist.info diff --git a/README.md b/README.md new file mode 100644 index 0000000000..49033adb5b --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ + +This is Lua 5.2.3, released on 11 Nov 2013. + +For installation instructions, license details, and +further information about Lua, see doc/readme.html. + diff --git a/dist.info b/dist.info new file mode 100644 index 0000000000..5614ecad18 --- /dev/null +++ b/dist.info @@ -0,0 +1,15 @@ +--- This file is part of LuaDist project + +name = "lua" +version = "5.2.3" + +desc = "Lua is a powerful, fast, light-weight, embeddable scripting language." +author = "Roberto Ierusalimschy, Waldemar Celes, Luiz Henrique de Figueiredo" +license = "MIT/X11" +url = "http://www.lua.org" +maintainer = "Peter Drahoš" + +-- Offers functionality of the following packages +provides = { + "bit32-5.2.0" +} From f715e1866009d47ca6621dfdec1b150264f511c4 Mon Sep 17 00:00:00 2001 From: Scott M Anderson Date: Mon, 17 Nov 2025 16:09:13 -0700 Subject: [PATCH 07/14] git submodule add https://github.com/externpro/externpro .devcontainer --- .devcontainer | 1 + .gitmodules | 3 +++ 2 files changed, 4 insertions(+) create mode 160000 .devcontainer create mode 100644 .gitmodules diff --git a/.devcontainer b/.devcontainer new file mode 160000 index 0000000000..9d4fcf4bfc --- /dev/null +++ b/.devcontainer @@ -0,0 +1 @@ +Subproject commit 9d4fcf4bfc12d259ebaea9e2f2bb682661cc31bc diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..18932abfb9 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule ".devcontainer"] + path = .devcontainer + url = https://github.com/externpro/externpro From edd3dfc55a40c861404df2f9103708756483cd16 Mon Sep 17 00:00:00 2001 From: Scott M Anderson Date: Mon, 17 Nov 2025 16:10:47 -0700 Subject: [PATCH 08/14] docker-compose links --- docker-compose.sh | 1 + docker-compose.yml | 1 + 2 files changed, 2 insertions(+) create mode 120000 docker-compose.sh create mode 120000 docker-compose.yml diff --git a/docker-compose.sh b/docker-compose.sh new file mode 120000 index 0000000000..85f182f0be --- /dev/null +++ b/docker-compose.sh @@ -0,0 +1 @@ +.devcontainer/compose.pro.sh \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 120000 index 0000000000..46c1f8918f --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1 @@ +.devcontainer/compose.bld.yml \ No newline at end of file From 81fd039f8407a1fe0b0f80832627d4ae18f8628d Mon Sep 17 00:00:00 2001 From: Scott M Anderson Date: Mon, 17 Nov 2025 16:11:08 -0700 Subject: [PATCH 09/14] add CMakePresets cp .devcontainer/cmake/presets/CMakePresets* . --- CMakePresets.json | 8 ++++++++ CMakePresetsBase.json | 16 ++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 CMakePresets.json create mode 100644 CMakePresetsBase.json diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 0000000000..f82cfdd2cf --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,8 @@ +{ + "version": 8, + "include": [ + ".devcontainer/cmake/presets/xpLinuxNinja.json", + ".devcontainer/cmake/presets/xpDarwinNinja.json", + ".devcontainer/cmake/presets/xpWindowsVs2022.json" + ] +} diff --git a/CMakePresetsBase.json b/CMakePresetsBase.json new file mode 100644 index 0000000000..085cdc3e31 --- /dev/null +++ b/CMakePresetsBase.json @@ -0,0 +1,16 @@ +{ + "version": 8, + "configurePresets": [ + { + "name": "config-base", + "hidden": true, + "binaryDir": "${sourceDir}/_bld-${presetName}" + } + ], + "buildPresets": [ + { + "name": "build-base", + "hidden": true + } + ] +} From f48b30e1413754435670d1dfd3cf5e11c5fa9445 Mon Sep 17 00:00:00 2001 From: Scott M Anderson Date: Mon, 17 Nov 2025 16:11:59 -0700 Subject: [PATCH 10/14] gitignore: externpro ignores --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..1fc17fa3f7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.env +_bld*/ +docker-compose.override.yml From 5261b86acd3cb66a20db844729eaccb602793f8e Mon Sep 17 00:00:00 2001 From: Scott M Anderson Date: Mon, 17 Nov 2025 16:27:30 -0700 Subject: [PATCH 11/14] externpro github/workflows @25.06 cp .devcontainer/.github/wf-templates/xp*.yml .github/workflows --- .github/workflows/xpbuild.yml | 30 ++++++++++++++++++++++++++++++ .github/workflows/xprelease.yml | 20 ++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 .github/workflows/xpbuild.yml create mode 100644 .github/workflows/xprelease.yml diff --git a/.github/workflows/xpbuild.yml b/.github/workflows/xpbuild.yml new file mode 100644 index 0000000000..169ff5269c --- /dev/null +++ b/.github/workflows/xpbuild.yml @@ -0,0 +1,30 @@ +name: Build +on: + push: + branches: [ "dev" ] + pull_request: + branches: [ "dev" ] + workflow_dispatch: +jobs: + linux: + uses: externpro/externpro/.github/workflows/build-linux.yml@25.06 + with: + cmake-workflow-preset: Linux + runon: ubuntu-latest + secrets: inherit + linux-arm64: + uses: externpro/externpro/.github/workflows/build-linux.yml@25.06 + with: + cmake-workflow-preset: Linux + runon: ubuntu-24.04-arm + secrets: inherit + macos: + uses: externpro/externpro/.github/workflows/build-macos.yml@25.06 + with: + cmake-workflow-preset: Darwin + secrets: inherit + windows: + uses: externpro/externpro/.github/workflows/build-windows.yml@25.06 + with: + cmake-workflow-preset: Windows + secrets: inherit diff --git a/.github/workflows/xprelease.yml b/.github/workflows/xprelease.yml new file mode 100644 index 0000000000..146191466e --- /dev/null +++ b/.github/workflows/xprelease.yml @@ -0,0 +1,20 @@ +name: Release +on: + workflow_dispatch: + inputs: + workflow_run_url: + description: 'URL of the workflow run containing artifacts to upload (e.g., https://github.com/owner/repo/actions/runs/123456789)' + required: true + type: string +jobs: + # Upload build artifacts as release assets + release-from-build: + uses: externpro/externpro/.github/workflows/release-from-build.yml@25.06 + with: + workflow_run_url: ${{ github.event.inputs.workflow_run_url }} + artifact_pattern: "*.tar.xz" + permissions: + contents: write + id-token: write + attestations: write + secrets: inherit From 0b5eae6130192303d1bb9c685b6bc42f53c902cb Mon Sep 17 00:00:00 2001 From: Scott M Anderson Date: Mon, 17 Nov 2025 21:50:38 -0700 Subject: [PATCH 12/14] CMakePresetsBase: add cacheVariables --- CMakePresetsBase.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CMakePresetsBase.json b/CMakePresetsBase.json index 085cdc3e31..4c565871fb 100644 --- a/CMakePresetsBase.json +++ b/CMakePresetsBase.json @@ -4,7 +4,13 @@ { "name": "config-base", "hidden": true, - "binaryDir": "${sourceDir}/_bld-${presetName}" + "binaryDir": "${sourceDir}/_bld-${presetName}", + "cacheVariables": { + "BUILD_SHARED_LIBS": "OFF", + "LUA_USE_READLINE": "OFF", + "LUA_USE_CURSES": "OFF", + "XP_NAMESPACE": "xpro" + } } ], "buildPresets": [ From 33227b8b12059a1758e240ef351fde0ae89e978b Mon Sep 17 00:00:00 2001 From: Scott M Anderson Date: Mon, 17 Nov 2025 21:50:48 -0700 Subject: [PATCH 13/14] externpro dependency provider --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5dd6dbe355..c675c3923e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,7 @@ # Please note that the package source code is licensed under its own license. cmake_minimum_required ( VERSION 2.8...3.31 ) +set(CMAKE_PROJECT_TOP_LEVEL_INCLUDES .devcontainer/cmake/xproinc.cmake) project ( lua C ) include(GNUInstallDirs) include(xpflags) From 2b199216a1c788350fd9c8319d5ceeec4d9e9f1d Mon Sep 17 00:00:00 2001 From: Scott M Anderson Date: Mon, 17 Nov 2025 21:52:08 -0700 Subject: [PATCH 14/14] externpro devel package --- CMakeLists.txt | 27 ++++++++++++++++++++++++++- cmake/dist.cmake | 40 ++++++++++++++++++---------------------- 2 files changed, 44 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c675c3923e..5f192b8c94 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -147,6 +147,32 @@ target_link_libraries ( lua liblua ) add_executable ( luac ${SRC_CORE} ${SRC_LIB} ${SRC_LUAC} src/luac.rc ) target_link_libraries ( luac ${LIBS} ) +set(targetsFile ${PROJECT_NAME}-targets) +if(NOT DEFINED XP_INSTALL_CMAKEDIR) + set(XP_INSTALL_CMAKEDIR ${CMAKE_INSTALL_DATADIR}/cmake) +endif() +if(DEFINED XP_NAMESPACE) + set(nameSpace NAMESPACE ${XP_NAMESPACE}::) + xpPackageDevel(TARGETS_FILE ${targetsFile} EXE ${XP_NAMESPACE}::lua LIBRARIES ${XP_NAMESPACE}::liblua) + set(LUA_COMPONENT_RT devel) + set(LUA_COMPONENT_LIB devel) + set(LUA_COMPONENT_HDR devel) + set(LUA_COMPONENT_DATA devel) + set(LUA_COMPONENT_DOC devel) + set(LUA_COMPONENT_EX devel) + set(LUA_COMPONENT_TEST devel) + set(LUA_COMPONENT_OTH devel) +else() + set(LUA_COMPONENT_RT Runtime) + set(LUA_COMPONENT_LIB Library) + set(LUA_COMPONENT_HDR Header) + set(LUA_COMPONENT_DATA Data) + set(LUA_COMPONENT_DOC Documentation) + set(LUA_COMPONENT_EX Example) + set(LUA_COMPONENT_TEST Test) + set(LUA_COMPONENT_OTH Other) +endif() + # On windows a variant of the lua interpreter without console output needs to be built if ( LUA_BUILD_WLUA ) add_executable ( wlua WIN32 src/wmain.c ${SRC_LUA} src/lua.rc ) @@ -154,7 +180,6 @@ if ( LUA_BUILD_WLUA ) install_executable ( wlua ) endif ( ) -set(targetsFile ${PROJECT_NAME}-targets) install_executable ( lua luac ) install_library ( liblua ) install_data ( README.md ) diff --git a/cmake/dist.cmake b/cmake/dist.cmake index 4b1b77619b..12da7087f8 100644 --- a/cmake/dist.cmake +++ b/cmake/dist.cmake @@ -142,7 +142,7 @@ macro ( install_executable ) SOVERSION ${DIST_VERSION} ) endif () install ( TARGETS ${_file} EXPORT ${targetsFile} RUNTIME DESTINATION ${INSTALL_BIN} - COMPONENT Runtime CONFIGURATIONS Release ) + COMPONENT ${LUA_COMPONENT_RT} CONFIGURATIONS Release ) endforeach() endmacro () @@ -160,16 +160,10 @@ macro ( install_library ) SOVERSION ${DIST_VERSION} ) endif () install ( TARGETS ${_file} EXPORT ${targetsFile} - RUNTIME DESTINATION ${INSTALL_BIN} COMPONENT Runtime - LIBRARY DESTINATION ${INSTALL_LIB} COMPONENT Runtime - ARCHIVE DESTINATION ${INSTALL_LIB} COMPONENT Library ) + RUNTIME DESTINATION ${INSTALL_BIN} COMPONENT ${LUA_COMPONENT_RT} + LIBRARY DESTINATION ${INSTALL_LIB} COMPONENT ${LUA_COMPONENT_RT} + ARCHIVE DESTINATION ${INSTALL_LIB} COMPONENT ${LUA_COMPONENT_LIB} ) endforeach() - if(DEFINED XP_NAMESPACE) - set(nameSpace NAMESPACE ${XP_NAMESPACE}::) - endif() - if(NOT DEFINED XP_INSTALL_CMAKEDIR) - set(XP_INSTALL_CMAKEDIR ${INSTALL_SHARE}/cmake) - endif() install(EXPORT ${targetsFile} DESTINATION ${XP_INSTALL_CMAKEDIR} ${nameSpace}) endmacro () @@ -197,10 +191,10 @@ macro ( install_header ) foreach ( _file ${_ARG_DEFAULT_ARGS} ) if ( IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${_file}" ) install ( DIRECTORY ${_file} DESTINATION ${INSTALL_INC}/${_ARG_INTO} - COMPONENT Header ${_ARG_PATTERN} ${_ARG_REGEX} ) + COMPONENT ${LUA_COMPONENT_HDR} ${_ARG_PATTERN} ${_ARG_REGEX} ) else () install ( FILES ${_file} DESTINATION ${INSTALL_INC}/${_ARG_INTO} - COMPONENT Header ) + COMPONENT ${LUA_COMPONENT_HDR} ) endif () endforeach() endmacro () @@ -220,10 +214,10 @@ macro ( install_data ) if ( IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${_file}" ) install ( DIRECTORY ${_file} DESTINATION ${INSTALL_DATA}/${_ARG_INTO} - COMPONENT Data ${_ARG_PATTERN} ${_ARG_REGEX} ) + COMPONENT ${LUA_COMPONENT_DATA} ${_ARG_PATTERN} ${_ARG_REGEX} ) else () install ( FILES ${_file} DESTINATION ${INSTALL_DATA}/${_ARG_INTO} - COMPONENT Data ) + COMPONENT ${LUA_COMPONENT_DATA} ) endif () endforeach() endmacro () @@ -242,10 +236,10 @@ macro ( install_doc ) foreach ( _file ${_ARG_DEFAULT_ARGS} ) if ( IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${_file}" ) install ( DIRECTORY ${_file} DESTINATION ${INSTALL_DOC}/${_ARG_INTO} - COMPONENT Documentation ${_ARG_PATTERN} ${_ARG_REGEX} ) + COMPONENT ${LUA_COMPONENT_DOC} ${_ARG_PATTERN} ${_ARG_REGEX} ) else () install ( FILES ${_file} DESTINATION ${INSTALL_DOC}/${_ARG_INTO} - COMPONENT Documentation ) + COMPONENT ${LUA_COMPONENT_DOC} ) endif () endforeach() endmacro () @@ -264,10 +258,10 @@ macro ( install_example ) foreach ( _file ${_ARG_DEFAULT_ARGS} ) if ( IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${_file}" ) install ( DIRECTORY ${_file} DESTINATION ${INSTALL_EXAMPLE}/${_ARG_INTO} - COMPONENT Example ${_ARG_PATTERN} ${_ARG_REGEX} ) + COMPONENT ${LUA_COMPONENT_EX} ${_ARG_PATTERN} ${_ARG_REGEX} ) else () install ( FILES ${_file} DESTINATION ${INSTALL_EXAMPLE}/${_ARG_INTO} - COMPONENT Example ) + COMPONENT ${LUA_COMPONENT_EX} ) endif () endforeach() endmacro () @@ -286,10 +280,10 @@ macro ( install_test ) foreach ( _file ${_ARG_DEFAULT_ARGS} ) if ( IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${_file}" ) install ( DIRECTORY ${_file} DESTINATION ${INSTALL_TEST}/${_ARG_INTO} - COMPONENT Test ${_ARG_PATTERN} ${_ARG_REGEX} ) + COMPONENT ${LUA_COMPONENT_TEST} ${_ARG_PATTERN} ${_ARG_REGEX} ) else () install ( FILES ${_file} DESTINATION ${INSTALL_TEST}/${_ARG_INTO} - COMPONENT Test ) + COMPONENT ${LUA_COMPONENT_TEST} ) endif () endforeach() endmacro () @@ -308,16 +302,17 @@ macro ( install_foo ) foreach ( _file ${_ARG_DEFAULT_ARGS} ) if ( IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${_file}" ) install ( DIRECTORY ${_file} DESTINATION ${INSTALL_FOO}/${_ARG_INTO} - COMPONENT Other ${_ARG_PATTERN} ${_ARG_REGEX} ) + COMPONENT ${LUA_COMPONENT_OTH} ${_ARG_PATTERN} ${_ARG_REGEX} ) else () install ( FILES ${_file} DESTINATION ${INSTALL_FOO}/${_ARG_INTO} - COMPONENT Other ) + COMPONENT ${LUA_COMPONENT_OTH} ) endif () endforeach() endmacro () ## CTest defaults +if(NOT DEFINED XP_NAMESPACE) ## CPack defaults set ( CPACK_GENERATOR "ZIP" ) set ( CPACK_STRIP_FILES TRUE ) @@ -326,3 +321,4 @@ set ( CPACK_PACKAGE_VERSION "${DIST_VERSION}") set ( CPACK_PACKAGE_VENDOR "LuaDist" ) set ( CPACK_COMPONENTS_ALL Runtime Library Header Data Documentation Example Other ) include ( CPack ) +endif()