示例#1
0
文件: lib_loader.c 项目: nowl/semblis
bool ll_set_library(LibLoader *ll, char *filename)
{
    LIBRARY_HANDLE handle;

    handle = LIBRARY_OPEN(filename);
    
    if( !handle) {
#ifdef WIN32
        OUTPUT_ERR("problem opening library\n");
#else 
        OUTPUT_ERR("problem opening library: %s\n", dlerror());
#endif
        return false;
    }

    loaded_libs = util_grow_buffer_to_size(loaded_libs,
                                           &loaded_libs_cap,
                                           loaded_libs_size+1,
                                           sizeof(*loaded_libs));

    loaded_libs[loaded_libs_size++] = handle;

    ll->_prev_handle = handle;

    return true;
}
示例#2
0
文件: lib_loader.c 项目: nowl/semblis
bool ll_register_foreign_func(LibLoader *ll,
                              char *lisp_func,
                              char *c_func)
{
    PrimFunc *func;

    func = (PrimFunc *)LIBRARY_GETSYM(ll->_prev_handle, c_func);

#ifndef WIN32
    {
        char *error;

        if((error = dlerror()) != NULL) {
            OUTPUT_ERR("problem finding symbol: %s\n", error);
            return false;
        }
    }
#else
    if(func == NULL) {
        OUTPUT_ERR("problem opening function: %s in library\n", c_func);
        return false;
    }
#endif

    if(strcmp(ll->_mod_name, "None") == 0) {
        /* need to first convert to String */
        String tmp_w[MAX_FUNCTION_LEN];
        mbsrtowcs((wchar_t *)tmp_w,
                  (const char **)&lisp_func,
                  MAX_FUNCTION_LEN,
                  NULL);

        REGISTER_FUNC("foreign", (wchar_t*)tmp_w, func);
    } else {
        char tmp[MAX_FUNCTION_LEN];
        char *tmp_p = tmp;
        String tmp_w[MAX_FUNCTION_LEN];

        snprintf(tmp_p, MAX_FUNCTION_LEN,
                 "%s:%s", ll->_mod_name, lisp_func);

        /* need to first convert to String */
        mbsrtowcs((wchar_t*)tmp_w,
                  (const char **)&tmp_p,
                  MAX_FUNCTION_LEN,
                  NULL);

        REGISTER_FUNC("foreign", (wchar_t*)tmp_w, func);
    }
    
    return true;
}
示例#3
0
/**
 * \brief This function interprets <Aux> Code
 *
 * \param[in]	pCode - Start of code to interpret
 * \return		STATUS_PASS - Test conformance (PASS)
 * 				STATUS_FAIL - Test nonconformance (FAIL)
 */
static
int16_t
interpretAux(P_CODE *pCode)
{
	outputXmlAttrAddCommon(LEVEL_SUMMARY, &pCode->common, A_NAME);
	if (pCode->code.cAux.flip)
	{
		outputXmlAttrAdd(A_FLIP, NC_ON);
	}
	else
	{
		outputXmlAttrAdd(A_FLIP, NC_OFF);
	}
	outputXmlTagCurrent(LEVEL_SUMMARY, P_AUX, outputXmlAttrGet());

	if (vt100_set_auxSwitch(pCode->code.cAux.flip ? NC_ON_VALUE : NC_OFF_VALUE))
	{
		// Aux switch set failed
		OUTPUT_ERR(pCode->common.lineNumber,
				   "interpretAux(): Setting of Aux Switch Failed",
				   vt100_get_errorText(),
				   NULL);
		return(STATUS_FAIL);
	}

	return(STATUS_PASS);
}
示例#4
0
/**
 * \brief This function is the constructor to start the input XML generator
 *
 * \param[in]	inputXml - Path to input file to use
 * \return		STATUS_FAIL - Failed to open input XML file
 * 				STATUS_PASS - Ready to process input XML
 */
