Make I/O functions exception aware.

Simplify their logic
Fix other bugs.
This commit is contained in:
Patrick Pelissier committed 2024-03-08 00:15:08 +01:00
1 parent ca25dfb537
commit d22e75d7a0
9 files changed
+293 -356

No files matched your search

+3 -3
View File
@@ -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
View File
@@ -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 */ ) \
+8 -3
View File
@@ -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.
+28 -35
View File
@@ -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 */ ) \
+71 -86
View File
@@ -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 */ ) \
\
+25 -29
View File
@@ -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
View File
@@ -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
View File
@@ -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 */
+74 -82
View File
@@ -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; \