#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); } } }