int16_t
inputXmlStart(char *inputXml)
{
	s_inputFile = NULL;		// Show nothing open yet

	s_inputXml = inputXml;	// Save file input

	// Prepare the input stream
	if (NULL != s_inputXml)
	{
		// A specific input stream was requested, open it
		if (NULL == (s_inputFile = fopen(inputXml, "r")))
		{
			char	string[OUTPUT_STRING_MAX];
			sprintf(string,
					"Failed to open input file [%s]",
					inputXml);
			OUTPUT_ERR(0, string, strerror(errno), NULL);
			return(STATUS_FAIL);
		}
	}
	else
	{
		s_inputFile = stdin;	// Default to STDIN
		s_inputXml = "stdin";	// For reporting
	}

	return(STATUS_PASS);
}
示例#5
0
/**
 * \brief This function interprets <FPUIInput> Code
 *
 * \param[in]	pCode - Start of code to interpret
 * \return		STATUS_PASS - Test conformance (PASS)
 * 				STATUS_FAIL - Test nonconformance (FAIL)
 */
static
int16_t
interpretFPUII(P_CODE *pCode)
{
	int16_t	status = STATUS_PASS;
	char	file[OUTPUT_STRING_MAX];
	sprintf(file,
			"%s%s",
			configFileGetFPUIIFP(),
			pCode->code.cFPUII.pFile->arg.data.value.pCharValue);

	// Complete FPUII format processing
	outputXmlAttrAddCommon(LEVEL_TRACE,  &pCode->common, A_VAR);
	outputXmlAttrAdd(A_FILE, file);
	outputXmlTagCurrent(LEVEL_TRACE, P_FPUII, outputXmlAttrGet());

	if (vt100_fileToVD(file))
	{
		OUTPUT_ERR(pCode->common.lineNumber,
				   "interpretFPUII(): Could not input VD",
				   vt100_get_errorText(),
				   NULL);
		status = STATUS_FAIL;
	}

	return(status);
}
示例#6
0
/**
 * \brief This function interprets <FIOReponse> Code
 *
 * \param[in]	pCode - Start of code to interpret
 * \return		STATUS_PASS - Test conformance (PASS)
 * 				STATUS_FAIL - Test nonconformance (FAIL)
 */
static
int16_t
interpretFIOR(P_CODE *pCode)
{
	char            file[OUTPUT_STRING_MAX];
	char            frame[OUTPUT_STRING_MAX];
	char            delaystr[OUTPUT_STRING_MAX];
	unsigned char   *pBuf;
	unsigned int    size;
	int		delay = 0;

	sprintf(file, "%s%s", configFileGetFIORFP(),
		pCode->code.cFIOR.pFile->arg.data.value.pCharValue);
	sprintf(frame, "%d", pCode->code.cFIOR.pFrame->arg.data.value.intValue);
	if (pCode->code.cFIOR.pDelay) {
		delay = pCode->code.cFIOR.pDelay->arg.data.value.intValue;
		sprintf(delaystr, "%d", delay);
	}

	// Complete FIOR format processing
	outputXmlAttrAddCommon(LEVEL_TRACE, &pCode->common, A_VAR);
	outputXmlAttrAdd(A_FILE, file);
	outputXmlAttrAdd(A_FRAME, frame);
	if (pCode->code.cFIOR.pDelay) {
		outputXmlAttrAdd(A_DELAY, delaystr);	
	}
	outputXmlTagCurrent(LEVEL_TRACE, P_FIOR, outputXmlAttrGet());

	if (STATUS_FAIL == argSet(pCode->common.lineNumber,
					configFileGetFIORFP(),
					pCode->code.cFIOR.pFile->arg.data.value.pCharValue,
					&pBuf,
					&size))
	{
		return(STATUS_FAIL);
	}

	if (emfio_setResponse(pCode->code.cFIOR.pFrame->arg.data.value.intValue,
				pBuf, (uint32_t)size, (uint32_t)delay) != 0)
	{
		// Could not load response
		char string[OUTPUT_STRING_MAX];
		sprintf(string, "interpretFIOR(): Could not load response frame [%s]",
			frame);
		OUTPUT_ERR(pCode->common.lineNumber, string, emfio_getErrorText(), NULL);
		free(pBuf);
		return(STATUS_FAIL);
	}

	free(pBuf);
	return(STATUS_PASS);
}
示例#7
0
/**
 * \brief This function processes the input APIVSXML file
 *
 * \return		STATUS_FAIL - Parsing of APIVSXML input file failed
 * 				STATUS_PASS - Parsing of APIVSXML input file was successful
 */
