summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md223
1 files changed, 111 insertions, 112 deletions
diff --git a/README.md b/README.md
index dd5d9f2..9a63e74 100644
--- a/README.md
+++ b/README.md
@@ -6,9 +6,9 @@ title: honeysuckle README
honeysuckle
===========
-A pure C library to make writing Lua bindings simple. honeysuckle provides
-functions to make argument parsing, table operations, error creation and
-handling, string wrangling, and registry operations easy and straightforward
+A pure C library to make writing Lua bindings simple. honeysuckle provides
+functions to make argument parsing, table operations, error creation and
+handling, string wrangling, and registry operations easy and straightforward
from within your C code.
Table of contents
@@ -35,7 +35,8 @@ sudo make install
To make the tests as well, do the above and then do `make test`.
-You should now be able to include `<honeysuckle.h>` into your C files for use.
+You should now be able to include `<honeysuckle.h>` into your C
+files for use.
Usage
-----
@@ -56,7 +57,8 @@ Usage
[(Back to top)](#table-of-contents)
-These constants are used when honeysuckle needs to know a type to expect.
+These constants are used when honeysuckle needs to know a type to
+expect.
- `HS_BOOL` - booleans
- `HS_INT` - integers
@@ -70,21 +72,29 @@ These constants are used when honeysuckle needs to know a type to expect.
- `HS_NIL` - lua's nil
- `HS_ANY` - any type
-`hs_type_to_string()` takes as argument a single type constant and returns a
-const string representing the type.
+`hs_type_to_string()` takes as argument a single type constant and
+returns a const string representing the type.
### Argument parsing
[(Back to top)](#table-of-contents)
-`hs_parse_args()` is the primary argument-parsing function. It accepts as
-arguments a lua_State pointer, any number of alternating type constant and
-pointer pairs, and finally `HS_END` to close the arguments. This function
-performs typechecking and in case of an error throws with helpful error
-messages.
+`hs_parse_args()` is the primary argument-parsing function. It
+accepts as arguments a lua_State pointer, any number of
+`struct hs_arg`s. These can either be constructed by hand or with
+function-like macros identified by the lowercase version of the type
+names from the section above. Use of the macros is recommended as
+they will likely reduce type mismatch errors (e.g. giving HS_BOOL as
+type but providing a pointer to a string).
-`HS_TBL`, `HS_FUNC`, `HS_NIL`, and `HS_ANY` take a pointer to an integer
-that will be filled with the stack index of the argument.
+This function performs typechecking and in case of an error throws
+with helpful error messages.
+
+`HS_TBL`, `HS_FUNC`, `HS_NIL`, and `HS_ANY` take a pointer to an
+integer that will be filled with the stack index of the argument.
+
+Please note that, due to technical limitations, this function can
+only parse up to 255 arguments.
```c
int some_lua_binding(lua_State *L)
@@ -96,13 +106,15 @@ int some_lua_binding(lua_State *L)
char *str;
void* user;
hs_parse_args(L,
- HS_BOOL, &b,
- HS_INT, &i,
- HS_TBL, &tbl_index,
- HS_NUM, &n,
- HS_STR, &str,
- HS_USER, &user,
- HS_END);
+ // explicit initializer for struct
+ { HS_BOOL, ptr.bool = &b },
+ // macro initialization (recommended)
+ hs_int(i),
+ hs_tbl(tbl_index),
+ hs_num(n),
+ hs_str(str),
+ hs_user(user)
+ );
// do something...
return 1;
}
@@ -110,27 +122,32 @@ int some_lua_binding(lua_State *L)
#### Overloading
-There is another function, `hs_parse_overloaded()`, that permits overloaded
-argument parsing. Its syntax is exactly as `hs_parse_args()` except that after
-each `HS_END` you may provide another argument list, and after the final
-argument list you must provide another `HS_END`. This function throws an error
-only if none of the argument lists match the provided arguments.
+There is another function, `hs_parse_overloaded()`, that permits
+overloaded argument parsing. Its syntax is exactly as
+`hs_parse_args()` except that each overload option must be wrapped
+in the macro `hs_overload()`. This function returns an integer
+containing the zero-indexed index of the overload option that was
+actually used.
+
+If none of the argument lists match the provided arguments, this
+function throws an error.
```c
int overloaded_lua_binding(lua_State *L)
{
int i;
+ float f;
char *str;
int choice = hs_parse_overloaded(L,
- HS_INT, &i, HS_END,
- HS_STR, &str, HS_END,
- HS_END);
+ hs_overload( hs_int(i) ),
+ hs_overload( hs_str(str), hs_num(f) )
+ );
if (choice == 0) {
// do something with i
- // str remains unassigned!!
+ // str and f remain unassigned!!
}
else {
- // choice == 1, do something with str
+ // choice == 1, do something with str and f
// i remains unassigned!!
}
return 0;
@@ -141,69 +158,58 @@ int overloaded_lua_binding(lua_State *L)
[(Back to top)](#table-of-contents)
-`hs_create_table()` takes a lua_State pointer, some number of string key/type
-constant/value triplets, and finally `HS_END`. It returns the stack index of
-the newly created table. Most of the type constants expect their associated
-type (e.g. `HS_INT` expects an `int`, `HS_CFUNC` expects `lua_CFunction`,
-etc.) but `HS_FUNC` and `HS_TBL` expect an integer stack index. You cannot
-use `HS_NIL` or `HS_ANY` with this function. `hs_create_table()`
-automatically pops any stack indices provided to it.
+`hs_create_table()` takes a lua_State pointer and then up to 255 `
+struct hs_tbl_entry`s. These can either be constructed by hand, or
+via function-like macros identified by lowercase versions of the
+typenames shown above (e.g. `hs_str_int` would create a string key
+with integer value). Most of the type constants expect their
+associated type (e.g. `HS_INT` expects an `int`, `HS_CFUNC` expects `
+lua_CFunction`, etc.) but `HS_FUNC`, `HS_USER`, and `HS_TBL` expect
+an integer stack index. You cannot use `HS_NIL` or `HS_ANY` with
+this function.
+
+This function returns the stack index of the newly created table,
+and automatically pops any stack indices provided to it.
```c
int *ptr; // some pointer
hs_create_table(L,
- "intVal", HS_INT, 4,
- "numVal", HS_NUM, 6.0f,
- "tableVal", HS_TBL, hs_create_table(L,
- "subTableCFunc", HS_CFUNC, some_lua_binding,
- "subTableString", HS_STR, "i'm a string!",
- HS_END),
+ // manual struct initialization
+ { HS_STR, key.string="intVal", HS_INT, value.integer=4 },
+ // macro initialization (recommended)
+ hs_str_num("numVal", 6.0f),
+ hs_int_tbl(12, hs_create_table(L,
+ hs_str_cfunc("subTableCFunc", some_lua_binding),
+ hs_int_bool(15, true),
+ ),
"lightUserdataVal", HS_LIGHT, (void *)ptr,
HS_END);
```
-#### Enums
-
-`hs_create_enum()` takes a lua_State pointer, some number of string/integer
-pairs, and finally `HS_END`. It creates a table in which, for each string/int
-pair `tbl[string] = int` and `tbl[int] = string` and returns the stack index
-of said table. `hs_string_to_enum()` uses such a table to convert a string
-literal to enum value and `hs_enum_to_string()` converts enums to strings. In
-case the value does not exist, converting to a string results in NULL and
-converting to an enum results in a negative value.
-
-```c
-enum { VALUE_1, VALUE_2, VALUE_3 } example_t;
-
-int index = hs_create_enum(L,
- "one", VALUE_1,
- "two", VALUE_2,
- "three", VALUE_3,
- HS_END);
-
-example_t e = hs_string_to_enum(L, index, "one"); // VALUE_1
-char *str = hs_enum_to_string(L, index, VALUE_3); // "three"
-```
-
### Table processing
[(Back to top)](#table-of-contents)
-`hs_process_table()` is intended for creating lua bindings that can be called
-like `set_config{ debug=true, verbosity=2, logfile='run.log' }`. It operates
-only on values with string keys and boolean, number, or string types.
-`hs_process_table()` accepts a lua_State pointer, a stack index for the table to
-operate on, and then a series of string key/data type/function/user data void
-pointer quadruplets, finished off by `HS_END`. This function does not pop the
-table from the stack.
+`hs_process_table()` is intended for creating lua bindings that can
+be called like `set_config{ debug=true, verbosity=2,
+logfile='run.log' }`. It operates only on values with string keys
+and boolean, number, or string types. `hs_process_table()` accepts a
+lua_State pointer, a stack index for the table to operate on, and
+then a series of `struct hs_table_processor`s. These can either be
+constructed manually, or via function-like macros. This function
+does not pop the table from the stack.
+
+honeysuckle provides the functions `hs_pt_set_bool`,
+`hs_pt_set_int`, `hs_pt_set_num`, and `hs_pt_set_string` for the
+very common operations of "set a variable to the provided value".
+These can also be set via the function-like macros `hs_set_bool()`,
+`hs_set_int()`, `hs_set_num()`, and `hs_set_str()`.
-honeysuckle provides the functions `hs_pt_set_bool`, `hs_pt_set_int`,
-`hs_pt_set_num`, and `hs_pt_set_string` for the very common operations of "set
-a variable to the provided value". User-defined functions should have signature
-`void (function)([type], void *)`, where [type] is either `lua_Boolean`,
-`lua_Integer`, `lua_Number`, or `const char *`, depending on the expected
-value type.
+User-defined functions should have signature
+`void (function)([type], void *)`, where [type] is either
+`lua_Boolean`, `lua_Integer`, `lua_Number`, or `const char *`,
+depending on the expected value type.
```c
@@ -220,27 +226,31 @@ struct settings {
};
struct settings s;
-
+
hs_process_table(L, tbl_index,
- "verbosity", HS_INT, hs_pt_set_int, &(s.verbosity),
- "debug", HS_BOOL, hs_pt_set_bool, &(s.debug),
- "logfile", HS_STR, set_logfile, &s
- "epsilon", HS_NUM, hs_pt_set_num, &(s.epsilon),
- HS_END);
+ // manual struct initialization
+ { "verbosity", HS_INT, func.integer=hs_pt_set_int, &(s.verbosity) },
+ // macro initialization (recommended)
+ hs_process_bool("debug", hs_pt_set_bool, s.debug),
+ hs_process_str("logfile", set_logfile, s),
+ // alternative to explicitly specifying hs_pt_set_bool
+ hs_set_num("epsilon", s.epsilon)
+);
```
### Errors and error handling
[(Back to top)](#table-of-contents)
-`hs_throw_error()` constructs and throws error messages like printf.
+`hs_throw_error()` constructs and throws error messages like
+printf.
```c
hs_throw_error(L, "ERROR: %d is not within range", 10);
```
-`hs_traceback()` can be supplied to `lua_pcall()` to get a helpful stack
-trace error message:
+`hs_traceback()` can be supplied to `lua_pcall()` to get a helpful
+stack trace error message:
```c
lua_pushcfunction(L, hs_traceback);
@@ -251,28 +261,15 @@ int tr_pos = lua_gettop();
int result = lua_pcall(L, nargs, nret, tr_pos);
```
-`hs_call()` performs the above, accepting simply a lua_State pointer, int
-nargs, and int nret as arguments. Alternatively, you can use `hs_call_args()`
-which provides the same helpful, contained error messages as `hs_call()` but
-takes arguments explicitly in the call for both function arguments and
-returns:
+`hs_call()` performs the above, accepting simply a lua_State
+pointer, int nargs, and int nret as arguments.
-```c
-// some_function accepts int, str and returns number, boolean
-lua_pushcfunction(L, some_function);
-
-lua_Number n;
-bool b;
-hs_call_args(L,
- HS_INT, 4, HS_STR, "hello", HS_END,
- HS_NUM, &n, HS_BOOL, &b, HS_END);
-```
### String wrangling
[(Back to top)](#table-of-contents)
-`hs_pushstring()` allows you to push string values using printf format
+`hs_pushstring()` allows you to push string values using printf format
strings.
```c
@@ -284,8 +281,8 @@ hs_pushstring(L, "hello there, %s. I hear the current time is %d:%02d", "dylan",
[(Back to top)](#table-of-contents)
honeysuckle provides three macros, `hs_rstore()`, `hs_rload()`, and `hs_
-rdel()` to make registry access easier. These are mostly just thin wrappers
-around `luaL_ref()`, `luaL_unref()` and `lua_rawgeti()` but they come up
+rdel()` to make registry access easier. These are mostly just thin wrappers
+around `luaL_ref()`, `luaL_unref()` and `lua_rawgeti()` but they come up
frequently enough that I think these are helpful.
```c
@@ -300,10 +297,12 @@ Development
-----------
[(Back to top)](#table-of-contents)
-honeysuckle is still very early in development. As the specifics of the build
-process and testing become clearer I'll update this section.
+honeysuckle is still very early in development. As the specifics of
+the build process and testing become clearer I'll update this
+section.
-If you're interested in helping out, send me an email! The to-dos at the time of writing are:
+If you're interested in helping out, send me an email! The to-dos at
+the time of writing are:
* Write initial tests for errors, tracebacks, and function calling
* Implement everything
@@ -315,8 +314,8 @@ License
[(Back to top)](#table-of-contents)
-honeysuckle is licensed under the [Anti-Capitalist Software License].
-Basically: if you're a single person, a co-op, or a nonprofit, feel free to
+honeysuckle is licensed under the [Anti-Capitalist Software License].
+Basically: if you're a single person, a co-op, or a nonprofit, feel free to
use this. Otherwise, send me an email. c:
[Anti-Capitalist Software License]: https://anticapitalist.software