nldecl
Nelua can read C code to generate Nelua bindings appropriate for its use. This can be done at compile-time and in a convenient manner, similar to the facilities offered by Terra, Zig, and D's ImportC. Or indeed, similar to build-system binding generators like SWIG. A practical example is included in examples/snakesdl_nldecl.nelua, distributed with Nelua.
For example, this code
##[[
local nldecl = require 'nelua.plugins.nldecl'
local fs = require 'nelua.utils.fs'
if not fs.isfile('pcre-bindings.nelua') then
nldecl.generate_bindings_file {
output_file = 'pcre-bindings.nelua',
parse_includes = {'<pcre.h>'},
include_names = {'^PCRE_', '^pcre_'},
}
end
cinclude '<pcre.h>'
linklib 'pcre'
]]
require 'pcre-bindings'generates, pcre-bindings.nelua, with code like
global pcre_extra: type <cimport,nodecl> = @record{
flags: culong,
study_data: pointer,
match_limit: culong,
callout_data: pointer,
tables: *cuchar,
match_limit_recursion: culong,
mark: **cuchar,
executable_jit: pointer
}
global pcre_stack_guard: function(): cint <cimport,nodecl>
global function pcre_study(a1: *pcre, a2: cint, a3: *cstring): *pcre_extra <cimport,nodecl> end
global PCRE_MAJOR: cint <comptime> = 8
global PCRE_MINOR: cint <comptime> = 39
global PCRE_DATE: cint <comptime> = 1996and so on. Even if a binding is relatively easy to do by hand, nldecl can make your program more responsive to changes in a C API, such as subtle type changes or additional struct members. nldecl's generate_bindings_file takes a Lua table which can contain quite a few options to control the generation of the bindings:
- cc - C compiler used for its preprocessor. Given
-E -dD -Pflags. - cflags - additional flags
- defines -
#definelines to add, for example to enable feature-gated functionality in a C library - enum_types - ???
- exclude_names - Lua patterns. If a symbol matches any of them, a binding for it is not generated.
- force_exclude_names - ???
- gsubs - Lua string.sub parameter arrays to filter the genereated Nelua bindings with. Happens earlier that output_foot, etc.
- include_dirs - additional
-Iflags to apss - include_names - Lua patterns. If a symbol mataches any of them, a binding for it is generated.
- includes - C header names to
#include, to generate a binding for. Angle brackets are implied, can be suppessed with double quotes. - incomplete_names - ???
- output_file - the file to write the binding to
- output_foot - text to append to the bindings after generating them
- output_head - text to prepend to the bindings
- output_postprocess - a function over the output bindings, as a string
- parse_defines - seems to be equivalent to
defines - parse_foot - text to append to the C file that bindings will be generated from
- parse_head - text to prepend
- parse_includes - equivalent to
includes - parse_typedefs - ???
- preprocess - function over the c file after it's preprocessed and before bindings are generated from it