int16_t
inputXmlParse()
{
	// See if stream is open
	if (NULL == s_inputFile)
	{
		OUTPUT_ERR(0, "Input stream is not open", NULL, NULL);
		return(STATUS_FAIL);
	}

	// Create the parser object
	XML_Parser	pParser = XML_ParserCreate(NULL);

	// Make sure we were able to allocate parser
	if (NULL == pParser)
	{
		OUTPUT_ERR(0,
				   "Failed to allocate APIVSXML parser",
				   strerror(errno),
				   NULL);
		return(STATUS_FAIL);
	}

	// Set up user data
	XML_SetUserData(pParser, pParser);

	// Set up the Element Handlers
	XML_SetElementHandler(pParser, inputXmlStartElement, inputXmlEndElement);

	// Set up the text handler
	XML_SetCharacterDataHandler(pParser, inputXmlText);

	// Process the APIVSXML input file
	for (;;)
	{
		int16_t	done;		// Flag for EOF
		int16_t	len;		// Number of bytes actually read

		// Read a line of input
		len = fread(s_inputBuffer, 1, INPUT_BUFFER_MAX, s_inputFile);

		// See if read was ok
		if (ferror(s_inputFile))
		{
			OUTPUT_ERR(XML_GetCurrentLineNumber(pParser),
					   "Failed to read from input APIVSXML",
					   strerror(errno),
					   NULL);
			XML_ParserFree(pParser);
			return(STATUS_FAIL);
		}
		done = feof(s_inputFile);	// Save EOF status

		// Now parse the input line
		if (!XML_Parse(pParser, s_inputBuffer, len, done))
		{
			OUTPUT_ERR(XML_GetCurrentLineNumber(pParser),
					   "Parse failed",
					   NULL,
					   XML_ErrorString(XML_GetErrorCode(pParser)));
			XML_ParserFree(pParser);
			return(STATUS_FAIL);
		}

		// See if an error has been reported
		if (STATUS_FAIL == outputXmlStatusGet())
		{
			// Yes, we are done!
			XML_ParserFree(pParser);
			return(STATUS_FAIL);
		}

		// See if EOF
		if (done)
		{
			break;
		}
	}

	// Show we are done
	XML_ParserFree(pParser);
	return (STATUS_PASS);
}
示例#8
0
/**
 * \brief This function interprets <Function> Code
 *
 * \param[in]	pCode - Start of code to interpret
 * \return		STATUS_PASS - Test conformance (PASS)
 * 				STATUS_FAIL - Test nonconformance (FAIL)
 */
static
int16_t
interpretFunction(P_CODE *pCode)
{
	int16_t	status;

	outputXmlAttrAddCommon(LEVEL_SUMMARY, &pCode->common, A_FNAME);
	if (NULL != pCode->code.cFunc.returnValue)
	{
		outputXmlAttrAdd(A_RETURN, pCode->code.cFunc.returnValue->pName);
	}
	if (NULL != pCode->code.cFunc.errnoValue)
	{
		outputXmlAttrAdd(A_ERRNO, pCode->code.cFunc.errnoValue->pName);
	}
	if (NULL != pCode->code.cFunc.arg[0])
	{
		outputXmlAttrAdd(A_P1, pCode->code.cFunc.arg[0]->pName);
	}
	if (NULL != pCode->code.cFunc.arg[1])
	{
		outputXmlAttrAdd(A_P2, pCode->code.cFunc.arg[1]->pName);
	}
	if (NULL != pCode->code.cFunc.arg[2])
	{
		outputXmlAttrAdd(A_P3, pCode->code.cFunc.arg[2]->pName);
	}
	if (NULL != pCode->code.cFunc.arg[3])
	{
		outputXmlAttrAdd(A_P4, pCode->code.cFunc.arg[3]->pName);
	}
	if (NULL != pCode->code.cFunc.arg[4])
	{
		outputXmlAttrAdd(A_P5, pCode->code.cFunc.arg[4]->pName);
	}
	if (NULL != pCode->code.cFunc.arg[5])
	{
		outputXmlAttrAdd(A_P6, pCode->code.cFunc.arg[5]->pName);
	}
	if (NULL != pCode->code.cFunc.arg[6])
	{
		outputXmlAttrAdd(A_P7, pCode->code.cFunc.arg[6]->pName);
	}
	outputXmlTagCurrent(LEVEL_SUMMARY, P_FUNCTION, outputXmlAttrGet());

	// See if there is a function defined
	if (NULL != pCode->code.cFunc.pFunc->pExe)
	{
		status = (*pCode->code.cFunc.pFunc->pExe)(pCode->common.lineNumber,
												  &pCode->code.cFunc);
	}
	else
	{
		// No function defined
		char	string[OUTPUT_STRING_MAX];
		sprintf(string,
				"interpretFunction(): No function defined for [%s]",
				pCode->code.cFunc.pFunc->pName);
		OUTPUT_ERR(pCode->common.lineNumber, string, NULL, NULL);
		status = STATUS_FAIL;
	}

	return(status);
}
示例#9
0
/**
 * \brief This function interprets <Signal> Code
 *
 * \param[in]	pCode - Start of code to interpret
 * \return		STATUS_PASS - Test conformance (PASS)
 * 				STATUS_FAIL - Test nonconformance (FAIL)
 */
