Work on shell
FossilOrigin-Name: d35a5a97ee9087fde859a9e0694d9eb7890d2834cd2df0712d81dfa47afc5323
This commit is contained in:
@ -112,6 +112,7 @@ CWSRC=\
|
||||
|
||||
KTVSRC=\
|
||||
cw_ktv_add.c\
|
||||
cw_ktv_cast.c\
|
||||
cw_ktv_replace.c\
|
||||
cw_ktv_add_from_str.c\
|
||||
cw_ktv_get_byte.c\
|
||||
@ -125,6 +126,7 @@ KTVSRC=\
|
||||
cw_ktv_get_dword.c\
|
||||
cw_ktv_get_sysptr.c\
|
||||
cw_ktv_get_str.c\
|
||||
cw_ktv_parser.c\
|
||||
cw_ktv_idx_get.c\
|
||||
cw_ktv_mavlcmp.c\
|
||||
cw_ktv_mavlcmp_type_by_name.c\
|
||||
|
@ -58,6 +58,15 @@ static int cmp_by_session_id ( const void *d1, const void *d2 )
|
||||
struct conn * c1 = *( void ** ) d1;
|
||||
struct conn * c2 = *( void ** ) d2;
|
||||
int len1,len2;
|
||||
|
||||
if (c1->session_id==NULL && c2->session_id==NULL)
|
||||
return 0;
|
||||
|
||||
if (c1->session_id==NULL)
|
||||
return -1;
|
||||
if (c2->session_id==NULL)
|
||||
return 1;
|
||||
|
||||
len1 = bstr16_len(c1->session_id);
|
||||
len2 = bstr16_len(c2->session_id);
|
||||
|
||||
|
14
src/cw/cw_ktv_cast.c
Normal file
14
src/cw/cw_ktv_cast.c
Normal file
@ -0,0 +1,14 @@
|
||||
#include "ktv.h"
|
||||
|
||||
cw_KTV_t * cw_ktv_cast(cw_KTV_t *v,const cw_Type_t * type)
|
||||
{
|
||||
if (strcmp(v->type->name,type->name)==0)
|
||||
return v;
|
||||
if (type->cast==NULL)
|
||||
return NULL;
|
||||
if (!type->cast(v))
|
||||
return NULL;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
359
src/cw/cw_ktv_parser.c
Normal file
359
src/cw/cw_ktv_parser.c
Normal file
@ -0,0 +1,359 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ktv.h"
|
||||
|
||||
|
||||
static int str_getc(struct cw_KTV_Reader * r)
|
||||
{
|
||||
if (r->next==r->maxlen)
|
||||
return EOF;
|
||||
|
||||
return *((uint8_t*)(r->data)+r->next++);
|
||||
}
|
||||
|
||||
static void str_ungetc(struct cw_KTV_Reader * r, int c)
|
||||
{
|
||||
if (r->next>0)
|
||||
r->next--;
|
||||
}
|
||||
|
||||
void cw_ktv_init_str_reader(struct cw_KTV_Reader *r, const char * str, int len)
|
||||
{
|
||||
memset(r,0,sizeof(struct cw_KTV_Reader));
|
||||
r->data = str;
|
||||
r->getchar=str_getc;
|
||||
r->ungetchar=str_ungetc;
|
||||
r->maxlen=len;
|
||||
}
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "ktv.h"
|
||||
/*
|
||||
struct parser {
|
||||
int line;
|
||||
int pos;
|
||||
int prevpos;
|
||||
char error[256];
|
||||
int quote;
|
||||
FILE *f;
|
||||
int (*getc)(struct parser *);
|
||||
void (*ungetc)(struct parser *)
|
||||
};
|
||||
*/
|
||||
|
||||
|
||||
|
||||
static int get_char(struct cw_KTV_Reader *r)
|
||||
{
|
||||
int c;
|
||||
c = r->getchar (r);
|
||||
r->pos++;
|
||||
if (c=='\n'){
|
||||
r->prevpos=r->pos;
|
||||
r->line ++;
|
||||
r->pos=0;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
static void unget_char(struct cw_KTV_Reader * r,int c){
|
||||
r->ungetchar(r,c);
|
||||
if (c=='\n'){
|
||||
r->line--;
|
||||
r->pos=r->prevpos;
|
||||
}
|
||||
else
|
||||
r->pos--;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int get_char_q(struct cw_KTV_Reader *p)
|
||||
{
|
||||
int c;
|
||||
|
||||
while(1) {
|
||||
c = get_char(p);
|
||||
if (c==EOF || c=='\n')
|
||||
return c;
|
||||
|
||||
if(c=='"' && !p->quote){
|
||||
p->quote=1;
|
||||
continue;
|
||||
}
|
||||
if(c=='"' && p->quote){
|
||||
p->quote=0;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (!p->quote)
|
||||
return c;
|
||||
|
||||
if (c!='\\')
|
||||
return c;
|
||||
|
||||
c = get_char(p);
|
||||
switch(c){
|
||||
case EOF:
|
||||
return c;
|
||||
case 'n':
|
||||
return '\n';
|
||||
|
||||
case '\\':
|
||||
return '\\';
|
||||
case '"':
|
||||
return '"';
|
||||
default:
|
||||
unget_char(p,c);
|
||||
return '\\';
|
||||
}
|
||||
|
||||
/* We will never reach here */
|
||||
/* return c;*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int skip_chars (struct cw_KTV_Reader *r, const char * chars)
|
||||
{
|
||||
int c;
|
||||
|
||||
while ( (c = get_char (r)) != EOF) {
|
||||
if (strchr (chars, c))
|
||||
continue;
|
||||
return c;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
static int skip_to_chars (struct cw_KTV_Reader *r, const char *chars)
|
||||
{
|
||||
int c;
|
||||
|
||||
while ( (c = get_char (r)) != EOF) {
|
||||
if (strchr (chars, c))
|
||||
return c;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int read_key (struct cw_KTV_Reader *r, char *key, int max_len)
|
||||
{
|
||||
int c,n;
|
||||
|
||||
do {
|
||||
c = skip_chars (r, " \t\n\a\v");
|
||||
if (c == '#') {
|
||||
c = skip_to_chars (r, "\n\a");
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} while (c != EOF);
|
||||
|
||||
unget_char(r,c);
|
||||
c=get_char_q(r);
|
||||
|
||||
n=0;
|
||||
while(c!=EOF && n<max_len){
|
||||
if (!r->quote && !isalnum(c) && !strchr("._/-()@#|{}[]\\",c)){
|
||||
unget_char(r,c);
|
||||
break;
|
||||
}
|
||||
|
||||
key[n]=c;
|
||||
c=get_char_q(r);
|
||||
n++;
|
||||
|
||||
}
|
||||
key[n]=0;
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
static int skip_to_colon(struct cw_KTV_Reader * r)
|
||||
{
|
||||
int c;
|
||||
c = skip_chars (r, " \t");
|
||||
if (c!=':' && c!='='){
|
||||
if (c=='\n'){
|
||||
unget_char(r,c);
|
||||
sprintf(r->error,"Unexpected EOL, colon or equal sign expected.");
|
||||
return -1;
|
||||
}
|
||||
sprintf(r->error,"Colon or equal sign expected.");
|
||||
return -1;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
static int read_type(struct cw_KTV_Reader * r, char *type, int max_len)
|
||||
{
|
||||
int c,n;
|
||||
|
||||
c = skip_to_colon(r);
|
||||
if (c==-1)
|
||||
return -1;
|
||||
if (c=='='){
|
||||
unget_char(r,c);
|
||||
return sprintf(type,"%s","Str");
|
||||
|
||||
}
|
||||
|
||||
c = skip_chars (r, " \t");
|
||||
|
||||
if (c==':'){
|
||||
unget_char(r,c);
|
||||
sprintf(type,"%s","Str");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!isalpha(c)){
|
||||
if (c=='\n'){
|
||||
unget_char(r,c);
|
||||
/*sprintf(p->error,"Error at line %d, pos %d: Unexpected EOL.", p->line, p->pos);*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*sprintf(p->error,"Error at line %d, pos %d: Letter expected.", p->line, p->pos);*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
n=0;
|
||||
while(c!=EOF && n<max_len){
|
||||
if (!isalnum(c) && !strchr("_/-.()@#|{}[]",c)/*strchr(": \t\n\a",c)*/){
|
||||
unget_char(r,c);
|
||||
break;
|
||||
}
|
||||
|
||||
type[n]=c;
|
||||
c=get_char(r);
|
||||
n++;
|
||||
}
|
||||
type[n]=0;
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
static int read_val(struct cw_KTV_Reader *r, char *val, int max_len){
|
||||
int c,n,quote;
|
||||
c = skip_to_colon(r);
|
||||
if (c==-1)
|
||||
return -1;
|
||||
c = skip_chars (r, " \t");
|
||||
if (c=='"'){
|
||||
quote=1;
|
||||
c=get_char(r);
|
||||
}
|
||||
else{
|
||||
quote=0;
|
||||
}
|
||||
n=0;
|
||||
while(c!=EOF && n<max_len){
|
||||
if (quote && c=='"'){
|
||||
break;
|
||||
}
|
||||
if (c=='\n'){
|
||||
break;
|
||||
}
|
||||
if (quote){
|
||||
if (c=='\\'){
|
||||
c = get_char(r);
|
||||
switch(c){
|
||||
case 'n':
|
||||
c='\n';
|
||||
break;
|
||||
case '\\':
|
||||
break;
|
||||
case '"':
|
||||
break;
|
||||
default:
|
||||
unget_char(r,c);
|
||||
c='\\';
|
||||
}
|
||||
}
|
||||
}
|
||||
val[n++]=c;
|
||||
c=get_char(r);
|
||||
}
|
||||
|
||||
|
||||
if(!quote && n>0){
|
||||
while(n>0){
|
||||
if (isspace(val[n-1]))
|
||||
n--;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
val[n]=0;
|
||||
|
||||
return n;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
int cw_ktv_parse_line (FILE *f, char * key, char * type, char *val)
|
||||
{
|
||||
int n;
|
||||
|
||||
struct parser p;
|
||||
p.line=1;
|
||||
p.pos=0;
|
||||
p.prevpos=0;
|
||||
p.quote=0;
|
||||
p.f=f;
|
||||
|
||||
n = read_key (&p,key,CW_KTV_MAX_KEY_LEN);
|
||||
n = read_type (&p,type,CW_KTV_MAX_KEY_LEN);
|
||||
if (n==-1){
|
||||
return -1;
|
||||
}
|
||||
|
||||
n = read_val (&p,val,CW_KTV_MAX_KEY_LEN);
|
||||
if (n==-1){
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
int cw_ktv_parse_line(struct cw_KTV_Reader * r)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int cw_ktv_parse_string(struct cw_KTV_Reader *r, char *key, char *type, char *val)
|
||||
{
|
||||
|
||||
int n;
|
||||
|
||||
|
||||
|
||||
n = read_key (r,key,CW_KTV_MAX_KEY_LEN);
|
||||
n = read_type(r,type,200);
|
||||
if (n==1)
|
||||
return -1;
|
||||
n = read_val(r,val,200);
|
||||
return n;
|
||||
|
||||
}
|
@ -9,8 +9,15 @@ struct parser {
|
||||
char error[256];
|
||||
int quote;
|
||||
FILE *f;
|
||||
int (*getc)(struct parser *);
|
||||
void (*ungetc)(struct parser *)
|
||||
};
|
||||
|
||||
static int pgetc(struct parser *parser)
|
||||
{
|
||||
return fgetc(parser->f);
|
||||
}
|
||||
|
||||
static int get_char(struct parser *p)
|
||||
{
|
||||
int c;
|
||||
|
@ -2,7 +2,7 @@
|
||||
#include "dbg.h"
|
||||
#include "log.h"
|
||||
|
||||
int cw_ktv_write_struct(mavl_t ktv, const cw_KTVStruct_t * stru, const char *pkey,
|
||||
int cw_ktv_write_struct(mavl_t ktv, mavl_t def, const cw_KTVStruct_t * stru, const char *pkey,
|
||||
uint8_t * dst)
|
||||
{
|
||||
char key[CW_KTV_MAX_KEY_LEN];
|
||||
@ -28,6 +28,10 @@ int cw_ktv_write_struct(mavl_t ktv, const cw_KTVStruct_t * stru, const char *pke
|
||||
result = cw_ktv_get(ktv,key,NULL);
|
||||
|
||||
|
||||
if (result == NULL && def != NULL){
|
||||
result = cw_ktv_get(def,key,NULL);
|
||||
}
|
||||
|
||||
|
||||
if (result == NULL){
|
||||
cw_log(LOG_ERR,"Can't put %s, no value found, filling zero.",key);
|
||||
@ -35,7 +39,13 @@ int cw_ktv_write_struct(mavl_t ktv, const cw_KTVStruct_t * stru, const char *pke
|
||||
}
|
||||
else{
|
||||
result->valguard=stru[i].valguard;
|
||||
if (strcmp(stru[i].type->name,result->type->name)){
|
||||
if (cw_ktv_cast(result,stru[i].type)==NULL){
|
||||
cw_log(LOG_ERR,"Can't cast key '%s' from %s to %s",key,result->type->name,stru[i].type->name);
|
||||
}
|
||||
/* if (strcmp(stru[i].type->name,result->type->name)){
|
||||
|
||||
|
||||
|
||||
printf("Type mismatch: %s != %s\n",stru[i].type->name,result->type->name);
|
||||
if (stru[i].type->cast != NULL){
|
||||
if (!stru[i].type->cast(result)){
|
||||
@ -46,7 +56,7 @@ int cw_ktv_write_struct(mavl_t ktv, const cw_KTVStruct_t * stru, const char *pke
|
||||
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
result->type->put(result,dst+pos);
|
||||
}
|
||||
if (stru[i].len!=-1)
|
||||
|
@ -16,8 +16,11 @@ int cw_out_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams
|
||||
int start, len, l;
|
||||
|
||||
/* Get the element */
|
||||
search.key=(char*)handler->key;
|
||||
/* search.key=(char*)handler->key;
|
||||
elem = mavl_get(params->conn->local_cfg, &search);
|
||||
*/
|
||||
elem = cw_ktv_get(params->conn->local_cfg,handler->key,NULL);
|
||||
|
||||
/* if (elem == NULL && params->conn->default_cfg !=NULL)
|
||||
elem = mavl_get(params->conn->default_cfg, &search);
|
||||
*/
|
||||
@ -48,6 +51,12 @@ int cw_out_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams
|
||||
/* start = handler->vendor ? 10 : 4; */
|
||||
start = params->conn->header_len(handler);
|
||||
|
||||
if (cw_ktv_cast(elem,handler->type)==NULL){
|
||||
cw_log(LOG_ERR,"Can't put element '%s'- can't cast from %s to %s for key: %s", handler->name,
|
||||
elem->type->name, ((const cw_Type_t*)handler->type)->name, handler->key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = ((const cw_Type_t*)(handler->type))->put(elem,dst+start);
|
||||
|
||||
/* ((const cw_Type_t*)(handler->type))->to_str(elem,detail,120);
|
||||
|
@ -33,7 +33,8 @@ int cw_out_generic_indexed_enum(struct cw_ElemHandler * handler, struct cw_ElemH
|
||||
if (e[i].fun_out==NULL)
|
||||
len += result->type->put(result,ob+start+len);
|
||||
else
|
||||
len += cw_ktv_write_struct(params->conn->local_cfg,e[i].type,key,ob+start+len);
|
||||
len += cw_ktv_write_struct(params->conn->local_cfg,
|
||||
NULL,e[i].type,key,ob+start+len);
|
||||
|
||||
/* thandler.type=e[i].type;
|
||||
thandler.key=key;
|
||||
|
@ -32,7 +32,9 @@ int cw_out_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHandler
|
||||
|
||||
start = params->conn->header_len(handler);
|
||||
|
||||
len = cw_ktv_write_struct(params->conn->local_cfg,handler->type,handler->key,dst+start);
|
||||
len = cw_ktv_write_struct(params->conn->local_cfg,
|
||||
params->conn->default_cfg,
|
||||
handler->type,handler->key,dst+start);
|
||||
|
||||
return params->conn->write_header(handler,dst,len);
|
||||
|
||||
|
@ -43,7 +43,7 @@ int cw_out_idx_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHan
|
||||
start = mdst + params->conn->header_len(handler);
|
||||
|
||||
len += cw_put_byte(start+len,idx);
|
||||
len += cw_ktv_write_struct(params->conn->local_cfg,handler->type,key,start+len);
|
||||
len += cw_ktv_write_struct(params->conn->local_cfg,NULL, handler->type,key,start+len);
|
||||
|
||||
mdst += params->conn->write_header(handler,mdst,len);
|
||||
|
||||
|
@ -43,7 +43,7 @@ int cw_out_radio_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemH
|
||||
|
||||
l=0;
|
||||
l+=cw_put_byte(cdst+offset+l,i);
|
||||
l+= cw_ktv_write_struct(params->conn->local_cfg,handler->type,basekey,cdst+offset+l);
|
||||
l+= cw_ktv_write_struct(params->conn->local_cfg,NULL, handler->type,basekey,cdst+offset+l);
|
||||
|
||||
|
||||
cdst+=params->conn->write_header(handler,cdst,l);
|
||||
|
@ -100,6 +100,11 @@ int cw_put_msg(struct conn *conn, uint8_t * rawout)
|
||||
params.msgdata=msg;
|
||||
params.debug_details=details;
|
||||
*details=0;
|
||||
|
||||
if (strcmp(handler->key,"cisco/ap-led-flash-config")==0){
|
||||
printf("flash config\n");
|
||||
/* cisco/ap-led-flash-config/flash-enable */
|
||||
}
|
||||
|
||||
l = handler->put(handler,¶ms,dst+len);
|
||||
|
||||
|
@ -91,6 +91,20 @@ static const char * get_type_name(cw_KTV_t *data)
|
||||
return CW_TYPE_BSTR16->name;
|
||||
}
|
||||
|
||||
static int cast(cw_KTV_t * data)
|
||||
{
|
||||
if (strcmp(data->type->name,CW_TYPE_BSTR16->name)==0)
|
||||
return 1;
|
||||
if (strcmp(data->type->name,CW_TYPE_STR->name)==0){
|
||||
char *src = data->val.ptr;
|
||||
CW_TYPE_BSTR16->from_str(data,src);
|
||||
free(src);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
const struct cw_Type cw_type_bstr16 = {
|
||||
"Bstr16", /* name */
|
||||
del, /* del */
|
||||
@ -100,5 +114,8 @@ const struct cw_Type cw_type_bstr16 = {
|
||||
from_str, /* from_str */
|
||||
len, /* len */
|
||||
data, /* data */
|
||||
get_type_name /* get_type_name */
|
||||
get_type_name, /* get_type_name */
|
||||
cast /* cast */
|
||||
};
|
||||
|
||||
|
||||
|
@ -50,6 +50,22 @@ static const char * get_type_name(cw_KTV_t *data)
|
||||
return CW_TYPE_DWORD->name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int cast(cw_KTV_t * data)
|
||||
{
|
||||
if (strcmp(data->type->name,CW_TYPE_BYTE->name)==0)
|
||||
return 1;
|
||||
if (strcmp(data->type->name,CW_TYPE_STR->name)==0){
|
||||
char *src = data->val.ptr;
|
||||
CW_TYPE_DWORD->from_str(data,src);
|
||||
free(src);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
const struct cw_Type cw_type_dword = {
|
||||
"Dword", /* name */
|
||||
NULL, /* del */
|
||||
@ -59,6 +75,7 @@ const struct cw_Type cw_type_dword = {
|
||||
from_str, /* from_str */
|
||||
NULL, /* len */
|
||||
NULL, /* data */
|
||||
get_type_name /* get_type_name */
|
||||
get_type_name, /* get_type_name */
|
||||
cast
|
||||
};
|
||||
|
||||
|
23
src/cw/ktv.h
23
src/cw/ktv.h
@ -136,7 +136,7 @@ typedef struct cw_KTVIndexed cw_KTVIndexed_t;
|
||||
|
||||
int cw_ktv_read_struct(mavl_t ktv,const cw_KTVStruct_t * stru, const char *pkey,
|
||||
uint8_t * data, int len);
|
||||
int cw_ktv_write_struct(mavl_t ktv, const cw_KTVStruct_t * stru, const char *pkey,
|
||||
int cw_ktv_write_struct(mavl_t ktv, mavl_t def, const cw_KTVStruct_t * stru, const char *pkey,
|
||||
uint8_t * dst);
|
||||
|
||||
|
||||
@ -209,10 +209,29 @@ char * cw_ktv_get_str(mavl_t ktv,const char *key, char * def);
|
||||
int cw_ktv_idx_get(mavl_t ktv, const char *key);
|
||||
cw_KTV_t * cw_ktv_base_exists(mavl_t ktvstore, const char *basekey);
|
||||
int cw_ktv_save(mavl_t ktvstore, const char * filename);
|
||||
|
||||
cw_KTV_t * cw_ktv_cast(cw_KTV_t *v,const cw_Type_t * type);
|
||||
|
||||
extern const cw_Type_t * cw_ktv_std_types[];
|
||||
#define CW_KTV_STD_TYPES cw_ktv_std_types
|
||||
|
||||
|
||||
|
||||
struct cw_KTV_Reader {
|
||||
const void * data;
|
||||
int (*getchar)(struct cw_KTV_Reader *);
|
||||
void (*ungetchar)(struct cw_KTV_Reader *, int c);
|
||||
int quote;
|
||||
int line;
|
||||
int pos;
|
||||
int prevpos;
|
||||
int next;
|
||||
int maxlen;
|
||||
char error[256];
|
||||
};
|
||||
|
||||
void cw_ktv_init_str_reader(struct cw_KTV_Reader *r, const char * str, int len);
|
||||
int cw_ktv_parse_string(struct cw_KTV_Reader *r, char *key, char *type, char *val);
|
||||
|
||||
/**
|
||||
* @} KTV
|
||||
* @} ALGOS
|
||||
|
Reference in New Issue
Block a user