00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "docviewprec.h"
00014
00015 #include "wx/docview/cparser.h"
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 a2dCommand_Error::a2dCommand_Error( const wxString& message, const wxString& header )
00029 {
00030 m_message = message;
00031 m_header = header;
00032 }
00033
00034 a2dCommand_Error::a2dCommand_Error(const a2dCommand_Error& a)
00035 {
00036 m_message = a.m_message;
00037 m_header = a.m_header;
00038 }
00039
00040 #define LINELENGTH 200
00041
00042 a2dCommandParser::a2dCommandParser()
00043 {
00044 m_error_mes.Clear();
00045 m_error_mes.Alloc(LINELENGTH);
00046 m_commandsofar.Clear();
00047 m_commandsofar.Alloc(LINELENGTH);
00048 m_b.Clear();
00049 m_b.Alloc(LINELENGTH);
00050 m_varref.Clear();
00051 m_varref.Alloc(LINELENGTH);
00052 FlushArg();
00053 m_linenumber=0;
00054 }
00055
00056 a2dCommandParser::~a2dCommandParser()
00057 {
00058 FlushArg();
00059 }
00060
00061 wxString a2dCommandParser::GetCommandParsed()
00062 {
00063 return m_commandsofar;
00064 }
00065
00066 bool a2dCommandParser::FlushArg()
00067 {
00068 m_commandsofar.Empty();
00069 m_argumentlist.DeleteAll();
00070 m_item = 0;
00071
00072 return true;
00073 }
00074
00075 wxString a2dCommandParser::GetItem( int i)
00076 {
00077 static wxString non = wxT("");
00078 if ( i < m_argumentlist.GetCount() )
00079 return m_argumentlist.GetVariableAsString(i);
00080 return non;
00081 }
00082
00083 a2dNamedProperty* a2dCommandParser::GetProperty( int i)
00084 {
00085 return const_cast<a2dNamedProperty*>( &(m_argumentlist.GetVariable(i)) );
00086 }
00087
00088 wxString a2dCommandParser::GetNextItem()
00089 {
00090 static wxString non = wxT("");
00091 if ( m_item < m_argumentlist.GetCount() )
00092 return m_argumentlist.GetVariableAsString( m_item++ );
00093 m_item++;
00094 return non;
00095 }
00096
00097 a2dNamedProperty* a2dCommandParser::GetNextProp()
00098 {
00099 if ( m_item < m_argumentlist.GetCount() )
00100 return const_cast<a2dNamedProperty*>( &(m_argumentlist.GetVariable( m_item++ )) );
00101 m_item++;
00102 return NULL;
00103 }
00104
00105 bool a2dCommandParser::GetNextItemBool()
00106 {
00107 if ( GetNextItem().IsSameAs( wxT("true"), false) )
00108 return true;
00109
00110 return false;
00111 }
00112
00113 int a2dCommandParser::GetNextItemInt()
00114 {
00115 a2dNamedProperty* prop = GetNextProp();
00116 if ( prop )
00117 {
00118 if ( wxDynamicCast( prop, a2dInt32Property ) == 0 )
00119 {
00120 a2dGeneralGlobals->ReportErrorF( a2dError_CommandError, _("Not derived from a2dInt32Property") );
00121 return 0;
00122 }
00123 return wxStaticCast( prop, a2dInt32Property )->GetValue();
00124 }
00125 return 0;
00126 }
00127
00128 double a2dCommandParser::GetNextItemDouble()
00129 {
00130 a2dNamedProperty* prop = GetNextProp();
00131 if ( prop )
00132 {
00133 if ( wxDynamicCast( prop, a2dDoubleProperty ) == 0 )
00134 {
00135 a2dGeneralGlobals->ReportErrorF( a2dError_CommandError, _("Not derived from a2dDoubleProperty") );
00136 return 0;
00137 }
00138 return wxStaticCast( prop, a2dDoubleProperty)->GetValue();
00139 }
00140 return 0;
00141 }
00142
00143 bool a2dCommandParser::GetCommand()
00144 {
00145 m_error_mes.Empty();
00146 m_commandsofar.Empty();
00147
00148 if (!m_linenumber)
00149 m_linenumber++;
00150
00151 IncC();
00152 while(a == wxT('\n') )
00153 {
00154 m_commandsofar.Empty();
00155 IncC();
00156 m_linenumber++;
00157 }
00158
00159 Blanks();
00160
00161 if (a == wxT('\0') )
00162 return false;
00163
00164 else if (a == wxT('#') )
00165 {
00166 Comment();
00167 if ( a == wxT('\0') || a == wxT('\n') )
00168 m_linenumber++;
00169 }
00170 else
00171 {
00172 while (Word())
00173 {
00174 bool found = Blanks();
00175 if ( !found && !( a == wxT('\0') || a == wxT('\n') || a == wxT(';')) )
00176 {
00177 m_error_mes = wxT(" whitespace expected or end command missing");
00178 return false;
00179 }
00180 if( a == wxT('\0') || a == wxT('\n') || a == wxT(';') )
00181 break;
00182 }
00183
00184 if ( m_error_mes.Len() )
00185 return false;
00186
00187
00188 if( a != wxT('\0') && a != wxT('\n') && a != wxT(';') )
00189 {
00190 m_error_mes = wxT("; or EOL expected");
00191 return false;
00192 }
00193 if ( a == wxT('\0') || a == wxT('\n') )
00194 m_linenumber++;
00195 }
00196
00197 if (a == wxT('\n') )
00198 m_commandsofar.RemoveLast();
00199 return true;
00200 }
00201
00202
00203 bool a2dCommandParser::Word()
00204 {
00205 Blanks();
00206 m_b.Empty();
00207
00208 if (a == wxT('"') )
00209 {
00210 if (!QuotedString())
00211 return false;
00212 if (!m_b.IsEmpty())
00213 {
00214 m_argumentlist.AppendVariableString( m_b );
00215 }
00216 }
00217 else if (a == wxT('{') )
00218 {
00219 if (!BracedString())
00220 return false;
00221 if (!m_b.IsEmpty())
00222 {
00223 m_argumentlist.AppendVariableString( m_b );
00224 }
00225 }
00226 else
00227 {
00228 if ( !MultiPartWord())
00229 return false;
00230
00231 if ( !m_b.IsEmpty() && !Number( m_b ) )
00232 {
00233 m_argumentlist.AppendVariableString( m_b );
00234 }
00235 }
00236
00237 return true;
00238 }
00239
00240 bool a2dCommandParser::Number( const wxString& number )
00241 {
00242 wxString numstr;
00243 bool integer = true;
00244
00245 const wxChar* a = number.GetData();
00246
00247 if ( !( isdigit(*a) || *a == wxT('+') || *a == wxT('-') ) )
00248 return false;
00249
00250 numstr += *a;
00251 a++;
00252
00253 while( isdigit(*a) )
00254 {
00255 numstr += *a;
00256 a++;
00257 }
00258
00259 if( *a == wxT('.') || *a == wxT('e') )
00260 {
00261 integer = false;
00262 numstr += *a;
00263 a++;
00264 if ( !( isdigit(*a) || *a == wxT('+') || *a == wxT('-') ) )
00265 {
00266 return false;
00267 }
00268 numstr += *a;
00269 a++;
00270
00271 while( isdigit(*a) )
00272 {
00273 numstr += *a;
00274 a++;
00275 }
00276
00277
00278 if ( *a == wxT('e') || *a == wxT('E') )
00279 {
00280 numstr += *a;
00281 a++;
00282 if ( !( isdigit(*a) || *a == wxT('+') || *a == wxT('-') ) )
00283 {
00284 return false;
00285 }
00286 numstr += *a;
00287 a++;
00288 while( isdigit(*a) )
00289 {
00290 numstr += *a;
00291 a++;
00292 }
00293 }
00294 }
00295
00296 if( *a != wxT(' ') && *a != wxT('\0') )
00297 return false;
00298
00299 if ( integer )
00300 {
00301 long aint;
00302 numstr.ToLong( &aint , 10 );
00303
00304 m_argumentlist.AppendVariableInt( aint );
00305 }
00306 else
00307 {
00308 double real;
00309 numstr.ToDouble( &real );
00310
00311 wxString argname;
00312 argname.Printf( wxT("%d"), m_argumentlist.GetCount() );
00313 m_argumentlist.AppendVariableDouble( real );
00314 }
00315
00316 return true;
00317 }
00318
00319
00320 bool a2dCommandParser::MultiPartWord()
00321 {
00322 while( a != wxT(' ') && a != wxT('\t') && a != wxT('\0') && a != wxT('\n') && a != wxT(';') )
00323 {
00324 if (a == wxT('\\') )
00325 { IncC();
00326 if ( a == wxT('\n') )
00327 IncC();
00328
00329 if ( a == wxT(' ') || a == wxT('\t') || a == wxT('\0') || a == wxT(';') )
00330 break;
00331
00332
00333 m_b += a;
00334 IncC();
00335 continue;
00336 }
00337
00338 if ( (a == wxT('$') ) || ( a == wxT('%') ))
00339 {
00340 if (!VarRef(a))
00341 return false;
00342 continue;
00343 }
00344
00345
00346 m_b += a;
00347 IncC();
00348 }
00349 return true;
00350 }
00351
00352
00353
00354 bool a2dCommandParser::Comment()
00355 {
00356 if( a != wxT('#') )
00357 {
00358 m_error_mes = wxT("wrong comment");
00359 return false;
00360 }
00361 m_b.Empty();
00362
00363 m_b += a;
00364 IncC();
00365
00366 while( a!= wxT('\0') )
00367 {
00368 if (a== wxT('\\') )
00369 {
00370 IncC();
00371 if (a == wxT('\n') )
00372 {
00373 m_b += wxT(' ');
00374 IncC();
00375 continue;
00376 }
00377 }
00378 if (a == wxT('\n') )
00379 break;
00380
00381 m_b += a;
00382 IncC();
00383 }
00384
00385 m_argumentlist.AppendVariableString( m_b );
00386 return true;
00387 }
00388
00389
00390
00391
00392 bool a2dCommandParser::Blanks()
00393 {
00394 int i=0;
00395
00396 while ( a == wxT(' ') || a == wxT('\t') || a == wxT('\\') || a ==0xd )
00397 {
00398 if ( a == wxT('\\') )
00399 {
00400 if (PeekNextC()!= wxT('\n') )
00401 break;
00402 else
00403 IncC(); i++;
00404 }
00405 IncC(); i++;
00406 }
00407
00408 return (i != 0);
00409 }
00410
00411
00412 wxString a2dCommandParser::GetErrorMes()
00413 {
00414 return m_error_mes;
00415 }
00416
00417
00418
00419 bool a2dCommandParser::Name()
00420 {
00421 m_varref.Empty();
00422 if ( !( isalnum(a) || a == wxT('_') || a == wxT('-') ) )
00423 {
00424 m_error_mes = wxT("wrong name");
00425 return false;
00426 }
00427 m_varref += a;
00428 IncC();
00429 while( isalnum(a) || a == wxT('_') )
00430 {
00431 m_varref+=a;
00432 IncC();
00433 }
00434 return true;
00435 }
00436
00437
00438
00439
00440
00441
00442 bool a2dCommandParser::VarRef( wxChar type)
00443 {
00444 if( a != type )
00445 {
00446 m_error_mes = wxT("wrong environment $ or % missing");
00447 return false;
00448 }
00449
00450 IncC();
00451 if( a == wxT('{') )
00452 {
00453 IncC();
00454 if( !Name() )
00455 return false;
00456 if( a != '}' )
00457 {
00458 m_error_mes = wxT("wrong environment name, end brace missing");
00459 return false;
00460 }
00461 IncC();
00462 }
00463 else
00464 {
00465 if( !Name() )
00466 return false;
00467 }
00468
00469 wxString evaluated;
00470 if (type == wxT('$') )
00471 {
00472 if( !GetEnv(m_varref, evaluated) )
00473 {
00474 m_error_mes = wxT("wrong environment Variable, environment does not exist");
00475 return false;
00476 }
00477 }
00478 else
00479 {
00480 const a2dNamedProperty *prop = m_aliaslist.GetVariable( m_varref );
00481 if( !prop )
00482 {
00483 m_error_mes = wxT("wrong Variable name, Variable does not exist");
00484 return false;
00485 }
00486
00487 evaluated = prop->StringValueRepresentation();
00488 }
00489
00490 m_b += evaluated;
00491 return true;
00492 }
00493
00494
00495 bool a2dCommandParser::QuotedString()
00496 {
00497 if( a != wxT('"') )
00498 {
00499 m_error_mes = wxT("wrong quotedstring, begin quote missing");
00500 return false;
00501 }
00502 IncC();
00503
00504 while( a != wxT('"') && a != wxT('\0') )
00505 {
00506 if (a == wxT('\\') )
00507 { IncC();
00508 if (a == wxT('\0') )
00509 break;
00510
00511 m_b+=a;
00512 IncC();
00513 continue;
00514 }
00515
00516 if ( (a == wxT('$')) || (a == wxT('%')))
00517 {
00518 if (!VarRef(a))
00519 return false;
00520 continue;
00521 }
00522
00523
00524 m_b += a;
00525 IncC();
00526 }
00527
00528 if( a != wxT('"') )
00529 {
00530 m_error_mes = wxT("wrong quotedstring, end quote missing");
00531 return false;
00532 }
00533 IncC();
00534
00535 return true;
00536 }
00537
00538
00539
00540 bool a2dCommandParser::BracedString()
00541 {
00542 if( a != wxT('{') )
00543 {
00544 m_error_mes = wxT("wrong bracedstring, begin brace missing");
00545 return false;
00546 }
00547
00548 IncC();
00549
00550 int brnr=0;
00551 while( (a != wxT('}') || brnr) && a != wxT('\0') )
00552 {
00553 if (a == '\\')
00554 { IncC();
00555 if (a == wxT('\0') )
00556 break;
00557
00558 m_b += a;
00559 IncC();
00560 continue;
00561 }
00562
00563
00564 if (a == wxT('{') )
00565 brnr++;
00566
00567 if (a == wxT('}') )
00568 brnr--;
00569
00570
00571 m_b += a;
00572 IncC();
00573 }
00574
00575 if( a != wxT('}') )
00576 {
00577 m_error_mes = wxT("wrong bracedstring, end brace missing");
00578 return false;
00579 }
00580 IncC();
00581
00582 return true;
00583 }
00584
00585
00586 bool a2dCommandParser::GetEnv(const wxString& envname, wxString& envstring)
00587 {
00588 if (envname.Len()==0)
00589 return false;
00590
00591 if( !wxGetEnv( envname, &envstring ) )
00592 return false;
00593
00594 return true;
00595 }
00596
00597 a2dEvalCommandString::a2dEvalCommandString( const wxString& commandString, a2dVariablesHash& aliaslist)
00598 : wxMemoryInputStream( commandString.c_str(), commandString.Len() )
00599 {
00600 m_aliaslist = aliaslist;
00601 m_linenumber=0;
00602 m_commands = commandString.c_str();
00603 m_c=0;
00604 a = wxT(' ');
00605 }
00606
00607
00608 a2dEvalCommandString::~a2dEvalCommandString()
00609 {
00610 }
00611
00612 void a2dEvalCommandString::IncC()
00613 {
00614 if (m_c == 0)
00615 {
00616 m_linenumber++;
00617 m_c = m_commands;
00618 }
00619 else
00620 {
00621 if (*m_c != wxT('\0') )
00622 m_c++;
00623 }
00624 a = *m_c;
00625 }
00626
00627 wxChar a2dEvalCommandString::PeekNextC()
00628 {
00629 wxChar p = wxT('\0');
00630 if (m_c == 0)
00631 p = *m_commands;
00632 else
00633 {
00634 if (*m_c != wxT('\0') )
00635 {
00636 m_c++;
00637 p =* m_c--;
00638 }
00639 }
00640 return p;
00641 }
00642
00643 void a2dEvalCommandString::Reset()
00644 {
00645 FlushArg();
00646 m_c = 0;
00647 SeekI(0);
00648
00649 m_evaluated.Clear();
00650 }
00651
00652 void a2dEvalCommandString::ResetEvaluatedString()
00653 {
00654 m_evaluated.Clear();
00655 }
00656
00657 bool a2dEvalCommandString::ParseNextCommand()
00658 {
00659 FlushArg();
00660 try
00661 {
00662 if( !GetCommand() )
00663 {
00664 if ( GetErrorMes().Len() )
00665 {
00666 wxString buffer;
00667 buffer.Printf( _T("Could not Parse line %d: \n %s \n Error: %s"),
00668 m_linenumber, m_commands, GetErrorMes().c_str() );
00669
00670 throw a2dCommand_Error( buffer, wxT("Command Parsing Error") );
00671 }
00672 }
00673
00674
00675 int i;
00676 for ( i = 0; i < m_argumentlist.GetCount(); i++ )
00677 {
00678 if ( i == 0 )
00679 m_evaluated += m_argumentlist.GetVariableAsString( i );
00680 else
00681 m_evaluated += wxT(" ") + m_argumentlist.GetVariableAsString( i );
00682 }
00683 }
00684 catch (a2dCommand_Error& error)
00685 {
00686 m_error_mes = error.GetMessage();
00687 return false;
00688 }
00689
00690 return true;
00691 }
00692
00693
00694
00695
00696 a2dFileLineParser::a2dFileLineParser( const wxString& the_file, a2dVariablesHash& aliaslist )
00697 : wxFileInputStream( the_file )
00698 {
00699
00700 m_line_file = the_file;
00701 m_aliaslist = aliaslist;
00702
00703
00704 if (!Ok())
00705 {
00706 wxString errbuf;
00707 errbuf.Printf( _T("Cannot open file %s!"), m_line_file.c_str() );
00708 throw a2dCommand_Error( errbuf, wxT("Parser: File Error") );
00709 }
00710
00711 m_linenumber=0;
00712 m_keyword = wxT("");
00713 m_back = false;
00714 a = wxT(' ');
00715 }
00716
00717
00718 a2dFileLineParser::~a2dFileLineParser()
00719 {
00720 }
00721
00722
00723 void a2dFileLineParser::Reset()
00724 {
00725 m_file->Seek(0);
00726 m_linenumber=0;
00727 m_keyword = wxT("");
00728 m_back=false;
00729 a = wxT(' ');
00730 m_commandsofar.Clear();
00731 }
00732
00733 void a2dFileLineParser::IncC()
00734 {
00735 a = (char) GetC();
00736 if (Eof())
00737 a = wxT('\0');
00738 if (a == wxChar(EOF) )
00739 a = wxT('\0');
00740 if (a == wxT('\r') )
00741 a = wxT(' ');
00742
00743 m_commandsofar+=a;
00744 }
00745
00746 wxChar a2dFileLineParser::PeekNextC()
00747 {
00748 wxChar p = (wxChar) Peek();
00749 return p;
00750 }
00751
00752
00753
00754 bool a2dFileLineParser::ReadItem( const wxString& type )
00755 {
00756
00757 if (m_back)
00758 {
00759 if (! m_keyword.CmpNoCase(type))
00760 m_back = false;
00761 else
00762 m_back = true;
00763 return bool(!m_back);
00764 }
00765
00766 bool Next=true;
00767 do
00768 {
00769 FlushArg();
00770 if( !GetCommand() )
00771 {
00772 if ( !GetErrorMes().IsEmpty() )
00773 {
00774 m_commandsofar.Printf(_T("Could not Parse line %d: \n Error: %s"),
00775 m_linenumber, GetErrorMes().c_str() );
00776
00777 throw a2dCommand_Error( m_commandsofar, wxT("Command Parsing Error") );
00778 }
00779 return false;
00780 }
00781 if ( !m_argumentlist.GetCount() )
00782 Next=true;
00783 else if ( m_argumentlist.GetVariableAsString( 0 ).GetChar( 0 ) == wxT('#') )
00784 Next=true;
00785 else
00786 Next=false;
00787 }
00788 while (Next);
00789
00790 m_linenumber++;
00791 m_keyword = m_argumentlist.GetVariableAsString( 0 );
00792
00793 if ( !m_keyword.CmpNoCase( type ) )
00794 m_back = false;
00795 else
00796 m_back = true;
00797 return bool(!m_back);
00798 }
00799
00800 bool a2dFileLineParser::ParseNextCommand()
00801 {
00802 FlushArg();
00803 if( !GetCommand() )
00804 {
00805 if ( !GetErrorMes().IsEmpty() )
00806 {
00807 m_commandsofar.Printf( _T("Could not Parse line %d: \n Error: %s"),
00808 m_linenumber, GetErrorMes().c_str() );
00809 throw a2dCommand_Error( m_commandsofar, wxT("Command Parsing Error") );
00810 }
00811 return false;
00812 }
00813 return true;
00814 }
00815