diff --git a/AUTHORS b/AUTHORS deleted file mode 100644 index 53c3ab914bb1fbd32713aad149bd431a0b159310..0000000000000000000000000000000000000000 --- a/AUTHORS +++ /dev/null @@ -1,3 +0,0 @@ -Claude Heiland-Allen -Frank Barknecht -Martin Peach diff --git a/CHANGES b/CHANGES deleted file mode 100644 index d5fa05570784c4df28458c7d00b55a9b4453f95e..0000000000000000000000000000000000000000 --- a/CHANGES +++ /dev/null @@ -1,41 +0,0 @@ -0.6 20110314 - Martin Peach changed names of externals to pdlua and pdluax and added the source to svn trunk/pd/externals/pdlua -0.6~svn 2009-09-14 - Building: autoconf system uses -fPIC for amd64 compatibility - -0.5 2008-06-18 - Building: Makefile.static (recommended) - Building: autoconfiscated (for advanced users) - Feature: interaction with [value], see [revalue] and [lexpr] - Feature: interaction with [table], see [ltabdump] and [ltabfill] - Feature: require() looks relative to .pd_lua and .pd_luax files - Internal: support pd >= 0.41 and pd < 0.41 (pd table API change) - -0.4 2008-03-26 - API change: "load $1"--[lua] users must add the file name extension - Bug fix: "load $1"--[lua] works as advertised - API change: users must name files "*.pd_lua" instead of "*.lua" - API change: users must name files "*.pd_luax" instead of "*.luax" - Bug fix: help patches should be found correctly - Examples++: [lurn], [luametro], [lpipe] - Internal: Doxygenated source comments - Internal: fewer leading underscores - Internal: renamed all examples for API change and tested them - -0.3 2007-12-02 - clock support - receive support - send support - support static builds - -0.2 2007-09-25 - renumbered inlets/outlets: now follow Lua 1,2,... conventions - fixed all examples for new numbering - more and updated documentation - opening via Pd's canvas path with obj:dofile(filename) - better error reporting - lexpr example - bugfix in dispatch (in_3_foo doesn't pass "foo" as an arg any more) - -0.1 2007-09-24 - initial release diff --git a/src/Makefile b/Makefile similarity index 51% rename from src/Makefile rename to Makefile index 0eeb3870f4935dfe66192f64aa2a7e7468532521..395b691fa23b73da5b86f394b1b3e10c104e665b 100644 --- a/src/Makefile +++ b/Makefile @@ -1,5 +1,6 @@ -## from Pd library template version 1.0.9 -# http://puredata.info/docs/developer/Makefilepdlua +## Pd library template version 1.0.14 +# For instructions on how to use this template, see: +# http://puredata.info/docs/developer/MakefileTemplate LIBRARY_NAME = pdlua # add your .c source files, one object per file, to the SOURCES @@ -7,25 +8,33 @@ LIBRARY_NAME = pdlua # objects, the matching .tcl file too SOURCES = pdlua.c +## the source directory: either 'src/' (if it exists) or '.' +PDLUA_SRCPATH=$(firstword $(patsubst src/%,src,$(wildcard src/*)) .) + # list all pd objects (i.e. myobject.pd) files here, and their helpfiles will # be included automatically -PDOBJECTS = pd.lua hello.lua hello.pd_lua hello.pd_luax +PDOBJECTS = $(PDLUA_SRCPATH)/pd.lua $(PDLUA_SRCPATH)/hello.lua $(PDLUA_SRCPATH)/hello.pd_lua $(PDLUA_SRCPATH)/hello.pd_luax # example patches and related files, in the 'examples' subfolder -EXAMPLES = examples/* +EXAMPLES = $(patsubst examples/%,%,$(wildcard examples/*)) # manuals and related files, in the 'manual' subfolder -MANUAL = doc/* +MANUAL = $(patsubst doc/%,%,$(wildcard doc/*)) + # if you want to include any other files in the source and binary tarballs, # list them here. This can be anything from header files, test patches, # documentation, etc. README.txt and LICENSE.txt are required and therefore # automatically included -EXTRA_DIST = nothing - - +EXTRA_DIST = +# unit tests and related files here, in the 'unittests' subfolder +UNITTESTS = +VPATH=$(PDLUA_SRCPATH) +HELPPATCHES= $(PDLUA_SRCPATH)/pdlua-help.pd \ + $(PDLUA_SRCPATH)/pdluax-help.pd \ + $(PDLUA_SRCPATH)/hello-help.pd #------------------------------------------------------------------------------# # @@ -33,14 +42,13 @@ EXTRA_DIST = nothing # #------------------------------------------------------------------------------# -# -I"$(PD_INCLUDE)/pd" supports the header location for 0.43 -# Lua setup -#CFLAGS += -ansi -pedantic -O2 -fPIC -I/usr/include/lua5.1 -I"$(PD_INCLUDE)/pd" -Wall -W -g -LDFLAGS = -#LUACFLAGS = -DPD -DVERSION='"$(LIBRARY_VERSION)"' -#LUACFLAGS += -fPIC -I"/usr/include/lua5.1" -I"$(PD_INCLUDE)/pd" -g -LUACFLAGS = -DVERSION='"$(LIBRARY_VERSION)"' -#LUACFLAGS += -DPD -fPIC -I"/usr/include/lua5.1" -I"$(PD_INCLUDE)/pd" -g +LIBRARY_META=$(PDLUA_SRCPATH)/$(LIBRARY_NAME)-meta.pd + +ALL_CFLAGS = -I"$(PD_INCLUDE)" +ALL_LDFLAGS = +SHARED_LDFLAGS = +ALL_LIBS = + #------------------------------------------------------------------------------# # @@ -48,11 +56,20 @@ LUACFLAGS = -DVERSION='"$(LIBRARY_VERSION)"' # #------------------------------------------------------------------------------# +# these can be set from outside without (usually) breaking the build +CFLAGS = -Wall -W -g +LDFLAGS = +LIBS = + +LUA_CFLAGS = -I/usr/include/lua +LUA_LIBS = -llua + # get library version from meta file -LIBRARY_VERSION = $(shell sed -n 's|^\#X text [0-9][0-9]* [0-9][0-9]* VERSION \(.*\);|\1|p' $(LIBRARY_NAME)-meta.pd) +LIBRARY_VERSION = $(shell sed -n 's|^\#X text [0-9][0-9]* [0-9][0-9]* VERSION \(.*\);|\1|p' $(LIBRARY_META)) +ALL_CFLAGS += -DPD -DVERSION='"$(LIBRARY_VERSION)"' -PD_INCLUDE = $(PD_PATH)/include +PD_INCLUDE = $(PD_PATH)/include/pd # where to install the library, overridden below depending on platform prefix = /usr/local libdir = $(prefix)/lib @@ -64,9 +81,9 @@ INSTALL_PROGRAM = $(INSTALL) -p -m 644 INSTALL_DATA = $(INSTALL) -p -m 644 INSTALL_DIR = $(INSTALL) -p -m 755 -d -ALLSOURCES := $(SOURCES) $(SOURCES_android) $(SOURCES_cygwin) $(SOURCES_macosx) \ +ALLSOURCES_ := $(SOURCES) $(SOURCES_android) $(SOURCES_cygwin) $(SOURCES_macosx) \ $(SOURCES_iphoneos) $(SOURCES_linux) $(SOURCES_windows) - +ALLSOURCES=$(ALLSOURCES_:%=$(PDLUA_SRCPATH)/%) DISTDIR=$(LIBRARY_NAME)-$(LIBRARY_VERSION) ORIGDIR=pd-$(LIBRARY_NAME:~=)_$(LIBRARY_VERSION) @@ -76,6 +93,7 @@ ifeq ($(UNAME),Darwin) ifeq ($(CPU),arm) # iPhone/iPod Touch SOURCES += $(SOURCES_iphoneos) EXTENSION = pd_darwin + SHARED_EXTENSION = dylib OS = iphoneos PD_PATH = /Applications/Pd-extended.app/Contents/Resources IPHONE_BASE=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin @@ -85,16 +103,16 @@ ifeq ($(UNAME),Darwin) ISYSROOT = -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk IPHONE_CFLAGS = -miphoneos-version-min=3.0 $(ISYSROOT) -arch armv6 OPT_CFLAGS = -fast -funroll-loops -fomit-frame-pointer - CFLAGS := $(IPHONE_CFLAGS) $(OPT_CFLAGS) $(CFLAGS) - LDFLAGS += -arch armv6 -bundle -undefined dynamic_lookup $(ISYSROOT) - LUACFLAGS += -I/usr/include/lua # lua is named differently on every platform, check this and change it to fit - LIBS += -llua # lua is named differently on every platform, check this and change it to fit - LIBS += -lc + ALL_CFLAGS := $(IPHONE_CFLAGS) $(ALL_CFLAGS) + ALL_LDFLAGS += -arch armv6 -bundle -undefined dynamic_lookup $(ISYSROOT) + SHARED_LDFLAGS += -arch armv6 -dynamiclib -undefined dynamic_lookup $(ISYSROOT) + ALL_LIBS += -lc $(LIBS_iphoneos) STRIP = strip -x DISTBINDIR=$(DISTDIR)-$(OS) else # Mac OS X SOURCES += $(SOURCES_macosx) EXTENSION = pd_darwin + SHARED_EXTENSION = dylib OS = macosx PD_PATH = /Applications/Pd-extended.app/Contents/Resources OPT_CFLAGS = -ftree-vectorize -ftree-vectorizer-verbose=2 -fast @@ -102,16 +120,22 @@ ifeq ($(UNAME),Darwin) ifeq ($(shell uname -r | sed 's|\([0-9][0-9]*\)\.[0-9][0-9]*\.[0-9][0-9]*|\1|'), 8) FAT_FLAGS = -arch ppc -arch i386 -mmacosx-version-min=10.4 else - FAT_FLAGS = -arch ppc -arch i386 -arch x86_64 -mmacosx-version-min=10.4 SOURCES += $(SOURCES_iphoneos) +# Starting with Xcode 4.0, the PowerPC compiler is not installed by default + ifeq ($(wildcard /usr/llvm-gcc-4.2/libexec/gcc/powerpc*), ) + FAT_FLAGS = -arch i386 -arch x86_64 -mmacosx-version-min=10.5 + else + FAT_FLAGS = -arch ppc -arch i386 -arch x86_64 -mmacosx-version-min=10.4 + endif endif - CFLAGS += $(FAT_FLAGS) -fPIC -I/sw/include - LDFLAGS += $(FAT_FLAGS) -bundle -undefined dynamic_lookup -L/sw/lib + ALL_CFLAGS += $(FAT_FLAGS) -fPIC -I/sw/include # if the 'pd' binary exists, check the linking against it to aid with stripping - LDFLAGS += $(shell test -e $(PD_PATH)/bin/pd && echo -bundle_loader $(PD_PATH)/bin/pd) - LUACFLAGS += -I/usr/include/lua # lua is named differently on every platform, check this and change it to fit - LIBS += -llua # lua is named differently on every platform, check this and change it to fit - LIBS += -lc + BUNDLE_LOADER = $(shell test ! -e $(PD_PATH)/bin/pd || echo -bundle_loader $(PD_PATH)/bin/pd) + ALL_LDFLAGS += $(FAT_FLAGS) -headerpad_max_install_names -bundle $(BUNDLE_LOADER) \ + -undefined dynamic_lookup -L/sw/lib + SHARED_LDFLAGS += $(FAT_FLAGS) -dynamiclib -undefined dynamic_lookup \ + -install_name @loader_path/$(SHARED_LIB) -compatibility_version 1 -current_version 1.0 + ALL_LIBS += -lc $(LIBS_macosx) STRIP = strip -x DISTBINDIR=$(DISTDIR)-$(OS) # install into ~/Library/Pd on Mac OS X since /usr/local isn't used much @@ -123,22 +147,32 @@ endif ifeq ($(UNAME),ANDROID) CPU := arm SOURCES += $(SOURCES_android) - EXTENSION = pd_linux + EXTENSION = so + SHARED_EXTENSION = so OS = android PD_PATH = /usr - NDK_BASE := /usr/local/android-ndk - NDK_PLATFORM_VERSION := 5 - NDK_SYSROOT=$(NDK_BASE)/platforms/android-$(NDK_PLATFORM_VERSION)/arch-arm - NDK_UNAME := $(shell uname -s | tr '[A-Z]' '[a-z]') - NDK_TOOLCHAIN_BASE=$(NDK_BASE)/toolchains/arm-linux-androideabi-4.4.3/prebuilt/$(NDK_UNAME)-x86 - CC := $(NDK_TOOLCHAIN_BASE)/bin/arm-linux-androideabi-gcc --sysroot=$(NDK_SYSROOT) + NDK_BASE := /opt/android-ndk + NDK_PLATFORM_LEVEL ?= 5 + NDK_ABI=arm + NDK_COMPILER_VERSION = 4.6 + NDK_SYSROOT=$(NDK_BASE)/platforms/android-$(NDK_PLATFORM_LEVEL)/arch-$(NDK_ABI) + NDK_UNAME:=$(shell uname -s | tr '[A-Z]' '[a-z]') + ifeq ($(NDK_ABI),x86) + HOST = i686-linux-android + NDK_TOOLCHAIN = $(NDK_ABI)-$(NDK_COMPILER_VERSION) + else + HOST = $(NDK_ABI)-linux-androideabi + NDK_TOOLCHAIN = $(HOST)-$(NDK_COMPILER_VERSION) + endif + NDK_TOOLCHAIN_BASE=$(NDK_BASE)/toolchains/$(NDK_TOOLCHAIN)/prebuilt/$(NDK_UNAME)-$(NDK_PROCESSOR) + CC := $(NDK_TOOLCHAIN_BASE)/bin/$(HOST)-gcc --sysroot=$(NDK_SYSROOT) + LD := $(NDK_TOOLCHAIN_BASE)/bin/$(HOST)-ld OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer CFLAGS += - LDFLAGS += -Wl,--export-dynamic -shared - LUACFLAGS += -I/usr/include/lua # lua is named differently on every platform, check this and change it to fit - LIBS += -llua # lua is named differently on every platform, check this and change it to fit - LIBS += -lc - STRIP := $(NDK_TOOLCHAIN_BASE)/bin/arm-linux-androideabi-strip \ + LDFLAGS += -rdynamic -shared + SHARED_LDFLAGS += -Wl,-soname,$(SHARED_LIB) -shared + LIBS += -lc $(LIBS_android) + STRIP := $(NDK_TOOLCHAIN_BASE)/bin/$(HOST)-strip) \ --strip-unneeded -R .note -R .comment DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m) endif @@ -146,14 +180,14 @@ ifeq ($(UNAME),Linux) CPU := $(shell uname -m) SOURCES += $(SOURCES_linux) EXTENSION = pd_linux + SHARED_EXTENSION = so OS = linux PD_PATH = /usr OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer - CFLAGS += -fPIC -threepic - LDFLAGS += -Wl,--export-dynamic -shared -fPIC - LUACFLAGS += -I/usr/include/lua # lua is named differently on every platform, check this and change it to fit - LIBS += -llua # lua is named differently on every platform, check this and change it to fit - LIBS += -lc + ALL_CFLAGS += -fPIC + ALL_LDFLAGS += -rdynamic -shared -fPIC -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags + SHARED_LDFLAGS += -Wl,-soname,$(SHARED_LIB) -shared + ALL_LIBS += -lc $(LIBS_linux) STRIP = strip --strip-unneeded -R .note -R .comment DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m) endif @@ -162,14 +196,14 @@ ifeq ($(UNAME),GNU) CPU := $(shell uname -m) SOURCES += $(SOURCES_linux) EXTENSION = pd_linux + SHARED_EXTENSION = so OS = linux PD_PATH = /usr OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer - CFLAGS += -fPIC - LDFLAGS += -Wl,--export-dynamic -shared -fPIC - LIBS += -lc - LUACFLAGS += -I/usr/include/lua # lua is named differently on every platform, check this and change it to fit - LIBS += -llua # lua is named differently on every platform, check this and change it to fit + ALL_CFLAGS += -fPIC + ALL_LDFLAGS += -rdynamic -shared -fPIC -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags + SHARED_LDFLAGS += -shared -Wl,-soname,$(SHARED_LIB) + ALL_LIBS += -lc $(LIBS_linux) STRIP = strip --strip-unneeded -R .note -R .comment DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m) endif @@ -178,14 +212,14 @@ ifeq ($(UNAME),GNU/kFreeBSD) CPU := $(shell uname -m) SOURCES += $(SOURCES_linux) EXTENSION = pd_linux + SHARED_EXTENSION = so OS = linux PD_PATH = /usr OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer - CFLAGS += -fPIC - LDFLAGS += -Wl,--export-dynamic -shared -fPIC - LIBS += -lc - LUACFLAGS += -I/usr/include/lua # lua is named differently on every platform, check this and change it to fit - LIBS += -llua # lua is named differently on every platform, check this and change it to fit + ALL_CFLAGS += -fPIC + ALL_LDFLAGS += -rdynamic -shared -fPIC -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags + SHARED_LDFLAGS += -shared -Wl,-soname,$(SHARED_LIB) + ALL_LIBS += -lc $(LIBS_linux) STRIP = strip --strip-unneeded -R .note -R .comment DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m) endif @@ -193,14 +227,14 @@ ifeq (CYGWIN,$(findstring CYGWIN,$(UNAME))) CPU := $(shell uname -m) SOURCES += $(SOURCES_cygwin) EXTENSION = dll + SHARED_EXTENSION = dll OS = cygwin - PD_PATH = $(cygpath $(PROGRAMFILES))/pd + PD_PATH = $(shell cygpath $$PROGRAMFILES)/pd OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer - CFLAGS += - LDFLAGS += -Wl,--export-dynamic -shared -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin" - LUACFLAGS += -I/usr/include/lua # lua is named differently on every platform, check this and change it to fit - LIBS += -llua # lua is named differently on every platform, check this and change it to fit - LIBS += -lc -lpd + ALL_CFLAGS += + ALL_LDFLAGS += -rdynamic -shared -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin" + SHARED_LDFLAGS += -shared -Wl,-soname,$(SHARED_LIB) + ALL_LIBS += -lc -lpd $(LIBS_cygwin) STRIP = strip --strip-unneeded -R .note -R .comment DISTBINDIR=$(DISTDIR)-$(OS) endif @@ -208,14 +242,17 @@ ifeq (MINGW,$(findstring MINGW,$(UNAME))) CPU := $(shell uname -m) SOURCES += $(SOURCES_windows) EXTENSION = dll + SHARED_EXTENSION = dll OS = windows - PD_PATH = $(shell cd "$(PROGRAMFILES)"/pd && pwd) + PD_PATH = $(shell cd "$$PROGRAMFILES/pd" && pwd) + # MinGW doesn't seem to include cc so force gcc + CC=gcc OPT_CFLAGS = -O3 -funroll-loops -fomit-frame-pointer - CFLAGS += -mms-bitfields - LDFLAGS += -s -shared -Wl,--enable-auto-import - LIBS += -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin" -L"$(PD_PATH)/obj" -lpd -lwsock32 -lkernel32 -luser32 -lgdi32 - LUACFLAGS += -I/usr/local/include # lua is named differently on every platform, check this and change it to fit - LIBS += -llua # lua is named differently on every platform, check this and change it to fit + ALL_CFLAGS += -mms-bitfields + ALL_LDFLAGS += -s -shared -Wl,--enable-auto-import + SHARED_LDFLAGS += -shared + ALL_LIBS += -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin" -L"$(PD_PATH)/obj" \ + -lpd -lwsock32 -lkernel32 -luser32 -lgdi32 -liberty $(LIBS_windows) STRIP = strip --strip-unneeded -R .note -R .comment DISTBINDIR=$(DISTDIR)-$(OS) endif @@ -223,52 +260,60 @@ endif # in case somebody manually set the HELPPATCHES above HELPPATCHES ?= $(SOURCES:.c=-help.pd) $(PDOBJECTS:.pd=-help.pd) -#CFLAGS += $(OPT_CFLAGS) -#CFLAGS += $(LUACFLAGS) +ALL_CFLAGS := $(CPPFLAGS) $(ALL_CFLAGS) $(CFLAGS) $(LUA_CFLAGS) $(OPT_CFLAGS) +ALL_LDFLAGS := $(LDFLAGS) $(LUA_LDFLAGS) $(ALL_LDFLAGS) +ALL_LIBS := $(LIBS) $(LUA_LIBS) $(ALL_LIBS) + +SHARED_SOURCE ?= $(wildcard lib$(LIBRARY_NAME).c) +SHARED_HEADER ?= $(shell test ! -e $(LIBRARY_NAME).h || echo $(LIBRARY_NAME).h) +SHARED_LIB ?= $(SHARED_SOURCE:.c=.$(SHARED_EXTENSION)) +SHARED_TCL_LIB = $(wildcard lib$(LIBRARY_NAME).tcl) -.PHONY = install libdir_install single_install install-doc install-exec install-examples install-manual clean dist etags $(LIBRARY_NAME) +.PHONY = install libdir_install single_install install-doc install-examples install-manual install-unittests clean distclean dist etags $(LIBRARY_NAME) TAGS_PD TAGS_SOURCES -all: $(SOURCES:.c=.$(EXTENSION)) +all: $(SOURCES:.c=.$(EXTENSION)) $(SHARED_LIB) %.o: %.c - @echo "compiling $(LIBRARY_NAME) version $(LIBRARY_VERSION)" - @echo "cflags are $(CFLAGS)" - @echo "optcflags are $(OPT_CFLAGS)" - @echo "luacflags are $(LUACFLAGS)" - @echo "ldflags are $(LDFLAGS)" - @echo "libs are $(LIBS)" - $(CC) $(CFLAGS) $(OPT_CFLAGS) $(LUACFLAGS) -o "$*.o" -c "$*.c" - -%.$(EXTENSION): %.o - @echo "linking $(LIBRARY_NAME) with $(LIBS)" - $(CC) $(LDFLAGS) -o "$*.$(EXTENSION)" "$*.o" $(LIBS) - chmod a-x "$*.$(EXTENSION)" + $(CC) $(ALL_CFLAGS) -o $@ -c $< + +%.$(EXTENSION): %.o $(SHARED_LIB) + $(CC) $(ALL_LDFLAGS) -o $@ $^ $(ALL_LIBS) + chmod a-x $@ # this links everything into a single binary file -$(LIBRARY_NAME): $(SOURCES:.c=.o) $(LIBRARY_NAME).o - $(CC) $(LDFLAGS) -o $(LIBRARY_NAME).$(EXTENSION) $(SOURCES:.c=.o) $(LIBRARY_NAME).o $(LIBS) - chmod a-x $(LIBRARY_NAME).$(EXTENSION) +$(LIBRARY_NAME): $(SOURCES:.c=.o) $(LIBRARY_NAME).o $(SHARED_SOURCE:.c=.o) + $(CC) $(ALL_LDFLAGS) -o $@.$(EXTENSION) $^ $(ALL_LIBS) + chmod a-x $@.$(EXTENSION) + +$(SHARED_LIB): $(SHARED_SOURCE:.c=.o) + $(CC) $(SHARED_LDFLAGS) -o $@ $^ $(ALL_LIBS) install: libdir_install # The meta and help files are explicitly installed to make sure they are # actually there. Those files are not optional, then need to be there. -libdir_install: $(SOURCES:.c=.$(EXTENSION)) install-doc install-examples install-manual +libdir_install: $(SOURCES:.c=.$(EXTENSION)) $(SHARED_LIB) install-doc install-examples install-manual install-unittests $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) - $(INSTALL_DATA) $(LIBRARY_NAME)-meta.pd \ + $(INSTALL_DATA) $(LIBRARY_META) \ $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) test -z "$(strip $(SOURCES))" || (\ $(INSTALL_PROGRAM) $(SOURCES:.c=.$(EXTENSION)) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) && \ $(STRIP) $(addprefix $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/,$(SOURCES:.c=.$(EXTENSION)))) - test -z "$(strip $(shell ls $(SOURCES:.c=.tcl)))" || \ - $(INSTALL_DATA) $(shell ls $(SOURCES:.c=.tcl)) \ + test -z "$(strip $(SHARED_LIB))" || \ + $(INSTALL_DATA) $(SHARED_LIB) \ + $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) + test -z "$(strip $(wildcard $(SOURCES:.c=.tcl)))" || \ + $(INSTALL_DATA) $(wildcard $(SOURCES:.c=.tcl)) \ $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) test -z "$(strip $(PDOBJECTS))" || \ $(INSTALL_DATA) $(PDOBJECTS) \ $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) + test -z "$(strip $(SHARED_TCL_LIB))" || \ + $(INSTALL_DATA) $(SHARED_TCL_LIB) \ + $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) # install library linked as single binary -single_install: $(LIBRARY_NAME) install-doc install-exec +single_install: $(LIBRARY_NAME) install-doc install-examples install-manual install-unittests $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) $(INSTALL_PROGRAM) $(LIBRARY_NAME).$(EXTENSION) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) $(STRIP) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/$(LIBRARY_NAME).$(EXTENSION) @@ -278,8 +323,8 @@ install-doc: test -z "$(strip $(SOURCES) $(PDOBJECTS))" || \ $(INSTALL_DATA) $(HELPPATCHES) \ $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) - $(INSTALL_DATA) README.txt $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/README.txt - $(INSTALL_DATA) LICENSE.txt $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/LICENSE.txt + $(INSTALL_DATA) README $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/README.txt + $(INSTALL_DATA) COPYING $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/LICENSE.txt install-examples: test -z "$(strip $(EXAMPLES))" || \ @@ -290,17 +335,24 @@ install-examples: install-manual: test -z "$(strip $(MANUAL))" || \ - $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/manual && \ + $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/doc && \ for file in $(MANUAL); do \ - $(INSTALL_DATA) manual/$$file $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/manual; \ + $(INSTALL_DATA) doc/$$file $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/doc; \ done +install-unittests: + test -z "$(strip $(UNITTESTS))" || \ + $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/unittests && \ + for file in $(UNITTESTS); do \ + $(INSTALL_DATA) unittests/$$file $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/unittests; \ + done clean: - -rm -f -- $(SOURCES:.c=.o) $(SOURCES_LIB:.c=.o) + -rm -f -- $(SOURCES:.c=.o) $(SOURCES_LIB:.c=.o) $(SHARED_SOURCE:.c=.o) -rm -f -- $(SOURCES:.c=.$(EXTENSION)) -rm -f -- $(LIBRARY_NAME).o -rm -f -- $(LIBRARY_NAME).$(EXTENSION) + -rm -f -- $(SHARED_LIB) distclean: clean -rm -f -- $(DISTBINDIR).tar.gz @@ -315,8 +367,8 @@ $(DISTBINDIR): $(INSTALL_DIR) $(DISTBINDIR) libdir: all $(DISTBINDIR) - $(INSTALL_DATA) $(LIBRARY_NAME)-meta.pd $(DISTBINDIR) - $(INSTALL_DATA) $(SOURCES) $(DISTBINDIR) + $(INSTALL_DATA) $(LIBRARY_META) $(DISTBINDIR) + $(INSTALL_DATA) $(ALLSOURCES) $(SHARED_SOURCE) $(SHARED_HEADER) $(DISTBINDIR) $(INSTALL_DATA) $(HELPPATCHES) $(DISTBINDIR) test -z "$(strip $(EXTRA_DIST))" || \ $(INSTALL_DATA) $(EXTRA_DIST) $(DISTBINDIR) @@ -330,13 +382,21 @@ $(ORIGDIR): dist: $(DISTDIR) $(INSTALL_DATA) Makefile $(DISTDIR) - $(INSTALL_DATA) README.txt $(DISTDIR) - $(INSTALL_DATA) LICENSE.txt $(DISTDIR) - $(INSTALL_DATA) $(LIBRARY_NAME)-meta.pd $(DISTDIR) + $(INSTALL_DATA) README $(DISTDIR) + $(INSTALL_DATA) COPYING $(DISTDIR) + $(INSTALL_DATA) $(LIBRARY_META) $(DISTDIR) test -z "$(strip $(ALLSOURCES))" || \ $(INSTALL_DATA) $(ALLSOURCES) $(DISTDIR) - test -z "$(strip $(shell ls $(ALLSOURCES:.c=.tcl)))" || \ - $(INSTALL_DATA) $(shell ls $(ALLSOURCES:.c=.tcl)) $(DISTDIR) + test -z "$(strip $(wildcard $(ALLSOURCES:.c=.tcl)))" || \ + $(INSTALL_DATA) $(wildcard $(ALLSOURCES:.c=.tcl)) $(DISTDIR) + test -z "$(strip $(wildcard $(LIBRARY_NAME).c))" || \ + $(INSTALL_DATA) $(LIBRARY_NAME).c $(DISTDIR) + test -z "$(strip $(SHARED_HEADER))" || \ + $(INSTALL_DATA) $(SHARED_HEADER) $(DISTDIR) + test -z "$(strip $(SHARED_SOURCE))" || \ + $(INSTALL_DATA) $(SHARED_SOURCE) $(DISTDIR) + test -z "$(strip $(SHARED_TCL_LIB))" || \ + $(INSTALL_DATA) $(SHARED_TCL_LIB) $(DISTDIR) test -z "$(strip $(PDOBJECTS))" || \ $(INSTALL_DATA) $(PDOBJECTS) $(DISTDIR) test -z "$(strip $(HELPPATCHES))" || \ @@ -349,9 +409,14 @@ dist: $(DISTDIR) $(INSTALL_DATA) examples/$$file $(DISTDIR)/examples; \ done test -z "$(strip $(MANUAL))" || \ - $(INSTALL_DIR) $(DISTDIR)/manual && \ + $(INSTALL_DIR) $(DISTDIR)/doc && \ for file in $(MANUAL); do \ - $(INSTALL_DATA) manual/$$file $(DISTDIR)/manual; \ + $(INSTALL_DATA) doc/$$file $(DISTDIR)/doc; \ + done + test -z "$(strip $(UNITTESTS))" || \ + $(INSTALL_DIR) $(DISTDIR)/unittests && \ + for file in $(UNITTESTS); do \ + $(INSTALL_DATA) unittests/$$file $(DISTDIR)/unittests; \ done tar --exclude-vcs -czpf $(DISTDIR).tar.gz $(DISTDIR) @@ -365,23 +430,49 @@ dpkg-source: rm -rf -- $(DISTDIR) $(ORIGDIR) cd .. && dpkg-source -b $(LIBRARY_NAME) -etags: - etags *.h $(SOURCES) ../../pd/src/*.[ch] /usr/include/*.h /usr/include/*/*.h +etags: TAGS + +TAGS_PD: $(wildcard $(PD_INCLUDE)/*.h) + etags $^ +TAGS_SOURCES: $(SOURCES) $(SHARED_SOURCE) $(SHARED_HEADER) + etags -a $^ + +TAGS: TAGS_PD TAGS_SOURCES + etags -a *.h + etags -a --language=none --regex="/proc[ \t]+\([^ \t]+\)/\1/" *.tcl showsetup: + @echo "CC: $(CC)" @echo "CFLAGS: $(CFLAGS)" @echo "LDFLAGS: $(LDFLAGS)" @echo "LIBS: $(LIBS)" + @echo "ALL_CFLAGS: $(ALL_CFLAGS)" + @echo "ALL_LDFLAGS: $(ALL_LDFLAGS)" + @echo "ALL_LIBS: $(ALL_LIBS)" @echo "PD_INCLUDE: $(PD_INCLUDE)" @echo "PD_PATH: $(PD_PATH)" @echo "objectsdir: $(objectsdir)" @echo "LIBRARY_NAME: $(LIBRARY_NAME)" @echo "LIBRARY_VERSION: $(LIBRARY_VERSION)" @echo "SOURCES: $(SOURCES)" + @echo "SHARED_HEADER: $(SHARED_HEADER)" + @echo "SHARED_SOURCE: $(SHARED_SOURCE)" + @echo "SHARED_LIB: $(SHARED_LIB)" + @echo "SHARED_TCL_LIB: $(SHARED_TCL_LIB)" @echo "PDOBJECTS: $(PDOBJECTS)" @echo "ALLSOURCES: $(ALLSOURCES)" + @echo "ALLSOURCES TCL: $(wildcard $(ALLSOURCES:.c=.tcl))" @echo "UNAME: $(UNAME)" @echo "CPU: $(CPU)" + @echo "OS: $(OS)" @echo "pkglibdir: $(pkglibdir)" @echo "DISTDIR: $(DISTDIR)" @echo "ORIGDIR: $(ORIGDIR)" + @echo "NDK_TOOLCHAIN: $(NDK_TOOLCHAIN)" + @echo "NDK_BASE: $(NDK_BASE)" + @echo "NDK_SYSROOT: $(NDK_SYSROOT)" + @echo "" + @echo "EXAMPLES: $(EXAMPLES)" + @echo "MANUAL: $(MANUAL)" + @echo "EXTRA: $(EXTRA_DIST)" + @echo "foo: $(PDLUA_SRCPATH)" diff --git a/README b/README index f062239a9b4db934646fc23ebf3eee80fe83bd90..07a8dbda8251df2bb8804e17469573d0a79e30ea 100644 --- a/README +++ b/README @@ -1,5 +1,5 @@ pdlua -- a Lua embedding for Pd -Copyright (C) 2007,2008,2009 Claude Heiland-Allen <claudiusmaximus@goto10.org> +Copyright (C) 2007,2008,2009 Claude Heiland-Allen <claude@mathr.co.uk> This program is free software; you can redistribute it and/or diff --git a/TODO b/TODO deleted file mode 100644 index 5a2d6d14595e093a903a75f4f52ff738c67d9119..0000000000000000000000000000000000000000 --- a/TODO +++ /dev/null @@ -1,24 +0,0 @@ -todo -- fix Pd crash when a Lua error contains '{' -- documentation -- install target for make -- audit require support thoroughly: - - make require() support compiled packages - - make require() look next to Lua source before containing Pd patch -- add access to this script's and (containing/parent) Pd patch paths -- /usr/bin/ld: lua-lua.o: relocation R_X86_64_32 against `.rodata.str1.1' - can not be used when making a shared object; recompile with -fPIC - -done -- variable support (like [v foo]) -- table support (like [tabread]/[tabwrite]) -- send support -- add hook for object (post creation) -- receive support (preferably multiple receives) -- clock support -- audit possible bugs relating to self.f = f(self, ...) misuse -- write docs on foo.lua vs foo.luax -- change inlet/outlet numbering to start from 1 instead of 0 -- add pd.dofile(file) that searches via Pd's path (actually obj:dofile(file)) -- write docs implementation (eg foo._bar => internal, etc) -- add more features to lexpr diff --git a/doc/pdlua.tex b/doc/pdlua.tex index becceb91b0139bffd170f369e1df773260908f1f..c37e23d4ad8a6c38799cf298a520b21fe9db70ac 100644 --- a/doc/pdlua.tex +++ b/doc/pdlua.tex @@ -3,7 +3,7 @@ \title{pdlua} \author{Claude Heiland-Allen \\ -\tt{claudiusmaximus@goto10.org}} +\tt{claude@mathr.co.uk}} \begin{document} diff --git a/examples/list-pak.pd_lua b/examples/list-pak.pd_lua index 1651582d7e88c3d5ee6d8a01ed3fa70ce35bbdee..5964b335415d8ed769e28453f8f8f281585ab883 100644 --- a/examples/list-pak.pd_lua +++ b/examples/list-pak.pd_lua @@ -48,7 +48,8 @@ function ListPak:in_n(i, sel, atoms) -- insert selector self.stored[i] = sel else - if table.getn(atoms) > 0 then +-- if table.getn(atoms) > 0 then + if #(atoms) > 0 then self.stored[i] = atoms[1] end end diff --git a/examples/list-unpack.pd_lua b/examples/list-unpack.pd_lua index 08b635c3169e32a1320b75e3f22ba346a46c4798..ebddc4590e6ba084651554fb74ad71f511cdb7f9 100644 --- a/examples/list-unpack.pd_lua +++ b/examples/list-unpack.pd_lua @@ -50,7 +50,8 @@ function ListUnpack:in_1(sel, atoms) -- also unpack selector of anythings table.insert(atoms, 1, sel) end - local size = math.min(self.outlets, table.getn(atoms)) +-- local size = math.min(self.outlets, table.getn(atoms)) + local size = math.min(self.outlets, #(atoms)) for i=size, 1, -1 do self:Outlet(i, atoms[i]) end diff --git a/examples/peekbag.pd_lua b/examples/peekbag.pd_lua index 15e4791ca68559baec51745f231f69ad8cac000d..c37a0a39739a55a7b9da8fec8c5e4640493da0e8 100644 --- a/examples/peekbag.pd_lua +++ b/examples/peekbag.pd_lua @@ -14,7 +14,8 @@ function PeekBag:in_1_float(f) if self.add then table.insert(self.bag, f) else - for i=table.getn(self.bag),1,-1 do +-- for i=table.getn(self.bag),1,-1 do + for i = #(self.bag), 1, -1 do if self.bag[i]==f then table.remove(self.bag, i) break @@ -59,9 +60,11 @@ end function PeekBag:in_1_aslist() -- print all values of array as list - if table.getn(self.bag) == 1 then +-- if table.getn(self.bag) == 1 then + if #(self.bag) == 1 then self:outlet(1, "float", {self.bag[1]}) - elseif table.getn(self.bag) > 1 then +-- elseif table.getn(self.bag) > 1 then + elseif #(self.bag) > 1 then self:outlet(1, "list", self.bag) end end diff --git a/src/hello-help.pd b/hello-help.pd similarity index 100% rename from src/hello-help.pd rename to hello-help.pd diff --git a/src/hello.lua b/hello.lua similarity index 100% rename from src/hello.lua rename to hello.lua diff --git a/src/hello.pd_lua b/hello.pd_lua similarity index 100% rename from src/hello.pd_lua rename to hello.pd_lua diff --git a/src/hello.pd_luax b/hello.pd_luax similarity index 100% rename from src/hello.pd_luax rename to hello.pd_luax diff --git a/src/pd.lua b/pd.lua similarity index 99% rename from src/pd.lua rename to pd.lua index 7ad18e94540ffea77732651a14908f58f369164c..fdd1c4a422ad064414d2108f1c4afd7e67e47006 100644 --- a/src/pd.lua +++ b/pd.lua @@ -1,6 +1,6 @@ --[[ pdlua -- a Lua embedding for Pd -Copyright (C) 2007,2008 Claude Heiland-Allen <claudiusmaximus@goto10.org> +Copyright (C) 2007,2008 Claude Heiland-Allen <claude@mathr.co.uk> Copyright (C) 2012 Martin Peach martin.peach@sympatico.ca This program is free software; you can redistribute it and/or diff --git a/src/pdlua-help.pd b/pdlua-help.pd similarity index 100% rename from src/pdlua-help.pd rename to pdlua-help.pd diff --git a/src/pdlua-meta.pd b/pdlua-meta.pd similarity index 84% rename from src/pdlua-meta.pd rename to pdlua-meta.pd index ae8607a7066ffab2650b3abf7abdd4d35d413d01..5100b300959d374a9b5a8ccd02490303db215708 100644 --- a/src/pdlua-meta.pd +++ b/pdlua-meta.pd @@ -5,6 +5,6 @@ #X text 10 50 LICENSE GNU GPL; #X text 10 70 DESCRIPTION lua loader for pd; #X text 10 90 AUTHOR Claude Heiland-Allen \, Frank Barknecht \, Martin -Peach; -#X text 10 110 VERSION 0.6; +Peach \, IOhannes m zmölnig; +#X text 10 110 VERSION 0.7.3; #X restore 10 20 pd META; diff --git a/src/pdlua.c b/pdlua.c similarity index 77% rename from src/pdlua.c rename to pdlua.c index 7feb382f60d71585e6b93178ca26ed546e322b9f..d47a91dce4197567265bbf21157780bd1b84ea50 100644 --- a/src/pdlua.c +++ b/pdlua.c @@ -1,1865 +1,1722 @@ -/* This is a version hacked by Martin Peach 20110120 martin.peach@sympatico.ca */ -/* Reformmatted the code and added some debug messages. Changed the name of the class to pdlua */ -/** @file lua.c - * @brief pdlua -- a Lua embedding for Pd. - * @author Claude Heiland-Allen <claudiusmaximus@goto10.org> - * @date 2008 - * @version 0.6~svn - * - * Copyright (C) 2007,2008 Claude Heiland-Allen <claudiusmaximus@goto10.org> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -/* various C stuff, mainly for reading files */ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> // for open -#include <sys/stat.h> // for open -#ifdef _MSC_VER -#include <io.h> -#include <fcntl.h> // for open -#define read _read -#define close _close -#define ssize_t int -#define snprintf _snprintf -#else -#include <sys/fcntl.h> // for open -#include <unistd.h> -#endif -/* we use Lua */ -#include <lua.h> -#include <lauxlib.h> -#include <lualib.h> - -/* we use Pd */ -#include "m_pd.h" -#include "s_stuff.h" // for sys_register_loader() -#include "m_imp.h" // for struct _class -/* BAD: support for Pd < 0.41 */ - -#if PD_MAJOR_VERSION == 0 -# if PD_MINOR_VERSION >= 41 -# define PDLUA_PD41 -/* use new garray support that is 64-bit safe */ -# define PDLUA_ARRAYGRAB garray_getfloatwords -# define PDLUA_ARRAYTYPE t_word -# define PDLUA_ARRAYELEM(arr,idx) ((arr)[(idx)].w_float) -# elif PD_MINOR_VERSION >= 40 -# define PDLUA_PD40 -/* use old garray support, not 64-bit safe */ -# define PDLUA_ARRAYGRAB garray_getfloatarray -# define PDLUA_ARRAYTYPE t_float -# define PDLUA_ARRAYELEM(arr,idx) ((arr)[(idx)]) -# elif PD_MINOR_VERSION >= 39 -# define PDLUA_PD39 -/* use old garray support, not 64-bit safe */ -# define PDLUA_ARRAYGRAB garray_getfloatarray -# define PDLUA_ARRAYTYPE t_float -# define PDLUA_ARRAYELEM(arr,idx) ((arr)[(idx)]) -# else -# error "Pd version is too old, please upgrade" -# endif -#else -# error "Pd version is too new, please file a bug report" -#endif - -/* BAD: end of bad section */ - -/* If defined, PDLUA_DEBUG lets pdlua post a lot of text */ -//#define PDLUA_DEBUG - -/** Global Lua interpreter state, needed in the constructor. */ -static lua_State *L; - -/** State for the Lua file reader. */ -typedef struct pdlua_readerdata -{ - int fd; /**< File descriptor to read from. */ - char buffer[MAXPDSTRING]; /**< Buffer to read into. */ -} t_pdlua_readerdata; - -/** Pd object data. */ -typedef struct pdlua -{ - t_object pd; /**< We are a Pd object. */ - int inlets; /**< Number of inlets. */ - struct pdlua_proxyinlet *in; /**< The inlets themselves. */ - int outlets; /**< Number of outlets. */ - t_outlet **out; /**< The outlets themselves. */ - t_canvas *canvas; /**< The canvas that the object was created on. */ -} t_pdlua; - -/** Proxy inlet object data. */ -typedef struct pdlua_proxyinlet -{ - t_pd pd; /**< Minimal Pd object. */ - struct pdlua *owner; /**< The owning object to forward inlet messages to. */ - unsigned int id; /**< The number of this inlet. */ -} t_pdlua_proxyinlet; - -/** Proxy receive object data. */ -typedef struct pdlua_proxyreceive -{ - t_pd pd; /**< Minimal Pd object. */ - struct pdlua *owner; /**< The owning object to forward received messages to. */ - t_symbol *name; /**< The receive-symbol to bind to. */ -} t_pdlua_proxyreceive; - -/** Proxy clock object data. */ -typedef struct pdlua_proxyclock -{ - t_pd pd; /**< Minimal Pd object. */ - struct pdlua *owner; /**< Object to forward messages to. */ - t_clock *clock; /** Pd clock to use. */ -} t_pdlua_proxyclock; -/* prototypes*/ - -static const char *pdlua_reader (lua_State *L, void *rr, size_t *size); -/** Proxy inlet 'anything' method. */ -static void pdlua_proxyinlet_anything (t_pdlua_proxyinlet *p, t_symbol *s, int argc, t_atom *argv); -/** Proxy inlet initialization. */ -static void pdlua_proxyinlet_init (t_pdlua_proxyinlet *p, struct pdlua *owner, unsigned int id); -/** Register the proxy inlet class with Pd. */ -static void pdlua_proxyinlet_setup (void); -/** Proxy receive 'anything' method. */ -static void pdlua_proxyreceive_anything (t_pdlua_proxyreceive *r, t_symbol *s, int argc, t_atom *argv); -/** Proxy receive allocation and initialization. */ -static t_pdlua_proxyreceive *pdlua_proxyreceive_new (struct pdlua *owner, t_symbol *name); -/** Proxy receive cleanup and deallocation. */ -static void pdlua_proxyreceive_free (t_pdlua_proxyreceive *r /**< The proxy receive to free. */); -/** Register the proxy receive class with Pd. */ -static void pdlua_proxyreceive_setup (void); -/** Proxy clock 'bang' method. */ -static void pdlua_proxyclock_bang (t_pdlua_proxyclock *c); -/** Proxy clock allocation and initialization. */ -static t_pdlua_proxyclock *pdlua_proxyclock_new (struct pdlua *owner); -/** Register the proxy clock class with Pd. */ -static void pdlua_proxyclock_setup (void); -/** Dump an array of atoms into a Lua table. */ -static void pdlua_pushatomtable (int argc, t_atom *argv); -/** Pd object constructor. */ -static t_pdlua *pdlua_new (t_symbol *s, int argc, t_atom *argv); -/** Pd object destructor. */ -static void pdlua_free (t_pdlua *o ); -static void pdlua_stack_dump (lua_State *L); -/** a handler for the open item in the right-click menu (mrpeach 20111025) */ -/** Here we find the lua code for the object and open it in an editor */ -static void pdlua_menu_open (t_pdlua *o); -/** Lua class registration. This is equivalent to the "setup" method for an ordinary Pd class */ -static int pdlua_class_new (lua_State *L); -/** Lua object creation. */ -static int pdlua_object_new (lua_State *L); -/** Lua object inlet creation. */ -static int pdlua_object_createinlets (lua_State *L); -/** Lua object outlet creation. */ -static int pdlua_object_createoutlets (lua_State *L); -/** Lua object receive creation. */ -static int pdlua_receive_new (lua_State *L); -/** Lua object receive destruction. */ -static int pdlua_receive_free (lua_State *L); -/** Lua object clock creation. */ -static int pdlua_clock_new (lua_State *L); -/** Lua proxy clock delay. */ -static int pdlua_clock_delay (lua_State *L); -/** Lua proxy clock set. */ -static int pdlua_clock_set (lua_State *L); -/** Lua proxy clock unset. */ -static int pdlua_clock_unset (lua_State *L); -/** Lua proxy clock destruction. */ -static int pdlua_clock_free (lua_State *L); -/** Lua object destruction. */ -static int pdlua_object_free (lua_State *L); -/** Dispatch Pd inlet messages to Lua objects. */ -static void pdlua_dispatch (t_pdlua *o, unsigned int inlet, t_symbol *s, int argc, t_atom *argv); -/** Dispatch Pd receive messages to Lua objects. */ -static void pdlua_receivedispatch (t_pdlua_proxyreceive *r, t_symbol *s, int argc, t_atom *argv); -/** Dispatch Pd clock messages to Lua objects. */ -static void pdlua_clockdispatch(t_pdlua_proxyclock *clock); -/** Convert a Lua table into a Pd atom array. */ -static t_atom *pdlua_popatomtable (lua_State *L, int *count, t_pdlua *o); -/** Send a message from a Lua object outlet. */ -static int pdlua_outlet (lua_State *L); -/** Send a message from a Lua object to a Pd receiver. */ -static int pdlua_send (lua_State *L); -/** Set a [value] object's value. */ -static int pdlua_setvalue (lua_State *L); -/** Get a [value] object's value. */ -static int pdlua_getvalue (lua_State *L); -/** Get a [table] object's array. */ -static int pdlua_getarray (lua_State *L); -/** Read from a [table] object's array. */ -static int pdlua_readarray (lua_State *L); -/** Write to a [table] object's array. */ -static int pdlua_writearray (lua_State *L); -/** Redraw a [table] object's graph. */ -static int pdlua_redrawarray (lua_State *L); -/** Post to Pd's console. */ -static int pdlua_post (lua_State *L); -/** Report an error from a Lua object to Pd's console. */ -static int pdlua_error (lua_State *L); -static void pdlua_setrequirepath (lua_State *L, const char *path); -static void pdlua_clearrequirepath (lua_State *L); -/** Run a Lua script using Pd's path. */ -static int pdlua_dofile (lua_State *L); -/** Initialize the pd API for Lua. */ -static void pdlua_init (lua_State *L); -/** Pd loader hook for loading and executing Lua scripts. */ -static int pdlua_loader (t_canvas *canvas, char *name); -/** Start the Lua runtime and register our loader hook. */ -#ifdef _WIN32 -__declspec(dllexport) -#endif -void pdlua_setup (void); -/* end prototypes*/ - -/* globals */ -struct pdlua_proxyinlet; -struct pdlua_proxyreceive; -struct pdlua_proxyclock; -/** Proxy inlet class pointer. */ -static t_class *pdlua_proxyinlet_class; -/** Proxy receive class pointer. */ -static t_class *pdlua_proxyreceive_class; -/** Proxy clock class pointer. */ -static t_class *pdlua_proxyclock_class; - -/** Lua file reader callback. */ -static const char *pdlua_reader -( - lua_State *L, /**< Lua interpreter state. */ - void *rr, /**< Lua file reader state. */ - size_t *size /**< How much data we have read. */ -) -{ - t_pdlua_readerdata *r = rr; - ssize_t s; -#ifdef PDLUA_DEBUG - post("pdlua_reader: fd is %d", r->fd); -#endif // PDLUA_DEBUG - s = read(r->fd, r->buffer, MAXPDSTRING-2); -#ifdef PDLUA_DEBUG - post("pdlua_reader: s is %ld", s);//////// -#endif // PDLUA_DEBUG - if (s <= 0) - { - *size = 0; - return NULL; - } - else - { - *size = s; - return r->buffer; - } -} - -/** Proxy inlet 'anything' method. */ -static void pdlua_proxyinlet_anything -( - t_pdlua_proxyinlet *p, /**< The proxy inlet that received the message. */ - t_symbol *s, /**< The message selector. */ - int argc, /**< The message length. */ - t_atom *argv /**< The atoms in the message. */ -) -{ - pdlua_dispatch(p->owner, p->id, s, argc, argv); -} - -/** Proxy inlet initialization. */ -static void pdlua_proxyinlet_init -( - t_pdlua_proxyinlet *p, /**< The proxy inlet to initialize. */ - struct pdlua *owner, /**< The owning object. */ - unsigned int id /**< The inlet number. */ -) -{ - p->pd = pdlua_proxyinlet_class; - p->owner = owner; - p->id = id; -} - -/** Register the proxy inlet class with Pd. */ -static void pdlua_proxyinlet_setup(void) -{ - pdlua_proxyinlet_class = class_new(gensym("pdlua proxy inlet"), 0, 0, sizeof(t_pdlua_proxyinlet), 0, 0); - class_addanything(pdlua_proxyinlet_class, pdlua_proxyinlet_anything); -} - -/** Proxy receive 'anything' method. */ -static void pdlua_proxyreceive_anything( - t_pdlua_proxyreceive *r, /**< The proxy receive that received the message. */ - t_symbol *s, /**< The message selector. */ - int argc, /**< The message length. */ - t_atom *argv /**< The atoms in the message. */ -) -{ - pdlua_receivedispatch(r, s, argc, argv); -} - -/** Proxy receive allocation and initialization. */ -static t_pdlua_proxyreceive *pdlua_proxyreceive_new -( - struct pdlua *owner, /**< The owning object. */ - t_symbol *name /**< The symbol to bind to. */ -) -{ - t_pdlua_proxyreceive *r = malloc(sizeof(t_pdlua_proxyreceive)); - r->pd = pdlua_proxyreceive_class; - r->owner = owner; - r->name = name; - pd_bind(&r->pd, r->name); - return r; -} - -/** Proxy receive cleanup and deallocation. */ -static void pdlua_proxyreceive_free(t_pdlua_proxyreceive *r /**< The proxy receive to free. */) -{ - pd_unbind(&r->pd, r->name); - r->pd = NULL; - r->owner = NULL; - r->name = NULL; - free(r); -} - -/** Register the proxy receive class with Pd. */ -static void pdlua_proxyreceive_setup() -{ - pdlua_proxyreceive_class = class_new(gensym("pdlua proxy receive"), 0, 0, sizeof(t_pdlua_proxyreceive), 0, 0); - class_addanything(pdlua_proxyreceive_class, pdlua_proxyreceive_anything); -} - -/** Proxy clock 'bang' method. */ -static void pdlua_proxyclock_bang(t_pdlua_proxyclock *c /**< The proxy clock that received the message. */) -{ - pdlua_clockdispatch(c); -} - -/** Proxy clock allocation and initialization. */ -static t_pdlua_proxyclock *pdlua_proxyclock_new -( - struct pdlua *owner /**< The object to forward messages to. */ -) -{ - t_pdlua_proxyclock *c = malloc(sizeof(t_pdlua_proxyclock)); - c->pd = pdlua_proxyclock_class; - c->owner = owner; - c->clock = clock_new(c, (t_method) pdlua_proxyclock_bang); - return c; -} - -/** Register the proxy clock class with Pd. */ -static void pdlua_proxyclock_setup(void) -{ - pdlua_proxyclock_class = class_new(gensym("pdlua proxy clock"), 0, 0, sizeof(t_pdlua_proxyclock), 0, 0); -} - -/** Dump an array of atoms into a Lua table. */ -static void pdlua_pushatomtable -( - int argc, /**< The number of atoms in the array. */ - t_atom *argv /**< The array of atoms. */ -) -{ - int i; - -#ifdef PDLUA_DEBUG - post("pdlua_pushatomtable: stack top %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - lua_newtable(L); - for (i = 0; i < argc; ++i) - { - lua_pushnumber(L, i+1); - switch (argv[i].a_type) - { - case A_FLOAT: - lua_pushnumber(L, argv[i].a_w.w_float); - break; - case A_SYMBOL: - lua_pushstring(L, argv[i].a_w.w_symbol->s_name); - break; - case A_POINTER: /* FIXME: check experimentality */ - lua_pushlightuserdata(L, argv[i].a_w.w_gpointer); - break; - default: - error("lua: zomg weasels!"); - lua_pushnil(L); - break; - } - lua_settable(L, -3); - } -#ifdef PDLUA_DEBUG - post("pdlua_pushatomtable: end. stack top %d", lua_gettop(L)); -#endif // PDLUA_DEBUG -} - -/** Pd object constructor. */ -static t_pdlua *pdlua_new -( - t_symbol *s, /**< The construction message selector. */ - int argc, /**< The construction message atom count. */ - t_atom *argv /**< The construction message atoms. */ -) -{ - int i; -#ifdef PDLUA_DEBUG - post("pdlua_new: s->s_name is %s", s->s_name); -#endif // PDLUA_DEBUG - for (i = 0; i < argc; ++i) - { - switch (argv[i].a_type) - { - case A_FLOAT: -#ifdef PDLUA_DEBUG - post("argv[%d]: %f", i, argv[i].a_w.w_float); -#endif // PDLUA_DEBUG - break; - case A_SYMBOL: -#ifdef PDLUA_DEBUG - post("argv[%d]: %s", i, argv[i].a_w.w_symbol->s_name); -#endif // PDLUA_DEBUG - break; - default: - error("pdlua_new: bad argument type"); // should never happen - return NULL; - } - } -#ifdef PDLUA_DEBUG - post("pdlua_new: start with stack top %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - lua_getglobal(L, "pd"); - lua_getfield(L, -1, "_constructor"); - lua_pushstring(L, s->s_name); - pdlua_pushatomtable(argc, argv); -#ifdef PDLUA_DEBUG - post("pdlua_new: before lua_pcall(L, 2, 1, 0) stack top %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - if (lua_pcall(L, 2, 1, 0)) - { - error("pdlua_new: error in constructor for `%s':\n%s", s->s_name, lua_tostring(L, -1)); - lua_pop(L, 2); /* pop the error string and the global "pd" */ - return NULL; - } - else - { - t_pdlua *object = NULL; -#ifdef PDLUA_DEBUG - post("pdlua_new: done lua_pcall(L, 2, 1, 0) stack top %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - if (lua_islightuserdata(L, -1)) - { - object = lua_touserdata(L, -1); - lua_pop(L, 2);/* pop the userdata and the global "pd" */ -#ifdef PDLUA_DEBUG - post("pdlua_new: before returning object %p stack top %d", object, lua_gettop(L)); -#endif // PDLUA_DEBUG - return object; - } - else - { - lua_pop(L, 2);/* pop the userdata and the global "pd" */ -#ifdef PDLUA_DEBUG - post("pdlua_new: done FALSE lua_islightuserdata(L, -1)"); -#endif // PDLUA_DEBUG - return NULL; - } - } -} - -/** Pd object destructor. */ -static void pdlua_free( t_pdlua *o /**< The object to destruct. */) -{ -#ifdef PDLUA_DEBUG - post("pdlua_free: stack top %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - lua_getglobal(L, "pd"); - lua_getfield (L, -1, "_destructor"); - lua_pushlightuserdata(L, o); - if (lua_pcall(L, 1, 0, 0)) - { - error("lua: error in destructor:\n%s", lua_tostring(L, -1)); - lua_pop(L, 1); /* pop the error string */ - } - lua_pop(L, 1); /* pop the global "pd" */ -#ifdef PDLUA_DEBUG - post("pdlua_free: end. stack top %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return; -} - -static void pdlua_stack_dump (lua_State *L) -{ - int i; - int top = lua_gettop(L); - - for (i = 1; i <= top; i++) - { /* repeat for each level */ - int t = lua_type(L, i); - switch (t) - { - case LUA_TSTRING: /* strings */ - printf("`%s'", lua_tostring(L, i)); - break; - - case LUA_TBOOLEAN: /* booleans */ - printf(lua_toboolean(L, i) ? "true" : "false"); - break; - - case LUA_TNUMBER: /* numbers */ - printf("%g", lua_tonumber(L, i)); - break; - - default: /* other values */ - printf("%s", lua_typename(L, t)); - break; - } - printf(" "); /* put a separator */ - } - printf("\n"); /* end the listing */ -} - -/** a handler for the open item in the right-click menu (mrpeach 20111025) */ -/** Here we find the lua code for the object and open it in an editor */ -static void pdlua_menu_open(t_pdlua *o) -{ - const char *name; - const char *path; - char pathname[FILENAME_MAX]; - t_class *class; - -#ifdef PDLUA_DEBUG - post("pdlua_menu_open stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - /** Get the scriptname of the object */ - lua_getglobal(L, "pd"); - lua_getfield(L, -1, "_whoami"); - lua_pushlightuserdata(L, o); - if (lua_pcall(L, 1, 1, 0)) - { - error("lua: error in whoami:\n%s", lua_tostring(L, -1)); - lua_pop(L, 2); /* pop the error string and the global "pd" */ - return; - } - name = luaL_checkstring(L, -1); -#ifdef PDLUA_DEBUG - post("pdlua_menu_open: L is %p, name is %s stack top is %d", L, name, lua_gettop(L)); -#endif // PDLUA_DEBUG - if (name) - { - if (name[strlen(name)-1] == 'x') - { - /* pdluax is a class, the particular file should loadable by name alone, we hope */ - sprintf(pathname, "%s", name); - lua_pop(L, 2); /* pop name and the global "pd" */ - } - else - { - lua_getglobal(L, "pd"); - lua_getfield(L, -1, "_get_class"); - lua_pushlightuserdata(L, o); - if (lua_pcall(L, 1, 1, 0)) - { - error("lua: error in get_class:\n%s", lua_tostring(L, -1)); - lua_pop(L, 4); /* pop the error string, global "pd", name, global "pd"*/ - return; - } - class = (t_class *)lua_touserdata(L, -1); - path = class->c_externdir->s_name; - sprintf(pathname, "%s/%s", path, name); - lua_pop(L, 4); /* pop class, global "pd", name, global "pd"*/ - } -#if PD_MAJOR_VERSION==0 && PD_MINOR_VERSION<43 - post("Opening %s for editing", pathname); -#else - logpost(NULL, 3, "Opening %s for editing", pathname); -#endif - sys_vgui("::pd_menucommands::menu_openfile {%s}\n", pathname); - } -#ifdef PDLUA_DEBUG - post("pdlua_menu_open end. stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG -} - -/** Lua class registration. This is equivalent to the "setup" method for an ordinary Pd class */ -static int pdlua_class_new(lua_State *L) -/**< Lua interpreter state. - * \par Inputs: - * \li \c 1 Class name string. - * \par Outputs: - * \li \c 1 Pd class pointer. - * */ -{ - const char *name; - t_class *c; - - name = luaL_checkstring(L, 1); -#ifdef PDLUA_DEBUG - post("pdlua_class_new: L is %p, name is %s stack top is %d", L, name, lua_gettop(L)); -#endif // PDLUA_DEBUG - c = class_new(gensym((char *) name), (t_newmethod) pdlua_new, - (t_method) pdlua_free, sizeof(t_pdlua), CLASS_NOINLET, A_GIMME, 0); - -/* a class with a "menu-open" method will have the "Open" item highlighted in the right-click menu */ - class_addmethod(c, (t_method)pdlua_menu_open, gensym("menu-open"), A_NULL);/* (mrpeach 20111025) */ -/**/ - - lua_pushlightuserdata(L, c); -#ifdef PDLUA_DEBUG - post("pdlua_class_new: end stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return 1; -} - -/** Lua object creation. */ -static int pdlua_object_new(lua_State *L) -/**< Lua interpreter state. - * \par Inputs: - * \li \c 1 Pd class pointer. - * \par Outputs: - * \li \c 2 Pd object pointer. - * */ -{ -#ifdef PDLUA_DEBUG - post("pdlua_object_new: stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - if (lua_islightuserdata(L, 1)) - { - t_class *c = lua_touserdata(L, 1); - if (c) - { -#ifdef PDLUA_DEBUG - char *path = c->c_externdir->s_name; - post("pdlua_object_new: path is %s", path); -#endif // PDLUA_DEBUG - t_pdlua *o = (t_pdlua *) pd_new(c); - if (o) - { - o->inlets = 0; - o->in = NULL; - o->outlets = 0; - o->out = NULL; - o->canvas = canvas_getcurrent(); - lua_pushlightuserdata(L, o); -#ifdef PDLUA_DEBUG - post("pdlua_object_new: success end. stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return 1; - } - } - } -#ifdef PDLUA_DEBUG - post("pdlua_object_new: fail end. stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return 0; -} - -/** Lua object inlet creation. */ -static int pdlua_object_createinlets(lua_State *L) -/**< Lua interpreter state. - * \par Inputs: - * \li \c 1 Pd object pointer. - * \li \c 2 Number of inlets. - * */ -{ - int i; - -#ifdef PDLUA_DEBUG - post("pdlua_object_createinlets: stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - if (lua_islightuserdata(L, 1)) - { - t_pdlua *o = lua_touserdata(L, 1); - if (o) - { - o->inlets = luaL_checknumber(L, 2); - o->in = malloc(o->inlets * sizeof(t_pdlua_proxyinlet)); - for (i = 0; i < o->inlets; ++i) - { - pdlua_proxyinlet_init(&o->in[i], o, i); - inlet_new(&o->pd, &o->in[i].pd, 0, 0); - } - } - } -#ifdef PDLUA_DEBUG - post("pdlua_object_createinlets: end. stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return 0; -} - -/** Lua object outlet creation. */ -static int pdlua_object_createoutlets(lua_State *L) -/**< Lua interpreter state. - * \par Inputs: - * \li \c 1 Pd object pointer. - * \li \c 2 Number of outlets. - * */ -{ - int i; - -#ifdef PDLUA_DEBUG - post("pdlua_object_createoutlets: stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - if (lua_islightuserdata(L, 1)) - { - t_pdlua *o = lua_touserdata(L, 1); - if (o) - { - o->outlets = luaL_checknumber(L, 2); - if (o->outlets > 0) - { - o->out = malloc(o->outlets * sizeof(t_outlet *)); - for (i = 0; i < o->outlets; ++i) o->out[i] = outlet_new(&o->pd, 0); - } - else o->out = NULL; - } - } -#ifdef PDLUA_DEBUG - post("pdlua_object_createoutlets: end stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return 0; -} - -/** Lua object receive creation. */ -static int pdlua_receive_new(lua_State *L) -/**< Lua interpreter state. - * \par Inputs: - * \li \c 1 Pd object pointer. - * \li \c 2 Receive name string. - * \par Outputs: - * \li \c 1 Pd receive pointer. - * */ -{ -#ifdef PDLUA_DEBUG - post("pdlua_receive_new: stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - if (lua_islightuserdata(L, 1)) - { - t_pdlua *o = lua_touserdata(L, 1); - if (o) - { - const char *name = luaL_checkstring(L, 2); - if (name) - { - t_pdlua_proxyreceive *r = pdlua_proxyreceive_new(o, gensym((char *) name)); /* const cast */ - lua_pushlightuserdata(L, r); -#ifdef PDLUA_DEBUG - post("pdlua_receive_new: success end. stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return 1; - } - } - } -#ifdef PDLUA_DEBUG - post("pdlua_receive_new: fail end. stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return 0; -} - -/** Lua object receive destruction. */ -static int pdlua_receive_free(lua_State *L) -/**< Lua interpreter state. - * \par Inputs: - * \li \c 1 Pd recieve pointer. - * */ -{ -#ifdef PDLUA_DEBUG - post("pdlua_receive_free: stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - if (lua_islightuserdata(L, 1)) - { - t_pdlua_proxyreceive *r = lua_touserdata(L, 1); - if (r) pdlua_proxyreceive_free(r); - } -#ifdef PDLUA_DEBUG - post("pdlua_receive_free: end. stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return 0; -} - -/** Lua object clock creation. */ -static int pdlua_clock_new(lua_State *L) -/**< Lua interpreter state. - * \par Inputs: - * \li \c 1 Pd object pointer. - * \par Outputs: - * \li \c 1 Pd clock pointer. - * */ -{ -#ifdef PDLUA_DEBUG - post("pdlua_clock_new: stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - if (lua_islightuserdata(L, 1)) - { - t_pdlua *o = lua_touserdata(L, 1); - if (o) - { - t_pdlua_proxyclock *c = pdlua_proxyclock_new(o); - lua_pushlightuserdata(L, c); -#ifdef PDLUA_DEBUG - post("pdlua_clock_new: success end. stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return 1; - } - } -#ifdef PDLUA_DEBUG - post("pdlua_clock_new: fail end. stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return 0; -} - -/** Lua proxy clock delay. */ -static int pdlua_clock_delay(lua_State *L) -/**< Lua interpreter state. - * \par Inputs: - * \li \c 1 Pd clock pointer. - * \li \c 2 Number of milliseconds to delay. - * */ -{ -#ifdef PDLUA_DEBUG - post("pdlua_clock_delay: stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - if (lua_islightuserdata(L, 1)) - { - t_pdlua_proxyclock *c = lua_touserdata(L, 1); - if (c) - { - double delaytime = luaL_checknumber(L, 2); - clock_delay(c->clock, delaytime); - } - } -#ifdef PDLUA_DEBUG - post("pdlua_clock_delay: end. stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return 0; -} - -/** Lua proxy clock set. */ -static int pdlua_clock_set(lua_State *L) -/**< Lua interpreter state. - * \par Inputs: - * \li \c 1 Pd clock pointer. - * \li \c 2 Number to set the clock. - * */ -{ -#ifdef PDLUA_DEBUG - post("pdlua_clock_set: stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - if (lua_islightuserdata(L, 1)) - { - t_pdlua_proxyclock *c = lua_touserdata(L, 1); - if (c) - { - double systime = luaL_checknumber(L, 2); - clock_set(c->clock, systime); - } - } -#ifdef PDLUA_DEBUG - post("pdlua_clock_set: end. stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return 0; -} - -/** Lua proxy clock unset. */ -static int pdlua_clock_unset(lua_State *L) -/**< Lua interpreter state. - * \par Inputs: - * \li \c 1 Pd clock pointer. - * */ -{ -#ifdef PDLUA_DEBUG - post("pdlua_clock_unset: stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - if (lua_islightuserdata(L, 1)) - { - t_pdlua_proxyclock *c = lua_touserdata(L, 1); - if (c) clock_unset(c->clock); - } -#ifdef PDLUA_DEBUG - post("pdlua_clock_unset: end. stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return 0; -} - -/** Lua proxy clock destruction. */ -static int pdlua_clock_free(lua_State *L) -/**< Lua interpreter state. - * \par Inputs: - * \li \c 1 Pd clock pointer. - * */ -{ -#ifdef PDLUA_DEBUG - post("pdlua_clock_free: stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - if (lua_islightuserdata(L, 1)) - { - t_pdlua_proxyclock *c = lua_touserdata(L, 1); - if (c) - { - clock_free(c->clock); - free(c); - } - } -#ifdef PDLUA_DEBUG - post("pdlua_clock_free: end. stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return 0; -} - -/** Lua object destruction. */ -static int pdlua_object_free(lua_State *L) -/**< Lua interpreter state. - * \par Inputs: - * \li \c 1 Pd object pointer. - * */ -{ - int i; - -#ifdef PDLUA_DEBUG - post("pdlua_object_free: stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - if (lua_islightuserdata(L, 1)) - { - t_pdlua *o = lua_touserdata(L, 1); - if (o) - { - if (o->in) free(o->in); - if(o->out) - { - for (i = 0; i < o->outlets; ++i) outlet_free(o->out[i]); - free(o->out); - o->out = NULL; - } - } - } -#ifdef PDLUA_DEBUG - post("pdlua_object_free: end. stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return 0; -} - -/** Dispatch Pd inlet messages to Lua objects. */ -static void pdlua_dispatch -( - t_pdlua *o, /**< The object that received the message. */ - unsigned int inlet, /**< The inlet that the message arrived at. */ - t_symbol *s, /**< The message selector. */ - int argc, /**< The message length. */ - t_atom *argv /**< The atoms in the message. */ -) -{ -#ifdef PDLUA_DEBUG - post("pdlua_dispatch: stack top %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - lua_getglobal(L, "pd"); - lua_getfield (L, -1, "_dispatcher"); - lua_pushlightuserdata(L, o); - lua_pushnumber(L, inlet + 1); /* C has 0.., Lua has 1.. */ - lua_pushstring(L, s->s_name); - pdlua_pushatomtable(argc, argv); - if (lua_pcall(L, 4, 0, 0)) - { - pd_error(o, "lua: error in dispatcher:\n%s", lua_tostring(L, -1)); - lua_pop(L, 1); /* pop the error string */ - } - lua_pop(L, 1); /* pop the global "pd" */ -#ifdef PDLUA_DEBUG - post("pdlua_dispatch: end. stack top %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return; -} - -/** Dispatch Pd receive messages to Lua objects. */ -static void pdlua_receivedispatch -( - t_pdlua_proxyreceive *r, /**< The proxy receive that received the message. */ - t_symbol *s, /**< The message selector. */ - int argc, /**< The message length. */ - t_atom *argv /**< The atoms in the message. */ -) -{ -#ifdef PDLUA_DEBUG - post("pdlua_receivedispatch: stack top %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - lua_getglobal(L, "pd"); - lua_getfield (L, -1, "_receivedispatch"); - lua_pushlightuserdata(L, r); - lua_pushstring(L, s->s_name); - pdlua_pushatomtable(argc, argv); - if (lua_pcall(L, 3, 0, 0)) - { - pd_error(r->owner, "lua: error in receive dispatcher:\n%s", lua_tostring(L, -1)); - lua_pop(L, 1); /* pop the error string */ - } - lua_pop(L, 1); /* pop the global "pd" */ -#ifdef PDLUA_DEBUG - post("pdlua_receivedispatch: end. stack top %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return; -} - -/** Dispatch Pd clock messages to Lua objects. */ -static void pdlua_clockdispatch( t_pdlua_proxyclock *clock) -/**< The proxy clock that received the message. */ -{ -#ifdef PDLUA_DEBUG - post("pdlua_clockdispatch: stack top %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - lua_getglobal(L, "pd"); - lua_getfield (L, -1, "_clockdispatch"); - lua_pushlightuserdata(L, clock); - if (lua_pcall(L, 1, 0, 0)) - { - pd_error(clock->owner, "lua: error in clock dispatcher:\n%s", lua_tostring(L, -1)); - lua_pop(L, 1); /* pop the error string */ - } - lua_pop(L, 1); /* pop the global "pd" */ -#ifdef PDLUA_DEBUG - post("pdlua_clockdispatch: end. stack top %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return; -} - -/** Convert a Lua table into a Pd atom array. */ -static t_atom *pdlua_popatomtable -( - lua_State *L, /**< Lua interpreter state. - * \par Inputs: - * \li \c -1 Table to convert. - * */ - int *count, /**< Where to store the array length. */ - t_pdlua *o /**< Object reference for error messages. */ -) -{ - int i; - int ok = 1; - t_float f; - const char *s; - void *p; - size_t sl; - t_atom *atoms = NULL; - -#ifdef PDLUA_DEBUG - post("pdlua_popatomtable: stack top %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - if (lua_istable(L, -1)) - { -#if LUA_VERSION_NUM < 502 - *count = lua_objlen(L, -1); -#else // 5.2 style - *count = lua_rawlen(L, -1); -#endif // LUA_VERSION_NUM < 502 - if (*count > 0) atoms = malloc(*count * sizeof(t_atom)); - i = 0; - lua_pushnil(L); - while (lua_next(L, -2) != 0) - { - if (i == *count) - { - pd_error(o, "lua: error: too many table elements"); - ok = 0; - break; - } - switch (lua_type(L, -1)) - { - case (LUA_TNUMBER): - f = lua_tonumber(L, -1); - SETFLOAT(&atoms[i], f); - break; - case (LUA_TSTRING): - s = lua_tolstring(L, -1, &sl); - if (s) - { - if (strlen(s) != sl) pd_error(o, "lua: warning: symbol munged (contains \\0 in body)"); - SETSYMBOL(&atoms[i], gensym((char *) s)); - } - else - { - pd_error(o, "lua: error: null string in table"); - ok = 0; - } - break; - case (LUA_TLIGHTUSERDATA): /* FIXME: check experimentality */ - p = lua_touserdata(L, -1); - SETPOINTER(&atoms[i], p); - break; - default: - pd_error(o, "lua: error: table element must be number or string or pointer"); - ok = 0; - break; - } - lua_pop(L, 1); - ++i; - } - if (i != *count) - { - pd_error(o, "lua: error: too few table elements"); - ok = 0; - } - } - else - { - pd_error(o, "lua: error: not a table"); - ok = 0; - } - lua_pop(L, 1); -#ifdef PDLUA_DEBUG - post("pdlua_popatomtable: end. stack top %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - if (ok) return atoms; - if (atoms) free(atoms); - return NULL; -} - -/** Send a message from a Lua object outlet. */ -static int pdlua_outlet(lua_State *L) -/**< Lua interpreter state. - * \par Inputs: - * \li \c 1 Pd object pointer. - * \li \c 2 Outlet number. - * \li \c 3 Message selector string. - * \li \c 4 Message atom table. - * */ -{ - t_pdlua *o; - int out; - size_t sl; - const char *s; - t_symbol *sym; - int count; - t_atom *atoms; - -#ifdef PDLUA_DEBUG - post("pdlua_outlet: stack top %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - if (lua_islightuserdata(L, 1)) - { - o = lua_touserdata(L, 1); - if (o) - { - if (lua_isnumber(L, 2)) out = lua_tonumber(L, 2) - 1; /* C has 0.., Lua has 1.. */ - else - { - pd_error(o, "lua: error: outlet must be a number"); - lua_pop(L, 4); /* pop all the arguments */ - return 0; - } - if (0 <= out && out < o->outlets) - { - if (lua_isstring(L, 3)) - { - s = lua_tolstring(L, 3, &sl); - sym = gensym((char *) s); /* const cast */ - if (s) - { - if (strlen(s) != sl) pd_error(o, "lua: warning: symbol munged (contains \\0 in body)"); - lua_pushvalue(L, 4); - atoms = pdlua_popatomtable(L, &count, o); - if (count == 0 || atoms) outlet_anything(o->out[out], sym, count, atoms); - else pd_error(o, "lua: error: no atoms??"); - if (atoms) - { - free(atoms); - lua_pop(L, 4); /* pop all the arguments */ - return 0; - } - } - else pd_error(o, "lua: error: null selector"); - } - else pd_error(o, "lua: error: selector must be a string"); - } - else pd_error(o, "lua: error: outlet out of range"); - } - else error("lua: error: no object to outlet from"); - } - else error("lua: error: bad arguments to outlet"); - lua_pop(L, 4); /* pop all the arguments */ -#ifdef PDLUA_DEBUG - post("pdlua_outlet: end. stack top %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return 0; -} - -/** Send a message from a Lua object to a Pd receiver. */ -static int pdlua_send(lua_State *L) -/**< Lua interpreter state. - * \par Inputs: - * \li \c 1 Receiver string. - * \li \c 2 Message selector string. - * \li \c 3 Message atom table. - * */ - -{ - size_t receivenamel; - const char *receivename; - t_symbol *receivesym; - size_t selnamel; - const char *selname; - t_symbol *selsym; - int count; - t_atom *atoms; - -#ifdef PDLUA_DEBUG - post("pdlua_send: stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - if (lua_isstring(L, 1)) - { - receivename = lua_tolstring(L, 1, &receivenamel); - receivesym = gensym((char *) receivename); /* const cast */ - if (receivesym) - { - if (strlen(receivename) != receivenamel) error("lua: warning: symbol munged (contains \\0 in body)"); - if (lua_isstring(L, 2)) - { - selname = lua_tolstring(L, 2, &selnamel); - selsym = gensym((char *) selname); /* const cast */ - if (selsym) - { - if (strlen(selname) != selnamel) error("lua: warning: symbol munged (contains \\0 in body)"); - lua_pushvalue(L, 3); - atoms = pdlua_popatomtable(L, &count, NULL); - if ((count == 0 || atoms) && (receivesym->s_thing)) typedmess(receivesym->s_thing, selsym, count, atoms); - else error("lua: error: no atoms??"); - if (atoms) - { - free(atoms); -#ifdef PDLUA_DEBUG - post("pdlua_send: success end. stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return 0; - } - } - else error("lua: error: null selector"); - } - else error("lua: error: selector must be a string"); - } - else error("lua: error: null receive name"); - } - else error("lua: error: receive name must be string"); -#ifdef PDLUA_DEBUG - post("pdlua_send: fail end. stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return 0; -} - -/** Set a [value] object's value. */ -static int pdlua_setvalue(lua_State *L) -/**< Lua interpreter state. - * \par Inputs: - * \li \c 1 Value name string. - * \li \c 2 Value number. - * \par Outputs: - * \li \c 1 success (usually depends on a [value] existing or not). - */ -{ - const char *str = luaL_checkstring(L, 1); - t_float val = luaL_checknumber(L, 2); - int err = value_setfloat(gensym(str), val); - -#ifdef PDLUA_DEBUG - post("pdlua_setvalue: stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - lua_pushboolean(L, !err); -#ifdef PDLUA_DEBUG - post("pdlua_setvalue: end. stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return 1; -} - -/** Get a [value] object's value. */ -static int pdlua_getvalue(lua_State *L) -/**< Lua interpreter state. - * \par Inputs: - * \li \c 1 Value name string. - * \par Outputs: - * \li \c 1 Value number, or nil for failure. - * */ -{ - const char *str = luaL_checkstring(L, 1); - t_float val; - int err = value_getfloat(gensym(str), &val); - -#ifdef PDLUA_DEBUG - post("pdlua_getvalue: stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - if (!err) lua_pushnumber(L, val); - else lua_pushnil(L); -#ifdef PDLUA_DEBUG - post("pdlua_getvalue: end. stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return 1; -} - -/** Get a [table] object's array. */ -static int pdlua_getarray(lua_State *L) -/**< Lua interpreter state. - * \par Inputs: - * \li \c 1 Table name string. - * \par Outputs: - * \li \c 1 Table length, or < 0 for failure. - * \li \c 2 Table pointer, or nil for failure. - * */ -{ - t_garray *a; - int n; - PDLUA_ARRAYTYPE *v; - const char *str = luaL_checkstring(L, 1); - -#ifdef PDLUA_DEBUG - post("pdlua_getarray: stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - if (!(a = (t_garray *) pd_findbyclass(gensym(str), garray_class))) - { - lua_pushnumber(L, -1); -#ifdef PDLUA_DEBUG - post("pdlua_getarray: end 1. stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return 1; - } - else if (!PDLUA_ARRAYGRAB(a, &n, &v)) - { - lua_pushnumber(L, -2); -#ifdef PDLUA_DEBUG - post("pdlua_getarray: end 2. stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return 1; - } - else - { - lua_pushnumber(L, n); - lua_pushlightuserdata(L, v); -#ifdef PDLUA_DEBUG - post("pdlua_getarray: end 3. stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return 2; - } -} - -/** Read from a [table] object's array. */ -static int pdlua_readarray(lua_State *L) -/**< Lua interpreter state. - * \par Inputs: - * \li \c 1 Table length number. - * \li \c 2 Table array pointer. - * \li \c 3 Table index number. - * \par Outputs: - * \li \c 1 Table element value, or nil for index out of range. - * */ -{ - int n = luaL_checknumber(L, 1); - PDLUA_ARRAYTYPE *v = lua_islightuserdata(L, 2) ? lua_touserdata(L, 2) : NULL; - int i = luaL_checknumber(L, 3); - -#ifdef PDLUA_DEBUG - post("pdlua_readarray: stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - if (0 <= i && i < n && v) - { - lua_pushnumber(L, PDLUA_ARRAYELEM(v, i)); -#ifdef PDLUA_DEBUG - post("pdlua_readarray: end 1. stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return 1; - } -#ifdef PDLUA_DEBUG - post("pdlua_readarray: end 2. stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return 0; -} - -/** Write to a [table] object's array. */ -static int pdlua_writearray(lua_State *L) -/**< Lua interpreter state. - * \par Inputs: - * \li \c 1 Table length number. - * \li \c 2 Table array pointer. - * \li \c 3 Table index number. - * \li \c 4 Table element value number. - * */ -{ - int n = luaL_checknumber(L, 1); - PDLUA_ARRAYTYPE *v = lua_islightuserdata(L, 2) ? lua_touserdata(L, 2) : NULL; - int i = luaL_checknumber(L, 3); - t_float x = luaL_checknumber(L, 4); - -#ifdef PDLUA_DEBUG - post("pdlua_writearray: stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - if (0 <= i && i < n && v) PDLUA_ARRAYELEM(v, i) = x; -#ifdef PDLUA_DEBUG - post("pdlua_writearray: end. stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return 0; -} - -/** Redraw a [table] object's graph. */ -static int pdlua_redrawarray(lua_State *L) -/**< Lua interpreter state. - * \par Inputs: - * \li \c 1 Table name string. - * */ -{ - t_garray *a; - const char *str = luaL_checkstring(L, 1); - -#ifdef PDLUA_DEBUG - post("pdlua_redrawarray: stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - if ((a = (t_garray *) pd_findbyclass(gensym(str), garray_class))) garray_redraw(a); -#ifdef PDLUA_DEBUG - post("pdlua_redrawarray: end. stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return 0; -} - -/** Post to Pd's console. */ -static int pdlua_post(lua_State *L) -/**< Lua interpreter state. - * \par Inputs: - * \li \c 1 Message string. - * */ -{ - const char *str = luaL_checkstring(L, 1); -#ifdef PDLUA_DEBUG - post("pdlua_post: stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - post("%s", str); -#ifdef PDLUA_DEBUG - post("pdlua_post: end. stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return 0; -} - -/** Report an error from a Lua object to Pd's console. */ -static int pdlua_error(lua_State *L) -/**< Lua interpreter state. - * \par Inputs: - * \li \c 1 Pd object pointer. - * \li \c 2 Message string. - * */ -{ - t_pdlua *o; - - - const char *s; - -#ifdef PDLUA_DEBUG - post("pdlua_error: stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - if (lua_islightuserdata(L, 1)) - { - o = lua_touserdata(L, 1); - if (o) - { - s = luaL_checkstring(L, 2); - if (s) pd_error(o, "%s", s); - else pd_error(o, "lua: error: null string in error function"); - } - else error("lua: error: null object in error function"); - } - else error("lua: error: bad arguments to error function"); -#ifdef PDLUA_DEBUG - post("pdlua_error: end. stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return 0; -} - -static void pdlua_setrequirepath -( /* FIXME: documentation (is this of any use at all?) */ - lua_State *L, - const char *path -) -{ -#ifdef PDLUA_DEBUG - post("pdlua_setrequirepath: stack top %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - lua_getglobal(L, "pd"); - lua_pushstring(L, "_setrequirepath"); - lua_gettable(L, -2); - lua_pushstring(L, path); - if (lua_pcall(L, 1, 0, 0) != 0) - { - error("lua: internal error in `pd._setrequirepath': %s", lua_tostring(L, -1)); - lua_pop(L, 1); - } - lua_pop(L, 1); -#ifdef PDLUA_DEBUG - post("pdlua_setrequirepath: end. stack top %d", lua_gettop(L)); -#endif // PDLUA_DEBUG -} - -static void pdlua_clearrequirepath -( /* FIXME: documentation (is this of any use at all?) */ - lua_State *L -) -{ -#ifdef PDLUA_DEBUG - post("pdlua_clearrequirepath: stack top %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - lua_getglobal(L, "pd"); - lua_pushstring(L, "_clearrequirepath"); - lua_gettable(L, -2); - if (lua_pcall(L, 0, 0, 0) != 0) - { - error("lua: internal error in `pd._clearrequirepath': %s", lua_tostring(L, -1)); - lua_pop(L, 1); - } - lua_pop(L, 1); -#ifdef PDLUA_DEBUG - post("pdlua_clearrequirepath: end. stack top %d", lua_gettop(L)); -#endif // PDLUA_DEBUG -} - -/** Run a Lua script using Pd's path. */ -static int pdlua_dofile(lua_State *L) -/**< Lua interpreter state. - * \par Inputs: - * \li \c 1 Pd object pointer. - * \li \c 2 Filename string. - * \par Outputs: - * \li \c * Determined by the script. - * */ -{ - char buf[MAXPDSTRING]; - char *ptr; - t_pdlua_readerdata reader; - int fd; - int n; - const char *filename; - t_pdlua *o; - -#ifdef PDLUA_DEBUG - post("pdlua_dofile: stack top %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - n = lua_gettop(L); - if (lua_islightuserdata(L, 1)) - { - o = lua_touserdata(L, 1); - if (o) - { - filename = luaL_optstring(L, 2, NULL); - fd = canvas_open(o->canvas, filename, "", buf, &ptr, MAXPDSTRING, 1); - if (fd >= 0) - { -#ifdef PDLUA_DEBUG - post("pdlua_dofile path is %s", buf); -#endif // PDLUA_DEBUG - //pdlua_setpathname(o, buf);/* change the scriptname to include its path */ - pdlua_setrequirepath(L, buf); - reader.fd = fd; -#if LUA_VERSION_NUM < 502 - if (lua_load(L, pdlua_reader, &reader, filename)) -#else // 5.2 style - if (lua_load(L, pdlua_reader, &reader, filename, NULL)) -#endif // LUA_VERSION_NUM < 502 - { - close(fd); - pdlua_clearrequirepath(L); - lua_error(L); - } - else - { - if (lua_pcall(L, 0, LUA_MULTRET, 0)) - { - pd_error(o, "lua: error running `%s':\n%s", filename, lua_tostring(L, -1)); - lua_pop(L, 1); - close(fd); - pdlua_clearrequirepath(L); - } - else - { - /* succeeded */ - close(fd); - pdlua_clearrequirepath(L); - } - } - } - else pd_error(o, "lua: error loading `%s': canvas_open() failed", filename); - } - else error("lua: error in object:dofile() - object is null"); - } - else error("lua: error in object:dofile() - object is wrong type"); - lua_pushstring(L, buf); /* return the path as well so we can open it later with pdlua_menu_open() */ -#ifdef PDLUA_DEBUG - post("pdlua_dofile end. stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - - return lua_gettop(L) - n; -} - -/** Initialize the pd API for Lua. */ -static void pdlua_init(lua_State *L) -/**< Lua interpreter state. */ -{ - lua_newtable(L); - lua_setglobal(L, "pd"); - lua_getglobal(L, "pd"); - lua_pushstring(L, "_iswindows"); -#ifdef _WIN32 - lua_pushboolean(L, 1); -#else - lua_pushboolean(L, 0); -#endif // _WIN32 - lua_settable(L, -3); - lua_pushstring(L, "_register"); - lua_pushcfunction(L, pdlua_class_new); - lua_settable(L, -3); - lua_pushstring(L, "_create"); - lua_pushcfunction(L, pdlua_object_new); - lua_settable(L, -3); - lua_pushstring(L, "_createinlets"); - lua_pushcfunction(L, pdlua_object_createinlets); - lua_settable(L, -3); - lua_pushstring(L, "_createoutlets"); - lua_pushcfunction(L, pdlua_object_createoutlets); - lua_settable(L, -3); - lua_pushstring(L, "_destroy"); - lua_pushcfunction(L, pdlua_object_free); - lua_settable(L, -3); - lua_pushstring(L, "_outlet"); - lua_pushcfunction(L, pdlua_outlet); - lua_settable(L, -3); - lua_pushstring(L, "_createreceive"); - lua_pushcfunction(L, pdlua_receive_new); - lua_settable(L, -3); - lua_pushstring(L, "_receivefree"); - lua_pushcfunction(L, pdlua_receive_free); - lua_settable(L, -3); - lua_pushstring(L, "_createclock"); - lua_pushcfunction(L, pdlua_clock_new); - lua_settable(L, -3); - lua_pushstring(L, "_clockfree"); - lua_pushcfunction(L, pdlua_clock_free); - lua_settable(L, -3); - lua_pushstring(L, "_clockset"); - lua_pushcfunction(L, pdlua_clock_set); - lua_settable(L, -3); - lua_pushstring(L, "_clockunset"); - lua_pushcfunction(L, pdlua_clock_unset); - lua_settable(L, -3); - lua_pushstring(L, "_clockdelay"); - lua_pushcfunction(L, pdlua_clock_delay); - lua_settable(L, -3); - lua_pushstring(L, "_dofile"); - lua_pushcfunction(L, pdlua_dofile); - lua_settable(L, -3); - lua_pushstring(L, "send"); - lua_pushcfunction(L, pdlua_send); - lua_settable(L, -3); - lua_pushstring(L, "getvalue"); - lua_pushcfunction(L, pdlua_getvalue); - lua_settable(L, -3); - lua_pushstring(L, "setvalue"); - lua_pushcfunction(L, pdlua_setvalue); - lua_settable(L, -3); - lua_pushstring(L, "_getarray"); - lua_pushcfunction(L, pdlua_getarray); - lua_settable(L, -3); - lua_pushstring(L, "_readarray"); - lua_pushcfunction(L, pdlua_readarray); - lua_settable(L, -3); - lua_pushstring(L, "_writearray"); - lua_pushcfunction(L, pdlua_writearray); - lua_settable(L, -3); - lua_pushstring(L, "_redrawarray"); - lua_pushcfunction(L, pdlua_redrawarray); - lua_settable(L, -3); - lua_pushstring(L, "post"); - lua_pushcfunction(L, pdlua_post); - lua_settable(L, -3); - lua_pushstring(L, "_error"); - lua_pushcfunction(L, pdlua_error); - lua_settable(L, -3); - lua_pop(L, 1); -#ifdef PDLUA_DEBUG - post("pdlua_init: end. stack top is %d", lua_gettop(L)); -#endif // PDLUA_DEBUG -} - -/** Pd loader hook for loading and executing Lua scripts. */ -static int pdlua_loader -( - t_canvas *canvas, /**< Pd canvas to use to find the script. */ - char *name /**< The name of the script (without .pd_lua extension). */ -) -{ - char dirbuf[MAXPDSTRING]; - char *ptr; - int fd; - t_pdlua_readerdata reader; - -#ifdef PDLUA_DEBUG - post("pdlua_loader: stack top %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - fd = canvas_open(canvas, name, ".pd_lua", dirbuf, &ptr, MAXPDSTRING, 1); - if (fd >= 0) - { - class_set_extern_dir(gensym(dirbuf)); - pdlua_setrequirepath(L, dirbuf); - reader.fd = fd; -#if LUA_VERSION_NUM < 502 - if (lua_load(L, pdlua_reader, &reader, name) || lua_pcall(L, 0, 0, 0)) -#else // 5.2 style - if (lua_load(L, pdlua_reader, &reader, name, NULL) || lua_pcall(L, 0, 0, 0)) -#endif // LUA_VERSION_NUM < 502 - { - - error("lua: error loading `%s':\n%s", name, lua_tostring(L, -1)); - lua_pop(L, 1); - close(fd); - pdlua_clearrequirepath(L); - class_set_extern_dir(&s_); -#ifdef PDLUA_DEBUG - post("pdlua_loader: script error end. stack top %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return 0; - } - close(fd); - pdlua_clearrequirepath(L); - class_set_extern_dir(&s_); -#ifdef PDLUA_DEBUG - post("pdlua_loader: end. stack top %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return 1; - } -#ifdef PDLUA_DEBUG - post("pdlua_loader: no file end. stack top %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - return 0; -} - -/** Start the Lua runtime and register our loader hook. */ -#ifdef _WIN32 -__declspec(dllexport) -#endif -void pdlua_setup(void) -{ - char pd_lua_path[MAXPDSTRING]; - t_pdlua_readerdata reader; - int fd; - int result; - char* pdluaver = "pdlua 0.7.2 (GPL) 2014 Martin Peach, based on"; - char* luaver = "lua 0.6~svn (GPL) 2008 Claude Heiland-Allen <claudiusmaximus@goto10.org>"; - char compiled[MAXPDSTRING]; - char luaversionStr[MAXPDSTRING]; - const lua_Number *luaversion = lua_version (NULL); - int lvm, lvl; - - snprintf(compiled, MAXPDSTRING-1, "pdlua: compiled for pd-%d.%d on %s %s", - PD_MAJOR_VERSION, PD_MINOR_VERSION, __DATE__, __TIME__); - - lvm = (*luaversion)/100; - lvl = (*luaversion) - (100*lvm); - snprintf(luaversionStr, MAXPDSTRING-1, "Using lua version %d.%d", lvm, lvl); - -#if PD_MAJOR_VERSION==0 && PD_MINOR_VERSION<43 - post(pdluaver); - post(luaver); - post(compiled); - post(luaversionStr); -#else - logpost(NULL, 3, pdluaver); - logpost(NULL, 3, luaver); - logpost(NULL, 3, compiled); - logpost(NULL, 3, luaversionStr); -#endif - pdlua_proxyinlet_setup(); -#ifdef PDLUA_DEBUG - post("pdlua pdlua_proxyinlet_setup done"); -#endif // PDLUA_DEBUG - pdlua_proxyreceive_setup(); -#ifdef PDLUA_DEBUG - post("pdlua pdlua_proxyreceive_setup done"); -#endif // PDLUA_DEBUG - pdlua_proxyclock_setup(); -#ifdef PDLUA_DEBUG - post("pdlua pdlua_proxyclock_setup done"); -#endif // PDLUA_DEBUG -#if LUA_VERSION_NUM < 502 - L = lua_open(); -#else // 5.2 style - L = luaL_newstate(); -#endif // LUA_VERSION_NUM < 502 -#ifdef PDLUA_DEBUG - post("pdlua lua_open done L = %p", L); -#endif // PDLUA_DEBUG - luaL_openlibs(L); -#ifdef PDLUA_DEBUG - post("pdlua luaL_openlibs done"); -#endif // PDLUA_DEBUG - pdlua_init(L); -#ifdef PDLUA_DEBUG - post("pdlua pdlua_init done"); -#endif // PDLUA_DEBUG - /* "pd.lua" is the Lua part of pdlua, want to keep the C part minimal */ - /* canvas_open can't find pd.lua unless we give the path to pd beforehand like pd -path /usr/lib/extra/pdlua */ - /* To avoid this we can use c_externdir from m_imp.h, struct _class: t_symbol *c_externdir; */ - /* c_externdir is the directory the extern was loaded from and is also the directory contining pd.lua */ - sprintf(pd_lua_path, "%s/pd.lua", pdlua_proxyinlet_class->c_externdir->s_name); /* the full path to pd.lua */ -#ifdef PDLUA_DEBUG - post("pd_lua_path %s", pd_lua_path); -#endif // PDLUA_DEBUG - fd = open(pd_lua_path, O_RDONLY); -/* fd = canvas_open(canvas_getcurrent(), "pd", ".lua", buf, &ptr, MAXPDSTRING, 1); looks all over and rarely succeeds */ -#ifdef PDLUA_DEBUG - post ("pd.lua loaded from %s", pd_lua_path); - post("pdlua canvas_open done fd = %d", fd); - post("pdlua_setup: stack top %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - if (fd >= 0) - { /* pd.lua was opened */ - reader.fd = fd; -#if LUA_VERSION_NUM < 502 - result = lua_load(L, pdlua_reader, &reader, "pd.lua"); -#else // 5.2 style - result = lua_load(L, pdlua_reader, &reader, "pd.lua", NULL); // mode bt for binary or text -#endif // LUA_VERSION_NUM < 502 -#ifdef PDLUA_DEBUG - post ("pdlua lua_load returned %d", result); -#endif // PDLUA_DEBUG - if (0 == result) - { - result = lua_pcall(L, 0, 0, 0); -#ifdef PDLUA_DEBUG - post ("pdlua lua_pcall returned %d", result); -#endif // PDLUA_DEBUG - } - if (0 != result) - //if (lua_load(L, pdlua_reader, &reader, "pd.lua") || lua_pcall(L, 0, 0, 0)) - { - error("lua: error loading `pd.lua':\n%s", lua_tostring(L, -1)); - error("lua: loader will not be registered!"); - error("lua: (is `pd.lua' in Pd's path list?)"); - lua_pop(L, 1); - close(fd); - } - else - { - close(fd); - sys_register_loader(pdlua_loader); - } - } - else - { - error("lua: error loading `pd.lua': canvas_open() failed"); - error("lua: loader will not be registered!"); - } -#ifdef PDLUA_DEBUG - post("pdlua_setup: end. stack top %d", lua_gettop(L)); -#endif // PDLUA_DEBUG - -} - -/* EOF */ +/* This is a version hacked by Martin Peach 20110120 martin.peach@sympatico.ca */ +/* Reformmatted the code and added some debug messages. Changed the name of the class to pdlua */ +/** @file lua.c + * @brief pdlua -- a Lua embedding for Pd. + * @author Claude Heiland-Allen <claude@mathr.co.uk> + * @date 2008 + * @version 0.6~svn + * + * Copyright (C) 2007,2008 Claude Heiland-Allen <claude@mathr.co.uk> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* various C stuff, mainly for reading files */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> // for open +#include <sys/stat.h> // for open +#ifdef _MSC_VER +#include <io.h> +#include <fcntl.h> // for open +#define read _read +#define close _close +#define ssize_t int +#define snprintf _snprintf +#else +#include <sys/fcntl.h> // for open +#include <unistd.h> +#endif +/* we use Lua */ +#include <lua.h> +#include <lauxlib.h> +#include <lualib.h> + +/* we use Pd */ +#include "m_pd.h" +#include "s_stuff.h" // for sys_register_loader() +#include "m_imp.h" // for struct _class +/* BAD: support for Pd < 0.41 */ + +#if PD_MAJOR_VERSION == 0 +# if PD_MINOR_VERSION >= 41 +# define PDLUA_PD41 +/* use new garray support that is 64-bit safe */ +# define PDLUA_ARRAYGRAB garray_getfloatwords +# define PDLUA_ARRAYTYPE t_word +# define PDLUA_ARRAYELEM(arr,idx) ((arr)[(idx)].w_float) +# elif PD_MINOR_VERSION >= 40 +# define PDLUA_PD40 +/* use old garray support, not 64-bit safe */ +# define PDLUA_ARRAYGRAB garray_getfloatarray +# define PDLUA_ARRAYTYPE t_float +# define PDLUA_ARRAYELEM(arr,idx) ((arr)[(idx)]) +# elif PD_MINOR_VERSION >= 39 +# define PDLUA_PD39 +/* use old garray support, not 64-bit safe */ +# define PDLUA_ARRAYGRAB garray_getfloatarray +# define PDLUA_ARRAYTYPE t_float +# define PDLUA_ARRAYELEM(arr,idx) ((arr)[(idx)]) +# else +# error "Pd version is too old, please upgrade" +# endif +#else +# error "Pd version is too new, please file a bug report" +#endif + +/* BAD: end of bad section */ + +/* If defined, PDLUA_DEBUG lets pdlua post a lot of text */ +//#define PDLUA_DEBUG post +#ifndef PDLUA_DEBUG +//static void PDLUA_DEBUG(const char *fmt, ...) {;} +# define PDLUA_DEBUG(x,y) +# define PDLUA_DEBUG2(x,y0,y1) +# define PDLUA_DEBUG3(x,y0,y1,y2) +#else +# define PDLUA_DEBUG2 PDLUA_DEBUG +# define PDLUA_DEBUG3 PDLUA_DEBUG +#endif + +/** Global Lua interpreter state, needed in the constructor. */ +static lua_State *L; + +/** State for the Lua file reader. */ +typedef struct pdlua_readerdata +{ + int fd; /**< File descriptor to read from. */ + char buffer[MAXPDSTRING]; /**< Buffer to read into. */ +} t_pdlua_readerdata; + +/** Pd object data. */ +typedef struct pdlua +{ + t_object pd; /**< We are a Pd object. */ + int inlets; /**< Number of inlets. */ + struct pdlua_proxyinlet *in; /**< The inlets themselves. */ + int outlets; /**< Number of outlets. */ + t_outlet **out; /**< The outlets themselves. */ + t_canvas *canvas; /**< The canvas that the object was created on. */ +} t_pdlua; + +/** Proxy inlet object data. */ +typedef struct pdlua_proxyinlet +{ + t_pd pd; /**< Minimal Pd object. */ + struct pdlua *owner; /**< The owning object to forward inlet messages to. */ + unsigned int id; /**< The number of this inlet. */ +} t_pdlua_proxyinlet; + +/** Proxy receive object data. */ +typedef struct pdlua_proxyreceive +{ + t_pd pd; /**< Minimal Pd object. */ + struct pdlua *owner; /**< The owning object to forward received messages to. */ + t_symbol *name; /**< The receive-symbol to bind to. */ +} t_pdlua_proxyreceive; + +/** Proxy clock object data. */ +typedef struct pdlua_proxyclock +{ + t_pd pd; /**< Minimal Pd object. */ + struct pdlua *owner; /**< Object to forward messages to. */ + t_clock *clock; /** Pd clock to use. */ +} t_pdlua_proxyclock; +/* prototypes*/ + +static const char *pdlua_reader (lua_State *L, void *rr, size_t *size); +/** Proxy inlet 'anything' method. */ +static void pdlua_proxyinlet_anything (t_pdlua_proxyinlet *p, t_symbol *s, int argc, t_atom *argv); +/** Proxy inlet initialization. */ +static void pdlua_proxyinlet_init (t_pdlua_proxyinlet *p, struct pdlua *owner, unsigned int id); +/** Register the proxy inlet class with Pd. */ +static void pdlua_proxyinlet_setup (void); +/** Proxy receive 'anything' method. */ +static void pdlua_proxyreceive_anything (t_pdlua_proxyreceive *r, t_symbol *s, int argc, t_atom *argv); +/** Proxy receive allocation and initialization. */ +static t_pdlua_proxyreceive *pdlua_proxyreceive_new (struct pdlua *owner, t_symbol *name); +/** Proxy receive cleanup and deallocation. */ +static void pdlua_proxyreceive_free (t_pdlua_proxyreceive *r /**< The proxy receive to free. */); +/** Register the proxy receive class with Pd. */ +static void pdlua_proxyreceive_setup (void); +/** Proxy clock 'bang' method. */ +static void pdlua_proxyclock_bang (t_pdlua_proxyclock *c); +/** Proxy clock allocation and initialization. */ +static t_pdlua_proxyclock *pdlua_proxyclock_new (struct pdlua *owner); +/** Register the proxy clock class with Pd. */ +static void pdlua_proxyclock_setup (void); +/** Dump an array of atoms into a Lua table. */ +static void pdlua_pushatomtable (int argc, t_atom *argv); +/** Pd object constructor. */ +static t_pdlua *pdlua_new (t_symbol *s, int argc, t_atom *argv); +/** Pd object destructor. */ +static void pdlua_free (t_pdlua *o ); +static void pdlua_stack_dump (lua_State *L); +/** a handler for the open item in the right-click menu (mrpeach 20111025) */ +/** Here we find the lua code for the object and open it in an editor */ +static void pdlua_menu_open (t_pdlua *o); +/** Lua class registration. This is equivalent to the "setup" method for an ordinary Pd class */ +static int pdlua_class_new (lua_State *L); +/** Lua object creation. */ +static int pdlua_object_new (lua_State *L); +/** Lua object inlet creation. */ +static int pdlua_object_createinlets (lua_State *L); +/** Lua object outlet creation. */ +static int pdlua_object_createoutlets (lua_State *L); +/** Lua object receive creation. */ +static int pdlua_receive_new (lua_State *L); +/** Lua object receive destruction. */ +static int pdlua_receive_free (lua_State *L); +/** Lua object clock creation. */ +static int pdlua_clock_new (lua_State *L); +/** Lua proxy clock delay. */ +static int pdlua_clock_delay (lua_State *L); +/** Lua proxy clock set. */ +static int pdlua_clock_set (lua_State *L); +/** Lua proxy clock unset. */ +static int pdlua_clock_unset (lua_State *L); +/** Lua proxy clock destruction. */ +static int pdlua_clock_free (lua_State *L); +/** Lua object destruction. */ +static int pdlua_object_free (lua_State *L); +/** Dispatch Pd inlet messages to Lua objects. */ +static void pdlua_dispatch (t_pdlua *o, unsigned int inlet, t_symbol *s, int argc, t_atom *argv); +/** Dispatch Pd receive messages to Lua objects. */ +static void pdlua_receivedispatch (t_pdlua_proxyreceive *r, t_symbol *s, int argc, t_atom *argv); +/** Dispatch Pd clock messages to Lua objects. */ +static void pdlua_clockdispatch(t_pdlua_proxyclock *clock); +/** Convert a Lua table into a Pd atom array. */ +static t_atom *pdlua_popatomtable (lua_State *L, int *count, t_pdlua *o); +/** Send a message from a Lua object outlet. */ +static int pdlua_outlet (lua_State *L); +/** Send a message from a Lua object to a Pd receiver. */ +static int pdlua_send (lua_State *L); +/** Set a [value] object's value. */ +static int pdlua_setvalue (lua_State *L); +/** Get a [value] object's value. */ +static int pdlua_getvalue (lua_State *L); +/** Get a [table] object's array. */ +static int pdlua_getarray (lua_State *L); +/** Read from a [table] object's array. */ +static int pdlua_readarray (lua_State *L); +/** Write to a [table] object's array. */ +static int pdlua_writearray (lua_State *L); +/** Redraw a [table] object's graph. */ +static int pdlua_redrawarray (lua_State *L); +/** Post to Pd's console. */ +static int pdlua_post (lua_State *L); +/** Report an error from a Lua object to Pd's console. */ +static int pdlua_error (lua_State *L); +static void pdlua_setrequirepath (lua_State *L, const char *path); +static void pdlua_clearrequirepath (lua_State *L); +/** Run a Lua script using Pd's path. */ +static int pdlua_dofile (lua_State *L); +/** Initialize the pd API for Lua. */ +static void pdlua_init (lua_State *L); +/** Pd loader hook for loading and executing Lua scripts. */ +static int pdlua_loader_legacy (t_canvas *canvas, char *name); +/** Start the Lua runtime and register our loader hook. */ +#ifdef _WIN32 +__declspec(dllexport) +#endif +void pdlua_setup (void); +/* end prototypes*/ + +/* globals */ +struct pdlua_proxyinlet; +struct pdlua_proxyreceive; +struct pdlua_proxyclock; +/** Proxy inlet class pointer. */ +static t_class *pdlua_proxyinlet_class; +/** Proxy receive class pointer. */ +static t_class *pdlua_proxyreceive_class; +/** Proxy clock class pointer. */ +static t_class *pdlua_proxyclock_class; + +/** Lua file reader callback. */ +static const char *pdlua_reader +( + lua_State *L, /**< Lua interpreter state. */ + void *rr, /**< Lua file reader state. */ + size_t *size /**< How much data we have read. */ +) +{ + t_pdlua_readerdata *r = rr; + ssize_t s; + PDLUA_DEBUG("pdlua_reader: fd is %d", r->fd); + s = read(r->fd, r->buffer, MAXPDSTRING-2); + PDLUA_DEBUG("pdlua_reader: s is %ld", s);//////// + if (s <= 0) + { + *size = 0; + return NULL; + } + else + { + *size = s; + return r->buffer; + } +} + +/** Proxy inlet 'anything' method. */ +static void pdlua_proxyinlet_anything +( + t_pdlua_proxyinlet *p, /**< The proxy inlet that received the message. */ + t_symbol *s, /**< The message selector. */ + int argc, /**< The message length. */ + t_atom *argv /**< The atoms in the message. */ +) +{ + pdlua_dispatch(p->owner, p->id, s, argc, argv); +} + +/** Proxy inlet initialization. */ +static void pdlua_proxyinlet_init +( + t_pdlua_proxyinlet *p, /**< The proxy inlet to initialize. */ + struct pdlua *owner, /**< The owning object. */ + unsigned int id /**< The inlet number. */ +) +{ + p->pd = pdlua_proxyinlet_class; + p->owner = owner; + p->id = id; +} + +/** Register the proxy inlet class with Pd. */ +static void pdlua_proxyinlet_setup(void) +{ + pdlua_proxyinlet_class = class_new(gensym("pdlua proxy inlet"), 0, 0, sizeof(t_pdlua_proxyinlet), 0, 0); + class_addanything(pdlua_proxyinlet_class, pdlua_proxyinlet_anything); +} + +/** Proxy receive 'anything' method. */ +static void pdlua_proxyreceive_anything( + t_pdlua_proxyreceive *r, /**< The proxy receive that received the message. */ + t_symbol *s, /**< The message selector. */ + int argc, /**< The message length. */ + t_atom *argv /**< The atoms in the message. */ +) +{ + pdlua_receivedispatch(r, s, argc, argv); +} + +/** Proxy receive allocation and initialization. */ +static t_pdlua_proxyreceive *pdlua_proxyreceive_new +( + struct pdlua *owner, /**< The owning object. */ + t_symbol *name /**< The symbol to bind to. */ +) +{ + t_pdlua_proxyreceive *r = malloc(sizeof(t_pdlua_proxyreceive)); + r->pd = pdlua_proxyreceive_class; + r->owner = owner; + r->name = name; + pd_bind(&r->pd, r->name); + return r; +} + +/** Proxy receive cleanup and deallocation. */ +static void pdlua_proxyreceive_free(t_pdlua_proxyreceive *r /**< The proxy receive to free. */) +{ + pd_unbind(&r->pd, r->name); + r->pd = NULL; + r->owner = NULL; + r->name = NULL; + free(r); +} + +/** Register the proxy receive class with Pd. */ +static void pdlua_proxyreceive_setup() +{ + pdlua_proxyreceive_class = class_new(gensym("pdlua proxy receive"), 0, 0, sizeof(t_pdlua_proxyreceive), 0, 0); + class_addanything(pdlua_proxyreceive_class, pdlua_proxyreceive_anything); +} + +/** Proxy clock 'bang' method. */ +static void pdlua_proxyclock_bang(t_pdlua_proxyclock *c /**< The proxy clock that received the message. */) +{ + pdlua_clockdispatch(c); +} + +/** Proxy clock allocation and initialization. */ +static t_pdlua_proxyclock *pdlua_proxyclock_new +( + struct pdlua *owner /**< The object to forward messages to. */ +) +{ + t_pdlua_proxyclock *c = malloc(sizeof(t_pdlua_proxyclock)); + c->pd = pdlua_proxyclock_class; + c->owner = owner; + c->clock = clock_new(c, (t_method) pdlua_proxyclock_bang); + return c; +} + +/** Register the proxy clock class with Pd. */ +static void pdlua_proxyclock_setup(void) +{ + pdlua_proxyclock_class = class_new(gensym("pdlua proxy clock"), 0, 0, sizeof(t_pdlua_proxyclock), 0, 0); +} + +/** Dump an array of atoms into a Lua table. */ +static void pdlua_pushatomtable +( + int argc, /**< The number of atoms in the array. */ + t_atom *argv /**< The array of atoms. */ +) +{ + int i; + + PDLUA_DEBUG("pdlua_pushatomtable: stack top %d", lua_gettop(L)); + lua_newtable(L); + for (i = 0; i < argc; ++i) + { + lua_pushnumber(L, i+1); + switch (argv[i].a_type) + { + case A_FLOAT: + lua_pushnumber(L, argv[i].a_w.w_float); + break; + case A_SYMBOL: + lua_pushstring(L, argv[i].a_w.w_symbol->s_name); + break; + case A_POINTER: /* FIXME: check experimentality */ + lua_pushlightuserdata(L, argv[i].a_w.w_gpointer); + break; + default: + error("lua: zomg weasels!"); + lua_pushnil(L); + break; + } + lua_settable(L, -3); + } + PDLUA_DEBUG("pdlua_pushatomtable: end. stack top %d", lua_gettop(L)); +} + +/** Pd object constructor. */ +static t_pdlua *pdlua_new +( + t_symbol *s, /**< The construction message selector. */ + int argc, /**< The construction message atom count. */ + t_atom *argv /**< The construction message atoms. */ +) +{ + int i; + PDLUA_DEBUG("pdlua_new: s->s_name is %s", s->s_name); + for (i = 0; i < argc; ++i) + { + switch (argv[i].a_type) + { + case A_FLOAT: + PDLUA_DEBUG2("argv[%d]: %f", i, argv[i].a_w.w_float); + break; + case A_SYMBOL: + PDLUA_DEBUG2("argv[%d]: %s", i, argv[i].a_w.w_symbol->s_name); + break; + default: + error("pdlua_new: bad argument type"); // should never happen + return NULL; + } + } + PDLUA_DEBUG("pdlua_new: start with stack top %d", lua_gettop(L)); + lua_getglobal(L, "pd"); + lua_getfield(L, -1, "_constructor"); + lua_pushstring(L, s->s_name); + pdlua_pushatomtable(argc, argv); + PDLUA_DEBUG("pdlua_new: before lua_pcall(L, 2, 1, 0) stack top %d", lua_gettop(L)); + if (lua_pcall(L, 2, 1, 0)) + { + error("pdlua_new: error in constructor for `%s':\n%s", s->s_name, lua_tostring(L, -1)); + lua_pop(L, 2); /* pop the error string and the global "pd" */ + return NULL; + } + else + { + t_pdlua *object = NULL; + PDLUA_DEBUG("pdlua_new: done lua_pcall(L, 2, 1, 0) stack top %d", lua_gettop(L)); + if (lua_islightuserdata(L, -1)) + { + object = lua_touserdata(L, -1); + lua_pop(L, 2);/* pop the userdata and the global "pd" */ + PDLUA_DEBUG2("pdlua_new: before returning object %p stack top %d", object, lua_gettop(L)); + return object; + } + else + { + lua_pop(L, 2);/* pop the userdata and the global "pd" */ + PDLUA_DEBUG("pdlua_new: done FALSE lua_islightuserdata(L, -1)", 0); + return NULL; + } + } +} + +/** Pd object destructor. */ +static void pdlua_free( t_pdlua *o /**< The object to destruct. */) +{ + PDLUA_DEBUG("pdlua_free: stack top %d", lua_gettop(L)); + lua_getglobal(L, "pd"); + lua_getfield (L, -1, "_destructor"); + lua_pushlightuserdata(L, o); + if (lua_pcall(L, 1, 0, 0)) + { + error("lua: error in destructor:\n%s", lua_tostring(L, -1)); + lua_pop(L, 1); /* pop the error string */ + } + lua_pop(L, 1); /* pop the global "pd" */ + PDLUA_DEBUG("pdlua_free: end. stack top %d", lua_gettop(L)); + return; +} + +static void pdlua_stack_dump (lua_State *L) +{ + int i; + int top = lua_gettop(L); + + for (i = 1; i <= top; i++) + { /* repeat for each level */ + int t = lua_type(L, i); + switch (t) + { + case LUA_TSTRING: /* strings */ + printf("`%s'", lua_tostring(L, i)); + break; + + case LUA_TBOOLEAN: /* booleans */ + printf(lua_toboolean(L, i) ? "true" : "false"); + break; + + case LUA_TNUMBER: /* numbers */ + printf("%g", lua_tonumber(L, i)); + break; + + default: /* other values */ + printf("%s", lua_typename(L, t)); + break; + } + printf(" "); /* put a separator */ + } + printf("\n"); /* end the listing */ +} + +/** a handler for the open item in the right-click menu (mrpeach 20111025) */ +/** Here we find the lua code for the object and open it in an editor */ +static void pdlua_menu_open(t_pdlua *o) +{ + const char *name; + const char *path; + char pathname[FILENAME_MAX]; + t_class *class; + + PDLUA_DEBUG("pdlua_menu_open stack top is %d", lua_gettop(L)); + /** Get the scriptname of the object */ + lua_getglobal(L, "pd"); + lua_getfield(L, -1, "_whoami"); + lua_pushlightuserdata(L, o); + if (lua_pcall(L, 1, 1, 0)) + { + error("lua: error in whoami:\n%s", lua_tostring(L, -1)); + lua_pop(L, 2); /* pop the error string and the global "pd" */ + return; + } + name = luaL_checkstring(L, -1); + PDLUA_DEBUG3("pdlua_menu_open: L is %p, name is %s stack top is %d", L, name, lua_gettop(L)); + if (name) + { + if (name[strlen(name)-1] == 'x') + { + /* pdluax is a class, the particular file should loadable by name alone, we hope */ + sprintf(pathname, "%s", name); + lua_pop(L, 2); /* pop name and the global "pd" */ + } + else + { + lua_getglobal(L, "pd"); + lua_getfield(L, -1, "_get_class"); + lua_pushlightuserdata(L, o); + if (lua_pcall(L, 1, 1, 0)) + { + error("lua: error in get_class:\n%s", lua_tostring(L, -1)); + lua_pop(L, 4); /* pop the error string, global "pd", name, global "pd"*/ + return; + } + class = (t_class *)lua_touserdata(L, -1); + path = class->c_externdir->s_name; + sprintf(pathname, "%s/%s", path, name); + lua_pop(L, 4); /* pop class, global "pd", name, global "pd"*/ + } +#if PD_MAJOR_VERSION==0 && PD_MINOR_VERSION<43 + post("Opening %s for editing", pathname); +#else + logpost(NULL, 3, "Opening %s for editing", pathname); +#endif + sys_vgui("::pd_menucommands::menu_openfile {%s}\n", pathname); + } + PDLUA_DEBUG("pdlua_menu_open end. stack top is %d", lua_gettop(L)); +} + +/** Lua class registration. This is equivalent to the "setup" method for an ordinary Pd class */ +static int pdlua_class_new(lua_State *L) +/**< Lua interpreter state. + * \par Inputs: + * \li \c 1 Class name string. + * \par Outputs: + * \li \c 1 Pd class pointer. + * */ +{ + const char *name; + t_class *c; + + name = luaL_checkstring(L, 1); + PDLUA_DEBUG3("pdlua_class_new: L is %p, name is %s stack top is %d", L, name, lua_gettop(L)); + c = class_new(gensym((char *) name), (t_newmethod) pdlua_new, + (t_method) pdlua_free, sizeof(t_pdlua), CLASS_NOINLET, A_GIMME, 0); + +/* a class with a "menu-open" method will have the "Open" item highlighted in the right-click menu */ + class_addmethod(c, (t_method)pdlua_menu_open, gensym("menu-open"), A_NULL);/* (mrpeach 20111025) */ +/**/ + + lua_pushlightuserdata(L, c); + PDLUA_DEBUG("pdlua_class_new: end stack top is %d", lua_gettop(L)); + return 1; +} + +/** Lua object creation. */ +static int pdlua_object_new(lua_State *L) +/**< Lua interpreter state. + * \par Inputs: + * \li \c 1 Pd class pointer. + * \par Outputs: + * \li \c 2 Pd object pointer. + * */ +{ + PDLUA_DEBUG("pdlua_object_new: stack top is %d", lua_gettop(L)); + if (lua_islightuserdata(L, 1)) + { + t_class *c = lua_touserdata(L, 1); + if (c) + { + PDLUA_DEBUG("pdlua_object_new: path is %s", c->c_externdir->s_name); + t_pdlua *o = (t_pdlua *) pd_new(c); + if (o) + { + o->inlets = 0; + o->in = NULL; + o->outlets = 0; + o->out = NULL; + o->canvas = canvas_getcurrent(); + lua_pushlightuserdata(L, o); + PDLUA_DEBUG("pdlua_object_new: success end. stack top is %d", lua_gettop(L)); + return 1; + } + } + } + PDLUA_DEBUG("pdlua_object_new: fail end. stack top is %d", lua_gettop(L)); + return 0; +} + +/** Lua object inlet creation. */ +static int pdlua_object_createinlets(lua_State *L) +/**< Lua interpreter state. + * \par Inputs: + * \li \c 1 Pd object pointer. + * \li \c 2 Number of inlets. + * */ +{ + int i; + + PDLUA_DEBUG("pdlua_object_createinlets: stack top is %d", lua_gettop(L)); + if (lua_islightuserdata(L, 1)) + { + t_pdlua *o = lua_touserdata(L, 1); + if (o) + { + o->inlets = luaL_checknumber(L, 2); + o->in = malloc(o->inlets * sizeof(t_pdlua_proxyinlet)); + for (i = 0; i < o->inlets; ++i) + { + pdlua_proxyinlet_init(&o->in[i], o, i); + inlet_new(&o->pd, &o->in[i].pd, 0, 0); + } + } + } + PDLUA_DEBUG("pdlua_object_createinlets: end. stack top is %d", lua_gettop(L)); + return 0; +} + +/** Lua object outlet creation. */ +static int pdlua_object_createoutlets(lua_State *L) +/**< Lua interpreter state. + * \par Inputs: + * \li \c 1 Pd object pointer. + * \li \c 2 Number of outlets. + * */ +{ + int i; + + PDLUA_DEBUG("pdlua_object_createoutlets: stack top is %d", lua_gettop(L)); + if (lua_islightuserdata(L, 1)) + { + t_pdlua *o = lua_touserdata(L, 1); + if (o) + { + o->outlets = luaL_checknumber(L, 2); + if (o->outlets > 0) + { + o->out = malloc(o->outlets * sizeof(t_outlet *)); + for (i = 0; i < o->outlets; ++i) o->out[i] = outlet_new(&o->pd, 0); + } + else o->out = NULL; + } + } + PDLUA_DEBUG("pdlua_object_createoutlets: end stack top is %d", lua_gettop(L)); + return 0; +} + +/** Lua object receive creation. */ +static int pdlua_receive_new(lua_State *L) +/**< Lua interpreter state. + * \par Inputs: + * \li \c 1 Pd object pointer. + * \li \c 2 Receive name string. + * \par Outputs: + * \li \c 1 Pd receive pointer. + * */ +{ + PDLUA_DEBUG("pdlua_receive_new: stack top is %d", lua_gettop(L)); + if (lua_islightuserdata(L, 1)) + { + t_pdlua *o = lua_touserdata(L, 1); + if (o) + { + const char *name = luaL_checkstring(L, 2); + if (name) + { + t_pdlua_proxyreceive *r = pdlua_proxyreceive_new(o, gensym((char *) name)); /* const cast */ + lua_pushlightuserdata(L, r); + PDLUA_DEBUG("pdlua_receive_new: success end. stack top is %d", lua_gettop(L)); + return 1; + } + } + } + PDLUA_DEBUG("pdlua_receive_new: fail end. stack top is %d", lua_gettop(L)); + return 0; +} + +/** Lua object receive destruction. */ +static int pdlua_receive_free(lua_State *L) +/**< Lua interpreter state. + * \par Inputs: + * \li \c 1 Pd recieve pointer. + * */ +{ + PDLUA_DEBUG("pdlua_receive_free: stack top is %d", lua_gettop(L)); + if (lua_islightuserdata(L, 1)) + { + t_pdlua_proxyreceive *r = lua_touserdata(L, 1); + if (r) pdlua_proxyreceive_free(r); + } + PDLUA_DEBUG("pdlua_receive_free: end. stack top is %d", lua_gettop(L)); + return 0; +} + +/** Lua object clock creation. */ +static int pdlua_clock_new(lua_State *L) +/**< Lua interpreter state. + * \par Inputs: + * \li \c 1 Pd object pointer. + * \par Outputs: + * \li \c 1 Pd clock pointer. + * */ +{ + PDLUA_DEBUG("pdlua_clock_new: stack top is %d", lua_gettop(L)); + if (lua_islightuserdata(L, 1)) + { + t_pdlua *o = lua_touserdata(L, 1); + if (o) + { + t_pdlua_proxyclock *c = pdlua_proxyclock_new(o); + lua_pushlightuserdata(L, c); + PDLUA_DEBUG("pdlua_clock_new: success end. stack top is %d", lua_gettop(L)); + return 1; + } + } + PDLUA_DEBUG("pdlua_clock_new: fail end. stack top is %d", lua_gettop(L)); + return 0; +} + +/** Lua proxy clock delay. */ +static int pdlua_clock_delay(lua_State *L) +/**< Lua interpreter state. + * \par Inputs: + * \li \c 1 Pd clock pointer. + * \li \c 2 Number of milliseconds to delay. + * */ +{ + PDLUA_DEBUG("pdlua_clock_delay: stack top is %d", lua_gettop(L)); + if (lua_islightuserdata(L, 1)) + { + t_pdlua_proxyclock *c = lua_touserdata(L, 1); + if (c) + { + double delaytime = luaL_checknumber(L, 2); + clock_delay(c->clock, delaytime); + } + } + PDLUA_DEBUG("pdlua_clock_delay: end. stack top is %d", lua_gettop(L)); + return 0; +} + +/** Lua proxy clock set. */ +static int pdlua_clock_set(lua_State *L) +/**< Lua interpreter state. + * \par Inputs: + * \li \c 1 Pd clock pointer. + * \li \c 2 Number to set the clock. + * */ +{ + PDLUA_DEBUG("pdlua_clock_set: stack top is %d", lua_gettop(L)); + if (lua_islightuserdata(L, 1)) + { + t_pdlua_proxyclock *c = lua_touserdata(L, 1); + if (c) + { + double systime = luaL_checknumber(L, 2); + clock_set(c->clock, systime); + } + } + PDLUA_DEBUG("pdlua_clock_set: end. stack top is %d", lua_gettop(L)); + return 0; +} + +/** Lua proxy clock unset. */ +static int pdlua_clock_unset(lua_State *L) +/**< Lua interpreter state. + * \par Inputs: + * \li \c 1 Pd clock pointer. + * */ +{ + PDLUA_DEBUG("pdlua_clock_unset: stack top is %d", lua_gettop(L)); + if (lua_islightuserdata(L, 1)) + { + t_pdlua_proxyclock *c = lua_touserdata(L, 1); + if (c) clock_unset(c->clock); + } + PDLUA_DEBUG("pdlua_clock_unset: end. stack top is %d", lua_gettop(L)); + return 0; +} + +/** Lua proxy clock destruction. */ +static int pdlua_clock_free(lua_State *L) +/**< Lua interpreter state. + * \par Inputs: + * \li \c 1 Pd clock pointer. + * */ +{ + PDLUA_DEBUG("pdlua_clock_free: stack top is %d", lua_gettop(L)); + if (lua_islightuserdata(L, 1)) + { + t_pdlua_proxyclock *c = lua_touserdata(L, 1); + if (c) + { + clock_free(c->clock); + free(c); + } + } + PDLUA_DEBUG("pdlua_clock_free: end. stack top is %d", lua_gettop(L)); + return 0; +} + +/** Lua object destruction. */ +static int pdlua_object_free(lua_State *L) +/**< Lua interpreter state. + * \par Inputs: + * \li \c 1 Pd object pointer. + * */ +{ + int i; + + PDLUA_DEBUG("pdlua_object_free: stack top is %d", lua_gettop(L)); + if (lua_islightuserdata(L, 1)) + { + t_pdlua *o = lua_touserdata(L, 1); + if (o) + { + if (o->in) free(o->in); + if(o->out) + { + for (i = 0; i < o->outlets; ++i) outlet_free(o->out[i]); + free(o->out); + o->out = NULL; + } + } + } + PDLUA_DEBUG("pdlua_object_free: end. stack top is %d", lua_gettop(L)); + return 0; +} + +/** Dispatch Pd inlet messages to Lua objects. */ +static void pdlua_dispatch +( + t_pdlua *o, /**< The object that received the message. */ + unsigned int inlet, /**< The inlet that the message arrived at. */ + t_symbol *s, /**< The message selector. */ + int argc, /**< The message length. */ + t_atom *argv /**< The atoms in the message. */ +) +{ + PDLUA_DEBUG("pdlua_dispatch: stack top %d", lua_gettop(L)); + lua_getglobal(L, "pd"); + lua_getfield (L, -1, "_dispatcher"); + lua_pushlightuserdata(L, o); + lua_pushnumber(L, inlet + 1); /* C has 0.., Lua has 1.. */ + lua_pushstring(L, s->s_name); + pdlua_pushatomtable(argc, argv); + if (lua_pcall(L, 4, 0, 0)) + { + pd_error(o, "lua: error in dispatcher:\n%s", lua_tostring(L, -1)); + lua_pop(L, 1); /* pop the error string */ + } + lua_pop(L, 1); /* pop the global "pd" */ + PDLUA_DEBUG("pdlua_dispatch: end. stack top %d", lua_gettop(L)); + return; +} + +/** Dispatch Pd receive messages to Lua objects. */ +static void pdlua_receivedispatch +( + t_pdlua_proxyreceive *r, /**< The proxy receive that received the message. */ + t_symbol *s, /**< The message selector. */ + int argc, /**< The message length. */ + t_atom *argv /**< The atoms in the message. */ +) +{ + PDLUA_DEBUG("pdlua_receivedispatch: stack top %d", lua_gettop(L)); + lua_getglobal(L, "pd"); + lua_getfield (L, -1, "_receivedispatch"); + lua_pushlightuserdata(L, r); + lua_pushstring(L, s->s_name); + pdlua_pushatomtable(argc, argv); + if (lua_pcall(L, 3, 0, 0)) + { + pd_error(r->owner, "lua: error in receive dispatcher:\n%s", lua_tostring(L, -1)); + lua_pop(L, 1); /* pop the error string */ + } + lua_pop(L, 1); /* pop the global "pd" */ + PDLUA_DEBUG("pdlua_receivedispatch: end. stack top %d", lua_gettop(L)); + return; +} + +/** Dispatch Pd clock messages to Lua objects. */ +static void pdlua_clockdispatch( t_pdlua_proxyclock *clock) +/**< The proxy clock that received the message. */ +{ + PDLUA_DEBUG("pdlua_clockdispatch: stack top %d", lua_gettop(L)); + lua_getglobal(L, "pd"); + lua_getfield (L, -1, "_clockdispatch"); + lua_pushlightuserdata(L, clock); + if (lua_pcall(L, 1, 0, 0)) + { + pd_error(clock->owner, "lua: error in clock dispatcher:\n%s", lua_tostring(L, -1)); + lua_pop(L, 1); /* pop the error string */ + } + lua_pop(L, 1); /* pop the global "pd" */ + PDLUA_DEBUG("pdlua_clockdispatch: end. stack top %d", lua_gettop(L)); + return; +} + +/** Convert a Lua table into a Pd atom array. */ +static t_atom *pdlua_popatomtable +( + lua_State *L, /**< Lua interpreter state. + * \par Inputs: + * \li \c -1 Table to convert. + * */ + int *count, /**< Where to store the array length. */ + t_pdlua *o /**< Object reference for error messages. */ +) +{ + int i; + int ok = 1; + t_float f; + const char *s; + void *p; + size_t sl; + t_atom *atoms = NULL; + + PDLUA_DEBUG("pdlua_popatomtable: stack top %d", lua_gettop(L)); + if (lua_istable(L, -1)) + { +#if LUA_VERSION_NUM < 502 + *count = lua_objlen(L, -1); +#else // 5.2 style + *count = lua_rawlen(L, -1); +#endif // LUA_VERSION_NUM < 502 + if (*count > 0) atoms = malloc(*count * sizeof(t_atom)); + i = 0; + lua_pushnil(L); + while (lua_next(L, -2) != 0) + { + if (i == *count) + { + pd_error(o, "lua: error: too many table elements"); + ok = 0; + break; + } + switch (lua_type(L, -1)) + { + case (LUA_TNUMBER): + f = lua_tonumber(L, -1); + SETFLOAT(&atoms[i], f); + break; + case (LUA_TSTRING): + s = lua_tolstring(L, -1, &sl); + if (s) + { + if (strlen(s) != sl) pd_error(o, "lua: warning: symbol munged (contains \\0 in body)"); + SETSYMBOL(&atoms[i], gensym((char *) s)); + } + else + { + pd_error(o, "lua: error: null string in table"); + ok = 0; + } + break; + case (LUA_TLIGHTUSERDATA): /* FIXME: check experimentality */ + p = lua_touserdata(L, -1); + SETPOINTER(&atoms[i], p); + break; + default: + pd_error(o, "lua: error: table element must be number or string or pointer"); + ok = 0; + break; + } + lua_pop(L, 1); + ++i; + } + if (i != *count) + { + pd_error(o, "lua: error: too few table elements"); + ok = 0; + } + } + else + { + pd_error(o, "lua: error: not a table"); + ok = 0; + } + lua_pop(L, 1); + PDLUA_DEBUG("pdlua_popatomtable: end. stack top %d", lua_gettop(L)); + if (ok) return atoms; + if (atoms) free(atoms); + return NULL; +} + +/** Send a message from a Lua object outlet. */ +static int pdlua_outlet(lua_State *L) +/**< Lua interpreter state. + * \par Inputs: + * \li \c 1 Pd object pointer. + * \li \c 2 Outlet number. + * \li \c 3 Message selector string. + * \li \c 4 Message atom table. + * */ +{ + t_pdlua *o; + int out; + size_t sl; + const char *s; + t_symbol *sym; + int count; + t_atom *atoms; + + PDLUA_DEBUG("pdlua_outlet: stack top %d", lua_gettop(L)); + if (lua_islightuserdata(L, 1)) + { + o = lua_touserdata(L, 1); + if (o) + { + if (lua_isnumber(L, 2)) out = lua_tonumber(L, 2) - 1; /* C has 0.., Lua has 1.. */ + else + { + pd_error(o, "lua: error: outlet must be a number"); + lua_pop(L, 4); /* pop all the arguments */ + return 0; + } + if (0 <= out && out < o->outlets) + { + if (lua_isstring(L, 3)) + { + s = lua_tolstring(L, 3, &sl); + sym = gensym((char *) s); /* const cast */ + if (s) + { + if (strlen(s) != sl) pd_error(o, "lua: warning: symbol munged (contains \\0 in body)"); + lua_pushvalue(L, 4); + atoms = pdlua_popatomtable(L, &count, o); + if (count == 0 || atoms) outlet_anything(o->out[out], sym, count, atoms); + else pd_error(o, "lua: error: no atoms??"); + if (atoms) + { + free(atoms); + lua_pop(L, 4); /* pop all the arguments */ + return 0; + } + } + else pd_error(o, "lua: error: null selector"); + } + else pd_error(o, "lua: error: selector must be a string"); + } + else pd_error(o, "lua: error: outlet out of range"); + } + else error("lua: error: no object to outlet from"); + } + else error("lua: error: bad arguments to outlet"); + lua_pop(L, 4); /* pop all the arguments */ + PDLUA_DEBUG("pdlua_outlet: end. stack top %d", lua_gettop(L)); + return 0; +} + +/** Send a message from a Lua object to a Pd receiver. */ +static int pdlua_send(lua_State *L) +/**< Lua interpreter state. + * \par Inputs: + * \li \c 1 Receiver string. + * \li \c 2 Message selector string. + * \li \c 3 Message atom table. + * */ + +{ + size_t receivenamel; + const char *receivename; + t_symbol *receivesym; + size_t selnamel; + const char *selname; + t_symbol *selsym; + int count; + t_atom *atoms; + + PDLUA_DEBUG("pdlua_send: stack top is %d", lua_gettop(L)); + if (lua_isstring(L, 1)) + { + receivename = lua_tolstring(L, 1, &receivenamel); + receivesym = gensym((char *) receivename); /* const cast */ + if (receivesym) + { + if (strlen(receivename) != receivenamel) error("lua: warning: symbol munged (contains \\0 in body)"); + if (lua_isstring(L, 2)) + { + selname = lua_tolstring(L, 2, &selnamel); + selsym = gensym((char *) selname); /* const cast */ + if (selsym) + { + if (strlen(selname) != selnamel) error("lua: warning: symbol munged (contains \\0 in body)"); + lua_pushvalue(L, 3); + atoms = pdlua_popatomtable(L, &count, NULL); + if ((count == 0 || atoms) && (receivesym->s_thing)) typedmess(receivesym->s_thing, selsym, count, atoms); + else error("lua: error: no atoms??"); + if (atoms) + { + free(atoms); + PDLUA_DEBUG("pdlua_send: success end. stack top is %d", lua_gettop(L)); + return 0; + } + } + else error("lua: error: null selector"); + } + else error("lua: error: selector must be a string"); + } + else error("lua: error: null receive name"); + } + else error("lua: error: receive name must be string"); + PDLUA_DEBUG("pdlua_send: fail end. stack top is %d", lua_gettop(L)); + return 0; +} + +/** Set a [value] object's value. */ +static int pdlua_setvalue(lua_State *L) +/**< Lua interpreter state. + * \par Inputs: + * \li \c 1 Value name string. + * \li \c 2 Value number. + * \par Outputs: + * \li \c 1 success (usually depends on a [value] existing or not). + */ +{ + const char *str = luaL_checkstring(L, 1); + t_float val = luaL_checknumber(L, 2); + int err = value_setfloat(gensym(str), val); + + PDLUA_DEBUG("pdlua_setvalue: stack top is %d", lua_gettop(L)); + lua_pushboolean(L, !err); + PDLUA_DEBUG("pdlua_setvalue: end. stack top is %d", lua_gettop(L)); + return 1; +} + +/** Get a [value] object's value. */ +static int pdlua_getvalue(lua_State *L) +/**< Lua interpreter state. + * \par Inputs: + * \li \c 1 Value name string. + * \par Outputs: + * \li \c 1 Value number, or nil for failure. + * */ +{ + const char *str = luaL_checkstring(L, 1); + t_float val; + int err = value_getfloat(gensym(str), &val); + + PDLUA_DEBUG("pdlua_getvalue: stack top is %d", lua_gettop(L)); + if (!err) lua_pushnumber(L, val); + else lua_pushnil(L); + PDLUA_DEBUG("pdlua_getvalue: end. stack top is %d", lua_gettop(L)); + return 1; +} + +/** Get a [table] object's array. */ +static int pdlua_getarray(lua_State *L) +/**< Lua interpreter state. + * \par Inputs: + * \li \c 1 Table name string. + * \par Outputs: + * \li \c 1 Table length, or < 0 for failure. + * \li \c 2 Table pointer, or nil for failure. + * */ +{ + t_garray *a; + int n; + PDLUA_ARRAYTYPE *v; + const char *str = luaL_checkstring(L, 1); + + PDLUA_DEBUG("pdlua_getarray: stack top is %d", lua_gettop(L)); + if (!(a = (t_garray *) pd_findbyclass(gensym(str), garray_class))) + { + lua_pushnumber(L, -1); + PDLUA_DEBUG("pdlua_getarray: end 1. stack top is %d", lua_gettop(L)); + return 1; + } + else if (!PDLUA_ARRAYGRAB(a, &n, &v)) + { + lua_pushnumber(L, -2); + PDLUA_DEBUG("pdlua_getarray: end 2. stack top is %d", lua_gettop(L)); + return 1; + } + else + { + lua_pushnumber(L, n); + lua_pushlightuserdata(L, v); + PDLUA_DEBUG("pdlua_getarray: end 3. stack top is %d", lua_gettop(L)); + return 2; + } +} + +/** Read from a [table] object's array. */ +static int pdlua_readarray(lua_State *L) +/**< Lua interpreter state. + * \par Inputs: + * \li \c 1 Table length number. + * \li \c 2 Table array pointer. + * \li \c 3 Table index number. + * \par Outputs: + * \li \c 1 Table element value, or nil for index out of range. + * */ +{ + int n = luaL_checknumber(L, 1); + PDLUA_ARRAYTYPE *v = lua_islightuserdata(L, 2) ? lua_touserdata(L, 2) : NULL; + int i = luaL_checknumber(L, 3); + + PDLUA_DEBUG("pdlua_readarray: stack top is %d", lua_gettop(L)); + if (0 <= i && i < n && v) + { + lua_pushnumber(L, PDLUA_ARRAYELEM(v, i)); + PDLUA_DEBUG("pdlua_readarray: end 1. stack top is %d", lua_gettop(L)); + return 1; + } + PDLUA_DEBUG("pdlua_readarray: end 2. stack top is %d", lua_gettop(L)); + return 0; +} + +/** Write to a [table] object's array. */ +static int pdlua_writearray(lua_State *L) +/**< Lua interpreter state. + * \par Inputs: + * \li \c 1 Table length number. + * \li \c 2 Table array pointer. + * \li \c 3 Table index number. + * \li \c 4 Table element value number. + * */ +{ + int n = luaL_checknumber(L, 1); + PDLUA_ARRAYTYPE *v = lua_islightuserdata(L, 2) ? lua_touserdata(L, 2) : NULL; + int i = luaL_checknumber(L, 3); + t_float x = luaL_checknumber(L, 4); + + PDLUA_DEBUG("pdlua_writearray: stack top is %d", lua_gettop(L)); + if (0 <= i && i < n && v) PDLUA_ARRAYELEM(v, i) = x; + PDLUA_DEBUG("pdlua_writearray: end. stack top is %d", lua_gettop(L)); + return 0; +} + +/** Redraw a [table] object's graph. */ +static int pdlua_redrawarray(lua_State *L) +/**< Lua interpreter state. + * \par Inputs: + * \li \c 1 Table name string. + * */ +{ + t_garray *a; + const char *str = luaL_checkstring(L, 1); + + PDLUA_DEBUG("pdlua_redrawarray: stack top is %d", lua_gettop(L)); + if ((a = (t_garray *) pd_findbyclass(gensym(str), garray_class))) garray_redraw(a); + PDLUA_DEBUG("pdlua_redrawarray: end. stack top is %d", lua_gettop(L)); + return 0; +} + +/** Post to Pd's console. */ +static int pdlua_post(lua_State *L) +/**< Lua interpreter state. + * \par Inputs: + * \li \c 1 Message string. + * */ +{ + const char *str = luaL_checkstring(L, 1); + PDLUA_DEBUG("pdlua_post: stack top is %d", lua_gettop(L)); + post("%s", str); + PDLUA_DEBUG("pdlua_post: end. stack top is %d", lua_gettop(L)); + return 0; +} + +/** Report an error from a Lua object to Pd's console. */ +static int pdlua_error(lua_State *L) +/**< Lua interpreter state. + * \par Inputs: + * \li \c 1 Pd object pointer. + * \li \c 2 Message string. + * */ +{ + t_pdlua *o; + + + const char *s; + + PDLUA_DEBUG("pdlua_error: stack top is %d", lua_gettop(L)); + if (lua_islightuserdata(L, 1)) + { + o = lua_touserdata(L, 1); + if (o) + { + s = luaL_checkstring(L, 2); + if (s) pd_error(o, "%s", s); + else pd_error(o, "lua: error: null string in error function"); + } + else error("lua: error: null object in error function"); + } + else error("lua: error: bad arguments to error function"); + PDLUA_DEBUG("pdlua_error: end. stack top is %d", lua_gettop(L)); + return 0; +} + +static void pdlua_setrequirepath +( /* FIXME: documentation (is this of any use at all?) */ + lua_State *L, + const char *path +) +{ + PDLUA_DEBUG("pdlua_setrequirepath: stack top %d", lua_gettop(L)); + lua_getglobal(L, "pd"); + lua_pushstring(L, "_setrequirepath"); + lua_gettable(L, -2); + lua_pushstring(L, path); + if (lua_pcall(L, 1, 0, 0) != 0) + { + error("lua: internal error in `pd._setrequirepath': %s", lua_tostring(L, -1)); + lua_pop(L, 1); + } + lua_pop(L, 1); + PDLUA_DEBUG("pdlua_setrequirepath: end. stack top %d", lua_gettop(L)); +} + +static void pdlua_clearrequirepath +( /* FIXME: documentation (is this of any use at all?) */ + lua_State *L +) +{ + PDLUA_DEBUG("pdlua_clearrequirepath: stack top %d", lua_gettop(L)); + lua_getglobal(L, "pd"); + lua_pushstring(L, "_clearrequirepath"); + lua_gettable(L, -2); + if (lua_pcall(L, 0, 0, 0) != 0) + { + error("lua: internal error in `pd._clearrequirepath': %s", lua_tostring(L, -1)); + lua_pop(L, 1); + } + lua_pop(L, 1); + PDLUA_DEBUG("pdlua_clearrequirepath: end. stack top %d", lua_gettop(L)); +} + +/** Run a Lua script using Pd's path. */ +static int pdlua_dofile(lua_State *L) +/**< Lua interpreter state. + * \par Inputs: + * \li \c 1 Pd object pointer. + * \li \c 2 Filename string. + * \par Outputs: + * \li \c * Determined by the script. + * */ +{ + char buf[MAXPDSTRING]; + char *ptr; + t_pdlua_readerdata reader; + int fd; + int n; + const char *filename; + t_pdlua *o; + + PDLUA_DEBUG("pdlua_dofile: stack top %d", lua_gettop(L)); + n = lua_gettop(L); + if (lua_islightuserdata(L, 1)) + { + o = lua_touserdata(L, 1); + if (o) + { + filename = luaL_optstring(L, 2, NULL); + fd = canvas_open(o->canvas, filename, "", buf, &ptr, MAXPDSTRING, 1); + if (fd >= 0) + { + PDLUA_DEBUG("pdlua_dofile path is %s", buf); + //pdlua_setpathname(o, buf);/* change the scriptname to include its path */ + pdlua_setrequirepath(L, buf); + reader.fd = fd; +#if LUA_VERSION_NUM < 502 + if (lua_load(L, pdlua_reader, &reader, filename)) +#else // 5.2 style + if (lua_load(L, pdlua_reader, &reader, filename, NULL)) +#endif // LUA_VERSION_NUM < 502 + { + close(fd); + pdlua_clearrequirepath(L); + lua_error(L); + } + else + { + if (lua_pcall(L, 0, LUA_MULTRET, 0)) + { + pd_error(o, "lua: error running `%s':\n%s", filename, lua_tostring(L, -1)); + lua_pop(L, 1); + close(fd); + pdlua_clearrequirepath(L); + } + else + { + /* succeeded */ + close(fd); + pdlua_clearrequirepath(L); + } + } + } + else pd_error(o, "lua: error loading `%s': canvas_open() failed", filename); + } + else error("lua: error in object:dofile() - object is null"); + } + else error("lua: error in object:dofile() - object is wrong type"); + lua_pushstring(L, buf); /* return the path as well so we can open it later with pdlua_menu_open() */ + PDLUA_DEBUG("pdlua_dofile end. stack top is %d", lua_gettop(L)); + + return lua_gettop(L) - n; +} + +/** Initialize the pd API for Lua. */ +static void pdlua_init(lua_State *L) +/**< Lua interpreter state. */ +{ + lua_newtable(L); + lua_setglobal(L, "pd"); + lua_getglobal(L, "pd"); + lua_pushstring(L, "_iswindows"); +#ifdef _WIN32 + lua_pushboolean(L, 1); +#else + lua_pushboolean(L, 0); +#endif // _WIN32 + lua_settable(L, -3); + lua_pushstring(L, "_register"); + lua_pushcfunction(L, pdlua_class_new); + lua_settable(L, -3); + lua_pushstring(L, "_create"); + lua_pushcfunction(L, pdlua_object_new); + lua_settable(L, -3); + lua_pushstring(L, "_createinlets"); + lua_pushcfunction(L, pdlua_object_createinlets); + lua_settable(L, -3); + lua_pushstring(L, "_createoutlets"); + lua_pushcfunction(L, pdlua_object_createoutlets); + lua_settable(L, -3); + lua_pushstring(L, "_destroy"); + lua_pushcfunction(L, pdlua_object_free); + lua_settable(L, -3); + lua_pushstring(L, "_outlet"); + lua_pushcfunction(L, pdlua_outlet); + lua_settable(L, -3); + lua_pushstring(L, "_createreceive"); + lua_pushcfunction(L, pdlua_receive_new); + lua_settable(L, -3); + lua_pushstring(L, "_receivefree"); + lua_pushcfunction(L, pdlua_receive_free); + lua_settable(L, -3); + lua_pushstring(L, "_createclock"); + lua_pushcfunction(L, pdlua_clock_new); + lua_settable(L, -3); + lua_pushstring(L, "_clockfree"); + lua_pushcfunction(L, pdlua_clock_free); + lua_settable(L, -3); + lua_pushstring(L, "_clockset"); + lua_pushcfunction(L, pdlua_clock_set); + lua_settable(L, -3); + lua_pushstring(L, "_clockunset"); + lua_pushcfunction(L, pdlua_clock_unset); + lua_settable(L, -3); + lua_pushstring(L, "_clockdelay"); + lua_pushcfunction(L, pdlua_clock_delay); + lua_settable(L, -3); + lua_pushstring(L, "_dofile"); + lua_pushcfunction(L, pdlua_dofile); + lua_settable(L, -3); + lua_pushstring(L, "send"); + lua_pushcfunction(L, pdlua_send); + lua_settable(L, -3); + lua_pushstring(L, "getvalue"); + lua_pushcfunction(L, pdlua_getvalue); + lua_settable(L, -3); + lua_pushstring(L, "setvalue"); + lua_pushcfunction(L, pdlua_setvalue); + lua_settable(L, -3); + lua_pushstring(L, "_getarray"); + lua_pushcfunction(L, pdlua_getarray); + lua_settable(L, -3); + lua_pushstring(L, "_readarray"); + lua_pushcfunction(L, pdlua_readarray); + lua_settable(L, -3); + lua_pushstring(L, "_writearray"); + lua_pushcfunction(L, pdlua_writearray); + lua_settable(L, -3); + lua_pushstring(L, "_redrawarray"); + lua_pushcfunction(L, pdlua_redrawarray); + lua_settable(L, -3); + lua_pushstring(L, "post"); + lua_pushcfunction(L, pdlua_post); + lua_settable(L, -3); + lua_pushstring(L, "_error"); + lua_pushcfunction(L, pdlua_error); + lua_settable(L, -3); + lua_pop(L, 1); + PDLUA_DEBUG("pdlua_init: end. stack top is %d", lua_gettop(L)); +} + +/** Pd loader hook for loading and executing Lua scripts. */ +static int pdlua_loader_fromfd +( + int fd, /**< file-descriptor of .pd_lua file */ + const char *name, /**< The name of the script (without .pd_lua extension). */ + const char *dirbuf /**< The name of the directory the .pd_lua files lives in */ +) +{ + t_pdlua_readerdata reader; + + PDLUA_DEBUG("pdlua_loader: stack top %d", lua_gettop(L)); + class_set_extern_dir(gensym(dirbuf)); + pdlua_setrequirepath(L, dirbuf); + reader.fd = fd; +#if LUA_VERSION_NUM < 502 + if (lua_load(L, pdlua_reader, &reader, name) || lua_pcall(L, 0, 0, 0)) +#else // 5.2 style + if (lua_load(L, pdlua_reader, &reader, name, NULL) || lua_pcall(L, 0, 0, 0)) +#endif // LUA_VERSION_NUM < 502 + { + error("lua: error loading `%s':\n%s", name, lua_tostring(L, -1)); + lua_pop(L, 1); + pdlua_clearrequirepath(L); + class_set_extern_dir(&s_); + PDLUA_DEBUG("pdlua_loader: script error end. stack top %d", lua_gettop(L)); + return 0; + } + pdlua_clearrequirepath(L); + class_set_extern_dir(&s_); + PDLUA_DEBUG("pdlua_loader: end. stack top %d", lua_gettop(L)); + return 1; +} + +static int pdlua_loader_legacy +( + t_canvas *canvas, /**< Pd canvas to use to find the script. */ + char *name /**< The name of the script (without .pd_lua extension). */ +) +{ + char dirbuf[MAXPDSTRING]; + char *ptr; + int fd; + int result = 0; + + fd = canvas_open(canvas, name, ".pd_lua", dirbuf, &ptr, MAXPDSTRING, 1); + if (fd>=0) + { + result=pdlua_loader_fromfd(fd, name, dirbuf); + sys_close(fd); + } + return result; +} + +static int pdlua_loader_pathwise +( + t_canvas *canvas, /**< Pd canvas to use to find the script. */ + const char *objectname, /**< The name of the script (without .pd_lua extension). */ + const char *path /**< The directory to search for the script */ +) +{ + char dirbuf[MAXPDSTRING]; + char *ptr; + int fd; + int result = 0; + + if(!path) + { + /* we already tried all paths, so skip this */ + return 0; + } + fd = sys_trytoopenone(path, objectname, ".pd_lua", + dirbuf, &ptr, MAXPDSTRING, 1); + /* TODO: try loading <classname>/<classname>.pd_lua */ + if (fd>=0) + { + result=pdlua_loader_fromfd(fd, objectname, dirbuf); + sys_close(fd); + } + return result; +} + + + +/** Start the Lua runtime and register our loader hook. */ +#ifdef _WIN32 +__declspec(dllexport) +#endif +void pdlua_setup(void) +{ + char pd_lua_path[MAXPDSTRING]; + t_pdlua_readerdata reader; + int fd; + int result; + char* pdluaver = "pdlua 0.7.3 (GPL) 2014-2016 Martin Peach et al., based on"; + char* luaver = "lua 0.6~svn (GPL) 2008 Claude Heiland-Allen <claude@mathr.co.uk>"; + char compiled[MAXPDSTRING]; + char luaversionStr[MAXPDSTRING]; + const lua_Number *luaversion = lua_version (NULL); + int lvm, lvl; + +#ifndef BUILD_DATE +# define BUILD_DATE __DATE__" "__TIME__ +#endif + + snprintf(compiled, MAXPDSTRING-1, "pdlua: compiled for pd-%d.%d on %s", + PD_MAJOR_VERSION, PD_MINOR_VERSION, BUILD_DATE); + + lvm = (*luaversion)/100; + lvl = (*luaversion) - (100*lvm); + snprintf(luaversionStr, MAXPDSTRING-1, "Using lua version %d.%d", lvm, lvl); + +#if PD_MAJOR_VERSION==0 && PD_MINOR_VERSION<43 + post(pdluaver); + post(luaver); + post(compiled); + post(luaversionStr); +#else + logpost(NULL, 3, pdluaver); + logpost(NULL, 3, luaver); + logpost(NULL, 3, compiled); + logpost(NULL, 3, luaversionStr); +#endif + pdlua_proxyinlet_setup(); + PDLUA_DEBUG("pdlua pdlua_proxyinlet_setup done", 0); + pdlua_proxyreceive_setup(); + PDLUA_DEBUG("pdlua pdlua_proxyreceive_setup done", 0); + pdlua_proxyclock_setup(); + PDLUA_DEBUG("pdlua pdlua_proxyclock_setup done", 0); +#if LUA_VERSION_NUM < 502 + L = lua_open(); +#else // 5.2 style + L = luaL_newstate(); +#endif // LUA_VERSION_NUM < 502 + PDLUA_DEBUG("pdlua lua_open done L = %p", L); + luaL_openlibs(L); + PDLUA_DEBUG("pdlua luaL_openlibs done", 0); + pdlua_init(L); + PDLUA_DEBUG("pdlua pdlua_init done", 0); + /* "pd.lua" is the Lua part of pdlua, want to keep the C part minimal */ + /* canvas_open can't find pd.lua unless we give the path to pd beforehand like pd -path /usr/lib/extra/pdlua */ + /* To avoid this we can use c_externdir from m_imp.h, struct _class: t_symbol *c_externdir; */ + /* c_externdir is the directory the extern was loaded from and is also the directory contining pd.lua */ + sprintf(pd_lua_path, "%s/pd.lua", pdlua_proxyinlet_class->c_externdir->s_name); /* the full path to pd.lua */ + PDLUA_DEBUG("pd_lua_path %s", pd_lua_path); + fd = open(pd_lua_path, O_RDONLY); +/* fd = canvas_open(canvas_getcurrent(), "pd", ".lua", buf, &ptr, MAXPDSTRING, 1); looks all over and rarely succeeds */ + PDLUA_DEBUG ("pd.lua loaded from %s", pd_lua_path); + PDLUA_DEBUG("pdlua canvas_open done fd = %d", fd); + PDLUA_DEBUG("pdlua_setup: stack top %d", lua_gettop(L)); + if (fd >= 0) + { /* pd.lua was opened */ + reader.fd = fd; +#if LUA_VERSION_NUM < 502 + result = lua_load(L, pdlua_reader, &reader, "pd.lua"); +#else // 5.2 style + result = lua_load(L, pdlua_reader, &reader, "pd.lua", NULL); // mode bt for binary or text +#endif // LUA_VERSION_NUM < 502 + PDLUA_DEBUG ("pdlua lua_load returned %d", result); + if (0 == result) + { + result = lua_pcall(L, 0, 0, 0); + PDLUA_DEBUG ("pdlua lua_pcall returned %d", result); + } + if (0 != result) + //if (lua_load(L, pdlua_reader, &reader, "pd.lua") || lua_pcall(L, 0, 0, 0)) + { + error("lua: error loading `pd.lua':\n%s", lua_tostring(L, -1)); + error("lua: loader will not be registered!"); + error("lua: (is `pd.lua' in Pd's path list?)"); + lua_pop(L, 1); + } + else + { + int maj=0,min=0,bug=0; + sys_getversion(&maj,&min,&bug); + if((maj==0) && (min<47)) + /* before Pd<0.47, the loaders had to iterate over each path themselves */ + sys_register_loader((loader_t)pdlua_loader_legacy); + else + /* since Pd>=0.47, Pd tries the loaders for each path */ + sys_register_loader((loader_t)pdlua_loader_pathwise); + } + close(fd); + } + else + { + error("lua: error loading `pd.lua': canvas_open() failed"); + error("lua: loader will not be registered!"); + } + PDLUA_DEBUG("pdlua_setup: end. stack top %d", lua_gettop(L)); + +} + +/* EOF */ diff --git a/src/pdluax-help.pd b/pdluax-help.pd similarity index 100% rename from src/pdluax-help.pd rename to pdluax-help.pd diff --git a/src/Doxyfile b/src/Doxyfile deleted file mode 100644 index 50a8de044258e6201febf58e874aa0483020b51b..0000000000000000000000000000000000000000 --- a/src/Doxyfile +++ /dev/null @@ -1,1252 +0,0 @@ -# Doxyfile 1.5.1 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = pdlua - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = 0.6 - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = ../doc - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, -# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, -# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, -# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. - -OUTPUT_LANGUAGE = English - -# This tag can be used to specify the encoding used in the generated output. -# The encoding is not always determined by the language that is chosen, -# but also whether or not the output is meant for Windows or non-Windows users. -# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES -# forces the Windows encoding (this is the default for the Windows binary), -# whereas setting the tag to NO uses a Unix-style encoding (the default for -# all platforms other than Windows). - -USE_WINDOWS_ENCODING = NO - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = YES - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like the Qt-style comments (thus requiring an -# explicit @brief command for a brief description. - -JAVADOC_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the DETAILS_AT_TOP tag is set to YES then Doxygen -# will output the detailed description near the top, like JavaDoc. -# If set to NO, the detailed description appears after the member -# documentation. - -DETAILS_AT_TOP = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 8 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = YES - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for Java. -# For instance, namespaces will be presented as packages, qualified scopes -# will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to -# include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. - -BUILTIN_STL_SUPPORT = NO - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = YES - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = YES - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = YES - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = YES - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = YES - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = NO - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from the -# version control system). Doxygen will invoke the program by executing (via -# popen()) the command <command> <input-file>, where <command> is the value of -# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be abled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = "lua.c" - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx -# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py - -FILE_PATTERNS = - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix filesystem feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command <filter> <input-file>, where <filter> -# is the value of the INPUT_FILTER tag, and <input-file> is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER -# is applied to all files. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = YES - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES (the default) -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = YES - -# If the REFERENCES_RELATION tag is set to YES (the default) -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = YES - -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. Otherwise they will link to the documentstion. - -REFERENCES_LINK_SOURCE = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = YES - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = NO - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. - -ENUM_VALUES_PER_LINE = 4 - -# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be -# generated containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, -# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are -# probably better off using the HTML help feature. - -GENERATE_TREEVIEW = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4wide - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = NO - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = NO - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. This is useful -# if you want to understand what is going on. On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_DEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse -# the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option is superseded by the HAVE_DOT option below. This is only a -# fallback. It is recommended to install and use dot, since it yields more -# powerful graphs. - -CLASS_DIAGRAMS = YES - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = YES - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will -# generate a call dependency graph for every global function or class method. -# Note that enabling this option will significantly increase the time of a run. -# So in most cases it will be better to enable call graphs for selected -# functions only using the \callgraph command. - -CALL_GRAPH = YES - -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will -# generate a caller dependency graph for every global function or class method. -# Note that enabling this option will significantly increase the time of a run. -# So in most cases it will be better to enable caller graphs for selected -# functions only using the \callergraph command. - -CALLER_GRAPH = YES - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, jpg, or gif -# If left blank png will be used. - -DOT_IMAGE_FORMAT = png - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width -# (in pixels) of the graphs generated by dot. If a graph becomes larger than -# this value, doxygen will try to truncate the graph, so that it fits within -# the specified constraint. Beware that most browsers cannot cope with very -# large images. - -MAX_DOT_GRAPH_WIDTH = 1024 - -# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height -# (in pixels) of the graphs generated by dot. If a graph becomes larger than -# this value, doxygen will try to truncate the graph, so that it fits within -# the specified constraint. Beware that most browsers cannot cope with very -# large images. - -MAX_DOT_GRAPH_HEIGHT = 1024 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that a graph may be further truncated if the graph's -# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH -# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), -# the graph is not depth-constrained. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, which results in a white background. -# Warning: Depending on the platform used, enabling this option may lead to -# badly anti-aliased labels on the edges of a graph (i.e. they become hard to -# read). - -DOT_TRANSPARENT = NO - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = NO - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- - -# The SEARCHENGINE tag specifies whether or not a search engine should be -# used. If set to NO the values of all tags below this one will be ignored. - -SEARCHENGINE = NO diff --git a/src/config.h b/src/config.h deleted file mode 100644 index ed61e3138873e4bd6b6542786f65fbb89287261e..0000000000000000000000000000000000000000 --- a/src/config.h +++ /dev/null @@ -1,75 +0,0 @@ -/* src/config.h. Generated from config.h.in by configure. */ -/* src/config.h.in. Generated from configure.ac by autoheader. */ - -/* Define to 1 if you have the <inttypes.h> header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if your system has a GNU libc compatible `malloc' function, and - to 0 otherwise. */ -#define HAVE_MALLOC 1 - -/* Define to 1 if you have the <memory.h> header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the <stdint.h> header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the <stdlib.h> header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the <strings.h> header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the <string.h> header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the <sys/types.h> header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the <unistd.h> header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to 1 if your C compiler doesn't accept -c and -o together. */ -/* #undef NO_MINUS_C_MINUS_O */ - -/* Name of package */ -#define PACKAGE "pdlua" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "martin.peach@sympatico.ca" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "pdlua" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "pdlua 0.1" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "pdlua" - -/* Define to the home page for this package. */ -#define PACKAGE_URL "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "0.1" - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Version number of package */ -#define VERSION "0.6" - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - -/* Define to rpl_malloc if the replacement function should be used. */ -/* #undef malloc */ - -/* Define to `unsigned int' if <sys/types.h> does not define. */ -/* #undef size_t */ - -/* Define to `int' if <sys/types.h> does not define. */ -/* #undef ssize_t */