Merging 'de' libcm into 'cmtest' libcm
This commit is contained in:
commit
ead258c822
677
cmData.c
677
cmData.c
@ -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);
|
||||||
@ -1459,6 +1478,15 @@ cmData_t* cmDataAllocPairLabel( cmData_t* parent, const cmChar_t *label, cmData_
|
|||||||
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
unsigned cmDataListCount(const cmData_t* p )
|
unsigned cmDataListCount(const cmData_t* 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,
|
||||||
|
27
cmData.h
27
cmData.h
@ -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:
|
||||||
@ -530,6 +537,16 @@ extern "C" {
|
|||||||
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 );
|
||||||
|
|
||||||
void cmDataTest( cmCtx_t* ctx );
|
void cmDataTest( cmCtx_t* ctx );
|
||||||
|
@ -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 );
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user