Main | License | Installation | FAQ | Screenshots | Contact | Links | Sf.net | Freshmeat.net | KDE-Apps.org
Requirements | Design | Modules | Class Hierarchy | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

mealMasterCompiler.cpp

Go to the documentation of this file.
00001 /* Copyright (C) 2002, 2003, 2004 Jan Wedekind.
00002    This file is part of the recipe database application AnyMeal.
00003 
00004    AnyMeal is free software; you can redistribute it and/or modify it under
00005    the terms of the GNU GENERAL PUBLIC LICENSE as published by the Free
00006    Software Foundation; either version 3 of the License, or (at your option)
00007    any later version.
00008 
00009    AnyMeal is distributed in the hope that it will be useful, but WITHOUT ANY
00010    WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS
00011    FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
00012    details.
00013 
00014    You should have received a copy of the GNU General Public License
00015    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
00016 #include <cstdio>
00017 #include <kglobal.h>
00018 #include <klocale.h>
00019 #include <limits.h>
00020 #include <vector>
00021 #include "mealMasterCompiler.hpp"
00022 #include "unitMap.hpp"
00023 #include "utils.hpp"
00024 
00025 using namespace boost;
00026 using namespace std;
00027 
00028 int mealMasterlex(void);
00029 int mealMasterrestart( FILE * );
00030 
00031 long position;
00032 int lineNo;
00033 int errorLine;
00034 int recipeStartPos;
00035 int recipeEndPos;
00036 int recipeStartLine;
00037 int recipeEndLine;
00038 const char *errorMessage;
00039 
00040 MealMasterCompiler *MealMasterCompiler::current = NULL;
00041 static vector< string > outputBuffer( 5 );
00042 static istream *currentInput;
00043 
00044 /* index:  
00045    0: main-buffer
00046    1: delayed first ingredient-column
00047    2: delayed second ingredient-column
00048    3: right-top continuation of ingredient (in two-column format)
00049    4: right-top continuation of preparation-method (in two-column format).*/
00050 void writeData( int index, const char *buffer, int size )
00051 {
00052   assert( MealMasterCompiler::current != NULL );
00053   assert( index >= 0 );
00054   assert( index < (signed)outputBuffer.size() );
00055   outputBuffer[ index ] += string( buffer, size );
00056 }
00057 
00058 void writeUnit( int index, const char *buffer, int size )
00059 {
00060   string unit( buffer, size );
00061   assert( MealMasterCompiler::current != NULL );
00062   string inverseUnit( MealMasterCompiler::current->
00063                       inverseUnitMap[ unit.c_str() ] );
00064   assert( !inverseUnit.empty() );
00065 #ifndef NDEBUG
00066   // cerr << "buffer[0] = " << buffer[0] << ' ' << (int)buffer[0] << endl
00067   //      << "buffer[1] = " << buffer[1] << ' ' << (int)buffer[1] << endl
00068   //      << "size = " << size << endl
00069   //      << "string( buffer, size ) = " << unit << endl
00070   //      << "inverseUnit = " << inverseUnit << endl;
00071 #endif
00072    outputBuffer[ index ] += (const char *)i18n( inverseUnit.c_str() );
00073 }
00074 
00075 void moveData( int index )
00076 {
00077   assert( index >= 1 );
00078   assert( index < (signed)outputBuffer.size() );
00079   outputBuffer[ 0 ] += outputBuffer[ index ];
00080   outputBuffer[ index ].clear();
00081 }
00082 
00083 int readData( char *buffer, int max_size )
00084 {
00085   int result;
00086   assert( MealMasterCompiler::current != NULL );
00087   if ( currentInput == NULL ) {
00088     result = 0;
00089   } else {
00090     currentInput->read( buffer, max_size );
00091     if ( currentInput->eof() ) {
00092       // Get number of bytes read.
00093       result = currentInput->gcount();
00094       currentInput = NULL;
00095     } else {
00096       // The buffer was filled.
00097       result = max_size;
00098     };
00099   };
00100   // cerr << "Read " << result << '/' << max_size << " characters." << endl;
00101   return result;
00102 }
00103 
00104 MealMasterCompiler::MealMasterCompiler
00105   ( int _maxRecipes, MealMasterParseErrorHandlerPtr _parseErrorHandler ):
00106   inverseUnitMap( createInverseUnitMap() ), maxRecipes(_maxRecipes),
00107   parseErrorHandler(_parseErrorHandler)
00108 {
00109   assert( current == NULL );
00110   current = this;
00111 
00112   // Restart line-number counting.
00113   lineNo = 1;
00114 }
00115 
00116 MealMasterCompiler::~MealMasterCompiler(void)
00117 {
00118   current = NULL;
00119 }
00120 
00121 void MealMasterCompiler::translate( istream &inputStream,
00122                                     ostream &outputStream ) const
00123   throw (Error)
00124 {
00125   currentInput = &inputStream;
00126   // Store current position.
00127   position = inputStream.tellg();
00128   // Clear any remaining input from buffer.
00129   mealMasterrestart( NULL );
00130   outputStream << "<?xml version='1.0' encoding='UTF-8'?>"
00131                << endl << "<insert xml:lang='"
00132                << anyMealLanguage() << "'>" << endl;
00133   int counter = maxRecipes;
00134   while ( counter != 0 ) {
00135     try {
00136       for ( int i=0; i<(signed)outputBuffer.size(); i++ )
00137         outputBuffer[ i ].clear();
00138       int x = mealMasterlex();
00139       if ( x ==  0 ) break;
00140       ERRORMACRO( x < +2, MealMasterParseError,
00141                   ( recipeStartLine, recipeEndLine, errorLine, &inputStream,
00142                     recipeStartPos, recipeEndPos ), errorMessage );
00143       assert( x == 1 );
00144       outputStream << outputBuffer[ 0 ];
00145     } catch ( MealMasterParseError &e ) {
00146 #ifndef NDEBUG
00147       cerr << e.what() << endl;
00148 #endif
00149       assert( parseErrorHandler );
00150       parseErrorHandler->error( e );
00151     };
00152     if ( counter > 0 ) counter--;
00153   };
00154   outputStream << "</insert>\n";
00155   // Seek to current scanner position.
00156   inputStream.seekg( position, ios::beg );
00157 }


anymeal 0.30 - recipe management software - Make the most of your food! - © Jan Wedekind Sun Sep 14 16:01:26 2008 - GNU Free Documentation License