summaryrefslogtreecommitdiff
path: root/libobj
diff options
context:
space:
mode:
Diffstat (limited to 'libobj')
-rw-r--r--libobj/CMakeLists.txt13
-rw-r--r--libobj/include/libobj/obj.h173
l---------libobj/tests/test.h1
-rw-r--r--libobj/tests/test_nest.c73
-rw-r--r--libobj/tests/test_obj.c61
5 files changed, 0 insertions, 321 deletions
diff --git a/libobj/CMakeLists.txt b/libobj/CMakeLists.txt
deleted file mode 100644
index f452e8a..0000000
--- a/libobj/CMakeLists.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-# libobj/CMakeLists.txt - A simple Go-ish object system built on GCC -fplan9-extensions
-#
-# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
-# SPDX-License-Identifier: AGPL-3.0-or-later
-
-add_library(libobj INTERFACE)
-target_include_directories(libobj PUBLIC INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include)
-target_link_libraries(libobj INTERFACE
- libmisc
-)
-
-add_lib_test(libobj test_obj)
-add_lib_test(libobj test_nest)
diff --git a/libobj/include/libobj/obj.h b/libobj/include/libobj/obj.h
deleted file mode 100644
index 06b7298..0000000
--- a/libobj/include/libobj/obj.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/* libobj/obj.h - A simple Go-ish object system
- *
- * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
- * SPDX-License-Identifier: AGPL-3.0-or-later
- */
-
-#ifndef _LIBOBJ_OBJ_H_
-#define _LIBOBJ_OBJ_H_
-
-#include <libmisc/macro.h>
-
-/**
- * Use `lo_interface` similarly to how you would use
- * `struct`/`enum`/`union` when writing the type of an interface
- * value.
- */
-#define lo_interface struct
-
-/**
- * Use `LO_INTERFACE` in a .h file to define an interface.
- *
- * First define a macro named `{iface_name}_LO_IFACE` consisting of a
- * series of calls to LO_NEST and/or LO_FUNC, then call
- * `LO_INTERFACE({iface_name})`:
- *
- * #define myiface_LO_IFACE \
- * LO_NEST(wrapped_iface_name) \
- * LO_FUNC(ret_type, func_name, args...)
- * LO_INTERFACE(myiface)
- *
- * Use `lo_interface {iface_name}` as the type of this interface; it
- * should not be a pointer type.
- *
- * If there are any LO_NEST interfaces, this will define a
- * `lo_box_{iface_name}_as_{wrapped_iface_name}(obj)` function for
- * each.
- */
-#define LO_NEST(_ARG_child_iface_name) \
- (lo_nest, _ARG_child_iface_name)
-#define LO_FUNC(_ARG_ret_type, _ARG_func_name, ...) \
- (lo_func, _ARG_ret_type, _ARG_func_name __VA_OPT__(,) __VA_ARGS__)
-#define LO_INTERFACE(_ARG_iface_name) \
- struct _lo_##_ARG_iface_name##_vtable { \
- LM_FOREACH_TUPLE(_ARG_iface_name##_LO_IFACE, \
- _LO_IFACE_VTABLE) \
- }; \
- struct _ARG_iface_name { \
- void *self; \
- const struct _lo_##_ARG_iface_name##_vtable *vtable; \
- }; \
- LM_FOREACH_TUPLE(_ARG_iface_name##_LO_IFACE, \
- _LO_IFACE_PROTO, _ARG_iface_name) \
- extern int LM_CAT2_(_HIDDEN_BOGUS_, __COUNTER__)
-
-#define _LO_IFACE_VTABLE(_tuple_typ, ...) _LO_IFACE_VTABLE_##_tuple_typ(__VA_ARGS__)
-#define _LO_IFACE_VTABLE_lo_nest(_ARG_child_iface_name) const struct _lo_##_ARG_child_iface_name##_vtable *_lo_##_ARG_child_iface_name##_vtable; LM_FOREACH_TUPLE2(_ARG_child_iface_name##_LO_IFACE, _LO_IFACE_VTABLE2)
-#define _LO_IFACE_VTABLE_lo_func(_ARG_ret_type, _ARG_func_name, ...) _ARG_ret_type (*_ARG_func_name)(void * __VA_OPT__(,) __VA_ARGS__);
-
-#define _LO_IFACE_VTABLE2(_tuple_typ, ...) _LO_IFACE_VTABLE2_##_tuple_typ(__VA_ARGS__)
-#define _LO_IFACE_VTABLE2_lo_nest(_ARG_child_iface_name) const struct _lo_##_ARG_child_iface_name##_vtable *_lo_##_ARG_child_iface_name##_vtable; LM_FOREACH_TUPLE3(_ARG_child_iface_name##_LO_IFACE, _LO_IFACE_VTABLE3)
-#define _LO_IFACE_VTABLE2_lo_func(_ARG_ret_type, _ARG_func_name, ...) _ARG_ret_type (*_ARG_func_name)(void * __VA_OPT__(,) __VA_ARGS__);
-
-#define _LO_IFACE_VTABLE3(_tuple_typ, ...) _LO_IFACE_VTABLE3_##_tuple_typ(__VA_ARGS__)
-#define _LO_IFACE_VTABLE3_lo_nest(_ARG_child_iface_name) const struct _lo_##_ARG_child_iface_name##_vtable *_lo_##_ARG_child_iface_name##_vtable; LM_FOREACH_TUPLE4(_ARG_child_iface_name##_LO_IFACE, _LO_IFACE_VTABLE4)
-#define _LO_IFACE_VTABLE3_lo_func(_ARG_ret_type, _ARG_func_name, ...) _ARG_ret_type (*_ARG_func_name)(void * __VA_OPT__(,) __VA_ARGS__);
-
-#define _LO_IFACE_VTABLE4(_tuple_typ, ...) _LO_IFACE_VTABLE4_##_tuple_typ(__VA_ARGS__)
-#define _LO_IFACE_VTABLE4_lo_nest(_ARG_child_iface_name) static_assert(0, "BUG: libobj cannot nest interfaces more than 4 deep");
-#define _LO_IFACE_VTABLE4_lo_func(_ARG_ret_type, _ARG_func_name, ...) _ARG_ret_type (*_ARG_func_name)(void * __VA_OPT__(,) __VA_ARGS__);
-
-#define _LO_IFACE_PROTO(_ARG_iface_name, _tuple_typ, ...) _LO_IFACE_PROTO_##_tuple_typ(_ARG_iface_name, __VA_ARGS__)
-#define _LO_IFACE_PROTO_lo_nest(_ARG_iface_name, _ARG_child_iface_name) \
- LM_ALWAYS_INLINE static lo_interface _ARG_child_iface_name \
- box_##_ARG_iface_name##_as_##_ARG_child_iface_name(lo_interface _ARG_iface_name obj) { \
- return (lo_interface _ARG_child_iface_name){ \
- .self = obj.self, \
- .vtable = obj.vtable->_lo_##_ARG_child_iface_name##_vtable, \
- }; \
- }
-#define _LO_IFACE_PROTO_lo_func(_ARG_iface_name, _ARG_ret_type, _ARG_func_name, ...) \
- /* empty */
-
-/**
- * `LO_NULL(iface_name)` is the null/nil/zero value for `lo_interface {iface_name}`.
- */
-#define LO_NULL(_ARG_iface_name) ((lo_interface _ARG_iface_name){0})
-
-/**
- * `LO_IS_NULL(iface_val)` returns whether `iface_val` is LO_NULL.
- */
-#define LO_IS_NULL(_ARG_iface_val) ((_ARG_iface_val).vtable == NULL)
-
-/**
- * `LO_IFACE_EQ(a, b)` returns whether the interface values `a` and
- * `b` are the same object.
- */
-#define LO_EQ(_ARG_iface_val_a, _ARG_iface_val_b) \
- ((_ARG_iface_val_a).self == (_ARG_iface_val_b).self)
-
-/**
- * Use LO_CALL(obj, method_name, args...) to call a method on an `lo_interface`.
- */
-#define LO_CALL(_ARG_obj, _ARG_meth, ...) \
- (_ARG_obj).vtable->_ARG_meth((_ARG_obj).self __VA_OPT__(,) __VA_ARGS__)
-
-/**
- * Use `LO_IMPLEMENTATION_H(iface_name, impl_type, impl_name)` in a .h
- * file to declare that `{impl_type}` implements the `{iface_name}`
- * interface with functions named `{impl_name}_{method_name}`.
- *
- * This will also define a `lo_box_{impl_name}_as_{iface_name}(obj)`
- * function.
- *
- * You must also call the LO_IMPLEMENTATION_C in a single .c file.
- */
-#define LO_IMPLEMENTATION_H(_ARG_iface_name, _ARG_impl_type, _ARG_impl_name) \
- /* Vtable. */ \
- extern const struct _lo_##_ARG_iface_name##_vtable \
- _lo_##_ARG_impl_name##_##_ARG_iface_name##_vtable; \
- /* Boxing. */ \
- LM_ALWAYS_INLINE static lo_interface _ARG_iface_name \
- lo_box_##_ARG_impl_name##_as_##_ARG_iface_name(_ARG_impl_type *self) { \
- return (lo_interface _ARG_iface_name){ \
- .self = self, \
- .vtable = &_lo_##_ARG_impl_name##_##_ARG_iface_name##_vtable, \
- }; \
- } \
- LM_FORCE_SEMICOLON
-
-/**
- * Use `LO_IMPLEMENTATION_C(iface_name, impl_type, impl_name[, static])` in a .c
- * file to declare that `{impl_type}` implements the `{iface_name}` interface
- * with functions named `{impl_name}_{method_name}`.
- *
- * You must also call the LO_IMPLEMENTATION_H in the corresponding .h file.
- *
- * If `iface_name` contains a nested interface, then the
- * implementation of the nested interfaces must be declared with
- * `LO_IMPLEMENTATION_C` first.
- */
-#define LO_IMPLEMENTATION_C(_ARG_iface_name, _ARG_impl_type, _ARG_impl_name, ...) \
- /* Method prototypes. */ \
- LM_FOREACH_TUPLE(_ARG_iface_name##_LO_IFACE, \
- _LO_IMPL_PROTO, _ARG_impl_type, _ARG_impl_name, __VA_ARGS__) \
- /* Vtable. */ \
- const struct _lo_##_ARG_iface_name##_vtable \
- _lo_##_ARG_impl_name##_##_ARG_iface_name##_vtable = { \
- LM_FOREACH_TUPLE(_ARG_iface_name##_LO_IFACE, \
- _LO_IMPL_VTABLE, _ARG_impl_name) \
- }
-
-#define _LO_IMPL_PROTO( _ARG_impl_type, _ARG_impl_name, _ARG_quals, _tuple_typ, ...) _LO_IMPL_PROTO_##_tuple_typ(_ARG_impl_type, _ARG_impl_name, _ARG_quals, __VA_ARGS__)
-#define _LO_IMPL_PROTO_lo_nest(_ARG_impl_type, _ARG_impl_name, _ARG_quals, _ARG_child_iface_name) /* empty */
-#define _LO_IMPL_PROTO_lo_func(_ARG_impl_type, _ARG_impl_name, _ARG_quals, _ARG_ret_type, _ARG_func_name, ...) _ARG_quals _ARG_ret_type _ARG_impl_name##_##_ARG_func_name(_ARG_impl_type * __VA_OPT__(,) __VA_ARGS__);
-
-#define _LO_IMPL_VTABLE(_ARG_impl_name, _tuple_typ, ...) _LO_IMPL_VTABLE_##_tuple_typ(_ARG_impl_name, __VA_ARGS__)
-#define _LO_IMPL_VTABLE_lo_nest(_ARG_impl_name, _ARG_child_iface_name) ._lo_##_ARG_child_iface_name##_vtable = &_lo_##_ARG_impl_name##_##_ARG_child_iface_name##_vtable, LM_FOREACH_TUPLE2(_ARG_child_iface_name##_LO_IFACE, _LO_IMPL_VTABLE2, _ARG_impl_name)
-#define _LO_IMPL_VTABLE_lo_func(_ARG_impl_name, _ARG_ret_type, _ARG_func_name, ...) ._ARG_func_name = (void*)_ARG_impl_name##_##_ARG_func_name,
-
-#define _LO_IMPL_VTABLE2(_ARG_impl_name, _tuple_typ, ...) _LO_IMPL_VTABLE2_##_tuple_typ(_ARG_impl_name, __VA_ARGS__)
-#define _LO_IMPL_VTABLE2_lo_nest(_ARG_impl_name, _ARG_child_iface_name) ._lo_##_ARG_child_iface_name##_vtable = &_lo_##_ARG_impl_name##_##_ARG_child_iface_name##_vtable, LM_FOREACH_TUPLE3(_ARG_child_iface_name##_LO_IFACE, _LO_IMPL_VTABLE3, _ARG_impl_name)
-#define _LO_IMPL_VTABLE2_lo_func(_ARG_impl_name, _ARG_ret_type, _ARG_func_name, ...) ._ARG_func_name = (void*)_ARG_impl_name##_##_ARG_func_name,
-
-#define _LO_IMPL_VTABLE3(_ARG_impl_name, _tuple_typ, ...) _LO_IMPL_VTABLE3_##_tuple_typ(_ARG_impl_name, __VA_ARGS__)
-#define _LO_IMPL_VTABLE3_lo_nest(_ARG_impl_name, _ARG_child_iface_name) ._lo_##_ARG_child_iface_name##_vtable = &_lo_##_ARG_impl_name##_##_ARG_child_iface_name##_vtable, LM_FOREACH_TUPLE4(_ARG_child_iface_name##_LO_IFACE, _LO_IMPL_VTABLE4, _ARG_impl_name)
-#define _LO_IMPL_VTABLE3_lo_func(_ARG_impl_name, _ARG_ret_type, _ARG_func_name, ...) ._ARG_func_name = (void*)_ARG_impl_name##_##_ARG_func_name,
-
-#define _LO_IMPL_VTABLE4(_ARG_impl_name, _tuple_typ, ...) _LO_IMPL_VTABLE4_##_tuple_typ(_ARG_impl_name, __VA_ARGS__)
-#define _LO_IMPL_VTABLE4_lo_nest(_ARG_impl_name, _ARG_child_iface_name) static_assert(0, "BUG: libobj cannot nest interfaces more than 4 deep");
-#define _LO_IMPL_VTABLE4_lo_func(_ARG_impl_name, _ARG_ret_type, _ARG_func_name, ...) ._ARG_func_name = (void*)_ARG_impl_name##_##_ARG_func_name,
-
-
-#endif /* _LIBOBJ_OBJ_H_ */
diff --git a/libobj/tests/test.h b/libobj/tests/test.h
deleted file mode 120000
index 2fb1bd5..0000000
--- a/libobj/tests/test.h
+++ /dev/null
@@ -1 +0,0 @@
-../../libmisc/tests/test.h \ No newline at end of file
diff --git a/libobj/tests/test_nest.c b/libobj/tests/test_nest.c
deleted file mode 100644
index f18b018..0000000
--- a/libobj/tests/test_nest.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/* libobj/tests/test_nest.c - Tests for <libobj/obj.h>
- *
- * Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com>
- * SPDX-License-Identifier: AGPL-3.0-or-later
- */
-
-#include <string.h> /* for memcpy() */
-
-#include <libobj/obj.h>
-
-#include "test.h"
-
-/* interfaces *****************************************************************/
-
-#define reader_LO_IFACE \
- LO_FUNC(ssize_t, read, void *, size_t)
-LO_INTERFACE(reader);
-
-#define writer_LO_IFACE \
- LO_FUNC(ssize_t, write, void *, size_t)
-LO_INTERFACE(writer);
-
-#define read_writer_LO_IFACE \
- LO_NEST(reader) \
- LO_NEST(writer)
-LO_INTERFACE(read_writer);
-
-/* implementation header ******************************************************/
-
-struct myclass {
- size_t len;
- char buf[512];
-};
-LO_IMPLEMENTATION_H(reader, struct myclass, myclass);
-LO_IMPLEMENTATION_H(writer, struct myclass, myclass);
-LO_IMPLEMENTATION_H(read_writer, struct myclass, myclass);
-
-/* implementation main ********************************************************/
-
-LO_IMPLEMENTATION_C(reader, struct myclass, myclass, static);
-LO_IMPLEMENTATION_C(writer, struct myclass, myclass, static);
-LO_IMPLEMENTATION_C(read_writer, struct myclass, myclass, static);
-
-static ssize_t myclass_read(struct myclass *self, void *buf, size_t count) {
- test_assert(self);
- if (count > self->len)
- count = self->len;
- memcpy(buf, self->buf, count);
- return count;
-}
-
-static ssize_t myclass_write(struct myclass *self, void *buf, size_t count) {
- test_assert(self);
- if (self->len)
- return -1;
- if (count > sizeof(self->buf))
- count = sizeof(self->buf);
- memcpy(self->buf, buf, count);
- self->len = count;
- return count;
-}
-
-/* main test body *************************************************************/
-
-int main() {
- struct myclass _obj = {0};
- lo_interface read_writer obj = lo_box_myclass_as_read_writer(&_obj);
- test_assert(LO_CALL(obj, write, "Hello", 6) == 6);
- char buf[6] = {0};
- test_assert(LO_CALL(obj, read, buf, 3) == 3);
- test_assert(memcmp(buf, "Hel\0\0\0", 6) == 0);
- return 0;
-}
diff --git a/libobj/tests/test_obj.c b/libobj/tests/test_obj.c
deleted file mode 100644
index d6861dc..0000000
--- a/libobj/tests/test_obj.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/* libobj/tests/test_obj.c - Tests for <libobj/obj.h>
- *
- * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
- * SPDX-License-Identifier: AGPL-3.0-or-later
- */
-
-#include <libobj/obj.h>
-
-#include "test.h"
-
-/* `lo_inteface frobber` header ***********************************************/
-
-#define frobber_LO_IFACE \
- /** Basic function. */ \
- LO_FUNC(int, frob) \
- /** Function that takes 1 argument. */ \
- LO_FUNC(int, frob1, int) \
- /** Function that returns nothing. */ \
- LO_FUNC(void, frob0)
-LO_INTERFACE(frobber);
-
-/* `struct myclass` header ****************************************************/
-
-struct myclass {
- int a;
-};
-LO_IMPLEMENTATION_H(frobber, struct myclass, myclass);
-
-/* `struct myclass` implementation ********************************************/
-
-LO_IMPLEMENTATION_C(frobber, struct myclass, myclass, static);
-
-static int myclass_frob(struct myclass *self) {
- test_assert(self);
- return self->a;
-}
-
-static int myclass_frob1(struct myclass *self, int arg) {
- test_assert(self);
- return arg;
-}
-
-static void myclass_frob0(struct myclass *self) {
- test_assert(self);
-}
-
-/* main test body *************************************************************/
-
-#define MAGIC1 909837
-#define MAGIC2 657441
-
-int main() {
- struct myclass obj = {
- .a = MAGIC1,
- };
- lo_interface frobber iface = lo_box_myclass_as_frobber(&obj);
- test_assert(LO_CALL(iface, frob) == MAGIC1);
- test_assert(LO_CALL(iface, frob1, MAGIC2) == MAGIC2);
- LO_CALL(iface, frob0);
- return 0;
-}