aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/gopkg.in/olebedev/go-duktape.v3/duk_print_alert.c
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gopkg.in/olebedev/go-duktape.v3/duk_print_alert.c')
-rwxr-xr-xvendor/gopkg.in/olebedev/go-duktape.v3/duk_print_alert.c127
1 files changed, 127 insertions, 0 deletions
diff --git a/vendor/gopkg.in/olebedev/go-duktape.v3/duk_print_alert.c b/vendor/gopkg.in/olebedev/go-duktape.v3/duk_print_alert.c
new file mode 100755
index 000000000..ec1259ff6
--- /dev/null
+++ b/vendor/gopkg.in/olebedev/go-duktape.v3/duk_print_alert.c
@@ -0,0 +1,127 @@
+/*
+ * Duktape 1.x compatible print() and alert() bindings.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "duktape.h"
+#include "duk_print_alert.h"
+
+#define DUK_PRINT_ALERT_FLUSH /* Flush after stdout/stderr write (Duktape 1.x: yes) */
+#undef DUK_PRINT_ALERT_SMALL /* Prefer smaller footprint (but slower and more memory churn) */
+
+#if defined(DUK_PRINT_ALERT_SMALL)
+static duk_ret_t duk__print_alert_helper(duk_context *ctx, FILE *fh) {
+ duk_idx_t nargs;
+
+ nargs = duk_get_top(ctx);
+
+ /* If argument count is 1 and first argument is a buffer, write the buffer
+ * as raw data into the file without a newline; this allows exact control
+ * over stdout/stderr without an additional entrypoint (useful for now).
+ * Otherwise current print/alert semantics are to ToString() coerce
+ * arguments, join them with a single space, and append a newline.
+ */
+
+ if (nargs == 1 && duk_is_buffer(ctx, 0)) {
+ buf = (const duk_uint8_t *) duk_get_buffer(ctx, 0, &sz_buf);
+ fwrite((const void *) buf, 1, (size_t) sz_buf, fh);
+ } else {
+ duk_push_string(ctx, " ");
+ duk_insert(ctx, 0);
+ duk_concat(ctx, nargs);
+ fprintf(fh, "%s\n", duk_require_string(ctx, -1));
+ }
+
+#if defined(DUK_PRINT_ALERT_FLUSH)
+ fflush(fh);
+#endif
+
+ return 0;
+}
+#else
+/* Faster, less churn, higher footprint option. */
+static duk_ret_t duk__print_alert_helper(duk_context *ctx, FILE *fh) {
+ duk_idx_t nargs;
+ const duk_uint8_t *buf;
+ duk_size_t sz_buf;
+ const char nl = (const char) '\n';
+ duk_uint8_t buf_stack[256];
+
+ nargs = duk_get_top(ctx);
+
+ /* If argument count is 1 and first argument is a buffer, write the buffer
+ * as raw data into the file without a newline; this allows exact control
+ * over stdout/stderr without an additional entrypoint (useful for now).
+ * Otherwise current print/alert semantics are to ToString() coerce
+ * arguments, join them with a single space, and append a newline.
+ */
+
+ if (nargs == 1 && duk_is_buffer(ctx, 0)) {
+ buf = (const duk_uint8_t *) duk_get_buffer(ctx, 0, &sz_buf);
+ } else if (nargs > 0) {
+ duk_idx_t i;
+ duk_size_t sz_str;
+ const duk_uint8_t *p_str;
+ duk_uint8_t *p;
+
+ sz_buf = (duk_size_t) nargs; /* spaces (nargs - 1) + newline */
+ for (i = 0; i < nargs; i++) {
+ (void) duk_to_lstring(ctx, i, &sz_str);
+ sz_buf += sz_str;
+ }
+
+ if (sz_buf <= sizeof(buf_stack)) {
+ p = (duk_uint8_t *) buf_stack;
+ } else {
+ p = (duk_uint8_t *) duk_push_fixed_buffer(ctx, sz_buf);
+ }
+
+ buf = (const duk_uint8_t *) p;
+ for (i = 0; i < nargs; i++) {
+ p_str = (const duk_uint8_t *) duk_get_lstring(ctx, i, &sz_str);
+ memcpy((void *) p, (const void *) p_str, sz_str);
+ p += sz_str;
+ *p++ = (duk_uint8_t) (i == nargs - 1 ? '\n' : ' ');
+ }
+ } else {
+ buf = (const duk_uint8_t *) &nl;
+ sz_buf = 1;
+ }
+
+ /* 'buf' contains the string to write, 'sz_buf' contains the length
+ * (which may be zero).
+ */
+
+ if (sz_buf > 0) {
+ fwrite((const void *) buf, 1, (size_t) sz_buf, fh);
+#if defined(DUK_PRINT_ALERT_FLUSH)
+ fflush(fh);
+#endif
+ }
+
+ return 0;
+}
+#endif
+
+static duk_ret_t duk__print(duk_context *ctx) {
+ return duk__print_alert_helper(ctx, stdout);
+}
+
+static duk_ret_t duk__alert(duk_context *ctx) {
+ return duk__print_alert_helper(ctx, stderr);
+}
+
+void duk_print_alert_init(duk_context *ctx, duk_uint_t flags) {
+ (void) flags; /* unused at the moment */
+
+ /* XXX: use duk_def_prop_list(). */
+ duk_push_global_object(ctx);
+ duk_push_string(ctx, "print");
+ duk_push_c_function(ctx, duk__print, DUK_VARARGS);
+ duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_SET_WRITABLE | DUK_DEFPROP_SET_CONFIGURABLE);
+ duk_push_string(ctx, "alert");
+ duk_push_c_function(ctx, duk__alert, DUK_VARARGS);
+ duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_SET_WRITABLE | DUK_DEFPROP_SET_CONFIGURABLE);
+ duk_pop(ctx);
+}