├── .gitignore
├── .travis.yml
├── CMakeLists.txt
├── History.txt
├── LICENSE
├── README.md
├── dist.info
├── doc
└── index.html
├── dox
└── usage.h
├── dub-2.2.5-1.rockspec
├── dub.lua
├── dub
├── CTemplate.lua
├── Class.lua
├── Function.lua
├── Inspector.lua
├── LuaBinder.lua
├── MemoryStorage.lua
├── Namespace.lua
├── OptParser.lua
├── assets
│ ├── Doxyfile
│ └── lua
│ │ ├── class.cpp
│ │ ├── dub
│ │ ├── dub.cpp
│ │ └── dub.h
│ │ └── lib.cpp
└── init.lua
├── scripts
├── build.lua
└── doc.lua
└── test
├── all.lua
├── class_test.lua
├── dub_test.lua
├── fixtures
├── constants
│ ├── Car.h
│ └── types.h
├── inherit
│ ├── Child.h
│ ├── ChildHelper.h
│ ├── ChildHelper.yml
│ ├── GrandParent.h
│ ├── Object.h
│ ├── Orphan.h
│ ├── Parent.h
│ └── child.cpp
├── inherit_hidden
│ └── Mother.h
├── memory
│ ├── CustomDtor.h
│ ├── NoDtor.h
│ ├── Nogc.h
│ ├── Owner.h
│ ├── Pen.h
│ ├── PrivateDtor.h
│ ├── Union.h
│ ├── Withgc.h
│ └── owner.cpp
├── namespace
│ ├── A.h
│ ├── A.yml
│ ├── B.h
│ ├── Nem.yml
│ ├── Out.h
│ ├── TRect.h
│ ├── _global.yml
│ ├── constants.h
│ └── nem.h
├── path.wi$th-[pat]
│ └── Pat.h
├── pointers
│ ├── Abstract.h
│ ├── Box.h
│ ├── Custom.h
│ ├── Vect.h
│ └── vect.cpp
├── simple
│ ├── Doxyfile
│ └── include
│ │ ├── Map2.H
│ │ ├── Reg.h
│ │ ├── simple.h
│ │ └── types.h
├── template
│ ├── Foo.h
│ ├── TRect.h
│ ├── TVect.h
│ └── types.h
└── thread
│ ├── Callback.h
│ ├── Caller.h
│ └── lua_callback.cpp
├── function_test.lua
├── inspect_box2d_test.lua
├── inspect_constants_test.lua
├── inspect_inherit_test.lua
├── inspect_memory_test.lua
├── inspect_namespace_test.lua
├── inspect_pointers_test.lua
├── inspect_simple_test.lua
├── inspect_template_test.lua
├── inspect_thread_test.lua
├── lua_box2d_test.lua
├── lua_constants_test.lua
├── lua_inherit_test.lua
├── lua_memory_test.lua
├── lua_namespace_test.lua
├── lua_pat_test.lua
├── lua_pointers_test.lua
├── lua_simple_test.lua
├── lua_template_test.lua
├── lua_thread_test.lua
├── namespace_test.lua
└── opt_parser_test.lua
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | *.o
3 | *.a
4 | *.so
5 | *.swp
6 | *.swo
7 | build
8 | test/fixtures/Box2D
9 | test/tmp
10 | tmp
11 | /html
12 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: erlang
2 |
3 | # Try using multiple Lua Implementations
4 | env:
5 | - LUA_VERSION='5.1' LUA="lua5.1"
6 | - LUA_VERSION='5.1' LUA="luajit" # Wee need to install lua5.1 or luarocks won't build
7 | - LUA_VERSION='5.2' LUA="lua5.2"
8 | - LUA_VERSION='5.3' LUA="lua"
9 |
10 | branches:
11 | only:
12 | - master
13 |
14 | install:
15 | - test "$LUA_VERSION" = "5.3" || sudo apt-get install lua$LUA_VERSION liblua$LUA_VERSION-dev
16 | - test "$LUA" = "luajit" && git clone http://luajit.org/git/luajit-2.0.git && cd luajit-2.0/ && sudo make install && cd .. || true
17 | - test "$LUA_VERSION" = "5.3" && wget http://www.lua.org/ftp/lua-5.3.0.tar.gz && tar xzf lua-5.3.0.tar.gz && cd lua-5.3.0 && make linux && sudo make install && cd .. || true
18 | - sudo apt-get --no-install-recommends install doxygen
19 | - git clone git://github.com/keplerproject/luarocks.git
20 | - cd luarocks
21 | - ./configure --lua-version=$LUA_VERSION --versioned-rocks-dir
22 | - make build
23 | - sudo make install
24 | - cd ..
25 | # Install testing dependency
26 | - sudo luarocks-$LUA_VERSION install lut
27 | # Build module
28 | - sudo luarocks-$LUA_VERSION make
29 |
30 | # Run tests
31 | script:
32 | - $LUA -v && $LUA test/all.lua
33 |
34 | notifications:
35 | recipients:
36 | - gaspard@teti.ch
37 | email:
38 | on_success: change
39 | on_failure: always
40 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | #
2 | # MACHINE GENERATED FILE. DO NOT EDIT.
3 | #
4 | # CMake build file for dub
5 | #
6 | # This file has been generated by lut.Builder 1.2.1
7 | #
8 |
9 | cmake_minimum_required(VERSION 2.8)
10 | # --------------------------------------------------------------
11 | # dub
12 | # --------------------------------------------------------------
13 | set(MODULE_NAME dub)
14 |
15 | # Where to install Lua files
16 | if(LUA_INSTALL_DIR)
17 | set(INSTALL_PATH ${LUA_INSTALL_DIR})
18 | else(LUA_INSTALL_DIR)
19 | set(INSTALL_PATH "${CMAKE_BINARY_DIR}/lib" CACHE STRING "Install directory path")
20 | endif(LUA_INSTALL_DIR)
21 | message("INSTALL Lua 'dub' TO '${INSTALL_PATH}'")
22 |
23 |
24 | # --------------------------------------------------------------
25 | # module
26 | # --------------------------------------------------------------
27 | add_custom_target(${MODULE_NAME} true)
28 |
29 | # --------------------------------------------------------------
30 | # install
31 | # --------------------------------------------------------------
32 | install(DIRECTORY ${MODULE_NAME}
33 | DESTINATION ${INSTALL_PATH}
34 | )
35 |
36 |
37 |
--------------------------------------------------------------------------------
/History.txt:
--------------------------------------------------------------------------------
1 | == 2.2.5
2 |
3 | * Adding option to use a different name for 'L' parameter (#12).
4 |
5 | == 2.2.4 2015-07-03
6 |
7 | * Adding 'unsigned' as C type for 'number' (#10).
8 |
9 | == 2.2.3 2015-06-26
10 |
11 | * Display warning instead of crash in case of missing ctype.
12 |
13 | == 2.2.2 2015-05-11
14 |
15 | * Compatibility with lua 5.3.
16 | * Fixed 'header_base' when paths contain lua pattern characters (Thanks Hendrik Muhs).
17 | * LuaBinder:bindClass now accepts an options table.
18 |
19 | == 2.2.1 2015-05-05
20 |
21 | * Fixed binding generation for Windows (missing dllexport). Thanks LPGhatguy.
22 | * Fixed string detection in overloaded function decision tree (#7).
23 | * Fixed dependency definitions.
24 | * Fixed Doxyfile to avoid doxygen warnings.
25 | * Fixed test compile warnings.
26 |
27 | == 2.2.0 2014-05-15
28 |
29 | * Major enhancement
30 | * Generate bindings compatible with Lua 5.2.
31 | * Not touching global namespace anymore: 'require' returns the library.
32 | * Moving all 'dub' C++ methods inside 'dub' namespace.
33 | * Replacing 'lubyk' dependency by 'lub'.
34 | * Functions marked as 'ignore' are no longer bound in sub-classes.
35 | * Installs with luarocks.
36 | * Removing 'lib_prefix' option and using 'no_prefix' argument instead.
37 | * Much improved documentation.
38 | * CMake build system.
39 |
40 | == 2.1.0
41 |
42 | * Major enhancement
43 | * Added support for functions (not class methods).
44 | * Anonymous union support.
45 | * Added support for Callbacks from C++.
46 | * Added support for pseudo-attributes (get/set methods).
47 | * Added support for string_format and string_args to customize __tostring from @dub.
48 | * Added support for 'register' option in @dub.
49 | * Added support for custom destructor: 'destructor' option in @dub.
50 | * Added 'namespace' option (support for namespace constants and functions.
51 | * Added :deleted() on all class bindings to detect C++ deleted objects from Lua.
52 | * Optimized 'dub_issdata' when the only type resolution involves userdata.
53 | * Automatically transform operator= to "set" method.
54 | * Added support for @dub name: "xxx" in method.
55 |
56 | * Minor enhancement
57 | * Should not add namespace to typedef of template in namespace.
58 | * Should check doxygen header versions.
59 | * Should create cast for unresolved templated parents.
60 | * Added 'ignore' setting for parser.
61 | * Ignoring 'struct' keyword in param (C++ name scoping rules apply).
62 | * Casting enum types to 'int' instead of double.
63 | * Added 'extra_headers' option to binder.
64 | * Fixed bug with unamed method parameters (Tim Mensch).
65 | * Fixed bug with void parameter (Tim Mensch).
66 | * Fixed bug where lua stack would grow during class registration (Tim Mensch).
67 | * Added 'attr_name_filter' to rename attributes.
68 | * Removed 'yaml' dependency and changed @dub options format.
69 | * Binding all classes now works inside a namespace.
70 | * Added support for custom bindings with default values.
71 | * Added @dub bind: false option to not create bindings.
72 | * Added @dub destructor: false option to not destroy from lua.
73 | * @dub ignore can be used to ignore attributes.
74 | * Warn on nested namespaces instead of crash.
75 | * Better handling of unknown (opaque) types.
76 | * Added tests for custom global function bindings.
77 | * Should list super classes in C++ visibility order (from child to parent).
78 | * Class.type should reflect class name, not registration name.
79 | * Should not create 'cast' method when superclasses have 'cast: false'.
80 | * Allow multiple 'header_base' paths to remove (removes the first one matching).
81 | * Make sure abstract types are detected even if all pure virtual functions are ignored.
82 | * Support for warn levels (5 = all, 4 = less, ..., 1 = errors).
83 | * Fixed a bug preventing dub from detecting ignored attributes.
84 | * Fixed a bug where dub would not recognize the correct super class.
85 | * Only cast to unknown classes when explicitely declared in @dub.
86 | * Including "lua.h" instead of "dub/lua.h" to not force dub's lua.h.
87 |
88 | == 2.0.0 2012-01-21
89 | * Complete rewrite in Lua
90 | * Most of the previous features are there (but not all).
91 | * Added support for attributes read/write.
92 | * Garbage collection protection for pointers.
93 | * Return value optimization.
94 | * Garbage collection optimization (an idea from Tim Mensch).
95 | * Doxygen parsing (no need to provide xml).
96 | * Added support for nested classes and namespaces.
97 | * Added support for custom bindings on attributes.
98 | * Added 'Doxyfile' option on inspector to allow custom Doxyfile.
99 | * Added support for void *userdata to store Lua types.
100 | * Added support for transparent native table wrapping.
101 | * Added support for abstract types and casting to these types.
102 | * ...
103 |
104 | == 1.1 --- Last version written in Ruby
105 |
106 | * Minor enhancement
107 | * We can omit 'return 0' when defining body with yaml.
108 | * Automatically uses luaDestroy with subclassed with LuaObject.
109 | * Fixed 'deleted' method (should be present when we use LuaObject).
110 |
111 | == 1.0.0
112 |
113 | * Major enhancement
114 | * Support for yaml definition of binding body.
115 | * Support for superclass (reuse of definitions from the super class)
116 |
117 | == 0.7.1
118 |
119 | The tests in this release do not pass, but the generator is really better and works. I just
120 | don't have the time to fix the tests.
121 |
122 | * Major enhancement
123 | * When the object inherits from a LuaObject class, it calls luaInit(L, obj, "foo.Bar")
124 |
125 | == 0.7.0 2011-08-19
126 |
127 | The tests in this release do not pass, but the generator is really better and works. I just
128 | don't have the time to fix the tests.
129 |
130 | * Major enhancements
131 | * Support for finding userdata from lua table ('super').
132 |
133 | == 0.6.7
134 |
135 | * Major enhancements
136 | * Added support for LuaStackSize pseudo return value (enables direct stack manipulation).
137 | * Added support for Qt 'public slot:' declarations.
138 | * Added support for 'ignore' @dub setting.
139 | * Added support for custom (or no) destructors.
140 | * Fixed bugs related to overloaded methods and constructors.
141 | * Added support for const char * return type.
142 | * Added support for delete in C++ and/or Lua (DeletableOutOfLua class).
143 | * Added 'deleted' method when the class can be destroyed out of Lua.
144 | * Added support for custom constructors.
145 | * Giving access to meta-table in libname.ClassName_.
146 | * Changed LuaL_check... for dubL_check... to work in try/catch scope (thanks to Ignacio Burgueño)
147 | * Fixed a bug in argument decision tree when there are default values.
148 | * Fixed error reporting in try/catch to avoid memory leaks (thanks to Ignacio Burgueño)
149 |
150 | == 0.6.6 2010-12-16
151 |
152 | * Major enhancements
153 | * Added support for @dub custom Doxygen tag to set class options.
154 |
155 | == 0.6.5 2010-12-15
156 |
157 | * Major enhancements
158 | * Added support for custom_types (defined with Dub::Lua.function_generator.custom_type).
159 | * Added support for lib_name and other customizations through klass.opts.
160 |
161 | == 0.6.4 2010-07-14
162 |
163 | * 1 enhancement
164 | * Fixed homepage link in gem and documentation.
165 |
166 | == 0.6.3 2010-07-07
167 |
168 | * 1 enhancement
169 | * Should ignore non-public member methods.
170 |
171 | == 0.6.2 2010-07-07
172 |
173 | * 1 enhancement
174 | * Added an option define (DUB_LUA_NO_OPEN) to replace luaopen_xx by luaload_xx
175 | * Added char in the list of 'int' types.
176 |
177 | == 0.6.1 2010-03-12
178 |
179 | * 2 enhancements
180 | * Wrapping all function calls in try.. catch blocks
181 | * Added support for custome templates (customize exception handling for example)
182 |
183 | == 0.6.0 2010-03-11
184 |
185 | * 4 enhancements
186 | * added support for custom tostring methods for classes
187 | * fixed parsing of templated return types
188 | * static class methods are now registered in the namespace as Klass_method
189 | * removing functions and methods with class pointer arguments (could use lists later on)
190 | * better parsing of complex types (including nested template arguments)
191 |
192 | == 0.5.1 2010-03-05
193 |
194 | * 2 minor enhancements
195 | * if an argument is fully specified, should not append namespace
196 | * better handling of boolean values
197 |
198 | == 0.5.0 2010-03-03
199 |
200 | * 1 major enhancement
201 | * initial release and tested with OpenCV bindings for Lua
202 |
203 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | ===============================================================================
2 |
3 | This file is part of the LUBYK project (http://lubyk.org)
4 | Copyright (c) 2007-2012 by Gaspard Bucher (http://teti.ch).
5 |
6 | ------------------------------------------------------------------------------
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining a copy
9 | of this software and associated documentation files (the "Software"), to deal
10 | in the Software without restriction, including without limitation the rights
11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | copies of the Software, and to permit persons to whom the Software is
13 | furnished to do so, subject to the following conditions:
14 |
15 | The above copyright notice and this permission notice shall be included in
16 | all copies or substantial portions of the Software.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 | THE SOFTWARE.
25 |
26 | ===============================================================================
27 |
28 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | dub [](https://travis-ci.org/lubyk/dub)
2 | ===
3 |
4 | Doxygen based Lua binding generator.
5 |
6 | [Documentation](http://doc.lubyk.org/dub.html).
7 |
8 | install
9 | -------
10 |
11 | luarocks install dub
12 |
13 |
14 | Features
15 | --------
16 |
17 | Currently, the parser supports:
18 |
19 | * public methods
20 | * public attributes read/write
21 | * pseudo-attributes read/write by calling getter/setter methods.
22 | * custom bindings (for methods and global functions).
23 | * custom read/write attributes (with void *userdata helper, union handling)
24 | * public class methods
25 | * public static attributes read/write
26 | * pointer to member (gc protected)
27 | * cast(default)/copy/disable const attribute
28 | * member pointer assignment (gc protected)
29 | * natural casting from std::string to string type (can include '\0')
30 | * class instantiation from templates through typedefs
31 | * class alias through typedefs
32 | * bindings for superclass
33 | * automatic casting to base class
34 | * default argument values
35 | * overloaded functions with optimized method selection from arguments
36 | * operator overloading (even operator[], operator() and operator+= and such)
37 | * return value optimization (no copy)
38 | * simple type garbage collection optimization (no __gc method)
39 | * namespace
40 | * nested classes
41 | * class enums
42 | * global enums
43 | * build system
44 | * group multiple bindings in a single library
45 | * rewrite class or library names
46 | * native Lua table wrapping setmetatable({super = obj}, Vect)
47 | * callback from C++ with error handling in Lua (with self.error).
48 | * error function captures current 'print' function and can be used with self._errfunc.
49 | * fully tested
50 | * custom method binding name
51 |
--------------------------------------------------------------------------------
/dist.info:
--------------------------------------------------------------------------------
1 | name = "dub"
2 | version = "2.2.5"
3 |
4 | desc = "Lua binding generator from C/C++ code (uses Doxygen to parse C++ comments)."
5 | author = "Gaspard Bucher"
6 | license = "MIT"
7 | url = "http://doc.lubyk.org/dub.html"
8 | maintainer = "Gaspard Bucher"
9 |
10 | depends = {
11 | "lua >= 5.1, < 5.4",
12 | "lub >= 1.0.4, < 2",
13 | "xml ~> 1",
14 | "yaml ~> 1",
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/doc/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | lub
5 |
6 |
7 | Online documentation
8 | doc.lubyk.org/dub.html
9 |
10 | Generate
11 | lua scripts/doc.lua && open html/index.html
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/dox/usage.h:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | * WARING: THIS IS OLD DOCUMENTATION. We keep it here until we have merged all
4 | * content in source code comments.
5 | *
6 | *
7 | * @page dub_usage Dub Usage
8 | *
9 | * @section custom_bindings Custom Class, Function, and Attribute Bindings
10 | *
11 | * @warning Whether a binding has a semicolon changes its behavior, at least in
12 | * accessor bindings. Should talk about this more, and see where the
13 | * behavior changes.
14 | *
15 | * @subsection dub_method_overrides Method Overrides
16 | *
17 | * @subsubsection dub_gc Mark this function as factory method.
18 | *
19 | * \@dub gc: true
20 | *
21 | * Set this value in a method to mark it as a factory method: In other words,
22 | * it's creating a new object that should be managed by Lua. Only makes sense on
23 | * functions that return a pointer generated by new.
24 | *
25 | * @subsection dub_class_overrides Class Overrides
26 | *
27 | * @subsubsection dub_register Change the name of a class
28 | *
29 | * @paragraph dub_register_1
30 | *
31 | * \@dub register: AlternateName
32 | *
33 | * Registers the class using the given AlternateName instead of its actual name.
34 | * Doesn't change the name of the associated metatable, though.
35 | *
36 | * @subsubsection dub_ignore Ignore a member function
37 | *
38 | * @paragraph dub_ignore_1
39 | *
40 | * \@dub ignore: memberName[, memberName2 ...]
41 | *
42 | * Tell Dub to ignore a member; in other words, don't generate any binding
43 | * information for any functions or member variables with matching names.
44 | *
45 | * @subsubsection dub_super Add parent class information
46 | *
47 | * @paragraph dub_super_1
48 | *
49 | * \@dub super: ParentClass[, ParentClass2]
50 | *
51 | * Set parent classes in Dub that Doxygen doesn't know about. Can also be used
52 | * to add mixins to a class.
53 | *
54 | * @subsubsection dub_bind Set binding for a class.
55 | *
56 | * @paragraph dub_bind_1
57 | *
58 | * \@dub bind: false
59 | *
60 | * Setting to false disables binding.
61 | *
62 | * @subsubsection dub_cast Set casting for a class.
63 | *
64 | * @paragraph dub_cast_1
65 | *
66 | * \@dub cast: false
67 | *
68 | * Setting to false disables casting.
69 | *
70 | * @subsubsection dub_push Mark a function as a "push" function
71 | *
72 | * @paragraph dub_push_1
73 | *
74 | * \@dub push: functionName -- typically "push"
75 | *
76 | * Set the name of the function to push this class onto the Lua stack. The
77 | * signature of the function should match:
78 | *
79 | * @code
80 | * void pushobject(lua_State* L, void* thisPtr,
81 | * const char * className, bool shouldGC);
82 | * @endcode
83 | *
84 | * Instead of "void *", the thisPtr can be defined as a pointer to the
85 | * current class. In most cases the pointer here will be the same as
86 | * this.
87 | *
88 | * The className will be passed in as the string that Dub uses
89 | * to identify the class in question.
90 | *
91 | * The boolean shouldGC will be true if Dub believes Lua should garbage-collect
92 | * the value. In practice this means that the call is being made in the
93 | * constructor of the class, or a method
94 | *
95 | * @subsubsection dub_destructor Set the destructor function for a class.
96 | *
97 | * @paragraph dub_destructor_1
98 | *
99 | * \@dub destructor: functionName
100 | *
101 | * The name of the member function to call to destroy the class. Should call
102 | * "delete this" if that's needed to destroy the underlying object.
103 | *
104 | * @subsubsection dub_destroy_free POD Class Optimization/Destructor Disabling
105 | *
106 | * @paragraph dub_destroy_free_1 Dub Command
107 | * \@dub destroy: 'free'
108 | *
109 | * @paragraph dub_destroy_free_1 Inspector Command
110 | * @code
111 | * local a = inspector.find("classname");
112 | * a.dub = { destroy = "free" }
113 | * @endcode
114 | *
115 | * This enables objects to be created with in-place new, preventing an
116 | * allocation and a copy, and it also completely disables the __gc garbage
117 | * collection callback for the class.
118 | *
119 | * Ideal for POD types that support operators. A vector class Vec2 that supports
120 | * operator+, for example, would be able to create a single extra Lua USERDATA
121 | * with an embedded Vec2 result constructed right in the USERDATA.
122 | *
123 | * @subsubsection dub_class_init Post-Creation Init
124 | *
125 | * @paragraph dub_class_init_1 Dub Command
126 | * @code
127 | * \@dub init: 'luaInit'
128 | * @endcode
129 | *
130 | * @paragraph dub_class_init_2 Inspector Command
131 | * @code
132 | * local a = inspector.find("classname");
133 | * a.dub = { init = "luaInit" }
134 | * @endcode
135 | *
136 | * @paragraph dub_class_init_3 Inspector Command
137 | * Causes Dub to call luaInit function after creating an instance of classname.
138 | * The luaInit function has the form:
139 | *
140 | * @code
141 | * int luaInit( lua_State * L );
142 | * @endcode
143 | *
144 | * This function can be used to do extra post-construction initialization for a
145 | * class.
146 | */
147 |
--------------------------------------------------------------------------------
/dub-2.2.5-1.rockspec:
--------------------------------------------------------------------------------
1 | package = "dub"
2 | version = "2.2.5-1"
3 | source = {
4 | url = 'git://github.com/lubyk/dub',
5 | tag = 'REL-2.2.5',
6 | dir = 'dub',
7 | }
8 | description = {
9 | summary = "Lua binding generator from C/C++ code (uses Doxygen to parse C++ comments).",
10 | detailed = [[
11 | A powerful binding generator for C/C++ code with support for attributes,
12 | callbacks, errors on callbacks, enums, nested classes, operators, public
13 | attributes, etc.
14 |
15 | Full documentation: http://doc.lubyk.org/dub.html
16 | ]],
17 | homepage = "http://doc.lubyk.org/dub.html",
18 | license = "MIT"
19 | }
20 |
21 | dependencies = {
22 | "lua >= 5.1, < 5.4",
23 | "lub >= 1.0.4, < 2",
24 | "xml ~> 1",
25 | "yaml ~> 1",
26 | }
27 | build = {
28 | type = 'builtin',
29 | modules = {
30 | -- Plain Lua files
31 | ['dub' ] = 'dub/init.lua',
32 | ['dub.Class' ] = 'dub/Class.lua',
33 | ['dub.CTemplate' ] = 'dub/CTemplate.lua',
34 | ['dub.Function' ] = 'dub/Function.lua',
35 | ['dub.Inspector' ] = 'dub/Inspector.lua',
36 | ['dub.LuaBinder' ] = 'dub/LuaBinder.lua',
37 | ['dub.MemoryStorage'] = 'dub/MemoryStorage.lua',
38 | ['dub.Namespace' ] = 'dub/Namespace.lua',
39 | ['dub.OptParser' ] = 'dub/OptParser.lua',
40 | },
41 | install = {
42 | -- Assets needed by library.
43 | lua = {
44 | ['dub.assets.Doxyfile' ] = 'dub/assets/Doxyfile',
45 | ['dub.assets.lua.class_cpp' ] = 'dub/assets/lua/class.cpp',
46 | ['dub.assets.lua.dub.dub_cpp' ] = 'dub/assets/lua/dub/dub.cpp',
47 | ['dub.assets.lua.dub.dub_h' ] = 'dub/assets/lua/dub/dub.h',
48 | ['dub.assets.lua.lib_cpp' ] = 'dub/assets/lua/lib.cpp',
49 | },
50 | },
51 | }
52 |
53 |
--------------------------------------------------------------------------------
/dub.lua:
--------------------------------------------------------------------------------
1 | dub/init.lua
--------------------------------------------------------------------------------
/dub/CTemplate.lua:
--------------------------------------------------------------------------------
1 | --[[------------------------------------------------------
2 |
3 | # A C++ template definition.
4 |
5 | (internal) C++ template definition. This is a sub-class of dub.Class.
6 |
7 | --]]------------------------------------------------------
8 | local lub = require 'lub'
9 | local dub = require 'dub'
10 | local lib = lub.class 'dub.CTemplate'
11 | local private = {}
12 |
13 | -- nodoc
14 | lib.template = true
15 |
16 | -- CTemplate is a sub-class of dub.Class
17 | setmetatable(lib, dub.Class)
18 |
19 | -- # Constructor
20 | -- The Constructor is never used. We transform a dub.Class while parsing
21 | -- template parameters.
22 |
23 | -- Returns a dub.Class by resolving the template parameters.
24 | function lib:resolveTemplateParams(parent, name, types)
25 | local name_to_type = {}
26 | name_to_type[self.name] = name
27 | local all_resolved = true
28 | for i, param in ipairs(self.template_params) do
29 | local typ = types[i]
30 | if typ then
31 | name_to_type[param] = typ
32 | else
33 | all_resolved = false
34 | end
35 | end
36 | if all_resolved then
37 | -- Make class
38 | local class = dub.Class {
39 | db = self.db,
40 | parent = parent or self.parent,
41 | name = name,
42 | }
43 | -- Rebuild methods
44 | private.resolveMethods(self, class, name_to_type)
45 | -- Rebuild attributes
46 | if self.has_variables then
47 | private.resolveAttributes(self, class, name_to_type)
48 | end
49 | return class
50 | else
51 | -- Make another template
52 | end
53 | end
54 |
55 | -- nodoc
56 | lib.fullname = dub.Class.fullname
57 |
58 | --=============================================== PRIVATE
59 |
60 | function private:resolveMethods(class, name_to_type)
61 | for method in self:methods() do
62 | local opts = {
63 | db = self.db,
64 | parent = class,
65 | name = method.name,
66 | params_list = private.resolveParams(method, name_to_type),
67 | return_value = private.resolveType(method.return_value, name_to_type),
68 | definition = method.definition,
69 | argsstring = method.argsstring,
70 | location = method.location,
71 | desc = method.desc,
72 | static = method.static,
73 | xml = method.xml,
74 | member = method.member,
75 | dtor = method.dtor,
76 | ctor = method.ctor,
77 | dub = method.dub,
78 | is_set_attr = method.is_set_attr,
79 | is_get_attr = method.is_get_attr,
80 | is_cast = method.is_cast,
81 | }
82 | if method.ctor then
83 | opts.name = class.name
84 | opts.return_value = dub.MemoryStorage.makeType(class.name .. ' *')
85 | elseif method.dtor then
86 | opts.name = '~' .. class.name
87 | end
88 |
89 | local m = dub.Function(opts)
90 | class.cache[m.name] = m
91 | table.insert(class.functions_list, m)
92 | end
93 | end
94 |
95 | function private:resolveAttributes(class, name_to_type)
96 | class.has_variables = true
97 | local list = class.variables_list
98 | for attr in self:attributes() do
99 | table.insert(list, {
100 | type = 'dub.Attribute',
101 | parent = class,
102 | name = attr.name,
103 | ctype = private.resolveType(attr.ctype, name_to_type),
104 | })
105 | end
106 | end
107 |
108 | function private:resolveParams(name_to_type)
109 | local res = {}
110 | for _, param in ipairs(self.params_list) do
111 | local p = {
112 | type = 'dub.Param',
113 | name = param.name,
114 | position = param.position,
115 | ctype = private.resolveType(param.ctype, name_to_type),
116 | }
117 | table.insert(res, p)
118 | end
119 | return res
120 | end
121 |
122 | function private.resolveType(ctype, name_to_type)
123 | if not ctype then
124 | return
125 | end
126 | local resolv = name_to_type[ctype.name]
127 |
128 | if resolv then
129 | local t = dub.MemoryStorage.makeType(resolv)
130 | return dub.MemoryStorage.makeType(resolv)
131 | else
132 | return ctype
133 | end
134 | end
135 |
136 | return lib
137 |
--------------------------------------------------------------------------------
/dub/Class.lua:
--------------------------------------------------------------------------------
1 | --[[------------------------------------------------------
2 | # C++ Class definition.
3 |
4 | (internal) A C++ class/struct definition.
5 |
6 | --]]------------------------------------------------------
7 |
8 | local lub = require 'lub'
9 | local dub = require 'dub'
10 | local lib = lub.class('dub.Class', {
11 | is_class = true,
12 | is_scope = true,
13 | SET_ATTR_NAME = '_set_',
14 | GET_ATTR_NAME = '_get_',
15 | CAST_NAME = '_cast_',
16 | -- Can be overwritten by dub.cast parameter
17 | should_cast = true,
18 | })
19 | local private = {}
20 |
21 | -- # Constructor
22 |
23 | -- Create a new class definition. Most of the attributes are passed with
24 | -- `def`. Usage example:
25 | --
26 | -- local class = dub.Class {
27 | -- -- self can be a class or db (root)
28 | -- db = self.db or self,
29 | -- parent = parent,
30 | -- name = name,
31 | -- xml = elem,
32 | -- xml_headers = {
33 | -- {path = header.dir .. lub.Dir.sep .. elem.refid .. '.xml', dir = header.dir}
34 | -- },
35 | -- }
36 | function lib.new(def)
37 | local self = def or {}
38 | self.cache = {}
39 | self.sorted_cache = {}
40 | self.functions_list = {}
41 | self.variables_list = {}
42 | self.constants_list = {}
43 | self.super_list = {}
44 |
45 | self.xml_headers = self.xml_headers or {}
46 | setmetatable(self, lib)
47 | self:setOpt(self.dub or {})
48 | self:setName(self.name)
49 | if self.dub.ignore == true then
50 | return nil
51 | else
52 | return self
53 | end
54 | end
55 |
56 | -- # Accessors
57 |
58 | -- The fullname of the class in the form of @parent::ClassName@.
59 | function lib:fullname()
60 | if self.parent and self.parent.name then
61 | return self.parent:fullname() .. '::' .. self.name
62 | else
63 | return self.name
64 | end
65 | end
66 |
67 | -- Returns true if the class has variables (public C attributes).
68 | function lib:hasVariables()
69 | if self.has_variables then
70 | return true
71 | end
72 | -- Look in inheritance chain
73 | for super in self:superclasses() do
74 | if super:hasVariables() then
75 | self.has_variables = true
76 | return true
77 | end
78 | end
79 | return false
80 | end
81 |
82 | -- Return true if the class needs a cast method (it has
83 | -- known superclasses).
84 | function lib:needCast()
85 | for super in self:superclasses() do
86 | return true
87 | end
88 | return false
89 | end
90 |
91 | -- Return true if the given function name should be ignored (do not create
92 | -- bindings).
93 | function lib:ignoreFunc(name)
94 | return self.ignore[name] or name == self.dub.push
95 | end
96 |
97 | -- Set the class name and C++ object creation type.
98 | function lib:setName(name)
99 | if not name then
100 | return
101 | end
102 | self.name = name
103 | -- Remove namespace from name
104 | local create_name = ''
105 | local current = self
106 | while current and current.is_scope do
107 | if current ~= self then
108 | create_name = '::' .. create_name
109 | end
110 | create_name = current.name .. create_name
111 | current = current.parent
112 | if current and current.type == 'dub.Namespace' then
113 | break
114 | end
115 | end
116 | self.create_name = create_name .. ' *'
117 | end
118 |
119 | -- Set options (usually from parsed C++ class comment).
120 | function lib:setOpt(opt)
121 | self.dub = opt or {}
122 | self.dub_type = self.dub.type
123 | self.ignore = self.dub.ignore or {}
124 | if type(self.ignore) == 'string' then
125 | self.ignore = { self.ignore,
126 | [self.ignore] = true,
127 | }
128 | end
129 |
130 | if type(self.dub.super) == 'string' then
131 | self.dub.super = { self.dub.super }
132 | end
133 |
134 | if self.dub.abstract then
135 | self.abstract = true
136 | end
137 |
138 | local dtor = self.dub.destructor
139 | if dtor == false then
140 | self.ignore['~'..self.name] = true
141 | elseif dtor then
142 | self.ignore[dtor] = true
143 | end
144 |
145 | -- cast
146 | if self.dub.cast == false then
147 | self.should_cast = false
148 | end
149 | end
150 |
151 | -- # Find
152 |
153 | -- Return the enclosing namespace or nil if none found.
154 | function lib:namespace()
155 | local p = self.parent
156 | while p do
157 | if p.type == 'dub.Namespace' then
158 | return p
159 | else
160 | p = p.parent
161 | end
162 | end
163 | end
164 |
165 | -- Return a child element named `name` or nil if nothing is found. Uses the
166 | -- database internally.
167 | function lib:findChild(name)
168 | private.makeSpecialMethods(self)
169 | return self.db:findChildFor(self, name)
170 | end
171 |
172 | -- Return a method from a given @name@.
173 | -- function lib:method(name)
174 |
175 | -- nodoc
176 | lib.method = lib.findChild
177 |
178 | -- # Iterators
179 |
180 | -- Return an iterator over the superclasses of this class.
181 | function lib:superclasses()
182 | return self.db:superclasses(self)
183 | end
184 |
185 | -- Return an iterator over the constants defined in this class.
186 | function lib:constants()
187 | return self.db:constants(self)
188 | end
189 |
190 | -- Return an iterator over the methods of this class.
191 | function lib:methods()
192 | -- Create --get--, --set-- and ~Destructor if needed.
193 | private.makeSpecialMethods(self)
194 | return self.db:functions(self)
195 | end
196 |
197 | -- Return an iterator over the attributes of this class.
198 | function lib:attributes()
199 | return self.db:variables(self)
200 | end
201 |
202 | -- nodoc
203 | function lib.__call(lib, ...)
204 | -- This lets sub-classes of dub.Class like dub.Namespace or dub.CTemplate
205 | -- use the same call convention to create new objects.
206 | return lib.new(...)
207 | end
208 |
209 | --=============================================== PRIVATE
210 |
211 | function private:makeSpecialMethods()
212 | if self.made_special_methods then
213 | return
214 | end
215 | self.made_special_methods = true
216 | dub.MemoryStorage.makeSpecialMethods(self)
217 | end
218 |
219 | return lib
220 |
--------------------------------------------------------------------------------
/dub/Function.lua:
--------------------------------------------------------------------------------
1 | --[[------------------------------------------------------
2 | # C++ Function definition.
3 |
4 | (internal) A public C++ function or method definition.
5 |
6 | --]]------------------------------------------------------
7 | local lub = require 'lub'
8 | local dub = require 'dub'
9 | local lib = lub.class 'dub.Function'
10 | local private = {}
11 |
12 | -- Create a new function object with `def` settings. Some important fields in
13 | -- `def`:
14 | --
15 | -- + name : Function name.
16 | -- + db : Storage engine (dub.MemoryStorage).
17 | -- + parent : Parent or storage engine if the function is defined in root.
18 | -- + header : Path to C++ header file where this function is declared.
19 | -- + params_list : List of dub.Param definitions for the function arguments.
20 | -- + return_value : Return type definition (see dub.MemoryStorage.makeType).
21 | -- + definition : Full function name as defined (used in comment).
22 | -- + argsstring : Arguments as a single string (used in comment).
23 | -- + location : A String representing the function source file and line.
24 | -- + desc : String description (will be used in a C++ comment in
25 | -- bindings).
26 | -- + static : True if the function is static (static class function or
27 | -- C function).
28 | -- + xml : An xml object representing the function definition.
29 | -- + member : True if the function is a member function (static or not).
30 | -- + dtor : True if the function is the destructor.
31 | -- + ctor : True if the function is a constructor.
32 | -- + dub : "dub" options as parsed from the "dub" C++ comment.
33 | -- + pure_virtual : True if the function is a pure virtual.
34 | function lib.new(def)
35 | local self = def
36 | self.dub = self.dub or {}
37 | self.member = self.parent.is_class and not (self.static or self.ctor)
38 | self.has_defaults = self.params_list.first_default and true
39 | self.header = self.header or self.parent.header
40 | if self.has_defaults then
41 | self.first_default = self.params_list.first_default
42 | -- minimal number of arguments
43 | self.min_arg_size = self.first_default - 1
44 | else
45 | self.min_arg_size = #self.params_list
46 | end
47 | setmetatable(self, lib)
48 | if not self:setName(self.name) then
49 | -- invalid name (usually an unknown operator)
50 | return nil
51 | end
52 |
53 | if self.db:ignored(self:fullname()) or
54 | self.dub.ignore == true or
55 | (self.parent.is_class and self.parent:ignoreFunc(self.name)) then
56 | return nil
57 | end
58 |
59 | self.sign = private.makeSignature(self)
60 | return self
61 | end
62 |
63 | -- # Operator overloading
64 | -- Read this table as 'operator[KEY]' translates into lua function '__[VALUE]'.
65 | -- For example `operator+` becomes `__add`. This works for most methods except
66 | -- for some operators which do not have a lua equivalent (+=, -=, etc).
67 |
68 | lib.OP_TO_NAME = { -- doc
69 | -- local v = foo + bar
70 | ['+'] = 'add',
71 | -- local v = foo - bar
72 | ['-'] = 'sub',
73 | -- local bar = -foo
74 | ['- '] = 'unm',
75 | -- local v = foo * bar
76 | ['*'] = 'mul',
77 | -- local v = foo / bar
78 | ['/'] = 'div',
79 | -- if (foo == bar) ...
80 | ['=='] = 'eq',
81 | -- if (foo < bar) ...
82 | ['<'] = 'lt',
83 | -- if (foo <= bar) ...
84 | ['<='] = 'le',
85 | -- This is the call on the object itself. Example:
86 | --
87 | -- local foo = Foo()
88 | -- foo() --> call
89 | ['()'] = 'call',
90 | -- Table access. When binding this method, integer access is very fast but we
91 | -- must also hand-code metatable access (to get methods) and attribute access.
92 | --
93 | -- It is thus better to avoid this operator for it has a non-negligible cost.
94 | --
95 | -- local x = foo[4]
96 | ['[]'] = 'index',
97 | -- This is not supported in lua due to the fact that all variables are
98 | -- references to objects and the equal sign is used to assign reference. We
99 | -- must therefore use 'set':
100 | --
101 | -- local foo, bar = Simple('I am foo'), Simple('I am bar')
102 | -- -- foo = bar would make 'foo' a pointer to bar, not assign
103 | -- -- values of bar into foo. We must use:
104 | -- foo:set(bar)
105 | -- --> C++ foo.operator=(bar)
106 | ['='] = 'sete',
107 | -- Mutable operator. No equivalent in Lua.
108 | --
109 | -- -- Add 50 into foo, mutating foo.
110 | -- foo:adde(50)
111 | ['+='] = 'adde',
112 | -- Mutable operator. No equivalent in Lua.
113 | --
114 | -- -- Remove 50 from foo, mutating foo.
115 | -- foo:sube(50)
116 | ['-='] = 'sube',
117 | -- Mutable operator. No equivalent in Lua.
118 | --
119 | -- -- Scale foo by 50, mutating foo.
120 | -- foo:mule(50)
121 | ['*='] = 'mule',
122 | -- Mutable operator. No equivalent in Lua.
123 | --
124 | -- -- Divide foo by 50, mutating foo.
125 | -- foo:dive(50)
126 | ['/='] = 'dive',
127 | }
128 |
129 | -- # Accessors
130 |
131 | -- Return the full name of the function (with enclosing namespaces separated
132 | -- by '::'. Example: `foo::Bar::drawLine`.
133 | -- function lib:fullname()
134 |
135 | -- nodoc
136 | lib.fullname = dub.Class.fullname
137 |
138 | -- Full C name for function. This is like #fullname but with the C names in
139 | -- case binding names are different.
140 | function lib:fullcname()
141 | if self.parent and self.parent.name then
142 | return self.parent:fullname() .. '::' .. self.cname
143 | else
144 | return self.cname
145 | end
146 | end
147 |
148 |
149 | -- String representation of the function name with arguments (used in comments).
150 | -- Example: `drawLine(int x, int y, int x2, int y2, const foo.Pen &pen)`
151 | function lib:nameWithArgs()
152 | return self.definition .. self.argsstring
153 | end
154 |
155 | -- Returns true if the function does not throw any C++ exception.
156 | function lib:neverThrows()
157 | return self.throw == 'throw ()' or
158 | self.is_set_attr or
159 | self.is_get_attr or
160 | self.is_cast
161 | end
162 |
163 | -- Set function name and C name.
164 | function lib:setName(name)
165 | self.name = name
166 | if string.match(self.name, '^~') then
167 | self.destructor = true
168 | self.cname = string.gsub(self.name, '~', '_')
169 | elseif string.match(name, '^operator') then
170 | local n = string.match(name, '^operator(.+)$')
171 | local op = self.OP_TO_NAME[n]
172 | if op then
173 | self.cname = 'operator_' .. op
174 | else
175 | return false
176 | end
177 | else
178 | self.cname = self.name
179 | end
180 | return true
181 | end
182 |
183 | -- # Iterators
184 |
185 | -- Return an iterator over the parameters of this function.
186 | function lib:params()
187 | local co = coroutine.create(private.paramsIterator)
188 | return function()
189 | local ok, value = coroutine.resume(co, self)
190 | if ok then
191 | return value
192 | end
193 | end
194 | end
195 |
196 | --=============================================== PRIVATE
197 |
198 | function private:paramsIterator()
199 | for _, param in ipairs(self.params_list) do
200 | coroutine.yield(param)
201 | end
202 | end
203 |
204 | -- Create a string identifying the met type for overloading. This is just
205 | -- a concatenation of param type names.
206 | function private.makeSignature(met)
207 | local res = ''
208 | for param in met:params() do
209 | if res ~= '' then
210 | res = res .. ', '
211 | end
212 | res = res .. param.ctype.name
213 | end
214 | return res
215 | end
216 |
217 | return lib
218 |
--------------------------------------------------------------------------------
/dub/Inspector.lua:
--------------------------------------------------------------------------------
1 | --[[------------------------------------------------------
2 |
3 | # Inspector
4 |
5 | The Inspector 'knows' about the functions and classes
6 | and can answer queries.
7 |
8 | --]]------------------------------------------------------
9 | local lub = require 'lub'
10 | local dub = require 'dub'
11 | local lib = lub.class 'dub.Inspector'
12 | local private = {}
13 |
14 |
15 | -- Create a new inspector by providing sources to scan. All upercase fields in
16 | -- `opts` correspond to options used by Doxygen. The `opts` table can
17 | -- contain the following keys (keys in parenthesis are optional):
18 | --
19 | -- + INPUT : List of source files separated by spaces (doxygen format). The
20 | -- sources can also be passed as a table.
21 | -- + (html) : Generate html documentation along the way (implies `keep_xml`).
22 | -- + (keep_xml) : Keep xml generated by Doxygen (used for debugging purposes).
23 | -- + (Doxyfile) : Custom Doxyfile to pass to Doxygen parser.
24 | -- + (PREDEFINED) : Defines to use by Doxygen during parsing (usually to remove
25 | -- unwanted clutter from "ATTRIBUTE_ALIGNED16" or
26 | -- "SIMD_FORCE_INLINE" kind of macros.
27 | -- + (EXCLUDE_PATTERNS) : Doxygen option to exclude files and/or directories.
28 | -- + (FILE_PATTERNS) : Doxygen option for header file name patterns such as `*.h *.hpp`.
29 | -- + (doc_dir) : Directory to store generated xml and html.
30 | -- + (ignore) : List of root level classes or functions to ignore.
31 | function lib.new(opts)
32 | local self = {db = dub.MemoryStorage()}
33 | setmetatable(self, lib)
34 | private.parse(self, opts)
35 | return self
36 | end
37 |
38 | -- The command used to call doxygen.
39 | lib.DOXYGEN_CMD = 'doxygen'
40 |
41 |
42 | -- Return a class or function from its name. A class in a namespace is
43 | -- queried with 'foo::Bar'. Uses dub.MemoryStorage.findByFullname.
44 | function lib:find(name)
45 | -- A 'child' of the Inspector can be anything so we
46 | -- have to walk through the files to find what we
47 | -- are asked for.
48 | -- Object lives at the root of the name space.
49 | return self.db:findByFullname(name)
50 | end
51 |
52 | -- Return an interator on all children known to the inspector (can be a function
53 | -- or class). Uses dub.MemoryStorage.children.
54 | function lib:children()
55 | return self.db:children()
56 | end
57 |
58 | -- Try to follow typedefs to resolve a type. Uses dub.MemoryStorage.resolveType
59 | -- internally.
60 | function lib:resolveType(name)
61 | return self.db:resolveType(self.db, name)
62 | end
63 |
64 |
65 | --=============================================== PRIVATE
66 |
67 | -- Add xml headers to the database. If `not_lazy` is set, parse everything
68 | -- directly (not when needed).
69 | function private:parseXml(xml_dir, not_lazy, ignore_list)
70 | self.db:parse(xml_dir, not_lazy, ignore_list)
71 | end
72 |
73 | function private:parse(opts)
74 | if type(opts) == 'string' then
75 | opts = {INPUT = opts}
76 | end
77 | assert(opts and opts.INPUT, "Missing 'INPUT' field")
78 |
79 | if not opts.FILE_PATTERNS then
80 | opts.FILE_PATTERNS = [[
81 | *.c \
82 | *.cc \
83 | *.cxx \
84 | *.cpp \
85 | *.c++ \
86 | *.d \
87 | *.java \
88 | *.ii \
89 | *.ixx \
90 | *.ipp \
91 | *.i++ \
92 | *.inl \
93 | *.h \
94 | *.H \
95 | *.hh \
96 | *.hxx \
97 | *.hpp \
98 | *.h++ \
99 | *.idl \
100 | *.odl \
101 | *.cs \
102 | *.php \
103 | *.php3 \
104 | *.inc \
105 | *.m \
106 | *.mm \
107 | *.dox \
108 | *.py \
109 | *.f90 \
110 | *.f \
111 | *.for \
112 | *.vhd \
113 | *.vhdl
114 | ]]
115 | end
116 |
117 | if opts.html then
118 | opts.GENERATE_HTML = 'YES'
119 | opts.keep_xml = true
120 | end
121 |
122 | local doc_dir = opts.doc_dir
123 | if opts.keep_xml and not doc_dir then
124 | doc_dir = 'dub-doc'
125 | elseif not doc_dir then
126 | doc_dir = 'dub-tmp'
127 | local i = 0
128 | while true do
129 | if lub.exist(doc_dir) then
130 | i = i + 1
131 | doc_dir = string.format('dub-tmp-%i', i)
132 | else
133 | break
134 | end
135 | end
136 | end
137 |
138 | private.execute('mkdir -p ' .. doc_dir)
139 |
140 | local doxypath = opts.Doxyfile
141 | if not doxypath then
142 | doxypath = doc_dir .. '/Doxyfile'
143 | local doxyfile = io.open(doxypath, 'w')
144 |
145 | local doxytemplate = lub.Template {path = lub.path('|assets/Doxyfile')}
146 | if type(opts.INPUT) == 'table' then
147 | opts.INPUT = lub.join(opts.INPUT, ' ')
148 | end
149 | if not opts.EXCLUDE_PATTERNS then
150 | opts.EXCLUDE_PATTERNS = ''
151 | elseif type(opts.EXCLUDE_PATTERNS) == 'table' then
152 | opts.EXCLUDE_PATTERNS = lub.join(opts.EXCLUDE_PATTERNS, ' ')
153 | end
154 | if type(opts.FILE_PATTERNS) == 'table' then
155 | opts.FILE_PATTERNS = lub.join(opts.FILE_PATTERNS, ' ')
156 | end
157 | if type(opts.PREDEFINED) == 'table' then
158 | opts.PREDEFINED = lub.join(opts.PREDEFINED, ' \\\n ')
159 | end
160 |
161 | -- Generate Doxyfile
162 | doxyfile:write(doxytemplate:run({doc_dir = doc_dir, opts = opts}))
163 | doxyfile:close()
164 | end
165 |
166 | -- Generate xml
167 | private.execute(self.DOXYGEN_CMD .. ' ' .. doxypath)
168 | -- Parse xml
169 | private.parseXml(self, doc_dir .. '/xml', true, opts.ignore)
170 | if not opts.keep_xml then
171 | if not opts.doc_dir then
172 | lub.rmTree(doc_dir, true)
173 | else
174 | lub.rmTree(doc_dir .. '/xml', true)
175 | end
176 | end
177 | end
178 |
179 | function private.execute(cmd)
180 | os.execute(cmd)
181 | end
182 |
183 | return lib
184 |
--------------------------------------------------------------------------------
/dub/Namespace.lua:
--------------------------------------------------------------------------------
1 | --[[------------------------------------------------------
2 |
3 | # C++ Namespace definition.
4 |
5 | (internal) A C++ namespace definition with nested classes, enums
6 | and functions.
7 |
8 | --]]------------------------------------------------------
9 | local lub = require 'lub'
10 | local dub = require 'dub'
11 | local lib = lub.class('dub.Namespace', {
12 | is_class = false,
13 | })
14 | local private = {}
15 |
16 | -- Behaves like a class by default
17 | setmetatable(lib, dub.Class)
18 |
19 | --=============================================== dub.Namespace()
20 | function lib.new(self)
21 | local self = self or {}
22 | local name = self.name
23 | self.name = nil
24 | self.const_headers = {}
25 | self = dub.Class(self)
26 | setmetatable(self, lib)
27 | self:setName(name)
28 | return self
29 | end
30 |
31 | function lib:namespaces()
32 | return self.db:namespaces()
33 | end
34 |
35 | function lib:functions()
36 | return self.db:functions(self)
37 | end
38 |
39 | --=============================================== PUBLIC METHODS
40 |
41 | function lib:setName(name)
42 | self.name = name
43 | end
44 |
45 | function lib:fullname()
46 | if self.parent and self.parent.type ~= 'dub.MemoryStorage' then
47 | return self.parent:fullname() .. '::' .. self.name
48 | else
49 | return self.name
50 | end
51 | end
52 |
53 | function lib:children()
54 | return self.db:children(self)
55 | end
56 |
57 | return lib
58 |
--------------------------------------------------------------------------------
/dub/OptParser.lua:
--------------------------------------------------------------------------------
1 | --[[------------------------------------------------------
2 |
3 | # "dub" options parser
4 |
5 | (internal) Simplified yaml parser to retrieve @dub inline options.
6 |
7 | --]]------------------------------------------------------
8 | local lub = require 'lub'
9 | local lib = lub.class 'dub.OptParser'
10 | local insert, match = table.insert, string.match
11 | local private = {}
12 |
13 | --=============================================== dub.Class()
14 | function lib.new(str)
15 | return lib.parse(str)
16 | end
17 |
18 | function lib.parse(str)
19 | local res = {}
20 | for line in str:gmatch("[^\r\n]+") do
21 | local key, value = line:match(' *([A-Za-z_]+): *(.-) *$')
22 | if not key then
23 | return nil
24 | end
25 | local str = value:match('^"(.*)"$') or
26 | value:match("^'(.*)'$")
27 | if str then
28 | -- string
29 | value = str
30 | elseif value == 'false' then
31 | value = false
32 | elseif value == 'true' then
33 | value = true
34 | elseif value:match('^[0-9.]+$') then
35 | value = value * 1
36 | elseif value:match(',') then
37 | local list = {}
38 | for elem in value:gmatch('[^,]+') do
39 | elem = private.strip(elem)
40 | insert(list, elem)
41 | list[elem] = true
42 | end
43 | value = list
44 | end
45 |
46 | res[key] = value
47 | end
48 | return res
49 | end
50 |
51 | --=============================================== PRIVATE
52 |
53 | function private.strip(str)
54 | return match(str, '^ *(.-) *$')
55 | end
56 |
57 | return lib
58 |
--------------------------------------------------------------------------------
/dub/assets/Doxyfile:
--------------------------------------------------------------------------------
1 | # Doxyfile 1.7.5.1
2 | DOXYFILE_ENCODING = UTF-8
3 | PROJECT_NAME = "Dub Bindings"
4 | PROJECT_NUMBER =
5 | PROJECT_BRIEF =
6 | PROJECT_LOGO =
7 | OUTPUT_DIRECTORY = "{{doc_dir}}"
8 | CREATE_SUBDIRS = NO
9 | OUTPUT_LANGUAGE = English
10 | BRIEF_MEMBER_DESC = YES
11 | REPEAT_BRIEF = YES
12 | ABBREVIATE_BRIEF = "The $name class" \
13 | "The $name widget" \
14 | "The $name file" \
15 | is \
16 | provides \
17 | specifies \
18 | contains \
19 | represents \
20 | a \
21 | an \
22 | the
23 | ALWAYS_DETAILED_SEC = NO
24 | INLINE_INHERITED_MEMB = NO
25 | FULL_PATH_NAMES = YES
26 | STRIP_FROM_PATH =
27 | STRIP_FROM_INC_PATH =
28 | SHORT_NAMES = NO
29 | JAVADOC_AUTOBRIEF = NO
30 | QT_AUTOBRIEF = NO
31 | MULTILINE_CPP_IS_BRIEF = NO
32 | INHERIT_DOCS = YES
33 | SEPARATE_MEMBER_PAGES = NO
34 | TAB_SIZE = 8
35 | ALIASES = "dub=\par Bindings info:\n"
36 | OPTIMIZE_OUTPUT_FOR_C = NO
37 | OPTIMIZE_OUTPUT_JAVA = NO
38 | OPTIMIZE_FOR_FORTRAN = NO
39 | OPTIMIZE_OUTPUT_VHDL = NO
40 | EXTENSION_MAPPING =
41 | BUILTIN_STL_SUPPORT = NO
42 | CPP_CLI_SUPPORT = NO
43 | SIP_SUPPORT = NO
44 | IDL_PROPERTY_SUPPORT = YES
45 | DISTRIBUTE_GROUP_DOC = NO
46 | SUBGROUPING = YES
47 | INLINE_GROUPED_CLASSES = NO
48 | TYPEDEF_HIDES_STRUCT = NO
49 | EXTRACT_ALL = YES
50 | EXTRACT_PRIVATE = NO
51 | EXTRACT_STATIC = NO
52 | EXTRACT_LOCAL_CLASSES = YES
53 | EXTRACT_LOCAL_METHODS = NO
54 | EXTRACT_ANON_NSPACES = NO
55 | HIDE_UNDOC_MEMBERS = NO
56 | HIDE_UNDOC_CLASSES = NO
57 | HIDE_FRIEND_COMPOUNDS = NO
58 | HIDE_IN_BODY_DOCS = NO
59 | INTERNAL_DOCS = NO
60 | CASE_SENSE_NAMES = NO
61 | HIDE_SCOPE_NAMES = NO
62 | SHOW_INCLUDE_FILES = YES
63 | FORCE_LOCAL_INCLUDES = NO
64 | INLINE_INFO = YES
65 | SORT_MEMBER_DOCS = YES
66 | SORT_BRIEF_DOCS = NO
67 | SORT_MEMBERS_CTORS_1ST = NO
68 | SORT_GROUP_NAMES = NO
69 | SORT_BY_SCOPE_NAME = NO
70 | STRICT_PROTO_MATCHING = NO
71 | GENERATE_TODOLIST = YES
72 | GENERATE_TESTLIST = YES
73 | GENERATE_BUGLIST = YES
74 | GENERATE_DEPRECATEDLIST= YES
75 | ENABLED_SECTIONS =
76 | MAX_INITIALIZER_LINES = 30
77 | SHOW_USED_FILES = YES
78 | SHOW_FILES = YES
79 | SHOW_NAMESPACES = YES
80 | FILE_VERSION_FILTER =
81 | LAYOUT_FILE =
82 | QUIET = YES
83 | WARNINGS = YES
84 | WARN_IF_UNDOCUMENTED = NO
85 | WARN_IF_DOC_ERROR = NO
86 | WARN_NO_PARAMDOC = NO
87 | WARN_FORMAT = "$file:$line: $text"
88 | WARN_LOGFILE =
89 | INPUT = {{opts.INPUT}}
90 | INPUT_ENCODING = UTF-8
91 | FILE_PATTERNS = {{opts.FILE_PATTERNS}}
92 | RECURSIVE = {{opts.RECURSIVE or 'NO'}}
93 | EXCLUDE =
94 | EXCLUDE_SYMLINKS = NO
95 | EXCLUDE_PATTERNS = {{opts.EXCLUDE_PATTERNS}}
96 | EXCLUDE_SYMBOLS =
97 | EXAMPLE_PATH =
98 | EXAMPLE_PATTERNS = *
99 | EXAMPLE_RECURSIVE = NO
100 | IMAGE_PATH =
101 | INPUT_FILTER =
102 | FILTER_PATTERNS =
103 | FILTER_SOURCE_FILES = NO
104 | FILTER_SOURCE_PATTERNS =
105 | SOURCE_BROWSER = NO
106 | INLINE_SOURCES = NO
107 | STRIP_CODE_COMMENTS = YES
108 | REFERENCED_BY_RELATION = NO
109 | REFERENCES_RELATION = NO
110 | REFERENCES_LINK_SOURCE = YES
111 | USE_HTAGS = NO
112 | VERBATIM_HEADERS = YES
113 | ALPHABETICAL_INDEX = YES
114 | COLS_IN_ALPHA_INDEX = 5
115 | IGNORE_PREFIX =
116 | GENERATE_HTML = {{opts.GENERATE_HTML or 'NO'}}
117 | HTML_OUTPUT = html
118 | HTML_FILE_EXTENSION = .html
119 | HTML_HEADER =
120 | HTML_FOOTER =
121 | HTML_STYLESHEET =
122 | HTML_EXTRA_FILES =
123 | HTML_COLORSTYLE_HUE = 220
124 | HTML_COLORSTYLE_SAT = 100
125 | HTML_COLORSTYLE_GAMMA = 80
126 | HTML_TIMESTAMP = YES
127 | HTML_DYNAMIC_SECTIONS = NO
128 | GENERATE_DOCSET = NO
129 | DOCSET_FEEDNAME = "Doxygen generated docs"
130 | DOCSET_BUNDLE_ID = org.doxygen.Project
131 | DOCSET_PUBLISHER_ID = org.doxygen.Publisher
132 | DOCSET_PUBLISHER_NAME = Publisher
133 | GENERATE_HTMLHELP = NO
134 | CHM_FILE =
135 | HHC_LOCATION =
136 | GENERATE_CHI = NO
137 | CHM_INDEX_ENCODING =
138 | BINARY_TOC = NO
139 | TOC_EXPAND = NO
140 | GENERATE_QHP = NO
141 | QCH_FILE =
142 | QHP_NAMESPACE = org.doxygen.Project
143 | QHP_VIRTUAL_FOLDER = doc
144 | QHP_CUST_FILTER_NAME =
145 | QHP_CUST_FILTER_ATTRS =
146 | QHP_SECT_FILTER_ATTRS =
147 | QHG_LOCATION =
148 | GENERATE_ECLIPSEHELP = NO
149 | ECLIPSE_DOC_ID = org.doxygen.Project
150 | DISABLE_INDEX = NO
151 | ENUM_VALUES_PER_LINE = 4
152 | GENERATE_TREEVIEW = NO
153 | TREEVIEW_WIDTH = 250
154 | EXT_LINKS_IN_WINDOW = NO
155 | FORMULA_FONTSIZE = 10
156 | FORMULA_TRANSPARENT = YES
157 | MATHJAX_RELPATH = http://www.mathjax.org/mathjax
158 | SEARCHENGINE = NO
159 | SERVER_BASED_SEARCH = NO
160 | GENERATE_LATEX = {{opts.GENERATE_LATEX or 'NO'}}
161 | LATEX_OUTPUT = latex
162 | LATEX_CMD_NAME = latex
163 | MAKEINDEX_CMD_NAME = makeindex
164 | COMPACT_LATEX = NO
165 | PAPER_TYPE = a4
166 | EXTRA_PACKAGES =
167 | LATEX_HEADER =
168 | LATEX_FOOTER =
169 | PDF_HYPERLINKS = YES
170 | USE_PDFLATEX = YES
171 | LATEX_BATCHMODE = NO
172 | LATEX_HIDE_INDICES = NO
173 | LATEX_SOURCE_CODE = NO
174 | GENERATE_RTF = NO
175 | RTF_OUTPUT = rtf
176 | COMPACT_RTF = NO
177 | RTF_HYPERLINKS = NO
178 | RTF_STYLESHEET_FILE =
179 | RTF_EXTENSIONS_FILE =
180 | GENERATE_MAN = NO
181 | MAN_OUTPUT = man
182 | MAN_EXTENSION = .3
183 | MAN_LINKS = NO
184 | GENERATE_XML = YES
185 | XML_OUTPUT = xml
186 | XML_PROGRAMLISTING = NO
187 | GENERATE_AUTOGEN_DEF = NO
188 | GENERATE_PERLMOD = NO
189 | PERLMOD_LATEX = NO
190 | PERLMOD_PRETTY = YES
191 | PERLMOD_MAKEVAR_PREFIX =
192 | ENABLE_PREPROCESSING = YES
193 | MACRO_EXPANSION = YES
194 | EXPAND_ONLY_PREDEF = YES
195 | SEARCH_INCLUDES = YES
196 | INCLUDE_PATH =
197 | INCLUDE_FILE_PATTERNS =
198 | PREDEFINED = {{opts.PREDEFINED}}
199 | EXPAND_AS_DEFINED =
200 | SKIP_FUNCTION_MACROS = YES
201 | TAGFILES =
202 | GENERATE_TAGFILE =
203 | ALLEXTERNALS = NO
204 | EXTERNAL_GROUPS = YES
205 | PERL_PATH = /usr/bin/perl
206 | CLASS_DIAGRAMS = NO
207 | MSCGEN_PATH =
208 | HIDE_UNDOC_RELATIONS = YES
209 | HAVE_DOT = NO
210 | DOT_NUM_THREADS = 0
211 | DOT_FONTNAME = Helvetica
212 | DOT_FONTSIZE = 10
213 | DOT_FONTPATH =
214 | CLASS_GRAPH = YES
215 | COLLABORATION_GRAPH = YES
216 | GROUP_GRAPHS = YES
217 | UML_LOOK = NO
218 | TEMPLATE_RELATIONS = NO
219 | INCLUDE_GRAPH = YES
220 | INCLUDED_BY_GRAPH = YES
221 | CALL_GRAPH = NO
222 | CALLER_GRAPH = NO
223 | GRAPHICAL_HIERARCHY = YES
224 | DIRECTORY_GRAPH = YES
225 | DOT_IMAGE_FORMAT = png
226 | DOT_PATH =
227 | DOTFILE_DIRS =
228 | MSCFILE_DIRS =
229 | DOT_GRAPH_MAX_NODES = 50
230 | MAX_DOT_GRAPH_DEPTH = 0
231 | DOT_TRANSPARENT = NO
232 | DOT_MULTI_TARGETS = NO
233 | GENERATE_LEGEND = YES
234 | DOT_CLEANUP = YES
235 |
--------------------------------------------------------------------------------
/dub/assets/lua/class.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | * MACHINE GENERATED FILE. DO NOT EDIT.
4 | *
5 | * Bindings for class {{class.name}}
6 | *
7 | * This file has been generated by dub {{dub.VERSION}}.
8 | */
9 | #include "dub/dub.h"
10 | {% for h in self:headers(class) do %}
11 | #include "{{self:header(h)}}"
12 | {% end %}
13 |
14 | {% if class:namespace() then %}
15 | using namespace {{class:namespace().name}};
16 | {% end %}
17 |
18 | {% for method in class:methods() do %}
19 | /** {{method:nameWithArgs()}}
20 | * {{method.location}}
21 | */
22 | static int {{class.name}}_{{method.cname}}(lua_State *{{self.L}}) {
23 | {% if method:neverThrows() then %}
24 |
25 | {| self:functionBody(class, method) |}
26 | {% else %}
27 | try {
28 | {| self:functionBody(class, method) |}
29 | } catch (std::exception &e) {
30 | lua_pushfstring({{self.L}}, "{{self:bindName(method)}}: %s", e.what());
31 | } catch (...) {
32 | lua_pushfstring({{self.L}}, "{{self:bindName(method)}}: Unknown exception");
33 | }
34 | return dub::error({{self.L}});
35 | {% end %}
36 | }
37 |
38 | {% end %}
39 |
40 | {% if not class:method('__tostring') then %}
41 |
42 | // --=============================================== __tostring
43 | static int {{class.name}}___tostring(lua_State *{{self.L}}) {
44 | {| self:toStringBody(class) |}
45 | return 1;
46 | }
47 | {% end %}
48 |
49 | // --=============================================== METHODS
50 |
51 | static const struct luaL_Reg {{class.name}}_member_methods[] = {
52 | {% for method in class:methods() do %}
53 | { {{string.format('%-15s, %-20s', '"'..self:bindName(method)..'"', class.name .. '_' .. method.cname)}} },
54 | {% end %}
55 | {% if not class:method('__tostring') then %}
56 | { {{string.format('%-15s, %-20s', '"__tostring"', class.name .. '___tostring')}} },
57 | {% end %}
58 | { "deleted" , dub::isDeleted },
59 | { NULL, NULL},
60 | };
61 |
62 | {% if class.has_constants then %}
63 | // --=============================================== CONSTANTS
64 | static const struct dub::const_Reg {{class.name}}_const[] = {
65 | {% for name, scope in class:constants() do %}
66 | { {{string.format('%-15s, %-20s', '"'.. self:constName(name, scope) ..'"', scope .. '::' .. name)}} },
67 | {% end %}
68 | { NULL, 0},
69 | };
70 | {% end %}
71 |
72 | DUB_EXPORT int luaopen_{{self:openName(class)}}(lua_State *{{self.L}})
73 | {
74 | // Create the metatable which will contain all the member methods
75 | luaL_newmetatable({{self.L}}, "{{self:libName(class)}}");
76 | //
77 | {% if class.has_constants then %}
78 | // register class constants
79 | dub::register_const({{self.L}}, {{class.name}}_const);
80 | {% end %}
81 |
82 | // register member methods
83 | dub::fregister({{self.L}}, {{ class.name }}_member_methods);
84 | // setup meta-table
85 | dub::setup({{self.L}}, "{{self:libName(class)}}");
86 | //
87 | return 1;
88 | }
89 |
--------------------------------------------------------------------------------
/dub/assets/lua/dub/dub.h:
--------------------------------------------------------------------------------
1 | /*
2 | ==============================================================================
3 |
4 | This file is part of the DUB bindings generator (http://lubyk.org/dub)
5 | Copyright (c) 2007-2012 by Gaspard Bucher (http://teti.ch).
6 |
7 | ------------------------------------------------------------------------------
8 |
9 | Permission is hereby granted, free of charge, to any person obtaining a copy
10 | of this software and associated documentation files (the "Software"), to deal
11 | in the Software without restriction, including without limitation the rights
12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | copies of the Software, and to permit persons to whom the Software is
14 | furnished to do so, subject to the following conditions:
15 |
16 | The above copyright notice and this permission notice shall be included in
17 | all copies or substantial portions of the Software.
18 |
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 | THE SOFTWARE.
26 |
27 | ==============================================================================
28 | */
29 | #ifndef DUB_BINDING_GENERATOR_DUB_H_
30 | #define DUB_BINDING_GENERATOR_DUB_H_
31 |
32 | #include // strlen strcmp
33 |
34 | #ifndef DUB_ASSERT_KEY
35 | #define DUB_ASSERT_KEY(k, m) strcmp(k, m)
36 | // Use this to avoid the overhead of strcmp in get/set of public attributes.
37 | // if you avoid strcmp, bad keys can map to any other key.
38 | //#define DUB_ASSERT_KEY(k, m) false
39 | #endif
40 | #define KEY_EXCEPTION_MSG "invalid key '%s'"
41 |
42 | typedef int LuaStackSize;
43 |
44 | #ifndef DUB_EXPORT
45 | #ifdef _WIN32
46 | #define DUB_EXPORT extern "C" __declspec(dllexport)
47 | #else
48 | #define DUB_EXPORT extern "C"
49 | #endif
50 | #endif
51 |
52 | #ifdef __cplusplus
53 | extern "C" {
54 | #endif
55 | // We need C linkage because lua lib is compiled as C code
56 | #include
57 | #include
58 | #ifdef __cplusplus
59 | }
60 | #endif
61 |
62 | #include // std::string for Exception
63 | #include // std::exception
64 |
65 | // Helpers to check for explicit 'false' or 'true' return values.
66 | #define lua_isfalse(L,i) (lua_isboolean(L,i) && !lua_toboolean(L,i))
67 | #define lua_istrue(L,i) (lua_isboolean(L,i) && lua_toboolean(L,i))
68 | #define luaL_checkboolean(L,n) (lua_toboolean(L,n))
69 |
70 | struct DubUserdata {
71 | void *ptr;
72 | bool gc;
73 | };
74 |
75 | // ======================================================================
76 | // =============================================== dub::Exception
77 | // ======================================================================
78 | namespace dub {
79 |
80 | /** All exceptions raised by dub::check.. are instances of this class. All
81 | * exceptions deriving from std::exception have their message displayed
82 | * in Lua (through lua_error).
83 | */
84 | class Exception : public std::exception {
85 | std::string message_;
86 | public:
87 | explicit Exception(const char *format, ...);
88 | ~Exception() throw();
89 | const char* what() const throw();
90 | };
91 |
92 | class TypeException : public Exception {
93 | public:
94 | explicit TypeException(lua_State *L, int narg, const char *type, bool is_super = false);
95 | };
96 |
97 | /** This class allows an object to be deleted from either C++ or Lua.
98 | * When Lua deletes the object, dub_destroy is called. When C++ deletes
99 | * the object, the related userdata is invalidated.
100 | */
101 | class Object {
102 | public:
103 | Object() : dub_userdata_(NULL) {}
104 |
105 | /** The destructor marks the userdata as deleted so that Lua no
106 | * longer tries to access it.
107 | */
108 | virtual ~Object() {
109 | if (dub_userdata_) {
110 | // Protect from gc.
111 | dub_userdata_->gc = false;
112 | // Invalidate Lua userdata.
113 | dub_userdata_->ptr = NULL;
114 | }
115 | }
116 |
117 | /** This is called on object instanciation by dub instead of
118 | * dub::pushudata to setup dub_userdata_.
119 | *
120 | */
121 | void dub_pushobject(lua_State *L, void *ptr, const char *type_name, bool gc = true);
122 |
123 | protected:
124 | /** Pointer to the userdata. *userdata => pointer to C++ object.
125 | */
126 | DubUserdata *dub_userdata_;
127 | };
128 |
129 | /** This class creates a 'self' table and prepares a thread
130 | * that can be used for callbacks from C++ to Lua.
131 | */
132 | class Thread : public Object {
133 | public:
134 | Thread()
135 | : dub_L(NULL) {}
136 | /** This is called on object instanciation by dub to create the lua
137 | * thread, prepare the table and setup metamethods. This is
138 | * called instead of dub::pushudata.
139 | *
140 | */
141 | void dub_pushobject(lua_State *L, void *ptr, const char *type_name, bool gc = true);
142 |
143 | /** Push function 'name' found in on the stack with as
144 | * first argument.
145 | *
146 | * Constness is there to make it easy to implement callbacks like
147 | * int rowCount() const, without requiring users to fiddle with constness
148 | * which is not a notion part of Lua anyway.
149 | */
150 | bool dub_pushcallback(const char *name) const;
151 |
152 | /** Push any lua value from self on the stack.
153 | */
154 | void dub_pushvalue(const char *name) const;
155 |
156 | /** Execute the protected call. If an error occurs, dub tries to find
157 | * an 'error' function in and calls this function with the
158 | * error string. If no error function is found, the error message is
159 | * just printed out to stderr.
160 | */
161 | bool dub_call(int param_count, int retval_count) const;
162 |
163 | /** Lua thread that contains on stack position 1. This lua thread
164 | * is public to ease object state manipulation from C++ (but stack *must
165 | * not* be messed up).
166 | */
167 | lua_State *dub_L;
168 |
169 | protected:
170 | /** Type name (allows faster check for cast).
171 | */
172 | const char *dub_typename_;
173 | };
174 |
175 | // ======================================================================
176 | // =============================================== dub::pushclass
177 | // ======================================================================
178 |
179 | // To ease storing a LuaRef in a void* pointer.
180 | struct DubRef {
181 | int ref;
182 |
183 | static int set(lua_State *L, void **ptr, int id) {
184 | if (lua_isnil(L, id)) {
185 | cleanup(L, ptr);
186 | } else {
187 | DubRef *ref;
188 | if (*ptr) {
189 | ref = (DubRef*)*ptr;
190 | luaL_unref(L, LUA_REGISTRYINDEX, ref->ref);
191 | } else {
192 | ref = new DubRef();
193 | *ptr = ref;
194 | }
195 | ref->ref = luaL_ref(L, LUA_REGISTRYINDEX);
196 | }
197 | return 0;
198 | }
199 |
200 | static int push(lua_State *L, void *ptr) {
201 | if (ptr) {
202 | DubRef *ref = (DubRef*)ptr;
203 | lua_rawgeti(L, LUA_REGISTRYINDEX, ref->ref);
204 | return 1;
205 | } else {
206 | return 0;
207 | }
208 | }
209 |
210 | static void cleanup(lua_State *L, void **ptr) {
211 | if (*ptr) {
212 | DubRef *ref = (DubRef*)*ptr;
213 | luaL_unref(L, LUA_REGISTRYINDEX, ref->ref);
214 | delete ref;
215 | *ptr = NULL;
216 | }
217 | }
218 | };
219 |
220 | /** Push a custom type on the stack.
221 | * Since the value is passed as a pointer, we assume it has been created
222 | * using 'new' and Lua can safely call delete when it needs to garbage-
223 | * -collect it.
224 | *
225 | * Constness: we const cast all passed values to ease passing read-only
226 | * arguments without requiring users to fiddle with constness which is not
227 | * a notion part of Lua anyway.
228 | */
229 | void pushudata(lua_State *L, const void *ptr, const char *type_name, bool gc = true);
230 |
231 | template
232 | struct DubFullUserdata {
233 | T *ptr;
234 | T obj;
235 | };
236 |
237 | template
238 | void pushfulldata(lua_State *L, const T &obj, const char *type_name) {
239 | DubFullUserdata *copy = (DubFullUserdata*)lua_newuserdata(L, sizeof(DubFullUserdata));
240 | copy->obj = obj;
241 | // now **copy gives back the object.
242 | copy->ptr = ©->obj;
243 |
244 | // the userdata is now on top of the stack
245 |
246 | // set metatable (contains methods)
247 | luaL_getmetatable(L, type_name);
248 | lua_setmetatable(L, -2);
249 | }
250 |
251 | template
252 | void pushclass(lua_State *L, const T &obj, const char *type_name) {
253 | T *copy = new T(obj);
254 | pushudata(L, (void*)copy, type_name);
255 | }
256 |
257 | // ======================================================================
258 | // =============================================== dub::pushclass2
259 | // ======================================================================
260 |
261 | /** Push a custom type on the stack and give it the pointer to the userdata.
262 | * Passing the userdata enables early deletion from C++ that safely
263 | * invalidates the userdatum by calling
264 | */
265 | template
266 | void pushclass2(lua_State *L, T *ptr, const char *type_name) {
267 | T **userdata = (T**)lua_newuserdata(L, sizeof(T*));
268 | *userdata = ptr;
269 |
270 | // Store pointer in class so that it can set it to NULL on destroy with
271 | // *userdata = NULL
272 | ptr->luaInit((void**)userdata);
273 | //
274 | luaL_getmetatable(L, type_name);
275 | //
276 | lua_setmetatable(L, -2);
277 | //
278 | }
279 |
280 | // ======================================================================
281 | // =============================================== constants
282 | // ======================================================================
283 |
284 | typedef struct const_Reg {
285 | const char *name;
286 | double value;
287 | } const_Reg;
288 |
289 | // register constants in the table at the top
290 | void register_const(lua_State *L, const const_Reg *l);
291 |
292 | // ======================================================================
293 | // =============================================== dub_check ...
294 | // ======================================================================
295 |
296 | // These provide the same funcionality as their equivalent luaL_check... but they
297 | // throw std::exception which can be caught (eventually to call lua_error).
298 | lua_Number checknumber(lua_State *L, int narg) throw(dub::TypeException);
299 | lua_Integer checkinteger(lua_State *L, int narg) throw(dub::TypeException);
300 | const char *checklstring(lua_State *L, int narg, size_t *len) throw(dub::TypeException);
301 | void **checkudata(lua_State *L, int ud, const char *tname, bool keep_mt = false) throw(dub::Exception);
302 |
303 | // Super aware userdata calls (finds userdata inside provided table with table.super).
304 | void **checksdata(lua_State *L, int ud, const char *tname, bool keep_mt = false) throw(dub::Exception);
305 | // Super aware userdata calls that DOES NOT check for dangling pointers (used in
306 | // __gc binding).
307 | void **checksdata_d(lua_State *L, int ud, const char *tname) throw(dub::Exception);
308 | // Return pointer if the type is correct. Used to resolve overloaded functions when there
309 | // is no other alternative (arg count, native types). We return the pointer so that we can
310 | // optimize away the corresponding 'dub_checksdata'.
311 | void **issdata(lua_State *L, int ud, const char *tname, int type);
312 | // Does not throw exceptions. This method behaves exactly like luaL_checkudata but searches
313 | // for table.super before calling lua_error. We cannot use throw() because of differing
314 | // implementations for luaL_error (luajit throws an exception on luaL_error).
315 | void **checksdata_n(lua_State *L, int ud, const char *tname, bool keep_mt = false);
316 |
317 | inline const char *checkstring(lua_State *L, int narg) throw(dub::TypeException) {
318 | return checklstring(L, narg, NULL);
319 | }
320 |
321 | inline int checkboolean(lua_State *L, int narg) throw() {
322 | return lua_toboolean(L, narg);
323 | }
324 |
325 | // This calls lua_Error after preparing the error message with line
326 | // and number.
327 | int error(lua_State *L);
328 |
329 | // This is a Lua binding called whenever we ask for obj:deleted() in Lua
330 | int isDeleted(lua_State *L);
331 |
332 | /** Protect garbage collection from pointers stored in objects or
333 | * retrieved in userdata copies.
334 | */
335 | void protect(lua_State *L, int owner, int original, const char *key);
336 |
337 | /** Prepare index function, setup 'type' field and __call metamethod.
338 | */
339 | void setup(lua_State *L, const char *class_name);
340 |
341 | // sdbm function: taken from http://www.cse.yorku.ca/~oz/hash.html
342 | // This version is slightly adapted to cope with different
343 | // hash sizes (and to be easy to write in Lua).
344 | int hash(const char *str, int sz);
345 |
346 | // Simple debugging function to print stack content.
347 | void printStack(lua_State *L, const char *msg = NULL);
348 |
349 | // Compatibility with luaL_register on lua 5.1 and 5.2
350 | void fregister(lua_State *L, const luaL_Reg *l);
351 |
352 |
353 | } // dub
354 |
355 | #endif // DUB_BINDING_GENERATOR_DUB_H_
356 |
357 |
--------------------------------------------------------------------------------
/dub/assets/lua/lib.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | * MACHINE GENERATED FILE. DO NOT EDIT.
4 | *
5 | * Bindings for library {{lib_name}}
6 | *
7 | * This file has been generated by dub {{dub.VERSION}}.
8 | */
9 | #include "dub/dub.h"
10 | {% for h in self:headers() do %}
11 | #include "{{self:header(h)}}"
12 | {% end %}
13 |
14 | {% for namespace in lib:namespaces() do %}
15 | using namespace {{namespace.name}};
16 | {% end %}
17 |
18 | extern "C" {
19 | {% for _, class in ipairs(classes) do %}
20 | int luaopen_{{self:openName(class)}}(lua_State *{{self.L}});
21 | {% end %}
22 | }
23 |
24 | {% for method in lib:functions() do %}
25 | /** {{method:nameWithArgs()}}
26 | * {{method.location}}
27 | */
28 | static int {{string.gsub(method:fullcname(), '::', '_')}}(lua_State *{{self.L}}) {
29 | {% if method:neverThrows() then %}
30 |
31 | {| self:functionBody(method) |}
32 | {% else %}
33 | try {
34 | {| self:functionBody(method) |}
35 | } catch (std::exception &e) {
36 | lua_pushfstring({{self.L}}, "{{self:libName(method)}}: %s", e.what());
37 | } catch (...) {
38 | lua_pushfstring({{self.L}}, "{{self:libName(method)}}: Unknown exception");
39 | }
40 | return lua_error({{self.L}});
41 | {% end %}
42 | }
43 |
44 | {% end %}
45 | // --=============================================== FUNCTIONS
46 | {% if lib.type == 'dub.Namespace' then %}
47 | // Functions from namespace {{lib.name}}
48 | {% end %}
49 | static const struct luaL_Reg {{lib_name}}_functions[] = {
50 | {% for method in lib:functions() do %}
51 | { {{string.format('%-15s, %-20s', '"'..self:bindName(method)..'"', string.gsub(method:fullcname(), '::', '_'))}} },
52 | {% end %}
53 | { NULL, NULL},
54 | };
55 |
56 | {% if lib.has_constants then %}
57 | // --=============================================== CONSTANTS
58 | {% if lib.type == 'dub.Namespace' then %}
59 | // Functions from namespace {{lib.name}}
60 | {% end %}
61 | static const struct dub::const_Reg {{lib_name}}_const[] = {
62 | {% for name, scope in lib:constants() do %}
63 | { {{string.format('%-15s, %-20s', '"'.. self:constName(name, scope) ..'"', scope .. '::' .. name)}} },
64 | {% end %}
65 | { NULL, 0},
66 | };
67 | {% end %}
68 |
69 | DUB_EXPORT int luaopen_{{self.options.luaopen or lib_name}}(lua_State *{{self.L}}) {
70 | lua_newtable({{self.L}});
71 | //
72 | {% if lib.has_constants then %}
73 | // register global constants
74 | dub::register_const({{self.L}}, {{lib_name}}_const);
75 | {% end %}
76 | dub::fregister({{self.L}}, {{lib_name}}_functions);
77 | //
78 |
79 | {{ self:openClasses(classes) }}
80 | //
81 | return 1;
82 | }
83 |
--------------------------------------------------------------------------------
/scripts/build.lua:
--------------------------------------------------------------------------------
1 | --
2 | -- Update build files for this project
3 | --
4 | local lut = require 'lut'
5 | local lib = require 'dub'
6 |
7 | lut.Builder(lib):make()
8 |
--------------------------------------------------------------------------------
/scripts/doc.lua:
--------------------------------------------------------------------------------
1 | --
2 | -- Generate documentation for this project into 'html' folder
3 | --
4 | local lut = require 'lut'
5 | lut.Doc.make {
6 | sources = {
7 | 'dub',
8 | },
9 | target = 'html',
10 | format = 'html',
11 | header = [[Lubyk documentation
]],
12 | index = [=[
13 | --[[--
14 | # Lubyk documentation
15 |
16 | ## List of available modules
17 | --]]--
18 | ]=]
19 | }
20 |
--------------------------------------------------------------------------------
/test/all.lua:
--------------------------------------------------------------------------------
1 | local lub = require 'lub'
2 | local lut = require 'lut'
3 | local dub = require 'dub'
4 |
5 | dub.warn_level = 4
6 | dub_test = {}
7 |
8 | for _, k in ipairs(arg) do
9 | if k == '--speed' then
10 | test_speed = true
11 | end
12 | end
13 |
14 | lut.Test.files(lub.path '|')
15 |
16 |
--------------------------------------------------------------------------------
/test/class_test.lua:
--------------------------------------------------------------------------------
1 | --[[------------------------------------------------------
2 |
3 | dub.Class
4 | ---------
5 |
6 | ...
7 |
8 | --]]------------------------------------------------------
9 | local lub = require 'lub'
10 | local lut = require 'lut'
11 | local dub = require 'dub'
12 |
13 | local should = lut.Test 'dub.Class'
14 |
15 | local ins = dub.Inspector {
16 | doc_dir = 'test/tmp',
17 | INPUT = {
18 | 'test/fixtures/simple/include',
19 | 'test/fixtures/constants',
20 | 'test/fixtures/namespace',
21 | 'test/fixtures/inherit',
22 | },
23 | }
24 |
25 | local Simple = ins:find('Simple')
26 | local Car = ins:find('Car')
27 | local A = ins:find('Nem::A')
28 | local Child = ins:find('Child')
29 |
30 | --=============================================== TESTS
31 | function should.autoload()
32 | assertType('table', dub.Class)
33 | end
34 |
35 | function should.createClass()
36 | local c = dub.Class()
37 | assertEqual('dub.Class', c.type)
38 | end
39 |
40 | function should.inheritNewInSubClass()
41 | local Sub = setmetatable({}, dub.Class)
42 | local c = Sub()
43 | assertEqual('dub.Class', c.type)
44 | end
45 |
46 | function should.beAClass()
47 | assertEqual('dub.Class', Simple.type)
48 | end
49 |
50 | function should.detectConscructor()
51 | local method = Simple:method('Simple')
52 | assertTrue(method.ctor)
53 | end
54 |
55 | function should.detectDestructor()
56 | local method = Simple:method('~Simple')
57 | assertTrue(method.dtor)
58 | end
59 |
60 | function should.listMethods()
61 | local m
62 | for method in Simple:methods() do
63 | if method.name == 'setValue' then
64 | m = method
65 | break
66 | end
67 | end
68 | assertEqual(m, Simple:method('setValue'))
69 | end
70 |
71 | function should.notListIgnoredMethods()
72 | local m
73 | for method in Child:methods() do
74 | if method.name == 'virtFunc' then
75 | fail("Method 'virtFunc' ignored but listed by 'methods()' iterator")
76 | end
77 | end
78 | assertTrue(true)
79 | end
80 |
81 | function should.haveHeader()
82 | local path = lub.absolutizePath(lub.path '|fixtures/simple/include/simple.h')
83 | assertEqual(path, Simple.header)
84 | end
85 |
86 | function should.detectDestructor()
87 | local method = Simple:method('~Simple')
88 | assertTrue(Simple:isDestructor(method))
89 | end
90 |
91 | function should.respondToAttributes()
92 | local r = {}
93 | for att in Car:attributes() do
94 | lub.insertSorted(r, att.name)
95 | end
96 | assertValueEqual({
97 | 'brand',
98 | 'name_',
99 | }, r)
100 | end
101 |
102 | function should.respondToAttributes()
103 | local r = {}
104 | for att in car:attributes() do
105 | lub.insertSorted(r, att.name)
106 | end
107 | assertValueEqual({
108 | 'brand',
109 | 'name_',
110 | }, r)
111 | end
112 |
113 | function should.respondToConstants()
114 | local r = {}
115 | for c in Car:constants() do
116 | lub.insertSorted(r, c)
117 | end
118 | assertValueEqual({
119 | 'Dangerous',
120 | 'Noisy',
121 | 'Polluty',
122 | 'Smoky',
123 | }, r)
124 | end
125 |
126 | function should.respondToFindChild()
127 | local f = Car:findChild 'setBrand'
128 | assertEqual('dub.Function', f.type)
129 | end
130 |
131 | function should.respondToNamespace()
132 | local n = A:namespace()
133 | assertEqual('dub.Namespace', n.type)
134 | end
135 |
136 | function should.respondToNeedCast()
137 | assertFalse(A:needCast())
138 | assertTrue(Child:needCast())
139 | end
140 |
141 | should:test()
142 |
143 |
--------------------------------------------------------------------------------
/test/dub_test.lua:
--------------------------------------------------------------------------------
1 | --[[------------------------------------------------------
2 |
3 | dub test
4 | --------
5 |
6 | Run all tests, test some helpers.
7 |
8 | --]]------------------------------------------------------
9 | local lub = require 'lub'
10 | local lut = require 'lut'
11 | local dub = require 'dub'
12 |
13 | local should = lut.Test 'dub'
14 |
15 | -- These functions are private: no coverage testing.
16 | should.ignore.warn = true
17 | should.ignore.printWarn = true
18 | should.ignore.silentWarn = true
19 |
20 | function should.findMinHash()
21 | assertEqual(6, dub.minHash {'a', 'b', 'ab', 'ca'})
22 | assertEqual(14, dub.minHash {'a', 'b', 'ab', 'ac', 'ca'})
23 | assertEqual(14, dub.minHash {'a', 'b', 'ab', 'ac', 'ca', 'bobli'})
24 | assertEqual(14, dub.minHash {'a', 'b', 'ab', 'ac', 'ca', 'bobli', 'malc'})
25 | assertEqual(3, dub.minHash {'name_', 'size_'})
26 | end
27 |
28 | function should.findMinHashWithDuplicates()
29 | assertEqual(6, dub.minHash {'a', 'a', 'b', 'ab', 'ca'})
30 | end
31 |
32 | function should.returnNilMinHashOnEmptyList()
33 | assertNil(dub.minHash {})
34 | end
35 |
36 | function should.hash()
37 | local sz = 14
38 | assertEqual(13, dub.hash('a',14))
39 | assertEqual(0, dub.hash('b',14))
40 | assertEqual(5, dub.hash('ab',14))
41 | assertEqual(6, dub.hash('ac',14))
42 | assertEqual(8, dub.hash('ca',14))
43 | assertEqual(0, dub.hash('name_',5))
44 | assertEqual(1, dub.hash('birth_year',2))
45 | end
46 |
47 | should:test()
48 |
49 |
--------------------------------------------------------------------------------
/test/fixtures/constants/Car.h:
--------------------------------------------------------------------------------
1 | #ifndef CONSTANTS_CAR_H_
2 | #define CONSTANTS_CAR_H_
3 |
4 | #include
5 |
6 | /** This class is used to test:
7 | * * class constants (enums).
8 | * * enum attributes read/write.
9 | * * alternate binding definition (using Car.new instead of Car())
10 | * * rename attribute filter.
11 | */
12 | class Car {
13 | public:
14 |
15 | /** List of Car brands.
16 | */
17 | enum Brand {
18 | Smoky,
19 | Polluty,
20 | Noisy,
21 | Dangerous,
22 | };
23 |
24 | /** Accessors should understand that Brand is an integer.
25 | */
26 | Brand brand;
27 |
28 | std::string name_;
29 |
30 | Car(const char * n, Brand b = Polluty)
31 | : brand(b)
32 | , name_(n) {
33 | }
34 |
35 | void setBrand(Brand b) {
36 | brand = b;
37 | }
38 |
39 | const char *brandName() {
40 | switch(brand) {
41 | case Smoky:
42 | return "Smoky";
43 | case Polluty:
44 | return "Polluty";
45 | case Noisy:
46 | return "Noisy";
47 | case Dangerous:
48 | return "Dangerous";
49 | default:
50 | return "???";
51 | }
52 | }
53 | };
54 |
55 | #endif // CONSTANTS_CAR_H_
56 |
57 |
--------------------------------------------------------------------------------
/test/fixtures/constants/types.h:
--------------------------------------------------------------------------------
1 | #ifndef CONSTANTS_TYPES_H_
2 | #define CONSTANTS_TYPES_H_
3 |
4 | /** Constants that should be accessible by libname.ConstName
5 | * or GlobalConstant.ConstName if no lib is provided.
6 | */
7 | enum GlobalConstant {
8 | One = 1,
9 | Two,
10 | Three = 55,
11 | };
12 |
13 | #endif // CONSTANTS_TYPES_H_
14 |
--------------------------------------------------------------------------------
/test/fixtures/inherit/Child.h:
--------------------------------------------------------------------------------
1 | #ifndef INHERIT_CHILD_H_
2 | #define INHERIT_CHILD_H_
3 |
4 | // Simulate complex inclusion (think external lib)
5 | // This class needs the "../inherit_hidden/Mother.h" header to compile.
6 | class Mother;
7 |
8 | #include "Parent.h"
9 |
10 | #include
11 |
12 | /** This class is used to test:
13 | * * attribute inheritance
14 | * * method inheritance
15 | * * custom bindings
16 | * * unknown types
17 | * * ignore methods from parent
18 | *
19 | * Since Doxygen does not know that Mother is a Parent, we tell this. We also
20 | * use 'mixin' of custom bindings from ChildHelper.
21 | * @dub super: Parent, ChildHelper, Mother
22 | * ignore: virtFunc
23 | */
24 | class Child : public Mother {
25 | // Private attribute
26 | double pos_x_;
27 | double pos_y_;
28 | public:
29 | // public attribute (child should inherit this)
30 | double teeth;
31 |
32 | Child(const std::string &name, MaritalStatus s, int birth_year, double x, double y);
33 |
34 | virtual ~Child() {}
35 |
36 | double x() {
37 | return pos_x_;
38 | }
39 |
40 | double y() {
41 | return pos_y_;
42 | }
43 |
44 | /** Unknown Unk1 type.
45 | */
46 | Unk1 returnUnk1(double value) {
47 | return Unk1(value);
48 | }
49 |
50 | /** Unknown Unk2 type.
51 | */
52 | Unk2 returnUnk2(double value) {
53 | return Unk2(value);
54 | }
55 |
56 | /** Unknown arguments.
57 | */
58 | double methodWithUnknown(Unk1 x, Unk2 *y) {
59 | return x.value() + y->value();
60 | }
61 |
62 | /** Should not inherit overloaded/virtuals twice.
63 | */
64 | std::string name();
65 | };
66 |
67 | /** This class should have set/get methods defined
68 | * because it inherits attributes from its parents.
69 | */
70 | class GrandChild : public Child {
71 | public:
72 | };
73 | #endif // INHERIT_CHILD_H_
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/test/fixtures/inherit/ChildHelper.h:
--------------------------------------------------------------------------------
1 | /** This is not a real C++ class. It is used to add custom methods to Child.
2 | *
3 | * This tells to not make bindings for this class and not try to cast.
4 | * @dub bind: false
5 | * cast: false
6 | */
7 | class ChildHelper {
8 | public:
9 | // Special method with multiple return values.
10 | LuaStackSize position();
11 |
12 | // Custom bindings with default values.
13 | double addToX(double n=4);
14 | };
15 |
--------------------------------------------------------------------------------
/test/fixtures/inherit/ChildHelper.yml:
--------------------------------------------------------------------------------
1 | lua:
2 | methods:
3 | position: |
4 | lua_pushnumber(L, self->x());
5 | lua_pushnumber(L, self->y());
6 | return 2;
7 | addToX:
8 | arg0: |
9 | lua_pushnumber(L, self->x() + 4.0);
10 | return 1;
11 | arg1: |
12 | lua_pushnumber(L, self->x() + n);
13 | return 1;
14 |
--------------------------------------------------------------------------------
/test/fixtures/inherit/GrandParent.h:
--------------------------------------------------------------------------------
1 | #ifndef INHERIT_GRAND_PARENT_H_
2 | #define INHERIT_GRAND_PARENT_H_
3 |
4 | #include "Object.h"
5 | #include
6 |
7 | /** This class is used to test:
8 | * * attribute inheritance
9 | * * method inheritance
10 | */
11 | class GrandParent : protected Object {
12 | public:
13 | // public attribute (all children should inherit this)
14 | double birth_year;
15 |
16 | GrandParent(int y)
17 | : birth_year(y) {}
18 |
19 | /** Method that should be inherited by all children.
20 | */
21 | int computeAge(int current_year) {
22 | return current_year - birth_year;
23 | }
24 | };
25 |
26 | #endif // INHERIT_GRAND_PARENT_H_
27 |
28 |
29 |
--------------------------------------------------------------------------------
/test/fixtures/inherit/Object.h:
--------------------------------------------------------------------------------
1 | #ifndef INHERIT_OBJECT_H_
2 | #define INHERIT_OBJECT_H_
3 |
4 | #include
5 |
6 | /** This class is used to test:
7 | * * make sure non public inheritance is not followed.
8 | */
9 | class Object {
10 | public:
11 | // public attribute (all children should inherit this)
12 | double memory;
13 |
14 | void checkMemory() {
15 | if (!memory) {
16 | printf("None left!\n");
17 | }
18 | }
19 | };
20 |
21 | #endif // INHERIT_OBJECT_H_
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/test/fixtures/inherit/Orphan.h:
--------------------------------------------------------------------------------
1 | #ifndef INHERIT_UNKNOWN_PARENT_H_
2 | #define INHERIT_UNKNOWN_PARENT_H_
3 |
4 | // Simulate complex inclusion (think external lib)
5 | #include "../inherit_hidden/Mother.h"
6 |
7 | #include
8 |
9 | template
10 | class Foo {
11 | };
12 |
13 | class Bar {
14 | };
15 | /** This class is used to test:
16 | * * unresolved super class (no typedef).
17 | * * multiple super classes.
18 | *
19 | * @dub super: Foo< int >
20 | */
21 | class Orphan : public Foo, public Bar {
22 | public:
23 | Orphan() {}
24 | };
25 |
26 | #endif // INHERIT_UNKNOWN_PARENT_H_
27 |
28 |
--------------------------------------------------------------------------------
/test/fixtures/inherit/Parent.h:
--------------------------------------------------------------------------------
1 | #ifndef INHERIT_PARENT_H_
2 | #define INHERIT_PARENT_H_
3 |
4 | #include "GrandParent.h"
5 |
6 | #include
7 |
8 | /** This class is used to test:
9 | * * attribute inheritance
10 | * * method inheritance
11 | */
12 | class Parent : public GrandParent {
13 | // Private attribute
14 | std::string name_;
15 | public:
16 | enum MaritalStatus {
17 | Single,
18 | Married,
19 | Poly,
20 | Depends,
21 | };
22 |
23 | // public attribute (child should inherit this)
24 | MaritalStatus status;
25 |
26 | // test boolean attribute
27 | bool happy;
28 |
29 | Parent(const std::string &name, MaritalStatus status_, int birth_year)
30 | : GrandParent(birth_year)
31 | , name_(name)
32 | , status(status_)
33 | , happy(true)
34 | {}
35 |
36 | virtual ~Parent() {}
37 |
38 | /** Method that should be inherited by child.
39 | */
40 | std::string name() {
41 | return name_;
42 | }
43 |
44 | /** Static method that should not be inherited.
45 | */
46 | static std::string getName(Parent *parent) {
47 | return parent->name_;
48 | }
49 |
50 | virtual void virtFunc() {
51 | }
52 | };
53 |
54 | #endif // INHERIT_PARENT_H_
55 |
56 |
57 |
--------------------------------------------------------------------------------
/test/fixtures/inherit/child.cpp:
--------------------------------------------------------------------------------
1 | #include "../inherit_hidden/Mother.h"
2 | #include "Child.h"
3 | #include
4 |
5 | Child::Child(const std::string &name, MaritalStatus s, int birth_year, double x, double y)
6 | : Mother(name, s, birth_year)
7 | , pos_x_(x)
8 | , pos_y_(y) {}
9 |
10 | std::string Child::name() {
11 | return std::string("Child ").append(Parent::name());
12 | }
13 |
--------------------------------------------------------------------------------
/test/fixtures/inherit_hidden/Mother.h:
--------------------------------------------------------------------------------
1 | #ifndef INHERIT_HIDDEN_MOTHER_H_
2 | #define INHERIT_HIDDEN_MOTHER_H_
3 |
4 | #include "Parent.h"
5 |
6 | #include
7 |
8 | /** This class is not seen by Doxygen and is used to 'explain' inheritance
9 | * of Parent by Child through the 'super' key in dub header doc.
10 | */
11 | class Mother : public Parent {
12 | public:
13 | Mother(const std::string &name, MaritalStatus s, int birth_year)
14 | : Parent(name, s, birth_year) {}
15 | };
16 |
17 |
18 | /** This class is not seed by Doxygen or Dub. Instances of this class
19 | * are passed around as opaque types.
20 | */
21 | class Unk1 {
22 | double v_;
23 | public:
24 | Unk1(double v) : v_(v) {}
25 | double value() {
26 | return v_;
27 | }
28 | };
29 |
30 | typedef Unk1 Unk2;
31 |
32 | #endif // INHERIT_HIDDEN_MOTHER_H_
33 |
34 |
--------------------------------------------------------------------------------
/test/fixtures/memory/CustomDtor.h:
--------------------------------------------------------------------------------
1 | #ifndef MEMORY_CUSTOM_DTOR_H_
2 | #define MEMORY_CUSTOM_DTOR_H_
3 |
4 | #include "dub/dub.h"
5 |
6 | /** This class is used to test:
7 | * * Custom destructors.
8 | *
9 | * @dub push: dub_pushobject
10 | * destructor: finalize
11 | */
12 | class CustomDtor : public dub::Thread {
13 | public:
14 | CustomDtor() {}
15 |
16 | ~CustomDtor() {}
17 |
18 | void finalize() {
19 | if (dub_pushcallback("callback")) {
20 | //
21 | dub_call(1, 0);
22 | }
23 | delete this;
24 | }
25 | };
26 | #endif // MEMORY_CUSTOM_DTOR_H_
27 |
--------------------------------------------------------------------------------
/test/fixtures/memory/NoDtor.h:
--------------------------------------------------------------------------------
1 | #ifndef MEMORY_NO_DTOR_H_
2 | #define MEMORY_NO_DTOR_H_
3 |
4 | #include "dub/dub.h"
5 |
6 | class NoDtor;
7 |
8 | /** @dub push: dub_pushobject
9 | * ignore: dead
10 | */
11 | class NoDtorCleaner : public dub::Thread {
12 | NoDtor *ndt_;
13 | public:
14 | NoDtorCleaner(NoDtor *ndt);
15 |
16 | ~NoDtorCleaner() {
17 | cleanup();
18 | }
19 |
20 | void cleanup();
21 |
22 | void dead(NoDtor *obj);
23 | };
24 |
25 | /** This class is used to test:
26 | * * Removing destructor.
27 | *
28 | * @dub destructor: false
29 | * ignore: s_
30 | */
31 | class NoDtor {
32 | friend class NoDtorCleaner;
33 | NoDtorCleaner *cleaner_;
34 | public:
35 | std::string s_;
36 |
37 | NoDtor(const char *s)
38 | : cleaner_(NULL)
39 | , s_(s) {
40 | }
41 |
42 | ~NoDtor() {
43 | if (cleaner_) {
44 | cleaner_->dead(this);
45 | }
46 | }
47 | };
48 |
49 | inline NoDtorCleaner::NoDtorCleaner(NoDtor *ndt)
50 | : ndt_(ndt) {
51 | ndt->cleaner_ = this;
52 | }
53 |
54 | inline void NoDtorCleaner::dead(NoDtor *obj) {
55 | if (dub_pushcallback("callback")) {
56 | lua_pushstring(dub_L, obj->s_.c_str());
57 | //
58 | dub_call(2, 0);
59 | }
60 | }
61 |
62 | inline void NoDtorCleaner::cleanup() {
63 | if (ndt_) {
64 | delete ndt_;
65 | ndt_ = NULL;
66 | }
67 | }
68 |
69 | #endif // MEMORY_NO_DTOR_H_
70 |
71 |
--------------------------------------------------------------------------------
/test/fixtures/memory/Nogc.h:
--------------------------------------------------------------------------------
1 | #ifndef MEMORY_NOGC_H_
2 | #define MEMORY_NOGC_H_
3 |
4 | /** This class is used to test:
5 | * * no gc optimization
6 | *
7 | * @dub destroy: 'free'
8 | */
9 | struct Nogc {
10 | double x;
11 | double y;
12 |
13 | Nogc(double x_, double y_)
14 | : x(x_)
15 | , y(y_)
16 | {}
17 |
18 | double surface() {
19 | return x * y;
20 | }
21 |
22 | Nogc operator+(const Nogc &v) {
23 | return Nogc(x + v.x, y + v.y);
24 | }
25 | };
26 |
27 | #endif // MEMORY_NOGC_H_
28 |
29 |
--------------------------------------------------------------------------------
/test/fixtures/memory/Owner.h:
--------------------------------------------------------------------------------
1 | #ifndef MEMORY_OWNER_H_
2 | #define MEMORY_OWNER_H_
3 |
4 | #include
5 | class Pen;
6 |
7 | /** This class is used to monitor:
8 | * * Deletion from C++.
9 | * * Deletion from the scripting language.
10 | */
11 | class Owner {
12 | Pen *pen_;
13 | public:
14 | std::string message_;
15 |
16 | Owner(Pen *pen = NULL);
17 |
18 | ~Owner();
19 |
20 | void own(Pen *pen);
21 |
22 | void setMessage(const std::string &msg) {
23 | message_ = msg;
24 | }
25 |
26 | void destroyPen();
27 | };
28 | #endif // MEMORY_OWNER_H_
29 |
--------------------------------------------------------------------------------
/test/fixtures/memory/Pen.h:
--------------------------------------------------------------------------------
1 | #ifndef MEMORY_PEN_H_
2 | #define MEMORY_PEN_H_
3 |
4 | #include "Owner.h"
5 |
6 | #include "dub/dub.h"
7 | #include
8 |
9 | #define SOME_FUNCTION_MACRO(x)
10 | #define OTHER_FUNCTION_MACRO(x)
11 |
12 | /** This class is used to test:
13 | * * when an object owned by the scripting language is deleted in C++.
14 | * * when an object owned by C++ is deleted in the scripting language.
15 | * * macro expansion setting
16 | *
17 | * @dub push: dub_pushobject
18 | */
19 | class Pen : public dub::Object {
20 | std::string name_;
21 | Owner *owner_;
22 | public:
23 | Pen(const char *name)
24 | : name_(name)
25 | , owner_(NULL) {}
26 |
27 | void setOwner(Owner *owner) {
28 | owner_ = owner;
29 | }
30 |
31 | ~Pen() {
32 | if (owner_) {
33 | owner_->setMessage(std::string("Pen '").append(name_).append("' is dying..."));
34 | }
35 | }
36 |
37 | const std::string &name() {
38 | return name_;
39 | }
40 |
41 | SOME_FUNCTION_MACRO(int x);
42 |
43 | OTHER_FUNCTION_MACRO(x);
44 |
45 | /** We declare this method so that Doxygen sees it (Doxygen does not parse
46 | * dub::Object) and adds the method to the generated xml. We can then ensure
47 | * that the 'push' method is ignored even if seen.
48 | */
49 | virtual void dub_pushobject(lua_State *L, void *ptr, const char *type_name, bool gc = true) {
50 | dub::Object::dub_pushobject(L, ptr, type_name, gc);
51 | }
52 |
53 | };
54 |
55 | #endif // MEMORY_PEN_H_
56 |
--------------------------------------------------------------------------------
/test/fixtures/memory/PrivateDtor.h:
--------------------------------------------------------------------------------
1 | #ifndef MEMORY_PRIVATE_DTOR_H_
2 | #define MEMORY_PRIVATE_DTOR_H_
3 |
4 | #include "dub/dub.h"
5 |
6 | /** This class is used to test:
7 | * * private destructors.
8 | */
9 | class PrivateDtor {
10 | public:
11 | PrivateDtor() {}
12 |
13 | private:
14 | ~PrivateDtor() {}
15 | };
16 |
17 | #endif // MEMORY_PRIVATE_DTOR_H_
18 |
19 |
--------------------------------------------------------------------------------
/test/fixtures/memory/Union.h:
--------------------------------------------------------------------------------
1 | #ifndef MEMORY_UNION_H_
2 | #define MEMORY_UNION_H_
3 |
4 | #include "dub/dub.h"
5 | #include
6 |
7 | #include
8 |
9 | /** This class is used to test:
10 | * * access to anonymous union members (custom bindings)
11 | */
12 | class Union {
13 | public:
14 | /** Anonymous union.
15 | */
16 | union {
17 | struct {
18 | uint8_t h;
19 | uint8_t s;
20 | uint8_t v;
21 | uint8_t a;
22 | };
23 | uint32_t c;
24 | };
25 |
26 | Union(uint8_t _h, uint8_t _s, uint8_t _v, uint8_t _a) {
27 | h = _h;
28 | s = _s;
29 | v = _v;
30 | a = _a;
31 | }
32 | };
33 |
34 | #endif // MEMORY_UNION_H_
35 |
36 |
--------------------------------------------------------------------------------
/test/fixtures/memory/Withgc.h:
--------------------------------------------------------------------------------
1 | #ifndef MEMORY_WITHGC_H_
2 | #define MEMORY_WITHGC_H_
3 |
4 | /** This class is used to compare execution with a __gc method
5 | * or without (Nogc version).
6 | * * no gc optimization (this one has a __gc method)
7 | *
8 | */
9 | struct Withgc {
10 | double x;
11 | double y;
12 |
13 | Withgc(double x_, double y_)
14 | : x(x_)
15 | , y(y_)
16 | {}
17 |
18 | double surface() {
19 | return x * y;
20 | }
21 |
22 | Withgc operator+(const Withgc &v) {
23 | return Withgc(x + v.x, y + v.y);
24 | }
25 | };
26 |
27 | #endif // MEMORY_WITHGC_H_
28 |
29 |
30 |
--------------------------------------------------------------------------------
/test/fixtures/memory/owner.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include "Owner.h"
3 | #include "Pen.h"
4 | // This is only required to monitor object destruction.
5 | Owner::Owner(Pen * pen) : pen_(pen) {
6 | if (pen_) pen_->setOwner(this);
7 | }
8 |
9 | void Owner::own(Pen *pen) {
10 | pen_ = pen;
11 | pen_->setOwner(this);
12 | }
13 |
14 | Owner::~Owner() {
15 | if (pen_) {
16 | pen_->setOwner(NULL);
17 | }
18 | }
19 |
20 | void Owner::destroyPen() {
21 | if (pen_) {
22 | delete pen_;
23 | pen_ = NULL;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/test/fixtures/namespace/A.h:
--------------------------------------------------------------------------------
1 | #ifndef NAMESPACE_A_H_
2 | #define NAMESPACE_A_H_
3 |
4 | #include "TRect.h"
5 | #include "B.h"
6 | #include
7 |
8 | namespace Nem {
9 |
10 | /** When resolving TRect to Rect, we remember the header where this
11 | * resolution happened.
12 | */
13 | typedef TRect Rect;
14 |
15 | /** This class is used to test:
16 | * * classes in namespace
17 | * * custom __tostring method
18 | * * lua_State pseudo-parameter
19 | * * custom accessor
20 | * * overwriten methods
21 | */
22 | class A {
23 | public:
24 | std::string name;
25 |
26 | /** We will attach any Lua value to this by writing a custom
27 | * accessor (see A.yml).
28 | */
29 | void *userdata;
30 |
31 | A(const char *name_ = "")
32 | : name(name_)
33 | , userdata(NULL)
34 | {}
35 |
36 | LuaStackSize __tostring(lua_State *L) {
37 | lua_pushfstring(L, "", this, name.c_str());
38 | return 1;
39 | }
40 |
41 | std::string over(A *a) {
42 | return "A";
43 | }
44 |
45 | std::string over(B *b) {
46 | return "B";
47 | }
48 |
49 | };
50 |
51 | /** Nested namespace. Ignored for now.
52 | */
53 | namespace SubNem {
54 | class X {};
55 | } // SubNem
56 | } // Nem
57 |
58 | #endif // NAMESPACE_A_H_
59 |
--------------------------------------------------------------------------------
/test/fixtures/namespace/A.yml:
--------------------------------------------------------------------------------
1 | lua:
2 | methods:
3 | '~A':
4 | cleanup: |
5 | dub::DubRef::cleanup(L, &self->userdata);
6 | attributes:
7 | userdata:
8 | # This is an experimental feature to allow arbitrary values attached to
9 | # void* pointers.
10 | set: |
11 | return dub::DubRef::set(L, &self->userdata, 3);
12 | get: |
13 | return dub::DubRef::push(L, self->userdata);
14 |
--------------------------------------------------------------------------------
/test/fixtures/namespace/B.h:
--------------------------------------------------------------------------------
1 | #ifndef NAMESPACE_B_H_
2 | #define NAMESPACE_B_H_
3 |
4 | namespace Nem {
5 |
6 | class A;
7 |
8 | /** This class is used to test:
9 | * * classes in namespace
10 | * * nested classes
11 | * * custom __tostring method
12 | * * lua_State pseudo-parameter
13 | */
14 | class B {
15 | public:
16 | int nb_;
17 | A *a;
18 |
19 | /** Nested public class.
20 | */
21 | class C {
22 | int nb_;
23 | friend class B;
24 | public:
25 | C(int nb)
26 | : nb_(nb)
27 | {}
28 |
29 | LuaStackSize __tostring(lua_State *L) {
30 | lua_pushfstring(L, "", this, nb_);
31 | return 1;
32 | }
33 |
34 | int nb() {
35 | return nb_;
36 | }
37 | };
38 |
39 | C *c;
40 |
41 | B(int nb)
42 | : nb_(nb)
43 | , a(NULL)
44 | , c(NULL)
45 | {}
46 |
47 | B(C *c_)
48 | : nb_(c_->nb_)
49 | , a(NULL)
50 | , c(c_)
51 | {}
52 |
53 | LuaStackSize __tostring(lua_State *L) {
54 | lua_pushfstring(L, "", this, nb_);
55 | return 1;
56 | }
57 |
58 | C *getC() {
59 | return c;
60 | }
61 | };
62 |
63 | } // Nem
64 | #endif // NAMESPACE_B_H_
65 |
66 |
--------------------------------------------------------------------------------
/test/fixtures/namespace/Nem.yml:
--------------------------------------------------------------------------------
1 | # Custom lua bindings for Nem namespace
2 | lua:
3 | methods:
4 | customGlobal: |
5 | lua_pushnumber(L, a + b);
6 | lua_pushstring(L, "custom global");
7 | return 2;
8 |
--------------------------------------------------------------------------------
/test/fixtures/namespace/Out.h:
--------------------------------------------------------------------------------
1 | #ifndef NAMESPACE_OUT_H_
2 | #define NAMESPACE_OUT_H_
3 |
4 | namespace Nem {
5 |
6 | /** A typedef defined inside the namespace.
7 | */
8 | typedef TRect Rectf;
9 |
10 | } // Nem
11 |
12 | /** A typedef defined outside the namespace.
13 | */
14 | typedef Nem::TRect nmRectf;
15 |
16 | #endif // NAMESPACE_OUT_H_
17 |
--------------------------------------------------------------------------------
/test/fixtures/namespace/TRect.h:
--------------------------------------------------------------------------------
1 | #ifndef NAMESPACE_T_RECT_H_
2 | #define NAMESPACE_T_RECT_H_
3 |
4 | #include
5 |
6 | namespace Nem {
7 |
8 | /** This class is used to test:
9 | * * template in namespace
10 | */
11 | template
12 | class TRect {
13 | public:
14 | T w;
15 | T h;
16 |
17 | TRect(T w_, T h_)
18 | : w(w_)
19 | , h(h_)
20 | {}
21 | };
22 |
23 | } // Nem
24 | #endif // NAMESPACE_T_RECT_H_
25 |
26 |
--------------------------------------------------------------------------------
/test/fixtures/namespace/_global.yml:
--------------------------------------------------------------------------------
1 | lua:
2 | methods:
3 | customGlobalOut: |
4 | lua_pushnumber(L, a + b);
5 | lua_pushstring(L, "custom global out");
6 | return 2;
7 |
8 |
--------------------------------------------------------------------------------
/test/fixtures/namespace/constants.h:
--------------------------------------------------------------------------------
1 | #ifndef NAMESPACE_CONSTANTS_H_
2 | #define NAMESPACE_CONSTANTS_H_
3 |
4 | namespace Nem {
5 |
6 | /** Constants that should be accessible by Nem.ConstName
7 | */
8 | enum NamespaceConstant {
9 | One = 1,
10 | Two,
11 | Three = 55,
12 | };
13 |
14 | } // Nem
15 |
16 | #endif // NAMESPACE_CONSTANTS_H_
17 |
18 |
--------------------------------------------------------------------------------
/test/fixtures/namespace/nem.h:
--------------------------------------------------------------------------------
1 | #ifndef NAMESPACE_NEM_H_
2 | #define NAMESPACE_NEM_H_
3 |
4 | #include "B.h"
5 | #include
6 |
7 | namespace Nem {
8 |
9 | /** Function inside the namespace.
10 | */
11 | double addTwo(const B &a, const B &b) {
12 | return a.nb_ + b.nb_;
13 | }
14 |
15 | /** Global function with custom bindings.
16 | */
17 | LuaStackSize customGlobal(float a, float b);
18 | } // Nem
19 |
20 | /** Function outside the namespace.
21 | */
22 | double addTwoOut(const Nem::B &a, const Nem::B &b) {
23 | return a.nb_ + b.nb_;
24 | }
25 |
26 | /** Function outside the namespace with custom bindings. The custom bindings
27 | * for global methods must live in [name of lib].yml
28 | */
29 | LuaStackSize customGlobalOut(float a, float b);
30 |
31 |
32 | #endif // NAMESPACE_NEM_H_
33 |
34 |
--------------------------------------------------------------------------------
/test/fixtures/path.wi$th-[pat]/Pat.h:
--------------------------------------------------------------------------------
1 | #ifndef PATH_WITH_PAT_PAT_H_
2 | #define PATH_WITH_PAT_PAT_H_
3 |
4 | #include