Example #1
0
/*
 * JX9_EOL
 *  Expand the correct 'End Of Line' symbol for this platform.
 */
static void JX9_EOL_Const(jx9_value *pVal, void *pUnused)
{
	SXUNUSED(pUnused);
#ifdef __WINNT__
	jx9_value_string(pVal, "\r\n", (int)sizeof("\r\n")-1);
#else
	jx9_value_string(pVal, "\n", (int)sizeof(char));
#endif
}
Example #2
0
/*
 * DIRECTORY_SEPARATOR.
 * Expand the directory separator character.
 */
static void JX9_DIRSEP_Const(jx9_value *pVal, void *pUnused)
{
	SXUNUSED(pUnused);
#ifdef __WINNT__
	jx9_value_string(pVal, "\\", (int)sizeof(char));
#else
	jx9_value_string(pVal, "/", (int)sizeof(char));
#endif
}
Example #3
0
/*
 * __FILE__
 *  Path of the processed script.
 */
static void JX9_FILE_Const(jx9_value *pVal, void *pUserData)
{
	jx9_vm *pVm = (jx9_vm *)pUserData;
	SyString *pFile;
	/* Peek the top entry */
	pFile = (SyString *)SySetPeek(&pVm->aFiles);
	if( pFile == 0 ){
		/* Expand the magic word: ":MEMORY:" */
		jx9_value_string(pVal, ":MEMORY:", (int)sizeof(":MEMORY:")-1);
	}else{
		jx9_value_string(pVal, pFile->zString, pFile->nByte);
	}
}
Example #4
0
/*
 * JX9_OS
 * __OS__
 *  Expand the name of the host Operating System.
 */
static void JX9_OS_Const(jx9_value *pVal, void *pUnused)
{
#if defined(__WINNT__)
	jx9_value_string(pVal, "WinNT", (int)sizeof("WinNT")-1);
#elif defined(__UNIXES__)
	struct utsname sInfo;
	if( uname(&sInfo) != 0 ){
		jx9_value_string(pVal, "Unix", (int)sizeof("Unix")-1);
	}else{
		jx9_value_string(pVal, sInfo.sysname, -1);
	}
#else
	jx9_value_string(pVal,"Host OS", (int)sizeof("Host OS")-1);
#endif
	SXUNUSED(pUnused);
}
Example #5
0
/*
 * __DIR__
 *  Directory holding the processed script.
 */
static void JX9_DIR_Const(jx9_value *pVal, void *pUserData)
{
	jx9_vm *pVm = (jx9_vm *)pUserData;
	SyString *pFile;
	/* Peek the top entry */
	pFile = (SyString *)SySetPeek(&pVm->aFiles);
	if( pFile == 0 ){
		/* Expand the magic word: ":MEMORY:" */
		jx9_value_string(pVal, ":MEMORY:", (int)sizeof(":MEMORY:")-1);
	}else{
		if( pFile->nByte > 0 ){
			const char *zDir;
			int nLen;
			zDir = jx9ExtractDirName(pFile->zString, (int)pFile->nByte, &nLen);
			jx9_value_string(pVal, zDir, nLen);
		}else{
			/* Expand '.' as the current directory*/
			jx9_value_string(pVal, ".", (int)sizeof(char));
		}
	}
}
Example #6
0
/*
 * Dequote [i.e: Resolve all backslash escapes ] a JSON string and store
 * the result in the given jx9_value.
 */
