gtkradiant/contrib/bobtoolz/ScriptParser.cpp
spog 06eb8cc3a4 ported bobtoolz
git-svn-id: svn://svn.icculus.org/gtkradiant/GtkRadiant/trunk@58 8a3a26a2-13c4-0310-b231-cf6edde360e5
2006-04-30 22:28:39 +00:00

286 lines
5.4 KiB
C++

/*
BobToolz plugin for GtkRadiant
Copyright (C) 2001 Gordon Biggans
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ScriptParser.h"
#include <string.h>
CScriptParser::CScriptParser(void):
m_pScript(NULL),
m_pScriptSection(NULL),
m_pLastScriptSection(NULL),
m_pToken(NULL) {
ClearBuffer();
}
CScriptParser::~CScriptParser(void) {
ClearBuffer();
}
void CScriptParser::ClearBuffer(void) {
if(m_pScript) {
delete[] m_pScript;
m_pScript = NULL;
}
if(m_pToken) {
delete[] m_pToken;
m_pToken = NULL;
}
m_pScriptSection = NULL;
m_pLastScriptSection = NULL;
memset(m_breakChars, 0, sizeof(m_breakChars));
}
const char* CScriptParser::MakeToken(const char* pToken) {
if(m_pToken) {
delete[] m_pToken;
m_pToken = NULL;
}
if(!pToken) {
pToken = "";
}
int len = static_cast<int>(strlen(pToken));
m_pToken = new char[len + 1];
m_pToken[len] = '\0';
strcpy(m_pToken, pToken);
return m_pToken;
}
#define MAX_TOKEN_STRING 1024
// Should NEVER return NULL
const char* CScriptParser::GetToken(bool bAllowLinebreaks) {
int c = 0, len;
char token[MAX_TOKEN_STRING];
bool bNewLines = false;
m_pLastScriptSection = m_pScriptSection;
len = 0;
*token = '\0';
if(!m_pScript || !m_pScriptSection) {
return MakeToken(token);
}
while ( true ) {
SkipWhitespace( &bNewLines );
if ( !*m_pScriptSection ) {
return MakeToken(token);
}
if ( bNewLines && !bAllowLinebreaks ) {
return MakeToken(token);
}
c = *m_pScriptSection;
if ( c == '/' && m_pScriptSection[1] == '/' ) { // C style comments
m_pScriptSection += 2;
while (*m_pScriptSection && *m_pScriptSection != '\n') {
m_pScriptSection++;
}
} else if ( c=='/' && m_pScriptSection[1] == '*' ) { // C++ style comments
m_pScriptSection += 2;
while ( *m_pScriptSection && ( *m_pScriptSection != '*' || m_pScriptSection[1] != '/' ) ) {
m_pScriptSection++;
}
if ( *m_pScriptSection ) {
m_pScriptSection += 2;
}
} else {
break;
}
}
if (c == '\"') {
m_pScriptSection++;
while ( true ) {
c = *m_pScriptSection++;
if (c=='\"' || !c) {
token[len] = 0;
return MakeToken(token);
}
if (len < MAX_TOKEN_STRING) {
token[len] = c;
len++;
}
}
}
do {
if(len > 0 && IsBreakChar(*m_pScriptSection)) {
break;
}
if (len < MAX_TOKEN_STRING) {
token[len] = c;
len++;
}
m_pScriptSection++;
if(IsBreakChar(c)) {
break;
}
c = *m_pScriptSection;
} while (c > 32);
if (len == MAX_TOKEN_STRING) {
len = 0;
}
token[len] = 0;
return MakeToken(token);
}
void CScriptParser::SkipWhitespace(bool* pbNewLines) {
int c;
if(!m_pScript || !m_pScriptSection) {
return;
}
while( (c = *m_pScriptSection) <= ' ') {
if( !c ) {
return;
}
if( c == '\n' ) {
*pbNewLines = true;
}
m_pScriptSection++;
}
}
void CScriptParser::SkipBracedSection(void) {
const char *token;
int depth;
depth = 0;
do {
token = GetToken( true );
if( token[1] == 0 ) {
if( *token == '{' ) {
depth++;
} else if( *token == '}' ) {
depth--;
}
}
} while( depth && *m_pScriptSection );
}
void CScriptParser::SkipRestOfLine(void) {
char *p;
int c;
p = m_pScriptSection;
while ( (c = *p++) != 0 ) {
if ( c == '\n' ) {
break;
}
}
m_pScriptSection = p;
}
void CScriptParser::UndoGetToken(void) {
if(!m_pLastScriptSection) {
return;
}
m_pScriptSection = m_pLastScriptSection;
m_pLastScriptSection = NULL;
}
void CScriptParser::ResetParseSession(void) {
if(!m_pScript) {
return;
}
m_pScriptSection = m_pScript;
m_pLastScriptSection = NULL;
}
char* CScriptParser::GetBufferCopy(void) {
if(!m_pScript) {
return NULL;
}
int len = static_cast<int>(strlen(m_pScript));
char* pBuffer = new char[len + 1];
strcpy(pBuffer, m_pScript);
return pBuffer;
}
int CScriptParser::GetTokenOffset(void) {
if(!m_pScript || !m_pScriptSection) {
return 0;
}
return static_cast<int>(m_pScriptSection - m_pScript);
}
void CScriptParser::LoadScript(const char* pScript) {
ClearBuffer();
int len = static_cast<int>(strlen(pScript));
if(len <= 0) {
return;
}
m_pScript = new char[len + 1];
m_pScript[len] = '\0';
strcpy(m_pScript, pScript);
m_pScriptSection = m_pScript;
}
void CScriptParser::AddBreakChar(char c) {
for(int i = 0; i < SP_MAX_BREAKCHARS; i++) {
if(!m_breakChars[i]) {
m_breakChars[i] = c;
return;
}
}
// TODO: Error: max break chars hit
}
bool CScriptParser::IsBreakChar(char c) {
for(int i = 0; i < SP_MAX_BREAKCHARS; i++) {
if(!m_breakChars[i]) {
return false;
}
if(m_breakChars[i] == c) {
return true;
}
}
return false;
}
void CScriptParser::SetScript(char* pScript) {
ClearBuffer();
int len = static_cast<int>(strlen(pScript));
if(len <= 0) {
return;
}
m_pScript = pScript;
m_pScriptSection = m_pScript;
}