Non linear str2int

This commit is contained in:
Olof hagsand 2019-04-23 12:53:29 +02:00
parent 77ad42f1ce
commit 1e1eabbc06
6 changed files with 104 additions and 19 deletions

View file

@ -86,6 +86,7 @@ int xml_chardata_encode(char **escp, char *fmt, ...);
int uri_percent_decode(char *enc, char **str); int uri_percent_decode(char *enc, char **str);
const char *clicon_int2str(const map_str2int *mstab, int i); const char *clicon_int2str(const map_str2int *mstab, int i);
int clicon_str2int(const map_str2int *mstab, char *str); int clicon_str2int(const map_str2int *mstab, char *str);
int clicon_str2int_search(const map_str2int *mstab, char *str, int upper);
int nodeid_split(char *nodeid, char **prefix, char **id); int nodeid_split(char *nodeid, char **prefix, char **id);
char *clixon_trim(char *str); char *clixon_trim(char *str);
int regexp_xsd2posix(char *xsd, char **posix); int regexp_xsd2posix(char *xsd, char **posix);

View file

@ -112,6 +112,7 @@ hash_bucket(const char *str)
* *
* @retval hash Pointer to new hash table. * @retval hash Pointer to new hash table.
* @retval NULL Error * @retval NULL Error
* @see hash_free For freeing the hash-table
*/ */
clicon_hash_t * clicon_hash_t *
hash_init(void) hash_init(void)

View file

