FunctionsParser.cc 5.31 KB
/*
 * FunctionsParser.cc
 *
 *  Created on: Mar 19, 2019
 *      Author: AKKA
 */

#include "NodeCfg.hh"
#include "AMDA_exception.hh"
#include "FunctionsParser.hh"
#include "ParserLogger.hh"

#include <boost/lexical_cast.hpp>

using namespace AMDA::XMLConfigurator;

namespace AMDA {
namespace parser {

///////////////////////////////////////////////////////////////////////////////
/*
 * @brief info_brief node
 */
class InfoBriefNode : public NodeCfg
{
public:
	void proceed(xmlNodePtr /*pNode*/,const AMDA::Parameters::CfgContext& /*pContext*/) {
		//Not used
	}
};

///////////////////////////////////////////////////////////////////////////////
/*
 * @brief prompt node
 */
class PromptNode : public NodeCfg
{
public:
	void proceed(xmlNodePtr pNode,const AMDA::Parameters::CfgContext& pContext) {
		if ((pNode->children != NULL) && (pNode->children->content != NULL)) {
			FunctionInfo *pFunctionInfo =  pContext.get<FunctionInfo *>();
			pFunctionInfo->setNbPromptedArgs(pFunctionInfo->getNbPromptedArgs()+1);
		}
	}
};

///////////////////////////////////////////////////////////////////////////////
/*
 * @brief prompts node
 */
class PromptsNode : public NodeGrpCfg {
public:

	PromptsNode () : NodeGrpCfg() {
		getChildList()["prompt"] = NodeCfgSPtr(new PromptNode);
	}

	void proceed(xmlNodePtr pNode, const AMDA::Parameters::CfgContext& pContext) {
		LOG4CXX_INFO(gLogger, "PromptsNode::proceed");

                // Proceed nodes
                NodeGrpCfg::proceed(pNode, pContext);
	}
};

///////////////////////////////////////////////////////////////////////////////
/*
 * @brief prompt node
 */
class PromptParamNode : public NodeCfg
{
public:
	void proceed(xmlNodePtr /*pNode*/,const AMDA::Parameters::CfgContext& /*pContext*/) {
		//Nothing to do
	}
};

///////////////////////////////////////////////////////////////////////////////
/*
 * @brief default_args node
 */
class DefaultArgsNode : public NodeCfg
{
public:
	void proceed(xmlNodePtr /*pNode*/,const AMDA::Parameters::CfgContext& /*pContext*/) {
		//Nothing to do
	}
};

///////////////////////////////////////////////////////////////////////////////
/*
 * @brief new_kernel node
 */
class NewKernelNode : public NodeCfg
{
public:
	void proceed(xmlNodePtr pNode,const AMDA::Parameters::CfgContext& pContext) {
		if ((pNode->children != NULL) && (pNode->children->content != NULL)) {
			FunctionInfo *pFunctionInfo =  pContext.get<FunctionInfo *>();
			pFunctionInfo->setKernelName(std::string((char*)pNode->children->content));
		}
	}
};

///////////////////////////////////////////////////////////////////////////////
/*
 * @brief function node
 */
class FunctionNode : public NodeGrpCfg
{
public:

	FunctionNode () : NodeGrpCfg() {
		getChildList()["prompts"] = RootNodeCfgSPtr(new PromptsNode);
                getChildList()["prompt_param"] = NodeCfgSPtr(new PromptParamNode);
		getChildList()["default_args"] = NodeCfgSPtr(new DefaultArgsNode);
		getChildList()["info_brief"] = NodeCfgSPtr(new InfoBriefNode);
		getChildList()["new_kernel"] = NodeCfgSPtr(new NewKernelNode);
	}

	void proceed(xmlNodePtr pNode,const AMDA::Parameters::CfgContext& pContext) {
		//Get name
		xmlChar* value = xmlGetProp(pNode, (const xmlChar *) "name");
		std::string name;
		if (value != NULL)
		{
			name = (char *)value;
			xmlFree(value);
			size_t lastindex = name.find_last_of("(");
			name = name.substr(0, lastindex);
		}

		if (!name.empty()) {
			AMDA::Parameters::CfgContext ctx;
			FunctionInfo functionInfo;
			ctx.push<FunctionInfo *>(&functionInfo);

			functionInfo.setIHMName(name);
			//Get args
			value = xmlGetProp(pNode, (const xmlChar *) "args");
			int nbArgs = 1;
			if (value != NULL)
			{
				nbArgs = boost::lexical_cast<int>(std::string((char*)value));
				functionInfo.setNbArgs(nbArgs);
			}

			//kind attribute  not used

			// Proceed nodes
			NodeGrpCfg::proceed(pNode, ctx);

			//Add function in map
			FunctionInfoMap *pFunctionsMap =  pContext.get<FunctionInfoMap *>();
			(*pFunctionsMap)[name] = functionInfo;
		}
	}
};

///////////////////////////////////////////////////////////////////////////////
/*
 * @brief functions node
 */
class FunctionsNode : public NodeGrpCfg {
public:

	FunctionsNode () : NodeGrpCfg() {
		getChildList()["function"] = NodeCfgSPtr(new FunctionNode);
	}

	void proceed(xmlNodePtr pNode, const AMDA::Parameters::CfgContext& pContext) {
		LOG4CXX_INFO(gLogger, "FunctionsNode::proceed");

		// Proceed nodes
		NodeGrpCfg::proceed(pNode, pContext);
	}
};

///////////////////////////////////////////////////////////////////////////////
/*
 * @brief functions node parser
 */
FunctionsParser::FunctionsParser (const char* pXSDFile) : XMLConfigurator(pXSDFile,true)
{

	// functions root node
	getXmlConfiguratorMap()["functions"] = RootNodeCfgSPtr(new FunctionsNode ());
}

FunctionInfoMap FunctionsParser::parse (const std::string& functionsFile) {
	LOG4CXX_INFO(gLogger, "FunctionsParser::parse parsing " << functionsFile);

	AMDA::Parameters::CfgContext ctx;
	FunctionInfoMap functionsMap;
	ctx.push<FunctionInfoMap *>(&functionsMap);

	// Check schema validity and parse xml file
	try {
		if (!XMLConfigurator::proceed(functionsFile.c_str(), ctx, true)) {
			return functionsMap;
		}
	}
	catch (...) {
		LOG4CXX_INFO(gLogger, "FunctionsParser::parse error while parsing file " << functionsFile);
		return functionsMap;
	}
	return functionsMap;
}

} /* namespace parser */
} /* namespace AMDA */