diff --git a/include/psyc/parser.h b/include/psyc/parser.h index c5d13be..2f320b4 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -66,44 +66,47 @@ typedef struct typedef struct { - size_t cursor; /** current position in buffer */ - size_t startc; /** line start position */ + size_t cursor; ///< current position in buffer + size_t startc; ///< line start position PSYC_Array buffer; uint8_t flags; - char part; /** part of the packet being parsed currently, see PSYC_Parts */ + char part; ///< part of the packet being parsed currently, see PSYC_Parts - size_t contentParsed; /** number of bytes parsed from the content so far */ - size_t contentLength; /** expected length of the content */ - char contentLengthFound; /** is there a length given for this packet? */ - size_t valueParsed; /** number of bytes parsed from the value so far */ - size_t valueLength; /** expected length of the value */ + size_t contentParsed; ///< number of bytes parsed from the content so far + size_t contentLength; ///< expected length of the content + char contentLengthFound; ///< is there a length given for this packet? + size_t valueParsed; ///< number of bytes parsed from the value so far + size_t valueLength; ///< expected length of the value } PSYC_State; typedef struct { - size_t cursor; /** current position in buffer */ - size_t startc; /** line start position */ + size_t cursor; ///< current position in buffer + size_t startc; ///< line start position PSYC_Array buffer; - char type; /** list type, see PSYC_ListTypes */ + char type; ///< list type, see PSYC_ListTypes - size_t elemParsed; /** number of bytes parsed from the elem so far */ - size_t elemLength; /** expected length of the elem */ + size_t elemParsed; ///< number of bytes parsed from the elem so far + size_t elemLength; ///< expected length of the elem } PSYC_ListState; #ifndef PSYC_COMPILE_LIBRARY -/* @brief Shortcut for creating an array. +/** + * Shortcut for creating an array. * * @param memory Pointer to the buffer. * @param length Length of that buffer. * - * @return An instance of the PSYC_Array struct. */ + * @return An instance of the PSYC_Array struct. + */ inline PSYC_Array PSYC_createArray (uint8_t* const memory, size_t length) { PSYC_Array arr = {length, memory}; return arr; } -/* @brief Initiates the state struct with flags. +/** + * Initiates the state struct with flags. * * @param state Pointer to the state struct that should be initiated. * @param flags The flags that one ones to set, see PSYC_Flags. @@ -114,7 +117,8 @@ inline void PSYC_initState2 (PSYC_State* state, uint8_t flags ) state->flags = flags; } -/* @brief Initiates the state struct. +/** + * Initiates the state struct. * * @param state Pointer to the state struct that should be initiated. */ @@ -123,7 +127,8 @@ inline void PSYC_initState (PSYC_State* state) memset(state, 0, sizeof(PSYC_State)); } -/* @brief Initiates the list state struct. +/** + * Initiates the list state struct. * * @param state Pointer to the list state struct that should be initiated. */ diff --git a/src/parser.c b/src/parser.c index 0c363c2..b039bbc 100644 --- a/src/parser.c +++ b/src/parser.c @@ -14,9 +14,9 @@ return ret; \ } -/** @brief isGlyph - * - * @todo: document this function +/** + * Determines if the argument is a glyph. + * Glyphs are: : = + - ? ! */ inline char isGlyph(uint8_t g) { @@ -34,11 +34,17 @@ inline char isGlyph(uint8_t g) } } +/** + * Determines if the argument is numeric. + */ inline char isNumeric(uint8_t c) { return c >= '0' && c <= '9'; } +/** + * Determines if the argument is alphanumeric. + */ inline char isAlphaNumeric(uint8_t c) { return @@ -47,14 +53,18 @@ inline char isAlphaNumeric(uint8_t c) isNumeric(c); } +/** + * Determines if the argument is a keyword character. + * Keyword characters are: alphanumeric and _ + */ inline char isKwChar(uint8_t c) { return isAlphaNumeric(c) || c == '_'; } /** - * @brief Parse variable name or method name. - * @details It should contain one or more keyword characters. + * Parse variable name or method name. + * It should contain one or more keyword characters. * @return PSYC_ERROR or PSYC_SUCCESS */ inline int PSYC_parseName(PSYC_State* state, PSYC_Array* name) @@ -64,7 +74,7 @@ inline int PSYC_parseName(PSYC_State* state, PSYC_Array* name) while (isKwChar(state->buffer.ptr[state->cursor])) { - name->length++; /* was a valid char, increase length */ + name->length++; // was a valid char, increase length ADVANCE_CURSOR_OR_RETURN(PSYC_INSUFFICIENT); } @@ -72,8 +82,8 @@ inline int PSYC_parseName(PSYC_State* state, PSYC_Array* name) } /** - * @brief Parse binary data into value. - * @details length is the expected length of the data, parsed is the number of bytes parsed so far + * Parse binary data into value. + * length is the expected length of the data, parsed is the number of bytes parsed so far * @return PSYC_COMPLETE or PSYC_INCOMPLETE */ inline int PSYC_parseBinaryValue(PSYC_State* state, PSYC_Array* value, size_t* length, size_t* parsed) @@ -81,7 +91,7 @@ inline int PSYC_parseBinaryValue(PSYC_State* state, PSYC_Array* value, size_t* l size_t remaining = *length - *parsed; value->ptr = state->buffer.ptr + state->cursor; - if (state->cursor + remaining > state->buffer.length) /* is the length larger than this buffer? */ + if (state->cursor + remaining > state->buffer.length) // is the length larger than this buffer? { value->length = state->buffer.length - state->cursor; *parsed += value->length; @@ -96,7 +106,7 @@ inline int PSYC_parseBinaryValue(PSYC_State* state, PSYC_Array* value, size_t* l } /** - * @brief Parse simple or binary variable + * Parse simple or binary variable. * @return PSYC_ERROR or PSYC_SUCCESS */ inline int PSYC_parseVar(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value) @@ -109,10 +119,10 @@ inline int PSYC_parseVar(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, value->length = 0; - /* Parse the value. - * If we're in the content part check if it's a binary var */ - if (state->part == PSYC_PART_CONTENT && state->buffer.ptr[state->cursor] == ' ') /* binary arg */ - { /* After SP the length follows. */ + // Parse the value. + // If we're in the content part check if it's a binary var. + if (state->part == PSYC_PART_CONTENT && state->buffer.ptr[state->cursor] == ' ') // binary arg + { // After SP the length follows. ADVANCE_CURSOR_OR_RETURN(PSYC_INSUFFICIENT); state->valueLength = 0; state->valueParsed = 0; @@ -129,11 +139,11 @@ inline int PSYC_parseVar(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, else return PSYC_ERROR_VAR_LEN; - /* After the length a TAB follows. */ + // After the length a TAB follows. if (state->buffer.ptr[state->cursor] != '\t') return PSYC_ERROR_VAR_TAB; - if (state->buffer.length <= ++(state->cursor)) /* Incremented cursor inside length? */ + if (state->buffer.length <= ++(state->cursor)) // Incremented cursor inside length? return PSYC_ENTITY_INCOMPLETE; if (PSYC_parseBinaryValue(state, value, &(state->valueLength), &(state->valueParsed)) == PSYC_INCOMPLETE) @@ -142,7 +152,7 @@ inline int PSYC_parseVar(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, state->cursor++; return PSYC_SUCCESS; } - else if (state->buffer.ptr[state->cursor] == '\t') /* simple arg */ + else if (state->buffer.ptr[state->cursor] == '\t') // simple arg { ADVANCE_CURSOR_OR_RETURN(PSYC_INSUFFICIENT); value->ptr = state->buffer.ptr + state->cursor; @@ -159,49 +169,52 @@ inline int PSYC_parseVar(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, return PSYC_ERROR_VAR_TAB; } -/** @brief Generalized line-based parser. */ +/** + * Parse PSYC packets. + * Generalized line-based parser. + * @return see PSYC_ReturnCodes + */ int PSYC_parse(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value) { - int ret; /* a return value */ - size_t pos; /* a cursor position */ + int ret; // a return value + size_t pos; // a cursor position - /* Start position of the current line in the buffer - * in case we return insufficent, we rewind to this position. */ + // Start position of the current line in the buffer + // in case we return insufficent, we rewind to this position. state->startc = state->cursor; - /* First we test if we can access the first char. */ - if (state->cursor >= state->buffer.length) /* cursor is not inside the length */ - return PSYC_INSUFFICIENT; /* return insufficient data. */ + // First we test if we can access the first char. + if (state->cursor >= state->buffer.length) // cursor is not inside the length + return PSYC_INSUFFICIENT; switch (state->part) { - case PSYC_PART_RESET: /* New packet starts here, reset state. */ + case PSYC_PART_RESET: // New packet starts here, reset state. state->valueParsed = 0; state->valueLength = 0; state->contentParsed = 0; state->contentLength = 0; state->contentLengthFound = 0; state->part = PSYC_PART_HEADER; - /* fall thru */ + // fall thru case PSYC_PART_HEADER: - /* Each line of the header starts with a glyph, - * i.e. :_name, -_name +_name etc, - * so just test if the first char is a glyph. - */ - if (isGlyph(state->buffer.ptr[state->cursor])) /* is the first char a glyph? */ - { /* it is a glyph, so a variable starts here */ + // Each line of the header starts with a glyph, + // i.e. :_name, -_name +_name etc, + // so just test if the first char is a glyph. + if (isGlyph(state->buffer.ptr[state->cursor])) // is the first char a glyph? + { // it is a glyph, so a variable starts here ret = PSYC_parseVar(state, modifier, name, value); return ret == PSYC_SUCCESS ? PSYC_ROUTING : ret; } - else /* not a glyph */ + else // not a glyph { state->part = PSYC_PART_LENGTH; - /* fall thru */ + // fall thru } case PSYC_PART_LENGTH: - /* End of header, content starts with an optional length then a NL */ + // End of header, content starts with an optional length then a NL if (isNumeric(state->buffer.ptr[state->cursor])) { state->contentLengthFound = 1; @@ -214,17 +227,18 @@ int PSYC_parse(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, PSYC_Arra while (isNumeric(state->buffer.ptr[state->cursor])); } - if (state->buffer.ptr[state->cursor] == '\n') /* start of content */ + if (state->buffer.ptr[state->cursor] == '\n') // start of content { - /* If we need to parse the header only and we know the content length, then skip content parsing. */ + // If we need to parse the header only and we know the content length, + // then skip content parsing. if (state->flags & PSYC_HEADER_ONLY && state->contentLengthFound) state->part = PSYC_PART_DATA; else state->part = PSYC_PART_CONTENT; } - else /* Not start of content, this must be the end. */ + else // Not start of content, this must be the end. { - /* If we have a length then it should've been followed by a \n */ + // If we have a length then it should've been followed by a \n if (state->contentLengthFound) return PSYC_ERROR_LENGTH; @@ -234,22 +248,21 @@ int PSYC_parse(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, PSYC_Arra ADVANCE_CURSOR_OR_RETURN(PSYC_INSUFFICIENT); state->startc = state->cursor; - /* fall thru */ + // fall thru case PSYC_PART_CONTENT: - /* In case of an incomplete binary variable resume parsing it. */ + // In case of an incomplete binary variable resume parsing it. if (state->valueParsed < state->valueLength) { ret = PSYC_parseBinaryValue(state, value, &(state->valueLength), &(state->valueParsed)); state->contentParsed += value->length; return ret == PSYC_COMPLETE ? PSYC_ENTITY : PSYC_ENTITY_INCOMPLETE; } - /* Each line of the header starts with a glyph, - * i.e. :_name, -_name +_name etc. - * So just test if the first char is a glyph. - * In the body, the same applies, only that the - * method does not start with a glyph. - */ + // Each line of the header starts with a glyph, + // i.e. :_name, -_name +_name etc. + // So just test if the first char is a glyph. + // In the body, the same applies, only that the + // method does not start with a glyph. if (isGlyph(state->buffer.ptr[state->cursor])) { pos = state->cursor; @@ -261,13 +274,13 @@ int PSYC_parse(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, PSYC_Arra { state->part = PSYC_PART_METHOD; state->startc = state->cursor; - /* fall thru */ + // fall thru } case PSYC_PART_METHOD: pos = state->cursor; if (PSYC_parseName(state, name) == PSYC_SUCCESS) - { /* the method ends with a \n then the data follows */ + { // the method ends with a \n then the data follows if (state->buffer.ptr[state->cursor] != '\n') return PSYC_ERROR_METHOD; @@ -277,9 +290,9 @@ int PSYC_parse(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, PSYC_Arra state->part = PSYC_PART_DATA; if (state->cursor >= state->buffer.length) return PSYC_INSUFFICIENT; - /* fall thru */ + // fall thru } - else /* No method, which means the packet should end now. */ + else // No method, which means the packet should end now. { state->part = PSYC_PART_END; state->startc = state->cursor; @@ -290,7 +303,7 @@ int PSYC_parse(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, PSYC_Arra value->ptr = state->buffer.ptr + state->cursor; value->length = 0; - if (state->contentLengthFound) /* We know the length of the packet. */ + if (state->contentLengthFound) // We know the length of the packet. { if (PSYC_parseBinaryValue(state, value, &(state->contentLength), &(state->contentParsed)) == PSYC_INCOMPLETE) return PSYC_BODY_INCOMPLETE; @@ -299,20 +312,20 @@ int PSYC_parse(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, PSYC_Arra state->part = PSYC_PART_END; return PSYC_BODY; } - else /* Search for the terminator. */ + else // Search for the terminator. { while (1) { if (state->buffer.ptr[state->cursor] == '\n') { - if (state->cursor+2 >= state->buffer.length) /* incremented cursor inside length? */ + if (state->cursor+2 >= state->buffer.length) // incremented cursor inside length? { state->cursor = state->startc; return PSYC_INSUFFICIENT; } if (state->buffer.ptr[state->cursor+1] == '|' && - state->buffer.ptr[state->cursor+2] == '\n') /* packet ends here */ + state->buffer.ptr[state->cursor+2] == '\n') // packet ends here { state->cursor++; state->part = PSYC_PART_END; @@ -326,28 +339,31 @@ int PSYC_parse(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, PSYC_Arra case PSYC_PART_END: PSYC_PART_END: - /* End of packet, at this point we have already passed a \n - and the cursor should point to | */ - if (state->cursor+1 >= state->buffer.length) /* incremented cursor inside length? */ + // End of packet, at this point we have already passed a \n + // and the cursor should point to | + if (state->cursor+1 >= state->buffer.length) // incremented cursor inside length? return PSYC_INSUFFICIENT; if (state->buffer.ptr[state->cursor] == '|' && - state->buffer.ptr[state->cursor+1] == '\n') /* packet ends here */ + state->buffer.ptr[state->cursor+1] == '\n') // packet ends here { state->cursor += 2; state->part = PSYC_PART_RESET; return PSYC_COMPLETE; } - else /* packet should've ended here, return error */ + else // packet should've ended here, return error { state->part = PSYC_PART_RESET; return PSYC_ERROR_END; } } - return PSYC_ERROR; /* should not be reached */ + return PSYC_ERROR; // should not be reached } -/** @brief list parser */ +/** + * List value parser. + * @return see PSYC_ListReturnCodes. + */ int PSYC_parseList(PSYC_ListState* state, PSYC_Array *name, PSYC_Array* value, PSYC_Array* elem) { if (state->cursor >= state->buffer.length) @@ -355,13 +371,13 @@ int PSYC_parseList(PSYC_ListState* state, PSYC_Array *name, PSYC_Array* value, P state->startc = state->cursor; - if (!state->type) /* If type is not set we're at the start */ + if (!state->type) // If type is not set we're at the start { if (name->length < 5 || memcmp(name->ptr, "_list", 5) != 0 || - (name->length > 5 && name->ptr[5] != '_')) /* name should be _list or should start with _list_ */ + (name->length > 5 && name->ptr[5] != '_')) // name should be _list or should start with _list_ return PSYC_ERROR_LIST_NAME; - /* First character is either | for text lists, or a number for binary lists */ + // First character is either | for text lists, or a number for binary lists if (state->buffer.ptr[state->cursor] == '|') { state->type = PSYC_LIST_TEXT; @@ -390,10 +406,11 @@ int PSYC_parseList(PSYC_ListState* state, PSYC_Array *name, PSYC_Array* value, P state->cursor++; return PSYC_LIST_ELEM; } - else /* binary list */ + else // binary list { - if (!(state->elemParsed < state->elemLength)) { - /* Element starts with a number. */ + if (!(state->elemParsed < state->elemLength)) + { + // Element starts with a number. if (isNumeric(state->buffer.ptr[state->cursor])) { do @@ -415,8 +432,9 @@ int PSYC_parseList(PSYC_ListState* state, PSYC_Array *name, PSYC_Array* value, P state->elemParsed = 0; } - /* Start or resume parsing the binary data */ - if (state->elemParsed < state->elemLength) { + // Start or resume parsing the binary data + if (state->elemParsed < state->elemLength) + { if (PSYC_parseBinaryValue((PSYC_State*)state, elem, &(state->elemLength), &(state->elemParsed)) == PSYC_INCOMPLETE) return PSYC_LIST_INCOMPLETE; @@ -433,5 +451,5 @@ int PSYC_parseList(PSYC_ListState* state, PSYC_Array *name, PSYC_Array* value, P } } - return PSYC_ERROR_LIST; /* should not be reached */ + return PSYC_ERROR_LIST; // should not be reached }