Hormiga 1.0

/var/www/hormigaproject.com.ar/files/src/coreinterface.cpp

Go to the documentation of this file.
00001 
00002 /*
00003 # Hormiga - Software de cálculo programable.
00004 #
00005 # Copyright (C) 2008, 2009 Leonardo Román, Hugo J. Curti, Norma  Ercoli,
00006 # Universidad Nacional del Centro de la Provincia de Buenos Aires
00007 # (UNCPBA)
00008 #
00009 # Este programa es parte de Hormiga.
00010 #
00011 # Hormiga es software libre. Puede redistribuirlo y/o modificarlo
00012 # bajo los términos de la Licencia Pública General de GNU según es
00013 # publicada por la Free Software Foundation, versión 2. Vea el archivo
00014 # COPIA (español, no oficial) o COPYING (inglés, oficial) en directorio
00015 # raíz.
00016 #
00017 # Hormiga se distribuye con la esperanza de que sea útil, pero SIN
00018 # NINGUNA GARANTÍA, incluso sin la garantía MERCANTIL implícita o sin
00019 # garantizar la CONVENIENCIA PARA UN PROPÓSITO PARTICULAR. Véase la
00020 # Licencia Pública General de GNU para más detalles.
00021 #
00022 # Debería haber recibido una copia de la Licencia Pública General junto
00023 # con Hormiga. Si no ha sido así, escriba a la Free Software
00024 # Foundation, Inc., en 675 Mass Ave, Cambridge, MA 02139, EEUU.
00025 # Añada también información sobre cómo contactar con usted mediante
00026 # correo electrónico y postal.
00027 #
00028 # This file is part of Hormiga.
00029 #
00030 # Hormiga is free software; you can redistribute it and/or modify
00031 # it under the terms of the GNU General Public License version 2
00032 # as published by the Free Software Foundation; see the file COPYING
00033 # in the top directory for details.
00034 #
00035 # Hormiga is distributed in the hope that it will be useful,
00036 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00037 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00038 # GNU General Public License for more details.
00039 #
00040 # You should have received a copy of the GNU General Public License
00041 # along with Hormiga; if not, write to the Free Software
00042 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
00043 # USA
00044 */
00045 
00046 #include "coreinterface.h"
00047 
00048 #include <QDir>
00049 
00050 #include "parser/parser_functions.h"
00051 #include "yy_lex.h"
00052 #include "yy_yacc.h"
00053 
00054 #ifdef ENABLE_NLS
00055 #include <libintl.h>
00056 #endif
00057 CoreInterface::CoreInterface()
00058 {
00059     this->coreFunctions = NULL ;
00060 
00061     // The next is used by "QSettings"
00062     //QCoreApplication::setOrganizationDomain("ximon.com.ar");
00063     QCoreApplication::setOrganizationName( MY_ORGANIZATION );
00064     QCoreApplication::setApplicationName( APPLICATION_NAME );
00065     this->settings = new QSettings( QSettings::IniFormat ,
00066                                     QSettings::SystemScope ,
00067                                     MY_ORGANIZATION , APPLICATION_NAME ) ;
00068     if ( QMetaType::type("T_STRING") == 0 )
00069         qRegisterMetaType<T_STRING>("T_STRING") ;
00070     this->hashCalc = new T_HASH_CALC( QCryptographicHash::Md5 );
00071     this->clear() ;
00072 
00073     // Support for internationalization (only needed under windows)...
00074     // Where the dictionaries are ?
00075 #ifdef ENABLE_NLS
00076     bindtextdomain ("bison-runtime" , LOCALES_DIR ) ;
00077 #endif
00078 }
00079 
00080 CoreInterface::~CoreInterface()
00081 {
00082     while ( this->stList.count() )
00083         delete this->stList.takeLast() ;
00084     delete this->coreFunctions ;
00085     delete this->settings ;
00086     delete this->hashCalc ;
00087 }
00088 
00089 SymbolTable* CoreInterface::beginEnviroment ()
00090 {
00091     this->st = new SymbolTable( this->st ) ;
00092     this->stList.append( this->st ) ;
00093     return ( this->st ) ;
00094 }
00095 
00096 SymbolTable* CoreInterface::getCurrentEnviroment ()
00097 {
00098     return ( this->st ) ;
00099 }
00100 
00101 SymbolTable* CoreInterface::endCurrentEnviroment ()
00102 {
00103     if ( this->st != NULL )
00104         this->st = this->st->getParentSymbolTable() ;
00105     return this->st ;
00106 }
00107 
00108 bool CoreInterface::markFile ( T_STRING &fullFileName )
00109 {
00110     if ( this->markedFiles.contains ( fullFileName ) )
00111         return ( false ) ;
00112     this->markedFiles.append( fullFileName ) ;
00113     return ( true ) ;
00114 }
00115 
00116 QStringList CoreInterface::getModulesDirs ()
00117 {
00118     QDir dir ( this->loadedProgramFile ) ;
00119     dir.cdUp() ; // Convert fileName to it's dirName.
00120     QStringList def ;
00121     def.append( DEFAULT_MODULES_PATH ) ; // the default if not config file.
00122     // Try to load the config file (or use 'def' else)...
00123     def = this->settings->value( "Core/Modules_Path" , def ).toStringList() ;
00124     def.append ( dir.absolutePath() ) ; // Try in program's dir too...
00125     return def ;
00126 }
00127 
00128 T_HASH_CALC* CoreInterface::getHashCalculator ()
00129 {
00130     return hashCalc ;
00131 }
00132 
00133 /* Slots */
00134 extern int yyparse( yyscan_t scanner , CoreInterface* core ) ;
00135 void CoreInterface::loadFile ( T_STRING &fname )
00136 {
00137     FILE *toLoad = fopen( fname.toAscii().data() , "r" ) ;
00138     if ( ! toLoad )
00139     {
00140         this->notifyMessage( 2, QString(
00141                 tr("ERROR!! Can not open file: '%1'.")
00142                 ).arg( fname ) );
00143         return ;
00144     }
00145     this->clear() ;
00146     this->loadedProgramFile = fname ;
00147     FlexExtraData fn ; fn.core = this ;
00148     fn.fileName.prepend( fname ) ;
00149     yyscan_t scanner ;
00150     yylex_init_extra ( &fn , &scanner ) ;
00151     yyset_in ( toLoad , scanner ) ;
00152 
00153     this->markFile ( fname ) ;
00154     int rc = yyparse( scanner, this ) ;
00155     yylex_destroy ( scanner ) ;
00156     if ( rc != 0 )
00157     {
00158         this->notifyMessage( 2, QString(
00159                 tr("ERROR!! While loading file '%1'. Code: %2")
00160                 ).arg( fname ).arg( rc ) );
00161     }
00162     fclose ( toLoad ) ;
00163 }
00164 
00165 void CoreInterface::clear ()
00166 {
00167     this->actualProcesingStep = NULL ;
00168     this->st = NULL ;
00169     this->markedFiles.clear() ;
00170     while ( this->stList.count() )
00171         delete this->stList.takeLast() ;
00172     if ( this->coreFunctions != NULL )
00173         delete this->coreFunctions ;
00174     this->coreFunctions = new CoreFunctionsBuilder ;
00175     this->loadedProgramFile.clear() ;
00176     this->hashCalc->reset() ;
00177 
00178     /* Create a default enviroment */
00179     this->beginEnviroment () ;
00180 }
00181 
00182 void CoreInterface::notifyStepCreated ( Step* newStep )
00183 {
00184     emit stepCreated(newStep) ;
00185     QObject::connect ( newStep , SIGNAL ( message(int,T_STRING) ) ,
00186                            this , SLOT ( notifyMessage(int,T_STRING)) ) ;
00187 }
00188 
00189 void CoreInterface::notifyMessage ( int severity , T_STRING msg )
00190 {
00191     printf ( "%s" , msg.toAscii().data() ) ;
00192     fflush(stdout);
00193     emit coreMessage( msg , severity ) ;
00194 }
00195 
00196 void CoreInterface::yyerror ( int severity , yyscan_t scanner , T_STRING msg )
00197 {
00198     QString level = tr( "ERROR!!" ) ;
00199     if ( severity < 2 )
00200         level = tr( "WARNING!!" ) ;
00201     msg = QString( tr("%1: in file '%2' at line %3 while parsing token '%4': %5\n") )
00202                 .arg( level )
00203                 .arg( yyget_extra( scanner )->fileName.first() )
00204                 .arg( yyget_lineno ( scanner ) )
00205                 .arg( yyget_text ( scanner ) )
00206                 .arg( msg ) ;
00207     this->notifyMessage( severity , msg ) ;
00208 }