Marsyas  0.6.0-alpha
/usr/src/RPM/BUILD/marsyas-0.6.0/src/marsyas/expr/Expr.cpp
Go to the documentation of this file.
00001 /*
00002 ** Copyright (C) 1998-2007 George Tzanetakis <gtzan@cs.uvic.ca>
00003 **
00004 ** This program is free software; you can redistribute it and/or modify
00005 ** it under the terms of the GNU General Public License as published by
00006 ** the Free Software Foundation; either version 2 of the License, or
00007 ** (at your option) any later version.
00008 **
00009 ** This program is distributed in the hope that it will be useful,
00010 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 ** GNU General Public License for more details.
00013 **
00014 ** You should have received a copy of the GNU General Public License
00015 ** along with this program; if not, write to the Free Software
00016 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017 */
00018 
00019 #include <marsyas/expr/Expr.h>
00020 #include <marsyas/expr/ExParser.h>
00021 #include <marsyas/expr/ExScanner.h>
00022 #include <marsyas/expr/ExSymTbl.h>
00023 #include <marsyas/expr/ExNode.h>
00024 #include <marsyas/system/MarSystem.h>
00025 #include <marsyas/sched/Scheduler.h>
00026 #include <marsyas/sched/TmTimer.h>
00027 
00028 #include <fstream>
00029 
00030 using std::ostringstream;
00031 using namespace Marsyas;
00032 
00033 void
00034 Ex::parse(Expr* e, ExNode*& init, ExNode*& expr)
00035 {
00036   ExScanner s;
00037   ExParser p(&(e->timer_),&s);
00038 
00039   // parse init expression
00040   if (init_!="") {
00041     s.setString(init_.c_str());
00042     p.Parse(e->sched_,e->marsym_,e->symbol_table_);
00043     init=p.getTree();
00044   }
00045   else init=NULL;
00046 
00047   if (expr_!="") {
00048     s.setString(expr_.c_str());
00049     p.Parse(e->sched_,e->marsym_,e->symbol_table_);
00050     expr=p.getTree();
00051   }
00052   else expr=NULL;
00053 }
00054 
00055 Expr::Expr()
00056 {
00057   symbol_table_=NULL;
00058   init_expr_=NULL; expr_=NULL;
00059   rept_=NULL; rate_=NULL;
00060   marsym_=NULL;
00061   sched_=NULL;
00062   timer_=NULL;
00063   initialized_=false;
00064 }
00065 Expr::Expr(MarSystem* msym, Ex e)
00066 {
00067   marsym_=msym;
00068   timer_=NULL;
00069   sched_=NULL;
00070   symbol_table_=new ExRecord();
00071   symbol_table_->inc_ref();
00072   e.parse(this,init_expr_,expr_);
00073   rept_=NULL;
00074   rate_=NULL;
00075   initialized_=false;
00076 }
00077 Expr::Expr(MarSystem* msym, Ex e, Rp r)
00078 {
00079   set(msym,e,r);
00080 }
00081 Expr::Expr(MarSystem* msym, ExFile ef)
00082 {
00083   Ex e=ef.getEx();
00084   Rp r=ef.getRp();
00085   set(msym,e,r);
00086 }
00087 void
00088 Expr::set(MarSystem* m, Ex& e, Rp& r)
00089 {
00090   marsym_=m;
00091   timer_=NULL;
00092   sched_=NULL;
00093   symbol_table_=new ExRecord();
00094   symbol_table_->inc_ref();
00095   e.parse(this,init_expr_,expr_);
00096   r.parse(this,rept_,rate_);
00097   if (rept_&&rept_->getEvalType()!="mrs_bool") {
00098     MRSWARN("Expr::  Repetition expression must evaluate to bool: "+rept_->getEvalType());
00099     rept_->deref(); rept_=NULL;
00100     if (rate_) rate_->deref(); rate_=NULL;
00101   }
00102   else if (rate_&&rate_->getEvalType()!="mrs_string") {
00103     MRSWARN("Expr::  Repetition rate expression must evaluate to string: "+rate_->getEvalType());
00104     if (rept_) rept_->deref(); rept_=NULL;
00105     if (rate_) rate_->deref(); rate_=NULL;
00106   }
00107   initialized_=false;
00108 }
00109 
00110 Expr::~Expr()
00111 {
00112   symbol_table_->deref();
00113   delete expr_;
00114   delete init_expr_;
00115   delete rept_;
00116   delete rate_;
00117 }
00118 
00119 void
00120 Expr::eval()
00121 {
00122   if (expr_!=NULL)
00123     expr_->eval();
00124 }
00125 
00126 bool
00127 Expr::repeat()
00128 {
00129   return (rept_)&&(rept_->eval()).toBool();
00130 }
00131 
00132 std::string
00133 Expr::repeat_interval()
00134 {
00135   if (rate_) return (rate_->eval()).toString();
00136   return "__NULL";
00137 }
00138 
00139 void
00140 Expr::setScheduler(Scheduler* v)
00141 {
00142   sched_=v;
00143 }
00144 
00145 void
00146 Expr::setTimer(TmTimer* t)
00147 {
00148   timer_=t;
00149 }
00150 
00151 void
00152 Expr::post()
00153 {
00154   if (init_expr_&&!initialized_)
00155     init_expr_->eval();
00156   initialized_=true;
00157 }
00158 
00159 void
00160 ExFile::read(std::string fname)
00161 {
00162   std::ifstream from(fname.c_str());
00163   if (!from) { MRSWARN("ExFile::read  Cannot open file: "+fname); return; }
00164   std::string data;
00165   char buffer[256];
00166   // flags correspond to the 5 possible blocks, no block can be declared more than once
00167   bool flags[6] = { false };
00168   int pos=-1;
00169   std::string line;
00170   while (from.getline(buffer,256)) {
00171     if (buffer[0]=='#') {
00172       if (buffer[1]=='E'&&buffer[2]=='x') { // #ExInit: | #ExExpr:
00173         if (buffer[3]=='I'&&buffer[4]=='n'&&buffer[5]=='i'&&buffer[6]=='t'&&buffer[7]==':') {
00174           store(pos,data); data=""; pos=1;
00175           if (flags[pos]) { MRSWARN("ExFile::read  Double declaration of #ExInit: block"); }
00176         }
00177         else if (buffer[3]=='E'&&buffer[4]=='x'&&buffer[5]=='p'&&buffer[6]=='r'&&buffer[7]==':') {
00178           store(pos,data); data=""; pos=2;
00179           if (flags[pos]) { MRSWARN("ExFile::read  Double declaration of #ExExpr: block"); }
00180         }
00181       }
00182       else if (buffer[1]=='R'&&buffer[2]=='p') {
00183         if (buffer[3]=='E'&&buffer[4]=='x'&&buffer[5]=='p'&&buffer[6]=='r'&&buffer[7]==':') {
00184           // #RpExpr:
00185           store(pos,data); data=""; pos=3;
00186           if (flags[pos]) { MRSWARN("ExFile::read  Double declaration of #RpExpr: block"); }
00187         }
00188         else if (buffer[3]=='R'&&buffer[4]=='a'&&buffer[5]=='t'&&buffer[6]=='e'&&buffer[7]==':') {
00189           // #RpRate:
00190           store(pos,data); data=""; pos=4;
00191           if (flags[pos]) { MRSWARN("ExFile::read  Double declaration of #RpRate: block"); }
00192         }
00193       }
00194       else {
00195         MRSWARN("ExFile::read  Unknown macro # in ExFile");
00196       }
00197       flags[pos]=true;
00198     }
00199     else { data=data+buffer; }
00200   }
00201   if (!data.empty()) { store(pos,data); }
00202   from.close();
00203   file_read_=true;
00204 }
00205 
00206 void
00207 ExFile::store(int pos, std::string data)
00208 {
00209   switch(pos) {
00210   case 1: iex_=data; break;
00211   case 2: ex_=data; break;
00212   case 3: rp_=data; break;
00213   case 4: rr_=data; break;
00214   }
00215 }