static
int16_t
interpretSignal(P_CODE *pCode)
{
	int		signalNum;
	P_CODE	*pCodeSH;

	signalNum = pCode->code.cSig.pSignal->arg.data.value.intValue;

	outputXmlAttrAddCommon(LEVEL_SUMMARY, &pCode->common, A_REF);
	outputXmlAttrAdd(A_SIG, pCode->code.cSig.pSignal->pName);
	if (pCode->code.cSig.enable)
	{
		outputXmlAttrAdd(A_ACTION, VALUE_ENABLE);
	}
	else
	{
		outputXmlAttrAdd(A_ACTION, VALUE_DISABLE);
	}
	outputXmlTagCurrent(LEVEL_SUMMARY, P_SIG, outputXmlAttrGet());

	if ((signalNum < 0) || (signalNum > SIGNAL_MAX))
	{
		// Illegal signal, just to be safe
		char	string[OUTPUT_STRING_MAX];
		sprintf(string,
				"interpretSignal(): Illegal signal [%d]",
				signalNum);
		OUTPUT_ERR(pCode->common.lineNumber, string, strerror(errno), NULL);
		return(STATUS_FAIL);
	}

	if (pCode->code.cSig.enable)
	{
		pCodeSH = pCode->code.cSig.pSH->pCode;
		if (NULL == pCodeSH)
		{
			// Illegal pCode, just to be safe
			char	string[OUTPUT_STRING_MAX];
			sprintf(string,
					"interpretSignal(): Illegal pCode for signal [%d]",
					signalNum);
			OUTPUT_ERR(pCode->common.lineNumber, string, strerror(errno), NULL);
			return(STATUS_FAIL);
		}

		s_signalPcode[signalNum] = pCodeSH;
		if (SIG_ERR == signal(signalNum, interpretSigHandler))
		{
			// Signal Handler error
			char	string[OUTPUT_STRING_MAX];
			sprintf(string,
					"interpretSignal(): Error setting up signal handler for signal [%d]",
					signalNum);
			OUTPUT_ERR(pCode->common.lineNumber, string, strerror(errno), NULL);
			return(STATUS_FAIL);
		}
	}
	else
	{
		s_signalPcode[signalNum] = NULL;
		if (SIG_ERR == signal(signalNum, SIG_IGN))
		{
			// Signal Handler error
			char	string[OUTPUT_STRING_MAX];
			sprintf(string,
					"interpretSignal(): Error ignoring signal [%d]",
					signalNum);
			OUTPUT_ERR(pCode->common.lineNumber, string, strerror(errno), NULL);
			return(STATUS_FAIL);
		}
	}

	return(STATUS_PASS);
}
示例#10
0
/**
 * \brief This function interprets <Load> Code
 *
 * \param[in]	pCode - Start of code to interpret
 * \return		STATUS_PASS - Test conformance (PASS)
 * 				STATUS_FAIL - Test nonconformance (FAIL)
 */
