1
0
Fork 0
mirror of git://git.psyc.eu/libpsyc synced 2024-08-15 03:19:02 +00:00

dict syntax; index & update mod parser; psyc-mode for emacs

This commit is contained in:
tg(x) 2012-02-06 15:05:08 +01:00
parent eaeab8c226
commit 71866659f9
31 changed files with 2063 additions and 691 deletions

View file

@ -4,7 +4,7 @@ prefix = /usr
includedir = ${prefix}/include
INSTALL = install
HEADERS = match.h method.h packet.h parse.h render.h syntax.h text.h uniform.h variable.h
HEADERS = match.h method.h packet.h parse.h render.h text.h uniform.h variable.h
install: ${HEADERS}

View file

@ -1,12 +1,15 @@
#ifndef PSYC_MATCH_H
#define PSYC_MATCH_H
typedef struct {
PsycString key;
void *value;
} PsycDict;
} PsycMap;
typedef struct {
PsycString key;
intptr_t value;
} PsycDictInt;
} PsycMapInt;
/**
* Checks if long keyword string inherits from short keyword string.
@ -21,10 +24,10 @@ int
psyc_matches (char *sho, size_t slen, char *lon, size_t llen);
/**
* Look up value associated with a key in a dictionary.
* Look up value associated with a key in a map.
*
* @param dict The dictionary to search, should be ordered alphabetically.
* @param size Size of dict.
* @param map The dictionary to search, should be ordered alphabetically.
* @param size Size of map.
* @param key Key to look for.
* @param keylen Length of key.
* @param inherit If true, also look for anything inheriting from key,
@ -34,16 +37,18 @@ psyc_matches (char *sho, size_t slen, char *lon, size_t llen);
*/
void *
psyc_dict_lookup (const PsycDict *dict, size_t size,
const char *key, size_t keylen, PsycBool inherit);
psyc_map_lookup (const PsycMap *map, size_t size,
const char *key, size_t keylen, PsycBool inherit);
/**
* Look up value associated with a key in a dictionary of integers.
* @see psyc_dict_lookup
* Look up value associated with a key in a map with integer values.
* @see psyc_map_lookup
*/
static inline intptr_t
psyc_dict_lookup_int (const PsycDictInt * dict, size_t size,
psyc_map_lookup_int (const PsycMapInt * map, size_t size,
const char *key, size_t keylen, PsycBool inherit)
{
return (intptr_t) psyc_dict_lookup((PsycDict *) dict, size, key, keylen, inherit);
return (intptr_t) psyc_map_lookup((PsycMap *) map, size, key, keylen, inherit);
}
#endif

View file

@ -18,9 +18,53 @@
#include <math.h>
#include "syntax.h"
#include "method.h"
/**
* Maximum allowed content size without length.
* Parser stops after reaching this limit.
*/
#define PSYC_CONTENT_SIZE_MAX 512
/**
* Content size after which a length is added when rendering.
*/
#ifndef PSYC_CONTENT_SIZE_THRESHOLD
# define PSYC_CONTENT_SIZE_THRESHOLD 9
#endif
/**
* Maximum allowed modifier size without length.
* Parser stops after reaching this limit.
*/
#define PSYC_MODIFIER_SIZE_MAX 256
/**
* Modifier size after which a length is added when rendering.
*/
#ifndef PSYC_MODIFIER_SIZE_THRESHOLD
# define PSYC_MODIFIER_SIZE_THRESHOLD 9
#endif
/**
* Maximum allowed element size without length.
* Parser stops after reaching this limit.
*/
#define PSYC_ELEM_SIZE_MAX 128
/**
* Element size after which a length is added when rendering.
*/
#ifndef PSYC_ELEM_SIZE_THRESHOLD
# define PSYC_ELEM_SIZE_THRESHOLD 9
#endif
#define PSYC_PACKET_DELIMITER_CHAR '|'
#define PSYC_PACKET_DELIMITER "\n|\n"
#define PSYC_LIST_ELEM_START '|'
#define PSYC_DICT_KEY_START '{'
#define PSYC_DICT_KEY_END '}'
#define PSYC_DICT_VALUE_START PSYC_DICT_KEY_END
#define PSYC_DICT_VALUE_END PSYC_DICT_KEY_START
/** Modifier flags. */
typedef enum {
/// Modifier needs to be checked if it needs length.
@ -30,18 +74,18 @@ typedef enum {
/// Modifier doesn't need length.
PSYC_MODIFIER_NO_LENGTH = 2,
/// Routing modifier, which implies that it doesn't need length.
PSYC_MODIFIER_ROUTING = 3,
PSYC_MODIFIER_ROUTING = 4,
} PsycModifierFlag;
/** List flags. */
/** List/dict element flags. */
typedef enum {
/// List needs to be checked if it needs length.
PSYC_LIST_CHECK_LENGTH = 0,
/// List needs length.
PSYC_LIST_NEED_LENGTH = 1,
/// List doesn't need length.
PSYC_LIST_NO_LENGTH = 2,
} PsycListFlag;
/// Element needs to be checked if it needs length.
PSYC_ELEM_CHECK_LENGTH = 0,
/// Element needs length.
PSYC_ELEM_NEED_LENGTH = 1,
/// Element doesn't need length.
PSYC_ELEM_NO_LENGTH = 2,
} PsycElemFlag;
/** Packet flags. */
typedef enum {
@ -77,35 +121,90 @@ typedef enum {
PSYC_PACKET_ID_ELEMS = 5,
} PsycPacketId;
/** Structure for a modifier. */
typedef struct {
char oper;
PsycString type;
PsycString value;
size_t length;
PsycElemFlag flag;
} PsycElem;
#define PSYC_ELEM(typ, typlen, val, vallen, flg) \
(PsycElem) { \
.type = PSYC_STRING(typ, typlen), \
.value = PSYC_STRING(val, vallen), \
.flag = flg, \
}
#define PSYC_ELEM_TV(typ, typlen, val, vallen) \
(PsycElem) { \
.type = PSYC_STRING(typ, typlen), \
.value = PSYC_STRING(val, vallen), \
}
#define PSYC_ELEM_VF(val, vallen, flg) \
(PsycElem) { \
.value = PSYC_STRING(val, vallen), \
.flag = flg, \
}
#define PSYC_ELEM_V(val, vallen) \
(PsycElem) { \
.value = PSYC_STRING(val, vallen), \
}
/** Dict key */
typedef struct {
PsycString value;
size_t length;
PsycElemFlag flag;
} PsycDictKey;
#define PSYC_DICT_KEY(k, klen, flg) \
(PsycDictKey) { \
.value = PSYC_STRING(k, klen), \
.flag = flg, \
}
/** Dict key/value */
typedef struct {
PsycElem value;
PsycDictKey key;
} PsycDictElem;
#define PSYC_DICT_ELEM(k, v) \
(PsycDictElem) { \
.key = k, \
.value = v, \
}
/** Dictionary */
typedef struct {
PsycString type;
PsycDictElem *elems;
size_t num_elems;
size_t length;
} PsycDict;
/** List */
typedef struct {
PsycString type;
PsycElem *elems;
size_t num_elems;
size_t length;
} PsycList;
/** Modifier */
typedef struct {
PsycString name;
PsycString value;
PsycModifierFlag flag;
char oper;
} PsycModifier;
/** Structure for an entity or routing header. */
/** Entity or routing header */
typedef struct {
size_t lines;
PsycModifier *modifiers;
} PsycHeader;
/** Structure for a list. */
typedef struct {
size_t num_elems;
PsycString *elems;
size_t length;
PsycListFlag flag;
} PsycList;
typedef struct {
PsycList *list;
size_t width;
size_t length;
} PsycTable;
/** Intermediate struct for a PSYC packet */
/** Intermediate struct for a PSYC packet. */
typedef struct {
PsycHeader routing; ///< Routing header.
PsycHeader entity; ///< Entity header.
@ -135,16 +234,12 @@ psyc_num_length (size_t n)
static inline PsycModifierFlag
psyc_modifier_length_check (PsycModifier *m)
{
PsycModifierFlag flag;
if (m->value.length > 0
&& (m->value.length > PSYC_MODIFIER_SIZE_THRESHOLD
|| memchr(m->value.data, (int) '\n', m->value.length)))
return PSYC_MODIFIER_NEED_LENGTH;
if (m->value.length > PSYC_MODIFIER_SIZE_THRESHOLD)
flag = PSYC_MODIFIER_NEED_LENGTH;
else if (memchr(m->value.data, (int) '\n', m->value.length))
flag = PSYC_MODIFIER_NEED_LENGTH;
else
flag = PSYC_MODIFIER_NO_LENGTH;
return flag;
return PSYC_MODIFIER_NO_LENGTH;
}
/** Initialize modifier */
@ -153,33 +248,61 @@ psyc_modifier_init (PsycModifier *m, PsycOperator oper,
char *name, size_t namelen,
char *value, size_t valuelen, PsycModifierFlag flag)
{
*m = (PsycModifier) {oper, {namelen, name}, {valuelen, value}, flag};
*m = (PsycModifier) {
.oper = oper,
.name = {namelen, name},
.value = {valuelen, value},
.flag = flag
};
if (flag == PSYC_MODIFIER_CHECK_LENGTH) // find out if it needs a length
m->flag = psyc_modifier_length_check(m);
else if (flag & PSYC_MODIFIER_ROUTING)
m->flag |= PSYC_MODIFIER_NO_LENGTH;
}
/**
* \internal
* Get the total length of a modifier when rendered.
* Check if a list/dict element needs length.
*/
PsycElemFlag
psyc_elem_length_check (PsycString *value, const char end);
/**
* \internal
* Get the rendered length of a list/dict element.
*/
size_t
psyc_elem_length (PsycElem *elem);
/**
* \internal
* Get the rendered length of a dict key.
*/
size_t
psyc_dict_key_length (PsycDictKey *elem);
/**
* \internal
* Get the rendered length of a list.
*/
size_t
psyc_list_length_set (PsycList *list);
/**
* \internal
* Get the rendered length of a dict.
*/
size_t
psyc_dict_length_set (PsycDict *dict);
/**
* \internal
* Get the rendered length of a modifier.
*/
size_t
psyc_modifier_length (PsycModifier *m);
/**
* \internal
* Check if a list needs length.
*/
PsycListFlag
psyc_list_length_check (PsycList *list);
/**
* \internal
* Get the total length of a list when rendered.
*/
PsycListFlag
psyc_list_length (PsycList *list);
/**
* \internal
* Check if a packet needs length.
@ -195,12 +318,11 @@ psyc_packet_length_set (PsycPacket *p);
/** Initialize a list. */
void
psyc_list_init (PsycList *list, PsycString *elems, size_t num_elems,
PsycListFlag flag);
psyc_list_init (PsycList *list, PsycElem *elems, size_t num_elems);
/** Initialize a table. */
/** Initialize a dict. */
void
psyc_table_init (PsycTable *table, size_t width, PsycList *list);
psyc_dict_init (PsycDict *dict, PsycDictElem *elems, size_t num_elems);
/** Initialize a packet. */
void
@ -218,10 +340,13 @@ psyc_packet_init_raw (PsycPacket *packet,
char *content, size_t contentlen,
PsycPacketFlag flag);
/** Get the total length of a packet ID when rendered. */
size_t
psyc_packet_id_length (size_t contextlen, size_t sourcelen, size_t targetelen,
size_t counterlen, size_t fragmentlen);
void
psyc_packet_id (PsycList *list, PsycElem *elems,
char *context, size_t contextlen,
char *source, size_t sourcelen,
char *target, size_t targetlen,
char *counter, size_t counterlen,
char *fragment, size_t fragmentlen);
/** @} */ // end of packet group

View file

@ -132,6 +132,10 @@ typedef enum {
* @see psyc_parse()
*/
typedef enum {
/// Error, no length is set for a modifier which is longer than PSYC_MODIFIER_SIZE_THRESHOLD.
PSYC_PARSE_ERROR_MOD_NO_LEN = -10,
/// Error, no length is set for the content but it is longer than PSYC_CONTENT_SIZE_THRESHOLD.
PSYC_PARSE_ERROR_NO_LEN = -9,
/// Error, packet is not ending with a valid delimiter.
PSYC_PARSE_ERROR_END = -8,
/// Error, expected NL after the method.
@ -197,106 +201,286 @@ typedef enum {
PSYC_PARSE_COMPLETE = 13,
} PsycParseRC;
/// PSYC packet parts.
typedef enum {
PSYC_PART_RESET = -1,
PSYC_PART_ROUTING = 0,
PSYC_PART_LENGTH = 1,
PSYC_PART_CONTENT = 2,
PSYC_PART_METHOD = 3,
PSYC_PART_DATA = 4,
PSYC_PART_END = 5,
} PsycPart;
/**
* The return value definitions for the list parsing function.
* @see psyc_parse_list()
*/
typedef enum {
PSYC_PARSE_LIST_ERROR_DELIM = -4,
PSYC_PARSE_LIST_ERROR_LEN = -3,
/// Error, no length is set for an element which is longer than PSYC_ELEM_SIZE_THRESHOLD.
PSYC_PARSE_LIST_ERROR_ELEM_NO_LEN = -6,
PSYC_PARSE_LIST_ERROR_ELEM_LENGTH = -5,
PSYC_PARSE_LIST_ERROR_ELEM_TYPE = -4,
PSYC_PARSE_LIST_ERROR_ELEM_START = -3,
PSYC_PARSE_LIST_ERROR_TYPE = -2,
PSYC_PARSE_LIST_ERROR = -1,
/// Completed parsing a list element.
PSYC_PARSE_LIST_ELEM = 1,
/// Reached end of buffer.
PSYC_PARSE_LIST_END = 2,
/// Binary list is incomplete.
PSYC_PARSE_LIST_INCOMPLETE = 3,
/// Buffer contains insufficient amount of data.
/// Fill another buffer and concatenate it with the end of the current buffer,
/// from the cursor position to the end.
PSYC_PARSE_LIST_INSUFFICIENT = 1,
/// Completed parsing the default type of the list.
PSYC_PARSE_LIST_TYPE = 2,
/// Start of an element is parsed but still not complete.
PSYC_PARSE_LIST_ELEM_START = 3,
/// Continuation of an incomplete element.
PSYC_PARSE_LIST_ELEM_CONT = 4,
/// Element parsing completed.
PSYC_PARSE_LIST_ELEM_END = 5,
/// Completed parsing a list element.
PSYC_PARSE_LIST_ELEM = 6,
/// Completed parsing the last element in the list.
PSYC_PARSE_LIST_ELEM_LAST = 7,
/// Reached end of buffer.
PSYC_PARSE_LIST_END = 8,
} PsycParseListRC;
typedef enum {
PSYC_PARSE_TABLE_ERROR_BODY = -5,
PSYC_PARSE_TABLE_ERROR_DELIM = -4,
PSYC_PARSE_TABLE_ERROR_HEAD = -3,
PSYC_PARSE_TABLE_ERROR_WIDTH = -2,
PSYC_PARSE_TABLE_ERROR = -1,
/// Completed parsing the width of the table.
PSYC_PARSE_TABLE_WIDTH = 1,
#ifdef PSYC_PARSE_TABLE_HEAD
/// Completed parsing the name of the key column.
PSYC_PARSE_TABLE_NAME_KEY = 2,
/// Completed parsing the name of a value column.
PSYC_PARSE_TABLE_NAME_VALUE = 3,
#endif
/// Completed parsing a key.
PSYC_PARSE_TABLE_KEY = 4,
/// Completed parsing a value.
PSYC_PARSE_TABLE_VALUE = 5,
/// Completed parsing a key and reached end of buffer.
PSYC_PARSE_TABLE_KEY_END = 6,
/// Completed parsing a value and reached end of buffer.
PSYC_PARSE_TABLE_VALUE_END = 7,
/// Binary table is incomplete.
PSYC_PARSE_TABLE_INCOMPLETE = 8,
} PsycParseTableRC;
PSYC_LIST_PART_START = 0,
PSYC_LIST_PART_TYPE = 1,
PSYC_LIST_PART_ELEM_START = 2,
PSYC_LIST_PART_ELEM_TYPE = 3,
PSYC_LIST_PART_ELEM_LENGTH = 4,
PSYC_LIST_PART_ELEM = 5,
} PsycListPart;
typedef enum {
PSYC_TABLE_PART_START = 0,
PSYC_TABLE_PART_WIDTH = 1,
#ifdef PSYC_PARSE_TABLE_HEAD
PSYC_TABLE_PART_HEAD_START = 2,
PSYC_TABLE_PART_HEAD = 3,
#endif
PSYC_TABLE_PART_BODY_START = 4,
PSYC_TABLE_PART_BODY = 5,
} PsycTablePart;
PSYC_PARSE_DICT_ERROR_VALUE = -9,
PSYC_PARSE_DICT_ERROR_VALUE_LENGTH = -8,
PSYC_PARSE_DICT_ERROR_VALUE_TYPE = -7,
PSYC_PARSE_DICT_ERROR_VALUE_START = -6,
PSYC_PARSE_DICT_ERROR_KEY = -5,
PSYC_PARSE_DICT_ERROR_KEY_LENGTH = -4,
PSYC_PARSE_DICT_ERROR_KEY_START = -3,
PSYC_PARSE_DICT_ERROR_TYPE = -2,
PSYC_PARSE_DICT_ERROR = -1,
/// Reached end of buffer.
/// Buffer contains insufficient amount of data.
/// Fill another buffer and concatenate it with the end of the current buffer,
/// from the cursor position to the end.
PSYC_PARSE_DICT_INSUFFICIENT = 1,
/// Completed parsing the default type of the dict.
PSYC_PARSE_DICT_TYPE = 2,
/// Start of a key is parsed but still not complete.
PSYC_PARSE_DICT_KEY_START = 3,
/// Continuation of an incomplete key.
PSYC_PARSE_DICT_KEY_CONT = 4,
/// Last continuation of a key.
PSYC_PARSE_DICT_KEY_END = 5,
/// Completed parsing a key in one go.
PSYC_PARSE_DICT_KEY = 6,
/// Start of a value is parsed but still not complete.
PSYC_PARSE_DICT_VALUE_START = 7,
/// Continuation of an incomplete value.
PSYC_PARSE_DICT_VALUE_CONT = 8,
/// Last continuation of a value.
PSYC_PARSE_DICT_VALUE_END = 9,
/// Completed parsing a value.
PSYC_PARSE_DICT_VALUE = 10,
/// Completed parsing the last value.
PSYC_PARSE_DICT_VALUE_LAST = 11,
/// Reached end of buffer.
PSYC_PARSE_DICT_END = 12,
} PsycParseDictRC;
typedef enum {
PSYC_DICT_PART_START = 0,
PSYC_DICT_PART_TYPE = 1,
PSYC_DICT_PART_KEY_START = 2,
PSYC_DICT_PART_KEY_LENGTH = 3,
PSYC_DICT_PART_KEY = 4,
PSYC_DICT_PART_VALUE_START = 5,
PSYC_DICT_PART_VALUE_TYPE = 6,
PSYC_DICT_PART_VALUE_LENGTH = 7,
PSYC_DICT_PART_VALUE = 8,
} PsycDictPart;
typedef enum {
PSYC_PARSE_INDEX_ERROR_DICT = -6,
PSYC_PARSE_INDEX_ERROR_DICT_LENGTH = -5,
PSYC_PARSE_INDEX_ERROR_STRUCT = -4,
PSYC_PARSE_INDEX_ERROR_LIST = -3,
PSYC_PARSE_INDEX_ERROR_TYPE = -2,
PSYC_PARSE_INDEX_ERROR = -1,
/// Reached end of buffer.
/// Buffer contains insufficient amount of data.
/// Fill another buffer and concatenate it with the end of the current buffer,
/// from the cursor position to the end.
PSYC_PARSE_INDEX_INSUFFICIENT = 1,
// Completed parsing a list index.
PSYC_PARSE_INDEX_LIST = 3,
// Completed parsing a list index at the end of the buffer.
PSYC_PARSE_INDEX_LIST_LAST = 4,
// Completed parsing a struct element name.
PSYC_PARSE_INDEX_STRUCT = 5,
// Completed parsing a struct element name at the end of the buffer.
PSYC_PARSE_INDEX_STRUCT_LAST = 6,
/// Start of a dict key is parsed but still not complete.
PSYC_PARSE_INDEX_DICT_START = 7,
/// Continuation of an incomplete dict key.
PSYC_PARSE_INDEX_DICT_CONT = 8,
/// Last continuation of a dict key.
PSYC_PARSE_INDEX_DICT_END = 9,
/// Completed parsing a dict key in one go.
PSYC_PARSE_INDEX_DICT = 10,
/// Reached end of buffer.
PSYC_PARSE_INDEX_END = 11,
} PsycParseIndexRC;
typedef enum {
PSYC_INDEX_PART_START = 0,
PSYC_INDEX_PART_TYPE = 1,
PSYC_INDEX_PART_LIST = 2,
PSYC_INDEX_PART_STRUCT = 3,
PSYC_INDEX_PART_DICT_LENGTH = 4,
PSYC_INDEX_PART_DICT = 5,
} PsycIndexPart;
typedef enum {
PSYC_PARSE_UPDATE_ERROR_VALUE = -24,
PSYC_PARSE_UPDATE_ERROR_LENGTH = -23,
PSYC_PARSE_UPDATE_ERROR_TYPE = -22,
PSYC_PARSE_UPDATE_ERROR_OPER = -21,
PSYC_PARSE_UPDATE_ERROR = -1,
/// Reached end of buffer.
/// Buffer contains insufficient amount of data.
/// Fill another buffer and concatenate it with the end of the current buffer,
/// from the cursor position to the end.
PSYC_PARSE_UPDATE_INSUFFICIENT = 1,
// Completed parsing a list index.
PSYC_PARSE_UPDATE_INDEX_LIST = 3,
// Completed parsing a struct element name.
PSYC_PARSE_UPDATE_INDEX_STRUCT = 5,
/// Start of a dict key is parsed but still not complete.
PSYC_PARSE_UPDATE_INDEX_DICT_START = 7,
/// Continuation of an incomplete dict key.
PSYC_PARSE_UPDATE_INDEX_DICT_CONT = 8,
/// Last continuation of a dict key.
PSYC_PARSE_UPDATE_INDEX_DICT_END = 9,
/// Completed parsing a dict key in one go.
PSYC_PARSE_UPDATE_INDEX_DICT = 10,
/// Completed parsing the type.
PSYC_PARSE_UPDATE_TYPE = 21,
/// Completed parsing the type and reached end of buffer.
PSYC_PARSE_UPDATE_TYPE_END = 22,
/// Start of the value is parsed but still not complete.
PSYC_PARSE_UPDATE_VALUE_START = 23,
/// Continuation of incomplete value.
PSYC_PARSE_UPDATE_VALUE_CONT = 24,
/// Last continuation of the value.
PSYC_PARSE_UPDATE_VALUE_END = 25,
/// Completed parsing the value in one go.
PSYC_PARSE_UPDATE_VALUE = 26,
/// Reached end of buffer.
PSYC_PARSE_UPDATE_END = 27,
} PsycParseUpdateRC;
typedef enum {
PSYC_UPDATE_PART_START = 0,
PSYC_UPDATE_INDEX_PART_TYPE = 1,
PSYC_UPDATE_INDEX_PART_LIST = 2,
PSYC_UPDATE_INDEX_PART_STRUCT = 3,
PSYC_UPDATE_INDEX_PART_DICT_LENGTH = 4,
PSYC_UPDATE_INDEX_PART_DICT = 5,
PSYC_UPDATE_PART_TYPE = 12,
PSYC_UPDATE_PART_LENGTH = 13,
PSYC_UPDATE_PART_VALUE = 14,
} PsycUpdatePart;
/**
* Struct for keeping parser state.
*/
typedef struct {
PsycString buffer; ///< Buffer with data to be parsed.
size_t cursor; ///< Current position in buffer.
size_t startc; ///< Position where the parsing would be resumed.
PsycString buffer; ///< Buffer with data to be parsed.
uint8_t flags; ///< Flags for the parser, see PsycParseFlag.
PsycPart part; ///< Part of the packet being parsed currently.
size_t routinglen; ///< Length of routing part parsed so far.
size_t content_parsed; ///< Number of bytes parsed from the content so far.
size_t contentlen; ///< Expected length of the content.
PsycBool contentlen_found; ///< Is there a length given for this packet?
size_t value_parsed; ///< Number of bytes parsed from the value so far.
size_t content_parsed; ///< Number of bytes parsed from the content so far.
size_t valuelen; ///< Expected length of the value.
PsycBool valuelen_found; ///< Is there a length given for this modifier?
size_t value_parsed; ///< Number of bytes parsed from the value so far.
PsycPart part; ///< Part of the packet being parsed currently.
uint8_t flags; ///< Flags for the parser, see PsycParseFlag.
uint8_t contentlen_found; ///< Is there a length given for this packet?
uint8_t valuelen_found; ///< Is there a length given for this modifier?
} PsycParseState;
/**
* Struct for keeping list parser state.
*/
typedef struct {
PsycString buffer; ///< Buffer with data to be parsed.
size_t cursor; ///< Current position in buffer.
size_t startc; ///< Line start position.
PsycString buffer; ///< Buffer with data to be parsed.
PsycListType type; ///< List type.
char term; ///< Terminator character at the end.
uint8_t term_set; ///< Look for terminator.
size_t elem_parsed; ///< Number of bytes parsed from the elem so far.
PsycString type; ///< List type.
size_t elemlen; ///< Expected length of the elem.
size_t elem_parsed; ///< Number of bytes parsed from the elem so far.
PsycListPart part; ///< Part of the list being parsed currently.
uint8_t elemlen_found; ///< Is there a length given for this element?
} PsycParseListState;
/**
* Struct for keeping table parser state.
* Struct for keeping dict parser state.
*/
typedef struct {
PsycString buffer; ///< Buffer with data to be parsed.
size_t cursor; ///< Current position in buffer.
size_t startc; ///< Line start position.
size_t elemlen; ///< Expected length of the key/value.
size_t elem_parsed; ///< Number of bytes parsed from the key/value so far.
PsycDictPart part; ///< Part of the dict being parsed currently.
uint8_t elemlen_found; ///< Is there a length given for this key/value?
} PsycParseDictState;
/**
* Struct for keeping index parser state.
*/
typedef struct {
PsycString buffer; ///< Buffer with data to be parsed.
PsycTablePart part; ///< Table type.
size_t width; ///< Width of table.
size_t elems; ///< Elems parsed so far in the table.
PsycParseListState list;
} PsycParseTableState;
size_t cursor; ///< Current position in buffer.
size_t startc; ///< Position where the parsing would be resumed.
size_t elemlen; ///< Expected length of an element.
size_t elem_parsed; ///< Number of bytes parsed from the elem so far.
PsycIndexPart part; ///< Part of the packet being parsed currently.
uint8_t elemlen_found; ///< Is there a length given for this element?
} PsycParseIndexState;
/**
* Struct for keeping update modifier parser state.
*/
typedef struct {
PsycString buffer; ///< Buffer with data to be parsed.
size_t cursor; ///< Current position in buffer.
size_t startc; ///< Position where the parsing would be resumed.
size_t elemlen; ///< Expected length of an element.
size_t elem_parsed; ///< Number of bytes parsed from the elem so far.
PsycUpdatePart part; ///< Part of the packet being parsed currently.
uint8_t elemlen_found; ///< Is there a length given for this element?
} PsycParseUpdateState;
/**
* Initializes the state struct.
@ -339,7 +523,7 @@ psyc_parse_buffer_set (PsycParseState *state, const char *buffer, size_t length)
}
/**
* Initializes the list state.
* Initializes the list parser state.
*/
static inline void
psyc_parse_list_state_init (PsycParseListState *state)
@ -358,27 +542,60 @@ psyc_parse_list_buffer_set (PsycParseListState *state,
state->cursor = 0;
}
/**
* Initializes the dict parser state.
*/
static inline void
psyc_parse_list_term_set (PsycParseListState *state, char term)
psyc_parse_dict_state_init (PsycParseDictState *state)
{
state->term = term;
state->term_set = PSYC_TRUE;
memset(state, 0, sizeof(PsycParseDictState));
}
/**
* Initializes the table state.
* Sets a new buffer in the dict parser state struct with data to be parsed.
*/
static inline void
psyc_parse_table_state_init (PsycParseTableState *state)
psyc_parse_dict_buffer_set (PsycParseDictState *state,
const char *buffer, size_t length)
{
memset(state, 0, sizeof(PsycParseTableState));
state->buffer = (PsycString) {length, (char*)buffer};
state->cursor = 0;
}
/**
* Sets a new buffer in the list parser state struct with data to be parsed.
* Initializes the index parser state.
*/
static inline void
psyc_parse_table_buffer_set (PsycParseTableState *state,
psyc_parse_index_state_init (PsycParseIndexState *state)
{
memset(state, 0, sizeof(PsycParseIndexState));
}
/**
* Sets a new buffer in the index parser state struct with data to be parsed.
*/
static inline void
psyc_parse_index_buffer_set (PsycParseIndexState *state,
const char *buffer, size_t length)
{
state->buffer = (PsycString) {length, (char*)buffer};
state->cursor = 0;
}
/**
* Initializes the update modifier parser state.
*/
static inline void
psyc_parse_update_state_init (PsycParseUpdateState *state)
{
memset(state, 0, sizeof(PsycParseUpdateState));
}
/**
* Sets a new buffer in the update modifier parser state struct with data to be parsed.
*/
static inline void
psyc_parse_update_buffer_set (PsycParseUpdateState *state,
const char *buffer, size_t length)
{
state->buffer = (PsycString) {length, (char*)buffer};
@ -471,10 +688,25 @@ psyc_parse (PsycParseState *state, char *oper,
static inline
#endif
PsycParseListRC
psyc_parse_list (PsycParseListState *state, PsycString *elem);
psyc_parse_list (PsycParseListState *state, PsycString *type, PsycString *elem);
PsycParseTableRC
psyc_parse_table (PsycParseTableState *state, PsycString *elem);
#ifdef __INLINE_PSYC_PARSE
static inline
#endif
PsycParseDictRC
psyc_parse_dict (PsycParseDictState *state, PsycString *type, PsycString *elem);
#ifdef __INLINE_PSYC_PARSE
static inline
#endif
PsycParseIndexRC
psyc_parse_index (PsycParseIndexState *state, PsycString *idx);
#ifdef __INLINE_PSYC_PARSE
static inline
#endif
PsycParseUpdateRC
psyc_parse_update (PsycParseUpdateState *state, char *oper, PsycString *value);
static inline size_t
psyc_parse_int (const char *value, size_t len, int64_t *n)
@ -516,7 +748,7 @@ psyc_parse_uint (const char *value, size_t len, uint64_t *n)
}
static inline size_t
psyc_parse_index (const char *value, size_t len, int64_t *n)
psyc_parse_list_index (const char *value, size_t len, int64_t *n)
{
if (!value || len == 0 || value[0] != '#')
return 0;

View file

@ -51,6 +51,12 @@ static inline
PsycRenderRC
psyc_render (PsycPacket *packet, char *buffer, size_t buflen);
PsycRenderRC
psyc_render_elem (PsycElem *elem, char *buffer, size_t buflen);
PsycRenderRC
psyc_render_dict_key (PsycDictKey *elem, char *buffer, size_t buflen);
/**
* Render a PSYC list into a buffer.
*/
@ -61,15 +67,7 @@ PsycRenderRC
psyc_render_list (PsycList *list, char *buffer, size_t buflen);
PsycRenderRC
psyc_render_table (PsycTable *table, char *buffer, size_t buflen);
PsycRenderRC
psyc_render_packet_id (char *context, size_t contextlen,
char *source, size_t sourcelen,
char *target, size_t targetlen,
char *counter, size_t counterlen,
char *fragment, size_t fragmentlen,
char *buffer, size_t buflen);
psyc_render_dict (PsycDict *dict, char *buffer, size_t buflen);
/** @} */ // end of render group

View file

@ -1,21 +0,0 @@
#ifndef PSYC_SYNTAX_H
#ifndef PSYC_LIST_SIZE_LIMIT
# define PSYC_LIST_SIZE_LIMIT 404
#endif
/* beyond this a content length must be provided */
#ifndef PSYC_CONTENT_SIZE_THRESHOLD
# define PSYC_CONTENT_SIZE_THRESHOLD 444
#endif
/* beyond this a modifier value length must be provided */
#ifndef PSYC_MODIFIER_SIZE_THRESHOLD
# define PSYC_MODIFIER_SIZE_THRESHOLD 404
#endif
#define PSYC_PACKET_DELIMITER_CHAR '|'
#define PSYC_PACKET_DELIMITER "\n|\n"
#define PSYC_SYNTAX_H
#endif

View file

@ -5,16 +5,17 @@
#ifndef PSYC_VARIABLE_H
#define PSYC_VARIABLE_H
#include "match.h"
#include "packet.h"
/// Routing variables in alphabetical order.
extern const PsycDictInt psyc_rvars[];
extern const PsycMapInt psyc_rvars[];
// Variable types in alphabetical order.
extern const PsycDictInt psyc_var_types[];
extern const PsycMapInt psyc_var_types[];
/// Method names in alphabetical order.
extern const PsycDictInt psyc_methods[];
extern const PsycMapInt psyc_methods[];
extern const size_t psyc_rvars_num;
extern const size_t psyc_var_types_num;
@ -37,14 +38,41 @@ typedef enum {
PSYC_RVARS_NUM,
} PsycRoutingVar;
/**
* Variable types.
*
* This enum lists PSYC variable types that
* this library is capable of checking for
* validity. Other variable types are treated
* as opaque data.
*/
typedef enum {
PSYC_TYPE_UNKNOWN,
PSYC_TYPE_AMOUNT,
PSYC_TYPE_COLOR,
PSYC_TYPE_COUNTER,
PSYC_TYPE_DATE,
PSYC_TYPE_DEGREE,
PSYC_TYPE_DICT,
PSYC_TYPE_ENTITY,
PSYC_TYPE_FLAG,
PSYC_TYPE_LANGUAGE,
PSYC_TYPE_LIST,
PSYC_TYPE_NICK,
PSYC_TYPE_PAGE,
PSYC_TYPE_STRUCT,
PSYC_TYPE_TIME,
PSYC_TYPE_UNIFORM,
} PsycType;
/**
* Look up routing variable.
*/
static inline PsycRoutingVar
psyc_var_routing (const char *name, size_t len)
{
return (PsycRoutingVar) psyc_dict_lookup((PsycDict *)psyc_rvars,
psyc_rvars_num, name, len, PSYC_NO);
return (PsycRoutingVar)
psyc_map_lookup((PsycMap*)psyc_rvars, psyc_rvars_num, name, len, PSYC_NO);
}
/**
@ -53,8 +81,9 @@ psyc_var_routing (const char *name, size_t len)
static inline PsycType
psyc_var_type (const char *name, size_t len)
{
return (PsycType) psyc_dict_lookup((PsycDict *)psyc_var_types,
psyc_var_types_num, name, len, PSYC_YES);
return (PsycType)
psyc_map_lookup((PsycMap*)psyc_var_types, psyc_var_types_num,
name, len, PSYC_YES);
}
/**