From cf02d065cf99574d968fbd6b120d1de7bccc6baa Mon Sep 17 00:00:00 2001 From: Gabor Adam Toth Date: Fri, 11 Nov 2011 22:18:24 +0100 Subject: [PATCH] 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 }