Make I/O functions exception aware.
Simplify their logic Fix other bugs.
This commit is contained in:
1 parent
ca25dfb537
commit
d22e75d7a0
9 files changed
+293
-356
No files matched your search
@@ -1018,7 +1018,7 @@
|
||||
if (M_UNLIKELY (c == ']')) { goto exit; } \
|
||||
if (M_UNLIKELY (c == 0)) { goto exit; } \
|
||||
str--; \
|
||||
M_QLET(item, type, oplist) { \
|
||||
M_QLET(1, item, type, oplist) { \
|
||||
do { \
|
||||
bool b = M_CALL_PARSE_STR(oplist, item, str, &str); \
|
||||
c = m_core_str_nospace(&str); \
|
||||
@@ -1046,7 +1046,7 @@
|
||||
if (M_UNLIKELY (c == ']')) return true; \
|
||||
if (M_UNLIKELY (c == EOF)) return false; \
|
||||
ungetc(c, file); \
|
||||
M_QLET(item, type, oplist) { \
|
||||
M_QLET(1, item, type, oplist) { \
|
||||
do { \
|
||||
bool b = M_CALL_IN_STR(oplist, item, file); \
|
||||
c = m_core_fgetc_nospace(file); \
|
||||
@@ -1095,7 +1095,7 @@
|
||||
return ret; \
|
||||
} \
|
||||
M_F(name, _reserve)(array, estimated_size); \
|
||||
M_QLET(item, type, oplist) { \
|
||||
M_QLET(1, item, type, oplist) { \
|
||||
do { \
|
||||
ret = M_CALL_IN_SERIAL(oplist, item, f); \
|
||||
if (ret != M_SERIAL_OK_DONE) { break; } \
|
||||
|
||||
+51
-66
@@ -1320,38 +1320,31 @@
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, t1); \
|
||||
M_ASSERT (str != NULL); \
|
||||
M_F(name,_reset)(t1); \
|
||||
bool success = false; \
|
||||
int c = *str++; \
|
||||
if (M_UNLIKELY (c != '[')) goto exit; \
|
||||
if (M_UNLIKELY (c != '[')) { c = 0; goto exit; } \
|
||||
c = *str++; \
|
||||
if (M_UNLIKELY (c == ']')) { success = true; goto exit;} \
|
||||
if (M_UNLIKELY (c == 0)) goto exit; \
|
||||
if (M_UNLIKELY (c == ']' || c == 0)) goto exit; \
|
||||
str--; \
|
||||
key_t key; \
|
||||
M_CALL_INIT(key_oplist, key); \
|
||||
M_IF(isMap)(value_t value; \
|
||||
M_CALL_INIT(value_oplist, value); \
|
||||
, /* No isMap */) \
|
||||
do { \
|
||||
bool b = M_CALL_PARSE_STR(key_oplist, key, str, &str); \
|
||||
do { c = *str++; } while (isspace(c)); \
|
||||
if (b == false) goto exit_clear; \
|
||||
M_IF(isMap)(if (c != ':') goto exit_clear; \
|
||||
b = M_CALL_PARSE_STR(value_oplist, value, str, &str); \
|
||||
do { c = *str++; } while (isspace(c)); \
|
||||
if (b == false || c == 0) goto exit_clear; \
|
||||
M_F(name, _set_at)(t1, key, value); \
|
||||
, \
|
||||
M_F(name, _push)(t1, key); \
|
||||
) \
|
||||
} while (c == M_GET_SEPARATOR key_oplist); \
|
||||
success = (c == ']'); \
|
||||
exit_clear: \
|
||||
M_CALL_CLEAR(key_oplist, key); \
|
||||
M_IF(isMap)(M_CALL_CLEAR(value_oplist, value); , /* No isMap */ ) \
|
||||
M_QLET(1, key, key_t, key_oplist) \
|
||||
M_IF(isMap)(M_QLET(2, value, value_t, value_oplist), /* No isMap */) { \
|
||||
do { \
|
||||
bool b = M_CALL_PARSE_STR(key_oplist, key, str, &str); \
|
||||
c = m_core_str_nospace(&str); \
|
||||
if (b == false) { c = 0; break; } \
|
||||
M_IF(isMap)(if (c != ':') { c = 0; break; } \
|
||||
b = M_CALL_PARSE_STR(value_oplist, value, str, &str); \
|
||||
c = m_core_str_nospace(&str); \
|
||||
if (b == false || c == 0) { c = 0; break; } \
|
||||
M_F(name, _set_at)(t1, key, value); \
|
||||
, \
|
||||
M_F(name, _push)(t1, key); \
|
||||
) \
|
||||
} while (c == M_GET_SEPARATOR key_oplist); \
|
||||
} \
|
||||
exit: \
|
||||
if (endp) *endp = str; \
|
||||
return success; \
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, t1); \
|
||||
return (c == ']'); \
|
||||
} \
|
||||
, /* no parse_str */ ) \
|
||||
\
|
||||
@@ -1368,27 +1361,23 @@
|
||||
if (M_UNLIKELY (c == ']')) return true; \
|
||||
if (M_UNLIKELY (c == EOF)) return false; \
|
||||
ungetc(c, file); \
|
||||
key_t key; \
|
||||
M_CALL_INIT (key_oplist, key); \
|
||||
M_IF(isMap)(value_t value; \
|
||||
M_CALL_INIT (value_oplist, value); \
|
||||
,) \
|
||||
do { \
|
||||
bool b = M_CALL_IN_STR(key_oplist, key, file); \
|
||||
do { c = fgetc(file); } while (isspace(c)); \
|
||||
if (b == false) break; \
|
||||
M_IF(isMap)(if (c!=':') break; \
|
||||
b = M_CALL_IN_STR(value_oplist,value, file); \
|
||||
do { c = fgetc(file); } while (isspace(c)); \
|
||||
if (b == false || c == EOF) break; \
|
||||
M_F(name, _set_at)(t1, key, value) \
|
||||
, \
|
||||
M_F(name, _push)(t1, key) \
|
||||
); \
|
||||
} while (c == M_GET_SEPARATOR key_oplist); \
|
||||
M_CALL_CLEAR(key_oplist, key); \
|
||||
M_IF(isMap)(M_CALL_CLEAR(value_oplist, value); \
|
||||
,) \
|
||||
M_QLET(1, key, key_t, key_oplist) \
|
||||
M_IF(isMap)(M_QLET(2, value, value_t, value_oplist) , /*nothing*/) { \
|
||||
do { \
|
||||
bool b = M_CALL_IN_STR(key_oplist, key, file); \
|
||||
c = m_core_fgetc_nospace(file); \
|
||||
if (b == false) { c = 0; break; } \
|
||||
M_IF(isMap)(if (c!=':') { c = 0; break; } \
|
||||
b = M_CALL_IN_STR(value_oplist,value, file); \
|
||||
c = m_core_fgetc_nospace(file); \
|
||||
if (b == false || c == EOF) { c = 0; break; } \
|
||||
M_F(name, _set_at)(t1, key, value) \
|
||||
, \
|
||||
M_F(name, _push)(t1, key) \
|
||||
); \
|
||||
} while (c == M_GET_SEPARATOR key_oplist); \
|
||||
} \
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, t1); \
|
||||
return c == ']'; \
|
||||
} \
|
||||
, /* no in_str */ ) \
|
||||
@@ -1446,37 +1435,33 @@
|
||||
m_serial_local_t local; \
|
||||
m_serial_return_code_t ret; \
|
||||
size_t estimated_size = 0; \
|
||||
key_t key; \
|
||||
M_F(name,_reset)(t1); \
|
||||
M_IF(isMap)( \
|
||||
value_t value; \
|
||||
M_QLET(1, key, key_t, key_oplist) \
|
||||
M_IF(isMap)(M_QLET(2, value, value_t, value_oplist) , /*nothing*/) { \
|
||||
M_IF(isMap)( \
|
||||
ret = f->m_interface->read_map_start(local, f, &estimated_size); \
|
||||
if (M_UNLIKELY (ret != M_SERIAL_OK_CONTINUE)) return ret; \
|
||||
M_CALL_INIT(key_oplist, key); \
|
||||
M_CALL_INIT (value_oplist, value); \
|
||||
if (M_UNLIKELY (ret != M_SERIAL_OK_CONTINUE)) break; \
|
||||
do { \
|
||||
ret = M_CALL_IN_SERIAL(key_oplist, key, f); \
|
||||
if (ret != M_SERIAL_OK_DONE) return M_SERIAL_FAIL; \
|
||||
if (ret != M_SERIAL_OK_DONE) break; \
|
||||
ret = f->m_interface->read_map_value(local, f); \
|
||||
if (ret != M_SERIAL_OK_CONTINUE) return M_SERIAL_FAIL; \
|
||||
if (ret != M_SERIAL_OK_CONTINUE) break; \
|
||||
ret = M_CALL_IN_SERIAL(value_oplist, value, f); \
|
||||
if (ret != M_SERIAL_OK_DONE) return M_SERIAL_FAIL; \
|
||||
if (ret != M_SERIAL_OK_DONE) break; \
|
||||
M_F(name, _set_at)(t1, key, value); \
|
||||
} while ((ret = f->m_interface->read_map_next(local, f)) == M_SERIAL_OK_CONTINUE); \
|
||||
M_CALL_CLEAR(key_oplist, key); \
|
||||
M_CALL_CLEAR(value_oplist, value); \
|
||||
, \
|
||||
, /* queue style */ \
|
||||
ret = f->m_interface->read_array_start(local, f, &estimated_size); \
|
||||
if (M_UNLIKELY (ret != M_SERIAL_OK_CONTINUE)) return ret; \
|
||||
M_CALL_INIT(key_oplist, key); \
|
||||
if (M_UNLIKELY (ret != M_SERIAL_OK_CONTINUE)) break; \
|
||||
do { \
|
||||
ret = M_CALL_IN_SERIAL(key_oplist, key, f); \
|
||||
if (ret != M_SERIAL_OK_DONE) { break; } \
|
||||
if (ret != M_SERIAL_OK_DONE) break; \
|
||||
M_F(name, _push)(t1, key); \
|
||||
} while ((ret = f->m_interface->read_array_next(local, f)) == M_SERIAL_OK_CONTINUE); \
|
||||
M_CALL_CLEAR(key_oplist, key); \
|
||||
) /* End of IF isMap */ \
|
||||
return ret; \
|
||||
) /* End of IF isMap */ \
|
||||
} \
|
||||
M_BPTR33_CONTRACT(N, isMulti, key_oplist, t1); \
|
||||
return ret; \
|
||||
} \
|
||||
, /* no in_serial */ ) \
|
||||
|
||||
|
||||
@@ -4401,10 +4401,15 @@ m_core_parse2_enum (const char str[], const char **endptr)
|
||||
#define M_LET_TRY_INJECT_POST(cont, oplist, name)
|
||||
|
||||
/*
|
||||
Internal M_LET for use within container.
|
||||
* Internal M_LET for use within container.
|
||||
* Declare the given variable of the given type and
|
||||
* initialize / clear it using the given oplist .
|
||||
*
|
||||
* index shall be a number within the function (from 1)
|
||||
* identifying the M_QLET in the service.
|
||||
*/
|
||||
#define M_QLET(x, type, oplist) \
|
||||
M_LET(x, M_OPEXTEND(oplist, TYPE(type)))
|
||||
#define M_QLET(index, var, type, oplist) \
|
||||
M_LET(var, M_OPEXTEND(oplist, TYPE(type)))
|
||||
|
||||
/* Transform the va list by adding their number as the first argument of
|
||||
the list.
|
||||
|
||||
@@ -951,28 +951,23 @@
|
||||
M_D3QU3_CONTRACT(deque); \
|
||||
M_ASSERT (str != NULL); \
|
||||
M_F(name,_reset)(deque); \
|
||||
bool success = false; \
|
||||
int c = *str++; \
|
||||
if (M_UNLIKELY (c != '[')) goto exit; \
|
||||
if (M_UNLIKELY (c != '[')) { c = 0; goto exit; } \
|
||||
c = *str++; \
|
||||
if (M_UNLIKELY (c == ']')) {success = true; goto exit;} \
|
||||
if (M_UNLIKELY (c == 0)) goto exit; \
|
||||
if (M_UNLIKELY (c == ']' || c == 0)) goto exit; \
|
||||
str--; \
|
||||
type item; \
|
||||
M_CALL_INIT(oplist, item); \
|
||||
do { \
|
||||
bool b = M_CALL_PARSE_STR(oplist, item, str, &str); \
|
||||
do { c = *str++; } while (isspace(c)); \
|
||||
if (b == false || c == 0) { goto exit_clear; } \
|
||||
M_F(name, _push_back)(deque, item); \
|
||||
} while (c == M_GET_SEPARATOR oplist); \
|
||||
M_D3QU3_CONTRACT(deque); \
|
||||
success = (c == ']'); \
|
||||
exit_clear: \
|
||||
M_CALL_CLEAR(oplist, item); \
|
||||
M_QLET(1, item, type, oplist) { \
|
||||
do { \
|
||||
bool b = M_CALL_PARSE_STR(oplist, item, str, &str); \
|
||||
c = m_core_str_nospace(&str); \
|
||||
if (b == false || c == 0) { c = 0; break; } \
|
||||
M_F(name, _push_back)(deque, item); \
|
||||
} while (c == M_GET_SEPARATOR oplist); \
|
||||
} \
|
||||
exit: \
|
||||
if (endp) *endp = str; \
|
||||
return success; \
|
||||
M_D3QU3_CONTRACT(deque); \
|
||||
return c == ']'; \
|
||||
} \
|
||||
, /* no PARSE_STR */ ) \
|
||||
\
|
||||
@@ -989,15 +984,14 @@
|
||||
if (M_UNLIKELY (c == ']')) return true; \
|
||||
if (M_UNLIKELY (c == EOF)) return false; \
|
||||
ungetc(c, file); \
|
||||
type item; \
|
||||
M_CALL_INIT(oplist, item); \
|
||||
do { \
|
||||
bool b = M_CALL_IN_STR(oplist, item, file); \
|
||||
do { c = fgetc(file); } while (isspace(c)); \
|
||||
if (b == false || c == EOF) { break; } \
|
||||
M_F(name, _push_back)(deque, item); \
|
||||
} while (c == M_GET_SEPARATOR oplist); \
|
||||
M_CALL_CLEAR(oplist, item); \
|
||||
M_QLET(1, item, type, oplist) { \
|
||||
do { \
|
||||
bool b = M_CALL_IN_STR(oplist, item, file); \
|
||||
c = m_core_fgetc_nospace(file); \
|
||||
if (b == false || c == EOF) { c = 0; break; } \
|
||||
M_F(name, _push_back)(deque, item); \
|
||||
} while (c == M_GET_SEPARATOR oplist); \
|
||||
} \
|
||||
M_D3QU3_CONTRACT(deque); \
|
||||
return c == ']'; \
|
||||
} \
|
||||
@@ -1040,15 +1034,14 @@
|
||||
M_F(name,_reset)(deque); \
|
||||
ret = f->m_interface->read_array_start(local, f, &estimated_size); \
|
||||
if (M_UNLIKELY (ret != M_SERIAL_OK_CONTINUE)) return ret; \
|
||||
type item; \
|
||||
M_CALL_INIT(oplist, item); \
|
||||
do { \
|
||||
ret = M_CALL_IN_SERIAL(oplist, item, f); \
|
||||
if (ret != M_SERIAL_OK_DONE) { break; } \
|
||||
M_F(name, _push_back)(deque, item); \
|
||||
ret = f->m_interface->read_array_next(local, f); \
|
||||
} while (ret == M_SERIAL_OK_CONTINUE); \
|
||||
M_CALL_CLEAR(oplist, item); \
|
||||
M_QLET(1, item, type, oplist) { \
|
||||
do { \
|
||||
ret = M_CALL_IN_SERIAL(oplist, item, f); \
|
||||
if (ret != M_SERIAL_OK_DONE) { break; } \
|
||||
M_F(name, _push_back)(deque, item); \
|
||||
ret = f->m_interface->read_array_next(local, f); \
|
||||
} while (ret == M_SERIAL_OK_CONTINUE); \
|
||||
} \
|
||||
return ret; \
|
||||
} \
|
||||
, /* no IN_SERIAL & INIT */ ) \
|
||||
|
||||
@@ -836,42 +836,35 @@
|
||||
{ \
|
||||
M_ASSERT (str != NULL); \
|
||||
M_F(name, _reset)(dict); \
|
||||
bool success = false; \
|
||||
int c = m_core_str_nospace(&str); \
|
||||
if (M_UNLIKELY (c != '{')) { goto exit; } \
|
||||
if (M_UNLIKELY (c != '{')) { c = 0; goto exit; } \
|
||||
c = m_core_str_nospace(&str); \
|
||||
if (M_UNLIKELY (c == '}')) { success = true; goto exit;} \
|
||||
if (M_UNLIKELY (c == 0)) { goto exit; } \
|
||||
if (M_UNLIKELY (c == '}' || c == 0)) goto exit; \
|
||||
str--; \
|
||||
key_type key; \
|
||||
M_IF(isSet)( ,value_type value); \
|
||||
M_CALL_INIT(key_oplist, key); \
|
||||
M_IF(isSet)( , M_CALL_INIT(value_oplist, value) ); \
|
||||
do { \
|
||||
c = m_core_str_nospace(&str); \
|
||||
str--; \
|
||||
bool b = M_CALL_PARSE_STR(key_oplist, key, str, &str); \
|
||||
M_IF(isSet)( \
|
||||
if (b == false) { goto exit_clear; } \
|
||||
M_F(name, _push)(dict, key); \
|
||||
, \
|
||||
c = m_core_str_nospace(&str); \
|
||||
if (b == false || c != ':') { goto exit_clear; } \
|
||||
c = m_core_str_nospace(&str); \
|
||||
str--; \
|
||||
b = M_CALL_PARSE_STR(value_oplist, value, str, &str); \
|
||||
if (b == false) { goto exit_clear; } \
|
||||
M_F(name, _set_at)(dict, key, value); \
|
||||
) \
|
||||
c = m_core_str_nospace(&str); \
|
||||
} while (c == ','); \
|
||||
success = (c == '}'); \
|
||||
exit_clear: \
|
||||
M_CALL_CLEAR(key_oplist, key); \
|
||||
M_CALL_CLEAR(value_oplist, value); \
|
||||
M_QLET(1, key, key_type, key_oplist) \
|
||||
M_IF(isSet)(,M_QLET(2, value, value_type, value_oplist)) { \
|
||||
do { \
|
||||
c = m_core_str_nospace(&str); \
|
||||
str--; \
|
||||
bool b = M_CALL_PARSE_STR(key_oplist, key, str, &str); \
|
||||
M_IF(isSet)( \
|
||||
if (b == false) { c = 0; break; } \
|
||||
M_F(name, _push)(dict, key); \
|
||||
, /* is a map */ \
|
||||
c = m_core_str_nospace(&str); \
|
||||
if (b == false || c != ':') { c = 0; break; } \
|
||||
c = m_core_str_nospace(&str); \
|
||||
str--; \
|
||||
b = M_CALL_PARSE_STR(value_oplist, value, str, &str); \
|
||||
if (b == false) { c = 0; break; } \
|
||||
M_F(name, _set_at)(dict, key, value); \
|
||||
) \
|
||||
c = m_core_str_nospace(&str); \
|
||||
} while (c == ','); \
|
||||
} \
|
||||
exit: \
|
||||
if (endp) *endp = str; \
|
||||
return success; \
|
||||
return c == '}'; \
|
||||
} \
|
||||
, /* no PARSE_STR */ ) \
|
||||
\
|
||||
@@ -887,32 +880,29 @@
|
||||
if (M_UNLIKELY(c == '}')) return true; \
|
||||
if (M_UNLIKELY (c == EOF)) return false; \
|
||||
ungetc(c, file); \
|
||||
key_type key; \
|
||||
M_IF(isSet)( ,value_type value); \
|
||||
M_CALL_INIT(key_oplist, key); \
|
||||
M_IF(isSet)( , M_CALL_INIT(value_oplist, value) ); \
|
||||
do { \
|
||||
M_QLET(1, key, key_type, key_oplist) \
|
||||
M_IF(isSet)(,M_QLET(2, value, value_type, value_oplist)) { \
|
||||
do { \
|
||||
c = m_core_fgetc_nospace(file); \
|
||||
if (M_UNLIKELY (c == EOF)) { break; } \
|
||||
ungetc(c, file); \
|
||||
bool b = M_CALL_IN_STR(key_oplist, key, file); \
|
||||
M_IF(isSet)( \
|
||||
if (M_UNLIKELY (b == false)) { c = 0; break; } \
|
||||
M_F(name, _push)(dict, key); \
|
||||
, /* is map */ \
|
||||
c = m_core_fgetc_nospace(file); \
|
||||
if (M_UNLIKELY (b == false || c != ':')) { c = 0; break; } \
|
||||
c = m_core_fgetc_nospace(file); \
|
||||
if (M_UNLIKELY (c == EOF)) { break; } \
|
||||
ungetc(c, file); \
|
||||
b = M_CALL_IN_STR(value_oplist, value, file); \
|
||||
if (M_UNLIKELY (b == false)) { c = 0; break; } \
|
||||
M_F(name, _set_at)(dict, key, value); \
|
||||
) \
|
||||
c = m_core_fgetc_nospace(file); \
|
||||
if (M_UNLIKELY (c == EOF)) { break; } \
|
||||
ungetc(c, file); \
|
||||
bool b = M_CALL_IN_STR(key_oplist, key, file); \
|
||||
M_IF(isSet)( \
|
||||
if (M_UNLIKELY (b == false)) { break; } \
|
||||
M_F(name, _push)(dict, key); \
|
||||
, \
|
||||
c = m_core_fgetc_nospace(file); \
|
||||
if (M_UNLIKELY (b == false || c != ':')) { c = 0; break; } \
|
||||
c = m_core_fgetc_nospace(file); \
|
||||
if (M_UNLIKELY (c == EOF)) { break; } \
|
||||
ungetc(c, file); \
|
||||
b = M_CALL_IN_STR(value_oplist, value, file); \
|
||||
if (M_UNLIKELY (b == false)) { c = 0; break; } \
|
||||
M_F(name, _set_at)(dict, key, value); \
|
||||
) \
|
||||
c = m_core_fgetc_nospace(file); \
|
||||
} while (c == ','); \
|
||||
M_CALL_CLEAR(key_oplist, key); \
|
||||
M_IF(isSet)(, M_CALL_CLEAR(value_oplist, value); ) \
|
||||
} while (c == ','); \
|
||||
} \
|
||||
return c == '}'; \
|
||||
} \
|
||||
, /* no IN_STR */ ) \
|
||||
@@ -968,37 +958,32 @@
|
||||
m_serial_local_t local; \
|
||||
m_serial_return_code_t ret; \
|
||||
size_t estimated_size = 0; \
|
||||
key_type key; \
|
||||
M_F(name,_reset)(t1); \
|
||||
M_IF(isSet)( \
|
||||
ret = f->m_interface->read_array_start(local, f, &estimated_size); \
|
||||
if (M_UNLIKELY (ret != M_SERIAL_OK_CONTINUE)) return ret; \
|
||||
M_CALL_INIT(key_oplist, key); \
|
||||
do { \
|
||||
ret = M_CALL_IN_SERIAL(key_oplist, key, f); \
|
||||
if (ret != M_SERIAL_OK_DONE) { break; } \
|
||||
M_F(name, _push)(t1, key); \
|
||||
} while ((ret = f->m_interface->read_array_next(local, f)) == M_SERIAL_OK_CONTINUE); \
|
||||
M_CALL_CLEAR(key_oplist, key); \
|
||||
, \
|
||||
value_type value; \
|
||||
ret = f->m_interface->read_map_start(local, f, &estimated_size); \
|
||||
if (M_UNLIKELY (ret != M_SERIAL_OK_CONTINUE)) return ret; \
|
||||
M_CALL_INIT(key_oplist, key); \
|
||||
M_CALL_INIT (value_oplist, value); \
|
||||
do { \
|
||||
ret = M_CALL_IN_SERIAL(key_oplist, key, f); \
|
||||
if (ret != M_SERIAL_OK_DONE) return M_SERIAL_FAIL; \
|
||||
ret = f->m_interface->read_map_value(local, f); \
|
||||
if (ret != M_SERIAL_OK_CONTINUE) return M_SERIAL_FAIL; \
|
||||
ret = M_CALL_IN_SERIAL(value_oplist, value, f); \
|
||||
if (ret != M_SERIAL_OK_DONE) return M_SERIAL_FAIL; \
|
||||
M_F(name, _set_at)(t1, key, value); \
|
||||
} while ((ret = f->m_interface->read_map_next(local, f)) == M_SERIAL_OK_CONTINUE); \
|
||||
M_CALL_CLEAR(key_oplist, key); \
|
||||
M_CALL_CLEAR(value_oplist, value); \
|
||||
) /* End of IF isSet */ \
|
||||
return ret; \
|
||||
M_QLET(1, key, key_type, key_oplist) \
|
||||
M_IF(isSet)(,M_QLET(2, value, value_type, value_oplist)) { \
|
||||
M_IF(isSet)( \
|
||||
ret = f->m_interface->read_array_start(local, f, &estimated_size); \
|
||||
if (M_UNLIKELY (ret != M_SERIAL_OK_CONTINUE)) break; \
|
||||
do { \
|
||||
ret = M_CALL_IN_SERIAL(key_oplist, key, f); \
|
||||
if (ret != M_SERIAL_OK_DONE) break; \
|
||||
M_F(name, _push)(t1, key); \
|
||||
} while ((ret = f->m_interface->read_array_next(local, f)) == M_SERIAL_OK_CONTINUE); \
|
||||
, /* is map */ \
|
||||
ret = f->m_interface->read_map_start(local, f, &estimated_size); \
|
||||
if (M_UNLIKELY (ret != M_SERIAL_OK_CONTINUE)) break; \
|
||||
do { \
|
||||
ret = M_CALL_IN_SERIAL(key_oplist, key, f); \
|
||||
if (ret != M_SERIAL_OK_DONE) break; \
|
||||
ret = f->m_interface->read_map_value(local, f); \
|
||||
if (ret != M_SERIAL_OK_CONTINUE) break; \
|
||||
ret = M_CALL_IN_SERIAL(value_oplist, value, f); \
|
||||
if (ret != M_SERIAL_OK_DONE) break; \
|
||||
M_F(name, _set_at)(t1, key, value); \
|
||||
} while ((ret = f->m_interface->read_map_next(local, f)) == M_SERIAL_OK_CONTINUE); \
|
||||
) /* End of IF isSet */ \
|
||||
} \
|
||||
return ret; \
|
||||
} \
|
||||
, /* no in_serial */ ) \
|
||||
\
|
||||
|
||||
@@ -736,18 +736,16 @@
|
||||
if (M_UNLIKELY (c == ']')) { success = true; goto exit;} \
|
||||
if (M_UNLIKELY (c == 0)) goto exit; \
|
||||
str--; \
|
||||
type item; \
|
||||
M_CALL_INIT(oplist, item); \
|
||||
do { \
|
||||
bool b = M_CALL_PARSE_STR(oplist, item, str, &str); \
|
||||
do { c = *str++; } while (isspace(c)); \
|
||||
if (b == false || c == 0) { goto exit_clear; } \
|
||||
M_F(name, _push_back)(list, item); \
|
||||
} while (c == M_GET_SEPARATOR oplist); \
|
||||
M_QLET(1, item, type, oplist) { \
|
||||
do { \
|
||||
bool b = M_CALL_PARSE_STR(oplist, item, str, &str); \
|
||||
c = m_core_str_nospace(&str); \
|
||||
if (b == false || c == 0) { c = 0; break; } \
|
||||
M_F(name, _push_back)(list, item); \
|
||||
} while (c == M_GET_SEPARATOR oplist); \
|
||||
success = (c == ']'); \
|
||||
} \
|
||||
M_F(name, _reverse)(list); \
|
||||
success = (c == ']'); \
|
||||
exit_clear: \
|
||||
M_CALL_CLEAR(oplist, item); \
|
||||
exit: \
|
||||
if (endp) *endp = str; \
|
||||
return success; \
|
||||
@@ -766,15 +764,14 @@
|
||||
if (M_UNLIKELY (c == ']')) return true; \
|
||||
if (M_UNLIKELY (c == EOF)) return false; \
|
||||
ungetc(c, file); \
|
||||
type item; \
|
||||
M_CALL_INIT(oplist, item); \
|
||||
do { \
|
||||
bool b = M_CALL_IN_STR(oplist, item, file); \
|
||||
do { c = fgetc(file); } while (isspace(c)); \
|
||||
if (b == false || c == EOF) { break; } \
|
||||
M_F(name, _push_back)(list, item); \
|
||||
} while (c == M_GET_SEPARATOR oplist); \
|
||||
M_CALL_CLEAR(oplist, item); \
|
||||
M_QLET(1, item, type, oplist) { \
|
||||
do { \
|
||||
bool b = M_CALL_IN_STR(oplist, item, file); \
|
||||
c = m_core_fgetc_nospace(file); \
|
||||
if (b == false || c == EOF) { c = 0; break; } \
|
||||
M_F(name, _push_back)(list, item); \
|
||||
} while (c == M_GET_SEPARATOR oplist); \
|
||||
} \
|
||||
M_F(name, _reverse)(list); \
|
||||
return c == ']'; \
|
||||
} \
|
||||
@@ -821,15 +818,14 @@
|
||||
M_F(name,_reset)(list); \
|
||||
ret = f->m_interface->read_array_start(local, f, &estimated_size); \
|
||||
if (M_UNLIKELY (ret != M_SERIAL_OK_CONTINUE)) return ret; \
|
||||
type item; \
|
||||
M_CALL_INIT(oplist, item); \
|
||||
do { \
|
||||
ret = M_CALL_IN_SERIAL(oplist, item, f); \
|
||||
if (ret != M_SERIAL_OK_DONE) { break; } \
|
||||
M_F(name, _push_back)(list, item); \
|
||||
ret = f->m_interface->read_array_next(local, f); \
|
||||
} while (ret == M_SERIAL_OK_CONTINUE); \
|
||||
M_CALL_CLEAR(oplist, item); \
|
||||
M_QLET(1, item, type, oplist) { \
|
||||
do { \
|
||||
ret = M_CALL_IN_SERIAL(oplist, item, f); \
|
||||
if (ret != M_SERIAL_OK_DONE) { break; } \
|
||||
M_F(name, _push_back)(list, item); \
|
||||
ret = f->m_interface->read_array_next(local, f); \
|
||||
} while (ret == M_SERIAL_OK_CONTINUE); \
|
||||
} \
|
||||
M_F(name, _reverse)(list); \
|
||||
return ret; \
|
||||
} \
|
||||
|
||||
+29
-35
@@ -1072,27 +1072,22 @@ typedef enum {
|
||||
M_RBTR33_CONTRACT(rbtree); \
|
||||
M_ASSERT (str != NULL); \
|
||||
M_F(name,_reset)(rbtree); \
|
||||
bool success = false; \
|
||||
int c = *str++; \
|
||||
if (M_UNLIKELY (c != '[')) goto exit; \
|
||||
c = *str++; \
|
||||
if (M_UNLIKELY (c == ']')) { success = true; goto exit; } \
|
||||
if (M_UNLIKELY (c == 0)) goto exit; \
|
||||
int c = m_core_str_nospace(&str); \
|
||||
if (M_UNLIKELY (c != '[')) { c = 0; goto exit; } \
|
||||
c = m_core_str_nospace(&str); \
|
||||
if (M_UNLIKELY (c == ']' || c == 0)) goto exit; \
|
||||
str--; \
|
||||
type item; \
|
||||
M_CALL_INIT(oplist, item); \
|
||||
do { \
|
||||
bool b = M_CALL_PARSE_STR(oplist, item, str, &str); \
|
||||
do { c = *str++; } while (isspace(c)); \
|
||||
if (b == false || c == 0) goto exit_clear; \
|
||||
M_F(name, _push)(rbtree, item); \
|
||||
} while (c == M_GET_SEPARATOR oplist); \
|
||||
success = (c == ']'); \
|
||||
exit_clear: \
|
||||
M_CALL_CLEAR(oplist, item); \
|
||||
M_QLET(1, item, type, oplist) { \
|
||||
do { \
|
||||
bool b = M_CALL_PARSE_STR(oplist, item, str, &str); \
|
||||
c = m_core_str_nospace(&str); \
|
||||
if (b == false || c == 0) { c= 0 ; break; }; \
|
||||
M_F(name, _push)(rbtree, item); \
|
||||
} while (c == M_GET_SEPARATOR oplist); \
|
||||
} \
|
||||
exit: \
|
||||
if (endp) *endp = str; \
|
||||
return success; \
|
||||
return c == ']'; \
|
||||
} \
|
||||
, /* no parse_str */ ) \
|
||||
\
|
||||
@@ -1109,15 +1104,14 @@ typedef enum {
|
||||
if (M_UNLIKELY (c == ']')) return true; \
|
||||
if (M_UNLIKELY (c == EOF)) return false; \
|
||||
ungetc(c, file); \
|
||||
type item; \
|
||||
M_CALL_INIT(oplist, item); \
|
||||
do { \
|
||||
bool b = M_CALL_IN_STR(oplist, item, file); \
|
||||
do { c = fgetc(file); } while (isspace(c)); \
|
||||
if (b == false || c == EOF) break; \
|
||||
M_F(name, _push)(rbtree, item); \
|
||||
} while (c == M_GET_SEPARATOR oplist); \
|
||||
M_CALL_CLEAR(oplist, item); \
|
||||
M_QLET(1, item, type, oplist) { \
|
||||
do { \
|
||||
bool b = M_CALL_IN_STR(oplist, item, file); \
|
||||
c = m_core_fgetc_nospace(file); \
|
||||
if (b == false || c == EOF) { c = 0; break; } \
|
||||
M_F(name, _push)(rbtree, item); \
|
||||
} while (c == M_GET_SEPARATOR oplist); \
|
||||
} \
|
||||
return c == ']'; \
|
||||
} \
|
||||
, /* no in_str */ ) \
|
||||
@@ -1157,17 +1151,17 @@ typedef enum {
|
||||
m_serial_local_t local; \
|
||||
m_serial_return_code_t ret; \
|
||||
size_t estimated_size = 0; \
|
||||
type key; \
|
||||
M_F(name,_reset)(t1); \
|
||||
ret = f->m_interface->read_array_start(local, f, &estimated_size); \
|
||||
if (M_UNLIKELY (ret != M_SERIAL_OK_CONTINUE)) return ret; \
|
||||
M_CALL_INIT(oplist, key); \
|
||||
do { \
|
||||
ret = M_CALL_IN_SERIAL(oplist, key, f); \
|
||||
if (ret != M_SERIAL_OK_DONE) { break; } \
|
||||
M_F(name, _push)(t1, key); \
|
||||
} while ((ret = f->m_interface->read_array_next(local, f)) == M_SERIAL_OK_CONTINUE); \
|
||||
M_CALL_CLEAR(oplist, key); \
|
||||
M_QLET(1, key, type, oplist) { \
|
||||
do { \
|
||||
ret = M_CALL_IN_SERIAL(oplist, key, f); \
|
||||
if (ret != M_SERIAL_OK_DONE) { break; } \
|
||||
M_F(name, _push)(t1, key); \
|
||||
ret = f->m_interface->read_array_next(local, f); \
|
||||
} while (ret == M_SERIAL_OK_CONTINUE); \
|
||||
} \
|
||||
return ret; \
|
||||
} \
|
||||
, /* no in_serial */ ) \
|
||||
|
||||
+4
-17
@@ -287,25 +287,13 @@ typedef m_serial_write_t m_serial_json_write_t;
|
||||
/*************************** FILE / READ / JSON ********************************/
|
||||
/********************************************************************************/
|
||||
|
||||
/* Helper function to skip a space */
|
||||
M_INLINE int
|
||||
m_ser1al_json_read_skip (FILE *f)
|
||||
{
|
||||
int c;
|
||||
do {
|
||||
// c is an int, and is the value of the character read as unsigned char
|
||||
c = fgetc(f);
|
||||
} while (c != EOF && isspace(c));
|
||||
return c;
|
||||
}
|
||||
|
||||
/* Read from the stream 'serial' a boolean.
|
||||
Set '*b' with the boolean value if succeeds
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
M_INLINE m_serial_return_code_t
|
||||
m_ser1al_json_read_boolean(m_serial_read_t serial, bool *b){
|
||||
FILE *f = (FILE*) serial->data[0].p;
|
||||
int c = m_ser1al_json_read_skip(f);
|
||||
int c = m_core_fgetc_nospace(f);
|
||||
if (c == 't') {
|
||||
*b = true;
|
||||
c = fgetc(f);
|
||||
@@ -473,7 +461,7 @@ m_ser1al_json_read_tuple_id(m_serial_local_t local, m_serial_read_t serial, cons
|
||||
{
|
||||
(void) local; // argument not used
|
||||
FILE *f = (FILE*) serial->data[0].p;
|
||||
int c = m_ser1al_json_read_skip(f);
|
||||
int c = m_core_fgetc_nospace(f);
|
||||
if (c == EOF) return m_core_serial_fail();
|
||||
if (c == '}') return M_SERIAL_OK_DONE;
|
||||
if (c == ',') {
|
||||
@@ -860,9 +848,8 @@ m_ser1al_str_json_getc(const char **p)
|
||||
M_INLINE void
|
||||
m_ser1al_str_json_skip (const char **p)
|
||||
{
|
||||
while (isspace (**p)) {
|
||||
(*p)++;
|
||||
}
|
||||
(void) m_core_str_nospace(p);
|
||||
(*p)--;
|
||||
}
|
||||
|
||||
/* Helper function to read a string with characters not present in reject */
|
||||
|
||||
@@ -1339,7 +1339,6 @@ M_INLINE bool \
|
||||
M_F(name, _parse_str)(tree_t tree, const char str[], const char **endp) { \
|
||||
M_TR33_CONTRACT(tree); \
|
||||
int cmd = 0; \
|
||||
type item; \
|
||||
it_t it; \
|
||||
M_F(name, _reset)(tree); \
|
||||
bool success = false; \
|
||||
@@ -1348,50 +1347,47 @@ M_F(name, _parse_str)(tree_t tree, const char str[], const char **endp) { \
|
||||
c = *++str; \
|
||||
if (M_UNLIKELY (c == ']')) { success = true; str++; goto exit; } \
|
||||
if (M_UNLIKELY (c == 0)) goto exit; \
|
||||
M_CALL_INIT(oplist, item); \
|
||||
it = M_F(name, _it_end)(tree); \
|
||||
while (true) { \
|
||||
c = *str++; \
|
||||
if (c != '{') goto exit_clear; \
|
||||
bool b = M_CALL_PARSE_STR(oplist, item, str, &str); \
|
||||
c = *str++; \
|
||||
if (b == false || c == 0) { goto exit_clear; } \
|
||||
/* Insert the item as the root or as a right sibling or as a child */ \
|
||||
switch (cmd) { \
|
||||
case 0: it = M_F(name, _set_root)(tree, item); break; \
|
||||
case 1: it = M_F(name, _insert_right)(it, item); break; \
|
||||
case 2: it = M_F(name, _insert_child)(it, item); break; \
|
||||
default: M_ASSERT(0); \
|
||||
} \
|
||||
if (c == ',') { \
|
||||
/* The current item has some children */ \
|
||||
M_QLET(1, item, type, oplist) { \
|
||||
it = M_F(name, _it_end)(tree); \
|
||||
while (true) { \
|
||||
c = *str++; \
|
||||
if (c != '[') { goto exit_clear; } \
|
||||
/* next is a child: push_down */ \
|
||||
cmd = 2; \
|
||||
continue; \
|
||||
} \
|
||||
/* The current item has no children. */ \
|
||||
if (c != '}') { goto exit_clear; } \
|
||||
/* Scan the next character to decide where to move (right or up) */ \
|
||||
c = *str++; \
|
||||
if (c == ']') { \
|
||||
do { \
|
||||
/* move up. It we cannot, we have reached the end */ \
|
||||
if (!M_F(name, _it_up)(&it)) { goto exit_success; } \
|
||||
if (c != '{') break; \
|
||||
bool b = M_CALL_PARSE_STR(oplist, item, str, &str); \
|
||||
c = *str++; \
|
||||
if (b == false || c == 0) break; \
|
||||
/* Insert the item as the root or as a right sibling or as a child */ \
|
||||
switch (cmd) { \
|
||||
case 0: it = M_F(name, _set_root)(tree, item); break; \
|
||||
case 1: it = M_F(name, _insert_right)(it, item); break; \
|
||||
case 2: it = M_F(name, _insert_child)(it, item); break; \
|
||||
default: M_ASSERT(0); \
|
||||
} \
|
||||
if (c == ',') { \
|
||||
/* The current item has some children */ \
|
||||
c = *str++; \
|
||||
if (c != '}') { goto exit_clear; } \
|
||||
c = *str++; \
|
||||
} while (c == ']'); \
|
||||
if (c != '[') break; \
|
||||
/* next is a child: push_down */ \
|
||||
cmd = 2; \
|
||||
continue; \
|
||||
} \
|
||||
/* The current item has no children. */ \
|
||||
if (c != '}') break; \
|
||||
/* Scan the next character to decide where to move (right or up) */ \
|
||||
c = *str++; \
|
||||
if (c == ']') { \
|
||||
do { \
|
||||
/* move up. It we cannot, we have reached the end */ \
|
||||
if (!M_F(name, _it_up)(&it)) { success = true; break; } \
|
||||
c = *str++; \
|
||||
if (c != '}') goto do_break; \
|
||||
c = *str++; \
|
||||
} while (c == ']'); \
|
||||
} \
|
||||
if (c != ',') { do_break: break; } \
|
||||
/* next is a sibling: push_right */ \
|
||||
cmd = 1; \
|
||||
} \
|
||||
if (c != ',') { goto exit_clear; } \
|
||||
/* next is a sibling: push_right */ \
|
||||
cmd = 1; \
|
||||
} \
|
||||
exit_success: \
|
||||
success = true; \
|
||||
exit_clear: \
|
||||
M_CALL_CLEAR(oplist, item); \
|
||||
exit: \
|
||||
if (endp) *endp = str; \
|
||||
M_TR33_CONTRACT(tree); \
|
||||
@@ -1440,7 +1436,6 @@ M_INLINE bool \
|
||||
M_F(name, _in_str)(tree_t tree, FILE *f) { \
|
||||
M_TR33_CONTRACT(tree); \
|
||||
int cmd = 0; \
|
||||
type item; \
|
||||
it_t it; \
|
||||
M_F(name, _reset)(tree); \
|
||||
bool success = false; \
|
||||
@@ -1450,50 +1445,47 @@ M_F(name, _in_str)(tree_t tree, FILE *f) { \
|
||||
if (M_UNLIKELY (c == ']')) { success = true; goto exit; } \
|
||||
ungetc(c, f); \
|
||||
if (M_UNLIKELY (c == 0)) goto exit; \
|
||||
M_CALL_INIT(oplist, item); \
|
||||
it = M_F(name, _it_end)(tree); \
|
||||
while (true) { \
|
||||
c = fgetc(f); \
|
||||
if (c != '{') goto exit_clear; \
|
||||
bool b = M_CALL_IN_STR(oplist, item, f); \
|
||||
c = fgetc(f); \
|
||||
if (b == false || c == 0) { goto exit_clear; } \
|
||||
/* Insert the item as the root or as a right sibling or as a child */ \
|
||||
switch (cmd) { \
|
||||
case 0: it = M_F(name, _set_root)(tree, item); break; \
|
||||
case 1: it = M_F(name, _insert_right)(it, item); break; \
|
||||
case 2: it = M_F(name, _insert_child)(it, item); break; \
|
||||
default: M_ASSERT(0); \
|
||||
} \
|
||||
if (c == ',') { \
|
||||
/* The current item has some children */ \
|
||||
M_QLET(1, item, type, oplist) { \
|
||||
it = M_F(name, _it_end)(tree); \
|
||||
while (true) { \
|
||||
c = fgetc(f); \
|
||||
if (c != '[') { goto exit_clear; } \
|
||||
/* next is a child: push_down */ \
|
||||
cmd = 2; \
|
||||
continue; \
|
||||
} \
|
||||
/* The current item has no children. */ \
|
||||
if (c != '}') { goto exit_clear; } \
|
||||
/* Scan the next character to decide where to move (right or up) */ \
|
||||
c = fgetc(f); \
|
||||
if (c == ']') { \
|
||||
do { \
|
||||
/* move up. It we cannot, we have reached the end */ \
|
||||
if (!M_F(name, _it_up)(&it)) { goto exit_success; } \
|
||||
if (c != '{') break; \
|
||||
bool b = M_CALL_IN_STR(oplist, item, f); \
|
||||
c = fgetc(f); \
|
||||
if (b == false || c == 0) break; \
|
||||
/* Insert the item as the root or as a right sibling or as a child */ \
|
||||
switch (cmd) { \
|
||||
case 0: it = M_F(name, _set_root)(tree, item); break; \
|
||||
case 1: it = M_F(name, _insert_right)(it, item); break; \
|
||||
case 2: it = M_F(name, _insert_child)(it, item); break; \
|
||||
default: M_ASSERT(0); \
|
||||
} \
|
||||
if (c == ',') { \
|
||||
/* The current item has some children */ \
|
||||
c = fgetc(f); \
|
||||
if (c != '}') { goto exit_clear; } \
|
||||
c = fgetc(f); \
|
||||
} while (c == ']'); \
|
||||
if (c != '[') break; \
|
||||
/* next is a child: push_down */ \
|
||||
cmd = 2; \
|
||||
continue; \
|
||||
} \
|
||||
/* The current item has no children. */ \
|
||||
if (c != '}') break; \
|
||||
/* Scan the next character to decide where to move (right or up) */ \
|
||||
c = fgetc(f); \
|
||||
if (c == ']') { \
|
||||
do { \
|
||||
/* move up. It we cannot, we have reached the end */ \
|
||||
if (!M_F(name, _it_up)(&it)) { success = true ; break; } \
|
||||
c = fgetc(f); \
|
||||
if (c != '}') goto do_break; \
|
||||
c = fgetc(f); \
|
||||
} while (c == ']'); \
|
||||
} \
|
||||
if (c != ',') { do_break: break; } \
|
||||
/* next is a sibling: push_right */ \
|
||||
cmd = 1; \
|
||||
} \
|
||||
if (c != ',') { goto exit_clear; } \
|
||||
/* next is a sibling: push_right */ \
|
||||
cmd = 1; \
|
||||
} \
|
||||
exit_success: \
|
||||
success = true; \
|
||||
exit_clear: \
|
||||
M_CALL_CLEAR(oplist, item); \
|
||||
exit: \
|
||||
M_TR33_CONTRACT(tree); \
|
||||
return success; \
|
||||
|
||||
Reference in new issue
Block a user