diff options
| author | Andre Weissflog <floooh@gmail.com> | 2018-10-17 19:36:58 +0200 |
|---|---|---|
| committer | Andre Weissflog <floooh@gmail.com> | 2018-10-17 19:36:58 +0200 |
| commit | a85bf31b5573286ec8a9b1d192607f85cd019f30 (patch) | |
| tree | beffb00b36a6aad29f794b6223df3df105e2b29a | |
| parent | e98796b7731ddfd5d921b0f89126ed8d1d6a05b1 (diff) | |
sokol_args.h: emscripten support
| -rw-r--r-- | sokol_args.h | 96 |
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 */ |