static void VmJsonDequoteString(const SyString *pStr, jx9_value *pWorker)
{
	const char *zIn = pStr->zString;
	const char *zEnd = &pStr->zString[pStr->nByte];
	const char *zCur;
	int c;
	/* Mark the value as a string */
	jx9_value_string(pWorker, "", 0); /* Empty string */
	for(;;){
		zCur = zIn;
		while( zIn < zEnd && zIn[0] != '\\' ){
			zIn++;
		}
		if( zIn > zCur ){
			/* Append chunk verbatim */
			jx9_value_string(pWorker, zCur, (int)(zIn-zCur));
		}
		zIn++;
		if( zIn >= zEnd ){
			/* End of the input reached */
			break;
		}
		c = zIn[0];
		/* Unescape the character */
		switch(c){
		case '"':  jx9_value_string(pWorker, (const char *)&c, (int)sizeof(char)); break;
		case '\\': jx9_value_string(pWorker, (const char *)&c, (int)sizeof(char)); break;
		case 'n':  jx9_value_string(pWorker, "\n", (int)sizeof(char)); break;
		case 'r':  jx9_value_string(pWorker, "\r", (int)sizeof(char)); break;
		case 't':  jx9_value_string(pWorker, "\t", (int)sizeof(char)); break;
		case 'f':  jx9_value_string(pWorker, "\f", (int)sizeof(char)); break;
		default:
			jx9_value_string(pWorker, (const char *)&c, (int)sizeof(char));
			break;
		}
		/* Advance the stream cursor */
		zIn++;
	}
}
Example #7
0
/*
 * DATE_W3C
 *  World Wide Web Consortium (example: 2005-08-15T15:52:01+00:00) 
 */
static void JX9_DATE_W3C_Const(jx9_value *pVal, void *pUserData)
{
	SXUNUSED(pUserData); /* cc warning */
	jx9_value_string(pVal, "Y-m-d\\TH:i:sP", -1/*Compute length automatically*/);
}
Example #8
0
/*
 * DATE_RSS
 *  RSS (Mon, 15 Aug 2005 15:52:01 +0000) 
 */
static void JX9_DATE_RSS_Const(jx9_value *pVal, void *pUserData)
{
	SXUNUSED(pUserData); /* cc warning */
	jx9_value_string(pVal, "D, d M Y H:i:s O", -1/*Compute length automatically*/);
}
Example #9
0
/*
 * DATE_RFC850
 *  RFC 850 (example: Monday, 15-Aug-05 15:52:01 UTC) 
 */
static void JX9_DATE_RFC850_Const(jx9_value *pVal, void *pUserData)
{
	SXUNUSED(pUserData); /* cc warning */
	jx9_value_string(pVal, "l, d-M-y H:i:s T", -1/*Compute length automatically*/);
}
Example #10
0
/*
 * JX9_VERSION
 * __JX9__
 *   Expand the current version of the JX9 engine.
 */
static void JX9_VER_Const(jx9_value *pVal, void *pUnused)
{
	SXUNUSED(pUnused);
	jx9_value_string(pVal, jx9_lib_signature(), -1/*Compute length automatically*/);
}
Example #11
0
/*
 * Returns a jx9_value holding the image of a JSON string. In other word perform a JSON decoding operation.
 * According to wikipedia
 * JSON's basic types are:
 *   Number (double precision floating-point format in JavaScript, generally depends on implementation)
 *   String (double-quoted Unicode, with backslash escaping)
 *   Boolean (true or false)
 *   Array (an ordered sequence of values, comma-separated and enclosed in square brackets; the values
 *    do not need to be of the same type)
 *   Object (an unordered collection of key:value pairs with the ':' character separating the key 
 *     and the value, comma-separated and enclosed in curly braces; the keys must be strings and should
 *     be distinct from each other)
 *   null (empty)
 * Non-significant white space may be added freely around the "structural characters" (i.e. the brackets "[{]}", colon ":" and comma ", ").
 */
