From f722733f08c6366ba1a0209d364a00998c30d24c Mon Sep 17 00:00:00 2001 From: "tg(x)" <*@tg-x.net> Date: Fri, 29 Apr 2011 22:58:19 +0200 Subject: [PATCH] getVarType --- .gitignore | 1 + include/psyc.h | 19 ++++++---- src/variable.c | 97 +++++++++++++++++++++++++++++++++++++---------- test/Makefile | 2 +- test/getVarType.c | 21 ++++++++++ 5 files changed, 112 insertions(+), 28 deletions(-) create mode 100644 test/getVarType.c diff --git a/.gitignore b/.gitignore index c21bfb4..6248e5f 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ test/testParser test/testRender test/testServer test/isRoutingVar +test/getVarType .config ~$* diff --git a/include/psyc.h b/include/psyc.h index 5d75ced..93358f1 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -107,6 +107,12 @@ typedef struct const char *ptr; } psycString; +typedef struct +{ + psycString name; + int value; +} psycMatchVar; + /** * Shortcut for creating a psycString. * @@ -204,8 +210,7 @@ inline psycPacket psyc_newPacket2(psycModifier *routing, size_t routinglen, /// Routing vars in alphabetical order. extern const psycString PSYC_routingVars[]; -/// Number of routing vars. -extern const size_t PSYC_routingVarsNum; +extern const psycMatchVar PSYC_varTypes[]; /** * Get the type of variable name. @@ -215,7 +220,7 @@ psycBool psyc_isRoutingVar(const char *name, size_t len); /** * Get the type of variable name. */ -psycType psyc_getVarType(char *name, size_t len); +psycType psyc_getVarType(const char *name, size_t len); /** * Checks if long keyword string inherits from short keyword string. @@ -238,8 +243,8 @@ int psyc_matches(char *sho, size_t slen, * number of bytes written. 0 is a legal return value. Should the * callback return -1, psyc_text leaves the original template text as is. */ -typedef int (*psyctextCB)(uint8_t *match, size_t mlen, - uint8_t **buffer, size_t *blen); +typedef int (*psyctextCB)(char *match, size_t mlen, + char **buffer, size_t *blen); /** * Fills out text templates by asking a callback for content. @@ -254,8 +259,8 @@ typedef int (*psyctextCB)(uint8_t *match, size_t mlen, * * See also http://about.psyc.eu/psyctext */ -int psyc_text(uint8_t *template, size_t tlen, - uint8_t **buffer, size_t *blen, +int psyc_text(char *template, size_t tlen, + char **buffer, size_t *blen, psyctextCB lookupValue, char *braceOpen, char *braceClose); diff --git a/src/variable.c b/src/variable.c index 6273e68..a30805d 100644 --- a/src/variable.c +++ b/src/variable.c @@ -1,62 +1,83 @@ -#include +#include #include /// Routing variables in alphabetical order. -const psycString PSYC_routingVars[] = + +const psycString psyc_routingVars[] = { PSYC_C2STR("_amount_fragments"), PSYC_C2STR("_context"), //PSYC_C2STR("_count"), // older PSYC - PSYC_C2STR("_counter"), // the name for this is supposed to be _count, not _counter + PSYC_C2STR("_counter"), // the name for this is supposed to be _count, not _counter PSYC_C2STR("_fragment"), //PSYC_C2STR("_length"), // older PSYC PSYC_C2STR("_source"), - PSYC_C2STR("_source_identification"), + //PSYC_C2STR("_source_identification"), // older PSYC + PSYC_C2STR("_source_identity"), PSYC_C2STR("_source_relay"), - PSYC_C2STR("_source_relay_relay"), // until you have a better idea.. is this really in use? + PSYC_C2STR("_source_relay_relay"), // until you have a better idea.. is this really in use? PSYC_C2STR("_tag"), PSYC_C2STR("_tag_relay"), //PSYC_C2STR("_tag_reply"), // older PSYC PSYC_C2STR("_target"), PSYC_C2STR("_target_forward"), PSYC_C2STR("_target_relay"), - //PSYC_C2STR(19, "_understand_modules"), // older PSYC - //PSYC_C2STR(14, "_using_modules"), // older PSYC + //PSYC_C2STR("_understand_modules"), // older PSYC + //PSYC_C2STR("_using_modules"), // older PSYC }; -const size_t PSYC_routingVarsNum = sizeof(PSYC_routingVars) / sizeof(*PSYC_routingVars); +const psycMatchVar psyc_varTypes[] = +{ + {PSYC_C2STR("_amount"), PSYC_TYPE_AMOUNT}, + {PSYC_C2STR("_color"), PSYC_TYPE_COLOR}, + {PSYC_C2STR("_date"), PSYC_TYPE_DATE}, + {PSYC_C2STR("_degree"), PSYC_TYPE_DEGREE}, + {PSYC_C2STR("_entity"), PSYC_TYPE_ENTITY}, + {PSYC_C2STR("_flag"), PSYC_TYPE_FLAG}, + {PSYC_C2STR("_language"), PSYC_TYPE_LANGUAGE}, + {PSYC_C2STR("_list"), PSYC_TYPE_LIST}, + {PSYC_C2STR("_nick"), PSYC_TYPE_NICK}, + {PSYC_C2STR("_page"), PSYC_TYPE_PAGE}, + {PSYC_C2STR("_uniform"), PSYC_TYPE_UNIFORM}, + {PSYC_C2STR("_time"), PSYC_TYPE_TIME}, +}; + +const size_t psyc_routingVarsNum = PSYC_NUM_ELEM(psyc_routingVars); +const size_t psyc_varTypesNum = PSYC_NUM_ELEM(psyc_varTypes); /** * Get the type of variable name. */ psycBool psyc_isRoutingVar(const char *name, size_t len) { + //return psyc_matchArray(psyc_routingVars, PSYC_NUM_ELEM(psyc_routingVars), name, len, 0); size_t cursor = 1; - int8_t matching[PSYC_routingVarsNum]; // indexes of matching vars - memset(&matching, -1, sizeof(matching)); uint8_t i, m = 0; + int8_t matching[psyc_routingVarsNum]; // indexes of matching vars if (len < 2 || name[0] != '_') return PSYC_FALSE; // first find the vars with matching length - for (i=0; i= 0) { - for (i = m = 0; i < PSYC_routingVarsNum; i++) + for (i = m = 0; i < psyc_routingVarsNum; i++) { if (matching[i] < 0) - break; - if (PSYC_routingVars[matching[i]].ptr[cursor] == name[cursor]) + break; // reached the end of possible matches + if (psyc_routingVars[matching[i]].ptr[cursor] == name[cursor]) matching[m++] = matching[i]; // found a match, update matching indexes - else if (PSYC_routingVars[matching[i]].ptr[cursor] > name[cursor]) - break; // passed the possible matches in alphabetical order + else if (psyc_routingVars[matching[i]].ptr[cursor] > name[cursor]) + break; // passed the possible matches in alphabetical order in the array } - if (m < PSYC_routingVarsNum) + if (m < psyc_routingVarsNum) matching[m] = -1; // mark the end of matching indexes cursor++; @@ -68,7 +89,43 @@ psycBool psyc_isRoutingVar(const char *name, size_t len) /** * Get the type of variable name. */ -psycType psyc_getVarType(char *name, size_t len) +psycType psyc_getVarType(const char *name, size_t len) { - return PSYC_TYPE_UNKNOWN; + //return psyc_matchArray(psyc_varTypes, PSYC_NUM_ELEM(psyc_varTypes), name, len, 1); + size_t cursor = 1; + uint8_t i, m = 0; + int8_t matching[psyc_varTypesNum]; // indexes of matching vars + + if (len < 2 || name[0] != '_') + return 0; + + // first find the vars with matching length + for (i=0; i psyc_varTypes[i].name.length && name[psyc_varTypes[i].name.length] == '_')) + matching[m++] = i; + + matching[m] = -1; // mark the end of matching indexes + + while (cursor < len && matching[0] >= 0) + { + for (i = m = 0; i < psyc_varTypesNum; i++) + { + if (matching[i] < 0) + break; // reached the end of possible matches + if (cursor < psyc_varTypes[matching[i]].name.length && psyc_varTypes[matching[i]].name.ptr[cursor] == name[cursor]) + matching[m++] = matching[i]; // found a match, update matching indexes + else if (cursor == psyc_varTypes[matching[i]].name.length && name[cursor] == '_') + return psyc_varTypes[matching[0]].value; // _ after the end of a matching prefix + else if (psyc_varTypes[matching[i]].name.ptr[cursor] > name[cursor]) + break; // passed the possible matches in alphabetical order in the array + } + + if (m < psyc_varTypesNum) + matching[m] = -1; // mark the end of matching indexes + + cursor++; + } + + // return first match if found + return matching[0] >= 0 ? psyc_varTypes[matching[0]].value : 0; } diff --git a/test/Makefile b/test/Makefile index b1b58e3..37bdba3 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,7 +1,7 @@ CFLAGS=-I../include -DDEBUG -g -O0 -Wall LDFLAGS=-L../src LOADLIBES=-lpsyc -lm -TARGETS=testServer testParser testMatch testRender isRoutingVar +TARGETS=testServer testParser testMatch testRender isRoutingVar getVarType PORT=4440 all: $(TARGETS) diff --git a/test/getVarType.c b/test/getVarType.c new file mode 100644 index 0000000..bdf6d3c --- /dev/null +++ b/test/getVarType.c @@ -0,0 +1,21 @@ +#include +#include +#include +#include +#include "../include/psyc/lib.h" + +int main() { + unless (psyc_getVarType(PSYC_C2ARG("_list"))) return 1; + unless (psyc_getVarType(PSYC_C2ARG("_list_foo"))) return 2; + unless (psyc_getVarType(PSYC_C2ARG("_color_red"))) return 3; + if (psyc_getVarType(PSYC_C2ARG("_last"))) return 4; + if (psyc_getVarType(PSYC_C2ARG("_lost_foo"))) return 5; + if (psyc_getVarType(PSYC_C2ARG("_colorful"))) return 6; + if (psyc_getVarType(PSYC_C2ARG("_foo"))) return 7; + if (psyc_getVarType(PSYC_C2ARG("bar"))) return 8; + if (psyc_getVarType(PSYC_C2ARG("______"))) return 9; + if (psyc_getVarType(PSYC_C2ARG("_"))) return 10; + + puts("psyc_getVarType passed all tests."); + return 0; // passed all tests +}