2011-05-08 21:40:26 +00:00
|
|
|
#include "lib.h"
|
2011-04-22 15:09:32 +00:00
|
|
|
#include <stdint.h>
|
|
|
|
|
2011-04-29 20:58:19 +00:00
|
|
|
|
2011-05-23 00:03:34 +00:00
|
|
|
/// Routing variables in alphabetical order.
|
2011-04-29 20:58:19 +00:00
|
|
|
const psycString psyc_routingVars[] =
|
2011-04-22 15:09:32 +00:00
|
|
|
{
|
2011-04-25 12:20:13 +00:00
|
|
|
PSYC_C2STR("_amount_fragments"),
|
|
|
|
PSYC_C2STR("_context"),
|
|
|
|
//PSYC_C2STR("_count"), // older PSYC
|
2011-04-29 20:58:19 +00:00
|
|
|
PSYC_C2STR("_counter"), // the name for this is supposed to be _count, not _counter
|
2011-04-25 12:20:13 +00:00
|
|
|
PSYC_C2STR("_fragment"),
|
|
|
|
//PSYC_C2STR("_length"), // older PSYC
|
|
|
|
PSYC_C2STR("_source"),
|
2011-04-29 20:58:19 +00:00
|
|
|
//PSYC_C2STR("_source_identification"), // older PSYC
|
|
|
|
PSYC_C2STR("_source_identity"),
|
2011-04-25 12:20:13 +00:00
|
|
|
PSYC_C2STR("_source_relay"),
|
2011-04-29 20:58:19 +00:00
|
|
|
PSYC_C2STR("_source_relay_relay"), // until you have a better idea.. is this really in use?
|
2011-04-25 12:20:13 +00:00
|
|
|
PSYC_C2STR("_tag"),
|
|
|
|
PSYC_C2STR("_tag_relay"),
|
|
|
|
//PSYC_C2STR("_tag_reply"), // older PSYC
|
|
|
|
PSYC_C2STR("_target"),
|
|
|
|
PSYC_C2STR("_target_forward"),
|
|
|
|
PSYC_C2STR("_target_relay"),
|
2011-04-29 20:58:19 +00:00
|
|
|
//PSYC_C2STR("_understand_modules"), // older PSYC
|
|
|
|
//PSYC_C2STR("_using_modules"), // older PSYC
|
|
|
|
};
|
|
|
|
|
2011-05-23 00:03:34 +00:00
|
|
|
// Variable types in alphabetical order.
|
2011-04-29 20:58:19 +00:00
|
|
|
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},
|
2011-04-22 15:09:32 +00:00
|
|
|
};
|
|
|
|
|
2011-04-29 20:58:19 +00:00
|
|
|
const size_t psyc_routingVarsNum = PSYC_NUM_ELEM(psyc_routingVars);
|
|
|
|
const size_t psyc_varTypesNum = PSYC_NUM_ELEM(psyc_varTypes);
|
2011-04-22 15:09:32 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the type of variable name.
|
|
|
|
*/
|
2011-05-20 00:58:32 +00:00
|
|
|
inline
|
|
|
|
psycBool psyc_isRoutingVar2(const char *name, size_t len)
|
2011-04-22 15:09:32 +00:00
|
|
|
{
|
2011-04-29 20:58:19 +00:00
|
|
|
//return psyc_matchArray(psyc_routingVars, PSYC_NUM_ELEM(psyc_routingVars), name, len, 0);
|
2011-04-22 15:09:32 +00:00
|
|
|
size_t cursor = 1;
|
|
|
|
uint8_t i, m = 0;
|
2011-04-29 20:58:19 +00:00
|
|
|
int8_t matching[psyc_routingVarsNum]; // indexes of matching vars
|
2011-04-22 15:09:32 +00:00
|
|
|
|
|
|
|
if (len < 2 || name[0] != '_')
|
|
|
|
return PSYC_FALSE;
|
|
|
|
|
|
|
|
// first find the vars with matching length
|
2011-04-29 20:58:19 +00:00
|
|
|
for (i=0; i<psyc_routingVarsNum; i++)
|
|
|
|
if (len == psyc_routingVars[i].length)
|
2011-04-22 15:09:32 +00:00
|
|
|
matching[m++] = i;
|
|
|
|
|
2011-04-29 20:58:19 +00:00
|
|
|
matching[m] = -1; // mark the end of matching indexes
|
|
|
|
|
2011-04-22 15:09:32 +00:00
|
|
|
while (cursor < len && matching[0] >= 0)
|
|
|
|
{
|
2011-04-29 20:58:19 +00:00
|
|
|
for (i = m = 0; i < psyc_routingVarsNum; i++)
|
2011-04-22 15:09:32 +00:00
|
|
|
{
|
|
|
|
if (matching[i] < 0)
|
2011-04-29 20:58:19 +00:00
|
|
|
break; // reached the end of possible matches
|
|
|
|
if (psyc_routingVars[matching[i]].ptr[cursor] == name[cursor])
|
2011-04-22 15:09:32 +00:00
|
|
|
matching[m++] = matching[i]; // found a match, update matching indexes
|
2011-04-29 20:58:19 +00:00
|
|
|
else if (psyc_routingVars[matching[i]].ptr[cursor] > name[cursor])
|
|
|
|
break; // passed the possible matches in alphabetical order in the array
|
2011-04-22 15:09:32 +00:00
|
|
|
}
|
|
|
|
|
2011-04-29 20:58:19 +00:00
|
|
|
if (m < psyc_routingVarsNum)
|
2011-04-22 15:09:32 +00:00
|
|
|
matching[m] = -1; // mark the end of matching indexes
|
|
|
|
|
|
|
|
cursor++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return matching[0] >= 0 ? PSYC_TRUE : PSYC_FALSE;
|
|
|
|
}
|
|
|
|
|
2011-05-20 00:58:32 +00:00
|
|
|
psycBool psyc_isRoutingVar(psycString *name)
|
|
|
|
{
|
|
|
|
return psyc_isRoutingVar2(name->ptr, name->length);
|
|
|
|
}
|
|
|
|
|
2011-04-22 15:09:32 +00:00
|
|
|
/**
|
|
|
|
* Get the type of variable name.
|
|
|
|
*/
|
2011-05-20 00:58:32 +00:00
|
|
|
inline
|
|
|
|
psycType psyc_getVarType2(const char *name, size_t len)
|
2011-04-22 15:09:32 +00:00
|
|
|
{
|
2011-04-29 20:58:19 +00:00
|
|
|
//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_varTypesNum; i++)
|
|
|
|
if (len == psyc_varTypes[i].name.length || (len > 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
|
2011-10-30 15:04:54 +00:00
|
|
|
if (cursor < psyc_varTypes[matching[i]].name.length &&
|
|
|
|
psyc_varTypes[matching[i]].name.ptr[cursor] == name[cursor])
|
2011-04-29 20:58:19 +00:00
|
|
|
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;
|
2011-04-22 15:09:32 +00:00
|
|
|
}
|
2011-05-20 00:58:32 +00:00
|
|
|
|
|
|
|
psycType psyc_getVarType(psycString *name)
|
|
|
|
{
|
|
|
|
return psyc_getVarType2(name->ptr, name->length);
|
|
|
|
}
|
2011-10-30 15:04:54 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Search for a variable name in an array.
|
|
|
|
*
|
|
|
|
* @param array The array to search, should be ordered alphabetically.
|
|
|
|
* @param size Size of array.
|
|
|
|
* @param name Name of variable to look for.
|
|
|
|
* @param namelen Length of name.
|
|
|
|
* @param startswith If true, look for any variable starting with name,
|
|
|
|
otherwise only exact matches are returned.
|
|
|
|
* @param matching A temporary array used for keeping track of results.
|
|
|
|
* Should be the same size as the array we're searching.
|
|
|
|
*
|
|
|
|
* @return The value of the matched variable in the array.
|
|
|
|
*/
|
|
|
|
int psyc_findVar(const psycMatchVar *array, size_t size,
|
|
|
|
const char *name, size_t namelen,
|
|
|
|
uint8_t startswith, int8_t *matching)
|
|
|
|
{
|
|
|
|
size_t cursor = 1;
|
|
|
|
uint8_t i, m = 0;
|
|
|
|
//memset(&matching, -1, sizeof matching);
|
|
|
|
|
|
|
|
if (namelen < 2 || name[0] != '_')
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
// first find the vars with matching length
|
|
|
|
for (i=0; i<size; i++)
|
|
|
|
if (namelen == array[i].name.length ||
|
|
|
|
(startswith && namelen > array[i].name.length &&
|
|
|
|
name[array[i].name.length] == '_'))
|
|
|
|
matching[m++] = i;
|
|
|
|
|
|
|
|
matching[m] = -1; // mark the end of matching indexes
|
|
|
|
|
|
|
|
while (cursor < namelen && matching[0] >= 0)
|
|
|
|
{
|
|
|
|
for (i = m = 0; i < size; i++)
|
|
|
|
{
|
|
|
|
if (matching[i] < 0)
|
|
|
|
break;
|
|
|
|
if (array[matching[i]].name.ptr[cursor] == name[cursor])
|
|
|
|
matching[m++] = matching[i]; // found a match, update matching indexes
|
|
|
|
else if (array[matching[i]].name.ptr[cursor] > name[cursor])
|
|
|
|
break; // passed the possible matches in alphabetical order
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m < size)
|
|
|
|
matching[m] = -1; // mark the end of matching indexes
|
|
|
|
|
|
|
|
cursor++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// return first match if found
|
|
|
|
return matching[0] >= 0 ? array[matching[0]].value : 0;
|
|
|
|
}
|