Mercurial > irccd
changeset 567:cf734c969727
Irccd: convert to dukx_type_traits:
- std::shared_ptr<server>
- std::shared_ptr<file>
- struct stat
author | David Demelier <markand@malikania.fr> |
---|---|
date | Mon, 27 Nov 2017 15:49:57 +0100 |
parents | bf56628e070b |
children | ed986ae52656 |
files | libirccd-js/irccd/js/duktape.hpp libirccd-js/irccd/js/file_jsapi.cpp libirccd-js/irccd/js/file_jsapi.hpp libirccd-js/irccd/js/js_plugin.cpp libirccd-js/irccd/js/server_jsapi.cpp libirccd-js/irccd/js/server_jsapi.hpp libirccd-js/irccd/js/system_jsapi.cpp |
diffstat | 7 files changed, 292 insertions(+), 163 deletions(-) [+] |
line wrap: on
line diff
--- a/libirccd-js/irccd/js/duktape.hpp Mon Nov 27 15:03:38 2017 +0100 +++ b/libirccd-js/irccd/js/duktape.hpp Mon Nov 27 15:49:57 2017 +0100 @@ -23,7 +23,7 @@ * \file duktape.hpp * \brief Miscellaneous Duktape extras * \author David Demelier <markand@malikania.fr> - * \version 0.1.0 + * \version 0.2.0 */ #include <cassert> @@ -317,6 +317,20 @@ { return duk_get_boolean(ctx, index); } + + /** + * Require a boolean. + * + * Uses duk_require_boolean. + * + * \param ctx the Duktape context + * \param index the value index + * \return the converted value + */ + static bool require(duk_context* ctx, duk_idx_t index) + { + return duk_require_boolean(ctx, index); + } }; /** @@ -351,6 +365,20 @@ { return duk_get_number(ctx, index); } + + /** + * Require a double. + * + * Uses duk_require_double. + * + * \param ctx the Duktape context + * \param index the value index + * \return the converted value + */ + static duk_double_t require(duk_context* ctx, duk_idx_t index) + { + return duk_require_number(ctx, index); + } }; /** @@ -385,6 +413,20 @@ { return duk_get_int(ctx, index); } + + /** + * Require an int. + * + * Uses duk_require_int. + * + * \param ctx the Duktape context + * \param index the value index + * \return the converted value + */ + static duk_int_t require(duk_context* ctx, duk_idx_t index) + { + return duk_require_int(ctx, index); + } }; /** @@ -419,6 +461,20 @@ { return duk_get_uint(ctx, index); } + + /** + * Require an unsigned int. + * + * Uses duk_require_uint. + * + * \param ctx the Duktape context + * \param index the value index + * \return the converted value + */ + static duk_uint_t require(duk_context* ctx, duk_idx_t index) + { + return duk_require_uint(ctx, index); + } }; /** @@ -453,6 +509,20 @@ { return duk_get_string(ctx, index); } + + /** + * Require a C string. + * + * Uses duk_require_string. + * + * \param ctx the Duktape context + * \param index the value index + * \return the converted value + */ + static const char* require(duk_context* ctx, duk_idx_t index) + { + return duk_require_string(ctx, index); + } }; /** @@ -490,6 +560,23 @@ return {str, length}; } + + /** + * Require a C++ std::string. + * + * Uses duk_require_lstring. + * + * \param ctx the Duktape context + * \param index the value index + * \return the converted value + */ + static std::string require(duk_context* ctx, duk_idx_t index) + { + duk_size_t length; + const char* str = duk_require_lstring(ctx, index, &length); + + return {str, length}; + } }; /** @@ -533,6 +620,25 @@ } /** + * Generic require function. + * + * This functions calls dukx_type_traits<T>::require if specialized. + * + * \param ctx the Duktape context + * \param index the value index + * \return the converted value + */ +template <typename T> +T dukx_require(duk_context* ctx, duk_idx_t index) +{ + using Type = typename std::decay<T>::type; + + static_assert(dukx_type_traits<Type>::value, "type T not supported"); + + return dukx_type_traits<Type>::require(ctx, index); +} + +/** * Push a Javascript array to the stack. * * This function push the value using duk_push_array and dukx_push for each @@ -542,6 +648,7 @@ * \param it the input iterator * \param end the end iterator * \return 1 for convenience + * \warning experimental and may change in the future */ template <typename InputIt> int dukx_push_array(duk_context* ctx, InputIt it, InputIt end) @@ -564,6 +671,7 @@ * \param ctx the Duktape context * \param values the list of values * \return 1 for convenience + * \warning experimental and may change in the future */ template <typename T> int dukx_push_array(duk_context* ctx, std::initializer_list<T> values) @@ -583,6 +691,7 @@ * \param it the input iterator * \param end the end iterator * \return 1 for convenience + * \warning experimental and may change in the future */ template <typename InputIt> int dukx_push_object(duk_context* ctx, InputIt it, InputIt end) @@ -606,6 +715,7 @@ * \param ctx the Duktape context * \param values the list of key/value values * \return 1 for convenience + * \warning experimental and may change in the future */ template <typename T> int dukx_push_object(duk_context* ctx, std::initializer_list<std::pair<std::string, T>> values) @@ -622,6 +732,7 @@ * \param ctx the Duktape context * \param index the array index * \param output the output iterator + * \warning experimental and may change in the future */ template <typename T, typename OutputIt> void dukx_get_array(duk_context* ctx, duk_idx_t index, OutputIt output) @@ -643,6 +754,7 @@ * \param ctx the Duktape context * \param index the array index * \return the container of values (e.g. `std::vector<int>`) + * \warning experimental and may change in the future */ template <typename Container> Container dukx_get_array(duk_context* ctx, duk_idx_t index) @@ -662,6 +774,7 @@ * \param ctx the Duktape context * \param index the object index * \return the container of values (e.g. `std::map<std::string, int>`) + * \warning experimental and may change in the future */ template <typename Container> Container dukx_get_object(duk_context* ctx, duk_idx_t index)
--- a/libirccd-js/irccd/js/file_jsapi.cpp Mon Nov 27 15:03:38 2017 +0100 +++ b/libirccd-js/irccd/js/file_jsapi.cpp Mon Nov 27 15:49:57 2017 +0100 @@ -16,8 +16,6 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <irccd/sysconfig.hpp> - #include <algorithm> #include <array> #include <cassert> @@ -26,11 +24,6 @@ #include <boost/filesystem.hpp> -#if defined(HAVE_STAT) -# include <sys/types.h> -# include <sys/stat.h> -#endif - #include <irccd/fs_util.hpp> #include "file_jsapi.hpp" @@ -44,75 +37,6 @@ const char *signature("\xff""\xff""irccd-file-ptr"); const char *prototype("\xff""\xff""irccd-file-prototype"); -#if defined(HAVE_STAT) - -/* - * push_stat - * ------------------------------------------------------------------ - */ - -void push_stat(duk_context* ctx, const struct stat& st) -{ - dukx_stack_assert sa(ctx, 1); - - duk_push_object(ctx); - -#if defined(HAVE_STAT_ST_ATIME) - duk_push_int(ctx, st.st_atime); - duk_put_prop_string(ctx, -2, "atime"); -#endif -#if defined(HAVE_STAT_ST_BLKSIZE) - duk_push_int(ctx, st.st_blksize); - duk_put_prop_string(ctx, -2, "blksize"); -#endif -#if defined(HAVE_STAT_ST_BLOCKS) - duk_push_int(ctx, st.st_blocks); - duk_put_prop_string(ctx, -2, "blocks"); -#endif -#if defined(HAVE_STAT_ST_CTIME) - duk_push_int(ctx, st.st_ctime); - duk_put_prop_string(ctx, -2, "ctime"); -#endif -#if defined(HAVE_STAT_ST_DEV) - duk_push_int(ctx, st.st_dev); - duk_put_prop_string(ctx, -2, "dev"); -#endif -#if defined(HAVE_STAT_ST_GID) - duk_push_int(ctx, st.st_gid); - duk_put_prop_string(ctx, -2, "gid"); -#endif -#if defined(HAVE_STAT_ST_INO) - duk_push_int(ctx, st.st_ino); - duk_put_prop_string(ctx, -2, "ino"); -#endif -#if defined(HAVE_STAT_ST_MODE) - duk_push_int(ctx, st.st_mode); - duk_put_prop_string(ctx, -2, "mode"); -#endif -#if defined(HAVE_STAT_ST_MTIME) - duk_push_int(ctx, st.st_mtime); - duk_put_prop_string(ctx, -2, "mtime"); -#endif -#if defined(HAVE_STAT_ST_NLINK) - duk_push_int(ctx, st.st_nlink); - duk_put_prop_string(ctx, -2, "nlink"); -#endif -#if defined(HAVE_STAT_ST_RDEV) - duk_push_int(ctx, st.st_rdev); - duk_put_prop_string(ctx, -2, "rdev"); -#endif -#if defined(HAVE_STAT_ST_SIZE) - duk_push_int(ctx, st.st_size); - duk_put_prop_string(ctx, -2, "size"); -#endif -#if defined(HAVE_STAT_ST_UID) - duk_push_int(ctx, st.st_uid); - duk_put_prop_string(ctx, -2, "uid"); -#endif -} - -#endif // !HAVE_STAT - // Remove trailing \r for CRLF line style. inline std::string clear_crlf(std::string input) { @@ -122,19 +46,19 @@ return input; } -file* self(duk_context* ctx) +std::shared_ptr<file> self(duk_context* ctx) { dukx_stack_assert sa(ctx); duk_push_this(ctx); duk_get_prop_string(ctx, -1, signature); - auto ptr = static_cast<file*>(duk_to_pointer(ctx, -1)); + auto ptr = static_cast<std::shared_ptr<file>*>(duk_to_pointer(ctx, -1)); duk_pop_2(ctx); if (!ptr) duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a File object"); - return ptr; + return *ptr; } /* @@ -371,7 +295,7 @@ if (file->handle() == nullptr && ::stat(file->path().c_str(), &st) < 0) dukx_throw(ctx, system_error()); else - push_stat(ctx, st); + dukx_push(ctx, st); return 1; } @@ -476,8 +400,14 @@ return 0; try { - dukx_new_file(ctx, new file(duk_require_string(ctx, 0), duk_require_string(ctx, 1))); - } catch (const std::exception &) { + auto path = dukx_require<std::string>(ctx, 0); + auto mode = dukx_require<std::string>(ctx, 1); + + duk_push_this(ctx); + duk_push_pointer(ctx, new std::shared_ptr<file>(new file(path, mode))); + duk_put_prop_string(ctx, -2, signature); + duk_pop(ctx); + } catch (const std::exception&) { dukx_throw(ctx, system_error()); } @@ -493,7 +423,7 @@ duk_ret_t destructor(duk_context* ctx) { duk_get_prop_string(ctx, 0, signature); - delete static_cast<file*>(duk_to_pointer(ctx, -1)); + delete static_cast<std::shared_ptr<file>*>(duk_to_pointer(ctx, -1)); duk_pop(ctx); duk_del_prop_string(ctx, 0, signature); @@ -597,9 +527,7 @@ if (::stat(duk_require_string(ctx, 0), &st) < 0) dukx_throw(ctx, system_error()); - push_stat(ctx, st); - - return 1; + return dukx_push(ctx, st); } #endif // !HAVE_STAT @@ -648,20 +576,9 @@ duk_pop(plugin->context()); } -void dukx_new_file(duk_context* ctx, file* fp) -{ - assert(ctx); - assert(fp); - - dukx_stack_assert sa(ctx); +using file_traits = dukx_type_traits<std::shared_ptr<file>>; - duk_push_this(ctx); - duk_push_pointer(ctx, fp); - duk_put_prop_string(ctx, -2, signature); - duk_pop(ctx); -} - -void dukx_push_file(duk_context* ctx, file* fp) +void file_traits::push(duk_context* ctx, std::shared_ptr<file> fp) { assert(ctx); assert(fp); @@ -669,22 +586,86 @@ dukx_stack_assert sa(ctx, 1); duk_push_object(ctx); - duk_push_pointer(ctx, fp); + duk_push_pointer(ctx, new std::shared_ptr<file>(std::move(fp))); duk_put_prop_string(ctx, -2, signature); duk_get_global_string(ctx, prototype); duk_set_prototype(ctx, -2); } -file* dukx_require_file(duk_context* ctx, duk_idx_t index) +std::shared_ptr<file> file_traits::require(duk_context* ctx, duk_idx_t index) { if (!duk_is_object(ctx, index) || !duk_has_prop_string(ctx, index, signature)) duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a File object"); duk_get_prop_string(ctx, index, signature); - auto fp = static_cast<file*>(duk_to_pointer(ctx, -1)); + auto fp = static_cast<std::shared_ptr<file>*>(duk_to_pointer(ctx, -1)); duk_pop(ctx); - return fp; + return *fp; } +#if defined(HAVE_STAT) + +void dukx_type_traits<struct stat>::push(duk_context* ctx, const struct stat& st) +{ + dukx_stack_assert sa(ctx, 1); + + duk_push_object(ctx); + +#if defined(HAVE_STAT_ST_ATIME) + duk_push_int(ctx, st.st_atime); + duk_put_prop_string(ctx, -2, "atime"); +#endif +#if defined(HAVE_STAT_ST_BLKSIZE) + duk_push_int(ctx, st.st_blksize); + duk_put_prop_string(ctx, -2, "blksize"); +#endif +#if defined(HAVE_STAT_ST_BLOCKS) + duk_push_int(ctx, st.st_blocks); + duk_put_prop_string(ctx, -2, "blocks"); +#endif +#if defined(HAVE_STAT_ST_CTIME) + duk_push_int(ctx, st.st_ctime); + duk_put_prop_string(ctx, -2, "ctime"); +#endif +#if defined(HAVE_STAT_ST_DEV) + duk_push_int(ctx, st.st_dev); + duk_put_prop_string(ctx, -2, "dev"); +#endif +#if defined(HAVE_STAT_ST_GID) + duk_push_int(ctx, st.st_gid); + duk_put_prop_string(ctx, -2, "gid"); +#endif +#if defined(HAVE_STAT_ST_INO) + duk_push_int(ctx, st.st_ino); + duk_put_prop_string(ctx, -2, "ino"); +#endif +#if defined(HAVE_STAT_ST_MODE) + duk_push_int(ctx, st.st_mode); + duk_put_prop_string(ctx, -2, "mode"); +#endif +#if defined(HAVE_STAT_ST_MTIME) + duk_push_int(ctx, st.st_mtime); + duk_put_prop_string(ctx, -2, "mtime"); +#endif +#if defined(HAVE_STAT_ST_NLINK) + duk_push_int(ctx, st.st_nlink); + duk_put_prop_string(ctx, -2, "nlink"); +#endif +#if defined(HAVE_STAT_ST_RDEV) + duk_push_int(ctx, st.st_rdev); + duk_put_prop_string(ctx, -2, "rdev"); +#endif +#if defined(HAVE_STAT_ST_SIZE) + duk_push_int(ctx, st.st_size); + duk_put_prop_string(ctx, -2, "size"); +#endif +#if defined(HAVE_STAT_ST_UID) + duk_push_int(ctx, st.st_uid); + duk_put_prop_string(ctx, -2, "uid"); +#endif +} + +#endif // !HAVE_STAT + } // !irccd
--- a/libirccd-js/irccd/js/file_jsapi.hpp Mon Nov 27 15:03:38 2017 +0100 +++ b/libirccd-js/irccd/js/file_jsapi.hpp Mon Nov 27 15:49:57 2017 +0100 @@ -24,6 +24,13 @@ * \brief Irccd.File Javascript API. */ +#include <irccd/sysconfig.hpp> + +#if defined(HAVE_STAT) +# include <sys/types.h> +# include <sys/stat.h> +#endif + #include <cassert> #include <cerrno> #include <cstdio> @@ -150,33 +157,52 @@ }; /** - * Construct the file as this. - * - * The object prototype takes ownership of fp and will be deleted once - * collected. + * \brief Specialization for generic file type as shared_ptr. * - * \pre fp != nullptr - * \param ctx the the context - * \param fp the file + * Supports push, require. */ -void dukx_new_file(duk_context* ctx, file* fp); +template <> +class dukx_type_traits<std::shared_ptr<file>> : public std::true_type { +public: + /** + * Push a file. + * + * \pre fp != nullptr + * \param ctx the the context + * \param fp the file + */ + static void push(duk_context* ctx, std::shared_ptr<file> fp); + + /** + * Require a file. Raises a JavaScript error if not a File. + * + * \param ctx the context + * \param index the index + * \return the file pointer + */ + static std::shared_ptr<file> require(duk_context* ctx, duk_idx_t index); +}; + +#if defined(HAVE_STAT) /** - * Push a file. + * \brief Specialization for struct stat. * - * \pre fp != nullptr - * \param ctx the the context - * \param fp the file + * Supports push. */ -void dukx_push_file(duk_context* ctx, file* fp); +template <> +class dukx_type_traits<struct stat> : public std::true_type { +public: + /** + * Push the stat information to the stack as Javascript object. + * + * \param ctx the context + * \param st the stat structure + */ + static void push(duk_context* ctx, const struct stat& st); +}; -/** - * Require a file. Raises a JavaScript error if not a File. - * - * \param ctx the context - * \param index the index - */ -file* dukx_require_file(duk_context* ctx, duk_idx_t index); +#endif // !HAVE_STAT } // !irccd
--- a/libirccd-js/irccd/js/js_plugin.cpp Mon Nov 27 15:03:38 2017 +0100 +++ b/libirccd-js/irccd/js/js_plugin.cpp Mon Nov 27 15:49:57 2017 +0100 @@ -150,7 +150,7 @@ { dukx_stack_assert sa(context_); - dukx_push_server(context_, std::move(event.server)); + dukx_push(context_, std::move(event.server)); dukx_push(context_, event.origin); dukx_push(context_, event.channel); dukx_push(context_, event.mode); @@ -162,7 +162,7 @@ { dukx_stack_assert sa(context_); - dukx_push_server(context_, std::move(event.server)); + dukx_push(context_, std::move(event.server)); dukx_push(context_, event.origin); dukx_push(context_, event.channel); dukx_push(context_, event.message); @@ -173,7 +173,7 @@ { dukx_stack_assert sa(context_); - dukx_push_server(context_, std::move(event.server)); + dukx_push(context_, std::move(event.server)); dukx_push(context_, event.origin); dukx_push(context_, event.channel); dukx_push(context_, event.message); @@ -184,7 +184,7 @@ { dukx_stack_assert sa(context_); - dukx_push_server(context_, std::move(event.server)); + dukx_push(context_, std::move(event.server)); call("onConnect", 1); } @@ -192,7 +192,7 @@ { dukx_stack_assert sa(context_); - dukx_push_server(context_, std::move(event.server)); + dukx_push(context_, std::move(event.server)); dukx_push(context_, event.origin); dukx_push(context_, event.channel); call("onInvite", 3); @@ -202,7 +202,7 @@ { dukx_stack_assert sa(context_); - dukx_push_server(context_, std::move(event.server)); + dukx_push(context_, std::move(event.server)); dukx_push(context_, event.origin); dukx_push(context_, event.channel); call("onJoin", 3); @@ -212,7 +212,7 @@ { dukx_stack_assert sa(context_); - dukx_push_server(context_, std::move(event.server)); + dukx_push(context_, std::move(event.server)); dukx_push(context_, event.origin); dukx_push(context_, event.channel); dukx_push(context_, event.target); @@ -231,7 +231,7 @@ { dukx_stack_assert sa(context_); - dukx_push_server(context_, std::move(event.server)); + dukx_push(context_, std::move(event.server)); dukx_push(context_, event.origin); dukx_push(context_, event.channel); dukx_push(context_, event.message); @@ -242,7 +242,7 @@ { dukx_stack_assert sa(context_); - dukx_push_server(context_, std::move(event.server)); + dukx_push(context_, std::move(event.server)); dukx_push(context_, event.origin); dukx_push(context_, event.channel); dukx_push(context_, event.message); @@ -253,7 +253,7 @@ { dukx_stack_assert sa(context_); - dukx_push_server(context_, std::move(event.server)); + dukx_push(context_, std::move(event.server)); dukx_push(context_, event.origin); dukx_push(context_, event.mode); call("onMode", 3); @@ -263,7 +263,7 @@ { dukx_stack_assert sa(context_); - dukx_push_server(context_, std::move(event.server)); + dukx_push(context_, std::move(event.server)); dukx_push(context_, event.channel); dukx_push_array(context_, event.names.begin(), event.names.end()); @@ -274,7 +274,7 @@ { dukx_stack_assert sa(context_); - dukx_push_server(context_, std::move(event.server)); + dukx_push(context_, std::move(event.server)); dukx_push(context_, event.origin); dukx_push(context_, event.nickname); call("onNick", 3); @@ -284,7 +284,7 @@ { dukx_stack_assert sa(context_); - dukx_push_server(context_, std::move(event.server)); + dukx_push(context_, std::move(event.server)); dukx_push(context_, event.origin); dukx_push(context_, event.message); call("onNotice", 3); @@ -294,7 +294,7 @@ { dukx_stack_assert sa(context_); - dukx_push_server(context_, std::move(event.server)); + dukx_push(context_, std::move(event.server)); dukx_push(context_, event.origin); dukx_push(context_, event.channel); dukx_push(context_, event.reason); @@ -305,7 +305,7 @@ { dukx_stack_assert sa(context_); - dukx_push_server(context_, std::move(event.server)); + dukx_push(context_, std::move(event.server)); dukx_push(context_, event.origin); dukx_push(context_, event.message); call("onQuery", 3); @@ -315,7 +315,7 @@ { dukx_stack_assert sa(context_); - dukx_push_server(context_, std::move(event.server)); + dukx_push(context_, std::move(event.server)); dukx_push(context_, event.origin); dukx_push(context_, event.message); call("onQueryCommand", 3); @@ -332,7 +332,7 @@ { dukx_stack_assert sa(context_); - dukx_push_server(context_, std::move(event.server)); + dukx_push(context_, std::move(event.server)); dukx_push(context_, event.origin); dukx_push(context_, event.channel); dukx_push(context_, event.topic); @@ -350,7 +350,7 @@ { dukx_stack_assert sa(context_); - dukx_push_server(context_, std::move(event.server)); + dukx_push(context_, std::move(event.server)); duk_push_object(context_); dukx_push(context_, event.whois.nick); duk_put_prop_string(context_, -2, "nickname");
--- a/libirccd-js/irccd/js/server_jsapi.cpp Mon Nov 27 15:03:38 2017 +0100 +++ b/libirccd-js/irccd/js/server_jsapi.cpp Mon Nov 27 15:49:57 2017 +0100 @@ -429,7 +429,7 @@ */ duk_ret_t add(duk_context* ctx) { - dukx_get_irccd(ctx).servers().add(dukx_require_server(ctx, 0)); + dukx_get_irccd(ctx).servers().add(dukx_require<std::shared_ptr<server>>(ctx, 0)); return 0; } @@ -452,7 +452,7 @@ if (!server) return 0; - dukx_push_server(ctx, server); + dukx_push(ctx, server); return 1; } @@ -471,7 +471,7 @@ duk_push_object(ctx); for (const auto &server : dukx_get_irccd(ctx).servers().servers()) { - dukx_push_server(ctx, server); + dukx_push(ctx, server); duk_put_prop_string(ctx, -2, server->name().c_str()); } @@ -549,7 +549,9 @@ duk_pop(plugin->context()); } -void dukx_push_server(duk_context* ctx, std::shared_ptr<server> server) +using server_traits = dukx_type_traits<std::shared_ptr<server>>; + +void server_traits::push(duk_context* ctx, std::shared_ptr<server> server) { assert(ctx); assert(server); @@ -563,7 +565,7 @@ duk_set_prototype(ctx, -2); } -std::shared_ptr<server> dukx_require_server(duk_context* ctx, duk_idx_t index) +std::shared_ptr<server> server_traits::require(duk_context* ctx, duk_idx_t index) { if (!duk_is_object(ctx, index) || !duk_has_prop_string(ctx, index, signature)) duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a Server object");
--- a/libirccd-js/irccd/js/server_jsapi.hpp Mon Nov 27 15:03:38 2017 +0100 +++ b/libirccd-js/irccd/js/server_jsapi.hpp Mon Nov 27 15:49:57 2017 +0100 @@ -47,22 +47,31 @@ }; /** - * Push a server. + * \brief Specialization for servers as shared_ptr. * - * \pre server != nullptr - * \param ctx the context - * \param server the server + * Supports push, require. */ -void dukx_push_server(duk_context* ctx, std::shared_ptr<server> server); +template <> +class dukx_type_traits<std::shared_ptr<server>> : public std::true_type { +public: + /** + * Push a server. + * + * \pre server != nullptr + * \param ctx the context + * \param server the server + */ + static void push(duk_context* ctx, std::shared_ptr<server> server); -/** - * Require a server. Raise a Javascript error if not a Server. - * - * \param ctx the context - * \param index the index - * \return the server - */ -std::shared_ptr<server> dukx_require_server(duk_context* ctx, duk_idx_t index); + /** + * Require a server. Raise a Javascript error if not a Server. + * + * \param ctx the context + * \param index the index + * \return the server + */ + static std::shared_ptr<server> require(duk_context* ctx, duk_idx_t index); +}; } // !irccd
--- a/libirccd-js/irccd/js/system_jsapi.cpp Mon Nov 27 15:03:38 2017 +0100 +++ b/libirccd-js/irccd/js/system_jsapi.cpp Mon Nov 27 15:49:57 2017 +0100 @@ -120,9 +120,7 @@ if (fp == nullptr) dukx_throw(ctx, system_error()); - dukx_push_file(ctx, new file(fp, [] (auto fp) { ::pclose(fp); })); - - return 1; + return dukx_push(ctx, std::make_shared<file>(fp, [] (auto fp) { ::pclose(fp); })); } #endif // !HAVE_POPEN