all repos — litestore @ 20f1efa1f29fed91d9cbd13872537fb50eae5892

A minimalist nosql document store.

src/litestorepkg/vendor/duktape/extras/print-alert/duk_print_alert.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 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_data(ctx, 0)) {
		buf = (const duk_uint8_t *) duk_get_buffer_data(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 = '\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_data(ctx, 0)) {
		buf = (const duk_uint8_t *) duk_get_buffer_data(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);
}