aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndre Weissflog <floooh@gmail.com>2018-10-17 19:36:58 +0200
committerAndre Weissflog <floooh@gmail.com>2018-10-17 19:36:58 +0200
commita85bf31b5573286ec8a9b1d192607f85cd019f30 (patch)
treebeffb00b36a6aad29f794b6223df3df105e2b29a
parente98796b7731ddfd5d921b0f89126ed8d1d6a05b1 (diff)
sokol_args.h: emscripten support
-rw-r--r--sokol_args.h96
1 files changed, 90 insertions, 6 deletions
diff --git a/sokol_args.h b/sokol_args.h
index 87247d67..bf279d6a 100644
--- a/sokol_args.h
+++ b/sokol_args.h
@@ -61,6 +61,14 @@
Return value associated with key, or the provided default
value if the value doesn't exist or has no key.
+ bool sargs_equals(const char* key, const char* val);
+ Return true if the value associated with key matches
+ the 'val' argument.
+
+ bool sargs_boolean(const char* key)
+ Return true if the value string associated with 'key' is one
+ of 'true', 'yes', 'on'.
+
int sargs_find(const char* key)
Find argument by key name and return its index, or -1 if not found.
@@ -110,7 +118,7 @@ extern "C" {
typedef struct {
int argc;
- const char** argv;
+ char** argv;
int max_args;
int buf_size;
} sargs_desc;
@@ -127,6 +135,10 @@ extern bool sargs_exists(const char* key);
extern const char* sargs_value(const char* key);
/* get value by key name, return provided default if key doesn't exist */
extern const char* sargs_value_def(const char* key, const char* def);
+/* return true if val arg matches the value associated with key */
+extern bool sargs_equals(const char* key, const char* val);
+/* return true if key's value is "true", "yes" or "on" */
+extern bool sargs_boolean(const char* key);
/* get index of arg by key name, return -1 if not exists */
extern int sargs_find(const char* key);
/* get number of parsed arguments */
@@ -144,6 +156,10 @@ extern const char* sargs_value_at(int index);
#ifdef SOKOL_IMPL
#include <string.h>
+#if defined(__EMSCRIPTEN__)
+#include <emscripten/emscripten.h>
+#endif
+
#ifndef SOKOL_DEBUG
#ifdef _DEBUG
#define SOKOL_DEBUG (1)
@@ -184,13 +200,15 @@ extern const char* sargs_value_at(int index);
#define _SARGS_MAX_ARGS_DEF (16)
#define _SARGS_BUF_SIZE_DEF (16*1024)
-/* parser state */
+/* parser state (no parser needed on emscripten) */
+#if !defined(__EMSCRIPTEN__)
#define _SARGS_EXPECT_KEY (1<<0)
#define _SARGS_EXPECT_SEP (1<<1)
#define _SARGS_EXPECT_VAL (1<<2)
#define _SARGS_PARSING_KEY (1<<3)
#define _SARGS_PARSING_VAL (1<<4)
#define _SARGS_ERROR (1<<5)
+#endif
/* a key/value pair struct */
typedef struct {
@@ -207,9 +225,13 @@ typedef struct {
int buf_pos; /* current buffer position */
char* buf; /* character buffer, first char is reserved and zero for 'empty string' */
bool valid;
+
+ /* arg parsing isn't needed on emscripten */
+ #if !defined(__EMSCRIPTEN__)
uint32_t parse_state;
char quote; /* current quote char, 0 if not in a quote */
bool in_escape; /* currently in an escape sequence */
+ #endif
} _sargs_state;
static _sargs_state _sargs;
@@ -221,6 +243,13 @@ _SOKOL_PRIVATE void _sargs_putc(char c) {
}
}
+_SOKOL_PRIVATE const char* _sargs_str(int index) {
+ SOKOL_ASSERT((index >= 0) && (index < _sargs.buf_size));
+ return &_sargs.buf[index];
+}
+
+/*-- argument parser functions (not required on emscripten) ------------------*/
+#if !defined(__EMSCRIPTEN__)
_SOKOL_PRIVATE void _sargs_expect_key(void) {
_sargs.parse_state = _SARGS_EXPECT_KEY;
}
@@ -430,12 +459,49 @@ _SOKOL_PRIVATE bool _sargs_parse_cargs(int argc, const char** argv) {
_sargs.parse_state = 0;
return retval;
}
+#endif /* __EMSCRIPTEN__ */
-_SOKOL_PRIVATE const char* _sargs_str(int index) {
- SOKOL_ASSERT((index >= 0) && (index < _sargs.buf_size));
- return &_sargs.buf[index];
+/*-- EMSCRIPTEN IMPLEMENTATION -----------------------------------------------*/
+#if defined(__EMSCRIPTEN__)
+
+EMSCRIPTEN_KEEPALIVE void _sargs_add_kvp(const char* key, const char* val) {
+ SOKOL_ASSERT(_sargs.valid && key && val);
+ if (_sargs.num_args >= _sargs.max_args) {
+ return;
+ }
+
+ /* copy key string */
+ char c;
+ _sargs.args[_sargs.num_args].key = _sargs.buf_pos;
+ const char* ptr = key;
+ while (0 != (c = *ptr++)) {
+ _sargs_putc(c);
+ }
+ _sargs_putc(0);
+
+ /* copy value string */
+ _sargs.args[_sargs.num_args].val = _sargs.buf_pos;
+ ptr = val;
+ while (0 != (c = *ptr++)) {
+ _sargs_putc(c);
+ }
+ _sargs_putc(0);
+
+ _sargs.num_args++;
}
+/* JS function to extract arguments from the page URL */
+EM_JS(void, sargs_js_parse_url, (), {
+ var params = new URLSearchParams(window.location.search).entries();
+ for (var p = params.next(); !p.done; p = params.next()) {
+ var key = p.value[0];
+ var val = p.value[1];
+ var res = Module.ccall('_sargs_add_kvp', 'void', ['string','string'], [key,val]);
+ }
+});
+
+#endif /* EMSCRIPTEN */
+
/*== PUBLIC IMPLEMENTATION FUNCTIONS =========================================*/
void sargs_setup(const sargs_desc* desc) {
SOKOL_ASSERT(desc);
@@ -447,7 +513,13 @@ void sargs_setup(const sargs_desc* desc) {
_sargs.buf = (char*) SOKOL_CALLOC(_sargs.buf_size, sizeof(char));
/* the first character in buf is reserved and always zero, this is the 'empty string' */
_sargs.buf_pos = 1;
- _sargs_parse_cargs(desc->argc, desc->argv);
+ #if defined(__EMSCRIPTEN__)
+ /* on emscripten, ignore argc/argv, and parse the page URL instead */
+ sargs_js_parse_url();
+ #else
+ /* on native platform, parse argc/argv */
+ _sargs_parse_cargs(desc->argc, (const char**) desc->argv);
+ #endif
_sargs.valid = true;
}
@@ -526,4 +598,16 @@ const char* sargs_value_def(const char* key, const char* def) {
}
}
+bool sargs_equals(const char* key, const char* val) {
+ SOKOL_ASSERT(_sargs.valid && key && val);
+ return 0 == strcmp(sargs_value(key), val);
+}
+
+bool sargs_boolean(const char* key) {
+ const char* val = sargs_value(key);
+ return (0 == strcmp("true", val)) ||
+ (0 == strcmp("yes", val)) ||
+ (0 == strcmp("on", val));
+}
+
#endif /* SOKOL_IMPL */