#include "cmt_model.h"
#include "cmt_fragment.h"
#include "cmt_symbol.h"
/**
* Filters out all predefined XML constructs.
*/
void CmtModel::filter (cmt_string& text)
{
text.replace_all ("", "\t");
text.replace_all ("", "\r");
text.replace_all ("", "\n");
}
void CmtModel::display (cmt_string& text)
{
text.replace_all ("<", "<");
text.replace_all (">", ">");
Symbol::expand (text);
cout << text;
}
void CmtModel::expand (const cmt_string& input_text)
{
int openmarker;
int closemarker;
CmtSystem::cmt_string_vector subargs;
cmt_string text = input_text;
cmt_string remaining;
filter (text);
for (;;)
{
/**
* Look for the next < ... /> pattern
* If not found, then simply dump the text as it is.
*/
openmarker = text.find ("<");
if (openmarker == cmt_string::npos) break;
closemarker = text.find (openmarker, "/>");
if (closemarker == cmt_string::npos) break;
if (CmtSystem::testenv ("CMTTESTMODEL"))
{
cerr << "text=[" << text << "]" << endl;
}
/**
* Extract the command from the pattern
*/
cmt_string command;
text.substr (openmarker + 1, closemarker - openmarker - 1, command);
if (CmtSystem::testenv ("CMTTESTMODEL"))
{
cerr << "command=[" << command << "]" << endl;
}
/**
* Get what is left from the original text beyond the pattern
*/
text.substr (closemarker + 2, remaining);
/**
* Cut the original text up to the pattern start
*/
text.erase (openmarker);
/**
* Now display it
*/
display (text);
/**
* Convert the extracted command into words
*/
CmtSystem::split (command, " ", subargs);
/**
* Recursively expand it
*/
expand (subargs);
/**
* The next iteration will operate on the remaining text
*/
text = remaining;
}
if (CmtSystem::testenv ("CMTTESTMODEL"))
{
cerr << "text=[" << text << "]" << endl;
}
/**
* Display what is left after extracting the last pattern
*/
display (text);
cout << endl;
}
/**
* Expands a model file
* Arguments are :
* model-name : name of a model file
* var=value : variable value to be expanded
* (will take the form ${var} )
*/
void CmtModel::expand (const CmtSystem::cmt_string_vector& arguments)
{
int i;
Variable::VariableVector variables;
/**
* We start by decoding all [variable=value] pairs from the arguments
* A vector of Variables is filled from them.
*/
for (i = 0; i < arguments.size (); i++)
{
const cmt_string& arg = arguments[i];
if (arg.find ("=") != cmt_string::npos)
{
cmt_string name;
cmt_string value;
int pos = arg.find ("=");
arg.substr (0, pos, name);
arg.substr (pos + 1, value);
Variable* v = Variable::find (variables, name);
if (v == 0)
{
v = &(variables.add ());
v->set (name);
}
(*v) = value;
}
}
/**
* Then model names are extracted.
* Each model may contain a set of <...> patterns.
* The expected syntax for each of them is :
*
*
* Therefore the current expand function is recursively restarted.
*
* Text around patterns is displayed after replacements of all
* variable values detected by ${variable-name} patterns
*/
cmt_string text;
for (i = 0; i < arguments.size (); i++)
{
const cmt_string& arg = arguments[i];
if (arg.find ("=") == cmt_string::npos)
{
FragmentHandle fragment (arg);
fragment.copy (text, variables, 0);
filter (text);
int openmarker;
int closemarker;
CmtSystem::cmt_string_vector subargs;
cmt_string remaining;
for (;;)
{
/**
* Look for the next <...> pattern
* If not found, then simply dump the text as it is.
*/
openmarker = text.find ("<");
if (openmarker == cmt_string::npos) break;
closemarker = text.find (openmarker, "/>");
if (closemarker == cmt_string::npos)
{
/**
* The opening < was in the text
*/
/**
* Get what is left from the original text beyond the pattern
*/
text.substr (openmarker + 1, remaining);
text.erase (openmarker + 1);
/**
* Now display it
*/
display (text);
}
else
{
/**
* Extract the command from the pattern
*/
cmt_string command;
text.substr (openmarker + 1, closemarker - openmarker - 1, command);
/**
* Get what is left from the original text beyond the pattern
*/
text.substr (closemarker + 2, remaining);
text.erase (openmarker);
/**
* Now display it
*/
display (text);
/**
* Convert the extracted command into words
*/
CmtSystem::split (command, " ", subargs);
/**
* Recursively expand it
*/
expand (subargs);
}
/**
* The next iteration will operate on the remaining text
*/
text = remaining;
}
/**
* Display what is left after extracting the last pattern
*/
display (text);
}
}
}