summaryrefslogtreecommitdiffstats
path: root/src/civetweb/src/third_party/duktape-1.8.0/examples/eventloop/main.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/civetweb/src/third_party/duktape-1.8.0/examples/eventloop/main.c256
1 files changed, 256 insertions, 0 deletions
diff --git a/src/civetweb/src/third_party/duktape-1.8.0/examples/eventloop/main.c b/src/civetweb/src/third_party/duktape-1.8.0/examples/eventloop/main.c
new file mode 100644
index 000000000..762792184
--- /dev/null
+++ b/src/civetweb/src/third_party/duktape-1.8.0/examples/eventloop/main.c
@@ -0,0 +1,256 @@
+/*
+ * Main for evloop command line tool.
+ *
+ * Runs a given script from file or stdin inside an eventloop. The
+ * script can then access setTimeout() etc.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifndef NO_SIGNAL
+#include <signal.h>
+#endif
+
+#include "duktape.h"
+
+extern void poll_register(duk_context *ctx);
+extern void ncurses_register(duk_context *ctx);
+extern void socket_register(duk_context *ctx);
+extern void fileio_register(duk_context *ctx);
+extern void eventloop_register(duk_context *ctx);
+extern int eventloop_run(duk_context *ctx); /* Duktape/C function, safe called */
+
+static int c_evloop = 0;
+
+#ifndef NO_SIGNAL
+static void my_sighandler(int x) {
+ fprintf(stderr, "Got signal %d\n", x);
+ fflush(stderr);
+}
+static void set_sigint_handler(void) {
+ (void) signal(SIGINT, my_sighandler);
+}
+#endif /* NO_SIGNAL */
+
+/* Print error to stderr and pop error. */
+static void print_error(duk_context *ctx, FILE *f) {
+ if (duk_is_object(ctx, -1) && duk_has_prop_string(ctx, -1, "stack")) {
+ /* XXX: print error objects specially */
+ /* XXX: pcall the string coercion */
+ duk_get_prop_string(ctx, -1, "stack");
+ if (duk_is_string(ctx, -1)) {
+ fprintf(f, "%s\n", duk_get_string(ctx, -1));
+ fflush(f);
+ duk_pop_2(ctx);
+ return;
+ } else {
+ duk_pop(ctx);
+ }
+ }
+ duk_to_string(ctx, -1);
+ fprintf(f, "%s\n", duk_get_string(ctx, -1));
+ fflush(f);
+ duk_pop(ctx);
+}
+
+int wrapped_compile_execute(duk_context *ctx) {
+ int comp_flags = 0;
+ int rc;
+
+ /* Compile input and place it into global _USERCODE */
+ duk_compile(ctx, comp_flags);
+ duk_push_global_object(ctx);
+ duk_insert(ctx, -2); /* [ ... global func ] */
+ duk_put_prop_string(ctx, -2, "_USERCODE");
+ duk_pop(ctx);
+#if 0
+ printf("compiled usercode\n");
+#endif
+
+ /* Start a zero timer which will call _USERCODE from within
+ * the event loop.
+ */
+ fprintf(stderr, "set _USERCODE timer\n");
+ fflush(stderr);
+ duk_eval_string(ctx, "setTimeout(function() { _USERCODE(); }, 0);");
+ duk_pop(ctx);
+
+ /* Finally, launch eventloop. This call only returns after the
+ * eventloop terminates.
+ */
+ if (c_evloop) {
+ fprintf(stderr, "calling eventloop_run()\n");
+ fflush(stderr);
+ rc = duk_safe_call(ctx, eventloop_run, 0 /*nargs*/, 1 /*nrets*/);
+ if (rc != 0) {
+ fprintf(stderr, "eventloop_run() failed: %s\n", duk_to_string(ctx, -1));
+ fflush(stderr);
+ }
+ duk_pop(ctx);
+ } else {
+ fprintf(stderr, "calling EventLoop.run()\n");
+ fflush(stderr);
+ duk_eval_string(ctx, "EventLoop.run();");
+ duk_pop(ctx);
+ }
+
+ return 0;
+}
+
+int handle_fh(duk_context *ctx, FILE *f, const char *filename) {
+ char *buf = NULL;
+ int len;
+ int got;
+ int rc;
+ int retval = -1;
+
+ if (fseek(f, 0, SEEK_END) < 0) {
+ goto error;
+ }
+ len = (int) ftell(f);
+ if (fseek(f, 0, SEEK_SET) < 0) {
+ goto error;
+ }
+ buf = (char *) malloc(len);
+ if (!buf) {
+ goto error;
+ }
+
+ got = fread((void *) buf, (size_t) 1, (size_t) len, f);
+
+ duk_push_lstring(ctx, buf, got);
+ duk_push_string(ctx, filename);
+
+ free(buf);
+ buf = NULL;
+
+ rc = duk_safe_call(ctx, wrapped_compile_execute, 2 /*nargs*/, 1 /*nret*/);
+ if (rc != DUK_EXEC_SUCCESS) {
+ print_error(ctx, stderr);
+ goto error;
+ } else {
+ duk_pop(ctx);
+ retval = 0;
+ }
+ /* fall thru */
+
+ error:
+ if (buf) {
+ free(buf);
+ }
+ return retval;
+}
+
+int handle_file(duk_context *ctx, const char *filename) {
+ FILE *f = NULL;
+ int retval;
+
+ f = fopen(filename, "rb");
+ if (!f) {
+ fprintf(stderr, "failed to open source file: %s\n", filename);
+ fflush(stderr);
+ goto error;
+ }
+
+ retval = handle_fh(ctx, f, filename);
+
+ fclose(f);
+ return retval;
+
+ error:
+ return -1;
+}
+
+int handle_stdin(duk_context *ctx) {
+ int retval;
+
+ retval = handle_fh(ctx, stdin, "stdin");
+
+ return retval;
+}
+
+int main(int argc, char *argv[]) {
+ duk_context *ctx = NULL;
+ int retval = 0;
+ const char *filename = NULL;
+ int i;
+
+#ifndef NO_SIGNAL
+ set_sigint_handler();
+
+ /* This is useful at the global level; libraries should avoid SIGPIPE though */
+ /*signal(SIGPIPE, SIG_IGN);*/
+#endif
+
+ for (i = 1; i < argc; i++) {
+ char *arg = argv[i];
+ if (!arg) {
+ goto usage;
+ }
+ if (strcmp(arg, "-c") == 0) {
+ c_evloop = 1;
+ } else if (strlen(arg) > 1 && arg[0] == '-') {
+ goto usage;
+ } else {
+ if (filename) {
+ goto usage;
+ }
+ filename = arg;
+ }
+ }
+ if (!filename) {
+ goto usage;
+ }
+
+ ctx = duk_create_heap_default();
+
+ poll_register(ctx);
+ ncurses_register(ctx);
+ socket_register(ctx);
+ fileio_register(ctx);
+
+ if (c_evloop) {
+ fprintf(stderr, "Using C based eventloop (omit -c to use Ecmascript based eventloop)\n");
+ fflush(stderr);
+
+ eventloop_register(ctx);
+ duk_eval_file(ctx, "c_eventloop.js");
+ } else {
+ fprintf(stderr, "Using Ecmascript based eventloop (give -c to use C based eventloop)\n");
+ fflush(stderr);
+
+ duk_eval_file(ctx, "ecma_eventloop.js");
+ }
+
+ fprintf(stderr, "Executing code from: '%s'\n", filename);
+ fflush(stderr);
+
+ if (strcmp(filename, "-") == 0) {
+ if (handle_stdin(ctx) != 0) {
+ retval = 1;
+ goto cleanup;
+ }
+ } else {
+ if (handle_file(ctx, filename) != 0) {
+ retval = 1;
+ goto cleanup;
+ }
+ }
+
+ cleanup:
+ if (ctx) {
+ duk_destroy_heap(ctx);
+ }
+
+ return retval;
+
+ usage:
+ fprintf(stderr, "Usage: evloop [-c] <filename>\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, "Uses an Ecmascript based eventloop (ecma_eventloop.js) by default.\n");
+ fprintf(stderr, "If -c option given, uses a C based eventloop (c_eventloop.{c,js}).\n");
+ fprintf(stderr, "If <filename> is '-', the entire STDIN executed.\n");
+ fflush(stderr);
+ exit(1);
+}