Przeglądaj źródła

sokol-args: escape sequences

Andre Weissflog 7 lat temu
rodzic
commit
e98796b773
1 zmienionych plików z 43 dodań i 12 usunięć
  1. 43 12
      sokol_args.h

+ 43 - 12
sokol_args.h

@@ -36,13 +36,7 @@
 
 
         The value string can contain the following escape sequences:
         The value string can contain the following escape sequences:
             \\  - escape '\'
             \\  - escape '\'
-            \=  - escape '='
-            \:  - escape ':'
-            \"  - escape '"'
-            \'  - escape '''
             \n, \r, \t  - newline, carriage return and tab
             \n, \r, \t  - newline, carriage return and tab
-            \[space]    - escape a space character
-            \[number]   - a decimal number (must fit in a byte)
 
 
         Any spaces between the end of key and the start of value are
         Any spaces between the end of key and the start of value are
         stripped. 
         stripped. 
@@ -215,6 +209,7 @@ typedef struct {
     bool valid;
     bool valid;
     uint32_t parse_state;
     uint32_t parse_state;
     char quote;         /* current quote char, 0 if not in a quote */
     char quote;         /* current quote char, 0 if not in a quote */
+    bool in_escape;     /* currently in an escape sequence */
 } _sargs_state;
 } _sargs_state;
 static _sargs_state _sargs;
 static _sargs_state _sargs;
 
 
@@ -312,6 +307,32 @@ _SOKOL_PRIVATE void _sargs_end_val(void) {
     _sargs.parse_state = 0;
     _sargs.parse_state = 0;
 }
 }
 
 
+_SOKOL_PRIVATE bool _sargs_is_escape(char c) {
+    return '\\' == c;
+}
+
+_SOKOL_PRIVATE void _sargs_start_escape(void) {
+    _sargs.in_escape = true;
+}
+
+_SOKOL_PRIVATE bool _sargs_in_escape(void) {
+    return _sargs.in_escape;
+}
+
+_SOKOL_PRIVATE char _sargs_escape(char c) {
+    switch (c) {
+        case 'n':   return '\n';
+        case 't':   return '\t';
+        case 'r':   return '\r';
+        case '\\':  return '\\';
+        default:    return c;
+    }
+}
+
+_SOKOL_PRIVATE void _sargs_end_escape(void) {
+    _sargs.in_escape = false;
+}
+
 _SOKOL_PRIVATE bool _sargs_parsing_val(void) {
 _SOKOL_PRIVATE bool _sargs_parsing_val(void) {
     return 0 != (_sargs.parse_state & _SARGS_PARSING_VAL);
     return 0 != (_sargs.parse_state & _SARGS_PARSING_VAL);
 }
 }
@@ -319,9 +340,17 @@ _SOKOL_PRIVATE bool _sargs_parsing_val(void) {
 _SOKOL_PRIVATE bool _sargs_parse_carg(const char* src) {
 _SOKOL_PRIVATE bool _sargs_parse_carg(const char* src) {
     char c;
     char c;
     while (0 != (c = *src++)) {
     while (0 != (c = *src++)) {
+        if (_sargs_in_escape()) {
+            c = _sargs_escape(c);
+            _sargs_end_escape();
+        }
+        else if (_sargs_is_escape(c)) {
+            _sargs_start_escape();
+            continue;
+        }
         if (_sargs_any_expected()) {
         if (_sargs_any_expected()) {
-            /* find start of key or value */
             if (!_sargs_is_whitespace(c)) {
             if (!_sargs_is_whitespace(c)) {
+                /* start of key, value or separator */
                 if (_sargs_key_expected()) {
                 if (_sargs_key_expected()) {
                     /* start of new key */
                     /* start of new key */
                     _sargs_start_key();
                     _sargs_start_key();
@@ -349,6 +378,7 @@ _SOKOL_PRIVATE bool _sargs_parse_carg(const char* src) {
         }
         }
         else if (_sargs_parsing_key()) {
         else if (_sargs_parsing_key()) {
             if (_sargs_is_whitespace(c) || _sargs_is_separator(c)) {
             if (_sargs_is_whitespace(c) || _sargs_is_separator(c)) {
+                /* end of key string */
                 _sargs_end_key();
                 _sargs_end_key();
                 if (_sargs_is_separator(c)) {
                 if (_sargs_is_separator(c)) {
                     _sargs_expect_val();
                     _sargs_expect_val();
@@ -361,6 +391,9 @@ _SOKOL_PRIVATE bool _sargs_parse_carg(const char* src) {
         }
         }
         else if (_sargs_parsing_val()) {
         else if (_sargs_parsing_val()) {
             if (_sargs_in_quotes()) {
             if (_sargs_in_quotes()) {
+                /* when in quotes, whitespace is a normal character 
+                   and a matching quote ends the value string
+                */
                 if (_sargs_is_quote(c)) {
                 if (_sargs_is_quote(c)) {
                     _sargs_end_quote();
                     _sargs_end_quote();
                     _sargs_end_val();
                     _sargs_end_val();
@@ -369,20 +402,19 @@ _SOKOL_PRIVATE bool _sargs_parse_carg(const char* src) {
                 }
                 }
             }
             }
             else if (_sargs_is_whitespace(c)) {
             else if (_sargs_is_whitespace(c)) {
+                /* end of value string (no quotes) */
                 _sargs_end_val();
                 _sargs_end_val();
                 _sargs_expect_key();
                 _sargs_expect_key();
                 continue;
                 continue;
             }
             }
         }
         }
-        if (c >= 32) {
-            _sargs_putc(c);
-        }
+        _sargs_putc(c);
     }
     }
     if (_sargs_parsing_key()) {
     if (_sargs_parsing_key()) {
         _sargs_end_key();
         _sargs_end_key();
         _sargs_expect_sep();
         _sargs_expect_sep();
     }
     }
-    else if (_sargs_parsing_val()) {
+    else if (_sargs_parsing_val() && !_sargs_in_quotes()) {
         _sargs_end_val();
         _sargs_end_val();
         _sargs_expect_key();
         _sargs_expect_key();
     }
     }
@@ -416,7 +448,6 @@ void sargs_setup(const sargs_desc* desc) {
     /* the first character in buf is reserved and always zero, this is the 'empty string' */
     /* the first character in buf is reserved and always zero, this is the 'empty string' */
     _sargs.buf_pos = 1;
     _sargs.buf_pos = 1;
     _sargs_parse_cargs(desc->argc, desc->argv);
     _sargs_parse_cargs(desc->argc, desc->argv);
-    /* FIXME: parse args */
     _sargs.valid = true;
     _sargs.valid = true;
 }
 }