static
int16_t
interpretLoad(P_CODE *pCode)
{
	int16_t	status = STATUS_PASS;
	char	frame[OUTPUT_STRING_MAX];

	if (pCode->code.cLoad.pFrame)
	{
		sprintf(frame, "%d", pCode->code.cLoad.pFrame->arg.data.value.intValue);
	}

	// Complete LOAD format processing
	outputXmlAttrAddCommon(LEVEL_SUMMARY, &pCode->common, A_FILE);
	outputXmlAttrAdd(A_LOAD, s_dumpType_string[pCode->code.cLoad.type]);
	if (pCode->code.cLoad.pFrame)
	{
		outputXmlAttrAdd(A_FRAME, frame);
	}
	outputXmlTagOpen(LEVEL_SUMMARY, P_LOAD, outputXmlAttrGet());

	switch (pCode->code.cLoad.type)
	{
		case DUMP_VD:
		{
			char	file[OUTPUT_STRING_MAX];
			sprintf(file,
					"%s%s",
					configFileGetFPUIDFP(),
					pCode->code.cLoad.pFile->arg.data.value.pCharValue);
			if (vt100_fromDumpToVD(file))
			{
				OUTPUT_ERR(pCode->common.lineNumber,
						   "interpretLoad(): Could not load VD",
						   vt100_get_errorText(),
						   NULL);
				status = STATUS_FAIL;
			}
		}
		break;

		case DUMP_CMDMSG:
		{
			unsigned char	*pBuf;
			unsigned int	size;

			if (STATUS_FAIL == argSet(pCode->common.lineNumber,
									  configFileGetFIODFP(),
									  pCode->code.cLoad.pFile->arg.data.value.pCharValue,
									  &pBuf,
									  &size))
			{
				status = STATUS_FAIL;
				break;
			}

			if (emfio_loadCommand(
						pCode->code.cLoad.pFrame->arg.data.value.intValue,
						pBuf,
						(uint32_t)size))
			{
				OUTPUT_ERR(pCode->common.lineNumber,
						   "interpretLoad(): Could not load CMD",
						   emfio_getErrorText(),
						   NULL);
				status = STATUS_FAIL;
				free(pBuf);
			}
		}
		break;

		default:
		{
			OUTPUT_ERR(pCode->common.lineNumber,
					   "interpretLoad(): Unknown load type requested",
					   NULL,
					   NULL);
			status = STATUS_FAIL;
		}
		break;
	}

	outputXmlTagClose(LEVEL_SUMMARY, P_LOAD);

	return(status);
}
示例#11
0
/**
 * \brief This function interprets <Dump> Code
 *
 * \param[in]	pCode - Start of code to interpret
 * \return		STATUS_PASS - Test conformance (PASS)
 * 				STATUS_FAIL - Test nonconformance (FAIL)
 */