static sxi32 VmJsonDecode(
	json_decoder *pDecoder, /* JSON decoder */      
	jx9_value *pArrayKey    /* Key for the decoded array */
	){
	jx9_value *pWorker; /* Worker variable */
	sxi32 rc;
	/* Check if we do not nest to much */
	if( pDecoder->rec_count > 31 ){
		/* Nesting limit reached, abort decoding immediately */
		return SXERR_ABORT;
	}
	if( pDecoder->pIn->nType & (JSON_TK_STR|JSON_TK_ID|JSON_TK_TRUE|JSON_TK_FALSE|JSON_TK_NULL|JSON_TK_NUM) ){
		/* Scalar value */
		pWorker = jx9_context_new_scalar(pDecoder->pCtx);
		if( pWorker == 0 ){
			jx9_context_throw_error(pDecoder->pCtx, JX9_CTX_ERR, "JX9 is running out of memory");
			/* Abort the decoding operation immediately */
			return SXERR_ABORT;
		}
		/* Reflect the JSON image */
		if( pDecoder->pIn->nType & JSON_TK_NULL ){
			/* Nullify the value.*/
			jx9_value_null(pWorker);
		}else if( pDecoder->pIn->nType & (JSON_TK_TRUE|JSON_TK_FALSE) ){
			/* Boolean value */
			jx9_value_bool(pWorker, (pDecoder->pIn->nType & JSON_TK_TRUE) ? 1 : 0 );
		}else if( pDecoder->pIn->nType & JSON_TK_NUM ){
			SyString *pStr = &pDecoder->pIn->sData;
			/* 
			 * Numeric value.
			 * Get a string representation first then try to get a numeric
			 * value.
			 */
			jx9_value_string(pWorker, pStr->zString, (int)pStr->nByte);
			/* Obtain a numeric representation */
			jx9MemObjToNumeric(pWorker);
		}else if( pDecoder->pIn->nType & JSON_TK_ID ){
			SyString *pStr = &pDecoder->pIn->sData;
			jx9_value_string(pWorker, pStr->zString, (int)pStr->nByte);
		}else{
			/* Dequote the string */
			VmJsonDequoteString(&pDecoder->pIn->sData, pWorker);
		}
		/* Invoke the consumer callback */
		rc = pDecoder->xConsumer(pDecoder->pCtx, pArrayKey, pWorker, pDecoder->pUserData);
		if( rc == SXERR_ABORT ){
			return SXERR_ABORT;
		}
		/* All done, advance the stream cursor */
		pDecoder->pIn++;
	}else if( pDecoder->pIn->nType & JSON_TK_OSB /*'[' */) {
		ProcJSONConsumer xOld;
		void *pOld;
		/* Array representation*/
		pDecoder->pIn++;
		/* Create a working array */
		pWorker = jx9_context_new_array(pDecoder->pCtx);
		if( pWorker == 0 ){
			jx9_context_throw_error(pDecoder->pCtx, JX9_CTX_ERR, "JX9 is running out of memory");
			/* Abort the decoding operation immediately */
			return SXERR_ABORT;
		}
		/* Save the old consumer */
		xOld = pDecoder->xConsumer;
		pOld = pDecoder->pUserData;
		/* Set the new consumer */
		pDecoder->xConsumer = VmJsonArrayDecoder;
		pDecoder->pUserData = pWorker;
		/* Decode the array */
		for(;;){
			/* Jump trailing comma. Note that the standard JX9 engine will not let you
			 * do this.
			 */
			while( (pDecoder->pIn < pDecoder->pEnd) && (pDecoder->pIn->nType & JSON_TK_COMMA) ){
				pDecoder->pIn++;
			}
			if( pDecoder->pIn >= pDecoder->pEnd || (pDecoder->pIn->nType & JSON_TK_CSB) /*']'*/ ){
				if( pDecoder->pIn < pDecoder->pEnd ){
					pDecoder->pIn++; /* Jump the trailing ']' */
				}
				break;
			}
			/* Recurse and decode the entry */
			pDecoder->rec_count++;
			rc = VmJsonDecode(pDecoder, 0);
			pDecoder->rec_count--;
			if( rc == SXERR_ABORT ){
				/* Abort processing immediately */
				return SXERR_ABORT;
			}
			/*The cursor is automatically advanced by the VmJsonDecode() function */
			if( (pDecoder->pIn < pDecoder->pEnd) &&
				((pDecoder->pIn->nType & (JSON_TK_CSB/*']'*/|JSON_TK_COMMA/*','*/))==0) ){
					/* Unexpected token, abort immediatley */
					*pDecoder->pErr = SXERR_SYNTAX;
					return SXERR_ABORT;
			}
		}
		/* Restore the old consumer */
		pDecoder->xConsumer = xOld;
		pDecoder->pUserData = pOld;
		/* Invoke the old consumer on the decoded array */
		xOld(pDecoder->pCtx, pArrayKey, pWorker, pOld);
	}else if( pDecoder->pIn->nType & JSON_TK_OCB /*'{' */) {
		ProcJSONConsumer xOld;
		jx9_value *pKey;
		void *pOld;
		/* Object representation*/
		pDecoder->pIn++;
		/* Create a working array */
		pWorker = jx9_context_new_array(pDecoder->pCtx);
		pKey = jx9_context_new_scalar(pDecoder->pCtx);
		if( pWorker == 0 || pKey == 0){
			jx9_context_throw_error(pDecoder->pCtx, JX9_CTX_ERR, "JX9 is running out of memory");
			/* Abort the decoding operation immediately */
			return SXERR_ABORT;
		}
		/* Save the old consumer */
		xOld = pDecoder->xConsumer;
		pOld = pDecoder->pUserData;
		/* Set the new consumer */
		pDecoder->xConsumer = VmJsonArrayDecoder;
		pDecoder->pUserData = pWorker;
		/* Decode the object */
		for(;;){
			/* Jump trailing comma. Note that the standard JX9 engine will not let you
			 * do this.
			 */
			while( (pDecoder->pIn < pDecoder->pEnd) && (pDecoder->pIn->nType & JSON_TK_COMMA) ){
				pDecoder->pIn++;
			}
			if( pDecoder->pIn >= pDecoder->pEnd || (pDecoder->pIn->nType & JSON_TK_CCB) /*'}'*/ ){
				if( pDecoder->pIn < pDecoder->pEnd ){
					pDecoder->pIn++; /* Jump the trailing ']' */
				}
				break;
			}
			if( (pDecoder->pIn->nType & (JSON_TK_ID|JSON_TK_STR)) == 0 || &pDecoder->pIn[1] >= pDecoder->pEnd
				|| (pDecoder->pIn[1].nType & JSON_TK_COLON) == 0){
					/* Syntax error, return immediately */
					*pDecoder->pErr = SXERR_SYNTAX;
					return SXERR_ABORT;
			}
			if( pDecoder->pIn->nType & JSON_TK_ID ){
				SyString *pStr = &pDecoder->pIn->sData;
				jx9_value_string(pKey, pStr->zString, (int)pStr->nByte);
			}else{
				/* Dequote the key */
				VmJsonDequoteString(&pDecoder->pIn->sData, pKey);
			}
			/* Jump the key and the colon */
			pDecoder->pIn += 2; 
			/* Recurse and decode the value */
			pDecoder->rec_count++;
			rc = VmJsonDecode(pDecoder, pKey);
			pDecoder->rec_count--;
			if( rc == SXERR_ABORT ){
				/* Abort processing immediately */
				return SXERR_ABORT;
			}
			/* Reset the internal buffer of the key */
			jx9_value_reset_string_cursor(pKey);
			/*The cursor is automatically advanced by the VmJsonDecode() function */
		}
		/* Restore the old consumer */
		pDecoder->xConsumer = xOld;
		pDecoder->pUserData = pOld;
		/* Invoke the old consumer on the decoded object*/
		xOld(pDecoder->pCtx, pArrayKey, pWorker, pOld);
		/* Release the key */
		jx9_context_release_value(pDecoder->pCtx, pKey);
	}else{
		/* Unexpected token */
		return SXERR_ABORT; /* Abort immediately */
	}
	/* Release the worker variable */
	jx9_context_release_value(pDecoder->pCtx, pWorker);
	return SXRET_OK;
}