Main Page | Class List | File List | Class Members | Related Pages

parser.cpp

00001 /***************************************************************************
00002                            parser.cpp
00003                            -------------------
00004     begin                : 2003-05-10
00005     copyright            : (C) 2004-2005 by Michael Menne
00006     email                : menne@users.sourceforge.net
00007     history              : 1.0 - 10.05.2003 - Zelda 3 Clone
00008                            1.1 - 14.04.2004 - WDS Maptool
00009                            1.2 - 17.04.2004 - ProSys - FHD
00010  ***************************************************************************/
00011 
00012 /***************************************************************************
00013  This program is free software; you can redistribute it and/or
00014  modify it under the terms of the GNU General Public License
00015  as published by the Free Software Foundation; either version 2
00016  of the License, or (at your option) any later version.
00017 
00018  This program is distributed in the hope that it will be useful,
00019  but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021  GNU General Public License for more details.
00022 
00023  You should have received a copy of the GNU General Public License
00024  along with this program; if not, write to the Free Software
00025  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00026  ***************************************************************************/
00027 
00028 #include "parser.h"
00029 #include <stdio.h>
00030 #include <string.h>
00031 
00032 /*----------------------------------------------------------------------------/
00033     Constructor / Desstructor
00034 -----------------------------------------------------------------------------*/
00035 
00036 CParser::CParser()
00037 {
00038     m_pBuffer  = NULL;
00039     m_pBufEnd  = NULL;
00040     m_pFileMem = NULL;
00041 }
00042 
00043 CParser::~CParser()
00044 {
00045     if(m_pFileMem != NULL)
00046     {
00047         delete [] m_pFileMem;
00048         m_pFileMem = NULL;
00049     }
00050 }
00051 
00052 /*---------------------------------------------------------------------------
00053     Methods:
00054 ---------------------------------------------------------------------------*/
00055 
00056 void CParser::StartParseBuffer(const unsigned char *pBuffer, const int nSize)
00057 {
00058     m_pBuffer = pBuffer;
00059     m_pBufEnd = pBuffer + nSize;
00060     m_nScriptLine = 1;
00061 }
00062 
00063 void CParser::StartParseString(const char *szString)
00064 {
00065     m_pBuffer = (unsigned char*) szString;
00066     m_pBufEnd = (unsigned char*) szString + strlen(szString);
00067     m_nScriptLine = 1;
00068 }
00069 
00070 bool CParser::StartParseFile(const char *szFile)
00071 {
00072     FILE *pFile = fopen(szFile, "r");
00073     if(!pFile)
00074         return false;
00075 
00076     fseek(pFile, 0L, SEEK_END);
00077     int nSize = ftell(pFile);
00078     rewind(pFile);
00079 
00080     m_pFileMem = new unsigned char[nSize];
00081     memset( m_pFileMem, 0, nSize );
00082     fread(m_pFileMem, nSize, 1, pFile);     // ToDo: Error checking
00083 
00084     // Set starting and end point
00085     m_pBuffer = m_pFileMem;
00086     m_pBufEnd = m_pFileMem + nSize;
00087     m_nScriptLine = 1;
00088 
00089     fclose( pFile );
00090     return true;
00091 }
00092 
00093 /*
00094  * If bCrossline is false, NextToken returns false when a line break is found
00095  * NextToken(true)  returns 0 only if end of file
00096  * NextToken(false) returns 0 if line break or end of file
00097  */
00098 bool CParser::NextToken(bool bCrossline)
00099 {
00100     char    *token_p;
00101 
00102     if( !m_pBuffer || m_pBuffer==m_pBufEnd )
00103         return 0;
00104 
00105     *m_szToken = 0; // init to zero
00106 
00107 
00108 // skip space
00109 skipspace:
00110     while(*m_pBuffer <= 32 || *m_pBuffer == '\n' || *m_pBuffer == ';')
00111     {
00112 
00113         if( m_pBuffer >= m_pBufEnd )
00114         {
00115             if( !bCrossline )
00116             {
00117                 // ("Line %i is incomplete", m_nScriptLine )
00118             }
00119             return 0;
00120         }
00121 
00122         if( !bCrossline )
00123         {
00124             if( *m_pBuffer=='\n' || *m_pBuffer==';' )
00125                 return 0;
00126         }
00127         else if(*m_pBuffer == '\n')
00128         {
00129             m_nScriptLine++;
00130         }
00131 
00132         m_pBuffer++;
00133     }
00134 
00135     if( m_pBuffer >= m_pBufEnd )
00136         return 0;
00137 
00138     // # // comments
00139     if( *m_pBuffer == '#' || ( m_pBuffer[0] == '/' && m_pBuffer[1] == '/' ) )
00140     {
00141         while(*m_pBuffer++ != '\n')
00142         {
00143             if( m_pBuffer >= m_pBufEnd )
00144                 return 0;
00145         }
00146         m_nScriptLine++;
00147         if( !bCrossline )
00148             return 0;
00149         goto skipspace;
00150     }
00151 
00152     // /* */ comments
00153     if( m_pBuffer[0] == '/' && m_pBuffer[1] == '*' )
00154     {
00155         m_pBuffer+=2;
00156         while( !(m_pBuffer[0] == '*' && m_pBuffer[1] == '/') )
00157         {
00158             m_pBuffer++;
00159             if (m_pBuffer >= m_pBufEnd)
00160             {
00161                 //("*** Error: Premature end of file, '/*' without '*/'")
00162                 return 0;
00163             }
00164             if(*m_pBuffer == '\n')
00165                 m_nScriptLine++;
00166         }
00167         m_pBuffer += 2;
00168         goto skipspace;
00169     }
00170 
00171 
00172     /*
00173      * copy m_szToken
00174      */
00175     token_p = m_szToken;
00176 
00177     if (*m_pBuffer == '"')  // quoted m_szToken
00178     {
00179         m_pBuffer++;
00180         while( *m_pBuffer != '"' )
00181         {
00182             *token_p++ = *m_pBuffer++;
00183             if( m_pBuffer == m_pBufEnd )
00184                 break;
00185 
00186             if( token_p == &m_szToken[MAXTOKEN] )
00187             {
00188                 //("*** Error, Token too large on line %i\n",m_nScriptLine)
00189             }
00190         }
00191         m_pBuffer++;
00192     }
00193     else    // regular m_szToken
00194     {
00195         if( *m_pBuffer == '{' || *m_pBuffer == '}' )
00196         {
00197             *token_p++ = *m_pBuffer++;
00198             *token_p = 0;
00199             return 1;
00200         }
00201 
00202         while( *m_pBuffer > 32 && *m_pBuffer != '\n' && *m_pBuffer != ';' && *m_pBuffer !='{' && *m_pBuffer !='}')
00203         {
00204             *token_p++ = *m_pBuffer++;
00205             if( m_pBuffer == m_pBufEnd)
00206                 break;
00207 
00208             if( token_p == &m_szToken[MAXTOKEN])
00209             {
00210                 //("*** Error, Token too large on line %i\n", m_nScriptLine)
00211             }
00212         }
00213     }
00214 
00215     *token_p = 0;
00216 
00217     return 1;
00218 }
00219 
00224 int CParser::SkipLine( )
00225 {
00226     int n = 0;
00227     while( NextToken( false) )
00228         n++;
00229     return n;
00230 }
00231 
00232 // kate: space-indent off; tab-width 4; replace-tabs off;

Generated on Sun Jan 16 18:20:26 2005 for WDSMap by  doxygen 1.3.9.1