static
int16_t
interpretDump(P_CODE *pCode)
{
	int16_t	status = STATUS_PASS;

	// Complete DUMP format processing
	if (   outputXmlShouldPrint(pCode->code.cDump.level)
		&& (   (pCode->code.cDump.force == TRUE)
			|| (s_validateCapture == CAPTURE_MODE)))
	{
		outputXmlAttrAddCommon(pCode->code.cDump.level, &pCode->common, A_FILE);
		outputXmlAttrAdd(A_DUMP, s_dumpType_string[pCode->code.cDump.type]);
		if (pCode->code.cDump.force)
		{
			outputXmlAttrAdd(A_FORCE, NC_TRUE);
		}
		outputXmlTagOpen(pCode->code.cDump.level, P_DUMP, outputXmlAttrGet());

		switch (pCode->code.cDump.type)
		{
			case DUMP_VD:
			{
				char	file[OUTPUT_STRING_MAX];
				int		sequence = 0;

				sprintf(file,
						"%s%s",
						configFileGetFPUIDFP(),
						pCode->code.cDump.pFile->arg.data.value.pCharValue);
				if (pCode->code.cDump.pSeq)
				{
					if (STATUS_FAIL ==
							(status = argCastInt(pCode->common.lineNumber,
												 pCode->code.cDump.pSeq,
												 &sequence)))
					{
						break;
					}
				}
				if (vt100_dumpVD(file,
								 (uint16_t)sequence,
								 pCode->common.pDesc))
				{
					OUTPUT_ERR(pCode->common.lineNumber,
							   "interpretDump(): Could not dump VD, error [%s]",
							   vt100_get_errorText(),
							   NULL);
					status = STATUS_FAIL;
				}
				else
				{
					outputXmlShowVD(pCode->common.pDesc);
				}
			}
			break;

			case DUMP_CMDMSG:
			{
				char	file[OUTPUT_STRING_MAX];
				int		frame;

				sprintf(file,
						"%s%s",
						configFileGetFIODFP(),
						pCode->code.cDump.pFile->arg.data.value.pCharValue);
				if (STATUS_FAIL ==
							(status = argCastInt(pCode->common.lineNumber,
												 pCode->code.cDump.pFrame,
												 &frame)))
				{
					break;
				}
				if (emfio_dumpCommand(frame, file))
				{
					// Dump failed
					char	string[OUTPUT_STRING_MAX];
					sprintf(string,
							"interpretDump(): Could not dump CMD [%d]",
							frame);
					OUTPUT_ERR(pCode->common.lineNumber,
							   string,
							   emfio_getErrorText(),
							   NULL);
					status = STATUS_FAIL;
				}
				else
				{
					outputXmlShowCMD(frame);
				}
			}
			break;

			default:
			{
				// Unknown dump type
				char	string[OUTPUT_STRING_MAX];
				sprintf(string,
						"interpretDump(): Unknown dump type [%d] requested",
						pCode->code.cDump.type);
				OUTPUT_ERR(pCode->common.lineNumber, string, NULL, NULL);
				status = STATUS_FAIL;
			}
			break;
		}

		outputXmlTagClose(pCode->code.cDump.level, P_DUMP);
	}

	return(status);
}
示例#12
0
/**
 * \brief This function interprets APIVSXML for the passed Test Suite
 *
 * \param[in]	pTS - A Specific Test Suite to interpret
 * \return		STATUS_PASS - Test conformance (PASS)
 * 				STATUS_FAIL - Test nonconformance (FAIL)
 */
int16_t
interpretTS(P_TS *pTS)
{
	char msg[OUTPUT_STRING_MAX];
	int16_t	status;
	
	P_TC	*pTC;

	// Interpret Test Suite
	
	// Start the Output XML Generator
	outputXmlAttrAddCommon(LEVEL_SUMMARY, &pTS->common, A_NAME);
	outputXmlTagOpen(LEVEL_SUMMARY, P_TESTSUITE, outputXmlAttrGet());

	if (strcmp(configFileGetFPUILBDEV(), "NULL")
		&& (0 != vt100_start(configFileGetFPUILBDEV(),
					configFileGetSH(),
					configFileGetSW())))
	{
		// vt100_start failed
		sprintf(msg,
				"interpretTS(): VT100 Virtual Display error starting device [%s]",
				configFileGetFPUILBDEV());
		OUTPUT_ERR(pTS->common.lineNumber,
				   msg,
				   vt100_get_errorText(),
				   NULL);
		return(STATUS_FAIL);
	}

	if (strcmp(configFileGetFIOLBDEV(), "NULL")
		&& (EMFIO_OK != emfio_start(configFileGetFIOLBDEV())))
	{
		// emfio_start failed
		sprintf(msg,
				"interpretTS(): FIO Emulator start error starting device [%s]",
				configFileGetFIOLBDEV());
		OUTPUT_ERR(pTS->common.lineNumber,
				   msg,
				   emfio_getErrorText(),
				   NULL);
		return(STATUS_FAIL);
	}

	// Lower relative priority after thread startup
	errno = 0;
	int prio = getpriority(PRIO_PROCESS, 0);
	if (errno == 0) {
		setpriority(PRIO_PROCESS, 0, prio+1);
	}
	
	if (STATUS_PASS == (status = interpretSetUp(pTS->pSU)))
	{
		pTC = pTS->pTC;			// First TC
		while (NULL != pTC)
		{
			outputXmlNewLine(LEVEL_SUMMARY);

			status = interpretTC(pTC);

			outputXmlNewLine(LEVEL_SUMMARY);

			if (STATUS_FAIL == status)
			{
				break;
			}

			pTC = pTC->pTC;		// Next Test Case
		}

		if (STATUS_PASS == status)
		{
			status = interpretTearDown(pTS->pTD);
		}
	}

	if (strcmp(configFileGetFPUILBDEV(), "NULL") && configFileGetFPUILBDEV())
	{
		vt100_end();
	}

	if (strcmp(configFileGetFIOLBDEV(), "NULL") && configFileGetFIOLBDEV())
	{
		emfio_end();
	}

	// Output final closing element tag
	outputXmlTagClose(LEVEL_SUMMARY, P_TESTSUITE);

	return(status);
}
示例#13
0
/**
 * \brief This function interprets APIVSXML Code
 *
 * \param[in]	pCode - Start of code to interpret
 * \return		STATUS_PASS - Test conformance (PASS)
 * 				STATUS_FAIL - Test nonconformance (FAIL)
 */