@ -552,7 +552,7 @@ clicon_int2str(const map_str2int *mstab,
* @param[in] str Input string * @param[in] str Input string
* @retval int Value * @retval int Value
* @retval -1 Error, not found * @retval -1 Error, not found
* @note linear search * @see clicon_str2int_search for optimized lookup, but strings must be sorted
*/ */
int int
clicon_str2int(const map_str2int *mstab, clicon_str2int(const map_str2int *mstab,
@ -566,6 +566,65 @@ clicon_str2int(const map_str2int *mstab,
return -1; return -1;
} }
/*! Map from string to int using binary (alphatical) search
* @param[in] ms String, integer map
* @param[in] str Input string
* @param[in] low Lower bound index
* @param[in] upper Upper bound index
* @param[in] len Length of array (max)
* @param[out] found Integer found (can also be negative)
* @retval 0 Not found
* @retval 1 Found with "found" value set.
* @note Assumes sorted strings, tree search
*/
static int
str2int_search1(const map_str2int *mstab,
char *str,
int low,
int upper,
int len,
int *found)
{
const struct map_str2int *ms;
int mid;
int cmp;
if (upper < low)
return 0; /* not found */
mid = (low + upper) / 2;
if (mid >= len) /* beyond range */
return 0; /* not found */
ms = &mstab[mid];
if ((cmp = strcmp(str, ms->ms_str)) == 0){
*found = ms->ms_int;
return 1; /* found */
}
else if (cmp < 0)
return str2int_search1(mstab, str, low, mid-1, len, found);
else
return str2int_search1(mstab, str, mid+1, upper, len, found);
}
/*! Map from string to int using str2int map
* @param[in] ms String, integer map
* @param[in] str Input string
* @retval int Value
* @retval -1 Error, not found
* @note Assumes sorted strings, tree search
* @note -1 can not be value
*/
int
clicon_str2int_search(const map_str2int *mstab,
char *str,
int len)
{
int found;
if (str2int_search1(mstab, str, 0, len, len, &found))
return found;
return -1; /* not found */
}
/*! Split colon-separated node identifier into prefix and name /*! Split colon-separated node identifier into prefix and name
* @param[in] node-id * @param[in] node-id
* @param[out] prefix Malloced string. May be NULL. * @param[out] prefix Malloced string. May be NULL.

View file

@ -744,8 +744,10 @@ xml_childvec_get(cxobj *x)
* ... * ...
* xml_free(x); * xml_free(x);
* @endcode * @endcode
* @note yspec may be NULL either because it is not known or it is irrelevant, * @note As a rule, yspec should be given in normal Clixon calls to enable
* eg for body or attribute * proper sorting and insert functionality. Except as follows:
* - type is body or attribute
* - Yang is unknown
* @see xml_sort_insert * @see xml_sort_insert
*/ */
cxobj * cxobj *
@ -828,6 +830,7 @@ xml_cv_set(cxobj *x,
* @retval xmlobj if found. * @retval xmlobj if found.
* @retval NULL if no such node found. * @retval NULL if no such node found.
* @see xml_find_type A more generic function * @see xml_find_type A more generic function
* @note Linear scalability and relies on strcmp
*/ */
cxobj * cxobj *
xml_find(cxobj *x_up, xml_find(cxobj *x_up,

View file

@ -80,19 +80,19 @@ static const map_str2int ytmap[] = {
{"int32", CGV_INT32}, /* NOTE, first match on right is significant, dont move */ {"int32", CGV_INT32}, /* NOTE, first match on right is significant, dont move */
{"string", CGV_STRING}, /* NOTE, first match on right is significant, dont move */ {"string", CGV_STRING}, /* NOTE, first match on right is significant, dont move */
{"string", CGV_REST}, /* For cv -> yang translation of rest */ {"string", CGV_REST}, /* For cv -> yang translation of rest */
{"binary", CGV_STRING}, {"binary", CGV_STRING},
{"bits", CGV_STRING}, {"bits", CGV_STRING},
{"boolean", CGV_BOOL}, {"boolean", CGV_BOOL},
{"decimal64", CGV_DEC64}, {"decimal64", CGV_DEC64},
{"empty", CGV_VOID}, /* May not include any content */ {"empty", CGV_VOID}, /* May not include any content */
{"enumeration", CGV_STRING}, {"enumeration", CGV_STRING},
{"identityref", CGV_STRING}, /* XXX */ {"identityref", CGV_STRING}, /* XXX */
{"instance-identifier", CGV_STRING}, /* XXX */ {"instance-identifier", CGV_STRING}, /* XXX */
{"int8", CGV_INT8}, {"int8", CGV_INT8},
{"int16", CGV_INT16}, {"int16", CGV_INT16},
{"int64", CGV_INT64}, {"int64", CGV_INT64},
{"leafref", CGV_STRING}, /* XXX */ {"leafref", CGV_STRING}, /* XXX */
{"uint8", CGV_UINT8}, {"uint8", CGV_UINT8},
{"uint16", CGV_UINT16}, {"uint16", CGV_UINT16},
{"uint32", CGV_UINT32}, {"uint32", CGV_UINT32},
{"uint64", CGV_UINT64}, {"uint64", CGV_UINT64},
@ -100,6 +100,33 @@ static const map_str2int ytmap[] = {
{NULL, -1} {NULL, -1}
}; };
/*! Mapping from yang string types --> cligen types
* @note not 100% same as map_str2int since it has significant order AND
* string->CGV_REST entry removed
*/
static const map_str2int ytmap2[] = {
{"binary", CGV_STRING},
{"bits", CGV_STRING},
{"boolean", CGV_BOOL},
{"decimal64", CGV_DEC64},
{"empty", CGV_VOID}, /* May not include any content */
{"enumeration", CGV_STRING},
{"identityref", CGV_STRING}, /* XXX */
{"instance-identifier", CGV_STRING}, /* XXX */
{"int16", CGV_INT16},
{"int32", CGV_INT32},
{"int64", CGV_INT64},
{"int8", CGV_INT8},
{"leafref", CGV_STRING}, /* XXX */
{"string", CGV_STRING},
{"uint16", CGV_UINT16},
{"uint32", CGV_UINT32},
{"uint64", CGV_UINT64},
{"uint8", CGV_UINT8},
{"union", CGV_REST}, /* Is replaced by actual type */
{NULL, -1}
};
/*! Regular expression compiling /*! Regular expression compiling
* @retval -1 Error * @retval -1 Error
* @retval 0 regex problem (no match?) * @retval 0 regex problem (no match?)
@ -172,7 +199,7 @@ regex_exec(regex_t *re,
static int static int
yang_builtin(char *type) yang_builtin(char *type)
{ {
if (clicon_str2int(ytmap, type) != -1) if (clicon_str2int_search(ytmap2, type, (sizeof(ytmap)/sizeof(map_str2int))-2) != -1)
return 1; return 1;
return 0; return 0;
} }
@ -318,7 +345,7 @@ yang2cv_type(char *ytype,
*cv_type = CGV_ERR; *cv_type = CGV_ERR;
/* built-in types */ /* built-in types */
if ((ret = clicon_str2int(ytmap, ytype)) != -1){ if ((ret = clicon_str2int_search(ytmap2, ytype, (sizeof(ytmap)/sizeof(map_str2int))-2)) != -1){
*cv_type = ret; *cv_type = ret;
return 0; return 0;
} }

View file

@ -33,13 +33,7 @@
See https://www.w3.org/TR/xpath/ See https://www.w3.org/TR/xpath/
* Turn this on to get an xpath test program *
* Usage: xpath [<xpath>]
* read xpath on first line and xml on rest of lines from input
* Example compile:
gcc -g -o xpath -I. -I../clixon ./clixon_xsl.c -lclixon -lcligen
* Example run:
echo "a\n<a><b/></a>" | xpath
*/ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H