diff --git a/include/psyc/parser.h b/include/psyc/parser.h index c1b9435..f463942 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -9,15 +9,35 @@ enum PSYC_Flags enum PSYC_ReturnCodes { - PSYC_ERROR_EXPECTED_TAB = -8, + PSYC_ERROR_END = -7, + PSYC_ERROR_METHOD = -6, + PSYC_ERROR_VAR_LEN = -5, + PSYC_ERROR_VAR_TAB = -4, + PSYC_ERROR_VAR_NAME = -3, + PSYC_ERROR_LENGTH = -2, + PSYC_ERROR = -1, + PSYC_SUCCESS = 0, PSYC_BODY = 1, - PSYC_BODY_INCOMPLETE, - PSYC_INSUFFICIENT, - PSYC_ROUTING, - PSYC_ENTITY, - PSYC_ENTITY_INCOMPLETE, - PSYC_HEADER_COMPLETE, - PSYC_COMPLETE, + PSYC_BODY_INCOMPLETE = 2, + PSYC_INSUFFICIENT = 3, + PSYC_ROUTING = 4, + PSYC_ENTITY = 5, + PSYC_ENTITY_INCOMPLETE = 6, + PSYC_HEADER_COMPLETE = 7, + PSYC_COMPLETE = 8, + PSYC_INCOMPLETE = 9, +}; + +enum PSYC_Parts +{ + PSYC_PART_RESET = -1, + PSYC_PART_HEADER = 0, + PSYC_PART_LENGTH, + PSYC_PART_HEADER_END, + PSYC_PART_CONTENT, + PSYC_PART_METHOD, + PSYC_PART_DATA, + PSYC_PART_END, }; @@ -30,14 +50,17 @@ typedef struct typedef struct { - unsigned int cursor; // current position in buffer + unsigned int cursor; /** current position in buffer */ + unsigned int startc; /** line start position */ PSYC_Array buffer; uint8_t flags; + char part; /** part of the packet being parsed currently, see PSYC_Parts */ - unsigned int contentParsed; // - char inContent; - unsigned int valueRemaining; - unsigned int contentLength; + unsigned int contentParsed; /** number of bytes parsed from the content so far */ + unsigned int contentLength; /** expected length of the content */ + char contentLengthFound; /** is there a length given for this packet? */ + unsigned int valueParsed; /** number of bytes parsef from the value so far */ + unsigned int valueLength; /** expected length of the value */ } PSYC_State; #ifndef PSYC_COMPILE_LIBRARY @@ -83,12 +106,6 @@ inline unsigned int PSYC_getContentLength (PSYC_State* s) return s->contentLength; } -inline unsigned int PSYC_getValueRemaining (PSYC_State* s) -{ - return s->valueRemaining; -} - #endif -int PSYC_parse(PSYC_State* state, - uint8_t* modifier, PSYC_Array* name, PSYC_Array* value); +int PSYC_parse(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value); diff --git a/src/Makefile b/src/Makefile index 5695fa1..241ad61 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,3 +1,4 @@ +CFLAGS=-I../../include -DDEBUG -DPSYC_COMPILE_LIBRARY -g -O0 -Wall CC=cc -I../include # CC=clang @@ -8,11 +9,11 @@ default: @/bin/echo -e "Usage:\n\tmake diet - compile with diet libc\n\tmake lib - compile with normal gnu libc" diet: - diet ${CC} -static -c -Os $S -DDEBUG -DPSYC_COMPILE_LIBRARY + diet ${CC} -static -c -Os $S ${CFLAGS} diet ar rcs libpsyc.a $O lib: $S - ${CC} -static -c -g -O0 $S -lc -DDEBUG -DPSYC_COMPILE_LIBRARY + ${CC} -static -c -g -O0 $S -lc ${CFLAGS} ar rcs libpsyc.a $O match: match.c diff --git a/src/parser.c b/src/parser.c index ba7c209..ab8c918 100644 --- a/src/parser.c +++ b/src/parser.c @@ -7,6 +7,13 @@ #include +#define ADVANCE_CURSOR_OR_RETURN() \ + if (++(state->cursor) >= state->buffer.length) \ + { \ + state->cursor = state->startc; \ + return PSYC_INSUFFICIENT; \ + } + /** @brief isGlyph * * @todo: document this function @@ -16,9 +23,10 @@ inline char isGlyph(uint8_t g) switch(g) { case ':': - case '-': - case '+': case '=': + case '?': + case '+': + case '-': return 1; default: return 0; @@ -26,411 +34,319 @@ inline char isGlyph(uint8_t g) } - inline char isNumeric(uint8_t c) { - return c >= '0' && c <= '9' ; + return c >= '0' && c <= '9'; } inline char isAlphaNumeric(uint8_t c) { return - (( c >= 'a' && c <= 'z' )|| - ( c >= 'A' && c <= 'Z' )|| - isNumeric(c)) - ; - + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + isNumeric(c); } - - -/** @brief generalized linebased parser */ -inline int PSYC_parse( - PSYC_State* state, - uint8_t* modifier, PSYC_Array* name, PSYC_Array* value) +inline char isKwChar(uint8_t c) { -start: + return c == '_' || isAlphaNumeric(c); +} - if (state->valueRemaining != 0) - goto binaryArg; +/** + * @brief Parse variable name or method name. + * @details It should contain one or more keyword characters. + * @return PSYC_ERROR or PSYC_SUCCESS + */ +inline int PSYC_parseName(PSYC_State* state, PSYC_Array* name) +{ + name->ptr = state->buffer.ptr + state->cursor; + name->length = 0; + + while (isKwChar(state->buffer.ptr[state->cursor])) + { + name->length++; // was a valid char, increase length + ADVANCE_CURSOR_OR_RETURN(); + } + + return name->length > 0 ? PSYC_SUCCESS : PSYC_ERROR; +} + +/** + * @brief Parse binary data into value. + * @details 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, unsigned int* length, unsigned int* parsed) +{ + unsigned int remaining = *length - *parsed; + value->ptr = state->buffer.ptr + state->cursor; + + if (state->cursor + remaining > state->buffer.length) // is the length larger than this buffer? + { + value->length = state->buffer.length - state->cursor; + *parsed += value->length; + state->cursor = 0; + return PSYC_INCOMPLETE; + } + + value->length += remaining; + state->cursor += remaining; + *parsed += value->length; + + return PSYC_COMPLETE; +} + +/** + * @brief 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) +{ + *modifier = *(state->buffer.ptr + state->cursor); + ADVANCE_CURSOR_OR_RETURN(); + + if (PSYC_parseName(state, name) != PSYC_SUCCESS) + return PSYC_ERROR_VAR_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. + ADVANCE_CURSOR_OR_RETURN(); + state->valueLength = 0; + state->valueParsed = 0; + + if (isNumeric(state->buffer.ptr[state->cursor])) + { + do + { + state->valueLength = 10 * state->valueLength + state->buffer.ptr[state->cursor] - '0'; + ADVANCE_CURSOR_OR_RETURN(); + } + while (isNumeric(state->buffer.ptr[state->cursor])); + } + else + return PSYC_ERROR_VAR_LEN; + + // 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? + { + state->cursor = 0; + return PSYC_ENTITY_INCOMPLETE; + } + + if (PSYC_parseBinaryValue(state, value, &(state->valueLength), &(state->valueParsed)) == PSYC_INCOMPLETE) + return PSYC_ENTITY_INCOMPLETE; + + state->cursor++; + return PSYC_SUCCESS; + } + else if (state->buffer.ptr[state->cursor] == '\t') // simple arg + { + ADVANCE_CURSOR_OR_RETURN(); + value->ptr = state->buffer.ptr + state->cursor; + + while (state->buffer.ptr[state->cursor] != '\n') + { + value->length++; + ADVANCE_CURSOR_OR_RETURN(); + } + state->cursor++; + return PSYC_SUCCESS; + } + else + return PSYC_ERROR_VAR_TAB; +} + +/** @brief generalized line-based parser */ +int PSYC_parse(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value) +{ + int ret; /* a return value */ + unsigned int pos; /* a cursor 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->buffer.length<=state->cursor) // cursor is not inside the length + if (state->buffer.length <= state->cursor) // cursor is not inside the length return PSYC_INSUFFICIENT; // return insufficient data. - // in case we return insufficent, we rewind to the start. - unsigned int startc=state->cursor; - - /****************************************** - * * * * * * * Inspect Header * * * * * * * - *******************************************/ - /* each line of the header starts with a glyph. - * iE :_name, -_name +_name etc, so just test if - * the first char is a glyph. */ - if(0==state->inContent) + switch (state->part) { - if(!isGlyph(state->buffer.ptr[state->cursor])) // is the first char not a glyph? - { // parse length of content here - if(isNumeric(state->buffer.ptr[state->cursor])) - { - if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length? - { - state->cursor=startc; // set to start value - return PSYC_INSUFFICIENT; // return insufficient - } + 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 - while(isNumeric(state->buffer.ptr[state->cursor])); + 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 + ret = PSYC_parseVar(state, modifier, name, value); + return ret == PSYC_SUCCESS ? PSYC_ROUTING : ret; + } + else // not a glyph + { + state->part = PSYC_PART_LENGTH; + // fall thru + } + + case PSYC_PART_LENGTH: + /* End of header, content starts with an optional length then a NL */ + if (isNumeric(state->buffer.ptr[state->cursor])) + { + state->contentLengthFound = 1; + state->contentLength = 0; + do { state->contentLength = 10 * state->contentLength + state->buffer.ptr[state->cursor] - '0'; - - if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length? - { - state->cursor=startc; // set to start value - return PSYC_INSUFFICIENT; // return insufficient - } + ADVANCE_CURSOR_OR_RETURN(); } - } - // header ends with a NL - if (state->buffer.ptr[state->cursor] != '\n') - { - return -10; + while (isNumeric(state->buffer.ptr[state->cursor])); } - if (state->buffer.length<=++(state->cursor)) // incremented cursor inside length? + if (state->buffer.ptr[state->cursor] == '\n') /* start of content */ { - state->cursor=startc; // set to start value - return PSYC_INSUFFICIENT; // return insufficient - } - - // the only other possibility now is that the packet - // is complete(empty packet) or that the method started. - if (isAlphaNumeric(state->buffer.ptr[state->cursor])) - { - state->inContent = 1; - - if (state->flags & PSYC_HEADER_ONLY) - return PSYC_HEADER_COMPLETE; // return header finished + /* 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 - goto start; + state->part = PSYC_PART_CONTENT; + } + 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 (state->contentLengthFound) + return PSYC_ERROR_LENGTH; + + state->part = PSYC_PART_END; + goto PSYC_PART_END; } - if (state->buffer.ptr[state->cursor] == '|') - { - if (state->buffer.length<=++(state->cursor)) // incremented cursor inside length? - { - state->cursor=startc; // set to start value - return PSYC_INSUFFICIENT; // return insufficient - } + ADVANCE_CURSOR_OR_RETURN(); + state->startc = state->cursor; + // fall thru - if (state->buffer.ptr[state->cursor]=='\n') - { - ++(state->cursor); - state->inContent = 0; - return PSYC_COMPLETE; // return packet finished - } - } - return -6; // report error - } - else // it is a glyph, so a variable name starts here - { - /*************************************************** - * * * * * * * Routing Variable Start * * * * * * * - **************************************************/ - - *modifier = *(state->buffer.ptr+state->cursor); - - if (state->buffer.length <= ++(state->cursor)) - { - state->cursor = startc; // rewind to start of line - return PSYC_INSUFFICIENT; // return insufficient + case PSYC_PART_CONTENT: + /* 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; } - name->ptr = state->buffer.ptr + state->cursor; - - name->length = 1; - } - } // endif inContent=0 - - char method=0; - /* each line of the header starts with a glyph. - * iE :_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(1==state->inContent) - { - if(!isGlyph(state->buffer.ptr[state->cursor])) - { - if(!isAlphaNumeric(state->buffer.ptr[state->cursor]) && state->buffer.ptr[state->cursor] != '_') + /* 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])) { - // the body rule is optional, which means - // that now also just |\n can follow. - if(state->buffer.ptr[state->cursor] == '|') - { - if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length? - { - state->cursor=startc; // set to start value - return PSYC_INSUFFICIENT; // return insufficient - } - - if(state->buffer.ptr[state->cursor]=='\n') - { - ++(state->cursor); - state->inContent = 0; - return PSYC_COMPLETE; // return packet finished - } - } - return -5; // report error + pos = state->cursor; + ret = PSYC_parseVar(state, modifier, name, value); + state->contentParsed += state->cursor - pos; + return ret == PSYC_SUCCESS ? PSYC_ENTITY : ret; } else { - name->ptr = state->buffer.ptr+state->cursor; - name->length=1; - method=1; - } - } - else - { - *modifier = *(state->buffer.ptr+state->cursor); - - if (state->buffer.length <= ++(state->cursor)) - { - state->cursor = startc; // rewind - return PSYC_INSUFFICIENT; // return insufficient + state->part = PSYC_PART_METHOD; + state->startc = state->cursor; + // fall thru } - name->ptr = state->buffer.ptr+state->cursor; - name->length=1; - } - } + case PSYC_PART_METHOD: + pos = state->cursor; + if (PSYC_parseName(state, name) == PSYC_SUCCESS) + { /* the method ends with a \n then the data follows */ + if (state->buffer.ptr[state->cursor] != '\n') + return PSYC_ERROR_METHOD; - /* validate the incremented cursor */ - if(state->buffer.length <= ++(state->cursor)) - { - state->cursor=startc; - return PSYC_INSUFFICIENT; - } - - /* what follows is the name. At least one char. - * allowed is alphanumeric and _ */ - - // first char must exist. - if(!isAlphaNumeric(state->buffer.ptr[state->cursor]) // is it not alphanum - && state->buffer.ptr[state->cursor] != '_') // AND not '_'. must be invalid then - return -1; // return parser error. - - name->length+=1; - - /* now checking how long the name of the variable is. */ - unsigned int i=0; - while(1) - { - if(state->buffer.length<= ++(state->cursor)) // incremented cursor inside length? - { - state->cursor=startc; // set to start value - return PSYC_INSUFFICIENT; // return insufficient - } - - // same as bevore - if(!isAlphaNumeric(state->buffer.ptr[state->cursor]) && - state->buffer.ptr[state->cursor] != '_') - break; // not valid? then stop the loop right here - - ++(name->length); // was a valid char, increase length - } - - /* we now parsed the variable name successfully - * after the name either a \n or a \t follows. - * - * for the method, the data starts after an \n - * so checking for \n too here - - * We dont check if cursor inside length, because - * the last loop iteration did that already. - */ - if(state->buffer.ptr[state->cursor] == '\t' || state->buffer.ptr[state->cursor] == '\n') // && method==1)) - { - /* after the \t the data follows, which is - * anything but \n. data can be of length 0 - * - * for the method: after the \n data follows, - * which is anything but \n|\n - * - * but data is optional, so we first check - * here if data follows at all. - * - * arg-data=value. we set value here so it - * points to a valid range and so we point - * to the first potential arg-data byte. - * If there is no arg-data, we still have - * the length attribute on 0. */ - if((method == 0 && state->buffer.ptr[state->cursor] == '\n') /* emptyvar */ || - (method == 1 && state->cursor+2 < state->buffer.length && - state->buffer.ptr[state->cursor+1] == '|' && - state->buffer.ptr[state->cursor+2] == '\n') /*no data */ ) - { - value->ptr=state->buffer.ptr+state->cursor; - value->length=0; - } - else - { - value->ptr=state->buffer.ptr+state->cursor+1; - if (0 != state->contentLength) // we know the length of the packet - { - // is the packet in the buffer? - if (value->ptr + state->contentLength + 3 > state->buffer.ptr + state->buffer.length) - { // no - value->length = state->buffer.length - state->cursor; - //*expectedBytes = state->contentLength - value->length; - } - else // yes, the packet is complete in the buffer. - { - value->length= state->buffer.length - state->cursor -3; - //*expectedBytes = 0; - } + state->cursor++; + state->startc = state->cursor; + state->contentParsed += state->cursor - pos; + state->part = PSYC_PART_DATA; + if (state->cursor >= state->buffer.length) + return PSYC_INSUFFICIENT; + // fall thru } - else // else search for the terminator + else /* no method, which means the packet should end now */ { - value->length=0; + state->part = PSYC_PART_END; + state->startc = state->cursor; + goto PSYC_PART_END; + } + case PSYC_PART_DATA: + value->ptr = state->buffer.ptr + state->cursor; + value->length = 0; + + 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; + + state->cursor++; + state->part = PSYC_PART_END; + return PSYC_BODY; + } + else // search for the terminator + { while (1) { - if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length? + if (state->buffer.ptr[state->cursor] == '\n') { - state->cursor=startc; // set to start value - return PSYC_INSUFFICIENT ; // return insufficient - } - - if(0 == method && state->buffer.ptr[state->cursor] == '\n') - break; - - if(1 == method && state->buffer.ptr[state->cursor] == '\n') - { - if(state->buffer.length<=(state->cursor)+2) // incremented cursor inside length? + if (state->cursor+2 >= state->buffer.length) // incremented cursor inside length? { - state->cursor=startc; // set to start value + state->cursor = state->startc; // set to start value return PSYC_INSUFFICIENT; // return insufficient } - if(state->buffer.ptr[state->cursor+1] == '|') - if(state->buffer.ptr[state->cursor+2] == '\n') - { - /* packet finishes here */ - state->cursor+=3; - state->inContent = 0; - return PSYC_COMPLETE; - } - + if (state->buffer.ptr[state->cursor+1] == '|' && + state->buffer.ptr[state->cursor+2] == '\n') /* packet ends here */ + { + state->cursor++; + state->part = PSYC_PART_END; + return PSYC_BODY; + } } - ++(value->length); + value->length++; + ADVANCE_CURSOR_OR_RETURN(); } } - } - } - else if(state->inContent == 1 && method==0 && state->buffer.ptr[state->cursor] == ' ') // oi, its a binary var! - { // after SP the length follows. - if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length? - { - state->cursor=startc; // set to start value - return PSYC_INSUFFICIENT; // return insufficient - } - while(isNumeric(state->buffer.ptr[state->cursor])) - { - value->length = 10 * value->length + state->buffer.ptr[state->cursor] - '0'; - - if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length? - { - state->cursor=startc; // set to start value + 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? return PSYC_INSUFFICIENT; // return insufficient + + if (state->buffer.ptr[state->cursor] == '|' && + 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 */ + { + state->part = PSYC_PART_RESET; + return PSYC_ERROR_END; } - } - // after the length a TAB follows - if (state->buffer.ptr[state->cursor] != '\t') - return PSYC_ERROR_EXPECTED_TAB; - -binaryArg: - if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length? - { - state->valueRemaining = value->length - state->cursor; - state->cursor=0; - - value->length = 0; - value->ptr = state->buffer.ptr; - - return PSYC_ENTITY_INCOMPLETE; - } - - // is the length still in this buffer? - if(state->buffer.length <= state->cursor+value->length+1 ) - { - state->valueRemaining = value->length - state->cursor; - state->cursor=0; - - value->ptr = state->buffer.ptr + state->cursor; - value->length = state->buffer.length - state->cursor; - - return PSYC_ENTITY_INCOMPLETE; - } - - value->ptr = state->buffer.ptr + state->cursor; - state->cursor += value->length; - state->valueRemaining = 0; } - else - return -8; - - - - - /* if there was a \t, then we parsed up until the - * \n char from the simple-arg rule ( \t arg-data \n ) - * - * Now, if there would be no \t, we still would be at - * the point where a \n must follow. - * - * So, just checking \n here will cover both cases of - * the alternative ( simple-arg / \n ) from rule - * routing-modifier - * - * again, the loop has already validated the cursors - * position*/ - if(state->buffer.ptr[state->cursor] != '\n') - return -2; // return parser error. - - /* if a \n follows now, the an body is attached. - * if not, a |\n must follow */ - if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length? - { - state->cursor=startc; // set to start value - return PSYC_INSUFFICIENT; // return insufficient - } - - if(0 == state->inContent && state->buffer.ptr[state->cursor] == '\n') - { - state->cursor+=1; - state->inContent = 1; - - return PSYC_ROUTING; // return header finished - } - - if(state->buffer.ptr[state->cursor] != '|') // no pipe, then only line complete, not the packet. - { - if (state->inContent == 0) - return PSYC_ROUTING; - else - return PSYC_ENTITY; - } - if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length? - { - state->cursor=startc; // set to start value - return PSYC_INSUFFICIENT; // return insufficient - } - if(state->buffer.ptr[state->cursor] != '\n') - return -4; - - state->cursor+=1; - state->inContent = 0; - return PSYC_COMPLETE; // packet is complete + return PSYC_ERROR; // should not be reached } - diff --git a/src/tests/Makefile b/src/tests/Makefile index 3ccdd4a..830b478 100644 --- a/src/tests/Makefile +++ b/src/tests/Makefile @@ -1,16 +1,12 @@ -CFLAGS=-I../../include -DDEBUG -g -O0 +CFLAGS=-I../../include -DDEBUG -g -O0 -Wall LDFLAGS=-L.. LOADLIBES=-lpsyc TARGETS=testParser testMatch all: $(TARGETS) -# special case because not in the same directory -testParser: - ${CC} ${CFLAGS} ${LDFLAGS} parser/testParser.c ${LOADLIBES} -o testParser - test: - for f in parser/*txt; do echo -e "\n>> $$f"; ./testParser $$f; done + for f in packets/*; do echo -e "\n>> $$f"; ./testParser $$f; done clean: - rm $(TARGETS) + rm -f $(TARGETS) diff --git a/src/tests/parser/binary.txt b/src/tests/packets/binary.txt similarity index 100% rename from src/tests/parser/binary.txt rename to src/tests/packets/binary.txt diff --git a/src/tests/parser/enter_leave_context.txt b/src/tests/packets/enter_leave_context.txt similarity index 100% rename from src/tests/parser/enter_leave_context.txt rename to src/tests/packets/enter_leave_context.txt diff --git a/src/tests/parser/fake_dns.txt b/src/tests/packets/fake_dns.txt similarity index 98% rename from src/tests/parser/fake_dns.txt rename to src/tests/packets/fake_dns.txt index ae6cde6..78deab0 100644 --- a/src/tests/parser/fake_dns.txt +++ b/src/tests/packets/fake_dns.txt @@ -4,4 +4,3 @@ _request_some_things content! | - diff --git a/src/tests/parser/invalid_dns.txt b/src/tests/packets/invalid_dns.txt similarity index 100% rename from src/tests/parser/invalid_dns.txt rename to src/tests/packets/invalid_dns.txt diff --git a/src/tests/packets/test-0-no-content b/src/tests/packets/test-0-no-content new file mode 100644 index 0000000..f17f81f --- /dev/null +++ b/src/tests/packets/test-0-no-content @@ -0,0 +1,3 @@ +:_source psyc://nb.tgbit.net/ +:_target psyc://nb.tgbit.net/ +| diff --git a/src/tests/packets/test-1 b/src/tests/packets/test-1 new file mode 100644 index 0000000..376237c --- /dev/null +++ b/src/tests/packets/test-1 @@ -0,0 +1,14 @@ +| +:_source psyc://foo/~bar +:_target psyc://bar/~baz +:_tag sch1828hu3r2cm + +:_foo bar baz +:_abc_def 11 foo bar +baz +:_foo_bar yay +_message_foo_bar +ohai there! +\o/ +| +| diff --git a/src/tests/packets/test-1-length b/src/tests/packets/test-1-length new file mode 100644 index 0000000..2c84573 --- /dev/null +++ b/src/tests/packets/test-1-length @@ -0,0 +1,14 @@ +| +:_source psyc://foo/~bar +:_target psyc://bar/~baz +:_tag sch1828hu3r2cm +85 +:_foo bar baz +:_abc_def 11 foo bar +baz +:_foo_bar yay +_message_foo_bar +ohai there! +\o/ +| +| diff --git a/src/tests/packets/test-1-length-error b/src/tests/packets/test-1-length-error new file mode 100644 index 0000000..98a6bf6 --- /dev/null +++ b/src/tests/packets/test-1-length-error @@ -0,0 +1,14 @@ +| +:_source psyc://foo/~bar +:_target psyc://bar/~baz +:_tag sch1828hu3r2cm +80 +:_foo bar baz +:_abc_def 11 foo bar +baz +:_foo_bar yay +_message_foo_bar +ohai there! +\o/ +| +| diff --git a/src/tests/packets/test-1-utf8 b/src/tests/packets/test-1-utf8 new file mode 100644 index 0000000..b054c27 --- /dev/null +++ b/src/tests/packets/test-1-utf8 @@ -0,0 +1,14 @@ +| +:_source psyc://foo/~bar +:_target psyc://bar/~baz +:_tag sch1828hu3r2cm + +:_foo bar baz +:_abc_def 15 fóö bär +báz +:_foo_bar yay +_message_foo_bar +ohai there! +\o/ +| +| diff --git a/src/tests/packets/test-2-list b/src/tests/packets/test-2-list new file mode 100644 index 0000000..b534143 --- /dev/null +++ b/src/tests/packets/test-2-list @@ -0,0 +1,25 @@ +| +=_source psyc://foo/~bar +:_target psyc://bar/~baz +=_list_foo foo|bar|baz +:_tag sch1828hu3r2cm + +=_foo bar baz +=_abc_def 11 ghi jkl + +xq +=_list_bar 36 3 foo|3 bar|7 foo +bar|11 foo +bar +baz +:_foo_bar yay +_message_foo_bar +ohai there! +\o/ +| +:_target psyc://foo.bar/~baz + +:_test 123 +_message_test +ohai! +| diff --git a/src/tests/packets/test-3-list b/src/tests/packets/test-3-list new file mode 100644 index 0000000..2cd79b6 --- /dev/null +++ b/src/tests/packets/test-3-list @@ -0,0 +1,34 @@ +| +=_source psyc://foo/~bar +:_target psyc://bar/~baz +=_list_foo foo|bar|baz +:_tag sch1828hu3r2cm + +?_test ignored +=_foo bar baz +=_abc_def 11 ghi jkl + +xq +=_list_bar 36 3 foo|3 bar|7 foo +bar|11 foo +b|r +baz +:_foo_bar yay +=_amount_x 10 +_message_foo_bar +ohai there! +\o/ +| +:_target psyc://foo.bar/~baz + +:_test 123 +_message_test +ohai! +| +:_target psyc://foo.bar/~baz + ++_list_foo yay +-_amount_x 2 +_notice_test +test! +| diff --git a/src/tests/packets/test-4-circuit b/src/tests/packets/test-4-circuit new file mode 100644 index 0000000..024937f --- /dev/null +++ b/src/tests/packets/test-4-circuit @@ -0,0 +1,5 @@ +| +:_list_understand_modules _state|_fragments|_context + +_request_features +| diff --git a/src/tests/packets/test-4-circuit-n b/src/tests/packets/test-4-circuit-n new file mode 100644 index 0000000..a9d3aec --- /dev/null +++ b/src/tests/packets/test-4-circuit-n @@ -0,0 +1,4 @@ +:_list_understand_modules _state|_fragments|_context + +_request_features +| diff --git a/src/tests/packets/test-5-message-private b/src/tests/packets/test-5-message-private new file mode 100644 index 0000000..6cfb1bb --- /dev/null +++ b/src/tests/packets/test-5-message-private @@ -0,0 +1,9 @@ +| +:_source psyc://nb.tgbit.net/~foo +:_target psyc://nb.tgbit.net/~bar +:_tag f00b4rb4z + +:_foo bar +_message_private +OHAI +| diff --git a/src/tests/packets/test-6-message-private-remote b/src/tests/packets/test-6-message-private-remote new file mode 100644 index 0000000..28d9641 --- /dev/null +++ b/src/tests/packets/test-6-message-private-remote @@ -0,0 +1,9 @@ +| +:_source psyc://nb.tgbit.net/~foo +:_target psyc://nb2.tgbit.net/~bar +:_tag f00b4rb4z + +:_foo bar +_message_private +OHAI +| diff --git a/src/tests/parser/Makefile b/src/tests/parser/Makefile deleted file mode 100644 index bdbf145..0000000 --- a/src/tests/parser/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -parser: - $(DIETLIB) cc -L../.. -I../../../include -DDEBUG -lpsyc testParser.c -lpsyc -o testParser - -diet: - DIETLIB=/opt/diet/bin/diet make parser - diff --git a/src/tests/parser/testParser.c b/src/tests/testParser.c similarity index 52% rename from src/tests/parser/testParser.c rename to src/tests/testParser.c index e224783..a9d7b9d 100644 --- a/src/tests/parser/testParser.c +++ b/src/tests/testParser.c @@ -10,43 +10,48 @@ int main(int argc, char** argv) int file = open(argv[1],O_RDONLY); if(file < 0) - return -1; + return -1; index = read(file,(void*)buffer,sizeof(buffer)); + write(1, ">> INPUT:\n", 10); + write(1, buffer, index); + write(1, ">> PARSE:\n", 10); PSYC_State state; PSYC_initState(&state); - unsigned int cursor=0,tmp=0; - unsigned long expectedBytes=0; + //unsigned int cursor=0,tmp=0; + //unsigned long expectedBytes=0; uint8_t modifier; int ret; PSYC_Array name, value; PSYC_nextBuffer(&state, PSYC_createArray(buffer, index)); - // try parsing that now - while(ret=PSYC_parse(&state, &name, &value, &modifier)) + // try parsing that now + while((ret=PSYC_parse(&state, &modifier, &name, &value))) { switch (ret) { case PSYC_ROUTING: case PSYC_ENTITY: - write(0,&modifier,1); - case PSYC_METHOD: - write(0,name.ptr, name.length); - write(0," = ", 3); - write(0,value.ptr, value.length); - write(0,"\n", 1); + write(1, &modifier, 1); + case PSYC_BODY: + write(1, name.ptr, name.length); + write(1, " = ", 3); + write(1, value.ptr, value.length); + write(1, "\n", 1); break; case PSYC_COMPLETE: - write(0, "Done parsing.\n", 15); + printf("Done parsing.\n"); continue; + case PSYC_INSUFFICIENT: + printf("Insufficient data.\n"); + return 0; default: printf("Error while parsing: %i\n", ret); - return; + return 1; } - } return 0;