int16_t
interpretPcode(P_CODE *pCode)
{
	int16_t	status = STATUS_PASS;
	boolean	done = FALSE;

	// Execute the pCode
	while (NULL != pCode)
	{
		// Execute current statment
		switch (pCode->type)
		{
			case PC_E_PRINT:
			{
				status = interpretPrint(pCode);
			}
			break;

			case PC_E_SET:
			{
				status = interpretSet(pCode);
			}
			break;

			case PC_E_FUNC:
			{
				status = interpretFunction(pCode);
			}
			break;

			case PC_E_IF:
			{
				status = interpretIf(pCode);
			}
			break;

			case PC_E_WHILE:
			{
				status = interpretWhile(pCode);
			}
			break;

			case PC_E_THEN:
			{
				outputXmlAttrAddCommon(LEVEL_TRACE, &pCode->common, A_NAME);
				outputXmlTagOpen(LEVEL_TRACE, P_THEN, outputXmlAttrGet());

				status = interpretPcode(pCode->pCode);

				outputXmlTagClose(LEVEL_TRACE, P_THEN);

				// Note done with this tree branch
				done = TRUE;
			}
			break;

			case PC_E_ELSE:
			{
				outputXmlAttrAddCommon(LEVEL_TRACE, &pCode->common, A_NAME);
				outputXmlTagOpen(LEVEL_TRACE, P_ELSE, outputXmlAttrGet());

				status = interpretPcode(pCode->pCode);

				outputXmlTagClose(LEVEL_TRACE, P_ELSE);

				// Note done with this tree branch
				done = TRUE;
			}
			break;

			case PC_E_CALL:
			{
				status = interpretCall(pCode);
			}
			break;

			case PC_E_SIG:
			{
				status = interpretSignal(pCode);
			}
			break;

			case PC_E_AUX:
			{
				status = interpretAux(pCode);
			}
			break;

			case PC_E_ABORT:
			{
				status = interpretAbort(pCode);
			}
			break;

			case PC_E_DUMP:
			{
				status = interpretDump(pCode);
			}
			break;

			case PC_E_LOAD:
			{
				status = interpretLoad(pCode);
			}
			break;

			case PC_E_FORMAT:
			{
				status = interpretFormat(pCode);
			}
			break;

			case PC_E_SLEEP:
			{
				status = interpretSleep(pCode);
			}
			break;

			case PC_E_FPUII:
			{
				status = interpretFPUII(pCode);
			}
			break;

			case PC_E_FIOR:
			{
				status = interpretFIOR(pCode);
			}
			break;

			default:
			{
				char	string[OUTPUT_STRING_MAX];

				sprintf(string,
						"Unknown P_CODE type[%d]",
						pCode->type);
				OUTPUT_ERR(pCode->common.lineNumber,
			   			   string,
						   NULL,
						   pCode->common.pDesc);
				status = STATUS_FAIL;
			}
			break;
		}

		if ( done || (/*(pCode->type == PC_E_ABORT) &&*/ (STATUS_FAIL == status)) )
		{
			break;		// We failed or we are done
		}

		// Move to next P_CODE
		pCode = pCode->pCode;
	}

	return(status);
}