From da875b083ce3f28e4463497873e2bc604e5767a9 Mon Sep 17 00:00:00 2001 From: Mathias Laurenz Baumann Date: Sun, 31 Jan 2010 15:27:00 +0100 Subject: [PATCH 001/378] inital commit with suggested api from the wiki --- include/psyc.h | 129 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 include/psyc.h diff --git a/include/psyc.h b/include/psyc.h new file mode 100644 index 0000000..7baf689 --- /dev/null +++ b/include/psyc.h @@ -0,0 +1,129 @@ +/** @brief parses a packet + * + * This function parses rawdata + * and uses the callbacks in PSYC_Parser + * to communicate with the caller. + * + * First the header will be parsed, + * after that the stateCallback + * (with inEntity set to false) + * will be called for each variable. + * Then, routingCallback will be called + * to find out if further parsing + * is desired. + * If it returns false, PSYC_parser returns. + * If it returns true, parsing continues + * to the body. + * After the entitystate has been parsed, + * stateCallback will be called for each + * variable, having inEntity set to true. + * Finally, bodyCallback will be called, + * containing the method, and its data. + * + * In case of an parsing error + * + * @param data constant pointer to the + * raw data that is to be processed. + * @param length the amount of bytes to parse + * @param pstate pointer to a preallocated + * instance of the struct state +*/ +void PSYC_parse(const uint8_t* data, unsigned int length, + struct PSYC_Parser* pstate); + +/** @brief FlagMod */ +enum PSYC_Modifier +{ + // variable modifers + ASSIGN=0x02, + AUGMENT=0x04, + DIMINISH=0x08, + SET=0x10, + QUERY=0x20 +} + + +struct PSYC_Parser +{ + /** @brief Callback for the states + * + * This callback will be called to inform + * the caller about the states. + * + * It will be called once for each variable. + * + * @param pstate pointer to the ParserState + * struct for identification + * @param name not null terminated c-string, + * containing the name of the variable + * @param nlength the length of the variable name + * @param value not null terminated c-string, + * containing the value of the variable + * @param vlength the length of the variable value + * @param modifers modifer of the variable (see Modifer) + * @param inEntity wether this variable is an entity + * variable(true) or a routing variable(false) */ + void (*stateCallback)(PSYC_Parser* pstate, + const uint8_t *name, const unsigned int nlength, + const uint8_t *value, const unsigned int vlength; + PSYC_Modifer modifiers, bool inEntity); + + /** @brief gets called after the routing-header was parsed + * + * @return if true, parser will continue to parse + * the content part and calls bodyCallback + * when finished, + * if false, parser will stop parsing and + * calls contentCallback */ + bool (*routingCallback)(PSYC_Parser* pstate); + + /** @brief Body callback, gets called when the body was parsed + * + * @param pstate pointer to the ParserState struct + * for identificiation + * @param method not null terminated c-string, + * containing the method name + * @param mlength the length of the methodname + * @param dlength the length of the data + * @param data not null terminated c-string, + * containing the data section + * @param content not null terminated c-string + * @param clength length of the content string */ + void (*bodyCallback)(PSYC_Parser* pstate, + const uint8_t* method, unsigned int mlength, + const uint8_t* data, unsigned int dlength + const uint8_t* content, unsigned int clength); + + /** @brief Error callback, gets called to indicate + * an error and the start of an error packet + * + * If there was an error while parsing the rawdata, + * instead of passing the packets data to the callbacks, + * an error packet will be passed back, describing the + * the error in more detail. + * + * On error, errorCallback will be called + * to report the errortype (in the method), + * after that errorStateCallback will be + * called to inform about more detailed facts + * of the error. + * + * Any previous state or body callbacks become + * invalid and have to be purged.*/ + void (*errorCallback)(PSYC_Parser* pstate, + const uint8_t *method, unsigned int mlength); + + /** @brief error state callback + * + * The parameters are the same as for stateCallback. + * The callback will be called once for each + * state variable in the error report packet + */ + void (*errorStateCallback)(PSYC_Parser* pstate, + const uint8_t *name, const unsigned int nlength, + const uint8_t *value, const unsigned int vlength; + PSYC_Modifer modifiers); + +} + + From db8bb01bd618f0c2649369340a9e9daf09305a98 Mon Sep 17 00:00:00 2001 From: Mathias Laurenz Baumann Date: Fri, 5 Feb 2010 18:39:42 +0100 Subject: [PATCH 002/378] added api without callbacks, added first impl. --- include/psyc_impl.h | 397 +++++++++++++++++++++++++++ include/psyc_parser.h | 135 +++++++++ include/{psyc.h => psyc_parser_cb.h} | 59 ++-- 3 files changed, 574 insertions(+), 17 deletions(-) create mode 100644 include/psyc_impl.h create mode 100644 include/psyc_parser.h rename include/{psyc.h => psyc_parser_cb.h} (72%) diff --git a/include/psyc_impl.h b/include/psyc_impl.h new file mode 100644 index 0000000..6ea2681 --- /dev/null +++ b/include/psyc_impl.h @@ -0,0 +1,397 @@ +#include + +/** @brief isGlyph + * + * @todo: document this function + */ +inline char isGlyph(uint8_t g) +{ + switch(g) + { + case ':': + case '-': + case '+': + case '=': + return 1; + default: + return 0; + } + +} + + +inline char isAlphaNumeric(uint8_t c) +{ + return + (( c >= 'a' && c <= 'z' )|| + ( c >= 'A' && c <= 'Z' )|| + ( c >= '0' && c <= '9' )) + ; + +} + +inline int PSYC_parseElement( + unsigned int* cursor, + const uint8_t * data, unsigned int dlength, + const uint8_t** name, unsigned int *nlength, + const uint8_t** value, unsigned int *vlength, + char inHeader); + +/** @brief parses a routerVariable + * + * This function parses one routing variable, + * advances the cursor after the variable, + * writes the variables name, value and their + * lengths in the corresponding out parameters + * and returns 0 or an errorcode. + * + * + * + * + * @param data pointer to the packet data + * @param dlength length of the data (amount of bytes) + * @param cursor pointer to the current parsing position. + * should be initialized to 0. + * @param name pointer-pointer, used to return the position + * of the name string + * @param nlength pointer to which the length of + * the name string will be written + * @param value pointer-pointer, used to retrun the position + * of the value string + * @param vlength pointer to which the length of + * the value string will be written + * + * @returns 0 on success + * 1 on insufficient data. + * This does not advance + * the cursor. + * 2 when no longer in the header, + * This advances the cursor to the + * body/entity section, but leaves + * the other out parameters invalid. + * 3 the packet is complete. + * >3 on a context error, + * <0 on a parsing error. + * This invalidates all but the cursor + * out paramater. */ +inline int PSYC_parseHeader( + unsigned int* cursor, + const uint8_t * data, unsigned int dlength, + const uint8_t** name, unsigned int *nlength, + const uint8_t** value, unsigned int *vlength) +{ + return PSYC_parseElement(cursor,data,dlength,name,nlength,value,vlength,1); +} + + + + +/** @brief parses one bodyelement + * + * This function is nearly identical to + * its brother parseClosedBody. * + * + * It assumes that we don’t know the + * real length of the packet and thus + * searches for the terminator. + */ +inline int PSYC_parseOpenBody( + unsigned int* cursor, + const uint8_t * data, unsigned int dlength, + const uint8_t** name, unsigned int *nlength, + const uint8_t** value, unsigned int *vlength) +{ + + return PSYC_parseElement(cursor,data,dlength,name,nlength,value,vlength,0); +} + + + + + + + + + +/** @brief generalized linebased parser */ +inline int PSYC_parseElement( + unsigned int* cursor, + const uint8_t * data, unsigned int dlength, + const uint8_t** name, unsigned int *nlength, + const uint8_t** value, unsigned int *vlength, + char inHeader) +{ + /* first we test if we can access the first char */ + if(dlength<*cursor) // cursor is not inside the length + return 1; // return insufficient data. + + // in case we return insufficent, we rewind to the start. + unsigned int startc=*cursor; + + /* 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(1==inHeader && !isGlyph(data[*cursor])) // is the first char not a glyph? + { + // the only other possibility now is that the packet + // is complete(empty packet) or that the method started. + if(isAlphaNumeric(data[*cursor])) + return 2; // return header finished + + if(data[*cursor] == '|') + { + if(dlength<++(*cursor)) // incremented cursor inside lenght? + { + *cursor=startc; // set to start value + return 1; // return insufficient + } + + if(data[*cursor]=='\n') + { + ++(*cursor); + return 3; // return packet finished + } + } + return -6; // report error + } + + char method=0; + /* in the body, the same applies, only that the + * method does not start with a glyph.*/ + if(0==inHeader && !isGlyph(data[*cursor])) + if(!isAlphaNumeric(data[*cursor])) + { + // the body rule is optional, which means + // that now also just |\n can follow. + if(data[*cursor] == '|') + { + if(dlength<++(*cursor)) // incremented cursor inside lenght? + { + *cursor=startc; // set to start value + return 1; // return insufficient + } + + if(data[*cursor]=='\n') + { + ++(*cursor); + return 3; // return packet finished + } + } + return -5; // report error + } + else + method=1; + + /* validate the incremented cursor */ + if(dlength<++(*cursor)) + { + *cursor=startc; + return 1; + } + + /* what follows is the name. At least one char. + * allowed is alphanumeric and _ */ + + // first char must exist. + if(!isAlphaNumeric(data[*cursor]) // is it not alphanum + && data[*cursor] != '_') // AND not '_'. must be invalid then + return -1; // return parser error. + + + *name=data+*cursor; // the name starts here. + *nlength=1; // the initial length is 1. + + + /* now checking how long the name of the variable is. */ + unsigned int i=0; + while(1) + { + if(dlength<++(*cursor)) // incremented cursor inside lenght? + { + *cursor=startc; // set to start value + return 1; // return insufficient + } + + // same as bevore + if(!isAlphaNumeric(data[*cursor]) && + data[*cursor] != '_') + break; // not valid? then stop the loop right here + + ++(*nlength); // 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(data[*cursor] == '\t' || (data[*cursor] == '\n' && method==1)) + { + /* after the \t the arg-data follows, which is + * anything but \n. arg-data can be of length 0 + * + * for the method: after the \n data follows, + * which is anything but \n|\n + * + * 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. */ + *value=data+*cursor+1; + *vlength=0; + + while(1) + { + if(dlength<++(*cursor)) // incremented cursor inside lenght? + { + *cursor=startc; // set to start value + return 1; // return insufficient + } + + if(data[*cursor] == '\n') + { + if(method==1) + { + if(dlength<++(*cursor)+1) // incremented cursor inside lenght? + { + *cursor=startc; // set to start value + return 1; // return insufficient + } + + /* packet finishes here */ + if(data[*cursor] == '|' && + data[*cursor+1] == '\n') + return 3; + + }else + break; + } + ++(*vlength); + } + + } + + + /* 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(data[*cursor] != '\n') + return -2; // return parser error. + + /* if a \n follows now, the an body is attached. + * if not, a |\n must follow */ + if(dlength<++(*cursor)) // incremented cursor inside lenght? + { + *cursor=startc; // set to start value + return 1; // return insufficient + } + + if(*cursor == '\n') + return 0; // line is complete + else if(*cursor != '|') + return -3; + + if(dlength<++(*cursor)) // incremented cursor inside lenght? + { + *cursor=startc; // set to start value + return 1; // return insufficient + } + if(*cursor != '\n') + return -4; + + + return 3; // packet is complete + + +} + +/** @brief parses one variable in two buffers + * + * This function is nearly identical to its + * brother parseHeader. The difference is, + * it uses two buffers and return parameters + * for everything. It is meant to be used + * in case parseHeader returned 2 for + * insufficient data and you don’t + * like to copy memory around to + * have all the data in one buffer. + * Using this function, you can pass two + * data buffers. The consequence is, + * that name and value can be distributed + * on two different buffers and thus need + * also two out paramaters. If only one + * will be used, length of the second + * will be 0. + * + * If your data is spread over more + * than two buffers, you need to + * copy that in one or two buffers. + * Given the unlikleyness of that + * event, we don't offer a three + * or more buffer function here. + * + */ +int PSYC_parseHeader2( + unsigned int* cursor, + const uint8_t * data1, unsigned int dlength1, + const uint8_t * data2, unsigned int dlength2, + const uint8_t** name1, unsigned int *nlength1, + const uint8_t** name2, unsigned int *nlength2, + const uint8_t** value1, unsigned int *vlength1, + const uint8_t** value2, unsigned int *vlength2); + +/** @brief parses one bodyelement + * + * This parses one body element, that is + * either an entity-variable or the method + * + * The function assumes that dlength is set + * to the exact length of the packet + * so that data[dlength-1] would be the + * ending "\n" of the packet. + * + * The parameters are nearly the same as for + * PSYC_routerVariable, only difference is + * that a returnvalue of 2 means, we encountered + * the method. + * This means that the out paramterer + * name contains the methodname and + * value the content. + * */ +int PSYC_parseClosedBody( + unsigned int* cursor, + const uint8_t * data, unsigned int dlength, + const uint8_t** name, unsigned int *nlength, + const uint8_t** value, unsigned int *vlength); + +/* @brief parses an bodyelement in two buffers + * + * This function is the brother of parseHeader2. + * It behaives the same as + * parseOpenBody and parseHeader2. */ +int PSYC_parseOpenBody2( + unsigned int* cursor, + const uint8_t * data1, unsigned int dlength1, + const uint8_t * data2, unsigned int dlength2, + const uint8_t** name1, unsigned int *nlength1, + const uint8_t** name2, unsigned int *nlength2, + const uint8_t** value1, unsigned int *vlength1, + const uint8_t** value2, unsigned int *vlength2); + + + + diff --git a/include/psyc_parser.h b/include/psyc_parser.h new file mode 100644 index 0000000..6d5f326 --- /dev/null +++ b/include/psyc_parser.h @@ -0,0 +1,135 @@ +/** @brief parses a routerVariable + * + * This function parses one routing variable, + * advances the cursor after the variable, + * writes the variables name, value and their + * lengths in the corresponding out parameters + * and returns 0 or an errorcode. + * + * + * + * + * @param data pointer to the packet data + * @param dlength length of the data (amount of bytes) + * @param cursor pointer to the current parsing position + * @param name pointer-pointer, used to return the position + * of the name string + * @param nlength pointer to which the length of + * the name string will be written + * @param value pointer-pointer, used to retrun the position + * of the value string + * @param vlength pointer to which the length of + * the value string will be written + * + * @returns 0 on success + * 1 on insufficient data. + * This does not advance + * the cursor. + * 2 when no longer in the header, + * This advances the cursor to the + * body/entity section, but leaves + * the other out parameters invalid. + * >2 on a context error, + * <0 on a parsing error. + * This invalidates all but the cursor + * out paramater. */ +int PSYC_parseHeader( + unsigned int* cursor, + const uint8_t * data, unsigned int dlength, + const uint8_t** name, unsigned int *nlength, + const uint8_t** value, unsigned int *vlength); + +/** @brief parses one variable in two buffers + * + * This function is nearly identical to its + * brother parseHeader. The difference is, + * it uses two buffers and return parameters + * for everything. It is meant to be used + * in case parseHeader returned 2 for + * insufficient data and you don’t + * like to copy memory around to + * have all the data in one buffer. + * Using this function, you can pass two + * data buffers. The consequence is, + * that name and value can be distributed + * on two different buffers and thus need + * also two out paramaters. If only one + * will be used, length of the second + * will be 0. + * + * If your data is spread over more + * than two buffers, you need to + * copy that in one or two buffers. + * Given the unlikleyness of that + * event, we don't offer a three + * or more buffer function here. + * + */ +int PSYC_parseHeader2( + unsigned int* cursor, + const uint8_t * data1, unsigned int dlength1, + const uint8_t * data2, unsigned int dlength2, + const uint8_t** name1, unsigned int *nlength1, + const uint8_t** name2, unsigned int *nlength2, + const uint8_t** value1, unsigned int *vlength1, + const uint8_t** value2, unsigned int *vlength2); + +/** @brief parses one bodyelement + * + * This parses one body element, that is + * either an entity-variable or the method + * + * The function assumes that dlength is set + * to the exact length of the packet + * so that data[dlength-1] would be the + * ending "|" of the packet. + * + * The parameters are nearly the same as for + * PSYC_routerVariable, only difference is + * that a returnvalue of 2 means, we encountered + * the method. + * This means that the out paramterer + * name contains the methodname and + * value the content. + * */ +int PSYC_parseClosedBody( + unsigned int* cursor, + const uint8_t * data, unsigned int dlength, + const uint8_t** name, unsigned int *nlength, + const uint8_t** value, unsigned int *vlength); + +/** @brief parses one bodyelement + * + * This function is nearly identical to + * its brother parseClosedBody. * + * + * It assumes that we don’t know the + * real length of the packet and thus + * searches for the terminator. + */ +int PSYC_parseOpenBody( + unsigned int* cursor, + const uint8_t * data, unsigned int dlength, + const uint8_t** name, unsigned int *nlength, + const uint8_t** value, unsigned int *vlength); + + + +/* @brief parses an bodyelement in two buffers + * + * This function is the borther of parseHeader2. + * It behaives the same as + * parseOpenBody and parseHeader2. */ +int PSYC_parseOpenBody2( + unsigned int* cursor, + const uint8_t * data1, unsigned int dlength1, + const uint8_t * data2, unsigned int dlength2, + const uint8_t** name1, unsigned int *nlength1, + const uint8_t** name2, unsigned int *nlength2, + const uint8_t** value1, unsigned int *vlength1, + const uint8_t** value2, unsigned int *vlength2); + + + + +#include diff --git a/include/psyc.h b/include/psyc_parser_cb.h similarity index 72% rename from include/psyc.h rename to include/psyc_parser_cb.h index 7baf689..25b212e 100644 --- a/include/psyc.h +++ b/include/psyc_parser_cb.h @@ -1,3 +1,15 @@ +#include + +struct PSYC_Parser; + +/** @brief initialize a pstate struct + * + * @param pstate pointer to an allocated + * PSYC_Parser struct. + */ +void PSYC_initState(struct PSYC_Parser* pstate); + + /** @brief parses a packet * * This function parses rawdata @@ -26,7 +38,9 @@ * raw data that is to be processed. * @param length the amount of bytes to parse * @param pstate pointer to a preallocated - * instance of the struct state + * and initialized (PSYC_initState) + * instance of the struct state + * */ void PSYC_parse(const uint8_t* data, unsigned int length, struct PSYC_Parser* pstate); @@ -40,8 +54,7 @@ enum PSYC_Modifier DIMINISH=0x08, SET=0x10, QUERY=0x20 -} - +}; struct PSYC_Parser { @@ -63,19 +76,19 @@ struct PSYC_Parser * @param modifers modifer of the variable (see Modifer) * @param inEntity wether this variable is an entity * variable(true) or a routing variable(false) */ - void (*stateCallback)(PSYC_Parser* pstate, + void (*stateCallback)(struct PSYC_Parser* pstate, const uint8_t *name, const unsigned int nlength, - const uint8_t *value, const unsigned int vlength; - PSYC_Modifer modifiers, bool inEntity); + const uint8_t *value, const unsigned int vlength, + enum PSYC_Modifier modifiers, char inEntity); /** @brief gets called after the routing-header was parsed * - * @return if true, parser will continue to parse + * @return if 0, parser will continue to parse * the content part and calls bodyCallback * when finished, - * if false, parser will stop parsing and + * if not 0, parser will stop parsing and * calls contentCallback */ - bool (*routingCallback)(PSYC_Parser* pstate); + char (*routingCallback)(struct PSYC_Parser* pstate); /** @brief Body callback, gets called when the body was parsed * @@ -89,9 +102,9 @@ struct PSYC_Parser * containing the data section * @param content not null terminated c-string * @param clength length of the content string */ - void (*bodyCallback)(PSYC_Parser* pstate, + void (*bodyCallback)(struct PSYC_Parser* pstate, const uint8_t* method, unsigned int mlength, - const uint8_t* data, unsigned int dlength + const uint8_t* data, unsigned int dlength, const uint8_t* content, unsigned int clength); /** @brief Error callback, gets called to indicate @@ -110,7 +123,7 @@ struct PSYC_Parser * * Any previous state or body callbacks become * invalid and have to be purged.*/ - void (*errorCallback)(PSYC_Parser* pstate, + void (*errorCallback)(struct PSYC_Parser* pstate, const uint8_t *method, unsigned int mlength); /** @brief error state callback @@ -119,11 +132,23 @@ struct PSYC_Parser * The callback will be called once for each * state variable in the error report packet */ - void (*errorStateCallback)(PSYC_Parser* pstate, + void (*errorStateCallback)(struct PSYC_Parser* pstate, const uint8_t *name, const unsigned int nlength, - const uint8_t *value, const unsigned int vlength; - PSYC_Modifer modifiers); - -} + const uint8_t *value, const unsigned int vlength, + enum PSYC_Modifier modifiers); + + + /******************************************* + * The following variables and datatypes * + * are being used to remember the * + * internal state. You should not * + * touch them. * + *******************************************/ + uint8_t glyph; + unsigned int contpos; // position inside the content + unsigned int mstart,mlength, // position and length of the method + dstart,dlength; // + +}; From a2e0356fbadd7879b84acd9746c838cb378d4cdb Mon Sep 17 00:00:00 2001 From: Mathias Laurenz Baumann Date: Sat, 20 Feb 2010 17:40:09 +0100 Subject: [PATCH 003/378] parser succeeds the first tests --- src/parser.c | 418 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/parser.h | 138 +++++++++++++++++ 2 files changed, 556 insertions(+) create mode 100644 src/parser.c create mode 100644 src/parser.h diff --git a/src/parser.c b/src/parser.c new file mode 100644 index 0000000..3114a58 --- /dev/null +++ b/src/parser.c @@ -0,0 +1,418 @@ +#include + +#ifdef DEBUG +#include +#endif + +/** @brief isGlyph + * + * @todo: document this function + */ +inline char isGlyph(uint8_t g) +{ + switch(g) + { + case ':': + case '-': + case '+': + case '=': + return 1; + default: + return 0; + } + +} + + +inline char isAlphaNumeric(uint8_t c) +{ + return + (( c >= 'a' && c <= 'z' )|| + ( c >= 'A' && c <= 'Z' )|| + ( c >= '0' && c <= '9' )) + ; + +} + +inline int PSYC_parseElement( + unsigned int* cursor, + const uint8_t * data, unsigned int dlength, + const uint8_t** name, unsigned int *nlength, + const uint8_t** value, unsigned int *vlength, + char inHeader); + +/** @brief parses a routerVariable + * + * This function parses one routing variable, + * advances the cursor after the variable, + * writes the variables name, value and their + * lengths in the corresponding out parameters + * and returns 0 or an errorcode. + * + * + * + * + * @param data pointer to the packet data + * @param dlength length of the data (amount of bytes) + * @param cursor pointer to the current parsing position. + * should be initialized to 0. + * @param name pointer-pointer, used to return the position + * of the name string + * @param nlength pointer to which the length of + * the name string will be written + * @param value pointer-pointer, used to retrun the position + * of the value string + * @param vlength pointer to which the length of + * the value string will be written + * + * @returns 0 on success + * 1 on insufficient data. + * This does not advance + * the cursor. + * 2 header is now finished. + * no more header variables follow + * 3 the packet is complete. + * >3 on a context error, + * <0 on a parsing error. + * This invalidates all but the cursor + * out paramater. */ +inline int PSYC_parseHeader( + unsigned int* cursor, + const uint8_t * data, unsigned int dlength, + const uint8_t** name, unsigned int *nlength, + const uint8_t** value, unsigned int *vlength) +{ + return PSYC_parseElement(cursor,data,dlength,name,nlength,value,vlength,1); +} + + + + +/** @brief parses one bodyelement + * + * This function is nearly identical to + * its brother parseClosedBody. * + * + * It assumes that we don’t know the + * real length of the packet and thus + * searches for the terminator. + */ +inline int PSYC_parseOpenBody( + unsigned int* cursor, + const uint8_t * data, unsigned int dlength, + const uint8_t** name, unsigned int *nlength, + const uint8_t** value, unsigned int *vlength) +{ + + return PSYC_parseElement(cursor,data,dlength,name,nlength,value,vlength,0); +} + + + + + + + + + +/** @brief generalized linebased parser */ +inline int PSYC_parseElement( + unsigned int* cursor, + const uint8_t * data, unsigned int dlength, + const uint8_t** name, unsigned int *nlength, + const uint8_t** value, unsigned int *vlength, + char inHeader) +{ + /* first we test if we can access the first char */ + if(dlength<=*cursor) // cursor is not inside the length + return 1; // return insufficient data. + + // in case we return insufficent, we rewind to the start. + unsigned int startc=*cursor; + + /* 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(1==inHeader) + { + if(!isGlyph(data[*cursor])) // is the first char not a glyph? + { + // the only other possibility now is that the packet + // is complete(empty packet) or that the method started. + if(isAlphaNumeric(data[*cursor])) + return 2; // return header finished + + if(data[*cursor] == '|') + { + if(dlength<=++(*cursor)) // incremented cursor inside lenght? + { + *cursor=startc; // set to start value + return 1; // return insufficient + } + + if(data[*cursor]=='\n') + { + ++(*cursor); + return 3; // return packet finished + } + } + return -6; // report error + }else // it is a glyph, so a variable name starts here + { + *name = data+*cursor; + *nlength = 1; + } + } + char method=0; + /* in the body, the same applies, only that the + * method does not start with a glyph.*/ + if(0==inHeader && !isGlyph(data[*cursor])) + { + if(!isAlphaNumeric(data[*cursor]) && data[*cursor] != '_') + { + // the body rule is optional, which means + // that now also just |\n can follow. + if(data[*cursor] == '|') + { + if(dlength<=++(*cursor)) // incremented cursor inside lenght? + { + *cursor=startc; // set to start value + return 1; // return insufficient + } + + if(data[*cursor]=='\n') + { + ++(*cursor); + return 3; // return packet finished + } + } + return -5; // report error + } + else + method=1; + } + else + { + *name = data+*cursor; + *nlength=1; + } + + /* validate the incremented cursor */ + if(dlength <= ++(*cursor)) + { + *cursor=startc; + return 1; + } + + /* what follows is the name. At least one char. + * allowed is alphanumeric and _ */ + + // first char must exist. + if(!isAlphaNumeric(data[*cursor]) // is it not alphanum + && data[*cursor] != '_') // AND not '_'. must be invalid then + return -1; // return parser error. + + if(1 == method) // for the method.. + { + *name=data+*cursor; // the name starts here. + *nlength=1; // the initial length is 1. + }else + *nlength+=1; + + /* now checking how long the name of the variable is. */ + unsigned int i=0; + while(1) + { + if(dlength<= ++(*cursor)) // incremented cursor inside lenght? + { + *cursor=startc; // set to start value + return 1; // return insufficient + } + + // same as bevore + if(!isAlphaNumeric(data[*cursor]) && + data[*cursor] != '_') + break; // not valid? then stop the loop right here + + ++(*nlength); // 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(data[*cursor] == '\t' || (data[*cursor] == '\n' && method==1)) + { + /* after the \t the arg-data follows, which is + * anything but \n. arg-data can be of length 0 + * + * for the method: after the \n data follows, + * which is anything but \n|\n + * + * 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. */ + *value=data+*cursor+1; + *vlength=0; + + while(1) + { + if(dlength<=++(*cursor)) // incremented cursor inside lenght? + { + *cursor=startc; // set to start value + return 1; // return insufficient + } + + if(1 != method && data[*cursor] == '\n') + break; + + if(1 == method && data[*cursor] == '|') + { + if(dlength<++(*cursor)) // incremented cursor inside lenght? + { + *cursor=startc; // set to start value + return 1; // return insufficient + } + + /* packet finishes here */ + if(data[*cursor] == '\n') + { + *cursor+=1; + return 3; + } + } + ++(*vlength); + } + + } + + + /* 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(data[*cursor] != '\n') + return -2; // return parser error. + + /* if a \n follows now, the an body is attached. + * if not, a |\n must follow */ + if(dlength<=++(*cursor)) // incremented cursor inside lenght? + { + *cursor=startc; // set to start value + return 1; // return insufficient + } + + if(1 == inHeader && data[*cursor] == '\n') + { + *cursor+=1; + return 2; // line is complete, but body starts now. + } + + if(data[*cursor] != '|') // no pipe, then only line complete, not the packet. + return 0; + + if(dlength<=++(*cursor)) // incremented cursor inside lenght? + { + *cursor=startc; // set to start value + return 1; // return insufficient + } + if(data[*cursor] != '\n') + return -4; + + *cursor+=1; + return 3; // packet is complete + + +} + +/** @brief parses one variable in two buffers + * + * This function is nearly identical to its + * brother parseHeader. The difference is, + * it uses two buffers and return parameters + * for everything. It is meant to be used + * in case parseHeader returned 2 for + * insufficient data and you don’t + * like to copy memory around to + * have all the data in one buffer. + * Using this function, you can pass two + * data buffers. The consequence is, + * that name and value can be distributed + * on two different buffers and thus need + * also two out paramaters. If only one + * will be used, length of the second + * will be 0. + * + * If your data is spread over more + * than two buffers, you need to + * copy that in one or two buffers. + * Given the unlikleyness of that + * event, we don't offer a three + * or more buffer function here. + * + */ +int PSYC_parseHeader2( + unsigned int* cursor, + const uint8_t * data1, unsigned int dlength1, + const uint8_t * data2, unsigned int dlength2, + const uint8_t** name1, unsigned int *nlength1, + const uint8_t** name2, unsigned int *nlength2, + const uint8_t** value1, unsigned int *vlength1, + const uint8_t** value2, unsigned int *vlength2); + +/** @brief parses one bodyelement + * + * This parses one body element, that is + * either an entity-variable or the method + * + * The function assumes that dlength is set + * to the exact length of the packet + * so that data[dlength-1] would be the + * ending "\n" of the packet. + * + * The parameters are nearly the same as for + * PSYC_routerVariable, only difference is + * that a returnvalue of 2 means, we encountered + * the method. + * This means that the out paramterer + * name contains the methodname and + * value the content. + * */ +int PSYC_parseClosedBody( + unsigned int* cursor, + const uint8_t * data, unsigned int dlength, + const uint8_t** name, unsigned int *nlength, + const uint8_t** value, unsigned int *vlength); + +/* @brief parses an bodyelement in two buffers + * + * This function is the brother of parseHeader2. + * It behaives the same as + * parseOpenBody and parseHeader2. */ +int PSYC_parseOpenBody2( + unsigned int* cursor, + const uint8_t * data1, unsigned int dlength1, + const uint8_t * data2, unsigned int dlength2, + const uint8_t** name1, unsigned int *nlength1, + const uint8_t** name2, unsigned int *nlength2, + const uint8_t** value1, unsigned int *vlength1, + const uint8_t** value2, unsigned int *vlength2); + + + + diff --git a/src/parser.h b/src/parser.h new file mode 100644 index 0000000..961de00 --- /dev/null +++ b/src/parser.h @@ -0,0 +1,138 @@ +#include + +/** @brief parses a routerVariable + * + * This function parses one routing variable, + * advances the cursor after the variable, + * writes the variables name, value and their + * lengths in the corresponding out parameters + * and returns 0 or an errorcode. + * + * + * + * + * @param data pointer to the packet data + * @param dlength length of the data (amount of bytes) + * @param cursor pointer to the current parsing position + * @param name pointer-pointer, used to return the position + * of the name string + * @param nlength pointer to which the length of + * the name string will be written + * @param value pointer-pointer, used to retrun the position + * of the value string + * @param vlength pointer to which the length of + * the value string will be written + * + * @returns 0 on success + * 1 on insufficient data. + * This does not advance + * the cursor. + * 2 when no longer in the header, + * This advances the cursor to the + * body/entity section, but leaves + * the other out parameters invalid. + * 3 the packet is complete. + * >2 on a context error, + * <0 on a parsing error. + * This invalidates all but the cursor + * out paramater. */ +int PSYC_parseHeader( + unsigned int* cursor, + const uint8_t * data, unsigned int dlength, + const uint8_t** name, unsigned int *nlength, + const uint8_t** value, unsigned int *vlength); + +/** @brief parses one variable in two buffers + * + * This function is nearly identical to its + * brother parseHeader. The difference is, + * it uses two buffers and return parameters + * for everything. It is meant to be used + * in case parseHeader returned 2 for + * insufficient data and you don’t + * like to copy memory around to + * have all the data in one buffer. + * Using this function, you can pass two + * data buffers. The consequence is, + * that name and value can be distributed + * on two different buffers and thus need + * also two out paramaters. If only one + * will be used, length of the second + * will be 0. + * + * If your data is spread over more + * than two buffers, you need to + * copy that in one or two buffers. + * Given the unlikleyness of that + * event, we don't offer a three + * or more buffer function here. + * + */ +int PSYC_parseHeader2( + unsigned int* cursor, + const uint8_t * data1, unsigned int dlength1, + const uint8_t * data2, unsigned int dlength2, + const uint8_t** name1, unsigned int *nlength1, + const uint8_t** name2, unsigned int *nlength2, + const uint8_t** value1, unsigned int *vlength1, + const uint8_t** value2, unsigned int *vlength2); + +/** @brief parses one bodyelement + * + * This parses one body element, that is + * either an entity-variable or the method + * + * The function assumes that dlength is set + * to the exact length of the packet + * so that data[dlength-1] would be the + * ending "|" of the packet. + * + * The parameters are nearly the same as for + * PSYC_routerVariable, only difference is + * that a returnvalue of 2 means, we encountered + * the method. + * This means that the out paramterer + * name contains the methodname and + * value the content. + * */ +int PSYC_parseClosedBody( + unsigned int* cursor, + const uint8_t * data, unsigned int dlength, + const uint8_t** name, unsigned int *nlength, + const uint8_t** value, unsigned int *vlength); + +/** @brief parses one bodyelement + * + * This function is nearly identical to + * its brother parseClosedBody. * + * + * It assumes that we don’t know the + * real length of the packet and thus + * searches for the terminator. + */ +int PSYC_parseOpenBody( + unsigned int* cursor, + const uint8_t * data, unsigned int dlength, + const uint8_t** name, unsigned int *nlength, + const uint8_t** value, unsigned int *vlength); + + + +/* @brief parses an bodyelement in two buffers + * + * This function is the borther of parseHeader2. + * It behaives the same as + * parseOpenBody and parseHeader2. */ +int PSYC_parseOpenBody2( + unsigned int* cursor, + const uint8_t * data1, unsigned int dlength1, + const uint8_t * data2, unsigned int dlength2, + const uint8_t** name1, unsigned int *nlength1, + const uint8_t** name2, unsigned int *nlength2, + const uint8_t** value1, unsigned int *vlength1, + const uint8_t** value2, unsigned int *vlength2); + + + + +//#include From 0b012a091ff5db2bc006d0fb38c742602a896d26 Mon Sep 17 00:00:00 2001 From: Mathias Laurenz Baumann Date: Sat, 20 Feb 2010 17:41:16 +0100 Subject: [PATCH 004/378] added tests & test code --- include/psyc_impl.h | 397 ------------------------------ include/psyc_parser.h | 135 ---------- {include => src}/psyc_parser_cb.h | 0 src/tests/CMakeLists.txt | 18 ++ src/tests/enter_leave_context.txt | 12 + src/tests/fake_dns.txt | 6 + src/tests/invalid_dns.txt | 6 + src/tests/testParser.c | 66 +++++ 8 files changed, 108 insertions(+), 532 deletions(-) delete mode 100644 include/psyc_impl.h delete mode 100644 include/psyc_parser.h rename {include => src}/psyc_parser_cb.h (100%) create mode 100644 src/tests/CMakeLists.txt create mode 100644 src/tests/enter_leave_context.txt create mode 100644 src/tests/fake_dns.txt create mode 100644 src/tests/invalid_dns.txt create mode 100644 src/tests/testParser.c diff --git a/include/psyc_impl.h b/include/psyc_impl.h deleted file mode 100644 index 6ea2681..0000000 --- a/include/psyc_impl.h +++ /dev/null @@ -1,397 +0,0 @@ -#include - -/** @brief isGlyph - * - * @todo: document this function - */ -inline char isGlyph(uint8_t g) -{ - switch(g) - { - case ':': - case '-': - case '+': - case '=': - return 1; - default: - return 0; - } - -} - - -inline char isAlphaNumeric(uint8_t c) -{ - return - (( c >= 'a' && c <= 'z' )|| - ( c >= 'A' && c <= 'Z' )|| - ( c >= '0' && c <= '9' )) - ; - -} - -inline int PSYC_parseElement( - unsigned int* cursor, - const uint8_t * data, unsigned int dlength, - const uint8_t** name, unsigned int *nlength, - const uint8_t** value, unsigned int *vlength, - char inHeader); - -/** @brief parses a routerVariable - * - * This function parses one routing variable, - * advances the cursor after the variable, - * writes the variables name, value and their - * lengths in the corresponding out parameters - * and returns 0 or an errorcode. - * - * - * - * - * @param data pointer to the packet data - * @param dlength length of the data (amount of bytes) - * @param cursor pointer to the current parsing position. - * should be initialized to 0. - * @param name pointer-pointer, used to return the position - * of the name string - * @param nlength pointer to which the length of - * the name string will be written - * @param value pointer-pointer, used to retrun the position - * of the value string - * @param vlength pointer to which the length of - * the value string will be written - * - * @returns 0 on success - * 1 on insufficient data. - * This does not advance - * the cursor. - * 2 when no longer in the header, - * This advances the cursor to the - * body/entity section, but leaves - * the other out parameters invalid. - * 3 the packet is complete. - * >3 on a context error, - * <0 on a parsing error. - * This invalidates all but the cursor - * out paramater. */ -inline int PSYC_parseHeader( - unsigned int* cursor, - const uint8_t * data, unsigned int dlength, - const uint8_t** name, unsigned int *nlength, - const uint8_t** value, unsigned int *vlength) -{ - return PSYC_parseElement(cursor,data,dlength,name,nlength,value,vlength,1); -} - - - - -/** @brief parses one bodyelement - * - * This function is nearly identical to - * its brother parseClosedBody. * - * - * It assumes that we don’t know the - * real length of the packet and thus - * searches for the terminator. - */ -inline int PSYC_parseOpenBody( - unsigned int* cursor, - const uint8_t * data, unsigned int dlength, - const uint8_t** name, unsigned int *nlength, - const uint8_t** value, unsigned int *vlength) -{ - - return PSYC_parseElement(cursor,data,dlength,name,nlength,value,vlength,0); -} - - - - - - - - - -/** @brief generalized linebased parser */ -inline int PSYC_parseElement( - unsigned int* cursor, - const uint8_t * data, unsigned int dlength, - const uint8_t** name, unsigned int *nlength, - const uint8_t** value, unsigned int *vlength, - char inHeader) -{ - /* first we test if we can access the first char */ - if(dlength<*cursor) // cursor is not inside the length - return 1; // return insufficient data. - - // in case we return insufficent, we rewind to the start. - unsigned int startc=*cursor; - - /* 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(1==inHeader && !isGlyph(data[*cursor])) // is the first char not a glyph? - { - // the only other possibility now is that the packet - // is complete(empty packet) or that the method started. - if(isAlphaNumeric(data[*cursor])) - return 2; // return header finished - - if(data[*cursor] == '|') - { - if(dlength<++(*cursor)) // incremented cursor inside lenght? - { - *cursor=startc; // set to start value - return 1; // return insufficient - } - - if(data[*cursor]=='\n') - { - ++(*cursor); - return 3; // return packet finished - } - } - return -6; // report error - } - - char method=0; - /* in the body, the same applies, only that the - * method does not start with a glyph.*/ - if(0==inHeader && !isGlyph(data[*cursor])) - if(!isAlphaNumeric(data[*cursor])) - { - // the body rule is optional, which means - // that now also just |\n can follow. - if(data[*cursor] == '|') - { - if(dlength<++(*cursor)) // incremented cursor inside lenght? - { - *cursor=startc; // set to start value - return 1; // return insufficient - } - - if(data[*cursor]=='\n') - { - ++(*cursor); - return 3; // return packet finished - } - } - return -5; // report error - } - else - method=1; - - /* validate the incremented cursor */ - if(dlength<++(*cursor)) - { - *cursor=startc; - return 1; - } - - /* what follows is the name. At least one char. - * allowed is alphanumeric and _ */ - - // first char must exist. - if(!isAlphaNumeric(data[*cursor]) // is it not alphanum - && data[*cursor] != '_') // AND not '_'. must be invalid then - return -1; // return parser error. - - - *name=data+*cursor; // the name starts here. - *nlength=1; // the initial length is 1. - - - /* now checking how long the name of the variable is. */ - unsigned int i=0; - while(1) - { - if(dlength<++(*cursor)) // incremented cursor inside lenght? - { - *cursor=startc; // set to start value - return 1; // return insufficient - } - - // same as bevore - if(!isAlphaNumeric(data[*cursor]) && - data[*cursor] != '_') - break; // not valid? then stop the loop right here - - ++(*nlength); // 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(data[*cursor] == '\t' || (data[*cursor] == '\n' && method==1)) - { - /* after the \t the arg-data follows, which is - * anything but \n. arg-data can be of length 0 - * - * for the method: after the \n data follows, - * which is anything but \n|\n - * - * 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. */ - *value=data+*cursor+1; - *vlength=0; - - while(1) - { - if(dlength<++(*cursor)) // incremented cursor inside lenght? - { - *cursor=startc; // set to start value - return 1; // return insufficient - } - - if(data[*cursor] == '\n') - { - if(method==1) - { - if(dlength<++(*cursor)+1) // incremented cursor inside lenght? - { - *cursor=startc; // set to start value - return 1; // return insufficient - } - - /* packet finishes here */ - if(data[*cursor] == '|' && - data[*cursor+1] == '\n') - return 3; - - }else - break; - } - ++(*vlength); - } - - } - - - /* 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(data[*cursor] != '\n') - return -2; // return parser error. - - /* if a \n follows now, the an body is attached. - * if not, a |\n must follow */ - if(dlength<++(*cursor)) // incremented cursor inside lenght? - { - *cursor=startc; // set to start value - return 1; // return insufficient - } - - if(*cursor == '\n') - return 0; // line is complete - else if(*cursor != '|') - return -3; - - if(dlength<++(*cursor)) // incremented cursor inside lenght? - { - *cursor=startc; // set to start value - return 1; // return insufficient - } - if(*cursor != '\n') - return -4; - - - return 3; // packet is complete - - -} - -/** @brief parses one variable in two buffers - * - * This function is nearly identical to its - * brother parseHeader. The difference is, - * it uses two buffers and return parameters - * for everything. It is meant to be used - * in case parseHeader returned 2 for - * insufficient data and you don’t - * like to copy memory around to - * have all the data in one buffer. - * Using this function, you can pass two - * data buffers. The consequence is, - * that name and value can be distributed - * on two different buffers and thus need - * also two out paramaters. If only one - * will be used, length of the second - * will be 0. - * - * If your data is spread over more - * than two buffers, you need to - * copy that in one or two buffers. - * Given the unlikleyness of that - * event, we don't offer a three - * or more buffer function here. - * - */ -int PSYC_parseHeader2( - unsigned int* cursor, - const uint8_t * data1, unsigned int dlength1, - const uint8_t * data2, unsigned int dlength2, - const uint8_t** name1, unsigned int *nlength1, - const uint8_t** name2, unsigned int *nlength2, - const uint8_t** value1, unsigned int *vlength1, - const uint8_t** value2, unsigned int *vlength2); - -/** @brief parses one bodyelement - * - * This parses one body element, that is - * either an entity-variable or the method - * - * The function assumes that dlength is set - * to the exact length of the packet - * so that data[dlength-1] would be the - * ending "\n" of the packet. - * - * The parameters are nearly the same as for - * PSYC_routerVariable, only difference is - * that a returnvalue of 2 means, we encountered - * the method. - * This means that the out paramterer - * name contains the methodname and - * value the content. - * */ -int PSYC_parseClosedBody( - unsigned int* cursor, - const uint8_t * data, unsigned int dlength, - const uint8_t** name, unsigned int *nlength, - const uint8_t** value, unsigned int *vlength); - -/* @brief parses an bodyelement in two buffers - * - * This function is the brother of parseHeader2. - * It behaives the same as - * parseOpenBody and parseHeader2. */ -int PSYC_parseOpenBody2( - unsigned int* cursor, - const uint8_t * data1, unsigned int dlength1, - const uint8_t * data2, unsigned int dlength2, - const uint8_t** name1, unsigned int *nlength1, - const uint8_t** name2, unsigned int *nlength2, - const uint8_t** value1, unsigned int *vlength1, - const uint8_t** value2, unsigned int *vlength2); - - - - diff --git a/include/psyc_parser.h b/include/psyc_parser.h deleted file mode 100644 index 6d5f326..0000000 --- a/include/psyc_parser.h +++ /dev/null @@ -1,135 +0,0 @@ -/** @brief parses a routerVariable - * - * This function parses one routing variable, - * advances the cursor after the variable, - * writes the variables name, value and their - * lengths in the corresponding out parameters - * and returns 0 or an errorcode. - * - * - * - * - * @param data pointer to the packet data - * @param dlength length of the data (amount of bytes) - * @param cursor pointer to the current parsing position - * @param name pointer-pointer, used to return the position - * of the name string - * @param nlength pointer to which the length of - * the name string will be written - * @param value pointer-pointer, used to retrun the position - * of the value string - * @param vlength pointer to which the length of - * the value string will be written - * - * @returns 0 on success - * 1 on insufficient data. - * This does not advance - * the cursor. - * 2 when no longer in the header, - * This advances the cursor to the - * body/entity section, but leaves - * the other out parameters invalid. - * >2 on a context error, - * <0 on a parsing error. - * This invalidates all but the cursor - * out paramater. */ -int PSYC_parseHeader( - unsigned int* cursor, - const uint8_t * data, unsigned int dlength, - const uint8_t** name, unsigned int *nlength, - const uint8_t** value, unsigned int *vlength); - -/** @brief parses one variable in two buffers - * - * This function is nearly identical to its - * brother parseHeader. The difference is, - * it uses two buffers and return parameters - * for everything. It is meant to be used - * in case parseHeader returned 2 for - * insufficient data and you don’t - * like to copy memory around to - * have all the data in one buffer. - * Using this function, you can pass two - * data buffers. The consequence is, - * that name and value can be distributed - * on two different buffers and thus need - * also two out paramaters. If only one - * will be used, length of the second - * will be 0. - * - * If your data is spread over more - * than two buffers, you need to - * copy that in one or two buffers. - * Given the unlikleyness of that - * event, we don't offer a three - * or more buffer function here. - * - */ -int PSYC_parseHeader2( - unsigned int* cursor, - const uint8_t * data1, unsigned int dlength1, - const uint8_t * data2, unsigned int dlength2, - const uint8_t** name1, unsigned int *nlength1, - const uint8_t** name2, unsigned int *nlength2, - const uint8_t** value1, unsigned int *vlength1, - const uint8_t** value2, unsigned int *vlength2); - -/** @brief parses one bodyelement - * - * This parses one body element, that is - * either an entity-variable or the method - * - * The function assumes that dlength is set - * to the exact length of the packet - * so that data[dlength-1] would be the - * ending "|" of the packet. - * - * The parameters are nearly the same as for - * PSYC_routerVariable, only difference is - * that a returnvalue of 2 means, we encountered - * the method. - * This means that the out paramterer - * name contains the methodname and - * value the content. - * */ -int PSYC_parseClosedBody( - unsigned int* cursor, - const uint8_t * data, unsigned int dlength, - const uint8_t** name, unsigned int *nlength, - const uint8_t** value, unsigned int *vlength); - -/** @brief parses one bodyelement - * - * This function is nearly identical to - * its brother parseClosedBody. * - * - * It assumes that we don’t know the - * real length of the packet and thus - * searches for the terminator. - */ -int PSYC_parseOpenBody( - unsigned int* cursor, - const uint8_t * data, unsigned int dlength, - const uint8_t** name, unsigned int *nlength, - const uint8_t** value, unsigned int *vlength); - - - -/* @brief parses an bodyelement in two buffers - * - * This function is the borther of parseHeader2. - * It behaives the same as - * parseOpenBody and parseHeader2. */ -int PSYC_parseOpenBody2( - unsigned int* cursor, - const uint8_t * data1, unsigned int dlength1, - const uint8_t * data2, unsigned int dlength2, - const uint8_t** name1, unsigned int *nlength1, - const uint8_t** name2, unsigned int *nlength2, - const uint8_t** value1, unsigned int *vlength1, - const uint8_t** value2, unsigned int *vlength2); - - - - -#include diff --git a/include/psyc_parser_cb.h b/src/psyc_parser_cb.h similarity index 100% rename from include/psyc_parser_cb.h rename to src/psyc_parser_cb.h diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt new file mode 100644 index 0000000..ecffeda --- /dev/null +++ b/src/tests/CMakeLists.txt @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 2.6) + + +FILE(GLOB SRC + parser.c + init.cpp + MainWindow.* + interface.cpp + Window.* + ConnectWindow.h + ) + +if(GTKMM_FOUND) + include_directories(${GTKMM_INCLUDE_DIRS}) + add_executable(nprog ${NPROG_CLIENT_SRC}) + target_link_libraries(nprog ${GTKMM_LIBRARIES} -pthread -lgthread-2.0 -lrt -lglib-2.0 ) +endif() + diff --git a/src/tests/enter_leave_context.txt b/src/tests/enter_leave_context.txt new file mode 100644 index 0000000..a323158 --- /dev/null +++ b/src/tests/enter_leave_context.txt @@ -0,0 +1,12 @@ +| +:_target psyc://p5B084547.dip.t-dialin.net/@test +:_source something + +_request_context_enter +| +:_target psyc://p5B084547.dip.t-dialin.net/@test + +:_more vars +:_entity variablevalue +_notice_context_leave +| diff --git a/src/tests/fake_dns.txt b/src/tests/fake_dns.txt new file mode 100644 index 0000000..0158dff --- /dev/null +++ b/src/tests/fake_dns.txt @@ -0,0 +1,6 @@ +| +:_source psyc://heise.de/~user + +_request_some_things +| + diff --git a/src/tests/invalid_dns.txt b/src/tests/invalid_dns.txt new file mode 100644 index 0000000..689e8d7 --- /dev/null +++ b/src/tests/invalid_dns.txt @@ -0,0 +1,6 @@ +| +:_source psyc://nonexisting.dns.tld/~user + +_request_some_things +| + diff --git a/src/tests/testParser.c b/src/tests/testParser.c new file mode 100644 index 0000000..8594bd6 --- /dev/null +++ b/src/tests/testParser.c @@ -0,0 +1,66 @@ +#include +#include +#include +#include + +int main(int argc, char** argv) +{ + const uint8_t buffer[2048]; + int index; + + int file = open(argv[1],O_RDONLY); + if(file < 0) + return -1; + index = read(file,(void*)buffer,sizeof(buffer)); + + unsigned int cursor=0,tmp=0; + while(cursor < index) + { + int ret; + const uint8_t *varname,*varvalue; + unsigned int nl,vl; + // try parsing that now + while((ret=PSYC_parseHeader( + &cursor, + buffer,index, + &varname,&nl, + &varvalue,&vl)) == 0) + { + write(0,varname,nl); + write(0," = ",3); + write(0,varvalue,vl); + write(0,"\n",1); + } + printf("ret0: %d\ncursor0: %d\n", + ret,cursor); + + if(ret == 3 || ret == 2) + { + write(0,varname,nl); + write(0," = ",3); + write(0,varvalue,vl); + write(0,"\n",1); + } + if(ret ==2) // header finished + while((ret=PSYC_parseOpenBody( + &cursor, + buffer,index, + &varname,&nl, + &varvalue,&vl)) == 0) + { + write(0,varname,nl); + write(0," = ",3); + write(0,varvalue,vl); + write(0,"\n",1); + } + + if(tmp != cursor) + tmp=cursor; + else + return; + printf("ret: %d\ncursor: %d\n--------\n", + ret,cursor); + } + return 0; + +} From 7f3acf977054eebf6cf3aea4cb43b184561e0308 Mon Sep 17 00:00:00 2001 From: Mathias Laurenz Baumann Date: Sat, 20 Feb 2010 19:50:10 +0100 Subject: [PATCH 005/378] added parsing of empty variables --- src/parser.c | 58 +++++++++++++++++-------------- src/tests/enter_leave_context.txt | 1 + 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/src/parser.c b/src/parser.c index 3114a58..d0db45e 100644 --- a/src/parser.c +++ b/src/parser.c @@ -245,8 +245,9 @@ inline int PSYC_parseElement( * so checking for \n too here * We dont check if cursor inside length, because - * the last loop iteration did that already. */ - if(data[*cursor] == '\t' || (data[*cursor] == '\n' && method==1)) + * the last loop iteration did that already. + */ + if(data[*cursor] == '\t' || data[*cursor] == '\n') // && method==1)) { /* after the \t the arg-data follows, which is * anything but \n. arg-data can be of length 0 @@ -259,38 +260,43 @@ inline int PSYC_parseElement( * to the first potential arg-data byte. * If there is no arg-data, we still have * the length attribute on 0. */ - *value=data+*cursor+1; - *vlength=0; - - while(1) + if(method == 0 && data[*cursor] == '\n') // emptyvar { - if(dlength<=++(*cursor)) // incremented cursor inside lenght? + *value=data+*cursor; + *vlength=0; + }else + { + *value=data+*cursor+1; + *vlength=0; + while(1) { - *cursor=startc; // set to start value - return 1; // return insufficient - } - - if(1 != method && data[*cursor] == '\n') - break; - - if(1 == method && data[*cursor] == '|') - { - if(dlength<++(*cursor)) // incremented cursor inside lenght? + if(dlength<=++(*cursor)) // incremented cursor inside lenght? { *cursor=startc; // set to start value return 1; // return insufficient } - /* packet finishes here */ - if(data[*cursor] == '\n') - { - *cursor+=1; - return 3; - } - } - ++(*vlength); - } + if(0 == method && data[*cursor] == '\n') + break; + if(1 == method && data[*cursor] == '|') + { + if(dlength<++(*cursor)) // incremented cursor inside lenght? + { + *cursor=startc; // set to start value + return 1; // return insufficient + } + + /* packet finishes here */ + if(data[*cursor] == '\n') + { + *cursor+=1; + return 3; + } + } + ++(*vlength); + } + } } diff --git a/src/tests/enter_leave_context.txt b/src/tests/enter_leave_context.txt index a323158..d929edd 100644 --- a/src/tests/enter_leave_context.txt +++ b/src/tests/enter_leave_context.txt @@ -7,6 +7,7 @@ _request_context_enter :_target psyc://p5B084547.dip.t-dialin.net/@test :_more vars +:_nocontent :_entity variablevalue _notice_context_leave | From e6b838537a2bddda0b913c28933ea6c06ae8768d Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Sat, 20 Feb 2010 20:03:27 +0100 Subject: [PATCH 006/378] cryptic Makefile .. har har --- src/tests/Makefile | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/tests/Makefile diff --git a/src/tests/Makefile b/src/tests/Makefile new file mode 100644 index 0000000..2df096b --- /dev/null +++ b/src/tests/Makefile @@ -0,0 +1,3 @@ +CFLAGS=-I.. -DDEBUG ../parser.c + +it: testParser From 583e61b6a1ecbbbbbdab9156c6c9f6f8c71f6365 Mon Sep 17 00:00:00 2001 From: Mathias Laurenz Baumann Date: Sat, 20 Feb 2010 20:31:22 +0100 Subject: [PATCH 007/378] added support for bin vars --- src/parser.c | 106 +++++++++++++++++++++--------- src/tests/enter_leave_context.txt | 4 +- 2 files changed, 79 insertions(+), 31 deletions(-) diff --git a/src/parser.c b/src/parser.c index d0db45e..ec2942e 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1,9 +1,12 @@ #include +#include #ifdef DEBUG #include #endif + + /** @brief isGlyph * * @todo: document this function @@ -24,22 +27,28 @@ inline char isGlyph(uint8_t g) } +inline char isNumeric(uint8_t c) +{ + return c >= '0' && c <= '9' ; +} + inline char isAlphaNumeric(uint8_t c) { return (( c >= 'a' && c <= 'z' )|| ( c >= 'A' && c <= 'Z' )|| - ( c >= '0' && c <= '9' )) + isNumeric(c)) ; } + inline int PSYC_parseElement( unsigned int* cursor, const uint8_t * data, unsigned int dlength, const uint8_t** name, unsigned int *nlength, const uint8_t** value, unsigned int *vlength, - char inHeader); + char inHeader,char complete); /** @brief parses a routerVariable * @@ -82,7 +91,7 @@ inline int PSYC_parseHeader( const uint8_t** name, unsigned int *nlength, const uint8_t** value, unsigned int *vlength) { - return PSYC_parseElement(cursor,data,dlength,name,nlength,value,vlength,1); + return PSYC_parseElement(cursor,data,dlength,name,nlength,value,vlength,1,0); } @@ -104,10 +113,36 @@ inline int PSYC_parseOpenBody( const uint8_t** value, unsigned int *vlength) { - return PSYC_parseElement(cursor,data,dlength,name,nlength,value,vlength,0); + return PSYC_parseElement(cursor,data,dlength,name,nlength,value,vlength,0,0); } +/** @brief parses one bodyelement + * + * This parses one body element, that is + * either an entity-variable or the method + * + * The function assumes that dlength is set + * to the exact length of the packet + * so that data[dlength-1] would be the + * ending "\n" of the packet. + * + * The parameters are nearly the same as for + * PSYC_parseHeader, only difference is + * that a returnvalue of 2 means, we encountered + * the method. + * This means that the out paramterer + * name contains the methodname and + * value the content. + * */ +int PSYC_parseClosedBody( + unsigned int* cursor, + const uint8_t * data, unsigned int dlength, + const uint8_t** name, unsigned int *nlength, + const uint8_t** value, unsigned int *vlength) +{ + return PSYC_parseElement(cursor,data,dlength,name,nlength,value,vlength,0,1); +} @@ -121,7 +156,7 @@ inline int PSYC_parseElement( const uint8_t * data, unsigned int dlength, const uint8_t** name, unsigned int *nlength, const uint8_t** value, unsigned int *vlength, - char inHeader) + char inHeader,char complete) { /* first we test if we can access the first char */ if(dlength<=*cursor) // cursor is not inside the length @@ -281,7 +316,7 @@ inline int PSYC_parseElement( if(1 == method && data[*cursor] == '|') { - if(dlength<++(*cursor)) // incremented cursor inside lenght? + if(dlength<=++(*cursor)) // incremented cursor inside lenght? { *cursor=startc; // set to start value return 1; // return insufficient @@ -297,7 +332,41 @@ inline int PSYC_parseElement( ++(*vlength); } } - } + }else if(inHeader == 0 && method==0 && data[*cursor] == ' ') // oi, its a binary var! + { // after SP the length follows. + const uint8_t * bin_length_str = data + *cursor+1; + int strln = 0; + do + { + if(dlength<=++(*cursor)) // incremented cursor inside lenght? + { + *cursor=startc; // set to start value + return 1; // return insufficient + } + + ++strln; + + }while(isNumeric(data[*cursor])); + + if(data[*cursor] != '\t') + return -8; + + // now we have the length. convert it to int + int binLength = atoi(bin_length_str); + // is that still in this buffer? + if(dlength <= *cursor+binLength+1 ) + { + *cursor=startc; + return 1; + } + + *value = data + *cursor; + *vlength=binLength; + *cursor += binLength; + }else + return -8; + + /* if there was a \t, then we parsed up until the @@ -381,29 +450,6 @@ int PSYC_parseHeader2( const uint8_t** value1, unsigned int *vlength1, const uint8_t** value2, unsigned int *vlength2); -/** @brief parses one bodyelement - * - * This parses one body element, that is - * either an entity-variable or the method - * - * The function assumes that dlength is set - * to the exact length of the packet - * so that data[dlength-1] would be the - * ending "\n" of the packet. - * - * The parameters are nearly the same as for - * PSYC_routerVariable, only difference is - * that a returnvalue of 2 means, we encountered - * the method. - * This means that the out paramterer - * name contains the methodname and - * value the content. - * */ -int PSYC_parseClosedBody( - unsigned int* cursor, - const uint8_t * data, unsigned int dlength, - const uint8_t** name, unsigned int *nlength, - const uint8_t** value, unsigned int *vlength); /* @brief parses an bodyelement in two buffers * diff --git a/src/tests/enter_leave_context.txt b/src/tests/enter_leave_context.txt index d929edd..ea2bc56 100644 --- a/src/tests/enter_leave_context.txt +++ b/src/tests/enter_leave_context.txt @@ -7,7 +7,9 @@ _request_context_enter :_target psyc://p5B084547.dip.t-dialin.net/@test :_more vars -:_nocontent +:_bin 4 1 +3 + :_entity variablevalue _notice_context_leave | From 472314568f7230960bd406f98360b31ffc619dff Mon Sep 17 00:00:00 2001 From: Mathias Laurenz Baumann Date: Sat, 20 Feb 2010 22:09:04 +0100 Subject: [PATCH 008/378] added support for binary packets, untested --- src/parser.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/parser.c b/src/parser.c index ec2942e..aaadde5 100644 --- a/src/parser.c +++ b/src/parser.c @@ -302,6 +302,11 @@ inline int PSYC_parseElement( }else { *value=data+*cursor+1; + if(1== complete) // we know the length of the packet + { + *vlength= dlength - *cursor -3; + }else + { *vlength=0; while(1) { @@ -330,7 +335,7 @@ inline int PSYC_parseElement( } } ++(*vlength); - } + }} } }else if(inHeader == 0 && method==0 && data[*cursor] == ' ') // oi, its a binary var! { // after SP the length follows. @@ -347,7 +352,7 @@ inline int PSYC_parseElement( ++strln; }while(isNumeric(data[*cursor])); - + // after the length a TAB follows if(data[*cursor] != '\t') return -8; From a96f01f355c5774f72e98d23ac0fd2509d347869 Mon Sep 17 00:00:00 2001 From: Mathias Laurenz Baumann Date: Sat, 20 Feb 2010 22:18:39 +0100 Subject: [PATCH 009/378] fixed bug in bin-var parsing --- src/parser.c | 48 +++++++++++++++---------------- src/tests/enter_leave_context.txt | 4 +-- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/parser.c b/src/parser.c index aaadde5..135953c 100644 --- a/src/parser.c +++ b/src/parser.c @@ -307,19 +307,8 @@ inline int PSYC_parseElement( *vlength= dlength - *cursor -3; }else { - *vlength=0; - while(1) - { - if(dlength<=++(*cursor)) // incremented cursor inside lenght? - { - *cursor=startc; // set to start value - return 1; // return insufficient - } - - if(0 == method && data[*cursor] == '\n') - break; - - if(1 == method && data[*cursor] == '|') + *vlength=0; + while(1) { if(dlength<=++(*cursor)) // incremented cursor inside lenght? { @@ -327,15 +316,26 @@ inline int PSYC_parseElement( return 1; // return insufficient } - /* packet finishes here */ - if(data[*cursor] == '\n') - { - *cursor+=1; - return 3; + if(0 == method && data[*cursor] == '\n') + break; + + if(1 == method && data[*cursor] == '|') + { + if(dlength<=++(*cursor)) // incremented cursor inside lenght? + { + *cursor=startc; // set to start value + return 1; // return insufficient + } + + /* packet finishes here */ + if(data[*cursor] == '\n') + { + *cursor+=1; + return 3; + } } - } - ++(*vlength); - }} + ++(*vlength); + }} } }else if(inHeader == 0 && method==0 && data[*cursor] == ' ') // oi, its a binary var! { // after SP the length follows. @@ -355,7 +355,7 @@ inline int PSYC_parseElement( // after the length a TAB follows if(data[*cursor] != '\t') return -8; - + // now we have the length. convert it to int int binLength = atoi(bin_length_str); // is that still in this buffer? @@ -365,9 +365,9 @@ inline int PSYC_parseElement( return 1; } - *value = data + *cursor; + *value = data + *cursor+1; *vlength=binLength; - *cursor += binLength; + *cursor += binLength+1; }else return -8; diff --git a/src/tests/enter_leave_context.txt b/src/tests/enter_leave_context.txt index ea2bc56..b201ad9 100644 --- a/src/tests/enter_leave_context.txt +++ b/src/tests/enter_leave_context.txt @@ -7,9 +7,9 @@ _request_context_enter :_target psyc://p5B084547.dip.t-dialin.net/@test :_more vars -:_bin 4 1 +:_bin 6 "1 3 - +" :_entity variablevalue _notice_context_leave | From 0063a98e5b52f4d76d8da8baf182216b497a7154 Mon Sep 17 00:00:00 2001 From: Mathias Laurenz Baumann Date: Sat, 20 Feb 2010 22:29:09 +0100 Subject: [PATCH 010/378] fixed method output in test and in parser --- src/parser.c | 11 +++++------ src/tests/fake_dns.txt | 1 + src/tests/testParser.c | 8 ++++++++ 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/parser.c b/src/parser.c index 135953c..e7bb231 100644 --- a/src/parser.c +++ b/src/parser.c @@ -224,7 +224,11 @@ inline int PSYC_parseElement( return -5; // report error } else + { + *name = data+*cursor; + *nlength=1; method=1; + } } else { @@ -247,12 +251,7 @@ inline int PSYC_parseElement( && data[*cursor] != '_') // AND not '_'. must be invalid then return -1; // return parser error. - if(1 == method) // for the method.. - { - *name=data+*cursor; // the name starts here. - *nlength=1; // the initial length is 1. - }else - *nlength+=1; + *nlength+=1; /* now checking how long the name of the variable is. */ unsigned int i=0; diff --git a/src/tests/fake_dns.txt b/src/tests/fake_dns.txt index 0158dff..ae6cde6 100644 --- a/src/tests/fake_dns.txt +++ b/src/tests/fake_dns.txt @@ -2,5 +2,6 @@ :_source psyc://heise.de/~user _request_some_things +content! | diff --git a/src/tests/testParser.c b/src/tests/testParser.c index 8594bd6..aff1350 100644 --- a/src/tests/testParser.c +++ b/src/tests/testParser.c @@ -54,6 +54,14 @@ int main(int argc, char** argv) write(0,"\n",1); } + if(ret == 3 || ret == 2) + { + write(0,varname,nl); + write(0," = ",3); + write(0,varvalue,vl); + write(0,"\n",1); + } + if(tmp != cursor) tmp=cursor; else From 001298b1de48edfd96f961b2d076cfd6da4c62c5 Mon Sep 17 00:00:00 2001 From: Mathias Laurenz Baumann Date: Sat, 20 Feb 2010 23:06:33 +0100 Subject: [PATCH 011/378] proper handling of method and data --- src/parser.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/parser.c b/src/parser.c index e7bb231..72d398e 100644 --- a/src/parser.c +++ b/src/parser.c @@ -289,16 +289,23 @@ inline int PSYC_parseElement( * 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 && data[*cursor] == '\n') // emptyvar + if((method == 0 && data[*cursor] == '\n') /* emptyvar */ || + (method == 1 && *cursor+2 < dlength && + data[*cursor+1] == '|' && + data[*cursor+2] == '\n') /*no data */ ) { *value=data+*cursor; *vlength=0; - }else + } + else { *value=data+*cursor+1; if(1== complete) // we know the length of the packet @@ -318,23 +325,26 @@ inline int PSYC_parseElement( if(0 == method && data[*cursor] == '\n') break; - if(1 == method && data[*cursor] == '|') + if(1 == method && data[*cursor] == '\n') { - if(dlength<=++(*cursor)) // incremented cursor inside lenght? + if(dlength<=(*cursor)+2) // incremented cursor inside lenght? { *cursor=startc; // set to start value return 1; // return insufficient } - /* packet finishes here */ - if(data[*cursor] == '\n') - { - *cursor+=1; - return 3; - } + if(data[*cursor+1] == '|') + if(data[*cursor+2] == '\n') + { + /* packet finishes here */ + *cursor+=3; + return 3; + } + } ++(*vlength); - }} + } + } } }else if(inHeader == 0 && method==0 && data[*cursor] == ' ') // oi, its a binary var! { // after SP the length follows. From 52eac395f6b75e6711b0da759f1397d4c594f1a0 Mon Sep 17 00:00:00 2001 From: Mathias Laurenz Baumann Date: Sun, 21 Feb 2010 00:20:55 +0100 Subject: [PATCH 012/378] added makefile to compile lib --- src/Makefile | 12 ++++++++++++ src/parser.c | 2 +- src/tests/Makefile | 2 +- src/tests/binary.txt | 7 +++++++ src/tests/testParser.c | 2 +- 5 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 src/Makefile create mode 100644 src/tests/binary.txt diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..e78f5bf --- /dev/null +++ b/src/Makefile @@ -0,0 +1,12 @@ +CC=clang + +dietlib: + /opt/diet/bin/diet ${CC} -c -Os parser.c -o libpsyc.o -DDEBUG + /opt/diet/bin/diet ar rcs libpsyc.a libpsyc.o + +lib: + ${CC} -static -c -Os parser.c -lc -o libpsyc.o -DDEBUG + ar rcs libpsyc.a libpsyc.o + + + diff --git a/src/parser.c b/src/parser.c index 72d398e..c1973e3 100644 --- a/src/parser.c +++ b/src/parser.c @@ -106,7 +106,7 @@ inline int PSYC_parseHeader( * real length of the packet and thus * searches for the terminator. */ -inline int PSYC_parseOpenBody( +int PSYC_parseOpenBody( unsigned int* cursor, const uint8_t * data, unsigned int dlength, const uint8_t** name, unsigned int *nlength, diff --git a/src/tests/Makefile b/src/tests/Makefile index 2df096b..78e053f 100644 --- a/src/tests/Makefile +++ b/src/tests/Makefile @@ -1,3 +1,3 @@ -CFLAGS=-I.. -DDEBUG ../parser.c +CFLAGS=-I.. -DDEBUG -lpsyc it: testParser diff --git a/src/tests/binary.txt b/src/tests/binary.txt new file mode 100644 index 0000000..6ea6c1f --- /dev/null +++ b/src/tests/binary.txt @@ -0,0 +1,7 @@ +:_source some_source +:_length + +_method +1234567 +| + diff --git a/src/tests/testParser.c b/src/tests/testParser.c index aff1350..8c40ab4 100644 --- a/src/tests/testParser.c +++ b/src/tests/testParser.c @@ -65,7 +65,7 @@ int main(int argc, char** argv) if(tmp != cursor) tmp=cursor; else - return; + return 1; printf("ret: %d\ncursor: %d\n--------\n", ret,cursor); } From d0c0958ddf428d10819515454968831ecec39764 Mon Sep 17 00:00:00 2001 From: Mathias Laurenz Baumann Date: Wed, 1 Sep 2010 15:47:26 +0200 Subject: [PATCH 013/378] small changes for linking --- src/Makefile | 2 +- src/parser.c | 2 +- src/parser.h | 4 ++-- src/tests/Makefile | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Makefile b/src/Makefile index e78f5bf..5bf2de1 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,4 +1,4 @@ -CC=clang +CC=cc dietlib: /opt/diet/bin/diet ${CC} -c -Os parser.c -o libpsyc.o -DDEBUG diff --git a/src/parser.c b/src/parser.c index c1973e3..277c994 100644 --- a/src/parser.c +++ b/src/parser.c @@ -106,7 +106,7 @@ inline int PSYC_parseHeader( * real length of the packet and thus * searches for the terminator. */ -int PSYC_parseOpenBody( +extern int PSYC_parseOpenBody( unsigned int* cursor, const uint8_t * data, unsigned int dlength, const uint8_t** name, unsigned int *nlength, diff --git a/src/parser.h b/src/parser.h index 961de00..1c7979c 100644 --- a/src/parser.h +++ b/src/parser.h @@ -36,7 +36,7 @@ * <0 on a parsing error. * This invalidates all but the cursor * out paramater. */ -int PSYC_parseHeader( +extern int PSYC_parseHeader( unsigned int* cursor, const uint8_t * data, unsigned int dlength, const uint8_t** name, unsigned int *nlength, @@ -110,7 +110,7 @@ int PSYC_parseClosedBody( * real length of the packet and thus * searches for the terminator. */ -int PSYC_parseOpenBody( +extern int PSYC_parseOpenBody( unsigned int* cursor, const uint8_t * data, unsigned int dlength, const uint8_t** name, unsigned int *nlength, diff --git a/src/tests/Makefile b/src/tests/Makefile index 78e053f..347e93c 100644 --- a/src/tests/Makefile +++ b/src/tests/Makefile @@ -1,3 +1,3 @@ -CFLAGS=-I.. -DDEBUG -lpsyc +CFLAGS=-L.. -I.. -DDEBUG -lpsyc it: testParser From eb7876b2d5ab8b9acdfa0da951253dbd8008950f Mon Sep 17 00:00:00 2001 From: Mathias Laurenz Baumann Date: Wed, 1 Sep 2010 17:16:35 +0200 Subject: [PATCH 014/378] fixed and extended makefile --- src/Makefile | 2 +- src/parser.c | 2 +- src/parser.h | 4 ++-- src/tests/Makefile | 7 +++++-- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Makefile b/src/Makefile index 5bf2de1..19c9ab1 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,7 +1,7 @@ CC=cc dietlib: - /opt/diet/bin/diet ${CC} -c -Os parser.c -o libpsyc.o -DDEBUG + /opt/diet/bin/diet ${CC} -static -c -Os parser.c -o libpsyc.o -DDEBUG /opt/diet/bin/diet ar rcs libpsyc.a libpsyc.o lib: diff --git a/src/parser.c b/src/parser.c index 277c994..d887c08 100644 --- a/src/parser.c +++ b/src/parser.c @@ -85,7 +85,7 @@ inline int PSYC_parseElement( * <0 on a parsing error. * This invalidates all but the cursor * out paramater. */ -inline int PSYC_parseHeader( +int PSYC_parseHeader( unsigned int* cursor, const uint8_t * data, unsigned int dlength, const uint8_t** name, unsigned int *nlength, diff --git a/src/parser.h b/src/parser.h index 1c7979c..961de00 100644 --- a/src/parser.h +++ b/src/parser.h @@ -36,7 +36,7 @@ * <0 on a parsing error. * This invalidates all but the cursor * out paramater. */ -extern int PSYC_parseHeader( +int PSYC_parseHeader( unsigned int* cursor, const uint8_t * data, unsigned int dlength, const uint8_t** name, unsigned int *nlength, @@ -110,7 +110,7 @@ int PSYC_parseClosedBody( * real length of the packet and thus * searches for the terminator. */ -extern int PSYC_parseOpenBody( +int PSYC_parseOpenBody( unsigned int* cursor, const uint8_t * data, unsigned int dlength, const uint8_t** name, unsigned int *nlength, diff --git a/src/tests/Makefile b/src/tests/Makefile index 347e93c..c73ef2b 100644 --- a/src/tests/Makefile +++ b/src/tests/Makefile @@ -1,3 +1,6 @@ -CFLAGS=-L.. -I.. -DDEBUG -lpsyc -it: testParser +dietlib: + /opt/diet/bin/diet cc -L.. -I.. -DDEBUG -lpsyc testParser.c -lpsyc -o testParser + +lib: + cc -L.. -I.. -DDEBUG -lpsyc testParser.c -lpsyc -o testParser From 39b9050e79108c3edb3275bcb154ebb6dfcd8ea2 Mon Sep 17 00:00:00 2001 From: Mathias Laurenz Baumann Date: Thu, 2 Sep 2010 13:01:18 +0200 Subject: [PATCH 015/378] reorganized test paths and makefile --- src/tests/Makefile | 6 ------ src/tests/parser/Makefile | 6 ++++++ src/tests/{ => parser}/binary.txt | 0 src/tests/{ => parser}/enter_leave_context.txt | 0 src/tests/{ => parser}/fake_dns.txt | 0 src/tests/{ => parser}/invalid_dns.txt | 0 src/tests/{ => parser}/testParser.c | 0 7 files changed, 6 insertions(+), 6 deletions(-) delete mode 100644 src/tests/Makefile create mode 100644 src/tests/parser/Makefile rename src/tests/{ => parser}/binary.txt (100%) rename src/tests/{ => parser}/enter_leave_context.txt (100%) rename src/tests/{ => parser}/fake_dns.txt (100%) rename src/tests/{ => parser}/invalid_dns.txt (100%) rename src/tests/{ => parser}/testParser.c (100%) diff --git a/src/tests/Makefile b/src/tests/Makefile deleted file mode 100644 index c73ef2b..0000000 --- a/src/tests/Makefile +++ /dev/null @@ -1,6 +0,0 @@ - -dietlib: - /opt/diet/bin/diet cc -L.. -I.. -DDEBUG -lpsyc testParser.c -lpsyc -o testParser - -lib: - cc -L.. -I.. -DDEBUG -lpsyc testParser.c -lpsyc -o testParser diff --git a/src/tests/parser/Makefile b/src/tests/parser/Makefile new file mode 100644 index 0000000..e6cf706 --- /dev/null +++ b/src/tests/parser/Makefile @@ -0,0 +1,6 @@ +parser: + $(DIETLIB) cc -L../.. -I../.. -DDEBUG -lpsyc testParser.c -lpsyc -o testParser + +diet: + DIETLIB=/opt/diet/bin/diet make parser + diff --git a/src/tests/binary.txt b/src/tests/parser/binary.txt similarity index 100% rename from src/tests/binary.txt rename to src/tests/parser/binary.txt diff --git a/src/tests/enter_leave_context.txt b/src/tests/parser/enter_leave_context.txt similarity index 100% rename from src/tests/enter_leave_context.txt rename to src/tests/parser/enter_leave_context.txt diff --git a/src/tests/fake_dns.txt b/src/tests/parser/fake_dns.txt similarity index 100% rename from src/tests/fake_dns.txt rename to src/tests/parser/fake_dns.txt diff --git a/src/tests/invalid_dns.txt b/src/tests/parser/invalid_dns.txt similarity index 100% rename from src/tests/invalid_dns.txt rename to src/tests/parser/invalid_dns.txt diff --git a/src/tests/testParser.c b/src/tests/parser/testParser.c similarity index 100% rename from src/tests/testParser.c rename to src/tests/parser/testParser.c From 7a53273f2d72b47927d9357ac556e6970d8c821f Mon Sep 17 00:00:00 2001 From: Mathias Laurenz Baumann Date: Sat, 18 Sep 2010 18:08:02 +0200 Subject: [PATCH 016/378] added usage for makefile --- src/Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Makefile b/src/Makefile index 19c9ab1..e174d5d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,12 +1,12 @@ CC=cc -dietlib: +default: + @/bin/echo -e "Usage:\n\tmake diet - compile with diet libc\n\tmake lib - compile with normal gnu libc" + +diet: /opt/diet/bin/diet ${CC} -static -c -Os parser.c -o libpsyc.o -DDEBUG /opt/diet/bin/diet ar rcs libpsyc.a libpsyc.o lib: ${CC} -static -c -Os parser.c -lc -o libpsyc.o -DDEBUG ar rcs libpsyc.a libpsyc.o - - - From 01031ceca71d946259563463f4488b1aeca3ca42 Mon Sep 17 00:00:00 2001 From: Mathias Laurenz Baumann Date: Sat, 18 Sep 2010 18:08:18 +0200 Subject: [PATCH 017/378] moved include file to include dir. --- {src => include}/parser.h | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {src => include}/parser.h (100%) diff --git a/src/parser.h b/include/parser.h similarity index 100% rename from src/parser.h rename to include/parser.h From 1c9bbd185cc441a6910cd5414d83fabbd875a836 Mon Sep 17 00:00:00 2001 From: Mathias Laurenz Baumann Date: Sat, 18 Sep 2010 20:02:40 +0200 Subject: [PATCH 018/378] psyc subdir for include files --- include/{ => psyc}/parser.h | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename include/{ => psyc}/parser.h (100%) diff --git a/include/parser.h b/include/psyc/parser.h similarity index 100% rename from include/parser.h rename to include/psyc/parser.h From f7043c22787599158c45ae9c803759ff2e5c7b16 Mon Sep 17 00:00:00 2001 From: Mathias Laurenz Baumann Date: Sat, 18 Sep 2010 21:37:26 +0200 Subject: [PATCH 019/378] fixed comments --- include/psyc/parser.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index 961de00..6718754 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -6,9 +6,12 @@ * advances the cursor after the variable, * writes the variables name, value and their * lengths in the corresponding out parameters - * and returns 0 or an errorcode. + * and returns 0 or an errorcode. * - * + * Note that a return value of 3 does + * not exclude the possibility of + * the variable related parameters being + * filled. * * * @param data pointer to the packet data @@ -32,7 +35,7 @@ * body/entity section, but leaves * the other out parameters invalid. * 3 the packet is complete. - * >2 on a context error, + * >3 on a context error, * <0 on a parsing error. * This invalidates all but the cursor * out paramater. */ @@ -135,4 +138,3 @@ int PSYC_parseOpenBody2( -//#include From b7efbaf6789a979f0139d6aefe2b4288ab969647 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Fri, 18 Feb 2011 14:03:45 +0100 Subject: [PATCH 020/378] - --- src/Makefile | 1 + src/tests/Makefile | 8 ++++++++ 2 files changed, 9 insertions(+) create mode 100644 src/tests/Makefile diff --git a/src/Makefile b/src/Makefile index e174d5d..238510d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,4 +1,5 @@ CC=cc +# CC=clang default: @/bin/echo -e "Usage:\n\tmake diet - compile with diet libc\n\tmake lib - compile with normal gnu libc" diff --git a/src/tests/Makefile b/src/tests/Makefile new file mode 100644 index 0000000..554c76e --- /dev/null +++ b/src/tests/Makefile @@ -0,0 +1,8 @@ +CFLAGS=-I.. -DDEBUG +LDFLAGS=-L.. -lpsyc + +works: + cc -I.. -DDEBUG -L.. testParser.c -o testParser -lpsyc + +it: testParser + From 453011001d92ef517977816114dc279af423d01d Mon Sep 17 00:00:00 2001 From: Mathias Laurenz Baumann Date: Sat, 16 Apr 2011 01:42:36 +0200 Subject: [PATCH 021/378] started new interface. incomplete. --- include/psyc/parser.h | 54 +++++++ src/parser.c | 355 +++++++++++++----------------------------- 2 files changed, 160 insertions(+), 249 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index 6718754..23e5018 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -1,4 +1,58 @@ #include +#include + +enum +{ + +} + +typedef struct +{ + unsigned int length; + const uint8_t *ptr; +} PSYC_Array; + +typedef struct +{ + unsigned int cursor; // current position in buffer + PSYC_Array buffer; + uint8_t flags; + + char inHeader; + unsigned int length; +} PSYC_State; + + +inline PSYC_Array (const uint8_t memory, unsigned int length) +{ + PSYC_Array arr = {length, memory}; + + return arr; +} + +inline void PSYC_initState (PSYC_State* state) +{ + memset(state, 0, sizeof(PSYC_State)); +} + +inline void PSYC_nextBuffer (PSYC_State* state, PSYC_Array newBuf) +{ + state->buffer = newBuf; +} + + +int PSYC_parse(PSYC_State* state, + PSYC_ConstArray name, + PSYC_ConstArray value, + uint8_t modifier, + unsigned long *expectedBytes); + + +inline unsigned int PSYC_getBodyLength (PSYC_State* state) +{ + return state->length; +} + /** @brief parses a routerVariable * diff --git a/src/parser.c b/src/parser.c index d887c08..4091f80 100644 --- a/src/parser.c +++ b/src/parser.c @@ -43,181 +43,89 @@ inline char isAlphaNumeric(uint8_t c) } -inline int PSYC_parseElement( - unsigned int* cursor, - const uint8_t * data, unsigned int dlength, - const uint8_t** name, unsigned int *nlength, - const uint8_t** value, unsigned int *vlength, - char inHeader,char complete); -/** @brief parses a routerVariable - * - * This function parses one routing variable, - * advances the cursor after the variable, - * writes the variables name, value and their - * lengths in the corresponding out parameters - * and returns 0 or an errorcode. - * - * - * - * - * @param data pointer to the packet data - * @param dlength length of the data (amount of bytes) - * @param cursor pointer to the current parsing position. - * should be initialized to 0. - * @param name pointer-pointer, used to return the position - * of the name string - * @param nlength pointer to which the length of - * the name string will be written - * @param value pointer-pointer, used to retrun the position - * of the value string - * @param vlength pointer to which the length of - * the value string will be written - * - * @returns 0 on success - * 1 on insufficient data. - * This does not advance - * the cursor. - * 2 header is now finished. - * no more header variables follow - * 3 the packet is complete. - * >3 on a context error, - * <0 on a parsing error. - * This invalidates all but the cursor - * out paramater. */ -int PSYC_parseHeader( - unsigned int* cursor, - const uint8_t * data, unsigned int dlength, - const uint8_t** name, unsigned int *nlength, - const uint8_t** value, unsigned int *vlength) -{ - return PSYC_parseElement(cursor,data,dlength,name,nlength,value,vlength,1,0); -} - - - - -/** @brief parses one bodyelement - * - * This function is nearly identical to - * its brother parseClosedBody. * - * - * It assumes that we don’t know the - * real length of the packet and thus - * searches for the terminator. - */ -extern int PSYC_parseOpenBody( - unsigned int* cursor, - const uint8_t * data, unsigned int dlength, - const uint8_t** name, unsigned int *nlength, - const uint8_t** value, unsigned int *vlength) +int PSYC_parse(PSYC_State* state, + PSYC_ConstArray name, + PSYC_ConstArray value, + uint8_t modifier, + unsigned long *expectedBytes) { - return PSYC_parseElement(cursor,data,dlength,name,nlength,value,vlength,0,0); } -/** @brief parses one bodyelement - * - * This parses one body element, that is - * either an entity-variable or the method - * - * The function assumes that dlength is set - * to the exact length of the packet - * so that data[dlength-1] would be the - * ending "\n" of the packet. - * - * The parameters are nearly the same as for - * PSYC_parseHeader, only difference is - * that a returnvalue of 2 means, we encountered - * the method. - * This means that the out paramterer - * name contains the methodname and - * value the content. - * */ -int PSYC_parseClosedBody( - unsigned int* cursor, - const uint8_t * data, unsigned int dlength, - const uint8_t** name, unsigned int *nlength, - const uint8_t** value, unsigned int *vlength) -{ - return PSYC_parseElement(cursor,data,dlength,name,nlength,value,vlength,0,1); -} - - - - - /** @brief generalized linebased parser */ -inline int PSYC_parseElement( - unsigned int* cursor, - const uint8_t * data, unsigned int dlength, - const uint8_t** name, unsigned int *nlength, - const uint8_t** value, unsigned int *vlength, - char inHeader,char complete) +inline int PSYC_parse( + PSYC_State* state, + PSYC_Array* name, PSYC_Array* value + uint8_t* modifier, unsigned long* expectedBytes) { /* first we test if we can access the first char */ - if(dlength<=*cursor) // cursor is not inside the length + if(state->buffer.length<=state->cursor) // cursor is not inside the length return 1; // return insufficient data. // in case we return insufficent, we rewind to the start. - unsigned int startc=*cursor; + unsigned int startc=state->cursor; /* 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(1==inHeader) + if(1==state->inHeader) { - if(!isGlyph(data[*cursor])) // is the first char not a glyph? + if(!isGlyph(state->buffer.ptr[state->cursor])) // is the first char not a glyph? { // the only other possibility now is that the packet // is complete(empty packet) or that the method started. - if(isAlphaNumeric(data[*cursor])) - return 2; // return header finished - - if(data[*cursor] == '|') + if(isAlphaNumeric(state->buffer.ptr[state->cursor])) { - if(dlength<=++(*cursor)) // incremented cursor inside lenght? + state->inHeader = 0; + return 2; // return header finished + } + + if(state->buffer.ptr[state->cursor] == '|') + { + if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? { - *cursor=startc; // set to start value + state->cursor=startc; // set to start value return 1; // return insufficient } - if(data[*cursor]=='\n') + if(state->buffer.ptr[state->cursor]=='\n') { - ++(*cursor); + ++(state->cursor); return 3; // return packet finished } } return -6; // report error }else // it is a glyph, so a variable name starts here { - *name = data+*cursor; - *nlength = 1; + *modifier = *state->buffer.ptr+state->cursor; + name->length = 0; } } + char method=0; /* in the body, the same applies, only that the * method does not start with a glyph.*/ - if(0==inHeader && !isGlyph(data[*cursor])) + if(0==state->inHeader && !isGlyph(state->buffer.ptr[state->cursor])) { - if(!isAlphaNumeric(data[*cursor]) && data[*cursor] != '_') + if(!isAlphaNumeric(state->buffer.ptr[state->cursor]) && state->buffer.ptr[state->cursor] != '_') { // the body rule is optional, which means // that now also just |\n can follow. - if(data[*cursor] == '|') + if(state->buffer.ptr[state->cursor] == '|') { - if(dlength<=++(*cursor)) // incremented cursor inside lenght? + if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? { - *cursor=startc; // set to start value + state->cursor=startc; // set to start value return 1; // return insufficient } - if(data[*cursor]=='\n') + if(state->buffer.ptr[state->cursor]=='\n') { - ++(*cursor); + ++(state->cursor); return 3; // return packet finished } } @@ -225,21 +133,21 @@ inline int PSYC_parseElement( } else { - *name = data+*cursor; - *nlength=1; + name->ptr = state->buffer.ptr+state->cursor; + name->length=1; method=1; } } else { - *name = data+*cursor; - *nlength=1; + name->ptr = state->buffer.ptr+state->cursor; + name->length=1; } /* validate the incremented cursor */ - if(dlength <= ++(*cursor)) + if(state->buffer.length <= ++(state->cursor)) { - *cursor=startc; + state->cursor=startc; return 1; } @@ -247,136 +155,139 @@ inline int PSYC_parseElement( * allowed is alphanumeric and _ */ // first char must exist. - if(!isAlphaNumeric(data[*cursor]) // is it not alphanum - && data[*cursor] != '_') // AND not '_'. must be invalid then + 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. - *nlength+=1; + name->length+=1; /* now checking how long the name of the variable is. */ unsigned int i=0; while(1) { - if(dlength<= ++(*cursor)) // incremented cursor inside lenght? + if(state->buffer.length<= ++(state->cursor)) // incremented cursor inside lenght? { - *cursor=startc; // set to start value + state->cursor=startc; // set to start value return 1; // return insufficient } // same as bevore - if(!isAlphaNumeric(data[*cursor]) && - data[*cursor] != '_') + if(!isAlphaNumeric(state->buffer.ptr[state->cursor]) && + state->buffer.ptr[state->cursor] != '_') break; // not valid? then stop the loop right here - ++(*nlength); // was a valid char, increase length + ++(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 + * for the method, the state->buffer.ptr 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(data[*cursor] == '\t' || data[*cursor] == '\n') // && method==1)) + if(state->buffer.ptr[state->cursor] == '\t' || state->buffer.ptr[state->cursor] == '\n') // && method==1)) { - /* after the \t the arg-data follows, which is - * anything but \n. arg-data can be of length 0 + /* after the \t the arg-state->buffer.ptr follows, which is + * anything but \n. arg-state->buffer.ptr can be of length 0 * - * for the method: after the \n data follows, + * for the method: after the \n state->buffer.ptr follows, * which is anything but \n|\n * - * but data is optional, so we first check - * here if data follows at all. + * but state->buffer.ptr is optional, so we first check + * here if state->buffer.ptr follows at all. * - * arg-data=*value. we set value here so it + * arg-state->buffer.ptr=value->ptr. 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 + * to the first potential arg-state->buffer.ptr byte. + * If there is no arg-state->buffer.ptr, we still have * the length attribute on 0. */ - if((method == 0 && data[*cursor] == '\n') /* emptyvar */ || - (method == 1 && *cursor+2 < dlength && - data[*cursor+1] == '|' && - data[*cursor+2] == '\n') /*no data */ ) + 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 state->buffer.ptr */ ) { - *value=data+*cursor; - *vlength=0; + value->ptr=state->buffer.ptr+state->cursor; + value->length=0; } else { - *value=data+*cursor+1; - if(1== complete) // we know the length of the packet + value->ptr=state->buffer.ptr+state->cursor+1; + if (1==state->length) // we know the length of the packet { - *vlength= dlength - *cursor -3; - }else + value->length= state->buffer.length - state->cursor -3; + } + else // else search for the terminator { - *vlength=0; - while(1) + value->length=0; + + while (1) { - if(dlength<=++(*cursor)) // incremented cursor inside lenght? + if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? { - *cursor=startc; // set to start value + state->cursor=startc; // set to start value return 1; // return insufficient } - if(0 == method && data[*cursor] == '\n') + if(0 == method && state->buffer.ptr[state->cursor] == '\n') break; - if(1 == method && data[*cursor] == '\n') + if(1 == method && state->buffer.ptr[state->cursor] == '\n') { - if(dlength<=(*cursor)+2) // incremented cursor inside lenght? + if(state->buffer.length<=(state->cursor)+2) // incremented cursor inside lenght? { - *cursor=startc; // set to start value + state->cursor=startc; // set to start value return 1; // return insufficient } - if(data[*cursor+1] == '|') - if(data[*cursor+2] == '\n') + if(state->buffer.ptr[state->cursor+1] == '|') + if(state->buffer.ptr[state->cursor+2] == '\n') { /* packet finishes here */ - *cursor+=3; + state->cursor+=3; return 3; } } - ++(*vlength); + ++(value->length); } } } - }else if(inHeader == 0 && method==0 && data[*cursor] == ' ') // oi, its a binary var! + }else if(state->inHeader == 0 && method==0 && state->buffer.ptr[state->cursor] == ' ') // oi, its a binary var! { // after SP the length follows. - const uint8_t * bin_length_str = data + *cursor+1; + const uint8_t * bin_length_str = state->buffer.ptr + state->cursor+1; int strln = 0; do { - if(dlength<=++(*cursor)) // incremented cursor inside lenght? + if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? { - *cursor=startc; // set to start value + state->cursor=startc; // set to start value return 1; // return insufficient } ++strln; + } + while(isNumeric(state->buffer.ptr[state->cursor])); - }while(isNumeric(data[*cursor])); // after the length a TAB follows - if(data[*cursor] != '\t') + if (state->buffer.ptr[state->cursor] != '\t') return -8; // now we have the length. convert it to int int binLength = atoi(bin_length_str); // is that still in this buffer? - if(dlength <= *cursor+binLength+1 ) + if(state->buffer.length <= state->cursor+binLength+1 ) { - *cursor=startc; + state->cursor=startc; return 1; } - *value = data + *cursor+1; - *vlength=binLength; - *cursor += binLength+1; + value->ptr = state->buffer.ptr + state->cursor+1; + value->length=binLength; + state->cursor += binLength+1; }else return -8; @@ -384,7 +295,7 @@ inline int PSYC_parseElement( /* if there was a \t, then we parsed up until the - * \n char from the simple-arg rule ( \t arg-data \n ) + * \n char from the simple-arg rule ( \t arg-state->buffer.ptr \n ) * * Now, if there would be no \t, we still would be at * the point where a \n must follow. @@ -395,90 +306,36 @@ inline int PSYC_parseElement( * * again, the loop has already validated the cursors * position*/ - if(data[*cursor] != '\n') + 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(dlength<=++(*cursor)) // incremented cursor inside lenght? + if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? { - *cursor=startc; // set to start value + state->cursor=startc; // set to start value return 1; // return insufficient } - if(1 == inHeader && data[*cursor] == '\n') + if(1 == state->inHeader && state->buffer.ptr[state->cursor] == '\n') { - *cursor+=1; + state->cursor+=1; + state->inHeader = 0; return 2; // line is complete, but body starts now. } - if(data[*cursor] != '|') // no pipe, then only line complete, not the packet. + if(state->buffer.ptr[state->cursor] != '|') // no pipe, then only line complete, not the packet. return 0; - if(dlength<=++(*cursor)) // incremented cursor inside lenght? + if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? { - *cursor=startc; // set to start value + state->cursor=startc; // set to start value return 1; // return insufficient } - if(data[*cursor] != '\n') + if(state->buffer.ptr[state->cursor] != '\n') return -4; - *cursor+=1; + state->cursor+=1; return 3; // packet is complete - - } -/** @brief parses one variable in two buffers - * - * This function is nearly identical to its - * brother parseHeader. The difference is, - * it uses two buffers and return parameters - * for everything. It is meant to be used - * in case parseHeader returned 2 for - * insufficient data and you don’t - * like to copy memory around to - * have all the data in one buffer. - * Using this function, you can pass two - * data buffers. The consequence is, - * that name and value can be distributed - * on two different buffers and thus need - * also two out paramaters. If only one - * will be used, length of the second - * will be 0. - * - * If your data is spread over more - * than two buffers, you need to - * copy that in one or two buffers. - * Given the unlikleyness of that - * event, we don't offer a three - * or more buffer function here. - * - */ -int PSYC_parseHeader2( - unsigned int* cursor, - const uint8_t * data1, unsigned int dlength1, - const uint8_t * data2, unsigned int dlength2, - const uint8_t** name1, unsigned int *nlength1, - const uint8_t** name2, unsigned int *nlength2, - const uint8_t** value1, unsigned int *vlength1, - const uint8_t** value2, unsigned int *vlength2); - - -/* @brief parses an bodyelement in two buffers - * - * This function is the brother of parseHeader2. - * It behaives the same as - * parseOpenBody and parseHeader2. */ -int PSYC_parseOpenBody2( - unsigned int* cursor, - const uint8_t * data1, unsigned int dlength1, - const uint8_t * data2, unsigned int dlength2, - const uint8_t** name1, unsigned int *nlength1, - const uint8_t** name2, unsigned int *nlength2, - const uint8_t** value1, unsigned int *vlength1, - const uint8_t** value2, unsigned int *vlength2); - - - - From c688bab1f8f629ba354c4ad03797b616f5012bfd Mon Sep 17 00:00:00 2001 From: "Mathias L. Baumann" Date: Sat, 16 Apr 2011 11:30:26 +0200 Subject: [PATCH 022/378] compiles now. setting of expectedBytes and parsing of length is still missing --- include/psyc/parser.h | 16 +++++----------- src/Makefile | 2 +- src/parser.c | 36 ++++++++++++++++++++---------------- 3 files changed, 26 insertions(+), 28 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index 23e5018..6b69cb1 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -1,15 +1,11 @@ #include #include -enum -{ - -} typedef struct { unsigned int length; - const uint8_t *ptr; + const uint8_t * ptr; } PSYC_Array; typedef struct @@ -23,7 +19,7 @@ typedef struct } PSYC_State; -inline PSYC_Array (const uint8_t memory, unsigned int length) +inline PSYC_Array PSYC_CreateArray (uint8_t* const memory, unsigned int length) { PSYC_Array arr = {length, memory}; @@ -41,11 +37,9 @@ inline void PSYC_nextBuffer (PSYC_State* state, PSYC_Array newBuf) } -int PSYC_parse(PSYC_State* state, - PSYC_ConstArray name, - PSYC_ConstArray value, - uint8_t modifier, - unsigned long *expectedBytes); +inline int PSYC_parse(PSYC_State* state, + PSYC_Array* name, PSYC_Array* value, + uint8_t* modifier, unsigned long *expectedBytes); inline unsigned int PSYC_getBodyLength (PSYC_State* state) diff --git a/src/Makefile b/src/Makefile index 238510d..9337223 100644 --- a/src/Makefile +++ b/src/Makefile @@ -9,5 +9,5 @@ diet: /opt/diet/bin/diet ar rcs libpsyc.a libpsyc.o lib: - ${CC} -static -c -Os parser.c -lc -o libpsyc.o -DDEBUG + ${CC} -static -c -Os parser.c -lc -o libpsyc.o -DDEBUG -I../include ar rcs libpsyc.a libpsyc.o diff --git a/src/parser.c b/src/parser.c index 4091f80..cadfe43 100644 --- a/src/parser.c +++ b/src/parser.c @@ -5,7 +5,7 @@ #include #endif - +#include /** @brief isGlyph * @@ -44,22 +44,10 @@ inline char isAlphaNumeric(uint8_t c) -int PSYC_parse(PSYC_State* state, - PSYC_ConstArray name, - PSYC_ConstArray value, - uint8_t modifier, - unsigned long *expectedBytes) -{ - -} - - - - /** @brief generalized linebased parser */ inline int PSYC_parse( PSYC_State* state, - PSYC_Array* name, PSYC_Array* value + PSYC_Array* name, PSYC_Array* value, uint8_t* modifier, unsigned long* expectedBytes) { /* first we test if we can access the first char */ @@ -101,7 +89,16 @@ inline int PSYC_parse( return -6; // report error }else // it is a glyph, so a variable name starts here { - *modifier = *state->buffer.ptr+state->cursor; + *modifier = *(state->buffer.ptr+state->cursor); + + if (state->buffer.length <= ++(state->cursor)) + { + state->cursor = startc; // rewind to start of line + return 1; // return insufficient + } + + name->ptr = state->buffer.ptr + state->cursor; + name->length = 0; } } @@ -140,6 +137,14 @@ inline int PSYC_parse( } else { + *modifier = *(state->buffer.ptr+state->cursor); + + if (state->buffer.length <= ++(state->cursor)) + { + state->cursor = startc; // rewind + return 1; // return insufficient + } + name->ptr = state->buffer.ptr+state->cursor; name->length=1; } @@ -177,7 +182,6 @@ inline int PSYC_parse( break; // not valid? then stop the loop right here ++(name->length); // was a valid char, increase length - } /* we now parsed the variable name successfully From d4b0f33d7b939482d9b10c8784d25abea2683853 Mon Sep 17 00:00:00 2001 From: "Mathias L. Baumann" Date: Sat, 16 Apr 2011 12:37:33 +0200 Subject: [PATCH 023/378] now parsing the number manually. Needs testing --- src/parser.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/parser.c b/src/parser.c index cadfe43..6c35caa 100644 --- a/src/parser.c +++ b/src/parser.c @@ -262,27 +262,29 @@ inline int PSYC_parse( } }else if(state->inHeader == 0 && method==0 && state->buffer.ptr[state->cursor] == ' ') // oi, its a binary var! { // after SP the length follows. - const uint8_t * bin_length_str = state->buffer.ptr + state->cursor+1; - int strln = 0; - do + unsigned int binLength= 0; + + if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? { + state->cursor=startc; // set to start value + return 1; // return insufficient + } + + while(isNumeric(state->buffer.ptr[state->cursor])); + { + binLength = 10 * binLength + state->buffer.ptr[state->cursor] - '0'; + if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? { state->cursor=startc; // set to start value return 1; // return insufficient } - - ++strln; } - while(isNumeric(state->buffer.ptr[state->cursor])); - // after the length a TAB follows if (state->buffer.ptr[state->cursor] != '\t') return -8; - // now we have the length. convert it to int - int binLength = atoi(bin_length_str); - // is that still in this buffer? + // is the length still in this buffer? if(state->buffer.length <= state->cursor+binLength+1 ) { state->cursor=startc; @@ -292,7 +294,8 @@ inline int PSYC_parse( value->ptr = state->buffer.ptr + state->cursor+1; value->length=binLength; state->cursor += binLength+1; - }else + } + else return -8; From 50b9ccab369ddc4b9b24925d4ee4655263ece094 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Sat, 16 Apr 2011 13:13:57 +0200 Subject: [PATCH 024/378] psycmatch() as a standalone command, being reworked into a function now --- src/match.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 src/match.c diff --git a/src/match.c b/src/match.c new file mode 100644 index 0000000..07de201 --- /dev/null +++ b/src/match.c @@ -0,0 +1,66 @@ +#include +#include + +int main(int argc, char **argv) { + char *sho, *lon, *s, *l, *se, *le; + int slen, llen; + + if (argc != 3) { + printf("Usage: %s \n\nExample: %s _failure_delivery _failure_unsuccessful_delivery_death\n", argv[0], argv[0]); + return -1; + } + sho = argv[1]; + lon = argv[2]; + + if (!(slen = strlen(sho)) || *sho != '_' || + !(llen = strlen(lon)) || *lon != '_') { + printf("Please use long format keywords (compact ones would be faster, I know..)\n"); + return -2; + } + + if (slen > llen) { + printf("The long string is shorter than the short one.\n"); + return -3; + } + + if (slen == llen) { + if (!strcmp(sho, lon)) { + printf("Identical arguments.\n"); + return 0; + } + printf("Same length but different.\nNo match, but they could be related or have a common type.\n"); + return -4; + } + printf("*start short '%s' long '%s'\n", sho, lon); + + se = sho+slen; + le = lon+llen; + *se = *le = '_'; + sho++; lon++; + while(s = strchr(sho, '_')) { + *s = 0; + printf("sho goes '%c' and lon goes '%c'\n", *sho, *lon); + while(l = strchr(lon, '_')) { + *l = 0; + printf("strcmp short '%s' long '%s'\n", sho, lon); + if (!strcmp(sho, lon)) goto foundone; + if (l == le) goto failed; + *l = '_'; + lon = ++l; + } + goto failed; +foundone: + printf("found: short '%s' long '%s'\n", sho, lon); + if (s == se) goto success; + *l = *s = '_'; + sho = ++s; + lon = ++l; + } +success: + printf("Yes, they match!\n"); + return 0; +failed: + printf("No, they don't!\n"); + return 1; +} + From a08c6f3f1d26ad73f3e1014baaee82c956609aa6 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Sat, 16 Apr 2011 13:49:47 +0200 Subject: [PATCH 025/378] match: intermediate version --- src/Makefile | 5 +++++ src/match.c | 46 +++++++++++++++++++++++++++------------------- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/src/Makefile b/src/Makefile index 9337223..0403868 100644 --- a/src/Makefile +++ b/src/Makefile @@ -11,3 +11,8 @@ diet: lib: ${CC} -static -c -Os parser.c -lc -o libpsyc.o -DDEBUG -I../include ar rcs libpsyc.a libpsyc.o + +match: match.c + ${CC} -o $@ -DTEST $< + +it: match diff --git a/src/match.c b/src/match.c index 07de201..c7dc6b2 100644 --- a/src/match.c +++ b/src/match.c @@ -1,37 +1,36 @@ #include #include -int main(int argc, char **argv) { - char *sho, *lon, *s, *l, *se, *le; - int slen, llen; +#ifdef TEST +# define PT(args) printf args; +#else +# define PT(args) +#endif - if (argc != 3) { - printf("Usage: %s \n\nExample: %s _failure_delivery _failure_unsuccessful_delivery_death\n", argv[0], argv[0]); - return -1; - } - sho = argv[1]; - lon = argv[2]; +int psycmatch(char* sho, char* lon) { + char *s, *l, *se, *le; + int slen, llen; if (!(slen = strlen(sho)) || *sho != '_' || !(llen = strlen(lon)) || *lon != '_') { - printf("Please use long format keywords (compact ones would be faster, I know..)\n"); + PT(("Please use long format keywords (compact ones would be faster, I know..)\n")) return -2; } if (slen > llen) { - printf("The long string is shorter than the short one.\n"); + PT(("The long string is shorter than the short one.\n")) return -3; } if (slen == llen) { if (!strcmp(sho, lon)) { - printf("Identical arguments.\n"); + PT(("Identical arguments.\n")) return 0; } - printf("Same length but different.\nNo match, but they could be related or have a common type.\n"); + PT(("Same length but different.\nNo match, but they could be related or have a common type.\n")) return -4; } - printf("*start short '%s' long '%s'\n", sho, lon); + PT(("*start short '%s' long '%s'\n", sho, lon)) se = sho+slen; le = lon+llen; @@ -39,10 +38,10 @@ int main(int argc, char **argv) { sho++; lon++; while(s = strchr(sho, '_')) { *s = 0; - printf("sho goes '%c' and lon goes '%c'\n", *sho, *lon); + PT(("sho goes '%c' and lon goes '%c'\n", *sho, *lon)) while(l = strchr(lon, '_')) { *l = 0; - printf("strcmp short '%s' long '%s'\n", sho, lon); + PT(("strcmp short '%s' long '%s'\n", sho, lon)) if (!strcmp(sho, lon)) goto foundone; if (l == le) goto failed; *l = '_'; @@ -50,17 +49,26 @@ int main(int argc, char **argv) { } goto failed; foundone: - printf("found: short '%s' long '%s'\n", sho, lon); + PT(("found: short '%s' long '%s'\n", sho, lon)) if (s == se) goto success; *l = *s = '_'; sho = ++s; lon = ++l; } success: - printf("Yes, they match!\n"); return 0; failed: - printf("No, they don't!\n"); + PT(("No, they don't match.\n")) return 1; } +#ifdef TEST +int main(int argc, char **argv) { + if (argc != 3) { + printf("Usage: %s \n\nExample: %s _failure_delivery _failure_unsuccessful_delivery_death\n", argv[0], argv[0]); + return -1; + } + if (psycmatch(argv[1], argv[2]) == 0) + printf("Yes, they match!\n"); +} +#endif From 9f0bb8508e6e6ce1de54d551cef385a4f9f28d01 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Sat, 16 Apr 2011 14:05:28 +0200 Subject: [PATCH 026/378] match in library style --- src/match.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/match.c b/src/match.c index c7dc6b2..6354012 100644 --- a/src/match.c +++ b/src/match.c @@ -1,18 +1,22 @@ -#include #include +#include #ifdef TEST +# include # define PT(args) printf args; #else # define PT(args) #endif -int psycmatch(char* sho, char* lon) { - char *s, *l, *se, *le; - int slen, llen; +int PSYC_matches(uint8_t* sho, unsigned int slen, + uint8_t* lon, unsigned int llen) { + uint8_t *s, *l, *se, *le; - if (!(slen = strlen(sho)) || *sho != '_' || - !(llen = strlen(lon)) || *lon != '_') { + if (!slen) slen = strlen(sho); + if (!llen) llen = strlen(lon); + + if (slen == 0 || *sho != '_' || + llen == 0 || *lon != '_') { PT(("Please use long format keywords (compact ones would be faster, I know..)\n")) return -2; } @@ -68,7 +72,7 @@ int main(int argc, char **argv) { printf("Usage: %s \n\nExample: %s _failure_delivery _failure_unsuccessful_delivery_death\n", argv[0], argv[0]); return -1; } - if (psycmatch(argv[1], argv[2]) == 0) + if (PSYC_matches((uint8_t*) argv[1], 0, (uint8_t*) argv[2], 0) == 0) printf("Yes, they match!\n"); } #endif From dbadcf407de5492f28316b641dd8698be1540eb2 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Sat, 16 Apr 2011 17:30:03 +0200 Subject: [PATCH 027/378] debug macros --- include/psyc.h | 10 +++++ include/psyc/debug.h | 95 +++++++++++++++++++++++++++++++++++++++++++ include/psyc/lib.h | 9 ++++ include/psyc/syntax.h | 39 ++++++++++++++++++ src/Makefile | 17 ++++---- src/match.c | 14 ++----- src/tests/testMatch.c | 12 ++++++ 7 files changed, 178 insertions(+), 18 deletions(-) create mode 100644 include/psyc.h create mode 100644 include/psyc/debug.h create mode 100644 include/psyc/lib.h create mode 100644 include/psyc/syntax.h create mode 100644 src/tests/testMatch.c diff --git a/include/psyc.h b/include/psyc.h new file mode 100644 index 0000000..040509d --- /dev/null +++ b/include/psyc.h @@ -0,0 +1,10 @@ +#include +#include + +#define PSYC_EPOCH 1440444041 // 2015-08-24 21:20:41 CET (Monday) + +/** @brief Checks if short keyword string matches long keyword string + */ +int PSYC_matches(uint8_t* sho, unsigned int slen, + uint8_t* lon, unsigned int llen); + diff --git a/include/psyc/debug.h b/include/psyc/debug.h new file mode 100644 index 0000000..0fcdb05 --- /dev/null +++ b/include/psyc/debug.h @@ -0,0 +1,95 @@ +#ifdef DEBUG +# include +# define PP(args) printf args; +#else +# define PP(args) +#endif + +#ifdef TEST +# define PT(MSG) PP(MSG); +# define DT(CODE) CODE +#else +# define PT(MSG) +# define DT(CODE) +#endif + +/* simplified form of conditional compilation */ + +#ifndef DEBUG_FLAGS +# ifdef DEBUG +# if DEBUG == 1 +# define DEBUG_FLAGS 0x03 +# else +# if DEBUG == 2 +# define DEBUG_FLAGS 0x07 +# else +# if DEBUG == 3 +# define DEBUG_FLAGS 0x0f +# else +# if DEBUG == 4 +# define DEBUG_FLAGS 0x1f +# else +# define DEBUG_FLAGS 0x01 +# endif +# endif +# endif +# endif +# else +# define DEBUG_FLAGS 0x00 /* no debugging */ +# endif +#endif + +#if DEBUG_FLAGS & 0x01 +# define D0(CODE) CODE +# define P0(MSG) PP(MSG); +#else +# define D0(CODE) +# define P0(MSG) +#endif + +#if DEBUG_FLAGS & 0x02 +# define D1(CODE) CODE +# define P1(MSG) PP(MSG); +#else +# define D1(CODE) +# define P1(MSG) +#endif + +#if DEBUG_FLAGS & 0x04 +# define D2(CODE) CODE +# define P2(MSG) PP(MSG); +#else +# define D2(CODE) +# define P2(MSG) +#endif + +#if DEBUG_FLAGS & 0x08 +# define D3(CODE) CODE +# define P3(MSG) PP(MSG); +#else +# define D3(CODE) +# define P3(MSG) +#endif + +#if DEBUG_FLAGS & 0x10 +# define D4(CODE) CODE +# define P4(MSG) PP(MSG); +#else +# define D4(CODE) +# define P4(MSG) +#endif + +// ASSERT() unused as yet +#if DEBUG > 0 +# ifdef STRICT +# define ASSERT(NAME,COND,VALUE) { unless (COND) { \ + PP(("Assertion %s failed in %s: %s\n", NAME, ME, VALUE)); \ + raise_error("Assertion failed (strict mode).\n"); } } +# else +# define ASSERT(NAME,COND,VALUE) { unless (COND) \ + PP(("Assertion %s failed in %s: %s\n", NAME, ME, VALUE)); } +# endif +#else +# define ASSERT(NAME,CONDITION,VALUE) +#endif + diff --git a/include/psyc/lib.h b/include/psyc/lib.h new file mode 100644 index 0000000..699f601 --- /dev/null +++ b/include/psyc/lib.h @@ -0,0 +1,9 @@ +/* this is needed to compile the library, not to use it */ + +#include "../psyc.h" +#include "./debug.h" + +/* perlisms for readability */ +#define unless(COND) if (!(COND)) +#define until(COND) while (!(COND)) + diff --git a/include/psyc/syntax.h b/include/psyc/syntax.h new file mode 100644 index 0000000..c15889e --- /dev/null +++ b/include/psyc/syntax.h @@ -0,0 +1,39 @@ +#ifndef PSYC_SYNTAX_H +#define PSYC_SYNTAX_H + +#ifndef PSYC_LIST_SIZE_LIMIT +# define PSYC_LIST_SIZE_LIMIT 404 +#endif + +/* beyond this a content length must be provided */ +#ifndef PSYC_CONTENT_SIZE_THRESHOLD +# define PSYC_CONTENT_SIZE_THRESHOLD 444 +#endif + +#define C_GLYPH_PACKET_DELIMITER '.' +#define S_GLYPH_PACKET_DELIMITER "." + +#define C_GLYPH_SEPARATOR_KEYWORD '_' +#define S_GLYPH_SEPARATOR_KEYWORD "_" + +#define C_GLYPH_MODIFIER_SET ':' +#define S_GLYPH_MODIFIER_SET ":" + +#define C_GLYPH_MODIFIER_ASSIGN '=' +#define S_GLYPH_MODIFIER_ASSIGN "=" + +#define C_GLYPH_MODIFIER_AUGMENT '+' +#define S_GLYPH_MODIFIER_AUGMENT "+" + +#define C_GLYPH_MODIFIER_DIMINISH '-' +#define S_GLYPH_MODIFIER_DIMINISH "-" + +#define C_GLYPH_MODIFIER_QUERY '?' +#define S_GLYPH_MODIFIER_QUERY "?" + +/* might move into routing.h or something */ +#define PSYC_ROUTING 1 +#define PSYC_ROUTING_MERGE 2 +#define PSYC_ROUTING_RENDER 4 + +#endif /* PSYC_SYNTAX_H */ diff --git a/src/Makefile b/src/Makefile index 0403868..10a5e93 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,18 +1,21 @@ -CC=cc +CC=cc -I../include # CC=clang +S=parser.c match.c +O=parser.o match.o + default: @/bin/echo -e "Usage:\n\tmake diet - compile with diet libc\n\tmake lib - compile with normal gnu libc" diet: - /opt/diet/bin/diet ${CC} -static -c -Os parser.c -o libpsyc.o -DDEBUG - /opt/diet/bin/diet ar rcs libpsyc.a libpsyc.o + /opt/diet/bin/diet ${CC} -static -c -Os $S -DDEBUG + /opt/diet/bin/diet ar rcs libpsyc.a $O -lib: - ${CC} -static -c -Os parser.c -lc -o libpsyc.o -DDEBUG -I../include - ar rcs libpsyc.a libpsyc.o +lib: $S + ${CC} -static -c -Os $S -lc -DDEBUG + ar rcs libpsyc.a $O match: match.c - ${CC} -o $@ -DTEST $< + ${CC} -o $@ -DDEBUG=2 -DCMDTOOL -DTEST $< it: match diff --git a/src/match.c b/src/match.c index 6354012..f80653e 100644 --- a/src/match.c +++ b/src/match.c @@ -1,15 +1,7 @@ -#include -#include - -#ifdef TEST -# include -# define PT(args) printf args; -#else -# define PT(args) -#endif +#include "psyc/lib.h" int PSYC_matches(uint8_t* sho, unsigned int slen, - uint8_t* lon, unsigned int llen) { + uint8_t* lon, unsigned int llen) { uint8_t *s, *l, *se, *le; if (!slen) slen = strlen(sho); @@ -66,7 +58,7 @@ failed: return 1; } -#ifdef TEST +#ifdef CMDTOOL int main(int argc, char **argv) { if (argc != 3) { printf("Usage: %s \n\nExample: %s _failure_delivery _failure_unsuccessful_delivery_death\n", argv[0], argv[0]); diff --git a/src/tests/testMatch.c b/src/tests/testMatch.c new file mode 100644 index 0000000..933d217 --- /dev/null +++ b/src/tests/testMatch.c @@ -0,0 +1,12 @@ +#include +#include "../include/psyc/lib.h" + +int main() { + if (PSYC_matches("_failure_delivery", 0, "_failure_unsuccessful_delivery_death", 0)) return -1; + if (PSYC_matches("_failure_trash", 8, "_failure_unsuccessful_delivery_death", 0)) return -2; + if (PSYC_matches("_unsuccessful", 0, "_failure_unsuccessful_delivery_death", 0)) return -3; + if (PSYC_matches("_fail", 0, "_failure_unsuccessful_delivery_death", 0)) return -4; + unless (PSYC_matches("_truthahn", 0, "_failure_unsuccessful_delivery_death", 0)) return -5; + + return 0; // passed all tests +} From 8507dd9659369aea50e238b3681412ccbeaa5f52 Mon Sep 17 00:00:00 2001 From: "Mathias L. Baumann" Date: Sun, 17 Apr 2011 12:05:14 +0200 Subject: [PATCH 028/378] started to fix the return values. WIP --- include/psyc/parser.h | 147 +++--------------------------------------- src/parser.c | 102 ++++++++++++++++++++--------- 2 files changed, 82 insertions(+), 167 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index 6b69cb1..6ea5fe8 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -1,6 +1,15 @@ #include #include +enum +{ + PSYC_SUCCESS = 0, + PSYC_INSUFFICIENT = 1, + PSYC_ROUTING = 2, + PSYC_ENTITY = 3, + PSYC_COMPLETE = 4, +}; + typedef struct { @@ -16,6 +25,7 @@ typedef struct char inHeader; unsigned int length; + unsigned int contentLength; } PSYC_State; @@ -48,141 +58,4 @@ inline unsigned int PSYC_getBodyLength (PSYC_State* state) } -/** @brief parses a routerVariable - * - * This function parses one routing variable, - * advances the cursor after the variable, - * writes the variables name, value and their - * lengths in the corresponding out parameters - * and returns 0 or an errorcode. - * - * Note that a return value of 3 does - * not exclude the possibility of - * the variable related parameters being - * filled. - * - * - * @param data pointer to the packet data - * @param dlength length of the data (amount of bytes) - * @param cursor pointer to the current parsing position - * @param name pointer-pointer, used to return the position - * of the name string - * @param nlength pointer to which the length of - * the name string will be written - * @param value pointer-pointer, used to retrun the position - * of the value string - * @param vlength pointer to which the length of - * the value string will be written - * - * @returns 0 on success - * 1 on insufficient data. - * This does not advance - * the cursor. - * 2 when no longer in the header, - * This advances the cursor to the - * body/entity section, but leaves - * the other out parameters invalid. - * 3 the packet is complete. - * >3 on a context error, - * <0 on a parsing error. - * This invalidates all but the cursor - * out paramater. */ -int PSYC_parseHeader( - unsigned int* cursor, - const uint8_t * data, unsigned int dlength, - const uint8_t** name, unsigned int *nlength, - const uint8_t** value, unsigned int *vlength); - -/** @brief parses one variable in two buffers - * - * This function is nearly identical to its - * brother parseHeader. The difference is, - * it uses two buffers and return parameters - * for everything. It is meant to be used - * in case parseHeader returned 2 for - * insufficient data and you don’t - * like to copy memory around to - * have all the data in one buffer. - * Using this function, you can pass two - * data buffers. The consequence is, - * that name and value can be distributed - * on two different buffers and thus need - * also two out paramaters. If only one - * will be used, length of the second - * will be 0. - * - * If your data is spread over more - * than two buffers, you need to - * copy that in one or two buffers. - * Given the unlikleyness of that - * event, we don't offer a three - * or more buffer function here. - * - */ -int PSYC_parseHeader2( - unsigned int* cursor, - const uint8_t * data1, unsigned int dlength1, - const uint8_t * data2, unsigned int dlength2, - const uint8_t** name1, unsigned int *nlength1, - const uint8_t** name2, unsigned int *nlength2, - const uint8_t** value1, unsigned int *vlength1, - const uint8_t** value2, unsigned int *vlength2); - -/** @brief parses one bodyelement - * - * This parses one body element, that is - * either an entity-variable or the method - * - * The function assumes that dlength is set - * to the exact length of the packet - * so that data[dlength-1] would be the - * ending "|" of the packet. - * - * The parameters are nearly the same as for - * PSYC_routerVariable, only difference is - * that a returnvalue of 2 means, we encountered - * the method. - * This means that the out paramterer - * name contains the methodname and - * value the content. - * */ -int PSYC_parseClosedBody( - unsigned int* cursor, - const uint8_t * data, unsigned int dlength, - const uint8_t** name, unsigned int *nlength, - const uint8_t** value, unsigned int *vlength); - -/** @brief parses one bodyelement - * - * This function is nearly identical to - * its brother parseClosedBody. * - * - * It assumes that we don’t know the - * real length of the packet and thus - * searches for the terminator. - */ -int PSYC_parseOpenBody( - unsigned int* cursor, - const uint8_t * data, unsigned int dlength, - const uint8_t** name, unsigned int *nlength, - const uint8_t** value, unsigned int *vlength); - - - -/* @brief parses an bodyelement in two buffers - * - * This function is the borther of parseHeader2. - * It behaives the same as - * parseOpenBody and parseHeader2. */ -int PSYC_parseOpenBody2( - unsigned int* cursor, - const uint8_t * data1, unsigned int dlength1, - const uint8_t * data2, unsigned int dlength2, - const uint8_t** name1, unsigned int *nlength1, - const uint8_t** name2, unsigned int *nlength2, - const uint8_t** value1, unsigned int *vlength1, - const uint8_t** value2, unsigned int *vlength2); - - - diff --git a/src/parser.c b/src/parser.c index 6c35caa..074bef8 100644 --- a/src/parser.c +++ b/src/parser.c @@ -52,7 +52,7 @@ inline int PSYC_parse( { /* first we test if we can access the first char */ if(state->buffer.length<=state->cursor) // cursor is not inside the length - return 1; // return insufficient data. + return PSYC_INSUFFICIENT; // return insufficient data. // in case we return insufficent, we rewind to the start. unsigned int startc=state->cursor; @@ -64,6 +64,32 @@ inline int PSYC_parse( { if(!isGlyph(state->buffer.ptr[state->cursor])) // is the first char not a glyph? { + if(isNumeric(state->buffer.ptr[state->cursor])) + { + if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? + { + state->cursor=startc; // set to start value + return PSYC_INSUFFICIENT; // return insufficient + } + + while(isNumeric(state->buffer.ptr[state->cursor])); + { + state->length = 10 * state->length + state->buffer.ptr[state->cursor] - '0'; + + if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? + { + state->cursor=startc; // set to start value + return PSYC_INSUFFICIENT; // return insufficient + } + } + + // a NL follows the length + if (state->buffer.ptr[state->cursor] != '\n') + { + + } + } + // 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])) @@ -77,7 +103,7 @@ inline int PSYC_parse( if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? { state->cursor=startc; // set to start value - return 1; // return insufficient + return PSYC_INSUFFICIENT; // return insufficient } if(state->buffer.ptr[state->cursor]=='\n') @@ -87,14 +113,15 @@ inline int PSYC_parse( } } return -6; // report error - }else // it is a glyph, so a variable name starts here + } + else // it is a glyph, so a variable name starts here { *modifier = *(state->buffer.ptr+state->cursor); if (state->buffer.length <= ++(state->cursor)) { state->cursor = startc; // rewind to start of line - return 1; // return insufficient + return PSYC_INSUFFICIENT; // return insufficient } name->ptr = state->buffer.ptr + state->cursor; @@ -117,7 +144,7 @@ inline int PSYC_parse( if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? { state->cursor=startc; // set to start value - return 1; // return insufficient + return PSYC_INSUFFICIENT; // return insufficient } if(state->buffer.ptr[state->cursor]=='\n') @@ -142,7 +169,7 @@ inline int PSYC_parse( if (state->buffer.length <= ++(state->cursor)) { state->cursor = startc; // rewind - return 1; // return insufficient + return PSYC_INSUFFICIENT; // return insufficient } name->ptr = state->buffer.ptr+state->cursor; @@ -153,7 +180,7 @@ inline int PSYC_parse( if(state->buffer.length <= ++(state->cursor)) { state->cursor=startc; - return 1; + return PSYC_INSUFFICIENT; } /* what follows is the name. At least one char. @@ -173,7 +200,7 @@ inline int PSYC_parse( if(state->buffer.length<= ++(state->cursor)) // incremented cursor inside lenght? { state->cursor=startc; // set to start value - return 1; // return insufficient + return PSYC_INSUFFICIENT; // return insufficient } // same as bevore @@ -187,7 +214,7 @@ inline int PSYC_parse( /* we now parsed the variable name successfully * after the name either a \n or a \t follows. * - * for the method, the state->buffer.ptr starts after an \n + * for the method, the data starts after an \n * so checking for \n too here * We dont check if cursor inside length, because @@ -195,24 +222,24 @@ inline int PSYC_parse( */ if(state->buffer.ptr[state->cursor] == '\t' || state->buffer.ptr[state->cursor] == '\n') // && method==1)) { - /* after the \t the arg-state->buffer.ptr follows, which is - * anything but \n. arg-state->buffer.ptr can be of length 0 + /* after the \t the data follows, which is + * anything but \n. data can be of length 0 * - * for the method: after the \n state->buffer.ptr follows, + * for the method: after the \n data follows, * which is anything but \n|\n * - * but state->buffer.ptr is optional, so we first check - * here if state->buffer.ptr follows at all. + * but data is optional, so we first check + * here if data follows at all. * - * arg-state->buffer.ptr=value->ptr. we set value here so it + * arg-data=value. we set value here so it * points to a valid range and so we point - * to the first potential arg-state->buffer.ptr byte. - * If there is no arg-state->buffer.ptr, we still have + * 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 state->buffer.ptr */ ) + state->buffer.ptr[state->cursor+2] == '\n') /*no data */ ) { value->ptr=state->buffer.ptr+state->cursor; value->length=0; @@ -220,9 +247,19 @@ inline int PSYC_parse( else { value->ptr=state->buffer.ptr+state->cursor+1; - if (1==state->length) // we know the length of the packet + if (0 != state->length) // we know the length of the packet { - value->length= state->buffer.length - state->cursor -3; + // is the packet in the buffer? + if (value->ptr + state->length + 3 > state->buffer.ptr + state->buffer.length) + { // no + value->length = state->buffer.length - state->cursor; + *expectedBytes = state->length - value->length; + } + else // yes, the packet is complete in the buffer. + { + value->length= state->buffer.length - state->cursor -3; + *expectedBytes = 0; + } } else // else search for the terminator { @@ -233,7 +270,7 @@ inline int PSYC_parse( if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? { state->cursor=startc; // set to start value - return 1; // return insufficient + return PSYC_INSUFFICIENT ; // return insufficient } if(0 == method && state->buffer.ptr[state->cursor] == '\n') @@ -244,7 +281,7 @@ inline int PSYC_parse( if(state->buffer.length<=(state->cursor)+2) // incremented cursor inside lenght? { state->cursor=startc; // set to start value - return 1; // return insufficient + return PSYC_INSUFFICIENT; // return insufficient } if(state->buffer.ptr[state->cursor+1] == '|') @@ -260,14 +297,15 @@ inline int PSYC_parse( } } } - }else if(state->inHeader == 0 && method==0 && state->buffer.ptr[state->cursor] == ' ') // oi, its a binary var! + } + else if(state->inHeader == 0 && method==0 && state->buffer.ptr[state->cursor] == ' ') // oi, its a binary var! { // after SP the length follows. unsigned int binLength= 0; if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? { state->cursor=startc; // set to start value - return 1; // return insufficient + return PSYC_INSUFFICIENT; // return insufficient } while(isNumeric(state->buffer.ptr[state->cursor])); @@ -277,7 +315,7 @@ inline int PSYC_parse( if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? { state->cursor=startc; // set to start value - return 1; // return insufficient + return PSYC_INSUFFICIENT; // return insufficient } } // after the length a TAB follows @@ -288,7 +326,7 @@ inline int PSYC_parse( if(state->buffer.length <= state->cursor+binLength+1 ) { state->cursor=startc; - return 1; + return PSYC_INSUFFICIENT; } value->ptr = state->buffer.ptr + state->cursor+1; @@ -321,7 +359,7 @@ inline int PSYC_parse( if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? { state->cursor=startc; // set to start value - return 1; // return insufficient + return PSYC_INSUFFICIENT; // return insufficient } if(1 == state->inHeader && state->buffer.ptr[state->cursor] == '\n') @@ -332,12 +370,16 @@ inline int PSYC_parse( } if(state->buffer.ptr[state->cursor] != '|') // no pipe, then only line complete, not the packet. - return 0; - + { + if (state->inHeader == 1) + return PSYC_ROUTING; + else + return PSYC_ENTITY; + } if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? { state->cursor=startc; // set to start value - return 1; // return insufficient + return PSYC_INSUFFICIENT; // return insufficient } if(state->buffer.ptr[state->cursor] != '\n') return -4; From c4ffec80c41d5c7abd48015d5c5c3d9b2570766b Mon Sep 17 00:00:00 2001 From: Marenz Date: Sun, 17 Apr 2011 12:56:24 +0200 Subject: [PATCH 029/378] added flag for parsing header only --- include/psyc/parser.h | 15 ++++++++++++++- src/parser.c | 14 +++++++++----- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index 6ea5fe8..009563a 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -1,13 +1,20 @@ #include #include -enum +enum PSYC_Flags +{ + PSYC_HEADER_ONLY = 1 +}; + + +enum PSYC_ReturnCodes { PSYC_SUCCESS = 0, PSYC_INSUFFICIENT = 1, PSYC_ROUTING = 2, PSYC_ENTITY = 3, PSYC_COMPLETE = 4, + PSYC_HEADER_COMPLETE = 5, }; @@ -36,6 +43,12 @@ inline PSYC_Array PSYC_CreateArray (uint8_t* const memory, unsigned int length) return arr; } +inline void PSYC_initState2 (PSYC_State* state, uint8_t flags ) +{ + memset(state, 0, sizeof(PSYC_State)); + state->flags = flags; +} + inline void PSYC_initState (PSYC_State* state) { memset(state, 0, sizeof(PSYC_State)); diff --git a/src/parser.c b/src/parser.c index 074bef8..31814d8 100644 --- a/src/parser.c +++ b/src/parser.c @@ -50,6 +50,7 @@ inline int PSYC_parse( PSYC_Array* name, PSYC_Array* value, uint8_t* modifier, unsigned long* expectedBytes) { +start: /* first we test if we can access the first char */ if(state->buffer.length<=state->cursor) // cursor is not inside the length return PSYC_INSUFFICIENT; // return insufficient data. @@ -95,7 +96,10 @@ inline int PSYC_parse( if(isAlphaNumeric(state->buffer.ptr[state->cursor])) { state->inHeader = 0; - return 2; // return header finished + if (state->flags & PSYC_HEADER_ONLY) + return PSYC_HEADER_COMPLETE; // return header finished + else + goto start; } if(state->buffer.ptr[state->cursor] == '|') @@ -109,7 +113,7 @@ inline int PSYC_parse( if(state->buffer.ptr[state->cursor]=='\n') { ++(state->cursor); - return 3; // return packet finished + return PSYC_COMPLETE; // return packet finished } } return -6; // report error @@ -150,7 +154,7 @@ inline int PSYC_parse( if(state->buffer.ptr[state->cursor]=='\n') { ++(state->cursor); - return 3; // return packet finished + return PSYC_COMPLETE; // return packet finished } } return -5; // report error @@ -289,7 +293,7 @@ inline int PSYC_parse( { /* packet finishes here */ state->cursor+=3; - return 3; + return PSYC_COMPLETE; } } @@ -385,6 +389,6 @@ inline int PSYC_parse( return -4; state->cursor+=1; - return 3; // packet is complete + return PSYC_COMPLETE; // packet is complete } From 9178516d81854b606f77799f56fb14220b2f8088 Mon Sep 17 00:00:00 2001 From: Marenz Date: Sun, 17 Apr 2011 13:25:06 +0200 Subject: [PATCH 030/378] updated testparser to work with the new api. Debugging time now --- include/psyc/parser.h | 24 +++++----- src/Makefile | 2 +- src/parser.c | 2 +- src/tests/Makefile | 2 +- src/tests/parser/testParser.c | 83 +++++++++++++---------------------- 5 files changed, 46 insertions(+), 67 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index 009563a..58ea653 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -9,12 +9,12 @@ enum PSYC_Flags enum PSYC_ReturnCodes { - PSYC_SUCCESS = 0, - PSYC_INSUFFICIENT = 1, - PSYC_ROUTING = 2, - PSYC_ENTITY = 3, - PSYC_COMPLETE = 4, - PSYC_HEADER_COMPLETE = 5, + PSYC_METHOD = 1, + PSYC_INSUFFICIENT, + PSYC_ROUTING, + PSYC_ENTITY, + PSYC_COMPLETE, + PSYC_HEADER_COMPLETE, }; @@ -35,7 +35,7 @@ typedef struct unsigned int contentLength; } PSYC_State; - +#ifndef PSYC_COMPILE_LIBRARY inline PSYC_Array PSYC_CreateArray (uint8_t* const memory, unsigned int length) { PSYC_Array arr = {length, memory}; @@ -60,15 +60,15 @@ inline void PSYC_nextBuffer (PSYC_State* state, PSYC_Array newBuf) } -inline int PSYC_parse(PSYC_State* state, - PSYC_Array* name, PSYC_Array* value, - uint8_t* modifier, unsigned long *expectedBytes); - inline unsigned int PSYC_getBodyLength (PSYC_State* state) { return state->length; } - +#endif + +int PSYC_parse(PSYC_State* state, + PSYC_Array* name, PSYC_Array* value, + uint8_t* modifier, unsigned long *expectedBytes); diff --git a/src/Makefile b/src/Makefile index 10a5e93..1bfc194 100644 --- a/src/Makefile +++ b/src/Makefile @@ -12,7 +12,7 @@ diet: /opt/diet/bin/diet ar rcs libpsyc.a $O lib: $S - ${CC} -static -c -Os $S -lc -DDEBUG + ${CC} -static -c -Os $S -lc -DDEBUG -DPSYC_COMPILE_LIBRARY ar rcs libpsyc.a $O match: match.c diff --git a/src/parser.c b/src/parser.c index 31814d8..4b4628d 100644 --- a/src/parser.c +++ b/src/parser.c @@ -87,7 +87,7 @@ start: // a NL follows the length if (state->buffer.ptr[state->cursor] != '\n') { - + return -10; } } diff --git a/src/tests/Makefile b/src/tests/Makefile index 554c76e..e36efe4 100644 --- a/src/tests/Makefile +++ b/src/tests/Makefile @@ -2,7 +2,7 @@ CFLAGS=-I.. -DDEBUG LDFLAGS=-L.. -lpsyc works: - cc -I.. -DDEBUG -L.. testParser.c -o testParser -lpsyc + cc -I../../include -DDEBUG -L.. parser/testParser.c -o testParser -lpsyc it: testParser diff --git a/src/tests/parser/testParser.c b/src/tests/parser/testParser.c index 8c40ab4..2939f64 100644 --- a/src/tests/parser/testParser.c +++ b/src/tests/parser/testParser.c @@ -1,11 +1,11 @@ -#include +#include #include #include #include int main(int argc, char** argv) { - const uint8_t buffer[2048]; + uint8_t buffer[2048]; int index; int file = open(argv[1],O_RDONLY); @@ -13,61 +13,40 @@ int main(int argc, char** argv) return -1; index = read(file,(void*)buffer,sizeof(buffer)); + + PSYC_State state; + PSYC_initState(&state); + unsigned int cursor=0,tmp=0; - while(cursor < index) + 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, &expectedBytes)) { - int ret; - const uint8_t *varname,*varvalue; - unsigned int nl,vl; - // try parsing that now - while((ret=PSYC_parseHeader( - &cursor, - buffer,index, - &varname,&nl, - &varvalue,&vl)) == 0) + switch (ret) { - write(0,varname,nl); - write(0," = ",3); - write(0,varvalue,vl); - write(0,"\n",1); - } - printf("ret0: %d\ncursor0: %d\n", - ret,cursor); - - if(ret == 3 || ret == 2) - { - write(0,varname,nl); - write(0," = ",3); - write(0,varvalue,vl); - write(0,"\n",1); - } - if(ret ==2) // header finished - while((ret=PSYC_parseOpenBody( - &cursor, - buffer,index, - &varname,&nl, - &varvalue,&vl)) == 0) - { - write(0,varname,nl); - write(0," = ",3); - write(0,varvalue,vl); - write(0,"\n",1); + case PSYC_ROUTING: + case PSYC_ENTITY: + case PSYC_METHOD: + write(0,&modifier,1); + write(0,name.ptr, name.length); + write(0," = ", 3); + write(0,value.ptr, value.length); + write(0,"\n", 1); + break; + case PSYC_COMPLETE: + write(0, "Done parsing.\n", 15); + continue; + default: + printf("Error while parsing: %i\n", ret); + return; } - if(ret == 3 || ret == 2) - { - write(0,varname,nl); - write(0," = ",3); - write(0,varvalue,vl); - write(0,"\n",1); - } - - if(tmp != cursor) - tmp=cursor; - else - return 1; - printf("ret: %d\ncursor: %d\n--------\n", - ret,cursor); } return 0; From eecbdc001cf0f51497f31e7c622c55cacf3d531b Mon Sep 17 00:00:00 2001 From: Marenz Date: Sun, 17 Apr 2011 13:59:07 +0200 Subject: [PATCH 031/378] ready for testing now. --- include/psyc/parser.h | 4 +- src/Makefile | 2 +- src/parser.c | 90 +++++++++++++++++++++++++------------------ src/tests/Makefile | 2 +- 4 files changed, 55 insertions(+), 43 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index 58ea653..467fc8b 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -30,7 +30,7 @@ typedef struct PSYC_Array buffer; uint8_t flags; - char inHeader; + char inBody; unsigned int length; unsigned int contentLength; } PSYC_State; @@ -59,8 +59,6 @@ inline void PSYC_nextBuffer (PSYC_State* state, PSYC_Array newBuf) state->buffer = newBuf; } - - inline unsigned int PSYC_getBodyLength (PSYC_State* state) { return state->length; diff --git a/src/Makefile b/src/Makefile index 1bfc194..08a36c7 100644 --- a/src/Makefile +++ b/src/Makefile @@ -12,7 +12,7 @@ diet: /opt/diet/bin/diet ar rcs libpsyc.a $O lib: $S - ${CC} -static -c -Os $S -lc -DDEBUG -DPSYC_COMPILE_LIBRARY + ${CC} -static -c -g -O0 $S -lc -DDEBUG -DPSYC_COMPILE_LIBRARY ar rcs libpsyc.a $O match: match.c diff --git a/src/parser.c b/src/parser.c index 4b4628d..dfdc901 100644 --- a/src/parser.c +++ b/src/parser.c @@ -61,7 +61,7 @@ start: /* 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(1==state->inHeader) + if(0==state->inBody) { if(!isGlyph(state->buffer.ptr[state->cursor])) // is the first char not a glyph? { @@ -95,7 +95,7 @@ start: // is complete(empty packet) or that the method started. if(isAlphaNumeric(state->buffer.ptr[state->cursor])) { - state->inHeader = 0; + state->inBody = 1; if (state->flags & PSYC_HEADER_ONLY) return PSYC_HEADER_COMPLETE; // return header finished else @@ -113,6 +113,7 @@ start: if(state->buffer.ptr[state->cursor]=='\n') { ++(state->cursor); + state->inBody = 0; return PSYC_COMPLETE; // return packet finished } } @@ -130,55 +131,62 @@ start: name->ptr = state->buffer.ptr + state->cursor; - name->length = 0; + name->length = 1; } - } + } // endif inBody=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(0==state->inHeader && !isGlyph(state->buffer.ptr[state->cursor])) + if(1==state->inBody) { - if(!isAlphaNumeric(state->buffer.ptr[state->cursor]) && state->buffer.ptr[state->cursor] != '_') + 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(!isAlphaNumeric(state->buffer.ptr[state->cursor]) && state->buffer.ptr[state->cursor] != '_') { - if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? + // the body rule is optional, which means + // that now also just |\n can follow. + if(state->buffer.ptr[state->cursor] == '|') { - state->cursor=startc; // set to start value - return PSYC_INSUFFICIENT; // return insufficient - } + if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? + { + state->cursor=startc; // set to start value + return PSYC_INSUFFICIENT; // return insufficient + } - if(state->buffer.ptr[state->cursor]=='\n') - { - ++(state->cursor); - return PSYC_COMPLETE; // return packet finished + if(state->buffer.ptr[state->cursor]=='\n') + { + ++(state->cursor); + state->inBody = 0; + return PSYC_COMPLETE; // return packet finished + } } + return -5; // report error + } + else + { + name->ptr = state->buffer.ptr+state->cursor; + name->length=1; + method=1; } - return -5; // report error } else { + *modifier = *(state->buffer.ptr+state->cursor); + + if (state->buffer.length <= ++(state->cursor)) + { + state->cursor = startc; // rewind + return PSYC_INSUFFICIENT; // return insufficient + } + 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 - } - - name->ptr = state->buffer.ptr+state->cursor; - name->length=1; - } /* validate the incremented cursor */ if(state->buffer.length <= ++(state->cursor)) @@ -293,6 +301,7 @@ start: { /* packet finishes here */ state->cursor+=3; + state->inBody = 0; return PSYC_COMPLETE; } @@ -302,7 +311,7 @@ start: } } } - else if(state->inHeader == 0 && method==0 && state->buffer.ptr[state->cursor] == ' ') // oi, its a binary var! + else if(state->inBody == 1 && method==0 && state->buffer.ptr[state->cursor] == ' ') // oi, its a binary var! { // after SP the length follows. unsigned int binLength= 0; @@ -344,7 +353,7 @@ start: /* if there was a \t, then we parsed up until the - * \n char from the simple-arg rule ( \t arg-state->buffer.ptr \n ) + * \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. @@ -366,16 +375,20 @@ start: return PSYC_INSUFFICIENT; // return insufficient } - if(1 == state->inHeader && state->buffer.ptr[state->cursor] == '\n') + if(0 == state->inBody && state->buffer.ptr[state->cursor] == '\n') { state->cursor+=1; - state->inHeader = 0; - return 2; // line is complete, but body starts now. + state->inBody = 1; + + if (state->flags & PSYC_HEADER_ONLY) + return PSYC_HEADER_COMPLETE; // return header finished + else + goto start; } if(state->buffer.ptr[state->cursor] != '|') // no pipe, then only line complete, not the packet. { - if (state->inHeader == 1) + if (state->inBody == 0) return PSYC_ROUTING; else return PSYC_ENTITY; @@ -389,6 +402,7 @@ start: return -4; state->cursor+=1; + state->inBody = 0; return PSYC_COMPLETE; // packet is complete } diff --git a/src/tests/Makefile b/src/tests/Makefile index e36efe4..1afe909 100644 --- a/src/tests/Makefile +++ b/src/tests/Makefile @@ -2,7 +2,7 @@ CFLAGS=-I.. -DDEBUG LDFLAGS=-L.. -lpsyc works: - cc -I../../include -DDEBUG -L.. parser/testParser.c -o testParser -lpsyc + cc -I../../include -g -O0 -DDEBUG -L.. parser/testParser.c -o testParser -lpsyc it: testParser From 9bb144b9ac9c5833d0a394c9c0df86905e3cd488 Mon Sep 17 00:00:00 2001 From: Marenz Date: Sun, 17 Apr 2011 14:22:01 +0200 Subject: [PATCH 032/378] fixed a bug --- src/parser.c | 7 ++----- src/tests/parser/testParser.c | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/parser.c b/src/parser.c index dfdc901..23e505d 100644 --- a/src/parser.c +++ b/src/parser.c @@ -321,7 +321,7 @@ start: return PSYC_INSUFFICIENT; // return insufficient } - while(isNumeric(state->buffer.ptr[state->cursor])); + while(isNumeric(state->buffer.ptr[state->cursor])) { binLength = 10 * binLength + state->buffer.ptr[state->cursor] - '0'; @@ -380,10 +380,7 @@ start: state->cursor+=1; state->inBody = 1; - if (state->flags & PSYC_HEADER_ONLY) - return PSYC_HEADER_COMPLETE; // return header finished - else - goto start; + return PSYC_ROUTING; // return header finished } if(state->buffer.ptr[state->cursor] != '|') // no pipe, then only line complete, not the packet. diff --git a/src/tests/parser/testParser.c b/src/tests/parser/testParser.c index 2939f64..773f831 100644 --- a/src/tests/parser/testParser.c +++ b/src/tests/parser/testParser.c @@ -32,8 +32,8 @@ int main(int argc, char** argv) { case PSYC_ROUTING: case PSYC_ENTITY: - case PSYC_METHOD: write(0,&modifier,1); + case PSYC_METHOD: write(0,name.ptr, name.length); write(0," = ", 3); write(0,value.ptr, value.length); From 890c2ad78d6ecd2759d4813d2fc484a0aafeaded Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sun, 17 Apr 2011 14:17:11 +0200 Subject: [PATCH 033/378] makefile fixes; gitignore --- src/.gitignore | 3 +++ src/Makefile | 4 ++-- src/tests/Makefile | 2 ++ 3 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 src/.gitignore diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 0000000..b96ae54 --- /dev/null +++ b/src/.gitignore @@ -0,0 +1,3 @@ +*.o +*.a +tests/testParser diff --git a/src/Makefile b/src/Makefile index 08a36c7..5695fa1 100644 --- a/src/Makefile +++ b/src/Makefile @@ -8,8 +8,8 @@ default: @/bin/echo -e "Usage:\n\tmake diet - compile with diet libc\n\tmake lib - compile with normal gnu libc" diet: - /opt/diet/bin/diet ${CC} -static -c -Os $S -DDEBUG - /opt/diet/bin/diet ar rcs libpsyc.a $O + diet ${CC} -static -c -Os $S -DDEBUG -DPSYC_COMPILE_LIBRARY + diet ar rcs libpsyc.a $O lib: $S ${CC} -static -c -g -O0 $S -lc -DDEBUG -DPSYC_COMPILE_LIBRARY diff --git a/src/tests/Makefile b/src/tests/Makefile index 1afe909..bd38e3c 100644 --- a/src/tests/Makefile +++ b/src/tests/Makefile @@ -6,3 +6,5 @@ works: it: testParser +test: + for f in parser/*txt; do echo -e "\n>> $$f"; ./testParser $$f; done From f1c03b463e125869e6e34809563cacfe5a9dd353 Mon Sep 17 00:00:00 2001 From: Marenz Date: Sun, 17 Apr 2011 14:47:25 +0200 Subject: [PATCH 034/378] added some documentation --- include/psyc/parser.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index 467fc8b..0e49b7e 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -36,13 +36,22 @@ typedef struct } PSYC_State; #ifndef PSYC_COMPILE_LIBRARY +/* @brief shortcut for creating an array + * + * @param memory pointer to the buffer + * @param length length of that buffer + * + * @returns an instance of the PSYC_Array struct */ inline PSYC_Array PSYC_CreateArray (uint8_t* const memory, unsigned int length) { PSYC_Array arr = {length, memory}; return arr; } - +/* @brief 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, se PSYC_Flags */ inline void PSYC_initState2 (PSYC_State* state, uint8_t flags ) { memset(state, 0, sizeof(PSYC_State)); From 1c9d85eec9483961597d0b171cd61da2372951c1 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Sun, 17 Apr 2011 21:25:52 +0200 Subject: [PATCH 035/378] + --- src/tests/parser/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/parser/Makefile b/src/tests/parser/Makefile index e6cf706..bdbf145 100644 --- a/src/tests/parser/Makefile +++ b/src/tests/parser/Makefile @@ -1,5 +1,5 @@ parser: - $(DIETLIB) cc -L../.. -I../.. -DDEBUG -lpsyc testParser.c -lpsyc -o testParser + $(DIETLIB) cc -L../.. -I../../../include -DDEBUG -lpsyc testParser.c -lpsyc -o testParser diet: DIETLIB=/opt/diet/bin/diet make parser From e3192d3c12cfaab84a34e5764bdc6524030f8399 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Sun, 17 Apr 2011 21:46:00 +0200 Subject: [PATCH 036/378] + --- src/tests/Makefile | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/tests/Makefile b/src/tests/Makefile index bd38e3c..3ccdd4a 100644 --- a/src/tests/Makefile +++ b/src/tests/Makefile @@ -1,10 +1,16 @@ -CFLAGS=-I.. -DDEBUG -LDFLAGS=-L.. -lpsyc +CFLAGS=-I../../include -DDEBUG -g -O0 +LDFLAGS=-L.. +LOADLIBES=-lpsyc +TARGETS=testParser testMatch -works: - cc -I../../include -g -O0 -DDEBUG -L.. parser/testParser.c -o testParser -lpsyc +all: $(TARGETS) -it: testParser +# 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 + +clean: + rm $(TARGETS) From 33d4896e0a5a4d5a10f05a601ad1beb30ce0b36d Mon Sep 17 00:00:00 2001 From: Marenz Date: Mon, 18 Apr 2011 10:09:35 +0200 Subject: [PATCH 037/378] commiting broken state --- include/psyc/parser.h | 37 +++++++--- src/parser.c | 129 +++++++++++++++++++++------------- src/tests/parser/testParser.c | 4 +- 3 files changed, 108 insertions(+), 62 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index 0e49b7e..a419107 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -9,12 +9,14 @@ enum PSYC_Flags enum PSYC_ReturnCodes { - PSYC_METHOD = 1, + PSYC_ERROR_EXPECTED_TAB = -8, + PSYC_BODY = 1, + PSYC_BODY_INCOMPLETE, PSYC_INSUFFICIENT, PSYC_ROUTING, PSYC_ENTITY, - PSYC_COMPLETE, - PSYC_HEADER_COMPLETE, + PSYC_ENTITY_INCOMPLETE, + PSYC_HEADER_DONE, }; @@ -24,14 +26,16 @@ typedef struct const uint8_t * ptr; } PSYC_Array; + typedef struct { unsigned int cursor; // current position in buffer PSYC_Array buffer; uint8_t flags; - char inBody; - unsigned int length; + unsigned int contentParsed; // + char inContent; + unsigned int valueRemaining; unsigned int contentLength; } PSYC_State; @@ -42,22 +46,26 @@ typedef struct * @param length length of that buffer * * @returns an instance of the PSYC_Array struct */ -inline PSYC_Array PSYC_CreateArray (uint8_t* const memory, unsigned int length) +inline PSYC_Array PSYC_createArray (uint8_t* const memory, unsigned int length) { PSYC_Array arr = {length, memory}; return arr; } + /* @brief 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, se PSYC_Flags */ + * @param flags the flags that one ones to set, see PSYC_Flags */ inline void PSYC_initState2 (PSYC_State* state, uint8_t flags ) { memset(state, 0, sizeof(PSYC_State)); state->flags = flags; } +/* @brief initiates the state struct + * + * @param state pointer to the state struct that should be initiated */ inline void PSYC_initState (PSYC_State* state) { memset(state, 0, sizeof(PSYC_State)); @@ -66,16 +74,23 @@ inline void PSYC_initState (PSYC_State* state) inline void PSYC_nextBuffer (PSYC_State* state, PSYC_Array newBuf) { state->buffer = newBuf; + state->cursor = 0; } -inline unsigned int PSYC_getBodyLength (PSYC_State* state) +inline unsigned int PSYC_getContentLength (PSYC_State* s) { - return state->length; + return s->contentLength; } + +inline unsigned int PSYC_getValueRemaining (PSYC_State* s) +{ + return s->valueRemaining; +} + #endif int PSYC_parse(PSYC_State* state, - PSYC_Array* name, PSYC_Array* value, - uint8_t* modifier, unsigned long *expectedBytes); + uint8_t* modifier, PSYC_Array* name, PSYC_Array* value, + unsigned long* bytesParsed, unsigned long *bytesExpected); diff --git a/src/parser.c b/src/parser.c index 23e505d..4eaa233 100644 --- a/src/parser.c +++ b/src/parser.c @@ -47,10 +47,13 @@ inline char isAlphaNumeric(uint8_t c) /** @brief generalized linebased parser */ inline int PSYC_parse( PSYC_State* state, - PSYC_Array* name, PSYC_Array* value, - uint8_t* modifier, unsigned long* expectedBytes) + uint8_t* modifier, PSYC_Array* name, PSYC_Array* value) { start: + + if (state->valueRemaining != 0) + goto binaryArg; + /* first we test if we can access the first char */ if(state->buffer.length<=state->cursor) // cursor is not inside the length return PSYC_INSUFFICIENT; // return insufficient data. @@ -58,16 +61,19 @@ start: // 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->inBody) + if(0==state->inContent) { 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 lenght? + if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length? { state->cursor=startc; // set to start value return PSYC_INSUFFICIENT; // return insufficient @@ -75,45 +81,51 @@ start: while(isNumeric(state->buffer.ptr[state->cursor])); { - state->length = 10 * state->length + state->buffer.ptr[state->cursor] - '0'; + state->contentLength = 10 * state->contentLength + state->buffer.ptr[state->cursor] - '0'; - if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? + if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length? { state->cursor=startc; // set to start value return PSYC_INSUFFICIENT; // return insufficient } } + } + // header ends with a NL + if (state->buffer.ptr[state->cursor] != '\n') + { + return -10; + } - // a NL follows the length - if (state->buffer.ptr[state->cursor] != '\n') - { - return -10; - } + if (state->buffer.length<=++(state->cursor)) // incremented cursor inside length? + { + 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])) + if (isAlphaNumeric(state->buffer.ptr[state->cursor])) { - state->inBody = 1; + state->inContent = 1; + if (state->flags & PSYC_HEADER_ONLY) return PSYC_HEADER_COMPLETE; // return header finished else goto start; } - if(state->buffer.ptr[state->cursor] == '|') + if (state->buffer.ptr[state->cursor] == '|') { - if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? + 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') + if (state->buffer.ptr[state->cursor]=='\n') { ++(state->cursor); - state->inBody = 0; + state->inContent = 0; return PSYC_COMPLETE; // return packet finished } } @@ -121,6 +133,10 @@ start: } 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)) @@ -133,7 +149,7 @@ start: name->length = 1; } - } // endif inBody=0 + } // endif inContent=0 char method=0; /* each line of the header starts with a glyph. @@ -141,7 +157,7 @@ start: * 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->inBody) + if(1==state->inContent) { if(!isGlyph(state->buffer.ptr[state->cursor])) { @@ -151,7 +167,7 @@ start: // that now also just |\n can follow. if(state->buffer.ptr[state->cursor] == '|') { - if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? + if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length? { state->cursor=startc; // set to start value return PSYC_INSUFFICIENT; // return insufficient @@ -160,7 +176,7 @@ start: if(state->buffer.ptr[state->cursor]=='\n') { ++(state->cursor); - state->inBody = 0; + state->inContent = 0; return PSYC_COMPLETE; // return packet finished } } @@ -209,7 +225,7 @@ start: unsigned int i=0; while(1) { - if(state->buffer.length<= ++(state->cursor)) // incremented cursor inside lenght? + if(state->buffer.length<= ++(state->cursor)) // incremented cursor inside length? { state->cursor=startc; // set to start value return PSYC_INSUFFICIENT; // return insufficient @@ -259,13 +275,13 @@ start: else { value->ptr=state->buffer.ptr+state->cursor+1; - if (0 != state->length) // we know the length of the packet + if (0 != state->contentLength) // we know the length of the packet { // is the packet in the buffer? - if (value->ptr + state->length + 3 > state->buffer.ptr + state->buffer.length) + if (value->ptr + state->contentLength + 3 > state->buffer.ptr + state->buffer.length) { // no value->length = state->buffer.length - state->cursor; - *expectedBytes = state->length - value->length; + *expectedBytes = state->contentLength - value->length; } else // yes, the packet is complete in the buffer. { @@ -279,7 +295,7 @@ start: while (1) { - if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? + if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length? { state->cursor=startc; // set to start value return PSYC_INSUFFICIENT ; // return insufficient @@ -290,7 +306,7 @@ start: if(1 == method && state->buffer.ptr[state->cursor] == '\n') { - if(state->buffer.length<=(state->cursor)+2) // incremented cursor inside lenght? + if(state->buffer.length<=(state->cursor)+2) // incremented cursor inside length? { state->cursor=startc; // set to start value return PSYC_INSUFFICIENT; // return insufficient @@ -301,7 +317,7 @@ start: { /* packet finishes here */ state->cursor+=3; - state->inBody = 0; + state->inContent = 0; return PSYC_COMPLETE; } @@ -311,11 +327,9 @@ start: } } } - else if(state->inBody == 1 && method==0 && state->buffer.ptr[state->cursor] == ' ') // oi, its a binary var! + else if(state->inContent == 1 && method==0 && state->buffer.ptr[state->cursor] == ' ') // oi, its a binary var! { // after SP the length follows. - unsigned int binLength= 0; - - if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? + if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length? { state->cursor=startc; // set to start value return PSYC_INSUFFICIENT; // return insufficient @@ -323,9 +337,9 @@ start: while(isNumeric(state->buffer.ptr[state->cursor])) { - binLength = 10 * binLength + state->buffer.ptr[state->cursor] - '0'; + value->length = 10 * value->length + state->buffer.ptr[state->cursor] - '0'; - if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? + if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length? { state->cursor=startc; // set to start value return PSYC_INSUFFICIENT; // return insufficient @@ -333,18 +347,35 @@ start: } // after the length a TAB follows if (state->buffer.ptr[state->cursor] != '\t') - return -8; + return PSYC_ERROR_EXPECTED_TAB; - // is the length still in this buffer? - if(state->buffer.length <= state->cursor+binLength+1 ) +binaryArg: + if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length? { - state->cursor=startc; - return PSYC_INSUFFICIENT; + state->valueRemaining = value->length - state->cursor; + state->cursor=0; + + value->length = 0; + value->ptr = state->buffer.ptr; + + return PSYC_ENTITY_INCOMPLETE; } - value->ptr = state->buffer.ptr + state->cursor+1; - value->length=binLength; - state->cursor += binLength+1; + // 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; @@ -369,28 +400,28 @@ start: /* 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 lenght? + 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->inBody && state->buffer.ptr[state->cursor] == '\n') + if(0 == state->inContent && state->buffer.ptr[state->cursor] == '\n') { state->cursor+=1; - state->inBody = 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->inBody == 0) + if (state->inContent == 0) return PSYC_ROUTING; else return PSYC_ENTITY; } - if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? + if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length? { state->cursor=startc; // set to start value return PSYC_INSUFFICIENT; // return insufficient @@ -399,7 +430,7 @@ start: return -4; state->cursor+=1; - state->inBody = 0; + state->inContent = 0; return PSYC_COMPLETE; // packet is complete } diff --git a/src/tests/parser/testParser.c b/src/tests/parser/testParser.c index 773f831..e224783 100644 --- a/src/tests/parser/testParser.c +++ b/src/tests/parser/testParser.c @@ -23,10 +23,10 @@ int main(int argc, char** argv) int ret; PSYC_Array name, value; - PSYC_nextBuffer(&state, PSYC_CreateArray(buffer, index)); + PSYC_nextBuffer(&state, PSYC_createArray(buffer, index)); // try parsing that now - while(ret=PSYC_parse(&state, &name, &value, &modifier, &expectedBytes)) + while(ret=PSYC_parse(&state, &name, &value, &modifier)) { switch (ret) { From 561174798f10e597149622dce4a96d1d885725aa Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 18 Apr 2011 13:27:48 +0200 Subject: [PATCH 038/378] compiles again --- .gitignore | 6 ++++++ include/psyc/parser.h | 8 +++----- src/.gitignore | 3 --- src/parser.c | 4 ++-- 4 files changed, 11 insertions(+), 10 deletions(-) create mode 100644 .gitignore delete mode 100644 src/.gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2042c95 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.* +*~ +\#* +*.o +*.a +src/tests/testParser diff --git a/include/psyc/parser.h b/include/psyc/parser.h index a419107..c1b9435 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -16,7 +16,8 @@ enum PSYC_ReturnCodes PSYC_ROUTING, PSYC_ENTITY, PSYC_ENTITY_INCOMPLETE, - PSYC_HEADER_DONE, + PSYC_HEADER_COMPLETE, + PSYC_COMPLETE, }; @@ -90,7 +91,4 @@ inline unsigned int PSYC_getValueRemaining (PSYC_State* s) #endif int PSYC_parse(PSYC_State* state, - uint8_t* modifier, PSYC_Array* name, PSYC_Array* value, - unsigned long* bytesParsed, unsigned long *bytesExpected); - - + uint8_t* modifier, PSYC_Array* name, PSYC_Array* value); diff --git a/src/.gitignore b/src/.gitignore deleted file mode 100644 index b96ae54..0000000 --- a/src/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*.o -*.a -tests/testParser diff --git a/src/parser.c b/src/parser.c index 4eaa233..ba7c209 100644 --- a/src/parser.c +++ b/src/parser.c @@ -281,12 +281,12 @@ start: 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; + //*expectedBytes = state->contentLength - value->length; } else // yes, the packet is complete in the buffer. { value->length= state->buffer.length - state->cursor -3; - *expectedBytes = 0; + //*expectedBytes = 0; } } else // else search for the terminator From 7a90de0ad1a27c03b85965847dbfc01a13067e13 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Mon, 18 Apr 2011 14:46:57 +0200 Subject: [PATCH 039/378] + --- .gitignore | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3910d12 --- /dev/null +++ b/.gitignore @@ -0,0 +1,21 @@ +CVS +.config +~$* +.DS_Store +.metadata +.actionScriptProperties +.#* +*~ +*.o +*.swf +*.swp +*.rej +*.log +*.pem +*old +*bak +*diff +*orig +src/match +src/tests/parser/testParser +src/tests/testMatch From e7772acb029d18b7b5079d0117560580d836eb32 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Mon, 18 Apr 2011 16:51:54 +0200 Subject: [PATCH 040/378] definition of PSYC_text() --- include/psyc.h | 28 ++++++++++++++++++++++++++++ src/match.c | 3 +++ src/render.c | 1 + src/text.c | 2 ++ 4 files changed, 34 insertions(+) create mode 100644 src/render.c create mode 100644 src/text.c diff --git a/include/psyc.h b/include/psyc.h index 040509d..f41c8a2 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -8,3 +8,31 @@ int PSYC_matches(uint8_t* sho, unsigned int slen, uint8_t* lon, unsigned int llen); +/** @brief Callback for PSYC_text() that produces a value for a match + * + * The application looks up a match such as _fruit from [_fruit] and + * if found writes its current value from its variable store into the + * outgoing buffer.. "Apple" for example. The template returns the + * number of bytes written. 0 is a legal return value. Should the + * callback return -1, PSYC_text leaves the original template text as is. + */ +typedef int (*PSYC_textCB)(uint8_t* match, unsigned int mlen, + uint8_t** buffer, unsigned int* blen); + +/** @brief Fills out text templates by asking a callback for content + * + * Copies the contents of the template into the buffer while looking + * for braceOpen and braceClose strings and calling the callback for + * each enclosed string between these braces. Should the callback + * return -1, the original template text is copied as is. + * + * By default PSYC's "[" and "]" are used but you can provide any other + * brace strings such as "${" and "}" or "". + * + * See also http://about.psyc.eu/psyctext + */ +int PSYC_text(uint8_t* template, unsigned int tlen, + uint8_t** buffer, unsigned int* blen, + PSYC_textCB lookupValue, + char* braceOpen, char* braceClose); + diff --git a/src/match.c b/src/match.c index f80653e..70fb200 100644 --- a/src/match.c +++ b/src/match.c @@ -1,5 +1,7 @@ #include "psyc/lib.h" +/* TODO: PSYC_inherits() */ + int PSYC_matches(uint8_t* sho, unsigned int slen, uint8_t* lon, unsigned int llen) { uint8_t *s, *l, *se, *le; @@ -30,6 +32,7 @@ int PSYC_matches(uint8_t* sho, unsigned int slen, se = sho+slen; le = lon+llen; + /* doesn't always work this way.. FIXME */ *se = *le = '_'; sho++; lon++; while(s = strchr(sho, '_')) { diff --git a/src/render.c b/src/render.c new file mode 100644 index 0000000..595b8e1 --- /dev/null +++ b/src/render.c @@ -0,0 +1 @@ +/* render PSYC packets */ diff --git a/src/text.c b/src/text.c new file mode 100644 index 0000000..1daa789 --- /dev/null +++ b/src/text.c @@ -0,0 +1,2 @@ +/* PSYC_text() */ + From b44cca63dc35330bdba6676a0af142342dc68dc1 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Mon, 18 Apr 2011 16:54:56 +0200 Subject: [PATCH 041/378] render.h & size_t --- include/psyc.h | 12 ++++++------ include/psyc/render.h | 13 +++++++++++++ src/match.c | 4 ++-- 3 files changed, 21 insertions(+), 8 deletions(-) create mode 100644 include/psyc/render.h diff --git a/include/psyc.h b/include/psyc.h index f41c8a2..0252999 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -5,8 +5,8 @@ /** @brief Checks if short keyword string matches long keyword string */ -int PSYC_matches(uint8_t* sho, unsigned int slen, - uint8_t* lon, unsigned int llen); +int PSYC_matches(uint8_t* sho, size_t slen, + uint8_t* lon, size_t llen); /** @brief Callback for PSYC_text() that produces a value for a match * @@ -16,8 +16,8 @@ int PSYC_matches(uint8_t* sho, unsigned int slen, * number of bytes written. 0 is a legal return value. Should the * callback return -1, PSYC_text leaves the original template text as is. */ -typedef int (*PSYC_textCB)(uint8_t* match, unsigned int mlen, - uint8_t** buffer, unsigned int* blen); +typedef int (*PSYC_textCB)(uint8_t* match, size_t mlen, + uint8_t** buffer, size_t * blen); /** @brief Fills out text templates by asking a callback for content * @@ -31,8 +31,8 @@ typedef int (*PSYC_textCB)(uint8_t* match, unsigned int mlen, * * See also http://about.psyc.eu/psyctext */ -int PSYC_text(uint8_t* template, unsigned int tlen, - uint8_t** buffer, unsigned int* blen, +int PSYC_text(uint8_t* template, size_t tlen, + uint8_t** buffer, size_t * blen, PSYC_textCB lookupValue, char* braceOpen, char* braceClose); diff --git a/include/psyc/render.h b/include/psyc/render.h new file mode 100644 index 0000000..1b3f576 --- /dev/null +++ b/include/psyc/render.h @@ -0,0 +1,13 @@ +int PSYC_renderHeader(struct PSYC_Buffers* pbuf, + const uint8_t* name, const size_t nlength, + const uint8_t* value, const size_t vlength, + const uchar flags, const uchar modifier); + +int PSYC_renderBody(struct PSYC_Buffers* pbuf, + const uint8_t* method, const size_t mlength, + const uint8_t* data, const size_t dlength, + const uchar flags); + +int PSYC_doneRender(struct PSYC_Buffers* pbuf, + uint8_t** buf, size_t* written); + diff --git a/src/match.c b/src/match.c index 70fb200..8b159f4 100644 --- a/src/match.c +++ b/src/match.c @@ -2,8 +2,8 @@ /* TODO: PSYC_inherits() */ -int PSYC_matches(uint8_t* sho, unsigned int slen, - uint8_t* lon, unsigned int llen) { +int PSYC_matches(uint8_t* sho, size_t slen, + uint8_t* lon, size_t llen) { uint8_t *s, *l, *se, *le; if (!slen) slen = strlen(sho); From e3d1bbd66f36f94180763c376c00e8ad3d17cd8b Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 19 Apr 2011 09:21:00 +0200 Subject: [PATCH 042/378] parser fixes & refactoring; added more tests --- include/psyc/parser.h | 57 +- src/Makefile | 5 +- src/parser.c | 628 ++++++++---------- src/tests/Makefile | 10 +- src/tests/{parser => packets}/binary.txt | 0 .../enter_leave_context.txt | 0 src/tests/{parser => packets}/fake_dns.txt | 1 - src/tests/{parser => packets}/invalid_dns.txt | 0 src/tests/packets/test-0-no-content | 3 + src/tests/packets/test-1 | 14 + src/tests/packets/test-1-length | 14 + src/tests/packets/test-1-length-error | 14 + src/tests/packets/test-1-utf8 | 14 + src/tests/packets/test-2-list | 25 + src/tests/packets/test-3-list | 34 + src/tests/packets/test-4-circuit | 5 + src/tests/packets/test-4-circuit-n | 4 + src/tests/packets/test-5-message-private | 9 + .../packets/test-6-message-private-remote | 9 + src/tests/parser/Makefile | 6 - src/tests/{parser => }/testParser.c | 33 +- 21 files changed, 479 insertions(+), 406 deletions(-) rename src/tests/{parser => packets}/binary.txt (100%) rename src/tests/{parser => packets}/enter_leave_context.txt (100%) rename src/tests/{parser => packets}/fake_dns.txt (98%) rename src/tests/{parser => packets}/invalid_dns.txt (100%) create mode 100644 src/tests/packets/test-0-no-content create mode 100644 src/tests/packets/test-1 create mode 100644 src/tests/packets/test-1-length create mode 100644 src/tests/packets/test-1-length-error create mode 100644 src/tests/packets/test-1-utf8 create mode 100644 src/tests/packets/test-2-list create mode 100644 src/tests/packets/test-3-list create mode 100644 src/tests/packets/test-4-circuit create mode 100644 src/tests/packets/test-4-circuit-n create mode 100644 src/tests/packets/test-5-message-private create mode 100644 src/tests/packets/test-6-message-private-remote delete mode 100644 src/tests/parser/Makefile rename src/tests/{parser => }/testParser.c (52%) 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; From 1e3e7c2f7877d3b8cd8dc37c01979abae3854a19 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 19 Apr 2011 09:42:43 +0200 Subject: [PATCH 043/378] size_t --- src/parser.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/parser.c b/src/parser.c index ab8c918..47b3ba1 100644 --- a/src/parser.c +++ b/src/parser.c @@ -76,9 +76,9 @@ inline int PSYC_parseName(PSYC_State* state, PSYC_Array* name) * @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) +inline int PSYC_parseBinaryValue(PSYC_State* state, PSYC_Array* value, size_t* length, size_t* parsed) { - unsigned int remaining = *length - *parsed; + 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? @@ -167,7 +167,7 @@ inline int PSYC_parseVar(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, 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 */ + 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 */ From eb344399256652a720a8ea7eb3cc2b3dbb398f51 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 19 Apr 2011 12:26:51 +0200 Subject: [PATCH 044/378] size_t --- include/psyc/parser.h | 18 +++++++++--------- src/parser.c | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index f463942..e599bb7 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -43,24 +43,24 @@ enum PSYC_Parts typedef struct { - unsigned int length; + size_t length; const uint8_t * ptr; } PSYC_Array; typedef struct { - unsigned int cursor; /** current position in buffer */ - unsigned int 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 */ - unsigned int contentParsed; /** number of bytes parsed from the content so far */ - unsigned int contentLength; /** expected length of the content */ + 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? */ - unsigned int valueParsed; /** number of bytes parsef from the value so far */ - unsigned int valueLength; /** expected length of the value */ + size_t valueParsed; /** number of bytes parsef from the value so far */ + size_t valueLength; /** expected length of the value */ } PSYC_State; #ifndef PSYC_COMPILE_LIBRARY @@ -70,7 +70,7 @@ typedef struct * @param length length of that buffer * * @returns an instance of the PSYC_Array struct */ -inline PSYC_Array PSYC_createArray (uint8_t* const memory, unsigned int length) +inline PSYC_Array PSYC_createArray (uint8_t* const memory, size_t length) { PSYC_Array arr = {length, memory}; @@ -101,7 +101,7 @@ inline void PSYC_nextBuffer (PSYC_State* state, PSYC_Array newBuf) state->cursor = 0; } -inline unsigned int PSYC_getContentLength (PSYC_State* s) +inline size_t PSYC_getContentLength (PSYC_State* s) { return s->contentLength; } diff --git a/src/parser.c b/src/parser.c index 47b3ba1..ef927b2 100644 --- a/src/parser.c +++ b/src/parser.c @@ -49,7 +49,7 @@ inline char isAlphaNumeric(uint8_t c) inline char isKwChar(uint8_t c) { - return c == '_' || isAlphaNumeric(c); + return isAlphaNumeric(c) || c == '_'; } /** From 875d48ee077c225fcd9f16f08b84683b2dacbd1d Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 19 Apr 2011 19:41:25 +0200 Subject: [PATCH 045/378] list parsing --- include/psyc/parser.h | 75 ++++++++--- src/parser.c | 187 ++++++++++++++++++++-------- src/tests/packets/test-2-list | 2 +- src/tests/packets/test-2-list-error | 26 ++++ src/tests/packets/test-3-list | 2 +- src/tests/testParser.c | 49 +++++--- 6 files changed, 259 insertions(+), 82 deletions(-) create mode 100644 src/tests/packets/test-2-list-error diff --git a/include/psyc/parser.h b/include/psyc/parser.h index e599bb7..c5d13be 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -28,27 +28,43 @@ enum PSYC_ReturnCodes PSYC_INCOMPLETE = 9, }; +enum PSYC_ListReturnCodes +{ + PSYC_ERROR_LIST_DELIM = -5, + PSYC_ERROR_LIST_LEN = -4, + PSYC_ERROR_LIST_TYPE = -3, + PSYC_ERROR_LIST_NAME = -2, + PSYC_ERROR_LIST= -1, + PSYC_LIST_ELEM = 1, + PSYC_LIST_END = 2, + PSYC_LIST_INCOMPLETE = 3, +}; + 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, }; +enum PSYC_ListTypes +{ + PSYC_LIST_TEXT = 1, + PSYC_LIST_BINARY = 2, +}; -typedef struct +typedef struct { size_t length; const uint8_t * ptr; } PSYC_Array; -typedef struct +typedef struct { size_t cursor; /** current position in buffer */ size_t startc; /** line start position */ @@ -59,45 +75,72 @@ typedef struct 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 parsef from the value so far */ + 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 */ + PSYC_Array buffer; + 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 */ +} PSYC_ListState; + #ifndef PSYC_COMPILE_LIBRARY -/* @brief shortcut for creating an array +/* @brief Shortcut for creating an array. * - * @param memory pointer to the buffer - * @param length length of that buffer + * @param memory Pointer to the buffer. + * @param length Length of that buffer. * - * @returns 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 +/* @brief 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 */ + * @param state Pointer to the state struct that should be initiated. + * @param flags The flags that one ones to set, see PSYC_Flags. + */ inline void PSYC_initState2 (PSYC_State* state, uint8_t flags ) { memset(state, 0, sizeof(PSYC_State)); state->flags = flags; } -/* @brief initiates the state struct +/* @brief Initiates the state struct. * - * @param state pointer to the state struct that should be initiated */ + * @param state Pointer to the state struct that should be initiated. + */ inline void PSYC_initState (PSYC_State* state) { memset(state, 0, sizeof(PSYC_State)); } +/* @brief Initiates the list state struct. + * + * @param state Pointer to the list state struct that should be initiated. + */ +inline void PSYC_initListState (PSYC_ListState* state) +{ + memset(state, 0, sizeof(PSYC_ListState)); +} + inline void PSYC_nextBuffer (PSYC_State* state, PSYC_Array newBuf) { - state->buffer = newBuf; + state->buffer = newBuf; + state->cursor = 0; +} + +inline void PSYC_nextListBuffer (PSYC_ListState* state, PSYC_Array newBuf) +{ + state->buffer = newBuf; state->cursor = 0; } @@ -109,3 +152,5 @@ inline size_t PSYC_getContentLength (PSYC_State* s) #endif int PSYC_parse(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value); + +int PSYC_parseList(PSYC_ListState* state, PSYC_Array *name, PSYC_Array* value, PSYC_Array* elem); diff --git a/src/parser.c b/src/parser.c index ef927b2..0c363c2 100644 --- a/src/parser.c +++ b/src/parser.c @@ -7,11 +7,11 @@ #include -#define ADVANCE_CURSOR_OR_RETURN() \ +#define ADVANCE_CURSOR_OR_RETURN(ret) \ if (++(state->cursor) >= state->buffer.length) \ { \ state->cursor = state->startc; \ - return PSYC_INSUFFICIENT; \ + return ret; \ } /** @brief isGlyph @@ -24,14 +24,14 @@ inline char isGlyph(uint8_t g) { case ':': case '=': - case '?': case '+': case '-': + case '?': + case '!': return 1; default: return 0; } - } inline char isNumeric(uint8_t c) @@ -64,8 +64,8 @@ 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 - ADVANCE_CURSOR_OR_RETURN(); + name->length++; /* was a valid char, increase length */ + ADVANCE_CURSOR_OR_RETURN(PSYC_INSUFFICIENT); } return name->length > 0 ? PSYC_SUCCESS : PSYC_ERROR; @@ -81,11 +81,10 @@ 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; - state->cursor = 0; return PSYC_INCOMPLETE; } @@ -103,7 +102,7 @@ inline int PSYC_parseBinaryValue(PSYC_State* state, PSYC_Array* value, size_t* l 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(); + ADVANCE_CURSOR_OR_RETURN(PSYC_INSUFFICIENT); if (PSYC_parseName(state, name) != PSYC_SUCCESS) return PSYC_ERROR_VAR_NAME; @@ -112,9 +111,9 @@ inline int PSYC_parseVar(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, /* 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(); + 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; @@ -123,22 +122,19 @@ inline int PSYC_parseVar(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, do { state->valueLength = 10 * state->valueLength + state->buffer.ptr[state->cursor] - '0'; - ADVANCE_CURSOR_OR_RETURN(); + ADVANCE_CURSOR_OR_RETURN(PSYC_INSUFFICIENT); } while (isNumeric(state->buffer.ptr[state->cursor])); } 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? - { - state->cursor = 0; + 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) return PSYC_ENTITY_INCOMPLETE; @@ -146,15 +142,15 @@ 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(); + ADVANCE_CURSOR_OR_RETURN(PSYC_INSUFFICIENT); value->ptr = state->buffer.ptr + state->cursor; while (state->buffer.ptr[state->cursor] != '\n') { value->length++; - ADVANCE_CURSOR_OR_RETURN(); + ADVANCE_CURSOR_OR_RETURN(PSYC_INSUFFICIENT); } state->cursor++; return PSYC_SUCCESS; @@ -163,45 +159,45 @@ inline int PSYC_parseVar(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, return PSYC_ERROR_VAR_TAB; } -/** @brief generalized line-based parser */ +/** @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 */ 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->buffer.length <= state->cursor) // 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; /* return insufficient data. */ 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 + 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: @@ -213,7 +209,7 @@ int PSYC_parse(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, PSYC_Arra do { state->contentLength = 10 * state->contentLength + state->buffer.ptr[state->cursor] - '0'; - ADVANCE_CURSOR_OR_RETURN(); + ADVANCE_CURSOR_OR_RETURN(PSYC_INSUFFICIENT); } while (isNumeric(state->buffer.ptr[state->cursor])); } @@ -226,9 +222,9 @@ int PSYC_parse(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, PSYC_Arra 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; @@ -236,9 +232,9 @@ int PSYC_parse(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, PSYC_Arra goto PSYC_PART_END; } - ADVANCE_CURSOR_OR_RETURN(); + 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. */ @@ -265,7 +261,7 @@ 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: @@ -281,9 +277,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; @@ -294,7 +290,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; @@ -303,16 +299,16 @@ 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; // set to start value - return PSYC_INSUFFICIENT; // return insufficient + state->cursor = state->startc; + return PSYC_INSUFFICIENT; } if (state->buffer.ptr[state->cursor+1] == '|' && @@ -324,16 +320,16 @@ int PSYC_parse(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, PSYC_Arra } } value->length++; - ADVANCE_CURSOR_OR_RETURN(); + ADVANCE_CURSOR_OR_RETURN(PSYC_INSUFFICIENT); } } case PSYC_PART_END: PSYC_PART_END: - /* end of packet, at this point we have already passed a \n + /* 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->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 */ @@ -348,5 +344,94 @@ int PSYC_parse(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, PSYC_Arra return PSYC_ERROR_END; } } - return PSYC_ERROR; // should not be reached + return PSYC_ERROR; /* should not be reached */ +} + +/** @brief list parser */ +int PSYC_parseList(PSYC_ListState* state, PSYC_Array *name, PSYC_Array* value, PSYC_Array* elem) +{ + if (state->cursor >= state->buffer.length) + return PSYC_LIST_INCOMPLETE; + + state->startc = state->cursor; + + 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_ */ + return PSYC_ERROR_LIST_NAME; + + /* First character is either | for text lists, or a number for binary lists */ + if (state->buffer.ptr[state->cursor] == '|') + { + state->type = PSYC_LIST_TEXT; + state->cursor++; + } + else if (isNumeric(state->buffer.ptr[state->cursor])) + state->type = PSYC_LIST_BINARY; + else + return PSYC_ERROR_LIST_TYPE; + } + + if (state->type == PSYC_LIST_TEXT) + { + elem->ptr = state->buffer.ptr + state->cursor; + elem->length = 0; + + if (state->cursor >= state->buffer.length) + return PSYC_LIST_END; + + while (state->buffer.ptr[state->cursor] != '|') + { + elem->length++; + if (++(state->cursor) >= state->buffer.length) + return PSYC_LIST_END; + } + state->cursor++; + return PSYC_LIST_ELEM; + } + else /* binary list */ + { + if (!(state->elemParsed < state->elemLength)) { + /* Element starts with a number. */ + if (isNumeric(state->buffer.ptr[state->cursor])) + { + do + { + state->elemLength = 10 * state->elemLength + state->buffer.ptr[state->cursor] - '0'; + ADVANCE_CURSOR_OR_RETURN(PSYC_LIST_INCOMPLETE); + } + while (isNumeric(state->buffer.ptr[state->cursor])); + } + else + return PSYC_ERROR_LIST_LEN; + + if (state->buffer.ptr[state->cursor] != ' ') + return PSYC_ERROR_LIST_LEN; + + state->cursor++; + elem->ptr = state->buffer.ptr + state->cursor; + elem->length = 0; + state->elemParsed = 0; + } + + /* 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; + + state->elemLength = 0; + + if (state->cursor >= state->buffer.length) + return PSYC_LIST_END; + + if (state->buffer.ptr[state->cursor] != '|') + return PSYC_ERROR_LIST_DELIM; + + state->cursor++; + return PSYC_LIST_ELEM; + } + } + + return PSYC_ERROR_LIST; /* should not be reached */ } diff --git a/src/tests/packets/test-2-list b/src/tests/packets/test-2-list index b534143..ebff895 100644 --- a/src/tests/packets/test-2-list +++ b/src/tests/packets/test-2-list @@ -1,7 +1,7 @@ | =_source psyc://foo/~bar :_target psyc://bar/~baz -=_list_foo foo|bar|baz +=_list_foo |foo|bar|baz :_tag sch1828hu3r2cm =_foo bar baz diff --git a/src/tests/packets/test-2-list-error b/src/tests/packets/test-2-list-error new file mode 100644 index 0000000..cbae3e6 --- /dev/null +++ b/src/tests/packets/test-2-list-error @@ -0,0 +1,26 @@ +| +=_source psyc://foo/~bar +:_target psyc://bar/~baz +=_list_foo foo|bar|baz +=_listfoo foo|bar|baz +:_tag sch1828hu3r2cm + +=_foo bar baz +=_abc_def 11 ghi jkl + +xq +=_list_bar 36 2 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 index 2cd79b6..4776f47 100644 --- a/src/tests/packets/test-3-list +++ b/src/tests/packets/test-3-list @@ -1,7 +1,7 @@ | =_source psyc://foo/~bar :_target psyc://bar/~baz -=_list_foo foo|bar|baz +=_list_foo |foo|bar|baz :_tag sch1828hu3r2cm ?_test ignored diff --git a/src/tests/testParser.c b/src/tests/testParser.c index a9d7b9d..a704409 100644 --- a/src/tests/testParser.c +++ b/src/tests/testParser.c @@ -5,31 +5,26 @@ int main(int argc, char** argv) { - uint8_t buffer[2048]; - int index; + int index, ret; + uint8_t buffer[2048], modifier; + PSYC_Array name, value, elem; + PSYC_State state; + PSYC_ListState listState; int file = open(argv[1],O_RDONLY); if(file < 0) return -1; index = read(file,(void*)buffer,sizeof(buffer)); - write(1, ">> INPUT:\n", 10); + write(1, ">> INPUT\n", 9); write(1, buffer, index); - write(1, ">> PARSE:\n", 10); + write(1, ">> PARSE\n", 9); - PSYC_State state; PSYC_initState(&state); - - //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, &modifier, &name, &value))) + while (ret = PSYC_parse(&state, &modifier, &name, &value)) { switch (ret) { @@ -41,6 +36,33 @@ int main(int argc, char** argv) write(1, " = ", 3); write(1, value.ptr, value.length); write(1, "\n", 1); + if (memcmp(name.ptr, "_list", 5) == 0) + { + write(1, ">>> LIST START\n", 15); + PSYC_initListState(&listState); + PSYC_nextListBuffer(&listState, value); + while (ret = PSYC_parseList(&listState, &name, &value, &elem)) + { + switch (ret) + { + case PSYC_LIST_END: + case PSYC_LIST_ELEM: + write(1, "|", 1); + write(1, elem.ptr, elem.length); + write(1, "\n", 1); + break; + default: + printf("Error while parsing list: %i\n", ret); + return 1; + } + + if (ret == PSYC_LIST_END) + { + write(1, ">>> LIST END\n", 13); + break; + } + } + } break; case PSYC_COMPLETE: printf("Done parsing.\n"); @@ -54,5 +76,4 @@ int main(int argc, char** argv) } } return 0; - } From fc7d22f604bc30314f3c7e3198c0e676c599e98d Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 19 Apr 2011 21:54:44 +0200 Subject: [PATCH 046/378] comment fixes --- include/psyc/parser.h | 41 ++++++----- src/parser.c | 162 +++++++++++++++++++++++------------------- 2 files changed, 113 insertions(+), 90 deletions(-) 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 } From b382194ca761584f1ed1926ef812323fc2daa923 Mon Sep 17 00:00:00 2001 From: Mathias Laurenz Baumann Date: Tue, 19 Apr 2011 21:55:22 +0200 Subject: [PATCH 047/378] added include guard --- include/psyc/parser.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index c5d13be..b8a8fdc 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -1,6 +1,9 @@ #include #include +#ifndef PSYC_PARSER_H_INCLUDED +#define PSYC_PARSER_H_INCLUDED + enum PSYC_Flags { PSYC_HEADER_ONLY = 1 @@ -154,3 +157,6 @@ inline size_t PSYC_getContentLength (PSYC_State* s) int PSYC_parse(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value); int PSYC_parseList(PSYC_ListState* state, PSYC_Array *name, PSYC_Array* value, PSYC_Array* elem); + + +#endif From 3b53517897cbc523d83a593119ac79269bbcc4da Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Tue, 19 Apr 2011 22:00:24 +0200 Subject: [PATCH 048/378] here's PSYC_Types - now shoot me --- include/psyc/parser.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index c5d13be..1a0ad83 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -1,6 +1,21 @@ #include #include +enum PSYC_Types { + PSYC_TYPE_AMOUNT, + PSYC_TYPE_COLOR, + PSYC_TYPE_DATE, + PSYC_TYPE_DEGREE, + PSYC_TYPE_ENTITY, + PSYC_TYPE_FLAG, + PSYC_TYPE_LANGUAGE, + PSYC_TYPE_LIST, + PSYC_TYPE_NICK, + PSYC_TYPE_PAGE, + PSYC_TYPE_UNIFORM, + PSYC_TYPE_TIME, +}; + enum PSYC_Flags { PSYC_HEADER_ONLY = 1 From 7aa352fb1fbd562dc5256326287159e483584fc5 Mon Sep 17 00:00:00 2001 From: Mathias Laurenz Baumann Date: Tue, 19 Apr 2011 22:12:40 +0200 Subject: [PATCH 049/378] Added doxygen file --- Doxyfile | 1719 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1719 insertions(+) create mode 100644 Doxyfile diff --git a/Doxyfile b/Doxyfile new file mode 100644 index 0000000..882cc8a --- /dev/null +++ b/Doxyfile @@ -0,0 +1,1719 @@ +# Doxyfile 1.7.3 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = LibPsyc + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 0.1 + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "Psyc Core Library" + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penalty. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will roughly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. The create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = src include + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.d \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.m \ + *.mm \ + *.dox \ + *.py \ + *.f90 \ + *.f \ + *.for \ + *.vhd \ + *.vhdl + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the stylesheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [0,1..20]) +# that doxygen will group on one line in the generated HTML documentation. +# Note that a value of 0 will completely suppress the enum values from +# appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the +# mathjax.org site, so you can quickly see the result without installing +# MathJax, but it is strongly recommended to install a local copy of MathJax +# before deployment. + +MATHJAX_RELPATH = http://www.mathjax.org/mathjax + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvantages are that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = YES + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will write a font called Helvetica to the output +# directory and reference it in all dot files that doxygen generates. +# When you want a differently looking font you can specify the font name +# using DOT_FONTNAME. You need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, svg, gif or svg. +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES From 52406375775658f71afdfd5c8eca15a3549accf0 Mon Sep 17 00:00:00 2001 From: Mathias Laurenz Baumann Date: Tue, 19 Apr 2011 22:27:38 +0200 Subject: [PATCH 050/378] added doxygen file documentation --- Doxyfile | 7 ++++--- include/psyc/parser.h | 8 ++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Doxyfile b/Doxyfile index 882cc8a..4f868f6 100644 --- a/Doxyfile +++ b/Doxyfile @@ -321,7 +321,7 @@ SYMBOL_CACHE_SIZE = 0 # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES -EXTRACT_ALL = YES +EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. @@ -612,7 +612,8 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = src include +INPUT = src \ + include # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is @@ -776,7 +777,7 @@ INLINE_SOURCES = NO # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. -STRIP_CODE_COMMENTS = YES +STRIP_CODE_COMMENTS = NO # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented diff --git a/include/psyc/parser.h b/include/psyc/parser.h index 1b739a5..8d14397 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -1,3 +1,11 @@ +/** + * @file psyc/parser.h + * @brief Interface for various psyc parser functions + * + * All parsing functions and the definitions they use are + * defined in this file. +*/ + #ifndef PSYC_PARSER_H # define PSYC_PARSER_H From 7ccc4e661a813b24fc86b2647d284eb54fcd8b07 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 19 Apr 2011 22:31:43 +0200 Subject: [PATCH 051/378] doxygen --- .gitignore | 1 + Makefile | 4 ++++ include/psyc/parser.h | 11 ++++++++++- 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 Makefile diff --git a/.gitignore b/.gitignore index 30cd0c5..94dda61 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +doc/ .config ~$* .DS_Store diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..987a385 --- /dev/null +++ b/Makefile @@ -0,0 +1,4 @@ +.PHONY: doc + +doc: + doxygen diff --git a/include/psyc/parser.h b/include/psyc/parser.h index 1b739a5..0d42c36 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -21,7 +21,7 @@ enum PSYC_Types { enum PSYC_Flags { - PSYC_HEADER_ONLY = 1 + PSYC_HEADER_ONLY = 1, }; @@ -174,8 +174,17 @@ inline size_t PSYC_getContentLength (PSYC_State* s) #endif +/** + * 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); +/** + * List value parser. + * @return see PSYC_ListReturnCodes. + */ int PSYC_parseList(PSYC_ListState* state, PSYC_Array *name, PSYC_Array* value, PSYC_Array* elem); #endif // PSYC_PARSER_H From 59c453d9bcc521385aaa623261d501600c6bf7d4 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 19 Apr 2011 22:37:42 +0200 Subject: [PATCH 052/378] moved tests dir --- .gitignore | 8 ++++---- {src/tests => tests}/CMakeLists.txt | 0 {src/tests => tests}/Makefile | 2 +- {src/tests => tests}/packets/binary.txt | 0 {src/tests => tests}/packets/enter_leave_context.txt | 0 {src/tests => tests}/packets/fake_dns.txt | 0 {src/tests => tests}/packets/invalid_dns.txt | 0 {src/tests => tests}/packets/test-0-no-content | 0 {src/tests => tests}/packets/test-1 | 0 {src/tests => tests}/packets/test-1-length | 0 {src/tests => tests}/packets/test-1-length-error | 0 {src/tests => tests}/packets/test-1-utf8 | 0 {src/tests => tests}/packets/test-2-list | 0 {src/tests => tests}/packets/test-2-list-error | 0 {src/tests => tests}/packets/test-3-list | 0 {src/tests => tests}/packets/test-4-circuit | 0 {src/tests => tests}/packets/test-4-circuit-n | 0 {src/tests => tests}/packets/test-5-message-private | 0 .../tests => tests}/packets/test-6-message-private-remote | 0 {src/tests => tests}/testMatch.c | 0 {src/tests => tests}/testParser.c | 0 21 files changed, 5 insertions(+), 5 deletions(-) rename {src/tests => tests}/CMakeLists.txt (100%) rename {src/tests => tests}/Makefile (80%) rename {src/tests => tests}/packets/binary.txt (100%) rename {src/tests => tests}/packets/enter_leave_context.txt (100%) rename {src/tests => tests}/packets/fake_dns.txt (100%) rename {src/tests => tests}/packets/invalid_dns.txt (100%) rename {src/tests => tests}/packets/test-0-no-content (100%) rename {src/tests => tests}/packets/test-1 (100%) rename {src/tests => tests}/packets/test-1-length (100%) rename {src/tests => tests}/packets/test-1-length-error (100%) rename {src/tests => tests}/packets/test-1-utf8 (100%) rename {src/tests => tests}/packets/test-2-list (100%) rename {src/tests => tests}/packets/test-2-list-error (100%) rename {src/tests => tests}/packets/test-3-list (100%) rename {src/tests => tests}/packets/test-4-circuit (100%) rename {src/tests => tests}/packets/test-4-circuit-n (100%) rename {src/tests => tests}/packets/test-5-message-private (100%) rename {src/tests => tests}/packets/test-6-message-private-remote (100%) rename {src/tests => tests}/testMatch.c (100%) rename {src/tests => tests}/testParser.c (100%) diff --git a/.gitignore b/.gitignore index 94dda61..15152b7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,8 @@ doc/ +src/match +tests/testMatch +tests/testParser + .config ~$* .DS_Store @@ -17,7 +21,3 @@ doc/ *bak *diff *orig -src/match -src/tests/parser/testParser -src/tests/testMatch -src/tests/testParser diff --git a/src/tests/CMakeLists.txt b/tests/CMakeLists.txt similarity index 100% rename from src/tests/CMakeLists.txt rename to tests/CMakeLists.txt diff --git a/src/tests/Makefile b/tests/Makefile similarity index 80% rename from src/tests/Makefile rename to tests/Makefile index 830b478..a9c8fe2 100644 --- a/src/tests/Makefile +++ b/tests/Makefile @@ -1,4 +1,4 @@ -CFLAGS=-I../../include -DDEBUG -g -O0 -Wall +CFLAGS=-I../include -DDEBUG -g -O0 -Wall LDFLAGS=-L.. LOADLIBES=-lpsyc TARGETS=testParser testMatch diff --git a/src/tests/packets/binary.txt b/tests/packets/binary.txt similarity index 100% rename from src/tests/packets/binary.txt rename to tests/packets/binary.txt diff --git a/src/tests/packets/enter_leave_context.txt b/tests/packets/enter_leave_context.txt similarity index 100% rename from src/tests/packets/enter_leave_context.txt rename to tests/packets/enter_leave_context.txt diff --git a/src/tests/packets/fake_dns.txt b/tests/packets/fake_dns.txt similarity index 100% rename from src/tests/packets/fake_dns.txt rename to tests/packets/fake_dns.txt diff --git a/src/tests/packets/invalid_dns.txt b/tests/packets/invalid_dns.txt similarity index 100% rename from src/tests/packets/invalid_dns.txt rename to tests/packets/invalid_dns.txt diff --git a/src/tests/packets/test-0-no-content b/tests/packets/test-0-no-content similarity index 100% rename from src/tests/packets/test-0-no-content rename to tests/packets/test-0-no-content diff --git a/src/tests/packets/test-1 b/tests/packets/test-1 similarity index 100% rename from src/tests/packets/test-1 rename to tests/packets/test-1 diff --git a/src/tests/packets/test-1-length b/tests/packets/test-1-length similarity index 100% rename from src/tests/packets/test-1-length rename to tests/packets/test-1-length diff --git a/src/tests/packets/test-1-length-error b/tests/packets/test-1-length-error similarity index 100% rename from src/tests/packets/test-1-length-error rename to tests/packets/test-1-length-error diff --git a/src/tests/packets/test-1-utf8 b/tests/packets/test-1-utf8 similarity index 100% rename from src/tests/packets/test-1-utf8 rename to tests/packets/test-1-utf8 diff --git a/src/tests/packets/test-2-list b/tests/packets/test-2-list similarity index 100% rename from src/tests/packets/test-2-list rename to tests/packets/test-2-list diff --git a/src/tests/packets/test-2-list-error b/tests/packets/test-2-list-error similarity index 100% rename from src/tests/packets/test-2-list-error rename to tests/packets/test-2-list-error diff --git a/src/tests/packets/test-3-list b/tests/packets/test-3-list similarity index 100% rename from src/tests/packets/test-3-list rename to tests/packets/test-3-list diff --git a/src/tests/packets/test-4-circuit b/tests/packets/test-4-circuit similarity index 100% rename from src/tests/packets/test-4-circuit rename to tests/packets/test-4-circuit diff --git a/src/tests/packets/test-4-circuit-n b/tests/packets/test-4-circuit-n similarity index 100% rename from src/tests/packets/test-4-circuit-n rename to tests/packets/test-4-circuit-n diff --git a/src/tests/packets/test-5-message-private b/tests/packets/test-5-message-private similarity index 100% rename from src/tests/packets/test-5-message-private rename to tests/packets/test-5-message-private diff --git a/src/tests/packets/test-6-message-private-remote b/tests/packets/test-6-message-private-remote similarity index 100% rename from src/tests/packets/test-6-message-private-remote rename to tests/packets/test-6-message-private-remote diff --git a/src/tests/testMatch.c b/tests/testMatch.c similarity index 100% rename from src/tests/testMatch.c rename to tests/testMatch.c diff --git a/src/tests/testParser.c b/tests/testParser.c similarity index 100% rename from src/tests/testParser.c rename to tests/testParser.c From 8e1a107b87957b9e97632e1ae9f8e12a98bff5ea Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 19 Apr 2011 22:52:08 +0200 Subject: [PATCH 053/378] Makefile improvements --- Makefile | 18 ++++++++++++++++++ src/Makefile | 3 +++ 2 files changed, 21 insertions(+) diff --git a/Makefile b/Makefile index 987a385..6ba55b6 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,22 @@ .PHONY: doc +.PHONY: tests + +default: + @/bin/echo -e "Usage:\n\tmake diet - compile with diet libc\n\tmake lib - compile with normal gnu libc\n\tmake tests\n\tmake doc" + +lib: + make -C src lib + +diet: + make -C src diet + +tests: + make -C tests doc: doxygen + +clean: + make -C src clean + make -C tests clean + rm -rf doc diff --git a/src/Makefile b/src/Makefile index 241ad61..ae8bad9 100644 --- a/src/Makefile +++ b/src/Makefile @@ -20,3 +20,6 @@ match: match.c ${CC} -o $@ -DDEBUG=2 -DCMDTOOL -DTEST $< it: match + +clean: + rm -f $O From c01d95f8834ffb9a8926948df5464bc08d2b0c15 Mon Sep 17 00:00:00 2001 From: Mathias Laurenz Baumann Date: Tue, 19 Apr 2011 22:57:49 +0200 Subject: [PATCH 054/378] more documentation --- Doxyfile | 2 +- include/psyc.h | 18 ++++++++++++++++++ include/psyc/parser.h | 39 +++++++++++++++++++++++++++++++++------ 3 files changed, 52 insertions(+), 7 deletions(-) diff --git a/Doxyfile b/Doxyfile index 4f868f6..47129a6 100644 --- a/Doxyfile +++ b/Doxyfile @@ -321,7 +321,7 @@ SYMBOL_CACHE_SIZE = 0 # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES -EXTRACT_ALL = YES +EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. diff --git a/include/psyc.h b/include/psyc.h index 0252999..3055da0 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -1,3 +1,21 @@ +/** @file psyc.h + * + * @brief Main psyc interface providing crucial functionality +*/ + +/** @mainpage Psyc Core Library + * + * @section intro_sec Introduction + * + * This is the introduction. + * + * @section install_sec Installation + * + * @subsection step1 Step 1: Opening the box + * + * etc... + */ + #include #include diff --git a/include/psyc/parser.h b/include/psyc/parser.h index 8bc6809..23ba5fc 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -6,12 +6,23 @@ * defined in this file. */ +/** @defgroup parsing Parsing Functions + * + * This module contains all parsing functions + * @{ + */ + #ifndef PSYC_PARSER_H # define PSYC_PARSER_H #include #include +/** Different types that a variable can have + * + * This enum lists all the types that a variable + * in a psyc packet can have + */ enum PSYC_Types { PSYC_TYPE_AMOUNT, PSYC_TYPE_COLOR, @@ -32,7 +43,9 @@ enum PSYC_Flags PSYC_HEADER_ONLY = 1, }; - +/** The return value definitions for packet parsing function + * @see PSYC_parse() + */ enum PSYC_ReturnCodes { PSYC_ERROR_END = -7, @@ -182,12 +195,24 @@ inline size_t PSYC_getContentLength (PSYC_State* s) #endif -/** - * Parse PSYC packets. - * Generalized line-based parser. - * @return see PSYC_ReturnCodes +/** Parse PSYC packets. + * + * Generalized line-based packet parser. + * + * @param state An initialized PSYC_State + * @param modifier A pointer to a character. In case of a variable, it will + * be set to the modifier of that variable + * @param name A pointer to a PSYC_Array. It will point to the name of + * the variable or method and its length will be set accordingly + * @param value A pointer to a PSYC_Array. It will point to the + * value/body the variable/method and its length will be set accordingly + * + * @return one of PSYC_ReturnCodes + * @see PSYC_ReturnCodes + * @see PSYC_State + * @see PSYC_Array */ -int PSYC_parse(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value); +PSYC_ReturnCodes PSYC_parse(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value); /** * List value parser. @@ -196,3 +221,5 @@ int PSYC_parse(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, PSYC_Arra int PSYC_parseList(PSYC_ListState* state, PSYC_Array *name, PSYC_Array* value, PSYC_Array* elem); #endif // PSYC_PARSER_H + +/** @} */ // end of parsing group From cbcedb05d93e08bfa7b99cb13c3f45de2a701f42 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Tue, 19 Apr 2011 23:17:23 +0200 Subject: [PATCH 055/378] + --- Doxyfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doxyfile b/Doxyfile index 47129a6..aa9c07c 100644 --- a/Doxyfile +++ b/Doxyfile @@ -25,7 +25,7 @@ DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. -PROJECT_NAME = LibPsyc +PROJECT_NAME = libpsyc # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or @@ -37,7 +37,7 @@ PROJECT_NUMBER = 0.1 # for a project that appears at the top of each page and should give viewer # a quick idea about the purpose of the project. Keep the description short. -PROJECT_BRIEF = "Psyc Core Library" +PROJECT_BRIEF = "PSYC core library" # With the PROJECT_LOGO tag one can specify an logo or icon that is # included in the documentation. The maximum height of the logo should not From 7113d6e68cf6a6e3422f82203ea3c265b589b209 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 20 Apr 2011 14:52:40 +0200 Subject: [PATCH 056/378] moar documentation & fix PSYC_parse return type --- include/psyc/parser.h | 57 +++++++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index 23ba5fc..700899d 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -1,15 +1,16 @@ -/** +/** * @file psyc/parser.h - * @brief Interface for various psyc parser functions + * @brief Interface for various psyc parser functions. * - * All parsing functions and the definitions they use are + * All parsing functions and the definitions they use are * defined in this file. */ -/** @defgroup parsing Parsing Functions - * - * This module contains all parsing functions - * @{ +/** + * @defgroup parsing Parsing Functions + * + * This module contains all parsing functions. + * @{ */ #ifndef PSYC_PARSER_H @@ -18,10 +19,11 @@ #include #include -/** Different types that a variable can have +/** + * Different types that a variable can have. * * This enum lists all the types that a variable - * in a psyc packet can have + * in a psyc packet can have. */ enum PSYC_Types { PSYC_TYPE_AMOUNT, @@ -43,8 +45,9 @@ enum PSYC_Flags PSYC_HEADER_ONLY = 1, }; -/** The return value definitions for packet parsing function - * @see PSYC_parse() +/** + * The return value definitions for the packet parsing function. + * @see PSYC_parse() */ enum PSYC_ReturnCodes { @@ -67,6 +70,10 @@ enum PSYC_ReturnCodes PSYC_INCOMPLETE = 9, }; +/** + * The return value definitions for the list parsing function. + * @see PSYC_parseList() + */ enum PSYC_ListReturnCodes { PSYC_ERROR_LIST_DELIM = -5, @@ -79,6 +86,9 @@ enum PSYC_ListReturnCodes PSYC_LIST_INCOMPLETE = 3, }; +/** + * PSYC packet parts. + */ enum PSYC_Parts { PSYC_PART_RESET = -1, @@ -90,6 +100,10 @@ enum PSYC_Parts PSYC_PART_END, }; +/** + * List types. + * Possible types are text and binary. + */ enum PSYC_ListTypes { PSYC_LIST_TEXT = 1, @@ -102,7 +116,9 @@ typedef struct const uint8_t * ptr; } PSYC_Array; - +/** + * Struct for keeping parser state. + */ typedef struct { size_t cursor; ///< current position in buffer @@ -118,6 +134,9 @@ typedef struct size_t valueLength; ///< expected length of the value } PSYC_State; +/** + * Struct for keeping list parser state. + */ typedef struct { size_t cursor; ///< current position in buffer @@ -195,13 +214,14 @@ inline size_t PSYC_getContentLength (PSYC_State* s) #endif -/** Parse PSYC packets. - * +/** + * Parse PSYC packets. + * * Generalized line-based packet parser. - * + * * @param state An initialized PSYC_State * @param modifier A pointer to a character. In case of a variable, it will - * be set to the modifier of that variable + * be set to the modifier of that variable * @param name A pointer to a PSYC_Array. It will point to the name of * the variable or method and its length will be set accordingly * @param value A pointer to a PSYC_Array. It will point to the @@ -212,11 +232,12 @@ inline size_t PSYC_getContentLength (PSYC_State* s) * @see PSYC_State * @see PSYC_Array */ -PSYC_ReturnCodes 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); /** * List value parser. - * @return see PSYC_ListReturnCodes. + * @return one of PSYC_ReturnCodes + * @see PSYC_ListReturnCodes */ int PSYC_parseList(PSYC_ListState* state, PSYC_Array *name, PSYC_Array* value, PSYC_Array* elem); From d019c261c4af48bbe725db5c72983b9b8df2be75 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Wed, 20 Apr 2011 15:36:56 +0200 Subject: [PATCH 057/378] typedef my enum! --- include/psyc.h | 4 ++-- include/psyc/parser.h | 10 ++++++---- src/match.c | 10 +++++----- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/include/psyc.h b/include/psyc.h index 3055da0..a0bb5bb 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -23,8 +23,8 @@ /** @brief Checks if short keyword string matches long keyword string */ -int PSYC_matches(uint8_t* sho, size_t slen, - uint8_t* lon, size_t llen); +int PSYC_matches(char* sho, size_t slen, + char* lon, size_t llen); /** @brief Callback for PSYC_text() that produces a value for a match * diff --git a/include/psyc/parser.h b/include/psyc/parser.h index 23ba5fc..5c4398e 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -20,10 +20,12 @@ /** Different types that a variable can have * - * This enum lists all the types that a variable - * in a psyc packet can have + * This enum lists PSYC variable types that + * this library is capable of checking for + * validity. Other variable types are treated + * as opaque data. */ -enum PSYC_Types { +typedef enum { PSYC_TYPE_AMOUNT, PSYC_TYPE_COLOR, PSYC_TYPE_DATE, @@ -36,7 +38,7 @@ enum PSYC_Types { PSYC_TYPE_PAGE, PSYC_TYPE_UNIFORM, PSYC_TYPE_TIME, -}; +} PSYC_Type; enum PSYC_Flags { diff --git a/src/match.c b/src/match.c index 8b159f4..1292c25 100644 --- a/src/match.c +++ b/src/match.c @@ -2,9 +2,9 @@ /* TODO: PSYC_inherits() */ -int PSYC_matches(uint8_t* sho, size_t slen, - uint8_t* lon, size_t llen) { - uint8_t *s, *l, *se, *le; +int PSYC_matches(char* sho, size_t slen, + char* lon, size_t llen) { + char *s, *l, *se, *le; if (!slen) slen = strlen(sho); if (!llen) llen = strlen(lon); @@ -35,10 +35,10 @@ int PSYC_matches(uint8_t* sho, size_t slen, /* doesn't always work this way.. FIXME */ *se = *le = '_'; sho++; lon++; - while(s = strchr(sho, '_')) { + while((s = strchr(sho, '_'))) { *s = 0; PT(("sho goes '%c' and lon goes '%c'\n", *sho, *lon)) - while(l = strchr(lon, '_')) { + while((l = strchr(lon, '_'))) { *l = 0; PT(("strcmp short '%s' long '%s'\n", sho, lon)) if (!strcmp(sho, lon)) goto foundone; From 45efc9e050129752a2447762f6588887be319179 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 20 Apr 2011 16:28:15 +0200 Subject: [PATCH 058/378] typedef enums, more doc --- include/psyc/parser.h | 61 +++++++++++++++++++++---------------------- src/parser.c | 11 ++++---- 2 files changed, 35 insertions(+), 37 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index 089504a..d54744d 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -42,16 +42,16 @@ typedef enum { PSYC_TYPE_TIME, } PSYC_Type; -enum PSYC_Flags +typedef enum { PSYC_HEADER_ONLY = 1, -}; +} PSYC_Flag; /** * The return value definitions for the packet parsing function. * @see PSYC_parse() */ -enum PSYC_ReturnCodes +typedef enum { PSYC_ERROR_END = -7, PSYC_ERROR_METHOD = -6, @@ -61,22 +61,28 @@ enum PSYC_ReturnCodes PSYC_ERROR_LENGTH = -2, PSYC_ERROR = -1, PSYC_SUCCESS = 0, - PSYC_BODY = 1, - 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, -}; + PSYC_INSUFFICIENT = 1, +/// Routing variable parsing done. Modifier, name & value contains the respective parts. + PSYC_ROUTING = 2, +/// Entity variable parsing done. Modifier, name & value contains the respective parts. + PSYC_ENTITY = 3, +/// Entity variable parsing is incomplete. Modifier & name are complete, value is incomplete. + PSYC_ENTITY_INCOMPLETE = 4, +/// Body parsing done, name contains method, value contains body. + PSYC_BODY = 5, +/// Body parsing is incomplete, name contains method, value contains part of the body. + PSYC_BODY_INCOMPLETE = 6, +/// Reached end of packet, parsing done. + PSYC_COMPLETE = 7, +// Binary value parsing incomplete, used internally. + PSYC_INCOMPLETE = 8, +} PSYC_ReturnCode; /** * The return value definitions for the list parsing function. * @see PSYC_parseList() */ -enum PSYC_ListReturnCodes +typedef enum { PSYC_ERROR_LIST_DELIM = -5, PSYC_ERROR_LIST_LEN = -4, @@ -86,12 +92,12 @@ enum PSYC_ListReturnCodes PSYC_LIST_ELEM = 1, PSYC_LIST_END = 2, PSYC_LIST_INCOMPLETE = 3, -}; +} PSYC_ListReturnCode; /** * PSYC packet parts. */ -enum PSYC_Parts +typedef enum { PSYC_PART_RESET = -1, PSYC_PART_HEADER = 0, @@ -100,17 +106,17 @@ enum PSYC_Parts PSYC_PART_METHOD, PSYC_PART_DATA, PSYC_PART_END, -}; +} PSYC_Part; /** * List types. * Possible types are text and binary. */ -enum PSYC_ListTypes +typedef enum { PSYC_LIST_TEXT = 1, PSYC_LIST_BINARY = 2, -}; +} PSYC_ListType; typedef struct { @@ -127,7 +133,7 @@ typedef struct size_t startc; ///< line start position PSYC_Array buffer; uint8_t flags; - char part; ///< part of the packet being parsed currently, see PSYC_Parts + PSYC_Part part; ///< part of the packet being parsed currently size_t contentParsed; ///< number of bytes parsed from the content so far size_t contentLength; ///< expected length of the content @@ -144,7 +150,7 @@ typedef struct size_t cursor; ///< current position in buffer size_t startc; ///< line start position PSYC_Array buffer; - char type; ///< list type, see PSYC_ListTypes + PSYC_ListType type; ///< list type size_t elemParsed; ///< number of bytes parsed from the elem so far size_t elemLength; ///< expected length of the elem @@ -169,7 +175,7 @@ inline PSYC_Array PSYC_createArray (uint8_t* const memory, size_t length) * 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. + * @param flags The flags that one ones to set, see PSYC_Flag. */ inline void PSYC_initState2 (PSYC_State* state, uint8_t flags ) { @@ -228,20 +234,13 @@ inline size_t PSYC_getContentLength (PSYC_State* s) * the variable or method and its length will be set accordingly * @param value A pointer to a PSYC_Array. It will point to the * value/body the variable/method and its length will be set accordingly - * - * @return one of PSYC_ReturnCodes - * @see PSYC_ReturnCodes - * @see PSYC_State - * @see PSYC_Array */ -int PSYC_parse(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value); +PSYC_ReturnCode PSYC_parse(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value); /** * List value parser. - * @return one of PSYC_ReturnCodes - * @see PSYC_ListReturnCodes */ -int PSYC_parseList(PSYC_ListState* state, PSYC_Array *name, PSYC_Array* value, PSYC_Array* elem); +PSYC_ListReturnCode PSYC_parseList(PSYC_ListState* state, PSYC_Array *name, PSYC_Array* value, PSYC_Array* elem); #endif // PSYC_PARSER_H diff --git a/src/parser.c b/src/parser.c index b039bbc..8fa9ce2 100644 --- a/src/parser.c +++ b/src/parser.c @@ -67,7 +67,7 @@ inline char isKwChar(uint8_t c) * It should contain one or more keyword characters. * @return PSYC_ERROR or PSYC_SUCCESS */ -inline int PSYC_parseName(PSYC_State* state, PSYC_Array* name) +inline PSYC_ReturnCode PSYC_parseName(PSYC_State* state, PSYC_Array* name) { name->ptr = state->buffer.ptr + state->cursor; name->length = 0; @@ -86,7 +86,7 @@ inline int PSYC_parseName(PSYC_State* state, PSYC_Array* name) * 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) +inline PSYC_ReturnCode PSYC_parseBinaryValue(PSYC_State* state, PSYC_Array* value, size_t* length, size_t* parsed) { size_t remaining = *length - *parsed; value->ptr = state->buffer.ptr + state->cursor; @@ -109,7 +109,7 @@ inline int PSYC_parseBinaryValue(PSYC_State* state, PSYC_Array* value, size_t* l * 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) +inline PSYC_ReturnCode PSYC_parseVar(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value) { *modifier = *(state->buffer.ptr + state->cursor); ADVANCE_CURSOR_OR_RETURN(PSYC_INSUFFICIENT); @@ -172,9 +172,8 @@ inline int PSYC_parseVar(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, /** * 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) +PSYC_ReturnCode 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 @@ -364,7 +363,7 @@ int PSYC_parse(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, PSYC_Arra * List value parser. * @return see PSYC_ListReturnCodes. */ -int PSYC_parseList(PSYC_ListState* state, PSYC_Array *name, PSYC_Array* value, PSYC_Array* elem) +PSYC_ListReturnCode PSYC_parseList(PSYC_ListState* state, PSYC_Array *name, PSYC_Array* value, PSYC_Array* elem) { if (state->cursor >= state->buffer.length) return PSYC_LIST_INCOMPLETE; From 1b3d5704c007bbff81dcb1896e359c1932c07590 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Wed, 20 Apr 2011 17:15:03 +0200 Subject: [PATCH 059/378] stupid gcc wants me to put extra () around the ret = --- include/psyc/parser.h | 2 +- tests/Makefile | 2 +- tests/testParser.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index d54744d..f03f6b4 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -121,7 +121,7 @@ typedef enum typedef struct { size_t length; - const uint8_t * ptr; + const uint8_t * ptr; // just an unsigned char for opaque data } PSYC_Array; /** diff --git a/tests/Makefile b/tests/Makefile index a9c8fe2..3f4dec0 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,5 +1,5 @@ CFLAGS=-I../include -DDEBUG -g -O0 -Wall -LDFLAGS=-L.. +LDFLAGS=-L../src LOADLIBES=-lpsyc TARGETS=testParser testMatch diff --git a/tests/testParser.c b/tests/testParser.c index a704409..7020354 100644 --- a/tests/testParser.c +++ b/tests/testParser.c @@ -24,7 +24,7 @@ int main(int argc, char** argv) PSYC_nextBuffer(&state, PSYC_createArray(buffer, index)); // try parsing that now - while (ret = PSYC_parse(&state, &modifier, &name, &value)) + while ((ret = PSYC_parse(&state, &modifier, &name, &value))) { switch (ret) { @@ -41,7 +41,7 @@ int main(int argc, char** argv) write(1, ">>> LIST START\n", 15); PSYC_initListState(&listState); PSYC_nextListBuffer(&listState, value); - while (ret = PSYC_parseList(&listState, &name, &value, &elem)) + while ((ret = PSYC_parseList(&listState, &name, &value, &elem))) { switch (ret) { From 4a8a77d4f4abe8301bcf881da4af1fdbcdaaf2fb Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Wed, 20 Apr 2011 18:59:27 +0200 Subject: [PATCH 060/378] clean version of PSYC_matches() --- src/Makefile | 4 ++-- src/match.c | 45 ++++++++++++++++++++++----------------------- tests/testMatch.c | 3 ++- tests/testParser.c | 1 + 4 files changed, 27 insertions(+), 26 deletions(-) diff --git a/src/Makefile b/src/Makefile index ae8bad9..837a9ce 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,4 +1,4 @@ -CFLAGS=-I../../include -DDEBUG -DPSYC_COMPILE_LIBRARY -g -O0 -Wall +CFLAGS=-I../../include -DDEBUG=2 -DPSYC_COMPILE_LIBRARY -g -O0 -Wall CC=cc -I../include # CC=clang @@ -17,7 +17,7 @@ lib: $S ar rcs libpsyc.a $O match: match.c - ${CC} -o $@ -DDEBUG=2 -DCMDTOOL -DTEST $< + ${CC} -o $@ -DDEBUG=4 -DCMDTOOL -DTEST $< it: match diff --git a/src/match.c b/src/match.c index 1292c25..a35a6e7 100644 --- a/src/match.c +++ b/src/match.c @@ -11,53 +11,52 @@ int PSYC_matches(char* sho, size_t slen, if (slen == 0 || *sho != '_' || llen == 0 || *lon != '_') { - PT(("Please use long format keywords (compact ones would be faster, I know..)\n")) + P1(("Please use long format keywords (compact ones would be faster, I know..)\n")) return -2; } if (slen > llen) { - PT(("The long string is shorter than the short one.\n")) + P1(("The long string is shorter than the short one.\n")) return -3; } if (slen == llen) { - if (!strcmp(sho, lon)) { - PT(("Identical arguments.\n")) + if (!strncmp(sho, lon, slen)) { + P1(("Identical arguments.\n")) return 0; } - PT(("Same length but different.\nNo match, but they could be related or have a common type.\n")) + P1(("Same length but different.\nNo match, but they could be related or have a common type.\n")) return -4; } - PT(("*start short '%s' long '%s'\n", sho, lon)) + P3(("# PSYC_matches short '%*s' in long '%*s' ?\n", slen, sho, llen, lon)) se = sho+slen; le = lon+llen; - /* doesn't always work this way.. FIXME */ - *se = *le = '_'; - sho++; lon++; - while((s = strchr(sho, '_'))) { - *s = 0; - PT(("sho goes '%c' and lon goes '%c'\n", *sho, *lon)) - while((l = strchr(lon, '_'))) { - *l = 0; - PT(("strcmp short '%s' long '%s'\n", sho, lon)) - if (!strcmp(sho, lon)) goto foundone; - if (l == le) goto failed; - *l = '_'; + sho++; lon++; slen--; llen--; + while(*sho && sho < se) { + P3(("# comparing short '%*s' (%d)\n", slen, sho, slen)) + unless (s = memchr(sho, '_', slen)) s = se; + P4(("# sho goes '%c' and lon goes '%c'\n", *sho, *lon)) + while(*lon && lon < le) { + P3(("# against long '%*s' (%d)\n", llen, lon, llen)) + unless (l = memchr(lon, '_', llen)) l = le; + P3(("# %d == %d && !strncmp '%*s', '%*s'\n", s-sho, l-lon, s-sho, sho, s-sho, lon)) + if (l-lon == s-sho && !strncmp(sho, lon, s-sho)) goto foundone; + P4(("# failed\n")) + llen -= l-lon + 1; lon = ++l; } goto failed; foundone: - PT(("found: short '%s' long '%s'\n", sho, lon)) - if (s == se) goto success; - *l = *s = '_'; + P3(("# found %d of short '%*s' and long '%*s'\n", s-sho, s-sho, sho, s-sho, lon)) + llen -= l-lon; + slen -= s-sho; sho = ++s; lon = ++l; } -success: return 0; failed: - PT(("No, they don't match.\n")) + P4(("No, they don't match.\n")) return 1; } diff --git a/tests/testMatch.c b/tests/testMatch.c index 933d217..a674aaa 100644 --- a/tests/testMatch.c +++ b/tests/testMatch.c @@ -5,8 +5,9 @@ int main() { if (PSYC_matches("_failure_delivery", 0, "_failure_unsuccessful_delivery_death", 0)) return -1; if (PSYC_matches("_failure_trash", 8, "_failure_unsuccessful_delivery_death", 0)) return -2; if (PSYC_matches("_unsuccessful", 0, "_failure_unsuccessful_delivery_death", 0)) return -3; - if (PSYC_matches("_fail", 0, "_failure_unsuccessful_delivery_death", 0)) return -4; + unless (PSYC_matches("_fail", 0, "_failure_unsuccessful_delivery_death", 0)) return -4; unless (PSYC_matches("_truthahn", 0, "_failure_unsuccessful_delivery_death", 0)) return -5; + puts("PSYC_matches passed all tests."); return 0; // passed all tests } diff --git a/tests/testParser.c b/tests/testParser.c index 7020354..107ec09 100644 --- a/tests/testParser.c +++ b/tests/testParser.c @@ -32,6 +32,7 @@ int main(int argc, char** argv) case PSYC_ENTITY: write(1, &modifier, 1); case PSYC_BODY: + // printf("the string is '%.*s'\n", name); write(1, name.ptr, name.length); write(1, " = ", 3); write(1, value.ptr, value.length); From 8e7236009ab29d62e5d55568233550546a27adf8 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 20 Apr 2011 19:18:35 +0200 Subject: [PATCH 061/378] moved types to psyc.h; added getVarType & isRoutingVar definitions; more doc --- include/psyc.h | 60 ++++++++++++++++++++++++++++++++++++++----- include/psyc/parser.h | 48 ++++++++++++---------------------- src/parser.c | 14 +++++++--- 3 files changed, 81 insertions(+), 41 deletions(-) diff --git a/include/psyc.h b/include/psyc.h index a0bb5bb..c4e15bb 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -1,9 +1,9 @@ /** @file psyc.h * - * @brief Main psyc interface providing crucial functionality + * @brief Main PSYC interface providing crucial functionality. */ -/** @mainpage Psyc Core Library +/** @mainpage PSYC Core Library * * @section intro_sec Introduction * @@ -12,21 +12,67 @@ * @section install_sec Installation * * @subsection step1 Step 1: Opening the box - * + * * etc... */ +#ifndef PSYC_H +# define PSYC_H + #include #include #define PSYC_EPOCH 1440444041 // 2015-08-24 21:20:41 CET (Monday) -/** @brief Checks if short keyword string matches long keyword string +typedef enum +{ + PSYC_FALSE = 0, + PSYC_TRUE = 1, +} PSYC_Bool; + +/** + * Different types that a variable can have. + * + * This enum lists PSYC variable types that + * this library is capable of checking for + * validity. Other variable types are treated + * as opaque data. + */ +typedef enum +{ + PSYC_TYPE_AMOUNT, + PSYC_TYPE_COLOR, + PSYC_TYPE_DATE, + PSYC_TYPE_DEGREE, + PSYC_TYPE_ENTITY, + PSYC_TYPE_FLAG, + PSYC_TYPE_LANGUAGE, + PSYC_TYPE_LIST, + PSYC_TYPE_NICK, + PSYC_TYPE_PAGE, + PSYC_TYPE_UNIFORM, + PSYC_TYPE_TIME, +} PSYC_Type; + +/** + * Get the type of variable name. + */ +PSYC_Type PSYC_getVarType(char* name, size_t len); + +/** + * Get the type of variable name. + */ +PSYC_Bool PSYC_isRoutingVar(char* name, size_t len); + + +/** + * Checks if short keyword string matches long keyword string. */ int PSYC_matches(char* sho, size_t slen, char* lon, size_t llen); -/** @brief Callback for PSYC_text() that produces a value for a match +/** + * Callback for PSYC_text() that produces a value for a match. * * The application looks up a match such as _fruit from [_fruit] and * if found writes its current value from its variable store into the @@ -37,7 +83,8 @@ int PSYC_matches(char* sho, size_t slen, typedef int (*PSYC_textCB)(uint8_t* match, size_t mlen, uint8_t** buffer, size_t * blen); -/** @brief Fills out text templates by asking a callback for content +/** + * Fills out text templates by asking a callback for content. * * Copies the contents of the template into the buffer while looking * for braceOpen and braceClose strings and calling the callback for @@ -54,3 +101,4 @@ int PSYC_text(uint8_t* template, size_t tlen, PSYC_textCB lookupValue, char* braceOpen, char* braceClose); +#endif // PSYC_H diff --git a/include/psyc/parser.h b/include/psyc/parser.h index f03f6b4..42a4d22 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -19,29 +19,6 @@ #include #include -/** - * Different types that a variable can have. - * - * This enum lists PSYC variable types that - * this library is capable of checking for - * validity. Other variable types are treated - * as opaque data. - */ -typedef enum { - PSYC_TYPE_AMOUNT, - PSYC_TYPE_COLOR, - PSYC_TYPE_DATE, - PSYC_TYPE_DEGREE, - PSYC_TYPE_ENTITY, - PSYC_TYPE_FLAG, - PSYC_TYPE_LANGUAGE, - PSYC_TYPE_LIST, - PSYC_TYPE_NICK, - PSYC_TYPE_PAGE, - PSYC_TYPE_UNIFORM, - PSYC_TYPE_TIME, -} PSYC_Type; - typedef enum { PSYC_HEADER_ONLY = 1, @@ -61,12 +38,18 @@ typedef enum PSYC_ERROR_LENGTH = -2, PSYC_ERROR = -1, PSYC_SUCCESS = 0, +/// Buffer contains insufficient amount of data. +/// Fill another buffer and concatenate it with the end of the current buffer, +/// from the cursor position to the end. PSYC_INSUFFICIENT = 1, -/// Routing variable parsing done. Modifier, name & value contains the respective parts. +/// Routing variable parsing done. +/// Modifier, name & value contains the respective parts. PSYC_ROUTING = 2, -/// Entity variable parsing done. Modifier, name & value contains the respective parts. +/// Entity variable parsing done. +/// Modifier, name & value contains the respective parts. PSYC_ENTITY = 3, -/// Entity variable parsing is incomplete. Modifier & name are complete, value is incomplete. +/// Entity variable parsing is incomplete. +/// Modifier & name are complete, value is incomplete. PSYC_ENTITY_INCOMPLETE = 4, /// Body parsing done, name contains method, value contains body. PSYC_BODY = 5, @@ -74,7 +57,7 @@ typedef enum PSYC_BODY_INCOMPLETE = 6, /// Reached end of packet, parsing done. PSYC_COMPLETE = 7, -// Binary value parsing incomplete, used internally. +/// Binary value parsing incomplete, used internally. PSYC_INCOMPLETE = 8, } PSYC_ReturnCode; @@ -89,8 +72,11 @@ typedef enum PSYC_ERROR_LIST_TYPE = -3, PSYC_ERROR_LIST_NAME = -2, PSYC_ERROR_LIST= -1, +/// Completed parsing a list element. PSYC_LIST_ELEM = 1, +/// Reached end of buffer. PSYC_LIST_END = 2, +/// Binary list is incomplete. PSYC_LIST_INCOMPLETE = 3, } PSYC_ListReturnCode; @@ -130,14 +116,14 @@ typedef struct typedef struct { size_t cursor; ///< current position in buffer - size_t startc; ///< line start position + size_t startc; ///< position where the parsing would be resumed PSYC_Array buffer; - uint8_t flags; + uint8_t flags; ///< flags for the parser, see PSYC_Flag PSYC_Part part; ///< part of the packet being parsed currently 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? + PSYC_Bool 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; @@ -175,7 +161,7 @@ inline PSYC_Array PSYC_createArray (uint8_t* const memory, size_t length) * 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_Flag. + * @param flags Flags to be set for the parser, see PSYC_Flag. */ inline void PSYC_initState2 (PSYC_State* state, uint8_t flags ) { diff --git a/src/parser.c b/src/parser.c index 8fa9ce2..5ce9aae 100644 --- a/src/parser.c +++ b/src/parser.c @@ -5,6 +5,7 @@ #include #endif +#include #include #define ADVANCE_CURSOR_OR_RETURN(ret) \ @@ -82,8 +83,13 @@ inline PSYC_ReturnCode PSYC_parseName(PSYC_State* state, PSYC_Array* name) } /** - * Parse binary data into value. - * length is the expected length of the data, parsed is the number of bytes parsed so far + * Parse binary data. + * + * @param state Parser state. + * @param value Start & length of parsed data is saved here. + * @param length Expected length of the data. + * @param parsed Number of bytes parsed so far. + * * @return PSYC_COMPLETE or PSYC_INCOMPLETE */ inline PSYC_ReturnCode PSYC_parseBinaryValue(PSYC_State* state, PSYC_Array* value, size_t* length, size_t* parsed) @@ -118,14 +124,14 @@ inline PSYC_ReturnCode PSYC_parseVar(PSYC_State* state, uint8_t* modifier, PSYC_ return PSYC_ERROR_VAR_NAME; value->length = 0; + state->valueLength = 0; + state->valueParsed = 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(PSYC_INSUFFICIENT); - state->valueLength = 0; - state->valueParsed = 0; if (isNumeric(state->buffer.ptr[state->cursor])) { From 99a396d487d6cc277c2635ef13ef42720ac62795 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Wed, 20 Apr 2011 21:36:33 +0200 Subject: [PATCH 062/378] how did this get here? --- tests/CMakeLists.txt | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 tests/CMakeLists.txt diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt deleted file mode 100644 index ecffeda..0000000 --- a/tests/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -cmake_minimum_required(VERSION 2.6) - - -FILE(GLOB SRC - parser.c - init.cpp - MainWindow.* - interface.cpp - Window.* - ConnectWindow.h - ) - -if(GTKMM_FOUND) - include_directories(${GTKMM_INCLUDE_DIRS}) - add_executable(nprog ${NPROG_CLIENT_SRC}) - target_link_libraries(nprog ${GTKMM_LIBRARIES} -pthread -lgthread-2.0 -lrt -lglib-2.0 ) -endif() - From 2efca8dc9601fb4702184622240f99ebcb216ad1 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Wed, 20 Apr 2011 22:22:55 +0200 Subject: [PATCH 063/378] memmem, not rendering yet --- include/psyc/lib.h | 5 ++++ include/psyc/render.h | 23 +++++++++++---- include/psyc/syntax.h | 5 ++-- src/Makefile | 4 +-- src/memmem.c | 67 +++++++++++++++++++++++++++++++++++++++++++ src/render.c | 24 ++++++++++++++++ 6 files changed, 119 insertions(+), 9 deletions(-) create mode 100644 src/memmem.c diff --git a/include/psyc/lib.h b/include/psyc/lib.h index 699f601..e6c8c6d 100644 --- a/include/psyc/lib.h +++ b/include/psyc/lib.h @@ -7,3 +7,8 @@ #define unless(COND) if (!(COND)) #define until(COND) while (!(COND)) +#ifndef _GNU_SOURCE +void *memmem(const void *haystack, size_t haystacklen, + const void *needle, size_t needlelen); +#endif + diff --git a/include/psyc/render.h b/include/psyc/render.h index 1b3f576..43eb0c7 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -1,13 +1,26 @@ -int PSYC_renderHeader(struct PSYC_Buffers* pbuf, +typedef enum { + PSYC_FINE = 0, + PSYC_NEED_LENGTH = 1 +} PSYC_RenderFlag; + +typedef struct { + PSYC_RenderFlag flag; ///< flags for the renderer + size_t cursor; ///< current position in buffer + size_t start; ///< position where the rendered packet starts + size_t length; ///< how big is the buffer we allocated + uint8_t buffer[]; ///< OMG a C99 feature! variable size buffer! +} PSYC_RenderState; + +int PSYC_renderHeader(PSYC_RenderState render, const uint8_t* name, const size_t nlength, const uint8_t* value, const size_t vlength, - const uchar flags, const uchar modifier); + const uint8_t flags, const uint8_t modifier); -int PSYC_renderBody(struct PSYC_Buffers* pbuf, +int PSYC_renderBody(PSYC_RenderState render, const uint8_t* method, const size_t mlength, const uint8_t* data, const size_t dlength, - const uchar flags); + const uint8_t flags); -int PSYC_doneRender(struct PSYC_Buffers* pbuf, +int PSYC_doneRender(PSYC_RenderState render, uint8_t** buf, size_t* written); diff --git a/include/psyc/syntax.h b/include/psyc/syntax.h index c15889e..004845e 100644 --- a/include/psyc/syntax.h +++ b/include/psyc/syntax.h @@ -10,8 +10,9 @@ # define PSYC_CONTENT_SIZE_THRESHOLD 444 #endif -#define C_GLYPH_PACKET_DELIMITER '.' -#define S_GLYPH_PACKET_DELIMITER "." +#define C_GLYPH_PACKET_DELIMITER '|' +#define S_GLYPH_PACKET_DELIMITER "|" +#define PSYC_PACKET_DELIMITER "\n|\n" #define C_GLYPH_SEPARATOR_KEYWORD '_' #define S_GLYPH_SEPARATOR_KEYWORD "_" diff --git a/src/Makefile b/src/Makefile index 837a9ce..5251245 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,8 +2,8 @@ CFLAGS=-I../../include -DDEBUG=2 -DPSYC_COMPILE_LIBRARY -g -O0 -Wall CC=cc -I../include # CC=clang -S=parser.c match.c -O=parser.o match.o +S=parser.c match.c render.c memmem.c +O=parser.o match.o render.o memmem.o default: @/bin/echo -e "Usage:\n\tmake diet - compile with diet libc\n\tmake lib - compile with normal gnu libc" diff --git a/src/memmem.c b/src/memmem.c new file mode 100644 index 0000000..a5e1ad3 --- /dev/null +++ b/src/memmem.c @@ -0,0 +1,67 @@ +#ifndef _GNU_SOURCE + +/* Copyright (C) 1991,92,93,94,96,97,98,2000,2004,2007 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* +#ifndef _LIBC +# include +#endif +*/ + +#include +#include + +#ifndef _LIBC +# define __builtin_expect(expr, val) (expr) +#endif + +#undef memmem + +/* Return the first occurrence of NEEDLE in HAYSTACK. */ +void * +memmem (haystack, haystack_len, needle, needle_len) + const void *haystack; + size_t haystack_len; + const void *needle; + size_t needle_len; +{ + const char *begin; + const char *const last_possible + = (const char *) haystack + haystack_len - needle_len; + + if (needle_len == 0) + /* The first occurrence of the empty string is deemed to occur at + the beginning of the string. */ + return (void *) haystack; + + /* Sanity check, otherwise the loop might search through the whole + memory. */ + if (__builtin_expect (haystack_len < needle_len, 0)) + return NULL; + + for (begin = (const char *) haystack; begin <= last_possible; ++begin) + if (begin[0] == ((const char *) needle)[0] && + !memcmp ((const void *) &begin[1], + (const void *) ((const char *) needle + 1), + needle_len - 1)) + return (void *) begin; + + return NULL; +} + +#endif diff --git a/src/render.c b/src/render.c index 595b8e1..269fba0 100644 --- a/src/render.c +++ b/src/render.c @@ -1 +1,25 @@ +#include "psyc/lib.h" +#include "psyc/render.h" +#include "psyc/syntax.h" + /* render PSYC packets */ + +int PSYC_renderBody(PSYC_RenderState render, + const uint8_t* method, const size_t mlength, + const uint8_t* data, const size_t dlength, + const uint8_t flags) { + + // find out if this packet needs a prepended length + if (dlength == 1 && data[0] == C_GLYPH_PACKET_DELIMITER) + render.flag = PSYC_NEED_LENGTH; + else if (dlength > 404) + render.flag = PSYC_NEED_LENGTH; + else if (memmem(data, dlength, PSYC_PACKET_DELIMITER, + sizeof(PSYC_PACKET_DELIMITER))) + render.flag = PSYC_NEED_LENGTH; + else + render.flag = PSYC_FINE; + + // TBD + return 0; +} From 44950099a18324860cec2ecb1dd4e9a278d5f175 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Wed, 20 Apr 2011 22:31:04 +0200 Subject: [PATCH 064/378] some typedef renames --- include/psyc/parser.h | 32 ++++++++++++++++---------------- src/parser.c | 14 +++++++------- tests/testParser.c | 2 +- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index 42a4d22..edc15c7 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -22,7 +22,7 @@ typedef enum { PSYC_HEADER_ONLY = 1, -} PSYC_Flag; +} PSYC_ParserFlag; /** * The return value definitions for the packet parsing function. @@ -59,7 +59,7 @@ typedef enum PSYC_COMPLETE = 7, /// Binary value parsing incomplete, used internally. PSYC_INCOMPLETE = 8, -} PSYC_ReturnCode; +} PSYC_ParseRC; /** * The return value definitions for the list parsing function. @@ -78,7 +78,7 @@ typedef enum PSYC_LIST_END = 2, /// Binary list is incomplete. PSYC_LIST_INCOMPLETE = 3, -} PSYC_ListReturnCode; +} PSYC_ListRC; /** * PSYC packet parts. @@ -108,7 +108,7 @@ typedef struct { size_t length; const uint8_t * ptr; // just an unsigned char for opaque data -} PSYC_Array; +} PSYC_Array; // to be renamed or solved differently.. /** * Struct for keeping parser state. @@ -118,7 +118,7 @@ typedef struct size_t cursor; ///< current position in buffer size_t startc; ///< position where the parsing would be resumed PSYC_Array buffer; - uint8_t flags; ///< flags for the parser, see PSYC_Flag + uint8_t flags; ///< flags for the parser, see PSYC_ParserFlag PSYC_Part part; ///< part of the packet being parsed currently size_t contentParsed; ///< number of bytes parsed from the content so far @@ -126,7 +126,7 @@ typedef struct PSYC_Bool 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; +} PSYC_ParserState; /** * Struct for keeping list parser state. @@ -161,11 +161,11 @@ inline PSYC_Array PSYC_createArray (uint8_t* const memory, size_t length) * Initiates the state struct with flags. * * @param state Pointer to the state struct that should be initiated. - * @param flags Flags to be set for the parser, see PSYC_Flag. + * @param flags Flags to be set for the parser, see PSYC_ParserFlag. */ -inline void PSYC_initState2 (PSYC_State* state, uint8_t flags ) +inline void PSYC_initState2 (PSYC_ParserState* state, uint8_t flags ) { - memset(state, 0, sizeof(PSYC_State)); + memset(state, 0, sizeof(PSYC_ParserState)); state->flags = flags; } @@ -174,9 +174,9 @@ inline void PSYC_initState2 (PSYC_State* state, uint8_t flags ) * * @param state Pointer to the state struct that should be initiated. */ -inline void PSYC_initState (PSYC_State* state) +inline void PSYC_initState (PSYC_ParserState* state) { - memset(state, 0, sizeof(PSYC_State)); + memset(state, 0, sizeof(PSYC_ParserState)); } /** @@ -189,7 +189,7 @@ inline void PSYC_initListState (PSYC_ListState* state) memset(state, 0, sizeof(PSYC_ListState)); } -inline void PSYC_nextBuffer (PSYC_State* state, PSYC_Array newBuf) +inline void PSYC_nextBuffer (PSYC_ParserState* state, PSYC_Array newBuf) { state->buffer = newBuf; state->cursor = 0; @@ -201,7 +201,7 @@ inline void PSYC_nextListBuffer (PSYC_ListState* state, PSYC_Array newBuf) state->cursor = 0; } -inline size_t PSYC_getContentLength (PSYC_State* s) +inline size_t PSYC_getContentLength (PSYC_ParserState* s) { return s->contentLength; } @@ -213,7 +213,7 @@ inline size_t PSYC_getContentLength (PSYC_State* s) * * Generalized line-based packet parser. * - * @param state An initialized PSYC_State + * @param state An initialized PSYC_ParserState * @param modifier A pointer to a character. In case of a variable, it will * be set to the modifier of that variable * @param name A pointer to a PSYC_Array. It will point to the name of @@ -221,12 +221,12 @@ inline size_t PSYC_getContentLength (PSYC_State* s) * @param value A pointer to a PSYC_Array. It will point to the * value/body the variable/method and its length will be set accordingly */ -PSYC_ReturnCode PSYC_parse(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value); +PSYC_ParseRC PSYC_parse(PSYC_ParserState* state, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value); /** * List value parser. */ -PSYC_ListReturnCode PSYC_parseList(PSYC_ListState* state, PSYC_Array *name, PSYC_Array* value, PSYC_Array* elem); +PSYC_ListRC PSYC_parseList(PSYC_ListState* state, PSYC_Array *name, PSYC_Array* value, PSYC_Array* elem); #endif // PSYC_PARSER_H diff --git a/src/parser.c b/src/parser.c index 5ce9aae..1f3b98a 100644 --- a/src/parser.c +++ b/src/parser.c @@ -68,7 +68,7 @@ inline char isKwChar(uint8_t c) * It should contain one or more keyword characters. * @return PSYC_ERROR or PSYC_SUCCESS */ -inline PSYC_ReturnCode PSYC_parseName(PSYC_State* state, PSYC_Array* name) +inline PSYC_ParseRC PSYC_parseName(PSYC_ParserState* state, PSYC_Array* name) { name->ptr = state->buffer.ptr + state->cursor; name->length = 0; @@ -92,7 +92,7 @@ inline PSYC_ReturnCode PSYC_parseName(PSYC_State* state, PSYC_Array* name) * * @return PSYC_COMPLETE or PSYC_INCOMPLETE */ -inline PSYC_ReturnCode PSYC_parseBinaryValue(PSYC_State* state, PSYC_Array* value, size_t* length, size_t* parsed) +inline PSYC_ParseRC PSYC_parseBinaryValue(PSYC_ParserState* state, PSYC_Array* value, size_t* length, size_t* parsed) { size_t remaining = *length - *parsed; value->ptr = state->buffer.ptr + state->cursor; @@ -115,7 +115,7 @@ inline PSYC_ReturnCode PSYC_parseBinaryValue(PSYC_State* state, PSYC_Array* valu * Parse simple or binary variable. * @return PSYC_ERROR or PSYC_SUCCESS */ -inline PSYC_ReturnCode PSYC_parseVar(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value) +inline PSYC_ParseRC PSYC_parseVar(PSYC_ParserState* state, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value) { *modifier = *(state->buffer.ptr + state->cursor); ADVANCE_CURSOR_OR_RETURN(PSYC_INSUFFICIENT); @@ -179,7 +179,7 @@ inline PSYC_ReturnCode PSYC_parseVar(PSYC_State* state, uint8_t* modifier, PSYC_ * Parse PSYC packets. * Generalized line-based parser. */ -PSYC_ReturnCode PSYC_parse(PSYC_State* state, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value) +PSYC_ParseRC PSYC_parse(PSYC_ParserState* state, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value) { int ret; // a return value size_t pos; // a cursor position @@ -367,9 +367,9 @@ PSYC_ReturnCode PSYC_parse(PSYC_State* state, uint8_t* modifier, PSYC_Array* nam /** * List value parser. - * @return see PSYC_ListReturnCodes. + * @return see PSYC_ListRC. */ -PSYC_ListReturnCode PSYC_parseList(PSYC_ListState* state, PSYC_Array *name, PSYC_Array* value, PSYC_Array* elem) +PSYC_ListRC PSYC_parseList(PSYC_ListState* state, PSYC_Array *name, PSYC_Array* value, PSYC_Array* elem) { if (state->cursor >= state->buffer.length) return PSYC_LIST_INCOMPLETE; @@ -440,7 +440,7 @@ PSYC_ListReturnCode PSYC_parseList(PSYC_ListState* state, PSYC_Array *name, PSYC // 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) + if (PSYC_parseBinaryValue((PSYC_ParserState*)state, elem, &(state->elemLength), &(state->elemParsed)) == PSYC_INCOMPLETE) return PSYC_LIST_INCOMPLETE; state->elemLength = 0; diff --git a/tests/testParser.c b/tests/testParser.c index 107ec09..a7fc065 100644 --- a/tests/testParser.c +++ b/tests/testParser.c @@ -8,7 +8,7 @@ int main(int argc, char** argv) int index, ret; uint8_t buffer[2048], modifier; PSYC_Array name, value, elem; - PSYC_State state; + PSYC_ParserState state; PSYC_ListState listState; int file = open(argv[1],O_RDONLY); From 13ffb3a120a6e99093096e0a1c7abb4ec2013cca Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Wed, 20 Apr 2011 23:08:20 +0200 Subject: [PATCH 065/378] PSYC_inherits() --- include/psyc.h | 6 ++++++ src/match.c | 42 +++++++++++++++++++++++++++++++++++++++--- tests/testMatch.c | 7 +++++++ 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/include/psyc.h b/include/psyc.h index c4e15bb..b7f5b8f 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -65,6 +65,12 @@ PSYC_Type PSYC_getVarType(char* name, size_t len); PSYC_Bool PSYC_isRoutingVar(char* name, size_t len); +/** + * Checks if long keyword string inherits from short keyword string. + */ +int PSYC_inherits(char* sho, size_t slen, + char* lon, size_t llen); + /** * Checks if short keyword string matches long keyword string. */ diff --git a/src/match.c b/src/match.c index a35a6e7..9cd79d0 100644 --- a/src/match.c +++ b/src/match.c @@ -1,6 +1,40 @@ #include "psyc/lib.h" -/* TODO: PSYC_inherits() */ +int PSYC_inherits(char* sho, size_t slen, + char* lon, size_t llen) { + if (!slen) slen = strlen(sho); + if (!llen) llen = strlen(lon); + + if (slen == 0 || *sho != '_' || + llen == 0 || *lon != '_') { + P1(("Please use long format keywords (compact ones would be faster, I know..)\n")) + return -2; + } + + if (slen > llen) { + P1(("The long string is shorter than the short one.\n")) + return -3; + } + + if (!strncmp(sho, lon, slen)) { + /* according to PSYC spec we have hereby already proved + * inheritance. the following check is optional! + */ + if (llen > slen && lon[slen] != '_') { + /* It is illegal to introduce a keyword family + * that starts just like an existing one. Since + * _failure exists, you can't use _fail. But + * implementations are not required to recognize + * that. + */ + P1(("Illegal choice of keyword names!\n")) + return -4; + } + return 0; + } + P4(("%*s does not inherit from %*s.\n", llen, lon, slen, sho)) + return 1; +} int PSYC_matches(char* sho, size_t slen, char* lon, size_t llen) { @@ -66,7 +100,9 @@ int main(int argc, char **argv) { printf("Usage: %s \n\nExample: %s _failure_delivery _failure_unsuccessful_delivery_death\n", argv[0], argv[0]); return -1; } - if (PSYC_matches((uint8_t*) argv[1], 0, (uint8_t*) argv[2], 0) == 0) - printf("Yes, they match!\n"); + if (PSYC_matches(argv[1], 0, argv[2], 0) == 0) + printf("Yes, %s matches %s!\n", argv[1], argv[2]); + if (PSYC_inherits(argv[1], 0, argv[2], 0) == 0) + printf("Yes, %s inherits from %s!\n", argv[2], argv[1]); } #endif diff --git a/tests/testMatch.c b/tests/testMatch.c index a674aaa..822a2d1 100644 --- a/tests/testMatch.c +++ b/tests/testMatch.c @@ -9,5 +9,12 @@ int main() { unless (PSYC_matches("_truthahn", 0, "_failure_unsuccessful_delivery_death", 0)) return -5; puts("PSYC_matches passed all tests."); + + unless (PSYC_inherits("_failure_delivery", 0, "_failure_unsuccessful_delivery_death", 0)) return -11; + if (PSYC_inherits("_failure_unsuccessful", 0, "_failure_unsuccessful_delivery_death", 0)) return -12; + unless (PSYC_inherits("_fail", 0, "_failure_unsuccessful_delivery_death", 0)) return -13; + + puts("PSYC_inherits passed all tests."); + return 0; // passed all tests } From 0841b3676f2c7425f1be93e99f3899b739ed3409 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Thu, 21 Apr 2011 14:20:24 +0200 Subject: [PATCH 066/378] renaming & moving stuff around; psyc logo --- .gitignore | 8 ++- Doxyfile | 4 +- Makefile | 12 ++-- doc/psyc.css | 3 + doc/psyc.svg | 71 +++++++++++++++++++ include/psyc.h | 25 ++++++- include/psyc/parser.h | 64 ++++++----------- include/psyc/render.h | 12 ++-- src/parser.c | 12 ++-- src/render.c | 10 +-- {tests => test}/Makefile | 0 {tests => test}/packets/binary.txt | 0 .../packets/enter_leave_context.txt | 0 {tests => test}/packets/fake_dns.txt | 0 {tests => test}/packets/invalid_dns.txt | 0 {tests => test}/packets/test-0-no-content | 0 {tests => test}/packets/test-1 | 0 {tests => test}/packets/test-1-length | 0 {tests => test}/packets/test-1-length-error | 0 {tests => test}/packets/test-1-utf8 | 0 {tests => test}/packets/test-2-list | 0 {tests => test}/packets/test-2-list-error | 0 {tests => test}/packets/test-3-list | 0 {tests => test}/packets/test-4-circuit | 0 {tests => test}/packets/test-4-circuit-n | 0 .../packets/test-5-message-private | 0 .../packets/test-6-message-private-remote | 0 {tests => test}/testMatch.c | 0 {tests => test}/testParser.c | 5 +- 29 files changed, 153 insertions(+), 73 deletions(-) create mode 100644 doc/psyc.css create mode 100644 doc/psyc.svg rename {tests => test}/Makefile (100%) rename {tests => test}/packets/binary.txt (100%) rename {tests => test}/packets/enter_leave_context.txt (100%) rename {tests => test}/packets/fake_dns.txt (100%) rename {tests => test}/packets/invalid_dns.txt (100%) rename {tests => test}/packets/test-0-no-content (100%) rename {tests => test}/packets/test-1 (100%) rename {tests => test}/packets/test-1-length (100%) rename {tests => test}/packets/test-1-length-error (100%) rename {tests => test}/packets/test-1-utf8 (100%) rename {tests => test}/packets/test-2-list (100%) rename {tests => test}/packets/test-2-list-error (100%) rename {tests => test}/packets/test-3-list (100%) rename {tests => test}/packets/test-4-circuit (100%) rename {tests => test}/packets/test-4-circuit-n (100%) rename {tests => test}/packets/test-5-message-private (100%) rename {tests => test}/packets/test-6-message-private-remote (100%) rename {tests => test}/testMatch.c (100%) rename {tests => test}/testParser.c (95%) diff --git a/.gitignore b/.gitignore index 15152b7..81af87c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,9 @@ -doc/ +doc/html +doc/latex +doc/man src/match -tests/testMatch -tests/testParser +test/testMatch +test/testParser .config ~$* diff --git a/Doxyfile b/Doxyfile index aa9c07c..98a81ba 100644 --- a/Doxyfile +++ b/Doxyfile @@ -44,7 +44,7 @@ PROJECT_BRIEF = "PSYC core library" # exceed 55 pixels and the maximum width should not exceed 200 pixels. # Doxygen will copy the logo to the output directory. -PROJECT_LOGO = +PROJECT_LOGO = doc/psyc.svg # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. @@ -875,7 +875,7 @@ HTML_FOOTER = # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! -HTML_STYLESHEET = +HTML_STYLESHEET = doc/psyc.css # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. # Doxygen will adjust the colors in the stylesheet and background images diff --git a/Makefile b/Makefile index 6ba55b6..c0c5d6f 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ .PHONY: doc -.PHONY: tests +.PHONY: test default: - @/bin/echo -e "Usage:\n\tmake diet - compile with diet libc\n\tmake lib - compile with normal gnu libc\n\tmake tests\n\tmake doc" + @/bin/echo -e "Usage:\n\tmake diet - compile with diet libc\n\tmake lib - compile with normal gnu libc\n\tmake test\n\tmake doc" lib: make -C src lib @@ -10,13 +10,13 @@ lib: diet: make -C src diet -tests: - make -C tests +test: + make -C test doc: doxygen clean: make -C src clean - make -C tests clean - rm -rf doc + make -C test clean + rm -rf doc/html doc/latex doc/man diff --git a/doc/psyc.css b/doc/psyc.css new file mode 100644 index 0000000..afe3cac --- /dev/null +++ b/doc/psyc.css @@ -0,0 +1,3 @@ +#projectlogo img { + height: 50px; +} diff --git a/doc/psyc.svg b/doc/psyc.svg new file mode 100644 index 0000000..9a9dbf3 --- /dev/null +++ b/doc/psyc.svg @@ -0,0 +1,71 @@ + + + diff --git a/include/psyc.h b/include/psyc.h index b7f5b8f..16ad97d 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -30,6 +30,20 @@ typedef enum PSYC_TRUE = 1, } PSYC_Bool; +/** + * PSYC packet parts. + */ +typedef enum +{ + PSYC_PART_RESET = -1, + PSYC_PART_HEADER = 0, + PSYC_PART_LENGTH, + PSYC_PART_CONTENT, + PSYC_PART_METHOD, + PSYC_PART_DATA, + PSYC_PART_END, +} PSYC_Part; + /** * Different types that a variable can have. * @@ -54,6 +68,16 @@ typedef enum PSYC_TYPE_TIME, } PSYC_Type; +/** + * List types. + * Possible types are text and binary. + */ +typedef enum +{ + PSYC_LIST_TEXT = 1, + PSYC_LIST_BINARY = 2, +} PSYC_ListType; + /** * Get the type of variable name. */ @@ -64,7 +88,6 @@ PSYC_Type PSYC_getVarType(char* name, size_t len); */ PSYC_Bool PSYC_isRoutingVar(char* name, size_t len); - /** * Checks if long keyword string inherits from short keyword string. */ diff --git a/include/psyc/parser.h b/include/psyc/parser.h index edc15c7..b669ca5 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -22,7 +22,7 @@ typedef enum { PSYC_HEADER_ONLY = 1, -} PSYC_ParserFlag; +} PSYC_ParseFlag; /** * The return value definitions for the packet parsing function. @@ -78,36 +78,12 @@ typedef enum PSYC_LIST_END = 2, /// Binary list is incomplete. PSYC_LIST_INCOMPLETE = 3, -} PSYC_ListRC; - -/** - * PSYC packet parts. - */ -typedef enum -{ - PSYC_PART_RESET = -1, - PSYC_PART_HEADER = 0, - PSYC_PART_LENGTH, - PSYC_PART_CONTENT, - PSYC_PART_METHOD, - PSYC_PART_DATA, - PSYC_PART_END, -} PSYC_Part; - -/** - * List types. - * Possible types are text and binary. - */ -typedef enum -{ - PSYC_LIST_TEXT = 1, - PSYC_LIST_BINARY = 2, -} PSYC_ListType; +} PSYC_ParseListRC; typedef struct { size_t length; - const uint8_t * ptr; // just an unsigned char for opaque data + const uint8_t* ptr; // just an unsigned char for opaque data } PSYC_Array; // to be renamed or solved differently.. /** @@ -117,8 +93,8 @@ typedef struct { size_t cursor; ///< current position in buffer size_t startc; ///< position where the parsing would be resumed - PSYC_Array buffer; - uint8_t flags; ///< flags for the parser, see PSYC_ParserFlag + PSYC_Array buffer; ///< buffer with data to be parsed + uint8_t flags; ///< flags for the parser, see PSYC_ParseFlag PSYC_Part part; ///< part of the packet being parsed currently size_t contentParsed; ///< number of bytes parsed from the content so far @@ -126,7 +102,7 @@ typedef struct PSYC_Bool 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_ParserState; +} PSYC_ParseState; /** * Struct for keeping list parser state. @@ -140,7 +116,7 @@ typedef struct size_t elemParsed; ///< number of bytes parsed from the elem so far size_t elemLength; ///< expected length of the elem -} PSYC_ListState; +} PSYC_ParseListState; #ifndef PSYC_COMPILE_LIBRARY /** @@ -161,11 +137,11 @@ inline PSYC_Array PSYC_createArray (uint8_t* const memory, size_t length) * Initiates the state struct with flags. * * @param state Pointer to the state struct that should be initiated. - * @param flags Flags to be set for the parser, see PSYC_ParserFlag. + * @param flags Flags to be set for the parser, see PSYC_ParseFlag. */ -inline void PSYC_initState2 (PSYC_ParserState* state, uint8_t flags ) +inline void PSYC_initState2 (PSYC_ParseState* state, uint8_t flags) { - memset(state, 0, sizeof(PSYC_ParserState)); + memset(state, 0, sizeof(PSYC_ParseState)); state->flags = flags; } @@ -174,9 +150,9 @@ inline void PSYC_initState2 (PSYC_ParserState* state, uint8_t flags ) * * @param state Pointer to the state struct that should be initiated. */ -inline void PSYC_initState (PSYC_ParserState* state) +inline void PSYC_initState (PSYC_ParseState* state) { - memset(state, 0, sizeof(PSYC_ParserState)); + memset(state, 0, sizeof(PSYC_ParseState)); } /** @@ -184,24 +160,24 @@ inline void PSYC_initState (PSYC_ParserState* state) * * @param state Pointer to the list state struct that should be initiated. */ -inline void PSYC_initListState (PSYC_ListState* state) +inline void PSYC_initListState (PSYC_ParseListState* state) { - memset(state, 0, sizeof(PSYC_ListState)); + memset(state, 0, sizeof(PSYC_ParseListState)); } -inline void PSYC_nextBuffer (PSYC_ParserState* state, PSYC_Array newBuf) +inline void PSYC_nextBuffer (PSYC_ParseState* state, PSYC_Array newBuf) { state->buffer = newBuf; state->cursor = 0; } -inline void PSYC_nextListBuffer (PSYC_ListState* state, PSYC_Array newBuf) +inline void PSYC_nextListBuffer (PSYC_ParseListState* state, PSYC_Array newBuf) { state->buffer = newBuf; state->cursor = 0; } -inline size_t PSYC_getContentLength (PSYC_ParserState* s) +inline size_t PSYC_getContentLength (PSYC_ParseState* s) { return s->contentLength; } @@ -213,7 +189,7 @@ inline size_t PSYC_getContentLength (PSYC_ParserState* s) * * Generalized line-based packet parser. * - * @param state An initialized PSYC_ParserState + * @param state An initialized PSYC_ParseState * @param modifier A pointer to a character. In case of a variable, it will * be set to the modifier of that variable * @param name A pointer to a PSYC_Array. It will point to the name of @@ -221,12 +197,12 @@ inline size_t PSYC_getContentLength (PSYC_ParserState* s) * @param value A pointer to a PSYC_Array. It will point to the * value/body the variable/method and its length will be set accordingly */ -PSYC_ParseRC PSYC_parse(PSYC_ParserState* state, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value); +PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value); /** * List value parser. */ -PSYC_ListRC PSYC_parseList(PSYC_ListState* state, PSYC_Array *name, PSYC_Array* value, PSYC_Array* elem); +PSYC_ParseListRC PSYC_parseList(PSYC_ParseListState* state, PSYC_Array *name, PSYC_Array* value, PSYC_Array* elem); #endif // PSYC_PARSER_H diff --git a/include/psyc/render.h b/include/psyc/render.h index 43eb0c7..52bf0c8 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -1,3 +1,6 @@ +/** + * Struct for keeping render state. + */ typedef enum { PSYC_FINE = 0, PSYC_NEED_LENGTH = 1 @@ -5,22 +8,23 @@ typedef enum { typedef struct { PSYC_RenderFlag flag; ///< flags for the renderer + PSYC_Part part; ///< part of the packet being rendered size_t cursor; ///< current position in buffer size_t start; ///< position where the rendered packet starts + size_t contentLength; ///< length of the content part size_t length; ///< how big is the buffer we allocated uint8_t buffer[]; ///< OMG a C99 feature! variable size buffer! } PSYC_RenderState; -int PSYC_renderHeader(PSYC_RenderState render, +int PSYC_renderHeader(PSYC_RenderState* render, const uint8_t* name, const size_t nlength, const uint8_t* value, const size_t vlength, const uint8_t flags, const uint8_t modifier); -int PSYC_renderBody(PSYC_RenderState render, +int PSYC_renderBody(PSYC_RenderState* render, const uint8_t* method, const size_t mlength, const uint8_t* data, const size_t dlength, const uint8_t flags); -int PSYC_doneRender(PSYC_RenderState render, +int PSYC_doneRender(PSYC_RenderState* render, uint8_t** buf, size_t* written); - diff --git a/src/parser.c b/src/parser.c index 1f3b98a..264b0d7 100644 --- a/src/parser.c +++ b/src/parser.c @@ -68,7 +68,7 @@ inline char isKwChar(uint8_t c) * It should contain one or more keyword characters. * @return PSYC_ERROR or PSYC_SUCCESS */ -inline PSYC_ParseRC PSYC_parseName(PSYC_ParserState* state, PSYC_Array* name) +inline PSYC_ParseRC PSYC_parseName(PSYC_ParseState* state, PSYC_Array* name) { name->ptr = state->buffer.ptr + state->cursor; name->length = 0; @@ -92,7 +92,7 @@ inline PSYC_ParseRC PSYC_parseName(PSYC_ParserState* state, PSYC_Array* name) * * @return PSYC_COMPLETE or PSYC_INCOMPLETE */ -inline PSYC_ParseRC PSYC_parseBinaryValue(PSYC_ParserState* state, PSYC_Array* value, size_t* length, size_t* parsed) +inline PSYC_ParseRC PSYC_parseBinaryValue(PSYC_ParseState* state, PSYC_Array* value, size_t* length, size_t* parsed) { size_t remaining = *length - *parsed; value->ptr = state->buffer.ptr + state->cursor; @@ -115,7 +115,7 @@ inline PSYC_ParseRC PSYC_parseBinaryValue(PSYC_ParserState* state, PSYC_Array* v * Parse simple or binary variable. * @return PSYC_ERROR or PSYC_SUCCESS */ -inline PSYC_ParseRC PSYC_parseVar(PSYC_ParserState* state, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value) +inline PSYC_ParseRC PSYC_parseVar(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value) { *modifier = *(state->buffer.ptr + state->cursor); ADVANCE_CURSOR_OR_RETURN(PSYC_INSUFFICIENT); @@ -179,7 +179,7 @@ inline PSYC_ParseRC PSYC_parseVar(PSYC_ParserState* state, uint8_t* modifier, PS * Parse PSYC packets. * Generalized line-based parser. */ -PSYC_ParseRC PSYC_parse(PSYC_ParserState* state, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value) +PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value) { int ret; // a return value size_t pos; // a cursor position @@ -369,7 +369,7 @@ PSYC_ParseRC PSYC_parse(PSYC_ParserState* state, uint8_t* modifier, PSYC_Array* * List value parser. * @return see PSYC_ListRC. */ -PSYC_ListRC PSYC_parseList(PSYC_ListState* state, PSYC_Array *name, PSYC_Array* value, PSYC_Array* elem) +PSYC_ParseListRC PSYC_parseList(PSYC_ParseListState* state, PSYC_Array *name, PSYC_Array* value, PSYC_Array* elem) { if (state->cursor >= state->buffer.length) return PSYC_LIST_INCOMPLETE; @@ -440,7 +440,7 @@ PSYC_ListRC PSYC_parseList(PSYC_ListState* state, PSYC_Array *name, PSYC_Array* // Start or resume parsing the binary data if (state->elemParsed < state->elemLength) { - if (PSYC_parseBinaryValue((PSYC_ParserState*)state, elem, &(state->elemLength), &(state->elemParsed)) == PSYC_INCOMPLETE) + if (PSYC_parseBinaryValue((PSYC_ParseState*)state, elem, &(state->elemLength), &(state->elemParsed)) == PSYC_INCOMPLETE) return PSYC_LIST_INCOMPLETE; state->elemLength = 0; diff --git a/src/render.c b/src/render.c index 269fba0..2bdec60 100644 --- a/src/render.c +++ b/src/render.c @@ -4,21 +4,21 @@ /* render PSYC packets */ -int PSYC_renderBody(PSYC_RenderState render, +int PSYC_renderBody(PSYC_RenderState* render, const uint8_t* method, const size_t mlength, const uint8_t* data, const size_t dlength, const uint8_t flags) { // find out if this packet needs a prepended length if (dlength == 1 && data[0] == C_GLYPH_PACKET_DELIMITER) - render.flag = PSYC_NEED_LENGTH; + render->flag = PSYC_NEED_LENGTH; else if (dlength > 404) - render.flag = PSYC_NEED_LENGTH; + render->flag = PSYC_NEED_LENGTH; else if (memmem(data, dlength, PSYC_PACKET_DELIMITER, sizeof(PSYC_PACKET_DELIMITER))) - render.flag = PSYC_NEED_LENGTH; + render->flag = PSYC_NEED_LENGTH; else - render.flag = PSYC_FINE; + render->flag = PSYC_FINE; // TBD return 0; diff --git a/tests/Makefile b/test/Makefile similarity index 100% rename from tests/Makefile rename to test/Makefile diff --git a/tests/packets/binary.txt b/test/packets/binary.txt similarity index 100% rename from tests/packets/binary.txt rename to test/packets/binary.txt diff --git a/tests/packets/enter_leave_context.txt b/test/packets/enter_leave_context.txt similarity index 100% rename from tests/packets/enter_leave_context.txt rename to test/packets/enter_leave_context.txt diff --git a/tests/packets/fake_dns.txt b/test/packets/fake_dns.txt similarity index 100% rename from tests/packets/fake_dns.txt rename to test/packets/fake_dns.txt diff --git a/tests/packets/invalid_dns.txt b/test/packets/invalid_dns.txt similarity index 100% rename from tests/packets/invalid_dns.txt rename to test/packets/invalid_dns.txt diff --git a/tests/packets/test-0-no-content b/test/packets/test-0-no-content similarity index 100% rename from tests/packets/test-0-no-content rename to test/packets/test-0-no-content diff --git a/tests/packets/test-1 b/test/packets/test-1 similarity index 100% rename from tests/packets/test-1 rename to test/packets/test-1 diff --git a/tests/packets/test-1-length b/test/packets/test-1-length similarity index 100% rename from tests/packets/test-1-length rename to test/packets/test-1-length diff --git a/tests/packets/test-1-length-error b/test/packets/test-1-length-error similarity index 100% rename from tests/packets/test-1-length-error rename to test/packets/test-1-length-error diff --git a/tests/packets/test-1-utf8 b/test/packets/test-1-utf8 similarity index 100% rename from tests/packets/test-1-utf8 rename to test/packets/test-1-utf8 diff --git a/tests/packets/test-2-list b/test/packets/test-2-list similarity index 100% rename from tests/packets/test-2-list rename to test/packets/test-2-list diff --git a/tests/packets/test-2-list-error b/test/packets/test-2-list-error similarity index 100% rename from tests/packets/test-2-list-error rename to test/packets/test-2-list-error diff --git a/tests/packets/test-3-list b/test/packets/test-3-list similarity index 100% rename from tests/packets/test-3-list rename to test/packets/test-3-list diff --git a/tests/packets/test-4-circuit b/test/packets/test-4-circuit similarity index 100% rename from tests/packets/test-4-circuit rename to test/packets/test-4-circuit diff --git a/tests/packets/test-4-circuit-n b/test/packets/test-4-circuit-n similarity index 100% rename from tests/packets/test-4-circuit-n rename to test/packets/test-4-circuit-n diff --git a/tests/packets/test-5-message-private b/test/packets/test-5-message-private similarity index 100% rename from tests/packets/test-5-message-private rename to test/packets/test-5-message-private diff --git a/tests/packets/test-6-message-private-remote b/test/packets/test-6-message-private-remote similarity index 100% rename from tests/packets/test-6-message-private-remote rename to test/packets/test-6-message-private-remote diff --git a/tests/testMatch.c b/test/testMatch.c similarity index 100% rename from tests/testMatch.c rename to test/testMatch.c diff --git a/tests/testParser.c b/test/testParser.c similarity index 95% rename from tests/testParser.c rename to test/testParser.c index a7fc065..c743462 100644 --- a/tests/testParser.c +++ b/test/testParser.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -8,8 +9,8 @@ int main(int argc, char** argv) int index, ret; uint8_t buffer[2048], modifier; PSYC_Array name, value, elem; - PSYC_ParserState state; - PSYC_ListState listState; + PSYC_ParseState state; + PSYC_ParseListState listState; int file = open(argv[1],O_RDONLY); if(file < 0) From f31a44ea6a423b4c982c06d7f5391292ff4c8079 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Fri, 22 Apr 2011 11:50:13 +0200 Subject: [PATCH 067/378] RenderHeader --- .gitignore | 1 + include/psyc/render.h | 21 +++++++++++++-------- src/render.c | 36 +++++++++++++++++++++++++++++++----- test/Makefile | 4 +++- test/testRender.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 90 insertions(+), 14 deletions(-) create mode 100644 test/testRender.c diff --git a/.gitignore b/.gitignore index 81af87c..6804378 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ doc/man src/match test/testMatch test/testParser +test/testRender .config ~$* diff --git a/include/psyc/render.h b/include/psyc/render.h index 52bf0c8..c236aa4 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -1,3 +1,5 @@ +#include "syntax.h" + /** * Struct for keeping render state. */ @@ -6,25 +8,28 @@ typedef enum { PSYC_NEED_LENGTH = 1 } PSYC_RenderFlag; +typedef enum { + PSYC_FLAG_ROUTING = 1 +} PSYC_RenderHeaderFlag; + typedef struct { PSYC_RenderFlag flag; ///< flags for the renderer PSYC_Part part; ///< part of the packet being rendered size_t cursor; ///< current position in buffer - size_t start; ///< position where the rendered packet starts + size_t spot; ///< space for rendered length between the headers size_t contentLength; ///< length of the content part size_t length; ///< how big is the buffer we allocated - uint8_t buffer[]; ///< OMG a C99 feature! variable size buffer! + char buffer[]; ///< OMG a C99 feature! variable size buffer! } PSYC_RenderState; int PSYC_renderHeader(PSYC_RenderState* render, - const uint8_t* name, const size_t nlength, - const uint8_t* value, const size_t vlength, - const uint8_t flags, const uint8_t modifier); + const char* name, size_t nlength, + const char* value, size_t vlength, + PSYC_RenderHeaderFlag flags, char modifier); int PSYC_renderBody(PSYC_RenderState* render, - const uint8_t* method, const size_t mlength, - const uint8_t* data, const size_t dlength, - const uint8_t flags); + const char* method, size_t mlength, + const char* data, size_t dlength); int PSYC_doneRender(PSYC_RenderState* render, uint8_t** buf, size_t* written); diff --git a/src/render.c b/src/render.c index 2bdec60..bf5e039 100644 --- a/src/render.c +++ b/src/render.c @@ -1,13 +1,39 @@ #include "psyc/lib.h" #include "psyc/render.h" -#include "psyc/syntax.h" -/* render PSYC packets */ +int PSYC_renderHeader(PSYC_RenderState* r, + const char* name, size_t nlength, + const char* value, size_t vlength, + const PSYC_RenderHeaderFlag flags, + char modifier) { + unless (nlength) nlength = strlen(name); + // vlength 0 means an empty variable.. no cheating there + unless (modifier) modifier = C_GLYPH_MODIFIER_SET; + + r->buffer[r->cursor++] = modifier; + strncpy(&r->buffer[r->cursor], name, nlength); + r->cursor += nlength; + if (vlength) { + r->buffer[r->cursor++] = '\t'; + strncpy(&r->buffer[r->cursor], value, vlength); + r->cursor += vlength; + } + + if (flags == PSYC_FLAG_ROUTING) { + if (r->spot != 0) { + P1(("Too late to add a routing variable!\n")) + return -1; + } + } else if (r->spot == 0) { + // add "\n000000000" to buffer + // and make spot point to the first 0 + } + return 0; +} int PSYC_renderBody(PSYC_RenderState* render, - const uint8_t* method, const size_t mlength, - const uint8_t* data, const size_t dlength, - const uint8_t flags) { + const char* method, size_t mlength, + const char* data, size_t dlength) { // find out if this packet needs a prepended length if (dlength == 1 && data[0] == C_GLYPH_PACKET_DELIMITER) diff --git a/test/Makefile b/test/Makefile index 3f4dec0..fd61356 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,7 +1,7 @@ CFLAGS=-I../include -DDEBUG -g -O0 -Wall LDFLAGS=-L../src LOADLIBES=-lpsyc -TARGETS=testParser testMatch +TARGETS=testParser testMatch testRender all: $(TARGETS) @@ -10,3 +10,5 @@ test: clean: rm -f $(TARGETS) + +it: all diff --git a/test/testRender.c b/test/testRender.c new file mode 100644 index 0000000..c69b1c0 --- /dev/null +++ b/test/testRender.c @@ -0,0 +1,42 @@ +#include +#include "../include/psyc/lib.h" +#include "../include/psyc/render.h" + +#define myUNI "psyc://10.100.1000/~ludwig" + +/* example renderer generating a presence packet */ +int writePresence(const char *avail, int availlen, const char *desc, int desclen) { + PSYC_RenderState *pb; // a chunk of mem will host both struct and buf1 +// char *t; +// unsigned int l; + + unless (availlen) availlen = strlen(avail); + unless (desclen) desclen = strlen(desc); + + if (!(pb = malloc(512))) { + P0(("Out of memory\n")) + return -1; + } +// if (PSYC_initBuffer(pb, WHATEVER)) die("PSYC_initBuffer hates me"); + + (void) PSYC_renderHeader(pb, "_context", 0, + myUNI, sizeof(myUNI), PSYC_FLAG_ROUTING, 0); + + // the first call to PSYC_renderHeader() without PSYC_FLAG_ROUTING adds the + // extra newline to the buffer. later vars with PSYC_FLAG_ROUTING cause an error. + (void) PSYC_renderHeader(pb, "_degree_availability", 0, avail, availlen, 0, C_GLYPH_MODIFIER_ASSIGN); + (void) PSYC_renderHeader(pb, "_description_presence", 0, desc, desclen, 0, C_GLYPH_MODIFIER_ASSIGN); + // presence is to be assigned permanently in distributed state + + (void) PSYC_renderBody(pb, "_notice_presence", 0, + NULL, 0); // no data in packet +// (void) PSYC_doneRender(pb, &t, &l); +// write(stdout, t, l); + free(pb); + return 0; +} + + +int main() { + return writePresence("_here", 0, "I'm omnipresent right now", 0); +} From ec76ea765e751549af3201eac68e987566ac5e7f Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 22 Apr 2011 17:09:32 +0200 Subject: [PATCH 068/378] isRoutingVar, rendering, some renames --- .gitignore | 1 + include/psyc.h | 24 ++++++-- include/psyc/debug.h | 4 ++ include/psyc/lib.h | 4 ++ include/psyc/parser.h | 73 +++++++++++-------------- include/psyc/render.h | 52 +++++++++++++----- src/Makefile | 8 +-- src/parser.c | 124 +++++++++++++++++++++--------------------- src/render.c | 83 +++++++++++++++++----------- src/variable.c | 73 +++++++++++++++++++++++++ test/Makefile | 2 +- test/isRoutingVar.c | 26 +++++++++ test/testParser.c | 24 ++++---- 13 files changed, 326 insertions(+), 172 deletions(-) create mode 100644 src/variable.c create mode 100644 test/isRoutingVar.c diff --git a/.gitignore b/.gitignore index 6804378..e802e07 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ src/match test/testMatch test/testParser test/testRender +test/isRoutingVar .config ~$* diff --git a/include/psyc.h b/include/psyc.h index 16ad97d..20fb553 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -36,7 +36,7 @@ typedef enum typedef enum { PSYC_PART_RESET = -1, - PSYC_PART_HEADER = 0, + PSYC_PART_ROUTING, PSYC_PART_LENGTH, PSYC_PART_CONTENT, PSYC_PART_METHOD, @@ -54,6 +54,7 @@ typedef enum */ typedef enum { + PSYC_TYPE_UNKNOWN, PSYC_TYPE_AMOUNT, PSYC_TYPE_COLOR, PSYC_TYPE_DATE, @@ -78,15 +79,26 @@ typedef enum PSYC_LIST_BINARY = 2, } PSYC_ListType; -/** - * Get the type of variable name. - */ -PSYC_Type PSYC_getVarType(char* name, size_t len); +typedef struct +{ + size_t length; + const char* ptr; +} PSYC_Array; + +/// Routing vars in alphabetical order. +extern const PSYC_Array PSYC_routingVars[]; +/// Number of routing vars. +extern const size_t PSYC_routingVarsNum; /** * Get the type of variable name. */ -PSYC_Bool PSYC_isRoutingVar(char* name, size_t len); +PSYC_Bool PSYC_isRoutingVar(const char* name, size_t len); + +/** + * Get the type of variable name. + */ +PSYC_Type PSYC_getVarType(char* name, size_t len); /** * Checks if long keyword string inherits from short keyword string. diff --git a/include/psyc/debug.h b/include/psyc/debug.h index 0fcdb05..6ddec4c 100644 --- a/include/psyc/debug.h +++ b/include/psyc/debug.h @@ -1,3 +1,6 @@ +#ifndef DEBUG_H +# define DEBUG_H + #ifdef DEBUG # include # define PP(args) printf args; @@ -93,3 +96,4 @@ # define ASSERT(NAME,CONDITION,VALUE) #endif +#endif // DEBUG_H diff --git a/include/psyc/lib.h b/include/psyc/lib.h index e6c8c6d..8378468 100644 --- a/include/psyc/lib.h +++ b/include/psyc/lib.h @@ -1,5 +1,8 @@ /* this is needed to compile the library, not to use it */ +#ifndef PSYC_LIB_H +# define PSYC_LIB_H + #include "../psyc.h" #include "./debug.h" @@ -12,3 +15,4 @@ void *memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen); #endif +#endif // PSYC_LIB_H diff --git a/include/psyc/parser.h b/include/psyc/parser.h index b669ca5..b4b0d89 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -21,7 +21,7 @@ typedef enum { - PSYC_HEADER_ONLY = 1, + PSYC_PARSE_HEADER_ONLY = 1, } PSYC_ParseFlag; /** @@ -30,35 +30,35 @@ typedef enum */ typedef enum { - 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_PARSE_ERROR_END = -7, + PSYC_PARSE_ERROR_METHOD = -6, + PSYC_PARSE_ERROR_VAR_LEN = -5, + PSYC_PARSE_ERROR_VAR_TAB = -4, + PSYC_PARSE_ERROR_VAR_NAME = -3, + PSYC_PARSE_ERROR_LENGTH = -2, + PSYC_PARSE_ERROR = -1, + PSYC_PARSE_SUCCESS = 0, /// Buffer contains insufficient amount of data. /// Fill another buffer and concatenate it with the end of the current buffer, /// from the cursor position to the end. - PSYC_INSUFFICIENT = 1, + PSYC_PARSE_INSUFFICIENT = 1, /// Routing variable parsing done. /// Modifier, name & value contains the respective parts. - PSYC_ROUTING = 2, + PSYC_PARSE_ROUTING = 2, /// Entity variable parsing done. /// Modifier, name & value contains the respective parts. - PSYC_ENTITY = 3, + PSYC_PARSE_ENTITY = 3, /// Entity variable parsing is incomplete. /// Modifier & name are complete, value is incomplete. - PSYC_ENTITY_INCOMPLETE = 4, + PSYC_PARSE_ENTITY_INCOMPLETE = 4, /// Body parsing done, name contains method, value contains body. - PSYC_BODY = 5, + PSYC_PARSE_BODY = 5, /// Body parsing is incomplete, name contains method, value contains part of the body. - PSYC_BODY_INCOMPLETE = 6, + PSYC_PARSE_BODY_INCOMPLETE = 6, /// Reached end of packet, parsing done. - PSYC_COMPLETE = 7, + PSYC_PARSE_COMPLETE = 7, /// Binary value parsing incomplete, used internally. - PSYC_INCOMPLETE = 8, + PSYC_PARSE_INCOMPLETE = 8, } PSYC_ParseRC; /** @@ -67,25 +67,19 @@ typedef enum */ typedef enum { - PSYC_ERROR_LIST_DELIM = -5, - PSYC_ERROR_LIST_LEN = -4, - PSYC_ERROR_LIST_TYPE = -3, - PSYC_ERROR_LIST_NAME = -2, - PSYC_ERROR_LIST= -1, + PSYC_PARSE_LIST_ERROR_DELIM = -5, + PSYC_PARSE_LIST_ERROR_LEN = -4, + PSYC_PARSE_LIST_ERROR_TYPE = -3, + PSYC_PARSE_LIST_ERROR_NAME = -2, + PSYC_PARSE_LIST_ERROR= -1, /// Completed parsing a list element. - PSYC_LIST_ELEM = 1, + PSYC_PARSE_LIST_ELEM = 1, /// Reached end of buffer. - PSYC_LIST_END = 2, + PSYC_PARSE_LIST_END = 2, /// Binary list is incomplete. - PSYC_LIST_INCOMPLETE = 3, + PSYC_PARSE_LIST_INCOMPLETE = 3, } PSYC_ParseListRC; -typedef struct -{ - size_t length; - const uint8_t* ptr; // just an unsigned char for opaque data -} PSYC_Array; // to be renamed or solved differently.. - /** * Struct for keeping parser state. */ @@ -118,7 +112,6 @@ typedef struct size_t elemLength; ///< expected length of the elem } PSYC_ParseListState; -#ifndef PSYC_COMPILE_LIBRARY /** * Shortcut for creating an array. * @@ -127,7 +120,7 @@ typedef struct * * @return An instance of the PSYC_Array struct. */ -inline PSYC_Array PSYC_createArray (uint8_t* const memory, size_t length) +inline PSYC_Array PSYC_createArray (const char* memory, size_t length) { PSYC_Array arr = {length, memory}; return arr; @@ -139,7 +132,7 @@ inline PSYC_Array PSYC_createArray (uint8_t* const memory, size_t length) * @param state Pointer to the state struct that should be initiated. * @param flags Flags to be set for the parser, see PSYC_ParseFlag. */ -inline void PSYC_initState2 (PSYC_ParseState* state, uint8_t flags) +inline void PSYC_initParseState2 (PSYC_ParseState* state, uint8_t flags) { memset(state, 0, sizeof(PSYC_ParseState)); state->flags = flags; @@ -150,7 +143,7 @@ inline void PSYC_initState2 (PSYC_ParseState* state, uint8_t flags) * * @param state Pointer to the state struct that should be initiated. */ -inline void PSYC_initState (PSYC_ParseState* state) +inline void PSYC_initParseState (PSYC_ParseState* state) { memset(state, 0, sizeof(PSYC_ParseState)); } @@ -160,18 +153,18 @@ inline void PSYC_initState (PSYC_ParseState* state) * * @param state Pointer to the list state struct that should be initiated. */ -inline void PSYC_initListState (PSYC_ParseListState* state) +inline void PSYC_initParseListState (PSYC_ParseListState* state) { memset(state, 0, sizeof(PSYC_ParseListState)); } -inline void PSYC_nextBuffer (PSYC_ParseState* state, PSYC_Array newBuf) +inline void PSYC_nextParseBuffer (PSYC_ParseState* state, PSYC_Array newBuf) { state->buffer = newBuf; state->cursor = 0; } -inline void PSYC_nextListBuffer (PSYC_ParseListState* state, PSYC_Array newBuf) +inline void PSYC_nextParseListBuffer (PSYC_ParseListState* state, PSYC_Array newBuf) { state->buffer = newBuf; state->cursor = 0; @@ -182,8 +175,6 @@ inline size_t PSYC_getContentLength (PSYC_ParseState* s) return s->contentLength; } -#endif - /** * Parse PSYC packets. * @@ -197,7 +188,7 @@ inline size_t PSYC_getContentLength (PSYC_ParseState* s) * @param value A pointer to a PSYC_Array. It will point to the * value/body the variable/method and its length will be set accordingly */ -PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value); +PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, char* modifier, PSYC_Array* name, PSYC_Array* value); /** * List value parser. diff --git a/include/psyc/render.h b/include/psyc/render.h index c236aa4..3170924 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -1,18 +1,33 @@ +#ifndef PSYC_RENDER_H +# define PSYC_RENDER_H + #include "syntax.h" +#define PSYC_FLAG_UNDEFINED 0 +#define PSYC_FLAG_NOT_BINARY 1 +#define PSYC_FLAG_YES_BINARY 2 +#define PSYC_FLAG_CHECK_BINARY 3 + +typedef enum +{ + PSYC_RENDER_CHECK_BINARY = 0, + PSYC_RENDER_BINARY = 1, + PSYC_RENDER_NOT_BINARY = 2, + PSYC_RENDER_ROUTING = 3, +} PSYC_RenderFlag; + +typedef enum +{ + PSYC_RENDER_ERROR_ROUTING = -2, + PSYC_RENDER_ERROR = -1, + PSYC_RENDER_SUCCESS = 0, +} PSYC_RenderRC; + /** * Struct for keeping render state. */ -typedef enum { - PSYC_FINE = 0, - PSYC_NEED_LENGTH = 1 -} PSYC_RenderFlag; - -typedef enum { - PSYC_FLAG_ROUTING = 1 -} PSYC_RenderHeaderFlag; - -typedef struct { +typedef struct +{ PSYC_RenderFlag flag; ///< flags for the renderer PSYC_Part part; ///< part of the packet being rendered size_t cursor; ///< current position in buffer @@ -22,14 +37,23 @@ typedef struct { char buffer[]; ///< OMG a C99 feature! variable size buffer! } PSYC_RenderState; -int PSYC_renderHeader(PSYC_RenderState* render, +/** + * Initiates the state struct. + * + * @param state Pointer to the state struct that should be initiated. + */ +inline void PSYC_initRenderState (PSYC_RenderState* state) +{ + memset(state, 0, sizeof(PSYC_RenderState)); +} + +int PSYC_renderVar(PSYC_RenderState* render, const char* name, size_t nlength, const char* value, size_t vlength, - PSYC_RenderHeaderFlag flags, char modifier); + PSYC_RenderFlag flags, char modifier); int PSYC_renderBody(PSYC_RenderState* render, const char* method, size_t mlength, const char* data, size_t dlength); -int PSYC_doneRender(PSYC_RenderState* render, - uint8_t** buf, size_t* written); +#endif // PSYC_RENDER_H diff --git a/src/Makefile b/src/Makefile index 5251245..4a3b661 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,9 +1,9 @@ -CFLAGS=-I../../include -DDEBUG=2 -DPSYC_COMPILE_LIBRARY -g -O0 -Wall -CC=cc -I../include +CFLAGS=-I../include -DDEBUG=2 -DPSYC_COMPILE_LIBRARY -g -O0 -Wall +CC=cc # CC=clang -S=parser.c match.c render.c memmem.c -O=parser.o match.o render.o memmem.o +S=parser.c match.c render.c memmem.c variable.c +O=parser.o match.o render.o memmem.o variable.o default: @/bin/echo -e "Usage:\n\tmake diet - compile with diet libc\n\tmake lib - compile with normal gnu libc" diff --git a/src/parser.c b/src/parser.c index 264b0d7..6d18511 100644 --- a/src/parser.c +++ b/src/parser.c @@ -66,7 +66,7 @@ inline char isKwChar(uint8_t c) /** * Parse variable name or method name. * It should contain one or more keyword characters. - * @return PSYC_ERROR or PSYC_SUCCESS + * @return PSYC_PARSE_ERROR or PSYC_PARSE_SUCCESS */ inline PSYC_ParseRC PSYC_parseName(PSYC_ParseState* state, PSYC_Array* name) { @@ -76,10 +76,10 @@ inline PSYC_ParseRC PSYC_parseName(PSYC_ParseState* state, PSYC_Array* name) while (isKwChar(state->buffer.ptr[state->cursor])) { name->length++; // was a valid char, increase length - ADVANCE_CURSOR_OR_RETURN(PSYC_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } - return name->length > 0 ? PSYC_SUCCESS : PSYC_ERROR; + return name->length > 0 ? PSYC_PARSE_SUCCESS : PSYC_PARSE_ERROR; } /** @@ -90,7 +90,7 @@ inline PSYC_ParseRC PSYC_parseName(PSYC_ParseState* state, PSYC_Array* name) * @param length Expected length of the data. * @param parsed Number of bytes parsed so far. * - * @return PSYC_COMPLETE or PSYC_INCOMPLETE + * @return PSYC_PARSE_COMPLETE or PSYC_PARSE_INCOMPLETE */ inline PSYC_ParseRC PSYC_parseBinaryValue(PSYC_ParseState* state, PSYC_Array* value, size_t* length, size_t* parsed) { @@ -101,27 +101,27 @@ inline PSYC_ParseRC PSYC_parseBinaryValue(PSYC_ParseState* state, PSYC_Array* va { value->length = state->buffer.length - state->cursor; *parsed += value->length; - return PSYC_INCOMPLETE; + return PSYC_PARSE_INCOMPLETE; } value->length += remaining; state->cursor += remaining; *parsed += value->length; - return PSYC_COMPLETE; + return PSYC_PARSE_COMPLETE; } /** * Parse simple or binary variable. - * @return PSYC_ERROR or PSYC_SUCCESS + * @return PSYC_PARSE_ERROR or PSYC_PARSE_SUCCESS */ -inline PSYC_ParseRC PSYC_parseVar(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value) +inline PSYC_ParseRC PSYC_parseVar(PSYC_ParseState* state, char* modifier, PSYC_Array* name, PSYC_Array* value) { *modifier = *(state->buffer.ptr + state->cursor); - ADVANCE_CURSOR_OR_RETURN(PSYC_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); - if (PSYC_parseName(state, name) != PSYC_SUCCESS) - return PSYC_ERROR_VAR_NAME; + if (PSYC_parseName(state, name) != PSYC_PARSE_SUCCESS) + return PSYC_PARSE_ERROR_VAR_NAME; value->length = 0; state->valueLength = 0; @@ -131,55 +131,55 @@ inline PSYC_ParseRC PSYC_parseVar(PSYC_ParseState* state, uint8_t* modifier, PSY // 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); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); if (isNumeric(state->buffer.ptr[state->cursor])) { do { state->valueLength = 10 * state->valueLength + state->buffer.ptr[state->cursor] - '0'; - ADVANCE_CURSOR_OR_RETURN(PSYC_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } while (isNumeric(state->buffer.ptr[state->cursor])); } else - return PSYC_ERROR_VAR_LEN; + return PSYC_PARSE_ERROR_VAR_LEN; // After the length a TAB follows. if (state->buffer.ptr[state->cursor] != '\t') - return PSYC_ERROR_VAR_TAB; + return PSYC_PARSE_ERROR_VAR_TAB; if (state->buffer.length <= ++(state->cursor)) // Incremented cursor inside length? - return PSYC_ENTITY_INCOMPLETE; + return PSYC_PARSE_ENTITY_INCOMPLETE; - if (PSYC_parseBinaryValue(state, value, &(state->valueLength), &(state->valueParsed)) == PSYC_INCOMPLETE) - return PSYC_ENTITY_INCOMPLETE; + if (PSYC_parseBinaryValue(state, value, &(state->valueLength), &(state->valueParsed)) == PSYC_PARSE_INCOMPLETE) + return PSYC_PARSE_ENTITY_INCOMPLETE; state->cursor++; - return PSYC_SUCCESS; + return PSYC_PARSE_SUCCESS; } else if (state->buffer.ptr[state->cursor] == '\t') // simple arg { - ADVANCE_CURSOR_OR_RETURN(PSYC_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); value->ptr = state->buffer.ptr + state->cursor; while (state->buffer.ptr[state->cursor] != '\n') { value->length++; - ADVANCE_CURSOR_OR_RETURN(PSYC_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } state->cursor++; - return PSYC_SUCCESS; + return PSYC_PARSE_SUCCESS; } else - return PSYC_ERROR_VAR_TAB; + return PSYC_PARSE_ERROR_VAR_TAB; } /** * Parse PSYC packets. * Generalized line-based parser. */ -PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value) +PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, char* modifier, PSYC_Array* name, PSYC_Array* value) { int ret; // a return value size_t pos; // a cursor position @@ -190,7 +190,7 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* n // 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 PSYC_PARSE_INSUFFICIENT; switch (state->part) { @@ -200,17 +200,17 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* n state->contentParsed = 0; state->contentLength = 0; state->contentLengthFound = 0; - state->part = PSYC_PART_HEADER; + state->part = PSYC_PART_ROUTING; // fall thru - case PSYC_PART_HEADER: + case PSYC_PART_ROUTING: // 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; + return ret == PSYC_PARSE_SUCCESS ? PSYC_PARSE_ROUTING : ret; } else // not a glyph { @@ -227,7 +227,7 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* n do { state->contentLength = 10 * state->contentLength + state->buffer.ptr[state->cursor] - '0'; - ADVANCE_CURSOR_OR_RETURN(PSYC_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } while (isNumeric(state->buffer.ptr[state->cursor])); } @@ -236,7 +236,7 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* n { // 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) + if (state->flags & PSYC_PARSE_HEADER_ONLY && state->contentLengthFound) state->part = PSYC_PART_DATA; else state->part = PSYC_PART_CONTENT; @@ -245,13 +245,13 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* n { // If we have a length then it should've been followed by a \n if (state->contentLengthFound) - return PSYC_ERROR_LENGTH; + return PSYC_PARSE_ERROR_LENGTH; state->part = PSYC_PART_END; goto PSYC_PART_END; } - ADVANCE_CURSOR_OR_RETURN(PSYC_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); state->startc = state->cursor; // fall thru @@ -260,7 +260,7 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* n 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; + return ret == PSYC_PARSE_COMPLETE ? PSYC_PARSE_ENTITY : PSYC_PARSE_ENTITY_INCOMPLETE; } // Each line of the header starts with a glyph, @@ -273,7 +273,7 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* n pos = state->cursor; ret = PSYC_parseVar(state, modifier, name, value); state->contentParsed += state->cursor - pos; - return ret == PSYC_SUCCESS ? PSYC_ENTITY : ret; + return ret == PSYC_PARSE_SUCCESS ? PSYC_PARSE_ENTITY : ret; } else { @@ -284,17 +284,17 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* n case PSYC_PART_METHOD: pos = state->cursor; - if (PSYC_parseName(state, name) == PSYC_SUCCESS) + if (PSYC_parseName(state, name) == PSYC_PARSE_SUCCESS) { // the method ends with a \n then the data follows if (state->buffer.ptr[state->cursor] != '\n') - return PSYC_ERROR_METHOD; + return PSYC_PARSE_ERROR_METHOD; 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; + return PSYC_PARSE_INSUFFICIENT; // fall thru } else // No method, which means the packet should end now. @@ -310,12 +310,12 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* n 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; + if (PSYC_parseBinaryValue(state, value, &(state->contentLength), &(state->contentParsed)) == PSYC_PARSE_INCOMPLETE) + return PSYC_PARSE_BODY_INCOMPLETE; state->cursor++; state->part = PSYC_PART_END; - return PSYC_BODY; + return PSYC_PARSE_BODY; } else // Search for the terminator. { @@ -326,7 +326,7 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* n if (state->cursor+2 >= state->buffer.length) // incremented cursor inside length? { state->cursor = state->startc; - return PSYC_INSUFFICIENT; + return PSYC_PARSE_INSUFFICIENT; } if (state->buffer.ptr[state->cursor+1] == '|' && @@ -334,11 +334,11 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* n { state->cursor++; state->part = PSYC_PART_END; - return PSYC_BODY; + return PSYC_PARSE_BODY; } } value->length++; - ADVANCE_CURSOR_OR_RETURN(PSYC_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } } @@ -347,22 +347,22 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* n // 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 PSYC_PARSE_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; + return PSYC_PARSE_COMPLETE; } else // packet should've ended here, return error { state->part = PSYC_PART_RESET; - return PSYC_ERROR_END; + return PSYC_PARSE_ERROR_END; } } - return PSYC_ERROR; // should not be reached + return PSYC_PARSE_ERROR; // should not be reached } /** @@ -372,7 +372,7 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* n PSYC_ParseListRC PSYC_parseList(PSYC_ParseListState* state, PSYC_Array *name, PSYC_Array* value, PSYC_Array* elem) { if (state->cursor >= state->buffer.length) - return PSYC_LIST_INCOMPLETE; + return PSYC_PARSE_LIST_INCOMPLETE; state->startc = state->cursor; @@ -380,7 +380,7 @@ PSYC_ParseListRC PSYC_parseList(PSYC_ParseListState* state, PSYC_Array *name, PS { 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_ - return PSYC_ERROR_LIST_NAME; + return PSYC_PARSE_LIST_ERROR_NAME; // First character is either | for text lists, or a number for binary lists if (state->buffer.ptr[state->cursor] == '|') @@ -391,7 +391,7 @@ PSYC_ParseListRC PSYC_parseList(PSYC_ParseListState* state, PSYC_Array *name, PS else if (isNumeric(state->buffer.ptr[state->cursor])) state->type = PSYC_LIST_BINARY; else - return PSYC_ERROR_LIST_TYPE; + return PSYC_PARSE_LIST_ERROR_TYPE; } if (state->type == PSYC_LIST_TEXT) @@ -400,16 +400,16 @@ PSYC_ParseListRC PSYC_parseList(PSYC_ParseListState* state, PSYC_Array *name, PS elem->length = 0; if (state->cursor >= state->buffer.length) - return PSYC_LIST_END; + return PSYC_PARSE_LIST_END; while (state->buffer.ptr[state->cursor] != '|') { elem->length++; if (++(state->cursor) >= state->buffer.length) - return PSYC_LIST_END; + return PSYC_PARSE_LIST_END; } state->cursor++; - return PSYC_LIST_ELEM; + return PSYC_PARSE_LIST_ELEM; } else // binary list { @@ -421,15 +421,15 @@ PSYC_ParseListRC PSYC_parseList(PSYC_ParseListState* state, PSYC_Array *name, PS do { state->elemLength = 10 * state->elemLength + state->buffer.ptr[state->cursor] - '0'; - ADVANCE_CURSOR_OR_RETURN(PSYC_LIST_INCOMPLETE); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_LIST_INCOMPLETE); } while (isNumeric(state->buffer.ptr[state->cursor])); } else - return PSYC_ERROR_LIST_LEN; + return PSYC_PARSE_LIST_ERROR_LEN; if (state->buffer.ptr[state->cursor] != ' ') - return PSYC_ERROR_LIST_LEN; + return PSYC_PARSE_LIST_ERROR_LEN; state->cursor++; elem->ptr = state->buffer.ptr + state->cursor; @@ -440,21 +440,21 @@ PSYC_ParseListRC PSYC_parseList(PSYC_ParseListState* state, PSYC_Array *name, PS // Start or resume parsing the binary data if (state->elemParsed < state->elemLength) { - if (PSYC_parseBinaryValue((PSYC_ParseState*)state, elem, &(state->elemLength), &(state->elemParsed)) == PSYC_INCOMPLETE) - return PSYC_LIST_INCOMPLETE; + if (PSYC_parseBinaryValue((PSYC_ParseState*)state, elem, &(state->elemLength), &(state->elemParsed)) == PSYC_PARSE_INCOMPLETE) + return PSYC_PARSE_LIST_INCOMPLETE; state->elemLength = 0; if (state->cursor >= state->buffer.length) - return PSYC_LIST_END; + return PSYC_PARSE_LIST_END; if (state->buffer.ptr[state->cursor] != '|') - return PSYC_ERROR_LIST_DELIM; + return PSYC_PARSE_LIST_ERROR_DELIM; state->cursor++; - return PSYC_LIST_ELEM; + return PSYC_PARSE_LIST_ELEM; } } - return PSYC_ERROR_LIST; // should not be reached + return PSYC_PARSE_LIST_ERROR; // should not be reached } diff --git a/src/render.c b/src/render.c index bf5e039..69a2771 100644 --- a/src/render.c +++ b/src/render.c @@ -1,51 +1,70 @@ #include "psyc/lib.h" #include "psyc/render.h" -int PSYC_renderHeader(PSYC_RenderState* r, - const char* name, size_t nlength, - const char* value, size_t vlength, - const PSYC_RenderHeaderFlag flags, - char modifier) { +PSYC_RenderRC PSYC_renderVar(PSYC_RenderState* state, + const char* name, size_t nlength, + const char* value, size_t vlength, + const PSYC_RenderFlag flags, char modifier) +{ + size_t startc = state->cursor; + unless (nlength) nlength = strlen(name); // vlength 0 means an empty variable.. no cheating there unless (modifier) modifier = C_GLYPH_MODIFIER_SET; - r->buffer[r->cursor++] = modifier; - strncpy(&r->buffer[r->cursor], name, nlength); - r->cursor += nlength; - if (vlength) { - r->buffer[r->cursor++] = '\t'; - strncpy(&r->buffer[r->cursor], value, vlength); - r->cursor += vlength; + state->buffer[state->cursor++] = modifier; + strncpy(&state->buffer[state->cursor], name, nlength); + state->cursor += nlength; + + if (vlength) + { + state->buffer[state->cursor++] = '\t'; + strncpy(&state->buffer[state->cursor], value, vlength); + state->cursor += vlength; } - if (flags == PSYC_FLAG_ROUTING) { - if (r->spot != 0) { - P1(("Too late to add a routing variable!\n")) - return -1; + //if (flags == PSYC_RENDER_ROUTING) + if (PSYC_isRoutingVar(name, nlength)) + { // no more routing headers allowed after content started + if (state->part != PSYC_PART_ROUTING) + { + P1(("Too late to add a routing variable!\n")); + return PSYC_RENDER_ERROR_ROUTING; } - } else if (r->spot == 0) { + } + else if (state->part == PSYC_PART_ROUTING) + { // first entity header, set part to content + state->part = PSYC_PART_CONTENT; // add "\n000000000" to buffer // and make spot point to the first 0 } - return 0; + + // update content length if we're in the content part + if (state->part == PSYC_PART_CONTENT) + state->contentLength += state->cursor - startc; + + return PSYC_RENDER_SUCCESS; } -int PSYC_renderBody(PSYC_RenderState* render, +/* render PSYC packets */ +PSYC_RenderRC PSYC_renderBody(PSYC_RenderState* state, const char* method, size_t mlength, - const char* data, size_t dlength) { - - // find out if this packet needs a prepended length - if (dlength == 1 && data[0] == C_GLYPH_PACKET_DELIMITER) - render->flag = PSYC_NEED_LENGTH; - else if (dlength > 404) - render->flag = PSYC_NEED_LENGTH; - else if (memmem(data, dlength, PSYC_PACKET_DELIMITER, - sizeof(PSYC_PACKET_DELIMITER))) - render->flag = PSYC_NEED_LENGTH; - else - render->flag = PSYC_FINE; + const char* data, size_t dlength) +{ + if (state->flag == PSYC_RENDER_CHECK_BINARY) + { + // find out if this packet needs a prepended length + if (dlength == 1 && data[0] == C_GLYPH_PACKET_DELIMITER) + state->flag = PSYC_RENDER_BINARY; + else if (dlength > 404) + state->flag = PSYC_RENDER_BINARY; + else if (memmem(data, dlength, PSYC_PACKET_DELIMITER, sizeof(PSYC_PACKET_DELIMITER))) + state->flag = PSYC_RENDER_BINARY; + else + state->flag = PSYC_RENDER_NOT_BINARY; + } // TBD - return 0; + + return PSYC_RENDER_SUCCESS; } diff --git a/src/variable.c b/src/variable.c new file mode 100644 index 0000000..abd786a --- /dev/null +++ b/src/variable.c @@ -0,0 +1,73 @@ +#include +#include + +const PSYC_Array PSYC_routingVars[] = +{ + {17, "_amount_fragments"}, + { 8, "_context"}, + { 6, "_count"}, + { 8, "_counter"}, // the name for this is supposed to be _count, not _counter + { 9, "_fragment"}, + { 7, "_length"}, + { 7, "_source"}, + {22, "_source_identification"}, + {13, "_source_relay"}, + {19, "_source_relay_relay"}, // until you have a better idea.. is this really in use? + { 4, "_tag"}, + {10, "_tag_relay"}, + {10, "_tag_reply"}, // should be obsolete, but.. TODO + { 7, "_target"}, + {15, "_target_forward"}, + {13, "_target_relay"}, + {19, "_understand_modules"}, + {14, "_using_modules"}, +}; + +const size_t PSYC_routingVarsNum = sizeof(PSYC_routingVars) / sizeof(*PSYC_routingVars); + +/** + * Get the type of variable name. + */ +PSYC_Bool PSYC_isRoutingVar(const char* name, size_t len) +{ + size_t cursor = 1; + int8_t matching[PSYC_routingVarsNum]; // indexes of matching vars + memset(&matching, -1, sizeof(matching)); + uint8_t i, m = 0; + + if (len < 2 || name[0] != '_') + return PSYC_FALSE; + + // first find the vars with matching length + for (i=0; i= 0) + { + for (i = m = 0; i < PSYC_routingVarsNum; i++) + { + if (matching[i] < 0) + break; + if (PSYC_routingVars[matching[i]].ptr[cursor] == name[cursor]) + matching[m++] = matching[i]; // found a match, update matching indexes + else if (PSYC_routingVars[matching[i]].ptr[cursor] > name[cursor]) + break; // passed the possible matches in alphabetical order + } + + if (m < PSYC_routingVarsNum) + matching[m] = -1; // mark the end of matching indexes + + cursor++; + } + + return matching[0] >= 0 ? PSYC_TRUE : PSYC_FALSE; +} + +/** + * Get the type of variable name. + */ +PSYC_Type PSYC_getVarType(char* name, size_t len) +{ + return PSYC_TYPE_UNKNOWN; +} diff --git a/test/Makefile b/test/Makefile index fd61356..2cd792c 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,7 +1,7 @@ CFLAGS=-I../include -DDEBUG -g -O0 -Wall LDFLAGS=-L../src LOADLIBES=-lpsyc -TARGETS=testParser testMatch testRender +TARGETS=testParser testMatch testRender isRoutingVar all: $(TARGETS) diff --git a/test/isRoutingVar.c b/test/isRoutingVar.c new file mode 100644 index 0000000..e744b95 --- /dev/null +++ b/test/isRoutingVar.c @@ -0,0 +1,26 @@ +#include +#include +#include +#include + +int main(int argc, char** argv) +{ + char* vars[] = + { + "_source", + "_source_relay", + "_source_foo", + "_sourcherry", + "_foo", + "bar", + "_", + }; + + int i; + for (i = 0; i < sizeof(vars) / sizeof(*vars); i++) + { + printf("%s: %d\n", vars[i], PSYC_isRoutingVar(vars[i], strlen(vars[i]))); + } + + return 0; +} diff --git a/test/testParser.c b/test/testParser.c index c743462..6815441 100644 --- a/test/testParser.c +++ b/test/testParser.c @@ -21,18 +21,18 @@ int main(int argc, char** argv) write(1, buffer, index); write(1, ">> PARSE\n", 9); - PSYC_initState(&state); - PSYC_nextBuffer(&state, PSYC_createArray(buffer, index)); + PSYC_initParseState(&state); + PSYC_nextParseBuffer(&state, PSYC_createArray(buffer, index)); // try parsing that now while ((ret = PSYC_parse(&state, &modifier, &name, &value))) { switch (ret) { - case PSYC_ROUTING: - case PSYC_ENTITY: + case PSYC_PARSE_ROUTING: + case PSYC_PARSE_ENTITY: write(1, &modifier, 1); - case PSYC_BODY: + case PSYC_PARSE_BODY: // printf("the string is '%.*s'\n", name); write(1, name.ptr, name.length); write(1, " = ", 3); @@ -41,14 +41,14 @@ int main(int argc, char** argv) if (memcmp(name.ptr, "_list", 5) == 0) { write(1, ">>> LIST START\n", 15); - PSYC_initListState(&listState); - PSYC_nextListBuffer(&listState, value); + PSYC_initParseListState(&listState); + PSYC_nextParseListBuffer(&listState, value); while ((ret = PSYC_parseList(&listState, &name, &value, &elem))) { switch (ret) { - case PSYC_LIST_END: - case PSYC_LIST_ELEM: + case PSYC_PARSE_LIST_END: + case PSYC_PARSE_LIST_ELEM: write(1, "|", 1); write(1, elem.ptr, elem.length); write(1, "\n", 1); @@ -58,7 +58,7 @@ int main(int argc, char** argv) return 1; } - if (ret == PSYC_LIST_END) + if (ret == PSYC_PARSE_LIST_END) { write(1, ">>> LIST END\n", 13); break; @@ -66,10 +66,10 @@ int main(int argc, char** argv) } } break; - case PSYC_COMPLETE: + case PSYC_PARSE_COMPLETE: printf("Done parsing.\n"); continue; - case PSYC_INSUFFICIENT: + case PSYC_PARSE_INSUFFICIENT: printf("Insufficient data.\n"); return 0; default: From 83e18a5f4a71f681fb7e7ed067637481efd10c8e Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 22 Apr 2011 20:22:20 +0200 Subject: [PATCH 069/378] s/binary/length --- include/psyc/render.h | 6 +++--- src/render.c | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/psyc/render.h b/include/psyc/render.h index 3170924..0569d01 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -10,9 +10,9 @@ typedef enum { - PSYC_RENDER_CHECK_BINARY = 0, - PSYC_RENDER_BINARY = 1, - PSYC_RENDER_NOT_BINARY = 2, + PSYC_RENDER_CHECK_LENGTH = 0, + PSYC_RENDER_NEED_LENGTH = 1, + PSYC_RENDER_NO_LENGTH = 2, PSYC_RENDER_ROUTING = 3, } PSYC_RenderFlag; diff --git a/src/render.c b/src/render.c index 69a2771..358458c 100644 --- a/src/render.c +++ b/src/render.c @@ -51,17 +51,17 @@ PSYC_RenderRC PSYC_renderBody(PSYC_RenderState* state, const char* method, size_t mlength, const char* data, size_t dlength) { - if (state->flag == PSYC_RENDER_CHECK_BINARY) + if (state->flag == PSYC_RENDER_CHECK_LENGTH) { // find out if this packet needs a prepended length if (dlength == 1 && data[0] == C_GLYPH_PACKET_DELIMITER) - state->flag = PSYC_RENDER_BINARY; + state->flag = PSYC_RENDER_NEED_LENGTH; else if (dlength > 404) - state->flag = PSYC_RENDER_BINARY; + state->flag = PSYC_RENDER_NEED_LENGTH; else if (memmem(data, dlength, PSYC_PACKET_DELIMITER, sizeof(PSYC_PACKET_DELIMITER))) - state->flag = PSYC_RENDER_BINARY; + state->flag = PSYC_RENDER_NEED_LENGTH; else - state->flag = PSYC_RENDER_NOT_BINARY; + state->flag = PSYC_RENDER_NO_LENGTH; } // TBD From 0e54f3f76a1b35e1ffd33662b709ce79f7ff721f Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 22 Apr 2011 20:33:22 +0200 Subject: [PATCH 070/378] compiles again --- include/psyc/parser.h | 51 +++++++++++-------------------------------- include/psyc/render.h | 5 +---- src/parser.c | 39 +++++++++++++++++++++++++++++++++ src/render.c | 5 +++++ src/variable.c | 2 +- test/testParser.c | 2 +- test/testRender.c | 12 +++++----- 7 files changed, 66 insertions(+), 50 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index b4b0d89..6331d0d 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -120,11 +120,14 @@ typedef struct * * @return An instance of the PSYC_Array struct. */ -inline PSYC_Array PSYC_createArray (const char* memory, size_t length) -{ - PSYC_Array arr = {length, memory}; - return arr; -} +inline PSYC_Array PSYC_createArray (const char* memory, size_t length); + +/** + * Initiates the state struct. + * + * @param state Pointer to the state struct that should be initiated. + */ +inline void PSYC_initParseState (PSYC_ParseState* state); /** * Initiates the state struct with flags. @@ -132,48 +135,20 @@ inline PSYC_Array PSYC_createArray (const char* memory, size_t length) * @param state Pointer to the state struct that should be initiated. * @param flags Flags to be set for the parser, see PSYC_ParseFlag. */ -inline void PSYC_initParseState2 (PSYC_ParseState* state, uint8_t flags) -{ - memset(state, 0, sizeof(PSYC_ParseState)); - state->flags = flags; -} - -/** - * Initiates the state struct. - * - * @param state Pointer to the state struct that should be initiated. - */ -inline void PSYC_initParseState (PSYC_ParseState* state) -{ - memset(state, 0, sizeof(PSYC_ParseState)); -} +inline void PSYC_initParseState2 (PSYC_ParseState* state, uint8_t flags); /** * Initiates the list state struct. * * @param state Pointer to the list state struct that should be initiated. */ -inline void PSYC_initParseListState (PSYC_ParseListState* state) -{ - memset(state, 0, sizeof(PSYC_ParseListState)); -} +inline void PSYC_initParseListState (PSYC_ParseListState* state); -inline void PSYC_nextParseBuffer (PSYC_ParseState* state, PSYC_Array newBuf) -{ - state->buffer = newBuf; - state->cursor = 0; -} +inline void PSYC_nextParseBuffer (PSYC_ParseState* state, PSYC_Array newBuf); -inline void PSYC_nextParseListBuffer (PSYC_ParseListState* state, PSYC_Array newBuf) -{ - state->buffer = newBuf; - state->cursor = 0; -} +inline void PSYC_nextParseListBuffer (PSYC_ParseListState* state, PSYC_Array newBuf); -inline size_t PSYC_getContentLength (PSYC_ParseState* s) -{ - return s->contentLength; -} +inline size_t PSYC_getContentLength (PSYC_ParseState* s); /** * Parse PSYC packets. diff --git a/include/psyc/render.h b/include/psyc/render.h index 0569d01..0620f2b 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -42,10 +42,7 @@ typedef struct * * @param state Pointer to the state struct that should be initiated. */ -inline void PSYC_initRenderState (PSYC_RenderState* state) -{ - memset(state, 0, sizeof(PSYC_RenderState)); -} +inline void PSYC_initRenderState (PSYC_RenderState* state); int PSYC_renderVar(PSYC_RenderState* render, const char* name, size_t nlength, diff --git a/src/parser.c b/src/parser.c index 6d18511..02d9fd5 100644 --- a/src/parser.c +++ b/src/parser.c @@ -15,6 +15,45 @@ return ret; \ } +inline PSYC_Array PSYC_createArray (const char* memory, size_t length) +{ + PSYC_Array arr = {length, memory}; + return arr; +} + +inline void PSYC_initParseState (PSYC_ParseState* state) +{ + memset(state, 0, sizeof(PSYC_ParseState)); +} + +inline void PSYC_initParseState2 (PSYC_ParseState* state, uint8_t flags) +{ + memset(state, 0, sizeof(PSYC_ParseState)); + state->flags = flags; +} + +inline void PSYC_initParseListState (PSYC_ParseListState* state) +{ + memset(state, 0, sizeof(PSYC_ParseListState)); +} + +inline void PSYC_nextParseBuffer (PSYC_ParseState* state, PSYC_Array newBuf) +{ + state->buffer = newBuf; + state->cursor = 0; +} + +inline void PSYC_nextParseListBuffer (PSYC_ParseListState* state, PSYC_Array newBuf) +{ + state->buffer = newBuf; + state->cursor = 0; +} + +inline size_t PSYC_getContentLength (PSYC_ParseState* s) +{ + return s->contentLength; +} + /** * Determines if the argument is a glyph. * Glyphs are: : = + - ? ! diff --git a/src/render.c b/src/render.c index 358458c..2268aa7 100644 --- a/src/render.c +++ b/src/render.c @@ -1,6 +1,11 @@ #include "psyc/lib.h" #include "psyc/render.h" +inline void PSYC_initRenderState (PSYC_RenderState* state) +{ + memset(state, 0, sizeof(PSYC_RenderState)); +} + PSYC_RenderRC PSYC_renderVar(PSYC_RenderState* state, const char* name, size_t nlength, const char* value, size_t vlength, diff --git a/src/variable.c b/src/variable.c index abd786a..d666047 100644 --- a/src/variable.c +++ b/src/variable.c @@ -1,7 +1,7 @@ #include #include -const PSYC_Array PSYC_routingVars[] = +const PSYC_Array PSYC_routingVars[] = /// Routing variables in alphabetical order. { {17, "_amount_fragments"}, { 8, "_context"}, diff --git a/test/testParser.c b/test/testParser.c index 6815441..7b1f8e8 100644 --- a/test/testParser.c +++ b/test/testParser.c @@ -7,7 +7,7 @@ int main(int argc, char** argv) { int index, ret; - uint8_t buffer[2048], modifier; + char buffer[2048], modifier; PSYC_Array name, value, elem; PSYC_ParseState state; PSYC_ParseListState listState; diff --git a/test/testRender.c b/test/testRender.c index c69b1c0..d2f856e 100644 --- a/test/testRender.c +++ b/test/testRender.c @@ -19,13 +19,13 @@ int writePresence(const char *avail, int availlen, const char *desc, int desclen } // if (PSYC_initBuffer(pb, WHATEVER)) die("PSYC_initBuffer hates me"); - (void) PSYC_renderHeader(pb, "_context", 0, - myUNI, sizeof(myUNI), PSYC_FLAG_ROUTING, 0); + (void) PSYC_renderVar(pb, "_context", 0, + myUNI, sizeof(myUNI), PSYC_RENDER_ROUTING, 0); - // the first call to PSYC_renderHeader() without PSYC_FLAG_ROUTING adds the - // extra newline to the buffer. later vars with PSYC_FLAG_ROUTING cause an error. - (void) PSYC_renderHeader(pb, "_degree_availability", 0, avail, availlen, 0, C_GLYPH_MODIFIER_ASSIGN); - (void) PSYC_renderHeader(pb, "_description_presence", 0, desc, desclen, 0, C_GLYPH_MODIFIER_ASSIGN); + // the first call to PSYC_renderHeader() without PSYC_RENDER_ROUTING adds the + // extra newline to the buffer. later vars with PSYC_RENDER_ROUTING cause an error. + (void) PSYC_renderVar(pb, "_degree_availability", 0, avail, availlen, 0, C_GLYPH_MODIFIER_ASSIGN); + (void) PSYC_renderVar(pb, "_description_presence", 0, desc, desclen, 0, C_GLYPH_MODIFIER_ASSIGN); // presence is to be assigned permanently in distributed state (void) PSYC_renderBody(pb, "_notice_presence", 0, From 4de626227a2adfada8e30b042eedf82b68a87614 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 22 Apr 2011 20:50:59 +0200 Subject: [PATCH 071/378] s/modifier/operator/ --- include/psyc/parser.h | 12 ++++++------ include/psyc/render.h | 7 +------ include/psyc/syntax.h | 20 ++++++++++---------- src/parser.c | 10 +++++----- src/psyc_parser_cb.h | 18 +++++++++--------- src/render.c | 6 +++--- test/testParser.c | 6 +++--- test/testRender.c | 4 ++-- 8 files changed, 39 insertions(+), 44 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index 6331d0d..22e3866 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -43,13 +43,13 @@ typedef enum /// from the cursor position to the end. PSYC_PARSE_INSUFFICIENT = 1, /// Routing variable parsing done. -/// Modifier, name & value contains the respective parts. +/// Operator, name & value contains the respective parts. PSYC_PARSE_ROUTING = 2, /// Entity variable parsing done. -/// Modifier, name & value contains the respective parts. +/// Operator, name & value contains the respective parts. PSYC_PARSE_ENTITY = 3, /// Entity variable parsing is incomplete. -/// Modifier & name are complete, value is incomplete. +/// Operator & name are complete, value is incomplete. PSYC_PARSE_ENTITY_INCOMPLETE = 4, /// Body parsing done, name contains method, value contains body. PSYC_PARSE_BODY = 5, @@ -156,14 +156,14 @@ inline size_t PSYC_getContentLength (PSYC_ParseState* s); * Generalized line-based packet parser. * * @param state An initialized PSYC_ParseState - * @param modifier A pointer to a character. In case of a variable, it will - * be set to the modifier of that variable + * @param operator A pointer to a character. In case of a variable, it will + * be set to the operator of that variable * @param name A pointer to a PSYC_Array. It will point to the name of * the variable or method and its length will be set accordingly * @param value A pointer to a PSYC_Array. It will point to the * value/body the variable/method and its length will be set accordingly */ -PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, char* modifier, PSYC_Array* name, PSYC_Array* value); +PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, char* operator, PSYC_Array* name, PSYC_Array* value); /** * List value parser. diff --git a/include/psyc/render.h b/include/psyc/render.h index 0620f2b..1a47149 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -3,11 +3,6 @@ #include "syntax.h" -#define PSYC_FLAG_UNDEFINED 0 -#define PSYC_FLAG_NOT_BINARY 1 -#define PSYC_FLAG_YES_BINARY 2 -#define PSYC_FLAG_CHECK_BINARY 3 - typedef enum { PSYC_RENDER_CHECK_LENGTH = 0, @@ -47,7 +42,7 @@ inline void PSYC_initRenderState (PSYC_RenderState* state); int PSYC_renderVar(PSYC_RenderState* render, const char* name, size_t nlength, const char* value, size_t vlength, - PSYC_RenderFlag flags, char modifier); + PSYC_RenderFlag flags, char operator); int PSYC_renderBody(PSYC_RenderState* render, const char* method, size_t mlength, diff --git a/include/psyc/syntax.h b/include/psyc/syntax.h index 004845e..ab4ff0d 100644 --- a/include/psyc/syntax.h +++ b/include/psyc/syntax.h @@ -17,20 +17,20 @@ #define C_GLYPH_SEPARATOR_KEYWORD '_' #define S_GLYPH_SEPARATOR_KEYWORD "_" -#define C_GLYPH_MODIFIER_SET ':' -#define S_GLYPH_MODIFIER_SET ":" +#define C_GLYPH_OPERATOR_SET ':' +#define S_GLYPH_OPERATOR_SET ":" -#define C_GLYPH_MODIFIER_ASSIGN '=' -#define S_GLYPH_MODIFIER_ASSIGN "=" +#define C_GLYPH_OPERATOR_ASSIGN '=' +#define S_GLYPH_OPERATOR_ASSIGN "=" -#define C_GLYPH_MODIFIER_AUGMENT '+' -#define S_GLYPH_MODIFIER_AUGMENT "+" +#define C_GLYPH_OPERATOR_AUGMENT '+' +#define S_GLYPH_OPERATOR_AUGMENT "+" -#define C_GLYPH_MODIFIER_DIMINISH '-' -#define S_GLYPH_MODIFIER_DIMINISH "-" +#define C_GLYPH_OPERATOR_DIMINISH '-' +#define S_GLYPH_OPERATOR_DIMINISH "-" -#define C_GLYPH_MODIFIER_QUERY '?' -#define S_GLYPH_MODIFIER_QUERY "?" +#define C_GLYPH_OPERATOR_QUERY '?' +#define S_GLYPH_OPERATOR_QUERY "?" /* might move into routing.h or something */ #define PSYC_ROUTING 1 diff --git a/src/parser.c b/src/parser.c index 02d9fd5..d1b7017 100644 --- a/src/parser.c +++ b/src/parser.c @@ -154,9 +154,9 @@ inline PSYC_ParseRC PSYC_parseBinaryValue(PSYC_ParseState* state, PSYC_Array* va * Parse simple or binary variable. * @return PSYC_PARSE_ERROR or PSYC_PARSE_SUCCESS */ -inline PSYC_ParseRC PSYC_parseVar(PSYC_ParseState* state, char* modifier, PSYC_Array* name, PSYC_Array* value) +inline PSYC_ParseRC PSYC_parseVar(PSYC_ParseState* state, char* operator, PSYC_Array* name, PSYC_Array* value) { - *modifier = *(state->buffer.ptr + state->cursor); + *operator = *(state->buffer.ptr + state->cursor); ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); if (PSYC_parseName(state, name) != PSYC_PARSE_SUCCESS) @@ -218,7 +218,7 @@ inline PSYC_ParseRC PSYC_parseVar(PSYC_ParseState* state, char* modifier, PSYC_A * Parse PSYC packets. * Generalized line-based parser. */ -PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, char* modifier, PSYC_Array* name, PSYC_Array* value) +PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, char* operator, PSYC_Array* name, PSYC_Array* value) { int ret; // a return value size_t pos; // a cursor position @@ -248,7 +248,7 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, char* modifier, PSYC_Array* name // 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); + ret = PSYC_parseVar(state, operator, name, value); return ret == PSYC_PARSE_SUCCESS ? PSYC_PARSE_ROUTING : ret; } else // not a glyph @@ -310,7 +310,7 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, char* modifier, PSYC_Array* name if (isGlyph(state->buffer.ptr[state->cursor])) { pos = state->cursor; - ret = PSYC_parseVar(state, modifier, name, value); + ret = PSYC_parseVar(state, operator, name, value); state->contentParsed += state->cursor - pos; return ret == PSYC_PARSE_SUCCESS ? PSYC_PARSE_ENTITY : ret; } diff --git a/src/psyc_parser_cb.h b/src/psyc_parser_cb.h index 25b212e..6216fca 100644 --- a/src/psyc_parser_cb.h +++ b/src/psyc_parser_cb.h @@ -46,14 +46,14 @@ void PSYC_parse(const uint8_t* data, unsigned int length, struct PSYC_Parser* pstate); /** @brief FlagMod */ -enum PSYC_Modifier +enum PSYC_Operator { - // variable modifers - ASSIGN=0x02, - AUGMENT=0x04, - DIMINISH=0x08, - SET=0x10, - QUERY=0x20 + // modifier operators + ASSIGN = 0x02, + AUGMENT = 0x04, + DIMINISH = 0x08, + SET = 0x10, + QUERY = 0x20, }; struct PSYC_Parser @@ -79,7 +79,7 @@ struct PSYC_Parser void (*stateCallback)(struct PSYC_Parser* pstate, const uint8_t *name, const unsigned int nlength, const uint8_t *value, const unsigned int vlength, - enum PSYC_Modifier modifiers, char inEntity); + enum PSYC_Operator operators, char inEntity); /** @brief gets called after the routing-header was parsed * @@ -135,7 +135,7 @@ struct PSYC_Parser void (*errorStateCallback)(struct PSYC_Parser* pstate, const uint8_t *name, const unsigned int nlength, const uint8_t *value, const unsigned int vlength, - enum PSYC_Modifier modifiers); + enum PSYC_Operator operators); /******************************************* diff --git a/src/render.c b/src/render.c index 2268aa7..a596124 100644 --- a/src/render.c +++ b/src/render.c @@ -9,15 +9,15 @@ inline void PSYC_initRenderState (PSYC_RenderState* state) PSYC_RenderRC PSYC_renderVar(PSYC_RenderState* state, const char* name, size_t nlength, const char* value, size_t vlength, - const PSYC_RenderFlag flags, char modifier) + const PSYC_RenderFlag flags, char operator) { size_t startc = state->cursor; unless (nlength) nlength = strlen(name); // vlength 0 means an empty variable.. no cheating there - unless (modifier) modifier = C_GLYPH_MODIFIER_SET; + unless (operator) operator = C_GLYPH_OPERATOR_SET; - state->buffer[state->cursor++] = modifier; + state->buffer[state->cursor++] = operator; strncpy(&state->buffer[state->cursor], name, nlength); state->cursor += nlength; diff --git a/test/testParser.c b/test/testParser.c index 7b1f8e8..bdab7e7 100644 --- a/test/testParser.c +++ b/test/testParser.c @@ -7,7 +7,7 @@ int main(int argc, char** argv) { int index, ret; - char buffer[2048], modifier; + char buffer[2048], operator; PSYC_Array name, value, elem; PSYC_ParseState state; PSYC_ParseListState listState; @@ -25,13 +25,13 @@ int main(int argc, char** argv) PSYC_nextParseBuffer(&state, PSYC_createArray(buffer, index)); // try parsing that now - while ((ret = PSYC_parse(&state, &modifier, &name, &value))) + while ((ret = PSYC_parse(&state, &operator, &name, &value))) { switch (ret) { case PSYC_PARSE_ROUTING: case PSYC_PARSE_ENTITY: - write(1, &modifier, 1); + write(1, &operator, 1); case PSYC_PARSE_BODY: // printf("the string is '%.*s'\n", name); write(1, name.ptr, name.length); diff --git a/test/testRender.c b/test/testRender.c index d2f856e..e3900ae 100644 --- a/test/testRender.c +++ b/test/testRender.c @@ -24,8 +24,8 @@ int writePresence(const char *avail, int availlen, const char *desc, int desclen // the first call to PSYC_renderHeader() without PSYC_RENDER_ROUTING adds the // extra newline to the buffer. later vars with PSYC_RENDER_ROUTING cause an error. - (void) PSYC_renderVar(pb, "_degree_availability", 0, avail, availlen, 0, C_GLYPH_MODIFIER_ASSIGN); - (void) PSYC_renderVar(pb, "_description_presence", 0, desc, desclen, 0, C_GLYPH_MODIFIER_ASSIGN); + (void) PSYC_renderVar(pb, "_degree_availability", 0, avail, availlen, 0, C_GLYPH_OPERATOR_ASSIGN); + (void) PSYC_renderVar(pb, "_description_presence", 0, desc, desclen, 0, C_GLYPH_OPERATOR_ASSIGN); // presence is to be assigned permanently in distributed state (void) PSYC_renderBody(pb, "_notice_presence", 0, From 746054dd0311c64658f3de2be73655a536b023ea Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Fri, 22 Apr 2011 22:44:14 +0200 Subject: [PATCH 072/378] PSYC_Packet struct? --- include/psyc.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/include/psyc.h b/include/psyc.h index 20fb553..ef166db 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -85,6 +85,23 @@ typedef struct const char* ptr; } PSYC_Array; + +/* intermediate struct for a PSYC variable modification */ +typedef struct { + char oper; // not call it 'operator' as C++ may not like that..? + PSYC_Array name; + PSYC_Array parameter; +} PSYC_Modifier; + +/* intermediate struct for a PSYC packet */ +typedef struct { + PSYC_Modifier **routing; // Header + PSYC_Modifier **entity; // Header + PSYC_Array method; + PSYC_Array data; +} PSYC_Packet; + + /// Routing vars in alphabetical order. extern const PSYC_Array PSYC_routingVars[]; /// Number of routing vars. From 427ef9ac565f0e614bed9cbcc3e409f87de48ad9 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 22 Apr 2011 22:59:15 +0200 Subject: [PATCH 073/378] s/operator/oper/ --- include/psyc/parser.h | 2 +- include/psyc/render.h | 2 +- src/parser.c | 10 +++++----- src/psyc_parser_cb.h | 4 ++-- src/render.c | 6 +++--- test/testParser.c | 6 +++--- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index 22e3866..caf4c59 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -163,7 +163,7 @@ inline size_t PSYC_getContentLength (PSYC_ParseState* s); * @param value A pointer to a PSYC_Array. It will point to the * value/body the variable/method and its length will be set accordingly */ -PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, char* operator, PSYC_Array* name, PSYC_Array* value); +PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, char* oper, PSYC_Array* name, PSYC_Array* value); /** * List value parser. diff --git a/include/psyc/render.h b/include/psyc/render.h index 1a47149..5e814fb 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -42,7 +42,7 @@ inline void PSYC_initRenderState (PSYC_RenderState* state); int PSYC_renderVar(PSYC_RenderState* render, const char* name, size_t nlength, const char* value, size_t vlength, - PSYC_RenderFlag flags, char operator); + PSYC_RenderFlag flags, char oper); int PSYC_renderBody(PSYC_RenderState* render, const char* method, size_t mlength, diff --git a/src/parser.c b/src/parser.c index d1b7017..bf87986 100644 --- a/src/parser.c +++ b/src/parser.c @@ -154,9 +154,9 @@ inline PSYC_ParseRC PSYC_parseBinaryValue(PSYC_ParseState* state, PSYC_Array* va * Parse simple or binary variable. * @return PSYC_PARSE_ERROR or PSYC_PARSE_SUCCESS */ -inline PSYC_ParseRC PSYC_parseVar(PSYC_ParseState* state, char* operator, PSYC_Array* name, PSYC_Array* value) +inline PSYC_ParseRC PSYC_parseVar(PSYC_ParseState* state, char* oper, PSYC_Array* name, PSYC_Array* value) { - *operator = *(state->buffer.ptr + state->cursor); + *oper = *(state->buffer.ptr + state->cursor); ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); if (PSYC_parseName(state, name) != PSYC_PARSE_SUCCESS) @@ -218,7 +218,7 @@ inline PSYC_ParseRC PSYC_parseVar(PSYC_ParseState* state, char* operator, PSYC_A * Parse PSYC packets. * Generalized line-based parser. */ -PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, char* operator, PSYC_Array* name, PSYC_Array* value) +PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, char* oper, PSYC_Array* name, PSYC_Array* value) { int ret; // a return value size_t pos; // a cursor position @@ -248,7 +248,7 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, char* operator, PSYC_Array* name // 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, operator, name, value); + ret = PSYC_parseVar(state, oper, name, value); return ret == PSYC_PARSE_SUCCESS ? PSYC_PARSE_ROUTING : ret; } else // not a glyph @@ -310,7 +310,7 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, char* operator, PSYC_Array* name if (isGlyph(state->buffer.ptr[state->cursor])) { pos = state->cursor; - ret = PSYC_parseVar(state, operator, name, value); + ret = PSYC_parseVar(state, oper, name, value); state->contentParsed += state->cursor - pos; return ret == PSYC_PARSE_SUCCESS ? PSYC_PARSE_ENTITY : ret; } diff --git a/src/psyc_parser_cb.h b/src/psyc_parser_cb.h index 6216fca..811f001 100644 --- a/src/psyc_parser_cb.h +++ b/src/psyc_parser_cb.h @@ -79,7 +79,7 @@ struct PSYC_Parser void (*stateCallback)(struct PSYC_Parser* pstate, const uint8_t *name, const unsigned int nlength, const uint8_t *value, const unsigned int vlength, - enum PSYC_Operator operators, char inEntity); + enum PSYC_Operator oper, char inEntity); /** @brief gets called after the routing-header was parsed * @@ -135,7 +135,7 @@ struct PSYC_Parser void (*errorStateCallback)(struct PSYC_Parser* pstate, const uint8_t *name, const unsigned int nlength, const uint8_t *value, const unsigned int vlength, - enum PSYC_Operator operators); + enum PSYC_Operator oper); /******************************************* diff --git a/src/render.c b/src/render.c index a596124..b83c9fb 100644 --- a/src/render.c +++ b/src/render.c @@ -9,15 +9,15 @@ inline void PSYC_initRenderState (PSYC_RenderState* state) PSYC_RenderRC PSYC_renderVar(PSYC_RenderState* state, const char* name, size_t nlength, const char* value, size_t vlength, - const PSYC_RenderFlag flags, char operator) + const PSYC_RenderFlag flags, char oper) { size_t startc = state->cursor; unless (nlength) nlength = strlen(name); // vlength 0 means an empty variable.. no cheating there - unless (operator) operator = C_GLYPH_OPERATOR_SET; + unless (oper) oper = C_GLYPH_OPERATOR_SET; - state->buffer[state->cursor++] = operator; + state->buffer[state->cursor++] = oper; strncpy(&state->buffer[state->cursor], name, nlength); state->cursor += nlength; diff --git a/test/testParser.c b/test/testParser.c index bdab7e7..de6b584 100644 --- a/test/testParser.c +++ b/test/testParser.c @@ -7,7 +7,7 @@ int main(int argc, char** argv) { int index, ret; - char buffer[2048], operator; + char buffer[2048], oper; PSYC_Array name, value, elem; PSYC_ParseState state; PSYC_ParseListState listState; @@ -25,13 +25,13 @@ int main(int argc, char** argv) PSYC_nextParseBuffer(&state, PSYC_createArray(buffer, index)); // try parsing that now - while ((ret = PSYC_parse(&state, &operator, &name, &value))) + while ((ret = PSYC_parse(&state, &oper, &name, &value))) { switch (ret) { case PSYC_PARSE_ROUTING: case PSYC_PARSE_ENTITY: - write(1, &operator, 1); + write(1, &oper, 1); case PSYC_PARSE_BODY: // printf("the string is '%.*s'\n", name); write(1, name.ptr, name.length); From c2ad0f0bd704d45db8b5659e3c0db24c0b622906 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 22 Apr 2011 23:16:50 +0200 Subject: [PATCH 074/378] more PSYC_Packet fields; s/Var/Modifier/ --- include/psyc.h | 19 +++++++++++++++++-- include/psyc/render.h | 2 +- src/parser.c | 6 +++--- src/render.c | 2 +- 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/include/psyc.h b/include/psyc.h index ef166db..53c1cf3 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -79,18 +79,31 @@ typedef enum PSYC_LIST_BINARY = 2, } PSYC_ListType; +typedef enum { + PSYC_MODIFIER_CHECK_LENGTH = 0, + PSYC_MODIFIER_NEED_LENGTH = 1, + PSYC_MODIFIER_NO_LENGTH = 2, + PSYC_MODIFIER_ROUTING = 3, +} PSYC_ModifierType; + +typedef enum { + PSYC_CONTENT_CHECK_LENGTH = 0, + PSYC_CONTENT_NEED_LENGTH = 1, + PSYC_CONTENT_NO_LENGTH = 2, +} PSYC_ContentType; + typedef struct { size_t length; const char* ptr; } PSYC_Array; - /* intermediate struct for a PSYC variable modification */ typedef struct { char oper; // not call it 'operator' as C++ may not like that..? PSYC_Array name; - PSYC_Array parameter; + PSYC_Array value; + PSYC_ModifierType type; } PSYC_Modifier; /* intermediate struct for a PSYC packet */ @@ -99,6 +112,8 @@ typedef struct { PSYC_Modifier **entity; // Header PSYC_Array method; PSYC_Array data; + PSYC_ContentType contentType; + size_t contentLength; } PSYC_Packet; diff --git a/include/psyc/render.h b/include/psyc/render.h index 5e814fb..34c0969 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -39,7 +39,7 @@ typedef struct */ inline void PSYC_initRenderState (PSYC_RenderState* state); -int PSYC_renderVar(PSYC_RenderState* render, +int PSYC_renderModifier(PSYC_RenderState* render, const char* name, size_t nlength, const char* value, size_t vlength, PSYC_RenderFlag flags, char oper); diff --git a/src/parser.c b/src/parser.c index bf87986..3638023 100644 --- a/src/parser.c +++ b/src/parser.c @@ -154,7 +154,7 @@ inline PSYC_ParseRC PSYC_parseBinaryValue(PSYC_ParseState* state, PSYC_Array* va * Parse simple or binary variable. * @return PSYC_PARSE_ERROR or PSYC_PARSE_SUCCESS */ -inline PSYC_ParseRC PSYC_parseVar(PSYC_ParseState* state, char* oper, PSYC_Array* name, PSYC_Array* value) +inline PSYC_ParseRC PSYC_parseModifier(PSYC_ParseState* state, char* oper, PSYC_Array* name, PSYC_Array* value) { *oper = *(state->buffer.ptr + state->cursor); ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); @@ -248,7 +248,7 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, char* oper, PSYC_Array* name, PS // 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, oper, name, value); + ret = PSYC_parseModifier(state, oper, name, value); return ret == PSYC_PARSE_SUCCESS ? PSYC_PARSE_ROUTING : ret; } else // not a glyph @@ -310,7 +310,7 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, char* oper, PSYC_Array* name, PS if (isGlyph(state->buffer.ptr[state->cursor])) { pos = state->cursor; - ret = PSYC_parseVar(state, oper, name, value); + ret = PSYC_parseModifier(state, oper, name, value); state->contentParsed += state->cursor - pos; return ret == PSYC_PARSE_SUCCESS ? PSYC_PARSE_ENTITY : ret; } diff --git a/src/render.c b/src/render.c index b83c9fb..7052f79 100644 --- a/src/render.c +++ b/src/render.c @@ -6,7 +6,7 @@ inline void PSYC_initRenderState (PSYC_RenderState* state) memset(state, 0, sizeof(PSYC_RenderState)); } -PSYC_RenderRC PSYC_renderVar(PSYC_RenderState* state, +PSYC_RenderRC PSYC_renderModifier(PSYC_RenderState* state, const char* name, size_t nlength, const char* value, size_t vlength, const PSYC_RenderFlag flags, char oper) From 094db6c07a2f80623858273f0a8ab56c4ba44329 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sat, 23 Apr 2011 16:51:46 +0200 Subject: [PATCH 075/378] function definitions for creating packet & modifier structs --- include/psyc.h | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/include/psyc.h b/include/psyc.h index 53c1cf3..c25f9e7 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -79,18 +79,20 @@ typedef enum PSYC_LIST_BINARY = 2, } PSYC_ListType; -typedef enum { +typedef enum +{ PSYC_MODIFIER_CHECK_LENGTH = 0, PSYC_MODIFIER_NEED_LENGTH = 1, PSYC_MODIFIER_NO_LENGTH = 2, PSYC_MODIFIER_ROUTING = 3, -} PSYC_ModifierType; +} PSYC_ModifierFlag; -typedef enum { - PSYC_CONTENT_CHECK_LENGTH = 0, - PSYC_CONTENT_NEED_LENGTH = 1, - PSYC_CONTENT_NO_LENGTH = 2, -} PSYC_ContentType; +typedef enum +{ + PSYC_PACKET_CHECK_LENGTH = 0, + PSYC_PACKET_NEED_LENGTH = 1, + PSYC_PACKET_NO_LENGTH = 2, +} PSYC_PacketFlag; typedef struct { @@ -99,23 +101,32 @@ typedef struct } PSYC_Array; /* intermediate struct for a PSYC variable modification */ -typedef struct { +typedef struct +{ char oper; // not call it 'operator' as C++ may not like that..? PSYC_Array name; PSYC_Array value; - PSYC_ModifierType type; + PSYC_ModifierFlag flag; } PSYC_Modifier; /* intermediate struct for a PSYC packet */ -typedef struct { - PSYC_Modifier **routing; // Header - PSYC_Modifier **entity; // Header +typedef struct +{ + PSYC_Modifier** routing; // Routing header + PSYC_Modifier** entity; // Entitiy header PSYC_Array method; PSYC_Array data; - PSYC_ContentType contentType; - size_t contentLength; + size_t length; /// Length of content part + PSYC_PacketFlag flag; } PSYC_Packet; +PSYC_Modifier PSYC_newModifier(char* oper, PSYC_Array* name, PSYC_Array* value, PSYC_ModifierFlag flag); + +PSYC_Modifier PSYC_newModifier2(char* oper, char* name, size_t namelen, char* value, size_t valuelen, PSYC_ModifierFlag flag); + +PSYC_Packet PSYC_newPacket(PSYC_Modifier** routing, PSYC_Modifier **entity, PSYC_Array* method, PSYC_Array* data, PSYC_PacketFlag flag) + +PSYC_Packet PSYC_newPacket2(PSYC_Modifier** routing, PSYC_Modifier **entity, char* method, size_t methodlen, char* data, size_t datalen, PSYC_PacketFlag flag) /// Routing vars in alphabetical order. extern const PSYC_Array PSYC_routingVars[]; From 2e688127c8f733541d44bf1d9f3a4a0ff91099e1 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sat, 23 Apr 2011 16:58:02 +0200 Subject: [PATCH 076/378] added missing ; --- include/psyc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/psyc.h b/include/psyc.h index c25f9e7..640416f 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -124,9 +124,9 @@ PSYC_Modifier PSYC_newModifier(char* oper, PSYC_Array* name, PSYC_Array* value, PSYC_Modifier PSYC_newModifier2(char* oper, char* name, size_t namelen, char* value, size_t valuelen, PSYC_ModifierFlag flag); -PSYC_Packet PSYC_newPacket(PSYC_Modifier** routing, PSYC_Modifier **entity, PSYC_Array* method, PSYC_Array* data, PSYC_PacketFlag flag) +PSYC_Packet PSYC_newPacket(PSYC_Modifier** routing, PSYC_Modifier **entity, PSYC_Array* method, PSYC_Array* data, PSYC_PacketFlag flag); -PSYC_Packet PSYC_newPacket2(PSYC_Modifier** routing, PSYC_Modifier **entity, char* method, size_t methodlen, char* data, size_t datalen, PSYC_PacketFlag flag) +PSYC_Packet PSYC_newPacket2(PSYC_Modifier** routing, PSYC_Modifier **entity, char* method, size_t methodlen, char* data, size_t datalen, PSYC_PacketFlag flag); /// Routing vars in alphabetical order. extern const PSYC_Array PSYC_routingVars[]; From 2e71c012f1778c9591a4633436f2fa3df1eb4643 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Sat, 23 Apr 2011 17:16:05 +0200 Subject: [PATCH 077/378] how to pass constrant strings with length at compile time --- include/psyc.h | 3 +++ src/variable.c | 16 +++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/include/psyc.h b/include/psyc.h index 53c1cf3..21aa8d7 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -98,6 +98,9 @@ typedef struct const char* ptr; } PSYC_Array; +#define PSYC_C2ARRAY(string) { sizeof(string)-1, string } +#define PSYC_C2ARG(string) string, sizeof(string)-1 + /* intermediate struct for a PSYC variable modification */ typedef struct { char oper; // not call it 'operator' as C++ may not like that..? diff --git a/src/variable.c b/src/variable.c index d666047..3754136 100644 --- a/src/variable.c +++ b/src/variable.c @@ -5,22 +5,24 @@ const PSYC_Array PSYC_routingVars[] = /// Routing variables in alphabetical orde { {17, "_amount_fragments"}, { 8, "_context"}, - { 6, "_count"}, +// { 6, "_count"}, // older PSYC { 8, "_counter"}, // the name for this is supposed to be _count, not _counter { 9, "_fragment"}, - { 7, "_length"}, +// { 7, "_length"}, // older PSYC { 7, "_source"}, - {22, "_source_identification"}, - {13, "_source_relay"}, + PSYC_C2ARRAY("_source_identification"), +// {22, "_source_identification"}, + PSYC_C2ARRAY("_source_relay"), +// {13, "_source_relay"}, {19, "_source_relay_relay"}, // until you have a better idea.. is this really in use? { 4, "_tag"}, {10, "_tag_relay"}, - {10, "_tag_reply"}, // should be obsolete, but.. TODO +// {10, "_tag_reply"}, // older PSYC { 7, "_target"}, {15, "_target_forward"}, {13, "_target_relay"}, - {19, "_understand_modules"}, - {14, "_using_modules"}, +// {19, "_understand_modules"}, // older PSYC +// {14, "_using_modules"}, // older PSYC }; const size_t PSYC_routingVarsNum = sizeof(PSYC_routingVars) / sizeof(*PSYC_routingVars); From 592aa596e8e3096cef0e70419a1f0392efc97e32 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sun, 24 Apr 2011 17:23:44 +0200 Subject: [PATCH 078/378] bsd memmem --- src/memmem.c | 129 +++++++++++++++++++++++++-------------------------- 1 file changed, 62 insertions(+), 67 deletions(-) diff --git a/src/memmem.c b/src/memmem.c index a5e1ad3..7bda893 100644 --- a/src/memmem.c +++ b/src/memmem.c @@ -1,67 +1,62 @@ -#ifndef _GNU_SOURCE - -/* Copyright (C) 1991,92,93,94,96,97,98,2000,2004,2007 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* -#ifndef _LIBC -# include -#endif -*/ - -#include -#include - -#ifndef _LIBC -# define __builtin_expect(expr, val) (expr) -#endif - -#undef memmem - -/* Return the first occurrence of NEEDLE in HAYSTACK. */ -void * -memmem (haystack, haystack_len, needle, needle_len) - const void *haystack; - size_t haystack_len; - const void *needle; - size_t needle_len; -{ - const char *begin; - const char *const last_possible - = (const char *) haystack + haystack_len - needle_len; - - if (needle_len == 0) - /* The first occurrence of the empty string is deemed to occur at - the beginning of the string. */ - return (void *) haystack; - - /* Sanity check, otherwise the loop might search through the whole - memory. */ - if (__builtin_expect (haystack_len < needle_len, 0)) - return NULL; - - for (begin = (const char *) haystack; begin <= last_possible; ++begin) - if (begin[0] == ((const char *) needle)[0] && - !memcmp ((const void *) &begin[1], - (const void *) ((const char *) needle + 1), - needle_len - 1)) - return (void *) begin; - - return NULL; -} - -#endif +/*- + * Copyright (c) 2005 Pascal Gloor + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +/* + * Find the first occurrence of the byte string s in byte string l. + */ + +void * +memmem(const void *l, size_t l_len, const void *s, size_t s_len) +{ + register char *cur, *last; + const char *cl = (const char *)l; + const char *cs = (const char *)s; + + /* we need something to compare */ + if (l_len == 0 || s_len == 0) + return NULL; + + /* "s" must be smaller or equal to "l" */ + if (l_len < s_len) + return NULL; + + /* special case where s_len == 1 */ + if (s_len == 1) + return memchr(l, (int)*cs, l_len); + + /* the last position where its possible to find "s" in "l" */ + last = (char *)cl + l_len - s_len; + + for (cur = (char *)cl; cur <= last; cur++) + if (cur[0] == cs[0] && memcmp(cur, cs, s_len) == 0) + return cur; + + return NULL; +} From 7db73bacda625791f75d76a0bbad5f7d754375e1 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sun, 24 Apr 2011 18:11:57 +0200 Subject: [PATCH 079/378] bsd memmem .h --- include/psyc/lib.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/psyc/lib.h b/include/psyc/lib.h index 8378468..1847ef5 100644 --- a/include/psyc/lib.h +++ b/include/psyc/lib.h @@ -5,14 +5,14 @@ #include "../psyc.h" #include "./debug.h" +#include /* perlisms for readability */ #define unless(COND) if (!(COND)) #define until(COND) while (!(COND)) -#ifndef _GNU_SOURCE -void *memmem(const void *haystack, size_t haystacklen, - const void *needle, size_t needlelen); +#if !defined(_GNU_SOURCE) && !defined(__FBSDID) +void * memmem(const void *l, size_t l_len, const void *s, size_t s_len); #endif #endif // PSYC_LIB_H From 5a1e4825adce036c46966d524a59b5e6ab208448 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 25 Apr 2011 14:20:13 +0200 Subject: [PATCH 080/378] functions for creating packet & modifier structs, rendering --- include/psyc.h | 85 ++++++++++++++++++++++------------ include/psyc/parser.h | 26 ++++------- include/psyc/render.h | 5 +- include/psyc/syntax.h | 5 ++ src/Makefile | 4 +- src/parser.c | 20 +++----- src/psyc.c | 104 ++++++++++++++++++++++++++++++++++++++++++ src/render.c | 61 +++++++++++++++++++++---- src/variable.c | 41 ++++++++--------- test/Makefile | 2 +- test/isRoutingVar.c | 3 +- test/testParser.c | 4 +- test/testRender.c | 6 +-- 13 files changed, 267 insertions(+), 99 deletions(-) create mode 100644 src/psyc.c diff --git a/include/psyc.h b/include/psyc.h index cb68fc0..860d7d4 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -97,66 +97,95 @@ typedef enum typedef struct { size_t length; - const char* ptr; -} PSYC_Array; + const char *ptr; +} PSYC_String; -#define PSYC_C2ARRAY(string) { sizeof(string)-1, string } +/** + * Shortcut for creating a PSYC_String. + * + * @param memory Pointer to the buffer. + * @param length Length of that buffer. + * + * @return An instance of the PSYC_String struct. + */ +inline PSYC_String PSYC_newString (const char *str, size_t strlen); + +#define PSYC_C2STR(string) {sizeof(string)-1, string} #define PSYC_C2ARG(string) string, sizeof(string)-1 /* intermediate struct for a PSYC variable modification */ typedef struct { - char oper; // not call it 'operator' as C++ may not like that..? - PSYC_Array name; - PSYC_Array value; + char oper; // not call it 'operator' as C++ may not like that.. + PSYC_String name; + PSYC_String value; PSYC_ModifierFlag flag; } PSYC_Modifier; +typedef struct +{ + size_t length; + PSYC_Modifier *ptr; +} PSYC_ModifierArray; + /* intermediate struct for a PSYC packet */ typedef struct { - PSYC_Modifier** routing; // Routing header - PSYC_Modifier** entity; // Entitiy header - PSYC_Array method; - PSYC_Array data; - size_t length; /// Length of content part + PSYC_ModifierArray routing; ///< Routing header. + PSYC_ModifierArray entity; ///< Entitiy header. + PSYC_String method; + PSYC_String data; + size_t routingLength; ///< Length of routing part. + size_t contentLength; ///< Length of content part. + size_t length; ///< Total length of packet. PSYC_PacketFlag flag; } PSYC_Packet; -PSYC_Modifier PSYC_newModifier(char* oper, PSYC_Array* name, PSYC_Array* value, PSYC_ModifierFlag flag); +inline PSYC_Modifier PSYC_newModifier(char oper, PSYC_String *name, PSYC_String *value, + PSYC_ModifierFlag flag); -PSYC_Modifier PSYC_newModifier2(char* oper, char* name, size_t namelen, char* value, size_t valuelen, PSYC_ModifierFlag flag); +inline PSYC_Modifier PSYC_newModifier2(char oper, + const char *name, size_t namelen, + const char *value, size_t valuelen, + PSYC_ModifierFlag flag); -PSYC_Packet PSYC_newPacket(PSYC_Modifier** routing, PSYC_Modifier **entity, PSYC_Array* method, PSYC_Array* data, PSYC_PacketFlag flag); +inline PSYC_Packet PSYC_newPacket(PSYC_ModifierArray *routing, + PSYC_ModifierArray *entity, + PSYC_String *method, PSYC_String *data, + PSYC_PacketFlag flag); -PSYC_Packet PSYC_newPacket2(PSYC_Modifier** routing, PSYC_Modifier **entity, char* method, size_t methodlen, char* data, size_t datalen, PSYC_PacketFlag flag); +inline PSYC_Packet PSYC_newPacket2(PSYC_Modifier **routing, size_t routinglen, + PSYC_Modifier **entity, size_t entitylen, + const char *method, size_t methodlen, + const char *data, size_t datalen, + PSYC_PacketFlag flag); /// Routing vars in alphabetical order. -extern const PSYC_Array PSYC_routingVars[]; +extern const PSYC_String PSYC_routingVars[]; /// Number of routing vars. extern const size_t PSYC_routingVarsNum; /** * Get the type of variable name. */ -PSYC_Bool PSYC_isRoutingVar(const char* name, size_t len); +PSYC_Bool PSYC_isRoutingVar(const char *name, size_t len); /** * Get the type of variable name. */ -PSYC_Type PSYC_getVarType(char* name, size_t len); +PSYC_Type PSYC_getVarType(char *name, size_t len); /** * Checks if long keyword string inherits from short keyword string. */ -int PSYC_inherits(char* sho, size_t slen, - char* lon, size_t llen); +int PSYC_inherits(char *sho, size_t slen, + char *lon, size_t llen); /** * Checks if short keyword string matches long keyword string. */ -int PSYC_matches(char* sho, size_t slen, - char* lon, size_t llen); +int PSYC_matches(char *sho, size_t slen, + char *lon, size_t llen); /** * Callback for PSYC_text() that produces a value for a match. @@ -167,8 +196,8 @@ int PSYC_matches(char* sho, size_t slen, * number of bytes written. 0 is a legal return value. Should the * callback return -1, PSYC_text leaves the original template text as is. */ -typedef int (*PSYC_textCB)(uint8_t* match, size_t mlen, - uint8_t** buffer, size_t * blen); +typedef int (*PSYC_textCB)(uint8_t *match, size_t mlen, + uint8_t **buffer, size_t *blen); /** * Fills out text templates by asking a callback for content. @@ -183,9 +212,9 @@ typedef int (*PSYC_textCB)(uint8_t* match, size_t mlen, * * See also http://about.psyc.eu/psyctext */ -int PSYC_text(uint8_t* template, size_t tlen, - uint8_t** buffer, size_t * blen, - PSYC_textCB lookupValue, - char* braceOpen, char* braceClose); +int PSYC_text(uint8_t *template, size_t tlen, + uint8_t **buffer, size_t *blen, + PSYC_textCB lookupValue, + char *braceOpen, char *braceClose); #endif // PSYC_H diff --git a/include/psyc/parser.h b/include/psyc/parser.h index caf4c59..7af13f1 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -87,7 +87,7 @@ typedef struct { size_t cursor; ///< current position in buffer size_t startc; ///< position where the parsing would be resumed - PSYC_Array buffer; ///< buffer with data to be parsed + PSYC_String buffer; ///< buffer with data to be parsed uint8_t flags; ///< flags for the parser, see PSYC_ParseFlag PSYC_Part part; ///< part of the packet being parsed currently @@ -105,23 +105,13 @@ typedef struct { size_t cursor; ///< current position in buffer size_t startc; ///< line start position - PSYC_Array buffer; + PSYC_String buffer; PSYC_ListType type; ///< list type size_t elemParsed; ///< number of bytes parsed from the elem so far size_t elemLength; ///< expected length of the elem } PSYC_ParseListState; -/** - * 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. - */ -inline PSYC_Array PSYC_createArray (const char* memory, size_t length); - /** * Initiates the state struct. * @@ -144,9 +134,9 @@ inline void PSYC_initParseState2 (PSYC_ParseState* state, uint8_t flags); */ inline void PSYC_initParseListState (PSYC_ParseListState* state); -inline void PSYC_nextParseBuffer (PSYC_ParseState* state, PSYC_Array newBuf); +inline void PSYC_nextParseBuffer (PSYC_ParseState* state, PSYC_String newBuf); -inline void PSYC_nextParseListBuffer (PSYC_ParseListState* state, PSYC_Array newBuf); +inline void PSYC_nextParseListBuffer (PSYC_ParseListState* state, PSYC_String newBuf); inline size_t PSYC_getContentLength (PSYC_ParseState* s); @@ -158,17 +148,17 @@ inline size_t PSYC_getContentLength (PSYC_ParseState* s); * @param state An initialized PSYC_ParseState * @param operator A pointer to a character. In case of a variable, it will * be set to the operator of that variable - * @param name A pointer to a PSYC_Array. It will point to the name of + * @param name A pointer to a PSYC_String. It will point to the name of * the variable or method and its length will be set accordingly - * @param value A pointer to a PSYC_Array. It will point to the + * @param value A pointer to a PSYC_String. It will point to the * value/body the variable/method and its length will be set accordingly */ -PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, char* oper, PSYC_Array* name, PSYC_Array* value); +PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, char* oper, PSYC_String* name, PSYC_String* value); /** * List value parser. */ -PSYC_ParseListRC PSYC_parseList(PSYC_ParseListState* state, PSYC_Array *name, PSYC_Array* value, PSYC_Array* elem); +PSYC_ParseListRC PSYC_parseList(PSYC_ParseListState* state, PSYC_String *name, PSYC_String* value, PSYC_String* elem); #endif // PSYC_PARSER_H diff --git a/include/psyc/render.h b/include/psyc/render.h index 34c0969..c70d108 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -32,11 +32,14 @@ typedef struct char buffer[]; ///< OMG a C99 feature! variable size buffer! } PSYC_RenderState; +PSYC_RenderRC PSYC_render(PSYC_Packet *packet, char *buffer, size_t buflen); + /** * Initiates the state struct. * * @param state Pointer to the state struct that should be initiated. */ +/* inline void PSYC_initRenderState (PSYC_RenderState* state); int PSYC_renderModifier(PSYC_RenderState* render, @@ -47,5 +50,5 @@ int PSYC_renderModifier(PSYC_RenderState* render, int PSYC_renderBody(PSYC_RenderState* render, const char* method, size_t mlength, const char* data, size_t dlength); - +*/ #endif // PSYC_RENDER_H diff --git a/include/psyc/syntax.h b/include/psyc/syntax.h index ab4ff0d..92aadb9 100644 --- a/include/psyc/syntax.h +++ b/include/psyc/syntax.h @@ -10,6 +10,11 @@ # define PSYC_CONTENT_SIZE_THRESHOLD 444 #endif +/* beyond this a modifier value length must be provided */ +#ifndef PSYC_MODIFIER_SIZE_THRESHOLD +# define PSYC_MODIFIER_SIZE_THRESHOLD 404 +#endif + #define C_GLYPH_PACKET_DELIMITER '|' #define S_GLYPH_PACKET_DELIMITER "|" #define PSYC_PACKET_DELIMITER "\n|\n" diff --git a/src/Makefile b/src/Makefile index 4a3b661..86c6c09 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,8 +2,8 @@ CFLAGS=-I../include -DDEBUG=2 -DPSYC_COMPILE_LIBRARY -g -O0 -Wall CC=cc # CC=clang -S=parser.c match.c render.c memmem.c variable.c -O=parser.o match.o render.o memmem.o variable.o +S=psyc.c parser.c match.c render.c memmem.c variable.c +O=psyc.o parser.o match.o render.o memmem.o variable.o default: @/bin/echo -e "Usage:\n\tmake diet - compile with diet libc\n\tmake lib - compile with normal gnu libc" diff --git a/src/parser.c b/src/parser.c index 3638023..13852fd 100644 --- a/src/parser.c +++ b/src/parser.c @@ -15,12 +15,6 @@ return ret; \ } -inline PSYC_Array PSYC_createArray (const char* memory, size_t length) -{ - PSYC_Array arr = {length, memory}; - return arr; -} - inline void PSYC_initParseState (PSYC_ParseState* state) { memset(state, 0, sizeof(PSYC_ParseState)); @@ -37,13 +31,13 @@ inline void PSYC_initParseListState (PSYC_ParseListState* state) memset(state, 0, sizeof(PSYC_ParseListState)); } -inline void PSYC_nextParseBuffer (PSYC_ParseState* state, PSYC_Array newBuf) +inline void PSYC_nextParseBuffer (PSYC_ParseState* state, PSYC_String newBuf) { state->buffer = newBuf; state->cursor = 0; } -inline void PSYC_nextParseListBuffer (PSYC_ParseListState* state, PSYC_Array newBuf) +inline void PSYC_nextParseListBuffer (PSYC_ParseListState* state, PSYC_String newBuf) { state->buffer = newBuf; state->cursor = 0; @@ -107,7 +101,7 @@ inline char isKwChar(uint8_t c) * It should contain one or more keyword characters. * @return PSYC_PARSE_ERROR or PSYC_PARSE_SUCCESS */ -inline PSYC_ParseRC PSYC_parseName(PSYC_ParseState* state, PSYC_Array* name) +inline PSYC_ParseRC PSYC_parseName(PSYC_ParseState* state, PSYC_String* name) { name->ptr = state->buffer.ptr + state->cursor; name->length = 0; @@ -131,7 +125,7 @@ inline PSYC_ParseRC PSYC_parseName(PSYC_ParseState* state, PSYC_Array* name) * * @return PSYC_PARSE_COMPLETE or PSYC_PARSE_INCOMPLETE */ -inline PSYC_ParseRC PSYC_parseBinaryValue(PSYC_ParseState* state, PSYC_Array* value, size_t* length, size_t* parsed) +inline PSYC_ParseRC PSYC_parseBinaryValue(PSYC_ParseState* state, PSYC_String* value, size_t* length, size_t* parsed) { size_t remaining = *length - *parsed; value->ptr = state->buffer.ptr + state->cursor; @@ -154,7 +148,7 @@ inline PSYC_ParseRC PSYC_parseBinaryValue(PSYC_ParseState* state, PSYC_Array* va * Parse simple or binary variable. * @return PSYC_PARSE_ERROR or PSYC_PARSE_SUCCESS */ -inline PSYC_ParseRC PSYC_parseModifier(PSYC_ParseState* state, char* oper, PSYC_Array* name, PSYC_Array* value) +inline PSYC_ParseRC PSYC_parseModifier(PSYC_ParseState* state, char* oper, PSYC_String* name, PSYC_String* value) { *oper = *(state->buffer.ptr + state->cursor); ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); @@ -218,7 +212,7 @@ inline PSYC_ParseRC PSYC_parseModifier(PSYC_ParseState* state, char* oper, PSYC_ * Parse PSYC packets. * Generalized line-based parser. */ -PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, char* oper, PSYC_Array* name, PSYC_Array* value) +PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, char* oper, PSYC_String* name, PSYC_String* value) { int ret; // a return value size_t pos; // a cursor position @@ -408,7 +402,7 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, char* oper, PSYC_Array* name, PS * List value parser. * @return see PSYC_ListRC. */ -PSYC_ParseListRC PSYC_parseList(PSYC_ParseListState* state, PSYC_Array *name, PSYC_Array* value, PSYC_Array* elem) +PSYC_ParseListRC PSYC_parseList(PSYC_ParseListState* state, PSYC_String *name, PSYC_String* value, PSYC_String* elem) { if (state->cursor >= state->buffer.length) return PSYC_PARSE_LIST_INCOMPLETE; diff --git a/src/psyc.c b/src/psyc.c new file mode 100644 index 0000000..6aec5e1 --- /dev/null +++ b/src/psyc.c @@ -0,0 +1,104 @@ +#include +#include + +#include + +inline PSYC_String PSYC_newString (const char *str, size_t strlen) +{ + PSYC_String s = {strlen, str}; + return s; +} + +inline PSYC_Modifier PSYC_newModifier(char oper, PSYC_String *name, PSYC_String *value, + PSYC_ModifierFlag flag) +{ + PSYC_Modifier m = {oper, *name, *value, flag}; + + if (flag == PSYC_MODIFIER_CHECK_LENGTH) // find out if it needs a length + { + if (value->length > PSYC_MODIFIER_SIZE_THRESHOLD) + m.flag = PSYC_PACKET_NEED_LENGTH; + else if (memchr(value->ptr, (int)'\n', value->length)) + m.flag = PSYC_PACKET_NEED_LENGTH; + else + m.flag = PSYC_PACKET_NO_LENGTH; + } + + return m; +} + +inline PSYC_Modifier PSYC_newModifier2(char oper, + const char *name, size_t namelen, + const char *value, size_t valuelen, + PSYC_ModifierFlag flag) +{ + PSYC_String n = {namelen, name}; + PSYC_String v = {valuelen, value}; + + return PSYC_newModifier(oper, &n, &v, flag); +} + +inline size_t PSYC_getModifierLength(PSYC_Modifier *m) +{ + size_t length = + m->name.length + 1 + // name\t + m->value.length + 1; // value\n + + if (m->flag == PSYC_MODIFIER_NEED_LENGTH) // add length of length if needed + length += log10((double)m->value.length) + 2; // SP length + + return length; +} + +inline PSYC_Packet PSYC_newPacket(PSYC_ModifierArray *routing, + PSYC_ModifierArray *entity, + PSYC_String *method, PSYC_String *data, + PSYC_PacketFlag flag) +{ + PSYC_Packet p = {*routing, *entity, *method, *data, 0, 0, flag}; + size_t i; + + if (flag == PSYC_PACKET_CHECK_LENGTH) // find out if it needs a length + { + if (data->length == 1 && data->ptr[0] == C_GLYPH_PACKET_DELIMITER) + p.flag = PSYC_PACKET_NEED_LENGTH; + else if (data->length > PSYC_CONTENT_SIZE_THRESHOLD) + p.flag = PSYC_PACKET_NEED_LENGTH; + else if (memmem(data->ptr, data->length, PSYC_C2ARG(PSYC_PACKET_DELIMITER))) + p.flag = PSYC_PACKET_NEED_LENGTH; + else + p.flag = PSYC_PACKET_NO_LENGTH; + } + + // calculate routing header length + for (i = 0; i < routing->length; i++) + p.routingLength += PSYC_getModifierLength(&routing->ptr[i]); + + // calculate entity header length + for (i = 0; i < entity->length; i++) + p.contentLength += PSYC_getModifierLength(&routing->ptr[i]); + + // add length of method, data & delimiter + p.contentLength += method->length + 1 + data->length; // method \n data + + // set total length: routing-header \n content \n|\n + p.length = p.routingLength + 1 + p.contentLength + sizeof(PSYC_PACKET_DELIMITER) - 1; + if (flag == PSYC_PACKET_NEED_LENGTH) // add length of length if needed + p.length += log10((double)data->length) + 1; + + return p; +} + +inline PSYC_Packet PSYC_newPacket2(PSYC_Modifier **routing, size_t routinglen, + PSYC_Modifier **entity, size_t entitylen, + const char *method, size_t methodlen, + const char *data, size_t datalen, + PSYC_PacketFlag flag) +{ + PSYC_ModifierArray r = {routinglen, *routing}; + PSYC_ModifierArray e = {entitylen, *entity}; + PSYC_String m = {methodlen, method}; + PSYC_String d = {datalen, data}; + + return PSYC_newPacket(&r, &e, &m, &d, flag); +} diff --git a/src/render.c b/src/render.c index 7052f79..bcf9d7f 100644 --- a/src/render.c +++ b/src/render.c @@ -1,14 +1,57 @@ #include "psyc/lib.h" #include "psyc/render.h" -inline void PSYC_initRenderState (PSYC_RenderState* state) +inline int PSYC_renderModifier(PSYC_Modifier *m, char *buffer) +{ + int cur = 0; + + memcpy(buffer + cur++, &m->oper, 1); + memcpy(buffer + cur, m->name.ptr, m->name.length); + cur += m->name.length; + if (m->flag == PSYC_MODIFIER_NEED_LENGTH) + { + memcpy(buffer + cur++, " ", 1); + cur += sprintf(buffer + cur, "%ld", m->value.length); + } + memcpy(buffer + cur, m->value.ptr, m->value.length); + cur += m->value.length; + memcpy(buffer + cur++, "\n", 1); + + return cur; +} + +PSYC_RenderRC PSYC_render(PSYC_Packet *packet, char *buffer, size_t buflen) +{ + size_t cur, i; + + if (packet->length > buflen) + return PSYC_RENDER_ERROR; + + for (i = 0; i < packet->routing.length; i++) + cur += PSYC_renderModifier(&packet->routing.ptr[i], buffer + cur); + + if (packet->flag == PSYC_PACKET_NEED_LENGTH) + cur += sprintf(buffer + cur, "%ld", packet->contentLength); + + memcpy(buffer + cur++, "\n", 1); + + for (i = 0; i < packet->entity.length; i++) + cur += PSYC_renderModifier(&packet->entity.ptr[i], buffer + cur); + + memcpy(buffer + cur, PSYC_C2ARG(PSYC_PACKET_DELIMITER)); + + return PSYC_RENDER_SUCCESS; +} + +/* +inline void PSYC_initRenderState (PSYC_RenderState *state) { memset(state, 0, sizeof(PSYC_RenderState)); } -PSYC_RenderRC PSYC_renderModifier(PSYC_RenderState* state, - const char* name, size_t nlength, - const char* value, size_t vlength, +PSYC_RenderRC PSYC_renderModifier(PSYC_RenderState *state, + const char *name, size_t nlength, + const char *value, size_t vlength, const PSYC_RenderFlag flags, char oper) { size_t startc = state->cursor; @@ -51,10 +94,9 @@ PSYC_RenderRC PSYC_renderModifier(PSYC_RenderState* state, return PSYC_RENDER_SUCCESS; } -/* render PSYC packets */ -PSYC_RenderRC PSYC_renderBody(PSYC_RenderState* state, - const char* method, size_t mlength, - const char* data, size_t dlength) +PSYC_RenderRC PSYC_renderBody(PSYC_RenderState *state, + const char *method, size_t mlength, + const char *data, size_t dlength) { if (state->flag == PSYC_RENDER_CHECK_LENGTH) { @@ -63,7 +105,7 @@ PSYC_RenderRC PSYC_renderBody(PSYC_RenderState* state, state->flag = PSYC_RENDER_NEED_LENGTH; else if (dlength > 404) state->flag = PSYC_RENDER_NEED_LENGTH; - else if (memmem(data, dlength, PSYC_PACKET_DELIMITER, sizeof(PSYC_PACKET_DELIMITER))) + else if (memmem(data, dlength, PSYC_C2ARG(PSYC_PACKET_DELIMITER))) state->flag = PSYC_RENDER_NEED_LENGTH; else state->flag = PSYC_RENDER_NO_LENGTH; @@ -73,3 +115,4 @@ PSYC_RenderRC PSYC_renderBody(PSYC_RenderState* state, return PSYC_RENDER_SUCCESS; } +*/ diff --git a/src/variable.c b/src/variable.c index 3754136..6048d36 100644 --- a/src/variable.c +++ b/src/variable.c @@ -1,28 +1,27 @@ #include #include -const PSYC_Array PSYC_routingVars[] = /// Routing variables in alphabetical order. +/// Routing variables in alphabetical order. +const PSYC_String PSYC_routingVars[] = { - {17, "_amount_fragments"}, - { 8, "_context"}, -// { 6, "_count"}, // older PSYC - { 8, "_counter"}, // the name for this is supposed to be _count, not _counter - { 9, "_fragment"}, -// { 7, "_length"}, // older PSYC - { 7, "_source"}, - PSYC_C2ARRAY("_source_identification"), -// {22, "_source_identification"}, - PSYC_C2ARRAY("_source_relay"), -// {13, "_source_relay"}, - {19, "_source_relay_relay"}, // until you have a better idea.. is this really in use? - { 4, "_tag"}, - {10, "_tag_relay"}, -// {10, "_tag_reply"}, // older PSYC - { 7, "_target"}, - {15, "_target_forward"}, - {13, "_target_relay"}, -// {19, "_understand_modules"}, // older PSYC -// {14, "_using_modules"}, // older PSYC + PSYC_C2STR("_amount_fragments"), + PSYC_C2STR("_context"), + //PSYC_C2STR("_count"), // older PSYC + PSYC_C2STR("_counter"), // the name for this is supposed to be _count, not _counter + PSYC_C2STR("_fragment"), + //PSYC_C2STR("_length"), // older PSYC + PSYC_C2STR("_source"), + PSYC_C2STR("_source_identification"), + PSYC_C2STR("_source_relay"), + PSYC_C2STR("_source_relay_relay"), // until you have a better idea.. is this really in use? + PSYC_C2STR("_tag"), + PSYC_C2STR("_tag_relay"), + //PSYC_C2STR("_tag_reply"), // older PSYC + PSYC_C2STR("_target"), + PSYC_C2STR("_target_forward"), + PSYC_C2STR("_target_relay"), + //PSYC_C2STR(19, "_understand_modules"), // older PSYC + //PSYC_C2STR(14, "_using_modules"), // older PSYC }; const size_t PSYC_routingVarsNum = sizeof(PSYC_routingVars) / sizeof(*PSYC_routingVars); diff --git a/test/Makefile b/test/Makefile index 2cd792c..459d777 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,6 +1,6 @@ CFLAGS=-I../include -DDEBUG -g -O0 -Wall LDFLAGS=-L../src -LOADLIBES=-lpsyc +LOADLIBES=-lpsyc -lm TARGETS=testParser testMatch testRender isRoutingVar all: $(TARGETS) diff --git a/test/isRoutingVar.c b/test/isRoutingVar.c index e744b95..10121b2 100644 --- a/test/isRoutingVar.c +++ b/test/isRoutingVar.c @@ -5,7 +5,7 @@ int main(int argc, char** argv) { - char* vars[] = + const char* vars[] = { "_source", "_source_relay", @@ -19,6 +19,7 @@ int main(int argc, char** argv) int i; for (i = 0; i < sizeof(vars) / sizeof(*vars); i++) { + printf(">> %s: %ld %ld\n", vars[i], sizeof(vars[i]), sizeof(*vars[i])); printf("%s: %d\n", vars[i], PSYC_isRoutingVar(vars[i], strlen(vars[i]))); } diff --git a/test/testParser.c b/test/testParser.c index de6b584..83792ce 100644 --- a/test/testParser.c +++ b/test/testParser.c @@ -8,7 +8,7 @@ int main(int argc, char** argv) { int index, ret; char buffer[2048], oper; - PSYC_Array name, value, elem; + PSYC_String name, value, elem; PSYC_ParseState state; PSYC_ParseListState listState; @@ -22,7 +22,7 @@ int main(int argc, char** argv) write(1, ">> PARSE\n", 9); PSYC_initParseState(&state); - PSYC_nextParseBuffer(&state, PSYC_createArray(buffer, index)); + PSYC_nextParseBuffer(&state, PSYC_newString(buffer, index)); // try parsing that now while ((ret = PSYC_parse(&state, &oper, &name, &value))) diff --git a/test/testRender.c b/test/testRender.c index e3900ae..b79a53b 100644 --- a/test/testRender.c +++ b/test/testRender.c @@ -19,13 +19,13 @@ int writePresence(const char *avail, int availlen, const char *desc, int desclen } // if (PSYC_initBuffer(pb, WHATEVER)) die("PSYC_initBuffer hates me"); - (void) PSYC_renderVar(pb, "_context", 0, + (void) PSYC_renderModifier(pb, "_context", 0, myUNI, sizeof(myUNI), PSYC_RENDER_ROUTING, 0); // the first call to PSYC_renderHeader() without PSYC_RENDER_ROUTING adds the // extra newline to the buffer. later vars with PSYC_RENDER_ROUTING cause an error. - (void) PSYC_renderVar(pb, "_degree_availability", 0, avail, availlen, 0, C_GLYPH_OPERATOR_ASSIGN); - (void) PSYC_renderVar(pb, "_description_presence", 0, desc, desclen, 0, C_GLYPH_OPERATOR_ASSIGN); + (void) PSYC_renderModifier(pb, "_degree_availability", 0, avail, availlen, 0, C_GLYPH_OPERATOR_ASSIGN); + (void) PSYC_renderModifier(pb, "_description_presence", 0, desc, desclen, 0, C_GLYPH_OPERATOR_ASSIGN); // presence is to be assigned permanently in distributed state (void) PSYC_renderBody(pb, "_notice_presence", 0, From a7c928f4e547b7e1ea61d4ab8d3d1d5056defbb6 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 25 Apr 2011 14:39:58 +0200 Subject: [PATCH 081/378] fixed modifier array --- include/psyc.h | 4 ++-- src/psyc.c | 12 ++++++------ src/render.c | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/include/psyc.h b/include/psyc.h index 860d7d4..5b6e3ec 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -124,8 +124,8 @@ typedef struct typedef struct { - size_t length; - PSYC_Modifier *ptr; + size_t lines; + PSYC_Modifier **modifiers; } PSYC_ModifierArray; /* intermediate struct for a PSYC packet */ diff --git a/src/psyc.c b/src/psyc.c index 6aec5e1..547e1d9 100644 --- a/src/psyc.c +++ b/src/psyc.c @@ -71,12 +71,12 @@ inline PSYC_Packet PSYC_newPacket(PSYC_ModifierArray *routing, } // calculate routing header length - for (i = 0; i < routing->length; i++) - p.routingLength += PSYC_getModifierLength(&routing->ptr[i]); + for (i = 0; i < routing->lines; i++) + p.routingLength += PSYC_getModifierLength(routing->modifiers[i]); // calculate entity header length - for (i = 0; i < entity->length; i++) - p.contentLength += PSYC_getModifierLength(&routing->ptr[i]); + for (i = 0; i < entity->lines; i++) + p.contentLength += PSYC_getModifierLength(routing->modifiers[i]); // add length of method, data & delimiter p.contentLength += method->length + 1 + data->length; // method \n data @@ -95,8 +95,8 @@ inline PSYC_Packet PSYC_newPacket2(PSYC_Modifier **routing, size_t routinglen, const char *data, size_t datalen, PSYC_PacketFlag flag) { - PSYC_ModifierArray r = {routinglen, *routing}; - PSYC_ModifierArray e = {entitylen, *entity}; + PSYC_ModifierArray r = {routinglen, routing}; + PSYC_ModifierArray e = {entitylen, entity}; PSYC_String m = {methodlen, method}; PSYC_String d = {datalen, data}; diff --git a/src/render.c b/src/render.c index bcf9d7f..44234bb 100644 --- a/src/render.c +++ b/src/render.c @@ -27,16 +27,16 @@ PSYC_RenderRC PSYC_render(PSYC_Packet *packet, char *buffer, size_t buflen) if (packet->length > buflen) return PSYC_RENDER_ERROR; - for (i = 0; i < packet->routing.length; i++) - cur += PSYC_renderModifier(&packet->routing.ptr[i], buffer + cur); + for (i = 0; i < packet->routing.lines; i++) + cur += PSYC_renderModifier(packet->routing.modifiers[i], buffer + cur); if (packet->flag == PSYC_PACKET_NEED_LENGTH) cur += sprintf(buffer + cur, "%ld", packet->contentLength); memcpy(buffer + cur++, "\n", 1); - for (i = 0; i < packet->entity.length; i++) - cur += PSYC_renderModifier(&packet->entity.ptr[i], buffer + cur); + for (i = 0; i < packet->entity.lines; i++) + cur += PSYC_renderModifier(packet->entity.modifiers[i], buffer + cur); memcpy(buffer + cur, PSYC_C2ARG(PSYC_PACKET_DELIMITER)); From a5e7b7f2817d0d0462bd3b90de6ba55d996176bd Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 25 Apr 2011 14:46:14 +0200 Subject: [PATCH 082/378] - --- src/render.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/render.c b/src/render.c index 44234bb..51d888f 100644 --- a/src/render.c +++ b/src/render.c @@ -10,12 +10,12 @@ inline int PSYC_renderModifier(PSYC_Modifier *m, char *buffer) cur += m->name.length; if (m->flag == PSYC_MODIFIER_NEED_LENGTH) { - memcpy(buffer + cur++, " ", 1); + buffer[cur++] = ' '; cur += sprintf(buffer + cur, "%ld", m->value.length); } memcpy(buffer + cur, m->value.ptr, m->value.length); cur += m->value.length; - memcpy(buffer + cur++, "\n", 1); + buffer[cur++] = '\n'; return cur; } @@ -33,7 +33,7 @@ PSYC_RenderRC PSYC_render(PSYC_Packet *packet, char *buffer, size_t buflen) if (packet->flag == PSYC_PACKET_NEED_LENGTH) cur += sprintf(buffer + cur, "%ld", packet->contentLength); - memcpy(buffer + cur++, "\n", 1); + buffer[cur++] = '\n'; for (i = 0; i < packet->entity.lines; i++) cur += PSYC_renderModifier(packet->entity.modifiers[i], buffer + cur); From 9946307d00fa217119cf1009fa8e3ebd7df675f9 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Mon, 25 Apr 2011 14:47:16 +0200 Subject: [PATCH 083/378] did you actually mean PSYC_MODIFIER_NEED_LENGTH ? --- src/match.c | 5 +++++ src/psyc.c | 6 +++--- src/render.c | 8 ++++---- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/match.c b/src/match.c index 9cd79d0..4e7e3ff 100644 --- a/src/match.c +++ b/src/match.c @@ -2,6 +2,11 @@ int PSYC_inherits(char* sho, size_t slen, char* lon, size_t llen) { + + // this allows to pass zero-terminated strings instead of providing + // the length.. but we would be faster here if we expected the callee + // to always use the PSYC_C2ARG() macro instead. additionally, the + // empty string would then be fully supported (in case you want that) if (!slen) slen = strlen(sho); if (!llen) llen = strlen(lon); diff --git a/src/psyc.c b/src/psyc.c index 6aec5e1..a3942bf 100644 --- a/src/psyc.c +++ b/src/psyc.c @@ -17,11 +17,11 @@ inline PSYC_Modifier PSYC_newModifier(char oper, PSYC_String *name, PSYC_String if (flag == PSYC_MODIFIER_CHECK_LENGTH) // find out if it needs a length { if (value->length > PSYC_MODIFIER_SIZE_THRESHOLD) - m.flag = PSYC_PACKET_NEED_LENGTH; + m.flag = PSYC_MODIFIER_NEED_LENGTH; else if (memchr(value->ptr, (int)'\n', value->length)) - m.flag = PSYC_PACKET_NEED_LENGTH; + m.flag = PSYC_MODIFIER_NEED_LENGTH; else - m.flag = PSYC_PACKET_NO_LENGTH; + m.flag = PSYC_MODIFIER_NO_LENGTH; } return m; diff --git a/src/render.c b/src/render.c index bcf9d7f..4a148f4 100644 --- a/src/render.c +++ b/src/render.c @@ -5,17 +5,17 @@ inline int PSYC_renderModifier(PSYC_Modifier *m, char *buffer) { int cur = 0; - memcpy(buffer + cur++, &m->oper, 1); + buffer[cur++] = m->oper; memcpy(buffer + cur, m->name.ptr, m->name.length); cur += m->name.length; if (m->flag == PSYC_MODIFIER_NEED_LENGTH) { - memcpy(buffer + cur++, " ", 1); + buffer[cur++] = ' '; cur += sprintf(buffer + cur, "%ld", m->value.length); } memcpy(buffer + cur, m->value.ptr, m->value.length); cur += m->value.length; - memcpy(buffer + cur++, "\n", 1); + buffer[cur++] = '\n'; return cur; } @@ -33,7 +33,7 @@ PSYC_RenderRC PSYC_render(PSYC_Packet *packet, char *buffer, size_t buflen) if (packet->flag == PSYC_PACKET_NEED_LENGTH) cur += sprintf(buffer + cur, "%ld", packet->contentLength); - memcpy(buffer + cur++, "\n", 1); + buffer[cur++] = '\n'; for (i = 0; i < packet->entity.length; i++) cur += PSYC_renderModifier(&packet->entity.ptr[i], buffer + cur); From 8d47fdee400307d99c62e245c2ac782bc3e5d0f7 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Mon, 25 Apr 2011 16:11:47 +0200 Subject: [PATCH 084/378] don't use sprintf for rendering numbers --- include/psyc/lib.h | 4 +++ src/Makefile | 7 ++-- src/itoa.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++ src/render.c | 9 +++-- 4 files changed, 100 insertions(+), 5 deletions(-) create mode 100644 src/itoa.c diff --git a/include/psyc/lib.h b/include/psyc/lib.h index 1847ef5..6708e4c 100644 --- a/include/psyc/lib.h +++ b/include/psyc/lib.h @@ -15,4 +15,8 @@ void * memmem(const void *l, size_t l_len, const void *s, size_t s_len); #endif +#if !defined(_GNU_SOURCE) && !defined(__FBSDID) +int itoa(int number, char* out, int base); +#endif + #endif // PSYC_LIB_H diff --git a/src/Makefile b/src/Makefile index 86c6c09..69625c8 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,8 +2,8 @@ CFLAGS=-I../include -DDEBUG=2 -DPSYC_COMPILE_LIBRARY -g -O0 -Wall CC=cc # CC=clang -S=psyc.c parser.c match.c render.c memmem.c variable.c -O=psyc.o parser.o match.o render.o memmem.o variable.o +S=psyc.c parser.c match.c render.c memmem.c itoa.c variable.c +O=psyc.o parser.o match.o render.o memmem.o itoa.o variable.o default: @/bin/echo -e "Usage:\n\tmake diet - compile with diet libc\n\tmake lib - compile with normal gnu libc" @@ -19,6 +19,9 @@ lib: $S match: match.c ${CC} -o $@ -DDEBUG=4 -DCMDTOOL -DTEST $< +itoa: itoa.c + ${CC} -o $@ -DDEBUG=4 -DCMDTOOL -DTEST -O0 $< + it: match clean: diff --git a/src/itoa.c b/src/itoa.c new file mode 100644 index 0000000..1292d9b --- /dev/null +++ b/src/itoa.c @@ -0,0 +1,85 @@ +#define ALPHANUMS "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" + +/** converts an integer to a string, using a base of 10 by default. + * + * if you NULL out the output buffer it will return the expected + * output string length anyway. + */ +int itoa(int number, char* out, int base) { + int t, count; + char *p, *q; + char c; + + p = q = out; + if (base < 2 || base > 36) base = 10; + + do { + t = number; + number /= base; + if (out) *p = ALPHANUMS[t+35 - number*base]; + p++; + } while (number); + + if (t < 0) { + if (out) *p = '-'; + p++; + } + count = p-out; + if (out) { + *p-- = '\0'; + while(q < p) { + c = *p; + *p-- = *q; + *q++ = c; + } + } + return count; +} + +/* This little test program shows that itoa() is roughly 3 times faster + * than sprintf --lynX + */ +#ifdef CMDTOOL + +#include +#include +#include + +int main(int argc, char **argv) { + char out[4404]; + int in[44]; + int c, i, j; + + if (argc < 3 || argc > sizeof(in)) { + printf("Usage: %s +\n\nExample: %s 999999 123 234 345 -49 -21892\n", argv[0], argv[0]); + return -1; + } + for (j=argc-1; j; j--) { +// printf("Looking at arg #%d: %s\n", j, argv[j]); + in[j] = atoi(argv[j]); +// printf("Got %d: %d\n", j, in[j]); + } + for (i=in[1]; i; i--) { + c = 0; + for (j=argc-1; j>1; j--) { +# if 0 + // use good old sprintf + c += sprintf(&out[c], " %d", in[j]); +# else +# if 1 + // use the itoa implementation + out[c++] = ' '; + c += itoa(in[j], &out[c], 10); +# else + // just count the needed space + c += itoa(in[j], NULL, 10) + 1; +# endif +# endif + } + } + printf("%d times, %d count, buffer len: %d, buffer: %s\n", + in[1], c, strlen(out), ""); // out + return 0; +} + +#endif diff --git a/src/render.c b/src/render.c index e311bd7..195549f 100644 --- a/src/render.c +++ b/src/render.c @@ -11,7 +11,8 @@ inline int PSYC_renderModifier(PSYC_Modifier *m, char *buffer) if (m->flag == PSYC_MODIFIER_NEED_LENGTH) { buffer[cur++] = ' '; - cur += sprintf(buffer + cur, "%ld", m->value.length); +// cur += sprintf(buffer + cur, "%ld", m->value.length); + cur += itoa(m->value.length, buffer + cur, 10); } memcpy(buffer + cur, m->value.ptr, m->value.length); cur += m->value.length; @@ -30,8 +31,10 @@ PSYC_RenderRC PSYC_render(PSYC_Packet *packet, char *buffer, size_t buflen) for (i = 0; i < packet->routing.lines; i++) cur += PSYC_renderModifier(packet->routing.modifiers[i], buffer + cur); - if (packet->flag == PSYC_PACKET_NEED_LENGTH) - cur += sprintf(buffer + cur, "%ld", packet->contentLength); + if (packet->flag == PSYC_PACKET_NEED_LENGTH) { +// cur += sprintf(buffer + cur, "%ld", packet->contentLength); + cur += itoa(packet->contentLength, buffer + cur, 10); + } buffer[cur++] = '\n'; From 13991231322b4cfb6803f664fdc8807bb708faa9 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Mon, 25 Apr 2011 21:28:24 +0200 Subject: [PATCH 085/378] warning: declaration of 'index' shadows a global declaration --- test/testParser.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/testParser.c b/test/testParser.c index 83792ce..2e4fc7a 100644 --- a/test/testParser.c +++ b/test/testParser.c @@ -6,7 +6,7 @@ int main(int argc, char** argv) { - int index, ret; + int indx, ret; char buffer[2048], oper; PSYC_String name, value, elem; PSYC_ParseState state; @@ -15,14 +15,14 @@ int main(int argc, char** argv) int file = open(argv[1],O_RDONLY); if(file < 0) return -1; - index = read(file,(void*)buffer,sizeof(buffer)); + indx = read(file,(void*)buffer,sizeof(buffer)); write(1, ">> INPUT\n", 9); - write(1, buffer, index); + write(1, buffer, indx); write(1, ">> PARSE\n", 9); PSYC_initParseState(&state); - PSYC_nextParseBuffer(&state, PSYC_newString(buffer, index)); + PSYC_nextParseBuffer(&state, PSYC_newString(buffer, indx)); // try parsing that now while ((ret = PSYC_parse(&state, &oper, &name, &value))) From 4fbaf4ececbd8d83233c21d7b2ecf91d61555358 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 25 Apr 2011 21:57:03 +0200 Subject: [PATCH 086/378] fixes & test for rendering --- include/psyc.h | 6 +++--- include/psyc/lib.h | 2 ++ src/psyc.c | 25 ++++++++++++++----------- src/render.c | 29 ++++++++++++++++++++++------- src/variable.c | 4 ++-- test/testRender.c | 34 ++++++++++++++++++++++++++++++++-- 6 files changed, 75 insertions(+), 25 deletions(-) diff --git a/include/psyc.h b/include/psyc.h index 5b6e3ec..2243e40 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -125,7 +125,7 @@ typedef struct typedef struct { size_t lines; - PSYC_Modifier **modifiers; + PSYC_Modifier *modifiers; } PSYC_ModifierArray; /* intermediate struct for a PSYC packet */ @@ -154,8 +154,8 @@ inline PSYC_Packet PSYC_newPacket(PSYC_ModifierArray *routing, PSYC_String *method, PSYC_String *data, PSYC_PacketFlag flag); -inline PSYC_Packet PSYC_newPacket2(PSYC_Modifier **routing, size_t routinglen, - PSYC_Modifier **entity, size_t entitylen, +inline PSYC_Packet PSYC_newPacket2(PSYC_Modifier *routing, size_t routinglen, + PSYC_Modifier *entity, size_t entitylen, const char *method, size_t methodlen, const char *data, size_t datalen, PSYC_PacketFlag flag); diff --git a/include/psyc/lib.h b/include/psyc/lib.h index 6708e4c..5e22a2c 100644 --- a/include/psyc/lib.h +++ b/include/psyc/lib.h @@ -11,6 +11,8 @@ #define unless(COND) if (!(COND)) #define until(COND) while (!(COND)) +#define PSYC_NUM_ELEM(a) (sizeof(a) / sizeof(*(a))) + #if !defined(_GNU_SOURCE) && !defined(__FBSDID) void * memmem(const void *l, size_t l_len, const void *s, size_t s_len); #endif diff --git a/src/psyc.c b/src/psyc.c index 0274c39..de6bd02 100644 --- a/src/psyc.c +++ b/src/psyc.c @@ -3,7 +3,7 @@ #include -inline PSYC_String PSYC_newString (const char *str, size_t strlen) +inline PSYC_String PSYC_newString(const char *str, size_t strlen) { PSYC_String s = {strlen, str}; return s; @@ -40,7 +40,7 @@ inline PSYC_Modifier PSYC_newModifier2(char oper, inline size_t PSYC_getModifierLength(PSYC_Modifier *m) { - size_t length = + size_t length = 1 + // oper m->name.length + 1 + // name\t m->value.length + 1; // value\n @@ -70,27 +70,30 @@ inline PSYC_Packet PSYC_newPacket(PSYC_ModifierArray *routing, p.flag = PSYC_PACKET_NO_LENGTH; } - // calculate routing header length + // add routing header length for (i = 0; i < routing->lines; i++) - p.routingLength += PSYC_getModifierLength(routing->modifiers[i]); + p.routingLength += PSYC_getModifierLength(&routing->modifiers[i]); - // calculate entity header length + // add entity header length for (i = 0; i < entity->lines; i++) - p.contentLength += PSYC_getModifierLength(routing->modifiers[i]); + p.contentLength += PSYC_getModifierLength(&entity->modifiers[i]); // add length of method, data & delimiter - p.contentLength += method->length + 1 + data->length; // method \n data + if (method->length) + p.contentLength += method->length + 1; // method\n + if (data->length) + p.contentLength += data->length + 1; // data\n - // set total length: routing-header \n content \n|\n - p.length = p.routingLength + 1 + p.contentLength + sizeof(PSYC_PACKET_DELIMITER) - 1; + // set total length: routing-header \n content |\n + p.length = p.routingLength + 1 + p.contentLength + sizeof(PSYC_PACKET_DELIMITER) - 2; if (flag == PSYC_PACKET_NEED_LENGTH) // add length of length if needed p.length += log10((double)data->length) + 1; return p; } -inline PSYC_Packet PSYC_newPacket2(PSYC_Modifier **routing, size_t routinglen, - PSYC_Modifier **entity, size_t entitylen, +inline PSYC_Packet PSYC_newPacket2(PSYC_Modifier *routing, size_t routinglen, + PSYC_Modifier *entity, size_t entitylen, const char *method, size_t methodlen, const char *data, size_t datalen, PSYC_PacketFlag flag) diff --git a/src/render.c b/src/render.c index 195549f..ac31c70 100644 --- a/src/render.c +++ b/src/render.c @@ -3,7 +3,7 @@ inline int PSYC_renderModifier(PSYC_Modifier *m, char *buffer) { - int cur = 0; + size_t cur = 0; buffer[cur++] = m->oper; memcpy(buffer + cur, m->name.ptr, m->name.length); @@ -11,9 +11,11 @@ inline int PSYC_renderModifier(PSYC_Modifier *m, char *buffer) if (m->flag == PSYC_MODIFIER_NEED_LENGTH) { buffer[cur++] = ' '; -// cur += sprintf(buffer + cur, "%ld", m->value.length); + //cur += sprintf(buffer + cur, "%ld", m->value.length); cur += itoa(m->value.length, buffer + cur, 10); } + + buffer[cur++] = '\t'; memcpy(buffer + cur, m->value.ptr, m->value.length); cur += m->value.length; buffer[cur++] = '\n'; @@ -23,26 +25,39 @@ inline int PSYC_renderModifier(PSYC_Modifier *m, char *buffer) PSYC_RenderRC PSYC_render(PSYC_Packet *packet, char *buffer, size_t buflen) { - size_t cur, i; + size_t i, cur = 0; if (packet->length > buflen) return PSYC_RENDER_ERROR; for (i = 0; i < packet->routing.lines; i++) - cur += PSYC_renderModifier(packet->routing.modifiers[i], buffer + cur); + cur += PSYC_renderModifier(&packet->routing.modifiers[i], buffer + cur); if (packet->flag == PSYC_PACKET_NEED_LENGTH) { -// cur += sprintf(buffer + cur, "%ld", packet->contentLength); + //cur += sprintf(buffer + cur, "%ld", packet->contentLength); cur += itoa(packet->contentLength, buffer + cur, 10); } buffer[cur++] = '\n'; for (i = 0; i < packet->entity.lines; i++) - cur += PSYC_renderModifier(packet->entity.modifiers[i], buffer + cur); + cur += PSYC_renderModifier(&packet->entity.modifiers[i], buffer + cur); - memcpy(buffer + cur, PSYC_C2ARG(PSYC_PACKET_DELIMITER)); + if (packet->method.length) + { + memcpy(buffer + cur, packet->method.ptr, packet->method.length); + cur += packet->method.length; + buffer[cur++] = '\n'; + } + if (packet->data.length) + { + memcpy(buffer + cur, packet->data.ptr, packet->method.length); + cur += packet->data.length; + buffer[cur++] = '\n'; + } + + memcpy(buffer + cur, PSYC_PACKET_DELIMITER + 1, 2); return PSYC_RENDER_SUCCESS; } diff --git a/src/variable.c b/src/variable.c index 6048d36..dc2b15d 100644 --- a/src/variable.c +++ b/src/variable.c @@ -29,7 +29,7 @@ const size_t PSYC_routingVarsNum = sizeof(PSYC_routingVars) / sizeof(*PSYC_routi /** * Get the type of variable name. */ -PSYC_Bool PSYC_isRoutingVar(const char* name, size_t len) +PSYC_Bool PSYC_isRoutingVar(const char *name, size_t len) { size_t cursor = 1; int8_t matching[PSYC_routingVarsNum]; // indexes of matching vars @@ -68,7 +68,7 @@ PSYC_Bool PSYC_isRoutingVar(const char* name, size_t len) /** * Get the type of variable name. */ -PSYC_Type PSYC_getVarType(char* name, size_t len) +PSYC_Type PSYC_getVarType(char *name, size_t len) { return PSYC_TYPE_UNKNOWN; } diff --git a/test/testRender.c b/test/testRender.c index b79a53b..0b9223f 100644 --- a/test/testRender.c +++ b/test/testRender.c @@ -1,11 +1,40 @@ #include +#include #include "../include/psyc/lib.h" #include "../include/psyc/render.h" #define myUNI "psyc://10.100.1000/~ludwig" /* example renderer generating a presence packet */ -int writePresence(const char *avail, int availlen, const char *desc, int desclen) { +int writePresence(const char *avail, int availlen, const char *desc, int desclen) +{ + PSYC_Modifier routing[] = { + PSYC_newModifier2(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_source"), PSYC_C2ARG(myUNI), + PSYC_MODIFIER_ROUTING), + PSYC_newModifier2(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_context"), PSYC_C2ARG(myUNI), + PSYC_MODIFIER_CHECK_LENGTH), + }; + + PSYC_Modifier entity[] = { + // presence is to be assigned permanently in distributed state + PSYC_newModifier2(C_GLYPH_OPERATOR_ASSIGN, PSYC_C2ARG("_degree_availability"), + avail, availlen, PSYC_PACKET_CHECK_LENGTH), + PSYC_newModifier2(C_GLYPH_OPERATOR_ASSIGN, PSYC_C2ARG("_description_presence"), + desc, desclen, PSYC_PACKET_CHECK_LENGTH), + }; + + PSYC_Packet packet = PSYC_newPacket2(routing, PSYC_NUM_ELEM(routing), + entity, PSYC_NUM_ELEM(entity), + PSYC_C2ARG("_notice_presence"), + NULL, 0, + //PSYC_C2ARG("foobar"), + PSYC_PACKET_CHECK_LENGTH); + + char buffer[512]; + PSYC_render(&packet, buffer, sizeof(buffer)); + write(0, buffer, packet.length); + +/* PSYC_RenderState *pb; // a chunk of mem will host both struct and buf1 // char *t; // unsigned int l; @@ -33,10 +62,11 @@ int writePresence(const char *avail, int availlen, const char *desc, int desclen // (void) PSYC_doneRender(pb, &t, &l); // write(stdout, t, l); free(pb); +*/ return 0; } int main() { - return writePresence("_here", 0, "I'm omnipresent right now", 0); + return writePresence(PSYC_C2ARG("_here"), PSYC_C2ARG("I'm omnipresent right now")); } From bfceeb59c8a2b9766b60e330ba9481fcf8e025af Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 25 Apr 2011 22:01:13 +0200 Subject: [PATCH 087/378] - --- test/testRender.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/testRender.c b/test/testRender.c index 0b9223f..a2f87a1 100644 --- a/test/testRender.c +++ b/test/testRender.c @@ -24,10 +24,10 @@ int writePresence(const char *avail, int availlen, const char *desc, int desclen }; PSYC_Packet packet = PSYC_newPacket2(routing, PSYC_NUM_ELEM(routing), - entity, PSYC_NUM_ELEM(entity), + entity, PSYC_NUM_ELEM(entity), PSYC_C2ARG("_notice_presence"), - NULL, 0, - //PSYC_C2ARG("foobar"), + NULL, 0, + //PSYC_C2ARG("foobar"), PSYC_PACKET_CHECK_LENGTH); char buffer[512]; From d1d4e3c516cf11726ce0e1282e829321120ad2e6 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Mon, 25 Apr 2011 22:02:24 +0200 Subject: [PATCH 088/378] used by psyclpc's configure script --- include/psyc.h | 2 ++ src/psyc.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/include/psyc.h b/include/psyc.h index 2243e40..7235696 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -141,6 +141,8 @@ typedef struct PSYC_PacketFlag flag; } PSYC_Packet; +inline int PSYC_version(); + inline PSYC_Modifier PSYC_newModifier(char oper, PSYC_String *name, PSYC_String *value, PSYC_ModifierFlag flag); diff --git a/src/psyc.c b/src/psyc.c index de6bd02..8317ea6 100644 --- a/src/psyc.c +++ b/src/psyc.c @@ -3,6 +3,8 @@ #include +int PSYC_version() { return 1; } + inline PSYC_String PSYC_newString(const char *str, size_t strlen) { PSYC_String s = {strlen, str}; From a253f96283dc52de7f00921125efc07cc4c699b5 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 25 Apr 2011 22:31:21 +0200 Subject: [PATCH 089/378] added assert for render, removed LPC assert --- include/psyc/debug.h | 16 +--------------- include/psyc/lib.h | 1 + src/render.c | 3 +++ test/testRender.c | 2 +- 4 files changed, 6 insertions(+), 16 deletions(-) diff --git a/include/psyc/debug.h b/include/psyc/debug.h index 6ddec4c..986dfc0 100644 --- a/include/psyc/debug.h +++ b/include/psyc/debug.h @@ -3,7 +3,7 @@ #ifdef DEBUG # include -# define PP(args) printf args; +# define PP(args) printf(args); #else # define PP(args) #endif @@ -82,18 +82,4 @@ # define P4(MSG) #endif -// ASSERT() unused as yet -#if DEBUG > 0 -# ifdef STRICT -# define ASSERT(NAME,COND,VALUE) { unless (COND) { \ - PP(("Assertion %s failed in %s: %s\n", NAME, ME, VALUE)); \ - raise_error("Assertion failed (strict mode).\n"); } } -# else -# define ASSERT(NAME,COND,VALUE) { unless (COND) \ - PP(("Assertion %s failed in %s: %s\n", NAME, ME, VALUE)); } -# endif -#else -# define ASSERT(NAME,CONDITION,VALUE) -#endif - #endif // DEBUG_H diff --git a/include/psyc/lib.h b/include/psyc/lib.h index 5e22a2c..d04aae2 100644 --- a/include/psyc/lib.h +++ b/include/psyc/lib.h @@ -6,6 +6,7 @@ #include "../psyc.h" #include "./debug.h" #include +#include /* perlisms for readability */ #define unless(COND) if (!(COND)) diff --git a/src/render.c b/src/render.c index ac31c70..7da3114 100644 --- a/src/render.c +++ b/src/render.c @@ -58,6 +58,9 @@ PSYC_RenderRC PSYC_render(PSYC_Packet *packet, char *buffer, size_t buflen) } memcpy(buffer + cur, PSYC_PACKET_DELIMITER + 1, 2); + cur += 2; + + assert(cur == packet->length); return PSYC_RENDER_SUCCESS; } diff --git a/test/testRender.c b/test/testRender.c index a2f87a1..657f249 100644 --- a/test/testRender.c +++ b/test/testRender.c @@ -12,7 +12,7 @@ int writePresence(const char *avail, int availlen, const char *desc, int desclen PSYC_newModifier2(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_source"), PSYC_C2ARG(myUNI), PSYC_MODIFIER_ROUTING), PSYC_newModifier2(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_context"), PSYC_C2ARG(myUNI), - PSYC_MODIFIER_CHECK_LENGTH), + PSYC_MODIFIER_ROUTING), }; PSYC_Modifier entity[] = { From 677d05b7840b7b0ed438857a651ea37e2d859dbb Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 25 Apr 2011 22:34:08 +0200 Subject: [PATCH 090/378] printf --- include/psyc/debug.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/psyc/debug.h b/include/psyc/debug.h index 986dfc0..073b280 100644 --- a/include/psyc/debug.h +++ b/include/psyc/debug.h @@ -3,7 +3,7 @@ #ifdef DEBUG # include -# define PP(args) printf(args); +# define PP(args) printf args; #else # define PP(args) #endif From da7f39edc320a5553e846bedc28ecfc9014b653c Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Mon, 25 Apr 2011 22:38:42 +0200 Subject: [PATCH 091/378] renamed: psyc.c -> packet.c --- src/Makefile | 4 ++-- src/misc.c | 2 ++ src/{psyc.c => packet.c} | 2 -- 3 files changed, 4 insertions(+), 4 deletions(-) create mode 100644 src/misc.c rename src/{psyc.c => packet.c} (99%) diff --git a/src/Makefile b/src/Makefile index 69625c8..7e464c2 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,8 +2,8 @@ CFLAGS=-I../include -DDEBUG=2 -DPSYC_COMPILE_LIBRARY -g -O0 -Wall CC=cc # CC=clang -S=psyc.c parser.c match.c render.c memmem.c itoa.c variable.c -O=psyc.o parser.o match.o render.o memmem.o itoa.o variable.o +S=packet.c misc.c parser.c match.c render.c memmem.c itoa.c variable.c +O=packet.o misc.o parser.o match.o render.o memmem.o itoa.o variable.o default: @/bin/echo -e "Usage:\n\tmake diet - compile with diet libc\n\tmake lib - compile with normal gnu libc" diff --git a/src/misc.c b/src/misc.c new file mode 100644 index 0000000..27c39d2 --- /dev/null +++ b/src/misc.c @@ -0,0 +1,2 @@ +int PSYC_version() { return 1; } + diff --git a/src/psyc.c b/src/packet.c similarity index 99% rename from src/psyc.c rename to src/packet.c index 8317ea6..de6bd02 100644 --- a/src/psyc.c +++ b/src/packet.c @@ -3,8 +3,6 @@ #include -int PSYC_version() { return 1; } - inline PSYC_String PSYC_newString(const char *str, size_t strlen) { PSYC_String s = {strlen, str}; From 156b57c2e9db84853782323b1687785d320b980b Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 25 Apr 2011 22:47:24 +0200 Subject: [PATCH 092/378] + --- src/packet.c | 4 ++-- src/render.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/packet.c b/src/packet.c index de6bd02..fa9c410 100644 --- a/src/packet.c +++ b/src/packet.c @@ -85,9 +85,9 @@ inline PSYC_Packet PSYC_newPacket(PSYC_ModifierArray *routing, p.contentLength += data->length + 1; // data\n // set total length: routing-header \n content |\n - p.length = p.routingLength + 1 + p.contentLength + sizeof(PSYC_PACKET_DELIMITER) - 2; + p.length = p.routingLength + 1 + p.contentLength + sizeof(PSYC_PACKET_DELIMITER) - 2; if (flag == PSYC_PACKET_NEED_LENGTH) // add length of length if needed - p.length += log10((double)data->length) + 1; + p.length += log10((double)data->length) + 1; return p; } diff --git a/src/render.c b/src/render.c index 7da3114..da66900 100644 --- a/src/render.c +++ b/src/render.c @@ -1,7 +1,7 @@ #include "psyc/lib.h" #include "psyc/render.h" -inline int PSYC_renderModifier(PSYC_Modifier *m, char *buffer) +inline size_t PSYC_renderModifier(PSYC_Modifier *m, char *buffer) { size_t cur = 0; From 4ceb768639437c79fb98571c78bba4482d7de485 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 25 Apr 2011 22:57:08 +0200 Subject: [PATCH 093/378] render: delim --- src/render.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/render.c b/src/render.c index da66900..8dfa088 100644 --- a/src/render.c +++ b/src/render.c @@ -57,8 +57,8 @@ PSYC_RenderRC PSYC_render(PSYC_Packet *packet, char *buffer, size_t buflen) buffer[cur++] = '\n'; } - memcpy(buffer + cur, PSYC_PACKET_DELIMITER + 1, 2); - cur += 2; + buffer[cur++] = C_GLYPH_PACKET_DELIMITER; + buffer[cur++] = '\n'; assert(cur == packet->length); return PSYC_RENDER_SUCCESS; From 0f9f1bdc94e5762f58637f047b4855ad32442311 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 25 Apr 2011 23:14:22 +0200 Subject: [PATCH 094/378] render doc --- include/psyc/parser.h | 2 +- include/psyc/render.h | 46 ++++++++++++++++++++++++++++++++----------- src/render.c | 14 +++++++++---- 3 files changed, 46 insertions(+), 16 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index 7af13f1..e8c46b5 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -1,6 +1,6 @@ /** * @file psyc/parser.h - * @brief Interface for various psyc parser functions. + * @brief Interface for various PSYC parser functions. * * All parsing functions and the definitions they use are * defined in this file. diff --git a/include/psyc/render.h b/include/psyc/render.h index c70d108..b900ad7 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -1,8 +1,37 @@ #ifndef PSYC_RENDER_H # define PSYC_RENDER_H -#include "syntax.h" +/** + * @file psyc/render.h + * @brief Interface for PSYC packet rendering. + * + * All rendering functions and the definitions they use are + * defined in this file. + */ +/** + * @defgroup rendering Rendering Functions + * + * This module contains all rendering functions. + * @{ + */ + +/** + * Return codes for PSYC_render. + */ +typedef enum +{ + //PSYC_RENDER_ERROR_ROUTING = -2, + PSYC_RENDER_ERROR = -1, + PSYC_RENDER_SUCCESS = 0, +} PSYC_RenderRC; + +/** + * Render a PSYC packet into a buffer. + */ +PSYC_RenderRC PSYC_render(PSYC_Packet *packet, char *buffer, size_t buflen); + +/* typedef enum { PSYC_RENDER_CHECK_LENGTH = 0, @@ -10,17 +39,12 @@ typedef enum PSYC_RENDER_NO_LENGTH = 2, PSYC_RENDER_ROUTING = 3, } PSYC_RenderFlag; - -typedef enum -{ - PSYC_RENDER_ERROR_ROUTING = -2, - PSYC_RENDER_ERROR = -1, - PSYC_RENDER_SUCCESS = 0, -} PSYC_RenderRC; +*/ /** * Struct for keeping render state. */ +/* typedef struct { PSYC_RenderFlag flag; ///< flags for the renderer @@ -31,9 +55,7 @@ typedef struct size_t length; ///< how big is the buffer we allocated char buffer[]; ///< OMG a C99 feature! variable size buffer! } PSYC_RenderState; - -PSYC_RenderRC PSYC_render(PSYC_Packet *packet, char *buffer, size_t buflen); - +*/ /** * Initiates the state struct. * @@ -52,3 +74,5 @@ int PSYC_renderBody(PSYC_RenderState* render, const char* data, size_t dlength); */ #endif // PSYC_RENDER_H + +/** @} */ // end of rendering group diff --git a/src/render.c b/src/render.c index 8dfa088..35350f5 100644 --- a/src/render.c +++ b/src/render.c @@ -1,5 +1,6 @@ #include "psyc/lib.h" #include "psyc/render.h" +#include "psyc/syntax.h" inline size_t PSYC_renderModifier(PSYC_Modifier *m, char *buffer) { @@ -28,38 +29,43 @@ PSYC_RenderRC PSYC_render(PSYC_Packet *packet, char *buffer, size_t buflen) size_t i, cur = 0; if (packet->length > buflen) - return PSYC_RENDER_ERROR; + return PSYC_RENDER_ERROR; // return error if packet doesn't fit in buffer + // render routing modifiers for (i = 0; i < packet->routing.lines; i++) cur += PSYC_renderModifier(&packet->routing.modifiers[i], buffer + cur); + // add length if needed if (packet->flag == PSYC_PACKET_NEED_LENGTH) { //cur += sprintf(buffer + cur, "%ld", packet->contentLength); cur += itoa(packet->contentLength, buffer + cur, 10); } - buffer[cur++] = '\n'; + buffer[cur++] = '\n'; // start of content part + // render entity modifiers for (i = 0; i < packet->entity.lines; i++) cur += PSYC_renderModifier(&packet->entity.modifiers[i], buffer + cur); - if (packet->method.length) + if (packet->method.length) // add method\n { memcpy(buffer + cur, packet->method.ptr, packet->method.length); cur += packet->method.length; buffer[cur++] = '\n'; } - if (packet->data.length) + if (packet->data.length) // add data\n { memcpy(buffer + cur, packet->data.ptr, packet->method.length); cur += packet->data.length; buffer[cur++] = '\n'; } + // add packet delimiter buffer[cur++] = C_GLYPH_PACKET_DELIMITER; buffer[cur++] = '\n'; + // actual length should be equal to pre-calculated length at this point assert(cur == packet->length); return PSYC_RENDER_SUCCESS; } From d1ec497ef35ff2b17815ec608dd14e81fbe3b66c Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Mon, 25 Apr 2011 23:40:38 +0200 Subject: [PATCH 095/378] new style: psyc_functions, psycTypes, PSYC_MACROS --- include/psyc.h | 88 +++++++++++++++++++++---------------------- include/psyc/parser.h | 50 ++++++++++++------------ include/psyc/render.h | 22 +++++------ src/match.c | 10 ++--- src/misc.c | 2 +- src/packet.c | 52 ++++++++++++------------- src/parser.c | 46 +++++++++++----------- src/psyc_parser_cb.h | 34 ++++++++--------- src/render.c | 20 +++++----- src/text.c | 2 +- src/variable.c | 6 +-- test/isRoutingVar.c | 4 +- test/testMatch.c | 20 +++++----- test/testParser.c | 18 ++++----- test/testRender.c | 33 ++++++++-------- 15 files changed, 204 insertions(+), 203 deletions(-) diff --git a/include/psyc.h b/include/psyc.h index 7235696..9ec6cbb 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -28,7 +28,7 @@ typedef enum { PSYC_FALSE = 0, PSYC_TRUE = 1, -} PSYC_Bool; +} psycBool; /** * PSYC packet parts. @@ -42,7 +42,7 @@ typedef enum PSYC_PART_METHOD, PSYC_PART_DATA, PSYC_PART_END, -} PSYC_Part; +} psycPart; /** * Different types that a variable can have. @@ -67,7 +67,7 @@ typedef enum PSYC_TYPE_PAGE, PSYC_TYPE_UNIFORM, PSYC_TYPE_TIME, -} PSYC_Type; +} psycType; /** * List types. @@ -77,7 +77,7 @@ typedef enum { PSYC_LIST_TEXT = 1, PSYC_LIST_BINARY = 2, -} PSYC_ListType; +} psycListType; typedef enum { @@ -85,30 +85,30 @@ typedef enum PSYC_MODIFIER_NEED_LENGTH = 1, PSYC_MODIFIER_NO_LENGTH = 2, PSYC_MODIFIER_ROUTING = 3, -} PSYC_ModifierFlag; +} psycModifierFlag; typedef enum { PSYC_PACKET_CHECK_LENGTH = 0, PSYC_PACKET_NEED_LENGTH = 1, PSYC_PACKET_NO_LENGTH = 2, -} PSYC_PacketFlag; +} psycPacketFlag; typedef struct { size_t length; const char *ptr; -} PSYC_String; +} psycString; /** - * Shortcut for creating a PSYC_String. + * Shortcut for creating a psycString. * * @param memory Pointer to the buffer. * @param length Length of that buffer. * - * @return An instance of the PSYC_String struct. + * @return An instance of the psycString struct. */ -inline PSYC_String PSYC_newString (const char *str, size_t strlen); +inline psycString psyc_newString (const char *str, size_t strlen); #define PSYC_C2STR(string) {sizeof(string)-1, string} #define PSYC_C2ARG(string) string, sizeof(string)-1 @@ -117,88 +117,88 @@ inline PSYC_String PSYC_newString (const char *str, size_t strlen); typedef struct { char oper; // not call it 'operator' as C++ may not like that.. - PSYC_String name; - PSYC_String value; - PSYC_ModifierFlag flag; -} PSYC_Modifier; + psycString name; + psycString value; + psycModifierFlag flag; +} psycModifier; typedef struct { size_t lines; - PSYC_Modifier *modifiers; -} PSYC_ModifierArray; + psycModifier *modifiers; +} psycModifierArray; /* intermediate struct for a PSYC packet */ typedef struct { - PSYC_ModifierArray routing; ///< Routing header. - PSYC_ModifierArray entity; ///< Entitiy header. - PSYC_String method; - PSYC_String data; + psycModifierArray routing; ///< Routing header. + psycModifierArray entity; ///< Entitiy header. + psycString method; + psycString data; size_t routingLength; ///< Length of routing part. size_t contentLength; ///< Length of content part. size_t length; ///< Total length of packet. - PSYC_PacketFlag flag; -} PSYC_Packet; + psycPacketFlag flag; +} psycPacket; -inline int PSYC_version(); +inline int psyc_version(); -inline PSYC_Modifier PSYC_newModifier(char oper, PSYC_String *name, PSYC_String *value, - PSYC_ModifierFlag flag); +inline psycModifier psyc_newModifier(char oper, psycString *name, psycString *value, + psycModifierFlag flag); -inline PSYC_Modifier PSYC_newModifier2(char oper, +inline psycModifier psyc_newModifier2(char oper, const char *name, size_t namelen, const char *value, size_t valuelen, - PSYC_ModifierFlag flag); + psycModifierFlag flag); -inline PSYC_Packet PSYC_newPacket(PSYC_ModifierArray *routing, - PSYC_ModifierArray *entity, - PSYC_String *method, PSYC_String *data, - PSYC_PacketFlag flag); +inline psycPacket psyc_newPacket(psycModifierArray *routing, + psycModifierArray *entity, + psycString *method, psycString *data, + psycPacketFlag flag); -inline PSYC_Packet PSYC_newPacket2(PSYC_Modifier *routing, size_t routinglen, - PSYC_Modifier *entity, size_t entitylen, +inline psycPacket psyc_newPacket2(psycModifier *routing, size_t routinglen, + psycModifier *entity, size_t entitylen, const char *method, size_t methodlen, const char *data, size_t datalen, - PSYC_PacketFlag flag); + psycPacketFlag flag); /// Routing vars in alphabetical order. -extern const PSYC_String PSYC_routingVars[]; +extern const psycString PSYC_routingVars[]; /// Number of routing vars. extern const size_t PSYC_routingVarsNum; /** * Get the type of variable name. */ -PSYC_Bool PSYC_isRoutingVar(const char *name, size_t len); +psycBool psyc_isRoutingVar(const char *name, size_t len); /** * Get the type of variable name. */ -PSYC_Type PSYC_getVarType(char *name, size_t len); +psycType psyc_getVarType(char *name, size_t len); /** * Checks if long keyword string inherits from short keyword string. */ -int PSYC_inherits(char *sho, size_t slen, +int psyc_inherits(char *sho, size_t slen, char *lon, size_t llen); /** * Checks if short keyword string matches long keyword string. */ -int PSYC_matches(char *sho, size_t slen, +int psyc_matches(char *sho, size_t slen, char *lon, size_t llen); /** - * Callback for PSYC_text() that produces a value for a match. + * Callback for psyc_text() that produces a value for a match. * * The application looks up a match such as _fruit from [_fruit] and * if found writes its current value from its variable store into the * outgoing buffer.. "Apple" for example. The template returns the * number of bytes written. 0 is a legal return value. Should the - * callback return -1, PSYC_text leaves the original template text as is. + * callback return -1, psyc_text leaves the original template text as is. */ -typedef int (*PSYC_textCB)(uint8_t *match, size_t mlen, +typedef int (*psyctextCB)(uint8_t *match, size_t mlen, uint8_t **buffer, size_t *blen); /** @@ -214,9 +214,9 @@ typedef int (*PSYC_textCB)(uint8_t *match, size_t mlen, * * See also http://about.psyc.eu/psyctext */ -int PSYC_text(uint8_t *template, size_t tlen, +int psyc_text(uint8_t *template, size_t tlen, uint8_t **buffer, size_t *blen, - PSYC_textCB lookupValue, + psyctextCB lookupValue, char *braceOpen, char *braceClose); #endif // PSYC_H diff --git a/include/psyc/parser.h b/include/psyc/parser.h index e8c46b5..a81ba36 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -22,11 +22,11 @@ typedef enum { PSYC_PARSE_HEADER_ONLY = 1, -} PSYC_ParseFlag; +} psycParseFlag; /** * The return value definitions for the packet parsing function. - * @see PSYC_parse() + * @see psyc_parse() */ typedef enum { @@ -59,11 +59,11 @@ typedef enum PSYC_PARSE_COMPLETE = 7, /// Binary value parsing incomplete, used internally. PSYC_PARSE_INCOMPLETE = 8, -} PSYC_ParseRC; +} psycParseRC; /** * The return value definitions for the list parsing function. - * @see PSYC_parseList() + * @see psyc_parseList() */ typedef enum { @@ -78,7 +78,7 @@ typedef enum PSYC_PARSE_LIST_END = 2, /// Binary list is incomplete. PSYC_PARSE_LIST_INCOMPLETE = 3, -} PSYC_ParseListRC; +} psycParseListRC; /** * Struct for keeping parser state. @@ -87,16 +87,16 @@ typedef struct { size_t cursor; ///< current position in buffer size_t startc; ///< position where the parsing would be resumed - PSYC_String buffer; ///< buffer with data to be parsed - uint8_t flags; ///< flags for the parser, see PSYC_ParseFlag - PSYC_Part part; ///< part of the packet being parsed currently + psycString buffer; ///< buffer with data to be parsed + uint8_t flags; ///< flags for the parser, see psycParseFlag + psycPart part; ///< part of the packet being parsed currently size_t contentParsed; ///< number of bytes parsed from the content so far size_t contentLength; ///< expected length of the content - PSYC_Bool contentLengthFound; ///< is there a length given for this packet? + psycBool 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_ParseState; +} psycParseState; /** * Struct for keeping list parser state. @@ -105,60 +105,60 @@ typedef struct { size_t cursor; ///< current position in buffer size_t startc; ///< line start position - PSYC_String buffer; - PSYC_ListType type; ///< list type + psycString buffer; + psycListType type; ///< list type size_t elemParsed; ///< number of bytes parsed from the elem so far size_t elemLength; ///< expected length of the elem -} PSYC_ParseListState; +} psycParseListState; /** * Initiates the state struct. * * @param state Pointer to the state struct that should be initiated. */ -inline void PSYC_initParseState (PSYC_ParseState* state); +inline void psyc_initParseState (psycParseState* state); /** * Initiates the state struct with flags. * * @param state Pointer to the state struct that should be initiated. - * @param flags Flags to be set for the parser, see PSYC_ParseFlag. + * @param flags Flags to be set for the parser, see psycParseFlag. */ -inline void PSYC_initParseState2 (PSYC_ParseState* state, uint8_t flags); +inline void psyc_initParseState2 (psycParseState* state, uint8_t flags); /** * Initiates the list state struct. * * @param state Pointer to the list state struct that should be initiated. */ -inline void PSYC_initParseListState (PSYC_ParseListState* state); +inline void psyc_initParseListState (psycParseListState* state); -inline void PSYC_nextParseBuffer (PSYC_ParseState* state, PSYC_String newBuf); +inline void psyc_nextParseBuffer (psycParseState* state, psycString newBuf); -inline void PSYC_nextParseListBuffer (PSYC_ParseListState* state, PSYC_String newBuf); +inline void psyc_nextParseListBuffer (psycParseListState* state, psycString newBuf); -inline size_t PSYC_getContentLength (PSYC_ParseState* s); +inline size_t psyc_getContentLength (psycParseState* s); /** * Parse PSYC packets. * * Generalized line-based packet parser. * - * @param state An initialized PSYC_ParseState + * @param state An initialized psycParseState * @param operator A pointer to a character. In case of a variable, it will * be set to the operator of that variable - * @param name A pointer to a PSYC_String. It will point to the name of + * @param name A pointer to a psycString. It will point to the name of * the variable or method and its length will be set accordingly - * @param value A pointer to a PSYC_String. It will point to the + * @param value A pointer to a psycString. It will point to the * value/body the variable/method and its length will be set accordingly */ -PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, char* oper, PSYC_String* name, PSYC_String* value); +psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psycString* value); /** * List value parser. */ -PSYC_ParseListRC PSYC_parseList(PSYC_ParseListState* state, PSYC_String *name, PSYC_String* value, PSYC_String* elem); +psycParseListRC psyc_parseList(psycParseListState* state, psycString *name, psycString* value, psycString* elem); #endif // PSYC_PARSER_H diff --git a/include/psyc/render.h b/include/psyc/render.h index b900ad7..8c21e0b 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -17,19 +17,19 @@ */ /** - * Return codes for PSYC_render. + * Return codes for psyc_render. */ typedef enum { //PSYC_RENDER_ERROR_ROUTING = -2, PSYC_RENDER_ERROR = -1, PSYC_RENDER_SUCCESS = 0, -} PSYC_RenderRC; +} psycRenderRC; /** * Render a PSYC packet into a buffer. */ -PSYC_RenderRC PSYC_render(PSYC_Packet *packet, char *buffer, size_t buflen); +psycRenderRC psyc_render(psycPacket *packet, char *buffer, size_t buflen); /* typedef enum @@ -38,7 +38,7 @@ typedef enum PSYC_RENDER_NEED_LENGTH = 1, PSYC_RENDER_NO_LENGTH = 2, PSYC_RENDER_ROUTING = 3, -} PSYC_RenderFlag; +} psycRenderFlag; */ /** @@ -47,14 +47,14 @@ typedef enum /* typedef struct { - PSYC_RenderFlag flag; ///< flags for the renderer - PSYC_Part part; ///< part of the packet being rendered + psycRenderFlag flag; ///< flags for the renderer + psycPart part; ///< part of the packet being rendered size_t cursor; ///< current position in buffer size_t spot; ///< space for rendered length between the headers size_t contentLength; ///< length of the content part size_t length; ///< how big is the buffer we allocated char buffer[]; ///< OMG a C99 feature! variable size buffer! -} PSYC_RenderState; +} psycRenderState; */ /** * Initiates the state struct. @@ -62,14 +62,14 @@ typedef struct * @param state Pointer to the state struct that should be initiated. */ /* -inline void PSYC_initRenderState (PSYC_RenderState* state); +inline void psyc_initRenderState (psycRenderState* state); -int PSYC_renderModifier(PSYC_RenderState* render, +int psyc_renderModifier(psycRenderState* render, const char* name, size_t nlength, const char* value, size_t vlength, - PSYC_RenderFlag flags, char oper); + psycRenderFlag flags, char oper); -int PSYC_renderBody(PSYC_RenderState* render, +int psyc_renderBody(psycRenderState* render, const char* method, size_t mlength, const char* data, size_t dlength); */ diff --git a/src/match.c b/src/match.c index 4e7e3ff..ab7918b 100644 --- a/src/match.c +++ b/src/match.c @@ -1,6 +1,6 @@ #include "psyc/lib.h" -int PSYC_inherits(char* sho, size_t slen, +int psyc_inherits(char* sho, size_t slen, char* lon, size_t llen) { // this allows to pass zero-terminated strings instead of providing @@ -41,7 +41,7 @@ int PSYC_inherits(char* sho, size_t slen, return 1; } -int PSYC_matches(char* sho, size_t slen, +int psyc_matches(char* sho, size_t slen, char* lon, size_t llen) { char *s, *l, *se, *le; @@ -67,7 +67,7 @@ int PSYC_matches(char* sho, size_t slen, P1(("Same length but different.\nNo match, but they could be related or have a common type.\n")) return -4; } - P3(("# PSYC_matches short '%*s' in long '%*s' ?\n", slen, sho, llen, lon)) + P3(("# psyc_matches short '%*s' in long '%*s' ?\n", slen, sho, llen, lon)) se = sho+slen; le = lon+llen; @@ -105,9 +105,9 @@ int main(int argc, char **argv) { printf("Usage: %s \n\nExample: %s _failure_delivery _failure_unsuccessful_delivery_death\n", argv[0], argv[0]); return -1; } - if (PSYC_matches(argv[1], 0, argv[2], 0) == 0) + if (psyc_matches(argv[1], 0, argv[2], 0) == 0) printf("Yes, %s matches %s!\n", argv[1], argv[2]); - if (PSYC_inherits(argv[1], 0, argv[2], 0) == 0) + if (psyc_inherits(argv[1], 0, argv[2], 0) == 0) printf("Yes, %s inherits from %s!\n", argv[2], argv[1]); } #endif diff --git a/src/misc.c b/src/misc.c index 27c39d2..a92359d 100644 --- a/src/misc.c +++ b/src/misc.c @@ -1,2 +1,2 @@ -int PSYC_version() { return 1; } +int psyc_version() { return 1; } diff --git a/src/packet.c b/src/packet.c index fa9c410..087c401 100644 --- a/src/packet.c +++ b/src/packet.c @@ -3,16 +3,16 @@ #include -inline PSYC_String PSYC_newString(const char *str, size_t strlen) +inline psycString psyc_newString(const char *str, size_t strlen) { - PSYC_String s = {strlen, str}; + psycString s = {strlen, str}; return s; } -inline PSYC_Modifier PSYC_newModifier(char oper, PSYC_String *name, PSYC_String *value, - PSYC_ModifierFlag flag) +inline psycModifier psyc_newModifier(char oper, psycString *name, psycString *value, + psycModifierFlag flag) { - PSYC_Modifier m = {oper, *name, *value, flag}; + psycModifier m = {oper, *name, *value, flag}; if (flag == PSYC_MODIFIER_CHECK_LENGTH) // find out if it needs a length { @@ -27,18 +27,18 @@ inline PSYC_Modifier PSYC_newModifier(char oper, PSYC_String *name, PSYC_String return m; } -inline PSYC_Modifier PSYC_newModifier2(char oper, +inline psycModifier psyc_newModifier2(char oper, const char *name, size_t namelen, const char *value, size_t valuelen, - PSYC_ModifierFlag flag) + psycModifierFlag flag) { - PSYC_String n = {namelen, name}; - PSYC_String v = {valuelen, value}; + psycString n = {namelen, name}; + psycString v = {valuelen, value}; - return PSYC_newModifier(oper, &n, &v, flag); + return psyc_newModifier(oper, &n, &v, flag); } -inline size_t PSYC_getModifierLength(PSYC_Modifier *m) +inline size_t psyc_getModifierLength(psycModifier *m) { size_t length = 1 + // oper m->name.length + 1 + // name\t @@ -50,12 +50,12 @@ inline size_t PSYC_getModifierLength(PSYC_Modifier *m) return length; } -inline PSYC_Packet PSYC_newPacket(PSYC_ModifierArray *routing, - PSYC_ModifierArray *entity, - PSYC_String *method, PSYC_String *data, - PSYC_PacketFlag flag) +inline psycPacket psyc_newPacket(psycModifierArray *routing, + psycModifierArray *entity, + psycString *method, psycString *data, + psycPacketFlag flag) { - PSYC_Packet p = {*routing, *entity, *method, *data, 0, 0, flag}; + psycPacket p = {*routing, *entity, *method, *data, 0, 0, flag}; size_t i; if (flag == PSYC_PACKET_CHECK_LENGTH) // find out if it needs a length @@ -72,11 +72,11 @@ inline PSYC_Packet PSYC_newPacket(PSYC_ModifierArray *routing, // add routing header length for (i = 0; i < routing->lines; i++) - p.routingLength += PSYC_getModifierLength(&routing->modifiers[i]); + p.routingLength += psyc_getModifierLength(&routing->modifiers[i]); // add entity header length for (i = 0; i < entity->lines; i++) - p.contentLength += PSYC_getModifierLength(&entity->modifiers[i]); + p.contentLength += psyc_getModifierLength(&entity->modifiers[i]); // add length of method, data & delimiter if (method->length) @@ -92,16 +92,16 @@ inline PSYC_Packet PSYC_newPacket(PSYC_ModifierArray *routing, return p; } -inline PSYC_Packet PSYC_newPacket2(PSYC_Modifier *routing, size_t routinglen, - PSYC_Modifier *entity, size_t entitylen, +inline psycPacket psyc_newPacket2(psycModifier *routing, size_t routinglen, + psycModifier *entity, size_t entitylen, const char *method, size_t methodlen, const char *data, size_t datalen, - PSYC_PacketFlag flag) + psycPacketFlag flag) { - PSYC_ModifierArray r = {routinglen, routing}; - PSYC_ModifierArray e = {entitylen, entity}; - PSYC_String m = {methodlen, method}; - PSYC_String d = {datalen, data}; + psycModifierArray r = {routinglen, routing}; + psycModifierArray e = {entitylen, entity}; + psycString m = {methodlen, method}; + psycString d = {datalen, data}; - return PSYC_newPacket(&r, &e, &m, &d, flag); + return psyc_newPacket(&r, &e, &m, &d, flag); } diff --git a/src/parser.c b/src/parser.c index 13852fd..8025b07 100644 --- a/src/parser.c +++ b/src/parser.c @@ -15,35 +15,35 @@ return ret; \ } -inline void PSYC_initParseState (PSYC_ParseState* state) +inline void psyc_initParseState (psycParseState* state) { - memset(state, 0, sizeof(PSYC_ParseState)); + memset(state, 0, sizeof(psycParseState)); } -inline void PSYC_initParseState2 (PSYC_ParseState* state, uint8_t flags) +inline void psyc_initParseState2 (psycParseState* state, uint8_t flags) { - memset(state, 0, sizeof(PSYC_ParseState)); + memset(state, 0, sizeof(psycParseState)); state->flags = flags; } -inline void PSYC_initParseListState (PSYC_ParseListState* state) +inline void psyc_initParseListState (psycParseListState* state) { - memset(state, 0, sizeof(PSYC_ParseListState)); + memset(state, 0, sizeof(psycParseListState)); } -inline void PSYC_nextParseBuffer (PSYC_ParseState* state, PSYC_String newBuf) +inline void psyc_nextParseBuffer (psycParseState* state, psycString newBuf) { state->buffer = newBuf; state->cursor = 0; } -inline void PSYC_nextParseListBuffer (PSYC_ParseListState* state, PSYC_String newBuf) +inline void psyc_nextParseListBuffer (psycParseListState* state, psycString newBuf) { state->buffer = newBuf; state->cursor = 0; } -inline size_t PSYC_getContentLength (PSYC_ParseState* s) +inline size_t psyc_getContentLength (psycParseState* s) { return s->contentLength; } @@ -101,7 +101,7 @@ inline char isKwChar(uint8_t c) * It should contain one or more keyword characters. * @return PSYC_PARSE_ERROR or PSYC_PARSE_SUCCESS */ -inline PSYC_ParseRC PSYC_parseName(PSYC_ParseState* state, PSYC_String* name) +inline psycParseRC psyc_parseName(psycParseState* state, psycString* name) { name->ptr = state->buffer.ptr + state->cursor; name->length = 0; @@ -125,7 +125,7 @@ inline PSYC_ParseRC PSYC_parseName(PSYC_ParseState* state, PSYC_String* name) * * @return PSYC_PARSE_COMPLETE or PSYC_PARSE_INCOMPLETE */ -inline PSYC_ParseRC PSYC_parseBinaryValue(PSYC_ParseState* state, PSYC_String* value, size_t* length, size_t* parsed) +inline psycParseRC psyc_parseBinaryValue(psycParseState* state, psycString* value, size_t* length, size_t* parsed) { size_t remaining = *length - *parsed; value->ptr = state->buffer.ptr + state->cursor; @@ -148,12 +148,12 @@ inline PSYC_ParseRC PSYC_parseBinaryValue(PSYC_ParseState* state, PSYC_String* v * Parse simple or binary variable. * @return PSYC_PARSE_ERROR or PSYC_PARSE_SUCCESS */ -inline PSYC_ParseRC PSYC_parseModifier(PSYC_ParseState* state, char* oper, PSYC_String* name, PSYC_String* value) +inline psycParseRC psyc_parseModifier(psycParseState* state, char* oper, psycString* name, psycString* value) { *oper = *(state->buffer.ptr + state->cursor); ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); - if (PSYC_parseName(state, name) != PSYC_PARSE_SUCCESS) + if (psyc_parseName(state, name) != PSYC_PARSE_SUCCESS) return PSYC_PARSE_ERROR_VAR_NAME; value->length = 0; @@ -185,7 +185,7 @@ inline PSYC_ParseRC PSYC_parseModifier(PSYC_ParseState* state, char* oper, PSYC_ if (state->buffer.length <= ++(state->cursor)) // Incremented cursor inside length? return PSYC_PARSE_ENTITY_INCOMPLETE; - if (PSYC_parseBinaryValue(state, value, &(state->valueLength), &(state->valueParsed)) == PSYC_PARSE_INCOMPLETE) + if (psyc_parseBinaryValue(state, value, &(state->valueLength), &(state->valueParsed)) == PSYC_PARSE_INCOMPLETE) return PSYC_PARSE_ENTITY_INCOMPLETE; state->cursor++; @@ -212,7 +212,7 @@ inline PSYC_ParseRC PSYC_parseModifier(PSYC_ParseState* state, char* oper, PSYC_ * Parse PSYC packets. * Generalized line-based parser. */ -PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, char* oper, PSYC_String* name, PSYC_String* value) +psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psycString* value) { int ret; // a return value size_t pos; // a cursor position @@ -242,7 +242,7 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, char* oper, PSYC_String* name, P // 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_parseModifier(state, oper, name, value); + ret = psyc_parseModifier(state, oper, name, value); return ret == PSYC_PARSE_SUCCESS ? PSYC_PARSE_ROUTING : ret; } else // not a glyph @@ -291,7 +291,7 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, char* oper, PSYC_String* name, P 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)); + ret = psyc_parseBinaryValue(state, value, &(state->valueLength), &(state->valueParsed)); state->contentParsed += value->length; return ret == PSYC_PARSE_COMPLETE ? PSYC_PARSE_ENTITY : PSYC_PARSE_ENTITY_INCOMPLETE; } @@ -304,7 +304,7 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, char* oper, PSYC_String* name, P if (isGlyph(state->buffer.ptr[state->cursor])) { pos = state->cursor; - ret = PSYC_parseModifier(state, oper, name, value); + ret = psyc_parseModifier(state, oper, name, value); state->contentParsed += state->cursor - pos; return ret == PSYC_PARSE_SUCCESS ? PSYC_PARSE_ENTITY : ret; } @@ -317,7 +317,7 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, char* oper, PSYC_String* name, P case PSYC_PART_METHOD: pos = state->cursor; - if (PSYC_parseName(state, name) == PSYC_PARSE_SUCCESS) + if (psyc_parseName(state, name) == PSYC_PARSE_SUCCESS) { // the method ends with a \n then the data follows if (state->buffer.ptr[state->cursor] != '\n') return PSYC_PARSE_ERROR_METHOD; @@ -343,7 +343,7 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, char* oper, PSYC_String* name, P if (state->contentLengthFound) // We know the length of the packet. { - if (PSYC_parseBinaryValue(state, value, &(state->contentLength), &(state->contentParsed)) == PSYC_PARSE_INCOMPLETE) + if (psyc_parseBinaryValue(state, value, &(state->contentLength), &(state->contentParsed)) == PSYC_PARSE_INCOMPLETE) return PSYC_PARSE_BODY_INCOMPLETE; state->cursor++; @@ -400,9 +400,9 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, char* oper, PSYC_String* name, P /** * List value parser. - * @return see PSYC_ListRC. + * @return see psycListRC. */ -PSYC_ParseListRC PSYC_parseList(PSYC_ParseListState* state, PSYC_String *name, PSYC_String* value, PSYC_String* elem) +psycParseListRC psyc_parseList(psycParseListState* state, psycString *name, psycString* value, psycString* elem) { if (state->cursor >= state->buffer.length) return PSYC_PARSE_LIST_INCOMPLETE; @@ -473,7 +473,7 @@ PSYC_ParseListRC PSYC_parseList(PSYC_ParseListState* state, PSYC_String *name, P // Start or resume parsing the binary data if (state->elemParsed < state->elemLength) { - if (PSYC_parseBinaryValue((PSYC_ParseState*)state, elem, &(state->elemLength), &(state->elemParsed)) == PSYC_PARSE_INCOMPLETE) + if (psyc_parseBinaryValue((psycParseState*)state, elem, &(state->elemLength), &(state->elemParsed)) == PSYC_PARSE_INCOMPLETE) return PSYC_PARSE_LIST_INCOMPLETE; state->elemLength = 0; diff --git a/src/psyc_parser_cb.h b/src/psyc_parser_cb.h index 811f001..1f38134 100644 --- a/src/psyc_parser_cb.h +++ b/src/psyc_parser_cb.h @@ -1,19 +1,19 @@ #include -struct PSYC_Parser; +struct psycParser; /** @brief initialize a pstate struct * * @param pstate pointer to an allocated - * PSYC_Parser struct. + * psycParser struct. */ -void PSYC_initState(struct PSYC_Parser* pstate); +void psyc_initState(struct psycParser* pstate); /** @brief parses a packet * * This function parses rawdata - * and uses the callbacks in PSYC_Parser + * and uses the callbacks in psycParser * to communicate with the caller. * * First the header will be parsed, @@ -23,7 +23,7 @@ void PSYC_initState(struct PSYC_Parser* pstate); * Then, routingCallback will be called * to find out if further parsing * is desired. - * If it returns false, PSYC_parser returns. + * If it returns false, psyc_parse returns. * If it returns true, parsing continues * to the body. * After the entitystate has been parsed, @@ -38,15 +38,15 @@ void PSYC_initState(struct PSYC_Parser* pstate); * raw data that is to be processed. * @param length the amount of bytes to parse * @param pstate pointer to a preallocated - * and initialized (PSYC_initState) + * and initialized (psyc_initState) * instance of the struct state * */ -void PSYC_parse(const uint8_t* data, unsigned int length, - struct PSYC_Parser* pstate); +void psyc_parse(const uint8_t* data, unsigned int length, + struct psycParser* pstate); /** @brief FlagMod */ -enum PSYC_Operator +enum psycOperator { // modifier operators ASSIGN = 0x02, @@ -56,7 +56,7 @@ enum PSYC_Operator QUERY = 0x20, }; -struct PSYC_Parser +struct psycParser { /** @brief Callback for the states * @@ -76,10 +76,10 @@ struct PSYC_Parser * @param modifers modifer of the variable (see Modifer) * @param inEntity wether this variable is an entity * variable(true) or a routing variable(false) */ - void (*stateCallback)(struct PSYC_Parser* pstate, + void (*stateCallback)(struct psycParser* pstate, const uint8_t *name, const unsigned int nlength, const uint8_t *value, const unsigned int vlength, - enum PSYC_Operator oper, char inEntity); + enum psycOperator oper, char inEntity); /** @brief gets called after the routing-header was parsed * @@ -88,7 +88,7 @@ struct PSYC_Parser * when finished, * if not 0, parser will stop parsing and * calls contentCallback */ - char (*routingCallback)(struct PSYC_Parser* pstate); + char (*routingCallback)(struct psycParser* pstate); /** @brief Body callback, gets called when the body was parsed * @@ -102,7 +102,7 @@ struct PSYC_Parser * containing the data section * @param content not null terminated c-string * @param clength length of the content string */ - void (*bodyCallback)(struct PSYC_Parser* pstate, + void (*bodyCallback)(struct psycParser* pstate, const uint8_t* method, unsigned int mlength, const uint8_t* data, unsigned int dlength, const uint8_t* content, unsigned int clength); @@ -123,7 +123,7 @@ struct PSYC_Parser * * Any previous state or body callbacks become * invalid and have to be purged.*/ - void (*errorCallback)(struct PSYC_Parser* pstate, + void (*errorCallback)(struct psycParser* pstate, const uint8_t *method, unsigned int mlength); /** @brief error state callback @@ -132,10 +132,10 @@ struct PSYC_Parser * The callback will be called once for each * state variable in the error report packet */ - void (*errorStateCallback)(struct PSYC_Parser* pstate, + void (*errorStateCallback)(struct psycParser* pstate, const uint8_t *name, const unsigned int nlength, const uint8_t *value, const unsigned int vlength, - enum PSYC_Operator oper); + enum psycOperator oper); /******************************************* diff --git a/src/render.c b/src/render.c index 35350f5..f78fcd9 100644 --- a/src/render.c +++ b/src/render.c @@ -2,7 +2,7 @@ #include "psyc/render.h" #include "psyc/syntax.h" -inline size_t PSYC_renderModifier(PSYC_Modifier *m, char *buffer) +inline size_t psyc_renderModifier(psycModifier *m, char *buffer) { size_t cur = 0; @@ -24,7 +24,7 @@ inline size_t PSYC_renderModifier(PSYC_Modifier *m, char *buffer) return cur; } -PSYC_RenderRC PSYC_render(PSYC_Packet *packet, char *buffer, size_t buflen) +psycRenderRC psyc_render(psycPacket *packet, char *buffer, size_t buflen) { size_t i, cur = 0; @@ -33,7 +33,7 @@ PSYC_RenderRC PSYC_render(PSYC_Packet *packet, char *buffer, size_t buflen) // render routing modifiers for (i = 0; i < packet->routing.lines; i++) - cur += PSYC_renderModifier(&packet->routing.modifiers[i], buffer + cur); + cur += psyc_renderModifier(&packet->routing.modifiers[i], buffer + cur); // add length if needed if (packet->flag == PSYC_PACKET_NEED_LENGTH) { @@ -45,7 +45,7 @@ PSYC_RenderRC PSYC_render(PSYC_Packet *packet, char *buffer, size_t buflen) // render entity modifiers for (i = 0; i < packet->entity.lines; i++) - cur += PSYC_renderModifier(&packet->entity.modifiers[i], buffer + cur); + cur += psyc_renderModifier(&packet->entity.modifiers[i], buffer + cur); if (packet->method.length) // add method\n { @@ -71,15 +71,15 @@ PSYC_RenderRC PSYC_render(PSYC_Packet *packet, char *buffer, size_t buflen) } /* -inline void PSYC_initRenderState (PSYC_RenderState *state) +inline void psyc_initRenderState (psycRenderState *state) { - memset(state, 0, sizeof(PSYC_RenderState)); + memset(state, 0, sizeof(psycRenderState)); } -PSYC_RenderRC PSYC_renderModifier(PSYC_RenderState *state, +psycRenderRC psyc_renderModifier(psycRenderState *state, const char *name, size_t nlength, const char *value, size_t vlength, - const PSYC_RenderFlag flags, char oper) + const psycRenderFlag flags, char oper) { size_t startc = state->cursor; @@ -99,7 +99,7 @@ PSYC_RenderRC PSYC_renderModifier(PSYC_RenderState *state, } //if (flags == PSYC_RENDER_ROUTING) - if (PSYC_isRoutingVar(name, nlength)) + if (psyc_isRoutingVar(name, nlength)) { // no more routing headers allowed after content started if (state->part != PSYC_PART_ROUTING) { @@ -121,7 +121,7 @@ PSYC_RenderRC PSYC_renderModifier(PSYC_RenderState *state, return PSYC_RENDER_SUCCESS; } -PSYC_RenderRC PSYC_renderBody(PSYC_RenderState *state, +psycRenderRC psyc_renderBody(psycRenderState *state, const char *method, size_t mlength, const char *data, size_t dlength) { diff --git a/src/text.c b/src/text.c index 1daa789..95dcc88 100644 --- a/src/text.c +++ b/src/text.c @@ -1,2 +1,2 @@ -/* PSYC_text() */ +/* psyc_text() */ diff --git a/src/variable.c b/src/variable.c index dc2b15d..6273e68 100644 --- a/src/variable.c +++ b/src/variable.c @@ -2,7 +2,7 @@ #include /// Routing variables in alphabetical order. -const PSYC_String PSYC_routingVars[] = +const psycString PSYC_routingVars[] = { PSYC_C2STR("_amount_fragments"), PSYC_C2STR("_context"), @@ -29,7 +29,7 @@ const size_t PSYC_routingVarsNum = sizeof(PSYC_routingVars) / sizeof(*PSYC_routi /** * Get the type of variable name. */ -PSYC_Bool PSYC_isRoutingVar(const char *name, size_t len) +psycBool psyc_isRoutingVar(const char *name, size_t len) { size_t cursor = 1; int8_t matching[PSYC_routingVarsNum]; // indexes of matching vars @@ -68,7 +68,7 @@ PSYC_Bool PSYC_isRoutingVar(const char *name, size_t len) /** * Get the type of variable name. */ -PSYC_Type PSYC_getVarType(char *name, size_t len) +psycType psyc_getVarType(char *name, size_t len) { return PSYC_TYPE_UNKNOWN; } diff --git a/test/isRoutingVar.c b/test/isRoutingVar.c index 10121b2..02b1fd8 100644 --- a/test/isRoutingVar.c +++ b/test/isRoutingVar.c @@ -19,8 +19,8 @@ int main(int argc, char** argv) int i; for (i = 0; i < sizeof(vars) / sizeof(*vars); i++) { - printf(">> %s: %ld %ld\n", vars[i], sizeof(vars[i]), sizeof(*vars[i])); - printf("%s: %d\n", vars[i], PSYC_isRoutingVar(vars[i], strlen(vars[i]))); + printf(">> %s: %d %d\n", vars[i], sizeof(vars[i]), sizeof(*vars[i])); + printf("%s: %d\n", vars[i], psyc_isRoutingVar(vars[i], strlen(vars[i]))); } return 0; diff --git a/test/testMatch.c b/test/testMatch.c index 822a2d1..b6695d3 100644 --- a/test/testMatch.c +++ b/test/testMatch.c @@ -2,19 +2,19 @@ #include "../include/psyc/lib.h" int main() { - if (PSYC_matches("_failure_delivery", 0, "_failure_unsuccessful_delivery_death", 0)) return -1; - if (PSYC_matches("_failure_trash", 8, "_failure_unsuccessful_delivery_death", 0)) return -2; - if (PSYC_matches("_unsuccessful", 0, "_failure_unsuccessful_delivery_death", 0)) return -3; - unless (PSYC_matches("_fail", 0, "_failure_unsuccessful_delivery_death", 0)) return -4; - unless (PSYC_matches("_truthahn", 0, "_failure_unsuccessful_delivery_death", 0)) return -5; + if (psyc_matches("_failure_delivery", 0, "_failure_unsuccessful_delivery_death", 0)) return -1; + if (psyc_matches("_failure_trash", 8, "_failure_unsuccessful_delivery_death", 0)) return -2; + if (psyc_matches("_unsuccessful", 0, "_failure_unsuccessful_delivery_death", 0)) return -3; + unless (psyc_matches("_fail", 0, "_failure_unsuccessful_delivery_death", 0)) return -4; + unless (psyc_matches("_truthahn", 0, "_failure_unsuccessful_delivery_death", 0)) return -5; - puts("PSYC_matches passed all tests."); + puts("psyc_matches passed all tests."); - unless (PSYC_inherits("_failure_delivery", 0, "_failure_unsuccessful_delivery_death", 0)) return -11; - if (PSYC_inherits("_failure_unsuccessful", 0, "_failure_unsuccessful_delivery_death", 0)) return -12; - unless (PSYC_inherits("_fail", 0, "_failure_unsuccessful_delivery_death", 0)) return -13; + unless (psyc_inherits("_failure_delivery", 0, "_failure_unsuccessful_delivery_death", 0)) return -11; + if (psyc_inherits("_failure_unsuccessful", 0, "_failure_unsuccessful_delivery_death", 0)) return -12; + unless (psyc_inherits("_fail", 0, "_failure_unsuccessful_delivery_death", 0)) return -13; - puts("PSYC_inherits passed all tests."); + puts("psyc_inherits passed all tests."); return 0; // passed all tests } diff --git a/test/testParser.c b/test/testParser.c index 2e4fc7a..d039a72 100644 --- a/test/testParser.c +++ b/test/testParser.c @@ -8,9 +8,9 @@ int main(int argc, char** argv) { int indx, ret; char buffer[2048], oper; - PSYC_String name, value, elem; - PSYC_ParseState state; - PSYC_ParseListState listState; + psycString name, value, elem; + psycParseState state; + psycParseListState listState; int file = open(argv[1],O_RDONLY); if(file < 0) @@ -21,11 +21,11 @@ int main(int argc, char** argv) write(1, buffer, indx); write(1, ">> PARSE\n", 9); - PSYC_initParseState(&state); - PSYC_nextParseBuffer(&state, PSYC_newString(buffer, indx)); + psyc_initParseState(&state); + psyc_nextParseBuffer(&state, psyc_newString(buffer, indx)); // try parsing that now - while ((ret = PSYC_parse(&state, &oper, &name, &value))) + while ((ret = psyc_parse(&state, &oper, &name, &value))) { switch (ret) { @@ -41,9 +41,9 @@ int main(int argc, char** argv) if (memcmp(name.ptr, "_list", 5) == 0) { write(1, ">>> LIST START\n", 15); - PSYC_initParseListState(&listState); - PSYC_nextParseListBuffer(&listState, value); - while ((ret = PSYC_parseList(&listState, &name, &value, &elem))) + psyc_initParseListState(&listState); + psyc_nextParseListBuffer(&listState, value); + while ((ret = psyc_parseList(&listState, &name, &value, &elem))) { switch (ret) { diff --git a/test/testRender.c b/test/testRender.c index 657f249..9244f68 100644 --- a/test/testRender.c +++ b/test/testRender.c @@ -2,28 +2,29 @@ #include #include "../include/psyc/lib.h" #include "../include/psyc/render.h" +#include "../include/psyc/syntax.h" #define myUNI "psyc://10.100.1000/~ludwig" /* example renderer generating a presence packet */ int writePresence(const char *avail, int availlen, const char *desc, int desclen) { - PSYC_Modifier routing[] = { - PSYC_newModifier2(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_source"), PSYC_C2ARG(myUNI), + psycModifier routing[] = { + psyc_newModifier2(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_source"), PSYC_C2ARG(myUNI), PSYC_MODIFIER_ROUTING), - PSYC_newModifier2(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_context"), PSYC_C2ARG(myUNI), + psyc_newModifier2(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_context"), PSYC_C2ARG(myUNI), PSYC_MODIFIER_ROUTING), }; - PSYC_Modifier entity[] = { + psycModifier entity[] = { // presence is to be assigned permanently in distributed state - PSYC_newModifier2(C_GLYPH_OPERATOR_ASSIGN, PSYC_C2ARG("_degree_availability"), + psyc_newModifier2(C_GLYPH_OPERATOR_ASSIGN, PSYC_C2ARG("_degree_availability"), avail, availlen, PSYC_PACKET_CHECK_LENGTH), - PSYC_newModifier2(C_GLYPH_OPERATOR_ASSIGN, PSYC_C2ARG("_description_presence"), + psyc_newModifier2(C_GLYPH_OPERATOR_ASSIGN, PSYC_C2ARG("_description_presence"), desc, desclen, PSYC_PACKET_CHECK_LENGTH), }; - PSYC_Packet packet = PSYC_newPacket2(routing, PSYC_NUM_ELEM(routing), + psycPacket packet = psyc_newPacket2(routing, PSYC_NUM_ELEM(routing), entity, PSYC_NUM_ELEM(entity), PSYC_C2ARG("_notice_presence"), NULL, 0, @@ -31,11 +32,11 @@ int writePresence(const char *avail, int availlen, const char *desc, int desclen PSYC_PACKET_CHECK_LENGTH); char buffer[512]; - PSYC_render(&packet, buffer, sizeof(buffer)); + psyc_render(&packet, buffer, sizeof(buffer)); write(0, buffer, packet.length); /* - PSYC_RenderState *pb; // a chunk of mem will host both struct and buf1 + psycRenderState *pb; // a chunk of mem will host both struct and buf1 // char *t; // unsigned int l; @@ -46,20 +47,20 @@ int writePresence(const char *avail, int availlen, const char *desc, int desclen P0(("Out of memory\n")) return -1; } -// if (PSYC_initBuffer(pb, WHATEVER)) die("PSYC_initBuffer hates me"); +// if (psyc_initBuffer(pb, WHATEVER)) die("psyc_initBuffer hates me"); - (void) PSYC_renderModifier(pb, "_context", 0, + (void) psyc_renderModifier(pb, "_context", 0, myUNI, sizeof(myUNI), PSYC_RENDER_ROUTING, 0); - // the first call to PSYC_renderHeader() without PSYC_RENDER_ROUTING adds the + // the first call to psyc_renderHeader() without PSYC_RENDER_ROUTING adds the // extra newline to the buffer. later vars with PSYC_RENDER_ROUTING cause an error. - (void) PSYC_renderModifier(pb, "_degree_availability", 0, avail, availlen, 0, C_GLYPH_OPERATOR_ASSIGN); - (void) PSYC_renderModifier(pb, "_description_presence", 0, desc, desclen, 0, C_GLYPH_OPERATOR_ASSIGN); + (void) psyc_renderModifier(pb, "_degree_availability", 0, avail, availlen, 0, C_GLYPH_OPERATOR_ASSIGN); + (void) psyc_renderModifier(pb, "_description_presence", 0, desc, desclen, 0, C_GLYPH_OPERATOR_ASSIGN); // presence is to be assigned permanently in distributed state - (void) PSYC_renderBody(pb, "_notice_presence", 0, + (void) psyc_renderBody(pb, "_notice_presence", 0, NULL, 0); // no data in packet -// (void) PSYC_doneRender(pb, &t, &l); +// (void) psyc_doneRender(pb, &t, &l); // write(stdout, t, l); free(pb); */ From b5f604c352be82e78d63c0b160e4761265bdfa27 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Mon, 25 Apr 2011 23:49:27 +0200 Subject: [PATCH 096/378] testRender now automaticable --- test/testRender.c | 50 ++++++++++++----------------------------------- 1 file changed, 13 insertions(+), 37 deletions(-) diff --git a/test/testRender.c b/test/testRender.c index 9244f68..58d86ca 100644 --- a/test/testRender.c +++ b/test/testRender.c @@ -7,11 +7,11 @@ #define myUNI "psyc://10.100.1000/~ludwig" /* example renderer generating a presence packet */ -int writePresence(const char *avail, int availlen, const char *desc, int desclen) +int testPresence(const char *avail, int availlen, const char *desc, int desclen, const char *rendered) { psycModifier routing[] = { - psyc_newModifier2(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_source"), PSYC_C2ARG(myUNI), - PSYC_MODIFIER_ROUTING), +// psyc_newModifier2(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_source"), PSYC_C2ARG(myUNI), +// PSYC_MODIFIER_ROUTING), psyc_newModifier2(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_context"), PSYC_C2ARG(myUNI), PSYC_MODIFIER_ROUTING), }; @@ -33,41 +33,17 @@ int writePresence(const char *avail, int availlen, const char *desc, int desclen char buffer[512]; psyc_render(&packet, buffer, sizeof(buffer)); - write(0, buffer, packet.length); - -/* - psycRenderState *pb; // a chunk of mem will host both struct and buf1 -// char *t; -// unsigned int l; - - unless (availlen) availlen = strlen(avail); - unless (desclen) desclen = strlen(desc); - - if (!(pb = malloc(512))) { - P0(("Out of memory\n")) - return -1; - } -// if (psyc_initBuffer(pb, WHATEVER)) die("psyc_initBuffer hates me"); - - (void) psyc_renderModifier(pb, "_context", 0, - myUNI, sizeof(myUNI), PSYC_RENDER_ROUTING, 0); - - // the first call to psyc_renderHeader() without PSYC_RENDER_ROUTING adds the - // extra newline to the buffer. later vars with PSYC_RENDER_ROUTING cause an error. - (void) psyc_renderModifier(pb, "_degree_availability", 0, avail, availlen, 0, C_GLYPH_OPERATOR_ASSIGN); - (void) psyc_renderModifier(pb, "_description_presence", 0, desc, desclen, 0, C_GLYPH_OPERATOR_ASSIGN); - // presence is to be assigned permanently in distributed state - - (void) psyc_renderBody(pb, "_notice_presence", 0, - NULL, 0); // no data in packet -// (void) psyc_doneRender(pb, &t, &l); -// write(stdout, t, l); - free(pb); -*/ - return 0; + // write(0, buffer, packet.length); + return strncmp(rendered, buffer, packet.length); } - int main() { - return writePresence(PSYC_C2ARG("_here"), PSYC_C2ARG("I'm omnipresent right now")); + return testPresence(PSYC_C2ARG("_here"), PSYC_C2ARG("I'm omnipresent right now"), "\ +:_context\tpsyc://10.100.1000/~ludwig\n\ +\n\ +=_degree_availability\t_here\n\ +=_description_presence\tI'm omnipresent right now\n\ +_notice_presence\n\ +|\n"); + } From a214bb2cae414576563a42d4850388b6d60dd816 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Mon, 25 Apr 2011 23:58:07 +0200 Subject: [PATCH 097/378] automizable psyc_isRoutingVar tests --- test/Makefile | 3 +++ test/isRoutingVar.c | 18 +++++++++++++++--- test/testRender.c | 7 ++++--- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/test/Makefile b/test/Makefile index 459d777..4de85e1 100644 --- a/test/Makefile +++ b/test/Makefile @@ -4,6 +4,9 @@ LOADLIBES=-lpsyc -lm TARGETS=testParser testMatch testRender isRoutingVar all: $(TARGETS) + ./testRender + ./testMatch + ./isRoutingVar test: for f in packets/*; do echo -e "\n>> $$f"; ./testParser $$f; done diff --git a/test/isRoutingVar.c b/test/isRoutingVar.c index 02b1fd8..c0eacd8 100644 --- a/test/isRoutingVar.c +++ b/test/isRoutingVar.c @@ -2,9 +2,10 @@ #include #include #include +#include "../include/psyc/lib.h" -int main(int argc, char** argv) -{ +int main() { +#if 0 const char* vars[] = { "_source", @@ -22,6 +23,17 @@ int main(int argc, char** argv) printf(">> %s: %d %d\n", vars[i], sizeof(vars[i]), sizeof(*vars[i])); printf("%s: %d\n", vars[i], psyc_isRoutingVar(vars[i], strlen(vars[i]))); } +#else + unless (psyc_isRoutingVar(PSYC_C2ARG("_source"))) return -1; + unless (psyc_isRoutingVar(PSYC_C2ARG("_source_relay"))) return -2; + if (psyc_isRoutingVar(PSYC_C2ARG("_source_foo"))) return -3; + if (psyc_isRoutingVar(PSYC_C2ARG("_sourcherry"))) return -4; + if (psyc_isRoutingVar(PSYC_C2ARG("_sour"))) return -5; + if (psyc_isRoutingVar(PSYC_C2ARG("_foo"))) return -6; + if (psyc_isRoutingVar(PSYC_C2ARG("bar"))) return -7; + if (psyc_isRoutingVar(PSYC_C2ARG("_"))) return -8; - return 0; + puts("psyc_isRoutingVar passed all tests."); +#endif + return 0; // passed all tests } diff --git a/test/testRender.c b/test/testRender.c index 58d86ca..c51c4d2 100644 --- a/test/testRender.c +++ b/test/testRender.c @@ -38,12 +38,13 @@ int testPresence(const char *avail, int availlen, const char *desc, int desclen, } int main() { - return testPresence(PSYC_C2ARG("_here"), PSYC_C2ARG("I'm omnipresent right now"), "\ -:_context\tpsyc://10.100.1000/~ludwig\n\ + int rc = testPresence(PSYC_C2ARG("_here"), PSYC_C2ARG("I'm omnipresent right now"), "\ +:_context\t" myUNI "\n\ \n\ =_degree_availability\t_here\n\ =_description_presence\tI'm omnipresent right now\n\ _notice_presence\n\ |\n"); - + unless (rc) puts("psyc_render passed the test."); + return rc; } From ad415322eb8b1d9e738b500f0a3f06034af8d872 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Tue, 26 Apr 2011 00:10:02 +0200 Subject: [PATCH 098/378] not automatic yet, but at least it exits cleanly --- test/Makefile | 4 ++-- test/packets/enter_leave_context.txt | 1 - test/packets/fake_dns.txt | 1 - test/packets/invalid_dns.txt | 1 - test/packets/test-1 | 1 - test/packets/test-1-length | 1 - test/packets/test-1-length-error | 1 - test/packets/test-1-utf8 | 1 - test/packets/test-2-list | 1 - test/packets/test-2-list-error | 1 - test/packets/test-3-list | 1 - test/packets/test-4-circuit | 1 - test/packets/test-5-message-private | 1 - test/packets/test-6-message-private-remote | 1 - test/testParser.c | 20 ++++++++++++-------- 15 files changed, 14 insertions(+), 23 deletions(-) diff --git a/test/Makefile b/test/Makefile index 4de85e1..58118ee 100644 --- a/test/Makefile +++ b/test/Makefile @@ -8,8 +8,8 @@ all: $(TARGETS) ./testMatch ./isRoutingVar -test: - for f in packets/*; do echo -e "\n>> $$f"; ./testParser $$f; done +test: $(TARGETS) + for f in packets/*; do echo "\n>> $$f"; ./testParser $$f; done clean: rm -f $(TARGETS) diff --git a/test/packets/enter_leave_context.txt b/test/packets/enter_leave_context.txt index b201ad9..b17078e 100644 --- a/test/packets/enter_leave_context.txt +++ b/test/packets/enter_leave_context.txt @@ -1,4 +1,3 @@ -| :_target psyc://p5B084547.dip.t-dialin.net/@test :_source something diff --git a/test/packets/fake_dns.txt b/test/packets/fake_dns.txt index 78deab0..066e28e 100644 --- a/test/packets/fake_dns.txt +++ b/test/packets/fake_dns.txt @@ -1,4 +1,3 @@ -| :_source psyc://heise.de/~user _request_some_things diff --git a/test/packets/invalid_dns.txt b/test/packets/invalid_dns.txt index 689e8d7..18e195d 100644 --- a/test/packets/invalid_dns.txt +++ b/test/packets/invalid_dns.txt @@ -1,4 +1,3 @@ -| :_source psyc://nonexisting.dns.tld/~user _request_some_things diff --git a/test/packets/test-1 b/test/packets/test-1 index 376237c..02ea1a6 100644 --- a/test/packets/test-1 +++ b/test/packets/test-1 @@ -1,4 +1,3 @@ -| :_source psyc://foo/~bar :_target psyc://bar/~baz :_tag sch1828hu3r2cm diff --git a/test/packets/test-1-length b/test/packets/test-1-length index 2c84573..6bbd234 100644 --- a/test/packets/test-1-length +++ b/test/packets/test-1-length @@ -1,4 +1,3 @@ -| :_source psyc://foo/~bar :_target psyc://bar/~baz :_tag sch1828hu3r2cm diff --git a/test/packets/test-1-length-error b/test/packets/test-1-length-error index 98a6bf6..21c91fe 100644 --- a/test/packets/test-1-length-error +++ b/test/packets/test-1-length-error @@ -1,4 +1,3 @@ -| :_source psyc://foo/~bar :_target psyc://bar/~baz :_tag sch1828hu3r2cm diff --git a/test/packets/test-1-utf8 b/test/packets/test-1-utf8 index b054c27..e1de776 100644 --- a/test/packets/test-1-utf8 +++ b/test/packets/test-1-utf8 @@ -1,4 +1,3 @@ -| :_source psyc://foo/~bar :_target psyc://bar/~baz :_tag sch1828hu3r2cm diff --git a/test/packets/test-2-list b/test/packets/test-2-list index ebff895..02202d2 100644 --- a/test/packets/test-2-list +++ b/test/packets/test-2-list @@ -1,4 +1,3 @@ -| =_source psyc://foo/~bar :_target psyc://bar/~baz =_list_foo |foo|bar|baz diff --git a/test/packets/test-2-list-error b/test/packets/test-2-list-error index cbae3e6..b6ce6d5 100644 --- a/test/packets/test-2-list-error +++ b/test/packets/test-2-list-error @@ -1,4 +1,3 @@ -| =_source psyc://foo/~bar :_target psyc://bar/~baz =_list_foo foo|bar|baz diff --git a/test/packets/test-3-list b/test/packets/test-3-list index 4776f47..222c726 100644 --- a/test/packets/test-3-list +++ b/test/packets/test-3-list @@ -1,4 +1,3 @@ -| =_source psyc://foo/~bar :_target psyc://bar/~baz =_list_foo |foo|bar|baz diff --git a/test/packets/test-4-circuit b/test/packets/test-4-circuit index 024937f..a9d3aec 100644 --- a/test/packets/test-4-circuit +++ b/test/packets/test-4-circuit @@ -1,4 +1,3 @@ -| :_list_understand_modules _state|_fragments|_context _request_features diff --git a/test/packets/test-5-message-private b/test/packets/test-5-message-private index 6cfb1bb..4ea0f79 100644 --- a/test/packets/test-5-message-private +++ b/test/packets/test-5-message-private @@ -1,4 +1,3 @@ -| :_source psyc://nb.tgbit.net/~foo :_target psyc://nb.tgbit.net/~bar :_tag f00b4rb4z diff --git a/test/packets/test-6-message-private-remote b/test/packets/test-6-message-private-remote index 28d9641..2c2464d 100644 --- a/test/packets/test-6-message-private-remote +++ b/test/packets/test-6-message-private-remote @@ -1,4 +1,3 @@ -| :_source psyc://nb.tgbit.net/~foo :_target psyc://nb2.tgbit.net/~bar :_tag f00b4rb4z diff --git a/test/testParser.c b/test/testParser.c index d039a72..9d86126 100644 --- a/test/testParser.c +++ b/test/testParser.c @@ -17,16 +17,18 @@ int main(int argc, char** argv) return -1; indx = read(file,(void*)buffer,sizeof(buffer)); - write(1, ">> INPUT\n", 9); - write(1, buffer, indx); - write(1, ">> PARSE\n", 9); +// write(1, ">> INPUT\n", 9); +// write(1, buffer, indx); +// write(1, ">> PARSE\n", 9); psyc_initParseState(&state); psyc_nextParseBuffer(&state, psyc_newString(buffer, indx)); // try parsing that now - while ((ret = psyc_parse(&state, &oper, &name, &value))) - { +// while ((ret = psyc_parse(&state, &oper, &name, &value))) +// { + do { + ret = psyc_parse(&state, &oper, &name, &value); switch (ret) { case PSYC_PARSE_ROUTING: @@ -67,15 +69,17 @@ int main(int argc, char** argv) } break; case PSYC_PARSE_COMPLETE: - printf("Done parsing.\n"); + // printf("Done parsing.\n"); + ret = 0; continue; case PSYC_PARSE_INSUFFICIENT: printf("Insufficient data.\n"); - return 0; + return -1; default: printf("Error while parsing: %i\n", ret); return 1; } - } + } while (ret); + return 0; } From 7e29ca4e5abcbc212a4630dd80b133f9ed96a32a Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 26 Apr 2011 03:43:49 +0200 Subject: [PATCH 099/378] parser: fix for empty data, testParser: verbose mode --- src/parser.c | 12 ++++++----- test/Makefile | 2 +- test/packets/test-4-circuit | 2 +- test/packets/test-4-circuit-n | 4 ---- test/testParser.c | 38 +++++++++++++++++++++-------------- 5 files changed, 32 insertions(+), 26 deletions(-) delete mode 100644 test/packets/test-4-circuit-n diff --git a/src/parser.c b/src/parser.c index 8025b07..6785514 100644 --- a/src/parser.c +++ b/src/parser.c @@ -354,18 +354,20 @@ psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psyc { while (1) { - if (state->buffer.ptr[state->cursor] == '\n') + uint8_t nl = state->buffer.ptr[state->cursor] == '\n'; + // check for |\n if we're at the start of data or we have found a \n + if (state->cursor == state->startc || nl) { - if (state->cursor+2 >= state->buffer.length) // incremented cursor inside length? + if (state->cursor+1+nl >= state->buffer.length) // incremented cursor inside length? { state->cursor = state->startc; return PSYC_PARSE_INSUFFICIENT; } - if (state->buffer.ptr[state->cursor+1] == '|' && - state->buffer.ptr[state->cursor+2] == '\n') // packet ends here + if (state->buffer.ptr[state->cursor+nl] == '|' && + state->buffer.ptr[state->cursor+1+nl] == '\n') // packet ends here { - state->cursor++; + state->cursor += nl; state->part = PSYC_PART_END; return PSYC_PARSE_BODY; } diff --git a/test/Makefile b/test/Makefile index 58118ee..0503d44 100644 --- a/test/Makefile +++ b/test/Makefile @@ -9,7 +9,7 @@ all: $(TARGETS) ./isRoutingVar test: $(TARGETS) - for f in packets/*; do echo "\n>> $$f"; ./testParser $$f; done + for f in packets/*; do echo ">> $$f"; ./testParser $$f; done clean: rm -f $(TARGETS) diff --git a/test/packets/test-4-circuit b/test/packets/test-4-circuit index a9d3aec..5905f2b 100644 --- a/test/packets/test-4-circuit +++ b/test/packets/test-4-circuit @@ -1,4 +1,4 @@ -:_list_understand_modules _state|_fragments|_context +:_list_understand_modules |_state|_fragments|_context _request_features | diff --git a/test/packets/test-4-circuit-n b/test/packets/test-4-circuit-n deleted file mode 100644 index a9d3aec..0000000 --- a/test/packets/test-4-circuit-n +++ /dev/null @@ -1,4 +0,0 @@ -:_list_understand_modules _state|_fragments|_context - -_request_features -| diff --git a/test/testParser.c b/test/testParser.c index 9d86126..e3b0a0d 100644 --- a/test/testParser.c +++ b/test/testParser.c @@ -6,7 +6,7 @@ int main(int argc, char** argv) { - int indx, ret; + int indx, ret, verbose = argc > 2; char buffer[2048], oper; psycString name, value, elem; psycParseState state; @@ -17,10 +17,11 @@ int main(int argc, char** argv) return -1; indx = read(file,(void*)buffer,sizeof(buffer)); -// write(1, ">> INPUT\n", 9); -// write(1, buffer, indx); -// write(1, ">> PARSE\n", 9); - + if (verbose) { + write(1, ">> INPUT\n", 9); + write(1, buffer, indx); + write(1, ">> PARSE\n", 9); + } psyc_initParseState(&state); psyc_nextParseBuffer(&state, psyc_newString(buffer, indx)); @@ -33,16 +34,20 @@ int main(int argc, char** argv) { case PSYC_PARSE_ROUTING: case PSYC_PARSE_ENTITY: - write(1, &oper, 1); + if (verbose) + write(1, &oper, 1); case PSYC_PARSE_BODY: // printf("the string is '%.*s'\n", name); - write(1, name.ptr, name.length); - write(1, " = ", 3); - write(1, value.ptr, value.length); - write(1, "\n", 1); + if (verbose) { + write(1, name.ptr, name.length); + write(1, " = ", 3); + write(1, value.ptr, value.length); + write(1, "\n", 1); + } if (memcmp(name.ptr, "_list", 5) == 0) { - write(1, ">>> LIST START\n", 15); + if (verbose) + write(1, ">>> LIST START\n", 15); psyc_initParseListState(&listState); psyc_nextParseListBuffer(&listState, value); while ((ret = psyc_parseList(&listState, &name, &value, &elem))) @@ -51,9 +56,11 @@ int main(int argc, char** argv) { case PSYC_PARSE_LIST_END: case PSYC_PARSE_LIST_ELEM: - write(1, "|", 1); - write(1, elem.ptr, elem.length); - write(1, "\n", 1); + if (verbose) { + write(1, "|", 1); + write(1, elem.ptr, elem.length); + write(1, "\n", 1); + } break; default: printf("Error while parsing list: %i\n", ret); @@ -62,7 +69,8 @@ int main(int argc, char** argv) if (ret == PSYC_PARSE_LIST_END) { - write(1, ">>> LIST END\n", 13); + if (verbose) + write(1, ">>> LIST END\n", 13); break; } } From 7a225b79c55db665652b77756af2672177d840ac Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 26 Apr 2011 17:23:06 +0200 Subject: [PATCH 100/378] list rendering --- include/psyc.h | 27 ++++++++++--- include/psyc/render.h | 5 +++ src/packet.c | 64 ++++++++++++++++++++++++------- src/render.c | 53 +++++++++++++++++++++----- test/testRender.c | 88 +++++++++++++++++++++++++++++++++++++------ 5 files changed, 198 insertions(+), 39 deletions(-) diff --git a/include/psyc.h b/include/psyc.h index 9ec6cbb..8752748 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -87,6 +87,13 @@ typedef enum PSYC_MODIFIER_ROUTING = 3, } psycModifierFlag; +typedef enum +{ + PSYC_LIST_CHECK_LENGTH = 0, + PSYC_LIST_NEED_LENGTH = 1, + PSYC_LIST_NO_LENGTH = 2, +} psycListFlag; + typedef enum { PSYC_PACKET_CHECK_LENGTH = 0, @@ -126,13 +133,21 @@ typedef struct { size_t lines; psycModifier *modifiers; -} psycModifierArray; +} psycHeader; + +typedef struct +{ + size_t num_elems; + psycString *elems; + size_t length; + psycListFlag flag; +} psycList; /* intermediate struct for a PSYC packet */ typedef struct { - psycModifierArray routing; ///< Routing header. - psycModifierArray entity; ///< Entitiy header. + psycHeader routing; ///< Routing header. + psycHeader entity; ///< Entitiy header. psycString method; psycString data; size_t routingLength; ///< Length of routing part. @@ -151,8 +166,10 @@ inline psycModifier psyc_newModifier2(char oper, const char *value, size_t valuelen, psycModifierFlag flag); -inline psycPacket psyc_newPacket(psycModifierArray *routing, - psycModifierArray *entity, +inline psycList psyc_newList(psycString *elems, size_t num_elems, psycListFlag flag); + +inline psycPacket psyc_newPacket(psycHeader *routing, + psycHeader *entity, psycString *method, psycString *data, psycPacketFlag flag); diff --git a/include/psyc/render.h b/include/psyc/render.h index 8c21e0b..c54a2b8 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -31,6 +31,11 @@ typedef enum */ psycRenderRC psyc_render(psycPacket *packet, char *buffer, size_t buflen); +/** + * Render a PSYC list into a buffer. + */ +inline psycRenderRC psyc_renderList(psycList *list, char *buffer, size_t buflen); + /* typedef enum { diff --git a/src/packet.c b/src/packet.c index 087c401..6bf4fb1 100644 --- a/src/packet.c +++ b/src/packet.c @@ -10,7 +10,7 @@ inline psycString psyc_newString(const char *str, size_t strlen) } inline psycModifier psyc_newModifier(char oper, psycString *name, psycString *value, - psycModifierFlag flag) + psycModifierFlag flag) { psycModifier m = {oper, *name, *value, flag}; @@ -28,9 +28,9 @@ inline psycModifier psyc_newModifier(char oper, psycString *name, psycString *va } inline psycModifier psyc_newModifier2(char oper, - const char *name, size_t namelen, - const char *value, size_t valuelen, - psycModifierFlag flag) + const char *name, size_t namelen, + const char *value, size_t valuelen, + psycModifierFlag flag) { psycString n = {namelen, name}; psycString v = {valuelen, value}; @@ -50,10 +50,46 @@ inline size_t psyc_getModifierLength(psycModifier *m) return length; } -inline psycPacket psyc_newPacket(psycModifierArray *routing, - psycModifierArray *entity, - psycString *method, psycString *data, - psycPacketFlag flag) +inline psycList psyc_newList(psycString *elems, size_t num_elems, psycListFlag flag) +{ + psycList list = {num_elems, elems, 0, flag}; + size_t i; + + if (flag == PSYC_LIST_CHECK_LENGTH) // check if list elements need length + { + for (i = 0; i < num_elems; i++) + { + if (memchr(elems[i].ptr, (int)'|', elems[i].length) || + memchr(elems[i].ptr, (int)'\n', elems[i].length)) + { + list.flag = PSYC_LIST_NEED_LENGTH; + break; + } + } + } + + if (list.flag == PSYC_LIST_NEED_LENGTH) + { + for (i = 0; i < num_elems; i++) + { + if (i > 0) + list.length++; // | + list.length += log10((double)elems[i].length) + 2 + elems[i].length; // length SP elem + } + } + else + { + for (i = 0; i < num_elems; i++) + list.length += 1 + elems[i].length; // |elem + } + + return list; +} + +inline psycPacket psyc_newPacket(psycHeader *routing, + psycHeader *entity, + psycString *method, psycString *data, + psycPacketFlag flag) { psycPacket p = {*routing, *entity, *method, *data, 0, 0, flag}; size_t i; @@ -93,13 +129,13 @@ inline psycPacket psyc_newPacket(psycModifierArray *routing, } inline psycPacket psyc_newPacket2(psycModifier *routing, size_t routinglen, - psycModifier *entity, size_t entitylen, - const char *method, size_t methodlen, - const char *data, size_t datalen, - psycPacketFlag flag) + psycModifier *entity, size_t entitylen, + const char *method, size_t methodlen, + const char *data, size_t datalen, + psycPacketFlag flag) { - psycModifierArray r = {routinglen, routing}; - psycModifierArray e = {entitylen, entity}; + psycHeader r = {routinglen, routing}; + psycHeader e = {entitylen, entity}; psycString m = {methodlen, method}; psycString d = {datalen, data}; diff --git a/src/render.c b/src/render.c index f78fcd9..1059e5c 100644 --- a/src/render.c +++ b/src/render.c @@ -2,23 +2,58 @@ #include "psyc/render.h" #include "psyc/syntax.h" -inline size_t psyc_renderModifier(psycModifier *m, char *buffer) +inline psycRenderRC psyc_renderList(psycList *list, char *buffer, size_t buflen) +{ + size_t i, cur = 0; + psycString *elem; + + if (list->length > buflen) + return PSYC_RENDER_ERROR; // return error if list doesn't fit in buffer + + if (list->flag == PSYC_LIST_NEED_LENGTH) + { + for (i = 0; i < list->num_elems; i++) + { + elem = &list->elems[i]; + if (i > 0) + buffer[cur++] = '|'; + cur += itoa(elem->length, buffer + cur, 10); + buffer[cur++] = ' '; + memcpy(buffer + cur, elem->ptr, elem->length); + cur += elem->length; + } + } + else + { + for (i = 0; i < list->num_elems; i++) + { + elem = &list->elems[i]; + buffer[cur++] = '|'; + memcpy(buffer + cur, elem->ptr, elem->length); + cur += elem->length; + } + } + + return PSYC_RENDER_SUCCESS; +} + +inline size_t psyc_renderModifier(psycModifier *mod, char *buffer) { size_t cur = 0; - buffer[cur++] = m->oper; - memcpy(buffer + cur, m->name.ptr, m->name.length); - cur += m->name.length; - if (m->flag == PSYC_MODIFIER_NEED_LENGTH) + buffer[cur++] = mod->oper; + memcpy(buffer + cur, mod->name.ptr, mod->name.length); + cur += mod->name.length; + if (mod->flag == PSYC_MODIFIER_NEED_LENGTH) { buffer[cur++] = ' '; - //cur += sprintf(buffer + cur, "%ld", m->value.length); - cur += itoa(m->value.length, buffer + cur, 10); + //cur += sprintf(buffer + cur, "%ld", mod->value.length); + cur += itoa(mod->value.length, buffer + cur, 10); } buffer[cur++] = '\t'; - memcpy(buffer + cur, m->value.ptr, m->value.length); - cur += m->value.length; + memcpy(buffer + cur, mod->value.ptr, mod->value.length); + cur += mod->value.length; buffer[cur++] = '\n'; return cur; diff --git a/test/testRender.c b/test/testRender.c index c51c4d2..5e5cf15 100644 --- a/test/testRender.c +++ b/test/testRender.c @@ -7,11 +7,9 @@ #define myUNI "psyc://10.100.1000/~ludwig" /* example renderer generating a presence packet */ -int testPresence(const char *avail, int availlen, const char *desc, int desclen, const char *rendered) +int testPresence(const char *avail, int availlen, const char *desc, int desclen, const char *rendered, uint8_t verbose) { psycModifier routing[] = { -// psyc_newModifier2(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_source"), PSYC_C2ARG(myUNI), -// PSYC_MODIFIER_ROUTING), psyc_newModifier2(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_context"), PSYC_C2ARG(myUNI), PSYC_MODIFIER_ROUTING), }; @@ -19,9 +17,9 @@ int testPresence(const char *avail, int availlen, const char *desc, int desclen, psycModifier entity[] = { // presence is to be assigned permanently in distributed state psyc_newModifier2(C_GLYPH_OPERATOR_ASSIGN, PSYC_C2ARG("_degree_availability"), - avail, availlen, PSYC_PACKET_CHECK_LENGTH), + avail, availlen, PSYC_MODIFIER_CHECK_LENGTH), psyc_newModifier2(C_GLYPH_OPERATOR_ASSIGN, PSYC_C2ARG("_description_presence"), - desc, desclen, PSYC_PACKET_CHECK_LENGTH), + desc, desclen, PSYC_MODIFIER_CHECK_LENGTH), }; psycPacket packet = psyc_newPacket2(routing, PSYC_NUM_ELEM(routing), @@ -33,18 +31,86 @@ int testPresence(const char *avail, int availlen, const char *desc, int desclen, char buffer[512]; psyc_render(&packet, buffer, sizeof(buffer)); - // write(0, buffer, packet.length); + if (verbose) + write(0, buffer, packet.length); return strncmp(rendered, buffer, packet.length); } -int main() { - int rc = testPresence(PSYC_C2ARG("_here"), PSYC_C2ARG("I'm omnipresent right now"), "\ +int testList(const char *rendered, uint8_t verbose) +{ + psycModifier routing[] = { + psyc_newModifier2(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_source"), PSYC_C2ARG(myUNI), + PSYC_MODIFIER_ROUTING), + psyc_newModifier2(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_context"), PSYC_C2ARG(myUNI), + PSYC_MODIFIER_ROUTING), + }; + + psycString elems_text[] = { + PSYC_C2STR("foo"), + PSYC_C2STR("bar"), + PSYC_C2STR("baz"), + }; + + psycString elems_bin[] = { + PSYC_C2STR("foo"), + PSYC_C2STR("b|r"), + PSYC_C2STR("baz\nqux"), + }; + + psycList list_text, list_bin; + list_text = psyc_newList(elems_text, PSYC_NUM_ELEM(elems_text), PSYC_LIST_CHECK_LENGTH); + list_bin = psyc_newList(elems_bin, PSYC_NUM_ELEM(elems_bin), PSYC_LIST_CHECK_LENGTH); + + char buf_text[32], buf_bin[32]; + psyc_renderList(&list_text, buf_text, sizeof(buf_text)); + psyc_renderList(&list_bin, buf_bin, sizeof(buf_bin)); + + psycModifier entity[] = { + // presence is to be assigned permanently in distributed state + psyc_newModifier2(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_list_text"), + buf_text, list_text.length, list_text.flag), + psyc_newModifier2(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_list_binary"), + buf_bin, list_bin.length, list_text.flag), + }; + + psycPacket packet = psyc_newPacket2(routing, PSYC_NUM_ELEM(routing), + entity, PSYC_NUM_ELEM(entity), + PSYC_C2ARG("_test_list"), + PSYC_C2ARG("list test"), + PSYC_PACKET_CHECK_LENGTH); + + char buffer[512]; + psyc_render(&packet, buffer, sizeof(buffer)); + if (verbose) + write(0, buffer, packet.length); + return strncmp(rendered, buffer, packet.length); +} + +int main(int argc, char* argv[]) { + uint8_t verbose = argc > 1; + + if (testPresence(PSYC_C2ARG("_here"), PSYC_C2ARG("I'm omnipresent right now"), "\ :_context\t" myUNI "\n\ \n\ =_degree_availability\t_here\n\ =_description_presence\tI'm omnipresent right now\n\ _notice_presence\n\ -|\n"); - unless (rc) puts("psyc_render passed the test."); - return rc; +|\n", verbose)) + return -1; + + if (testList("\ +:_source psyc://10.100.1000/~ludwig\n\ +:_context psyc://10.100.1000/~ludwig\n\ +\n\ +:_list_text |foo|bar|baz\n\ +:_list_binary 21 3 foo|3 b|r|7 baz\n\ +qux\n\ +_test_list\n\ +list test\n\ +|\n", verbose)) + return -2; + + puts("psyc_render passed all tests."); + + return 0; } From 8ed84b967d8835ca5d94715444efe40a5463a59e Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 26 Apr 2011 19:17:33 +0200 Subject: [PATCH 101/378] + --- test/testRender.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/testRender.c b/test/testRender.c index 5e5cf15..0bdddda 100644 --- a/test/testRender.c +++ b/test/testRender.c @@ -26,7 +26,6 @@ int testPresence(const char *avail, int availlen, const char *desc, int desclen, entity, PSYC_NUM_ELEM(entity), PSYC_C2ARG("_notice_presence"), NULL, 0, - //PSYC_C2ARG("foobar"), PSYC_PACKET_CHECK_LENGTH); char buffer[512]; @@ -66,7 +65,6 @@ int testList(const char *rendered, uint8_t verbose) psyc_renderList(&list_bin, buf_bin, sizeof(buf_bin)); psycModifier entity[] = { - // presence is to be assigned permanently in distributed state psyc_newModifier2(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_list_text"), buf_text, list_text.length, list_text.flag), psyc_newModifier2(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_list_binary"), From e77cb20b70d6f83266f1915cf14806e40cf841c3 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 26 Apr 2011 22:44:48 +0200 Subject: [PATCH 102/378] render: restructuring into more functions, added some docs --- include/psyc.h | 47 +++++++++--- src/packet.c | 181 ++++++++++++++++++++++++++++------------------ test/testParser.c | 17 +++-- test/testRender.c | 12 +-- 4 files changed, 160 insertions(+), 97 deletions(-) diff --git a/include/psyc.h b/include/psyc.h index 8752748..149b903 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -147,7 +147,7 @@ typedef struct typedef struct { psycHeader routing; ///< Routing header. - psycHeader entity; ///< Entitiy header. + psycHeader entity; ///< Entitiy header. psycString method; psycString data; size_t routingLength; ///< Length of routing part. @@ -158,26 +158,49 @@ typedef struct inline int psyc_version(); +/** Check if a modifier needs length */ +inline psycModifierFlag psyc_checkModifierLength(psycModifier *m); + +/** Get the total length of a modifier. */ +inline size_t psyc_getModifierLength(psycModifier *m); + +/** Create new modifier */ inline psycModifier psyc_newModifier(char oper, psycString *name, psycString *value, + psycModifierFlag flag); + +/** Create new modifier */ +inline psycModifier psyc_newModifier2(char oper, + const char *name, size_t namelen, + const char *value, size_t valuelen, psycModifierFlag flag); -inline psycModifier psyc_newModifier2(char oper, - const char *name, size_t namelen, - const char *value, size_t valuelen, - psycModifierFlag flag); +/** Check if a list needs length */ +inline psycListFlag psyc_checkListLength(psycList *list); +/** Get the total length of a list. */ +inline psycListFlag psyc_getListLength(psycList *list); + +/** Check if a packet needs length */ +inline psycPacketFlag psyc_checkPacketLength(psycPacket *p); + +/** Calculate and set the length of packet parts and total packet length */ +inline size_t psyc_setPacketLength(psycPacket *p); + +/** Create new list */ inline psycList psyc_newList(psycString *elems, size_t num_elems, psycListFlag flag); +/** Create new packet */ inline psycPacket psyc_newPacket(psycHeader *routing, - psycHeader *entity, - psycString *method, psycString *data, - psycPacketFlag flag); + psycHeader *entity, + psycString *method, psycString *data, + psycPacketFlag flag); +/** Create new packet */ inline psycPacket psyc_newPacket2(psycModifier *routing, size_t routinglen, - psycModifier *entity, size_t entitylen, - const char *method, size_t methodlen, - const char *data, size_t datalen, - psycPacketFlag flag); + psycModifier *entity, size_t entitylen, + const char *method, size_t methodlen, + const char *data, size_t datalen, + psycPacketFlag flag); /// Routing vars in alphabetical order. extern const psycString PSYC_routingVars[]; diff --git a/src/packet.c b/src/packet.c index 6bf4fb1..3676c2c 100644 --- a/src/packet.c +++ b/src/packet.c @@ -9,20 +9,39 @@ inline psycString psyc_newString(const char *str, size_t strlen) return s; } +inline psycModifierFlag psyc_checkModifierLength(psycModifier *m) +{ + psycModifierFlag flag; + + if (m->value.length > PSYC_MODIFIER_SIZE_THRESHOLD) + flag = PSYC_MODIFIER_NEED_LENGTH; + else if (memchr(m->value.ptr, (int)'\n', m->value.length)) + flag = PSYC_MODIFIER_NEED_LENGTH; + else + flag = PSYC_MODIFIER_NO_LENGTH; + + return flag; +} + +inline size_t psyc_getModifierLength(psycModifier *m) +{ + size_t length = 1 + // oper + m->name.length + 1 + // name\t + m->value.length + 1; // value\n + + if (m->flag == PSYC_MODIFIER_NEED_LENGTH) // add length of length if needed + length += log10((double)m->value.length) + 2; // SP length + + return length; +} + inline psycModifier psyc_newModifier(char oper, psycString *name, psycString *value, psycModifierFlag flag) { psycModifier m = {oper, *name, *value, flag}; if (flag == PSYC_MODIFIER_CHECK_LENGTH) // find out if it needs a length - { - if (value->length > PSYC_MODIFIER_SIZE_THRESHOLD) - m.flag = PSYC_MODIFIER_NEED_LENGTH; - else if (memchr(value->ptr, (int)'\n', value->length)) - m.flag = PSYC_MODIFIER_NEED_LENGTH; - else - m.flag = PSYC_MODIFIER_NO_LENGTH; - } + m.flag = psyc_checkModifierLength(&m); return m; } @@ -38,14 +57,45 @@ inline psycModifier psyc_newModifier2(char oper, return psyc_newModifier(oper, &n, &v, flag); } -inline size_t psyc_getModifierLength(psycModifier *m) +inline psycListFlag psyc_checkListLength(psycList *list) { - size_t length = 1 + // oper - m->name.length + 1 + // name\t - m->value.length + 1; // value\n + psycListFlag flag = PSYC_LIST_NO_LENGTH; + size_t i, length = 0; - if (m->flag == PSYC_MODIFIER_NEED_LENGTH) // add length of length if needed - length += log10((double)m->value.length) + 2; // SP length + for (i = 0; i < list->num_elems; i++) + { + psycString *elem = &list->elems[i]; + length += 1 + elem->length; // |elem + if (length > PSYC_MODIFIER_SIZE_THRESHOLD || + memchr(elem->ptr, (int)'|', elem->length) || + memchr(elem->ptr, (int)'\n', elem->length)) + { + flag = PSYC_LIST_NEED_LENGTH; + break; + } + } + + return flag; +} + +inline psycListFlag psyc_getListLength(psycList *list) +{ + size_t i, length = 0; + + if (list->flag == PSYC_LIST_NEED_LENGTH) + { + for (i = 0; i < list->num_elems; i++) + { + if (i > 0) + length++; // | + length += log10((double)list->elems[i].length) + 2 + list->elems[i].length; // length SP elem + } + } + else + { + for (i = 0; i < list->num_elems; i++) + length += 1 + list->elems[i].length; // |elem + } return length; } @@ -53,78 +103,67 @@ inline size_t psyc_getModifierLength(psycModifier *m) inline psycList psyc_newList(psycString *elems, size_t num_elems, psycListFlag flag) { psycList list = {num_elems, elems, 0, flag}; - size_t i; if (flag == PSYC_LIST_CHECK_LENGTH) // check if list elements need length - { - for (i = 0; i < num_elems; i++) - { - if (memchr(elems[i].ptr, (int)'|', elems[i].length) || - memchr(elems[i].ptr, (int)'\n', elems[i].length)) - { - list.flag = PSYC_LIST_NEED_LENGTH; - break; - } - } - } - - if (list.flag == PSYC_LIST_NEED_LENGTH) - { - for (i = 0; i < num_elems; i++) - { - if (i > 0) - list.length++; // | - list.length += log10((double)elems[i].length) + 2 + elems[i].length; // length SP elem - } - } - else - { - for (i = 0; i < num_elems; i++) - list.length += 1 + elems[i].length; // |elem - } + list.flag = psyc_checkListLength(&list); + list.length = psyc_getListLength(&list); return list; } +inline psycPacketFlag psyc_checkPacketLength(psycPacket *p) +{ + psycPacketFlag flag; + + if (p->data.length == 1 && p->data.ptr[0] == C_GLYPH_PACKET_DELIMITER) + flag = PSYC_PACKET_NEED_LENGTH; + else if (p->data.length > PSYC_CONTENT_SIZE_THRESHOLD) + flag = PSYC_PACKET_NEED_LENGTH; + else if (memmem(p->data.ptr, p->data.length, PSYC_C2ARG(PSYC_PACKET_DELIMITER))) + flag = PSYC_PACKET_NEED_LENGTH; + else + flag = PSYC_PACKET_NO_LENGTH; + + return flag; +} + +inline size_t psyc_setPacketLength(psycPacket *p) +{ + size_t i; + + // add routing header length + for (i = 0; i < p->routing.lines; i++) + p->routingLength += psyc_getModifierLength(&(p->routing.modifiers[i])); + + // add entity header length + for (i = 0; i < p->entity.lines; i++) + p->contentLength += psyc_getModifierLength(&(p->entity.modifiers[i])); + + // add length of method, data & delimiter + if (p->method.length) + p->contentLength += p->method.length + 1; // method\n + if (p->data.length) + p->contentLength += p->data.length + 1; // data\n + + // set total length: routing-header \n content |\n + p->length = p->routingLength + 1 + p->contentLength + sizeof(PSYC_PACKET_DELIMITER) - 2; + if (p->flag == PSYC_PACKET_NEED_LENGTH) // add length of length if needed + p->length += log10((double)p->data.length) + 1; + + return p->length; +} + inline psycPacket psyc_newPacket(psycHeader *routing, psycHeader *entity, psycString *method, psycString *data, psycPacketFlag flag) { psycPacket p = {*routing, *entity, *method, *data, 0, 0, flag}; - size_t i; if (flag == PSYC_PACKET_CHECK_LENGTH) // find out if it needs a length - { - if (data->length == 1 && data->ptr[0] == C_GLYPH_PACKET_DELIMITER) - p.flag = PSYC_PACKET_NEED_LENGTH; - else if (data->length > PSYC_CONTENT_SIZE_THRESHOLD) - p.flag = PSYC_PACKET_NEED_LENGTH; - else if (memmem(data->ptr, data->length, PSYC_C2ARG(PSYC_PACKET_DELIMITER))) - p.flag = PSYC_PACKET_NEED_LENGTH; - else - p.flag = PSYC_PACKET_NO_LENGTH; - } - - // add routing header length - for (i = 0; i < routing->lines; i++) - p.routingLength += psyc_getModifierLength(&routing->modifiers[i]); - - // add entity header length - for (i = 0; i < entity->lines; i++) - p.contentLength += psyc_getModifierLength(&entity->modifiers[i]); - - // add length of method, data & delimiter - if (method->length) - p.contentLength += method->length + 1; // method\n - if (data->length) - p.contentLength += data->length + 1; // data\n - - // set total length: routing-header \n content |\n - p.length = p.routingLength + 1 + p.contentLength + sizeof(PSYC_PACKET_DELIMITER) - 2; - if (flag == PSYC_PACKET_NEED_LENGTH) // add length of length if needed - p.length += log10((double)data->length) + 1; + p.flag = psyc_checkPacketLength(&p); + psyc_setPacketLength(&p); return p; } diff --git a/test/testParser.c b/test/testParser.c index e3b0a0d..0473e88 100644 --- a/test/testParser.c +++ b/test/testParser.c @@ -1,29 +1,30 @@ -#include -#include #include #include #include -int main(int argc, char** argv) +#include +#include + +int main(int argc, char **argv) { - int indx, ret, verbose = argc > 2; + int idx, ret, verbose = argc > 2; char buffer[2048], oper; psycString name, value, elem; psycParseState state; psycParseListState listState; int file = open(argv[1],O_RDONLY); - if(file < 0) + if (file < 0) return -1; - indx = read(file,(void*)buffer,sizeof(buffer)); + idx = read(file,(void*)buffer,sizeof(buffer)); if (verbose) { write(1, ">> INPUT\n", 9); - write(1, buffer, indx); + write(1, buffer, idx); write(1, ">> PARSE\n", 9); } psyc_initParseState(&state); - psyc_nextParseBuffer(&state, psyc_newString(buffer, indx)); + psyc_nextParseBuffer(&state, psyc_newString(buffer, idx)); // try parsing that now // while ((ret = psyc_parse(&state, &oper, &name, &value))) diff --git a/test/testRender.c b/test/testRender.c index 0bdddda..249ead2 100644 --- a/test/testRender.c +++ b/test/testRender.c @@ -23,10 +23,10 @@ int testPresence(const char *avail, int availlen, const char *desc, int desclen, }; psycPacket packet = psyc_newPacket2(routing, PSYC_NUM_ELEM(routing), - entity, PSYC_NUM_ELEM(entity), - PSYC_C2ARG("_notice_presence"), - NULL, 0, - PSYC_PACKET_CHECK_LENGTH); + entity, PSYC_NUM_ELEM(entity), + PSYC_C2ARG("_notice_presence"), + NULL, 0, + PSYC_PACKET_CHECK_LENGTH); char buffer[512]; psyc_render(&packet, buffer, sizeof(buffer)); @@ -68,7 +68,7 @@ int testList(const char *rendered, uint8_t verbose) psyc_newModifier2(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_list_text"), buf_text, list_text.length, list_text.flag), psyc_newModifier2(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_list_binary"), - buf_bin, list_bin.length, list_text.flag), + buf_bin, list_bin.length, list_bin.flag), }; psycPacket packet = psyc_newPacket2(routing, PSYC_NUM_ELEM(routing), @@ -84,7 +84,7 @@ int testList(const char *rendered, uint8_t verbose) return strncmp(rendered, buffer, packet.length); } -int main(int argc, char* argv[]) { +int main(int argc, char **argv) { uint8_t verbose = argc > 1; if (testPresence(PSYC_C2ARG("_here"), PSYC_C2ARG("I'm omnipresent right now"), "\ From 031d960a991c57fa5a7c03b1d9c303888a1007b7 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Tue, 26 Apr 2011 23:16:56 +0200 Subject: [PATCH 103/378] THAT'S where the bug was!?!?!!!! --- src/render.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/render.c b/src/render.c index 1059e5c..eb76494 100644 --- a/src/render.c +++ b/src/render.c @@ -91,7 +91,7 @@ psycRenderRC psyc_render(psycPacket *packet, char *buffer, size_t buflen) if (packet->data.length) // add data\n { - memcpy(buffer + cur, packet->data.ptr, packet->method.length); + memcpy(buffer + cur, packet->data.ptr, packet->data.length); cur += packet->data.length; buffer[cur++] = '\n'; } From f8d95ce640b23a4686b339a962c4c7d07233db55 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 27 Apr 2011 00:17:19 +0200 Subject: [PATCH 104/378] doc style fix --- Doxyfile | 2 +- doc/psyc.css | 3 --- doc/psyc.svg | 8 ++++---- 3 files changed, 5 insertions(+), 8 deletions(-) delete mode 100644 doc/psyc.css diff --git a/Doxyfile b/Doxyfile index 98a81ba..c504594 100644 --- a/Doxyfile +++ b/Doxyfile @@ -875,7 +875,7 @@ HTML_FOOTER = # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! -HTML_STYLESHEET = doc/psyc.css +#HTML_STYLESHEET = doc/psyc.css # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. # Doxygen will adjust the colors in the stylesheet and background images diff --git a/doc/psyc.css b/doc/psyc.css deleted file mode 100644 index afe3cac..0000000 --- a/doc/psyc.css +++ /dev/null @@ -1,3 +0,0 @@ -#projectlogo img { - height: 50px; -} diff --git a/doc/psyc.svg b/doc/psyc.svg index 9a9dbf3..b8ed42a 100644 --- a/doc/psyc.svg +++ b/doc/psyc.svg @@ -8,13 +8,13 @@ xmlns="http://www.w3.org/2000/svg" id="svg4025" version="1.1" - width="715.59717" - height="145.17674" + width="234" + height="50" xml:space="preserve"> Date: Wed, 27 Apr 2011 18:37:03 +0200 Subject: [PATCH 105/378] fixes for parsing partial packets --- include/psyc/parser.h | 19 ++++---- src/parser.c | 106 +++++++++++++++++++++++++++++++----------- 2 files changed, 89 insertions(+), 36 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index a81ba36..ffac7d9 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -30,11 +30,13 @@ typedef enum */ typedef enum { - PSYC_PARSE_ERROR_END = -7, - PSYC_PARSE_ERROR_METHOD = -6, - PSYC_PARSE_ERROR_VAR_LEN = -5, - PSYC_PARSE_ERROR_VAR_TAB = -4, - PSYC_PARSE_ERROR_VAR_NAME = -3, + PSYC_PARSE_ERROR_END = -9, + PSYC_PARSE_ERROR_BODY = -8, + PSYC_PARSE_ERROR_METHOD = -7, + PSYC_PARSE_ERROR_MOD_NL = -6, + PSYC_PARSE_ERROR_MOD_LEN = -5, + PSYC_PARSE_ERROR_MOD_TAB = -4, + PSYC_PARSE_ERROR_MOD_NAME = -3, PSYC_PARSE_ERROR_LENGTH = -2, PSYC_PARSE_ERROR = -1, PSYC_PARSE_SUCCESS = 0, @@ -42,13 +44,13 @@ typedef enum /// Fill another buffer and concatenate it with the end of the current buffer, /// from the cursor position to the end. PSYC_PARSE_INSUFFICIENT = 1, -/// Routing variable parsing done. +/// Routing modifier parsing done. /// Operator, name & value contains the respective parts. PSYC_PARSE_ROUTING = 2, -/// Entity variable parsing done. +/// Entity modifier parsing done. /// Operator, name & value contains the respective parts. PSYC_PARSE_ENTITY = 3, -/// Entity variable parsing is incomplete. +/// Entity modifier parsing is incomplete. /// Operator & name are complete, value is incomplete. PSYC_PARSE_ENTITY_INCOMPLETE = 4, /// Body parsing done, name contains method, value contains body. @@ -91,6 +93,7 @@ typedef struct uint8_t flags; ///< flags for the parser, see psycParseFlag psycPart part; ///< part of the packet being parsed currently + size_t routingLength; ///< length of routing part parsed so far size_t contentParsed; ///< number of bytes parsed from the content so far size_t contentLength; ///< expected length of the content psycBool contentLengthFound; ///< is there a length given for this packet? diff --git a/src/parser.c b/src/parser.c index 6785514..c90dd03 100644 --- a/src/parser.c +++ b/src/parser.c @@ -133,13 +133,15 @@ inline psycParseRC psyc_parseBinaryValue(psycParseState* state, psycString* valu if (state->cursor + remaining > state->buffer.length) // is the length larger than this buffer? { value->length = state->buffer.length - state->cursor; + state->cursor += value->length; *parsed += value->length; return PSYC_PARSE_INCOMPLETE; } - value->length += remaining; + value->length = remaining; state->cursor += remaining; - *parsed += value->length; + *parsed += remaining; + assert(*parsed == *length); return PSYC_PARSE_COMPLETE; } @@ -153,9 +155,13 @@ inline psycParseRC psyc_parseModifier(psycParseState* state, char* oper, psycStr *oper = *(state->buffer.ptr + state->cursor); ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); - if (psyc_parseName(state, name) != PSYC_PARSE_SUCCESS) - return PSYC_PARSE_ERROR_VAR_NAME; + psycParseRC ret = psyc_parseName(state, name); + if (ret == PSYC_PARSE_ERROR) + return PSYC_PARSE_ERROR_MOD_NAME; + else if (ret != PSYC_PARSE_SUCCESS) + return ret; + size_t length = 0; value->length = 0; state->valueLength = 0; state->valueParsed = 0; @@ -170,25 +176,25 @@ inline psycParseRC psyc_parseModifier(psycParseState* state, char* oper, psycStr { do { - state->valueLength = 10 * state->valueLength + state->buffer.ptr[state->cursor] - '0'; + length = 10 * length + state->buffer.ptr[state->cursor] - '0'; ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } while (isNumeric(state->buffer.ptr[state->cursor])); + state->valueLength = length; } else - return PSYC_PARSE_ERROR_VAR_LEN; + return PSYC_PARSE_ERROR_MOD_LEN; // After the length a TAB follows. if (state->buffer.ptr[state->cursor] != '\t') - return PSYC_PARSE_ERROR_VAR_TAB; + return PSYC_PARSE_ERROR_MOD_TAB; - if (state->buffer.length <= ++(state->cursor)) // Incremented cursor inside length? - return PSYC_PARSE_ENTITY_INCOMPLETE; + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INCOMPLETE); - if (psyc_parseBinaryValue(state, value, &(state->valueLength), &(state->valueParsed)) == PSYC_PARSE_INCOMPLETE) - return PSYC_PARSE_ENTITY_INCOMPLETE; + ret = psyc_parseBinaryValue(state, value, &(state->valueLength), &(state->valueParsed)); + if (ret == PSYC_PARSE_INCOMPLETE) + return ret; - state->cursor++; return PSYC_PARSE_SUCCESS; } else if (state->buffer.ptr[state->cursor] == '\t') // simple arg @@ -201,11 +207,11 @@ inline psycParseRC psyc_parseModifier(psycParseState* state, char* oper, psycStr value->length++; ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } - state->cursor++; + return PSYC_PARSE_SUCCESS; } else - return PSYC_PARSE_ERROR_VAR_TAB; + return PSYC_PARSE_ERROR_MOD_TAB; } /** @@ -214,7 +220,7 @@ inline psycParseRC psyc_parseModifier(psycParseState* state, char* oper, psycStr */ psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psycString* value) { - int ret; // a return value + psycParseRC ret; // a return value size_t pos; // a cursor position // Start position of the current line in the buffer @@ -230,6 +236,7 @@ psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psyc case PSYC_PART_RESET: // New packet starts here, reset state. state->valueParsed = 0; state->valueLength = 0; + state->routingLength = 0; state->contentParsed = 0; state->contentLength = 0; state->contentLengthFound = 0; @@ -237,12 +244,21 @@ psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psyc // fall thru case PSYC_PART_ROUTING: + pos = state->cursor; + if (state->routingLength > 0) + { + if (state->buffer.ptr[state->cursor] != '\n') + return PSYC_PARSE_ERROR_MOD_NL; + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + } + // 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_parseModifier(state, oper, name, value); + state->routingLength += state->cursor - pos; return ret == PSYC_PARSE_SUCCESS ? PSYC_PARSE_ROUTING : ret; } else // not a glyph @@ -293,7 +309,20 @@ psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psyc if (state->valueParsed < state->valueLength) { ret = psyc_parseBinaryValue(state, value, &(state->valueLength), &(state->valueParsed)); state->contentParsed += value->length; - return ret == PSYC_PARSE_COMPLETE ? PSYC_PARSE_ENTITY : PSYC_PARSE_ENTITY_INCOMPLETE; + + if (ret == PSYC_PARSE_INCOMPLETE) + return PSYC_PARSE_ENTITY_INCOMPLETE; + + return PSYC_PARSE_ENTITY; + } + + pos = state->cursor; + + if (state->contentParsed > 0) + { + if (state->buffer.ptr[state->cursor] != '\n') + return PSYC_PARSE_ERROR_MOD_NL; + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } // Each line of the header starts with a glyph, @@ -303,31 +332,45 @@ psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psyc // method does not start with a glyph. if (isGlyph(state->buffer.ptr[state->cursor])) { - pos = state->cursor; ret = psyc_parseModifier(state, oper, name, value); state->contentParsed += state->cursor - pos; - return ret == PSYC_PARSE_SUCCESS ? PSYC_PARSE_ENTITY : ret; + + if (ret == PSYC_PARSE_INCOMPLETE) + return PSYC_PARSE_ENTITY_INCOMPLETE; + else if (ret == PSYC_PARSE_SUCCESS) + return PSYC_PARSE_ENTITY; + + return ret; } else { - state->part = PSYC_PART_METHOD; + state->contentParsed += state->cursor - pos; state->startc = state->cursor; + state->part = PSYC_PART_METHOD; // fall thru } case PSYC_PART_METHOD: pos = state->cursor; - if (psyc_parseName(state, name) == PSYC_PARSE_SUCCESS) + ret = psyc_parseName(state, name); + + if (ret == PSYC_PARSE_INSUFFICIENT) + return ret; + else if (ret == PSYC_PARSE_SUCCESS) { // the method ends with a \n then the data follows if (state->buffer.ptr[state->cursor] != '\n') return PSYC_PARSE_ERROR_METHOD; - state->cursor++; - state->startc = state->cursor; + if (state->contentLengthFound) + { // if length was found set start position to the beginning of data + state->cursor++; + state->startc = state->cursor; + state->part = PSYC_PART_DATA; + } + else // otherwise keep it at the beginning of method + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + state->contentParsed += state->cursor - pos; - state->part = PSYC_PART_DATA; - if (state->cursor >= state->buffer.length) - return PSYC_PARSE_INSUFFICIENT; // fall thru } else // No method, which means the packet should end now. @@ -343,9 +386,16 @@ psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psyc if (state->contentLengthFound) // We know the length of the packet. { - if (psyc_parseBinaryValue(state, value, &(state->contentLength), &(state->contentParsed)) == PSYC_PARSE_INCOMPLETE) + if (state->contentParsed < state->contentLength && + psyc_parseBinaryValue(state, value, &(state->contentLength), &(state->contentParsed)) == PSYC_PARSE_INCOMPLETE) return PSYC_PARSE_BODY_INCOMPLETE; + if (state->cursor >= state->buffer.length) + return PSYC_PARSE_BODY; + + if (state->buffer.ptr[state->cursor] != '\n') + return PSYC_PARSE_ERROR_BODY; + state->cursor++; state->part = PSYC_PART_END; return PSYC_PARSE_BODY; @@ -385,7 +435,7 @@ psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psyc return PSYC_PARSE_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; @@ -414,7 +464,7 @@ psycParseListRC psyc_parseList(psycParseListState* state, psycString *name, psyc 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_PARSE_LIST_ERROR_NAME; // First character is either | for text lists, or a number for binary lists From 6fec64f5764639b6935c23e973035bd2de8d4d05 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 27 Apr 2011 18:37:36 +0200 Subject: [PATCH 106/378] partial test packets --- test/packets/test-1 | 1 - test/packets/test-1-length | 1 - test/packets/test-1-length-p1 | 1 + test/packets/test-1-length-p2 | 1 + test/packets/test-1-length-p3 | 3 +++ test/packets/test-1-length-p4 | 1 + test/packets/test-1-length-p5 | 1 + test/packets/test-1-length-p6 | 1 + test/packets/test-1-length-p7 | 1 + test/packets/test-1-length-p8 | 1 + test/packets/test-1-length-p9 | 1 + test/packets/test-1-p1 | 2 ++ test/packets/test-1-p2 | 2 ++ test/packets/test-1-p3 | 3 +++ test/packets/test-1-p4 | 2 ++ test/packets/test-1-p5 | 1 + test/packets/test-1-p6 | 4 ++++ test/packets/test-1-p7 | 2 ++ test/packets/test-1-p8 | 2 ++ test/packets/test-1-p9 | 1 + 20 files changed, 30 insertions(+), 2 deletions(-) create mode 120000 test/packets/test-1-length-p1 create mode 120000 test/packets/test-1-length-p2 create mode 100644 test/packets/test-1-length-p3 create mode 120000 test/packets/test-1-length-p4 create mode 120000 test/packets/test-1-length-p5 create mode 120000 test/packets/test-1-length-p6 create mode 120000 test/packets/test-1-length-p7 create mode 120000 test/packets/test-1-length-p8 create mode 120000 test/packets/test-1-length-p9 create mode 100644 test/packets/test-1-p1 create mode 100644 test/packets/test-1-p2 create mode 100644 test/packets/test-1-p3 create mode 100644 test/packets/test-1-p4 create mode 100644 test/packets/test-1-p5 create mode 100644 test/packets/test-1-p6 create mode 100644 test/packets/test-1-p7 create mode 100644 test/packets/test-1-p8 create mode 100644 test/packets/test-1-p9 diff --git a/test/packets/test-1 b/test/packets/test-1 index 02ea1a6..10cd6e9 100644 --- a/test/packets/test-1 +++ b/test/packets/test-1 @@ -10,4 +10,3 @@ _message_foo_bar ohai there! \o/ | -| diff --git a/test/packets/test-1-length b/test/packets/test-1-length index 6bbd234..d4334de 100644 --- a/test/packets/test-1-length +++ b/test/packets/test-1-length @@ -10,4 +10,3 @@ _message_foo_bar ohai there! \o/ | -| diff --git a/test/packets/test-1-length-p1 b/test/packets/test-1-length-p1 new file mode 120000 index 0000000..e9d736a --- /dev/null +++ b/test/packets/test-1-length-p1 @@ -0,0 +1 @@ +test-1-p1 \ No newline at end of file diff --git a/test/packets/test-1-length-p2 b/test/packets/test-1-length-p2 new file mode 120000 index 0000000..2f233e2 --- /dev/null +++ b/test/packets/test-1-length-p2 @@ -0,0 +1 @@ +test-1-p2 \ No newline at end of file diff --git a/test/packets/test-1-length-p3 b/test/packets/test-1-length-p3 new file mode 100644 index 0000000..ed36f14 --- /dev/null +++ b/test/packets/test-1-length-p3 @@ -0,0 +1,3 @@ +hu3r2cm +85 +:_foo bar baz \ No newline at end of file diff --git a/test/packets/test-1-length-p4 b/test/packets/test-1-length-p4 new file mode 120000 index 0000000..778fb3c --- /dev/null +++ b/test/packets/test-1-length-p4 @@ -0,0 +1 @@ +test-1-p4 \ No newline at end of file diff --git a/test/packets/test-1-length-p5 b/test/packets/test-1-length-p5 new file mode 120000 index 0000000..5411477 --- /dev/null +++ b/test/packets/test-1-length-p5 @@ -0,0 +1 @@ +test-1-p5 \ No newline at end of file diff --git a/test/packets/test-1-length-p6 b/test/packets/test-1-length-p6 new file mode 120000 index 0000000..86f1560 --- /dev/null +++ b/test/packets/test-1-length-p6 @@ -0,0 +1 @@ +test-1-p6 \ No newline at end of file diff --git a/test/packets/test-1-length-p7 b/test/packets/test-1-length-p7 new file mode 120000 index 0000000..3ca4aca --- /dev/null +++ b/test/packets/test-1-length-p7 @@ -0,0 +1 @@ +test-1-p7 \ No newline at end of file diff --git a/test/packets/test-1-length-p8 b/test/packets/test-1-length-p8 new file mode 120000 index 0000000..c8ee162 --- /dev/null +++ b/test/packets/test-1-length-p8 @@ -0,0 +1 @@ +test-1-p8 \ No newline at end of file diff --git a/test/packets/test-1-length-p9 b/test/packets/test-1-length-p9 new file mode 120000 index 0000000..c8a65cb --- /dev/null +++ b/test/packets/test-1-length-p9 @@ -0,0 +1 @@ +test-1-p9 \ No newline at end of file diff --git a/test/packets/test-1-p1 b/test/packets/test-1-p1 new file mode 100644 index 0000000..5a4579e --- /dev/null +++ b/test/packets/test-1-p1 @@ -0,0 +1,2 @@ +:_source psyc://foo/~bar +:_tar \ No newline at end of file diff --git a/test/packets/test-1-p2 b/test/packets/test-1-p2 new file mode 100644 index 0000000..82affb8 --- /dev/null +++ b/test/packets/test-1-p2 @@ -0,0 +1,2 @@ +get psyc://bar/~baz +:_tag sch1828 \ No newline at end of file diff --git a/test/packets/test-1-p3 b/test/packets/test-1-p3 new file mode 100644 index 0000000..126300c --- /dev/null +++ b/test/packets/test-1-p3 @@ -0,0 +1,3 @@ +hu3r2cm + +:_foo bar baz \ No newline at end of file diff --git a/test/packets/test-1-p4 b/test/packets/test-1-p4 new file mode 100644 index 0000000..3cd7e42 --- /dev/null +++ b/test/packets/test-1-p4 @@ -0,0 +1,2 @@ + +:_abc_def 1 \ No newline at end of file diff --git a/test/packets/test-1-p5 b/test/packets/test-1-p5 new file mode 100644 index 0000000..cb3b80c --- /dev/null +++ b/test/packets/test-1-p5 @@ -0,0 +1 @@ +1 foo \ No newline at end of file diff --git a/test/packets/test-1-p6 b/test/packets/test-1-p6 new file mode 100644 index 0000000..0acc380 --- /dev/null +++ b/test/packets/test-1-p6 @@ -0,0 +1,4 @@ + bar +baz +:_foo_bar yay +_message \ No newline at end of file diff --git a/test/packets/test-1-p7 b/test/packets/test-1-p7 new file mode 100644 index 0000000..a8dfc27 --- /dev/null +++ b/test/packets/test-1-p7 @@ -0,0 +1,2 @@ +_foo_bar +ohai \ No newline at end of file diff --git a/test/packets/test-1-p8 b/test/packets/test-1-p8 new file mode 100644 index 0000000..1651eb0 --- /dev/null +++ b/test/packets/test-1-p8 @@ -0,0 +1,2 @@ + there! +\o/ diff --git a/test/packets/test-1-p9 b/test/packets/test-1-p9 new file mode 100644 index 0000000..948cf94 --- /dev/null +++ b/test/packets/test-1-p9 @@ -0,0 +1 @@ +| From 8714d4dfcdb09fff4e163d770cd996bb435f191f Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 27 Apr 2011 19:17:41 +0200 Subject: [PATCH 107/378] renamed test packets --- test/packets/binary.txt | 7 ------- test/packets/{test-1-length-error => error-1-length} | 0 test/packets/{test-2-list-error => error-2-list} | 0 test/packets/{test-0-no-content => full-0-no-content} | 0 test/packets/{test-1 => full-1} | 0 test/packets/{test-1-length => full-1-length} | 0 test/packets/{test-1-utf8 => full-1-utf8} | 0 test/packets/{test-2-list => full-2-list} | 0 test/packets/{test-3-list => full-3-list} | 0 test/packets/{test-4-circuit => full-4-circuit} | 0 .../{test-5-message-private => full-5-message-private} | 0 ...essage-private-remote => full-6-message-private-remote} | 0 test/packets/{fake_dns.txt => full-7-dns-fake} | 0 test/packets/{invalid_dns.txt => full-7-dns-invalid} | 1 - ...{enter_leave_context.txt => full-8-enter-leave-context} | 0 test/packets/part-1-length-p1 | 1 + test/packets/part-1-length-p2 | 1 + test/packets/{test-1-length-p3 => part-1-length-p3} | 0 test/packets/part-1-length-p4 | 1 + test/packets/part-1-length-p5 | 1 + test/packets/part-1-length-p6 | 1 + test/packets/part-1-length-p7 | 1 + test/packets/part-1-length-p8 | 1 + test/packets/part-1-length-p9 | 1 + test/packets/{test-1-p1 => part-1-p1} | 0 test/packets/{test-1-p2 => part-1-p2} | 0 test/packets/{test-1-p3 => part-1-p3} | 0 test/packets/{test-1-p4 => part-1-p4} | 0 test/packets/{test-1-p5 => part-1-p5} | 0 test/packets/{test-1-p6 => part-1-p6} | 0 test/packets/{test-1-p7 => part-1-p7} | 0 test/packets/{test-1-p8 => part-1-p8} | 0 test/packets/{test-1-p9 => part-1-p9} | 0 test/packets/test-1-length-p1 | 1 - test/packets/test-1-length-p2 | 1 - test/packets/test-1-length-p4 | 1 - test/packets/test-1-length-p5 | 1 - test/packets/test-1-length-p6 | 1 - test/packets/test-1-length-p7 | 1 - test/packets/test-1-length-p8 | 1 - test/packets/test-1-length-p9 | 1 - 41 files changed, 8 insertions(+), 16 deletions(-) delete mode 100644 test/packets/binary.txt rename test/packets/{test-1-length-error => error-1-length} (100%) rename test/packets/{test-2-list-error => error-2-list} (100%) rename test/packets/{test-0-no-content => full-0-no-content} (100%) rename test/packets/{test-1 => full-1} (100%) rename test/packets/{test-1-length => full-1-length} (100%) rename test/packets/{test-1-utf8 => full-1-utf8} (100%) rename test/packets/{test-2-list => full-2-list} (100%) rename test/packets/{test-3-list => full-3-list} (100%) rename test/packets/{test-4-circuit => full-4-circuit} (100%) rename test/packets/{test-5-message-private => full-5-message-private} (100%) rename test/packets/{test-6-message-private-remote => full-6-message-private-remote} (100%) rename test/packets/{fake_dns.txt => full-7-dns-fake} (100%) rename test/packets/{invalid_dns.txt => full-7-dns-invalid} (98%) rename test/packets/{enter_leave_context.txt => full-8-enter-leave-context} (100%) create mode 120000 test/packets/part-1-length-p1 create mode 120000 test/packets/part-1-length-p2 rename test/packets/{test-1-length-p3 => part-1-length-p3} (100%) create mode 120000 test/packets/part-1-length-p4 create mode 120000 test/packets/part-1-length-p5 create mode 120000 test/packets/part-1-length-p6 create mode 120000 test/packets/part-1-length-p7 create mode 120000 test/packets/part-1-length-p8 create mode 120000 test/packets/part-1-length-p9 rename test/packets/{test-1-p1 => part-1-p1} (100%) rename test/packets/{test-1-p2 => part-1-p2} (100%) rename test/packets/{test-1-p3 => part-1-p3} (100%) rename test/packets/{test-1-p4 => part-1-p4} (100%) rename test/packets/{test-1-p5 => part-1-p5} (100%) rename test/packets/{test-1-p6 => part-1-p6} (100%) rename test/packets/{test-1-p7 => part-1-p7} (100%) rename test/packets/{test-1-p8 => part-1-p8} (100%) rename test/packets/{test-1-p9 => part-1-p9} (100%) delete mode 120000 test/packets/test-1-length-p1 delete mode 120000 test/packets/test-1-length-p2 delete mode 120000 test/packets/test-1-length-p4 delete mode 120000 test/packets/test-1-length-p5 delete mode 120000 test/packets/test-1-length-p6 delete mode 120000 test/packets/test-1-length-p7 delete mode 120000 test/packets/test-1-length-p8 delete mode 120000 test/packets/test-1-length-p9 diff --git a/test/packets/binary.txt b/test/packets/binary.txt deleted file mode 100644 index 6ea6c1f..0000000 --- a/test/packets/binary.txt +++ /dev/null @@ -1,7 +0,0 @@ -:_source some_source -:_length - -_method -1234567 -| - diff --git a/test/packets/test-1-length-error b/test/packets/error-1-length similarity index 100% rename from test/packets/test-1-length-error rename to test/packets/error-1-length diff --git a/test/packets/test-2-list-error b/test/packets/error-2-list similarity index 100% rename from test/packets/test-2-list-error rename to test/packets/error-2-list diff --git a/test/packets/test-0-no-content b/test/packets/full-0-no-content similarity index 100% rename from test/packets/test-0-no-content rename to test/packets/full-0-no-content diff --git a/test/packets/test-1 b/test/packets/full-1 similarity index 100% rename from test/packets/test-1 rename to test/packets/full-1 diff --git a/test/packets/test-1-length b/test/packets/full-1-length similarity index 100% rename from test/packets/test-1-length rename to test/packets/full-1-length diff --git a/test/packets/test-1-utf8 b/test/packets/full-1-utf8 similarity index 100% rename from test/packets/test-1-utf8 rename to test/packets/full-1-utf8 diff --git a/test/packets/test-2-list b/test/packets/full-2-list similarity index 100% rename from test/packets/test-2-list rename to test/packets/full-2-list diff --git a/test/packets/test-3-list b/test/packets/full-3-list similarity index 100% rename from test/packets/test-3-list rename to test/packets/full-3-list diff --git a/test/packets/test-4-circuit b/test/packets/full-4-circuit similarity index 100% rename from test/packets/test-4-circuit rename to test/packets/full-4-circuit diff --git a/test/packets/test-5-message-private b/test/packets/full-5-message-private similarity index 100% rename from test/packets/test-5-message-private rename to test/packets/full-5-message-private diff --git a/test/packets/test-6-message-private-remote b/test/packets/full-6-message-private-remote similarity index 100% rename from test/packets/test-6-message-private-remote rename to test/packets/full-6-message-private-remote diff --git a/test/packets/fake_dns.txt b/test/packets/full-7-dns-fake similarity index 100% rename from test/packets/fake_dns.txt rename to test/packets/full-7-dns-fake diff --git a/test/packets/invalid_dns.txt b/test/packets/full-7-dns-invalid similarity index 98% rename from test/packets/invalid_dns.txt rename to test/packets/full-7-dns-invalid index 18e195d..96ce59e 100644 --- a/test/packets/invalid_dns.txt +++ b/test/packets/full-7-dns-invalid @@ -2,4 +2,3 @@ _request_some_things | - diff --git a/test/packets/enter_leave_context.txt b/test/packets/full-8-enter-leave-context similarity index 100% rename from test/packets/enter_leave_context.txt rename to test/packets/full-8-enter-leave-context diff --git a/test/packets/part-1-length-p1 b/test/packets/part-1-length-p1 new file mode 120000 index 0000000..b934188 --- /dev/null +++ b/test/packets/part-1-length-p1 @@ -0,0 +1 @@ +part-1-p1 \ No newline at end of file diff --git a/test/packets/part-1-length-p2 b/test/packets/part-1-length-p2 new file mode 120000 index 0000000..e3f9bb4 --- /dev/null +++ b/test/packets/part-1-length-p2 @@ -0,0 +1 @@ +part-1-p2 \ No newline at end of file diff --git a/test/packets/test-1-length-p3 b/test/packets/part-1-length-p3 similarity index 100% rename from test/packets/test-1-length-p3 rename to test/packets/part-1-length-p3 diff --git a/test/packets/part-1-length-p4 b/test/packets/part-1-length-p4 new file mode 120000 index 0000000..75d3aaf --- /dev/null +++ b/test/packets/part-1-length-p4 @@ -0,0 +1 @@ +part-1-p4 \ No newline at end of file diff --git a/test/packets/part-1-length-p5 b/test/packets/part-1-length-p5 new file mode 120000 index 0000000..854fc1b --- /dev/null +++ b/test/packets/part-1-length-p5 @@ -0,0 +1 @@ +part-1-p5 \ No newline at end of file diff --git a/test/packets/part-1-length-p6 b/test/packets/part-1-length-p6 new file mode 120000 index 0000000..3fc7513 --- /dev/null +++ b/test/packets/part-1-length-p6 @@ -0,0 +1 @@ +part-1-p6 \ No newline at end of file diff --git a/test/packets/part-1-length-p7 b/test/packets/part-1-length-p7 new file mode 120000 index 0000000..c4fd783 --- /dev/null +++ b/test/packets/part-1-length-p7 @@ -0,0 +1 @@ +part-1-p7 \ No newline at end of file diff --git a/test/packets/part-1-length-p8 b/test/packets/part-1-length-p8 new file mode 120000 index 0000000..46db87b --- /dev/null +++ b/test/packets/part-1-length-p8 @@ -0,0 +1 @@ +part-1-p8 \ No newline at end of file diff --git a/test/packets/part-1-length-p9 b/test/packets/part-1-length-p9 new file mode 120000 index 0000000..d933075 --- /dev/null +++ b/test/packets/part-1-length-p9 @@ -0,0 +1 @@ +part-1-p9 \ No newline at end of file diff --git a/test/packets/test-1-p1 b/test/packets/part-1-p1 similarity index 100% rename from test/packets/test-1-p1 rename to test/packets/part-1-p1 diff --git a/test/packets/test-1-p2 b/test/packets/part-1-p2 similarity index 100% rename from test/packets/test-1-p2 rename to test/packets/part-1-p2 diff --git a/test/packets/test-1-p3 b/test/packets/part-1-p3 similarity index 100% rename from test/packets/test-1-p3 rename to test/packets/part-1-p3 diff --git a/test/packets/test-1-p4 b/test/packets/part-1-p4 similarity index 100% rename from test/packets/test-1-p4 rename to test/packets/part-1-p4 diff --git a/test/packets/test-1-p5 b/test/packets/part-1-p5 similarity index 100% rename from test/packets/test-1-p5 rename to test/packets/part-1-p5 diff --git a/test/packets/test-1-p6 b/test/packets/part-1-p6 similarity index 100% rename from test/packets/test-1-p6 rename to test/packets/part-1-p6 diff --git a/test/packets/test-1-p7 b/test/packets/part-1-p7 similarity index 100% rename from test/packets/test-1-p7 rename to test/packets/part-1-p7 diff --git a/test/packets/test-1-p8 b/test/packets/part-1-p8 similarity index 100% rename from test/packets/test-1-p8 rename to test/packets/part-1-p8 diff --git a/test/packets/test-1-p9 b/test/packets/part-1-p9 similarity index 100% rename from test/packets/test-1-p9 rename to test/packets/part-1-p9 diff --git a/test/packets/test-1-length-p1 b/test/packets/test-1-length-p1 deleted file mode 120000 index e9d736a..0000000 --- a/test/packets/test-1-length-p1 +++ /dev/null @@ -1 +0,0 @@ -test-1-p1 \ No newline at end of file diff --git a/test/packets/test-1-length-p2 b/test/packets/test-1-length-p2 deleted file mode 120000 index 2f233e2..0000000 --- a/test/packets/test-1-length-p2 +++ /dev/null @@ -1 +0,0 @@ -test-1-p2 \ No newline at end of file diff --git a/test/packets/test-1-length-p4 b/test/packets/test-1-length-p4 deleted file mode 120000 index 778fb3c..0000000 --- a/test/packets/test-1-length-p4 +++ /dev/null @@ -1 +0,0 @@ -test-1-p4 \ No newline at end of file diff --git a/test/packets/test-1-length-p5 b/test/packets/test-1-length-p5 deleted file mode 120000 index 5411477..0000000 --- a/test/packets/test-1-length-p5 +++ /dev/null @@ -1 +0,0 @@ -test-1-p5 \ No newline at end of file diff --git a/test/packets/test-1-length-p6 b/test/packets/test-1-length-p6 deleted file mode 120000 index 86f1560..0000000 --- a/test/packets/test-1-length-p6 +++ /dev/null @@ -1 +0,0 @@ -test-1-p6 \ No newline at end of file diff --git a/test/packets/test-1-length-p7 b/test/packets/test-1-length-p7 deleted file mode 120000 index 3ca4aca..0000000 --- a/test/packets/test-1-length-p7 +++ /dev/null @@ -1 +0,0 @@ -test-1-p7 \ No newline at end of file diff --git a/test/packets/test-1-length-p8 b/test/packets/test-1-length-p8 deleted file mode 120000 index c8ee162..0000000 --- a/test/packets/test-1-length-p8 +++ /dev/null @@ -1 +0,0 @@ -test-1-p8 \ No newline at end of file diff --git a/test/packets/test-1-length-p9 b/test/packets/test-1-length-p9 deleted file mode 120000 index c8a65cb..0000000 --- a/test/packets/test-1-length-p9 +++ /dev/null @@ -1 +0,0 @@ -test-1-p9 \ No newline at end of file From 56ac354c7db12b7bddf5dee1740c6e0a6664bb1e Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 27 Apr 2011 19:18:17 +0200 Subject: [PATCH 108/378] test server --- .gitignore | 1 + test/Makefile | 14 ++- test/testServer.c | 257 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 270 insertions(+), 2 deletions(-) create mode 100644 test/testServer.c diff --git a/.gitignore b/.gitignore index e802e07..c21bfb4 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ src/match test/testMatch test/testParser test/testRender +test/testServer test/isRoutingVar .config diff --git a/test/Makefile b/test/Makefile index 0503d44..9e59256 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,7 +1,8 @@ CFLAGS=-I../include -DDEBUG -g -O0 -Wall LDFLAGS=-L../src LOADLIBES=-lpsyc -lm -TARGETS=testParser testMatch testRender isRoutingVar +TARGETS=testServer testParser testMatch testRender isRoutingVar +PORT=4440 all: $(TARGETS) ./testRender @@ -9,7 +10,16 @@ all: $(TARGETS) ./isRoutingVar test: $(TARGETS) - for f in packets/*; do echo ">> $$f"; ./testParser $$f; done + for f in packets/full-* packets/error-*; do echo ">> $$f"; ./testParser $$f; done + +nettest: + for f in packets/full-* packets/error-*; do echo ">> $$f"; cat $$f | nc localhost $(PORT); done + +nettestp1: + (for f in packets/part-1-p*; do cat $$f; done) | nc nb $(PORT) + +nettestp2: + (for f in packets/part-1-length-p*; do cat $$f; done) | nc nb $(PORT) clean: rm -f $(TARGETS) diff --git a/test/testServer.c b/test/testServer.c new file mode 100644 index 0000000..9134c25 --- /dev/null +++ b/test/testServer.c @@ -0,0 +1,257 @@ +/** + * libpsyc test server for packet parsing & rendering + * based on selectserver.c from http://beej.us/guide/bgnet/ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +const size_t RECV_BUF_SIZE = 256; +const size_t SEND_BUF_SIZE = 1024; +const size_t NUM_PARSERS = 100; + +// get sockaddr, IPv4 or IPv6: +void *get_in_addr(struct sockaddr *sa) +{ + if (sa->sa_family == AF_INET) { + return &(((struct sockaddr_in*)sa)->sin_addr); + } + + return &(((struct sockaddr_in6*)sa)->sin6_addr); +} + +int main(int argc, char **argv) +{ + char *port = argc > 1 ? argv[1] : "4440"; + uint8_t verbose = argc > 2; + + fd_set master; // master file descriptor list + fd_set read_fds; // temp file descriptor list for select() + int fdmax; // maximum file descriptor number + + int listener; // listening socket descriptor + int newfd; // newly accept()ed socket descriptor + struct sockaddr_storage remoteaddr; // client address + socklen_t addrlen; + + char buf[2*RECV_BUF_SIZE]; // cont buf + recv buf: [ ccrrrr] + char *recvbuf = buf + RECV_BUF_SIZE; // recv buf: ^^^^ + char *parsebuf; // parse buf: ^^^^^^ + char sendbuf[SEND_BUF_SIZE]; + size_t nbytes, contbytes = 0; + + char remoteIP[INET6_ADDRSTRLEN]; + + int yes = 1; // for setsockopt() SO_REUSEADDR, below + int i, rv; + + struct addrinfo hints, *ai, *p; + + psycParseState parsers[NUM_PARSERS]; + psycPacket packets[NUM_PARSERS]; + + int ret, retl; + char oper; + psycString name, value, elem; + psycParseListState listState; + + FD_ZERO(&master); // clear the master and temp sets + FD_ZERO(&read_fds); + + // get us a socket and bind it + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + if ((rv = getaddrinfo(NULL, port, &hints, &ai)) != 0) { + fprintf(stderr, "error: %s\n", gai_strerror(rv)); + exit(1); + } + + for (p = ai; p != NULL; p = p->ai_next) { + listener = socket(p->ai_family, p->ai_socktype, p->ai_protocol); + if (listener < 0) { + continue; + } + + // lose the pesky "address already in use" error message + setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); + + if (bind(listener, p->ai_addr, p->ai_addrlen) < 0) { + close(listener); + continue; + } + + break; + } + + // if we got here, it means we didn't get bound + if (p == NULL) { + fprintf(stderr, "failed to bind\n"); + exit(2); + } + + freeaddrinfo(ai); // all done with this + + // listen + if (listen(listener, 10) == -1) { + perror("listen"); + exit(3); + } + + // add the listener to the master set + FD_SET(listener, &master); + + // keep track of the biggest file descriptor + fdmax = listener; // so far, it's this one + + // main loop + for (;;) { + read_fds = master; // copy it + if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) { + perror("select"); + exit(4); + } + + // run through the existing connections looking for data to read + for (i = 0; i <= fdmax; i++) { + if (FD_ISSET(i, &read_fds)) { // we got one!! + if (i == listener) { + // handle new connections + if (fdmax == NUM_PARSERS - 1) + continue; // ignore if there's too many + + addrlen = sizeof remoteaddr; + newfd = accept(listener, (struct sockaddr *)&remoteaddr, &addrlen); + + if (newfd == -1) { + perror("accept"); + } else { + FD_SET(newfd, &master); // add to master set + if (newfd > fdmax) { // keep track of the max + fdmax = newfd; + } + + // reset parser state & packet + psyc_initParseState(&parsers[newfd]); + memset(&packets[newfd], 0, sizeof(psycPacket)); + + printf("# New connection from %s on socket %d\n", + inet_ntop(remoteaddr.ss_family, + get_in_addr((struct sockaddr*)&remoteaddr), + remoteIP, INET6_ADDRSTRLEN), + newfd); + } + } else { + // handle data from a client + if ((nbytes = recv(i, recvbuf, RECV_BUF_SIZE, 0)) <= 0) { + // got error or connection closed by client + if (nbytes == 0) { + // connection closed + printf("socket %d hung up\n", i); + } else { + perror("recv"); + } + close(i); // bye! + FD_CLR(i, &master); // remove from master set + } else { + // we got some data from a client + parsebuf = recvbuf - contbytes; + psyc_nextParseBuffer(&parsers[i], psyc_newString(parsebuf, contbytes + nbytes)); + contbytes = 0; + + do { + ret = psyc_parse(&parsers[i], &oper, &name, &value); + switch (ret) { + case PSYC_PARSE_ROUTING: + case PSYC_PARSE_ENTITY: + case PSYC_PARSE_ENTITY_INCOMPLETE: + if (verbose) + write(1, &oper, 1); + case PSYC_PARSE_BODY: + case PSYC_PARSE_BODY_INCOMPLETE: + if (ret == PSYC_PARSE_BODY_INCOMPLETE || + ret == PSYC_PARSE_ENTITY_INCOMPLETE) + ret = 0; + + // printf("the string is '%.*s'\n", name); + if (verbose) { + write(1, name.ptr, name.length); + write(1, " = ", 3); + write(1, value.ptr, value.length); + write(1, "\n", 1); + } + if (memcmp(name.ptr, "_list", 5) == 0) { + if (verbose) + write(1, ">>> LIST START\n", 15); + psyc_initParseListState(&listState); + psyc_nextParseListBuffer(&listState, value); + do { + retl = psyc_parseList(&listState, &name, &value, &elem); + switch (retl) { + case PSYC_PARSE_LIST_END: + retl = 0; + case PSYC_PARSE_LIST_ELEM: + if (verbose) { + write(1, "|", 1); + write(1, elem.ptr, elem.length); + write(1, "\n", 1); + if (ret == PSYC_PARSE_LIST_END) + write(1, ">>> LIST END\n", 13); + } + break; + default: + printf("# Error while parsing list: %i\n", ret); + ret = retl = -1; + } + } while (retl > 0); + } + break; + case PSYC_PARSE_COMPLETE: + printf("# Done parsing.\n"); +#ifdef RENDER_WORKS + psyc_render(&packets[i], sendbuf, SEND_BUF_SIZE); + if (send(i, sendbuf, packets[i].length, 0) == -1) { + perror("send"); + } +#endif + ret = -1; + break; + case PSYC_PARSE_INSUFFICIENT: + printf("# Insufficient data.\n"); + contbytes = parsers[i].buffer.length - parsers[i].cursor; + if (contbytes > 0) { // copy end of parsebuf before start of recvbuf + assert(recvbuf - contbytes >= buf); // make sure it's still in the buffer + memcpy(recvbuf - contbytes, parsebuf + parsers[i].cursor, contbytes); + } + ret = 0; + break; + default: + printf("# Error while parsing: %i\n", ret); + ret = -1; + } + } while (ret > 0); + if (ret < 0) { + printf("# Closing connection: %i\n", i); + close(i); // bye! + FD_CLR(i, &master); // remove from master set + } + } + } // END handle data from client + } // END got new incoming connection + } // END looping through file descriptors + } // END for(;;)--and you thought it would never end! + + return 0; +} From 119822d1b2938fae4c9926f4449ea84997670471 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Thu, 28 Apr 2011 12:33:06 +0200 Subject: [PATCH 109/378] fix for parsing empty data --- src/parser.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/parser.c b/src/parser.c index c90dd03..37980ae 100644 --- a/src/parser.c +++ b/src/parser.c @@ -402,11 +402,12 @@ psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psyc } else // Search for the terminator. { + size_t datac = state->cursor; // start of data while (1) { uint8_t nl = state->buffer.ptr[state->cursor] == '\n'; // check for |\n if we're at the start of data or we have found a \n - if (state->cursor == state->startc || nl) + if (state->cursor == datac || nl) { if (state->cursor+1+nl >= state->buffer.length) // incremented cursor inside length? { From ca95d51e49fb8108b216492125225568da0144f8 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Thu, 28 Apr 2011 15:15:37 +0200 Subject: [PATCH 110/378] + --- test/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/Makefile b/test/Makefile index 9e59256..3574c63 100644 --- a/test/Makefile +++ b/test/Makefile @@ -16,10 +16,10 @@ nettest: for f in packets/full-* packets/error-*; do echo ">> $$f"; cat $$f | nc localhost $(PORT); done nettestp1: - (for f in packets/part-1-p*; do cat $$f; done) | nc nb $(PORT) + (for f in packets/part-1-p*; do cat $$f; done) | nc localhost $(PORT) nettestp2: - (for f in packets/part-1-length-p*; do cat $$f; done) | nc nb $(PORT) + (for f in packets/part-1-length-p*; do cat $$f; done) | nc localhost $(PORT) clean: rm -f $(TARGETS) From d0d07f7410652cb78038e93ddd82e01000cd9ce7 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Thu, 28 Apr 2011 15:20:07 +0200 Subject: [PATCH 111/378] + --- include/psyc.h | 10 +++++----- test/Makefile | 4 ++-- test/testServer.c | 2 ++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/include/psyc.h b/include/psyc.h index 149b903..5d75ced 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -146,13 +146,13 @@ typedef struct /* intermediate struct for a PSYC packet */ typedef struct { - psycHeader routing; ///< Routing header. - psycHeader entity; ///< Entitiy header. + psycHeader routing; ///< Routing header. + psycHeader entity; ///< Entity header. psycString method; psycString data; - size_t routingLength; ///< Length of routing part. - size_t contentLength; ///< Length of content part. - size_t length; ///< Total length of packet. + size_t routingLength; ///< Length of routing part. + size_t contentLength; ///< Length of content part. + size_t length; ///< Total length of packet. psycPacketFlag flag; } psycPacket; diff --git a/test/Makefile b/test/Makefile index 9e59256..3574c63 100644 --- a/test/Makefile +++ b/test/Makefile @@ -16,10 +16,10 @@ nettest: for f in packets/full-* packets/error-*; do echo ">> $$f"; cat $$f | nc localhost $(PORT); done nettestp1: - (for f in packets/part-1-p*; do cat $$f; done) | nc nb $(PORT) + (for f in packets/part-1-p*; do cat $$f; done) | nc localhost $(PORT) nettestp2: - (for f in packets/part-1-length-p*; do cat $$f; done) | nc nb $(PORT) + (for f in packets/part-1-length-p*; do cat $$f; done) | nc localhost $(PORT) clean: rm -f $(TARGETS) diff --git a/test/testServer.c b/test/testServer.c index 9134c25..78b9eb1 100644 --- a/test/testServer.c +++ b/test/testServer.c @@ -1,6 +1,8 @@ /** * libpsyc test server for packet parsing & rendering + * * based on selectserver.c from http://beej.us/guide/bgnet/ + * "The C source code presented in this document is hereby granted to the public domain, and is completely free of any license restriction." */ #include From 9f00ddcb1ecf4d33362f75ed2ef2b3cb3c513546 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 29 Apr 2011 03:13:50 +0200 Subject: [PATCH 112/378] test packets: 1 packet/file --- test/packets/full-1-utf8 | 1 - test/packets/full-2-list | 6 ------ test/packets/full-3-list | 13 ------------- test/packets/full-8-context-enter | 5 +++++ ...l-8-enter-leave-context => full-8-context-leave} | 5 ----- 5 files changed, 5 insertions(+), 25 deletions(-) create mode 100644 test/packets/full-8-context-enter rename test/packets/{full-8-enter-leave-context => full-8-context-leave} (56%) diff --git a/test/packets/full-1-utf8 b/test/packets/full-1-utf8 index e1de776..fc3472a 100644 --- a/test/packets/full-1-utf8 +++ b/test/packets/full-1-utf8 @@ -10,4 +10,3 @@ _message_foo_bar ohai there! \o/ | -| diff --git a/test/packets/full-2-list b/test/packets/full-2-list index 02202d2..9c9e37e 100644 --- a/test/packets/full-2-list +++ b/test/packets/full-2-list @@ -16,9 +16,3 @@ _message_foo_bar ohai there! \o/ | -:_target psyc://foo.bar/~baz - -:_test 123 -_message_test -ohai! -| diff --git a/test/packets/full-3-list b/test/packets/full-3-list index 222c726..f613741 100644 --- a/test/packets/full-3-list +++ b/test/packets/full-3-list @@ -18,16 +18,3 @@ _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/test/packets/full-8-context-enter b/test/packets/full-8-context-enter new file mode 100644 index 0000000..39648d9 --- /dev/null +++ b/test/packets/full-8-context-enter @@ -0,0 +1,5 @@ +:_target psyc://p5B084547.dip.t-dialin.net/@test +:_source something + +_request_context_enter +| diff --git a/test/packets/full-8-enter-leave-context b/test/packets/full-8-context-leave similarity index 56% rename from test/packets/full-8-enter-leave-context rename to test/packets/full-8-context-leave index b17078e..bc26ab8 100644 --- a/test/packets/full-8-enter-leave-context +++ b/test/packets/full-8-context-leave @@ -1,9 +1,4 @@ :_target psyc://p5B084547.dip.t-dialin.net/@test -:_source something - -_request_context_enter -| -:_target psyc://p5B084547.dip.t-dialin.net/@test :_more vars :_bin 6 "1 From a4e3dcc5159d07966a27cef3c3607ecd63660a8c Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 29 Apr 2011 03:15:36 +0200 Subject: [PATCH 113/378] render: no \n after routing headers if content is empty --- src/packet.c | 11 ++++++++--- src/render.c | 3 ++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/packet.c b/src/packet.c index 3676c2c..8455636 100644 --- a/src/packet.c +++ b/src/packet.c @@ -146,9 +146,14 @@ inline size_t psyc_setPacketLength(psycPacket *p) p->contentLength += p->data.length + 1; // data\n // set total length: routing-header \n content |\n - p->length = p->routingLength + 1 + p->contentLength + sizeof(PSYC_PACKET_DELIMITER) - 2; - if (p->flag == PSYC_PACKET_NEED_LENGTH) // add length of length if needed - p->length += log10((double)p->data.length) + 1; + p->length = p->routingLength + p->contentLength + sizeof(PSYC_PACKET_DELIMITER) - 2; + if (p->contentLength > 0) + { + p->contentLength--; // subtract the \n from the delimiter, as that doesn't belong to the content part + p->length++; // add \n at the start of the content part + if (p->flag == PSYC_PACKET_NEED_LENGTH) // add length of length if needed + p->length += log10((double)p->data.length) + 1; + } return p->length; } diff --git a/src/render.c b/src/render.c index eb76494..e7b5793 100644 --- a/src/render.c +++ b/src/render.c @@ -76,7 +76,8 @@ psycRenderRC psyc_render(psycPacket *packet, char *buffer, size_t buflen) cur += itoa(packet->contentLength, buffer + cur, 10); } - buffer[cur++] = '\n'; // start of content part + if (packet->entity.lines || packet->method.length || packet->data.length) + buffer[cur++] = '\n'; // start of content part if there's content // render entity modifiers for (i = 0; i < packet->entity.lines; i++) From b2ae4a58afcf55e5da35b0f407809c4b08a2ddda Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 29 Apr 2011 03:20:00 +0200 Subject: [PATCH 114/378] testServer: added rendering; nettest: fail if there's a diff between input & rendered packet --- test/Makefile | 9 ++- test/testServer.c | 147 +++++++++++++++++++++++++++++++++------------- 2 files changed, 111 insertions(+), 45 deletions(-) diff --git a/test/Makefile b/test/Makefile index 3574c63..cdbbaaa 100644 --- a/test/Makefile +++ b/test/Makefile @@ -13,13 +13,16 @@ test: $(TARGETS) for f in packets/full-* packets/error-*; do echo ">> $$f"; ./testParser $$f; done nettest: - for f in packets/full-* packets/error-*; do echo ">> $$f"; cat $$f | nc localhost $(PORT); done + for f in packets/full-*; do echo ">> $$f"; cat $$f | nc localhost $(PORT) | diff -u $$f -; done + +nettesterr: + for f in packets/error-*; do echo ">> $$f"; cat $$f | nc localhost $(PORT); done nettestp1: - (for f in packets/part-1-p*; do cat $$f; done) | nc localhost $(PORT) + (for f in packets/part-1-p*; do cat $$f; done) | nc localhost $(PORT) | diff -u packets/full-1 - nettestp2: - (for f in packets/part-1-length-p*; do cat $$f; done) | nc localhost $(PORT) + (for f in packets/part-1-length-p*; do cat $$f; done) | nc localhost $(PORT) | diff -u packets/full-1-length - clean: rm -f $(TARGETS) diff --git a/test/testServer.c b/test/testServer.c index 78b9eb1..aef8d81 100644 --- a/test/testServer.c +++ b/test/testServer.c @@ -14,14 +14,20 @@ #include #include #include +#include #include #include #include +#include const size_t RECV_BUF_SIZE = 256; +const size_t CONT_BUF_SIZE = 512; const size_t SEND_BUF_SIZE = 1024; const size_t NUM_PARSERS = 100; +// max size for routing & entity header +const size_t ROUTING_LINES = 16; +const size_t ENTITY_LINES = 32; // get sockaddr, IPv4 or IPv6: void *get_in_addr(struct sockaddr *sa) @@ -47,9 +53,9 @@ int main(int argc, char **argv) struct sockaddr_storage remoteaddr; // client address socklen_t addrlen; - char buf[2*RECV_BUF_SIZE]; // cont buf + recv buf: [ ccrrrr] - char *recvbuf = buf + RECV_BUF_SIZE; // recv buf: ^^^^ - char *parsebuf; // parse buf: ^^^^^^ + char buf[CONT_BUF_SIZE + RECV_BUF_SIZE]; // cont buf + recv buf: [ ccrrrr] + char *recvbuf = buf + CONT_BUF_SIZE; // recv buf: ^^^^ + char *parsebuf; // parse buf: ^^^^^^ char sendbuf[SEND_BUF_SIZE]; size_t nbytes, contbytes = 0; @@ -62,10 +68,14 @@ int main(int argc, char **argv) psycParseState parsers[NUM_PARSERS]; psycPacket packets[NUM_PARSERS]; + psycModifier routing[NUM_PARSERS][ROUTING_LINES]; + psycModifier entity[NUM_PARSERS][ENTITY_LINES]; + psycModifier *mod; int ret, retl; char oper; psycString name, value, elem; + psycString *pname, *pvalue; psycParseListState listState; FD_ZERO(&master); // clear the master and temp sets @@ -148,6 +158,10 @@ int main(int argc, char **argv) // reset parser state & packet psyc_initParseState(&parsers[newfd]); memset(&packets[newfd], 0, sizeof(psycPacket)); + memset(&routing[newfd], 0, sizeof(psycModifier) * ROUTING_LINES); + memset(&entity[newfd], 0, sizeof(psycModifier) * ENTITY_LINES); + packets[newfd].routing.modifiers = routing[newfd]; + packets[newfd].entity.modifiers = entity[newfd]; printf("# New connection from %s on socket %d\n", inet_ntop(remoteaddr.ss_family, @@ -172,29 +186,101 @@ int main(int argc, char **argv) parsebuf = recvbuf - contbytes; psyc_nextParseBuffer(&parsers[i], psyc_newString(parsebuf, contbytes + nbytes)); contbytes = 0; + oper = 0; + name.length = 0; + value.length = 0; do { ret = psyc_parse(&parsers[i], &oper, &name, &value); switch (ret) { case PSYC_PARSE_ROUTING: - case PSYC_PARSE_ENTITY: + assert(packets[i].routing.lines < ROUTING_LINES); + mod = &(packets[i].routing.modifiers[packets[i].routing.lines]); + pname = &mod->name; + pvalue = &mod->value; + mod->flag = PSYC_MODIFIER_ROUTING; + packets[i].routing.lines++; + break; case PSYC_PARSE_ENTITY_INCOMPLETE: - if (verbose) - write(1, &oper, 1); - case PSYC_PARSE_BODY: - case PSYC_PARSE_BODY_INCOMPLETE: - if (ret == PSYC_PARSE_BODY_INCOMPLETE || - ret == PSYC_PARSE_ENTITY_INCOMPLETE) - ret = 0; - - // printf("the string is '%.*s'\n", name); - if (verbose) { - write(1, name.ptr, name.length); - write(1, " = ", 3); - write(1, value.ptr, value.length); - write(1, "\n", 1); + case PSYC_PARSE_ENTITY: + assert(packets[i].entity.lines < ENTITY_LINES); + mod = &(packets[i].entity.modifiers[packets[i].entity.lines]); + pname = &mod->name; + pvalue = &mod->value; + if (ret == PSYC_PARSE_ENTITY) { + packets[i].entity.lines++; + mod->flag = parsers[i].valueLength ? PSYC_MODIFIER_NEED_LENGTH : PSYC_MODIFIER_NO_LENGTH; } - if (memcmp(name.ptr, "_list", 5) == 0) { + break; + case PSYC_PARSE_BODY_INCOMPLETE: + case PSYC_PARSE_BODY: + pname = &(packets[i].method); + pvalue = &(packets[i].data); + break; + case PSYC_PARSE_COMPLETE: + printf("# Done parsing.\n"); + packets[i].flag = parsers[i].contentLengthFound ? PSYC_PACKET_NEED_LENGTH : PSYC_PACKET_NO_LENGTH; + psyc_setPacketLength(&packets[i]); + psyc_render(&packets[i], sendbuf, SEND_BUF_SIZE); + if (send(i, sendbuf, packets[i].length, 0) == -1) { + perror("send"); + } + ret = -1; + break; + case PSYC_PARSE_INSUFFICIENT: + printf("# Insufficient data.\n"); + contbytes = parsers[i].buffer.length - parsers[i].cursor; + if (contbytes > 0) { // copy end of parsebuf before start of recvbuf + assert(recvbuf - contbytes >= buf); // make sure it's still in the buffer + memcpy(recvbuf - contbytes, parsebuf + parsers[i].cursor, contbytes); + } + ret = 0; + break; + default: + printf("# Error while parsing: %i\n", ret); + ret = -1; + } + + switch (ret) { + case PSYC_PARSE_ENTITY_INCOMPLETE: + case PSYC_PARSE_BODY_INCOMPLETE: + ret = 0; + case PSYC_PARSE_ENTITY: + case PSYC_PARSE_ROUTING: + case PSYC_PARSE_BODY: + if (oper) { + mod->oper = oper; + if (verbose) write(1, &oper, 1); + } + + if (name.length) { + pname->ptr = malloc(name.length); + pname->length = name.length; + assert(pname->ptr != NULL); + memcpy((void*)pname->ptr, name.ptr, name.length); + name.length = 0; + if (verbose) { + write(1, pname->ptr, pname->length); + write(1, " = ", 3); + } + } + + if (value.length) { + if (!pvalue->ptr) + pvalue->ptr = malloc(parsers[i].valueLength ? parsers[i].valueLength : value.length); + assert(pvalue->ptr != NULL); + memcpy((void*)pvalue->ptr + pvalue->length, value.ptr, value.length); + pvalue->length += value.length; + value.length = 0; + if (verbose) { + write(1, pvalue->ptr, pvalue->length); + if (parsers[i].valueLength > pvalue->length) + write(1, "...", 3); + write(1, "\n", 1); + } + } + + if (name.length >= 5 && memcmp(name.ptr, "_list", 5) == 0) { if (verbose) write(1, ">>> LIST START\n", 15); psyc_initParseListState(&listState); @@ -219,29 +305,6 @@ int main(int argc, char **argv) } } while (retl > 0); } - break; - case PSYC_PARSE_COMPLETE: - printf("# Done parsing.\n"); -#ifdef RENDER_WORKS - psyc_render(&packets[i], sendbuf, SEND_BUF_SIZE); - if (send(i, sendbuf, packets[i].length, 0) == -1) { - perror("send"); - } -#endif - ret = -1; - break; - case PSYC_PARSE_INSUFFICIENT: - printf("# Insufficient data.\n"); - contbytes = parsers[i].buffer.length - parsers[i].cursor; - if (contbytes > 0) { // copy end of parsebuf before start of recvbuf - assert(recvbuf - contbytes >= buf); // make sure it's still in the buffer - memcpy(recvbuf - contbytes, parsebuf + parsers[i].cursor, contbytes); - } - ret = 0; - break; - default: - printf("# Error while parsing: %i\n", ret); - ret = -1; } } while (ret > 0); if (ret < 0) { From 4fd4a49e09a6ca40317649cdee9a063570941bb1 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 29 Apr 2011 04:12:55 +0200 Subject: [PATCH 115/378] Makefile: netstart --- test/Makefile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/Makefile b/test/Makefile index cdbbaaa..abb7d0a 100644 --- a/test/Makefile +++ b/test/Makefile @@ -12,6 +12,12 @@ all: $(TARGETS) test: $(TARGETS) for f in packets/full-* packets/error-*; do echo ">> $$f"; ./testParser $$f; done +netstart: + ./testServer $(PORT) + +netstartv: + ./testServer $(PORT) -v + nettest: for f in packets/full-*; do echo ">> $$f"; cat $$f | nc localhost $(PORT) | diff -u $$f -; done From 23633f0eb6f45d7feceab18e8fb99c83b1606671 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 29 Apr 2011 16:00:48 +0200 Subject: [PATCH 116/378] parser: fixes for partial packets --- src/parser.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/parser.c b/src/parser.c index 37980ae..501c300 100644 --- a/src/parser.c +++ b/src/parser.c @@ -189,7 +189,8 @@ inline psycParseRC psyc_parseModifier(psycParseState* state, char* oper, psycStr if (state->buffer.ptr[state->cursor] != '\t') return PSYC_PARSE_ERROR_MOD_TAB; - ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INCOMPLETE); + if (++(state->cursor) >= state->buffer.length) + return PSYC_PARSE_INCOMPLETE; ret = psyc_parseBinaryValue(state, value, &(state->valueLength), &(state->valueParsed)); if (ret == PSYC_PARSE_INCOMPLETE) @@ -264,6 +265,7 @@ psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psyc else // not a glyph { state->part = PSYC_PART_LENGTH; + state->startc = state->cursor; // fall thru } @@ -300,8 +302,8 @@ psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psyc goto PSYC_PART_END; } + state->startc = state->cursor + 1; ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); - state->startc = state->cursor; // fall thru case PSYC_PART_CONTENT: @@ -365,12 +367,12 @@ psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psyc { // if length was found set start position to the beginning of data state->cursor++; state->startc = state->cursor; + state->contentParsed += state->cursor - pos; state->part = PSYC_PART_DATA; } else // otherwise keep it at the beginning of method ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); - state->contentParsed += state->cursor - pos; // fall thru } else // No method, which means the packet should end now. @@ -418,6 +420,7 @@ psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psyc if (state->buffer.ptr[state->cursor+nl] == '|' && state->buffer.ptr[state->cursor+1+nl] == '\n') // packet ends here { + state->contentParsed += state->cursor - pos; state->cursor += nl; state->part = PSYC_PART_END; return PSYC_PARSE_BODY; From 6785ed048c532e9720ff2ee215088175f54a83a6 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 29 Apr 2011 16:02:38 +0200 Subject: [PATCH 117/378] testServer: s/write/printf/ --- test/testServer.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/test/testServer.c b/test/testServer.c index aef8d81..0092eaf 100644 --- a/test/testServer.c +++ b/test/testServer.c @@ -228,7 +228,8 @@ int main(int argc, char **argv) ret = -1; break; case PSYC_PARSE_INSUFFICIENT: - printf("# Insufficient data.\n"); + if (verbose) + printf("# Insufficient data.\n"); contbytes = parsers[i].buffer.length - parsers[i].cursor; if (contbytes > 0) { // copy end of parsebuf before start of recvbuf assert(recvbuf - contbytes >= buf); // make sure it's still in the buffer @@ -250,7 +251,8 @@ int main(int argc, char **argv) case PSYC_PARSE_BODY: if (oper) { mod->oper = oper; - if (verbose) write(1, &oper, 1); + if (verbose) + printf("%c", oper); } if (name.length) { @@ -260,8 +262,7 @@ int main(int argc, char **argv) memcpy((void*)pname->ptr, name.ptr, name.length); name.length = 0; if (verbose) { - write(1, pname->ptr, pname->length); - write(1, " = ", 3); + printf("%.*s = ", (int)pname->length, pname->ptr); } } @@ -273,16 +274,21 @@ int main(int argc, char **argv) pvalue->length += value.length; value.length = 0; if (verbose) { - write(1, pvalue->ptr, pvalue->length); + printf("%.*s", (int)pvalue->length, pvalue->ptr); if (parsers[i].valueLength > pvalue->length) - write(1, "...", 3); - write(1, "\n", 1); + printf("..."); + printf("\n"); } + } else if (verbose) { + printf("\n"); } + if (verbose) + printf("\t\t\t\t\t\t\t\t# n:%ld v:%ld c:%ld r:%ld\n", pname->length, pvalue->length, parsers[i].contentParsed, parsers[i].routingLength); + if (name.length >= 5 && memcmp(name.ptr, "_list", 5) == 0) { if (verbose) - write(1, ">>> LIST START\n", 15); + printf("## LIST START\n"); psyc_initParseListState(&listState); psyc_nextParseListBuffer(&listState, value); do { @@ -292,11 +298,9 @@ int main(int argc, char **argv) retl = 0; case PSYC_PARSE_LIST_ELEM: if (verbose) { - write(1, "|", 1); - write(1, elem.ptr, elem.length); - write(1, "\n", 1); + printf("|%.*s\n", (int)elem.length, elem.ptr); if (ret == PSYC_PARSE_LIST_END) - write(1, ">>> LIST END\n", 13); + printf("## LIST END"); } break; default: From bd3e61970c6ef3b85b49eb44a9ac653d1e4c86de Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 29 Apr 2011 16:03:17 +0200 Subject: [PATCH 118/378] splittest --- test/Makefile | 3 +++ test/splittest.pl | 28 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100755 test/splittest.pl diff --git a/test/Makefile b/test/Makefile index abb7d0a..b1b58e3 100644 --- a/test/Makefile +++ b/test/Makefile @@ -24,6 +24,9 @@ nettest: nettesterr: for f in packets/error-*; do echo ">> $$f"; cat $$f | nc localhost $(PORT); done +splittest: + for f in packets/full-*; do echo ">> $$f"; ./splittest.pl $$f $(PORT) | diff -u $$f -; done + nettestp1: (for f in packets/part-1-p*; do cat $$f; done) | nc localhost $(PORT) | diff -u packets/full-1 - diff --git a/test/splittest.pl b/test/splittest.pl new file mode 100755 index 0000000..9794390 --- /dev/null +++ b/test/splittest.pl @@ -0,0 +1,28 @@ +#!/usr/bin/env perl +use strict; +use warnings; +use IO::Socket; +$| = 1; + +print "Usage: splittest.pl [ [ [-v]]]\n" and exit unless @ARGV; +my $port = $ARGV[1] || 4440; +my $length = int($ARGV[2] || 1); $length = 1 if $length < 1; +my $verbose = $ARGV[3]; + +open FILE, '<', $ARGV[0] or die "$ARGV[0]: $!\n"; +my $file = ''; $file .= $_ while ; +close FILE; + +my $s = IO::Socket::INET->new(Proto => "tcp", PeerAddr => "localhost", PeerPort => $port) or die "localhost:$port: $!\n"; +$s->autoflush(1); + +my $c = 0; +while ($c < length $file) { + my $chunk = substr $file, $c, $length; + print "[$chunk]" if $verbose; + print $s $chunk; + $c += $length; +} + +print while <$s>; +close $s; From e72d576528fad3d6b708667660b9c4d281cbb025 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 29 Apr 2011 17:01:54 +0200 Subject: [PATCH 119/378] testServer: fixed list parsing --- test/packets/error-1-length | 1 - test/packets/error-2-list | 6 ------ test/testServer.c | 10 +++++++--- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/test/packets/error-1-length b/test/packets/error-1-length index 21c91fe..45f49d6 100644 --- a/test/packets/error-1-length +++ b/test/packets/error-1-length @@ -10,4 +10,3 @@ _message_foo_bar ohai there! \o/ | -| diff --git a/test/packets/error-2-list b/test/packets/error-2-list index b6ce6d5..f6fe4fe 100644 --- a/test/packets/error-2-list +++ b/test/packets/error-2-list @@ -17,9 +17,3 @@ _message_foo_bar ohai there! \o/ | -:_target psyc://foo.bar/~baz - -:_test 123 -_message_test -ohai! -| diff --git a/test/testServer.c b/test/testServer.c index 0092eaf..64a6f00 100644 --- a/test/testServer.c +++ b/test/testServer.c @@ -285,14 +285,18 @@ int main(int argc, char **argv) if (verbose) printf("\t\t\t\t\t\t\t\t# n:%ld v:%ld c:%ld r:%ld\n", pname->length, pvalue->length, parsers[i].contentParsed, parsers[i].routingLength); + } - if (name.length >= 5 && memcmp(name.ptr, "_list", 5) == 0) { + switch (ret) { + case PSYC_PARSE_ROUTING: + case PSYC_PARSE_ENTITY: + if (pname->length >= 5 && memcmp(pname->ptr, "_list", 5) == 0) { if (verbose) printf("## LIST START\n"); psyc_initParseListState(&listState); - psyc_nextParseListBuffer(&listState, value); + psyc_nextParseListBuffer(&listState, *pvalue); do { - retl = psyc_parseList(&listState, &name, &value, &elem); + retl = psyc_parseList(&listState, pname, pvalue, &elem); switch (retl) { case PSYC_PARSE_LIST_END: retl = 0; From ea3e40d575550409e38e99bc72b6c5bc86119953 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 29 Apr 2011 22:58:19 +0200 Subject: [PATCH 120/378] getVarType --- .gitignore | 1 + include/psyc.h | 19 ++++++---- src/variable.c | 97 +++++++++++++++++++++++++++++++++++++---------- test/Makefile | 2 +- test/getVarType.c | 21 ++++++++++ 5 files changed, 112 insertions(+), 28 deletions(-) create mode 100644 test/getVarType.c diff --git a/.gitignore b/.gitignore index c21bfb4..6248e5f 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ test/testParser test/testRender test/testServer test/isRoutingVar +test/getVarType .config ~$* diff --git a/include/psyc.h b/include/psyc.h index 5d75ced..93358f1 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -107,6 +107,12 @@ typedef struct const char *ptr; } psycString; +typedef struct +{ + psycString name; + int value; +} psycMatchVar; + /** * Shortcut for creating a psycString. * @@ -204,8 +210,7 @@ inline psycPacket psyc_newPacket2(psycModifier *routing, size_t routinglen, /// Routing vars in alphabetical order. extern const psycString PSYC_routingVars[]; -/// Number of routing vars. -extern const size_t PSYC_routingVarsNum; +extern const psycMatchVar PSYC_varTypes[]; /** * Get the type of variable name. @@ -215,7 +220,7 @@ psycBool psyc_isRoutingVar(const char *name, size_t len); /** * Get the type of variable name. */ -psycType psyc_getVarType(char *name, size_t len); +psycType psyc_getVarType(const char *name, size_t len); /** * Checks if long keyword string inherits from short keyword string. @@ -238,8 +243,8 @@ int psyc_matches(char *sho, size_t slen, * number of bytes written. 0 is a legal return value. Should the * callback return -1, psyc_text leaves the original template text as is. */ -typedef int (*psyctextCB)(uint8_t *match, size_t mlen, - uint8_t **buffer, size_t *blen); +typedef int (*psyctextCB)(char *match, size_t mlen, + char **buffer, size_t *blen); /** * Fills out text templates by asking a callback for content. @@ -254,8 +259,8 @@ typedef int (*psyctextCB)(uint8_t *match, size_t mlen, * * See also http://about.psyc.eu/psyctext */ -int psyc_text(uint8_t *template, size_t tlen, - uint8_t **buffer, size_t *blen, +int psyc_text(char *template, size_t tlen, + char **buffer, size_t *blen, psyctextCB lookupValue, char *braceOpen, char *braceClose); diff --git a/src/variable.c b/src/variable.c index 6273e68..a30805d 100644 --- a/src/variable.c +++ b/src/variable.c @@ -1,62 +1,83 @@ -#include +#include #include /// Routing variables in alphabetical order. -const psycString PSYC_routingVars[] = + +const psycString psyc_routingVars[] = { PSYC_C2STR("_amount_fragments"), PSYC_C2STR("_context"), //PSYC_C2STR("_count"), // older PSYC - PSYC_C2STR("_counter"), // the name for this is supposed to be _count, not _counter + PSYC_C2STR("_counter"), // the name for this is supposed to be _count, not _counter PSYC_C2STR("_fragment"), //PSYC_C2STR("_length"), // older PSYC PSYC_C2STR("_source"), - PSYC_C2STR("_source_identification"), + //PSYC_C2STR("_source_identification"), // older PSYC + PSYC_C2STR("_source_identity"), PSYC_C2STR("_source_relay"), - PSYC_C2STR("_source_relay_relay"), // until you have a better idea.. is this really in use? + PSYC_C2STR("_source_relay_relay"), // until you have a better idea.. is this really in use? PSYC_C2STR("_tag"), PSYC_C2STR("_tag_relay"), //PSYC_C2STR("_tag_reply"), // older PSYC PSYC_C2STR("_target"), PSYC_C2STR("_target_forward"), PSYC_C2STR("_target_relay"), - //PSYC_C2STR(19, "_understand_modules"), // older PSYC - //PSYC_C2STR(14, "_using_modules"), // older PSYC + //PSYC_C2STR("_understand_modules"), // older PSYC + //PSYC_C2STR("_using_modules"), // older PSYC }; -const size_t PSYC_routingVarsNum = sizeof(PSYC_routingVars) / sizeof(*PSYC_routingVars); +const psycMatchVar psyc_varTypes[] = +{ + {PSYC_C2STR("_amount"), PSYC_TYPE_AMOUNT}, + {PSYC_C2STR("_color"), PSYC_TYPE_COLOR}, + {PSYC_C2STR("_date"), PSYC_TYPE_DATE}, + {PSYC_C2STR("_degree"), PSYC_TYPE_DEGREE}, + {PSYC_C2STR("_entity"), PSYC_TYPE_ENTITY}, + {PSYC_C2STR("_flag"), PSYC_TYPE_FLAG}, + {PSYC_C2STR("_language"), PSYC_TYPE_LANGUAGE}, + {PSYC_C2STR("_list"), PSYC_TYPE_LIST}, + {PSYC_C2STR("_nick"), PSYC_TYPE_NICK}, + {PSYC_C2STR("_page"), PSYC_TYPE_PAGE}, + {PSYC_C2STR("_uniform"), PSYC_TYPE_UNIFORM}, + {PSYC_C2STR("_time"), PSYC_TYPE_TIME}, +}; + +const size_t psyc_routingVarsNum = PSYC_NUM_ELEM(psyc_routingVars); +const size_t psyc_varTypesNum = PSYC_NUM_ELEM(psyc_varTypes); /** * Get the type of variable name. */ psycBool psyc_isRoutingVar(const char *name, size_t len) { + //return psyc_matchArray(psyc_routingVars, PSYC_NUM_ELEM(psyc_routingVars), name, len, 0); size_t cursor = 1; - int8_t matching[PSYC_routingVarsNum]; // indexes of matching vars - memset(&matching, -1, sizeof(matching)); uint8_t i, m = 0; + int8_t matching[psyc_routingVarsNum]; // indexes of matching vars if (len < 2 || name[0] != '_') return PSYC_FALSE; // first find the vars with matching length - for (i=0; i= 0) { - for (i = m = 0; i < PSYC_routingVarsNum; i++) + for (i = m = 0; i < psyc_routingVarsNum; i++) { if (matching[i] < 0) - break; - if (PSYC_routingVars[matching[i]].ptr[cursor] == name[cursor]) + break; // reached the end of possible matches + if (psyc_routingVars[matching[i]].ptr[cursor] == name[cursor]) matching[m++] = matching[i]; // found a match, update matching indexes - else if (PSYC_routingVars[matching[i]].ptr[cursor] > name[cursor]) - break; // passed the possible matches in alphabetical order + else if (psyc_routingVars[matching[i]].ptr[cursor] > name[cursor]) + break; // passed the possible matches in alphabetical order in the array } - if (m < PSYC_routingVarsNum) + if (m < psyc_routingVarsNum) matching[m] = -1; // mark the end of matching indexes cursor++; @@ -68,7 +89,43 @@ psycBool psyc_isRoutingVar(const char *name, size_t len) /** * Get the type of variable name. */ -psycType psyc_getVarType(char *name, size_t len) +psycType psyc_getVarType(const char *name, size_t len) { - return PSYC_TYPE_UNKNOWN; + //return psyc_matchArray(psyc_varTypes, PSYC_NUM_ELEM(psyc_varTypes), name, len, 1); + size_t cursor = 1; + uint8_t i, m = 0; + int8_t matching[psyc_varTypesNum]; // indexes of matching vars + + if (len < 2 || name[0] != '_') + return 0; + + // first find the vars with matching length + for (i=0; i psyc_varTypes[i].name.length && name[psyc_varTypes[i].name.length] == '_')) + matching[m++] = i; + + matching[m] = -1; // mark the end of matching indexes + + while (cursor < len && matching[0] >= 0) + { + for (i = m = 0; i < psyc_varTypesNum; i++) + { + if (matching[i] < 0) + break; // reached the end of possible matches + if (cursor < psyc_varTypes[matching[i]].name.length && psyc_varTypes[matching[i]].name.ptr[cursor] == name[cursor]) + matching[m++] = matching[i]; // found a match, update matching indexes + else if (cursor == psyc_varTypes[matching[i]].name.length && name[cursor] == '_') + return psyc_varTypes[matching[0]].value; // _ after the end of a matching prefix + else if (psyc_varTypes[matching[i]].name.ptr[cursor] > name[cursor]) + break; // passed the possible matches in alphabetical order in the array + } + + if (m < psyc_varTypesNum) + matching[m] = -1; // mark the end of matching indexes + + cursor++; + } + + // return first match if found + return matching[0] >= 0 ? psyc_varTypes[matching[0]].value : 0; } diff --git a/test/Makefile b/test/Makefile index b1b58e3..37bdba3 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,7 +1,7 @@ CFLAGS=-I../include -DDEBUG -g -O0 -Wall LDFLAGS=-L../src LOADLIBES=-lpsyc -lm -TARGETS=testServer testParser testMatch testRender isRoutingVar +TARGETS=testServer testParser testMatch testRender isRoutingVar getVarType PORT=4440 all: $(TARGETS) diff --git a/test/getVarType.c b/test/getVarType.c new file mode 100644 index 0000000..bdf6d3c --- /dev/null +++ b/test/getVarType.c @@ -0,0 +1,21 @@ +#include +#include +#include +#include +#include "../include/psyc/lib.h" + +int main() { + unless (psyc_getVarType(PSYC_C2ARG("_list"))) return 1; + unless (psyc_getVarType(PSYC_C2ARG("_list_foo"))) return 2; + unless (psyc_getVarType(PSYC_C2ARG("_color_red"))) return 3; + if (psyc_getVarType(PSYC_C2ARG("_last"))) return 4; + if (psyc_getVarType(PSYC_C2ARG("_lost_foo"))) return 5; + if (psyc_getVarType(PSYC_C2ARG("_colorful"))) return 6; + if (psyc_getVarType(PSYC_C2ARG("_foo"))) return 7; + if (psyc_getVarType(PSYC_C2ARG("bar"))) return 8; + if (psyc_getVarType(PSYC_C2ARG("______"))) return 9; + if (psyc_getVarType(PSYC_C2ARG("_"))) return 10; + + puts("psyc_getVarType passed all tests."); + return 0; // passed all tests +} From 56371a3792b5b2da0b9a365cea27b723ae6b9768 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 29 Apr 2011 23:00:03 +0200 Subject: [PATCH 121/378] test: positive return codes; match: disabled strlen check --- src/match.c | 9 +++++---- test/isRoutingVar.c | 16 ++++++++-------- test/testMatch.c | 16 ++++++++-------- test/testParser.c | 2 +- test/testRender.c | 6 +++--- 5 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/match.c b/src/match.c index ab7918b..23cd067 100644 --- a/src/match.c +++ b/src/match.c @@ -7,8 +7,9 @@ int psyc_inherits(char* sho, size_t slen, // the length.. but we would be faster here if we expected the callee // to always use the PSYC_C2ARG() macro instead. additionally, the // empty string would then be fully supported (in case you want that) - if (!slen) slen = strlen(sho); - if (!llen) llen = strlen(lon); + // Disabled this, let's use that macro rather. + //if (!slen) slen = strlen(sho); + //if (!llen) llen = strlen(lon); if (slen == 0 || *sho != '_' || llen == 0 || *lon != '_') { @@ -45,8 +46,8 @@ int psyc_matches(char* sho, size_t slen, char* lon, size_t llen) { char *s, *l, *se, *le; - if (!slen) slen = strlen(sho); - if (!llen) llen = strlen(lon); + //if (!slen) slen = strlen(sho); + //if (!llen) llen = strlen(lon); if (slen == 0 || *sho != '_' || llen == 0 || *lon != '_') { diff --git a/test/isRoutingVar.c b/test/isRoutingVar.c index c0eacd8..f2d0ceb 100644 --- a/test/isRoutingVar.c +++ b/test/isRoutingVar.c @@ -24,14 +24,14 @@ int main() { printf("%s: %d\n", vars[i], psyc_isRoutingVar(vars[i], strlen(vars[i]))); } #else - unless (psyc_isRoutingVar(PSYC_C2ARG("_source"))) return -1; - unless (psyc_isRoutingVar(PSYC_C2ARG("_source_relay"))) return -2; - if (psyc_isRoutingVar(PSYC_C2ARG("_source_foo"))) return -3; - if (psyc_isRoutingVar(PSYC_C2ARG("_sourcherry"))) return -4; - if (psyc_isRoutingVar(PSYC_C2ARG("_sour"))) return -5; - if (psyc_isRoutingVar(PSYC_C2ARG("_foo"))) return -6; - if (psyc_isRoutingVar(PSYC_C2ARG("bar"))) return -7; - if (psyc_isRoutingVar(PSYC_C2ARG("_"))) return -8; + unless (psyc_isRoutingVar(PSYC_C2ARG("_source"))) return 1; + unless (psyc_isRoutingVar(PSYC_C2ARG("_source_relay"))) return 2; + if (psyc_isRoutingVar(PSYC_C2ARG("_source_foo"))) return 3; + if (psyc_isRoutingVar(PSYC_C2ARG("_sourcherry"))) return 4; + if (psyc_isRoutingVar(PSYC_C2ARG("_sour"))) return 5; + if (psyc_isRoutingVar(PSYC_C2ARG("_foo"))) return 6; + if (psyc_isRoutingVar(PSYC_C2ARG("bar"))) return 7; + if (psyc_isRoutingVar(PSYC_C2ARG("_"))) return 8; puts("psyc_isRoutingVar passed all tests."); #endif diff --git a/test/testMatch.c b/test/testMatch.c index b6695d3..b43f036 100644 --- a/test/testMatch.c +++ b/test/testMatch.c @@ -2,17 +2,17 @@ #include "../include/psyc/lib.h" int main() { - if (psyc_matches("_failure_delivery", 0, "_failure_unsuccessful_delivery_death", 0)) return -1; - if (psyc_matches("_failure_trash", 8, "_failure_unsuccessful_delivery_death", 0)) return -2; - if (psyc_matches("_unsuccessful", 0, "_failure_unsuccessful_delivery_death", 0)) return -3; - unless (psyc_matches("_fail", 0, "_failure_unsuccessful_delivery_death", 0)) return -4; - unless (psyc_matches("_truthahn", 0, "_failure_unsuccessful_delivery_death", 0)) return -5; + if (psyc_matches("_failure_delivery", 0, "_failure_unsuccessful_delivery_death", 0)) return 1; + if (psyc_matches("_failure_trash", 8, "_failure_unsuccessful_delivery_death", 0)) return 2; + if (psyc_matches("_unsuccessful", 0, "_failure_unsuccessful_delivery_death", 0)) return 3; + unless (psyc_matches("_fail", 0, "_failure_unsuccessful_delivery_death", 0)) return 4; + unless (psyc_matches("_truthahn", 0, "_failure_unsuccessful_delivery_death", 0)) return 5; puts("psyc_matches passed all tests."); - unless (psyc_inherits("_failure_delivery", 0, "_failure_unsuccessful_delivery_death", 0)) return -11; - if (psyc_inherits("_failure_unsuccessful", 0, "_failure_unsuccessful_delivery_death", 0)) return -12; - unless (psyc_inherits("_fail", 0, "_failure_unsuccessful_delivery_death", 0)) return -13; + unless (psyc_inherits("_failure_delivery", 0, "_failure_unsuccessful_delivery_death", 0)) return 11; + if (psyc_inherits("_failure_unsuccessful", 0, "_failure_unsuccessful_delivery_death", 0)) return 12; + unless (psyc_inherits("_fail", 0, "_failure_unsuccessful_delivery_death", 0)) return 13; puts("psyc_inherits passed all tests."); diff --git a/test/testParser.c b/test/testParser.c index 0473e88..fc30905 100644 --- a/test/testParser.c +++ b/test/testParser.c @@ -83,7 +83,7 @@ int main(int argc, char **argv) continue; case PSYC_PARSE_INSUFFICIENT: printf("Insufficient data.\n"); - return -1; + return 1; default: printf("Error while parsing: %i\n", ret); return 1; diff --git a/test/testRender.c b/test/testRender.c index 249ead2..79681d5 100644 --- a/test/testRender.c +++ b/test/testRender.c @@ -32,7 +32,7 @@ int testPresence(const char *avail, int availlen, const char *desc, int desclen, psyc_render(&packet, buffer, sizeof(buffer)); if (verbose) write(0, buffer, packet.length); - return strncmp(rendered, buffer, packet.length); + return strncmp(rendered, buffer, packet. } int testList(const char *rendered, uint8_t verbose) @@ -94,7 +94,7 @@ int main(int argc, char **argv) { =_description_presence\tI'm omnipresent right now\n\ _notice_presence\n\ |\n", verbose)) - return -1; + return 1; if (testList("\ :_source psyc://10.100.1000/~ludwig\n\ @@ -106,7 +106,7 @@ qux\n\ _test_list\n\ list test\n\ |\n", verbose)) - return -2; + return 2; puts("psyc_render passed all tests."); From cb2132ef93675ce0846258889658e75de2ca1e52 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 29 Apr 2011 23:11:40 +0200 Subject: [PATCH 122/378] testMatch: use C2ARG --- test/testMatch.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/testMatch.c b/test/testMatch.c index b43f036..cdac58a 100644 --- a/test/testMatch.c +++ b/test/testMatch.c @@ -2,17 +2,17 @@ #include "../include/psyc/lib.h" int main() { - if (psyc_matches("_failure_delivery", 0, "_failure_unsuccessful_delivery_death", 0)) return 1; - if (psyc_matches("_failure_trash", 8, "_failure_unsuccessful_delivery_death", 0)) return 2; - if (psyc_matches("_unsuccessful", 0, "_failure_unsuccessful_delivery_death", 0)) return 3; - unless (psyc_matches("_fail", 0, "_failure_unsuccessful_delivery_death", 0)) return 4; - unless (psyc_matches("_truthahn", 0, "_failure_unsuccessful_delivery_death", 0)) return 5; + if (psyc_matches(PSYC_C2ARG("_failure_delivery"), PSYC_C2ARG("_failure_unsuccessful_delivery_death"))) return 1; + if (psyc_matches(PSYC_C2ARG("_failure"), PSYC_C2ARG("_failure_unsuccessful_delivery_death"))) return 2; + if (psyc_matches(PSYC_C2ARG("_unsuccessful"), PSYC_C2ARG("_failure_unsuccessful_delivery_death"))) return 3; + unless (psyc_matches(PSYC_C2ARG("_fail"), PSYC_C2ARG("_failure_unsuccessful_delivery_death"))) return 4; + unless (psyc_matches(PSYC_C2ARG("_truthahn"), PSYC_C2ARG("_failure_unsuccessful_delivery_death"))) return 5; puts("psyc_matches passed all tests."); - unless (psyc_inherits("_failure_delivery", 0, "_failure_unsuccessful_delivery_death", 0)) return 11; - if (psyc_inherits("_failure_unsuccessful", 0, "_failure_unsuccessful_delivery_death", 0)) return 12; - unless (psyc_inherits("_fail", 0, "_failure_unsuccessful_delivery_death", 0)) return 13; + unless (psyc_inherits(PSYC_C2ARG("_failure_delivery"), PSYC_C2ARG("_failure_unsuccessful_delivery_death"))) return 11; + if (psyc_inherits(PSYC_C2ARG("_failure_unsuccessful"), PSYC_C2ARG("_failure_unsuccessful_delivery_death"))) return 12; + unless (psyc_inherits(PSYC_C2ARG("_fail"), PSYC_C2ARG("_failure_unsuccessful_delivery_death"))) return 13; puts("psyc_inherits passed all tests."); From 47e7af73547d043e42806a9c42147aff2379faf8 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 29 Apr 2011 23:11:48 +0200 Subject: [PATCH 123/378] + --- test/Makefile | 1 + test/testRender.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/test/Makefile b/test/Makefile index 37bdba3..158a3c5 100644 --- a/test/Makefile +++ b/test/Makefile @@ -8,6 +8,7 @@ all: $(TARGETS) ./testRender ./testMatch ./isRoutingVar + ./getVarType test: $(TARGETS) for f in packets/full-* packets/error-*; do echo ">> $$f"; ./testParser $$f; done diff --git a/test/testRender.c b/test/testRender.c index 79681d5..7d2ac5d 100644 --- a/test/testRender.c +++ b/test/testRender.c @@ -32,7 +32,7 @@ int testPresence(const char *avail, int availlen, const char *desc, int desclen, psyc_render(&packet, buffer, sizeof(buffer)); if (verbose) write(0, buffer, packet.length); - return strncmp(rendered, buffer, packet. + return strncmp(rendered, buffer, packet.length); } int testList(const char *rendered, uint8_t verbose) From 9dfa030e49ae8c39e6f90e7e2e7c129c1ef2d2ed Mon Sep 17 00:00:00 2001 From: Marenz Date: Sat, 30 Apr 2011 12:56:07 +0200 Subject: [PATCH 124/378] renamed lib target to glibc. Puts .a file now in lib/ --- Makefile | 4 ++-- src/Makefile | 14 +++++++++----- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index c0c5d6f..0dd1c65 100644 --- a/Makefile +++ b/Makefile @@ -4,8 +4,8 @@ default: @/bin/echo -e "Usage:\n\tmake diet - compile with diet libc\n\tmake lib - compile with normal gnu libc\n\tmake test\n\tmake doc" -lib: - make -C src lib +glibc: + make -C src glibc diet: make -C src diet diff --git a/src/Makefile b/src/Makefile index 7e464c2..6447d44 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,6 +2,8 @@ CFLAGS=-I../include -DDEBUG=2 -DPSYC_COMPILE_LIBRARY -g -O0 -Wall CC=cc # CC=clang +test -z "$DIET" || DIET=diet + S=packet.c misc.c parser.c match.c render.c memmem.c itoa.c variable.c O=packet.o misc.o parser.o match.o render.o memmem.o itoa.o variable.o @@ -9,12 +11,14 @@ 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 ${CFLAGS} - diet ar rcs libpsyc.a $O + ${DIET} ${CC} -static -c -Os $S ${CFLAGS} + @test -d ../lib || mkdir ../lib + ${DIET} ar rcs ../lib/libpsyc.a $O -lib: $S +glibc: $S ${CC} -static -c -g -O0 $S -lc ${CFLAGS} - ar rcs libpsyc.a $O + @test -d ../lib || mkdir ../lib + ar rcs ../lib/libpsyc.a $O match: match.c ${CC} -o $@ -DDEBUG=4 -DCMDTOOL -DTEST $< @@ -25,4 +29,4 @@ itoa: itoa.c it: match clean: - rm -f $O + rm -f $O ../lib/libpsyc.a From bc14c0985f37d66341cf6f2be9b3dcdbd7d0c77d Mon Sep 17 00:00:00 2001 From: Marenz Date: Sat, 30 Apr 2011 12:57:06 +0200 Subject: [PATCH 125/378] added lib dir to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index e802e07..d51a447 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +lib doc/html doc/latex doc/man From 03dede07b30e46bbfe40e7ca781368e9a71dc4dc Mon Sep 17 00:00:00 2001 From: Marenz Date: Sat, 30 Apr 2011 13:09:24 +0200 Subject: [PATCH 126/378] fixed makefile for test, fixed help output --- Makefile | 2 +- test/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 0dd1c65..c446fe6 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ .PHONY: test default: - @/bin/echo -e "Usage:\n\tmake diet - compile with diet libc\n\tmake lib - compile with normal gnu libc\n\tmake test\n\tmake doc" + @/bin/echo -e "Usage:\n\tmake diet - compile with diet libc\n\tmake glibc - compile with normal gnu libc\n\tmake test\n\tmake doc" glibc: make -C src glibc diff --git a/test/Makefile b/test/Makefile index 158a3c5..d3f2324 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,5 +1,5 @@ CFLAGS=-I../include -DDEBUG -g -O0 -Wall -LDFLAGS=-L../src +LDFLAGS=-L../lib LOADLIBES=-lpsyc -lm TARGETS=testServer testParser testMatch testRender isRoutingVar getVarType PORT=4440 From 28400d0553610ce49e3a30bc2ec690a06eecef23 Mon Sep 17 00:00:00 2001 From: Marenz Date: Sat, 30 Apr 2011 14:30:01 +0200 Subject: [PATCH 127/378] added first draft for d binding --- include/d/psyc/parser.d | 166 +++++++++++++++++++++++++ include/d/psyc/psyc.d | 262 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 428 insertions(+) create mode 100644 include/d/psyc/parser.d create mode 100644 include/d/psyc/psyc.d diff --git a/include/d/psyc/parser.d b/include/d/psyc/parser.d new file mode 100644 index 0000000..19e343f --- /dev/null +++ b/include/d/psyc/parser.d @@ -0,0 +1,166 @@ +module psyc.parser; + +import psyc.psyc; + +/** + * @file d/psyc/parser.d + * @brief D Interface for various PSYC parser functions. + * + * All parsing functions and the definitions they use are + * defined in this file. +*/ + +/** + * @defgroup parsing-d Parsing Functions + * + * This module contains all parsing functions. + * @{ + */ + +extern (C): + +enum ParseFlag +{ + PARSE_HEADER_ONLY = 1, +} + +/** + * The return value definitions for the packet parsing function. + * @see parse() + */ +enum ParseRC +{ + PARSE_ERROR_END = -9, + PARSE_ERROR_BODY = -8, + PARSE_ERROR_METHOD = -7, + PARSE_ERROR_MOD_NL = -6, + PARSE_ERROR_MOD_LEN = -5, + PARSE_ERROR_MOD_TAB = -4, + PARSE_ERROR_MOD_NAME = -3, + PARSE_ERROR_LENGTH = -2, + PARSE_ERROR = -1, + PARSE_SUCCESS = 0, +/// Buffer contains insufficient amount of data. +/// Fill another buffer and concatenate it with the end of the current buffer, +/// from the cursor position to the end. + PARSE_INSUFFICIENT = 1, +/// Routing modifier parsing done. +/// Operator, name & value contains the respective parts. + PARSE_ROUTING = 2, +/// Entity modifier parsing done. +/// Operator, name & value contains the respective parts. + PARSE_ENTITY = 3, +/// Entity modifier parsing is incomplete. +/// Operator & name are complete, value is incomplete. + PARSE_ENTITY_INCOMPLETE = 4, +/// Body parsing done, name contains method, value contains body. + PARSE_BODY = 5, +/// Body parsing is incomplete, name contains method, value contains part of the body. + PARSE_BODY_INCOMPLETE = 6, +/// Reached end of packet, parsing done. + PARSE_COMPLETE = 7, +/// Binary value parsing incomplete, used internally. + PARSE_INCOMPLETE = 8, +} + +/** + * The return value definitions for the list parsing function. + * @see parseList() + */ +enum ParseListRC +{ + PARSE_LIST_ERROR_DELIM = -5, + PARSE_LIST_ERROR_LEN = -4, + PARSE_LIST_ERROR_TYPE = -3, + PARSE_LIST_ERROR_NAME = -2, + PARSE_LIST_ERROR= -1, +/// Completed parsing a list element. + PARSE_LIST_ELEM = 1, +/// Reached end of buffer. + PARSE_LIST_END = 2, +/// Binary list is incomplete. + PARSE_LIST_INCOMPLETE = 3, +} + +/** + * Struct for keeping parser state. + */ +struct ParseState +{ + size_t cursor; ///< current position in buffer + size_t startc; ///< position where the parsing would be resumed + String buffer; ///< buffer with data to be parsed + ubyte flags; ///< flags for the parser, see ParseFlag + Part part; ///< part of the packet being parsed currently + + size_t routingLength; ///< length of routing part parsed so far + size_t contentParsed; ///< number of bytes parsed from the content so far + size_t contentLength; ///< expected length of the content + Bool 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 +} + +/** + * Struct for keeping list parser state. + */ +struct ParseListState +{ + size_t cursor; ///< current position in buffer + size_t startc; ///< line start position + String buffer; + ListType type; ///< list type + + size_t elemParsed; ///< number of bytes parsed from the elem so far + size_t elemLength; ///< expected length of the elem +} + +/** + * Initiates the state struct. + * + * @param state Pointer to the state struct that should be initiated. + */ +void psyc_initParseState (ParseState* state); + +/** + * Initiates the state struct with flags. + * + * @param state Pointer to the state struct that should be initiated. + * @param flags Flags to be set for the parser, see ParseFlag. + */ +void psyc_initParseState2 (ParseState* state, ubyte flags); + +/** + * Initiates the list state struct. + * + * @param state Pointer to the list state struct that should be initiated. + */ +void psyc_initParseListState (ParseListState* state); + +void psyc_nextParseBuffer (ParseState* state, String newBuf); + +void psyc_nextParseListBuffer (ParseListState* state, String newBuf); + +size_t psyc_getContentLength (ParseState* s); + +/** + * Parse PSYC packets. + * + * Generalized line-based packet parser. + * + * @param state An initialized ParseState + * @param oper A pointer to a character. In case of a variable, it will + * be set to the operator of that variable + * @param name A pointer to a String. It will point to the name of + * the variable or method and its length will be set accordingly + * @param value A pointer to a String. It will point to the + * value/body the variable/method and its length will be set accordingly + */ +ParseRC psyc_parse(ParseState* state, char* oper, String* name, String* value); + +/** + * List value parser. + */ +ParseListRC psyc_parseList(ParseListState* state, String *name, String* value, String* elem); + +/** @} */ // end of parsing group diff --git a/include/d/psyc/psyc.d b/include/d/psyc/psyc.d new file mode 100644 index 0000000..cb66937 --- /dev/null +++ b/include/d/psyc/psyc.d @@ -0,0 +1,262 @@ +/** @file d/.d + * + * @brief Main PSYC interface providing crucial functionality. +*/ + +/** @mainpage PSYC Core Library + * + * @section intro_sec Introduction + * + * This is the introduction. + * + * @section install_sec Installation + * + * @subsection step1 Step 1: Opening the box + * + * etc... + */ + +EPOCH = 1440444041 // 2015-08-24 21:20:41 CET (Monday) + +extern (C): + +enum Bool +{ + FALSE = 0, + TRUE = 1, +} + +/** + * PSYC packet parts. + */ +enum Part +{ + PART_RESET = -1, + PART_ROUTING, + PART_LENGTH, + PART_CONTENT, + PART_METHOD, + PART_DATA, + PART_END, +} + +/** + * Different types that a variable can have. + * + * This enum lists PSYC variable types that + * this library is capable of checking for + * validity. Other variable types are treated + * as opaque data. + */ +enum Type +{ + TYPE_UNKNOWN, + TYPE_AMOUNT, + TYPE_COLOR, + TYPE_DATE, + TYPE_DEGREE, + TYPE_ENTITY, + TYPE_FLAG, + TYPE_LANGUAGE, + TYPE_LIST, + TYPE_NICK, + TYPE_PAGE, + TYPE_UNIFORM, + TYPE_TIME, +} + +/** + * List types. + * Possible types are text and binary. + */ +enum ListType +{ + LIST_TEXT = 1, + LIST_BINARY = 2, +} + +enum ModifierFlag +{ + MODIFIER_CHECK_LENGTH = 0, + MODIFIER_NEED_LENGTH = 1, + MODIFIER_NO_LENGTH = 2, + MODIFIER_ROUTING = 3, +} + +enum ListFlag +{ + LIST_CHECK_LENGTH = 0, + LIST_NEED_LENGTH = 1, + LIST_NO_LENGTH = 2, +} + +enum PacketFlag +{ + PACKET_CHECK_LENGTH = 0, + PACKET_NEED_LENGTH = 1, + PACKET_NO_LENGTH = 2, +} + +struct String +{ + size_t length; + char *ptr; +} + +struct MatchVar +{ + String name; + int value; +} + +/** +* Shortcut for creating a String. + * + * @param memory Pointer to the buffer. + * @param length Length of that buffer. + * + * @return An instance of the String struct. + */ +String newString (char *str, size_t strlen); + +#define C2STR(_string) {sizeof(_string)-1, _string} +#define C2ARG(_string) _string, sizeof(_string)-1 + +/* intermediate struct for a PSYC variable modification */ +struct Modifier +{ + char oper; // not call it 'operator' as C++ may not like that.. + String name; + String value; + ModifierFlag flag; +} + +struct Header +{ + size_t lines; + Modifier *modifiers; +} + +struct List +{ + size_t num_elems; + String *elems; + size_t length; + ListFlag flag; +} + +/* intermediate struct for a PSYC packet */ +struct Packet +{ + Header routing; ///< Routing header. + Header entity; ///< Entity header. + String method; + String data; + size_t routingLength; ///< Length of routing part. + size_t contentLength; ///< Length of content part. + size_t length; ///< Total length of packet. + PacketFlag flag; +} + +int psyc_version(); + +/** Check if a modifier needs length */ +ModifierFlag checkModifierLength(Modifier *m); + +/** Get the total length of a modifier. */ +size_t getModifierLength(Modifier *m); + +/** Create new modifier */ +Modifier newModifier(char oper, String *name, String *value, + ModifierFlag flag); + +/** Create new modifier */ +Modifier newModifier2(char oper, + char *name, size_t namelen, + char *value, size_t valuelen, + ModifierFlag flag); + +/** Check if a list needs length */ +ListFlag checkListLength(List *list); + +/** Get the total length of a list. */ +ListFlag getListLength(List *list); + +/** Check if a packet needs length */ +PacketFlag checkPacketLength(Packet *p); + +/** Calculate and set the length of packet parts and total packet length */ +size_t setPacketLength(Packet *p); + +/** Create new list */ +List newList(String *elems, size_t num_elems, ListFlag flag); + +/** Create new packet */ +Packet newPacket(Header *routing, + Header *entity, + String *method, String *data, + PacketFlag flag); + +/** Create new packet */ +Packet newPacket2(Modifier *routing, size_t routinglen, + Modifier *entity, size_t entitylen, + char *method, size_t methodlen, + char *data, size_t datalen, + PacketFlag flag); + +/// Routing vars in alphabetical order. +extern (C) String routingVars[]; +extern (C) MatchVar varTypes[]; + +/** + * Get the type of variable name. + */ +Bool isRoutingVar(char *name, size_t len); + +/** + * Get the type of variable name. + */ +Type getVarType(char *name, size_t len); + +/** + * Checks if long keyword string inherits from short keyword string. + */ +int inherits(char *sho, size_t slen, + char *lon, size_t llen); + +/** + * Checks if short keyword string matches long keyword string. + */ +int matches(char *sho, size_t slen, + char *lon, size_t llen); + +/** + * Callback for text() that produces a value for a match. + * + * The application looks up a match such as _fruit from [_fruit] and + * if found writes its current value from its variable store into the + * outgoing buffer.. "Apple" for example. The template returns the + * number of bytes written. 0 is a legal return value. Should the + * callback return -1, text leaves the original template text as is. + */ +typedef int (*textCB)(char *match, size_t mlen, + char **buffer, size_t *blen); + +/** + * Fills out text templates by asking a callback for content. + * + * Copies the contents of the template into the buffer while looking + * for braceOpen and braceClose strings and calling the callback for + * each enclosed string between these braces. Should the callback + * return -1, the original template text is copied as is. + * + * By default PSYC's "[" and "]" are used but you can provide any other + * brace strings such as "${" and "}" or "". + * + * See also http://about..eu/text + */ +int text(char *template, size_t tlen, + char **buffer, size_t *blen, + textCB lookupValue, + char *braceOpen, char *braceClose); + From 14feb9dc08917f44a700886d4cd329cc71637802 Mon Sep 17 00:00:00 2001 From: Marenz Date: Sat, 30 Apr 2011 14:39:04 +0200 Subject: [PATCH 128/378] more work on the d binding --- include/d/psyc/{psyc.d => common.d} | 12 +++++------- include/d/psyc/parser.d | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-) rename include/d/psyc/{psyc.d => common.d} (94%) diff --git a/include/d/psyc/psyc.d b/include/d/psyc/common.d similarity index 94% rename from include/d/psyc/psyc.d rename to include/d/psyc/common.d index cb66937..efb5a90 100644 --- a/include/d/psyc/psyc.d +++ b/include/d/psyc/common.d @@ -16,7 +16,9 @@ * etc... */ -EPOCH = 1440444041 // 2015-08-24 21:20:41 CET (Monday) +module psyc.common; + +const EPOCH = 1440444041; // 2015-08-24 21:20:41 CET (Monday) extern (C): @@ -119,9 +121,6 @@ struct MatchVar */ String newString (char *str, size_t strlen); -#define C2STR(_string) {sizeof(_string)-1, _string} -#define C2ARG(_string) _string, sizeof(_string)-1 - /* intermediate struct for a PSYC variable modification */ struct Modifier { @@ -239,8 +238,7 @@ int matches(char *sho, size_t slen, * number of bytes written. 0 is a legal return value. Should the * callback return -1, text leaves the original template text as is. */ -typedef int (*textCB)(char *match, size_t mlen, - char **buffer, size_t *blen); +alias extern (C) int function (char *match, size_t mlen, char **buffer, size_t *blen) textCB; /** * Fills out text templates by asking a callback for content. @@ -255,7 +253,7 @@ typedef int (*textCB)(char *match, size_t mlen, * * See also http://about..eu/text */ -int text(char *template, size_t tlen, +int text(char *_template, size_t tlen, char **buffer, size_t *blen, textCB lookupValue, char *braceOpen, char *braceClose); diff --git a/include/d/psyc/parser.d b/include/d/psyc/parser.d index 19e343f..4345d52 100644 --- a/include/d/psyc/parser.d +++ b/include/d/psyc/parser.d @@ -1,6 +1,6 @@ module psyc.parser; -import psyc.psyc; +import psyc.common; /** * @file d/psyc/parser.d From d48aa1e53ba2fcb8ad8269d32b97b2b255bbc95b Mon Sep 17 00:00:00 2001 From: Marenz Date: Sat, 30 Apr 2011 15:35:34 +0200 Subject: [PATCH 129/378] added flag to parse only contents of a packet --- include/psyc/parser.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index ffac7d9..f1e8412 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -22,6 +22,8 @@ typedef enum { PSYC_PARSE_HEADER_ONLY = 1, + /// Expects only the content part of a packet. The length of the content must fit exactly in this case + PSYC_BEGIN_PARSE_AT_CONTENT = 2, } psycParseFlag; /** From 166b73d5abde8070196e9798554d2521c60e6aad Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sat, 30 Apr 2011 15:42:48 +0200 Subject: [PATCH 130/378] Makefile improvements --- Makefile | 9 +++++---- src/Makefile | 34 +++++++++++++++++++--------------- test/Makefile | 45 ++++++++++++++++++++++++++++----------------- 3 files changed, 52 insertions(+), 36 deletions(-) diff --git a/Makefile b/Makefile index c446fe6..86f7430 100644 --- a/Makefile +++ b/Makefile @@ -1,17 +1,18 @@ .PHONY: doc .PHONY: test +.PHONY: lib default: @/bin/echo -e "Usage:\n\tmake diet - compile with diet libc\n\tmake glibc - compile with normal gnu libc\n\tmake test\n\tmake doc" -glibc: - make -C src glibc +lib: + ${MAKE} -C src lib diet: - make -C src diet + ${MAKE} -C src diet test: - make -C test + ${MAKE} -C test doc: doxygen diff --git a/src/Makefile b/src/Makefile index 6447d44..c8a0f88 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,24 +1,28 @@ -CFLAGS=-I../include -DDEBUG=2 -DPSYC_COMPILE_LIBRARY -g -O0 -Wall -CC=cc -# CC=clang +OPT = -O2 +DEBUG = 2 +CFLAGS = -I../include -Wall ${OPT} +DIET = diet +WRAPPER = -test -z "$DIET" || DIET=diet +S = packet.c misc.c parser.c match.c render.c memmem.c itoa.c variable.c +O = packet.o misc.o parser.o match.o render.o memmem.o itoa.o variable.o -S=packet.c misc.c parser.c match.c render.c memmem.c itoa.c variable.c -O=packet.o misc.o parser.o match.o render.o memmem.o itoa.o variable.o +all: lib -default: +help: @/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 ${CFLAGS} - @test -d ../lib || mkdir ../lib - ${DIET} ar rcs ../lib/libpsyc.a $O +debug: CFLAGS += -DDEBUG=${DEBUG} -g +debug: CFLAGS := $(subst ${OPT},-O0,${CFLAGS}) +debug: lib -glibc: $S - ${CC} -static -c -g -O0 $S -lc ${CFLAGS} - @test -d ../lib || mkdir ../lib - ar rcs ../lib/libpsyc.a $O +diet: WRAPPER = ${DIET} +diet: lib + +lib: CC := ${WRAPPER} ${CC} +lib: $O + @mkdir -p ../lib + ${WRAPPER} ar rcs ../lib/libpsyc.a $O match: match.c ${CC} -o $@ -DDEBUG=4 -DCMDTOOL -DTEST $< diff --git a/test/Makefile b/test/Makefile index d3f2324..d2f2796 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,40 +1,51 @@ -CFLAGS=-I../include -DDEBUG -g -O0 -Wall -LDFLAGS=-L../lib -LOADLIBES=-lpsyc -lm -TARGETS=testServer testParser testMatch testRender isRoutingVar getVarType -PORT=4440 +OPT = -O2 +DEBUG = 2 +CFLAGS = -I../include -Wall ${OPT} +LDFLAGS = -L../lib +LOADLIBES = -lpsyc -lm +TARGETS = testServer testParser testMatch testRender isRoutingVar getVarType +WRAPPER = +DIET = diet +PORT = 4440 -all: $(TARGETS) +all: test + +diet: WRAPPER = ${DIET} +diet: all + +debug: CFLAGS += -DDEBUG=${DEBUG} -g +debug: CFLAGS := $(subst ${OPT},-O0,${CFLAGS}) +debug: all + +test: ${TARGETS} ./testRender ./testMatch ./isRoutingVar ./getVarType - -test: $(TARGETS) - for f in packets/full-* packets/error-*; do echo ">> $$f"; ./testParser $$f; done + for f in packets/full-*; do echo ">> $$f"; ./testParser $$f; done netstart: - ./testServer $(PORT) + ./testServer ${PORT} netstartv: - ./testServer $(PORT) -v + ./testServer ${PORT} -v nettest: - for f in packets/full-*; do echo ">> $$f"; cat $$f | nc localhost $(PORT) | diff -u $$f -; done + for f in packets/full-*; do echo ">> $$f"; cat $$f | nc localhost ${PORT} | diff -u $$f -; done nettesterr: - for f in packets/error-*; do echo ">> $$f"; cat $$f | nc localhost $(PORT); done + for f in packets/error-*; do echo ">> $$f"; cat $$f | nc localhost ${PORT}; done splittest: - for f in packets/full-*; do echo ">> $$f"; ./splittest.pl $$f $(PORT) | diff -u $$f -; done + for f in packets/full-*; do echo ">> $$f"; ./splittest.pl $$f ${PORT} | diff -u $$f -; done nettestp1: - (for f in packets/part-1-p*; do cat $$f; done) | nc localhost $(PORT) | diff -u packets/full-1 - + (for f in packets/part-1-p*; do cat $$f; done) | nc localhost ${PORT} | diff -u packets/full-1 - nettestp2: - (for f in packets/part-1-length-p*; do cat $$f; done) | nc localhost $(PORT) | diff -u packets/full-1-length - + (for f in packets/part-1-length-p*; do cat $$f; done) | nc localhost ${PORT} | diff -u packets/full-1-length - clean: - rm -f $(TARGETS) + rm -f ${TARGETS} it: all From 10e8deff472744637595ada7ff78331bbdc216ac Mon Sep 17 00:00:00 2001 From: Marenz Date: Sat, 30 Apr 2011 15:43:00 +0200 Subject: [PATCH 131/378] adjusted functions for flag PARSE_BEGIN_AT_CONTENT --- include/d/psyc/parser.d | 1 + include/psyc/parser.h | 2 +- src/parser.c | 13 ++++++++++++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/include/d/psyc/parser.d b/include/d/psyc/parser.d index 4345d52..1d03adc 100644 --- a/include/d/psyc/parser.d +++ b/include/d/psyc/parser.d @@ -22,6 +22,7 @@ extern (C): enum ParseFlag { PARSE_HEADER_ONLY = 1, + PARSE_BEGIN_AT_CONTENT = 2, } /** diff --git a/include/psyc/parser.h b/include/psyc/parser.h index f1e8412..bff444d 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -23,7 +23,7 @@ typedef enum { PSYC_PARSE_HEADER_ONLY = 1, /// Expects only the content part of a packet. The length of the content must fit exactly in this case - PSYC_BEGIN_PARSE_AT_CONTENT = 2, + PSYC_PARSE_BEGIN_AT_CONTENT = 2, } psycParseFlag; /** diff --git a/src/parser.c b/src/parser.c index 501c300..914e483 100644 --- a/src/parser.c +++ b/src/parser.c @@ -24,6 +24,9 @@ inline void psyc_initParseState2 (psycParseState* state, uint8_t flags) { memset(state, 0, sizeof(psycParseState)); state->flags = flags; + + if (flags & PSYC_PARSE_BEGIN_AT_CONTENT) + state->part = PSYC_PART_CONTENT; } inline void psyc_initParseListState (psycParseListState* state) @@ -33,6 +36,12 @@ inline void psyc_initParseListState (psycParseListState* state) inline void psyc_nextParseBuffer (psycParseState* state, psycString newBuf) { + if (state->flags & PSYC_PARSE_BEGIN_AT_CONTENT) + { + state->contentLength = newBuf.length; + state->contentLengthFound = PSYC_TRUE; + } + state->buffer = newBuf; state->cursor = 0; } @@ -275,6 +284,7 @@ psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psyc { state->contentLengthFound = 1; state->contentLength = 0; + do { state->contentLength = 10 * state->contentLength + state->buffer.ptr[state->cursor] - '0'; @@ -308,7 +318,8 @@ psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psyc case PSYC_PART_CONTENT: // In case of an incomplete binary variable resume parsing it. - if (state->valueParsed < state->valueLength) { + if (state->valueParsed < state->valueLength) + { ret = psyc_parseBinaryValue(state, value, &(state->valueLength), &(state->valueParsed)); state->contentParsed += value->length; From b24592cf02abedabf0e5c532be54c554e928a0bf Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sat, 30 Apr 2011 15:44:12 +0200 Subject: [PATCH 132/378] match: fixed warnings --- src/match.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/match.c b/src/match.c index 23cd067..22d6ced 100644 --- a/src/match.c +++ b/src/match.c @@ -38,7 +38,7 @@ int psyc_inherits(char* sho, size_t slen, } return 0; } - P4(("%*s does not inherit from %*s.\n", llen, lon, slen, sho)) + P4(("%.*s does not inherit from %.*s.\n", (int)llen, lon, (int)slen, sho)) return 1; } @@ -68,19 +68,19 @@ int psyc_matches(char* sho, size_t slen, P1(("Same length but different.\nNo match, but they could be related or have a common type.\n")) return -4; } - P3(("# psyc_matches short '%*s' in long '%*s' ?\n", slen, sho, llen, lon)) + P3(("# psyc_matches short '%.*s' in long '%.*s' ?\n", (int)slen, sho, (int)llen, lon)) se = sho+slen; le = lon+llen; sho++; lon++; slen--; llen--; while(*sho && sho < se) { - P3(("# comparing short '%*s' (%d)\n", slen, sho, slen)) + P3(("# comparing short '%.*s' (%d)\n", (int)slen, sho, (int)slen)) unless (s = memchr(sho, '_', slen)) s = se; - P4(("# sho goes '%c' and lon goes '%c'\n", *sho, *lon)) + P4(("# sho goes '%c' and lon goes '%c'\n", *sho, (int)*lon)) while(*lon && lon < le) { - P3(("# against long '%*s' (%d)\n", llen, lon, llen)) + P3(("# against long '%.*s' (%d)\n", (int)llen, lon, (int)llen)) unless (l = memchr(lon, '_', llen)) l = le; - P3(("# %d == %d && !strncmp '%*s', '%*s'\n", s-sho, l-lon, s-sho, sho, s-sho, lon)) + P3(("# %ld == %ld && !strncmp '%.*s', '%.*s'\n", s-sho, l-lon, (int)(s-sho), sho, (int)(s-sho), lon)) if (l-lon == s-sho && !strncmp(sho, lon, s-sho)) goto foundone; P4(("# failed\n")) llen -= l-lon + 1; @@ -88,7 +88,7 @@ int psyc_matches(char* sho, size_t slen, } goto failed; foundone: - P3(("# found %d of short '%*s' and long '%*s'\n", s-sho, s-sho, sho, s-sho, lon)) + P3(("# found %ld of short '%.*s' and long '%.*s'\n", s-sho, (int)(s-sho), sho, (int)(s-sho), lon)) llen -= l-lon; slen -= s-sho; sho = ++s; From b4c6008ffd8339c0c0d0025034adb8f2529b439d Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sat, 30 Apr 2011 15:46:17 +0200 Subject: [PATCH 133/378] + --- src/parser.c | 3 +-- src/text.c | 7 +++++++ test/testServer.c | 3 ++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/parser.c b/src/parser.c index 501c300..7701644 100644 --- a/src/parser.c +++ b/src/parser.c @@ -222,7 +222,7 @@ inline psycParseRC psyc_parseModifier(psycParseState* state, char* oper, psycStr psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psycString* value) { psycParseRC ret; // a return value - size_t pos; // a cursor position + size_t pos = state->cursor; // a cursor position // Start position of the current line in the buffer // in case we return insufficent, we rewind to this position. @@ -245,7 +245,6 @@ psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psyc // fall thru case PSYC_PART_ROUTING: - pos = state->cursor; if (state->routingLength > 0) { if (state->buffer.ptr[state->cursor] != '\n') diff --git a/src/text.c b/src/text.c index 95dcc88..6bc8c1d 100644 --- a/src/text.c +++ b/src/text.c @@ -1,2 +1,9 @@ /* psyc_text() */ +int psyc_text(char *template, size_t tlen, + char **buffer, size_t *blen, + psyctextCB lookupValue, + char *braceOpen, char *braceClose) +{ + +} diff --git a/test/testServer.c b/test/testServer.c index 64a6f00..4cb9088 100644 --- a/test/testServer.c +++ b/test/testServer.c @@ -15,8 +15,9 @@ #include #include #include +#include -#include +#include #include #include #include From 293f9160ae4ee7a8434a2f355cf0e8a6daae4a35 Mon Sep 17 00:00:00 2001 From: Marenz Date: Sat, 30 Apr 2011 15:48:52 +0200 Subject: [PATCH 134/378] added check for invalid flags combination --- include/psyc/parser.h | 3 +++ src/parser.c | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index bff444d..984ae84 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -21,6 +21,7 @@ typedef enum { + /// Parse only the header PSYC_PARSE_HEADER_ONLY = 1, /// Expects only the content part of a packet. The length of the content must fit exactly in this case PSYC_PARSE_BEGIN_AT_CONTENT = 2, @@ -32,6 +33,8 @@ typedef enum */ typedef enum { + /// Invalid combination of flags + PSYC_PARSE_ERROR_INVALID_FLAGS = -10, PSYC_PARSE_ERROR_END = -9, PSYC_PARSE_ERROR_BODY = -8, PSYC_PARSE_ERROR_METHOD = -7, diff --git a/src/parser.c b/src/parser.c index 914e483..e24a351 100644 --- a/src/parser.c +++ b/src/parser.c @@ -136,6 +136,10 @@ inline psycParseRC psyc_parseName(psycParseState* state, psycString* name) */ inline psycParseRC psyc_parseBinaryValue(psycParseState* state, psycString* value, size_t* length, size_t* parsed) { + if (state->flags & PSYC_PARSE_HEADER_ONLY && + state->flags & PSYC_PARSE_BEGIN_AT_CONTENT) + return PSYC_PARSE_ERROR_INVALID_FLAGS; + size_t remaining = *length - *parsed; value->ptr = state->buffer.ptr + state->cursor; From 7bfd705b491b07f9ebe03054658d9ea1680ccd09 Mon Sep 17 00:00:00 2001 From: Marenz Date: Sat, 30 Apr 2011 15:59:11 +0200 Subject: [PATCH 135/378] added check to wrong function --- src/parser.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/parser.c b/src/parser.c index 6e84964..d08ea67 100644 --- a/src/parser.c +++ b/src/parser.c @@ -136,10 +136,6 @@ inline psycParseRC psyc_parseName(psycParseState* state, psycString* name) */ inline psycParseRC psyc_parseBinaryValue(psycParseState* state, psycString* value, size_t* length, size_t* parsed) { - if (state->flags & PSYC_PARSE_HEADER_ONLY && - state->flags & PSYC_PARSE_BEGIN_AT_CONTENT) - return PSYC_PARSE_ERROR_INVALID_FLAGS; - size_t remaining = *length - *parsed; value->ptr = state->buffer.ptr + state->cursor; @@ -234,6 +230,10 @@ inline psycParseRC psyc_parseModifier(psycParseState* state, char* oper, psycStr */ psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psycString* value) { + if (state->flags & PSYC_PARSE_HEADER_ONLY && + state->flags & PSYC_PARSE_BEGIN_AT_CONTENT) + return PSYC_PARSE_ERROR_INVALID_FLAGS; + psycParseRC ret; // a return value size_t pos = state->cursor; // a cursor position From 65f5906484f344bcaa4ac319aaa4ab2621519b27 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sat, 30 Apr 2011 16:05:48 +0200 Subject: [PATCH 136/378] Makefile fixes --- Makefile | 10 +++++----- src/Makefile | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index 86f7430..8e0a66f 100644 --- a/Makefile +++ b/Makefile @@ -2,11 +2,8 @@ .PHONY: test .PHONY: lib -default: - @/bin/echo -e "Usage:\n\tmake diet - compile with diet libc\n\tmake glibc - compile with normal gnu libc\n\tmake test\n\tmake doc" - -lib: - ${MAKE} -C src lib +all: + ${MAKE} -C src diet: ${MAKE} -C src diet @@ -21,3 +18,6 @@ clean: make -C src clean make -C test clean rm -rf doc/html doc/latex doc/man + +help: + @/bin/echo -e "Usage:\n\tmake - compile\n\tmake diet - compile with diet libc\n\tmake test\n\tmake doc" diff --git a/src/Makefile b/src/Makefile index c8a0f88..26c07fd 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,24 +2,21 @@ OPT = -O2 DEBUG = 2 CFLAGS = -I../include -Wall ${OPT} DIET = diet -WRAPPER = S = packet.c misc.c parser.c match.c render.c memmem.c itoa.c variable.c O = packet.o misc.o parser.o match.o render.o memmem.o itoa.o variable.o +all: CC := ${WRAPPER} ${CC} all: lib -help: - @/bin/echo -e "Usage:\n\tmake diet - compile with diet libc\n\tmake lib - compile with normal gnu libc" - debug: CFLAGS += -DDEBUG=${DEBUG} -g debug: CFLAGS := $(subst ${OPT},-O0,${CFLAGS}) debug: lib diet: WRAPPER = ${DIET} +diet: CC := ${WRAPPER} ${CC} diet: lib -lib: CC := ${WRAPPER} ${CC} lib: $O @mkdir -p ../lib ${WRAPPER} ar rcs ../lib/libpsyc.a $O @@ -34,3 +31,6 @@ it: match clean: rm -f $O ../lib/libpsyc.a + +help: + @/bin/echo -e "Usage:\n\tmake - compile\n\tmake diet - compile with diet libc" From 6107757c2ef9ab359fef327684d130df167b5d35 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sat, 30 Apr 2011 16:41:30 +0200 Subject: [PATCH 137/378] makefile --- Makefile | 5 ++++- test/Makefile | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 8e0a66f..a004220 100644 --- a/Makefile +++ b/Makefile @@ -5,11 +5,14 @@ all: ${MAKE} -C src +debug: + ${MAKE} -C src debug + diet: ${MAKE} -C src diet test: - ${MAKE} -C test + ${MAKE} -C test test doc: doxygen diff --git a/test/Makefile b/test/Makefile index d2f2796..482dd7e 100644 --- a/test/Makefile +++ b/test/Makefile @@ -8,7 +8,7 @@ WRAPPER = DIET = diet PORT = 4440 -all: test +all: ${TARGETS} diet: WRAPPER = ${DIET} diet: all From 357f0f6de4c50eedf559a1d443460a39fff38154 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sat, 30 Apr 2011 16:42:03 +0200 Subject: [PATCH 138/378] parser: fixes for header only parsing --- include/psyc/parser.h | 2 +- src/parser.c | 12 +++++++----- test/testParser.c | 13 +++++++++++-- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index 984ae84..ada7b91 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -24,7 +24,7 @@ typedef enum /// Parse only the header PSYC_PARSE_HEADER_ONLY = 1, /// Expects only the content part of a packet. The length of the content must fit exactly in this case - PSYC_PARSE_BEGIN_AT_CONTENT = 2, + PSYC_PARSE_BEGIN_AT_CONTENT = 2, } psycParseFlag; /** diff --git a/src/parser.c b/src/parser.c index 6e84964..bf75347 100644 --- a/src/parser.c +++ b/src/parser.c @@ -136,10 +136,6 @@ inline psycParseRC psyc_parseName(psycParseState* state, psycString* name) */ inline psycParseRC psyc_parseBinaryValue(psycParseState* state, psycString* value, size_t* length, size_t* parsed) { - if (state->flags & PSYC_PARSE_HEADER_ONLY && - state->flags & PSYC_PARSE_BEGIN_AT_CONTENT) - return PSYC_PARSE_ERROR_INVALID_FLAGS; - size_t remaining = *length - *parsed; value->ptr = state->buffer.ptr + state->cursor; @@ -300,8 +296,13 @@ psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psyc { // If we need to parse the header only and we know the content length, // then skip content parsing. - if (state->flags & PSYC_PARSE_HEADER_ONLY && state->contentLengthFound) + if (state->flags & PSYC_PARSE_HEADER_ONLY) + { state->part = PSYC_PART_DATA; + if (++(state->cursor) >= state->buffer.length) + return PSYC_PARSE_INSUFFICIENT; + goto PSYC_PART_DATA; + } else state->part = PSYC_PART_CONTENT; } @@ -397,6 +398,7 @@ psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psyc } case PSYC_PART_DATA: + PSYC_PART_DATA: value->ptr = state->buffer.ptr + state->cursor; value->length = 0; diff --git a/test/testParser.c b/test/testParser.c index fc30905..662ba77 100644 --- a/test/testParser.c +++ b/test/testParser.c @@ -7,7 +7,7 @@ int main(int argc, char **argv) { - int idx, ret, verbose = argc > 2; + int idx, ret, header_only = argc > 2, verbose = argc > 3; char buffer[2048], oper; psycString name, value, elem; psycParseState state; @@ -23,14 +23,23 @@ int main(int argc, char **argv) write(1, buffer, idx); write(1, ">> PARSE\n", 9); } - psyc_initParseState(&state); + if (header_only) + psyc_initParseState2(&state, PSYC_PARSE_HEADER_ONLY); + else + psyc_initParseState(&state); psyc_nextParseBuffer(&state, psyc_newString(buffer, idx)); // try parsing that now // while ((ret = psyc_parse(&state, &oper, &name, &value))) // { do { + oper = 0; + name.length = 0; + value.length = 0; + ret = psyc_parse(&state, &oper, &name, &value); + if (verbose) + printf(">> ret = %d\n", ret); switch (ret) { case PSYC_PARSE_ROUTING: From bd3b098423f7de8cb74e5ad1ae1e34bd20214256 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sat, 30 Apr 2011 16:45:17 +0200 Subject: [PATCH 139/378] parser: only check flags in debug mode --- src/parser.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/parser.c b/src/parser.c index c039869..9157f3b 100644 --- a/src/parser.c +++ b/src/parser.c @@ -230,10 +230,11 @@ inline psycParseRC psyc_parseModifier(psycParseState* state, char* oper, psycStr */ psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psycString* value) { - if (state->flags & PSYC_PARSE_HEADER_ONLY && - state->flags & PSYC_PARSE_BEGIN_AT_CONTENT) - return PSYC_PARSE_ERROR_INVALID_FLAGS; - +#ifdef DEBUG + if (state->flags & PSYC_PARSE_HEADER_ONLY && state->flags & PSYC_PARSE_BEGIN_AT_CONTENT) + PP(("Invalid flag combination")) +#endif + psycParseRC ret; // a return value size_t pos = state->cursor; // a cursor position From 8488c39ce1e05b4d39efaf246fea9f9ee37bd1d9 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sat, 30 Apr 2011 16:46:09 +0200 Subject: [PATCH 140/378] + --- include/psyc/parser.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index ada7b91..bcd4579 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -33,8 +33,6 @@ typedef enum */ typedef enum { - /// Invalid combination of flags - PSYC_PARSE_ERROR_INVALID_FLAGS = -10, PSYC_PARSE_ERROR_END = -9, PSYC_PARSE_ERROR_BODY = -8, PSYC_PARSE_ERROR_METHOD = -7, From 13153634106771e049c71730f07e6b6b79a9ee65 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sat, 30 Apr 2011 17:07:01 +0200 Subject: [PATCH 141/378] parser: renamed flags, testServer: added routing only option --- include/psyc/parser.h | 6 +++--- src/parser.c | 8 ++++---- test/Makefile | 6 ++++++ test/testParser.c | 6 +++--- test/testServer.c | 9 +++++++-- 5 files changed, 23 insertions(+), 12 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index bcd4579..bc17948 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -22,9 +22,9 @@ typedef enum { /// Parse only the header - PSYC_PARSE_HEADER_ONLY = 1, - /// Expects only the content part of a packet. The length of the content must fit exactly in this case - PSYC_PARSE_BEGIN_AT_CONTENT = 2, + PSYC_PARSE_ROUTING_ONLY = 1, + /// Expects only the content part of a packet. The buffer should contain the whole content in this case. + PSYC_PARSE_START_AT_CONTENT = 2, } psycParseFlag; /** diff --git a/src/parser.c b/src/parser.c index 9157f3b..ffebd44 100644 --- a/src/parser.c +++ b/src/parser.c @@ -25,7 +25,7 @@ inline void psyc_initParseState2 (psycParseState* state, uint8_t flags) memset(state, 0, sizeof(psycParseState)); state->flags = flags; - if (flags & PSYC_PARSE_BEGIN_AT_CONTENT) + if (flags & PSYC_PARSE_START_AT_CONTENT) state->part = PSYC_PART_CONTENT; } @@ -36,7 +36,7 @@ inline void psyc_initParseListState (psycParseListState* state) inline void psyc_nextParseBuffer (psycParseState* state, psycString newBuf) { - if (state->flags & PSYC_PARSE_BEGIN_AT_CONTENT) + if (state->flags & PSYC_PARSE_START_AT_CONTENT) { state->contentLength = newBuf.length; state->contentLengthFound = PSYC_TRUE; @@ -231,7 +231,7 @@ inline psycParseRC psyc_parseModifier(psycParseState* state, char* oper, psycStr psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psycString* value) { #ifdef DEBUG - if (state->flags & PSYC_PARSE_HEADER_ONLY && state->flags & PSYC_PARSE_BEGIN_AT_CONTENT) + if (state->flags & PSYC_PARSE_ROUTING_ONLY && state->flags & PSYC_PARSE_START_AT_CONTENT) PP(("Invalid flag combination")) #endif @@ -301,7 +301,7 @@ psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psyc { // If we need to parse the header only and we know the content length, // then skip content parsing. - if (state->flags & PSYC_PARSE_HEADER_ONLY) + if (state->flags & PSYC_PARSE_ROUTING_ONLY) { state->part = PSYC_PART_DATA; if (++(state->cursor) >= state->buffer.length) diff --git a/test/Makefile b/test/Makefile index 482dd7e..c7d8813 100644 --- a/test/Makefile +++ b/test/Makefile @@ -27,9 +27,15 @@ test: ${TARGETS} netstart: ./testServer ${PORT} +netstartr: + ./testServer ${PORT} -r + netstartv: ./testServer ${PORT} -v +netstartrv: + ./testServer ${PORT} -r -v + nettest: for f in packets/full-*; do echo ">> $$f"; cat $$f | nc localhost ${PORT} | diff -u $$f -; done diff --git a/test/testParser.c b/test/testParser.c index 662ba77..c589851 100644 --- a/test/testParser.c +++ b/test/testParser.c @@ -7,7 +7,7 @@ int main(int argc, char **argv) { - int idx, ret, header_only = argc > 2, verbose = argc > 3; + int idx, ret, routing_only = argc > 2, verbose = argc > 3; char buffer[2048], oper; psycString name, value, elem; psycParseState state; @@ -23,8 +23,8 @@ int main(int argc, char **argv) write(1, buffer, idx); write(1, ">> PARSE\n", 9); } - if (header_only) - psyc_initParseState2(&state, PSYC_PARSE_HEADER_ONLY); + if (routing_only) + psyc_initParseState2(&state, PSYC_PARSE_ROUTING_ONLY); else psyc_initParseState(&state); psyc_nextParseBuffer(&state, psyc_newString(buffer, idx)); diff --git a/test/testServer.c b/test/testServer.c index 4cb9088..7c5dd8d 100644 --- a/test/testServer.c +++ b/test/testServer.c @@ -43,7 +43,7 @@ void *get_in_addr(struct sockaddr *sa) int main(int argc, char **argv) { char *port = argc > 1 ? argv[1] : "4440"; - uint8_t verbose = argc > 2; + uint8_t routing_only = argc > 2, verbose = argc > 3; fd_set master; // master file descriptor list fd_set read_fds; // temp file descriptor list for select() @@ -157,7 +157,10 @@ int main(int argc, char **argv) } // reset parser state & packet - psyc_initParseState(&parsers[newfd]); + if (routing_only) + psyc_initParseState2(&parsers[newfd], PSYC_PARSE_ROUTING_ONLY); + else + psyc_initParseState(&parsers[newfd]); memset(&packets[newfd], 0, sizeof(psycPacket)); memset(&routing[newfd], 0, sizeof(psycModifier) * ROUTING_LINES); memset(&entity[newfd], 0, sizeof(psycModifier) * ENTITY_LINES); @@ -193,6 +196,8 @@ int main(int argc, char **argv) do { ret = psyc_parse(&parsers[i], &oper, &name, &value); + if (verbose) + printf("# ret = %d\n", ret); switch (ret) { case PSYC_PARSE_ROUTING: assert(packets[i].routing.lines < ROUTING_LINES); From 2b70735aea2bee140df2984feea0e43b8cfe5781 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sat, 30 Apr 2011 18:34:43 +0200 Subject: [PATCH 142/378] fixed content length issues in parser & renderer --- src/packet.c | 35 +++++++++++++++++++++-------------- src/parser.c | 3 +-- src/render.c | 5 +---- test/packets/full-1-length | 2 +- test/testRender.c | 2 +- 5 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/packet.c b/src/packet.c index 8455636..a29a21f 100644 --- a/src/packet.c +++ b/src/packet.c @@ -113,23 +113,30 @@ inline psycList psyc_newList(psycString *elems, size_t num_elems, psycListFlag f inline psycPacketFlag psyc_checkPacketLength(psycPacket *p) { - psycPacketFlag flag; - if (p->data.length == 1 && p->data.ptr[0] == C_GLYPH_PACKET_DELIMITER) - flag = PSYC_PACKET_NEED_LENGTH; - else if (p->data.length > PSYC_CONTENT_SIZE_THRESHOLD) - flag = PSYC_PACKET_NEED_LENGTH; - else if (memmem(p->data.ptr, p->data.length, PSYC_C2ARG(PSYC_PACKET_DELIMITER))) - flag = PSYC_PACKET_NEED_LENGTH; - else - flag = PSYC_PACKET_NO_LENGTH; + return PSYC_PACKET_NEED_LENGTH; - return flag; + if (p->data.length > PSYC_CONTENT_SIZE_THRESHOLD) + return PSYC_PACKET_NEED_LENGTH; + + int i; + // if any entity modifiers need length it is possible they contain + // a packet terminator, thus the content should have a length as well + for (i = 0; i < p->entity.lines; i++) + if (p->entity.modifiers[i].flag == PSYC_MODIFIER_NEED_LENGTH) + return PSYC_PACKET_NEED_LENGTH; + + if (memmem(p->data.ptr, p->data.length, PSYC_C2ARG(PSYC_PACKET_DELIMITER))) + return PSYC_PACKET_NEED_LENGTH; + + return PSYC_PACKET_NO_LENGTH; } inline size_t psyc_setPacketLength(psycPacket *p) { size_t i; + p->routingLength = 0; + p->contentLength = 0; // add routing header length for (i = 0; i < p->routing.lines; i++) @@ -145,14 +152,14 @@ inline size_t psyc_setPacketLength(psycPacket *p) if (p->data.length) p->contentLength += p->data.length + 1; // data\n - // set total length: routing-header \n content |\n - p->length = p->routingLength + p->contentLength + sizeof(PSYC_PACKET_DELIMITER) - 2; + // set total length: routing-header content |\n + p->length = p->routingLength + p->contentLength + 2; + if (p->contentLength > 0) { - p->contentLength--; // subtract the \n from the delimiter, as that doesn't belong to the content part p->length++; // add \n at the start of the content part if (p->flag == PSYC_PACKET_NEED_LENGTH) // add length of length if needed - p->length += log10((double)p->data.length) + 1; + p->length += log10((double)p->contentLength) + 1; } return p->length; diff --git a/src/parser.c b/src/parser.c index ffebd44..7db0b74 100644 --- a/src/parser.c +++ b/src/parser.c @@ -416,10 +416,9 @@ psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psyc if (state->cursor >= state->buffer.length) return PSYC_PARSE_BODY; - if (state->buffer.ptr[state->cursor] != '\n') + if (state->buffer.ptr[state->cursor] != '|') return PSYC_PARSE_ERROR_BODY; - state->cursor++; state->part = PSYC_PART_END; return PSYC_PARSE_BODY; } diff --git a/src/render.c b/src/render.c index e7b5793..b7a6773 100644 --- a/src/render.c +++ b/src/render.c @@ -47,7 +47,6 @@ inline size_t psyc_renderModifier(psycModifier *mod, char *buffer) if (mod->flag == PSYC_MODIFIER_NEED_LENGTH) { buffer[cur++] = ' '; - //cur += sprintf(buffer + cur, "%ld", mod->value.length); cur += itoa(mod->value.length, buffer + cur, 10); } @@ -71,10 +70,8 @@ psycRenderRC psyc_render(psycPacket *packet, char *buffer, size_t buflen) cur += psyc_renderModifier(&packet->routing.modifiers[i], buffer + cur); // add length if needed - if (packet->flag == PSYC_PACKET_NEED_LENGTH) { - //cur += sprintf(buffer + cur, "%ld", packet->contentLength); + if (packet->flag == PSYC_PACKET_NEED_LENGTH) cur += itoa(packet->contentLength, buffer + cur, 10); - } if (packet->entity.lines || packet->method.length || packet->data.length) buffer[cur++] = '\n'; // start of content part if there's content diff --git a/test/packets/full-1-length b/test/packets/full-1-length index d4334de..fddf47a 100644 --- a/test/packets/full-1-length +++ b/test/packets/full-1-length @@ -1,7 +1,7 @@ :_source psyc://foo/~bar :_target psyc://bar/~baz :_tag sch1828hu3r2cm -85 +86 :_foo bar baz :_abc_def 11 foo bar baz diff --git a/test/testRender.c b/test/testRender.c index 7d2ac5d..4a274f8 100644 --- a/test/testRender.c +++ b/test/testRender.c @@ -99,7 +99,7 @@ _notice_presence\n\ if (testList("\ :_source psyc://10.100.1000/~ludwig\n\ :_context psyc://10.100.1000/~ludwig\n\ -\n\ +85\n\ :_list_text |foo|bar|baz\n\ :_list_binary 21 3 foo|3 b|r|7 baz\n\ qux\n\ From d60d694d7ffba55a73d44bbc02a4982ca4fe3d44 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sun, 1 May 2011 00:30:25 +0200 Subject: [PATCH 143/378] render: removed old code --- include/psyc/render.h | 42 ------------------------ src/render.c | 74 ------------------------------------------- 2 files changed, 116 deletions(-) diff --git a/include/psyc/render.h b/include/psyc/render.h index c54a2b8..c880125 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -36,48 +36,6 @@ psycRenderRC psyc_render(psycPacket *packet, char *buffer, size_t buflen); */ inline psycRenderRC psyc_renderList(psycList *list, char *buffer, size_t buflen); -/* -typedef enum -{ - PSYC_RENDER_CHECK_LENGTH = 0, - PSYC_RENDER_NEED_LENGTH = 1, - PSYC_RENDER_NO_LENGTH = 2, - PSYC_RENDER_ROUTING = 3, -} psycRenderFlag; -*/ - -/** - * Struct for keeping render state. - */ -/* -typedef struct -{ - psycRenderFlag flag; ///< flags for the renderer - psycPart part; ///< part of the packet being rendered - size_t cursor; ///< current position in buffer - size_t spot; ///< space for rendered length between the headers - size_t contentLength; ///< length of the content part - size_t length; ///< how big is the buffer we allocated - char buffer[]; ///< OMG a C99 feature! variable size buffer! -} psycRenderState; -*/ -/** - * Initiates the state struct. - * - * @param state Pointer to the state struct that should be initiated. - */ -/* -inline void psyc_initRenderState (psycRenderState* state); - -int psyc_renderModifier(psycRenderState* render, - const char* name, size_t nlength, - const char* value, size_t vlength, - psycRenderFlag flags, char oper); - -int psyc_renderBody(psycRenderState* render, - const char* method, size_t mlength, - const char* data, size_t dlength); -*/ #endif // PSYC_RENDER_H /** @} */ // end of rendering group diff --git a/src/render.c b/src/render.c index b7a6773..c12c06b 100644 --- a/src/render.c +++ b/src/render.c @@ -102,77 +102,3 @@ psycRenderRC psyc_render(psycPacket *packet, char *buffer, size_t buflen) assert(cur == packet->length); return PSYC_RENDER_SUCCESS; } - -/* -inline void psyc_initRenderState (psycRenderState *state) -{ - memset(state, 0, sizeof(psycRenderState)); -} - -psycRenderRC psyc_renderModifier(psycRenderState *state, - const char *name, size_t nlength, - const char *value, size_t vlength, - const psycRenderFlag flags, char oper) -{ - size_t startc = state->cursor; - - unless (nlength) nlength = strlen(name); - // vlength 0 means an empty variable.. no cheating there - unless (oper) oper = C_GLYPH_OPERATOR_SET; - - state->buffer[state->cursor++] = oper; - strncpy(&state->buffer[state->cursor], name, nlength); - state->cursor += nlength; - - if (vlength) - { - state->buffer[state->cursor++] = '\t'; - strncpy(&state->buffer[state->cursor], value, vlength); - state->cursor += vlength; - } - - //if (flags == PSYC_RENDER_ROUTING) - if (psyc_isRoutingVar(name, nlength)) - { // no more routing headers allowed after content started - if (state->part != PSYC_PART_ROUTING) - { - P1(("Too late to add a routing variable!\n")); - return PSYC_RENDER_ERROR_ROUTING; - } - } - else if (state->part == PSYC_PART_ROUTING) - { // first entity header, set part to content - state->part = PSYC_PART_CONTENT; - // add "\n000000000" to buffer - // and make spot point to the first 0 - } - - // update content length if we're in the content part - if (state->part == PSYC_PART_CONTENT) - state->contentLength += state->cursor - startc; - - return PSYC_RENDER_SUCCESS; -} - -psycRenderRC psyc_renderBody(psycRenderState *state, - const char *method, size_t mlength, - const char *data, size_t dlength) -{ - if (state->flag == PSYC_RENDER_CHECK_LENGTH) - { - // find out if this packet needs a prepended length - if (dlength == 1 && data[0] == C_GLYPH_PACKET_DELIMITER) - state->flag = PSYC_RENDER_NEED_LENGTH; - else if (dlength > 404) - state->flag = PSYC_RENDER_NEED_LENGTH; - else if (memmem(data, dlength, PSYC_C2ARG(PSYC_PACKET_DELIMITER))) - state->flag = PSYC_RENDER_NEED_LENGTH; - else - state->flag = PSYC_RENDER_NO_LENGTH; - } - - // TBD - - return PSYC_RENDER_SUCCESS; -} -*/ From 5a75ec3a6e236874a66c6bb92c72f4621a62ae7f Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sun, 1 May 2011 11:59:15 +0200 Subject: [PATCH 144/378] parser: added return code aliases for routing-only mode --- include/psyc/parser.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index bc17948..3fdfbd3 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -60,6 +60,10 @@ typedef enum PSYC_PARSE_BODY = 5, /// Body parsing is incomplete, name contains method, value contains part of the body. PSYC_PARSE_BODY_INCOMPLETE = 6, +/// Content parsing done, value contains the whole content. Used when PSYC_PARSE_ROUTING_ONLY is set. + PSYC_PARSE_CONTENT = 5, +/// Content parsing is incomplete, value contains part of content. Used when PSYC_PARSE_ROUTING_ONLY is set. + PSYC_PARSE_CONTENT_INCOMPLETE = 6, /// Reached end of packet, parsing done. PSYC_PARSE_COMPLETE = 7, /// Binary value parsing incomplete, used internally. From aa98e00fbac9462421a1ec733eadf13950eb46fc Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sun, 1 May 2011 12:08:09 +0200 Subject: [PATCH 145/378] parser: added return code aliases for routing-only mode --- include/d/psyc/parser.d | 6 ++++++ include/psyc/parser.h | 6 ++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/include/d/psyc/parser.d b/include/d/psyc/parser.d index 1d03adc..465a641 100644 --- a/include/d/psyc/parser.d +++ b/include/d/psyc/parser.d @@ -58,6 +58,12 @@ enum ParseRC PARSE_BODY = 5, /// Body parsing is incomplete, name contains method, value contains part of the body. PARSE_BODY_INCOMPLETE = 6, +/// Content parsing done, value contains the whole content. +/// Used when PSYC_PARSE_ROUTING_ONLY is set. + PARSE_CONTENT = 5, +/// Content parsing is incomplete, value contains part of content. +/// Used when PSYC_PARSE_ROUTING_ONLY is set. + PARSE_CONTENT_INCOMPLETE = 6, /// Reached end of packet, parsing done. PARSE_COMPLETE = 7, /// Binary value parsing incomplete, used internally. diff --git a/include/psyc/parser.h b/include/psyc/parser.h index 3fdfbd3..f683459 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -60,9 +60,11 @@ typedef enum PSYC_PARSE_BODY = 5, /// Body parsing is incomplete, name contains method, value contains part of the body. PSYC_PARSE_BODY_INCOMPLETE = 6, -/// Content parsing done, value contains the whole content. Used when PSYC_PARSE_ROUTING_ONLY is set. +/// Content parsing done, value contains the whole content. +/// Used when PSYC_PARSE_ROUTING_ONLY is set. PSYC_PARSE_CONTENT = 5, -/// Content parsing is incomplete, value contains part of content. Used when PSYC_PARSE_ROUTING_ONLY is set. +/// Content parsing is incomplete, value contains part of content. +/// Used when PSYC_PARSE_ROUTING_ONLY is set. PSYC_PARSE_CONTENT_INCOMPLETE = 6, /// Reached end of packet, parsing done. PSYC_PARSE_COMPLETE = 7, From 804a2ab394d3c64988914d834b485ff31a00d0ba Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 3 May 2011 22:18:35 +0200 Subject: [PATCH 146/378] psyc_text + tests --- .gitignore | 1 + include/psyc.h | 32 +----------- include/psyc/text.h | 71 ++++++++++++++++++++++++++ src/Makefile | 4 +- src/text.c | 119 +++++++++++++++++++++++++++++++++++++++++--- test/Makefile | 2 +- test/testText.c | 90 +++++++++++++++++++++++++++++++++ 7 files changed, 279 insertions(+), 40 deletions(-) create mode 100644 include/psyc/text.h create mode 100644 test/testText.c diff --git a/.gitignore b/.gitignore index 8616e19..b585751 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ test/testMatch test/testParser test/testRender test/testServer +test/testText test/isRoutingVar test/getVarType diff --git a/include/psyc.h b/include/psyc.h index 93358f1..8ca562b 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -149,7 +149,7 @@ typedef struct psycListFlag flag; } psycList; -/* intermediate struct for a PSYC packet */ +/** intermediate struct for a PSYC packet */ typedef struct { psycHeader routing; ///< Routing header. @@ -234,34 +234,4 @@ int psyc_inherits(char *sho, size_t slen, int psyc_matches(char *sho, size_t slen, char *lon, size_t llen); -/** - * Callback for psyc_text() that produces a value for a match. - * - * The application looks up a match such as _fruit from [_fruit] and - * if found writes its current value from its variable store into the - * outgoing buffer.. "Apple" for example. The template returns the - * number of bytes written. 0 is a legal return value. Should the - * callback return -1, psyc_text leaves the original template text as is. - */ -typedef int (*psyctextCB)(char *match, size_t mlen, - char **buffer, size_t *blen); - -/** - * Fills out text templates by asking a callback for content. - * - * Copies the contents of the template into the buffer while looking - * for braceOpen and braceClose strings and calling the callback for - * each enclosed string between these braces. Should the callback - * return -1, the original template text is copied as is. - * - * By default PSYC's "[" and "]" are used but you can provide any other - * brace strings such as "${" and "}" or "". - * - * See also http://about.psyc.eu/psyctext - */ -int psyc_text(char *template, size_t tlen, - char **buffer, size_t *blen, - psyctextCB lookupValue, - char *braceOpen, char *braceClose); - #endif // PSYC_H diff --git a/include/psyc/text.h b/include/psyc/text.h new file mode 100644 index 0000000..7774684 --- /dev/null +++ b/include/psyc/text.h @@ -0,0 +1,71 @@ +/** + * The return value definitions for the PSYC text parsing function. + * @see psyc_text() + */ + +typedef enum +{ + PSYC_TEXT_NO_SUBST = -1, + PSYC_TEXT_COMPLETE = 0, + PSYC_TEXT_INCOMPLETE = 1, +} psycTextRC; + +typedef enum +{ + PSYC_TEXT_VALUE_NOT_FOUND = -1, + PSYC_TEXT_VALUE_FOUND = 0, +} psycTextValueRC; + +/** + * Struct for keeping PSYC text parser state. + */ +typedef struct +{ + size_t cursor; ///< current position in the template + size_t written; ///< number of bytes written to buffer + psycString template; ///< template to parse + psycString buffer; ///< buffer for writing to + psycString open; + psycString close; +} psycTextState; + +/** + * Callback for psyc_text() that produces a value for a match. + * + * The application looks up a match such as _fruit from [_fruit] and + * if found writes its current value from its variable store into the + * outgoing buffer.. "Apple" for example. The template returns the + * number of bytes written. 0 is a legal return value. Should the + * callback return -1, psyc_text leaves the original template text as is. + */ +typedef psycTextValueRC (*psycTextCB)(char *name, size_t len, psycString *value); + +inline void psyc_initTextState (psycTextState *state, + char *template, size_t tlen, + char *buffer, size_t blen); + +inline void psyc_initTextState2 (psycTextState* state, + char *template, size_t tlen, + char *buffer, size_t blen, + char *open, size_t openlen, + char *close, size_t closelen); + +inline void psyc_setTextBuffer (psycTextState *state, psycString buffer); + +inline void psyc_setTextBuffer2 (psycTextState *state, char *buffer, size_t length); + +/** + * Fills out text templates by asking a callback for content. + * + * Copies the contents of the template into the buffer while looking + * for braceOpen and braceClose strings and calling the callback for + * each enclosed string between these braces. Should the callback + * return -1, the original template text is copied as is. + * + * By default PSYC's "[" and "]" are used but you can provide any other + * brace strings such as "${" and "}" or "". + * + * See also http://about.psyc.eu/psyctext + */ + +psycTextRC psyc_text(psycTextState *state, psycTextCB getValue); diff --git a/src/Makefile b/src/Makefile index 26c07fd..4ffaed1 100644 --- a/src/Makefile +++ b/src/Makefile @@ -3,8 +3,8 @@ DEBUG = 2 CFLAGS = -I../include -Wall ${OPT} DIET = diet -S = packet.c misc.c parser.c match.c render.c memmem.c itoa.c variable.c -O = packet.o misc.o parser.o match.o render.o memmem.o itoa.o variable.o +S = packet.c misc.c parser.c match.c render.c memmem.c itoa.c variable.c text.c +O = packet.o misc.o parser.o match.o render.o memmem.o itoa.o variable.o text.o all: CC := ${WRAPPER} ${CC} all: lib diff --git a/src/text.c b/src/text.c index 6bc8c1d..2d00058 100644 --- a/src/text.c +++ b/src/text.c @@ -1,9 +1,116 @@ -/* psyc_text() */ +#include +#include -int psyc_text(char *template, size_t tlen, - char **buffer, size_t *blen, - psyctextCB lookupValue, - char *braceOpen, char *braceClose) +inline void psyc_initTextState (psycTextState *state, + char *template, size_t tlen, + char *buffer, size_t blen) { - + state->cursor = state->written = 0; + state->template = psyc_newString(template, tlen); + state->buffer = psyc_newString(buffer, blen); + state->open = psyc_newString("[", 1); + state->close = psyc_newString("]", 1); +} + +inline void psyc_initTextState2 (psycTextState* state, + char *template, size_t tlen, + char *buffer, size_t blen, + char *open, size_t openlen, + char *close, size_t closelen) +{ + state->template = psyc_newString(template, tlen); + state->buffer = psyc_newString(buffer, blen); + state->open = psyc_newString(open, openlen); + state->close = psyc_newString(close, closelen); +} + +inline void psyc_setTextBuffer (psycTextState* state, psycString buffer) +{ + state->buffer = buffer; + state->written = 0; +} + +inline void psyc_setTextBuffer2 (psycTextState* state, char *buffer, size_t length) +{ + psyc_setTextBuffer(state, psyc_newString(buffer, length)); +} + +psycTextRC psyc_text (psycTextState *state, psycTextCB getValue) +{ + char *start = state->template.ptr, *end; // start & end of variable name + char *prev = state->template.ptr + state->cursor; + psycString value; + int ret; + size_t len; + uint8_t no_subst = (state->cursor == 0); // whether we can return NO_SUBST + + while (state->cursor < state->template.length) + { + start = memmem(state->template.ptr + state->cursor, + state->template.length - state->cursor, + state->open.ptr, state->open.length); + if (!start) + break; + + state->cursor = (start - state->template.ptr) + state->open.length; + if (state->cursor >= state->template.length) + break; // [ at the end + + end = memmem(state->template.ptr + state->cursor, + state->template.length - state->cursor, + state->close.ptr, state->close.length); + state->cursor = (end - state->template.ptr) + state->close.length; + + if (!end) + break; // ] not found + if (start + state->open.length == end) + { + state->cursor += state->close.length; + continue; // [] is invalid, name can't be empty + } + + ret = getValue(start + state->open.length, end - start - state->open.length, &value); + + if (ret < 0) + continue; // value not found, no substitution + + // first copy the part in the template from the previous subst. to the current one + // if there's enough buffer space for that + len = start - prev; + if (state->written + len > state->buffer.length) + { + state->cursor = prev - state->template.ptr; + return PSYC_TEXT_INCOMPLETE; + } + + memcpy((void *)(state->buffer.ptr + state->written), prev, len); + state->written += len; + + // now substitute the value if there's enough buffer space + if (state->written + value.length > state->buffer.length) + { + state->cursor = start - state->template.ptr; + return PSYC_TEXT_INCOMPLETE; + } + + memcpy((void *)(state->buffer.ptr + state->written), value.ptr, value.length); + state->written += value.length; + + // mark the start of the next chunk of text in the template + prev = state->template.ptr + state->cursor; + no_subst = 0; + } + + if (no_subst) + return PSYC_TEXT_NO_SUBST; + + // copy the rest of the template after the last var + len = state->template.length - (prev - state->template.ptr); + if (state->written + len > state->buffer.length) + return PSYC_TEXT_INCOMPLETE; + + memcpy((void *)(state->buffer.ptr + state->written), prev, len); + state->written += len; + + return PSYC_TEXT_COMPLETE; } diff --git a/test/Makefile b/test/Makefile index c7d8813..7b7dbb5 100644 --- a/test/Makefile +++ b/test/Makefile @@ -3,7 +3,7 @@ DEBUG = 2 CFLAGS = -I../include -Wall ${OPT} LDFLAGS = -L../lib LOADLIBES = -lpsyc -lm -TARGETS = testServer testParser testMatch testRender isRoutingVar getVarType +TARGETS = testServer testParser testMatch testRender testText isRoutingVar getVarType WRAPPER = DIET = diet PORT = 4440 diff --git a/test/testText.c b/test/testText.c new file mode 100644 index 0000000..26ffcd6 --- /dev/null +++ b/test/testText.c @@ -0,0 +1,90 @@ +#include +#include + +#define BUFSIZE 512 + +uint8_t verbose; + +psycTextValueRC getValueFooBar (char *name, size_t len, psycString *value) +{ + value->ptr = "Foo Bar"; + value->length = 7; + return PSYC_TEXT_VALUE_FOUND; +} + +psycTextValueRC getValueEmpty (char *name, size_t len, psycString *value) +{ + value->ptr = ""; + value->length = 0; + return PSYC_TEXT_VALUE_FOUND; +} + +psycTextValueRC getValueNotFound (char *name, size_t len, psycString *value) +{ + return PSYC_TEXT_VALUE_NOT_FOUND; +} + +int testText (char *template, size_t tmplen, char *buffer, size_t buflen, psycString *result, psycTextCB getValue) +{ + psycTextState state; + size_t length = 0; + psycTextRC ret; + + psyc_initTextState(&state, template, tmplen, buffer, buflen); + do + { + ret = psyc_text(&state, getValue); + length += state.written; + switch (ret) + { + case PSYC_TEXT_INCOMPLETE: + if (verbose) + printf("# %.*s...\n", (int)length, buffer); + psyc_setTextBuffer2(&state, buffer + length, BUFSIZE - length); + break; + case PSYC_TEXT_COMPLETE: + if (verbose) + printf("%.*s\n", (int)length, buffer); + result->length = length; + result->ptr = buffer; + return ret; + case PSYC_TEXT_NO_SUBST: + if (verbose) + printf("%.*s\n", (int)tmplen, template); + return ret; + } + } + while (ret == PSYC_TEXT_INCOMPLETE); + + return -2; // shouldn't be reached +} + +int main(int argc, char **argv) +{ + verbose = argc > 1; + char buffer[BUFSIZE]; + psycString result; + + char *str = "Hello [_foo] & [_bar]!"; + size_t len = strlen(str); + int i; + + testText(str, len, buffer, BUFSIZE, &result, &getValueFooBar); + if (memcmp(result.ptr, PSYC_C2ARG("Hello Foo Bar & Foo Bar!"))) + return 1; + + testText(str, len, buffer, BUFSIZE, &result, &getValueEmpty); + if (memcmp(result.ptr, PSYC_C2ARG("Hello & !"))) + return 2; + + if (testText(str, len, buffer, BUFSIZE, &result, &getValueNotFound) != PSYC_TEXT_NO_SUBST) + return 3; + + for (i = 1; i < 22; i++) + { + testText(str, len, buffer, i, &result, &getValueFooBar); + if (memcmp(result.ptr, PSYC_C2ARG("Hello Foo Bar & Foo Bar!"))) + return 10 + i; + } + return 0; +} From ad6971e93ee4fc073c1167a4d62a6aae21cf5bb6 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 3 May 2011 22:21:26 +0200 Subject: [PATCH 147/378] + --- test/testText.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/testText.c b/test/testText.c index 26ffcd6..e67b37e 100644 --- a/test/testText.c +++ b/test/testText.c @@ -1,3 +1,5 @@ +#include + #include #include From 86f997eddd7f7e8ad27c203be087cf032fd7b61a Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 3 May 2011 22:24:50 +0200 Subject: [PATCH 148/378] parser: next*Buffer -> set*Buffer, added setParse*Buffer2, added PSYC_ prefix to macro --- include/psyc/parser.h | 18 +++++++--- src/parser.c | 78 ++++++++++++++++++++++++------------------- test/testParser.c | 8 +++-- test/testServer.c | 8 +++-- 4 files changed, 70 insertions(+), 42 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index f683459..b3c26af 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -139,6 +139,13 @@ inline void psyc_initParseState (psycParseState* state); */ inline void psyc_initParseState2 (psycParseState* state, uint8_t flags); +/** + * Sets a new buffer in the parser state struct with data to be parsed. + */ +inline void psyc_setParseBuffer (psycParseState* state, psycString buffer); + +inline void psyc_setParseBuffer2 (psycParseState* state, char *buffer, size_t length); + /** * Initiates the list state struct. * @@ -146,9 +153,12 @@ inline void psyc_initParseState2 (psycParseState* state, uint8_t flags); */ inline void psyc_initParseListState (psycParseListState* state); -inline void psyc_nextParseBuffer (psycParseState* state, psycString newBuf); +/** + * Sets a new buffer in the list parser state struct with data to be parsed. + */ +inline void psyc_setParseListBuffer (psycParseListState* state, psycString buffer); -inline void psyc_nextParseListBuffer (psycParseListState* state, psycString newBuf); +inline void psyc_setParseListBuffer2 (psycParseListState* state, char *buffer, size_t length); inline size_t psyc_getContentLength (psycParseState* s); @@ -165,12 +175,12 @@ inline size_t psyc_getContentLength (psycParseState* s); * @param value A pointer to a psycString. It will point to the * value/body the variable/method and its length will be set accordingly */ -psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psycString* value); +psycParseRC psyc_parse (psycParseState* state, char* oper, psycString* name, psycString* value); /** * List value parser. */ -psycParseListRC psyc_parseList(psycParseListState* state, psycString *name, psycString* value, psycString* elem); +psycParseListRC psyc_parseList (psycParseListState* state, psycString *name, psycString* value, psycString* elem); #endif // PSYC_PARSER_H diff --git a/src/parser.c b/src/parser.c index 7db0b74..5a19146 100644 --- a/src/parser.c +++ b/src/parser.c @@ -8,11 +8,11 @@ #include #include -#define ADVANCE_CURSOR_OR_RETURN(ret) \ +#define PSYC_ADVANCE_CURSOR_OR_RETURN(ret) \ if (++(state->cursor) >= state->buffer.length) \ - { \ - state->cursor = state->startc; \ - return ret; \ + { \ + state->cursor = state->startc; \ + return ret; \ } inline void psyc_initParseState (psycParseState* state) @@ -29,27 +29,37 @@ inline void psyc_initParseState2 (psycParseState* state, uint8_t flags) state->part = PSYC_PART_CONTENT; } +inline void psyc_setParseBuffer (psycParseState* state, psycString buffer) +{ + state->buffer = buffer; + state->cursor = 0; + + if (state->flags & PSYC_PARSE_START_AT_CONTENT) + { + state->contentLength = buffer.length; + state->contentLengthFound = PSYC_TRUE; + } +} + +inline void psyc_setParseBuffer2 (psycParseState* state, char *buffer, size_t length) +{ + psyc_setParseBuffer(state, psyc_newString(buffer, length)); +} + inline void psyc_initParseListState (psycParseListState* state) { memset(state, 0, sizeof(psycParseListState)); } -inline void psyc_nextParseBuffer (psycParseState* state, psycString newBuf) +inline void psyc_setParseListBuffer (psycParseListState* state, psycString buffer) { - if (state->flags & PSYC_PARSE_START_AT_CONTENT) - { - state->contentLength = newBuf.length; - state->contentLengthFound = PSYC_TRUE; - } - - state->buffer = newBuf; + state->buffer = buffer; state->cursor = 0; } -inline void psyc_nextParseListBuffer (psycParseListState* state, psycString newBuf) +inline void psyc_setParseListBuffer2 (psycParseListState* state, char *buffer, size_t length) { - state->buffer = newBuf; - state->cursor = 0; + psyc_setParseListBuffer(state, psyc_newString(buffer, length)); } inline size_t psyc_getContentLength (psycParseState* s) @@ -80,7 +90,7 @@ inline char isGlyph(uint8_t g) /** * Determines if the argument is numeric. */ -inline char isNumeric(uint8_t c) +inline char isNumeric (uint8_t c) { return c >= '0' && c <= '9'; } @@ -88,7 +98,7 @@ inline char isNumeric(uint8_t c) /** * Determines if the argument is alphanumeric. */ -inline char isAlphaNumeric(uint8_t c) +inline char isAlphaNumeric (uint8_t c) { return (c >= 'a' && c <= 'z') || @@ -100,7 +110,7 @@ inline char isAlphaNumeric(uint8_t c) * Determines if the argument is a keyword character. * Keyword characters are: alphanumeric and _ */ -inline char isKwChar(uint8_t c) +inline char isKwChar (uint8_t c) { return isAlphaNumeric(c) || c == '_'; } @@ -110,7 +120,7 @@ inline char isKwChar(uint8_t c) * It should contain one or more keyword characters. * @return PSYC_PARSE_ERROR or PSYC_PARSE_SUCCESS */ -inline psycParseRC psyc_parseName(psycParseState* state, psycString* name) +inline psycParseRC psyc_parseName (psycParseState* state, psycString* name) { name->ptr = state->buffer.ptr + state->cursor; name->length = 0; @@ -118,7 +128,7 @@ inline psycParseRC psyc_parseName(psycParseState* state, psycString* name) while (isKwChar(state->buffer.ptr[state->cursor])) { name->length++; // was a valid char, increase length - ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } return name->length > 0 ? PSYC_PARSE_SUCCESS : PSYC_PARSE_ERROR; @@ -134,7 +144,7 @@ inline psycParseRC psyc_parseName(psycParseState* state, psycString* name) * * @return PSYC_PARSE_COMPLETE or PSYC_PARSE_INCOMPLETE */ -inline psycParseRC psyc_parseBinaryValue(psycParseState* state, psycString* value, size_t* length, size_t* parsed) +inline psycParseRC psyc_parseBinaryValue (psycParseState* state, psycString* value, size_t* length, size_t* parsed) { size_t remaining = *length - *parsed; value->ptr = state->buffer.ptr + state->cursor; @@ -159,10 +169,10 @@ inline psycParseRC psyc_parseBinaryValue(psycParseState* state, psycString* valu * Parse simple or binary variable. * @return PSYC_PARSE_ERROR or PSYC_PARSE_SUCCESS */ -inline psycParseRC psyc_parseModifier(psycParseState* state, char* oper, psycString* name, psycString* value) +inline psycParseRC psyc_parseModifier (psycParseState* state, char* oper, psycString* name, psycString* value) { *oper = *(state->buffer.ptr + state->cursor); - ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); psycParseRC ret = psyc_parseName(state, name); if (ret == PSYC_PARSE_ERROR) @@ -179,14 +189,14 @@ inline psycParseRC psyc_parseModifier(psycParseState* state, char* oper, psycStr // 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_PARSE_INSUFFICIENT); + PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); if (isNumeric(state->buffer.ptr[state->cursor])) { do { length = 10 * length + state->buffer.ptr[state->cursor] - '0'; - ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } while (isNumeric(state->buffer.ptr[state->cursor])); state->valueLength = length; @@ -209,13 +219,13 @@ inline psycParseRC psyc_parseModifier(psycParseState* state, char* oper, psycStr } else if (state->buffer.ptr[state->cursor] == '\t') // simple arg { - ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); value->ptr = state->buffer.ptr + state->cursor; while (state->buffer.ptr[state->cursor] != '\n') { value->length++; - ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } return PSYC_PARSE_SUCCESS; @@ -263,7 +273,7 @@ psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psyc { if (state->buffer.ptr[state->cursor] != '\n') return PSYC_PARSE_ERROR_MOD_NL; - ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } // Each line of the header starts with a glyph, @@ -292,7 +302,7 @@ psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psyc do { state->contentLength = 10 * state->contentLength + state->buffer.ptr[state->cursor] - '0'; - ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } while (isNumeric(state->buffer.ptr[state->cursor])); } @@ -322,7 +332,7 @@ psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psyc } state->startc = state->cursor + 1; - ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); // fall thru case PSYC_PART_CONTENT: @@ -344,7 +354,7 @@ psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psyc { if (state->buffer.ptr[state->cursor] != '\n') return PSYC_PARSE_ERROR_MOD_NL; - ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } // Each line of the header starts with a glyph, @@ -391,7 +401,7 @@ psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psyc state->part = PSYC_PART_DATA; } else // otherwise keep it at the beginning of method - ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); // fall thru } @@ -447,7 +457,7 @@ psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psyc } } value->length++; - ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } } @@ -530,7 +540,7 @@ psycParseListRC psyc_parseList(psycParseListState* state, psycString *name, psyc do { state->elemLength = 10 * state->elemLength + state->buffer.ptr[state->cursor] - '0'; - ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_LIST_INCOMPLETE); + PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_LIST_INCOMPLETE); } while (isNumeric(state->buffer.ptr[state->cursor])); } diff --git a/test/testParser.c b/test/testParser.c index c589851..deb470e 100644 --- a/test/testParser.c +++ b/test/testParser.c @@ -23,11 +23,13 @@ int main(int argc, char **argv) write(1, buffer, idx); write(1, ">> PARSE\n", 9); } + if (routing_only) psyc_initParseState2(&state, PSYC_PARSE_ROUTING_ONLY); else psyc_initParseState(&state); - psyc_nextParseBuffer(&state, psyc_newString(buffer, idx)); + + psyc_setParseBuffer(&state, psyc_newString(buffer, idx)); // try parsing that now // while ((ret = psyc_parse(&state, &oper, &name, &value))) @@ -58,8 +60,10 @@ int main(int argc, char **argv) { if (verbose) write(1, ">>> LIST START\n", 15); + psyc_initParseListState(&listState); - psyc_nextParseListBuffer(&listState, value); + psyc_setParseListBuffer(&listState, value); + while ((ret = psyc_parseList(&listState, &name, &value, &elem))) { switch (ret) diff --git a/test/testServer.c b/test/testServer.c index 7c5dd8d..b2256da 100644 --- a/test/testServer.c +++ b/test/testServer.c @@ -161,6 +161,7 @@ int main(int argc, char **argv) psyc_initParseState2(&parsers[newfd], PSYC_PARSE_ROUTING_ONLY); else psyc_initParseState(&parsers[newfd]); + memset(&packets[newfd], 0, sizeof(psycPacket)); memset(&routing[newfd], 0, sizeof(psycModifier) * ROUTING_LINES); memset(&entity[newfd], 0, sizeof(psycModifier) * ENTITY_LINES); @@ -188,7 +189,7 @@ int main(int argc, char **argv) } else { // we got some data from a client parsebuf = recvbuf - contbytes; - psyc_nextParseBuffer(&parsers[i], psyc_newString(parsebuf, contbytes + nbytes)); + psyc_setParseBuffer(&parsers[i], psyc_newString(parsebuf, contbytes + nbytes)); contbytes = 0; oper = 0; name.length = 0; @@ -198,6 +199,7 @@ int main(int argc, char **argv) ret = psyc_parse(&parsers[i], &oper, &name, &value); if (verbose) printf("# ret = %d\n", ret); + switch (ret) { case PSYC_PARSE_ROUTING: assert(packets[i].routing.lines < ROUTING_LINES); @@ -299,8 +301,10 @@ int main(int argc, char **argv) if (pname->length >= 5 && memcmp(pname->ptr, "_list", 5) == 0) { if (verbose) printf("## LIST START\n"); + psyc_initParseListState(&listState); - psyc_nextParseListBuffer(&listState, *pvalue); + psyc_setParseListBuffer(&listState, *pvalue); + do { retl = psyc_parseList(&listState, pname, pvalue, &elem); switch (retl) { From e05081b074c014ac53d13b501f9f7fbd69a2e189 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 3 May 2011 22:54:34 +0200 Subject: [PATCH 149/378] render: -inline --- include/psyc/render.h | 2 +- src/render.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/psyc/render.h b/include/psyc/render.h index c880125..86eb037 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -34,7 +34,7 @@ psycRenderRC psyc_render(psycPacket *packet, char *buffer, size_t buflen); /** * Render a PSYC list into a buffer. */ -inline psycRenderRC psyc_renderList(psycList *list, char *buffer, size_t buflen); +psycRenderRC psyc_renderList(psycList *list, char *buffer, size_t buflen); #endif // PSYC_RENDER_H diff --git a/src/render.c b/src/render.c index c12c06b..b6a9569 100644 --- a/src/render.c +++ b/src/render.c @@ -2,7 +2,7 @@ #include "psyc/render.h" #include "psyc/syntax.h" -inline psycRenderRC psyc_renderList(psycList *list, char *buffer, size_t buflen) +psycRenderRC psyc_renderList(psycList *list, char *buffer, size_t buflen) { size_t i, cur = 0; psycString *elem; From d139e1a191f81081daf51b08bf41571d2b9f7749 Mon Sep 17 00:00:00 2001 From: Mathias Laurenz Baumann Date: Tue, 3 May 2011 22:56:54 +0200 Subject: [PATCH 150/378] moved inline functions back to the header shouldn't result in any problems when used with static inline --- include/psyc/parser.h | 65 +++++++++++++++++++++++++++++++++++++------ src/parser.c | 51 --------------------------------- 2 files changed, 57 insertions(+), 59 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index b3c26af..369b87c 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -18,6 +18,7 @@ #include #include +#include typedef enum { @@ -129,7 +130,10 @@ typedef struct * * @param state Pointer to the state struct that should be initiated. */ -inline void psyc_initParseState (psycParseState* state); +static inline void psyc_initParseState (psycParseState* state) +{ + memset(state, 0, sizeof(psycParseState)); +} /** * Initiates the state struct with flags. @@ -137,30 +141,75 @@ inline void psyc_initParseState (psycParseState* state); * @param state Pointer to the state struct that should be initiated. * @param flags Flags to be set for the parser, see psycParseFlag. */ -inline void psyc_initParseState2 (psycParseState* state, uint8_t flags); +static inline void psyc_initParseState2 (psycParseState* state, uint8_t flags) +{ + memset(state, 0, sizeof(psycParseState)); + state->flags = flags; + + if (flags & PSYC_PARSE_START_AT_CONTENT) + state->part = PSYC_PART_CONTENT; +} /** * Sets a new buffer in the parser state struct with data to be parsed. + * + * @param state Pointer to the initialized state of the parser + * @param buffer the buffer that should be parsed now + * @see psycString */ -inline void psyc_setParseBuffer (psycParseState* state, psycString buffer); +static inline void psyc_setParseBuffer (psycParseState* state, psycString buffer) +{ + state->buffer = buffer; + state->cursor = 0; -inline void psyc_setParseBuffer2 (psycParseState* state, char *buffer, size_t length); + if (state->flags & PSYC_PARSE_START_AT_CONTENT) + { + state->contentLength = buffer.length; + state->contentLengthFound = PSYC_TRUE; + } +} + +/** + * Sets a new buffer in the parser state struct with data to be parsed. + * + * @param state Pointer to the initialized state of the parser + * @param buffer pointer to the data that should be parsed + * @param length length of the data in bytes + * @see psycString + */ +static inline void psyc_setParseBuffer2 (psycParseState* state, char *buffer, size_t length) +{ + psyc_setParseBuffer(state, psyc_newString(buffer, length)); +} /** * Initiates the list state struct. * * @param state Pointer to the list state struct that should be initiated. */ -inline void psyc_initParseListState (psycParseListState* state); +static inline void psyc_initParseListState (psycParseListState* state) +{ + memset(state, 0, sizeof(psycParseListState)); +} /** * Sets a new buffer in the list parser state struct with data to be parsed. */ -inline void psyc_setParseListBuffer (psycParseListState* state, psycString buffer); +static inline void psyc_setParseListBuffer (psycParseListState* state, psycString buffer) +{ + state->buffer = buffer; + state->cursor = 0; +} -inline void psyc_setParseListBuffer2 (psycParseListState* state, char *buffer, size_t length); +static inline void psyc_setParseListBuffer2 (psycParseListState* state, char *buffer, size_t length) +{ + psyc_setParseListBuffer(state, psyc_newString(buffer, length)); +} -inline size_t psyc_getContentLength (psycParseState* s); +static inline size_t psyc_getContentLength (psycParseState* s) +{ + return s->contentLength; +} /** * Parse PSYC packets. diff --git a/src/parser.c b/src/parser.c index 5a19146..a4b866c 100644 --- a/src/parser.c +++ b/src/parser.c @@ -15,57 +15,6 @@ return ret; \ } -inline void psyc_initParseState (psycParseState* state) -{ - memset(state, 0, sizeof(psycParseState)); -} - -inline void psyc_initParseState2 (psycParseState* state, uint8_t flags) -{ - memset(state, 0, sizeof(psycParseState)); - state->flags = flags; - - if (flags & PSYC_PARSE_START_AT_CONTENT) - state->part = PSYC_PART_CONTENT; -} - -inline void psyc_setParseBuffer (psycParseState* state, psycString buffer) -{ - state->buffer = buffer; - state->cursor = 0; - - if (state->flags & PSYC_PARSE_START_AT_CONTENT) - { - state->contentLength = buffer.length; - state->contentLengthFound = PSYC_TRUE; - } -} - -inline void psyc_setParseBuffer2 (psycParseState* state, char *buffer, size_t length) -{ - psyc_setParseBuffer(state, psyc_newString(buffer, length)); -} - -inline void psyc_initParseListState (psycParseListState* state) -{ - memset(state, 0, sizeof(psycParseListState)); -} - -inline void psyc_setParseListBuffer (psycParseListState* state, psycString buffer) -{ - state->buffer = buffer; - state->cursor = 0; -} - -inline void psyc_setParseListBuffer2 (psycParseListState* state, char *buffer, size_t length) -{ - psyc_setParseListBuffer(state, psyc_newString(buffer, length)); -} - -inline size_t psyc_getContentLength (psycParseState* s) -{ - return s->contentLength; -} /** * Determines if the argument is a glyph. From 9941b82761f72567cf8093c8f00028aa7e3a81e8 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 3 May 2011 23:03:52 +0200 Subject: [PATCH 151/378] text: moved inline functions to .h, fixed warnings --- include/psyc/text.h | 47 ++++++++++++++++++++++++++++++++++----------- src/text.c | 38 ++---------------------------------- test/testText.c | 9 ++++++--- 3 files changed, 44 insertions(+), 50 deletions(-) diff --git a/include/psyc/text.h b/include/psyc/text.h index 7774684..2bb5394 100644 --- a/include/psyc/text.h +++ b/include/psyc/text.h @@ -38,21 +38,46 @@ typedef struct * number of bytes written. 0 is a legal return value. Should the * callback return -1, psyc_text leaves the original template text as is. */ -typedef psycTextValueRC (*psycTextCB)(char *name, size_t len, psycString *value); +typedef psycTextValueRC (*psycTextCB)(const char *name, size_t len, psycString *value); -inline void psyc_initTextState (psycTextState *state, - char *template, size_t tlen, - char *buffer, size_t blen); +static inline +void psyc_initTextState (psycTextState *state, + char *template, size_t tlen, + char *buffer, size_t blen) +{ + state->cursor = state->written = 0; + state->template = psyc_newString(template, tlen); + state->buffer = psyc_newString(buffer, blen); + state->open = psyc_newString("[", 1); + state->close = psyc_newString("]", 1); +} -inline void psyc_initTextState2 (psycTextState* state, - char *template, size_t tlen, - char *buffer, size_t blen, - char *open, size_t openlen, - char *close, size_t closelen); +static inline +void psyc_initTextState2 (psycTextState* state, + char *template, size_t tlen, + char *buffer, size_t blen, + char *open, size_t openlen, + char *close, size_t closelen) +{ + state->template = psyc_newString(template, tlen); + state->buffer = psyc_newString(buffer, blen); + state->open = psyc_newString(open, openlen); + state->close = psyc_newString(close, closelen); +} -inline void psyc_setTextBuffer (psycTextState *state, psycString buffer); +static inline +void psyc_setTextBuffer (psycTextState* state, psycString buffer) +{ + state->buffer = buffer; + state->written = 0; +} -inline void psyc_setTextBuffer2 (psycTextState *state, char *buffer, size_t length); +static inline +void psyc_setTextBuffer2 (psycTextState* state, + char *buffer, size_t length) +{ + psyc_setTextBuffer(state, psyc_newString(buffer, length)); +} /** * Fills out text templates by asking a callback for content. diff --git a/src/text.c b/src/text.c index 2d00058..674890b 100644 --- a/src/text.c +++ b/src/text.c @@ -1,44 +1,10 @@ #include #include -inline void psyc_initTextState (psycTextState *state, - char *template, size_t tlen, - char *buffer, size_t blen) -{ - state->cursor = state->written = 0; - state->template = psyc_newString(template, tlen); - state->buffer = psyc_newString(buffer, blen); - state->open = psyc_newString("[", 1); - state->close = psyc_newString("]", 1); -} - -inline void psyc_initTextState2 (psycTextState* state, - char *template, size_t tlen, - char *buffer, size_t blen, - char *open, size_t openlen, - char *close, size_t closelen) -{ - state->template = psyc_newString(template, tlen); - state->buffer = psyc_newString(buffer, blen); - state->open = psyc_newString(open, openlen); - state->close = psyc_newString(close, closelen); -} - -inline void psyc_setTextBuffer (psycTextState* state, psycString buffer) -{ - state->buffer = buffer; - state->written = 0; -} - -inline void psyc_setTextBuffer2 (psycTextState* state, char *buffer, size_t length) -{ - psyc_setTextBuffer(state, psyc_newString(buffer, length)); -} - psycTextRC psyc_text (psycTextState *state, psycTextCB getValue) { - char *start = state->template.ptr, *end; // start & end of variable name - char *prev = state->template.ptr + state->cursor; + const char *start = state->template.ptr, *end; // start & end of variable name + const char *prev = state->template.ptr + state->cursor; psycString value; int ret; size_t len; diff --git a/test/testText.c b/test/testText.c index e67b37e..6ea51f7 100644 --- a/test/testText.c +++ b/test/testText.c @@ -7,21 +7,21 @@ uint8_t verbose; -psycTextValueRC getValueFooBar (char *name, size_t len, psycString *value) +psycTextValueRC getValueFooBar (const char *name, size_t len, psycString *value) { value->ptr = "Foo Bar"; value->length = 7; return PSYC_TEXT_VALUE_FOUND; } -psycTextValueRC getValueEmpty (char *name, size_t len, psycString *value) +psycTextValueRC getValueEmpty (const char *name, size_t len, psycString *value) { value->ptr = ""; value->length = 0; return PSYC_TEXT_VALUE_FOUND; } -psycTextValueRC getValueNotFound (char *name, size_t len, psycString *value) +psycTextValueRC getValueNotFound (const char *name, size_t len, psycString *value) { return PSYC_TEXT_VALUE_NOT_FOUND; } @@ -88,5 +88,8 @@ int main(int argc, char **argv) if (memcmp(result.ptr, PSYC_C2ARG("Hello Foo Bar & Foo Bar!"))) return 10 + i; } + + puts("psyc_text passed all tests."); + return 0; } From 13afcccaef8b69b9ae979b62bc19c7860fc7fe72 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 3 May 2011 23:11:13 +0200 Subject: [PATCH 152/378] + --- include/psyc/parser.h | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index 369b87c..87de724 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -130,7 +130,8 @@ typedef struct * * @param state Pointer to the state struct that should be initiated. */ -static inline void psyc_initParseState (psycParseState* state) +static inline +void psyc_initParseState (psycParseState* state) { memset(state, 0, sizeof(psycParseState)); } @@ -141,7 +142,8 @@ static inline void psyc_initParseState (psycParseState* state) * @param state Pointer to the state struct that should be initiated. * @param flags Flags to be set for the parser, see psycParseFlag. */ -static inline void psyc_initParseState2 (psycParseState* state, uint8_t flags) +static inline +void psyc_initParseState2 (psycParseState* state, uint8_t flags) { memset(state, 0, sizeof(psycParseState)); state->flags = flags; @@ -157,7 +159,8 @@ static inline void psyc_initParseState2 (psycParseState* state, uint8_t flags) * @param buffer the buffer that should be parsed now * @see psycString */ -static inline void psyc_setParseBuffer (psycParseState* state, psycString buffer) +static inline +void psyc_setParseBuffer (psycParseState* state, psycString buffer) { state->buffer = buffer; state->cursor = 0; @@ -177,7 +180,8 @@ static inline void psyc_setParseBuffer (psycParseState* state, psycString buffer * @param length length of the data in bytes * @see psycString */ -static inline void psyc_setParseBuffer2 (psycParseState* state, char *buffer, size_t length) +static inline +void psyc_setParseBuffer2 (psycParseState* state, char *buffer, size_t length) { psyc_setParseBuffer(state, psyc_newString(buffer, length)); } @@ -187,7 +191,8 @@ static inline void psyc_setParseBuffer2 (psycParseState* state, char *buffer, si * * @param state Pointer to the list state struct that should be initiated. */ -static inline void psyc_initParseListState (psycParseListState* state) +static inline +void psyc_initParseListState (psycParseListState* state) { memset(state, 0, sizeof(psycParseListState)); } @@ -195,18 +200,21 @@ static inline void psyc_initParseListState (psycParseListState* state) /** * Sets a new buffer in the list parser state struct with data to be parsed. */ -static inline void psyc_setParseListBuffer (psycParseListState* state, psycString buffer) +static inline +void psyc_setParseListBuffer (psycParseListState* state, psycString buffer) { state->buffer = buffer; state->cursor = 0; } -static inline void psyc_setParseListBuffer2 (psycParseListState* state, char *buffer, size_t length) +static inline +void psyc_setParseListBuffer2 (psycParseListState* state, char *buffer, size_t length) { psyc_setParseListBuffer(state, psyc_newString(buffer, length)); } -static inline size_t psyc_getContentLength (psycParseState* s) +static inline +size_t psyc_getContentLength (psycParseState* s) { return s->contentLength; } From 570077f554070bfd58233ea46707a7442bd9d7e9 Mon Sep 17 00:00:00 2001 From: Mathias Laurenz Baumann Date: Tue, 3 May 2011 23:15:31 +0200 Subject: [PATCH 153/378] formating change in parser.h --- include/psyc/parser.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index 87de724..77e10cd 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -131,7 +131,7 @@ typedef struct * @param state Pointer to the state struct that should be initiated. */ static inline -void psyc_initParseState (psycParseState* state) +void psyc_initParseState ( psycParseState* state ) { memset(state, 0, sizeof(psycParseState)); } @@ -143,7 +143,7 @@ void psyc_initParseState (psycParseState* state) * @param flags Flags to be set for the parser, see psycParseFlag. */ static inline -void psyc_initParseState2 (psycParseState* state, uint8_t flags) +void psyc_initParseState2 ( psycParseState* state, uint8_t flags ) { memset(state, 0, sizeof(psycParseState)); state->flags = flags; @@ -160,7 +160,7 @@ void psyc_initParseState2 (psycParseState* state, uint8_t flags) * @see psycString */ static inline -void psyc_setParseBuffer (psycParseState* state, psycString buffer) +void psyc_setParseBuffer ( psycParseState* state, psycString buffer ) { state->buffer = buffer; state->cursor = 0; @@ -181,7 +181,7 @@ void psyc_setParseBuffer (psycParseState* state, psycString buffer) * @see psycString */ static inline -void psyc_setParseBuffer2 (psycParseState* state, char *buffer, size_t length) +void psyc_setParseBuffer2 ( psycParseState* state, char *buffer, size_t length ) { psyc_setParseBuffer(state, psyc_newString(buffer, length)); } @@ -192,7 +192,7 @@ void psyc_setParseBuffer2 (psycParseState* state, char *buffer, size_t length) * @param state Pointer to the list state struct that should be initiated. */ static inline -void psyc_initParseListState (psycParseListState* state) +void psyc_initParseListState ( psycParseListState* state ) { memset(state, 0, sizeof(psycParseListState)); } @@ -201,20 +201,20 @@ void psyc_initParseListState (psycParseListState* state) * Sets a new buffer in the list parser state struct with data to be parsed. */ static inline -void psyc_setParseListBuffer (psycParseListState* state, psycString buffer) +void psyc_setParseListBuffer ( psycParseListState* state, psycString buffer ) { state->buffer = buffer; state->cursor = 0; } static inline -void psyc_setParseListBuffer2 (psycParseListState* state, char *buffer, size_t length) +void psyc_setParseListBuffer2 ( psycParseListState* state, char *buffer, size_t length ) { psyc_setParseListBuffer(state, psyc_newString(buffer, length)); } static inline -size_t psyc_getContentLength (psycParseState* s) +size_t psyc_getContentLength ( psycParseState* s ) { return s->contentLength; } @@ -232,12 +232,12 @@ size_t psyc_getContentLength (psycParseState* s) * @param value A pointer to a psycString. It will point to the * value/body the variable/method and its length will be set accordingly */ -psycParseRC psyc_parse (psycParseState* state, char* oper, psycString* name, psycString* value); +psycParseRC psyc_parse ( psycParseState* state, char* oper, psycString* name, psycString* value); /** * List value parser. */ -psycParseListRC psyc_parseList (psycParseListState* state, psycString *name, psycString* value, psycString* elem); +psycParseListRC psyc_parseList ( psycParseListState* state, psycString *name, psycString* value, psycString* elem); #endif // PSYC_PARSER_H From aaf480b7826371ae619bd1c11f1c4c4e817036af Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 4 May 2011 01:00:35 +0200 Subject: [PATCH 154/378] fixes for inline functions, c99 mode, formatting --- include/psyc.h | 117 ++++---------------------------- include/psyc/packet.h | 138 ++++++++++++++++++++++++++++++++++++++ include/psyc/parser.h | 20 +++--- include/psyc/render.h | 6 +- include/psyc/text.h | 2 +- src/Makefile | 6 +- src/misc.c | 2 - src/packet.c | 103 ++++++++++------------------- src/parser.c | 42 ++++++++---- src/render.c | 7 +- test/Makefile | 5 +- test/testParser.c | 43 ++++++------ test/testRender.c | 22 ++++--- test/testServer.c | 150 +++++++++++++++++++++++++++--------------- 14 files changed, 368 insertions(+), 295 deletions(-) create mode 100644 include/psyc/packet.h delete mode 100644 src/misc.c diff --git a/include/psyc.h b/include/psyc.h index 8ca562b..6d8f1bc 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -24,6 +24,9 @@ #define PSYC_EPOCH 1440444041 // 2015-08-24 21:20:41 CET (Monday) +#define PSYC_C2STR(string) {sizeof(string)-1, string} +#define PSYC_C2ARG(string) string, sizeof(string)-1 + typedef enum { PSYC_FALSE = 0, @@ -79,28 +82,6 @@ typedef enum PSYC_LIST_BINARY = 2, } psycListType; -typedef enum -{ - PSYC_MODIFIER_CHECK_LENGTH = 0, - PSYC_MODIFIER_NEED_LENGTH = 1, - PSYC_MODIFIER_NO_LENGTH = 2, - PSYC_MODIFIER_ROUTING = 3, -} psycModifierFlag; - -typedef enum -{ - PSYC_LIST_CHECK_LENGTH = 0, - PSYC_LIST_NEED_LENGTH = 1, - PSYC_LIST_NO_LENGTH = 2, -} psycListFlag; - -typedef enum -{ - PSYC_PACKET_CHECK_LENGTH = 0, - PSYC_PACKET_NEED_LENGTH = 1, - PSYC_PACKET_NO_LENGTH = 2, -} psycPacketFlag; - typedef struct { size_t length; @@ -121,92 +102,18 @@ typedef struct * * @return An instance of the psycString struct. */ -inline psycString psyc_newString (const char *str, size_t strlen); - -#define PSYC_C2STR(string) {sizeof(string)-1, string} -#define PSYC_C2ARG(string) string, sizeof(string)-1 - -/* intermediate struct for a PSYC variable modification */ -typedef struct +static inline +psycString psyc_newString (const char *str, size_t strlen) { - char oper; // not call it 'operator' as C++ may not like that.. - psycString name; - psycString value; - psycModifierFlag flag; -} psycModifier; + psycString s = {strlen, str}; + return s; +} -typedef struct +static inline +unsigned int psyc_version () { - size_t lines; - psycModifier *modifiers; -} psycHeader; - -typedef struct -{ - size_t num_elems; - psycString *elems; - size_t length; - psycListFlag flag; -} psycList; - -/** intermediate struct for a PSYC packet */ -typedef struct -{ - psycHeader routing; ///< Routing header. - psycHeader entity; ///< Entity header. - psycString method; - psycString data; - size_t routingLength; ///< Length of routing part. - size_t contentLength; ///< Length of content part. - size_t length; ///< Total length of packet. - psycPacketFlag flag; -} psycPacket; - -inline int psyc_version(); - -/** Check if a modifier needs length */ -inline psycModifierFlag psyc_checkModifierLength(psycModifier *m); - -/** Get the total length of a modifier. */ -inline size_t psyc_getModifierLength(psycModifier *m); - -/** Create new modifier */ -inline psycModifier psyc_newModifier(char oper, psycString *name, psycString *value, - psycModifierFlag flag); - -/** Create new modifier */ -inline psycModifier psyc_newModifier2(char oper, - const char *name, size_t namelen, - const char *value, size_t valuelen, - psycModifierFlag flag); - -/** Check if a list needs length */ -inline psycListFlag psyc_checkListLength(psycList *list); - -/** Get the total length of a list. */ -inline psycListFlag psyc_getListLength(psycList *list); - -/** Check if a packet needs length */ -inline psycPacketFlag psyc_checkPacketLength(psycPacket *p); - -/** Calculate and set the length of packet parts and total packet length */ -inline size_t psyc_setPacketLength(psycPacket *p); - -/** Create new list */ -inline psycList psyc_newList(psycString *elems, size_t num_elems, psycListFlag flag); - -/** Create new packet */ -inline psycPacket psyc_newPacket(psycHeader *routing, - psycHeader *entity, - psycString *method, psycString *data, - psycPacketFlag flag); - -/** Create new packet */ -inline psycPacket psyc_newPacket2(psycModifier *routing, size_t routinglen, - psycModifier *entity, size_t entitylen, - const char *method, size_t methodlen, - const char *data, size_t datalen, - psycPacketFlag flag); + return 1; +} /// Routing vars in alphabetical order. extern const psycString PSYC_routingVars[]; diff --git a/include/psyc/packet.h b/include/psyc/packet.h new file mode 100644 index 0000000..173b3d9 --- /dev/null +++ b/include/psyc/packet.h @@ -0,0 +1,138 @@ +#ifndef PSYC_PACKET_H +# define PSYC_PACKET_H + +#include +#include + +typedef enum +{ + PSYC_MODIFIER_CHECK_LENGTH = 0, + PSYC_MODIFIER_NEED_LENGTH = 1, + PSYC_MODIFIER_NO_LENGTH = 2, + PSYC_MODIFIER_ROUTING = 3, +} psycModifierFlag; + +typedef enum +{ + PSYC_LIST_CHECK_LENGTH = 0, + PSYC_LIST_NEED_LENGTH = 1, + PSYC_LIST_NO_LENGTH = 2, +} psycListFlag; + +typedef enum +{ + PSYC_PACKET_CHECK_LENGTH = 0, + PSYC_PACKET_NEED_LENGTH = 1, + PSYC_PACKET_NO_LENGTH = 2, +} psycPacketFlag; + +/** intermediate struct for a PSYC variable modification */ +typedef struct +{ + char oper; + psycString name; + psycString value; + psycModifierFlag flag; +} psycModifier; + +typedef struct +{ + size_t lines; + psycModifier *modifiers; +} psycHeader; + +typedef struct +{ + size_t num_elems; + psycString *elems; + size_t length; + psycListFlag flag; +} psycList; + +/** intermediate struct for a PSYC packet */ +typedef struct +{ + psycHeader routing; ///< Routing header. + psycHeader entity; ///< Entity header. + psycString method; + psycString data; + size_t routingLength; ///< Length of routing part. + size_t contentLength; ///< Length of content part. + size_t length; ///< Total length of packet. + psycPacketFlag flag; +} psycPacket; + +/** Check if a modifier needs length */ +static inline +psycModifierFlag psyc_checkModifierLength (psycModifier *m) +{ + psycModifierFlag flag; + + if (m->value.length > PSYC_MODIFIER_SIZE_THRESHOLD) + flag = PSYC_MODIFIER_NEED_LENGTH; + else if (memchr(m->value.ptr, (int)'\n', m->value.length)) + flag = PSYC_MODIFIER_NEED_LENGTH; + else + flag = PSYC_MODIFIER_NO_LENGTH; + + return flag; +} + +/** Create new modifier */ +static inline +psycModifier psyc_newModifier (char oper, psycString *name, psycString *value, + psycModifierFlag flag) +{ + psycModifier m = {oper, *name, *value, flag}; + + if (flag == PSYC_MODIFIER_CHECK_LENGTH) // find out if it needs a length + m.flag = psyc_checkModifierLength(&m); + + return m; +} + +/** Create new modifier */ +static inline +psycModifier psyc_newModifier2 (char oper, + const char *name, size_t namelen, + const char *value, size_t valuelen, + psycModifierFlag flag) +{ + psycString n = {namelen, name}; + psycString v = {valuelen, value}; + + return psyc_newModifier(oper, &n, &v, flag); +} + +/** Get the total length of a modifier. */ +size_t psyc_getModifierLength (psycModifier *m); + +/** Check if a list needs length */ +psycListFlag psyc_checkListLength (psycList *list); + +/** Get the total length of a list. */ +psycListFlag psyc_getListLength (psycList *list); + +/** Check if a packet needs length */ +psycPacketFlag psyc_checkPacketLength (psycPacket *p); + +/** Calculate and set the length of packet parts and total packet length */ +size_t psyc_setPacketLength (psycPacket *p); + +/** Create new list */ +psycList psyc_newList (psycString *elems, size_t num_elems, psycListFlag flag); + +/** Create new packet */ +psycPacket psyc_newPacket (psycHeader *routing, + psycHeader *entity, + psycString *method, psycString *data, + psycPacketFlag flag); + +/** Create new packet */ +psycPacket psyc_newPacket2 (psycModifier *routing, size_t routinglen, + psycModifier *entity, size_t entitylen, + const char *method, size_t methodlen, + const char *data, size_t datalen, + psycPacketFlag flag); + +#endif // PSYC_PACKET_H diff --git a/include/psyc/parser.h b/include/psyc/parser.h index 77e10cd..87de724 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -131,7 +131,7 @@ typedef struct * @param state Pointer to the state struct that should be initiated. */ static inline -void psyc_initParseState ( psycParseState* state ) +void psyc_initParseState (psycParseState* state) { memset(state, 0, sizeof(psycParseState)); } @@ -143,7 +143,7 @@ void psyc_initParseState ( psycParseState* state ) * @param flags Flags to be set for the parser, see psycParseFlag. */ static inline -void psyc_initParseState2 ( psycParseState* state, uint8_t flags ) +void psyc_initParseState2 (psycParseState* state, uint8_t flags) { memset(state, 0, sizeof(psycParseState)); state->flags = flags; @@ -160,7 +160,7 @@ void psyc_initParseState2 ( psycParseState* state, uint8_t flags ) * @see psycString */ static inline -void psyc_setParseBuffer ( psycParseState* state, psycString buffer ) +void psyc_setParseBuffer (psycParseState* state, psycString buffer) { state->buffer = buffer; state->cursor = 0; @@ -181,7 +181,7 @@ void psyc_setParseBuffer ( psycParseState* state, psycString buffer ) * @see psycString */ static inline -void psyc_setParseBuffer2 ( psycParseState* state, char *buffer, size_t length ) +void psyc_setParseBuffer2 (psycParseState* state, char *buffer, size_t length) { psyc_setParseBuffer(state, psyc_newString(buffer, length)); } @@ -192,7 +192,7 @@ void psyc_setParseBuffer2 ( psycParseState* state, char *buffer, size_t length ) * @param state Pointer to the list state struct that should be initiated. */ static inline -void psyc_initParseListState ( psycParseListState* state ) +void psyc_initParseListState (psycParseListState* state) { memset(state, 0, sizeof(psycParseListState)); } @@ -201,20 +201,20 @@ void psyc_initParseListState ( psycParseListState* state ) * Sets a new buffer in the list parser state struct with data to be parsed. */ static inline -void psyc_setParseListBuffer ( psycParseListState* state, psycString buffer ) +void psyc_setParseListBuffer (psycParseListState* state, psycString buffer) { state->buffer = buffer; state->cursor = 0; } static inline -void psyc_setParseListBuffer2 ( psycParseListState* state, char *buffer, size_t length ) +void psyc_setParseListBuffer2 (psycParseListState* state, char *buffer, size_t length) { psyc_setParseListBuffer(state, psyc_newString(buffer, length)); } static inline -size_t psyc_getContentLength ( psycParseState* s ) +size_t psyc_getContentLength (psycParseState* s) { return s->contentLength; } @@ -232,12 +232,12 @@ size_t psyc_getContentLength ( psycParseState* s ) * @param value A pointer to a psycString. It will point to the * value/body the variable/method and its length will be set accordingly */ -psycParseRC psyc_parse ( psycParseState* state, char* oper, psycString* name, psycString* value); +psycParseRC psyc_parse (psycParseState* state, char* oper, psycString* name, psycString* value); /** * List value parser. */ -psycParseListRC psyc_parseList ( psycParseListState* state, psycString *name, psycString* value, psycString* elem); +psycParseListRC psyc_parseList (psycParseListState* state, psycString *name, psycString* value, psycString* elem); #endif // PSYC_PARSER_H diff --git a/include/psyc/render.h b/include/psyc/render.h index 86eb037..bf7ebcb 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -1,6 +1,8 @@ #ifndef PSYC_RENDER_H # define PSYC_RENDER_H +#include + /** * @file psyc/render.h * @brief Interface for PSYC packet rendering. @@ -29,12 +31,12 @@ typedef enum /** * Render a PSYC packet into a buffer. */ -psycRenderRC psyc_render(psycPacket *packet, char *buffer, size_t buflen); +psycRenderRC psyc_render (psycPacket *packet, char *buffer, size_t buflen); /** * Render a PSYC list into a buffer. */ -psycRenderRC psyc_renderList(psycList *list, char *buffer, size_t buflen); +psycRenderRC psyc_renderList (psycList *list, char *buffer, size_t buflen); #endif // PSYC_RENDER_H diff --git a/include/psyc/text.h b/include/psyc/text.h index 2bb5394..a9f25b3 100644 --- a/include/psyc/text.h +++ b/include/psyc/text.h @@ -93,4 +93,4 @@ void psyc_setTextBuffer2 (psycTextState* state, * See also http://about.psyc.eu/psyctext */ -psycTextRC psyc_text(psycTextState *state, psycTextCB getValue); +psycTextRC psyc_text (psycTextState *state, psycTextCB getValue); diff --git a/src/Makefile b/src/Makefile index 4ffaed1..e0bb01b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,10 +1,10 @@ OPT = -O2 DEBUG = 2 -CFLAGS = -I../include -Wall ${OPT} +CFLAGS = -I../include -Wall -std=c99 ${OPT} DIET = diet -S = packet.c misc.c parser.c match.c render.c memmem.c itoa.c variable.c text.c -O = packet.o misc.o parser.o match.o render.o memmem.o itoa.o variable.o text.o +S = packet.c parser.c match.c render.c memmem.c itoa.c variable.c text.c +O = packet.o parser.o match.o render.o memmem.o itoa.o variable.o text.o all: CC := ${WRAPPER} ${CC} all: lib diff --git a/src/misc.c b/src/misc.c deleted file mode 100644 index a92359d..0000000 --- a/src/misc.c +++ /dev/null @@ -1,2 +0,0 @@ -int psyc_version() { return 1; } - diff --git a/src/packet.c b/src/packet.c index a29a21f..c30d9fd 100644 --- a/src/packet.c +++ b/src/packet.c @@ -1,63 +1,11 @@ #include #include +#include #include -inline psycString psyc_newString(const char *str, size_t strlen) -{ - psycString s = {strlen, str}; - return s; -} - -inline psycModifierFlag psyc_checkModifierLength(psycModifier *m) -{ - psycModifierFlag flag; - - if (m->value.length > PSYC_MODIFIER_SIZE_THRESHOLD) - flag = PSYC_MODIFIER_NEED_LENGTH; - else if (memchr(m->value.ptr, (int)'\n', m->value.length)) - flag = PSYC_MODIFIER_NEED_LENGTH; - else - flag = PSYC_MODIFIER_NO_LENGTH; - - return flag; -} - -inline size_t psyc_getModifierLength(psycModifier *m) -{ - size_t length = 1 + // oper - m->name.length + 1 + // name\t - m->value.length + 1; // value\n - - if (m->flag == PSYC_MODIFIER_NEED_LENGTH) // add length of length if needed - length += log10((double)m->value.length) + 2; // SP length - - return length; -} - -inline psycModifier psyc_newModifier(char oper, psycString *name, psycString *value, - psycModifierFlag flag) -{ - psycModifier m = {oper, *name, *value, flag}; - - if (flag == PSYC_MODIFIER_CHECK_LENGTH) // find out if it needs a length - m.flag = psyc_checkModifierLength(&m); - - return m; -} - -inline psycModifier psyc_newModifier2(char oper, - const char *name, size_t namelen, - const char *value, size_t valuelen, - psycModifierFlag flag) -{ - psycString n = {namelen, name}; - psycString v = {valuelen, value}; - - return psyc_newModifier(oper, &n, &v, flag); -} - -inline psycListFlag psyc_checkListLength(psycList *list) +inline +psycListFlag psyc_checkListLength (psycList *list) { psycListFlag flag = PSYC_LIST_NO_LENGTH; size_t i, length = 0; @@ -78,7 +26,8 @@ inline psycListFlag psyc_checkListLength(psycList *list) return flag; } -inline psycListFlag psyc_getListLength(psycList *list) +inline +psycListFlag psyc_getListLength (psycList *list) { size_t i, length = 0; @@ -100,7 +49,8 @@ inline psycListFlag psyc_getListLength(psycList *list) return length; } -inline psycList psyc_newList(psycString *elems, size_t num_elems, psycListFlag flag) +inline +psycList psyc_newList(psycString *elems, size_t num_elems, psycListFlag flag) { psycList list = {num_elems, elems, 0, flag}; @@ -111,7 +61,22 @@ inline psycList psyc_newList(psycString *elems, size_t num_elems, psycListFlag f return list; } -inline psycPacketFlag psyc_checkPacketLength(psycPacket *p) + +inline +size_t psyc_getModifierLength (psycModifier *m) +{ + size_t length = 1 + // oper + m->name.length + 1 + // name\t + m->value.length + 1; // value\n + + if (m->flag == PSYC_MODIFIER_NEED_LENGTH) // add length of length if needed + length += log10((double)m->value.length) + 2; // SP length + + return length; +} + +inline +psycPacketFlag psyc_checkPacketLength(psycPacket *p) { if (p->data.length == 1 && p->data.ptr[0] == C_GLYPH_PACKET_DELIMITER) return PSYC_PACKET_NEED_LENGTH; @@ -132,7 +97,8 @@ inline psycPacketFlag psyc_checkPacketLength(psycPacket *p) return PSYC_PACKET_NO_LENGTH; } -inline size_t psyc_setPacketLength(psycPacket *p) +inline +size_t psyc_setPacketLength(psycPacket *p) { size_t i; p->routingLength = 0; @@ -165,10 +131,10 @@ inline size_t psyc_setPacketLength(psycPacket *p) return p->length; } -inline psycPacket psyc_newPacket(psycHeader *routing, - psycHeader *entity, - psycString *method, psycString *data, - psycPacketFlag flag) +inline +psycPacket psyc_newPacket (psycHeader *routing, psycHeader *entity, + psycString *method, psycString *data, + psycPacketFlag flag) { psycPacket p = {*routing, *entity, *method, *data, 0, 0, flag}; @@ -179,11 +145,12 @@ inline psycPacket psyc_newPacket(psycHeader *routing, return p; } -inline psycPacket psyc_newPacket2(psycModifier *routing, size_t routinglen, - psycModifier *entity, size_t entitylen, - const char *method, size_t methodlen, - const char *data, size_t datalen, - psycPacketFlag flag) +inline +psycPacket psyc_newPacket2 (psycModifier *routing, size_t routinglen, + psycModifier *entity, size_t entitylen, + const char *method, size_t methodlen, + const char *data, size_t datalen, + psycPacketFlag flag) { psycHeader r = {routinglen, routing}; psycHeader e = {entitylen, entity}; diff --git a/src/parser.c b/src/parser.c index a4b866c..6778090 100644 --- a/src/parser.c +++ b/src/parser.c @@ -20,7 +20,8 @@ * Determines if the argument is a glyph. * Glyphs are: : = + - ? ! */ -inline char isGlyph(uint8_t g) +static inline +char isGlyph (uint8_t g) { switch(g) { @@ -39,7 +40,8 @@ inline char isGlyph(uint8_t g) /** * Determines if the argument is numeric. */ -inline char isNumeric (uint8_t c) +static inline +char isNumeric (uint8_t c) { return c >= '0' && c <= '9'; } @@ -47,7 +49,8 @@ inline char isNumeric (uint8_t c) /** * Determines if the argument is alphanumeric. */ -inline char isAlphaNumeric (uint8_t c) +static inline +char isAlphaNumeric (uint8_t c) { return (c >= 'a' && c <= 'z') || @@ -59,7 +62,8 @@ inline char isAlphaNumeric (uint8_t c) * Determines if the argument is a keyword character. * Keyword characters are: alphanumeric and _ */ -inline char isKwChar (uint8_t c) +static inline +char isKwChar (uint8_t c) { return isAlphaNumeric(c) || c == '_'; } @@ -69,7 +73,8 @@ inline char isKwChar (uint8_t c) * It should contain one or more keyword characters. * @return PSYC_PARSE_ERROR or PSYC_PARSE_SUCCESS */ -inline psycParseRC psyc_parseName (psycParseState* state, psycString* name) +static inline +psycParseRC psyc_parseKeyword (psycParseState* state, psycString* name) { name->ptr = state->buffer.ptr + state->cursor; name->length = 0; @@ -93,7 +98,9 @@ inline psycParseRC psyc_parseName (psycParseState* state, psycString* name) * * @return PSYC_PARSE_COMPLETE or PSYC_PARSE_INCOMPLETE */ -inline psycParseRC psyc_parseBinaryValue (psycParseState* state, psycString* value, size_t* length, size_t* parsed) +static inline +psycParseRC psyc_parseBinaryValue (psycParseState *state, psycString *value, + size_t *length, size_t *parsed) { size_t remaining = *length - *parsed; value->ptr = state->buffer.ptr + state->cursor; @@ -118,12 +125,14 @@ inline psycParseRC psyc_parseBinaryValue (psycParseState* state, psycString* val * Parse simple or binary variable. * @return PSYC_PARSE_ERROR or PSYC_PARSE_SUCCESS */ -inline psycParseRC psyc_parseModifier (psycParseState* state, char* oper, psycString* name, psycString* value) +static inline +psycParseRC psyc_parseModifier (psycParseState *state, char *oper, + psycString *name, psycString *value) { *oper = *(state->buffer.ptr + state->cursor); PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); - psycParseRC ret = psyc_parseName(state, name); + psycParseRC ret = psyc_parseKeyword(state, name); if (ret == PSYC_PARSE_ERROR) return PSYC_PARSE_ERROR_MOD_NAME; else if (ret != PSYC_PARSE_SUCCESS) @@ -187,10 +196,12 @@ inline psycParseRC psyc_parseModifier (psycParseState* state, char* oper, psycSt * Parse PSYC packets. * Generalized line-based parser. */ -psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psycString* value) +psycParseRC psyc_parse (psycParseState* state, char* oper, + psycString* name, psycString* value) { #ifdef DEBUG - if (state->flags & PSYC_PARSE_ROUTING_ONLY && state->flags & PSYC_PARSE_START_AT_CONTENT) + if (state->flags & PSYC_PARSE_ROUTING_ONLY && + state->flags & PSYC_PARSE_START_AT_CONTENT) PP(("Invalid flag combination")) #endif @@ -333,7 +344,7 @@ psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psyc case PSYC_PART_METHOD: pos = state->cursor; - ret = psyc_parseName(state, name); + ret = psyc_parseKeyword(state, name); if (ret == PSYC_PARSE_INSUFFICIENT) return ret; @@ -369,7 +380,8 @@ psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psyc if (state->contentLengthFound) // We know the length of the packet. { if (state->contentParsed < state->contentLength && - psyc_parseBinaryValue(state, value, &(state->contentLength), &(state->contentParsed)) == PSYC_PARSE_INCOMPLETE) + psyc_parseBinaryValue(state, value, &(state->contentLength), + &(state->contentParsed)) == PSYC_PARSE_INCOMPLETE) return PSYC_PARSE_BODY_INCOMPLETE; if (state->cursor >= state->buffer.length) @@ -437,7 +449,8 @@ psycParseRC psyc_parse(psycParseState* state, char* oper, psycString* name, psyc * List value parser. * @return see psycListRC. */ -psycParseListRC psyc_parseList(psycParseListState* state, psycString *name, psycString* value, psycString* elem) +psycParseListRC psyc_parseList (psycParseListState* state, psycString *name, + psycString* value, psycString* elem) { if (state->cursor >= state->buffer.length) return PSYC_PARSE_LIST_INCOMPLETE; @@ -508,7 +521,8 @@ psycParseListRC psyc_parseList(psycParseListState* state, psycString *name, psyc // Start or resume parsing the binary data if (state->elemParsed < state->elemLength) { - if (psyc_parseBinaryValue((psycParseState*)state, elem, &(state->elemLength), &(state->elemParsed)) == PSYC_PARSE_INCOMPLETE) + if (psyc_parseBinaryValue((psycParseState*)state, elem, + &(state->elemLength), &(state->elemParsed)) == PSYC_PARSE_INCOMPLETE) return PSYC_PARSE_LIST_INCOMPLETE; state->elemLength = 0; diff --git a/src/render.c b/src/render.c index b6a9569..6935f8f 100644 --- a/src/render.c +++ b/src/render.c @@ -2,7 +2,7 @@ #include "psyc/render.h" #include "psyc/syntax.h" -psycRenderRC psyc_renderList(psycList *list, char *buffer, size_t buflen) +psycRenderRC psyc_renderList (psycList *list, char *buffer, size_t buflen) { size_t i, cur = 0; psycString *elem; @@ -37,7 +37,8 @@ psycRenderRC psyc_renderList(psycList *list, char *buffer, size_t buflen) return PSYC_RENDER_SUCCESS; } -inline size_t psyc_renderModifier(psycModifier *mod, char *buffer) +static inline +size_t psyc_renderModifier (psycModifier *mod, char *buffer) { size_t cur = 0; @@ -58,7 +59,7 @@ inline size_t psyc_renderModifier(psycModifier *mod, char *buffer) return cur; } -psycRenderRC psyc_render(psycPacket *packet, char *buffer, size_t buflen) +psycRenderRC psyc_render (psycPacket *packet, char *buffer, size_t buflen) { size_t i, cur = 0; diff --git a/test/Makefile b/test/Makefile index 7b7dbb5..4b73eb7 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,6 +1,6 @@ OPT = -O2 DEBUG = 2 -CFLAGS = -I../include -Wall ${OPT} +CFLAGS = -I../include -Wall -std=c99 ${OPT} LDFLAGS = -L../lib LOADLIBES = -lpsyc -lm TARGETS = testServer testParser testMatch testRender testText isRoutingVar getVarType @@ -20,10 +20,13 @@ debug: all test: ${TARGETS} ./testRender ./testMatch + ./testText ./isRoutingVar ./getVarType for f in packets/full-*; do echo ">> $$f"; ./testParser $$f; done +testServer: CFLAGS := $(subst -std=c99,,${CFLAGS}) + netstart: ./testServer ${PORT} diff --git a/test/testParser.c b/test/testParser.c index deb470e..2f203f7 100644 --- a/test/testParser.c +++ b/test/testParser.c @@ -2,10 +2,10 @@ #include #include -#include +#include #include -int main(int argc, char **argv) +int main (int argc, char **argv) { int idx, ret, routing_only = argc > 2, verbose = argc > 3; char buffer[2048], oper; @@ -19,9 +19,9 @@ int main(int argc, char **argv) idx = read(file,(void*)buffer,sizeof(buffer)); if (verbose) { - write(1, ">> INPUT\n", 9); - write(1, buffer, idx); - write(1, ">> PARSE\n", 9); + printf(">> INPUT\n"); + printf("%.*s\n", (int)idx, buffer); + printf(">> PARSE\n"); } if (routing_only) @@ -32,9 +32,8 @@ int main(int argc, char **argv) psyc_setParseBuffer(&state, psyc_newString(buffer, idx)); // try parsing that now -// while ((ret = psyc_parse(&state, &oper, &name, &value))) -// { - do { + do + { oper = 0; name.length = 0; value.length = 0; @@ -42,24 +41,24 @@ int main(int argc, char **argv) ret = psyc_parse(&state, &oper, &name, &value); if (verbose) printf(">> ret = %d\n", ret); + switch (ret) { case PSYC_PARSE_ROUTING: case PSYC_PARSE_ENTITY: if (verbose) - write(1, &oper, 1); + printf("%c", oper); case PSYC_PARSE_BODY: // printf("the string is '%.*s'\n", name); - if (verbose) { - write(1, name.ptr, name.length); - write(1, " = ", 3); - write(1, value.ptr, value.length); - write(1, "\n", 1); - } + if (verbose) + printf("%.*s = %.*s\n", + (int)name.length, name.ptr, + (int)value.length, value.ptr); + if (memcmp(name.ptr, "_list", 5) == 0) { if (verbose) - write(1, ">>> LIST START\n", 15); + printf(">> LIST START\n"); psyc_initParseListState(&listState); psyc_setParseListBuffer(&listState, value); @@ -70,11 +69,8 @@ int main(int argc, char **argv) { case PSYC_PARSE_LIST_END: case PSYC_PARSE_LIST_ELEM: - if (verbose) { - write(1, "|", 1); - write(1, elem.ptr, elem.length); - write(1, "\n", 1); - } + if (verbose) + printf("|%.*s\n", (int)elem.length, elem.ptr); break; default: printf("Error while parsing list: %i\n", ret); @@ -84,7 +80,7 @@ int main(int argc, char **argv) if (ret == PSYC_PARSE_LIST_END) { if (verbose) - write(1, ">>> LIST END\n", 13); + printf(">> LIST END\n"); break; } } @@ -101,7 +97,8 @@ int main(int argc, char **argv) printf("Error while parsing: %i\n", ret); return 1; } - } while (ret); + } + while (ret); return 0; } diff --git a/test/testRender.c b/test/testRender.c index 4a274f8..edfb798 100644 --- a/test/testRender.c +++ b/test/testRender.c @@ -1,13 +1,15 @@ -#include -#include -#include "../include/psyc/lib.h" -#include "../include/psyc/render.h" -#include "../include/psyc/syntax.h" +#include + +#include +#include +#include #define myUNI "psyc://10.100.1000/~ludwig" /* example renderer generating a presence packet */ -int testPresence(const char *avail, int availlen, const char *desc, int desclen, const char *rendered, uint8_t verbose) +int testPresence (const char *avail, int availlen, + const char *desc, int desclen, + const char *rendered, uint8_t verbose) { psycModifier routing[] = { psyc_newModifier2(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_context"), PSYC_C2ARG(myUNI), @@ -31,11 +33,11 @@ int testPresence(const char *avail, int availlen, const char *desc, int desclen, char buffer[512]; psyc_render(&packet, buffer, sizeof(buffer)); if (verbose) - write(0, buffer, packet.length); + printf("%.*s\n", (int)packet.length, buffer); return strncmp(rendered, buffer, packet.length); } -int testList(const char *rendered, uint8_t verbose) +int testList (const char *rendered, uint8_t verbose) { psycModifier routing[] = { psyc_newModifier2(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_source"), PSYC_C2ARG(myUNI), @@ -80,11 +82,11 @@ int testList(const char *rendered, uint8_t verbose) char buffer[512]; psyc_render(&packet, buffer, sizeof(buffer)); if (verbose) - write(0, buffer, packet.length); + printf("%.*s\n", (int)packet.length, buffer); return strncmp(rendered, buffer, packet.length); } -int main(int argc, char **argv) { +int main (int argc, char **argv) { uint8_t verbose = argc > 1; if (testPresence(PSYC_C2ARG("_here"), PSYC_C2ARG("I'm omnipresent right now"), "\ diff --git a/test/testServer.c b/test/testServer.c index b2256da..9003cf2 100644 --- a/test/testServer.c +++ b/test/testServer.c @@ -31,16 +31,15 @@ const size_t ROUTING_LINES = 16; const size_t ENTITY_LINES = 32; // get sockaddr, IPv4 or IPv6: -void *get_in_addr(struct sockaddr *sa) +void *get_in_addr (struct sockaddr *sa) { - if (sa->sa_family == AF_INET) { + if (sa->sa_family == AF_INET) return &(((struct sockaddr_in*)sa)->sin_addr); - } return &(((struct sockaddr_in6*)sa)->sin6_addr); } -int main(int argc, char **argv) +int main (int argc, char **argv) { char *port = argc > 1 ? argv[1] : "4440"; uint8_t routing_only = argc > 2, verbose = argc > 3; @@ -71,12 +70,12 @@ int main(int argc, char **argv) psycPacket packets[NUM_PARSERS]; psycModifier routing[NUM_PARSERS][ROUTING_LINES]; psycModifier entity[NUM_PARSERS][ENTITY_LINES]; - psycModifier *mod; + psycModifier *mod = NULL; int ret, retl; char oper; psycString name, value, elem; - psycString *pname, *pvalue; + psycString *pname = NULL, *pvalue = NULL; psycParseListState listState; FD_ZERO(&master); // clear the master and temp sets @@ -87,21 +86,23 @@ int main(int argc, char **argv) hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; - if ((rv = getaddrinfo(NULL, port, &hints, &ai)) != 0) { + if ((rv = getaddrinfo(NULL, port, &hints, &ai)) != 0) +{ fprintf(stderr, "error: %s\n", gai_strerror(rv)); exit(1); } - for (p = ai; p != NULL; p = p->ai_next) { + for (p = ai; p != NULL; p = p->ai_next) + { listener = socket(p->ai_family, p->ai_socktype, p->ai_protocol); - if (listener < 0) { + if (listener < 0) continue; - } // lose the pesky "address already in use" error message setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); - if (bind(listener, p->ai_addr, p->ai_addrlen) < 0) { + if (bind(listener, p->ai_addr, p->ai_addrlen) < 0) + { close(listener); continue; } @@ -110,7 +111,8 @@ int main(int argc, char **argv) } // if we got here, it means we didn't get bound - if (p == NULL) { + if (p == NULL) + { fprintf(stderr, "failed to bind\n"); exit(2); } @@ -118,7 +120,8 @@ int main(int argc, char **argv) freeaddrinfo(ai); // all done with this // listen - if (listen(listener, 10) == -1) { + if (listen(listener, 10) == -1) + { perror("listen"); exit(3); } @@ -130,17 +133,22 @@ int main(int argc, char **argv) fdmax = listener; // so far, it's this one // main loop - for (;;) { + for (;;) + { read_fds = master; // copy it - if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) { + if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) + { perror("select"); exit(4); } // run through the existing connections looking for data to read - for (i = 0; i <= fdmax; i++) { - if (FD_ISSET(i, &read_fds)) { // we got one!! - if (i == listener) { + for (i = 0; i <= fdmax; i++) + { + if (FD_ISSET(i, &read_fds)) // we got one!! + { + if (i == listener) + { // handle new connections if (fdmax == NUM_PARSERS - 1) continue; // ignore if there's too many @@ -148,13 +156,13 @@ int main(int argc, char **argv) addrlen = sizeof remoteaddr; newfd = accept(listener, (struct sockaddr *)&remoteaddr, &addrlen); - if (newfd == -1) { + if (newfd == -1) perror("accept"); - } else { + else + { FD_SET(newfd, &master); // add to master set - if (newfd > fdmax) { // keep track of the max + if (newfd > fdmax) // keep track of the max fdmax = newfd; - } // reset parser state & packet if (routing_only) @@ -174,19 +182,23 @@ int main(int argc, char **argv) remoteIP, INET6_ADDRSTRLEN), newfd); } - } else { + } + else + { // handle data from a client - if ((nbytes = recv(i, recvbuf, RECV_BUF_SIZE, 0)) <= 0) { + if ((nbytes = recv(i, recvbuf, RECV_BUF_SIZE, 0)) <= 0) + { // got error or connection closed by client - if (nbytes == 0) { - // connection closed + if (nbytes == 0) // connection closed printf("socket %d hung up\n", i); - } else { + else perror("recv"); - } + close(i); // bye! FD_CLR(i, &master); // remove from master set - } else { + } + else + { // we got some data from a client parsebuf = recvbuf - contbytes; psyc_setParseBuffer(&parsers[i], psyc_newString(parsebuf, contbytes + nbytes)); @@ -195,7 +207,8 @@ int main(int argc, char **argv) name.length = 0; value.length = 0; - do { + do + { ret = psyc_parse(&parsers[i], &oper, &name, &value); if (verbose) printf("# ret = %d\n", ret); @@ -209,69 +222,86 @@ int main(int argc, char **argv) mod->flag = PSYC_MODIFIER_ROUTING; packets[i].routing.lines++; break; + case PSYC_PARSE_ENTITY_INCOMPLETE: case PSYC_PARSE_ENTITY: assert(packets[i].entity.lines < ENTITY_LINES); mod = &(packets[i].entity.modifiers[packets[i].entity.lines]); pname = &mod->name; pvalue = &mod->value; - if (ret == PSYC_PARSE_ENTITY) { + + if (ret == PSYC_PARSE_ENTITY) + { packets[i].entity.lines++; - mod->flag = parsers[i].valueLength ? PSYC_MODIFIER_NEED_LENGTH : PSYC_MODIFIER_NO_LENGTH; + mod->flag = parsers[i].valueLength ? + PSYC_MODIFIER_NEED_LENGTH : PSYC_MODIFIER_NO_LENGTH; } break; + case PSYC_PARSE_BODY_INCOMPLETE: case PSYC_PARSE_BODY: pname = &(packets[i].method); pvalue = &(packets[i].data); break; + case PSYC_PARSE_COMPLETE: printf("# Done parsing.\n"); - packets[i].flag = parsers[i].contentLengthFound ? PSYC_PACKET_NEED_LENGTH : PSYC_PACKET_NO_LENGTH; + packets[i].flag = parsers[i].contentLengthFound ? + PSYC_PACKET_NEED_LENGTH : PSYC_PACKET_NO_LENGTH; + psyc_setPacketLength(&packets[i]); psyc_render(&packets[i], sendbuf, SEND_BUF_SIZE); - if (send(i, sendbuf, packets[i].length, 0) == -1) { + + if (send(i, sendbuf, packets[i].length, 0) == -1) perror("send"); - } + ret = -1; break; case PSYC_PARSE_INSUFFICIENT: if (verbose) printf("# Insufficient data.\n"); + contbytes = parsers[i].buffer.length - parsers[i].cursor; - if (contbytes > 0) { // copy end of parsebuf before start of recvbuf + + if (contbytes > 0) // copy end of parsebuf before start of recvbuf + { assert(recvbuf - contbytes >= buf); // make sure it's still in the buffer memcpy(recvbuf - contbytes, parsebuf + parsers[i].cursor, contbytes); } ret = 0; break; + default: printf("# Error while parsing: %i\n", ret); ret = -1; } - switch (ret) { + switch (ret) + { case PSYC_PARSE_ENTITY_INCOMPLETE: case PSYC_PARSE_BODY_INCOMPLETE: ret = 0; case PSYC_PARSE_ENTITY: case PSYC_PARSE_ROUTING: case PSYC_PARSE_BODY: - if (oper) { + if (oper) + { mod->oper = oper; if (verbose) printf("%c", oper); } - if (name.length) { + if (name.length) + { pname->ptr = malloc(name.length); pname->length = name.length; + assert(pname->ptr != NULL); memcpy((void*)pname->ptr, name.ptr, name.length); name.length = 0; - if (verbose) { + + if (verbose) printf("%.*s = ", (int)pname->length, pname->ptr); - } } if (value.length) { @@ -281,51 +311,65 @@ int main(int argc, char **argv) memcpy((void*)pvalue->ptr + pvalue->length, value.ptr, value.length); pvalue->length += value.length; value.length = 0; - if (verbose) { + + if (verbose) + { printf("%.*s", (int)pvalue->length, pvalue->ptr); if (parsers[i].valueLength > pvalue->length) printf("..."); printf("\n"); } - } else if (verbose) { - printf("\n"); } + else if (verbose) + printf("\n"); if (verbose) - printf("\t\t\t\t\t\t\t\t# n:%ld v:%ld c:%ld r:%ld\n", pname->length, pvalue->length, parsers[i].contentParsed, parsers[i].routingLength); + printf("\t\t\t\t\t\t\t\t# n:%ld v:%ld c:%ld r:%ld\n", + pname->length, pvalue->length, + parsers[i].contentParsed, parsers[i].routingLength); } - switch (ret) { + switch (ret) + { case PSYC_PARSE_ROUTING: case PSYC_PARSE_ENTITY: - if (pname->length >= 5 && memcmp(pname->ptr, "_list", 5) == 0) { + if (pname->length >= 5 && memcmp(pname->ptr, "_list", 5) == 0) + { if (verbose) printf("## LIST START\n"); psyc_initParseListState(&listState); psyc_setParseListBuffer(&listState, *pvalue); - do { + do + { retl = psyc_parseList(&listState, pname, pvalue, &elem); - switch (retl) { + switch (retl) + { case PSYC_PARSE_LIST_END: retl = 0; case PSYC_PARSE_LIST_ELEM: - if (verbose) { + if (verbose) + { printf("|%.*s\n", (int)elem.length, elem.ptr); if (ret == PSYC_PARSE_LIST_END) printf("## LIST END"); } break; + default: printf("# Error while parsing list: %i\n", ret); ret = retl = -1; } - } while (retl > 0); + } + while (retl > 0); } } - } while (ret > 0); - if (ret < 0) { + } + while (ret > 0); + + if (ret < 0) + { printf("# Closing connection: %i\n", i); close(i); // bye! FD_CLR(i, &master); // remove from master set From a2133e15f9c7bb373d7584289239c95a60ed550d Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 4 May 2011 01:30:09 +0200 Subject: [PATCH 155/378] text: docs --- include/psyc/parser.h | 16 ++++---- include/psyc/render.h | 4 +- include/psyc/text.h | 85 +++++++++++++++++++++++++++++++++++-------- 3 files changed, 80 insertions(+), 25 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index 87de724..dc6c378 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -7,7 +7,7 @@ */ /** - * @defgroup parsing Parsing Functions + * @defgroup parser Parsing Functions * * This module contains all parsing functions. * @{ @@ -126,9 +126,9 @@ typedef struct } psycParseListState; /** - * Initiates the state struct. + * Initializes the state struct. * - * @param state Pointer to the state struct that should be initiated. + * @param state Pointer to the state struct that should be initialized. */ static inline void psyc_initParseState (psycParseState* state) @@ -137,9 +137,9 @@ void psyc_initParseState (psycParseState* state) } /** - * Initiates the state struct with flags. + * Initializes the state struct with flags. * - * @param state Pointer to the state struct that should be initiated. + * @param state Pointer to the state struct that should be initialized. * @param flags Flags to be set for the parser, see psycParseFlag. */ static inline @@ -187,9 +187,9 @@ void psyc_setParseBuffer2 (psycParseState* state, char *buffer, size_t length) } /** - * Initiates the list state struct. + * Initializes the list state struct. * - * @param state Pointer to the list state struct that should be initiated. + * @param state Pointer to the list state struct that should be initialized. */ static inline void psyc_initParseListState (psycParseListState* state) @@ -241,4 +241,4 @@ psycParseListRC psyc_parseList (psycParseListState* state, psycString *name, psy #endif // PSYC_PARSER_H -/** @} */ // end of parsing group +/** @} */ // end of parser group diff --git a/include/psyc/render.h b/include/psyc/render.h index bf7ebcb..c2d988c 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -12,7 +12,7 @@ */ /** - * @defgroup rendering Rendering Functions + * @defgroup render Rendering Functions * * This module contains all rendering functions. * @{ @@ -40,4 +40,4 @@ psycRenderRC psyc_renderList (psycList *list, char *buffer, size_t buflen); #endif // PSYC_RENDER_H -/** @} */ // end of rendering group +/** @} */ // end of render group diff --git a/include/psyc/text.h b/include/psyc/text.h index a9f25b3..606fc1f 100644 --- a/include/psyc/text.h +++ b/include/psyc/text.h @@ -1,18 +1,41 @@ /** - * The return value definitions for the PSYC text parsing function. - * @see psyc_text() + * @file psyc/text.h + * @brief Interface for text template rendering. + * + * All text template functions and the definitions they use are + * defined in this file. */ +/** + * @defgroup text Text template functions + * + * This module contains all text template functions. + * @{ + */ + +/** + * Return values for the text template parsing function. + * @see psyc_text() + */ typedef enum { + /// No substitution was made, nothing was written to the buffer. PSYC_TEXT_NO_SUBST = -1, + /// Text template parsing & rendering complete. PSYC_TEXT_COMPLETE = 0, + /// Text template parsing & rendering is incomplete, because the buffer was too small. + /// Another call is required to this function with a new buffer. PSYC_TEXT_INCOMPLETE = 1, } psycTextRC; +/** + * Return values for psycTextCB. + */ typedef enum { + /// Value not found, don't substitute anything. PSYC_TEXT_VALUE_NOT_FOUND = -1, + /// Value found, substitute contents of the value variable. PSYC_TEXT_VALUE_FOUND = 0, } psycTextValueRC; @@ -33,13 +56,23 @@ typedef struct * Callback for psyc_text() that produces a value for a match. * * The application looks up a match such as _fruit from [_fruit] and - * if found writes its current value from its variable store into the - * outgoing buffer.. "Apple" for example. The template returns the - * number of bytes written. 0 is a legal return value. Should the - * callback return -1, psyc_text leaves the original template text as is. + * if found sets value->ptr & value->length to point to the found value, + * "Apple" for example. 0 is a legal value for the length. + * The callbacks returns either PSYC_TEXT_VALUE_FOUND or + * PSYC_TEXT_VALUE_NOT_FOUND if no match found in which case psyc_text + * leaves the original template text as is. */ typedef psycTextValueRC (*psycTextCB)(const char *name, size_t len, psycString *value); +/** + * Initializes the PSYC text state struct. + * + * @param state Pointer to the PSYC text state struct that should be initialized. + * @param template Text template to be parsed. + * @param tlen Length of template. + * @param buffer Buffer where the rendered text is going to be written. + * @param blen Length of buffer. + */ static inline void psyc_initTextState (psycTextState *state, char *template, size_t tlen, @@ -52,6 +85,19 @@ void psyc_initTextState (psycTextState *state, state->close = psyc_newString("]", 1); } +/** + * Initializes the PSYC text state struct with custom open & closing braces. + * + * @param state Pointer to the PSYC text state struct that should be initialized. + * @param template Text template to be parsed. + * @param tlen Length of template. + * @param buffer Buffer where the rendered text is going to be written. + * @param blen Length of buffer. + * @param open Opening brace. + * @param openlen Length of opening brace. + * @param close Closing brace. + * @param closelen Length of closing brace. + */ static inline void psyc_initTextState2 (psycTextState* state, char *template, size_t tlen, @@ -65,6 +111,9 @@ void psyc_initTextState2 (psycTextState* state, state->close = psyc_newString(close, closelen); } +/** + * Sets a new buffer in the PSYC text state struct. + */ static inline void psyc_setTextBuffer (psycTextState* state, psycString buffer) { @@ -72,6 +121,9 @@ void psyc_setTextBuffer (psycTextState* state, psycString buffer) state->written = 0; } +/** + * Sets a new buffer in the PSYC text state struct. + */ static inline void psyc_setTextBuffer2 (psycTextState* state, char *buffer, size_t length) @@ -82,15 +134,18 @@ void psyc_setTextBuffer2 (psycTextState* state, /** * Fills out text templates by asking a callback for content. * - * Copies the contents of the template into the buffer while looking - * for braceOpen and braceClose strings and calling the callback for - * each enclosed string between these braces. Should the callback - * return -1, the original template text is copied as is. + * Copies the contents of the template into the buffer while looking for the + * opening and closing brace strings and calling the callback for each enclosed + * string between these braces. Should the callback return + * PSYC_TEXT_VALUE_NOT_FOUND, the original template text is copied as is. * - * By default PSYC's "[" and "]" are used but you can provide any other - * brace strings such as "${" and "}" or "". + * Before calling this function psyc_initTextState or psyc_initTextState should + * be called to initialze the state struct. By default PSYC's "[" and "]" are + * used but you can provide any other brace strings such as "${" and "}" or + * "". * - * See also http://about.psyc.eu/psyctext - */ - + * @see http://about.psyc.eu/psyctext + **/ psycTextRC psyc_text (psycTextState *state, psycTextCB getValue); + +/** @} */ // end of text group From 95ef2fd538df2e1be02aea7abd30406788d585e1 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 4 May 2011 01:54:27 +0200 Subject: [PATCH 156/378] parser, text: added functions for accessing state variables --- test/testServer.c | 8 ++++---- test/testText.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/testServer.c b/test/testServer.c index 9003cf2..adcd2b7 100644 --- a/test/testServer.c +++ b/test/testServer.c @@ -233,7 +233,7 @@ int main (int argc, char **argv) if (ret == PSYC_PARSE_ENTITY) { packets[i].entity.lines++; - mod->flag = parsers[i].valueLength ? + mod->flag = psyc_getParseValueLength(&parsers[i]) ? PSYC_MODIFIER_NEED_LENGTH : PSYC_MODIFIER_NO_LENGTH; } break; @@ -246,7 +246,7 @@ int main (int argc, char **argv) case PSYC_PARSE_COMPLETE: printf("# Done parsing.\n"); - packets[i].flag = parsers[i].contentLengthFound ? + packets[i].flag = psyc_isParseContentLengthFound(&parsers[i]) ? PSYC_PACKET_NEED_LENGTH : PSYC_PACKET_NO_LENGTH; psyc_setPacketLength(&packets[i]); @@ -261,12 +261,12 @@ int main (int argc, char **argv) if (verbose) printf("# Insufficient data.\n"); - contbytes = parsers[i].buffer.length - parsers[i].cursor; + contbytes = psyc_getParseRemainingLength(&parsers[i]); if (contbytes > 0) // copy end of parsebuf before start of recvbuf { assert(recvbuf - contbytes >= buf); // make sure it's still in the buffer - memcpy(recvbuf - contbytes, parsebuf + parsers[i].cursor, contbytes); + memcpy(recvbuf - contbytes, psyc_getParseRemainingBuffer(&parsers[i]), contbytes); } ret = 0; break; diff --git a/test/testText.c b/test/testText.c index 6ea51f7..9fd3c1f 100644 --- a/test/testText.c +++ b/test/testText.c @@ -36,7 +36,7 @@ int testText (char *template, size_t tmplen, char *buffer, size_t buflen, psycSt do { ret = psyc_text(&state, getValue); - length += state.written; + length += psyc_getTextBytesWritten(&state); switch (ret) { case PSYC_TEXT_INCOMPLETE: From b294afd0a45a9bf518fcfeb3fa0573dd5dfd4149 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 4 May 2011 04:01:21 +0200 Subject: [PATCH 157/378] parser, text: added functions for accessing state variables - headers --- include/psyc/parser.h | 60 +++++++++++++++++++++++++++++++++++-------- include/psyc/text.h | 12 ++++++--- 2 files changed, 58 insertions(+), 14 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index dc6c378..85f7de5 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -131,7 +131,7 @@ typedef struct * @param state Pointer to the state struct that should be initialized. */ static inline -void psyc_initParseState (psycParseState* state) +void psyc_initParseState (psycParseState *state) { memset(state, 0, sizeof(psycParseState)); } @@ -143,7 +143,7 @@ void psyc_initParseState (psycParseState* state) * @param flags Flags to be set for the parser, see psycParseFlag. */ static inline -void psyc_initParseState2 (psycParseState* state, uint8_t flags) +void psyc_initParseState2 (psycParseState *state, uint8_t flags) { memset(state, 0, sizeof(psycParseState)); state->flags = flags; @@ -160,7 +160,7 @@ void psyc_initParseState2 (psycParseState* state, uint8_t flags) * @see psycString */ static inline -void psyc_setParseBuffer (psycParseState* state, psycString buffer) +void psyc_setParseBuffer (psycParseState *state, psycString buffer) { state->buffer = buffer; state->cursor = 0; @@ -181,7 +181,7 @@ void psyc_setParseBuffer (psycParseState* state, psycString buffer) * @see psycString */ static inline -void psyc_setParseBuffer2 (psycParseState* state, char *buffer, size_t length) +void psyc_setParseBuffer2 (psycParseState *state, char *buffer, size_t length) { psyc_setParseBuffer(state, psyc_newString(buffer, length)); } @@ -192,7 +192,7 @@ void psyc_setParseBuffer2 (psycParseState* state, char *buffer, size_t length) * @param state Pointer to the list state struct that should be initialized. */ static inline -void psyc_initParseListState (psycParseListState* state) +void psyc_initParseListState (psycParseListState *state) { memset(state, 0, sizeof(psycParseListState)); } @@ -201,22 +201,58 @@ void psyc_initParseListState (psycParseListState* state) * Sets a new buffer in the list parser state struct with data to be parsed. */ static inline -void psyc_setParseListBuffer (psycParseListState* state, psycString buffer) +void psyc_setParseListBuffer (psycParseListState *state, psycString buffer) { state->buffer = buffer; state->cursor = 0; } static inline -void psyc_setParseListBuffer2 (psycParseListState* state, char *buffer, size_t length) +void psyc_setParseListBuffer2 (psycParseListState *state, char *buffer, size_t length) { psyc_setParseListBuffer(state, psyc_newString(buffer, length)); } static inline -size_t psyc_getContentLength (psycParseState* s) +size_t psyc_getParseContentLength (psycParseState *state) { - return s->contentLength; + return state->contentLength; +} + +static inline +psycBool psyc_isParseContentLengthFound (psycParseState *state) +{ + return state->contentLengthFound; +} + +static inline +size_t psyc_getParseValueLength (psycParseState *state) +{ + return state->valueLength; +} + +static inline +size_t psyc_getParseCursor (psycParseState *state) +{ + return state->cursor; +} + +static inline +size_t psyc_getParseBufferLength (psycParseState *state) +{ + return state->buffer.length; +} + +static inline +size_t psyc_getParseRemainingLength (psycParseState *state) +{ + return state->buffer.length - state->cursor; +} + +static inline +const char * psyc_getParseRemainingBuffer (psycParseState *state) +{ + return state->buffer.ptr + state->cursor; } /** @@ -232,12 +268,14 @@ size_t psyc_getContentLength (psycParseState* s) * @param value A pointer to a psycString. It will point to the * value/body the variable/method and its length will be set accordingly */ -psycParseRC psyc_parse (psycParseState* state, char* oper, psycString* name, psycString* value); +psycParseRC psyc_parse (psycParseState *state, char *oper, + psycString *name, psycString *value); /** * List value parser. */ -psycParseListRC psyc_parseList (psycParseListState* state, psycString *name, psycString* value, psycString* elem); +psycParseListRC psyc_parseList (psycParseListState *state, psycString *name, + psycString *value, psycString *elem); #endif // PSYC_PARSER_H diff --git a/include/psyc/text.h b/include/psyc/text.h index 606fc1f..8f3b1f0 100644 --- a/include/psyc/text.h +++ b/include/psyc/text.h @@ -99,7 +99,7 @@ void psyc_initTextState (psycTextState *state, * @param closelen Length of closing brace. */ static inline -void psyc_initTextState2 (psycTextState* state, +void psyc_initTextState2 (psycTextState *state, char *template, size_t tlen, char *buffer, size_t blen, char *open, size_t openlen, @@ -115,7 +115,7 @@ void psyc_initTextState2 (psycTextState* state, * Sets a new buffer in the PSYC text state struct. */ static inline -void psyc_setTextBuffer (psycTextState* state, psycString buffer) +void psyc_setTextBuffer (psycTextState *state, psycString buffer) { state->buffer = buffer; state->written = 0; @@ -125,12 +125,18 @@ void psyc_setTextBuffer (psycTextState* state, psycString buffer) * Sets a new buffer in the PSYC text state struct. */ static inline -void psyc_setTextBuffer2 (psycTextState* state, +void psyc_setTextBuffer2 (psycTextState *state, char *buffer, size_t length) { psyc_setTextBuffer(state, psyc_newString(buffer, length)); } +static inline +size_t psyc_getTextBytesWritten (psycTextState *state) +{ + return state->written; +} + /** * Fills out text templates by asking a callback for content. * From a11c632e3d6db17fb9bd14815f816f690358c348 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 4 May 2011 15:40:05 +0200 Subject: [PATCH 158/378] parser: fix for binary body length --- src/parser.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/parser.c b/src/parser.c index 6778090..7fd694f 100644 --- a/src/parser.c +++ b/src/parser.c @@ -381,9 +381,12 @@ psycParseRC psyc_parse (psycParseState* state, char* oper, { if (state->contentParsed < state->contentLength && psyc_parseBinaryValue(state, value, &(state->contentLength), - &(state->contentParsed)) == PSYC_PARSE_INCOMPLETE) + &(state->contentParsed)) == PSYC_PARSE_INCOMPLETE) return PSYC_PARSE_BODY_INCOMPLETE; + if (value->length) + value->length--; // \n at the end is not part of the body + if (state->cursor >= state->buffer.length) return PSYC_PARSE_BODY; From 4394aa5e0c896939320bf4b7cabdc55cc380962f Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 4 May 2011 15:41:35 +0200 Subject: [PATCH 159/378] render: added error codes for missing method & modifier name; fixes for test tools --- include/psyc/render.h | 3 ++- src/render.c | 26 ++++++++++++++++++-------- test/Makefile | 3 ++- test/testParser.c | 8 ++++++-- test/testServer.c | 20 ++++++++++++++------ 5 files changed, 42 insertions(+), 18 deletions(-) diff --git a/include/psyc/render.h b/include/psyc/render.h index c2d988c..6b837da 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -23,7 +23,8 @@ */ typedef enum { - //PSYC_RENDER_ERROR_ROUTING = -2, + PSYC_RENDER_ERROR_METHOD_MISSING = -3, ///< method missing, but data present + PSYC_RENDER_ERROR_MODIFIER_NAME_MISSING = -2, ///< modifier name missing PSYC_RENDER_ERROR = -1, PSYC_RENDER_SUCCESS = 0, } psycRenderRC; diff --git a/src/render.c b/src/render.c index 6935f8f..a5848c0 100644 --- a/src/render.c +++ b/src/render.c @@ -45,6 +45,9 @@ size_t psyc_renderModifier (psycModifier *mod, char *buffer) buffer[cur++] = mod->oper; memcpy(buffer + cur, mod->name.ptr, mod->name.length); cur += mod->name.length; + if (cur <= 1) + return cur; // error, name can't be empty + if (mod->flag == PSYC_MODIFIER_NEED_LENGTH) { buffer[cur++] = ' '; @@ -61,14 +64,19 @@ size_t psyc_renderModifier (psycModifier *mod, char *buffer) psycRenderRC psyc_render (psycPacket *packet, char *buffer, size_t buflen) { - size_t i, cur = 0; + size_t i, cur = 0, len; if (packet->length > buflen) return PSYC_RENDER_ERROR; // return error if packet doesn't fit in buffer // render routing modifiers for (i = 0; i < packet->routing.lines; i++) - cur += psyc_renderModifier(&packet->routing.modifiers[i], buffer + cur); + { + len = psyc_renderModifier(&packet->routing.modifiers[i], buffer + cur); + cur += len; + if (len <= 1) + return PSYC_RENDER_ERROR_MODIFIER_NAME_MISSING; + } // add length if needed if (packet->flag == PSYC_PACKET_NEED_LENGTH) @@ -86,14 +94,16 @@ psycRenderRC psyc_render (psycPacket *packet, char *buffer, size_t buflen) memcpy(buffer + cur, packet->method.ptr, packet->method.length); cur += packet->method.length; buffer[cur++] = '\n'; - } + if (packet->data.length) // add data\n + { + memcpy(buffer + cur, packet->data.ptr, packet->data.length); + cur += packet->data.length; - if (packet->data.length) // add data\n - { - memcpy(buffer + cur, packet->data.ptr, packet->data.length); - cur += packet->data.length; - buffer[cur++] = '\n'; + buffer[cur++] = '\n'; + } } + else if (packet->data.length) // error, we have data but no modifier + return PSYC_RENDER_ERROR_METHOD_MISSING; // add packet delimiter buffer[cur++] = C_GLYPH_PACKET_DELIMITER; diff --git a/test/Makefile b/test/Makefile index 4b73eb7..5560569 100644 --- a/test/Makefile +++ b/test/Makefile @@ -24,6 +24,7 @@ test: ${TARGETS} ./isRoutingVar ./getVarType for f in packets/full-*; do echo ">> $$f"; ./testParser $$f; done + for f in packets/full-*; do echo ">> $$f"; ./testParser $$f -r; done testServer: CFLAGS := $(subst -std=c99,,${CFLAGS}) @@ -37,7 +38,7 @@ netstartv: ./testServer ${PORT} -v netstartrv: - ./testServer ${PORT} -r -v + ./testServer ${PORT} -rv nettest: for f in packets/full-*; do echo ">> $$f"; cat $$f | nc localhost ${PORT} | diff -u $$f -; done diff --git a/test/testParser.c b/test/testParser.c index 2f203f7..38a1d46 100644 --- a/test/testParser.c +++ b/test/testParser.c @@ -7,12 +7,16 @@ int main (int argc, char **argv) { - int idx, ret, routing_only = argc > 2, verbose = argc > 3; + uint8_t routing_only = argc > 2 && memchr(argv[2], (int)'r', strlen(argv[2])); + uint8_t verbose = argc > 2 && memchr(argv[2], (int)'v', strlen(argv[2])); + int idx, ret; char buffer[2048], oper; psycString name, value, elem; psycParseState state; psycParseListState listState; + if (argc < 2) + return -1; int file = open(argv[1],O_RDONLY); if (file < 0) return -1; @@ -55,7 +59,7 @@ int main (int argc, char **argv) (int)name.length, name.ptr, (int)value.length, value.ptr); - if (memcmp(name.ptr, "_list", 5) == 0) + if (name.length >= 5 && memcmp(name.ptr, "_list", 5) == 0) { if (verbose) printf(">> LIST START\n"); diff --git a/test/testServer.c b/test/testServer.c index adcd2b7..e7aeccc 100644 --- a/test/testServer.c +++ b/test/testServer.c @@ -42,7 +42,8 @@ void *get_in_addr (struct sockaddr *sa) int main (int argc, char **argv) { char *port = argc > 1 ? argv[1] : "4440"; - uint8_t routing_only = argc > 2, verbose = argc > 3; + uint8_t routing_only = argc > 2 && memchr(argv[2], (int)'r', strlen(argv[2])); + uint8_t verbose = argc > 2 && memchr(argv[2], (int)'v', strlen(argv[2])); fd_set master; // master file descriptor list fd_set read_fds; // temp file descriptor list for select() @@ -249,11 +250,18 @@ int main (int argc, char **argv) packets[i].flag = psyc_isParseContentLengthFound(&parsers[i]) ? PSYC_PACKET_NEED_LENGTH : PSYC_PACKET_NO_LENGTH; - psyc_setPacketLength(&packets[i]); - psyc_render(&packets[i], sendbuf, SEND_BUF_SIZE); + if (routing_only) + packets[i].method = psyc_newString(PSYC_C2ARG("_packet_content")); - if (send(i, sendbuf, packets[i].length, 0) == -1) - perror("send"); + psyc_setPacketLength(&packets[i]); + + if (psyc_render(&packets[i], sendbuf, SEND_BUF_SIZE) == PSYC_RENDER_SUCCESS) + { + if (send(i, sendbuf, packets[i].length, 0) == -1) + perror("send error"); + } + else + perror("render error"); ret = -1; break; @@ -314,7 +322,7 @@ int main (int argc, char **argv) if (verbose) { - printf("%.*s", (int)pvalue->length, pvalue->ptr); + printf("[%.*s]", (int)pvalue->length, pvalue->ptr); if (parsers[i].valueLength > pvalue->length) printf("..."); printf("\n"); From c0a6ba753075b9a5ef187caeca09f8bd2890470c Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 4 May 2011 17:44:12 +0200 Subject: [PATCH 160/378] packets: rename, new packets --- test/Makefile | 16 +++++----------- test/packets/00-length-no-content | 4 ++++ test/packets/00-length-no-data | 5 +++++ test/packets/00-method-only | 3 +++ test/packets/00-no-content | 3 +++ test/packets/00-no-data | 5 +++++ test/packets/00-no-entity | 6 ++++++ test/packets/00-no-routing | 4 ++++ test/packets/{full-1 => 01} | 0 test/packets/{full-1-length => 01-length} | 0 test/packets/{full-1-utf8 => 01-utf8} | 0 test/packets/{full-2-list => 02-list} | 0 test/packets/{full-3-list => 03-list} | 0 test/packets/{full-4-circuit => 04-circuit} | 0 ...full-5-message-private => 05-message-private} | 0 ...-private-remote => 06-message-private-remote} | 0 test/packets/{full-7-dns-fake => 07-dns-fake} | 0 .../{full-7-dns-invalid => 07-dns-invalid} | 0 .../{full-8-context-enter => 08-context-enter} | 0 .../{full-8-context-leave => 08-context-leave} | 0 test/packets/{error-1-length => err-01-length} | 0 test/packets/{error-2-list => err-02-list} | 0 test/packets/full-0-no-content | 3 --- test/packets/part-1-length-p1 | 1 - test/packets/part-1-length-p2 | 1 - test/packets/part-1-length-p3 | 3 --- test/packets/part-1-length-p4 | 1 - test/packets/part-1-length-p5 | 1 - test/packets/part-1-length-p6 | 1 - test/packets/part-1-length-p7 | 1 - test/packets/part-1-length-p8 | 1 - test/packets/part-1-length-p9 | 1 - test/packets/part-1-p1 | 2 -- test/packets/part-1-p2 | 2 -- test/packets/part-1-p3 | 3 --- test/packets/part-1-p4 | 2 -- test/packets/part-1-p5 | 1 - test/packets/part-1-p6 | 4 ---- test/packets/part-1-p7 | 2 -- test/packets/part-1-p8 | 2 -- test/packets/part-1-p9 | 1 - 41 files changed, 35 insertions(+), 44 deletions(-) create mode 100644 test/packets/00-length-no-content create mode 100644 test/packets/00-length-no-data create mode 100644 test/packets/00-method-only create mode 100644 test/packets/00-no-content create mode 100644 test/packets/00-no-data create mode 100644 test/packets/00-no-entity create mode 100644 test/packets/00-no-routing rename test/packets/{full-1 => 01} (100%) rename test/packets/{full-1-length => 01-length} (100%) rename test/packets/{full-1-utf8 => 01-utf8} (100%) rename test/packets/{full-2-list => 02-list} (100%) rename test/packets/{full-3-list => 03-list} (100%) rename test/packets/{full-4-circuit => 04-circuit} (100%) rename test/packets/{full-5-message-private => 05-message-private} (100%) rename test/packets/{full-6-message-private-remote => 06-message-private-remote} (100%) rename test/packets/{full-7-dns-fake => 07-dns-fake} (100%) rename test/packets/{full-7-dns-invalid => 07-dns-invalid} (100%) rename test/packets/{full-8-context-enter => 08-context-enter} (100%) rename test/packets/{full-8-context-leave => 08-context-leave} (100%) rename test/packets/{error-1-length => err-01-length} (100%) rename test/packets/{error-2-list => err-02-list} (100%) delete mode 100644 test/packets/full-0-no-content delete mode 120000 test/packets/part-1-length-p1 delete mode 120000 test/packets/part-1-length-p2 delete mode 100644 test/packets/part-1-length-p3 delete mode 120000 test/packets/part-1-length-p4 delete mode 120000 test/packets/part-1-length-p5 delete mode 120000 test/packets/part-1-length-p6 delete mode 120000 test/packets/part-1-length-p7 delete mode 120000 test/packets/part-1-length-p8 delete mode 120000 test/packets/part-1-length-p9 delete mode 100644 test/packets/part-1-p1 delete mode 100644 test/packets/part-1-p2 delete mode 100644 test/packets/part-1-p3 delete mode 100644 test/packets/part-1-p4 delete mode 100644 test/packets/part-1-p5 delete mode 100644 test/packets/part-1-p6 delete mode 100644 test/packets/part-1-p7 delete mode 100644 test/packets/part-1-p8 delete mode 100644 test/packets/part-1-p9 diff --git a/test/Makefile b/test/Makefile index 5560569..8a7837d 100644 --- a/test/Makefile +++ b/test/Makefile @@ -23,8 +23,8 @@ test: ${TARGETS} ./testText ./isRoutingVar ./getVarType - for f in packets/full-*; do echo ">> $$f"; ./testParser $$f; done - for f in packets/full-*; do echo ">> $$f"; ./testParser $$f -r; done + for f in packets/[0-9]*; do echo ">> $$f"; ./testParser $$f; done + for f in packets/[0-9]*; do echo ">> $$f"; ./testParser $$f -r; done testServer: CFLAGS := $(subst -std=c99,,${CFLAGS}) @@ -41,19 +41,13 @@ netstartrv: ./testServer ${PORT} -rv nettest: - for f in packets/full-*; do echo ">> $$f"; cat $$f | nc localhost ${PORT} | diff -u $$f -; done + for f in packets/[0-9]*; do echo ">> $$f"; cat $$f | nc localhost ${PORT} | diff -u $$f -; done nettesterr: - for f in packets/error-*; do echo ">> $$f"; cat $$f | nc localhost ${PORT}; done + for f in packets/err-*; do echo ">> $$f"; cat $$f | nc localhost ${PORT}; done splittest: - for f in packets/full-*; do echo ">> $$f"; ./splittest.pl $$f ${PORT} | diff -u $$f -; done - -nettestp1: - (for f in packets/part-1-p*; do cat $$f; done) | nc localhost ${PORT} | diff -u packets/full-1 - - -nettestp2: - (for f in packets/part-1-length-p*; do cat $$f; done) | nc localhost ${PORT} | diff -u packets/full-1-length - + for f in packets/[0-9]*; do echo ">> $$f"; ./splittest.pl $$f ${PORT} | diff -u $$f -; done clean: rm -f ${TARGETS} diff --git a/test/packets/00-length-no-content b/test/packets/00-length-no-content new file mode 100644 index 0000000..0954c09 --- /dev/null +++ b/test/packets/00-length-no-content @@ -0,0 +1,4 @@ +:_source psyc://foo.example.com/ +:_target psyc://bar.example.com/ +0 +| diff --git a/test/packets/00-length-no-data b/test/packets/00-length-no-data new file mode 100644 index 0000000..5ee71c1 --- /dev/null +++ b/test/packets/00-length-no-data @@ -0,0 +1,5 @@ +:_source psyc://foo.example.com/ +:_target psyc://bar.example.com/ +16 +_notice_foo_bar +| diff --git a/test/packets/00-method-only b/test/packets/00-method-only new file mode 100644 index 0000000..0f903d4 --- /dev/null +++ b/test/packets/00-method-only @@ -0,0 +1,3 @@ + +_notice_foo_bar +| diff --git a/test/packets/00-no-content b/test/packets/00-no-content new file mode 100644 index 0000000..0efa599 --- /dev/null +++ b/test/packets/00-no-content @@ -0,0 +1,3 @@ +:_source psyc://foo.example.com/ +:_target psyc://bar.example.com/ +| diff --git a/test/packets/00-no-data b/test/packets/00-no-data new file mode 100644 index 0000000..88265ca --- /dev/null +++ b/test/packets/00-no-data @@ -0,0 +1,5 @@ +:_source psyc://foo.example.com/ +:_target psyc://bar.example.com/ + +_notice_foo_bar +| diff --git a/test/packets/00-no-entity b/test/packets/00-no-entity new file mode 100644 index 0000000..48ce4e9 --- /dev/null +++ b/test/packets/00-no-entity @@ -0,0 +1,6 @@ +:_source psyc://foo.example.com/ +:_target psyc://bar.example.com/ + +_message_private +OHAI +| diff --git a/test/packets/00-no-routing b/test/packets/00-no-routing new file mode 100644 index 0000000..85c66e5 --- /dev/null +++ b/test/packets/00-no-routing @@ -0,0 +1,4 @@ + +:_foo bar +_notice_foo_bar +| diff --git a/test/packets/full-1 b/test/packets/01 similarity index 100% rename from test/packets/full-1 rename to test/packets/01 diff --git a/test/packets/full-1-length b/test/packets/01-length similarity index 100% rename from test/packets/full-1-length rename to test/packets/01-length diff --git a/test/packets/full-1-utf8 b/test/packets/01-utf8 similarity index 100% rename from test/packets/full-1-utf8 rename to test/packets/01-utf8 diff --git a/test/packets/full-2-list b/test/packets/02-list similarity index 100% rename from test/packets/full-2-list rename to test/packets/02-list diff --git a/test/packets/full-3-list b/test/packets/03-list similarity index 100% rename from test/packets/full-3-list rename to test/packets/03-list diff --git a/test/packets/full-4-circuit b/test/packets/04-circuit similarity index 100% rename from test/packets/full-4-circuit rename to test/packets/04-circuit diff --git a/test/packets/full-5-message-private b/test/packets/05-message-private similarity index 100% rename from test/packets/full-5-message-private rename to test/packets/05-message-private diff --git a/test/packets/full-6-message-private-remote b/test/packets/06-message-private-remote similarity index 100% rename from test/packets/full-6-message-private-remote rename to test/packets/06-message-private-remote diff --git a/test/packets/full-7-dns-fake b/test/packets/07-dns-fake similarity index 100% rename from test/packets/full-7-dns-fake rename to test/packets/07-dns-fake diff --git a/test/packets/full-7-dns-invalid b/test/packets/07-dns-invalid similarity index 100% rename from test/packets/full-7-dns-invalid rename to test/packets/07-dns-invalid diff --git a/test/packets/full-8-context-enter b/test/packets/08-context-enter similarity index 100% rename from test/packets/full-8-context-enter rename to test/packets/08-context-enter diff --git a/test/packets/full-8-context-leave b/test/packets/08-context-leave similarity index 100% rename from test/packets/full-8-context-leave rename to test/packets/08-context-leave diff --git a/test/packets/error-1-length b/test/packets/err-01-length similarity index 100% rename from test/packets/error-1-length rename to test/packets/err-01-length diff --git a/test/packets/error-2-list b/test/packets/err-02-list similarity index 100% rename from test/packets/error-2-list rename to test/packets/err-02-list diff --git a/test/packets/full-0-no-content b/test/packets/full-0-no-content deleted file mode 100644 index f17f81f..0000000 --- a/test/packets/full-0-no-content +++ /dev/null @@ -1,3 +0,0 @@ -:_source psyc://nb.tgbit.net/ -:_target psyc://nb.tgbit.net/ -| diff --git a/test/packets/part-1-length-p1 b/test/packets/part-1-length-p1 deleted file mode 120000 index b934188..0000000 --- a/test/packets/part-1-length-p1 +++ /dev/null @@ -1 +0,0 @@ -part-1-p1 \ No newline at end of file diff --git a/test/packets/part-1-length-p2 b/test/packets/part-1-length-p2 deleted file mode 120000 index e3f9bb4..0000000 --- a/test/packets/part-1-length-p2 +++ /dev/null @@ -1 +0,0 @@ -part-1-p2 \ No newline at end of file diff --git a/test/packets/part-1-length-p3 b/test/packets/part-1-length-p3 deleted file mode 100644 index ed36f14..0000000 --- a/test/packets/part-1-length-p3 +++ /dev/null @@ -1,3 +0,0 @@ -hu3r2cm -85 -:_foo bar baz \ No newline at end of file diff --git a/test/packets/part-1-length-p4 b/test/packets/part-1-length-p4 deleted file mode 120000 index 75d3aaf..0000000 --- a/test/packets/part-1-length-p4 +++ /dev/null @@ -1 +0,0 @@ -part-1-p4 \ No newline at end of file diff --git a/test/packets/part-1-length-p5 b/test/packets/part-1-length-p5 deleted file mode 120000 index 854fc1b..0000000 --- a/test/packets/part-1-length-p5 +++ /dev/null @@ -1 +0,0 @@ -part-1-p5 \ No newline at end of file diff --git a/test/packets/part-1-length-p6 b/test/packets/part-1-length-p6 deleted file mode 120000 index 3fc7513..0000000 --- a/test/packets/part-1-length-p6 +++ /dev/null @@ -1 +0,0 @@ -part-1-p6 \ No newline at end of file diff --git a/test/packets/part-1-length-p7 b/test/packets/part-1-length-p7 deleted file mode 120000 index c4fd783..0000000 --- a/test/packets/part-1-length-p7 +++ /dev/null @@ -1 +0,0 @@ -part-1-p7 \ No newline at end of file diff --git a/test/packets/part-1-length-p8 b/test/packets/part-1-length-p8 deleted file mode 120000 index 46db87b..0000000 --- a/test/packets/part-1-length-p8 +++ /dev/null @@ -1 +0,0 @@ -part-1-p8 \ No newline at end of file diff --git a/test/packets/part-1-length-p9 b/test/packets/part-1-length-p9 deleted file mode 120000 index d933075..0000000 --- a/test/packets/part-1-length-p9 +++ /dev/null @@ -1 +0,0 @@ -part-1-p9 \ No newline at end of file diff --git a/test/packets/part-1-p1 b/test/packets/part-1-p1 deleted file mode 100644 index 5a4579e..0000000 --- a/test/packets/part-1-p1 +++ /dev/null @@ -1,2 +0,0 @@ -:_source psyc://foo/~bar -:_tar \ No newline at end of file diff --git a/test/packets/part-1-p2 b/test/packets/part-1-p2 deleted file mode 100644 index 82affb8..0000000 --- a/test/packets/part-1-p2 +++ /dev/null @@ -1,2 +0,0 @@ -get psyc://bar/~baz -:_tag sch1828 \ No newline at end of file diff --git a/test/packets/part-1-p3 b/test/packets/part-1-p3 deleted file mode 100644 index 126300c..0000000 --- a/test/packets/part-1-p3 +++ /dev/null @@ -1,3 +0,0 @@ -hu3r2cm - -:_foo bar baz \ No newline at end of file diff --git a/test/packets/part-1-p4 b/test/packets/part-1-p4 deleted file mode 100644 index 3cd7e42..0000000 --- a/test/packets/part-1-p4 +++ /dev/null @@ -1,2 +0,0 @@ - -:_abc_def 1 \ No newline at end of file diff --git a/test/packets/part-1-p5 b/test/packets/part-1-p5 deleted file mode 100644 index cb3b80c..0000000 --- a/test/packets/part-1-p5 +++ /dev/null @@ -1 +0,0 @@ -1 foo \ No newline at end of file diff --git a/test/packets/part-1-p6 b/test/packets/part-1-p6 deleted file mode 100644 index 0acc380..0000000 --- a/test/packets/part-1-p6 +++ /dev/null @@ -1,4 +0,0 @@ - bar -baz -:_foo_bar yay -_message \ No newline at end of file diff --git a/test/packets/part-1-p7 b/test/packets/part-1-p7 deleted file mode 100644 index a8dfc27..0000000 --- a/test/packets/part-1-p7 +++ /dev/null @@ -1,2 +0,0 @@ -_foo_bar -ohai \ No newline at end of file diff --git a/test/packets/part-1-p8 b/test/packets/part-1-p8 deleted file mode 100644 index 1651eb0..0000000 --- a/test/packets/part-1-p8 +++ /dev/null @@ -1,2 +0,0 @@ - there! -\o/ diff --git a/test/packets/part-1-p9 b/test/packets/part-1-p9 deleted file mode 100644 index 948cf94..0000000 --- a/test/packets/part-1-p9 +++ /dev/null @@ -1 +0,0 @@ -| From 29a72caf6f9fc23a46d92ac8fc9978f87c3aa6f2 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 4 May 2011 17:46:20 +0200 Subject: [PATCH 161/378] fix for 0 length content/modifiers --- src/packet.c | 21 +++++++++++++-------- src/parser.c | 29 ++++++++++++++--------------- src/render.c | 7 ++++--- test/testText.c | 6 ++++++ 4 files changed, 37 insertions(+), 26 deletions(-) diff --git a/src/packet.c b/src/packet.c index c30d9fd..1b84dcc 100644 --- a/src/packet.c +++ b/src/packet.c @@ -4,6 +4,12 @@ #include +static inline +size_t psyc_getNumLength(size_t n) +{ + return n < 10 ? 1 : log10(n) + 1; +} + inline psycListFlag psyc_checkListLength (psycList *list) { @@ -37,7 +43,7 @@ psycListFlag psyc_getListLength (psycList *list) { if (i > 0) length++; // | - length += log10((double)list->elems[i].length) + 2 + list->elems[i].length; // length SP elem + length += psyc_getNumLength(list->elems[i].length) + 1 + list->elems[i].length; // length SP elem } } else @@ -69,8 +75,8 @@ size_t psyc_getModifierLength (psycModifier *m) m->name.length + 1 + // name\t m->value.length + 1; // value\n - if (m->flag == PSYC_MODIFIER_NEED_LENGTH) // add length of length if needed - length += log10((double)m->value.length) + 2; // SP length + if (m->flag == PSYC_MODIFIER_NEED_LENGTH && m->value.length) // add length of length if needed + length += psyc_getNumLength(m->value.length) + 1; // SP length return length; } @@ -121,12 +127,11 @@ size_t psyc_setPacketLength(psycPacket *p) // set total length: routing-header content |\n p->length = p->routingLength + p->contentLength + 2; - if (p->contentLength > 0) - { + if (p->contentLength > 0 || p->flag == PSYC_PACKET_NEED_LENGTH) p->length++; // add \n at the start of the content part - if (p->flag == PSYC_PACKET_NEED_LENGTH) // add length of length if needed - p->length += log10((double)p->contentLength) + 1; - } + + if (p->flag == PSYC_PACKET_NEED_LENGTH) // add length of length if needed + p->length += psyc_getNumLength(p->contentLength); return p->length; } diff --git a/src/parser.c b/src/parser.c index 7fd694f..2316b40 100644 --- a/src/parser.c +++ b/src/parser.c @@ -8,14 +8,13 @@ #include #include -#define PSYC_ADVANCE_CURSOR_OR_RETURN(ret) \ +#define ADVANCE_CURSOR_OR_RETURN(ret) \ if (++(state->cursor) >= state->buffer.length) \ { \ state->cursor = state->startc; \ return ret; \ } - /** * Determines if the argument is a glyph. * Glyphs are: : = + - ? ! @@ -82,7 +81,7 @@ psycParseRC psyc_parseKeyword (psycParseState* state, psycString* name) while (isKwChar(state->buffer.ptr[state->cursor])) { name->length++; // was a valid char, increase length - PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } return name->length > 0 ? PSYC_PARSE_SUCCESS : PSYC_PARSE_ERROR; @@ -130,7 +129,7 @@ psycParseRC psyc_parseModifier (psycParseState *state, char *oper, psycString *name, psycString *value) { *oper = *(state->buffer.ptr + state->cursor); - PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); psycParseRC ret = psyc_parseKeyword(state, name); if (ret == PSYC_PARSE_ERROR) @@ -147,14 +146,14 @@ psycParseRC psyc_parseModifier (psycParseState *state, char *oper, // 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. - PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); if (isNumeric(state->buffer.ptr[state->cursor])) { do { length = 10 * length + state->buffer.ptr[state->cursor] - '0'; - PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } while (isNumeric(state->buffer.ptr[state->cursor])); state->valueLength = length; @@ -177,13 +176,13 @@ psycParseRC psyc_parseModifier (psycParseState *state, char *oper, } else if (state->buffer.ptr[state->cursor] == '\t') // simple arg { - PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); value->ptr = state->buffer.ptr + state->cursor; while (state->buffer.ptr[state->cursor] != '\n') { value->length++; - PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } return PSYC_PARSE_SUCCESS; @@ -233,7 +232,7 @@ psycParseRC psyc_parse (psycParseState* state, char* oper, { if (state->buffer.ptr[state->cursor] != '\n') return PSYC_PARSE_ERROR_MOD_NL; - PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } // Each line of the header starts with a glyph, @@ -262,7 +261,7 @@ psycParseRC psyc_parse (psycParseState* state, char* oper, do { state->contentLength = 10 * state->contentLength + state->buffer.ptr[state->cursor] - '0'; - PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } while (isNumeric(state->buffer.ptr[state->cursor])); } @@ -292,7 +291,7 @@ psycParseRC psyc_parse (psycParseState* state, char* oper, } state->startc = state->cursor + 1; - PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); // fall thru case PSYC_PART_CONTENT: @@ -314,7 +313,7 @@ psycParseRC psyc_parse (psycParseState* state, char* oper, { if (state->buffer.ptr[state->cursor] != '\n') return PSYC_PARSE_ERROR_MOD_NL; - PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } // Each line of the header starts with a glyph, @@ -361,7 +360,7 @@ psycParseRC psyc_parse (psycParseState* state, char* oper, state->part = PSYC_PART_DATA; } else // otherwise keep it at the beginning of method - PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); // fall thru } @@ -421,7 +420,7 @@ psycParseRC psyc_parse (psycParseState* state, char* oper, } } value->length++; - PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } } @@ -505,7 +504,7 @@ psycParseListRC psyc_parseList (psycParseListState* state, psycString *name, do { state->elemLength = 10 * state->elemLength + state->buffer.ptr[state->cursor] - '0'; - PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_LIST_INCOMPLETE); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_LIST_INCOMPLETE); } while (isNumeric(state->buffer.ptr[state->cursor])); } diff --git a/src/render.c b/src/render.c index a5848c0..74ba859 100644 --- a/src/render.c +++ b/src/render.c @@ -82,8 +82,9 @@ psycRenderRC psyc_render (psycPacket *packet, char *buffer, size_t buflen) if (packet->flag == PSYC_PACKET_NEED_LENGTH) cur += itoa(packet->contentLength, buffer + cur, 10); - if (packet->entity.lines || packet->method.length || packet->data.length) - buffer[cur++] = '\n'; // start of content part if there's content + if (packet->flag == PSYC_PACKET_NEED_LENGTH || + packet->entity.lines || packet->method.length || packet->data.length) + buffer[cur++] = '\n'; // start of content part if there's content or length // render entity modifiers for (i = 0; i < packet->entity.lines; i++) @@ -94,11 +95,11 @@ psycRenderRC psyc_render (psycPacket *packet, char *buffer, size_t buflen) memcpy(buffer + cur, packet->method.ptr, packet->method.length); cur += packet->method.length; buffer[cur++] = '\n'; + if (packet->data.length) // add data\n { memcpy(buffer + cur, packet->data.ptr, packet->data.length); cur += packet->data.length; - buffer[cur++] = '\n'; } } diff --git a/test/testText.c b/test/testText.c index 9fd3c1f..e5aff36 100644 --- a/test/testText.c +++ b/test/testText.c @@ -9,6 +9,8 @@ uint8_t verbose; psycTextValueRC getValueFooBar (const char *name, size_t len, psycString *value) { + if (verbose) + printf("> getValue: %.*s\n", (int)len, name); value->ptr = "Foo Bar"; value->length = 7; return PSYC_TEXT_VALUE_FOUND; @@ -16,6 +18,8 @@ psycTextValueRC getValueFooBar (const char *name, size_t len, psycString *value) psycTextValueRC getValueEmpty (const char *name, size_t len, psycString *value) { + if (verbose) + printf("> getValue: %.*s\n", (int)len, name); value->ptr = ""; value->length = 0; return PSYC_TEXT_VALUE_FOUND; @@ -23,6 +27,8 @@ psycTextValueRC getValueEmpty (const char *name, size_t len, psycString *value) psycTextValueRC getValueNotFound (const char *name, size_t len, psycString *value) { + if (verbose) + printf("> getValue: %.*s\n", (int)len, name); return PSYC_TEXT_VALUE_NOT_FOUND; } From 44622925f5839b41fede9ecba0f3f6e761983cb6 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 4 May 2011 17:59:51 +0200 Subject: [PATCH 162/378] tests & fix for 0 length modifier value --- include/psyc/parser.h | 7 +++++++ src/packet.c | 2 +- src/parser.c | 2 ++ test/packets/00-length-no-value | 7 +++++++ test/packets/00-no-value | 7 +++++++ test/testServer.c | 2 +- 6 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 test/packets/00-length-no-value create mode 100644 test/packets/00-no-value diff --git a/include/psyc/parser.h b/include/psyc/parser.h index 85f7de5..edbb84e 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -109,6 +109,7 @@ typedef struct psycBool 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 + psycBool valueLengthFound; ///< is there a length given for this modifier? } psycParseState; /** @@ -231,6 +232,12 @@ size_t psyc_getParseValueLength (psycParseState *state) return state->valueLength; } +static inline +psycBool psyc_isParseValueLengthFound (psycParseState *state) +{ + return state->valueLengthFound; +} + static inline size_t psyc_getParseCursor (psycParseState *state) { diff --git a/src/packet.c b/src/packet.c index 1b84dcc..5fbfccc 100644 --- a/src/packet.c +++ b/src/packet.c @@ -75,7 +75,7 @@ size_t psyc_getModifierLength (psycModifier *m) m->name.length + 1 + // name\t m->value.length + 1; // value\n - if (m->flag == PSYC_MODIFIER_NEED_LENGTH && m->value.length) // add length of length if needed + if (m->flag == PSYC_MODIFIER_NEED_LENGTH) // add length of length if needed length += psyc_getNumLength(m->value.length) + 1; // SP length return length; diff --git a/src/parser.c b/src/parser.c index 2316b40..d74a2d5 100644 --- a/src/parser.c +++ b/src/parser.c @@ -140,6 +140,7 @@ psycParseRC psyc_parseModifier (psycParseState *state, char *oper, size_t length = 0; value->length = 0; state->valueLength = 0; + state->valueLengthFound = 0; state->valueParsed = 0; // Parse the value. @@ -150,6 +151,7 @@ psycParseRC psyc_parseModifier (psycParseState *state, char *oper, if (isNumeric(state->buffer.ptr[state->cursor])) { + state->valueLengthFound = 1; do { length = 10 * length + state->buffer.ptr[state->cursor] - '0'; diff --git a/test/packets/00-length-no-value b/test/packets/00-length-no-value new file mode 100644 index 0000000..87627cb --- /dev/null +++ b/test/packets/00-length-no-value @@ -0,0 +1,7 @@ +:_source psyc://foo.example.com/ +:_target psyc://bar.example.com/ + +:_foo 0 +_message_private +OHAI +| diff --git a/test/packets/00-no-value b/test/packets/00-no-value new file mode 100644 index 0000000..db992a4 --- /dev/null +++ b/test/packets/00-no-value @@ -0,0 +1,7 @@ +:_source psyc://foo.example.com/ +:_target psyc://bar.example.com/ + +:_foo +_message_private +OHAI +| diff --git a/test/testServer.c b/test/testServer.c index e7aeccc..a93bc5c 100644 --- a/test/testServer.c +++ b/test/testServer.c @@ -234,7 +234,7 @@ int main (int argc, char **argv) if (ret == PSYC_PARSE_ENTITY) { packets[i].entity.lines++; - mod->flag = psyc_getParseValueLength(&parsers[i]) ? + mod->flag = psyc_isParseValueLengthFound(&parsers[i]) ? PSYC_MODIFIER_NEED_LENGTH : PSYC_MODIFIER_NO_LENGTH; } break; From 3fc8eebfa1770c43beec261ab850f1508b56034b Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 4 May 2011 18:09:01 +0200 Subject: [PATCH 163/378] nettest: run split tests too --- test/Makefile | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/test/Makefile b/test/Makefile index 8a7837d..bb10097 100644 --- a/test/Makefile +++ b/test/Makefile @@ -40,15 +40,17 @@ netstartv: netstartrv: ./testServer ${PORT} -rv -nettest: +nettest: nettestfull nettestsplit + +nettestfull: for f in packets/[0-9]*; do echo ">> $$f"; cat $$f | nc localhost ${PORT} | diff -u $$f -; done +nettestsplit: + for f in packets/[0-9]*; do echo ">> $$f"; ./splittest.pl $$f ${PORT} | diff -u $$f -; done + nettesterr: for f in packets/err-*; do echo ">> $$f"; cat $$f | nc localhost ${PORT}; done -splittest: - for f in packets/[0-9]*; do echo ">> $$f"; ./splittest.pl $$f ${PORT} | diff -u $$f -; done - clean: rm -f ${TARGETS} From 289de97bead9c94e8eff8676ec4655671ebf3a61 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 4 May 2011 18:58:46 +0200 Subject: [PATCH 164/378] fix for 0 length modifier value --- src/parser.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/parser.c b/src/parser.c index d74a2d5..b706c50 100644 --- a/src/parser.c +++ b/src/parser.c @@ -73,7 +73,7 @@ char isKwChar (uint8_t c) * @return PSYC_PARSE_ERROR or PSYC_PARSE_SUCCESS */ static inline -psycParseRC psyc_parseKeyword (psycParseState* state, psycString* name) +psycParseRC psyc_parseKeyword (psycParseState *state, psycString *name) { name->ptr = state->buffer.ptr + state->cursor; name->length = 0; @@ -104,8 +104,8 @@ psycParseRC psyc_parseBinaryValue (psycParseState *state, psycString *value, 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) + { // value doesn't fit in the buffer completely value->length = state->buffer.length - state->cursor; state->cursor += value->length; *parsed += value->length; @@ -168,7 +168,7 @@ psycParseRC psyc_parseModifier (psycParseState *state, char *oper, return PSYC_PARSE_ERROR_MOD_TAB; if (++(state->cursor) >= state->buffer.length) - return PSYC_PARSE_INCOMPLETE; + return length ? PSYC_PARSE_INCOMPLETE : PSYC_PARSE_SUCCESS; // if length=0 we're done ret = psyc_parseBinaryValue(state, value, &(state->valueLength), &(state->valueParsed)); if (ret == PSYC_PARSE_INCOMPLETE) @@ -197,8 +197,8 @@ psycParseRC psyc_parseModifier (psycParseState *state, char *oper, * Parse PSYC packets. * Generalized line-based parser. */ -psycParseRC psyc_parse (psycParseState* state, char* oper, - psycString* name, psycString* value) +psycParseRC psyc_parse (psycParseState *state, char *oper, + psycString *name, psycString *value) { #ifdef DEBUG if (state->flags & PSYC_PARSE_ROUTING_ONLY && @@ -298,7 +298,7 @@ psycParseRC psyc_parse (psycParseState* state, char* oper, case PSYC_PART_CONTENT: // In case of an incomplete binary variable resume parsing it. - if (state->valueParsed < state->valueLength) + if (state->valueParsed < state->valueLength) { ret = psyc_parseBinaryValue(state, value, &(state->valueLength), &(state->valueParsed)); state->contentParsed += value->length; @@ -453,8 +453,8 @@ psycParseRC psyc_parse (psycParseState* state, char* oper, * List value parser. * @return see psycListRC. */ -psycParseListRC psyc_parseList (psycParseListState* state, psycString *name, - psycString* value, psycString* elem) +psycParseListRC psyc_parseList (psycParseListState *state, psycString *name, + psycString *value, psycString *elem) { if (state->cursor >= state->buffer.length) return PSYC_PARSE_LIST_INCOMPLETE; From 07c6711db037532944d375c5d8d7cb6846401c2d Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 6 May 2011 00:13:37 +0200 Subject: [PATCH 165/378] parser: fixes routing-only mode, set valueParsed & valueLength for data as well; render: added support for rendering raw content --- include/psyc.h | 12 +++++------ include/psyc/packet.h | 8 +++++++ include/psyc/parser.h | 2 +- src/packet.c | 47 +++++++++++++++++++++++++++++++++-------- src/parser.c | 49 ++++++++++++++++++++++++++++++++----------- src/render.c | 44 ++++++++++++++++++++++---------------- 6 files changed, 116 insertions(+), 46 deletions(-) diff --git a/include/psyc.h b/include/psyc.h index 6d8f1bc..c4fca1d 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -39,12 +39,12 @@ typedef enum typedef enum { PSYC_PART_RESET = -1, - PSYC_PART_ROUTING, - PSYC_PART_LENGTH, - PSYC_PART_CONTENT, - PSYC_PART_METHOD, - PSYC_PART_DATA, - PSYC_PART_END, + PSYC_PART_ROUTING = 0, + PSYC_PART_LENGTH = 1, + PSYC_PART_CONTENT = 2, + PSYC_PART_METHOD = 3, + PSYC_PART_DATA = 4, + PSYC_PART_END = 5, } psycPart; /** diff --git a/include/psyc/packet.h b/include/psyc/packet.h index 173b3d9..31c7748 100644 --- a/include/psyc/packet.h +++ b/include/psyc/packet.h @@ -56,6 +56,7 @@ typedef struct psycHeader entity; ///< Entity header. psycString method; psycString data; + psycString content; size_t routingLength; ///< Length of routing part. size_t contentLength; ///< Length of content part. size_t length; ///< Total length of packet. @@ -135,4 +136,11 @@ psycPacket psyc_newPacket2 (psycModifier *routing, size_t routinglen, const char *data, size_t datalen, psycPacketFlag flag); +psycPacket psyc_newPacketContent (psycHeader *routing, psycString *content, + psycPacketFlag flag); + +psycPacket psyc_newPacketContent2 (psycModifier *routing, size_t routinglen, + const char *content, size_t contentlen, + psycPacketFlag flag); + #endif // PSYC_PACKET_H diff --git a/include/psyc/parser.h b/include/psyc/parser.h index edbb84e..b28d064 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -4,7 +4,7 @@ * * All parsing functions and the definitions they use are * defined in this file. -*/ + */ /** * @defgroup parser Parsing Functions diff --git a/src/packet.c b/src/packet.c index 5fbfccc..d96e31a 100644 --- a/src/packet.c +++ b/src/packet.c @@ -114,15 +114,20 @@ size_t psyc_setPacketLength(psycPacket *p) for (i = 0; i < p->routing.lines; i++) p->routingLength += psyc_getModifierLength(&(p->routing.modifiers[i])); - // add entity header length - for (i = 0; i < p->entity.lines; i++) - p->contentLength += psyc_getModifierLength(&(p->entity.modifiers[i])); + if (p->content.length) + p->contentLength = p->content.length; + else + { + // add entity header length + for (i = 0; i < p->entity.lines; i++) + p->contentLength += psyc_getModifierLength(&(p->entity.modifiers[i])); - // add length of method, data & delimiter - if (p->method.length) - p->contentLength += p->method.length + 1; // method\n - if (p->data.length) - p->contentLength += p->data.length + 1; // data\n + // add length of method, data & delimiter + if (p->method.length) + p->contentLength += p->method.length + 1; // method\n + if (p->data.length) + p->contentLength += p->data.length + 1; // data\n + } // set total length: routing-header content |\n p->length = p->routingLength + p->contentLength + 2; @@ -141,7 +146,7 @@ psycPacket psyc_newPacket (psycHeader *routing, psycHeader *entity, psycString *method, psycString *data, psycPacketFlag flag) { - psycPacket p = {*routing, *entity, *method, *data, 0, 0, flag}; + psycPacket p = {*routing, *entity, *method, *data, {0,0}, 0, 0, flag}; if (flag == PSYC_PACKET_CHECK_LENGTH) // find out if it needs a length p.flag = psyc_checkPacketLength(&p); @@ -164,3 +169,27 @@ psycPacket psyc_newPacket2 (psycModifier *routing, size_t routinglen, return psyc_newPacket(&r, &e, &m, &d, flag); } + +inline +psycPacket psyc_newPacketContent (psycHeader *routing, psycString *content, + psycPacketFlag flag) +{ + psycPacket p = {*routing, {0,0}, {0,0}, {0,0}, *content, 0, 0, flag}; + + if (flag == PSYC_PACKET_CHECK_LENGTH) // find out if it needs a length + p.flag = psyc_checkPacketLength(&p); + + psyc_setPacketLength(&p); + return p; +} + +inline +psycPacket psyc_newPacketContent2 (psycModifier *routing, size_t routinglen, + const char *content, size_t contentlen, + psycPacketFlag flag) +{ + psycHeader r = {routinglen, routing}; + psycString c = {contentlen, content}; + + return psyc_newPacketContent(&r, &c, flag); +} diff --git a/src/parser.c b/src/parser.c index b706c50..36c8bb9 100644 --- a/src/parser.c +++ b/src/parser.c @@ -222,6 +222,7 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, case PSYC_PART_RESET: // New packet starts here, reset state. state->valueParsed = 0; state->valueLength = 0; + state->valueLengthFound = 0; state->routingLength = 0; state->contentParsed = 0; state->contentLength = 0; @@ -354,6 +355,10 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, if (state->buffer.ptr[state->cursor] != '\n') return PSYC_PARSE_ERROR_METHOD; + state->valueLengthFound = 0; + state->valueParsed = 0; + state->valueLength = 0; + if (state->contentLengthFound) { // if length was found set start position to the beginning of data state->cursor++; @@ -362,7 +367,9 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, state->part = PSYC_PART_DATA; } else // otherwise keep it at the beginning of method + { ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + } // fall thru } @@ -380,19 +387,21 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, if (state->contentLengthFound) // We know the length of the packet. { - if (state->contentParsed < state->contentLength && - psyc_parseBinaryValue(state, value, &(state->contentLength), - &(state->contentParsed)) == PSYC_PARSE_INCOMPLETE) - return PSYC_PARSE_BODY_INCOMPLETE; + if (!state->valueLengthFound) // start of data + { + state->valueLengthFound = 1; + state->valueLength = state->contentLength - state->contentParsed; // length of data + if (state->valueLength && !(state->flags & PSYC_PARSE_ROUTING_ONLY)) + state->valueLength--; // \n at the end is not part of data + } + if (state->valueParsed < state->valueLength) + { + ret = psyc_parseBinaryValue(state, value, &(state->valueLength), &(state->valueParsed)); + state->contentParsed += value->length; - if (value->length) - value->length--; // \n at the end is not part of the body - - if (state->cursor >= state->buffer.length) - return PSYC_PARSE_BODY; - - if (state->buffer.ptr[state->cursor] != '|') - return PSYC_PARSE_ERROR_BODY; + if (ret == PSYC_PARSE_INCOMPLETE) + return PSYC_PARSE_BODY_INCOMPLETE; + } state->part = PSYC_PART_END; return PSYC_PARSE_BODY; @@ -415,6 +424,9 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, if (state->buffer.ptr[state->cursor+nl] == '|' && state->buffer.ptr[state->cursor+1+nl] == '\n') // packet ends here { + if (state->flags & PSYC_PARSE_ROUTING_ONLY) + value->length++; + state->contentParsed += state->cursor - pos; state->cursor += nl; state->part = PSYC_PART_END; @@ -428,6 +440,19 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, case PSYC_PART_END: PSYC_PART_END: + if (state->contentLengthFound && state->valueLengthFound && state->valueLength && + !(state->flags & PSYC_PARSE_ROUTING_ONLY)) + { // if data was not empty next is the \n at the end of data + state->valueLength = 0; + state->valueLengthFound = 0; + + if (state->buffer.ptr[state->cursor] != '\n') + return PSYC_PARSE_ERROR_END; + + state->contentParsed++; + state->cursor++; + } + // 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? diff --git a/src/render.c b/src/render.c index 74ba859..5990f4b 100644 --- a/src/render.c +++ b/src/render.c @@ -82,29 +82,37 @@ psycRenderRC psyc_render (psycPacket *packet, char *buffer, size_t buflen) if (packet->flag == PSYC_PACKET_NEED_LENGTH) cur += itoa(packet->contentLength, buffer + cur, 10); - if (packet->flag == PSYC_PACKET_NEED_LENGTH || + if (packet->flag == PSYC_PACKET_NEED_LENGTH || packet->content.length || packet->entity.lines || packet->method.length || packet->data.length) buffer[cur++] = '\n'; // start of content part if there's content or length - // render entity modifiers - for (i = 0; i < packet->entity.lines; i++) - cur += psyc_renderModifier(&packet->entity.modifiers[i], buffer + cur); - - if (packet->method.length) // add method\n + if (packet->content.length) // render raw content if present { - memcpy(buffer + cur, packet->method.ptr, packet->method.length); - cur += packet->method.length; - buffer[cur++] = '\n'; - - if (packet->data.length) // add data\n - { - memcpy(buffer + cur, packet->data.ptr, packet->data.length); - cur += packet->data.length; - buffer[cur++] = '\n'; - } + memcpy(buffer + cur, packet->content.ptr, packet->content.length); + cur += packet->content.length; + } + else + { + // render entity modifiers + for (i = 0; i < packet->entity.lines; i++) + cur += psyc_renderModifier(&packet->entity.modifiers[i], buffer + cur); + + if (packet->method.length) // add method\n + { + memcpy(buffer + cur, packet->method.ptr, packet->method.length); + cur += packet->method.length; + buffer[cur++] = '\n'; + + if (packet->data.length) // add data\n + { + memcpy(buffer + cur, packet->data.ptr, packet->data.length); + cur += packet->data.length; + buffer[cur++] = '\n'; + } + } + else if (packet->data.length) // error, we have data but no modifier + return PSYC_RENDER_ERROR_METHOD_MISSING; } - else if (packet->data.length) // error, we have data but no modifier - return PSYC_RENDER_ERROR_METHOD_MISSING; // add packet delimiter buffer[cur++] = C_GLYPH_PACKET_DELIMITER; From aa59061a0a16027284bd75bf4211e362f90a1375 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 6 May 2011 00:15:37 +0200 Subject: [PATCH 166/378] testServer: new cmdline options, memory handling fixes, fixes for routing-only mode --- test/Makefile | 38 ++++++++++++----- test/testServer.c | 102 ++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 117 insertions(+), 23 deletions(-) diff --git a/test/Makefile b/test/Makefile index bb10097..67c8524 100644 --- a/test/Makefile +++ b/test/Makefile @@ -17,6 +17,11 @@ debug: CFLAGS += -DDEBUG=${DEBUG} -g debug: CFLAGS := $(subst ${OPT},-O0,${CFLAGS}) debug: all +clean: + rm -f ${TARGETS} + +it: all + test: ${TARGETS} ./testRender ./testMatch @@ -26,7 +31,16 @@ test: ${TARGETS} for f in packets/[0-9]*; do echo ">> $$f"; ./testParser $$f; done for f in packets/[0-9]*; do echo ">> $$f"; ./testParser $$f -r; done -testServer: CFLAGS := $(subst -std=c99,,${CFLAGS}) +nettest: nettestfull nettestsplit + +nettestfull: + for f in packets/[0-9]*; do echo ">> $$f"; cat $$f | nc localhost ${PORT} | diff -u $$f -; done + +nettestsplit: + for f in packets/[0-9]*; do echo ">> $$f"; ./splittest.pl $$f ${PORT} | diff -u $$f -; done + +nettesterr: + for f in packets/err-*; do echo ">> $$f"; cat $$f | nc localhost ${PORT}; done netstart: ./testServer ${PORT} @@ -40,18 +54,20 @@ netstartv: netstartrv: ./testServer ${PORT} -rv -nettest: nettestfull nettestsplit +netstartm: + ./testServer ${PORT} -m -nettestfull: - for f in packets/[0-9]*; do echo ">> $$f"; cat $$f | nc localhost ${PORT} | diff -u $$f -; done +netstartmr: + ./testServer ${PORT} -mr -nettestsplit: - for f in packets/[0-9]*; do echo ">> $$f"; ./splittest.pl $$f ${PORT} | diff -u $$f -; done +netstartms: + ./testServer ${PORT} -ms -nettesterr: - for f in packets/err-*; do echo ">> $$f"; cat $$f | nc localhost ${PORT}; done +netstartmsp: + ./testServer ${PORT} -msp -clean: - rm -f ${TARGETS} +netstartmv: + ./testServer ${PORT} -mv -it: all +netstartmrv: + ./testServer ${PORT} -mrv diff --git a/test/testServer.c b/test/testServer.c index a93bc5c..d61c2d7 100644 --- a/test/testServer.c +++ b/test/testServer.c @@ -11,8 +11,11 @@ #include #include #include +#include +#include #include #include +#define __USE_POSIX #include #include #include @@ -22,14 +25,24 @@ #include #include -const size_t RECV_BUF_SIZE = 256; -const size_t CONT_BUF_SIZE = 512; -const size_t SEND_BUF_SIZE = 1024; +const size_t RECV_BUF_SIZE = 8 * 1024; +const size_t CONT_BUF_SIZE = 8 * 1024; +const size_t SEND_BUF_SIZE = 8 * 1024; const size_t NUM_PARSERS = 100; // max size for routing & entity header const size_t ROUTING_LINES = 16; const size_t ENTITY_LINES = 32; +static inline +void resetString (psycString *s, uint8_t freeptr) +{ + if (freeptr && s->length) + free((void*)s->ptr); + + s->ptr = NULL; + s->length = 0; +} + // get sockaddr, IPv4 or IPv6: void *get_in_addr (struct sockaddr *sa) { @@ -42,8 +55,14 @@ void *get_in_addr (struct sockaddr *sa) int main (int argc, char **argv) { char *port = argc > 1 ? argv[1] : "4440"; - uint8_t routing_only = argc > 2 && memchr(argv[2], (int)'r', strlen(argv[2])); - uint8_t verbose = argc > 2 && memchr(argv[2], (int)'v', strlen(argv[2])); + uint8_t routing_only = argc > 2 && memchr(argv[2], (int)'r', strlen(argv[2])); + uint8_t verbose = argc > 2 && memchr(argv[2], (int)'v', strlen(argv[2])); + uint8_t parse_multiple = argc > 2 && memchr(argv[2], (int)'m', strlen(argv[2])); + uint8_t progress = argc > 2 && memchr(argv[2], (int)'p', strlen(argv[2])); + uint8_t stats = argc > 2 && memchr(argv[2], (int)'s', strlen(argv[2])); + size_t recv_buf_size = argc > 3 ? atoi(argv[3]) : 0; + if (recv_buf_size <= 0) + recv_buf_size = RECV_BUF_SIZE; fd_set master; // master file descriptor list fd_set read_fds; // temp file descriptor list for select() @@ -63,7 +82,7 @@ int main (int argc, char **argv) char remoteIP[INET6_ADDRSTRLEN]; int yes = 1; // for setsockopt() SO_REUSEADDR, below - int i, rv; + int i, j, rv; struct addrinfo hints, *ai, *p; @@ -73,6 +92,8 @@ int main (int argc, char **argv) psycModifier entity[NUM_PARSERS][ENTITY_LINES]; psycModifier *mod = NULL; + struct timeval start[NUM_PARSERS], end[NUM_PARSERS]; + int ret, retl; char oper; psycString name, value, elem; @@ -182,13 +203,19 @@ int main (int argc, char **argv) get_in_addr((struct sockaddr*)&remoteaddr), remoteIP, INET6_ADDRSTRLEN), newfd); + + if (stats) + gettimeofday(&start[newfd], NULL); } } else { // handle data from a client - if ((nbytes = recv(i, recvbuf, RECV_BUF_SIZE, 0)) <= 0) + if ((nbytes = recv(i, recvbuf, recv_buf_size, 0)) <= 0) { + if (stats) + printf("%ld ms\n", (end[i].tv_sec * 1000000 + end[i].tv_usec - start[i].tv_sec * 1000000 - start[i].tv_usec) / 1000); + // got error or connection closed by client if (nbytes == 0) // connection closed printf("socket %d hung up\n", i); @@ -246,25 +273,70 @@ int main (int argc, char **argv) break; case PSYC_PARSE_COMPLETE: - printf("# Done parsing.\n"); + if (verbose) + printf("# Done parsing.\n"); + else if (progress) + write(1, ".", 1); + if (!parse_multiple) // parse multiple packets? + ret = -1; + packets[i].flag = psyc_isParseContentLengthFound(&parsers[i]) ? PSYC_PACKET_NEED_LENGTH : PSYC_PACKET_NO_LENGTH; if (routing_only) - packets[i].method = psyc_newString(PSYC_C2ARG("_packet_content")); + { + packets[i].content = packets[i].data; + resetString(&packets[i].data, 0); + } psyc_setPacketLength(&packets[i]); if (psyc_render(&packets[i], sendbuf, SEND_BUF_SIZE) == PSYC_RENDER_SUCCESS) { if (send(i, sendbuf, packets[i].length, 0) == -1) + { perror("send error"); + ret = -1; + } } else + { perror("render error"); + ret = -1; + } + + // reset packet + packets[i].routingLength = 0; + packets[i].contentLength = 0; + packets[i].length = 0; + packets[i].flag = 0; + + for (j = 0; j < packets[i].routing.lines; j++) + { + resetString(&packets[i].routing.modifiers[j].name, 1); + resetString(&packets[i].routing.modifiers[j].value, 1); + } + packets[i].routing.lines = 0; + + if (routing_only) + { + resetString(&packets[i].content, 1); + } + else + { + for (j = 0; j < packets[i].entity.lines; j++) + { + resetString(&packets[i].entity.modifiers[j].name, 1); + resetString(&packets[i].entity.modifiers[j].value, 1); + } + packets[i].entity.lines = 0; + + resetString(&packets[i].method, 1); + resetString(&packets[i].data, 1); + } - ret = -1; break; + case PSYC_PARSE_INSUFFICIENT: if (verbose) printf("# Insufficient data.\n"); @@ -274,7 +346,7 @@ int main (int argc, char **argv) if (contbytes > 0) // copy end of parsebuf before start of recvbuf { assert(recvbuf - contbytes >= buf); // make sure it's still in the buffer - memcpy(recvbuf - contbytes, psyc_getParseRemainingBuffer(&parsers[i]), contbytes); + memmove(recvbuf - contbytes, psyc_getParseRemainingBuffer(&parsers[i]), contbytes); } ret = 0; break; @@ -313,7 +385,7 @@ int main (int argc, char **argv) } if (value.length) { - if (!pvalue->ptr) + if (!pvalue->length) pvalue->ptr = malloc(parsers[i].valueLength ? parsers[i].valueLength : value.length); assert(pvalue->ptr != NULL); memcpy((void*)pvalue->ptr + pvalue->length, value.ptr, value.length); @@ -376,6 +448,12 @@ int main (int argc, char **argv) } while (ret > 0); + if (progress) + write(1, " ", 1); + + if (stats) + gettimeofday(&end[i], NULL); + if (ret < 0) { printf("# Closing connection: %i\n", i); From 03a33c7a5e6ecb406696a51362d3fbac7d723009 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 6 May 2011 00:18:25 +0200 Subject: [PATCH 167/378] + --- include/psyc/packet.h | 10 +++++----- src/packet.c | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/include/psyc/packet.h b/include/psyc/packet.h index 31c7748..350a418 100644 --- a/include/psyc/packet.h +++ b/include/psyc/packet.h @@ -136,11 +136,11 @@ psycPacket psyc_newPacket2 (psycModifier *routing, size_t routinglen, const char *data, size_t datalen, psycPacketFlag flag); -psycPacket psyc_newPacketContent (psycHeader *routing, psycString *content, - psycPacketFlag flag); +psycPacket psyc_newRawPacket (psycHeader *routing, psycString *content, + psycPacketFlag flag); -psycPacket psyc_newPacketContent2 (psycModifier *routing, size_t routinglen, - const char *content, size_t contentlen, - psycPacketFlag flag); +psycPacket psyc_newRawPacket2 (psycModifier *routing, size_t routinglen, + const char *content, size_t contentlen, + psycPacketFlag flag); #endif // PSYC_PACKET_H diff --git a/src/packet.c b/src/packet.c index d96e31a..aed1aa5 100644 --- a/src/packet.c +++ b/src/packet.c @@ -171,8 +171,8 @@ psycPacket psyc_newPacket2 (psycModifier *routing, size_t routinglen, } inline -psycPacket psyc_newPacketContent (psycHeader *routing, psycString *content, - psycPacketFlag flag) +psycPacket psyc_newRawPacket (psycHeader *routing, psycString *content, + psycPacketFlag flag) { psycPacket p = {*routing, {0,0}, {0,0}, {0,0}, *content, 0, 0, flag}; @@ -184,12 +184,12 @@ psycPacket psyc_newPacketContent (psycHeader *routing, psycString *content, } inline -psycPacket psyc_newPacketContent2 (psycModifier *routing, size_t routinglen, - const char *content, size_t contentlen, - psycPacketFlag flag) +psycPacket psyc_newRawPacket2 (psycModifier *routing, size_t routinglen, + const char *content, size_t contentlen, + psycPacketFlag flag) { psycHeader r = {routinglen, routing}; psycString c = {contentlen, content}; - return psyc_newPacketContent(&r, &c, flag); + return psyc_newRawPacket(&r, &c, flag); } From 52552b8528b0334de53622a9a8c64fd42d78b166 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 6 May 2011 13:32:12 +0200 Subject: [PATCH 168/378] better nettest --- test/Makefile | 45 ++++++++++++++------------------------------- test/testServer.c | 46 ++++++++++++++++++++++++++-------------------- 2 files changed, 40 insertions(+), 51 deletions(-) diff --git a/test/Makefile b/test/Makefile index 67c8524..f36fb7d 100644 --- a/test/Makefile +++ b/test/Makefile @@ -31,43 +31,26 @@ test: ${TARGETS} for f in packets/[0-9]*; do echo ">> $$f"; ./testParser $$f; done for f in packets/[0-9]*; do echo ">> $$f"; ./testParser $$f -r; done -nettest: nettestfull nettestsplit +# test packet parsing & rendering with the test server +nettest: srvstart pkt pktsplit srvkill -nettestfull: +# same test but parse routing headers only +nettestr: srvstartr pkt pktsplit srvkill + +pkt: for f in packets/[0-9]*; do echo ">> $$f"; cat $$f | nc localhost ${PORT} | diff -u $$f -; done -nettestsplit: +pktsplit: for f in packets/[0-9]*; do echo ">> $$f"; ./splittest.pl $$f ${PORT} | diff -u $$f -; done -nettesterr: +pkterr: for f in packets/err-*; do echo ">> $$f"; cat $$f | nc localhost ${PORT}; done -netstart: - ./testServer ${PORT} +srvstart: + ./testServer ${PORT} & -netstartr: - ./testServer ${PORT} -r +srvstartr: + ./testServer ${PORT} -r & -netstartv: - ./testServer ${PORT} -v - -netstartrv: - ./testServer ${PORT} -rv - -netstartm: - ./testServer ${PORT} -m - -netstartmr: - ./testServer ${PORT} -mr - -netstartms: - ./testServer ${PORT} -ms - -netstartmsp: - ./testServer ${PORT} -msp - -netstartmv: - ./testServer ${PORT} -mv - -netstartmrv: - ./testServer ${PORT} -mrv +srvkill: + killall testServer diff --git a/test/testServer.c b/test/testServer.c index d61c2d7..182377d 100644 --- a/test/testServer.c +++ b/test/testServer.c @@ -55,11 +55,15 @@ void *get_in_addr (struct sockaddr *sa) int main (int argc, char **argv) { char *port = argc > 1 ? argv[1] : "4440"; - uint8_t routing_only = argc > 2 && memchr(argv[2], (int)'r', strlen(argv[2])); - uint8_t verbose = argc > 2 && memchr(argv[2], (int)'v', strlen(argv[2])); - uint8_t parse_multiple = argc > 2 && memchr(argv[2], (int)'m', strlen(argv[2])); - uint8_t progress = argc > 2 && memchr(argv[2], (int)'p', strlen(argv[2])); - uint8_t stats = argc > 2 && memchr(argv[2], (int)'s', strlen(argv[2])); + char *opts = argc > 2 ? argv[2] : NULL; + char *v, *w; + uint8_t verbose = opts && (v = memchr(opts, (int)'v', strlen(opts))) ? + v - opts > 0 && (w = memchr(v+1, (int)'v', strlen(opts) - (v - opts))) ? + w - v > 0 && memchr(w+1, (int)'v', strlen(opts) - (w - opts)) ? 3 : 2 : 1 : 0; + uint8_t routing_only = opts && memchr(opts, (int)'r', strlen(opts)); + uint8_t parse_multiple = opts && memchr(opts, (int)'m', strlen(opts)); + uint8_t progress = opts && memchr(opts, (int)'p', strlen(opts)); + uint8_t stats = opts && memchr(opts, (int)'s', strlen(opts)); size_t recv_buf_size = argc > 3 ? atoi(argv[3]) : 0; if (recv_buf_size <= 0) recv_buf_size = RECV_BUF_SIZE; @@ -198,11 +202,12 @@ int main (int argc, char **argv) packets[newfd].routing.modifiers = routing[newfd]; packets[newfd].entity.modifiers = entity[newfd]; - printf("# New connection from %s on socket %d\n", - inet_ntop(remoteaddr.ss_family, - get_in_addr((struct sockaddr*)&remoteaddr), - remoteIP, INET6_ADDRSTRLEN), - newfd); + if (verbose) + printf("# New connection from %s on socket %d\n", + inet_ntop(remoteaddr.ss_family, + get_in_addr((struct sockaddr*)&remoteaddr), + remoteIP, INET6_ADDRSTRLEN), + newfd); if (stats) gettimeofday(&start[newfd], NULL); @@ -218,7 +223,7 @@ int main (int argc, char **argv) // got error or connection closed by client if (nbytes == 0) // connection closed - printf("socket %d hung up\n", i); + printf("# Socket %d hung up\n", i); else perror("recv"); @@ -238,7 +243,7 @@ int main (int argc, char **argv) do { ret = psyc_parse(&parsers[i], &oper, &name, &value); - if (verbose) + if (verbose >= 2) printf("# ret = %d\n", ret); switch (ret) { @@ -338,7 +343,7 @@ int main (int argc, char **argv) break; case PSYC_PARSE_INSUFFICIENT: - if (verbose) + if (verbose >= 2) printf("# Insufficient data.\n"); contbytes = psyc_getParseRemainingLength(&parsers[i]); @@ -367,7 +372,7 @@ int main (int argc, char **argv) if (oper) { mod->oper = oper; - if (verbose) + if (verbose >= 2) printf("%c", oper); } @@ -380,7 +385,7 @@ int main (int argc, char **argv) memcpy((void*)pname->ptr, name.ptr, name.length); name.length = 0; - if (verbose) + if (verbose >= 2) printf("%.*s = ", (int)pname->length, pname->ptr); } @@ -392,7 +397,7 @@ int main (int argc, char **argv) pvalue->length += value.length; value.length = 0; - if (verbose) + if (verbose >= 2) { printf("[%.*s]", (int)pvalue->length, pvalue->ptr); if (parsers[i].valueLength > pvalue->length) @@ -403,7 +408,7 @@ int main (int argc, char **argv) else if (verbose) printf("\n"); - if (verbose) + if (verbose >= 3) printf("\t\t\t\t\t\t\t\t# n:%ld v:%ld c:%ld r:%ld\n", pname->length, pvalue->length, parsers[i].contentParsed, parsers[i].routingLength); @@ -415,7 +420,7 @@ int main (int argc, char **argv) case PSYC_PARSE_ENTITY: if (pname->length >= 5 && memcmp(pname->ptr, "_list", 5) == 0) { - if (verbose) + if (verbose >= 2) printf("## LIST START\n"); psyc_initParseListState(&listState); @@ -429,7 +434,7 @@ int main (int argc, char **argv) case PSYC_PARSE_LIST_END: retl = 0; case PSYC_PARSE_LIST_ELEM: - if (verbose) + if (verbose >= 2) { printf("|%.*s\n", (int)elem.length, elem.ptr); if (ret == PSYC_PARSE_LIST_END) @@ -456,7 +461,8 @@ int main (int argc, char **argv) if (ret < 0) { - printf("# Closing connection: %i\n", i); + if (verbose) + printf("# Closing connection: %i\n", i); close(i); // bye! FD_CLR(i, &master); // remove from master set } From ac1b16bebdbd1e654b693690e66dde4d4cfccc20 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 6 May 2011 13:34:04 +0200 Subject: [PATCH 169/378] better nettest --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index a004220..862feeb 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,8 @@ diet: test: ${MAKE} -C test test + ${MAKE} -C test nettest + ${MAKE} -C test nettestr doc: doxygen From a2815d69710ec63b05711e5715d4cb5049d26477 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 6 May 2011 15:26:28 +0200 Subject: [PATCH 170/378] psycString init --- include/psyc/parser.h | 6 ++++-- include/psyc/text.h | 22 ++++++++++++---------- test/testParser.c | 2 +- test/testServer.c | 2 +- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index b28d064..a9bf74f 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -184,7 +184,8 @@ void psyc_setParseBuffer (psycParseState *state, psycString buffer) static inline void psyc_setParseBuffer2 (psycParseState *state, char *buffer, size_t length) { - psyc_setParseBuffer(state, psyc_newString(buffer, length)); + psycString buf = {length, buffer}; + psyc_setParseBuffer(state, buf); } /** @@ -211,7 +212,8 @@ void psyc_setParseListBuffer (psycParseListState *state, psycString buffer) static inline void psyc_setParseListBuffer2 (psycParseListState *state, char *buffer, size_t length) { - psyc_setParseListBuffer(state, psyc_newString(buffer, length)); + psycString buf = {length, buffer}; + psyc_setParseListBuffer(state, buf); } static inline diff --git a/include/psyc/text.h b/include/psyc/text.h index 8f3b1f0..3f4746f 100644 --- a/include/psyc/text.h +++ b/include/psyc/text.h @@ -78,11 +78,12 @@ void psyc_initTextState (psycTextState *state, char *template, size_t tlen, char *buffer, size_t blen) { - state->cursor = state->written = 0; - state->template = psyc_newString(template, tlen); - state->buffer = psyc_newString(buffer, blen); - state->open = psyc_newString("[", 1); - state->close = psyc_newString("]", 1); + state->cursor = 0; + state->written = 0; + state->template = {tlen, template}; + state->buffer = {blen, buffer}; + state->open = {1, "["}; + state->close = {1, "]"}; } /** @@ -105,10 +106,10 @@ void psyc_initTextState2 (psycTextState *state, char *open, size_t openlen, char *close, size_t closelen) { - state->template = psyc_newString(template, tlen); - state->buffer = psyc_newString(buffer, blen); - state->open = psyc_newString(open, openlen); - state->close = psyc_newString(close, closelen); + state->template = {tlen, template}; + state->buffer = {blen, buffer}; + state->open = {openlen, open}; + state->close = {closelen, close}; } /** @@ -128,7 +129,8 @@ static inline void psyc_setTextBuffer2 (psycTextState *state, char *buffer, size_t length) { - psyc_setTextBuffer(state, psyc_newString(buffer, length)); + psycString buf = {length, buffer}; + psyc_setTextBuffer(state, buf); } static inline diff --git a/test/testParser.c b/test/testParser.c index 38a1d46..8634bcb 100644 --- a/test/testParser.c +++ b/test/testParser.c @@ -33,7 +33,7 @@ int main (int argc, char **argv) else psyc_initParseState(&state); - psyc_setParseBuffer(&state, psyc_newString(buffer, idx)); + psyc_setParseBuffer2(&state, buffer, idx); // try parsing that now do diff --git a/test/testServer.c b/test/testServer.c index 182377d..95a8caa 100644 --- a/test/testServer.c +++ b/test/testServer.c @@ -234,7 +234,7 @@ int main (int argc, char **argv) { // we got some data from a client parsebuf = recvbuf - contbytes; - psyc_setParseBuffer(&parsers[i], psyc_newString(parsebuf, contbytes + nbytes)); + psyc_setParseBuffer2(&parsers[i], parsebuf, contbytes + nbytes); contbytes = 0; oper = 0; name.length = 0; From 7a5d75147791240e9edc435b759458e8625d9078 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 6 May 2011 15:33:52 +0200 Subject: [PATCH 171/378] psycString init fix --- include/psyc/text.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/include/psyc/text.h b/include/psyc/text.h index 3f4746f..dd9b180 100644 --- a/include/psyc/text.h +++ b/include/psyc/text.h @@ -78,12 +78,12 @@ void psyc_initTextState (psycTextState *state, char *template, size_t tlen, char *buffer, size_t blen) { - state->cursor = 0; - state->written = 0; - state->template = {tlen, template}; - state->buffer = {blen, buffer}; - state->open = {1, "["}; - state->close = {1, "]"}; + state->cursor = 0; + state->written = 0; + state->template = (psycString) {tlen, template}; + state->buffer = (psycString) {blen, buffer}; + state->open = (psycString) {1, "["}; + state->close = (psycString) {1, "]"}; } /** @@ -106,10 +106,10 @@ void psyc_initTextState2 (psycTextState *state, char *open, size_t openlen, char *close, size_t closelen) { - state->template = {tlen, template}; - state->buffer = {blen, buffer}; - state->open = {openlen, open}; - state->close = {closelen, close}; + state->template = (psycString) {tlen, template}; + state->buffer = (psycString) {blen, buffer}; + state->open = (psycString) {openlen, open}; + state->close = (psycString) {closelen, close}; } /** From 84ef512168b8e43a72072df6f9834210526ba33f Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sat, 7 May 2011 18:13:59 +0200 Subject: [PATCH 172/378] parser: more detailed return codes for incomplete values --- include/psyc/parser.h | 20 +++++++++++++------- src/parser.c | 10 +++++----- test/testServer.c | 28 ++++++++++++++++++++++------ 3 files changed, 40 insertions(+), 18 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index a9bf74f..8167148 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -56,21 +56,27 @@ typedef enum PSYC_PARSE_ENTITY = 3, /// Entity modifier parsing is incomplete. /// Operator & name are complete, value is incomplete. - PSYC_PARSE_ENTITY_INCOMPLETE = 4, + PSYC_PARSE_ENTITY_START = 4, + PSYC_PARSE_ENTITY_CONT = 5, + PSYC_PARSE_ENTITY_END = 6, /// Body parsing done, name contains method, value contains body. - PSYC_PARSE_BODY = 5, + PSYC_PARSE_BODY = 7, /// Body parsing is incomplete, name contains method, value contains part of the body. - PSYC_PARSE_BODY_INCOMPLETE = 6, + PSYC_PARSE_BODY_START = 8, + PSYC_PARSE_BODY_CONT = 9, + PSYC_PARSE_BODY_END = 10, /// Content parsing done, value contains the whole content. /// Used when PSYC_PARSE_ROUTING_ONLY is set. - PSYC_PARSE_CONTENT = 5, + PSYC_PARSE_CONTENT = 7, /// Content parsing is incomplete, value contains part of content. /// Used when PSYC_PARSE_ROUTING_ONLY is set. - PSYC_PARSE_CONTENT_INCOMPLETE = 6, + PSYC_PARSE_CONTENT_START = 8, + PSYC_PARSE_CONTENT_CONT = 9, + PSYC_PARSE_CONTENT_END = 10, /// Reached end of packet, parsing done. - PSYC_PARSE_COMPLETE = 7, + PSYC_PARSE_COMPLETE = 11, /// Binary value parsing incomplete, used internally. - PSYC_PARSE_INCOMPLETE = 8, + PSYC_PARSE_INCOMPLETE = 12, } psycParseRC; /** diff --git a/src/parser.c b/src/parser.c index 36c8bb9..575a546 100644 --- a/src/parser.c +++ b/src/parser.c @@ -305,9 +305,9 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, state->contentParsed += value->length; if (ret == PSYC_PARSE_INCOMPLETE) - return PSYC_PARSE_ENTITY_INCOMPLETE; + return PSYC_PARSE_ENTITY_CONT; - return PSYC_PARSE_ENTITY; + return PSYC_PARSE_ENTITY_END; } pos = state->cursor; @@ -330,7 +330,7 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, state->contentParsed += state->cursor - pos; if (ret == PSYC_PARSE_INCOMPLETE) - return PSYC_PARSE_ENTITY_INCOMPLETE; + return PSYC_PARSE_ENTITY_START; else if (ret == PSYC_PARSE_SUCCESS) return PSYC_PARSE_ENTITY; @@ -400,11 +400,11 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, state->contentParsed += value->length; if (ret == PSYC_PARSE_INCOMPLETE) - return PSYC_PARSE_BODY_INCOMPLETE; + return state->valueParsed == value->length ? PSYC_PARSE_BODY_START : PSYC_PARSE_BODY_CONT; } state->part = PSYC_PART_END; - return PSYC_PARSE_BODY; + return state->valueLength == value->length ? PSYC_PARSE_BODY : PSYC_PARSE_BODY_END; } else // Search for the terminator. { diff --git a/test/testServer.c b/test/testServer.c index 95a8caa..41b6da7 100644 --- a/test/testServer.c +++ b/test/testServer.c @@ -103,6 +103,7 @@ int main (int argc, char **argv) psycString name, value, elem; psycString *pname = NULL, *pvalue = NULL; psycParseListState listState; + size_t len; FD_ZERO(&master); // clear the master and temp sets FD_ZERO(&read_fds); @@ -256,14 +257,16 @@ int main (int argc, char **argv) packets[i].routing.lines++; break; - case PSYC_PARSE_ENTITY_INCOMPLETE: + case PSYC_PARSE_ENTITY_START: + case PSYC_PARSE_ENTITY_CONT: + case PSYC_PARSE_ENTITY_END: case PSYC_PARSE_ENTITY: assert(packets[i].entity.lines < ENTITY_LINES); mod = &(packets[i].entity.modifiers[packets[i].entity.lines]); pname = &mod->name; pvalue = &mod->value; - if (ret == PSYC_PARSE_ENTITY) + if (ret == PSYC_PARSE_ENTITY || ret == PSYC_PARSE_ENTITY_END) { packets[i].entity.lines++; mod->flag = psyc_isParseValueLengthFound(&parsers[i]) ? @@ -271,7 +274,9 @@ int main (int argc, char **argv) } break; - case PSYC_PARSE_BODY_INCOMPLETE: + case PSYC_PARSE_BODY_START: + case PSYC_PARSE_BODY_CONT: + case PSYC_PARSE_BODY_END: case PSYC_PARSE_BODY: pname = &(packets[i].method); pvalue = &(packets[i].data); @@ -363,12 +368,16 @@ int main (int argc, char **argv) switch (ret) { - case PSYC_PARSE_ENTITY_INCOMPLETE: - case PSYC_PARSE_BODY_INCOMPLETE: + case PSYC_PARSE_ENTITY_START: + case PSYC_PARSE_ENTITY_CONT: + case PSYC_PARSE_BODY_START: + case PSYC_PARSE_BODY_CONT: ret = 0; case PSYC_PARSE_ENTITY: + case PSYC_PARSE_ENTITY_END: case PSYC_PARSE_ROUTING: case PSYC_PARSE_BODY: + case PSYC_PARSE_BODY_END: if (oper) { mod->oper = oper; @@ -391,7 +400,13 @@ int main (int argc, char **argv) if (value.length) { if (!pvalue->length) - pvalue->ptr = malloc(parsers[i].valueLength ? parsers[i].valueLength : value.length); + { + if (psyc_isParseValueLengthFound(&parsers[i])) + len = psyc_getParseValueLength(&parsers[i]); + else + len = value.length; + pvalue->ptr = malloc(len); + } assert(pvalue->ptr != NULL); memcpy((void*)pvalue->ptr + pvalue->length, value.ptr, value.length); pvalue->length += value.length; @@ -418,6 +433,7 @@ int main (int argc, char **argv) { case PSYC_PARSE_ROUTING: case PSYC_PARSE_ENTITY: + case PSYC_PARSE_ENTITY_END: if (pname->length >= 5 && memcmp(pname->ptr, "_list", 5) == 0) { if (verbose >= 2) From 8cf748b945ea7d06e58ea15a44d9273b572af87c Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sat, 7 May 2011 19:25:18 +0200 Subject: [PATCH 173/378] parser: return code doc --- include/psyc/parser.h | 63 +++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index 8167148..b27912e 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -34,15 +34,23 @@ typedef enum */ typedef enum { - PSYC_PARSE_ERROR_END = -9, - PSYC_PARSE_ERROR_BODY = -8, +/// Error, packet is not ending with a valid delimiter. + PSYC_PARSE_ERROR_END = -8, +/// Error, expected NL after the method. PSYC_PARSE_ERROR_METHOD = -7, +/// Error, expected NL after a modifier. PSYC_PARSE_ERROR_MOD_NL = -6, +/// Error, modifier length is not numeric. PSYC_PARSE_ERROR_MOD_LEN = -5, +/// Error, expected TAB before modifier value. PSYC_PARSE_ERROR_MOD_TAB = -4, +/// Error, modifier name is missing. PSYC_PARSE_ERROR_MOD_NAME = -3, +/// Error, expected NL after the content length. PSYC_PARSE_ERROR_LENGTH = -2, +/// Error in packet. PSYC_PARSE_ERROR = -1, +// Success, used internally. PSYC_PARSE_SUCCESS = 0, /// Buffer contains insufficient amount of data. /// Fill another buffer and concatenate it with the end of the current buffer, @@ -51,31 +59,40 @@ typedef enum /// Routing modifier parsing done. /// Operator, name & value contains the respective parts. PSYC_PARSE_ROUTING = 2, -/// Entity modifier parsing done. -/// Operator, name & value contains the respective parts. - PSYC_PARSE_ENTITY = 3, -/// Entity modifier parsing is incomplete. +/// Start of an incomplete entity modifier. /// Operator & name are complete, value is incomplete. - PSYC_PARSE_ENTITY_START = 4, - PSYC_PARSE_ENTITY_CONT = 5, - PSYC_PARSE_ENTITY_END = 6, -/// Body parsing done, name contains method, value contains body. - PSYC_PARSE_BODY = 7, -/// Body parsing is incomplete, name contains method, value contains part of the body. - PSYC_PARSE_BODY_START = 8, - PSYC_PARSE_BODY_CONT = 9, - PSYC_PARSE_BODY_END = 10, -/// Content parsing done, value contains the whole content. + PSYC_PARSE_ENTITY_START = 3, +/// Continuation of an incomplete entity modifier. + PSYC_PARSE_ENTITY_CONT = 4, +/// End of an incomplete entity modifier. + PSYC_PARSE_ENTITY_END = 5, +/// Entity modifier parsing done in one go. +/// Operator, name & value contains the respective parts. + PSYC_PARSE_ENTITY = 6, +/// Start of an incomplete body. +/// Name contains method, value contains part of the body. + PSYC_PARSE_BODY_START = 7, +/// Continuation of an incomplete body. + PSYC_PARSE_BODY_CONT = 8, +/// End of an incomplete body. + PSYC_PARSE_BODY_END = 9, +/// Body parsing done in one go, name contains method, value contains body. + PSYC_PARSE_BODY = 10, +/// Start of an incomplete content, value contains part of content. /// Used when PSYC_PARSE_ROUTING_ONLY is set. - PSYC_PARSE_CONTENT = 7, -/// Content parsing is incomplete, value contains part of content. + PSYC_PARSE_CONTENT_START = 7, +/// Continuation of an incomplete body. /// Used when PSYC_PARSE_ROUTING_ONLY is set. - PSYC_PARSE_CONTENT_START = 8, - PSYC_PARSE_CONTENT_CONT = 9, - PSYC_PARSE_CONTENT_END = 10, -/// Reached end of packet, parsing done. + PSYC_PARSE_CONTENT_CONT = 8, +/// End of an incomplete body. +/// Used when PSYC_PARSE_ROUTING_ONLY is set. + PSYC_PARSE_CONTENT_END = 9, +/// Content parsing done in one go, value contains the whole content. +/// Used when PSYC_PARSE_ROUTING_ONLY is set. + PSYC_PARSE_CONTENT = 10, +// Binary value parsing complete, used internally. PSYC_PARSE_COMPLETE = 11, -/// Binary value parsing incomplete, used internally. +// Binary value parsing incomplete, used internally. PSYC_PARSE_INCOMPLETE = 12, } psycParseRC; From 86cae5ed7dbc84c892b4ef4206e2c3210f335e76 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sun, 8 May 2011 03:15:06 +0200 Subject: [PATCH 174/378] makefile improvements --- Makefile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 862feeb..4144243 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,12 @@ debug: diet: ${MAKE} -C src diet -test: +debugtest: testdebug test + +testdebug: debug + ${MAKE} -C test debug + +test: all ${MAKE} -C test test ${MAKE} -C test nettest ${MAKE} -C test nettestr From 1ebcb8b17d754272e03b6b674d82a3d8b3005e78 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sun, 8 May 2011 04:11:36 +0200 Subject: [PATCH 175/378] makefile fixes for solaris --- Makefile | 4 ++-- include/psyc/lib.h | 5 ++--- test/Makefile | 15 +++++++++++---- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 4144243..5cb0938 100644 --- a/Makefile +++ b/Makefile @@ -25,8 +25,8 @@ doc: doxygen clean: - make -C src clean - make -C test clean + ${MAKE} -C src clean + ${MAKE} -C test clean rm -rf doc/html doc/latex doc/man help: diff --git a/include/psyc/lib.h b/include/psyc/lib.h index d04aae2..dfa017b 100644 --- a/include/psyc/lib.h +++ b/include/psyc/lib.h @@ -5,7 +5,6 @@ #include "../psyc.h" #include "./debug.h" -#include #include /* perlisms for readability */ @@ -14,11 +13,11 @@ #define PSYC_NUM_ELEM(a) (sizeof(a) / sizeof(*(a))) -#if !defined(_GNU_SOURCE) && !defined(__FBSDID) +#if !defined(__USE_GNU) && !(defined(__FBSDID) && defined(__BSD_VISIBLE)) void * memmem(const void *l, size_t l_len, const void *s, size_t s_len); #endif -#if !defined(_GNU_SOURCE) && !defined(__FBSDID) +#if !defined(__USE_GNU) && !(defined(__FBSDID) && defined(__BSD_VISIBLE)) int itoa(int number, char* out, int base); #endif diff --git a/test/Makefile b/test/Makefile index f36fb7d..0ead41e 100644 --- a/test/Makefile +++ b/test/Makefile @@ -2,13 +2,22 @@ OPT = -O2 DEBUG = 2 CFLAGS = -I../include -Wall -std=c99 ${OPT} LDFLAGS = -L../lib -LOADLIBES = -lpsyc -lm TARGETS = testServer testParser testMatch testRender testText isRoutingVar getVarType WRAPPER = DIET = diet PORT = 4440 +LOADLIBES = -lpsyc -lm +ifeq ($(shell uname),SunOS) + LOADLIBES_NET = ${LOADLIBES} -lsocket -lnsl +else + LOADLIBES_NET = ${LOADLIBES} +endif + all: ${TARGETS} +it: all + +testServer: LOADLIBES := ${LOADLIBES_NET} diet: WRAPPER = ${DIET} diet: all @@ -20,8 +29,6 @@ debug: all clean: rm -f ${TARGETS} -it: all - test: ${TARGETS} ./testRender ./testMatch @@ -53,4 +60,4 @@ srvstartr: ./testServer ${PORT} -r & srvkill: - killall testServer + pkill -x testServer From 16672ee1f7bc1045b5dc2fe316a2b1152178734f Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sun, 8 May 2011 16:49:24 +0200 Subject: [PATCH 176/378] makefile --- test/Makefile | 10 ++++++---- test/testServer.c | 4 ++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/test/Makefile b/test/Makefile index 0ead41e..e4965f5 100644 --- a/test/Makefile +++ b/test/Makefile @@ -2,16 +2,18 @@ OPT = -O2 DEBUG = 2 CFLAGS = -I../include -Wall -std=c99 ${OPT} LDFLAGS = -L../lib +LOADLIBES = -lpsyc -lm +LOADLIBES_NET = ${LOADLIBES} TARGETS = testServer testParser testMatch testRender testText isRoutingVar getVarType WRAPPER = DIET = diet PORT = 4440 +NC = nc +DIFF = diff -LOADLIBES = -lpsyc -lm ifeq ($(shell uname),SunOS) - LOADLIBES_NET = ${LOADLIBES} -lsocket -lnsl -else - LOADLIBES_NET = ${LOADLIBES} + LOADLIBES_NET := ${LOADLIBES_NET} -lsocket -lnsl + DIFF = gdiff endif all: ${TARGETS} diff --git a/test/testServer.c b/test/testServer.c index 41b6da7..255d425 100644 --- a/test/testServer.c +++ b/test/testServer.c @@ -434,6 +434,10 @@ int main (int argc, char **argv) case PSYC_PARSE_ROUTING: case PSYC_PARSE_ENTITY: case PSYC_PARSE_ENTITY_END: + oper = 0; + name.length = 0; + value.length = 0; + if (pname->length >= 5 && memcmp(pname->ptr, "_list", 5) == 0) { if (verbose >= 2) From 20e1cc1334269eda5437e9e871430026104b823c Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sun, 8 May 2011 16:50:14 +0200 Subject: [PATCH 177/378] makefile --- test/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/Makefile b/test/Makefile index e4965f5..dc6767f 100644 --- a/test/Makefile +++ b/test/Makefile @@ -47,10 +47,10 @@ nettest: srvstart pkt pktsplit srvkill nettestr: srvstartr pkt pktsplit srvkill pkt: - for f in packets/[0-9]*; do echo ">> $$f"; cat $$f | nc localhost ${PORT} | diff -u $$f -; done + for f in packets/[0-9]*; do echo ">> $$f"; cat $$f | nc localhost ${PORT} | ${DIFF} -u $$f -; done pktsplit: - for f in packets/[0-9]*; do echo ">> $$f"; ./splittest.pl $$f ${PORT} | diff -u $$f -; done + for f in packets/[0-9]*; do echo ">> $$f"; ./splittest.pl $$f ${PORT} | ${DIFF} -u $$f -; done pkterr: for f in packets/err-*; do echo ">> $$f"; cat $$f | nc localhost ${PORT}; done From 5d2b33fb765dc61ee1c75ea63e1a267c39d88bd2 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sun, 8 May 2011 18:45:41 +0200 Subject: [PATCH 178/378] splittest fix --- test/splittest.pl | 8 ++++---- test/testServer.c | 5 +++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/test/splittest.pl b/test/splittest.pl index 9794390..f467b67 100755 --- a/test/splittest.pl +++ b/test/splittest.pl @@ -4,8 +4,9 @@ use warnings; use IO::Socket; $| = 1; -print "Usage: splittest.pl [ [ [-v]]]\n" and exit unless @ARGV; -my $port = $ARGV[1] || 4440; +print "Usage: splittest.pl [[:] [ [-v]]]\n" and exit unless @ARGV; +my ($host, $port) = $ARGV[1] =~ /^(?:([a-z0-9.-]+):)?(\d+)$/i; +$host ||= 'localhost'; $port ||= 4440; my $length = int($ARGV[2] || 1); $length = 1 if $length < 1; my $verbose = $ARGV[3]; @@ -13,8 +14,7 @@ open FILE, '<', $ARGV[0] or die "$ARGV[0]: $!\n"; my $file = ''; $file .= $_ while ; close FILE; -my $s = IO::Socket::INET->new(Proto => "tcp", PeerAddr => "localhost", PeerPort => $port) or die "localhost:$port: $!\n"; -$s->autoflush(1); +my $s = IO::Socket::INET->new(Proto => "tcp", PeerAddr => $host, PeerPort => $port) or die "$host:$port: $!\n"; my $c = 0; while ($c < length $file) { diff --git a/test/testServer.c b/test/testServer.c index 255d425..4d15d68 100644 --- a/test/testServer.c +++ b/test/testServer.c @@ -233,6 +233,11 @@ int main (int argc, char **argv) } else { + if (verbose >= 2) + printf("> %ld bytes\n", nbytes); + if (verbose >= 3) + printf("> [%.*s]", (int)nbytes, recvbuf); + // we got some data from a client parsebuf = recvbuf - contbytes; psyc_setParseBuffer2(&parsers[i], parsebuf, contbytes + nbytes); From 16fdc8691a9ebce99e45ca1697325bbd5cbada8b Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sun, 8 May 2011 20:17:56 +0200 Subject: [PATCH 179/378] test: makefile improvements --- Makefile | 4 +--- test/Makefile | 27 +++++++++++++++------------ 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/Makefile b/Makefile index 5cb0938..c3343d6 100644 --- a/Makefile +++ b/Makefile @@ -17,9 +17,7 @@ testdebug: debug ${MAKE} -C test debug test: all - ${MAKE} -C test test - ${MAKE} -C test nettest - ${MAKE} -C test nettestr + ${MAKE} -C test test nettest doc: doxygen diff --git a/test/Makefile b/test/Makefile index dc6767f..722ab38 100644 --- a/test/Makefile +++ b/test/Makefile @@ -37,29 +37,32 @@ test: ${TARGETS} ./testText ./isRoutingVar ./getVarType - for f in packets/[0-9]*; do echo ">> $$f"; ./testParser $$f; done - for f in packets/[0-9]*; do echo ">> $$f"; ./testParser $$f -r; done + x=0; for f in packets/[0-9]*; do echo ">> $$f"; ./testParser $$f; x=$$((x+$$?)); done; exit $$x + x=0; for f in packets/[0-9]*; do echo ">> $$f"; ./testParser $$f -r; x=$$((x+$$?)); done; exit $$x -# test packet parsing & rendering with the test server -nettest: srvstart pkt pktsplit srvkill +nettest: nettestfull nettestsplit -# same test but parse routing headers only -nettestr: srvstartr pkt pktsplit srvkill +nettestrun: srvstart pkt srvkill + +nettestfull: + ${MAKE} nettestrun + ${MAKE} nettestrun srv_args=r + +nettestsplit: + for n in 1 2 3 4 5; do ${MAKE} nettestrun srv_recvbuf=$$n && ${MAKE} nettestrun srv_args=r srv_recvbuf=$$n || exit $$?; done pkt: - for f in packets/[0-9]*; do echo ">> $$f"; cat $$f | nc localhost ${PORT} | ${DIFF} -u $$f -; done + x=0; for f in packets/[0-9]*; do echo ">> $$f"; cat $$f | nc localhost ${PORT} | ${DIFF} -u $$f -; x=$$((x+$$?)); done; exit $$x pktsplit: - for f in packets/[0-9]*; do echo ">> $$f"; ./splittest.pl $$f ${PORT} | ${DIFF} -u $$f -; done + x=0; for f in packets/[0-9]*; do echo ">> $$f"; ./splittest.pl $$f ${PORT} | ${DIFF} -u $$f -; x=$$((x+$$?)); done; exit $$x pkterr: for f in packets/err-*; do echo ">> $$f"; cat $$f | nc localhost ${PORT}; done srvstart: - ./testServer ${PORT} & - -srvstartr: - ./testServer ${PORT} -r & + pkill -x testServer; exit 0 + ./testServer ${PORT} -${srv_args} ${srv_recvbuf} & srvkill: pkill -x testServer From fa877024ae3f0618913049b0d00610f4b7da1b5b Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sun, 8 May 2011 22:08:48 +0200 Subject: [PATCH 180/378] parser: fix for partial content in routing-only mode --- src/parser.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/parser.c b/src/parser.c index 575a546..4e50dce 100644 --- a/src/parser.c +++ b/src/parser.c @@ -409,6 +409,9 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, else // Search for the terminator. { size_t datac = state->cursor; // start of data + if (state->flags & PSYC_PARSE_ROUTING_ONLY) + state->startc = datac; // in routing-only mode restart from the start of data + while (1) { uint8_t nl = state->buffer.ptr[state->cursor] == '\n'; From 697e597e61dcb543ced498c865f5aa91bd5cd23c Mon Sep 17 00:00:00 2001 From: Marenz Date: Sun, 8 May 2011 22:20:01 +0200 Subject: [PATCH 181/378] Added readme --- README | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 README diff --git a/README b/README new file mode 100644 index 0000000..c84e3dd --- /dev/null +++ b/README @@ -0,0 +1,62 @@ += libpsyc Readme File = + +libpsyc implements various functions required to use psyc. +See http://about.psyc.eu/libpsyc for more information on the library +See http://about.psyc.eu/Specification for more information on the new psyc +specification +See http://about.psyc.eu for information on psyc in general. + +The plain C API located in the include/psyc directory along with the file psyc.h +is primary intended to be used for binding with other languages and frameworks. + +Available bindings are located in include/ where name is the lanugage or +framework. + + +== Directory Overview == + +doc — where the documentation will be put after generation +include — contains all bindings and the core C API for the library +lib — where the compiled library will be put +src — contains the sourcecode of the library +test — contains test sourcecodes and test input files + +== Compiling libpsyc == + +Type + + make + +and you are done. +Other possible targets include: + + make diet — compile with diet libc + make test — compile and run the test + make doc — generate the API documentation (will be put in the doc folder) + make help — display the possible targets + +== Contributors And Contribution == + +The library is being developed by + +* tg — psyc://tgbit.net/~tg + xmpp:tg@tgbit.net + irc://tgbit.net/~tg +* lynx — psyc://psyced.org/~lynx + xmpp:lynx@psyced.org + irc://psyced.org/~lynX +* Marenz — psyc://supraverse.net/~marenz + xmpp:marenz@supraverse.net + irc://supraverse.net/~marenz + +If you created new bindings, patches or anything other that you think should go +into the library, contact either anyone of us directly or just join the +developement room at + + psyc://psyced.org/@welcome + xmpp:*welcome@psyced.org (jabber is known to have problems sometimes) + irc://psyced.org/welcome + +== Licence == + +— To be discussed — From ec51f6c08dc6aac6a8b867bb9c06c329bc8d4543 Mon Sep 17 00:00:00 2001 From: Marenz Date: Sun, 8 May 2011 22:26:38 +0200 Subject: [PATCH 182/378] removed aliases for nicknames --- README | 6 ------ 1 file changed, 6 deletions(-) diff --git a/README b/README index c84e3dd..7523336 100644 --- a/README +++ b/README @@ -40,14 +40,8 @@ Other possible targets include: The library is being developed by * tg — psyc://tgbit.net/~tg - xmpp:tg@tgbit.net - irc://tgbit.net/~tg * lynx — psyc://psyced.org/~lynx - xmpp:lynx@psyced.org - irc://psyced.org/~lynX * Marenz — psyc://supraverse.net/~marenz - xmpp:marenz@supraverse.net - irc://supraverse.net/~marenz If you created new bindings, patches or anything other that you think should go into the library, contact either anyone of us directly or just join the From 90f45aa424f468a3025fdf9b91396ac20ee0c046 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Sun, 8 May 2011 22:31:54 +0200 Subject: [PATCH 183/378] + --- README | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/README b/README index c84e3dd..119feec 100644 --- a/README +++ b/README @@ -1,13 +1,14 @@ = libpsyc Readme File = libpsyc implements various functions required to use psyc. -See http://about.psyc.eu/libpsyc for more information on the library -See http://about.psyc.eu/Specification for more information on the new psyc -specification -See http://about.psyc.eu for information on psyc in general. + +See http://about.psyc.eu/libpsyc for more information on the library. +See http://about.psyc.eu/Specification for more information + on the new PSYC specification. +See http://about.psyc.eu for information on PSYC in general. The plain C API located in the include/psyc directory along with the file psyc.h -is primary intended to be used for binding with other languages and frameworks. +is primarily intended to be used for binding with other languages and frameworks. Available bindings are located in include/ where name is the lanugage or framework. @@ -15,11 +16,11 @@ framework. == Directory Overview == -doc — where the documentation will be put after generation -include — contains all bindings and the core C API for the library -lib — where the compiled library will be put -src — contains the sourcecode of the library -test — contains test sourcecodes and test input files +doc -- where the documentation will be put after generation +include -- contains all bindings and the core C API for the library +lib -- where the compiled library will be put +src -- contains the sourcecode of the library +test -- contains test sourcecodes and test input files == Compiling libpsyc == @@ -30,22 +31,26 @@ Type and you are done. Other possible targets include: - make diet — compile with diet libc - make test — compile and run the test - make doc — generate the API documentation (will be put in the doc folder) - make help — display the possible targets + make diet -- compile with diet libc + make test -- compile and run the test + make doc -- generate the API documentation (will be put in the doc folder) + make help -- display the possible targets + +== Requirements == + +libpsyc is currently known to compile under Linux and SunOS. == Contributors And Contribution == The library is being developed by -* tg — psyc://tgbit.net/~tg +* tg -- psyc://tgbit.net/~tg xmpp:tg@tgbit.net irc://tgbit.net/~tg -* lynx — psyc://psyced.org/~lynx +* lynx -- psyc://psyced.org/~lynx xmpp:lynx@psyced.org irc://psyced.org/~lynX -* Marenz — psyc://supraverse.net/~marenz +* Marenz -- psyc://supraverse.net/~marenz xmpp:marenz@supraverse.net irc://supraverse.net/~marenz @@ -59,4 +64,4 @@ developement room at == Licence == -— To be discussed — +-- To be discussed -- From 1fb9633a96643371ef3951e6876e156bc8d68f5b Mon Sep 17 00:00:00 2001 From: Marenz Date: Sun, 8 May 2011 22:32:16 +0200 Subject: [PATCH 184/378] removed UTF character for people from <1990 --- README | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/README b/README index 7523336..a85a0b3 100644 --- a/README +++ b/README @@ -15,11 +15,11 @@ framework. == Directory Overview == -doc — where the documentation will be put after generation -include — contains all bindings and the core C API for the library -lib — where the compiled library will be put -src — contains the sourcecode of the library -test — contains test sourcecodes and test input files +doc - where the documentation will be put after generation +include - contains all bindings and the core C API for the library +lib - where the compiled library will be put +src - contains the sourcecode of the library +test - contains test sourcecodes and test input files == Compiling libpsyc == @@ -30,18 +30,18 @@ Type and you are done. Other possible targets include: - make diet — compile with diet libc - make test — compile and run the test - make doc — generate the API documentation (will be put in the doc folder) - make help — display the possible targets + make diet - compile with diet libc + make test - compile and run the test + make doc - generate the API documentation (will be put in the doc folder) + make help - display the possible targets == Contributors And Contribution == The library is being developed by -* tg — psyc://tgbit.net/~tg -* lynx — psyc://psyced.org/~lynx -* Marenz — psyc://supraverse.net/~marenz +* tg - psyc://tgbit.net/~tg +* lynx - psyc://psyced.org/~lynx +* Marenz - psyc://supraverse.net/~marenz If you created new bindings, patches or anything other that you think should go into the library, contact either anyone of us directly or just join the @@ -53,4 +53,4 @@ developement room at == Licence == -— To be discussed — +- To be discussed - From 2a709e57b58304afcbb8b4fb51f618f502523d2e Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Sun, 8 May 2011 22:33:21 +0200 Subject: [PATCH 185/378] marenz, you die. you are resurrected. --- README | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README b/README index 9b07d8a..7b31ad6 100644 --- a/README +++ b/README @@ -1,6 +1,6 @@ -= libpsyc Readme File = += libpsyc README file = -libpsyc implements various functions required to use psyc. +libpsyc implements various functions required to use PSYC. See http://about.psyc.eu/libpsyc for more information on the library. See http://about.psyc.eu/Specification for more information From 642311fcaeab01da2f75a2a34f6d2ce55f957625 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sun, 8 May 2011 22:53:45 +0200 Subject: [PATCH 186/378] test: kill testserver on error --- test/Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/Makefile b/test/Makefile index 722ab38..e0ae750 100644 --- a/test/Makefile +++ b/test/Makefile @@ -45,11 +45,12 @@ nettest: nettestfull nettestsplit nettestrun: srvstart pkt srvkill nettestfull: - ${MAKE} nettestrun - ${MAKE} nettestrun srv_args=r + ${MAKE} nettestrun; x=$$?; pkill -x testServer; exit $$x + ${MAKE} nettestrun srv_args=r; x=$$?; pkill -x testServer; exit $$x +split_max = 10 nettestsplit: - for n in 1 2 3 4 5; do ${MAKE} nettestrun srv_recvbuf=$$n && ${MAKE} nettestrun srv_args=r srv_recvbuf=$$n || exit $$?; done + x=0; for n in `seq 1 ${split_max}`; do ${MAKE} nettestrun srv_recvbuf=$$n && ${MAKE} nettestrun srv_args=r srv_recvbuf=$$n || break; done; x=$$?; pkill -x testServer; exit $$x pkt: x=0; for f in packets/[0-9]*; do echo ">> $$f"; cat $$f | nc localhost ${PORT} | ${DIFF} -u $$f -; x=$$((x+$$?)); done; exit $$x From b830bdf3c1a8059f61d25585aced0c206004de6c Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sun, 8 May 2011 23:08:00 +0200 Subject: [PATCH 187/378] nettest: not parallel --- test/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/Makefile b/test/Makefile index e0ae750..749fd75 100644 --- a/test/Makefile +++ b/test/Makefile @@ -40,6 +40,8 @@ test: ${TARGETS} x=0; for f in packets/[0-9]*; do echo ">> $$f"; ./testParser $$f; x=$$((x+$$?)); done; exit $$x x=0; for f in packets/[0-9]*; do echo ">> $$f"; ./testParser $$f -r; x=$$((x+$$?)); done; exit $$x +.NOTPARALLEL: nettestrun + nettest: nettestfull nettestsplit nettestrun: srvstart pkt srvkill From 19d0d000f06cd46fb9dbb0646bca480db85cafc2 Mon Sep 17 00:00:00 2001 From: Marenz Date: Sun, 8 May 2011 23:40:26 +0200 Subject: [PATCH 188/378] moved debug.h lib.h to src --- {include/psyc => src}/debug.h | 0 {include/psyc => src}/lib.h | 2 +- src/match.c | 2 +- src/packet.c | 2 +- src/parser.c | 2 +- src/render.c | 6 +++--- src/text.c | 2 +- src/variable.c | 2 +- test/Makefile | 2 +- test/getVarType.c | 2 +- test/isRoutingVar.c | 2 +- test/testMatch.c | 2 +- test/testRender.c | 2 +- test/testText.c | 2 +- 14 files changed, 15 insertions(+), 15 deletions(-) rename {include/psyc => src}/debug.h (100%) rename {include/psyc => src}/lib.h (96%) diff --git a/include/psyc/debug.h b/src/debug.h similarity index 100% rename from include/psyc/debug.h rename to src/debug.h diff --git a/include/psyc/lib.h b/src/lib.h similarity index 96% rename from include/psyc/lib.h rename to src/lib.h index dfa017b..ba7808c 100644 --- a/include/psyc/lib.h +++ b/src/lib.h @@ -3,7 +3,7 @@ #ifndef PSYC_LIB_H # define PSYC_LIB_H -#include "../psyc.h" +#include #include "./debug.h" #include diff --git a/src/match.c b/src/match.c index 22d6ced..7fc3c25 100644 --- a/src/match.c +++ b/src/match.c @@ -1,4 +1,4 @@ -#include "psyc/lib.h" +#include "lib.h" int psyc_inherits(char* sho, size_t slen, char* lon, size_t llen) { diff --git a/src/packet.c b/src/packet.c index aed1aa5..fe7c13e 100644 --- a/src/packet.c +++ b/src/packet.c @@ -1,4 +1,4 @@ -#include +#include "lib.h" #include #include diff --git a/src/parser.c b/src/parser.c index 4e50dce..b447750 100644 --- a/src/parser.c +++ b/src/parser.c @@ -5,7 +5,7 @@ #include #endif -#include +#include "lib.h" #include #define ADVANCE_CURSOR_OR_RETURN(ret) \ diff --git a/src/render.c b/src/render.c index 5990f4b..c0e0a77 100644 --- a/src/render.c +++ b/src/render.c @@ -1,6 +1,6 @@ -#include "psyc/lib.h" -#include "psyc/render.h" -#include "psyc/syntax.h" +#include "lib.h" +#include +#include psycRenderRC psyc_renderList (psycList *list, char *buffer, size_t buflen) { diff --git a/src/text.c b/src/text.c index 674890b..70a437b 100644 --- a/src/text.c +++ b/src/text.c @@ -1,4 +1,4 @@ -#include +#include "lib.h" #include psycTextRC psyc_text (psycTextState *state, psycTextCB getValue) diff --git a/src/variable.c b/src/variable.c index a30805d..a1e4845 100644 --- a/src/variable.c +++ b/src/variable.c @@ -1,4 +1,4 @@ -#include +#include "lib.h" #include /// Routing variables in alphabetical order. diff --git a/test/Makefile b/test/Makefile index 749fd75..8217eb5 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,6 +1,6 @@ OPT = -O2 DEBUG = 2 -CFLAGS = -I../include -Wall -std=c99 ${OPT} +CFLAGS = -I../include -I../src -Wall -std=c99 ${OPT} LDFLAGS = -L../lib LOADLIBES = -lpsyc -lm LOADLIBES_NET = ${LOADLIBES} diff --git a/test/getVarType.c b/test/getVarType.c index bdf6d3c..d0fd152 100644 --- a/test/getVarType.c +++ b/test/getVarType.c @@ -2,7 +2,7 @@ #include #include #include -#include "../include/psyc/lib.h" +#include int main() { unless (psyc_getVarType(PSYC_C2ARG("_list"))) return 1; diff --git a/test/isRoutingVar.c b/test/isRoutingVar.c index f2d0ceb..9c31685 100644 --- a/test/isRoutingVar.c +++ b/test/isRoutingVar.c @@ -2,7 +2,7 @@ #include #include #include -#include "../include/psyc/lib.h" +#include int main() { #if 0 diff --git a/test/testMatch.c b/test/testMatch.c index cdac58a..6874e14 100644 --- a/test/testMatch.c +++ b/test/testMatch.c @@ -1,5 +1,5 @@ #include -#include "../include/psyc/lib.h" +#include int main() { if (psyc_matches(PSYC_C2ARG("_failure_delivery"), PSYC_C2ARG("_failure_unsuccessful_delivery_death"))) return 1; diff --git a/test/testRender.c b/test/testRender.c index edfb798..1f1f61b 100644 --- a/test/testRender.c +++ b/test/testRender.c @@ -1,6 +1,6 @@ #include -#include +#include #include #include diff --git a/test/testText.c b/test/testText.c index e5aff36..21f732d 100644 --- a/test/testText.c +++ b/test/testText.c @@ -1,6 +1,6 @@ #include -#include +#include #include #define BUFSIZE 512 From 76f8539adef8c211795099d52f973f37d6d91ffe Mon Sep 17 00:00:00 2001 From: Marenz Date: Sun, 8 May 2011 23:56:33 +0200 Subject: [PATCH 189/378] adde C API section to README --- README | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/README b/README index 7b31ad6..2140aa1 100644 --- a/README +++ b/README @@ -10,9 +10,20 @@ See http://about.psyc.eu for information on PSYC in general. The plain C API located in the include/psyc directory along with the file psyc.h is primarily intended to be used for binding with other languages and frameworks. -Available bindings are located in include/ where name is the lanugage or +Available bindings are located in include/ where name is the language or framework. +== C API == + +The "plain C API" is a very low-level API intended to be used for bindings. +To access a certain module of the library, just include the according header +file from the psyc directory: + +parser.h -- parse psyc packets +render.h -- render psyc packets +text.h -- text template functions +packet.h -- structures for render.h and functions to initialize them +syntax.h -- definitions and constants related to parsing and rendering == Directory Overview == From 638c4b94aa2367b3f07849502c52e7a514b33c73 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 9 May 2011 00:01:23 +0200 Subject: [PATCH 190/378] + --- include/d/psyc/parser.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/d/psyc/parser.d b/include/d/psyc/parser.d index 465a641..72770fd 100644 --- a/include/d/psyc/parser.d +++ b/include/d/psyc/parser.d @@ -11,7 +11,7 @@ import psyc.common; */ /** - * @defgroup parsing-d Parsing Functions + * @defgroup parsing-d D Parsing Functions * * This module contains all parsing functions. * @{ From a6e273989c94cbed3d59689742a38def62bba09d Mon Sep 17 00:00:00 2001 From: Marenz Date: Mon, 9 May 2011 00:14:48 +0200 Subject: [PATCH 191/378] minor formating changes --- include/psyc/parser.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index b27912e..4206913 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -106,7 +106,7 @@ typedef enum PSYC_PARSE_LIST_ERROR_LEN = -4, PSYC_PARSE_LIST_ERROR_TYPE = -3, PSYC_PARSE_LIST_ERROR_NAME = -2, - PSYC_PARSE_LIST_ERROR= -1, + PSYC_PARSE_LIST_ERROR = -1, /// Completed parsing a list element. PSYC_PARSE_LIST_ELEM = 1, /// Reached end of buffer. @@ -293,8 +293,8 @@ const char * psyc_getParseRemainingBuffer (psycParseState *state) * Generalized line-based packet parser. * * @param state An initialized psycParseState - * @param operator A pointer to a character. In case of a variable, it will - * be set to the operator of that variable + * @param oper A pointer to a character. In case of a variable, it will + * be set to the operator of that variable * @param name A pointer to a psycString. It will point to the name of * the variable or method and its length will be set accordingly * @param value A pointer to a psycString. It will point to the From 4db0c4fd9c0f57cfac288358d7d9bb3b3e5a47c5 Mon Sep 17 00:00:00 2001 From: Marenz Date: Mon, 9 May 2011 00:15:03 +0200 Subject: [PATCH 192/378] synchronized the D binding --- include/d/psyc/common.d | 202 ++++------------------------- include/d/psyc/parser.d | 273 ++++++++++++++++++++++++++++++---------- 2 files changed, 232 insertions(+), 243 deletions(-) diff --git a/include/d/psyc/common.d b/include/d/psyc/common.d index efb5a90..41ad6a5 100644 --- a/include/d/psyc/common.d +++ b/include/d/psyc/common.d @@ -1,20 +1,9 @@ -/** @file d/.d +/** @file d/psyc/common.d * * @brief Main PSYC interface providing crucial functionality. */ -/** @mainpage PSYC Core Library - * - * @section intro_sec Introduction - * - * This is the introduction. - * - * @section install_sec Installation - * - * @subsection step1 Step 1: Opening the box - * - * etc... - */ + module psyc.common; @@ -33,13 +22,13 @@ enum Bool */ enum Part { - PART_RESET = -1, - PART_ROUTING, - PART_LENGTH, - PART_CONTENT, - PART_METHOD, - PART_DATA, - PART_END, + RESET = -1, + ROUTING = 0, + LENGTH = 1, + CONTENT = 2, + METHOD = 3, + DATA = 4, + END = 5, } /** @@ -52,19 +41,19 @@ enum Part */ enum Type { - TYPE_UNKNOWN, - TYPE_AMOUNT, - TYPE_COLOR, - TYPE_DATE, - TYPE_DEGREE, - TYPE_ENTITY, - TYPE_FLAG, - TYPE_LANGUAGE, - TYPE_LIST, - TYPE_NICK, - TYPE_PAGE, - TYPE_UNIFORM, - TYPE_TIME, + UNKNOWN, + AMOUNT, + COLOR, + DATE, + DEGREE, + ENTITY, + FLAG, + LANGUAGE, + LIST, + NICK, + PAGE, + UNIFORM, + TIME, } /** @@ -77,32 +66,10 @@ enum ListType LIST_BINARY = 2, } -enum ModifierFlag -{ - MODIFIER_CHECK_LENGTH = 0, - MODIFIER_NEED_LENGTH = 1, - MODIFIER_NO_LENGTH = 2, - MODIFIER_ROUTING = 3, -} - -enum ListFlag -{ - LIST_CHECK_LENGTH = 0, - LIST_NEED_LENGTH = 1, - LIST_NO_LENGTH = 2, -} - -enum PacketFlag -{ - PACKET_CHECK_LENGTH = 0, - PACKET_NEED_LENGTH = 1, - PACKET_NO_LENGTH = 2, -} - struct String { size_t length; - char *ptr; + ubyte *ptr; } struct MatchVar @@ -111,98 +78,11 @@ struct MatchVar int value; } -/** -* Shortcut for creating a String. - * - * @param memory Pointer to the buffer. - * @param length Length of that buffer. - * - * @return An instance of the String struct. - */ -String newString (char *str, size_t strlen); - -/* intermediate struct for a PSYC variable modification */ -struct Modifier +int psyc_version() { - char oper; // not call it 'operator' as C++ may not like that.. - String name; - String value; - ModifierFlag flag; + return 1; } -struct Header -{ - size_t lines; - Modifier *modifiers; -} - -struct List -{ - size_t num_elems; - String *elems; - size_t length; - ListFlag flag; -} - -/* intermediate struct for a PSYC packet */ -struct Packet -{ - Header routing; ///< Routing header. - Header entity; ///< Entity header. - String method; - String data; - size_t routingLength; ///< Length of routing part. - size_t contentLength; ///< Length of content part. - size_t length; ///< Total length of packet. - PacketFlag flag; -} - -int psyc_version(); - -/** Check if a modifier needs length */ -ModifierFlag checkModifierLength(Modifier *m); - -/** Get the total length of a modifier. */ -size_t getModifierLength(Modifier *m); - -/** Create new modifier */ -Modifier newModifier(char oper, String *name, String *value, - ModifierFlag flag); - -/** Create new modifier */ -Modifier newModifier2(char oper, - char *name, size_t namelen, - char *value, size_t valuelen, - ModifierFlag flag); - -/** Check if a list needs length */ -ListFlag checkListLength(List *list); - -/** Get the total length of a list. */ -ListFlag getListLength(List *list); - -/** Check if a packet needs length */ -PacketFlag checkPacketLength(Packet *p); - -/** Calculate and set the length of packet parts and total packet length */ -size_t setPacketLength(Packet *p); - -/** Create new list */ -List newList(String *elems, size_t num_elems, ListFlag flag); - -/** Create new packet */ -Packet newPacket(Header *routing, - Header *entity, - String *method, String *data, - PacketFlag flag); - -/** Create new packet */ -Packet newPacket2(Modifier *routing, size_t routinglen, - Modifier *entity, size_t entitylen, - char *method, size_t methodlen, - char *data, size_t datalen, - PacketFlag flag); - /// Routing vars in alphabetical order. extern (C) String routingVars[]; extern (C) MatchVar varTypes[]; @@ -221,40 +101,12 @@ Type getVarType(char *name, size_t len); * Checks if long keyword string inherits from short keyword string. */ int inherits(char *sho, size_t slen, - char *lon, size_t llen); + char *lon, size_t llen); /** * Checks if short keyword string matches long keyword string. */ int matches(char *sho, size_t slen, - char *lon, size_t llen); + char *lon, size_t llen); -/** - * Callback for text() that produces a value for a match. - * - * The application looks up a match such as _fruit from [_fruit] and - * if found writes its current value from its variable store into the - * outgoing buffer.. "Apple" for example. The template returns the - * number of bytes written. 0 is a legal return value. Should the - * callback return -1, text leaves the original template text as is. - */ -alias extern (C) int function (char *match, size_t mlen, char **buffer, size_t *blen) textCB; - -/** - * Fills out text templates by asking a callback for content. - * - * Copies the contents of the template into the buffer while looking - * for braceOpen and braceClose strings and calling the callback for - * each enclosed string between these braces. Should the callback - * return -1, the original template text is copied as is. - * - * By default PSYC's "[" and "]" are used but you can provide any other - * brace strings such as "${" and "}" or "". - * - * See also http://about..eu/text - */ -int text(char *_template, size_t tlen, - char **buffer, size_t *blen, - textCB lookupValue, - char *braceOpen, char *braceClose); diff --git a/include/d/psyc/parser.d b/include/d/psyc/parser.d index 465a641..244aa01 100644 --- a/include/d/psyc/parser.d +++ b/include/d/psyc/parser.d @@ -21,8 +21,8 @@ extern (C): enum ParseFlag { - PARSE_HEADER_ONLY = 1, - PARSE_BEGIN_AT_CONTENT = 2, + ROUTING_ONLY = 1, + START_AT_CONTENT = 2, } /** @@ -31,43 +31,66 @@ enum ParseFlag */ enum ParseRC { - PARSE_ERROR_END = -9, - PARSE_ERROR_BODY = -8, - PARSE_ERROR_METHOD = -7, - PARSE_ERROR_MOD_NL = -6, - PARSE_ERROR_MOD_LEN = -5, - PARSE_ERROR_MOD_TAB = -4, - PARSE_ERROR_MOD_NAME = -3, - PARSE_ERROR_LENGTH = -2, - PARSE_ERROR = -1, - PARSE_SUCCESS = 0, +/// Error, packet is not ending with a valid delimiter. + ERROR_END = -8, +/// Error, expected NL after the method. + ERROR_METHOD = -7, +/// Error, expected NL after a modifier. + ERROR_MOD_NL = -6, +/// Error, modifier length is not numeric. + ERROR_MOD_LEN = -5, +/// Error, expected TAB before modifier value. + ERROR_MOD_TAB = -4, +/// Error, modifier name is missing. + ERROR_MOD_NAME = -3, +/// Error, expected NL after the content length. + ERROR_LENGTH = -2, +/// Error in packet. + ERROR = -1, +// Success, used internally. + SUCCESS = 0, /// Buffer contains insufficient amount of data. /// Fill another buffer and concatenate it with the end of the current buffer, /// from the cursor position to the end. - PARSE_INSUFFICIENT = 1, + INSUFFICIENT = 1, /// Routing modifier parsing done. /// Operator, name & value contains the respective parts. - PARSE_ROUTING = 2, -/// Entity modifier parsing done. -/// Operator, name & value contains the respective parts. - PARSE_ENTITY = 3, -/// Entity modifier parsing is incomplete. + ROUTING = 2, +/// Start of an incomplete entity modifier. /// Operator & name are complete, value is incomplete. - PARSE_ENTITY_INCOMPLETE = 4, -/// Body parsing done, name contains method, value contains body. - PARSE_BODY = 5, -/// Body parsing is incomplete, name contains method, value contains part of the body. - PARSE_BODY_INCOMPLETE = 6, -/// Content parsing done, value contains the whole content. -/// Used when PSYC_PARSE_ROUTING_ONLY is set. - PARSE_CONTENT = 5, -/// Content parsing is incomplete, value contains part of content. -/// Used when PSYC_PARSE_ROUTING_ONLY is set. - PARSE_CONTENT_INCOMPLETE = 6, -/// Reached end of packet, parsing done. - PARSE_COMPLETE = 7, -/// Binary value parsing incomplete, used internally. - PARSE_INCOMPLETE = 8, + ENTITY_START = 3, +/// Continuation of an incomplete entity modifier. + ENTITY_CONT = 4, +/// End of an incomplete entity modifier. + ENTITY_END = 5, +/// Entity modifier parsing done in one go. +/// Operator, name & value contains the respective parts. + ENTITY = 6, +/// Start of an incomplete body. +/// Name contains method, value contains part of the body. + BODY_START = 7, +/// Continuation of an incomplete body. + BODY_CONT = 8, +/// End of an incomplete body. + BODY_END = 9, +/// Body parsing done in one go, name contains method, value contains body. + BODY = 10, +/// Start of an incomplete content, value contains part of content. +/// Used when ROUTING_ONLY is set. + CONTENT_START = 7, +/// Continuation of an incomplete body. +/// Used when ROUTING_ONLY is set. + CONTENT_CONT = 8, +/// End of an incomplete body. +/// Used when ROUTING_ONLY is set. + CONTENT_END = 9, +/// Content parsing done in one go, value contains the whole content. +/// Used when ROUTING_ONLY is set. + CONTENT = 10, +// Binary value parsing complete, used internally. + COMPLETE = 11, +// Binary value parsing incomplete, used internally. + INCOMPLETE = 12, } /** @@ -76,17 +99,17 @@ enum ParseRC */ enum ParseListRC { - PARSE_LIST_ERROR_DELIM = -5, - PARSE_LIST_ERROR_LEN = -4, - PARSE_LIST_ERROR_TYPE = -3, - PARSE_LIST_ERROR_NAME = -2, - PARSE_LIST_ERROR= -1, + LIST_ERROR_DELIM = -5, + LIST_ERROR_LEN = -4, + LIST_ERROR_TYPE = -3, + LIST_ERROR_NAME = -2, + LIST_ERROR = -1, /// Completed parsing a list element. - PARSE_LIST_ELEM = 1, + LIST_ELEM = 1, /// Reached end of buffer. - PARSE_LIST_END = 2, + LIST_END = 2, /// Binary list is incomplete. - PARSE_LIST_INCOMPLETE = 3, + LIST_INCOMPLETE = 3, } /** @@ -106,6 +129,118 @@ struct ParseState Bool 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 + Bool valueLengthFound; ///< is there a length given for this modifier? + + /** + * Initiates the state struct. + */ + static ParseState opCall ( ) + { + ParseState inst; + return inst; + } + + /** + * Initializes the state struct with flags. + * + * @param flags Flags to be set for the parser, see ParseFlag. + */ + static ParseState opCall ( ubyte flags ) + { + ParseState inst; + inst.flags = flags; + + if (flags & ParseFlag.ROUTING_ONLY) + inst.part = Part.CONTENT; + + return inst; + } + + /** + * Sets a new buffer in the parser state struct with data to be parsed. + * + * @param buffer the buffer that should be parsed now + * @see String + */ + void setParseBuffer ( String buffer ) + { + this.buffer = buffer; + this.cursor = 0; + + if (this.flags & ParseFlag.START_AT_CONTENT) + { + this.contentLength = buffer.length; + this.contentLengthFound = Bool.TRUE; + } + } + + /** + * Sets a new buffer in the parser state struct with data to be parsed. + * + * @param buffer the buffer that should be parsed now + * @see String + */ + void setParseBuffer ( ubyte[] buffer ) + { + this.setParseBuffer(*(cast(String*) &buffer)); + } + + /** + * Sets a new buffer in the parser state struct with data to be parsed. + * + * @param buffer pointer to the buffer that should be parsed now + * @param length length of the buffer + */ + void setParseBuffer ( ubyte* buffer, size_t length ) + { + this.setParseBuffer(String(length, cast(ubyte*)buffer)); + } + + size_t getContentLength ( ) + { + return this.contentLength; + } + + bool isContentLengthFound ( ) + { + return this.contentLengthFound == Bool.TRUE; + } + + size_t getValueLength ( ) + { + return this.valueLength; + } + + bool isValueLengthFound ( ) + { + return this.valueLengthFound == Bool.TRUE; + } + + size_t getCursor ( ) + { + return this.cursor; + } + + size_t getBufferLength ( ) + { + return this.buffer.length; + } + + size_t getRemainingLength ( ) + { + return this.buffer.length - this.cursor; + } + + ubyte* getRemainingBuffer ( ) + { + return this.buffer.ptr + this.cursor; + } + + void getRemainingBuffer ( ref ubyte[] buf ) + { + buf = this.buffer.ptr[cursor .. getRemainingLength()]; + } + } /** @@ -120,35 +255,37 @@ struct ParseListState size_t elemParsed; ///< number of bytes parsed from the elem so far size_t elemLength; ///< expected length of the elem + + /** + * Sets a new buffer with data to be parsed + * @param buffer the buffer to be parsed + */ + void setBuffer ( String buffer ) + { + this.buffer = buffer; + this.cursor = 0; + } + + /** + * Sets a new buffer with data to be parsed + * @param buffer the buffer to be parsed + */ + void setBuffer ( ubyte[] buffer ) + { + this.setBuffer(*(cast(String*) &buffer)); + } + + /** + * Sets a new buffer with data to be parsed + * @param buffer pointer to the buffer to be parsed + * @param length size of the buffer + */ + void setBuffer ( ubyte* buffer, size_t length ) + { + this.setBuffer(String(length, buffer)); + } } -/** - * Initiates the state struct. - * - * @param state Pointer to the state struct that should be initiated. - */ -void psyc_initParseState (ParseState* state); - -/** - * Initiates the state struct with flags. - * - * @param state Pointer to the state struct that should be initiated. - * @param flags Flags to be set for the parser, see ParseFlag. - */ -void psyc_initParseState2 (ParseState* state, ubyte flags); - -/** - * Initiates the list state struct. - * - * @param state Pointer to the list state struct that should be initiated. - */ -void psyc_initParseListState (ParseListState* state); - -void psyc_nextParseBuffer (ParseState* state, String newBuf); - -void psyc_nextParseListBuffer (ParseListState* state, String newBuf); - -size_t psyc_getContentLength (ParseState* s); /** * Parse PSYC packets. From f56343e7714c9e17720797225eee0c56bcd7b9d3 Mon Sep 17 00:00:00 2001 From: Marenz Date: Mon, 9 May 2011 00:21:22 +0200 Subject: [PATCH 193/378] excluding D from documentation generation --- Doxyfile | 64 +++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 17 deletions(-) diff --git a/Doxyfile b/Doxyfile index c504594..df1212c 100644 --- a/Doxyfile +++ b/Doxyfile @@ -1,4 +1,4 @@ -# Doxyfile 1.7.3 +# Doxyfile 1.7.4 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project @@ -33,8 +33,8 @@ PROJECT_NAME = libpsyc PROJECT_NUMBER = 0.1 -# Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer # a quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = "PSYC core library" @@ -286,6 +286,13 @@ DISTRIBUTE_GROUP_DOC = NO SUBGROUPING = YES +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct @@ -461,10 +468,10 @@ SORT_GROUP_NAMES = NO SORT_BY_SCOPE_NAME = NO -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to # do proper type resolution of all parameters of a function it will reject a -# match between the prototype and the implementation of a member function even -# if there is only one candidate or it is obvious which candidate to choose +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose # by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen # will still accept a match between prototype and implementation in such cases. @@ -674,7 +681,7 @@ RECURSIVE = YES # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. -EXCLUDE = +EXCLUDE = include/d # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded @@ -858,7 +865,14 @@ HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a -# standard header. +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is adviced to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! HTML_HEADER = @@ -875,7 +889,16 @@ HTML_FOOTER = # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! -#HTML_STYLESHEET = doc/psyc.css +HTML_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. # Doxygen will adjust the colors in the stylesheet and background images @@ -1079,10 +1102,10 @@ ECLIPSE_DOC_ID = org.doxygen.Project DISABLE_INDEX = NO -# This tag can be used to set the number of enum values (range [0,1..20]) -# that doxygen will group on one line in the generated HTML documentation. -# Note that a value of 0 will completely suppress the enum values from -# appearing in the overview section. +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. ENUM_VALUES_PER_LINE = 4 @@ -1141,7 +1164,7 @@ USE_MATHJAX = NO # HTML output directory using the MATHJAX_RELPATH option. The destination # directory should contain the MathJax.js script. For instance, if the mathjax # directory is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to the +# MATHJAX_RELPATH should be ../mathjax. The default value points to the # mathjax.org site, so you can quickly see the result without installing # MathJax, but it is strongly recommended to install a local copy of MathJax # before deployment. @@ -1221,6 +1244,13 @@ EXTRA_PACKAGES = LATEX_HEADER = +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references @@ -1428,7 +1458,7 @@ MACRO_EXPANSION = NO EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. +# pointed to by INCLUDE_PATH will be searched when a #include is found. SEARCH_INCLUDES = YES @@ -1458,7 +1488,7 @@ PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition that +# Use the PREDEFINED tag if you want to use a different macro definition that # overrules the definition found in the source code. EXPAND_AS_DEFINED = @@ -1650,7 +1680,7 @@ GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, svg, gif or svg. +# generated by dot. Possible values are svg, png, jpg, or gif. # If left blank png will be used. DOT_IMAGE_FORMAT = png From 975837472bf0d52c6261353431c0b77316c089ee Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 9 May 2011 00:28:51 +0200 Subject: [PATCH 194/378] d stuff go in d/ --- d/Doxyfile | 1 + d/Makefile | 4 ++++ d/doc/psyc.svg | 1 + {include/d => d/include}/psyc/common.d | 0 {include/d => d/include}/psyc/parser.d | 2 +- 5 files changed, 7 insertions(+), 1 deletion(-) create mode 120000 d/Doxyfile create mode 100644 d/Makefile create mode 120000 d/doc/psyc.svg rename {include/d => d/include}/psyc/common.d (100%) rename {include/d => d/include}/psyc/parser.d (99%) diff --git a/d/Doxyfile b/d/Doxyfile new file mode 120000 index 0000000..c247307 --- /dev/null +++ b/d/Doxyfile @@ -0,0 +1 @@ +../Doxyfile \ No newline at end of file diff --git a/d/Makefile b/d/Makefile new file mode 100644 index 0000000..987a385 --- /dev/null +++ b/d/Makefile @@ -0,0 +1,4 @@ +.PHONY: doc + +doc: + doxygen diff --git a/d/doc/psyc.svg b/d/doc/psyc.svg new file mode 120000 index 0000000..73c1ee9 --- /dev/null +++ b/d/doc/psyc.svg @@ -0,0 +1 @@ +../../doc/psyc.svg \ No newline at end of file diff --git a/include/d/psyc/common.d b/d/include/psyc/common.d similarity index 100% rename from include/d/psyc/common.d rename to d/include/psyc/common.d diff --git a/include/d/psyc/parser.d b/d/include/psyc/parser.d similarity index 99% rename from include/d/psyc/parser.d rename to d/include/psyc/parser.d index 3183301..244aa01 100644 --- a/include/d/psyc/parser.d +++ b/d/include/psyc/parser.d @@ -11,7 +11,7 @@ import psyc.common; */ /** - * @defgroup parsing-d D Parsing Functions + * @defgroup parsing-d Parsing Functions * * This module contains all parsing functions. * @{ From a09be0f15e2117093e5ff59944f298bba70de61b Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 9 May 2011 00:29:01 +0200 Subject: [PATCH 195/378] + --- Makefile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Makefile b/Makefile index c3343d6..43d301b 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,4 @@ -.PHONY: doc -.PHONY: test -.PHONY: lib +.PHONY: doc test all: ${MAKE} -C src From 2ef7cb40b9bd42fb3b39d1ef0b9d6f5deac06a05 Mon Sep 17 00:00:00 2001 From: Marenz Date: Mon, 9 May 2011 00:39:21 +0200 Subject: [PATCH 196/378] changed documentation to Ddoc for parser.d --- include/d/psyc/parser.d | 69 +++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/include/d/psyc/parser.d b/include/d/psyc/parser.d index 3183301..9f0e382 100644 --- a/include/d/psyc/parser.d +++ b/include/d/psyc/parser.d @@ -2,20 +2,6 @@ module psyc.parser; import psyc.common; -/** - * @file d/psyc/parser.d - * @brief D Interface for various PSYC parser functions. - * - * All parsing functions and the definitions they use are - * defined in this file. -*/ - -/** - * @defgroup parsing-d D Parsing Functions - * - * This module contains all parsing functions. - * @{ - */ extern (C): @@ -27,7 +13,9 @@ enum ParseFlag /** * The return value definitions for the packet parsing function. - * @see parse() + * + * See_Also: + * parse() */ enum ParseRC { @@ -95,7 +83,7 @@ enum ParseRC /** * The return value definitions for the list parsing function. - * @see parseList() + * See_Also: parseList() */ enum ParseListRC { @@ -143,7 +131,8 @@ struct ParseState /** * Initializes the state struct with flags. * - * @param flags Flags to be set for the parser, see ParseFlag. + * Params: + * flags = Flags to be set for the parser, see ParseFlag. */ static ParseState opCall ( ubyte flags ) { @@ -159,8 +148,10 @@ struct ParseState /** * Sets a new buffer in the parser state struct with data to be parsed. * - * @param buffer the buffer that should be parsed now - * @see String + * Params: + * buffer the buffer that should be parsed now + * + * See_Also: String */ void setParseBuffer ( String buffer ) { @@ -177,8 +168,10 @@ struct ParseState /** * Sets a new buffer in the parser state struct with data to be parsed. * - * @param buffer the buffer that should be parsed now - * @see String + * Params: + * buffer = the buffer that should be parsed now + * + * See_Also: String */ void setParseBuffer ( ubyte[] buffer ) { @@ -188,8 +181,9 @@ struct ParseState /** * Sets a new buffer in the parser state struct with data to be parsed. * - * @param buffer pointer to the buffer that should be parsed now - * @param length length of the buffer + * Params: + * buffer = pointer to the buffer that should be parsed now + * length = length of the buffer */ void setParseBuffer ( ubyte* buffer, size_t length ) { @@ -258,7 +252,9 @@ struct ParseListState /** * Sets a new buffer with data to be parsed - * @param buffer the buffer to be parsed + * + * Params: + * buffer = the buffer to be parsed */ void setBuffer ( String buffer ) { @@ -268,7 +264,9 @@ struct ParseListState /** * Sets a new buffer with data to be parsed - * @param buffer the buffer to be parsed + * + * Params: + * buffer = the buffer to be parsed */ void setBuffer ( ubyte[] buffer ) { @@ -277,8 +275,10 @@ struct ParseListState /** * Sets a new buffer with data to be parsed - * @param buffer pointer to the buffer to be parsed - * @param length size of the buffer + * + * Params: + * buffer = pointer to the buffer to be parsed + * length = size of the buffer */ void setBuffer ( ubyte* buffer, size_t length ) { @@ -292,13 +292,14 @@ struct ParseListState * * Generalized line-based packet parser. * - * @param state An initialized ParseState - * @param oper A pointer to a character. In case of a variable, it will - * be set to the operator of that variable - * @param name A pointer to a String. It will point to the name of - * the variable or method and its length will be set accordingly - * @param value A pointer to a String. It will point to the - * value/body the variable/method and its length will be set accordingly + * Params: + * state = An initialized ParseState + * oper = A pointer to a character. In case of a variable, it will + * be set to the operator of that variable + * name = A pointer to a String. It will point to the name of + * the variable or method and its length will be set accordingly + * value = A pointer to a String. It will point to the + * value/body the variable/method and its length will be set accordingly */ ParseRC psyc_parse(ParseState* state, char* oper, String* name, String* value); From e8bd72eb4ac4d22b607b98f6ad476d50186e62d2 Mon Sep 17 00:00:00 2001 From: Marenz Date: Mon, 9 May 2011 00:39:41 +0200 Subject: [PATCH 197/378] Explain a little more that the functions don't allocate memory --- include/psyc/parser.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index 4206913..317e36b 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -179,6 +179,9 @@ void psyc_initParseState2 (psycParseState *state, uint8_t flags) /** * Sets a new buffer in the parser state struct with data to be parsed. * + * This function does NOT copy the buffer. It will parse whatever is + * at the memory pointed to by buffer. + * * @param state Pointer to the initialized state of the parser * @param buffer the buffer that should be parsed now * @see psycString @@ -199,6 +202,9 @@ void psyc_setParseBuffer (psycParseState *state, psycString buffer) /** * Sets a new buffer in the parser state struct with data to be parsed. * + * This function does NOT copy the buffer. It will parse whatever is + * at the memory pointed to by buffer. + * * @param state Pointer to the initialized state of the parser * @param buffer pointer to the data that should be parsed * @param length length of the data in bytes @@ -292,6 +298,8 @@ const char * psyc_getParseRemainingBuffer (psycParseState *state) * * Generalized line-based packet parser. * + * This function will never allocate heap memory. + * * @param state An initialized psycParseState * @param oper A pointer to a character. In case of a variable, it will * be set to the operator of that variable From 6a6a3b66115c80d2d49019cff4fa17c53b423fc7 Mon Sep 17 00:00:00 2001 From: Marenz Date: Mon, 9 May 2011 01:36:57 +0200 Subject: [PATCH 198/378] added small parsing tutorial --- include/psyc/parser.h | 94 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 91 insertions(+), 3 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index 317e36b..b5b6984 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -9,10 +9,95 @@ /** * @defgroup parser Parsing Functions * - * This module contains all parsing functions. - * @{ + * This module contains packet and list parsing functions. + * + * To parse a packet you first have to initialize a state: + * + * @code + * psycParseState state; + * + * psyc_initParseState(&state); + * @endcode + * + * Note that there is also psyc_initParseState2 if you want to fine-tune what + * should be parsed. + * + * Next, you have to tell the parser what it should parse. Assuming the variable + * raw_data points to our packet and raw_len contains the length, you can pass + * it to the parser as follows: + * + * @code + * char* raw_data; // points to our (possibly incomplete) packet + * size_t raw_len; // how many bytes of data + * + * psyc_setParseBuffer(&state, // our initialized state from before + * raw_data, + * raw_len); + * @endcode + * + * Now the the variables that will save the output of the parser need to be + * declared: + * + * @code + * psycString name, // Name of the variable or method + * value; // Value of the variable or body + * char oper; // operator of the variable (if any) + * @endcode + * + * They will be passd to the parsing function which will set them to + * the according positions and lengths. + * + * Now the real parsing begins. The parsing function needs to be called + * repeatedly with various actions in between, depending on the return values: + * + * @code + * + * int res; + * + * do // run the parsing in a loop, each time parsing one line + * { + * name.length = value.length = oper = 0; // reset the output variables + * + * ret = psyc_parse(&state, &oper, &name, &value); // call the parsing function + * + * switch (ret) // look at the return value + * { + * case PSYC_PARSE_ROUTING: // it is a routing variable + * case PSYC_PARSE_ENTITY: // it is a entity variable + * // Name, value and operator of the variable can now be found in the + * // respective variables: + * printf("Variable: %.*s Value: %.*s Operator: %c\n", + * name.length, name.ptr, + * value.length, value.ptr, + * operator); + * // Note that the .ptr member still points at your original buffer. If + * // you want to reuse that buffer for the next packet, you better copy it + * // before passing it to the parser or you copy each variable now. + * break; + * case PSYC_PARSE_BODY: // it is the method and the body of the packet. + * printf("Method Name: %.*s Body: %.*s\n", + * name.length, name.ptr, // name of the method + * value.length, value.ptr); // valeu of the body + * break; + * case PSYC_PARSER_COMPLETE: // parsing of this packet is complete + * // You can simply continue parsing till you get the + * // PSYC_PARSE_INSUFFICIENT code which means teh packet is incomplete. + * continue; + * default: // + * perror("Error %i happened :(\n", res); + * return res; + * } + * } + * @endcode + * + * This simple example does not consider some more complex cases for when you + * recieve incomplete packets but still want to access the data. This code would + * simply reject incomplete packets as error. A more detailed tutorial for + * incomplete packets will follow, in the mean time, have look at the return + * codes in psycParseRC and their explainations. */ +/** @{ */ // end of parser group #ifndef PSYC_PARSER_H # define PSYC_PARSER_H @@ -153,6 +238,7 @@ typedef struct * Initializes the state struct. * * @param state Pointer to the state struct that should be initialized. + * @see psyc_initParseState2 */ static inline void psyc_initParseState (psycParseState *state) @@ -165,6 +251,8 @@ void psyc_initParseState (psycParseState *state) * * @param state Pointer to the state struct that should be initialized. * @param flags Flags to be set for the parser, see psycParseFlag. + * @see psyc_initParseState + * @see psycParseFlag */ static inline void psyc_initParseState2 (psycParseState *state, uint8_t flags) @@ -298,7 +386,7 @@ const char * psyc_getParseRemainingBuffer (psycParseState *state) * * Generalized line-based packet parser. * - * This function will never allocate heap memory. + * This function never allocates heap memory. * * @param state An initialized psycParseState * @param oper A pointer to a character. In case of a variable, it will From dea9b8edb93d631c11c1448f75ce2f3a7a0ff4f2 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 9 May 2011 01:47:06 +0200 Subject: [PATCH 199/378] parser: cleaned up psycParseRC --- include/psyc/parser.h | 6 +---- src/parser.c | 62 ++++++++++++++++++++++++------------------- 2 files changed, 36 insertions(+), 32 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index 317e36b..ae3670e 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -50,8 +50,6 @@ typedef enum PSYC_PARSE_ERROR_LENGTH = -2, /// Error in packet. PSYC_PARSE_ERROR = -1, -// Success, used internally. - PSYC_PARSE_SUCCESS = 0, /// Buffer contains insufficient amount of data. /// Fill another buffer and concatenate it with the end of the current buffer, /// from the cursor position to the end. @@ -90,10 +88,8 @@ typedef enum /// Content parsing done in one go, value contains the whole content. /// Used when PSYC_PARSE_ROUTING_ONLY is set. PSYC_PARSE_CONTENT = 10, -// Binary value parsing complete, used internally. +/// Finished parsing packet. PSYC_PARSE_COMPLETE = 11, -// Binary value parsing incomplete, used internally. - PSYC_PARSE_INCOMPLETE = 12, } psycParseRC; /** diff --git a/src/parser.c b/src/parser.c index b447750..2ec5a66 100644 --- a/src/parser.c +++ b/src/parser.c @@ -15,6 +15,14 @@ return ret; \ } +typedef enum { + PARSE_ERROR = -1, + PARSE_SUCCESS = 0, + PARSE_INSUFFICIENT = 1, + PARSE_COMPLETE = 100, + PARSE_INCOMPLETE = 101, +} parseRC; + /** * Determines if the argument is a glyph. * Glyphs are: : = + - ? ! @@ -70,10 +78,10 @@ char isKwChar (uint8_t c) /** * Parse variable name or method name. * It should contain one or more keyword characters. - * @return PSYC_PARSE_ERROR or PSYC_PARSE_SUCCESS + * @return PARSE_ERROR or PARSE_SUCCESS */ static inline -psycParseRC psyc_parseKeyword (psycParseState *state, psycString *name) +parseRC psyc_parseKeyword (psycParseState *state, psycString *name) { name->ptr = state->buffer.ptr + state->cursor; name->length = 0; @@ -84,7 +92,7 @@ psycParseRC psyc_parseKeyword (psycParseState *state, psycString *name) ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } - return name->length > 0 ? PSYC_PARSE_SUCCESS : PSYC_PARSE_ERROR; + return name->length > 0 ? PARSE_SUCCESS : PARSE_ERROR; } /** @@ -95,11 +103,11 @@ psycParseRC psyc_parseKeyword (psycParseState *state, psycString *name) * @param length Expected length of the data. * @param parsed Number of bytes parsed so far. * - * @return PSYC_PARSE_COMPLETE or PSYC_PARSE_INCOMPLETE + * @return PARSE_COMPLETE or PARSE_INCOMPLETE */ static inline -psycParseRC psyc_parseBinaryValue (psycParseState *state, psycString *value, - size_t *length, size_t *parsed) +parseRC psyc_parseBinaryValue (psycParseState *state, psycString *value, + size_t *length, size_t *parsed) { size_t remaining = *length - *parsed; value->ptr = state->buffer.ptr + state->cursor; @@ -109,7 +117,7 @@ psycParseRC psyc_parseBinaryValue (psycParseState *state, psycString *value, value->length = state->buffer.length - state->cursor; state->cursor += value->length; *parsed += value->length; - return PSYC_PARSE_INCOMPLETE; + return PARSE_INCOMPLETE; } value->length = remaining; @@ -117,24 +125,24 @@ psycParseRC psyc_parseBinaryValue (psycParseState *state, psycString *value, *parsed += remaining; assert(*parsed == *length); - return PSYC_PARSE_COMPLETE; + return PARSE_COMPLETE; } /** * Parse simple or binary variable. - * @return PSYC_PARSE_ERROR or PSYC_PARSE_SUCCESS + * @return PARSE_ERROR or PARSE_SUCCESS */ static inline -psycParseRC psyc_parseModifier (psycParseState *state, char *oper, - psycString *name, psycString *value) +parseRC psyc_parseModifier (psycParseState *state, char *oper, + psycString *name, psycString *value) { *oper = *(state->buffer.ptr + state->cursor); ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); - psycParseRC ret = psyc_parseKeyword(state, name); - if (ret == PSYC_PARSE_ERROR) + parseRC ret = psyc_parseKeyword(state, name); + if (ret == PARSE_ERROR) return PSYC_PARSE_ERROR_MOD_NAME; - else if (ret != PSYC_PARSE_SUCCESS) + else if (ret != PARSE_SUCCESS) return ret; size_t length = 0; @@ -168,13 +176,13 @@ psycParseRC psyc_parseModifier (psycParseState *state, char *oper, return PSYC_PARSE_ERROR_MOD_TAB; if (++(state->cursor) >= state->buffer.length) - return length ? PSYC_PARSE_INCOMPLETE : PSYC_PARSE_SUCCESS; // if length=0 we're done + return length ? PARSE_INCOMPLETE : PARSE_SUCCESS; // if length=0 we're done ret = psyc_parseBinaryValue(state, value, &(state->valueLength), &(state->valueParsed)); - if (ret == PSYC_PARSE_INCOMPLETE) + if (ret == PARSE_INCOMPLETE) return ret; - return PSYC_PARSE_SUCCESS; + return PARSE_SUCCESS; } else if (state->buffer.ptr[state->cursor] == '\t') // simple arg { @@ -187,7 +195,7 @@ psycParseRC psyc_parseModifier (psycParseState *state, char *oper, ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } - return PSYC_PARSE_SUCCESS; + return PARSE_SUCCESS; } else return PSYC_PARSE_ERROR_MOD_TAB; @@ -206,7 +214,7 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, PP(("Invalid flag combination")) #endif - psycParseRC ret; // a return value + parseRC ret; // a return value size_t pos = state->cursor; // a cursor position // Start position of the current line in the buffer @@ -245,7 +253,7 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, { // it is a glyph, so a variable starts here ret = psyc_parseModifier(state, oper, name, value); state->routingLength += state->cursor - pos; - return ret == PSYC_PARSE_SUCCESS ? PSYC_PARSE_ROUTING : ret; + return ret == PARSE_SUCCESS ? PSYC_PARSE_ROUTING : ret; } else // not a glyph { @@ -304,7 +312,7 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, ret = psyc_parseBinaryValue(state, value, &(state->valueLength), &(state->valueParsed)); state->contentParsed += value->length; - if (ret == PSYC_PARSE_INCOMPLETE) + if (ret == PARSE_INCOMPLETE) return PSYC_PARSE_ENTITY_CONT; return PSYC_PARSE_ENTITY_END; @@ -329,9 +337,9 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, ret = psyc_parseModifier(state, oper, name, value); state->contentParsed += state->cursor - pos; - if (ret == PSYC_PARSE_INCOMPLETE) + if (ret == PARSE_INCOMPLETE) return PSYC_PARSE_ENTITY_START; - else if (ret == PSYC_PARSE_SUCCESS) + else if (ret == PARSE_SUCCESS) return PSYC_PARSE_ENTITY; return ret; @@ -348,9 +356,9 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, pos = state->cursor; ret = psyc_parseKeyword(state, name); - if (ret == PSYC_PARSE_INSUFFICIENT) + if (ret == PARSE_INSUFFICIENT) return ret; - else if (ret == PSYC_PARSE_SUCCESS) + else if (ret == PARSE_SUCCESS) { // the method ends with a \n then the data follows if (state->buffer.ptr[state->cursor] != '\n') return PSYC_PARSE_ERROR_METHOD; @@ -399,7 +407,7 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, ret = psyc_parseBinaryValue(state, value, &(state->valueLength), &(state->valueParsed)); state->contentParsed += value->length; - if (ret == PSYC_PARSE_INCOMPLETE) + if (ret == PARSE_INCOMPLETE) return state->valueParsed == value->length ? PSYC_PARSE_BODY_START : PSYC_PARSE_BODY_CONT; } @@ -554,7 +562,7 @@ psycParseListRC psyc_parseList (psycParseListState *state, psycString *name, if (state->elemParsed < state->elemLength) { if (psyc_parseBinaryValue((psycParseState*)state, elem, - &(state->elemLength), &(state->elemParsed)) == PSYC_PARSE_INCOMPLETE) + &(state->elemLength), &(state->elemParsed)) == PARSE_INCOMPLETE) return PSYC_PARSE_LIST_INCOMPLETE; state->elemLength = 0; From 919ac96907fdabd6bab16aa5a6439657add43340 Mon Sep 17 00:00:00 2001 From: Marenz Date: Mon, 9 May 2011 01:49:04 +0200 Subject: [PATCH 200/378] enhancement in the documentation --- include/psyc.h | 11 +++++++++-- include/psyc/parser.h | 8 ++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/include/psyc.h b/include/psyc.h index c4fca1d..5446e80 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -82,10 +82,17 @@ typedef enum PSYC_LIST_BINARY = 2, } psycListType; +/** + * String struct. + * + * Contains pointer and length for a buffer. + */ typedef struct { - size_t length; - const char *ptr; + /// Length of the data pointed to by ptr + size_t length; + /// pointer to the data + const char *ptr; } psycString; typedef struct diff --git a/include/psyc/parser.h b/include/psyc/parser.h index b5b6984..0e2928b 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -20,7 +20,7 @@ * @endcode * * Note that there is also psyc_initParseState2 if you want to fine-tune what - * should be parsed. + * part of the packet should be parsed. @see psycParseFlag * * Next, you have to tell the parser what it should parse. Assuming the variable * raw_data points to our packet and raw_len contains the length, you can pass @@ -69,7 +69,7 @@ * printf("Variable: %.*s Value: %.*s Operator: %c\n", * name.length, name.ptr, * value.length, value.ptr, - * operator); + * oper); * // Note that the .ptr member still points at your original buffer. If * // you want to reuse that buffer for the next packet, you better copy it * // before passing it to the parser or you copy each variable now. @@ -94,7 +94,7 @@ * recieve incomplete packets but still want to access the data. This code would * simply reject incomplete packets as error. A more detailed tutorial for * incomplete packets will follow, in the mean time, have look at the return - * codes in psycParseRC and their explainations. + * codes in psycParseRC and their explainations. @see psycParseRC */ /** @{ */ // end of parser group @@ -109,7 +109,7 @@ typedef enum { /// Parse only the header PSYC_PARSE_ROUTING_ONLY = 1, - /// Expects only the content part of a packet. The buffer should contain the whole content in this case. + /// Parse only the content. This means that there is no header and parsing will fail if there is one. The beginning of the content is expected. PSYC_PARSE_START_AT_CONTENT = 2, } psycParseFlag; From ddf1c1d9c9b6333bbec90680269835de388b3ed2 Mon Sep 17 00:00:00 2001 From: Marenz Date: Mon, 9 May 2011 01:53:30 +0200 Subject: [PATCH 201/378] fixed a typo --- include/psyc/parser.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index bd89299..03a624b 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -79,7 +79,7 @@ * name.length, name.ptr, // name of the method * value.length, value.ptr); // valeu of the body * break; - * case PSYC_PARSER_COMPLETE: // parsing of this packet is complete + * case PSYC_PARSE_COMPLETE: // parsing of this packet is complete * // You can simply continue parsing till you get the * // PSYC_PARSE_INSUFFICIENT code which means teh packet is incomplete. * continue; @@ -97,7 +97,8 @@ * codes in psycParseRC and their explainations. @see psycParseRC */ -/** @{ */ // end of parser group +/** @{ */ // begin of parser group + #ifndef PSYC_PARSER_H # define PSYC_PARSER_H From 29e5ca95325a4dd1e17a2616eb18e77e227223fb Mon Sep 17 00:00:00 2001 From: Marenz Date: Mon, 9 May 2011 02:07:13 +0200 Subject: [PATCH 202/378] more documentation --- include/psyc/parser.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index 03a624b..f9fcfa2 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -10,6 +10,15 @@ * @defgroup parser Parsing Functions * * This module contains packet and list parsing functions. + * The parser adheres to the definition of a packet found at + * + * http://about.psyc.eu/Spec:Packet + * + * and the according terms are used throughout this documentation and in the + * return codes. You should be at least + * vaguely familiar with what the difference between "body" and "content" as + * well as "routing variable" and "entity variable" is. + * * * To parse a packet you first have to initialize a state: * @@ -77,7 +86,7 @@ * case PSYC_PARSE_BODY: // it is the method and the body of the packet. * printf("Method Name: %.*s Body: %.*s\n", * name.length, name.ptr, // name of the method - * value.length, value.ptr); // valeu of the body + * value.length, value.ptr); // value of the body * break; * case PSYC_PARSE_COMPLETE: // parsing of this packet is complete * // You can simply continue parsing till you get the @@ -110,7 +119,7 @@ typedef enum { /// Parse only the header PSYC_PARSE_ROUTING_ONLY = 1, - /// Parse only the content. This means that there is no header and parsing will fail if there is one. The beginning of the content is expected. + /// Parse only the content. Parsing starts at the content and the content must be complete. "content" means the definition used in the packet specification. PSYC_PARSE_START_AT_CONTENT = 2, } psycParseFlag; From d895cd86b79360f66756cde4c492ce232a598da8 Mon Sep 17 00:00:00 2001 From: Marenz Date: Mon, 9 May 2011 02:24:41 +0200 Subject: [PATCH 203/378] removed obsolete part --- include/psyc/parser.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/psyc/parser.h b/include/psyc/parser.h index f9fcfa2..f9d5b89 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -119,7 +119,7 @@ typedef enum { /// Parse only the header PSYC_PARSE_ROUTING_ONLY = 1, - /// Parse only the content. Parsing starts at the content and the content must be complete. "content" means the definition used in the packet specification. + /// Parse only the content. Parsing starts at the content and the content must be complete. PSYC_PARSE_START_AT_CONTENT = 2, } psycParseFlag; From d7a36076d5113edba5c96066fdba5533b477ee32 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 9 May 2011 02:27:12 +0200 Subject: [PATCH 204/378] make install --- .gitignore | 5 ++++- Doxyfile | 2 +- Makefile | 13 ++++++++++++- d/Makefile | 3 +++ d/include/Makefile | 2 ++ d/include/psyc/Makefile | 13 +++++++++++++ include/Makefile | 14 ++++++++++++++ include/psyc/Makefile | 13 +++++++++++++ lib/Makefile | 13 +++++++++++++ 9 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 d/include/Makefile create mode 100644 d/include/psyc/Makefile create mode 100644 include/Makefile create mode 100644 include/psyc/Makefile create mode 100644 lib/Makefile diff --git a/.gitignore b/.gitignore index b585751..34d93bb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,10 @@ -lib +lib/libpsyc.a doc/html doc/latex doc/man +d/doc/html +d/doc/latex +d/doc/man src/match test/testMatch test/testParser diff --git a/Doxyfile b/Doxyfile index df1212c..38dfdac 100644 --- a/Doxyfile +++ b/Doxyfile @@ -681,7 +681,7 @@ RECURSIVE = YES # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. -EXCLUDE = include/d +EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded diff --git a/Makefile b/Makefile index 43d301b..1cb161a 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,17 @@ all: ${MAKE} -C src +install: install-lib install-inc install-d + +install-lib: all + ${MAKE} -C lib install + +install-inc: all + ${MAKE} -C include install + +install-d: all + ${MAKE} -C d install + debug: ${MAKE} -C src debug @@ -26,4 +37,4 @@ clean: rm -rf doc/html doc/latex doc/man help: - @/bin/echo -e "Usage:\n\tmake - compile\n\tmake diet - compile with diet libc\n\tmake test\n\tmake doc" + @/bin/echo -e "Usage:\n\tmake - compile\n\tmake diet - compile with diet libc\n\tmake test\n\tmake doc\n\tmake install [prefix=/usr]" diff --git a/d/Makefile b/d/Makefile index 987a385..a2e05a4 100644 --- a/d/Makefile +++ b/d/Makefile @@ -2,3 +2,6 @@ doc: doxygen + +install: + ${MAKE} -C include install diff --git a/d/include/Makefile b/d/include/Makefile new file mode 100644 index 0000000..727f0a9 --- /dev/null +++ b/d/include/Makefile @@ -0,0 +1,2 @@ +install: + ${MAKE} -C psyc install diff --git a/d/include/psyc/Makefile b/d/include/psyc/Makefile new file mode 100644 index 0000000..d474c2f --- /dev/null +++ b/d/include/psyc/Makefile @@ -0,0 +1,13 @@ +prefix = /usr +includedir = ${prefix}/include/d + +INSTALL = install +HEADERS = common.d parser.d + +install: ${HEADERS} + +installdir: + ${INSTALL} -d ${includedir}/psyc + +${HEADERS}: installdir + ${INSTALL} -m 644 $@ ${includedir}/psyc diff --git a/include/Makefile b/include/Makefile new file mode 100644 index 0000000..6fe5d21 --- /dev/null +++ b/include/Makefile @@ -0,0 +1,14 @@ +prefix = /usr +includedir = ${prefix}/include + +INSTALL = install +HEADERS = psyc.h + +install: ${HEADERS} + ${MAKE} -C psyc install + +installdir: + ${INSTALL} -d ${includedir} + +${HEADERS}: installdir + ${INSTALL} -m 644 $@ ${includedir} diff --git a/include/psyc/Makefile b/include/psyc/Makefile new file mode 100644 index 0000000..9733a9d --- /dev/null +++ b/include/psyc/Makefile @@ -0,0 +1,13 @@ +prefix = /usr +includedir = ${prefix}/include + +INSTALL = install +HEADERS = packet.h parser.h render.h syntax.h text.h + +install: ${HEADERS} + +installdir: + ${INSTALL} -d ${includedir}/psyc + +${HEADERS}: installdir + ${INSTALL} -m 644 $@ ${includedir}/psyc diff --git a/lib/Makefile b/lib/Makefile new file mode 100644 index 0000000..6b53b18 --- /dev/null +++ b/lib/Makefile @@ -0,0 +1,13 @@ +prefix = /usr +libdir = ${prefix}/lib + +INSTALL = install +LIBS = libpsyc.a + +install: ${LIBS} + +libdir: + ${INSTALL} -d ${libdir} + +${LIBS}: libdir + ${INSTALL} $@ ${libdir} From 26539cdd14a22fe08e813a3730260673972b2936 Mon Sep 17 00:00:00 2001 From: Marenz Date: Mon, 9 May 2011 02:41:16 +0200 Subject: [PATCH 205/378] intro text changed --- include/psyc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/psyc.h b/include/psyc.h index 5446e80..e1b39e8 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -7,7 +7,7 @@ * * @section intro_sec Introduction * - * This is the introduction. + * Welcome to the libpsyc Documentation! * * @section install_sec Installation * From 36491b48864d55a01781fbcdb7e30921bc869b56 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Mon, 9 May 2011 09:02:15 +0200 Subject: [PATCH 206/378] death the parser --- README | 19 ++++++++++++++----- include/psyc.h | 4 ++-- include/psyc/Makefile | 4 +++- include/psyc/packet.h | 4 ++-- include/psyc/{parser.h => parse.h} | 12 ++++++------ include/psyc/render.h | 6 +++--- include/psyc/syntax.h | 4 ++-- include/psyc/text.h | 5 +++++ src/lib.h | 2 +- src/parser.c | 2 +- test/testParser.c | 2 +- test/testServer.c | 2 +- 12 files changed, 41 insertions(+), 25 deletions(-) rename include/psyc/{parser.h => parse.h} (99%) diff --git a/README b/README index 2140aa1..e8b71d5 100644 --- a/README +++ b/README @@ -19,11 +19,12 @@ The "plain C API" is a very low-level API intended to be used for bindings. To access a certain module of the library, just include the according header file from the psyc directory: -parser.h -- parse psyc packets -render.h -- render psyc packets -text.h -- text template functions -packet.h -- structures for render.h and functions to initialize them -syntax.h -- definitions and constants related to parsing and rendering +psyc.h -- basic things for well-being +psyc/parse.h -- parse psyc packets +psyc/render.h -- render psyc packets +psyc/text.h -- text template functions +psyc/packet.h -- structures for render.h and functions to initialize them +psyc/syntax.h -- definitions and constants related to parsing and rendering == Directory Overview == @@ -70,3 +71,11 @@ developement room at == Licence == -- To be discussed -- + +== Style Wars == + +This source code should follow the http://about.psyc.eu/Indent conventions. + (if you have good reasons to use another style, discuss it on the + wiki page so that it becomes the general style convention for all + of us, not just for you). + diff --git a/include/psyc.h b/include/psyc.h index e1b39e8..c9b6e11 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -17,7 +17,6 @@ */ #ifndef PSYC_H -# define PSYC_H #include #include @@ -148,4 +147,5 @@ int psyc_inherits(char *sho, size_t slen, int psyc_matches(char *sho, size_t slen, char *lon, size_t llen); -#endif // PSYC_H +#define PSYC_H +#endif diff --git a/include/psyc/Makefile b/include/psyc/Makefile index 9733a9d..daad9c8 100644 --- a/include/psyc/Makefile +++ b/include/psyc/Makefile @@ -1,8 +1,10 @@ +# Why do we have a Makefile in the include directory? + prefix = /usr includedir = ${prefix}/include INSTALL = install -HEADERS = packet.h parser.h render.h syntax.h text.h +HEADERS = packet.h parse.h render.h syntax.h text.h install: ${HEADERS} diff --git a/include/psyc/packet.h b/include/psyc/packet.h index 350a418..becb0e4 100644 --- a/include/psyc/packet.h +++ b/include/psyc/packet.h @@ -1,5 +1,4 @@ #ifndef PSYC_PACKET_H -# define PSYC_PACKET_H #include #include @@ -143,4 +142,5 @@ psycPacket psyc_newRawPacket2 (psycModifier *routing, size_t routinglen, const char *content, size_t contentlen, psycPacketFlag flag); -#endif // PSYC_PACKET_H +#define PSYC_PACKET_H +#endif diff --git a/include/psyc/parser.h b/include/psyc/parse.h similarity index 99% rename from include/psyc/parser.h rename to include/psyc/parse.h index f9d5b89..d5c3146 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parse.h @@ -1,5 +1,7 @@ +#ifndef PSYC_PARSE_H + /** - * @file psyc/parser.h + * @file psyc/parse.h * @brief Interface for various PSYC parser functions. * * All parsing functions and the definitions they use are @@ -108,9 +110,6 @@ /** @{ */ // begin of parser group -#ifndef PSYC_PARSER_H -# define PSYC_PARSER_H - #include #include #include @@ -411,6 +410,7 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, psycParseListRC psyc_parseList (psycParseListState *state, psycString *name, psycString *value, psycString *elem); -#endif // PSYC_PARSER_H - /** @} */ // end of parser group + +#define PSYC_PARSE_H +#endif diff --git a/include/psyc/render.h b/include/psyc/render.h index 6b837da..a9b6b57 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -1,5 +1,4 @@ #ifndef PSYC_RENDER_H -# define PSYC_RENDER_H #include @@ -39,6 +38,7 @@ psycRenderRC psyc_render (psycPacket *packet, char *buffer, size_t buflen); */ psycRenderRC psyc_renderList (psycList *list, char *buffer, size_t buflen); -#endif // PSYC_RENDER_H - /** @} */ // end of render group + +#define PSYC_RENDER_H +#endif diff --git a/include/psyc/syntax.h b/include/psyc/syntax.h index 92aadb9..105d59e 100644 --- a/include/psyc/syntax.h +++ b/include/psyc/syntax.h @@ -1,5 +1,4 @@ #ifndef PSYC_SYNTAX_H -#define PSYC_SYNTAX_H #ifndef PSYC_LIST_SIZE_LIMIT # define PSYC_LIST_SIZE_LIMIT 404 @@ -42,4 +41,5 @@ #define PSYC_ROUTING_MERGE 2 #define PSYC_ROUTING_RENDER 4 -#endif /* PSYC_SYNTAX_H */ +#define PSYC_SYNTAX_H +#endif diff --git a/include/psyc/text.h b/include/psyc/text.h index dd9b180..5b964b3 100644 --- a/include/psyc/text.h +++ b/include/psyc/text.h @@ -1,3 +1,5 @@ +#ifndef PSYC_TEXT_H + /** * @file psyc/text.h * @brief Interface for text template rendering. @@ -157,3 +159,6 @@ size_t psyc_getTextBytesWritten (psycTextState *state) psycTextRC psyc_text (psycTextState *state, psycTextCB getValue); /** @} */ // end of text group + +#define PSYC_TEXT_H +#endif diff --git a/src/lib.h b/src/lib.h index ba7808c..637b082 100644 --- a/src/lib.h +++ b/src/lib.h @@ -4,8 +4,8 @@ # define PSYC_LIB_H #include -#include "./debug.h" #include +#include "debug.h" /* perlisms for readability */ #define unless(COND) if (!(COND)) diff --git a/src/parser.c b/src/parser.c index 2ec5a66..d11db10 100644 --- a/src/parser.c +++ b/src/parser.c @@ -6,7 +6,7 @@ #endif #include "lib.h" -#include +#include #define ADVANCE_CURSOR_OR_RETURN(ret) \ if (++(state->cursor) >= state->buffer.length) \ diff --git a/test/testParser.c b/test/testParser.c index 8634bcb..bbba26f 100644 --- a/test/testParser.c +++ b/test/testParser.c @@ -3,7 +3,7 @@ #include #include -#include +#include int main (int argc, char **argv) { diff --git a/test/testServer.c b/test/testServer.c index 4d15d68..620580f 100644 --- a/test/testServer.c +++ b/test/testServer.c @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include From ad868c83f4818744f2cd911d7035b3cfec30f53e Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Mon, 9 May 2011 09:06:52 +0200 Subject: [PATCH 207/378] more death to the parser --- d/include/psyc/Makefile | 2 +- d/include/psyc/{parser.d => parse.d} | 2 +- include/psyc/parse.h | 2 +- src/Makefile | 4 ++-- src/{parser.c => parse.c} | 0 5 files changed, 5 insertions(+), 5 deletions(-) rename d/include/psyc/{parser.d => parse.d} (99%) rename src/{parser.c => parse.c} (100%) diff --git a/d/include/psyc/Makefile b/d/include/psyc/Makefile index d474c2f..3e8ad21 100644 --- a/d/include/psyc/Makefile +++ b/d/include/psyc/Makefile @@ -2,7 +2,7 @@ prefix = /usr includedir = ${prefix}/include/d INSTALL = install -HEADERS = common.d parser.d +HEADERS = common.d parse.d install: ${HEADERS} diff --git a/d/include/psyc/parser.d b/d/include/psyc/parse.d similarity index 99% rename from d/include/psyc/parser.d rename to d/include/psyc/parse.d index e24bdf9..d655da2 100644 --- a/d/include/psyc/parser.d +++ b/d/include/psyc/parse.d @@ -1,4 +1,4 @@ -module psyc.parser; +module psyc.parse; import psyc.common; diff --git a/include/psyc/parse.h b/include/psyc/parse.h index d5c3146..176779d 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -2,7 +2,7 @@ /** * @file psyc/parse.h - * @brief Interface for various PSYC parser functions. + * @brief Interface for various PSYC parsing functions. * * All parsing functions and the definitions they use are * defined in this file. diff --git a/src/Makefile b/src/Makefile index e0bb01b..f7dacad 100644 --- a/src/Makefile +++ b/src/Makefile @@ -3,8 +3,8 @@ DEBUG = 2 CFLAGS = -I../include -Wall -std=c99 ${OPT} DIET = diet -S = packet.c parser.c match.c render.c memmem.c itoa.c variable.c text.c -O = packet.o parser.o match.o render.o memmem.o itoa.o variable.o text.o +S = packet.c parse.c match.c render.c memmem.c itoa.c variable.c text.c +O = packet.o parse.o match.o render.o memmem.o itoa.o variable.o text.o all: CC := ${WRAPPER} ${CC} all: lib diff --git a/src/parser.c b/src/parse.c similarity index 100% rename from src/parser.c rename to src/parse.c From 421e201759373aaa29130cfb68a40b53c7a78038 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Mon, 9 May 2011 09:11:59 +0200 Subject: [PATCH 208/378] + --- include/psyc.h | 2 +- include/psyc/parse.h | 10 +++++----- include/psyc/render.h | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/psyc.h b/include/psyc.h index c9b6e11..5bc0803 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -7,7 +7,7 @@ * * @section intro_sec Introduction * - * Welcome to the libpsyc Documentation! + * Welcome to the libpsyc documentation! * * @section install_sec Installation * diff --git a/include/psyc/parse.h b/include/psyc/parse.h index 176779d..3c34c09 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -9,7 +9,7 @@ */ /** - * @defgroup parser Parsing Functions + * @defgroup PSYC Parsing Functions * * This module contains packet and list parsing functions. * The parser adheres to the definition of a packet found at @@ -101,11 +101,11 @@ * } * @endcode * - * This simple example does not consider some more complex cases for when you - * recieve incomplete packets but still want to access the data. This code would + * This simple example does not consider some more complex cases when you + * receive incomplete packets but still want to access the data. This code would * simply reject incomplete packets as error. A more detailed tutorial for - * incomplete packets will follow, in the mean time, have look at the return - * codes in psycParseRC and their explainations. @see psycParseRC + * incomplete packets will follow. In the mean time, have look at the return + * codes in psycParseRC and their explanations. @see psycParseRC */ /** @{ */ // begin of parser group diff --git a/include/psyc/render.h b/include/psyc/render.h index a9b6b57..e2620af 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -38,7 +38,7 @@ psycRenderRC psyc_render (psycPacket *packet, char *buffer, size_t buflen); */ psycRenderRC psyc_renderList (psycList *list, char *buffer, size_t buflen); -/** @} */ // end of render group +/** @} */ // end of renderer group #define PSYC_RENDER_H #endif From 7870dfceeac3197f67b99a9cdaebdbfdd6b433dd Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 9 May 2011 12:42:42 +0200 Subject: [PATCH 209/378] + --- include/psyc/parse.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/psyc/parse.h b/include/psyc/parse.h index 3c34c09..333f109 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -9,7 +9,7 @@ */ /** - * @defgroup PSYC Parsing Functions + * @defgroup parse Parsing Functions * * This module contains packet and list parsing functions. * The parser adheres to the definition of a packet found at @@ -410,7 +410,7 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, psycParseListRC psyc_parseList (psycParseListState *state, psycString *name, psycString *value, psycString *elem); -/** @} */ // end of parser group +/** @} */ // end of parse group #define PSYC_PARSE_H #endif From 11e265b32e8269d6187acf742c7eeb733d3e77b1 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 9 May 2011 14:37:57 +0200 Subject: [PATCH 210/378] doc --- include/psyc.h | 14 ++++++-------- include/psyc/packet.h | 17 +++++++++++++++++ include/psyc/parse.h | 5 ++--- include/psyc/render.h | 5 ++--- 4 files changed, 27 insertions(+), 14 deletions(-) diff --git a/include/psyc.h b/include/psyc.h index 5bc0803..cafc026 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -1,20 +1,18 @@ -/** @file psyc.h - * +/** + * @file psyc.h * @brief Main PSYC interface providing crucial functionality. -*/ + */ -/** @mainpage PSYC Core Library +/** + * @mainpage PSYC Core Library * * @section intro_sec Introduction * * Welcome to the libpsyc documentation! * * @section install_sec Installation - * - * @subsection step1 Step 1: Opening the box - * - * etc... */ +// * @subsection step1 Step 1: Opening the box #ifndef PSYC_H diff --git a/include/psyc/packet.h b/include/psyc/packet.h index becb0e4..ffb26a8 100644 --- a/include/psyc/packet.h +++ b/include/psyc/packet.h @@ -1,5 +1,20 @@ #ifndef PSYC_PACKET_H +/** + * @file psyc/packet.h + * @brief Interface for PSYC packet data structures. + * + * Packet data structures and functions for creating them are defined here. + */ + +/** + * @defgroup packet Packet data structures + * + * This module contains definitions of packet data structures and functions for + * creating them. + * @{ + */ + #include #include @@ -142,5 +157,7 @@ psycPacket psyc_newRawPacket2 (psycModifier *routing, size_t routinglen, const char *content, size_t contentlen, psycPacketFlag flag); +/** @} */ // end of packet group + #define PSYC_PACKET_H #endif diff --git a/include/psyc/parse.h b/include/psyc/parse.h index 333f109..6628321 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -2,10 +2,9 @@ /** * @file psyc/parse.h - * @brief Interface for various PSYC parsing functions. + * @brief Interface for PSYC packet parsing. * - * All parsing functions and the definitions they use are - * defined in this file. + * All parsing functions and the definitions they use are defined here. */ /** diff --git a/include/psyc/render.h b/include/psyc/render.h index e2620af..9f2bcd5 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -6,8 +6,7 @@ * @file psyc/render.h * @brief Interface for PSYC packet rendering. * - * All rendering functions and the definitions they use are - * defined in this file. + * All rendering functions and the definitions they use are defined here. */ /** @@ -38,7 +37,7 @@ psycRenderRC psyc_render (psycPacket *packet, char *buffer, size_t buflen); */ psycRenderRC psyc_renderList (psycList *list, char *buffer, size_t buflen); -/** @} */ // end of renderer group +/** @} */ // end of render group #define PSYC_RENDER_H #endif From a1e1419f298da2bb56c3df062c2b89c7cf9c6b9b Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 9 May 2011 16:32:39 +0200 Subject: [PATCH 211/378] moar doc --- include/psyc/packet.h | 49 +++++++++++++------ include/psyc/parse.h | 111 +++++++++++++++++++++--------------------- include/psyc/render.h | 34 +++++++++++-- src/render.c | 12 ++--- 4 files changed, 126 insertions(+), 80 deletions(-) diff --git a/include/psyc/packet.h b/include/psyc/packet.h index ffb26a8..d16dd1b 100644 --- a/include/psyc/packet.h +++ b/include/psyc/packet.h @@ -18,43 +18,58 @@ #include #include +/** Modifier flags. */ typedef enum { + /// Modifier needs to be checked if it needs length. PSYC_MODIFIER_CHECK_LENGTH = 0, + /// Modifier needs length. PSYC_MODIFIER_NEED_LENGTH = 1, + /// Modifier doesn't need length. PSYC_MODIFIER_NO_LENGTH = 2, + /// Routing modifier, which implies that it doesn't need length. PSYC_MODIFIER_ROUTING = 3, } psycModifierFlag; +/** List flags. */ typedef enum { + /// List needs to be checked if it needs length. PSYC_LIST_CHECK_LENGTH = 0, + /// List needs length. PSYC_LIST_NEED_LENGTH = 1, + /// List doesn't need length. PSYC_LIST_NO_LENGTH = 2, } psycListFlag; +/** Packet flags. */ typedef enum { + /// Packet needs to be checked if it needs content length. PSYC_PACKET_CHECK_LENGTH = 0, + /// Packet needs content length. PSYC_PACKET_NEED_LENGTH = 1, + /// Packet doesn't need content length. PSYC_PACKET_NO_LENGTH = 2, } psycPacketFlag; -/** intermediate struct for a PSYC variable modification */ +/** Structure for a modifier. */ typedef struct -{ +t{ char oper; psycString name; psycString value; psycModifierFlag flag; } psycModifier; +/** Structure for an entity or routing header. */ typedef struct { size_t lines; psycModifier *modifiers; } psycHeader; +/** Structure for a list. */ typedef struct { size_t num_elems; @@ -68,16 +83,16 @@ typedef struct { psycHeader routing; ///< Routing header. psycHeader entity; ///< Entity header. - psycString method; - psycString data; - psycString content; + psycString method; ///< Contains the method. + psycString data; ///< Contains the data. + psycString content; ///< Contains the whole content. size_t routingLength; ///< Length of routing part. size_t contentLength; ///< Length of content part. size_t length; ///< Total length of packet. - psycPacketFlag flag; + psycPacketFlag flag; ///< Packet flag. } psycPacket; -/** Check if a modifier needs length */ +/** Check if a modifier needs length. */ static inline psycModifierFlag psyc_checkModifierLength (psycModifier *m) { @@ -93,7 +108,7 @@ psycModifierFlag psyc_checkModifierLength (psycModifier *m) return flag; } -/** Create new modifier */ +/** Create new modifier. */ static inline psycModifier psyc_newModifier (char oper, psycString *name, psycString *value, psycModifierFlag flag) @@ -119,40 +134,42 @@ psycModifier psyc_newModifier2 (char oper, return psyc_newModifier(oper, &n, &v, flag); } -/** Get the total length of a modifier. */ +/** Get the total length of a modifier when rendered. */ size_t psyc_getModifierLength (psycModifier *m); -/** Check if a list needs length */ +/** Check if a list needs length. */ psycListFlag psyc_checkListLength (psycList *list); -/** Get the total length of a list. */ +/** Get the total length of a list when rendered. */ psycListFlag psyc_getListLength (psycList *list); -/** Check if a packet needs length */ +/** Check if a packet needs length. */ psycPacketFlag psyc_checkPacketLength (psycPacket *p); -/** Calculate and set the length of packet parts and total packet length */ +/** Calculate and set the rendered length of packet parts and total packet length. */ size_t psyc_setPacketLength (psycPacket *p); -/** Create new list */ +/** Create new list. */ psycList psyc_newList (psycString *elems, size_t num_elems, psycListFlag flag); -/** Create new packet */ +/** Create new packet. */ psycPacket psyc_newPacket (psycHeader *routing, psycHeader *entity, psycString *method, psycString *data, psycPacketFlag flag); -/** Create new packet */ +/** Create new packet. */ psycPacket psyc_newPacket2 (psycModifier *routing, size_t routinglen, psycModifier *entity, size_t entitylen, const char *method, size_t methodlen, const char *data, size_t datalen, psycPacketFlag flag); +/** Create new packet with raw content. */ psycPacket psyc_newRawPacket (psycHeader *routing, psycString *content, psycPacketFlag flag); +/** Create new packet with raw content. */ psycPacket psyc_newRawPacket2 (psycModifier *routing, size_t routinglen, const char *content, size_t contentlen, psycPacketFlag flag); diff --git a/include/psyc/parse.h b/include/psyc/parse.h index 6628321..2673e6b 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -117,7 +117,8 @@ typedef enum { /// Parse only the header PSYC_PARSE_ROUTING_ONLY = 1, - /// Parse only the content. Parsing starts at the content and the content must be complete. + /// Parse only the content. + /// Parsing starts at the content and the content must be complete. PSYC_PARSE_START_AT_CONTENT = 2, } psycParseFlag; @@ -127,61 +128,61 @@ typedef enum */ typedef enum { -/// Error, packet is not ending with a valid delimiter. + /// Error, packet is not ending with a valid delimiter. PSYC_PARSE_ERROR_END = -8, -/// Error, expected NL after the method. + /// Error, expected NL after the method. PSYC_PARSE_ERROR_METHOD = -7, -/// Error, expected NL after a modifier. + /// Error, expected NL after a modifier. PSYC_PARSE_ERROR_MOD_NL = -6, -/// Error, modifier length is not numeric. + /// Error, modifier length is not numeric. PSYC_PARSE_ERROR_MOD_LEN = -5, -/// Error, expected TAB before modifier value. + /// Error, expected TAB before modifier value. PSYC_PARSE_ERROR_MOD_TAB = -4, -/// Error, modifier name is missing. + /// Error, modifier name is missing. PSYC_PARSE_ERROR_MOD_NAME = -3, -/// Error, expected NL after the content length. + /// Error, expected NL after the content length. PSYC_PARSE_ERROR_LENGTH = -2, -/// Error in packet. + /// Error in packet. PSYC_PARSE_ERROR = -1, -/// Buffer contains insufficient amount of data. -/// Fill another buffer and concatenate it with the end of the current buffer, -/// from the cursor position to the end. + /// Buffer contains insufficient amount of data. + /// Fill another buffer and concatenate it with the end of the current buffer, + /// from the cursor position to the end. PSYC_PARSE_INSUFFICIENT = 1, -/// Routing modifier parsing done. -/// Operator, name & value contains the respective parts. + /// Routing modifier parsing done. + /// Operator, name & value contains the respective parts. PSYC_PARSE_ROUTING = 2, -/// Start of an incomplete entity modifier. -/// Operator & name are complete, value is incomplete. + /// Start of an incomplete entity modifier. + /// Operator & name are complete, value is incomplete. PSYC_PARSE_ENTITY_START = 3, -/// Continuation of an incomplete entity modifier. + /// Continuation of an incomplete entity modifier. PSYC_PARSE_ENTITY_CONT = 4, -/// End of an incomplete entity modifier. + /// End of an incomplete entity modifier. PSYC_PARSE_ENTITY_END = 5, -/// Entity modifier parsing done in one go. -/// Operator, name & value contains the respective parts. + /// Entity modifier parsing done in one go. + /// Operator, name & value contains the respective parts. PSYC_PARSE_ENTITY = 6, -/// Start of an incomplete body. -/// Name contains method, value contains part of the body. + /// Start of an incomplete body. + /// Name contains method, value contains part of the body. PSYC_PARSE_BODY_START = 7, -/// Continuation of an incomplete body. + /// Continuation of an incomplete body. PSYC_PARSE_BODY_CONT = 8, -/// End of an incomplete body. + /// End of an incomplete body. PSYC_PARSE_BODY_END = 9, -/// Body parsing done in one go, name contains method, value contains body. + /// Body parsing done in one go, name contains method, value contains body. PSYC_PARSE_BODY = 10, -/// Start of an incomplete content, value contains part of content. -/// Used when PSYC_PARSE_ROUTING_ONLY is set. + /// Start of an incomplete content, value contains part of content. + /// Used when PSYC_PARSE_ROUTING_ONLY is set. PSYC_PARSE_CONTENT_START = 7, -/// Continuation of an incomplete body. -/// Used when PSYC_PARSE_ROUTING_ONLY is set. + /// Continuation of an incomplete body. + /// Used when PSYC_PARSE_ROUTING_ONLY is set. PSYC_PARSE_CONTENT_CONT = 8, -/// End of an incomplete body. -/// Used when PSYC_PARSE_ROUTING_ONLY is set. + /// End of an incomplete body. + /// Used when PSYC_PARSE_ROUTING_ONLY is set. PSYC_PARSE_CONTENT_END = 9, -/// Content parsing done in one go, value contains the whole content. -/// Used when PSYC_PARSE_ROUTING_ONLY is set. + /// Content parsing done in one go, value contains the whole content. + /// Used when PSYC_PARSE_ROUTING_ONLY is set. PSYC_PARSE_CONTENT = 10, -/// Finished parsing packet. + /// Finished parsing packet. PSYC_PARSE_COMPLETE = 11, } psycParseRC; @@ -196,11 +197,11 @@ typedef enum PSYC_PARSE_LIST_ERROR_TYPE = -3, PSYC_PARSE_LIST_ERROR_NAME = -2, PSYC_PARSE_LIST_ERROR = -1, -/// Completed parsing a list element. + /// Completed parsing a list element. PSYC_PARSE_LIST_ELEM = 1, -/// Reached end of buffer. + /// Reached end of buffer. PSYC_PARSE_LIST_END = 2, -/// Binary list is incomplete. + /// Binary list is incomplete. PSYC_PARSE_LIST_INCOMPLETE = 3, } psycParseListRC; @@ -209,19 +210,19 @@ typedef enum */ typedef struct { - size_t cursor; ///< current position in buffer - size_t startc; ///< position where the parsing would be resumed - psycString buffer; ///< buffer with data to be parsed - uint8_t flags; ///< flags for the parser, see psycParseFlag - psycPart part; ///< part of the packet being parsed currently + size_t cursor; ///< Current position in buffer. + size_t startc; ///< Position where the parsing would be resumed. + psycString buffer; ///< Buffer with data to be parsed. + uint8_t flags; ///< Flags for the parser, see psycParseFlag. + psycPart part; ///< Part of the packet being parsed currently. - size_t routingLength; ///< length of routing part parsed so far - size_t contentParsed; ///< number of bytes parsed from the content so far - size_t contentLength; ///< expected length of the content - psycBool 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 - psycBool valueLengthFound; ///< is there a length given for this modifier? + size_t routingLength; ///< Length of routing part parsed so far. + size_t contentParsed; ///< Number of bytes parsed from the content so far. + size_t contentLength; ///< Expected length of the content. + psycBool 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. + psycBool valueLengthFound; ///< Is there a length given for this modifier? } psycParseState; /** @@ -229,13 +230,13 @@ typedef struct */ typedef struct { - size_t cursor; ///< current position in buffer - size_t startc; ///< line start position - psycString buffer; - psycListType type; ///< list type + size_t cursor; ///< Current position in buffer. + size_t startc; ///< Line start position. + psycString buffer; ///< Buffer with data to be parsed. + psycListType type; ///< List type. - 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. } psycParseListState; /** diff --git a/include/psyc/render.h b/include/psyc/render.h index 9f2bcd5..9d0b5c4 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -21,21 +21,49 @@ */ typedef enum { - PSYC_RENDER_ERROR_METHOD_MISSING = -3, ///< method missing, but data present - PSYC_RENDER_ERROR_MODIFIER_NAME_MISSING = -2, ///< modifier name missing + /// Error, method is missing, but data is present. + PSYC_RENDER_ERROR_METHOD_MISSING = -3, + /// Error, a modifier name is missing. + PSYC_RENDER_ERROR_MODIFIER_NAME_MISSING = -2, + /// Error, buffer is too small to render the packet. PSYC_RENDER_ERROR = -1, + /// Packet is rendered successfully in the buffer. PSYC_RENDER_SUCCESS = 0, } psycRenderRC; +/** + * Return codes for psyc_renderList. + */ +typedef enum +{ + /// Error, buffer is too small to render the list. + PSYC_RENDER_LIST_ERROR = -1, + /// List is rendered successfully in the buffer. + PSYC_RENDER_LIST_SUCCESS = 0, +} psycRenderListRC; + /** * Render a PSYC packet into a buffer. + * + * The packet structure should contain the packet parts, either routing, entity, + * method & data, or routing & content when rendering raw content. + * It should also contain the contentLength & total length of the packet, + * you can use psyc_setPacketLength for calculating & setting these values. + * This function renders packet->length bytes to buffer, + * if it doesn't fit in the buffer an error is returned. + * + * @see psyc_newPacket + * @see psyc_newPacket2 + * @see psyc_newRawPacket + * @see psyc_newRawPacket2 + * @see psyc_setPacketLength */ psycRenderRC psyc_render (psycPacket *packet, char *buffer, size_t buflen); /** * Render a PSYC list into a buffer. */ -psycRenderRC psyc_renderList (psycList *list, char *buffer, size_t buflen); +psycRenderListRC psyc_renderList (psycList *list, char *buffer, size_t buflen); /** @} */ // end of render group diff --git a/src/render.c b/src/render.c index c0e0a77..3d9d31b 100644 --- a/src/render.c +++ b/src/render.c @@ -2,13 +2,13 @@ #include #include -psycRenderRC psyc_renderList (psycList *list, char *buffer, size_t buflen) +psycRenderListRC psyc_renderList (psycList *list, char *buffer, size_t buflen) { size_t i, cur = 0; psycString *elem; - if (list->length > buflen) - return PSYC_RENDER_ERROR; // return error if list doesn't fit in buffer + if (list->length > buflen) // return error if list doesn't fit in buffer + return PSYC_RENDER_LIST_ERROR; if (list->flag == PSYC_LIST_NEED_LENGTH) { @@ -34,7 +34,7 @@ psycRenderRC psyc_renderList (psycList *list, char *buffer, size_t buflen) } } - return PSYC_RENDER_SUCCESS; + return PSYC_RENDER_LIST_SUCCESS; } static inline @@ -66,8 +66,8 @@ psycRenderRC psyc_render (psycPacket *packet, char *buffer, size_t buflen) { size_t i, cur = 0, len; - if (packet->length > buflen) - return PSYC_RENDER_ERROR; // return error if packet doesn't fit in buffer + if (packet->length > buflen) // return error if packet doesn't fit in buffer + return PSYC_RENDER_ERROR; // render routing modifiers for (i = 0; i < packet->routing.lines; i++) From 49057824f3f871515d86955514761cca8e2697e2 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 9 May 2011 16:56:26 +0200 Subject: [PATCH 212/378] doc --- include/psyc/render.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/psyc/render.h b/include/psyc/render.h index 9d0b5c4..12fd42d 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -48,9 +48,9 @@ typedef enum * The packet structure should contain the packet parts, either routing, entity, * method & data, or routing & content when rendering raw content. * It should also contain the contentLength & total length of the packet, - * you can use psyc_setPacketLength for calculating & setting these values. - * This function renders packet->length bytes to buffer, - * if it doesn't fit in the buffer an error is returned. + * you can use psyc_setPacketLength() for calculating & setting these values. + * This function renders packet->length bytes to the buffer, + * if buflen is less than that an error is returned. * * @see psyc_newPacket * @see psyc_newPacket2 From 3490df97c9b3e33d8f7a50ebb857c02b5b25218f Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 9 May 2011 17:06:15 +0200 Subject: [PATCH 213/378] + --- include/psyc/packet.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/psyc/packet.h b/include/psyc/packet.h index d16dd1b..94d16f3 100644 --- a/include/psyc/packet.h +++ b/include/psyc/packet.h @@ -55,7 +55,7 @@ typedef enum /** Structure for a modifier. */ typedef struct -t{ +{ char oper; psycString name; psycString value; From 79d3adcd9c7c5ace6cdbdc7454a0b01fbf516e7d Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 9 May 2011 19:21:26 +0200 Subject: [PATCH 214/378] added psyc_isListVar(), removed name param from psyc_parseList(), added more documentation --- include/psyc.h | 19 ++++++++++++++++++ include/psyc/parse.h | 47 ++++++++++++++++++++++++++------------------ src/parse.c | 18 ++++------------- test/testParser.c | 4 ++-- test/testServer.c | 4 ++-- 5 files changed, 55 insertions(+), 37 deletions(-) diff --git a/include/psyc.h b/include/psyc.h index cafc026..2847bfa 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -133,6 +133,25 @@ psycBool psyc_isRoutingVar(const char *name, size_t len); */ psycType psyc_getVarType(const char *name, size_t len); +/** + * Is this a list variable name? + */ +static inline +psycBool psyc_isListVar(psycString *name) +{ + return name->length < 5 || memcmp(name->ptr, "_list", 5) != 0 || + (name->length > 5 && name->ptr[5] != '_') ? PSYC_FALSE : PSYC_TRUE; +} + +/** + * Is this a list variable name? + */ +static inline +psycBool psyc_isListVar2(const char *name, size_t len) +{ + return psyc_isListVar(&(psycString){len, name}); +} + /** * Checks if long keyword string inherits from short keyword string. */ diff --git a/include/psyc/parse.h b/include/psyc/parse.h index 2673e6b..4a5b492 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -54,7 +54,7 @@ * char oper; // operator of the variable (if any) * @endcode * - * They will be passd to the parsing function which will set them to + * They will be passed to the parsing function which will set them to * the according positions and lengths. * * Now the real parsing begins. The parsing function needs to be called @@ -91,7 +91,7 @@ * break; * case PSYC_PARSE_COMPLETE: // parsing of this packet is complete * // You can simply continue parsing till you get the - * // PSYC_PARSE_INSUFFICIENT code which means teh packet is incomplete. + * // PSYC_PARSE_INSUFFICIENT code which means the line is incomplete. * continue; * default: // * perror("Error %i happened :(\n", res); @@ -192,10 +192,9 @@ typedef enum */ typedef enum { - PSYC_PARSE_LIST_ERROR_DELIM = -5, - PSYC_PARSE_LIST_ERROR_LEN = -4, - PSYC_PARSE_LIST_ERROR_TYPE = -3, - PSYC_PARSE_LIST_ERROR_NAME = -2, + PSYC_PARSE_LIST_ERROR_DELIM = -4, + PSYC_PARSE_LIST_ERROR_LEN = -3, + PSYC_PARSE_LIST_ERROR_TYPE = -2, PSYC_PARSE_LIST_ERROR = -1, /// Completed parsing a list element. PSYC_PARSE_LIST_ELEM = 1, @@ -389,26 +388,36 @@ const char * psyc_getParseRemainingBuffer (psycParseState *state) /** * Parse PSYC packets. * - * Generalized line-based packet parser. + * This function parses a full or partial PSYC packet while keeping parsing + * state in a state variable that you have to pass in every time, and returns + * whenever a modifier or the body is found. See psycParseRC for the possible + * return codes. When it returns oper, name & value will point to the respective + * parts of the buffer, no memory allocation is done. * - * This function never allocates heap memory. - * - * @param state An initialized psycParseState - * @param oper A pointer to a character. In case of a variable, it will - * be set to the operator of that variable - * @param name A pointer to a psycString. It will point to the name of - * the variable or method and its length will be set accordingly - * @param value A pointer to a psycString. It will point to the - * value/body the variable/method and its length will be set accordingly + * @param state An initialized psycParseState. + * @param oper In case of a modifier it will be set to the operator. + * @param name In case of a modifier it will point to the name, + * in case of the body it will point to the method. + * @param value In case of a modifier it will point to the value, + * in case of the body it will point to the data. */ psycParseRC psyc_parse (psycParseState *state, char *oper, psycString *name, psycString *value); /** - * List value parser. + * List parser. + * + * This function parses a _list modifier value and returns one element a time + * while keeping parsing state in a state variable that you have to pass in + * every time. When it returns elem will point to the next element in value, no + * memory allocation is done. + * + * @param state An initialized psycParseListState. + * @param value Contains the list to be parsed. + * @param elem It will point to the next element in the list. */ -psycParseListRC psyc_parseList (psycParseListState *state, psycString *name, - psycString *value, psycString *elem); +psycParseListRC psyc_parseList (psycParseListState *state, psycString *value, + psycString *elem); /** @} */ // end of parse group diff --git a/src/parse.c b/src/parse.c index d11db10..0bfc6c1 100644 --- a/src/parse.c +++ b/src/parse.c @@ -201,10 +201,7 @@ parseRC psyc_parseModifier (psycParseState *state, char *oper, return PSYC_PARSE_ERROR_MOD_TAB; } -/** - * Parse PSYC packets. - * Generalized line-based parser. - */ +/** Parse PSYC packets. */ psycParseRC psyc_parse (psycParseState *state, char *oper, psycString *name, psycString *value) { @@ -485,12 +482,9 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, return PSYC_PARSE_ERROR; // should not be reached } -/** - * List value parser. - * @return see psycListRC. - */ -psycParseListRC psyc_parseList (psycParseListState *state, psycString *name, - psycString *value, psycString *elem) +/** List parser. */ +psycParseListRC psyc_parseList (psycParseListState *state, psycString *value, + psycString *elem) { if (state->cursor >= state->buffer.length) return PSYC_PARSE_LIST_INCOMPLETE; @@ -499,10 +493,6 @@ psycParseListRC psyc_parseList (psycParseListState *state, psycString *name, 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_ - return PSYC_PARSE_LIST_ERROR_NAME; - // First character is either | for text lists, or a number for binary lists if (state->buffer.ptr[state->cursor] == '|') { diff --git a/test/testParser.c b/test/testParser.c index bbba26f..e312910 100644 --- a/test/testParser.c +++ b/test/testParser.c @@ -59,7 +59,7 @@ int main (int argc, char **argv) (int)name.length, name.ptr, (int)value.length, value.ptr); - if (name.length >= 5 && memcmp(name.ptr, "_list", 5) == 0) + if (psyc_isListVar(&name)) { if (verbose) printf(">> LIST START\n"); @@ -67,7 +67,7 @@ int main (int argc, char **argv) psyc_initParseListState(&listState); psyc_setParseListBuffer(&listState, value); - while ((ret = psyc_parseList(&listState, &name, &value, &elem))) + while ((ret = psyc_parseList(&listState, &value, &elem))) { switch (ret) { diff --git a/test/testServer.c b/test/testServer.c index 620580f..78dbcc1 100644 --- a/test/testServer.c +++ b/test/testServer.c @@ -443,7 +443,7 @@ int main (int argc, char **argv) name.length = 0; value.length = 0; - if (pname->length >= 5 && memcmp(pname->ptr, "_list", 5) == 0) + if (psyc_isListVar(pname)) { if (verbose >= 2) printf("## LIST START\n"); @@ -453,7 +453,7 @@ int main (int argc, char **argv) do { - retl = psyc_parseList(&listState, pname, pvalue, &elem); + retl = psyc_parseList(&listState, pvalue, &elem); switch (retl) { case PSYC_PARSE_LIST_END: From 248e9234e15d1b76f45ee08119985e34974191a6 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 10 May 2011 16:54:40 +0200 Subject: [PATCH 215/378] make clean --- Makefile | 3 +++ lib/Makefile | 3 +++ src/Makefile | 3 ++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 1cb161a..7365ae0 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,8 @@ all: ${MAKE} -C src +it: all + install: install-lib install-inc install-d install-lib: all @@ -33,6 +35,7 @@ doc: clean: ${MAKE} -C src clean + ${MAKE} -C lib clean ${MAKE} -C test clean rm -rf doc/html doc/latex doc/man diff --git a/lib/Makefile b/lib/Makefile index 6b53b18..fa8114a 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -11,3 +11,6 @@ libdir: ${LIBS}: libdir ${INSTALL} $@ ${libdir} + +clean: + rm -f ${LIBS} diff --git a/src/Makefile b/src/Makefile index f7dacad..25df0c6 100644 --- a/src/Makefile +++ b/src/Makefile @@ -5,6 +5,7 @@ DIET = diet S = packet.c parse.c match.c render.c memmem.c itoa.c variable.c text.c O = packet.o parse.o match.o render.o memmem.o itoa.o variable.o text.o +P = match itoa all: CC := ${WRAPPER} ${CC} all: lib @@ -30,7 +31,7 @@ itoa: itoa.c it: match clean: - rm -f $O ../lib/libpsyc.a + rm -f $O $P help: @/bin/echo -e "Usage:\n\tmake - compile\n\tmake diet - compile with diet libc" From 0b823493f920a76031a64c1330e0d3c20a282567 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 13 May 2011 17:02:31 +0200 Subject: [PATCH 216/378] parseList: removed unused value parameter --- include/psyc/parse.h | 3 +-- src/Makefile | 2 +- src/parse.c | 3 +-- src/render.c | 2 ++ test/testParser.c | 2 +- test/testServer.c | 4 ++-- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/psyc/parse.h b/include/psyc/parse.h index 4a5b492..edc4117 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -416,8 +416,7 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, * @param value Contains the list to be parsed. * @param elem It will point to the next element in the list. */ -psycParseListRC psyc_parseList (psycParseListState *state, psycString *value, - psycString *elem); +psycParseListRC psyc_parseList (psycParseListState *state, psycString *elem); /** @} */ // end of parse group diff --git a/src/Makefile b/src/Makefile index 25df0c6..3ef9d67 100644 --- a/src/Makefile +++ b/src/Makefile @@ -20,7 +20,7 @@ diet: lib lib: $O @mkdir -p ../lib - ${WRAPPER} ar rcs ../lib/libpsyc.a $O + ${WRAPPER} ${AR} rcs ../lib/libpsyc.a $O match: match.c ${CC} -o $@ -DDEBUG=4 -DCMDTOOL -DTEST $< diff --git a/src/parse.c b/src/parse.c index 0bfc6c1..a1f5798 100644 --- a/src/parse.c +++ b/src/parse.c @@ -483,8 +483,7 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, } /** List parser. */ -psycParseListRC psyc_parseList (psycParseListState *state, psycString *value, - psycString *elem) +psycParseListRC psyc_parseList (psycParseListState *state, psycString *elem) { if (state->cursor >= state->buffer.length) return PSYC_PARSE_LIST_INCOMPLETE; diff --git a/src/render.c b/src/render.c index 3d9d31b..ad4822d 100644 --- a/src/render.c +++ b/src/render.c @@ -34,6 +34,8 @@ psycRenderListRC psyc_renderList (psycList *list, char *buffer, size_t buflen) } } + // actual length should be equal to pre-calculated length at this point + assert(cur == list->length); return PSYC_RENDER_LIST_SUCCESS; } diff --git a/test/testParser.c b/test/testParser.c index e312910..641c70d 100644 --- a/test/testParser.c +++ b/test/testParser.c @@ -67,7 +67,7 @@ int main (int argc, char **argv) psyc_initParseListState(&listState); psyc_setParseListBuffer(&listState, value); - while ((ret = psyc_parseList(&listState, &value, &elem))) + while ((ret = psyc_parseList(&listState, &elem))) { switch (ret) { diff --git a/test/testServer.c b/test/testServer.c index 78dbcc1..44cf31e 100644 --- a/test/testServer.c +++ b/test/testServer.c @@ -453,7 +453,7 @@ int main (int argc, char **argv) do { - retl = psyc_parseList(&listState, pvalue, &elem); + retl = psyc_parseList(&listState, &elem); switch (retl) { case PSYC_PARSE_LIST_END: @@ -468,7 +468,7 @@ int main (int argc, char **argv) break; default: - printf("# Error while parsing list: %i\n", ret); + printf("# Error while parsing list: %i\n", retl); ret = retl = -1; } } From 0d415308b8cc0e2c1ebecafbfe733cf3d8c37a5c Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 13 May 2011 23:31:43 +0200 Subject: [PATCH 217/378] testServer: no_render option --- test/testServer.c | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/test/testServer.c b/test/testServer.c index 44cf31e..f57c72c 100644 --- a/test/testServer.c +++ b/test/testServer.c @@ -62,6 +62,7 @@ int main (int argc, char **argv) w - v > 0 && memchr(w+1, (int)'v', strlen(opts) - (w - opts)) ? 3 : 2 : 1 : 0; uint8_t routing_only = opts && memchr(opts, (int)'r', strlen(opts)); uint8_t parse_multiple = opts && memchr(opts, (int)'m', strlen(opts)); + uint8_t no_render = opts && memchr(opts, (int)'n', strlen(opts)); uint8_t progress = opts && memchr(opts, (int)'p', strlen(opts)); uint8_t stats = opts && memchr(opts, (int)'s', strlen(opts)); size_t recv_buf_size = argc > 3 ? atoi(argv[3]) : 0; @@ -114,7 +115,7 @@ int main (int argc, char **argv) hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; if ((rv = getaddrinfo(NULL, port, &hints, &ai)) != 0) -{ + { fprintf(stderr, "error: %s\n", gai_strerror(rv)); exit(1); } @@ -295,30 +296,33 @@ int main (int argc, char **argv) if (!parse_multiple) // parse multiple packets? ret = -1; - packets[i].flag = psyc_isParseContentLengthFound(&parsers[i]) ? - PSYC_PACKET_NEED_LENGTH : PSYC_PACKET_NO_LENGTH; - - if (routing_only) + if (!no_render) { - packets[i].content = packets[i].data; - resetString(&packets[i].data, 0); - } + packets[i].flag = psyc_isParseContentLengthFound(&parsers[i]) ? + PSYC_PACKET_NEED_LENGTH : PSYC_PACKET_NO_LENGTH; - psyc_setPacketLength(&packets[i]); - - if (psyc_render(&packets[i], sendbuf, SEND_BUF_SIZE) == PSYC_RENDER_SUCCESS) - { - if (send(i, sendbuf, packets[i].length, 0) == -1) + if (routing_only) { - perror("send error"); + packets[i].content = packets[i].data; + resetString(&packets[i].data, 0); + } + + psyc_setPacketLength(&packets[i]); + + if (psyc_render(&packets[i], sendbuf, SEND_BUF_SIZE) == PSYC_RENDER_SUCCESS) + { + if (send(i, sendbuf, packets[i].length, 0) == -1) + { + perror("send error"); + ret = -1; + } + } + else + { + perror("render error"); ret = -1; } } - else - { - perror("render error"); - ret = -1; - } // reset packet packets[i].routingLength = 0; From bafa18f7b79e2349902e139c8c62eb10ec62d52e Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sat, 14 May 2011 02:18:01 +0200 Subject: [PATCH 218/378] testServer: moved psyc parse & render code to separate file --- test/testServer.c | 372 ++++-------------------------------------- test/testServer.h | 21 +++ test/testServerPsyc.c | 275 +++++++++++++++++++++++++++++++ 3 files changed, 326 insertions(+), 342 deletions(-) create mode 100644 test/testServer.h create mode 100644 test/testServerPsyc.c diff --git a/test/testServer.c b/test/testServer.c index f57c72c..75ede08 100644 --- a/test/testServer.c +++ b/test/testServer.c @@ -1,5 +1,5 @@ /** - * libpsyc test server for packet parsing & rendering + * test server for packet parsing & rendering * * based on selectserver.c from http://beej.us/guide/bgnet/ * "The C source code presented in this document is hereby granted to the public domain, and is completely free of any license restriction." @@ -17,54 +17,30 @@ #include #define __USE_POSIX #include -#include -#include -#include -#include -#include -#include - -const size_t RECV_BUF_SIZE = 8 * 1024; -const size_t CONT_BUF_SIZE = 8 * 1024; -const size_t SEND_BUF_SIZE = 8 * 1024; -const size_t NUM_PARSERS = 100; -// max size for routing & entity header -const size_t ROUTING_LINES = 16; -const size_t ENTITY_LINES = 32; - -static inline -void resetString (psycString *s, uint8_t freeptr) -{ - if (freeptr && s->length) - free((void*)s->ptr); - - s->ptr = NULL; - s->length = 0; -} +#include "testServer.h" +#include "testServerPsyc.c" // get sockaddr, IPv4 or IPv6: -void *get_in_addr (struct sockaddr *sa) -{ +void *get_in_addr (struct sockaddr *sa) { if (sa->sa_family == AF_INET) return &(((struct sockaddr_in*)sa)->sin_addr); return &(((struct sockaddr_in6*)sa)->sin6_addr); } -int main (int argc, char **argv) -{ +int main (int argc, char **argv) { char *port = argc > 1 ? argv[1] : "4440"; char *opts = argc > 2 ? argv[2] : NULL; char *v, *w; - uint8_t verbose = opts && (v = memchr(opts, (int)'v', strlen(opts))) ? + verbose = opts && (v = memchr(opts, (int)'v', strlen(opts))) ? v - opts > 0 && (w = memchr(v+1, (int)'v', strlen(opts) - (v - opts))) ? w - v > 0 && memchr(w+1, (int)'v', strlen(opts) - (w - opts)) ? 3 : 2 : 1 : 0; - uint8_t routing_only = opts && memchr(opts, (int)'r', strlen(opts)); - uint8_t parse_multiple = opts && memchr(opts, (int)'m', strlen(opts)); - uint8_t no_render = opts && memchr(opts, (int)'n', strlen(opts)); - uint8_t progress = opts && memchr(opts, (int)'p', strlen(opts)); - uint8_t stats = opts && memchr(opts, (int)'s', strlen(opts)); + routing_only = opts && memchr(opts, (int)'r', strlen(opts)); + parse_multiple = opts && memchr(opts, (int)'m', strlen(opts)); + no_render = opts && memchr(opts, (int)'n', strlen(opts)); + progress = opts && memchr(opts, (int)'p', strlen(opts)); + stats = opts && memchr(opts, (int)'s', strlen(opts)); size_t recv_buf_size = argc > 3 ? atoi(argv[3]) : 0; if (recv_buf_size <= 0) recv_buf_size = RECV_BUF_SIZE; @@ -78,34 +54,14 @@ int main (int argc, char **argv) struct sockaddr_storage remoteaddr; // client address socklen_t addrlen; - char buf[CONT_BUF_SIZE + RECV_BUF_SIZE]; // cont buf + recv buf: [ ccrrrr] - char *recvbuf = buf + CONT_BUF_SIZE; // recv buf: ^^^^ - char *parsebuf; // parse buf: ^^^^^^ - char sendbuf[SEND_BUF_SIZE]; - size_t nbytes, contbytes = 0; - char remoteIP[INET6_ADDRSTRLEN]; int yes = 1; // for setsockopt() SO_REUSEADDR, below - int i, j, rv; + int i, rv, ret; struct addrinfo hints, *ai, *p; - - psycParseState parsers[NUM_PARSERS]; - psycPacket packets[NUM_PARSERS]; - psycModifier routing[NUM_PARSERS][ROUTING_LINES]; - psycModifier entity[NUM_PARSERS][ENTITY_LINES]; - psycModifier *mod = NULL; - struct timeval start[NUM_PARSERS], end[NUM_PARSERS]; - int ret, retl; - char oper; - psycString name, value, elem; - psycString *pname = NULL, *pvalue = NULL; - psycParseListState listState; - size_t len; - FD_ZERO(&master); // clear the master and temp sets FD_ZERO(&read_fds); @@ -114,14 +70,12 @@ int main (int argc, char **argv) hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; - if ((rv = getaddrinfo(NULL, port, &hints, &ai)) != 0) - { + if ((rv = getaddrinfo(NULL, port, &hints, &ai)) != 0) { fprintf(stderr, "error: %s\n", gai_strerror(rv)); exit(1); } - for (p = ai; p != NULL; p = p->ai_next) - { + for (p = ai; p != NULL; p = p->ai_next) { listener = socket(p->ai_family, p->ai_socktype, p->ai_protocol); if (listener < 0) continue; @@ -129,8 +83,7 @@ int main (int argc, char **argv) // lose the pesky "address already in use" error message setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); - if (bind(listener, p->ai_addr, p->ai_addrlen) < 0) - { + if (bind(listener, p->ai_addr, p->ai_addrlen) < 0) { close(listener); continue; } @@ -139,8 +92,7 @@ int main (int argc, char **argv) } // if we got here, it means we didn't get bound - if (p == NULL) - { + if (p == NULL) { fprintf(stderr, "failed to bind\n"); exit(2); } @@ -148,8 +100,7 @@ int main (int argc, char **argv) freeaddrinfo(ai); // all done with this // listen - if (listen(listener, 10) == -1) - { + if (listen(listener, 10) == -1) { perror("listen"); exit(3); } @@ -161,22 +112,17 @@ int main (int argc, char **argv) fdmax = listener; // so far, it's this one // main loop - for (;;) - { + for (;;) { read_fds = master; // copy it - if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) - { + if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) { perror("select"); exit(4); } // run through the existing connections looking for data to read - for (i = 0; i <= fdmax; i++) - { - if (FD_ISSET(i, &read_fds)) // we got one!! - { - if (i == listener) - { + for (i = 0; i <= fdmax; i++) { + if (FD_ISSET(i, &read_fds)) { // we got one!! + if (i == listener) { // handle new connections if (fdmax == NUM_PARSERS - 1) continue; // ignore if there's too many @@ -184,25 +130,14 @@ int main (int argc, char **argv) addrlen = sizeof remoteaddr; newfd = accept(listener, (struct sockaddr *)&remoteaddr, &addrlen); - if (newfd == -1) + if (newfd == -1) { perror("accept"); - else - { + } else { FD_SET(newfd, &master); // add to master set if (newfd > fdmax) // keep track of the max fdmax = newfd; - // reset parser state & packet - if (routing_only) - psyc_initParseState2(&parsers[newfd], PSYC_PARSE_ROUTING_ONLY); - else - psyc_initParseState(&parsers[newfd]); - - memset(&packets[newfd], 0, sizeof(psycPacket)); - memset(&routing[newfd], 0, sizeof(psycModifier) * ROUTING_LINES); - memset(&entity[newfd], 0, sizeof(psycModifier) * ENTITY_LINES); - packets[newfd].routing.modifiers = routing[newfd]; - packets[newfd].entity.modifiers = entity[newfd]; + test_init(newfd); if (verbose) printf("# New connection from %s on socket %d\n", @@ -214,12 +149,9 @@ int main (int argc, char **argv) if (stats) gettimeofday(&start[newfd], NULL); } - } - else - { + } else { // handle data from a client - if ((nbytes = recv(i, recvbuf, recv_buf_size, 0)) <= 0) - { + if ((nbytes = recv(i, recvbuf, recv_buf_size, 0)) <= 0) { if (stats) printf("%ld ms\n", (end[i].tv_sec * 1000000 + end[i].tv_usec - start[i].tv_sec * 1000000 - start[i].tv_usec) / 1000); @@ -231,256 +163,13 @@ int main (int argc, char **argv) close(i); // bye! FD_CLR(i, &master); // remove from master set - } - else - { + } else { if (verbose >= 2) printf("> %ld bytes\n", nbytes); if (verbose >= 3) printf("> [%.*s]", (int)nbytes, recvbuf); - // we got some data from a client - parsebuf = recvbuf - contbytes; - psyc_setParseBuffer2(&parsers[i], parsebuf, contbytes + nbytes); - contbytes = 0; - oper = 0; - name.length = 0; - value.length = 0; - - do - { - ret = psyc_parse(&parsers[i], &oper, &name, &value); - if (verbose >= 2) - printf("# ret = %d\n", ret); - - switch (ret) { - case PSYC_PARSE_ROUTING: - assert(packets[i].routing.lines < ROUTING_LINES); - mod = &(packets[i].routing.modifiers[packets[i].routing.lines]); - pname = &mod->name; - pvalue = &mod->value; - mod->flag = PSYC_MODIFIER_ROUTING; - packets[i].routing.lines++; - break; - - case PSYC_PARSE_ENTITY_START: - case PSYC_PARSE_ENTITY_CONT: - case PSYC_PARSE_ENTITY_END: - case PSYC_PARSE_ENTITY: - assert(packets[i].entity.lines < ENTITY_LINES); - mod = &(packets[i].entity.modifiers[packets[i].entity.lines]); - pname = &mod->name; - pvalue = &mod->value; - - if (ret == PSYC_PARSE_ENTITY || ret == PSYC_PARSE_ENTITY_END) - { - packets[i].entity.lines++; - mod->flag = psyc_isParseValueLengthFound(&parsers[i]) ? - PSYC_MODIFIER_NEED_LENGTH : PSYC_MODIFIER_NO_LENGTH; - } - break; - - case PSYC_PARSE_BODY_START: - case PSYC_PARSE_BODY_CONT: - case PSYC_PARSE_BODY_END: - case PSYC_PARSE_BODY: - pname = &(packets[i].method); - pvalue = &(packets[i].data); - break; - - case PSYC_PARSE_COMPLETE: - if (verbose) - printf("# Done parsing.\n"); - else if (progress) - write(1, ".", 1); - if (!parse_multiple) // parse multiple packets? - ret = -1; - - if (!no_render) - { - packets[i].flag = psyc_isParseContentLengthFound(&parsers[i]) ? - PSYC_PACKET_NEED_LENGTH : PSYC_PACKET_NO_LENGTH; - - if (routing_only) - { - packets[i].content = packets[i].data; - resetString(&packets[i].data, 0); - } - - psyc_setPacketLength(&packets[i]); - - if (psyc_render(&packets[i], sendbuf, SEND_BUF_SIZE) == PSYC_RENDER_SUCCESS) - { - if (send(i, sendbuf, packets[i].length, 0) == -1) - { - perror("send error"); - ret = -1; - } - } - else - { - perror("render error"); - ret = -1; - } - } - - // reset packet - packets[i].routingLength = 0; - packets[i].contentLength = 0; - packets[i].length = 0; - packets[i].flag = 0; - - for (j = 0; j < packets[i].routing.lines; j++) - { - resetString(&packets[i].routing.modifiers[j].name, 1); - resetString(&packets[i].routing.modifiers[j].value, 1); - } - packets[i].routing.lines = 0; - - if (routing_only) - { - resetString(&packets[i].content, 1); - } - else - { - for (j = 0; j < packets[i].entity.lines; j++) - { - resetString(&packets[i].entity.modifiers[j].name, 1); - resetString(&packets[i].entity.modifiers[j].value, 1); - } - packets[i].entity.lines = 0; - - resetString(&packets[i].method, 1); - resetString(&packets[i].data, 1); - } - - break; - - case PSYC_PARSE_INSUFFICIENT: - if (verbose >= 2) - printf("# Insufficient data.\n"); - - contbytes = psyc_getParseRemainingLength(&parsers[i]); - - if (contbytes > 0) // copy end of parsebuf before start of recvbuf - { - assert(recvbuf - contbytes >= buf); // make sure it's still in the buffer - memmove(recvbuf - contbytes, psyc_getParseRemainingBuffer(&parsers[i]), contbytes); - } - ret = 0; - break; - - default: - printf("# Error while parsing: %i\n", ret); - ret = -1; - } - - switch (ret) - { - case PSYC_PARSE_ENTITY_START: - case PSYC_PARSE_ENTITY_CONT: - case PSYC_PARSE_BODY_START: - case PSYC_PARSE_BODY_CONT: - ret = 0; - case PSYC_PARSE_ENTITY: - case PSYC_PARSE_ENTITY_END: - case PSYC_PARSE_ROUTING: - case PSYC_PARSE_BODY: - case PSYC_PARSE_BODY_END: - if (oper) - { - mod->oper = oper; - if (verbose >= 2) - printf("%c", oper); - } - - if (name.length) - { - pname->ptr = malloc(name.length); - pname->length = name.length; - - assert(pname->ptr != NULL); - memcpy((void*)pname->ptr, name.ptr, name.length); - name.length = 0; - - if (verbose >= 2) - printf("%.*s = ", (int)pname->length, pname->ptr); - } - - if (value.length) { - if (!pvalue->length) - { - if (psyc_isParseValueLengthFound(&parsers[i])) - len = psyc_getParseValueLength(&parsers[i]); - else - len = value.length; - pvalue->ptr = malloc(len); - } - assert(pvalue->ptr != NULL); - memcpy((void*)pvalue->ptr + pvalue->length, value.ptr, value.length); - pvalue->length += value.length; - value.length = 0; - - if (verbose >= 2) - { - printf("[%.*s]", (int)pvalue->length, pvalue->ptr); - if (parsers[i].valueLength > pvalue->length) - printf("..."); - printf("\n"); - } - } - else if (verbose) - printf("\n"); - - if (verbose >= 3) - printf("\t\t\t\t\t\t\t\t# n:%ld v:%ld c:%ld r:%ld\n", - pname->length, pvalue->length, - parsers[i].contentParsed, parsers[i].routingLength); - } - - switch (ret) - { - case PSYC_PARSE_ROUTING: - case PSYC_PARSE_ENTITY: - case PSYC_PARSE_ENTITY_END: - oper = 0; - name.length = 0; - value.length = 0; - - if (psyc_isListVar(pname)) - { - if (verbose >= 2) - printf("## LIST START\n"); - - psyc_initParseListState(&listState); - psyc_setParseListBuffer(&listState, *pvalue); - - do - { - retl = psyc_parseList(&listState, &elem); - switch (retl) - { - case PSYC_PARSE_LIST_END: - retl = 0; - case PSYC_PARSE_LIST_ELEM: - if (verbose >= 2) - { - printf("|%.*s\n", (int)elem.length, elem.ptr); - if (ret == PSYC_PARSE_LIST_END) - printf("## LIST END"); - } - break; - - default: - printf("# Error while parsing list: %i\n", retl); - ret = retl = -1; - } - } - while (retl > 0); - } - } - } - while (ret > 0); + ret = test_input(i); if (progress) write(1, " ", 1); @@ -488,8 +177,7 @@ int main (int argc, char **argv) if (stats) gettimeofday(&end[i], NULL); - if (ret < 0) - { + if (ret < 0) { if (verbose) printf("# Closing connection: %i\n", i); close(i); // bye! diff --git a/test/testServer.h b/test/testServer.h new file mode 100644 index 0000000..16bb9e1 --- /dev/null +++ b/test/testServer.h @@ -0,0 +1,21 @@ +#ifndef TESTSERVER_H +# define TESTSERVER_H + +# define RECV_BUF_SIZE 8 * 1024 +# define CONT_BUF_SIZE 8 * 1024 +# define SEND_BUF_SIZE 8 * 1024 +# define NUM_PARSERS 100 + +char sendbuf[SEND_BUF_SIZE]; +char buf[CONT_BUF_SIZE + RECV_BUF_SIZE]; // cont buf + recv buf: [ ccrrrr] +char *recvbuf = buf + CONT_BUF_SIZE; // recv buf: ^^^^ + // parse buf: ^^^^^^ + +// cmd line args +uint8_t verbose, routing_only, parse_multiple, no_render, progress, stats; +size_t nbytes; + +void test_init(int i); +int test_input(int i); + +#endif diff --git a/test/testServerPsyc.c b/test/testServerPsyc.c new file mode 100644 index 0000000..86dfe4f --- /dev/null +++ b/test/testServerPsyc.c @@ -0,0 +1,275 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "testServer.h" + +// max size for routing & entity header +#define ROUTING_LINES 16 +#define ENTITY_LINES 32 + +psycParseState parsers[NUM_PARSERS]; +psycPacket packets[NUM_PARSERS]; +psycModifier routing[NUM_PARSERS][ROUTING_LINES]; +psycModifier entity[NUM_PARSERS][ENTITY_LINES]; +psycModifier *mod = NULL; + +int ret, retl, contbytes = 0; +char oper; +psycString name, value, elem; +psycString *pname = NULL, *pvalue = NULL; +psycParseListState listState; +size_t len; + +static inline +void resetString (psycString *s, uint8_t freeptr) { + if (freeptr && s->length) + free((void*)s->ptr); + + s->ptr = NULL; + s->length = 0; +} + +void test_init (int i) { + // reset parser state & packet + if (routing_only) + psyc_initParseState2(&parsers[i], PSYC_PARSE_ROUTING_ONLY); + else + psyc_initParseState(&parsers[i]); + + memset(&packets[i], 0, sizeof(psycPacket)); + memset(&routing[i], 0, sizeof(psycModifier) * ROUTING_LINES); + memset(&entity[i], 0, sizeof(psycModifier) * ENTITY_LINES); + packets[i].routing.modifiers = routing[i]; + packets[i].entity.modifiers = entity[i]; +} + +int test_input (int i) { + // we got some data from a client + int j; + char *parsebuf = recvbuf - contbytes; + psyc_setParseBuffer2(&parsers[i], parsebuf, contbytes + nbytes); + contbytes = 0; + oper = 0; + name.length = 0; + value.length = 0; + + do { + ret = psyc_parse(&parsers[i], &oper, &name, &value); + if (verbose >= 2) + printf("# ret = %d\n", ret); + + switch (ret) { + case PSYC_PARSE_ROUTING: + assert(packets[i].routing.lines < ROUTING_LINES); + mod = &(packets[i].routing.modifiers[packets[i].routing.lines]); + pname = &mod->name; + pvalue = &mod->value; + mod->flag = PSYC_MODIFIER_ROUTING; + packets[i].routing.lines++; + break; + + case PSYC_PARSE_ENTITY_START: + case PSYC_PARSE_ENTITY_CONT: + case PSYC_PARSE_ENTITY_END: + case PSYC_PARSE_ENTITY: + assert(packets[i].entity.lines < ENTITY_LINES); + mod = &(packets[i].entity.modifiers[packets[i].entity.lines]); + pname = &mod->name; + pvalue = &mod->value; + + if (ret == PSYC_PARSE_ENTITY || ret == PSYC_PARSE_ENTITY_END) { + packets[i].entity.lines++; + mod->flag = psyc_isParseValueLengthFound(&parsers[i]) ? + PSYC_MODIFIER_NEED_LENGTH : PSYC_MODIFIER_NO_LENGTH; + } + break; + + case PSYC_PARSE_BODY_START: + case PSYC_PARSE_BODY_CONT: + case PSYC_PARSE_BODY_END: + case PSYC_PARSE_BODY: + pname = &(packets[i].method); + pvalue = &(packets[i].data); + break; + + case PSYC_PARSE_COMPLETE: + if (verbose) + printf("# Done parsing.\n"); + else if (progress) + write(1, ".", 1); + if (!parse_multiple) // parse multiple packets? + ret = -1; + + if (!no_render) { + packets[i].flag = psyc_isParseContentLengthFound(&parsers[i]) ? + PSYC_PACKET_NEED_LENGTH : PSYC_PACKET_NO_LENGTH; + + if (routing_only) { + packets[i].content = packets[i].data; + resetString(&packets[i].data, 0); + } + + psyc_setPacketLength(&packets[i]); + + if (psyc_render(&packets[i], sendbuf, SEND_BUF_SIZE) == PSYC_RENDER_SUCCESS) { + if (send(i, sendbuf, packets[i].length, 0) == -1) { + perror("send error"); + ret = -1; + } + } else { + perror("render error"); + ret = -1; + } + } + + // reset packet + packets[i].routingLength = 0; + packets[i].contentLength = 0; + packets[i].length = 0; + packets[i].flag = 0; + + for (j = 0; j < packets[i].routing.lines; j++) { + resetString(&packets[i].routing.modifiers[j].name, 1); + resetString(&packets[i].routing.modifiers[j].value, 1); + } + packets[i].routing.lines = 0; + + if (routing_only) { + resetString(&packets[i].content, 1); + } else { + for (j = 0; j < packets[i].entity.lines; j++) { + resetString(&packets[i].entity.modifiers[j].name, 1); + resetString(&packets[i].entity.modifiers[j].value, 1); + } + packets[i].entity.lines = 0; + + resetString(&packets[i].method, 1); + resetString(&packets[i].data, 1); + } + + break; + + case PSYC_PARSE_INSUFFICIENT: + if (verbose >= 2) + printf("# Insufficient data.\n"); + + contbytes = psyc_getParseRemainingLength(&parsers[i]); + + if (contbytes > 0) { // copy end of parsebuf before start of recvbuf + assert(recvbuf - contbytes >= buf); // make sure it's still in the buffer + memmove(recvbuf - contbytes, psyc_getParseRemainingBuffer(&parsers[i]), contbytes); + } + ret = 0; + break; + + default: + printf("# Error while parsing: %i\n", ret); + ret = -1; + } + + switch (ret) { + case PSYC_PARSE_ENTITY_START: + case PSYC_PARSE_ENTITY_CONT: + case PSYC_PARSE_BODY_START: + case PSYC_PARSE_BODY_CONT: + ret = 0; + case PSYC_PARSE_ENTITY: + case PSYC_PARSE_ENTITY_END: + case PSYC_PARSE_ROUTING: + case PSYC_PARSE_BODY: + case PSYC_PARSE_BODY_END: + if (oper) { + mod->oper = oper; + if (verbose >= 2) + printf("%c", oper); + } + + if (name.length) { + pname->ptr = malloc(name.length); + pname->length = name.length; + + assert(pname->ptr != NULL); + memcpy((void*)pname->ptr, name.ptr, name.length); + name.length = 0; + + if (verbose >= 2) + printf("%.*s = ", (int)pname->length, pname->ptr); + } + + if (value.length) { + if (!pvalue->length) { + if (psyc_isParseValueLengthFound(&parsers[i])) + len = psyc_getParseValueLength(&parsers[i]); + else + len = value.length; + pvalue->ptr = malloc(len); + } + assert(pvalue->ptr != NULL); + memcpy((void*)pvalue->ptr + pvalue->length, value.ptr, value.length); + pvalue->length += value.length; + value.length = 0; + + if (verbose >= 2) { + printf("[%.*s]", (int)pvalue->length, pvalue->ptr); + if (parsers[i].valueLength > pvalue->length) + printf("..."); + printf("\n"); + } + } + else if (verbose) + printf("\n"); + + if (verbose >= 3) + printf("\t\t\t\t\t\t\t\t# n:%ld v:%ld c:%ld r:%ld\n", + pname->length, pvalue->length, + parsers[i].contentParsed, parsers[i].routingLength); + } + + switch (ret) { + case PSYC_PARSE_ROUTING: + case PSYC_PARSE_ENTITY: + case PSYC_PARSE_ENTITY_END: + oper = 0; + name.length = 0; + value.length = 0; + + if (psyc_isListVar(pname)) { + if (verbose >= 2) + printf("## LIST START\n"); + + psyc_initParseListState(&listState); + psyc_setParseListBuffer(&listState, *pvalue); + + do { + retl = psyc_parseList(&listState, &elem); + switch (retl) { + case PSYC_PARSE_LIST_END: + retl = 0; + case PSYC_PARSE_LIST_ELEM: + if (verbose >= 2) { + printf("|%.*s\n", (int)elem.length, elem.ptr); + if (ret == PSYC_PARSE_LIST_END) + printf("## LIST END"); + } + break; + + default: + printf("# Error while parsing list: %i\n", retl); + ret = retl = -1; + } + } + while (retl > 0); + } + } + } + while (ret > 0); + return ret; +} From e71f5a92911e7573d6e468cbc64c3655b7c75aef Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Sat, 14 May 2011 18:18:54 +0200 Subject: [PATCH 219/378] first suggestions for a benchmark --- bench/benchmark.wiki | 53 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 bench/benchmark.wiki diff --git a/bench/benchmark.wiki b/bench/benchmark.wiki new file mode 100644 index 0000000..c0a1228 --- /dev/null +++ b/bench/benchmark.wiki @@ -0,0 +1,53 @@ += libpsyc Performance Benchmarks = + +In this document we present the results of performance benchmarks +of libpsyc compared with libjson-glib and libxml2. + +== Procedure == + +We'll use typical messages from the XMPP ("stanzas" in Jabber +lingo) and compare them with equivalent PSYC packets and +JSON encodings. + +In some cases we will additionally compare PSYC packets to +a more efficient XML encoding based on PSYC methods, to have +a more accurate comparison of the actual PSYC and XML +syntaxes, rather than the protocol structures of PSYC and XMPP. + +== Caveats == + +In every case we'll compare performance of parsing and re-rendering +these messages, but consider also that the applicative processing +of an XML DOM tree is more complicated than just accessing +certain elements in a JSON data structure or PSYC variable +mapping. + +For a speed check in real world conditions which also consider the +complexity of processing incoming messages we should compare +the performance of a chat client using the two protocols, +for instance by using libpurple with XMPP and PSYC accounts. +To this purpose we first need to integrate libpsyc into libpurple. + +== The Benchmarks == + +=== A presence packet === + +Since presence packets are by far the dominant messaging content +in the XMPP network, we'll start with one of them. + +
+...
+
+ +and here's the same information in a JSON rendition: + +
+...
+
+ +=== An average chat message === +=== A social network activity === +=== A message with JSON-unfriendly characters === +=== A message with XML-unfriendly characters === +=== A packet containing a JPEG photograph === + From 5b7364650803e73196c2dda432900a9213e8b5ac Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sat, 14 May 2011 18:21:00 +0200 Subject: [PATCH 220/378] testServer modularizing --- .gitignore | 2 +- test/Makefile | 20 +++++++++++--------- test/testServer.c | 33 +++++++++++---------------------- test/testServer.h | 12 ++---------- test/testServerPsyc.c | 35 +++++++++++++++++++++++++++++++++-- 5 files changed, 58 insertions(+), 44 deletions(-) diff --git a/.gitignore b/.gitignore index 34d93bb..185848a 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,7 @@ src/match test/testMatch test/testParser test/testRender -test/testServer +test/testServerPsyc test/testText test/isRoutingVar test/getVarType diff --git a/test/Makefile b/test/Makefile index 8217eb5..2c6c843 100644 --- a/test/Makefile +++ b/test/Makefile @@ -4,7 +4,8 @@ CFLAGS = -I../include -I../src -Wall -std=c99 ${OPT} LDFLAGS = -L../lib LOADLIBES = -lpsyc -lm LOADLIBES_NET = ${LOADLIBES} -TARGETS = testServer testParser testMatch testRender testText isRoutingVar getVarType +TARGETS = testServerPsyc testParser testMatch testRender testText isRoutingVar getVarType +O = testServer.o WRAPPER = DIET = diet PORT = 4440 @@ -19,7 +20,8 @@ endif all: ${TARGETS} it: all -testServer: LOADLIBES := ${LOADLIBES_NET} +testServerPsyc: LOADLIBES := ${LOADLIBES_NET} +testServerPsyc: testServer.o diet: WRAPPER = ${DIET} diet: all @@ -29,7 +31,7 @@ debug: CFLAGS := $(subst ${OPT},-O0,${CFLAGS}) debug: all clean: - rm -f ${TARGETS} + rm -f ${TARGETS} $O test: ${TARGETS} ./testRender @@ -47,12 +49,12 @@ nettest: nettestfull nettestsplit nettestrun: srvstart pkt srvkill nettestfull: - ${MAKE} nettestrun; x=$$?; pkill -x testServer; exit $$x - ${MAKE} nettestrun srv_args=r; x=$$?; pkill -x testServer; exit $$x + ${MAKE} nettestrun; x=$$?; pkill -x testServerPsyc; exit $$x + ${MAKE} nettestrun srv_args=r; x=$$?; pkill -x testServerPsyc; exit $$x split_max = 10 nettestsplit: - x=0; for n in `seq 1 ${split_max}`; do ${MAKE} nettestrun srv_recvbuf=$$n && ${MAKE} nettestrun srv_args=r srv_recvbuf=$$n || break; done; x=$$?; pkill -x testServer; exit $$x + x=0; for n in `seq 1 ${split_max}`; do ${MAKE} nettestrun srv_recvbuf=$$n && ${MAKE} nettestrun srv_args=r srv_recvbuf=$$n || break; done; x=$$?; pkill -x testServerPsyc; exit $$x pkt: x=0; for f in packets/[0-9]*; do echo ">> $$f"; cat $$f | nc localhost ${PORT} | ${DIFF} -u $$f -; x=$$((x+$$?)); done; exit $$x @@ -64,8 +66,8 @@ pkterr: for f in packets/err-*; do echo ">> $$f"; cat $$f | nc localhost ${PORT}; done srvstart: - pkill -x testServer; exit 0 - ./testServer ${PORT} -${srv_args} ${srv_recvbuf} & + pkill -x testServerPsyc; exit 0 + ./testServerPsyc ${PORT} -${srv_args} ${srv_recvbuf} & srvkill: - pkill -x testServer + pkill -x testServerPsyc diff --git a/test/testServer.c b/test/testServer.c index 75ede08..d74d22a 100644 --- a/test/testServer.c +++ b/test/testServer.c @@ -19,7 +19,9 @@ #include #include "testServer.h" -#include "testServerPsyc.c" + +// cmd line args +extern uint8_t verbose, stats; // get sockaddr, IPv4 or IPv6: void *get_in_addr (struct sockaddr *sa) { @@ -29,21 +31,9 @@ void *get_in_addr (struct sockaddr *sa) { return &(((struct sockaddr_in6*)sa)->sin6_addr); } -int main (int argc, char **argv) { - char *port = argc > 1 ? argv[1] : "4440"; - char *opts = argc > 2 ? argv[2] : NULL; - char *v, *w; - verbose = opts && (v = memchr(opts, (int)'v', strlen(opts))) ? - v - opts > 0 && (w = memchr(v+1, (int)'v', strlen(opts) - (v - opts))) ? - w - v > 0 && memchr(w+1, (int)'v', strlen(opts) - (w - opts)) ? 3 : 2 : 1 : 0; - routing_only = opts && memchr(opts, (int)'r', strlen(opts)); - parse_multiple = opts && memchr(opts, (int)'m', strlen(opts)); - no_render = opts && memchr(opts, (int)'n', strlen(opts)); - progress = opts && memchr(opts, (int)'p', strlen(opts)); - stats = opts && memchr(opts, (int)'s', strlen(opts)); - size_t recv_buf_size = argc > 3 ? atoi(argv[3]) : 0; - if (recv_buf_size <= 0) - recv_buf_size = RECV_BUF_SIZE; +void test_server(const char* port, size_t recv_buf_size) { + char buf[CONT_BUF_SIZE + RECV_BUF_SIZE]; // cont buf + recv buf: [ ccrrrr] + char *recvbuf = buf + CONT_BUF_SIZE; // recv buf: ^^^^ fd_set master; // master file descriptor list fd_set read_fds; // temp file descriptor list for select() @@ -53,6 +43,7 @@ int main (int argc, char **argv) { int newfd; // newly accept()ed socket descriptor struct sockaddr_storage remoteaddr; // client address socklen_t addrlen; + size_t nbytes; char remoteIP[INET6_ADDRSTRLEN]; @@ -62,6 +53,9 @@ int main (int argc, char **argv) { struct addrinfo hints, *ai, *p; struct timeval start[NUM_PARSERS], end[NUM_PARSERS]; + if (recv_buf_size <= 0) + recv_buf_size = RECV_BUF_SIZE; + FD_ZERO(&master); // clear the master and temp sets FD_ZERO(&read_fds); @@ -169,10 +163,7 @@ int main (int argc, char **argv) { if (verbose >= 3) printf("> [%.*s]", (int)nbytes, recvbuf); - ret = test_input(i); - - if (progress) - write(1, " ", 1); + ret = test_input(i, recvbuf, nbytes); if (stats) gettimeofday(&end[i], NULL); @@ -188,6 +179,4 @@ int main (int argc, char **argv) { } // END got new incoming connection } // END looping through file descriptors } // END for(;;)--and you thought it would never end! - - return 0; } diff --git a/test/testServer.h b/test/testServer.h index 16bb9e1..0268769 100644 --- a/test/testServer.h +++ b/test/testServer.h @@ -6,16 +6,8 @@ # define SEND_BUF_SIZE 8 * 1024 # define NUM_PARSERS 100 -char sendbuf[SEND_BUF_SIZE]; -char buf[CONT_BUF_SIZE + RECV_BUF_SIZE]; // cont buf + recv buf: [ ccrrrr] -char *recvbuf = buf + CONT_BUF_SIZE; // recv buf: ^^^^ - // parse buf: ^^^^^^ - -// cmd line args -uint8_t verbose, routing_only, parse_multiple, no_render, progress, stats; -size_t nbytes; - void test_init(int i); -int test_input(int i); +int test_input(int i, char *recvbuf, size_t nbytes); +void test_server(const char* port, size_t recv_buf_size); #endif diff --git a/test/testServerPsyc.c b/test/testServerPsyc.c index 86dfe4f..ddbf959 100644 --- a/test/testServerPsyc.c +++ b/test/testServerPsyc.c @@ -10,17 +10,23 @@ #include #include "testServer.h" +//#include "testServer.c" // max size for routing & entity header #define ROUTING_LINES 16 #define ENTITY_LINES 32 +// cmd line args +uint8_t verbose, stats; + psycParseState parsers[NUM_PARSERS]; psycPacket packets[NUM_PARSERS]; psycModifier routing[NUM_PARSERS][ROUTING_LINES]; psycModifier entity[NUM_PARSERS][ENTITY_LINES]; psycModifier *mod = NULL; +uint8_t routing_only, parse_multiple, no_render, progress; + int ret, retl, contbytes = 0; char oper; psycString name, value, elem; @@ -28,6 +34,25 @@ psycString *pname = NULL, *pvalue = NULL; psycParseListState listState; size_t len; +int main (int argc, char **argv) { + char *port = argc > 1 ? argv[1] : "4440"; + char *opts = argc > 2 ? argv[2] : NULL; + char *v, *w; + verbose = opts && (v = memchr(opts, (int)'v', strlen(opts))) ? + v - opts > 0 && (w = memchr(v+1, (int)'v', strlen(opts) - (v - opts))) ? + w - v > 0 && memchr(w+1, (int)'v', strlen(opts) - (w - opts)) ? 3 : 2 : 1 : 0; + stats = opts && memchr(opts, (int)'s', strlen(opts)); + + routing_only = opts && memchr(opts, (int)'r', strlen(opts)); + parse_multiple = opts && memchr(opts, (int)'m', strlen(opts)); + no_render = opts && memchr(opts, (int)'n', strlen(opts)); + progress = opts && memchr(opts, (int)'p', strlen(opts)); + size_t recv_buf_size = argc > 3 ? atoi(argv[3]) : 0; + + test_server(port, recv_buf_size); + return 0; +} + static inline void resetString (psycString *s, uint8_t freeptr) { if (freeptr && s->length) @@ -51,10 +76,12 @@ void test_init (int i) { packets[i].entity.modifiers = entity[i]; } -int test_input (int i) { +int test_input (int i, char *recvbuf, size_t nbytes) { // we got some data from a client int j; char *parsebuf = recvbuf - contbytes; + char sendbuf[SEND_BUF_SIZE]; + psyc_setParseBuffer2(&parsers[i], parsebuf, contbytes + nbytes); contbytes = 0; oper = 0; @@ -164,7 +191,7 @@ int test_input (int i) { contbytes = psyc_getParseRemainingLength(&parsers[i]); if (contbytes > 0) { // copy end of parsebuf before start of recvbuf - assert(recvbuf - contbytes >= buf); // make sure it's still in the buffer + assert(contbytes <= CONT_BUF_SIZE); // make sure it's still in the buffer memmove(recvbuf - contbytes, psyc_getParseRemainingBuffer(&parsers[i]), contbytes); } ret = 0; @@ -271,5 +298,9 @@ int test_input (int i) { } } while (ret > 0); + + if (progress) + write(1, " ", 1); + return ret; } From a1547d399b0132f6e3d0124f5762f983c1de52ea Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sat, 14 May 2011 18:27:42 +0200 Subject: [PATCH 221/378] + --- test/testServer.c | 1 + test/testServerPsyc.c | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testServer.c b/test/testServer.c index d74d22a..aaaaca1 100644 --- a/test/testServer.c +++ b/test/testServer.c @@ -158,6 +158,7 @@ void test_server(const char* port, size_t recv_buf_size) { close(i); // bye! FD_CLR(i, &master); // remove from master set } else { + // we got some data from a client if (verbose >= 2) printf("> %ld bytes\n", nbytes); if (verbose >= 3) diff --git a/test/testServerPsyc.c b/test/testServerPsyc.c index ddbf959..90335ba 100644 --- a/test/testServerPsyc.c +++ b/test/testServerPsyc.c @@ -77,7 +77,6 @@ void test_init (int i) { } int test_input (int i, char *recvbuf, size_t nbytes) { - // we got some data from a client int j; char *parsebuf = recvbuf - contbytes; char sendbuf[SEND_BUF_SIZE]; From 11bf44ab2ec6b7eb4a2209ee8f4b908868634c13 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Sat, 14 May 2011 19:22:24 +0200 Subject: [PATCH 222/378] two examples to start with --- bench/benchmark.wiki | 105 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 96 insertions(+), 9 deletions(-) diff --git a/bench/benchmark.wiki b/bench/benchmark.wiki index c0a1228..235ff7d 100644 --- a/bench/benchmark.wiki +++ b/bench/benchmark.wiki @@ -6,8 +6,8 @@ of libpsyc compared with libjson-glib and libxml2. == Procedure == We'll use typical messages from the XMPP ("stanzas" in Jabber -lingo) and compare them with equivalent PSYC packets and -JSON encodings. +lingo) and compare them with equivalent JSON encodings, +verbose and compact PSYC formats. In some cases we will additionally compare PSYC packets to a more efficient XML encoding based on PSYC methods, to have @@ -34,16 +34,43 @@ To this purpose we first need to integrate libpsyc into libpurple. Since presence packets are by far the dominant messaging content in the XMPP network, we'll start with one of them. +Here's an example from paragraph 4.4.2 of RFC 6121. -
-...
-
+{{{ + + away + -and here's the same information in a JSON rendition: +}}} -
-...
-
+And here's the same information in a JSON rendition: + +{{{ +... +}}} + +Here's the equivalent PSYC packet in verbose form +(since it is a multicast, the single recipients do not +need to be mentioned): + +{{{ +:_context psyc://example.com/~juliet + +=_degree_availability 4 +_notice_presence +| +}}} + +And the same in compact form: + +{{{ +:c psyc://example.com/~juliet + +=da 4 +np +| +}}} === An average chat message === === A social network activity === @@ -51,3 +78,63 @@ and here's the same information in a JSON rendition: === A message with XML-unfriendly characters === === A packet containing a JPEG photograph === +=== A random data structure === + +In this test we'll not consider XMPP at all and simply compare the +efficiency of the three syntaxes at serializing a typical user data base +storage information. We'll again start with XML: + +{{{ + + Silvio Berlusconi + Premier + I +
+ Via del Colosseo, 1 + 00100 + Roma +
+ http://example.org +
+}}} + +In JSON this would look like this: + +{{{ +... +}}} + +Here's a way to model this in PSYC: + +{{{ +:_name Silvio Berlusconi +:_title_job Premier +:_country I +:_address_street Via del Colosseo, 1 +:_address_code_postal 00100 +:_address_city Roma +:_page http://example.org +_profile_user +| +}}} + +== Conclusions == + +== Criticism == + +Are we comparing apples and oranges? Yes and no, depends on what you +need. XML is a syntax best suited for complex structured data in +well-defined formats - especially good for text mark-up. JSON is a syntax +intended to hold arbitrarily structured data suitable for immediate +inclusion in javascript source codes. The PSYC syntax is an evolved +derivate of RFC 822, the syntax used by HTTP and E-Mail, and is therefore +limited in the kind and depth of data structures that can be represented +with it, but in exchange it is highly performant at doing just that. + +So it is up to you to find out which of the three formats fulfils your +requirements the best. We use PSYC for the majority of messaging where +JSON and XMPP aren't efficient and opaque enough, but we employ XML and +JSON as payloads within PSYC for data that doesn't fit the PSYC model. +For some reason all three formats are being used for messaging, although +only PSYC was actually designed for that purpose. + From 620a61514eda6f6077e0789e2184db23c1a6fccb Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sat, 14 May 2011 19:59:08 +0200 Subject: [PATCH 223/378] testServer is now testPsyc and it can handle file input as well --- .gitignore | 2 +- test/Makefile | 24 ++++++------- test/{testServer.c => test.c} | 29 +++++++++++++--- test/{testServer.h => test.h} | 6 ++-- test/{testServerPsyc.c => testPsyc.c} | 49 +++++++++++++++------------ 5 files changed, 70 insertions(+), 40 deletions(-) rename test/{testServer.c => test.c} (89%) rename test/{testServer.h => test.h} (79%) rename test/{testServerPsyc.c => testPsyc.c} (90%) diff --git a/.gitignore b/.gitignore index 185848a..4c7cf96 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,7 @@ src/match test/testMatch test/testParser test/testRender -test/testServerPsyc +test/testPsyc test/testText test/isRoutingVar test/getVarType diff --git a/test/Makefile b/test/Makefile index 2c6c843..437aee3 100644 --- a/test/Makefile +++ b/test/Makefile @@ -4,8 +4,8 @@ CFLAGS = -I../include -I../src -Wall -std=c99 ${OPT} LDFLAGS = -L../lib LOADLIBES = -lpsyc -lm LOADLIBES_NET = ${LOADLIBES} -TARGETS = testServerPsyc testParser testMatch testRender testText isRoutingVar getVarType -O = testServer.o +TARGETS = testPsyc testParser testMatch testRender testText isRoutingVar getVarType +O = test.o WRAPPER = DIET = diet PORT = 4440 @@ -20,8 +20,8 @@ endif all: ${TARGETS} it: all -testServerPsyc: LOADLIBES := ${LOADLIBES_NET} -testServerPsyc: testServer.o +testPsyc: LOADLIBES := ${LOADLIBES_NET} +testPsyc: test.o diet: WRAPPER = ${DIET} diet: all @@ -39,8 +39,8 @@ test: ${TARGETS} ./testText ./isRoutingVar ./getVarType - x=0; for f in packets/[0-9]*; do echo ">> $$f"; ./testParser $$f; x=$$((x+$$?)); done; exit $$x - x=0; for f in packets/[0-9]*; do echo ">> $$f"; ./testParser $$f -r; x=$$((x+$$?)); done; exit $$x + x=0; for f in packets/[0-9]*; do echo ">> $$f"; ./testPsyc $$f -f | ${DIFF} -u $$f -; x=$$((x+$$?)); done; exit $$x + x=0; for f in packets/[0-9]*; do echo ">> $$f"; ./testPsyc $$f -fr | ${DIFF} -u $$f -; x=$$((x+$$?)); done; exit $$x .NOTPARALLEL: nettestrun @@ -49,12 +49,12 @@ nettest: nettestfull nettestsplit nettestrun: srvstart pkt srvkill nettestfull: - ${MAKE} nettestrun; x=$$?; pkill -x testServerPsyc; exit $$x - ${MAKE} nettestrun srv_args=r; x=$$?; pkill -x testServerPsyc; exit $$x + ${MAKE} nettestrun; x=$$?; pkill -x testPsyc; exit $$x + ${MAKE} nettestrun srv_args=r; x=$$?; pkill -x testPsyc; exit $$x split_max = 10 nettestsplit: - x=0; for n in `seq 1 ${split_max}`; do ${MAKE} nettestrun srv_recvbuf=$$n && ${MAKE} nettestrun srv_args=r srv_recvbuf=$$n || break; done; x=$$?; pkill -x testServerPsyc; exit $$x + x=0; for n in `seq 1 ${split_max}`; do ${MAKE} nettestrun srv_recvbuf=$$n && ${MAKE} nettestrun srv_args=r srv_recvbuf=$$n || break; done; x=$$?; pkill -x testPsyc; exit $$x pkt: x=0; for f in packets/[0-9]*; do echo ">> $$f"; cat $$f | nc localhost ${PORT} | ${DIFF} -u $$f -; x=$$((x+$$?)); done; exit $$x @@ -66,8 +66,8 @@ pkterr: for f in packets/err-*; do echo ">> $$f"; cat $$f | nc localhost ${PORT}; done srvstart: - pkill -x testServerPsyc; exit 0 - ./testServerPsyc ${PORT} -${srv_args} ${srv_recvbuf} & + pkill -x testPsyc; exit 0 + ./testPsyc ${PORT} -${srv_args} ${srv_recvbuf} & srvkill: - pkill -x testServerPsyc + pkill -x testPsyc diff --git a/test/testServer.c b/test/test.c similarity index 89% rename from test/testServer.c rename to test/test.c index aaaaca1..def047d 100644 --- a/test/testServer.c +++ b/test/test.c @@ -9,16 +9,19 @@ #include #include #include +#include + #include #include #include #include + #include #include #define __USE_POSIX #include -#include "testServer.h" +#include "test.h" // cmd line args extern uint8_t verbose, stats; @@ -31,6 +34,22 @@ void *get_in_addr (struct sockaddr *sa) { return &(((struct sockaddr_in6*)sa)->sin6_addr); } +void test_file(const char* filename) { + char buf[CONT_BUF_SIZE + RECV_BUF_SIZE]; // cont buf + recv buf: [ ccrrrr] + char *recvbuf = buf + CONT_BUF_SIZE; // recv buf: ^^^^ + size_t nbytes; + + int fd = open(filename, O_RDONLY); + if (fd < 0) { + perror("open"); + exit(1); + } + + test_init(0); + while ((nbytes = read(fd, (void*)recvbuf, RECV_BUF_SIZE))) + test_input(0, recvbuf, nbytes); +} + void test_server(const char* port, size_t recv_buf_size) { char buf[CONT_BUF_SIZE + RECV_BUF_SIZE]; // cont buf + recv buf: [ ccrrrr] char *recvbuf = buf + CONT_BUF_SIZE; // recv buf: ^^^^ @@ -150,10 +169,12 @@ void test_server(const char* port, size_t recv_buf_size) { printf("%ld ms\n", (end[i].tv_sec * 1000000 + end[i].tv_usec - start[i].tv_sec * 1000000 - start[i].tv_usec) / 1000); // got error or connection closed by client - if (nbytes == 0) // connection closed - printf("# Socket %d hung up\n", i); - else + if (nbytes == 0) { // connection closed + if (verbose) + printf("# Socket %d hung up\n", i); + } else { perror("recv"); + } close(i); // bye! FD_CLR(i, &master); // remove from master set diff --git a/test/testServer.h b/test/test.h similarity index 79% rename from test/testServer.h rename to test/test.h index 0268769..0aede53 100644 --- a/test/testServer.h +++ b/test/test.h @@ -1,5 +1,5 @@ -#ifndef TESTSERVER_H -# define TESTSERVER_H +#ifndef TEST_H +# define TEST_H # define RECV_BUF_SIZE 8 * 1024 # define CONT_BUF_SIZE 8 * 1024 @@ -8,6 +8,8 @@ void test_init(int i); int test_input(int i, char *recvbuf, size_t nbytes); + +void test_file(const char* filename); void test_server(const char* port, size_t recv_buf_size); #endif diff --git a/test/testServerPsyc.c b/test/testPsyc.c similarity index 90% rename from test/testServerPsyc.c rename to test/testPsyc.c index 90335ba..bc597d4 100644 --- a/test/testServerPsyc.c +++ b/test/testPsyc.c @@ -9,30 +9,22 @@ #include #include -#include "testServer.h" -//#include "testServer.c" +#include "test.h" // max size for routing & entity header #define ROUTING_LINES 16 #define ENTITY_LINES 32 // cmd line args -uint8_t verbose, stats; +uint8_t verbose, stats, file; +uint8_t routing_only, parse_multiple, no_render, progress; psycParseState parsers[NUM_PARSERS]; psycPacket packets[NUM_PARSERS]; psycModifier routing[NUM_PARSERS][ROUTING_LINES]; psycModifier entity[NUM_PARSERS][ENTITY_LINES]; -psycModifier *mod = NULL; -uint8_t routing_only, parse_multiple, no_render, progress; - -int ret, retl, contbytes = 0; -char oper; -psycString name, value, elem; -psycString *pname = NULL, *pvalue = NULL; -psycParseListState listState; -size_t len; +int contbytes = 0, last_ret = 0; int main (int argc, char **argv) { char *port = argc > 1 ? argv[1] : "4440"; @@ -47,10 +39,15 @@ int main (int argc, char **argv) { parse_multiple = opts && memchr(opts, (int)'m', strlen(opts)); no_render = opts && memchr(opts, (int)'n', strlen(opts)); progress = opts && memchr(opts, (int)'p', strlen(opts)); + file = opts && memchr(opts, (int)'f', strlen(opts)); size_t recv_buf_size = argc > 3 ? atoi(argv[3]) : 0; - test_server(port, recv_buf_size); - return 0; + if (file) + test_file(argv[1]); + else + test_server(port, recv_buf_size); + + return last_ret; } static inline @@ -77,10 +74,17 @@ void test_init (int i) { } int test_input (int i, char *recvbuf, size_t nbytes) { - int j; + int j, ret, retl, r; char *parsebuf = recvbuf - contbytes; char sendbuf[SEND_BUF_SIZE]; + char oper; + psycString name, value, elem; + psycString *pname = NULL, *pvalue = NULL; + psycModifier *mod = NULL; + psycParseListState listState; + size_t len; + psyc_setParseBuffer2(&parsers[i], parsebuf, contbytes + nbytes); contbytes = 0; oper = 0; @@ -88,7 +92,7 @@ int test_input (int i, char *recvbuf, size_t nbytes) { value.length = 0; do { - ret = psyc_parse(&parsers[i], &oper, &name, &value); + ret = last_ret = psyc_parse(&parsers[i], &oper, &name, &value); if (verbose >= 2) printf("# ret = %d\n", ret); @@ -130,7 +134,7 @@ int test_input (int i, char *recvbuf, size_t nbytes) { if (verbose) printf("# Done parsing.\n"); else if (progress) - write(1, ".", 1); + r = write(1, ".", 1); if (!parse_multiple) // parse multiple packets? ret = -1; @@ -146,12 +150,15 @@ int test_input (int i, char *recvbuf, size_t nbytes) { psyc_setPacketLength(&packets[i]); if (psyc_render(&packets[i], sendbuf, SEND_BUF_SIZE) == PSYC_RENDER_SUCCESS) { - if (send(i, sendbuf, packets[i].length, 0) == -1) { - perror("send error"); + if (file && write(1, sendbuf, packets[i].length) == -1) { + perror("write"); + ret = -1; + } else if (!file && send(i, sendbuf, packets[i].length, 0) == -1) { + perror("send"); ret = -1; } } else { - perror("render error"); + printf("# Render error"); ret = -1; } } @@ -299,7 +306,7 @@ int test_input (int i, char *recvbuf, size_t nbytes) { while (ret > 0); if (progress) - write(1, " ", 1); + r = write(1, " ", 1); return ret; } From 3f4bb396631486baf8c0bfb54b77e1da9159d58f Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sat, 14 May 2011 20:13:55 +0200 Subject: [PATCH 224/378] test: buf size option for files too --- test/test.c | 14 +++++++++----- test/test.h | 2 +- test/testPsyc.c | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/test/test.c b/test/test.c index def047d..fd3b951 100644 --- a/test/test.c +++ b/test/test.c @@ -34,7 +34,10 @@ void *get_in_addr (struct sockaddr *sa) { return &(((struct sockaddr_in6*)sa)->sin6_addr); } -void test_file(const char* filename) { +void test_file(const char* filename, size_t recv_buf_size) { + if (recv_buf_size <= 0) + recv_buf_size = RECV_BUF_SIZE; + char buf[CONT_BUF_SIZE + RECV_BUF_SIZE]; // cont buf + recv buf: [ ccrrrr] char *recvbuf = buf + CONT_BUF_SIZE; // recv buf: ^^^^ size_t nbytes; @@ -46,11 +49,15 @@ void test_file(const char* filename) { } test_init(0); - while ((nbytes = read(fd, (void*)recvbuf, RECV_BUF_SIZE))) + + while ((nbytes = read(fd, (void*)recvbuf, recv_buf_size))) test_input(0, recvbuf, nbytes); } void test_server(const char* port, size_t recv_buf_size) { + if (recv_buf_size <= 0) + recv_buf_size = RECV_BUF_SIZE; + char buf[CONT_BUF_SIZE + RECV_BUF_SIZE]; // cont buf + recv buf: [ ccrrrr] char *recvbuf = buf + CONT_BUF_SIZE; // recv buf: ^^^^ @@ -72,9 +79,6 @@ void test_server(const char* port, size_t recv_buf_size) { struct addrinfo hints, *ai, *p; struct timeval start[NUM_PARSERS], end[NUM_PARSERS]; - if (recv_buf_size <= 0) - recv_buf_size = RECV_BUF_SIZE; - FD_ZERO(&master); // clear the master and temp sets FD_ZERO(&read_fds); diff --git a/test/test.h b/test/test.h index 0aede53..bd9fd36 100644 --- a/test/test.h +++ b/test/test.h @@ -9,7 +9,7 @@ void test_init(int i); int test_input(int i, char *recvbuf, size_t nbytes); -void test_file(const char* filename); +void test_file(const char* filename, size_t recv_buf_size); void test_server(const char* port, size_t recv_buf_size); #endif diff --git a/test/testPsyc.c b/test/testPsyc.c index bc597d4..0f102a6 100644 --- a/test/testPsyc.c +++ b/test/testPsyc.c @@ -43,7 +43,7 @@ int main (int argc, char **argv) { size_t recv_buf_size = argc > 3 ? atoi(argv[3]) : 0; if (file) - test_file(argv[1]); + test_file(argv[1], recv_buf_size); else test_server(port, recv_buf_size); From 3d4d0499cf0ea2d9862f171472e0d7814c29e26e Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sat, 14 May 2011 20:28:34 +0200 Subject: [PATCH 225/378] + --- test/test.c | 6 ------ test/testPsyc.c | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/test/test.c b/test/test.c index fd3b951..b2dbadf 100644 --- a/test/test.c +++ b/test/test.c @@ -35,9 +35,6 @@ void *get_in_addr (struct sockaddr *sa) { } void test_file(const char* filename, size_t recv_buf_size) { - if (recv_buf_size <= 0) - recv_buf_size = RECV_BUF_SIZE; - char buf[CONT_BUF_SIZE + RECV_BUF_SIZE]; // cont buf + recv buf: [ ccrrrr] char *recvbuf = buf + CONT_BUF_SIZE; // recv buf: ^^^^ size_t nbytes; @@ -55,9 +52,6 @@ void test_file(const char* filename, size_t recv_buf_size) { } void test_server(const char* port, size_t recv_buf_size) { - if (recv_buf_size <= 0) - recv_buf_size = RECV_BUF_SIZE; - char buf[CONT_BUF_SIZE + RECV_BUF_SIZE]; // cont buf + recv buf: [ ccrrrr] char *recvbuf = buf + CONT_BUF_SIZE; // recv buf: ^^^^ diff --git a/test/testPsyc.c b/test/testPsyc.c index 0f102a6..2595642 100644 --- a/test/testPsyc.c +++ b/test/testPsyc.c @@ -40,7 +40,7 @@ int main (int argc, char **argv) { no_render = opts && memchr(opts, (int)'n', strlen(opts)); progress = opts && memchr(opts, (int)'p', strlen(opts)); file = opts && memchr(opts, (int)'f', strlen(opts)); - size_t recv_buf_size = argc > 3 ? atoi(argv[3]) : 0; + size_t recv_buf_size = argc > 3 ? atoi(argv[3]) : RECV_BUF_SIZE; if (file) test_file(argv[1], recv_buf_size); From fb720b746ec4f2000629601d36b875b1939a97c5 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sat, 14 May 2011 21:16:11 +0200 Subject: [PATCH 226/378] test: getopt --- test/Makefile | 10 +++++----- test/testPsyc.c | 48 +++++++++++++++++++++++++++++------------------- 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/test/Makefile b/test/Makefile index 437aee3..2987aea 100644 --- a/test/Makefile +++ b/test/Makefile @@ -39,8 +39,8 @@ test: ${TARGETS} ./testText ./isRoutingVar ./getVarType - x=0; for f in packets/[0-9]*; do echo ">> $$f"; ./testPsyc $$f -f | ${DIFF} -u $$f -; x=$$((x+$$?)); done; exit $$x - x=0; for f in packets/[0-9]*; do echo ">> $$f"; ./testPsyc $$f -fr | ${DIFF} -u $$f -; x=$$((x+$$?)); done; exit $$x + x=0; for f in packets/[0-9]*; do echo ">> $$f"; ./testPsyc -f $$f | ${DIFF} -u $$f -; x=$$((x+$$?)); done; exit $$x + x=0; for f in packets/[0-9]*; do echo ">> $$f"; ./testPsyc -rf $$f | ${DIFF} -u $$f -; x=$$((x+$$?)); done; exit $$x .NOTPARALLEL: nettestrun @@ -50,11 +50,11 @@ nettestrun: srvstart pkt srvkill nettestfull: ${MAKE} nettestrun; x=$$?; pkill -x testPsyc; exit $$x - ${MAKE} nettestrun srv_args=r; x=$$?; pkill -x testPsyc; exit $$x + ${MAKE} nettestrun srv_args=-r; x=$$?; pkill -x testPsyc; exit $$x split_max = 10 nettestsplit: - x=0; for n in `seq 1 ${split_max}`; do ${MAKE} nettestrun srv_recvbuf=$$n && ${MAKE} nettestrun srv_args=r srv_recvbuf=$$n || break; done; x=$$?; pkill -x testPsyc; exit $$x + x=0; for n in `seq 1 ${split_max}`; do ${MAKE} nettestrun srv_args="-b $$n" && ${MAKE} nettestrun srv_args="-r -b $$n" || break; done; x=$$?; pkill -x testPsyc; exit $$x pkt: x=0; for f in packets/[0-9]*; do echo ">> $$f"; cat $$f | nc localhost ${PORT} | ${DIFF} -u $$f -; x=$$((x+$$?)); done; exit $$x @@ -67,7 +67,7 @@ pkterr: srvstart: pkill -x testPsyc; exit 0 - ./testPsyc ${PORT} -${srv_args} ${srv_recvbuf} & + ./testPsyc -p ${PORT} ${srv_args} & srvkill: pkill -x testPsyc diff --git a/test/testPsyc.c b/test/testPsyc.c index 2595642..fb1f4cc 100644 --- a/test/testPsyc.c +++ b/test/testPsyc.c @@ -1,7 +1,9 @@ +#include #include #include #include #include +#include #include #include @@ -16,8 +18,10 @@ #define ENTITY_LINES 32 // cmd line args -uint8_t verbose, stats, file; +uint8_t verbose, stats; uint8_t routing_only, parse_multiple, no_render, progress; +char *filename, *port = "4440"; +size_t recv_buf_size = RECV_BUF_SIZE; psycParseState parsers[NUM_PARSERS]; psycPacket packets[NUM_PARSERS]; @@ -27,23 +31,29 @@ psycModifier entity[NUM_PARSERS][ENTITY_LINES]; int contbytes = 0, last_ret = 0; int main (int argc, char **argv) { - char *port = argc > 1 ? argv[1] : "4440"; - char *opts = argc > 2 ? argv[2] : NULL; - char *v, *w; - verbose = opts && (v = memchr(opts, (int)'v', strlen(opts))) ? - v - opts > 0 && (w = memchr(v+1, (int)'v', strlen(opts) - (v - opts))) ? - w - v > 0 && memchr(w+1, (int)'v', strlen(opts) - (w - opts)) ? 3 : 2 : 1 : 0; - stats = opts && memchr(opts, (int)'s', strlen(opts)); + int c; + while ((c = getopt (argc, argv, "f:p:b:mnrsvP")) != -1) { + switch (c) { + case 'f': filename = optarg; break; + case 'p': port = optarg; + if (atoi(optarg) <= 0) { printf("-p: error, should be > 0\n"); exit(-1); } + break; + case 'b': recv_buf_size = atoi(optarg); + if (atoi(optarg) <= 0) { printf("-b: error, should be > 0\n"); exit(-1); } + break; + case 'm': parse_multiple = 1; break; + case 'n': no_render = 1; break; + case 'r': routing_only = 1; break; + case 's': stats = 1; break; + case 'v': verbose++; break; + case 'P': progress = 1; break; + case '?': exit(-1); + default: abort(); + } + } - routing_only = opts && memchr(opts, (int)'r', strlen(opts)); - parse_multiple = opts && memchr(opts, (int)'m', strlen(opts)); - no_render = opts && memchr(opts, (int)'n', strlen(opts)); - progress = opts && memchr(opts, (int)'p', strlen(opts)); - file = opts && memchr(opts, (int)'f', strlen(opts)); - size_t recv_buf_size = argc > 3 ? atoi(argv[3]) : RECV_BUF_SIZE; - - if (file) - test_file(argv[1], recv_buf_size); + if (filename) + test_file(filename, recv_buf_size); else test_server(port, recv_buf_size); @@ -150,10 +160,10 @@ int test_input (int i, char *recvbuf, size_t nbytes) { psyc_setPacketLength(&packets[i]); if (psyc_render(&packets[i], sendbuf, SEND_BUF_SIZE) == PSYC_RENDER_SUCCESS) { - if (file && write(1, sendbuf, packets[i].length) == -1) { + if (filename && write(1, sendbuf, packets[i].length) == -1) { perror("write"); ret = -1; - } else if (!file && send(i, sendbuf, packets[i].length, 0) == -1) { + } else if (!filename && send(i, sendbuf, packets[i].length, 0) == -1) { perror("send"); ret = -1; } From 6529f303805d5ccf0d8ab8be9e68d9591f8c697e Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sun, 15 May 2011 00:17:33 +0200 Subject: [PATCH 227/378] + --- test/testPsyc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/testPsyc.c b/test/testPsyc.c index fb1f4cc..9a3c868 100644 --- a/test/testPsyc.c +++ b/test/testPsyc.c @@ -28,7 +28,7 @@ psycPacket packets[NUM_PARSERS]; psycModifier routing[NUM_PARSERS][ROUTING_LINES]; psycModifier entity[NUM_PARSERS][ENTITY_LINES]; -int contbytes = 0, last_ret = 0; +int contbytes, last_ret; int main (int argc, char **argv) { int c; @@ -36,10 +36,10 @@ int main (int argc, char **argv) { switch (c) { case 'f': filename = optarg; break; case 'p': port = optarg; - if (atoi(optarg) <= 0) { printf("-p: error, should be > 0\n"); exit(-1); } + if (atoi(optarg) <= 0) { printf("-%c: error, should be > 0\n", c); exit(-1); } break; case 'b': recv_buf_size = atoi(optarg); - if (atoi(optarg) <= 0) { printf("-b: error, should be > 0\n"); exit(-1); } + if (atoi(optarg) <= 0) { printf("-%c: error, should be > 0\n", c); exit(-1); } break; case 'm': parse_multiple = 1; break; case 'n': no_render = 1; break; From dc97c514db3c88494190ce94456391af39d2fe26 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Sun, 15 May 2011 00:54:43 +0200 Subject: [PATCH 228/378] some sons of jay --- bench/benchmark.wiki | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/bench/benchmark.wiki b/bench/benchmark.wiki index 235ff7d..87b5ced 100644 --- a/bench/benchmark.wiki +++ b/bench/benchmark.wiki @@ -14,20 +14,6 @@ a more efficient XML encoding based on PSYC methods, to have a more accurate comparison of the actual PSYC and XML syntaxes, rather than the protocol structures of PSYC and XMPP. -== Caveats == - -In every case we'll compare performance of parsing and re-rendering -these messages, but consider also that the applicative processing -of an XML DOM tree is more complicated than just accessing -certain elements in a JSON data structure or PSYC variable -mapping. - -For a speed check in real world conditions which also consider the -complexity of processing incoming messages we should compare -the performance of a chat client using the two protocols, -for instance by using libpurple with XMPP and PSYC accounts. -To this purpose we first need to integrate libpsyc into libpurple. - == The Benchmarks == === A presence packet === @@ -47,7 +33,7 @@ Here's an example from paragraph 4.4.2 of RFC 6121. And here's the same information in a JSON rendition: {{{ -... +["presence",{"from":"juliet@example.com/balcony","to":"benvolio@example.net"},{"show":"away"}] }}} Here's the equivalent PSYC packet in verbose form @@ -101,7 +87,8 @@ storage information. We'll again start with XML: In JSON this would look like this: {{{ -... +["UserProfile",{"Name":"Silvio Berlusconi","JobTitle":"Premier","Country":"I","Address": +{"Street":"Via del Colosseo, 1","PostalCode":"00100","City":"Roma"},"Page":"http://example.org"}] }}} Here's a way to model this in PSYC: @@ -138,3 +125,17 @@ JSON as payloads within PSYC for data that doesn't fit the PSYC model. For some reason all three formats are being used for messaging, although only PSYC was actually designed for that purpose. +== Caveats == + +In every case we'll compare performance of parsing and re-rendering +these messages, but consider also that the applicative processing +of an XML DOM tree is more complicated than just accessing +certain elements in a JSON data structure or PSYC variable +mapping. + +For a speed check in real world conditions which also consider the +complexity of processing incoming messages we should compare +the performance of a chat client using the two protocols, +for instance by using libpurple with XMPP and PSYC accounts. +To this purpose we first need to integrate libpsyc into libpurple. + From 1ba95671005521f5d9bf2939612ee3f1e3d2b1c9 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sun, 15 May 2011 11:51:30 +0200 Subject: [PATCH 229/378] test: stats option for files too --- test/test.c | 10 ++++++++++ test/testPsyc.c | 20 ++++++++++++-------- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/test/test.c b/test/test.c index b2dbadf..1dabfdc 100644 --- a/test/test.c +++ b/test/test.c @@ -38,6 +38,7 @@ void test_file(const char* filename, size_t recv_buf_size) { char buf[CONT_BUF_SIZE + RECV_BUF_SIZE]; // cont buf + recv buf: [ ccrrrr] char *recvbuf = buf + CONT_BUF_SIZE; // recv buf: ^^^^ size_t nbytes; + struct timeval start, end; int fd = open(filename, O_RDONLY); if (fd < 0) { @@ -45,10 +46,19 @@ void test_file(const char* filename, size_t recv_buf_size) { exit(1); } + test_init(0); + if (stats) + gettimeofday(&start, NULL); + while ((nbytes = read(fd, (void*)recvbuf, recv_buf_size))) test_input(0, recvbuf, nbytes); + + if (stats) { + gettimeofday(&end, NULL); + printf("%ld ms\n", (end.tv_sec * 1000000 + end.tv_usec - start.tv_sec * 1000000 - start.tv_usec) / 1000); + } } void test_server(const char* port, size_t recv_buf_size) { diff --git a/test/testPsyc.c b/test/testPsyc.c index 9a3c868..c3905ba 100644 --- a/test/testPsyc.c +++ b/test/testPsyc.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -19,7 +20,7 @@ // cmd line args uint8_t verbose, stats; -uint8_t routing_only, parse_multiple, no_render, progress; +uint8_t routing_only, parse_multiple, no_render, quiet, progress; char *filename, *port = "4440"; size_t recv_buf_size = RECV_BUF_SIZE; @@ -32,7 +33,7 @@ int contbytes, last_ret; int main (int argc, char **argv) { int c; - while ((c = getopt (argc, argv, "f:p:b:mnrsvP")) != -1) { + while ((c = getopt (argc, argv, "f:p:b:mnqrsvP")) != -1) { switch (c) { case 'f': filename = optarg; break; case 'p': port = optarg; @@ -43,6 +44,7 @@ int main (int argc, char **argv) { break; case 'm': parse_multiple = 1; break; case 'n': no_render = 1; break; + case 'q': quiet = 1; break; case 'r': routing_only = 1; break; case 's': stats = 1; break; case 'v': verbose++; break; @@ -160,12 +162,14 @@ int test_input (int i, char *recvbuf, size_t nbytes) { psyc_setPacketLength(&packets[i]); if (psyc_render(&packets[i], sendbuf, SEND_BUF_SIZE) == PSYC_RENDER_SUCCESS) { - if (filename && write(1, sendbuf, packets[i].length) == -1) { - perror("write"); - ret = -1; - } else if (!filename && send(i, sendbuf, packets[i].length, 0) == -1) { - perror("send"); - ret = -1; + if (!quiet) { + if (filename && write(1, sendbuf, packets[i].length) == -1) { + perror("write"); + ret = -1; + } else if (!filename && send(i, sendbuf, packets[i].length, 0) == -1) { + perror("send"); + ret = -1; + } } } else { printf("# Render error"); From b15ea8e587cb63d30555a8e41f5c3be492208566 Mon Sep 17 00:00:00 2001 From: Marenz Date: Sun, 15 May 2011 20:26:52 +0200 Subject: [PATCH 230/378] rephrased --- include/psyc/parse.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/psyc/parse.h b/include/psyc/parse.h index edc4117..e1f2495 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -17,8 +17,8 @@ * * and the according terms are used throughout this documentation and in the * return codes. You should be at least - * vaguely familiar with what the difference between "body" and "content" as - * well as "routing variable" and "entity variable" is. + * vaguely familiar with differences between "body" and "content" as + * well as "routing variable" and "entity variable". * * * To parse a packet you first have to initialize a state: From f92e4e750fd09a40bfbe0d819a68be4eed4f6daa Mon Sep 17 00:00:00 2001 From: Marenz Date: Sun, 15 May 2011 20:36:16 +0200 Subject: [PATCH 231/378] added function setParseFlags --- d/include/psyc/parse.d | 21 +++++++++++++++++++-- include/psyc/parse.h | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/d/include/psyc/parse.d b/d/include/psyc/parse.d index d655da2..5027ce1 100644 --- a/d/include/psyc/parse.d +++ b/d/include/psyc/parse.d @@ -133,17 +133,34 @@ struct ParseState * Params: * flags = Flags to be set for the parser, see ParseFlag. */ - static ParseState opCall ( ubyte flags ) + static ParseState opCall ( ParseFlag flags ) { ParseState inst; inst.flags = flags; - if (flags & ParseFlag.ROUTING_ONLY) + if (flags & ParseFlag.START_AT_CONTENT) inst.part = Part.CONTENT; return inst; } + /** + * Change parse flags in state + * + * Params: + * state = Pointer to the state struct that should be initialized. + * flags = Flags to be set for the parser, see psycParseFlag. + * + * See_Also: psyc_initParseState psycParseFlag + */ + void setParseFlags (ParseFlag flags) + { + this.flags = flags; + + if (flags & ParseFlag.START_AT_CONTENT) + this.part = Part.CONTENT; + } + /** * Sets a new buffer in the parser state struct with data to be parsed. * diff --git a/include/psyc/parse.h b/include/psyc/parse.h index e1f2495..79687b5 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -268,6 +268,25 @@ void psyc_initParseState2 (psycParseState *state, uint8_t flags) state->part = PSYC_PART_CONTENT; } +/** + * Change parse flags in state + * + * @param state Pointer to the state struct that should be initialized. + * @param flags Flags to be set for the parser, see psycParseFlag. + * @see psyc_initParseState + * @see psycParseFlag + */ +static inline +void psyc_setParseFlags (psycParseState *state, uint8_t flags) +{ + state->flags = flags; + + if (flags & PSYC_PARSE_START_AT_CONTENT) + state->part = PSYC_PART_CONTENT; +} + + + /** * Sets a new buffer in the parser state struct with data to be parsed. * From 5ef946fa3b6c8b74228a10f9aeeacbc15e55bc00 Mon Sep 17 00:00:00 2001 From: Marenz Date: Sun, 15 May 2011 20:37:14 +0200 Subject: [PATCH 232/378] Forgot else clause for setParseFlags --- d/include/psyc/parse.d | 2 ++ include/psyc/parse.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/d/include/psyc/parse.d b/d/include/psyc/parse.d index 5027ce1..52aa4da 100644 --- a/d/include/psyc/parse.d +++ b/d/include/psyc/parse.d @@ -159,6 +159,8 @@ struct ParseState if (flags & ParseFlag.START_AT_CONTENT) this.part = Part.CONTENT; + else + this.part = 0; } /** diff --git a/include/psyc/parse.h b/include/psyc/parse.h index 79687b5..1f1dcce 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -283,6 +283,8 @@ void psyc_setParseFlags (psycParseState *state, uint8_t flags) if (flags & PSYC_PARSE_START_AT_CONTENT) state->part = PSYC_PART_CONTENT; + else + state->part = 0; } From e30a555c2bdd24c5784355b4f2fe30e53d1118bc Mon Sep 17 00:00:00 2001 From: Marenz Date: Sun, 15 May 2011 20:47:54 +0200 Subject: [PATCH 233/378] D-Binding: created small wrapper f. parse function --- d/include/psyc/parse.d | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/d/include/psyc/parse.d b/d/include/psyc/parse.d index 52aa4da..9b8a700 100644 --- a/d/include/psyc/parse.d +++ b/d/include/psyc/parse.d @@ -144,6 +144,24 @@ struct ParseState return inst; } + /** + * Parse PSYC packets. + * + * Generalized line-based packet parser. + * + * Params: + * oper = A reference to a character. In case of a variable, it will + * be set to the operator of that variable + * name = A reference to a String. It will point to the name of + * the variable or method and its length will be set accordingly + * value = A reference to a String. It will point to the + * value/body the variable/method and its length will be set accordingly + */ + ParseRC parse ( ref char oper, ref char[] name, ref char[] value ) + { + return psyc_parse(this, &oper, cast(String*) &name, cast(String*) &value); + } + /** * Change parse flags in state * @@ -160,7 +178,7 @@ struct ParseState if (flags & ParseFlag.START_AT_CONTENT) this.part = Part.CONTENT; else - this.part = 0; + this.part = Part.ROUTING; } /** @@ -304,6 +322,7 @@ struct ParseListState } } +private: /** * Parse PSYC packets. From 4f606a0fe45ec552a0d23b17311a83daec278bbd Mon Sep 17 00:00:00 2001 From: Marenz Date: Sun, 15 May 2011 21:10:27 +0200 Subject: [PATCH 234/378] added new ParseFlag --- d/include/psyc/parse.d | 1 + include/psyc/parse.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/d/include/psyc/parse.d b/d/include/psyc/parse.d index 9b8a700..aeff7d1 100644 --- a/d/include/psyc/parse.d +++ b/d/include/psyc/parse.d @@ -6,6 +6,7 @@ extern (C): enum ParseFlag { + ALL = 0 ROUTING_ONLY = 1, START_AT_CONTENT = 2, } diff --git a/include/psyc/parse.h b/include/psyc/parse.h index 1f1dcce..8367a48 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -115,6 +115,8 @@ typedef enum { + /// Default Flag. Parse everything. + PSYC_PARSE_ALL = 0, /// Parse only the header PSYC_PARSE_ROUTING_ONLY = 1, /// Parse only the content. From 8d86238305fb7c371db6e6175ba607a7c3265dfa Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sun, 15 May 2011 21:12:17 +0200 Subject: [PATCH 235/378] test: opts, help --- test/test.c | 24 ++++++++++++++++++----- test/test.h | 5 +++-- test/testPsyc.c | 51 ++++++++++++++++++++++++++++++++----------------- 3 files changed, 56 insertions(+), 24 deletions(-) diff --git a/test/test.c b/test/test.c index 1dabfdc..ef09db4 100644 --- a/test/test.c +++ b/test/test.c @@ -26,6 +26,18 @@ // cmd line args extern uint8_t verbose, stats; +void check_range(char c, const char *s, int min, int max) { + int n = atoi(s); + if (n < min) { + printf("-%c: error, should be >= %d\n", c, min); + exit(-1); + } + if (max > min && n > max) { + printf("-%c: error, should be <= %d\n", c, max); + exit(-1); + } +} + // get sockaddr, IPv4 or IPv6: void *get_in_addr (struct sockaddr *sa) { if (sa->sa_family == AF_INET) @@ -34,10 +46,10 @@ void *get_in_addr (struct sockaddr *sa) { return &(((struct sockaddr_in6*)sa)->sin6_addr); } -void test_file(const char* filename, size_t recv_buf_size) { +void test_file(const char* filename, size_t count, size_t recv_buf_size) { char buf[CONT_BUF_SIZE + RECV_BUF_SIZE]; // cont buf + recv buf: [ ccrrrr] char *recvbuf = buf + CONT_BUF_SIZE; // recv buf: ^^^^ - size_t nbytes; + size_t i, nbytes; struct timeval start, end; int fd = open(filename, O_RDONLY); @@ -46,14 +58,14 @@ void test_file(const char* filename, size_t recv_buf_size) { exit(1); } - test_init(0); if (stats) gettimeofday(&start, NULL); while ((nbytes = read(fd, (void*)recvbuf, recv_buf_size))) - test_input(0, recvbuf, nbytes); + for (i = 0; i < count; i++) + test_input(0, recvbuf, nbytes); if (stats) { gettimeofday(&end, NULL); @@ -61,7 +73,7 @@ void test_file(const char* filename, size_t recv_buf_size) { } } -void test_server(const char* port, size_t recv_buf_size) { +void test_server(const char* port, size_t count, size_t recv_buf_size) { char buf[CONT_BUF_SIZE + RECV_BUF_SIZE]; // cont buf + recv buf: [ ccrrrr] char *recvbuf = buf + CONT_BUF_SIZE; // recv buf: ^^^^ @@ -126,6 +138,8 @@ void test_server(const char* port, size_t recv_buf_size) { exit(3); } + printf("# Listening on TCP port %s\n", port); + // add the listener to the master set FD_SET(listener, &master); diff --git a/test/test.h b/test/test.h index bd9fd36..b49f7f8 100644 --- a/test/test.h +++ b/test/test.h @@ -9,7 +9,8 @@ void test_init(int i); int test_input(int i, char *recvbuf, size_t nbytes); -void test_file(const char* filename, size_t recv_buf_size); -void test_server(const char* port, size_t recv_buf_size); +void test_file(const char* filename, size_t count, size_t recv_buf_size); +void test_server(const char* port, size_t count, size_t recv_buf_size); +void check_range(char c, const char *s, int min, int max); #endif diff --git a/test/testPsyc.c b/test/testPsyc.c index c3905ba..4e92ee1 100644 --- a/test/testPsyc.c +++ b/test/testPsyc.c @@ -19,47 +19,64 @@ #define ENTITY_LINES 32 // cmd line args -uint8_t verbose, stats; -uint8_t routing_only, parse_multiple, no_render, quiet, progress; char *filename, *port = "4440"; -size_t recv_buf_size = RECV_BUF_SIZE; +uint8_t verbose, stats; +uint8_t multiple, single, routing_only, no_render, quiet, progress; +size_t count = 1, recv_buf_size = RECV_BUF_SIZE; psycParseState parsers[NUM_PARSERS]; psycPacket packets[NUM_PARSERS]; psycModifier routing[NUM_PARSERS][ROUTING_LINES]; psycModifier entity[NUM_PARSERS][ENTITY_LINES]; -int contbytes, last_ret; +int contbytes, exit_code; int main (int argc, char **argv) { int c; - while ((c = getopt (argc, argv, "f:p:b:mnqrsvP")) != -1) { + while ((c = getopt (argc, argv, "f:p:b:c:nmqrsvPSh")) != -1) { switch (c) { case 'f': filename = optarg; break; - case 'p': port = optarg; - if (atoi(optarg) <= 0) { printf("-%c: error, should be > 0\n", c); exit(-1); } - break; - case 'b': recv_buf_size = atoi(optarg); - if (atoi(optarg) <= 0) { printf("-%c: error, should be > 0\n", c); exit(-1); } - break; - case 'm': parse_multiple = 1; break; + case 'p': port = optarg; check_range(c, optarg, 1, 0); break; + case 'b': recv_buf_size = atoi(optarg); check_range(c, optarg, 1, RECV_BUF_SIZE); break; + case 'c': count = atoi(optarg); check_range(c, optarg, 1, 0); break; case 'n': no_render = 1; break; + case 'm': multiple = 1; break; case 'q': quiet = 1; break; case 'r': routing_only = 1; break; case 's': stats = 1; break; case 'v': verbose++; break; case 'P': progress = 1; break; + case 'S': single = 1; break; + case 'h': + printf( + "testPsyc -f [-b ] [-c ] [-mnqrSsvP]\n" + "testPsyc [-p ] [-b ] [-nqrsvP]\n" + " -f \tInput file name\n" + " -p \t\tListen on TCP port, default is %s\n" + " -b \tRead/receive buffer size, default is %d\n" + " -c \t\tParse data from file times\n" + " -m\t\t\tParse multiple packets from file\n" + " -n\t\t\tNo rendering, only parsing\n" + " -r\t\t\tParse routing header only\n" + " -q\t\t\tQuiet mode, don't output rendered string\n" + " -S\t\t\tSingle packet mode, close connection after parsing one packet\n" + " -s\t\t\tShow statistics at the end\n" + " -v\t\t\tVerbose, can be specified multiple times for more verbosity\n" + " -P\t\t\tShow progress\n" + " -h\t\t\tShow this help\n", + port, RECV_BUF_SIZE); + exit(0); case '?': exit(-1); default: abort(); } } if (filename) - test_file(filename, recv_buf_size); + test_file(filename, count, recv_buf_size); else - test_server(port, recv_buf_size); + test_server(port, count, recv_buf_size); - return last_ret; + return exit_code; } static inline @@ -104,7 +121,7 @@ int test_input (int i, char *recvbuf, size_t nbytes) { value.length = 0; do { - ret = last_ret = psyc_parse(&parsers[i], &oper, &name, &value); + ret = exit_code = psyc_parse(&parsers[i], &oper, &name, &value); if (verbose >= 2) printf("# ret = %d\n", ret); @@ -147,7 +164,7 @@ int test_input (int i, char *recvbuf, size_t nbytes) { printf("# Done parsing.\n"); else if (progress) r = write(1, ".", 1); - if (!parse_multiple) // parse multiple packets? + if ((filename && !multiple) || (!filename && single)) ret = -1; if (!no_render) { From 257f8c30fe69ac721b628d8bc50e51608e4c4133 Mon Sep 17 00:00:00 2001 From: Marenz Date: Sun, 15 May 2011 21:13:10 +0200 Subject: [PATCH 236/378] forgot a , in parse.d --- d/include/psyc/parse.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/d/include/psyc/parse.d b/d/include/psyc/parse.d index aeff7d1..bd0ca28 100644 --- a/d/include/psyc/parse.d +++ b/d/include/psyc/parse.d @@ -6,7 +6,7 @@ extern (C): enum ParseFlag { - ALL = 0 + ALL = 0, ROUTING_ONLY = 1, START_AT_CONTENT = 2, } From 20228ce6d22e016f3da34ba6a7bcb4dd26873708 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sun, 15 May 2011 21:20:58 +0200 Subject: [PATCH 237/378] test: make opts --- test/Makefile | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/test/Makefile b/test/Makefile index 2987aea..c01a811 100644 --- a/test/Makefile +++ b/test/Makefile @@ -3,7 +3,6 @@ DEBUG = 2 CFLAGS = -I../include -I../src -Wall -std=c99 ${OPT} LDFLAGS = -L../lib LOADLIBES = -lpsyc -lm -LOADLIBES_NET = ${LOADLIBES} TARGETS = testPsyc testParser testMatch testRender testText isRoutingVar getVarType O = test.o WRAPPER = @@ -13,14 +12,14 @@ NC = nc DIFF = diff ifeq ($(shell uname),SunOS) - LOADLIBES_NET := ${LOADLIBES_NET} -lsocket -lnsl + LOADLIBES_NET := -lsocket -lnsl DIFF = gdiff endif all: ${TARGETS} it: all -testPsyc: LOADLIBES := ${LOADLIBES_NET} +testPsyc: LOADLIBES := ${LOADLIBES} ${LOADLIBES_NET} testPsyc: test.o diet: WRAPPER = ${DIET} @@ -67,7 +66,7 @@ pkterr: srvstart: pkill -x testPsyc; exit 0 - ./testPsyc -p ${PORT} ${srv_args} & + ./testPsyc -p ${PORT} -S ${srv_args} & srvkill: pkill -x testPsyc From 513f26169eb29850c5832fba08f9708753523202 Mon Sep 17 00:00:00 2001 From: Marenz Date: Sun, 15 May 2011 21:35:26 +0200 Subject: [PATCH 238/378] error in example code --- include/psyc/parse.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/psyc/parse.h b/include/psyc/parse.h index 8367a48..7fc084c 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -97,7 +97,7 @@ * perror("Error %i happened :(\n", res); * return res; * } - * } + * } while (ret > 0) * @endcode * * This simple example does not consider some more complex cases when you From 7c3e8ec3abc238b0e0d9dbe3f9f0aef6c8b4dac9 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sun, 15 May 2011 22:48:51 +0200 Subject: [PATCH 239/378] doc: link to example code; testPsyc: moved interesting code to the top --- Doxyfile | 3 +- include/psyc/parse.h | 7 ++- test/testPsyc.c | 133 ++++++++++++++++++++++++------------------- 3 files changed, 81 insertions(+), 62 deletions(-) diff --git a/Doxyfile b/Doxyfile index 38dfdac..a05f707 100644 --- a/Doxyfile +++ b/Doxyfile @@ -619,8 +619,7 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = src \ - include +INPUT = src include test/testPsyc.c # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is diff --git a/include/psyc/parse.h b/include/psyc/parse.h index 7fc084c..8d9009d 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -58,11 +58,14 @@ * the according positions and lengths. * * Now the real parsing begins. The parsing function needs to be called - * repeatedly with various actions in between, depending on the return values: + * repeatedly with various actions in between, depending on the return values. + * + * A simplified example follows, see test/testPsyc.c for actual code that + * handles incomplete packets too. * * @code * - * int res; + * int ret; * * do // run the parsing in a loop, each time parsing one line * { diff --git a/test/testPsyc.c b/test/testPsyc.c index 4e92ee1..ce397ef 100644 --- a/test/testPsyc.c +++ b/test/testPsyc.c @@ -31,63 +31,9 @@ psycModifier entity[NUM_PARSERS][ENTITY_LINES]; int contbytes, exit_code; -int main (int argc, char **argv) { - int c; - while ((c = getopt (argc, argv, "f:p:b:c:nmqrsvPSh")) != -1) { - switch (c) { - case 'f': filename = optarg; break; - case 'p': port = optarg; check_range(c, optarg, 1, 0); break; - case 'b': recv_buf_size = atoi(optarg); check_range(c, optarg, 1, RECV_BUF_SIZE); break; - case 'c': count = atoi(optarg); check_range(c, optarg, 1, 0); break; - case 'n': no_render = 1; break; - case 'm': multiple = 1; break; - case 'q': quiet = 1; break; - case 'r': routing_only = 1; break; - case 's': stats = 1; break; - case 'v': verbose++; break; - case 'P': progress = 1; break; - case 'S': single = 1; break; - case 'h': - printf( - "testPsyc -f [-b ] [-c ] [-mnqrSsvP]\n" - "testPsyc [-p ] [-b ] [-nqrsvP]\n" - " -f \tInput file name\n" - " -p \t\tListen on TCP port, default is %s\n" - " -b \tRead/receive buffer size, default is %d\n" - " -c \t\tParse data from file times\n" - " -m\t\t\tParse multiple packets from file\n" - " -n\t\t\tNo rendering, only parsing\n" - " -r\t\t\tParse routing header only\n" - " -q\t\t\tQuiet mode, don't output rendered string\n" - " -S\t\t\tSingle packet mode, close connection after parsing one packet\n" - " -s\t\t\tShow statistics at the end\n" - " -v\t\t\tVerbose, can be specified multiple times for more verbosity\n" - " -P\t\t\tShow progress\n" - " -h\t\t\tShow this help\n", - port, RECV_BUF_SIZE); - exit(0); - case '?': exit(-1); - default: abort(); - } - } - - if (filename) - test_file(filename, count, recv_buf_size); - else - test_server(port, count, recv_buf_size); - - return exit_code; -} - -static inline -void resetString (psycString *s, uint8_t freeptr) { - if (freeptr && s->length) - free((void*)s->ptr); - - s->ptr = NULL; - s->length = 0; -} - +static inline void resetString (psycString *s, uint8_t freeptr); +t +// initialize parser & packet variables void test_init (int i) { // reset parser state & packet if (routing_only) @@ -102,10 +48,21 @@ void test_init (int i) { packets[i].entity.modifiers = entity[i]; } +// parse & render input int test_input (int i, char *recvbuf, size_t nbytes) { int j, ret, retl, r; - char *parsebuf = recvbuf - contbytes; char sendbuf[SEND_BUF_SIZE]; + char *parsebuf = recvbuf - contbytes; + /* We have a buffer with pointers pointing to various parts of it: + * *contbuf-vv + * buffer: [ ccrrrr] + * *recvbuf---^^^^ + * *parsebuf-^^^^^^ + * + * New data is in recvbuf, if it contains an incomplete packet then remaining + * unparsed data is copied to contbuf that will be parsed during the next call + * to this function together with the new data. + */ char oper; psycString name, value, elem; @@ -114,6 +71,7 @@ int test_input (int i, char *recvbuf, size_t nbytes) { psycParseListState listState; size_t len; + // Set buffer with data for the parser. psyc_setParseBuffer2(&parsers[i], parsebuf, contbytes + nbytes); contbytes = 0; oper = 0; @@ -121,6 +79,7 @@ int test_input (int i, char *recvbuf, size_t nbytes) { value.length = 0; do { + // Parse the next part of the packet (a routing/entity modifier or the body) ret = exit_code = psyc_parse(&parsers[i], &oper, &name, &value); if (verbose >= 2) printf("# ret = %d\n", ret); @@ -341,3 +300,61 @@ int test_input (int i, char *recvbuf, size_t nbytes) { return ret; } + +static inline +void resetString (psycString *s, uint8_t freeptr) +{ + if (freeptr && s->length) + free((void*)s->ptr); + + s->ptr = NULL; + s->length = 0; +} + +int main (int argc, char **argv) { + int c; + while ((c = getopt (argc, argv, "f:p:b:c:nmqrsvPSh")) != -1) { + switch (c) { + case 'f': filename = optarg; break; + case 'p': port = optarg; check_range(c, optarg, 1, 0); break; + case 'b': recv_buf_size = atoi(optarg); check_range(c, optarg, 1, RECV_BUF_SIZE); break; + case 'c': count = atoi(optarg); check_range(c, optarg, 1, 0); break; + case 'n': no_render = 1; break; + case 'm': multiple = 1; break; + case 'q': quiet = 1; break; + case 'r': routing_only = 1; break; + case 's': stats = 1; break; + case 'v': verbose++; break; + case 'P': progress = 1; break; + case 'S': single = 1; break; + case 'h': + printf( + "testPsyc -f [-b ] [-c ] [-mnqrSsvP]\n" + "testPsyc [-p ] [-b ] [-nqrsvP]\n" + " -f \tInput file name\n" + " -p \t\tListen on TCP port, default is %s\n" + " -b \tRead/receive buffer size, default is %d\n" + " -c \t\tParse data from file times\n" + " -m\t\t\tParse multiple packets from file\n" + " -n\t\t\tNo rendering, only parsing\n" + " -r\t\t\tParse routing header only\n" + " -q\t\t\tQuiet mode, don't output rendered string\n" + " -S\t\t\tSingle packet mode, close connection after parsing one packet\n" + " -s\t\t\tShow statistics at the end\n" + " -v\t\t\tVerbose, can be specified multiple times for more verbosity\n" + " -P\t\t\tShow progress\n" + " -h\t\t\tShow this help\n", + port, RECV_BUF_SIZE); + exit(0); + case '?': exit(-1); + default: abort(); + } + } + + if (filename) + test_file(filename, count, recv_buf_size); + else + test_server(port, count, recv_buf_size); + + return exit_code; +} From 19d9420eaad1c99a4e321218537599cf0adb2c1a Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Sun, 15 May 2011 22:59:30 +0200 Subject: [PATCH 240/378] funny activity stream encoding for xmpp --- bench/benchmark.wiki | 132 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 130 insertions(+), 2 deletions(-) diff --git a/bench/benchmark.wiki b/bench/benchmark.wiki index 87b5ced..498b76d 100644 --- a/bench/benchmark.wiki +++ b/bench/benchmark.wiki @@ -27,7 +27,6 @@ Here's an example from paragraph 4.4.2 of RFC 6121. to='benvolio@example.net'> away - }}} And here's the same information in a JSON rendition: @@ -59,11 +58,132 @@ np }}} === An average chat message === -=== A social network activity === + +{{{ + + Art thou not Romeo, and a Montague? + +}}} + +=== A new status updated activity === + +Example taken from http://onesocialweb.org/spec/1.0/osw-activities.html +You could call this XML namespace hell: + +{{{ + + + + + + to be or not to be ? + http://activitystrea.ms/schema/1.0/post + + http://onesocialweb.org/spec/1.0/object/status + to be or not to be ? + + + + http://onesocialweb.org/spec/1.0/acl/action/view + + + + + + + + +}}} + +http://activitystrea.ms/head/json-activity.html proposes a JSON encoding +of this. We'll have to add a routing header to it. + +{{{ +["activity",{"from":"hamlet@denmark.lit/snsclient"},{"verb":"post", +"title":"to be or not to be ?","object":{"type":"status", +"content":"to be or not to be ?","contentType":"text/plain"}] +}}} + +http://about.psyc.eu/Activity suggests a PSYC mapping for activity +streams. Should a "status post" be considered equivalent to a presence +description announcement or just a message in the "microblogging" channel? +We'll use the latter here: + +{{{ +:_context psyc://denmark.lit/~hamlet#_follow + +:_subject to be or not to be ? +:_type_content text/plain +_message +to be or not to be ? +| +}}} + === A message with JSON-unfriendly characters === + +{{{ + + "Neither, fair saint, if either thee dislike.", he said. +And +the +rest +is +history. + +}}} + === A message with XML-unfriendly characters === + +{{{ + + Wherefore art thou, Romeo? + + PročeŽ jsi ty, Romeo? + + +}}} + +=== A message with PSYC-unfriendly strings === + +{{{ + + I implore you with a pointless +newline in a header variable + Wherefore art thou, Romeo? +| +And for practicing purposes we added a PSYC packet delimiter. + +}}} + === A packet containing a JPEG photograph === +... TBD ... + === A random data structure === In this test we'll not consider XMPP at all and simply compare the @@ -107,6 +227,8 @@ _profile_user == Conclusions == +... TBD ... + == Criticism == Are we comparing apples and oranges? Yes and no, depends on what you @@ -139,3 +261,9 @@ the performance of a chat client using the two protocols, for instance by using libpurple with XMPP and PSYC accounts. To this purpose we first need to integrate libpsyc into libpurple. +== Futures == + +After a month of development libpsyc is already performing pretty +well, but we presume various optimizations, like rewriting parts +in assembler, are possible. + From ea3b9cbbf9ad03aa1c1b2cd12116eb0ce94ce697 Mon Sep 17 00:00:00 2001 From: Marenz Date: Mon, 16 May 2011 00:01:02 +0200 Subject: [PATCH 241/378] changed formating --- include/psyc/parse.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/psyc/parse.h b/include/psyc/parse.h index 8d9009d..4c5c28d 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -100,7 +100,8 @@ * perror("Error %i happened :(\n", res); * return res; * } - * } while (ret > 0) + * } + * while (ret > 0) * @endcode * * This simple example does not consider some more complex cases when you From 917ef4cff2c8bf69c95f3617798d34567be8f3b6 Mon Sep 17 00:00:00 2001 From: Marenz Date: Mon, 16 May 2011 00:01:13 +0200 Subject: [PATCH 242/378] enhancement and fixes for D binding --- d/include/psyc/common.d | 8 +++-- d/include/psyc/parse.d | 72 +++++++++++++++++++---------------------- 2 files changed, 40 insertions(+), 40 deletions(-) diff --git a/d/include/psyc/common.d b/d/include/psyc/common.d index 41ad6a5..b873bfa 100644 --- a/d/include/psyc/common.d +++ b/d/include/psyc/common.d @@ -90,12 +90,16 @@ extern (C) MatchVar varTypes[]; /** * Get the type of variable name. */ -Bool isRoutingVar(char *name, size_t len); +Bool psyc_isRoutingVar(char *name, size_t len); + +alias psyc_isRoutingVar isRoutingVar; /** * Get the type of variable name. */ -Type getVarType(char *name, size_t len); +Type psyc_getVarType(char *name, size_t len); + +alias psyc_getVarType getVarType; /** * Checks if long keyword string inherits from short keyword string. diff --git a/d/include/psyc/parse.d b/d/include/psyc/parse.d index bd0ca28..ad87453 100644 --- a/d/include/psyc/parse.d +++ b/d/include/psyc/parse.d @@ -19,66 +19,62 @@ enum ParseFlag */ enum ParseRC { -/// Error, packet is not ending with a valid delimiter. + /// Error, packet is not ending with a valid delimiter. ERROR_END = -8, -/// Error, expected NL after the method. + /// Error, expected NL after the method. ERROR_METHOD = -7, -/// Error, expected NL after a modifier. + /// Error, expected NL after a modifier. ERROR_MOD_NL = -6, -/// Error, modifier length is not numeric. + /// Error, modifier length is not numeric. ERROR_MOD_LEN = -5, -/// Error, expected TAB before modifier value. + /// Error, expected TAB before modifier value. ERROR_MOD_TAB = -4, -/// Error, modifier name is missing. + /// Error, modifier name is missing. ERROR_MOD_NAME = -3, -/// Error, expected NL after the content length. + /// Error, expected NL after the content length. ERROR_LENGTH = -2, -/// Error in packet. + /// Error in packet. ERROR = -1, -// Success, used internally. - SUCCESS = 0, -/// Buffer contains insufficient amount of data. -/// Fill another buffer and concatenate it with the end of the current buffer, -/// from the cursor position to the end. + /// Buffer contains insufficient amount of data. + /// Fill another buffer and concatenate it with the end of the current buffer, + /// from the cursor position to the end. INSUFFICIENT = 1, -/// Routing modifier parsing done. -/// Operator, name & value contains the respective parts. + /// Routing modifier parsing done. + /// Operator, name & value contains the respective parts. ROUTING = 2, -/// Start of an incomplete entity modifier. -/// Operator & name are complete, value is incomplete. + /// Start of an incomplete entity modifier. + /// Operator & name are complete, value is incomplete. ENTITY_START = 3, -/// Continuation of an incomplete entity modifier. + /// Continuation of an incomplete entity modifier. ENTITY_CONT = 4, -/// End of an incomplete entity modifier. + /// End of an incomplete entity modifier. ENTITY_END = 5, -/// Entity modifier parsing done in one go. -/// Operator, name & value contains the respective parts. + /// Entity modifier parsing done in one go. + /// Operator, name & value contains the respective parts. ENTITY = 6, -/// Start of an incomplete body. -/// Name contains method, value contains part of the body. + /// Start of an incomplete body. + /// Name contains method, value contains part of the body. BODY_START = 7, -/// Continuation of an incomplete body. + /// Continuation of an incomplete body. BODY_CONT = 8, -/// End of an incomplete body. + /// End of an incomplete body. BODY_END = 9, -/// Body parsing done in one go, name contains method, value contains body. + /// Body parsing done in one go, name contains method, value contains body. BODY = 10, -/// Start of an incomplete content, value contains part of content. -/// Used when ROUTING_ONLY is set. + /// Start of an incomplete content, value contains part of content. + /// Used when ROUTING_ONLY is set. CONTENT_START = 7, -/// Continuation of an incomplete body. -/// Used when ROUTING_ONLY is set. + /// Continuation of an incomplete body. + /// Used when ROUTING_ONLY is set. CONTENT_CONT = 8, -/// End of an incomplete body. -/// Used when ROUTING_ONLY is set. + /// End of an incomplete body. + /// Used when ROUTING_ONLY is set. CONTENT_END = 9, -/// Content parsing done in one go, value contains the whole content. -/// Used when ROUTING_ONLY is set. + /// Content parsing done in one go, value contains the whole content. + /// Used when ROUTING_ONLY is set. CONTENT = 10, -// Binary value parsing complete, used internally. - COMPLETE = 11, -// Binary value parsing incomplete, used internally. - INCOMPLETE = 12, + /// Finished parsing packet. + COMPLETE = 11 } /** From 972f076dc8f203ea11bd0a91df00b051841de804 Mon Sep 17 00:00:00 2001 From: Marenz Date: Mon, 16 May 2011 00:15:32 +0200 Subject: [PATCH 243/378] updated README --- README | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/README b/README index e8b71d5..26b9b6b 100644 --- a/README +++ b/README @@ -10,8 +10,8 @@ See http://about.psyc.eu for information on PSYC in general. The plain C API located in the include/psyc directory along with the file psyc.h is primarily intended to be used for binding with other languages and frameworks. -Available bindings are located in include/ where name is the language or -framework. +Available bindings are located directly in the root folder named according to +the language or framework. Currently there exists only a binding for D == C API == @@ -28,11 +28,12 @@ psyc/syntax.h -- definitions and constants related to parsing and rendering == Directory Overview == -doc -- where the documentation will be put after generation -include -- contains all bindings and the core C API for the library -lib -- where the compiled library will be put -src -- contains the sourcecode of the library -test -- contains test sourcecodes and test input files +doc -- target folder for the documentation after generation (make doc) +include -- the core C API for the library +lib -- target folder for the compiled library (make) +src -- the sourcecode of the library +test -- test sourcecodes and test input files +d -- the D binding == Compiling libpsyc == @@ -65,7 +66,7 @@ into the library, contact either anyone of us directly or just join the developement room at psyc://psyced.org/@welcome - xmpp:*welcome@psyced.org (jabber is known to have problems sometimes) + xmpp:*welcome@psyced.org (gtalk probably won't work) irc://psyced.org/welcome == Licence == From d2e785a30b5f994e2be8a49a18d88d86587fdaba Mon Sep 17 00:00:00 2001 From: Marenz Date: Mon, 16 May 2011 00:35:11 +0200 Subject: [PATCH 244/378] removed comment --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index 26b9b6b..363d683 100644 --- a/README +++ b/README @@ -66,7 +66,7 @@ into the library, contact either anyone of us directly or just join the developement room at psyc://psyced.org/@welcome - xmpp:*welcome@psyced.org (gtalk probably won't work) + xmpp:*welcome@psyced.org irc://psyced.org/welcome == Licence == From b2833eaa8aea4e4ff74055ecf2277e0ff3d9f432 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Mon, 16 May 2011 01:39:26 +0200 Subject: [PATCH 245/378] where the lpc is --- README | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README b/README index 363d683..a3ef4a9 100644 --- a/README +++ b/README @@ -10,8 +10,10 @@ See http://about.psyc.eu for information on PSYC in general. The plain C API located in the include/psyc directory along with the file psyc.h is primarily intended to be used for binding with other languages and frameworks. -Available bindings are located directly in the root folder named according to -the language or framework. Currently there exists only a binding for D +The LPC binding for psyced is distributed with psyclpc since it is spread +over several files (LPC has no simple approach to binding). Other bindings +are located directly in the root folder named according to the language or +framework. Currently there's only a binding for D. == C API == From db597756d9fe5c981db5ad1d65474caf2aea3467 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 16 May 2011 12:18:49 +0200 Subject: [PATCH 246/378] license header --- LICENSE | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..200529a --- /dev/null +++ b/LICENSE @@ -0,0 +1,5 @@ +Copyright (c) since 2011 by: + Carlo von Loesch (psyc://psyced.org/~lynX) + Gabor Adam Toth (psyc://tgbit.net/~tg) + Mathias Baumann (psyc://supraverse.net/~marenz) + From 254bb58a7cdf25ec6a774e851a94980efde3b73b Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 16 May 2011 13:17:57 +0200 Subject: [PATCH 247/378] bench: converted to org, added packet extraction script, added first results --- bench/Makefile | 28 +++++ bench/benchmark.org | 270 ++++++++++++++++++++++++++++++++++++++++++++ bench/results.org | 55 +++++++++ 3 files changed, 353 insertions(+) create mode 100644 bench/Makefile create mode 100644 bench/benchmark.org create mode 100644 bench/results.org diff --git a/bench/Makefile b/bench/Makefile new file mode 100644 index 0000000..d886661 --- /dev/null +++ b/bench/Makefile @@ -0,0 +1,28 @@ +ORG_PATH = /usr/share/emacs/site-lisp/org-mode +INIT = (setq load-path (cons \"/usr/share/emacs/site-lisp/org-mode\" load-path)) (require 'org-install) + +wiki2org: + perl -pe '\ + s/^= (.*) =\s*$$/#+TITLE: $$1\n/; \ + s/^== (.*) ==\s*$$/* $$1/; \ + s/^=== (.*) ===\s*$$/** $$1/; \ + s/^{{{/#+BEGIN_SRC/; \ + s/^}}}/#+END_SRC/ \ + ' benchmark.wiki >benchmark.org + +tangle: + emacs -Q --batch --eval \ + "(progn ${INIT} (find-file \"benchmark.org\") \ + (setq org-babel-tangle-pad-newline nil org-src-preserve-indentation t) \ + (org-babel-tangle) (kill-buffer))" + perl -pi -e 'print "\n" unless $$p; $$p=1' packets/user_profile.psyc + +html: + emacs -Q --batch --eval \ + "(progn ${INIT} (find-file \"benchmark.org\") \ + (org-export-as-html-batch) (kill-buffer))" + +pdf: + emacs -Q --batch --eval \ + "(progn ${INIT} (find-file \"benchmark.org\") \ + (org-export-as-pdf org-export-headline-levels) (kill-buffer))" diff --git a/bench/benchmark.org b/bench/benchmark.org new file mode 100644 index 0000000..7532afa --- /dev/null +++ b/bench/benchmark.org @@ -0,0 +1,270 @@ +#+TITLE: libpsyc Performance Benchmarks + +In this document we present the results of performance benchmarks +of libpsyc compared with libjson-glib and libxml2. + +* Procedure +We'll use typical messages from the XMPP ("stanzas" in Jabber +lingo) and compare them with equivalent JSON encodings, +verbose and compact PSYC formats. + +In some cases we will additionally compare PSYC packets to +a more efficient XML encoding based on PSYC methods, to have +a more accurate comparison of the actual PSYC and XML +syntaxes, rather than the protocol structures of PSYC and XMPP. + +* The Benchmarks +** A presence packet +Since presence packets are by far the dominant messaging content +in the XMPP network, we'll start with one of them. +Here's an example from paragraph 4.4.2 of RFC 6121. + +#+BEGIN_SRC xml :tangle packets/presence.xml + + away + +#+END_SRC + +And here's the same information in a JSON rendition: + +#+BEGIN_SRC js :tangle packets/presence.json +["presence",{"from":"juliet@example.com/balcony","to":"benvolio@example.net"},{"show":"away"}] +#+END_SRC + +Here's the equivalent PSYC packet in verbose form +(since it is a multicast, the single recipients do not +need to be mentioned): + +#+BEGIN_SRC psyc :tangle packets/presence.psyc +:_context psyc://example.com/~juliet + +=_degree_availability 4 +_notice_presence +| +#+END_SRC + +And the same in compact form: + +#+BEGIN_SRC psyc +:c psyc://example.com/~juliet + +=da 4 +np +| +#+END_SRC + +** An average chat message + +XML: + +#+BEGIN_SRC xml :tangle packets/chat_msg.xml + + Art thou not Romeo, and a Montague? + +#+END_SRC + +PSYC: + +#+BEGIN_SRC psyc :tangle packets/chat_msg.psyc +:_source psyc://example.com/~juliet +:_target psyc://example.net/~romeo + +_message_private +Art thou not Romeo, and a Montague? +| +#+END_SRC + +** A new status updated activity +Example taken from http://onesocialweb.org/spec/1.0/osw-activities.html +You could call this XML namespace hell: + +#+BEGIN_SRC xml :tangle packets/activity.xml + + + + + + to be or not to be ? + http://activitystrea.ms/schema/1.0/post + + http://onesocialweb.org/spec/1.0/object/status + to be or not to be ? + + + + http://onesocialweb.org/spec/1.0/acl/action/view + + + + + + + + +#+END_SRC + +http://activitystrea.ms/head/json-activity.html proposes a JSON encoding +of this. We'll have to add a routing header to it. + +#+BEGIN_SRC js :tangle packets/activity.json +["activity",{"from":"hamlet@denmark.lit/snsclient"},{"verb":"post", +"title":"to be or not to be ?","object":{"type":"status", +"content":"to be or not to be ?","contentType":"text/plain"}}] +#+END_SRC + +http://about.psyc.eu/Activity suggests a PSYC mapping for activity +streams. Should a "status post" be considered equivalent to a presence +description announcement or just a message in the "microblogging" channel? +We'll use the latter here: + +#+BEGIN_SRC psyc :tangle packets/activity.psyc +:_context psyc://denmark.lit/~hamlet#_follow + +:_subject to be or not to be ? +:_type_content text/plain +_message +to be or not to be ? +| +#+END_SRC + +** A message with JSON-unfriendly characters +#+BEGIN_SRC xml :tangle packets/json-unfriendly.xml + + "Neither, fair saint, if either thee dislike.", he said. +And +the +rest +is +history. + +#+END_SRC + +** A message with XML-unfriendly characters +#+BEGIN_SRC xml :tangle packets/xml-unfriendly.xml + + Wherefore art thou, Romeo? + + PročeŽ jsi ty, Romeo? + + +#+END_SRC + +** A message with PSYC-unfriendly strings +#+BEGIN_SRC xml :tangle packets/psyc-unfriendly.xml + + I implore you with a pointless +newline in a header variable + Wherefore art thou, Romeo? +| +And for practicing purposes we added a PSYC packet delimiter. + +#+END_SRC + +** A packet containing a JPEG photograph +... TBD ... + +** A random data structure +In this test we'll not consider XMPP at all and simply compare the +efficiency of the three syntaxes at serializing a typical user data base +storage information. We'll again start with XML: + +#+BEGIN_SRC xml :tangle packets/user_profile.xml + + Silvio Berlusconi + Premier + I +
+ Via del Colosseo, 1 + 00100 + Roma +
+ http://example.org +
+#+END_SRC + +In JSON this would look like this: + +#+BEGIN_SRC js :tangle packets/user_profile.json +["UserProfile",{"Name":"Silvio Berlusconi","JobTitle":"Premier","Country":"I","Address": +{"Street":"Via del Colosseo, 1","PostalCode":"00100","City":"Roma"},"Page":"http://example.org"}] +#+END_SRC + +Here's a way to model this in PSYC: + +#+BEGIN_SRC psyc :tangle packets/user_profile.psyc + +:_name Silvio Berlusconi +:_title_job Premier +:_country I +:_address_street Via del Colosseo, 1 +:_address_code_postal 00100 +:_address_city Roma +:_page http://example.org +_profile_user +| +#+END_SRC + +* Conclusions +... TBD ... + +* Criticism +Are we comparing apples and oranges? Yes and no, depends on what you +need. XML is a syntax best suited for complex structured data in +well-defined formats - especially good for text mark-up. JSON is a syntax +intended to hold arbitrarily structured data suitable for immediate +inclusion in javascript source codes. The PSYC syntax is an evolved +derivate of RFC 822, the syntax used by HTTP and E-Mail, and is therefore +limited in the kind and depth of data structures that can be represented +with it, but in exchange it is highly performant at doing just that. + +So it is up to you to find out which of the three formats fulfils your +requirements the best. We use PSYC for the majority of messaging where +JSON and XMPP aren't efficient and opaque enough, but we employ XML and +JSON as payloads within PSYC for data that doesn't fit the PSYC model. +For some reason all three formats are being used for messaging, although +only PSYC was actually designed for that purpose. + +* Caveats +In every case we'll compare performance of parsing and re-rendering +these messages, but consider also that the applicative processing +of an XML DOM tree is more complicated than just accessing +certain elements in a JSON data structure or PSYC variable +mapping. + +For a speed check in real world conditions which also consider the +complexity of processing incoming messages we should compare +the performance of a chat client using the two protocols, +for instance by using libpurple with XMPP and PSYC accounts. +To this purpose we first need to integrate libpsyc into libpurple. + +* Futures +After a month of development libpsyc is already performing pretty +well, but we presume various optimizations, like rewriting parts +in assembler, are possible. + diff --git a/bench/results.org b/bench/results.org new file mode 100644 index 0000000..a81c3ae --- /dev/null +++ b/bench/results.org @@ -0,0 +1,55 @@ +#+TITLE: Benchmark results +#+OPTIONS: ^:{} + +* libpsyc + +: ./testPsyc -snqc 1000000 -f $file + +- presence: 597 ms +- chat_msg: 714 ms +- user_profile: 1806 ms +- activity: 903 ms + +* libjson + +: ./testJson -snqc 1000000 -f $file + +- presence: 3247 ms +- user_profile: 5847 ms +- activity: 5768 ms + +* rapidxml + +: ./rapidxml 1000000 $file + +- presence: 1719 ms +- chat_msg: 1893 ms +- user_profile: 2477 ms +- activity: 4419 ms + +* rapidxml fast mode + +: fast_mode=1 ./rapidxml 1000000 $file + +- presence: 1643 ms +- chat_msg: 1799 ms +- user_profile: 2218 ms +- activity: 4001 ms + +* libxml + +: ./libxml 1000000 $file + +- presence: 7557 ms +- chat_msg: 9777 ms +- user_profile: 12377 ms +- activity: 28858 ms + +* libxml sax + +: ./libxml-sax 1000000 $file + +- presence: 4997 ms +- chat_msg: 5997 ms +- user_profile: 7350 ms +- activity: 13357 ms From bded07ac3120bd6c3c7b48553d01c9d8b7787ab5 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 16 May 2011 13:19:14 +0200 Subject: [PATCH 248/378] + --- bench/results.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bench/results.org b/bench/results.org index a81c3ae..d2798d1 100644 --- a/bench/results.org +++ b/bench/results.org @@ -10,7 +10,7 @@ - user_profile: 1806 ms - activity: 903 ms -* libjson +* json-c : ./testJson -snqc 1000000 -f $file From 498ea9bc5902ea4ae9836f237c31f7e0134ced77 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 16 May 2011 14:23:53 +0200 Subject: [PATCH 249/378] bench: results in table --- bench/results.org | 57 +++++++++++------------------------------------ 1 file changed, 13 insertions(+), 44 deletions(-) diff --git a/bench/results.org b/bench/results.org index d2798d1..a50b427 100644 --- a/bench/results.org +++ b/bench/results.org @@ -1,55 +1,24 @@ #+TITLE: Benchmark results -#+OPTIONS: ^:{} +#+OPTIONS: ^:{} toc:nil -* libpsyc +* Results -: ./testPsyc -snqc 1000000 -f $file +Parsing time of 1 000 000 packets in milliseconds: -- presence: 597 ms -- chat_msg: 714 ms -- user_profile: 1806 ms -- activity: 903 ms +| | libpsyc | json-c | rapidxml | rapidxml-fast | libxml | libxml-sax | +|-----------+---------+--------+----------+---------------+--------+------------| +| presence | 597 | 3247 | 1719 | 1643 | 7557 | 4997 | +| chat msg | 714 | | 1893 | 1799 | 9777 | 5997 | +| activity | 903 | 5768 | 4419 | 4001 | 28858 | 13357 | +| user prof | 1806 | 5847 | 2477 | 2218 | 12377 | 7350 | +| / | < | | | | > | | -* json-c -: ./testJson -snqc 1000000 -f $file - -- presence: 3247 ms -- user_profile: 5847 ms -- activity: 5768 ms - -* rapidxml +* Commands used +: ./testPsyc -snc 1000000 -f $file +: ./testJson -snc 1000000 -f $file : ./rapidxml 1000000 $file - -- presence: 1719 ms -- chat_msg: 1893 ms -- user_profile: 2477 ms -- activity: 4419 ms - -* rapidxml fast mode - : fast_mode=1 ./rapidxml 1000000 $file - -- presence: 1643 ms -- chat_msg: 1799 ms -- user_profile: 2218 ms -- activity: 4001 ms - -* libxml - : ./libxml 1000000 $file - -- presence: 7557 ms -- chat_msg: 9777 ms -- user_profile: 12377 ms -- activity: 28858 ms - -* libxml sax - : ./libxml-sax 1000000 $file - -- presence: 4997 ms -- chat_msg: 5997 ms -- user_profile: 7350 ms -- activity: 13357 ms From 58b4db474f45341f151bae01a436e7585ac6df27 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 16 May 2011 14:26:24 +0200 Subject: [PATCH 250/378] + --- bench/results.org | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/bench/results.org b/bench/results.org index a50b427..24ff8a1 100644 --- a/bench/results.org +++ b/bench/results.org @@ -5,13 +5,13 @@ Parsing time of 1 000 000 packets in milliseconds: -| | libpsyc | json-c | rapidxml | rapidxml-fast | libxml | libxml-sax | -|-----------+---------+--------+----------+---------------+--------+------------| -| presence | 597 | 3247 | 1719 | 1643 | 7557 | 4997 | -| chat msg | 714 | | 1893 | 1799 | 9777 | 5997 | -| activity | 903 | 5768 | 4419 | 4001 | 28858 | 13357 | -| user prof | 1806 | 5847 | 2477 | 2218 | 12377 | 7350 | -| / | < | | | | > | | +| | libpsyc | json-c | libxml-sax | libxml | rapidxml-fast | rapidxml | +|-----------+---------+--------+------------+--------+---------------+----------| +| presence | 597 | 3247 | 4997 | 7557 | 1643 | 1719 | +| chat msg | 714 | | 5997 | 9777 | 1799 | 1893 | +| activity | 903 | 5768 | 13357 | 28858 | 4001 | 4419 | +| user prof | 1806 | 5847 | 7350 | 12377 | 2218 | 2477 | +| / | < | | | | | > | * Commands used From 4d45e306b6bd274f923cc6507ad4943abe883af3 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 16 May 2011 15:02:06 +0200 Subject: [PATCH 251/378] bench: json-glib results --- bench/results.org | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/bench/results.org b/bench/results.org index 24ff8a1..ada183c 100644 --- a/bench/results.org +++ b/bench/results.org @@ -5,19 +5,20 @@ Parsing time of 1 000 000 packets in milliseconds: -| | libpsyc | json-c | libxml-sax | libxml | rapidxml-fast | rapidxml | -|-----------+---------+--------+------------+--------+---------------+----------| -| presence | 597 | 3247 | 4997 | 7557 | 1643 | 1719 | -| chat msg | 714 | | 5997 | 9777 | 1799 | 1893 | -| activity | 903 | 5768 | 13357 | 28858 | 4001 | 4419 | -| user prof | 1806 | 5847 | 7350 | 12377 | 2218 | 2477 | -| / | < | | | | | > | +| | libpsyc | json-c | json-glib | libxml-sax | libxml | rapidxml-fast | rapidxml | +|-----------+---------+--------+-----------+------------+--------+---------------+----------| +| presence | 597 | 3247 | 10197 | 4997 | 7557 | 1643 | 1719 | +| chat msg | 714 | | | 5997 | 9777 | 1799 | 1893 | +| activity | 903 | 5768 | 16846 | 13357 | 28858 | 4001 | 4419 | +| user prof | 1806 | 5847 | 17468 | 7350 | 12377 | 2218 | 2477 | +| / | < | | | | | | > | * Commands used : ./testPsyc -snc 1000000 -f $file : ./testJson -snc 1000000 -f $file +: ./testJsonGlib -snc 1000000 -f $file : ./rapidxml 1000000 $file : fast_mode=1 ./rapidxml 1000000 $file : ./libxml 1000000 $file From c38cb2107f510164bc1644c4204aed72bfc26ac2 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 16 May 2011 15:25:30 +0200 Subject: [PATCH 252/378] bench make --- bench/Makefile | 10 ++++++++-- bench/results.org | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/bench/Makefile b/bench/Makefile index d886661..1acfe12 100644 --- a/bench/Makefile +++ b/bench/Makefile @@ -1,5 +1,12 @@ ORG_PATH = /usr/share/emacs/site-lisp/org-mode -INIT = (setq load-path (cons \"/usr/share/emacs/site-lisp/org-mode\" load-path)) (require 'org-install) +INIT = (setq load-path (cons \"/usr/share/emacs/site-lisp/org-mode\" load-path) \ + make-backup-files nil \ + org-export-author-info nil \ + org-export-creator-info nil \ + org-export-html-validation-link nil \ + org-babel-tangle-pad-newline nil \ + org-src-preserve-indentation t) \ + (require 'org-install) wiki2org: perl -pe '\ @@ -13,7 +20,6 @@ wiki2org: tangle: emacs -Q --batch --eval \ "(progn ${INIT} (find-file \"benchmark.org\") \ - (setq org-babel-tangle-pad-newline nil org-src-preserve-indentation t) \ (org-babel-tangle) (kill-buffer))" perl -pi -e 'print "\n" unless $$p; $$p=1' packets/user_profile.psyc diff --git a/bench/results.org b/bench/results.org index ada183c..2352788 100644 --- a/bench/results.org +++ b/bench/results.org @@ -5,13 +5,13 @@ Parsing time of 1 000 000 packets in milliseconds: -| | libpsyc | json-c | json-glib | libxml-sax | libxml | rapidxml-fast | rapidxml | +| | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml fast | rapidxml | |-----------+---------+--------+-----------+------------+--------+---------------+----------| | presence | 597 | 3247 | 10197 | 4997 | 7557 | 1643 | 1719 | | chat msg | 714 | | | 5997 | 9777 | 1799 | 1893 | | activity | 903 | 5768 | 16846 | 13357 | 28858 | 4001 | 4419 | | user prof | 1806 | 5847 | 17468 | 7350 | 12377 | 2218 | 2477 | -| / | < | | | | | | > | +| / | <> | < | > | < | > | < | > | * Commands used From 32139344712ee2670e0d03b891f88019f8bb151a Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 16 May 2011 16:27:51 +0200 Subject: [PATCH 253/378] license --- LICENSE | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/LICENSE b/LICENSE index 200529a..efc2cc9 100644 --- a/LICENSE +++ b/LICENSE @@ -3,3 +3,20 @@ Copyright (c) since 2011 by: Gabor Adam Toth (psyc://tgbit.net/~tg) Mathias Baumann (psyc://supraverse.net/~marenz) +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. From 13fdac0613608da1533ba7c143b6ef93af058df9 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 16 May 2011 20:13:10 +0200 Subject: [PATCH 254/378] bench: testPsycFast results --- .gitignore | 1 + bench/Makefile | 19 ++++++---- bench/results.org | 18 +++++----- test/Makefile | 8 +++-- test/test.c | 5 ++- test/test.h | 8 +++++ test/testPsyc.c | 10 +++--- test/testPsycFast.c | 88 +++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 133 insertions(+), 24 deletions(-) create mode 100644 test/testPsycFast.c diff --git a/.gitignore b/.gitignore index 4c7cf96..754a28f 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ test/testMatch test/testParser test/testRender test/testPsyc +test/testPsycFast test/testText test/isRoutingVar test/getVarType diff --git a/bench/Makefile b/bench/Makefile index 1acfe12..2aa0ca3 100644 --- a/bench/Makefile +++ b/bench/Makefile @@ -8,6 +8,8 @@ INIT = (setq load-path (cons \"/usr/share/emacs/site-lisp/org-mode\" load-path) org-src-preserve-indentation t) \ (require 'org-install) +ORG = benchmark.org results.org + wiki2org: perl -pe '\ s/^= (.*) =\s*$$/#+TITLE: $$1\n/; \ @@ -17,18 +19,21 @@ wiki2org: s/^}}}/#+END_SRC/ \ ' benchmark.wiki >benchmark.org -tangle: +packets: emacs -Q --batch --eval \ "(progn ${INIT} (find-file \"benchmark.org\") \ (org-babel-tangle) (kill-buffer))" perl -pi -e 'print "\n" unless $$p; $$p=1' packets/user_profile.psyc html: - emacs -Q --batch --eval \ - "(progn ${INIT} (find-file \"benchmark.org\") \ - (org-export-as-html-batch) (kill-buffer))" + for f in ${ORG}; do \ + emacs -Q --batch --eval \ + "(progn ${INIT} (find-file \"$$f\") \ + (org-export-as-html-batch) (kill-buffer))"; \ + done pdf: - emacs -Q --batch --eval \ - "(progn ${INIT} (find-file \"benchmark.org\") \ - (org-export-as-pdf org-export-headline-levels) (kill-buffer))" + for f in ${ORG}; do \ + emacs -Q --batch --eval \ + "(progn ${INIT} (find-file \"$@.org\") \ + (org-export-as-pdf org-export-headline-levels) (kill-buffer))" diff --git a/bench/results.org b/bench/results.org index 2352788..e46d1f6 100644 --- a/bench/results.org +++ b/bench/results.org @@ -5,20 +5,22 @@ Parsing time of 1 000 000 packets in milliseconds: -| | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml fast | rapidxml | -|-----------+---------+--------+-----------+------------+--------+---------------+----------| -| presence | 597 | 3247 | 10197 | 4997 | 7557 | 1643 | 1719 | -| chat msg | 714 | | | 5997 | 9777 | 1799 | 1893 | -| activity | 903 | 5768 | 16846 | 13357 | 28858 | 4001 | 4419 | -| user prof | 1806 | 5847 | 17468 | 7350 | 12377 | 2218 | 2477 | -| / | <> | < | > | < | > | < | > | - +| | libpsyc | libpsyc fast | json-c | json-glib | libxml sax | libxml | rapidxml fast | rapidxml | +|-----------+---------+--------------+--------+-----------+------------+--------+---------------+----------| +| presence | 597 | 246 | 3247 | 10197 | 4997 | 7557 | 1643 | 1719 | +| chat msg | 714 | 320 | | | 5997 | 9777 | 1799 | 1893 | +| activity | 903 | 366 | 5768 | 16846 | 13357 | 28858 | 4001 | 4419 | +| user prof | 1806 | 608 | 5847 | 17468 | 7350 | 12377 | 2218 | 2477 | +|-----------+---------+--------------+--------+-----------+------------+--------+---------------+----------| +| / | < | > | < | > | < | > | < | > | * Commands used : ./testPsyc -snc 1000000 -f $file +: ./testPsycFast -sc 1000000 -f $file : ./testJson -snc 1000000 -f $file : ./testJsonGlib -snc 1000000 -f $file +: ./testStrlen -sc 1000000 -f $file : ./rapidxml 1000000 $file : fast_mode=1 ./rapidxml 1000000 $file : ./libxml 1000000 $file diff --git a/test/Makefile b/test/Makefile index c01a811..4d3c38e 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,9 +1,10 @@ OPT = -O2 DEBUG = 2 -CFLAGS = -I../include -I../src -Wall -std=c99 ${OPT} +CFLAGS_COMMON = -Wall -std=c99 ${OPT} +CFLAGS = -I../include -I../src ${CFLAGS_COMMON} LDFLAGS = -L../lib LOADLIBES = -lpsyc -lm -TARGETS = testPsyc testParser testMatch testRender testText isRoutingVar getVarType +TARGETS = testPsyc testPsycFast testParser testMatch testRender testText isRoutingVar getVarType O = test.o WRAPPER = DIET = diet @@ -20,7 +21,8 @@ all: ${TARGETS} it: all testPsyc: LOADLIBES := ${LOADLIBES} ${LOADLIBES_NET} -testPsyc: test.o +testPsycFast: LOADLIBES := ${LOADLIBES} ${LOADLIBES_NET} +#testPsycFast: LOADLIBES := ${LOADLIBES_NET} diet: WRAPPER = ${DIET} diet: all diff --git a/test/test.c b/test/test.c index ef09db4..b11f683 100644 --- a/test/test.c +++ b/test/test.c @@ -5,6 +5,10 @@ * "The C source code presented in this document is hereby granted to the public domain, and is completely free of any license restriction." */ +#ifndef __USE_POSIX +# define __USE_POSIX +#endif + #include #include #include @@ -18,7 +22,6 @@ #include #include -#define __USE_POSIX #include #include "test.h" diff --git a/test/test.h b/test/test.h index b49f7f8..8b7b0be 100644 --- a/test/test.h +++ b/test/test.h @@ -1,10 +1,18 @@ #ifndef TEST_H # define TEST_H +#ifndef RECV_BUF_SIZE # define RECV_BUF_SIZE 8 * 1024 +#endif +#ifndef CONT_BUF_SIZE # define CONT_BUF_SIZE 8 * 1024 +#endif +#ifndef SEND_BUF_SIZE # define SEND_BUF_SIZE 8 * 1024 +#endif +#ifndef NUM_PARSERS # define NUM_PARSERS 100 +#endif void test_init(int i); int test_input(int i, char *recvbuf, size_t nbytes); diff --git a/test/testPsyc.c b/test/testPsyc.c index ce397ef..f3cbf0f 100644 --- a/test/testPsyc.c +++ b/test/testPsyc.c @@ -12,7 +12,7 @@ #include #include -#include "test.h" +#include "test.c" // max size for routing & entity header #define ROUTING_LINES 16 @@ -31,8 +31,9 @@ psycModifier entity[NUM_PARSERS][ENTITY_LINES]; int contbytes, exit_code; -static inline void resetString (psycString *s, uint8_t freeptr); -t +static inline +void resetString (psycString *s, uint8_t freeptr); + // initialize parser & packet variables void test_init (int i) { // reset parser state & packet @@ -301,8 +302,7 @@ int test_input (int i, char *recvbuf, size_t nbytes) { return ret; } -static inline -void resetString (psycString *s, uint8_t freeptr) +inline void resetString (psycString *s, uint8_t freeptr) { if (freeptr && s->length) free((void*)s->ptr); diff --git a/test/testPsycFast.c b/test/testPsycFast.c new file mode 100644 index 0000000..0e1aa28 --- /dev/null +++ b/test/testPsycFast.c @@ -0,0 +1,88 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +//#define PSYC_PARSE_INLINE +//#include "../src/parse.c" +#include + +#include "test.c" + +// max size for routing & entity header +#define ROUTING_LINES 16 +#define ENTITY_LINES 32 + +// cmd line args +char *filename, *port = "4440"; +uint8_t verbose, stats; +uint8_t routing_only; +size_t count = 1, recv_buf_size = RECV_BUF_SIZE; + +psycParseState parser; + +void test_init (int i) { + // reset parser state + if (routing_only) + psyc_initParseState2(&parser, PSYC_PARSE_ROUTING_ONLY); + else + psyc_initParseState(&parser); +} + +int test_input (int i, char *recvbuf, size_t nbytes) { + char oper; + psycString name, value; + int ret; + + parser.buffer = (psycString){nbytes, recvbuf}; + parser.cursor = 0; + + for (;;) { + ret = psyc_parse(&parser, &oper, &name, &value); + + if (ret == PSYC_PARSE_COMPLETE || ret < 0) + return -1; + } +} + +int main (int argc, char **argv) { + int c; + while ((c = getopt (argc, argv, "f:p:b:c:qrsvh")) != -1) { + switch (c) { + case 'f': filename = optarg; break; + case 'p': port = optarg; check_range(c, optarg, 1, 0); break; + case 'b': recv_buf_size = atoi(optarg); check_range(c, optarg, 1, RECV_BUF_SIZE); break; + case 'c': count = atoi(optarg); check_range(c, optarg, 1, 0); break; + case 'r': routing_only = 1; break; + case 's': stats = 1; break; + case 'v': verbose++; break; + case 'h': + printf( + "testPsyc -f [-b ] [-c ] [-mnqrSsvP]\n" + "testPsyc [-p ] [-b ] [-nqrsvP]\n" + " -f \tInput file name\n" + " -p \t\tListen on TCP port, default is %s\n" + " -b \tRead/receive buffer size, default is %d\n" + " -c \t\tParse data from file times\n" + " -r\t\t\tParse routing header only\n" + " -s\t\t\tShow statistics at the end\n" + " -h\t\t\tShow this help\n" + " -v\t\t\tVerbose\n", + port, RECV_BUF_SIZE); + exit(0); + case '?': exit(-1); + default: abort(); + } + } + + if (filename) + test_file(filename, count, recv_buf_size); + else + test_server(port, count, recv_buf_size); + + return 0; +} From 9de3d1c1da65f5a8e03919b2008a56fa80ca1b75 Mon Sep 17 00:00:00 2001 From: Marenz Date: Tue, 17 May 2011 00:27:20 +0200 Subject: [PATCH 255/378] fixed bug in D-binding: state.getRemainingBuffer --- d/include/psyc/parse.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/d/include/psyc/parse.d b/d/include/psyc/parse.d index ad87453..adb9acd 100644 --- a/d/include/psyc/parse.d +++ b/d/include/psyc/parse.d @@ -265,7 +265,7 @@ struct ParseState void getRemainingBuffer ( ref ubyte[] buf ) { - buf = this.buffer.ptr[cursor .. getRemainingLength()]; + buf = this.buffer.ptr[cursor .. cursor + getRemainingLength()]; } } From 6e68b6a17d33e79b4274550e70580cfdcdbbb914 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 17 May 2011 00:27:26 +0200 Subject: [PATCH 256/378] bench: added test tools, updated results; added inline option for parse & render --- .gitignore | 5 +- bench/.gitignore | 3 ++ bench/results.org | 20 ++++---- include/psyc/parse.h | 6 +++ include/psyc/render.h | 6 +++ src/parse.c | 6 +++ src/render.c | 6 +++ test/Makefile | 13 +++-- test/test.h | 28 +++++++++++ test/testJson.c | 113 ++++++++++++++++++++++++++++++++++++++++++ test/testJsonGlib.c | 100 +++++++++++++++++++++++++++++++++++++ test/testPsyc.c | 38 ++++---------- test/testPsycFast.c | 88 -------------------------------- test/testPsycSpeed.c | 74 +++++++++++++++++++++++++++ test/testStrlen.c | 63 +++++++++++++++++++++++ 15 files changed, 438 insertions(+), 131 deletions(-) create mode 100644 bench/.gitignore create mode 100644 test/testJson.c create mode 100644 test/testJsonGlib.c delete mode 100644 test/testPsycFast.c create mode 100644 test/testPsycSpeed.c create mode 100644 test/testStrlen.c diff --git a/.gitignore b/.gitignore index 754a28f..b6b2544 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,10 @@ test/testMatch test/testParser test/testRender test/testPsyc -test/testPsycFast +test/testPsycSpeed +test/testJson +test/testJsonGlib +test/testStrlen test/testText test/isRoutingVar test/getVarType diff --git a/bench/.gitignore b/bench/.gitignore new file mode 100644 index 0000000..f93db6e --- /dev/null +++ b/bench/.gitignore @@ -0,0 +1,3 @@ +*.html +*.pdf +packets/ diff --git a/bench/results.org b/bench/results.org index e46d1f6..48dc2f1 100644 --- a/bench/results.org +++ b/bench/results.org @@ -5,23 +5,21 @@ Parsing time of 1 000 000 packets in milliseconds: -| | libpsyc | libpsyc fast | json-c | json-glib | libxml sax | libxml | rapidxml fast | rapidxml | -|-----------+---------+--------------+--------+-----------+------------+--------+---------------+----------| -| presence | 597 | 246 | 3247 | 10197 | 4997 | 7557 | 1643 | 1719 | -| chat msg | 714 | 320 | | | 5997 | 9777 | 1799 | 1893 | -| activity | 903 | 366 | 5768 | 16846 | 13357 | 28858 | 4001 | 4419 | -| user prof | 1806 | 608 | 5847 | 17468 | 7350 | 12377 | 2218 | 2477 | -|-----------+---------+--------------+--------+-----------+------------+--------+---------------+----------| -| / | < | > | < | > | < | > | < | > | +| | strlen | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml | +|-----------+--------+---------+--------+-----------+------------+--------+----------| +| presence | 30 | 246 | 2463 | 10197 | 4997 | 7557 | 1719 | +| chat msg | 41 | 320 | | | 5997 | 9777 | 1893 | +| activity | 42 | 366 | 4666 | 16846 | 13357 | 28858 | 4419 | +| user prof | 55 | 608 | 4715 | 17468 | 7350 | 12377 | 2477 | +|-----------+--------+---------+--------+-----------+------------+--------+----------| +| / | < | < | < | > | < | > | > | * Commands used -: ./testPsyc -snc 1000000 -f $file -: ./testPsycFast -sc 1000000 -f $file +: ./testPsycSpeed -sc 1000000 -f $file : ./testJson -snc 1000000 -f $file : ./testJsonGlib -snc 1000000 -f $file : ./testStrlen -sc 1000000 -f $file : ./rapidxml 1000000 $file -: fast_mode=1 ./rapidxml 1000000 $file : ./libxml 1000000 $file : ./libxml-sax 1000000 $file diff --git a/include/psyc/parse.h b/include/psyc/parse.h index 4c5c28d..0f2332c 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -428,6 +428,9 @@ const char * psyc_getParseRemainingBuffer (psycParseState *state) * @param value In case of a modifier it will point to the value, * in case of the body it will point to the data. */ +#ifdef __INLINE_PSYC_PARSE +static inline +#endif psycParseRC psyc_parse (psycParseState *state, char *oper, psycString *name, psycString *value); @@ -443,6 +446,9 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, * @param value Contains the list to be parsed. * @param elem It will point to the next element in the list. */ +#ifdef __INLINE_PSYC_PARSE +static inline +#endif psycParseListRC psyc_parseList (psycParseListState *state, psycString *elem); /** @} */ // end of parse group diff --git a/include/psyc/render.h b/include/psyc/render.h index 12fd42d..2f13793 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -58,11 +58,17 @@ typedef enum * @see psyc_newRawPacket2 * @see psyc_setPacketLength */ +#ifdef __INLINE_PSYC_RENDER +static inline +#endif psycRenderRC psyc_render (psycPacket *packet, char *buffer, size_t buflen); /** * Render a PSYC list into a buffer. */ +#ifdef __INLINE_PSYC_RENDER +static inline +#endif psycRenderListRC psyc_renderList (psycList *list, char *buffer, size_t buflen); /** @} */ // end of render group diff --git a/src/parse.c b/src/parse.c index a1f5798..4248c7c 100644 --- a/src/parse.c +++ b/src/parse.c @@ -202,6 +202,9 @@ parseRC psyc_parseModifier (psycParseState *state, char *oper, } /** Parse PSYC packets. */ +#ifdef __INLINE_PSYC_PARSE +static inline +#endif psycParseRC psyc_parse (psycParseState *state, char *oper, psycString *name, psycString *value) { @@ -483,6 +486,9 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, } /** List parser. */ +#ifdef __INLINE_PSYC_PARSE +static inline +#endif psycParseListRC psyc_parseList (psycParseListState *state, psycString *elem) { if (state->cursor >= state->buffer.length) diff --git a/src/render.c b/src/render.c index ad4822d..449d280 100644 --- a/src/render.c +++ b/src/render.c @@ -2,6 +2,9 @@ #include #include +#ifdef __INLINE_PSYC_RENDER +static inline +#endif psycRenderListRC psyc_renderList (psycList *list, char *buffer, size_t buflen) { size_t i, cur = 0; @@ -64,6 +67,9 @@ size_t psyc_renderModifier (psycModifier *mod, char *buffer) return cur; } +#ifdef __INLINE_PSYC_RENDER +static inline +#endif psycRenderRC psyc_render (psycPacket *packet, char *buffer, size_t buflen) { size_t i, cur = 0, len; diff --git a/test/Makefile b/test/Makefile index 4d3c38e..934ed1c 100644 --- a/test/Makefile +++ b/test/Makefile @@ -4,7 +4,7 @@ CFLAGS_COMMON = -Wall -std=c99 ${OPT} CFLAGS = -I../include -I../src ${CFLAGS_COMMON} LDFLAGS = -L../lib LOADLIBES = -lpsyc -lm -TARGETS = testPsyc testPsycFast testParser testMatch testRender testText isRoutingVar getVarType +TARGETS = testPsyc testPsycSpeed testParser testMatch testRender testText isRoutingVar getVarType O = test.o WRAPPER = DIET = diet @@ -21,8 +21,15 @@ all: ${TARGETS} it: all testPsyc: LOADLIBES := ${LOADLIBES} ${LOADLIBES_NET} -testPsycFast: LOADLIBES := ${LOADLIBES} ${LOADLIBES_NET} -#testPsycFast: LOADLIBES := ${LOADLIBES_NET} +testPsycSpeed: LOADLIBES := ${LOADLIBES} ${LOADLIBES_NET} +#testPsycSpeed: LOADLIBES := ${LOADLIBES_NET} + +testJson: LOADLIBES := ${LOADLIBES_NET} -ljson + +testJsonGlib: CFLAGS = ${CFLAGS_COMMON} -I/usr/include/json-glib-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include +testJsonGlib: LOADLIBES := ${LOADLIBES_NET} -ljson-glib-1.0 + +testStrlen: LOADLIBES := ${LOADLIBES_NET} diet: WRAPPER = ${DIET} diet: all diff --git a/test/test.h b/test/test.h index 8b7b0be..ee0d1f5 100644 --- a/test/test.h +++ b/test/test.h @@ -14,6 +14,34 @@ # define NUM_PARSERS 100 #endif +#define CASE_f case 'f': filename = optarg; break; +#define CASE_p case 'p': port = optarg; check_range(c, optarg, 1, 0); break; +#define CASE_b case 'b': recv_buf_size = atoi(optarg); check_range(c, optarg, 1, RECV_BUF_SIZE); break; +#define CASE_c case 'c': count = atoi(optarg); check_range(c, optarg, 1, 0); break; +#define CASE_n case 'n': no_render = 1; break; +#define CASE_m case 'm': multiple = 1; break; +#define CASE_q case 'q': quiet = 1; break; +#define CASE_r case 'r': routing_only = 1; break; +#define CASE_s case 's': stats = 1; break; +#define CASE_v case 'v': verbose++; break; +#define CASE_P case 'P': progress = 1; break; +#define CASE_S case 'S': single = 1; break; +#define HELP_FILE(name, opts) name " -f [-b ] [-c ] [-" opts "]\n" +#define HELP_PORT(name, opts) name " [-p ] [-b ] [-" opts "]\n" +#define HELP_f " -f \tInput file name\n" +#define HELP_p " -p \t\tListen on TCP port, default is %s\n" +#define HELP_b " -b \tRead/receive buffer size, default is %d\n" +#define HELP_c " -c \t\tParse data from file times\n" +#define HELP_m " -m\t\t\tParse multiple packets from file\n" +#define HELP_n " -n\t\t\tNo rendering, only parsing\n" +#define HELP_q " -q\t\t\tQuiet mode, don't output rendered string\n" +#define HELP_r " -r\t\t\tParse routing header only\n" +#define HELP_S " -S\t\t\tSingle packet mode, close connection after parsing one packet\n" +#define HELP_s " -s\t\t\tShow statistics at the end\n" +#define HELP_v " -v\t\t\tVerbose, can be specified multiple times for more verbosity\n" +#define HELP_P " -P\t\t\tShow progress\n" +#define HELP_h " -h\t\t\tShow this help\n" + void test_init(int i); int test_input(int i, char *recvbuf, size_t nbytes); diff --git a/test/testJson.c b/test/testJson.c new file mode 100644 index 0000000..d1c7e21 --- /dev/null +++ b/test/testJson.c @@ -0,0 +1,113 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "test.c" + +// cmd line args +char *filename, *port = "4441"; +uint8_t verbose, stats; +uint8_t multiple, single, no_render, quiet, progress; +size_t count = 1, recv_buf_size = RECV_BUF_SIZE; + +int exit_code; + +json_object *obj; +json_tokener *tok; +enum json_tokener_error error; + +int main (int argc, char **argv) { + int c; + + while ((c = getopt (argc, argv, "f:p:b:c:mnqsvPSh")) != -1) { + switch (c) { + CASE_f CASE_p CASE_b CASE_c + CASE_m CASE_n CASE_q CASE_s + CASE_v CASE_S CASE_P + case 'h': + printf( + HELP_FILE("testJson", "mnqSsvP") + HELP_PORT("testJson", "nqsvP") + HELP_f HELP_p HELP_b HELP_c + HELP_m HELP_n HELP_q HELP_S + HELP_s HELP_v HELP_P HELP_h, + port, RECV_BUF_SIZE); + exit(0); + case '?': exit(-1); + default: abort(); + } + } + + if (filename) + test_file(filename, count, recv_buf_size); + else + test_server(port, count, recv_buf_size); + + return exit_code; +} + +void test_init (int i) { + tok = json_tokener_new(); +} + +int test_input (int i, char *recvbuf, size_t nbytes) { + size_t cursor = 0; + int r, ret = 0; + + json_tokener_reset(tok); + + do { + obj = json_tokener_parse_ex(tok, recvbuf + cursor, nbytes - cursor); + cursor += tok->char_offset; + + if (verbose) + printf("#%d\n", tok->err); + + switch (tok->err) { + case json_tokener_continue: + return 0; + + case json_tokener_success: + if (!no_render) { + const char *str = json_object_to_json_string(obj); + if (!quiet) { + size_t len = strlen(str); + if (filename) { + r = write(1, str, len); + r = write(1, "\n", 1); + } else { + send(i, str, len, 0); + send(i, "\n", 1, 0); + } + } + } + + json_object_put(obj); + + if (verbose) + printf("# Done parsing.\n"); + else if (progress) + r = write(1, ".", 1); + if ((filename && !multiple) || (!filename && single)) + return -1; + break; + + default: + printf("parse error\n"); + exit_code = tok->err; + return -1; + } + } while (cursor < nbytes); + + return ret; +} diff --git a/test/testJsonGlib.c b/test/testJsonGlib.c new file mode 100644 index 0000000..94e9373 --- /dev/null +++ b/test/testJsonGlib.c @@ -0,0 +1,100 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "test.c" + +// cmd line args +char *filename, *port = "4442"; +uint8_t verbose, stats; +uint8_t no_render, quiet, progress; +size_t count = 1, recv_buf_size = RECV_BUF_SIZE; + +int exit_code; + +JsonParser *parser; +JsonGenerator *generator; + +int main (int argc, char **argv) { + int c; + + while ((c = getopt (argc, argv, "f:p:b:c:nqsvPh")) != -1) { + switch (c) { + CASE_f CASE_p CASE_b + CASE_c CASE_n CASE_q + CASE_s CASE_v CASE_P + case 'h': + printf( + HELP_FILE("testJsonGlib", "mnqSsvP") + HELP_PORT("testJsonGlib", "nqsvP") + HELP_f HELP_p HELP_b HELP_c + HELP_m HELP_n HELP_q HELP_S + HELP_s HELP_v HELP_P HELP_h, + port, RECV_BUF_SIZE); + exit(0); + case '?': exit(-1); + default: abort(); + } + } + + if (filename) + test_file(filename, count, recv_buf_size); + else + test_server(port, count, recv_buf_size); + + return exit_code; +} + +void test_init (int i) { + g_type_init(); + parser = json_parser_new(); + generator = json_generator_new(); +} + +int test_input (int i, char *recvbuf, size_t nbytes) { + JsonNode *root; + GError *error; + char *str; + size_t len; + int r, ret; + + ret = json_parser_load_from_data(parser, recvbuf, nbytes, &error); + + if (!ret) { + printf("Parse error\n"); + exit_code = 1; + return -1; + } + + root = json_parser_get_root(parser); + + if (!no_render) { + json_generator_set_root(generator, root); + str = json_generator_to_data(generator, &len);; + if (!quiet) { + if (filename) { + r = write(1, str, len); + r = write(1, "\n", 1); + } else { + send(i, str, len, 0); + send(i, "\n", 1, 0); + } + } + } + + if (verbose) + printf("# Done parsing.\n"); + else if (progress) + r = write(1, ".", 1); + + return ret; +} diff --git a/test/testPsyc.c b/test/testPsyc.c index f3cbf0f..6b4add0 100644 --- a/test/testPsyc.c +++ b/test/testPsyc.c @@ -313,37 +313,19 @@ inline void resetString (psycString *s, uint8_t freeptr) int main (int argc, char **argv) { int c; - while ((c = getopt (argc, argv, "f:p:b:c:nmqrsvPSh")) != -1) { + while ((c = getopt (argc, argv, "f:p:b:c:mnqrsvPSh")) != -1) { switch (c) { - case 'f': filename = optarg; break; - case 'p': port = optarg; check_range(c, optarg, 1, 0); break; - case 'b': recv_buf_size = atoi(optarg); check_range(c, optarg, 1, RECV_BUF_SIZE); break; - case 'c': count = atoi(optarg); check_range(c, optarg, 1, 0); break; - case 'n': no_render = 1; break; - case 'm': multiple = 1; break; - case 'q': quiet = 1; break; - case 'r': routing_only = 1; break; - case 's': stats = 1; break; - case 'v': verbose++; break; - case 'P': progress = 1; break; - case 'S': single = 1; break; + CASE_f CASE_p CASE_b CASE_c + CASE_m CASE_n CASE_q CASE_r + CASE_s CASE_v CASE_S CASE_P case 'h': printf( - "testPsyc -f [-b ] [-c ] [-mnqrSsvP]\n" - "testPsyc [-p ] [-b ] [-nqrsvP]\n" - " -f \tInput file name\n" - " -p \t\tListen on TCP port, default is %s\n" - " -b \tRead/receive buffer size, default is %d\n" - " -c \t\tParse data from file times\n" - " -m\t\t\tParse multiple packets from file\n" - " -n\t\t\tNo rendering, only parsing\n" - " -r\t\t\tParse routing header only\n" - " -q\t\t\tQuiet mode, don't output rendered string\n" - " -S\t\t\tSingle packet mode, close connection after parsing one packet\n" - " -s\t\t\tShow statistics at the end\n" - " -v\t\t\tVerbose, can be specified multiple times for more verbosity\n" - " -P\t\t\tShow progress\n" - " -h\t\t\tShow this help\n", + HELP_FILE("testPsyc", "mnqrSsvP") + HELP_PORT("testPsyc", "nqrsvP") + HELP_f HELP_p HELP_b HELP_c + HELP_m HELP_n HELP_r + HELP_q HELP_S HELP_s + HELP_v HELP_P HELP_h, port, RECV_BUF_SIZE); exit(0); case '?': exit(-1); diff --git a/test/testPsycFast.c b/test/testPsycFast.c deleted file mode 100644 index 0e1aa28..0000000 --- a/test/testPsycFast.c +++ /dev/null @@ -1,88 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -//#define PSYC_PARSE_INLINE -//#include "../src/parse.c" -#include - -#include "test.c" - -// max size for routing & entity header -#define ROUTING_LINES 16 -#define ENTITY_LINES 32 - -// cmd line args -char *filename, *port = "4440"; -uint8_t verbose, stats; -uint8_t routing_only; -size_t count = 1, recv_buf_size = RECV_BUF_SIZE; - -psycParseState parser; - -void test_init (int i) { - // reset parser state - if (routing_only) - psyc_initParseState2(&parser, PSYC_PARSE_ROUTING_ONLY); - else - psyc_initParseState(&parser); -} - -int test_input (int i, char *recvbuf, size_t nbytes) { - char oper; - psycString name, value; - int ret; - - parser.buffer = (psycString){nbytes, recvbuf}; - parser.cursor = 0; - - for (;;) { - ret = psyc_parse(&parser, &oper, &name, &value); - - if (ret == PSYC_PARSE_COMPLETE || ret < 0) - return -1; - } -} - -int main (int argc, char **argv) { - int c; - while ((c = getopt (argc, argv, "f:p:b:c:qrsvh")) != -1) { - switch (c) { - case 'f': filename = optarg; break; - case 'p': port = optarg; check_range(c, optarg, 1, 0); break; - case 'b': recv_buf_size = atoi(optarg); check_range(c, optarg, 1, RECV_BUF_SIZE); break; - case 'c': count = atoi(optarg); check_range(c, optarg, 1, 0); break; - case 'r': routing_only = 1; break; - case 's': stats = 1; break; - case 'v': verbose++; break; - case 'h': - printf( - "testPsyc -f [-b ] [-c ] [-mnqrSsvP]\n" - "testPsyc [-p ] [-b ] [-nqrsvP]\n" - " -f \tInput file name\n" - " -p \t\tListen on TCP port, default is %s\n" - " -b \tRead/receive buffer size, default is %d\n" - " -c \t\tParse data from file times\n" - " -r\t\t\tParse routing header only\n" - " -s\t\t\tShow statistics at the end\n" - " -h\t\t\tShow this help\n" - " -v\t\t\tVerbose\n", - port, RECV_BUF_SIZE); - exit(0); - case '?': exit(-1); - default: abort(); - } - } - - if (filename) - test_file(filename, count, recv_buf_size); - else - test_server(port, count, recv_buf_size); - - return 0; -} diff --git a/test/testPsycSpeed.c b/test/testPsycSpeed.c new file mode 100644 index 0000000..7baecb5 --- /dev/null +++ b/test/testPsycSpeed.c @@ -0,0 +1,74 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#define __INLINE_PSYC_PARSE +#include "../src/parse.c" +//#include + +#include "test.c" + +// max size for routing & entity header +#define ROUTING_LINES 16 +#define ENTITY_LINES 32 + +// cmd line args +char *filename, *port = "4440"; +uint8_t verbose, stats; +uint8_t routing_only; +size_t count = 1, recv_buf_size = RECV_BUF_SIZE; + +psycParseState parser; + +void test_init (int i) { + if (routing_only) + psyc_initParseState2(&parser, PSYC_PARSE_ROUTING_ONLY); + else + psyc_initParseState(&parser); +} + +int test_input (int i, char *recvbuf, size_t nbytes) { + char oper; + psycString name, value; + int ret; + + psyc_setParseBuffer2(&parser, recvbuf, nbytes); + + for (;;) { + ret = psyc_parse(&parser, &oper, &name, &value); + if (ret == PSYC_PARSE_COMPLETE || ret < 0) + return -1; + } +} + +int main (int argc, char **argv) { + int c; + while ((c = getopt (argc, argv, "f:p:b:c:rsh")) != -1) { + switch (c) { + CASE_f CASE_p CASE_b CASE_c + CASE_r CASE_s + case 'h': + printf( + HELP_FILE("testPsycSpeed", "rs") + HELP_PORT("testPsycSpeed", "rs") + HELP_f HELP_p HELP_b HELP_c + HELP_r HELP_s HELP_h, + port, RECV_BUF_SIZE); + exit(0); + case '?': exit(-1); + default: abort(); + } + } + + if (filename) + test_file(filename, count, recv_buf_size); + else + test_server(port, count, recv_buf_size); + + return 0; +} diff --git a/test/testStrlen.c b/test/testStrlen.c new file mode 100644 index 0000000..6b5785e --- /dev/null +++ b/test/testStrlen.c @@ -0,0 +1,63 @@ +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test.c" + +// cmd line args +char *filename, *port = "4443"; +uint8_t verbose, stats; +uint8_t no_render, quiet, progress; +size_t count = 1, recv_buf_size = RECV_BUF_SIZE; + +int exit_code; + +void test_init (int i) { +} + +int test_input (int i, char *recvbuf, size_t nbytes) { + size_t len = strnlen(recvbuf, nbytes); + + if (!len) { + printf("Empty string\n"); + return -1; + } + + return 0; +} + +int main (int argc, char **argv) { + int c; + + while ((c = getopt (argc, argv, "f:p:b:c:sh")) != -1) { + switch (c) { + CASE_f CASE_p CASE_b CASE_c + CASE_s + case 'h': + printf( + HELP_FILE("testStrlen", "s") + HELP_PORT("testStrlen", "s") + HELP_f HELP_p HELP_b HELP_c + HELP_s HELP_h, + port, RECV_BUF_SIZE); + exit(0); + case '?': exit(-1); + default: abort(); + } + } + + if (filename) + test_file(filename, count, recv_buf_size); + else + test_server(port, count, recv_buf_size); + + return exit_code; +} From 73f3ec2393a7c4c60df288b549db636dbb206545 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 17 May 2011 00:50:46 +0200 Subject: [PATCH 257/378] bench: results table --- bench/results.org | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bench/results.org b/bench/results.org index 48dc2f1..c393254 100644 --- a/bench/results.org +++ b/bench/results.org @@ -5,14 +5,15 @@ Parsing time of 1 000 000 packets in milliseconds: -| | strlen | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml | +| input | PSYC | | JSON | | | XML | | +| parser | strlen | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml | |-----------+--------+---------+--------+-----------+------------+--------+----------| | presence | 30 | 246 | 2463 | 10197 | 4997 | 7557 | 1719 | | chat msg | 41 | 320 | | | 5997 | 9777 | 1893 | | activity | 42 | 366 | 4666 | 16846 | 13357 | 28858 | 4419 | | user prof | 55 | 608 | 4715 | 17468 | 7350 | 12377 | 2477 | |-----------+--------+---------+--------+-----------+------------+--------+----------| -| / | < | < | < | > | < | > | > | +| / | < | > | < | > | < | | > | * Commands used From e89cc6312bbcbf947567076eaceda873d2fffb8d Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 17 May 2011 12:27:07 +0200 Subject: [PATCH 258/378] bench: moved packets to separate files, put results in the main document --- bench/.gitignore | 1 - bench/Makefile | 17 +- bench/benchmark.org | 192 +++++---------------- bench/benchmark.wiki | 269 ------------------------------ bench/packets/activity.json | 3 + bench/packets/activity.psyc | 7 + bench/packets/activity.xml | 27 +++ bench/packets/chat_msg.psyc | 6 + bench/packets/chat_msg.xml | 8 + bench/packets/json-unfriendly.xml | 13 ++ bench/packets/presence.json | 1 + bench/packets/presence.psyc | 5 + bench/packets/presence.xml | 4 + bench/packets/psyc-unfriendly.xml | 12 ++ bench/packets/user_profile.json | 2 + bench/packets/user_profile.psyc | 10 ++ bench/packets/user_profile.xml | 11 ++ bench/packets/xml-unfriendly.xml | 11 ++ bench/results.org | 26 --- 19 files changed, 166 insertions(+), 459 deletions(-) delete mode 100644 bench/benchmark.wiki create mode 100644 bench/packets/activity.json create mode 100644 bench/packets/activity.psyc create mode 100644 bench/packets/activity.xml create mode 100644 bench/packets/chat_msg.psyc create mode 100644 bench/packets/chat_msg.xml create mode 100644 bench/packets/json-unfriendly.xml create mode 100644 bench/packets/presence.json create mode 100644 bench/packets/presence.psyc create mode 100644 bench/packets/presence.xml create mode 100644 bench/packets/psyc-unfriendly.xml create mode 100644 bench/packets/user_profile.json create mode 100644 bench/packets/user_profile.psyc create mode 100644 bench/packets/user_profile.xml create mode 100644 bench/packets/xml-unfriendly.xml delete mode 100644 bench/results.org diff --git a/bench/.gitignore b/bench/.gitignore index f93db6e..23f832b 100644 --- a/bench/.gitignore +++ b/bench/.gitignore @@ -1,3 +1,2 @@ *.html *.pdf -packets/ diff --git a/bench/Makefile b/bench/Makefile index 2aa0ca3..e263ac0 100644 --- a/bench/Makefile +++ b/bench/Makefile @@ -8,22 +8,7 @@ INIT = (setq load-path (cons \"/usr/share/emacs/site-lisp/org-mode\" load-path) org-src-preserve-indentation t) \ (require 'org-install) -ORG = benchmark.org results.org - -wiki2org: - perl -pe '\ - s/^= (.*) =\s*$$/#+TITLE: $$1\n/; \ - s/^== (.*) ==\s*$$/* $$1/; \ - s/^=== (.*) ===\s*$$/** $$1/; \ - s/^{{{/#+BEGIN_SRC/; \ - s/^}}}/#+END_SRC/ \ - ' benchmark.wiki >benchmark.org - -packets: - emacs -Q --batch --eval \ - "(progn ${INIT} (find-file \"benchmark.org\") \ - (org-babel-tangle) (kill-buffer))" - perl -pi -e 'print "\n" unless $$p; $$p=1' packets/user_profile.psyc +ORG = benchmark.org html: for f in ${ORG}; do \ diff --git a/bench/benchmark.org b/bench/benchmark.org index 7532afa..20d1c9c 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -19,30 +19,17 @@ Since presence packets are by far the dominant messaging content in the XMPP network, we'll start with one of them. Here's an example from paragraph 4.4.2 of RFC 6121. -#+BEGIN_SRC xml :tangle packets/presence.xml - - away - -#+END_SRC +#+INCLUDE: packets/presence.xml src xml And here's the same information in a JSON rendition: -#+BEGIN_SRC js :tangle packets/presence.json -["presence",{"from":"juliet@example.com/balcony","to":"benvolio@example.net"},{"show":"away"}] -#+END_SRC +#INCLUDE: packets/presence.json src js Here's the equivalent PSYC packet in verbose form (since it is a multicast, the single recipients do not need to be mentioned): -#+BEGIN_SRC psyc :tangle packets/presence.psyc -:_context psyc://example.com/~juliet - -=_degree_availability 4 -_notice_presence -| -#+END_SRC +#+INCLUDE: packets/presence.psyc src psyc And the same in compact form: @@ -58,133 +45,38 @@ np XML: -#+BEGIN_SRC xml :tangle packets/chat_msg.xml - - Art thou not Romeo, and a Montague? - -#+END_SRC +#+INCLUDE: packets/chat_msg.xml src xml PSYC: -#+BEGIN_SRC psyc :tangle packets/chat_msg.psyc -:_source psyc://example.com/~juliet -:_target psyc://example.net/~romeo - -_message_private -Art thou not Romeo, and a Montague? -| -#+END_SRC +#+INCLUDE: packets/chat_msg.psyc src psyc ** A new status updated activity Example taken from http://onesocialweb.org/spec/1.0/osw-activities.html You could call this XML namespace hell: -#+BEGIN_SRC xml :tangle packets/activity.xml - - - - - - to be or not to be ? - http://activitystrea.ms/schema/1.0/post - - http://onesocialweb.org/spec/1.0/object/status - to be or not to be ? - - - - http://onesocialweb.org/spec/1.0/acl/action/view - - - - - - - - -#+END_SRC +#+INCLUDE: packets/activity.xml src xml http://activitystrea.ms/head/json-activity.html proposes a JSON encoding of this. We'll have to add a routing header to it. -#+BEGIN_SRC js :tangle packets/activity.json -["activity",{"from":"hamlet@denmark.lit/snsclient"},{"verb":"post", -"title":"to be or not to be ?","object":{"type":"status", -"content":"to be or not to be ?","contentType":"text/plain"}}] -#+END_SRC +#+INCLUDE: packets/activity.json src js http://about.psyc.eu/Activity suggests a PSYC mapping for activity streams. Should a "status post" be considered equivalent to a presence description announcement or just a message in the "microblogging" channel? We'll use the latter here: -#+BEGIN_SRC psyc :tangle packets/activity.psyc -:_context psyc://denmark.lit/~hamlet#_follow - -:_subject to be or not to be ? -:_type_content text/plain -_message -to be or not to be ? -| -#+END_SRC +#+INCLUDE: packets/activity.psyc src psyc ** A message with JSON-unfriendly characters -#+BEGIN_SRC xml :tangle packets/json-unfriendly.xml - - "Neither, fair saint, if either thee dislike.", he said. -And -the -rest -is -history. - -#+END_SRC +#+INCLUDE: packets/json-unfriendly.xml src xml ** A message with XML-unfriendly characters -#+BEGIN_SRC xml :tangle packets/xml-unfriendly.xml - - Wherefore art thou, Romeo? - - PročeŽ jsi ty, Romeo? - - -#+END_SRC +#+INCLUDE: packets/xml-unfriendly.xml src xml ** A message with PSYC-unfriendly strings -#+BEGIN_SRC xml :tangle packets/psyc-unfriendly.xml - - I implore you with a pointless -newline in a header variable - Wherefore art thou, Romeo? -| -And for practicing purposes we added a PSYC packet delimiter. - -#+END_SRC +#+INCLUDE: packets/psyc-unfriendly.xml src xml ** A packet containing a JPEG photograph ... TBD ... @@ -194,41 +86,31 @@ In this test we'll not consider XMPP at all and simply compare the efficiency of the three syntaxes at serializing a typical user data base storage information. We'll again start with XML: -#+BEGIN_SRC xml :tangle packets/user_profile.xml - - Silvio Berlusconi - Premier - I -
- Via del Colosseo, 1 - 00100 - Roma -
- http://example.org -
-#+END_SRC +#+INCLUDE: packets/user_profile.xml src xml In JSON this would look like this: -#+BEGIN_SRC js :tangle packets/user_profile.json -["UserProfile",{"Name":"Silvio Berlusconi","JobTitle":"Premier","Country":"I","Address": -{"Street":"Via del Colosseo, 1","PostalCode":"00100","City":"Roma"},"Page":"http://example.org"}] -#+END_SRC +#+INCLUDE: packets/user_profile.json src js Here's a way to model this in PSYC: -#+BEGIN_SRC psyc :tangle packets/user_profile.psyc +#+INCLUDE: packets/user_profile.psyc src psyc -:_name Silvio Berlusconi -:_title_job Premier -:_country I -:_address_street Via del Colosseo, 1 -:_address_code_postal 00100 -:_address_city Roma -:_page http://example.org -_profile_user -| -#+END_SRC +* Results + +Parsing time of 1 000 000 packets in milliseconds: + +| input: | PSYC | | JSON | | | XML | | +| parser: | strlen | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml | +|-----------+--------+---------+--------+-----------+------------+--------+----------| +| presence | 30 | 246 | 2463 | 10197 | 4997 | 7557 | 1719 | +| chat msg | 41 | 320 | | | 5997 | 9777 | 1893 | +| activity | 42 | 366 | 4666 | 16846 | 13357 | 28858 | 4419 | +| user prof | 55 | 608 | 4715 | 17468 | 7350 | 12377 | 2477 | +|-----------+--------+---------+--------+-----------+------------+--------+----------| +| / | < | > | < | > | < | | > | + +These tests were performed on a 2.53 GHz Intel(R) Core(TM)2 Duo P9500 CPU. * Conclusions ... TBD ... @@ -268,3 +150,19 @@ After a month of development libpsyc is already performing pretty well, but we presume various optimizations, like rewriting parts in assembler, are possible. + +* Appendix +** Tools used + +libpsyc: + +: test/testStrlen -sc 1000000 -f $file +: test/testPsycSpeed -sc 1000000 -f $file +: test/testJson -snc 1000000 -f $file +: test/testJsonGlib -snc 1000000 -f $file + +xmlbench: + +: parse/libxml-sax 1000000 $file +: parse/libxml 1000000 $file +: parse/rapidxml 1000000 $file diff --git a/bench/benchmark.wiki b/bench/benchmark.wiki deleted file mode 100644 index 498b76d..0000000 --- a/bench/benchmark.wiki +++ /dev/null @@ -1,269 +0,0 @@ -= libpsyc Performance Benchmarks = - -In this document we present the results of performance benchmarks -of libpsyc compared with libjson-glib and libxml2. - -== Procedure == - -We'll use typical messages from the XMPP ("stanzas" in Jabber -lingo) and compare them with equivalent JSON encodings, -verbose and compact PSYC formats. - -In some cases we will additionally compare PSYC packets to -a more efficient XML encoding based on PSYC methods, to have -a more accurate comparison of the actual PSYC and XML -syntaxes, rather than the protocol structures of PSYC and XMPP. - -== The Benchmarks == - -=== A presence packet === - -Since presence packets are by far the dominant messaging content -in the XMPP network, we'll start with one of them. -Here's an example from paragraph 4.4.2 of RFC 6121. - -{{{ - - away - -}}} - -And here's the same information in a JSON rendition: - -{{{ -["presence",{"from":"juliet@example.com/balcony","to":"benvolio@example.net"},{"show":"away"}] -}}} - -Here's the equivalent PSYC packet in verbose form -(since it is a multicast, the single recipients do not -need to be mentioned): - -{{{ -:_context psyc://example.com/~juliet - -=_degree_availability 4 -_notice_presence -| -}}} - -And the same in compact form: - -{{{ -:c psyc://example.com/~juliet - -=da 4 -np -| -}}} - -=== An average chat message === - -{{{ - - Art thou not Romeo, and a Montague? - -}}} - -=== A new status updated activity === - -Example taken from http://onesocialweb.org/spec/1.0/osw-activities.html -You could call this XML namespace hell: - -{{{ - - - - - - to be or not to be ? - http://activitystrea.ms/schema/1.0/post - - http://onesocialweb.org/spec/1.0/object/status - to be or not to be ? - - - - http://onesocialweb.org/spec/1.0/acl/action/view - - - - - - - - -}}} - -http://activitystrea.ms/head/json-activity.html proposes a JSON encoding -of this. We'll have to add a routing header to it. - -{{{ -["activity",{"from":"hamlet@denmark.lit/snsclient"},{"verb":"post", -"title":"to be or not to be ?","object":{"type":"status", -"content":"to be or not to be ?","contentType":"text/plain"}] -}}} - -http://about.psyc.eu/Activity suggests a PSYC mapping for activity -streams. Should a "status post" be considered equivalent to a presence -description announcement or just a message in the "microblogging" channel? -We'll use the latter here: - -{{{ -:_context psyc://denmark.lit/~hamlet#_follow - -:_subject to be or not to be ? -:_type_content text/plain -_message -to be or not to be ? -| -}}} - -=== A message with JSON-unfriendly characters === - -{{{ - - "Neither, fair saint, if either thee dislike.", he said. -And -the -rest -is -history. - -}}} - -=== A message with XML-unfriendly characters === - -{{{ - - Wherefore art thou, Romeo? - - PročeŽ jsi ty, Romeo? - - -}}} - -=== A message with PSYC-unfriendly strings === - -{{{ - - I implore you with a pointless -newline in a header variable - Wherefore art thou, Romeo? -| -And for practicing purposes we added a PSYC packet delimiter. - -}}} - -=== A packet containing a JPEG photograph === - -... TBD ... - -=== A random data structure === - -In this test we'll not consider XMPP at all and simply compare the -efficiency of the three syntaxes at serializing a typical user data base -storage information. We'll again start with XML: - -{{{ - - Silvio Berlusconi - Premier - I -
- Via del Colosseo, 1 - 00100 - Roma -
- http://example.org -
-}}} - -In JSON this would look like this: - -{{{ -["UserProfile",{"Name":"Silvio Berlusconi","JobTitle":"Premier","Country":"I","Address": -{"Street":"Via del Colosseo, 1","PostalCode":"00100","City":"Roma"},"Page":"http://example.org"}] -}}} - -Here's a way to model this in PSYC: - -{{{ -:_name Silvio Berlusconi -:_title_job Premier -:_country I -:_address_street Via del Colosseo, 1 -:_address_code_postal 00100 -:_address_city Roma -:_page http://example.org -_profile_user -| -}}} - -== Conclusions == - -... TBD ... - -== Criticism == - -Are we comparing apples and oranges? Yes and no, depends on what you -need. XML is a syntax best suited for complex structured data in -well-defined formats - especially good for text mark-up. JSON is a syntax -intended to hold arbitrarily structured data suitable for immediate -inclusion in javascript source codes. The PSYC syntax is an evolved -derivate of RFC 822, the syntax used by HTTP and E-Mail, and is therefore -limited in the kind and depth of data structures that can be represented -with it, but in exchange it is highly performant at doing just that. - -So it is up to you to find out which of the three formats fulfils your -requirements the best. We use PSYC for the majority of messaging where -JSON and XMPP aren't efficient and opaque enough, but we employ XML and -JSON as payloads within PSYC for data that doesn't fit the PSYC model. -For some reason all three formats are being used for messaging, although -only PSYC was actually designed for that purpose. - -== Caveats == - -In every case we'll compare performance of parsing and re-rendering -these messages, but consider also that the applicative processing -of an XML DOM tree is more complicated than just accessing -certain elements in a JSON data structure or PSYC variable -mapping. - -For a speed check in real world conditions which also consider the -complexity of processing incoming messages we should compare -the performance of a chat client using the two protocols, -for instance by using libpurple with XMPP and PSYC accounts. -To this purpose we first need to integrate libpsyc into libpurple. - -== Futures == - -After a month of development libpsyc is already performing pretty -well, but we presume various optimizations, like rewriting parts -in assembler, are possible. - diff --git a/bench/packets/activity.json b/bench/packets/activity.json new file mode 100644 index 0000000..d6e9abc --- /dev/null +++ b/bench/packets/activity.json @@ -0,0 +1,3 @@ +["activity",{"from":"hamlet@denmark.lit/snsclient"},{"verb":"post", +"title":"to be or not to be ?","object":{"type":"status", +"content":"to be or not to be ?","contentType":"text/plain"}}] diff --git a/bench/packets/activity.psyc b/bench/packets/activity.psyc new file mode 100644 index 0000000..bb61c79 --- /dev/null +++ b/bench/packets/activity.psyc @@ -0,0 +1,7 @@ +:_context psyc://denmark.lit/~hamlet#_follow + +:_subject to be or not to be ? +:_type_content text/plain +_message +to be or not to be ? +| diff --git a/bench/packets/activity.xml b/bench/packets/activity.xml new file mode 100644 index 0000000..babdc17 --- /dev/null +++ b/bench/packets/activity.xml @@ -0,0 +1,27 @@ + + + + + + to be or not to be ? + http://activitystrea.ms/schema/1.0/post + + http://onesocialweb.org/spec/1.0/object/status + to be or not to be ? + + + + http://onesocialweb.org/spec/1.0/acl/action/view + + + + + + + + diff --git a/bench/packets/chat_msg.psyc b/bench/packets/chat_msg.psyc new file mode 100644 index 0000000..b39ad33 --- /dev/null +++ b/bench/packets/chat_msg.psyc @@ -0,0 +1,6 @@ +:_source psyc://example.com/~juliet +:_target psyc://example.net/~romeo + +_message_private +Art thou not Romeo, and a Montague? +| diff --git a/bench/packets/chat_msg.xml b/bench/packets/chat_msg.xml new file mode 100644 index 0000000..f7a6b83 --- /dev/null +++ b/bench/packets/chat_msg.xml @@ -0,0 +1,8 @@ + + Art thou not Romeo, and a Montague? + diff --git a/bench/packets/json-unfriendly.xml b/bench/packets/json-unfriendly.xml new file mode 100644 index 0000000..86465cc --- /dev/null +++ b/bench/packets/json-unfriendly.xml @@ -0,0 +1,13 @@ + + "Neither, fair saint, if either thee dislike.", he said. +And +the +rest +is +history. + diff --git a/bench/packets/presence.json b/bench/packets/presence.json new file mode 100644 index 0000000..3260aa3 --- /dev/null +++ b/bench/packets/presence.json @@ -0,0 +1 @@ +["presence",{"from":"juliet@example.com/balcony","to":"benvolio@example.net"},{"show":"away"}] diff --git a/bench/packets/presence.psyc b/bench/packets/presence.psyc new file mode 100644 index 0000000..3eb0bfe --- /dev/null +++ b/bench/packets/presence.psyc @@ -0,0 +1,5 @@ +:_context psyc://example.com/~juliet + +=_degree_availability 4 +_notice_presence +| diff --git a/bench/packets/presence.xml b/bench/packets/presence.xml new file mode 100644 index 0000000..8d074d8 --- /dev/null +++ b/bench/packets/presence.xml @@ -0,0 +1,4 @@ + + away + diff --git a/bench/packets/psyc-unfriendly.xml b/bench/packets/psyc-unfriendly.xml new file mode 100644 index 0000000..3b5d1a6 --- /dev/null +++ b/bench/packets/psyc-unfriendly.xml @@ -0,0 +1,12 @@ + + I implore you with a pointless +newline in a header variable + Wherefore art thou, Romeo? +| +And for practicing purposes we added a PSYC packet delimiter. + diff --git a/bench/packets/user_profile.json b/bench/packets/user_profile.json new file mode 100644 index 0000000..fd69439 --- /dev/null +++ b/bench/packets/user_profile.json @@ -0,0 +1,2 @@ +["UserProfile",{"Name":"Silvio Berlusconi","JobTitle":"Premier","Country":"I","Address": +{"Street":"Via del Colosseo, 1","PostalCode":"00100","City":"Roma"},"Page":"http://example.org"}] diff --git a/bench/packets/user_profile.psyc b/bench/packets/user_profile.psyc new file mode 100644 index 0000000..5b926d0 --- /dev/null +++ b/bench/packets/user_profile.psyc @@ -0,0 +1,10 @@ + +:_name Silvio Berlusconi +:_title_job Premier +:_country I +:_address_street Via del Colosseo, 1 +:_address_code_postal 00100 +:_address_city Roma +:_page http://example.org +_profile_user +| diff --git a/bench/packets/user_profile.xml b/bench/packets/user_profile.xml new file mode 100644 index 0000000..c2d5c18 --- /dev/null +++ b/bench/packets/user_profile.xml @@ -0,0 +1,11 @@ + + Silvio Berlusconi + Premier + I +
+ Via del Colosseo, 1 + 00100 + Roma +
+ http://example.org +
diff --git a/bench/packets/xml-unfriendly.xml b/bench/packets/xml-unfriendly.xml new file mode 100644 index 0000000..e70cb72 --- /dev/null +++ b/bench/packets/xml-unfriendly.xml @@ -0,0 +1,11 @@ + + Wherefore art thou, Romeo? + + PročeŽ jsi ty, Romeo? + + diff --git a/bench/results.org b/bench/results.org deleted file mode 100644 index c393254..0000000 --- a/bench/results.org +++ /dev/null @@ -1,26 +0,0 @@ -#+TITLE: Benchmark results -#+OPTIONS: ^:{} toc:nil - -* Results - -Parsing time of 1 000 000 packets in milliseconds: - -| input | PSYC | | JSON | | | XML | | -| parser | strlen | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml | -|-----------+--------+---------+--------+-----------+------------+--------+----------| -| presence | 30 | 246 | 2463 | 10197 | 4997 | 7557 | 1719 | -| chat msg | 41 | 320 | | | 5997 | 9777 | 1893 | -| activity | 42 | 366 | 4666 | 16846 | 13357 | 28858 | 4419 | -| user prof | 55 | 608 | 4715 | 17468 | 7350 | 12377 | 2477 | -|-----------+--------+---------+--------+-----------+------------+--------+----------| -| / | < | > | < | > | < | | > | - -* Commands used - -: ./testPsycSpeed -sc 1000000 -f $file -: ./testJson -snc 1000000 -f $file -: ./testJsonGlib -snc 1000000 -f $file -: ./testStrlen -sc 1000000 -f $file -: ./rapidxml 1000000 $file -: ./libxml 1000000 $file -: ./libxml-sax 1000000 $file From 43debf5d4bda73238f0813eed52b81871781b53e Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 18 May 2011 20:51:46 +0200 Subject: [PATCH 259/378] + --- bench/benchmark.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bench/benchmark.org b/bench/benchmark.org index 20d1c9c..70e78df 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -23,7 +23,7 @@ Here's an example from paragraph 4.4.2 of RFC 6121. And here's the same information in a JSON rendition: -#INCLUDE: packets/presence.json src js +#+INCLUDE: packets/presence.json src js Here's the equivalent PSYC packet in verbose form (since it is a multicast, the single recipients do not From 8a811c4ee92cb607b4e1dc4fb21a622a6d905db9 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Wed, 18 May 2011 21:59:00 +0200 Subject: [PATCH 260/378] more paketz --- bench/benchmark.org | 17 ++++++++++++++++- bench/packets/chat_msg.json | 2 ++ bench/packets/chat_msg.psyc | 2 +- bench/packets/json-unfriendly.json | 2 ++ bench/packets/json-unfriendly.psyc | 11 +++++++++++ bench/packets/psyc-unfriendly.json | 3 +++ bench/packets/psyc-unfriendly.psyc | 10 ++++++++++ 7 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 bench/packets/chat_msg.json create mode 100644 bench/packets/json-unfriendly.json create mode 100644 bench/packets/json-unfriendly.psyc create mode 100644 bench/packets/psyc-unfriendly.json create mode 100644 bench/packets/psyc-unfriendly.psyc diff --git a/bench/benchmark.org b/bench/benchmark.org index 70e78df..ba3c7d7 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -43,14 +43,25 @@ np ** An average chat message -XML: +XMPP: #+INCLUDE: packets/chat_msg.xml src xml +JSON: + +#+INCLUDE: packets/chat_msg.json src js + PSYC: #+INCLUDE: packets/chat_msg.psyc src psyc +Why PSYC doesn't have an id? Because packet counting from contexts +and circuits is automatic: The packet already has a number just by +being there. + +Also, PSYC by default doesn't mention a "resource" in XMPP terms, +instead it allows for more addressing schemes than just PSYC. + ** A new status updated activity Example taken from http://onesocialweb.org/spec/1.0/osw-activities.html You could call this XML namespace hell: @@ -71,12 +82,16 @@ We'll use the latter here: ** A message with JSON-unfriendly characters #+INCLUDE: packets/json-unfriendly.xml src xml +#+INCLUDE: packets/json-unfriendly.json src js +#+INCLUDE: packets/json-unfriendly.psyc src psyc ** A message with XML-unfriendly characters #+INCLUDE: packets/xml-unfriendly.xml src xml ** A message with PSYC-unfriendly strings #+INCLUDE: packets/psyc-unfriendly.xml src xml +#+INCLUDE: packets/psyc-unfriendly.json src js +#+INCLUDE: packets/psyc-unfriendly.psyc src psyc ** A packet containing a JPEG photograph ... TBD ... diff --git a/bench/packets/chat_msg.json b/bench/packets/chat_msg.json new file mode 100644 index 0000000..6b41aa3 --- /dev/null +++ b/bench/packets/chat_msg.json @@ -0,0 +1,2 @@ +["message",{"from":"juliet@example.com/balcony","to":"romeo@example.net"}, +"Art thou not Romeo, and a Montague?"] diff --git a/bench/packets/chat_msg.psyc b/bench/packets/chat_msg.psyc index b39ad33..51def66 100644 --- a/bench/packets/chat_msg.psyc +++ b/bench/packets/chat_msg.psyc @@ -1,6 +1,6 @@ :_source psyc://example.com/~juliet :_target psyc://example.net/~romeo -_message_private +_message Art thou not Romeo, and a Montague? | diff --git a/bench/packets/json-unfriendly.json b/bench/packets/json-unfriendly.json new file mode 100644 index 0000000..7ce2ba0 --- /dev/null +++ b/bench/packets/json-unfriendly.json @@ -0,0 +1,2 @@ +["message",{"from":"romeo@example.net/orchard","to":"juliet@example.com/balcony"}, +"\"Neither, fair saint, if either thee dislike.\", he said.\nAnd\nthe\nrest\nis\nhistory."] diff --git a/bench/packets/json-unfriendly.psyc b/bench/packets/json-unfriendly.psyc new file mode 100644 index 0000000..7747862 --- /dev/null +++ b/bench/packets/json-unfriendly.psyc @@ -0,0 +1,11 @@ +:_source psyc://example.com/~romeo +:_target psyc://example.net/~juliet + +_message +"Neither, fair saint, if either thee dislike.", he said. +And +the +rest +is +history. +| diff --git a/bench/packets/psyc-unfriendly.json b/bench/packets/psyc-unfriendly.json new file mode 100644 index 0000000..a0eb59c --- /dev/null +++ b/bench/packets/psyc-unfriendly.json @@ -0,0 +1,3 @@ +["message",{"from":"juliet@example.com/balcony',"to":"romeo@example.net", +"subject":"I implore you with a pointless\nnewline in a header variable"}, +"Wherefore art thou, Romeo?\n|\nAnd for practicing purposes we added a PSYC packet delimiter.] diff --git a/bench/packets/psyc-unfriendly.psyc b/bench/packets/psyc-unfriendly.psyc new file mode 100644 index 0000000..514015c --- /dev/null +++ b/bench/packets/psyc-unfriendly.psyc @@ -0,0 +1,10 @@ +:_source psyc://example.com/~juliet +:_target psyc://example.net/~romeo +177 +:_subject 59 I implore you with a pointless +newline in a header variable +_message +Wherefore art thou, Romeo? +| +And for practicing purposes we added a PSYC packet delimiter. +| From de5a8f999971904e7dd10b1a5fbcd1f921367806 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 18 May 2011 22:00:28 +0200 Subject: [PATCH 261/378] test: support for large files; make bench --- Makefile | 3 +++ bench/.gitignore | 1 + test/Makefile | 21 +++++++++++++++ test/test.c | 33 ++++++++++++++++++----- test/test.h | 2 +- test/testJson.c | 62 ++++++++++++++++++++++---------------------- test/testJsonGlib.c | 62 ++++++++++++++++++++++---------------------- test/testPsyc.c | 2 +- test/testPsycSpeed.c | 2 +- test/testStrlen.c | 2 +- 10 files changed, 118 insertions(+), 72 deletions(-) diff --git a/Makefile b/Makefile index 7365ae0..dcf4c6d 100644 --- a/Makefile +++ b/Makefile @@ -30,6 +30,9 @@ testdebug: debug test: all ${MAKE} -C test test nettest +bench: all + ${MAKE} -C test bench + doc: doxygen diff --git a/bench/.gitignore b/bench/.gitignore index 23f832b..bffe52f 100644 --- a/bench/.gitignore +++ b/bench/.gitignore @@ -1,2 +1,3 @@ *.html *.pdf +results/ diff --git a/test/Makefile b/test/Makefile index 934ed1c..4419313 100644 --- a/test/Makefile +++ b/test/Makefile @@ -2,6 +2,7 @@ OPT = -O2 DEBUG = 2 CFLAGS_COMMON = -Wall -std=c99 ${OPT} CFLAGS = -I../include -I../src ${CFLAGS_COMMON} +CFLAGS_TEST = -Wall ${OPT} LDFLAGS = -L../lib LOADLIBES = -lpsyc -lm TARGETS = testPsyc testPsycSpeed testParser testMatch testRender testText isRoutingVar getVarType @@ -11,6 +12,7 @@ DIET = diet PORT = 4440 NC = nc DIFF = diff +TEE = tee ifeq ($(shell uname),SunOS) LOADLIBES_NET := -lsocket -lnsl @@ -20,7 +22,9 @@ endif all: ${TARGETS} it: all +testPsyc: CFLAGS := ${CFLAGS_TEST} testPsyc: LOADLIBES := ${LOADLIBES} ${LOADLIBES_NET} +testPsycSpeed: CFLAGS := ${CFLAGS_TEST} testPsycSpeed: LOADLIBES := ${LOADLIBES} ${LOADLIBES_NET} #testPsycSpeed: LOADLIBES := ${LOADLIBES_NET} @@ -50,6 +54,23 @@ test: ${TARGETS} x=0; for f in packets/[0-9]*; do echo ">> $$f"; ./testPsyc -f $$f | ${DIFF} -u $$f -; x=$$((x+$$?)); done; exit $$x x=0; for f in packets/[0-9]*; do echo ">> $$f"; ./testPsyc -rf $$f | ${DIFF} -u $$f -; x=$$((x+$$?)); done; exit $$x +bench: bench-psyc bench-json bench-xml + +bench-dir: + @mkdir -p ../bench/results + +bench-psyc: bench-dir testStrlen testPsycSpeed + for f in ../bench/packets/*.psyc; do bf=`basename $$f`; echo strlen: $$bf; ./testStrlen -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf.strlen; done + for f in ../bench/packets/*.psyc; do bf=`basename $$f`; echo libpsyc: $$f; ./testPsycSpeed -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf; done + +bench-json: bench-dir testStrlen testJson testJsonGlib + for f in ../bench/packets/*.json; do bf=`basename $$f`; echo strlen: $$bf; ./testStrlen -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf.strlen; done + for f in ../bench/packets/*.json; do bf=`basename $$f`; echo json-c: $$bf; ./testJson -snc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf; done + for f in ../bench/packets/*.json; do bf=`basename $$f`; echo json-glib: $$bf; ./testJsonGlib -snc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf-glib; done + +bench-xml: bench-dir testStrlen + for f in ../bench/packets/*.xml; do bf=`basename $$f`; echo strlen: $$bf; ./testStrlen -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf.strlen; done + .NOTPARALLEL: nettestrun nettest: nettestfull nettestsplit diff --git a/test/test.c b/test/test.c index b11f683..412f7c9 100644 --- a/test/test.c +++ b/test/test.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -50,10 +51,10 @@ void *get_in_addr (struct sockaddr *sa) { } void test_file(const char* filename, size_t count, size_t recv_buf_size) { - char buf[CONT_BUF_SIZE + RECV_BUF_SIZE]; // cont buf + recv buf: [ ccrrrr] - char *recvbuf = buf + CONT_BUF_SIZE; // recv buf: ^^^^ + char *buf, *recvbuf; // cont buf + recv buf: [ ccrrrr] size_t i, nbytes; struct timeval start, end; + struct stat st; int fd = open(filename, O_RDONLY); if (fd < 0) { @@ -61,18 +62,38 @@ void test_file(const char* filename, size_t count, size_t recv_buf_size) { exit(1); } + fstat(fd, &st); + + buf = malloc(CONT_BUF_SIZE + st.st_size); + if (!buf) { + perror("malloc"); + exit(1); + } + recvbuf = buf + CONT_BUF_SIZE; + test_init(0); - if (stats) - gettimeofday(&start, NULL); + if (recv_buf_size) { + if (stats) + gettimeofday(&start, NULL); + + for (i = 0; i < count; i++) + while ((nbytes = read(fd, (void*)recvbuf, recv_buf_size))) + test_input(0, recvbuf, nbytes); + + } else { + nbytes = read(fd, (void*)recvbuf, RECV_BUF_SIZE); + + if (stats) + gettimeofday(&start, NULL); - while ((nbytes = read(fd, (void*)recvbuf, recv_buf_size))) for (i = 0; i < count; i++) test_input(0, recvbuf, nbytes); + } if (stats) { gettimeofday(&end, NULL); - printf("%ld ms\n", (end.tv_sec * 1000000 + end.tv_usec - start.tv_sec * 1000000 - start.tv_usec) / 1000); + printf("%ld\n", (end.tv_sec * 1000000 + end.tv_usec - start.tv_sec * 1000000 - start.tv_usec) / 1000); } } diff --git a/test/test.h b/test/test.h index ee0d1f5..877de82 100644 --- a/test/test.h +++ b/test/test.h @@ -16,7 +16,7 @@ #define CASE_f case 'f': filename = optarg; break; #define CASE_p case 'p': port = optarg; check_range(c, optarg, 1, 0); break; -#define CASE_b case 'b': recv_buf_size = atoi(optarg); check_range(c, optarg, 1, RECV_BUF_SIZE); break; +#define CASE_b case 'b': recv_buf_size = atoi(optarg); check_range(c, optarg, 1, 0); break; #define CASE_c case 'c': count = atoi(optarg); check_range(c, optarg, 1, 0); break; #define CASE_n case 'n': no_render = 1; break; #define CASE_m case 'm': multiple = 1; break; diff --git a/test/testJson.c b/test/testJson.c index d1c7e21..19ccbef 100644 --- a/test/testJson.c +++ b/test/testJson.c @@ -18,7 +18,7 @@ char *filename, *port = "4441"; uint8_t verbose, stats; uint8_t multiple, single, no_render, quiet, progress; -size_t count = 1, recv_buf_size = RECV_BUF_SIZE; +size_t count = 1, recv_buf_size; int exit_code; @@ -26,36 +26,6 @@ json_object *obj; json_tokener *tok; enum json_tokener_error error; -int main (int argc, char **argv) { - int c; - - while ((c = getopt (argc, argv, "f:p:b:c:mnqsvPSh")) != -1) { - switch (c) { - CASE_f CASE_p CASE_b CASE_c - CASE_m CASE_n CASE_q CASE_s - CASE_v CASE_S CASE_P - case 'h': - printf( - HELP_FILE("testJson", "mnqSsvP") - HELP_PORT("testJson", "nqsvP") - HELP_f HELP_p HELP_b HELP_c - HELP_m HELP_n HELP_q HELP_S - HELP_s HELP_v HELP_P HELP_h, - port, RECV_BUF_SIZE); - exit(0); - case '?': exit(-1); - default: abort(); - } - } - - if (filename) - test_file(filename, count, recv_buf_size); - else - test_server(port, count, recv_buf_size); - - return exit_code; -} - void test_init (int i) { tok = json_tokener_new(); } @@ -111,3 +81,33 @@ int test_input (int i, char *recvbuf, size_t nbytes) { return ret; } + +int main (int argc, char **argv) { + int c; + + while ((c = getopt (argc, argv, "f:p:b:c:mnqsvPSh")) != -1) { + switch (c) { + CASE_f CASE_p CASE_b CASE_c + CASE_m CASE_n CASE_q CASE_s + CASE_v CASE_S CASE_P + case 'h': + printf( + HELP_FILE("testJson", "mnqSsvP") + HELP_PORT("testJson", "nqsvP") + HELP_f HELP_p HELP_b HELP_c + HELP_m HELP_n HELP_q HELP_S + HELP_s HELP_v HELP_P HELP_h, + port, RECV_BUF_SIZE); + exit(0); + case '?': exit(-1); + default: abort(); + } + } + + if (filename) + test_file(filename, count, recv_buf_size); + else + test_server(port, count, recv_buf_size); + + return exit_code; +} diff --git a/test/testJsonGlib.c b/test/testJsonGlib.c index 94e9373..91fe9b5 100644 --- a/test/testJsonGlib.c +++ b/test/testJsonGlib.c @@ -17,43 +17,13 @@ char *filename, *port = "4442"; uint8_t verbose, stats; uint8_t no_render, quiet, progress; -size_t count = 1, recv_buf_size = RECV_BUF_SIZE; +size_t count = 1, recv_buf_size; int exit_code; JsonParser *parser; JsonGenerator *generator; -int main (int argc, char **argv) { - int c; - - while ((c = getopt (argc, argv, "f:p:b:c:nqsvPh")) != -1) { - switch (c) { - CASE_f CASE_p CASE_b - CASE_c CASE_n CASE_q - CASE_s CASE_v CASE_P - case 'h': - printf( - HELP_FILE("testJsonGlib", "mnqSsvP") - HELP_PORT("testJsonGlib", "nqsvP") - HELP_f HELP_p HELP_b HELP_c - HELP_m HELP_n HELP_q HELP_S - HELP_s HELP_v HELP_P HELP_h, - port, RECV_BUF_SIZE); - exit(0); - case '?': exit(-1); - default: abort(); - } - } - - if (filename) - test_file(filename, count, recv_buf_size); - else - test_server(port, count, recv_buf_size); - - return exit_code; -} - void test_init (int i) { g_type_init(); parser = json_parser_new(); @@ -98,3 +68,33 @@ int test_input (int i, char *recvbuf, size_t nbytes) { return ret; } + +int main (int argc, char **argv) { + int c; + + while ((c = getopt (argc, argv, "f:p:b:c:nqsvPh")) != -1) { + switch (c) { + CASE_f CASE_p CASE_b + CASE_c CASE_n CASE_q + CASE_s CASE_v CASE_P + case 'h': + printf( + HELP_FILE("testJsonGlib", "mnqSsvP") + HELP_PORT("testJsonGlib", "nqsvP") + HELP_f HELP_p HELP_b HELP_c + HELP_m HELP_n HELP_q HELP_S + HELP_s HELP_v HELP_P HELP_h, + port, RECV_BUF_SIZE); + exit(0); + case '?': exit(-1); + default: abort(); + } + } + + if (filename) + test_file(filename, count, recv_buf_size); + else + test_server(port, count, recv_buf_size); + + return exit_code; +} diff --git a/test/testPsyc.c b/test/testPsyc.c index 6b4add0..7fe6943 100644 --- a/test/testPsyc.c +++ b/test/testPsyc.c @@ -22,7 +22,7 @@ char *filename, *port = "4440"; uint8_t verbose, stats; uint8_t multiple, single, routing_only, no_render, quiet, progress; -size_t count = 1, recv_buf_size = RECV_BUF_SIZE; +size_t count = 1, recv_buf_size; psycParseState parsers[NUM_PARSERS]; psycPacket packets[NUM_PARSERS]; diff --git a/test/testPsycSpeed.c b/test/testPsycSpeed.c index 7baecb5..b17f5d8 100644 --- a/test/testPsycSpeed.c +++ b/test/testPsycSpeed.c @@ -21,7 +21,7 @@ char *filename, *port = "4440"; uint8_t verbose, stats; uint8_t routing_only; -size_t count = 1, recv_buf_size = RECV_BUF_SIZE; +size_t count = 1, recv_buf_size; psycParseState parser; diff --git a/test/testStrlen.c b/test/testStrlen.c index 6b5785e..9bd6866 100644 --- a/test/testStrlen.c +++ b/test/testStrlen.c @@ -16,7 +16,7 @@ char *filename, *port = "4443"; uint8_t verbose, stats; uint8_t no_render, quiet, progress; -size_t count = 1, recv_buf_size = RECV_BUF_SIZE; +size_t count = 1, recv_buf_size; int exit_code; From 9396a0dba8450883dab204585dc228a880f3e186 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 18 May 2011 22:08:30 +0200 Subject: [PATCH 262/378] bench: fixed packet errors --- Makefile | 2 +- bench/packets/psyc-unfriendly.json | 4 ++-- bench/packets/psyc-unfriendly.psyc | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index dcf4c6d..05f4d55 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: doc test +.PHONY: doc test bench all: ${MAKE} -C src diff --git a/bench/packets/psyc-unfriendly.json b/bench/packets/psyc-unfriendly.json index a0eb59c..699b09f 100644 --- a/bench/packets/psyc-unfriendly.json +++ b/bench/packets/psyc-unfriendly.json @@ -1,3 +1,3 @@ -["message",{"from":"juliet@example.com/balcony',"to":"romeo@example.net", +["message",{"from":"juliet@example.com/balcony","to":"romeo@example.net", "subject":"I implore you with a pointless\nnewline in a header variable"}, -"Wherefore art thou, Romeo?\n|\nAnd for practicing purposes we added a PSYC packet delimiter.] +"Wherefore art thou, Romeo?\n|\nAnd for practicing purposes we added a PSYC packet delimiter."] diff --git a/bench/packets/psyc-unfriendly.psyc b/bench/packets/psyc-unfriendly.psyc index 514015c..0defb2b 100644 --- a/bench/packets/psyc-unfriendly.psyc +++ b/bench/packets/psyc-unfriendly.psyc @@ -1,6 +1,6 @@ :_source psyc://example.com/~juliet :_target psyc://example.net/~romeo -177 +173 :_subject 59 I implore you with a pointless newline in a header variable _message From 52c9159b2ec0641bf9397d47550f5555381f35e1 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 20 May 2011 02:53:56 +0200 Subject: [PATCH 263/378] test tool fixes --- test/Makefile | 8 ++------ test/test.c | 7 ++++--- test/testPsyc.c | 3 ++- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/test/Makefile b/test/Makefile index 4419313..66c2445 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,8 +1,6 @@ OPT = -O2 DEBUG = 2 -CFLAGS_COMMON = -Wall -std=c99 ${OPT} -CFLAGS = -I../include -I../src ${CFLAGS_COMMON} -CFLAGS_TEST = -Wall ${OPT} +CFLAGS = -I../include -I../src -Wall -std=c99 ${OPT} LDFLAGS = -L../lib LOADLIBES = -lpsyc -lm TARGETS = testPsyc testPsycSpeed testParser testMatch testRender testText isRoutingVar getVarType @@ -22,15 +20,13 @@ endif all: ${TARGETS} it: all -testPsyc: CFLAGS := ${CFLAGS_TEST} testPsyc: LOADLIBES := ${LOADLIBES} ${LOADLIBES_NET} -testPsycSpeed: CFLAGS := ${CFLAGS_TEST} testPsycSpeed: LOADLIBES := ${LOADLIBES} ${LOADLIBES_NET} #testPsycSpeed: LOADLIBES := ${LOADLIBES_NET} testJson: LOADLIBES := ${LOADLIBES_NET} -ljson -testJsonGlib: CFLAGS = ${CFLAGS_COMMON} -I/usr/include/json-glib-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include +testJsonGlib: CFLAGS := ${CFLAGS} -I/usr/include/json-glib-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include testJsonGlib: LOADLIBES := ${LOADLIBES_NET} -ljson-glib-1.0 testStrlen: LOADLIBES := ${LOADLIBES_NET} diff --git a/test/test.c b/test/test.c index 412f7c9..6c30028 100644 --- a/test/test.c +++ b/test/test.c @@ -52,7 +52,7 @@ void *get_in_addr (struct sockaddr *sa) { void test_file(const char* filename, size_t count, size_t recv_buf_size) { char *buf, *recvbuf; // cont buf + recv buf: [ ccrrrr] - size_t i, nbytes; + size_t i, nbytes, size = 0; struct timeval start, end; struct stat st; @@ -82,13 +82,14 @@ void test_file(const char* filename, size_t count, size_t recv_buf_size) { test_input(0, recvbuf, nbytes); } else { - nbytes = read(fd, (void*)recvbuf, RECV_BUF_SIZE); + while ((nbytes = read(fd, (void*)recvbuf + size, RECV_BUF_SIZE))) + size += nbytes; if (stats) gettimeofday(&start, NULL); for (i = 0; i < count; i++) - test_input(0, recvbuf, nbytes); + test_input(0, recvbuf, size); } if (stats) { diff --git a/test/testPsyc.c b/test/testPsyc.c index 7fe6943..087beaf 100644 --- a/test/testPsyc.c +++ b/test/testPsyc.c @@ -302,7 +302,8 @@ int test_input (int i, char *recvbuf, size_t nbytes) { return ret; } -inline void resetString (psycString *s, uint8_t freeptr) +static inline +void resetString (psycString *s, uint8_t freeptr) { if (freeptr && s->length) free((void*)s->ptr); From 653fbcc15642b54764b2c0bc24cebbd02b3b7361 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 20 May 2011 02:58:32 +0200 Subject: [PATCH 264/378] number, date & time parsing functions; psycString variant for isRoutingVar & getVarType --- include/psyc.h | 33 ++++++++++++++++--------- include/psyc/parse.h | 59 ++++++++++++++++++++++++++++++++++++++++++++ src/variable.c | 16 ++++++++++-- test/getVarType.c | 20 +++++++-------- test/isRoutingVar.c | 18 +++++++------- 5 files changed, 113 insertions(+), 33 deletions(-) diff --git a/include/psyc.h b/include/psyc.h index 2847bfa..abcf9d3 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -18,6 +18,7 @@ #include #include +#include #define PSYC_EPOCH 1440444041 // 2015-08-24 21:20:41 CET (Monday) @@ -124,24 +125,22 @@ extern const psycString PSYC_routingVars[]; extern const psycMatchVar PSYC_varTypes[]; /** - * Get the type of variable name. + * Is this a routing variable name? */ -psycBool psyc_isRoutingVar(const char *name, size_t len); +psycBool psyc_isRoutingVar(psycString *name); +/** + * Is this a routing variable name? + */ +psycBool psyc_isRoutingVar2(const char *name, size_t len); /** * Get the type of variable name. */ -psycType psyc_getVarType(const char *name, size_t len); - +psycType psyc_getVarType(psycString *name); /** - * Is this a list variable name? + * Get the type of variable name. */ -static inline -psycBool psyc_isListVar(psycString *name) -{ - return name->length < 5 || memcmp(name->ptr, "_list", 5) != 0 || - (name->length > 5 && name->ptr[5] != '_') ? PSYC_FALSE : PSYC_TRUE; -} +psycType psyc_getVarType2(const char *name, size_t len); /** * Is this a list variable name? @@ -149,7 +148,17 @@ psycBool psyc_isListVar(psycString *name) static inline psycBool psyc_isListVar2(const char *name, size_t len) { - return psyc_isListVar(&(psycString){len, name}); + return len < 5 || memcmp(name, "_list", 5) != 0 || + (len > 5 && name[5] != '_') ? PSYC_FALSE : PSYC_TRUE; +} + +/** + * Is this a list variable name? + */ +static inline +psycBool psyc_isListVar(psycString *name) +{ + return psyc_isListVar2(name->ptr, name->length); } /** diff --git a/include/psyc/parse.h b/include/psyc/parse.h index 0f2332c..1b6ef6a 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -451,6 +451,65 @@ static inline #endif psycParseListRC psyc_parseList (psycParseListState *state, psycString *elem); +static inline +psycBool psyc_parseNumber2 (const char *value, size_t len, ssize_t *n) +{ + size_t c = 0; + uint8_t neg = 0; + + if (!value) + return PSYC_FALSE; + + if (value[0] == '-') + neg = ++c; + + *n = 0; + while (c < len && value[c] >= '0' && value[c] <= '9') + *n = 10 * *n + (value[c++] - '0'); + + if (c != len) + return PSYC_FALSE; + + if (neg) + *n = 0 - *n; + + return PSYC_TRUE; +} + +static inline +psycBool psyc_parseNumber (psycString *value, ssize_t *n) +{ + return psyc_parseNumber2(value->ptr, value->length, n); +} + +static inline +psycBool psyc_parseTime2 (const char *value, size_t len, time_t *t) +{ + return psyc_parseNumber2(value, len, t); +} + +static inline +psycBool psyc_parseTime (psycString *value, time_t *t) +{ + return psyc_parseNumber2(value->ptr, value->length, t); +} + +static inline +psycBool psyc_parseDate2 (const char *value, size_t len, time_t *t) +{ + if (psyc_parseNumber2(value, len, t)) { + *t += PSYC_EPOCH; + return PSYC_TRUE; + } + return PSYC_FALSE; +} + +static inline +psycBool psyc_parseDate (psycString *value, time_t *t) +{ + return psyc_parseDate2(value->ptr, value->length, t); +} + /** @} */ // end of parse group #define PSYC_PARSE_H diff --git a/src/variable.c b/src/variable.c index a1e4845..e9c96d7 100644 --- a/src/variable.c +++ b/src/variable.c @@ -48,7 +48,8 @@ const size_t psyc_varTypesNum = PSYC_NUM_ELEM(psyc_varTypes); /** * Get the type of variable name. */ -psycBool psyc_isRoutingVar(const char *name, size_t len) +inline +psycBool psyc_isRoutingVar2(const char *name, size_t len) { //return psyc_matchArray(psyc_routingVars, PSYC_NUM_ELEM(psyc_routingVars), name, len, 0); size_t cursor = 1; @@ -86,10 +87,16 @@ psycBool psyc_isRoutingVar(const char *name, size_t len) return matching[0] >= 0 ? PSYC_TRUE : PSYC_FALSE; } +psycBool psyc_isRoutingVar(psycString *name) +{ + return psyc_isRoutingVar2(name->ptr, name->length); +} + /** * Get the type of variable name. */ -psycType psyc_getVarType(const char *name, size_t len) +inline +psycType psyc_getVarType2(const char *name, size_t len) { //return psyc_matchArray(psyc_varTypes, PSYC_NUM_ELEM(psyc_varTypes), name, len, 1); size_t cursor = 1; @@ -129,3 +136,8 @@ psycType psyc_getVarType(const char *name, size_t len) // return first match if found return matching[0] >= 0 ? psyc_varTypes[matching[0]].value : 0; } + +psycType psyc_getVarType(psycString *name) +{ + return psyc_getVarType2(name->ptr, name->length); +} diff --git a/test/getVarType.c b/test/getVarType.c index d0fd152..de7f9e0 100644 --- a/test/getVarType.c +++ b/test/getVarType.c @@ -5,16 +5,16 @@ #include int main() { - unless (psyc_getVarType(PSYC_C2ARG("_list"))) return 1; - unless (psyc_getVarType(PSYC_C2ARG("_list_foo"))) return 2; - unless (psyc_getVarType(PSYC_C2ARG("_color_red"))) return 3; - if (psyc_getVarType(PSYC_C2ARG("_last"))) return 4; - if (psyc_getVarType(PSYC_C2ARG("_lost_foo"))) return 5; - if (psyc_getVarType(PSYC_C2ARG("_colorful"))) return 6; - if (psyc_getVarType(PSYC_C2ARG("_foo"))) return 7; - if (psyc_getVarType(PSYC_C2ARG("bar"))) return 8; - if (psyc_getVarType(PSYC_C2ARG("______"))) return 9; - if (psyc_getVarType(PSYC_C2ARG("_"))) return 10; + unless (psyc_getVarType2(PSYC_C2ARG("_list"))) return 1; + unless (psyc_getVarType2(PSYC_C2ARG("_list_foo"))) return 2; + unless (psyc_getVarType2(PSYC_C2ARG("_color_red"))) return 3; + if (psyc_getVarType2(PSYC_C2ARG("_last"))) return 4; + if (psyc_getVarType2(PSYC_C2ARG("_lost_foo"))) return 5; + if (psyc_getVarType2(PSYC_C2ARG("_colorful"))) return 6; + if (psyc_getVarType2(PSYC_C2ARG("_foo"))) return 7; + if (psyc_getVarType2(PSYC_C2ARG("bar"))) return 8; + if (psyc_getVarType2(PSYC_C2ARG("______"))) return 9; + if (psyc_getVarType2(PSYC_C2ARG("_"))) return 10; puts("psyc_getVarType passed all tests."); return 0; // passed all tests diff --git a/test/isRoutingVar.c b/test/isRoutingVar.c index 9c31685..4b6e431 100644 --- a/test/isRoutingVar.c +++ b/test/isRoutingVar.c @@ -21,17 +21,17 @@ int main() { for (i = 0; i < sizeof(vars) / sizeof(*vars); i++) { printf(">> %s: %d %d\n", vars[i], sizeof(vars[i]), sizeof(*vars[i])); - printf("%s: %d\n", vars[i], psyc_isRoutingVar(vars[i], strlen(vars[i]))); + printf("%s: %d\n", vars[i], psyc_isRoutingVar2(vars[i], strlen(vars[i]))); } #else - unless (psyc_isRoutingVar(PSYC_C2ARG("_source"))) return 1; - unless (psyc_isRoutingVar(PSYC_C2ARG("_source_relay"))) return 2; - if (psyc_isRoutingVar(PSYC_C2ARG("_source_foo"))) return 3; - if (psyc_isRoutingVar(PSYC_C2ARG("_sourcherry"))) return 4; - if (psyc_isRoutingVar(PSYC_C2ARG("_sour"))) return 5; - if (psyc_isRoutingVar(PSYC_C2ARG("_foo"))) return 6; - if (psyc_isRoutingVar(PSYC_C2ARG("bar"))) return 7; - if (psyc_isRoutingVar(PSYC_C2ARG("_"))) return 8; + unless (psyc_isRoutingVar2(PSYC_C2ARG("_source"))) return 1; + unless (psyc_isRoutingVar2(PSYC_C2ARG("_source_relay"))) return 2; + if (psyc_isRoutingVar2(PSYC_C2ARG("_source_foo"))) return 3; + if (psyc_isRoutingVar2(PSYC_C2ARG("_sourcherry"))) return 4; + if (psyc_isRoutingVar2(PSYC_C2ARG("_sour"))) return 5; + if (psyc_isRoutingVar2(PSYC_C2ARG("_foo"))) return 6; + if (psyc_isRoutingVar2(PSYC_C2ARG("bar"))) return 7; + if (psyc_isRoutingVar2(PSYC_C2ARG("_"))) return 8; puts("psyc_isRoutingVar passed all tests."); #endif From 773a94788e3ce6d6d7a922087ea6fd6043906201 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 23 May 2011 02:03:34 +0200 Subject: [PATCH 265/378] fix for routingVars & varTypes declaration --- include/psyc.h | 11 ++++++++--- src/variable.c | 3 ++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/include/psyc.h b/include/psyc.h index abcf9d3..b33e96a 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -120,9 +120,14 @@ unsigned int psyc_version () return 1; } -/// Routing vars in alphabetical order. -extern const psycString PSYC_routingVars[]; -extern const psycMatchVar PSYC_varTypes[]; +/// Routing variables in alphabetical order. +extern const psycString psyc_routingVars[]; + +// Variable types in alphabetical order. +extern const psycMatchVar psyc_varTypes[]; + +extern const size_t psyc_routingVarsNum; +extern const size_t psyc_varTypesNum; /** * Is this a routing variable name? diff --git a/src/variable.c b/src/variable.c index e9c96d7..472e105 100644 --- a/src/variable.c +++ b/src/variable.c @@ -1,8 +1,8 @@ #include "lib.h" #include -/// Routing variables in alphabetical order. +/// Routing variables in alphabetical order. const psycString psyc_routingVars[] = { PSYC_C2STR("_amount_fragments"), @@ -26,6 +26,7 @@ const psycString psyc_routingVars[] = //PSYC_C2STR("_using_modules"), // older PSYC }; +// Variable types in alphabetical order. const psycMatchVar psyc_varTypes[] = { {PSYC_C2STR("_amount"), PSYC_TYPE_AMOUNT}, From 8f95311cf1276ce63d6e7851f2ceac6cbe2bacb6 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Mon, 23 May 2011 09:14:45 +0200 Subject: [PATCH 266/378] We need more XMPP-free comparisons --- bench/benchmark.org | 109 +++++++++++++++++++++++++++----------------- 1 file changed, 68 insertions(+), 41 deletions(-) diff --git a/bench/benchmark.org b/bench/benchmark.org index ba3c7d7..6f9faab 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -3,17 +3,67 @@ In this document we present the results of performance benchmarks of libpsyc compared with libjson-glib and libxml2. -* Procedure -We'll use typical messages from the XMPP ("stanzas" in Jabber -lingo) and compare them with equivalent JSON encodings, +* PSYC, JSON, XML Syntax Benchmarks +First we look at the mere performance of the PSYC syntax +compared to equivalent XML and JSON encodings. We'll +look at actual XMPP messaging later. + +** User Profile +In this test we'll compare the efficiency of the three +syntaxes at serializing a typical user data base +storage information. Let's start with XML: + +#+INCLUDE: packets/user_profile.xml src xml + +In JSON this could look like this: + +#+INCLUDE: packets/user_profile.json src js + +Here's a way to model this in PSYC: + +#+INCLUDE: packets/user_profile.psyc src psyc + +** A message with JSON-unfriendly characters +This message contains some characters which are +impractical to encode in JSON. Let's see how much +performance impact this has. + +#+INCLUDE: packets/json-unfriendly.xml src xml +#+INCLUDE: packets/json-unfriendly.json src js +#+INCLUDE: packets/json-unfriendly.psyc src psyc + +** A message with XML-unfriendly characters +Same test with characters which aren't practical +in the XML syntax. + +#+INCLUDE: packets/xml-unfriendly.xml src xml + +** A message with PSYC-unfriendly strings +PSYC prefixes data with length as soon as it +exceeds certain sizes or contains certain strings. +In the case of short messages this is less +efficient than scanning the values without lengths. +Also, lengths are harder to edit by hand. + +#+INCLUDE: packets/psyc-unfriendly.xml src xml +#+INCLUDE: packets/psyc-unfriendly.json src js +#+INCLUDE: packets/psyc-unfriendly.psyc src psyc + +** Packets containing binary data +We'll use a generator of random binary data to +see how well the formats behave with different +sizes of data. We'll consider 7000 as a possible +size of an icon, 70000 for an avatar, 700000 +for a photograph, 7000000 for a piece of music, +70000000 for a large project and +700000000 for the contents of a CD. + +* PSYC vs XMPP Protocol Benchmarks + +These tests use typical messages from the XMPP ("stanzas" in +Jabber lingo) and compare them with equivalent JSON encodings, verbose and compact PSYC formats. -In some cases we will additionally compare PSYC packets to -a more efficient XML encoding based on PSYC methods, to have -a more accurate comparison of the actual PSYC and XML -syntaxes, rather than the protocol structures of PSYC and XMPP. - -* The Benchmarks ** A presence packet Since presence packets are by far the dominant messaging content in the XMPP network, we'll start with one of them. @@ -80,37 +130,6 @@ We'll use the latter here: #+INCLUDE: packets/activity.psyc src psyc -** A message with JSON-unfriendly characters -#+INCLUDE: packets/json-unfriendly.xml src xml -#+INCLUDE: packets/json-unfriendly.json src js -#+INCLUDE: packets/json-unfriendly.psyc src psyc - -** A message with XML-unfriendly characters -#+INCLUDE: packets/xml-unfriendly.xml src xml - -** A message with PSYC-unfriendly strings -#+INCLUDE: packets/psyc-unfriendly.xml src xml -#+INCLUDE: packets/psyc-unfriendly.json src js -#+INCLUDE: packets/psyc-unfriendly.psyc src psyc - -** A packet containing a JPEG photograph -... TBD ... - -** A random data structure -In this test we'll not consider XMPP at all and simply compare the -efficiency of the three syntaxes at serializing a typical user data base -storage information. We'll again start with XML: - -#+INCLUDE: packets/user_profile.xml src xml - -In JSON this would look like this: - -#+INCLUDE: packets/user_profile.json src js - -Here's a way to model this in PSYC: - -#+INCLUDE: packets/user_profile.psyc src psyc - * Results Parsing time of 1 000 000 packets in milliseconds: @@ -118,10 +137,18 @@ Parsing time of 1 000 000 packets in milliseconds: | input: | PSYC | | JSON | | | XML | | | parser: | strlen | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml | |-----------+--------+---------+--------+-----------+------------+--------+----------| +| user prof | 55 | 608 | 4715 | 17468 | 7350 | 12377 | 2477 | +|-----------+--------+---------+--------+-----------+------------+--------+----------| +| / | < | > | < | > | < | | > | + +Pure syntax comparisons above, protocol performance comparisons below: + +| input: | PSYC | | JSON | | | XMPP | | +| parser: | strlen | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml | +|-----------+--------+---------+--------+-----------+------------+--------+----------| | presence | 30 | 246 | 2463 | 10197 | 4997 | 7557 | 1719 | | chat msg | 41 | 320 | | | 5997 | 9777 | 1893 | | activity | 42 | 366 | 4666 | 16846 | 13357 | 28858 | 4419 | -| user prof | 55 | 608 | 4715 | 17468 | 7350 | 12377 | 2477 | |-----------+--------+---------+--------+-----------+------------+--------+----------| | / | < | > | < | > | < | | > | From 42b1059fa6e988495d1e883bb0de646a414f2f35 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Mon, 23 May 2011 16:08:26 +0200 Subject: [PATCH 267/378] xml-unfriendly complete --- bench/benchmark.org | 27 +++++++++++++++++---------- bench/packets/json-unfriendly.xml | 9 ++------- bench/packets/psyc-unfriendly.xml | 11 +++-------- bench/packets/xml-unfriendly.json | 3 +++ bench/packets/xml-unfriendly.psyc | 6 ++++++ bench/packets/xml-unfriendly.xml | 12 ++---------- 6 files changed, 33 insertions(+), 35 deletions(-) create mode 100644 bench/packets/xml-unfriendly.json create mode 100644 bench/packets/xml-unfriendly.psyc diff --git a/bench/benchmark.org b/bench/benchmark.org index 6f9faab..b5d6ba2 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -37,6 +37,8 @@ Same test with characters which aren't practical in the XML syntax. #+INCLUDE: packets/xml-unfriendly.xml src xml +#+INCLUDE: packets/xml-unfriendly.json src js +#+INCLUDE: packets/xml-unfriendly.psyc src psyc ** A message with PSYC-unfriendly strings PSYC prefixes data with length as soon as it @@ -93,16 +95,8 @@ np ** An average chat message -XMPP: - #+INCLUDE: packets/chat_msg.xml src xml - -JSON: - #+INCLUDE: packets/chat_msg.json src js - -PSYC: - #+INCLUDE: packets/chat_msg.psyc src psyc Why PSYC doesn't have an id? Because packet counting from contexts @@ -155,7 +149,19 @@ Pure syntax comparisons above, protocol performance comparisons below: These tests were performed on a 2.53 GHz Intel(R) Core(TM)2 Duo P9500 CPU. * Conclusions -... TBD ... + +The Internet has developed two major breeds of protocol formats. +The binary ones are extremely efficient but usually not very flexible +while the plain-text ones are reaching out for achieving perfection +in data representation while leaving the path of efficiency. Some +protocols such as HTTP and SIP are in-between these two schools, +offering both a text-based extensible syntax (it's actually easier to +add a header to HTTP than to come up with a namespace for XMPP...) +and the ability to deliver binary data. But these protocols do not +come with native data structure support. PSYC is a protocol that +combines the compactness and efficiency of binary protocols with the +extensibility of text-based protocols and still provides for enough +data structuring to rarely require the use of other data formats. * Criticism Are we comparing apples and oranges? Yes and no, depends on what you @@ -192,7 +198,6 @@ After a month of development libpsyc is already performing pretty well, but we presume various optimizations, like rewriting parts in assembler, are possible. - * Appendix ** Tools used @@ -208,3 +213,5 @@ xmlbench: : parse/libxml-sax 1000000 $file : parse/libxml 1000000 $file : parse/rapidxml 1000000 $file + +See also "make bench" diff --git a/bench/packets/json-unfriendly.xml b/bench/packets/json-unfriendly.xml index 86465cc..591cb9f 100644 --- a/bench/packets/json-unfriendly.xml +++ b/bench/packets/json-unfriendly.xml @@ -1,10 +1,5 @@ - - "Neither, fair saint, if either thee dislike.", he said. + +"Neither, fair saint, if either thee dislike.", he said. And the rest diff --git a/bench/packets/psyc-unfriendly.xml b/bench/packets/psyc-unfriendly.xml index 3b5d1a6..05743e8 100644 --- a/bench/packets/psyc-unfriendly.xml +++ b/bench/packets/psyc-unfriendly.xml @@ -1,12 +1,7 @@ - - I implore you with a pointless + +I implore you with a pointless newline in a header variable - Wherefore art thou, Romeo? +Wherefore art thou, Romeo? | And for practicing purposes we added a PSYC packet delimiter. diff --git a/bench/packets/xml-unfriendly.json b/bench/packets/xml-unfriendly.json new file mode 100644 index 0000000..8b137d5 --- /dev/null +++ b/bench/packets/xml-unfriendly.json @@ -0,0 +1,3 @@ + +["message",{"from":"juliet@example.com/balcony","to":"romeo@example.net"}, +"Pro\x010De\x017D jsi ty, Romeo?"] diff --git a/bench/packets/xml-unfriendly.psyc b/bench/packets/xml-unfriendly.psyc new file mode 100644 index 0000000..21f4364 --- /dev/null +++ b/bench/packets/xml-unfriendly.psyc @@ -0,0 +1,6 @@ +:_source psyc://example.com/~juliet +:_target psyc://example.net/~romeo + +_message + PročeŽ jsi ty, Romeo? +| diff --git a/bench/packets/xml-unfriendly.xml b/bench/packets/xml-unfriendly.xml index e70cb72..207f3e2 100644 --- a/bench/packets/xml-unfriendly.xml +++ b/bench/packets/xml-unfriendly.xml @@ -1,11 +1,3 @@ - - Wherefore art thou, Romeo? - - PročeŽ jsi ty, Romeo? - + +PročeŽ jsi ty, Romeo? From 34c88b5ff43457972eff7e2d936568043eea05d6 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Mon, 23 May 2011 16:17:10 +0200 Subject: [PATCH 268/378] + --- bench/packets/xml-unfriendly.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bench/packets/xml-unfriendly.json b/bench/packets/xml-unfriendly.json index 8b137d5..34800b5 100644 --- a/bench/packets/xml-unfriendly.json +++ b/bench/packets/xml-unfriendly.json @@ -1,3 +1,2 @@ - ["message",{"from":"juliet@example.com/balcony","to":"romeo@example.net"}, -"Pro\x010De\x017D jsi ty, Romeo?"] +"Pro\u010de\u017d jsi ty, Romeo?"] From a6c2c56dbb2d561a38950554837aea639649de61 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Mon, 23 May 2011 16:52:44 +0200 Subject: [PATCH 269/378] related work added --- bench/benchmark.org | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/bench/benchmark.org b/bench/benchmark.org index b5d6ba2..283c081 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -164,6 +164,7 @@ extensibility of text-based protocols and still provides for enough data structuring to rarely require the use of other data formats. * Criticism + Are we comparing apples and oranges? Yes and no, depends on what you need. XML is a syntax best suited for complex structured data in well-defined formats - especially good for text mark-up. JSON is a syntax @@ -173,14 +174,23 @@ derivate of RFC 822, the syntax used by HTTP and E-Mail, and is therefore limited in the kind and depth of data structures that can be represented with it, but in exchange it is highly performant at doing just that. -So it is up to you to find out which of the three formats fulfils your +So it is up to you to find out which format fulfils your requirements the best. We use PSYC for the majority of messaging where JSON and XMPP aren't efficient and opaque enough, but we employ XML and JSON as payloads within PSYC for data that doesn't fit the PSYC model. For some reason all three formats are being used for messaging, although only PSYC was actually designed for that purpose. +Another aspect is the availability of these formats for spontaneous +use. You could generate and parse JSON yourself but you have to be +careful about escaping. XML can be rendered manually if you know your +data will not break the syntax, but you can't really parse it without +a bullet proof parser. PSYC is easy to render and parse yourself for +simple tasks, as long as your body does not contain "\n|\n" and your +variables do not contain newlines. + * Caveats + In every case we'll compare performance of parsing and re-rendering these messages, but consider also that the applicative processing of an XML DOM tree is more complicated than just accessing @@ -194,10 +204,27 @@ for instance by using libpurple with XMPP and PSYC accounts. To this purpose we first need to integrate libpsyc into libpurple. * Futures + After a month of development libpsyc is already performing pretty well, but we presume various optimizations, like rewriting parts in assembler, are possible. +* Related Work + +If this didn't help, you can also look into: + +** Adobe AMF +** ASN.1 +** BSON +** Cisco Etch +** Facebook Thrift +** Google Protocol Buffers + +The drawback of these binary formats is, unlike PSYC, JSON and XML +you can't edit them manually and you can't produce valid messages +by replacing variables in a simple text template. You depend on +specialized parsers and renderers to be provided. + * Appendix ** Tools used From a4abbfbab17438e67a9b8e0823256ebf14b86a3e Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Mon, 23 May 2011 17:10:11 +0200 Subject: [PATCH 270/378] + --- bench/benchmark.org | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bench/benchmark.org b/bench/benchmark.org index 283c081..38ff07a 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -152,6 +152,8 @@ These tests were performed on a 2.53 GHz Intel(R) Core(TM)2 Duo P9500 CPU. The Internet has developed two major breeds of protocol formats. The binary ones are extremely efficient but usually not very flexible +(unless you are willing to recompile all instances each time you +change something) while the plain-text ones are reaching out for achieving perfection in data representation while leaving the path of efficiency. Some protocols such as HTTP and SIP are in-between these two schools, @@ -217,6 +219,7 @@ If this didn't help, you can also look into: ** ASN.1 ** BSON ** Cisco Etch +** Efficient XML ** Facebook Thrift ** Google Protocol Buffers From 4baeb20e9d4a59a454d3790de06ef4afa64c0c5b Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 23 May 2011 17:15:01 +0200 Subject: [PATCH 271/378] + --- bench/benchmark.org | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/bench/benchmark.org b/bench/benchmark.org index 38ff07a..c11ed24 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -215,13 +215,13 @@ in assembler, are possible. If this didn't help, you can also look into: -** Adobe AMF -** ASN.1 -** BSON -** Cisco Etch -** Efficient XML -** Facebook Thrift -** Google Protocol Buffers +- Adobe AMF +- ASN.1 +- BSON +- Cisco Etch +- Efficient XML +- Facebook Thrift +- Google Protocol Buffers The drawback of these binary formats is, unlike PSYC, JSON and XML you can't edit them manually and you can't produce valid messages From 6dca44b64d21bde544d8df770a0449bc88aec92a Mon Sep 17 00:00:00 2001 From: PSYC Date: Mon, 23 May 2011 19:12:27 +0200 Subject: [PATCH 272/378] declaration of 'strlen' shadows a global declaration --- bench/benchmark.org | 3 ++- include/psyc.h | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/bench/benchmark.org b/bench/benchmark.org index 38ff07a..c30705f 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -126,7 +126,8 @@ We'll use the latter here: * Results -Parsing time of 1 000 000 packets in milliseconds: +Parsing time of 1 000 000 packets, in milliseconds. +a simple strlen scan of the respective message is provided for comparison. | input: | PSYC | | JSON | | | XML | | | parser: | strlen | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml | diff --git a/include/psyc.h b/include/psyc.h index b33e96a..6146665 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -108,9 +108,9 @@ typedef struct * @return An instance of the psycString struct. */ static inline -psycString psyc_newString (const char *str, size_t strlen) +psycString psyc_newString (const char *str, size_t slen) { - psycString s = {strlen, str}; + psycString s = {slen, str}; return s; } From d0181e633a3473aca30cbf3771ade78e53a7f6a2 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Mon, 23 May 2011 19:13:51 +0200 Subject: [PATCH 273/378] declaration of 'strlen' shadows a global declaration --- bench/benchmark.org | 3 ++- include/psyc.h | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/bench/benchmark.org b/bench/benchmark.org index 38ff07a..c30705f 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -126,7 +126,8 @@ We'll use the latter here: * Results -Parsing time of 1 000 000 packets in milliseconds: +Parsing time of 1 000 000 packets, in milliseconds. +a simple strlen scan of the respective message is provided for comparison. | input: | PSYC | | JSON | | | XML | | | parser: | strlen | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml | diff --git a/include/psyc.h b/include/psyc.h index b33e96a..6146665 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -108,9 +108,9 @@ typedef struct * @return An instance of the psycString struct. */ static inline -psycString psyc_newString (const char *str, size_t strlen) +psycString psyc_newString (const char *str, size_t slen) { - psycString s = {strlen, str}; + psycString s = {slen, str}; return s; } From 574f33ce85761d1c95edcc3938e55fbbfc9092fa Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 24 May 2011 17:37:00 +0200 Subject: [PATCH 274/378] bench: binary packet generation & results --- bench/.gitignore | 1 + bench/Makefile | 2 +- bench/benchmark.org | 47 ++++++++++++++------ bench/packets/binary/json-footer | 1 + bench/packets/binary/json-header | 1 + bench/packets/binary/psyc-content | 2 + bench/packets/binary/psyc-header | 0 bench/packets/binary/xml-footer | 1 + bench/packets/binary/xml-header | 1 + test/Makefile | 74 ++++++++++++++++++++++++------- test/testJsonGlib.c | 5 +-- 11 files changed, 100 insertions(+), 35 deletions(-) create mode 100644 bench/packets/binary/json-footer create mode 100644 bench/packets/binary/json-header create mode 100644 bench/packets/binary/psyc-content create mode 100644 bench/packets/binary/psyc-header create mode 100644 bench/packets/binary/xml-footer create mode 100644 bench/packets/binary/xml-header diff --git a/bench/.gitignore b/bench/.gitignore index bffe52f..fd2f6c3 100644 --- a/bench/.gitignore +++ b/bench/.gitignore @@ -1,3 +1,4 @@ *.html *.pdf results/ +packets/binary/[0-9]* diff --git a/bench/Makefile b/bench/Makefile index e263ac0..cecdfe3 100644 --- a/bench/Makefile +++ b/bench/Makefile @@ -7,7 +7,7 @@ INIT = (setq load-path (cons \"/usr/share/emacs/site-lisp/org-mode\" load-path) org-babel-tangle-pad-newline nil \ org-src-preserve-indentation t) \ (require 'org-install) - +#' ORG = benchmark.org html: diff --git a/bench/benchmark.org b/bench/benchmark.org index 3bcce3b..0916eaa 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -129,23 +129,42 @@ We'll use the latter here: Parsing time of 1 000 000 packets, in milliseconds. a simple strlen scan of the respective message is provided for comparison. -| input: | PSYC | | JSON | | | XML | | -| parser: | strlen | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml | -|-----------+--------+---------+--------+-----------+------------+--------+----------| -| user prof | 55 | 608 | 4715 | 17468 | 7350 | 12377 | 2477 | -|-----------+--------+---------+--------+-----------+------------+--------+----------| -| / | < | > | < | > | < | | > | +| input: | PSYC | | JSON | | | XML | | +| parser: | strlen | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml | +|--------------+--------+---------+--------+-----------+------------+--------+----------| +| user profile | 55 | 608 | 4715 | 16503 | 7350 | 12377 | 2477 | +|--------------+--------+---------+--------+-----------+------------+--------+----------| +| / | < | > | < | > | < | | > | Pure syntax comparisons above, protocol performance comparisons below: -| input: | PSYC | | JSON | | | XMPP | | -| parser: | strlen | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml | -|-----------+--------+---------+--------+-----------+------------+--------+----------| -| presence | 30 | 246 | 2463 | 10197 | 4997 | 7557 | 1719 | -| chat msg | 41 | 320 | | | 5997 | 9777 | 1893 | -| activity | 42 | 366 | 4666 | 16846 | 13357 | 28858 | 4419 | -|-----------+--------+---------+--------+-----------+------------+--------+----------| -| / | < | > | < | > | < | | > | +| input: | PSYC | | JSON | | | XMPP | | +| parser: | strlen | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml | +|-----------------+--------+---------+--------+-----------+------------+--------+----------| +| presence | 30 | 236 | 2463 | 10016 | 4997 | 7557 | 1719 | +| chat msg | 40 | 295 | 2147 | 9526 | 5997 | 9777 | 1893 | +| activity | 42 | 353 | 4666 | 16327 | 13357 | 28858 | 4356 | +| psyc-unfriendly | 70 | 286 | 2892 | 12567 | 5538 | 8659 | 1896 | +| json-unfriendly | 49 | 430 | 2328 | 10006 | 5141 | 7875 | 1751 | +| xml-unfriendly | 37 | 296 | 2156 | 9591 | 5571 | 8769 | 1765 | +|-----------------+--------+---------+--------+-----------+------------+--------+----------| +| / | < | > | < | > | < | | > | + +Parsing large amounts of binary data. For JSON & XML base64 encoding was used. +Note that the results below include only the parsing time, base64 decoding was +not performed. + +| input: | PSYC | | JSON | | | XML | | +| parser: | strlen | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml | +|-------------+--------+---------+--------+------------+------------+-----------+----------| +| binary 7K | 92 | 77 | 14459 | 98000 | 11445 | 19299 | 8701 | +| binary 70K | 53 | 77 | 14509 | 1003900 | 96209 | 167738 | 74296 | +| binary 700K | 42 | 77 | 14551 | 10616000 | 842025 | 1909428 | 729419 | +| binary 7M | 258 | 78 | 14555 | 120810000 | 12466610 | 16751363 | 7581169 | +| binary 70M | 304 | 80 | 14534 | 1241000000 | 169622110 | 296017820 | 75308906 | +|-------------+--------+---------+--------+------------+------------+-----------+----------| +| / | < | > | < | > | < | | > | + These tests were performed on a 2.53 GHz Intel(R) Core(TM)2 Duo P9500 CPU. diff --git a/bench/packets/binary/json-footer b/bench/packets/binary/json-footer new file mode 100644 index 0000000..6b822c2 --- /dev/null +++ b/bench/packets/binary/json-footer @@ -0,0 +1 @@ +"} \ No newline at end of file diff --git a/bench/packets/binary/json-header b/bench/packets/binary/json-header new file mode 100644 index 0000000..e045aed --- /dev/null +++ b/bench/packets/binary/json-header @@ -0,0 +1 @@ +{"data":" \ No newline at end of file diff --git a/bench/packets/binary/psyc-content b/bench/packets/binary/psyc-content new file mode 100644 index 0000000..7ab1318 --- /dev/null +++ b/bench/packets/binary/psyc-content @@ -0,0 +1,2 @@ +:_foo bar +_data diff --git a/bench/packets/binary/psyc-header b/bench/packets/binary/psyc-header new file mode 100644 index 0000000..e69de29 diff --git a/bench/packets/binary/xml-footer b/bench/packets/binary/xml-footer new file mode 100644 index 0000000..f09e8d4 --- /dev/null +++ b/bench/packets/binary/xml-footer @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bench/packets/binary/xml-header b/bench/packets/binary/xml-header new file mode 100644 index 0000000..3f35021 --- /dev/null +++ b/bench/packets/binary/xml-header @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/Makefile b/test/Makefile index 66c2445..f7f49ea 100644 --- a/test/Makefile +++ b/test/Makefile @@ -50,23 +50,6 @@ test: ${TARGETS} x=0; for f in packets/[0-9]*; do echo ">> $$f"; ./testPsyc -f $$f | ${DIFF} -u $$f -; x=$$((x+$$?)); done; exit $$x x=0; for f in packets/[0-9]*; do echo ">> $$f"; ./testPsyc -rf $$f | ${DIFF} -u $$f -; x=$$((x+$$?)); done; exit $$x -bench: bench-psyc bench-json bench-xml - -bench-dir: - @mkdir -p ../bench/results - -bench-psyc: bench-dir testStrlen testPsycSpeed - for f in ../bench/packets/*.psyc; do bf=`basename $$f`; echo strlen: $$bf; ./testStrlen -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf.strlen; done - for f in ../bench/packets/*.psyc; do bf=`basename $$f`; echo libpsyc: $$f; ./testPsycSpeed -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf; done - -bench-json: bench-dir testStrlen testJson testJsonGlib - for f in ../bench/packets/*.json; do bf=`basename $$f`; echo strlen: $$bf; ./testStrlen -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf.strlen; done - for f in ../bench/packets/*.json; do bf=`basename $$f`; echo json-c: $$bf; ./testJson -snc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf; done - for f in ../bench/packets/*.json; do bf=`basename $$f`; echo json-glib: $$bf; ./testJsonGlib -snc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf-glib; done - -bench-xml: bench-dir testStrlen - for f in ../bench/packets/*.xml; do bf=`basename $$f`; echo strlen: $$bf; ./testStrlen -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf.strlen; done - .NOTPARALLEL: nettestrun nettest: nettestfull nettestsplit @@ -96,3 +79,60 @@ srvstart: srvkill: pkill -x testPsyc + + +bench: bench-genpkts bench-psyc bench-json bench-xml + +bench-dir: + @mkdir -p ../bench/results + +bench-psyc: bench-dir testStrlen testPsycSpeed + for f in ../bench/packets/*.psyc ../bench/packets/binary/*.psyc; do bf=`basename $$f`; echo strlen: $$bf; ./testStrlen -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf.strlen; done + for f in ../bench/packets/*.psyc ../bench/packets/binary/*.psyc; do bf=`basename $$f`; echo libpsyc: $$f; ./testPsycSpeed -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf; done + +bench-json: bench-dir testStrlen testJson testJsonGlib + for f in ../bench/packets/*.json ../bench/packets/binary/*.json; do bf=`basename $$f`; echo strlen: $$bf; ./testStrlen -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf.strlen; done + for f in ../bench/packets/*.json ../bench/packets/binary/*.json; do bf=`basename $$f`; echo json-c: $$bf; ./testJson -snc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf; done + for f in ../bench/packets/*.json; do bf=`basename $$f`; echo json-glib: $$bf; ./testJsonGlib -snc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf-glib; done + +bench-xml: bench-dir testStrlen + for f in ../bench/packets/*.xml ../bench/packets/binary/*.xml; do bf=`basename $$f`; echo strlen: $$bf; ./testStrlen -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf.strlen; done + +bench-genpkts: + @${MAKE} genpkt header=../bench/packets/binary/psyc-header content=../bench/packets/binary/psyc-content bs=7000 of=../bench/packets/binary/7K.psyc + @${MAKE} genpkt header=../bench/packets/binary/psyc-header content=../bench/packets/binary/psyc-content bs=70000 of=../bench/packets/binary/70K.psyc + @${MAKE} genpkt header=../bench/packets/binary/psyc-header content=../bench/packets/binary/psyc-content bs=700000 of=../bench/packets/binary/700K.psyc + @${MAKE} genpkt header=../bench/packets/binary/psyc-header content=../bench/packets/binary/psyc-content bs=7000000 of=../bench/packets/binary/7000K.psyc + @${MAKE} genpkt header=../bench/packets/binary/psyc-header content=../bench/packets/binary/psyc-content bs=7000000 count=10 of=../bench/packets/binary/70000K.psyc +# @${MAKE} genpkt header=../bench/packets/binary/psyc-header content=../bench/packets/binary/psyc-content bs=7000000 count=100 of=../bench/packets/binary/700000K.psyc + + @${MAKE} genb64 header=../bench/packets/binary/json-header footer=../bench/packets/binary/json-footer bs=7000 of=../bench/packets/binary/7K.json + @${MAKE} genb64 header=../bench/packets/binary/json-header footer=../bench/packets/binary/json-footer bs=70000 of=../bench/packets/binary/70K.json + @${MAKE} genb64 header=../bench/packets/binary/json-header footer=../bench/packets/binary/json-footer bs=700000 of=../bench/packets/binary/700K.json + @${MAKE} genb64 header=../bench/packets/binary/json-header footer=../bench/packets/binary/json-footer bs=7000000 of=../bench/packets/binary/7000K.json + @${MAKE} genb64 header=../bench/packets/binary/json-header footer=../bench/packets/binary/json-footer bs=7000000 count=10 of=../bench/packets/binary/70000K.json +# @${MAKE} genb64 header=../bench/packets/binary/json-header footer=../bench/packets/binary/json-footer bs=7000000 count=100 of=../bench/packets/binary/700000K.json + + @${MAKE} genb64 header=../bench/packets/binary/xml-header footer=../bench/packets/binary/xml-footer bs=7000 of=../bench/packets/binary/7K.xml + @${MAKE} genb64 header=../bench/packets/binary/xml-header footer=../bench/packets/binary/xml-footer bs=70000 of=../bench/packets/binary/70K.xml + @${MAKE} genb64 header=../bench/packets/binary/xml-header footer=../bench/packets/binary/xml-footer bs=700000 of=../bench/packets/binary/700K.xml + @${MAKE} genb64 header=../bench/packets/binary/xml-header footer=../bench/packets/binary/xml-footer bs=7000000 of=../bench/packets/binary/7000K.xml + @${MAKE} genb64 header=../bench/packets/binary/xml-header footer=../bench/packets/binary/xml-footer bs=7000000 count=10 of=../bench/packets/binary/70000K.xml +# @${MAKE} genb64 header=../bench/packets/binary/xml-header footer=../bench/packets/binary/xml-footer bs=7000000 count=100 of=../bench/packets/binary/700000K.xml + +bs = 1 +count = 1 +genpkt: + @[[ -n "${of}" ]] + [[ -f "${of}" ]] || ( \ + cat ${header} >${of}; \ + perl -le 'my @se=stat(q('${content}')); print $$se[7] + ${bs} * ${count} + 1' >>${of}; \ + cat ${content} >>${of}; \ + dd if=/dev/urandom of=${of} bs=${bs} count=${count} oflag=append conv=notrunc; \ + echo -ne "\n|\n" >>${of} ) + +bs = 1 +count = 1 +genb64: + @[[ -n "${of}" ]] + [[ -f "${of}" ]] || (cat ${header} >${of}; dd if=/dev/urandom bs=${bs} count=${count} | base64 -w0 >>${of}; cat ${footer} >>${of}) diff --git a/test/testJsonGlib.c b/test/testJsonGlib.c index 91fe9b5..2ef2e3e 100644 --- a/test/testJsonGlib.c +++ b/test/testJsonGlib.c @@ -32,7 +32,7 @@ void test_init (int i) { int test_input (int i, char *recvbuf, size_t nbytes) { JsonNode *root; - GError *error; + GError *error = NULL; char *str; size_t len; int r, ret; @@ -41,8 +41,7 @@ int test_input (int i, char *recvbuf, size_t nbytes) { if (!ret) { printf("Parse error\n"); - exit_code = 1; - return -1; + exit(1); } root = json_parser_get_root(parser); From 3f78dad3988edfe0de504e81ddeffd2f5b6d2212 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 24 May 2011 17:43:20 +0200 Subject: [PATCH 275/378] + --- bench/benchmark.org | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/bench/benchmark.org b/bench/benchmark.org index 0916eaa..3d85a79 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -129,12 +129,13 @@ We'll use the latter here: Parsing time of 1 000 000 packets, in milliseconds. a simple strlen scan of the respective message is provided for comparison. -| input: | PSYC | | JSON | | | XML | | +| input: | PSYC | | JSON | | | XML | | | parser: | strlen | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml | |--------------+--------+---------+--------+-----------+------------+--------+----------| -| user profile | 55 | 608 | 4715 | 16503 | 7350 | 12377 | 2477 | +| user profile | 55 | 608 | 4715 | 16503 | 7350 | 12377 | 2477 | |--------------+--------+---------+--------+-----------+------------+--------+----------| -| / | < | > | < | > | < | | > | +| / | < | > | < | > | < | | > | +| | | | | | | | | Pure syntax comparisons above, protocol performance comparisons below: @@ -154,16 +155,17 @@ Parsing large amounts of binary data. For JSON & XML base64 encoding was used. Note that the results below include only the parsing time, base64 decoding was not performed. -| input: | PSYC | | JSON | | | XML | | -| parser: | strlen | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml | -|-------------+--------+---------+--------+------------+------------+-----------+----------| -| binary 7K | 92 | 77 | 14459 | 98000 | 11445 | 19299 | 8701 | -| binary 70K | 53 | 77 | 14509 | 1003900 | 96209 | 167738 | 74296 | -| binary 700K | 42 | 77 | 14551 | 10616000 | 842025 | 1909428 | 729419 | -| binary 7M | 258 | 78 | 14555 | 120810000 | 12466610 | 16751363 | 7581169 | -| binary 70M | 304 | 80 | 14534 | 1241000000 | 169622110 | 296017820 | 75308906 | -|-------------+--------+---------+--------+------------+------------+-----------+----------| -| / | < | > | < | > | < | | > | +| input: | PSYC | | JSON | | | XML | | +| parser: | strlen | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml | +|---------+--------+---------+--------+------------+------------+-----------+----------| +| 7K | 92 | 77 | 14459 | 98000 | 11445 | 19299 | 8701 | +| 70K | 53 | 77 | 14509 | 1003900 | 96209 | 167738 | 74296 | +| 700K | 42 | 77 | 14551 | 10616000 | 842025 | 1909428 | 729419 | +| 7M | 258 | 78 | 14555 | 120810000 | 12466610 | 16751363 | 7581169 | +| 70M | 304 | 80 | 14534 | 1241000000 | 169622110 | 296017820 | 75308906 | +|---------+--------+---------+--------+------------+------------+-----------+----------| +| / | < | > | < | > | < | | > | +| | | | | | | | | These tests were performed on a 2.53 GHz Intel(R) Core(TM)2 Duo P9500 CPU. From 59fafcb5c0c4d7e52746120cd96b3f441ea13b02 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 24 May 2011 18:04:00 +0200 Subject: [PATCH 276/378] + --- bench/benchmark.org | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/bench/benchmark.org b/bench/benchmark.org index 3d85a79..5a9f0be 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -253,17 +253,19 @@ specialized parsers and renderers to be provided. * Appendix ** Tools used -libpsyc: +*** libpsyc + +: make bench + +which uses the following commands: : test/testStrlen -sc 1000000 -f $file : test/testPsycSpeed -sc 1000000 -f $file : test/testJson -snc 1000000 -f $file : test/testJsonGlib -snc 1000000 -f $file -xmlbench: +*** xmlbench : parse/libxml-sax 1000000 $file : parse/libxml 1000000 $file : parse/rapidxml 1000000 $file - -See also "make bench" From 88cf8c07c9996de1faedfd3385b6b22964a9392e Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 24 May 2011 19:15:05 +0200 Subject: [PATCH 277/378] + --- bench/benchmark.org | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/bench/benchmark.org b/bench/benchmark.org index 5a9f0be..c6e9bd2 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -129,13 +129,16 @@ We'll use the latter here: Parsing time of 1 000 000 packets, in milliseconds. a simple strlen scan of the respective message is provided for comparison. -| input: | PSYC | | JSON | | | XML | | -| parser: | strlen | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml | -|--------------+--------+---------+--------+-----------+------------+--------+----------| -| user profile | 55 | 608 | 4715 | 16503 | 7350 | 12377 | 2477 | -|--------------+--------+---------+--------+-----------+------------+--------+----------| -| / | < | > | < | > | < | | > | -| | | | | | | | | +| input: | PSYC | | JSON | | | XML | | +| parser: | strlen | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml | +|-----------------+--------+---------+--------+-----------+------------+--------+----------| +| user profile | 55 | 608 | 4715 | 16503 | 7350 | 12377 | 2477 | +| psyc-unfriendly | 70 | 286 | 2892 | 12567 | 5538 | 8659 | 1896 | +| json-unfriendly | 49 | 430 | 2328 | 10006 | 5141 | 7875 | 1751 | +| xml-unfriendly | 37 | 296 | 2156 | 9591 | 5571 | 8769 | 1765 | +|-----------------+--------+---------+--------+-----------+------------+--------+----------| +| / | < | > | < | > | < | | > | +| | | | | | | | | Pure syntax comparisons above, protocol performance comparisons below: @@ -145,9 +148,6 @@ Pure syntax comparisons above, protocol performance comparisons below: | presence | 30 | 236 | 2463 | 10016 | 4997 | 7557 | 1719 | | chat msg | 40 | 295 | 2147 | 9526 | 5997 | 9777 | 1893 | | activity | 42 | 353 | 4666 | 16327 | 13357 | 28858 | 4356 | -| psyc-unfriendly | 70 | 286 | 2892 | 12567 | 5538 | 8659 | 1896 | -| json-unfriendly | 49 | 430 | 2328 | 10006 | 5141 | 7875 | 1751 | -| xml-unfriendly | 37 | 296 | 2156 | 9591 | 5571 | 8769 | 1765 | |-----------------+--------+---------+--------+-----------+------------+--------+----------| | / | < | > | < | > | < | | > | From 5a3fec3e7fb68316bf028412582401ee2916497f Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Tue, 24 May 2011 20:13:16 +0200 Subject: [PATCH 278/378] conclusion moved --- bench/benchmark.org | 91 ++++++++++++++++++++++++--------------------- 1 file changed, 48 insertions(+), 43 deletions(-) diff --git a/bench/benchmark.org b/bench/benchmark.org index 5a9f0be..079e8ca 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -25,8 +25,9 @@ Here's a way to model this in PSYC: ** A message with JSON-unfriendly characters This message contains some characters which are -impractical to encode in JSON. Let's see how much -performance impact this has. +impractical to encode in JSON. We should probably +put a lot more inside to actually see an impact +on performance. #+INCLUDE: packets/json-unfriendly.xml src xml #+INCLUDE: packets/json-unfriendly.json src js @@ -34,7 +35,8 @@ performance impact this has. ** A message with XML-unfriendly characters Same test with characters which aren't practical -in the XML syntax. +in the XML syntax, yet we should put more of +them inside. #+INCLUDE: packets/xml-unfriendly.xml src xml #+INCLUDE: packets/xml-unfriendly.json src js @@ -170,6 +172,49 @@ not performed. These tests were performed on a 2.53 GHz Intel(R) Core(TM)2 Duo P9500 CPU. +* Criticism + +Are we comparing apples and oranges? Yes and no, depends on what you +need. XML is a syntax best suited for complex structured data in +well-defined formats - especially good for text mark-up. JSON is a syntax +intended to hold arbitrarily structured data suitable for immediate +inclusion in javascript source codes. The PSYC syntax is an evolved +derivate of RFC 822, the syntax used by HTTP and E-Mail, and is therefore +limited in the kind and depth of data structures that can be represented +with it, but in exchange it is highly performant at doing just that. +In fact we are looking into suitable syntax extensions to represent +generic structures and semantic signatures, but for now PSYC only +provides for simple typed values and lists of typed values. + +Another aspect is the availability of these formats for spontaneous +use. You could generate and parse JSON yourself but you have to be +careful about escaping. XML can be rendered manually if you know your +data will not break the syntax, but you can't really parse it without +a bullet proof parser. PSYC is easy to render and parse yourself for +simple tasks, as long as your body does not contain "\n|\n" and your +variables do not contain newlines. + +After all it is up to you to find out which format fulfils your +requirements the best. We use PSYC for the majority of messaging where +JSON and XMPP aren't efficient and opaque enough, but we employ XML and +JSON as payloads within PSYC for data that doesn't fit the PSYC model. +For some reason all three formats are being used for messaging, although +only PSYC was actually designed for that purpose. + +* Caveats + +In every case we'll compare performance of parsing and re-rendering +these messages, but consider also that the applicative processing +of an XML DOM tree is more complicated than just accessing +certain elements in a JSON data structure or PSYC variable +mapping. + +For a speed check in real world conditions which also consider the +complexity of processing incoming messages we should compare +the performance of a chat client using the two protocols, +for instance by using libpurple with XMPP and PSYC accounts. +To this purpose we first need to integrate libpsyc into libpurple. + * Conclusions The Internet has developed two major breeds of protocol formats. @@ -187,46 +232,6 @@ combines the compactness and efficiency of binary protocols with the extensibility of text-based protocols and still provides for enough data structuring to rarely require the use of other data formats. -* Criticism - -Are we comparing apples and oranges? Yes and no, depends on what you -need. XML is a syntax best suited for complex structured data in -well-defined formats - especially good for text mark-up. JSON is a syntax -intended to hold arbitrarily structured data suitable for immediate -inclusion in javascript source codes. The PSYC syntax is an evolved -derivate of RFC 822, the syntax used by HTTP and E-Mail, and is therefore -limited in the kind and depth of data structures that can be represented -with it, but in exchange it is highly performant at doing just that. - -So it is up to you to find out which format fulfils your -requirements the best. We use PSYC for the majority of messaging where -JSON and XMPP aren't efficient and opaque enough, but we employ XML and -JSON as payloads within PSYC for data that doesn't fit the PSYC model. -For some reason all three formats are being used for messaging, although -only PSYC was actually designed for that purpose. - -Another aspect is the availability of these formats for spontaneous -use. You could generate and parse JSON yourself but you have to be -careful about escaping. XML can be rendered manually if you know your -data will not break the syntax, but you can't really parse it without -a bullet proof parser. PSYC is easy to render and parse yourself for -simple tasks, as long as your body does not contain "\n|\n" and your -variables do not contain newlines. - -* Caveats - -In every case we'll compare performance of parsing and re-rendering -these messages, but consider also that the applicative processing -of an XML DOM tree is more complicated than just accessing -certain elements in a JSON data structure or PSYC variable -mapping. - -For a speed check in real world conditions which also consider the -complexity of processing incoming messages we should compare -the performance of a chat client using the two protocols, -for instance by using libpurple with XMPP and PSYC accounts. -To this purpose we first need to integrate libpsyc into libpurple. - * Futures After a month of development libpsyc is already performing pretty From eebf3ff4e12fe7a9d861c5add61d403272394e71 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Tue, 24 May 2011 20:18:05 +0200 Subject: [PATCH 279/378] + --- bench/benchmark.org | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bench/benchmark.org b/bench/benchmark.org index 6d1c2a7..1726064 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -258,6 +258,9 @@ specialized parsers and renderers to be provided. * Appendix ** Tools used +This document and its benchmarks are distributed with libpsyc. +See http://about.psyc.eu/libpsyc on how to obtain it. + *** libpsyc : make bench From a91412885d246a6b2dd36f74690d7901a5f906b9 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 24 May 2011 20:41:27 +0200 Subject: [PATCH 280/378] bench: fix for strlen & json-c tests --- bench/benchmark.org | 22 +++++++++++----------- test/Makefile | 10 +++++----- test/test.c | 18 ++++++++++++++++-- test/testStrlen.c | 1 + 4 files changed, 33 insertions(+), 18 deletions(-) diff --git a/bench/benchmark.org b/bench/benchmark.org index c6e9bd2..b0c5b73 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -155,17 +155,17 @@ Parsing large amounts of binary data. For JSON & XML base64 encoding was used. Note that the results below include only the parsing time, base64 decoding was not performed. -| input: | PSYC | | JSON | | | XML | | -| parser: | strlen | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml | -|---------+--------+---------+--------+------------+------------+-----------+----------| -| 7K | 92 | 77 | 14459 | 98000 | 11445 | 19299 | 8701 | -| 70K | 53 | 77 | 14509 | 1003900 | 96209 | 167738 | 74296 | -| 700K | 42 | 77 | 14551 | 10616000 | 842025 | 1909428 | 729419 | -| 7M | 258 | 78 | 14555 | 120810000 | 12466610 | 16751363 | 7581169 | -| 70M | 304 | 80 | 14534 | 1241000000 | 169622110 | 296017820 | 75308906 | -|---------+--------+---------+--------+------------+------------+-----------+----------| -| / | < | > | < | > | < | | > | -| | | | | | | | | +| input: | PSYC | | JSON | | | XML | | +| parser: | strlen | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml | +|---------+----------+---------+-----------+------------+------------+-----------+----------| +| 7K | 978 | 77 | 18609 | 98000 | 11445 | 19299 | 8701 | +| 70K | 9613 | 77 | 187540 | 1003900 | 96209 | 167738 | 74296 | +| 700K | 95888 | 77 | 1883500 | 10616000 | 842025 | 1909428 | 729419 | +| 7M | 1347300 | 78 | 26359000 | 120810000 | 12466610 | 16751363 | 7581169 | +| 70M | 14414000 | 80 | 357010000 | 1241000000 | 169622110 | 296017820 | 75308906 | +|---------+----------+---------+-----------+------------+------------+-----------+----------| +| / | < | > | < | > | < | | > | +| | | | | | | | | These tests were performed on a 2.53 GHz Intel(R) Core(TM)2 Duo P9500 CPU. diff --git a/test/Makefile b/test/Makefile index f7f49ea..29b0d05 100644 --- a/test/Makefile +++ b/test/Makefile @@ -87,16 +87,16 @@ bench-dir: @mkdir -p ../bench/results bench-psyc: bench-dir testStrlen testPsycSpeed - for f in ../bench/packets/*.psyc ../bench/packets/binary/*.psyc; do bf=`basename $$f`; echo strlen: $$bf; ./testStrlen -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf.strlen; done - for f in ../bench/packets/*.psyc ../bench/packets/binary/*.psyc; do bf=`basename $$f`; echo libpsyc: $$f; ./testPsycSpeed -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf; done + for f in ../bench/packets/*.psyc `ls ../bench/packets/binary/*.psyc | sort -r`; do bf=`basename $$f`; echo strlen: $$bf; ./testStrlen -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf.strlen; done + for f in ../bench/packets/*.psyc `ls ../bench/packets/binary/*.psyc | sort -r`; do bf=`basename $$f`; echo libpsyc: $$f; ./testPsycSpeed -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf; done bench-json: bench-dir testStrlen testJson testJsonGlib - for f in ../bench/packets/*.json ../bench/packets/binary/*.json; do bf=`basename $$f`; echo strlen: $$bf; ./testStrlen -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf.strlen; done - for f in ../bench/packets/*.json ../bench/packets/binary/*.json; do bf=`basename $$f`; echo json-c: $$bf; ./testJson -snc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf; done +# for f in ../bench/packets/*.json `ls ../bench/packets/binary/*.json | sort -r`; do bf=`basename $$f`; echo strlen: $$bf; ./testStrlen -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf.strlen; done + for f in ../bench/packets/*.json `ls ../bench/packets/binary/*.json | sort -r`; do bf=`basename $$f`; echo json-c: $$bf; ./testJson -snc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf; done for f in ../bench/packets/*.json; do bf=`basename $$f`; echo json-glib: $$bf; ./testJsonGlib -snc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf-glib; done bench-xml: bench-dir testStrlen - for f in ../bench/packets/*.xml ../bench/packets/binary/*.xml; do bf=`basename $$f`; echo strlen: $$bf; ./testStrlen -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf.strlen; done +# for f in ../bench/packets/*.xml `ls ../bench/packets/binary/*.xml | sort -r`; do bf=`basename $$f`; echo strlen: $$bf; ./testStrlen -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf.strlen; done bench-genpkts: @${MAKE} genpkt header=../bench/packets/binary/psyc-header content=../bench/packets/binary/psyc-content bs=7000 of=../bench/packets/binary/7K.psyc diff --git a/test/test.c b/test/test.c index 6c30028..1265a5c 100644 --- a/test/test.c +++ b/test/test.c @@ -52,7 +52,7 @@ void *get_in_addr (struct sockaddr *sa) { void test_file(const char* filename, size_t count, size_t recv_buf_size) { char *buf, *recvbuf; // cont buf + recv buf: [ ccrrrr] - size_t i, nbytes, size = 0; + size_t i, nbytes, size; struct timeval start, end; struct stat st; @@ -64,7 +64,8 @@ void test_file(const char* filename, size_t count, size_t recv_buf_size) { fstat(fd, &st); - buf = malloc(CONT_BUF_SIZE + st.st_size); + size = CONT_BUF_SIZE + st.st_size; + buf = malloc(size); if (!buf) { perror("malloc"); exit(1); @@ -77,13 +78,26 @@ void test_file(const char* filename, size_t count, size_t recv_buf_size) { if (stats) gettimeofday(&start, NULL); +#ifdef NOREAD + memset(buf, 1, size); +#else + size = 0; +#endif + for (i = 0; i < count; i++) +#ifndef NOREAD while ((nbytes = read(fd, (void*)recvbuf, recv_buf_size))) +#endif test_input(0, recvbuf, nbytes); } else { +#ifdef NOREAD + memset(buf, 1, size); +#else + size = 0; while ((nbytes = read(fd, (void*)recvbuf + size, RECV_BUF_SIZE))) size += nbytes; +#endif if (stats) gettimeofday(&start, NULL); diff --git a/test/testStrlen.c b/test/testStrlen.c index 9bd6866..40a50a5 100644 --- a/test/testStrlen.c +++ b/test/testStrlen.c @@ -10,6 +10,7 @@ #include #include +#define NOREAD #include "test.c" // cmd line args From 481bfbda5f5c5a1e88c8d3db06fcd213d1513a61 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Tue, 24 May 2011 21:24:15 +0200 Subject: [PATCH 281/378] explanations --- bench/benchmark.org | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/bench/benchmark.org b/bench/benchmark.org index 463075e..29627dc 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -129,7 +129,8 @@ We'll use the latter here: * Results Parsing time of 1 000 000 packets, in milliseconds. -a simple strlen scan of the respective message is provided for comparison. +A simple strlen() scan of the respective message is provided for comparison. +These tests were performed on a 2.53 GHz Intel(R) Core(TM)2 Duo P9500 CPU. | input: | PSYC | | JSON | | | XML | | | parser: | strlen | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml | @@ -169,8 +170,17 @@ not performed. | / | < | > | < | > | < | | > | | | | | | | | | | +* Explanations -These tests were performed on a 2.53 GHz Intel(R) Core(TM)2 Duo P9500 CPU. +As you can tell the PSYC data format outpaces its rivals in all circumstances. +Extremely so when delivering binary data as PSYC simply returns the starting +point and the length of the given buffer while the other parsers have to scan +for the end of the transmission, but also with many simpler operations, when +PSYC quickly figures out where the data starts and ends and passes such +information back to the application while the other formats are forced to +generate a copy of the data in order to process possibly embedded special +character sequences. PSYC essentially operates like a binary data protocol +even though it is actually still text-based. * Criticism @@ -186,6 +196,8 @@ In fact we are looking into suitable syntax extensions to represent generic structures and semantic signatures, but for now PSYC only provides for simple typed values and lists of typed values. +* Ease of implementation + Another aspect is the availability of these formats for spontaneous use. You could generate and parse JSON yourself but you have to be careful about escaping. XML can be rendered manually if you know your @@ -194,6 +206,15 @@ a bullet proof parser. PSYC is easy to render and parse yourself for simple tasks, as long as your body does not contain "\n|\n" and your variables do not contain newlines. +* Caveats + +In every case we'll compare performance of parsing and re-rendering +these messages, but consider also that the applicative processing +of an XML DOM tree is more complicated than just accessing +certain elements in a JSON data structure or PSYC variable mapping. + +* Conclusions + After all it is up to you to find out which format fulfils your requirements the best. We use PSYC for the majority of messaging where JSON and XMPP aren't efficient and opaque enough, but we employ XML and @@ -201,22 +222,6 @@ JSON as payloads within PSYC for data that doesn't fit the PSYC model. For some reason all three formats are being used for messaging, although only PSYC was actually designed for that purpose. -* Caveats - -In every case we'll compare performance of parsing and re-rendering -these messages, but consider also that the applicative processing -of an XML DOM tree is more complicated than just accessing -certain elements in a JSON data structure or PSYC variable -mapping. - -For a speed check in real world conditions which also consider the -complexity of processing incoming messages we should compare -the performance of a chat client using the two protocols, -for instance by using libpurple with XMPP and PSYC accounts. -To this purpose we first need to integrate libpsyc into libpurple. - -* Conclusions - The Internet has developed two major breeds of protocol formats. The binary ones are extremely efficient but usually not very flexible (unless you are willing to recompile all instances each time you From 219e07494304373afd691e50d860415e5b5c95b5 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 24 May 2011 21:48:35 +0200 Subject: [PATCH 282/378] bench: compact --- bench/benchmark.org | 26 ++++++++++---------------- bench/packets/presence-compact.psyc | 5 +++++ 2 files changed, 15 insertions(+), 16 deletions(-) create mode 100644 bench/packets/presence-compact.psyc diff --git a/bench/benchmark.org b/bench/benchmark.org index 29627dc..5d76ca0 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -87,13 +87,7 @@ need to be mentioned): And the same in compact form: -#+BEGIN_SRC psyc -:c psyc://example.com/~juliet - -=da 4 -np -| -#+END_SRC +#+INCLUDE: packets/presence-compact.psyc src psyc ** An average chat message @@ -140,19 +134,19 @@ These tests were performed on a 2.53 GHz Intel(R) Core(TM)2 Duo P9500 CPU. | json-unfriendly | 49 | 430 | 2328 | 10006 | 5141 | 7875 | 1751 | | xml-unfriendly | 37 | 296 | 2156 | 9591 | 5571 | 8769 | 1765 | |-----------------+--------+---------+--------+-----------+------------+--------+----------| -| / | < | > | < | > | < | | > | +| / | < | | < | > | < | | > | | | | | | | | | | Pure syntax comparisons above, protocol performance comparisons below: -| input: | PSYC | | JSON | | | XMPP | | -| parser: | strlen | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml | -|-----------------+--------+---------+--------+-----------+------------+--------+----------| -| presence | 30 | 236 | 2463 | 10016 | 4997 | 7557 | 1719 | -| chat msg | 40 | 295 | 2147 | 9526 | 5997 | 9777 | 1893 | -| activity | 42 | 353 | 4666 | 16327 | 13357 | 28858 | 4356 | -|-----------------+--------+---------+--------+-----------+------------+--------+----------| -| / | < | > | < | > | < | | > | +| input: | | PSYC | | JSON | | | XMPP | | +| parser: | strlen | libpsyc | compact | json-c | json-glib | libxml sax | libxml | rapidxml | +|----------+--------+---------+---------+--------+-----------+------------+--------+----------| +| presence | 30 | 236 | 122 | 2463 | 10016 | 4997 | 7557 | 1719 | +| chat msg | 40 | 295 | | 2147 | 9526 | 5997 | 9777 | 1893 | +| activity | 42 | 353 | | 4666 | 16327 | 13357 | 28858 | 4356 | +|----------+--------+---------+---------+--------+-----------+------------+--------+----------| +| / | < | | > | < | > | < | | > | Parsing large amounts of binary data. For JSON & XML base64 encoding was used. Note that the results below include only the parsing time, base64 decoding was diff --git a/bench/packets/presence-compact.psyc b/bench/packets/presence-compact.psyc new file mode 100644 index 0000000..eabd5d6 --- /dev/null +++ b/bench/packets/presence-compact.psyc @@ -0,0 +1,5 @@ +:c psyc://example.com/~juliet + +=da 4 +np +| From 90f8e7a65b16da34942592d817f0182b00c9676c Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Tue, 24 May 2011 21:49:38 +0200 Subject: [PATCH 283/378] .... --- bench/benchmark.org | 35 +++++++++++++++++++---------------- bench/packets/chat_msg.psyc | 2 +- bench/packets/chat_msg.xml | 10 +++------- 3 files changed, 23 insertions(+), 24 deletions(-) diff --git a/bench/benchmark.org b/bench/benchmark.org index 29627dc..14c3ff3 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -1,7 +1,7 @@ #+TITLE: libpsyc Performance Benchmarks In this document we present the results of performance benchmarks -of libpsyc compared with libjson-glib and libxml2. +of libpsyc compared to json-c, libjson-glib, rapidxml and libxml2. * PSYC, JSON, XML Syntax Benchmarks First we look at the mere performance of the PSYC syntax @@ -19,7 +19,7 @@ In JSON this could look like this: #+INCLUDE: packets/user_profile.json src js -Here's a way to model this in PSYC: +Here's a way to model this in PSYC (verbose mode): #+INCLUDE: packets/user_profile.psyc src psyc @@ -27,7 +27,7 @@ Here's a way to model this in PSYC: This message contains some characters which are impractical to encode in JSON. We should probably put a lot more inside to actually see an impact -on performance. +on performance. *TODO* #+INCLUDE: packets/json-unfriendly.xml src xml #+INCLUDE: packets/json-unfriendly.json src js @@ -36,7 +36,7 @@ on performance. ** A message with XML-unfriendly characters Same test with characters which aren't practical in the XML syntax, yet we should put more of -them inside. +them inside. *TODO* #+INCLUDE: packets/xml-unfriendly.xml src xml #+INCLUDE: packets/xml-unfriendly.json src js @@ -65,8 +65,8 @@ for a photograph, 7000000 for a piece of music, * PSYC vs XMPP Protocol Benchmarks These tests use typical messages from the XMPP ("stanzas" in -Jabber lingo) and compare them with equivalent JSON encodings, -verbose and compact PSYC formats. +Jabber lingo) and compare them with equivalent JSON encodings +and PSYC formats. ** A presence packet Since presence packets are by far the dominant messaging content @@ -79,13 +79,15 @@ And here's the same information in a JSON rendition: #+INCLUDE: packets/presence.json src js -Here's the equivalent PSYC packet in verbose form +Here's the equivalent PSYC packet in verbose mode (since it is a multicast, the single recipients do not need to be mentioned): #+INCLUDE: packets/presence.psyc src psyc -And the same in compact form: +And this is the same message in PSYC's compact form, but since compact mode +hasn't been implemented nor deployed yet, we will not include it +in the benchmarks: #+BEGIN_SRC psyc :c psyc://example.com/~juliet @@ -180,7 +182,7 @@ PSYC quickly figures out where the data starts and ends and passes such information back to the application while the other formats are forced to generate a copy of the data in order to process possibly embedded special character sequences. PSYC essentially operates like a binary data protocol -even though it is actually still text-based. +even though it is actually text-based. * Criticism @@ -188,22 +190,23 @@ Are we comparing apples and oranges? Yes and no, depends on what you need. XML is a syntax best suited for complex structured data in well-defined formats - especially good for text mark-up. JSON is a syntax intended to hold arbitrarily structured data suitable for immediate -inclusion in javascript source codes. The PSYC syntax is an evolved -derivate of RFC 822, the syntax used by HTTP and E-Mail, and is therefore +inclusion in Javascript source codes. The PSYC syntax is an evolved +derivate of RFC 822, the syntax used by HTTP and E-Mail. It is currently limited in the kind and depth of data structures that can be represented -with it, but in exchange it is highly performant at doing just that. -In fact we are looking into suitable syntax extensions to represent +with it, but it is highly efficient in exchange. + +In fact we are currently looking into suitable syntax extensions to represent generic structures and semantic signatures, but for now PSYC only provides for simple typed values and lists of typed values. -* Ease of implementation +* Ease of Implementation Another aspect is the availability of these formats for spontaneous use. You could generate and parse JSON yourself but you have to be careful about escaping. XML can be rendered manually if you know your -data will not break the syntax, but you can't really parse it without +data will not break the syntax, but you shouldn't dare to parse it without a bullet proof parser. PSYC is easy to render and parse yourself for -simple tasks, as long as your body does not contain "\n|\n" and your +simple tasks, as long as the body does not contain "\n|\n" and your variables do not contain newlines. * Caveats diff --git a/bench/packets/chat_msg.psyc b/bench/packets/chat_msg.psyc index 51def66..324bf4f 100644 --- a/bench/packets/chat_msg.psyc +++ b/bench/packets/chat_msg.psyc @@ -1,5 +1,5 @@ :_source psyc://example.com/~juliet -:_target psyc://example.net/~romeo +:_target xmpp:romeo@example.net _message Art thou not Romeo, and a Montague? diff --git a/bench/packets/chat_msg.xml b/bench/packets/chat_msg.xml index f7a6b83..eec1675 100644 --- a/bench/packets/chat_msg.xml +++ b/bench/packets/chat_msg.xml @@ -1,8 +1,4 @@ - - Art thou not Romeo, and a Montague? + +Art thou not Romeo, and a Montague? From c7415867aba8030a1ce2e298b6e7eedbeac69892 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Tue, 24 May 2011 21:52:55 +0200 Subject: [PATCH 284/378] + --- bench/packets/activity-c.psyc | 7 +++++++ bench/packets/chat_msg-c.psyc | 6 ++++++ bench/packets/{presence-compact.psyc => presence-c.psyc} | 0 3 files changed, 13 insertions(+) create mode 100644 bench/packets/activity-c.psyc create mode 100644 bench/packets/chat_msg-c.psyc rename bench/packets/{presence-compact.psyc => presence-c.psyc} (100%) diff --git a/bench/packets/activity-c.psyc b/bench/packets/activity-c.psyc new file mode 100644 index 0000000..2d00386 --- /dev/null +++ b/bench/packets/activity-c.psyc @@ -0,0 +1,7 @@ +:c psyc://denmark.lit/~hamlet#_follow + +:j to be or not to be ? +:tc text/plain +m +to be or not to be ? +| diff --git a/bench/packets/chat_msg-c.psyc b/bench/packets/chat_msg-c.psyc new file mode 100644 index 0000000..5556eb2 --- /dev/null +++ b/bench/packets/chat_msg-c.psyc @@ -0,0 +1,6 @@ +:s psyc://example.com/~juliet +:t xmpp:romeo@example.net + +m +Art thou not Romeo, and a Montague? +| diff --git a/bench/packets/presence-compact.psyc b/bench/packets/presence-c.psyc similarity index 100% rename from bench/packets/presence-compact.psyc rename to bench/packets/presence-c.psyc From 7dc0b02c28240747b559899870eb8c809708fd9b Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Tue, 24 May 2011 21:53:18 +0200 Subject: [PATCH 285/378] + --- bench/benchmark.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bench/benchmark.org b/bench/benchmark.org index 79ccd8d..a3b439d 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -89,7 +89,7 @@ And this is the same message in PSYC's compact form, but since compact mode hasn't been implemented nor deployed yet, we will not include it in the benchmarks: -#+INCLUDE: packets/presence-compact.psyc src psyc +#+INCLUDE: packets/presence-c.psyc src psyc ** An average chat message From dad0893632c7d38c2a9037b97d3d5c84238a6ddd Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 24 May 2011 21:54:55 +0200 Subject: [PATCH 286/378] + --- bench/benchmark.org | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bench/benchmark.org b/bench/benchmark.org index a3b439d..58e069e 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -144,11 +144,11 @@ Pure syntax comparisons above, protocol performance comparisons below: | input: | | PSYC | | JSON | | | XMPP | | | parser: | strlen | libpsyc | compact | json-c | json-glib | libxml sax | libxml | rapidxml | |----------+--------+---------+---------+--------+-----------+------------+--------+----------| -| presence | 30 | 236 | 122 | 2463 | 10016 | 4997 | 7557 | 1719 | -| chat msg | 40 | 295 | | 2147 | 9526 | 5997 | 9777 | 1893 | -| activity | 42 | 353 | | 4666 | 16327 | 13357 | 28858 | 4356 | +| presence | 30 | 236 | 122 | 2463 | 10016 | 4997 | 7557 | 1719 | +| chat msg | 40 | 295 | 258 | 2147 | 9526 | 5997 | 9777 | 1893 | +| activity | 42 | 353 | 279 | 4666 | 16327 | 13357 | 28858 | 4356 | |----------+--------+---------+---------+--------+-----------+------------+--------+----------| -| / | < | | > | < | > | < | | > | +| / | < | | > | < | > | < | | > | Parsing large amounts of binary data. For JSON & XML base64 encoding was used. Note that the results below include only the parsing time, base64 decoding was From 452131cd0f9e2f8b91c80e17d38c26a0dbe15762 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Tue, 24 May 2011 21:59:09 +0200 Subject: [PATCH 287/378] out of the cave --- bench/benchmark.org | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/bench/benchmark.org b/bench/benchmark.org index a3b439d..2e6c9a5 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -166,6 +166,11 @@ not performed. | / | < | > | < | > | < | | > | | | | | | | | | | +In each case we compared performance of parsing and re-rendering +these messages, but consider also that the applicative processing +of an XML DOM tree is more complicated than just accessing +certain elements in a JSON data structure or PSYC variable mapping. + * Explanations As you can tell the PSYC data format outpaces its rivals in all circumstances. @@ -203,13 +208,6 @@ a bullet proof parser. PSYC is easy to render and parse yourself for simple tasks, as long as the body does not contain "\n|\n" and your variables do not contain newlines. -* Caveats - -In every case we'll compare performance of parsing and re-rendering -these messages, but consider also that the applicative processing -of an XML DOM tree is more complicated than just accessing -certain elements in a JSON data structure or PSYC variable mapping. - * Conclusions After all it is up to you to find out which format fulfils your From 392ed4b842b784e97ac7b1abad04a223ce08ca09 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 24 May 2011 21:59:32 +0200 Subject: [PATCH 288/378] + --- bench/benchmark.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bench/benchmark.org b/bench/benchmark.org index 58e069e..5f4f766 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -145,7 +145,7 @@ Pure syntax comparisons above, protocol performance comparisons below: | parser: | strlen | libpsyc | compact | json-c | json-glib | libxml sax | libxml | rapidxml | |----------+--------+---------+---------+--------+-----------+------------+--------+----------| | presence | 30 | 236 | 122 | 2463 | 10016 | 4997 | 7557 | 1719 | -| chat msg | 40 | 295 | 258 | 2147 | 9526 | 5997 | 9777 | 1893 | +| chat msg | 40 | 295 | 258 | 2147 | 9526 | 5911 | 8999 | 1850 | | activity | 42 | 353 | 279 | 4666 | 16327 | 13357 | 28858 | 4356 | |----------+--------+---------+---------+--------+-----------+------------+--------+----------| | / | < | | > | < | > | < | | > | From fe3e69ef389f4b99bb3504833ce0f56fb897ae19 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Tue, 24 May 2011 22:16:54 +0200 Subject: [PATCH 289/378] read on --- bench/benchmark.org | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/bench/benchmark.org b/bench/benchmark.org index 6c57120..526fb3f 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -218,9 +218,8 @@ For some reason all three formats are being used for messaging, although only PSYC was actually designed for that purpose. The Internet has developed two major breeds of protocol formats. -The binary ones are extremely efficient but usually not very flexible -(unless you are willing to recompile all instances each time you -change something) +The binary ones are extremely efficient but in most cases you have +to recompile all instances each time you change something while the plain-text ones are reaching out for achieving perfection in data representation while leaving the path of efficiency. Some protocols such as HTTP and SIP are in-between these two schools, @@ -255,6 +254,12 @@ you can't edit them manually and you can't produce valid messages by replacing variables in a simple text template. You depend on specialized parsers and renderers to be provided. +* Further Reading + +http://about.psyc.eu/Spec:Syntax provides you with the ABNF grammar +of the PSYC 1.0 syntax. You may also be interested in PSYC's decentralized +state mechanism provided by the +/-/= operators. + * Appendix ** Tools used From dcd351136d1d779fb870aa8248a53f22d4417cf5 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 24 May 2011 22:59:49 +0200 Subject: [PATCH 290/378] make bench --- bench/benchmark.org | 14 ++------------ test/Makefile | 29 ++++++++++++++++++++--------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/bench/benchmark.org b/bench/benchmark.org index 526fb3f..d1e153b 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -266,19 +266,9 @@ state mechanism provided by the +/-/= operators. This document and its benchmarks are distributed with libpsyc. See http://about.psyc.eu/libpsyc on how to obtain it. -*** libpsyc +The benchmarks can be run with the following command +(xmlbench is needed for the xml tests): : make bench -which uses the following commands: -: test/testStrlen -sc 1000000 -f $file -: test/testPsycSpeed -sc 1000000 -f $file -: test/testJson -snc 1000000 -f $file -: test/testJsonGlib -snc 1000000 -f $file - -*** xmlbench - -: parse/libxml-sax 1000000 $file -: parse/libxml 1000000 $file -: parse/rapidxml 1000000 $file diff --git a/test/Makefile b/test/Makefile index 29b0d05..b41e6bb 100644 --- a/test/Makefile +++ b/test/Makefile @@ -80,23 +80,34 @@ srvstart: srvkill: pkill -x testPsyc - -bench: bench-genpkts bench-psyc bench-json bench-xml +bench: bench-genpkts bench-psyc bench-psyc-bin bench-json bench-json-bin bench-xml bench-dir: @mkdir -p ../bench/results bench-psyc: bench-dir testStrlen testPsycSpeed - for f in ../bench/packets/*.psyc `ls ../bench/packets/binary/*.psyc | sort -r`; do bf=`basename $$f`; echo strlen: $$bf; ./testStrlen -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf.strlen; done - for f in ../bench/packets/*.psyc `ls ../bench/packets/binary/*.psyc | sort -r`; do bf=`basename $$f`; echo libpsyc: $$f; ./testPsycSpeed -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf; done + for f in ../bench/packets/*.psyc; do bf=`basename $$f`; echo strlen: $$bf; ./testStrlen -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf.strlen; done + for f in ../bench/packets/*.psyc; do bf=`basename $$f`; echo libpsyc: $$f; ./testPsycSpeed -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf; done -bench-json: bench-dir testStrlen testJson testJsonGlib -# for f in ../bench/packets/*.json `ls ../bench/packets/binary/*.json | sort -r`; do bf=`basename $$f`; echo strlen: $$bf; ./testStrlen -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf.strlen; done - for f in ../bench/packets/*.json `ls ../bench/packets/binary/*.json | sort -r`; do bf=`basename $$f`; echo json-c: $$bf; ./testJson -snc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf; done +bench-psyc-bin: bench-dir testStrlen testPsycSpeed + for f in `ls ../bench/packets/binary/*.psyc | sort -r`; do bf=`basename $$f`; echo "libpsyc: $$f * 1000000"; ./testPsycSpeed -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf; done + c=1000000; for f in `ls ../bench/packets/binary/*.psyc | sort -r`; do bf=`basename $$f`; echo "strlen: $$bf * $$c"; ./testStrlen -sc $$c -f $$f | ${TEE} -a ../bench/results/$$bf.strlen; c=$$((c/10)); done + +bench-json: bench-dir testJson testJsonGlib +# for f in ../bench/packets/*.json; do bf=`basename $$f`; echo strlen: $$bf; ./testStrlen -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf.strlen; done + for f in ../bench/packets/*.json; do bf=`basename $$f`; echo json-c: $$bf; ./testJson -snc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf; done for f in ../bench/packets/*.json; do bf=`basename $$f`; echo json-glib: $$bf; ./testJsonGlib -snc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf-glib; done -bench-xml: bench-dir testStrlen -# for f in ../bench/packets/*.xml `ls ../bench/packets/binary/*.xml | sort -r`; do bf=`basename $$f`; echo strlen: $$bf; ./testStrlen -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf.strlen; done +bench-json-bin: bench-dir testJson testJsonGlib + c=1000000; for f in `ls ../bench/packets/binary/*.json | sort -r`; do bf=`basename $$f`; echo "json-c: $$bf * $$c"; ./testJson -snc $$c -f $$f | ${TEE} -a ../bench/results/$$bf; c=$$((c/10)); done + c=1000000; for f in `ls ../bench/packets/binary/*.json | sort -r`; do bf=`basename $$f`; echo "json-glib: $$bf * $$c"; ./testJsonGlib -snc $$c -f $$f | ${TEE} -a ../bench/results/$$bf-glib; c=$$((c/10)); done + +bench-xml: bench-dir + @[[ -n "${xmlbench}" ]] || (echo xmlbench path needs to be set with xmlbench=/path/to/xmlbench; exit 1) +# for f in ../bench/packets/*.xml; do bf=`basename $$f`; echo strlen: $$bf; ./testStrlen -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf.strlen; done + for f in ../bench/packets/*.xml; do bf=`basename $$f`; echo libxml: $$bf; ${xmlbench}/parse/libxml 1000000 $$f | ${TEE} -a ../bench/results/$$bf-libxml; done + for f in ../bench/packets/*.xml; do bf=`basename $$f`; echo libxml-sax: $$bf; ${xmlbench}/parse/libxml-sax 1000000 $$f | ${TEE} -a ../bench/results/$$bf-libxml-sax; done + for f in ../bench/packets/*.xml; do bf=`basename $$f`; echo rapidxml: $$bf; ${xmlbench}/parse/rapidxml 1000000 $$f | ${TEE} -a ../bench/results/$$bf-rapidxml; done bench-genpkts: @${MAKE} genpkt header=../bench/packets/binary/psyc-header content=../bench/packets/binary/psyc-content bs=7000 of=../bench/packets/binary/7K.psyc From 7c1dcf97a4f72414a25cdda5de30f0630295c4e8 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 25 May 2011 19:04:27 +0200 Subject: [PATCH 291/378] + --- bench/benchmark.org | 2 -- 1 file changed, 2 deletions(-) diff --git a/bench/benchmark.org b/bench/benchmark.org index d1e153b..efdf3ca 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -270,5 +270,3 @@ The benchmarks can be run with the following command (xmlbench is needed for the xml tests): : make bench - - From e7feef1cd0a28d6515400244b3705418198aab7d Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Wed, 25 May 2011 21:12:19 +0200 Subject: [PATCH 292/378] bencode --- bench/benchmark.org | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/bench/benchmark.org b/bench/benchmark.org index 526fb3f..f6da696 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -254,6 +254,14 @@ you can't edit them manually and you can't produce valid messages by replacing variables in a simple text template. You depend on specialized parsers and renderers to be provided. +There's also + +- Bittorrent's bencode + +This format is formally text-based, but not easy to read as it doesn't +have any visual separators and isn't easy to edit as everything is +prefixed by lengths even for very short items. + * Further Reading http://about.psyc.eu/Spec:Syntax provides you with the ABNF grammar From 4500ca0852b423aebdcc13e8cc0982043280fab3 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sat, 28 May 2011 19:39:42 +0200 Subject: [PATCH 293/378] text: naming & doc fixes --- include/psyc.h | 4 +-- include/psyc/parse.h | 4 +-- include/psyc/text.h | 68 +++++++++++++++++++++++--------------------- src/text.c | 30 +++++++++---------- 4 files changed, 54 insertions(+), 52 deletions(-) diff --git a/include/psyc.h b/include/psyc.h index 6146665..769ea8b 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -88,9 +88,9 @@ typedef enum typedef struct { /// Length of the data pointed to by ptr - size_t length; + size_t length; /// pointer to the data - const char *ptr; + const char *ptr; } psycString; typedef struct diff --git a/include/psyc/parse.h b/include/psyc/parse.h index 1b6ef6a..340eba6 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -330,7 +330,7 @@ void psyc_setParseBuffer (psycParseState *state, psycString buffer) * @see psycString */ static inline -void psyc_setParseBuffer2 (psycParseState *state, char *buffer, size_t length) +void psyc_setParseBuffer2 (psycParseState *state, const char *buffer, size_t length) { psycString buf = {length, buffer}; psyc_setParseBuffer(state, buf); @@ -358,7 +358,7 @@ void psyc_setParseListBuffer (psycParseListState *state, psycString buffer) } static inline -void psyc_setParseListBuffer2 (psycParseListState *state, char *buffer, size_t length) +void psyc_setParseListBuffer2 (psycParseListState *state, const char *buffer, size_t length) { psycString buf = {length, buffer}; psyc_setParseListBuffer(state, buf); diff --git a/include/psyc/text.h b/include/psyc/text.h index 5b964b3..a94dd3b 100644 --- a/include/psyc/text.h +++ b/include/psyc/text.h @@ -26,7 +26,7 @@ typedef enum /// Text template parsing & rendering complete. PSYC_TEXT_COMPLETE = 0, /// Text template parsing & rendering is incomplete, because the buffer was too small. - /// Another call is required to this function with a new buffer. + /// Another call is required to this function after setting a new buffer. PSYC_TEXT_INCOMPLETE = 1, } psycTextRC; @@ -48,8 +48,8 @@ typedef struct { size_t cursor; ///< current position in the template size_t written; ///< number of bytes written to buffer - psycString template; ///< template to parse - psycString buffer; ///< buffer for writing to + psycString tmpl; ///< input buffer with text template to parse + psycString buffer; ///< output buffer for rendered text psycString open; psycString close; } psycTextState; @@ -70,32 +70,32 @@ typedef psycTextValueRC (*psycTextCB)(const char *name, size_t len, psycString * * Initializes the PSYC text state struct. * * @param state Pointer to the PSYC text state struct that should be initialized. - * @param template Text template to be parsed. - * @param tlen Length of template. - * @param buffer Buffer where the rendered text is going to be written. - * @param blen Length of buffer. + * @param tmpl Input buffer with text template to be parsed. + * @param tmplen Length of input buffer. + * @param buffer Output buffer where the rendered text is going to be written. + * @param buflen Length of output buffer. */ static inline void psyc_initTextState (psycTextState *state, - char *template, size_t tlen, - char *buffer, size_t blen) + const char *tmpl, size_t tmplen, + char *buffer, size_t buflen) { - state->cursor = 0; - state->written = 0; - state->template = (psycString) {tlen, template}; - state->buffer = (psycString) {blen, buffer}; - state->open = (psycString) {1, "["}; - state->close = (psycString) {1, "]"}; + state->cursor = 0; + state->written = 0; + state->tmpl = (psycString) {tmplen, tmpl}; + state->buffer = (psycString) {buflen, buffer}; + state->open = (psycString) {1, "["}; + state->close = (psycString) {1, "]"}; } /** - * Initializes the PSYC text state struct with custom open & closing braces. + * Initializes the PSYC text state struct with custom opening & closing braces. * * @param state Pointer to the PSYC text state struct that should be initialized. - * @param template Text template to be parsed. - * @param tlen Length of template. - * @param buffer Buffer where the rendered text is going to be written. - * @param blen Length of buffer. + * @param tmpl Input buffer with text template to be parsed. + * @param tmplen Length of input buffer. + * @param buffer Output buffer where the rendered text is going to be written. + * @param buflen Length of output buffer. * @param open Opening brace. * @param openlen Length of opening brace. * @param close Closing brace. @@ -103,19 +103,21 @@ void psyc_initTextState (psycTextState *state, */ static inline void psyc_initTextState2 (psycTextState *state, - char *template, size_t tlen, - char *buffer, size_t blen, - char *open, size_t openlen, - char *close, size_t closelen) + const char *tmpl, size_t tmplen, + char *buffer, size_t buflen, + const char *open, size_t openlen, + const char *close, size_t closelen) { - state->template = (psycString) {tlen, template}; - state->buffer = (psycString) {blen, buffer}; - state->open = (psycString) {openlen, open}; - state->close = (psycString) {closelen, close}; + state->cursor = 0; + state->written = 0; + state->tmpl = (psycString) {tmplen, tmpl}; + state->buffer = (psycString) {buflen, buffer}; + state->open = (psycString) {openlen, open}; + state->close = (psycString) {closelen, close}; } /** - * Sets a new buffer in the PSYC text state struct. + * Sets a new output buffer in the PSYC text state struct. */ static inline void psyc_setTextBuffer (psycTextState *state, psycString buffer) @@ -149,10 +151,10 @@ size_t psyc_getTextBytesWritten (psycTextState *state) * string between these braces. Should the callback return * PSYC_TEXT_VALUE_NOT_FOUND, the original template text is copied as is. * - * Before calling this function psyc_initTextState or psyc_initTextState should - * be called to initialze the state struct. By default PSYC's "[" and "]" are - * used but you can provide any other brace strings such as "${" and "}" or - * "". + * Before calling this function psyc_initTextState should be called to initialize + * the state struct. By default PSYC's "[" and "]" are used but you can provide + * any other brace strings such as "${" and "}" or "" if you use + * the psyc_initTextState2 variant. * * @see http://about.psyc.eu/psyctext **/ diff --git a/src/text.c b/src/text.c index 70a437b..c4a5fea 100644 --- a/src/text.c +++ b/src/text.c @@ -3,29 +3,29 @@ psycTextRC psyc_text (psycTextState *state, psycTextCB getValue) { - const char *start = state->template.ptr, *end; // start & end of variable name - const char *prev = state->template.ptr + state->cursor; + const char *start = state->tmpl.ptr, *end; // start & end of variable name + const char *prev = state->tmpl.ptr + state->cursor; psycString value; int ret; size_t len; uint8_t no_subst = (state->cursor == 0); // whether we can return NO_SUBST - while (state->cursor < state->template.length) + while (state->cursor < state->tmpl.length) { - start = memmem(state->template.ptr + state->cursor, - state->template.length - state->cursor, + start = memmem(state->tmpl.ptr + state->cursor, + state->tmpl.length - state->cursor, state->open.ptr, state->open.length); if (!start) break; - state->cursor = (start - state->template.ptr) + state->open.length; - if (state->cursor >= state->template.length) + state->cursor = (start - state->tmpl.ptr) + state->open.length; + if (state->cursor >= state->tmpl.length) break; // [ at the end - end = memmem(state->template.ptr + state->cursor, - state->template.length - state->cursor, + end = memmem(state->tmpl.ptr + state->cursor, + state->tmpl.length - state->cursor, state->close.ptr, state->close.length); - state->cursor = (end - state->template.ptr) + state->close.length; + state->cursor = (end - state->tmpl.ptr) + state->close.length; if (!end) break; // ] not found @@ -40,12 +40,12 @@ psycTextRC psyc_text (psycTextState *state, psycTextCB getValue) if (ret < 0) continue; // value not found, no substitution - // first copy the part in the template from the previous subst. to the current one + // first copy the part in the input from the previous subst. to the current one // if there's enough buffer space for that len = start - prev; if (state->written + len > state->buffer.length) { - state->cursor = prev - state->template.ptr; + state->cursor = prev - state->tmpl.ptr; return PSYC_TEXT_INCOMPLETE; } @@ -55,7 +55,7 @@ psycTextRC psyc_text (psycTextState *state, psycTextCB getValue) // now substitute the value if there's enough buffer space if (state->written + value.length > state->buffer.length) { - state->cursor = start - state->template.ptr; + state->cursor = start - state->tmpl.ptr; return PSYC_TEXT_INCOMPLETE; } @@ -63,7 +63,7 @@ psycTextRC psyc_text (psycTextState *state, psycTextCB getValue) state->written += value.length; // mark the start of the next chunk of text in the template - prev = state->template.ptr + state->cursor; + prev = state->tmpl.ptr + state->cursor; no_subst = 0; } @@ -71,7 +71,7 @@ psycTextRC psyc_text (psycTextState *state, psycTextCB getValue) return PSYC_TEXT_NO_SUBST; // copy the rest of the template after the last var - len = state->template.length - (prev - state->template.ptr); + len = state->tmpl.length - (prev - state->tmpl.ptr); if (state->written + len > state->buffer.length) return PSYC_TEXT_INCOMPLETE; From 0c99850a4557e64a9e39a61f0edffc2ce3ab31f9 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sat, 28 May 2011 20:23:54 +0200 Subject: [PATCH 294/378] bench table fix --- bench/benchmark.org | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/bench/benchmark.org b/bench/benchmark.org index 798bd36..c2729dd 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -128,8 +128,7 @@ Parsing time of 1 000 000 packets, in milliseconds. A simple strlen() scan of the respective message is provided for comparison. These tests were performed on a 2.53 GHz Intel(R) Core(TM)2 Duo P9500 CPU. -| input: | PSYC | | JSON | | | XML | | -| parser: | strlen | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml | +| | strlen | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml | |-----------------+--------+---------+--------+-----------+------------+--------+----------| | user profile | 55 | 608 | 4715 | 16503 | 7350 | 12377 | 2477 | | psyc-unfriendly | 70 | 286 | 2892 | 12567 | 5538 | 8659 | 1896 | @@ -141,21 +140,20 @@ These tests were performed on a 2.53 GHz Intel(R) Core(TM)2 Duo P9500 CPU. Pure syntax comparisons above, protocol performance comparisons below: -| input: | | PSYC | | JSON | | | XMPP | | -| parser: | strlen | libpsyc | compact | json-c | json-glib | libxml sax | libxml | rapidxml | -|----------+--------+---------+---------+--------+-----------+------------+--------+----------| -| presence | 30 | 236 | 122 | 2463 | 10016 | 4997 | 7557 | 1719 | -| chat msg | 40 | 295 | 258 | 2147 | 9526 | 5911 | 8999 | 1850 | -| activity | 42 | 353 | 279 | 4666 | 16327 | 13357 | 28858 | 4356 | -|----------+--------+---------+---------+--------+-----------+------------+--------+----------| -| / | < | | > | < | > | < | | > | +| | strlen | libpsyc | libpsyc compact | json-c | json-glib | libxml sax | libxml | rapidxml | +|----------+--------+---------+-----------------+--------+-----------+------------+--------+----------| +| presence | 30 | 236 | 122 | 2463 | 10016 | 4997 | 7557 | 1719 | +| chat msg | 40 | 295 | 258 | 2147 | 9526 | 5911 | 8999 | 1850 | +| activity | 42 | 353 | 279 | 4666 | 16327 | 13357 | 28858 | 4356 | +|----------+--------+---------+-----------------+--------+-----------+------------+--------+----------| +| / | < | | > | < | > | < | | > | +| | | | | | | | | | Parsing large amounts of binary data. For JSON & XML base64 encoding was used. Note that the results below include only the parsing time, base64 decoding was not performed. -| input: | PSYC | | JSON | | | XML | | -| parser: | strlen | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml | +| | strlen | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml | |---------+----------+---------+-----------+------------+------------+-----------+----------| | 7K | 978 | 77 | 18609 | 98000 | 11445 | 19299 | 8701 | | 70K | 9613 | 77 | 187540 | 1003900 | 96209 | 167738 | 74296 | From 019b069af21af806b49745e2eda41f9d3f5e2b6f Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sat, 28 May 2011 20:24:36 +0200 Subject: [PATCH 295/378] doc: internal functions --- include/psyc/packet.h | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/include/psyc/packet.h b/include/psyc/packet.h index 94d16f3..3767b62 100644 --- a/include/psyc/packet.h +++ b/include/psyc/packet.h @@ -92,7 +92,10 @@ typedef struct psycPacketFlag flag; ///< Packet flag. } psycPacket; -/** Check if a modifier needs length. */ +/** + * \internal + * Check if a modifier needs length. + */ static inline psycModifierFlag psyc_checkModifierLength (psycModifier *m) { @@ -137,13 +140,19 @@ psycModifier psyc_newModifier2 (char oper, /** Get the total length of a modifier when rendered. */ size_t psyc_getModifierLength (psycModifier *m); -/** Check if a list needs length. */ +/** + * \internal + * Check if a list needs length. + */ psycListFlag psyc_checkListLength (psycList *list); /** Get the total length of a list when rendered. */ psycListFlag psyc_getListLength (psycList *list); -/** Check if a packet needs length. */ +/** + * \internal + * Check if a packet needs length. + */ psycPacketFlag psyc_checkPacketLength (psycPacket *p); /** Calculate and set the rendered length of packet parts and total packet length. */ From 20daced691ed516755a0b4a5bbc93e447a55a63b Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sat, 28 May 2011 20:29:19 +0200 Subject: [PATCH 296/378] doc: internal functions --- include/psyc/packet.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/include/psyc/packet.h b/include/psyc/packet.h index 3767b62..5407ba2 100644 --- a/include/psyc/packet.h +++ b/include/psyc/packet.h @@ -137,7 +137,10 @@ psycModifier psyc_newModifier2 (char oper, return psyc_newModifier(oper, &n, &v, flag); } -/** Get the total length of a modifier when rendered. */ +/** + * \internal + * Get the total length of a modifier when rendered. + */ size_t psyc_getModifierLength (psycModifier *m); /** @@ -146,7 +149,10 @@ size_t psyc_getModifierLength (psycModifier *m); */ psycListFlag psyc_checkListLength (psycList *list); -/** Get the total length of a list when rendered. */ +/** + * \internal + * Get the total length of a list when rendered. + */ psycListFlag psyc_getListLength (psycList *list); /** @@ -155,7 +161,9 @@ psycListFlag psyc_getListLength (psycList *list); */ psycPacketFlag psyc_checkPacketLength (psycPacket *p); -/** Calculate and set the rendered length of packet parts and total packet length. */ +/** + * Calculate and set the rendered length of packet parts and total packet length. + */ size_t psyc_setPacketLength (psycPacket *p); /** Create new list. */ From 7e64a5e53f2acd7a000b52a5eb8e7ecd67d339f8 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sat, 28 May 2011 20:38:53 +0200 Subject: [PATCH 297/378] + --- include/psyc/parse.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/psyc/parse.h b/include/psyc/parse.h index 340eba6..919c1c1 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -290,7 +290,7 @@ void psyc_setParseFlags (psycParseState *state, uint8_t flags) if (flags & PSYC_PARSE_START_AT_CONTENT) state->part = PSYC_PART_CONTENT; else - state->part = 0; + state->part = PSYC_PART_ROUTING; } From d4b5ec28677ad0468fa96999f1972f92f5452116 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 30 May 2011 04:05:13 +0200 Subject: [PATCH 298/378] dox: extract static --- Doxyfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doxyfile b/Doxyfile index a05f707..38a7fa8 100644 --- a/Doxyfile +++ b/Doxyfile @@ -338,7 +338,7 @@ EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. -EXTRACT_STATIC = NO +EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. From c5cfa7e119e301348a69d0480e6ad1d69baea3b3 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Thu, 2 Jun 2011 13:25:48 +0200 Subject: [PATCH 299/378] more test packets & additional testPsyc debug msgs --- test/packets/00-body-only | 4 ++++ test/packets/00-empty | 1 + test/packets/00-length-body-only | 4 ++++ test/packets/00-length-no-entity | 6 ++++++ test/packets/00-method-only-1 | 3 +++ test/testPsyc.c | 2 ++ 6 files changed, 20 insertions(+) create mode 100644 test/packets/00-body-only create mode 100644 test/packets/00-empty create mode 100644 test/packets/00-length-body-only create mode 100644 test/packets/00-length-no-entity create mode 100644 test/packets/00-method-only-1 diff --git a/test/packets/00-body-only b/test/packets/00-body-only new file mode 100644 index 0000000..116d391 --- /dev/null +++ b/test/packets/00-body-only @@ -0,0 +1,4 @@ + +_message_private +OHAI +| diff --git a/test/packets/00-empty b/test/packets/00-empty new file mode 100644 index 0000000..948cf94 --- /dev/null +++ b/test/packets/00-empty @@ -0,0 +1 @@ +| diff --git a/test/packets/00-length-body-only b/test/packets/00-length-body-only new file mode 100644 index 0000000..22e96eb --- /dev/null +++ b/test/packets/00-length-body-only @@ -0,0 +1,4 @@ +22 +_message_private +OHAI +| diff --git a/test/packets/00-length-no-entity b/test/packets/00-length-no-entity new file mode 100644 index 0000000..27785b5 --- /dev/null +++ b/test/packets/00-length-no-entity @@ -0,0 +1,6 @@ +:_source psyc://foo.example.com/ +:_target psyc://bar.example.com/ +22 +_message_private +OHAI +| diff --git a/test/packets/00-method-only-1 b/test/packets/00-method-only-1 new file mode 100644 index 0000000..0da4d2f --- /dev/null +++ b/test/packets/00-method-only-1 @@ -0,0 +1,3 @@ + +_ +| diff --git a/test/testPsyc.c b/test/testPsyc.c index 087beaf..f49922a 100644 --- a/test/testPsyc.c +++ b/test/testPsyc.c @@ -80,6 +80,8 @@ int test_input (int i, char *recvbuf, size_t nbytes) { value.length = 0; do { + if (verbose >= 3) + printf("\n# buffer = [%.*s]\n# part = %d\n", (int)parsers[i].buffer.length, parsers[i].buffer.ptr, parsers[i].part); // Parse the next part of the packet (a routing/entity modifier or the body) ret = exit_code = psyc_parse(&parsers[i], &oper, &name, &value); if (verbose >= 2) From c0b78df2ba7ba0bb76a78fe8873102f8bbef1de4 Mon Sep 17 00:00:00 2001 From: Marenz Date: Thu, 2 Jun 2011 14:58:39 +0200 Subject: [PATCH 300/378] removed setParseFlags from the D-binding --- d/include/psyc/parse.d | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/d/include/psyc/parse.d b/d/include/psyc/parse.d index adb9acd..dcc1015 100644 --- a/d/include/psyc/parse.d +++ b/d/include/psyc/parse.d @@ -159,25 +159,6 @@ struct ParseState return psyc_parse(this, &oper, cast(String*) &name, cast(String*) &value); } - /** - * Change parse flags in state - * - * Params: - * state = Pointer to the state struct that should be initialized. - * flags = Flags to be set for the parser, see psycParseFlag. - * - * See_Also: psyc_initParseState psycParseFlag - */ - void setParseFlags (ParseFlag flags) - { - this.flags = flags; - - if (flags & ParseFlag.START_AT_CONTENT) - this.part = Part.CONTENT; - else - this.part = Part.ROUTING; - } - /** * Sets a new buffer in the parser state struct with data to be parsed. * @@ -265,6 +246,7 @@ struct ParseState void getRemainingBuffer ( ref ubyte[] buf ) { + buf = this.buffer.ptr[cursor .. cursor + getRemainingLength()]; } From f6673f821065ce8e34b932e979ae2670bf3bcb39 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Thu, 2 Jun 2011 15:01:26 +0200 Subject: [PATCH 301/378] removed setParseFlags --- include/psyc/parse.h | 29 +++-------------------------- 1 file changed, 3 insertions(+), 26 deletions(-) diff --git a/include/psyc/parse.h b/include/psyc/parse.h index 919c1c1..08eacc4 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -40,9 +40,7 @@ * char* raw_data; // points to our (possibly incomplete) packet * size_t raw_len; // how many bytes of data * - * psyc_setParseBuffer(&state, // our initialized state from before - * raw_data, - * raw_len); + * psyc_setParseBuffer(&state, raw_data, raw_len); // state is our initialized state from before * @endcode * * Now the the variables that will save the output of the parser need to be @@ -179,10 +177,10 @@ typedef enum /// Start of an incomplete content, value contains part of content. /// Used when PSYC_PARSE_ROUTING_ONLY is set. PSYC_PARSE_CONTENT_START = 7, - /// Continuation of an incomplete body. + /// Continuation of an incomplete content. /// Used when PSYC_PARSE_ROUTING_ONLY is set. PSYC_PARSE_CONTENT_CONT = 8, - /// End of an incomplete body. + /// End of an incomplete content. /// Used when PSYC_PARSE_ROUTING_ONLY is set. PSYC_PARSE_CONTENT_END = 9, /// Content parsing done in one go, value contains the whole content. @@ -274,27 +272,6 @@ void psyc_initParseState2 (psycParseState *state, uint8_t flags) state->part = PSYC_PART_CONTENT; } -/** - * Change parse flags in state - * - * @param state Pointer to the state struct that should be initialized. - * @param flags Flags to be set for the parser, see psycParseFlag. - * @see psyc_initParseState - * @see psycParseFlag - */ -static inline -void psyc_setParseFlags (psycParseState *state, uint8_t flags) -{ - state->flags = flags; - - if (flags & PSYC_PARSE_START_AT_CONTENT) - state->part = PSYC_PART_CONTENT; - else - state->part = PSYC_PART_ROUTING; -} - - - /** * Sets a new buffer in the parser state struct with data to be parsed. * From 5583e9ca9c2916419da6569e0803c68f03948da7 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Thu, 2 Jun 2011 15:07:11 +0200 Subject: [PATCH 302/378] testPsyc: +debug msg --- test/testPsyc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/testPsyc.c b/test/testPsyc.c index f49922a..43e969e 100644 --- a/test/testPsyc.c +++ b/test/testPsyc.c @@ -190,6 +190,8 @@ int test_input (int i, char *recvbuf, size_t nbytes) { contbytes = psyc_getParseRemainingLength(&parsers[i]); if (contbytes > 0) { // copy end of parsebuf before start of recvbuf + if (verbose >= 3) + printf("# remaining = [%.*s]\n", (int)contbytes, psyc_getParseRemainingBuffer(&parsers[i])); assert(contbytes <= CONT_BUF_SIZE); // make sure it's still in the buffer memmove(recvbuf - contbytes, psyc_getParseRemainingBuffer(&parsers[i]), contbytes); } From 2da15e5d4b5a65dc33610277ef642ace1c12ef3d Mon Sep 17 00:00:00 2001 From: Mathias Laurenz Baumann Date: Thu, 2 Jun 2011 21:59:00 +0200 Subject: [PATCH 303/378] added rudimentary binding for render.h --- d/include/psyc/packet.d | 182 ++++++++++++++++++++++++++++++++++++++++ d/include/psyc/render.d | 57 +++++++++++++ d/include/psyc/syntax.d | 36 ++++++++ 3 files changed, 275 insertions(+) create mode 100644 d/include/psyc/packet.d create mode 100644 d/include/psyc/render.d create mode 100644 d/include/psyc/syntax.d diff --git a/d/include/psyc/packet.d b/d/include/psyc/packet.d new file mode 100644 index 0000000..b9584cb --- /dev/null +++ b/d/include/psyc/packet.d @@ -0,0 +1,182 @@ + /* + * Packet data structures and functions for creating them are defined here. + */ + +module psyc.packet; + +import psyc.common; +import psyc.syntax; + + +/** Modifier flags. */ +enum ModifierFlag +{ + /// Modifier needs to be checked if it needs length. + CHECK_LENGTH = 0, + /// Modifier needs length. + NEED_LENGTH = 1, + /// Modifier doesn't need length. + NO_LENGTH = 2, + /// Routing modifier, which implies that it doesn't need length. + ROUTING = 3, +}; + +/** List flags. */ +enum ListFlag +{ + /// List needs to be checked if it needs length. + CHECK_LENGTH = 0, + /// List needs length. + NEED_LENGTH = 1, + /// List doesn't need length. + NO_LENGTH = 2, +} ; + +/** Packet flags. */ +enum PacketFlag +{ + /// Packet needs to be checked if it needs content length. + CHECK_LENGTH = 0, + /// Packet needs content length. + NEED_LENGTH = 1, + /// Packet doesn't need content length. + NO_LENGTH = 2, +} ; + +/** Structure for a modifier. */ +struct Modifier +{ + char oper; + String name; + String value; + ModifierFlag flag; +} ; + +/** Structure for an entity or routing header. */ +struct Header +{ + size_t lines; + Modifier *modifiers; +} ; + +/** Structure for a list. */ +struct List +{ + size_t num_elems; + String *elems; + size_t length; + ListFlag flag; +} ; + +/** intermediate struct for a PSYC packet */ +struct Packet +{ + Header routing; ///< Routing header. + Header entity; ///< Entity header. + String method; ///< Contains the method. + String data; ///< Contains the data. + String content; ///< Contains the whole content. + size_t routingLength; ///< Length of routing part. + size_t contentLength; ///< Length of content part. + size_t length; ///< Total length of packet. + PacketFlag flag; ///< Packet flag. +} ; + +/** + * \internal + * Check if a modifier needs length. + */ + +ModifierFlag psyc_checkModifierLength (Modifier *m) +{ + ModifierFlag flag; + + if (m->value.length > PSYC_MODIFIER_SIZE_THRESHOLD) + flag = ModifierFlag.NEED_LENGTH; + else if (memchr(m->value.ptr, (int)'\n', m->value.length)) + flag = ModifierFlag.NEED_LENGTH; + else + flag = ModifierFlag.NO_LENGTH; + + return flag; +} + +/** Create new modifier. */ + +Modifier psyc_newModifier (char oper, String *name, String *value, + ModifierFlag flag) +{ + Modifier m = {oper, *name, *value, flag}; + + if (flag == ModifierFlag.CHECK_LENGTH) // find out if it needs a length + m.flag = psyc_checkModifierLength(&m); + + return m; +} + +/** Create new modifier */ +Modifier psyc_newModifier2 (char oper, + char *name, size_t namelen, + char *value, size_t valuelen, + ModifierFlag flag) +{ + String n = {namelen, name}; + String v = {valuelen, value}; + + return psyc_newModifier(oper, &n, &v, flag); +} + +/** + * \internal + * Get the total length of a modifier when rendered. + */ +size_t psyc_getModifierLength (Modifier *m); + +/** + * \internal + * Check if a list needs length. + */ +ListFlag psyc_checkListLength (List *list); + +/** + * \internal + * Get the total length of a list when rendered. + */ +ListFlag psyc_getListLength (List *list); + +/** + * \internal + * Check if a packet needs length. + */ +PacketFlag psyc_checkPacketLength (Packet *p); + +/** + * Calculate and set the rendered length of packet parts and total packet length. + */ +size_t psyc_setPacketLength (Packet *p); + +/** Create new list. */ +List psyc_newList (String *elems, size_t num_elems, ListFlag flag); + +/** Create new packet. */ +Packet psyc_newPacket (Header *routing, + Header *entity, + String *method, String *data, + PacketFlag flag); + +/** Create new packet. */ +Packet psyc_newPacket2 (Modifier *routing, size_t routinglen, + Modifier *entity, size_t entitylen, + char *method, size_t methodlen, + char *data, size_t datalen, + PacketFlag flag); + +/** Create new packet with raw content. */ +Packet psyc_newRawPacket (Header *routing, String *content, + PacketFlag flag); + +/** Create new packet with raw content. */ +Packet psyc_newRawPacket2 (Modifier *routing, size_t routinglen, + char *content, size_t contentlen, + PacketFlag flag); + diff --git a/d/include/psyc/render.d b/d/include/psyc/render.d new file mode 100644 index 0000000..f12bbbe --- /dev/null +++ b/d/include/psyc/render.d @@ -0,0 +1,57 @@ +module psyc.render; + +import psyc.packet; + + /* + * All rendering functions and the definitions they use are defined here. + */ + +/** + * Return codes for psyc_render. + */ +enum RenderRC +{ + /// Error, method is missing, but data is present. + ERROR_METHOD_MISSING = -3, + /// Error, a modifier name is missing. + ERROR_MODIFIER_NAME_MISSING = -2, + /// Error, buffer is too small to render the packet. + ERROR = -1, + /// Packet is rendered successfully in the buffer. + SUCCESS = 0, +} ; + +/** + * Return codes for psyc_renderList. + */ +enum RenderListRC +{ + /// Error, buffer is too small to render the list. + ERROR = -1, + /// List is rendered successfully in the buffer. + SUCCESS = 0, +}; + +/** + * Render a PSYC packet into a buffer. + * + * The packet structure should contain the packet parts, either routing, entity, + * method & data, or routing & content when rendering raw content. + * It should also contain the contentLength & total length of the packet, + * you can use psyc_setPacketLength() for calculating & setting these values. + * This function renders packet->length bytes to the buffer, + * if buflen is less than that an error is returned. + * + * @see psyc_newPacket + * @see psyc_newPacket2 + * @see psyc_newRawPacket + * @see psyc_newRawPacket2 + * @see psyc_setPacketLength + */ +RenderRC psyc_render (Packet *packet, char *buffer, size_t buflen); + +/** + * Render a PSYC list into a buffer. + */ +RenderListRC psyc_renderList (List *list, char *buffer, size_t buflen); + diff --git a/d/include/psyc/syntax.d b/d/include/psyc/syntax.d new file mode 100644 index 0000000..a5fcfe3 --- /dev/null +++ b/d/include/psyc/syntax.d @@ -0,0 +1,36 @@ +module psyc.syntax; + +const PSYC_LIST_SIZE_LIMIT = 404; + +/* beyond this a content length must be provided */ +const = PSYC_CONTENT_SIZE_THRESHOLD = 444; + +/* beyond this a modifier value length must be provided */ +const PSYC_MODIFIER_SIZE_THRESHOLD = 404; + +const C_GLYPH_PACKET_DELIMITER = '|'; +const S_GLYPH_PACKET_DELIMITER = "|"; +const PSYC_PACKET_DELIMITER = "\n|\n"; + +const C_GLYPH_SEPARATOR_KEYWORD = '_'; +const S_GLYPH_SEPARATOR_KEYWORD = "_"; + +const C_GLYPH_OPERATOR_SET = ':'; +const S_GLYPH_OPERATOR_SET = ":"; + +const C_GLYPH_OPERATOR_ASSIGN = '='; +const S_GLYPH_OPERATOR_ASSIGN = "="; + +const C_GLYPH_OPERATOR_AUGMENT = '+'; +const S_GLYPH_OPERATOR_AUGMENT = "+"; + +const C_GLYPH_OPERATOR_DIMINISH = '-'; +const S_GLYPH_OPERATOR_DIMINISH = "-"; + +const C_GLYPH_OPERATOR_QUERY = '?'; +const S_GLYPH_OPERATOR_QUERY = "?"; + +/* might move into routing.h or something */ +const PSYC_ROUTING = 1; +const PSYC_ROUTING_MERGE = 2; +const PSYC_ROUTING_RENDER = 4; From 3d4aeac8ba1f2c3142c8d006e6c49030e8dce118 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sun, 5 Jun 2011 10:44:34 +0200 Subject: [PATCH 304/378] make .so --- src/Makefile | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/Makefile b/src/Makefile index 3ef9d67..822ccfa 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,12 +1,15 @@ OPT = -O2 DEBUG = 2 -CFLAGS = -I../include -Wall -std=c99 ${OPT} +CFLAGS = -I../include -Wall -std=c99 -fPIC ${OPT} DIET = diet S = packet.c parse.c match.c render.c memmem.c itoa.c variable.c text.c O = packet.o parse.o match.o render.o memmem.o itoa.o variable.o text.o P = match itoa +A = ../lib/libpsyc.a +SO = ../lib/libpsyc.so + all: CC := ${WRAPPER} ${CC} all: lib @@ -18,9 +21,15 @@ diet: WRAPPER = ${DIET} diet: CC := ${WRAPPER} ${CC} diet: lib -lib: $O +lib: $O $A ${SO} + +${SO}: @mkdir -p ../lib - ${WRAPPER} ${AR} rcs ../lib/libpsyc.a $O + ${CC} ${CFLAGS} -shared -lm -o $@ $O + +$A: + @mkdir -p ../lib + ${WRAPPER} ${AR} rcs $@ $O match: match.c ${CC} -o $@ -DDEBUG=4 -DCMDTOOL -DTEST $< From 22a97266fbf9835c4955042e0d7ae7f79a43ed8b Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Sat, 11 Jun 2011 08:48:38 +0200 Subject: [PATCH 305/378] reasoning why XML namespaces aren't better.. they're just very verbose --- bench/benchmark.org | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/bench/benchmark.org b/bench/benchmark.org index 798bd36..805f3fb 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -106,7 +106,7 @@ instead it allows for more addressing schemes than just PSYC. ** A new status updated activity Example taken from http://onesocialweb.org/spec/1.0/osw-activities.html -You could call this XML namespace hell: +You could call this XML namespace hell.. :-) #+INCLUDE: packets/activity.xml src xml @@ -122,6 +122,16 @@ We'll use the latter here: #+INCLUDE: packets/activity.psyc src psyc +It's nice about XML namespaces how they can by definition never collide, +but this degree of engineering perfection causes us a lot of overhead. +The PSYC approach is to just extend the name of the method - as long as +people use differing method names, protocol extensions can exist next +to each other happily. Method name unicity cannot mathematically be ensured, +but it's enough to append your company name to make it unlikely for anyone +else on earth to have the same name. How this kind of safety is delivered +when using the JSON syntax of ActivityStreams is unclear. Apparently it was +no longer an important design criterion. + * Results Parsing time of 1 000 000 packets, in milliseconds. From a6810ec6e560b1e14ab4492c587f49af2d9af036 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Sat, 11 Jun 2011 09:19:14 +0200 Subject: [PATCH 306/378] + --- bench/benchmark.org | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bench/benchmark.org b/bench/benchmark.org index f67d5e1..2c4c0be 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -276,6 +276,9 @@ http://about.psyc.eu/Spec:Syntax provides you with the ABNF grammar of the PSYC 1.0 syntax. You may also be interested in PSYC's decentralized state mechanism provided by the +/-/= operators. +See http://about.psyc.eu/XML and http://about.psyc.eu/JSON for more +biased information on the respective formats. + * Appendix ** Tools used From dfdb0f74661d6d83340c85bd9eac5526c5824a69 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sun, 12 Jun 2011 11:54:21 +0200 Subject: [PATCH 307/378] license note --- README | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README b/README index a3ef4a9..44f6420 100644 --- a/README +++ b/README @@ -71,9 +71,9 @@ developement room at xmpp:*welcome@psyced.org irc://psyced.org/welcome -== Licence == +== License == --- To be discussed -- +See the LICENSE file. == Style Wars == From 47d77a4ea98763522755c02331713f8df3ded215 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sun, 12 Jun 2011 12:40:08 +0200 Subject: [PATCH 308/378] orgified readme --- README | 84 ------------------------------------------------- README.org | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 84 deletions(-) delete mode 100644 README create mode 100644 README.org diff --git a/README b/README deleted file mode 100644 index 44f6420..0000000 --- a/README +++ /dev/null @@ -1,84 +0,0 @@ -= libpsyc README file = - -libpsyc implements various functions required to use PSYC. - -See http://about.psyc.eu/libpsyc for more information on the library. -See http://about.psyc.eu/Specification for more information - on the new PSYC specification. -See http://about.psyc.eu for information on PSYC in general. - -The plain C API located in the include/psyc directory along with the file psyc.h -is primarily intended to be used for binding with other languages and frameworks. - -The LPC binding for psyced is distributed with psyclpc since it is spread -over several files (LPC has no simple approach to binding). Other bindings -are located directly in the root folder named according to the language or -framework. Currently there's only a binding for D. - -== C API == - -The "plain C API" is a very low-level API intended to be used for bindings. -To access a certain module of the library, just include the according header -file from the psyc directory: - -psyc.h -- basic things for well-being -psyc/parse.h -- parse psyc packets -psyc/render.h -- render psyc packets -psyc/text.h -- text template functions -psyc/packet.h -- structures for render.h and functions to initialize them -psyc/syntax.h -- definitions and constants related to parsing and rendering - -== Directory Overview == - -doc -- target folder for the documentation after generation (make doc) -include -- the core C API for the library -lib -- target folder for the compiled library (make) -src -- the sourcecode of the library -test -- test sourcecodes and test input files -d -- the D binding - -== Compiling libpsyc == - -Type - - make - -and you are done. -Other possible targets include: - - make diet -- compile with diet libc - make test -- compile and run the test - make doc -- generate the API documentation (will be put in the doc folder) - make help -- display the possible targets - -== Requirements == - -libpsyc is currently known to compile under Linux and SunOS. - -== Contributors And Contribution == - -The library is being developed by - -* tg -- psyc://tgbit.net/~tg -* lynx -- psyc://psyced.org/~lynx -* Marenz -- psyc://supraverse.net/~marenz - -If you created new bindings, patches or anything other that you think should go -into the library, contact either anyone of us directly or just join the -developement room at - - psyc://psyced.org/@welcome - xmpp:*welcome@psyced.org - irc://psyced.org/welcome - -== License == - -See the LICENSE file. - -== Style Wars == - -This source code should follow the http://about.psyc.eu/Indent conventions. - (if you have good reasons to use another style, discuss it on the - wiki page so that it becomes the general style convention for all - of us, not just for you). - diff --git a/README.org b/README.org new file mode 100644 index 0000000..51f1644 --- /dev/null +++ b/README.org @@ -0,0 +1,91 @@ +#+TITLE: libpsyc README file +#+OPTIONS: toc:nil num:nil + +* About + +libpsyc implements various functions required to use PSYC. + +- See http://about.psyc.eu/libpsyc for more information on the library. +- See http://lib.psyc.eu/doc/ for the API documentation. +- See http://about.psyc.eu/Specification for more information on the new PSYC + specification. +- See http://about.psyc.eu for information on PSYC in general. + +The plain C API located in the include/psyc directory along with the file psyc.h +is primarily intended to be used for binding with other languages and frameworks. + +The LPC binding for psyced is distributed with psyclpc since it is spread +over several files (LPC has no simple approach to binding). Other bindings +are located directly in the root folder named according to the language or +framework. Currently there's only a binding for D. + +* C API + +The "plain C API" is a very low-level API intended to be used for bindings. +To access a certain module of the library, just include the according header +file from the psyc directory: + +: #include // basic things for well-being +: #include // parse psyc packets +: #include // render psyc packets +: #include // text template functions +: #include // structures for render.h and functions to initialize them +: #include // definitions and constants related to parsing and rendering + +For more information see the API documentation at [[http://lib.psyc.eu/doc/]]. + +* Directory Overview + +: doc/ # target folder for the documentation after generation (make doc) +: include/ # the core C API for the library +: lib/ # target folder for the compiled library (make) +: src/ # the sourcecode of the library +: test/ # test sourcecodes and test input files +: d/ # the D binding + +* Compiling libpsyc + +Type +: make + +and you are done. +Other possible targets include: + +: make install [prefix=/usr] # install into prefix +: make diet # compile with diet libc +: make test # compile and run the tests +: make doc # generate the API documentation (will be put in the doc folder) +: make help # display the possible targets + +* Requirements + +libpsyc is currently known to compile under Linux and SunOS. + +* Authors + +The library is being developed by + +- tg -- psyc://tgbit.net/~tg +- lynx -- psyc://psyced.org/~lynx +- Marenz -- psyc://supraverse.net/~marenz + +* Contact + +If you created new bindings, patches or anything other that you think should go +into the library, contact either anyone of us directly or just join the +developement room at + +- psyc://psyced.org/@welcome +- xmpp:*welcome@psyced.org +- irc://psyced.org/welcome + +* License + +This library is distributed under the MIT license, see the LICENSE file for details. + +* Style Wars + +This source code should follow the http://about.psyc.eu/Indent conventions. +(if you have good reasons to use another style, discuss it on the +wiki page so that it becomes the general style convention for all +of us, not just for you). From b48d226e8014eea6a23f50599616ba1fe6ad97ac Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sun, 12 Jun 2011 12:52:27 +0200 Subject: [PATCH 309/378] pike binding by fippo --- pike/Makefile | 14 +++ pike/README | 6 ++ pike/parsetest.pike | 11 +++ pike/psyc.cmod | 209 +++++++++++++++++++++++++++++++++++++++++++ pike/rendertest.pike | 8 ++ 5 files changed, 248 insertions(+) create mode 100644 pike/Makefile create mode 100644 pike/README create mode 100644 pike/parsetest.pike create mode 100644 pike/psyc.cmod create mode 100644 pike/rendertest.pike diff --git a/pike/Makefile b/pike/Makefile new file mode 100644 index 0000000..8e114cb --- /dev/null +++ b/pike/Makefile @@ -0,0 +1,14 @@ +CC=gcc +CFLAGS := -O9 -shared -Wall -fPIC -I/usr/include/pike $(CFLAGS) $(shell $(PIKE) -x cflags) +LD=$(CC) -shared -lpsyc + +all: module.so + +module.so: module.o + $(LD) -o module.so module.o $(LDFLAGS) + +module.o: module.c + $(CC) $(CFLAGS) -c module.c + +module.c: psyc.cmod + $(PIKE) -x precompile $< > $@ diff --git a/pike/README b/pike/README new file mode 100644 index 0000000..ab3db07 --- /dev/null +++ b/pike/README @@ -0,0 +1,6 @@ +to compile the cmod: +pike -x module + +to run the code: +pike -M. rendertest.pike +pike -M. parsetest.pike diff --git a/pike/parsetest.pike b/pike/parsetest.pike new file mode 100644 index 0000000..86321e8 --- /dev/null +++ b/pike/parsetest.pike @@ -0,0 +1,11 @@ +int main() { + .Parser p = Parser(); + p->feed(":_source\tpsyc://nb.tgbit.net/~foo\n" + ":_target\tpsyc://nb2.tgbit.net/~bar\n" + ":_tag\tf00b4rb4z\n" + "\n" + ":_foo\tbar\n" + "_message_private\n" + "OHAI\n" + "|\n"); +} diff --git a/pike/psyc.cmod b/pike/psyc.cmod new file mode 100644 index 0000000..d29b67c --- /dev/null +++ b/pike/psyc.cmod @@ -0,0 +1,209 @@ +#include "global.h" +#include "interpret.h" +#include "stralloc.h" +#include "mapping.h" +#include "svalue.h" +#include "operators.h" +#include "array.h" +#include "builtin_functions.h" +#include "module.h" + +#include +#ifndef DEFAULT_CMOD_STORAGE +#define DEFAULT_CMOD_STORAGE +#endif + +// libpsyc dependencies +# include +# include +# include + +#define MODULE_NAME "PSYC" +#define MODULE_MAJOR 0 +#define MODULE_MINOR 1 +#define MODULE_PATCH 0 + +/*! @module PSYC + *! + *! Implements PSYC parsing and rendering based on libpsyc + *! FIXME: parser not implemented yet + *! + */ + +/*! @decl string render(mapping rvars, mapping evars, string method, string|void body) + *! @param rvars + *! FIXME + *! @param evars + *! FIXME + *! @param method + *! FIXME + *! @param data + *! FIXME + *! @returns + *! serialized packet as a string + */ +PIKEFUN string render(mapping rvars, mapping evars, string method, string|void body) { + char buffer[1024*1024]; // static buffer, FIXME + psycPacket packet; + psycHeader rheaders, eheaders; + + struct keypair *k; // for mappings + INT32 e; + + char oper = C_GLYPH_OPERATOR_SET; + + // fill headers + rheaders.lines = 0; + rheaders.modifiers = malloc(sizeof(psycModifier) * rvars->data->size); + NEW_MAPPING_LOOP(rvars->data) { + if (k->ind.type == PIKE_T_STRING) { + switch(k->val.type) { + case PIKE_T_INT: + printf("integer value %ld\n", k->val.u.integer); + break; + case PIKE_T_FLOAT: + printf("float value %f\n", k->val.u.float_number); + break; + case PIKE_T_STRING: + rheaders.modifiers[rheaders.lines++] = psyc_newModifier2(oper, + (char *)STR0(k->ind.u.string), + k->ind.u.string->len, + (char *)STR0(k->val.u.string), + k->val.u.string->len, + PSYC_MODIFIER_ROUTING); + break; + case PIKE_T_MAPPING: + printf("mapping value length %d\n", k->val.u.mapping->data->size); + // another walk_mapping? + break; + case PIKE_T_ARRAY: + printf("array value length %d\n", k->val.u.array->size); + /* + for(e = 0; e < data->u.array->size; e++) { + struct svalue item = data->u.array->item[e]; + inner_serialize2(&item, sb); + } + */ + break; + default: + break; + } + } else { + Pike_error("psyc render: unsupported non-string key in rvars\n"); + } + } + + eheaders.lines = 0; + eheaders.modifiers = malloc(sizeof(psycModifier) * evars->data->size); + NEW_MAPPING_LOOP(evars->data) { + if (k->ind.type == PIKE_T_STRING) { + char *key; + size_t keylen; + char *val = NULL; + size_t vallen = 0; + + key = (char *) STR0(k->ind.u.string); + keylen = k->ind.u.string->len; + + switch(k->val.type) { + case PIKE_T_INT: + printf("integer value %ld\n", k->val.u.integer); + break; + case PIKE_T_STRING: + val = (char *) STR0(k->ind.u.string); + vallen = k->ind.u.string->len; + break; + case PIKE_T_FLOAT: + printf("float value %f\n", k->val.u.float_number); + break; + case PIKE_T_MAPPING: + printf("mapping value length %d\n", k->val.u.mapping->data->size); + // another walk_mapping? + break; + case PIKE_T_ARRAY: + printf("array value length %d\n", k->val.u.array->size); + /* + for(e = 0; e < data->u.array->size; e++) { + struct svalue item = data->u.array->item[e]; + inner_serialize2(&item, sb); + } + */ + break; + default: + break; + } + eheaders.modifiers[eheaders.lines++] = psyc_newModifier2(oper, + key, keylen, + val, vallen, + PSYC_MODIFIER_CHECK_LENGTH); + } else { + Pike_error("psyc render: unsupported non-string key in evars\n"); + } + } + + if (body != NULL) { + packet = psyc_newPacket2(rheaders.modifiers, + rheaders.lines, + eheaders.modifiers, + eheaders.lines, + (const char *)STR0(method), method->len, + (const char *)STR0(body), body->len, + PSYC_PACKET_CHECK_LENGTH); + } else { // body arg was not given + packet = psyc_newPacket2(rheaders.modifiers, + rheaders.lines, + eheaders.modifiers, + eheaders.lines, + (const char *)STR0(method), method->len, + NULL, 0, + PSYC_PACKET_CHECK_LENGTH); + } + + /* + FIXME: how to allocate space and pass it to libpsyc? + string builder probably + */ + psyc_render(&packet, buffer, packet.length); + // pop_n_elems(args); + RETURN make_shared_binary_string(buffer, packet.length); +} + +PIKECLASS Parser { + CVAR psycParseState parser; + + INIT { + psyc_initParseState(&THIS->parser); + } + + EXIT { + + } + + PIKEFUN void feed(string data) { + char oper; + psycString name, value; + int ret; + + psyc_setParseBuffer2(&THIS->parser, + (char *) STR0(data), data->len); + for (;;) { + printf("looping...\n"); + ret = psyc_parse(&THIS->parser, &oper, &name, &value); + if (ret == PSYC_PARSE_COMPLETE || ret < 0) { + break; + } + } + printf("down here\n"); + } + +} + +INIT { + +} + +EXTRA { + add_integer_constant("__version_major", MODULE_MAJOR, 0); + add_integer_constant("__version_minor", MODULE_MAJOR, 0); + add_integer_constant("__version_patch", MODULE_MAJOR, 0); +} diff --git a/pike/rendertest.pike b/pike/rendertest.pike new file mode 100644 index 0000000..cb5c5cd --- /dev/null +++ b/pike/rendertest.pike @@ -0,0 +1,8 @@ +int main() { + werror("render:\n%s\---\n", + render( ([ "_context" : "psyc://denmark.lit/~hamlet#_follow" ]), + ([ "_type_content" : "text/plain", "_subject" : "to be or not to be ?", + "_bla" : 123 ]), + "_message", + "to be or not to be ?")); +} From e612a5bac6211249570088f9a07c415579fe8628 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sun, 12 Jun 2011 13:02:33 +0200 Subject: [PATCH 310/378] + --- README.org | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.org b/README.org index 51f1644..320428e 100644 --- a/README.org +++ b/README.org @@ -5,11 +5,11 @@ libpsyc implements various functions required to use PSYC. -- See http://about.psyc.eu/libpsyc for more information on the library. -- See http://lib.psyc.eu/doc/ for the API documentation. -- See http://about.psyc.eu/Specification for more information on the new PSYC - specification. -- See http://about.psyc.eu for information on PSYC in general. +See http://about.psyc.eu/libpsyc for more information on the library. \\ +See http://lib.psyc.eu/doc/ for the API documentation. \\ +See http://about.psyc.eu/Specification for more information on the new PSYC +specification. \\ +See http://about.psyc.eu for information on PSYC in general. The plain C API located in the include/psyc directory along with the file psyc.h is primarily intended to be used for binding with other languages and frameworks. From 5d4b1ba36fa7804c4c49db81921a515accce3e1c Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sun, 12 Jun 2011 13:05:17 +0200 Subject: [PATCH 311/378] + --- README.org | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.org b/README.org index 320428e..ac3b792 100644 --- a/README.org +++ b/README.org @@ -5,11 +5,11 @@ libpsyc implements various functions required to use PSYC. -See http://about.psyc.eu/libpsyc for more information on the library. \\ -See http://lib.psyc.eu/doc/ for the API documentation. \\ -See http://about.psyc.eu/Specification for more information on the new PSYC -specification. \\ -See http://about.psyc.eu for information on PSYC in general. +- See [[http://about.psyc.eu/libpsyc]] for more information on the library. +- See [[http://lib.psyc.eu/doc/]] for the API documentation. +- See [[http://about.psyc.eu/Specification]] for more information on the new PSYC + specification. +- See [[http://about.psyc.eu/]] for information on PSYC in general. The plain C API located in the include/psyc directory along with the file psyc.h is primarily intended to be used for binding with other languages and frameworks. From d4a56501f4b89a868f219cfe83e47bdfb0f057fa Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sun, 12 Jun 2011 13:08:24 +0200 Subject: [PATCH 312/378] + --- README.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.org b/README.org index ac3b792..22586fc 100644 --- a/README.org +++ b/README.org @@ -85,7 +85,7 @@ This library is distributed under the MIT license, see the LICENSE file for deta * Style Wars -This source code should follow the http://about.psyc.eu/Indent conventions. +This source code should follow the [[http://about.psyc.eu/Indent]] conventions. (if you have good reasons to use another style, discuss it on the wiki page so that it becomes the general style convention for all of us, not just for you). From ae281884f3d68f2cf18a07ac35aa78a47916b89d Mon Sep 17 00:00:00 2001 From: Mathias Laurenz Baumann Date: Sun, 12 Jun 2011 13:13:17 +0200 Subject: [PATCH 313/378] more work on the d binding --- d/include/psyc/common.d | 5 ++++- d/include/psyc/packet.d | 35 +++++++++++++++++++++++++++++++++-- d/include/psyc/render.d | 3 +++ 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/d/include/psyc/common.d b/d/include/psyc/common.d index b873bfa..8a39604 100644 --- a/d/include/psyc/common.d +++ b/d/include/psyc/common.d @@ -66,11 +66,14 @@ enum ListType LIST_BINARY = 2, } +/+ struct String { size_t length; ubyte *ptr; -} +}+/ + +alias char[] String; struct MatchVar { diff --git a/d/include/psyc/packet.d b/d/include/psyc/packet.d index b9584cb..9817ad3 100644 --- a/d/include/psyc/packet.d +++ b/d/include/psyc/packet.d @@ -8,6 +8,8 @@ import psyc.common; import psyc.syntax; +extern (C): + /** Modifier flags. */ enum ModifierFlag { @@ -46,11 +48,40 @@ enum PacketFlag /** Structure for a modifier. */ struct Modifier { - char oper; + char operator; String name; String value; ModifierFlag flag; -} ; + + static Modifier opCall ( char op, char[] nam, char[] val ) + { + Modifier v; + + with (v) + { + operator = op; + name = nam; + value = val; + } + + return v; + } + + bool opEquals ( ref Modifier n ) + { + return operator == n.operator && + value == n.value && + name == n.name; + } + + Modifier dup ( ) + { + auto v = M(operator, name.dup, value.dup); + return v; + } +}; + +alias Modifier M; /** Structure for an entity or routing header. */ struct Header diff --git a/d/include/psyc/render.d b/d/include/psyc/render.d index f12bbbe..c02a188 100644 --- a/d/include/psyc/render.d +++ b/d/include/psyc/render.d @@ -2,6 +2,9 @@ module psyc.render; import psyc.packet; + +extern (C): + /* * All rendering functions and the definitions they use are defined here. */ From e226eb784720e4c207acc39edd5520f7097d59d2 Mon Sep 17 00:00:00 2001 From: Marenz Date: Sun, 12 Jun 2011 14:16:39 +0200 Subject: [PATCH 314/378] rephrasing of a comment --- include/psyc/parse.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/psyc/parse.h b/include/psyc/parse.h index 08eacc4..9224c47 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -59,7 +59,7 @@ * repeatedly with various actions in between, depending on the return values. * * A simplified example follows, see test/testPsyc.c for actual code that - * handles incomplete packets too. + * handles incomplete packets as well. * * @code * From e4ac9c4552bc4606901bca41329b121044a5c807 Mon Sep 17 00:00:00 2001 From: Marenz Date: Sun, 12 Jun 2011 14:25:22 +0200 Subject: [PATCH 315/378] added comment for PSYC_PARSE_BODY --- include/psyc/parse.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/psyc/parse.h b/include/psyc/parse.h index 9224c47..5f1ed0c 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -165,12 +165,15 @@ typedef enum /// Entity modifier parsing done in one go. /// Operator, name & value contains the respective parts. PSYC_PARSE_ENTITY = 6, - /// Start of an incomplete body. + /// Start of an incomplete body. /// Name contains method, value contains part of the body. + /// Used when packet length is given PSYC_PARSE_BODY_START = 7, /// Continuation of an incomplete body. + /// Used when packet length is given PSYC_PARSE_BODY_CONT = 8, /// End of an incomplete body. + /// Used when packet length is given PSYC_PARSE_BODY_END = 9, /// Body parsing done in one go, name contains method, value contains body. PSYC_PARSE_BODY = 10, From ecafe7142090ec0272cccb8a73ba9b725356e1fe Mon Sep 17 00:00:00 2001 From: Mathias Laurenz Baumann Date: Sun, 12 Jun 2011 18:06:00 +0200 Subject: [PATCH 316/378] D-binding: more work on the rendering, removed unneeded functions, changed various other things --- d/include/psyc/common.d | 17 ++-- d/include/psyc/packet.d | 171 ++++++++++++++++++++++++---------------- d/include/psyc/parse.d | 56 ++++++------- d/include/psyc/render.d | 4 +- d/include/psyc/syntax.d | 2 +- 5 files changed, 141 insertions(+), 109 deletions(-) diff --git a/d/include/psyc/common.d b/d/include/psyc/common.d index 8a39604..ecaba77 100644 --- a/d/include/psyc/common.d +++ b/d/include/psyc/common.d @@ -11,11 +11,15 @@ const EPOCH = 1440444041; // 2015-08-24 21:20:41 CET (Monday) extern (C): -enum Bool +/+enum Bool { FALSE = 0, TRUE = 1, -} +}+/ + +alias bool Bool; +static const FALSE = false; +static const TRUE = true; /** * PSYC packet parts. @@ -73,7 +77,7 @@ struct String ubyte *ptr; }+/ -alias char[] String; +alias ubyte[] String; struct MatchVar { @@ -93,9 +97,12 @@ extern (C) MatchVar varTypes[]; /** * Get the type of variable name. */ -Bool psyc_isRoutingVar(char *name, size_t len); +Bool psyc_isRoutingVar (char[]* name); -alias psyc_isRoutingVar isRoutingVar; +bool isRoutingVar (char[] name) +{ + return psyc_isRoutingVar(&name); +} /** * Get the type of variable name. diff --git a/d/include/psyc/packet.d b/d/include/psyc/packet.d index 9817ad3..3846b3f 100644 --- a/d/include/psyc/packet.d +++ b/d/include/psyc/packet.d @@ -6,8 +6,9 @@ module psyc.packet; import psyc.common; import psyc.syntax; +import psyc.render; - +import tango.stdc.string : memchr; extern (C): /** Modifier flags. */ @@ -49,11 +50,17 @@ enum PacketFlag struct Modifier { char operator; - String name; + char[] name; String value; ModifierFlag flag; - static Modifier opCall ( char op, char[] nam, char[] val ) + static Modifier opCall ( char op, char[] nam, char[] val, + ModifierFlag flg = ModifierFlag.CHECK_LENGTH ) + { + return opCall(op, nam, cast(ubyte[])val, flg); + } + static Modifier opCall ( char op, char[] nam, ubyte[] val, + ModifierFlag flg = ModifierFlag.CHECK_LENGTH ) { Modifier v; @@ -62,11 +69,18 @@ struct Modifier operator = op; name = nam; value = val; + flag = (flg == ModifierFlag.CHECK_LENGTH) ? + checkLength(val) : flg; } return v; } + char[] valuestr ( ) + { + return cast(char[]) value; + } + bool opEquals ( ref Modifier n ) { return operator == n.operator && @@ -79,17 +93,29 @@ struct Modifier auto v = M(operator, name.dup, value.dup); return v; } + + size_t length ( ) + { + return psyc_getModifierLength (this); + } + + private ModifierFlag checkLength ( ubyte[] value ) + { + ModifierFlag flag; + + if (value.length > PSYC_MODIFIER_SIZE_THRESHOLD) + flag = ModifierFlag.NEED_LENGTH; + else if (memchr(value.ptr, cast(int)'\n', value.length)) + flag = ModifierFlag.NEED_LENGTH; + else + flag = ModifierFlag.NO_LENGTH; + + return flag; + } }; alias Modifier M; -/** Structure for an entity or routing header. */ -struct Header -{ - size_t lines; - Modifier *modifiers; -} ; - /** Structure for a list. */ struct List { @@ -102,66 +128,68 @@ struct List /** intermediate struct for a PSYC packet */ struct Packet { - Header routing; ///< Routing header. - Header entity; ///< Entity header. + Modifier[] routing; ///< Routing header. + Modifier[] entity; ///< Entity header. String method; ///< Contains the method. String data; ///< Contains the data. String content; ///< Contains the whole content. size_t routingLength; ///< Length of routing part. size_t contentLength; ///< Length of content part. - size_t length; ///< Total length of packet. + size_t _length; ///< Total length of packet. PacketFlag flag; ///< Packet flag. -} ; + + static Packet opCall (Modifier[] routing, Modifier[] entity, + char[] method, ubyte[] data, + PacketFlag flag = PacketFlag.CHECK_LENGTH) + { + return psyc_newPacket (&routing, &entity, cast(ubyte[]*)&method, &data, flag); + } + + static Packet opCall (Modifier[] routing, ubyte[] content, + PacketFlag flag = PacketFlag.CHECK_LENGTH) + { + return psyc_newRawPacket (&routing, &content, flag); + } + + size_t length ( ) + { + psyc_setPacketLength(this); + return this._length; + } + + ubyte[] render ( ubyte[] buffer ) + { + psyc_setPacketLength(this); + + with (RenderRC) + switch (psyc_render(this, buffer.ptr, buffer.length)) + { + case ERROR_METHOD_MISSING: + throw new Exception("Method missing"); + break; + + case ERROR_MODIFIER_NAME_MISSING: + throw new Exception("Modifier name missing"); + break; + + case ERROR: + throw new Exception("Buffer to small"); + break; + + case SUCCESS: + return buffer[0 .. this._length]; + + default: + throw new Exception("Unknown Return Code"); + } + } +}; + /** * \internal - * Check if a modifier needs length. */ - -ModifierFlag psyc_checkModifierLength (Modifier *m) -{ - ModifierFlag flag; - - if (m->value.length > PSYC_MODIFIER_SIZE_THRESHOLD) - flag = ModifierFlag.NEED_LENGTH; - else if (memchr(m->value.ptr, (int)'\n', m->value.length)) - flag = ModifierFlag.NEED_LENGTH; - else - flag = ModifierFlag.NO_LENGTH; - - return flag; -} - -/** Create new modifier. */ - -Modifier psyc_newModifier (char oper, String *name, String *value, - ModifierFlag flag) -{ - Modifier m = {oper, *name, *value, flag}; - - if (flag == ModifierFlag.CHECK_LENGTH) // find out if it needs a length - m.flag = psyc_checkModifierLength(&m); - - return m; -} - -/** Create new modifier */ -Modifier psyc_newModifier2 (char oper, - char *name, size_t namelen, - char *value, size_t valuelen, - ModifierFlag flag) -{ - String n = {namelen, name}; - String v = {valuelen, value}; - - return psyc_newModifier(oper, &n, &v, flag); -} - -/** - * \internal - * Get the total length of a modifier when rendered. - */ -size_t psyc_getModifierLength (Modifier *m); +private size_t psyc_getModifierLength (Modifier *m); /** * \internal @@ -184,26 +212,29 @@ PacketFlag psyc_checkPacketLength (Packet *p); /** * Calculate and set the rendered length of packet parts and total packet length. */ -size_t psyc_setPacketLength (Packet *p); +private size_t psyc_setPacketLength (Packet *p); /** Create new list. */ List psyc_newList (String *elems, size_t num_elems, ListFlag flag); /** Create new packet. */ -Packet psyc_newPacket (Header *routing, - Header *entity, - String *method, String *data, - PacketFlag flag); +private Packet psyc_newPacket (Modifier[]* routing, + Modifier[]* entity, + String *method, String *data, + PacketFlag flag); + + + /** Create new packet. */ Packet psyc_newPacket2 (Modifier *routing, size_t routinglen, - Modifier *entity, size_t entitylen, - char *method, size_t methodlen, - char *data, size_t datalen, - PacketFlag flag); + Modifier *entity, size_t entitylen, + char *method, size_t methodlen, + char *data, size_t datalen, + PacketFlag flag); /** Create new packet with raw content. */ -Packet psyc_newRawPacket (Header *routing, String *content, +Packet psyc_newRawPacket (Modifier[] *routing, ubyte[] *content, PacketFlag flag); /** Create new packet with raw content. */ diff --git a/d/include/psyc/parse.d b/d/include/psyc/parse.d index dcc1015..ac5be77 100644 --- a/d/include/psyc/parse.d +++ b/d/include/psyc/parse.d @@ -141,6 +141,24 @@ struct ParseState return inst; } + /** + * Parse PSYC packets. + * + * Generalized line-based packet parser. + * + * Params: + * oper = A reference to a character. In case of a variable, it will + * be set to the operator of that variable + * name = A reference to a String. It will point to the name of + * the variable or method and its length will be set accordingly + * value = A reference to a String. It will point to the + * value/body the variable/method and its length will be set accordingly + */ + ParseRC parse ( ref char oper, ref char[] name, ref ubyte[] value ) + { + return psyc_parse(this, &oper, cast(String*) &name, cast(String*) &value); + } + /** * Parse PSYC packets. * @@ -175,7 +193,7 @@ struct ParseState if (this.flags & ParseFlag.START_AT_CONTENT) { this.contentLength = buffer.length; - this.contentLengthFound = Bool.TRUE; + this.contentLengthFound = TRUE; } } @@ -187,23 +205,11 @@ struct ParseState * * See_Also: String */ - void setParseBuffer ( ubyte[] buffer ) + void setParseBuffer ( char[] buffer ) { this.setParseBuffer(*(cast(String*) &buffer)); } - /** - * Sets a new buffer in the parser state struct with data to be parsed. - * - * Params: - * buffer = pointer to the buffer that should be parsed now - * length = length of the buffer - */ - void setParseBuffer ( ubyte* buffer, size_t length ) - { - this.setParseBuffer(String(length, cast(ubyte*)buffer)); - } - size_t getContentLength ( ) { return this.contentLength; @@ -211,7 +217,7 @@ struct ParseState bool isContentLengthFound ( ) { - return this.contentLengthFound == Bool.TRUE; + return this.contentLengthFound == TRUE; } size_t getValueLength ( ) @@ -221,7 +227,7 @@ struct ParseState bool isValueLengthFound ( ) { - return this.valueLengthFound == Bool.TRUE; + return this.valueLengthFound == true; } size_t getCursor ( ) @@ -241,13 +247,13 @@ struct ParseState ubyte* getRemainingBuffer ( ) { - return this.buffer.ptr + this.cursor; + return cast(ubyte*)this.buffer.ptr + this.cursor; } void getRemainingBuffer ( ref ubyte[] buf ) { - buf = this.buffer.ptr[cursor .. cursor + getRemainingLength()]; + buf = cast(ubyte[])this.buffer.ptr[cursor .. cursor + getRemainingLength()]; } } @@ -283,22 +289,10 @@ struct ParseListState * Params: * buffer = the buffer to be parsed */ - void setBuffer ( ubyte[] buffer ) + void setBuffer ( char[] buffer ) { this.setBuffer(*(cast(String*) &buffer)); } - - /** - * Sets a new buffer with data to be parsed - * - * Params: - * buffer = pointer to the buffer to be parsed - * length = size of the buffer - */ - void setBuffer ( ubyte* buffer, size_t length ) - { - this.setBuffer(String(length, buffer)); - } } private: diff --git a/d/include/psyc/render.d b/d/include/psyc/render.d index c02a188..c9e248a 100644 --- a/d/include/psyc/render.d +++ b/d/include/psyc/render.d @@ -51,10 +51,10 @@ enum RenderListRC * @see psyc_newRawPacket2 * @see psyc_setPacketLength */ -RenderRC psyc_render (Packet *packet, char *buffer, size_t buflen); +RenderRC psyc_render (Packet *packet, ubyte *buffer, size_t buflen); /** * Render a PSYC list into a buffer. */ -RenderListRC psyc_renderList (List *list, char *buffer, size_t buflen); +RenderListRC psyc_renderList (List *list, ubyte *buffer, size_t buflen); diff --git a/d/include/psyc/syntax.d b/d/include/psyc/syntax.d index a5fcfe3..2962f57 100644 --- a/d/include/psyc/syntax.d +++ b/d/include/psyc/syntax.d @@ -3,7 +3,7 @@ module psyc.syntax; const PSYC_LIST_SIZE_LIMIT = 404; /* beyond this a content length must be provided */ -const = PSYC_CONTENT_SIZE_THRESHOLD = 444; +const PSYC_CONTENT_SIZE_THRESHOLD = 444; /* beyond this a modifier value length must be provided */ const PSYC_MODIFIER_SIZE_THRESHOLD = 404; From 340b164f6d2f81868021884ff6f0581b0cd7b63d Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sun, 12 Jun 2011 20:55:26 +0200 Subject: [PATCH 317/378] make fixes --- Makefile | 1 + src/Makefile | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 05f4d55..d7f5997 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,5 @@ .PHONY: doc test bench +.NOTPARALLEL: clean all: ${MAKE} -C src diff --git a/src/Makefile b/src/Makefile index 822ccfa..da0452d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -10,6 +10,8 @@ P = match itoa A = ../lib/libpsyc.a SO = ../lib/libpsyc.so +.NOTPARALLEL: clean + all: CC := ${WRAPPER} ${CC} all: lib @@ -21,13 +23,13 @@ diet: WRAPPER = ${DIET} diet: CC := ${WRAPPER} ${CC} diet: lib -lib: $O $A ${SO} +lib: $A ${SO} -${SO}: +${SO}: $O @mkdir -p ../lib ${CC} ${CFLAGS} -shared -lm -o $@ $O -$A: +$A: $O @mkdir -p ../lib ${WRAPPER} ${AR} rcs $@ $O From f0e3038e6885b6f06bcf2956cafd9e3c2bb916f7 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sun, 12 Jun 2011 21:04:11 +0200 Subject: [PATCH 318/378] psyc_text: added extra param --- include/psyc/text.h | 4 ++-- lib/Makefile | 4 ++-- src/text.c | 4 ++-- test/testText.c | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/include/psyc/text.h b/include/psyc/text.h index a94dd3b..a09d3fb 100644 --- a/include/psyc/text.h +++ b/include/psyc/text.h @@ -64,7 +64,7 @@ typedef struct * PSYC_TEXT_VALUE_NOT_FOUND if no match found in which case psyc_text * leaves the original template text as is. */ -typedef psycTextValueRC (*psycTextCB)(const char *name, size_t len, psycString *value); +typedef psycTextValueRC (*psycTextCB)(const char *name, size_t len, psycString *value, void *extra); /** * Initializes the PSYC text state struct. @@ -158,7 +158,7 @@ size_t psyc_getTextBytesWritten (psycTextState *state) * * @see http://about.psyc.eu/psyctext **/ -psycTextRC psyc_text (psycTextState *state, psycTextCB getValue); +psycTextRC psyc_text (psycTextState *state, psycTextCB getValue, void *extra); /** @} */ // end of text group diff --git a/lib/Makefile b/lib/Makefile index fa8114a..62f7a85 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -2,7 +2,7 @@ prefix = /usr libdir = ${prefix}/lib INSTALL = install -LIBS = libpsyc.a +LIBS = libpsyc.a libpsyc.so install: ${LIBS} @@ -10,7 +10,7 @@ libdir: ${INSTALL} -d ${libdir} ${LIBS}: libdir - ${INSTALL} $@ ${libdir} + -${INSTALL} $@ ${libdir} clean: rm -f ${LIBS} diff --git a/src/text.c b/src/text.c index c4a5fea..944dd41 100644 --- a/src/text.c +++ b/src/text.c @@ -1,7 +1,7 @@ #include "lib.h" #include -psycTextRC psyc_text (psycTextState *state, psycTextCB getValue) +psycTextRC psyc_text (psycTextState *state, psycTextCB getValue, void* extra) { const char *start = state->tmpl.ptr, *end; // start & end of variable name const char *prev = state->tmpl.ptr + state->cursor; @@ -35,7 +35,7 @@ psycTextRC psyc_text (psycTextState *state, psycTextCB getValue) continue; // [] is invalid, name can't be empty } - ret = getValue(start + state->open.length, end - start - state->open.length, &value); + ret = getValue(start + state->open.length, end - start - state->open.length, &value, extra); if (ret < 0) continue; // value not found, no substitution diff --git a/test/testText.c b/test/testText.c index 21f732d..5f667f5 100644 --- a/test/testText.c +++ b/test/testText.c @@ -7,7 +7,7 @@ uint8_t verbose; -psycTextValueRC getValueFooBar (const char *name, size_t len, psycString *value) +psycTextValueRC getValueFooBar (const char *name, size_t len, psycString *value, void *extra) { if (verbose) printf("> getValue: %.*s\n", (int)len, name); @@ -16,7 +16,7 @@ psycTextValueRC getValueFooBar (const char *name, size_t len, psycString *value) return PSYC_TEXT_VALUE_FOUND; } -psycTextValueRC getValueEmpty (const char *name, size_t len, psycString *value) +psycTextValueRC getValueEmpty (const char *name, size_t len, psycString *value, void *extra) { if (verbose) printf("> getValue: %.*s\n", (int)len, name); @@ -25,7 +25,7 @@ psycTextValueRC getValueEmpty (const char *name, size_t len, psycString *value) return PSYC_TEXT_VALUE_FOUND; } -psycTextValueRC getValueNotFound (const char *name, size_t len, psycString *value) +psycTextValueRC getValueNotFound (const char *name, size_t len, psycString *value, void *extra) { if (verbose) printf("> getValue: %.*s\n", (int)len, name); @@ -41,7 +41,7 @@ int testText (char *template, size_t tmplen, char *buffer, size_t buflen, psycSt psyc_initTextState(&state, template, tmplen, buffer, buflen); do { - ret = psyc_text(&state, getValue); + ret = psyc_text(&state, getValue, NULL); length += psyc_getTextBytesWritten(&state); switch (ret) { From 38b206aec0a479687dca7dfe96f16912331bf8c0 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 15 Jun 2011 21:36:43 +0200 Subject: [PATCH 319/378] pike changes by fippo --- pike/README | 4 +- pike/parserender.pike | 64 +++++++ pike/psyc.cmod | 377 ++++++++++++++++++++++++++++++++++++------ pike/text.pike | 5 + 4 files changed, 393 insertions(+), 57 deletions(-) create mode 100644 pike/parserender.pike create mode 100644 pike/text.pike diff --git a/pike/README b/pike/README index ab3db07..a3fd345 100644 --- a/pike/README +++ b/pike/README @@ -1,6 +1,6 @@ +needs latest libpsyc from git://supraverse.net/libpsyc to compile the cmod: pike -x module to run the code: -pike -M. rendertest.pike -pike -M. parsetest.pike +pike -M. parserender.pike diff --git a/pike/parserender.pike b/pike/parserender.pike new file mode 100644 index 0000000..975e6a3 --- /dev/null +++ b/pike/parserender.pike @@ -0,0 +1,64 @@ +class ParserWithCallback { + inherit .Parser; + void handle_packet(mapping rvars, mapping evars, string|void method, string|void body) { + write("rvars -> %O\n", rvars); + write("evars -> %O\n", evars); + write("method-> %O\n", method); + write("body -> %O\n", body); + if (!method) { + method = ""; + } + if (!body) { + body = ""; + } + /* + string re = render(rvars, evars, method, body); + write("\n------test:\n%s\n-----rendered:\n%s\n----\n", test, re); + */ + } + void handle_error(int code) { + write("error: %d\n", code); + } +} + +array(string) testcases = ({ + "00-length-no-content", + "00-length-no-data", + "00-length-no-value", + "00-method-only", + "00-no-content", + "00-no-data", + "00-no-entity", + "00-no-routing", + "00-no-value", + "01", + "01-length", + "01-utf8", + "02-list", + "03-list", + "04-circuit", + "05-message-private", + "06-message-private-remote", + "07-dns-fake", + "07-dns-invalid", + "08-context-enter", + "08-context-leave", + "err-01-length", + "err-02-list" +}); +string basedir = "../test/packets/"; + +string test; + +int main() { + .Parser p = ParserWithCallback(); + for (int i = 0; i < sizeof(testcases); i++) { + Stdio.File f = Stdio.File(basedir + testcases[i], "r"); + test = f->read(); + f->close(); + write("TEST #%d: %s\n", i, testcases[i]); + p->feed(test); + write("-----\n"); + + } +} diff --git a/pike/psyc.cmod b/pike/psyc.cmod index d29b67c..c528ca1 100644 --- a/pike/psyc.cmod +++ b/pike/psyc.cmod @@ -2,6 +2,7 @@ #include "interpret.h" #include "stralloc.h" #include "mapping.h" +#include "array.h" #include "svalue.h" #include "operators.h" #include "array.h" @@ -14,36 +15,95 @@ #endif // libpsyc dependencies -# include -# include -# include +#include +#include +#include +#include #define MODULE_NAME "PSYC" #define MODULE_MAJOR 0 -#define MODULE_MINOR 1 +#define MODULE_MINOR 2 #define MODULE_PATCH 0 /*! @module PSYC *! *! Implements PSYC parsing and rendering based on libpsyc - *! FIXME: parser not implemented yet *! */ +// psyctext helper +psycTextValueRC lookup_value_mapping(const char *name, size_t len, psycString *value, void *extra) +{ + printf("lookup_value_mapping called for %.*s\n", (int) len, name); + struct pike_string *key = make_shared_binary_string(name, len); + struct mapping *m = (struct mapping *) extra; + struct svalue *s = low_mapping_string_lookup(m, key); + free_string(key); + + if (s == NULL) { + return PSYC_TEXT_VALUE_NOT_FOUND; + } + + switch(s->type) { + case PIKE_T_STRING: + //printf("lookup returned %.*s\n", (int) s->u.string->len, STR0(s->u.string)); + value->ptr = (char *) STR0(s->u.string); + value->length = s->u.string->len; + break; + default: + printf("lookup did return !string\n"); + // FIXME + value->ptr = ""; + value->length = 0; + } + return PSYC_TEXT_VALUE_FOUND; +} + +/*! @decl string psyc_text(string template, mapping vars) + *! @param template + *! template to be filled + *! @param vars + *! mapping(string:string) with substituions + *! @returns + *! rendered string + */ +PIKEFUN string psyc_text(string template, mapping vars) { + psycTextState state; + psycTextRC ret; + size_t len = 0; + // FIXME: + char buffer[512]; + + psyc_initTextState(&state, (char *) STR0(template), template->len, buffer, 512); + do + { + ret = psyc_text(&state, lookup_value_mapping, vars); + len += psyc_getTextBytesWritten(&state); + switch (ret) { + case PSYC_TEXT_INCOMPLETE: // need to realloc buffer + //psyc_setTextBuffer2(&state, buffer + len, BUFSIZE - len); + break; + case PSYC_TEXT_COMPLETE: // we're done + RETURN make_shared_binary_string(buffer, len); + case PSYC_TEXT_NO_SUBST: // no substituions, return original string + RETURN template; + } + } while (ret == PSYC_TEXT_INCOMPLETE); +} + /*! @decl string render(mapping rvars, mapping evars, string method, string|void body) *! @param rvars - *! FIXME + *! routing vars (mapping string:string) *! @param evars - *! FIXME + *! entity vars (mapping string:mixed *! @param method - *! FIXME + *! method name *! @param data - *! FIXME + *! body *! @returns *! serialized packet as a string */ PIKEFUN string render(mapping rvars, mapping evars, string method, string|void body) { - char buffer[1024*1024]; // static buffer, FIXME psycPacket packet; psycHeader rheaders, eheaders; @@ -58,12 +118,6 @@ PIKEFUN string render(mapping rvars, mapping evars, string method, string|void b NEW_MAPPING_LOOP(rvars->data) { if (k->ind.type == PIKE_T_STRING) { switch(k->val.type) { - case PIKE_T_INT: - printf("integer value %ld\n", k->val.u.integer); - break; - case PIKE_T_FLOAT: - printf("float value %f\n", k->val.u.float_number); - break; case PIKE_T_STRING: rheaders.modifiers[rheaders.lines++] = psyc_newModifier2(oper, (char *)STR0(k->ind.u.string), @@ -72,20 +126,8 @@ PIKEFUN string render(mapping rvars, mapping evars, string method, string|void b k->val.u.string->len, PSYC_MODIFIER_ROUTING); break; - case PIKE_T_MAPPING: - printf("mapping value length %d\n", k->val.u.mapping->data->size); - // another walk_mapping? - break; - case PIKE_T_ARRAY: - printf("array value length %d\n", k->val.u.array->size); - /* - for(e = 0; e < data->u.array->size; e++) { - struct svalue item = data->u.array->item[e]; - inner_serialize2(&item, sb); - } - */ - break; default: + Pike_error("psyc render: unsupported non-string value in rvars\n"); break; } } else { @@ -101,35 +143,61 @@ PIKEFUN string render(mapping rvars, mapping evars, string method, string|void b size_t keylen; char *val = NULL; size_t vallen = 0; + struct pike_string *s; key = (char *) STR0(k->ind.u.string); keylen = k->ind.u.string->len; switch(k->val.type) { case PIKE_T_INT: - printf("integer value %ld\n", k->val.u.integer); + do { + struct string_builder b; + init_string_builder(&b, 0); + string_builder_append_integer(&b, k->val.u.integer, + 10, APPEND_SIGNED, 0, 0); + s = finish_string_builder(&b); + val = (char *) STR0(s); + vallen = s->len; + free_string(s); + } while (0); break; case PIKE_T_STRING: - val = (char *) STR0(k->ind.u.string); - vallen = k->ind.u.string->len; + val = (char *) STR0(k->val.u.string); + vallen = k->val.u.string->len; break; + /* case PIKE_T_FLOAT: printf("float value %f\n", k->val.u.float_number); break; - case PIKE_T_MAPPING: - printf("mapping value length %d\n", k->val.u.mapping->data->size); - // another walk_mapping? - break; - case PIKE_T_ARRAY: - printf("array value length %d\n", k->val.u.array->size); - /* - for(e = 0; e < data->u.array->size; e++) { - struct svalue item = data->u.array->item[e]; - inner_serialize2(&item, sb); - } */ + case PIKE_T_ARRAY: + do { + psycString *elems = xcalloc(k->val.u.array->size, sizeof(psycString)); + psycList list; + // FIXME: check for out of memory + for(e = 0; e < k->val.u.array->size; e++) { + struct svalue item = k->val.u.array->item[e]; + switch(item.type) { + case PIKE_T_STRING: + elems[e] = (psycString) { item.u.string->len, (char *) STR0(item.u.string) }; + break; + default: + // FIXME: xfree(elems) ? + Pike_error("psyc_render: unsupported data type in list\n"); + } + } + list = psyc_newList(elems, k->val.u.array->size, PSYC_LIST_CHECK_LENGTH); + + struct pike_string *listbuf = begin_shared_string(list.length); + psyc_renderList(&list, (char *) STR0(listbuf), listbuf->len); + end_shared_string(listbuf); + val = (char *) STR0(listbuf); + vallen = listbuf->len; + xfree(elems); + } while (0); break; default: + Pike_error("psyc_render: unsupported value in evars\n"); break; } eheaders.modifiers[eheaders.lines++] = psyc_newModifier2(oper, @@ -159,41 +227,240 @@ PIKEFUN string render(mapping rvars, mapping evars, string method, string|void b PSYC_PACKET_CHECK_LENGTH); } - /* - FIXME: how to allocate space and pass it to libpsyc? - string builder probably - */ - psyc_render(&packet, buffer, packet.length); + struct pike_string *s = begin_shared_string(packet.length); + psyc_render(&packet, (char *) STR0(s), packet.length); // pop_n_elems(args); - RETURN make_shared_binary_string(buffer, packet.length); + RETURN end_shared_string(s); } PIKECLASS Parser { CVAR psycParseState parser; + CVAR struct pike_string *buffer; + CVAR int handle_packet; + CVAR int handle_error; + + // packet state + CVAR struct mapping *rvars; + CVAR struct mapping *evars; + CVAR struct pike_string *method; + CVAR struct pike_string *body; + + // for incomplete length prefixed entity var data / body data + CVAR struct string_builder incomplete; INIT { psyc_initParseState(&THIS->parser); + THIS->buffer = NULL; + THIS->handle_packet = find_identifier("handle_packet", Pike_fp->current_object->prog); + THIS->handle_error = find_identifier("handle_error", Pike_fp->current_object->prog); + THIS->rvars = allocate_mapping(0); + THIS->evars = allocate_mapping(0); + THIS->method = NULL; + THIS->body = NULL; + //THIS->body_buffer = NULL; } EXIT { - + if (THIS->buffer != NULL) { + free_string(THIS->buffer); + } + if (THIS->rvars != NULL) { + do_free_mapping(THIS->rvars); + } + // FIXME: free packet state } PIKEFUN void feed(string data) { char oper; psycString name, value; int ret; + int err; + if (THIS->buffer != NULL) { + /* we have remaining buffer from previous input */ + //printf("%d bytes remaining from previous read\n", THIS->buffer->len); + struct pike_string *tmp; + tmp = add_shared_strings(THIS->buffer, data); + free_string(THIS->buffer); + data = tmp; + THIS->buffer = NULL; + } psyc_setParseBuffer2(&THIS->parser, (char *) STR0(data), data->len); - for (;;) { - printf("looping...\n"); + do { ret = psyc_parse(&THIS->parser, &oper, &name, &value); - if (ret == PSYC_PARSE_COMPLETE || ret < 0) { + switch(ret) { + case PSYC_PARSE_ROUTING: + // printf("R %.*s -> %.*s\n", (int)name.length, name.ptr, (int)value.length, value.ptr); + mapping_string_insert_string(THIS->rvars, + make_shared_binary_string(name.ptr, name.length), + make_shared_binary_string(value.ptr, value.length)); break; + case PSYC_PARSE_ENTITY_START: // entity var with length + init_string_builder_alloc(&THIS->incomplete, psyc_getParseValueLength(&THIS->parser), 0); + // fall thru + case PSYC_PARSE_ENTITY_CONT: + string_builder_append(&THIS->incomplete, MKPCHARP(value.ptr, 0), value.length); + break; + case PSYC_PARSE_ENTITY_END: + string_builder_append(&THIS->incomplete, MKPCHARP(value.ptr, 0), value.length); + do { + struct pike_string *tmp = finish_string_builder(&THIS->incomplete); + value.length = tmp->len; + value.ptr = (char *) STR0(tmp); + // FIXME: not sure if this is really safe + free_string(tmp); + } while (0); + // fall thru + case PSYC_PARSE_ENTITY: + //printf("E %.*s -> %.*s\n", (int)name.length, name.ptr, (int)value.length, value.ptr); + do { + err = 0; + int type = psyc_getVarType(&name); + struct svalue sv; + time_t timmy; + switch(type) { + case PSYC_TYPE_DATE: + if (psyc_parseDate(&value, &timmy)) { + sv.type = PIKE_T_INT; sv.u.integer = timmy; + mapping_string_insert(THIS->evars, + make_shared_binary_string(name.ptr, name.length), + &sv); + } else { + err = 1; + } + break; + case PSYC_TYPE_TIME: + if (psyc_parseTime(&value, &timmy)) { + sv.type = PIKE_T_INT; sv.u.integer = timmy; + mapping_string_insert(THIS->evars, + make_shared_binary_string(name.ptr, name.length), + &sv); + } else { + err = 2; + } + break; + case PSYC_TYPE_AMOUNT: + break; + case PSYC_TYPE_DEGREE: + if (value.length && value.ptr[0] >= '0' && value.ptr[0] <= '9') { + sv.type = PIKE_T_FLOAT; sv.u.float_number = (float) (value.ptr[0] - '0') / 10.0; + mapping_string_insert(THIS->evars, + make_shared_binary_string(name.ptr, name.length), + &sv); + } else { + err = 3; + } + break; + case PSYC_TYPE_FLAG: + if (value.length && value.ptr[0] >= '0' && value.ptr[0] <= '1') { + sv.type = PIKE_T_INT; sv.u.integer = value.ptr[0] - '0'; + mapping_string_insert(THIS->evars, + make_shared_binary_string(name.ptr, name.length), + &sv); + } else { + err = 4; + } + break; + case PSYC_TYPE_LIST: + do { + struct array *elems = low_allocate_array(0, 32); + if (value.length > 0) { + int retl; + int count = 0; + psycParseListState listState; + psycString elem = (psycString) {0, 0}; + + psyc_initParseListState(&listState); + psyc_setParseListBuffer(&listState, value); + do { + retl = psyc_parseList(&listState, &elem); + switch(retl) { + case PSYC_PARSE_LIST_END: // last element + retl = 0; + case PSYC_PARSE_LIST_ELEM: + sv.type = PIKE_T_STRING; sv.u.string = make_shared_binary_string(elem.ptr, elem.length); + elems = array_insert(elems, &sv, count++); + break; + default: + err = 5; + break; + } + } while (retl > 0 && !err); + } + if (!err) { + sv.type = PIKE_T_ARRAY; + sv.u.array = elems; + mapping_string_insert(THIS->evars, + make_shared_binary_string(name.ptr, name.length), + &sv); + } + free_array(elems); + } while (0); + break; + default: // string + mapping_string_insert_string(THIS->evars, + make_shared_binary_string(name.ptr, name.length), + make_shared_binary_string(value.ptr, value.length)); + } + } while (0); + if (err) { // there was an error while + // FIXME + return; + } + break; + case PSYC_PARSE_BODY_START: // if length was given this is used for body + init_string_builder_alloc(&THIS->incomplete, psyc_getParseValueLength(&THIS->parser), 0); + case PSYC_PARSE_BODY_CONT: + string_builder_append(&THIS->incomplete, MKPCHARP(value.ptr, 0), value.length); + break; + case PSYC_PARSE_BODY_END: + string_builder_append(&THIS->incomplete, MKPCHARP(value.ptr, 0), value.length); + do { + struct pike_string *tmp = finish_string_builder(&THIS->incomplete); + value.length = tmp->len; + value.ptr = (char *) STR0(tmp); + // FIXME: not sure if this is really safe + free_string(tmp); + } while (0); + // fall thru + case PSYC_PARSE_BODY: + THIS->method = make_shared_binary_string(name.ptr, name.length); + THIS->body = make_shared_binary_string(value.ptr, value.length); + break; + case PSYC_PARSE_COMPLETE: // apply the callback + push_mapping(THIS->rvars); + push_mapping(THIS->evars); + if (THIS->method == NULL) { + apply_low(Pike_fp->current_object, THIS->handle_packet, 2); + } else if (THIS->body == NULL) { + push_string(THIS->method); + apply_low(Pike_fp->current_object, THIS->handle_packet, 3); + } else { + push_string(THIS->method); + push_string(THIS->body); + apply_low(Pike_fp->current_object, THIS->handle_packet, 4); + } + + // reset packet state + THIS->rvars = allocate_mapping(0); + THIS->evars = allocate_mapping(0); + THIS->method = NULL; + THIS->body = NULL; + break; + case PSYC_PARSE_INSUFFICIENT: // not enough data + if (psyc_getParseRemainingBuffer(&THIS->parser) > 0) { + THIS->buffer = make_shared_binary_string(psyc_getParseRemainingBuffer(&THIS->parser), + psyc_getParseRemainingLength(&THIS->parser)); + } + return; + default: // fatal error + push_int(ret); + apply_low(Pike_fp->current_object, THIS->handle_error, 1); + // FIXME: free stuff? or do we kill the socket and parser anyway + return; } - } - printf("down here\n"); + } while (1); } } diff --git a/pike/text.pike b/pike/text.pike new file mode 100644 index 0000000..6eb1faf --- /dev/null +++ b/pike/text.pike @@ -0,0 +1,5 @@ +int main() { + write("%O\n", + psyc_text("some template with a single variable '[_foo_ba]' done.", ([ "_foo" : "abc" ]))); + //psyc_text("some template [_foo] with a single variable '[_foo_ba]' done.", ([ "_foo" : "abc" ]))); +} From 2bd28adbd7a34b23fce6534bf425e4a2389d5bd6 Mon Sep 17 00:00:00 2001 From: Philipp Hancke Date: Thu, 16 Jun 2011 08:18:27 +0200 Subject: [PATCH 320/378] removed old files --- pike/parsetest.pike | 11 ----------- pike/psyc.cmod | 4 ++-- pike/rendertest.pike | 8 -------- 3 files changed, 2 insertions(+), 21 deletions(-) delete mode 100644 pike/parsetest.pike delete mode 100644 pike/rendertest.pike diff --git a/pike/parsetest.pike b/pike/parsetest.pike deleted file mode 100644 index 86321e8..0000000 --- a/pike/parsetest.pike +++ /dev/null @@ -1,11 +0,0 @@ -int main() { - .Parser p = Parser(); - p->feed(":_source\tpsyc://nb.tgbit.net/~foo\n" - ":_target\tpsyc://nb2.tgbit.net/~bar\n" - ":_tag\tf00b4rb4z\n" - "\n" - ":_foo\tbar\n" - "_message_private\n" - "OHAI\n" - "|\n"); -} diff --git a/pike/psyc.cmod b/pike/psyc.cmod index c528ca1..7757143 100644 --- a/pike/psyc.cmod +++ b/pike/psyc.cmod @@ -34,7 +34,7 @@ // psyctext helper psycTextValueRC lookup_value_mapping(const char *name, size_t len, psycString *value, void *extra) { - printf("lookup_value_mapping called for %.*s\n", (int) len, name); + //printf("lookup_value_mapping called for %.*s\n", (int) len, name); struct pike_string *key = make_shared_binary_string(name, len); struct mapping *m = (struct mapping *) extra; struct svalue *s = low_mapping_string_lookup(m, key); @@ -52,7 +52,7 @@ psycTextValueRC lookup_value_mapping(const char *name, size_t len, psycString *v break; default: printf("lookup did return !string\n"); - // FIXME + // FIXME: we need the automagic value conversion value->ptr = ""; value->length = 0; } diff --git a/pike/rendertest.pike b/pike/rendertest.pike deleted file mode 100644 index cb5c5cd..0000000 --- a/pike/rendertest.pike +++ /dev/null @@ -1,8 +0,0 @@ -int main() { - werror("render:\n%s\---\n", - render( ([ "_context" : "psyc://denmark.lit/~hamlet#_follow" ]), - ([ "_type_content" : "text/plain", "_subject" : "to be or not to be ?", - "_bla" : 123 ]), - "_message", - "to be or not to be ?")); -} From 960f0e6d67ea0ce225479aaa7043887786f13a26 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 5 Jul 2011 13:28:29 +0200 Subject: [PATCH 321/378] doc fix --- include/psyc/parse.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/psyc/parse.h b/include/psyc/parse.h index 5f1ed0c..d8289e0 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -423,7 +423,6 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, * memory allocation is done. * * @param state An initialized psycParseListState. - * @param value Contains the list to be parsed. * @param elem It will point to the next element in the list. */ #ifdef __INLINE_PSYC_PARSE From e8647a09d5d7dad635d0b19404fc047eda433960 Mon Sep 17 00:00:00 2001 From: Philipp Hancke Date: Sun, 17 Jul 2011 10:48:01 +0200 Subject: [PATCH 322/378] add is_routingvar wrapper --- pike/psyc.cmod | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pike/psyc.cmod b/pike/psyc.cmod index 7757143..11ba358 100644 --- a/pike/psyc.cmod +++ b/pike/psyc.cmod @@ -91,6 +91,17 @@ PIKEFUN string psyc_text(string template, mapping vars) { } while (ret == PSYC_TEXT_INCOMPLETE); } +/*! @decl string is_routingvar(string name) + *! @param name + *! name of the variable + *! @returns + *! 1 if it is a routing variable + *! 0 otherwise + */ +PIKEFUN int is_routingvar(string name) { + RETURN psyc_isRoutingVar2((char *) STR0(name), name->len); +} + /*! @decl string render(mapping rvars, mapping evars, string method, string|void body) *! @param rvars *! routing vars (mapping string:string) From da9cb17bf5de9065dd480bae5d4dd3b06c2a6426 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Fri, 22 Jul 2011 10:27:20 +0200 Subject: [PATCH 323/378] we did include it in the benchmarks later --- bench/benchmark.org | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bench/benchmark.org b/bench/benchmark.org index 2c4c0be..4382cdb 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -86,8 +86,8 @@ need to be mentioned): #+INCLUDE: packets/presence.psyc src psyc And this is the same message in PSYC's compact form, but since compact mode -hasn't been implemented nor deployed yet, we will not include it -in the benchmarks: +hasn't been implemented nor deployed yet, you should only consider this +for future projects: #+INCLUDE: packets/presence-c.psyc src psyc From d265944c8d4691a1f1b50f276dc7f9d40db56676 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Mon, 22 Aug 2011 23:29:14 +0200 Subject: [PATCH 324/378] + --- README.org | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.org b/README.org index 22586fc..7c70580 100644 --- a/README.org +++ b/README.org @@ -7,12 +7,13 @@ libpsyc implements various functions required to use PSYC. - See [[http://about.psyc.eu/libpsyc]] for more information on the library. - See [[http://lib.psyc.eu/doc/]] for the API documentation. -- See [[http://about.psyc.eu/Specification]] for more information on the new PSYC - specification. +- See [[http://about.psyc.eu/Specification]] for more information + on the new PSYC specification. - See [[http://about.psyc.eu/]] for information on PSYC in general. -The plain C API located in the include/psyc directory along with the file psyc.h -is primarily intended to be used for binding with other languages and frameworks. +The plain C API located in the include/psyc directory along with the file +psyc.h is primarily intended to be used for binding with other languages +and frameworks. The LPC binding for psyced is distributed with psyclpc since it is spread over several files (LPC has no simple approach to binding). Other bindings @@ -76,8 +77,8 @@ into the library, contact either anyone of us directly or just join the developement room at - psyc://psyced.org/@welcome -- xmpp:*welcome@psyced.org - irc://psyced.org/welcome +- xmpp:*welcome@psyced.org * License From 38298882030da1b4fd48870731c9e98a54fe156e Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 12 Sep 2011 11:44:48 +0200 Subject: [PATCH 325/378] some swig code, needs more work --- .gitignore | 8 ++++++++ perl/Makefile | 25 +++++++++++++++++++++++++ perl/psyc.i | 42 ++++++++++++++++++++++++++++++++++++++++++ python/Makefile | 24 ++++++++++++++++++++++++ python/psyc.i | 1 + 5 files changed, 100 insertions(+) create mode 100644 perl/Makefile create mode 100644 perl/psyc.i create mode 100644 python/Makefile create mode 120000 python/psyc.i diff --git a/.gitignore b/.gitignore index b6b2544..5f4516d 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,14 @@ test/testText test/isRoutingVar test/getVarType +perl/*.c +perl/*.so +perl/*.pm + +python/*.c +python/*.so +python/*.py + .config ~$* .DS_Store diff --git a/perl/Makefile b/perl/Makefile new file mode 100644 index 0000000..638b883 --- /dev/null +++ b/perl/Makefile @@ -0,0 +1,25 @@ +CFLAGS = -I../include -Wall -std=c99 -fPIC +SWIG = swig +PERL = perl + +I = psyc.i +S = psyc_wrap.c +O = psyc_wrap.o +SO = PSYC.so +PM = PSYC.pm +PSYCO = ../src/packet.o ../src/parse.o ../src/match.o ../src/render.o ../src/memmem.o ../src/itoa.o ../src/variable.o ../src/text.o + +all: swig lib + +swig: + ${SWIG} -I../include -perl5 $I + +CFLAGS = ${CFLAGS_COMMON} $(shell ${PERL} -MConfig -e 'print join(" ", @Config{qw(ccflags optimize cccdlflags)}, "-I$$Config{archlib}/CORE")') -D_XOPEN_SOURCE +$O: $S + +lib: $O + ${MAKE} -C ../src ${PSYCO} + ${CC} ${CFLAGS} $(shell ${PERL} -MConfig -e 'print $$Config{lddlflags}') ${PSYCO} $O -o ${SO} + +clean: + rm -f $S $O ${SO} ${PM} diff --git a/perl/psyc.i b/perl/psyc.i new file mode 100644 index 0000000..5906435 --- /dev/null +++ b/perl/psyc.i @@ -0,0 +1,42 @@ + %module PSYC + %{ + /* Includes the headers in the wrapper code */ + #include "psyc.h" + #include "psyc/packet.h" + #include "psyc/parse.h" + #include "psyc/render.h" + #include "psyc/syntax.h" + #include "psyc/text.h" + %} + +/* Parse the headers to generate wrappers */ +%include "cdata.i" + +%rename("%(regex:/^PSYC_(.*)/\\1/)s") ""; +%rename("%(regex:/^psyc_?(.*)/\\1/)s") ""; +%rename("%(regex:/^psyc_(.*)2$/\\1/)s") ""; + +%apply (char *STRING, size_t LENGTH) { (const char *buffer, size_t length) }; +%apply (char *STRING, size_t LENGTH) { (const char *name, size_t len) }; +%apply (char *STRING, size_t LENGTH) { (const char *value, size_t len) }; + +// initTextState +%apply (char *STRING, size_t LENGTH) { (char *template, size_t tlen) }; +%apply (char *STRING, size_t LENGTH) { (char *buffer, size_t blen) }; +// setTextBrackets +%apply (char *STRING, size_t LENGTH) { (char *open, size_t openlen) }; +%apply (char *STRING, size_t LENGTH) { (char *close, size_t closelen) }; + +//%apply (char *STRING, size_t LENGTH) { }; + +psycParseRC psyc_parse2 (psycParseState *state, char *oper, + char *name, size_t namelen, + char *value, size_t valuelen); + + +%include "psyc.h" +%include "psyc/packet.h" +%include "psyc/parse.h" +%include "psyc/render.h" +%include "psyc/syntax.h" +%include "psyc/text.h" diff --git a/python/Makefile b/python/Makefile new file mode 100644 index 0000000..f223c93 --- /dev/null +++ b/python/Makefile @@ -0,0 +1,24 @@ +CFLAGS = -Wall -std=c99 -fPIC -I../include $(shell ${PYTHON_CONFIG} --includes) +SWIG = swig +PYTHON_CONFIG = python-config + +I = psyc.i +S = psyc_wrap.c +O = psyc_wrap.o +SO = _PSYC.so +PY = PSYC.py +PSYCO = ../src/packet.o ../src/parse.o ../src/match.o ../src/render.o ../src/memmem.o ../src/itoa.o ../src/variable.o ../src/text.o + +all: swig lib + +swig: + ${SWIG} -I../include -python $I + +$O: $S + +lib: $O + ${MAKE} -C ../src ${PSYCO} + ${CC} -shared ${PSYCO} $O -o ${SO} + +clean: + rm -f $S $O ${SO} ${PY} ${PY}c diff --git a/python/psyc.i b/python/psyc.i new file mode 120000 index 0000000..327cba2 --- /dev/null +++ b/python/psyc.i @@ -0,0 +1 @@ +../perl/psyc.i \ No newline at end of file From 54bf9472d2b837e4fc0f41f7126aceae8dd6d52e Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 14 Oct 2011 00:29:32 +0200 Subject: [PATCH 326/378] uniform parser --- .gitignore | 1 + include/psyc.h | 2 + include/psyc/parse.h | 96 +++++++++++++++++++++--- include/psyc/uniform.h | 69 +++++++++++++++++ src/Makefile | 4 +- src/parse.c | 72 +++--------------- src/uniform.c | 166 +++++++++++++++++++++++++++++++++++++++++ test/Makefile | 3 +- test/parseUniform.c | 51 +++++++++++++ 9 files changed, 387 insertions(+), 77 deletions(-) create mode 100644 include/psyc/uniform.h create mode 100644 src/uniform.c create mode 100644 test/parseUniform.c diff --git a/.gitignore b/.gitignore index 5f4516d..a193596 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ test/testStrlen test/testText test/isRoutingVar test/getVarType +test/parseUniform perl/*.c perl/*.so diff --git a/include/psyc.h b/include/psyc.h index 769ea8b..416f9eb 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -24,6 +24,8 @@ #define PSYC_C2STR(string) {sizeof(string)-1, string} #define PSYC_C2ARG(string) string, sizeof(string)-1 +#define PSYC_S2ARG(string) string.ptr, string.length +#define PSYC_S2ARG2(string) string.length, string.ptr typedef enum { diff --git a/include/psyc/parse.h b/include/psyc/parse.h index d8289e0..d0b22d5 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -115,8 +115,7 @@ #include #include -typedef enum -{ +typedef enum { /// Default Flag. Parse everything. PSYC_PARSE_ALL = 0, /// Parse only the header @@ -130,8 +129,7 @@ typedef enum * The return value definitions for the packet parsing function. * @see psyc_parse() */ -typedef enum -{ +typedef enum { /// Error, packet is not ending with a valid delimiter. PSYC_PARSE_ERROR_END = -8, /// Error, expected NL after the method. @@ -197,8 +195,7 @@ typedef enum * The return value definitions for the list parsing function. * @see psyc_parseList() */ -typedef enum -{ +typedef enum { PSYC_PARSE_LIST_ERROR_DELIM = -4, PSYC_PARSE_LIST_ERROR_LEN = -3, PSYC_PARSE_LIST_ERROR_TYPE = -2, @@ -214,8 +211,7 @@ typedef enum /** * Struct for keeping parser state. */ -typedef struct -{ +typedef struct { size_t cursor; ///< Current position in buffer. size_t startc; ///< Position where the parsing would be resumed. psycString buffer; ///< Buffer with data to be parsed. @@ -234,8 +230,7 @@ typedef struct /** * Struct for keeping list parser state. */ -typedef struct -{ +typedef struct { size_t cursor; ///< Current position in buffer. size_t startc; ///< Line start position. psycString buffer; ///< Buffer with data to be parsed. @@ -291,8 +286,7 @@ void psyc_setParseBuffer (psycParseState *state, psycString buffer) state->buffer = buffer; state->cursor = 0; - if (state->flags & PSYC_PARSE_START_AT_CONTENT) - { + if (state->flags & PSYC_PARSE_START_AT_CONTENT) { state->contentLength = buffer.length; state->contentLengthFound = PSYC_TRUE; } @@ -489,6 +483,84 @@ psycBool psyc_parseDate (psycString *value, time_t *t) return psyc_parseDate2(value->ptr, value->length, t); } +/** + * Determines if the argument is a glyph. + * Glyphs are: : = + - ? ! + */ +static inline +char psyc_isGlyph (uint8_t g) +{ + switch(g) { + case ':': + case '=': + case '+': + case '-': + case '?': + case '!': + return 1; + default: + return 0; + } +} + +/** + * Determines if the argument is numeric. + */ +static inline +char psyc_isNumeric (uint8_t c) +{ + return c >= '0' && c <= '9'; +} + +/** + * Determines if the argument is alphabetic. + */ +static inline +char psyc_isAlpha (uint8_t c) +{ + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); +} + +/** + * Determines if the argument is alphanumeric. + */ +static inline +char psyc_isAlphaNumeric (uint8_t c) +{ + return psyc_isAlpha(c) || psyc_isNumeric(c); +} + +/** + * Determines if the argument is a keyword character. + * Keyword characters are: alphanumeric and _ + */ +static inline +char psyc_isKwChar (uint8_t c) +{ + return psyc_isAlphaNumeric(c) || c == '_'; +} + +/** + * Determines if the argument is a name character. + * Name characters are: see opaque_part in RFC 2396 + */ +static inline +char psyc_isNameChar (uint8_t c) +{ + return psyc_isAlpha(c) || (c >= '$' && c <= ';') || + c == '_' || c == '!' || c == '?' || c == '=' || c == '@' || c == '~'; +} + +/** + * Determines if the argument is a hostname character. + * Hostname characters are: alphanumeric and - + */ +static inline +char psyc_isHostChar (uint8_t c) +{ + return psyc_isAlphaNumeric(c) || c == '.' || c == '-'; +} + /** @} */ // end of parse group #define PSYC_PARSE_H diff --git a/include/psyc/uniform.h b/include/psyc/uniform.h new file mode 100644 index 0000000..9f338f8 --- /dev/null +++ b/include/psyc/uniform.h @@ -0,0 +1,69 @@ +#ifndef PSYC_UNIFORM_H +/** + * @file uniform.h + * @brief Uniform parsing. + */ + +#include + +typedef enum { +// essential parts + PSYC_UNIFORM_SCHEME = 0, + PSYC_UNIFORM_USER = 1, + PSYC_UNIFORM_PASS = 2, + PSYC_UNIFORM_HOST = 3, + PSYC_UNIFORM_PORT = 4, + PSYC_UNIFORM_TRANSPORT = 5, + PSYC_UNIFORM_RESOURCE = 6, + PSYC_UNIFORM_QUERY = 7, + PSYC_UNIFORM_CHANNEL = 8, + +// convenient snippets of the URL + PSYC_UNIFORM_FULL = 9, // the URL as such + PSYC_UNIFORM_BODY = 10, // the URL without scheme and '//' + PSYC_UNIFORM_USERATHOST = 11, // mailto and xmpp style + PSYC_UNIFORM_HOSTPORT = 12, // just host:port (and transport) + PSYC_UNIFORM_ROOT = 13, // root UNI of peer/server + PSYC_UNIFORM_SLASHES = 14, // the // if the protocol has them + PSYC_UNIFORM_NICK = 15, // whatever works as a nickname + PSYC_UNIFORM_SIZE = 16, +} psycUniformField; + +typedef enum { + PSYC_PARSE_UNIFORM_INVALID_SLASHES = -7, + PSYC_PARSE_UNIFORM_INVALID_CHANNEL = -6, + PSYC_PARSE_UNIFORM_INVALID_RESOURCE = -5, + PSYC_PARSE_UNIFORM_INVALID_TRANSPORT = -4, + PSYC_PARSE_UNIFORM_INVALID_PORT = -3, + PSYC_PARSE_UNIFORM_INVALID_HOST = -2, + PSYC_PARSE_UNIFORM_INVALID_SCHEME = -1, +} psycParseUniformRC; + +typedef enum { + PSYC_SCHEME_PSYC = 0, + PSYC_SCHEME_IRC = 1, + PSYC_SCHEME_XMPP = 2, + PSYC_SCHEME_SIP = 3, +} psycScheme; + +typedef enum { + PSYC_TRANSPORT_TCP = 'c', + PSYC_TRANSPORT_UDP = 'd', + PSYC_TRANSPORT_TLS = 's', + PSYC_TRANSPORT_GNUNET = 'g', +} psycTransport; + +typedef enum { + PSYC_ENTITY_PERSON = '~', + PSYC_ENTITY_PLACE = '@', + PSYC_ENTITY_SERVICE = '$', +} psycEntityType; + +typedef psycString psycUniform[PSYC_UNIFORM_SIZE]; + +int psyc_parseUniform2(psycUniform *uni, const char *str, size_t length); + +int psyc_parseUniform(psycUniform *uni, psycString *str); + +#define PSYC_UNIFORM_H +#endif diff --git a/src/Makefile b/src/Makefile index da0452d..92d8218 100644 --- a/src/Makefile +++ b/src/Makefile @@ -3,8 +3,8 @@ DEBUG = 2 CFLAGS = -I../include -Wall -std=c99 -fPIC ${OPT} DIET = diet -S = packet.c parse.c match.c render.c memmem.c itoa.c variable.c text.c -O = packet.o parse.o match.o render.o memmem.o itoa.o variable.o text.o +S = packet.c parse.c match.c render.c memmem.c itoa.c variable.c text.c uniform.c +O = packet.o parse.o match.o render.o memmem.o itoa.o variable.o text.o uniform.o P = match itoa A = ../lib/libpsyc.a diff --git a/src/parse.c b/src/parse.c index 4248c7c..eaa85ad 100644 --- a/src/parse.c +++ b/src/parse.c @@ -23,58 +23,6 @@ typedef enum { PARSE_INCOMPLETE = 101, } parseRC; -/** - * Determines if the argument is a glyph. - * Glyphs are: : = + - ? ! - */ -static inline -char isGlyph (uint8_t g) -{ - switch(g) - { - case ':': - case '=': - case '+': - case '-': - case '?': - case '!': - return 1; - default: - return 0; - } -} - -/** - * Determines if the argument is numeric. - */ -static inline -char isNumeric (uint8_t c) -{ - return c >= '0' && c <= '9'; -} - -/** - * Determines if the argument is alphanumeric. - */ -static inline -char isAlphaNumeric (uint8_t c) -{ - return - (c >= 'a' && c <= 'z') || - (c >= 'A' && c <= 'Z') || - isNumeric(c); -} - -/** - * Determines if the argument is a keyword character. - * Keyword characters are: alphanumeric and _ - */ -static inline -char isKwChar (uint8_t c) -{ - return isAlphaNumeric(c) || c == '_'; -} - /** * Parse variable name or method name. * It should contain one or more keyword characters. @@ -86,7 +34,7 @@ parseRC psyc_parseKeyword (psycParseState *state, psycString *name) name->ptr = state->buffer.ptr + state->cursor; name->length = 0; - while (isKwChar(state->buffer.ptr[state->cursor])) + while (psyc_isKwChar(state->buffer.ptr[state->cursor])) { name->length++; // was a valid char, increase length ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); @@ -157,7 +105,7 @@ parseRC psyc_parseModifier (psycParseState *state, char *oper, { // After SP the length follows. ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); - if (isNumeric(state->buffer.ptr[state->cursor])) + if (psyc_isNumeric(state->buffer.ptr[state->cursor])) { state->valueLengthFound = 1; do @@ -165,7 +113,7 @@ parseRC psyc_parseModifier (psycParseState *state, char *oper, length = 10 * length + state->buffer.ptr[state->cursor] - '0'; ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } - while (isNumeric(state->buffer.ptr[state->cursor])); + while (psyc_isNumeric(state->buffer.ptr[state->cursor])); state->valueLength = length; } else @@ -249,7 +197,7 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, // 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? + if (psyc_isGlyph(state->buffer.ptr[state->cursor])) // is the first char a glyph? { // it is a glyph, so a variable starts here ret = psyc_parseModifier(state, oper, name, value); state->routingLength += state->cursor - pos; @@ -264,7 +212,7 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, case PSYC_PART_LENGTH: // End of header, content starts with an optional length then a NL - if (isNumeric(state->buffer.ptr[state->cursor])) + if (psyc_isNumeric(state->buffer.ptr[state->cursor])) { state->contentLengthFound = 1; state->contentLength = 0; @@ -274,7 +222,7 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, state->contentLength = 10 * state->contentLength + state->buffer.ptr[state->cursor] - '0'; ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } - while (isNumeric(state->buffer.ptr[state->cursor])); + while (psyc_isNumeric(state->buffer.ptr[state->cursor])); } if (state->buffer.ptr[state->cursor] == '\n') // start of content @@ -332,7 +280,7 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, // 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])) + if (psyc_isGlyph(state->buffer.ptr[state->cursor])) { ret = psyc_parseModifier(state, oper, name, value); state->contentParsed += state->cursor - pos; @@ -504,7 +452,7 @@ psycParseListRC psyc_parseList (psycParseListState *state, psycString *elem) state->type = PSYC_LIST_TEXT; state->cursor++; } - else if (isNumeric(state->buffer.ptr[state->cursor])) + else if (psyc_isNumeric(state->buffer.ptr[state->cursor])) state->type = PSYC_LIST_BINARY; else return PSYC_PARSE_LIST_ERROR_TYPE; @@ -532,14 +480,14 @@ psycParseListRC psyc_parseList (psycParseListState *state, psycString *elem) if (!(state->elemParsed < state->elemLength)) { // Element starts with a number. - if (isNumeric(state->buffer.ptr[state->cursor])) + if (psyc_isNumeric(state->buffer.ptr[state->cursor])) { do { state->elemLength = 10 * state->elemLength + state->buffer.ptr[state->cursor] - '0'; ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_LIST_INCOMPLETE); } - while (isNumeric(state->buffer.ptr[state->cursor])); + while (psyc_isNumeric(state->buffer.ptr[state->cursor])); } else return PSYC_PARSE_LIST_ERROR_LEN; diff --git a/src/uniform.c b/src/uniform.c new file mode 100644 index 0000000..ac61742 --- /dev/null +++ b/src/uniform.c @@ -0,0 +1,166 @@ +#include +#include "lib.h" +#include "psyc/uniform.h" +#include "psyc/parse.h" + +int psyc_parseUniform2 (psycUniform *uni, const char *str, size_t length) +{ + char c; + psycString *p; + size_t pos = 0, part = PSYC_UNIFORM_SCHEME, scheme; + + (*uni)[PSYC_UNIFORM_FULL].ptr = str; + (*uni)[PSYC_UNIFORM_FULL].length = length; + + while (pos < length) { + c = str[pos]; + if (c == ':') { + (*uni)[part].ptr = str; + (*uni)[part].length = pos++; + break; + } else if (!psyc_isHostChar(c)) + return PSYC_PARSE_UNIFORM_INVALID_SCHEME; + pos++; + } + + p = &(*uni)[PSYC_UNIFORM_SCHEME]; + if (p->length == 4 && + tolower(p->ptr[0]) == 'p' && + tolower(p->ptr[1]) == 's' && + tolower(p->ptr[2]) == 'y' && + tolower(p->ptr[3]) == 'c') { + scheme = PSYC_SCHEME_PSYC; + part = PSYC_UNIFORM_SLASHES; + (*uni)[part].ptr = str + pos; + (*uni)[part].length = 0; + + while (pos < length) { + c = str[pos]; + switch (part) { + case PSYC_UNIFORM_SLASHES: + if (c == '/') + (*uni)[part].length++; + else return PSYC_PARSE_UNIFORM_INVALID_SLASHES; + + if ((*uni)[part].length == 2) { + part = PSYC_UNIFORM_HOST; + (*uni)[part].ptr = str + pos + 1; + (*uni)[part].length = 0; + } + break; + + case PSYC_UNIFORM_HOST: + if (psyc_isHostChar(c)) { + (*uni)[part].length++; + break; + } + + if ((*uni)[part].length == 0) + return PSYC_PARSE_UNIFORM_INVALID_HOST; + + if (c == ':') + part = PSYC_UNIFORM_PORT; + else if (c == '/') + part = PSYC_UNIFORM_RESOURCE; + else return PSYC_PARSE_UNIFORM_INVALID_HOST; + + (*uni)[part].ptr = str + pos + 1; + (*uni)[part].length = 0; + break; + + case PSYC_UNIFORM_PORT: + if (psyc_isNumeric(c)) { + (*uni)[part].length++; + break; + } + + if ((*uni)[part].length == 0 && c != PSYC_TRANSPORT_GNUNET) + return PSYC_PARSE_UNIFORM_INVALID_PORT; + + if (c == '/') { + part = PSYC_UNIFORM_RESOURCE; + (*uni)[part].ptr = str + pos + 1; + (*uni)[part].length = 0; + break; + } + else { + part = PSYC_UNIFORM_TRANSPORT; + (*uni)[part].ptr = str + pos; + (*uni)[part].length = 0; + } + // fall thru + + case PSYC_UNIFORM_TRANSPORT: + switch (c) { + case PSYC_TRANSPORT_GNUNET: + if ((*uni)[PSYC_UNIFORM_PORT].length > 0) + return PSYC_PARSE_UNIFORM_INVALID_TRANSPORT; + case PSYC_TRANSPORT_TCP: + case PSYC_TRANSPORT_UDP: + case PSYC_TRANSPORT_TLS: + if ((*uni)[part].length > 0) + return PSYC_PARSE_UNIFORM_INVALID_TRANSPORT; + (*uni)[part].length++; + break; + case '/': + part = PSYC_UNIFORM_RESOURCE; + (*uni)[part].ptr = str + pos + 1; + (*uni)[part].length = 0; + break; + default: + return PSYC_PARSE_UNIFORM_INVALID_TRANSPORT; + } + break; + + case PSYC_UNIFORM_RESOURCE: + if (psyc_isNameChar(c)) { + (*uni)[part].length++; + break; + } else if (c == '#') { + part = PSYC_UNIFORM_CHANNEL; + (*uni)[part].ptr = str + pos + 1; + (*uni)[part].length = 0; + break; + } else return PSYC_PARSE_UNIFORM_INVALID_RESOURCE; + + case PSYC_UNIFORM_CHANNEL: + if (psyc_isNameChar(c)) { + (*uni)[part].length++; + break; + } else return PSYC_PARSE_UNIFORM_INVALID_CHANNEL; + } + pos++; + } + + if ((*uni)[PSYC_UNIFORM_HOST].length == 0) + return PSYC_PARSE_UNIFORM_INVALID_HOST; + + (*uni)[PSYC_UNIFORM_ROOT].ptr = str; + (*uni)[PSYC_UNIFORM_ROOT].length = (*uni)[PSYC_UNIFORM_SCHEME].length + 1 + + (*uni)[PSYC_UNIFORM_SLASHES].length + (*uni)[PSYC_UNIFORM_HOST].length + + (*uni)[PSYC_UNIFORM_PORT].length + (*uni)[PSYC_UNIFORM_TRANSPORT].length; + + if ((*uni)[PSYC_UNIFORM_PORT].length > 0 || + (*uni)[PSYC_UNIFORM_TRANSPORT].length > 0) + (*uni)[PSYC_UNIFORM_ROOT].length++; // : + + (*uni)[PSYC_UNIFORM_BODY].ptr = (*uni)[PSYC_UNIFORM_HOST].ptr; + (*uni)[PSYC_UNIFORM_BODY].length = length - (*uni)[PSYC_UNIFORM_SCHEME].length - 1 - + (*uni)[PSYC_UNIFORM_SLASHES].length; + + if ((*uni)[PSYC_UNIFORM_RESOURCE].length) { + (*uni)[PSYC_UNIFORM_NICK].ptr = (*uni)[PSYC_UNIFORM_RESOURCE].ptr + 1; + (*uni)[PSYC_UNIFORM_NICK].length = (*uni)[PSYC_UNIFORM_RESOURCE].length; + } + } else return PSYC_PARSE_UNIFORM_INVALID_SCHEME; + + if ((*uni)[PSYC_UNIFORM_HOST].length == 0) + return PSYC_PARSE_UNIFORM_INVALID_HOST; + + return scheme; +} + +int psyc_parseUniform (psycUniform *uni, psycString *str) +{ + return psyc_parseUniform2(uni, str->ptr, str->length); +} diff --git a/test/Makefile b/test/Makefile index b41e6bb..ed0de0b 100644 --- a/test/Makefile +++ b/test/Makefile @@ -3,7 +3,7 @@ DEBUG = 2 CFLAGS = -I../include -I../src -Wall -std=c99 ${OPT} LDFLAGS = -L../lib LOADLIBES = -lpsyc -lm -TARGETS = testPsyc testPsycSpeed testParser testMatch testRender testText isRoutingVar getVarType +TARGETS = testPsyc testPsycSpeed testParser testMatch testRender testText isRoutingVar getVarType parseUniform O = test.o WRAPPER = DIET = diet @@ -47,6 +47,7 @@ test: ${TARGETS} ./testText ./isRoutingVar ./getVarType + ./parseUniform x=0; for f in packets/[0-9]*; do echo ">> $$f"; ./testPsyc -f $$f | ${DIFF} -u $$f -; x=$$((x+$$?)); done; exit $$x x=0; for f in packets/[0-9]*; do echo ">> $$f"; ./testPsyc -rf $$f | ${DIFF} -u $$f -; x=$$((x+$$?)); done; exit $$x diff --git a/test/parseUniform.c b/test/parseUniform.c new file mode 100644 index 0000000..384dd5a --- /dev/null +++ b/test/parseUniform.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include + +void +testUniform(char *str, int ret) { + psycUniform *uni = malloc(sizeof(psycUniform)); + memset(uni, 0, sizeof(psycUniform)); + printf("%s\n", str); + int r = psyc_parseUniform2(uni, str, strlen(str)); + + PP(("[%.*s] : [%.*s] [%.*s] : [%.*s] [%.*s] / [%.*s] # [%.*s]\n[%.*s] [%.*s]\n[%.*s]\n\n", + (int)PSYC_S2ARG2((*uni)[PSYC_UNIFORM_SCHEME]), + (int)PSYC_S2ARG2((*uni)[PSYC_UNIFORM_SLASHES]), + (int)PSYC_S2ARG2((*uni)[PSYC_UNIFORM_HOST]), + (int)PSYC_S2ARG2((*uni)[PSYC_UNIFORM_PORT]), + (int)PSYC_S2ARG2((*uni)[PSYC_UNIFORM_TRANSPORT]), + (int)PSYC_S2ARG2((*uni)[PSYC_UNIFORM_RESOURCE]), + (int)PSYC_S2ARG2((*uni)[PSYC_UNIFORM_CHANNEL]), + (int)PSYC_S2ARG2((*uni)[PSYC_UNIFORM_ROOT]), + (int)PSYC_S2ARG2((*uni)[PSYC_UNIFORM_NICK]), + (int)PSYC_S2ARG2((*uni)[PSYC_UNIFORM_BODY]))); + + free(uni); + if (r != ret) { + fprintf(stderr, "ERROR: psyc_parseUniform returned %d instead of %d\n", r, ret); + exit(1); + } +} + +int main() { + testUniform("psyc://foo.tld:4404d/@bar#baz", PSYC_SCHEME_PSYC); + testUniform("psyc://foo:4405/~bar", PSYC_SCHEME_PSYC); + testUniform("psyc://foo:1234", PSYC_SCHEME_PSYC); + testUniform("psyc://foo:1234d", PSYC_SCHEME_PSYC); + testUniform("psyc://foo/", PSYC_SCHEME_PSYC); + testUniform("psyc://foo", PSYC_SCHEME_PSYC); + testUniform("psyc://1234567890abcdef:g/~foo", PSYC_SCHEME_PSYC); + + testUniform("xmpp:user@host", PSYC_PARSE_UNIFORM_INVALID_SCHEME); + testUniform("psyc:host", PSYC_PARSE_UNIFORM_INVALID_SLASHES); + testUniform("psyc://", PSYC_PARSE_UNIFORM_INVALID_HOST); + testUniform("psyc://:123/", PSYC_PARSE_UNIFORM_INVALID_HOST); + testUniform("psyc://host:/~foo", PSYC_PARSE_UNIFORM_INVALID_PORT); + testUniform("psyc://host:d/~foo", PSYC_PARSE_UNIFORM_INVALID_PORT); + testUniform("psyc://1234567890abcdef:1g/~foo", PSYC_PARSE_UNIFORM_INVALID_TRANSPORT); + + printf("SUCCESS: psyc_parseUniform passed all tests.\n"); + return 0; +} From 4c7b78aecc428952b2bc628d87ced2385096f283 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 14 Oct 2011 00:31:43 +0200 Subject: [PATCH 327/378] testPsyc beautify --- test/testPsyc.c | 85 +++++++++++++++++++++++++------------------------ 1 file changed, 44 insertions(+), 41 deletions(-) diff --git a/test/testPsyc.c b/test/testPsyc.c index 43e969e..2deb620 100644 --- a/test/testPsyc.c +++ b/test/testPsyc.c @@ -65,6 +65,9 @@ int test_input (int i, char *recvbuf, size_t nbytes) { * to this function together with the new data. */ + psycParseState *parser = &parsers[i]; + psycPacket *packet = &packets[i]; + char oper; psycString name, value, elem; psycString *pname = NULL, *pvalue = NULL; @@ -73,7 +76,7 @@ int test_input (int i, char *recvbuf, size_t nbytes) { size_t len; // Set buffer with data for the parser. - psyc_setParseBuffer2(&parsers[i], parsebuf, contbytes + nbytes); + psyc_setParseBuffer2(parser, parsebuf, contbytes + nbytes); contbytes = 0; oper = 0; name.length = 0; @@ -81,34 +84,34 @@ int test_input (int i, char *recvbuf, size_t nbytes) { do { if (verbose >= 3) - printf("\n# buffer = [%.*s]\n# part = %d\n", (int)parsers[i].buffer.length, parsers[i].buffer.ptr, parsers[i].part); + printf("\n# buffer = [%.*s]\n# part = %d\n", (int)parser->buffer.length, parser->buffer.ptr, parser->part); // Parse the next part of the packet (a routing/entity modifier or the body) - ret = exit_code = psyc_parse(&parsers[i], &oper, &name, &value); + ret = exit_code = psyc_parse(parser, &oper, &name, &value); if (verbose >= 2) printf("# ret = %d\n", ret); switch (ret) { case PSYC_PARSE_ROUTING: - assert(packets[i].routing.lines < ROUTING_LINES); - mod = &(packets[i].routing.modifiers[packets[i].routing.lines]); + assert(packet->routing.lines < ROUTING_LINES); + mod = &(packet->routing.modifiers[packet->routing.lines]); pname = &mod->name; pvalue = &mod->value; mod->flag = PSYC_MODIFIER_ROUTING; - packets[i].routing.lines++; + packet->routing.lines++; break; case PSYC_PARSE_ENTITY_START: case PSYC_PARSE_ENTITY_CONT: case PSYC_PARSE_ENTITY_END: case PSYC_PARSE_ENTITY: - assert(packets[i].entity.lines < ENTITY_LINES); - mod = &(packets[i].entity.modifiers[packets[i].entity.lines]); + assert(packet->entity.lines < ENTITY_LINES); + mod = &(packet->entity.modifiers[packet->entity.lines]); pname = &mod->name; pvalue = &mod->value; if (ret == PSYC_PARSE_ENTITY || ret == PSYC_PARSE_ENTITY_END) { - packets[i].entity.lines++; - mod->flag = psyc_isParseValueLengthFound(&parsers[i]) ? + packet->entity.lines++; + mod->flag = psyc_isParseValueLengthFound(parser) ? PSYC_MODIFIER_NEED_LENGTH : PSYC_MODIFIER_NO_LENGTH; } break; @@ -117,8 +120,8 @@ int test_input (int i, char *recvbuf, size_t nbytes) { case PSYC_PARSE_BODY_CONT: case PSYC_PARSE_BODY_END: case PSYC_PARSE_BODY: - pname = &(packets[i].method); - pvalue = &(packets[i].data); + pname = &(packet->method); + pvalue = &(packet->data); break; case PSYC_PARSE_COMPLETE: @@ -130,22 +133,22 @@ int test_input (int i, char *recvbuf, size_t nbytes) { ret = -1; if (!no_render) { - packets[i].flag = psyc_isParseContentLengthFound(&parsers[i]) ? + packet->flag = psyc_isParseContentLengthFound(parser) ? PSYC_PACKET_NEED_LENGTH : PSYC_PACKET_NO_LENGTH; if (routing_only) { - packets[i].content = packets[i].data; - resetString(&packets[i].data, 0); + packet->content = packet->data; + resetString(&(packet->data), 0); } - psyc_setPacketLength(&packets[i]); + psyc_setPacketLength(packet); - if (psyc_render(&packets[i], sendbuf, SEND_BUF_SIZE) == PSYC_RENDER_SUCCESS) { + if (psyc_render(packet, sendbuf, SEND_BUF_SIZE) == PSYC_RENDER_SUCCESS) { if (!quiet) { - if (filename && write(1, sendbuf, packets[i].length) == -1) { + if (filename && write(1, sendbuf, packet->length) == -1) { perror("write"); ret = -1; - } else if (!filename && send(i, sendbuf, packets[i].length, 0) == -1) { + } else if (!filename && send(i, sendbuf, packet->length, 0) == -1) { perror("send"); ret = -1; } @@ -157,28 +160,28 @@ int test_input (int i, char *recvbuf, size_t nbytes) { } // reset packet - packets[i].routingLength = 0; - packets[i].contentLength = 0; - packets[i].length = 0; - packets[i].flag = 0; + packet->routingLength = 0; + packet->contentLength = 0; + packet->length = 0; + packet->flag = 0; - for (j = 0; j < packets[i].routing.lines; j++) { - resetString(&packets[i].routing.modifiers[j].name, 1); - resetString(&packets[i].routing.modifiers[j].value, 1); + for (j = 0; j < packet->routing.lines; j++) { + resetString(&(packet->routing.modifiers[j].name), 1); + resetString(&(packet->routing.modifiers[j].value), 1); } - packets[i].routing.lines = 0; + packet->routing.lines = 0; if (routing_only) { - resetString(&packets[i].content, 1); + resetString(&(packet->content), 1); } else { - for (j = 0; j < packets[i].entity.lines; j++) { - resetString(&packets[i].entity.modifiers[j].name, 1); - resetString(&packets[i].entity.modifiers[j].value, 1); + for (j = 0; j < packet->entity.lines; j++) { + resetString(&(packet->entity.modifiers[j].name), 1); + resetString(&(packet->entity.modifiers[j].value), 1); } - packets[i].entity.lines = 0; + packet->entity.lines = 0; - resetString(&packets[i].method, 1); - resetString(&packets[i].data, 1); + resetString(&(packet->method), 1); + resetString(&(packet->data), 1); } break; @@ -187,13 +190,13 @@ int test_input (int i, char *recvbuf, size_t nbytes) { if (verbose >= 2) printf("# Insufficient data.\n"); - contbytes = psyc_getParseRemainingLength(&parsers[i]); + contbytes = psyc_getParseRemainingLength(parser); if (contbytes > 0) { // copy end of parsebuf before start of recvbuf if (verbose >= 3) - printf("# remaining = [%.*s]\n", (int)contbytes, psyc_getParseRemainingBuffer(&parsers[i])); + printf("# remaining = [%.*s]\n", (int)contbytes, psyc_getParseRemainingBuffer(parser)); assert(contbytes <= CONT_BUF_SIZE); // make sure it's still in the buffer - memmove(recvbuf - contbytes, psyc_getParseRemainingBuffer(&parsers[i]), contbytes); + memmove(recvbuf - contbytes, psyc_getParseRemainingBuffer(parser), contbytes); } ret = 0; break; @@ -234,8 +237,8 @@ int test_input (int i, char *recvbuf, size_t nbytes) { if (value.length) { if (!pvalue->length) { - if (psyc_isParseValueLengthFound(&parsers[i])) - len = psyc_getParseValueLength(&parsers[i]); + if (psyc_isParseValueLengthFound(parser)) + len = psyc_getParseValueLength(parser); else len = value.length; pvalue->ptr = malloc(len); @@ -247,7 +250,7 @@ int test_input (int i, char *recvbuf, size_t nbytes) { if (verbose >= 2) { printf("[%.*s]", (int)pvalue->length, pvalue->ptr); - if (parsers[i].valueLength > pvalue->length) + if (parser->valueLength > pvalue->length) printf("..."); printf("\n"); } @@ -258,7 +261,7 @@ int test_input (int i, char *recvbuf, size_t nbytes) { if (verbose >= 3) printf("\t\t\t\t\t\t\t\t# n:%ld v:%ld c:%ld r:%ld\n", pname->length, pvalue->length, - parsers[i].contentParsed, parsers[i].routingLength); + parser->contentParsed, parser->routingLength); } switch (ret) { From 4b0705d697c4bd5368d83370362245b8aedce7c1 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 14 Oct 2011 01:16:09 +0200 Subject: [PATCH 328/378] uniform struct --- include/psyc/uniform.h | 65 +++++++++++++++----------- src/uniform.c | 104 +++++++++++++++++++++-------------------- test/parseUniform.c | 20 ++++---- 3 files changed, 102 insertions(+), 87 deletions(-) diff --git a/include/psyc/uniform.h b/include/psyc/uniform.h index 9f338f8..a07f3b7 100644 --- a/include/psyc/uniform.h +++ b/include/psyc/uniform.h @@ -7,27 +7,47 @@ #include typedef enum { + PSYC_SCHEME_PSYC = 0, + PSYC_SCHEME_IRC = 1, + PSYC_SCHEME_XMPP = 2, + PSYC_SCHEME_SIP = 3, +} psycScheme; + +typedef struct { // essential parts - PSYC_UNIFORM_SCHEME = 0, - PSYC_UNIFORM_USER = 1, - PSYC_UNIFORM_PASS = 2, - PSYC_UNIFORM_HOST = 3, - PSYC_UNIFORM_PORT = 4, - PSYC_UNIFORM_TRANSPORT = 5, - PSYC_UNIFORM_RESOURCE = 6, - PSYC_UNIFORM_QUERY = 7, - PSYC_UNIFORM_CHANNEL = 8, + psycScheme type; + psycString scheme; + psycString user; + psycString pass; + psycString host; + psycString port; + psycString transport; + psycString resource; + psycString query; + psycString channel; // convenient snippets of the URL - PSYC_UNIFORM_FULL = 9, // the URL as such - PSYC_UNIFORM_BODY = 10, // the URL without scheme and '//' - PSYC_UNIFORM_USERATHOST = 11, // mailto and xmpp style - PSYC_UNIFORM_HOSTPORT = 12, // just host:port (and transport) - PSYC_UNIFORM_ROOT = 13, // root UNI of peer/server - PSYC_UNIFORM_SLASHES = 14, // the // if the protocol has them - PSYC_UNIFORM_NICK = 15, // whatever works as a nickname - PSYC_UNIFORM_SIZE = 16, -} psycUniformField; + psycString full; // the URL as such + psycString body; // the URL without scheme and '//' + psycString user_host; // mailto and xmpp style + psycString host_port; // just host:port (and transport) + psycString root; // root UNI of peer/server + psycString slashes; // the // if the protocol has them + psycString nick; // whatever works as a nickname +} psycUniform; + +typedef enum { + PSYC_UNIFORM_SCHEME = 0, + PSYC_UNIFORM_SLASHES, + PSYC_UNIFORM_USER, + PSYC_UNIFORM_PASS, + PSYC_UNIFORM_HOST, + PSYC_UNIFORM_PORT, + PSYC_UNIFORM_TRANSPORT, + PSYC_UNIFORM_RESOURCE, + PSYC_UNIFORM_QUERY, + PSYC_UNIFORM_CHANNEL, +} psycUniformPart; typedef enum { PSYC_PARSE_UNIFORM_INVALID_SLASHES = -7, @@ -39,13 +59,6 @@ typedef enum { PSYC_PARSE_UNIFORM_INVALID_SCHEME = -1, } psycParseUniformRC; -typedef enum { - PSYC_SCHEME_PSYC = 0, - PSYC_SCHEME_IRC = 1, - PSYC_SCHEME_XMPP = 2, - PSYC_SCHEME_SIP = 3, -} psycScheme; - typedef enum { PSYC_TRANSPORT_TCP = 'c', PSYC_TRANSPORT_UDP = 'd', @@ -59,8 +72,6 @@ typedef enum { PSYC_ENTITY_SERVICE = '$', } psycEntityType; -typedef psycString psycUniform[PSYC_UNIFORM_SIZE]; - int psyc_parseUniform2(psycUniform *uni, const char *str, size_t length); int psyc_parseUniform(psycUniform *uni, psycString *str); diff --git a/src/uniform.c b/src/uniform.c index ac61742..5a52158 100644 --- a/src/uniform.c +++ b/src/uniform.c @@ -7,105 +7,109 @@ int psyc_parseUniform2 (psycUniform *uni, const char *str, size_t length) { char c; psycString *p; - size_t pos = 0, part = PSYC_UNIFORM_SCHEME, scheme; + size_t pos = 0, part = PSYC_UNIFORM_SCHEME; - (*uni)[PSYC_UNIFORM_FULL].ptr = str; - (*uni)[PSYC_UNIFORM_FULL].length = length; + uni->full.ptr = str; + uni->full.length = length; while (pos < length) { c = str[pos]; if (c == ':') { - (*uni)[part].ptr = str; - (*uni)[part].length = pos++; + uni->scheme.ptr = str; + uni->scheme.length = pos++; break; } else if (!psyc_isHostChar(c)) return PSYC_PARSE_UNIFORM_INVALID_SCHEME; pos++; } - p = &(*uni)[PSYC_UNIFORM_SCHEME]; + p = &uni->scheme; if (p->length == 4 && tolower(p->ptr[0]) == 'p' && tolower(p->ptr[1]) == 's' && tolower(p->ptr[2]) == 'y' && tolower(p->ptr[3]) == 'c') { - scheme = PSYC_SCHEME_PSYC; + + uni->type = PSYC_SCHEME_PSYC; part = PSYC_UNIFORM_SLASHES; - (*uni)[part].ptr = str + pos; - (*uni)[part].length = 0; + uni->slashes.ptr = str + pos; + uni->slashes.length = 0; while (pos < length) { c = str[pos]; switch (part) { case PSYC_UNIFORM_SLASHES: if (c == '/') - (*uni)[part].length++; + uni->slashes.length++; else return PSYC_PARSE_UNIFORM_INVALID_SLASHES; - if ((*uni)[part].length == 2) { + if (uni->slashes.length == 2) { part = PSYC_UNIFORM_HOST; - (*uni)[part].ptr = str + pos + 1; - (*uni)[part].length = 0; + uni->host.ptr = str + pos + 1; + uni->host.length = 0; } break; case PSYC_UNIFORM_HOST: if (psyc_isHostChar(c)) { - (*uni)[part].length++; + uni->host.length++; break; } - if ((*uni)[part].length == 0) + if (uni->host.length == 0) return PSYC_PARSE_UNIFORM_INVALID_HOST; - if (c == ':') + if (c == ':') { part = PSYC_UNIFORM_PORT; - else if (c == '/') + p = &uni->port; + } else if (c == '/') { part = PSYC_UNIFORM_RESOURCE; + p = &uni->resource; + } else return PSYC_PARSE_UNIFORM_INVALID_HOST; - (*uni)[part].ptr = str + pos + 1; - (*uni)[part].length = 0; + p->ptr = str + pos + 1; + p->length = 0; break; case PSYC_UNIFORM_PORT: if (psyc_isNumeric(c)) { - (*uni)[part].length++; + uni->port.length++; break; } - if ((*uni)[part].length == 0 && c != PSYC_TRANSPORT_GNUNET) + if (uni->port.length == 0 && c != PSYC_TRANSPORT_GNUNET) return PSYC_PARSE_UNIFORM_INVALID_PORT; if (c == '/') { part = PSYC_UNIFORM_RESOURCE; - (*uni)[part].ptr = str + pos + 1; - (*uni)[part].length = 0; + uni->resource.ptr = str + pos + 1; + uni->resource.length = 0; break; } else { part = PSYC_UNIFORM_TRANSPORT; - (*uni)[part].ptr = str + pos; - (*uni)[part].length = 0; + uni->transport.ptr = str + pos; + uni->transport.length = 0; } // fall thru case PSYC_UNIFORM_TRANSPORT: switch (c) { case PSYC_TRANSPORT_GNUNET: - if ((*uni)[PSYC_UNIFORM_PORT].length > 0) + if (uni->port.length > 0) return PSYC_PARSE_UNIFORM_INVALID_TRANSPORT; case PSYC_TRANSPORT_TCP: case PSYC_TRANSPORT_UDP: case PSYC_TRANSPORT_TLS: - if ((*uni)[part].length > 0) + if (uni->transport.length > 0) return PSYC_PARSE_UNIFORM_INVALID_TRANSPORT; - (*uni)[part].length++; + uni->transport.length++; break; case '/': part = PSYC_UNIFORM_RESOURCE; - (*uni)[part].ptr = str + pos + 1; - (*uni)[part].length = 0; + uni->resource.ptr = str + pos + 1; + uni->resource.length = 0; break; default: return PSYC_PARSE_UNIFORM_INVALID_TRANSPORT; @@ -114,50 +118,50 @@ int psyc_parseUniform2 (psycUniform *uni, const char *str, size_t length) case PSYC_UNIFORM_RESOURCE: if (psyc_isNameChar(c)) { - (*uni)[part].length++; + uni->resource.length++; break; } else if (c == '#') { part = PSYC_UNIFORM_CHANNEL; - (*uni)[part].ptr = str + pos + 1; - (*uni)[part].length = 0; + uni->channel.ptr = str + pos + 1; + uni->channel.length = 0; break; } else return PSYC_PARSE_UNIFORM_INVALID_RESOURCE; case PSYC_UNIFORM_CHANNEL: if (psyc_isNameChar(c)) { - (*uni)[part].length++; + uni->channel.length++; break; } else return PSYC_PARSE_UNIFORM_INVALID_CHANNEL; } pos++; } - if ((*uni)[PSYC_UNIFORM_HOST].length == 0) + if (uni->host.length == 0) return PSYC_PARSE_UNIFORM_INVALID_HOST; - (*uni)[PSYC_UNIFORM_ROOT].ptr = str; - (*uni)[PSYC_UNIFORM_ROOT].length = (*uni)[PSYC_UNIFORM_SCHEME].length + 1 + - (*uni)[PSYC_UNIFORM_SLASHES].length + (*uni)[PSYC_UNIFORM_HOST].length + - (*uni)[PSYC_UNIFORM_PORT].length + (*uni)[PSYC_UNIFORM_TRANSPORT].length; + uni->host_port.ptr = uni->host.ptr; + uni->host_port.length = uni->host.length + uni->port.length + uni->transport.length; + if (uni->port.length > 0 || uni->transport.length > 0) + uni->host_port.length++; - if ((*uni)[PSYC_UNIFORM_PORT].length > 0 || - (*uni)[PSYC_UNIFORM_TRANSPORT].length > 0) - (*uni)[PSYC_UNIFORM_ROOT].length++; // : + uni->root.ptr = str; + uni->root.length = uni->scheme.length + 1 + uni->slashes.length + + uni->host_port.length; - (*uni)[PSYC_UNIFORM_BODY].ptr = (*uni)[PSYC_UNIFORM_HOST].ptr; - (*uni)[PSYC_UNIFORM_BODY].length = length - (*uni)[PSYC_UNIFORM_SCHEME].length - 1 - - (*uni)[PSYC_UNIFORM_SLASHES].length; + uni->body.ptr = uni->host.ptr; + uni->body.length = length - uni->scheme.length - 1 - uni->slashes.length; - if ((*uni)[PSYC_UNIFORM_RESOURCE].length) { - (*uni)[PSYC_UNIFORM_NICK].ptr = (*uni)[PSYC_UNIFORM_RESOURCE].ptr + 1; - (*uni)[PSYC_UNIFORM_NICK].length = (*uni)[PSYC_UNIFORM_RESOURCE].length; + if (uni->resource.length) { + uni->nick.ptr = uni->resource.ptr + 1; + uni->nick.length = uni->resource.length; } + } else return PSYC_PARSE_UNIFORM_INVALID_SCHEME; - if ((*uni)[PSYC_UNIFORM_HOST].length == 0) + if (uni->host.length == 0) return PSYC_PARSE_UNIFORM_INVALID_HOST; - return scheme; + return uni->type; } int psyc_parseUniform (psycUniform *uni, psycString *str) diff --git a/test/parseUniform.c b/test/parseUniform.c index 384dd5a..ae20c5e 100644 --- a/test/parseUniform.c +++ b/test/parseUniform.c @@ -11,16 +11,16 @@ testUniform(char *str, int ret) { int r = psyc_parseUniform2(uni, str, strlen(str)); PP(("[%.*s] : [%.*s] [%.*s] : [%.*s] [%.*s] / [%.*s] # [%.*s]\n[%.*s] [%.*s]\n[%.*s]\n\n", - (int)PSYC_S2ARG2((*uni)[PSYC_UNIFORM_SCHEME]), - (int)PSYC_S2ARG2((*uni)[PSYC_UNIFORM_SLASHES]), - (int)PSYC_S2ARG2((*uni)[PSYC_UNIFORM_HOST]), - (int)PSYC_S2ARG2((*uni)[PSYC_UNIFORM_PORT]), - (int)PSYC_S2ARG2((*uni)[PSYC_UNIFORM_TRANSPORT]), - (int)PSYC_S2ARG2((*uni)[PSYC_UNIFORM_RESOURCE]), - (int)PSYC_S2ARG2((*uni)[PSYC_UNIFORM_CHANNEL]), - (int)PSYC_S2ARG2((*uni)[PSYC_UNIFORM_ROOT]), - (int)PSYC_S2ARG2((*uni)[PSYC_UNIFORM_NICK]), - (int)PSYC_S2ARG2((*uni)[PSYC_UNIFORM_BODY]))); + (int)PSYC_S2ARG2(uni->scheme), + (int)PSYC_S2ARG2(uni->slashes), + (int)PSYC_S2ARG2(uni->host), + (int)PSYC_S2ARG2(uni->port), + (int)PSYC_S2ARG2(uni->transport), + (int)PSYC_S2ARG2(uni->resource), + (int)PSYC_S2ARG2(uni->channel), + (int)PSYC_S2ARG2(uni->root), + (int)PSYC_S2ARG2(uni->nick), + (int)PSYC_S2ARG2(uni->body))); free(uni); if (r != ret) { From a9942c9830bb3fbf9bd923e984bce7db135b41aa Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sun, 23 Oct 2011 00:13:42 +0200 Subject: [PATCH 329/378] uniform - added 'valid' member; macro fix --- include/psyc.h | 10 +++++----- include/psyc/uniform.h | 1 + src/uniform.c | 2 ++ 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/include/psyc.h b/include/psyc.h index 416f9eb..692e5c6 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -22,10 +22,10 @@ #define PSYC_EPOCH 1440444041 // 2015-08-24 21:20:41 CET (Monday) -#define PSYC_C2STR(string) {sizeof(string)-1, string} -#define PSYC_C2ARG(string) string, sizeof(string)-1 -#define PSYC_S2ARG(string) string.ptr, string.length -#define PSYC_S2ARG2(string) string.length, string.ptr +#define PSYC_C2STR(str) {sizeof(str)-1, str} +#define PSYC_C2ARG(str) str, sizeof(str)-1 +#define PSYC_S2ARG(str) (str).ptr, (str).length +#define PSYC_S2ARG2(str) (str).length, (str).ptr typedef enum { @@ -92,7 +92,7 @@ typedef struct /// Length of the data pointed to by ptr size_t length; /// pointer to the data - const char *ptr; + char *ptr; } psycString; typedef struct diff --git a/include/psyc/uniform.h b/include/psyc/uniform.h index a07f3b7..24324cf 100644 --- a/include/psyc/uniform.h +++ b/include/psyc/uniform.h @@ -15,6 +15,7 @@ typedef enum { typedef struct { // essential parts + uint8_t valid; psycScheme type; psycString scheme; psycString user; diff --git a/src/uniform.c b/src/uniform.c index 5a52158..519e5c0 100644 --- a/src/uniform.c +++ b/src/uniform.c @@ -9,6 +9,7 @@ int psyc_parseUniform2 (psycUniform *uni, const char *str, size_t length) psycString *p; size_t pos = 0, part = PSYC_UNIFORM_SCHEME; + uni->valid = 0; uni->full.ptr = str; uni->full.length = length; @@ -161,6 +162,7 @@ int psyc_parseUniform2 (psycUniform *uni, const char *str, size_t length) if (uni->host.length == 0) return PSYC_PARSE_UNIFORM_INVALID_HOST; + uni->valid = 1; return uni->type; } From e82d444c3d637c9a9b13f966ee32374fa2b8230d Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sun, 30 Oct 2011 16:04:54 +0100 Subject: [PATCH 330/378] find var in array --- .gitignore | 1 + include/psyc.h | 20 +++++++++++++++++ src/variable.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 79 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index a193596..3459b4b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ lib/libpsyc.a +lib/libpsyc.so doc/html doc/latex doc/man diff --git a/include/psyc.h b/include/psyc.h index 692e5c6..192c6ed 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -31,6 +31,8 @@ typedef enum { PSYC_FALSE = 0, PSYC_TRUE = 1, + PSYC_NO = 0, + PSYC_YES = 1, } psycBool; /** @@ -149,6 +151,24 @@ psycType psyc_getVarType(psycString *name); */ psycType psyc_getVarType2(const char *name, size_t len); +/** + * Search for a variable name in an array. + * + * @param array The array to search, should be ordered alphabetically. + * @param size Size of array. + * @param name Name of variable to look for. + * @param namelen Length of name. + * @param startswith If true, look for any variable starting with name, + otherwise only exact matches are returned. + * @param matching A temporary array used for keeping track of results. + * Should be the same size as the array we're searching. + * + * @return The value of the matched variable in the array. + */ +int psyc_findVar(const psycMatchVar *array, size_t size, + const char *name, size_t namelen, + uint8_t startswith, int8_t *matching); + /** * Is this a list variable name? */ diff --git a/src/variable.c b/src/variable.c index 472e105..b0de9f5 100644 --- a/src/variable.c +++ b/src/variable.c @@ -120,7 +120,8 @@ psycType psyc_getVarType2(const char *name, size_t len) { if (matching[i] < 0) break; // reached the end of possible matches - if (cursor < psyc_varTypes[matching[i]].name.length && psyc_varTypes[matching[i]].name.ptr[cursor] == name[cursor]) + if (cursor < psyc_varTypes[matching[i]].name.length && + psyc_varTypes[matching[i]].name.ptr[cursor] == name[cursor]) matching[m++] = matching[i]; // found a match, update matching indexes else if (cursor == psyc_varTypes[matching[i]].name.length && name[cursor] == '_') return psyc_varTypes[matching[0]].value; // _ after the end of a matching prefix @@ -142,3 +143,59 @@ psycType psyc_getVarType(psycString *name) { return psyc_getVarType2(name->ptr, name->length); } + +/** + * Search for a variable name in an array. + * + * @param array The array to search, should be ordered alphabetically. + * @param size Size of array. + * @param name Name of variable to look for. + * @param namelen Length of name. + * @param startswith If true, look for any variable starting with name, + otherwise only exact matches are returned. + * @param matching A temporary array used for keeping track of results. + * Should be the same size as the array we're searching. + * + * @return The value of the matched variable in the array. + */ +int psyc_findVar(const psycMatchVar *array, size_t size, + const char *name, size_t namelen, + uint8_t startswith, int8_t *matching) +{ + size_t cursor = 1; + uint8_t i, m = 0; + //memset(&matching, -1, sizeof matching); + + if (namelen < 2 || name[0] != '_') + return 0; + + // first find the vars with matching length + for (i=0; i array[i].name.length && + name[array[i].name.length] == '_')) + matching[m++] = i; + + matching[m] = -1; // mark the end of matching indexes + + while (cursor < namelen && matching[0] >= 0) + { + for (i = m = 0; i < size; i++) + { + if (matching[i] < 0) + break; + if (array[matching[i]].name.ptr[cursor] == name[cursor]) + matching[m++] = matching[i]; // found a match, update matching indexes + else if (array[matching[i]].name.ptr[cursor] > name[cursor]) + break; // passed the possible matches in alphabetical order + } + + if (m < size) + matching[m] = -1; // mark the end of matching indexes + + cursor++; + } + + // return first match if found + return matching[0] >= 0 ? array[matching[0]].value : 0; +} From 6a994e2eb2c188b9f110f15315f7bbcf692f196f Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 31 Oct 2011 20:04:16 +0100 Subject: [PATCH 331/378] refactoring - renamed functions --- .gitignore | 25 ++-- d/include/psyc/common.d | 8 +- d/include/psyc/packet.d | 43 ++---- d/include/psyc/parse.d | 2 +- d/include/psyc/render.d | 14 +- doc/renames | 66 +++++++++ include/psyc.h | 82 +++-------- include/psyc/packet.h | 79 +++++------ include/psyc/parse.h | 144 ++++++-------------- include/psyc/render.h | 14 +- include/psyc/text.h | 38 ++---- include/psyc/uniform.h | 4 +- include/psyc/variable.h | 37 +++++ pike/psyc.cmod | 52 +++---- src/lib.h | 2 - src/match.c | 64 ++++++++- src/packet.c | 89 ++++-------- src/parse.c | 44 +++--- src/psyc_parser_cb.h | 4 +- src/render.c | 8 +- src/uniform.c | 17 +-- src/variable.c | 134 +++--------------- test/Makefile | 72 +++++----- test/getVarType.c | 21 --- test/isRoutingVar.c | 39 ------ test/{testJson.c => test_json.c} | 0 test/{testJsonGlib.c => test_json_glib.c} | 0 test/{testMatch.c => test_match.c} | 0 test/{testParser.c => test_parser.c} | 17 +-- test/{testPsyc.c => test_psyc.c} | 32 ++--- test/{testPsycSpeed.c => test_psyc_speed.c} | 8 +- test/{testRender.c => test_render.c} | 26 ++-- test/{testStrlen.c => test_strlen.c} | 0 test/{testText.c => test_text.c} | 6 +- test/{parseUniform.c => uniform_parse.c} | 10 +- test/var_is_routing.c | 39 ++++++ test/var_type.c | 21 +++ 37 files changed, 570 insertions(+), 691 deletions(-) create mode 100644 doc/renames create mode 100644 include/psyc/variable.h delete mode 100644 test/getVarType.c delete mode 100644 test/isRoutingVar.c rename test/{testJson.c => test_json.c} (100%) rename test/{testJsonGlib.c => test_json_glib.c} (100%) rename test/{testMatch.c => test_match.c} (100%) rename test/{testParser.c => test_parser.c} (84%) rename test/{testPsyc.c => test_psyc.c} (90%) rename test/{testPsycSpeed.c => test_psyc_speed.c} (88%) rename test/{testRender.c => test_render.c} (76%) rename test/{testStrlen.c => test_strlen.c} (100%) rename test/{testText.c => test_text.c} (92%) rename test/{parseUniform.c => uniform_parse.c} (86%) create mode 100644 test/var_is_routing.c create mode 100644 test/var_type.c diff --git a/.gitignore b/.gitignore index 3459b4b..d3efafe 100644 --- a/.gitignore +++ b/.gitignore @@ -7,18 +7,19 @@ d/doc/html d/doc/latex d/doc/man src/match -test/testMatch -test/testParser -test/testRender -test/testPsyc -test/testPsycSpeed -test/testJson -test/testJsonGlib -test/testStrlen -test/testText -test/isRoutingVar -test/getVarType -test/parseUniform +test/test_list +test/test_match +test/test_parser +test/test_render +test/test_psyc +test/test_psyc_speed +test/test_json +test/test_json_glib +test/test_strlen +test/test_text +test/var_is_routing +test/var_type +test/uniform_parse perl/*.c perl/*.so diff --git a/d/include/psyc/common.d b/d/include/psyc/common.d index ecaba77..21938f9 100644 --- a/d/include/psyc/common.d +++ b/d/include/psyc/common.d @@ -97,19 +97,19 @@ extern (C) MatchVar varTypes[]; /** * Get the type of variable name. */ -Bool psyc_isRoutingVar (char[]* name); +Bool psyc_var_is_routing (char* name, size_t len); bool isRoutingVar (char[] name) { - return psyc_isRoutingVar(&name); + return psyc_var_is_routing(name.ptr, name.length); //FIXME } /** * Get the type of variable name. */ -Type psyc_getVarType(char *name, size_t len); +Type psyc_var_type(char *name, size_t len); -alias psyc_getVarType getVarType; +alias psyc_var_type getVarType; /** * Checks if long keyword string inherits from short keyword string. diff --git a/d/include/psyc/packet.d b/d/include/psyc/packet.d index 3846b3f..da544e0 100644 --- a/d/include/psyc/packet.d +++ b/d/include/psyc/packet.d @@ -96,7 +96,7 @@ struct Modifier size_t length ( ) { - return psyc_getModifierLength (this); + return psyc_modifier_length (this); } private ModifierFlag checkLength ( ubyte[] value ) @@ -142,24 +142,24 @@ struct Packet char[] method, ubyte[] data, PacketFlag flag = PacketFlag.CHECK_LENGTH) { - return psyc_newPacket (&routing, &entity, cast(ubyte[]*)&method, &data, flag); + return psyc_packet_new(&routing, &entity, cast(ubyte[]*)&method, &data, flag); // FIXME } static Packet opCall (Modifier[] routing, ubyte[] content, PacketFlag flag = PacketFlag.CHECK_LENGTH) { - return psyc_newRawPacket (&routing, &content, flag); + return psyc_packet_new_raw(&routing, &content, flag); // FIXME } size_t length ( ) { - psyc_setPacketLength(this); + psyc_packet_length_set(this); return this._length; } ubyte[] render ( ubyte[] buffer ) { - psyc_setPacketLength(this); + psyc_packet_length_set(this); with (RenderRC) switch (psyc_render(this, buffer.ptr, buffer.length)) @@ -189,56 +189,43 @@ struct Packet /** * \internal */ -private size_t psyc_getModifierLength (Modifier *m); +private size_t psyc_modifier_length (Modifier *m); /** * \internal * Check if a list needs length. */ -ListFlag psyc_checkListLength (List *list); +ListFlag psyc_list_length_check (List *list); /** * \internal * Get the total length of a list when rendered. */ -ListFlag psyc_getListLength (List *list); +ListFlag psyc_list_length (List *list); /** * \internal * Check if a packet needs length. */ -PacketFlag psyc_checkPacketLength (Packet *p); +PacketFlag psyc_packet_length_check (Packet *p); /** * Calculate and set the rendered length of packet parts and total packet length. */ -private size_t psyc_setPacketLength (Packet *p); +private size_t psyc_packet_length_set (Packet *p); /** Create new list. */ -List psyc_newList (String *elems, size_t num_elems, ListFlag flag); +List psyc_list_new (String *elems, size_t num_elems, ListFlag flag); /** Create new packet. */ -private Packet psyc_newPacket (Modifier[]* routing, - Modifier[]* entity, - String *method, String *data, - PacketFlag flag); - - - - -/** Create new packet. */ -Packet psyc_newPacket2 (Modifier *routing, size_t routinglen, +Packet psyc_packet_new (Modifier *routing, size_t routinglen, Modifier *entity, size_t entitylen, char *method, size_t methodlen, char *data, size_t datalen, PacketFlag flag); /** Create new packet with raw content. */ -Packet psyc_newRawPacket (Modifier[] *routing, ubyte[] *content, - PacketFlag flag); - -/** Create new packet with raw content. */ -Packet psyc_newRawPacket2 (Modifier *routing, size_t routinglen, - char *content, size_t contentlen, - PacketFlag flag); +Packet psyc_packet_new_raw (Modifier *routing, size_t routinglen, + char *content, size_t contentlen, + PacketFlag flag); diff --git a/d/include/psyc/parse.d b/d/include/psyc/parse.d index ac5be77..7d21714 100644 --- a/d/include/psyc/parse.d +++ b/d/include/psyc/parse.d @@ -316,6 +316,6 @@ ParseRC psyc_parse(ParseState* state, char* oper, String* name, String* value); /** * List value parser. */ -ParseListRC psyc_parseList(ParseListState* state, String *name, String* value, String* elem); +ParseListRC psyc_parse_list(ParseListState* state, String *name, String* value, String* elem); /** @} */ // end of parsing group diff --git a/d/include/psyc/render.d b/d/include/psyc/render.d index c9e248a..d1dd0e4 100644 --- a/d/include/psyc/render.d +++ b/d/include/psyc/render.d @@ -25,7 +25,7 @@ enum RenderRC } ; /** - * Return codes for psyc_renderList. + * Return codes for psyc_render_list. */ enum RenderListRC { @@ -41,20 +41,18 @@ enum RenderListRC * The packet structure should contain the packet parts, either routing, entity, * method & data, or routing & content when rendering raw content. * It should also contain the contentLength & total length of the packet, - * you can use psyc_setPacketLength() for calculating & setting these values. + * you can use psyc_packet_length_set() for calculating & setting these values. * This function renders packet->length bytes to the buffer, * if buflen is less than that an error is returned. * - * @see psyc_newPacket - * @see psyc_newPacket2 - * @see psyc_newRawPacket - * @see psyc_newRawPacket2 - * @see psyc_setPacketLength + * @see psyc_packet_new + * @see psyc_packet_new_raw + * @see psyc_packet_length_set */ RenderRC psyc_render (Packet *packet, ubyte *buffer, size_t buflen); /** * Render a PSYC list into a buffer. */ -RenderListRC psyc_renderList (List *list, ubyte *buffer, size_t buflen); +RenderListRC psyc_render_list (List *list, ubyte *buffer, size_t buflen); diff --git a/doc/renames b/doc/renames new file mode 100644 index 0000000..c2ed1da --- /dev/null +++ b/doc/renames @@ -0,0 +1,66 @@ +psyc_newString psyc_string_new +psyc_routingVars psyc_routing_vars +psyc_routingVarsNum psyc_routing_vars_num +psyc_varTypes psyc_var_types +psyc_varTypesNum psyc_var_types_num +psyc_isRoutingVar - +psyc_isRoutingVar2 psyc_var_is_routing +psyc_isListVar - +psyc_isListVar2 psyc_var_is_list +psyc_getVarType - +psyc_getVarType2 psyc_var_type + +psyc_newModifier - +psyc_newModifier2 psyc_modifier_new +psyc_getModifierLength psyc_modifier_length +psyc_checkModifierLength psyc_modifier_length_check +psyc_getListLength psyc_list_length +psyc_checkListLength psyc_list_length_check +psyc_getNumLength psyc_num_length +psyc_newPacket - +psyc_newPacket2 psyc_packet_new +psyc_newRawPacket - +psyc_newRawPacket2 psyc_packet_new_raw +psyc_checkPacketLength psyc_packet_length_check +psyc_setPacketLength psyc_packet_length_set + +psyc_parseUniform - +psyc_parseUniform2 psyc_uniform_parse + +psyc_initTextState psyc_text_state_init +psyc_initTextState2 psyc_text_state_init_custom +psyc_setTextBuffer - +psyc_setTextBuffer2 psyc_text_buffer_set +psyc_getTextBytesWritten psyc_text_bytes_written + +psyc_parseList psyc_parse_list +psyc_parseNumber - +psyc_parseNumber2 psyc_parse_number +psyc_parseTime - +psyc_parseTime2 psyc_parse_time +psyc_parseDate - +psyc_parseDate2 psyc_parse_date +psyc_initParseState - +psyc_initParseState2 psyc_parse_state_init +psyc_setParseBuffer - +psyc_setParseBuffer2 psyc_parse_buffer_set +psyc_initParseListState psyc_parse_list_state_init +psyc_setParseListBuffer - +psyc_setParseListBuffer2 psyc_parse_list_buffer_set +psyc_getParseContentLength psyc_parse_content_length +psyc_isParseContentLengthFound psyc_parse_content_length_found +psyc_getParseValueLength psyc_parse_value_length +psyc_isParseValueLengthFound psyc_parse_value_length_found +psyc_getParseCursor psyc_parse_cursor +psyc_getParseBufferLength psyc_parse_buffer_length +psyc_getParseRemainingLength psyc_parse_remaining_length +psyc_getParseRemainingBuffer psyc_parse_remaining_buffer + +psyc_isGlyph psyc_is_glyph +psyc_isAlpha psyc_is_alpha +psyc_isAlphaNumeric psyc_is_alpha_numeric +psyc_isKwChar psyc_is_kw_char +psyc_isNameChar psyc_is_name_char +psyc_isHostChar psyc_is_host_char + +psyc_renderList psyc_render_list diff --git a/include/psyc.h b/include/psyc.h index 192c6ed..58e4aa2 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -27,6 +27,8 @@ #define PSYC_S2ARG(str) (str).ptr, (str).length #define PSYC_S2ARG2(str) (str).length, (str).ptr +#define PSYC_NUM_ELEM(a) (sizeof(a) / sizeof(*(a))) + typedef enum { PSYC_FALSE = 0, @@ -99,22 +101,22 @@ typedef struct typedef struct { - psycString name; + psycString key; int value; } psycMatchVar; /** * Shortcut for creating a psycString. * - * @param memory Pointer to the buffer. - * @param length Length of that buffer. + * @param str Pointer to the buffer. + * @param len Length of that buffer. * * @return An instance of the psycString struct. */ static inline -psycString psyc_newString (const char *str, size_t slen) +psycString psyc_string_new (char *str, size_t len) { - psycString s = {slen, str}; + psycString s = {len, str}; return s; } @@ -124,81 +126,39 @@ unsigned int psyc_version () return 1; } -/// Routing variables in alphabetical order. -extern const psycString psyc_routingVars[]; - -// Variable types in alphabetical order. -extern const psycMatchVar psyc_varTypes[]; - -extern const size_t psyc_routingVarsNum; -extern const size_t psyc_varTypesNum; /** - * Is this a routing variable name? + * Checks if long keyword string inherits from short keyword string. */ -psycBool psyc_isRoutingVar(psycString *name); -/** - * Is this a routing variable name? - */ -psycBool psyc_isRoutingVar2(const char *name, size_t len); +int psyc_inherits (char *sho, size_t slen, + char *lon, size_t llen); /** - * Get the type of variable name. + * Checks if short keyword string matches long keyword string. */ -psycType psyc_getVarType(psycString *name); -/** - * Get the type of variable name. - */ -psycType psyc_getVarType2(const char *name, size_t len); +int psyc_matches (char *sho, size_t slen, + char *lon, size_t llen); /** - * Search for a variable name in an array. + * Check if keyword is in array. * * @param array The array to search, should be ordered alphabetically. * @param size Size of array. - * @param name Name of variable to look for. - * @param namelen Length of name. - * @param startswith If true, look for any variable starting with name, + * @param kw Keyword to look for. + * @param kwlen Length of keyword. + * @param inherit If true, also look for anything inheriting from kw, otherwise only exact matches are returned. * @param matching A temporary array used for keeping track of results. * Should be the same size as the array we're searching. * * @return The value of the matched variable in the array. */ -int psyc_findVar(const psycMatchVar *array, size_t size, - const char *name, size_t namelen, - uint8_t startswith, int8_t *matching); -/** - * Is this a list variable name? - */ -static inline -psycBool psyc_isListVar2(const char *name, size_t len) -{ - return len < 5 || memcmp(name, "_list", 5) != 0 || - (len > 5 && name[5] != '_') ? PSYC_FALSE : PSYC_TRUE; -} +int psyc_in_array (const psycMatchVar *array, size_t size, + const char *kw, size_t kwlen, + psycBool inherit, int8_t *matching); -/** - * Is this a list variable name? - */ -static inline -psycBool psyc_isListVar(psycString *name) -{ - return psyc_isListVar2(name->ptr, name->length); -} - -/** - * Checks if long keyword string inherits from short keyword string. - */ -int psyc_inherits(char *sho, size_t slen, - char *lon, size_t llen); - -/** - * Checks if short keyword string matches long keyword string. - */ -int psyc_matches(char *sho, size_t slen, - char *lon, size_t llen); +#include "psyc/variable.h" #define PSYC_H #endif diff --git a/include/psyc/packet.h b/include/psyc/packet.h index 5407ba2..0080cc1 100644 --- a/include/psyc/packet.h +++ b/include/psyc/packet.h @@ -17,6 +17,7 @@ #include #include +#include /** Modifier flags. */ typedef enum @@ -78,7 +79,7 @@ typedef struct psycListFlag flag; } psycList; -/** intermediate struct for a PSYC packet */ +/** Intermediate struct for a PSYC packet */ typedef struct { psycHeader routing; ///< Routing header. @@ -92,12 +93,21 @@ typedef struct psycPacketFlag flag; ///< Packet flag. } psycPacket; +/** + * Return the number of digits a number has in its base 10 representation. + */ +static inline +size_t psyc_num_length (size_t n) +{ + return n < 10 ? 1 : log10(n) + 1; +} + /** * \internal * Check if a modifier needs length. */ static inline -psycModifierFlag psyc_checkModifierLength (psycModifier *m) +psycModifierFlag psyc_modifier_length_check (psycModifier *m) { psycModifierFlag flag; @@ -111,85 +121,64 @@ psycModifierFlag psyc_checkModifierLength (psycModifier *m) return flag; } -/** Create new modifier. */ -static inline -psycModifier psyc_newModifier (char oper, psycString *name, psycString *value, - psycModifierFlag flag) -{ - psycModifier m = {oper, *name, *value, flag}; - - if (flag == PSYC_MODIFIER_CHECK_LENGTH) // find out if it needs a length - m.flag = psyc_checkModifierLength(&m); - - return m; -} - /** Create new modifier */ static inline -psycModifier psyc_newModifier2 (char oper, - const char *name, size_t namelen, - const char *value, size_t valuelen, - psycModifierFlag flag) -{ - psycString n = {namelen, name}; - psycString v = {valuelen, value}; +psycModifier psyc_modifier_new (char oper, + char *name, size_t namelen, + char *value, size_t valuelen, + psycModifierFlag flag){ - return psyc_newModifier(oper, &n, &v, flag); + psycModifier m = {oper, {namelen, name}, {valuelen, value}, flag}; + + if (flag == PSYC_MODIFIER_CHECK_LENGTH) // find out if it needs a length + m.flag = psyc_modifier_length_check(&m); + + return m; } /** * \internal * Get the total length of a modifier when rendered. */ -size_t psyc_getModifierLength (psycModifier *m); +size_t psyc_modifier_length (psycModifier *m); /** * \internal * Check if a list needs length. */ -psycListFlag psyc_checkListLength (psycList *list); +psycListFlag psyc_list_length_check (psycList *list); /** * \internal * Get the total length of a list when rendered. */ -psycListFlag psyc_getListLength (psycList *list); +psycListFlag psyc_list_length (psycList *list); /** * \internal * Check if a packet needs length. */ -psycPacketFlag psyc_checkPacketLength (psycPacket *p); +psycPacketFlag psyc_packet_length_check (psycPacket *p); /** * Calculate and set the rendered length of packet parts and total packet length. */ -size_t psyc_setPacketLength (psycPacket *p); +size_t psyc_packet_length_set (psycPacket *p); /** Create new list. */ -psycList psyc_newList (psycString *elems, size_t num_elems, psycListFlag flag); +psycList psyc_list_new (psycString *elems, size_t num_elems, psycListFlag flag); /** Create new packet. */ -psycPacket psyc_newPacket (psycHeader *routing, - psycHeader *entity, - psycString *method, psycString *data, - psycPacketFlag flag); - -/** Create new packet. */ -psycPacket psyc_newPacket2 (psycModifier *routing, size_t routinglen, +psycPacket psyc_packet_new (psycModifier *routing, size_t routinglen, psycModifier *entity, size_t entitylen, - const char *method, size_t methodlen, - const char *data, size_t datalen, + char *method, size_t methodlen, + char *data, size_t datalen, psycPacketFlag flag); /** Create new packet with raw content. */ -psycPacket psyc_newRawPacket (psycHeader *routing, psycString *content, - psycPacketFlag flag); - -/** Create new packet with raw content. */ -psycPacket psyc_newRawPacket2 (psycModifier *routing, size_t routinglen, - const char *content, size_t contentlen, - psycPacketFlag flag); +psycPacket psyc_packet_new_raw (psycModifier *routing, size_t routinglen, + char *content, size_t contentlen, + psycPacketFlag flag); /** @} */ // end of packet group diff --git a/include/psyc/parse.h b/include/psyc/parse.h index d0b22d5..cf86340 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -11,8 +11,8 @@ * @defgroup parse Parsing Functions * * This module contains packet and list parsing functions. - * The parser adheres to the definition of a packet found at - * + * The parser adheres to the definition of a packet found at + * * http://about.psyc.eu/Spec:Packet * * and the according terms are used throughout this documentation and in the @@ -25,11 +25,10 @@ * * @code * psycParseState state; - * - * psyc_initParseState(&state); + * psyc_parse_state_init(&state, flags); * @endcode * - * Note that there is also psyc_initParseState2 if you want to fine-tune what + * With the flags parameter you can fine-tune what * part of the packet should be parsed. @see psycParseFlag * * Next, you have to tell the parser what it should parse. Assuming the variable @@ -40,7 +39,7 @@ * char* raw_data; // points to our (possibly incomplete) packet * size_t raw_len; // how many bytes of data * - * psyc_setParseBuffer(&state, raw_data, raw_len); // state is our initialized state from before + * psyc_parse_buffer_set(&state, raw_data, raw_len); // state is our initialized state from before * @endcode * * Now the the variables that will save the output of the parser need to be @@ -77,7 +76,7 @@ * case PSYC_PARSE_ENTITY: // it is a entity variable * // Name, value and operator of the variable can now be found in the * // respective variables: - * printf("Variable: %.*s Value: %.*s Operator: %c\n", + * printf("Variable: %.*s Value: %.*s Operator: %c\n", * name.length, name.ptr, * value.length, value.ptr, * oper); @@ -86,7 +85,7 @@ * // before passing it to the parser or you copy each variable now. * break; * case PSYC_PARSE_BODY: // it is the method and the body of the packet. - * printf("Method Name: %.*s Body: %.*s\n", + * printf("Method Name: %.*s Body: %.*s\n", * name.length, name.ptr, // name of the method * value.length, value.ptr); // value of the body * break; @@ -94,11 +93,11 @@ * // You can simply continue parsing till you get the * // PSYC_PARSE_INSUFFICIENT code which means the line is incomplete. * continue; - * default: // + * default: // * perror("Error %i happened :(\n", res); * return res; * } - * } + * } * while (ret > 0) * @endcode * @@ -193,7 +192,7 @@ typedef enum { /** * The return value definitions for the list parsing function. - * @see psyc_parseList() + * @see psyc_parse_list() */ typedef enum { PSYC_PARSE_LIST_ERROR_DELIM = -4, @@ -244,24 +243,11 @@ typedef struct { * Initializes the state struct. * * @param state Pointer to the state struct that should be initialized. - * @see psyc_initParseState2 - */ -static inline -void psyc_initParseState (psycParseState *state) -{ - memset(state, 0, sizeof(psycParseState)); -} - -/** - * Initializes the state struct with flags. - * - * @param state Pointer to the state struct that should be initialized. * @param flags Flags to be set for the parser, see psycParseFlag. - * @see psyc_initParseState * @see psycParseFlag */ static inline -void psyc_initParseState2 (psycParseState *state, uint8_t flags) +void psyc_parse_state_init (psycParseState *state, uint8_t flags) { memset(state, 0, sizeof(psycParseState)); state->flags = flags; @@ -277,46 +263,29 @@ void psyc_initParseState2 (psycParseState *state, uint8_t flags) * at the memory pointed to by buffer. * * @param state Pointer to the initialized state of the parser - * @param buffer the buffer that should be parsed now + * @param buffer pointer to the data that should be parsed + * @param length length of the data in bytes * @see psycString */ static inline -void psyc_setParseBuffer (psycParseState *state, psycString buffer) +void psyc_parse_buffer_set (psycParseState *state, char *buffer, size_t length) { - state->buffer = buffer; + state->buffer = (psycString) {length, buffer}; state->cursor = 0; if (state->flags & PSYC_PARSE_START_AT_CONTENT) { - state->contentLength = buffer.length; + state->contentLength = length; state->contentLengthFound = PSYC_TRUE; } } -/** - * Sets a new buffer in the parser state struct with data to be parsed. - * - * This function does NOT copy the buffer. It will parse whatever is - * at the memory pointed to by buffer. - * - * @param state Pointer to the initialized state of the parser - * @param buffer pointer to the data that should be parsed - * @param length length of the data in bytes - * @see psycString - */ -static inline -void psyc_setParseBuffer2 (psycParseState *state, const char *buffer, size_t length) -{ - psycString buf = {length, buffer}; - psyc_setParseBuffer(state, buf); -} - /** * Initializes the list state struct. * * @param state Pointer to the list state struct that should be initialized. */ static inline -void psyc_initParseListState (psycParseListState *state) +void psyc_parse_list_state_init (psycParseListState *state) { memset(state, 0, sizeof(psycParseListState)); } @@ -325,63 +294,56 @@ void psyc_initParseListState (psycParseListState *state) * Sets a new buffer in the list parser state struct with data to be parsed. */ static inline -void psyc_setParseListBuffer (psycParseListState *state, psycString buffer) +void psyc_parse_list_buffer_set (psycParseListState *state, char *buffer, size_t length) { - state->buffer = buffer; + state->buffer = (psycString) {length, buffer}; state->cursor = 0; } static inline -void psyc_setParseListBuffer2 (psycParseListState *state, const char *buffer, size_t length) -{ - psycString buf = {length, buffer}; - psyc_setParseListBuffer(state, buf); -} - -static inline -size_t psyc_getParseContentLength (psycParseState *state) +size_t psyc_parse_content_length (psycParseState *state) { return state->contentLength; } static inline -psycBool psyc_isParseContentLengthFound (psycParseState *state) +psycBool psyc_parse_content_length_found (psycParseState *state) { return state->contentLengthFound; } static inline -size_t psyc_getParseValueLength (psycParseState *state) +size_t psyc_parse_value_length (psycParseState *state) { return state->valueLength; } static inline -psycBool psyc_isParseValueLengthFound (psycParseState *state) +psycBool psyc_parse_value_length_found (psycParseState *state) { return state->valueLengthFound; } static inline -size_t psyc_getParseCursor (psycParseState *state) +size_t psyc_parse_cursor (psycParseState *state) { return state->cursor; } static inline -size_t psyc_getParseBufferLength (psycParseState *state) +size_t psyc_parse_buffer_length (psycParseState *state) { return state->buffer.length; } static inline -size_t psyc_getParseRemainingLength (psycParseState *state) +size_t psyc_parse_remaining_length (psycParseState *state) { return state->buffer.length - state->cursor; } static inline -const char * psyc_getParseRemainingBuffer (psycParseState *state) +const char * psyc_parse_remaining_buffer (psycParseState *state) { return state->buffer.ptr + state->cursor; } @@ -422,10 +384,10 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, #ifdef __INLINE_PSYC_PARSE static inline #endif -psycParseListRC psyc_parseList (psycParseListState *state, psycString *elem); +psycParseListRC psyc_parse_list (psycParseListState *state, psycString *elem); static inline -psycBool psyc_parseNumber2 (const char *value, size_t len, ssize_t *n) +psycBool psyc_parse_number (const char *value, size_t len, ssize_t *n) { size_t c = 0; uint8_t neg = 0; @@ -450,45 +412,27 @@ psycBool psyc_parseNumber2 (const char *value, size_t len, ssize_t *n) } static inline -psycBool psyc_parseNumber (psycString *value, ssize_t *n) +psycBool psyc_parse_time (const char *value, size_t len, time_t *t) { - return psyc_parseNumber2(value->ptr, value->length, n); + return psyc_parse_number(value, len, t); } static inline -psycBool psyc_parseTime2 (const char *value, size_t len, time_t *t) +psycBool psyc_parse_date (const char *value, size_t len, time_t *t) { - return psyc_parseNumber2(value, len, t); -} - -static inline -psycBool psyc_parseTime (psycString *value, time_t *t) -{ - return psyc_parseNumber2(value->ptr, value->length, t); -} - -static inline -psycBool psyc_parseDate2 (const char *value, size_t len, time_t *t) -{ - if (psyc_parseNumber2(value, len, t)) { + if (psyc_parse_number(value, len, t)) { *t += PSYC_EPOCH; return PSYC_TRUE; } return PSYC_FALSE; } -static inline -psycBool psyc_parseDate (psycString *value, time_t *t) -{ - return psyc_parseDate2(value->ptr, value->length, t); -} - /** * Determines if the argument is a glyph. * Glyphs are: : = + - ? ! */ static inline -char psyc_isGlyph (uint8_t g) +char psyc_is_glyph (uint8_t g) { switch(g) { case ':': @@ -507,7 +451,7 @@ char psyc_isGlyph (uint8_t g) * Determines if the argument is numeric. */ static inline -char psyc_isNumeric (uint8_t c) +char psyc_is_numeric (uint8_t c) { return c >= '0' && c <= '9'; } @@ -516,7 +460,7 @@ char psyc_isNumeric (uint8_t c) * Determines if the argument is alphabetic. */ static inline -char psyc_isAlpha (uint8_t c) +char psyc_is_alpha (uint8_t c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); } @@ -525,9 +469,9 @@ char psyc_isAlpha (uint8_t c) * Determines if the argument is alphanumeric. */ static inline -char psyc_isAlphaNumeric (uint8_t c) +char psyc_is_alpha_numeric (uint8_t c) { - return psyc_isAlpha(c) || psyc_isNumeric(c); + return psyc_is_alpha(c) || psyc_is_numeric(c); } /** @@ -535,9 +479,9 @@ char psyc_isAlphaNumeric (uint8_t c) * Keyword characters are: alphanumeric and _ */ static inline -char psyc_isKwChar (uint8_t c) +char psyc_is_kw_char (uint8_t c) { - return psyc_isAlphaNumeric(c) || c == '_'; + return psyc_is_alpha_numeric(c) || c == '_'; } /** @@ -545,9 +489,9 @@ char psyc_isKwChar (uint8_t c) * Name characters are: see opaque_part in RFC 2396 */ static inline -char psyc_isNameChar (uint8_t c) +char psyc_is_name_char (uint8_t c) { - return psyc_isAlpha(c) || (c >= '$' && c <= ';') || + return psyc_is_alpha(c) || (c >= '$' && c <= ';') || c == '_' || c == '!' || c == '?' || c == '=' || c == '@' || c == '~'; } @@ -556,9 +500,9 @@ char psyc_isNameChar (uint8_t c) * Hostname characters are: alphanumeric and - */ static inline -char psyc_isHostChar (uint8_t c) +char psyc_is_host_char (uint8_t c) { - return psyc_isAlphaNumeric(c) || c == '.' || c == '-'; + return psyc_is_alpha_numeric(c) || c == '.' || c == '-'; } /** @} */ // end of parse group diff --git a/include/psyc/render.h b/include/psyc/render.h index 2f13793..e4cd8f2 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -32,7 +32,7 @@ typedef enum } psycRenderRC; /** - * Return codes for psyc_renderList. + * Return codes for psyc_render_list. */ typedef enum { @@ -48,15 +48,13 @@ typedef enum * The packet structure should contain the packet parts, either routing, entity, * method & data, or routing & content when rendering raw content. * It should also contain the contentLength & total length of the packet, - * you can use psyc_setPacketLength() for calculating & setting these values. + * you can use psyc_packet_length_set() for calculating & setting these values. * This function renders packet->length bytes to the buffer, * if buflen is less than that an error is returned. * - * @see psyc_newPacket - * @see psyc_newPacket2 - * @see psyc_newRawPacket - * @see psyc_newRawPacket2 - * @see psyc_setPacketLength + * @see psyc_packet_new + * @see psyc_packet_new_raw + * @see psyc_packet_length_set */ #ifdef __INLINE_PSYC_RENDER static inline @@ -69,7 +67,7 @@ psycRenderRC psyc_render (psycPacket *packet, char *buffer, size_t buflen); #ifdef __INLINE_PSYC_RENDER static inline #endif -psycRenderListRC psyc_renderList (psycList *list, char *buffer, size_t buflen); +psycRenderListRC psyc_render_list (psycList *list, char *buffer, size_t buflen); /** @} */ // end of render group diff --git a/include/psyc/text.h b/include/psyc/text.h index a09d3fb..55f35e5 100644 --- a/include/psyc/text.h +++ b/include/psyc/text.h @@ -76,9 +76,9 @@ typedef psycTextValueRC (*psycTextCB)(const char *name, size_t len, psycString * * @param buflen Length of output buffer. */ static inline -void psyc_initTextState (psycTextState *state, - const char *tmpl, size_t tmplen, - char *buffer, size_t buflen) +void psyc_text_state_init (psycTextState *state, + char *tmpl, size_t tmplen, + char *buffer, size_t buflen) { state->cursor = 0; state->written = 0; @@ -102,11 +102,11 @@ void psyc_initTextState (psycTextState *state, * @param closelen Length of closing brace. */ static inline -void psyc_initTextState2 (psycTextState *state, - const char *tmpl, size_t tmplen, - char *buffer, size_t buflen, - const char *open, size_t openlen, - const char *close, size_t closelen) +void psyc_text_state_init_custom (psycTextState *state, + char *tmpl, size_t tmplen, + char *buffer, size_t buflen, + char *open, size_t openlen, + char *close, size_t closelen) { state->cursor = 0; state->written = 0; @@ -120,25 +120,15 @@ void psyc_initTextState2 (psycTextState *state, * Sets a new output buffer in the PSYC text state struct. */ static inline -void psyc_setTextBuffer (psycTextState *state, psycString buffer) +void psyc_text_buffer_set (psycTextState *state, + char *buffer, size_t length) { - state->buffer = buffer; + state->buffer = (psycString){length, buffer}; state->written = 0; } -/** - * Sets a new buffer in the PSYC text state struct. - */ static inline -void psyc_setTextBuffer2 (psycTextState *state, - char *buffer, size_t length) -{ - psycString buf = {length, buffer}; - psyc_setTextBuffer(state, buf); -} - -static inline -size_t psyc_getTextBytesWritten (psycTextState *state) +size_t psyc_text_bytes_written (psycTextState *state) { return state->written; } @@ -151,10 +141,10 @@ size_t psyc_getTextBytesWritten (psycTextState *state) * string between these braces. Should the callback return * PSYC_TEXT_VALUE_NOT_FOUND, the original template text is copied as is. * - * Before calling this function psyc_initTextState should be called to initialize + * Before calling this function psyc_text_state_init should be called to initialize * the state struct. By default PSYC's "[" and "]" are used but you can provide * any other brace strings such as "${" and "}" or "" if you use - * the psyc_initTextState2 variant. + * the psyc_text_state_init_custom variant. * * @see http://about.psyc.eu/psyctext **/ diff --git a/include/psyc/uniform.h b/include/psyc/uniform.h index 24324cf..7bc86ba 100644 --- a/include/psyc/uniform.h +++ b/include/psyc/uniform.h @@ -73,9 +73,7 @@ typedef enum { PSYC_ENTITY_SERVICE = '$', } psycEntityType; -int psyc_parseUniform2(psycUniform *uni, const char *str, size_t length); - -int psyc_parseUniform(psycUniform *uni, psycString *str); +int psyc_uniform_parse (psycUniform *uni, char *str, size_t length); #define PSYC_UNIFORM_H #endif diff --git a/include/psyc/variable.h b/include/psyc/variable.h new file mode 100644 index 0000000..c4671f6 --- /dev/null +++ b/include/psyc/variable.h @@ -0,0 +1,37 @@ +#ifndef PSYC_VARIABLE_H + +/** + * @file psyc/variable.h + */ + +/// Routing variables in alphabetical order. +extern const psycString psyc_routing_vars[]; + +// Variable types in alphabetical order. +extern const psycMatchVar psyc_var_types[]; + +extern const size_t psyc_routing_vars_num; +extern const size_t psyc_var_types_num; + +/** + * Is this a routing variable name? + */ +psycBool psyc_var_is_routing (const char *name, size_t len); + +/** + * Get the type of variable name. + */ +psycType psyc_var_type (const char *name, size_t len); + +/** + * Is this a list variable name? + */ +static inline +psycBool psyc_var_is_list (const char *name, size_t len) +{ + return len < 5 || memcmp(name, "_list", 5) != 0 || + (len > 5 && name[5] != '_') ? PSYC_FALSE : PSYC_TRUE; +} + +#define PSYC_VARIABLE_H +#endif diff --git a/pike/psyc.cmod b/pike/psyc.cmod index 11ba358..2f31b7d 100644 --- a/pike/psyc.cmod +++ b/pike/psyc.cmod @@ -74,14 +74,14 @@ PIKEFUN string psyc_text(string template, mapping vars) { // FIXME: char buffer[512]; - psyc_initTextState(&state, (char *) STR0(template), template->len, buffer, 512); + psyc_text_state_init(&state, (char *) STR0(template), template->len, buffer, 512); do { ret = psyc_text(&state, lookup_value_mapping, vars); - len += psyc_getTextBytesWritten(&state); + len += psyc_text_bytes_written(&state); switch (ret) { case PSYC_TEXT_INCOMPLETE: // need to realloc buffer - //psyc_setTextBuffer2(&state, buffer + len, BUFSIZE - len); + //psyc_text_buffer_set(&state, buffer + len, BUFSIZE - len); break; case PSYC_TEXT_COMPLETE: // we're done RETURN make_shared_binary_string(buffer, len); @@ -99,7 +99,7 @@ PIKEFUN string psyc_text(string template, mapping vars) { *! 0 otherwise */ PIKEFUN int is_routingvar(string name) { - RETURN psyc_isRoutingVar2((char *) STR0(name), name->len); + RETURN psyc_var_is_routing((char *) STR0(name), name->len); } /*! @decl string render(mapping rvars, mapping evars, string method, string|void body) @@ -130,11 +130,11 @@ PIKEFUN string render(mapping rvars, mapping evars, string method, string|void b if (k->ind.type == PIKE_T_STRING) { switch(k->val.type) { case PIKE_T_STRING: - rheaders.modifiers[rheaders.lines++] = psyc_newModifier2(oper, + rheaders.modifiers[rheaders.lines++] = psyc_modifier_new(oper, (char *)STR0(k->ind.u.string), k->ind.u.string->len, (char *)STR0(k->val.u.string), - k->val.u.string->len, + k->val.u.string->len, PSYC_MODIFIER_ROUTING); break; default: @@ -197,10 +197,10 @@ PIKEFUN string render(mapping rvars, mapping evars, string method, string|void b Pike_error("psyc_render: unsupported data type in list\n"); } } - list = psyc_newList(elems, k->val.u.array->size, PSYC_LIST_CHECK_LENGTH); + list = psyc_list_new(elems, k->val.u.array->size, PSYC_LIST_CHECK_LENGTH); struct pike_string *listbuf = begin_shared_string(list.length); - psyc_renderList(&list, (char *) STR0(listbuf), listbuf->len); + psyc_render_list(&list, (char *) STR0(listbuf), listbuf->len); end_shared_string(listbuf); val = (char *) STR0(listbuf); vallen = listbuf->len; @@ -211,7 +211,7 @@ PIKEFUN string render(mapping rvars, mapping evars, string method, string|void b Pike_error("psyc_render: unsupported value in evars\n"); break; } - eheaders.modifiers[eheaders.lines++] = psyc_newModifier2(oper, + eheaders.modifiers[eheaders.lines++] = psyc_modifier_new(oper, key, keylen, val, vallen, PSYC_MODIFIER_CHECK_LENGTH); @@ -221,19 +221,19 @@ PIKEFUN string render(mapping rvars, mapping evars, string method, string|void b } if (body != NULL) { - packet = psyc_newPacket2(rheaders.modifiers, + packet = psyc_packet_new(rheaders.modifiers, rheaders.lines, eheaders.modifiers, eheaders.lines, - (const char *)STR0(method), method->len, + (const char *)STR0(method), method->len, (const char *)STR0(body), body->len, PSYC_PACKET_CHECK_LENGTH); } else { // body arg was not given - packet = psyc_newPacket2(rheaders.modifiers, + packet = psyc_packet_new(rheaders.modifiers, rheaders.lines, eheaders.modifiers, eheaders.lines, - (const char *)STR0(method), method->len, + (const char *)STR0(method), method->len, NULL, 0, PSYC_PACKET_CHECK_LENGTH); } @@ -260,7 +260,7 @@ PIKECLASS Parser { CVAR struct string_builder incomplete; INIT { - psyc_initParseState(&THIS->parser); + psyc_parse_state_init(&THIS->parser, PSYC_PARSE_ALL); THIS->buffer = NULL; THIS->handle_packet = find_identifier("handle_packet", Pike_fp->current_object->prog); THIS->handle_error = find_identifier("handle_error", Pike_fp->current_object->prog); @@ -296,7 +296,7 @@ PIKECLASS Parser { data = tmp; THIS->buffer = NULL; } - psyc_setParseBuffer2(&THIS->parser, + psyc_parse_buffer_set(&THIS->parser, (char *) STR0(data), data->len); do { ret = psyc_parse(&THIS->parser, &oper, &name, &value); @@ -308,7 +308,7 @@ PIKECLASS Parser { make_shared_binary_string(value.ptr, value.length)); break; case PSYC_PARSE_ENTITY_START: // entity var with length - init_string_builder_alloc(&THIS->incomplete, psyc_getParseValueLength(&THIS->parser), 0); + init_string_builder_alloc(&THIS->incomplete, psyc_parse_value_length(&THIS->parser), 0); // fall thru case PSYC_PARSE_ENTITY_CONT: string_builder_append(&THIS->incomplete, MKPCHARP(value.ptr, 0), value.length); @@ -327,12 +327,12 @@ PIKECLASS Parser { //printf("E %.*s -> %.*s\n", (int)name.length, name.ptr, (int)value.length, value.ptr); do { err = 0; - int type = psyc_getVarType(&name); + int type = psyc_var_type(PSYC_S2ARG(&name)); struct svalue sv; time_t timmy; switch(type) { case PSYC_TYPE_DATE: - if (psyc_parseDate(&value, &timmy)) { + if (psyc_parse_date(&value, &timmy)) { sv.type = PIKE_T_INT; sv.u.integer = timmy; mapping_string_insert(THIS->evars, make_shared_binary_string(name.ptr, name.length), @@ -342,7 +342,7 @@ PIKECLASS Parser { } break; case PSYC_TYPE_TIME: - if (psyc_parseTime(&value, &timmy)) { + if (psyc_parse_time(&value, &timmy)) { sv.type = PIKE_T_INT; sv.u.integer = timmy; mapping_string_insert(THIS->evars, make_shared_binary_string(name.ptr, name.length), @@ -382,10 +382,10 @@ PIKECLASS Parser { psycParseListState listState; psycString elem = (psycString) {0, 0}; - psyc_initParseListState(&listState); - psyc_setParseListBuffer(&listState, value); + psyc_parse_list_state_init(&listState); + psyc_parse_list_buffer_set(&listState, PSYC_S2ARG(value)); do { - retl = psyc_parseList(&listState, &elem); + retl = psyc_parse_list(&listState, &elem); switch(retl) { case PSYC_PARSE_LIST_END: // last element retl = 0; @@ -421,7 +421,7 @@ PIKECLASS Parser { } break; case PSYC_PARSE_BODY_START: // if length was given this is used for body - init_string_builder_alloc(&THIS->incomplete, psyc_getParseValueLength(&THIS->parser), 0); + init_string_builder_alloc(&THIS->incomplete, psyc_parse_value_length(&THIS->parser), 0); case PSYC_PARSE_BODY_CONT: string_builder_append(&THIS->incomplete, MKPCHARP(value.ptr, 0), value.length); break; @@ -460,9 +460,9 @@ PIKECLASS Parser { THIS->body = NULL; break; case PSYC_PARSE_INSUFFICIENT: // not enough data - if (psyc_getParseRemainingBuffer(&THIS->parser) > 0) { - THIS->buffer = make_shared_binary_string(psyc_getParseRemainingBuffer(&THIS->parser), - psyc_getParseRemainingLength(&THIS->parser)); + if (psyc_parse_remaining_buffer(&THIS->parser) > 0) { + THIS->buffer = make_shared_binary_string(psyc_parse_remaining_buffer(&THIS->parser), + psyc_parse_remaining_length(&THIS->parser)); } return; default: // fatal error diff --git a/src/lib.h b/src/lib.h index 637b082..f24beae 100644 --- a/src/lib.h +++ b/src/lib.h @@ -11,8 +11,6 @@ #define unless(COND) if (!(COND)) #define until(COND) while (!(COND)) -#define PSYC_NUM_ELEM(a) (sizeof(a) / sizeof(*(a))) - #if !defined(__USE_GNU) && !(defined(__FBSDID) && defined(__BSD_VISIBLE)) void * memmem(const void *l, size_t l_len, const void *s, size_t s_len); #endif diff --git a/src/match.c b/src/match.c index 7fc3c25..dd68d77 100644 --- a/src/match.c +++ b/src/match.c @@ -1,7 +1,7 @@ #include "lib.h" -int psyc_inherits(char* sho, size_t slen, - char* lon, size_t llen) { +int psyc_inherits (char* sho, size_t slen, + char* lon, size_t llen) { // this allows to pass zero-terminated strings instead of providing // the length.. but we would be faster here if we expected the callee @@ -42,8 +42,8 @@ int psyc_inherits(char* sho, size_t slen, return 1; } -int psyc_matches(char* sho, size_t slen, - char* lon, size_t llen) { +int psyc_matches (char* sho, size_t slen, + char* lon, size_t llen) { char *s, *l, *se, *le; //if (!slen) slen = strlen(sho); @@ -100,6 +100,62 @@ failed: return 1; } +/** + * Check if keyword is in array. + * + * @param array The array to search, should be ordered alphabetically. + * @param size Size of array. + * @param kw Keyword to look for. + * @param kwlen Length of keyword. + * @param inherit If true, look for any keyword inheriting from name, + otherwise only exact matches are returned. + * @param matching A temporary array used for keeping track of results. + * Should be the same size as the array we're searching. + * + * @return The value of the matched variable in the array. + */ +int psyc_in_array (const psycMatchVar *array, size_t size, + const char *kw, size_t kwlen, + psycBool inherit, int8_t *matching) +{ + size_t cursor = 1; + uint8_t i, m = 0; + //memset(&matching, -1, sizeof matching); + + if (kwlen < 2 || kw[0] != '_') + return 0; + + // first find the keywords with matching length + for (i=0; i array[i].key.length && kw[array[i].key.length] == '_')) + matching[m++] = i; + + matching[m] = -1; // mark the end of matching indexes + + while (cursor < kwlen && matching[0] >= 0) { + for (i = m = 0; i < size; i++) { + if (matching[i] < 0) + break; // reached the end of possible matches + if (cursor < array[matching[i]].key.length && + array[matching[i]].key.ptr[cursor] == kw[cursor]) + matching[m++] = matching[i]; // found a match, update matching indexes + else if (cursor == array[matching[i]].key.length && kw[cursor] == '_') + return array[matching[0]].value; // _ after the end of a matching prefix + else if (array[matching[i]].key.ptr[cursor] > kw[cursor]) + break; // passed the possible matches in alphabetical order in the array + } + + if (m < size) + matching[m] = -1; // mark the end of matching indexes + + cursor++; + } + + // return first match if found + return matching[0] >= 0 ? array[matching[0]].value : 0; +} + #ifdef CMDTOOL int main(int argc, char **argv) { if (argc != 3) { diff --git a/src/packet.c b/src/packet.c index fe7c13e..a06bc72 100644 --- a/src/packet.c +++ b/src/packet.c @@ -2,16 +2,8 @@ #include #include -#include - -static inline -size_t psyc_getNumLength(size_t n) -{ - return n < 10 ? 1 : log10(n) + 1; -} - inline -psycListFlag psyc_checkListLength (psycList *list) +psycListFlag psyc_list_length_check (psycList *list) { psycListFlag flag = PSYC_LIST_NO_LENGTH; size_t i, length = 0; @@ -33,7 +25,7 @@ psycListFlag psyc_checkListLength (psycList *list) } inline -psycListFlag psyc_getListLength (psycList *list) +psycListFlag psyc_list_length (psycList *list) { size_t i, length = 0; @@ -43,7 +35,7 @@ psycListFlag psyc_getListLength (psycList *list) { if (i > 0) length++; // | - length += psyc_getNumLength(list->elems[i].length) + 1 + list->elems[i].length; // length SP elem + length += psyc_num_length(list->elems[i].length) + 1 + list->elems[i].length; // length SP elem } } else @@ -56,33 +48,33 @@ psycListFlag psyc_getListLength (psycList *list) } inline -psycList psyc_newList(psycString *elems, size_t num_elems, psycListFlag flag) +psycList psyc_list_new (psycString *elems, size_t num_elems, psycListFlag flag) { psycList list = {num_elems, elems, 0, flag}; if (flag == PSYC_LIST_CHECK_LENGTH) // check if list elements need length - list.flag = psyc_checkListLength(&list); + list.flag = psyc_list_length_check(&list); - list.length = psyc_getListLength(&list); + list.length = psyc_list_length(&list); return list; } inline -size_t psyc_getModifierLength (psycModifier *m) +size_t psyc_modifier_length (psycModifier *m) { size_t length = 1 + // oper m->name.length + 1 + // name\t m->value.length + 1; // value\n if (m->flag == PSYC_MODIFIER_NEED_LENGTH) // add length of length if needed - length += psyc_getNumLength(m->value.length) + 1; // SP length + length += psyc_num_length(m->value.length) + 1; // SP length return length; } inline -psycPacketFlag psyc_checkPacketLength(psycPacket *p) +psycPacketFlag psyc_packet_length_check (psycPacket *p) { if (p->data.length == 1 && p->data.ptr[0] == C_GLYPH_PACKET_DELIMITER) return PSYC_PACKET_NEED_LENGTH; @@ -104,7 +96,7 @@ psycPacketFlag psyc_checkPacketLength(psycPacket *p) } inline -size_t psyc_setPacketLength(psycPacket *p) +size_t psyc_packet_length_set (psycPacket *p) { size_t i; p->routingLength = 0; @@ -112,7 +104,7 @@ size_t psyc_setPacketLength(psycPacket *p) // add routing header length for (i = 0; i < p->routing.lines; i++) - p->routingLength += psyc_getModifierLength(&(p->routing.modifiers[i])); + p->routingLength += psyc_modifier_length(&(p->routing.modifiers[i])); if (p->content.length) p->contentLength = p->content.length; @@ -120,7 +112,7 @@ size_t psyc_setPacketLength(psycPacket *p) { // add entity header length for (i = 0; i < p->entity.lines; i++) - p->contentLength += psyc_getModifierLength(&(p->entity.modifiers[i])); + p->contentLength += psyc_modifier_length(&(p->entity.modifiers[i])); // add length of method, data & delimiter if (p->method.length) @@ -136,60 +128,39 @@ size_t psyc_setPacketLength(psycPacket *p) p->length++; // add \n at the start of the content part if (p->flag == PSYC_PACKET_NEED_LENGTH) // add length of length if needed - p->length += psyc_getNumLength(p->contentLength); + p->length += psyc_num_length(p->contentLength); return p->length; } inline -psycPacket psyc_newPacket (psycHeader *routing, psycHeader *entity, - psycString *method, psycString *data, - psycPacketFlag flag) -{ - psycPacket p = {*routing, *entity, *method, *data, {0,0}, 0, 0, flag}; - - if (flag == PSYC_PACKET_CHECK_LENGTH) // find out if it needs a length - p.flag = psyc_checkPacketLength(&p); - - psyc_setPacketLength(&p); - return p; -} - -inline -psycPacket psyc_newPacket2 (psycModifier *routing, size_t routinglen, +psycPacket psyc_packet_new (psycModifier *routing, size_t routinglen, psycModifier *entity, size_t entitylen, - const char *method, size_t methodlen, - const char *data, size_t datalen, + char *method, size_t methodlen, + char *data, size_t datalen, psycPacketFlag flag) { - psycHeader r = {routinglen, routing}; - psycHeader e = {entitylen, entity}; - psycString m = {methodlen, method}; - psycString d = {datalen, data}; - - return psyc_newPacket(&r, &e, &m, &d, flag); -} - -inline -psycPacket psyc_newRawPacket (psycHeader *routing, psycString *content, - psycPacketFlag flag) -{ - psycPacket p = {*routing, {0,0}, {0,0}, {0,0}, *content, 0, 0, flag}; + psycPacket p = {{routinglen, routing}, {entitylen, entity}, + {methodlen, method}, {datalen, data}, {0,0}, 0, 0, flag}; if (flag == PSYC_PACKET_CHECK_LENGTH) // find out if it needs a length - p.flag = psyc_checkPacketLength(&p); + p.flag = psyc_packet_length_check(&p); - psyc_setPacketLength(&p); + psyc_packet_length_set(&p); return p; } inline -psycPacket psyc_newRawPacket2 (psycModifier *routing, size_t routinglen, - const char *content, size_t contentlen, - psycPacketFlag flag) +psycPacket psyc_packet_new_raw (psycModifier *routing, size_t routinglen, + char *content, size_t contentlen, + psycPacketFlag flag) { - psycHeader r = {routinglen, routing}; - psycString c = {contentlen, content}; + psycPacket p = {{routinglen, routing}, {0,0}, {0,0}, {0,0}, + {contentlen, content}, 0, 0, flag}; - return psyc_newRawPacket(&r, &c, flag); + if (flag == PSYC_PACKET_CHECK_LENGTH) // find out if it needs a length + p.flag = psyc_packet_length_check(&p); + + psyc_packet_length_set(&p); + return p; } diff --git a/src/parse.c b/src/parse.c index eaa85ad..6fdd807 100644 --- a/src/parse.c +++ b/src/parse.c @@ -29,12 +29,12 @@ typedef enum { * @return PARSE_ERROR or PARSE_SUCCESS */ static inline -parseRC psyc_parseKeyword (psycParseState *state, psycString *name) +parseRC psyc_parse_keyword (psycParseState *state, psycString *name) { name->ptr = state->buffer.ptr + state->cursor; name->length = 0; - while (psyc_isKwChar(state->buffer.ptr[state->cursor])) + while (psyc_is_kw_char(state->buffer.ptr[state->cursor])) { name->length++; // was a valid char, increase length ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); @@ -54,7 +54,7 @@ parseRC psyc_parseKeyword (psycParseState *state, psycString *name) * @return PARSE_COMPLETE or PARSE_INCOMPLETE */ static inline -parseRC psyc_parseBinaryValue (psycParseState *state, psycString *value, +parseRC psyc_parse_binary_value (psycParseState *state, psycString *value, size_t *length, size_t *parsed) { size_t remaining = *length - *parsed; @@ -81,13 +81,13 @@ parseRC psyc_parseBinaryValue (psycParseState *state, psycString *value, * @return PARSE_ERROR or PARSE_SUCCESS */ static inline -parseRC psyc_parseModifier (psycParseState *state, char *oper, +parseRC psyc_parse_modifier (psycParseState *state, char *oper, psycString *name, psycString *value) { *oper = *(state->buffer.ptr + state->cursor); ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); - parseRC ret = psyc_parseKeyword(state, name); + parseRC ret = psyc_parse_keyword(state, name); if (ret == PARSE_ERROR) return PSYC_PARSE_ERROR_MOD_NAME; else if (ret != PARSE_SUCCESS) @@ -105,7 +105,7 @@ parseRC psyc_parseModifier (psycParseState *state, char *oper, { // After SP the length follows. ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); - if (psyc_isNumeric(state->buffer.ptr[state->cursor])) + if (psyc_is_numeric(state->buffer.ptr[state->cursor])) { state->valueLengthFound = 1; do @@ -113,7 +113,7 @@ parseRC psyc_parseModifier (psycParseState *state, char *oper, length = 10 * length + state->buffer.ptr[state->cursor] - '0'; ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } - while (psyc_isNumeric(state->buffer.ptr[state->cursor])); + while (psyc_is_numeric(state->buffer.ptr[state->cursor])); state->valueLength = length; } else @@ -126,7 +126,7 @@ parseRC psyc_parseModifier (psycParseState *state, char *oper, if (++(state->cursor) >= state->buffer.length) return length ? PARSE_INCOMPLETE : PARSE_SUCCESS; // if length=0 we're done - ret = psyc_parseBinaryValue(state, value, &(state->valueLength), &(state->valueParsed)); + ret = psyc_parse_binary_value(state, value, &(state->valueLength), &(state->valueParsed)); if (ret == PARSE_INCOMPLETE) return ret; @@ -197,9 +197,9 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, // 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 (psyc_isGlyph(state->buffer.ptr[state->cursor])) // is the first char a glyph? + if (psyc_is_glyph(state->buffer.ptr[state->cursor])) // is the first char a glyph? { // it is a glyph, so a variable starts here - ret = psyc_parseModifier(state, oper, name, value); + ret = psyc_parse_modifier(state, oper, name, value); state->routingLength += state->cursor - pos; return ret == PARSE_SUCCESS ? PSYC_PARSE_ROUTING : ret; } @@ -212,7 +212,7 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, case PSYC_PART_LENGTH: // End of header, content starts with an optional length then a NL - if (psyc_isNumeric(state->buffer.ptr[state->cursor])) + if (psyc_is_numeric(state->buffer.ptr[state->cursor])) { state->contentLengthFound = 1; state->contentLength = 0; @@ -222,7 +222,7 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, state->contentLength = 10 * state->contentLength + state->buffer.ptr[state->cursor] - '0'; ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } - while (psyc_isNumeric(state->buffer.ptr[state->cursor])); + while (psyc_is_numeric(state->buffer.ptr[state->cursor])); } if (state->buffer.ptr[state->cursor] == '\n') // start of content @@ -257,7 +257,7 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, // In case of an incomplete binary variable resume parsing it. if (state->valueParsed < state->valueLength) { - ret = psyc_parseBinaryValue(state, value, &(state->valueLength), &(state->valueParsed)); + ret = psyc_parse_binary_value(state, value, &(state->valueLength), &(state->valueParsed)); state->contentParsed += value->length; if (ret == PARSE_INCOMPLETE) @@ -280,9 +280,9 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, // 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 (psyc_isGlyph(state->buffer.ptr[state->cursor])) + if (psyc_is_glyph(state->buffer.ptr[state->cursor])) { - ret = psyc_parseModifier(state, oper, name, value); + ret = psyc_parse_modifier(state, oper, name, value); state->contentParsed += state->cursor - pos; if (ret == PARSE_INCOMPLETE) @@ -302,7 +302,7 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, case PSYC_PART_METHOD: pos = state->cursor; - ret = psyc_parseKeyword(state, name); + ret = psyc_parse_keyword(state, name); if (ret == PARSE_INSUFFICIENT) return ret; @@ -352,7 +352,7 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, } if (state->valueParsed < state->valueLength) { - ret = psyc_parseBinaryValue(state, value, &(state->valueLength), &(state->valueParsed)); + ret = psyc_parse_binary_value(state, value, &(state->valueLength), &(state->valueParsed)); state->contentParsed += value->length; if (ret == PARSE_INCOMPLETE) @@ -437,7 +437,7 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, #ifdef __INLINE_PSYC_PARSE static inline #endif -psycParseListRC psyc_parseList (psycParseListState *state, psycString *elem) +psycParseListRC psyc_parse_list (psycParseListState *state, psycString *elem) { if (state->cursor >= state->buffer.length) return PSYC_PARSE_LIST_INCOMPLETE; @@ -452,7 +452,7 @@ psycParseListRC psyc_parseList (psycParseListState *state, psycString *elem) state->type = PSYC_LIST_TEXT; state->cursor++; } - else if (psyc_isNumeric(state->buffer.ptr[state->cursor])) + else if (psyc_is_numeric(state->buffer.ptr[state->cursor])) state->type = PSYC_LIST_BINARY; else return PSYC_PARSE_LIST_ERROR_TYPE; @@ -480,14 +480,14 @@ psycParseListRC psyc_parseList (psycParseListState *state, psycString *elem) if (!(state->elemParsed < state->elemLength)) { // Element starts with a number. - if (psyc_isNumeric(state->buffer.ptr[state->cursor])) + if (psyc_is_numeric(state->buffer.ptr[state->cursor])) { do { state->elemLength = 10 * state->elemLength + state->buffer.ptr[state->cursor] - '0'; ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_LIST_INCOMPLETE); } - while (psyc_isNumeric(state->buffer.ptr[state->cursor])); + while (psyc_is_numeric(state->buffer.ptr[state->cursor])); } else return PSYC_PARSE_LIST_ERROR_LEN; @@ -504,7 +504,7 @@ psycParseListRC psyc_parseList (psycParseListState *state, psycString *elem) // Start or resume parsing the binary data if (state->elemParsed < state->elemLength) { - if (psyc_parseBinaryValue((psycParseState*)state, elem, + if (psyc_parse_binary_value((psycParseState*)state, elem, &(state->elemLength), &(state->elemParsed)) == PARSE_INCOMPLETE) return PSYC_PARSE_LIST_INCOMPLETE; diff --git a/src/psyc_parser_cb.h b/src/psyc_parser_cb.h index 1f38134..ff58491 100644 --- a/src/psyc_parser_cb.h +++ b/src/psyc_parser_cb.h @@ -7,7 +7,7 @@ struct psycParser; * @param pstate pointer to an allocated * psycParser struct. */ -void psyc_initState(struct psycParser* pstate); +void psyc_parse_state_init(struct psycParser* pstate); /** @brief parses a packet @@ -38,7 +38,7 @@ void psyc_initState(struct psycParser* pstate); * raw data that is to be processed. * @param length the amount of bytes to parse * @param pstate pointer to a preallocated - * and initialized (psyc_initState) + * and initialized (psyc_parse_state_init) * instance of the struct state * */ diff --git a/src/render.c b/src/render.c index 449d280..f66a2a8 100644 --- a/src/render.c +++ b/src/render.c @@ -5,7 +5,7 @@ #ifdef __INLINE_PSYC_RENDER static inline #endif -psycRenderListRC psyc_renderList (psycList *list, char *buffer, size_t buflen) +psycRenderListRC psyc_render_list (psycList *list, char *buffer, size_t buflen) { size_t i, cur = 0; psycString *elem; @@ -43,7 +43,7 @@ psycRenderListRC psyc_renderList (psycList *list, char *buffer, size_t buflen) } static inline -size_t psyc_renderModifier (psycModifier *mod, char *buffer) +size_t psyc_render_modifier (psycModifier *mod, char *buffer) { size_t cur = 0; @@ -80,7 +80,7 @@ psycRenderRC psyc_render (psycPacket *packet, char *buffer, size_t buflen) // render routing modifiers for (i = 0; i < packet->routing.lines; i++) { - len = psyc_renderModifier(&packet->routing.modifiers[i], buffer + cur); + len = psyc_render_modifier(&packet->routing.modifiers[i], buffer + cur); cur += len; if (len <= 1) return PSYC_RENDER_ERROR_MODIFIER_NAME_MISSING; @@ -103,7 +103,7 @@ psycRenderRC psyc_render (psycPacket *packet, char *buffer, size_t buflen) { // render entity modifiers for (i = 0; i < packet->entity.lines; i++) - cur += psyc_renderModifier(&packet->entity.modifiers[i], buffer + cur); + cur += psyc_render_modifier(&packet->entity.modifiers[i], buffer + cur); if (packet->method.length) // add method\n { diff --git a/src/uniform.c b/src/uniform.c index 519e5c0..efc36bb 100644 --- a/src/uniform.c +++ b/src/uniform.c @@ -3,7 +3,7 @@ #include "psyc/uniform.h" #include "psyc/parse.h" -int psyc_parseUniform2 (psycUniform *uni, const char *str, size_t length) +int psyc_uniform_parse (psycUniform *uni, char *str, size_t length) { char c; psycString *p; @@ -19,7 +19,7 @@ int psyc_parseUniform2 (psycUniform *uni, const char *str, size_t length) uni->scheme.ptr = str; uni->scheme.length = pos++; break; - } else if (!psyc_isHostChar(c)) + } else if (!psyc_is_host_char(c)) return PSYC_PARSE_UNIFORM_INVALID_SCHEME; pos++; } @@ -52,7 +52,7 @@ int psyc_parseUniform2 (psycUniform *uni, const char *str, size_t length) break; case PSYC_UNIFORM_HOST: - if (psyc_isHostChar(c)) { + if (psyc_is_host_char(c)) { uni->host.length++; break; } @@ -74,7 +74,7 @@ int psyc_parseUniform2 (psycUniform *uni, const char *str, size_t length) break; case PSYC_UNIFORM_PORT: - if (psyc_isNumeric(c)) { + if (psyc_is_numeric(c)) { uni->port.length++; break; } @@ -118,7 +118,7 @@ int psyc_parseUniform2 (psycUniform *uni, const char *str, size_t length) break; case PSYC_UNIFORM_RESOURCE: - if (psyc_isNameChar(c)) { + if (psyc_is_name_char(c)) { uni->resource.length++; break; } else if (c == '#') { @@ -129,7 +129,7 @@ int psyc_parseUniform2 (psycUniform *uni, const char *str, size_t length) } else return PSYC_PARSE_UNIFORM_INVALID_RESOURCE; case PSYC_UNIFORM_CHANNEL: - if (psyc_isNameChar(c)) { + if (psyc_is_name_char(c)) { uni->channel.length++; break; } else return PSYC_PARSE_UNIFORM_INVALID_CHANNEL; @@ -165,8 +165,3 @@ int psyc_parseUniform2 (psycUniform *uni, const char *str, size_t length) uni->valid = 1; return uni->type; } - -int psyc_parseUniform (psycUniform *uni, psycString *str) -{ - return psyc_parseUniform2(uni, str->ptr, str->length); -} diff --git a/src/variable.c b/src/variable.c index b0de9f5..e13614b 100644 --- a/src/variable.c +++ b/src/variable.c @@ -3,7 +3,7 @@ /// Routing variables in alphabetical order. -const psycString psyc_routingVars[] = +const psycString psyc_routing_vars[] = { PSYC_C2STR("_amount_fragments"), PSYC_C2STR("_context"), @@ -27,7 +27,7 @@ const psycString psyc_routingVars[] = }; // Variable types in alphabetical order. -const psycMatchVar psyc_varTypes[] = +const psycMatchVar psyc_var_types[] = { {PSYC_C2STR("_amount"), PSYC_TYPE_AMOUNT}, {PSYC_C2STR("_color"), PSYC_TYPE_COLOR}, @@ -43,43 +43,42 @@ const psycMatchVar psyc_varTypes[] = {PSYC_C2STR("_time"), PSYC_TYPE_TIME}, }; -const size_t psyc_routingVarsNum = PSYC_NUM_ELEM(psyc_routingVars); -const size_t psyc_varTypesNum = PSYC_NUM_ELEM(psyc_varTypes); +const size_t psyc_routing_vars_num = PSYC_NUM_ELEM(psyc_routing_vars); +const size_t psyc_var_types_num = PSYC_NUM_ELEM(psyc_var_types); /** * Get the type of variable name. */ inline -psycBool psyc_isRoutingVar2(const char *name, size_t len) +psycBool psyc_var_is_routing (const char *name, size_t len) { - //return psyc_matchArray(psyc_routingVars, PSYC_NUM_ELEM(psyc_routingVars), name, len, 0); size_t cursor = 1; uint8_t i, m = 0; - int8_t matching[psyc_routingVarsNum]; // indexes of matching vars + int8_t matching[psyc_routing_vars_num]; // indexes of matching vars if (len < 2 || name[0] != '_') return PSYC_FALSE; // first find the vars with matching length - for (i=0; i= 0) { - for (i = m = 0; i < psyc_routingVarsNum; i++) + for (i = m = 0; i < psyc_routing_vars_num; i++) { if (matching[i] < 0) break; // reached the end of possible matches - if (psyc_routingVars[matching[i]].ptr[cursor] == name[cursor]) + if (psyc_routing_vars[matching[i]].ptr[cursor] == name[cursor]) matching[m++] = matching[i]; // found a match, update matching indexes - else if (psyc_routingVars[matching[i]].ptr[cursor] > name[cursor]) + else if (psyc_routing_vars[matching[i]].ptr[cursor] > name[cursor]) break; // passed the possible matches in alphabetical order in the array } - if (m < psyc_routingVarsNum) + if (m < psyc_routing_vars_num) matching[m] = -1; // mark the end of matching indexes cursor++; @@ -88,114 +87,13 @@ psycBool psyc_isRoutingVar2(const char *name, size_t len) return matching[0] >= 0 ? PSYC_TRUE : PSYC_FALSE; } -psycBool psyc_isRoutingVar(psycString *name) -{ - return psyc_isRoutingVar2(name->ptr, name->length); -} - /** * Get the type of variable name. */ inline -psycType psyc_getVarType2(const char *name, size_t len) +psycType psyc_var_type (const char *name, size_t len) { - //return psyc_matchArray(psyc_varTypes, PSYC_NUM_ELEM(psyc_varTypes), name, len, 1); - size_t cursor = 1; - uint8_t i, m = 0; - int8_t matching[psyc_varTypesNum]; // indexes of matching vars - - if (len < 2 || name[0] != '_') - return 0; - - // first find the vars with matching length - for (i=0; i psyc_varTypes[i].name.length && name[psyc_varTypes[i].name.length] == '_')) - matching[m++] = i; - - matching[m] = -1; // mark the end of matching indexes - - while (cursor < len && matching[0] >= 0) - { - for (i = m = 0; i < psyc_varTypesNum; i++) - { - if (matching[i] < 0) - break; // reached the end of possible matches - if (cursor < psyc_varTypes[matching[i]].name.length && - psyc_varTypes[matching[i]].name.ptr[cursor] == name[cursor]) - matching[m++] = matching[i]; // found a match, update matching indexes - else if (cursor == psyc_varTypes[matching[i]].name.length && name[cursor] == '_') - return psyc_varTypes[matching[0]].value; // _ after the end of a matching prefix - else if (psyc_varTypes[matching[i]].name.ptr[cursor] > name[cursor]) - break; // passed the possible matches in alphabetical order in the array - } - - if (m < psyc_varTypesNum) - matching[m] = -1; // mark the end of matching indexes - - cursor++; - } - - // return first match if found - return matching[0] >= 0 ? psyc_varTypes[matching[0]].value : 0; -} - -psycType psyc_getVarType(psycString *name) -{ - return psyc_getVarType2(name->ptr, name->length); -} - -/** - * Search for a variable name in an array. - * - * @param array The array to search, should be ordered alphabetically. - * @param size Size of array. - * @param name Name of variable to look for. - * @param namelen Length of name. - * @param startswith If true, look for any variable starting with name, - otherwise only exact matches are returned. - * @param matching A temporary array used for keeping track of results. - * Should be the same size as the array we're searching. - * - * @return The value of the matched variable in the array. - */ -int psyc_findVar(const psycMatchVar *array, size_t size, - const char *name, size_t namelen, - uint8_t startswith, int8_t *matching) -{ - size_t cursor = 1; - uint8_t i, m = 0; - //memset(&matching, -1, sizeof matching); - - if (namelen < 2 || name[0] != '_') - return 0; - - // first find the vars with matching length - for (i=0; i array[i].name.length && - name[array[i].name.length] == '_')) - matching[m++] = i; - - matching[m] = -1; // mark the end of matching indexes - - while (cursor < namelen && matching[0] >= 0) - { - for (i = m = 0; i < size; i++) - { - if (matching[i] < 0) - break; - if (array[matching[i]].name.ptr[cursor] == name[cursor]) - matching[m++] = matching[i]; // found a match, update matching indexes - else if (array[matching[i]].name.ptr[cursor] > name[cursor]) - break; // passed the possible matches in alphabetical order - } - - if (m < size) - matching[m] = -1; // mark the end of matching indexes - - cursor++; - } - - // return first match if found - return matching[0] >= 0 ? array[matching[0]].value : 0; + int8_t m[psyc_var_types_num]; + return psyc_in_array(psyc_var_types, psyc_var_types_num, + name, len, PSYC_YES, (int8_t*)&m); } diff --git a/test/Makefile b/test/Makefile index ed0de0b..05a41c2 100644 --- a/test/Makefile +++ b/test/Makefile @@ -3,7 +3,7 @@ DEBUG = 2 CFLAGS = -I../include -I../src -Wall -std=c99 ${OPT} LDFLAGS = -L../lib LOADLIBES = -lpsyc -lm -TARGETS = testPsyc testPsycSpeed testParser testMatch testRender testText isRoutingVar getVarType parseUniform +TARGETS = test_psyc test_psyc_speed test_parser test_match test_render test_text var_is_routing var_type uniform_parse O = test.o WRAPPER = DIET = diet @@ -20,16 +20,16 @@ endif all: ${TARGETS} it: all -testPsyc: LOADLIBES := ${LOADLIBES} ${LOADLIBES_NET} -testPsycSpeed: LOADLIBES := ${LOADLIBES} ${LOADLIBES_NET} -#testPsycSpeed: LOADLIBES := ${LOADLIBES_NET} +test_psyc: LOADLIBES := ${LOADLIBES} ${LOADLIBES_NET} +test_psyc_speed: LOADLIBES := ${LOADLIBES} ${LOADLIBES_NET} +#test_psyc_speed: LOADLIBES := ${LOADLIBES_NET} -testJson: LOADLIBES := ${LOADLIBES_NET} -ljson +test_json: LOADLIBES := ${LOADLIBES_NET} -ljson -testJsonGlib: CFLAGS := ${CFLAGS} -I/usr/include/json-glib-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -testJsonGlib: LOADLIBES := ${LOADLIBES_NET} -ljson-glib-1.0 +test_json_glib: CFLAGS := ${CFLAGS} -I/usr/include/json-glib-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include +test_json_glib: LOADLIBES := ${LOADLIBES_NET} -ljson-glib-1.0 -testStrlen: LOADLIBES := ${LOADLIBES_NET} +test_strlen: LOADLIBES := ${LOADLIBES_NET} diet: WRAPPER = ${DIET} diet: all @@ -42,14 +42,14 @@ clean: rm -f ${TARGETS} $O test: ${TARGETS} - ./testRender - ./testMatch - ./testText - ./isRoutingVar - ./getVarType - ./parseUniform - x=0; for f in packets/[0-9]*; do echo ">> $$f"; ./testPsyc -f $$f | ${DIFF} -u $$f -; x=$$((x+$$?)); done; exit $$x - x=0; for f in packets/[0-9]*; do echo ">> $$f"; ./testPsyc -rf $$f | ${DIFF} -u $$f -; x=$$((x+$$?)); done; exit $$x + ./test_render + ./test_match + ./test_text + ./var_is_routing + ./var_type + ./uniform_parse + x=0; for f in packets/[0-9]*; do echo ">> $$f"; ./test_psyc -f $$f | ${DIFF} -u $$f -; x=$$((x+$$?)); done; exit $$x + x=0; for f in packets/[0-9]*; do echo ">> $$f"; ./test_psyc -rf $$f | ${DIFF} -u $$f -; x=$$((x+$$?)); done; exit $$x .NOTPARALLEL: nettestrun @@ -58,12 +58,12 @@ nettest: nettestfull nettestsplit nettestrun: srvstart pkt srvkill nettestfull: - ${MAKE} nettestrun; x=$$?; pkill -x testPsyc; exit $$x - ${MAKE} nettestrun srv_args=-r; x=$$?; pkill -x testPsyc; exit $$x + ${MAKE} nettestrun; x=$$?; pkill -x test_psyc; exit $$x + ${MAKE} nettestrun srv_args=-r; x=$$?; pkill -x test_psyc; exit $$x split_max = 10 nettestsplit: - x=0; for n in `seq 1 ${split_max}`; do ${MAKE} nettestrun srv_args="-b $$n" && ${MAKE} nettestrun srv_args="-r -b $$n" || break; done; x=$$?; pkill -x testPsyc; exit $$x + x=0; for n in `seq 1 ${split_max}`; do ${MAKE} nettestrun srv_args="-b $$n" && ${MAKE} nettestrun srv_args="-r -b $$n" || break; done; x=$$?; pkill -x test_psyc; exit $$x pkt: x=0; for f in packets/[0-9]*; do echo ">> $$f"; cat $$f | nc localhost ${PORT} | ${DIFF} -u $$f -; x=$$((x+$$?)); done; exit $$x @@ -75,37 +75,37 @@ pkterr: for f in packets/err-*; do echo ">> $$f"; cat $$f | nc localhost ${PORT}; done srvstart: - pkill -x testPsyc; exit 0 - ./testPsyc -p ${PORT} -S ${srv_args} & + pkill -x test_psyc; exit 0 + ./test_psyc -p ${PORT} -S ${srv_args} & srvkill: - pkill -x testPsyc + pkill -x test_psyc bench: bench-genpkts bench-psyc bench-psyc-bin bench-json bench-json-bin bench-xml bench-dir: @mkdir -p ../bench/results -bench-psyc: bench-dir testStrlen testPsycSpeed - for f in ../bench/packets/*.psyc; do bf=`basename $$f`; echo strlen: $$bf; ./testStrlen -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf.strlen; done - for f in ../bench/packets/*.psyc; do bf=`basename $$f`; echo libpsyc: $$f; ./testPsycSpeed -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf; done +bench-psyc: bench-dir test_strlen test_psyc_speed + for f in ../bench/packets/*.psyc; do bf=`basename $$f`; echo strlen: $$bf; ./test_strlen -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf.strlen; done + for f in ../bench/packets/*.psyc; do bf=`basename $$f`; echo libpsyc: $$f; ./test_psyc_speed -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf; done -bench-psyc-bin: bench-dir testStrlen testPsycSpeed - for f in `ls ../bench/packets/binary/*.psyc | sort -r`; do bf=`basename $$f`; echo "libpsyc: $$f * 1000000"; ./testPsycSpeed -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf; done - c=1000000; for f in `ls ../bench/packets/binary/*.psyc | sort -r`; do bf=`basename $$f`; echo "strlen: $$bf * $$c"; ./testStrlen -sc $$c -f $$f | ${TEE} -a ../bench/results/$$bf.strlen; c=$$((c/10)); done +bench-psyc-bin: bench-dir test_strlen test_psyc_speed + for f in `ls ../bench/packets/binary/*.psyc | sort -r`; do bf=`basename $$f`; echo "libpsyc: $$f * 1000000"; ./test_psyc_speed -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf; done + c=1000000; for f in `ls ../bench/packets/binary/*.psyc | sort -r`; do bf=`basename $$f`; echo "strlen: $$bf * $$c"; ./test_strlen -sc $$c -f $$f | ${TEE} -a ../bench/results/$$bf.strlen; c=$$((c/10)); done -bench-json: bench-dir testJson testJsonGlib -# for f in ../bench/packets/*.json; do bf=`basename $$f`; echo strlen: $$bf; ./testStrlen -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf.strlen; done - for f in ../bench/packets/*.json; do bf=`basename $$f`; echo json-c: $$bf; ./testJson -snc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf; done - for f in ../bench/packets/*.json; do bf=`basename $$f`; echo json-glib: $$bf; ./testJsonGlib -snc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf-glib; done +bench-json: bench-dir test_json test_json_glib +# for f in ../bench/packets/*.json; do bf=`basename $$f`; echo strlen: $$bf; ./test_strlen -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf.strlen; done + for f in ../bench/packets/*.json; do bf=`basename $$f`; echo json-c: $$bf; ./test_json -snc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf; done + for f in ../bench/packets/*.json; do bf=`basename $$f`; echo json-glib: $$bf; ./test_json_glib -snc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf-glib; done -bench-json-bin: bench-dir testJson testJsonGlib - c=1000000; for f in `ls ../bench/packets/binary/*.json | sort -r`; do bf=`basename $$f`; echo "json-c: $$bf * $$c"; ./testJson -snc $$c -f $$f | ${TEE} -a ../bench/results/$$bf; c=$$((c/10)); done - c=1000000; for f in `ls ../bench/packets/binary/*.json | sort -r`; do bf=`basename $$f`; echo "json-glib: $$bf * $$c"; ./testJsonGlib -snc $$c -f $$f | ${TEE} -a ../bench/results/$$bf-glib; c=$$((c/10)); done +bench-json-bin: bench-dir test_json test_json_glib + c=1000000; for f in `ls ../bench/packets/binary/*.json | sort -r`; do bf=`basename $$f`; echo "json-c: $$bf * $$c"; ./test_json -snc $$c -f $$f | ${TEE} -a ../bench/results/$$bf; c=$$((c/10)); done + c=1000000; for f in `ls ../bench/packets/binary/*.json | sort -r`; do bf=`basename $$f`; echo "json-glib: $$bf * $$c"; ./test_json_glib -snc $$c -f $$f | ${TEE} -a ../bench/results/$$bf-glib; c=$$((c/10)); done bench-xml: bench-dir @[[ -n "${xmlbench}" ]] || (echo xmlbench path needs to be set with xmlbench=/path/to/xmlbench; exit 1) -# for f in ../bench/packets/*.xml; do bf=`basename $$f`; echo strlen: $$bf; ./testStrlen -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf.strlen; done +# for f in ../bench/packets/*.xml; do bf=`basename $$f`; echo strlen: $$bf; ./test_strlen -sc 1000000 -f $$f | ${TEE} -a ../bench/results/$$bf.strlen; done for f in ../bench/packets/*.xml; do bf=`basename $$f`; echo libxml: $$bf; ${xmlbench}/parse/libxml 1000000 $$f | ${TEE} -a ../bench/results/$$bf-libxml; done for f in ../bench/packets/*.xml; do bf=`basename $$f`; echo libxml-sax: $$bf; ${xmlbench}/parse/libxml-sax 1000000 $$f | ${TEE} -a ../bench/results/$$bf-libxml-sax; done for f in ../bench/packets/*.xml; do bf=`basename $$f`; echo rapidxml: $$bf; ${xmlbench}/parse/rapidxml 1000000 $$f | ${TEE} -a ../bench/results/$$bf-rapidxml; done diff --git a/test/getVarType.c b/test/getVarType.c deleted file mode 100644 index de7f9e0..0000000 --- a/test/getVarType.c +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include -#include -#include -#include - -int main() { - unless (psyc_getVarType2(PSYC_C2ARG("_list"))) return 1; - unless (psyc_getVarType2(PSYC_C2ARG("_list_foo"))) return 2; - unless (psyc_getVarType2(PSYC_C2ARG("_color_red"))) return 3; - if (psyc_getVarType2(PSYC_C2ARG("_last"))) return 4; - if (psyc_getVarType2(PSYC_C2ARG("_lost_foo"))) return 5; - if (psyc_getVarType2(PSYC_C2ARG("_colorful"))) return 6; - if (psyc_getVarType2(PSYC_C2ARG("_foo"))) return 7; - if (psyc_getVarType2(PSYC_C2ARG("bar"))) return 8; - if (psyc_getVarType2(PSYC_C2ARG("______"))) return 9; - if (psyc_getVarType2(PSYC_C2ARG("_"))) return 10; - - puts("psyc_getVarType passed all tests."); - return 0; // passed all tests -} diff --git a/test/isRoutingVar.c b/test/isRoutingVar.c deleted file mode 100644 index 4b6e431..0000000 --- a/test/isRoutingVar.c +++ /dev/null @@ -1,39 +0,0 @@ -#include -#include -#include -#include -#include - -int main() { -#if 0 - const char* vars[] = - { - "_source", - "_source_relay", - "_source_foo", - "_sourcherry", - "_foo", - "bar", - "_", - }; - - int i; - for (i = 0; i < sizeof(vars) / sizeof(*vars); i++) - { - printf(">> %s: %d %d\n", vars[i], sizeof(vars[i]), sizeof(*vars[i])); - printf("%s: %d\n", vars[i], psyc_isRoutingVar2(vars[i], strlen(vars[i]))); - } -#else - unless (psyc_isRoutingVar2(PSYC_C2ARG("_source"))) return 1; - unless (psyc_isRoutingVar2(PSYC_C2ARG("_source_relay"))) return 2; - if (psyc_isRoutingVar2(PSYC_C2ARG("_source_foo"))) return 3; - if (psyc_isRoutingVar2(PSYC_C2ARG("_sourcherry"))) return 4; - if (psyc_isRoutingVar2(PSYC_C2ARG("_sour"))) return 5; - if (psyc_isRoutingVar2(PSYC_C2ARG("_foo"))) return 6; - if (psyc_isRoutingVar2(PSYC_C2ARG("bar"))) return 7; - if (psyc_isRoutingVar2(PSYC_C2ARG("_"))) return 8; - - puts("psyc_isRoutingVar passed all tests."); -#endif - return 0; // passed all tests -} diff --git a/test/testJson.c b/test/test_json.c similarity index 100% rename from test/testJson.c rename to test/test_json.c diff --git a/test/testJsonGlib.c b/test/test_json_glib.c similarity index 100% rename from test/testJsonGlib.c rename to test/test_json_glib.c diff --git a/test/testMatch.c b/test/test_match.c similarity index 100% rename from test/testMatch.c rename to test/test_match.c diff --git a/test/testParser.c b/test/test_parser.c similarity index 84% rename from test/testParser.c rename to test/test_parser.c index 641c70d..9566692 100644 --- a/test/testParser.c +++ b/test/test_parser.c @@ -28,12 +28,9 @@ int main (int argc, char **argv) printf(">> PARSE\n"); } - if (routing_only) - psyc_initParseState2(&state, PSYC_PARSE_ROUTING_ONLY); - else - psyc_initParseState(&state); - - psyc_setParseBuffer2(&state, buffer, idx); + psyc_parse_state_init(&state, routing_only ? + PSYC_PARSE_ROUTING_ONLY : PSYC_PARSE_ALL); + psyc_parse_buffer_set(&state, buffer, idx); // try parsing that now do @@ -59,15 +56,15 @@ int main (int argc, char **argv) (int)name.length, name.ptr, (int)value.length, value.ptr); - if (psyc_isListVar(&name)) + if (psyc_var_is_list(PSYC_S2ARG(name))) { if (verbose) printf(">> LIST START\n"); - psyc_initParseListState(&listState); - psyc_setParseListBuffer(&listState, value); + psyc_parse_list_state_init(&listState); + psyc_parse_list_buffer_set(&listState, PSYC_S2ARG(value)); - while ((ret = psyc_parseList(&listState, &elem))) + while ((ret = psyc_parse_list(&listState, &elem))) { switch (ret) { diff --git a/test/testPsyc.c b/test/test_psyc.c similarity index 90% rename from test/testPsyc.c rename to test/test_psyc.c index 2deb620..1ce375f 100644 --- a/test/testPsyc.c +++ b/test/test_psyc.c @@ -37,10 +37,8 @@ void resetString (psycString *s, uint8_t freeptr); // initialize parser & packet variables void test_init (int i) { // reset parser state & packet - if (routing_only) - psyc_initParseState2(&parsers[i], PSYC_PARSE_ROUTING_ONLY); - else - psyc_initParseState(&parsers[i]); + psyc_parse_state_init(&parsers[i], routing_only ? + PSYC_PARSE_ROUTING_ONLY : PSYC_PARSE_ALL); memset(&packets[i], 0, sizeof(psycPacket)); memset(&routing[i], 0, sizeof(psycModifier) * ROUTING_LINES); @@ -76,7 +74,7 @@ int test_input (int i, char *recvbuf, size_t nbytes) { size_t len; // Set buffer with data for the parser. - psyc_setParseBuffer2(parser, parsebuf, contbytes + nbytes); + psyc_parse_buffer_set(parser, parsebuf, contbytes + nbytes); contbytes = 0; oper = 0; name.length = 0; @@ -111,7 +109,7 @@ int test_input (int i, char *recvbuf, size_t nbytes) { if (ret == PSYC_PARSE_ENTITY || ret == PSYC_PARSE_ENTITY_END) { packet->entity.lines++; - mod->flag = psyc_isParseValueLengthFound(parser) ? + mod->flag = psyc_parse_value_length_found(parser) ? PSYC_MODIFIER_NEED_LENGTH : PSYC_MODIFIER_NO_LENGTH; } break; @@ -133,7 +131,7 @@ int test_input (int i, char *recvbuf, size_t nbytes) { ret = -1; if (!no_render) { - packet->flag = psyc_isParseContentLengthFound(parser) ? + packet->flag = psyc_parse_content_length_found(parser) ? PSYC_PACKET_NEED_LENGTH : PSYC_PACKET_NO_LENGTH; if (routing_only) { @@ -141,7 +139,7 @@ int test_input (int i, char *recvbuf, size_t nbytes) { resetString(&(packet->data), 0); } - psyc_setPacketLength(packet); + psyc_packet_length_set(packet); if (psyc_render(packet, sendbuf, SEND_BUF_SIZE) == PSYC_RENDER_SUCCESS) { if (!quiet) { @@ -190,13 +188,13 @@ int test_input (int i, char *recvbuf, size_t nbytes) { if (verbose >= 2) printf("# Insufficient data.\n"); - contbytes = psyc_getParseRemainingLength(parser); + contbytes = psyc_parse_remaining_length(parser); if (contbytes > 0) { // copy end of parsebuf before start of recvbuf if (verbose >= 3) - printf("# remaining = [%.*s]\n", (int)contbytes, psyc_getParseRemainingBuffer(parser)); + printf("# remaining = [%.*s]\n", (int)contbytes, psyc_parse_remaining_buffer(parser)); assert(contbytes <= CONT_BUF_SIZE); // make sure it's still in the buffer - memmove(recvbuf - contbytes, psyc_getParseRemainingBuffer(parser), contbytes); + memmove(recvbuf - contbytes, psyc_parse_remaining_buffer(parser), contbytes); } ret = 0; break; @@ -237,8 +235,8 @@ int test_input (int i, char *recvbuf, size_t nbytes) { if (value.length) { if (!pvalue->length) { - if (psyc_isParseValueLengthFound(parser)) - len = psyc_getParseValueLength(parser); + if (psyc_parse_value_length_found(parser)) + len = psyc_parse_value_length(parser); else len = value.length; pvalue->ptr = malloc(len); @@ -272,15 +270,15 @@ int test_input (int i, char *recvbuf, size_t nbytes) { name.length = 0; value.length = 0; - if (psyc_isListVar(pname)) { + if (psyc_var_is_list(PSYC_S2ARG(*pname))) { if (verbose >= 2) printf("## LIST START\n"); - psyc_initParseListState(&listState); - psyc_setParseListBuffer(&listState, *pvalue); + psyc_parse_list_state_init(&listState); + psyc_parse_list_buffer_set(&listState, PSYC_S2ARG(*pvalue)); do { - retl = psyc_parseList(&listState, &elem); + retl = psyc_parse_list(&listState, &elem); switch (retl) { case PSYC_PARSE_LIST_END: retl = 0; diff --git a/test/testPsycSpeed.c b/test/test_psyc_speed.c similarity index 88% rename from test/testPsycSpeed.c rename to test/test_psyc_speed.c index b17f5d8..3abcfe1 100644 --- a/test/testPsycSpeed.c +++ b/test/test_psyc_speed.c @@ -26,10 +26,8 @@ size_t count = 1, recv_buf_size; psycParseState parser; void test_init (int i) { - if (routing_only) - psyc_initParseState2(&parser, PSYC_PARSE_ROUTING_ONLY); - else - psyc_initParseState(&parser); + psyc_parse_state_init(&parser, routing_only ? + PSYC_PARSE_ROUTING_ONLY : PSYC_PARSE_ALL); } int test_input (int i, char *recvbuf, size_t nbytes) { @@ -37,7 +35,7 @@ int test_input (int i, char *recvbuf, size_t nbytes) { psycString name, value; int ret; - psyc_setParseBuffer2(&parser, recvbuf, nbytes); + psyc_parse_buffer_set(&parser, recvbuf, nbytes); for (;;) { ret = psyc_parse(&parser, &oper, &name, &value); diff --git a/test/testRender.c b/test/test_render.c similarity index 76% rename from test/testRender.c rename to test/test_render.c index 1f1f61b..59432b3 100644 --- a/test/testRender.c +++ b/test/test_render.c @@ -12,19 +12,19 @@ int testPresence (const char *avail, int availlen, const char *rendered, uint8_t verbose) { psycModifier routing[] = { - psyc_newModifier2(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_context"), PSYC_C2ARG(myUNI), + psyc_modifier_new(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_context"), PSYC_C2ARG(myUNI), PSYC_MODIFIER_ROUTING), }; psycModifier entity[] = { // presence is to be assigned permanently in distributed state - psyc_newModifier2(C_GLYPH_OPERATOR_ASSIGN, PSYC_C2ARG("_degree_availability"), + psyc_modifier_new(C_GLYPH_OPERATOR_ASSIGN, PSYC_C2ARG("_degree_availability"), avail, availlen, PSYC_MODIFIER_CHECK_LENGTH), - psyc_newModifier2(C_GLYPH_OPERATOR_ASSIGN, PSYC_C2ARG("_description_presence"), + psyc_modifier_new(C_GLYPH_OPERATOR_ASSIGN, PSYC_C2ARG("_description_presence"), desc, desclen, PSYC_MODIFIER_CHECK_LENGTH), }; - psycPacket packet = psyc_newPacket2(routing, PSYC_NUM_ELEM(routing), + psycPacket packet = psyc_packet_new(routing, PSYC_NUM_ELEM(routing), entity, PSYC_NUM_ELEM(entity), PSYC_C2ARG("_notice_presence"), NULL, 0, @@ -40,9 +40,9 @@ int testPresence (const char *avail, int availlen, int testList (const char *rendered, uint8_t verbose) { psycModifier routing[] = { - psyc_newModifier2(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_source"), PSYC_C2ARG(myUNI), + psyc_modifier_new(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_source"), PSYC_C2ARG(myUNI), PSYC_MODIFIER_ROUTING), - psyc_newModifier2(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_context"), PSYC_C2ARG(myUNI), + psyc_modifier_new(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_context"), PSYC_C2ARG(myUNI), PSYC_MODIFIER_ROUTING), }; @@ -59,21 +59,21 @@ int testList (const char *rendered, uint8_t verbose) }; psycList list_text, list_bin; - list_text = psyc_newList(elems_text, PSYC_NUM_ELEM(elems_text), PSYC_LIST_CHECK_LENGTH); - list_bin = psyc_newList(elems_bin, PSYC_NUM_ELEM(elems_bin), PSYC_LIST_CHECK_LENGTH); + list_text = psyc_list_new(elems_text, PSYC_NUM_ELEM(elems_text), PSYC_LIST_CHECK_LENGTH); + list_bin = psyc_list_new(elems_bin, PSYC_NUM_ELEM(elems_bin), PSYC_LIST_CHECK_LENGTH); char buf_text[32], buf_bin[32]; - psyc_renderList(&list_text, buf_text, sizeof(buf_text)); - psyc_renderList(&list_bin, buf_bin, sizeof(buf_bin)); + psyc_render_list(&list_text, buf_text, sizeof(buf_text)); + psyc_render_list(&list_bin, buf_bin, sizeof(buf_bin)); psycModifier entity[] = { - psyc_newModifier2(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_list_text"), + psyc_modifier_new(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_list_text"), buf_text, list_text.length, list_text.flag), - psyc_newModifier2(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_list_binary"), + psyc_modifier_new(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_list_binary"), buf_bin, list_bin.length, list_bin.flag), }; - psycPacket packet = psyc_newPacket2(routing, PSYC_NUM_ELEM(routing), + psycPacket packet = psyc_packet_new(routing, PSYC_NUM_ELEM(routing), entity, PSYC_NUM_ELEM(entity), PSYC_C2ARG("_test_list"), PSYC_C2ARG("list test"), diff --git a/test/testStrlen.c b/test/test_strlen.c similarity index 100% rename from test/testStrlen.c rename to test/test_strlen.c diff --git a/test/testText.c b/test/test_text.c similarity index 92% rename from test/testText.c rename to test/test_text.c index 5f667f5..214d106 100644 --- a/test/testText.c +++ b/test/test_text.c @@ -38,17 +38,17 @@ int testText (char *template, size_t tmplen, char *buffer, size_t buflen, psycSt size_t length = 0; psycTextRC ret; - psyc_initTextState(&state, template, tmplen, buffer, buflen); + psyc_text_state_init(&state, template, tmplen, buffer, buflen); do { ret = psyc_text(&state, getValue, NULL); - length += psyc_getTextBytesWritten(&state); + length += psyc_text_bytes_written(&state); switch (ret) { case PSYC_TEXT_INCOMPLETE: if (verbose) printf("# %.*s...\n", (int)length, buffer); - psyc_setTextBuffer2(&state, buffer + length, BUFSIZE - length); + psyc_text_buffer_set(&state, buffer + length, BUFSIZE - length); break; case PSYC_TEXT_COMPLETE: if (verbose) diff --git a/test/parseUniform.c b/test/uniform_parse.c similarity index 86% rename from test/parseUniform.c rename to test/uniform_parse.c index ae20c5e..ff5d307 100644 --- a/test/parseUniform.c +++ b/test/uniform_parse.c @@ -4,11 +4,11 @@ #include void -testUniform(char *str, int ret) { +testUniform (char *str, int ret) { psycUniform *uni = malloc(sizeof(psycUniform)); memset(uni, 0, sizeof(psycUniform)); printf("%s\n", str); - int r = psyc_parseUniform2(uni, str, strlen(str)); + int r = psyc_uniform_parse(uni, str, strlen(str)); PP(("[%.*s] : [%.*s] [%.*s] : [%.*s] [%.*s] / [%.*s] # [%.*s]\n[%.*s] [%.*s]\n[%.*s]\n\n", (int)PSYC_S2ARG2(uni->scheme), @@ -24,12 +24,12 @@ testUniform(char *str, int ret) { free(uni); if (r != ret) { - fprintf(stderr, "ERROR: psyc_parseUniform returned %d instead of %d\n", r, ret); + fprintf(stderr, "ERROR: psyc_uniform_parse returned %d instead of %d\n", r, ret); exit(1); } } -int main() { +int main () { testUniform("psyc://foo.tld:4404d/@bar#baz", PSYC_SCHEME_PSYC); testUniform("psyc://foo:4405/~bar", PSYC_SCHEME_PSYC); testUniform("psyc://foo:1234", PSYC_SCHEME_PSYC); @@ -46,6 +46,6 @@ int main() { testUniform("psyc://host:d/~foo", PSYC_PARSE_UNIFORM_INVALID_PORT); testUniform("psyc://1234567890abcdef:1g/~foo", PSYC_PARSE_UNIFORM_INVALID_TRANSPORT); - printf("SUCCESS: psyc_parseUniform passed all tests.\n"); + printf("SUCCESS: psyc_uniform_parse passed all tests.\n"); return 0; } diff --git a/test/var_is_routing.c b/test/var_is_routing.c new file mode 100644 index 0000000..bb3ffca --- /dev/null +++ b/test/var_is_routing.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#include + +int main() { +#if 0 + const char* vars[] = + { + "_source", + "_source_relay", + "_source_foo", + "_sourcherry", + "_foo", + "bar", + "_", + }; + + int i; + for (i = 0; i < sizeof(vars) / sizeof(*vars); i++) + { + printf(">> %s: %d %d\n", vars[i], sizeof(vars[i]), sizeof(*vars[i])); + printf("%s: %d\n", vars[i], psyc_var_is_routing(vars[i], strlen(vars[i]))); + } +#else + unless (psyc_var_is_routing(PSYC_C2ARG("_source"))) return 1; + unless (psyc_var_is_routing(PSYC_C2ARG("_source_relay"))) return 2; + if (psyc_var_is_routing(PSYC_C2ARG("_source_foo"))) return 3; + if (psyc_var_is_routing(PSYC_C2ARG("_sourcherry"))) return 4; + if (psyc_var_is_routing(PSYC_C2ARG("_sour"))) return 5; + if (psyc_var_is_routing(PSYC_C2ARG("_foo"))) return 6; + if (psyc_var_is_routing(PSYC_C2ARG("bar"))) return 7; + if (psyc_var_is_routing(PSYC_C2ARG("_"))) return 8; + + puts("psyc_var_is_routing passed all tests."); +#endif + return 0; // passed all tests +} diff --git a/test/var_type.c b/test/var_type.c new file mode 100644 index 0000000..b043979 --- /dev/null +++ b/test/var_type.c @@ -0,0 +1,21 @@ +#include +#include +#include +#include +#include + +int main() { + unless (psyc_var_type(PSYC_C2ARG("_list"))) return 1; + unless (psyc_var_type(PSYC_C2ARG("_list_foo"))) return 2; + unless (psyc_var_type(PSYC_C2ARG("_color_red"))) return 3; + if (psyc_var_type(PSYC_C2ARG("_last"))) return 4; + if (psyc_var_type(PSYC_C2ARG("_lost_foo"))) return 5; + if (psyc_var_type(PSYC_C2ARG("_colorful"))) return 6; + if (psyc_var_type(PSYC_C2ARG("_foo"))) return 7; + if (psyc_var_type(PSYC_C2ARG("bar"))) return 8; + if (psyc_var_type(PSYC_C2ARG("______"))) return 9; + if (psyc_var_type(PSYC_C2ARG("_"))) return 10; + + puts("psyc_var_type passed all tests."); + return 0; // passed all tests +} From 1713e0857672659bfb246433e73225f549a6b3ec Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 31 Oct 2011 20:04:41 +0100 Subject: [PATCH 332/378] list test --- test/test_list.c | 208 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 test/test_list.c diff --git a/test/test_list.c b/test/test_list.c new file mode 100644 index 0000000..bbf6b4a --- /dev/null +++ b/test/test_list.c @@ -0,0 +1,208 @@ +#include +#include +#include + +#include +#include +#include +#include + +#define NELEMS 100 + +int main (int argc, char **argv) { + uint8_t verbose = argc > 1; + int i, k, n, ret; + + psycParseListState listState; + psycList list_text, list_bin; + psycString elems_text[NELEMS], elems_bin[NELEMS], elem; + char buf_text[NELEMS * 200], buf_bin[NELEMS * 200], *elems[NELEMS], **elems2 = NULL; + + struct timeval start, end; + + for (i=0; i 0); + } + gettimeofday(&end, NULL); + //printf("%ld ms\n", (end.tv_sec * 1000000 + end.tv_usec - start.tv_sec * 1000000 - start.tv_usec) / 1000); + printf("%ld us\n", (end.tv_sec * 1000000 + end.tv_usec - start.tv_sec * 1000000 - start.tv_usec)); +#endif + +#if 1 + printf("parsing binary list to elems[]\n"); + gettimeofday(&start, NULL); + for (n = 0; n < NELEMS; n++) { + psyc_parse_list_state_init(&listState); + psyc_parse_list_buffer_set(&listState, buf_bin, list_bin.length); + i = 0; + do { + ret = psyc_parse_list(&listState, &elem); + switch (ret) { + case PSYC_PARSE_LIST_END: + ret = 0; + case PSYC_PARSE_LIST_ELEM: + //if (verbose) printf("|%.*s\n", (int)elem.length, elem.ptr); + if (verbose) printf("|%d: %.*s... (%ld)\n", i, 10, elem.ptr, elem.length); + elems[i] = malloc(elem.length); + memcpy(elems[i++], elem.ptr, elem.length); + break; + default: + printf("# Error while parsing list: %i\n", ret); + ret = -1; + } + } while (ret > 0); + } + gettimeofday(&end, NULL); + //printf("%ld ms\n", (end.tv_sec * 1000000 + end.tv_usec - start.tv_sec * 1000000 - start.tv_usec)); + printf("%ld us\n", (end.tv_sec * 1000000 + end.tv_usec - start.tv_sec * 1000000 - start.tv_usec)); +#endif + +#if 1 + printf("parsing binary list to elems2[] with realloc\n"); + gettimeofday(&start, NULL); + for (n = 0; n < NELEMS; n++) { + psyc_parse_list_state_init(&listState); + psyc_parse_list_buffer_set(&listState, buf_bin, list_bin.length); + i = 0; + do { + ret = psyc_parse_list(&listState, &elem); + switch (ret) { + case PSYC_PARSE_LIST_END: + ret = 0; + case PSYC_PARSE_LIST_ELEM: + if (elems2) + elems2 = realloc(elems2, (i+1) * sizeof(char*)); + else + elems2 = malloc((i+1) * sizeof(char*)); + + elems2[i] = malloc(elem.length); + memcpy(elems2[i++], elem.ptr, elem.length); + break; + default: + printf("# Error while parsing list: %i\n", ret); + ret = -1; + } + } while (ret > 0); + } + gettimeofday(&end, NULL); + //printf("%ld ms\n", (end.tv_sec * 1000000 + end.tv_usec - start.tv_sec * 1000000 - start.tv_usec)); + printf("%ld us\n", (end.tv_sec * 1000000 + end.tv_usec - start.tv_sec * 1000000 - start.tv_usec)); +#endif + +#if 1 + printf("parsing binary list to elems2[] with malloc\n"); + gettimeofday(&start, NULL); + for (n = 0; n < NELEMS; n++) { + psyc_parse_list_state_init(&listState); + psyc_parse_list_buffer_set(&listState, buf_bin, list_bin.length); + i = 0; + do { + ret = psyc_parse_list(&listState, &elem); + switch (ret) { + case PSYC_PARSE_LIST_END: + ret = 0; + case PSYC_PARSE_LIST_ELEM: + /* + if (elems2) + elems2 = realloc(elems2, (i+1) * sizeof(char*)); + else + elems2 = malloc((i+1) * sizeof(char*)); + */ + elems2 = malloc(sizeof(char*)); + elems2[i] = malloc(elem.length); + memcpy(elems2[i], elem.ptr, elem.length); + break; + default: + printf("# Error while parsing list: %i\n", ret); + ret = -1; + } + } while (ret > 0); + } + gettimeofday(&end, NULL); + //printf("%ld ms\n", (end.tv_sec * 1000000 + end.tv_usec - start.tv_sec * 1000000 - start.tv_usec)); + printf("%ld us\n", (end.tv_sec * 1000000 + end.tv_usec - start.tv_sec * 1000000 - start.tv_usec)); +#endif + +#if 1 + printf("parsing binary list to elems2[] with double-parsing\n"); + gettimeofday(&start, NULL); + for (n = 0; n < NELEMS; n++) { + psyc_parse_list_state_init(&listState); + psyc_parse_list_buffer_set(&listState, buf_bin, list_bin.length); + i = 0; + k = 0; + + do { + ret = psyc_parse_list(&listState, &elem); + switch (ret) { + case PSYC_PARSE_LIST_END: + ret = 0; + case PSYC_PARSE_LIST_ELEM: + k++; + break; + default: + printf("# Error while parsing list: %i\n", ret); + ret = -1; + } + } while (ret > 0); + + elems2 = malloc(k * sizeof(char*)); + psyc_parse_list_buffer_set(&listState, buf_bin, list_bin.length); + + do { + ret = psyc_parse_list(&listState, &elem); + switch (ret) { + case PSYC_PARSE_LIST_END: + ret = 0; + case PSYC_PARSE_LIST_ELEM: + elems2[i] = malloc(elem.length); + memcpy(elems2[i++], elem.ptr, elem.length); + break; + default: + printf("# Error while parsing list: %i\n", ret); + ret = -1; + } + } while (ret > 0); + } + gettimeofday(&end, NULL); + //printf("%ld ms\n", (end.tv_sec * 1000000 + end.tv_usec - start.tv_sec * 1000000 - start.tv_usec)); + printf("%ld us\n", (end.tv_sec * 1000000 + end.tv_usec - start.tv_sec * 1000000 - start.tv_usec)); +#endif + + return 0; +} From baed20aed87889328f1a5de226969571fca2cca6 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 31 Oct 2011 20:26:47 +0100 Subject: [PATCH 333/378] refactoring - renamed types --- include/psyc.h | 26 ++++++------ include/psyc/packet.h | 70 ++++++++++++++++---------------- include/psyc/parse.h | 88 ++++++++++++++++++++--------------------- include/psyc/render.h | 8 ++-- include/psyc/text.h | 46 ++++++++++----------- include/psyc/uniform.h | 48 +++++++++++----------- include/psyc/variable.h | 10 ++--- pike/psyc.cmod | 28 ++++++------- src/match.c | 4 +- src/packet.c | 32 +++++++-------- src/parse.c | 16 ++++---- src/psyc_parser_cb.h | 28 ++++++------- src/render.c | 8 ++-- src/text.c | 4 +- src/uniform.c | 4 +- src/variable.c | 8 ++-- test/test_list.c | 10 ++--- test/test_parser.c | 6 +-- test/test_psyc.c | 30 +++++++------- test/test_psyc_speed.c | 4 +- test/test_render.c | 18 ++++----- test/test_text.c | 14 +++---- test/uniform_parse.c | 4 +- 23 files changed, 257 insertions(+), 257 deletions(-) diff --git a/include/psyc.h b/include/psyc.h index 58e4aa2..395f645 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -35,7 +35,7 @@ typedef enum PSYC_TRUE = 1, PSYC_NO = 0, PSYC_YES = 1, -} psycBool; +} PsycBool; /** * PSYC packet parts. @@ -49,7 +49,7 @@ typedef enum PSYC_PART_METHOD = 3, PSYC_PART_DATA = 4, PSYC_PART_END = 5, -} psycPart; +} PsycPart; /** * Different types that a variable can have. @@ -74,7 +74,7 @@ typedef enum PSYC_TYPE_PAGE, PSYC_TYPE_UNIFORM, PSYC_TYPE_TIME, -} psycType; +} PsycType; /** * List types. @@ -84,7 +84,7 @@ typedef enum { PSYC_LIST_TEXT = 1, PSYC_LIST_BINARY = 2, -} psycListType; +} PsycListType; /** * String struct. @@ -97,26 +97,26 @@ typedef struct size_t length; /// pointer to the data char *ptr; -} psycString; +} PsycString; typedef struct { - psycString key; + PsycString key; int value; -} psycMatchVar; +} PsycMatchVar; /** - * Shortcut for creating a psycString. + * Shortcut for creating a PsycString. * * @param str Pointer to the buffer. * @param len Length of that buffer. * - * @return An instance of the psycString struct. + * @return An instance of the PsycString struct. */ static inline -psycString psyc_string_new (char *str, size_t len) +PsycString psyc_string_new (char *str, size_t len) { - psycString s = {len, str}; + PsycString s = {len, str}; return s; } @@ -154,9 +154,9 @@ int psyc_matches (char *sho, size_t slen, * @return The value of the matched variable in the array. */ -int psyc_in_array (const psycMatchVar *array, size_t size, +int psyc_in_array (const PsycMatchVar *array, size_t size, const char *kw, size_t kwlen, - psycBool inherit, int8_t *matching); + PsycBool inherit, int8_t *matching); #include "psyc/variable.h" diff --git a/include/psyc/packet.h b/include/psyc/packet.h index 0080cc1..c0fddaa 100644 --- a/include/psyc/packet.h +++ b/include/psyc/packet.h @@ -30,7 +30,7 @@ typedef enum PSYC_MODIFIER_NO_LENGTH = 2, /// Routing modifier, which implies that it doesn't need length. PSYC_MODIFIER_ROUTING = 3, -} psycModifierFlag; +} PsycModifierFlag; /** List flags. */ typedef enum @@ -41,7 +41,7 @@ typedef enum PSYC_LIST_NEED_LENGTH = 1, /// List doesn't need length. PSYC_LIST_NO_LENGTH = 2, -} psycListFlag; +} PsycListFlag; /** Packet flags. */ typedef enum @@ -52,46 +52,46 @@ typedef enum PSYC_PACKET_NEED_LENGTH = 1, /// Packet doesn't need content length. PSYC_PACKET_NO_LENGTH = 2, -} psycPacketFlag; +} PsycPacketFlag; /** Structure for a modifier. */ typedef struct { char oper; - psycString name; - psycString value; - psycModifierFlag flag; -} psycModifier; + PsycString name; + PsycString value; + PsycModifierFlag flag; +} PsycModifier; /** Structure for an entity or routing header. */ typedef struct { size_t lines; - psycModifier *modifiers; -} psycHeader; + PsycModifier *modifiers; +} PsycHeader; /** Structure for a list. */ typedef struct { size_t num_elems; - psycString *elems; + PsycString *elems; size_t length; - psycListFlag flag; -} psycList; + PsycListFlag flag; +} PsycList; /** Intermediate struct for a PSYC packet */ typedef struct { - psycHeader routing; ///< Routing header. - psycHeader entity; ///< Entity header. - psycString method; ///< Contains the method. - psycString data; ///< Contains the data. - psycString content; ///< Contains the whole content. + PsycHeader routing; ///< Routing header. + PsycHeader entity; ///< Entity header. + PsycString method; ///< Contains the method. + PsycString data; ///< Contains the data. + PsycString content; ///< Contains the whole content. size_t routingLength; ///< Length of routing part. size_t contentLength; ///< Length of content part. size_t length; ///< Total length of packet. - psycPacketFlag flag; ///< Packet flag. -} psycPacket; + PsycPacketFlag flag; ///< Packet flag. +} PsycPacket; /** * Return the number of digits a number has in its base 10 representation. @@ -107,9 +107,9 @@ size_t psyc_num_length (size_t n) * Check if a modifier needs length. */ static inline -psycModifierFlag psyc_modifier_length_check (psycModifier *m) +PsycModifierFlag psyc_modifier_length_check (PsycModifier *m) { - psycModifierFlag flag; + PsycModifierFlag flag; if (m->value.length > PSYC_MODIFIER_SIZE_THRESHOLD) flag = PSYC_MODIFIER_NEED_LENGTH; @@ -123,12 +123,12 @@ psycModifierFlag psyc_modifier_length_check (psycModifier *m) /** Create new modifier */ static inline -psycModifier psyc_modifier_new (char oper, +PsycModifier psyc_modifier_new (char oper, char *name, size_t namelen, char *value, size_t valuelen, - psycModifierFlag flag){ + PsycModifierFlag flag){ - psycModifier m = {oper, {namelen, name}, {valuelen, value}, flag}; + PsycModifier m = {oper, {namelen, name}, {valuelen, value}, flag}; if (flag == PSYC_MODIFIER_CHECK_LENGTH) // find out if it needs a length m.flag = psyc_modifier_length_check(&m); @@ -140,45 +140,45 @@ psycModifier psyc_modifier_new (char oper, * \internal * Get the total length of a modifier when rendered. */ -size_t psyc_modifier_length (psycModifier *m); +size_t psyc_modifier_length (PsycModifier *m); /** * \internal * Check if a list needs length. */ -psycListFlag psyc_list_length_check (psycList *list); +PsycListFlag psyc_list_length_check (PsycList *list); /** * \internal * Get the total length of a list when rendered. */ -psycListFlag psyc_list_length (psycList *list); +PsycListFlag psyc_list_length (PsycList *list); /** * \internal * Check if a packet needs length. */ -psycPacketFlag psyc_packet_length_check (psycPacket *p); +PsycPacketFlag psyc_packet_length_check (PsycPacket *p); /** * Calculate and set the rendered length of packet parts and total packet length. */ -size_t psyc_packet_length_set (psycPacket *p); +size_t psyc_packet_length_set (PsycPacket *p); /** Create new list. */ -psycList psyc_list_new (psycString *elems, size_t num_elems, psycListFlag flag); +PsycList psyc_list_new (PsycString *elems, size_t num_elems, PsycListFlag flag); /** Create new packet. */ -psycPacket psyc_packet_new (psycModifier *routing, size_t routinglen, - psycModifier *entity, size_t entitylen, +PsycPacket psyc_packet_new (PsycModifier *routing, size_t routinglen, + PsycModifier *entity, size_t entitylen, char *method, size_t methodlen, char *data, size_t datalen, - psycPacketFlag flag); + PsycPacketFlag flag); /** Create new packet with raw content. */ -psycPacket psyc_packet_new_raw (psycModifier *routing, size_t routinglen, +PsycPacket psyc_packet_new_raw (PsycModifier *routing, size_t routinglen, char *content, size_t contentlen, - psycPacketFlag flag); + PsycPacketFlag flag); /** @} */ // end of packet group diff --git a/include/psyc/parse.h b/include/psyc/parse.h index cf86340..c1ba421 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -24,12 +24,12 @@ * To parse a packet you first have to initialize a state: * * @code - * psycParseState state; + * PsycParseState state; * psyc_parse_state_init(&state, flags); * @endcode * * With the flags parameter you can fine-tune what - * part of the packet should be parsed. @see psycParseFlag + * part of the packet should be parsed. @see PsycParseFlag * * Next, you have to tell the parser what it should parse. Assuming the variable * raw_data points to our packet and raw_len contains the length, you can pass @@ -46,7 +46,7 @@ * declared: * * @code - * psycString name, // Name of the variable or method + * PsycString name, // Name of the variable or method * value; // Value of the variable or body * char oper; // operator of the variable (if any) * @endcode @@ -105,7 +105,7 @@ * receive incomplete packets but still want to access the data. This code would * simply reject incomplete packets as error. A more detailed tutorial for * incomplete packets will follow. In the mean time, have look at the return - * codes in psycParseRC and their explanations. @see psycParseRC + * codes in PsycParseRC and their explanations. @see PsycParseRC */ /** @{ */ // begin of parser group @@ -122,7 +122,7 @@ typedef enum { /// Parse only the content. /// Parsing starts at the content and the content must be complete. PSYC_PARSE_START_AT_CONTENT = 2, -} psycParseFlag; +} PsycParseFlag; /** * The return value definitions for the packet parsing function. @@ -188,7 +188,7 @@ typedef enum { PSYC_PARSE_CONTENT = 10, /// Finished parsing packet. PSYC_PARSE_COMPLETE = 11, -} psycParseRC; +} PsycParseRC; /** * The return value definitions for the list parsing function. @@ -205,7 +205,7 @@ typedef enum { PSYC_PARSE_LIST_END = 2, /// Binary list is incomplete. PSYC_PARSE_LIST_INCOMPLETE = 3, -} psycParseListRC; +} PsycParseListRC; /** * Struct for keeping parser state. @@ -213,18 +213,18 @@ typedef enum { typedef struct { size_t cursor; ///< Current position in buffer. size_t startc; ///< Position where the parsing would be resumed. - psycString buffer; ///< Buffer with data to be parsed. - uint8_t flags; ///< Flags for the parser, see psycParseFlag. - psycPart part; ///< Part of the packet being parsed currently. + PsycString buffer; ///< Buffer with data to be parsed. + uint8_t flags; ///< Flags for the parser, see PsycParseFlag. + PsycPart part; ///< Part of the packet being parsed currently. size_t routingLength; ///< Length of routing part parsed so far. size_t contentParsed; ///< Number of bytes parsed from the content so far. size_t contentLength; ///< Expected length of the content. - psycBool contentLengthFound; ///< Is there a length given for this packet? + PsycBool 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. - psycBool valueLengthFound; ///< Is there a length given for this modifier? -} psycParseState; + PsycBool valueLengthFound; ///< Is there a length given for this modifier? +} PsycParseState; /** * Struct for keeping list parser state. @@ -232,24 +232,24 @@ typedef struct { typedef struct { size_t cursor; ///< Current position in buffer. size_t startc; ///< Line start position. - psycString buffer; ///< Buffer with data to be parsed. - psycListType type; ///< List type. + PsycString buffer; ///< Buffer with data to be parsed. + PsycListType type; ///< List type. size_t elemParsed; ///< Number of bytes parsed from the elem so far. size_t elemLength; ///< Expected length of the elem. -} psycParseListState; +} PsycParseListState; /** * Initializes the state struct. * * @param state Pointer to the state struct that should be initialized. - * @param flags Flags to be set for the parser, see psycParseFlag. - * @see psycParseFlag + * @param flags Flags to be set for the parser, see PsycParseFlag. + * @see PsycParseFlag */ static inline -void psyc_parse_state_init (psycParseState *state, uint8_t flags) +void psyc_parse_state_init (PsycParseState *state, uint8_t flags) { - memset(state, 0, sizeof(psycParseState)); + memset(state, 0, sizeof(PsycParseState)); state->flags = flags; if (flags & PSYC_PARSE_START_AT_CONTENT) @@ -265,12 +265,12 @@ void psyc_parse_state_init (psycParseState *state, uint8_t flags) * @param state Pointer to the initialized state of the parser * @param buffer pointer to the data that should be parsed * @param length length of the data in bytes - * @see psycString + * @see PsycString */ static inline -void psyc_parse_buffer_set (psycParseState *state, char *buffer, size_t length) +void psyc_parse_buffer_set (PsycParseState *state, char *buffer, size_t length) { - state->buffer = (psycString) {length, buffer}; + state->buffer = (PsycString) {length, buffer}; state->cursor = 0; if (state->flags & PSYC_PARSE_START_AT_CONTENT) { @@ -285,65 +285,65 @@ void psyc_parse_buffer_set (psycParseState *state, char *buffer, size_t length) * @param state Pointer to the list state struct that should be initialized. */ static inline -void psyc_parse_list_state_init (psycParseListState *state) +void psyc_parse_list_state_init (PsycParseListState *state) { - memset(state, 0, sizeof(psycParseListState)); + memset(state, 0, sizeof(PsycParseListState)); } /** * Sets a new buffer in the list parser state struct with data to be parsed. */ static inline -void psyc_parse_list_buffer_set (psycParseListState *state, char *buffer, size_t length) +void psyc_parse_list_buffer_set (PsycParseListState *state, char *buffer, size_t length) { - state->buffer = (psycString) {length, buffer}; + state->buffer = (PsycString) {length, buffer}; state->cursor = 0; } static inline -size_t psyc_parse_content_length (psycParseState *state) +size_t psyc_parse_content_length (PsycParseState *state) { return state->contentLength; } static inline -psycBool psyc_parse_content_length_found (psycParseState *state) +PsycBool psyc_parse_content_length_found (PsycParseState *state) { return state->contentLengthFound; } static inline -size_t psyc_parse_value_length (psycParseState *state) +size_t psyc_parse_value_length (PsycParseState *state) { return state->valueLength; } static inline -psycBool psyc_parse_value_length_found (psycParseState *state) +PsycBool psyc_parse_value_length_found (PsycParseState *state) { return state->valueLengthFound; } static inline -size_t psyc_parse_cursor (psycParseState *state) +size_t psyc_parse_cursor (PsycParseState *state) { return state->cursor; } static inline -size_t psyc_parse_buffer_length (psycParseState *state) +size_t psyc_parse_buffer_length (PsycParseState *state) { return state->buffer.length; } static inline -size_t psyc_parse_remaining_length (psycParseState *state) +size_t psyc_parse_remaining_length (PsycParseState *state) { return state->buffer.length - state->cursor; } static inline -const char * psyc_parse_remaining_buffer (psycParseState *state) +const char * psyc_parse_remaining_buffer (PsycParseState *state) { return state->buffer.ptr + state->cursor; } @@ -353,11 +353,11 @@ const char * psyc_parse_remaining_buffer (psycParseState *state) * * This function parses a full or partial PSYC packet while keeping parsing * state in a state variable that you have to pass in every time, and returns - * whenever a modifier or the body is found. See psycParseRC for the possible + * whenever a modifier or the body is found. See PsycParseRC for the possible * return codes. When it returns oper, name & value will point to the respective * parts of the buffer, no memory allocation is done. * - * @param state An initialized psycParseState. + * @param state An initialized PsycParseState. * @param oper In case of a modifier it will be set to the operator. * @param name In case of a modifier it will point to the name, * in case of the body it will point to the method. @@ -367,8 +367,8 @@ const char * psyc_parse_remaining_buffer (psycParseState *state) #ifdef __INLINE_PSYC_PARSE static inline #endif -psycParseRC psyc_parse (psycParseState *state, char *oper, - psycString *name, psycString *value); +PsycParseRC psyc_parse (PsycParseState *state, char *oper, + PsycString *name, PsycString *value); /** * List parser. @@ -378,16 +378,16 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, * every time. When it returns elem will point to the next element in value, no * memory allocation is done. * - * @param state An initialized psycParseListState. + * @param state An initialized PsycParseListState. * @param elem It will point to the next element in the list. */ #ifdef __INLINE_PSYC_PARSE static inline #endif -psycParseListRC psyc_parse_list (psycParseListState *state, psycString *elem); +PsycParseListRC psyc_parse_list (PsycParseListState *state, PsycString *elem); static inline -psycBool psyc_parse_number (const char *value, size_t len, ssize_t *n) +PsycBool psyc_parse_number (const char *value, size_t len, ssize_t *n) { size_t c = 0; uint8_t neg = 0; @@ -412,13 +412,13 @@ psycBool psyc_parse_number (const char *value, size_t len, ssize_t *n) } static inline -psycBool psyc_parse_time (const char *value, size_t len, time_t *t) +PsycBool psyc_parse_time (const char *value, size_t len, time_t *t) { return psyc_parse_number(value, len, t); } static inline -psycBool psyc_parse_date (const char *value, size_t len, time_t *t) +PsycBool psyc_parse_date (const char *value, size_t len, time_t *t) { if (psyc_parse_number(value, len, t)) { *t += PSYC_EPOCH; diff --git a/include/psyc/render.h b/include/psyc/render.h index e4cd8f2..5b64804 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -29,7 +29,7 @@ typedef enum PSYC_RENDER_ERROR = -1, /// Packet is rendered successfully in the buffer. PSYC_RENDER_SUCCESS = 0, -} psycRenderRC; +} PsycRenderRC; /** * Return codes for psyc_render_list. @@ -40,7 +40,7 @@ typedef enum PSYC_RENDER_LIST_ERROR = -1, /// List is rendered successfully in the buffer. PSYC_RENDER_LIST_SUCCESS = 0, -} psycRenderListRC; +} PsycRenderListRC; /** * Render a PSYC packet into a buffer. @@ -59,7 +59,7 @@ typedef enum #ifdef __INLINE_PSYC_RENDER static inline #endif -psycRenderRC psyc_render (psycPacket *packet, char *buffer, size_t buflen); +PsycRenderRC psyc_render (PsycPacket *packet, char *buffer, size_t buflen); /** * Render a PSYC list into a buffer. @@ -67,7 +67,7 @@ psycRenderRC psyc_render (psycPacket *packet, char *buffer, size_t buflen); #ifdef __INLINE_PSYC_RENDER static inline #endif -psycRenderListRC psyc_render_list (psycList *list, char *buffer, size_t buflen); +PsycRenderListRC psyc_render_list (PsycList *list, char *buffer, size_t buflen); /** @} */ // end of render group diff --git a/include/psyc/text.h b/include/psyc/text.h index 55f35e5..f3e1bc8 100644 --- a/include/psyc/text.h +++ b/include/psyc/text.h @@ -28,10 +28,10 @@ typedef enum /// Text template parsing & rendering is incomplete, because the buffer was too small. /// Another call is required to this function after setting a new buffer. PSYC_TEXT_INCOMPLETE = 1, -} psycTextRC; +} PsycTextRC; /** - * Return values for psycTextCB. + * Return values for PsycTextCB. */ typedef enum { @@ -39,7 +39,7 @@ typedef enum PSYC_TEXT_VALUE_NOT_FOUND = -1, /// Value found, substitute contents of the value variable. PSYC_TEXT_VALUE_FOUND = 0, -} psycTextValueRC; +} PsycTextValueRC; /** * Struct for keeping PSYC text parser state. @@ -48,11 +48,11 @@ typedef struct { size_t cursor; ///< current position in the template size_t written; ///< number of bytes written to buffer - psycString tmpl; ///< input buffer with text template to parse - psycString buffer; ///< output buffer for rendered text - psycString open; - psycString close; -} psycTextState; + PsycString tmpl; ///< input buffer with text template to parse + PsycString buffer; ///< output buffer for rendered text + PsycString open; + PsycString close; +} PsycTextState; /** * Callback for psyc_text() that produces a value for a match. @@ -64,7 +64,7 @@ typedef struct * PSYC_TEXT_VALUE_NOT_FOUND if no match found in which case psyc_text * leaves the original template text as is. */ -typedef psycTextValueRC (*psycTextCB)(const char *name, size_t len, psycString *value, void *extra); +typedef PsycTextValueRC (*PsycTextCB)(const char *name, size_t len, PsycString *value, void *extra); /** * Initializes the PSYC text state struct. @@ -76,16 +76,16 @@ typedef psycTextValueRC (*psycTextCB)(const char *name, size_t len, psycString * * @param buflen Length of output buffer. */ static inline -void psyc_text_state_init (psycTextState *state, +void psyc_text_state_init (PsycTextState *state, char *tmpl, size_t tmplen, char *buffer, size_t buflen) { state->cursor = 0; state->written = 0; - state->tmpl = (psycString) {tmplen, tmpl}; - state->buffer = (psycString) {buflen, buffer}; - state->open = (psycString) {1, "["}; - state->close = (psycString) {1, "]"}; + state->tmpl = (PsycString) {tmplen, tmpl}; + state->buffer = (PsycString) {buflen, buffer}; + state->open = (PsycString) {1, "["}; + state->close = (PsycString) {1, "]"}; } /** @@ -102,7 +102,7 @@ void psyc_text_state_init (psycTextState *state, * @param closelen Length of closing brace. */ static inline -void psyc_text_state_init_custom (psycTextState *state, +void psyc_text_state_init_custom (PsycTextState *state, char *tmpl, size_t tmplen, char *buffer, size_t buflen, char *open, size_t openlen, @@ -110,25 +110,25 @@ void psyc_text_state_init_custom (psycTextState *state, { state->cursor = 0; state->written = 0; - state->tmpl = (psycString) {tmplen, tmpl}; - state->buffer = (psycString) {buflen, buffer}; - state->open = (psycString) {openlen, open}; - state->close = (psycString) {closelen, close}; + state->tmpl = (PsycString) {tmplen, tmpl}; + state->buffer = (PsycString) {buflen, buffer}; + state->open = (PsycString) {openlen, open}; + state->close = (PsycString) {closelen, close}; } /** * Sets a new output buffer in the PSYC text state struct. */ static inline -void psyc_text_buffer_set (psycTextState *state, +void psyc_text_buffer_set (PsycTextState *state, char *buffer, size_t length) { - state->buffer = (psycString){length, buffer}; + state->buffer = (PsycString){length, buffer}; state->written = 0; } static inline -size_t psyc_text_bytes_written (psycTextState *state) +size_t psyc_text_bytes_written (PsycTextState *state) { return state->written; } @@ -148,7 +148,7 @@ size_t psyc_text_bytes_written (psycTextState *state) * * @see http://about.psyc.eu/psyctext **/ -psycTextRC psyc_text (psycTextState *state, psycTextCB getValue, void *extra); +PsycTextRC psyc_text (PsycTextState *state, PsycTextCB getValue, void *extra); /** @} */ // end of text group diff --git a/include/psyc/uniform.h b/include/psyc/uniform.h index 7bc86ba..cd0abdb 100644 --- a/include/psyc/uniform.h +++ b/include/psyc/uniform.h @@ -11,31 +11,31 @@ typedef enum { PSYC_SCHEME_IRC = 1, PSYC_SCHEME_XMPP = 2, PSYC_SCHEME_SIP = 3, -} psycScheme; +} PsycScheme; typedef struct { // essential parts uint8_t valid; - psycScheme type; - psycString scheme; - psycString user; - psycString pass; - psycString host; - psycString port; - psycString transport; - psycString resource; - psycString query; - psycString channel; + PsycScheme type; + PsycString scheme; + PsycString user; + PsycString pass; + PsycString host; + PsycString port; + PsycString transport; + PsycString resource; + PsycString query; + PsycString channel; // convenient snippets of the URL - psycString full; // the URL as such - psycString body; // the URL without scheme and '//' - psycString user_host; // mailto and xmpp style - psycString host_port; // just host:port (and transport) - psycString root; // root UNI of peer/server - psycString slashes; // the // if the protocol has them - psycString nick; // whatever works as a nickname -} psycUniform; + PsycString full; // the URL as such + PsycString body; // the URL without scheme and '//' + PsycString user_host; // mailto and xmpp style + PsycString host_port; // just host:port (and transport) + PsycString root; // root UNI of peer/server + PsycString slashes; // the // if the protocol has them + PsycString nick; // whatever works as a nickname +} PsycUniform; typedef enum { PSYC_UNIFORM_SCHEME = 0, @@ -48,7 +48,7 @@ typedef enum { PSYC_UNIFORM_RESOURCE, PSYC_UNIFORM_QUERY, PSYC_UNIFORM_CHANNEL, -} psycUniformPart; +} PsycUniformPart; typedef enum { PSYC_PARSE_UNIFORM_INVALID_SLASHES = -7, @@ -58,22 +58,22 @@ typedef enum { PSYC_PARSE_UNIFORM_INVALID_PORT = -3, PSYC_PARSE_UNIFORM_INVALID_HOST = -2, PSYC_PARSE_UNIFORM_INVALID_SCHEME = -1, -} psycParseUniformRC; +} PsycParseUniformRC; typedef enum { PSYC_TRANSPORT_TCP = 'c', PSYC_TRANSPORT_UDP = 'd', PSYC_TRANSPORT_TLS = 's', PSYC_TRANSPORT_GNUNET = 'g', -} psycTransport; +} PsycTransport; typedef enum { PSYC_ENTITY_PERSON = '~', PSYC_ENTITY_PLACE = '@', PSYC_ENTITY_SERVICE = '$', -} psycEntityType; +} PsycEntityType; -int psyc_uniform_parse (psycUniform *uni, char *str, size_t length); +int psyc_uniform_parse (PsycUniform *uni, char *str, size_t length); #define PSYC_UNIFORM_H #endif diff --git a/include/psyc/variable.h b/include/psyc/variable.h index c4671f6..1e42f7e 100644 --- a/include/psyc/variable.h +++ b/include/psyc/variable.h @@ -5,10 +5,10 @@ */ /// Routing variables in alphabetical order. -extern const psycString psyc_routing_vars[]; +extern const PsycString psyc_routing_vars[]; // Variable types in alphabetical order. -extern const psycMatchVar psyc_var_types[]; +extern const PsycMatchVar psyc_var_types[]; extern const size_t psyc_routing_vars_num; extern const size_t psyc_var_types_num; @@ -16,18 +16,18 @@ extern const size_t psyc_var_types_num; /** * Is this a routing variable name? */ -psycBool psyc_var_is_routing (const char *name, size_t len); +PsycBool psyc_var_is_routing (const char *name, size_t len); /** * Get the type of variable name. */ -psycType psyc_var_type (const char *name, size_t len); +PsycType psyc_var_type (const char *name, size_t len); /** * Is this a list variable name? */ static inline -psycBool psyc_var_is_list (const char *name, size_t len) +PsycBool psyc_var_is_list (const char *name, size_t len) { return len < 5 || memcmp(name, "_list", 5) != 0 || (len > 5 && name[5] != '_') ? PSYC_FALSE : PSYC_TRUE; diff --git a/pike/psyc.cmod b/pike/psyc.cmod index 2f31b7d..3aca2dd 100644 --- a/pike/psyc.cmod +++ b/pike/psyc.cmod @@ -32,7 +32,7 @@ */ // psyctext helper -psycTextValueRC lookup_value_mapping(const char *name, size_t len, psycString *value, void *extra) +PsycTextValueRC lookup_value_mapping(const char *name, size_t len, PsycString *value, void *extra) { //printf("lookup_value_mapping called for %.*s\n", (int) len, name); struct pike_string *key = make_shared_binary_string(name, len); @@ -68,8 +68,8 @@ psycTextValueRC lookup_value_mapping(const char *name, size_t len, psycString *v *! rendered string */ PIKEFUN string psyc_text(string template, mapping vars) { - psycTextState state; - psycTextRC ret; + PsycTextState state; + PsycTextRC ret; size_t len = 0; // FIXME: char buffer[512]; @@ -115,8 +115,8 @@ PIKEFUN int is_routingvar(string name) { *! serialized packet as a string */ PIKEFUN string render(mapping rvars, mapping evars, string method, string|void body) { - psycPacket packet; - psycHeader rheaders, eheaders; + PsycPacket packet; + PsycHeader rheaders, eheaders; struct keypair *k; // for mappings INT32 e; @@ -125,7 +125,7 @@ PIKEFUN string render(mapping rvars, mapping evars, string method, string|void b // fill headers rheaders.lines = 0; - rheaders.modifiers = malloc(sizeof(psycModifier) * rvars->data->size); + rheaders.modifiers = malloc(sizeof(PsycModifier) * rvars->data->size); NEW_MAPPING_LOOP(rvars->data) { if (k->ind.type == PIKE_T_STRING) { switch(k->val.type) { @@ -147,7 +147,7 @@ PIKEFUN string render(mapping rvars, mapping evars, string method, string|void b } eheaders.lines = 0; - eheaders.modifiers = malloc(sizeof(psycModifier) * evars->data->size); + eheaders.modifiers = malloc(sizeof(PsycModifier) * evars->data->size); NEW_MAPPING_LOOP(evars->data) { if (k->ind.type == PIKE_T_STRING) { char *key; @@ -183,14 +183,14 @@ PIKEFUN string render(mapping rvars, mapping evars, string method, string|void b */ case PIKE_T_ARRAY: do { - psycString *elems = xcalloc(k->val.u.array->size, sizeof(psycString)); - psycList list; + PsycString *elems = xcalloc(k->val.u.array->size, sizeof(PsycString)); + PsycList list; // FIXME: check for out of memory for(e = 0; e < k->val.u.array->size; e++) { struct svalue item = k->val.u.array->item[e]; switch(item.type) { case PIKE_T_STRING: - elems[e] = (psycString) { item.u.string->len, (char *) STR0(item.u.string) }; + elems[e] = (PsycString) { item.u.string->len, (char *) STR0(item.u.string) }; break; default: // FIXME: xfree(elems) ? @@ -245,7 +245,7 @@ PIKEFUN string render(mapping rvars, mapping evars, string method, string|void b } PIKECLASS Parser { - CVAR psycParseState parser; + CVAR PsycParseState parser; CVAR struct pike_string *buffer; CVAR int handle_packet; CVAR int handle_error; @@ -283,7 +283,7 @@ PIKECLASS Parser { PIKEFUN void feed(string data) { char oper; - psycString name, value; + PsycString name, value; int ret; int err; @@ -379,8 +379,8 @@ PIKECLASS Parser { if (value.length > 0) { int retl; int count = 0; - psycParseListState listState; - psycString elem = (psycString) {0, 0}; + PsycParseListState listState; + PsycString elem = (PsycString) {0, 0}; psyc_parse_list_state_init(&listState); psyc_parse_list_buffer_set(&listState, PSYC_S2ARG(value)); diff --git a/src/match.c b/src/match.c index dd68d77..cc06dc6 100644 --- a/src/match.c +++ b/src/match.c @@ -114,9 +114,9 @@ failed: * * @return The value of the matched variable in the array. */ -int psyc_in_array (const psycMatchVar *array, size_t size, +int psyc_in_array (const PsycMatchVar *array, size_t size, const char *kw, size_t kwlen, - psycBool inherit, int8_t *matching) + PsycBool inherit, int8_t *matching) { size_t cursor = 1; uint8_t i, m = 0; diff --git a/src/packet.c b/src/packet.c index a06bc72..dc7f10a 100644 --- a/src/packet.c +++ b/src/packet.c @@ -3,14 +3,14 @@ #include inline -psycListFlag psyc_list_length_check (psycList *list) +PsycListFlag psyc_list_length_check (PsycList *list) { - psycListFlag flag = PSYC_LIST_NO_LENGTH; + PsycListFlag flag = PSYC_LIST_NO_LENGTH; size_t i, length = 0; for (i = 0; i < list->num_elems; i++) { - psycString *elem = &list->elems[i]; + PsycString *elem = &list->elems[i]; length += 1 + elem->length; // |elem if (length > PSYC_MODIFIER_SIZE_THRESHOLD || memchr(elem->ptr, (int)'|', elem->length) || @@ -25,7 +25,7 @@ psycListFlag psyc_list_length_check (psycList *list) } inline -psycListFlag psyc_list_length (psycList *list) +PsycListFlag psyc_list_length (PsycList *list) { size_t i, length = 0; @@ -48,9 +48,9 @@ psycListFlag psyc_list_length (psycList *list) } inline -psycList psyc_list_new (psycString *elems, size_t num_elems, psycListFlag flag) +PsycList psyc_list_new (PsycString *elems, size_t num_elems, PsycListFlag flag) { - psycList list = {num_elems, elems, 0, flag}; + PsycList list = {num_elems, elems, 0, flag}; if (flag == PSYC_LIST_CHECK_LENGTH) // check if list elements need length list.flag = psyc_list_length_check(&list); @@ -61,7 +61,7 @@ psycList psyc_list_new (psycString *elems, size_t num_elems, psycListFlag flag) inline -size_t psyc_modifier_length (psycModifier *m) +size_t psyc_modifier_length (PsycModifier *m) { size_t length = 1 + // oper m->name.length + 1 + // name\t @@ -74,7 +74,7 @@ size_t psyc_modifier_length (psycModifier *m) } inline -psycPacketFlag psyc_packet_length_check (psycPacket *p) +PsycPacketFlag psyc_packet_length_check (PsycPacket *p) { if (p->data.length == 1 && p->data.ptr[0] == C_GLYPH_PACKET_DELIMITER) return PSYC_PACKET_NEED_LENGTH; @@ -96,7 +96,7 @@ psycPacketFlag psyc_packet_length_check (psycPacket *p) } inline -size_t psyc_packet_length_set (psycPacket *p) +size_t psyc_packet_length_set (PsycPacket *p) { size_t i; p->routingLength = 0; @@ -134,13 +134,13 @@ size_t psyc_packet_length_set (psycPacket *p) } inline -psycPacket psyc_packet_new (psycModifier *routing, size_t routinglen, - psycModifier *entity, size_t entitylen, +PsycPacket psyc_packet_new (PsycModifier *routing, size_t routinglen, + PsycModifier *entity, size_t entitylen, char *method, size_t methodlen, char *data, size_t datalen, - psycPacketFlag flag) + PsycPacketFlag flag) { - psycPacket p = {{routinglen, routing}, {entitylen, entity}, + PsycPacket p = {{routinglen, routing}, {entitylen, entity}, {methodlen, method}, {datalen, data}, {0,0}, 0, 0, flag}; if (flag == PSYC_PACKET_CHECK_LENGTH) // find out if it needs a length @@ -151,11 +151,11 @@ psycPacket psyc_packet_new (psycModifier *routing, size_t routinglen, } inline -psycPacket psyc_packet_new_raw (psycModifier *routing, size_t routinglen, +PsycPacket psyc_packet_new_raw (PsycModifier *routing, size_t routinglen, char *content, size_t contentlen, - psycPacketFlag flag) + PsycPacketFlag flag) { - psycPacket p = {{routinglen, routing}, {0,0}, {0,0}, {0,0}, + PsycPacket p = {{routinglen, routing}, {0,0}, {0,0}, {0,0}, {contentlen, content}, 0, 0, flag}; if (flag == PSYC_PACKET_CHECK_LENGTH) // find out if it needs a length diff --git a/src/parse.c b/src/parse.c index 6fdd807..8c8e763 100644 --- a/src/parse.c +++ b/src/parse.c @@ -29,7 +29,7 @@ typedef enum { * @return PARSE_ERROR or PARSE_SUCCESS */ static inline -parseRC psyc_parse_keyword (psycParseState *state, psycString *name) +parseRC psyc_parse_keyword (PsycParseState *state, PsycString *name) { name->ptr = state->buffer.ptr + state->cursor; name->length = 0; @@ -54,7 +54,7 @@ parseRC psyc_parse_keyword (psycParseState *state, psycString *name) * @return PARSE_COMPLETE or PARSE_INCOMPLETE */ static inline -parseRC psyc_parse_binary_value (psycParseState *state, psycString *value, +parseRC psyc_parse_binary_value (PsycParseState *state, PsycString *value, size_t *length, size_t *parsed) { size_t remaining = *length - *parsed; @@ -81,8 +81,8 @@ parseRC psyc_parse_binary_value (psycParseState *state, psycString *value, * @return PARSE_ERROR or PARSE_SUCCESS */ static inline -parseRC psyc_parse_modifier (psycParseState *state, char *oper, - psycString *name, psycString *value) +parseRC psyc_parse_modifier (PsycParseState *state, char *oper, + PsycString *name, PsycString *value) { *oper = *(state->buffer.ptr + state->cursor); ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); @@ -153,8 +153,8 @@ parseRC psyc_parse_modifier (psycParseState *state, char *oper, #ifdef __INLINE_PSYC_PARSE static inline #endif -psycParseRC psyc_parse (psycParseState *state, char *oper, - psycString *name, psycString *value) +PsycParseRC psyc_parse (PsycParseState *state, char *oper, + PsycString *name, PsycString *value) { #ifdef DEBUG if (state->flags & PSYC_PARSE_ROUTING_ONLY && @@ -437,7 +437,7 @@ psycParseRC psyc_parse (psycParseState *state, char *oper, #ifdef __INLINE_PSYC_PARSE static inline #endif -psycParseListRC psyc_parse_list (psycParseListState *state, psycString *elem) +PsycParseListRC psyc_parse_list (PsycParseListState *state, PsycString *elem) { if (state->cursor >= state->buffer.length) return PSYC_PARSE_LIST_INCOMPLETE; @@ -504,7 +504,7 @@ psycParseListRC psyc_parse_list (psycParseListState *state, psycString *elem) // Start or resume parsing the binary data if (state->elemParsed < state->elemLength) { - if (psyc_parse_binary_value((psycParseState*)state, elem, + if (psyc_parse_binary_value((PsycParseState*)state, elem, &(state->elemLength), &(state->elemParsed)) == PARSE_INCOMPLETE) return PSYC_PARSE_LIST_INCOMPLETE; diff --git a/src/psyc_parser_cb.h b/src/psyc_parser_cb.h index ff58491..427a7bb 100644 --- a/src/psyc_parser_cb.h +++ b/src/psyc_parser_cb.h @@ -1,19 +1,19 @@ #include -struct psycParser; +struct PsycParser; /** @brief initialize a pstate struct * * @param pstate pointer to an allocated - * psycParser struct. + * PsycParser struct. */ -void psyc_parse_state_init(struct psycParser* pstate); +void psyc_parse_state_init(struct PsycParser* pstate); /** @brief parses a packet * * This function parses rawdata - * and uses the callbacks in psycParser + * and uses the callbacks in PsycParser * to communicate with the caller. * * First the header will be parsed, @@ -43,10 +43,10 @@ void psyc_parse_state_init(struct psycParser* pstate); * */ void psyc_parse(const uint8_t* data, unsigned int length, - struct psycParser* pstate); + struct PsycParser* pstate); /** @brief FlagMod */ -enum psycOperator +enum PsycOperator { // modifier operators ASSIGN = 0x02, @@ -56,7 +56,7 @@ enum psycOperator QUERY = 0x20, }; -struct psycParser +struct PsycParser { /** @brief Callback for the states * @@ -76,10 +76,10 @@ struct psycParser * @param modifers modifer of the variable (see Modifer) * @param inEntity wether this variable is an entity * variable(true) or a routing variable(false) */ - void (*stateCallback)(struct psycParser* pstate, + void (*stateCallback)(struct PsycParser* pstate, const uint8_t *name, const unsigned int nlength, const uint8_t *value, const unsigned int vlength, - enum psycOperator oper, char inEntity); + enum PsycOperator oper, char inEntity); /** @brief gets called after the routing-header was parsed * @@ -88,7 +88,7 @@ struct psycParser * when finished, * if not 0, parser will stop parsing and * calls contentCallback */ - char (*routingCallback)(struct psycParser* pstate); + char (*routingCallback)(struct PsycParser* pstate); /** @brief Body callback, gets called when the body was parsed * @@ -102,7 +102,7 @@ struct psycParser * containing the data section * @param content not null terminated c-string * @param clength length of the content string */ - void (*bodyCallback)(struct psycParser* pstate, + void (*bodyCallback)(struct PsycParser* pstate, const uint8_t* method, unsigned int mlength, const uint8_t* data, unsigned int dlength, const uint8_t* content, unsigned int clength); @@ -123,7 +123,7 @@ struct psycParser * * Any previous state or body callbacks become * invalid and have to be purged.*/ - void (*errorCallback)(struct psycParser* pstate, + void (*errorCallback)(struct PsycParser* pstate, const uint8_t *method, unsigned int mlength); /** @brief error state callback @@ -132,10 +132,10 @@ struct psycParser * The callback will be called once for each * state variable in the error report packet */ - void (*errorStateCallback)(struct psycParser* pstate, + void (*errorStateCallback)(struct PsycParser* pstate, const uint8_t *name, const unsigned int nlength, const uint8_t *value, const unsigned int vlength, - enum psycOperator oper); + enum PsycOperator oper); /******************************************* diff --git a/src/render.c b/src/render.c index f66a2a8..e310419 100644 --- a/src/render.c +++ b/src/render.c @@ -5,10 +5,10 @@ #ifdef __INLINE_PSYC_RENDER static inline #endif -psycRenderListRC psyc_render_list (psycList *list, char *buffer, size_t buflen) +PsycRenderListRC psyc_render_list (PsycList *list, char *buffer, size_t buflen) { size_t i, cur = 0; - psycString *elem; + PsycString *elem; if (list->length > buflen) // return error if list doesn't fit in buffer return PSYC_RENDER_LIST_ERROR; @@ -43,7 +43,7 @@ psycRenderListRC psyc_render_list (psycList *list, char *buffer, size_t buflen) } static inline -size_t psyc_render_modifier (psycModifier *mod, char *buffer) +size_t psyc_render_modifier (PsycModifier *mod, char *buffer) { size_t cur = 0; @@ -70,7 +70,7 @@ size_t psyc_render_modifier (psycModifier *mod, char *buffer) #ifdef __INLINE_PSYC_RENDER static inline #endif -psycRenderRC psyc_render (psycPacket *packet, char *buffer, size_t buflen) +PsycRenderRC psyc_render (PsycPacket *packet, char *buffer, size_t buflen) { size_t i, cur = 0, len; diff --git a/src/text.c b/src/text.c index 944dd41..943daff 100644 --- a/src/text.c +++ b/src/text.c @@ -1,11 +1,11 @@ #include "lib.h" #include -psycTextRC psyc_text (psycTextState *state, psycTextCB getValue, void* extra) +PsycTextRC psyc_text (PsycTextState *state, PsycTextCB getValue, void* extra) { const char *start = state->tmpl.ptr, *end; // start & end of variable name const char *prev = state->tmpl.ptr + state->cursor; - psycString value; + PsycString value; int ret; size_t len; uint8_t no_subst = (state->cursor == 0); // whether we can return NO_SUBST diff --git a/src/uniform.c b/src/uniform.c index efc36bb..6dab7b7 100644 --- a/src/uniform.c +++ b/src/uniform.c @@ -3,10 +3,10 @@ #include "psyc/uniform.h" #include "psyc/parse.h" -int psyc_uniform_parse (psycUniform *uni, char *str, size_t length) +int psyc_uniform_parse (PsycUniform *uni, char *str, size_t length) { char c; - psycString *p; + PsycString *p; size_t pos = 0, part = PSYC_UNIFORM_SCHEME; uni->valid = 0; diff --git a/src/variable.c b/src/variable.c index e13614b..a55b37c 100644 --- a/src/variable.c +++ b/src/variable.c @@ -3,7 +3,7 @@ /// Routing variables in alphabetical order. -const psycString psyc_routing_vars[] = +const PsycString psyc_routing_vars[] = { PSYC_C2STR("_amount_fragments"), PSYC_C2STR("_context"), @@ -27,7 +27,7 @@ const psycString psyc_routing_vars[] = }; // Variable types in alphabetical order. -const psycMatchVar psyc_var_types[] = +const PsycMatchVar psyc_var_types[] = { {PSYC_C2STR("_amount"), PSYC_TYPE_AMOUNT}, {PSYC_C2STR("_color"), PSYC_TYPE_COLOR}, @@ -50,7 +50,7 @@ const size_t psyc_var_types_num = PSYC_NUM_ELEM(psyc_var_types); * Get the type of variable name. */ inline -psycBool psyc_var_is_routing (const char *name, size_t len) +PsycBool psyc_var_is_routing (const char *name, size_t len) { size_t cursor = 1; uint8_t i, m = 0; @@ -91,7 +91,7 @@ psycBool psyc_var_is_routing (const char *name, size_t len) * Get the type of variable name. */ inline -psycType psyc_var_type (const char *name, size_t len) +PsycType psyc_var_type (const char *name, size_t len) { int8_t m[psyc_var_types_num]; return psyc_in_array(psyc_var_types, psyc_var_types_num, diff --git a/test/test_list.c b/test/test_list.c index bbf6b4a..dd0be16 100644 --- a/test/test_list.c +++ b/test/test_list.c @@ -13,18 +13,18 @@ int main (int argc, char **argv) { uint8_t verbose = argc > 1; int i, k, n, ret; - psycParseListState listState; - psycList list_text, list_bin; - psycString elems_text[NELEMS], elems_bin[NELEMS], elem; + PsycParseListState listState; + PsycList list_text, list_bin; + PsycString elems_text[NELEMS], elems_bin[NELEMS], elem; char buf_text[NELEMS * 200], buf_bin[NELEMS * 200], *elems[NELEMS], **elems2 = NULL; struct timeval start, end; for (i=0; i 2 && memchr(argv[2], (int)'v', strlen(argv[2])); int idx, ret; char buffer[2048], oper; - psycString name, value, elem; - psycParseState state; - psycParseListState listState; + PsycString name, value, elem; + PsycParseState state; + PsycParseListState listState; if (argc < 2) return -1; diff --git a/test/test_psyc.c b/test/test_psyc.c index 1ce375f..43bbbd6 100644 --- a/test/test_psyc.c +++ b/test/test_psyc.c @@ -24,15 +24,15 @@ uint8_t verbose, stats; uint8_t multiple, single, routing_only, no_render, quiet, progress; size_t count = 1, recv_buf_size; -psycParseState parsers[NUM_PARSERS]; -psycPacket packets[NUM_PARSERS]; -psycModifier routing[NUM_PARSERS][ROUTING_LINES]; -psycModifier entity[NUM_PARSERS][ENTITY_LINES]; +PsycParseState parsers[NUM_PARSERS]; +PsycPacket packets[NUM_PARSERS]; +PsycModifier routing[NUM_PARSERS][ROUTING_LINES]; +PsycModifier entity[NUM_PARSERS][ENTITY_LINES]; int contbytes, exit_code; static inline -void resetString (psycString *s, uint8_t freeptr); +void resetString (PsycString *s, uint8_t freeptr); // initialize parser & packet variables void test_init (int i) { @@ -40,9 +40,9 @@ void test_init (int i) { psyc_parse_state_init(&parsers[i], routing_only ? PSYC_PARSE_ROUTING_ONLY : PSYC_PARSE_ALL); - memset(&packets[i], 0, sizeof(psycPacket)); - memset(&routing[i], 0, sizeof(psycModifier) * ROUTING_LINES); - memset(&entity[i], 0, sizeof(psycModifier) * ENTITY_LINES); + memset(&packets[i], 0, sizeof(PsycPacket)); + memset(&routing[i], 0, sizeof(PsycModifier) * ROUTING_LINES); + memset(&entity[i], 0, sizeof(PsycModifier) * ENTITY_LINES); packets[i].routing.modifiers = routing[i]; packets[i].entity.modifiers = entity[i]; } @@ -63,14 +63,14 @@ int test_input (int i, char *recvbuf, size_t nbytes) { * to this function together with the new data. */ - psycParseState *parser = &parsers[i]; - psycPacket *packet = &packets[i]; + PsycParseState *parser = &parsers[i]; + PsycPacket *packet = &packets[i]; char oper; - psycString name, value, elem; - psycString *pname = NULL, *pvalue = NULL; - psycModifier *mod = NULL; - psycParseListState listState; + PsycString name, value, elem; + PsycString *pname = NULL, *pvalue = NULL; + PsycModifier *mod = NULL; + PsycParseListState listState; size_t len; // Set buffer with data for the parser. @@ -308,7 +308,7 @@ int test_input (int i, char *recvbuf, size_t nbytes) { } static inline -void resetString (psycString *s, uint8_t freeptr) +void resetString (PsycString *s, uint8_t freeptr) { if (freeptr && s->length) free((void*)s->ptr); diff --git a/test/test_psyc_speed.c b/test/test_psyc_speed.c index 3abcfe1..7ee20fe 100644 --- a/test/test_psyc_speed.c +++ b/test/test_psyc_speed.c @@ -23,7 +23,7 @@ uint8_t verbose, stats; uint8_t routing_only; size_t count = 1, recv_buf_size; -psycParseState parser; +PsycParseState parser; void test_init (int i) { psyc_parse_state_init(&parser, routing_only ? @@ -32,7 +32,7 @@ void test_init (int i) { int test_input (int i, char *recvbuf, size_t nbytes) { char oper; - psycString name, value; + PsycString name, value; int ret; psyc_parse_buffer_set(&parser, recvbuf, nbytes); diff --git a/test/test_render.c b/test/test_render.c index 59432b3..ecebae5 100644 --- a/test/test_render.c +++ b/test/test_render.c @@ -11,12 +11,12 @@ int testPresence (const char *avail, int availlen, const char *desc, int desclen, const char *rendered, uint8_t verbose) { - psycModifier routing[] = { + PsycModifier routing[] = { psyc_modifier_new(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_context"), PSYC_C2ARG(myUNI), PSYC_MODIFIER_ROUTING), }; - psycModifier entity[] = { + PsycModifier entity[] = { // presence is to be assigned permanently in distributed state psyc_modifier_new(C_GLYPH_OPERATOR_ASSIGN, PSYC_C2ARG("_degree_availability"), avail, availlen, PSYC_MODIFIER_CHECK_LENGTH), @@ -24,7 +24,7 @@ int testPresence (const char *avail, int availlen, desc, desclen, PSYC_MODIFIER_CHECK_LENGTH), }; - psycPacket packet = psyc_packet_new(routing, PSYC_NUM_ELEM(routing), + PsycPacket packet = psyc_packet_new(routing, PSYC_NUM_ELEM(routing), entity, PSYC_NUM_ELEM(entity), PSYC_C2ARG("_notice_presence"), NULL, 0, @@ -39,26 +39,26 @@ int testPresence (const char *avail, int availlen, int testList (const char *rendered, uint8_t verbose) { - psycModifier routing[] = { + PsycModifier routing[] = { psyc_modifier_new(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_source"), PSYC_C2ARG(myUNI), PSYC_MODIFIER_ROUTING), psyc_modifier_new(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_context"), PSYC_C2ARG(myUNI), PSYC_MODIFIER_ROUTING), }; - psycString elems_text[] = { + PsycString elems_text[] = { PSYC_C2STR("foo"), PSYC_C2STR("bar"), PSYC_C2STR("baz"), }; - psycString elems_bin[] = { + PsycString elems_bin[] = { PSYC_C2STR("foo"), PSYC_C2STR("b|r"), PSYC_C2STR("baz\nqux"), }; - psycList list_text, list_bin; + PsycList list_text, list_bin; list_text = psyc_list_new(elems_text, PSYC_NUM_ELEM(elems_text), PSYC_LIST_CHECK_LENGTH); list_bin = psyc_list_new(elems_bin, PSYC_NUM_ELEM(elems_bin), PSYC_LIST_CHECK_LENGTH); @@ -66,14 +66,14 @@ int testList (const char *rendered, uint8_t verbose) psyc_render_list(&list_text, buf_text, sizeof(buf_text)); psyc_render_list(&list_bin, buf_bin, sizeof(buf_bin)); - psycModifier entity[] = { + PsycModifier entity[] = { psyc_modifier_new(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_list_text"), buf_text, list_text.length, list_text.flag), psyc_modifier_new(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_list_binary"), buf_bin, list_bin.length, list_bin.flag), }; - psycPacket packet = psyc_packet_new(routing, PSYC_NUM_ELEM(routing), + PsycPacket packet = psyc_packet_new(routing, PSYC_NUM_ELEM(routing), entity, PSYC_NUM_ELEM(entity), PSYC_C2ARG("_test_list"), PSYC_C2ARG("list test"), diff --git a/test/test_text.c b/test/test_text.c index 214d106..cd1552d 100644 --- a/test/test_text.c +++ b/test/test_text.c @@ -7,7 +7,7 @@ uint8_t verbose; -psycTextValueRC getValueFooBar (const char *name, size_t len, psycString *value, void *extra) +PsycTextValueRC getValueFooBar (const char *name, size_t len, PsycString *value, void *extra) { if (verbose) printf("> getValue: %.*s\n", (int)len, name); @@ -16,7 +16,7 @@ psycTextValueRC getValueFooBar (const char *name, size_t len, psycString *value, return PSYC_TEXT_VALUE_FOUND; } -psycTextValueRC getValueEmpty (const char *name, size_t len, psycString *value, void *extra) +PsycTextValueRC getValueEmpty (const char *name, size_t len, PsycString *value, void *extra) { if (verbose) printf("> getValue: %.*s\n", (int)len, name); @@ -25,18 +25,18 @@ psycTextValueRC getValueEmpty (const char *name, size_t len, psycString *value, return PSYC_TEXT_VALUE_FOUND; } -psycTextValueRC getValueNotFound (const char *name, size_t len, psycString *value, void *extra) +PsycTextValueRC getValueNotFound (const char *name, size_t len, PsycString *value, void *extra) { if (verbose) printf("> getValue: %.*s\n", (int)len, name); return PSYC_TEXT_VALUE_NOT_FOUND; } -int testText (char *template, size_t tmplen, char *buffer, size_t buflen, psycString *result, psycTextCB getValue) +int testText (char *template, size_t tmplen, char *buffer, size_t buflen, PsycString *result, PsycTextCB getValue) { - psycTextState state; + PsycTextState state; size_t length = 0; - psycTextRC ret; + PsycTextRC ret; psyc_text_state_init(&state, template, tmplen, buffer, buflen); do @@ -71,7 +71,7 @@ int main(int argc, char **argv) { verbose = argc > 1; char buffer[BUFSIZE]; - psycString result; + PsycString result; char *str = "Hello [_foo] & [_bar]!"; size_t len = strlen(str); diff --git a/test/uniform_parse.c b/test/uniform_parse.c index ff5d307..1a466fa 100644 --- a/test/uniform_parse.c +++ b/test/uniform_parse.c @@ -5,8 +5,8 @@ void testUniform (char *str, int ret) { - psycUniform *uni = malloc(sizeof(psycUniform)); - memset(uni, 0, sizeof(psycUniform)); + PsycUniform *uni = malloc(sizeof(PsycUniform)); + memset(uni, 0, sizeof(PsycUniform)); printf("%s\n", str); int r = psyc_uniform_parse(uni, str, strlen(str)); From 0cd53743e20f2c7cea9a2888d23aa9dc3aac9d24 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 1 Nov 2011 12:06:58 +0100 Subject: [PATCH 334/378] refactoring - more renames --- d/include/psyc/common.d | 2 +- d/include/psyc/packet.d | 4 +-- d/include/psyc/parse.d | 4 +-- include/psyc.h | 62 +++++++++++++++++++++++---------- include/psyc/packet.h | 2 +- include/psyc/parse.h | 12 +++---- include/psyc/text.h | 2 +- include/psyc/uniform.h | 1 + include/psyc/variable.h | 2 +- pike/psyc.cmod | 52 ++++++++++++++-------------- src/match.c | 41 ++++++++-------------- src/packet.c | 8 ++--- src/parse.c | 76 ++++++++++++++++++++--------------------- src/render.c | 14 ++++---- src/text.c | 30 ++++++++-------- src/uniform.c | 34 +++++++++--------- src/variable.c | 10 +++--- test/test_list.c | 16 ++++----- test/test_parser.c | 6 ++-- test/test_psyc.c | 24 ++++++------- test/test_text.c | 12 +++---- 21 files changed, 215 insertions(+), 199 deletions(-) diff --git a/d/include/psyc/common.d b/d/include/psyc/common.d index 21938f9..2f41a6b 100644 --- a/d/include/psyc/common.d +++ b/d/include/psyc/common.d @@ -101,7 +101,7 @@ Bool psyc_var_is_routing (char* name, size_t len); bool isRoutingVar (char[] name) { - return psyc_var_is_routing(name.ptr, name.length); //FIXME + return psyc_var_is_routing(name.data, name.length); //FIXME } /** diff --git a/d/include/psyc/packet.d b/d/include/psyc/packet.d index da544e0..a2e5648 100644 --- a/d/include/psyc/packet.d +++ b/d/include/psyc/packet.d @@ -105,7 +105,7 @@ struct Modifier if (value.length > PSYC_MODIFIER_SIZE_THRESHOLD) flag = ModifierFlag.NEED_LENGTH; - else if (memchr(value.ptr, cast(int)'\n', value.length)) + else if (memchr(value.data, cast(int)'\n', value.length)) flag = ModifierFlag.NEED_LENGTH; else flag = ModifierFlag.NO_LENGTH; @@ -162,7 +162,7 @@ struct Packet psyc_packet_length_set(this); with (RenderRC) - switch (psyc_render(this, buffer.ptr, buffer.length)) + switch (psyc_render(this, buffer.data, buffer.length)) { case ERROR_METHOD_MISSING: throw new Exception("Method missing"); diff --git a/d/include/psyc/parse.d b/d/include/psyc/parse.d index 7d21714..4f4dfe7 100644 --- a/d/include/psyc/parse.d +++ b/d/include/psyc/parse.d @@ -247,13 +247,13 @@ struct ParseState ubyte* getRemainingBuffer ( ) { - return cast(ubyte*)this.buffer.ptr + this.cursor; + return cast(ubyte*)this.buffer.data + this.cursor; } void getRemainingBuffer ( ref ubyte[] buf ) { - buf = cast(ubyte[])this.buffer.ptr[cursor .. cursor + getRemainingLength()]; + buf = cast(ubyte[])this.buffer.data[cursor .. cursor + getRemainingLength()]; } } diff --git a/include/psyc.h b/include/psyc.h index 395f645..b980a3d 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -24,8 +24,8 @@ #define PSYC_C2STR(str) {sizeof(str)-1, str} #define PSYC_C2ARG(str) str, sizeof(str)-1 -#define PSYC_S2ARG(str) (str).ptr, (str).length -#define PSYC_S2ARG2(str) (str).length, (str).ptr +#define PSYC_S2ARG(str) (str).data, (str).length +#define PSYC_S2ARG2(str) (str).length, (str).data #define PSYC_NUM_ELEM(a) (sizeof(a) / sizeof(*(a))) @@ -37,6 +37,12 @@ typedef enum PSYC_YES = 1, } PsycBool; +typedef enum +{ + PSYC_OK = 1, + PSYC_ERROR = -1, +} PsycRC; + /** * PSYC packet parts. */ @@ -96,14 +102,20 @@ typedef struct /// Length of the data pointed to by ptr size_t length; /// pointer to the data - char *ptr; + char *data; } PsycString; typedef struct { PsycString key; - int value; -} PsycMatchVar; + void *value; +} PsycDict; + +typedef struct +{ + PsycString key; + intptr_t value; +} PsycDictInt; /** * Shortcut for creating a PsycString. @@ -140,23 +152,37 @@ int psyc_matches (char *sho, size_t slen, char *lon, size_t llen); /** - * Check if keyword is in array. + * Look up value associated with a key in a dictionary. * - * @param array The array to search, should be ordered alphabetically. - * @param size Size of array. - * @param kw Keyword to look for. - * @param kwlen Length of keyword. - * @param inherit If true, also look for anything inheriting from kw, - otherwise only exact matches are returned. - * @param matching A temporary array used for keeping track of results. - * Should be the same size as the array we're searching. + * @param dict The dictionary to search, should be ordered alphabetically. + * @param size Size of dict. + * @param key Key to look for. + * @param keylen Length of key. + * @param inherit If true, also look for anything inheriting from key, + otherwise only exact matches are returned. + * @param tmp A temporary array used for keeping track of results. + * Should be the same size as dict. * - * @return The value of the matched variable in the array. + * @return The value of the entry if found, or NULL if not found. */ -int psyc_in_array (const PsycMatchVar *array, size_t size, - const char *kw, size_t kwlen, - PsycBool inherit, int8_t *matching); +void * psyc_dict_lookup (const PsycDict *dict, size_t size, + const char *key, size_t keylen, + PsycBool inherit, int8_t *tmp); + +/** + * Look up value associated with a key in a dictionary of integers. + * @see psyc_dict_lookup + */ +static inline +intptr_t psyc_dict_lookup_int (const PsycDictInt *dict, size_t size, + const char *key, size_t keylen, + PsycBool inherit, int8_t *tmp) +{ + return (intptr_t) psyc_dict_lookup((PsycDict *)dict, size, key, keylen, inherit, tmp); +} + + #include "psyc/variable.h" diff --git a/include/psyc/packet.h b/include/psyc/packet.h index c0fddaa..9608c2c 100644 --- a/include/psyc/packet.h +++ b/include/psyc/packet.h @@ -113,7 +113,7 @@ PsycModifierFlag psyc_modifier_length_check (PsycModifier *m) if (m->value.length > PSYC_MODIFIER_SIZE_THRESHOLD) flag = PSYC_MODIFIER_NEED_LENGTH; - else if (memchr(m->value.ptr, (int)'\n', m->value.length)) + else if (memchr(m->value.data, (int)'\n', m->value.length)) flag = PSYC_MODIFIER_NEED_LENGTH; else flag = PSYC_MODIFIER_NO_LENGTH; diff --git a/include/psyc/parse.h b/include/psyc/parse.h index c1ba421..0b9c737 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -77,17 +77,17 @@ * // Name, value and operator of the variable can now be found in the * // respective variables: * printf("Variable: %.*s Value: %.*s Operator: %c\n", - * name.length, name.ptr, - * value.length, value.ptr, + * name.length, name.data, + * value.length, value.data, * oper); - * // Note that the .ptr member still points at your original buffer. If + * // Note that the .data member still points at your original buffer. If * // you want to reuse that buffer for the next packet, you better copy it * // before passing it to the parser or you copy each variable now. * break; * case PSYC_PARSE_BODY: // it is the method and the body of the packet. * printf("Method Name: %.*s Body: %.*s\n", - * name.length, name.ptr, // name of the method - * value.length, value.ptr); // value of the body + * name.length, name.data, // name of the method + * value.length, value.data); // value of the body * break; * case PSYC_PARSE_COMPLETE: // parsing of this packet is complete * // You can simply continue parsing till you get the @@ -345,7 +345,7 @@ size_t psyc_parse_remaining_length (PsycParseState *state) static inline const char * psyc_parse_remaining_buffer (PsycParseState *state) { - return state->buffer.ptr + state->cursor; + return state->buffer.data + state->cursor; } /** diff --git a/include/psyc/text.h b/include/psyc/text.h index f3e1bc8..83b0232 100644 --- a/include/psyc/text.h +++ b/include/psyc/text.h @@ -58,7 +58,7 @@ typedef struct * Callback for psyc_text() that produces a value for a match. * * The application looks up a match such as _fruit from [_fruit] and - * if found sets value->ptr & value->length to point to the found value, + * if found sets value->data & value->length to point to the found value, * "Apple" for example. 0 is a legal value for the length. * The callbacks returns either PSYC_TEXT_VALUE_FOUND or * PSYC_TEXT_VALUE_NOT_FOUND if no match found in which case psyc_text diff --git a/include/psyc/uniform.h b/include/psyc/uniform.h index cd0abdb..bf1d84c 100644 --- a/include/psyc/uniform.h +++ b/include/psyc/uniform.h @@ -68,6 +68,7 @@ typedef enum { } PsycTransport; typedef enum { + PSYC_ENTITY_ROOT = 0, PSYC_ENTITY_PERSON = '~', PSYC_ENTITY_PLACE = '@', PSYC_ENTITY_SERVICE = '$', diff --git a/include/psyc/variable.h b/include/psyc/variable.h index 1e42f7e..0c3d9b9 100644 --- a/include/psyc/variable.h +++ b/include/psyc/variable.h @@ -8,7 +8,7 @@ extern const PsycString psyc_routing_vars[]; // Variable types in alphabetical order. -extern const PsycMatchVar psyc_var_types[]; +extern const PsycDictInt psyc_var_types[]; extern const size_t psyc_routing_vars_num; extern const size_t psyc_var_types_num; diff --git a/pike/psyc.cmod b/pike/psyc.cmod index 3aca2dd..211ab81 100644 --- a/pike/psyc.cmod +++ b/pike/psyc.cmod @@ -47,13 +47,13 @@ PsycTextValueRC lookup_value_mapping(const char *name, size_t len, PsycString *v switch(s->type) { case PIKE_T_STRING: //printf("lookup returned %.*s\n", (int) s->u.string->len, STR0(s->u.string)); - value->ptr = (char *) STR0(s->u.string); + value->data = (char *) STR0(s->u.string); value->length = s->u.string->len; break; default: printf("lookup did return !string\n"); // FIXME: we need the automagic value conversion - value->ptr = ""; + value->data = ""; value->length = 0; } return PSYC_TEXT_VALUE_FOUND; @@ -302,29 +302,29 @@ PIKECLASS Parser { ret = psyc_parse(&THIS->parser, &oper, &name, &value); switch(ret) { case PSYC_PARSE_ROUTING: - // printf("R %.*s -> %.*s\n", (int)name.length, name.ptr, (int)value.length, value.ptr); + // printf("R %.*s -> %.*s\n", (int)name.length, name.data, (int)value.length, value.data); mapping_string_insert_string(THIS->rvars, - make_shared_binary_string(name.ptr, name.length), - make_shared_binary_string(value.ptr, value.length)); + make_shared_binary_string(name.data, name.length), + make_shared_binary_string(value.data, value.length)); break; case PSYC_PARSE_ENTITY_START: // entity var with length init_string_builder_alloc(&THIS->incomplete, psyc_parse_value_length(&THIS->parser), 0); // fall thru case PSYC_PARSE_ENTITY_CONT: - string_builder_append(&THIS->incomplete, MKPCHARP(value.ptr, 0), value.length); + string_builder_append(&THIS->incomplete, MKPCHARP(value.data, 0), value.length); break; case PSYC_PARSE_ENTITY_END: - string_builder_append(&THIS->incomplete, MKPCHARP(value.ptr, 0), value.length); + string_builder_append(&THIS->incomplete, MKPCHARP(value.data, 0), value.length); do { struct pike_string *tmp = finish_string_builder(&THIS->incomplete); value.length = tmp->len; - value.ptr = (char *) STR0(tmp); + value.data = (char *) STR0(tmp); // FIXME: not sure if this is really safe free_string(tmp); } while (0); // fall thru case PSYC_PARSE_ENTITY: - //printf("E %.*s -> %.*s\n", (int)name.length, name.ptr, (int)value.length, value.ptr); + //printf("E %.*s -> %.*s\n", (int)name.length, name.data, (int)value.length, value.data); do { err = 0; int type = psyc_var_type(PSYC_S2ARG(&name)); @@ -335,7 +335,7 @@ PIKECLASS Parser { if (psyc_parse_date(&value, &timmy)) { sv.type = PIKE_T_INT; sv.u.integer = timmy; mapping_string_insert(THIS->evars, - make_shared_binary_string(name.ptr, name.length), + make_shared_binary_string(name.data, name.length), &sv); } else { err = 1; @@ -345,7 +345,7 @@ PIKECLASS Parser { if (psyc_parse_time(&value, &timmy)) { sv.type = PIKE_T_INT; sv.u.integer = timmy; mapping_string_insert(THIS->evars, - make_shared_binary_string(name.ptr, name.length), + make_shared_binary_string(name.data, name.length), &sv); } else { err = 2; @@ -354,20 +354,20 @@ PIKECLASS Parser { case PSYC_TYPE_AMOUNT: break; case PSYC_TYPE_DEGREE: - if (value.length && value.ptr[0] >= '0' && value.ptr[0] <= '9') { - sv.type = PIKE_T_FLOAT; sv.u.float_number = (float) (value.ptr[0] - '0') / 10.0; + if (value.length && value.data[0] >= '0' && value.data[0] <= '9') { + sv.type = PIKE_T_FLOAT; sv.u.float_number = (float) (value.data[0] - '0') / 10.0; mapping_string_insert(THIS->evars, - make_shared_binary_string(name.ptr, name.length), + make_shared_binary_string(name.data, name.length), &sv); } else { err = 3; } break; case PSYC_TYPE_FLAG: - if (value.length && value.ptr[0] >= '0' && value.ptr[0] <= '1') { - sv.type = PIKE_T_INT; sv.u.integer = value.ptr[0] - '0'; + if (value.length && value.data[0] >= '0' && value.data[0] <= '1') { + sv.type = PIKE_T_INT; sv.u.integer = value.data[0] - '0'; mapping_string_insert(THIS->evars, - make_shared_binary_string(name.ptr, name.length), + make_shared_binary_string(name.data, name.length), &sv); } else { err = 4; @@ -390,7 +390,7 @@ PIKECLASS Parser { case PSYC_PARSE_LIST_END: // last element retl = 0; case PSYC_PARSE_LIST_ELEM: - sv.type = PIKE_T_STRING; sv.u.string = make_shared_binary_string(elem.ptr, elem.length); + sv.type = PIKE_T_STRING; sv.u.string = make_shared_binary_string(elem.data, elem.length); elems = array_insert(elems, &sv, count++); break; default: @@ -403,7 +403,7 @@ PIKECLASS Parser { sv.type = PIKE_T_ARRAY; sv.u.array = elems; mapping_string_insert(THIS->evars, - make_shared_binary_string(name.ptr, name.length), + make_shared_binary_string(name.data, name.length), &sv); } free_array(elems); @@ -411,8 +411,8 @@ PIKECLASS Parser { break; default: // string mapping_string_insert_string(THIS->evars, - make_shared_binary_string(name.ptr, name.length), - make_shared_binary_string(value.ptr, value.length)); + make_shared_binary_string(name.data, name.length), + make_shared_binary_string(value.data, value.length)); } } while (0); if (err) { // there was an error while @@ -423,21 +423,21 @@ PIKECLASS Parser { case PSYC_PARSE_BODY_START: // if length was given this is used for body init_string_builder_alloc(&THIS->incomplete, psyc_parse_value_length(&THIS->parser), 0); case PSYC_PARSE_BODY_CONT: - string_builder_append(&THIS->incomplete, MKPCHARP(value.ptr, 0), value.length); + string_builder_append(&THIS->incomplete, MKPCHARP(value.data, 0), value.length); break; case PSYC_PARSE_BODY_END: - string_builder_append(&THIS->incomplete, MKPCHARP(value.ptr, 0), value.length); + string_builder_append(&THIS->incomplete, MKPCHARP(value.data, 0), value.length); do { struct pike_string *tmp = finish_string_builder(&THIS->incomplete); value.length = tmp->len; - value.ptr = (char *) STR0(tmp); + value.data = (char *) STR0(tmp); // FIXME: not sure if this is really safe free_string(tmp); } while (0); // fall thru case PSYC_PARSE_BODY: - THIS->method = make_shared_binary_string(name.ptr, name.length); - THIS->body = make_shared_binary_string(value.ptr, value.length); + THIS->method = make_shared_binary_string(name.data, name.length); + THIS->body = make_shared_binary_string(value.data, value.length); break; case PSYC_PARSE_COMPLETE: // apply the callback push_mapping(THIS->rvars); diff --git a/src/match.c b/src/match.c index cc06dc6..de34c1f 100644 --- a/src/match.c +++ b/src/match.c @@ -101,49 +101,38 @@ failed: } /** - * Check if keyword is in array. - * - * @param array The array to search, should be ordered alphabetically. - * @param size Size of array. - * @param kw Keyword to look for. - * @param kwlen Length of keyword. - * @param inherit If true, look for any keyword inheriting from name, - otherwise only exact matches are returned. - * @param matching A temporary array used for keeping track of results. - * Should be the same size as the array we're searching. - * - * @return The value of the matched variable in the array. + * Look up value associated with a key in a dictionary. */ -int psyc_in_array (const PsycMatchVar *array, size_t size, - const char *kw, size_t kwlen, - PsycBool inherit, int8_t *matching) +void * psyc_dict_lookup (const PsycDict *dict, size_t size, + const char *key, size_t keylen, + PsycBool inherit, int8_t *matching) { size_t cursor = 1; uint8_t i, m = 0; //memset(&matching, -1, sizeof matching); - if (kwlen < 2 || kw[0] != '_') + if (keylen < 2 || key[0] != '_') return 0; // first find the keywords with matching length for (i=0; i array[i].key.length && kw[array[i].key.length] == '_')) + if (keylen == dict[i].key.length || + (inherit && keylen > dict[i].key.length && key[dict[i].key.length] == '_')) matching[m++] = i; matching[m] = -1; // mark the end of matching indexes - while (cursor < kwlen && matching[0] >= 0) { + while (cursor < keylen && matching[0] >= 0) { for (i = m = 0; i < size; i++) { if (matching[i] < 0) break; // reached the end of possible matches - if (cursor < array[matching[i]].key.length && - array[matching[i]].key.ptr[cursor] == kw[cursor]) + if (cursor < dict[matching[i]].key.length && + dict[matching[i]].key.data[cursor] == key[cursor]) matching[m++] = matching[i]; // found a match, update matching indexes - else if (cursor == array[matching[i]].key.length && kw[cursor] == '_') - return array[matching[0]].value; // _ after the end of a matching prefix - else if (array[matching[i]].key.ptr[cursor] > kw[cursor]) - break; // passed the possible matches in alphabetical order in the array + else if (cursor == dict[matching[i]].key.length && key[cursor] == '_') + return dict[matching[0]].value; // _ after the end of a matching prefix + else if (dict[matching[i]].key.data[cursor] > key[cursor]) + break; // passed the possible matches in alphabetical order in the dict } if (m < size) @@ -153,7 +142,7 @@ int psyc_in_array (const PsycMatchVar *array, size_t size, } // return first match if found - return matching[0] >= 0 ? array[matching[0]].value : 0; + return matching[0] >= 0 ? dict[matching[0]].value : 0; } #ifdef CMDTOOL diff --git a/src/packet.c b/src/packet.c index dc7f10a..b4444e7 100644 --- a/src/packet.c +++ b/src/packet.c @@ -13,8 +13,8 @@ PsycListFlag psyc_list_length_check (PsycList *list) PsycString *elem = &list->elems[i]; length += 1 + elem->length; // |elem if (length > PSYC_MODIFIER_SIZE_THRESHOLD || - memchr(elem->ptr, (int)'|', elem->length) || - memchr(elem->ptr, (int)'\n', elem->length)) + memchr(elem->data, (int)'|', elem->length) || + memchr(elem->data, (int)'\n', elem->length)) { flag = PSYC_LIST_NEED_LENGTH; break; @@ -76,7 +76,7 @@ size_t psyc_modifier_length (PsycModifier *m) inline PsycPacketFlag psyc_packet_length_check (PsycPacket *p) { - if (p->data.length == 1 && p->data.ptr[0] == C_GLYPH_PACKET_DELIMITER) + if (p->data.length == 1 && p->data.data[0] == C_GLYPH_PACKET_DELIMITER) return PSYC_PACKET_NEED_LENGTH; if (p->data.length > PSYC_CONTENT_SIZE_THRESHOLD) @@ -89,7 +89,7 @@ PsycPacketFlag psyc_packet_length_check (PsycPacket *p) if (p->entity.modifiers[i].flag == PSYC_MODIFIER_NEED_LENGTH) return PSYC_PACKET_NEED_LENGTH; - if (memmem(p->data.ptr, p->data.length, PSYC_C2ARG(PSYC_PACKET_DELIMITER))) + if (memmem(p->data.data, p->data.length, PSYC_C2ARG(PSYC_PACKET_DELIMITER))) return PSYC_PACKET_NEED_LENGTH; return PSYC_PACKET_NO_LENGTH; diff --git a/src/parse.c b/src/parse.c index 8c8e763..42459e3 100644 --- a/src/parse.c +++ b/src/parse.c @@ -31,10 +31,10 @@ typedef enum { static inline parseRC psyc_parse_keyword (PsycParseState *state, PsycString *name) { - name->ptr = state->buffer.ptr + state->cursor; + name->data = state->buffer.data + state->cursor; name->length = 0; - while (psyc_is_kw_char(state->buffer.ptr[state->cursor])) + while (psyc_is_kw_char(state->buffer.data[state->cursor])) { name->length++; // was a valid char, increase length ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); @@ -58,7 +58,7 @@ parseRC psyc_parse_binary_value (PsycParseState *state, PsycString *value, size_t *length, size_t *parsed) { size_t remaining = *length - *parsed; - value->ptr = state->buffer.ptr + state->cursor; + value->data = state->buffer.data + state->cursor; if (state->cursor + remaining > state->buffer.length) { // value doesn't fit in the buffer completely @@ -84,7 +84,7 @@ static inline parseRC psyc_parse_modifier (PsycParseState *state, char *oper, PsycString *name, PsycString *value) { - *oper = *(state->buffer.ptr + state->cursor); + *oper = *(state->buffer.data + state->cursor); ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); parseRC ret = psyc_parse_keyword(state, name); @@ -101,26 +101,26 @@ parseRC psyc_parse_modifier (PsycParseState *state, char *oper, // 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 + if (state->part == PSYC_PART_CONTENT && state->buffer.data[state->cursor] == ' ') // binary arg { // After SP the length follows. ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); - if (psyc_is_numeric(state->buffer.ptr[state->cursor])) + if (psyc_is_numeric(state->buffer.data[state->cursor])) { state->valueLengthFound = 1; do { - length = 10 * length + state->buffer.ptr[state->cursor] - '0'; + length = 10 * length + state->buffer.data[state->cursor] - '0'; ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } - while (psyc_is_numeric(state->buffer.ptr[state->cursor])); + while (psyc_is_numeric(state->buffer.data[state->cursor])); state->valueLength = length; } else return PSYC_PARSE_ERROR_MOD_LEN; // After the length a TAB follows. - if (state->buffer.ptr[state->cursor] != '\t') + if (state->buffer.data[state->cursor] != '\t') return PSYC_PARSE_ERROR_MOD_TAB; if (++(state->cursor) >= state->buffer.length) @@ -132,12 +132,12 @@ parseRC psyc_parse_modifier (PsycParseState *state, char *oper, return PARSE_SUCCESS; } - else if (state->buffer.ptr[state->cursor] == '\t') // simple arg + else if (state->buffer.data[state->cursor] == '\t') // simple arg { ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); - value->ptr = state->buffer.ptr + state->cursor; + value->data = state->buffer.data + state->cursor; - while (state->buffer.ptr[state->cursor] != '\n') + while (state->buffer.data[state->cursor] != '\n') { value->length++; ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); @@ -189,7 +189,7 @@ PsycParseRC psyc_parse (PsycParseState *state, char *oper, case PSYC_PART_ROUTING: if (state->routingLength > 0) { - if (state->buffer.ptr[state->cursor] != '\n') + if (state->buffer.data[state->cursor] != '\n') return PSYC_PARSE_ERROR_MOD_NL; ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } @@ -197,7 +197,7 @@ PsycParseRC psyc_parse (PsycParseState *state, char *oper, // 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 (psyc_is_glyph(state->buffer.ptr[state->cursor])) // is the first char a glyph? + if (psyc_is_glyph(state->buffer.data[state->cursor])) // is the first char a glyph? { // it is a glyph, so a variable starts here ret = psyc_parse_modifier(state, oper, name, value); state->routingLength += state->cursor - pos; @@ -212,20 +212,20 @@ PsycParseRC psyc_parse (PsycParseState *state, char *oper, case PSYC_PART_LENGTH: // End of header, content starts with an optional length then a NL - if (psyc_is_numeric(state->buffer.ptr[state->cursor])) + if (psyc_is_numeric(state->buffer.data[state->cursor])) { state->contentLengthFound = 1; state->contentLength = 0; do { - state->contentLength = 10 * state->contentLength + state->buffer.ptr[state->cursor] - '0'; + state->contentLength = 10 * state->contentLength + state->buffer.data[state->cursor] - '0'; ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } - while (psyc_is_numeric(state->buffer.ptr[state->cursor])); + while (psyc_is_numeric(state->buffer.data[state->cursor])); } - if (state->buffer.ptr[state->cursor] == '\n') // start of content + if (state->buffer.data[state->cursor] == '\n') // start of content { // If we need to parse the header only and we know the content length, // then skip content parsing. @@ -270,7 +270,7 @@ PsycParseRC psyc_parse (PsycParseState *state, char *oper, if (state->contentParsed > 0) { - if (state->buffer.ptr[state->cursor] != '\n') + if (state->buffer.data[state->cursor] != '\n') return PSYC_PARSE_ERROR_MOD_NL; ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } @@ -280,7 +280,7 @@ PsycParseRC psyc_parse (PsycParseState *state, char *oper, // 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 (psyc_is_glyph(state->buffer.ptr[state->cursor])) + if (psyc_is_glyph(state->buffer.data[state->cursor])) { ret = psyc_parse_modifier(state, oper, name, value); state->contentParsed += state->cursor - pos; @@ -308,7 +308,7 @@ PsycParseRC psyc_parse (PsycParseState *state, char *oper, return ret; else if (ret == PARSE_SUCCESS) { // the method ends with a \n then the data follows - if (state->buffer.ptr[state->cursor] != '\n') + if (state->buffer.data[state->cursor] != '\n') return PSYC_PARSE_ERROR_METHOD; state->valueLengthFound = 0; @@ -338,7 +338,7 @@ PsycParseRC psyc_parse (PsycParseState *state, char *oper, case PSYC_PART_DATA: PSYC_PART_DATA: - value->ptr = state->buffer.ptr + state->cursor; + value->data = state->buffer.data + state->cursor; value->length = 0; if (state->contentLengthFound) // We know the length of the packet. @@ -370,7 +370,7 @@ PsycParseRC psyc_parse (PsycParseState *state, char *oper, while (1) { - uint8_t nl = state->buffer.ptr[state->cursor] == '\n'; + uint8_t nl = state->buffer.data[state->cursor] == '\n'; // check for |\n if we're at the start of data or we have found a \n if (state->cursor == datac || nl) { @@ -380,8 +380,8 @@ PsycParseRC psyc_parse (PsycParseState *state, char *oper, return PSYC_PARSE_INSUFFICIENT; } - if (state->buffer.ptr[state->cursor+nl] == '|' && - state->buffer.ptr[state->cursor+1+nl] == '\n') // packet ends here + if (state->buffer.data[state->cursor+nl] == '|' && + state->buffer.data[state->cursor+1+nl] == '\n') // packet ends here { if (state->flags & PSYC_PARSE_ROUTING_ONLY) value->length++; @@ -405,7 +405,7 @@ PsycParseRC psyc_parse (PsycParseState *state, char *oper, state->valueLength = 0; state->valueLengthFound = 0; - if (state->buffer.ptr[state->cursor] != '\n') + if (state->buffer.data[state->cursor] != '\n') return PSYC_PARSE_ERROR_END; state->contentParsed++; @@ -417,8 +417,8 @@ PsycParseRC psyc_parse (PsycParseState *state, char *oper, if (state->cursor+1 >= state->buffer.length) // incremented cursor inside length? return PSYC_PARSE_INSUFFICIENT; - if (state->buffer.ptr[state->cursor] == '|' && - state->buffer.ptr[state->cursor+1] == '\n') // packet ends here + if (state->buffer.data[state->cursor] == '|' && + state->buffer.data[state->cursor+1] == '\n') // packet ends here { state->cursor += 2; state->part = PSYC_PART_RESET; @@ -447,12 +447,12 @@ PsycParseListRC psyc_parse_list (PsycParseListState *state, PsycString *elem) if (!state->type) // If type is not set we're at the start { // First character is either | for text lists, or a number for binary lists - if (state->buffer.ptr[state->cursor] == '|') + if (state->buffer.data[state->cursor] == '|') { state->type = PSYC_LIST_TEXT; state->cursor++; } - else if (psyc_is_numeric(state->buffer.ptr[state->cursor])) + else if (psyc_is_numeric(state->buffer.data[state->cursor])) state->type = PSYC_LIST_BINARY; else return PSYC_PARSE_LIST_ERROR_TYPE; @@ -460,13 +460,13 @@ PsycParseListRC psyc_parse_list (PsycParseListState *state, PsycString *elem) if (state->type == PSYC_LIST_TEXT) { - elem->ptr = state->buffer.ptr + state->cursor; + elem->data = state->buffer.data + state->cursor; elem->length = 0; if (state->cursor >= state->buffer.length) return PSYC_PARSE_LIST_END; - while (state->buffer.ptr[state->cursor] != '|') + while (state->buffer.data[state->cursor] != '|') { elem->length++; if (++(state->cursor) >= state->buffer.length) @@ -480,23 +480,23 @@ PsycParseListRC psyc_parse_list (PsycParseListState *state, PsycString *elem) if (!(state->elemParsed < state->elemLength)) { // Element starts with a number. - if (psyc_is_numeric(state->buffer.ptr[state->cursor])) + if (psyc_is_numeric(state->buffer.data[state->cursor])) { do { - state->elemLength = 10 * state->elemLength + state->buffer.ptr[state->cursor] - '0'; + state->elemLength = 10 * state->elemLength + state->buffer.data[state->cursor] - '0'; ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_LIST_INCOMPLETE); } - while (psyc_is_numeric(state->buffer.ptr[state->cursor])); + while (psyc_is_numeric(state->buffer.data[state->cursor])); } else return PSYC_PARSE_LIST_ERROR_LEN; - if (state->buffer.ptr[state->cursor] != ' ') + if (state->buffer.data[state->cursor] != ' ') return PSYC_PARSE_LIST_ERROR_LEN; state->cursor++; - elem->ptr = state->buffer.ptr + state->cursor; + elem->data = state->buffer.data + state->cursor; elem->length = 0; state->elemParsed = 0; } @@ -513,7 +513,7 @@ PsycParseListRC psyc_parse_list (PsycParseListState *state, PsycString *elem) if (state->cursor >= state->buffer.length) return PSYC_PARSE_LIST_END; - if (state->buffer.ptr[state->cursor] != '|') + if (state->buffer.data[state->cursor] != '|') return PSYC_PARSE_LIST_ERROR_DELIM; state->cursor++; diff --git a/src/render.c b/src/render.c index e310419..68f2fd9 100644 --- a/src/render.c +++ b/src/render.c @@ -22,7 +22,7 @@ PsycRenderListRC psyc_render_list (PsycList *list, char *buffer, size_t buflen) buffer[cur++] = '|'; cur += itoa(elem->length, buffer + cur, 10); buffer[cur++] = ' '; - memcpy(buffer + cur, elem->ptr, elem->length); + memcpy(buffer + cur, elem->data, elem->length); cur += elem->length; } } @@ -32,7 +32,7 @@ PsycRenderListRC psyc_render_list (PsycList *list, char *buffer, size_t buflen) { elem = &list->elems[i]; buffer[cur++] = '|'; - memcpy(buffer + cur, elem->ptr, elem->length); + memcpy(buffer + cur, elem->data, elem->length); cur += elem->length; } } @@ -48,7 +48,7 @@ size_t psyc_render_modifier (PsycModifier *mod, char *buffer) size_t cur = 0; buffer[cur++] = mod->oper; - memcpy(buffer + cur, mod->name.ptr, mod->name.length); + memcpy(buffer + cur, mod->name.data, mod->name.length); cur += mod->name.length; if (cur <= 1) return cur; // error, name can't be empty @@ -60,7 +60,7 @@ size_t psyc_render_modifier (PsycModifier *mod, char *buffer) } buffer[cur++] = '\t'; - memcpy(buffer + cur, mod->value.ptr, mod->value.length); + memcpy(buffer + cur, mod->value.data, mod->value.length); cur += mod->value.length; buffer[cur++] = '\n'; @@ -96,7 +96,7 @@ PsycRenderRC psyc_render (PsycPacket *packet, char *buffer, size_t buflen) if (packet->content.length) // render raw content if present { - memcpy(buffer + cur, packet->content.ptr, packet->content.length); + memcpy(buffer + cur, packet->content.data, packet->content.length); cur += packet->content.length; } else @@ -107,13 +107,13 @@ PsycRenderRC psyc_render (PsycPacket *packet, char *buffer, size_t buflen) if (packet->method.length) // add method\n { - memcpy(buffer + cur, packet->method.ptr, packet->method.length); + memcpy(buffer + cur, packet->method.data, packet->method.length); cur += packet->method.length; buffer[cur++] = '\n'; if (packet->data.length) // add data\n { - memcpy(buffer + cur, packet->data.ptr, packet->data.length); + memcpy(buffer + cur, packet->data.data, packet->data.length); cur += packet->data.length; buffer[cur++] = '\n'; } diff --git a/src/text.c b/src/text.c index 943daff..1c48010 100644 --- a/src/text.c +++ b/src/text.c @@ -3,8 +3,8 @@ PsycTextRC psyc_text (PsycTextState *state, PsycTextCB getValue, void* extra) { - const char *start = state->tmpl.ptr, *end; // start & end of variable name - const char *prev = state->tmpl.ptr + state->cursor; + const char *start = state->tmpl.data, *end; // start & end of variable name + const char *prev = state->tmpl.data + state->cursor; PsycString value; int ret; size_t len; @@ -12,20 +12,20 @@ PsycTextRC psyc_text (PsycTextState *state, PsycTextCB getValue, void* extra) while (state->cursor < state->tmpl.length) { - start = memmem(state->tmpl.ptr + state->cursor, + start = memmem(state->tmpl.data + state->cursor, state->tmpl.length - state->cursor, - state->open.ptr, state->open.length); + state->open.data, state->open.length); if (!start) break; - state->cursor = (start - state->tmpl.ptr) + state->open.length; + state->cursor = (start - state->tmpl.data) + state->open.length; if (state->cursor >= state->tmpl.length) break; // [ at the end - end = memmem(state->tmpl.ptr + state->cursor, + end = memmem(state->tmpl.data + state->cursor, state->tmpl.length - state->cursor, - state->close.ptr, state->close.length); - state->cursor = (end - state->tmpl.ptr) + state->close.length; + state->close.data, state->close.length); + state->cursor = (end - state->tmpl.data) + state->close.length; if (!end) break; // ] not found @@ -45,25 +45,25 @@ PsycTextRC psyc_text (PsycTextState *state, PsycTextCB getValue, void* extra) len = start - prev; if (state->written + len > state->buffer.length) { - state->cursor = prev - state->tmpl.ptr; + state->cursor = prev - state->tmpl.data; return PSYC_TEXT_INCOMPLETE; } - memcpy((void *)(state->buffer.ptr + state->written), prev, len); + memcpy((void *)(state->buffer.data + state->written), prev, len); state->written += len; // now substitute the value if there's enough buffer space if (state->written + value.length > state->buffer.length) { - state->cursor = start - state->tmpl.ptr; + state->cursor = start - state->tmpl.data; return PSYC_TEXT_INCOMPLETE; } - memcpy((void *)(state->buffer.ptr + state->written), value.ptr, value.length); + memcpy((void *)(state->buffer.data + state->written), value.data, value.length); state->written += value.length; // mark the start of the next chunk of text in the template - prev = state->tmpl.ptr + state->cursor; + prev = state->tmpl.data + state->cursor; no_subst = 0; } @@ -71,11 +71,11 @@ PsycTextRC psyc_text (PsycTextState *state, PsycTextCB getValue, void* extra) return PSYC_TEXT_NO_SUBST; // copy the rest of the template after the last var - len = state->tmpl.length - (prev - state->tmpl.ptr); + len = state->tmpl.length - (prev - state->tmpl.data); if (state->written + len > state->buffer.length) return PSYC_TEXT_INCOMPLETE; - memcpy((void *)(state->buffer.ptr + state->written), prev, len); + memcpy((void *)(state->buffer.data + state->written), prev, len); state->written += len; return PSYC_TEXT_COMPLETE; diff --git a/src/uniform.c b/src/uniform.c index 6dab7b7..26b83bf 100644 --- a/src/uniform.c +++ b/src/uniform.c @@ -10,13 +10,13 @@ int psyc_uniform_parse (PsycUniform *uni, char *str, size_t length) size_t pos = 0, part = PSYC_UNIFORM_SCHEME; uni->valid = 0; - uni->full.ptr = str; + uni->full.data = str; uni->full.length = length; while (pos < length) { c = str[pos]; if (c == ':') { - uni->scheme.ptr = str; + uni->scheme.data = str; uni->scheme.length = pos++; break; } else if (!psyc_is_host_char(c)) @@ -26,14 +26,14 @@ int psyc_uniform_parse (PsycUniform *uni, char *str, size_t length) p = &uni->scheme; if (p->length == 4 && - tolower(p->ptr[0]) == 'p' && - tolower(p->ptr[1]) == 's' && - tolower(p->ptr[2]) == 'y' && - tolower(p->ptr[3]) == 'c') { + tolower(p->data[0]) == 'p' && + tolower(p->data[1]) == 's' && + tolower(p->data[2]) == 'y' && + tolower(p->data[3]) == 'c') { uni->type = PSYC_SCHEME_PSYC; part = PSYC_UNIFORM_SLASHES; - uni->slashes.ptr = str + pos; + uni->slashes.data = str + pos; uni->slashes.length = 0; while (pos < length) { @@ -46,7 +46,7 @@ int psyc_uniform_parse (PsycUniform *uni, char *str, size_t length) if (uni->slashes.length == 2) { part = PSYC_UNIFORM_HOST; - uni->host.ptr = str + pos + 1; + uni->host.data = str + pos + 1; uni->host.length = 0; } break; @@ -69,7 +69,7 @@ int psyc_uniform_parse (PsycUniform *uni, char *str, size_t length) } else return PSYC_PARSE_UNIFORM_INVALID_HOST; - p->ptr = str + pos + 1; + p->data = str + pos + 1; p->length = 0; break; @@ -84,13 +84,13 @@ int psyc_uniform_parse (PsycUniform *uni, char *str, size_t length) if (c == '/') { part = PSYC_UNIFORM_RESOURCE; - uni->resource.ptr = str + pos + 1; + uni->resource.data = str + pos + 1; uni->resource.length = 0; break; } else { part = PSYC_UNIFORM_TRANSPORT; - uni->transport.ptr = str + pos; + uni->transport.data = str + pos; uni->transport.length = 0; } // fall thru @@ -109,7 +109,7 @@ int psyc_uniform_parse (PsycUniform *uni, char *str, size_t length) break; case '/': part = PSYC_UNIFORM_RESOURCE; - uni->resource.ptr = str + pos + 1; + uni->resource.data = str + pos + 1; uni->resource.length = 0; break; default: @@ -123,7 +123,7 @@ int psyc_uniform_parse (PsycUniform *uni, char *str, size_t length) break; } else if (c == '#') { part = PSYC_UNIFORM_CHANNEL; - uni->channel.ptr = str + pos + 1; + uni->channel.data = str + pos + 1; uni->channel.length = 0; break; } else return PSYC_PARSE_UNIFORM_INVALID_RESOURCE; @@ -140,20 +140,20 @@ int psyc_uniform_parse (PsycUniform *uni, char *str, size_t length) if (uni->host.length == 0) return PSYC_PARSE_UNIFORM_INVALID_HOST; - uni->host_port.ptr = uni->host.ptr; + uni->host_port.data = uni->host.data; uni->host_port.length = uni->host.length + uni->port.length + uni->transport.length; if (uni->port.length > 0 || uni->transport.length > 0) uni->host_port.length++; - uni->root.ptr = str; + uni->root.data = str; uni->root.length = uni->scheme.length + 1 + uni->slashes.length + uni->host_port.length; - uni->body.ptr = uni->host.ptr; + uni->body.data = uni->host.data; uni->body.length = length - uni->scheme.length - 1 - uni->slashes.length; if (uni->resource.length) { - uni->nick.ptr = uni->resource.ptr + 1; + uni->nick.data = uni->resource.data + 1; uni->nick.length = uni->resource.length; } diff --git a/src/variable.c b/src/variable.c index a55b37c..72cc839 100644 --- a/src/variable.c +++ b/src/variable.c @@ -27,7 +27,7 @@ const PsycString psyc_routing_vars[] = }; // Variable types in alphabetical order. -const PsycMatchVar psyc_var_types[] = +const PsycDictInt psyc_var_types[] = { {PSYC_C2STR("_amount"), PSYC_TYPE_AMOUNT}, {PSYC_C2STR("_color"), PSYC_TYPE_COLOR}, @@ -72,9 +72,9 @@ PsycBool psyc_var_is_routing (const char *name, size_t len) { if (matching[i] < 0) break; // reached the end of possible matches - if (psyc_routing_vars[matching[i]].ptr[cursor] == name[cursor]) + if (psyc_routing_vars[matching[i]].data[cursor] == name[cursor]) matching[m++] = matching[i]; // found a match, update matching indexes - else if (psyc_routing_vars[matching[i]].ptr[cursor] > name[cursor]) + else if (psyc_routing_vars[matching[i]].data[cursor] > name[cursor]) break; // passed the possible matches in alphabetical order in the array } @@ -94,6 +94,6 @@ inline PsycType psyc_var_type (const char *name, size_t len) { int8_t m[psyc_var_types_num]; - return psyc_in_array(psyc_var_types, psyc_var_types_num, - name, len, PSYC_YES, (int8_t*)&m); + return (PsycType) psyc_dict_lookup((PsycDict*)psyc_var_types, psyc_var_types_num, + name, len, PSYC_YES, (int8_t*)&m); } diff --git a/test/test_list.c b/test/test_list.c index dd0be16..e4ebb39 100644 --- a/test/test_list.c +++ b/test/test_list.c @@ -48,9 +48,9 @@ int main (int argc, char **argv) { case PSYC_PARSE_LIST_END: ret = 0; case PSYC_PARSE_LIST_ELEM: - if (verbose) printf("|%d: %.*s... (%ld)\n", i, 10, elem.ptr, elem.length); + if (verbose) printf("|%d: %.*s... (%ld)\n", i, 10, elem.data, elem.length); //elems[i] = malloc(elem.length); - //memcpy(&elems[i++], elem.ptr, elem.length); + //memcpy(&elems[i++], elem.data, elem.length); break; default: printf("# Error while parsing list: %i\n", ret); @@ -76,10 +76,10 @@ int main (int argc, char **argv) { case PSYC_PARSE_LIST_END: ret = 0; case PSYC_PARSE_LIST_ELEM: - //if (verbose) printf("|%.*s\n", (int)elem.length, elem.ptr); - if (verbose) printf("|%d: %.*s... (%ld)\n", i, 10, elem.ptr, elem.length); + //if (verbose) printf("|%.*s\n", (int)elem.length, elem.data); + if (verbose) printf("|%d: %.*s... (%ld)\n", i, 10, elem.data, elem.length); elems[i] = malloc(elem.length); - memcpy(elems[i++], elem.ptr, elem.length); + memcpy(elems[i++], elem.data, elem.length); break; default: printf("# Error while parsing list: %i\n", ret); @@ -111,7 +111,7 @@ int main (int argc, char **argv) { elems2 = malloc((i+1) * sizeof(char*)); elems2[i] = malloc(elem.length); - memcpy(elems2[i++], elem.ptr, elem.length); + memcpy(elems2[i++], elem.data, elem.length); break; default: printf("# Error while parsing list: %i\n", ret); @@ -145,7 +145,7 @@ int main (int argc, char **argv) { */ elems2 = malloc(sizeof(char*)); elems2[i] = malloc(elem.length); - memcpy(elems2[i], elem.ptr, elem.length); + memcpy(elems2[i], elem.data, elem.length); break; default: printf("# Error while parsing list: %i\n", ret); @@ -191,7 +191,7 @@ int main (int argc, char **argv) { ret = 0; case PSYC_PARSE_LIST_ELEM: elems2[i] = malloc(elem.length); - memcpy(elems2[i++], elem.ptr, elem.length); + memcpy(elems2[i++], elem.data, elem.length); break; default: printf("# Error while parsing list: %i\n", ret); diff --git a/test/test_parser.c b/test/test_parser.c index 43d5ed9..4d2c4e4 100644 --- a/test/test_parser.c +++ b/test/test_parser.c @@ -53,8 +53,8 @@ int main (int argc, char **argv) // printf("the string is '%.*s'\n", name); if (verbose) printf("%.*s = %.*s\n", - (int)name.length, name.ptr, - (int)value.length, value.ptr); + (int)name.length, name.data, + (int)value.length, value.data); if (psyc_var_is_list(PSYC_S2ARG(name))) { @@ -71,7 +71,7 @@ int main (int argc, char **argv) case PSYC_PARSE_LIST_END: case PSYC_PARSE_LIST_ELEM: if (verbose) - printf("|%.*s\n", (int)elem.length, elem.ptr); + printf("|%.*s\n", (int)elem.length, elem.data); break; default: printf("Error while parsing list: %i\n", ret); diff --git a/test/test_psyc.c b/test/test_psyc.c index 43bbbd6..d18bc7a 100644 --- a/test/test_psyc.c +++ b/test/test_psyc.c @@ -82,7 +82,7 @@ int test_input (int i, char *recvbuf, size_t nbytes) { do { if (verbose >= 3) - printf("\n# buffer = [%.*s]\n# part = %d\n", (int)parser->buffer.length, parser->buffer.ptr, parser->part); + printf("\n# buffer = [%.*s]\n# part = %d\n", (int)parser->buffer.length, parser->buffer.data, parser->part); // Parse the next part of the packet (a routing/entity modifier or the body) ret = exit_code = psyc_parse(parser, &oper, &name, &value); if (verbose >= 2) @@ -222,15 +222,15 @@ int test_input (int i, char *recvbuf, size_t nbytes) { } if (name.length) { - pname->ptr = malloc(name.length); + pname->data = malloc(name.length); pname->length = name.length; - assert(pname->ptr != NULL); - memcpy((void*)pname->ptr, name.ptr, name.length); + assert(pname->data != NULL); + memcpy((void*)pname->data, name.data, name.length); name.length = 0; if (verbose >= 2) - printf("%.*s = ", (int)pname->length, pname->ptr); + printf("%.*s = ", (int)pname->length, pname->data); } if (value.length) { @@ -239,15 +239,15 @@ int test_input (int i, char *recvbuf, size_t nbytes) { len = psyc_parse_value_length(parser); else len = value.length; - pvalue->ptr = malloc(len); + pvalue->data = malloc(len); } - assert(pvalue->ptr != NULL); - memcpy((void*)pvalue->ptr + pvalue->length, value.ptr, value.length); + assert(pvalue->data != NULL); + memcpy((void*)pvalue->data + pvalue->length, value.data, value.length); pvalue->length += value.length; value.length = 0; if (verbose >= 2) { - printf("[%.*s]", (int)pvalue->length, pvalue->ptr); + printf("[%.*s]", (int)pvalue->length, pvalue->data); if (parser->valueLength > pvalue->length) printf("..."); printf("\n"); @@ -284,7 +284,7 @@ int test_input (int i, char *recvbuf, size_t nbytes) { retl = 0; case PSYC_PARSE_LIST_ELEM: if (verbose >= 2) { - printf("|%.*s\n", (int)elem.length, elem.ptr); + printf("|%.*s\n", (int)elem.length, elem.data); if (ret == PSYC_PARSE_LIST_END) printf("## LIST END"); } @@ -311,9 +311,9 @@ static inline void resetString (PsycString *s, uint8_t freeptr) { if (freeptr && s->length) - free((void*)s->ptr); + free((void*)s->data); - s->ptr = NULL; + s->data = NULL; s->length = 0; } diff --git a/test/test_text.c b/test/test_text.c index cd1552d..d776e3b 100644 --- a/test/test_text.c +++ b/test/test_text.c @@ -11,7 +11,7 @@ PsycTextValueRC getValueFooBar (const char *name, size_t len, PsycString *value, { if (verbose) printf("> getValue: %.*s\n", (int)len, name); - value->ptr = "Foo Bar"; + value->data = "Foo Bar"; value->length = 7; return PSYC_TEXT_VALUE_FOUND; } @@ -20,7 +20,7 @@ PsycTextValueRC getValueEmpty (const char *name, size_t len, PsycString *value, { if (verbose) printf("> getValue: %.*s\n", (int)len, name); - value->ptr = ""; + value->data = ""; value->length = 0; return PSYC_TEXT_VALUE_FOUND; } @@ -54,7 +54,7 @@ int testText (char *template, size_t tmplen, char *buffer, size_t buflen, PsycSt if (verbose) printf("%.*s\n", (int)length, buffer); result->length = length; - result->ptr = buffer; + result->data = buffer; return ret; case PSYC_TEXT_NO_SUBST: if (verbose) @@ -78,11 +78,11 @@ int main(int argc, char **argv) int i; testText(str, len, buffer, BUFSIZE, &result, &getValueFooBar); - if (memcmp(result.ptr, PSYC_C2ARG("Hello Foo Bar & Foo Bar!"))) + if (memcmp(result.data, PSYC_C2ARG("Hello Foo Bar & Foo Bar!"))) return 1; testText(str, len, buffer, BUFSIZE, &result, &getValueEmpty); - if (memcmp(result.ptr, PSYC_C2ARG("Hello & !"))) + if (memcmp(result.data, PSYC_C2ARG("Hello & !"))) return 2; if (testText(str, len, buffer, BUFSIZE, &result, &getValueNotFound) != PSYC_TEXT_NO_SUBST) @@ -91,7 +91,7 @@ int main(int argc, char **argv) for (i = 1; i < 22; i++) { testText(str, len, buffer, i, &result, &getValueFooBar); - if (memcmp(result.ptr, PSYC_C2ARG("Hello Foo Bar & Foo Bar!"))) + if (memcmp(result.data, PSYC_C2ARG("Hello Foo Bar & Foo Bar!"))) return 10 + i; } From ed5feee0e316a1003a12bb78de01bcd24c050c6e Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 1 Nov 2011 12:22:30 +0100 Subject: [PATCH 335/378] added entity & slash to uniform struct --- include/psyc/uniform.h | 4 +++- src/uniform.c | 12 ++++++++++++ test/uniform_parse.c | 3 ++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/include/psyc/uniform.h b/include/psyc/uniform.h index bf1d84c..332367e 100644 --- a/include/psyc/uniform.h +++ b/include/psyc/uniform.h @@ -32,8 +32,10 @@ typedef struct { PsycString body; // the URL without scheme and '//' PsycString user_host; // mailto and xmpp style PsycString host_port; // just host:port (and transport) - PsycString root; // root UNI of peer/server + PsycString root; // root UNI + PsycString entity; // entity UNI, without the channel PsycString slashes; // the // if the protocol has them + PsycString slash; // first / after host PsycString nick; // whatever works as a nickname } PsycUniform; diff --git a/src/uniform.c b/src/uniform.c index 26b83bf..d888423 100644 --- a/src/uniform.c +++ b/src/uniform.c @@ -64,6 +64,9 @@ int psyc_uniform_parse (PsycUniform *uni, char *str, size_t length) part = PSYC_UNIFORM_PORT; p = &uni->port; } else if (c == '/') { + uni->slash.data = str + pos; + uni->slash.length = 1; + part = PSYC_UNIFORM_RESOURCE; p = &uni->resource; } @@ -83,6 +86,9 @@ int psyc_uniform_parse (PsycUniform *uni, char *str, size_t length) return PSYC_PARSE_UNIFORM_INVALID_PORT; if (c == '/') { + uni->slash.data = str + pos; + uni->slash.length = 1; + part = PSYC_UNIFORM_RESOURCE; uni->resource.data = str + pos + 1; uni->resource.length = 0; @@ -108,6 +114,9 @@ int psyc_uniform_parse (PsycUniform *uni, char *str, size_t length) uni->transport.length++; break; case '/': + uni->slash.data = str + pos; + uni->slash.length = 1; + part = PSYC_UNIFORM_RESOURCE; uni->resource.data = str + pos + 1; uni->resource.length = 0; @@ -149,6 +158,9 @@ int psyc_uniform_parse (PsycUniform *uni, char *str, size_t length) uni->root.length = uni->scheme.length + 1 + uni->slashes.length + uni->host_port.length; + uni->entity.data = str; + uni->entity.length = uni->root.length + uni->slash.length + uni->resource.length; + uni->body.data = uni->host.data; uni->body.length = length - uni->scheme.length - 1 - uni->slashes.length; diff --git a/test/uniform_parse.c b/test/uniform_parse.c index 1a466fa..0b82b61 100644 --- a/test/uniform_parse.c +++ b/test/uniform_parse.c @@ -10,7 +10,7 @@ testUniform (char *str, int ret) { printf("%s\n", str); int r = psyc_uniform_parse(uni, str, strlen(str)); - PP(("[%.*s] : [%.*s] [%.*s] : [%.*s] [%.*s] / [%.*s] # [%.*s]\n[%.*s] [%.*s]\n[%.*s]\n\n", + PP(("[%.*s] : [%.*s] [%.*s] : [%.*s] [%.*s] / [%.*s] # [%.*s]\n[%.*s]\n[%.*s] [%.*s]\n[%.*s]\n\n", (int)PSYC_S2ARG2(uni->scheme), (int)PSYC_S2ARG2(uni->slashes), (int)PSYC_S2ARG2(uni->host), @@ -18,6 +18,7 @@ testUniform (char *str, int ret) { (int)PSYC_S2ARG2(uni->transport), (int)PSYC_S2ARG2(uni->resource), (int)PSYC_S2ARG2(uni->channel), + (int)PSYC_S2ARG2(uni->entity), (int)PSYC_S2ARG2(uni->root), (int)PSYC_S2ARG2(uni->nick), (int)PSYC_S2ARG2(uni->body))); From 68a0959795e66c7797d7d70dc00f1c62837a6d93 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 1 Nov 2011 22:24:35 +0100 Subject: [PATCH 336/378] c2arg2 --- include/psyc.h | 1 + include/psyc/packet.h | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/psyc.h b/include/psyc.h index b980a3d..4bcf520 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -24,6 +24,7 @@ #define PSYC_C2STR(str) {sizeof(str)-1, str} #define PSYC_C2ARG(str) str, sizeof(str)-1 +#define PSYC_C2ARG2(str) sizeof(str)-1, str #define PSYC_S2ARG(str) (str).data, (str).length #define PSYC_S2ARG2(str) (str).length, (str).data diff --git a/include/psyc/packet.h b/include/psyc/packet.h index 9608c2c..b72b912 100644 --- a/include/psyc/packet.h +++ b/include/psyc/packet.h @@ -126,8 +126,8 @@ static inline PsycModifier psyc_modifier_new (char oper, char *name, size_t namelen, char *value, size_t valuelen, - PsycModifierFlag flag){ - + PsycModifierFlag flag) +{ PsycModifier m = {oper, {namelen, name}, {valuelen, value}, flag}; if (flag == PSYC_MODIFIER_CHECK_LENGTH) // find out if it needs a length From 19c7cadad210baf57a00508d103e8669e1df9020 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Thu, 3 Nov 2011 14:15:42 +0100 Subject: [PATCH 337/378] unsigned number parsing --- include/psyc/parse.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/include/psyc/parse.h b/include/psyc/parse.h index 0b9c737..2f8b31d 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -387,7 +387,7 @@ static inline PsycParseListRC psyc_parse_list (PsycParseListState *state, PsycString *elem); static inline -PsycBool psyc_parse_number (const char *value, size_t len, ssize_t *n) +PsycBool psyc_parse_number (const char *value, size_t len, int64_t *n) { size_t c = 0; uint8_t neg = 0; @@ -411,6 +411,20 @@ PsycBool psyc_parse_number (const char *value, size_t len, ssize_t *n) return PSYC_TRUE; } +static inline +PsycBool psyc_parse_number_unsigned (const char *value, size_t len, uint64_t *n) +{ + size_t c = 0; + if (!value) + return PSYC_FALSE; + + *n = 0; + while (c < len && value[c] >= '0' && value[c] <= '9') + *n = 10 * *n + (value[c++] - '0'); + + return c == len ? PSYC_TRUE : PSYC_FALSE; +} + static inline PsycBool psyc_parse_time (const char *value, size_t len, time_t *t) { From 8906e675290ef15dd1cefc86a2c0d9c266c3236e Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Thu, 3 Nov 2011 14:27:01 +0100 Subject: [PATCH 338/378] refactoring - init functions --- .gitignore | 9 +++-- d/include/psyc/packet.d | 32 +++++++++------- d/include/psyc/render.d | 6 +-- include/psyc.h | 25 +------------ include/psyc/packet.h | 43 +++++++++++----------- include/psyc/render.h | 6 +-- pike/psyc.cmod | 81 +++++++++++++++++++---------------------- src/packet.c | 50 ++++++++++++------------- test/test_list.c | 4 +- test/test_render.c | 75 ++++++++++++++++++++------------------ 10 files changed, 158 insertions(+), 173 deletions(-) diff --git a/.gitignore b/.gitignore index d3efafe..bfa0c96 100644 --- a/.gitignore +++ b/.gitignore @@ -43,7 +43,8 @@ python/*.py *.rej *.log *.pem -*old -*bak -*diff -*orig +*.old +*.bak +*.orig +*.diff +*.patch diff --git a/d/include/psyc/packet.d b/d/include/psyc/packet.d index a2e5648..eb1b2a4 100644 --- a/d/include/psyc/packet.d +++ b/d/include/psyc/packet.d @@ -142,13 +142,17 @@ struct Packet char[] method, ubyte[] data, PacketFlag flag = PacketFlag.CHECK_LENGTH) { - return psyc_packet_new(&routing, &entity, cast(ubyte[]*)&method, &data, flag); // FIXME + Packet p; + psyc_packet_init(&p, &routing, &entity, cast(ubyte[]*)&method, &data, flag); // FIXME + return p; } static Packet opCall (Modifier[] routing, ubyte[] content, PacketFlag flag = PacketFlag.CHECK_LENGTH) { - return psyc_packet_new_raw(&routing, &content, flag); // FIXME + Packet p; + psyc_packet_init_raw(&routing, &content, flag); // FIXME + return p; } size_t length ( ) @@ -215,17 +219,19 @@ PacketFlag psyc_packet_length_check (Packet *p); private size_t psyc_packet_length_set (Packet *p); /** Create new list. */ -List psyc_list_new (String *elems, size_t num_elems, ListFlag flag); +void psyc_list_init (List *list, String *elems, size_t num_elems, ListFlag flag); -/** Create new packet. */ -Packet psyc_packet_new (Modifier *routing, size_t routinglen, - Modifier *entity, size_t entitylen, - char *method, size_t methodlen, - char *data, size_t datalen, - PacketFlag flag); +/** Initialize packet. */ +void psyc_packet_init (Packet packet, + Modifier *routing, size_t routinglen, + Modifier *entity, size_t entitylen, + char *method, size_t methodlen, + char *data, size_t datalen, + PacketFlag flag); -/** Create new packet with raw content. */ -Packet psyc_packet_new_raw (Modifier *routing, size_t routinglen, - char *content, size_t contentlen, - PacketFlag flag); +/** Initialize packet with raw content. */ +void psyc_packet_init_raw (Packet packet, + Modifier *routing, size_t routinglen, + char *content, size_t contentlen, + PacketFlag flag); diff --git a/d/include/psyc/render.d b/d/include/psyc/render.d index d1dd0e4..44d1b0b 100644 --- a/d/include/psyc/render.d +++ b/d/include/psyc/render.d @@ -45,9 +45,9 @@ enum RenderListRC * This function renders packet->length bytes to the buffer, * if buflen is less than that an error is returned. * - * @see psyc_packet_new - * @see psyc_packet_new_raw - * @see psyc_packet_length_set + * @see psyc_packet_init() + * @see psyc_packet_init_raw() + * @see psyc_packet_length_set() */ RenderRC psyc_render (Packet *packet, ubyte *buffer, size_t buflen); diff --git a/include/psyc.h b/include/psyc.h index 4bcf520..b059dab 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -20,7 +20,8 @@ #include #include -#define PSYC_EPOCH 1440444041 // 2015-08-24 21:20:41 CET (Monday) +#define PSYC_VERSION 1 +#define PSYC_EPOCH 1440444041 // 2015-08-24 21:20:41 CET (Monday) #define PSYC_C2STR(str) {sizeof(str)-1, str} #define PSYC_C2ARG(str) str, sizeof(str)-1 @@ -118,28 +119,6 @@ typedef struct intptr_t value; } PsycDictInt; -/** - * Shortcut for creating a PsycString. - * - * @param str Pointer to the buffer. - * @param len Length of that buffer. - * - * @return An instance of the PsycString struct. - */ -static inline -PsycString psyc_string_new (char *str, size_t len) -{ - PsycString s = {len, str}; - return s; -} - -static inline -unsigned int psyc_version () -{ - return 1; -} - - /** * Checks if long keyword string inherits from short keyword string. */ diff --git a/include/psyc/packet.h b/include/psyc/packet.h index b72b912..4777a84 100644 --- a/include/psyc/packet.h +++ b/include/psyc/packet.h @@ -121,19 +121,17 @@ PsycModifierFlag psyc_modifier_length_check (PsycModifier *m) return flag; } -/** Create new modifier */ +/** Initialize modifier */ static inline -PsycModifier psyc_modifier_new (char oper, - char *name, size_t namelen, - char *value, size_t valuelen, - PsycModifierFlag flag) +void psyc_modifier_init (PsycModifier *m, char oper, + char *name, size_t namelen, + char *value, size_t valuelen, + PsycModifierFlag flag) { - PsycModifier m = {oper, {namelen, name}, {valuelen, value}, flag}; + *m = (PsycModifier) {oper, {namelen, name}, {valuelen, value}, flag}; if (flag == PSYC_MODIFIER_CHECK_LENGTH) // find out if it needs a length - m.flag = psyc_modifier_length_check(&m); - - return m; + m->flag = psyc_modifier_length_check(m); } /** @@ -165,20 +163,23 @@ PsycPacketFlag psyc_packet_length_check (PsycPacket *p); */ size_t psyc_packet_length_set (PsycPacket *p); -/** Create new list. */ -PsycList psyc_list_new (PsycString *elems, size_t num_elems, PsycListFlag flag); +/** Initialize list. */ +void psyc_list_init (PsycList *list, PsycString *elems, size_t num_elems, + PsycListFlag flag); -/** Create new packet. */ -PsycPacket psyc_packet_new (PsycModifier *routing, size_t routinglen, - PsycModifier *entity, size_t entitylen, - char *method, size_t methodlen, - char *data, size_t datalen, - PsycPacketFlag flag); +/** Initialize packet. */ +void psyc_packet_init (PsycPacket *packet, + PsycModifier *routing, size_t routinglen, + PsycModifier *entity, size_t entitylen, + char *method, size_t methodlen, + char *data, size_t datalen, + PsycPacketFlag flag); -/** Create new packet with raw content. */ -PsycPacket psyc_packet_new_raw (PsycModifier *routing, size_t routinglen, - char *content, size_t contentlen, - PsycPacketFlag flag); +/** Initialize packet with raw content. */ +void psyc_packet_init_raw (PsycPacket *packet, + PsycModifier *routing, size_t routinglen, + char *content, size_t contentlen, + PsycPacketFlag flag); /** @} */ // end of packet group diff --git a/include/psyc/render.h b/include/psyc/render.h index 5b64804..9b18af6 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -52,9 +52,9 @@ typedef enum * This function renders packet->length bytes to the buffer, * if buflen is less than that an error is returned. * - * @see psyc_packet_new - * @see psyc_packet_new_raw - * @see psyc_packet_length_set + * @see psyc_packet_init() + * @see psyc_packet_init_raw() + * @see psyc_packet_length_set() */ #ifdef __INLINE_PSYC_RENDER static inline diff --git a/pike/psyc.cmod b/pike/psyc.cmod index 211ab81..2ec7c9f 100644 --- a/pike/psyc.cmod +++ b/pike/psyc.cmod @@ -1,12 +1,12 @@ -#include "global.h" -#include "interpret.h" -#include "stralloc.h" -#include "mapping.h" +#include "global.h" +#include "interpret.h" +#include "stralloc.h" +#include "mapping.h" #include "array.h" -#include "svalue.h" -#include "operators.h" -#include "array.h" -#include "builtin_functions.h" +#include "svalue.h" +#include "operators.h" +#include "array.h" +#include "builtin_functions.h" #include "module.h" #include @@ -37,7 +37,7 @@ PsycTextValueRC lookup_value_mapping(const char *name, size_t len, PsycString *v //printf("lookup_value_mapping called for %.*s\n", (int) len, name); struct pike_string *key = make_shared_binary_string(name, len); struct mapping *m = (struct mapping *) extra; - struct svalue *s = low_mapping_string_lookup(m, key); + struct svalue *s = low_mapping_string_lookup(m, key); free_string(key); if (s == NULL) { @@ -125,17 +125,15 @@ PIKEFUN string render(mapping rvars, mapping evars, string method, string|void b // fill headers rheaders.lines = 0; - rheaders.modifiers = malloc(sizeof(PsycModifier) * rvars->data->size); + rheaders.modifiers = malloc(sizeof(PsycModifier) * rvars->data->size); NEW_MAPPING_LOOP(rvars->data) { if (k->ind.type == PIKE_T_STRING) { switch(k->val.type) { case PIKE_T_STRING: - rheaders.modifiers[rheaders.lines++] = psyc_modifier_new(oper, - (char *)STR0(k->ind.u.string), - k->ind.u.string->len, - (char *)STR0(k->val.u.string), - k->val.u.string->len, - PSYC_MODIFIER_ROUTING); + psyc_modifier_init(&rheaders.modifiers[rheaders.lines++], oper, + (char *)STR0(k->ind.u.string), k->ind.u.string->len, + (char *)STR0(k->val.u.string), k->val.u.string->len, + PSYC_MODIFIER_ROUTING); break; default: Pike_error("psyc render: unsupported non-string value in rvars\n"); @@ -147,7 +145,7 @@ PIKEFUN string render(mapping rvars, mapping evars, string method, string|void b } eheaders.lines = 0; - eheaders.modifiers = malloc(sizeof(PsycModifier) * evars->data->size); + eheaders.modifiers = malloc(sizeof(PsycModifier) * evars->data->size); NEW_MAPPING_LOOP(evars->data) { if (k->ind.type == PIKE_T_STRING) { char *key; @@ -157,7 +155,7 @@ PIKEFUN string render(mapping rvars, mapping evars, string method, string|void b struct pike_string *s; key = (char *) STR0(k->ind.u.string); - keylen = k->ind.u.string->len; + keylen = k->ind.u.string->len; switch(k->val.type) { case PIKE_T_INT: @@ -197,7 +195,7 @@ PIKEFUN string render(mapping rvars, mapping evars, string method, string|void b Pike_error("psyc_render: unsupported data type in list\n"); } } - list = psyc_list_new(elems, k->val.u.array->size, PSYC_LIST_CHECK_LENGTH); + psyc_list_init(&list, elems, k->val.u.array->size, PSYC_LIST_CHECK_LENGTH); struct pike_string *listbuf = begin_shared_string(list.length); psyc_render_list(&list, (char *) STR0(listbuf), listbuf->len); @@ -211,37 +209,32 @@ PIKEFUN string render(mapping rvars, mapping evars, string method, string|void b Pike_error("psyc_render: unsupported value in evars\n"); break; } - eheaders.modifiers[eheaders.lines++] = psyc_modifier_new(oper, - key, keylen, - val, vallen, - PSYC_MODIFIER_CHECK_LENGTH); + psyc_modifier_init(&eheaders.modifiers[eheaders.lines++], oper, + key, keylen, + val, vallen, + PSYC_MODIFIER_CHECK_LENGTH); } else { Pike_error("psyc render: unsupported non-string key in evars\n"); } } if (body != NULL) { - packet = psyc_packet_new(rheaders.modifiers, - rheaders.lines, - eheaders.modifiers, - eheaders.lines, - (const char *)STR0(method), method->len, - (const char *)STR0(body), body->len, - PSYC_PACKET_CHECK_LENGTH); + psyc_packet_init(&packet, rheaders.modifiers, rheaders.lines, + eheaders.modifiers, eheaders.lines, + (const char *)STR0(method), method->len, + (const char *)STR0(body), body->len, + PSYC_PACKET_CHECK_LENGTH); } else { // body arg was not given - packet = psyc_packet_new(rheaders.modifiers, - rheaders.lines, - eheaders.modifiers, - eheaders.lines, - (const char *)STR0(method), method->len, - NULL, 0, - PSYC_PACKET_CHECK_LENGTH); + psyc_packet_init(&packet, rheaders.modifiers, rheaders.lines, + eheaders.modifiers, eheaders.lines, + (const char *)STR0(method), method->len, + NULL, 0, PSYC_PACKET_CHECK_LENGTH); } struct pike_string *s = begin_shared_string(packet.length); psyc_render(&packet, (char *) STR0(s), packet.length); // pop_n_elems(args); - RETURN end_shared_string(s); + RETURN end_shared_string(s); } PIKECLASS Parser { @@ -360,7 +353,7 @@ PIKECLASS Parser { make_shared_binary_string(name.data, name.length), &sv); } else { - err = 3; + err = 3; } break; case PSYC_TYPE_FLAG: @@ -415,7 +408,7 @@ PIKECLASS Parser { make_shared_binary_string(value.data, value.length)); } } while (0); - if (err) { // there was an error while + if (err) { // there was an error while // FIXME return; } @@ -443,14 +436,14 @@ PIKECLASS Parser { push_mapping(THIS->rvars); push_mapping(THIS->evars); if (THIS->method == NULL) { - apply_low(Pike_fp->current_object, THIS->handle_packet, 2); + apply_low(Pike_fp->current_object, THIS->handle_packet, 2); } else if (THIS->body == NULL) { push_string(THIS->method); - apply_low(Pike_fp->current_object, THIS->handle_packet, 3); + apply_low(Pike_fp->current_object, THIS->handle_packet, 3); } else { push_string(THIS->method); push_string(THIS->body); - apply_low(Pike_fp->current_object, THIS->handle_packet, 4); + apply_low(Pike_fp->current_object, THIS->handle_packet, 4); } // reset packet state @@ -467,7 +460,7 @@ PIKECLASS Parser { return; default: // fatal error push_int(ret); - apply_low(Pike_fp->current_object, THIS->handle_error, 1); + apply_low(Pike_fp->current_object, THIS->handle_error, 1); // FIXME: free stuff? or do we kill the socket and parser anyway return; } diff --git a/src/packet.c b/src/packet.c index b4444e7..9862be6 100644 --- a/src/packet.c +++ b/src/packet.c @@ -48,15 +48,15 @@ PsycListFlag psyc_list_length (PsycList *list) } inline -PsycList psyc_list_new (PsycString *elems, size_t num_elems, PsycListFlag flag) +void psyc_list_init (PsycList *list, PsycString *elems, size_t num_elems, + PsycListFlag flag) { - PsycList list = {num_elems, elems, 0, flag}; + *list = (PsycList) {num_elems, elems, 0, flag}; if (flag == PSYC_LIST_CHECK_LENGTH) // check if list elements need length - list.flag = psyc_list_length_check(&list); + list->flag = psyc_list_length_check(list); - list.length = psyc_list_length(&list); - return list; + list->length = psyc_list_length(list); } @@ -134,33 +134,33 @@ size_t psyc_packet_length_set (PsycPacket *p) } inline -PsycPacket psyc_packet_new (PsycModifier *routing, size_t routinglen, - PsycModifier *entity, size_t entitylen, - char *method, size_t methodlen, - char *data, size_t datalen, - PsycPacketFlag flag) +void psyc_packet_init (PsycPacket *p, + PsycModifier *routing, size_t routinglen, + PsycModifier *entity, size_t entitylen, + char *method, size_t methodlen, + char *data, size_t datalen, + PsycPacketFlag flag) { - PsycPacket p = {{routinglen, routing}, {entitylen, entity}, - {methodlen, method}, {datalen, data}, {0,0}, 0, 0, flag}; + *p = (PsycPacket) {{routinglen, routing}, {entitylen, entity}, + {methodlen, method}, {datalen, data}, {0,0}, 0, 0, flag}; - if (flag == PSYC_PACKET_CHECK_LENGTH) // find out if it needs a length - p.flag = psyc_packet_length_check(&p); + if (flag == PSYC_PACKET_CHECK_LENGTH) // find out if it needs length + p->flag = psyc_packet_length_check(p); - psyc_packet_length_set(&p); - return p; + psyc_packet_length_set(p); } inline -PsycPacket psyc_packet_new_raw (PsycModifier *routing, size_t routinglen, - char *content, size_t contentlen, - PsycPacketFlag flag) +void psyc_packet_init_raw (PsycPacket *p, + PsycModifier *routing, size_t routinglen, + char *content, size_t contentlen, + PsycPacketFlag flag) { - PsycPacket p = {{routinglen, routing}, {0,0}, {0,0}, {0,0}, - {contentlen, content}, 0, 0, flag}; + *p = (PsycPacket) {{routinglen, routing}, {0,0}, {0,0}, {0,0}, + {contentlen, content}, 0, 0, flag}; - if (flag == PSYC_PACKET_CHECK_LENGTH) // find out if it needs a length - p.flag = psyc_packet_length_check(&p); + if (flag == PSYC_PACKET_CHECK_LENGTH) // find out if it needs length + p->flag = psyc_packet_length_check(p); - psyc_packet_length_set(&p); - return p; + psyc_packet_length_set(p); } diff --git a/test/test_list.c b/test/test_list.c index e4ebb39..36fb8c5 100644 --- a/test/test_list.c +++ b/test/test_list.c @@ -26,8 +26,8 @@ int main (int argc, char **argv) { for (i=0; i Date: Thu, 3 Nov 2011 14:44:04 +0100 Subject: [PATCH 339/378] c2str --- include/psyc.h | 3 ++- src/variable.c | 62 +++++++++++++++++++++++++------------------------- 2 files changed, 33 insertions(+), 32 deletions(-) diff --git a/include/psyc.h b/include/psyc.h index b059dab..ed8ff0d 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -23,7 +23,8 @@ #define PSYC_VERSION 1 #define PSYC_EPOCH 1440444041 // 2015-08-24 21:20:41 CET (Monday) -#define PSYC_C2STR(str) {sizeof(str)-1, str} +#define PSYC_C2STR(str) (PsycString) {sizeof(str)-1, str} +#define PSYC_C2STRI(str) {sizeof(str)-1, str} #define PSYC_C2ARG(str) str, sizeof(str)-1 #define PSYC_C2ARG2(str) sizeof(str)-1, str #define PSYC_S2ARG(str) (str).data, (str).length diff --git a/src/variable.c b/src/variable.c index 72cc839..11aa1a1 100644 --- a/src/variable.c +++ b/src/variable.c @@ -5,42 +5,42 @@ /// Routing variables in alphabetical order. const PsycString psyc_routing_vars[] = { - PSYC_C2STR("_amount_fragments"), - PSYC_C2STR("_context"), - //PSYC_C2STR("_count"), // older PSYC - PSYC_C2STR("_counter"), // the name for this is supposed to be _count, not _counter - PSYC_C2STR("_fragment"), - //PSYC_C2STR("_length"), // older PSYC - PSYC_C2STR("_source"), - //PSYC_C2STR("_source_identification"), // older PSYC - PSYC_C2STR("_source_identity"), - PSYC_C2STR("_source_relay"), - PSYC_C2STR("_source_relay_relay"), // until you have a better idea.. is this really in use? - PSYC_C2STR("_tag"), - PSYC_C2STR("_tag_relay"), - //PSYC_C2STR("_tag_reply"), // older PSYC - PSYC_C2STR("_target"), - PSYC_C2STR("_target_forward"), - PSYC_C2STR("_target_relay"), - //PSYC_C2STR("_understand_modules"), // older PSYC - //PSYC_C2STR("_using_modules"), // older PSYC + PSYC_C2STRI("_amount_fragments"), + PSYC_C2STRI("_context"), + //PSYC_C2STRI("_count"), // older PSYC + PSYC_C2STRI("_counter"), // the name for this is supposed to be _count, not _counter + PSYC_C2STRI("_fragment"), + //PSYC_C2STRI("_length"), // older PSYC + PSYC_C2STRI("_source"), + //PSYC_C2STRI("_source_identification"), // older PSYC + PSYC_C2STRI("_source_identity"), + PSYC_C2STRI("_source_relay"), + PSYC_C2STRI("_source_relay_relay"), // until you have a better idea.. is this really in use? + PSYC_C2STRI("_tag"), + PSYC_C2STRI("_tag_relay"), + //PSYC_C2STRI("_tag_reply"), // older PSYC + PSYC_C2STRI("_target"), + PSYC_C2STRI("_target_forward"), + PSYC_C2STRI("_target_relay"), + //PSYC_C2STRI("_understand_modules"), // older PSYC + //PSYC_C2STRI("_using_modules"), // older PSYC }; // Variable types in alphabetical order. const PsycDictInt psyc_var_types[] = { - {PSYC_C2STR("_amount"), PSYC_TYPE_AMOUNT}, - {PSYC_C2STR("_color"), PSYC_TYPE_COLOR}, - {PSYC_C2STR("_date"), PSYC_TYPE_DATE}, - {PSYC_C2STR("_degree"), PSYC_TYPE_DEGREE}, - {PSYC_C2STR("_entity"), PSYC_TYPE_ENTITY}, - {PSYC_C2STR("_flag"), PSYC_TYPE_FLAG}, - {PSYC_C2STR("_language"), PSYC_TYPE_LANGUAGE}, - {PSYC_C2STR("_list"), PSYC_TYPE_LIST}, - {PSYC_C2STR("_nick"), PSYC_TYPE_NICK}, - {PSYC_C2STR("_page"), PSYC_TYPE_PAGE}, - {PSYC_C2STR("_uniform"), PSYC_TYPE_UNIFORM}, - {PSYC_C2STR("_time"), PSYC_TYPE_TIME}, + {PSYC_C2STRI("_amount"), PSYC_TYPE_AMOUNT}, + {PSYC_C2STRI("_color"), PSYC_TYPE_COLOR}, + {PSYC_C2STRI("_date"), PSYC_TYPE_DATE}, + {PSYC_C2STRI("_degree"), PSYC_TYPE_DEGREE}, + {PSYC_C2STRI("_entity"), PSYC_TYPE_ENTITY}, + {PSYC_C2STRI("_flag"), PSYC_TYPE_FLAG}, + {PSYC_C2STRI("_language"), PSYC_TYPE_LANGUAGE}, + {PSYC_C2STRI("_list"), PSYC_TYPE_LIST}, + {PSYC_C2STRI("_nick"), PSYC_TYPE_NICK}, + {PSYC_C2STRI("_page"), PSYC_TYPE_PAGE}, + {PSYC_C2STRI("_uniform"), PSYC_TYPE_UNIFORM}, + {PSYC_C2STRI("_time"), PSYC_TYPE_TIME}, }; const size_t psyc_routing_vars_num = PSYC_NUM_ELEM(psyc_routing_vars); From 8a9ef747070c0649350ce2d32561a8f7308c1cea Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 9 Nov 2011 19:01:05 +0100 Subject: [PATCH 340/378] added psyc operator defs --- include/psyc.h | 6 +++--- include/psyc/packet.h | 9 +++++++++ pike/psyc.cmod | 2 +- test/test_json.c | 4 ++-- test/test_json_glib.c | 4 ++-- test/test_psyc.c | 4 ++-- test/test_psyc_speed.c | 4 ++-- test/test_render.c | 14 +++++++------- test/test_strlen.c | 4 ++-- test/uniform_parse.c | 2 ++ 10 files changed, 32 insertions(+), 21 deletions(-) diff --git a/include/psyc.h b/include/psyc.h index ed8ff0d..2926623 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -32,6 +32,7 @@ #define PSYC_NUM_ELEM(a) (sizeof(a) / sizeof(*(a))) +/// Boolean: true/false, yes/no. typedef enum { PSYC_FALSE = 0, @@ -40,15 +41,14 @@ typedef enum PSYC_YES = 1, } PsycBool; +/// Return code: OK/error. typedef enum { PSYC_OK = 1, PSYC_ERROR = -1, } PsycRC; -/** - * PSYC packet parts. - */ +/// PSYC packet parts. typedef enum { PSYC_PART_RESET = -1, diff --git a/include/psyc/packet.h b/include/psyc/packet.h index 4777a84..0a9d41b 100644 --- a/include/psyc/packet.h +++ b/include/psyc/packet.h @@ -54,6 +54,15 @@ typedef enum PSYC_PACKET_NO_LENGTH = 2, } PsycPacketFlag; +typedef enum +{ + PSYC_OPERATOR_SET = ':', + PSYC_OPERATOR_ASSIGN = '=', + PSYC_OPERATOR_AUGMENT = '+', + PSYC_OPERATOR_DIMINISH = '-', + PSYC_OPERATOR_QUERY = '?', +} PsycOperator; + /** Structure for a modifier. */ typedef struct { diff --git a/pike/psyc.cmod b/pike/psyc.cmod index 2ec7c9f..2cb1d44 100644 --- a/pike/psyc.cmod +++ b/pike/psyc.cmod @@ -121,7 +121,7 @@ PIKEFUN string render(mapping rvars, mapping evars, string method, string|void b struct keypair *k; // for mappings INT32 e; - char oper = C_GLYPH_OPERATOR_SET; + char oper = PSYC_OPERATOR_SET; // fill headers rheaders.lines = 0; diff --git a/test/test_json.c b/test/test_json.c index 19ccbef..126a84b 100644 --- a/test/test_json.c +++ b/test/test_json.c @@ -92,8 +92,8 @@ int main (int argc, char **argv) { CASE_v CASE_S CASE_P case 'h': printf( - HELP_FILE("testJson", "mnqSsvP") - HELP_PORT("testJson", "nqsvP") + HELP_FILE("test_json", "mnqSsvP") + HELP_PORT("test_json", "nqsvP") HELP_f HELP_p HELP_b HELP_c HELP_m HELP_n HELP_q HELP_S HELP_s HELP_v HELP_P HELP_h, diff --git a/test/test_json_glib.c b/test/test_json_glib.c index 2ef2e3e..4327adb 100644 --- a/test/test_json_glib.c +++ b/test/test_json_glib.c @@ -78,8 +78,8 @@ int main (int argc, char **argv) { CASE_s CASE_v CASE_P case 'h': printf( - HELP_FILE("testJsonGlib", "mnqSsvP") - HELP_PORT("testJsonGlib", "nqsvP") + HELP_FILE("test_json_glib", "mnqSsvP") + HELP_PORT("test_json_glib", "nqsvP") HELP_f HELP_p HELP_b HELP_c HELP_m HELP_n HELP_q HELP_S HELP_s HELP_v HELP_P HELP_h, diff --git a/test/test_psyc.c b/test/test_psyc.c index d18bc7a..c9961b6 100644 --- a/test/test_psyc.c +++ b/test/test_psyc.c @@ -326,8 +326,8 @@ int main (int argc, char **argv) { CASE_s CASE_v CASE_S CASE_P case 'h': printf( - HELP_FILE("testPsyc", "mnqrSsvP") - HELP_PORT("testPsyc", "nqrsvP") + HELP_FILE("test_psyc", "mnqrSsvP") + HELP_PORT("test_psyc", "nqrsvP") HELP_f HELP_p HELP_b HELP_c HELP_m HELP_n HELP_r HELP_q HELP_S HELP_s diff --git a/test/test_psyc_speed.c b/test/test_psyc_speed.c index 7ee20fe..d1012db 100644 --- a/test/test_psyc_speed.c +++ b/test/test_psyc_speed.c @@ -52,8 +52,8 @@ int main (int argc, char **argv) { CASE_r CASE_s case 'h': printf( - HELP_FILE("testPsycSpeed", "rs") - HELP_PORT("testPsycSpeed", "rs") + HELP_FILE("test_psyc_speed", "rs") + HELP_PORT("test_psyc_speed", "rs") HELP_f HELP_p HELP_b HELP_c HELP_r HELP_s HELP_h, port, RECV_BUF_SIZE); diff --git a/test/test_render.c b/test/test_render.c index 55497cc..8e55ec0 100644 --- a/test/test_render.c +++ b/test/test_render.c @@ -12,16 +12,16 @@ int testPresence (const char *avail, int availlen, const char *rendered, uint8_t verbose) { PsycModifier routing[1]; - psyc_modifier_init(&routing[0], C_GLYPH_OPERATOR_SET, + psyc_modifier_init(&routing[0], PSYC_OPERATOR_SET, PSYC_C2ARG("_context"), PSYC_C2ARG(myUNI), PSYC_MODIFIER_ROUTING); PsycModifier entity[2]; // presence is to be assigned permanently in distributed state - psyc_modifier_init(&entity[0], C_GLYPH_OPERATOR_ASSIGN, + psyc_modifier_init(&entity[0], PSYC_OPERATOR_ASSIGN, PSYC_C2ARG("_degree_availability"), avail, availlen, PSYC_MODIFIER_CHECK_LENGTH); - psyc_modifier_init(&entity[1], C_GLYPH_OPERATOR_ASSIGN, + psyc_modifier_init(&entity[1], PSYC_OPERATOR_ASSIGN, PSYC_C2ARG("_description_presence"), desc, desclen, PSYC_MODIFIER_CHECK_LENGTH); @@ -42,10 +42,10 @@ int testPresence (const char *avail, int availlen, int testList (const char *rendered, uint8_t verbose) { PsycModifier routing[2]; - psyc_modifier_init(&routing[0], C_GLYPH_OPERATOR_SET, + psyc_modifier_init(&routing[0], PSYC_OPERATOR_SET, PSYC_C2ARG("_source"), PSYC_C2ARG(myUNI), PSYC_MODIFIER_ROUTING); - psyc_modifier_init(&routing[1], C_GLYPH_OPERATOR_SET, + psyc_modifier_init(&routing[1], PSYC_OPERATOR_SET, PSYC_C2ARG("_context"), PSYC_C2ARG(myUNI), PSYC_MODIFIER_ROUTING); @@ -70,10 +70,10 @@ int testList (const char *rendered, uint8_t verbose) psyc_render_list(&list_bin, buf_bin, sizeof(buf_bin)); PsycModifier entity[2]; - psyc_modifier_init(&entity[0], C_GLYPH_OPERATOR_SET, + psyc_modifier_init(&entity[0], PSYC_OPERATOR_SET, PSYC_C2ARG("_list_text"), buf_text, list_text.length, list_text.flag); - psyc_modifier_init(&entity[1], C_GLYPH_OPERATOR_SET, + psyc_modifier_init(&entity[1], PSYC_OPERATOR_SET, PSYC_C2ARG("_list_binary"), buf_bin, list_bin.length, list_bin.flag); diff --git a/test/test_strlen.c b/test/test_strlen.c index 40a50a5..b2d5bf4 100644 --- a/test/test_strlen.c +++ b/test/test_strlen.c @@ -44,8 +44,8 @@ int main (int argc, char **argv) { CASE_s case 'h': printf( - HELP_FILE("testStrlen", "s") - HELP_PORT("testStrlen", "s") + HELP_FILE("test_strlen", "s") + HELP_PORT("test_strlen", "s") HELP_f HELP_p HELP_b HELP_c HELP_s HELP_h, port, RECV_BUF_SIZE); diff --git a/test/uniform_parse.c b/test/uniform_parse.c index 0b82b61..97e6c53 100644 --- a/test/uniform_parse.c +++ b/test/uniform_parse.c @@ -35,6 +35,8 @@ int main () { testUniform("psyc://foo:4405/~bar", PSYC_SCHEME_PSYC); testUniform("psyc://foo:1234", PSYC_SCHEME_PSYC); testUniform("psyc://foo:1234d", PSYC_SCHEME_PSYC); + testUniform("psyc://foo:-1234", PSYC_SCHEME_PSYC); + testUniform("psyc://foo:-1234d", PSYC_SCHEME_PSYC); testUniform("psyc://foo/", PSYC_SCHEME_PSYC); testUniform("psyc://foo", PSYC_SCHEME_PSYC); testUniform("psyc://1234567890abcdef:g/~foo", PSYC_SCHEME_PSYC); From d2780c0dbfba3fa6f660e24f145aa581b8361c2c Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 9 Nov 2011 19:02:21 +0100 Subject: [PATCH 341/378] added support for state sync/reset packets --- src/match.c | 1 - src/packet.c | 6 +++--- src/parse.c | 22 ++++++++++++---------- src/render.c | 25 +++++++++++++------------ src/uniform.c | 2 +- test/packets/00-no-body | 6 ++++++ test/packets/00-state-reset | 7 +++++++ test/packets/00-state-sync | 5 +++++ 8 files changed, 47 insertions(+), 27 deletions(-) create mode 100644 test/packets/00-no-body create mode 100644 test/packets/00-state-reset create mode 100644 test/packets/00-state-sync diff --git a/src/match.c b/src/match.c index de34c1f..56ec8ce 100644 --- a/src/match.c +++ b/src/match.c @@ -109,7 +109,6 @@ void * psyc_dict_lookup (const PsycDict *dict, size_t size, { size_t cursor = 1; uint8_t i, m = 0; - //memset(&matching, -1, sizeof matching); if (keylen < 2 || key[0] != '_') return 0; diff --git a/src/packet.c b/src/packet.c index 9862be6..8b305b6 100644 --- a/src/packet.c +++ b/src/packet.c @@ -63,9 +63,9 @@ void psyc_list_init (PsycList *list, PsycString *elems, size_t num_elems, inline size_t psyc_modifier_length (PsycModifier *m) { - size_t length = 1 + // oper - m->name.length + 1 + // name\t - m->value.length + 1; // value\n + size_t length = 2; // oper\n + if (m->name.length > 0) + length += m->name.length + 1 + m->value.length; // name\tvalue if (m->flag == PSYC_MODIFIER_NEED_LENGTH) // add length of length if needed length += psyc_num_length(m->value.length) + 1; // SP length diff --git a/src/parse.c b/src/parse.c index 42459e3..fef2429 100644 --- a/src/parse.c +++ b/src/parse.c @@ -21,7 +21,7 @@ typedef enum { PARSE_INSUFFICIENT = 1, PARSE_COMPLETE = 100, PARSE_INCOMPLETE = 101, -} parseRC; +} ParseRC; /** * Parse variable name or method name. @@ -29,7 +29,7 @@ typedef enum { * @return PARSE_ERROR or PARSE_SUCCESS */ static inline -parseRC psyc_parse_keyword (PsycParseState *state, PsycString *name) +ParseRC psyc_parse_keyword (PsycParseState *state, PsycString *name) { name->data = state->buffer.data + state->cursor; name->length = 0; @@ -54,8 +54,8 @@ parseRC psyc_parse_keyword (PsycParseState *state, PsycString *name) * @return PARSE_COMPLETE or PARSE_INCOMPLETE */ static inline -parseRC psyc_parse_binary_value (PsycParseState *state, PsycString *value, - size_t *length, size_t *parsed) +ParseRC psyc_parse_binary_value (PsycParseState *state, PsycString *value, + size_t *length, size_t *parsed) { size_t remaining = *length - *parsed; value->data = state->buffer.data + state->cursor; @@ -81,13 +81,16 @@ parseRC psyc_parse_binary_value (PsycParseState *state, PsycString *value, * @return PARSE_ERROR or PARSE_SUCCESS */ static inline -parseRC psyc_parse_modifier (PsycParseState *state, char *oper, - PsycString *name, PsycString *value) +ParseRC psyc_parse_modifier (PsycParseState *state, char *oper, + PsycString *name, PsycString *value) { *oper = *(state->buffer.data + state->cursor); ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); - parseRC ret = psyc_parse_keyword(state, name); + if (state->part == PSYC_PART_CONTENT && state->buffer.data[state->cursor] == '\n') + return PARSE_SUCCESS; // only oper is present, used for state sync/reset + + ParseRC ret = psyc_parse_keyword(state, name); if (ret == PARSE_ERROR) return PSYC_PARSE_ERROR_MOD_NAME; else if (ret != PARSE_SUCCESS) @@ -162,7 +165,7 @@ PsycParseRC psyc_parse (PsycParseState *state, char *oper, PP(("Invalid flag combination")) #endif - parseRC ret; // a return value + ParseRC ret; // a return value size_t pos = state->cursor; // a cursor position // Start position of the current line in the buffer @@ -326,8 +329,6 @@ PsycParseRC psyc_parse (PsycParseState *state, char *oper, { ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } - - // fall thru } else // No method, which means the packet should end now. { @@ -335,6 +336,7 @@ PsycParseRC psyc_parse (PsycParseState *state, char *oper, state->startc = state->cursor; goto PSYC_PART_END; } + // fall thru case PSYC_PART_DATA: PSYC_PART_DATA: diff --git a/src/render.c b/src/render.c index 68f2fd9..bd26745 100644 --- a/src/render.c +++ b/src/render.c @@ -46,24 +46,25 @@ static inline size_t psyc_render_modifier (PsycModifier *mod, char *buffer) { size_t cur = 0; - buffer[cur++] = mod->oper; - memcpy(buffer + cur, mod->name.data, mod->name.length); - cur += mod->name.length; - if (cur <= 1) - return cur; // error, name can't be empty - if (mod->flag == PSYC_MODIFIER_NEED_LENGTH) + if (mod->name.length > 0) { - buffer[cur++] = ' '; - cur += itoa(mod->value.length, buffer + cur, 10); + memcpy(buffer + cur, mod->name.data, mod->name.length); + cur += mod->name.length; + + if (mod->flag == PSYC_MODIFIER_NEED_LENGTH) + { + buffer[cur++] = ' '; + cur += itoa(mod->value.length, buffer + cur, 10); + } + + buffer[cur++] = '\t'; + memcpy(buffer + cur, mod->value.data, mod->value.length); + cur += mod->value.length; } - buffer[cur++] = '\t'; - memcpy(buffer + cur, mod->value.data, mod->value.length); - cur += mod->value.length; buffer[cur++] = '\n'; - return cur; } diff --git a/src/uniform.c b/src/uniform.c index d888423..74c3098 100644 --- a/src/uniform.c +++ b/src/uniform.c @@ -77,7 +77,7 @@ int psyc_uniform_parse (PsycUniform *uni, char *str, size_t length) break; case PSYC_UNIFORM_PORT: - if (psyc_is_numeric(c)) { + if (psyc_is_numeric(c) || (uni->port.length == 0 && c == '-')) { uni->port.length++; break; } diff --git a/test/packets/00-no-body b/test/packets/00-no-body new file mode 100644 index 0000000..a3c91ea --- /dev/null +++ b/test/packets/00-no-body @@ -0,0 +1,6 @@ +:_source psyc://foo.example.com/ +:_target psyc://bar.example.com/ + +:_foo bar +:_baz qux +| diff --git a/test/packets/00-state-reset b/test/packets/00-state-reset new file mode 100644 index 0000000..eca0239 --- /dev/null +++ b/test/packets/00-state-reset @@ -0,0 +1,7 @@ +:_source psyc://foo.example.com/ +:_target psyc://bar.example.com/ + += +=_foo bar +=_baz qux +| diff --git a/test/packets/00-state-sync b/test/packets/00-state-sync new file mode 100644 index 0000000..8c59a25 --- /dev/null +++ b/test/packets/00-state-sync @@ -0,0 +1,5 @@ +:_source psyc://foo.example.com/ +:_target psyc://bar.example.com/ + +? +| From 27dbed5dc7e5e8c2ebe1ce415b80961dec92be12 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 9 Nov 2011 19:45:27 +0100 Subject: [PATCH 342/378] allow only = and ? to be alone on a line --- src/parse.c | 4 +++- test/packets/err-00-oper-alone | 7 +++++++ 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 test/packets/err-00-oper-alone diff --git a/src/parse.c b/src/parse.c index fef2429..9dca3c2 100644 --- a/src/parse.c +++ b/src/parse.c @@ -6,6 +6,7 @@ #endif #include "lib.h" +#include #include #define ADVANCE_CURSOR_OR_RETURN(ret) \ @@ -87,7 +88,8 @@ ParseRC psyc_parse_modifier (PsycParseState *state, char *oper, *oper = *(state->buffer.data + state->cursor); ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); - if (state->part == PSYC_PART_CONTENT && state->buffer.data[state->cursor] == '\n') + if (state->part == PSYC_PART_CONTENT && state->buffer.data[state->cursor] == '\n' && + (*oper == PSYC_OPERATOR_ASSIGN || *oper == PSYC_OPERATOR_QUERY)) return PARSE_SUCCESS; // only oper is present, used for state sync/reset ParseRC ret = psyc_parse_keyword(state, name); diff --git a/test/packets/err-00-oper-alone b/test/packets/err-00-oper-alone new file mode 100644 index 0000000..709e2b2 --- /dev/null +++ b/test/packets/err-00-oper-alone @@ -0,0 +1,7 @@ +:_source psyc://foo.example.com/ +:_target psyc://bar.example.com/ + +: +=_foo bar +=_baz qux +| From af6106c1251f1c0f2b8fa04e01ab4a28dc65cf97 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 9 Nov 2011 21:22:58 +0100 Subject: [PATCH 343/378] added state op return codes for psyc_parse, added stateop to PsycPacket --- d/include/psyc/syntax.d | 23 ++--------------------- include/psyc/packet.h | 24 ++++++++++++++++-------- include/psyc/parse.h | 30 +++++++++++++++++------------- include/psyc/syntax.h | 28 ++-------------------------- src/packet.c | 12 ++++++++---- src/parse.c | 22 ++++++++++++++++++---- src/render.c | 36 +++++++++++++++++++++--------------- test/test_psyc.c | 5 +++++ test/test_render.c | 2 ++ 9 files changed, 91 insertions(+), 91 deletions(-) diff --git a/d/include/psyc/syntax.d b/d/include/psyc/syntax.d index 2962f57..2a55864 100644 --- a/d/include/psyc/syntax.d +++ b/d/include/psyc/syntax.d @@ -8,27 +8,8 @@ const PSYC_CONTENT_SIZE_THRESHOLD = 444; /* beyond this a modifier value length must be provided */ const PSYC_MODIFIER_SIZE_THRESHOLD = 404; -const C_GLYPH_PACKET_DELIMITER = '|'; -const S_GLYPH_PACKET_DELIMITER = "|"; -const PSYC_PACKET_DELIMITER = "\n|\n"; - -const C_GLYPH_SEPARATOR_KEYWORD = '_'; -const S_GLYPH_SEPARATOR_KEYWORD = "_"; - -const C_GLYPH_OPERATOR_SET = ':'; -const S_GLYPH_OPERATOR_SET = ":"; - -const C_GLYPH_OPERATOR_ASSIGN = '='; -const S_GLYPH_OPERATOR_ASSIGN = "="; - -const C_GLYPH_OPERATOR_AUGMENT = '+'; -const S_GLYPH_OPERATOR_AUGMENT = "+"; - -const C_GLYPH_OPERATOR_DIMINISH = '-'; -const S_GLYPH_OPERATOR_DIMINISH = "-"; - -const C_GLYPH_OPERATOR_QUERY = '?'; -const S_GLYPH_OPERATOR_QUERY = "?"; +const PSYC_PACKET_DELIMITER_CHAR = '|'; +const PSYC_PACKET_DELIMITER = "\n|\n"; /* might move into routing.h or something */ const PSYC_ROUTING = 1; diff --git a/include/psyc/packet.h b/include/psyc/packet.h index 0a9d41b..e0d5383 100644 --- a/include/psyc/packet.h +++ b/include/psyc/packet.h @@ -63,6 +63,13 @@ typedef enum PSYC_OPERATOR_QUERY = '?', } PsycOperator; +typedef enum +{ + PSYC_STATE_NOOP = 0, + PSYC_STATE_RESET = '=', + PSYC_STATE_SYNC = '?', +} PsycStateOp; + /** Structure for a modifier. */ typedef struct { @@ -91,15 +98,16 @@ typedef struct /** Intermediate struct for a PSYC packet */ typedef struct { - PsycHeader routing; ///< Routing header. - PsycHeader entity; ///< Entity header. - PsycString method; ///< Contains the method. - PsycString data; ///< Contains the data. - PsycString content; ///< Contains the whole content. + PsycHeader routing; ///< Routing header. + PsycHeader entity; ///< Entity header. + char stateop; ///< State operation. @see PsycStateOp + PsycString method; ///< Contains the method. + PsycString data; ///< Contains the data. + PsycString content; ///< Contains the whole content. size_t routingLength; ///< Length of routing part. size_t contentLength; ///< Length of content part. - size_t length; ///< Total length of packet. - PsycPacketFlag flag; ///< Packet flag. + size_t length; ///< Total length of packet. + PsycPacketFlag flag; ///< Packet flag. } PsycPacket; /** @@ -182,7 +190,7 @@ void psyc_packet_init (PsycPacket *packet, PsycModifier *entity, size_t entitylen, char *method, size_t methodlen, char *data, size_t datalen, - PsycPacketFlag flag); + char stateop, PsycPacketFlag flag); /** Initialize packet with raw content. */ void psyc_packet_init_raw (PsycPacket *packet, diff --git a/include/psyc/parse.h b/include/psyc/parse.h index 2f8b31d..b290c5f 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -152,42 +152,46 @@ typedef enum { /// Routing modifier parsing done. /// Operator, name & value contains the respective parts. PSYC_PARSE_ROUTING = 2, + /// State sync operation. + PSYC_PARSE_STATE_SYNC = 3, + /// State reset operation. + PSYC_PARSE_STATE_RESET = 4, /// Start of an incomplete entity modifier. /// Operator & name are complete, value is incomplete. - PSYC_PARSE_ENTITY_START = 3, + PSYC_PARSE_ENTITY_START = 5, /// Continuation of an incomplete entity modifier. - PSYC_PARSE_ENTITY_CONT = 4, + PSYC_PARSE_ENTITY_CONT = 6, /// End of an incomplete entity modifier. - PSYC_PARSE_ENTITY_END = 5, + PSYC_PARSE_ENTITY_END = 7, /// Entity modifier parsing done in one go. /// Operator, name & value contains the respective parts. - PSYC_PARSE_ENTITY = 6, + PSYC_PARSE_ENTITY = 8, /// Start of an incomplete body. /// Name contains method, value contains part of the body. /// Used when packet length is given - PSYC_PARSE_BODY_START = 7, + PSYC_PARSE_BODY_START = 9, /// Continuation of an incomplete body. /// Used when packet length is given - PSYC_PARSE_BODY_CONT = 8, + PSYC_PARSE_BODY_CONT = 10, /// End of an incomplete body. /// Used when packet length is given - PSYC_PARSE_BODY_END = 9, + PSYC_PARSE_BODY_END = 11, /// Body parsing done in one go, name contains method, value contains body. - PSYC_PARSE_BODY = 10, + PSYC_PARSE_BODY = 12, /// Start of an incomplete content, value contains part of content. /// Used when PSYC_PARSE_ROUTING_ONLY is set. - PSYC_PARSE_CONTENT_START = 7, + PSYC_PARSE_CONTENT_START = 9, /// Continuation of an incomplete content. /// Used when PSYC_PARSE_ROUTING_ONLY is set. - PSYC_PARSE_CONTENT_CONT = 8, + PSYC_PARSE_CONTENT_CONT = 10, /// End of an incomplete content. /// Used when PSYC_PARSE_ROUTING_ONLY is set. - PSYC_PARSE_CONTENT_END = 9, + PSYC_PARSE_CONTENT_END = 11, /// Content parsing done in one go, value contains the whole content. /// Used when PSYC_PARSE_ROUTING_ONLY is set. - PSYC_PARSE_CONTENT = 10, + PSYC_PARSE_CONTENT = 12, /// Finished parsing packet. - PSYC_PARSE_COMPLETE = 11, + PSYC_PARSE_COMPLETE = 13, } PsycParseRC; /** diff --git a/include/psyc/syntax.h b/include/psyc/syntax.h index 105d59e..d46e0c0 100644 --- a/include/psyc/syntax.h +++ b/include/psyc/syntax.h @@ -14,32 +14,8 @@ # define PSYC_MODIFIER_SIZE_THRESHOLD 404 #endif -#define C_GLYPH_PACKET_DELIMITER '|' -#define S_GLYPH_PACKET_DELIMITER "|" -#define PSYC_PACKET_DELIMITER "\n|\n" - -#define C_GLYPH_SEPARATOR_KEYWORD '_' -#define S_GLYPH_SEPARATOR_KEYWORD "_" - -#define C_GLYPH_OPERATOR_SET ':' -#define S_GLYPH_OPERATOR_SET ":" - -#define C_GLYPH_OPERATOR_ASSIGN '=' -#define S_GLYPH_OPERATOR_ASSIGN "=" - -#define C_GLYPH_OPERATOR_AUGMENT '+' -#define S_GLYPH_OPERATOR_AUGMENT "+" - -#define C_GLYPH_OPERATOR_DIMINISH '-' -#define S_GLYPH_OPERATOR_DIMINISH "-" - -#define C_GLYPH_OPERATOR_QUERY '?' -#define S_GLYPH_OPERATOR_QUERY "?" - -/* might move into routing.h or something */ -#define PSYC_ROUTING 1 -#define PSYC_ROUTING_MERGE 2 -#define PSYC_ROUTING_RENDER 4 +#define PSYC_PACKET_DELIMITER_CHAR '|' +#define PSYC_PACKET_DELIMITER "\n|\n" #define PSYC_SYNTAX_H #endif diff --git a/src/packet.c b/src/packet.c index 8b305b6..e8594fd 100644 --- a/src/packet.c +++ b/src/packet.c @@ -76,7 +76,7 @@ size_t psyc_modifier_length (PsycModifier *m) inline PsycPacketFlag psyc_packet_length_check (PsycPacket *p) { - if (p->data.length == 1 && p->data.data[0] == C_GLYPH_PACKET_DELIMITER) + if (p->data.length == 1 && p->data.data[0] == PSYC_PACKET_DELIMITER_CHAR) return PSYC_PACKET_NEED_LENGTH; if (p->data.length > PSYC_CONTENT_SIZE_THRESHOLD) @@ -110,6 +110,10 @@ size_t psyc_packet_length_set (PsycPacket *p) p->contentLength = p->content.length; else { + // add state operation + if (p->stateop != PSYC_STATE_NOOP) + p->contentLength += 2; // op\n + // add entity header length for (i = 0; i < p->entity.lines; i++) p->contentLength += psyc_modifier_length(&(p->entity.modifiers[i])); @@ -139,9 +143,9 @@ void psyc_packet_init (PsycPacket *p, PsycModifier *entity, size_t entitylen, char *method, size_t methodlen, char *data, size_t datalen, - PsycPacketFlag flag) + char stateop, PsycPacketFlag flag) { - *p = (PsycPacket) {{routinglen, routing}, {entitylen, entity}, + *p = (PsycPacket) {{routinglen, routing}, {entitylen, entity}, stateop, {methodlen, method}, {datalen, data}, {0,0}, 0, 0, flag}; if (flag == PSYC_PACKET_CHECK_LENGTH) // find out if it needs length @@ -156,7 +160,7 @@ void psyc_packet_init_raw (PsycPacket *p, char *content, size_t contentlen, PsycPacketFlag flag) { - *p = (PsycPacket) {{routinglen, routing}, {0,0}, {0,0}, {0,0}, + *p = (PsycPacket) {{routinglen, routing}, {0,0}, 0, {0,0}, {0,0}, {contentlen, content}, 0, 0, flag}; if (flag == PSYC_PACKET_CHECK_LENGTH) // find out if it needs length diff --git a/src/parse.c b/src/parse.c index 9dca3c2..51246c6 100644 --- a/src/parse.c +++ b/src/parse.c @@ -88,10 +88,6 @@ ParseRC psyc_parse_modifier (PsycParseState *state, char *oper, *oper = *(state->buffer.data + state->cursor); ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); - if (state->part == PSYC_PART_CONTENT && state->buffer.data[state->cursor] == '\n' && - (*oper == PSYC_OPERATOR_ASSIGN || *oper == PSYC_OPERATOR_QUERY)) - return PARSE_SUCCESS; // only oper is present, used for state sync/reset - ParseRC ret = psyc_parse_keyword(state, name); if (ret == PARSE_ERROR) return PSYC_PARSE_ERROR_MOD_NAME; @@ -287,6 +283,24 @@ PsycParseRC psyc_parse (PsycParseState *state, char *oper, // method does not start with a glyph. if (psyc_is_glyph(state->buffer.data[state->cursor])) { + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + if (state->contentParsed == 0 && state->buffer.data[state->cursor] == '\n') + { + *oper = *(state->buffer.data + state->cursor - 1); + switch (*oper) + { + case PSYC_STATE_SYNC: + state->contentParsed += 2; + return PSYC_PARSE_STATE_SYNC; + case PSYC_STATE_RESET: + state->contentParsed += 2; + return PSYC_PARSE_STATE_RESET; + default: + return PSYC_PARSE_ERROR_MOD_NAME; + } + } + state->cursor--; + ret = psyc_parse_modifier(state, oper, name, value); state->contentParsed += state->cursor - pos; diff --git a/src/render.c b/src/render.c index bd26745..887f82e 100644 --- a/src/render.c +++ b/src/render.c @@ -1,4 +1,5 @@ #include "lib.h" +#include #include #include @@ -46,25 +47,24 @@ static inline size_t psyc_render_modifier (PsycModifier *mod, char *buffer) { size_t cur = 0; + buffer[cur++] = mod->oper; + memcpy(buffer + cur, mod->name.data, mod->name.length); + cur += mod->name.length; + if (cur == 1) + return cur; // error, name can't be empty - if (mod->name.length > 0) + if (mod->flag == PSYC_MODIFIER_NEED_LENGTH) { - memcpy(buffer + cur, mod->name.data, mod->name.length); - cur += mod->name.length; - - if (mod->flag == PSYC_MODIFIER_NEED_LENGTH) - { - buffer[cur++] = ' '; - cur += itoa(mod->value.length, buffer + cur, 10); - } - - buffer[cur++] = '\t'; - memcpy(buffer + cur, mod->value.data, mod->value.length); - cur += mod->value.length; + buffer[cur++] = ' '; + cur += itoa(mod->value.length, buffer + cur, 10); } + buffer[cur++] = '\t'; + memcpy(buffer + cur, mod->value.data, mod->value.length); + cur += mod->value.length; buffer[cur++] = '\n'; + return cur; } @@ -92,7 +92,8 @@ PsycRenderRC psyc_render (PsycPacket *packet, char *buffer, size_t buflen) cur += itoa(packet->contentLength, buffer + cur, 10); if (packet->flag == PSYC_PACKET_NEED_LENGTH || packet->content.length || - packet->entity.lines || packet->method.length || packet->data.length) + packet->stateop || packet->entity.lines || + packet->method.length || packet->data.length) buffer[cur++] = '\n'; // start of content part if there's content or length if (packet->content.length) // render raw content if present @@ -102,6 +103,11 @@ PsycRenderRC psyc_render (PsycPacket *packet, char *buffer, size_t buflen) } else { + if (packet->stateop) { + buffer[cur++] = packet->stateop; + buffer[cur++] = '\n'; + } + // render entity modifiers for (i = 0; i < packet->entity.lines; i++) cur += psyc_render_modifier(&packet->entity.modifiers[i], buffer + cur); @@ -124,7 +130,7 @@ PsycRenderRC psyc_render (PsycPacket *packet, char *buffer, size_t buflen) } // add packet delimiter - buffer[cur++] = C_GLYPH_PACKET_DELIMITER; + buffer[cur++] = PSYC_PACKET_DELIMITER_CHAR; buffer[cur++] = '\n'; // actual length should be equal to pre-calculated length at this point diff --git a/test/test_psyc.c b/test/test_psyc.c index c9961b6..ad052ee 100644 --- a/test/test_psyc.c +++ b/test/test_psyc.c @@ -98,6 +98,11 @@ int test_input (int i, char *recvbuf, size_t nbytes) { packet->routing.lines++; break; + case PSYC_PARSE_STATE_SYNC: + case PSYC_PARSE_STATE_RESET: + packet->stateop = oper; + break; + case PSYC_PARSE_ENTITY_START: case PSYC_PARSE_ENTITY_CONT: case PSYC_PARSE_ENTITY_END: diff --git a/test/test_render.c b/test/test_render.c index 8e55ec0..58f6036 100644 --- a/test/test_render.c +++ b/test/test_render.c @@ -30,6 +30,7 @@ int testPresence (const char *avail, int availlen, entity, PSYC_NUM_ELEM(entity), PSYC_C2ARG("_notice_presence"), NULL, 0, + PSYC_STATE_NOOP, PSYC_PACKET_CHECK_LENGTH); char buffer[512]; @@ -82,6 +83,7 @@ int testList (const char *rendered, uint8_t verbose) entity, PSYC_NUM_ELEM(entity), PSYC_C2ARG("_test_list"), PSYC_C2ARG("list test"), + PSYC_STATE_NOOP, PSYC_PACKET_CHECK_LENGTH); char buffer[512]; From 58d4b73597e6dbb545f3fb107466c3267f8ab78e Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 9 Nov 2011 21:38:06 +0100 Subject: [PATCH 344/378] resync --- include/psyc/packet.h | 6 +++--- include/psyc/parse.h | 2 +- src/parse.c | 4 ++-- test/test_psyc.c | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/psyc/packet.h b/include/psyc/packet.h index e0d5383..3b5caa0 100644 --- a/include/psyc/packet.h +++ b/include/psyc/packet.h @@ -65,9 +65,9 @@ typedef enum typedef enum { - PSYC_STATE_NOOP = 0, - PSYC_STATE_RESET = '=', - PSYC_STATE_SYNC = '?', + PSYC_STATE_NOOP = 0, + PSYC_STATE_RESET = '=', + PSYC_STATE_RESYNC = '?', } PsycStateOp; /** Structure for a modifier. */ diff --git a/include/psyc/parse.h b/include/psyc/parse.h index b290c5f..d0825f4 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -153,7 +153,7 @@ typedef enum { /// Operator, name & value contains the respective parts. PSYC_PARSE_ROUTING = 2, /// State sync operation. - PSYC_PARSE_STATE_SYNC = 3, + PSYC_PARSE_STATE_RESYNC = 3, /// State reset operation. PSYC_PARSE_STATE_RESET = 4, /// Start of an incomplete entity modifier. diff --git a/src/parse.c b/src/parse.c index 51246c6..1257845 100644 --- a/src/parse.c +++ b/src/parse.c @@ -289,9 +289,9 @@ PsycParseRC psyc_parse (PsycParseState *state, char *oper, *oper = *(state->buffer.data + state->cursor - 1); switch (*oper) { - case PSYC_STATE_SYNC: + case PSYC_STATE_RESYNC: state->contentParsed += 2; - return PSYC_PARSE_STATE_SYNC; + return PSYC_PARSE_STATE_RESYNC; case PSYC_STATE_RESET: state->contentParsed += 2; return PSYC_PARSE_STATE_RESET; diff --git a/test/test_psyc.c b/test/test_psyc.c index ad052ee..fd37d56 100644 --- a/test/test_psyc.c +++ b/test/test_psyc.c @@ -98,7 +98,7 @@ int test_input (int i, char *recvbuf, size_t nbytes) { packet->routing.lines++; break; - case PSYC_PARSE_STATE_SYNC: + case PSYC_PARSE_STATE_RESYNC: case PSYC_PARSE_STATE_RESET: packet->stateop = oper; break; From cf02d065cf99574d968fbd6b120d1de7bccc6baa Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 11 Nov 2011 22:18:24 +0100 Subject: [PATCH 345/378] indent --- Makefile | 3 + include/psyc.h | 128 +++--- include/psyc/packet.h | 208 +++++----- include/psyc/parse.h | 461 ++++++++++----------- include/psyc/render.h | 38 +- include/psyc/text.h | 119 +++--- include/psyc/uniform.h | 104 ++--- include/psyc/variable.h | 16 +- src/itoa.c | 135 ++++--- src/match.c | 281 +++++++------ src/memmem.c | 45 +-- src/packet.c | 259 ++++++------ src/parse.c | 874 +++++++++++++++++++--------------------- src/render.c | 197 +++++---- src/text.c | 133 +++--- src/uniform.c | 317 ++++++++------- src/variable.c | 136 +++---- test/test.c | 370 ++++++++--------- test/test.h | 18 +- test/test_json.c | 147 +++---- test/test_json_glib.c | 119 +++--- test/test_match.c | 38 +- test/test_parser.c | 163 ++++---- test/test_psyc.c | 622 ++++++++++++++-------------- test/test_psyc_speed.c | 82 ++-- test/test_render.c | 162 ++++---- test/test_strlen.c | 75 ++-- test/test_text.c | 144 +++---- test/uniform_parse.c | 88 ++-- test/var_is_routing.c | 50 ++- test/var_type.c | 24 +- 31 files changed, 2797 insertions(+), 2759 deletions(-) diff --git a/Makefile b/Makefile index d7f5997..0b62293 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,9 @@ .PHONY: doc test bench .NOTPARALLEL: clean +indent_args = -nbad -bap -bbo -nbc -br -brs -ncdb -cdw -ce -ci4 -cli0 -cs -d0 -di1 \ +-nfc1 -nfca -hnl -i4 -ip0 -l80 -lp -npcs -nprs -npsl -saf -sai -saw -nsc -nsob -nss + all: ${MAKE} -C src diff --git a/include/psyc.h b/include/psyc.h index 2926623..351de41 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -15,13 +15,14 @@ // * @subsection step1 Step 1: Opening the box #ifndef PSYC_H +#define PSYC_H #include #include #include #define PSYC_VERSION 1 -#define PSYC_EPOCH 1440444041 // 2015-08-24 21:20:41 CET (Monday) +#define PSYC_EPOCH 1440444041 // 2015-08-24 21:20:41 CET (Monday) #define PSYC_C2STR(str) (PsycString) {sizeof(str)-1, str} #define PSYC_C2STRI(str) {sizeof(str)-1, str} @@ -33,31 +34,28 @@ #define PSYC_NUM_ELEM(a) (sizeof(a) / sizeof(*(a))) /// Boolean: true/false, yes/no. -typedef enum -{ - PSYC_FALSE = 0, - PSYC_TRUE = 1, - PSYC_NO = 0, - PSYC_YES = 1, +typedef enum { + PSYC_FALSE = 0, + PSYC_TRUE = 1, + PSYC_NO = 0, + PSYC_YES = 1, } PsycBool; /// Return code: OK/error. -typedef enum -{ - PSYC_OK = 1, - PSYC_ERROR = -1, +typedef enum { + PSYC_OK = 1, + PSYC_ERROR = -1, } PsycRC; /// PSYC packet parts. -typedef enum -{ - PSYC_PART_RESET = -1, - PSYC_PART_ROUTING = 0, - PSYC_PART_LENGTH = 1, - PSYC_PART_CONTENT = 2, - PSYC_PART_METHOD = 3, - PSYC_PART_DATA = 4, - PSYC_PART_END = 5, +typedef enum { + PSYC_PART_RESET = -1, + PSYC_PART_ROUTING = 0, + PSYC_PART_LENGTH = 1, + PSYC_PART_CONTENT = 2, + PSYC_PART_METHOD = 3, + PSYC_PART_DATA = 4, + PSYC_PART_END = 5, } PsycPart; /** @@ -68,31 +66,29 @@ typedef enum * validity. Other variable types are treated * as opaque data. */ -typedef enum -{ - PSYC_TYPE_UNKNOWN, - PSYC_TYPE_AMOUNT, - PSYC_TYPE_COLOR, - PSYC_TYPE_DATE, - PSYC_TYPE_DEGREE, - PSYC_TYPE_ENTITY, - PSYC_TYPE_FLAG, - PSYC_TYPE_LANGUAGE, - PSYC_TYPE_LIST, - PSYC_TYPE_NICK, - PSYC_TYPE_PAGE, - PSYC_TYPE_UNIFORM, - PSYC_TYPE_TIME, +typedef enum { + PSYC_TYPE_UNKNOWN, + PSYC_TYPE_AMOUNT, + PSYC_TYPE_COLOR, + PSYC_TYPE_DATE, + PSYC_TYPE_DEGREE, + PSYC_TYPE_ENTITY, + PSYC_TYPE_FLAG, + PSYC_TYPE_LANGUAGE, + PSYC_TYPE_LIST, + PSYC_TYPE_NICK, + PSYC_TYPE_PAGE, + PSYC_TYPE_UNIFORM, + PSYC_TYPE_TIME, } PsycType; /** * List types. * Possible types are text and binary. */ -typedef enum -{ - PSYC_LIST_TEXT = 1, - PSYC_LIST_BINARY = 2, +typedef enum { + PSYC_LIST_TEXT = 1, + PSYC_LIST_BINARY = 2, } PsycListType; /** @@ -100,37 +96,34 @@ typedef enum * * Contains pointer and length for a buffer. */ -typedef struct -{ - /// Length of the data pointed to by ptr - size_t length; - /// pointer to the data - char *data; +typedef struct { + /// Length of the data pointed to by ptr + size_t length; + /// pointer to the data + char *data; } PsycString; -typedef struct -{ - PsycString key; - void *value; +typedef struct { + PsycString key; + void *value; } PsycDict; -typedef struct -{ - PsycString key; - intptr_t value; +typedef struct { + PsycString key; + intptr_t value; } PsycDictInt; /** * Checks if long keyword string inherits from short keyword string. */ -int psyc_inherits (char *sho, size_t slen, - char *lon, size_t llen); +int +psyc_inherits (char *sho, size_t slen, char *lon, size_t llen); /** * Checks if short keyword string matches long keyword string. */ -int psyc_matches (char *sho, size_t slen, - char *lon, size_t llen); +int +psyc_matches (char *sho, size_t slen, char *lon, size_t llen); /** * Look up value associated with a key in a dictionary. @@ -147,25 +140,24 @@ int psyc_matches (char *sho, size_t slen, * @return The value of the entry if found, or NULL if not found. */ -void * psyc_dict_lookup (const PsycDict *dict, size_t size, - const char *key, size_t keylen, - PsycBool inherit, int8_t *tmp); +void * +psyc_dict_lookup (const PsycDict *dict, size_t size, + const char *key, size_t keylen, + PsycBool inherit, int8_t *tmp); /** * Look up value associated with a key in a dictionary of integers. * @see psyc_dict_lookup */ -static inline -intptr_t psyc_dict_lookup_int (const PsycDictInt *dict, size_t size, - const char *key, size_t keylen, - PsycBool inherit, int8_t *tmp) +static inline intptr_t +psyc_dict_lookup_int (const PsycDictInt * dict, size_t size, + const char *key, size_t keylen, + PsycBool inherit, int8_t *tmp) { - return (intptr_t) psyc_dict_lookup((PsycDict *)dict, size, key, keylen, inherit, tmp); + return (intptr_t) psyc_dict_lookup((PsycDict *) dict, size, key, keylen, + inherit, tmp); } - - #include "psyc/variable.h" -#define PSYC_H #endif diff --git a/include/psyc/packet.h b/include/psyc/packet.h index 3b5caa0..5c5fb18 100644 --- a/include/psyc/packet.h +++ b/include/psyc/packet.h @@ -1,4 +1,5 @@ #ifndef PSYC_PACKET_H +#define PSYC_PACKET_H /** * @file psyc/packet.h @@ -20,185 +21,182 @@ #include /** Modifier flags. */ -typedef enum -{ - /// Modifier needs to be checked if it needs length. - PSYC_MODIFIER_CHECK_LENGTH = 0, - /// Modifier needs length. - PSYC_MODIFIER_NEED_LENGTH = 1, - /// Modifier doesn't need length. - PSYC_MODIFIER_NO_LENGTH = 2, - /// Routing modifier, which implies that it doesn't need length. - PSYC_MODIFIER_ROUTING = 3, +typedef enum { + /// Modifier needs to be checked if it needs length. + PSYC_MODIFIER_CHECK_LENGTH = 0, + /// Modifier needs length. + PSYC_MODIFIER_NEED_LENGTH = 1, + /// Modifier doesn't need length. + PSYC_MODIFIER_NO_LENGTH = 2, + /// Routing modifier, which implies that it doesn't need length. + PSYC_MODIFIER_ROUTING = 3, } PsycModifierFlag; /** List flags. */ -typedef enum -{ - /// List needs to be checked if it needs length. - PSYC_LIST_CHECK_LENGTH = 0, - /// List needs length. - PSYC_LIST_NEED_LENGTH = 1, - /// List doesn't need length. - PSYC_LIST_NO_LENGTH = 2, +typedef enum { + /// List needs to be checked if it needs length. + PSYC_LIST_CHECK_LENGTH = 0, + /// List needs length. + PSYC_LIST_NEED_LENGTH = 1, + /// List doesn't need length. + PSYC_LIST_NO_LENGTH = 2, } PsycListFlag; /** Packet flags. */ -typedef enum -{ - /// Packet needs to be checked if it needs content length. - PSYC_PACKET_CHECK_LENGTH = 0, - /// Packet needs content length. - PSYC_PACKET_NEED_LENGTH = 1, - /// Packet doesn't need content length. - PSYC_PACKET_NO_LENGTH = 2, +typedef enum { + /// Packet needs to be checked if it needs content length. + PSYC_PACKET_CHECK_LENGTH = 0, + /// Packet needs content length. + PSYC_PACKET_NEED_LENGTH = 1, + /// Packet doesn't need content length. + PSYC_PACKET_NO_LENGTH = 2, } PsycPacketFlag; -typedef enum -{ - PSYC_OPERATOR_SET = ':', - PSYC_OPERATOR_ASSIGN = '=', - PSYC_OPERATOR_AUGMENT = '+', - PSYC_OPERATOR_DIMINISH = '-', - PSYC_OPERATOR_QUERY = '?', +typedef enum { + PSYC_OPERATOR_SET = ':', + PSYC_OPERATOR_ASSIGN = '=', + PSYC_OPERATOR_AUGMENT = '+', + PSYC_OPERATOR_DIMINISH = '-', + PSYC_OPERATOR_QUERY = '?', } PsycOperator; -typedef enum -{ - PSYC_STATE_NOOP = 0, - PSYC_STATE_RESET = '=', - PSYC_STATE_RESYNC = '?', +typedef enum { + PSYC_STATE_NOOP = 0, + PSYC_STATE_RESET = '=', + PSYC_STATE_RESYNC = '?', } PsycStateOp; /** Structure for a modifier. */ -typedef struct -{ - char oper; - PsycString name; - PsycString value; - PsycModifierFlag flag; +typedef struct { + char oper; + PsycString name; + PsycString value; + PsycModifierFlag flag; } PsycModifier; /** Structure for an entity or routing header. */ -typedef struct -{ - size_t lines; - PsycModifier *modifiers; +typedef struct { + size_t lines; + PsycModifier *modifiers; } PsycHeader; /** Structure for a list. */ -typedef struct -{ - size_t num_elems; - PsycString *elems; - size_t length; - PsycListFlag flag; +typedef struct { + size_t num_elems; + PsycString *elems; + size_t length; + PsycListFlag flag; } PsycList; /** Intermediate struct for a PSYC packet */ -typedef struct -{ - PsycHeader routing; ///< Routing header. - PsycHeader entity; ///< Entity header. - char stateop; ///< State operation. @see PsycStateOp - PsycString method; ///< Contains the method. - PsycString data; ///< Contains the data. - PsycString content; ///< Contains the whole content. - size_t routingLength; ///< Length of routing part. - size_t contentLength; ///< Length of content part. - size_t length; ///< Total length of packet. - PsycPacketFlag flag; ///< Packet flag. +typedef struct { + PsycHeader routing; ///< Routing header. + PsycHeader entity; ///< Entity header. + char stateop; ///< State operation. @see PsycStateOp + PsycString method; ///< Contains the method. + PsycString data; ///< Contains the data. + PsycString content; ///< Contains the whole content. + size_t routingLength; ///< Length of routing part. + size_t contentLength; ///< Length of content part. + size_t length; ///< Total length of packet. + PsycPacketFlag flag; ///< Packet flag. } PsycPacket; /** * Return the number of digits a number has in its base 10 representation. */ -static inline -size_t psyc_num_length (size_t n) +static inline size_t +psyc_num_length (size_t n) { - return n < 10 ? 1 : log10(n) + 1; + return n < 10 ? 1 : log10(n) + 1; } /** * \internal * Check if a modifier needs length. */ -static inline -PsycModifierFlag psyc_modifier_length_check (PsycModifier *m) +static inline PsycModifierFlag +psyc_modifier_length_check (PsycModifier *m) { - PsycModifierFlag flag; + PsycModifierFlag flag; - if (m->value.length > PSYC_MODIFIER_SIZE_THRESHOLD) - flag = PSYC_MODIFIER_NEED_LENGTH; - else if (memchr(m->value.data, (int)'\n', m->value.length)) - flag = PSYC_MODIFIER_NEED_LENGTH; - else - flag = PSYC_MODIFIER_NO_LENGTH; + if (m->value.length > PSYC_MODIFIER_SIZE_THRESHOLD) + flag = PSYC_MODIFIER_NEED_LENGTH; + else if (memchr(m->value.data, (int) '\n', m->value.length)) + flag = PSYC_MODIFIER_NEED_LENGTH; + else + flag = PSYC_MODIFIER_NO_LENGTH; - return flag; + return flag; } /** Initialize modifier */ -static inline -void psyc_modifier_init (PsycModifier *m, char oper, - char *name, size_t namelen, - char *value, size_t valuelen, - PsycModifierFlag flag) +static inline void +psyc_modifier_init (PsycModifier *m, char oper, + char *name, size_t namelen, + char *value, size_t valuelen, PsycModifierFlag flag) { - *m = (PsycModifier) {oper, {namelen, name}, {valuelen, value}, flag}; + *m = (PsycModifier) {oper, {namelen, name}, {valuelen, value}, flag}; - if (flag == PSYC_MODIFIER_CHECK_LENGTH) // find out if it needs a length - m->flag = psyc_modifier_length_check(m); + if (flag == PSYC_MODIFIER_CHECK_LENGTH) // find out if it needs a length + m->flag = psyc_modifier_length_check(m); } /** * \internal * Get the total length of a modifier when rendered. */ -size_t psyc_modifier_length (PsycModifier *m); +size_t +psyc_modifier_length (PsycModifier *m); /** * \internal * Check if a list needs length. */ -PsycListFlag psyc_list_length_check (PsycList *list); +PsycListFlag +psyc_list_length_check (PsycList *list); /** * \internal * Get the total length of a list when rendered. */ -PsycListFlag psyc_list_length (PsycList *list); +PsycListFlag +psyc_list_length (PsycList *list); /** * \internal * Check if a packet needs length. */ -PsycPacketFlag psyc_packet_length_check (PsycPacket *p); +PsycPacketFlag +psyc_packet_length_check (PsycPacket *p); /** * Calculate and set the rendered length of packet parts and total packet length. */ -size_t psyc_packet_length_set (PsycPacket *p); +size_t +psyc_packet_length_set (PsycPacket *p); /** Initialize list. */ -void psyc_list_init (PsycList *list, PsycString *elems, size_t num_elems, - PsycListFlag flag); +void +psyc_list_init (PsycList *list, PsycString *elems, size_t num_elems, + PsycListFlag flag); /** Initialize packet. */ -void psyc_packet_init (PsycPacket *packet, - PsycModifier *routing, size_t routinglen, - PsycModifier *entity, size_t entitylen, - char *method, size_t methodlen, - char *data, size_t datalen, - char stateop, PsycPacketFlag flag); +void +psyc_packet_init (PsycPacket *packet, + PsycModifier *routing, size_t routinglen, + PsycModifier *entity, size_t entitylen, + char *method, size_t methodlen, + char *data, size_t datalen, + char stateop, PsycPacketFlag flag); /** Initialize packet with raw content. */ -void psyc_packet_init_raw (PsycPacket *packet, - PsycModifier *routing, size_t routinglen, - char *content, size_t contentlen, - PsycPacketFlag flag); +void +psyc_packet_init_raw (PsycPacket *packet, + PsycModifier *routing, size_t routinglen, + char *content, size_t contentlen, + PsycPacketFlag flag); /** @} */ // end of packet group -#define PSYC_PACKET_H #endif diff --git a/include/psyc/parse.h b/include/psyc/parse.h index d0825f4..da28af4 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -1,4 +1,5 @@ #ifndef PSYC_PARSE_H +#define PSYC_PARSE_H /** * @file psyc/parse.h @@ -115,13 +116,13 @@ #include typedef enum { - /// Default Flag. Parse everything. - PSYC_PARSE_ALL = 0, - /// Parse only the header - PSYC_PARSE_ROUTING_ONLY = 1, - /// Parse only the content. - /// Parsing starts at the content and the content must be complete. - PSYC_PARSE_START_AT_CONTENT = 2, + /// Default Flag. Parse everything. + PSYC_PARSE_ALL = 0, + /// Parse only the header + PSYC_PARSE_ROUTING_ONLY = 1, + /// Parse only the content. + /// Parsing starts at the content and the content must be complete. + PSYC_PARSE_START_AT_CONTENT = 2, } PsycParseFlag; /** @@ -129,69 +130,69 @@ typedef enum { * @see psyc_parse() */ typedef enum { - /// Error, packet is not ending with a valid delimiter. - PSYC_PARSE_ERROR_END = -8, - /// Error, expected NL after the method. - PSYC_PARSE_ERROR_METHOD = -7, - /// Error, expected NL after a modifier. - PSYC_PARSE_ERROR_MOD_NL = -6, - /// Error, modifier length is not numeric. - PSYC_PARSE_ERROR_MOD_LEN = -5, - /// Error, expected TAB before modifier value. - PSYC_PARSE_ERROR_MOD_TAB = -4, - /// Error, modifier name is missing. - PSYC_PARSE_ERROR_MOD_NAME = -3, - /// Error, expected NL after the content length. - PSYC_PARSE_ERROR_LENGTH = -2, - /// Error in packet. - PSYC_PARSE_ERROR = -1, - /// Buffer contains insufficient amount of data. - /// Fill another buffer and concatenate it with the end of the current buffer, - /// from the cursor position to the end. - PSYC_PARSE_INSUFFICIENT = 1, - /// Routing modifier parsing done. - /// Operator, name & value contains the respective parts. - PSYC_PARSE_ROUTING = 2, - /// State sync operation. - PSYC_PARSE_STATE_RESYNC = 3, - /// State reset operation. - PSYC_PARSE_STATE_RESET = 4, - /// Start of an incomplete entity modifier. - /// Operator & name are complete, value is incomplete. - PSYC_PARSE_ENTITY_START = 5, - /// Continuation of an incomplete entity modifier. - PSYC_PARSE_ENTITY_CONT = 6, - /// End of an incomplete entity modifier. - PSYC_PARSE_ENTITY_END = 7, - /// Entity modifier parsing done in one go. - /// Operator, name & value contains the respective parts. - PSYC_PARSE_ENTITY = 8, - /// Start of an incomplete body. - /// Name contains method, value contains part of the body. - /// Used when packet length is given - PSYC_PARSE_BODY_START = 9, - /// Continuation of an incomplete body. - /// Used when packet length is given - PSYC_PARSE_BODY_CONT = 10, - /// End of an incomplete body. - /// Used when packet length is given - PSYC_PARSE_BODY_END = 11, - /// Body parsing done in one go, name contains method, value contains body. - PSYC_PARSE_BODY = 12, - /// Start of an incomplete content, value contains part of content. - /// Used when PSYC_PARSE_ROUTING_ONLY is set. - PSYC_PARSE_CONTENT_START = 9, - /// Continuation of an incomplete content. - /// Used when PSYC_PARSE_ROUTING_ONLY is set. - PSYC_PARSE_CONTENT_CONT = 10, - /// End of an incomplete content. - /// Used when PSYC_PARSE_ROUTING_ONLY is set. - PSYC_PARSE_CONTENT_END = 11, - /// Content parsing done in one go, value contains the whole content. - /// Used when PSYC_PARSE_ROUTING_ONLY is set. - PSYC_PARSE_CONTENT = 12, - /// Finished parsing packet. - PSYC_PARSE_COMPLETE = 13, + /// Error, packet is not ending with a valid delimiter. + PSYC_PARSE_ERROR_END = -8, + /// Error, expected NL after the method. + PSYC_PARSE_ERROR_METHOD = -7, + /// Error, expected NL after a modifier. + PSYC_PARSE_ERROR_MOD_NL = -6, + /// Error, modifier length is not numeric. + PSYC_PARSE_ERROR_MOD_LEN = -5, + /// Error, expected TAB before modifier value. + PSYC_PARSE_ERROR_MOD_TAB = -4, + /// Error, modifier name is missing. + PSYC_PARSE_ERROR_MOD_NAME = -3, + /// Error, expected NL after the content length. + PSYC_PARSE_ERROR_LENGTH = -2, + /// Error in packet. + PSYC_PARSE_ERROR = -1, + /// Buffer contains insufficient amount of data. + /// Fill another buffer and concatenate it with the end of the current buffer, + /// from the cursor position to the end. + PSYC_PARSE_INSUFFICIENT = 1, + /// Routing modifier parsing done. + /// Operator, name & value contains the respective parts. + PSYC_PARSE_ROUTING = 2, + /// State sync operation. + PSYC_PARSE_STATE_RESYNC = 3, + /// State reset operation. + PSYC_PARSE_STATE_RESET = 4, + /// Start of an incomplete entity modifier. + /// Operator & name are complete, value is incomplete. + PSYC_PARSE_ENTITY_START = 5, + /// Continuation of an incomplete entity modifier. + PSYC_PARSE_ENTITY_CONT = 6, + /// End of an incomplete entity modifier. + PSYC_PARSE_ENTITY_END = 7, + /// Entity modifier parsing done in one go. + /// Operator, name & value contains the respective parts. + PSYC_PARSE_ENTITY = 8, + /// Start of an incomplete body. + /// Name contains method, value contains part of the body. + /// Used when packet length is given + PSYC_PARSE_BODY_START = 9, + /// Continuation of an incomplete body. + /// Used when packet length is given + PSYC_PARSE_BODY_CONT = 10, + /// End of an incomplete body. + /// Used when packet length is given + PSYC_PARSE_BODY_END = 11, + /// Body parsing done in one go, name contains method, value contains body. + PSYC_PARSE_BODY = 12, + /// Start of an incomplete content, value contains part of content. + /// Used when PSYC_PARSE_ROUTING_ONLY is set. + PSYC_PARSE_CONTENT_START = 9, + /// Continuation of an incomplete content. + /// Used when PSYC_PARSE_ROUTING_ONLY is set. + PSYC_PARSE_CONTENT_CONT = 10, + /// End of an incomplete content. + /// Used when PSYC_PARSE_ROUTING_ONLY is set. + PSYC_PARSE_CONTENT_END = 11, + /// Content parsing done in one go, value contains the whole content. + /// Used when PSYC_PARSE_ROUTING_ONLY is set. + PSYC_PARSE_CONTENT = 12, + /// Finished parsing packet. + PSYC_PARSE_COMPLETE = 13, } PsycParseRC; /** @@ -199,48 +200,48 @@ typedef enum { * @see psyc_parse_list() */ typedef enum { - PSYC_PARSE_LIST_ERROR_DELIM = -4, - PSYC_PARSE_LIST_ERROR_LEN = -3, - PSYC_PARSE_LIST_ERROR_TYPE = -2, - PSYC_PARSE_LIST_ERROR = -1, - /// Completed parsing a list element. - PSYC_PARSE_LIST_ELEM = 1, - /// Reached end of buffer. - PSYC_PARSE_LIST_END = 2, - /// Binary list is incomplete. - PSYC_PARSE_LIST_INCOMPLETE = 3, + PSYC_PARSE_LIST_ERROR_DELIM = -4, + PSYC_PARSE_LIST_ERROR_LEN = -3, + PSYC_PARSE_LIST_ERROR_TYPE = -2, + PSYC_PARSE_LIST_ERROR = -1, + /// Completed parsing a list element. + PSYC_PARSE_LIST_ELEM = 1, + /// Reached end of buffer. + PSYC_PARSE_LIST_END = 2, + /// Binary list is incomplete. + PSYC_PARSE_LIST_INCOMPLETE = 3, } PsycParseListRC; /** * Struct for keeping parser state. */ typedef struct { - size_t cursor; ///< Current position in buffer. - size_t startc; ///< Position where the parsing would be resumed. - PsycString buffer; ///< Buffer with data to be parsed. - uint8_t flags; ///< Flags for the parser, see PsycParseFlag. - PsycPart part; ///< Part of the packet being parsed currently. + size_t cursor; ///< Current position in buffer. + size_t startc; ///< Position where the parsing would be resumed. + PsycString buffer; ///< Buffer with data to be parsed. + uint8_t flags; ///< Flags for the parser, see PsycParseFlag. + PsycPart part; ///< Part of the packet being parsed currently. - size_t routingLength; ///< Length of routing part parsed so far. - size_t contentParsed; ///< Number of bytes parsed from the content so far. - size_t contentLength; ///< Expected length of the content. - PsycBool 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. - PsycBool valueLengthFound; ///< Is there a length given for this modifier? + size_t routingLength; ///< Length of routing part parsed so far. + size_t contentParsed; ///< Number of bytes parsed from the content so far. + size_t contentLength; ///< Expected length of the content. + PsycBool 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. + PsycBool valueLengthFound; ///< Is there a length given for this modifier? } PsycParseState; /** * Struct for keeping list parser state. */ typedef struct { - size_t cursor; ///< Current position in buffer. - size_t startc; ///< Line start position. - PsycString buffer; ///< Buffer with data to be parsed. - PsycListType type; ///< List type. + size_t cursor; ///< Current position in buffer. + size_t startc; ///< Line start position. + PsycString buffer; ///< Buffer with data to be parsed. + PsycListType type; ///< List type. - 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. } PsycParseListState; /** @@ -250,14 +251,14 @@ typedef struct { * @param flags Flags to be set for the parser, see PsycParseFlag. * @see PsycParseFlag */ -static inline -void psyc_parse_state_init (PsycParseState *state, uint8_t flags) +static inline void +psyc_parse_state_init (PsycParseState *state, uint8_t flags) { - memset(state, 0, sizeof(PsycParseState)); - state->flags = flags; + memset(state, 0, sizeof(PsycParseState)); + state->flags = flags; - if (flags & PSYC_PARSE_START_AT_CONTENT) - state->part = PSYC_PART_CONTENT; + if (flags & PSYC_PARSE_START_AT_CONTENT) + state->part = PSYC_PART_CONTENT; } /** @@ -271,16 +272,17 @@ void psyc_parse_state_init (PsycParseState *state, uint8_t flags) * @param length length of the data in bytes * @see PsycString */ -static inline -void psyc_parse_buffer_set (PsycParseState *state, char *buffer, size_t length) +static inline void +psyc_parse_buffer_set (PsycParseState *state, char *buffer, + size_t length) { - state->buffer = (PsycString) {length, buffer}; - state->cursor = 0; + state->buffer = (PsycString) {length, buffer}; + state->cursor = 0; - if (state->flags & PSYC_PARSE_START_AT_CONTENT) { - state->contentLength = length; - state->contentLengthFound = PSYC_TRUE; - } + if (state->flags & PSYC_PARSE_START_AT_CONTENT) { + state->contentLength = length; + state->contentLengthFound = PSYC_TRUE; + } } /** @@ -288,68 +290,68 @@ void psyc_parse_buffer_set (PsycParseState *state, char *buffer, size_t length) * * @param state Pointer to the list state struct that should be initialized. */ -static inline -void psyc_parse_list_state_init (PsycParseListState *state) +static inline void +psyc_parse_list_state_init (PsycParseListState *state) { - memset(state, 0, sizeof(PsycParseListState)); + memset(state, 0, sizeof(PsycParseListState)); } /** * Sets a new buffer in the list parser state struct with data to be parsed. */ -static inline -void psyc_parse_list_buffer_set (PsycParseListState *state, char *buffer, size_t length) +static inline void +psyc_parse_list_buffer_set (PsycParseListState *state, char *buffer, size_t length) { - state->buffer = (PsycString) {length, buffer}; - state->cursor = 0; + state->buffer = (PsycString) {length, buffer}; + state->cursor = 0; } -static inline -size_t psyc_parse_content_length (PsycParseState *state) +static inline size_t +psyc_parse_content_length (PsycParseState *state) { - return state->contentLength; + return state->contentLength; } -static inline -PsycBool psyc_parse_content_length_found (PsycParseState *state) +static inline PsycBool +psyc_parse_content_length_found (PsycParseState *state) { - return state->contentLengthFound; + return state->contentLengthFound; } -static inline -size_t psyc_parse_value_length (PsycParseState *state) +static inline size_t +psyc_parse_value_length (PsycParseState *state) { - return state->valueLength; + return state->valueLength; } -static inline -PsycBool psyc_parse_value_length_found (PsycParseState *state) +static inline PsycBool +psyc_parse_value_length_found (PsycParseState *state) { - return state->valueLengthFound; + return state->valueLengthFound; } -static inline -size_t psyc_parse_cursor (PsycParseState *state) +static inline size_t +psyc_parse_cursor (PsycParseState *state) { - return state->cursor; + return state->cursor; } -static inline -size_t psyc_parse_buffer_length (PsycParseState *state) +static inline size_t +psyc_parse_buffer_length (PsycParseState *state) { - return state->buffer.length; + return state->buffer.length; } -static inline -size_t psyc_parse_remaining_length (PsycParseState *state) +static inline size_t +psyc_parse_remaining_length (PsycParseState *state) { - return state->buffer.length - state->cursor; + return state->buffer.length - state->cursor; } -static inline -const char * psyc_parse_remaining_buffer (PsycParseState *state) +static inline const char * +psyc_parse_remaining_buffer (PsycParseState *state) { - return state->buffer.data + state->cursor; + return state->buffer.data + state->cursor; } /** @@ -371,8 +373,9 @@ const char * psyc_parse_remaining_buffer (PsycParseState *state) #ifdef __INLINE_PSYC_PARSE static inline #endif -PsycParseRC psyc_parse (PsycParseState *state, char *oper, - PsycString *name, PsycString *value); +PsycParseRC +psyc_parse (PsycParseState *state, char *oper, + PsycString *name, PsycString *value); /** * List parser. @@ -388,142 +391,142 @@ PsycParseRC psyc_parse (PsycParseState *state, char *oper, #ifdef __INLINE_PSYC_PARSE static inline #endif -PsycParseListRC psyc_parse_list (PsycParseListState *state, PsycString *elem); +PsycParseListRC +psyc_parse_list (PsycParseListState *state, PsycString *elem); -static inline -PsycBool psyc_parse_number (const char *value, size_t len, int64_t *n) +static inline PsycBool +psyc_parse_number (const char *value, size_t len, int64_t *n) { - size_t c = 0; - uint8_t neg = 0; + size_t c = 0; + uint8_t neg = 0; - if (!value) - return PSYC_FALSE; - - if (value[0] == '-') - neg = ++c; - - *n = 0; - while (c < len && value[c] >= '0' && value[c] <= '9') - *n = 10 * *n + (value[c++] - '0'); - - if (c != len) - return PSYC_FALSE; - - if (neg) - *n = 0 - *n; - - return PSYC_TRUE; -} - -static inline -PsycBool psyc_parse_number_unsigned (const char *value, size_t len, uint64_t *n) -{ - size_t c = 0; - if (!value) - return PSYC_FALSE; - - *n = 0; - while (c < len && value[c] >= '0' && value[c] <= '9') - *n = 10 * *n + (value[c++] - '0'); - - return c == len ? PSYC_TRUE : PSYC_FALSE; -} - -static inline -PsycBool psyc_parse_time (const char *value, size_t len, time_t *t) -{ - return psyc_parse_number(value, len, t); -} - -static inline -PsycBool psyc_parse_date (const char *value, size_t len, time_t *t) -{ - if (psyc_parse_number(value, len, t)) { - *t += PSYC_EPOCH; - return PSYC_TRUE; - } + if (!value) return PSYC_FALSE; + + if (value[0] == '-') + neg = ++c; + + *n = 0; + while (c < len && value[c] >= '0' && value[c] <= '9') + *n = 10 * *n + (value[c++] - '0'); + + if (c != len) + return PSYC_FALSE; + + if (neg) + *n = 0 - *n; + + return PSYC_TRUE; +} + +static inline PsycBool +psyc_parse_number_unsigned (const char *value, size_t len, uint64_t *n) +{ + size_t c = 0; + if (!value) + return PSYC_FALSE; + + *n = 0; + while (c < len && value[c] >= '0' && value[c] <= '9') + *n = 10 * *n + (value[c++] - '0'); + + return c == len ? PSYC_TRUE : PSYC_FALSE; +} + +static inline PsycBool +psyc_parse_time (const char *value, size_t len, time_t *t) +{ + return psyc_parse_number(value, len, t); +} + +static inline PsycBool +psyc_parse_date (const char *value, size_t len, time_t *t) +{ + if (psyc_parse_number(value, len, t)) { + *t += PSYC_EPOCH; + return PSYC_TRUE; + } + return PSYC_FALSE; } /** * Determines if the argument is a glyph. * Glyphs are: : = + - ? ! */ -static inline -char psyc_is_glyph (uint8_t g) +static inline char +psyc_is_glyph (uint8_t g) { - switch(g) { - case ':': - case '=': - case '+': - case '-': - case '?': - case '!': - return 1; - default: - return 0; - } + switch (g) { + case ':': + case '=': + case '+': + case '-': + case '?': + case '!': + return 1; + default: + return 0; + } } /** * Determines if the argument is numeric. */ -static inline -char psyc_is_numeric (uint8_t c) +static inline char +psyc_is_numeric (uint8_t c) { - return c >= '0' && c <= '9'; + return c >= '0' && c <= '9'; } /** * Determines if the argument is alphabetic. */ -static inline -char psyc_is_alpha (uint8_t c) +static inline char +psyc_is_alpha (uint8_t c) { - return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); } /** * Determines if the argument is alphanumeric. */ -static inline -char psyc_is_alpha_numeric (uint8_t c) +static inline char +psyc_is_alpha_numeric (uint8_t c) { - return psyc_is_alpha(c) || psyc_is_numeric(c); + return psyc_is_alpha(c) || psyc_is_numeric(c); } /** * Determines if the argument is a keyword character. * Keyword characters are: alphanumeric and _ */ -static inline -char psyc_is_kw_char (uint8_t c) +static inline char +psyc_is_kw_char (uint8_t c) { - return psyc_is_alpha_numeric(c) || c == '_'; + return psyc_is_alpha_numeric(c) || c == '_'; } /** * Determines if the argument is a name character. * Name characters are: see opaque_part in RFC 2396 */ -static inline -char psyc_is_name_char (uint8_t c) +static inline char +psyc_is_name_char (uint8_t c) { - return psyc_is_alpha(c) || (c >= '$' && c <= ';') || - c == '_' || c == '!' || c == '?' || c == '=' || c == '@' || c == '~'; + return psyc_is_alpha(c) || (c >= '$' && c <= ';') + || c == '_' || c == '!' || c == '?' || c == '=' || c == '@' || c == '~'; } /** * Determines if the argument is a hostname character. * Hostname characters are: alphanumeric and - */ -static inline -char psyc_is_host_char (uint8_t c) +static inline char +psyc_is_host_char (uint8_t c) { - return psyc_is_alpha_numeric(c) || c == '.' || c == '-'; + return psyc_is_alpha_numeric(c) || c == '.' || c == '-'; } /** @} */ // end of parse group -#define PSYC_PARSE_H #endif diff --git a/include/psyc/render.h b/include/psyc/render.h index 9b18af6..d08174c 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -1,4 +1,5 @@ #ifndef PSYC_RENDER_H +#define PSYC_RENDER_H #include @@ -19,27 +20,25 @@ /** * Return codes for psyc_render. */ -typedef enum -{ - /// Error, method is missing, but data is present. - PSYC_RENDER_ERROR_METHOD_MISSING = -3, - /// Error, a modifier name is missing. - PSYC_RENDER_ERROR_MODIFIER_NAME_MISSING = -2, - /// Error, buffer is too small to render the packet. - PSYC_RENDER_ERROR = -1, - /// Packet is rendered successfully in the buffer. - PSYC_RENDER_SUCCESS = 0, +typedef enum { + /// Error, method is missing, but data is present. + PSYC_RENDER_ERROR_METHOD_MISSING = -3, + /// Error, a modifier name is missing. + PSYC_RENDER_ERROR_MODIFIER_NAME_MISSING = -2, + /// Error, buffer is too small to render the packet. + PSYC_RENDER_ERROR = -1, + /// Packet is rendered successfully in the buffer. + PSYC_RENDER_SUCCESS = 0, } PsycRenderRC; /** * Return codes for psyc_render_list. */ -typedef enum -{ - /// Error, buffer is too small to render the list. - PSYC_RENDER_LIST_ERROR = -1, - /// List is rendered successfully in the buffer. - PSYC_RENDER_LIST_SUCCESS = 0, +typedef enum { + /// Error, buffer is too small to render the list. + PSYC_RENDER_LIST_ERROR = -1, + /// List is rendered successfully in the buffer. + PSYC_RENDER_LIST_SUCCESS = 0, } PsycRenderListRC; /** @@ -59,7 +58,8 @@ typedef enum #ifdef __INLINE_PSYC_RENDER static inline #endif -PsycRenderRC psyc_render (PsycPacket *packet, char *buffer, size_t buflen); +PsycRenderRC +psyc_render (PsycPacket *packet, char *buffer, size_t buflen); /** * Render a PSYC list into a buffer. @@ -67,9 +67,9 @@ PsycRenderRC psyc_render (PsycPacket *packet, char *buffer, size_t buflen); #ifdef __INLINE_PSYC_RENDER static inline #endif -PsycRenderListRC psyc_render_list (PsycList *list, char *buffer, size_t buflen); +PsycRenderListRC +psyc_render_list (PsycList *list, char *buffer, size_t buflen); /** @} */ // end of render group -#define PSYC_RENDER_H #endif diff --git a/include/psyc/text.h b/include/psyc/text.h index 83b0232..02adbbe 100644 --- a/include/psyc/text.h +++ b/include/psyc/text.h @@ -1,4 +1,5 @@ #ifndef PSYC_TEXT_H +#define PSYC_TEXT_H /** * @file psyc/text.h @@ -19,39 +20,36 @@ * Return values for the text template parsing function. * @see psyc_text() */ -typedef enum -{ - /// No substitution was made, nothing was written to the buffer. - PSYC_TEXT_NO_SUBST = -1, - /// Text template parsing & rendering complete. - PSYC_TEXT_COMPLETE = 0, - /// Text template parsing & rendering is incomplete, because the buffer was too small. - /// Another call is required to this function after setting a new buffer. - PSYC_TEXT_INCOMPLETE = 1, +typedef enum { + /// No substitution was made, nothing was written to the buffer. + PSYC_TEXT_NO_SUBST = -1, + /// Text template parsing & rendering complete. + PSYC_TEXT_COMPLETE = 0, + /// Text template parsing & rendering is incomplete, because the buffer was too + /// small. Another call is required to this function after setting a new buffer. + PSYC_TEXT_INCOMPLETE = 1, } PsycTextRC; /** * Return values for PsycTextCB. */ -typedef enum -{ - /// Value not found, don't substitute anything. - PSYC_TEXT_VALUE_NOT_FOUND = -1, - /// Value found, substitute contents of the value variable. - PSYC_TEXT_VALUE_FOUND = 0, +typedef enum { + /// Value not found, don't substitute anything. + PSYC_TEXT_VALUE_NOT_FOUND = -1, + /// Value found, substitute contents of the value variable. + PSYC_TEXT_VALUE_FOUND = 0, } PsycTextValueRC; /** * Struct for keeping PSYC text parser state. */ -typedef struct -{ - size_t cursor; ///< current position in the template - size_t written; ///< number of bytes written to buffer - PsycString tmpl; ///< input buffer with text template to parse - PsycString buffer; ///< output buffer for rendered text - PsycString open; - PsycString close; +typedef struct { + size_t cursor; ///< current position in the template + size_t written; ///< number of bytes written to buffer + PsycString tmpl; ///< input buffer with text template to parse + PsycString buffer; ///< output buffer for rendered text + PsycString open; + PsycString close; } PsycTextState; /** @@ -64,7 +62,8 @@ typedef struct * PSYC_TEXT_VALUE_NOT_FOUND if no match found in which case psyc_text * leaves the original template text as is. */ -typedef PsycTextValueRC (*PsycTextCB)(const char *name, size_t len, PsycString *value, void *extra); +typedef PsycTextValueRC (*PsycTextCB) (const char *name, size_t len, + PsycString *value, void *extra); /** * Initializes the PSYC text state struct. @@ -75,17 +74,21 @@ typedef PsycTextValueRC (*PsycTextCB)(const char *name, size_t len, PsycString * * @param buffer Output buffer where the rendered text is going to be written. * @param buflen Length of output buffer. */ -static inline -void psyc_text_state_init (PsycTextState *state, - char *tmpl, size_t tmplen, - char *buffer, size_t buflen) +static inline void +psyc_text_state_init (PsycTextState *state, + char *tmpl, size_t tmplen, + char *buffer, size_t buflen) { - state->cursor = 0; - state->written = 0; - state->tmpl = (PsycString) {tmplen, tmpl}; - state->buffer = (PsycString) {buflen, buffer}; - state->open = (PsycString) {1, "["}; - state->close = (PsycString) {1, "]"}; + state->cursor = 0; + state->written = 0; + state->tmpl = (PsycString) { + tmplen, tmpl}; + state->buffer = (PsycString) { + buflen, buffer}; + state->open = (PsycString) { + 1, "["}; + state->close = (PsycString) { + 1, "]"}; } /** @@ -101,36 +104,40 @@ void psyc_text_state_init (PsycTextState *state, * @param close Closing brace. * @param closelen Length of closing brace. */ -static inline -void psyc_text_state_init_custom (PsycTextState *state, - char *tmpl, size_t tmplen, - char *buffer, size_t buflen, - char *open, size_t openlen, - char *close, size_t closelen) +static inline void +psyc_text_state_init_custom (PsycTextState *state, + char *tmpl, size_t tmplen, + char *buffer, size_t buflen, + char *open, size_t openlen, + char *close, size_t closelen) { - state->cursor = 0; - state->written = 0; - state->tmpl = (PsycString) {tmplen, tmpl}; - state->buffer = (PsycString) {buflen, buffer}; - state->open = (PsycString) {openlen, open}; - state->close = (PsycString) {closelen, close}; + state->cursor = 0; + state->written = 0; + state->tmpl = (PsycString) { + tmplen, tmpl}; + state->buffer = (PsycString) { + buflen, buffer}; + state->open = (PsycString) { + openlen, open}; + state->close = (PsycString) { + closelen, close}; } /** * Sets a new output buffer in the PSYC text state struct. */ -static inline -void psyc_text_buffer_set (PsycTextState *state, - char *buffer, size_t length) +static inline void +psyc_text_buffer_set (PsycTextState *state, char *buffer, size_t length) { - state->buffer = (PsycString){length, buffer}; - state->written = 0; + state->buffer = (PsycString) { + length, buffer}; + state->written = 0; } -static inline -size_t psyc_text_bytes_written (PsycTextState *state) +static inline size_t +psyc_text_bytes_written (PsycTextState *state) { - return state->written; + return state->written; } /** @@ -148,9 +155,9 @@ size_t psyc_text_bytes_written (PsycTextState *state) * * @see http://about.psyc.eu/psyctext **/ -PsycTextRC psyc_text (PsycTextState *state, PsycTextCB getValue, void *extra); +PsycTextRC +psyc_text (PsycTextState *state, PsycTextCB getValue, void *extra); /** @} */ // end of text group -#define PSYC_TEXT_H #endif diff --git a/include/psyc/uniform.h b/include/psyc/uniform.h index 332367e..e69599c 100644 --- a/include/psyc/uniform.h +++ b/include/psyc/uniform.h @@ -1,4 +1,6 @@ #ifndef PSYC_UNIFORM_H +#define PSYC_UNIFORM_H + /** * @file uniform.h * @brief Uniform parsing. @@ -7,76 +9,76 @@ #include typedef enum { - PSYC_SCHEME_PSYC = 0, - PSYC_SCHEME_IRC = 1, - PSYC_SCHEME_XMPP = 2, - PSYC_SCHEME_SIP = 3, + PSYC_SCHEME_PSYC = 0, + PSYC_SCHEME_IRC = 1, + PSYC_SCHEME_XMPP = 2, + PSYC_SCHEME_SIP = 3, } PsycScheme; typedef struct { // essential parts - uint8_t valid; - PsycScheme type; - PsycString scheme; - PsycString user; - PsycString pass; - PsycString host; - PsycString port; - PsycString transport; - PsycString resource; - PsycString query; - PsycString channel; + uint8_t valid; + PsycScheme type; + PsycString scheme; + PsycString user; + PsycString pass; + PsycString host; + PsycString port; + PsycString transport; + PsycString resource; + PsycString query; + PsycString channel; // convenient snippets of the URL - PsycString full; // the URL as such - PsycString body; // the URL without scheme and '//' - PsycString user_host; // mailto and xmpp style - PsycString host_port; // just host:port (and transport) - PsycString root; // root UNI - PsycString entity; // entity UNI, without the channel - PsycString slashes; // the // if the protocol has them - PsycString slash; // first / after host - PsycString nick; // whatever works as a nickname + PsycString full; // the URL as such + PsycString body; // the URL without scheme and '//' + PsycString user_host; // mailto and xmpp style + PsycString host_port; // just host:port (and transport) + PsycString root; // root UNI + PsycString entity; // entity UNI, without the channel + PsycString slashes; // the // if the protocol has them + PsycString slash; // first / after host + PsycString nick; // whatever works as a nickname } PsycUniform; typedef enum { - PSYC_UNIFORM_SCHEME = 0, - PSYC_UNIFORM_SLASHES, - PSYC_UNIFORM_USER, - PSYC_UNIFORM_PASS, - PSYC_UNIFORM_HOST, - PSYC_UNIFORM_PORT, - PSYC_UNIFORM_TRANSPORT, - PSYC_UNIFORM_RESOURCE, - PSYC_UNIFORM_QUERY, - PSYC_UNIFORM_CHANNEL, + PSYC_UNIFORM_SCHEME = 0, + PSYC_UNIFORM_SLASHES, + PSYC_UNIFORM_USER, + PSYC_UNIFORM_PASS, + PSYC_UNIFORM_HOST, + PSYC_UNIFORM_PORT, + PSYC_UNIFORM_TRANSPORT, + PSYC_UNIFORM_RESOURCE, + PSYC_UNIFORM_QUERY, + PSYC_UNIFORM_CHANNEL, } PsycUniformPart; typedef enum { - PSYC_PARSE_UNIFORM_INVALID_SLASHES = -7, - PSYC_PARSE_UNIFORM_INVALID_CHANNEL = -6, - PSYC_PARSE_UNIFORM_INVALID_RESOURCE = -5, - PSYC_PARSE_UNIFORM_INVALID_TRANSPORT = -4, - PSYC_PARSE_UNIFORM_INVALID_PORT = -3, - PSYC_PARSE_UNIFORM_INVALID_HOST = -2, - PSYC_PARSE_UNIFORM_INVALID_SCHEME = -1, + PSYC_PARSE_UNIFORM_INVALID_SLASHES = -7, + PSYC_PARSE_UNIFORM_INVALID_CHANNEL = -6, + PSYC_PARSE_UNIFORM_INVALID_RESOURCE = -5, + PSYC_PARSE_UNIFORM_INVALID_TRANSPORT = -4, + PSYC_PARSE_UNIFORM_INVALID_PORT = -3, + PSYC_PARSE_UNIFORM_INVALID_HOST = -2, + PSYC_PARSE_UNIFORM_INVALID_SCHEME = -1, } PsycParseUniformRC; typedef enum { - PSYC_TRANSPORT_TCP = 'c', - PSYC_TRANSPORT_UDP = 'd', - PSYC_TRANSPORT_TLS = 's', - PSYC_TRANSPORT_GNUNET = 'g', + PSYC_TRANSPORT_TCP = 'c', + PSYC_TRANSPORT_UDP = 'd', + PSYC_TRANSPORT_TLS = 's', + PSYC_TRANSPORT_GNUNET = 'g', } PsycTransport; typedef enum { - PSYC_ENTITY_ROOT = 0, - PSYC_ENTITY_PERSON = '~', - PSYC_ENTITY_PLACE = '@', - PSYC_ENTITY_SERVICE = '$', + PSYC_ENTITY_ROOT = 0, + PSYC_ENTITY_PERSON = '~', + PSYC_ENTITY_PLACE = '@', + PSYC_ENTITY_SERVICE = '$', } PsycEntityType; -int psyc_uniform_parse (PsycUniform *uni, char *str, size_t length); +int +psyc_uniform_parse (PsycUniform * uni, char *str, size_t length); -#define PSYC_UNIFORM_H #endif diff --git a/include/psyc/variable.h b/include/psyc/variable.h index 0c3d9b9..957698e 100644 --- a/include/psyc/variable.h +++ b/include/psyc/variable.h @@ -1,4 +1,5 @@ #ifndef PSYC_VARIABLE_H +#define PSYC_VARIABLE_H /** * @file psyc/variable.h @@ -16,22 +17,23 @@ extern const size_t psyc_var_types_num; /** * Is this a routing variable name? */ -PsycBool psyc_var_is_routing (const char *name, size_t len); +PsycBool +psyc_var_is_routing (const char *name, size_t len); /** * Get the type of variable name. */ -PsycType psyc_var_type (const char *name, size_t len); +PsycType +psyc_var_type (const char *name, size_t len); /** * Is this a list variable name? */ -static inline -PsycBool psyc_var_is_list (const char *name, size_t len) +static inline PsycBool +psyc_var_is_list (const char *name, size_t len) { - return len < 5 || memcmp(name, "_list", 5) != 0 || - (len > 5 && name[5] != '_') ? PSYC_FALSE : PSYC_TRUE; + return len < 5 || memcmp(name, "_list", 5) != 0 || (len > 5 && name[5] != '_') + ? PSYC_FALSE : PSYC_TRUE; } -#define PSYC_VARIABLE_H #endif diff --git a/src/itoa.c b/src/itoa.c index 1292d9b..3af833a 100644 --- a/src/itoa.c +++ b/src/itoa.c @@ -1,39 +1,45 @@ #define ALPHANUMS "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" -/** converts an integer to a string, using a base of 10 by default. +/** + * Converts an integer to a string, using a base of 10 by default. * - * if you NULL out the output buffer it will return the expected + * If you NULL out the output buffer it will return the expected * output string length anyway. */ -int itoa(int number, char* out, int base) { - int t, count; - char *p, *q; - char c; +int +itoa (int number, char *out, int base) +{ + int t, count; + char *p, *q; + char c; - p = q = out; - if (base < 2 || base > 36) base = 10; + p = q = out; + if (base < 2 || base > 36) + base = 10; - do { - t = number; - number /= base; - if (out) *p = ALPHANUMS[t+35 - number*base]; - p++; - } while (number); + do { + t = number; + number /= base; + if (out) + *p = ALPHANUMS[t + 35 - number * base]; + p++; + } while (number); - if (t < 0) { - if (out) *p = '-'; - p++; + if (t < 0) { + if (out) + *p = '-'; + p++; + } + count = p - out; + if (out) { + *p-- = '\0'; + while (q < p) { + c = *p; + *p-- = *q; + *q++ = c; } - count = p-out; - if (out) { - *p-- = '\0'; - while(q < p) { - c = *p; - *p-- = *q; - *q++ = c; - } - } - return count; + } + return count; } /* This little test program shows that itoa() is roughly 3 times faster @@ -45,41 +51,44 @@ int itoa(int number, char* out, int base) { #include #include -int main(int argc, char **argv) { - char out[4404]; - int in[44]; - int c, i, j; - - if (argc < 3 || argc > sizeof(in)) { - printf("Usage: %s +\n\nExample: %s 999999 123 234 345 -49 -21892\n", argv[0], argv[0]); - return -1; - } - for (j=argc-1; j; j--) { -// printf("Looking at arg #%d: %s\n", j, argv[j]); - in[j] = atoi(argv[j]); -// printf("Got %d: %d\n", j, in[j]); - } - for (i=in[1]; i; i--) { - c = 0; - for (j=argc-1; j>1; j--) { -# if 0 - // use good old sprintf - c += sprintf(&out[c], " %d", in[j]); -# else -# if 1 - // use the itoa implementation - out[c++] = ' '; - c += itoa(in[j], &out[c], 10); -# else - // just count the needed space - c += itoa(in[j], NULL, 10) + 1; -# endif -# endif - } - } - printf("%d times, %d count, buffer len: %d, buffer: %s\n", - in[1], c, strlen(out), ""); // out - return 0; -} +int +main (int argc, char **argv) +{ + char out[4404]; + int in[44]; + int c, i, j; + if (argc < 3 || argc > sizeof(in)) { + printf("Usage: %s +\n\n" + "Example: %s 999999 123 234 345 -49 -21892\n", + argv[0], argv[0]); + return -1; + } + for (j = argc - 1; j; j--) { + //printf("Looking at arg #%d: %s\n", j, argv[j]); + in[j] = atoi(argv[j]); + //printf("Got %d: %d\n", j, in[j]); + } + for (i = in[1]; i; i--) { + c = 0; + for (j = argc - 1; j > 1; j--) { +#if 0 + // use good old sprintf + c += sprintf(&out[c], " %d", in[j]); +#else +#if 1 + // use the itoa implementation + out[c++] = ' '; + c += itoa(in[j], &out[c], 10); +#else + // just count the needed space + c += itoa(in[j], NULL, 10) + 1; +#endif +#endif + } + } + printf("%d times, %d count, buffer len: %d, buffer: %s\n", + in[1], c, strlen(out), ""); // out + return 0; +} #endif diff --git a/src/match.c b/src/match.c index 56ec8ce..ac63b5e 100644 --- a/src/match.c +++ b/src/match.c @@ -1,158 +1,171 @@ #include "lib.h" -int psyc_inherits (char* sho, size_t slen, - char* lon, size_t llen) { +int +psyc_inherits(char *sho, size_t slen, char *lon, size_t llen) +{ + // this allows to pass zero-terminated strings instead of providing + // the length.. but we would be faster here if we expected the callee + // to always use the PSYC_C2ARG() macro instead. additionally, the + // empty string would then be fully supported (in case you want that) + // Disabled this, let's use that macro rather. + //if (!slen) slen = strlen(sho); + //if (!llen) llen = strlen(lon); - // this allows to pass zero-terminated strings instead of providing - // the length.. but we would be faster here if we expected the callee - // to always use the PSYC_C2ARG() macro instead. additionally, the - // empty string would then be fully supported (in case you want that) - // Disabled this, let's use that macro rather. - //if (!slen) slen = strlen(sho); - //if (!llen) llen = strlen(lon); + if (slen == 0 || *sho != '_' || llen == 0 || *lon != '_') { + P1(("Please use long format keywords (compact ones would be faster, I know..)\n")); + return -2; + } - if (slen == 0 || *sho != '_' || - llen == 0 || *lon != '_') { - P1(("Please use long format keywords (compact ones would be faster, I know..)\n")) - return -2; - } + if (slen > llen) { + P1(("The long string is shorter than the short one.\n")); + return -3; + } - if (slen > llen) { - P1(("The long string is shorter than the short one.\n")) - return -3; - } - - if (!strncmp(sho, lon, slen)) { - /* according to PSYC spec we have hereby already proved - * inheritance. the following check is optional! - */ - if (llen > slen && lon[slen] != '_') { - /* It is illegal to introduce a keyword family - * that starts just like an existing one. Since - * _failure exists, you can't use _fail. But - * implementations are not required to recognize - * that. - */ - P1(("Illegal choice of keyword names!\n")) - return -4; - } - return 0; - } - P4(("%.*s does not inherit from %.*s.\n", (int)llen, lon, (int)slen, sho)) - return 1; -} - -int psyc_matches (char* sho, size_t slen, - char* lon, size_t llen) { - char *s, *l, *se, *le; - - //if (!slen) slen = strlen(sho); - //if (!llen) llen = strlen(lon); - - if (slen == 0 || *sho != '_' || - llen == 0 || *lon != '_') { - P1(("Please use long format keywords (compact ones would be faster, I know..)\n")) - return -2; - } - - if (slen > llen) { - P1(("The long string is shorter than the short one.\n")) - return -3; - } - - if (slen == llen) { - if (!strncmp(sho, lon, slen)) { - P1(("Identical arguments.\n")) - return 0; - } - P1(("Same length but different.\nNo match, but they could be related or have a common type.\n")) - return -4; - } - P3(("# psyc_matches short '%.*s' in long '%.*s' ?\n", (int)slen, sho, (int)llen, lon)) - - se = sho+slen; - le = lon+llen; - sho++; lon++; slen--; llen--; - while(*sho && sho < se) { - P3(("# comparing short '%.*s' (%d)\n", (int)slen, sho, (int)slen)) - unless (s = memchr(sho, '_', slen)) s = se; - P4(("# sho goes '%c' and lon goes '%c'\n", *sho, (int)*lon)) - while(*lon && lon < le) { - P3(("# against long '%.*s' (%d)\n", (int)llen, lon, (int)llen)) - unless (l = memchr(lon, '_', llen)) l = le; - P3(("# %ld == %ld && !strncmp '%.*s', '%.*s'\n", s-sho, l-lon, (int)(s-sho), sho, (int)(s-sho), lon)) - if (l-lon == s-sho && !strncmp(sho, lon, s-sho)) goto foundone; - P4(("# failed\n")) - llen -= l-lon + 1; - lon = ++l; - } - goto failed; -foundone: - P3(("# found %ld of short '%.*s' and long '%.*s'\n", s-sho, (int)(s-sho), sho, (int)(s-sho), lon)) - llen -= l-lon; - slen -= s-sho; - sho = ++s; - lon = ++l; + if (!strncmp(sho, lon, slen)) { + /* according to PSYC spec we have hereby already proved + * inheritance. the following check is optional! + */ + if (llen > slen && lon[slen] != '_') { + /* It is illegal to introduce a keyword family + * that starts just like an existing one. Since + * _failure exists, you can't use _fail. But + * implementations are not required to recognize + * that. + */ + P1(("Illegal choice of keyword names!\n")); + return -4; } return 0; -failed: - P4(("No, they don't match.\n")) - return 1; + } + P4(("%.*s does not inherit from %.*s.\n", (int) llen, lon, (int) slen, sho)); + return 1; +} + +int +psyc_matches(char *sho, size_t slen, char *lon, size_t llen) +{ + char *s, *l, *se, *le; + + //if (!slen) slen = strlen(sho); + //if (!llen) llen = strlen(lon); + + if (slen == 0 || *sho != '_' || llen == 0 || *lon != '_') { + P1(("Please use long format keywords (compact ones would be faster, I know..)\n")); + return -2; + } + + if (slen > llen) { + P1(("The long string is shorter than the short one.\n")); + return -3; + } + + if (slen == llen) { + if (!strncmp(sho, lon, slen)) { + P1(("Identical arguments.\n")); + return 0; + } + P1(("Same length but different.\nNo match, but they could be related or have a common type.\n")); + return -4; + } + P3(("# psyc_matches short '%.*s' in long '%.*s' ?\n", (int) slen, sho, + (int) llen, lon)); + + se = sho + slen; + le = lon + llen; + sho++; + lon++; + slen--; + llen--; + while (*sho && sho < se) { + P3(("# comparing short '%.*s' (%d)\n", (int) slen, sho, (int) slen)); + unless(s = memchr(sho, '_', slen)) s = se; + P4(("# sho goes '%c' and lon goes '%c'\n", *sho, (int) *lon)); + while (*lon && lon < le) { + P3(("# against long '%.*s' (%d)\n", (int) llen, lon, (int) llen)); + unless(l = memchr(lon, '_', llen)) l = le; + P3(("# %ld == %ld && !strncmp '%.*s', '%.*s'\n", s - sho, l - lon, + (int) (s - sho), sho, (int) (s - sho), lon)); + if (l - lon == s - sho && !strncmp(sho, lon, s - sho)) + goto foundone; + P4(("# failed\n")); + llen -= l - lon + 1; + lon = ++l; + } + goto failed; + foundone: + P3(("# found %ld of short '%.*s' and long '%.*s'\n", s - sho, + (int) (s - sho), sho, (int) (s - sho), lon)); + llen -= l - lon; + slen -= s - sho; + sho = ++s; + lon = ++l; + } + return 0; + failed: + P4(("No, they don't match.\n")); + return 1; } /** * Look up value associated with a key in a dictionary. */ -void * psyc_dict_lookup (const PsycDict *dict, size_t size, - const char *key, size_t keylen, - PsycBool inherit, int8_t *matching) +void * +psyc_dict_lookup(const PsycDict * dict, size_t size, + const char *key, size_t keylen, + PsycBool inherit, int8_t * matching) { - size_t cursor = 1; - uint8_t i, m = 0; + size_t cursor = 1; + uint8_t i, m = 0; - if (keylen < 2 || key[0] != '_') - return 0; + if (keylen < 2 || key[0] != '_') + return 0; - // first find the keywords with matching length - for (i=0; i dict[i].key.length && key[dict[i].key.length] == '_')) - matching[m++] = i; + // first find the keywords with matching length + for (i = 0; i < size; i++) { + if (keylen == dict[i].key.length + || (inherit && keylen > dict[i].key.length + && key[dict[i].key.length] == '_')) + matching[m++] = i; + } - matching[m] = -1; // mark the end of matching indexes + matching[m] = -1; // mark the end of matching indexes - while (cursor < keylen && matching[0] >= 0) { - for (i = m = 0; i < size; i++) { - if (matching[i] < 0) - break; // reached the end of possible matches - if (cursor < dict[matching[i]].key.length && - dict[matching[i]].key.data[cursor] == key[cursor]) - matching[m++] = matching[i]; // found a match, update matching indexes - else if (cursor == dict[matching[i]].key.length && key[cursor] == '_') - return dict[matching[0]].value; // _ after the end of a matching prefix - else if (dict[matching[i]].key.data[cursor] > key[cursor]) - break; // passed the possible matches in alphabetical order in the dict - } - - if (m < size) - matching[m] = -1; // mark the end of matching indexes - - cursor++; + while (cursor < keylen && matching[0] >= 0) { + for (i = m = 0; i < size; i++) { + if (matching[i] < 0) + break; // reached the end of possible matches + if (cursor < dict[matching[i]].key.length && + dict[matching[i]].key.data[cursor] == key[cursor]) + matching[m++] = matching[i]; // found a match, update matching indexes + else if (cursor == dict[matching[i]].key.length && key[cursor] == '_') + return dict[matching[0]].value; // _ after the end of a matching prefix + else if (dict[matching[i]].key.data[cursor] > key[cursor]) + break; // passed the possible matches in alphabetical order in the dict } - // return first match if found - return matching[0] >= 0 ? dict[matching[0]].value : 0; + if (m < size) + matching[m] = -1; // mark the end of matching indexes + + cursor++; + } + + // return first match if found + return matching[0] >= 0 ? dict[matching[0]].value : 0; } #ifdef CMDTOOL -int main(int argc, char **argv) { - if (argc != 3) { - printf("Usage: %s \n\nExample: %s _failure_delivery _failure_unsuccessful_delivery_death\n", argv[0], argv[0]); - return -1; - } - if (psyc_matches(argv[1], 0, argv[2], 0) == 0) - printf("Yes, %s matches %s!\n", argv[1], argv[2]); - if (psyc_inherits(argv[1], 0, argv[2], 0) == 0) - printf("Yes, %s inherits from %s!\n", argv[2], argv[1]); +int +main(int argc, char **argv) +{ + if (argc != 3) { + printf("Usage: %s \n\n" + "Example: %s _failure_delivery _failure_unsuccessful_delivery_death\n", + argv[0], argv[0]); + return -1; + } + if (psyc_matches(argv[1], 0, argv[2], 0) == 0) + printf("Yes, %s matches %s!\n", argv[1], argv[2]); + if (psyc_inherits(argv[1], 0, argv[2], 0) == 0) + printf("Yes, %s inherits from %s!\n", argv[2], argv[1]); } #endif diff --git a/src/memmem.c b/src/memmem.c index 7bda893..609e656 100644 --- a/src/memmem.c +++ b/src/memmem.c @@ -31,32 +31,31 @@ /* * Find the first occurrence of the byte string s in byte string l. */ - void * memmem(const void *l, size_t l_len, const void *s, size_t s_len) { - register char *cur, *last; - const char *cl = (const char *)l; - const char *cs = (const char *)s; - - /* we need something to compare */ - if (l_len == 0 || s_len == 0) - return NULL; - - /* "s" must be smaller or equal to "l" */ - if (l_len < s_len) - return NULL; - - /* special case where s_len == 1 */ - if (s_len == 1) - return memchr(l, (int)*cs, l_len); - - /* the last position where its possible to find "s" in "l" */ - last = (char *)cl + l_len - s_len; - - for (cur = (char *)cl; cur <= last; cur++) - if (cur[0] == cs[0] && memcmp(cur, cs, s_len) == 0) - return cur; + register char *cur, *last; + const char *cl = (const char *) l; + const char *cs = (const char *) s; + /* we need something to compare */ + if (l_len == 0 || s_len == 0) return NULL; + + /* "s" must be smaller or equal to "l" */ + if (l_len < s_len) + return NULL; + + /* special case where s_len == 1 */ + if (s_len == 1) + return memchr(l, (int) *cs, l_len); + + /* the last position where its possible to find "s" in "l" */ + last = (char *) cl + l_len - s_len; + + for (cur = (char *) cl; cur <= last; cur++) + if (cur[0] == cs[0] && memcmp(cur, cs, s_len) == 0) + return cur; + + return NULL; } diff --git a/src/packet.c b/src/packet.c index e8594fd..d637e70 100644 --- a/src/packet.c +++ b/src/packet.c @@ -2,169 +2,164 @@ #include #include -inline -PsycListFlag psyc_list_length_check (PsycList *list) +inline PsycListFlag +psyc_list_length_check (PsycList * list) { - PsycListFlag flag = PSYC_LIST_NO_LENGTH; - size_t i, length = 0; + PsycListFlag flag = PSYC_LIST_NO_LENGTH; + size_t i, length = 0; + for (i = 0; i < list->num_elems; i++) { + PsycString *elem = &list->elems[i]; + length += 1 + elem->length; // |elem + if (length > PSYC_MODIFIER_SIZE_THRESHOLD || + memchr(elem->data, (int) '|', elem->length) || + memchr(elem->data, (int) '\n', elem->length)) { + flag = PSYC_LIST_NEED_LENGTH; + break; + } + } + + return flag; +} + +inline PsycListFlag +psyc_list_length (PsycList * list) +{ + size_t i, length = 0; + + if (list->flag == PSYC_LIST_NEED_LENGTH) { + for (i = 0; i < list->num_elems; i++) { + if (i > 0) + length++; // | + length += // length SP elem + psyc_num_length(list->elems[i].length) + 1 + list->elems[i].length; + } + } else { for (i = 0; i < list->num_elems; i++) - { - PsycString *elem = &list->elems[i]; - length += 1 + elem->length; // |elem - if (length > PSYC_MODIFIER_SIZE_THRESHOLD || - memchr(elem->data, (int)'|', elem->length) || - memchr(elem->data, (int)'\n', elem->length)) - { - flag = PSYC_LIST_NEED_LENGTH; - break; - } - } + length += 1 + list->elems[i].length; // |elem + } - return flag; + return length; } -inline -PsycListFlag psyc_list_length (PsycList *list) +inline void +psyc_list_init (PsycList * list, PsycString * elems, size_t num_elems, + PsycListFlag flag) { - size_t i, length = 0; + *list = (PsycList) { + num_elems, elems, 0, flag}; - if (list->flag == PSYC_LIST_NEED_LENGTH) - { - for (i = 0; i < list->num_elems; i++) - { - if (i > 0) - length++; // | - length += psyc_num_length(list->elems[i].length) + 1 + list->elems[i].length; // length SP elem - } - } - else - { - for (i = 0; i < list->num_elems; i++) - length += 1 + list->elems[i].length; // |elem - } + if (flag == PSYC_LIST_CHECK_LENGTH) // check if list elements need length + list->flag = psyc_list_length_check(list); - return length; -} - -inline -void psyc_list_init (PsycList *list, PsycString *elems, size_t num_elems, - PsycListFlag flag) -{ - *list = (PsycList) {num_elems, elems, 0, flag}; - - if (flag == PSYC_LIST_CHECK_LENGTH) // check if list elements need length - list->flag = psyc_list_length_check(list); - - list->length = psyc_list_length(list); + list->length = psyc_list_length(list); } -inline -size_t psyc_modifier_length (PsycModifier *m) +inline size_t +psyc_modifier_length (PsycModifier * m) { - size_t length = 2; // oper\n - if (m->name.length > 0) - length += m->name.length + 1 + m->value.length; // name\tvalue + size_t length = 2; // oper\n + if (m->name.length > 0) + length += m->name.length + 1 + m->value.length; // name\tvalue - if (m->flag == PSYC_MODIFIER_NEED_LENGTH) // add length of length if needed - length += psyc_num_length(m->value.length) + 1; // SP length + if (m->flag == PSYC_MODIFIER_NEED_LENGTH) // add length of length if needed + length += psyc_num_length(m->value.length) + 1; // SP length - return length; + return length; } -inline -PsycPacketFlag psyc_packet_length_check (PsycPacket *p) +inline PsycPacketFlag +psyc_packet_length_check (PsycPacket * p) { - if (p->data.length == 1 && p->data.data[0] == PSYC_PACKET_DELIMITER_CHAR) - return PSYC_PACKET_NEED_LENGTH; + if (p->data.length == 1 && p->data.data[0] == PSYC_PACKET_DELIMITER_CHAR) + return PSYC_PACKET_NEED_LENGTH; - if (p->data.length > PSYC_CONTENT_SIZE_THRESHOLD) - return PSYC_PACKET_NEED_LENGTH; + if (p->data.length > PSYC_CONTENT_SIZE_THRESHOLD) + return PSYC_PACKET_NEED_LENGTH; - int i; - // if any entity modifiers need length it is possible they contain - // a packet terminator, thus the content should have a length as well + int i; + // If any entity modifiers need length, it is possible they contain + // a packet terminator, thus the content should have a length as well. + for (i = 0; i < p->entity.lines; i++) + if (p->entity.modifiers[i].flag == PSYC_MODIFIER_NEED_LENGTH) + return PSYC_PACKET_NEED_LENGTH; + + if (memmem(p->data.data, p->data.length, PSYC_C2ARG(PSYC_PACKET_DELIMITER))) + return PSYC_PACKET_NEED_LENGTH; + + return PSYC_PACKET_NO_LENGTH; +} + +inline size_t +psyc_packet_length_set (PsycPacket * p) +{ + size_t i; + p->routingLength = 0; + p->contentLength = 0; + + // add routing header length + for (i = 0; i < p->routing.lines; i++) + p->routingLength += psyc_modifier_length(&(p->routing.modifiers[i])); + + if (p->content.length) + p->contentLength = p->content.length; + else { + // add state operation + if (p->stateop != PSYC_STATE_NOOP) + p->contentLength += 2; // op\n + + // add entity header length for (i = 0; i < p->entity.lines; i++) - if (p->entity.modifiers[i].flag == PSYC_MODIFIER_NEED_LENGTH) - return PSYC_PACKET_NEED_LENGTH; + p->contentLength += psyc_modifier_length(&(p->entity.modifiers[i])); - if (memmem(p->data.data, p->data.length, PSYC_C2ARG(PSYC_PACKET_DELIMITER))) - return PSYC_PACKET_NEED_LENGTH; + // add length of method, data & delimiter + if (p->method.length) + p->contentLength += p->method.length + 1; // method\n + if (p->data.length) + p->contentLength += p->data.length + 1; // data\n + } - return PSYC_PACKET_NO_LENGTH; + // set total length: routing-header content |\n + p->length = p->routingLength + p->contentLength + 2; + + if (p->contentLength > 0 || p->flag == PSYC_PACKET_NEED_LENGTH) + p->length++; // add \n at the start of the content part + + if (p->flag == PSYC_PACKET_NEED_LENGTH) // add length of length if needed + p->length += psyc_num_length(p->contentLength); + + return p->length; } -inline -size_t psyc_packet_length_set (PsycPacket *p) +inline void +psyc_packet_init (PsycPacket * p, + PsycModifier * routing, size_t routinglen, + PsycModifier * entity, size_t entitylen, + char *method, size_t methodlen, + char *data, size_t datalen, + char stateop, PsycPacketFlag flag) { - size_t i; - p->routingLength = 0; - p->contentLength = 0; + *p = (PsycPacket) {{routinglen, routing}, {entitylen, entity}, stateop, + {methodlen, method}, {datalen, data}, {0, 0}, 0, 0, flag}; - // add routing header length - for (i = 0; i < p->routing.lines; i++) - p->routingLength += psyc_modifier_length(&(p->routing.modifiers[i])); + if (flag == PSYC_PACKET_CHECK_LENGTH) // find out if it needs length + p->flag = psyc_packet_length_check(p); - if (p->content.length) - p->contentLength = p->content.length; - else - { - // add state operation - if (p->stateop != PSYC_STATE_NOOP) - p->contentLength += 2; // op\n - - // add entity header length - for (i = 0; i < p->entity.lines; i++) - p->contentLength += psyc_modifier_length(&(p->entity.modifiers[i])); - - // add length of method, data & delimiter - if (p->method.length) - p->contentLength += p->method.length + 1; // method\n - if (p->data.length) - p->contentLength += p->data.length + 1; // data\n - } - - // set total length: routing-header content |\n - p->length = p->routingLength + p->contentLength + 2; - - if (p->contentLength > 0 || p->flag == PSYC_PACKET_NEED_LENGTH) - p->length++; // add \n at the start of the content part - - if (p->flag == PSYC_PACKET_NEED_LENGTH) // add length of length if needed - p->length += psyc_num_length(p->contentLength); - - return p->length; + psyc_packet_length_set(p); } -inline -void psyc_packet_init (PsycPacket *p, - PsycModifier *routing, size_t routinglen, - PsycModifier *entity, size_t entitylen, - char *method, size_t methodlen, - char *data, size_t datalen, - char stateop, PsycPacketFlag flag) +inline void +psyc_packet_init_raw (PsycPacket * p, + PsycModifier * routing, size_t routinglen, + char *content, size_t contentlen, + PsycPacketFlag flag) { - *p = (PsycPacket) {{routinglen, routing}, {entitylen, entity}, stateop, - {methodlen, method}, {datalen, data}, {0,0}, 0, 0, flag}; + *p = (PsycPacket) {{routinglen, routing}, {0, 0}, 0, {0, 0}, {0, 0}, + {contentlen, content}, 0, 0, flag}; - if (flag == PSYC_PACKET_CHECK_LENGTH) // find out if it needs length - p->flag = psyc_packet_length_check(p); + if (flag == PSYC_PACKET_CHECK_LENGTH) // find out if it needs length + p->flag = psyc_packet_length_check(p); - psyc_packet_length_set(p); -} - -inline -void psyc_packet_init_raw (PsycPacket *p, - PsycModifier *routing, size_t routinglen, - char *content, size_t contentlen, - PsycPacketFlag flag) -{ - *p = (PsycPacket) {{routinglen, routing}, {0,0}, 0, {0,0}, {0,0}, - {contentlen, content}, 0, 0, flag}; - - if (flag == PSYC_PACKET_CHECK_LENGTH) // find out if it needs length - p->flag = psyc_packet_length_check(p); - - psyc_packet_length_set(p); + psyc_packet_length_set(p); } diff --git a/src/parse.c b/src/parse.c index 1257845..5a3dd05 100644 --- a/src/parse.c +++ b/src/parse.c @@ -9,19 +9,18 @@ #include #include -#define ADVANCE_CURSOR_OR_RETURN(ret) \ - if (++(state->cursor) >= state->buffer.length) \ - { \ - state->cursor = state->startc; \ - return ret; \ - } +#define ADVANCE_CURSOR_OR_RETURN(ret) \ + if (++(state->cursor) >= state->buffer.length) { \ + state->cursor = state->startc; \ + return ret; \ + } typedef enum { - PARSE_ERROR = -1, - PARSE_SUCCESS = 0, - PARSE_INSUFFICIENT = 1, - PARSE_COMPLETE = 100, - PARSE_INCOMPLETE = 101, + PARSE_ERROR = -1, + PARSE_SUCCESS = 0, + PARSE_INSUFFICIENT = 1, + PARSE_COMPLETE = 100, + PARSE_INCOMPLETE = 101, } ParseRC; /** @@ -29,19 +28,18 @@ typedef enum { * It should contain one or more keyword characters. * @return PARSE_ERROR or PARSE_SUCCESS */ -static inline -ParseRC psyc_parse_keyword (PsycParseState *state, PsycString *name) +static inline ParseRC +psyc_parse_keyword (PsycParseState *state, PsycString *name) { - name->data = state->buffer.data + state->cursor; - name->length = 0; + name->data = state->buffer.data + state->cursor; + name->length = 0; - while (psyc_is_kw_char(state->buffer.data[state->cursor])) - { - name->length++; // was a valid char, increase length - ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); - } + while (psyc_is_kw_char(state->buffer.data[state->cursor])) { + name->length++; // was a valid char, increase length + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + } - return name->length > 0 ? PARSE_SUCCESS : PARSE_ERROR; + return name->length > 0 ? PARSE_SUCCESS : PARSE_ERROR; } /** @@ -54,490 +52,448 @@ ParseRC psyc_parse_keyword (PsycParseState *state, PsycString *name) * * @return PARSE_COMPLETE or PARSE_INCOMPLETE */ -static inline -ParseRC psyc_parse_binary_value (PsycParseState *state, PsycString *value, - size_t *length, size_t *parsed) +static inline ParseRC +psyc_parse_binary_value (PsycParseState *state, PsycString *value, + size_t *length, size_t *parsed) { - size_t remaining = *length - *parsed; - value->data = state->buffer.data + state->cursor; + size_t remaining = *length - *parsed; + value->data = state->buffer.data + state->cursor; - if (state->cursor + remaining > state->buffer.length) - { // value doesn't fit in the buffer completely - value->length = state->buffer.length - state->cursor; - state->cursor += value->length; - *parsed += value->length; - return PARSE_INCOMPLETE; - } + if (state->cursor + remaining > state->buffer.length) { + // value doesn't fit in the buffer completely + value->length = state->buffer.length - state->cursor; + state->cursor += value->length; + *parsed += value->length; + return PARSE_INCOMPLETE; + } - value->length = remaining; - state->cursor += remaining; - *parsed += remaining; - assert(*parsed == *length); + value->length = remaining; + state->cursor += remaining; + *parsed += remaining; + assert(*parsed == *length); - return PARSE_COMPLETE; + return PARSE_COMPLETE; } /** * Parse simple or binary variable. * @return PARSE_ERROR or PARSE_SUCCESS */ -static inline -ParseRC psyc_parse_modifier (PsycParseState *state, char *oper, - PsycString *name, PsycString *value) +static inline ParseRC +psyc_parse_modifier (PsycParseState *state, char *oper, + PsycString *name, PsycString *value) { - *oper = *(state->buffer.data + state->cursor); + *oper = *(state->buffer.data + state->cursor); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + + ParseRC ret = psyc_parse_keyword(state, name); + if (ret == PARSE_ERROR) + return PSYC_PARSE_ERROR_MOD_NAME; + else if (ret != PARSE_SUCCESS) + return ret; + + size_t length = 0; + value->length = 0; + state->valueLength = 0; + state->valueLengthFound = 0; + state->valueParsed = 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.data[state->cursor] == ' ') { + // binary arg + // After SP the length follows. ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); - ParseRC ret = psyc_parse_keyword(state, name); - if (ret == PARSE_ERROR) - return PSYC_PARSE_ERROR_MOD_NAME; - else if (ret != PARSE_SUCCESS) - return ret; - - size_t length = 0; - value->length = 0; - state->valueLength = 0; - state->valueLengthFound = 0; - state->valueParsed = 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.data[state->cursor] == ' ') // binary arg - { // After SP the length follows. + if (psyc_is_numeric(state->buffer.data[state->cursor])) { + state->valueLengthFound = 1; + do { + length = 10 * length + state->buffer.data[state->cursor] - '0'; ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + } + while (psyc_is_numeric(state->buffer.data[state->cursor])); + state->valueLength = length; + } else + return PSYC_PARSE_ERROR_MOD_LEN; - if (psyc_is_numeric(state->buffer.data[state->cursor])) - { - state->valueLengthFound = 1; - do - { - length = 10 * length + state->buffer.data[state->cursor] - '0'; - ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); - } - while (psyc_is_numeric(state->buffer.data[state->cursor])); - state->valueLength = length; - } - else - return PSYC_PARSE_ERROR_MOD_LEN; + // After the length a TAB follows. + if (state->buffer.data[state->cursor] != '\t') + return PSYC_PARSE_ERROR_MOD_TAB; - // After the length a TAB follows. - if (state->buffer.data[state->cursor] != '\t') - return PSYC_PARSE_ERROR_MOD_TAB; + if (++(state->cursor) >= state->buffer.length) + return length ? PARSE_INCOMPLETE : PARSE_SUCCESS; // if length=0 we're done - if (++(state->cursor) >= state->buffer.length) - return length ? PARSE_INCOMPLETE : PARSE_SUCCESS; // if length=0 we're done + ret = + psyc_parse_binary_value(state, value, &(state->valueLength), + &(state->valueParsed)); + if (ret == PARSE_INCOMPLETE) + return ret; - ret = psyc_parse_binary_value(state, value, &(state->valueLength), &(state->valueParsed)); - if (ret == PARSE_INCOMPLETE) - return ret; + return PARSE_SUCCESS; + } else if (state->buffer.data[state->cursor] == '\t') { // simple arg + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + value->data = state->buffer.data + state->cursor; - return PARSE_SUCCESS; + while (state->buffer.data[state->cursor] != '\n') { + value->length++; + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } - else if (state->buffer.data[state->cursor] == '\t') // simple arg - { - ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); - value->data = state->buffer.data + state->cursor; - while (state->buffer.data[state->cursor] != '\n') - { - value->length++; - ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); - } - - return PARSE_SUCCESS; - } - else - return PSYC_PARSE_ERROR_MOD_TAB; + return PARSE_SUCCESS; + } else + return PSYC_PARSE_ERROR_MOD_TAB; } /** Parse PSYC packets. */ #ifdef __INLINE_PSYC_PARSE static inline #endif -PsycParseRC psyc_parse (PsycParseState *state, char *oper, - PsycString *name, PsycString *value) +PsycParseRC +psyc_parse (PsycParseState *state, char *oper, + PsycString *name, PsycString *value) { #ifdef DEBUG - if (state->flags & PSYC_PARSE_ROUTING_ONLY && - state->flags & PSYC_PARSE_START_AT_CONTENT) - PP(("Invalid flag combination")) + if (state->flags & PSYC_PARSE_ROUTING_ONLY && + state->flags & PSYC_PARSE_START_AT_CONTENT) + PP(("Invalid flag combination")); #endif + ParseRC ret; // a return value + size_t pos = state->cursor; // a cursor position - ParseRC ret; // a return value - size_t pos = state->cursor; // 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; - // 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_PARSE_INSUFFICIENT; - // First we test if we can access the first char. - if (state->cursor >= state->buffer.length) // cursor is not inside the length - return PSYC_PARSE_INSUFFICIENT; + switch (state->part) { + case PSYC_PART_RESET: // New packet starts here, reset state. + state->valueParsed = 0; + state->valueLength = 0; + state->valueLengthFound = 0; + state->routingLength = 0; + state->contentParsed = 0; + state->contentLength = 0; + state->contentLengthFound = 0; + state->part = PSYC_PART_ROUTING; + // fall thru - switch (state->part) - { - case PSYC_PART_RESET: // New packet starts here, reset state. - state->valueParsed = 0; - state->valueLength = 0; - state->valueLengthFound = 0; - state->routingLength = 0; - state->contentParsed = 0; - state->contentLength = 0; - state->contentLengthFound = 0; - state->part = PSYC_PART_ROUTING; - // fall thru - - case PSYC_PART_ROUTING: - if (state->routingLength > 0) - { - if (state->buffer.data[state->cursor] != '\n') - return PSYC_PARSE_ERROR_MOD_NL; - ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); - } - - // 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 (psyc_is_glyph(state->buffer.data[state->cursor])) // is the first char a glyph? - { // it is a glyph, so a variable starts here - ret = psyc_parse_modifier(state, oper, name, value); - state->routingLength += state->cursor - pos; - return ret == PARSE_SUCCESS ? PSYC_PARSE_ROUTING : ret; - } - else // not a glyph - { - state->part = PSYC_PART_LENGTH; - state->startc = state->cursor; - // fall thru - } - - case PSYC_PART_LENGTH: - // End of header, content starts with an optional length then a NL - if (psyc_is_numeric(state->buffer.data[state->cursor])) - { - state->contentLengthFound = 1; - state->contentLength = 0; - - do - { - state->contentLength = 10 * state->contentLength + state->buffer.data[state->cursor] - '0'; - ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); - } - while (psyc_is_numeric(state->buffer.data[state->cursor])); - } - - if (state->buffer.data[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 (state->flags & PSYC_PARSE_ROUTING_ONLY) - { - state->part = PSYC_PART_DATA; - if (++(state->cursor) >= state->buffer.length) - return PSYC_PARSE_INSUFFICIENT; - goto PSYC_PART_DATA; - } - else - 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_PARSE_ERROR_LENGTH; - - state->part = PSYC_PART_END; - goto PSYC_PART_END; - } - - state->startc = state->cursor + 1; - ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); - // fall thru - - case PSYC_PART_CONTENT: - // In case of an incomplete binary variable resume parsing it. - if (state->valueParsed < state->valueLength) - { - ret = psyc_parse_binary_value(state, value, &(state->valueLength), &(state->valueParsed)); - state->contentParsed += value->length; - - if (ret == PARSE_INCOMPLETE) - return PSYC_PARSE_ENTITY_CONT; - - return PSYC_PARSE_ENTITY_END; - } - - pos = state->cursor; - - if (state->contentParsed > 0) - { - if (state->buffer.data[state->cursor] != '\n') - return PSYC_PARSE_ERROR_MOD_NL; - ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); - } - - // 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 (psyc_is_glyph(state->buffer.data[state->cursor])) - { - ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); - if (state->contentParsed == 0 && state->buffer.data[state->cursor] == '\n') - { - *oper = *(state->buffer.data + state->cursor - 1); - switch (*oper) - { - case PSYC_STATE_RESYNC: - state->contentParsed += 2; - return PSYC_PARSE_STATE_RESYNC; - case PSYC_STATE_RESET: - state->contentParsed += 2; - return PSYC_PARSE_STATE_RESET; - default: - return PSYC_PARSE_ERROR_MOD_NAME; - } - } - state->cursor--; - - ret = psyc_parse_modifier(state, oper, name, value); - state->contentParsed += state->cursor - pos; - - if (ret == PARSE_INCOMPLETE) - return PSYC_PARSE_ENTITY_START; - else if (ret == PARSE_SUCCESS) - return PSYC_PARSE_ENTITY; - - return ret; - } - else - { - state->contentParsed += state->cursor - pos; - state->startc = state->cursor; - state->part = PSYC_PART_METHOD; - // fall thru - } - - case PSYC_PART_METHOD: - pos = state->cursor; - ret = psyc_parse_keyword(state, name); - - if (ret == PARSE_INSUFFICIENT) - return ret; - else if (ret == PARSE_SUCCESS) - { // the method ends with a \n then the data follows - if (state->buffer.data[state->cursor] != '\n') - return PSYC_PARSE_ERROR_METHOD; - - state->valueLengthFound = 0; - state->valueParsed = 0; - state->valueLength = 0; - - if (state->contentLengthFound) - { // if length was found set start position to the beginning of data - state->cursor++; - state->startc = state->cursor; - state->contentParsed += state->cursor - pos; - state->part = PSYC_PART_DATA; - } - else // otherwise keep it at the beginning of method - { - ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); - } - } - else // No method, which means the packet should end now. - { - state->part = PSYC_PART_END; - state->startc = state->cursor; - goto PSYC_PART_END; - } - // fall thru - - case PSYC_PART_DATA: - PSYC_PART_DATA: - value->data = state->buffer.data + state->cursor; - value->length = 0; - - if (state->contentLengthFound) // We know the length of the packet. - { - if (!state->valueLengthFound) // start of data - { - state->valueLengthFound = 1; - state->valueLength = state->contentLength - state->contentParsed; // length of data - if (state->valueLength && !(state->flags & PSYC_PARSE_ROUTING_ONLY)) - state->valueLength--; // \n at the end is not part of data - } - if (state->valueParsed < state->valueLength) - { - ret = psyc_parse_binary_value(state, value, &(state->valueLength), &(state->valueParsed)); - state->contentParsed += value->length; - - if (ret == PARSE_INCOMPLETE) - return state->valueParsed == value->length ? PSYC_PARSE_BODY_START : PSYC_PARSE_BODY_CONT; - } - - state->part = PSYC_PART_END; - return state->valueLength == value->length ? PSYC_PARSE_BODY : PSYC_PARSE_BODY_END; - } - else // Search for the terminator. - { - size_t datac = state->cursor; // start of data - if (state->flags & PSYC_PARSE_ROUTING_ONLY) - state->startc = datac; // in routing-only mode restart from the start of data - - while (1) - { - uint8_t nl = state->buffer.data[state->cursor] == '\n'; - // check for |\n if we're at the start of data or we have found a \n - if (state->cursor == datac || nl) - { - if (state->cursor+1+nl >= state->buffer.length) // incremented cursor inside length? - { - state->cursor = state->startc; - return PSYC_PARSE_INSUFFICIENT; - } - - if (state->buffer.data[state->cursor+nl] == '|' && - state->buffer.data[state->cursor+1+nl] == '\n') // packet ends here - { - if (state->flags & PSYC_PARSE_ROUTING_ONLY) - value->length++; - - state->contentParsed += state->cursor - pos; - state->cursor += nl; - state->part = PSYC_PART_END; - return PSYC_PARSE_BODY; - } - } - value->length++; - ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); - } - } - - case PSYC_PART_END: - PSYC_PART_END: - if (state->contentLengthFound && state->valueLengthFound && state->valueLength && - !(state->flags & PSYC_PARSE_ROUTING_ONLY)) - { // if data was not empty next is the \n at the end of data - state->valueLength = 0; - state->valueLengthFound = 0; - - if (state->buffer.data[state->cursor] != '\n') - return PSYC_PARSE_ERROR_END; - - state->contentParsed++; - state->cursor++; - } - - // 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_PARSE_INSUFFICIENT; - - if (state->buffer.data[state->cursor] == '|' && - state->buffer.data[state->cursor+1] == '\n') // packet ends here - { - state->cursor += 2; - state->part = PSYC_PART_RESET; - return PSYC_PARSE_COMPLETE; - } - else // packet should've ended here, return error - { - state->part = PSYC_PART_RESET; - return PSYC_PARSE_ERROR_END; - } + case PSYC_PART_ROUTING: + if (state->routingLength > 0) { + if (state->buffer.data[state->cursor] != '\n') + return PSYC_PARSE_ERROR_MOD_NL; + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } - return PSYC_PARSE_ERROR; // should not be reached + // 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 (psyc_is_glyph(state->buffer.data[state->cursor])) { + // it is a glyph, so a variable starts here + ret = psyc_parse_modifier(state, oper, name, value); + state->routingLength += state->cursor - pos; + return ret == PARSE_SUCCESS ? PSYC_PARSE_ROUTING : ret; + } else { // not a glyph + state->part = PSYC_PART_LENGTH; + state->startc = state->cursor; + // fall thru + } + + case PSYC_PART_LENGTH: + // End of header, content starts with an optional length then a NL + if (psyc_is_numeric(state->buffer.data[state->cursor])) { + state->contentLengthFound = 1; + state->contentLength = 0; + + do { + state->contentLength = + 10 * state->contentLength + + state->buffer.data[state->cursor] - '0'; + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + } while (psyc_is_numeric(state->buffer.data[state->cursor])); + } + + if (state->buffer.data[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 (state->flags & PSYC_PARSE_ROUTING_ONLY) { + state->part = PSYC_PART_DATA; + if (++(state->cursor) >= state->buffer.length) + return PSYC_PARSE_INSUFFICIENT; + goto PSYC_PART_DATA; + } else + 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_PARSE_ERROR_LENGTH; + + state->part = PSYC_PART_END; + goto PSYC_PART_END; + } + + state->startc = state->cursor + 1; + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + // fall thru + + case PSYC_PART_CONTENT: + // In case of an incomplete binary variable resume parsing it. + if (state->valueParsed < state->valueLength) { + ret = psyc_parse_binary_value(state, value, &(state->valueLength), + &(state->valueParsed)); + state->contentParsed += value->length; + + if (ret == PARSE_INCOMPLETE) + return PSYC_PARSE_ENTITY_CONT; + + return PSYC_PARSE_ENTITY_END; + } + + pos = state->cursor; + + if (state->contentParsed > 0) { + if (state->buffer.data[state->cursor] != '\n') + return PSYC_PARSE_ERROR_MOD_NL; + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + } + // 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 (psyc_is_glyph(state->buffer.data[state->cursor])) { + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + if (state->contentParsed == 0 + && state->buffer.data[state->cursor] == '\n') { + *oper = *(state->buffer.data + state->cursor - 1); + switch (*oper) { + case PSYC_STATE_RESYNC: + state->contentParsed += 2; + return PSYC_PARSE_STATE_RESYNC; + case PSYC_STATE_RESET: + state->contentParsed += 2; + return PSYC_PARSE_STATE_RESET; + default: + return PSYC_PARSE_ERROR_MOD_NAME; + } + } + state->cursor--; + + ret = psyc_parse_modifier(state, oper, name, value); + state->contentParsed += state->cursor - pos; + + if (ret == PARSE_INCOMPLETE) + return PSYC_PARSE_ENTITY_START; + else if (ret == PARSE_SUCCESS) + return PSYC_PARSE_ENTITY; + + return ret; + } else { + state->contentParsed += state->cursor - pos; + state->startc = state->cursor; + state->part = PSYC_PART_METHOD; + // fall thru + } + + case PSYC_PART_METHOD: + pos = state->cursor; + ret = psyc_parse_keyword(state, name); + + if (ret == PARSE_INSUFFICIENT) + return ret; + else if (ret == PARSE_SUCCESS) { + // The method ends with a \n then the data follows. + if (state->buffer.data[state->cursor] != '\n') + return PSYC_PARSE_ERROR_METHOD; + + state->valueLengthFound = 0; + state->valueParsed = 0; + state->valueLength = 0; + + if (state->contentLengthFound) { + // Length found, set start position to the beginning of data. + state->cursor++; + state->startc = state->cursor; + state->contentParsed += state->cursor - pos; + state->part = PSYC_PART_DATA; + } else { // Otherwise keep it at the beginning of method. + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + } + } else { // No method, which means the packet should end now. + state->part = PSYC_PART_END; + state->startc = state->cursor; + goto PSYC_PART_END; + } + // fall thru + + case PSYC_PART_DATA: + PSYC_PART_DATA: + value->data = state->buffer.data + state->cursor; + value->length = 0; + + if (state->contentLengthFound) { // We know the length of the packet. + if (!state->valueLengthFound) { // start of data + state->valueLengthFound = 1; + state->valueLength = state->contentLength - state->contentParsed; + if (state->valueLength && !(state->flags & PSYC_PARSE_ROUTING_ONLY)) + state->valueLength--; // \n at the end is not part of data + } + if (state->valueParsed < state->valueLength) { + ret = psyc_parse_binary_value(state, value, &(state->valueLength), + &(state->valueParsed)); + state->contentParsed += value->length; + + if (ret == PARSE_INCOMPLETE) + return state->valueParsed == value->length + ? PSYC_PARSE_BODY_START : PSYC_PARSE_BODY_CONT; + } + + state->part = PSYC_PART_END; + return state->valueLength == value->length ? + PSYC_PARSE_BODY : PSYC_PARSE_BODY_END; + } else { // Search for the terminator. + size_t datac = state->cursor; // start of data + if (state->flags & PSYC_PARSE_ROUTING_ONLY) // in routing-only mode restart + state->startc = datac; // from the start of data + + while (1) { + uint8_t nl = state->buffer.data[state->cursor] == '\n'; + // check for |\n if we're at the start of data or we have found a \n + if (state->cursor == datac || nl) { + // incremented cursor inside length? + if (state->cursor + 1 + nl >= state->buffer.length) { + state->cursor = state->startc; + return PSYC_PARSE_INSUFFICIENT; + } + + if (state->buffer.data[state->cursor + nl] == '|' + && state->buffer.data[state->cursor + 1 + nl] == '\n') { + // packet ends here + if (state->flags & PSYC_PARSE_ROUTING_ONLY) + value->length++; + + state->contentParsed += state->cursor - pos; + state->cursor += nl; + state->part = PSYC_PART_END; + return PSYC_PARSE_BODY; + } + } + value->length++; + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + } + } + + case PSYC_PART_END: + PSYC_PART_END: + // if data was not empty next is the \n at the end of data + if (state->contentLengthFound && state->valueLengthFound + && state->valueLength && !(state->flags & PSYC_PARSE_ROUTING_ONLY)) { + state->valueLength = 0; + state->valueLengthFound = 0; + + if (state->buffer.data[state->cursor] != '\n') + return PSYC_PARSE_ERROR_END; + + state->contentParsed++; + state->cursor++; + } + // 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) + return PSYC_PARSE_INSUFFICIENT; + + if (state->buffer.data[state->cursor] == '|' + && state->buffer.data[state->cursor + 1] == '\n') { + // Packet ends here. + state->cursor += 2; + state->part = PSYC_PART_RESET; + return PSYC_PARSE_COMPLETE; + } else { // Packet should've ended here, return error. + state->part = PSYC_PART_RESET; + return PSYC_PARSE_ERROR_END; + } + } + return PSYC_PARSE_ERROR; // should not be reached } /** List parser. */ #ifdef __INLINE_PSYC_PARSE static inline #endif -PsycParseListRC psyc_parse_list (PsycParseListState *state, PsycString *elem) +PsycParseListRC +psyc_parse_list (PsycParseListState *state, PsycString *elem) { + if (state->cursor >= state->buffer.length) + return PSYC_PARSE_LIST_INCOMPLETE; + + state->startc = state->cursor; + + if (!state->type) { // If type is not set we're at the start. + // First character is either | for text lists, or a number for binary lists + if (state->buffer.data[state->cursor] == '|') { + state->type = PSYC_LIST_TEXT; + state->cursor++; + } else if (psyc_is_numeric(state->buffer.data[state->cursor])) + state->type = PSYC_LIST_BINARY; + else + return PSYC_PARSE_LIST_ERROR_TYPE; + } + + if (state->type == PSYC_LIST_TEXT) { + elem->data = state->buffer.data + state->cursor; + elem->length = 0; + if (state->cursor >= state->buffer.length) + return PSYC_PARSE_LIST_END; + + while (state->buffer.data[state->cursor] != '|') { + elem->length++; + if (++(state->cursor) >= state->buffer.length) + return PSYC_PARSE_LIST_END; + } + state->cursor++; + return PSYC_PARSE_LIST_ELEM; + } else { // binary list + if (!(state->elemParsed < state->elemLength)) { + // Element starts with a number. + if (psyc_is_numeric(state->buffer.data[state->cursor])) { + do { + state->elemLength = + 10 * state->elemLength + + state->buffer.data[state->cursor] - '0'; + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_LIST_INCOMPLETE); + } while (psyc_is_numeric(state->buffer.data[state->cursor])); + } else + return PSYC_PARSE_LIST_ERROR_LEN; + + if (state->buffer.data[state->cursor] != ' ') + return PSYC_PARSE_LIST_ERROR_LEN; + + state->cursor++; + elem->data = state->buffer.data + state->cursor; + elem->length = 0; + state->elemParsed = 0; + } + // Start or resume parsing the binary data + if (state->elemParsed < state->elemLength) { + if (PARSE_INCOMPLETE == psyc_parse_binary_value((PsycParseState*)state, + elem, &state->elemLength, + &state->elemParsed)) return PSYC_PARSE_LIST_INCOMPLETE; - state->startc = state->cursor; + state->elemLength = 0; - if (!state->type) // If type is not set we're at the start - { - // First character is either | for text lists, or a number for binary lists - if (state->buffer.data[state->cursor] == '|') - { - state->type = PSYC_LIST_TEXT; - state->cursor++; - } - else if (psyc_is_numeric(state->buffer.data[state->cursor])) - state->type = PSYC_LIST_BINARY; - else - return PSYC_PARSE_LIST_ERROR_TYPE; + if (state->cursor >= state->buffer.length) + return PSYC_PARSE_LIST_END; + + if (state->buffer.data[state->cursor] != '|') + return PSYC_PARSE_LIST_ERROR_DELIM; + + state->cursor++; + return PSYC_PARSE_LIST_ELEM; } + } - if (state->type == PSYC_LIST_TEXT) - { - elem->data = state->buffer.data + state->cursor; - elem->length = 0; - - if (state->cursor >= state->buffer.length) - return PSYC_PARSE_LIST_END; - - while (state->buffer.data[state->cursor] != '|') - { - elem->length++; - if (++(state->cursor) >= state->buffer.length) - return PSYC_PARSE_LIST_END; - } - state->cursor++; - return PSYC_PARSE_LIST_ELEM; - } - else // binary list - { - if (!(state->elemParsed < state->elemLength)) - { - // Element starts with a number. - if (psyc_is_numeric(state->buffer.data[state->cursor])) - { - do - { - state->elemLength = 10 * state->elemLength + state->buffer.data[state->cursor] - '0'; - ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_LIST_INCOMPLETE); - } - while (psyc_is_numeric(state->buffer.data[state->cursor])); - } - else - return PSYC_PARSE_LIST_ERROR_LEN; - - if (state->buffer.data[state->cursor] != ' ') - return PSYC_PARSE_LIST_ERROR_LEN; - - state->cursor++; - elem->data = state->buffer.data + state->cursor; - elem->length = 0; - state->elemParsed = 0; - } - - // Start or resume parsing the binary data - if (state->elemParsed < state->elemLength) - { - if (psyc_parse_binary_value((PsycParseState*)state, elem, - &(state->elemLength), &(state->elemParsed)) == PARSE_INCOMPLETE) - return PSYC_PARSE_LIST_INCOMPLETE; - - state->elemLength = 0; - - if (state->cursor >= state->buffer.length) - return PSYC_PARSE_LIST_END; - - if (state->buffer.data[state->cursor] != '|') - return PSYC_PARSE_LIST_ERROR_DELIM; - - state->cursor++; - return PSYC_PARSE_LIST_ELEM; - } - } - - return PSYC_PARSE_LIST_ERROR; // should not be reached + return PSYC_PARSE_LIST_ERROR; // should not be reached } diff --git a/src/render.c b/src/render.c index 887f82e..5fefbb0 100644 --- a/src/render.c +++ b/src/render.c @@ -6,134 +6,123 @@ #ifdef __INLINE_PSYC_RENDER static inline #endif -PsycRenderListRC psyc_render_list (PsycList *list, char *buffer, size_t buflen) +PsycRenderListRC +psyc_render_list (PsycList * list, char *buffer, size_t buflen) { - size_t i, cur = 0; - PsycString *elem; + size_t i, cur = 0; + PsycString *elem; - if (list->length > buflen) // return error if list doesn't fit in buffer - return PSYC_RENDER_LIST_ERROR; + if (list->length > buflen) // return error if list doesn't fit in buffer + return PSYC_RENDER_LIST_ERROR; - if (list->flag == PSYC_LIST_NEED_LENGTH) - { - for (i = 0; i < list->num_elems; i++) - { - elem = &list->elems[i]; - if (i > 0) - buffer[cur++] = '|'; - cur += itoa(elem->length, buffer + cur, 10); - buffer[cur++] = ' '; - memcpy(buffer + cur, elem->data, elem->length); - cur += elem->length; - } + if (list->flag == PSYC_LIST_NEED_LENGTH) { + for (i = 0; i < list->num_elems; i++) { + elem = &list->elems[i]; + if (i > 0) + buffer[cur++] = '|'; + cur += itoa(elem->length, buffer + cur, 10); + buffer[cur++] = ' '; + memcpy(buffer + cur, elem->data, elem->length); + cur += elem->length; } - else - { - for (i = 0; i < list->num_elems; i++) - { - elem = &list->elems[i]; - buffer[cur++] = '|'; - memcpy(buffer + cur, elem->data, elem->length); - cur += elem->length; - } + } else { + for (i = 0; i < list->num_elems; i++) { + elem = &list->elems[i]; + buffer[cur++] = '|'; + memcpy(buffer + cur, elem->data, elem->length); + cur += elem->length; } + } - // actual length should be equal to pre-calculated length at this point - assert(cur == list->length); - return PSYC_RENDER_LIST_SUCCESS; + // Actual length should be equal to pre-calculated length at this point. + assert(cur == list->length); + return PSYC_RENDER_LIST_SUCCESS; } -static inline -size_t psyc_render_modifier (PsycModifier *mod, char *buffer) +static inline size_t +psyc_render_modifier (PsycModifier * mod, char *buffer) { - size_t cur = 0; + size_t cur = 0; - buffer[cur++] = mod->oper; - memcpy(buffer + cur, mod->name.data, mod->name.length); - cur += mod->name.length; - if (cur == 1) - return cur; // error, name can't be empty + buffer[cur++] = mod->oper; + memcpy(buffer + cur, mod->name.data, mod->name.length); + cur += mod->name.length; + if (cur == 1) + return cur; // error, name can't be empty - if (mod->flag == PSYC_MODIFIER_NEED_LENGTH) - { - buffer[cur++] = ' '; - cur += itoa(mod->value.length, buffer + cur, 10); - } + if (mod->flag == PSYC_MODIFIER_NEED_LENGTH) { + buffer[cur++] = ' '; + cur += itoa(mod->value.length, buffer + cur, 10); + } - buffer[cur++] = '\t'; - memcpy(buffer + cur, mod->value.data, mod->value.length); - cur += mod->value.length; - buffer[cur++] = '\n'; + buffer[cur++] = '\t'; + memcpy(buffer + cur, mod->value.data, mod->value.length); + cur += mod->value.length; + buffer[cur++] = '\n'; - return cur; + return cur; } #ifdef __INLINE_PSYC_RENDER static inline #endif -PsycRenderRC psyc_render (PsycPacket *packet, char *buffer, size_t buflen) +PsycRenderRC +psyc_render (PsycPacket * packet, char *buffer, size_t buflen) { - size_t i, cur = 0, len; + size_t i, cur = 0, len; - if (packet->length > buflen) // return error if packet doesn't fit in buffer - return PSYC_RENDER_ERROR; + if (packet->length > buflen) // return error if packet doesn't fit in buffer + return PSYC_RENDER_ERROR; - // render routing modifiers - for (i = 0; i < packet->routing.lines; i++) - { - len = psyc_render_modifier(&packet->routing.modifiers[i], buffer + cur); - cur += len; - if (len <= 1) - return PSYC_RENDER_ERROR_MODIFIER_NAME_MISSING; + // render routing modifiers + for (i = 0; i < packet->routing.lines; i++) { + len = psyc_render_modifier(&packet->routing.modifiers[i], buffer + cur); + cur += len; + if (len <= 1) + return PSYC_RENDER_ERROR_MODIFIER_NAME_MISSING; + } + + // add length if needed + if (packet->flag == PSYC_PACKET_NEED_LENGTH) + cur += itoa(packet->contentLength, buffer + cur, 10); + + if (packet->flag == PSYC_PACKET_NEED_LENGTH || packet->content.length + || packet->stateop || packet->entity.lines + || packet->method.length || packet->data.length) + buffer[cur++] = '\n'; // start of content part if there's content or length + + if (packet->content.length) { // render raw content if present + memcpy(buffer + cur, packet->content.data, packet->content.length); + cur += packet->content.length; + } else { + if (packet->stateop) { + buffer[cur++] = packet->stateop; + buffer[cur++] = '\n'; } + // render entity modifiers + for (i = 0; i < packet->entity.lines; i++) + cur += psyc_render_modifier(&packet->entity.modifiers[i], + buffer + cur); - // add length if needed - if (packet->flag == PSYC_PACKET_NEED_LENGTH) - cur += itoa(packet->contentLength, buffer + cur, 10); + if (packet->method.length) { // add method\n + memcpy(buffer + cur, packet->method.data, packet->method.length); + cur += packet->method.length; + buffer[cur++] = '\n'; - if (packet->flag == PSYC_PACKET_NEED_LENGTH || packet->content.length || - packet->stateop || packet->entity.lines || - packet->method.length || packet->data.length) - buffer[cur++] = '\n'; // start of content part if there's content or length + if (packet->data.length) { // add data\n + memcpy(buffer + cur, packet->data.data, packet->data.length); + cur += packet->data.length; + buffer[cur++] = '\n'; + } + } else if (packet->data.length) // error, we have data but no modifier + return PSYC_RENDER_ERROR_METHOD_MISSING; + } - if (packet->content.length) // render raw content if present - { - memcpy(buffer + cur, packet->content.data, packet->content.length); - cur += packet->content.length; - } - else - { - if (packet->stateop) { - buffer[cur++] = packet->stateop; - buffer[cur++] = '\n'; - } + // add packet delimiter + buffer[cur++] = PSYC_PACKET_DELIMITER_CHAR; + buffer[cur++] = '\n'; - // render entity modifiers - for (i = 0; i < packet->entity.lines; i++) - cur += psyc_render_modifier(&packet->entity.modifiers[i], buffer + cur); - - if (packet->method.length) // add method\n - { - memcpy(buffer + cur, packet->method.data, packet->method.length); - cur += packet->method.length; - buffer[cur++] = '\n'; - - if (packet->data.length) // add data\n - { - memcpy(buffer + cur, packet->data.data, packet->data.length); - cur += packet->data.length; - buffer[cur++] = '\n'; - } - } - else if (packet->data.length) // error, we have data but no modifier - return PSYC_RENDER_ERROR_METHOD_MISSING; - } - - // add packet delimiter - buffer[cur++] = PSYC_PACKET_DELIMITER_CHAR; - buffer[cur++] = '\n'; - - // actual length should be equal to pre-calculated length at this point - assert(cur == packet->length); - return PSYC_RENDER_SUCCESS; + // actual length should be equal to pre-calculated length at this point + assert(cur == packet->length); + return PSYC_RENDER_SUCCESS; } diff --git a/src/text.c b/src/text.c index 1c48010..31d1e10 100644 --- a/src/text.c +++ b/src/text.c @@ -1,82 +1,81 @@ #include "lib.h" #include -PsycTextRC psyc_text (PsycTextState *state, PsycTextCB getValue, void* extra) +PsycTextRC +psyc_text (PsycTextState *state, PsycTextCB getValue, void *extra) { - const char *start = state->tmpl.data, *end; // start & end of variable name - const char *prev = state->tmpl.data + state->cursor; - PsycString value; - int ret; - size_t len; - uint8_t no_subst = (state->cursor == 0); // whether we can return NO_SUBST + const char *start = state->tmpl.data, *end; // start & end of variable name + const char *prev = state->tmpl.data + state->cursor; + PsycString value; + int ret; + size_t len; + uint8_t no_subst = (state->cursor == 0); // whether we can return NO_SUBST - while (state->cursor < state->tmpl.length) - { - start = memmem(state->tmpl.data + state->cursor, - state->tmpl.length - state->cursor, - state->open.data, state->open.length); - if (!start) - break; + while (state->cursor < state->tmpl.length) { + start = memmem(state->tmpl.data + state->cursor, + state->tmpl.length - state->cursor, + state->open.data, state->open.length); + if (!start) + break; - state->cursor = (start - state->tmpl.data) + state->open.length; - if (state->cursor >= state->tmpl.length) - break; // [ at the end + state->cursor = (start - state->tmpl.data) + state->open.length; + if (state->cursor >= state->tmpl.length) + break; // [ at the end - end = memmem(state->tmpl.data + state->cursor, - state->tmpl.length - state->cursor, - state->close.data, state->close.length); - state->cursor = (end - state->tmpl.data) + state->close.length; + end = memmem(state->tmpl.data + state->cursor, + state->tmpl.length - state->cursor, + state->close.data, state->close.length); + state->cursor = (end - state->tmpl.data) + state->close.length; - if (!end) - break; // ] not found - if (start + state->open.length == end) - { - state->cursor += state->close.length; - continue; // [] is invalid, name can't be empty - } - - ret = getValue(start + state->open.length, end - start - state->open.length, &value, extra); - - if (ret < 0) - continue; // value not found, no substitution - - // first copy the part in the input from the previous subst. to the current one - // if there's enough buffer space for that - len = start - prev; - if (state->written + len > state->buffer.length) - { - state->cursor = prev - state->tmpl.data; - return PSYC_TEXT_INCOMPLETE; - } - - memcpy((void *)(state->buffer.data + state->written), prev, len); - state->written += len; - - // now substitute the value if there's enough buffer space - if (state->written + value.length > state->buffer.length) - { - state->cursor = start - state->tmpl.data; - return PSYC_TEXT_INCOMPLETE; - } - - memcpy((void *)(state->buffer.data + state->written), value.data, value.length); - state->written += value.length; - - // mark the start of the next chunk of text in the template - prev = state->tmpl.data + state->cursor; - no_subst = 0; + if (!end) + break; // ] not found + if (start + state->open.length == end) { + state->cursor += state->close.length; + continue; // [] is invalid, name can't be empty } - if (no_subst) - return PSYC_TEXT_NO_SUBST; + ret = getValue(start + state->open.length, + end - start - state->open.length, &value, extra); - // copy the rest of the template after the last var - len = state->tmpl.length - (prev - state->tmpl.data); - if (state->written + len > state->buffer.length) - return PSYC_TEXT_INCOMPLETE; + if (ret < 0) + continue; // value not found, no substitution - memcpy((void *)(state->buffer.data + state->written), prev, len); + // First copy the part in the input from the previous subst. + // to the current one, if there's enough buffer space for that. + len = start - prev; + if (state->written + len > state->buffer.length) { + state->cursor = prev - state->tmpl.data; + return PSYC_TEXT_INCOMPLETE; + } + + memcpy((void *) (state->buffer.data + state->written), prev, len); state->written += len; - return PSYC_TEXT_COMPLETE; + // Now substitute the value if there's enough buffer space. + if (state->written + value.length > state->buffer.length) { + state->cursor = start - state->tmpl.data; + return PSYC_TEXT_INCOMPLETE; + } + + memcpy((void *) (state->buffer.data + state->written), value.data, + value.length); + state->written += value.length; + + // Mark the start of the next chunk of text in the template. + prev = state->tmpl.data + state->cursor; + no_subst = 0; + } + + if (no_subst) + return PSYC_TEXT_NO_SUBST; + + // Copy the rest of the template after the last var. + len = state->tmpl.length - (prev - state->tmpl.data); + if (state->written + len > state->buffer.length) + return PSYC_TEXT_INCOMPLETE; + + memcpy((void *) (state->buffer.data + state->written), prev, len); + state->written += len; + + return PSYC_TEXT_COMPLETE; } diff --git a/src/uniform.c b/src/uniform.c index 74c3098..5a68ca3 100644 --- a/src/uniform.c +++ b/src/uniform.c @@ -3,177 +3,182 @@ #include "psyc/uniform.h" #include "psyc/parse.h" -int psyc_uniform_parse (PsycUniform *uni, char *str, size_t length) +int +psyc_uniform_parse (PsycUniform *uni, char *str, size_t length) { - char c; - PsycString *p; - size_t pos = 0, part = PSYC_UNIFORM_SCHEME; + char c; + PsycString *p; + size_t pos = 0, part = PSYC_UNIFORM_SCHEME; - uni->valid = 0; - uni->full.data = str; - uni->full.length = length; + uni->valid = 0; + uni->full.data = str; + uni->full.length = length; + + while (pos < length) { + c = str[pos]; + if (c == ':') { + uni->scheme.data = str; + uni->scheme.length = pos++; + break; + } else if (!psyc_is_host_char(c)) + return PSYC_PARSE_UNIFORM_INVALID_SCHEME; + pos++; + } + + p = &uni->scheme; + if (p->length == 4 && (tolower(p->data[0]) == 'p' && + tolower(p->data[1]) == 's' && + tolower(p->data[2]) == 'y' && + tolower(p->data[3]) == 'c')) { + uni->type = PSYC_SCHEME_PSYC; + part = PSYC_UNIFORM_SLASHES; + uni->slashes.data = str + pos; + uni->slashes.length = 0; while (pos < length) { - c = str[pos]; - if (c == ':') { - uni->scheme.data = str; - uni->scheme.length = pos++; - break; - } else if (!psyc_is_host_char(c)) - return PSYC_PARSE_UNIFORM_INVALID_SCHEME; - pos++; - } + c = str[pos]; + switch (part) { + case PSYC_UNIFORM_SLASHES: + if (c == '/') + uni->slashes.length++; + else + return PSYC_PARSE_UNIFORM_INVALID_SLASHES; - p = &uni->scheme; - if (p->length == 4 && - tolower(p->data[0]) == 'p' && - tolower(p->data[1]) == 's' && - tolower(p->data[2]) == 'y' && - tolower(p->data[3]) == 'c') { + if (uni->slashes.length == 2) { + part = PSYC_UNIFORM_HOST; + uni->host.data = str + pos + 1; + uni->host.length = 0; + } + break; - uni->type = PSYC_SCHEME_PSYC; - part = PSYC_UNIFORM_SLASHES; - uni->slashes.data = str + pos; - uni->slashes.length = 0; - - while (pos < length) { - c = str[pos]; - switch (part) { - case PSYC_UNIFORM_SLASHES: - if (c == '/') - uni->slashes.length++; - else return PSYC_PARSE_UNIFORM_INVALID_SLASHES; - - if (uni->slashes.length == 2) { - part = PSYC_UNIFORM_HOST; - uni->host.data = str + pos + 1; - uni->host.length = 0; - } - break; - - case PSYC_UNIFORM_HOST: - if (psyc_is_host_char(c)) { - uni->host.length++; - break; - } - - if (uni->host.length == 0) - return PSYC_PARSE_UNIFORM_INVALID_HOST; - - if (c == ':') { - part = PSYC_UNIFORM_PORT; - p = &uni->port; - } else if (c == '/') { - uni->slash.data = str + pos; - uni->slash.length = 1; - - part = PSYC_UNIFORM_RESOURCE; - p = &uni->resource; - } - else return PSYC_PARSE_UNIFORM_INVALID_HOST; - - p->data = str + pos + 1; - p->length = 0; - break; - - case PSYC_UNIFORM_PORT: - if (psyc_is_numeric(c) || (uni->port.length == 0 && c == '-')) { - uni->port.length++; - break; - } - - if (uni->port.length == 0 && c != PSYC_TRANSPORT_GNUNET) - return PSYC_PARSE_UNIFORM_INVALID_PORT; - - if (c == '/') { - uni->slash.data = str + pos; - uni->slash.length = 1; - - part = PSYC_UNIFORM_RESOURCE; - uni->resource.data = str + pos + 1; - uni->resource.length = 0; - break; - } - else { - part = PSYC_UNIFORM_TRANSPORT; - uni->transport.data = str + pos; - uni->transport.length = 0; - } - // fall thru - - case PSYC_UNIFORM_TRANSPORT: - switch (c) { - case PSYC_TRANSPORT_GNUNET: - if (uni->port.length > 0) - return PSYC_PARSE_UNIFORM_INVALID_TRANSPORT; - case PSYC_TRANSPORT_TCP: - case PSYC_TRANSPORT_UDP: - case PSYC_TRANSPORT_TLS: - if (uni->transport.length > 0) - return PSYC_PARSE_UNIFORM_INVALID_TRANSPORT; - uni->transport.length++; - break; - case '/': - uni->slash.data = str + pos; - uni->slash.length = 1; - - part = PSYC_UNIFORM_RESOURCE; - uni->resource.data = str + pos + 1; - uni->resource.length = 0; - break; - default: - return PSYC_PARSE_UNIFORM_INVALID_TRANSPORT; - } - break; - - case PSYC_UNIFORM_RESOURCE: - if (psyc_is_name_char(c)) { - uni->resource.length++; - break; - } else if (c == '#') { - part = PSYC_UNIFORM_CHANNEL; - uni->channel.data = str + pos + 1; - uni->channel.length = 0; - break; - } else return PSYC_PARSE_UNIFORM_INVALID_RESOURCE; - - case PSYC_UNIFORM_CHANNEL: - if (psyc_is_name_char(c)) { - uni->channel.length++; - break; - } else return PSYC_PARSE_UNIFORM_INVALID_CHANNEL; - } - pos++; + case PSYC_UNIFORM_HOST: + if (psyc_is_host_char(c)) { + uni->host.length++; + break; } if (uni->host.length == 0) - return PSYC_PARSE_UNIFORM_INVALID_HOST; + return PSYC_PARSE_UNIFORM_INVALID_HOST; - uni->host_port.data = uni->host.data; - uni->host_port.length = uni->host.length + uni->port.length + uni->transport.length; - if (uni->port.length > 0 || uni->transport.length > 0) - uni->host_port.length++; + if (c == ':') { + part = PSYC_UNIFORM_PORT; + p = &uni->port; + } else if (c == '/') { + uni->slash.data = str + pos; + uni->slash.length = 1; - uni->root.data = str; - uni->root.length = uni->scheme.length + 1 + uni->slashes.length + - uni->host_port.length; + part = PSYC_UNIFORM_RESOURCE; + p = &uni->resource; + } else + return PSYC_PARSE_UNIFORM_INVALID_HOST; - uni->entity.data = str; - uni->entity.length = uni->root.length + uni->slash.length + uni->resource.length; + p->data = str + pos + 1; + p->length = 0; + break; - uni->body.data = uni->host.data; - uni->body.length = length - uni->scheme.length - 1 - uni->slashes.length; - - if (uni->resource.length) { - uni->nick.data = uni->resource.data + 1; - uni->nick.length = uni->resource.length; + case PSYC_UNIFORM_PORT: + if (psyc_is_numeric(c) || (uni->port.length == 0 && c == '-')) { + uni->port.length++; + break; } - } else return PSYC_PARSE_UNIFORM_INVALID_SCHEME; + if (uni->port.length == 0 && c != PSYC_TRANSPORT_GNUNET) + return PSYC_PARSE_UNIFORM_INVALID_PORT; - if (uni->host.length == 0) - return PSYC_PARSE_UNIFORM_INVALID_HOST; + if (c == '/') { + uni->slash.data = str + pos; + uni->slash.length = 1; - uni->valid = 1; - return uni->type; + part = PSYC_UNIFORM_RESOURCE; + uni->resource.data = str + pos + 1; + uni->resource.length = 0; + break; + } else { + part = PSYC_UNIFORM_TRANSPORT; + uni->transport.data = str + pos; + uni->transport.length = 0; + } + // fall thru + + case PSYC_UNIFORM_TRANSPORT: + switch (c) { + case PSYC_TRANSPORT_GNUNET: + if (uni->port.length > 0) + return PSYC_PARSE_UNIFORM_INVALID_TRANSPORT; + case PSYC_TRANSPORT_TCP: + case PSYC_TRANSPORT_UDP: + case PSYC_TRANSPORT_TLS: + if (uni->transport.length > 0) + return PSYC_PARSE_UNIFORM_INVALID_TRANSPORT; + uni->transport.length++; + break; + case '/': + uni->slash.data = str + pos; + uni->slash.length = 1; + + part = PSYC_UNIFORM_RESOURCE; + uni->resource.data = str + pos + 1; + uni->resource.length = 0; + break; + default: + return PSYC_PARSE_UNIFORM_INVALID_TRANSPORT; + } + break; + + case PSYC_UNIFORM_RESOURCE: + if (psyc_is_name_char(c)) { + uni->resource.length++; + break; + } else if (c == '#') { + part = PSYC_UNIFORM_CHANNEL; + uni->channel.data = str + pos + 1; + uni->channel.length = 0; + break; + } else + return PSYC_PARSE_UNIFORM_INVALID_RESOURCE; + + case PSYC_UNIFORM_CHANNEL: + if (psyc_is_name_char(c)) { + uni->channel.length++; + break; + } else + return PSYC_PARSE_UNIFORM_INVALID_CHANNEL; + } + pos++; + } + + if (uni->host.length == 0) + return PSYC_PARSE_UNIFORM_INVALID_HOST; + + uni->host_port.data = uni->host.data; + uni->host_port.length = uni->host.length + uni->port.length + + uni->transport.length; + + if (uni->port.length > 0 || uni->transport.length > 0) + uni->host_port.length++; + + uni->root.data = str; + uni->root.length = uni->scheme.length + 1 + + uni->slashes.length + uni->host_port.length; + + uni->entity.data = str; + uni->entity.length = uni->root.length + uni->slash.length + + uni->resource.length; + + uni->body.data = uni->host.data; + uni->body.length = length - uni->scheme.length - 1 - uni->slashes.length; + + if (uni->resource.length) { + uni->nick.data = uni->resource.data + 1; + uni->nick.length = uni->resource.length; + } + + } else + return PSYC_PARSE_UNIFORM_INVALID_SCHEME; + + if (uni->host.length == 0) + return PSYC_PARSE_UNIFORM_INVALID_HOST; + + uni->valid = 1; + return uni->type; } diff --git a/src/variable.c b/src/variable.c index 11aa1a1..3d0833d 100644 --- a/src/variable.c +++ b/src/variable.c @@ -3,44 +3,43 @@ /// Routing variables in alphabetical order. -const PsycString psyc_routing_vars[] = -{ - PSYC_C2STRI("_amount_fragments"), - PSYC_C2STRI("_context"), - //PSYC_C2STRI("_count"), // older PSYC - PSYC_C2STRI("_counter"), // the name for this is supposed to be _count, not _counter - PSYC_C2STRI("_fragment"), - //PSYC_C2STRI("_length"), // older PSYC - PSYC_C2STRI("_source"), - //PSYC_C2STRI("_source_identification"), // older PSYC - PSYC_C2STRI("_source_identity"), - PSYC_C2STRI("_source_relay"), - PSYC_C2STRI("_source_relay_relay"), // until you have a better idea.. is this really in use? - PSYC_C2STRI("_tag"), - PSYC_C2STRI("_tag_relay"), - //PSYC_C2STRI("_tag_reply"), // older PSYC - PSYC_C2STRI("_target"), - PSYC_C2STRI("_target_forward"), - PSYC_C2STRI("_target_relay"), - //PSYC_C2STRI("_understand_modules"), // older PSYC - //PSYC_C2STRI("_using_modules"), // older PSYC +const PsycString psyc_routing_vars[] = { + PSYC_C2STRI("_amount_fragments"), + PSYC_C2STRI("_context"), + //PSYC_C2STRI("_count"), // older PSYC + PSYC_C2STRI("_counter"), // the name for this is supposed to be _count, not _counter + PSYC_C2STRI("_fragment"), + //PSYC_C2STRI("_length"), // older PSYC + PSYC_C2STRI("_source"), + //PSYC_C2STRI("_source_identification"), // older PSYC + PSYC_C2STRI("_source_identity"), + PSYC_C2STRI("_source_relay"), + // until you have a better idea.. is this really in use? + PSYC_C2STRI("_source_relay_relay"), + PSYC_C2STRI("_tag"), + PSYC_C2STRI("_tag_relay"), + //PSYC_C2STRI("_tag_reply"), // older PSYC + PSYC_C2STRI("_target"), + PSYC_C2STRI("_target_forward"), + PSYC_C2STRI("_target_relay"), + //PSYC_C2STRI("_understand_modules"), // older PSYC + //PSYC_C2STRI("_using_modules"), // older PSYC }; // Variable types in alphabetical order. -const PsycDictInt psyc_var_types[] = -{ - {PSYC_C2STRI("_amount"), PSYC_TYPE_AMOUNT}, - {PSYC_C2STRI("_color"), PSYC_TYPE_COLOR}, - {PSYC_C2STRI("_date"), PSYC_TYPE_DATE}, - {PSYC_C2STRI("_degree"), PSYC_TYPE_DEGREE}, - {PSYC_C2STRI("_entity"), PSYC_TYPE_ENTITY}, - {PSYC_C2STRI("_flag"), PSYC_TYPE_FLAG}, - {PSYC_C2STRI("_language"), PSYC_TYPE_LANGUAGE}, - {PSYC_C2STRI("_list"), PSYC_TYPE_LIST}, - {PSYC_C2STRI("_nick"), PSYC_TYPE_NICK}, - {PSYC_C2STRI("_page"), PSYC_TYPE_PAGE}, - {PSYC_C2STRI("_uniform"), PSYC_TYPE_UNIFORM}, - {PSYC_C2STRI("_time"), PSYC_TYPE_TIME}, +const PsycDictInt psyc_var_types[] = { + {PSYC_C2STRI("_amount"), PSYC_TYPE_AMOUNT}, + {PSYC_C2STRI("_color"), PSYC_TYPE_COLOR}, + {PSYC_C2STRI("_date"), PSYC_TYPE_DATE}, + {PSYC_C2STRI("_degree"), PSYC_TYPE_DEGREE}, + {PSYC_C2STRI("_entity"), PSYC_TYPE_ENTITY}, + {PSYC_C2STRI("_flag"), PSYC_TYPE_FLAG}, + {PSYC_C2STRI("_language"), PSYC_TYPE_LANGUAGE}, + {PSYC_C2STRI("_list"), PSYC_TYPE_LIST}, + {PSYC_C2STRI("_nick"), PSYC_TYPE_NICK}, + {PSYC_C2STRI("_page"), PSYC_TYPE_PAGE}, + {PSYC_C2STRI("_uniform"), PSYC_TYPE_UNIFORM}, + {PSYC_C2STRI("_time"), PSYC_TYPE_TIME}, }; const size_t psyc_routing_vars_num = PSYC_NUM_ELEM(psyc_routing_vars); @@ -49,51 +48,50 @@ const size_t psyc_var_types_num = PSYC_NUM_ELEM(psyc_var_types); /** * Get the type of variable name. */ -inline -PsycBool psyc_var_is_routing (const char *name, size_t len) +inline PsycBool +psyc_var_is_routing (const char *name, size_t len) { - size_t cursor = 1; - uint8_t i, m = 0; - int8_t matching[psyc_routing_vars_num]; // indexes of matching vars + size_t cursor = 1; + uint8_t i, m = 0; + int8_t matching[psyc_routing_vars_num]; // indexes of matching vars - if (len < 2 || name[0] != '_') - return PSYC_FALSE; + if (len < 2 || name[0] != '_') + return PSYC_FALSE; - // first find the vars with matching length - for (i=0; i= 0) - { - for (i = m = 0; i < psyc_routing_vars_num; i++) - { - if (matching[i] < 0) - break; // reached the end of possible matches - if (psyc_routing_vars[matching[i]].data[cursor] == name[cursor]) - matching[m++] = matching[i]; // found a match, update matching indexes - else if (psyc_routing_vars[matching[i]].data[cursor] > name[cursor]) - break; // passed the possible matches in alphabetical order in the array - } - - if (m < psyc_routing_vars_num) - matching[m] = -1; // mark the end of matching indexes - - cursor++; + while (cursor < len && matching[0] >= 0) { + for (i = m = 0; i < psyc_routing_vars_num; i++) { + if (matching[i] < 0) + break; // reached the end of possible matches + if (psyc_routing_vars[matching[i]].data[cursor] == name[cursor]) + matching[m++] = matching[i]; // found a match, update matching indexes + else if (psyc_routing_vars[matching[i]].data[cursor] > name[cursor]) + break; // passed the possible matches in alphabetical order in the array } - return matching[0] >= 0 ? PSYC_TRUE : PSYC_FALSE; + if (m < psyc_routing_vars_num) + matching[m] = -1; // mark the end of matching indexes + + cursor++; + } + + return matching[0] >= 0 ? PSYC_TRUE : PSYC_FALSE; } /** * Get the type of variable name. */ -inline -PsycType psyc_var_type (const char *name, size_t len) +inline PsycType +psyc_var_type (const char *name, size_t len) { - int8_t m[psyc_var_types_num]; - return (PsycType) psyc_dict_lookup((PsycDict*)psyc_var_types, psyc_var_types_num, - name, len, PSYC_YES, (int8_t*)&m); + int8_t m[psyc_var_types_num]; + return (PsycType) psyc_dict_lookup((PsycDict *) psyc_var_types, + psyc_var_types_num, name, len, PSYC_YES, + (int8_t *) &m); } diff --git a/test/test.c b/test/test.c index 1265a5c..af20530 100644 --- a/test/test.c +++ b/test/test.c @@ -30,236 +30,244 @@ // cmd line args extern uint8_t verbose, stats; -void check_range(char c, const char *s, int min, int max) { - int n = atoi(s); - if (n < min) { - printf("-%c: error, should be >= %d\n", c, min); - exit(-1); - } - if (max > min && n > max) { - printf("-%c: error, should be <= %d\n", c, max); - exit(-1); - } +void +check_range (char c, const char *s, int min, int max) +{ + int n = atoi(s); + if (n < min) { + printf("-%c: error, should be >= %d\n", c, min); + exit(-1); + } + if (max > min && n > max) { + printf("-%c: error, should be <= %d\n", c, max); + exit(-1); + } } // get sockaddr, IPv4 or IPv6: -void *get_in_addr (struct sockaddr *sa) { - if (sa->sa_family == AF_INET) - return &(((struct sockaddr_in*)sa)->sin_addr); +void * +get_in_addr (struct sockaddr *sa) +{ + if (sa->sa_family == AF_INET) + return &(((struct sockaddr_in*)sa)->sin_addr); - return &(((struct sockaddr_in6*)sa)->sin6_addr); + return &(((struct sockaddr_in6*)sa)->sin6_addr); } -void test_file(const char* filename, size_t count, size_t recv_buf_size) { - char *buf, *recvbuf; // cont buf + recv buf: [ ccrrrr] - size_t i, nbytes, size; - struct timeval start, end; - struct stat st; +void +test_file (const char* filename, size_t count, size_t recv_buf_size) +{ + char *buf, *recvbuf; // cont buf + recv buf: [ ccrrrr] + size_t i, nbytes, size; + struct timeval start, end; + struct stat st; - int fd = open(filename, O_RDONLY); - if (fd < 0) { - perror("open"); - exit(1); - } + int fd = open(filename, O_RDONLY); + if (fd < 0) { + perror("open"); + exit(1); + } - fstat(fd, &st); + fstat(fd, &st); - size = CONT_BUF_SIZE + st.st_size; - buf = malloc(size); - if (!buf) { - perror("malloc"); - exit(1); - } - recvbuf = buf + CONT_BUF_SIZE; + size = CONT_BUF_SIZE + st.st_size; + buf = malloc(size); + if (!buf) { + perror("malloc"); + exit(1); + } + recvbuf = buf + CONT_BUF_SIZE; - test_init(0); + test_init(0); - if (recv_buf_size) { - if (stats) - gettimeofday(&start, NULL); + if (recv_buf_size) { + if (stats) + gettimeofday(&start, NULL); #ifdef NOREAD - memset(buf, 1, size); + memset(buf, 1, size); #else - size = 0; + size = 0; #endif - for (i = 0; i < count; i++) + for (i = 0; i < count; i++) #ifndef NOREAD - while ((nbytes = read(fd, (void*)recvbuf, recv_buf_size))) + while ((nbytes = read(fd, (void*)recvbuf, recv_buf_size))) #endif - test_input(0, recvbuf, nbytes); + test_input(0, recvbuf, nbytes); - } else { + } else { #ifdef NOREAD - memset(buf, 1, size); + memset(buf, 1, size); #else - size = 0; - while ((nbytes = read(fd, (void*)recvbuf + size, RECV_BUF_SIZE))) - size += nbytes; + size = 0; + while ((nbytes = read(fd, (void*)recvbuf + size, RECV_BUF_SIZE))) + size += nbytes; #endif - if (stats) - gettimeofday(&start, NULL); + if (stats) + gettimeofday(&start, NULL); - for (i = 0; i < count; i++) - test_input(0, recvbuf, size); - } + for (i = 0; i < count; i++) + test_input(0, recvbuf, size); + } - if (stats) { - gettimeofday(&end, NULL); - printf("%ld\n", (end.tv_sec * 1000000 + end.tv_usec - start.tv_sec * 1000000 - start.tv_usec) / 1000); - } + if (stats) { + gettimeofday(&end, NULL); + printf("%ld\n", (end.tv_sec * 1000000 + end.tv_usec - start.tv_sec * 1000000 - start.tv_usec) / 1000); + } } -void test_server(const char* port, size_t count, size_t recv_buf_size) { - char buf[CONT_BUF_SIZE + RECV_BUF_SIZE]; // cont buf + recv buf: [ ccrrrr] - char *recvbuf = buf + CONT_BUF_SIZE; // recv buf: ^^^^ +void +test_server (const char* port, size_t count, size_t recv_buf_size) +{ + char buf[CONT_BUF_SIZE + RECV_BUF_SIZE]; // cont buf + recv buf: [ ccrrrr] + char *recvbuf = buf + CONT_BUF_SIZE; // recv buf: ^^^^ - fd_set master; // master file descriptor list - fd_set read_fds; // temp file descriptor list for select() - int fdmax; // maximum file descriptor number + fd_set master; // master file descriptor list + fd_set read_fds; // temp file descriptor list for select() + int fdmax; // maximum file descriptor number - int listener; // listening socket descriptor - int newfd; // newly accept()ed socket descriptor - struct sockaddr_storage remoteaddr; // client address - socklen_t addrlen; - size_t nbytes; + int listener; // listening socket descriptor + int newfd; // newly accept()ed socket descriptor + struct sockaddr_storage remoteaddr; // client address + socklen_t addrlen; + size_t nbytes; - char remoteIP[INET6_ADDRSTRLEN]; + char remoteIP[INET6_ADDRSTRLEN]; - int yes = 1; // for setsockopt() SO_REUSEADDR, below - int i, rv, ret; + int yes = 1; // for setsockopt() SO_REUSEADDR, below + int i, rv, ret; - struct addrinfo hints, *ai, *p; - struct timeval start[NUM_PARSERS], end[NUM_PARSERS]; + struct addrinfo hints, *ai, *p; + struct timeval start[NUM_PARSERS], end[NUM_PARSERS]; - FD_ZERO(&master); // clear the master and temp sets - FD_ZERO(&read_fds); + FD_ZERO(&master); // clear the master and temp sets + FD_ZERO(&read_fds); - // get us a socket and bind it - memset(&hints, 0, sizeof hints); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_PASSIVE; - if ((rv = getaddrinfo(NULL, port, &hints, &ai)) != 0) { - fprintf(stderr, "error: %s\n", gai_strerror(rv)); - exit(1); - } + // get us a socket and bind it + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + if ((rv = getaddrinfo(NULL, port, &hints, &ai)) != 0) { + fprintf(stderr, "error: %s\n", gai_strerror(rv)); + exit(1); + } - for (p = ai; p != NULL; p = p->ai_next) { - listener = socket(p->ai_family, p->ai_socktype, p->ai_protocol); - if (listener < 0) - continue; + for (p = ai; p != NULL; p = p->ai_next) { + listener = socket(p->ai_family, p->ai_socktype, p->ai_protocol); + if (listener < 0) + continue; - // lose the pesky "address already in use" error message - setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); + // lose the pesky "address already in use" error message + setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); - if (bind(listener, p->ai_addr, p->ai_addrlen) < 0) { - close(listener); - continue; - } - - break; + if (bind(listener, p->ai_addr, p->ai_addrlen) < 0) { + close(listener); + continue; } - // if we got here, it means we didn't get bound - if (p == NULL) { - fprintf(stderr, "failed to bind\n"); - exit(2); + break; + } + + // if we got here, it means we didn't get bound + if (p == NULL) { + fprintf(stderr, "failed to bind\n"); + exit(2); + } + + freeaddrinfo(ai); // all done with this + + // listen + if (listen(listener, 10) == -1) { + perror("listen"); + exit(3); + } + + printf("# Listening on TCP port %s\n", port); + + // add the listener to the master set + FD_SET(listener, &master); + + // keep track of the biggest file descriptor + fdmax = listener; // so far, it's this one + + // main loop + for (;;) { + read_fds = master; // copy it + if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) { + perror("select"); + exit(4); } - freeaddrinfo(ai); // all done with this + // run through the existing connections looking for data to read + for (i = 0; i <= fdmax; i++) { + if (FD_ISSET(i, &read_fds)) { // we got one!! + if (i == listener) { + // handle new connections + if (fdmax == NUM_PARSERS - 1) + continue; // ignore if there's too many - // listen - if (listen(listener, 10) == -1) { - perror("listen"); - exit(3); - } + addrlen = sizeof remoteaddr; + newfd = accept(listener, (struct sockaddr *)&remoteaddr, &addrlen); - printf("# Listening on TCP port %s\n", port); + if (newfd == -1) { + perror("accept"); + } else { + FD_SET(newfd, &master); // add to master set + if (newfd > fdmax) // keep track of the max + fdmax = newfd; - // add the listener to the master set - FD_SET(listener, &master); + test_init(newfd); - // keep track of the biggest file descriptor - fdmax = listener; // so far, it's this one + if (verbose) + printf("# New connection from %s on socket %d\n", + inet_ntop(remoteaddr.ss_family, + get_in_addr((struct sockaddr*)&remoteaddr), + remoteIP, INET6_ADDRSTRLEN), + newfd); - // main loop - for (;;) { - read_fds = master; // copy it - if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) { - perror("select"); - exit(4); - } + if (stats) + gettimeofday(&start[newfd], NULL); + } + } else { + // handle data from a client + if ((nbytes = recv(i, recvbuf, recv_buf_size, 0)) <= 0) { + if (stats) + printf("%ld ms\n", (end[i].tv_sec * 1000000 + end[i].tv_usec - start[i].tv_sec * 1000000 - start[i].tv_usec) / 1000); - // run through the existing connections looking for data to read - for (i = 0; i <= fdmax; i++) { - if (FD_ISSET(i, &read_fds)) { // we got one!! - if (i == listener) { - // handle new connections - if (fdmax == NUM_PARSERS - 1) - continue; // ignore if there's too many + // got error or connection closed by client + if (nbytes == 0) { // connection closed + if (verbose) + printf("# Socket %d hung up\n", i); + } else { + perror("recv"); + } - addrlen = sizeof remoteaddr; - newfd = accept(listener, (struct sockaddr *)&remoteaddr, &addrlen); + close(i); // bye! + FD_CLR(i, &master); // remove from master set + } else { + // we got some data from a client + if (verbose >= 2) + printf("> %ld bytes\n", nbytes); + if (verbose >= 3) + printf("> [%.*s]", (int)nbytes, recvbuf); - if (newfd == -1) { - perror("accept"); - } else { - FD_SET(newfd, &master); // add to master set - if (newfd > fdmax) // keep track of the max - fdmax = newfd; + ret = test_input(i, recvbuf, nbytes); - test_init(newfd); + if (stats) + gettimeofday(&end[i], NULL); - if (verbose) - printf("# New connection from %s on socket %d\n", - inet_ntop(remoteaddr.ss_family, - get_in_addr((struct sockaddr*)&remoteaddr), - remoteIP, INET6_ADDRSTRLEN), - newfd); - - if (stats) - gettimeofday(&start[newfd], NULL); - } - } else { - // handle data from a client - if ((nbytes = recv(i, recvbuf, recv_buf_size, 0)) <= 0) { - if (stats) - printf("%ld ms\n", (end[i].tv_sec * 1000000 + end[i].tv_usec - start[i].tv_sec * 1000000 - start[i].tv_usec) / 1000); - - // got error or connection closed by client - if (nbytes == 0) { // connection closed - if (verbose) - printf("# Socket %d hung up\n", i); - } else { - perror("recv"); - } - - close(i); // bye! - FD_CLR(i, &master); // remove from master set - } else { - // we got some data from a client - if (verbose >= 2) - printf("> %ld bytes\n", nbytes); - if (verbose >= 3) - printf("> [%.*s]", (int)nbytes, recvbuf); - - ret = test_input(i, recvbuf, nbytes); - - if (stats) - gettimeofday(&end[i], NULL); - - if (ret < 0) { - if (verbose) - printf("# Closing connection: %i\n", i); - close(i); // bye! - FD_CLR(i, &master); // remove from master set - } - } - } // END handle data from client - } // END got new incoming connection - } // END looping through file descriptors - } // END for(;;)--and you thought it would never end! + if (ret < 0) { + if (verbose) + printf("# Closing connection: %i\n", i); + close(i); // bye! + FD_CLR(i, &master); // remove from master set + } + } + } // END handle data from client + } // END got new incoming connection + } // END looping through file descriptors + } // END for(;;)--and you thought it would never end! } diff --git a/test/test.h b/test/test.h index 877de82..e8bf2c0 100644 --- a/test/test.h +++ b/test/test.h @@ -42,11 +42,19 @@ #define HELP_P " -P\t\t\tShow progress\n" #define HELP_h " -h\t\t\tShow this help\n" -void test_init(int i); -int test_input(int i, char *recvbuf, size_t nbytes); +void +test_init (int i); -void test_file(const char* filename, size_t count, size_t recv_buf_size); -void test_server(const char* port, size_t count, size_t recv_buf_size); -void check_range(char c, const char *s, int min, int max); +int +test_input (int i, char *recvbuf, size_t nbytes); + +void +test_file (const char* filename, size_t count, size_t recv_buf_size); + +void +test_server (const char* port, size_t count, size_t recv_buf_size); + +void +check_range (char c, const char *s, int min, int max); #endif diff --git a/test/test_json.c b/test/test_json.c index 126a84b..7d47a8d 100644 --- a/test/test_json.c +++ b/test/test_json.c @@ -26,88 +26,93 @@ json_object *obj; json_tokener *tok; enum json_tokener_error error; -void test_init (int i) { - tok = json_tokener_new(); +void +test_init (int i) +{ + tok = json_tokener_new(); } -int test_input (int i, char *recvbuf, size_t nbytes) { - size_t cursor = 0; - int r, ret = 0; +int +test_input (int i, char *recvbuf, size_t nbytes) +{ + size_t cursor = 0; + int r, ret = 0; - json_tokener_reset(tok); + json_tokener_reset(tok); - do { - obj = json_tokener_parse_ex(tok, recvbuf + cursor, nbytes - cursor); - cursor += tok->char_offset; + do { + obj = json_tokener_parse_ex(tok, recvbuf + cursor, nbytes - cursor); + cursor += tok->char_offset; - if (verbose) - printf("#%d\n", tok->err); + if (verbose) + printf("#%d\n", tok->err); - switch (tok->err) { - case json_tokener_continue: - return 0; + switch (tok->err) { + case json_tokener_continue: + return 0; - case json_tokener_success: - if (!no_render) { - const char *str = json_object_to_json_string(obj); - if (!quiet) { - size_t len = strlen(str); - if (filename) { - r = write(1, str, len); - r = write(1, "\n", 1); - } else { - send(i, str, len, 0); - send(i, "\n", 1, 0); - } - } - } - - json_object_put(obj); - - if (verbose) - printf("# Done parsing.\n"); - else if (progress) - r = write(1, ".", 1); - if ((filename && !multiple) || (!filename && single)) - return -1; - break; - - default: - printf("parse error\n"); - exit_code = tok->err; - return -1; + case json_tokener_success: + if (!no_render) { + const char *str = json_object_to_json_string(obj); + if (!quiet) { + size_t len = strlen(str); + if (filename) { + r = write(1, str, len); + r = write(1, "\n", 1); + } else { + send(i, str, len, 0); + send(i, "\n", 1, 0); + } } - } while (cursor < nbytes); + } - return ret; -} + json_object_put(obj); -int main (int argc, char **argv) { - int c; + if (verbose) + printf("# Done parsing.\n"); + else if (progress) + r = write(1, ".", 1); + if ((filename && !multiple) || (!filename && single)) + return -1; + break; - while ((c = getopt (argc, argv, "f:p:b:c:mnqsvPSh")) != -1) { - switch (c) { - CASE_f CASE_p CASE_b CASE_c - CASE_m CASE_n CASE_q CASE_s - CASE_v CASE_S CASE_P - case 'h': - printf( - HELP_FILE("test_json", "mnqSsvP") - HELP_PORT("test_json", "nqsvP") - HELP_f HELP_p HELP_b HELP_c - HELP_m HELP_n HELP_q HELP_S - HELP_s HELP_v HELP_P HELP_h, - port, RECV_BUF_SIZE); - exit(0); - case '?': exit(-1); - default: abort(); - } + default: + printf("parse error\n"); + exit_code = tok->err; + return -1; } + } while (cursor < nbytes); - if (filename) - test_file(filename, count, recv_buf_size); - else - test_server(port, count, recv_buf_size); - - return exit_code; + return ret; +} + +int +main (int argc, char **argv) +{ + int c; + + while ((c = getopt (argc, argv, "f:p:b:c:mnqsvPSh")) != -1) { + switch (c) { + CASE_f CASE_p CASE_b CASE_c + CASE_m CASE_n CASE_q CASE_s + CASE_v CASE_S CASE_P + case 'h': + printf(HELP_FILE("test_json", "mnqSsvP") + HELP_PORT("test_json", "nqsvP") + HELP_f HELP_p HELP_b HELP_c + HELP_m HELP_n HELP_q HELP_S + HELP_s HELP_v HELP_P HELP_h, + port, RECV_BUF_SIZE); + exit(0); + case '?': exit(-1); + default: abort(); + } + } + + if (filename) + test_file(filename, count, recv_buf_size); + else + test_server(port, count, recv_buf_size); + + return exit_code; } diff --git a/test/test_json_glib.c b/test/test_json_glib.c index 4327adb..5fd2577 100644 --- a/test/test_json_glib.c +++ b/test/test_json_glib.c @@ -24,76 +24,79 @@ int exit_code; JsonParser *parser; JsonGenerator *generator; -void test_init (int i) { - g_type_init(); - parser = json_parser_new(); - generator = json_generator_new(); +void +test_init (int i) +{ + g_type_init(); + parser = json_parser_new(); + generator = json_generator_new(); } -int test_input (int i, char *recvbuf, size_t nbytes) { - JsonNode *root; - GError *error = NULL; - char *str; - size_t len; - int r, ret; +int +test_input (int i, char *recvbuf, size_t nbytes) +{ + JsonNode *root; + GError *error = NULL; + char *str; + size_t len; + int r, ret; - ret = json_parser_load_from_data(parser, recvbuf, nbytes, &error); + ret = json_parser_load_from_data(parser, recvbuf, nbytes, &error); - if (!ret) { - printf("Parse error\n"); - exit(1); + if (!ret) { + printf("Parse error\n"); + exit(1); + } + + root = json_parser_get_root(parser); + + if (!no_render) { + json_generator_set_root(generator, root); + str = json_generator_to_data(generator, &len);; + if (!quiet) { + if (filename) { + r = write(1, str, len); + r = write(1, "\n", 1); + } else { + send(i, str, len, 0); + send(i, "\n", 1, 0); + } } + } - root = json_parser_get_root(parser); + if (verbose) + printf("# Done parsing.\n"); + else if (progress) + r = write(1, ".", 1); - if (!no_render) { - json_generator_set_root(generator, root); - str = json_generator_to_data(generator, &len);; - if (!quiet) { - if (filename) { - r = write(1, str, len); - r = write(1, "\n", 1); - } else { - send(i, str, len, 0); - send(i, "\n", 1, 0); - } - } - } - - if (verbose) - printf("# Done parsing.\n"); - else if (progress) - r = write(1, ".", 1); - - return ret; + return ret; } int main (int argc, char **argv) { - int c; + int c; - while ((c = getopt (argc, argv, "f:p:b:c:nqsvPh")) != -1) { - switch (c) { - CASE_f CASE_p CASE_b - CASE_c CASE_n CASE_q - CASE_s CASE_v CASE_P - case 'h': - printf( - HELP_FILE("test_json_glib", "mnqSsvP") - HELP_PORT("test_json_glib", "nqsvP") - HELP_f HELP_p HELP_b HELP_c - HELP_m HELP_n HELP_q HELP_S - HELP_s HELP_v HELP_P HELP_h, - port, RECV_BUF_SIZE); - exit(0); - case '?': exit(-1); - default: abort(); - } + while ((c = getopt (argc, argv, "f:p:b:c:nqsvPh")) != -1) { + switch (c) { + CASE_f CASE_p CASE_b + CASE_c CASE_n CASE_q + CASE_s CASE_v CASE_P + case 'h': + printf(HELP_FILE("test_json_glib", "mnqSsvP") + HELP_PORT("test_json_glib", "nqsvP") + HELP_f HELP_p HELP_b HELP_c + HELP_m HELP_n HELP_q HELP_S + HELP_s HELP_v HELP_P HELP_h, + port, RECV_BUF_SIZE); + exit(0); + case '?': exit(-1); + default: abort(); } + } - if (filename) - test_file(filename, count, recv_buf_size); - else - test_server(port, count, recv_buf_size); + if (filename) + test_file(filename, count, recv_buf_size); + else + test_server(port, count, recv_buf_size); - return exit_code; + return exit_code; } diff --git a/test/test_match.c b/test/test_match.c index 6874e14..1a490b8 100644 --- a/test/test_match.c +++ b/test/test_match.c @@ -2,19 +2,35 @@ #include int main() { - if (psyc_matches(PSYC_C2ARG("_failure_delivery"), PSYC_C2ARG("_failure_unsuccessful_delivery_death"))) return 1; - if (psyc_matches(PSYC_C2ARG("_failure"), PSYC_C2ARG("_failure_unsuccessful_delivery_death"))) return 2; - if (psyc_matches(PSYC_C2ARG("_unsuccessful"), PSYC_C2ARG("_failure_unsuccessful_delivery_death"))) return 3; - unless (psyc_matches(PSYC_C2ARG("_fail"), PSYC_C2ARG("_failure_unsuccessful_delivery_death"))) return 4; - unless (psyc_matches(PSYC_C2ARG("_truthahn"), PSYC_C2ARG("_failure_unsuccessful_delivery_death"))) return 5; + if (psyc_matches(PSYC_C2ARG("_failure_delivery"), + PSYC_C2ARG("_failure_unsuccessful_delivery_death"))) + return 1; + if (psyc_matches(PSYC_C2ARG("_failure"), + PSYC_C2ARG("_failure_unsuccessful_delivery_death"))) + return 2; + if (psyc_matches(PSYC_C2ARG("_unsuccessful"), + PSYC_C2ARG("_failure_unsuccessful_delivery_death"))) + return 3; + unless (psyc_matches(PSYC_C2ARG("_fail"), + PSYC_C2ARG("_failure_unsuccessful_delivery_death"))) + return 4; + unless (psyc_matches(PSYC_C2ARG("_truthahn"), + PSYC_C2ARG("_failure_unsuccessful_delivery_death"))) + return 5; - puts("psyc_matches passed all tests."); + puts("psyc_matches passed all tests."); - unless (psyc_inherits(PSYC_C2ARG("_failure_delivery"), PSYC_C2ARG("_failure_unsuccessful_delivery_death"))) return 11; - if (psyc_inherits(PSYC_C2ARG("_failure_unsuccessful"), PSYC_C2ARG("_failure_unsuccessful_delivery_death"))) return 12; - unless (psyc_inherits(PSYC_C2ARG("_fail"), PSYC_C2ARG("_failure_unsuccessful_delivery_death"))) return 13; + unless (psyc_inherits(PSYC_C2ARG("_failure_delivery"), + PSYC_C2ARG("_failure_unsuccessful_delivery_death"))) + return 11; + if (psyc_inherits(PSYC_C2ARG("_failure_unsuccessful"), + PSYC_C2ARG("_failure_unsuccessful_delivery_death"))) + return 12; + unless (psyc_inherits(PSYC_C2ARG("_fail"), + PSYC_C2ARG("_failure_unsuccessful_delivery_death"))) + return 13; - puts("psyc_inherits passed all tests."); + puts("psyc_inherits passed all tests."); - return 0; // passed all tests + return 0; // passed all tests } diff --git a/test/test_parser.c b/test/test_parser.c index 4d2c4e4..769ca23 100644 --- a/test/test_parser.c +++ b/test/test_parser.c @@ -5,101 +5,96 @@ #include #include -int main (int argc, char **argv) +int +main (int argc, char **argv) { - uint8_t routing_only = argc > 2 && memchr(argv[2], (int)'r', strlen(argv[2])); - uint8_t verbose = argc > 2 && memchr(argv[2], (int)'v', strlen(argv[2])); - int idx, ret; - char buffer[2048], oper; - PsycString name, value, elem; - PsycParseState state; - PsycParseListState listState; + uint8_t routing_only = argc > 2 && memchr(argv[2], (int)'r', strlen(argv[2])); + uint8_t verbose = argc > 2 && memchr(argv[2], (int)'v', strlen(argv[2])); + int idx, ret; + char buffer[2048], oper; + PsycString name, value, elem; + PsycParseState state; + PsycParseListState listState; - if (argc < 2) - return -1; - int file = open(argv[1],O_RDONLY); - if (file < 0) - return -1; - idx = read(file,(void*)buffer,sizeof(buffer)); + if (argc < 2) + return -1; + int file = open(argv[1],O_RDONLY); + if (file < 0) + return -1; + idx = read(file,(void*)buffer,sizeof(buffer)); - if (verbose) { - printf(">> INPUT\n"); - printf("%.*s\n", (int)idx, buffer); - printf(">> PARSE\n"); - } + if (verbose) { + printf(">> INPUT\n"); + printf("%.*s\n", (int)idx, buffer); + printf(">> PARSE\n"); + } - psyc_parse_state_init(&state, routing_only ? - PSYC_PARSE_ROUTING_ONLY : PSYC_PARSE_ALL); - psyc_parse_buffer_set(&state, buffer, idx); + psyc_parse_state_init(&state, routing_only ? + PSYC_PARSE_ROUTING_ONLY : PSYC_PARSE_ALL); + psyc_parse_buffer_set(&state, buffer, idx); - // try parsing that now - do - { - oper = 0; - name.length = 0; - value.length = 0; + // try parsing that now + do { + oper = 0; + name.length = 0; + value.length = 0; - ret = psyc_parse(&state, &oper, &name, &value); + ret = psyc_parse(&state, &oper, &name, &value); + if (verbose) + printf(">> ret = %d\n", ret); + + switch (ret) { + case PSYC_PARSE_ROUTING: + case PSYC_PARSE_ENTITY: + if (verbose) + printf("%c", oper); + case PSYC_PARSE_BODY: + // printf("the string is '%.*s'\n", name); + if (verbose) + printf("%.*s = %.*s\n", + (int)name.length, name.data, + (int)value.length, value.data); + + if (psyc_var_is_list(PSYC_S2ARG(name))) { if (verbose) - printf(">> ret = %d\n", ret); + printf(">> LIST START\n"); - switch (ret) - { - case PSYC_PARSE_ROUTING: - case PSYC_PARSE_ENTITY: - if (verbose) - printf("%c", oper); - case PSYC_PARSE_BODY: - // printf("the string is '%.*s'\n", name); - if (verbose) - printf("%.*s = %.*s\n", - (int)name.length, name.data, - (int)value.length, value.data); + psyc_parse_list_state_init(&listState); + psyc_parse_list_buffer_set(&listState, PSYC_S2ARG(value)); - if (psyc_var_is_list(PSYC_S2ARG(name))) - { - if (verbose) - printf(">> LIST START\n"); + while ((ret = psyc_parse_list(&listState, &elem))) { + switch (ret) { + case PSYC_PARSE_LIST_END: + case PSYC_PARSE_LIST_ELEM: + if (verbose) + printf("|%.*s\n", (int)elem.length, elem.data); + break; + default: + printf("Error while parsing list: %i\n", ret); + return 1; + } - psyc_parse_list_state_init(&listState); - psyc_parse_list_buffer_set(&listState, PSYC_S2ARG(value)); - - while ((ret = psyc_parse_list(&listState, &elem))) - { - switch (ret) - { - case PSYC_PARSE_LIST_END: - case PSYC_PARSE_LIST_ELEM: - if (verbose) - printf("|%.*s\n", (int)elem.length, elem.data); - break; - default: - printf("Error while parsing list: %i\n", ret); - return 1; - } - - if (ret == PSYC_PARSE_LIST_END) - { - if (verbose) - printf(">> LIST END\n"); - break; - } - } - } - break; - case PSYC_PARSE_COMPLETE: - // printf("Done parsing.\n"); - ret = 0; - continue; - case PSYC_PARSE_INSUFFICIENT: - printf("Insufficient data.\n"); - return 1; - default: - printf("Error while parsing: %i\n", ret); - return 1; + if (ret == PSYC_PARSE_LIST_END) { + if (verbose) + printf(">> LIST END\n"); + break; + } } + } + break; + case PSYC_PARSE_COMPLETE: + // printf("Done parsing.\n"); + ret = 0; + continue; + case PSYC_PARSE_INSUFFICIENT: + printf("Insufficient data.\n"); + return 1; + default: + printf("Error while parsing: %i\n", ret); + return 1; } - while (ret); + } + while (ret); - return 0; + return 0; } diff --git a/test/test_psyc.c b/test/test_psyc.c index fd37d56..18bfe9c 100644 --- a/test/test_psyc.c +++ b/test/test_psyc.c @@ -31,323 +31,333 @@ PsycModifier entity[NUM_PARSERS][ENTITY_LINES]; int contbytes, exit_code; -static inline -void resetString (PsycString *s, uint8_t freeptr); +static inline void +resetString (PsycString *s, uint8_t freeptr); // initialize parser & packet variables -void test_init (int i) { - // reset parser state & packet - psyc_parse_state_init(&parsers[i], routing_only ? - PSYC_PARSE_ROUTING_ONLY : PSYC_PARSE_ALL); +void +test_init (int i) +{ + // reset parser state & packet + psyc_parse_state_init(&parsers[i], + routing_only ? PSYC_PARSE_ROUTING_ONLY : PSYC_PARSE_ALL); - memset(&packets[i], 0, sizeof(PsycPacket)); - memset(&routing[i], 0, sizeof(PsycModifier) * ROUTING_LINES); - memset(&entity[i], 0, sizeof(PsycModifier) * ENTITY_LINES); - packets[i].routing.modifiers = routing[i]; - packets[i].entity.modifiers = entity[i]; + memset(&packets[i], 0, sizeof(PsycPacket)); + memset(&routing[i], 0, sizeof(PsycModifier) * ROUTING_LINES); + memset(&entity[i], 0, sizeof(PsycModifier) * ENTITY_LINES); + packets[i].routing.modifiers = routing[i]; + packets[i].entity.modifiers = entity[i]; } // parse & render input -int test_input (int i, char *recvbuf, size_t nbytes) { - int j, ret, retl, r; - char sendbuf[SEND_BUF_SIZE]; - char *parsebuf = recvbuf - contbytes; - /* We have a buffer with pointers pointing to various parts of it: - * *contbuf-vv - * buffer: [ ccrrrr] - * *recvbuf---^^^^ - * *parsebuf-^^^^^^ - * - * New data is in recvbuf, if it contains an incomplete packet then remaining - * unparsed data is copied to contbuf that will be parsed during the next call - * to this function together with the new data. - */ - - PsycParseState *parser = &parsers[i]; - PsycPacket *packet = &packets[i]; - - char oper; - PsycString name, value, elem; - PsycString *pname = NULL, *pvalue = NULL; - PsycModifier *mod = NULL; - PsycParseListState listState; - size_t len; - - // Set buffer with data for the parser. - psyc_parse_buffer_set(parser, parsebuf, contbytes + nbytes); - contbytes = 0; - oper = 0; - name.length = 0; - value.length = 0; - - do { - if (verbose >= 3) - printf("\n# buffer = [%.*s]\n# part = %d\n", (int)parser->buffer.length, parser->buffer.data, parser->part); - // Parse the next part of the packet (a routing/entity modifier or the body) - ret = exit_code = psyc_parse(parser, &oper, &name, &value); - if (verbose >= 2) - printf("# ret = %d\n", ret); - - switch (ret) { - case PSYC_PARSE_ROUTING: - assert(packet->routing.lines < ROUTING_LINES); - mod = &(packet->routing.modifiers[packet->routing.lines]); - pname = &mod->name; - pvalue = &mod->value; - mod->flag = PSYC_MODIFIER_ROUTING; - packet->routing.lines++; - break; - - case PSYC_PARSE_STATE_RESYNC: - case PSYC_PARSE_STATE_RESET: - packet->stateop = oper; - break; - - case PSYC_PARSE_ENTITY_START: - case PSYC_PARSE_ENTITY_CONT: - case PSYC_PARSE_ENTITY_END: - case PSYC_PARSE_ENTITY: - assert(packet->entity.lines < ENTITY_LINES); - mod = &(packet->entity.modifiers[packet->entity.lines]); - pname = &mod->name; - pvalue = &mod->value; - - if (ret == PSYC_PARSE_ENTITY || ret == PSYC_PARSE_ENTITY_END) { - packet->entity.lines++; - mod->flag = psyc_parse_value_length_found(parser) ? - PSYC_MODIFIER_NEED_LENGTH : PSYC_MODIFIER_NO_LENGTH; - } - break; - - case PSYC_PARSE_BODY_START: - case PSYC_PARSE_BODY_CONT: - case PSYC_PARSE_BODY_END: - case PSYC_PARSE_BODY: - pname = &(packet->method); - pvalue = &(packet->data); - break; - - case PSYC_PARSE_COMPLETE: - if (verbose) - printf("# Done parsing.\n"); - else if (progress) - r = write(1, ".", 1); - if ((filename && !multiple) || (!filename && single)) - ret = -1; - - if (!no_render) { - packet->flag = psyc_parse_content_length_found(parser) ? - PSYC_PACKET_NEED_LENGTH : PSYC_PACKET_NO_LENGTH; - - if (routing_only) { - packet->content = packet->data; - resetString(&(packet->data), 0); - } - - psyc_packet_length_set(packet); - - if (psyc_render(packet, sendbuf, SEND_BUF_SIZE) == PSYC_RENDER_SUCCESS) { - if (!quiet) { - if (filename && write(1, sendbuf, packet->length) == -1) { - perror("write"); - ret = -1; - } else if (!filename && send(i, sendbuf, packet->length, 0) == -1) { - perror("send"); - ret = -1; - } - } - } else { - printf("# Render error"); - ret = -1; - } - } - - // reset packet - packet->routingLength = 0; - packet->contentLength = 0; - packet->length = 0; - packet->flag = 0; - - for (j = 0; j < packet->routing.lines; j++) { - resetString(&(packet->routing.modifiers[j].name), 1); - resetString(&(packet->routing.modifiers[j].value), 1); - } - packet->routing.lines = 0; - - if (routing_only) { - resetString(&(packet->content), 1); - } else { - for (j = 0; j < packet->entity.lines; j++) { - resetString(&(packet->entity.modifiers[j].name), 1); - resetString(&(packet->entity.modifiers[j].value), 1); - } - packet->entity.lines = 0; - - resetString(&(packet->method), 1); - resetString(&(packet->data), 1); - } - - break; - - case PSYC_PARSE_INSUFFICIENT: - if (verbose >= 2) - printf("# Insufficient data.\n"); - - contbytes = psyc_parse_remaining_length(parser); - - if (contbytes > 0) { // copy end of parsebuf before start of recvbuf - if (verbose >= 3) - printf("# remaining = [%.*s]\n", (int)contbytes, psyc_parse_remaining_buffer(parser)); - assert(contbytes <= CONT_BUF_SIZE); // make sure it's still in the buffer - memmove(recvbuf - contbytes, psyc_parse_remaining_buffer(parser), contbytes); - } - ret = 0; - break; - - default: - printf("# Error while parsing: %i\n", ret); - ret = -1; - } - - switch (ret) { - case PSYC_PARSE_ENTITY_START: - case PSYC_PARSE_ENTITY_CONT: - case PSYC_PARSE_BODY_START: - case PSYC_PARSE_BODY_CONT: - ret = 0; - case PSYC_PARSE_ENTITY: - case PSYC_PARSE_ENTITY_END: - case PSYC_PARSE_ROUTING: - case PSYC_PARSE_BODY: - case PSYC_PARSE_BODY_END: - if (oper) { - mod->oper = oper; - if (verbose >= 2) - printf("%c", oper); - } - - if (name.length) { - pname->data = malloc(name.length); - pname->length = name.length; - - assert(pname->data != NULL); - memcpy((void*)pname->data, name.data, name.length); - name.length = 0; - - if (verbose >= 2) - printf("%.*s = ", (int)pname->length, pname->data); - } - - if (value.length) { - if (!pvalue->length) { - if (psyc_parse_value_length_found(parser)) - len = psyc_parse_value_length(parser); - else - len = value.length; - pvalue->data = malloc(len); - } - assert(pvalue->data != NULL); - memcpy((void*)pvalue->data + pvalue->length, value.data, value.length); - pvalue->length += value.length; - value.length = 0; - - if (verbose >= 2) { - printf("[%.*s]", (int)pvalue->length, pvalue->data); - if (parser->valueLength > pvalue->length) - printf("..."); - printf("\n"); - } - } - else if (verbose) - printf("\n"); - - if (verbose >= 3) - printf("\t\t\t\t\t\t\t\t# n:%ld v:%ld c:%ld r:%ld\n", - pname->length, pvalue->length, - parser->contentParsed, parser->routingLength); - } - - switch (ret) { - case PSYC_PARSE_ROUTING: - case PSYC_PARSE_ENTITY: - case PSYC_PARSE_ENTITY_END: - oper = 0; - name.length = 0; - value.length = 0; - - if (psyc_var_is_list(PSYC_S2ARG(*pname))) { - if (verbose >= 2) - printf("## LIST START\n"); - - psyc_parse_list_state_init(&listState); - psyc_parse_list_buffer_set(&listState, PSYC_S2ARG(*pvalue)); - - do { - retl = psyc_parse_list(&listState, &elem); - switch (retl) { - case PSYC_PARSE_LIST_END: - retl = 0; - case PSYC_PARSE_LIST_ELEM: - if (verbose >= 2) { - printf("|%.*s\n", (int)elem.length, elem.data); - if (ret == PSYC_PARSE_LIST_END) - printf("## LIST END"); - } - break; - - default: - printf("# Error while parsing list: %i\n", retl); - ret = retl = -1; - } - } - while (retl > 0); - } - } - } - while (ret > 0); - - if (progress) - r = write(1, " ", 1); - - return ret; -} - -static inline -void resetString (PsycString *s, uint8_t freeptr) +int +test_input (int i, char *recvbuf, size_t nbytes) { - if (freeptr && s->length) - free((void*)s->data); + int j, ret, retl, r; + char sendbuf[SEND_BUF_SIZE]; + char *parsebuf = recvbuf - contbytes; + /* We have a buffer with pointers pointing to various parts of it: + * *contbuf-vv + * buffer: [ ccrrrr] + * *recvbuf---^^^^ + * *parsebuf-^^^^^^ + * + * New data is in recvbuf, if it contains an incomplete packet then remaining + * unparsed data is copied to contbuf that will be parsed during the next call + * to this function together with the new data. + */ - s->data = NULL; - s->length = 0; -} + PsycParseState *parser = &parsers[i]; + PsycPacket *packet = &packets[i]; -int main (int argc, char **argv) { - int c; - while ((c = getopt (argc, argv, "f:p:b:c:mnqrsvPSh")) != -1) { - switch (c) { - CASE_f CASE_p CASE_b CASE_c - CASE_m CASE_n CASE_q CASE_r - CASE_s CASE_v CASE_S CASE_P - case 'h': - printf( - HELP_FILE("test_psyc", "mnqrSsvP") - HELP_PORT("test_psyc", "nqrsvP") - HELP_f HELP_p HELP_b HELP_c - HELP_m HELP_n HELP_r - HELP_q HELP_S HELP_s - HELP_v HELP_P HELP_h, - port, RECV_BUF_SIZE); - exit(0); - case '?': exit(-1); - default: abort(); + char oper; + PsycString name, value, elem; + PsycString *pname = NULL, *pvalue = NULL; + PsycModifier *mod = NULL; + PsycParseListState listState; + size_t len; + + // Set buffer with data for the parser. + psyc_parse_buffer_set(parser, parsebuf, contbytes + nbytes); + contbytes = 0; + oper = 0; + name.length = 0; + value.length = 0; + + do { + if (verbose >= 3) + printf("\n# buffer = [%.*s]\n# part = %d\n", + (int)parser->buffer.length, parser->buffer.data, parser->part); + // Parse the next part of the packet (a routing/entity modifier or the body) + ret = exit_code = psyc_parse(parser, &oper, &name, &value); + if (verbose >= 2) + printf("# ret = %d\n", ret); + + switch (ret) { + case PSYC_PARSE_ROUTING: + assert(packet->routing.lines < ROUTING_LINES); + mod = &(packet->routing.modifiers[packet->routing.lines]); + pname = &mod->name; + pvalue = &mod->value; + mod->flag = PSYC_MODIFIER_ROUTING; + packet->routing.lines++; + break; + + case PSYC_PARSE_STATE_RESYNC: + case PSYC_PARSE_STATE_RESET: + packet->stateop = oper; + break; + + case PSYC_PARSE_ENTITY_START: + case PSYC_PARSE_ENTITY_CONT: + case PSYC_PARSE_ENTITY_END: + case PSYC_PARSE_ENTITY: + assert(packet->entity.lines < ENTITY_LINES); + mod = &(packet->entity.modifiers[packet->entity.lines]); + pname = &mod->name; + pvalue = &mod->value; + + if (ret == PSYC_PARSE_ENTITY || ret == PSYC_PARSE_ENTITY_END) { + packet->entity.lines++; + mod->flag = psyc_parse_value_length_found(parser) ? + PSYC_MODIFIER_NEED_LENGTH : PSYC_MODIFIER_NO_LENGTH; + } + break; + + case PSYC_PARSE_BODY_START: + case PSYC_PARSE_BODY_CONT: + case PSYC_PARSE_BODY_END: + case PSYC_PARSE_BODY: + pname = &(packet->method); + pvalue = &(packet->data); + break; + + case PSYC_PARSE_COMPLETE: + if (verbose) + printf("# Done parsing.\n"); + else if (progress) + r = write(1, ".", 1); + if ((filename && !multiple) || (!filename && single)) + ret = -1; + + if (!no_render) { + packet->flag = psyc_parse_content_length_found(parser) ? + PSYC_PACKET_NEED_LENGTH : PSYC_PACKET_NO_LENGTH; + + if (routing_only) { + packet->content = packet->data; + resetString(&(packet->data), 0); } + + psyc_packet_length_set(packet); + + if (PSYC_RENDER_SUCCESS == psyc_render(packet, sendbuf, + SEND_BUF_SIZE)) { + if (!quiet) { + if (filename && write(1, sendbuf, packet->length) == -1) { + perror("write"); + ret = -1; + } else if (!filename && -1 == send(i, sendbuf, + packet->length, 0)) { + perror("send"); + ret = -1; + } + } + } else { + printf("# Render error"); + ret = -1; + } + } + + // reset packet + packet->routingLength = 0; + packet->contentLength = 0; + packet->length = 0; + packet->flag = 0; + + for (j = 0; j < packet->routing.lines; j++) { + resetString(&(packet->routing.modifiers[j].name), 1); + resetString(&(packet->routing.modifiers[j].value), 1); + } + packet->routing.lines = 0; + + if (routing_only) { + resetString(&(packet->content), 1); + } else { + for (j = 0; j < packet->entity.lines; j++) { + resetString(&(packet->entity.modifiers[j].name), 1); + resetString(&(packet->entity.modifiers[j].value), 1); + } + packet->entity.lines = 0; + + resetString(&(packet->method), 1); + resetString(&(packet->data), 1); + } + + break; + + case PSYC_PARSE_INSUFFICIENT: + if (verbose >= 2) + printf("# Insufficient data.\n"); + + contbytes = psyc_parse_remaining_length(parser); + + if (contbytes > 0) { // copy end of parsebuf before start of recvbuf + if (verbose >= 3) + printf("# remaining = [%.*s]\n", + (int)contbytes, psyc_parse_remaining_buffer(parser)); + assert(contbytes <= CONT_BUF_SIZE); // make sure it fits in the buffer + memmove(recvbuf - contbytes, + psyc_parse_remaining_buffer(parser), contbytes); + } + ret = 0; + break; + + default: + printf("# Error while parsing: %i\n", ret); + ret = -1; } - if (filename) - test_file(filename, count, recv_buf_size); - else - test_server(port, count, recv_buf_size); + switch (ret) { + case PSYC_PARSE_ENTITY_START: + case PSYC_PARSE_ENTITY_CONT: + case PSYC_PARSE_BODY_START: + case PSYC_PARSE_BODY_CONT: + ret = 0; + case PSYC_PARSE_ENTITY: + case PSYC_PARSE_ENTITY_END: + case PSYC_PARSE_ROUTING: + case PSYC_PARSE_BODY: + case PSYC_PARSE_BODY_END: + if (oper) { + mod->oper = oper; + if (verbose >= 2) + printf("%c", oper); + } - return exit_code; + if (name.length) { + pname->data = malloc(name.length); + pname->length = name.length; + + assert(pname->data != NULL); + memcpy((void*)pname->data, name.data, name.length); + name.length = 0; + + if (verbose >= 2) + printf("%.*s = ", (int)pname->length, pname->data); + } + + if (value.length) { + if (!pvalue->length) { + if (psyc_parse_value_length_found(parser)) + len = psyc_parse_value_length(parser); + else + len = value.length; + pvalue->data = malloc(len); + } + assert(pvalue->data != NULL); + memcpy((void*)pvalue->data + pvalue->length, value.data, value.length); + pvalue->length += value.length; + value.length = 0; + + if (verbose >= 2) { + printf("[%.*s]", (int)pvalue->length, pvalue->data); + if (parser->valueLength > pvalue->length) + printf("..."); + printf("\n"); + } + } + else if (verbose) + printf("\n"); + + if (verbose >= 3) + printf("\t\t\t\t\t\t\t\t# n:%ld v:%ld c:%ld r:%ld\n", + pname->length, pvalue->length, + parser->contentParsed, parser->routingLength); + } + + switch (ret) { + case PSYC_PARSE_ROUTING: + case PSYC_PARSE_ENTITY: + case PSYC_PARSE_ENTITY_END: + oper = 0; + name.length = 0; + value.length = 0; + + if (psyc_var_is_list(PSYC_S2ARG(*pname))) { + if (verbose >= 2) + printf("## LIST START\n"); + + psyc_parse_list_state_init(&listState); + psyc_parse_list_buffer_set(&listState, PSYC_S2ARG(*pvalue)); + + do { + retl = psyc_parse_list(&listState, &elem); + switch (retl) { + case PSYC_PARSE_LIST_END: + retl = 0; + case PSYC_PARSE_LIST_ELEM: + if (verbose >= 2) { + printf("|%.*s\n", (int)elem.length, elem.data); + if (ret == PSYC_PARSE_LIST_END) + printf("## LIST END"); + } + break; + + default: + printf("# Error while parsing list: %i\n", retl); + ret = retl = -1; + } + } + while (retl > 0); + } + } + } + while (ret > 0); + + if (progress) + r = write(1, " ", 1); + + return ret; +} + +static inline void +resetString (PsycString *s, uint8_t freeptr) +{ + if (freeptr && s->length) + free((void*)s->data); + + s->data = NULL; + s->length = 0; +} + +int +main (int argc, char **argv) +{ + int c; + while ((c = getopt (argc, argv, "f:p:b:c:mnqrsvPSh")) != -1) { + switch (c) { + CASE_f CASE_p CASE_b CASE_c + CASE_m CASE_n CASE_q CASE_r + CASE_s CASE_v CASE_S CASE_P + case 'h': + printf(HELP_FILE("test_psyc", "mnqrSsvP") + HELP_PORT("test_psyc", "nqrsvP") + HELP_f HELP_p HELP_b HELP_c + HELP_m HELP_n HELP_r + HELP_q HELP_S HELP_s + HELP_v HELP_P HELP_h, + port, RECV_BUF_SIZE); + exit(0); + case '?': exit(-1); + default: abort(); + } + } + + if (filename) + test_file(filename, count, recv_buf_size); + else + test_server(port, count, recv_buf_size); + + return exit_code; } diff --git a/test/test_psyc_speed.c b/test/test_psyc_speed.c index d1012db..e24cb67 100644 --- a/test/test_psyc_speed.c +++ b/test/test_psyc_speed.c @@ -25,48 +25,52 @@ size_t count = 1, recv_buf_size; PsycParseState parser; -void test_init (int i) { - psyc_parse_state_init(&parser, routing_only ? - PSYC_PARSE_ROUTING_ONLY : PSYC_PARSE_ALL); +void +test_init (int i) +{ + psyc_parse_state_init(&parser, routing_only + ? PSYC_PARSE_ROUTING_ONLY : PSYC_PARSE_ALL); } -int test_input (int i, char *recvbuf, size_t nbytes) { - char oper; - PsycString name, value; - int ret; +int +test_input (int i, char *recvbuf, size_t nbytes) +{ + char oper; + PsycString name, value; + int ret; - psyc_parse_buffer_set(&parser, recvbuf, nbytes); + psyc_parse_buffer_set(&parser, recvbuf, nbytes); - for (;;) { - ret = psyc_parse(&parser, &oper, &name, &value); - if (ret == PSYC_PARSE_COMPLETE || ret < 0) - return -1; + for (;;) { + ret = psyc_parse(&parser, &oper, &name, &value); + if (ret == PSYC_PARSE_COMPLETE || ret < 0) + return -1; + } +} + +int +main (int argc, char **argv) +{ + int c; + while ((c = getopt (argc, argv, "f:p:b:c:rsh")) != -1) { + switch (c) { + CASE_f CASE_p CASE_b CASE_c CASE_r CASE_s + case 'h': + printf(HELP_FILE("test_psyc_speed", "rs") + HELP_PORT("test_psyc_speed", "rs") + HELP_f HELP_p HELP_b HELP_c + HELP_r HELP_s HELP_h, + port, RECV_BUF_SIZE); + exit(0); + case '?': exit(-1); + default: abort(); } -} - -int main (int argc, char **argv) { - int c; - while ((c = getopt (argc, argv, "f:p:b:c:rsh")) != -1) { - switch (c) { - CASE_f CASE_p CASE_b CASE_c - CASE_r CASE_s - case 'h': - printf( - HELP_FILE("test_psyc_speed", "rs") - HELP_PORT("test_psyc_speed", "rs") - HELP_f HELP_p HELP_b HELP_c - HELP_r HELP_s HELP_h, - port, RECV_BUF_SIZE); - exit(0); - case '?': exit(-1); - default: abort(); - } - } - - if (filename) - test_file(filename, count, recv_buf_size); - else - test_server(port, count, recv_buf_size); - - return 0; + } + + if (filename) + test_file(filename, count, recv_buf_size); + else + test_server(port, count, recv_buf_size); + + return 0; } diff --git a/test/test_render.c b/test/test_render.c index 58f6036..506b384 100644 --- a/test/test_render.c +++ b/test/test_render.c @@ -7,105 +7,111 @@ #define myUNI "psyc://10.100.1000/~ludwig" /* example renderer generating a presence packet */ -int testPresence (const char *avail, int availlen, - const char *desc, int desclen, - const char *rendered, uint8_t verbose) +int +testPresence (const char *avail, int availlen, + const char *desc, int desclen, + const char *rendered, uint8_t verbose) { - PsycModifier routing[1]; - psyc_modifier_init(&routing[0], PSYC_OPERATOR_SET, - PSYC_C2ARG("_context"), - PSYC_C2ARG(myUNI), PSYC_MODIFIER_ROUTING); + PsycModifier routing[1]; + psyc_modifier_init(&routing[0], PSYC_OPERATOR_SET, + PSYC_C2ARG("_context"), + PSYC_C2ARG(myUNI), PSYC_MODIFIER_ROUTING); - PsycModifier entity[2]; - // presence is to be assigned permanently in distributed state - psyc_modifier_init(&entity[0], PSYC_OPERATOR_ASSIGN, - PSYC_C2ARG("_degree_availability"), - avail, availlen, PSYC_MODIFIER_CHECK_LENGTH); - psyc_modifier_init(&entity[1], PSYC_OPERATOR_ASSIGN, - PSYC_C2ARG("_description_presence"), - desc, desclen, PSYC_MODIFIER_CHECK_LENGTH); + PsycModifier entity[2]; + // presence is to be assigned permanently in distributed state + psyc_modifier_init(&entity[0], PSYC_OPERATOR_ASSIGN, + PSYC_C2ARG("_degree_availability"), + avail, availlen, PSYC_MODIFIER_CHECK_LENGTH); + psyc_modifier_init(&entity[1], PSYC_OPERATOR_ASSIGN, + PSYC_C2ARG("_description_presence"), + desc, desclen, PSYC_MODIFIER_CHECK_LENGTH); - PsycPacket packet; - psyc_packet_init(&packet, routing, PSYC_NUM_ELEM(routing), - entity, PSYC_NUM_ELEM(entity), - PSYC_C2ARG("_notice_presence"), - NULL, 0, - PSYC_STATE_NOOP, - PSYC_PACKET_CHECK_LENGTH); + PsycPacket packet; + psyc_packet_init(&packet, routing, PSYC_NUM_ELEM(routing), + entity, PSYC_NUM_ELEM(entity), + PSYC_C2ARG("_notice_presence"), + NULL, 0, + PSYC_STATE_NOOP, + PSYC_PACKET_CHECK_LENGTH); - char buffer[512]; - psyc_render(&packet, buffer, sizeof(buffer)); - if (verbose) - printf("%.*s\n", (int)packet.length, buffer); - return strncmp(rendered, buffer, packet.length); + char buffer[512]; + psyc_render(&packet, buffer, sizeof(buffer)); + if (verbose) + printf("%.*s\n", (int)packet.length, buffer); + return strncmp(rendered, buffer, packet.length); } -int testList (const char *rendered, uint8_t verbose) +int +testList (const char *rendered, uint8_t verbose) { - PsycModifier routing[2]; - psyc_modifier_init(&routing[0], PSYC_OPERATOR_SET, - PSYC_C2ARG("_source"), - PSYC_C2ARG(myUNI), PSYC_MODIFIER_ROUTING); - psyc_modifier_init(&routing[1], PSYC_OPERATOR_SET, - PSYC_C2ARG("_context"), - PSYC_C2ARG(myUNI), PSYC_MODIFIER_ROUTING); + PsycModifier routing[2]; + psyc_modifier_init(&routing[0], PSYC_OPERATOR_SET, + PSYC_C2ARG("_source"), + PSYC_C2ARG(myUNI), PSYC_MODIFIER_ROUTING); + psyc_modifier_init(&routing[1], PSYC_OPERATOR_SET, + PSYC_C2ARG("_context"), + PSYC_C2ARG(myUNI), PSYC_MODIFIER_ROUTING); - PsycString elems_text[] = { - PSYC_C2STR("foo"), - PSYC_C2STR("bar"), - PSYC_C2STR("baz"), - }; + PsycString elems_text[] = { + PSYC_C2STR("foo"), + PSYC_C2STR("bar"), + PSYC_C2STR("baz"), + }; - PsycString elems_bin[] = { - PSYC_C2STR("foo"), - PSYC_C2STR("b|r"), - PSYC_C2STR("baz\nqux"), - }; + PsycString elems_bin[] = { + PSYC_C2STR("foo"), + PSYC_C2STR("b|r"), + PSYC_C2STR("baz\nqux"), + }; - PsycList list_text, list_bin; - psyc_list_init(&list_text, elems_text, PSYC_NUM_ELEM(elems_text), PSYC_LIST_CHECK_LENGTH); - psyc_list_init(&list_bin, elems_bin, PSYC_NUM_ELEM(elems_bin), PSYC_LIST_CHECK_LENGTH); + PsycList list_text, list_bin; + psyc_list_init(&list_text, elems_text, + PSYC_NUM_ELEM(elems_text), PSYC_LIST_CHECK_LENGTH); + psyc_list_init(&list_bin, elems_bin, + PSYC_NUM_ELEM(elems_bin), PSYC_LIST_CHECK_LENGTH); - char buf_text[32], buf_bin[32]; - psyc_render_list(&list_text, buf_text, sizeof(buf_text)); - psyc_render_list(&list_bin, buf_bin, sizeof(buf_bin)); + char buf_text[32], buf_bin[32]; + psyc_render_list(&list_text, buf_text, sizeof(buf_text)); + psyc_render_list(&list_bin, buf_bin, sizeof(buf_bin)); - PsycModifier entity[2]; - psyc_modifier_init(&entity[0], PSYC_OPERATOR_SET, - PSYC_C2ARG("_list_text"), - buf_text, list_text.length, list_text.flag); - psyc_modifier_init(&entity[1], PSYC_OPERATOR_SET, - PSYC_C2ARG("_list_binary"), - buf_bin, list_bin.length, list_bin.flag); + PsycModifier entity[2]; + psyc_modifier_init(&entity[0], PSYC_OPERATOR_SET, + PSYC_C2ARG("_list_text"), + buf_text, list_text.length, list_text.flag); + psyc_modifier_init(&entity[1], PSYC_OPERATOR_SET, + PSYC_C2ARG("_list_binary"), + buf_bin, list_bin.length, list_bin.flag); - PsycPacket packet; - psyc_packet_init(&packet, routing, PSYC_NUM_ELEM(routing), - entity, PSYC_NUM_ELEM(entity), - PSYC_C2ARG("_test_list"), - PSYC_C2ARG("list test"), - PSYC_STATE_NOOP, - PSYC_PACKET_CHECK_LENGTH); + PsycPacket packet; + psyc_packet_init(&packet, routing, PSYC_NUM_ELEM(routing), + entity, PSYC_NUM_ELEM(entity), + PSYC_C2ARG("_test_list"), + PSYC_C2ARG("list test"), + PSYC_STATE_NOOP, + PSYC_PACKET_CHECK_LENGTH); - char buffer[512]; - psyc_render(&packet, buffer, sizeof(buffer)); - if (verbose) - printf("%.*s\n", (int)packet.length, buffer); - return strncmp(rendered, buffer, packet.length); + char buffer[512]; + psyc_render(&packet, buffer, sizeof(buffer)); + if (verbose) + printf("%.*s\n", (int)packet.length, buffer); + return strncmp(rendered, buffer, packet.length); } -int main (int argc, char **argv) { - uint8_t verbose = argc > 1; +int +main (int argc, char **argv) +{ + uint8_t verbose = argc > 1; - if (testPresence(PSYC_C2ARG("_here"), PSYC_C2ARG("I'm omnipresent right now"), "\ + if (testPresence(PSYC_C2ARG("_here"), PSYC_C2ARG("I'm omnipresent right now"), "\ :_context\t" myUNI "\n\ \n\ =_degree_availability\t_here\n\ =_description_presence\tI'm omnipresent right now\n\ _notice_presence\n\ |\n", verbose)) - return 1; + return 1; - if (testList("\ + if (testList("\ :_source psyc://10.100.1000/~ludwig\n\ :_context psyc://10.100.1000/~ludwig\n\ 85\n\ @@ -115,9 +121,9 @@ qux\n\ _test_list\n\ list test\n\ |\n", verbose)) - return 2; + return 2; - puts("psyc_render passed all tests."); + puts("psyc_render passed all tests."); - return 0; + return 0; } diff --git a/test/test_strlen.c b/test/test_strlen.c index b2d5bf4..2686aba 100644 --- a/test/test_strlen.c +++ b/test/test_strlen.c @@ -21,44 +21,49 @@ size_t count = 1, recv_buf_size; int exit_code; -void test_init (int i) { +void +test_init (int i) +{ + } -int test_input (int i, char *recvbuf, size_t nbytes) { - size_t len = strnlen(recvbuf, nbytes); +int +test_input (int i, char *recvbuf, size_t nbytes) +{ + size_t len = strnlen(recvbuf, nbytes); - if (!len) { - printf("Empty string\n"); - return -1; + if (!len) { + printf("Empty string\n"); + return -1; + } + + return 0; +} + +int +main (int argc, char **argv) +{ + int c; + + while ((c = getopt (argc, argv, "f:p:b:c:sh")) != -1) { + switch (c) { + CASE_f CASE_p CASE_b CASE_c CASE_s + case 'h': + printf(HELP_FILE("test_strlen", "s") + HELP_PORT("test_strlen", "s") + HELP_f HELP_p HELP_b HELP_c + HELP_s HELP_h, + port, RECV_BUF_SIZE); + exit(0); + case '?': exit(-1); + default: abort(); } + } - return 0; -} - -int main (int argc, char **argv) { - int c; - - while ((c = getopt (argc, argv, "f:p:b:c:sh")) != -1) { - switch (c) { - CASE_f CASE_p CASE_b CASE_c - CASE_s - case 'h': - printf( - HELP_FILE("test_strlen", "s") - HELP_PORT("test_strlen", "s") - HELP_f HELP_p HELP_b HELP_c - HELP_s HELP_h, - port, RECV_BUF_SIZE); - exit(0); - case '?': exit(-1); - default: abort(); - } - } - - if (filename) - test_file(filename, count, recv_buf_size); - else - test_server(port, count, recv_buf_size); - - return exit_code; + if (filename) + test_file(filename, count, recv_buf_size); + else + test_server(port, count, recv_buf_size); + + return exit_code; } diff --git a/test/test_text.c b/test/test_text.c index d776e3b..40716bb 100644 --- a/test/test_text.c +++ b/test/test_text.c @@ -7,95 +7,99 @@ uint8_t verbose; -PsycTextValueRC getValueFooBar (const char *name, size_t len, PsycString *value, void *extra) +PsycTextValueRC +getValueFooBar (const char *name, size_t len, PsycString *value, void *extra) { - if (verbose) - printf("> getValue: %.*s\n", (int)len, name); - value->data = "Foo Bar"; - value->length = 7; - return PSYC_TEXT_VALUE_FOUND; + if (verbose) + printf("> getValue: %.*s\n", (int)len, name); + value->data = "Foo Bar"; + value->length = 7; + return PSYC_TEXT_VALUE_FOUND; } -PsycTextValueRC getValueEmpty (const char *name, size_t len, PsycString *value, void *extra) +PsycTextValueRC +getValueEmpty (const char *name, size_t len, PsycString *value, void *extra) { - if (verbose) - printf("> getValue: %.*s\n", (int)len, name); - value->data = ""; - value->length = 0; - return PSYC_TEXT_VALUE_FOUND; + if (verbose) + printf("> getValue: %.*s\n", (int)len, name); + value->data = ""; + value->length = 0; + return PSYC_TEXT_VALUE_FOUND; } -PsycTextValueRC getValueNotFound (const char *name, size_t len, PsycString *value, void *extra) +PsycTextValueRC +getValueNotFound (const char *name, size_t len, PsycString *value, void *extra) { - if (verbose) - printf("> getValue: %.*s\n", (int)len, name); - return PSYC_TEXT_VALUE_NOT_FOUND; + if (verbose) + printf("> getValue: %.*s\n", (int)len, name); + return PSYC_TEXT_VALUE_NOT_FOUND; } -int testText (char *template, size_t tmplen, char *buffer, size_t buflen, PsycString *result, PsycTextCB getValue) +int +testText (char *template, size_t tmplen, char *buffer, size_t buflen, + PsycString *result, PsycTextCB getValue) { - PsycTextState state; - size_t length = 0; - PsycTextRC ret; + PsycTextState state; + size_t length = 0; + PsycTextRC ret; - psyc_text_state_init(&state, template, tmplen, buffer, buflen); - do - { - ret = psyc_text(&state, getValue, NULL); - length += psyc_text_bytes_written(&state); - switch (ret) - { - case PSYC_TEXT_INCOMPLETE: - if (verbose) - printf("# %.*s...\n", (int)length, buffer); - psyc_text_buffer_set(&state, buffer + length, BUFSIZE - length); - break; - case PSYC_TEXT_COMPLETE: - if (verbose) - printf("%.*s\n", (int)length, buffer); - result->length = length; - result->data = buffer; - return ret; - case PSYC_TEXT_NO_SUBST: - if (verbose) - printf("%.*s\n", (int)tmplen, template); - return ret; - } + psyc_text_state_init(&state, template, tmplen, buffer, buflen); + do { + ret = psyc_text(&state, getValue, NULL); + length += psyc_text_bytes_written(&state); + switch (ret) { + case PSYC_TEXT_INCOMPLETE: + if (verbose) + printf("# %.*s...\n", (int)length, buffer); + psyc_text_buffer_set(&state, buffer + length, BUFSIZE - length); + break; + case PSYC_TEXT_COMPLETE: + if (verbose) + printf("%.*s\n", (int)length, buffer); + result->length = length; + result->data = buffer; + return ret; + case PSYC_TEXT_NO_SUBST: + if (verbose) + printf("%.*s\n", (int)tmplen, template); + return ret; } - while (ret == PSYC_TEXT_INCOMPLETE); + } + while (ret == PSYC_TEXT_INCOMPLETE); - return -2; // shouldn't be reached + return -2; // shouldn't be reached } -int main(int argc, char **argv) +int +main (int argc, char **argv) { - verbose = argc > 1; - char buffer[BUFSIZE]; - PsycString result; + verbose = argc > 1; + char buffer[BUFSIZE]; + PsycString result; - char *str = "Hello [_foo] & [_bar]!"; - size_t len = strlen(str); - int i; + char *str = "Hello [_foo] & [_bar]!"; + size_t len = strlen(str); + int i; - testText(str, len, buffer, BUFSIZE, &result, &getValueFooBar); + testText(str, len, buffer, BUFSIZE, &result, &getValueFooBar); + if (memcmp(result.data, PSYC_C2ARG("Hello Foo Bar & Foo Bar!"))) + return 1; + + testText(str, len, buffer, BUFSIZE, &result, &getValueEmpty); + if (memcmp(result.data, PSYC_C2ARG("Hello & !"))) + return 2; + + if (PSYC_TEXT_NO_SUBST != testText(str, len, buffer, BUFSIZE, + &result, &getValueNotFound)) + return 3; + + for (i = 1; i < 22; i++) { + testText(str, len, buffer, i, &result, &getValueFooBar); if (memcmp(result.data, PSYC_C2ARG("Hello Foo Bar & Foo Bar!"))) - return 1; + return 10 + i; + } - testText(str, len, buffer, BUFSIZE, &result, &getValueEmpty); - if (memcmp(result.data, PSYC_C2ARG("Hello & !"))) - return 2; + puts("psyc_text passed all tests."); - if (testText(str, len, buffer, BUFSIZE, &result, &getValueNotFound) != PSYC_TEXT_NO_SUBST) - return 3; - - for (i = 1; i < 22; i++) - { - testText(str, len, buffer, i, &result, &getValueFooBar); - if (memcmp(result.data, PSYC_C2ARG("Hello Foo Bar & Foo Bar!"))) - return 10 + i; - } - - puts("psyc_text passed all tests."); - - return 0; + return 0; } diff --git a/test/uniform_parse.c b/test/uniform_parse.c index 97e6c53..805d917 100644 --- a/test/uniform_parse.c +++ b/test/uniform_parse.c @@ -4,51 +4,57 @@ #include void -testUniform (char *str, int ret) { - PsycUniform *uni = malloc(sizeof(PsycUniform)); - memset(uni, 0, sizeof(PsycUniform)); - printf("%s\n", str); - int r = psyc_uniform_parse(uni, str, strlen(str)); +testUniform (char *str, int ret) +{ + PsycUniform *uni = malloc(sizeof(PsycUniform)); + memset(uni, 0, sizeof(PsycUniform)); + printf("%s\n", str); + int r = psyc_uniform_parse(uni, str, strlen(str)); - PP(("[%.*s] : [%.*s] [%.*s] : [%.*s] [%.*s] / [%.*s] # [%.*s]\n[%.*s]\n[%.*s] [%.*s]\n[%.*s]\n\n", - (int)PSYC_S2ARG2(uni->scheme), - (int)PSYC_S2ARG2(uni->slashes), - (int)PSYC_S2ARG2(uni->host), - (int)PSYC_S2ARG2(uni->port), - (int)PSYC_S2ARG2(uni->transport), - (int)PSYC_S2ARG2(uni->resource), - (int)PSYC_S2ARG2(uni->channel), - (int)PSYC_S2ARG2(uni->entity), - (int)PSYC_S2ARG2(uni->root), - (int)PSYC_S2ARG2(uni->nick), - (int)PSYC_S2ARG2(uni->body))); + PP(("[%.*s] : [%.*s] [%.*s] : [%.*s] [%.*s] / " + "[%.*s] # [%.*s]\n[%.*s]\n[%.*s] [%.*s]\n[%.*s]\n\n", + (int)PSYC_S2ARG2(uni->scheme), + (int)PSYC_S2ARG2(uni->slashes), + (int)PSYC_S2ARG2(uni->host), + (int)PSYC_S2ARG2(uni->port), + (int)PSYC_S2ARG2(uni->transport), + (int)PSYC_S2ARG2(uni->resource), + (int)PSYC_S2ARG2(uni->channel), + (int)PSYC_S2ARG2(uni->entity), + (int)PSYC_S2ARG2(uni->root), + (int)PSYC_S2ARG2(uni->nick), + (int)PSYC_S2ARG2(uni->body))); - free(uni); - if (r != ret) { - fprintf(stderr, "ERROR: psyc_uniform_parse returned %d instead of %d\n", r, ret); - exit(1); - } + free(uni); + if (r != ret) { + fprintf(stderr, "ERROR: psyc_uniform_parse returned %d instead of %d\n", + r, ret); + exit(1); + } } -int main () { - testUniform("psyc://foo.tld:4404d/@bar#baz", PSYC_SCHEME_PSYC); - testUniform("psyc://foo:4405/~bar", PSYC_SCHEME_PSYC); - testUniform("psyc://foo:1234", PSYC_SCHEME_PSYC); - testUniform("psyc://foo:1234d", PSYC_SCHEME_PSYC); - testUniform("psyc://foo:-1234", PSYC_SCHEME_PSYC); - testUniform("psyc://foo:-1234d", PSYC_SCHEME_PSYC); - testUniform("psyc://foo/", PSYC_SCHEME_PSYC); - testUniform("psyc://foo", PSYC_SCHEME_PSYC); - testUniform("psyc://1234567890abcdef:g/~foo", PSYC_SCHEME_PSYC); +int +main () +{ + testUniform("psyc://foo.tld:4404d/@bar#baz", PSYC_SCHEME_PSYC); + testUniform("psyc://foo:4405/~bar", PSYC_SCHEME_PSYC); + testUniform("psyc://foo:1234", PSYC_SCHEME_PSYC); + testUniform("psyc://foo:1234d", PSYC_SCHEME_PSYC); + testUniform("psyc://foo:-1234", PSYC_SCHEME_PSYC); + testUniform("psyc://foo:-1234d", PSYC_SCHEME_PSYC); + testUniform("psyc://foo/", PSYC_SCHEME_PSYC); + testUniform("psyc://foo", PSYC_SCHEME_PSYC); + testUniform("psyc://1234567890abcdef:g/~foo", PSYC_SCHEME_PSYC); - testUniform("xmpp:user@host", PSYC_PARSE_UNIFORM_INVALID_SCHEME); - testUniform("psyc:host", PSYC_PARSE_UNIFORM_INVALID_SLASHES); - testUniform("psyc://", PSYC_PARSE_UNIFORM_INVALID_HOST); - testUniform("psyc://:123/", PSYC_PARSE_UNIFORM_INVALID_HOST); - testUniform("psyc://host:/~foo", PSYC_PARSE_UNIFORM_INVALID_PORT); - testUniform("psyc://host:d/~foo", PSYC_PARSE_UNIFORM_INVALID_PORT); - testUniform("psyc://1234567890abcdef:1g/~foo", PSYC_PARSE_UNIFORM_INVALID_TRANSPORT); + testUniform("xmpp:user@host", PSYC_PARSE_UNIFORM_INVALID_SCHEME); + testUniform("psyc:host", PSYC_PARSE_UNIFORM_INVALID_SLASHES); + testUniform("psyc://", PSYC_PARSE_UNIFORM_INVALID_HOST); + testUniform("psyc://:123/", PSYC_PARSE_UNIFORM_INVALID_HOST); + testUniform("psyc://host:/~foo", PSYC_PARSE_UNIFORM_INVALID_PORT); + testUniform("psyc://host:d/~foo", PSYC_PARSE_UNIFORM_INVALID_PORT); + testUniform("psyc://1234567890abcdef:1g/~foo", + PSYC_PARSE_UNIFORM_INVALID_TRANSPORT); - printf("SUCCESS: psyc_uniform_parse passed all tests.\n"); - return 0; + printf("SUCCESS: psyc_uniform_parse passed all tests.\n"); + return 0; } diff --git a/test/var_is_routing.c b/test/var_is_routing.c index bb3ffca..caba355 100644 --- a/test/var_is_routing.c +++ b/test/var_is_routing.c @@ -6,34 +6,32 @@ int main() { #if 0 - const char* vars[] = - { - "_source", - "_source_relay", - "_source_foo", - "_sourcherry", - "_foo", - "bar", - "_", - }; + const char* vars[] = { + "_source", + "_source_relay", + "_source_foo", + "_sourcherry", + "_foo", + "bar", + "_", + }; - int i; - for (i = 0; i < sizeof(vars) / sizeof(*vars); i++) - { - printf(">> %s: %d %d\n", vars[i], sizeof(vars[i]), sizeof(*vars[i])); - printf("%s: %d\n", vars[i], psyc_var_is_routing(vars[i], strlen(vars[i]))); - } + int i; + for (i = 0; i < sizeof(vars) / sizeof(*vars); i++) { + printf(">> %s: %d %d\n", vars[i], sizeof(vars[i]), sizeof(*vars[i])); + printf("%s: %d\n", vars[i], psyc_var_is_routing(vars[i], strlen(vars[i]))); + } #else - unless (psyc_var_is_routing(PSYC_C2ARG("_source"))) return 1; - unless (psyc_var_is_routing(PSYC_C2ARG("_source_relay"))) return 2; - if (psyc_var_is_routing(PSYC_C2ARG("_source_foo"))) return 3; - if (psyc_var_is_routing(PSYC_C2ARG("_sourcherry"))) return 4; - if (psyc_var_is_routing(PSYC_C2ARG("_sour"))) return 5; - if (psyc_var_is_routing(PSYC_C2ARG("_foo"))) return 6; - if (psyc_var_is_routing(PSYC_C2ARG("bar"))) return 7; - if (psyc_var_is_routing(PSYC_C2ARG("_"))) return 8; + unless (psyc_var_is_routing(PSYC_C2ARG("_source"))) return 1; + unless (psyc_var_is_routing(PSYC_C2ARG("_source_relay"))) return 2; + if (psyc_var_is_routing(PSYC_C2ARG("_source_foo"))) return 3; + if (psyc_var_is_routing(PSYC_C2ARG("_sourcherry"))) return 4; + if (psyc_var_is_routing(PSYC_C2ARG("_sour"))) return 5; + if (psyc_var_is_routing(PSYC_C2ARG("_foo"))) return 6; + if (psyc_var_is_routing(PSYC_C2ARG("bar"))) return 7; + if (psyc_var_is_routing(PSYC_C2ARG("_"))) return 8; - puts("psyc_var_is_routing passed all tests."); + puts("psyc_var_is_routing passed all tests."); #endif - return 0; // passed all tests + return 0; // passed all tests } diff --git a/test/var_type.c b/test/var_type.c index b043979..9050398 100644 --- a/test/var_type.c +++ b/test/var_type.c @@ -5,17 +5,17 @@ #include int main() { - unless (psyc_var_type(PSYC_C2ARG("_list"))) return 1; - unless (psyc_var_type(PSYC_C2ARG("_list_foo"))) return 2; - unless (psyc_var_type(PSYC_C2ARG("_color_red"))) return 3; - if (psyc_var_type(PSYC_C2ARG("_last"))) return 4; - if (psyc_var_type(PSYC_C2ARG("_lost_foo"))) return 5; - if (psyc_var_type(PSYC_C2ARG("_colorful"))) return 6; - if (psyc_var_type(PSYC_C2ARG("_foo"))) return 7; - if (psyc_var_type(PSYC_C2ARG("bar"))) return 8; - if (psyc_var_type(PSYC_C2ARG("______"))) return 9; - if (psyc_var_type(PSYC_C2ARG("_"))) return 10; + unless (psyc_var_type(PSYC_C2ARG("_list"))) return 1; + unless (psyc_var_type(PSYC_C2ARG("_list_foo"))) return 2; + unless (psyc_var_type(PSYC_C2ARG("_color_red"))) return 3; + if (psyc_var_type(PSYC_C2ARG("_last"))) return 4; + if (psyc_var_type(PSYC_C2ARG("_lost_foo"))) return 5; + if (psyc_var_type(PSYC_C2ARG("_colorful"))) return 6; + if (psyc_var_type(PSYC_C2ARG("_foo"))) return 7; + if (psyc_var_type(PSYC_C2ARG("bar"))) return 8; + if (psyc_var_type(PSYC_C2ARG("______"))) return 9; + if (psyc_var_type(PSYC_C2ARG("_"))) return 10; - puts("psyc_var_type passed all tests."); - return 0; // passed all tests + puts("psyc_var_type passed all tests."); + return 0; // passed all tests } From f583c90dc339d90d78c35d7b3e080c2a9b7b9c1f Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sat, 12 Nov 2011 11:35:37 +0100 Subject: [PATCH 346/378] indent --- test/test_list.c | 362 +++++++++++++++++++++++++---------------------- 1 file changed, 192 insertions(+), 170 deletions(-) diff --git a/test/test_list.c b/test/test_list.c index 36fb8c5..723a9d9 100644 --- a/test/test_list.c +++ b/test/test_list.c @@ -9,200 +9,222 @@ #define NELEMS 100 -int main (int argc, char **argv) { - uint8_t verbose = argc > 1; - int i, k, n, ret; +int +main (int argc, char **argv) +{ + uint8_t verbose = argc > 1; + int i, k, n, ret; - PsycParseListState listState; - PsycList list_text, list_bin; - PsycString elems_text[NELEMS], elems_bin[NELEMS], elem; - char buf_text[NELEMS * 200], buf_bin[NELEMS * 200], *elems[NELEMS], **elems2 = NULL; + PsycParseListState listState; + PsycList list_text, list_bin; + PsycString elems_text[NELEMS], elems_bin[NELEMS], elem; + char buf_text[NELEMS * 200], buf_bin[NELEMS * 200], *elems[NELEMS], **elems2 = NULL; - struct timeval start, end; + struct timeval start, end; - for (i=0; i 0); - } - gettimeofday(&end, NULL); - //printf("%ld ms\n", (end.tv_sec * 1000000 + end.tv_usec - start.tv_sec * 1000000 - start.tv_usec) / 1000); - printf("%ld us\n", (end.tv_sec * 1000000 + end.tv_usec - start.tv_sec * 1000000 - start.tv_usec)); + printf("parsing text list to elems[]\n"); + gettimeofday(&start, NULL); + for (n = 0; n < NELEMS; n++) { + psyc_parse_list_state_init(&listState); + psyc_parse_list_buffer_set(&listState, buf_text, list_text.length); + i = 0; + do { + ret = psyc_parse_list(&listState, &elem); + switch (ret) { + case PSYC_PARSE_LIST_END: + ret = 0; + case PSYC_PARSE_LIST_ELEM: + if (verbose) + printf("|%d: %.*s... (%ld)\n", i, 10, elem.data, elem.length); + //elems[i] = malloc(elem.length); + //memcpy(&elems[i++], elem.data, elem.length); + break; + default: + printf("# Error while parsing list: %i\n", ret); + ret = -1; + } + } while (ret > 0); + } + gettimeofday(&end, NULL); +// printf("%ld ms\n", (end.tv_sec * 1000000 + end.tv_usec +// - start.tv_sec * 1000000 - start.tv_usec) / 1000); + printf("%ld us\n", (end.tv_sec * 1000000 + end.tv_usec + - start.tv_sec * 1000000 - start.tv_usec)); #endif #if 1 - printf("parsing binary list to elems[]\n"); - gettimeofday(&start, NULL); - for (n = 0; n < NELEMS; n++) { - psyc_parse_list_state_init(&listState); - psyc_parse_list_buffer_set(&listState, buf_bin, list_bin.length); - i = 0; - do { - ret = psyc_parse_list(&listState, &elem); - switch (ret) { - case PSYC_PARSE_LIST_END: - ret = 0; - case PSYC_PARSE_LIST_ELEM: - //if (verbose) printf("|%.*s\n", (int)elem.length, elem.data); - if (verbose) printf("|%d: %.*s... (%ld)\n", i, 10, elem.data, elem.length); - elems[i] = malloc(elem.length); - memcpy(elems[i++], elem.data, elem.length); - break; - default: - printf("# Error while parsing list: %i\n", ret); - ret = -1; - } - } while (ret > 0); - } - gettimeofday(&end, NULL); - //printf("%ld ms\n", (end.tv_sec * 1000000 + end.tv_usec - start.tv_sec * 1000000 - start.tv_usec)); - printf("%ld us\n", (end.tv_sec * 1000000 + end.tv_usec - start.tv_sec * 1000000 - start.tv_usec)); + printf("parsing binary list to elems[]\n"); + gettimeofday(&start, NULL); + for (n = 0; n < NELEMS; n++) { + psyc_parse_list_state_init(&listState); + psyc_parse_list_buffer_set(&listState, buf_bin, list_bin.length); + i = 0; + do { + ret = psyc_parse_list(&listState, &elem); + switch (ret) { + case PSYC_PARSE_LIST_END: + ret = 0; + case PSYC_PARSE_LIST_ELEM: + //if (verbose) printf("|%.*s\n", (int)elem.length, elem.data); + if (verbose) printf("|%d: %.*s... (%ld)\n", i, 10, elem.data, elem.length); + elems[i] = malloc(elem.length); + memcpy(elems[i++], elem.data, elem.length); + break; + default: + printf("# Error while parsing list: %i\n", ret); + ret = -1; + } + } while (ret > 0); + } + gettimeofday(&end, NULL); +// printf("%ld ms\n", (end.tv_sec * 1000000 + end.tv_usec +// - start.tv_sec * 1000000 - start.tv_usec)); + printf("%ld us\n", (end.tv_sec * 1000000 + end.tv_usec + - start.tv_sec * 1000000 - start.tv_usec)); #endif #if 1 - printf("parsing binary list to elems2[] with realloc\n"); - gettimeofday(&start, NULL); - for (n = 0; n < NELEMS; n++) { - psyc_parse_list_state_init(&listState); - psyc_parse_list_buffer_set(&listState, buf_bin, list_bin.length); - i = 0; - do { - ret = psyc_parse_list(&listState, &elem); - switch (ret) { - case PSYC_PARSE_LIST_END: - ret = 0; - case PSYC_PARSE_LIST_ELEM: - if (elems2) - elems2 = realloc(elems2, (i+1) * sizeof(char*)); - else - elems2 = malloc((i+1) * sizeof(char*)); + printf("parsing binary list to elems2[] with realloc\n"); + gettimeofday(&start, NULL); + for (n = 0; n < NELEMS; n++) { + psyc_parse_list_state_init(&listState); + psyc_parse_list_buffer_set(&listState, buf_bin, list_bin.length); + i = 0; + do { + ret = psyc_parse_list(&listState, &elem); + switch (ret) { + case PSYC_PARSE_LIST_END: + ret = 0; + case PSYC_PARSE_LIST_ELEM: + if (elems2) + elems2 = realloc(elems2, (i+1) * sizeof(char*)); + else + elems2 = malloc((i+1) * sizeof(char*)); - elems2[i] = malloc(elem.length); - memcpy(elems2[i++], elem.data, elem.length); - break; - default: - printf("# Error while parsing list: %i\n", ret); - ret = -1; - } - } while (ret > 0); - } - gettimeofday(&end, NULL); - //printf("%ld ms\n", (end.tv_sec * 1000000 + end.tv_usec - start.tv_sec * 1000000 - start.tv_usec)); - printf("%ld us\n", (end.tv_sec * 1000000 + end.tv_usec - start.tv_sec * 1000000 - start.tv_usec)); + elems2[i] = malloc(elem.length); + memcpy(elems2[i++], elem.data, elem.length); + break; + default: + printf("# Error while parsing list: %i\n", ret); + ret = -1; + } + } while (ret > 0); + } + gettimeofday(&end, NULL); +// printf("%ld ms\n", (end.tv_sec * 1000000 + end.tv_usec +// - start.tv_sec * 1000000 - start.tv_usec)); + printf("%ld us\n", (end.tv_sec * 1000000 + end.tv_usec + - start.tv_sec * 1000000 - start.tv_usec)); #endif #if 1 - printf("parsing binary list to elems2[] with malloc\n"); - gettimeofday(&start, NULL); - for (n = 0; n < NELEMS; n++) { - psyc_parse_list_state_init(&listState); - psyc_parse_list_buffer_set(&listState, buf_bin, list_bin.length); - i = 0; - do { - ret = psyc_parse_list(&listState, &elem); - switch (ret) { - case PSYC_PARSE_LIST_END: - ret = 0; - case PSYC_PARSE_LIST_ELEM: - /* - if (elems2) - elems2 = realloc(elems2, (i+1) * sizeof(char*)); - else - elems2 = malloc((i+1) * sizeof(char*)); - */ - elems2 = malloc(sizeof(char*)); - elems2[i] = malloc(elem.length); - memcpy(elems2[i], elem.data, elem.length); - break; - default: - printf("# Error while parsing list: %i\n", ret); - ret = -1; - } - } while (ret > 0); - } - gettimeofday(&end, NULL); - //printf("%ld ms\n", (end.tv_sec * 1000000 + end.tv_usec - start.tv_sec * 1000000 - start.tv_usec)); - printf("%ld us\n", (end.tv_sec * 1000000 + end.tv_usec - start.tv_sec * 1000000 - start.tv_usec)); + printf("parsing binary list to elems2[] with malloc\n"); + gettimeofday(&start, NULL); + for (n = 0; n < NELEMS; n++) { + psyc_parse_list_state_init(&listState); + psyc_parse_list_buffer_set(&listState, buf_bin, list_bin.length); + i = 0; + do { + ret = psyc_parse_list(&listState, &elem); + switch (ret) { + case PSYC_PARSE_LIST_END: + ret = 0; + case PSYC_PARSE_LIST_ELEM: + /* + if (elems2) + elems2 = realloc(elems2, (i+1) * sizeof(char*)); + else + elems2 = malloc((i+1) * sizeof(char*)); + */ + elems2 = malloc(sizeof(char*)); + elems2[i] = malloc(elem.length); + memcpy(elems2[i], elem.data, elem.length); + break; + default: + printf("# Error while parsing list: %i\n", ret); + ret = -1; + } + } while (ret > 0); + } + gettimeofday(&end, NULL); +// printf("%ld ms\n", (end.tv_sec * 1000000 + end.tv_usec +// - start.tv_sec * 1000000 - start.tv_usec)); + printf("%ld us\n", (end.tv_sec * 1000000 + end.tv_usec + - start.tv_sec * 1000000 - start.tv_usec)); #endif #if 1 - printf("parsing binary list to elems2[] with double-parsing\n"); - gettimeofday(&start, NULL); - for (n = 0; n < NELEMS; n++) { - psyc_parse_list_state_init(&listState); - psyc_parse_list_buffer_set(&listState, buf_bin, list_bin.length); - i = 0; - k = 0; + printf("parsing binary list to elems2[] with double-parsing\n"); + gettimeofday(&start, NULL); + for (n = 0; n < NELEMS; n++) { + psyc_parse_list_state_init(&listState); + psyc_parse_list_buffer_set(&listState, buf_bin, list_bin.length); + i = 0; + k = 0; - do { - ret = psyc_parse_list(&listState, &elem); - switch (ret) { - case PSYC_PARSE_LIST_END: - ret = 0; - case PSYC_PARSE_LIST_ELEM: - k++; - break; - default: - printf("# Error while parsing list: %i\n", ret); - ret = -1; - } - } while (ret > 0); + do { + ret = psyc_parse_list(&listState, &elem); + switch (ret) { + case PSYC_PARSE_LIST_END: + ret = 0; + case PSYC_PARSE_LIST_ELEM: + k++; + break; + default: + printf("# Error while parsing list: %i\n", ret); + ret = -1; + } + } while (ret > 0); - elems2 = malloc(k * sizeof(char*)); - psyc_parse_list_buffer_set(&listState, buf_bin, list_bin.length); + elems2 = malloc(k * sizeof(char*)); + psyc_parse_list_buffer_set(&listState, buf_bin, list_bin.length); - do { - ret = psyc_parse_list(&listState, &elem); - switch (ret) { - case PSYC_PARSE_LIST_END: - ret = 0; - case PSYC_PARSE_LIST_ELEM: - elems2[i] = malloc(elem.length); - memcpy(elems2[i++], elem.data, elem.length); - break; - default: - printf("# Error while parsing list: %i\n", ret); - ret = -1; - } - } while (ret > 0); - } - gettimeofday(&end, NULL); - //printf("%ld ms\n", (end.tv_sec * 1000000 + end.tv_usec - start.tv_sec * 1000000 - start.tv_usec)); - printf("%ld us\n", (end.tv_sec * 1000000 + end.tv_usec - start.tv_sec * 1000000 - start.tv_usec)); + do { + ret = psyc_parse_list(&listState, &elem); + switch (ret) { + case PSYC_PARSE_LIST_END: + ret = 0; + case PSYC_PARSE_LIST_ELEM: + elems2[i] = malloc(elem.length); + memcpy(elems2[i++], elem.data, elem.length); + break; + default: + printf("# Error while parsing list: %i\n", ret); + ret = -1; + } + } while (ret > 0); + } + gettimeofday(&end, NULL); +// printf("%ld ms\n", (end.tv_sec * 1000000 + end.tv_usec +// - start.tv_sec * 1000000 - start.tv_usec)); + printf("%ld us\n", (end.tv_sec * 1000000 + end.tv_usec + - start.tv_sec * 1000000 - start.tv_usec)); #endif - return 0; + return 0; } From 03cf28ae797a0a5b76d001f9d285d55e3407fc12 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 14 Nov 2011 22:02:02 +0100 Subject: [PATCH 347/378] table parsing --- .gitignore | 1 + include/psyc/parse.h | 113 ++++++++++++++++++++++++++++++++++------ src/parse.c | 120 ++++++++++++++++++++++++++++++++++++++++--- test/Makefile | 3 +- test/test_table.c | 80 +++++++++++++++++++++++++++++ 5 files changed, 293 insertions(+), 24 deletions(-) create mode 100644 test/test_table.c diff --git a/.gitignore b/.gitignore index bfa0c96..83138ed 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ test/test_json test/test_json_glib test/test_strlen test/test_text +test/test_table test/var_is_routing test/var_type test/uniform_parse diff --git a/include/psyc/parse.h b/include/psyc/parse.h index da28af4..2572c0e 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -40,7 +40,8 @@ * char* raw_data; // points to our (possibly incomplete) packet * size_t raw_len; // how many bytes of data * - * psyc_parse_buffer_set(&state, raw_data, raw_len); // state is our initialized state from before + * // state is our initialized state from before + * psyc_parse_buffer_set(&state, raw_data, raw_len); * @endcode * * Now the the variables that will save the output of the parser need to be @@ -212,6 +213,43 @@ typedef enum { PSYC_PARSE_LIST_INCOMPLETE = 3, } PsycParseListRC; +typedef enum { + PSYC_PARSE_TABLE_ERROR_BODY = -5, + PSYC_PARSE_TABLE_ERROR_DELIM = -4, + PSYC_PARSE_TABLE_ERROR_HEAD = -3, + PSYC_PARSE_TABLE_ERROR_WIDTH = -2, + PSYC_PARSE_TABLE_ERROR = -1, + /// Completed parsing the width of the table. + PSYC_PARSE_TABLE_WIDTH = 1, +#ifdef PSYC_PARSE_TABLE_HEAD + /// Completed parsing the name of the key column. + PSYC_PARSE_TABLE_NAME_KEY = 2, + /// Completed parsing the name of a value column. + PSYC_PARSE_TABLE_NAME_VALUE = 3, +#endif + /// Completed parsing a key. + PSYC_PARSE_TABLE_KEY = 4, + /// Completed parsing a value. + PSYC_PARSE_TABLE_VALUE = 5, + /// Completed parsing a key and reached end of buffer. + PSYC_PARSE_TABLE_KEY_END = 6, + /// Completed parsing a value and reached end of buffer. + PSYC_PARSE_TABLE_VALUE_END = 7, + /// Binary table is incomplete. + PSYC_PARSE_TABLE_INCOMPLETE = 8, +} PsycParseTableRC; + +typedef enum { + PSYC_TABLE_PART_START = 0, + PSYC_TABLE_PART_WIDTH = 1, +#ifdef PSYC_PARSE_TABLE_HEAD + PSYC_TABLE_PART_HEAD_START = 2, + PSYC_TABLE_PART_HEAD = 3, +#endif + PSYC_TABLE_PART_BODY_START = 4, + PSYC_TABLE_PART_BODY = 5, +} PsycTablePart; + /** * Struct for keeping parser state. */ @@ -239,11 +277,26 @@ typedef struct { size_t startc; ///< Line start position. PsycString buffer; ///< Buffer with data to be parsed. PsycListType type; ///< List type. + char term; ///< Terminator character at the end. + uint8_t term_set; ///< Look for terminator. size_t elemParsed; ///< Number of bytes parsed from the elem so far. size_t elemLength; ///< Expected length of the elem. } PsycParseListState; +/** + * Struct for keeping table parser state. + */ +typedef struct { + size_t cursor; ///< Current position in buffer. + size_t startc; ///< Line start position. + PsycString buffer; ///< Buffer with data to be parsed. + PsycTablePart part; ///< Table type. + size_t width; ///< Width of table. + size_t elems; ///< Elems parsed so far in the table. + PsycParseListState list; +} PsycParseTableState; + /** * Initializes the state struct. * @@ -273,8 +326,7 @@ psyc_parse_state_init (PsycParseState *state, uint8_t flags) * @see PsycString */ static inline void -psyc_parse_buffer_set (PsycParseState *state, char *buffer, - size_t length) +psyc_parse_buffer_set (PsycParseState *state, const char *buffer, size_t length) { state->buffer = (PsycString) {length, buffer}; state->cursor = 0; @@ -286,9 +338,7 @@ psyc_parse_buffer_set (PsycParseState *state, char *buffer, } /** - * Initializes the list state struct. - * - * @param state Pointer to the list state struct that should be initialized. + * Initializes the list state. */ static inline void psyc_parse_list_state_init (PsycParseListState *state) @@ -306,6 +356,32 @@ psyc_parse_list_buffer_set (PsycParseListState *state, char *buffer, size_t leng state->cursor = 0; } +static inline void +psyc_parse_list_term_set (PsycParseListState *state, char term) +{ + state->term = term; + state->term_set = PSYC_TRUE; +} + +/** + * Initializes the table state. + */ +static inline void +psyc_parse_table_state_init (PsycParseTableState *state) +{ + memset(state, 0, sizeof(PsycParseTableState)); +} + +/** + * Sets a new buffer in the list parser state struct with data to be parsed. + */ +static inline void +psyc_parse_table_buffer_set (PsycParseTableState *state, char *buffer, size_t length) +{ + state->buffer = (PsycString) {length, buffer}; + state->cursor = 0; +} + static inline size_t psyc_parse_content_length (PsycParseState *state) { @@ -394,14 +470,17 @@ static inline PsycParseListRC psyc_parse_list (PsycParseListState *state, PsycString *elem); -static inline PsycBool +PsycParseTableRC +psyc_parse_table (PsycParseTableState *state, PsycString *elem); + +static inline PsycRC psyc_parse_number (const char *value, size_t len, int64_t *n) { size_t c = 0; uint8_t neg = 0; if (!value) - return PSYC_FALSE; + return PSYC_ERROR; if (value[0] == '-') neg = ++c; @@ -411,42 +490,42 @@ psyc_parse_number (const char *value, size_t len, int64_t *n) *n = 10 * *n + (value[c++] - '0'); if (c != len) - return PSYC_FALSE; + return PSYC_ERROR; if (neg) *n = 0 - *n; - return PSYC_TRUE; + return PSYC_OK; } -static inline PsycBool +static inline PsycRC psyc_parse_number_unsigned (const char *value, size_t len, uint64_t *n) { size_t c = 0; if (!value) - return PSYC_FALSE; + return PSYC_ERROR; *n = 0; while (c < len && value[c] >= '0' && value[c] <= '9') *n = 10 * *n + (value[c++] - '0'); - return c == len ? PSYC_TRUE : PSYC_FALSE; + return c == len ? PSYC_OK : PSYC_ERROR; } -static inline PsycBool +static inline PsycRC psyc_parse_time (const char *value, size_t len, time_t *t) { return psyc_parse_number(value, len, t); } -static inline PsycBool +static inline PsycRC psyc_parse_date (const char *value, size_t len, time_t *t) { if (psyc_parse_number(value, len, t)) { *t += PSYC_EPOCH; - return PSYC_TRUE; + return PSYC_OK; } - return PSYC_FALSE; + return PSYC_ERROR; } /** diff --git a/src/parse.c b/src/parse.c index 5a3dd05..27af0a5 100644 --- a/src/parse.c +++ b/src/parse.c @@ -328,7 +328,7 @@ psyc_parse (PsycParseState *state, char *oper, // fall thru case PSYC_PART_DATA: - PSYC_PART_DATA: + PSYC_PART_DATA: value->data = state->buffer.data + state->cursor; value->length = 0; @@ -385,7 +385,7 @@ psyc_parse (PsycParseState *state, char *oper, } case PSYC_PART_END: - PSYC_PART_END: + PSYC_PART_END: // if data was not empty next is the \n at the end of data if (state->contentLengthFound && state->valueLengthFound && state->valueLength && !(state->flags & PSYC_PARSE_ROUTING_ONLY)) { @@ -447,10 +447,20 @@ psyc_parse_list (PsycParseListState *state, PsycString *elem) if (state->cursor >= state->buffer.length) return PSYC_PARSE_LIST_END; - while (state->buffer.data[state->cursor] != '|') { - elem->length++; - if (++(state->cursor) >= state->buffer.length) - return PSYC_PARSE_LIST_END; + if (state->term_set) { + while (state->buffer.data[state->cursor] != '|') { + elem->length++; + if (state->buffer.data[state->cursor] == state->term) + return PSYC_PARSE_LIST_END; + if (++(state->cursor) >= state->buffer.length) + return PSYC_PARSE_LIST_END; + } + } else { + while (state->buffer.data[state->cursor] != '|') { + elem->length++; + if (++(state->cursor) >= state->buffer.length) + return PSYC_PARSE_LIST_END; + } } state->cursor++; return PSYC_PARSE_LIST_ELEM; @@ -497,3 +507,101 @@ psyc_parse_list (PsycParseListState *state, PsycString *elem) return PSYC_PARSE_LIST_ERROR; // should not be reached } + +PsycParseTableRC +psyc_parse_table (PsycParseTableState *state, PsycString *elem) +{ + if (state->cursor >= state->buffer.length) + return PSYC_PARSE_TABLE_INCOMPLETE; + + state->startc = state->cursor; + + switch (state->part) { + case PSYC_TABLE_PART_START: + if (state->buffer.data[state->cursor] != '*') { + state->part = PSYC_TABLE_PART_BODY_START; + goto PSYC_TABLE_PART_BODY_START; + } else { + state->part = PSYC_TABLE_PART_WIDTH; + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_TABLE_INCOMPLETE); + } + // fall thru + + case PSYC_TABLE_PART_WIDTH: + if (psyc_is_numeric(state->buffer.data[state->cursor])) { + do { + state->width = + 10 * state->width + state->buffer.data[state->cursor] - '0'; + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_TABLE_INCOMPLETE); + } while (psyc_is_numeric(state->buffer.data[state->cursor])); + } else + return PSYC_PARSE_TABLE_ERROR_WIDTH; + + switch (state->buffer.data[state->cursor]) { +#ifdef PSYC_PARSE_TABLE_HEAD + case '|': + state->part = PSYC_TABLE_PART_HEAD_START; + break; +#endif + case ' ': + state->part = PSYC_TABLE_PART_BODY_START; + state->cursor++; + } + + elem->length = state->width; + return PSYC_TABLE_PART_WIDTH; +#ifdef PSYC_PARSE_TABLE_HEAD + case PSYC_TABLE_PART_HEAD_START: + psyc_parse_list_buffer_set(&state->list, state->buffer.data + state->cursor, + state->buffer.length - state->cursor); + psyc_parse_list_term_set(&state->list, ' '); + state->part = PSYC_TABLE_PART_HEAD; + // fall thru + + case PSYC_TABLE_PART_HEAD: + switch (psyc_parse_list(&state->list, elem)) { + case PSYC_PARSE_LIST_ELEM: + if (state->elems == 0) { + state->elems++; + return PSYC_PARSE_TABLE_NAME_KEY; + } else if (state->elems < state->width) { + state->elems++; + return PSYC_PARSE_TABLE_NAME_VALUE; + } else // too many elements + return PSYC_PARSE_TABLE_ERROR_HEAD; + + case PSYC_PARSE_LIST_END: + if (state->elems != state->width) + return PSYC_PARSE_TABLE_ERROR_HEAD; + + state->part = PSYC_TABLE_PART_BODY_START; + state->cursor += state->list.cursor + 1; + psyc_parse_list_state_init(&state->list); + return state->elems++ == 0 + ? PSYC_PARSE_TABLE_NAME_KEY : PSYC_PARSE_TABLE_NAME_VALUE; + default: + return PSYC_PARSE_TABLE_ERROR_HEAD; + } +#endif + case PSYC_TABLE_PART_BODY_START: + PSYC_TABLE_PART_BODY_START: + psyc_parse_list_buffer_set(&state->list, state->buffer.data + state->cursor, + state->buffer.length - state->cursor); + state->part = PSYC_TABLE_PART_BODY; + // fall thru + + case PSYC_TABLE_PART_BODY: + switch (psyc_parse_list(&state->list, elem)) { + case PSYC_PARSE_LIST_ELEM: + return state->elems++ % (state->width + 1) == 0 + ? PSYC_PARSE_TABLE_KEY : PSYC_PARSE_TABLE_VALUE; + case PSYC_PARSE_LIST_END: + return state->elems++ % (state->width + 1) == 0 + ? PSYC_PARSE_TABLE_KEY_END : PSYC_PARSE_TABLE_VALUE_END; + default: + return PSYC_PARSE_TABLE_ERROR_BODY; + } + } + + return PSYC_PARSE_LIST_ERROR; // should not be reached +} diff --git a/test/Makefile b/test/Makefile index 05a41c2..ba570c3 100644 --- a/test/Makefile +++ b/test/Makefile @@ -3,7 +3,7 @@ DEBUG = 2 CFLAGS = -I../include -I../src -Wall -std=c99 ${OPT} LDFLAGS = -L../lib LOADLIBES = -lpsyc -lm -TARGETS = test_psyc test_psyc_speed test_parser test_match test_render test_text var_is_routing var_type uniform_parse +TARGETS = test_psyc test_psyc_speed test_parser test_match test_render test_text var_is_routing var_type uniform_parse test_table O = test.o WRAPPER = DIET = diet @@ -48,6 +48,7 @@ test: ${TARGETS} ./var_is_routing ./var_type ./uniform_parse + ./test_table x=0; for f in packets/[0-9]*; do echo ">> $$f"; ./test_psyc -f $$f | ${DIFF} -u $$f -; x=$$((x+$$?)); done; exit $$x x=0; for f in packets/[0-9]*; do echo ">> $$f"; ./test_psyc -rf $$f | ${DIFF} -u $$f -; x=$$((x+$$?)); done; exit $$x diff --git a/test/test_table.c b/test/test_table.c new file mode 100644 index 0000000..01759b2 --- /dev/null +++ b/test/test_table.c @@ -0,0 +1,80 @@ +#include +#include + +#include + +int +parse_table (char *buf, size_t buflen) +{ + printf(">> %.*s\n", (int)buflen, buf); + + int ret; + PsycString elem; + PsycParseTableState state; + psyc_parse_table_state_init(&state); + psyc_parse_table_buffer_set(&state, buf, buflen); + + do { + ret = psyc_parse_table(&state, &elem); + switch (ret) { + case PSYC_PARSE_TABLE_WIDTH: + printf("width: %ld\n", elem.length); + break; +#ifdef PSYC_PARSE_TABLE_HEAD + case PSYC_PARSE_TABLE_NAME_KEY: + printf("name key: %.*s\n", (int)PSYC_S2ARG2(elem)); + break; + case PSYC_PARSE_TABLE_NAME_VALUE: + printf("name val: %.*s\n", (int)PSYC_S2ARG2(elem)); + break; +#endif + case PSYC_PARSE_TABLE_KEY_END: + ret = 0; + case PSYC_PARSE_TABLE_KEY: + printf("key: %.*s\n", (int)PSYC_S2ARG2(elem)); + break; + case PSYC_PARSE_TABLE_VALUE_END: + ret = 0; + case PSYC_PARSE_TABLE_VALUE: + printf("val: %.*s\n", (int)PSYC_S2ARG2(elem)); + break; + default: + printf("err: %d\n", ret); + } + } while (ret > 0); + return ret == 0; +} + +int +main (int argc, char **argv) +{ + +#ifdef PSYC_PARSE_TABLE_HEAD + if (!parse_table(PSYC_C2ARG("*2|_key|_val1|_val2 |_foo|bar|baz|_aaa|bbb|ccc"))) + return 1; +#endif + + if (!parse_table(PSYC_C2ARG("*2 |_foo|bar|baz|_aaa|bbb|ccc"))) + return 2; + +#ifdef PSYC_PARSE_TABLE_HEAD + if (!parse_table(PSYC_C2ARG("*1|_key|_val1 |_foo|bar|_baz|aaa|_bbb|ccc"))) + return 1; +#endif + + if (!parse_table(PSYC_C2ARG("*1 |_foo|bar|_baz|aaa|_bbb|ccc"))) + return 3; + +#ifdef PSYC_PARSE_TABLE_HEAD + if (!parse_table(PSYC_C2ARG("*0|_key |foo|bar|baz|aaa|bbb|ccc"))) + return 4; +#endif + + if (!parse_table(PSYC_C2ARG("*0 |foo|bar|baz|aaa|bbb|ccc"))) + return 4; + + if (!parse_table(PSYC_C2ARG("|foo|bar|baz|aaa|bbb|ccc"))) + return 5; + + return 0; +} From 7c1c74dd93245063e3b48c141c9257f20bbf7748 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 21 Nov 2011 16:00:46 +0100 Subject: [PATCH 348/378] added @ op & _table type; number, index & keyword parsing --- include/psyc.h | 4 +- include/psyc/packet.h | 7 ++- include/psyc/parse.h | 102 +++++++++++++++++--------------- src/packet.c | 50 +++++++++++----- src/parse.c | 132 +++++++++++++++++++++--------------------- src/render.c | 2 +- src/variable.c | 3 +- 7 files changed, 165 insertions(+), 135 deletions(-) diff --git a/include/psyc.h b/include/psyc.h index 351de41..e04b030 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -70,6 +70,7 @@ typedef enum { PSYC_TYPE_UNKNOWN, PSYC_TYPE_AMOUNT, PSYC_TYPE_COLOR, + PSYC_TYPE_COUNTER, PSYC_TYPE_DATE, PSYC_TYPE_DEGREE, PSYC_TYPE_ENTITY, @@ -78,8 +79,9 @@ typedef enum { PSYC_TYPE_LIST, PSYC_TYPE_NICK, PSYC_TYPE_PAGE, - PSYC_TYPE_UNIFORM, + PSYC_TYPE_TABLE, PSYC_TYPE_TIME, + PSYC_TYPE_UNIFORM, } PsycType; /** diff --git a/include/psyc/packet.h b/include/psyc/packet.h index 5c5fb18..24429a0 100644 --- a/include/psyc/packet.h +++ b/include/psyc/packet.h @@ -57,6 +57,7 @@ typedef enum { PSYC_OPERATOR_ASSIGN = '=', PSYC_OPERATOR_AUGMENT = '+', PSYC_OPERATOR_DIMINISH = '-', + PSYC_OPERATOR_UPDATE = '@', PSYC_OPERATOR_QUERY = '?', } PsycOperator; @@ -92,13 +93,13 @@ typedef struct { typedef struct { PsycHeader routing; ///< Routing header. PsycHeader entity; ///< Entity header. - char stateop; ///< State operation. @see PsycStateOp PsycString method; ///< Contains the method. PsycString data; ///< Contains the data. PsycString content; ///< Contains the whole content. - size_t routingLength; ///< Length of routing part. - size_t contentLength; ///< Length of content part. + size_t routinglen; ///< Length of routing part. + size_t contentlen; ///< Length of content part. size_t length; ///< Total length of packet. + PsycStateOp stateop; ///< State operation. @see PsycStateOp PsycPacketFlag flag; ///< Packet flag. } PsycPacket; diff --git a/include/psyc/parse.h b/include/psyc/parse.h index 2572c0e..93f64d3 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -260,13 +260,13 @@ typedef struct { uint8_t flags; ///< Flags for the parser, see PsycParseFlag. PsycPart part; ///< Part of the packet being parsed currently. - size_t routingLength; ///< Length of routing part parsed so far. - size_t contentParsed; ///< Number of bytes parsed from the content so far. - size_t contentLength; ///< Expected length of the content. - PsycBool 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. - PsycBool valueLengthFound; ///< Is there a length given for this modifier? + size_t routinglen; ///< Length of routing part parsed so far. + size_t content_parsed; ///< Number of bytes parsed from the content so far. + size_t contentlen; ///< Expected length of the content. + PsycBool contentlen_found; ///< Is there a length given for this packet? + size_t value_parsed; ///< Number of bytes parsed from the value so far. + size_t valuelen; ///< Expected length of the value. + PsycBool valuelen_found; ///< Is there a length given for this modifier? } PsycParseState; /** @@ -280,8 +280,8 @@ typedef struct { char term; ///< Terminator character at the end. uint8_t term_set; ///< Look for terminator. - size_t elemParsed; ///< Number of bytes parsed from the elem so far. - size_t elemLength; ///< Expected length of the elem. + size_t elem_parsed; ///< Number of bytes parsed from the elem so far. + size_t elemlen; ///< Expected length of the elem. } PsycParseListState; /** @@ -326,14 +326,14 @@ psyc_parse_state_init (PsycParseState *state, uint8_t flags) * @see PsycString */ static inline void -psyc_parse_buffer_set (PsycParseState *state, const char *buffer, size_t length) +psyc_parse_buffer_set (PsycParseState *state, char *buffer, size_t length) { state->buffer = (PsycString) {length, buffer}; state->cursor = 0; if (state->flags & PSYC_PARSE_START_AT_CONTENT) { - state->contentLength = length; - state->contentLengthFound = PSYC_TRUE; + state->contentlen = length; + state->contentlen_found = PSYC_TRUE; } } @@ -385,25 +385,25 @@ psyc_parse_table_buffer_set (PsycParseTableState *state, char *buffer, size_t le static inline size_t psyc_parse_content_length (PsycParseState *state) { - return state->contentLength; + return state->contentlen; } static inline PsycBool psyc_parse_content_length_found (PsycParseState *state) { - return state->contentLengthFound; + return state->contentlen_found; } static inline size_t psyc_parse_value_length (PsycParseState *state) { - return state->valueLength; + return state->valuelen; } static inline PsycBool psyc_parse_value_length_found (PsycParseState *state) { - return state->valueLengthFound; + return state->valuelen_found; } static inline size_t @@ -473,14 +473,14 @@ psyc_parse_list (PsycParseListState *state, PsycString *elem); PsycParseTableRC psyc_parse_table (PsycParseTableState *state, PsycString *elem); -static inline PsycRC -psyc_parse_number (const char *value, size_t len, int64_t *n) +static inline size_t +psyc_parse_int (const char *value, size_t len, int64_t *n) { size_t c = 0; uint8_t neg = 0; if (!value) - return PSYC_ERROR; + return c; if (value[0] == '-') neg = ++c; @@ -490,61 +490,54 @@ psyc_parse_number (const char *value, size_t len, int64_t *n) *n = 10 * *n + (value[c++] - '0'); if (c != len) - return PSYC_ERROR; + return c; if (neg) *n = 0 - *n; - return PSYC_OK; + return c; } -static inline PsycRC -psyc_parse_number_unsigned (const char *value, size_t len, uint64_t *n) +static inline size_t +psyc_parse_uint (const char *value, size_t len, uint64_t *n) { size_t c = 0; if (!value) - return PSYC_ERROR; + return c; *n = 0; while (c < len && value[c] >= '0' && value[c] <= '9') *n = 10 * *n + (value[c++] - '0'); - return c == len ? PSYC_OK : PSYC_ERROR; + return c; } -static inline PsycRC -psyc_parse_time (const char *value, size_t len, time_t *t) +static inline size_t +psyc_parse_index (const char *value, size_t len, int64_t *n) { - return psyc_parse_number(value, len, t); -} - -static inline PsycRC -psyc_parse_date (const char *value, size_t len, time_t *t) -{ - if (psyc_parse_number(value, len, t)) { - *t += PSYC_EPOCH; - return PSYC_OK; - } - return PSYC_ERROR; + if (!value || len == 0 || value[0] != '#') + return 0; + return psyc_parse_int(value + 1, len, n) + 1; } /** * Determines if the argument is a glyph. * Glyphs are: : = + - ? ! */ -static inline char -psyc_is_glyph (uint8_t g) +static inline PsycBool +psyc_is_glyph (char g) { switch (g) { case ':': case '=': case '+': case '-': + case '@': case '?': case '!': - return 1; + return PSYC_TRUE; default: - return 0; + return PSYC_FALSE; } } @@ -552,7 +545,7 @@ psyc_is_glyph (uint8_t g) * Determines if the argument is numeric. */ static inline char -psyc_is_numeric (uint8_t c) +psyc_is_numeric (char c) { return c >= '0' && c <= '9'; } @@ -561,7 +554,7 @@ psyc_is_numeric (uint8_t c) * Determines if the argument is alphabetic. */ static inline char -psyc_is_alpha (uint8_t c) +psyc_is_alpha (char c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); } @@ -570,7 +563,7 @@ psyc_is_alpha (uint8_t c) * Determines if the argument is alphanumeric. */ static inline char -psyc_is_alpha_numeric (uint8_t c) +psyc_is_alpha_numeric (char c) { return psyc_is_alpha(c) || psyc_is_numeric(c); } @@ -580,7 +573,7 @@ psyc_is_alpha_numeric (uint8_t c) * Keyword characters are: alphanumeric and _ */ static inline char -psyc_is_kw_char (uint8_t c) +psyc_is_kw_char (char c) { return psyc_is_alpha_numeric(c) || c == '_'; } @@ -590,7 +583,7 @@ psyc_is_kw_char (uint8_t c) * Name characters are: see opaque_part in RFC 2396 */ static inline char -psyc_is_name_char (uint8_t c) +psyc_is_name_char (char c) { return psyc_is_alpha(c) || (c >= '$' && c <= ';') || c == '_' || c == '!' || c == '?' || c == '=' || c == '@' || c == '~'; @@ -601,11 +594,24 @@ psyc_is_name_char (uint8_t c) * Hostname characters are: alphanumeric and - */ static inline char -psyc_is_host_char (uint8_t c) +psyc_is_host_char (char c) { return psyc_is_alpha_numeric(c) || c == '.' || c == '-'; } +/** + * Parse variable name or method name. + * It should contain one or more keyword characters. + * @return Number of characters parsed. + */ +static inline size_t +psyc_parse_keyword (const char *data, size_t len) +{ + size_t c = 0; + while (c < len && psyc_is_kw_char(data[c++])); + return c > 0 ? c - 1 : 0; +} + /** @} */ // end of parse group #endif diff --git a/src/packet.c b/src/packet.c index d637e70..6626812 100644 --- a/src/packet.c +++ b/src/packet.c @@ -95,39 +95,39 @@ inline size_t psyc_packet_length_set (PsycPacket * p) { size_t i; - p->routingLength = 0; - p->contentLength = 0; + p->routinglen = 0; + p->contentlen = 0; // add routing header length for (i = 0; i < p->routing.lines; i++) - p->routingLength += psyc_modifier_length(&(p->routing.modifiers[i])); + p->routinglen += psyc_modifier_length(&(p->routing.modifiers[i])); if (p->content.length) - p->contentLength = p->content.length; + p->contentlen = p->content.length; else { // add state operation if (p->stateop != PSYC_STATE_NOOP) - p->contentLength += 2; // op\n + p->contentlen += 2; // op\n // add entity header length for (i = 0; i < p->entity.lines; i++) - p->contentLength += psyc_modifier_length(&(p->entity.modifiers[i])); + p->contentlen += psyc_modifier_length(&(p->entity.modifiers[i])); // add length of method, data & delimiter if (p->method.length) - p->contentLength += p->method.length + 1; // method\n + p->contentlen += p->method.length + 1; // method\n if (p->data.length) - p->contentLength += p->data.length + 1; // data\n + p->contentlen += p->data.length + 1; // data\n } // set total length: routing-header content |\n - p->length = p->routingLength + p->contentLength + 2; + p->length = p->routinglen + p->contentlen + 2; - if (p->contentLength > 0 || p->flag == PSYC_PACKET_NEED_LENGTH) + if (p->contentlen > 0 || p->flag == PSYC_PACKET_NEED_LENGTH) p->length++; // add \n at the start of the content part if (p->flag == PSYC_PACKET_NEED_LENGTH) // add length of length if needed - p->length += psyc_num_length(p->contentLength); + p->length += psyc_num_length(p->contentlen); return p->length; } @@ -140,8 +140,18 @@ psyc_packet_init (PsycPacket * p, char *data, size_t datalen, char stateop, PsycPacketFlag flag) { - *p = (PsycPacket) {{routinglen, routing}, {entitylen, entity}, stateop, - {methodlen, method}, {datalen, data}, {0, 0}, 0, 0, flag}; + *p = (PsycPacket) { + .routing = {routinglen, routing}, + .entity = {entitylen, entity}, + .method = {methodlen, method}, + .data = {datalen, data}, + .content = {0, 0}, + .routinglen = 0, + .contentlen = 0, + .length = 0, + .stateop = stateop, + .flag = flag, + }; if (flag == PSYC_PACKET_CHECK_LENGTH) // find out if it needs length p->flag = psyc_packet_length_check(p); @@ -155,8 +165,18 @@ psyc_packet_init_raw (PsycPacket * p, char *content, size_t contentlen, PsycPacketFlag flag) { - *p = (PsycPacket) {{routinglen, routing}, {0, 0}, 0, {0, 0}, {0, 0}, - {contentlen, content}, 0, 0, flag}; + *p = (PsycPacket) { + .routing = {routinglen, routing}, + .entity = {0, 0}, + .method = {0, 0}, + .data = {0, 0}, + .content = {contentlen, content}, + .routinglen = 0, + .contentlen = 0, + .length = 0, + .stateop = 0, + .flag = flag, + }; if (flag == PSYC_PACKET_CHECK_LENGTH) // find out if it needs length p->flag = psyc_packet_length_check(p); diff --git a/src/parse.c b/src/parse.c index 27af0a5..0ccf9c5 100644 --- a/src/parse.c +++ b/src/parse.c @@ -29,7 +29,7 @@ typedef enum { * @return PARSE_ERROR or PARSE_SUCCESS */ static inline ParseRC -psyc_parse_keyword (PsycParseState *state, PsycString *name) +parse_keyword (PsycParseState *state, PsycString *name) { name->data = state->buffer.data + state->cursor; name->length = 0; @@ -86,7 +86,7 @@ psyc_parse_modifier (PsycParseState *state, char *oper, *oper = *(state->buffer.data + state->cursor); ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); - ParseRC ret = psyc_parse_keyword(state, name); + ParseRC ret = parse_keyword(state, name); if (ret == PARSE_ERROR) return PSYC_PARSE_ERROR_MOD_NAME; else if (ret != PARSE_SUCCESS) @@ -94,9 +94,9 @@ psyc_parse_modifier (PsycParseState *state, char *oper, size_t length = 0; value->length = 0; - state->valueLength = 0; - state->valueLengthFound = 0; - state->valueParsed = 0; + state->valuelen = 0; + state->valuelen_found = 0; + state->value_parsed = 0; // Parse the value. // If we're in the content part check if it's a binary var. @@ -106,13 +106,13 @@ psyc_parse_modifier (PsycParseState *state, char *oper, ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); if (psyc_is_numeric(state->buffer.data[state->cursor])) { - state->valueLengthFound = 1; + state->valuelen_found = 1; do { length = 10 * length + state->buffer.data[state->cursor] - '0'; ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } while (psyc_is_numeric(state->buffer.data[state->cursor])); - state->valueLength = length; + state->valuelen = length; } else return PSYC_PARSE_ERROR_MOD_LEN; @@ -124,8 +124,8 @@ psyc_parse_modifier (PsycParseState *state, char *oper, return length ? PARSE_INCOMPLETE : PARSE_SUCCESS; // if length=0 we're done ret = - psyc_parse_binary_value(state, value, &(state->valueLength), - &(state->valueParsed)); + psyc_parse_binary_value(state, value, &(state->valuelen), + &(state->value_parsed)); if (ret == PARSE_INCOMPLETE) return ret; @@ -170,18 +170,18 @@ psyc_parse (PsycParseState *state, char *oper, switch (state->part) { case PSYC_PART_RESET: // New packet starts here, reset state. - state->valueParsed = 0; - state->valueLength = 0; - state->valueLengthFound = 0; - state->routingLength = 0; - state->contentParsed = 0; - state->contentLength = 0; - state->contentLengthFound = 0; + state->value_parsed = 0; + state->valuelen = 0; + state->valuelen_found = 0; + state->routinglen = 0; + state->content_parsed = 0; + state->contentlen = 0; + state->contentlen_found = 0; state->part = PSYC_PART_ROUTING; // fall thru case PSYC_PART_ROUTING: - if (state->routingLength > 0) { + if (state->routinglen > 0) { if (state->buffer.data[state->cursor] != '\n') return PSYC_PARSE_ERROR_MOD_NL; ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); @@ -192,7 +192,7 @@ psyc_parse (PsycParseState *state, char *oper, if (psyc_is_glyph(state->buffer.data[state->cursor])) { // it is a glyph, so a variable starts here ret = psyc_parse_modifier(state, oper, name, value); - state->routingLength += state->cursor - pos; + state->routinglen += state->cursor - pos; return ret == PARSE_SUCCESS ? PSYC_PARSE_ROUTING : ret; } else { // not a glyph state->part = PSYC_PART_LENGTH; @@ -203,12 +203,12 @@ psyc_parse (PsycParseState *state, char *oper, case PSYC_PART_LENGTH: // End of header, content starts with an optional length then a NL if (psyc_is_numeric(state->buffer.data[state->cursor])) { - state->contentLengthFound = 1; - state->contentLength = 0; + state->contentlen_found = 1; + state->contentlen = 0; do { - state->contentLength = - 10 * state->contentLength + + state->contentlen = + 10 * state->contentlen + state->buffer.data[state->cursor] - '0'; ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } while (psyc_is_numeric(state->buffer.data[state->cursor])); @@ -226,7 +226,7 @@ psyc_parse (PsycParseState *state, char *oper, 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) + if (state->contentlen_found) return PSYC_PARSE_ERROR_LENGTH; state->part = PSYC_PART_END; @@ -239,10 +239,10 @@ psyc_parse (PsycParseState *state, char *oper, case PSYC_PART_CONTENT: // In case of an incomplete binary variable resume parsing it. - if (state->valueParsed < state->valueLength) { - ret = psyc_parse_binary_value(state, value, &(state->valueLength), - &(state->valueParsed)); - state->contentParsed += value->length; + if (state->value_parsed < state->valuelen) { + ret = psyc_parse_binary_value(state, value, &(state->valuelen), + &(state->value_parsed)); + state->content_parsed += value->length; if (ret == PARSE_INCOMPLETE) return PSYC_PARSE_ENTITY_CONT; @@ -252,7 +252,7 @@ psyc_parse (PsycParseState *state, char *oper, pos = state->cursor; - if (state->contentParsed > 0) { + if (state->content_parsed > 0) { if (state->buffer.data[state->cursor] != '\n') return PSYC_PARSE_ERROR_MOD_NL; ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); @@ -264,15 +264,15 @@ psyc_parse (PsycParseState *state, char *oper, // method does not start with a glyph. if (psyc_is_glyph(state->buffer.data[state->cursor])) { ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); - if (state->contentParsed == 0 + if (state->content_parsed == 0 && state->buffer.data[state->cursor] == '\n') { *oper = *(state->buffer.data + state->cursor - 1); switch (*oper) { case PSYC_STATE_RESYNC: - state->contentParsed += 2; + state->content_parsed += 2; return PSYC_PARSE_STATE_RESYNC; case PSYC_STATE_RESET: - state->contentParsed += 2; + state->content_parsed += 2; return PSYC_PARSE_STATE_RESET; default: return PSYC_PARSE_ERROR_MOD_NAME; @@ -281,7 +281,7 @@ psyc_parse (PsycParseState *state, char *oper, state->cursor--; ret = psyc_parse_modifier(state, oper, name, value); - state->contentParsed += state->cursor - pos; + state->content_parsed += state->cursor - pos; if (ret == PARSE_INCOMPLETE) return PSYC_PARSE_ENTITY_START; @@ -290,7 +290,7 @@ psyc_parse (PsycParseState *state, char *oper, return ret; } else { - state->contentParsed += state->cursor - pos; + state->content_parsed += state->cursor - pos; state->startc = state->cursor; state->part = PSYC_PART_METHOD; // fall thru @@ -298,7 +298,7 @@ psyc_parse (PsycParseState *state, char *oper, case PSYC_PART_METHOD: pos = state->cursor; - ret = psyc_parse_keyword(state, name); + ret = parse_keyword(state, name); if (ret == PARSE_INSUFFICIENT) return ret; @@ -307,15 +307,15 @@ psyc_parse (PsycParseState *state, char *oper, if (state->buffer.data[state->cursor] != '\n') return PSYC_PARSE_ERROR_METHOD; - state->valueLengthFound = 0; - state->valueParsed = 0; - state->valueLength = 0; + state->valuelen_found = 0; + state->value_parsed = 0; + state->valuelen = 0; - if (state->contentLengthFound) { - // Length found, set start position to the beginning of data. + if (state->contentlen_found) { + // len found, set start position to the beginning of data. state->cursor++; state->startc = state->cursor; - state->contentParsed += state->cursor - pos; + state->content_parsed += state->cursor - pos; state->part = PSYC_PART_DATA; } else { // Otherwise keep it at the beginning of method. ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); @@ -332,25 +332,25 @@ psyc_parse (PsycParseState *state, char *oper, value->data = state->buffer.data + state->cursor; value->length = 0; - if (state->contentLengthFound) { // We know the length of the packet. - if (!state->valueLengthFound) { // start of data - state->valueLengthFound = 1; - state->valueLength = state->contentLength - state->contentParsed; - if (state->valueLength && !(state->flags & PSYC_PARSE_ROUTING_ONLY)) - state->valueLength--; // \n at the end is not part of data + if (state->contentlen_found) { // We know the length of the packet. + if (!state->valuelen_found) { // start of data + state->valuelen_found = 1; + state->valuelen = state->contentlen - state->content_parsed; + if (state->valuelen && !(state->flags & PSYC_PARSE_ROUTING_ONLY)) + state->valuelen--; // \n at the end is not part of data } - if (state->valueParsed < state->valueLength) { - ret = psyc_parse_binary_value(state, value, &(state->valueLength), - &(state->valueParsed)); - state->contentParsed += value->length; + if (state->value_parsed < state->valuelen) { + ret = psyc_parse_binary_value(state, value, &(state->valuelen), + &(state->value_parsed)); + state->content_parsed += value->length; if (ret == PARSE_INCOMPLETE) - return state->valueParsed == value->length + return state->value_parsed == value->length ? PSYC_PARSE_BODY_START : PSYC_PARSE_BODY_CONT; } state->part = PSYC_PART_END; - return state->valueLength == value->length ? + return state->valuelen == value->length ? PSYC_PARSE_BODY : PSYC_PARSE_BODY_END; } else { // Search for the terminator. size_t datac = state->cursor; // start of data @@ -373,7 +373,7 @@ psyc_parse (PsycParseState *state, char *oper, if (state->flags & PSYC_PARSE_ROUTING_ONLY) value->length++; - state->contentParsed += state->cursor - pos; + state->content_parsed += state->cursor - pos; state->cursor += nl; state->part = PSYC_PART_END; return PSYC_PARSE_BODY; @@ -387,15 +387,15 @@ psyc_parse (PsycParseState *state, char *oper, case PSYC_PART_END: PSYC_PART_END: // if data was not empty next is the \n at the end of data - if (state->contentLengthFound && state->valueLengthFound - && state->valueLength && !(state->flags & PSYC_PARSE_ROUTING_ONLY)) { - state->valueLength = 0; - state->valueLengthFound = 0; + if (state->contentlen_found && state->valuelen_found + && state->valuelen && !(state->flags & PSYC_PARSE_ROUTING_ONLY)) { + state->valuelen = 0; + state->valuelen_found = 0; if (state->buffer.data[state->cursor] != '\n') return PSYC_PARSE_ERROR_END; - state->contentParsed++; + state->content_parsed++; state->cursor++; } // End of packet, at this point we have already passed a \n @@ -465,12 +465,12 @@ psyc_parse_list (PsycParseListState *state, PsycString *elem) state->cursor++; return PSYC_PARSE_LIST_ELEM; } else { // binary list - if (!(state->elemParsed < state->elemLength)) { + if (!(state->elem_parsed < state->elemlen)) { // Element starts with a number. if (psyc_is_numeric(state->buffer.data[state->cursor])) { do { - state->elemLength = - 10 * state->elemLength + + state->elemlen = + 10 * state->elemlen + state->buffer.data[state->cursor] - '0'; ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_LIST_INCOMPLETE); } while (psyc_is_numeric(state->buffer.data[state->cursor])); @@ -483,16 +483,16 @@ psyc_parse_list (PsycParseListState *state, PsycString *elem) state->cursor++; elem->data = state->buffer.data + state->cursor; elem->length = 0; - state->elemParsed = 0; + state->elem_parsed = 0; } // Start or resume parsing the binary data - if (state->elemParsed < state->elemLength) { + if (state->elem_parsed < state->elemlen) { if (PARSE_INCOMPLETE == psyc_parse_binary_value((PsycParseState*)state, - elem, &state->elemLength, - &state->elemParsed)) + elem, &state->elemlen, + &state->elem_parsed)) return PSYC_PARSE_LIST_INCOMPLETE; - state->elemLength = 0; + state->elemlen = 0; if (state->cursor >= state->buffer.length) return PSYC_PARSE_LIST_END; diff --git a/src/render.c b/src/render.c index 5fefbb0..72508cc 100644 --- a/src/render.c +++ b/src/render.c @@ -84,7 +84,7 @@ psyc_render (PsycPacket * packet, char *buffer, size_t buflen) // add length if needed if (packet->flag == PSYC_PACKET_NEED_LENGTH) - cur += itoa(packet->contentLength, buffer + cur, 10); + cur += itoa(packet->contentlen, buffer + cur, 10); if (packet->flag == PSYC_PACKET_NEED_LENGTH || packet->content.length || packet->stateop || packet->entity.lines diff --git a/src/variable.c b/src/variable.c index 3d0833d..e762b74 100644 --- a/src/variable.c +++ b/src/variable.c @@ -38,8 +38,9 @@ const PsycDictInt psyc_var_types[] = { {PSYC_C2STRI("_list"), PSYC_TYPE_LIST}, {PSYC_C2STRI("_nick"), PSYC_TYPE_NICK}, {PSYC_C2STRI("_page"), PSYC_TYPE_PAGE}, - {PSYC_C2STRI("_uniform"), PSYC_TYPE_UNIFORM}, + {PSYC_C2STRI("_table"), PSYC_TYPE_TABLE}, {PSYC_C2STRI("_time"), PSYC_TYPE_TIME}, + {PSYC_C2STRI("_uniform"), PSYC_TYPE_UNIFORM}, }; const size_t psyc_routing_vars_num = PSYC_NUM_ELEM(psyc_routing_vars); From 5d1659f5f518b431ede43b30547d26e6cc4ef6b8 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sat, 26 Nov 2011 15:03:10 +0100 Subject: [PATCH 349/378] table rendering --- include/psyc.h | 1 + include/psyc/packet.h | 14 ++++++- include/psyc/render.h | 15 ++----- src/packet.c | 40 +++++++++++++------ src/parse.c | 33 ++++++++------- src/render.c | 26 ++++++++++-- src/variable.c | 1 + .../{00-state-sync => 00-state-resync} | 0 test/test_psyc.c | 8 ++-- 9 files changed, 90 insertions(+), 48 deletions(-) rename test/packets/{00-state-sync => 00-state-resync} (100%) diff --git a/include/psyc.h b/include/psyc.h index e04b030..5c3076d 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -71,6 +71,7 @@ typedef enum { PSYC_TYPE_AMOUNT, PSYC_TYPE_COLOR, PSYC_TYPE_COUNTER, + PSYC_TYPE_DEF, PSYC_TYPE_DATE, PSYC_TYPE_DEGREE, PSYC_TYPE_ENTITY, diff --git a/include/psyc/packet.h b/include/psyc/packet.h index 24429a0..8dc92db 100644 --- a/include/psyc/packet.h +++ b/include/psyc/packet.h @@ -89,6 +89,12 @@ typedef struct { PsycListFlag flag; } PsycList; +typedef struct { + PsycList *list; + size_t width; + size_t length; +} PsycTable; + /** Intermediate struct for a PSYC packet */ typedef struct { PsycHeader routing; ///< Routing header. @@ -177,12 +183,16 @@ psyc_packet_length_check (PsycPacket *p); size_t psyc_packet_length_set (PsycPacket *p); -/** Initialize list. */ +/** Initialize a list. */ void psyc_list_init (PsycList *list, PsycString *elems, size_t num_elems, PsycListFlag flag); -/** Initialize packet. */ +/** Initialize a table. */ +void +psyc_table_init (PsycTable *table, size_t width, PsycList *list); + +/** Initialize a packet. */ void psyc_packet_init (PsycPacket *packet, PsycModifier *routing, size_t routinglen, diff --git a/include/psyc/render.h b/include/psyc/render.h index d08174c..4595ed0 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -31,16 +31,6 @@ typedef enum { PSYC_RENDER_SUCCESS = 0, } PsycRenderRC; -/** - * Return codes for psyc_render_list. - */ -typedef enum { - /// Error, buffer is too small to render the list. - PSYC_RENDER_LIST_ERROR = -1, - /// List is rendered successfully in the buffer. - PSYC_RENDER_LIST_SUCCESS = 0, -} PsycRenderListRC; - /** * Render a PSYC packet into a buffer. * @@ -67,9 +57,12 @@ psyc_render (PsycPacket *packet, char *buffer, size_t buflen); #ifdef __INLINE_PSYC_RENDER static inline #endif -PsycRenderListRC +PsycRenderRC psyc_render_list (PsycList *list, char *buffer, size_t buflen); +PsycRenderRC +psyc_render_table (PsycTable *table, char *buffer, size_t buflen); + /** @} */ // end of render group #endif diff --git a/src/packet.c b/src/packet.c index 6626812..c61ee8d 100644 --- a/src/packet.c +++ b/src/packet.c @@ -3,7 +3,7 @@ #include inline PsycListFlag -psyc_list_length_check (PsycList * list) +psyc_list_length_check (PsycList *list) { PsycListFlag flag = PSYC_LIST_NO_LENGTH; size_t i, length = 0; @@ -23,7 +23,7 @@ psyc_list_length_check (PsycList * list) } inline PsycListFlag -psyc_list_length (PsycList * list) +psyc_list_length (PsycList *list) { size_t i, length = 0; @@ -42,12 +42,16 @@ psyc_list_length (PsycList * list) return length; } -inline void -psyc_list_init (PsycList * list, PsycString * elems, size_t num_elems, +void +psyc_list_init (PsycList *list, PsycString *elems, size_t num_elems, PsycListFlag flag) { *list = (PsycList) { - num_elems, elems, 0, flag}; + .num_elems = num_elems, + .elems = elems, + .length = 0, + .flag = flag, + }; if (flag == PSYC_LIST_CHECK_LENGTH) // check if list elements need length list->flag = psyc_list_length_check(list); @@ -55,9 +59,19 @@ psyc_list_init (PsycList * list, PsycString * elems, size_t num_elems, list->length = psyc_list_length(list); } +void +psyc_table_init (PsycTable *table, size_t width, PsycList *list) +{ + *table = (PsycTable) { + .width = width, + .list = list, + }; + + table->length = (width > 0 ? psyc_num_length(width) + 2 : 0) + list->length; +} inline size_t -psyc_modifier_length (PsycModifier * m) +psyc_modifier_length (PsycModifier *m) { size_t length = 2; // oper\n if (m->name.length > 0) @@ -70,7 +84,7 @@ psyc_modifier_length (PsycModifier * m) } inline PsycPacketFlag -psyc_packet_length_check (PsycPacket * p) +psyc_packet_length_check (PsycPacket *p) { if (p->data.length == 1 && p->data.data[0] == PSYC_PACKET_DELIMITER_CHAR) return PSYC_PACKET_NEED_LENGTH; @@ -92,7 +106,7 @@ psyc_packet_length_check (PsycPacket * p) } inline size_t -psyc_packet_length_set (PsycPacket * p) +psyc_packet_length_set (PsycPacket *p) { size_t i; p->routinglen = 0; @@ -133,9 +147,9 @@ psyc_packet_length_set (PsycPacket * p) } inline void -psyc_packet_init (PsycPacket * p, - PsycModifier * routing, size_t routinglen, - PsycModifier * entity, size_t entitylen, +psyc_packet_init (PsycPacket *p, + PsycModifier *routing, size_t routinglen, + PsycModifier *entity, size_t entitylen, char *method, size_t methodlen, char *data, size_t datalen, char stateop, PsycPacketFlag flag) @@ -160,8 +174,8 @@ psyc_packet_init (PsycPacket * p, } inline void -psyc_packet_init_raw (PsycPacket * p, - PsycModifier * routing, size_t routinglen, +psyc_packet_init_raw (PsycPacket *p, + PsycModifier *routing, size_t routinglen, char *content, size_t contentlen, PsycPacketFlag flag) { diff --git a/src/parse.c b/src/parse.c index 0ccf9c5..f4701fe 100644 --- a/src/parse.c +++ b/src/parse.c @@ -164,6 +164,10 @@ psyc_parse (PsycParseState *state, char *oper, // in case we return insufficent, we rewind to this position. state->startc = state->cursor; + if (state->flags & PSYC_PARSE_START_AT_CONTENT + && (state->buffer.length == 0 || state->cursor >= state->buffer.length - 1)) + return PSYC_PARSE_COMPLETE; + // First we test if we can access the first char. if (state->cursor >= state->buffer.length) // Cursor is not inside the length. return PSYC_PARSE_INSUFFICIENT; @@ -263,22 +267,23 @@ psyc_parse (PsycParseState *state, char *oper, // In the body, the same applies, only that the // method does not start with a glyph. if (psyc_is_glyph(state->buffer.data[state->cursor])) { - ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); - if (state->content_parsed == 0 - && state->buffer.data[state->cursor] == '\n') { - *oper = *(state->buffer.data + state->cursor - 1); - switch (*oper) { - case PSYC_STATE_RESYNC: - state->content_parsed += 2; - return PSYC_PARSE_STATE_RESYNC; - case PSYC_STATE_RESET: - state->content_parsed += 2; - return PSYC_PARSE_STATE_RESET; - default: - return PSYC_PARSE_ERROR_MOD_NAME; + if (state->content_parsed == 0) { + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + if (state->buffer.data[state->cursor] == '\n') { + *oper = *(state->buffer.data + state->cursor - 1); + switch (*oper) { + case PSYC_STATE_RESYNC: + state->content_parsed++; + return PSYC_PARSE_STATE_RESYNC; + case PSYC_STATE_RESET: + state->content_parsed++; + return PSYC_PARSE_STATE_RESET; + default: + return PSYC_PARSE_ERROR_MOD_NAME; + } } + state->cursor--; } - state->cursor--; ret = psyc_parse_modifier(state, oper, name, value); state->content_parsed += state->cursor - pos; diff --git a/src/render.c b/src/render.c index 72508cc..9ba51ff 100644 --- a/src/render.c +++ b/src/render.c @@ -6,14 +6,14 @@ #ifdef __INLINE_PSYC_RENDER static inline #endif -PsycRenderListRC -psyc_render_list (PsycList * list, char *buffer, size_t buflen) +PsycRenderRC +psyc_render_list (PsycList *list, char *buffer, size_t buflen) { size_t i, cur = 0; PsycString *elem; if (list->length > buflen) // return error if list doesn't fit in buffer - return PSYC_RENDER_LIST_ERROR; + return PSYC_RENDER_ERROR; if (list->flag == PSYC_LIST_NEED_LENGTH) { for (i = 0; i < list->num_elems; i++) { @@ -34,9 +34,27 @@ psyc_render_list (PsycList * list, char *buffer, size_t buflen) } } +#ifdef DEBUG // Actual length should be equal to pre-calculated length at this point. assert(cur == list->length); - return PSYC_RENDER_LIST_SUCCESS; +#endif + return PSYC_RENDER_SUCCESS; +} + +PsycRenderRC +psyc_render_table (PsycTable *table, char *buffer, size_t buflen) +{ + size_t cur = 0; + + if (table->length > buflen) // return error if table doesn't fit in buffer + return PSYC_RENDER_ERROR; + + if (table->width > 0) { + cur = sprintf(buffer, "*%ld", table->width); + buffer[cur++] = ' '; + } + + return psyc_render_list(table->list, buffer + cur, buflen - cur); } static inline size_t diff --git a/src/variable.c b/src/variable.c index e762b74..396dc39 100644 --- a/src/variable.c +++ b/src/variable.c @@ -31,6 +31,7 @@ const PsycDictInt psyc_var_types[] = { {PSYC_C2STRI("_amount"), PSYC_TYPE_AMOUNT}, {PSYC_C2STRI("_color"), PSYC_TYPE_COLOR}, {PSYC_C2STRI("_date"), PSYC_TYPE_DATE}, + {PSYC_C2STRI("_def"), PSYC_TYPE_DEF}, {PSYC_C2STRI("_degree"), PSYC_TYPE_DEGREE}, {PSYC_C2STRI("_entity"), PSYC_TYPE_ENTITY}, {PSYC_C2STRI("_flag"), PSYC_TYPE_FLAG}, diff --git a/test/packets/00-state-sync b/test/packets/00-state-resync similarity index 100% rename from test/packets/00-state-sync rename to test/packets/00-state-resync diff --git a/test/test_psyc.c b/test/test_psyc.c index 18bfe9c..55699e1 100644 --- a/test/test_psyc.c +++ b/test/test_psyc.c @@ -170,8 +170,8 @@ test_input (int i, char *recvbuf, size_t nbytes) } // reset packet - packet->routingLength = 0; - packet->contentLength = 0; + packet->routinglen = 0; + packet->contentlen = 0; packet->length = 0; packet->flag = 0; @@ -262,7 +262,7 @@ test_input (int i, char *recvbuf, size_t nbytes) if (verbose >= 2) { printf("[%.*s]", (int)pvalue->length, pvalue->data); - if (parser->valueLength > pvalue->length) + if (parser->valuelen > pvalue->length) printf("..."); printf("\n"); } @@ -273,7 +273,7 @@ test_input (int i, char *recvbuf, size_t nbytes) if (verbose >= 3) printf("\t\t\t\t\t\t\t\t# n:%ld v:%ld c:%ld r:%ld\n", pname->length, pvalue->length, - parser->contentParsed, parser->routingLength); + parser->content_parsed, parser->routinglen); } switch (ret) { From 1aa08235b7452c39169c0b9c7f46c7ee138b8854 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 28 Nov 2011 14:00:41 +0100 Subject: [PATCH 350/378] psyc_method_family() --- include/psyc.h | 8 +++++ include/psyc/packet.h | 15 +++++++++ include/psyc/variable.h | 11 +++++-- src/variable.c | 73 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 104 insertions(+), 3 deletions(-) diff --git a/include/psyc.h b/include/psyc.h index 5c3076d..1a3506a 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -94,6 +94,14 @@ typedef enum { PSYC_LIST_BINARY = 2, } PsycListType; +typedef enum PsycMessageFlag { + PSYC_MESSAGE_TEMPLATE = 1 << 0, + PSYC_MESSAGE_REPLY = 1 << 1, + PSYC_MESSAGE_VISIBLE = 1 << 2, + PSYC_MESSAGE_LOGGABLE = 1 << 3, + PSYC_MESSAGE_MANUAL = 1 << 4, +} PsycMessageFlag; + /** * String struct. * diff --git a/include/psyc/packet.h b/include/psyc/packet.h index 8dc92db..1b81cff 100644 --- a/include/psyc/packet.h +++ b/include/psyc/packet.h @@ -67,6 +67,21 @@ typedef enum { PSYC_STATE_RESYNC = '?', } PsycStateOp; +typedef enum PsycMethod { + PSYC_METHOD_UNKNOWN, + PSYC_METHOD_DATA, + PSYC_METHOD_ECHO, + PSYC_METHOD_ERROR, + PSYC_METHOD_FAILURE, + PSYC_METHOD_INFO, + PSYC_METHOD_MESSAGE, + PSYC_METHOD_MESSAGE_ECHO, + PSYC_METHOD_NOTICE, + PSYC_METHOD_REQUEST, + PSYC_METHOD_STATUS, + PSYC_METHOD_WARNING, +} PsycMethod; + /** Structure for a modifier. */ typedef struct { char oper; diff --git a/include/psyc/variable.h b/include/psyc/variable.h index 957698e..fb9ce67 100644 --- a/include/psyc/variable.h +++ b/include/psyc/variable.h @@ -1,10 +1,12 @@ -#ifndef PSYC_VARIABLE_H -#define PSYC_VARIABLE_H - /** * @file psyc/variable.h */ +#ifndef PSYC_VARIABLE_H +#define PSYC_VARIABLE_H + +#include "packet.h" + /// Routing variables in alphabetical order. extern const PsycString psyc_routing_vars[]; @@ -36,4 +38,7 @@ psyc_var_is_list (const char *name, size_t len) ? PSYC_FALSE : PSYC_TRUE; } +PsycMethod +psyc_method_family (char *method, size_t methodlen, unsigned int *flag); + #endif diff --git a/src/variable.c b/src/variable.c index 396dc39..e202757 100644 --- a/src/variable.c +++ b/src/variable.c @@ -1,6 +1,8 @@ #include "lib.h" #include +#include + /// Routing variables in alphabetical order. const PsycString psyc_routing_vars[] = { @@ -44,8 +46,22 @@ const PsycDictInt psyc_var_types[] = { {PSYC_C2STRI("_uniform"), PSYC_TYPE_UNIFORM}, }; +const PsycDictInt psyc_method_families[] = { + {PSYC_C2STRI("_data"), PSYC_METHOD_DATA}, + {PSYC_C2STRI("_echo"), PSYC_METHOD_ECHO}, + {PSYC_C2STRI("_failure"), PSYC_METHOD_FAILURE}, + {PSYC_C2STRI("_info"), PSYC_METHOD_INFO}, + {PSYC_C2STRI("_message"), PSYC_METHOD_MESSAGE}, + {PSYC_C2STRI("_message_echo"), PSYC_METHOD_MESSAGE_ECHO}, + {PSYC_C2STRI("_notice"), PSYC_METHOD_NOTICE}, + {PSYC_C2STRI("_request"), PSYC_METHOD_REQUEST}, + {PSYC_C2STRI("_status"), PSYC_METHOD_STATUS}, + {PSYC_C2STRI("_warning"), PSYC_METHOD_WARNING}, +}; + const size_t psyc_routing_vars_num = PSYC_NUM_ELEM(psyc_routing_vars); const size_t psyc_var_types_num = PSYC_NUM_ELEM(psyc_var_types); +const size_t psyc_method_families_num = PSYC_NUM_ELEM(psyc_method_families); /** * Get the type of variable name. @@ -97,3 +113,60 @@ psyc_var_type (const char *name, size_t len) psyc_var_types_num, name, len, PSYC_YES, (int8_t *) &m); } + +/** + * Get the family and flags for a method. + */ +PsycMethod +psyc_method_family (char *method, size_t methodlen, unsigned int *flag) +{ + int8_t tmp[PSYC_NUM_ELEM(psyc_method_families)]; + int mc = psyc_dict_lookup_int(psyc_method_families, psyc_method_families_num, + method, methodlen, PSYC_YES, tmp); + + if (!flag) + return mc; + + switch (mc) { + case PSYC_METHOD_DATA: + break; + case PSYC_METHOD_ECHO: + *flag = PSYC_MESSAGE_TEMPLATE | PSYC_MESSAGE_REPLY | PSYC_MESSAGE_VISIBLE; + break; + case PSYC_METHOD_ERROR: + *flag = PSYC_MESSAGE_TEMPLATE | PSYC_MESSAGE_REPLY | PSYC_MESSAGE_VISIBLE + | PSYC_MESSAGE_LOGGABLE; + break; + case PSYC_METHOD_FAILURE: + *flag = PSYC_MESSAGE_TEMPLATE | PSYC_MESSAGE_REPLY | PSYC_MESSAGE_VISIBLE + | PSYC_MESSAGE_LOGGABLE; + break; + case PSYC_METHOD_INFO: + *flag = PSYC_MESSAGE_TEMPLATE | PSYC_MESSAGE_REPLY | PSYC_MESSAGE_VISIBLE + | PSYC_MESSAGE_LOGGABLE; + break; + case PSYC_METHOD_MESSAGE: + *flag = PSYC_MESSAGE_VISIBLE | PSYC_MESSAGE_LOGGABLE | PSYC_MESSAGE_MANUAL; + break; + case PSYC_METHOD_MESSAGE_ECHO: + *flag = PSYC_MESSAGE_REPLY | PSYC_MESSAGE_VISIBLE | PSYC_MESSAGE_LOGGABLE + | PSYC_MESSAGE_MANUAL; + break; + case PSYC_METHOD_NOTICE: + *flag = PSYC_MESSAGE_TEMPLATE | PSYC_MESSAGE_VISIBLE | PSYC_MESSAGE_LOGGABLE; + break; + case PSYC_METHOD_REQUEST: + *flag = PSYC_MESSAGE_TEMPLATE | PSYC_MESSAGE_VISIBLE | PSYC_MESSAGE_LOGGABLE; + break; + case PSYC_METHOD_STATUS: + *flag = PSYC_MESSAGE_TEMPLATE | PSYC_MESSAGE_REPLY | PSYC_MESSAGE_VISIBLE + | PSYC_MESSAGE_LOGGABLE; + break; + case PSYC_METHOD_WARNING: + *flag = PSYC_MESSAGE_TEMPLATE | PSYC_MESSAGE_REPLY | PSYC_MESSAGE_VISIBLE + | PSYC_MESSAGE_LOGGABLE; + break; + } + + return mc; +} From 5dd68d87fc8c11aea8bc9c284bcd10b921c2cde8 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 30 Nov 2011 13:51:50 +0100 Subject: [PATCH 351/378] methods & templates --- include/psyc.h | 8 --- include/psyc/method.h | 65 ++++++++++++++++++ include/psyc/packet.h | 20 +----- include/psyc/parse.h | 3 +- include/psyc/render.h | 2 +- include/psyc/text.h | 10 +++ include/psyc/variable.h | 6 +- src/templates.h | 12 ++++ src/text.c | 8 ++- src/variable.c | 149 ++++++++++++++++++++++++---------------- test/test_text.c | 6 +- 11 files changed, 197 insertions(+), 92 deletions(-) create mode 100644 include/psyc/method.h create mode 100644 src/templates.h diff --git a/include/psyc.h b/include/psyc.h index 1a3506a..5c3076d 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -94,14 +94,6 @@ typedef enum { PSYC_LIST_BINARY = 2, } PsycListType; -typedef enum PsycMessageFlag { - PSYC_MESSAGE_TEMPLATE = 1 << 0, - PSYC_MESSAGE_REPLY = 1 << 1, - PSYC_MESSAGE_VISIBLE = 1 << 2, - PSYC_MESSAGE_LOGGABLE = 1 << 3, - PSYC_MESSAGE_MANUAL = 1 << 4, -} PsycMessageFlag; - /** * String struct. * diff --git a/include/psyc/method.h b/include/psyc/method.h new file mode 100644 index 0000000..e58896f --- /dev/null +++ b/include/psyc/method.h @@ -0,0 +1,65 @@ +#ifndef PSYC_METHOD_H +#define PSYC_METHOD_H + +typedef enum PsycMethodFlag { + PSYC_METHOD_TEMPLATE = 1 << 0, + PSYC_METHOD_REPLY = 1 << 1, + PSYC_METHOD_VISIBLE = 1 << 2, + PSYC_METHOD_LOGGABLE = 1 << 3, + PSYC_METHOD_MANUAL = 1 << 4, +} PsycMethodFlag; + +typedef enum PsycMethod { + PSYC_MC_UNKNOWN, + + PSYC_MC_DATA, + PSYC_MC_ECHO, + PSYC_MC_ECHO_CONTEXT_ENTER, + PSYC_MC_ECHO_CONTEXT_LEAVE, + PSYC_MC_ERROR, + PSYC_MC_FAILURE, + PSYC_MC_INFO, + PSYC_MC_MESSAGE, + PSYC_MC_MESSAGE_ACTION, + PSYC_MC_MESSAGE_ECHO, + PSYC_MC_MESSAGE_ECHO_ACTION, + PSYC_MC_NOTICE, + PSYC_MC_NOTICE_CONTEXT_ENTER, + PSYC_MC_NOTICE_CONTEXT_LEAVE, + PSYC_MC_REQUEST, + PSYC_MC_REQUEST_CONTEXT_ENTER, + PSYC_MC_REQUEST_CONTEXT_LEAVE, + PSYC_MC_STATUS, + PSYC_MC_STATUS_CONTEXTS_ENTERED, + PSYC_MC_WARNING, + + PSYC_METHODS_NUM, +} PsycMethod; + +typedef union PsycTemplates { + PsycString a[PSYC_METHODS_NUM]; + struct { + PsycString _; + PsycString _data; + PsycString _echo; + PsycString _echo_context_enter; + PsycString _echo_context_leave; + PsycString _error; + PsycString _failure; + PsycString _info; + PsycString _message; + PsycString _message_action; + PsycString _message_echo_action; + PsycString _notice; + PsycString _notice_context_enter; + PsycString _notice_context_leave; + PsycString _request; + PsycString _request_context_enter; + PsycString _request_context_leave; + PsycString _status; + PsycString _status_contexts_entered; + PsycString _warning; + } s; +} PsycTemplates; + +#endif diff --git a/include/psyc/packet.h b/include/psyc/packet.h index 1b81cff..3e5a979 100644 --- a/include/psyc/packet.h +++ b/include/psyc/packet.h @@ -16,10 +16,11 @@ * @{ */ -#include -#include #include +#include "syntax.h" +#include "method.h" + /** Modifier flags. */ typedef enum { /// Modifier needs to be checked if it needs length. @@ -67,21 +68,6 @@ typedef enum { PSYC_STATE_RESYNC = '?', } PsycStateOp; -typedef enum PsycMethod { - PSYC_METHOD_UNKNOWN, - PSYC_METHOD_DATA, - PSYC_METHOD_ECHO, - PSYC_METHOD_ERROR, - PSYC_METHOD_FAILURE, - PSYC_METHOD_INFO, - PSYC_METHOD_MESSAGE, - PSYC_METHOD_MESSAGE_ECHO, - PSYC_METHOD_NOTICE, - PSYC_METHOD_REQUEST, - PSYC_METHOD_STATUS, - PSYC_METHOD_WARNING, -} PsycMethod; - /** Structure for a modifier. */ typedef struct { char oper; diff --git a/include/psyc/parse.h b/include/psyc/parse.h index 93f64d3..afa6757 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -114,7 +114,8 @@ #include #include -#include + +#include "../psyc.h" typedef enum { /// Default Flag. Parse everything. diff --git a/include/psyc/render.h b/include/psyc/render.h index 4595ed0..4a826db 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -1,7 +1,7 @@ #ifndef PSYC_RENDER_H #define PSYC_RENDER_H -#include +#include "packet.h" /** * @file psyc/render.h diff --git a/include/psyc/text.h b/include/psyc/text.h index 02adbbe..03d7aff 100644 --- a/include/psyc/text.h +++ b/include/psyc/text.h @@ -158,6 +158,16 @@ psyc_text_bytes_written (PsycTextState *state) PsycTextRC psyc_text (PsycTextState *state, PsycTextCB getValue, void *extra); +extern const PsycTemplates psyc_templates; + +static inline const char * +psyc_template (PsycMethod mc, size_t *len) { + PsycString t = psyc_templates.a[mc]; + if (len) + *len = t.length; + return t.data; +} + /** @} */ // end of text group #endif diff --git a/include/psyc/variable.h b/include/psyc/variable.h index fb9ce67..264a79c 100644 --- a/include/psyc/variable.h +++ b/include/psyc/variable.h @@ -13,8 +13,12 @@ extern const PsycString psyc_routing_vars[]; // Variable types in alphabetical order. extern const PsycDictInt psyc_var_types[]; +/// Method names in alphabetical order. +extern const PsycDictInt psyc_methods[]; + extern const size_t psyc_routing_vars_num; extern const size_t psyc_var_types_num; +extern const size_t psyc_methods_num; /** * Is this a routing variable name? @@ -39,6 +43,6 @@ psyc_var_is_list (const char *name, size_t len) } PsycMethod -psyc_method_family (char *method, size_t methodlen, unsigned int *flag); +psyc_method (char *method, size_t methodlen, PsycMethod *family, unsigned int *flag); #endif diff --git a/src/templates.h b/src/templates.h new file mode 100644 index 0000000..46b5acf --- /dev/null +++ b/src/templates.h @@ -0,0 +1,12 @@ +#define _ PSYC_C2STRI + +._echo_context_enter = + _("You enter [_nick_place]" ), +._echo_context_leave = + _("You leave [_nick_place]"), +._notice_context_enter = + _("[_nick] enters [_nick_place]"), +._notice_context_leave = + _("[_nick] leaves [_nick_place]"), +._request_context_enter = + _("[_nick] asks for your permission to enter [_nick_place]"), diff --git a/src/text.c b/src/text.c index 31d1e10..6c91446 100644 --- a/src/text.c +++ b/src/text.c @@ -1,8 +1,12 @@ #include "lib.h" #include +const PsycTemplates psyc_templates = { .s = { +#include "templates.h" +}}; + PsycTextRC -psyc_text (PsycTextState *state, PsycTextCB getValue, void *extra) +psyc_text (PsycTextState *state, PsycTextCB get_value, void *extra) { const char *start = state->tmpl.data, *end; // start & end of variable name const char *prev = state->tmpl.data + state->cursor; @@ -34,7 +38,7 @@ psyc_text (PsycTextState *state, PsycTextCB getValue, void *extra) continue; // [] is invalid, name can't be empty } - ret = getValue(start + state->open.length, + ret = get_value(start + state->open.length, end - start - state->open.length, &value, extra); if (ret < 0) diff --git a/src/variable.c b/src/variable.c index e202757..2c8eeda 100644 --- a/src/variable.c +++ b/src/variable.c @@ -9,7 +9,7 @@ const PsycString psyc_routing_vars[] = { PSYC_C2STRI("_amount_fragments"), PSYC_C2STRI("_context"), //PSYC_C2STRI("_count"), // older PSYC - PSYC_C2STRI("_counter"), // the name for this is supposed to be _count, not _counter + PSYC_C2STRI("_counter"), PSYC_C2STRI("_fragment"), //PSYC_C2STRI("_length"), // older PSYC PSYC_C2STRI("_source"), @@ -30,38 +30,46 @@ const PsycString psyc_routing_vars[] = { // Variable types in alphabetical order. const PsycDictInt psyc_var_types[] = { - {PSYC_C2STRI("_amount"), PSYC_TYPE_AMOUNT}, - {PSYC_C2STRI("_color"), PSYC_TYPE_COLOR}, - {PSYC_C2STRI("_date"), PSYC_TYPE_DATE}, - {PSYC_C2STRI("_def"), PSYC_TYPE_DEF}, - {PSYC_C2STRI("_degree"), PSYC_TYPE_DEGREE}, - {PSYC_C2STRI("_entity"), PSYC_TYPE_ENTITY}, - {PSYC_C2STRI("_flag"), PSYC_TYPE_FLAG}, - {PSYC_C2STRI("_language"), PSYC_TYPE_LANGUAGE}, - {PSYC_C2STRI("_list"), PSYC_TYPE_LIST}, - {PSYC_C2STRI("_nick"), PSYC_TYPE_NICK}, - {PSYC_C2STRI("_page"), PSYC_TYPE_PAGE}, - {PSYC_C2STRI("_table"), PSYC_TYPE_TABLE}, - {PSYC_C2STRI("_time"), PSYC_TYPE_TIME}, - {PSYC_C2STRI("_uniform"), PSYC_TYPE_UNIFORM}, + { PSYC_C2STRI("_amount"), PSYC_TYPE_AMOUNT }, + { PSYC_C2STRI("_color"), PSYC_TYPE_COLOR }, + { PSYC_C2STRI("_date"), PSYC_TYPE_DATE }, + { PSYC_C2STRI("_def"), PSYC_TYPE_DEF }, + { PSYC_C2STRI("_degree"), PSYC_TYPE_DEGREE }, + { PSYC_C2STRI("_entity"), PSYC_TYPE_ENTITY }, + { PSYC_C2STRI("_flag"), PSYC_TYPE_FLAG }, + { PSYC_C2STRI("_language"), PSYC_TYPE_LANGUAGE }, + { PSYC_C2STRI("_list"), PSYC_TYPE_LIST }, + { PSYC_C2STRI("_nick"), PSYC_TYPE_NICK }, + { PSYC_C2STRI("_page"), PSYC_TYPE_PAGE }, + { PSYC_C2STRI("_table"), PSYC_TYPE_TABLE }, + { PSYC_C2STRI("_time"), PSYC_TYPE_TIME }, + { PSYC_C2STRI("_uniform"), PSYC_TYPE_UNIFORM }, }; -const PsycDictInt psyc_method_families[] = { - {PSYC_C2STRI("_data"), PSYC_METHOD_DATA}, - {PSYC_C2STRI("_echo"), PSYC_METHOD_ECHO}, - {PSYC_C2STRI("_failure"), PSYC_METHOD_FAILURE}, - {PSYC_C2STRI("_info"), PSYC_METHOD_INFO}, - {PSYC_C2STRI("_message"), PSYC_METHOD_MESSAGE}, - {PSYC_C2STRI("_message_echo"), PSYC_METHOD_MESSAGE_ECHO}, - {PSYC_C2STRI("_notice"), PSYC_METHOD_NOTICE}, - {PSYC_C2STRI("_request"), PSYC_METHOD_REQUEST}, - {PSYC_C2STRI("_status"), PSYC_METHOD_STATUS}, - {PSYC_C2STRI("_warning"), PSYC_METHOD_WARNING}, +/// Method names in alphabetical order. +const PsycDictInt psyc_methods[] = { + { PSYC_C2STRI("_data"), PSYC_MC_DATA }, + { PSYC_C2STRI("_echo_context_enter"), PSYC_MC_ECHO_CONTEXT_ENTER }, + { PSYC_C2STRI("_echo_context_leave"), PSYC_MC_ECHO_CONTEXT_LEAVE }, + { PSYC_C2STRI("_echo"), PSYC_MC_ECHO }, + { PSYC_C2STRI("_failure"), PSYC_MC_FAILURE }, + { PSYC_C2STRI("_info"), PSYC_MC_INFO }, + { PSYC_C2STRI("_message_echo"), PSYC_MC_MESSAGE_ECHO }, + { PSYC_C2STRI("_message"), PSYC_MC_MESSAGE }, + { PSYC_C2STRI("_notice_context_enter"), PSYC_MC_NOTICE_CONTEXT_ENTER }, + { PSYC_C2STRI("_notice_context_leave"), PSYC_MC_NOTICE_CONTEXT_LEAVE }, + { PSYC_C2STRI("_notice"), PSYC_MC_NOTICE }, + { PSYC_C2STRI("_request_context_enter"), PSYC_MC_REQUEST_CONTEXT_ENTER }, + { PSYC_C2STRI("_request_context_leave"), PSYC_MC_REQUEST_CONTEXT_LEAVE }, + { PSYC_C2STRI("_request"), PSYC_MC_REQUEST }, + { PSYC_C2STRI("_status_contexts_entered"), PSYC_MC_STATUS_CONTEXTS_ENTERED }, + { PSYC_C2STRI("_status"), PSYC_MC_STATUS }, + { PSYC_C2STRI("_warning"), PSYC_MC_WARNING }, }; const size_t psyc_routing_vars_num = PSYC_NUM_ELEM(psyc_routing_vars); const size_t psyc_var_types_num = PSYC_NUM_ELEM(psyc_var_types); -const size_t psyc_method_families_num = PSYC_NUM_ELEM(psyc_method_families); +const size_t psyc_methods_num = PSYC_NUM_ELEM(psyc_methods); /** * Get the type of variable name. @@ -115,57 +123,76 @@ psyc_var_type (const char *name, size_t len) } /** - * Get the family and flags for a method. + * Get the method, its family and its flags. */ PsycMethod -psyc_method_family (char *method, size_t methodlen, unsigned int *flag) +psyc_method (char *method, size_t methodlen, PsycMethod *family, unsigned int *flag) { - int8_t tmp[PSYC_NUM_ELEM(psyc_method_families)]; - int mc = psyc_dict_lookup_int(psyc_method_families, psyc_method_families_num, + int8_t tmp[PSYC_NUM_ELEM(psyc_methods)]; + int mc = psyc_dict_lookup_int(psyc_methods, psyc_methods_num, method, methodlen, PSYC_YES, tmp); - if (!flag) - return mc; - switch (mc) { - case PSYC_METHOD_DATA: + case PSYC_MC_DATA: + *family = PSYC_MC_DATA; + *flag = 0; break; - case PSYC_METHOD_ECHO: - *flag = PSYC_MESSAGE_TEMPLATE | PSYC_MESSAGE_REPLY | PSYC_MESSAGE_VISIBLE; + case PSYC_MC_ECHO: + case PSYC_MC_ECHO_CONTEXT_ENTER: + case PSYC_MC_ECHO_CONTEXT_LEAVE: + *family = PSYC_MC_ECHO; + *flag = PSYC_METHOD_TEMPLATE | PSYC_METHOD_REPLY | PSYC_METHOD_VISIBLE; break; - case PSYC_METHOD_ERROR: - *flag = PSYC_MESSAGE_TEMPLATE | PSYC_MESSAGE_REPLY | PSYC_MESSAGE_VISIBLE - | PSYC_MESSAGE_LOGGABLE; + case PSYC_MC_ERROR: + *family = PSYC_MC_ERROR; + *flag = PSYC_METHOD_TEMPLATE | PSYC_METHOD_REPLY | PSYC_METHOD_VISIBLE + | PSYC_METHOD_LOGGABLE; break; - case PSYC_METHOD_FAILURE: - *flag = PSYC_MESSAGE_TEMPLATE | PSYC_MESSAGE_REPLY | PSYC_MESSAGE_VISIBLE - | PSYC_MESSAGE_LOGGABLE; + case PSYC_MC_FAILURE: + *family = PSYC_MC_FAILURE; + *flag = PSYC_METHOD_TEMPLATE | PSYC_METHOD_REPLY | PSYC_METHOD_VISIBLE + | PSYC_METHOD_LOGGABLE; break; - case PSYC_METHOD_INFO: - *flag = PSYC_MESSAGE_TEMPLATE | PSYC_MESSAGE_REPLY | PSYC_MESSAGE_VISIBLE - | PSYC_MESSAGE_LOGGABLE; + case PSYC_MC_INFO: + *family = PSYC_MC_INFO; + *flag = PSYC_METHOD_TEMPLATE | PSYC_METHOD_REPLY | PSYC_METHOD_VISIBLE + | PSYC_METHOD_LOGGABLE; break; - case PSYC_METHOD_MESSAGE: - *flag = PSYC_MESSAGE_VISIBLE | PSYC_MESSAGE_LOGGABLE | PSYC_MESSAGE_MANUAL; + case PSYC_MC_MESSAGE: + *family = PSYC_MC_MESSAGE; + *flag = PSYC_METHOD_VISIBLE | PSYC_METHOD_LOGGABLE | PSYC_METHOD_MANUAL; break; - case PSYC_METHOD_MESSAGE_ECHO: - *flag = PSYC_MESSAGE_REPLY | PSYC_MESSAGE_VISIBLE | PSYC_MESSAGE_LOGGABLE - | PSYC_MESSAGE_MANUAL; + case PSYC_MC_MESSAGE_ECHO: + *family = PSYC_MC_MESSAGE_ECHO; + *flag = PSYC_METHOD_REPLY | PSYC_METHOD_VISIBLE | PSYC_METHOD_LOGGABLE + | PSYC_METHOD_MANUAL; break; - case PSYC_METHOD_NOTICE: - *flag = PSYC_MESSAGE_TEMPLATE | PSYC_MESSAGE_VISIBLE | PSYC_MESSAGE_LOGGABLE; + case PSYC_MC_NOTICE: + case PSYC_MC_NOTICE_CONTEXT_ENTER: + case PSYC_MC_NOTICE_CONTEXT_LEAVE: + *family = PSYC_MC_NOTICE; + *flag = PSYC_METHOD_TEMPLATE | PSYC_METHOD_VISIBLE | PSYC_METHOD_LOGGABLE; break; - case PSYC_METHOD_REQUEST: - *flag = PSYC_MESSAGE_TEMPLATE | PSYC_MESSAGE_VISIBLE | PSYC_MESSAGE_LOGGABLE; + case PSYC_MC_REQUEST: + case PSYC_MC_REQUEST_CONTEXT_ENTER: + case PSYC_MC_REQUEST_CONTEXT_LEAVE: + *family = PSYC_MC_REQUEST; + *flag = PSYC_METHOD_TEMPLATE | PSYC_METHOD_VISIBLE | PSYC_METHOD_LOGGABLE; break; - case PSYC_METHOD_STATUS: - *flag = PSYC_MESSAGE_TEMPLATE | PSYC_MESSAGE_REPLY | PSYC_MESSAGE_VISIBLE - | PSYC_MESSAGE_LOGGABLE; + case PSYC_MC_STATUS: + case PSYC_MC_STATUS_CONTEXTS_ENTERED: + *family = PSYC_MC_STATUS; + *flag = PSYC_METHOD_TEMPLATE | PSYC_METHOD_REPLY | PSYC_METHOD_VISIBLE + | PSYC_METHOD_LOGGABLE; break; - case PSYC_METHOD_WARNING: - *flag = PSYC_MESSAGE_TEMPLATE | PSYC_MESSAGE_REPLY | PSYC_MESSAGE_VISIBLE - | PSYC_MESSAGE_LOGGABLE; + case PSYC_MC_WARNING: + *family = PSYC_MC_WARNING; + *flag = PSYC_METHOD_TEMPLATE | PSYC_METHOD_REPLY | PSYC_METHOD_VISIBLE + | PSYC_METHOD_LOGGABLE; break; + default: + *family = mc; + *flag = 0; } return mc; diff --git a/test/test_text.c b/test/test_text.c index 40716bb..3d69ea4 100644 --- a/test/test_text.c +++ b/test/test_text.c @@ -99,7 +99,11 @@ main (int argc, char **argv) return 10 + i; } - puts("psyc_text passed all tests."); + size_t tlen = 0; + char *t = psyc_template(PSYC_MC_NOTICE_CONTEXT_ENTER, &tlen); + printf("_notice_context_enter = %s, %ld\n", t, tlen); + + printf("psyc_text passed all tests.\n"); return 0; } From c4d364a70bf5f49a2ea07e531a562e750491d434 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Thu, 1 Dec 2011 14:12:41 +0100 Subject: [PATCH 352/378] PSYC_STRING, func params --- include/psyc.h | 14 +++++---- include/psyc/packet.h | 2 +- include/psyc/parse.h | 16 +++++----- include/psyc/uniform.h | 2 +- src/parse.c | 4 +-- src/render.c | 2 ++ src/uniform.c | 69 ++++++++++++++++-------------------------- test/test_render.c | 6 ++-- test/test_text.c | 2 +- 9 files changed, 53 insertions(+), 64 deletions(-) diff --git a/include/psyc.h b/include/psyc.h index 5c3076d..2ba0d56 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -24,12 +24,14 @@ #define PSYC_VERSION 1 #define PSYC_EPOCH 1440444041 // 2015-08-24 21:20:41 CET (Monday) -#define PSYC_C2STR(str) (PsycString) {sizeof(str)-1, str} -#define PSYC_C2STRI(str) {sizeof(str)-1, str} -#define PSYC_C2ARG(str) str, sizeof(str)-1 -#define PSYC_C2ARG2(str) sizeof(str)-1, str -#define PSYC_S2ARG(str) (str).data, (str).length -#define PSYC_S2ARG2(str) (str).length, (str).data +#define PSYC_STRING(data, len) (PsycString) {len, data} +#define PSYC_C2STR(str) (PsycString) {sizeof(str)-1, str} +#define PSYC_C2STRI(str) {sizeof(str)-1, str} +#define PSYC_C2ARG(str) str, sizeof(str)-1 +#define PSYC_C2ARG2(str) sizeof(str)-1, str +#define PSYC_S2ARG(str) (str).data, (str).length +#define PSYC_S2ARG2(str) (str).length, (str).data +#define PSYC_S2ARGP(str) (int)(str).length, (str).data #define PSYC_NUM_ELEM(a) (sizeof(a) / sizeof(*(a))) diff --git a/include/psyc/packet.h b/include/psyc/packet.h index 3e5a979..7eecd0c 100644 --- a/include/psyc/packet.h +++ b/include/psyc/packet.h @@ -140,7 +140,7 @@ psyc_modifier_length_check (PsycModifier *m) /** Initialize modifier */ static inline void -psyc_modifier_init (PsycModifier *m, char oper, +psyc_modifier_init (PsycModifier *m, PsycOperator oper, char *name, size_t namelen, char *value, size_t valuelen, PsycModifierFlag flag) { diff --git a/include/psyc/parse.h b/include/psyc/parse.h index afa6757..36b0991 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -327,9 +327,9 @@ psyc_parse_state_init (PsycParseState *state, uint8_t flags) * @see PsycString */ static inline void -psyc_parse_buffer_set (PsycParseState *state, char *buffer, size_t length) +psyc_parse_buffer_set (PsycParseState *state, const char *buffer, size_t length) { - state->buffer = (PsycString) {length, buffer}; + state->buffer = (PsycString) {length, (char*)buffer}; state->cursor = 0; if (state->flags & PSYC_PARSE_START_AT_CONTENT) { @@ -351,9 +351,10 @@ psyc_parse_list_state_init (PsycParseListState *state) * Sets a new buffer in the list parser state struct with data to be parsed. */ static inline void -psyc_parse_list_buffer_set (PsycParseListState *state, char *buffer, size_t length) +psyc_parse_list_buffer_set (PsycParseListState *state, + const char *buffer, size_t length) { - state->buffer = (PsycString) {length, buffer}; + state->buffer = (PsycString) {length, (char*)buffer}; state->cursor = 0; } @@ -377,9 +378,10 @@ psyc_parse_table_state_init (PsycParseTableState *state) * Sets a new buffer in the list parser state struct with data to be parsed. */ static inline void -psyc_parse_table_buffer_set (PsycParseTableState *state, char *buffer, size_t length) +psyc_parse_table_buffer_set (PsycParseTableState *state, + const char *buffer, size_t length) { - state->buffer = (PsycString) {length, buffer}; + state->buffer = (PsycString) {length, (char*)buffer}; state->cursor = 0; } @@ -526,7 +528,7 @@ psyc_parse_index (const char *value, size_t len, int64_t *n) * Glyphs are: : = + - ? ! */ static inline PsycBool -psyc_is_glyph (char g) +psyc_is_oper (char g) { switch (g) { case ':': diff --git a/include/psyc/uniform.h b/include/psyc/uniform.h index e69599c..0200519 100644 --- a/include/psyc/uniform.h +++ b/include/psyc/uniform.h @@ -79,6 +79,6 @@ typedef enum { } PsycEntityType; int -psyc_uniform_parse (PsycUniform * uni, char *str, size_t length); +psyc_uniform_parse (PsycUniform *uni, const char *buffer, size_t length); #endif diff --git a/src/parse.c b/src/parse.c index f4701fe..f621491 100644 --- a/src/parse.c +++ b/src/parse.c @@ -193,7 +193,7 @@ psyc_parse (PsycParseState *state, char *oper, // 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 (psyc_is_glyph(state->buffer.data[state->cursor])) { + if (psyc_is_oper(state->buffer.data[state->cursor])) { // it is a glyph, so a variable starts here ret = psyc_parse_modifier(state, oper, name, value); state->routinglen += state->cursor - pos; @@ -266,7 +266,7 @@ psyc_parse (PsycParseState *state, char *oper, // 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 (psyc_is_glyph(state->buffer.data[state->cursor])) { + if (psyc_is_oper(state->buffer.data[state->cursor])) { if (state->content_parsed == 0) { ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); if (state->buffer.data[state->cursor] == '\n') { diff --git a/src/render.c b/src/render.c index 9ba51ff..0db289d 100644 --- a/src/render.c +++ b/src/render.c @@ -1,3 +1,5 @@ +#include + #include "lib.h" #include #include diff --git a/src/uniform.c b/src/uniform.c index 5a68ca3..e7a9fbf 100644 --- a/src/uniform.c +++ b/src/uniform.c @@ -4,21 +4,20 @@ #include "psyc/parse.h" int -psyc_uniform_parse (PsycUniform *uni, char *str, size_t length) +psyc_uniform_parse (PsycUniform *uni, const char *buffer, size_t length) { char c; PsycString *p; + char *data = (char*)buffer; size_t pos = 0, part = PSYC_UNIFORM_SCHEME; uni->valid = 0; - uni->full.data = str; - uni->full.length = length; + uni->full = PSYC_STRING(data, length); while (pos < length) { - c = str[pos]; + c = data[pos]; if (c == ':') { - uni->scheme.data = str; - uni->scheme.length = pos++; + uni->scheme = PSYC_STRING(data, pos++); break; } else if (!psyc_is_host_char(c)) return PSYC_PARSE_UNIFORM_INVALID_SCHEME; @@ -32,11 +31,10 @@ psyc_uniform_parse (PsycUniform *uni, char *str, size_t length) tolower(p->data[3]) == 'c')) { uni->type = PSYC_SCHEME_PSYC; part = PSYC_UNIFORM_SLASHES; - uni->slashes.data = str + pos; - uni->slashes.length = 0; + uni->slashes = PSYC_STRING(data + pos, 0); while (pos < length) { - c = str[pos]; + c = data[pos]; switch (part) { case PSYC_UNIFORM_SLASHES: if (c == '/') @@ -46,8 +44,7 @@ psyc_uniform_parse (PsycUniform *uni, char *str, size_t length) if (uni->slashes.length == 2) { part = PSYC_UNIFORM_HOST; - uni->host.data = str + pos + 1; - uni->host.length = 0; + uni->host = PSYC_STRING(data + pos + 1, 0); } break; @@ -64,16 +61,14 @@ psyc_uniform_parse (PsycUniform *uni, char *str, size_t length) part = PSYC_UNIFORM_PORT; p = &uni->port; } else if (c == '/') { - uni->slash.data = str + pos; - uni->slash.length = 1; + uni->slash = PSYC_STRING(data + pos, 1); part = PSYC_UNIFORM_RESOURCE; p = &uni->resource; } else return PSYC_PARSE_UNIFORM_INVALID_HOST; - p->data = str + pos + 1; - p->length = 0; + *p = PSYC_STRING(data + pos + 1, 0); break; case PSYC_UNIFORM_PORT: @@ -86,17 +81,14 @@ psyc_uniform_parse (PsycUniform *uni, char *str, size_t length) return PSYC_PARSE_UNIFORM_INVALID_PORT; if (c == '/') { - uni->slash.data = str + pos; - uni->slash.length = 1; + uni->slash = PSYC_STRING(data + pos, 1); part = PSYC_UNIFORM_RESOURCE; - uni->resource.data = str + pos + 1; - uni->resource.length = 0; + uni->resource = PSYC_STRING(data + pos + 1, 0); break; } else { part = PSYC_UNIFORM_TRANSPORT; - uni->transport.data = str + pos; - uni->transport.length = 0; + uni->transport = PSYC_STRING(data + pos, 0); } // fall thru @@ -113,12 +105,10 @@ psyc_uniform_parse (PsycUniform *uni, char *str, size_t length) uni->transport.length++; break; case '/': - uni->slash.data = str + pos; - uni->slash.length = 1; + uni->slash = PSYC_STRING(data + pos, 1); part = PSYC_UNIFORM_RESOURCE; - uni->resource.data = str + pos + 1; - uni->resource.length = 0; + uni->resource = PSYC_STRING(data + pos + 1, 0); break; default: return PSYC_PARSE_UNIFORM_INVALID_TRANSPORT; @@ -131,8 +121,7 @@ psyc_uniform_parse (PsycUniform *uni, char *str, size_t length) break; } else if (c == '#') { part = PSYC_UNIFORM_CHANNEL; - uni->channel.data = str + pos + 1; - uni->channel.length = 0; + uni->channel = PSYC_STRING(data + pos + 1, 0); break; } else return PSYC_PARSE_UNIFORM_INVALID_RESOURCE; @@ -150,28 +139,22 @@ psyc_uniform_parse (PsycUniform *uni, char *str, size_t length) if (uni->host.length == 0) return PSYC_PARSE_UNIFORM_INVALID_HOST; - uni->host_port.data = uni->host.data; - uni->host_port.length = uni->host.length + uni->port.length - + uni->transport.length; - + uni->host_port = PSYC_STRING(uni->host.data, uni->host.length + + uni->port.length + uni->transport.length); if (uni->port.length > 0 || uni->transport.length > 0) uni->host_port.length++; - uni->root.data = str; - uni->root.length = uni->scheme.length + 1 - + uni->slashes.length + uni->host_port.length; + uni->root = PSYC_STRING(data, uni->scheme.length + 1 + + uni->slashes.length + uni->host_port.length); - uni->entity.data = str; - uni->entity.length = uni->root.length + uni->slash.length - + uni->resource.length; + uni->entity = PSYC_STRING(data, uni->root.length + uni->slash.length + + uni->resource.length); - uni->body.data = uni->host.data; - uni->body.length = length - uni->scheme.length - 1 - uni->slashes.length; + uni->body = PSYC_STRING(uni->host.data, + length - uni->scheme.length - 1 - uni->slashes.length); - if (uni->resource.length) { - uni->nick.data = uni->resource.data + 1; - uni->nick.length = uni->resource.length; - } + if (uni->resource.length) + uni->nick = PSYC_STRING(uni->resource.data + 1, uni->resource.length); } else return PSYC_PARSE_UNIFORM_INVALID_SCHEME; diff --git a/test/test_render.c b/test/test_render.c index 506b384..be57804 100644 --- a/test/test_render.c +++ b/test/test_render.c @@ -8,9 +8,9 @@ /* example renderer generating a presence packet */ int -testPresence (const char *avail, int availlen, - const char *desc, int desclen, - const char *rendered, uint8_t verbose) +testPresence (char *avail, int availlen, + char *desc, int desclen, + char *rendered, uint8_t verbose) { PsycModifier routing[1]; psyc_modifier_init(&routing[0], PSYC_OPERATOR_SET, diff --git a/test/test_text.c b/test/test_text.c index 3d69ea4..977a66e 100644 --- a/test/test_text.c +++ b/test/test_text.c @@ -100,7 +100,7 @@ main (int argc, char **argv) } size_t tlen = 0; - char *t = psyc_template(PSYC_MC_NOTICE_CONTEXT_ENTER, &tlen); + const char *t = psyc_template(PSYC_MC_NOTICE_CONTEXT_ENTER, &tlen); printf("_notice_context_enter = %s, %ld\n", t, tlen); printf("psyc_text passed all tests.\n"); From 60fc690d81e5e34e39fdd53eaec83cd8823f843f Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sat, 3 Dec 2011 14:34:29 +0100 Subject: [PATCH 353/378] psyc_entity_type(), _action methods --- include/psyc/uniform.h | 25 +++++++++++++++++++++++++ src/uniform.c | 5 +++++ src/variable.c | 4 ++++ 3 files changed, 34 insertions(+) diff --git a/include/psyc/uniform.h b/include/psyc/uniform.h index 0200519..1e65e53 100644 --- a/include/psyc/uniform.h +++ b/include/psyc/uniform.h @@ -78,7 +78,32 @@ typedef enum { PSYC_ENTITY_SERVICE = '$', } PsycEntityType; +/** + * Parse uniform. + * + * @return PsycScheme on success, PsycParseUniformRC on error. + */ int psyc_uniform_parse (PsycUniform *uni, const char *buffer, size_t length); +/** + * Get entity type. + * + * @return PsycEntityType on success, PSYC_ERROR on error. + */ +static inline int +psyc_entity_type (char entity) +{ + switch (entity) { + case PSYC_ENTITY_PERSON: + return PSYC_ENTITY_PERSON; + case PSYC_ENTITY_PLACE: + return PSYC_ENTITY_PLACE; + case PSYC_ENTITY_SERVICE: + return PSYC_ENTITY_SERVICE; + default: + return PSYC_ERROR; + } +} + #endif diff --git a/src/uniform.c b/src/uniform.c index e7a9fbf..f805999 100644 --- a/src/uniform.c +++ b/src/uniform.c @@ -3,6 +3,11 @@ #include "psyc/uniform.h" #include "psyc/parse.h" +/** + * Parse uniform. + * + * @return PsycScheme on success, PsycParseUniformRC on error. + */ int psyc_uniform_parse (PsycUniform *uni, const char *buffer, size_t length) { diff --git a/src/variable.c b/src/variable.c index 2c8eeda..253c0bd 100644 --- a/src/variable.c +++ b/src/variable.c @@ -54,6 +54,8 @@ const PsycDictInt psyc_methods[] = { { PSYC_C2STRI("_echo"), PSYC_MC_ECHO }, { PSYC_C2STRI("_failure"), PSYC_MC_FAILURE }, { PSYC_C2STRI("_info"), PSYC_MC_INFO }, + { PSYC_C2STRI("_message_action"), PSYC_MC_MESSAGE_ACTION }, + { PSYC_C2STRI("_message_echo_action"), PSYC_MC_MESSAGE_ECHO_ACTION }, { PSYC_C2STRI("_message_echo"), PSYC_MC_MESSAGE_ECHO }, { PSYC_C2STRI("_message"), PSYC_MC_MESSAGE }, { PSYC_C2STRI("_notice_context_enter"), PSYC_MC_NOTICE_CONTEXT_ENTER }, @@ -159,10 +161,12 @@ psyc_method (char *method, size_t methodlen, PsycMethod *family, unsigned int *f | PSYC_METHOD_LOGGABLE; break; case PSYC_MC_MESSAGE: + case PSYC_MC_MESSAGE_ACTION: *family = PSYC_MC_MESSAGE; *flag = PSYC_METHOD_VISIBLE | PSYC_METHOD_LOGGABLE | PSYC_METHOD_MANUAL; break; case PSYC_MC_MESSAGE_ECHO: + case PSYC_MC_MESSAGE_ECHO_ACTION: *family = PSYC_MC_MESSAGE_ECHO; *flag = PSYC_METHOD_REPLY | PSYC_METHOD_VISIBLE | PSYC_METHOD_LOGGABLE | PSYC_METHOD_MANUAL; From a6a795e5a85924afb77e3ff07bb429fa90977c8e Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Sun, 4 Dec 2011 15:04:48 +0100 Subject: [PATCH 354/378] install .h --- include/psyc/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/psyc/Makefile b/include/psyc/Makefile index daad9c8..dd2fee0 100644 --- a/include/psyc/Makefile +++ b/include/psyc/Makefile @@ -4,7 +4,7 @@ prefix = /usr includedir = ${prefix}/include INSTALL = install -HEADERS = packet.h parse.h render.h syntax.h text.h +HEADERS = packet.h parse.h render.h syntax.h text.h uniform.h variable.h method.h install: ${HEADERS} From f7a16b85648717405be261dcaafb7d8efc068fb0 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Sun, 4 Dec 2011 15:05:51 +0100 Subject: [PATCH 355/378] method.h --- include/psyc/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/psyc/Makefile b/include/psyc/Makefile index dd2fee0..80d522c 100644 --- a/include/psyc/Makefile +++ b/include/psyc/Makefile @@ -4,7 +4,7 @@ prefix = /usr includedir = ${prefix}/include INSTALL = install -HEADERS = packet.h parse.h render.h syntax.h text.h uniform.h variable.h method.h +HEADERS = method.h packet.h parse.h render.h syntax.h text.h uniform.h variable.h install: ${HEADERS} From 946c56c100adc0d568f3a6dba1d061b49c882726 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 27 Dec 2011 17:50:25 +0100 Subject: [PATCH 356/378] hello methods --- include/psyc.h | 1 + include/psyc/method.h | 4 ++++ src/templates.h | 4 ++++ src/variable.c | 3 +++ 4 files changed, 12 insertions(+) diff --git a/include/psyc.h b/include/psyc.h index 2ba0d56..9a1a7bb 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -28,6 +28,7 @@ #define PSYC_C2STR(str) (PsycString) {sizeof(str)-1, str} #define PSYC_C2STRI(str) {sizeof(str)-1, str} #define PSYC_C2ARG(str) str, sizeof(str)-1 +#define PSYC_C2ARG1(str) str, sizeof(str) #define PSYC_C2ARG2(str) sizeof(str)-1, str #define PSYC_S2ARG(str) (str).data, (str).length #define PSYC_S2ARG2(str) (str).length, (str).data diff --git a/include/psyc/method.h b/include/psyc/method.h index e58896f..cb41300 100644 --- a/include/psyc/method.h +++ b/include/psyc/method.h @@ -31,6 +31,7 @@ typedef enum PsycMethod { PSYC_MC_REQUEST_CONTEXT_LEAVE, PSYC_MC_STATUS, PSYC_MC_STATUS_CONTEXTS_ENTERED, + PSYC_MC_STATUS_HELLO, PSYC_MC_WARNING, PSYC_METHODS_NUM, @@ -44,11 +45,13 @@ typedef union PsycTemplates { PsycString _echo; PsycString _echo_context_enter; PsycString _echo_context_leave; + PsycString _echo_hello_offer; PsycString _error; PsycString _failure; PsycString _info; PsycString _message; PsycString _message_action; + PsycString _message_echo; PsycString _message_echo_action; PsycString _notice; PsycString _notice_context_enter; @@ -58,6 +61,7 @@ typedef union PsycTemplates { PsycString _request_context_leave; PsycString _status; PsycString _status_contexts_entered; + PsycString _status_hello; PsycString _warning; } s; } PsycTemplates; diff --git a/src/templates.h b/src/templates.h index 46b5acf..38c587d 100644 --- a/src/templates.h +++ b/src/templates.h @@ -4,9 +4,13 @@ _("You enter [_nick_place]" ), ._echo_context_leave = _("You leave [_nick_place]"), +._echo_hello_offer = + _("Received hello message"), ._notice_context_enter = _("[_nick] enters [_nick_place]"), ._notice_context_leave = _("[_nick] leaves [_nick_place]"), +._status_hello = + _("Your hello is [_hello]"), ._request_context_enter = _("[_nick] asks for your permission to enter [_nick_place]"), diff --git a/src/variable.c b/src/variable.c index 253c0bd..4db11ec 100644 --- a/src/variable.c +++ b/src/variable.c @@ -60,11 +60,13 @@ const PsycDictInt psyc_methods[] = { { PSYC_C2STRI("_message"), PSYC_MC_MESSAGE }, { PSYC_C2STRI("_notice_context_enter"), PSYC_MC_NOTICE_CONTEXT_ENTER }, { PSYC_C2STRI("_notice_context_leave"), PSYC_MC_NOTICE_CONTEXT_LEAVE }, + { PSYC_C2STRI("_notice_hello"), PSYC_MC_NOTICE_HELLO }, { PSYC_C2STRI("_notice"), PSYC_MC_NOTICE }, { PSYC_C2STRI("_request_context_enter"), PSYC_MC_REQUEST_CONTEXT_ENTER }, { PSYC_C2STRI("_request_context_leave"), PSYC_MC_REQUEST_CONTEXT_LEAVE }, { PSYC_C2STRI("_request"), PSYC_MC_REQUEST }, { PSYC_C2STRI("_status_contexts_entered"), PSYC_MC_STATUS_CONTEXTS_ENTERED }, + { PSYC_C2STRI("_status_hello"), PSYC_MC_STATUS_HELLO }, { PSYC_C2STRI("_status"), PSYC_MC_STATUS }, { PSYC_C2STRI("_warning"), PSYC_MC_WARNING }, }; @@ -185,6 +187,7 @@ psyc_method (char *method, size_t methodlen, PsycMethod *family, unsigned int *f break; case PSYC_MC_STATUS: case PSYC_MC_STATUS_CONTEXTS_ENTERED: + case PSYC_MC_STATUS_HELLO: *family = PSYC_MC_STATUS; *flag = PSYC_METHOD_TEMPLATE | PSYC_METHOD_REPLY | PSYC_METHOD_VISIBLE | PSYC_METHOD_LOGGABLE; From aad05d84834539a0d814f82a6f152f1fa36d698d Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 28 Dec 2011 23:45:16 +0100 Subject: [PATCH 357/378] packet id --- .gitignore | 1 + include/psyc.h | 7 +++++ include/psyc/method.h | 1 + include/psyc/packet.h | 14 +++++++++ include/psyc/render.h | 8 +++++ src/packet.c | 7 +++++ src/render.c | 26 ++++++++++++++++ test/Makefile | 4 ++- test/test_packet_id.c | 70 +++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 test/test_packet_id.c diff --git a/.gitignore b/.gitignore index 83138ed..abeb59a 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ test/test_json_glib test/test_strlen test/test_text test/test_table +test/test_packet_id test/var_is_routing test/var_type test/uniform_parse diff --git a/include/psyc.h b/include/psyc.h index 9a1a7bb..41ace37 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -164,6 +164,13 @@ psyc_dict_lookup_int (const PsycDictInt * dict, size_t size, inherit, tmp); } +#include "psyc/syntax.h" +#include "psyc/method.h" +#include "psyc/packet.h" +#include "psyc/parse.h" +#include "psyc/render.h" +#include "psyc/text.h" +#include "psyc/uniform.h" #include "psyc/variable.h" #endif diff --git a/include/psyc/method.h b/include/psyc/method.h index cb41300..9bbac06 100644 --- a/include/psyc/method.h +++ b/include/psyc/method.h @@ -26,6 +26,7 @@ typedef enum PsycMethod { PSYC_MC_NOTICE, PSYC_MC_NOTICE_CONTEXT_ENTER, PSYC_MC_NOTICE_CONTEXT_LEAVE, + PSYC_MC_NOTICE_HELLO, PSYC_MC_REQUEST, PSYC_MC_REQUEST_CONTEXT_ENTER, PSYC_MC_REQUEST_CONTEXT_LEAVE, diff --git a/include/psyc/packet.h b/include/psyc/packet.h index 7eecd0c..4f37750 100644 --- a/include/psyc/packet.h +++ b/include/psyc/packet.h @@ -68,6 +68,15 @@ typedef enum { PSYC_STATE_RESYNC = '?', } PsycStateOp; +typedef enum { + PSYC_PACKET_ID_CONTEXT = 0, + PSYC_PACKET_ID_SOURCE = 1, + PSYC_PACKET_ID_TARGET = 2, + PSYC_PACKET_ID_COUNTER = 3, + PSYC_PACKET_ID_FRAGMENT = 4, + PSYC_PACKET_ID_ELEMS = 5, +} PsycPacketId; + /** Structure for a modifier. */ typedef struct { char oper; @@ -209,6 +218,11 @@ psyc_packet_init_raw (PsycPacket *packet, char *content, size_t contentlen, PsycPacketFlag flag); +/** Get the total length of a packet ID when rendered. */ +size_t +psyc_packet_id_length (size_t contextlen, size_t sourcelen, size_t targetelen, + size_t counterlen, size_t fragmentlen); + /** @} */ // end of packet group #endif diff --git a/include/psyc/render.h b/include/psyc/render.h index 4a826db..7563ece 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -63,6 +63,14 @@ psyc_render_list (PsycList *list, char *buffer, size_t buflen); PsycRenderRC psyc_render_table (PsycTable *table, char *buffer, size_t buflen); +PsycRenderRC +psyc_render_packet_id (char *context, size_t contextlen, + char *source, size_t sourcelen, + char *target, size_t targetlen, + char *counter, size_t counterlen, + char *fragment, size_t fragmentlen, + char *buffer, size_t buflen); + /** @} */ // end of render group #endif diff --git a/src/packet.c b/src/packet.c index c61ee8d..17bd207 100644 --- a/src/packet.c +++ b/src/packet.c @@ -197,3 +197,10 @@ psyc_packet_init_raw (PsycPacket *p, psyc_packet_length_set(p); } + +size_t +psyc_packet_id_length (size_t contextlen, size_t sourcelen, size_t targetlen, + size_t counterlen, size_t fragmentlen) +{ + return contextlen + sourcelen + targetlen + counterlen + fragmentlen + 5; +} diff --git a/src/render.c b/src/render.c index 0db289d..f0a93fe 100644 --- a/src/render.c +++ b/src/render.c @@ -146,3 +146,29 @@ psyc_render (PsycPacket * packet, char *buffer, size_t buflen) assert(cur == packet->length); return PSYC_RENDER_SUCCESS; } + +PsycRenderRC +psyc_render_packet_id (char *context, size_t contextlen, + char *source, size_t sourcelen, + char *target, size_t targetlen, + char *counter, size_t counterlen, + char *fragment, size_t fragmentlen, + char *buffer, size_t buflen) +{ + PsycList list; + PsycString elems[PSYC_PACKET_ID_ELEMS] = {}; + + if (contextlen) + elems[PSYC_PACKET_ID_CONTEXT] = PSYC_STRING(context, contextlen); + if (sourcelen) + elems[PSYC_PACKET_ID_SOURCE] = PSYC_STRING(source, sourcelen); + if (targetlen) + elems[PSYC_PACKET_ID_TARGET] = PSYC_STRING(target, targetlen); + if (counterlen) + elems[PSYC_PACKET_ID_COUNTER] = PSYC_STRING(counter, counterlen); + if (fragmentlen) + elems[PSYC_PACKET_ID_FRAGMENT] = PSYC_STRING(fragment, fragmentlen); + + psyc_list_init(&list, elems, PSYC_PACKET_ID_ELEMS, PSYC_LIST_NO_LENGTH); + return psyc_render_list(&list, buffer, buflen); +} diff --git a/test/Makefile b/test/Makefile index ba570c3..123de1b 100644 --- a/test/Makefile +++ b/test/Makefile @@ -3,7 +3,7 @@ DEBUG = 2 CFLAGS = -I../include -I../src -Wall -std=c99 ${OPT} LDFLAGS = -L../lib LOADLIBES = -lpsyc -lm -TARGETS = test_psyc test_psyc_speed test_parser test_match test_render test_text var_is_routing var_type uniform_parse test_table +TARGETS = test_psyc test_psyc_speed test_parser test_match test_render test_text var_is_routing var_type uniform_parse test_list test_table test_packet_id O = test.o WRAPPER = DIET = diet @@ -48,7 +48,9 @@ test: ${TARGETS} ./var_is_routing ./var_type ./uniform_parse + ./test_list ./test_table + ./test_packet_id x=0; for f in packets/[0-9]*; do echo ">> $$f"; ./test_psyc -f $$f | ${DIFF} -u $$f -; x=$$((x+$$?)); done; exit $$x x=0; for f in packets/[0-9]*; do echo ">> $$f"; ./test_psyc -rf $$f | ${DIFF} -u $$f -; x=$$((x+$$?)); done; exit $$x diff --git a/test/test_packet_id.c b/test/test_packet_id.c new file mode 100644 index 0000000..c42de6e --- /dev/null +++ b/test/test_packet_id.c @@ -0,0 +1,70 @@ +#include +#include + +#include +#include +#include + +int +packet_id (char *context, size_t contextlen, + char *source, size_t sourcelen, + char *target, size_t targetlen, + char *counter, size_t counterlen, + char *fragment, size_t fragmentlen, + char *result, size_t resultlen) +{ + size_t idlen = psyc_packet_id_length(contextlen, sourcelen, targetlen, + counterlen, fragmentlen); + char *id = malloc(idlen); + psyc_render_packet_id(context, contextlen, + source, sourcelen, + target, targetlen, + counter, counterlen, + fragment, fragmentlen, + id, idlen); + printf("%.*s\n", (int)idlen, id); + int ret = idlen == resultlen && memcmp(result, id, idlen) == 0; + free(id); + return ret; +} + +int +main (int argc, char **argv) +{ + if (!packet_id(PSYC_C2ARG(""), + PSYC_C2ARG("psyc://example.net/~alice"), + PSYC_C2ARG("psyc://example.net/~bob"), + PSYC_C2ARG("1337"), + PSYC_C2ARG("42"), + PSYC_C2ARG("||psyc://example.net/~alice|psyc://example.net/~bob" + "|1337|42"))) + return 1; + + if (!packet_id(PSYC_C2ARG("psyc://example.net/@bar"), + PSYC_C2ARG("psyc://example.net/~alice"), + PSYC_C2ARG(""), + PSYC_C2ARG("1337"), + PSYC_C2ARG("42"), + PSYC_C2ARG("|psyc://example.net/@bar|psyc://example.net/~alice|" + "|1337|42"))) + return 2; + + if (!packet_id(PSYC_C2ARG("psyc://example.net/@bar"), + PSYC_C2ARG(""), + PSYC_C2ARG("psyc://example.net/~alice"), + PSYC_C2ARG("1337"), + PSYC_C2ARG("42"), + PSYC_C2ARG("|psyc://example.net/@bar||psyc://example.net/~alice" + "|1337|42"))) + return 3; + + if (!packet_id(PSYC_C2ARG("psyc://example.net/@bar"), + PSYC_C2ARG(""), + PSYC_C2ARG(""), + PSYC_C2ARG(""), + PSYC_C2ARG(""), + PSYC_C2ARG("|psyc://example.net/@bar||||"))) + return 4; + + return 0; +} From 5fc5c5079a908ada2920b8efde6da9c0f5aa880c Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 4 Jan 2012 23:32:01 +0100 Subject: [PATCH 358/378] psyc_text params --- include/psyc/text.h | 6 +++--- src/render.c | 4 ++-- src/text.c | 6 +++--- test/test_text.c | 6 +++--- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/include/psyc/text.h b/include/psyc/text.h index 03d7aff..0588b65 100644 --- a/include/psyc/text.h +++ b/include/psyc/text.h @@ -62,8 +62,8 @@ typedef struct { * PSYC_TEXT_VALUE_NOT_FOUND if no match found in which case psyc_text * leaves the original template text as is. */ -typedef PsycTextValueRC (*PsycTextCB) (const char *name, size_t len, - PsycString *value, void *extra); +typedef PsycTextValueRC (*PsycTextCB) (void *cls, const char *name, size_t namelen, + PsycString *value); /** * Initializes the PSYC text state struct. @@ -156,7 +156,7 @@ psyc_text_bytes_written (PsycTextState *state) * @see http://about.psyc.eu/psyctext **/ PsycTextRC -psyc_text (PsycTextState *state, PsycTextCB getValue, void *extra); +psyc_text (PsycTextState *state, PsycTextCB get_value, void *get_value_cls); extern const PsycTemplates psyc_templates; diff --git a/src/render.c b/src/render.c index f0a93fe..d61e68e 100644 --- a/src/render.c +++ b/src/render.c @@ -60,7 +60,7 @@ psyc_render_table (PsycTable *table, char *buffer, size_t buflen) } static inline size_t -psyc_render_modifier (PsycModifier * mod, char *buffer) +psyc_render_modifier (PsycModifier *mod, char *buffer) { size_t cur = 0; @@ -87,7 +87,7 @@ psyc_render_modifier (PsycModifier * mod, char *buffer) static inline #endif PsycRenderRC -psyc_render (PsycPacket * packet, char *buffer, size_t buflen) +psyc_render (PsycPacket *packet, char *buffer, size_t buflen) { size_t i, cur = 0, len; diff --git a/src/text.c b/src/text.c index 6c91446..390460d 100644 --- a/src/text.c +++ b/src/text.c @@ -6,7 +6,7 @@ const PsycTemplates psyc_templates = { .s = { }}; PsycTextRC -psyc_text (PsycTextState *state, PsycTextCB get_value, void *extra) +psyc_text (PsycTextState *state, PsycTextCB get_value, void *get_value_cls) { const char *start = state->tmpl.data, *end; // start & end of variable name const char *prev = state->tmpl.data + state->cursor; @@ -38,8 +38,8 @@ psyc_text (PsycTextState *state, PsycTextCB get_value, void *extra) continue; // [] is invalid, name can't be empty } - ret = get_value(start + state->open.length, - end - start - state->open.length, &value, extra); + ret = get_value(get_value_cls, start + state->open.length, + end - start - state->open.length, &value); if (ret < 0) continue; // value not found, no substitution diff --git a/test/test_text.c b/test/test_text.c index 977a66e..cd6bf46 100644 --- a/test/test_text.c +++ b/test/test_text.c @@ -8,7 +8,7 @@ uint8_t verbose; PsycTextValueRC -getValueFooBar (const char *name, size_t len, PsycString *value, void *extra) +getValueFooBar (void *cls, const char *name, size_t len, PsycString *value) { if (verbose) printf("> getValue: %.*s\n", (int)len, name); @@ -18,7 +18,7 @@ getValueFooBar (const char *name, size_t len, PsycString *value, void *extra) } PsycTextValueRC -getValueEmpty (const char *name, size_t len, PsycString *value, void *extra) +getValueEmpty (void *cls, const char *name, size_t len, PsycString *value) { if (verbose) printf("> getValue: %.*s\n", (int)len, name); @@ -28,7 +28,7 @@ getValueEmpty (const char *name, size_t len, PsycString *value, void *extra) } PsycTextValueRC -getValueNotFound (const char *name, size_t len, PsycString *value, void *extra) +getValueNotFound (void *cls, const char *name, size_t len, PsycString *value) { if (verbose) printf("> getValue: %.*s\n", (int)len, name); From 7c87d03d3bfe169e219cdb74c8c0617d7191a277 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 4 Jan 2012 23:33:43 +0100 Subject: [PATCH 359/378] hello methods & templates --- include/psyc/method.h | 4 ++-- src/templates.h | 4 ++-- src/variable.c | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/include/psyc/method.h b/include/psyc/method.h index 9bbac06..23da0e4 100644 --- a/include/psyc/method.h +++ b/include/psyc/method.h @@ -16,6 +16,7 @@ typedef enum PsycMethod { PSYC_MC_ECHO, PSYC_MC_ECHO_CONTEXT_ENTER, PSYC_MC_ECHO_CONTEXT_LEAVE, + PSYC_MC_ECHO_HELLO, PSYC_MC_ERROR, PSYC_MC_FAILURE, PSYC_MC_INFO, @@ -26,7 +27,6 @@ typedef enum PsycMethod { PSYC_MC_NOTICE, PSYC_MC_NOTICE_CONTEXT_ENTER, PSYC_MC_NOTICE_CONTEXT_LEAVE, - PSYC_MC_NOTICE_HELLO, PSYC_MC_REQUEST, PSYC_MC_REQUEST_CONTEXT_ENTER, PSYC_MC_REQUEST_CONTEXT_LEAVE, @@ -46,7 +46,7 @@ typedef union PsycTemplates { PsycString _echo; PsycString _echo_context_enter; PsycString _echo_context_leave; - PsycString _echo_hello_offer; + PsycString _echo_hello; PsycString _error; PsycString _failure; PsycString _info; diff --git a/src/templates.h b/src/templates.h index 38c587d..da6548d 100644 --- a/src/templates.h +++ b/src/templates.h @@ -4,8 +4,8 @@ _("You enter [_nick_place]" ), ._echo_context_leave = _("You leave [_nick_place]"), -._echo_hello_offer = - _("Received hello message"), +._echo_hello = + _("Received hello of psyc://[_pubkey]:g/"), ._notice_context_enter = _("[_nick] enters [_nick_place]"), ._notice_context_leave = diff --git a/src/variable.c b/src/variable.c index 4db11ec..99fde96 100644 --- a/src/variable.c +++ b/src/variable.c @@ -51,6 +51,7 @@ const PsycDictInt psyc_methods[] = { { PSYC_C2STRI("_data"), PSYC_MC_DATA }, { PSYC_C2STRI("_echo_context_enter"), PSYC_MC_ECHO_CONTEXT_ENTER }, { PSYC_C2STRI("_echo_context_leave"), PSYC_MC_ECHO_CONTEXT_LEAVE }, + { PSYC_C2STRI("_echo_hello"), PSYC_MC_ECHO_HELLO }, { PSYC_C2STRI("_echo"), PSYC_MC_ECHO }, { PSYC_C2STRI("_failure"), PSYC_MC_FAILURE }, { PSYC_C2STRI("_info"), PSYC_MC_INFO }, @@ -60,7 +61,6 @@ const PsycDictInt psyc_methods[] = { { PSYC_C2STRI("_message"), PSYC_MC_MESSAGE }, { PSYC_C2STRI("_notice_context_enter"), PSYC_MC_NOTICE_CONTEXT_ENTER }, { PSYC_C2STRI("_notice_context_leave"), PSYC_MC_NOTICE_CONTEXT_LEAVE }, - { PSYC_C2STRI("_notice_hello"), PSYC_MC_NOTICE_HELLO }, { PSYC_C2STRI("_notice"), PSYC_MC_NOTICE }, { PSYC_C2STRI("_request_context_enter"), PSYC_MC_REQUEST_CONTEXT_ENTER }, { PSYC_C2STRI("_request_context_leave"), PSYC_MC_REQUEST_CONTEXT_LEAVE }, @@ -144,6 +144,7 @@ psyc_method (char *method, size_t methodlen, PsycMethod *family, unsigned int *f case PSYC_MC_ECHO: case PSYC_MC_ECHO_CONTEXT_ENTER: case PSYC_MC_ECHO_CONTEXT_LEAVE: + case PSYC_MC_ECHO_HELLO: *family = PSYC_MC_ECHO; *flag = PSYC_METHOD_TEMPLATE | PSYC_METHOD_REPLY | PSYC_METHOD_VISIBLE; break; From 97d5ae6af3de829cf1dc89f4b485c408dc33320f Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 9 Jan 2012 11:52:09 +0100 Subject: [PATCH 360/378] better psyc_dict_lookup --- include/psyc.h | 56 +----------------------- include/psyc/Makefile | 2 +- include/psyc/match.h | 49 +++++++++++++++++++++ include/psyc/variable.h | 19 ++++++--- src/match.c | 51 ++++++++++------------ src/variable.c | 95 ++++++++++------------------------------- test/Makefile | 2 +- test/method.c | 29 +++++++++++++ test/var_type.c | 27 +++++++----- 9 files changed, 156 insertions(+), 174 deletions(-) create mode 100644 include/psyc/match.h create mode 100644 test/method.c diff --git a/include/psyc.h b/include/psyc.h index 41ace37..b046a58 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -109,62 +109,8 @@ typedef struct { char *data; } PsycString; -typedef struct { - PsycString key; - void *value; -} PsycDict; - -typedef struct { - PsycString key; - intptr_t value; -} PsycDictInt; - -/** - * Checks if long keyword string inherits from short keyword string. - */ -int -psyc_inherits (char *sho, size_t slen, char *lon, size_t llen); - -/** - * Checks if short keyword string matches long keyword string. - */ -int -psyc_matches (char *sho, size_t slen, char *lon, size_t llen); - -/** - * Look up value associated with a key in a dictionary. - * - * @param dict The dictionary to search, should be ordered alphabetically. - * @param size Size of dict. - * @param key Key to look for. - * @param keylen Length of key. - * @param inherit If true, also look for anything inheriting from key, - otherwise only exact matches are returned. - * @param tmp A temporary array used for keeping track of results. - * Should be the same size as dict. - * - * @return The value of the entry if found, or NULL if not found. - */ - -void * -psyc_dict_lookup (const PsycDict *dict, size_t size, - const char *key, size_t keylen, - PsycBool inherit, int8_t *tmp); - -/** - * Look up value associated with a key in a dictionary of integers. - * @see psyc_dict_lookup - */ -static inline intptr_t -psyc_dict_lookup_int (const PsycDictInt * dict, size_t size, - const char *key, size_t keylen, - PsycBool inherit, int8_t *tmp) -{ - return (intptr_t) psyc_dict_lookup((PsycDict *) dict, size, key, keylen, - inherit, tmp); -} - #include "psyc/syntax.h" +#include "psyc/match.h" #include "psyc/method.h" #include "psyc/packet.h" #include "psyc/parse.h" diff --git a/include/psyc/Makefile b/include/psyc/Makefile index 80d522c..74d0e77 100644 --- a/include/psyc/Makefile +++ b/include/psyc/Makefile @@ -4,7 +4,7 @@ prefix = /usr includedir = ${prefix}/include INSTALL = install -HEADERS = method.h packet.h parse.h render.h syntax.h text.h uniform.h variable.h +HEADERS = match.h method.h packet.h parse.h render.h syntax.h text.h uniform.h variable.h install: ${HEADERS} diff --git a/include/psyc/match.h b/include/psyc/match.h new file mode 100644 index 0000000..2b61f9f --- /dev/null +++ b/include/psyc/match.h @@ -0,0 +1,49 @@ +typedef struct { + PsycString key; + void *value; +} PsycDict; + +typedef struct { + PsycString key; + intptr_t value; +} PsycDictInt; + +/** + * Checks if long keyword string inherits from short keyword string. + */ +int +psyc_inherits (char *sho, size_t slen, char *lon, size_t llen); + +/** + * Checks if short keyword string matches long keyword string. + */ +int +psyc_matches (char *sho, size_t slen, char *lon, size_t llen); + +/** + * Look up value associated with a key in a dictionary. + * + * @param dict The dictionary to search, should be ordered alphabetically. + * @param size Size of dict. + * @param key Key to look for. + * @param keylen Length of key. + * @param inherit If true, also look for anything inheriting from key, + * otherwise only exact matches are returned. + * + * @return The value of the entry if found, or NULL if not found. + */ + +void * +psyc_dict_lookup (const PsycDict *dict, size_t size, + const char *key, size_t keylen, PsycBool inherit); + +/** + * Look up value associated with a key in a dictionary of integers. + * @see psyc_dict_lookup + */ +static inline intptr_t +psyc_dict_lookup_int (const PsycDictInt * dict, size_t size, + const char *key, size_t keylen, PsycBool inherit) +{ + return (intptr_t) psyc_dict_lookup((PsycDict *) dict, size, key, keylen, inherit); +} diff --git a/include/psyc/variable.h b/include/psyc/variable.h index 264a79c..6c8db7c 100644 --- a/include/psyc/variable.h +++ b/include/psyc/variable.h @@ -8,7 +8,8 @@ #include "packet.h" /// Routing variables in alphabetical order. -extern const PsycString psyc_routing_vars[]; +//extern const PsycString psyc_routing_vars[]; +extern const PsycDictInt psyc_routing_vars[]; // Variable types in alphabetical order. extern const PsycDictInt psyc_var_types[]; @@ -23,14 +24,22 @@ extern const size_t psyc_methods_num; /** * Is this a routing variable name? */ -PsycBool -psyc_var_is_routing (const char *name, size_t len); +static inline PsycBool +psyc_var_is_routing (const char *name, size_t len) +{ + return (PsycBool) psyc_dict_lookup((PsycDict *)psyc_routing_vars, + psyc_routing_vars_num, name, len, PSYC_NO); +} /** * Get the type of variable name. */ -PsycType -psyc_var_type (const char *name, size_t len); +static inline PsycType +psyc_var_type (const char *name, size_t len) +{ + return (PsycType) psyc_dict_lookup((PsycDict *)psyc_var_types, + psyc_var_types_num, name, len, PSYC_YES); +} /** * Is this a list variable name? diff --git a/src/match.c b/src/match.c index ac63b5e..ee82401 100644 --- a/src/match.c +++ b/src/match.c @@ -111,46 +111,39 @@ psyc_matches(char *sho, size_t slen, char *lon, size_t llen) */ void * psyc_dict_lookup(const PsycDict * dict, size_t size, - const char *key, size_t keylen, - PsycBool inherit, int8_t * matching) + const char *key, size_t keylen, PsycBool inherit) { - size_t cursor = 1; - uint8_t i, m = 0; + //size_t cursor = 1; + size_t c = 0; + uint8_t i, match = 0; if (keylen < 2 || key[0] != '_') return 0; - // first find the keywords with matching length + //for (c = 0, i = 0; c < keylen && i < size; c++) { for (i = 0; i < size; i++) { - if (keylen == dict[i].key.length - || (inherit && keylen > dict[i].key.length - && key[dict[i].key.length] == '_')) - matching[m++] = i; - } + if (!(keylen == dict[i].key.length + || (inherit && keylen > dict[i].key.length + && key[dict[i].key.length] == '_'))) + continue; - matching[m] = -1; // mark the end of matching indexes + match = 1; + for (c = 0; c < keylen; c++) { + if (c < dict[i].key.length && dict[i].key.data[c] == key[c]) + continue; + else if (c == dict[i].key.length && key[c] == '_') + return dict[i].value; // after the end of a matching prefix + else if (dict[i].key.data[c] > key[c]) + return NULL; - while (cursor < keylen && matching[0] >= 0) { - for (i = m = 0; i < size; i++) { - if (matching[i] < 0) - break; // reached the end of possible matches - if (cursor < dict[matching[i]].key.length && - dict[matching[i]].key.data[cursor] == key[cursor]) - matching[m++] = matching[i]; // found a match, update matching indexes - else if (cursor == dict[matching[i]].key.length && key[cursor] == '_') - return dict[matching[0]].value; // _ after the end of a matching prefix - else if (dict[matching[i]].key.data[cursor] > key[cursor]) - break; // passed the possible matches in alphabetical order in the dict + match = 0; + break; } - - if (m < size) - matching[m] = -1; // mark the end of matching indexes - - cursor++; + if (match) + return dict[i].value; } - // return first match if found - return matching[0] >= 0 ? dict[matching[0]].value : 0; + return NULL; } #ifdef CMDTOOL diff --git a/src/variable.c b/src/variable.c index 99fde96..d972f9b 100644 --- a/src/variable.c +++ b/src/variable.c @@ -5,27 +5,28 @@ /// Routing variables in alphabetical order. -const PsycString psyc_routing_vars[] = { - PSYC_C2STRI("_amount_fragments"), - PSYC_C2STRI("_context"), - //PSYC_C2STRI("_count"), // older PSYC - PSYC_C2STRI("_counter"), - PSYC_C2STRI("_fragment"), - //PSYC_C2STRI("_length"), // older PSYC - PSYC_C2STRI("_source"), - //PSYC_C2STRI("_source_identification"), // older PSYC - PSYC_C2STRI("_source_identity"), - PSYC_C2STRI("_source_relay"), +//const PsycString psyc_routing_vars[] = { +const PsycDictInt psyc_routing_vars[] = { + { PSYC_C2STRI("_amount_fragments"), 1 }, + { PSYC_C2STRI("_context"), 1 }, + //{ PSYC_C2STRI("_count"), 1 }, // older PSYC + { PSYC_C2STRI("_counter"), 1 }, + { PSYC_C2STRI("_fragment"), 1 }, + //{ PSYC_C2STRI("_length"), 1 }, // older PSYC + { PSYC_C2STRI("_source"), 1 }, + //{ PSYC_C2STRI("_source_identification"), 1 }, // older PSYC + { PSYC_C2STRI("_source_identity"), 1 }, + { PSYC_C2STRI("_source_relay"), 1 }, // until you have a better idea.. is this really in use? - PSYC_C2STRI("_source_relay_relay"), - PSYC_C2STRI("_tag"), - PSYC_C2STRI("_tag_relay"), - //PSYC_C2STRI("_tag_reply"), // older PSYC - PSYC_C2STRI("_target"), - PSYC_C2STRI("_target_forward"), - PSYC_C2STRI("_target_relay"), - //PSYC_C2STRI("_understand_modules"), // older PSYC - //PSYC_C2STRI("_using_modules"), // older PSYC + { PSYC_C2STRI("_source_relay_relay"), 1 }, + { PSYC_C2STRI("_tag"), 1 }, + { PSYC_C2STRI("_tag_relay"), 1 }, + //{ PSYC_C2STRI("_tag_reply"), 1 }, // older PSYC + { PSYC_C2STRI("_target"), 1 }, + { PSYC_C2STRI("_target_forward"), 1 }, + { PSYC_C2STRI("_target_relay"), 1 }, + //{ PSYC_C2STRI("_understand_modules"), 1 }, // older PSYC + //{ PSYC_C2STRI("_using_modules"), 1 }, // older PSYC }; // Variable types in alphabetical order. @@ -75,66 +76,14 @@ const size_t psyc_routing_vars_num = PSYC_NUM_ELEM(psyc_routing_vars); const size_t psyc_var_types_num = PSYC_NUM_ELEM(psyc_var_types); const size_t psyc_methods_num = PSYC_NUM_ELEM(psyc_methods); -/** - * Get the type of variable name. - */ -inline PsycBool -psyc_var_is_routing (const char *name, size_t len) -{ - size_t cursor = 1; - uint8_t i, m = 0; - int8_t matching[psyc_routing_vars_num]; // indexes of matching vars - - if (len < 2 || name[0] != '_') - return PSYC_FALSE; - - // first find the vars with matching length - for (i = 0; i < psyc_routing_vars_num; i++) - if (len == psyc_routing_vars[i].length) - matching[m++] = i; - - matching[m] = -1; // mark the end of matching indexes - - while (cursor < len && matching[0] >= 0) { - for (i = m = 0; i < psyc_routing_vars_num; i++) { - if (matching[i] < 0) - break; // reached the end of possible matches - if (psyc_routing_vars[matching[i]].data[cursor] == name[cursor]) - matching[m++] = matching[i]; // found a match, update matching indexes - else if (psyc_routing_vars[matching[i]].data[cursor] > name[cursor]) - break; // passed the possible matches in alphabetical order in the array - } - - if (m < psyc_routing_vars_num) - matching[m] = -1; // mark the end of matching indexes - - cursor++; - } - - return matching[0] >= 0 ? PSYC_TRUE : PSYC_FALSE; -} - -/** - * Get the type of variable name. - */ -inline PsycType -psyc_var_type (const char *name, size_t len) -{ - int8_t m[psyc_var_types_num]; - return (PsycType) psyc_dict_lookup((PsycDict *) psyc_var_types, - psyc_var_types_num, name, len, PSYC_YES, - (int8_t *) &m); -} - /** * Get the method, its family and its flags. */ PsycMethod psyc_method (char *method, size_t methodlen, PsycMethod *family, unsigned int *flag) { - int8_t tmp[PSYC_NUM_ELEM(psyc_methods)]; int mc = psyc_dict_lookup_int(psyc_methods, psyc_methods_num, - method, methodlen, PSYC_YES, tmp); + method, methodlen, PSYC_YES); switch (mc) { case PSYC_MC_DATA: diff --git a/test/Makefile b/test/Makefile index 123de1b..75f15c0 100644 --- a/test/Makefile +++ b/test/Makefile @@ -3,7 +3,7 @@ DEBUG = 2 CFLAGS = -I../include -I../src -Wall -std=c99 ${OPT} LDFLAGS = -L../lib LOADLIBES = -lpsyc -lm -TARGETS = test_psyc test_psyc_speed test_parser test_match test_render test_text var_is_routing var_type uniform_parse test_list test_table test_packet_id +TARGETS = test_psyc test_psyc_speed test_parser test_match test_render test_text var_is_routing var_type uniform_parse test_list test_table test_packet_id method O = test.o WRAPPER = DIET = diet diff --git a/test/method.c b/test/method.c new file mode 100644 index 0000000..408f1ab --- /dev/null +++ b/test/method.c @@ -0,0 +1,29 @@ +#include +#include +#include + +int main() +{ + PsycMethod family = 0; + unsigned int flag = 0; + + int i; + for (i = 0; i < psyc_methods_num; i++) + if (psyc_method(PSYC_S2ARG(psyc_methods[i].key), &family, &flag) + != psyc_methods[i].value) + return i + 1; + + if (psyc_method(PSYC_C2ARG("_echo_hallo"), &family, &flag) != PSYC_MC_UNKNOWN + && family != PSYC_MC_ECHO) + return 101; + + if (psyc_method(PSYC_C2ARG("_foo_bar"), &family, &flag) != PSYC_MC_UNKNOWN) + return 102; + + if (psyc_method(PSYC_C2ARG("_warning_test"), &family, &flag) != PSYC_MC_WARNING + && family != PSYC_MC_WARNING) + return 103; + + printf("psyc_method passed all tests.\n"); + return 0; +} diff --git a/test/var_type.c b/test/var_type.c index 9050398..cc8a1dc 100644 --- a/test/var_type.c +++ b/test/var_type.c @@ -5,16 +5,23 @@ #include int main() { - unless (psyc_var_type(PSYC_C2ARG("_list"))) return 1; - unless (psyc_var_type(PSYC_C2ARG("_list_foo"))) return 2; - unless (psyc_var_type(PSYC_C2ARG("_color_red"))) return 3; - if (psyc_var_type(PSYC_C2ARG("_last"))) return 4; - if (psyc_var_type(PSYC_C2ARG("_lost_foo"))) return 5; - if (psyc_var_type(PSYC_C2ARG("_colorful"))) return 6; - if (psyc_var_type(PSYC_C2ARG("_foo"))) return 7; - if (psyc_var_type(PSYC_C2ARG("bar"))) return 8; - if (psyc_var_type(PSYC_C2ARG("______"))) return 9; - if (psyc_var_type(PSYC_C2ARG("_"))) return 10; + int i; + for (i = 0; i < psyc_var_types_num; i++) + if (psyc_var_type(PSYC_S2ARG(psyc_var_types[i].key)) + != psyc_var_types[i].value) + return i + 1; + + unless (psyc_var_type(PSYC_C2ARG("_list"))) return 51; + unless (psyc_var_type(PSYC_C2ARG("_list_foo"))) return 52; + unless (psyc_var_type(PSYC_C2ARG("_color_red"))) return 53; + + if (psyc_var_type(PSYC_C2ARG("_last"))) return 104; + if (psyc_var_type(PSYC_C2ARG("_lost_foo"))) return 105; + if (psyc_var_type(PSYC_C2ARG("_colorful"))) return 106; + if (psyc_var_type(PSYC_C2ARG("_foo"))) return 107; + if (psyc_var_type(PSYC_C2ARG("bar"))) return 108; + if (psyc_var_type(PSYC_C2ARG("______"))) return 109; + if (psyc_var_type(PSYC_C2ARG("_"))) return 110; puts("psyc_var_type passed all tests."); return 0; // passed all tests From f7e40dcf52cdff94a6ae3393d97e046f26e8cd97 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 17 Jan 2012 10:53:34 +0100 Subject: [PATCH 361/378] + --- include/psyc/method.h | 4 ++++ src/templates.h | 2 +- src/variable.c | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/include/psyc/method.h b/include/psyc/method.h index 23da0e4..4ef724f 100644 --- a/include/psyc/method.h +++ b/include/psyc/method.h @@ -27,9 +27,11 @@ typedef enum PsycMethod { PSYC_MC_NOTICE, PSYC_MC_NOTICE_CONTEXT_ENTER, PSYC_MC_NOTICE_CONTEXT_LEAVE, + PSYC_MC_NOTICE_LINK, PSYC_MC_REQUEST, PSYC_MC_REQUEST_CONTEXT_ENTER, PSYC_MC_REQUEST_CONTEXT_LEAVE, + PSYC_MC_REQUEST_LINK, PSYC_MC_STATUS, PSYC_MC_STATUS_CONTEXTS_ENTERED, PSYC_MC_STATUS_HELLO, @@ -57,9 +59,11 @@ typedef union PsycTemplates { PsycString _notice; PsycString _notice_context_enter; PsycString _notice_context_leave; + PsycString _notice_link; PsycString _request; PsycString _request_context_enter; PsycString _request_context_leave; + PsycString _request_link; PsycString _status; PsycString _status_contexts_entered; PsycString _status_hello; diff --git a/src/templates.h b/src/templates.h index da6548d..10f23db 100644 --- a/src/templates.h +++ b/src/templates.h @@ -5,7 +5,7 @@ ._echo_context_leave = _("You leave [_nick_place]"), ._echo_hello = - _("Received hello of psyc://[_pubkey]:g/"), + _("Received hello of psyc://[_key_public]:g/"), ._notice_context_enter = _("[_nick] enters [_nick_place]"), ._notice_context_leave = diff --git a/src/variable.c b/src/variable.c index d972f9b..7b430cc 100644 --- a/src/variable.c +++ b/src/variable.c @@ -62,6 +62,7 @@ const PsycDictInt psyc_methods[] = { { PSYC_C2STRI("_message"), PSYC_MC_MESSAGE }, { PSYC_C2STRI("_notice_context_enter"), PSYC_MC_NOTICE_CONTEXT_ENTER }, { PSYC_C2STRI("_notice_context_leave"), PSYC_MC_NOTICE_CONTEXT_LEAVE }, + { PSYC_C2STRI("_notice_link"), PSYC_MC_NOTICE_LINK }, { PSYC_C2STRI("_notice"), PSYC_MC_NOTICE }, { PSYC_C2STRI("_request_context_enter"), PSYC_MC_REQUEST_CONTEXT_ENTER }, { PSYC_C2STRI("_request_context_leave"), PSYC_MC_REQUEST_CONTEXT_LEAVE }, From b76b9d2fd2c96fd94fd7d3e87e6059fbc4a18628 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Sat, 21 Jan 2012 20:02:20 +0100 Subject: [PATCH 362/378] + --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index 0b62293..b81cfa7 100644 --- a/Makefile +++ b/Makefile @@ -48,3 +48,6 @@ clean: help: @/bin/echo -e "Usage:\n\tmake - compile\n\tmake diet - compile with diet libc\n\tmake test\n\tmake doc\n\tmake install [prefix=/usr]" + +legal: + git push l From 04842f910570e607c1e0d487a691d3c1673fbeae Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 25 Jan 2012 18:05:44 +0100 Subject: [PATCH 363/378] uniform path; more methods --- include/psyc/method.h | 24 ++++++++++++++++++------ include/psyc/uniform.h | 1 + src/templates.h | 22 ++++++++++++++++++---- src/uniform.c | 5 +++++ src/variable.c | 26 ++++++++++++++++++-------- test/uniform_parse.c | 8 +++++++- 6 files changed, 67 insertions(+), 19 deletions(-) diff --git a/include/psyc/method.h b/include/psyc/method.h index 4ef724f..d2fdcf1 100644 --- a/include/psyc/method.h +++ b/include/psyc/method.h @@ -19,19 +19,25 @@ typedef enum PsycMethod { PSYC_MC_ECHO_HELLO, PSYC_MC_ERROR, PSYC_MC_FAILURE, + PSYC_MC_FAILURE_ALIAS_NONEXISTANT, + PSYC_MC_FAILURE_ALIAS_UNAVAILABLE, PSYC_MC_INFO, PSYC_MC_MESSAGE, PSYC_MC_MESSAGE_ACTION, - PSYC_MC_MESSAGE_ECHO, - PSYC_MC_MESSAGE_ECHO_ACTION, PSYC_MC_NOTICE, + PSYC_MC_NOTICE_ALIAS_ADD, + PSYC_MC_NOTICE_ALIAS_CHANGE, + PSYC_MC_NOTICE_ALIAS_REMOVE, PSYC_MC_NOTICE_CONTEXT_ENTER, PSYC_MC_NOTICE_CONTEXT_LEAVE, + PSYC_MC_NOTICE_FRIENDSHIP, PSYC_MC_NOTICE_LINK, + PSYC_MC_NOTICE_SET, + PSYC_MC_NOTICE_UNLINK, PSYC_MC_REQUEST, PSYC_MC_REQUEST_CONTEXT_ENTER, PSYC_MC_REQUEST_CONTEXT_LEAVE, - PSYC_MC_REQUEST_LINK, + PSYC_MC_REQUEST_FRIENDSHIP, PSYC_MC_STATUS, PSYC_MC_STATUS_CONTEXTS_ENTERED, PSYC_MC_STATUS_HELLO, @@ -51,19 +57,25 @@ typedef union PsycTemplates { PsycString _echo_hello; PsycString _error; PsycString _failure; + PsycString _failure_alias_nonexistant; + PsycString _failure_alias_unavailable; PsycString _info; PsycString _message; PsycString _message_action; - PsycString _message_echo; - PsycString _message_echo_action; PsycString _notice; + PsycString _notice_alias_add; + PsycString _notice_alias_change; + PsycString _notice_alias_remove; PsycString _notice_context_enter; PsycString _notice_context_leave; + PsycString _notice_friendship; PsycString _notice_link; + PsycString _notice_set; + PsycString _notice_unlink; PsycString _request; PsycString _request_context_enter; PsycString _request_context_leave; - PsycString _request_link; + PsycString _request_friendship; PsycString _status; PsycString _status_contexts_entered; PsycString _status_hello; diff --git a/include/psyc/uniform.h b/include/psyc/uniform.h index 1e65e53..1164c8f 100644 --- a/include/psyc/uniform.h +++ b/include/psyc/uniform.h @@ -38,6 +38,7 @@ typedef struct { PsycString entity; // entity UNI, without the channel PsycString slashes; // the // if the protocol has them PsycString slash; // first / after host + PsycString path; // path begins at first / after host PsycString nick; // whatever works as a nickname } PsycUniform; diff --git a/src/templates.h b/src/templates.h index 10f23db..4a0bf5b 100644 --- a/src/templates.h +++ b/src/templates.h @@ -1,16 +1,30 @@ #define _ PSYC_C2STRI +._notice_alias_add = + _("[_nick] is now an alias for [_uniform]"), +._notice_alias_remove = + _("[_nick] is no longer an alias for [_uniform]"), +._notice_alias_change = + _("[_nick_old] is now known as [_nick_new]"), + +._failure_alias_unavailable = + _("[_nick] is already an alias for [_uniform]"), +._failure_alias_nonexistant = + _("[_nick] is not an alias"), + +._request_context_enter = + _("[_nick] asks for your permission to enter [_nick_place]"), ._echo_context_enter = _("You enter [_nick_place]" ), ._echo_context_leave = _("You leave [_nick_place]"), -._echo_hello = - _("Received hello of psyc://[_key_public]:g/"), + ._notice_context_enter = _("[_nick] enters [_nick_place]"), ._notice_context_leave = _("[_nick] leaves [_nick_place]"), + +._echo_hello = + _("Received hello of psyc://[_key_public]:g/"), ._status_hello = _("Your hello is [_hello]"), -._request_context_enter = - _("[_nick] asks for your permission to enter [_nick_place]"), diff --git a/src/uniform.c b/src/uniform.c index f805999..084574b 100644 --- a/src/uniform.c +++ b/src/uniform.c @@ -158,6 +158,11 @@ psyc_uniform_parse (PsycUniform *uni, const char *buffer, size_t length) uni->body = PSYC_STRING(uni->host.data, length - uni->scheme.length - 1 - uni->slashes.length); + if (uni->slash.length) { + uni->path.data = uni->slash.data; + uni->path.length = length - uni->root.length; + } + if (uni->resource.length) uni->nick = PSYC_STRING(uni->resource.data + 1, uni->resource.length); diff --git a/src/variable.c b/src/variable.c index 7b430cc..fa2f842 100644 --- a/src/variable.c +++ b/src/variable.c @@ -54,18 +54,25 @@ const PsycDictInt psyc_methods[] = { { PSYC_C2STRI("_echo_context_leave"), PSYC_MC_ECHO_CONTEXT_LEAVE }, { PSYC_C2STRI("_echo_hello"), PSYC_MC_ECHO_HELLO }, { PSYC_C2STRI("_echo"), PSYC_MC_ECHO }, + { PSYC_C2STRI("_failure_alias_nonexistant"),PSYC_MC_FAILURE_ALIAS_NONEXISTANT }, + { PSYC_C2STRI("_failure_alias_unavailable"),PSYC_MC_FAILURE_ALIAS_UNAVAILABLE }, { PSYC_C2STRI("_failure"), PSYC_MC_FAILURE }, { PSYC_C2STRI("_info"), PSYC_MC_INFO }, { PSYC_C2STRI("_message_action"), PSYC_MC_MESSAGE_ACTION }, - { PSYC_C2STRI("_message_echo_action"), PSYC_MC_MESSAGE_ECHO_ACTION }, - { PSYC_C2STRI("_message_echo"), PSYC_MC_MESSAGE_ECHO }, { PSYC_C2STRI("_message"), PSYC_MC_MESSAGE }, + { PSYC_C2STRI("_notice_alias_add"), PSYC_MC_NOTICE_ALIAS_ADD }, + { PSYC_C2STRI("_notice_alias_change"), PSYC_MC_NOTICE_ALIAS_CHANGE }, + { PSYC_C2STRI("_notice_alias_remove"), PSYC_MC_NOTICE_ALIAS_REMOVE }, { PSYC_C2STRI("_notice_context_enter"), PSYC_MC_NOTICE_CONTEXT_ENTER }, { PSYC_C2STRI("_notice_context_leave"), PSYC_MC_NOTICE_CONTEXT_LEAVE }, + { PSYC_C2STRI("_notice_friendship"), PSYC_MC_NOTICE_FRIENDSHIP }, { PSYC_C2STRI("_notice_link"), PSYC_MC_NOTICE_LINK }, + { PSYC_C2STRI("_notice_set"), PSYC_MC_NOTICE_SET }, + { PSYC_C2STRI("_notice_unlink"), PSYC_MC_NOTICE_UNLINK }, { PSYC_C2STRI("_notice"), PSYC_MC_NOTICE }, { PSYC_C2STRI("_request_context_enter"), PSYC_MC_REQUEST_CONTEXT_ENTER }, { PSYC_C2STRI("_request_context_leave"), PSYC_MC_REQUEST_CONTEXT_LEAVE }, + { PSYC_C2STRI("_request_frienship"), PSYC_MC_REQUEST_FRIENDSHIP }, { PSYC_C2STRI("_request"), PSYC_MC_REQUEST }, { PSYC_C2STRI("_status_contexts_entered"), PSYC_MC_STATUS_CONTEXTS_ENTERED }, { PSYC_C2STRI("_status_hello"), PSYC_MC_STATUS_HELLO }, @@ -104,6 +111,8 @@ psyc_method (char *method, size_t methodlen, PsycMethod *family, unsigned int *f | PSYC_METHOD_LOGGABLE; break; case PSYC_MC_FAILURE: + case PSYC_MC_FAILURE_ALIAS_NONEXISTANT: + case PSYC_MC_FAILURE_ALIAS_UNAVAILABLE: *family = PSYC_MC_FAILURE; *flag = PSYC_METHOD_TEMPLATE | PSYC_METHOD_REPLY | PSYC_METHOD_VISIBLE | PSYC_METHOD_LOGGABLE; @@ -118,15 +127,16 @@ psyc_method (char *method, size_t methodlen, PsycMethod *family, unsigned int *f *family = PSYC_MC_MESSAGE; *flag = PSYC_METHOD_VISIBLE | PSYC_METHOD_LOGGABLE | PSYC_METHOD_MANUAL; break; - case PSYC_MC_MESSAGE_ECHO: - case PSYC_MC_MESSAGE_ECHO_ACTION: - *family = PSYC_MC_MESSAGE_ECHO; - *flag = PSYC_METHOD_REPLY | PSYC_METHOD_VISIBLE | PSYC_METHOD_LOGGABLE - | PSYC_METHOD_MANUAL; - break; case PSYC_MC_NOTICE: + case PSYC_MC_NOTICE_ALIAS_ADD: + case PSYC_MC_NOTICE_ALIAS_CHANGE: + case PSYC_MC_NOTICE_ALIAS_REMOVE: case PSYC_MC_NOTICE_CONTEXT_ENTER: case PSYC_MC_NOTICE_CONTEXT_LEAVE: + case PSYC_MC_NOTICE_FRIENDSHIP: + case PSYC_MC_NOTICE_LINK: + case PSYC_MC_NOTICE_SET: + case PSYC_MC_NOTICE_UNLINK: *family = PSYC_MC_NOTICE; *flag = PSYC_METHOD_TEMPLATE | PSYC_METHOD_VISIBLE | PSYC_METHOD_LOGGABLE; break; diff --git a/test/uniform_parse.c b/test/uniform_parse.c index 805d917..5b22a2b 100644 --- a/test/uniform_parse.c +++ b/test/uniform_parse.c @@ -12,7 +12,11 @@ testUniform (char *str, int ret) int r = psyc_uniform_parse(uni, str, strlen(str)); PP(("[%.*s] : [%.*s] [%.*s] : [%.*s] [%.*s] / " - "[%.*s] # [%.*s]\n[%.*s]\n[%.*s] [%.*s]\n[%.*s]\n\n", + "[%.*s] # [%.*s]\n" + "[%.*s]\n" + "[%.*s] [%.*s]\n" + "[%.*s]\n" + "[%.*s]\n\n", (int)PSYC_S2ARG2(uni->scheme), (int)PSYC_S2ARG2(uni->slashes), (int)PSYC_S2ARG2(uni->host), @@ -23,6 +27,7 @@ testUniform (char *str, int ret) (int)PSYC_S2ARG2(uni->entity), (int)PSYC_S2ARG2(uni->root), (int)PSYC_S2ARG2(uni->nick), + (int)PSYC_S2ARG2(uni->path), (int)PSYC_S2ARG2(uni->body))); free(uni); @@ -37,6 +42,7 @@ int main () { testUniform("psyc://foo.tld:4404d/@bar#baz", PSYC_SCHEME_PSYC); + testUniform("psyc://foo.tld:4404d/#baz", PSYC_SCHEME_PSYC); testUniform("psyc://foo:4405/~bar", PSYC_SCHEME_PSYC); testUniform("psyc://foo:1234", PSYC_SCHEME_PSYC); testUniform("psyc://foo:1234d", PSYC_SCHEME_PSYC); From c0ec7c3e21398f160606fa92a98900be1a98db10 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Fri, 27 Jan 2012 15:57:02 +0100 Subject: [PATCH 364/378] we usually do it like this, but maybe we should do it like you say? --- include/psyc/method.h | 4 ++-- src/variable.c | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/psyc/method.h b/include/psyc/method.h index d2fdcf1..a70e138 100644 --- a/include/psyc/method.h +++ b/include/psyc/method.h @@ -19,8 +19,8 @@ typedef enum PsycMethod { PSYC_MC_ECHO_HELLO, PSYC_MC_ERROR, PSYC_MC_FAILURE, - PSYC_MC_FAILURE_ALIAS_NONEXISTANT, - PSYC_MC_FAILURE_ALIAS_UNAVAILABLE, + PSYC_MC_FAILURE_UNKNOWN_ALIAS, + PSYC_MC_FAILURE_UNAVAILABLE_ALIAS, PSYC_MC_INFO, PSYC_MC_MESSAGE, PSYC_MC_MESSAGE_ACTION, diff --git a/src/variable.c b/src/variable.c index fa2f842..1dd46aa 100644 --- a/src/variable.c +++ b/src/variable.c @@ -54,8 +54,8 @@ const PsycDictInt psyc_methods[] = { { PSYC_C2STRI("_echo_context_leave"), PSYC_MC_ECHO_CONTEXT_LEAVE }, { PSYC_C2STRI("_echo_hello"), PSYC_MC_ECHO_HELLO }, { PSYC_C2STRI("_echo"), PSYC_MC_ECHO }, - { PSYC_C2STRI("_failure_alias_nonexistant"),PSYC_MC_FAILURE_ALIAS_NONEXISTANT }, - { PSYC_C2STRI("_failure_alias_unavailable"),PSYC_MC_FAILURE_ALIAS_UNAVAILABLE }, + { PSYC_C2STRI("_failure_alias_nonexistant"),PSYC_MC_FAILURE_UNKNOWN_ALIAS }, + { PSYC_C2STRI("_failure_alias_unavailable"),PSYC_MC_FAILURE_UNAVAILABLE_ALIAS }, { PSYC_C2STRI("_failure"), PSYC_MC_FAILURE }, { PSYC_C2STRI("_info"), PSYC_MC_INFO }, { PSYC_C2STRI("_message_action"), PSYC_MC_MESSAGE_ACTION }, @@ -111,8 +111,8 @@ psyc_method (char *method, size_t methodlen, PsycMethod *family, unsigned int *f | PSYC_METHOD_LOGGABLE; break; case PSYC_MC_FAILURE: - case PSYC_MC_FAILURE_ALIAS_NONEXISTANT: - case PSYC_MC_FAILURE_ALIAS_UNAVAILABLE: + case PSYC_MC_FAILURE_UNKNOWN_ALIAS: + case PSYC_MC_FAILURE_UNAVAILABLE_ALIAS: *family = PSYC_MC_FAILURE; *flag = PSYC_METHOD_TEMPLATE | PSYC_METHOD_REPLY | PSYC_METHOD_VISIBLE | PSYC_METHOD_LOGGABLE; From 3ee2f0e392b45f0a5832c37197c454c4009846ac Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 31 Jan 2012 19:34:11 +0100 Subject: [PATCH 365/378] psyc_is_var_routing() -> psyc_var_routing() --- include/psyc/method.h | 4 ++-- include/psyc/variable.h | 32 +++++++++++++++++++------- pike/psyc.cmod | 2 +- src/variable.c | 50 ++++++++++++++++++++--------------------- test/Makefile | 4 ++-- test/var_is_routing.c | 37 ------------------------------ test/var_routing.c | 23 +++++++++++++++++++ 7 files changed, 76 insertions(+), 76 deletions(-) delete mode 100644 test/var_is_routing.c create mode 100644 test/var_routing.c diff --git a/include/psyc/method.h b/include/psyc/method.h index d2fdcf1..bf445f9 100644 --- a/include/psyc/method.h +++ b/include/psyc/method.h @@ -1,7 +1,7 @@ #ifndef PSYC_METHOD_H #define PSYC_METHOD_H -typedef enum PsycMethodFlag { +typedef enum { PSYC_METHOD_TEMPLATE = 1 << 0, PSYC_METHOD_REPLY = 1 << 1, PSYC_METHOD_VISIBLE = 1 << 2, @@ -9,7 +9,7 @@ typedef enum PsycMethodFlag { PSYC_METHOD_MANUAL = 1 << 4, } PsycMethodFlag; -typedef enum PsycMethod { +typedef enum { PSYC_MC_UNKNOWN, PSYC_MC_DATA, diff --git a/include/psyc/variable.h b/include/psyc/variable.h index 6c8db7c..a17f56d 100644 --- a/include/psyc/variable.h +++ b/include/psyc/variable.h @@ -8,8 +8,7 @@ #include "packet.h" /// Routing variables in alphabetical order. -//extern const PsycString psyc_routing_vars[]; -extern const PsycDictInt psyc_routing_vars[]; +extern const PsycDictInt psyc_rvars[]; // Variable types in alphabetical order. extern const PsycDictInt psyc_var_types[]; @@ -17,18 +16,35 @@ extern const PsycDictInt psyc_var_types[]; /// Method names in alphabetical order. extern const PsycDictInt psyc_methods[]; -extern const size_t psyc_routing_vars_num; +extern const size_t psyc_rvars_num; extern const size_t psyc_var_types_num; extern const size_t psyc_methods_num; +typedef enum { + PSYC_RVAR_UNKNOWN, + + PSYC_RVAR_AMOUNT_FRAGMENTS, + PSYC_RVAR_CONTEXT, + PSYC_RVAR_COUNTER, + PSYC_RVAR_FRAGMENT, + PSYC_RVAR_SOURCE, + PSYC_RVAR_SOURCE_RELAY, + PSYC_RVAR_TAG, + PSYC_RVAR_TAG_RELAY, + PSYC_RVAR_TARGET, + PSYC_RVAR_TARGET_RELAY, + + PSYC_RVARS_NUM, +} PsycRoutingVar; + /** - * Is this a routing variable name? + * Look up routing variable. */ -static inline PsycBool -psyc_var_is_routing (const char *name, size_t len) +static inline PsycRoutingVar +psyc_var_routing (const char *name, size_t len) { - return (PsycBool) psyc_dict_lookup((PsycDict *)psyc_routing_vars, - psyc_routing_vars_num, name, len, PSYC_NO); + return (PsycRoutingVar) psyc_dict_lookup((PsycDict *)psyc_rvars, + psyc_rvars_num, name, len, PSYC_NO); } /** diff --git a/pike/psyc.cmod b/pike/psyc.cmod index 2cb1d44..31d6cf9 100644 --- a/pike/psyc.cmod +++ b/pike/psyc.cmod @@ -99,7 +99,7 @@ PIKEFUN string psyc_text(string template, mapping vars) { *! 0 otherwise */ PIKEFUN int is_routingvar(string name) { - RETURN psyc_var_is_routing((char *) STR0(name), name->len); + RETURN psyc_var_routing((char *) STR0(name), name->len); } /*! @decl string render(mapping rvars, mapping evars, string method, string|void body) diff --git a/src/variable.c b/src/variable.c index fa2f842..23c5e10 100644 --- a/src/variable.c +++ b/src/variable.c @@ -3,31 +3,31 @@ #include - /// Routing variables in alphabetical order. -//const PsycString psyc_routing_vars[] = { -const PsycDictInt psyc_routing_vars[] = { - { PSYC_C2STRI("_amount_fragments"), 1 }, - { PSYC_C2STRI("_context"), 1 }, - //{ PSYC_C2STRI("_count"), 1 }, // older PSYC - { PSYC_C2STRI("_counter"), 1 }, - { PSYC_C2STRI("_fragment"), 1 }, - //{ PSYC_C2STRI("_length"), 1 }, // older PSYC - { PSYC_C2STRI("_source"), 1 }, - //{ PSYC_C2STRI("_source_identification"), 1 }, // older PSYC - { PSYC_C2STRI("_source_identity"), 1 }, - { PSYC_C2STRI("_source_relay"), 1 }, - // until you have a better idea.. is this really in use? - { PSYC_C2STRI("_source_relay_relay"), 1 }, - { PSYC_C2STRI("_tag"), 1 }, - { PSYC_C2STRI("_tag_relay"), 1 }, - //{ PSYC_C2STRI("_tag_reply"), 1 }, // older PSYC - { PSYC_C2STRI("_target"), 1 }, - { PSYC_C2STRI("_target_forward"), 1 }, - { PSYC_C2STRI("_target_relay"), 1 }, - //{ PSYC_C2STRI("_understand_modules"), 1 }, // older PSYC - //{ PSYC_C2STRI("_using_modules"), 1 }, // older PSYC +const PsycDictInt psyc_rvars[] = { + { PSYC_C2STRI("_amount_fragments"), PSYC_RVAR_AMOUNT_FRAGMENTS }, + { PSYC_C2STRI("_context"), PSYC_RVAR_CONTEXT }, + { PSYC_C2STRI("_counter"), PSYC_RVAR_COUNTER }, + { PSYC_C2STRI("_fragment"), PSYC_RVAR_FRAGMENT }, + { PSYC_C2STRI("_source"), PSYC_RVAR_SOURCE }, + { PSYC_C2STRI("_source_relay"), PSYC_RVAR_SOURCE_RELAY }, + { PSYC_C2STRI("_tag"), PSYC_RVAR_TAG }, + { PSYC_C2STRI("_tag_relay"), PSYC_RVAR_TAG_RELAY }, + { PSYC_C2STRI("_target"), PSYC_RVAR_TARGET }, + { PSYC_C2STRI("_target_relay"), PSYC_RVAR_TARGET_RELAY }, + +/* old psyc: + { PSYC_C2STRI("_length"), PSYC_RVAR_LENGTH }, + { PSYC_C2STRI("_source_identification"), PSYC_RVAR_SOURCE_IDENTIFICATION }, + { PSYC_C2STRI("_source_identity"), PSYC_RVAR_SOURCE_IDENTITY }, + { PSYC_C2STRI("_source_relay_relay"), PSYC_RVAR_RELAY_RELAY }, + { PSYC_C2STRI("_tag_reply"), PSYC_RVAR_TAG_REPLY }, + { PSYC_C2STRI("_target_forward"), PSYC_RVAR_TARGET_FORWARD }, + { PSYC_C2STRI("_understand_modules"), PSYC_RVAR_UNDERSTAND_MODULES }, + { PSYC_C2STRI("_using_modules"), PSYC_RVAR_USING_MODULES }, +*/ }; +const size_t psyc_rvars_num = PSYC_NUM_ELEM(psyc_rvars); // Variable types in alphabetical order. const PsycDictInt psyc_var_types[] = { @@ -46,6 +46,7 @@ const PsycDictInt psyc_var_types[] = { { PSYC_C2STRI("_time"), PSYC_TYPE_TIME }, { PSYC_C2STRI("_uniform"), PSYC_TYPE_UNIFORM }, }; +const size_t psyc_var_types_num = PSYC_NUM_ELEM(psyc_var_types); /// Method names in alphabetical order. const PsycDictInt psyc_methods[] = { @@ -79,9 +80,6 @@ const PsycDictInt psyc_methods[] = { { PSYC_C2STRI("_status"), PSYC_MC_STATUS }, { PSYC_C2STRI("_warning"), PSYC_MC_WARNING }, }; - -const size_t psyc_routing_vars_num = PSYC_NUM_ELEM(psyc_routing_vars); -const size_t psyc_var_types_num = PSYC_NUM_ELEM(psyc_var_types); const size_t psyc_methods_num = PSYC_NUM_ELEM(psyc_methods); /** diff --git a/test/Makefile b/test/Makefile index 75f15c0..662f2a2 100644 --- a/test/Makefile +++ b/test/Makefile @@ -3,7 +3,7 @@ DEBUG = 2 CFLAGS = -I../include -I../src -Wall -std=c99 ${OPT} LDFLAGS = -L../lib LOADLIBES = -lpsyc -lm -TARGETS = test_psyc test_psyc_speed test_parser test_match test_render test_text var_is_routing var_type uniform_parse test_list test_table test_packet_id method +TARGETS = test_psyc test_psyc_speed test_parser test_match test_render test_text var_routing var_type uniform_parse test_list test_table test_packet_id method O = test.o WRAPPER = DIET = diet @@ -45,7 +45,7 @@ test: ${TARGETS} ./test_render ./test_match ./test_text - ./var_is_routing + ./var_routing ./var_type ./uniform_parse ./test_list diff --git a/test/var_is_routing.c b/test/var_is_routing.c deleted file mode 100644 index caba355..0000000 --- a/test/var_is_routing.c +++ /dev/null @@ -1,37 +0,0 @@ -#include -#include -#include -#include -#include - -int main() { -#if 0 - const char* vars[] = { - "_source", - "_source_relay", - "_source_foo", - "_sourcherry", - "_foo", - "bar", - "_", - }; - - int i; - for (i = 0; i < sizeof(vars) / sizeof(*vars); i++) { - printf(">> %s: %d %d\n", vars[i], sizeof(vars[i]), sizeof(*vars[i])); - printf("%s: %d\n", vars[i], psyc_var_is_routing(vars[i], strlen(vars[i]))); - } -#else - unless (psyc_var_is_routing(PSYC_C2ARG("_source"))) return 1; - unless (psyc_var_is_routing(PSYC_C2ARG("_source_relay"))) return 2; - if (psyc_var_is_routing(PSYC_C2ARG("_source_foo"))) return 3; - if (psyc_var_is_routing(PSYC_C2ARG("_sourcherry"))) return 4; - if (psyc_var_is_routing(PSYC_C2ARG("_sour"))) return 5; - if (psyc_var_is_routing(PSYC_C2ARG("_foo"))) return 6; - if (psyc_var_is_routing(PSYC_C2ARG("bar"))) return 7; - if (psyc_var_is_routing(PSYC_C2ARG("_"))) return 8; - - puts("psyc_var_is_routing passed all tests."); -#endif - return 0; // passed all tests -} diff --git a/test/var_routing.c b/test/var_routing.c new file mode 100644 index 0000000..c6b131d --- /dev/null +++ b/test/var_routing.c @@ -0,0 +1,23 @@ +#include +#include +#include +#include +#include + +int main() { + int i; + + for (i = 0; i < psyc_rvars_num; i++) + if (psyc_var_routing(PSYC_S2ARG(psyc_rvars[i].key)) != psyc_rvars[i].value) + return i + 1; + + if (psyc_var_routing(PSYC_C2ARG("_source_foo"))) return 3; + if (psyc_var_routing(PSYC_C2ARG("_sourcherry"))) return 4; + if (psyc_var_routing(PSYC_C2ARG("_sour"))) return 5; + if (psyc_var_routing(PSYC_C2ARG("_foo"))) return 6; + if (psyc_var_routing(PSYC_C2ARG("bar"))) return 7; + if (psyc_var_routing(PSYC_C2ARG("_"))) return 8; + + puts("psyc_var_routing passed all tests."); + return 0; +} From d3aa4508b958661c247408919426f3934e36c6ce Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 6 Feb 2012 15:05:08 +0100 Subject: [PATCH 366/378] dict syntax; index & update mod parser; psyc-mode for emacs --- .gitignore | 4 +- emacs/psyc.el | 124 +++++ include/psyc.h | 53 +- include/psyc/Makefile | 2 +- include/psyc/match.h | 27 +- include/psyc/packet.h | 247 ++++++--- include/psyc/parse.h | 374 ++++++++++--- include/psyc/render.h | 16 +- include/psyc/syntax.h | 21 - include/psyc/variable.h | 43 +- src/debug.h | 2 + src/match.c | 22 +- src/packet.c | 159 ++++-- src/parse.c | 880 ++++++++++++++++++++++++------ src/render.c | 190 ++++--- src/variable.c | 12 +- test/Makefile | 9 +- test/packets/00-length-no-content | 4 - test/packets/00-length-no-value | 7 - test/packets/02-list | 31 +- test/packets/02-list2 | 7 + test/packets/03-dict | 11 + test/packets/03-list | 20 - test/packets/04-circuit | 2 +- test/test_index.c | 87 +++ test/test_list.c | 27 +- test/test_packet_id.c | 45 +- test/test_parser.c | 7 +- test/test_psyc.c | 128 ++++- test/test_render.c | 53 +- test/test_update.c | 140 +++++ 31 files changed, 2063 insertions(+), 691 deletions(-) create mode 100644 emacs/psyc.el delete mode 100644 include/psyc/syntax.h delete mode 100644 test/packets/00-length-no-content delete mode 100644 test/packets/00-length-no-value create mode 100644 test/packets/02-list2 create mode 100644 test/packets/03-dict delete mode 100644 test/packets/03-list create mode 100644 test/test_index.c create mode 100644 test/test_update.c diff --git a/.gitignore b/.gitignore index abeb59a..098e713 100644 --- a/.gitignore +++ b/.gitignore @@ -19,7 +19,9 @@ test/test_strlen test/test_text test/test_table test/test_packet_id -test/var_is_routing +test/test_index +test/test_update +test/var_routing test/var_type test/uniform_parse diff --git a/emacs/psyc.el b/emacs/psyc.el new file mode 100644 index 0000000..fb38ac6 --- /dev/null +++ b/emacs/psyc.el @@ -0,0 +1,124 @@ +(require 'font-lock) + +(setq + psyc-op "\\([:!?=$@+-]\\)" + psyc-routing-op "^\\([:=]\\)" + psyc-state-op "^\\([?=]\\)$" + + psyc-num "\\([0-9]+\\)" + psyc-kw "\\([a-z_][a-z0-9_]*\\)" + + psyc-length "^[0-9]+$" + + psyc-routing-var-names (regexp-opt '("_amount_fragments" "_context" "_counter" + "_fragment" "_source" "_source_relay" + "_target" "_target_relay" + "_tag" "_tag_relay") 'word) + psyc-routing-var (concat psyc-routing-op psyc-routing-var-names) + + psyc-types (concat "\\([a-z][a-z0-9]+\\|" + (regexp-opt '("_dict" "_list" "_struct" + "_int" "_uint" "_num" "_unum" "_flag" "_amount" + "_date" "_time" "_uniform") nil) + "\\)") + + psyc-mod-op (concat "^" psyc-op) + psyc-mod-name (concat psyc-mod-op psyc-kw) ;2 + psyc-mod-type (concat psyc-mod-op psyc-types "\\b") ;2 + psyc-mod-len (concat psyc-mod-op psyc-kw " " psyc-num) ;3 + psyc-mod-delim (concat "\\(?: " psyc-num "\\)?[\t ]+") + psyc-mod (concat psyc-mod-op psyc-kw psyc-mod-delim) ;3 + + psyc-default-name (concat psyc-mod psyc-kw "[|{]") ;4 + psyc-default-type (concat psyc-mod psyc-types "[_|{]") ;4 +; psyc-default-name (concat "[\t ]" psyc-kw "[|{]") +; psyc-default-type (concat "[\t ]" psyc-types "[_|{]") + + + psyc-elem-delim "[|{}]" + psyc-elem-start "[|}]" + psyc-elem-op (concat psyc-elem-start "\\(=\\)") + psyc-elem-name (concat psyc-elem-start "=" psyc-kw) + psyc-elem-type (concat psyc-elem-start "=" psyc-types "\\b") + psyc-elem-name-delim (concat psyc-elem-name "\\(:\\)") ;2 + psyc-elem-len (concat "\\(?:" psyc-elem-name-delim "\\)?" psyc-num) ;3 + + psyc-update-op (concat "^@" psyc-kw psyc-mod-delim ".+ " psyc-op) ;3 + psyc-update-name (concat "^@" psyc-kw psyc-mod-delim ".+ " + psyc-op psyc-kw) ;4 + psyc-update-type (concat "^@" psyc-kw psyc-mod-delim ".+ " + psyc-op psyc-types "\\b") ;4 + psyc-update-len-delim (concat "^@" psyc-kw psyc-mod-delim ".+ " + psyc-op psyc-kw "?\\(:\\)") ;5 + psyc-update-len (concat "^@" psyc-kw psyc-mod-delim ".+ " + psyc-op psyc-kw "?:" psyc-num) ;5 + + psyc-index-delim "\\(#\\)-?[0-9]+" + + psyc-struct-delim "[\t0-9}]\\(\\.\\)" + psyc-struct-name (concat psyc-struct-delim psyc-kw) ;2 + psyc-struct-type (concat psyc-struct-delim psyc-types "\\b") ;2 + + + psyc-dict-key-len (concat "{" psyc-num) + psyc-dict-key (concat "{\\(?:" psyc-num " \\)?\\([^}]+\\)") ;2 + + psyc-method (concat "^_" psyc-kw) + ;psyc-body "^[^_:!?=$@+-].*$" + + psyc-tmpl-start (concat "\\(\\[\\)" psyc-kw ".+?\\]") + psyc-tmpl-end (concat "\\[" psyc-kw ".+?\\(\\]\\)") + + psyc-packet-delim "^|$" + + psyc-font-lock-keywords + `( + (,psyc-routing-var . (2 font-lock-keyword-face t)) + (,psyc-length . (0 font-lock-constant-face)) + (,psyc-state-op . (0 font-lock-preprocessor-face)) + (,psyc-mod-op . (1 font-lock-preprocessor-face)) + (,psyc-mod-name . (2 font-lock-variable-name-face)) + (,psyc-mod-type . (2 font-lock-type-face t)) + (,psyc-mod-len . (3 font-lock-constant-face)) + + (,psyc-default-name . (4 font-lock-variable-name-face)) + (,psyc-default-type . (4 font-lock-type-face t)) + + (,psyc-dict-key-len . (1 font-lock-constant-face)) + (,psyc-dict-key . (2 font-lock-string-face)) + + (,psyc-elem-op . (1 font-lock-preprocessor-face)) + (,psyc-elem-name . (1 font-lock-variable-name-face)) + (,psyc-elem-type . (1 font-lock-type-face t)) + (,psyc-elem-name-delim . (2 font-lock-comment-face)) + (,psyc-elem-len . (3 font-lock-constant-face)) + (,psyc-elem-delim . (0 font-lock-keyword-face)) + + (,psyc-update-op . (3 font-lock-preprocessor-face)) + (,psyc-update-name . (4 font-lock-variable-name-face)) + (,psyc-update-type . (4 font-lock-type-face t)) + (,psyc-update-len-delim . (5 font-lock-comment-face)) + (,psyc-update-len . (5 font-lock-constant-face)) + + (,psyc-method . (0 font-lock-function-name-face)) + ;(,psyc-body . (0 font-lock-comment-face)) + + (,psyc-index-delim . (1 font-lock-comment-face)) + (,psyc-struct-name . (1 font-lock-comment-face)) + (,psyc-struct-name . (2 font-lock-variable-name-face)) + (,psyc-struct-type . (2 font-lock-type-face t)) + + (,psyc-tmpl-start . (1 font-lock-keyword-face)) + (,psyc-tmpl-end . (2 font-lock-keyword-face)) + + (,psyc-packet-delim . (0 font-lock-preprocessor-face)) + )) + +(define-derived-mode psyc-mode fundamental-mode + "PSYC" + "Major mode for editing PSYC packets" + + (setq font-lock-defaults '((psyc-font-lock-keywords))) + (setq show-trailing-whitespace t)) + +(provide 'psyc) diff --git a/include/psyc.h b/include/psyc.h index b046a58..1689ac7 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -24,7 +24,6 @@ #define PSYC_VERSION 1 #define PSYC_EPOCH 1440444041 // 2015-08-24 21:20:41 CET (Monday) -#define PSYC_STRING(data, len) (PsycString) {len, data} #define PSYC_C2STR(str) (PsycString) {sizeof(str)-1, str} #define PSYC_C2STRI(str) {sizeof(str)-1, str} #define PSYC_C2ARG(str) str, sizeof(str)-1 @@ -50,53 +49,6 @@ typedef enum { PSYC_ERROR = -1, } PsycRC; -/// PSYC packet parts. -typedef enum { - PSYC_PART_RESET = -1, - PSYC_PART_ROUTING = 0, - PSYC_PART_LENGTH = 1, - PSYC_PART_CONTENT = 2, - PSYC_PART_METHOD = 3, - PSYC_PART_DATA = 4, - PSYC_PART_END = 5, -} PsycPart; - -/** - * Different types that a variable can have. - * - * This enum lists PSYC variable types that - * this library is capable of checking for - * validity. Other variable types are treated - * as opaque data. - */ -typedef enum { - PSYC_TYPE_UNKNOWN, - PSYC_TYPE_AMOUNT, - PSYC_TYPE_COLOR, - PSYC_TYPE_COUNTER, - PSYC_TYPE_DEF, - PSYC_TYPE_DATE, - PSYC_TYPE_DEGREE, - PSYC_TYPE_ENTITY, - PSYC_TYPE_FLAG, - PSYC_TYPE_LANGUAGE, - PSYC_TYPE_LIST, - PSYC_TYPE_NICK, - PSYC_TYPE_PAGE, - PSYC_TYPE_TABLE, - PSYC_TYPE_TIME, - PSYC_TYPE_UNIFORM, -} PsycType; - -/** - * List types. - * Possible types are text and binary. - */ -typedef enum { - PSYC_LIST_TEXT = 1, - PSYC_LIST_BINARY = 2, -} PsycListType; - /** * String struct. * @@ -109,14 +61,15 @@ typedef struct { char *data; } PsycString; -#include "psyc/syntax.h" +#define PSYC_STRING(data, len) (PsycString) {len, data} + #include "psyc/match.h" #include "psyc/method.h" #include "psyc/packet.h" +#include "psyc/variable.h" #include "psyc/parse.h" #include "psyc/render.h" #include "psyc/text.h" #include "psyc/uniform.h" -#include "psyc/variable.h" #endif diff --git a/include/psyc/Makefile b/include/psyc/Makefile index 74d0e77..989f7c7 100644 --- a/include/psyc/Makefile +++ b/include/psyc/Makefile @@ -4,7 +4,7 @@ prefix = /usr includedir = ${prefix}/include INSTALL = install -HEADERS = match.h method.h packet.h parse.h render.h syntax.h text.h uniform.h variable.h +HEADERS = match.h method.h packet.h parse.h render.h text.h uniform.h variable.h install: ${HEADERS} diff --git a/include/psyc/match.h b/include/psyc/match.h index 2b61f9f..8be0704 100644 --- a/include/psyc/match.h +++ b/include/psyc/match.h @@ -1,12 +1,15 @@ +#ifndef PSYC_MATCH_H +#define PSYC_MATCH_H + typedef struct { PsycString key; void *value; -} PsycDict; +} PsycMap; typedef struct { PsycString key; intptr_t value; -} PsycDictInt; +} PsycMapInt; /** * Checks if long keyword string inherits from short keyword string. @@ -21,10 +24,10 @@ int psyc_matches (char *sho, size_t slen, char *lon, size_t llen); /** - * Look up value associated with a key in a dictionary. + * Look up value associated with a key in a map. * - * @param dict The dictionary to search, should be ordered alphabetically. - * @param size Size of dict. + * @param map The dictionary to search, should be ordered alphabetically. + * @param size Size of map. * @param key Key to look for. * @param keylen Length of key. * @param inherit If true, also look for anything inheriting from key, @@ -34,16 +37,18 @@ psyc_matches (char *sho, size_t slen, char *lon, size_t llen); */ void * -psyc_dict_lookup (const PsycDict *dict, size_t size, - const char *key, size_t keylen, PsycBool inherit); +psyc_map_lookup (const PsycMap *map, size_t size, + const char *key, size_t keylen, PsycBool inherit); /** - * Look up value associated with a key in a dictionary of integers. - * @see psyc_dict_lookup + * Look up value associated with a key in a map with integer values. + * @see psyc_map_lookup */ static inline intptr_t -psyc_dict_lookup_int (const PsycDictInt * dict, size_t size, +psyc_map_lookup_int (const PsycMapInt * map, size_t size, const char *key, size_t keylen, PsycBool inherit) { - return (intptr_t) psyc_dict_lookup((PsycDict *) dict, size, key, keylen, inherit); + return (intptr_t) psyc_map_lookup((PsycMap *) map, size, key, keylen, inherit); } + +#endif diff --git a/include/psyc/packet.h b/include/psyc/packet.h index 4f37750..88af733 100644 --- a/include/psyc/packet.h +++ b/include/psyc/packet.h @@ -18,9 +18,53 @@ #include -#include "syntax.h" #include "method.h" +/** + * Maximum allowed content size without length. + * Parser stops after reaching this limit. + */ +#define PSYC_CONTENT_SIZE_MAX 512 +/** + * Content size after which a length is added when rendering. + */ +#ifndef PSYC_CONTENT_SIZE_THRESHOLD +# define PSYC_CONTENT_SIZE_THRESHOLD 9 +#endif + +/** + * Maximum allowed modifier size without length. + * Parser stops after reaching this limit. + */ +#define PSYC_MODIFIER_SIZE_MAX 256 +/** + * Modifier size after which a length is added when rendering. + */ +#ifndef PSYC_MODIFIER_SIZE_THRESHOLD +# define PSYC_MODIFIER_SIZE_THRESHOLD 9 +#endif + +/** + * Maximum allowed element size without length. + * Parser stops after reaching this limit. + */ +#define PSYC_ELEM_SIZE_MAX 128 +/** + * Element size after which a length is added when rendering. + */ +#ifndef PSYC_ELEM_SIZE_THRESHOLD +# define PSYC_ELEM_SIZE_THRESHOLD 9 +#endif + +#define PSYC_PACKET_DELIMITER_CHAR '|' +#define PSYC_PACKET_DELIMITER "\n|\n" + +#define PSYC_LIST_ELEM_START '|' +#define PSYC_DICT_KEY_START '{' +#define PSYC_DICT_KEY_END '}' +#define PSYC_DICT_VALUE_START PSYC_DICT_KEY_END +#define PSYC_DICT_VALUE_END PSYC_DICT_KEY_START + /** Modifier flags. */ typedef enum { /// Modifier needs to be checked if it needs length. @@ -30,18 +74,18 @@ typedef enum { /// Modifier doesn't need length. PSYC_MODIFIER_NO_LENGTH = 2, /// Routing modifier, which implies that it doesn't need length. - PSYC_MODIFIER_ROUTING = 3, + PSYC_MODIFIER_ROUTING = 4, } PsycModifierFlag; -/** List flags. */ +/** List/dict element flags. */ typedef enum { - /// List needs to be checked if it needs length. - PSYC_LIST_CHECK_LENGTH = 0, - /// List needs length. - PSYC_LIST_NEED_LENGTH = 1, - /// List doesn't need length. - PSYC_LIST_NO_LENGTH = 2, -} PsycListFlag; + /// Element needs to be checked if it needs length. + PSYC_ELEM_CHECK_LENGTH = 0, + /// Element needs length. + PSYC_ELEM_NEED_LENGTH = 1, + /// Element doesn't need length. + PSYC_ELEM_NO_LENGTH = 2, +} PsycElemFlag; /** Packet flags. */ typedef enum { @@ -77,35 +121,90 @@ typedef enum { PSYC_PACKET_ID_ELEMS = 5, } PsycPacketId; -/** Structure for a modifier. */ typedef struct { - char oper; + PsycString type; + PsycString value; + size_t length; + PsycElemFlag flag; +} PsycElem; + +#define PSYC_ELEM(typ, typlen, val, vallen, flg) \ + (PsycElem) { \ + .type = PSYC_STRING(typ, typlen), \ + .value = PSYC_STRING(val, vallen), \ + .flag = flg, \ + } +#define PSYC_ELEM_TV(typ, typlen, val, vallen) \ + (PsycElem) { \ + .type = PSYC_STRING(typ, typlen), \ + .value = PSYC_STRING(val, vallen), \ + } +#define PSYC_ELEM_VF(val, vallen, flg) \ + (PsycElem) { \ + .value = PSYC_STRING(val, vallen), \ + .flag = flg, \ + } +#define PSYC_ELEM_V(val, vallen) \ + (PsycElem) { \ + .value = PSYC_STRING(val, vallen), \ + } + +/** Dict key */ +typedef struct { + PsycString value; + size_t length; + PsycElemFlag flag; +} PsycDictKey; + +#define PSYC_DICT_KEY(k, klen, flg) \ + (PsycDictKey) { \ + .value = PSYC_STRING(k, klen), \ + .flag = flg, \ + } + +/** Dict key/value */ +typedef struct { + PsycElem value; + PsycDictKey key; +} PsycDictElem; + +#define PSYC_DICT_ELEM(k, v) \ + (PsycDictElem) { \ + .key = k, \ + .value = v, \ + } + +/** Dictionary */ +typedef struct { + PsycString type; + PsycDictElem *elems; + size_t num_elems; + size_t length; +} PsycDict; + +/** List */ +typedef struct { + PsycString type; + PsycElem *elems; + size_t num_elems; + size_t length; +} PsycList; + +/** Modifier */ +typedef struct { PsycString name; PsycString value; PsycModifierFlag flag; + char oper; } PsycModifier; -/** Structure for an entity or routing header. */ +/** Entity or routing header */ typedef struct { size_t lines; PsycModifier *modifiers; } PsycHeader; -/** Structure for a list. */ -typedef struct { - size_t num_elems; - PsycString *elems; - size_t length; - PsycListFlag flag; -} PsycList; - -typedef struct { - PsycList *list; - size_t width; - size_t length; -} PsycTable; - -/** Intermediate struct for a PSYC packet */ +/** Intermediate struct for a PSYC packet. */ typedef struct { PsycHeader routing; ///< Routing header. PsycHeader entity; ///< Entity header. @@ -135,16 +234,12 @@ psyc_num_length (size_t n) static inline PsycModifierFlag psyc_modifier_length_check (PsycModifier *m) { - PsycModifierFlag flag; + if (m->value.length > 0 + && (m->value.length > PSYC_MODIFIER_SIZE_THRESHOLD + || memchr(m->value.data, (int) '\n', m->value.length))) + return PSYC_MODIFIER_NEED_LENGTH; - if (m->value.length > PSYC_MODIFIER_SIZE_THRESHOLD) - flag = PSYC_MODIFIER_NEED_LENGTH; - else if (memchr(m->value.data, (int) '\n', m->value.length)) - flag = PSYC_MODIFIER_NEED_LENGTH; - else - flag = PSYC_MODIFIER_NO_LENGTH; - - return flag; + return PSYC_MODIFIER_NO_LENGTH; } /** Initialize modifier */ @@ -153,33 +248,61 @@ psyc_modifier_init (PsycModifier *m, PsycOperator oper, char *name, size_t namelen, char *value, size_t valuelen, PsycModifierFlag flag) { - *m = (PsycModifier) {oper, {namelen, name}, {valuelen, value}, flag}; + *m = (PsycModifier) { + .oper = oper, + .name = {namelen, name}, + .value = {valuelen, value}, + .flag = flag + }; if (flag == PSYC_MODIFIER_CHECK_LENGTH) // find out if it needs a length m->flag = psyc_modifier_length_check(m); + else if (flag & PSYC_MODIFIER_ROUTING) + m->flag |= PSYC_MODIFIER_NO_LENGTH; } /** * \internal - * Get the total length of a modifier when rendered. + * Check if a list/dict element needs length. + */ +PsycElemFlag +psyc_elem_length_check (PsycString *value, const char end); + +/** + * \internal + * Get the rendered length of a list/dict element. + */ +size_t +psyc_elem_length (PsycElem *elem); + +/** + * \internal + * Get the rendered length of a dict key. + */ +size_t +psyc_dict_key_length (PsycDictKey *elem); + +/** + * \internal + * Get the rendered length of a list. + */ +size_t +psyc_list_length_set (PsycList *list); + +/** + * \internal + * Get the rendered length of a dict. + */ +size_t +psyc_dict_length_set (PsycDict *dict); + +/** + * \internal + * Get the rendered length of a modifier. */ size_t psyc_modifier_length (PsycModifier *m); -/** - * \internal - * Check if a list needs length. - */ -PsycListFlag -psyc_list_length_check (PsycList *list); - -/** - * \internal - * Get the total length of a list when rendered. - */ -PsycListFlag -psyc_list_length (PsycList *list); - /** * \internal * Check if a packet needs length. @@ -195,12 +318,11 @@ psyc_packet_length_set (PsycPacket *p); /** Initialize a list. */ void -psyc_list_init (PsycList *list, PsycString *elems, size_t num_elems, - PsycListFlag flag); +psyc_list_init (PsycList *list, PsycElem *elems, size_t num_elems); -/** Initialize a table. */ +/** Initialize a dict. */ void -psyc_table_init (PsycTable *table, size_t width, PsycList *list); +psyc_dict_init (PsycDict *dict, PsycDictElem *elems, size_t num_elems); /** Initialize a packet. */ void @@ -218,10 +340,13 @@ psyc_packet_init_raw (PsycPacket *packet, char *content, size_t contentlen, PsycPacketFlag flag); -/** Get the total length of a packet ID when rendered. */ -size_t -psyc_packet_id_length (size_t contextlen, size_t sourcelen, size_t targetelen, - size_t counterlen, size_t fragmentlen); +void +psyc_packet_id (PsycList *list, PsycElem *elems, + char *context, size_t contextlen, + char *source, size_t sourcelen, + char *target, size_t targetlen, + char *counter, size_t counterlen, + char *fragment, size_t fragmentlen); /** @} */ // end of packet group diff --git a/include/psyc/parse.h b/include/psyc/parse.h index 36b0991..01ea398 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -132,6 +132,10 @@ typedef enum { * @see psyc_parse() */ typedef enum { + /// Error, no length is set for a modifier which is longer than PSYC_MODIFIER_SIZE_THRESHOLD. + PSYC_PARSE_ERROR_MOD_NO_LEN = -10, + /// Error, no length is set for the content but it is longer than PSYC_CONTENT_SIZE_THRESHOLD. + PSYC_PARSE_ERROR_NO_LEN = -9, /// Error, packet is not ending with a valid delimiter. PSYC_PARSE_ERROR_END = -8, /// Error, expected NL after the method. @@ -197,106 +201,286 @@ typedef enum { PSYC_PARSE_COMPLETE = 13, } PsycParseRC; +/// PSYC packet parts. +typedef enum { + PSYC_PART_RESET = -1, + PSYC_PART_ROUTING = 0, + PSYC_PART_LENGTH = 1, + PSYC_PART_CONTENT = 2, + PSYC_PART_METHOD = 3, + PSYC_PART_DATA = 4, + PSYC_PART_END = 5, +} PsycPart; + /** * The return value definitions for the list parsing function. * @see psyc_parse_list() */ typedef enum { - PSYC_PARSE_LIST_ERROR_DELIM = -4, - PSYC_PARSE_LIST_ERROR_LEN = -3, + /// Error, no length is set for an element which is longer than PSYC_ELEM_SIZE_THRESHOLD. + PSYC_PARSE_LIST_ERROR_ELEM_NO_LEN = -6, + PSYC_PARSE_LIST_ERROR_ELEM_LENGTH = -5, + PSYC_PARSE_LIST_ERROR_ELEM_TYPE = -4, + PSYC_PARSE_LIST_ERROR_ELEM_START = -3, PSYC_PARSE_LIST_ERROR_TYPE = -2, PSYC_PARSE_LIST_ERROR = -1, - /// Completed parsing a list element. - PSYC_PARSE_LIST_ELEM = 1, /// Reached end of buffer. - PSYC_PARSE_LIST_END = 2, - /// Binary list is incomplete. - PSYC_PARSE_LIST_INCOMPLETE = 3, + /// Buffer contains insufficient amount of data. + /// Fill another buffer and concatenate it with the end of the current buffer, + /// from the cursor position to the end. + PSYC_PARSE_LIST_INSUFFICIENT = 1, + /// Completed parsing the default type of the list. + PSYC_PARSE_LIST_TYPE = 2, + /// Start of an element is parsed but still not complete. + PSYC_PARSE_LIST_ELEM_START = 3, + /// Continuation of an incomplete element. + PSYC_PARSE_LIST_ELEM_CONT = 4, + /// Element parsing completed. + PSYC_PARSE_LIST_ELEM_END = 5, + /// Completed parsing a list element. + PSYC_PARSE_LIST_ELEM = 6, + /// Completed parsing the last element in the list. + PSYC_PARSE_LIST_ELEM_LAST = 7, + /// Reached end of buffer. + PSYC_PARSE_LIST_END = 8, } PsycParseListRC; typedef enum { - PSYC_PARSE_TABLE_ERROR_BODY = -5, - PSYC_PARSE_TABLE_ERROR_DELIM = -4, - PSYC_PARSE_TABLE_ERROR_HEAD = -3, - PSYC_PARSE_TABLE_ERROR_WIDTH = -2, - PSYC_PARSE_TABLE_ERROR = -1, - /// Completed parsing the width of the table. - PSYC_PARSE_TABLE_WIDTH = 1, -#ifdef PSYC_PARSE_TABLE_HEAD - /// Completed parsing the name of the key column. - PSYC_PARSE_TABLE_NAME_KEY = 2, - /// Completed parsing the name of a value column. - PSYC_PARSE_TABLE_NAME_VALUE = 3, -#endif - /// Completed parsing a key. - PSYC_PARSE_TABLE_KEY = 4, - /// Completed parsing a value. - PSYC_PARSE_TABLE_VALUE = 5, - /// Completed parsing a key and reached end of buffer. - PSYC_PARSE_TABLE_KEY_END = 6, - /// Completed parsing a value and reached end of buffer. - PSYC_PARSE_TABLE_VALUE_END = 7, - /// Binary table is incomplete. - PSYC_PARSE_TABLE_INCOMPLETE = 8, -} PsycParseTableRC; + PSYC_LIST_PART_START = 0, + PSYC_LIST_PART_TYPE = 1, + PSYC_LIST_PART_ELEM_START = 2, + PSYC_LIST_PART_ELEM_TYPE = 3, + PSYC_LIST_PART_ELEM_LENGTH = 4, + PSYC_LIST_PART_ELEM = 5, +} PsycListPart; typedef enum { - PSYC_TABLE_PART_START = 0, - PSYC_TABLE_PART_WIDTH = 1, -#ifdef PSYC_PARSE_TABLE_HEAD - PSYC_TABLE_PART_HEAD_START = 2, - PSYC_TABLE_PART_HEAD = 3, -#endif - PSYC_TABLE_PART_BODY_START = 4, - PSYC_TABLE_PART_BODY = 5, -} PsycTablePart; + PSYC_PARSE_DICT_ERROR_VALUE = -9, + PSYC_PARSE_DICT_ERROR_VALUE_LENGTH = -8, + PSYC_PARSE_DICT_ERROR_VALUE_TYPE = -7, + PSYC_PARSE_DICT_ERROR_VALUE_START = -6, + PSYC_PARSE_DICT_ERROR_KEY = -5, + PSYC_PARSE_DICT_ERROR_KEY_LENGTH = -4, + PSYC_PARSE_DICT_ERROR_KEY_START = -3, + PSYC_PARSE_DICT_ERROR_TYPE = -2, + PSYC_PARSE_DICT_ERROR = -1, + /// Reached end of buffer. + /// Buffer contains insufficient amount of data. + /// Fill another buffer and concatenate it with the end of the current buffer, + /// from the cursor position to the end. + PSYC_PARSE_DICT_INSUFFICIENT = 1, + /// Completed parsing the default type of the dict. + PSYC_PARSE_DICT_TYPE = 2, + /// Start of a key is parsed but still not complete. + PSYC_PARSE_DICT_KEY_START = 3, + /// Continuation of an incomplete key. + PSYC_PARSE_DICT_KEY_CONT = 4, + /// Last continuation of a key. + PSYC_PARSE_DICT_KEY_END = 5, + /// Completed parsing a key in one go. + PSYC_PARSE_DICT_KEY = 6, + /// Start of a value is parsed but still not complete. + PSYC_PARSE_DICT_VALUE_START = 7, + /// Continuation of an incomplete value. + PSYC_PARSE_DICT_VALUE_CONT = 8, + /// Last continuation of a value. + PSYC_PARSE_DICT_VALUE_END = 9, + /// Completed parsing a value. + PSYC_PARSE_DICT_VALUE = 10, + /// Completed parsing the last value. + PSYC_PARSE_DICT_VALUE_LAST = 11, + /// Reached end of buffer. + PSYC_PARSE_DICT_END = 12, +} PsycParseDictRC; + +typedef enum { + PSYC_DICT_PART_START = 0, + PSYC_DICT_PART_TYPE = 1, + PSYC_DICT_PART_KEY_START = 2, + PSYC_DICT_PART_KEY_LENGTH = 3, + PSYC_DICT_PART_KEY = 4, + PSYC_DICT_PART_VALUE_START = 5, + PSYC_DICT_PART_VALUE_TYPE = 6, + PSYC_DICT_PART_VALUE_LENGTH = 7, + PSYC_DICT_PART_VALUE = 8, +} PsycDictPart; + +typedef enum { + PSYC_PARSE_INDEX_ERROR_DICT = -6, + PSYC_PARSE_INDEX_ERROR_DICT_LENGTH = -5, + PSYC_PARSE_INDEX_ERROR_STRUCT = -4, + PSYC_PARSE_INDEX_ERROR_LIST = -3, + PSYC_PARSE_INDEX_ERROR_TYPE = -2, + PSYC_PARSE_INDEX_ERROR = -1, + /// Reached end of buffer. + /// Buffer contains insufficient amount of data. + /// Fill another buffer and concatenate it with the end of the current buffer, + /// from the cursor position to the end. + PSYC_PARSE_INDEX_INSUFFICIENT = 1, + // Completed parsing a list index. + PSYC_PARSE_INDEX_LIST = 3, + // Completed parsing a list index at the end of the buffer. + PSYC_PARSE_INDEX_LIST_LAST = 4, + // Completed parsing a struct element name. + PSYC_PARSE_INDEX_STRUCT = 5, + // Completed parsing a struct element name at the end of the buffer. + PSYC_PARSE_INDEX_STRUCT_LAST = 6, + /// Start of a dict key is parsed but still not complete. + PSYC_PARSE_INDEX_DICT_START = 7, + /// Continuation of an incomplete dict key. + PSYC_PARSE_INDEX_DICT_CONT = 8, + /// Last continuation of a dict key. + PSYC_PARSE_INDEX_DICT_END = 9, + /// Completed parsing a dict key in one go. + PSYC_PARSE_INDEX_DICT = 10, + /// Reached end of buffer. + PSYC_PARSE_INDEX_END = 11, +} PsycParseIndexRC; + +typedef enum { + PSYC_INDEX_PART_START = 0, + PSYC_INDEX_PART_TYPE = 1, + PSYC_INDEX_PART_LIST = 2, + PSYC_INDEX_PART_STRUCT = 3, + PSYC_INDEX_PART_DICT_LENGTH = 4, + PSYC_INDEX_PART_DICT = 5, +} PsycIndexPart; + +typedef enum { + PSYC_PARSE_UPDATE_ERROR_VALUE = -24, + PSYC_PARSE_UPDATE_ERROR_LENGTH = -23, + PSYC_PARSE_UPDATE_ERROR_TYPE = -22, + PSYC_PARSE_UPDATE_ERROR_OPER = -21, + PSYC_PARSE_UPDATE_ERROR = -1, + /// Reached end of buffer. + /// Buffer contains insufficient amount of data. + /// Fill another buffer and concatenate it with the end of the current buffer, + /// from the cursor position to the end. + PSYC_PARSE_UPDATE_INSUFFICIENT = 1, + + // Completed parsing a list index. + PSYC_PARSE_UPDATE_INDEX_LIST = 3, + // Completed parsing a struct element name. + PSYC_PARSE_UPDATE_INDEX_STRUCT = 5, + /// Start of a dict key is parsed but still not complete. + PSYC_PARSE_UPDATE_INDEX_DICT_START = 7, + /// Continuation of an incomplete dict key. + PSYC_PARSE_UPDATE_INDEX_DICT_CONT = 8, + /// Last continuation of a dict key. + PSYC_PARSE_UPDATE_INDEX_DICT_END = 9, + /// Completed parsing a dict key in one go. + PSYC_PARSE_UPDATE_INDEX_DICT = 10, + + /// Completed parsing the type. + PSYC_PARSE_UPDATE_TYPE = 21, + /// Completed parsing the type and reached end of buffer. + PSYC_PARSE_UPDATE_TYPE_END = 22, + /// Start of the value is parsed but still not complete. + PSYC_PARSE_UPDATE_VALUE_START = 23, + /// Continuation of incomplete value. + PSYC_PARSE_UPDATE_VALUE_CONT = 24, + /// Last continuation of the value. + PSYC_PARSE_UPDATE_VALUE_END = 25, + /// Completed parsing the value in one go. + PSYC_PARSE_UPDATE_VALUE = 26, + /// Reached end of buffer. + PSYC_PARSE_UPDATE_END = 27, +} PsycParseUpdateRC; + +typedef enum { + PSYC_UPDATE_PART_START = 0, + + PSYC_UPDATE_INDEX_PART_TYPE = 1, + PSYC_UPDATE_INDEX_PART_LIST = 2, + PSYC_UPDATE_INDEX_PART_STRUCT = 3, + PSYC_UPDATE_INDEX_PART_DICT_LENGTH = 4, + PSYC_UPDATE_INDEX_PART_DICT = 5, + + PSYC_UPDATE_PART_TYPE = 12, + PSYC_UPDATE_PART_LENGTH = 13, + PSYC_UPDATE_PART_VALUE = 14, +} PsycUpdatePart; /** * Struct for keeping parser state. */ typedef struct { + PsycString buffer; ///< Buffer with data to be parsed. size_t cursor; ///< Current position in buffer. size_t startc; ///< Position where the parsing would be resumed. - PsycString buffer; ///< Buffer with data to be parsed. - uint8_t flags; ///< Flags for the parser, see PsycParseFlag. - PsycPart part; ///< Part of the packet being parsed currently. size_t routinglen; ///< Length of routing part parsed so far. - size_t content_parsed; ///< Number of bytes parsed from the content so far. size_t contentlen; ///< Expected length of the content. - PsycBool contentlen_found; ///< Is there a length given for this packet? - size_t value_parsed; ///< Number of bytes parsed from the value so far. + size_t content_parsed; ///< Number of bytes parsed from the content so far. size_t valuelen; ///< Expected length of the value. - PsycBool valuelen_found; ///< Is there a length given for this modifier? + size_t value_parsed; ///< Number of bytes parsed from the value so far. + + PsycPart part; ///< Part of the packet being parsed currently. + uint8_t flags; ///< Flags for the parser, see PsycParseFlag. + uint8_t contentlen_found; ///< Is there a length given for this packet? + uint8_t valuelen_found; ///< Is there a length given for this modifier? } PsycParseState; /** * Struct for keeping list parser state. */ typedef struct { + PsycString buffer; ///< Buffer with data to be parsed. size_t cursor; ///< Current position in buffer. size_t startc; ///< Line start position. - PsycString buffer; ///< Buffer with data to be parsed. - PsycListType type; ///< List type. - char term; ///< Terminator character at the end. - uint8_t term_set; ///< Look for terminator. - size_t elem_parsed; ///< Number of bytes parsed from the elem so far. + PsycString type; ///< List type. size_t elemlen; ///< Expected length of the elem. + size_t elem_parsed; ///< Number of bytes parsed from the elem so far. + + PsycListPart part; ///< Part of the list being parsed currently. + uint8_t elemlen_found; ///< Is there a length given for this element? } PsycParseListState; /** - * Struct for keeping table parser state. + * Struct for keeping dict parser state. */ typedef struct { + PsycString buffer; ///< Buffer with data to be parsed. size_t cursor; ///< Current position in buffer. size_t startc; ///< Line start position. + + size_t elemlen; ///< Expected length of the key/value. + size_t elem_parsed; ///< Number of bytes parsed from the key/value so far. + + PsycDictPart part; ///< Part of the dict being parsed currently. + uint8_t elemlen_found; ///< Is there a length given for this key/value? +} PsycParseDictState; + +/** + * Struct for keeping index parser state. + */ +typedef struct { PsycString buffer; ///< Buffer with data to be parsed. - PsycTablePart part; ///< Table type. - size_t width; ///< Width of table. - size_t elems; ///< Elems parsed so far in the table. - PsycParseListState list; -} PsycParseTableState; + size_t cursor; ///< Current position in buffer. + size_t startc; ///< Position where the parsing would be resumed. + + size_t elemlen; ///< Expected length of an element. + size_t elem_parsed; ///< Number of bytes parsed from the elem so far. + + PsycIndexPart part; ///< Part of the packet being parsed currently. + uint8_t elemlen_found; ///< Is there a length given for this element? +} PsycParseIndexState; + +/** + * Struct for keeping update modifier parser state. + */ +typedef struct { + PsycString buffer; ///< Buffer with data to be parsed. + size_t cursor; ///< Current position in buffer. + size_t startc; ///< Position where the parsing would be resumed. + + size_t elemlen; ///< Expected length of an element. + size_t elem_parsed; ///< Number of bytes parsed from the elem so far. + + PsycUpdatePart part; ///< Part of the packet being parsed currently. + uint8_t elemlen_found; ///< Is there a length given for this element? +} PsycParseUpdateState; /** * Initializes the state struct. @@ -339,7 +523,7 @@ psyc_parse_buffer_set (PsycParseState *state, const char *buffer, size_t length) } /** - * Initializes the list state. + * Initializes the list parser state. */ static inline void psyc_parse_list_state_init (PsycParseListState *state) @@ -358,27 +542,60 @@ psyc_parse_list_buffer_set (PsycParseListState *state, state->cursor = 0; } +/** + * Initializes the dict parser state. + */ static inline void -psyc_parse_list_term_set (PsycParseListState *state, char term) +psyc_parse_dict_state_init (PsycParseDictState *state) { - state->term = term; - state->term_set = PSYC_TRUE; + memset(state, 0, sizeof(PsycParseDictState)); } /** - * Initializes the table state. + * Sets a new buffer in the dict parser state struct with data to be parsed. */ static inline void -psyc_parse_table_state_init (PsycParseTableState *state) +psyc_parse_dict_buffer_set (PsycParseDictState *state, + const char *buffer, size_t length) { - memset(state, 0, sizeof(PsycParseTableState)); + state->buffer = (PsycString) {length, (char*)buffer}; + state->cursor = 0; } /** - * Sets a new buffer in the list parser state struct with data to be parsed. + * Initializes the index parser state. */ static inline void -psyc_parse_table_buffer_set (PsycParseTableState *state, +psyc_parse_index_state_init (PsycParseIndexState *state) +{ + memset(state, 0, sizeof(PsycParseIndexState)); +} + +/** + * Sets a new buffer in the index parser state struct with data to be parsed. + */ +static inline void +psyc_parse_index_buffer_set (PsycParseIndexState *state, + const char *buffer, size_t length) +{ + state->buffer = (PsycString) {length, (char*)buffer}; + state->cursor = 0; +} + +/** + * Initializes the update modifier parser state. + */ +static inline void +psyc_parse_update_state_init (PsycParseUpdateState *state) +{ + memset(state, 0, sizeof(PsycParseUpdateState)); +} + +/** + * Sets a new buffer in the update modifier parser state struct with data to be parsed. + */ +static inline void +psyc_parse_update_buffer_set (PsycParseUpdateState *state, const char *buffer, size_t length) { state->buffer = (PsycString) {length, (char*)buffer}; @@ -471,10 +688,25 @@ psyc_parse (PsycParseState *state, char *oper, static inline #endif PsycParseListRC -psyc_parse_list (PsycParseListState *state, PsycString *elem); +psyc_parse_list (PsycParseListState *state, PsycString *type, PsycString *elem); -PsycParseTableRC -psyc_parse_table (PsycParseTableState *state, PsycString *elem); +#ifdef __INLINE_PSYC_PARSE +static inline +#endif +PsycParseDictRC +psyc_parse_dict (PsycParseDictState *state, PsycString *type, PsycString *elem); + +#ifdef __INLINE_PSYC_PARSE +static inline +#endif +PsycParseIndexRC +psyc_parse_index (PsycParseIndexState *state, PsycString *idx); + +#ifdef __INLINE_PSYC_PARSE +static inline +#endif +PsycParseUpdateRC +psyc_parse_update (PsycParseUpdateState *state, char *oper, PsycString *value); static inline size_t psyc_parse_int (const char *value, size_t len, int64_t *n) @@ -516,7 +748,7 @@ psyc_parse_uint (const char *value, size_t len, uint64_t *n) } static inline size_t -psyc_parse_index (const char *value, size_t len, int64_t *n) +psyc_parse_list_index (const char *value, size_t len, int64_t *n) { if (!value || len == 0 || value[0] != '#') return 0; diff --git a/include/psyc/render.h b/include/psyc/render.h index 7563ece..17cf066 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -51,6 +51,12 @@ static inline PsycRenderRC psyc_render (PsycPacket *packet, char *buffer, size_t buflen); +PsycRenderRC +psyc_render_elem (PsycElem *elem, char *buffer, size_t buflen); + +PsycRenderRC +psyc_render_dict_key (PsycDictKey *elem, char *buffer, size_t buflen); + /** * Render a PSYC list into a buffer. */ @@ -61,15 +67,7 @@ PsycRenderRC psyc_render_list (PsycList *list, char *buffer, size_t buflen); PsycRenderRC -psyc_render_table (PsycTable *table, char *buffer, size_t buflen); - -PsycRenderRC -psyc_render_packet_id (char *context, size_t contextlen, - char *source, size_t sourcelen, - char *target, size_t targetlen, - char *counter, size_t counterlen, - char *fragment, size_t fragmentlen, - char *buffer, size_t buflen); +psyc_render_dict (PsycDict *dict, char *buffer, size_t buflen); /** @} */ // end of render group diff --git a/include/psyc/syntax.h b/include/psyc/syntax.h deleted file mode 100644 index d46e0c0..0000000 --- a/include/psyc/syntax.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef PSYC_SYNTAX_H - -#ifndef PSYC_LIST_SIZE_LIMIT -# define PSYC_LIST_SIZE_LIMIT 404 -#endif - -/* beyond this a content length must be provided */ -#ifndef PSYC_CONTENT_SIZE_THRESHOLD -# define PSYC_CONTENT_SIZE_THRESHOLD 444 -#endif - -/* beyond this a modifier value length must be provided */ -#ifndef PSYC_MODIFIER_SIZE_THRESHOLD -# define PSYC_MODIFIER_SIZE_THRESHOLD 404 -#endif - -#define PSYC_PACKET_DELIMITER_CHAR '|' -#define PSYC_PACKET_DELIMITER "\n|\n" - -#define PSYC_SYNTAX_H -#endif diff --git a/include/psyc/variable.h b/include/psyc/variable.h index a17f56d..b947829 100644 --- a/include/psyc/variable.h +++ b/include/psyc/variable.h @@ -5,16 +5,17 @@ #ifndef PSYC_VARIABLE_H #define PSYC_VARIABLE_H +#include "match.h" #include "packet.h" /// Routing variables in alphabetical order. -extern const PsycDictInt psyc_rvars[]; +extern const PsycMapInt psyc_rvars[]; // Variable types in alphabetical order. -extern const PsycDictInt psyc_var_types[]; +extern const PsycMapInt psyc_var_types[]; /// Method names in alphabetical order. -extern const PsycDictInt psyc_methods[]; +extern const PsycMapInt psyc_methods[]; extern const size_t psyc_rvars_num; extern const size_t psyc_var_types_num; @@ -37,14 +38,41 @@ typedef enum { PSYC_RVARS_NUM, } PsycRoutingVar; +/** + * Variable types. + * + * This enum lists PSYC variable types that + * this library is capable of checking for + * validity. Other variable types are treated + * as opaque data. + */ +typedef enum { + PSYC_TYPE_UNKNOWN, + PSYC_TYPE_AMOUNT, + PSYC_TYPE_COLOR, + PSYC_TYPE_COUNTER, + PSYC_TYPE_DATE, + PSYC_TYPE_DEGREE, + PSYC_TYPE_DICT, + PSYC_TYPE_ENTITY, + PSYC_TYPE_FLAG, + PSYC_TYPE_LANGUAGE, + PSYC_TYPE_LIST, + PSYC_TYPE_NICK, + PSYC_TYPE_PAGE, + PSYC_TYPE_STRUCT, + PSYC_TYPE_TIME, + PSYC_TYPE_UNIFORM, +} PsycType; + /** * Look up routing variable. */ static inline PsycRoutingVar psyc_var_routing (const char *name, size_t len) { - return (PsycRoutingVar) psyc_dict_lookup((PsycDict *)psyc_rvars, - psyc_rvars_num, name, len, PSYC_NO); + return (PsycRoutingVar) + psyc_map_lookup((PsycMap*)psyc_rvars, psyc_rvars_num, name, len, PSYC_NO); } /** @@ -53,8 +81,9 @@ psyc_var_routing (const char *name, size_t len) static inline PsycType psyc_var_type (const char *name, size_t len) { - return (PsycType) psyc_dict_lookup((PsycDict *)psyc_var_types, - psyc_var_types_num, name, len, PSYC_YES); + return (PsycType) + psyc_map_lookup((PsycMap*)psyc_var_types, psyc_var_types_num, + name, len, PSYC_YES); } /** diff --git a/src/debug.h b/src/debug.h index 073b280..6d9f081 100644 --- a/src/debug.h +++ b/src/debug.h @@ -4,8 +4,10 @@ #ifdef DEBUG # include # define PP(args) printf args; +# define ASSERT(cond) assert(cond) #else # define PP(args) +# define ASSERT(cond) #endif #ifdef TEST diff --git a/src/match.c b/src/match.c index ee82401..ff811b2 100644 --- a/src/match.c +++ b/src/match.c @@ -107,11 +107,11 @@ psyc_matches(char *sho, size_t slen, char *lon, size_t llen) } /** - * Look up value associated with a key in a dictionary. + * Look up value associated with a key in a map. */ void * -psyc_dict_lookup(const PsycDict * dict, size_t size, - const char *key, size_t keylen, PsycBool inherit) +psyc_map_lookup(const PsycMap * map, size_t size, + const char *key, size_t keylen, PsycBool inherit) { //size_t cursor = 1; size_t c = 0; @@ -122,25 +122,25 @@ psyc_dict_lookup(const PsycDict * dict, size_t size, //for (c = 0, i = 0; c < keylen && i < size; c++) { for (i = 0; i < size; i++) { - if (!(keylen == dict[i].key.length - || (inherit && keylen > dict[i].key.length - && key[dict[i].key.length] == '_'))) + if (!(keylen == map[i].key.length + || (inherit && keylen > map[i].key.length + && key[map[i].key.length] == '_'))) continue; match = 1; for (c = 0; c < keylen; c++) { - if (c < dict[i].key.length && dict[i].key.data[c] == key[c]) + if (c < map[i].key.length && map[i].key.data[c] == key[c]) continue; - else if (c == dict[i].key.length && key[c] == '_') - return dict[i].value; // after the end of a matching prefix - else if (dict[i].key.data[c] > key[c]) + else if (c == map[i].key.length && key[c] == '_') + return map[i].value; // after the end of a matching prefix + else if (map[i].key.data[c] > key[c]) return NULL; match = 0; break; } if (match) - return dict[i].value; + return map[i].value; } return NULL; diff --git a/src/packet.c b/src/packet.c index 17bd207..98310fc 100644 --- a/src/packet.c +++ b/src/packet.c @@ -1,73 +1,99 @@ #include "lib.h" -#include #include -inline PsycListFlag -psyc_list_length_check (PsycList *list) +inline PsycElemFlag +psyc_elem_length_check (PsycString *value, const char end) { - PsycListFlag flag = PSYC_LIST_NO_LENGTH; - size_t i, length = 0; + if (value->length > PSYC_ELEM_SIZE_THRESHOLD + || memchr(value->data, (int)end, value->length)) + return PSYC_ELEM_NEED_LENGTH; - for (i = 0; i < list->num_elems; i++) { - PsycString *elem = &list->elems[i]; - length += 1 + elem->length; // |elem - if (length > PSYC_MODIFIER_SIZE_THRESHOLD || - memchr(elem->data, (int) '|', elem->length) || - memchr(elem->data, (int) '\n', elem->length)) { - flag = PSYC_LIST_NEED_LENGTH; - break; - } - } - - return flag; + return PSYC_ELEM_NO_LENGTH;; } -inline PsycListFlag -psyc_list_length (PsycList *list) +inline size_t +psyc_elem_length (PsycElem *elem) { - size_t i, length = 0; + return + (elem->type.length ? 1 + elem->type.length : 0) + + (elem->value.length && elem->flag != PSYC_ELEM_NO_LENGTH + ? (elem->type.length ? 1 : 0) + psyc_num_length(elem->value.length) : 0) + + (elem->value.length ? 1 + elem->value.length : 0); +} - if (list->flag == PSYC_LIST_NEED_LENGTH) { - for (i = 0; i < list->num_elems; i++) { - if (i > 0) - length++; // | - length += // length SP elem - psyc_num_length(list->elems[i].length) + 1 + list->elems[i].length; - } - } else { - for (i = 0; i < list->num_elems; i++) - length += 1 + list->elems[i].length; // |elem +inline size_t +psyc_dict_key_length (PsycDictKey *elem) +{ + return + (elem->flag != PSYC_ELEM_NO_LENGTH + ? psyc_num_length(elem->value.length) : 0) + + (elem->value.length ? 1 + elem->value.length : 0); +} + +inline size_t +psyc_list_length_set (PsycList *list) +{ + size_t i; + PsycElem *elem; + + list->length = list->type.length; + + for (i = 0; i < list->num_elems; i++) { + elem = &list->elems[i]; + if (elem->flag == PSYC_ELEM_CHECK_LENGTH) + elem->flag = psyc_elem_length_check(&elem->value, '|'); + elem->length = psyc_elem_length(elem); + list->length += 1 + elem->length; } - return length; + return list->length; +} + +inline size_t +psyc_dict_length_set (PsycDict *dict) +{ + size_t i; + PsycDictKey *key; + PsycElem *value; + + dict->length = dict->type.length; + + for (i = 0; i < dict->num_elems; i++) { + key = &dict->elems[i].key; + value = &dict->elems[i].value; + + if (key->flag == PSYC_ELEM_CHECK_LENGTH) + key->flag = psyc_elem_length_check(&key->value, '}'); + if (value->flag == PSYC_ELEM_CHECK_LENGTH) + value->flag = psyc_elem_length_check(&value->value, '{'); + + key->length = psyc_dict_key_length(key); + value->length = psyc_elem_length(value); + + dict->length += 1 + key->length + 1 + value->length; + } + + return dict->length; } void -psyc_list_init (PsycList *list, PsycString *elems, size_t num_elems, - PsycListFlag flag) +psyc_list_init (PsycList *list, PsycElem *elems, size_t num_elems) { *list = (PsycList) { .num_elems = num_elems, .elems = elems, - .length = 0, - .flag = flag, }; - - if (flag == PSYC_LIST_CHECK_LENGTH) // check if list elements need length - list->flag = psyc_list_length_check(list); - - list->length = psyc_list_length(list); + psyc_list_length_set(list); } void -psyc_table_init (PsycTable *table, size_t width, PsycList *list) +psyc_dict_init (PsycDict *dict, PsycDictElem *elems, size_t num_elems) { - *table = (PsycTable) { - .width = width, - .list = list, + *dict = (PsycDict) { + .num_elems = num_elems, + .elems = elems, }; - - table->length = (width > 0 ? psyc_num_length(width) + 2 : 0) + list->length; + psyc_dict_length_set(dict); } inline size_t @@ -77,7 +103,10 @@ psyc_modifier_length (PsycModifier *m) if (m->name.length > 0) length += m->name.length + 1 + m->value.length; // name\tvalue - if (m->flag == PSYC_MODIFIER_NEED_LENGTH) // add length of length if needed + // add length of length if needed + if (m->value.length + && (m->flag & PSYC_MODIFIER_NEED_LENGTH + || m->flag == PSYC_MODIFIER_CHECK_LENGTH)) length += psyc_num_length(m->value.length) + 1; // SP length return length; @@ -96,7 +125,8 @@ psyc_packet_length_check (PsycPacket *p) // If any entity modifiers need length, it is possible they contain // a packet terminator, thus the content should have a length as well. for (i = 0; i < p->entity.lines; i++) - if (p->entity.modifiers[i].flag == PSYC_MODIFIER_NEED_LENGTH) + if (p->entity.modifiers[i].flag & PSYC_MODIFIER_NEED_LENGTH + || p->entity.modifiers[i].flag == PSYC_MODIFIER_CHECK_LENGTH) return PSYC_PACKET_NEED_LENGTH; if (memmem(p->data.data, p->data.length, PSYC_C2ARG(PSYC_PACKET_DELIMITER))) @@ -137,10 +167,11 @@ psyc_packet_length_set (PsycPacket *p) // set total length: routing-header content |\n p->length = p->routinglen + p->contentlen + 2; - if (p->contentlen > 0 || p->flag == PSYC_PACKET_NEED_LENGTH) + if (p->contentlen) p->length++; // add \n at the start of the content part - if (p->flag == PSYC_PACKET_NEED_LENGTH) // add length of length if needed + // add length of length if needed + if (p->contentlen && !(p->flag & PSYC_PACKET_NO_LENGTH)) p->length += psyc_num_length(p->contentlen); return p->length; @@ -198,9 +229,29 @@ psyc_packet_init_raw (PsycPacket *p, psyc_packet_length_set(p); } -size_t -psyc_packet_id_length (size_t contextlen, size_t sourcelen, size_t targetlen, - size_t counterlen, size_t fragmentlen) +void +psyc_packet_id (PsycList *list, PsycElem *elems, + char *context, size_t contextlen, + char *source, size_t sourcelen, + char *target, size_t targetlen, + char *counter, size_t counterlen, + char *fragment, size_t fragmentlen) { - return contextlen + sourcelen + targetlen + counterlen + fragmentlen + 5; + if (contextlen) + elems[PSYC_PACKET_ID_CONTEXT] = + PSYC_ELEM_VF(context, contextlen, PSYC_ELEM_NO_LENGTH); + if (sourcelen) + elems[PSYC_PACKET_ID_SOURCE] = + PSYC_ELEM_VF(source, sourcelen, PSYC_ELEM_NO_LENGTH); + if (targetlen) + elems[PSYC_PACKET_ID_TARGET] = + PSYC_ELEM_VF(target, targetlen, PSYC_ELEM_NO_LENGTH); + if (counterlen) + elems[PSYC_PACKET_ID_COUNTER] = + PSYC_ELEM_VF(counter, counterlen, PSYC_ELEM_NO_LENGTH); + if (fragmentlen) + elems[PSYC_PACKET_ID_FRAGMENT] = + PSYC_ELEM_VF(fragment, fragmentlen, PSYC_ELEM_NO_LENGTH); + + psyc_list_init(list, elems, PSYC_PACKET_ID_ELEMS); } diff --git a/src/parse.c b/src/parse.c index f621491..3b13d0c 100644 --- a/src/parse.c +++ b/src/parse.c @@ -15,33 +15,67 @@ return ret; \ } +#define ADVANCE_STARTC_OR_RETURN(ret) \ + state->startc = state->cursor + 1; \ + if (++(state->cursor) >= state->buffer.length) \ + return ret; \ + typedef enum { PARSE_ERROR = -1, PARSE_SUCCESS = 0, PARSE_INSUFFICIENT = 1, - PARSE_COMPLETE = 100, - PARSE_INCOMPLETE = 101, + PARSE_INCOMPLETE = 2, } ParseRC; +typedef struct { + PsycString buffer; + size_t cursor; + size_t startc; +} ParseState; + /** * Parse variable name or method name. + * * It should contain one or more keyword characters. + * * @return PARSE_ERROR or PARSE_SUCCESS */ static inline ParseRC -parse_keyword (PsycParseState *state, PsycString *name) +parse_keyword (ParseState *state, PsycString *name) { name->data = state->buffer.data + state->cursor; name->length = 0; while (psyc_is_kw_char(state->buffer.data[state->cursor])) { name->length++; // was a valid char, increase length - ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PARSE_INSUFFICIENT); } return name->length > 0 ? PARSE_SUCCESS : PARSE_ERROR; } +/** + * Parse length. + * + * @return PARSE_SUCCESS, PARSE_ERROR or PARSE_INSUFFICIENT + */ +static inline ParseRC +parse_length (ParseState *state, size_t *len) +{ + ParseRC ret = PARSE_ERROR; + *len = 0; + + if (psyc_is_numeric(state->buffer.data[state->cursor])) { + ret = PARSE_SUCCESS; + do { + *len = 10 * *len + state->buffer.data[state->cursor] - '0'; + ADVANCE_CURSOR_OR_RETURN(PARSE_INSUFFICIENT); + } while (psyc_is_numeric(state->buffer.data[state->cursor])); + } + + return ret; +} + /** * Parse binary data. * @@ -50,13 +84,12 @@ parse_keyword (PsycParseState *state, PsycString *name) * @param length Expected length of the data. * @param parsed Number of bytes parsed so far. * - * @return PARSE_COMPLETE or PARSE_INCOMPLETE + * @return PARSE_SUCCESS or PARSE_INCOMPLETE */ static inline ParseRC -psyc_parse_binary_value (PsycParseState *state, PsycString *value, - size_t *length, size_t *parsed) +parse_binary (ParseState *state, size_t length, PsycString *value, size_t *parsed) { - size_t remaining = *length - *parsed; + size_t remaining = length - *parsed; value->data = state->buffer.data + state->cursor; if (state->cursor + remaining > state->buffer.length) { @@ -70,9 +103,32 @@ psyc_parse_binary_value (PsycParseState *state, PsycString *value, value->length = remaining; state->cursor += remaining; *parsed += remaining; - assert(*parsed == *length); + ASSERT(*parsed == length); - return PARSE_COMPLETE; + return PARSE_SUCCESS; +} + +/** + * Parse data until a given character is found. + * + * @param state Parser state. + * @param value Start & length of parsed data is saved here. + * @param end Parse until this character is found. + * @param parsed Number of bytes parsed so far. + * + * @return PARSE_SUCCESS or PARSE_INSUFFICIENT + */ +static inline ParseRC +parse_until (ParseState *state, const char end, PsycString *value) +{ + value->data = state->buffer.data + state->cursor; + + while (state->buffer.data[state->cursor] != end) { + value->length++; + ADVANCE_CURSOR_OR_RETURN(PARSE_INSUFFICIENT); + } + + return PARSE_SUCCESS; } /** @@ -86,7 +142,7 @@ psyc_parse_modifier (PsycParseState *state, char *oper, *oper = *(state->buffer.data + state->cursor); ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); - ParseRC ret = parse_keyword(state, name); + ParseRC ret = parse_keyword((ParseState*)state, name); if (ret == PARSE_ERROR) return PSYC_PARSE_ERROR_MOD_NAME; else if (ret != PARSE_SUCCESS) @@ -123,9 +179,7 @@ psyc_parse_modifier (PsycParseState *state, char *oper, if (++(state->cursor) >= state->buffer.length) return length ? PARSE_INCOMPLETE : PARSE_SUCCESS; // if length=0 we're done - ret = - psyc_parse_binary_value(state, value, &(state->valuelen), - &(state->value_parsed)); + ret = parse_binary((ParseState*)state, state->valuelen, value, &state->value_parsed); if (ret == PARSE_INCOMPLETE) return ret; @@ -244,8 +298,8 @@ psyc_parse (PsycParseState *state, char *oper, case PSYC_PART_CONTENT: // In case of an incomplete binary variable resume parsing it. if (state->value_parsed < state->valuelen) { - ret = psyc_parse_binary_value(state, value, &(state->valuelen), - &(state->value_parsed)); + ret = parse_binary((ParseState*)state, state->valuelen, value, + &state->value_parsed); state->content_parsed += value->length; if (ret == PARSE_INCOMPLETE) @@ -303,7 +357,7 @@ psyc_parse (PsycParseState *state, char *oper, case PSYC_PART_METHOD: pos = state->cursor; - ret = parse_keyword(state, name); + ret = parse_keyword((ParseState*)state, name); if (ret == PARSE_INSUFFICIENT) return ret; @@ -345,8 +399,8 @@ psyc_parse (PsycParseState *state, char *oper, state->valuelen--; // \n at the end is not part of data } if (state->value_parsed < state->valuelen) { - ret = psyc_parse_binary_value(state, value, &(state->valuelen), - &(state->value_parsed)); + ret = parse_binary((ParseState*)state, state->valuelen, value, + &state->value_parsed); state->content_parsed += value->length; if (ret == PARSE_INCOMPLETE) @@ -422,191 +476,653 @@ psyc_parse (PsycParseState *state, char *oper, return PSYC_PARSE_ERROR; // should not be reached } -/** List parser. */ +/** + * Parse list. + * + * list = [ default-type ] *list-elem + * list-elem = "|" ( type [ SP list-value ] / [ length ] [ ":" type ] [ SP *OCTET ] ) + * list-value = %x00-7B / %x7D-FF ; any byte except "|" + */ #ifdef __INLINE_PSYC_PARSE static inline #endif PsycParseListRC -psyc_parse_list (PsycParseListState *state, PsycString *elem) +psyc_parse_list (PsycParseListState *state, PsycString *type, PsycString *elem) { + ParseRC ret; + if (state->cursor >= state->buffer.length) - return PSYC_PARSE_LIST_INCOMPLETE; - - state->startc = state->cursor; - - if (!state->type) { // If type is not set we're at the start. - // First character is either | for text lists, or a number for binary lists - if (state->buffer.data[state->cursor] == '|') { - state->type = PSYC_LIST_TEXT; - state->cursor++; - } else if (psyc_is_numeric(state->buffer.data[state->cursor])) - state->type = PSYC_LIST_BINARY; - else - return PSYC_PARSE_LIST_ERROR_TYPE; - } - - if (state->type == PSYC_LIST_TEXT) { - elem->data = state->buffer.data + state->cursor; - elem->length = 0; - - if (state->cursor >= state->buffer.length) - return PSYC_PARSE_LIST_END; - - if (state->term_set) { - while (state->buffer.data[state->cursor] != '|') { - elem->length++; - if (state->buffer.data[state->cursor] == state->term) - return PSYC_PARSE_LIST_END; - if (++(state->cursor) >= state->buffer.length) - return PSYC_PARSE_LIST_END; - } - } else { - while (state->buffer.data[state->cursor] != '|') { - elem->length++; - if (++(state->cursor) >= state->buffer.length) - return PSYC_PARSE_LIST_END; - } - } - state->cursor++; - return PSYC_PARSE_LIST_ELEM; - } else { // binary list - if (!(state->elem_parsed < state->elemlen)) { - // Element starts with a number. - if (psyc_is_numeric(state->buffer.data[state->cursor])) { - do { - state->elemlen = - 10 * state->elemlen + - state->buffer.data[state->cursor] - '0'; - ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_LIST_INCOMPLETE); - } while (psyc_is_numeric(state->buffer.data[state->cursor])); - } else - return PSYC_PARSE_LIST_ERROR_LEN; - - if (state->buffer.data[state->cursor] != ' ') - return PSYC_PARSE_LIST_ERROR_LEN; - - state->cursor++; - elem->data = state->buffer.data + state->cursor; - elem->length = 0; - state->elem_parsed = 0; - } - // Start or resume parsing the binary data - if (state->elem_parsed < state->elemlen) { - if (PARSE_INCOMPLETE == psyc_parse_binary_value((PsycParseState*)state, - elem, &state->elemlen, - &state->elem_parsed)) - return PSYC_PARSE_LIST_INCOMPLETE; - - state->elemlen = 0; - - if (state->cursor >= state->buffer.length) - return PSYC_PARSE_LIST_END; - - if (state->buffer.data[state->cursor] != '|') - return PSYC_PARSE_LIST_ERROR_DELIM; - - state->cursor++; - return PSYC_PARSE_LIST_ELEM; - } - } - - return PSYC_PARSE_LIST_ERROR; // should not be reached -} - -PsycParseTableRC -psyc_parse_table (PsycParseTableState *state, PsycString *elem) -{ - if (state->cursor >= state->buffer.length) - return PSYC_PARSE_TABLE_INCOMPLETE; + return PSYC_PARSE_LIST_END; state->startc = state->cursor; switch (state->part) { - case PSYC_TABLE_PART_START: - if (state->buffer.data[state->cursor] != '*') { - state->part = PSYC_TABLE_PART_BODY_START; - goto PSYC_TABLE_PART_BODY_START; - } else { - state->part = PSYC_TABLE_PART_WIDTH; - ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_TABLE_INCOMPLETE); + case PSYC_LIST_PART_START: + type->length = elem->length = 0; + type->data = elem->data = NULL; + + state->part = PSYC_LIST_PART_TYPE; + // fall thru + + case PSYC_LIST_PART_TYPE: + switch (parse_keyword((ParseState*)state, type)) { + case PARSE_SUCCESS: // end of keyword + state->part = PSYC_LIST_PART_ELEM_START; + return PSYC_PARSE_LIST_TYPE; + case PARSE_INSUFFICIENT: // end of buffer + return PSYC_PARSE_LIST_END; + case PARSE_ERROR: // no keyword + state->part = PSYC_LIST_PART_ELEM_START; + break; + default: // should not be reached + return PSYC_PARSE_LIST_ERROR; } // fall thru - case PSYC_TABLE_PART_WIDTH: - if (psyc_is_numeric(state->buffer.data[state->cursor])) { - do { - state->width = - 10 * state->width + state->buffer.data[state->cursor] - '0'; - ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_TABLE_INCOMPLETE); - } while (psyc_is_numeric(state->buffer.data[state->cursor])); - } else - return PSYC_PARSE_TABLE_ERROR_WIDTH; + case PSYC_LIST_PART_ELEM_START: + if (state->buffer.data[state->cursor] != '|') + return PSYC_PARSE_LIST_ERROR_ELEM_START; + + type->length = elem->length = 0; + type->data = elem->data = NULL; + + state->elem_parsed = 0; + state->elemlen_found = 0; + + state->part = PSYC_LIST_PART_ELEM_LENGTH; + ADVANCE_STARTC_OR_RETURN(PSYC_PARSE_LIST_ELEM_LAST); + // fall thru + + case PSYC_LIST_PART_ELEM_TYPE: + if (state->buffer.data[state->cursor] == '=') { + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + + switch (parse_keyword((ParseState*)state, type)) { + case PARSE_SUCCESS: + switch (state->buffer.data[state->cursor]) { + case ':': + state->part = PSYC_LIST_PART_ELEM_LENGTH; + ADVANCE_STARTC_OR_RETURN(PSYC_PARSE_LIST_ELEM_LAST); + break; + case ' ': + state->part = PSYC_LIST_PART_ELEM; + ADVANCE_STARTC_OR_RETURN(PSYC_PARSE_LIST_ELEM_LAST); + goto PSYC_LIST_PART_ELEM; + case '|': + state->part = PSYC_LIST_PART_ELEM_START; + return PSYC_PARSE_LIST_ELEM; + break; + default: + return PSYC_PARSE_LIST_ERROR_ELEM_TYPE; + } + break; + case PARSE_INSUFFICIENT: // end of buffer + return PSYC_PARSE_LIST_ELEM_LAST; + case PARSE_ERROR: + return PSYC_PARSE_LIST_ERROR_ELEM_TYPE; + default: // should not be reached + return PSYC_PARSE_LIST_ERROR; + } + } + // fall thru + + case PSYC_LIST_PART_ELEM_LENGTH: + switch (parse_length((ParseState*)state, &state->elemlen)) { + case PARSE_SUCCESS: // length is complete + state->elemlen_found = 1; + state->elem_parsed = 0; + elem->length = state->elemlen; + elem->data = NULL; + break; + case PARSE_INSUFFICIENT: // length is incomplete + return PSYC_PARSE_LIST_INSUFFICIENT; + case PARSE_ERROR: // no length + break; + default: // should not be reached + return PSYC_PARSE_LIST_ERROR; + } switch (state->buffer.data[state->cursor]) { -#ifdef PSYC_PARSE_TABLE_HEAD - case '|': - state->part = PSYC_TABLE_PART_HEAD_START; - break; -#endif case ' ': - state->part = PSYC_TABLE_PART_BODY_START; - state->cursor++; + state->part = PSYC_LIST_PART_ELEM; + ADVANCE_STARTC_OR_RETURN(PSYC_PARSE_LIST_ELEM_LAST); + break; + case '|': + state->part = PSYC_LIST_PART_ELEM_START; + return PSYC_PARSE_LIST_ELEM; + default: + return PSYC_PARSE_LIST_ERROR_ELEM_LENGTH; } - - elem->length = state->width; - return PSYC_TABLE_PART_WIDTH; -#ifdef PSYC_PARSE_TABLE_HEAD - case PSYC_TABLE_PART_HEAD_START: - psyc_parse_list_buffer_set(&state->list, state->buffer.data + state->cursor, - state->buffer.length - state->cursor); - psyc_parse_list_term_set(&state->list, ' '); - state->part = PSYC_TABLE_PART_HEAD; // fall thru - case PSYC_TABLE_PART_HEAD: - switch (psyc_parse_list(&state->list, elem)) { - case PSYC_PARSE_LIST_ELEM: - if (state->elems == 0) { - state->elems++; - return PSYC_PARSE_TABLE_NAME_KEY; - } else if (state->elems < state->width) { - state->elems++; - return PSYC_PARSE_TABLE_NAME_VALUE; - } else // too many elements - return PSYC_PARSE_TABLE_ERROR_HEAD; - - case PSYC_PARSE_LIST_END: - if (state->elems != state->width) - return PSYC_PARSE_TABLE_ERROR_HEAD; - - state->part = PSYC_TABLE_PART_BODY_START; - state->cursor += state->list.cursor + 1; - psyc_parse_list_state_init(&state->list); - return state->elems++ == 0 - ? PSYC_PARSE_TABLE_NAME_KEY : PSYC_PARSE_TABLE_NAME_VALUE; - default: - return PSYC_PARSE_TABLE_ERROR_HEAD; + case PSYC_LIST_PART_ELEM: + PSYC_LIST_PART_ELEM: + if (state->elemlen_found) { + switch (parse_binary((ParseState*)state, state->elemlen, elem, + &state->elem_parsed)) { + case PARSE_SUCCESS: + if (elem->length == state->elem_parsed) + ret = PSYC_PARSE_LIST_ELEM; + else + ret = PSYC_PARSE_LIST_ELEM_END; + break; + case PARSE_INCOMPLETE: + if (elem->length == state->elem_parsed) + ret = PSYC_PARSE_LIST_ELEM_START; + else + ret = PSYC_PARSE_LIST_ELEM_CONT; + break; + default: // should not be reached + return PSYC_PARSE_LIST_ERROR; + } + } else { + switch (parse_until((ParseState*)state, '|', elem)) { + case PARSE_SUCCESS: + ret = PSYC_PARSE_LIST_ELEM; + break; + case PARSE_INSUFFICIENT: + return PSYC_PARSE_LIST_ELEM_LAST; + default: // should not be reached + return PSYC_PARSE_LIST_ERROR; + } } -#endif - case PSYC_TABLE_PART_BODY_START: - PSYC_TABLE_PART_BODY_START: - psyc_parse_list_buffer_set(&state->list, state->buffer.data + state->cursor, - state->buffer.length - state->cursor); - state->part = PSYC_TABLE_PART_BODY; - // fall thru - case PSYC_TABLE_PART_BODY: - switch (psyc_parse_list(&state->list, elem)) { - case PSYC_PARSE_LIST_ELEM: - return state->elems++ % (state->width + 1) == 0 - ? PSYC_PARSE_TABLE_KEY : PSYC_PARSE_TABLE_VALUE; - case PSYC_PARSE_LIST_END: - return state->elems++ % (state->width + 1) == 0 - ? PSYC_PARSE_TABLE_KEY_END : PSYC_PARSE_TABLE_VALUE_END; - default: - return PSYC_PARSE_TABLE_ERROR_BODY; - } + state->part = PSYC_LIST_PART_ELEM_START; + state->startc = state->cursor; + return ret; } return PSYC_PARSE_LIST_ERROR; // should not be reached } + +/** + * Parse dictionary. + * + * dict = [ type ] *dict-item + * dict-item = "{" ( dict-key / length SP OCTET) "}" + * ( type [ SP dict-value ] / [ length ] [ ":" type ] [ SP *OCTET ] ) + * dict-key = %x00-7C / %x7E-FF ; any byte except "{" + * dict-value = %x00-7A / %x7C-FF ; any byte except "}" + */ +PsycParseDictRC +psyc_parse_dict (PsycParseDictState *state, PsycString *type, PsycString *elem) +{ + ParseRC ret; + + if (state->cursor >= state->buffer.length) + return PSYC_PARSE_DICT_END; + + state->startc = state->cursor; + + switch (state->part) { + case PSYC_DICT_PART_START: + type->length = elem->length = 0; + type->data = elem->data = NULL; + + state->part = PSYC_DICT_PART_TYPE; + // fall thru + + case PSYC_DICT_PART_TYPE: + switch (parse_keyword((ParseState*)state, type)) { + case PARSE_SUCCESS: // end of keyword + state->part = PSYC_DICT_PART_KEY_START; + return PSYC_PARSE_DICT_TYPE; + case PARSE_INSUFFICIENT: // end of buffer + return PSYC_PARSE_DICT_END; + case PARSE_ERROR: // no keyword + state->part = PSYC_DICT_PART_KEY_START; + break; + default: // should not be reached + return PSYC_PARSE_DICT_ERROR; + } + // fall thru + + case PSYC_DICT_PART_KEY_START: + if (state->buffer.data[state->cursor] != '{') + return PSYC_PARSE_DICT_ERROR_KEY_START; + + type->length = elem->length = 0; + type->data = elem->data = NULL; + + state->elem_parsed = 0; + state->elemlen_found = 0; + + state->part = PSYC_DICT_PART_KEY_LENGTH; + ADVANCE_STARTC_OR_RETURN(PSYC_PARSE_DICT_INSUFFICIENT); + // fall thru + + case PSYC_DICT_PART_KEY_LENGTH: + switch (parse_length((ParseState*)state, &state->elemlen)) { + case PARSE_SUCCESS: // length is complete + state->elemlen_found = 1; + state->elem_parsed = 0; + elem->length = state->elemlen; + elem->data = NULL; + + if (state->buffer.data[state->cursor] != ' ') + return PSYC_PARSE_DICT_ERROR_KEY_LENGTH; + + state->part = PSYC_DICT_PART_KEY; + ADVANCE_STARTC_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + break; + case PARSE_INSUFFICIENT: // length is incomplete + return PSYC_PARSE_DICT_INSUFFICIENT; + case PARSE_ERROR: // no length + state->part = PSYC_DICT_PART_KEY; + break; + default: // should not be reached + return PSYC_PARSE_DICT_ERROR; + } + // fall thru + + case PSYC_DICT_PART_KEY: + if (state->elemlen_found) { + switch (parse_binary((ParseState*)state, state->elemlen, elem, + &state->elem_parsed)) { + case PARSE_SUCCESS: + if (elem->length == state->elem_parsed) + ret = PSYC_PARSE_DICT_KEY; + else + ret = PSYC_PARSE_DICT_KEY_END; + break; + case PARSE_INCOMPLETE: + if (elem->length == state->elem_parsed) + ret = PSYC_PARSE_DICT_KEY_START; + else + ret = PSYC_PARSE_DICT_KEY_CONT; + break; + default: // should not be reached + return PSYC_PARSE_DICT_ERROR; + } + } else { + switch (parse_until((ParseState*)state, '}', elem)) { + case PARSE_SUCCESS: + ret = PSYC_PARSE_DICT_KEY; + break; + case PARSE_INSUFFICIENT: + return PSYC_PARSE_DICT_INSUFFICIENT; + default: // should not be reached + return PSYC_PARSE_DICT_ERROR; + } + } + + state->part = PSYC_DICT_PART_VALUE_START; + state->startc = state->cursor; + return ret; + + case PSYC_DICT_PART_VALUE_START: + switch (state->buffer.data[state->cursor] != '}') + return PSYC_PARSE_DICT_ERROR_VALUE_START; + + type->length = elem->length = 0; + type->data = elem->data = NULL; + + state->elem_parsed = 0; + state->elemlen_found = 0; + + state->part = PSYC_DICT_PART_VALUE_TYPE; + ADVANCE_STARTC_OR_RETURN(PSYC_PARSE_DICT_VALUE_LAST); + // fall thru + + case PSYC_DICT_PART_VALUE_TYPE: + if (state->buffer.data[state->cursor] == '=') { + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + + switch (parse_keyword((ParseState*)state, type)) { + case PARSE_SUCCESS: + switch (state->buffer.data[state->cursor]) { + case ':': + state->part = PSYC_DICT_PART_VALUE_LENGTH; + ADVANCE_STARTC_OR_RETURN(PSYC_PARSE_DICT_VALUE_LAST); + break; + case ' ': + state->part = PSYC_DICT_PART_VALUE; + ADVANCE_STARTC_OR_RETURN(PSYC_PARSE_DICT_VALUE_LAST); + goto PSYC_DICT_PART_VALUE; + case '{': + state->part = PSYC_DICT_PART_KEY_START; + return PSYC_PARSE_DICT_VALUE; + break; + default: + return PSYC_PARSE_DICT_ERROR_VALUE_TYPE; + } + break; + case PARSE_INSUFFICIENT: // end of buffer + return PSYC_PARSE_DICT_VALUE_LAST; + case PARSE_ERROR: + return PSYC_PARSE_DICT_ERROR_VALUE_TYPE; + default: // should not be reached + return PSYC_PARSE_DICT_ERROR; + } + } + // fall thru + + case PSYC_DICT_PART_VALUE_LENGTH: + switch (parse_length((ParseState*)state, &state->elemlen)) { + case PARSE_SUCCESS: // length is complete + state->elemlen_found = 1; + state->elem_parsed = 0; + elem->length = state->elemlen; + elem->data = NULL; + break; + case PARSE_INSUFFICIENT: // length is incomplete + return PSYC_PARSE_DICT_INSUFFICIENT; + case PARSE_ERROR: // no length + break; + default: // should not be reached + return PSYC_PARSE_DICT_ERROR; + } + + switch (state->buffer.data[state->cursor]) { + case ' ': + state->part = PSYC_DICT_PART_VALUE; + ADVANCE_STARTC_OR_RETURN(PSYC_PARSE_DICT_VALUE_LAST); + break; + case '{': + state->part = PSYC_DICT_PART_KEY_START; + return PSYC_PARSE_DICT_VALUE; + default: + return PSYC_PARSE_DICT_ERROR_VALUE_LENGTH; + } + // fall thru + + case PSYC_DICT_PART_VALUE: + PSYC_DICT_PART_VALUE: + if (state->elemlen_found) { + switch (parse_binary((ParseState*)state, state->elemlen, elem, + &state->elem_parsed)) { + case PARSE_SUCCESS: + if (elem->length == state->elem_parsed) + ret = PSYC_PARSE_DICT_VALUE; + else + ret = PSYC_PARSE_DICT_VALUE_END; + break; + case PARSE_INCOMPLETE: + if (elem->length == state->elem_parsed) + ret = PSYC_PARSE_DICT_VALUE_START; + else + ret = PSYC_PARSE_DICT_VALUE_CONT; + break; + default: // should not be reached + return PSYC_PARSE_DICT_ERROR; + } + } else { + switch (parse_until((ParseState*)state, '{', elem)) { + case PARSE_SUCCESS: + ret = PSYC_PARSE_DICT_VALUE; + break; + case PARSE_INSUFFICIENT: + return PSYC_PARSE_DICT_VALUE_LAST; + default: // should not be reached + return PSYC_PARSE_DICT_ERROR; + } + } + + state->part = PSYC_DICT_PART_KEY_START; + return ret; + } + + return PSYC_PARSE_DICT_ERROR; // should not be reached +} + +#ifdef __INLINE_PSYC_PARSE +static inline +#endif +PsycParseIndexRC +psyc_parse_index (PsycParseIndexState *state, PsycString *idx) +{ + ParseRC ret; + + if (state->cursor >= state->buffer.length) + return PSYC_PARSE_INDEX_END; + + state->startc = state->cursor; + + switch (state->part) { + case PSYC_INDEX_PART_START: + case PSYC_INDEX_PART_TYPE: + idx->length = 0; + idx->data = NULL; + + switch (state->buffer.data[state->cursor]) { + case '#': + state->part = PSYC_INDEX_PART_LIST; + ADVANCE_STARTC_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + goto PSYC_INDEX_PART_LIST; + case '.': + state->part = PSYC_INDEX_PART_DICT; + ADVANCE_STARTC_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + goto PSYC_INDEX_PART_STRUCT; + case '{': + state->part = PSYC_INDEX_PART_DICT; + ADVANCE_STARTC_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + goto PSYC_INDEX_PART_DICT_LENGTH; + default: + return PSYC_PARSE_INDEX_ERROR_TYPE; + } + + case PSYC_INDEX_PART_LIST: + PSYC_INDEX_PART_LIST: + switch (parse_length((ParseState*)state, &idx->length)) { + case PARSE_SUCCESS: // list index is complete + state->part = PSYC_INDEX_PART_TYPE; + return PSYC_PARSE_INDEX_LIST; + case PARSE_INSUFFICIENT: // list index at the end of buffer + return PSYC_PARSE_INDEX_LIST_LAST; + case PARSE_ERROR: // no index + return PSYC_PARSE_INDEX_ERROR_LIST; + default: // should not be reached + return PSYC_PARSE_INDEX_ERROR; + } + + case PSYC_INDEX_PART_STRUCT: + PSYC_INDEX_PART_STRUCT: + switch (parse_keyword((ParseState*)state, idx)) { + case PARSE_SUCCESS: // end of keyword + state->part = PSYC_INDEX_PART_TYPE; + return PSYC_PARSE_INDEX_STRUCT; + case PARSE_INSUFFICIENT: // end of buffer + return PSYC_PARSE_INDEX_STRUCT_LAST; + case PARSE_ERROR: // no keyword + return PSYC_PARSE_INDEX_ERROR_STRUCT; + default: // should not be reached + return PSYC_PARSE_INDEX_ERROR; + } + + case PSYC_INDEX_PART_DICT_LENGTH: + PSYC_INDEX_PART_DICT_LENGTH: + switch (parse_length((ParseState*)state, &state->elemlen)) { + case PARSE_SUCCESS: // length is complete + state->elemlen_found = 1; + state->elem_parsed = 0; + idx->length = state->elemlen; + idx->data = NULL; + + if (state->buffer.data[state->cursor] != ' ') + return PSYC_PARSE_INDEX_ERROR_DICT_LENGTH; + + state->part = PSYC_INDEX_PART_DICT; + ADVANCE_STARTC_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + break; + case PARSE_INSUFFICIENT: // length is incomplete + return PSYC_PARSE_DICT_INSUFFICIENT; + case PARSE_ERROR: // no length + state->part = PSYC_INDEX_PART_DICT; + break; + default: // should not be reached + return PSYC_PARSE_INDEX_ERROR; + } + // fall thru + + case PSYC_INDEX_PART_DICT: + if (state->elemlen_found) { + switch (parse_binary((ParseState*)state, state->elemlen, idx, + &state->elem_parsed)) { + case PARSE_SUCCESS: + if (idx->length == state->elem_parsed) + ret = PSYC_PARSE_INDEX_DICT; + else + ret = PSYC_PARSE_INDEX_DICT_END; + break; + case PARSE_INCOMPLETE: + if (idx->length == state->elem_parsed) + ret = PSYC_PARSE_INDEX_DICT_START; + else + ret = PSYC_PARSE_INDEX_DICT_CONT; + break; + default: // should not be reached + return PSYC_PARSE_INDEX_ERROR_DICT; + } + } else { + switch (parse_until((ParseState*)state, '}', idx)) { + case PARSE_SUCCESS: + ret = PSYC_PARSE_INDEX_DICT; + break; + case PARSE_INSUFFICIENT: + return PSYC_PARSE_INDEX_INSUFFICIENT; + default: // should not be reached + return PSYC_PARSE_INDEX_ERROR_DICT; + } + } + + state->part = PSYC_INDEX_PART_TYPE; + state->cursor++; + return ret; + } + + return PSYC_PARSE_INDEX_ERROR; // should not be reached +} + +#ifdef __INLINE_PSYC_PARSE +static inline +#endif +PsycParseUpdateRC +psyc_parse_update (PsycParseUpdateState *state, char *oper, PsycString *value) +{ + PsycParseIndexRC ret; + + if (state->cursor >= state->buffer.length) + return PSYC_PARSE_UPDATE_END; + + state->startc = state->cursor; + + switch (state->part) { + case PSYC_UPDATE_PART_START: + value->length = 0; + value->data = NULL; + // fall thru + + case PSYC_INDEX_PART_TYPE: + case PSYC_INDEX_PART_LIST: + case PSYC_INDEX_PART_STRUCT: + case PSYC_INDEX_PART_DICT_LENGTH: + case PSYC_INDEX_PART_DICT: + ret = psyc_parse_index((PsycParseIndexState*)state, value); + + switch (ret) { + case PSYC_PARSE_INDEX_INSUFFICIENT: + case PSYC_PARSE_INDEX_LIST_LAST: + case PSYC_PARSE_INDEX_STRUCT_LAST: + case PSYC_PARSE_INDEX_END: + return PSYC_PARSE_UPDATE_INSUFFICIENT; + case PSYC_PARSE_INDEX_ERROR_TYPE: + if (state->buffer.data[state->cursor] != ' ') + return ret; + state->part = PSYC_PARSE_UPDATE_TYPE; + value->length = 0; + value->data = NULL; + ADVANCE_STARTC_OR_RETURN(PSYC_PARSE_UPDATE_INSUFFICIENT); + break; + default: + return ret; + } + case PSYC_UPDATE_PART_TYPE: + if (!psyc_is_oper(state->buffer.data[state->cursor])) + return PSYC_PARSE_UPDATE_ERROR_OPER; + + *oper = state->buffer.data[state->cursor]; + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_UPDATE_END); + + switch (parse_keyword((ParseState*)state, value)) { + case PARSE_SUCCESS: // end of keyword + case PARSE_ERROR: // no keyword + switch (state->buffer.data[state->cursor]) { + case ':': + state->part = PSYC_UPDATE_PART_LENGTH; + break; + case ' ': + state->part = PSYC_UPDATE_PART_VALUE; + break; + default: + return PSYC_PARSE_UPDATE_ERROR_TYPE; + } + + state->cursor++; + return PSYC_PARSE_UPDATE_TYPE; + break; + case PARSE_INSUFFICIENT: // end of buffer + return PSYC_PARSE_UPDATE_TYPE_END; + default: // should not be reached + return PSYC_PARSE_UPDATE_ERROR; + } + break; + + case PSYC_UPDATE_PART_LENGTH: + switch (parse_length((ParseState*)state, &state->elemlen)) { + case PARSE_SUCCESS: // length is complete + state->elemlen_found = 1; + state->elem_parsed = 0; + value->length = state->elemlen; + value->data = NULL; + + if (state->buffer.data[state->cursor] != ' ') + return PSYC_PARSE_UPDATE_ERROR_LENGTH; + + state->part = PSYC_UPDATE_PART_VALUE; + if (value->length == 0) + return PSYC_PARSE_UPDATE_END; + ADVANCE_STARTC_OR_RETURN(PSYC_PARSE_UPDATE_INSUFFICIENT); + break; + case PARSE_INSUFFICIENT: // length is incomplete + if (value->length == 0) + return PSYC_PARSE_UPDATE_END; + return PSYC_PARSE_UPDATE_INSUFFICIENT; + case PARSE_ERROR: // no length after : + return PSYC_PARSE_UPDATE_ERROR_LENGTH; + default: // should not be reached + return PSYC_PARSE_UPDATE_ERROR; + } + // fall thru + + case PSYC_UPDATE_PART_VALUE: + if (state->elemlen_found) { + switch (parse_binary((ParseState*)state, state->elemlen, value, + &state->elem_parsed)) { + case PARSE_SUCCESS: + if (value->length == state->elem_parsed) + ret = PSYC_PARSE_UPDATE_VALUE; + else + ret = PSYC_PARSE_UPDATE_VALUE_END; + break; + case PARSE_INCOMPLETE: + if (value->length == state->elem_parsed) + ret = PSYC_PARSE_UPDATE_VALUE_START; + else + ret = PSYC_PARSE_UPDATE_VALUE_CONT; + break; + default: // should not be reached + return PSYC_PARSE_UPDATE_ERROR_VALUE; + } + } else { + value->data = state->buffer.data + state->cursor; + value->length = state->buffer.length - state->cursor; + ret = PSYC_PARSE_UPDATE_VALUE; + } + + state->part = PSYC_INDEX_PART_TYPE; + state->cursor++; + return ret; + } + + return PSYC_PARSE_INDEX_ERROR; // should not be reached +} diff --git a/src/render.c b/src/render.c index d61e68e..21d9b08 100644 --- a/src/render.c +++ b/src/render.c @@ -3,7 +3,59 @@ #include "lib.h" #include #include -#include + +inline PsycRenderRC +psyc_render_elem (PsycElem *elem, char *buffer, size_t buflen) +{ + size_t cur = 0; + + if (elem->length > buflen) // return error if element doesn't fit in buffer + return PSYC_RENDER_ERROR; + + if (elem->type.length) { + buffer[cur++] = '='; + memcpy(buffer + cur, PSYC_S2ARG(elem->type)); + cur += elem->type.length; + } + + if (elem->value.length && !(elem->flag & PSYC_ELEM_NO_LENGTH)) { + if (elem->type.length) + buffer[cur++] = ':'; + cur += itoa(elem->value.length, buffer + cur, 10); + } + + if (elem->value.length) { + buffer[cur++] = ' '; + memcpy(buffer + cur, PSYC_S2ARG(elem->value)); + cur += elem->value.length; + } + + // Actual length should be equal to pre-calculated length at this point. + ASSERT(cur == elem->length); + return PSYC_RENDER_SUCCESS; +} + +inline PsycRenderRC +psyc_render_dict_key (PsycDictKey *elem, char *buffer, size_t buflen) +{ + size_t cur = 0; + + if (elem->length > buflen) // return error if element doesn't fit in buffer + return PSYC_RENDER_ERROR; + + if (elem->value.length && !(elem->flag & PSYC_ELEM_NO_LENGTH)) + cur += itoa(elem->value.length, buffer + cur, 10); + + if (elem->value.length) { + buffer[cur++] = ' '; + memcpy(buffer + cur, PSYC_S2ARG(elem->value)); + cur += elem->value.length; + } + + // Actual length should be equal to pre-calculated length at this point. + ASSERT(cur == elem->length); + return PSYC_RENDER_SUCCESS; +} #ifdef __INLINE_PSYC_RENDER static inline @@ -12,51 +64,55 @@ PsycRenderRC psyc_render_list (PsycList *list, char *buffer, size_t buflen) { size_t i, cur = 0; - PsycString *elem; if (list->length > buflen) // return error if list doesn't fit in buffer return PSYC_RENDER_ERROR; - if (list->flag == PSYC_LIST_NEED_LENGTH) { - for (i = 0; i < list->num_elems; i++) { - elem = &list->elems[i]; - if (i > 0) - buffer[cur++] = '|'; - cur += itoa(elem->length, buffer + cur, 10); - buffer[cur++] = ' '; - memcpy(buffer + cur, elem->data, elem->length); - cur += elem->length; - } - } else { - for (i = 0; i < list->num_elems; i++) { - elem = &list->elems[i]; - buffer[cur++] = '|'; - memcpy(buffer + cur, elem->data, elem->length); - cur += elem->length; - } + if (list->type.length) { + memcpy(buffer + cur, PSYC_S2ARG(list->type)); + cur += list->type.length; + } + + for (i = 0; i < list->num_elems; i++) { + buffer[cur++] = '|'; + psyc_render_elem(&list->elems[i], buffer + cur, buflen - cur); + cur += list->elems[i].length; } -#ifdef DEBUG // Actual length should be equal to pre-calculated length at this point. - assert(cur == list->length); -#endif + ASSERT(cur == list->length); return PSYC_RENDER_SUCCESS; } +#ifdef __INLINE_PSYC_RENDER +static inline +#endif PsycRenderRC -psyc_render_table (PsycTable *table, char *buffer, size_t buflen) +psyc_render_dict (PsycDict *dict, char *buffer, size_t buflen) { - size_t cur = 0; + size_t i, cur = 0; - if (table->length > buflen) // return error if table doesn't fit in buffer + if (dict->length > buflen) // return error if dict doesn't fit in buffer return PSYC_RENDER_ERROR; - if (table->width > 0) { - cur = sprintf(buffer, "*%ld", table->width); - buffer[cur++] = ' '; + if (dict->type.length) { + memcpy(buffer + cur, PSYC_S2ARG(dict->type)); + cur += dict->type.length; } - return psyc_render_list(table->list, buffer + cur, buflen - cur); + for (i = 0; i < dict->num_elems; i++) { + buffer[cur++] = '{'; + psyc_render_dict_key(&dict->elems[i].key, buffer + cur, buflen - cur); + cur += dict->elems[i].key.length; + + buffer[cur++] = '}'; + psyc_render_elem(&dict->elems[i].value, buffer + cur, buflen - cur); + cur += dict->elems[i].value.length; + } + + // Actual length should be equal to pre-calculated length at this point. + ASSERT(cur == dict->length); + return PSYC_RENDER_SUCCESS; } static inline size_t @@ -70,7 +126,9 @@ psyc_render_modifier (PsycModifier *mod, char *buffer) if (cur == 1) return cur; // error, name can't be empty - if (mod->flag == PSYC_MODIFIER_NEED_LENGTH) { + if (mod->value.length + && (mod->flag & PSYC_MODIFIER_NEED_LENGTH + || mod->flag == PSYC_MODIFIER_CHECK_LENGTH)) { buffer[cur++] = ' '; cur += itoa(mod->value.length, buffer + cur, 10); } @@ -87,54 +145,52 @@ psyc_render_modifier (PsycModifier *mod, char *buffer) static inline #endif PsycRenderRC -psyc_render (PsycPacket *packet, char *buffer, size_t buflen) +psyc_render (PsycPacket *p, char *buffer, size_t buflen) { size_t i, cur = 0, len; - if (packet->length > buflen) // return error if packet doesn't fit in buffer + if (p->length > buflen) // return error if packet doesn't fit in buffer return PSYC_RENDER_ERROR; // render routing modifiers - for (i = 0; i < packet->routing.lines; i++) { - len = psyc_render_modifier(&packet->routing.modifiers[i], buffer + cur); + for (i = 0; i < p->routing.lines; i++) { + len = psyc_render_modifier(&p->routing.modifiers[i], buffer + cur); cur += len; if (len <= 1) return PSYC_RENDER_ERROR_MODIFIER_NAME_MISSING; } // add length if needed - if (packet->flag == PSYC_PACKET_NEED_LENGTH) - cur += itoa(packet->contentlen, buffer + cur, 10); + if (p->contentlen && !(p->flag & PSYC_PACKET_NO_LENGTH)) + cur += itoa(p->contentlen, buffer + cur, 10); - if (packet->flag == PSYC_PACKET_NEED_LENGTH || packet->content.length - || packet->stateop || packet->entity.lines - || packet->method.length || packet->data.length) + if (p->contentlen) buffer[cur++] = '\n'; // start of content part if there's content or length - if (packet->content.length) { // render raw content if present - memcpy(buffer + cur, packet->content.data, packet->content.length); - cur += packet->content.length; + if (p->content.length) { // render raw content if present + memcpy(buffer + cur, p->content.data, p->content.length); + cur += p->content.length; } else { - if (packet->stateop) { - buffer[cur++] = packet->stateop; + if (p->stateop) { + buffer[cur++] = p->stateop; buffer[cur++] = '\n'; } // render entity modifiers - for (i = 0; i < packet->entity.lines; i++) - cur += psyc_render_modifier(&packet->entity.modifiers[i], + for (i = 0; i < p->entity.lines; i++) + cur += psyc_render_modifier(&p->entity.modifiers[i], buffer + cur); - if (packet->method.length) { // add method\n - memcpy(buffer + cur, packet->method.data, packet->method.length); - cur += packet->method.length; + if (p->method.length) { // add method\n + memcpy(buffer + cur, p->method.data, p->method.length); + cur += p->method.length; buffer[cur++] = '\n'; - if (packet->data.length) { // add data\n - memcpy(buffer + cur, packet->data.data, packet->data.length); - cur += packet->data.length; + if (p->data.length) { // add data\n + memcpy(buffer + cur, p->data.data, p->data.length); + cur += p->data.length; buffer[cur++] = '\n'; } - } else if (packet->data.length) // error, we have data but no modifier + } else if (p->data.length) // error, we have data but no modifier return PSYC_RENDER_ERROR_METHOD_MISSING; } @@ -143,32 +199,6 @@ psyc_render (PsycPacket *packet, char *buffer, size_t buflen) buffer[cur++] = '\n'; // actual length should be equal to pre-calculated length at this point - assert(cur == packet->length); + ASSERT(cur == p->length); return PSYC_RENDER_SUCCESS; } - -PsycRenderRC -psyc_render_packet_id (char *context, size_t contextlen, - char *source, size_t sourcelen, - char *target, size_t targetlen, - char *counter, size_t counterlen, - char *fragment, size_t fragmentlen, - char *buffer, size_t buflen) -{ - PsycList list; - PsycString elems[PSYC_PACKET_ID_ELEMS] = {}; - - if (contextlen) - elems[PSYC_PACKET_ID_CONTEXT] = PSYC_STRING(context, contextlen); - if (sourcelen) - elems[PSYC_PACKET_ID_SOURCE] = PSYC_STRING(source, sourcelen); - if (targetlen) - elems[PSYC_PACKET_ID_TARGET] = PSYC_STRING(target, targetlen); - if (counterlen) - elems[PSYC_PACKET_ID_COUNTER] = PSYC_STRING(counter, counterlen); - if (fragmentlen) - elems[PSYC_PACKET_ID_FRAGMENT] = PSYC_STRING(fragment, fragmentlen); - - psyc_list_init(&list, elems, PSYC_PACKET_ID_ELEMS, PSYC_LIST_NO_LENGTH); - return psyc_render_list(&list, buffer, buflen); -} diff --git a/src/variable.c b/src/variable.c index 23c5e10..dfe1a3c 100644 --- a/src/variable.c +++ b/src/variable.c @@ -4,7 +4,7 @@ #include /// Routing variables in alphabetical order. -const PsycDictInt psyc_rvars[] = { +const PsycMapInt psyc_rvars[] = { { PSYC_C2STRI("_amount_fragments"), PSYC_RVAR_AMOUNT_FRAGMENTS }, { PSYC_C2STRI("_context"), PSYC_RVAR_CONTEXT }, { PSYC_C2STRI("_counter"), PSYC_RVAR_COUNTER }, @@ -30,26 +30,26 @@ const PsycDictInt psyc_rvars[] = { const size_t psyc_rvars_num = PSYC_NUM_ELEM(psyc_rvars); // Variable types in alphabetical order. -const PsycDictInt psyc_var_types[] = { +const PsycMapInt psyc_var_types[] = { { PSYC_C2STRI("_amount"), PSYC_TYPE_AMOUNT }, { PSYC_C2STRI("_color"), PSYC_TYPE_COLOR }, { PSYC_C2STRI("_date"), PSYC_TYPE_DATE }, - { PSYC_C2STRI("_def"), PSYC_TYPE_DEF }, { PSYC_C2STRI("_degree"), PSYC_TYPE_DEGREE }, + { PSYC_C2STRI("_dict"), PSYC_TYPE_DICT }, { PSYC_C2STRI("_entity"), PSYC_TYPE_ENTITY }, { PSYC_C2STRI("_flag"), PSYC_TYPE_FLAG }, { PSYC_C2STRI("_language"), PSYC_TYPE_LANGUAGE }, { PSYC_C2STRI("_list"), PSYC_TYPE_LIST }, { PSYC_C2STRI("_nick"), PSYC_TYPE_NICK }, { PSYC_C2STRI("_page"), PSYC_TYPE_PAGE }, - { PSYC_C2STRI("_table"), PSYC_TYPE_TABLE }, + { PSYC_C2STRI("_struct"), PSYC_TYPE_STRUCT }, { PSYC_C2STRI("_time"), PSYC_TYPE_TIME }, { PSYC_C2STRI("_uniform"), PSYC_TYPE_UNIFORM }, }; const size_t psyc_var_types_num = PSYC_NUM_ELEM(psyc_var_types); /// Method names in alphabetical order. -const PsycDictInt psyc_methods[] = { +const PsycMapInt psyc_methods[] = { { PSYC_C2STRI("_data"), PSYC_MC_DATA }, { PSYC_C2STRI("_echo_context_enter"), PSYC_MC_ECHO_CONTEXT_ENTER }, { PSYC_C2STRI("_echo_context_leave"), PSYC_MC_ECHO_CONTEXT_LEAVE }, @@ -88,7 +88,7 @@ const size_t psyc_methods_num = PSYC_NUM_ELEM(psyc_methods); PsycMethod psyc_method (char *method, size_t methodlen, PsycMethod *family, unsigned int *flag) { - int mc = psyc_dict_lookup_int(psyc_methods, psyc_methods_num, + int mc = psyc_map_lookup_int(psyc_methods, psyc_methods_num, method, methodlen, PSYC_YES); switch (mc) { diff --git a/test/Makefile b/test/Makefile index 662f2a2..1b1d98c 100644 --- a/test/Makefile +++ b/test/Makefile @@ -3,7 +3,7 @@ DEBUG = 2 CFLAGS = -I../include -I../src -Wall -std=c99 ${OPT} LDFLAGS = -L../lib LOADLIBES = -lpsyc -lm -TARGETS = test_psyc test_psyc_speed test_parser test_match test_render test_text var_routing var_type uniform_parse test_list test_table test_packet_id method +TARGETS = test_psyc test_psyc_speed test_parser test_match test_render test_text var_routing var_type uniform_parse test_packet_id test_index test_update method O = test.o WRAPPER = DIET = diet @@ -47,10 +47,13 @@ test: ${TARGETS} ./test_text ./var_routing ./var_type + ./method ./uniform_parse - ./test_list - ./test_table +# ./test_list +# ./test_table ./test_packet_id + ./test_index + ./test_update x=0; for f in packets/[0-9]*; do echo ">> $$f"; ./test_psyc -f $$f | ${DIFF} -u $$f -; x=$$((x+$$?)); done; exit $$x x=0; for f in packets/[0-9]*; do echo ">> $$f"; ./test_psyc -rf $$f | ${DIFF} -u $$f -; x=$$((x+$$?)); done; exit $$x diff --git a/test/packets/00-length-no-content b/test/packets/00-length-no-content deleted file mode 100644 index 0954c09..0000000 --- a/test/packets/00-length-no-content +++ /dev/null @@ -1,4 +0,0 @@ -:_source psyc://foo.example.com/ -:_target psyc://bar.example.com/ -0 -| diff --git a/test/packets/00-length-no-value b/test/packets/00-length-no-value deleted file mode 100644 index 87627cb..0000000 --- a/test/packets/00-length-no-value +++ /dev/null @@ -1,7 +0,0 @@ -:_source psyc://foo.example.com/ -:_target psyc://bar.example.com/ - -:_foo 0 -_message_private -OHAI -| diff --git a/test/packets/02-list b/test/packets/02-list index 9c9e37e..8f4b8ed 100644 --- a/test/packets/02-list +++ b/test/packets/02-list @@ -1,18 +1,17 @@ -=_source psyc://foo/~bar -:_target psyc://bar/~baz -=_list_foo |foo|bar|baz -:_tag sch1828hu3r2cm +=_context psyc://foo/~bar -=_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/ +=_list_xxx |=_foo|=_bar|=_baz|4 abc +=_list_foo |=_foo|=_bar ||=_baz| +=_list_foo _test|3 foo|=_color:4 blue|=_nick bar +=_list_bar 43 |3 foo|=_color:4 blue|=_nick bar|8 +foo|bar +=_list_bar 43 |3 foo|=_color:4 blue|=_nick bar|9 +foo|bar +=_list_a _type| elem1| elem2| elem3 +=_list_b |=_type1 elem1|=_type2 elem2|=_type3 elem3 +=_list_members _uniform| psyc://example.net/~alice| psyc://example.org/~bob +=_list_topic |9 democracy|3 now +=_list_c | foo| bar|6 foobar|3 baz|=_int 234|=_time 1234 +=_list_foo |=_int 234|=_time 1234|=_picture:3 \o/|7 \oXoXo/ +_test_list | diff --git a/test/packets/02-list2 b/test/packets/02-list2 new file mode 100644 index 0000000..59a722f --- /dev/null +++ b/test/packets/02-list2 @@ -0,0 +1,7 @@ +:_source psyc://foo/~bar +:_target psyc://bar/~baz + +=_list_foo _test|3 foo|=_color:4 blue|=_nick bar +=_list_bar |3 foo|=_color:4 blue|=_nick bar +_test +| diff --git a/test/packets/03-dict b/test/packets/03-dict new file mode 100644 index 0000000..174aefb --- /dev/null +++ b/test/packets/03-dict @@ -0,0 +1,11 @@ +=_context psyc://foo/~bar + +=_dict _type{4 key1}6 value1{key2} value2{key3}6 value3{key4} value4 +=_dict_example {4 key1}=_type1:6 value1{key2}=_type2 value2{key3}6 value3{key4} value4 +=_struct_member |=_nick|=_picture +=_dict_owners {psyc://example.net/~alice}{psyc://example.org/~bob} +=_dict_members {psyc://example.net/~alice}=_struct_member | alice| \o/{psyc://example.org/~bob}=_struct_member | bob| \oXo/ +=_dict_members {25 psyc://example.net/~alice}=_struct_member:12 | alice| \o/{psyc://example.org/~bob}=_struct_member | bob| \oXo/ +=_dict_members _struct_member{25 psyc://example.net/~alice}12 | alice| \o/{psyc://example.org/~bob} | bob| \oXo/ +_test_dict +| diff --git a/test/packets/03-list b/test/packets/03-list deleted file mode 100644 index f613741..0000000 --- a/test/packets/03-list +++ /dev/null @@ -1,20 +0,0 @@ -=_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/ -| diff --git a/test/packets/04-circuit b/test/packets/04-circuit index 5905f2b..089cc3a 100644 --- a/test/packets/04-circuit +++ b/test/packets/04-circuit @@ -1,4 +1,4 @@ -:_list_understand_modules |_state|_fragments|_context +:_list_understand_modules | _state| _fragments| _context _request_features | diff --git a/test/test_index.c b/test/test_index.c new file mode 100644 index 0000000..340a7ae --- /dev/null +++ b/test/test_index.c @@ -0,0 +1,87 @@ +#include +#include +#include +#include +#include + +uint8_t verbose; + +int +test_index (const char *buf, size_t buflen) +{ + char *res = malloc(buflen * 2); + size_t reslen = 0; + + int ret, reti, len = 0; + PsycString idx; + PsycParseIndexState state; + psyc_parse_index_state_init(&state); + psyc_parse_index_buffer_set(&state, buf, buflen); + + if (verbose) + printf(">> %.*s\n", (int)buflen, buf); + + do { + ret = reti = psyc_parse_index(&state, &idx); + len = 0; + + switch (ret) { + case PSYC_PARSE_INDEX_LIST_LAST: + ret = 0; + case PSYC_PARSE_INDEX_LIST: + len = sprintf(res + reslen, "#%ld", idx.length); + break; + case PSYC_PARSE_INDEX_STRUCT_LAST: + ret = 0; + case PSYC_PARSE_INDEX_STRUCT: + len = sprintf(res + reslen, ".%.*s", PSYC_S2ARGP(idx)); + break; + case PSYC_PARSE_INDEX_DICT: + if (state.elemlen_found) + len = sprintf(res + reslen, "{%ld %.*s}", + idx.length, PSYC_S2ARGP(idx)); + else + len = sprintf(res + reslen, "{%.*s}", PSYC_S2ARGP(idx)); + break; + case PSYC_PARSE_INDEX_END: + ret = 0; + break; + default: + ret = -1; + } + if (verbose) + printf("%2d: %.*s\n", reti, len, res + reslen); + reslen += len; + } while (ret > 0); + + if (reslen != buflen || memcmp(res, buf, buflen) != 0) { + printf("ERROR: got\n\[%.*s] (%ld) instead of\n[%.*s] (%ld)\n", + (int)reslen, res, reslen, (int)buflen, buf, buflen); + ret = 1; + } else + ret = 0; + + free(res); + return ret; +} + +int +main (int argc, char **argv) +{ + verbose = argc > 1; + + if (test_index(PSYC_C2ARG("#1{foo}._bar")) != 0) + return 1; + + if (test_index(PSYC_C2ARG("{3 foo}._bar#0")) != 0) + return 2; + + if (test_index(PSYC_C2ARG("{foo}#2._bar")) != 0) + return 3; + + if (test_index(PSYC_C2ARG("._bar#1{3 foo}")) != 0) + return 4; + + printf("test_index passed all tests.\n"); + return 0; // passed all tests +} diff --git a/test/test_list.c b/test/test_list.c index 723a9d9..560a52b 100644 --- a/test/test_list.c +++ b/test/test_list.c @@ -17,21 +17,25 @@ main (int argc, char **argv) PsycParseListState listState; PsycList list_text, list_bin; - PsycString elems_text[NELEMS], elems_bin[NELEMS], elem; + PsycElem elems_text[NELEMS], elems_bin[NELEMS]; + PsycString type, value; char buf_text[NELEMS * 200], buf_bin[NELEMS * 200], *elems[NELEMS], **elems2 = NULL; struct timeval start, end; + char *text = "1234567890abcdefghijklmnopqrstuvwxyz-._ " + "1234567890abcdefghijklmnopqrstuvwxyz-._ " + "1234567890abcdefghijklmnopqrstuvwxyz-._ " + "1234567890"; + char *bin = "1234567890|abcdefghijklmnopqrstuvwxyz|_\n" + "1234567890|abcdefghijklmnopqrstuvwxyz|_\n" + "1234567890|abcdefghijklmnopqrstuvwxyz|_\n" + "1234567890"; + for (i=0; i #include +uint8_t verbose; + int packet_id (char *context, size_t contextlen, char *source, size_t sourcelen, @@ -13,16 +15,22 @@ packet_id (char *context, size_t contextlen, char *fragment, size_t fragmentlen, char *result, size_t resultlen) { - size_t idlen = psyc_packet_id_length(contextlen, sourcelen, targetlen, - counterlen, fragmentlen); + PsycList list; + PsycElem elems[PSYC_PACKET_ID_ELEMS]; + memset(&list, 0, sizeof(PsycList)); + memset(elems, 0, sizeof(PsycElem) * PSYC_PACKET_ID_ELEMS); + + psyc_packet_id(&list, elems, context, contextlen, + source, sourcelen, target, targetlen, + counter, counterlen, fragment, fragmentlen); + + size_t idlen = list.length; char *id = malloc(idlen); - psyc_render_packet_id(context, contextlen, - source, sourcelen, - target, targetlen, - counter, counterlen, - fragment, fragmentlen, - id, idlen); - printf("%.*s\n", (int)idlen, id); + + psyc_render_list(&list, id, idlen); + + if (verbose) + printf("[%.*s]\n", (int)idlen, id); int ret = idlen == resultlen && memcmp(result, id, idlen) == 0; free(id); return ret; @@ -31,13 +39,16 @@ packet_id (char *context, size_t contextlen, int main (int argc, char **argv) { + verbose = argc > 1; + if (!packet_id(PSYC_C2ARG(""), PSYC_C2ARG("psyc://example.net/~alice"), PSYC_C2ARG("psyc://example.net/~bob"), PSYC_C2ARG("1337"), PSYC_C2ARG("42"), - PSYC_C2ARG("||psyc://example.net/~alice|psyc://example.net/~bob" - "|1337|42"))) + PSYC_C2ARG("|| psyc://example.net/~alice" + "| psyc://example.net/~bob" + "| 1337| 42"))) return 1; if (!packet_id(PSYC_C2ARG("psyc://example.net/@bar"), @@ -45,8 +56,9 @@ main (int argc, char **argv) PSYC_C2ARG(""), PSYC_C2ARG("1337"), PSYC_C2ARG("42"), - PSYC_C2ARG("|psyc://example.net/@bar|psyc://example.net/~alice|" - "|1337|42"))) + PSYC_C2ARG("| psyc://example.net/@bar" + "| psyc://example.net/~alice|" + "| 1337| 42"))) return 2; if (!packet_id(PSYC_C2ARG("psyc://example.net/@bar"), @@ -54,8 +66,9 @@ main (int argc, char **argv) PSYC_C2ARG("psyc://example.net/~alice"), PSYC_C2ARG("1337"), PSYC_C2ARG("42"), - PSYC_C2ARG("|psyc://example.net/@bar||psyc://example.net/~alice" - "|1337|42"))) + PSYC_C2ARG("| psyc://example.net/@bar|" + "| psyc://example.net/~alice" + "| 1337| 42"))) return 3; if (!packet_id(PSYC_C2ARG("psyc://example.net/@bar"), @@ -63,7 +76,7 @@ main (int argc, char **argv) PSYC_C2ARG(""), PSYC_C2ARG(""), PSYC_C2ARG(""), - PSYC_C2ARG("|psyc://example.net/@bar||||"))) + PSYC_C2ARG("| psyc://example.net/@bar||||"))) return 4; return 0; diff --git a/test/test_parser.c b/test/test_parser.c index 769ca23..d317903 100644 --- a/test/test_parser.c +++ b/test/test_parser.c @@ -12,7 +12,7 @@ main (int argc, char **argv) uint8_t verbose = argc > 2 && memchr(argv[2], (int)'v', strlen(argv[2])); int idx, ret; char buffer[2048], oper; - PsycString name, value, elem; + PsycString name, value, type; PsycParseState state; PsycParseListState listState; @@ -62,12 +62,13 @@ main (int argc, char **argv) psyc_parse_list_state_init(&listState); psyc_parse_list_buffer_set(&listState, PSYC_S2ARG(value)); - while ((ret = psyc_parse_list(&listState, &elem))) { + while ((ret = psyc_parse_list(&listState, &type, &value))) { switch (ret) { case PSYC_PARSE_LIST_END: case PSYC_PARSE_LIST_ELEM: if (verbose) - printf("|%.*s\n", (int)elem.length, elem.data); + printf("|%.*s %.*s\n", (int)type.length, type.data, + (int)value.length, value.data); break; default: printf("Error while parsing list: %i\n", ret); diff --git a/test/test_psyc.c b/test/test_psyc.c index 55699e1..447c7b7 100644 --- a/test/test_psyc.c +++ b/test/test_psyc.c @@ -8,9 +8,6 @@ #include #include -#include -#include -#include #include "test.c" @@ -71,10 +68,11 @@ test_input (int i, char *recvbuf, size_t nbytes) PsycPacket *packet = &packets[i]; char oper; - PsycString name, value, elem; + PsycString name, value, type; PsycString *pname = NULL, *pvalue = NULL; PsycModifier *mod = NULL; - PsycParseListState listState; + PsycParseListState lstate; + PsycParseDictState dstate; size_t len; // Set buffer with data for the parser. @@ -283,37 +281,131 @@ test_input (int i, char *recvbuf, size_t nbytes) oper = 0; name.length = 0; value.length = 0; + type.length = 0; - if (psyc_var_is_list(PSYC_S2ARG(*pname))) { + switch (psyc_var_type(PSYC_S2ARG(*pname))) { + case PSYC_TYPE_LIST: if (verbose >= 2) printf("## LIST START\n"); - psyc_parse_list_state_init(&listState); - psyc_parse_list_buffer_set(&listState, PSYC_S2ARG(*pvalue)); + psyc_parse_list_state_init(&lstate); + psyc_parse_list_buffer_set(&lstate, PSYC_S2ARG(*pvalue)); do { - retl = psyc_parse_list(&listState, &elem); + retl = psyc_parse_list(&lstate, &type, &value); switch (retl) { - case PSYC_PARSE_LIST_END: + case PSYC_PARSE_LIST_TYPE: + if (verbose >= 2) + printf("## LIST TYPE: %.*s\n", (int)type.length, type.data); + break; + case PSYC_PARSE_LIST_ELEM_START: + case PSYC_PARSE_LIST_ELEM_LAST: retl = 0; case PSYC_PARSE_LIST_ELEM: if (verbose >= 2) { - printf("|%.*s\n", (int)elem.length, elem.data); - if (ret == PSYC_PARSE_LIST_END) - printf("## LIST END"); + printf("|%.*s [%.*s]", (int)type.length, type.data, + (int)value.length, value.data); + if (retl == PSYC_PARSE_LIST_ELEM_START) + printf(" ..."); + printf("\n"); + if (ret == PSYC_PARSE_LIST_ELEM_LAST) + printf("## LAST ELEM\n"); } break; - + case PSYC_PARSE_LIST_ELEM_CONT: + retl = 0; + case PSYC_PARSE_LIST_ELEM_END: + if (verbose >= 2) { + printf("... [%.*s]", (int)value.length, value.data); + if (retl == PSYC_PARSE_LIST_ELEM_CONT) + printf(" ..."); + printf("\n"); + } + break; + case PSYC_PARSE_LIST_END: + retl = 0; + if (verbose >= 2) + printf("## LIST END\n"); + break; default: printf("# Error while parsing list: %i\n", retl); ret = retl = -1; } - } - while (retl > 0); + } while (retl > 0); + break; + case PSYC_TYPE_DICT: + if (verbose >= 2) + printf("## DICT START\n"); + + psyc_parse_dict_state_init(&dstate); + psyc_parse_dict_buffer_set(&dstate, PSYC_S2ARG(*pvalue)); + + do { + retl = psyc_parse_dict(&dstate, &type, &value); + switch (retl) { + case PSYC_PARSE_DICT_TYPE: + if (verbose >= 2) + printf("## DICT TYPE: %.*s\n", (int)type.length, type.data); + break; + case PSYC_PARSE_DICT_KEY_START: + retl = 0; + case PSYC_PARSE_DICT_KEY: + if (verbose >= 2) { + printf("{[%.*s]", (int)value.length, value.data); + if (retl == PSYC_PARSE_DICT_KEY_START) + printf(" ..."); + printf("\n"); + } + break; + case PSYC_PARSE_DICT_KEY_CONT: + retl = 0; + case PSYC_PARSE_DICT_KEY_END: + if (verbose >= 2) { + printf("... [%.*s]", (int)value.length, value.data); + if (retl == PSYC_PARSE_DICT_KEY_CONT) + printf(" ..."); + printf("\n"); + } + break; + case PSYC_PARSE_DICT_VALUE_START: + case PSYC_PARSE_DICT_VALUE_LAST: + retl = 0; + case PSYC_PARSE_DICT_VALUE: + if (verbose >= 2) { + printf("}%.*s [%.*s]", (int)type.length, type.data, + (int)value.length, value.data); + if (retl == PSYC_PARSE_DICT_VALUE_START) + printf(" ..."); + printf("\n"); + if (ret == PSYC_PARSE_DICT_VALUE_LAST) + printf("## LAST VALUE\n"); + } + break; + case PSYC_PARSE_DICT_VALUE_CONT: + retl = 0; + case PSYC_PARSE_DICT_VALUE_END: + if (verbose >= 2) { + printf("... [%.*s]", (int)value.length, value.data); + if (retl == PSYC_PARSE_DICT_VALUE_CONT) + printf(" ..."); + printf("\n"); + } + break; + case PSYC_PARSE_DICT_END: + retl = 0; + printf("## DICT END\n"); + break; + default: + printf("# Error while parsing dict: %i\n", retl); + ret = retl = -1; + } + } while (retl > 0); + break; + default: + break; } } - } - while (ret > 0); + } while (ret > 0); if (progress) r = write(1, " ", 1); diff --git a/test/test_render.c b/test/test_render.c index be57804..e02ab25 100644 --- a/test/test_render.c +++ b/test/test_render.c @@ -1,16 +1,15 @@ #include #include -#include -#include +#include #define myUNI "psyc://10.100.1000/~ludwig" /* example renderer generating a presence packet */ int -testPresence (char *avail, int availlen, - char *desc, int desclen, - char *rendered, uint8_t verbose) +test_presence (char *avail, int availlen, + char *desc, int desclen, + char *rendered, uint8_t verbose) { PsycModifier routing[1]; psyc_modifier_init(&routing[0], PSYC_OPERATOR_SET, @@ -42,7 +41,7 @@ testPresence (char *avail, int availlen, } int -testList (const char *rendered, uint8_t verbose) +test_list (const char *rendered, uint8_t verbose) { PsycModifier routing[2]; psyc_modifier_init(&routing[0], PSYC_OPERATOR_SET, @@ -52,23 +51,21 @@ testList (const char *rendered, uint8_t verbose) PSYC_C2ARG("_context"), PSYC_C2ARG(myUNI), PSYC_MODIFIER_ROUTING); - PsycString elems_text[] = { - PSYC_C2STR("foo"), - PSYC_C2STR("bar"), - PSYC_C2STR("baz"), + PsycElem elems_text[] = { + PSYC_ELEM_V("foo", 3), + PSYC_ELEM_V("bar", 3), + PSYC_ELEM_V("baz", 3), }; - PsycString elems_bin[] = { - PSYC_C2STR("foo"), - PSYC_C2STR("b|r"), - PSYC_C2STR("baz\nqux"), + PsycElem elems_bin[] = { + PSYC_ELEM_V("foo", 3), + PSYC_ELEM_V("b|r", 3), + PSYC_ELEM_V("baz\nqux", 7), }; PsycList list_text, list_bin; - psyc_list_init(&list_text, elems_text, - PSYC_NUM_ELEM(elems_text), PSYC_LIST_CHECK_LENGTH); - psyc_list_init(&list_bin, elems_bin, - PSYC_NUM_ELEM(elems_bin), PSYC_LIST_CHECK_LENGTH); + psyc_list_init(&list_text, elems_text, PSYC_NUM_ELEM(elems_text)); + psyc_list_init(&list_bin, elems_bin, PSYC_NUM_ELEM(elems_bin)); char buf_text[32], buf_bin[32]; psyc_render_list(&list_text, buf_text, sizeof(buf_text)); @@ -77,10 +74,12 @@ testList (const char *rendered, uint8_t verbose) PsycModifier entity[2]; psyc_modifier_init(&entity[0], PSYC_OPERATOR_SET, PSYC_C2ARG("_list_text"), - buf_text, list_text.length, list_text.flag); + buf_text, list_text.length, + PSYC_MODIFIER_CHECK_LENGTH); psyc_modifier_init(&entity[1], PSYC_OPERATOR_SET, PSYC_C2ARG("_list_binary"), - buf_bin, list_bin.length, list_bin.flag); + buf_bin, list_bin.length, + PSYC_MODIFIER_CHECK_LENGTH); PsycPacket packet; psyc_packet_init(&packet, routing, PSYC_NUM_ELEM(routing), @@ -102,21 +101,21 @@ main (int argc, char **argv) { uint8_t verbose = argc > 1; - if (testPresence(PSYC_C2ARG("_here"), PSYC_C2ARG("I'm omnipresent right now"), "\ + if (test_presence(PSYC_C2ARG("_here"), PSYC_C2ARG("I'm omnipresent right now"), "\ :_context\t" myUNI "\n\ -\n\ +97\n\ =_degree_availability\t_here\n\ -=_description_presence\tI'm omnipresent right now\n\ +=_description_presence 25\tI'm omnipresent right now\n\ _notice_presence\n\ |\n", verbose)) return 1; - if (testList("\ + if (test_list("\ :_source psyc://10.100.1000/~ludwig\n\ :_context psyc://10.100.1000/~ludwig\n\ -85\n\ -:_list_text |foo|bar|baz\n\ -:_list_binary 21 3 foo|3 b|r|7 baz\n\ +90\n\ +:_list_text 15 | foo| bar| baz\n\ +:_list_binary 20 | foo|3 b|r| baz\n\ qux\n\ _test_list\n\ list test\n\ diff --git a/test/test_update.c b/test/test_update.c new file mode 100644 index 0000000..2eeb8a5 --- /dev/null +++ b/test/test_update.c @@ -0,0 +1,140 @@ +#include +#include +#include +#include +#include + +uint8_t verbose; + +int +test_update (const char *buf, size_t buflen, + const char *r_idx, size_t r_idxlen, char r_oper, + const char *r_typ, size_t r_typlen, + const char *r_val, size_t r_vallen) +{ + char *idx = malloc(r_idxlen * 2); + char *typ = NULL, *val = NULL; + size_t idxlen = 0, typlen = 0, vallen = 0; + + int ret, reti, len = 0; + char oper; + PsycString value; + PsycParseUpdateState state; + psyc_parse_update_state_init(&state); + psyc_parse_update_buffer_set(&state, buf, buflen); + + if (verbose) + printf(">> %.*s\n", (int)buflen, buf); + + do { + ret = reti = psyc_parse_update(&state, &oper, &value); + len = 0; + + switch (ret) { + case PSYC_PARSE_INDEX_LIST: + len = sprintf(idx + idxlen, "#%ld", value.length); + break; + case PSYC_PARSE_INDEX_STRUCT: + len = sprintf(idx + idxlen, ".%.*s", PSYC_S2ARGP(value)); + break; + case PSYC_PARSE_INDEX_DICT: + if (state.elemlen_found) + len = sprintf(idx + idxlen, "{%ld %.*s}", + value.length, PSYC_S2ARGP(value)); + else + len = sprintf(idx + idxlen, "{%.*s}", PSYC_S2ARGP(value)); + break; + case PSYC_PARSE_UPDATE_TYPE_END: + ret = 0; + case PSYC_PARSE_UPDATE_TYPE: + typ = value.data; + typlen = value.length; + if (verbose) + printf("%c[%.*s]\n", oper, PSYC_S2ARGP(value)); + break; + case PSYC_PARSE_UPDATE_VALUE: + val = value.data; + vallen = value.length; + ret = 0; + if (verbose) + printf("[%.*s]\n", PSYC_S2ARGP(value)); + break; + case PSYC_PARSE_UPDATE_END: + ret = 0; + break; + default: + ret = -1; + } + if (verbose && len) + printf("%2d: %.*s\n", reti, len, idx + idxlen); + idxlen += len; + } while (ret > 0); + + if (ret == 0) { + if (idxlen != r_idxlen || oper != r_oper + || typlen != r_typlen || vallen != r_vallen + || memcmp(r_idx, idx, idxlen) != 0 + || memcmp(r_typ, typ, typlen) != 0 + || memcmp(r_val, val, vallen) != 0) { + printf("ERROR: got\n\[%.*s] %c[%.*s]:[%ld] [%.*s] instead of\n[%.*s]\n", + (int)idxlen, idx, oper, (int)typlen, typ, vallen, (int)vallen, val, + (int)buflen, buf); + ret = 1; + } else + ret = 0; + } + + free(idx); + return ret; +} + +int +main (int argc, char **argv) +{ + verbose = argc > 1; + + if (test_update(PSYC_C2ARG("#1{foo}._bar =_foo:3 bar"), + PSYC_C2ARG("#1{foo}._bar"), '=', + PSYC_C2ARG("_foo"), + PSYC_C2ARG("bar")) != 0) + return 1; + + if (test_update(PSYC_C2ARG("{3 foo}._bar#0 +:3 baz"), + PSYC_C2ARG("{3 foo}._bar#0"), '+', + PSYC_C2ARG(""), + PSYC_C2ARG("baz")) != 0) + return 2; + + if (test_update(PSYC_C2ARG("{foo}#2._bar - 1337"), + PSYC_C2ARG("{foo}#2._bar"), '-', + PSYC_C2ARG(""), + PSYC_C2ARG("1337")) != 0) + return 3; + + if (test_update(PSYC_C2ARG("._bar#1{3 foo} ="), + PSYC_C2ARG("._bar#1{3 foo}"), '=', + PSYC_C2ARG(""), + PSYC_C2ARG("")) != 0) + return 4; + + if (test_update(PSYC_C2ARG("#1{3 foo}._bar =_list"), + PSYC_C2ARG("#1{3 foo}._bar"), '=', + PSYC_C2ARG("_list"), + PSYC_C2ARG("")) != 0) + return 5; + + if (test_update(PSYC_C2ARG("#1{3 foo}._bar =_list "), + PSYC_C2ARG("#1{3 foo}._bar"), '=', + PSYC_C2ARG("_list"), + PSYC_C2ARG("")) != 0) + return 6; + + if (test_update(PSYC_C2ARG("#1{3 foo}._bar =_list"), + PSYC_C2ARG("#1{3 foo}._bar"), '=', + PSYC_C2ARG("_list"), + PSYC_C2ARG("")) != 0) + return 7; + + printf("test_update passed all tests.\n"); + return 0; // passed all tests +} From 632616a2fb599a40dc925c20b0253b905e82db7c Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Mon, 6 Feb 2012 15:07:27 +0100 Subject: [PATCH 367/378] Revert "we usually do it like this, but maybe we should do it like you say?" This reverts commit c0ec7c3e21398f160606fa92a98900be1a98db10. --- include/psyc/method.h | 4 ++-- src/variable.c | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/psyc/method.h b/include/psyc/method.h index 6a5ac93..bf445f9 100644 --- a/include/psyc/method.h +++ b/include/psyc/method.h @@ -19,8 +19,8 @@ typedef enum { PSYC_MC_ECHO_HELLO, PSYC_MC_ERROR, PSYC_MC_FAILURE, - PSYC_MC_FAILURE_UNKNOWN_ALIAS, - PSYC_MC_FAILURE_UNAVAILABLE_ALIAS, + PSYC_MC_FAILURE_ALIAS_NONEXISTANT, + PSYC_MC_FAILURE_ALIAS_UNAVAILABLE, PSYC_MC_INFO, PSYC_MC_MESSAGE, PSYC_MC_MESSAGE_ACTION, diff --git a/src/variable.c b/src/variable.c index 3ab235b..dfe1a3c 100644 --- a/src/variable.c +++ b/src/variable.c @@ -55,8 +55,8 @@ const PsycMapInt psyc_methods[] = { { PSYC_C2STRI("_echo_context_leave"), PSYC_MC_ECHO_CONTEXT_LEAVE }, { PSYC_C2STRI("_echo_hello"), PSYC_MC_ECHO_HELLO }, { PSYC_C2STRI("_echo"), PSYC_MC_ECHO }, - { PSYC_C2STRI("_failure_alias_nonexistant"),PSYC_MC_FAILURE_UNKNOWN_ALIAS }, - { PSYC_C2STRI("_failure_alias_unavailable"),PSYC_MC_FAILURE_UNAVAILABLE_ALIAS }, + { PSYC_C2STRI("_failure_alias_nonexistant"),PSYC_MC_FAILURE_ALIAS_NONEXISTANT }, + { PSYC_C2STRI("_failure_alias_unavailable"),PSYC_MC_FAILURE_ALIAS_UNAVAILABLE }, { PSYC_C2STRI("_failure"), PSYC_MC_FAILURE }, { PSYC_C2STRI("_info"), PSYC_MC_INFO }, { PSYC_C2STRI("_message_action"), PSYC_MC_MESSAGE_ACTION }, @@ -109,8 +109,8 @@ psyc_method (char *method, size_t methodlen, PsycMethod *family, unsigned int *f | PSYC_METHOD_LOGGABLE; break; case PSYC_MC_FAILURE: - case PSYC_MC_FAILURE_UNKNOWN_ALIAS: - case PSYC_MC_FAILURE_UNAVAILABLE_ALIAS: + case PSYC_MC_FAILURE_ALIAS_NONEXISTANT: + case PSYC_MC_FAILURE_ALIAS_UNAVAILABLE: *family = PSYC_MC_FAILURE; *flag = PSYC_METHOD_TEMPLATE | PSYC_METHOD_REPLY | PSYC_METHOD_VISIBLE | PSYC_METHOD_LOGGABLE; From 2a7778f86853e262b7174b787b141d04529213f9 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 15 Feb 2012 22:39:19 +0100 Subject: [PATCH 368/378] modifier, psyc-mode fix --- emacs/psyc.el | 4 ++-- include/psyc/packet.h | 8 ++++++++ include/psyc/render.h | 3 +++ src/render.c | 2 +- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/emacs/psyc.el b/emacs/psyc.el index fb38ac6..8015a7b 100644 --- a/emacs/psyc.el +++ b/emacs/psyc.el @@ -41,7 +41,7 @@ psyc-elem-name (concat psyc-elem-start "=" psyc-kw) psyc-elem-type (concat psyc-elem-start "=" psyc-types "\\b") psyc-elem-name-delim (concat psyc-elem-name "\\(:\\)") ;2 - psyc-elem-len (concat "\\(?:" psyc-elem-name-delim "\\)?" psyc-num) ;3 + psyc-elem-len (concat psyc-elem-start "\\(?:=" psyc-kw ":\\)?" psyc-num) ;2 psyc-update-op (concat "^@" psyc-kw psyc-mod-delim ".+ " psyc-op) ;3 psyc-update-name (concat "^@" psyc-kw psyc-mod-delim ".+ " @@ -91,7 +91,7 @@ (,psyc-elem-name . (1 font-lock-variable-name-face)) (,psyc-elem-type . (1 font-lock-type-face t)) (,psyc-elem-name-delim . (2 font-lock-comment-face)) - (,psyc-elem-len . (3 font-lock-constant-face)) + (,psyc-elem-len . (2 font-lock-constant-face)) (,psyc-elem-delim . (0 font-lock-keyword-face)) (,psyc-update-op . (3 font-lock-preprocessor-face)) diff --git a/include/psyc/packet.h b/include/psyc/packet.h index 88af733..9f593a8 100644 --- a/include/psyc/packet.h +++ b/include/psyc/packet.h @@ -198,6 +198,14 @@ typedef struct { char oper; } PsycModifier; +#define PSYC_MODIFIER(op, nam, val, flg) \ + (PsycModifier) { \ + .oper = op, \ + .name = nam, \ + .value = val, \ + .flag = flg, \ + } + /** Entity or routing header */ typedef struct { size_t lines; diff --git a/include/psyc/render.h b/include/psyc/render.h index 17cf066..17c794c 100644 --- a/include/psyc/render.h +++ b/include/psyc/render.h @@ -51,6 +51,9 @@ static inline PsycRenderRC psyc_render (PsycPacket *packet, char *buffer, size_t buflen); +size_t +psyc_render_modifier (PsycModifier *mod, char *buffer); + PsycRenderRC psyc_render_elem (PsycElem *elem, char *buffer, size_t buflen); diff --git a/src/render.c b/src/render.c index 21d9b08..8dd4829 100644 --- a/src/render.c +++ b/src/render.c @@ -115,7 +115,7 @@ psyc_render_dict (PsycDict *dict, char *buffer, size_t buflen) return PSYC_RENDER_SUCCESS; } -static inline size_t +inline size_t psyc_render_modifier (PsycModifier *mod, char *buffer) { size_t cur = 0; From 89b1466d58e493330b830f4a1b0625f4a5647712 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Wed, 15 Feb 2012 22:47:16 +0100 Subject: [PATCH 369/378] linking fix for -lm --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 92d8218..6e0ee6c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -27,7 +27,7 @@ lib: $A ${SO} ${SO}: $O @mkdir -p ../lib - ${CC} ${CFLAGS} -shared -lm -o $@ $O + ${CC} ${CFLAGS} -shared -o $@ $O -lm $A: $O @mkdir -p ../lib From 6bc4dbb8ccb79eaa5d3fc5282eb1cd6074e587c7 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 21 Feb 2012 03:00:52 +0100 Subject: [PATCH 370/378] c++ compat --- include/psyc.h | 15 +++++++++++++++ include/psyc/match.h | 4 ++-- include/psyc/packet.h | 12 +++++------- include/psyc/parse.h | 4 ++-- include/psyc/variable.h | 7 ++++--- 5 files changed, 28 insertions(+), 14 deletions(-) diff --git a/include/psyc.h b/include/psyc.h index 1689ac7..7be4ff8 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -17,6 +17,14 @@ #ifndef PSYC_H #define PSYC_H +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + #include #include #include @@ -72,4 +80,11 @@ typedef struct { #include "psyc/text.h" #include "psyc/uniform.h" +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/psyc/match.h b/include/psyc/match.h index 8be0704..b3c8c11 100644 --- a/include/psyc/match.h +++ b/include/psyc/match.h @@ -45,8 +45,8 @@ psyc_map_lookup (const PsycMap *map, size_t size, * @see psyc_map_lookup */ static inline intptr_t -psyc_map_lookup_int (const PsycMapInt * map, size_t size, - const char *key, size_t keylen, PsycBool inherit) +psyc_map_lookup_int (const PsycMapInt *map, size_t size, + const char *key, size_t keylen, PsycBool inherit) { return (intptr_t) psyc_map_lookup((PsycMap *) map, size, key, keylen, inherit); } diff --git a/include/psyc/packet.h b/include/psyc/packet.h index 9f593a8..9cb04cd 100644 --- a/include/psyc/packet.h +++ b/include/psyc/packet.h @@ -256,17 +256,15 @@ psyc_modifier_init (PsycModifier *m, PsycOperator oper, char *name, size_t namelen, char *value, size_t valuelen, PsycModifierFlag flag) { - *m = (PsycModifier) { - .oper = oper, - .name = {namelen, name}, - .value = {valuelen, value}, - .flag = flag - }; + m->oper = oper; + m->name = (PsycString){namelen, name}; + m->value = (PsycString){valuelen, value}; + m->flag = flag; if (flag == PSYC_MODIFIER_CHECK_LENGTH) // find out if it needs a length m->flag = psyc_modifier_length_check(m); else if (flag & PSYC_MODIFIER_ROUTING) - m->flag |= PSYC_MODIFIER_NO_LENGTH; + m->flag = (PsycModifierFlag)(m->flag | PSYC_MODIFIER_NO_LENGTH); } /** diff --git a/include/psyc/parse.h b/include/psyc/parse.h index 01ea398..71c32b0 100644 --- a/include/psyc/parse.h +++ b/include/psyc/parse.h @@ -611,7 +611,7 @@ psyc_parse_content_length (PsycParseState *state) static inline PsycBool psyc_parse_content_length_found (PsycParseState *state) { - return state->contentlen_found; + return (PsycBool) state->contentlen_found; } static inline size_t @@ -623,7 +623,7 @@ psyc_parse_value_length (PsycParseState *state) static inline PsycBool psyc_parse_value_length_found (PsycParseState *state) { - return state->valuelen_found; + return (PsycBool) state->valuelen_found; } static inline size_t diff --git a/include/psyc/variable.h b/include/psyc/variable.h index b947829..6005aef 100644 --- a/include/psyc/variable.h +++ b/include/psyc/variable.h @@ -72,7 +72,8 @@ static inline PsycRoutingVar psyc_var_routing (const char *name, size_t len) { return (PsycRoutingVar) - psyc_map_lookup((PsycMap*)psyc_rvars, psyc_rvars_num, name, len, PSYC_NO); + psyc_map_lookup_int((PsycMapInt*)psyc_rvars, psyc_rvars_num, name, len, + PSYC_NO); } /** @@ -82,8 +83,8 @@ static inline PsycType psyc_var_type (const char *name, size_t len) { return (PsycType) - psyc_map_lookup((PsycMap*)psyc_var_types, psyc_var_types_num, - name, len, PSYC_YES); + psyc_map_lookup_int((PsycMapInt*)psyc_var_types, psyc_var_types_num, + name, len, PSYC_YES); } /** From 01a79a37559ded04642af6de389a79631c1c3e46 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Mon, 27 Feb 2012 23:13:32 +0100 Subject: [PATCH 371/378] having to look through docs if you just want to install things can be confusing.. mami just spent time finding the line that says "make" --- INSTALL.org | 23 +++++++++++++++++++++++ README.org | 18 ------------------ 2 files changed, 23 insertions(+), 18 deletions(-) create mode 100644 INSTALL.org diff --git a/INSTALL.org b/INSTALL.org new file mode 100644 index 0000000..7f2ee09 --- /dev/null +++ b/INSTALL.org @@ -0,0 +1,23 @@ +#+TITLE: libpsyc INSTALL file +#+OPTIONS: toc:nil num:nil + +* Requirements + +libpsyc is currently known to compile under Linux and SunOS. +It depends on no one. + +* Compiling libpsyc + +Type +: make + +and you are done. + +Other possible targets include: + +: make install [prefix=/usr] # install into prefix +: make diet # compile with diet libc +: make test # compile and run the tests +: make doc # generate the API documentation (will be put in the doc folder) +: make help # display the possible targets + diff --git a/README.org b/README.org index 7c70580..3c7ab79 100644 --- a/README.org +++ b/README.org @@ -44,24 +44,6 @@ For more information see the API documentation at [[http://lib.psyc.eu/doc/]]. : test/ # test sourcecodes and test input files : d/ # the D binding -* Compiling libpsyc - -Type -: make - -and you are done. -Other possible targets include: - -: make install [prefix=/usr] # install into prefix -: make diet # compile with diet libc -: make test # compile and run the tests -: make doc # generate the API documentation (will be put in the doc folder) -: make help # display the possible targets - -* Requirements - -libpsyc is currently known to compile under Linux and SunOS. - * Authors The library is being developed by From 7513578c43f5f71b3599ea9e65476de0144b2c63 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Tue, 6 Mar 2012 02:36:30 +0100 Subject: [PATCH 372/378] _notice_peer_(dis)connect methods --- include/psyc/method.h | 4 ++++ src/variable.c | 2 ++ 2 files changed, 6 insertions(+) diff --git a/include/psyc/method.h b/include/psyc/method.h index bf445f9..2827cdd 100644 --- a/include/psyc/method.h +++ b/include/psyc/method.h @@ -32,6 +32,8 @@ typedef enum { PSYC_MC_NOTICE_CONTEXT_LEAVE, PSYC_MC_NOTICE_FRIENDSHIP, PSYC_MC_NOTICE_LINK, + PSYC_MC_NOTICE_PEER_CONNECT, + PSYC_MC_NOTICE_PEER_DISCONNECT, PSYC_MC_NOTICE_SET, PSYC_MC_NOTICE_UNLINK, PSYC_MC_REQUEST, @@ -70,6 +72,8 @@ typedef union PsycTemplates { PsycString _notice_context_leave; PsycString _notice_friendship; PsycString _notice_link; + PsycString _notice_peer_connect; + PsycString _notice_peer_disconnect; PsycString _notice_set; PsycString _notice_unlink; PsycString _request; diff --git a/src/variable.c b/src/variable.c index dfe1a3c..e1d1c3f 100644 --- a/src/variable.c +++ b/src/variable.c @@ -68,6 +68,8 @@ const PsycMapInt psyc_methods[] = { { PSYC_C2STRI("_notice_context_leave"), PSYC_MC_NOTICE_CONTEXT_LEAVE }, { PSYC_C2STRI("_notice_friendship"), PSYC_MC_NOTICE_FRIENDSHIP }, { PSYC_C2STRI("_notice_link"), PSYC_MC_NOTICE_LINK }, + { PSYC_C2STRI("_notice_peer_connect"), PSYC_MC_NOTICE_PEER_CONNECT }, + { PSYC_C2STRI("_notice_peer_disconnect"), PSYC_MC_NOTICE_PEER_DISCONNECT }, { PSYC_C2STRI("_notice_set"), PSYC_MC_NOTICE_SET }, { PSYC_C2STRI("_notice_unlink"), PSYC_MC_NOTICE_UNLINK }, { PSYC_C2STRI("_notice"), PSYC_MC_NOTICE }, From cda6a4331e3efe6f9c4449c690bfccce33db6069 Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Thu, 8 Mar 2012 10:29:43 +0100 Subject: [PATCH 373/378] template var names --- src/templates.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/templates.h b/src/templates.h index 4a0bf5b..bb701dd 100644 --- a/src/templates.h +++ b/src/templates.h @@ -13,16 +13,16 @@ _("[_nick] is not an alias"), ._request_context_enter = - _("[_nick] asks for your permission to enter [_nick_place]"), + _("[_source] asks for your permission to enter [_context]"), ._echo_context_enter = - _("You enter [_nick_place]" ), + _("You enter [_source]" ), ._echo_context_leave = - _("You leave [_nick_place]"), + _("You leave [_source]"), ._notice_context_enter = - _("[_nick] enters [_nick_place]"), + _("[_source] enters [_context]"), ._notice_context_leave = - _("[_nick] leaves [_nick_place]"), + _("[_source] leaves [_context]"), ._echo_hello = _("Received hello of psyc://[_key_public]:g/"), From a676950b28f74722bac132e49004aa0aca1b4f03 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Sun, 6 May 2012 15:39:02 +0200 Subject: [PATCH 374/378] criticism of "id" was inaccurate. fixed. --- bench/benchmark.org | 11 +++++++---- bench/packets/chat_msg.xml | 3 +-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/bench/benchmark.org b/bench/benchmark.org index 4382cdb..05bcf77 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -97,11 +97,14 @@ for future projects: #+INCLUDE: packets/chat_msg.json src js #+INCLUDE: packets/chat_msg.psyc src psyc -Why PSYC doesn't have an id? Because packet counting from contexts -and circuits is automatic: The packet already has a number just by -being there. +# Why PSYC doesn't have an id? Because for most operations they aren't +# needed: PSYC has automatic packet counting from contexts and circuits. +# Therefore, the packet already has an id just by being there. +# Should you want to tag a packet anyway, you can do so by adding a _tag. +# +# Update: XMPP doesn't *need* to have an id there, so we can just remove it. -Also, PSYC by default doesn't mention a "resource" in XMPP terms, +Little difference: PSYC by default doesn't mention a "resource" in XMPP terms, instead it allows for more addressing schemes than just PSYC. ** A new status updated activity diff --git a/bench/packets/chat_msg.xml b/bench/packets/chat_msg.xml index eec1675..bcceaa4 100644 --- a/bench/packets/chat_msg.xml +++ b/bench/packets/chat_msg.xml @@ -1,4 +1,3 @@ - + Art thou not Romeo, and a Montague? From 359915a5682d850798bfcd8ead202b455258a7f7 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Fri, 11 May 2012 11:49:17 +0200 Subject: [PATCH 375/378] thx to urs, made it less confusing --- INSTALL.org | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/INSTALL.org b/INSTALL.org index 7f2ee09..4fe3d71 100644 --- a/INSTALL.org +++ b/INSTALL.org @@ -11,13 +11,18 @@ It depends on no one. Type : make -and you are done. +* Installation -Other possible targets include: +So that other projects like psycd and psyced immediately +find the library on compilation... -: make install [prefix=/usr] # install into prefix -: make diet # compile with diet libc -: make test # compile and run the tests -: make doc # generate the API documentation (will be put in the doc folder) -: make help # display the possible targets +: [sudo] make install [prefix=/usr] # install into prefix + +* Other possible targets include: + +: make help # display the possible targets +: make test # compile and run the tests +: make diet # compile with diet libc +: make doc # generate the API documentation + # (will be put in the doc folder) From d37879cae5d5c1cf45f0c5b19c98d73f6d1092e3 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Fri, 7 Sep 2012 21:57:30 +0200 Subject: [PATCH 376/378] - --- INSTALL.org | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/INSTALL.org b/INSTALL.org index 4fe3d71..eb95ee2 100644 --- a/INSTALL.org +++ b/INSTALL.org @@ -26,3 +26,7 @@ find the library on compilation... : make doc # generate the API documentation # (will be put in the doc folder) +* Bug Reporting + +https://projects.tgbit.net/projects/psyc + From c66ef5227fde5a46b33a1c68e2bac66c4bf75798 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Wed, 4 Sep 2013 15:54:18 +0200 Subject: [PATCH 377/378] BSD --- README.org | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.org b/README.org index 7c70580..14f2281 100644 --- a/README.org +++ b/README.org @@ -46,8 +46,11 @@ For more information see the API documentation at [[http://lib.psyc.eu/doc/]]. * Compiling libpsyc -Type +On GNU systems, type : make + +On other systems install GNU make, then type +: gmake and you are done. Other possible targets include: From 0db086944376e895d214f9727656bcf69efb8dfa Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" Date: Fri, 14 Aug 2015 10:45:55 +0200 Subject: [PATCH 378/378] update org-mode syntax, include benchmark.html --- bench/.gitignore | 4 +- bench/Makefile | 4 +- bench/benchmark.html | 1104 ++++++++++++++++++++++++++++++++++++++++++ bench/benchmark.org | 1 + 4 files changed, 1109 insertions(+), 4 deletions(-) create mode 100644 bench/benchmark.html diff --git a/bench/.gitignore b/bench/.gitignore index fd2f6c3..71da57f 100644 --- a/bench/.gitignore +++ b/bench/.gitignore @@ -1,4 +1,4 @@ -*.html -*.pdf +# *.html +# *.pdf results/ packets/binary/[0-9]* diff --git a/bench/Makefile b/bench/Makefile index cecdfe3..2c9c80b 100644 --- a/bench/Makefile +++ b/bench/Makefile @@ -10,11 +10,11 @@ INIT = (setq load-path (cons \"/usr/share/emacs/site-lisp/org-mode\" load-path) #' ORG = benchmark.org -html: +it: for f in ${ORG}; do \ emacs -Q --batch --eval \ "(progn ${INIT} (find-file \"$$f\") \ - (org-export-as-html-batch) (kill-buffer))"; \ + (org-html-export-to-html) (kill-buffer))"; \ done pdf: diff --git a/bench/benchmark.html b/bench/benchmark.html new file mode 100644 index 0000000..537c7da --- /dev/null +++ b/bench/benchmark.html @@ -0,0 +1,1104 @@ + + + + +libpsyc Performance Benchmarks + + + + + + + + + +
+

libpsyc Performance Benchmarks

+ + + +

+In this document we present the results of performance benchmarks +of libpsyc compared to json-c, libjson-glib, rapidxml and libxml2. +

+ +
+

1 PSYC, JSON, XML Syntax Benchmarks

+
+

+First we look at the mere performance of the PSYC syntax +compared to equivalent XML and JSON encodings. We'll +look at actual XMPP messaging later. +

+
+ +
+

1.1 User Profile

+
+

+In this test we'll compare the efficiency of the three +syntaxes at serializing a typical user data base +storage information. Let's start with XML: +

+ +
+ +
<UserProfile>
+    <Name>Silvio Berlusconi</Name>
+    <JobTitle>Premier</JobTitle>
+    <Country>I</Country>
+    <Address>
+	    <Street>Via del Colosseo, 1</Street>
+	    <PostalCode>00100</PostalCode>
+	    <City>Roma</City>
+    </Address>
+    <Page>http://example.org</Page>
+</UserProfile>
+
+
+ +

+In JSON this could look like this: +

+ +
+ +
["UserProfile",{"Name":"Silvio Berlusconi","JobTitle":"Premier","Country":"I","Address":
+{"Street":"Via del Colosseo, 1","PostalCode":"00100","City":"Roma"},"Page":"http://example.org"}]
+
+
+ +

+Here's a way to model this in PSYC (verbose mode): +

+ +
+ +
:_name	Silvio Berlusconi
+:_title_job	Premier
+:_country	I
+:_address_street	Via del Colosseo, 1
+:_address_code_postal	00100
+:_address_city	Roma
+:_page	http://example.org
+_profile_user
+|
+
+
+
+
+ +
+

1.2 A message with JSON-unfriendly characters

+
+

+This message contains some characters which are +impractical to encode in JSON. We should probably +put a lot more inside to actually see an impact +on performance. TODO +

+ +
+ +
<message from='romeo@example.net/orchard' to='juliet@example.com/balcony'>
+<body>"Neither, fair saint, if either thee dislike.", he said.
+And
+the
+rest
+is
+history.</body>
+</message>
+
+
+
+ +
["message",{"from":"romeo@example.net/orchard","to":"juliet@example.com/balcony"},
+"\"Neither, fair saint, if either thee dislike.\", he said.\nAnd\nthe\nrest\nis\nhistory."]
+
+
+
+ +
:_source	psyc://example.com/~romeo
+:_target	psyc://example.net/~juliet
+
+_message
+"Neither, fair saint, if either thee dislike.", he said.
+And
+the
+rest
+is
+history.
+|
+
+
+
+
+ +
+

1.3 A message with XML-unfriendly characters

+
+

+Same test with characters which aren't practical +in the XML syntax, yet we should put more of +them inside. TODO +

+ +
+ +
<message from='juliet@example.com/balcony' to='romeo@example.net'>
+<body>Pro&#x010D;e&#x017D; jsi ty, Romeo?</body>
+</message>
+
+
+
+ +
["message",{"from":"juliet@example.com/balcony","to":"romeo@example.net"},
+"Pro\u010de\u017d jsi ty, Romeo?"]
+
+
+
+ +
:_source	psyc://example.com/~juliet
+:_target	psyc://example.net/~romeo
+
+_message
+ Pro&#x010D;e&#x017D; jsi ty, Romeo?
+|
+
+
+
+
+ +
+

1.4 A message with PSYC-unfriendly strings

+
+

+PSYC prefixes data with length as soon as it +exceeds certain sizes or contains certain strings. +In the case of short messages this is less +efficient than scanning the values without lengths. +Also, lengths are harder to edit by hand. +

+ +
+ +
<message from='juliet@example.com/balcony' to='romeo@example.net'>
+<subject>I implore you with a pointless
+newline in a header variable</subject>
+<body>Wherefore art thou, Romeo?
+|
+And for practicing purposes we added a PSYC packet delimiter.</body>
+</message>
+
+
+
+ +
["message",{"from":"juliet@example.com/balcony","to":"romeo@example.net",
+"subject":"I implore you with a pointless\nnewline in a header variable"},
+"Wherefore art thou, Romeo?\n|\nAnd for practicing purposes we added a PSYC packet delimiter."]
+
+
+
+ +
:_source	psyc://example.com/~juliet
+:_target	psyc://example.net/~romeo
+173
+:_subject 59	I implore you with a pointless
+newline in a header variable
+_message
+Wherefore art thou, Romeo?
+|
+And for practicing purposes we added a PSYC packet delimiter.
+|
+
+
+
+
+ +
+

1.5 Packets containing binary data

+
+

+We'll use a generator of random binary data to +see how well the formats behave with different +sizes of data. We'll consider 7000 as a possible +size of an icon, 70000 for an avatar, 700000 +for a photograph, 7000000 for a piece of music, +70000000 for a large project and +700000000 for the contents of a CD. +

+
+
+
+ +
+

2 PSYC vs XMPP Protocol Benchmarks

+
+

+These tests use typical messages from the XMPP ("stanzas" in +Jabber lingo) and compare them with equivalent JSON encodings +and PSYC formats. +

+
+ +
+

2.1 A presence packet

+
+

+Since presence packets are by far the dominant messaging content +in the XMPP network, we'll start with one of them. +Here's an example from paragraph 4.4.2 of RFC 6121. +

+ +
+ +
<presence from='juliet@example.com/balcony'
+            to='benvolio@example.net'>
+	<show>away</show>
+</presence>
+
+
+ +

+And here's the same information in a JSON rendition: +

+ +
+ +
["presence",{"from":"juliet@example.com/balcony","to":"benvolio@example.net"},{"show":"away"}]
+
+
+ +

+Here's the equivalent PSYC packet in verbose mode +(since it is a multicast, the single recipients do not +need to be mentioned): +

+ +
+ +
:_context	psyc://example.com/~juliet
+
+=_degree_availability	4
+_notice_presence
+|
+
+
+ +

+And this is the same message in PSYC's compact form, but since compact mode +hasn't been implemented nor deployed yet, you should only consider this +for future projects: +

+ +
+ +
:c	psyc://example.com/~juliet
+
+=da	4
+np
+|
+
+
+
+
+ +
+

2.2 An average chat message

+
+
+ +
<message from='juliet@example.com/balcony' to='romeo@example.net' type='chat'>
+<body>Art thou not Romeo, and a Montague?</body>
+</message>
+
+
+
+ +
["message",{"from":"juliet@example.com/balcony","to":"romeo@example.net"},
+"Art thou not Romeo, and a Montague?"]
+
+
+
+ +
:_source	psyc://example.com/~juliet
+:_target	xmpp:romeo@example.net
+
+_message
+Art thou not Romeo, and a Montague?
+|
+
+
+ +

+Little difference: PSYC by default doesn't mention a "resource" in XMPP terms, +instead it allows for more addressing schemes than just PSYC. +

+
+
+ +
+

2.3 A new status updated activity

+
+

+Example taken from http://onesocialweb.org/spec/1.0/osw-activities.html +You could call this XML namespace hell.. :-) +

+ +
+ +
<iq type='set'
+    from='hamlet@denmark.lit/snsclient'
+    to='hamlet@denmark.lit'
+    id='osw1'>
+ <pubsub xmlns='http://jabber.org/protocol/pubsub'>
+    <publish node='urn:xmpp:microblog:0'>
+      <item>
+        <entry xmlns="http://www.w3.org/2005/Atom" 
+               xmlns:activity="http://activitystrea.ms/spec/1.0/" 
+               xmlns:osw="http://onesocialweb.org/spec/1.0/">
+          <title>to be or not to be ?</title>
+          <activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
+          <activity:object>
+            <activity:object-type>http://onesocialweb.org/spec/1.0/object/status</activity:object-type>
+            <content type="text/plain">to be or not to be ?</content>
+          </activity:object>
+          <osw:acl-rule>
+            <osw:acl-action permission="http://onesocialweb.org/spec/1.0/acl/permission/grant">
+              http://onesocialweb.org/spec/1.0/acl/action/view
+            </osw:acl-action>
+            <osw:acl-subject type="http://onesocialweb.org/spec/1.0/acl/subject/everyone"/>
+          </osw:acl-rule>
+        </entry>
+      </item>
+    </publish>
+  </pubsub>
+</iq>
+
+
+ +

+http://activitystrea.ms/head/json-activity.html proposes a JSON encoding +of this. We'll have to add a routing header to it. +

+ +
+ +
["activity",{"from":"hamlet@denmark.lit/snsclient"},{"verb":"post",
+"title":"to be or not to be ?","object":{"type":"status",
+"content":"to be or not to be ?","contentType":"text/plain"}}]
+
+
+ +

+http://about.psyc.eu/Activity suggests a PSYC mapping for activity +streams. Should a "status post" be considered equivalent to a presence +description announcement or just a message in the "microblogging" channel? +We'll use the latter here: +

+ +
+ +
:_context	psyc://denmark.lit/~hamlet#_follow
+
+:_subject	to be or not to be ?
+:_type_content	text/plain
+_message
+to be or not to be ?
+|
+
+
+ +

+It's nice about XML namespaces how they can by definition never collide, +but this degree of engineering perfection causes us a lot of overhead. +The PSYC approach is to just extend the name of the method - as long as +people use differing method names, protocol extensions can exist next +to each other happily. Method name unicity cannot mathematically be ensured, +but it's enough to append your company name to make it unlikely for anyone +else on earth to have the same name. How this kind of safety is delivered +when using the JSON syntax of ActivityStreams is unclear. Apparently it was +no longer an important design criterion. +

+
+
+
+ +
+

3 Results

+
+

+Parsing time of 1 000 000 packets, in milliseconds. +A simple strlen() scan of the respective message is provided for comparison. +These tests were performed on a 2.53 GHz Intel(R) Core(TM)2 Duo P9500 CPU. +

+ + + + +++ + +++ ++ + +++ ++ + +++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 strlenlibpsycjson-cjson-gliblibxml saxlibxmlrapidxml
user profile556084715165037350123772477
psyc-unfriendly70286289212567553886591896
json-unfriendly49430232810006514178751751
xml-unfriendly3729621569591557187691765
+ +

+Pure syntax comparisons above, protocol performance comparisons below: +

+ + + + +++ + +++ ++ ++ + +++ ++ + +++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 strlenlibpsyclibpsyc compactjson-cjson-gliblibxml saxlibxmlrapidxml
presence30236122246310016499775571719
chat msg4029525821479526591189991850
activity4235327946661632713357288584356
+ +

+Parsing large amounts of binary data. For JSON & XML base64 encoding was used. +Note that the results below include only the parsing time, base64 decoding was +not performed. +

+ + + + +++ + +++ ++ + +++ ++ + +++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 strlenlibpsycjson-cjson-gliblibxml saxlibxmlrapidxml
7K97877186099800011445192998701
70K96137718754010039009620916773874296
700K95888771883500106160008420251909428729419
7M1347300782635900012081000012466610167513637581169
70M1441400080357010000124100000016962211029601782075308906
+ +

+In each case we compared performance of parsing and re-rendering +these messages, but consider also that the applicative processing +of an XML DOM tree is more complicated than just accessing +certain elements in a JSON data structure or PSYC variable mapping. +

+
+
+ +
+

4 Explanations

+
+

+As you can tell the PSYC data format outpaces its rivals in all circumstances. +Extremely so when delivering binary data as PSYC simply returns the starting +point and the length of the given buffer while the other parsers have to scan +for the end of the transmission, but also with many simpler operations, when +PSYC quickly figures out where the data starts and ends and passes such +information back to the application while the other formats are forced to +generate a copy of the data in order to process possibly embedded special +character sequences. PSYC essentially operates like a binary data protocol +even though it is actually text-based. +

+
+
+ +
+

5 Criticism

+
+

+Are we comparing apples and oranges? Yes and no, depends on what you +need. XML is a syntax best suited for complex structured data in +well-defined formats - especially good for text mark-up. JSON is a syntax +intended to hold arbitrarily structured data suitable for immediate +inclusion in Javascript source codes. The PSYC syntax is an evolved +derivate of RFC 822, the syntax used by HTTP and E-Mail. It is currently +limited in the kind and depth of data structures that can be represented +with it, but it is highly efficient in exchange. +

+ +

+In fact we are currently looking into suitable syntax extensions to represent +generic structures and semantic signatures, but for now PSYC only +provides for simple typed values and lists of typed values. +

+
+
+ +
+

6 Ease of Implementation

+
+

+Another aspect is the availability of these formats for spontaneous +use. You could generate and parse JSON yourself but you have to be +careful about escaping. XML can be rendered manually if you know your +data will not break the syntax, but you shouldn't dare to parse it without +a bullet proof parser. PSYC is easy to render and parse yourself for +simple tasks, as long as the body does not contain "\n|\n" and your +variables do not contain newlines. +

+
+
+ +
+

7 Conclusions

+
+

+After all it is up to you to find out which format fulfils your +requirements the best. We use PSYC for the majority of messaging where +JSON and XMPP aren't efficient and opaque enough, but we employ XML and +JSON as payloads within PSYC for data that doesn't fit the PSYC model. +For some reason all three formats are being used for messaging, although +only PSYC was actually designed for that purpose. +

+ +

+The Internet has developed two major breeds of protocol formats. +The binary ones are extremely efficient but in most cases you have +to recompile all instances each time you change something +while the plain-text ones are reaching out for achieving perfection +in data representation while leaving the path of efficiency. Some +protocols such as HTTP and SIP are in-between these two schools, +offering both a text-based extensible syntax (it's actually easier to +add a header to HTTP than to come up with a namespace for XMPP…) +and the ability to deliver binary data. But these protocols do not +come with native data structure support. PSYC is a protocol that +combines the compactness and efficiency of binary protocols with the +extensibility of text-based protocols and still provides for enough +data structuring to rarely require the use of other data formats. +

+
+
+ +
+

8 Futures

+
+

+After a month of development libpsyc is already performing pretty +well, but we presume various optimizations, like rewriting parts +in assembler, are possible. +

+
+
+ +
+

9 Related Work

+
+

+If this didn't help, you can also look into: +

+ +
    +
  • Adobe AMF +
  • +
  • ASN.1 +
  • +
  • BSON +
  • +
  • Cisco Etch +
  • +
  • Efficient XML +
  • +
  • Facebook Thrift +
  • +
  • Google Protocol Buffers +
  • +
+ +

+The drawback of these binary formats is, unlike PSYC, JSON and XML +you can't edit them manually and you can't produce valid messages +by replacing variables in a simple text template. You depend on +specialized parsers and renderers to be provided. +

+ +

+There's also +

+ +
    +
  • Bittorrent's bencode +
  • +
+ +

+This format is formally text-based, but not easy to read as it doesn't +have any visual separators and isn't easy to edit as everything is +prefixed by lengths even for very short items. +

+
+
+ +
+

10 Further Reading

+
+

+http://about.psyc.eu/Spec:Syntax provides you with the ABNF grammar +of the PSYC 1.0 syntax. You may also be interested in PSYC's decentralized +state mechanism provided by the +/-/= operators. +

+ +

+See http://about.psyc.eu/XML and http://about.psyc.eu/JSON for more +biased information on the respective formats. +

+
+
+ +
+

11 Appendix

+
+
+

11.1 Tools used

+
+

+This document and its benchmarks are distributed with libpsyc. +See http://about.psyc.eu/libpsyc on how to obtain it. +

+ +

+The benchmarks can be run with the following command +(xmlbench is needed for the xml tests): +

+ +
+make bench
+
+
+
+
+
+
+

Created: 2015-08-14 Fri 10:43

+

Emacs 24.4.1 (Org mode 8.2.6)

+

Validate

+
+ + diff --git a/bench/benchmark.org b/bench/benchmark.org index 05bcf77..affdc13 100644 --- a/bench/benchmark.org +++ b/bench/benchmark.org @@ -1,4 +1,5 @@ #+TITLE: libpsyc Performance Benchmarks +#+HTML: In this document we present the results of performance benchmarks of libpsyc compared to json-c, libjson-glib, rapidxml and libxml2.