/* * Free an expression tree. */ static void ExprFreeTree(jx9_gen_state *pGen, jx9_expr_node *pNode) { if( pNode->pLeft ){ /* Release the left tree */ ExprFreeTree(&(*pGen), pNode->pLeft); } if( pNode->pRight ){ /* Release the right tree */ ExprFreeTree(&(*pGen), pNode->pRight); } if( pNode->pCond ){ /* Release the conditional tree used by the ternary operator */ ExprFreeTree(&(*pGen), pNode->pCond); } if( SySetUsed(&pNode->aNodeArgs) > 0 ){ jx9_expr_node **apArg; sxu32 n; /* Release node arguments */ apArg = (jx9_expr_node **)SySetBasePtr(&pNode->aNodeArgs); for( n = 0 ; n < SySetUsed(&pNode->aNodeArgs) ; ++n ){ ExprFreeTree(&(*pGen), apArg[n]); } SySetRelease(&pNode->aNodeArgs); } /* Finally, release this node */ SyMemBackendPoolFree(&pGen->pVm->sAllocator, pNode); }
/* * Exported JSON decoding interface */ JX9_PRIVATE int jx9JsonDecode(jx9_context *pCtx,const char *zJSON,int nByte) { jx9_vm *pVm = pCtx->pVm; json_decoder sDecoder; SySet sToken; SyLex sLex; sxi32 rc; /* Tokenize the input */ SySetInit(&sToken, &pVm->sAllocator, sizeof(SyToken)); rc = SXRET_OK; SyLexInit(&sLex, &sToken, VmJsonTokenize, &rc); SyLexTokenizeInput(&sLex,zJSON,(sxu32)nByte, 0, 0, 0); if( rc != SXRET_OK ){ /* Something goes wrong while tokenizing input. [i.e: Unexpected token] */ SyLexRelease(&sLex); SySetRelease(&sToken); /* return NULL */ jx9_result_null(pCtx); return JX9_OK; } /* Fill the decoder */ sDecoder.pCtx = pCtx; sDecoder.pErr = &rc; sDecoder.pIn = (SyToken *)SySetBasePtr(&sToken); sDecoder.pEnd = &sDecoder.pIn[SySetUsed(&sToken)]; sDecoder.iFlags = 0; sDecoder.rec_count = 0; /* Set a default consumer */ sDecoder.xConsumer = VmJsonDefaultDecoder; sDecoder.pUserData = 0; /* Decode the raw JSON input */ rc = VmJsonDecode(&sDecoder, 0); if( rc == SXERR_ABORT ){ /* * Something goes wrong while decoding JSON input.Return NULL. */ jx9_result_null(pCtx); } /* Clean-up the mess left behind */ SyLexRelease(&sLex); SySetRelease(&sToken); /* All done */ return JX9_OK; }