Click here to Skip to main content
15,892,927 members
Articles / Programming Languages / C#

An extensible math expression parser with plug-ins

Rate me:
Please Sign up or sign in to vote.
4.92/5 (147 votes)
13 Mar 2008CPOL51 min read 1.4M   29K   364  
Design and code for an extensible, maintainable, robust, and easy to use math parser.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>MTParserLib: MTParserRegistrar.cpp Source File</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.4.4 -->
<div class="qindex"><a class="qindex" href="main.html">Main&nbsp;Page</a> | <a class="qindex" href="namespaces.html">Namespace List</a> | <a class="qindex" href="hierarchy.html">Class&nbsp;Hierarchy</a> | <a class="qindex" href="annotated.html">Class&nbsp;List</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="namespacemembers.html">Namespace&nbsp;Members</a> | <a class="qindex" href="functions.html">Class&nbsp;Members</a> | <a class="qindex" href="globals.html">File&nbsp;Members</a></div>
<h1>MTParserRegistrar.cpp</h1><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 <span class="preprocessor">#include "<a class="code" href="MTParserRegistrar_8h.html">MTParserRegistrar.h</a>"</span>
<a name="l00002"></a>00002 <span class="preprocessor">#include "<a class="code" href="MTTools_8h.html">MTTools.h</a>"</span>
<a name="l00003"></a>00003 <span class="preprocessor">#include "<a class="code" href="MTParser_8h.html">MTParser.h</a>"</span>
<a name="l00004"></a>00004 <span class="preprocessor">#include &lt;windows.h&gt;</span>
<a name="l00005"></a>00005 <span class="preprocessor">#include &lt;assert.h&gt;</span>
<a name="l00006"></a>00006 
<a name="l00007"></a>00007 <span class="comment">/*************************************************</span>
<a name="l00008"></a>00008 <span class="comment"></span>
<a name="l00009"></a>00009 <span class="comment">  Steps to add a new item type:</span>
<a name="l00010"></a>00010 <span class="comment"></span>
<a name="l00011"></a>00011 <span class="comment">  1) create a defineXXX method</span>
<a name="l00012"></a>00012 <span class="comment">  2) create a getNbDefinedXXX method</span>
<a name="l00013"></a>00013 <span class="comment">  3) create a getXXX method</span>
<a name="l00014"></a>00014 <span class="comment">  4) modify the spawn method</span>
<a name="l00015"></a>00015 <span class="comment">  5) modify the destructor</span>
<a name="l00016"></a>00016 <span class="comment"></span>
<a name="l00017"></a>00017 <span class="comment">  *It is important not to remove items once defined.  Items can be undefined all at once</span>
<a name="l00018"></a>00018 <span class="comment">  but not individually since internal ids would not be updated.  Only variables can be</span>
<a name="l00019"></a>00019 <span class="comment">  undefined since their ids (keys) are updated.</span>
<a name="l00020"></a>00020 <span class="comment"></span>
<a name="l00021"></a>00021 <span class="comment">*************************************************/</span>
<a name="l00022"></a>00022 <span class="comment"></span>
<a name="l00023"></a>00023 <span class="comment">//! The type library file needing to be registered in order to instanciate plug-ins</span>
<a name="l00024"></a>00024 <span class="comment"></span><span class="preprocessor">#define MTPLUGIN_TYPELIBFILE    _T("_MTParserPlugin.tlb")</span>
<a name="l00025"></a>00025 <span class="preprocessor"></span>
<a name="l00026"></a>00026 
<a name="l00027"></a><a class="code" href="classMTParserRegistrar.html#a33">00027</a> <a class="code" href="classMTParserRegistrar.html#a33">MTParserRegistrar::MTParserRegistrar</a>()
<a name="l00028"></a>00028 {       
<a name="l00029"></a>00029         m_pVarFactory = NULL;
<a name="l00030"></a>00030         m_varKeyVersion = 0;    
<a name="l00031"></a>00031 }
<a name="l00032"></a>00032 
<a name="l00033"></a><a class="code" href="classMTParserRegistrar.html#a32">00033</a> <a class="code" href="classMTRegistrarI.html">MTRegistrarI</a>* <a class="code" href="classMTParserRegistrar.html#a32">MTParserRegistrar::spawn</a>() throw(<a class="code" href="classMTChainedExceptions.html">MTParserException</a>)
<a name="l00034"></a>00034 {
<a name="l00035"></a>00035         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> t;
<a name="l00036"></a>00036         
<a name="l00037"></a>00037         <a class="code" href="classMTParserRegistrar.html">MTParserRegistrar</a> *pObj = <span class="keyword">new</span> <a class="code" href="classMTParserRegistrar.html">MTParserRegistrar</a>;
<a name="l00038"></a>00038 
<a name="l00039"></a>00039         <span class="comment">// define syntax...</span>
<a name="l00040"></a>00040         pObj-&gt;<a class="code" href="classMTParserRegistrar.html#a0">setSyntax</a>(<a class="code" href="classMTParserRegistrar.html#a1">getSyntax</a>());   
<a name="l00041"></a>00041 
<a name="l00042"></a>00042         <span class="comment">// Use the registerX methods instead of the defineX methods to</span>
<a name="l00043"></a>00043         <span class="comment">// avoid doing validations again</span>
<a name="l00044"></a>00044 
<a name="l00045"></a>00045         <span class="comment">// define variables...</span>
<a name="l00046"></a>00046         pObj-&gt;<a class="code" href="classMTParserRegistrar.html#a22">setVarFactory</a>(m_pVarFactory-&gt;<a class="code" href="classMTVariableFactoryI.html#a1">spawn</a>());
<a name="l00047"></a>00047         
<a name="l00048"></a>00048         pObj-&gt;<a class="code" href="classMTParserRegistrar.html#r5">m_variableList</a>.reserve(m_variableList.size());
<a name="l00049"></a>00049         TVariableMap::iterator it = m_variableMap.begin();      
<a name="l00050"></a>00050         <span class="keywordflow">for</span>( t=0; t&lt;m_variableMap.size(); t++ )
<a name="l00051"></a>00051         {
<a name="l00052"></a>00052                 pObj-&gt;<a class="code" href="classMTParserRegistrar.html#d3">registerVar</a>((*it).second-&gt;pVar-&gt;spawn());
<a name="l00053"></a>00053                 it++;
<a name="l00054"></a>00054         }
<a name="l00055"></a>00055 
<a name="l00056"></a>00056 <span class="preprocessor">#ifdef _MTPARSER_USE_PLUGIN</span>
<a name="l00057"></a>00057 <span class="preprocessor"></span>        <span class="comment">// Copy plug-in references...</span>
<a name="l00058"></a>00058         pObj-&gt;<a class="code" href="classMTParserRegistrar.html#r11">m_pluginPtr</a> = m_pluginPtr;
<a name="l00059"></a>00059 <span class="preprocessor">#endif</span>
<a name="l00060"></a>00060 <span class="preprocessor"></span>
<a name="l00061"></a>00061         <span class="comment">// define constants...</span>
<a name="l00062"></a>00062         pObj-&gt;<a class="code" href="classMTParserRegistrar.html#r7">m_constList</a> = m_constList;        
<a name="l00063"></a>00063         pObj-&gt;<a class="code" href="classMTParserRegistrar.html#r6">m_constMap</a> = m_constMap;
<a name="l00064"></a>00064         
<a name="l00065"></a>00065         <span class="comment">// define operators...</span>
<a name="l00066"></a>00066         pObj-&gt;<a class="code" href="classMTParserRegistrar.html#r1">m_opList</a>.reserve( <a class="code" href="classMTParserRegistrar.html#a15">getNbDefinedOps</a>() );    
<a name="l00067"></a>00067         <span class="keywordflow">for</span>( t=0; t&lt;<a class="code" href="classMTParserRegistrar.html#a15">getNbDefinedOps</a>(); t++ )
<a name="l00068"></a>00068         {
<a name="l00069"></a>00069                 pObj-&gt;<a class="code" href="classMTParserRegistrar.html#d0">registerOp</a>(<a class="code" href="classMTParserRegistrar.html#a16">getOp</a>(t)-&gt;<a class="code" href="classMTParserRegistrar.html#a32">spawn</a>());
<a name="l00070"></a>00070         }
<a name="l00071"></a>00071 
<a name="l00072"></a>00072         <span class="comment">// define functions...</span>
<a name="l00073"></a>00073         pObj-&gt;<a class="code" href="classMTParserRegistrar.html#r3">m_funcList</a>.reserve( <a class="code" href="classMTParserRegistrar.html#a19">getNbDefinedFuncs</a>() );
<a name="l00074"></a>00074         <span class="keywordflow">for</span>( t=0; t&lt;<a class="code" href="classMTParserRegistrar.html#a19">getNbDefinedFuncs</a>(); t++ )
<a name="l00075"></a>00075         {
<a name="l00076"></a>00076                 pObj-&gt;<a class="code" href="classMTParserRegistrar.html#d1">registerFunc</a>(<a class="code" href="classMTParserRegistrar.html#a20">getFunc</a>(t)-&gt;<a class="code" href="classMTParserRegistrar.html#a32">spawn</a>());
<a name="l00077"></a>00077         }       
<a name="l00078"></a>00078 
<a name="l00079"></a>00079         <span class="keywordflow">return</span> pObj;    
<a name="l00080"></a>00080 }
<a name="l00081"></a>00081 
<a name="l00082"></a><a class="code" href="classMTParserRegistrar.html#a34">00082</a> <a class="code" href="classMTParserRegistrar.html#a34">MTParserRegistrar::~MTParserRegistrar</a>()
<a name="l00083"></a>00083 {
<a name="l00084"></a>00084         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> t;
<a name="l00085"></a>00085 
<a name="l00086"></a>00086         <span class="comment">// delete operators</span>
<a name="l00087"></a>00087         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nbOps = m_opList.size();
<a name="l00088"></a>00088         <span class="keywordflow">for</span>( t=0; t&lt;nbOps; t++ )
<a name="l00089"></a>00089         {               
<a name="l00090"></a>00090                 <span class="keyword">delete</span> m_opList[t].pOp;
<a name="l00091"></a>00091                 m_opList[t].pOp = NULL; 
<a name="l00092"></a>00092         }
<a name="l00093"></a>00093 
<a name="l00094"></a>00094         <span class="comment">// delete functions</span>
<a name="l00095"></a>00095         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nbFuncs = m_funcList.size();
<a name="l00096"></a>00096         <span class="keywordflow">for</span>( t=0; t&lt;nbFuncs; t++ )
<a name="l00097"></a>00097         {               
<a name="l00098"></a>00098                 <span class="keyword">delete</span> m_funcList[t].pFunc;
<a name="l00099"></a>00099                 m_funcList[t].pFunc = NULL;             
<a name="l00100"></a>00100         }
<a name="l00101"></a>00101 
<a name="l00102"></a>00102         <a class="code" href="classMTParserRegistrar.html#a5">undefineAllVars</a>();      
<a name="l00103"></a>00103 
<a name="l00104"></a>00104         <span class="keywordflow">if</span>( m_pVarFactory != NULL )
<a name="l00105"></a>00105         {
<a name="l00106"></a>00106                 <span class="keyword">delete</span> m_pVarFactory;
<a name="l00107"></a>00107                 m_pVarFactory = NULL;
<a name="l00108"></a>00108         }
<a name="l00109"></a>00109 }
<a name="l00110"></a>00110 
<a name="l00111"></a><a class="code" href="classMTParserRegistrar.html#a5">00111</a> <span class="keywordtype">void</span> <a class="code" href="classMTParserRegistrar.html#a5">MTParserRegistrar::undefineAllVars</a>()
<a name="l00112"></a>00112 {
<a name="l00113"></a>00113         TVariableMap::iterator it, itEnd;
<a name="l00114"></a>00114         it = m_variableMap.begin();
<a name="l00115"></a>00115         itEnd = m_variableMap.end();
<a name="l00116"></a>00116         
<a name="l00117"></a>00117         <span class="comment">// delete all variable evaluator objects</span>
<a name="l00118"></a>00118         <span class="keywordflow">for</span>( ; it != itEnd; it++ )
<a name="l00119"></a>00119         {       
<a name="l00120"></a>00120                 <span class="keyword">delete</span> (*it).second-&gt;pVar;
<a name="l00121"></a>00121                 (*it).second-&gt;pVar = NULL;      
<a name="l00122"></a>00122                 
<a name="l00123"></a>00123                 <span class="keyword">delete</span> (*it).second;
<a name="l00124"></a>00124         }
<a name="l00125"></a>00125                 
<a name="l00126"></a>00126         m_variableMap.clear();
<a name="l00127"></a>00127         m_variableList.clear();
<a name="l00128"></a>00128         
<a name="l00129"></a>00129         m_varKeyVersion++;      <span class="comment">// invalidate all variable keys</span>
<a name="l00130"></a>00130 }
<a name="l00131"></a>00131 
<a name="l00132"></a><a class="code" href="classMTParserRegistrar.html#a0">00132</a> <span class="keywordtype">void</span> <a class="code" href="classMTParserRegistrar.html#a0">MTParserRegistrar::setSyntax</a>(<span class="keyword">const</span> <a class="code" href="structMTSyntax.html">MTSyntax</a> &amp;syntax) <span class="keywordflow">throw</span>(<a class="code" href="classMTChainedExceptions.html">MTParserException</a>)
<a name="l00133"></a>00133 {
<a name="l00134"></a>00134         defValidateSyntax(syntax);
<a name="l00135"></a>00135         m_syntax = syntax;
<a name="l00136"></a>00136 }
<a name="l00137"></a>00137 
<a name="l00138"></a>00138 <span class="keywordtype">void</span> MTParserRegistrar::defValidateSyntax(<span class="keyword">const</span> <a class="code" href="structMTSyntax.html">MTSyntax</a> &amp;syntax)<span class="keyword">const</span> <span class="keywordflow">throw</span>(<a class="code" href="classMTChainedExceptions.html">MTParserException</a>)
<a name="l00139"></a>00139 {
<a name="l00140"></a>00140 
<a name="l00141"></a>00141         <span class="comment">// all syntax elements must be different...</span>
<a name="l00142"></a>00142         <span class="keywordflow">if</span>( syntax.argumentSeparator == syntax.decimalPoint )
<a name="l00143"></a>00143         {
<a name="l00144"></a>00144                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a0">MTDEFEXCEP_SyntaxArgDecConflict</a>, _T(<span class="stringliteral">""</span>));                 
<a name="l00145"></a>00145         }
<a name="l00146"></a>00146 
<a name="l00147"></a>00147 
<a name="l00148"></a>00148         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> t;
<a name="l00149"></a>00149         
<a name="l00150"></a>00150         <a class="code" href="MTUnicodeANSIDefs_8h.html#a0">MTSTRING</a> itemName;
<a name="l00151"></a>00151         <a class="code" href="MTUnicodeANSIDefs_8h.html#a1">MTCHAR</a> conflict;
<a name="l00152"></a>00152 
<a name="l00153"></a>00153         <span class="comment">// operators...</span>
<a name="l00154"></a>00154         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nbOps = getNbDefinedOps();
<a name="l00155"></a>00155         <span class="keywordflow">for</span>( t=0; t&lt;nbOps; t++ )
<a name="l00156"></a>00156         {
<a name="l00157"></a>00157                 itemName = getOp(t)-&gt;getSymbol();
<a name="l00158"></a>00158                 <span class="keywordflow">if</span>( !defValidateSyntaxConflict(syntax, itemName, conflict) )
<a name="l00159"></a>00159                 {
<a name="l00160"></a>00160                         <a class="code" href="MTUnicodeANSIDefs_8h.html#a0">MTSTRING</a> conflictStr;
<a name="l00161"></a>00161                         conflictStr = conflict;
<a name="l00162"></a>00162 
<a name="l00163"></a>00163                         throwDefExcep(<a class="code" href="MTParserException_8h.html#a4">MTDEFEXCEP_OpNameSyntaxConflict</a>, itemName, conflictStr);                  
<a name="l00164"></a>00164                 }
<a name="l00165"></a>00165         }
<a name="l00166"></a>00166 
<a name="l00167"></a>00167 
<a name="l00168"></a>00168         <span class="comment">// functions...</span>
<a name="l00169"></a>00169         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nbFuncs = getNbDefinedFuncs();
<a name="l00170"></a>00170         <span class="keywordflow">for</span>( t=0; t&lt;nbFuncs; t++ )
<a name="l00171"></a>00171         {
<a name="l00172"></a>00172                 itemName = getFunc(t)-&gt;getSymbol();
<a name="l00173"></a>00173                 <span class="keywordflow">if</span>( !defValidateSyntaxConflict(syntax, itemName, conflict) )
<a name="l00174"></a>00174                 {
<a name="l00175"></a>00175                         <a class="code" href="MTUnicodeANSIDefs_8h.html#a0">MTSTRING</a> conflictStr;
<a name="l00176"></a>00176                         conflictStr = conflict;
<a name="l00177"></a>00177 
<a name="l00178"></a>00178                         throwDefExcep(<a class="code" href="MTParserException_8h.html#a10">MTDEFEXCEP_FuncNameSyntaxConflict</a>, itemName, conflictStr);                        
<a name="l00179"></a>00179                 }
<a name="l00180"></a>00180         }
<a name="l00181"></a>00181 
<a name="l00182"></a>00182         <span class="comment">// constants...</span>
<a name="l00183"></a>00183         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nbConsts = m_constList.size();
<a name="l00184"></a>00184         <span class="keywordflow">for</span>( t=0; t&lt;nbConsts; t++ )
<a name="l00185"></a>00185         {
<a name="l00186"></a>00186                 itemName = m_constList[t].name;
<a name="l00187"></a>00187                 <span class="keywordflow">if</span>( !defValidateSyntaxConflict(syntax, itemName, conflict) )
<a name="l00188"></a>00188                 {
<a name="l00189"></a>00189                         <a class="code" href="MTUnicodeANSIDefs_8h.html#a0">MTSTRING</a> conflictStr;
<a name="l00190"></a>00190                         conflictStr = conflict;
<a name="l00191"></a>00191 
<a name="l00192"></a>00192                         throwDefExcep(<a class="code" href="MTParserException_8h.html#a23">MTDEFEXCEP_ConstNameSyntaxConflict</a>, itemName, conflictStr);                       
<a name="l00193"></a>00193                 }
<a name="l00194"></a>00194         }
<a name="l00195"></a>00195 }
<a name="l00196"></a>00196 
<a name="l00197"></a><a class="code" href="classMTParserRegistrar.html#a1">00197</a> <a class="code" href="structMTSyntax.html">MTSyntax</a> <a class="code" href="classMTParserRegistrar.html#a1">MTParserRegistrar::getSyntax</a>()<span class="keyword">const</span>
<a name="l00198"></a>00198 <span class="keyword"></span>{
<a name="l00199"></a>00199         <span class="keywordflow">return</span> m_syntax;
<a name="l00200"></a>00200 }
<a name="l00201"></a>00201 
<a name="l00202"></a>00202 <span class="keywordtype">bool</span> MTParserRegistrar::defValidateSyntaxConflict(<span class="keyword">const</span> <a class="code" href="structMTSyntax.html">MTSyntax</a> &amp;syntax, <span class="keyword">const</span> <a class="code" href="MTUnicodeANSIDefs_8h.html#a0">MTSTRING</a> &amp;word, <a class="code" href="MTUnicodeANSIDefs_8h.html#a1">MTCHAR</a> &amp;conflict)<span class="keyword">const</span>
<a name="l00203"></a>00203 <span class="keyword"></span>{
<a name="l00204"></a>00204 
<a name="l00205"></a>00205         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> size = word.size();
<a name="l00206"></a>00206         <a class="code" href="MTUnicodeANSIDefs_8h.html#a1">MTCHAR</a> c;
<a name="l00207"></a>00207         <span class="keywordflow">for</span>( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> t=0; t&lt;size; t++ )
<a name="l00208"></a>00208         {
<a name="l00209"></a>00209                 c = word[t];
<a name="l00210"></a>00210                 
<a name="l00211"></a>00211                 <span class="comment">// don't validate the decimal point since not used to split formula parts...</span>
<a name="l00212"></a>00212                 <span class="keywordflow">if</span>( c == syntax.<a class="code" href="structMTSyntax.html#o1">argumentSeparator</a> ||                    
<a name="l00213"></a>00213                         c == <a class="code" href="MTParserPublic_8h.html#a3">MTOPEN_BRACKET</a> ||
<a name="l00214"></a>00214                         c == <a class="code" href="MTParserPublic_8h.html#a4">MTCLOSE_BRACKET</a>)
<a name="l00215"></a>00215                 {
<a name="l00216"></a>00216                         conflict = c;
<a name="l00217"></a>00217                         <span class="keywordflow">return</span> <span class="keyword">false</span>;           <span class="comment">// conflict detected!</span>
<a name="l00218"></a>00218                 }
<a name="l00219"></a>00219         }
<a name="l00220"></a>00220 
<a name="l00221"></a>00221         <span class="keywordflow">return</span> <span class="keyword">true</span>;    <span class="comment">// all is ok!</span>
<a name="l00222"></a>00222 
<a name="l00223"></a>00223 }
<a name="l00224"></a>00224 
<a name="l00225"></a>00225 
<a name="l00226"></a><a class="code" href="classMTParserRegistrar.html#a14">00226</a> <span class="keywordtype">void</span> <a class="code" href="classMTParserRegistrar.html#a14">MTParserRegistrar::defineOp</a>(<a class="code" href="classMTOperatorI.html">MTOperatorI</a> *pOp) <span class="keywordflow">throw</span>(<a class="code" href="classMTChainedExceptions.html">MTParserException</a>)
<a name="l00227"></a>00227 {
<a name="l00228"></a>00228         <span class="keywordflow">try</span>
<a name="l00229"></a>00229         {
<a name="l00230"></a>00230                 defValidateOp(pOp);
<a name="l00231"></a>00231         }
<a name="l00232"></a>00232         <span class="keywordflow">catch</span>( <a class="code" href="classMTChainedExceptions.html">MTParserException</a> &amp;e )
<a name="l00233"></a>00233         {                       
<a name="l00234"></a>00234                 <span class="keyword">delete</span> pOp;             
<a name="l00235"></a>00235 
<a name="l00236"></a>00236                 <span class="comment">// rethrow the same exception</span>
<a name="l00237"></a>00237                 <span class="keywordflow">throw</span>(e);               
<a name="l00238"></a>00238         }       
<a name="l00239"></a>00239 
<a name="l00240"></a>00240         registerOp(pOp);        
<a name="l00241"></a>00241 }
<a name="l00242"></a>00242 
<a name="l00243"></a>00243 <span class="keywordtype">void</span> MTParserRegistrar::registerOp(<a class="code" href="classMTOperatorI.html">MTOperatorI</a> *pOp)
<a name="l00244"></a>00244 {
<a name="l00245"></a>00245         <span class="comment">// insert the operator in the hash table at the right position</span>
<a name="l00246"></a>00246         <span class="comment">// to keep the vector ordered by operator symbol length.</span>
<a name="l00247"></a>00247         <span class="comment">// This is essential in order to be able to recognize multicharacter operators</span>
<a name="l00248"></a>00248 
<a name="l00249"></a>00249         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> hashID = getOpHashKey(pOp-&gt;<a class="code" href="classMTParserItemI.html#a1">getSymbol</a>());
<a name="l00250"></a>00250 
<a name="l00251"></a>00251         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nbOps = m_opHash[hashID].size();
<a name="l00252"></a>00252         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> symbolLength = lstrlen(pOp-&gt;<a class="code" href="classMTParserItemI.html#a1">getSymbol</a>());
<a name="l00253"></a>00253         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> t;
<a name="l00254"></a>00254 
<a name="l00255"></a>00255         <span class="keywordflow">for</span>( t=0; t&lt;nbOps; t++ )
<a name="l00256"></a>00256         {
<a name="l00257"></a>00257                 <span class="keywordflow">if</span>( getOpByHashID(hashID, t)-&gt;symbolLength &lt; symbolLength )
<a name="l00258"></a>00258                 {
<a name="l00259"></a>00259                         <span class="comment">// insert the operator here</span>
<a name="l00260"></a>00260                         <span class="keywordflow">break</span>;
<a name="l00261"></a>00261                 }
<a name="l00262"></a>00262         }
<a name="l00263"></a>00263 
<a name="l00264"></a>00264         SOperatorInfo opInfo;
<a name="l00265"></a>00265         opInfo.pOp = pOp;       
<a name="l00266"></a>00266         opInfo.symbol = pOp-&gt;<a class="code" href="classMTParserItemI.html#a1">getSymbol</a>();
<a name="l00267"></a>00267         opInfo.symbolLength = symbolLength;     
<a name="l00268"></a>00268 
<a name="l00269"></a>00269         m_opHash[hashID].insert(m_opHash[hashID].begin()+t, m_opList.size());
<a name="l00270"></a>00270         m_opList.push_back(opInfo);
<a name="l00271"></a>00271 
<a name="l00272"></a>00272 }
<a name="l00273"></a>00273 
<a name="l00274"></a>00274 <span class="keywordtype">void</span> MTParserRegistrar::defValidateOp(<a class="code" href="classMTOperatorI.html">MTOperatorI</a> *pOp)<span class="keyword">const</span> <span class="keywordflow">throw</span>(<a class="code" href="classMTChainedExceptions.html">MTParserException</a>)
<a name="l00275"></a>00275 {
<a name="l00276"></a>00276 
<a name="l00277"></a>00277         <a class="code" href="MTUnicodeANSIDefs_8h.html#a0">MTSTRING</a> opName = pOp-&gt;<a class="code" href="classMTParserItemI.html#a1">getSymbol</a>();
<a name="l00278"></a>00278 
<a name="l00279"></a>00279         <span class="comment">// operator name can't be null</span>
<a name="l00280"></a>00280         <span class="keywordflow">if</span>( opName.size() == 0 )
<a name="l00281"></a>00281         {
<a name="l00282"></a>00282                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a2">MTDEFEXCEP_OpNameNull</a>, opName);           
<a name="l00283"></a>00283         }
<a name="l00284"></a>00284 
<a name="l00285"></a>00285         <span class="comment">// operator name cannot contains space characters</span>
<a name="l00286"></a>00286         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> pos;
<a name="l00287"></a>00287         <span class="keywordflow">if</span>( <a class="code" href="namespaceMTTools.html#a1">MTTools::findSubStr</a>(opName, _T(<span class="stringliteral">" "</span>), pos) )
<a name="l00288"></a>00288         {
<a name="l00289"></a>00289                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a3">MTDEFEXCEP_OpNameSpace</a>, opName);          
<a name="l00290"></a>00290         }
<a name="l00291"></a>00291 
<a name="l00292"></a>00292         <span class="comment">// operator precedence must be less than function precedence and greater or equal to 0</span>
<a name="l00293"></a>00293         <span class="keywordflow">if</span>( pOp-&gt;<a class="code" href="classMTOperatorI.html#a0">getPrecedence</a>() &gt;= <a class="code" href="MTParserPublic_8h.html#a20a19">e_MTOpPrec_FCT</a> ||
<a name="l00294"></a>00294                 pOp-&gt;<a class="code" href="classMTOperatorI.html#a0">getPrecedence</a>() &lt; 0)
<a name="l00295"></a>00295         {
<a name="l00296"></a>00296                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a5">MTDEFEXCEP_OpPrecedence</a>, opName);
<a name="l00297"></a>00297         }
<a name="l00298"></a>00298 
<a name="l00299"></a>00299         
<a name="l00300"></a>00300         <span class="comment">// validate that this symbol is not already defined...</span>
<a name="l00301"></a>00301         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> index;
<a name="l00302"></a>00302         <span class="keywordflow">if</span>( findOp(opName.c_str(), pOp-&gt;<a class="code" href="classMTOperatorI.html#a1">isUnaryOp</a>(), index) )
<a name="l00303"></a>00303         {               
<a name="l00304"></a>00304                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a1">MTDEFEXCEP_OpAlreadyDefined</a>, opName);
<a name="l00305"></a>00305         }
<a name="l00306"></a>00306 
<a name="l00307"></a>00307         <span class="comment">// operator name cannot contains syntax element characters...</span>
<a name="l00308"></a>00308         <a class="code" href="MTUnicodeANSIDefs_8h.html#a1">MTCHAR</a> syntaxConflict;
<a name="l00309"></a>00309         <span class="keywordflow">if</span>( !defValidateSyntaxConflict(getSyntax(), opName, syntaxConflict) )
<a name="l00310"></a>00310         {
<a name="l00311"></a>00311                 <a class="code" href="MTUnicodeANSIDefs_8h.html#a0">MTSTRING</a> conflictStr;
<a name="l00312"></a>00312                 conflictStr = syntaxConflict;
<a name="l00313"></a>00313                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a4">MTDEFEXCEP_OpNameSyntaxConflict</a>, opName, conflictStr);
<a name="l00314"></a>00314         }
<a name="l00315"></a>00315 
<a name="l00316"></a>00316         <span class="comment">// revalidate functions, variables and constants to be sure that this new operator</span>
<a name="l00317"></a>00317         <span class="comment">// symbol will not conflict with another symbols...     </span>
<a name="l00318"></a>00318 
<a name="l00319"></a>00319         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> t; 
<a name="l00320"></a>00320         <a class="code" href="MTUnicodeANSIDefs_8h.html#a0">MTSTRING</a> itemName;              
<a name="l00321"></a>00321 
<a name="l00322"></a>00322         <span class="comment">// functions...</span>
<a name="l00323"></a>00323         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nbFuncs = getNbDefinedFuncs();
<a name="l00324"></a>00324         <span class="keywordflow">for</span>( t=0; t&lt;nbFuncs; t++ )
<a name="l00325"></a>00325         {
<a name="l00326"></a>00326                 itemName = getFunc(t)-&gt;getSymbol();
<a name="l00327"></a>00327                 <span class="keywordflow">if</span>( <a class="code" href="namespaceMTTools.html#a1">MTTools::findSubStr</a>(itemName, opName, pos) )
<a name="l00328"></a>00328                 {
<a name="l00329"></a>00329                         throwDefExcep(<a class="code" href="MTParserException_8h.html#a11">MTDEFEXCEP_FuncNameOpConflict</a>, itemName, opName);
<a name="l00330"></a>00330                 }
<a name="l00331"></a>00331         }
<a name="l00332"></a>00332 
<a name="l00333"></a>00333         <span class="comment">// constants...</span>
<a name="l00334"></a>00334         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nbConsts = m_constList.size();
<a name="l00335"></a>00335         <span class="keywordflow">for</span>( t=0; t&lt;nbConsts; t++ )
<a name="l00336"></a>00336         {
<a name="l00337"></a>00337                 itemName = m_constList[t].name;
<a name="l00338"></a>00338                 <span class="keywordflow">if</span>( <a class="code" href="namespaceMTTools.html#a1">MTTools::findSubStr</a>(itemName, opName, pos) )
<a name="l00339"></a>00339                 {
<a name="l00340"></a>00340                         throwDefExcep(<a class="code" href="MTParserException_8h.html#a24">MTDEFEXCEP_ConstNameOpConflict</a>, itemName, opName);
<a name="l00341"></a>00341                 }
<a name="l00342"></a>00342         }
<a name="l00343"></a>00343 }
<a name="l00344"></a>00344 
<a name="l00345"></a><a class="code" href="classMTParserRegistrar.html#a25">00345</a> <span class="keywordtype">bool</span> <a class="code" href="classMTParserRegistrar.html#a25">MTParserRegistrar::findOp</a>(<span class="keyword">const</span> <a class="code" href="MTUnicodeANSIDefs_8h.html#a1">MTCHAR</a> *symbol, <span class="keywordtype">bool</span> unaryOp, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> &amp;index)<span class="keyword">const</span>
<a name="l00346"></a>00346 <span class="keyword"></span>{       
<a name="l00347"></a>00347         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> hashID = getOpHashKey(symbol);
<a name="l00348"></a>00348 
<a name="l00349"></a>00349         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nbOps = m_opHash[hashID].size();
<a name="l00350"></a>00350         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> t;
<a name="l00351"></a>00351 
<a name="l00352"></a>00352         <span class="keywordflow">for</span>( t=0; t&lt;nbOps; t++ )
<a name="l00353"></a>00353         {
<a name="l00354"></a>00354                 <span class="keywordflow">if</span>( lstrcmp(symbol, getOpByHashID(hashID, t)-&gt;symbol.c_str() ) == 0 &amp;&amp;
<a name="l00355"></a>00355                         getOpByHashID(hashID, t)-&gt;pOp-&gt;isUnaryOp() == unaryOp)
<a name="l00356"></a>00356                 {
<a name="l00357"></a>00357                         index = getOpIndexByHashID(hashID, t);
<a name="l00358"></a>00358                         <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00359"></a>00359                 }
<a name="l00360"></a>00360         }
<a name="l00361"></a>00361 
<a name="l00362"></a>00362         <span class="keywordflow">return</span> <span class="keyword">false</span>;   <span class="comment">// not found</span>
<a name="l00363"></a>00363 
<a name="l00364"></a>00364 }
<a name="l00365"></a>00365 
<a name="l00366"></a><a class="code" href="classMTParserRegistrar.html#a15">00366</a> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> <a class="code" href="classMTParserRegistrar.html#a15">MTParserRegistrar::getNbDefinedOps</a>()<span class="keyword">const</span>
<a name="l00367"></a>00367 <span class="keyword"></span>{
<a name="l00368"></a>00368         <span class="keywordflow">return</span> m_opList.size();
<a name="l00369"></a>00369 }
<a name="l00370"></a>00370 
<a name="l00371"></a><a class="code" href="classMTParserRegistrar.html#a18">00371</a> <span class="keywordtype">void</span> <a class="code" href="classMTParserRegistrar.html#a18">MTParserRegistrar::defineFunc</a>( <a class="code" href="classMTFunctionI.html">MTFunctionI</a> *pFunc) <span class="keywordflow">throw</span>(<a class="code" href="classMTChainedExceptions.html">MTParserException</a>)
<a name="l00372"></a>00372 {
<a name="l00373"></a>00373         <span class="keywordflow">try</span>
<a name="l00374"></a>00374         {
<a name="l00375"></a>00375                 defValidateFunc(pFunc);
<a name="l00376"></a>00376         }
<a name="l00377"></a>00377         <span class="keywordflow">catch</span>( <a class="code" href="classMTChainedExceptions.html">MTParserException</a> &amp;e )
<a name="l00378"></a>00378         {
<a name="l00379"></a>00379                 
<a name="l00380"></a>00380                 <span class="keyword">delete</span> pFunc;   
<a name="l00381"></a>00381 
<a name="l00382"></a>00382                 <span class="comment">// rethrow the same exception</span>
<a name="l00383"></a>00383                 <span class="keywordflow">throw</span>(e);               
<a name="l00384"></a>00384         }       
<a name="l00385"></a>00385 
<a name="l00386"></a>00386         registerFunc(pFunc);
<a name="l00387"></a>00387 
<a name="l00388"></a>00388 }
<a name="l00389"></a>00389 
<a name="l00390"></a>00390 <span class="keywordtype">void</span> MTParserRegistrar::registerFunc(<a class="code" href="classMTFunctionI.html">MTFunctionI</a> *pFunc)
<a name="l00391"></a>00391 {       
<a name="l00392"></a>00392         SFunctionInfo funcInfo;
<a name="l00393"></a>00393         funcInfo.pFunc = pFunc;         
<a name="l00394"></a>00394         funcInfo.symbol = pFunc-&gt;<a class="code" href="classMTParserItemI.html#a1">getSymbol</a>();   
<a name="l00395"></a>00395 
<a name="l00396"></a>00396         m_funcMap.insert(TFuncMap::value_type(funcInfo.symbol.c_str(), m_funcList.size()));     
<a name="l00397"></a>00397         m_funcList.push_back(funcInfo);
<a name="l00398"></a>00398 }
<a name="l00399"></a>00399 
<a name="l00400"></a><a class="code" href="classMTParserRegistrar.html#a21">00400</a> <span class="keywordtype">void</span> <a class="code" href="classMTParserRegistrar.html#a21">MTParserRegistrar::undefineFunc</a>(<a class="code" href="classMTFunctionI.html">MTFunctionI</a> *pFunc) <span class="keywordflow">throw</span>(<a class="code" href="classMTChainedExceptions.html">MTParserException</a>)
<a name="l00401"></a>00401 {
<a name="l00402"></a>00402         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> index;
<a name="l00403"></a>00403         <span class="keywordflow">if</span>( !findFunctionExact(pFunc-&gt;<a class="code" href="classMTParserItemI.html#a1">getSymbol</a>(), pFunc-&gt;<a class="code" href="classMTFunctionI.html#a0">getNbArgs</a>(), index) )
<a name="l00404"></a>00404         {
<a name="l00405"></a>00405                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a6">MTDEFEXCEP_ItemNotFound</a>, pFunc-&gt;<a class="code" href="classMTParserItemI.html#a1">getSymbol</a>());
<a name="l00406"></a>00406         }
<a name="l00407"></a>00407         
<a name="l00408"></a>00408         m_funcList.erase(m_funcList.begin()+index);
<a name="l00409"></a>00409         <span class="keyword">delete</span> pFunc;
<a name="l00410"></a>00410         rebuildFuncMap();       
<a name="l00411"></a>00411 }
<a name="l00412"></a>00412 
<a name="l00413"></a>00413 <span class="keywordtype">void</span> MTParserRegistrar::rebuildFuncMap()
<a name="l00414"></a>00414 {
<a name="l00415"></a>00415         m_funcMap.clear();
<a name="l00416"></a>00416         
<a name="l00417"></a>00417         <span class="keywordflow">for</span>(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> t=0; t&lt;m_funcList.size(); t++ )
<a name="l00418"></a>00418         {
<a name="l00419"></a>00419                 m_funcMap.insert(TFuncMap::value_type(m_funcList[t].symbol.c_str(), t));
<a name="l00420"></a>00420         }
<a name="l00421"></a>00421 }
<a name="l00422"></a>00422 
<a name="l00423"></a>00423 
<a name="l00424"></a><a class="code" href="classMTParserRegistrar.html#a17">00424</a> <span class="keywordtype">void</span> <a class="code" href="classMTParserRegistrar.html#a17">MTParserRegistrar::undefineOp</a>(<a class="code" href="classMTOperatorI.html">MTOperatorI</a> *pOp) <span class="keywordflow">throw</span>(<a class="code" href="classMTChainedExceptions.html">MTParserException</a>)
<a name="l00425"></a>00425 {       
<a name="l00426"></a>00426         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> index;
<a name="l00427"></a>00427         <span class="keywordflow">if</span>(!findOp(pOp-&gt;<a class="code" href="classMTParserItemI.html#a1">getSymbol</a>(), pOp-&gt;<a class="code" href="classMTOperatorI.html#a1">isUnaryOp</a>(), index) )
<a name="l00428"></a>00428         {
<a name="l00429"></a>00429                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a6">MTDEFEXCEP_ItemNotFound</a>, pOp-&gt;<a class="code" href="classMTParserItemI.html#a1">getSymbol</a>());
<a name="l00430"></a>00430         }       
<a name="l00431"></a>00431 
<a name="l00432"></a>00432         removeFromOpHash(pOp);
<a name="l00433"></a>00433         m_opList.erase(m_opList.begin()+index);
<a name="l00434"></a>00434         decreaseOpHashAfter(index);
<a name="l00435"></a>00435 
<a name="l00436"></a>00436         <span class="keyword">delete</span> pOp;
<a name="l00437"></a>00437 }
<a name="l00438"></a>00438 
<a name="l00439"></a>00439 <span class="keywordtype">void</span> MTParserRegistrar::decreaseOpHashAfter(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> index)
<a name="l00440"></a>00440 {       
<a name="l00441"></a>00441         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> hashID;
<a name="l00442"></a>00442         <span class="keywordflow">for</span>(hashID=0; hashID&lt;<a class="code" href="MTParserRegistrar_8h.html#a0">MTREGISTRAR_OPHASHSIZE</a>; hashID++)
<a name="l00443"></a>00443         {
<a name="l00444"></a>00444                 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> t;
<a name="l00445"></a>00445                 <span class="keywordflow">for</span>(t=0; t&lt;m_opHash[hashID].size(); t++)
<a name="l00446"></a>00446                 {
<a name="l00447"></a>00447                         <span class="keywordflow">if</span>( m_opHash[hashID][t] &gt; index )
<a name="l00448"></a>00448                         {
<a name="l00449"></a>00449                                 m_opHash[hashID][t]--;                          
<a name="l00450"></a>00450                         }                       
<a name="l00451"></a>00451                 }
<a name="l00452"></a>00452         }
<a name="l00453"></a>00453 }
<a name="l00454"></a>00454 
<a name="l00455"></a>00455 <span class="keywordtype">void</span> MTParserRegistrar::removeFromOpHash(<a class="code" href="classMTOperatorI.html">MTOperatorI</a> *pOp)
<a name="l00456"></a>00456 {
<a name="l00457"></a>00457         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> hashID = getOpHashKey(pOp-&gt;<a class="code" href="classMTParserItemI.html#a1">getSymbol</a>());
<a name="l00458"></a>00458 
<a name="l00459"></a>00459         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nbOps = m_opHash[hashID].size();
<a name="l00460"></a>00460         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> t;
<a name="l00461"></a>00461 
<a name="l00462"></a>00462         <span class="keywordflow">for</span>( t=0; t&lt;nbOps; t++ )
<a name="l00463"></a>00463         {
<a name="l00464"></a>00464                 <span class="keywordflow">if</span>( getOpByHashID(hashID, t)-&gt;pOp == pOp )
<a name="l00465"></a>00465                 {                       
<a name="l00466"></a>00466                         m_opHash[hashID].erase( m_opHash[hashID].begin()+t );
<a name="l00467"></a>00467                         <span class="keywordflow">return</span>;
<a name="l00468"></a>00468                 }
<a name="l00469"></a>00469         }
<a name="l00470"></a>00470 
<a name="l00471"></a>00471         throwDefExcep(<a class="code" href="MTParserException_8h.html#a6">MTDEFEXCEP_ItemNotFound</a>, pOp-&gt;<a class="code" href="classMTParserItemI.html#a1">getSymbol</a>());
<a name="l00472"></a>00472 }
<a name="l00473"></a>00473 
<a name="l00474"></a>00474 
<a name="l00475"></a>00475 <span class="keywordtype">void</span> MTParserRegistrar::defValidateFunc(<a class="code" href="classMTFunctionI.html">MTFunctionI</a> *pFunc)<span class="keyword">const</span> <span class="keywordflow">throw</span>(<a class="code" href="classMTChainedExceptions.html">MTParserException</a>)
<a name="l00476"></a>00476 {
<a name="l00477"></a>00477         <a class="code" href="MTUnicodeANSIDefs_8h.html#a0">MTSTRING</a> funcName = pFunc-&gt;<a class="code" href="classMTParserItemI.html#a1">getSymbol</a>();
<a name="l00478"></a>00478 
<a name="l00479"></a>00479         <span class="comment">// function name can't be null</span>
<a name="l00480"></a>00480         <span class="keywordflow">if</span>( funcName.size() == 0 )
<a name="l00481"></a>00481         {
<a name="l00482"></a>00482                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a8">MTDEFEXCEP_FuncNameNull</a>, funcName);               
<a name="l00483"></a>00483         }
<a name="l00484"></a>00484         
<a name="l00485"></a>00485         <span class="comment">// function name cannot contains space characters</span>
<a name="l00486"></a>00486         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> pos;
<a name="l00487"></a>00487         <span class="keywordflow">if</span>( <a class="code" href="namespaceMTTools.html#a1">MTTools::findSubStr</a>(funcName, _T(<span class="stringliteral">" "</span>), pos) )
<a name="l00488"></a>00488         {
<a name="l00489"></a>00489                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a9">MTDEFEXCEP_FuncNameSpace</a>, funcName);              
<a name="l00490"></a>00490         }
<a name="l00491"></a>00491 
<a name="l00492"></a>00492         <span class="comment">// validate that this symbol is not already defined...</span>
<a name="l00493"></a>00493         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> index;
<a name="l00494"></a>00494         <span class="keywordflow">if</span>( findFunctionExact(funcName.c_str(), pFunc-&gt;<a class="code" href="classMTFunctionI.html#a0">getNbArgs</a>(), index) )
<a name="l00495"></a>00495         {               
<a name="l00496"></a>00496                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a7">MTDEFEXCEP_FuncAlreadyDefined</a>, funcName);
<a name="l00497"></a>00497         }
<a name="l00498"></a>00498 
<a name="l00499"></a>00499         <span class="comment">// function name cannot contains syntax element characters...</span>
<a name="l00500"></a>00500         <a class="code" href="MTUnicodeANSIDefs_8h.html#a1">MTCHAR</a> syntaxConflict;
<a name="l00501"></a>00501         <span class="keywordflow">if</span>( !defValidateSyntaxConflict(getSyntax(), funcName, syntaxConflict) )
<a name="l00502"></a>00502         {
<a name="l00503"></a>00503                 <a class="code" href="MTUnicodeANSIDefs_8h.html#a0">MTSTRING</a> conflictStr;
<a name="l00504"></a>00504                 conflictStr = syntaxConflict;
<a name="l00505"></a>00505                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a10">MTDEFEXCEP_FuncNameSyntaxConflict</a>, funcName, conflictStr);
<a name="l00506"></a>00506         }
<a name="l00507"></a>00507 
<a name="l00508"></a>00508         <span class="comment">// function name cannot contains operator characters...</span>
<a name="l00509"></a>00509         <a class="code" href="MTUnicodeANSIDefs_8h.html#a0">MTSTRING</a> opConflict;
<a name="l00510"></a>00510         <span class="keywordflow">if</span>( !defValidateOpSymbolConflict(funcName, opConflict) )
<a name="l00511"></a>00511         {
<a name="l00512"></a>00512                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a11">MTDEFEXCEP_FuncNameOpConflict</a>, funcName, opConflict);
<a name="l00513"></a>00513 
<a name="l00514"></a>00514         }
<a name="l00515"></a>00515 }
<a name="l00516"></a>00516 
<a name="l00517"></a>00517 
<a name="l00518"></a>00518 <span class="keywordtype">bool</span> MTParserRegistrar::defValidateOpSymbolConflict(<span class="keyword">const</span> <a class="code" href="MTUnicodeANSIDefs_8h.html#a0">MTSTRING</a> &amp;word, <a class="code" href="MTUnicodeANSIDefs_8h.html#a0">MTSTRING</a> &amp;conflict)<span class="keyword">const</span>
<a name="l00519"></a>00519 <span class="keyword"></span>{
<a name="l00520"></a>00520         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> size = word.size();
<a name="l00521"></a>00521         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> t;
<a name="l00522"></a>00522         <span class="keywordflow">for</span>( t=0; t&lt;size; t++ )
<a name="l00523"></a>00523         {
<a name="l00524"></a>00524                 <span class="keywordflow">if</span>( <a class="code" href="classMTParserRegistrar.html#a31">areNextCharsOpString</a>(word.c_str()+t, word.size()-t, conflict) )
<a name="l00525"></a>00525                 {
<a name="l00526"></a>00526                         <span class="keywordflow">return</span> <span class="keyword">false</span>;   <span class="comment">// conflict</span>
<a name="l00527"></a>00527                 }
<a name="l00528"></a>00528         }
<a name="l00529"></a>00529 
<a name="l00530"></a>00530         <span class="keywordflow">return</span> <span class="keyword">true</span>;    <span class="comment">// no conflict</span>
<a name="l00531"></a>00531 }
<a name="l00532"></a>00532 
<a name="l00533"></a>00533 <span class="comment">// This method is very often called while in the compilation step.  So performance must be high.</span>
<a name="l00534"></a><a class="code" href="classMTParserRegistrar.html#a31">00534</a> <span class="keywordtype">bool</span> <a class="code" href="classMTParserRegistrar.html#a31">MTParserRegistrar::areNextCharsOpString</a>(<span class="keyword">const</span> <a class="code" href="MTUnicodeANSIDefs_8h.html#a1">MTCHAR</a> *str, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> strLength, <a class="code" href="MTUnicodeANSIDefs_8h.html#a0">MTSTRING</a> &amp;symbol)<span class="keyword">const</span>
<a name="l00535"></a>00535 <span class="keyword"></span>{
<a name="l00536"></a>00536         <span class="comment">// assume that the operators are ordered by symbol length (decreasing order)    </span>
<a name="l00537"></a>00537         
<a name="l00538"></a>00538         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> t;
<a name="l00539"></a>00539         
<a name="l00540"></a>00540         <span class="comment">// compute the hash table indice</span>
<a name="l00541"></a>00541         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> hashID = getOpHashKey(str);
<a name="l00542"></a>00542         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nbOps = m_opHash[hashID].size();   
<a name="l00543"></a>00543 
<a name="l00544"></a>00544         <span class="keywordflow">for</span>( t=0; t&lt;nbOps; t++ )
<a name="l00545"></a>00545         {
<a name="l00546"></a>00546                 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> symbolLength = getOpByHashID(hashID, t)-&gt;symbolLength;             
<a name="l00547"></a>00547 
<a name="l00548"></a>00548                 <span class="keywordflow">if</span>( symbolLength &lt;= strLength )
<a name="l00549"></a>00549                 {
<a name="l00550"></a>00550                         <span class="keywordflow">if</span>( <a class="code" href="namespaceMTTools.html#a3">MTTools::isStrBegin</a>(str, getOpByHashID(hashID, t)-&gt;symbol.c_str(), strLength, symbolLength) )
<a name="l00551"></a>00551                         {
<a name="l00552"></a>00552                                 symbol = getOpByHashID(hashID, t)-&gt;symbol.c_str();
<a name="l00553"></a>00553                                 <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00554"></a>00554 
<a name="l00555"></a>00555                         }               
<a name="l00556"></a>00556                 }
<a name="l00557"></a>00557         }
<a name="l00558"></a>00558 
<a name="l00559"></a>00559         <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00560"></a>00560 }
<a name="l00561"></a>00561 
<a name="l00562"></a>00562 
<a name="l00563"></a><a class="code" href="classMTParserRegistrar.html#a19">00563</a> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> <a class="code" href="classMTParserRegistrar.html#a19">MTParserRegistrar::getNbDefinedFuncs</a>()<span class="keyword">const</span>
<a name="l00564"></a>00564 <span class="keyword"></span>{
<a name="l00565"></a>00565         <span class="keywordflow">return</span> m_funcList.size();
<a name="l00566"></a>00566 }
<a name="l00567"></a>00567 
<a name="l00568"></a><a class="code" href="classMTParserRegistrar.html#a22">00568</a> <span class="keywordtype">void</span> <a class="code" href="classMTParserRegistrar.html#a22">MTParserRegistrar::setVarFactory</a>(<a class="code" href="classMTVariableFactoryI.html">MTVariableFactoryI</a> *pFactory)
<a name="l00569"></a>00569 {
<a name="l00570"></a>00570         assert( pFactory != NULL );             <span class="comment">// must be a valid object</span>
<a name="l00571"></a>00571         
<a name="l00572"></a>00572         <span class="keywordflow">if</span>( m_pVarFactory != NULL )
<a name="l00573"></a>00573         {
<a name="l00574"></a>00574                 <span class="keyword">delete</span> m_pVarFactory;
<a name="l00575"></a>00575                 m_pVarFactory = NULL;
<a name="l00576"></a>00576         }
<a name="l00577"></a>00577 
<a name="l00578"></a>00578         m_pVarFactory = pFactory;
<a name="l00579"></a>00579 }
<a name="l00580"></a>00580 
<a name="l00581"></a><a class="code" href="classMTParserRegistrar.html#a23">00581</a> <span class="keywordtype">void</span> <a class="code" href="classMTParserRegistrar.html#a2">MTParserRegistrar::defineVar</a>(<span class="keyword">const</span> <a class="code" href="MTUnicodeANSIDefs_8h.html#a1">MTCHAR</a> *symbol) <span class="keywordflow">throw</span>(<a class="code" href="classMTChainedExceptions.html">MTParserException</a>)
<a name="l00582"></a>00582 {
<a name="l00583"></a>00583         <a class="code" href="classMTVariableI.html">MTVariableI</a> *pVar = m_pVarFactory-&gt;create(symbol);
<a name="l00584"></a>00584 
<a name="l00585"></a>00585         <span class="keywordflow">if</span>( pVar == NULL )
<a name="l00586"></a>00586         {
<a name="l00587"></a>00587                 <span class="comment">// cannot create this variable!</span>
<a name="l00588"></a>00588                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a6">MTDEFEXCEP_ItemNotFound</a>, symbol, _T(<span class="stringliteral">""</span>));
<a name="l00589"></a>00589         }
<a name="l00590"></a>00590 
<a name="l00591"></a>00591         defineVar(pVar);
<a name="l00592"></a>00592 }
<a name="l00593"></a>00593 
<a name="l00594"></a><a class="code" href="classMTParserRegistrar.html#a2">00594</a> <span class="keywordtype">void</span> <a class="code" href="classMTParserRegistrar.html#a2">MTParserRegistrar::defineVar</a>(<a class="code" href="classMTVariableI.html">MTVariableI</a> *pVar) <span class="keywordflow">throw</span>(<a class="code" href="classMTChainedExceptions.html">MTParserException</a>)
<a name="l00595"></a>00595 {
<a name="l00596"></a>00596         <a class="code" href="MTUnicodeANSIDefs_8h.html#a0">MTSTRING</a> varName = pVar-&gt;getSymbol();
<a name="l00597"></a>00597         
<a name="l00598"></a>00598         <span class="keywordflow">try</span>
<a name="l00599"></a>00599         {
<a name="l00600"></a>00600                 defValidateVar(varName);
<a name="l00601"></a>00601         }
<a name="l00602"></a>00602         <span class="keywordflow">catch</span>( <a class="code" href="classMTChainedExceptions.html">MTParserException</a> &amp;e )
<a name="l00603"></a>00603         {
<a name="l00604"></a>00604                 
<a name="l00605"></a>00605                 <span class="keyword">delete</span> pVar;            
<a name="l00606"></a>00606 
<a name="l00607"></a>00607                 <span class="comment">// rethrow the same exception</span>
<a name="l00608"></a>00608                 <span class="keywordflow">throw</span>(e);               
<a name="l00609"></a>00609         }
<a name="l00610"></a>00610 
<a name="l00611"></a>00611         registerVar(pVar);      
<a name="l00612"></a>00612 }
<a name="l00613"></a>00613 
<a name="l00614"></a>00614 <span class="keywordtype">void</span> MTParserRegistrar::registerVar(<a class="code" href="classMTVariableI.html">MTVariableI</a> *pVar)
<a name="l00615"></a>00615 {
<a name="l00616"></a>00616         SVariableInfo *pVarInfo = <span class="keyword">new</span> SVariableInfo;    
<a name="l00617"></a>00617         pVarInfo-&gt;pVar = pVar;  
<a name="l00618"></a>00618         pVarInfo-&gt;index = m_variableList.size();
<a name="l00619"></a>00619         
<a name="l00620"></a>00620         m_variableList.push_back(pVarInfo);
<a name="l00621"></a>00621         m_variableMap.insert(TVariableMap::value_type(pVar-&gt;<a class="code" href="classMTParserItemI.html#a1">getSymbol</a>(), pVarInfo));
<a name="l00622"></a>00622 }
<a name="l00623"></a>00623 
<a name="l00624"></a>00624 <span class="keyword">const</span> MTParserRegistrar::SVariableInfo* MTParserRegistrar::getVarInfo(<span class="keyword">const</span> <a class="code" href="MTUnicodeANSIDefs_8h.html#a0">MTSTRING</a> &amp;varName)<span class="keyword">const</span>
<a name="l00625"></a>00625 <span class="keyword"></span>{               
<a name="l00626"></a>00626         TVariableMap::const_iterator it = m_variableMap.find(varName);
<a name="l00627"></a>00627         <span class="keywordflow">if</span>( it !=  m_variableMap.end() )
<a name="l00628"></a>00628         {
<a name="l00629"></a>00629                 <span class="keywordflow">return</span> (*it).second;
<a name="l00630"></a>00630         }
<a name="l00631"></a>00631         <span class="keywordflow">else</span>
<a name="l00632"></a>00632         {
<a name="l00633"></a>00633                 <span class="keywordflow">return</span> NULL;    <span class="comment">// variable not found</span>
<a name="l00634"></a>00634         }
<a name="l00635"></a>00635 }
<a name="l00636"></a>00636 
<a name="l00637"></a>00637 <span class="keywordtype">void</span> MTParserRegistrar::defValidateVar(<span class="keyword">const</span> <a class="code" href="MTUnicodeANSIDefs_8h.html#a0">MTSTRING</a> &amp;varName)<span class="keyword">const</span> <span class="keywordflow">throw</span>(<a class="code" href="classMTChainedExceptions.html">MTParserException</a>)
<a name="l00638"></a>00638 {
<a name="l00639"></a>00639 
<a name="l00640"></a>00640         <span class="comment">// variable name can't be null</span>
<a name="l00641"></a>00641         <span class="keywordflow">if</span>( varName.size() == 0 )
<a name="l00642"></a>00642         {
<a name="l00643"></a>00643                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a13">MTDEFEXCEP_VarNameNull</a>, varName);         
<a name="l00644"></a>00644         }
<a name="l00645"></a>00645 
<a name="l00646"></a>00646         <span class="comment">// variable name cannot contains space characters</span>
<a name="l00647"></a>00647         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> pos;
<a name="l00648"></a>00648         <span class="keywordflow">if</span>( <a class="code" href="namespaceMTTools.html#a1">MTTools::findSubStr</a>(varName, _T(<span class="stringliteral">" "</span>), pos) )
<a name="l00649"></a>00649         {
<a name="l00650"></a>00650                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a14">MTDEFEXCEP_VarNameSpace</a>, varName);                
<a name="l00651"></a>00651         }
<a name="l00652"></a>00652 
<a name="l00653"></a>00653         <span class="comment">// variable name cannot be used twice!</span>
<a name="l00654"></a>00654         <span class="keywordflow">if</span>( isVarDefined(varName.c_str()) != NULL )
<a name="l00655"></a>00655         {               
<a name="l00656"></a>00656                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a12">MTDEFEXCEP_VarAlreadyDefined</a>, varName);
<a name="l00657"></a>00657         }
<a name="l00658"></a>00658 
<a name="l00659"></a>00659         <span class="comment">// variable name cannot contain only numbers... </span>
<a name="l00660"></a>00660         <span class="keywordflow">if</span>( <a class="code" href="namespaceMTTools.html#a7">MTTools::isOnlyNum</a>(varName, m_syntax.decimalPoint) )
<a name="l00661"></a>00661         {               
<a name="l00662"></a>00662                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a15">MTDEFEXCEP_VarNameOnlyNum</a>, varName);
<a name="l00663"></a>00663         }       
<a name="l00664"></a>00664 
<a name="l00665"></a>00665         <span class="comment">// variable name must not be a constant name...</span>
<a name="l00666"></a>00666         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> index;
<a name="l00667"></a>00667         <span class="keywordflow">if</span>( findConst(varName.c_str(), index) )
<a name="l00668"></a>00668         {
<a name="l00669"></a>00669                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a16">MTDEFEXCEP_VarNameConstConflict</a>, varName);
<a name="l00670"></a>00670         }
<a name="l00671"></a>00671 
<a name="l00672"></a>00672         <span class="comment">// variable name cannot contain syntax character...</span>
<a name="l00673"></a>00673         <a class="code" href="MTUnicodeANSIDefs_8h.html#a1">MTCHAR</a> syntaxConflict;
<a name="l00674"></a>00674         <span class="keywordflow">if</span>( !defValidateSyntaxConflict(getSyntax(), varName, syntaxConflict) )
<a name="l00675"></a>00675         {
<a name="l00676"></a>00676                 <a class="code" href="MTUnicodeANSIDefs_8h.html#a0">MTSTRING</a> conflictStr;
<a name="l00677"></a>00677                 conflictStr = syntaxConflict;
<a name="l00678"></a>00678                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a17">MTDEFEXCEP_VarNameSyntaxConflict</a>, varName, conflictStr);
<a name="l00679"></a>00679         }
<a name="l00680"></a>00680         
<a name="l00681"></a>00681         <span class="comment">// variable name cannot contains operator characters...</span>
<a name="l00682"></a>00682         <a class="code" href="MTUnicodeANSIDefs_8h.html#a0">MTSTRING</a> opConflict;
<a name="l00683"></a>00683         <span class="keywordflow">if</span>( !defValidateOpSymbolConflict(varName, opConflict) )
<a name="l00684"></a>00684         {
<a name="l00685"></a>00685                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a18">MTDEFEXCEP_VarNameOpConflict</a>, varName, opConflict);
<a name="l00686"></a>00686 
<a name="l00687"></a>00687         }
<a name="l00688"></a>00688 }
<a name="l00689"></a>00689 
<a name="l00690"></a><a class="code" href="classMTParserRegistrar.html#a3">00690</a> <span class="keywordtype">void</span> <a class="code" href="classMTParserRegistrar.html#a3">MTParserRegistrar::redefineVar</a>(<a class="code" href="classMTVariableI.html">MTVariableI</a> *pVar) <span class="keywordflow">throw</span>(<a class="code" href="classMTChainedExceptions.html">MTParserException</a>)
<a name="l00691"></a>00691 {
<a name="l00692"></a>00692         <span class="comment">// try to find the variable and REPLACE it</span>
<a name="l00693"></a>00693         TVariableMap::iterator it = m_variableMap.find(pVar-&gt;<a class="code" href="classMTParserItemI.html#a1">getSymbol</a>());
<a name="l00694"></a>00694         <span class="keywordflow">if</span>( it !=  m_variableMap.end() )
<a name="l00695"></a>00695         {
<a name="l00696"></a>00696                 <span class="keyword">delete</span> (*it).second-&gt;pVar;              <span class="comment">// delete the old object</span>
<a name="l00697"></a>00697                 (*it).second-&gt;pVar = pVar;              <span class="comment">// put the new one                                                              </span>
<a name="l00698"></a>00698         }
<a name="l00699"></a>00699         <span class="keywordflow">else</span>
<a name="l00700"></a>00700         {
<a name="l00701"></a>00701                 <span class="comment">// variable not found...</span>
<a name="l00702"></a>00702                 <a class="code" href="MTUnicodeANSIDefs_8h.html#a0">MTSTRING</a> symbol = pVar-&gt;<a class="code" href="classMTParserItemI.html#a1">getSymbol</a>();
<a name="l00703"></a>00703                 <span class="keyword">delete</span> pVar;    <span class="comment">// delete it because we own it</span>
<a name="l00704"></a>00704                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a6">MTDEFEXCEP_ItemNotFound</a>, symbol);
<a name="l00705"></a>00705         }
<a name="l00706"></a>00706 }
<a name="l00707"></a>00707 
<a name="l00708"></a><a class="code" href="classMTParserRegistrar.html#a4">00708</a> <span class="keywordtype">void</span> <a class="code" href="classMTParserRegistrar.html#a4">MTParserRegistrar::undefineVar</a>(<span class="keyword">const</span> <a class="code" href="MTUnicodeANSIDefs_8h.html#a1">MTCHAR</a> *symbol) <span class="keywordflow">throw</span>(<a class="code" href="classMTChainedExceptions.html">MTParserException</a>)
<a name="l00709"></a>00709 {       
<a name="l00710"></a>00710         <span class="comment">// try to find the variable and delete it</span>
<a name="l00711"></a>00711         TVariableMap::iterator it = m_variableMap.find(symbol);
<a name="l00712"></a>00712         <span class="keywordflow">if</span>( it !=  m_variableMap.end() )
<a name="l00713"></a>00713         {
<a name="l00714"></a>00714                 <span class="keyword">delete</span> (*it).second-&gt;pVar;
<a name="l00715"></a>00715                 (*it).second-&gt;pVar = NULL;                              
<a name="l00716"></a>00716 
<a name="l00717"></a>00717                 m_variableList.erase(m_variableList.begin()+(*it).second-&gt;index);       <span class="comment">// use the up-to-date key       </span>
<a name="l00718"></a>00718                 <span class="keyword">delete</span> (*it).second;
<a name="l00719"></a>00719 
<a name="l00720"></a>00720                 m_variableMap.erase(it);                                
<a name="l00721"></a>00721 
<a name="l00722"></a>00722                 m_varKeyVersion++;      <span class="comment">// invalidate all variable keys</span>
<a name="l00723"></a>00723                 updateVarKeys();
<a name="l00724"></a>00724                                                                 
<a name="l00725"></a>00725         }
<a name="l00726"></a>00726         <span class="keywordflow">else</span>
<a name="l00727"></a>00727         {
<a name="l00728"></a>00728                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a6">MTDEFEXCEP_ItemNotFound</a>, symbol); <span class="comment">// variable not found</span>
<a name="l00729"></a>00729         }
<a name="l00730"></a>00730 
<a name="l00731"></a>00731 }
<a name="l00732"></a>00732 
<a name="l00733"></a><a class="code" href="classMTParserRegistrar.html#a24">00733</a> <span class="keywordtype">bool</span> <a class="code" href="classMTParserRegistrar.html#a24">MTParserRegistrar::isVarDefined</a>(<span class="keyword">const</span> <a class="code" href="MTUnicodeANSIDefs_8h.html#a1">MTCHAR</a> *symbol)<span class="keyword">const</span>
<a name="l00734"></a>00734 <span class="keyword"></span>{
<a name="l00735"></a>00735         <span class="keywordflow">return</span> getVarInfo(symbol) != NULL;
<a name="l00736"></a>00736 }
<a name="l00737"></a>00737         
<a name="l00738"></a><a class="code" href="classMTParserRegistrar.html#a6">00738</a> <a class="code" href="classMTVariableI.html">MTVariableI</a>* <a class="code" href="classMTParserRegistrar.html#a6">MTParserRegistrar::getVarBySymbol</a>(<span class="keyword">const</span> <a class="code" href="MTUnicodeANSIDefs_8h.html#a1">MTCHAR</a> *symbol)<span class="keyword">const</span> <span class="keywordflow">throw</span>(<a class="code" href="classMTChainedExceptions.html">MTParserException</a>)
<a name="l00739"></a>00739 {
<a name="l00740"></a>00740         <span class="keyword">const</span> SVariableInfo* pInfo = getVarInfo(symbol);
<a name="l00741"></a>00741 
<a name="l00742"></a>00742         <span class="keywordflow">if</span>( pInfo == NULL )
<a name="l00743"></a>00743         {
<a name="l00744"></a>00744                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a6">MTDEFEXCEP_ItemNotFound</a>, symbol);
<a name="l00745"></a>00745         }
<a name="l00746"></a>00746 
<a name="l00747"></a>00747         <span class="keywordflow">return</span> pInfo-&gt;pVar;
<a name="l00748"></a>00748 }
<a name="l00749"></a>00749 
<a name="l00750"></a><a class="code" href="classMTParserRegistrar.html#a7">00750</a> <a class="code" href="classMTVariableI.html">MTVariableI</a>* <a class="code" href="classMTParserRegistrar.html#a7">MTParserRegistrar::getVar</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> index)<span class="keyword">const</span> <span class="keywordflow">throw</span>(<a class="code" href="classMTChainedExceptions.html">MTParserException</a>)
<a name="l00751"></a>00751 {
<a name="l00752"></a>00752         <span class="keywordflow">return</span> getVarBySymbol(getVarSymbol(index).c_str());
<a name="l00753"></a>00753 }
<a name="l00754"></a>00754 
<a name="l00755"></a><a class="code" href="classMTParserRegistrar.html#a8">00755</a> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> <a class="code" href="classMTParserRegistrar.html#a8">MTParserRegistrar::getNbDefinedVars</a>()<span class="keyword">const</span>
<a name="l00756"></a>00756 <span class="keyword"></span>{
<a name="l00757"></a>00757         <span class="keywordflow">return</span> m_variableList.size();
<a name="l00758"></a>00758 }
<a name="l00759"></a>00759 <a class="code" href="MTUnicodeANSIDefs_8h.html#a0">MTSTRING</a> MTParserRegistrar::getVarSymbol(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> index)<span class="keyword">const</span> <span class="keywordflow">throw</span>(<a class="code" href="classMTChainedExceptions.html">MTParserException</a>)
<a name="l00760"></a>00760 {
<a name="l00761"></a>00761         <span class="keywordflow">if</span>( index &lt; 0 || index &gt;= m_variableList.size() )
<a name="l00762"></a>00762         {
<a name="l00763"></a>00763                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a6">MTDEFEXCEP_ItemNotFound</a>, index);  
<a name="l00764"></a>00764         }
<a name="l00765"></a>00765 
<a name="l00766"></a>00766         <span class="keywordflow">return</span> m_variableList[index]-&gt;pVar-&gt;getSymbol();
<a name="l00767"></a>00767 }
<a name="l00768"></a>00768 
<a name="l00769"></a>00769 <span class="keywordtype">void</span> MTParserRegistrar::updateVarKeys()
<a name="l00770"></a>00770 {
<a name="l00771"></a>00771         std::vector&lt;SVariableInfo*&gt;::iterator it = m_variableList.begin();
<a name="l00772"></a>00772         std::vector&lt;SVariableInfo*&gt;::iterator end = m_variableList.end();
<a name="l00773"></a>00773 
<a name="l00774"></a>00774         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> t=0;
<a name="l00775"></a>00775         
<a name="l00776"></a>00776         <span class="keywordflow">for</span>( ; it!=end; it++ )
<a name="l00777"></a>00777         {
<a name="l00778"></a>00778                 (*it)-&gt;index = t;
<a name="l00779"></a>00779                 t++;
<a name="l00780"></a>00780         }
<a name="l00781"></a>00781 }
<a name="l00782"></a>00782 
<a name="l00783"></a>00783 
<a name="l00784"></a><a class="code" href="classMTParserRegistrar.html#a26">00784</a> <span class="keywordtype">bool</span> <a class="code" href="classMTParserRegistrar.html#a26">MTParserRegistrar::isAFunction</a>(<span class="keyword">const</span> <a class="code" href="MTUnicodeANSIDefs_8h.html#a1">MTCHAR</a> *word, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> &amp;index)<span class="keyword">const</span>
<a name="l00785"></a>00785 <span class="keyword"></span>{
<a name="l00786"></a>00786         <span class="keywordflow">if</span>( m_funcMap.count(word) &gt; 0 )
<a name="l00787"></a>00787         {
<a name="l00788"></a>00788                 <span class="comment">// return the first function with this symbol</span>
<a name="l00789"></a>00789                 index = (*m_funcMap.find(word)).second;
<a name="l00790"></a>00790                 <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00791"></a>00791         }
<a name="l00792"></a>00792         <span class="keywordflow">else</span>
<a name="l00793"></a>00793         {
<a name="l00794"></a>00794                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00795"></a>00795         }
<a name="l00796"></a>00796 }
<a name="l00797"></a>00797 
<a name="l00798"></a><a class="code" href="classMTParserRegistrar.html#a27">00798</a> <span class="keywordtype">bool</span> <a class="code" href="classMTParserRegistrar.html#a27">MTParserRegistrar::findFunction</a>(<span class="keyword">const</span> <a class="code" href="MTUnicodeANSIDefs_8h.html#a1">MTCHAR</a> *word, <span class="keywordtype">int</span> nbArgs, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> &amp;index)<span class="keyword">const</span>
<a name="l00799"></a>00799 <span class="keyword"></span>{       
<a name="l00800"></a>00800         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nbFuncs = m_funcMap.count(word);
<a name="l00801"></a>00801 
<a name="l00802"></a>00802         <span class="keywordflow">if</span>( nbFuncs == 0 )
<a name="l00803"></a>00803         {
<a name="l00804"></a>00804                 <span class="keywordflow">return</span> <span class="keyword">false</span>;   <span class="comment">// no function with this name</span>
<a name="l00805"></a>00805         }
<a name="l00806"></a>00806         
<a name="l00807"></a>00807         <span class="keywordtype">int</span> undefNbArgs = -1;
<a name="l00808"></a>00808         TFuncMap::const_iterator it = m_funcMap.find(word);
<a name="l00809"></a>00809 
<a name="l00810"></a>00810         <span class="keywordflow">for</span>( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> t=0; t&lt;nbFuncs; t++ )
<a name="l00811"></a>00811         {
<a name="l00812"></a>00812                 <span class="keywordflow">if</span>( m_funcList[(*it).second].pFunc-&gt;getNbArgs() == <a class="code" href="MTParserPublic_8h.html#a10">c_MTNbArgUndefined</a> &amp;&amp; nbArgs &gt; 0)
<a name="l00813"></a>00813                 {
<a name="l00814"></a>00814                         <span class="comment">// take this function if no exact match</span>
<a name="l00815"></a>00815                         <span class="comment">// the requested number of arguments</span>
<a name="l00816"></a>00816                         undefNbArgs = (*it).second;                                     
<a name="l00817"></a>00817                 }
<a name="l00818"></a>00818                 <span class="keywordflow">else</span> <span class="keywordflow">if</span>( m_funcList[(*it).second].pFunc-&gt;getNbArgs() == nbArgs) 
<a name="l00819"></a>00819                 {                       
<a name="l00820"></a>00820                         <span class="comment">// exact macth! take that function</span>
<a name="l00821"></a>00821                         index = (*it).second;
<a name="l00822"></a>00822                         <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00823"></a>00823                 }
<a name="l00824"></a>00824 
<a name="l00825"></a>00825                 it++;
<a name="l00826"></a>00826         }
<a name="l00827"></a>00827 
<a name="l00828"></a>00828         <span class="keywordflow">if</span>( undefNbArgs != -1 )
<a name="l00829"></a>00829         {
<a name="l00830"></a>00830                 <span class="comment">// return the default function with undefined number</span>
<a name="l00831"></a>00831                 <span class="comment">// of arguments</span>
<a name="l00832"></a>00832                 index = undefNbArgs;
<a name="l00833"></a>00833                 <span class="keywordflow">return</span> <span class="keyword">true</span>;            
<a name="l00834"></a>00834         }
<a name="l00835"></a>00835         <span class="keywordflow">else</span>
<a name="l00836"></a>00836         {
<a name="l00837"></a>00837                 <span class="keywordflow">return</span> <span class="keyword">false</span>; <span class="comment">// no function found</span>
<a name="l00838"></a>00838         }
<a name="l00839"></a>00839 }
<a name="l00840"></a>00840 
<a name="l00841"></a><a class="code" href="classMTParserRegistrar.html#a28">00841</a> std::vector&lt;MTFunctionI*&gt; <a class="code" href="classMTParserRegistrar.html#a28">MTParserRegistrar::findFunctions</a>(<span class="keyword">const</span> <a class="code" href="MTUnicodeANSIDefs_8h.html#a1">MTCHAR</a> *symbol)<span class="keyword">const</span>
<a name="l00842"></a>00842 <span class="keyword"></span>{
<a name="l00843"></a>00843         std::vector&lt;MTFunctionI*&gt; functions;
<a name="l00844"></a>00844 
<a name="l00845"></a>00845         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nbFuncs = m_funcMap.count(symbol);
<a name="l00846"></a>00846 
<a name="l00847"></a>00847         TFuncMap::const_iterator it = m_funcMap.find(symbol);
<a name="l00848"></a>00848 
<a name="l00849"></a>00849         <span class="keywordflow">for</span>( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> t=0; t&lt;nbFuncs; t++ )
<a name="l00850"></a>00850         {
<a name="l00851"></a>00851                 functions.push_back(<a class="code" href="classMTParserRegistrar.html#a20">getFunc</a>((*it).second));
<a name="l00852"></a>00852                 it++;
<a name="l00853"></a>00853         }
<a name="l00854"></a>00854 
<a name="l00855"></a>00855         <span class="keywordflow">return</span> functions;
<a name="l00856"></a>00856 }
<a name="l00857"></a>00857 
<a name="l00858"></a><a class="code" href="classMTParserRegistrar.html#a29">00858</a> <span class="keywordtype">bool</span> <a class="code" href="classMTParserRegistrar.html#a29">MTParserRegistrar::findFunctionExact</a>(<span class="keyword">const</span> <a class="code" href="MTUnicodeANSIDefs_8h.html#a1">MTCHAR</a> *word, <span class="keywordtype">int</span> nbArgs, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> &amp;index)<span class="keyword">const</span>
<a name="l00859"></a>00859 <span class="keyword"></span>{
<a name="l00860"></a>00860 
<a name="l00861"></a>00861         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nbFuncs = m_funcMap.count(word);
<a name="l00862"></a>00862 
<a name="l00863"></a>00863         <span class="keywordflow">if</span>( nbFuncs == 0 )
<a name="l00864"></a>00864         {
<a name="l00865"></a>00865                 <span class="keywordflow">return</span> <span class="keyword">false</span>;   <span class="comment">// no function with this name</span>
<a name="l00866"></a>00866         }
<a name="l00867"></a>00867 
<a name="l00868"></a>00868         TFuncMap::const_iterator it = m_funcMap.find(word);
<a name="l00869"></a>00869 
<a name="l00870"></a>00870         <span class="keywordflow">for</span>( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> t=0; t&lt;nbFuncs; t++ )
<a name="l00871"></a>00871         {
<a name="l00872"></a>00872                 <span class="keywordflow">if</span>( m_funcList[(*it).second].pFunc-&gt;getNbArgs() == nbArgs) 
<a name="l00873"></a>00873                 {                       
<a name="l00874"></a>00874                         <span class="comment">// exact macth! take that function</span>
<a name="l00875"></a>00875                         index = (*it).second;
<a name="l00876"></a>00876                         <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00877"></a>00877                 }
<a name="l00878"></a>00878 
<a name="l00879"></a>00879                 it++;
<a name="l00880"></a>00880         }
<a name="l00881"></a>00881 
<a name="l00882"></a>00882         <span class="keywordflow">return</span> <span class="keyword">false</span>;   <span class="comment">// no function found</span>
<a name="l00883"></a>00883 }
<a name="l00884"></a>00884 
<a name="l00885"></a><a class="code" href="classMTParserRegistrar.html#a16">00885</a> <a class="code" href="classMTOperatorI.html">MTOperatorI</a>* <a class="code" href="classMTParserRegistrar.html#a16">MTParserRegistrar::getOp</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> index)<span class="keyword">const</span> <span class="keywordflow">throw</span>(<a class="code" href="classMTChainedExceptions.html">MTParserException</a>)
<a name="l00886"></a>00886 {
<a name="l00887"></a>00887         <span class="keywordflow">if</span>( index &lt; 0 || index &gt;= m_opList.size() )
<a name="l00888"></a>00888         {
<a name="l00889"></a>00889                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a6">MTDEFEXCEP_ItemNotFound</a>, index);  
<a name="l00890"></a>00890         }
<a name="l00891"></a>00891 
<a name="l00892"></a>00892         <span class="keywordflow">return</span> m_opList[index].pOp;
<a name="l00893"></a>00893 }
<a name="l00894"></a><a class="code" href="classMTParserRegistrar.html#a20">00894</a> <a class="code" href="classMTFunctionI.html">MTFunctionI</a>* <a class="code" href="classMTParserRegistrar.html#a20">MTParserRegistrar::getFunc</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> index)<span class="keyword">const</span> <span class="keywordflow">throw</span>(<a class="code" href="classMTChainedExceptions.html">MTParserException</a>)
<a name="l00895"></a>00895 {
<a name="l00896"></a>00896         <span class="keywordflow">if</span>( index &lt; 0 || index &gt;= m_funcList.size() )
<a name="l00897"></a>00897         {
<a name="l00898"></a>00898                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a6">MTDEFEXCEP_ItemNotFound</a>, index);  
<a name="l00899"></a>00899         }
<a name="l00900"></a>00900 
<a name="l00901"></a>00901         <span class="keywordflow">return</span> m_funcList[index].pFunc;
<a name="l00902"></a>00902 }
<a name="l00903"></a>00903 
<a name="l00904"></a><a class="code" href="classMTParserRegistrar.html#a13">00904</a> <span class="keywordtype">void</span> <a class="code" href="classMTParserRegistrar.html#a13">MTParserRegistrar::undefineConst</a>(<span class="keyword">const</span> <a class="code" href="MTUnicodeANSIDefs_8h.html#a1">MTCHAR</a> *name) <span class="keywordflow">throw</span>(<a class="code" href="classMTChainedExceptions.html">MTParserException</a>)
<a name="l00905"></a>00905 {       
<a name="l00906"></a>00906         TConstMap::iterator it = m_constMap.find(name);
<a name="l00907"></a>00907         <span class="keywordflow">if</span>( it !=  m_constMap.end() )
<a name="l00908"></a>00908         {       
<a name="l00909"></a>00909                 m_constList.erase(m_constList.begin()+(*it).second);
<a name="l00910"></a>00910                 m_constMap.erase(it);                           
<a name="l00911"></a>00911 
<a name="l00912"></a>00912                 rebuildConstMap();
<a name="l00913"></a>00913         }
<a name="l00914"></a>00914         <span class="keywordflow">else</span>
<a name="l00915"></a>00915         {
<a name="l00916"></a>00916                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a6">MTDEFEXCEP_ItemNotFound</a>, name);
<a name="l00917"></a>00917         }
<a name="l00918"></a>00918 }
<a name="l00919"></a>00919 
<a name="l00920"></a>00920 <span class="keywordtype">void</span> MTParserRegistrar::rebuildConstMap()
<a name="l00921"></a>00921 {
<a name="l00922"></a>00922         m_constMap.clear();
<a name="l00923"></a>00923 
<a name="l00924"></a>00924         
<a name="l00925"></a>00925         <span class="keywordflow">for</span>(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> t=0; t&lt;m_constList.size(); t++ )
<a name="l00926"></a>00926         {
<a name="l00927"></a>00927                 m_constMap.insert(TConstMap::value_type(m_constList[t].name, t));
<a name="l00928"></a>00928         }
<a name="l00929"></a>00929 }
<a name="l00930"></a>00930 
<a name="l00931"></a>00931 
<a name="l00932"></a>00932 
<a name="l00933"></a>00933 <span class="preprocessor">#ifdef _MTPARSER_USE_PLUGIN</span>
<a name="l00934"></a><a class="code" href="classMTParserRegistrar.html#a9">00934</a> <span class="preprocessor"></span><span class="keywordtype">void</span> <a class="code" href="classMTParserRegistrar.html#a9">MTParserRegistrar::loadPlugin</a>(<span class="keyword">const</span> <a class="code" href="MTUnicodeANSIDefs_8h.html#a1">MTCHAR</a> *clsid) <span class="keywordflow">throw</span>(<a class="code" href="classMTChainedExceptions.html">MTParserException</a>)
<a name="l00935"></a>00935 {
<a name="l00936"></a>00936         <span class="comment">// convert the string to a clsid...</span>
<a name="l00937"></a>00937         CLSID nClsid;
<a name="l00938"></a>00938         <span class="keywordflow">if</span>( CLSIDFromString((<span class="keywordtype">wchar_t</span>*)<a class="code" href="MTUnicodeANSIDefs_8h.html#a6">MTSTRINGTOUNICODE</a>(clsid), &amp;nClsid) != NOERROR )
<a name="l00939"></a>00939         {                       
<a name="l00940"></a>00940                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a27">MTDEFEXCEP_PluginNotFound</a>, clsid);                
<a name="l00941"></a>00941         }       
<a name="l00942"></a>00942         
<a name="l00943"></a>00943         <span class="comment">// instanciate the plug-in...</span>
<a name="l00944"></a>00944         IMTParserPluginPtr pPlugin;     
<a name="l00945"></a>00945         HRESULT hRes = pPlugin.CreateInstance(nClsid);
<a name="l00946"></a>00946         <span class="keywordflow">if</span>( FAILED(hRes) )
<a name="l00947"></a>00947         {
<a name="l00948"></a>00948                 <span class="keywordflow">if</span>( hRes == E_NOINTERFACE || 
<a name="l00949"></a>00949                         hRes == 0x80029c4a)             <span class="comment">// error loading type library/DLL</span>
<a name="l00950"></a>00950                 {
<a name="l00951"></a>00951                         <span class="comment">// the most common problem for these errors is the missing tlb file</span>
<a name="l00952"></a>00952                         <span class="comment">// or that the file is not registered</span>
<a name="l00953"></a>00953                         throwDefExcep(<a class="code" href="MTParserException_8h.html#a28">MTDEFEXCEP_PluginTypeLibNotFound</a>, MTPLUGIN_TYPELIBFILE);
<a name="l00954"></a>00954                 }
<a name="l00955"></a>00955                 <span class="keywordflow">else</span>
<a name="l00956"></a>00956                 {
<a name="l00957"></a>00957                         throwDefExcep(<a class="code" href="MTParserException_8h.html#a27">MTDEFEXCEP_PluginNotFound</a>, clsid);                                
<a name="l00958"></a>00958                 }
<a name="l00959"></a>00959                 
<a name="l00960"></a>00960         }       
<a name="l00961"></a>00961 
<a name="l00962"></a>00962         m_pluginPtr.push_back(pPlugin);
<a name="l00963"></a>00963         
<a name="l00964"></a>00964         <span class="keywordflow">try</span>
<a name="l00965"></a>00965         {       
<a name="l00966"></a>00966                 <span class="comment">// validate the parser interface version...</span>
<a name="l00967"></a>00967                 <span class="comment">// because we use directly c++ objects from the plug-in, we must</span>
<a name="l00968"></a>00968                 <span class="comment">// be sure that they implement the righ interfaces.</span>
<a name="l00969"></a>00969                 BSTR version = pPlugin-&gt;getMTParserVersion();
<a name="l00970"></a>00970                 <a class="code" href="MTUnicodeANSIDefs_8h.html#a0">MTSTRING</a> verStr = <a class="code" href="MTUnicodeANSIDefs_8h.html#a5">UNICODETOMTSTRING</a>(version);
<a name="l00971"></a>00971                 SysFreeString(version);
<a name="l00972"></a>00972                 <span class="keywordflow">if</span>( lstrcmp(verStr.c_str(), <a class="code" href="MTParserPublic_8h.html#a2">MTPARSER_INTERFACE_VERSION</a>) != 0 )
<a name="l00973"></a>00973                 {               
<a name="l00974"></a>00974                         <a class="code" href="MTParserPrivate_8h.html#a0">MTTHROW</a>(<a class="code" href="classMTExcepData.html">MTExcepData</a> (   <a class="code" href="MTParserException_8h.html#a26">MTDEFEXCEP_PluginVersion</a>,
<a name="l00975"></a>00975                                                                         <a class="code" href="MTParserException_8h.html#a53">MTEXCEPARG_ITEMNAME</a>, clsid,
<a name="l00976"></a>00976                                                                         <a class="code" href="MTParserException_8h.html#a54">MTEXCEPARG_CONFLICTITEMNAME</a>, <a class="code" href="MTParserPublic_8h.html#a2">MTPARSER_INTERFACE_VERSION</a>,
<a name="l00977"></a>00977                                                                         <a class="code" href="MTParserException_8h.html#a55">MTEXCEPARG_PARAM1</a>, verStr.c_str()))                     
<a name="l00978"></a>00978                 }                       
<a name="l00979"></a>00979                 
<a name="l00980"></a>00980                 <span class="keywordtype">int</span> t;
<a name="l00981"></a>00981 
<a name="l00982"></a>00982                 <span class="keywordflow">try</span>
<a name="l00983"></a>00983                 {
<a name="l00984"></a>00984                         <span class="comment">// constants loading... </span>
<a name="l00985"></a>00985                         <span class="keywordtype">int</span> nbConsts = pPlugin-&gt;getNbConsts();          
<a name="l00986"></a>00986                         
<a name="l00987"></a>00987                         SMTPluginConst constInfo;
<a name="l00988"></a>00988                         
<a name="l00989"></a>00989                         <span class="keywordflow">for</span>( t=0; t&lt;nbConsts; t++ )
<a name="l00990"></a>00990                         {
<a name="l00991"></a>00991                                 constInfo = pPlugin-&gt;getConst(t);
<a name="l00992"></a>00992                                 <a class="code" href="MTUnicodeANSIDefs_8h.html#a0">MTSTRING</a> constName = <a class="code" href="MTUnicodeANSIDefs_8h.html#a5">UNICODETOMTSTRING</a>(constInfo.name);
<a name="l00993"></a>00993                                 defineConst(constName.c_str(), constInfo.val);
<a name="l00994"></a>00994                                 SysFreeString(constInfo.name);  
<a name="l00995"></a>00995                         }
<a name="l00996"></a>00996                         
<a name="l00997"></a>00997                         
<a name="l00998"></a>00998                         <span class="comment">// operators loading...</span>
<a name="l00999"></a>00999                         
<a name="l01000"></a>01000                         <span class="keywordtype">int</span> nbOps = pPlugin-&gt;getNbOps();        
<a name="l01001"></a>01001                         <span class="keywordflow">for</span>( t=0; t&lt;nbOps; t++ )
<a name="l01002"></a>01002                         {                               
<a name="l01003"></a>01003                                 defineOp((<a class="code" href="classMTOperatorI.html">MTOperatorI</a>*)pPlugin-&gt;newOp(t));
<a name="l01004"></a>01004                         }
<a name="l01005"></a>01005                         
<a name="l01006"></a>01006 
<a name="l01007"></a>01007                         <span class="comment">// functions loading... </span>
<a name="l01008"></a>01008                         <span class="keywordtype">int</span> nbFuncs = pPlugin-&gt;getNbFuncs();    
<a name="l01009"></a>01009                         <span class="keywordflow">for</span>( t=0; t&lt;nbFuncs; t++ )
<a name="l01010"></a>01010                         {
<a name="l01011"></a>01011                                 defineFunc((<a class="code" href="classMTFunctionI.html">MTFunctionI</a>*)pPlugin-&gt;newFunc(t));
<a name="l01012"></a>01012                         }
<a name="l01013"></a>01013                 }
<a name="l01014"></a>01014                 <span class="keywordflow">catch</span>( <a class="code" href="classMTChainedExceptions.html">MTParserException</a> &amp;e )
<a name="l01015"></a>01015                 {
<a name="l01016"></a>01016                         <a class="code" href="MTParserPrivate_8h.html#a1">MTRETHROW</a>(<a class="code" href="classMTExcepData.html">MTExcepData</a>(  <a class="code" href="MTParserException_8h.html#a29">MTDEFEXCEP_PluginDefConflict</a>,
<a name="l01017"></a>01017                                                                         <a class="code" href="MTParserException_8h.html#a53">MTEXCEPARG_ITEMNAME</a>, clsid ), e)
<a name="l01018"></a>01018                                                                         
<a name="l01019"></a>01019                 }               
<a name="l01020"></a>01020         }
<a name="l01021"></a>01021         <span class="keywordflow">catch</span>( _com_error )
<a name="l01022"></a>01022         {
<a name="l01023"></a>01023                 <span class="comment">// something is wrong with this plug-in...must be the version!</span>
<a name="l01024"></a>01024                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a26">MTDEFEXCEP_PluginVersion</a>, clsid, <a class="code" href="MTParserPublic_8h.html#a2">MTPARSER_INTERFACE_VERSION</a>);                                     
<a name="l01025"></a>01025         }       
<a name="l01026"></a>01026 }
<a name="l01027"></a>01027 <span class="preprocessor">#endif</span>
<a name="l01028"></a>01028 <span class="preprocessor"></span>
<a name="l01029"></a><a class="code" href="classMTParserRegistrar.html#a10">01029</a> <span class="keywordtype">void</span> <a class="code" href="classMTParserRegistrar.html#a10">MTParserRegistrar::defineConst</a>(<span class="keyword">const</span> <a class="code" href="MTUnicodeANSIDefs_8h.html#a1">MTCHAR</a> *name, <a class="code" href="MTParserPublic_8h.html#a8">MTDOUBLE</a> val) <span class="keywordflow">throw</span>(<a class="code" href="classMTChainedExceptions.html">MTParserException</a>)
<a name="l01030"></a>01030 {
<a name="l01031"></a>01031         <a class="code" href="MTUnicodeANSIDefs_8h.html#a0">MTSTRING</a> constName = name;
<a name="l01032"></a>01032         defValidateConst(constName);
<a name="l01033"></a>01033         
<a name="l01034"></a>01034         registerConst(name, val);
<a name="l01035"></a>01035 
<a name="l01036"></a>01036 }
<a name="l01037"></a>01037 
<a name="l01038"></a>01038 <span class="keywordtype">void</span> MTParserRegistrar::registerConst(<span class="keyword">const</span> <a class="code" href="MTUnicodeANSIDefs_8h.html#a1">MTCHAR</a> *name, <a class="code" href="MTParserPublic_8h.html#a8">MTDOUBLE</a> val)
<a name="l01039"></a>01039 {
<a name="l01040"></a>01040         SConstantInfo constInfo;        
<a name="l01041"></a>01041         constInfo.name = name;
<a name="l01042"></a>01042         constInfo.val = val;    
<a name="l01043"></a>01043         
<a name="l01044"></a>01044         m_constMap.insert(TConstMap::value_type(name, m_constList.size()));
<a name="l01045"></a>01045         m_constList.push_back(constInfo);
<a name="l01046"></a>01046 }
<a name="l01047"></a>01047 
<a name="l01048"></a><a class="code" href="classMTParserRegistrar.html#a30">01048</a> <span class="keywordtype">bool</span> <a class="code" href="classMTParserRegistrar.html#a30">MTParserRegistrar::findConst</a>(<span class="keyword">const</span> <a class="code" href="MTUnicodeANSIDefs_8h.html#a1">MTCHAR</a> *constName, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> &amp;index)<span class="keyword">const</span>
<a name="l01049"></a>01049 <span class="keyword"></span>{
<a name="l01050"></a>01050         TConstMap::const_iterator it = m_constMap.find(constName);
<a name="l01051"></a>01051         <span class="keywordflow">if</span>( it !=  m_constMap.end() )
<a name="l01052"></a>01052         {
<a name="l01053"></a>01053                 index = (*it).second;
<a name="l01054"></a>01054                 <span class="keywordflow">return</span> <span class="keyword">true</span>;    <span class="comment">// constant found</span>
<a name="l01055"></a>01055         }
<a name="l01056"></a>01056         <span class="keywordflow">else</span>
<a name="l01057"></a>01057         {
<a name="l01058"></a>01058                 <span class="keywordflow">return</span> <span class="keyword">false</span>;   <span class="comment">// constant not found</span>
<a name="l01059"></a>01059         }       
<a name="l01060"></a>01060 }
<a name="l01061"></a>01061 <span class="keywordtype">void</span> MTParserRegistrar::defValidateConst(<span class="keyword">const</span> <a class="code" href="MTUnicodeANSIDefs_8h.html#a0">MTSTRING</a> &amp;constName)<span class="keyword">const</span> <span class="keywordflow">throw</span>(<a class="code" href="classMTChainedExceptions.html">MTParserException</a>)
<a name="l01062"></a>01062 {
<a name="l01063"></a>01063 
<a name="l01064"></a>01064         <span class="comment">// constant name can't be null</span>
<a name="l01065"></a>01065         <span class="keywordflow">if</span>( constName.size() == 0 )
<a name="l01066"></a>01066         {
<a name="l01067"></a>01067                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a20">MTDEFEXCEP_ConstNameNull</a>, constName);             
<a name="l01068"></a>01068         }
<a name="l01069"></a>01069 
<a name="l01070"></a>01070         <span class="comment">// constant name cannot contains space characters</span>
<a name="l01071"></a>01071         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> pos;
<a name="l01072"></a>01072         <span class="keywordflow">if</span>( <a class="code" href="namespaceMTTools.html#a1">MTTools::findSubStr</a>(constName, _T(<span class="stringliteral">" "</span>), pos) )
<a name="l01073"></a>01073         {
<a name="l01074"></a>01074                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a21">MTDEFEXCEP_ConstNameSpace</a>, constName);            
<a name="l01075"></a>01075         }
<a name="l01076"></a>01076 
<a name="l01077"></a>01077         <span class="comment">// constant name cannot be used twice!</span>
<a name="l01078"></a>01078         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> index;
<a name="l01079"></a>01079         <span class="keywordflow">if</span>( findConst(constName.c_str(), index) )
<a name="l01080"></a>01080         {               
<a name="l01081"></a>01081                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a19">MTDEFEXCEP_ConstAlreadyDefined</a>, constName);
<a name="l01082"></a>01082         }
<a name="l01083"></a>01083 
<a name="l01084"></a>01084         <span class="comment">// constant name cannot contains only numbers... </span>
<a name="l01085"></a>01085         <span class="keywordflow">if</span>( <a class="code" href="namespaceMTTools.html#a7">MTTools::isOnlyNum</a>(constName, m_syntax.decimalPoint) )
<a name="l01086"></a>01086         {               
<a name="l01087"></a>01087                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a22">MTDEFEXCEP_ConstNameOnlyNum</a>, constName);
<a name="l01088"></a>01088         }
<a name="l01089"></a>01089 
<a name="l01090"></a>01090         <span class="comment">// constant name cannot contains syntax element characters...</span>
<a name="l01091"></a>01091         <a class="code" href="MTUnicodeANSIDefs_8h.html#a1">MTCHAR</a> syntaxConflict;
<a name="l01092"></a>01092         <span class="keywordflow">if</span>( !defValidateSyntaxConflict(getSyntax(), constName, syntaxConflict) )
<a name="l01093"></a>01093         {
<a name="l01094"></a>01094                 <a class="code" href="MTUnicodeANSIDefs_8h.html#a0">MTSTRING</a> conflictStr;
<a name="l01095"></a>01095                 conflictStr = syntaxConflict;
<a name="l01096"></a>01096                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a23">MTDEFEXCEP_ConstNameSyntaxConflict</a>, constName, conflictStr);
<a name="l01097"></a>01097         }
<a name="l01098"></a>01098 
<a name="l01099"></a>01099         <span class="comment">// constant name cannot contains operator characters...</span>
<a name="l01100"></a>01100         <a class="code" href="MTUnicodeANSIDefs_8h.html#a0">MTSTRING</a> opConflict;
<a name="l01101"></a>01101         <span class="keywordflow">if</span>( !defValidateOpSymbolConflict(constName, opConflict) )
<a name="l01102"></a>01102         {
<a name="l01103"></a>01103                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a24">MTDEFEXCEP_ConstNameOpConflict</a>, constName, opConflict);
<a name="l01104"></a>01104         }
<a name="l01105"></a>01105 
<a name="l01106"></a>01106         <span class="comment">// no variable can have the same name as this constant...</span>
<a name="l01107"></a>01107         <span class="keywordflow">if</span>( isVarDefined(constName.c_str()) != NULL )
<a name="l01108"></a>01108         {
<a name="l01109"></a>01109                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a25">MTDEFEXCEP_ConstNameVarConflict</a>, constName);
<a name="l01110"></a>01110         }
<a name="l01111"></a>01111 
<a name="l01112"></a>01112 }
<a name="l01113"></a>01113 
<a name="l01114"></a><a class="code" href="classMTParserRegistrar.html#a11">01114</a> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> <a class="code" href="classMTParserRegistrar.html#a11">MTParserRegistrar::getNbDefinedConsts</a>()<span class="keyword">const</span>
<a name="l01115"></a>01115 <span class="keyword"></span>{
<a name="l01116"></a>01116         <span class="keywordflow">return</span> m_constList.size();
<a name="l01117"></a>01117 }
<a name="l01118"></a>01118 
<a name="l01119"></a><a class="code" href="classMTParserRegistrar.html#a12">01119</a> <span class="keywordtype">void</span> <a class="code" href="classMTParserRegistrar.html#a12">MTParserRegistrar::getConst</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> index, <a class="code" href="MTUnicodeANSIDefs_8h.html#a0">MTSTRING</a> &amp;constName, <a class="code" href="MTParserPublic_8h.html#a8">MTDOUBLE</a> &amp;val)<span class="keyword">const</span> <span class="keywordflow">throw</span>(<a class="code" href="classMTChainedExceptions.html">MTParserException</a>)
<a name="l01120"></a>01120 {
<a name="l01121"></a>01121         <span class="keywordflow">if</span>( index &lt; 0 || index &gt;= m_constList.size() )
<a name="l01122"></a>01122         {
<a name="l01123"></a>01123                 throwDefExcep(<a class="code" href="MTParserException_8h.html#a6">MTDEFEXCEP_ItemNotFound</a>, index);  
<a name="l01124"></a>01124         }
<a name="l01125"></a>01125         
<a name="l01126"></a>01126         constName = m_constList[index].name;
<a name="l01127"></a>01127         val = m_constList[index].val;
<a name="l01128"></a>01128 }
<a name="l01129"></a>01129 
<a name="l01130"></a>01130 <span class="keywordtype">void</span> MTParserRegistrar::throwDefExcep(<span class="keyword">const</span> <a class="code" href="MTUnicodeANSIDefs_8h.html#a1">MTCHAR</a> * <span class="keywordtype">id</span>, <a class="code" href="MTUnicodeANSIDefs_8h.html#a0">MTSTRING</a> itemName, <a class="code" href="MTUnicodeANSIDefs_8h.html#a0">MTSTRING</a> conflictItemName)<span class="keyword">const</span> <span class="keywordflow">throw</span>(<a class="code" href="classMTChainedExceptions.html">MTParserException</a>)
<a name="l01131"></a>01131 {
<a name="l01132"></a>01132         <a class="code" href="classMTExcepData.html">MTExcepData</a> data(       <span class="keywordtype">id</span>,
<a name="l01133"></a>01133                                                 <a class="code" href="MTParserException_8h.html#a53">MTEXCEPARG_ITEMNAME</a>, itemName.c_str(),
<a name="l01134"></a>01134                                                 <a class="code" href="MTParserException_8h.html#a54">MTEXCEPARG_CONFLICTITEMNAME</a>, conflictItemName.c_str() );
<a name="l01135"></a>01135         
<a name="l01136"></a>01136         <a class="code" href="MTParserPrivate_8h.html#a0">MTTHROW</a>(data)
<a name="l01137"></a>01137 }
<a name="l01138"></a>01138 
<a name="l01139"></a>01139 <span class="keywordtype">void</span> MTParserRegistrar::throwDefExcep(<span class="keyword">const</span> <a class="code" href="MTUnicodeANSIDefs_8h.html#a1">MTCHAR</a> * <span class="keywordtype">id</span>, <span class="keywordtype">int</span> param)<span class="keyword">const</span> <span class="keywordflow">throw</span>(<a class="code" href="classMTChainedExceptions.html">MTParserException</a>)
<a name="l01140"></a>01140 {
<a name="l01141"></a>01141         <a class="code" href="classMTExcepData.html">MTExcepData</a> data(       <span class="keywordtype">id</span>,
<a name="l01142"></a>01142                                                 <a class="code" href="MTParserException_8h.html#a55">MTEXCEPARG_PARAM1</a>, <a class="code" href="namespaceMTTools.html#a14">MTTools::longToS</a>(param).c_str() );                                           
<a name="l01143"></a>01143 
<a name="l01144"></a>01144         <a class="code" href="MTParserPrivate_8h.html#a0">MTTHROW</a>(data)
<a name="l01145"></a>01145 }
</pre></div><hr size="1"><address style="align: right;"><small>Generated on Sun Mar 9 17:39:36 2008 for MTParserLib by&nbsp;
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.4 </small></address>
</body>
</html>

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Canada Canada
Software Engineer working at a fun and smart startup company

Comments and Discussions