Merging 'de' libcm into 'cmtest' libcm

This commit is contained in:
kevin 2013-11-14 16:51:20 -05:00
commit ead258c822
4 changed files with 697 additions and 14 deletions

677
cmData.c
View File

@ -4,7 +4,11 @@
#include "cmCtx.h" #include "cmCtx.h"
#include "cmMem.h" #include "cmMem.h"
#include "cmMallocDebug.h" #include "cmMallocDebug.h"
#include "cmLinkedHeap.h"
#include "cmData.h" #include "cmData.h"
#include "cmLex.h"
#include "cmText.h"
#include "cmStack.h"
cmDtRC_t _cmDataErrNo = kOkDtRC; cmDtRC_t _cmDataErrNo = kOkDtRC;
@ -666,20 +670,26 @@ cmData_t* cmDataSetDoublePtr( cmData_t* p, double* vp, unsigned cnt )
// Set the value of an existing array based data object. // Set the value of an existing array based data object.
// Allocate the internal array and copy the array into it. // Allocate the internal array and copy the array into it.
cmData_t* cmDataSetStrAlloc( cmData_t* p, const cmChar_t* s ) cmData_t* cmDataSetStrAllocN( cmData_t* p, const cmChar_t* s, unsigned charCnt )
{ {
if( cmIsFlag(p->flags,kDynPtrDtFl) ) if( cmIsFlag(p->flags,kDynPtrDtFl) )
cmMemResizeStr(p->u.z,s); cmMemResizeStrN(p->u.z,s,charCnt);
else else
{ {
_cmDataFreeArray(p); _cmDataFreeArray(p);
p->u.z = cmMemAllocStr(s); p->u.z = cmMemAllocStrN(s,charCnt);
} }
p->tid = kStrDtId; p->tid = kStrDtId;
p->flags = cmSetFlag(p->flags,kDynPtrDtFl); p->flags = cmSetFlag(p->flags,kDynPtrDtFl);
return p; return p;
} }
cmData_t* cmDataSetStrAlloc( cmData_t* p, const cmChar_t* s )
{ return cmDataSetStrAllocN(p,s,strlen(s)); }
cmData_t* cmDataSetConstStrAllocN( cmData_t* p, const cmChar_t* s, unsigned charCnt )
{ return cmDataSetStrAllocN(p,s,charCnt); }
cmData_t* cmDataSetConstStrAlloc( cmData_t* p, const cmChar_t* s ) cmData_t* cmDataSetConstStrAlloc( cmData_t* p, const cmChar_t* s )
{ return cmDataSetStrAlloc(p,s); } { return cmDataSetStrAlloc(p,s); }
@ -695,6 +705,7 @@ cmData_t* cmDataSetCharAllocPtr( cmData_t* p, const char* vp, unsigned cnt )
_cmDataFreeArray(p); _cmDataFreeArray(p);
p->u.cp = cmMemAlloc(char, cnt ); p->u.cp = cmMemAlloc(char, cnt );
} }
memcpy(p->u.cp,vp,sizeof(char)*cnt); memcpy(p->u.cp,vp,sizeof(char)*cnt);
p->tid = kCharPtrDtId; p->tid = kCharPtrDtId;
p->flags = cmSetFlag(p->flags,kDynPtrDtFl); p->flags = cmSetFlag(p->flags,kDynPtrDtFl);
@ -1032,6 +1043,14 @@ cmData_t* cmDataStrAlloc( cmData_t* parent, cmChar_t* str )
return p; return p;
} }
cmData_t* cmDataConstStrAllocN( cmData_t* parent, const cmChar_t* str, unsigned charCnt )
{
cmData_t* p = _cmDataAllocNode(parent,kConstStrDtId);
cmDataSetConstStrAllocN(p,str,charCnt);
return p;
}
cmData_t* cmDataConstStrAlloc( cmData_t* parent, const cmChar_t* str ) cmData_t* cmDataConstStrAlloc( cmData_t* parent, const cmChar_t* str )
{ {
cmData_t* p = _cmDataAllocNode(parent,kConstStrDtId); cmData_t* p = _cmDataAllocNode(parent,kConstStrDtId);
@ -1458,6 +1477,15 @@ cmData_t* cmDataAllocPairLabel( cmData_t* parent, const cmChar_t *label, cmData_
cmDataAppendChild(p,value); cmDataAppendChild(p,value);
return p; return p;
} }
cmData_t* cmDataAllocPairLabelN(cmData_t* parent, const cmChar_t* label, unsigned charCnt, cmData_t* value)
{
cmData_t* p = _cmDataAllocNode(parent,kPairDtId);
cmDataConstStrAllocN(p,label,charCnt);
cmDataAppendChild(p,value);
return p;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -1757,7 +1785,7 @@ const cmChar_t* cmDataRecdKeyLabel( cmData_t* p, unsigned index )
return label; return label;
} }
cmData_t* cmRecdMake( cmData_t* parent, cmData_t* p ) cmData_t* cmDataRecdMake( cmData_t* parent, cmData_t* p )
{ {
_cmDataFree(p); _cmDataFree(p);
p->parent = parent; p->parent = parent;
@ -1767,10 +1795,10 @@ cmData_t* cmRecdMake( cmData_t* parent, cmData_t* p )
return p; return p;
} }
cmData_t* cmRecdAlloc(cmData_t* parent) cmData_t* cmDataRecdAlloc(cmData_t* parent)
{ return _cmDataAllocNode(parent,kRecordDtId); } { return _cmDataAllocNode(parent,kRecordDtId); }
cmData_t* cmRecdAppendPair( cmData_t* p, cmData_t* pair ) cmData_t* cmDataRecdAppendPair( cmData_t* p, cmData_t* pair )
{ {
assert( p!=NULL && p->tid==kRecordDtId); assert( p!=NULL && p->tid==kRecordDtId);
cmDataAppendChild(p,pair); cmDataAppendChild(p,pair);
@ -1820,7 +1848,7 @@ cmDtRC_t _cmDataRecdParseInputV(cmData_t* parent, unsigned idFl, va_list vl )
cmData_t* cmDataRecdAllocLabelV( cmData_t* parent, va_list vl ) cmData_t* cmDataRecdAllocLabelV( cmData_t* parent, va_list vl )
{ {
cmData_t* p = cmRecdAlloc(parent); cmData_t* p = cmDataRecdAlloc(parent);
cmDtRC_t rc = _cmDataRecdParseInputV(p, false, vl ); cmDtRC_t rc = _cmDataRecdParseInputV(p, false, vl );
if( rc != kOkDtRC ) if( rc != kOkDtRC )
{ {
@ -1841,7 +1869,7 @@ cmData_t* cmDataRecdAllocLabelA( cmData_t* parent, ... )
cmData_t* cmDataRecdAllocIdV( cmData_t* parent, va_list vl ) cmData_t* cmDataRecdAllocIdV( cmData_t* parent, va_list vl )
{ {
cmData_t* p = cmRecdAlloc(parent); cmData_t* p = cmDataRecdAlloc(parent);
cmDtRC_t rc = _cmDataRecdParseInputV(p, true, vl ); cmDtRC_t rc = _cmDataRecdParseInputV(p, true, vl );
if( rc != kOkDtRC ) if( rc != kOkDtRC )
{ {
@ -2061,7 +2089,10 @@ cmDtRC_t cmDataRecdParseId(cmData_t* p, cmErr_t* err, unsigned errRC, ... )
//---------------------------------------------------------------------------- //============================================================================
//============================================================================
//============================================================================
unsigned _cmDataSerializeNodeByteCount( const cmData_t* p ) unsigned _cmDataSerializeNodeByteCount( const cmData_t* p )
{ {
unsigned n = 0; unsigned n = 0;
@ -2191,6 +2222,590 @@ cmDtRC_t cmDataDeserialize( const void* buf, unsigned bufByteCnt, cmData_t** pp
return kOkDtRC; return kOkDtRC;
} }
//============================================================================
//============================================================================
//============================================================================
enum
{
kLCurlyLexTId = kUserLexTId + 1,
kRCurlyLexTId,
kLParenLexTId,
kRParenLexTId,
kLBrackLexTId,
kRBrackLexTId,
kColonLexTId,
kCommaLexTId,
};
typedef struct
{
unsigned id;
const cmChar_t* label;
} cmDtToken_t;
cmDtToken_t _cmDtTokenArray[] =
{
{ kLCurlyLexTId, "{" },
{ kRCurlyLexTId, "}" },
{ kLBrackLexTId, "[" },
{ kRBrackLexTId, "]" },
{ kLParenLexTId, "(" },
{ kRParenLexTId, ")" },
{ kColonLexTId, ":" },
{ kCommaLexTId, "," },
{ kErrorLexTId,""}
};
typedef struct
{
cmErr_t err;
cmLexH lexH;
cmStackH_t stH;
} cmDataParser_t;
cmDataParserH_t cmDataParserNullHandle = cmSTATIC_NULL_HANDLE;
cmDataParser_t* _cmDataParserHandleToPtr( cmDataParserH_t h )
{
cmDataParser_t* p = (cmDataParser_t*)h.h;
assert( p!= NULL );
return p;
}
cmDtRC_t _cmDataParserDestroy( cmDataParser_t* p )
{
if( cmLexFinal(&p->lexH) != kOkLexRC )
cmErrMsg(&p->err,kLexFailDtRC,"Lexer release failed.");
if( cmStackFree(&p->stH) != kOkStRC )
cmErrMsg(&p->err,kParseStackFailDtRC,"The data object parser stack release failed.");
return kOkDtRC;
}
cmDtRC_t cmDataParserCreate( cmCtx_t* ctx, cmDataParserH_t* hp )
{
cmDtRC_t rc;
unsigned i;
if((rc = cmDataParserDestroy(hp)) != kOkDtRC )
return rc;
cmDataParser_t* p = cmMemAllocZ(cmDataParser_t,1);
cmErrSetup(&p->err,&ctx->rpt,"Data Parser");
if(cmLexIsValid(p->lexH = cmLexInit(NULL,0,0,&ctx->rpt))==false)
{
rc = cmErrMsg(&p->err, kLexFailDtRC, "The data object parser lexer create failed.");
goto errLabel;
}
for(i=0; _cmDtTokenArray[i].id != kErrorLexTId; ++i)
if( cmLexRegisterToken(p->lexH, _cmDtTokenArray[i].id, _cmDtTokenArray[i].label) != kOkLexRC )
{
rc = cmErrMsg(&p->err,kLexFailDtRC,"The data object parser lexer could not register the '%s' token.",_cmDtTokenArray[i].label);
goto errLabel;
}
if( cmStackAlloc(ctx, &p->stH, 1024, 1024, sizeof(cmData_t*)) != kOkStRC )
{
rc = cmErrMsg(&p->err,kParseStackFailDtRC,"The data object parser stack create failed.");
goto errLabel;
}
hp->h = p;
errLabel:
if( rc != kOkDtRC )
_cmDataParserDestroy(p);
return kOkDtRC;
}
cmDtRC_t cmDataParserDestroy( cmDataParserH_t* hp )
{
cmDtRC_t rc=kOkDtRC;
if( hp==NULL || cmDataParserIsValid(*hp)==false )
return rc;
cmDataParser_t* p = _cmDataParserHandleToPtr(*hp);
if((rc = _cmDataParserDestroy(p)) != kOkDtRC )
return rc;
hp->h = NULL;
return kOkDtRC;
}
bool cmDataParserIsValid( cmDataParserH_t h )
{ return h.h != NULL; }
// {
// id0 : scalar_value
// id1 : ( heterogenous, array, value )
// id2 : [ homogeneous array values ]
// id3 :
// }
// flags describing the expected next token
enum
{
kValueExpFl = 0x01,
kIdExpFl = 0x02,
kColonExpFl = 0x04,
kCommaExpFl = 0x08
};
typedef struct
{
cmData_t* dp;
} cmDataStEle_t;
typedef struct
{
cmDataParser_t* p;
cmData_t* cnp;
unsigned flags;
cmChar_t* tmpStr;
unsigned arrayCnt;
void* arrayMem;
} cmDataParserCtx_t;
cmDtRC_t _cmDpSyntaxErrV( cmDataParserCtx_t* c, const cmChar_t* fmt, va_list vl )
{
cmChar_t* s0 = NULL;
s0 = cmTsVPrintfP(s0,fmt,vl);
cmDtRC_t rc = cmErrMsg(&c->p->err,kSyntaxErrDtRC,"Syntax error on line %i. %s",cmLexCurrentLineNumber(c->p->lexH),cmStringNullGuard(s0));
cmMemFree(s0);
return rc;
}
cmDtRC_t _cmDpSyntaxErr( cmDataParserCtx_t* c, const cmChar_t* fmt, ... )
{
va_list vl;
va_start(vl,fmt);
cmDtRC_t rc = _cmDpSyntaxErrV(c,fmt,vl);
va_end(vl);
return rc;
}
cmDtRC_t _cmDpPopStack( cmDataParserCtx_t* c, cmData_t** pp )
{
const void* vp;
if((vp = cmStackTop(c->p->stH)) == NULL )
return _cmDpSyntaxErr(c,"Stack underflow.");
*pp = *(cmData_t**)vp;
return kOkDtRC;
}
cmDtRC_t _cmDpStoreArrayEle( cmDataParserCtx_t* c, void* dp, unsigned byteCnt )
{
char* vp = cmMemResize(char, c->cnp->u.vp, c->cnp->cnt+byteCnt);
memcpy(vp + c->cnp->cnt,dp,byteCnt);
c->cnp->u.vp = vp;
c->cnp->cnt += byteCnt;
c->flags = kValueExpFl | kCommaExpFl;
return kOkDtRC;
}
cmDtRC_t _cmDataParserOpenPair( cmDataParserCtx_t* c )
{
assert( c->cnp->tid == kRecordDtId );
cmData_t* nnp = cmDataAllocNull(NULL);
cmData_t* pnp = cmDataAllocPairLabelN( c->cnp, cmLexTokenText(c->p->lexH), cmLexTokenCharCount(c->p->lexH), nnp );
// store the current node
if( cmStackPush(c->p->stH, &c->cnp, 1 ) != kOkStRC )
return _cmDpSyntaxErr(c,"Parser stack push failed.");
// make the new pair the current node
c->cnp = pnp;
// pair openings must be followed by a colon.
c->flags = kColonExpFl;
return kOkDtRC;
}
cmDtRC_t _cmDataParserClosePair( cmDataParserCtx_t* c )
{
cmDtRC_t rc;
// make the pair's parent record the current node
if((rc = _cmDpPopStack(c, &c->cnp )) != kOkDtRC )
return rc;
// pairs only occur in records
if( c->cnp->tid != kRecordDtId )
return _cmDpSyntaxErr(c,"A 'pair' end was found outside of a 'record'.");
// pairs must be followed by id's or comma's
c->flags = kIdExpFl | kCommaExpFl;
return rc;
}
cmDtRC_t _cmDpStoreValue( cmDataParserCtx_t* c, cmData_t* np, const cmChar_t* typeLabel )
{
assert( np != NULL );
cmDtRC_t rc = kOkDtRC;
switch( c->cnp->tid )
{
case kPairDtId:
// assign the new node as the value of the pair
cmDataPairSetValue(c->cnp,np);
// close the values parent pair
rc = _cmDataParserClosePair(c);
break;
case kListDtId:
cmDataAppendChild(c->cnp,np);
c->flags = kValueExpFl;
break;
default:
rc = _cmDpSyntaxErr(c,"A '%s' value was found outside of a valid container.",typeLabel);
}
c->flags |= kCommaExpFl;
return rc;
}
cmDtRC_t _cmDataParserReal( cmDataParserCtx_t* c )
{
cmDtRC_t rc = kOkDtRC;
double val = cmLexTokenDouble(c->p->lexH);
if( c->cnp->tid == kVoidPtrDtId )
rc = _cmDpStoreArrayEle(c,&val,sizeof(val));
else
rc = _cmDpStoreValue(c,cmDataAllocDouble(NULL,val),"real");
return rc;
}
cmDtRC_t _cmDataParserInt( cmDataParserCtx_t* c )
{
cmDtRC_t rc = kOkDtRC;
int val = cmLexTokenInt(c->p->lexH);
if( c->cnp->tid == kVoidPtrDtId )
rc = _cmDpStoreArrayEle(c,&val,sizeof(val));
else
rc = _cmDpStoreValue(c,cmDataAllocInt(NULL,val),"int");
return rc;
}
cmDtRC_t _cmDataParserString( cmDataParserCtx_t* c )
{
// if we are expecting a pair label
if( cmIsFlag(c->flags,kIdExpFl) )
return _cmDataParserOpenPair(c);
// otherwise a 'value' must be expected
if( cmIsNotFlag(c->flags,kValueExpFl) )
return _cmDpSyntaxErr(c,"Unexpected string.");
cmData_t* np = cmDataConstStrAllocN(NULL,cmLexTokenText(c->p->lexH), cmLexTokenCharCount(c->p->lexH));
return _cmDpStoreValue(c,np,"string");
}
cmDtRC_t _cmDataParserOpenRecd( cmDataParserCtx_t* c )
{
// records are values - so we must be expecting a value
if( cmIsFlag(c->flags,kValueExpFl) == false )
return _cmDpSyntaxErr(c,"Unexpected '{'.");
// store the current node
if( cmStackPush(c->p->stH, &c->cnp, 1 ) != kOkStRC )
return _cmDpSyntaxErr(c,"Parser stack push failed.");
// alloc a new record and make it the current node
if( (c->cnp = cmDataRecdAlloc(c->cnp)) == NULL )
return _cmDpSyntaxErr(c,"'recd' allocate failed.");
// new records must be followed by an id token.
c->flags = kIdExpFl;
return kOkDtRC;
}
cmDtRC_t _cmDataParserCloseRecd( cmDataParserCtx_t* c )
{
cmDtRC_t rc;
// make the parent node the new curren node
if((rc = _cmDpPopStack(c,&c->cnp)) != kOkDtRC )
return rc;
switch( c->cnp->tid )
{
case kPairDtId:
// if the parent node is a pair then close it
rc = _cmDataParserClosePair(c);
break;
case kListDtId:
// parent node is a list - so expect another value
c->flags = kValueExpFl;
break;
default:
return _cmDpSyntaxErr(c,"'records' may only be contained in other records or heterogenous arrays.");
}
c->flags |= kCommaExpFl;
return rc;
}
cmDtRC_t _cmDataParserOpenList( cmDataParserCtx_t* c )
{
// lists are values - so we must be expecting a value
if( cmIsFlag(c->flags,kValueExpFl) == false )
return _cmDpSyntaxErr(c,"Unexpected '('.");
// store the current node
if( cmStackPush(c->p->stH, &c->cnp, 1 ) != kOkStRC )
return _cmDpSyntaxErr(c,"Parser stack push failed.");
// create a new list
if( (c->cnp = cmDataListAlloc(c->cnp)) == NULL )
return _cmDpSyntaxErr(c,"'list' allocate failed.");
// new lists must be followed by a value
c->flags = kValueExpFl;
return kOkDtRC;
}
cmDtRC_t _cmDataParserCloseList( cmDataParserCtx_t* c )
{
cmDtRC_t rc;
// make the list's parent the current node
if((rc = _cmDpPopStack(c,&c->cnp)) != kOkDtRC )
return rc;
switch( c->cnp->tid )
{
case kPairDtId:
// if the list's parent is a pair then close it
rc = _cmDataParserClosePair(c);
break;
case kListDtId:
// the list's parent is another list so expect a value
c->flags = kValueExpFl;
break;
default:
return _cmDpSyntaxErr(c,"'lists' may only be contained in other records or lists.");
}
c->flags |= kCommaExpFl;
return rc;
}
cmDtRC_t _cmDataParserOpenArray( cmDataParserCtx_t* c )
{
// arrays are values - so we must be expecting a value
if( cmIsFlag(c->flags,kValueExpFl) == false )
return _cmDpSyntaxErr(c,"Unexpected '('.");
// store the current node
if( cmStackPush(c->p->stH, &c->cnp, 1 ) != kOkStRC )
return _cmDpSyntaxErr(c,"Parser stack push failed.");
// create a new array
if( (c->cnp = cmDataSetVoidAllocPtr(c->cnp, NULL, 0 )) == NULL )
return _cmDpSyntaxErr(c,"'array' allocate failed.");
// new arrays must be followed by a value
c->flags = kValueExpFl;
return kOkDtRC;
}
cmDtRC_t _cmDataParserCloseArray( cmDataParserCtx_t* c )
{
cmDtRC_t rc;
// make the arrays parent the current node
if((rc = _cmDpPopStack(c,&c->cnp)) != kOkDtRC )
return rc;
switch( c->cnp->tid )
{
case kPairDtId:
// the arrays parent is a pair - so close it
rc = _cmDataParserClosePair(c);
break;
case kListDtId:
// the arrays parent is a list - so expect a value
c->flags = kValueExpFl;
break;
default:
return _cmDpSyntaxErr(c,"'arrays' may only be contained in other records or lists.");
}
c->flags |= kCommaExpFl;
return rc;
}
cmDtRC_t _cmDataParserOnColon( cmDataParserCtx_t* c )
{
// colons only follow field identifiers and are always followed by values.
if( cmIsFlag(c->flags,kColonExpFl) == false )
return _cmDpSyntaxErr(c,"Unexpected colon.");
c->flags = kValueExpFl;
return kOkDtRC;
}
cmDtRC_t _cmDataParserOnComma( cmDataParserCtx_t* c )
{
// comma's may be found in three places:
// 1) following field values
// 2) between list values
// 3) between array values
// comma's are always followed by values
if( cmIsFlag(c->flags,kCommaExpFl) == false )
return _cmDpSyntaxErr(c, "Unexpected comma.");
c->flags = kValueExpFl;
return kOkDtRC;
}
cmDtRC_t cmDataParserExec( cmDataParserH_t h, const cmChar_t* text, cmData_t** pp )
{
cmDtRC_t rc = kOkDtRC;
unsigned tokenId;
cmDataParserCtx_t ctx;
cmDataParser_t* p = _cmDataParserHandleToPtr(h);
ctx.cnp = NULL; // current node ptr
ctx.p = p;
ctx.flags = kValueExpFl;
if( cmLexSetTextBuffer(p->lexH,text,strlen(text)) != kOkLexRC )
return cmErrMsg(&p->err,kLexFailDtRC,"The data object lexer failed during reset.");
cmStackClear(p->stH,false);
while((tokenId = cmLexGetNextToken(p->lexH)) != kEofLexTId )
{
switch(tokenId)
{
case kRealLexTId: // real number (contains a decimal point or is in scientific notation)
rc = _cmDataParserReal(&ctx);
break;
case kIntLexTId: // decimal integer
rc = _cmDataParserInt(&ctx);
break;
case kHexLexTId: // hexidecimal integer
rc = _cmDataParserInt(&ctx);
break;
case kIdentLexTId: // identifiers are treated as strings
case kQStrLexTId: // quoted string
rc = _cmDataParserString(&ctx);
break;
case kLCurlyLexTId: // a new record is starting
rc = _cmDataParserOpenRecd(&ctx);
break;
case kRCurlyLexTId: // the current record is finished
rc = _cmDataParserCloseRecd(&ctx);
break;
case kLParenLexTId: // a list is starting
rc = _cmDataParserOpenList(&ctx);
break;
case kRParenLexTId: // a list is finished
rc = _cmDataParserCloseList(&ctx);
break;
case kLBrackLexTId: // an array is starting
rc = _cmDataParserOpenArray(&ctx);
break;
case kRBrackLexTId: // an array is ending
rc = _cmDataParserCloseArray(&ctx);
break;
case kColonLexTId: // the previous id was a field id
rc = _cmDataParserOnColon(&ctx);
break;
case kCommaLexTId: // comma sep. for array or fields
rc = _cmDataParserOnComma(&ctx);
break;
case kBlockCmtLexTId: // block comment
case kLineCmtLexTId: // line comment
case kErrorLexTId: // the lexer was unable to identify the current token
case kUnknownLexTId: // the token is of an unknown type (only used when kReturnUnknownLexFl is set)
case kEofLexTId: // the lexer reached the end of input
case kSpaceLexTId: // white space
{
rc = cmErrMsg(&p->err,kLexFailDtRC,"The data object lexer failed with an unexpected token '%s' on line '%i'.",cmLexIdToLabel(p->lexH,tokenId),cmLexCurrentLineNumber(p->lexH));
goto errLabel;
}
}
}
errLabel:
return rc;
}
//============================================================================
//============================================================================
//============================================================================
#define parr(rpt,fmt,arr,n) do{int i=0; cmRptPrintf(rpt,"[ "); for(;i<n;++i) cmRptPrintf(rpt,fmt,arr[i]); cmRptPrintf(rpt," ]"); }while(0) #define parr(rpt,fmt,arr,n) do{int i=0; cmRptPrintf(rpt,"[ "); for(;i<n;++i) cmRptPrintf(rpt,fmt,arr[i]); cmRptPrintf(rpt," ]"); }while(0)
void _cmDataPrintIndent( cmRpt_t* rpt, unsigned indent ) void _cmDataPrintIndent( cmRpt_t* rpt, unsigned indent )
@ -2280,10 +2895,54 @@ void _cmDataPrint( const cmData_t* p, cmRpt_t* rpt, unsigned indent )
void cmDataPrint( const cmData_t* p, cmRpt_t* rpt ) void cmDataPrint( const cmData_t* p, cmRpt_t* rpt )
{ _cmDataPrint(p,rpt,0); } { _cmDataPrint(p,rpt,0); }
cmDtRC_t cmDataParserTest( cmCtx_t* ctx )
{
cmDtRC_t rc = kOkDtRC;
cmDataParserH_t h = cmDataParserNullHandle;
cmErr_t err;
cmData_t* dp = NULL;
const cmChar_t text[] =
{
"{ f0:1.23 f1:\"hey\" "
};
cmErrSetup(&err,&ctx->rpt,"Data Parser Tester");
if((rc = cmDataParserCreate(ctx, &h )) != kOkDtRC )
{
rc = cmErrMsg(&err,rc,"Data parser create failed.");
goto errLabel;
}
if( cmDataParserExec(h,text,&dp) != kOkDtRC )
rc = cmErrMsg(&err,rc,"Data parser exec failed.");
else
{
cmDataPrint(dp,&ctx->rpt);
}
errLabel:
if( cmDataParserDestroy( &h ) != kOkDtRC )
{
rc = cmErrMsg(&err,rc,"Data parser destroy failed.");
goto errLabel;
}
cmDataFree(dp);
return rc;
}
void cmDataTest( cmCtx_t* ctx ) void cmDataTest( cmCtx_t* ctx )
{ {
float farr[] = { 1.23, 45.6, 7.89 }; float farr[] = { 1.23, 45.6, 7.89 };
cmDataParserTest(ctx);
return;
cmData_t* d0 = cmDataRecdAllocLabelA(NULL, cmData_t* d0 = cmDataRecdAllocLabelA(NULL,
"name",kConstStrDtId,"This is a string.", "name",kConstStrDtId,"This is a string.",
"id", kUIntDtId, 21, "id", kUIntDtId, 21,

View File

@ -11,6 +11,9 @@ extern "C" {
kCvtErrDtRC, kCvtErrDtRC,
kVarArgErrDtRC, kVarArgErrDtRC,
kMissingFieldDtRC, kMissingFieldDtRC,
kLexFailDtRC,
kParseStackFailDtRC,
kSyntaxErrDtRC,
kEolDtRC kEolDtRC
}; };
@ -64,8 +67,8 @@ extern "C" {
kMinStructDtId, kMinStructDtId,
kListDtId = kMinStructDtId, // children nodes are array elements, cnt=child count kListDtId = kMinStructDtId, // children nodes are array elements, cnt=child count
kPairDtId, // key/value pairs, cnt=2, first child is key, second is value kPairDtId, // key/value pairs, cnt=2, first child is key, second is value
kRecordDtId, // children nodes are pairs, cnt=pair count kRecordDtId, // children nodes are pairs, cnt=pair count
kMaxStructDtId, kMaxStructDtId,
kOptArgDtFl = 0x80000000 kOptArgDtFl = 0x80000000
@ -271,7 +274,9 @@ extern "C" {
// These functions begin by releasing any resources help by *p // These functions begin by releasing any resources help by *p
// and then dynamically allocate the internal array and copy // and then dynamically allocate the internal array and copy
// the array data into it. // the array data into it.
cmData_t* cmDataSetStrAllocN( cmData_t* p, const cmChar_t* s, unsigned charCnt );
cmData_t* cmDataSetStrAlloc( cmData_t* p, const cmChar_t* s ); cmData_t* cmDataSetStrAlloc( cmData_t* p, const cmChar_t* s );
cmData_t* cmDataSetConstStrAllocN( cmData_t* p, const cmChar_t* s, unsigned charCnt );
cmData_t* cmDataSetConstStrAlloc( cmData_t* p, const cmChar_t* s ); cmData_t* cmDataSetConstStrAlloc( cmData_t* p, const cmChar_t* s );
cmData_t* cmDataSetVoidAllocPtr( cmData_t* p, const void* vp, unsigned cnt ); cmData_t* cmDataSetVoidAllocPtr( cmData_t* p, const void* vp, unsigned cnt );
cmData_t* cmDataSetCharAllocPtr( cmData_t* p, const char* vp, unsigned cnt ); cmData_t* cmDataSetCharAllocPtr( cmData_t* p, const char* vp, unsigned cnt );
@ -324,6 +329,7 @@ extern "C" {
// and copy v[cnt] into it. // and copy v[cnt] into it.
cmData_t* cmDataStrAlloc( cmData_t* parent, cmChar_t* str ); cmData_t* cmDataStrAlloc( cmData_t* parent, cmChar_t* str );
cmData_t* cmDataConstStrAlloc( cmData_t* parent, const cmChar_t* str ); cmData_t* cmDataConstStrAlloc( cmData_t* parent, const cmChar_t* str );
cmData_t* cmDataConstStrAllocN( cmData_t* parent, const cmChar_t* str, unsigned charCnt );
cmData_t* cmDataCharAllocPtr( cmData_t* parent, const char* v, unsigned cnt ); cmData_t* cmDataCharAllocPtr( cmData_t* parent, const char* v, unsigned cnt );
cmData_t* cmDataUCharAllocPtr( cmData_t* parent, const unsigned char* v, unsigned cnt ); cmData_t* cmDataUCharAllocPtr( cmData_t* parent, const unsigned char* v, unsigned cnt );
cmData_t* cmDataShortAllocPtr( cmData_t* parent, const short* v, unsigned cnt ); cmData_t* cmDataShortAllocPtr( cmData_t* parent, const short* v, unsigned cnt );
@ -428,6 +434,7 @@ extern "C" {
cmData_t* cmDataAllocPairId( cmData_t* parent, unsigned keyId, cmData_t* value ); cmData_t* cmDataAllocPairId( cmData_t* parent, unsigned keyId, cmData_t* value );
// Dynamically allocate the label but link (w/o realloc) the value. // Dynamically allocate the label but link (w/o realloc) the value.
cmData_t* cmDataAllocPairLabelN(cmData_t* parent, const cmChar_t* label, unsigned charCnt, cmData_t* value);
cmData_t* cmDataAllocPairLabel( cmData_t* parent, const cmChar_t* label, cmData_t* value ); cmData_t* cmDataAllocPairLabel( cmData_t* parent, const cmChar_t* label, cmData_t* value );
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -487,13 +494,13 @@ extern "C" {
unsigned cmDataRecdKeyId( cmData_t* p, unsigned index ); unsigned cmDataRecdKeyId( cmData_t* p, unsigned index );
const cmChar_t* cmDataRecdKeyLabel( cmData_t* p, unsigned index ); const cmChar_t* cmDataRecdKeyLabel( cmData_t* p, unsigned index );
cmData_t* cmRecdMake( cmData_t* parent, cmData_t* p ); cmData_t* cmDataRecdMake( cmData_t* parent, cmData_t* p );
cmData_t* cmRecdAlloc( cmData_t* parent ); cmData_t* cmDataRecdAlloc( cmData_t* parent );
// Append a pair node by linking the pair node 'pair' to the record node 'p'. // Append a pair node by linking the pair node 'pair' to the record node 'p'.
// 'pair' is simply linked to 'p' via cmDataAppendChild() no // 'pair' is simply linked to 'p' via cmDataAppendChild() no
// reallocation or duplicattion takes place. // reallocation or duplicattion takes place.
cmData_t* cmRecdAppendPair( cmData_t* p, cmData_t* pair ); cmData_t* cmDataRecdAppendPair( cmData_t* p, cmData_t* pair );
// Var-args format: // Var-args format:
@ -529,6 +536,16 @@ extern "C" {
unsigned cmDataSerializeByteCount( const cmData_t* p ); unsigned cmDataSerializeByteCount( const cmData_t* p );
cmDtRC_t cmDataSerialize( const cmData_t* p, void* buf, unsigned bufByteCnt ); cmDtRC_t cmDataSerialize( const cmData_t* p, void* buf, unsigned bufByteCnt );
cmDtRC_t cmDataDeserialize( const void* buf, unsigned bufByteCnt, cmData_t** pp ); cmDtRC_t cmDataDeserialize( const void* buf, unsigned bufByteCnt, cmData_t** pp );
//-----------------------------------------------------------------------------
typedef cmHandle_t cmDataParserH_t;
//static cmDataParserH_t cmDataParserNullHandle;
cmDtRC_t cmDataParserCreate( cmCtx_t* ctx, cmDataParserH_t* hp );
cmDtRC_t cmDataParserDestroy( cmDataParserH_t* hp );
bool cmDataParserIsValid( cmDataParserH_t h );
cmDtRC_t cmDataParserExec( cmDataParserH_t h, const cmChar_t* text, cmData_t** pp );
//-----------------------------------------------------------------------------
void cmDataPrint( const cmData_t* p, cmRpt_t* rpt ); void cmDataPrint( const cmData_t* p, cmRpt_t* rpt );

View File

@ -60,7 +60,11 @@ extern "C" {
// Draw the page. // Draw the page.
void cmGrPageDraw( cmGrPgH_t h, cmGrDcH_t dcH ); void cmGrPageDraw( cmGrPgH_t h, cmGrDcH_t dcH );
// Label callback functions are used to translate numeric axis values to
// text strings. Multiple label callback functions can be registered with
// a page and then assigned to a given view axis via cmGrViewSetLabelFunc().
typedef void (*cmGrLabelFunc_t)( void* arg, cmChar_t* label, unsigned labelCharCnt, cmGrV_t value ); typedef void (*cmGrLabelFunc_t)( void* arg, cmChar_t* label, unsigned labelCharCnt, cmGrV_t value );
// Returns id of the new page label function. // Returns id of the new page label function.
unsigned cmGrPageLabelFuncRegister( cmGrPgH_t h, cmGrLabelFunc_t func, void* arg, const cmChar_t* label ); unsigned cmGrPageLabelFuncRegister( cmGrPgH_t h, cmGrLabelFunc_t func, void* arg, const cmChar_t* label );
unsigned cmGrPageLabelFuncCount( cmGrPgH_t h ); unsigned cmGrPageLabelFuncCount( cmGrPgH_t h );

View File

@ -42,12 +42,15 @@ extern "C" {
const void* cmStackTop( cmStackH_t h ); const void* cmStackTop( cmStackH_t h );
// Set the value of 'dataEleCnt' elements on the stack. // Set the value of 'dataEleCnt' elements on the stack.
// The top element is at index cmStackCount() - 1.
cmStRC_t cmStackSet( cmStackH_t h, unsigned index, const void* data, unsigned dataEleCnt ); cmStRC_t cmStackSet( cmStackH_t h, unsigned index, const void* data, unsigned dataEleCnt );
// Copy 'dataEleCnt' elements into the buffer pointed to by 'data'. // Copy 'dataEleCnt' elements into the buffer pointed to by 'data'.
// The top element is at index cmStackCount() - 1.
cmStRC_t cmStackGetN( cmStackH_t h, unsigned index, void* data, unsigned dataEleCnt ); cmStRC_t cmStackGetN( cmStackH_t h, unsigned index, void* data, unsigned dataEleCnt );
// Return a pointer to a single element on the stack. // Return a pointer to a single element on the stack.
// The top element is at index cmStackCount() - 1.
const void* cmStackGet( cmStackH_t h, unsigned index ); const void* cmStackGet( cmStackH_t h, unsigned index );
// Convert the internal representation of the stack to a linear array and return // Convert the internal representation of the stack to a linear array and return