From 9ff906700aa1bf767198fbea176ec60c7cf00687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Palmer?= Date: Thu, 15 Feb 2024 11:39:12 +0100 Subject: [PATCH] Documentation: add documentation for parser_state.(c|h) --- app/src/parser/parser_state.c | 9 ++ app/src/parser/parser_state.h | 203 ++++++++++++++++++++++++++-------- 2 files changed, 164 insertions(+), 48 deletions(-) diff --git a/app/src/parser/parser_state.c b/app/src/parser/parser_state.c index 33ff70f6f..d00380564 100644 --- a/app/src/parser/parser_state.c +++ b/app/src/parser/parser_state.c @@ -18,9 +18,18 @@ #include "parser_state.h" +/** + * @brief Syntactic sugar to handle parser result case + * + */ #define TZ_LABEL(_x) \ case TZ_##_x: \ return #_x + +/** + * @brief Syntactic sugar to handle blocking parser result case + * + */ #define BLO_LABEL(_x) \ case TZ_BLO_##_x: \ return #_x diff --git a/app/src/parser/parser_state.h b/app/src/parser/parser_state.h index a530c8010..4b727ae12 100644 --- a/app/src/parser/parser_state.h +++ b/app/src/parser/parser_state.h @@ -24,84 +24,182 @@ // Parser buffers and buffer handling registers +/** + * @brief This struct represents the parser register. + * + * It contains output and input buffers + * + */ typedef struct { - // update `ibuf`, `iofs` and `ilen` at once with `parser_regs_refill` - // invariant between two refills: - // `iofs + ilen` = (constant) number of readable bytes in `ibuf` - uint8_t *ibuf; // input buffer - size_t iofs; // current offset - size_t ilen; // remaining bytes readable in input - // update `obuf`, `oofs` and `olen` at once with `parser_regs_flush` - // invariant between two refills: - // `oofs + olen` = (constant) number of readable bytes in `obuf` - char *obuf; // output buffer - size_t oofs; // current offset - size_t olen; // remaining bytes writable in output + /// update `ibuf`, `iofs` and `ilen` at once with `parser_regs_refill` + /// invariant between two refills: + /// `iofs + ilen` = (constant) number of readable bytes in `ibuf` + uint8_t *ibuf; /// input buffer + size_t iofs; /// current offset + size_t ilen; /// remaining bytes readable in input + /// update `obuf`, `oofs` and `olen` at once with `parser_regs_flush` + /// invariant between two refills: + /// `oofs + olen` = (constant) number of readable bytes in `obuf` + char *obuf; /// output buffer + size_t oofs; /// current offset + size_t olen; /// remaining bytes writable in output } tz_parser_regs; // Parser state -#define TZ_FIELD_NAME_SIZE 30 -#define TZ_CAPTURE_BUFFER_SIZE 256 +#define TZ_FIELD_NAME_SIZE 30 /// The size of the field name buffer +#define TZ_CAPTURE_BUFFER_SIZE 256 /// The size of the capture buffer +/** + * @brief Enumeration of all kinds of results meaningful to the parser + * + */ typedef enum { - // success and non blocking, should loop again - TZ_CONTINUE = 0, // fall through rest of current step - TZ_BREAK, // signals caller to return, errno should be CONTINUE - // success but parsing blocked - TZ_BLO_DONE = 100, // parsing complete - TZ_BLO_FEED_ME, // blocked on read from input - TZ_BLO_IM_FULL, // blocked on output space - // everything below is an error - TZ_ERR_INVALID_TAG = 200, - TZ_ERR_INVALID_OP, - TZ_ERR_INVALID_DATA, - TZ_ERR_UNSUPPORTED, - TZ_ERR_TOO_LARGE, - TZ_ERR_TOO_DEEP, - TZ_ERR_INVALID_STATE, + /// success and non blocking, should loop again + TZ_CONTINUE = 0, /// fall through rest of current step + TZ_BREAK, /// signals caller to return, errno should be CONTINUE + /// success but parsing blocked + TZ_BLO_DONE = 100, /// parsing complete + TZ_BLO_FEED_ME, /// blocked on read from input + TZ_BLO_IM_FULL, /// blocked on output space + /// everything below is an error + TZ_ERR_INVALID_TAG = 200, /// an invalid tag has been found + TZ_ERR_INVALID_OP, /// an invalid michelson operation has been found + TZ_ERR_INVALID_DATA, /// a data has been considered as invalid + TZ_ERR_UNSUPPORTED, /// a non-supported action has been triggered + TZ_ERR_TOO_LARGE, /// too large data has been found + TZ_ERR_TOO_DEEP, /// too deep data has been found + TZ_ERR_INVALID_STATE, /// the parser is in an invalid state } tz_parser_result; -#define TZ_IS_BLOCKED(code) (code >= 100) -#define TZ_IS_ERR(code) (code >= 200) +#define TZ_IS_BLOCKED(code) \ + (code >= 100) /// If the result is a blocking result +#define TZ_IS_ERR(code) (code >= 200) /// If the result is an error + +/** + * @brief Get the human readable name of a parser result + * + * @param code: the parser result + * @return const char*: the name of the parser result + */ const char *tz_parser_result_name(tz_parser_result code); +/** + * @brief This struct represents the parser state. + * + */ typedef struct { - tz_parser_regs regs; + tz_parser_regs regs; /// parser register // common fields to communicate with caller - tz_parser_result errno; + tz_parser_result errno; /// current parser result struct { - char field_name[TZ_FIELD_NAME_SIZE]; - bool is_field_complex; - int field_index; - } field_info; - // common singleton buffers - int ofs; + char field_name[TZ_FIELD_NAME_SIZE]; /// the name of the last field + /// parsed + bool is_field_complex; /// if the last field parsed is considered + /// complex for a common user + int field_index; /// the index of the last field parsed + } field_info; /// information of the last field parsed + // common singleton buffers + int ofs; /// offset for the parser struct { - tz_num_parser_buffer num; - uint8_t capture[TZ_CAPTURE_BUFFER_SIZE]; + tz_num_parser_buffer num; /// number parser buffer + uint8_t capture[TZ_CAPTURE_BUFFER_SIZE]; /// capture buffer is used + /// to store string values } buffers; // input type specific state - tz_micheline_state micheline; - tz_operation_state operation; + tz_micheline_state micheline; /// micheline parser state + tz_operation_state operation; /// operation parser state } tz_parser_state; +/** + * @brief Initialize a parser state + * + * @param state: the parser state + */ void tz_parser_init(tz_parser_state *state); + +/** + * @brief Flush what has been parsed + * + * @param state: the parser state + * @param obuf: the ouput buffer + * @param olen: the length of the output buffer + */ void tz_parser_flush(tz_parser_state *state, char *obuf, size_t olen); + +/** + * @brief Flush a part of what has been parsed + * + * @param state: the parser state + * @param obuf: the ouput buffer + * @param olen: the length of the output buffer + * @param up_to: the length of what we want to flush up to + */ void tz_parser_flush_up_to(tz_parser_state *state, char *obuf, size_t olen, size_t up_to); + +/** + * @brief Refill what should be parsed + * + * @param state: the parser state + * @param ibuf: the input buffer + * @param ilen: the length of the input buffer + */ void tz_parser_refill(tz_parser_state *state, uint8_t *ibuf, size_t ilen); + +/** + * @brief Skip to next byte + * + * @param state: the parser state + */ void tz_parser_skip(tz_parser_state *state); +/** + * @brief Put a character at the end of was has been parsed + * + * @param state: the parser state + * @param c: the character + * @return tz_parser_result: the parser result + */ tz_parser_result tz_parser_put(tz_parser_state *state, char c); + +/** + * @brief Read a bytes + * + * @param state: the parser state + * @param out: the output character pointer + * @return tz_parser_result: the parser result + */ tz_parser_result tz_parser_read(tz_parser_state *state, uint8_t *out); + +/** + * @brief Peek a bytes + * + * @param state: the parser state + * @param out: the output character pointer + * @return tz_parser_result: the parser result + */ tz_parser_result tz_parser_peek(tz_parser_state *state, uint8_t *out); // error handling utils +/** + * @brief Set and raise a parser result + * + * @param state: the parser state + * @param code: the parser result to set + * @return tz_parser_result: the parser result raised + */ tz_parser_result tz_parser_set_errno(tz_parser_state *state, tz_parser_result code); + +/** + * @brief Set a parser result and raise + * + * Expect a `state` variable + * + */ #ifdef TEZOS_DEBUG #define tz_return(e) \ do { \ @@ -115,9 +213,17 @@ tz_parser_result tz_parser_set_errno(tz_parser_state *state, #else #define tz_return(e) return tz_parser_set_errno(state, e) #endif -#define tz_raise(e) tz_return(TZ_ERR_##e) -#define tz_stop(e) tz_return(TZ_BLO_##e) -#define tz_reraise return state->errno + +#define tz_raise(e) tz_return(TZ_ERR_##e) /// Raise an parser error +#define tz_stop(e) tz_return(TZ_BLO_##e) /// Stop the parser +#define tz_reraise return state->errno /// Re-raise the parser result + +/** + * @brief Raise if the condition did not continue + * + * Usually used to ensure that the parser did not raised errors + * + */ #define tz_must(cond) \ do { \ tz_parser_result _err = cond; \ @@ -125,5 +231,6 @@ tz_parser_result tz_parser_set_errno(tz_parser_state *state, tz_return(_err); \ } \ } while (0) -#define tz_continue tz_return(TZ_CONTINUE) -#define tz_break tz_return(TZ_BREAK) + +#define tz_continue tz_return(TZ_CONTINUE) /// continue the parsing +#define tz_break tz_return(TZ_BREAK) /// break the parsing