mirror of
https://github.com/SWG-Source/src.git
synced 2026-07-13 21:01:08 -04:00
Added Miff tool
This commit is contained in:
@@ -12,7 +12,9 @@ set(SWG_ENGINE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/engine)
|
||||
set(SWG_EXTERNALS_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external)
|
||||
set(SWG_GAME_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/game)
|
||||
|
||||
find_package(BISON REQUIRED)
|
||||
find_package(Boost REQUIRED)
|
||||
find_package(FLEX REQUIRED)
|
||||
find_package(JNI REQUIRED)
|
||||
find_package(LibXml2 REQUIRED)
|
||||
find_package(Oracle REQUIRED)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
add_subdirectory(client)
|
||||
add_subdirectory(server)
|
||||
add_subdirectory(shared)
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
add_subdirectory(application)
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
add_subdirectory(Miff)
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
project(Miff)
|
||||
|
||||
add_subdirectory(src)
|
||||
@@ -0,0 +1,100 @@
|
||||
|
||||
if(WIN32)
|
||||
set(PLATFORM_SOURCES
|
||||
win32/InputFileHandler.cpp
|
||||
win32/InputFileHandler.h
|
||||
win32/OutputFileHandler.cpp
|
||||
win32/OutputFileHandler.h
|
||||
win32/miff.cpp
|
||||
)
|
||||
|
||||
set(PLATFORM win32)
|
||||
else()
|
||||
set(PLATFORM_SOURCES
|
||||
linux/InputFileHandler.cpp
|
||||
linux/InputFileHandler.h
|
||||
linux/OutputFileHandler.cpp
|
||||
linux/OutputFileHandler.h
|
||||
linux/miff.cpp
|
||||
)
|
||||
|
||||
set(PLATFORM linux)
|
||||
endif()
|
||||
|
||||
include_directories(
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedCompression/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedDebug/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFile/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundation/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundationTypes/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMemoryManager/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedThread/include/public
|
||||
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/fileInterface/include/public
|
||||
)
|
||||
|
||||
set(PARSER_LEX ${CMAKE_CURRENT_SOURCE_DIR}/${PLATFORM}/parser.lex)
|
||||
file(TO_NATIVE_PATH ${PARSER_LEX} PARSER_LEX_NATIVE)
|
||||
|
||||
set(PARSER_YAC ${CMAKE_CURRENT_SOURCE_DIR}/${PLATFORM}/parser.yac)
|
||||
file(TO_NATIVE_PATH ${PARSER_YAC} PARSER_YAC_NATIVE)
|
||||
|
||||
set(LEX_YY_C ${CMAKE_CURRENT_BINARY_DIR}/lex_yy.c)
|
||||
file(TO_NATIVE_PATH ${LEX_YY_C} LEX_YY_C_NATIVE)
|
||||
|
||||
set(PARSER_C ${CMAKE_CURRENT_BINARY_DIR}/parser.c)
|
||||
file(TO_NATIVE_PATH ${PARSER_C} PARSER_C_NATIVE)
|
||||
|
||||
set(PARSER_H ${CMAKE_CURRENT_BINARY_DIR}/parser.h)
|
||||
file(TO_NATIVE_PATH ${PARSER_H} PARSER_H_NATIVE)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${LEX_YY_C}
|
||||
COMMAND ${FLEX_EXECUTABLE} -w -o${LEX_YY_C_NATIVE} ${PARSER_LEX_NATIVE}
|
||||
DEPENDS ${PARSER_LEX}
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${PARSER_C} ${PARSER_H}
|
||||
COMMAND ${BISON_EXECUTABLE} -d -o ${PARSER_C_NATIVE} ${PARSER_YAC_NATIVE}
|
||||
DEPENDS ${PARSER_YAC}
|
||||
)
|
||||
|
||||
add_executable(Miff
|
||||
${PLATFORM_SOURCES}
|
||||
${LEX_YY_C}
|
||||
${PARSER_C}
|
||||
${PARSER_H}
|
||||
)
|
||||
|
||||
target_link_libraries(Miff
|
||||
#sharedCommandParser
|
||||
sharedCompression
|
||||
sharedDebug
|
||||
sharedFile
|
||||
sharedFoundation
|
||||
#sharedGame
|
||||
#sharedLog
|
||||
#sharedMath
|
||||
sharedMemoryManager
|
||||
#sharedMessageDispatch
|
||||
#sharedNetwork
|
||||
#sharedNetworkMessages
|
||||
#sharedObject
|
||||
#sharedRandom
|
||||
#sharedSynchronization
|
||||
sharedThread
|
||||
#sharedUtility
|
||||
#serverKeyShare
|
||||
#serverMetrics
|
||||
#serverNetworkMessages
|
||||
#serverUtility
|
||||
#archive
|
||||
#crypto
|
||||
fileInterface
|
||||
#localization
|
||||
#localizationArchive
|
||||
#unicode
|
||||
#unicodeArchive
|
||||
${STLPORT_LIBRARIES}
|
||||
${CMAKE_DL_LIBS}
|
||||
)
|
||||
@@ -0,0 +1,334 @@
|
||||
|
||||
extern int timeclock;
|
||||
|
||||
|
||||
int yyerror; /* Yyerror and yycost are set by guards. */
|
||||
int yycost; /* If yyerror is set to a nonzero value by a */
|
||||
/* guard, the reduction with which the guard */
|
||||
/* is associated is not performed, and the */
|
||||
/* error recovery mechanism is invoked. */
|
||||
/* Yycost indicates the cost of performing */
|
||||
/* the reduction given the attributes of the */
|
||||
/* symbols. */
|
||||
|
||||
|
||||
/* YYMAXDEPTH indicates the size of the parser's state and value */
|
||||
/* stacks. */
|
||||
|
||||
#ifndef YYMAXDEPTH
|
||||
#define YYMAXDEPTH 500
|
||||
#endif
|
||||
|
||||
/* YYMAXRULES must be at least as large as the number of rules that */
|
||||
/* could be placed in the rule queue. That number could be determined */
|
||||
/* from the grammar and the size of the stack, but, as yet, it is not. */
|
||||
|
||||
#ifndef YYMAXRULES
|
||||
#define YYMAXRULES 100
|
||||
#endif
|
||||
|
||||
#ifndef YYMAXBACKUP
|
||||
#define YYMAXBACKUP 100
|
||||
#endif
|
||||
|
||||
|
||||
short yyss[YYMAXDEPTH]; /* the state stack */
|
||||
YYSTYPE yyvs[YYMAXDEPTH]; /* the semantic value stack */
|
||||
YYLTYPE yyls[YYMAXDEPTH]; /* the location stack */
|
||||
short yyrq[YYMAXRULES]; /* the rule queue */
|
||||
int yychar; /* the lookahead symbol */
|
||||
|
||||
YYSTYPE yylval; /* the semantic value of the */
|
||||
/* lookahead symbol */
|
||||
|
||||
YYSTYPE yytval; /* the semantic value for the state */
|
||||
/* at the top of the state stack. */
|
||||
|
||||
YYSTYPE yyval; /* the variable used to return */
|
||||
/* semantic values from the action */
|
||||
/* routines */
|
||||
|
||||
YYLTYPE yylloc; /* location data for the lookahead */
|
||||
/* symbol */
|
||||
|
||||
YYLTYPE yytloc; /* location data for the state at the */
|
||||
/* top of the state stack */
|
||||
|
||||
|
||||
int yynunlexed;
|
||||
short yyunchar[YYMAXBACKUP];
|
||||
YYSTYPE yyunval[YYMAXBACKUP];
|
||||
YYLTYPE yyunloc[YYMAXBACKUP];
|
||||
|
||||
short *yygssp; /* a pointer to the top of the state */
|
||||
/* stack; only set during error */
|
||||
/* recovery. */
|
||||
|
||||
YYSTYPE *yygvsp; /* a pointer to the top of the value */
|
||||
/* stack; only set during error */
|
||||
/* recovery. */
|
||||
|
||||
YYLTYPE *yyglsp; /* a pointer to the top of the */
|
||||
/* location stack; only set during */
|
||||
/* error recovery. */
|
||||
|
||||
|
||||
/* Yyget is an interface between the parser and the lexical analyzer. */
|
||||
/* It is costly to provide such an interface, but it avoids requiring */
|
||||
/* the lexical analyzer to be able to back up the scan. */
|
||||
|
||||
yyget()
|
||||
{
|
||||
if (yynunlexed > 0)
|
||||
{
|
||||
yynunlexed--;
|
||||
yychar = yyunchar[yynunlexed];
|
||||
yylval = yyunval[yynunlexed];
|
||||
yylloc = yyunloc[yynunlexed];
|
||||
}
|
||||
else if (yychar <= 0)
|
||||
yychar = 0;
|
||||
else
|
||||
{
|
||||
yychar = yylex();
|
||||
if (yychar < 0)
|
||||
yychar = 0;
|
||||
else yychar = YYTRANSLATE(yychar);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
yyunlex(chr, val, loc)
|
||||
int chr;
|
||||
YYSTYPE val;
|
||||
YYLTYPE loc;
|
||||
{
|
||||
yyunchar[yynunlexed] = chr;
|
||||
yyunval[yynunlexed] = val;
|
||||
yyunloc[yynunlexed] = loc;
|
||||
yynunlexed++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
yyrestore(first, last)
|
||||
register short *first;
|
||||
register short *last;
|
||||
{
|
||||
register short *ssp;
|
||||
register short *rp;
|
||||
register int symbol;
|
||||
register int state;
|
||||
register int tvalsaved;
|
||||
|
||||
ssp = yygssp;
|
||||
yyunlex(yychar, yylval, yylloc);
|
||||
|
||||
tvalsaved = 0;
|
||||
while (first != last)
|
||||
{
|
||||
symbol = yystos[*ssp];
|
||||
if (symbol < YYNTBASE)
|
||||
{
|
||||
yyunlex(symbol, yytval, yytloc);
|
||||
tvalsaved = 1;
|
||||
ssp--;
|
||||
}
|
||||
|
||||
ssp--;
|
||||
|
||||
if (first == yyrq)
|
||||
first = yyrq + YYMAXRULES;
|
||||
|
||||
first--;
|
||||
|
||||
for (rp = yyrhs + yyprhs[*first]; symbol = *rp; rp++)
|
||||
{
|
||||
if (symbol < YYNTBASE)
|
||||
state = yytable[yypact[*ssp] + symbol];
|
||||
else
|
||||
{
|
||||
state = yypgoto[symbol - YYNTBASE] + *ssp;
|
||||
|
||||
if (state >= 0 && state <= YYLAST && yycheck[state] == *ssp)
|
||||
state = yytable[state];
|
||||
else
|
||||
state = yydefgoto[symbol - YYNTBASE];
|
||||
}
|
||||
|
||||
*++ssp = state;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! tvalsaved && ssp > yyss)
|
||||
{
|
||||
yyunlex(yystos[*ssp], yytval, yytloc);
|
||||
ssp--;
|
||||
}
|
||||
|
||||
yygssp = ssp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
yyparse()
|
||||
{
|
||||
register int yystate;
|
||||
register int yyn;
|
||||
register short *yyssp;
|
||||
register short *yyrq0;
|
||||
register short *yyptr;
|
||||
register YYSTYPE *yyvsp;
|
||||
|
||||
int yylen;
|
||||
YYLTYPE *yylsp;
|
||||
short *yyrq1;
|
||||
short *yyrq2;
|
||||
|
||||
yystate = 0;
|
||||
yyssp = yyss - 1;
|
||||
yyvsp = yyvs - 1;
|
||||
yylsp = yyls - 1;
|
||||
yyrq0 = yyrq;
|
||||
yyrq1 = yyrq0;
|
||||
yyrq2 = yyrq0;
|
||||
|
||||
yychar = yylex();
|
||||
if (yychar < 0)
|
||||
yychar = 0;
|
||||
else yychar = YYTRANSLATE(yychar);
|
||||
|
||||
yynewstate:
|
||||
|
||||
if (yyssp >= yyss + YYMAXDEPTH - 1)
|
||||
{
|
||||
yyabort("Parser Stack Overflow");
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
*++yyssp = yystate;
|
||||
|
||||
yyresume:
|
||||
|
||||
yyn = yypact[yystate];
|
||||
if (yyn == YYFLAG)
|
||||
goto yydefault;
|
||||
|
||||
yyn += yychar;
|
||||
if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar)
|
||||
goto yydefault;
|
||||
|
||||
yyn = yytable[yyn];
|
||||
if (yyn < 0)
|
||||
{
|
||||
yyn = -yyn;
|
||||
goto yyreduce;
|
||||
}
|
||||
else if (yyn == 0)
|
||||
goto yyerrlab;
|
||||
|
||||
yystate = yyn;
|
||||
|
||||
yyptr = yyrq2;
|
||||
while (yyptr != yyrq1)
|
||||
{
|
||||
yyn = *yyptr++;
|
||||
yylen = yyr2[yyn];
|
||||
yyvsp -= yylen;
|
||||
yylsp -= yylen;
|
||||
|
||||
yyguard(yyn, yyvsp, yylsp);
|
||||
if (yyerror)
|
||||
goto yysemerr;
|
||||
|
||||
yyaction(yyn, yyvsp, yylsp);
|
||||
*++yyvsp = yyval;
|
||||
|
||||
yylsp++;
|
||||
if (yylen == 0)
|
||||
{
|
||||
yylsp->timestamp = timeclock;
|
||||
yylsp->first_line = yytloc.first_line;
|
||||
yylsp->first_column = yytloc.first_column;
|
||||
yylsp->last_line = (yylsp-1)->last_line;
|
||||
yylsp->last_column = (yylsp-1)->last_column;
|
||||
yylsp->text = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
yylsp->last_line = (yylsp+yylen-1)->last_line;
|
||||
yylsp->last_column = (yylsp+yylen-1)->last_column;
|
||||
}
|
||||
|
||||
if (yyptr == yyrq + YYMAXRULES)
|
||||
yyptr = yyrq;
|
||||
}
|
||||
|
||||
if (yystate == YYFINAL)
|
||||
YYACCEPT;
|
||||
|
||||
yyrq2 = yyptr;
|
||||
yyrq1 = yyrq0;
|
||||
|
||||
*++yyvsp = yytval;
|
||||
*++yylsp = yytloc;
|
||||
yytval = yylval;
|
||||
yytloc = yylloc;
|
||||
yyget();
|
||||
|
||||
goto yynewstate;
|
||||
|
||||
yydefault:
|
||||
|
||||
yyn = yydefact[yystate];
|
||||
if (yyn == 0)
|
||||
goto yyerrlab;
|
||||
|
||||
yyreduce:
|
||||
|
||||
*yyrq0++ = yyn;
|
||||
|
||||
if (yyrq0 == yyrq + YYMAXRULES)
|
||||
yyrq0 = yyrq;
|
||||
|
||||
if (yyrq0 == yyrq2)
|
||||
{
|
||||
yyabort("Parser Rule Queue Overflow");
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
yyssp -= yyr2[yyn];
|
||||
yyn = yyr1[yyn];
|
||||
|
||||
yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
|
||||
if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
|
||||
yystate = yytable[yystate];
|
||||
else
|
||||
yystate = yydefgoto[yyn - YYNTBASE];
|
||||
|
||||
goto yynewstate;
|
||||
|
||||
yysemerr:
|
||||
*--yyptr = yyn;
|
||||
yyrq2 = yyptr;
|
||||
yyvsp += yyr2[yyn];
|
||||
|
||||
yyerrlab:
|
||||
|
||||
yygssp = yyssp;
|
||||
yygvsp = yyvsp;
|
||||
yyglsp = yylsp;
|
||||
yyrestore(yyrq0, yyrq2);
|
||||
yyrecover();
|
||||
yystate = *yygssp;
|
||||
yyssp = yygssp;
|
||||
yyvsp = yygvsp;
|
||||
yyrq0 = yyrq;
|
||||
yyrq1 = yyrq0;
|
||||
yyrq2 = yyrq0;
|
||||
goto yyresume;
|
||||
}
|
||||
|
||||
$
|
||||
@@ -0,0 +1,136 @@
|
||||
//===========================================================================
|
||||
//
|
||||
// FILENAME: InputFileHandler.cpp [C:\Projects\new\tools\src\miff\src\]
|
||||
// COPYRIGHT: (C) 1999 BY Bootprint Entertainment
|
||||
//
|
||||
// DESCRIPTION: file handler for input files (standard flat text files)
|
||||
// AUTHOR: Hideki Ikeda
|
||||
// DATE: 1/13/99 4:53:31 PM
|
||||
//
|
||||
// HISTORY: 1/13/99 [HAI] - File created
|
||||
// :
|
||||
//
|
||||
// FUNCTION: InputFileHandler() constructor
|
||||
// : ~InputFileHandler() destructor
|
||||
// :
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
//========================================================== include files ==
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "InputFileHandler.h"
|
||||
|
||||
#include "sharedFile/TreeFile.h"
|
||||
//#include "sharedFile/Iff.h"
|
||||
|
||||
//================================================= static vars assignment ==
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//
|
||||
// Remarks:
|
||||
//
|
||||
//
|
||||
// See Also:
|
||||
//
|
||||
//
|
||||
// Revisions and History:
|
||||
// 1/13/99 [HAI] - created
|
||||
//
|
||||
InputFileHandler::InputFileHandler(const char *infilename)
|
||||
{
|
||||
TreeFile::addSearchAbsolute(0); // search current working directory
|
||||
|
||||
file = TreeFile::open(infilename, AbstractFile::PriorityData, true);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Destructor
|
||||
//
|
||||
// Remarks:
|
||||
//
|
||||
//
|
||||
// See Also:
|
||||
//
|
||||
//
|
||||
// Revisions and History:
|
||||
// 1/13/99 [HAI] - created
|
||||
//
|
||||
InputFileHandler::~InputFileHandler(void)
|
||||
{
|
||||
if(file)
|
||||
delete file;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// reads a file stream into specified buffer of the size passed
|
||||
//
|
||||
// Return Value:
|
||||
// actual size read (signed int)
|
||||
//
|
||||
// Remarks:
|
||||
//
|
||||
//
|
||||
// See Also:
|
||||
// Treefile::read()
|
||||
//
|
||||
// Revisions and History:
|
||||
// 1/13/99 [HAI] - created
|
||||
//
|
||||
const int InputFileHandler::read(
|
||||
void *sourceBuffer, // pointer to the buffer
|
||||
int bufferSize // number of BYTES to be read
|
||||
)
|
||||
{
|
||||
int retVal = -1; // assume fileHandle is NOT valid
|
||||
|
||||
if (file)
|
||||
retVal = file->read(sourceBuffer, bufferSize);
|
||||
|
||||
return(retVal);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Deletes a file
|
||||
//
|
||||
// Return Value:
|
||||
// whatever DeleteFile() returns
|
||||
// if fileHandle != -1, it assumes that the fileHandle passed belonged to
|
||||
// this filename, and therefore, it will attempt to close the file and
|
||||
// set it to 0.
|
||||
//
|
||||
// Remarks:
|
||||
// calls DeleteFile() found in windows.h
|
||||
// InputFileHandler does NOT have any way to validate that the handle
|
||||
// passed belongs to the filename that it wants to be deleted. So use
|
||||
// it with caution
|
||||
//
|
||||
// See Also:
|
||||
// windows.h
|
||||
//
|
||||
// Revisions and History:
|
||||
// 1/13/99 [HAI] - created
|
||||
//
|
||||
int InputFileHandler::deleteFile(
|
||||
const char *filename,
|
||||
bool deleteHandleFlag
|
||||
)
|
||||
{
|
||||
if (deleteHandleFlag && file)
|
||||
{
|
||||
delete file;
|
||||
file = NULL;
|
||||
}
|
||||
return(unlink(filename));
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//============================================================ End-of-file ==
|
||||
//===========================================================================
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
#ifndef __INPUTFILEHANDLER_H__
|
||||
#define __INPUTFILEHANDLER_H__
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// FILENAME: InputFileHandler.h [C:\Projects\new\tools\src\miff\src\]
|
||||
// COPYRIGHT: (C) 1999 BY Bootprint Entertainment
|
||||
//
|
||||
// DESCRIPTION: file handler for input files (flat text files)
|
||||
// AUTHOR: Hideki Ikeda
|
||||
// DATE: 1/13/99 4:55:15 PM
|
||||
//
|
||||
// HISTORY: 1/13/99 [HAI] - File created
|
||||
// :
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
//============================================================== #includes ==
|
||||
|
||||
//========================================================= class typedefs ==
|
||||
|
||||
//====================================================== class definitions ==
|
||||
|
||||
class AbstractFile;
|
||||
|
||||
class InputFileHandler
|
||||
{
|
||||
//------------------------------
|
||||
//--- public var & functions ---
|
||||
//------------------------------
|
||||
public: // functions
|
||||
InputFileHandler(const char *infilename);
|
||||
~InputFileHandler(void);
|
||||
|
||||
const int read(void *sourceBuffer, int bufferSize);
|
||||
int deleteFile(const char * filename, bool deleteHandleFlag = false);
|
||||
|
||||
public: // vars
|
||||
|
||||
|
||||
//-------------------------------
|
||||
//--- member vars declaration ---
|
||||
//-------------------------------
|
||||
protected: // vars
|
||||
AbstractFile *file;
|
||||
|
||||
private: // vars
|
||||
|
||||
//-----------------------------------
|
||||
//--- member function declaration ---
|
||||
//-----------------------------------
|
||||
protected: // functions
|
||||
|
||||
private: // functions
|
||||
void close(void); // close the input file called by destructor
|
||||
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
//========================================================= inline methods ==
|
||||
//===========================================================================
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//============================================================ End-of-file ==
|
||||
//===========================================================================
|
||||
#else
|
||||
#ifdef DEBUG
|
||||
#pragma message("InputFileHandler.h included more then once!")
|
||||
#endif
|
||||
#endif // ifndef __H__
|
||||
@@ -0,0 +1,164 @@
|
||||
//===========================================================================
|
||||
//
|
||||
// FILENAME: OutputFileHandler.cpp
|
||||
// COPYRIGHT: (C) 1999 BY Bootprint Entertainment
|
||||
//
|
||||
// DESCRIPTION: file handler for Output file (IFF file)
|
||||
// AUTHOR: Hideki Ikeda
|
||||
// DATE: 1/13/99 4:52:42 PM
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "OutputFileHandler.h"
|
||||
|
||||
#include "sharedFile/Iff.h"
|
||||
|
||||
//===========================================================================
|
||||
// Constructor
|
||||
|
||||
OutputFileHandler::OutputFileHandler(const char *filename)
|
||||
{
|
||||
outputIFF = new Iff(MAXIFFDATASIZE);
|
||||
outFilename = NULL;
|
||||
|
||||
setCurrentFilename(filename);
|
||||
}
|
||||
|
||||
void OutputFileHandler::setCurrentFilename(const char *filename)
|
||||
{
|
||||
if (outFilename)
|
||||
delete [] outFilename;
|
||||
|
||||
outFilename = new char[strlen(filename)+1];
|
||||
strcpy(outFilename, filename);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Destructor
|
||||
|
||||
OutputFileHandler::~OutputFileHandler(void)
|
||||
{
|
||||
if (outputIFF && outFilename)
|
||||
{
|
||||
delete outputIFF;
|
||||
delete [] outFilename;
|
||||
}
|
||||
|
||||
outputIFF = NULL;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// begins a new FORM in the IFF
|
||||
//
|
||||
// Return Value:
|
||||
// bool - true == success
|
||||
//
|
||||
// See Also:
|
||||
// Iff::insertForm()
|
||||
|
||||
void OutputFileHandler::insertForm(
|
||||
const char *tag
|
||||
)
|
||||
{
|
||||
Tag formTag = convertStrToTag(tag);
|
||||
outputIFF->insertForm(formTag);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// begins a new CHUNK in the IFF
|
||||
//
|
||||
// See Also:
|
||||
// Iff::insertChunk()
|
||||
|
||||
void OutputFileHandler::insertChunk(
|
||||
const char *tag
|
||||
)
|
||||
{
|
||||
Tag chunkTag = convertStrToTag(tag);
|
||||
outputIFF->insertChunk(chunkTag);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// converts string (4 bytes) form into Tag format
|
||||
//
|
||||
// Return Value:
|
||||
// Tag
|
||||
//
|
||||
// Remarks:
|
||||
// currently, this code is machine dependant code (non portable) and it assumes little endian
|
||||
//
|
||||
// See Also:
|
||||
// Tag
|
||||
|
||||
Tag OutputFileHandler::convertStrToTag(
|
||||
const char *str
|
||||
)
|
||||
{
|
||||
// prepare for hack-o-rama. It is byte order dependant, thus not portable ^_^
|
||||
Tag retVal = str[3] + (str[2] * 0x100) + (str[1] * 0x10000) + (str[0] * 0x1000000);
|
||||
|
||||
return(retVal);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// adds new chunk data into the current chunk it is in
|
||||
//
|
||||
// See Also:
|
||||
// Iff::insertChunkData()
|
||||
//
|
||||
|
||||
void OutputFileHandler::insertChunkData(
|
||||
void *data,
|
||||
int length
|
||||
)
|
||||
{
|
||||
outputIFF->insertChunkData(data, length);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// exits current FORM section we are in
|
||||
//
|
||||
// See Also:
|
||||
// Iff::exitForm()
|
||||
|
||||
void OutputFileHandler::exitForm(void)
|
||||
{
|
||||
outputIFF->exitForm();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// exits current CHUNK we are in
|
||||
//
|
||||
// See Also:
|
||||
// Iff::exitChunk()
|
||||
|
||||
void OutputFileHandler::exitChunk(void)
|
||||
{
|
||||
outputIFF->exitChunk();
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Calls Iff:write()
|
||||
//
|
||||
// Return Value:
|
||||
//
|
||||
// True if the Iff was successfully written, otherwise false
|
||||
//
|
||||
// See Also:
|
||||
// Iff::write()
|
||||
|
||||
bool OutputFileHandler::writeBuffer(void)
|
||||
{
|
||||
if (outputIFF && outFilename)
|
||||
return outputIFF->write(outFilename, true);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
#ifndef __OUTPUTFILEHANDLER_H__
|
||||
#define __OUTPUTFILEHANDLER_H__
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// FILENAME: OutputFileHandler.h [C:\Projects\new\tools\src\miff\src\]
|
||||
// COPYRIGHT: (C) 1999 BY Bootprint Entertainment
|
||||
//
|
||||
// DESCRIPTION: file handler for output files (IFF file format)
|
||||
// AUTHOR: Hideki Ikeda
|
||||
// DATE: 1/13/99 4:55:56 PM
|
||||
//
|
||||
// HISTORY: 1/13/99 [HAI] - File created
|
||||
// :
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
//============================================================== #includes ==
|
||||
|
||||
//========================================================= class typedefs ==
|
||||
#include "sharedFile/Iff.h"
|
||||
|
||||
//====================================================== class definitions ==
|
||||
class OutputFileHandler
|
||||
{
|
||||
//------------------------------
|
||||
//--- public var & functions ---
|
||||
//------------------------------
|
||||
public: // functions
|
||||
OutputFileHandler(const char *filename);
|
||||
~OutputFileHandler(void);
|
||||
bool writeBuffer(void);
|
||||
|
||||
void insertForm(const char *tagName);
|
||||
void insertChunk(const char *tagName);
|
||||
void insertChunkData(void *data, int length);
|
||||
void exitForm(void);
|
||||
void exitChunk(void);
|
||||
|
||||
void setCurrentFilename(const char *fname);
|
||||
|
||||
public: // vars
|
||||
|
||||
|
||||
//-------------------------------
|
||||
//--- member vars declaration ---
|
||||
//-------------------------------
|
||||
protected: // vars
|
||||
Iff * outputIFF;
|
||||
char *outFilename;
|
||||
|
||||
enum{
|
||||
MAXIFFDATASIZE = 8192 // allocate 8K of memory for a starter
|
||||
};
|
||||
|
||||
private: // vars
|
||||
|
||||
//-----------------------------------
|
||||
//--- member function declaration ---
|
||||
//-----------------------------------
|
||||
protected: // functions
|
||||
|
||||
private: // functions
|
||||
Tag convertStrToTag(const char *str);
|
||||
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
//========================================================= inline methods ==
|
||||
//===========================================================================
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//============================================================ End-of-file ==
|
||||
//===========================================================================
|
||||
#else
|
||||
#ifdef DEBUG
|
||||
#pragma message("OutputFileHandler.h included more then once!")
|
||||
#endif
|
||||
#endif // ifndef __H__
|
||||
@@ -0,0 +1,698 @@
|
||||
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
|
||||
#line 3 "bison.simple"
|
||||
|
||||
/* Skeleton output parser for bison,
|
||||
Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* As a special exception, when this file is copied by Bison into a
|
||||
Bison output file, you may use that output file without restriction.
|
||||
This special exception was added by the Free Software Foundation
|
||||
in version 1.24 of Bison. */
|
||||
|
||||
#define MSDOS 1
|
||||
|
||||
#ifndef alloca
|
||||
#ifdef __GNUC__
|
||||
#define alloca __builtin_alloca
|
||||
#else /* not GNU C. */
|
||||
#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
|
||||
#include <alloca.h>
|
||||
#else /* not sparc */
|
||||
#if defined (MSDOS) && !defined (__TURBOC__)
|
||||
#include <malloc.h>
|
||||
#else /* not MSDOS, or __TURBOC__ */
|
||||
#if defined(_AIX)
|
||||
#include <malloc.h>
|
||||
#pragma alloca
|
||||
#else /* not MSDOS, __TURBOC__, or _AIX */
|
||||
#ifdef __hpux
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
void *alloca (unsigned int);
|
||||
};
|
||||
#else /* not __cplusplus */
|
||||
void *alloca ();
|
||||
#endif /* not __cplusplus */
|
||||
#endif /* __hpux */
|
||||
#endif /* not _AIX */
|
||||
#endif /* not MSDOS, or __TURBOC__ */
|
||||
#endif /* not sparc. */
|
||||
#endif /* not GNU C. */
|
||||
#endif /* alloca not defined. */
|
||||
|
||||
#ifdef MSDOS
|
||||
#define alloca(n) malloc(n)
|
||||
#endif
|
||||
|
||||
/* This is the parser code that is written into each bison parser
|
||||
when the %semantic_parser declaration is not specified in the grammar.
|
||||
It was written by Richard Stallman by simplifying the hairy parser
|
||||
used when %semantic_parser is specified. */
|
||||
|
||||
/* Note: there must be only one dollar sign in this file.
|
||||
It is replaced by the list of actions, each action
|
||||
as one case of the switch. */
|
||||
|
||||
#define yyerrok (yyerrstatus = 0)
|
||||
#define yyclearin (yychar = YYEMPTY)
|
||||
#define YYEMPTY -2
|
||||
#define YYEOF 0
|
||||
#define YYACCEPT return(0)
|
||||
#define YYABORT return(1)
|
||||
#define YYERROR goto yyerrlab1
|
||||
/* Like YYERROR except do call yyerror.
|
||||
This remains here temporarily to ease the
|
||||
transition to the new meaning of YYERROR, for GCC.
|
||||
Once GCC version 2 has supplanted version 1, this can go. */
|
||||
#define YYFAIL goto yyerrlab
|
||||
#define YYRECOVERING() (!!yyerrstatus)
|
||||
#define YYBACKUP(token, value) \
|
||||
do \
|
||||
if (yychar == YYEMPTY && yylen == 1) \
|
||||
{ yychar = (token), yylval = (value); \
|
||||
yychar1 = YYTRANSLATE (yychar); \
|
||||
YYPOPSTACK; \
|
||||
goto yybackup; \
|
||||
} \
|
||||
else \
|
||||
{ yyerror ("syntax error: cannot back up"); YYERROR; } \
|
||||
while (0)
|
||||
|
||||
#define YYTERROR 1
|
||||
#define YYERRCODE 256
|
||||
|
||||
#ifndef YYPURE
|
||||
#define YYLEX yylex()
|
||||
#endif
|
||||
|
||||
#ifdef YYPURE
|
||||
#ifdef YYLSP_NEEDED
|
||||
#ifdef YYLEX_PARAM
|
||||
#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
|
||||
#else
|
||||
#define YYLEX yylex(&yylval, &yylloc)
|
||||
#endif
|
||||
#else /* not YYLSP_NEEDED */
|
||||
#ifdef YYLEX_PARAM
|
||||
#define YYLEX yylex(&yylval, YYLEX_PARAM)
|
||||
#else
|
||||
#define YYLEX yylex(&yylval)
|
||||
#endif
|
||||
#endif /* not YYLSP_NEEDED */
|
||||
#endif
|
||||
|
||||
/* If nonreentrant, generate the variables here */
|
||||
|
||||
#ifndef YYPURE
|
||||
|
||||
int yychar; /* the lookahead symbol */
|
||||
YYSTYPE yylval; /* the semantic value of the */
|
||||
/* lookahead symbol */
|
||||
|
||||
#ifdef YYLSP_NEEDED
|
||||
YYLTYPE yylloc; /* location data for the lookahead */
|
||||
/* symbol */
|
||||
#endif
|
||||
|
||||
int yynerrs; /* number of parse errors so far */
|
||||
#endif /* not YYPURE */
|
||||
|
||||
#if YYDEBUG != 0
|
||||
int yydebug = 1; /* nonzero means print parse trace */
|
||||
/* Since this is uninitialized, it does not stop multiple parsers
|
||||
from coexisting. */
|
||||
#endif
|
||||
|
||||
/* YYINITDEPTH indicates the initial size of the parser's stacks */
|
||||
|
||||
#ifndef YYINITDEPTH
|
||||
#define YYINITDEPTH 200
|
||||
#endif
|
||||
|
||||
/* YYMAXDEPTH is the maximum size the stacks can grow to
|
||||
(effective only if the built-in stack extension method is used). */
|
||||
|
||||
#if YYMAXDEPTH == 0
|
||||
#undef YYMAXDEPTH
|
||||
#endif
|
||||
|
||||
#ifndef YYMAXDEPTH
|
||||
#define YYMAXDEPTH 10000
|
||||
#endif
|
||||
|
||||
/* Prevent warning if -Wstrict-prototypes. */
|
||||
#ifdef __GNUC__
|
||||
int yyparse (void);
|
||||
#endif
|
||||
|
||||
#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
|
||||
#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT)
|
||||
#else /* not GNU C or C++ */
|
||||
#ifndef __cplusplus
|
||||
|
||||
/* This is the most reliable way to avoid incompatibilities
|
||||
in available built-in functions on various systems. */
|
||||
static void
|
||||
__yy_memcpy (to, from, count)
|
||||
char *to;
|
||||
char *from;
|
||||
int count;
|
||||
{
|
||||
register char *f = from;
|
||||
register char *t = to;
|
||||
register int i = count;
|
||||
|
||||
while (i-- > 0)
|
||||
*t++ = *f++;
|
||||
}
|
||||
|
||||
#else /* __cplusplus */
|
||||
|
||||
/* This is the most reliable way to avoid incompatibilities
|
||||
in available built-in functions on various systems. */
|
||||
static void
|
||||
__yy_memcpy (char *to, char *from, int count)
|
||||
{
|
||||
register char *f = from;
|
||||
register char *t = to;
|
||||
register int i = count;
|
||||
|
||||
while (i-- > 0)
|
||||
*t++ = *f++;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#line 196 "bison.simple"
|
||||
|
||||
/* The user can define YYPARSE_PARAM as the name of an argument to be passed
|
||||
into yyparse. The argument should have type void *.
|
||||
It should actually point to an object.
|
||||
Grammar actions can access the variable by casting it
|
||||
to the proper pointer type. */
|
||||
|
||||
#ifdef YYPARSE_PARAM
|
||||
#ifdef __cplusplus
|
||||
#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
|
||||
#define YYPARSE_PARAM_DECL
|
||||
#else /* not __cplusplus */
|
||||
#define YYPARSE_PARAM_ARG YYPARSE_PARAM
|
||||
#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
|
||||
#endif /* not __cplusplus */
|
||||
#else /* not YYPARSE_PARAM */
|
||||
#define YYPARSE_PARAM_ARG
|
||||
#define YYPARSE_PARAM_DECL
|
||||
#endif /* not YYPARSE_PARAM */
|
||||
|
||||
int
|
||||
yyparse(YYPARSE_PARAM_ARG)
|
||||
YYPARSE_PARAM_DECL
|
||||
{
|
||||
register int yystate;
|
||||
register int yyn;
|
||||
register short *yyssp;
|
||||
register YYSTYPE *yyvsp;
|
||||
int yyerrstatus; /* number of tokens to shift before error messages enabled */
|
||||
int yychar1 = 0; /* lookahead token as an internal (translated) token number */
|
||||
|
||||
short yyssa[YYINITDEPTH]; /* the state stack */
|
||||
YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
|
||||
|
||||
short *yyss = yyssa; /* refer to the stacks thru separate pointers */
|
||||
YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
|
||||
|
||||
#ifdef YYLSP_NEEDED
|
||||
YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
|
||||
YYLTYPE *yyls = yylsa;
|
||||
YYLTYPE *yylsp;
|
||||
|
||||
#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
|
||||
#else
|
||||
#define YYPOPSTACK (yyvsp--, yyssp--)
|
||||
#endif
|
||||
|
||||
int yystacksize = YYINITDEPTH;
|
||||
|
||||
#ifdef YYPURE
|
||||
int yychar;
|
||||
YYSTYPE yylval;
|
||||
int yynerrs;
|
||||
#ifdef YYLSP_NEEDED
|
||||
YYLTYPE yylloc;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
YYSTYPE yyval; /* the variable used to return */
|
||||
/* semantic values from the action */
|
||||
/* routines */
|
||||
|
||||
int yylen;
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
fprintf(stderr, "Starting parse\n");
|
||||
#endif
|
||||
|
||||
yystate = 0;
|
||||
yyerrstatus = 0;
|
||||
yynerrs = 0;
|
||||
yychar = YYEMPTY; /* Cause a token to be read. */
|
||||
|
||||
/* Initialize stack pointers.
|
||||
Waste one element of value and location stack
|
||||
so that they stay on the same level as the state stack.
|
||||
The wasted elements are never initialized. */
|
||||
|
||||
yyssp = yyss - 1;
|
||||
yyvsp = yyvs;
|
||||
#ifdef YYLSP_NEEDED
|
||||
yylsp = yyls;
|
||||
#endif
|
||||
|
||||
/* Push a new state, which is found in yystate . */
|
||||
/* In all cases, when you get here, the value and location stacks
|
||||
have just been pushed. so pushing a state here evens the stacks. */
|
||||
yynewstate:
|
||||
|
||||
*++yyssp = yystate;
|
||||
|
||||
if (yyssp >= yyss + yystacksize - 1)
|
||||
{
|
||||
/* Give user a chance to reallocate the stack */
|
||||
/* Use copies of these so that the &'s don't force the real ones into memory. */
|
||||
YYSTYPE *yyvs1 = yyvs;
|
||||
short *yyss1 = yyss;
|
||||
#ifdef YYLSP_NEEDED
|
||||
YYLTYPE *yyls1 = yyls;
|
||||
#endif
|
||||
|
||||
/* Get the current used size of the three stacks, in elements. */
|
||||
int size = yyssp - yyss + 1;
|
||||
|
||||
#ifdef yyoverflow
|
||||
/* Each stack pointer address is followed by the size of
|
||||
the data in use in that stack, in bytes. */
|
||||
#ifdef YYLSP_NEEDED
|
||||
/* This used to be a conditional around just the two extra args,
|
||||
but that might be undefined if yyoverflow is a macro. */
|
||||
yyoverflow("parser stack overflow",
|
||||
&yyss1, size * sizeof (*yyssp),
|
||||
&yyvs1, size * sizeof (*yyvsp),
|
||||
&yyls1, size * sizeof (*yylsp),
|
||||
&yystacksize);
|
||||
#else
|
||||
yyoverflow("parser stack overflow",
|
||||
&yyss1, size * sizeof (*yyssp),
|
||||
&yyvs1, size * sizeof (*yyvsp),
|
||||
&yystacksize);
|
||||
#endif
|
||||
|
||||
yyss = yyss1; yyvs = yyvs1;
|
||||
#ifdef YYLSP_NEEDED
|
||||
yyls = yyls1;
|
||||
#endif
|
||||
#else /* no yyoverflow */
|
||||
/* Extend the stack our own way. */
|
||||
if (yystacksize >= YYMAXDEPTH)
|
||||
{
|
||||
yyerror("parser stack overflow");
|
||||
return 2;
|
||||
}
|
||||
yystacksize *= 2;
|
||||
if (yystacksize > YYMAXDEPTH)
|
||||
yystacksize = YYMAXDEPTH;
|
||||
yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
|
||||
__yy_memcpy ((char *)yyss, (char *)yyss1, size * sizeof (*yyssp));
|
||||
yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
|
||||
__yy_memcpy ((char *)yyvs, (char *)yyvs1, size * sizeof (*yyvsp));
|
||||
#ifdef YYLSP_NEEDED
|
||||
yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
|
||||
__yy_memcpy ((char *)yyls, (char *)yyls1, size * sizeof (*yylsp));
|
||||
#endif
|
||||
#endif /* no yyoverflow */
|
||||
|
||||
yyssp = yyss + size - 1;
|
||||
yyvsp = yyvs + size - 1;
|
||||
#ifdef YYLSP_NEEDED
|
||||
yylsp = yyls + size - 1;
|
||||
#endif
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
fprintf(stderr, "Stack size increased to %d\n", yystacksize);
|
||||
#endif
|
||||
|
||||
if (yyssp >= yyss + yystacksize - 1)
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
fprintf(stderr, "Entering state %d\n", yystate);
|
||||
#endif
|
||||
|
||||
goto yybackup;
|
||||
yybackup:
|
||||
|
||||
/* Do appropriate processing given the current state. */
|
||||
/* Read a lookahead token if we need one and don't already have one. */
|
||||
/* yyresume: */
|
||||
|
||||
/* First try to decide what to do without reference to lookahead token. */
|
||||
|
||||
yyn = yypact[yystate];
|
||||
if (yyn == YYFLAG)
|
||||
goto yydefault;
|
||||
|
||||
/* Not known => get a lookahead token if don't already have one. */
|
||||
|
||||
/* yychar is either YYEMPTY or YYEOF
|
||||
or a valid token in external form. */
|
||||
|
||||
if (yychar == YYEMPTY)
|
||||
{
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
fprintf(stderr, "Reading a token: ");
|
||||
#endif
|
||||
yychar = YYLEX;
|
||||
}
|
||||
|
||||
/* Convert token to internal form (in yychar1) for indexing tables with */
|
||||
|
||||
if (yychar <= 0) /* This means end of input. */
|
||||
{
|
||||
yychar1 = 0;
|
||||
yychar = YYEOF; /* Don't call YYLEX any more */
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
fprintf(stderr, "Now at end of input.\n");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
yychar1 = YYTRANSLATE(yychar);
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
{
|
||||
fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
|
||||
/* Give the individual parser a way to print the precise meaning
|
||||
of a token, for further debugging info. */
|
||||
#ifdef YYPRINT
|
||||
YYPRINT (stderr, yychar, yylval);
|
||||
#endif
|
||||
fprintf (stderr, ")\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
yyn += yychar1;
|
||||
if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
|
||||
goto yydefault;
|
||||
|
||||
yyn = yytable[yyn];
|
||||
|
||||
/* yyn is what to do for this token type in this state.
|
||||
Negative => reduce, -yyn is rule number.
|
||||
Positive => shift, yyn is new state.
|
||||
New state is final state => don't bother to shift,
|
||||
just return success.
|
||||
0, or most negative number => error. */
|
||||
|
||||
if (yyn < 0)
|
||||
{
|
||||
if (yyn == YYFLAG)
|
||||
goto yyerrlab;
|
||||
yyn = -yyn;
|
||||
goto yyreduce;
|
||||
}
|
||||
else if (yyn == 0)
|
||||
goto yyerrlab;
|
||||
|
||||
if (yyn == YYFINAL)
|
||||
YYACCEPT;
|
||||
|
||||
/* Shift the lookahead token. */
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
|
||||
#endif
|
||||
|
||||
/* Discard the token being shifted unless it is eof. */
|
||||
if (yychar != YYEOF)
|
||||
yychar = YYEMPTY;
|
||||
|
||||
*++yyvsp = yylval;
|
||||
#ifdef YYLSP_NEEDED
|
||||
*++yylsp = yylloc;
|
||||
#endif
|
||||
|
||||
/* count tokens shifted since error; after three, turn off error status. */
|
||||
if (yyerrstatus) yyerrstatus--;
|
||||
|
||||
yystate = yyn;
|
||||
goto yynewstate;
|
||||
|
||||
/* Do the default action for the current state. */
|
||||
yydefault:
|
||||
|
||||
yyn = yydefact[yystate];
|
||||
if (yyn == 0)
|
||||
goto yyerrlab;
|
||||
|
||||
/* Do a reduction. yyn is the number of a rule to reduce with. */
|
||||
yyreduce:
|
||||
yylen = yyr2[yyn];
|
||||
if (yylen > 0)
|
||||
yyval = yyvsp[1-yylen]; /* implement default value of the action */
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
{
|
||||
int i;
|
||||
|
||||
fprintf (stderr, "Reducing via rule %d (line %d), ",
|
||||
yyn, yyrline[yyn]);
|
||||
|
||||
/* Print the symbols being reduced, and their result. */
|
||||
for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
|
||||
fprintf (stderr, "%s ", yytname[yyrhs[i]]);
|
||||
fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
|
||||
}
|
||||
#endif
|
||||
|
||||
$ /* the action file gets copied in in place of this dollarsign */
|
||||
#line 498 "bison.simple"
|
||||
|
||||
yyvsp -= yylen;
|
||||
yyssp -= yylen;
|
||||
#ifdef YYLSP_NEEDED
|
||||
yylsp -= yylen;
|
||||
#endif
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
{
|
||||
short *ssp1 = yyss - 1;
|
||||
fprintf (stderr, "state stack now");
|
||||
while (ssp1 != yyssp)
|
||||
fprintf (stderr, " %d", *++ssp1);
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
*++yyvsp = yyval;
|
||||
|
||||
#ifdef YYLSP_NEEDED
|
||||
yylsp++;
|
||||
if (yylen == 0)
|
||||
{
|
||||
yylsp->first_line = yylloc.first_line;
|
||||
yylsp->first_column = yylloc.first_column;
|
||||
yylsp->last_line = (yylsp-1)->last_line;
|
||||
yylsp->last_column = (yylsp-1)->last_column;
|
||||
yylsp->text = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
yylsp->last_line = (yylsp+yylen-1)->last_line;
|
||||
yylsp->last_column = (yylsp+yylen-1)->last_column;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Now "shift" the result of the reduction.
|
||||
Determine what state that goes to,
|
||||
based on the state we popped back to
|
||||
and the rule number reduced by. */
|
||||
|
||||
yyn = yyr1[yyn];
|
||||
|
||||
yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
|
||||
if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
|
||||
yystate = yytable[yystate];
|
||||
else
|
||||
yystate = yydefgoto[yyn - YYNTBASE];
|
||||
|
||||
goto yynewstate;
|
||||
|
||||
yyerrlab: /* here on detecting error */
|
||||
|
||||
if (! yyerrstatus)
|
||||
/* If not already recovering from an error, report this error. */
|
||||
{
|
||||
++yynerrs;
|
||||
|
||||
#ifdef YYERROR_VERBOSE
|
||||
yyn = yypact[yystate];
|
||||
|
||||
if (yyn > YYFLAG && yyn < YYLAST)
|
||||
{
|
||||
int size = 0;
|
||||
char *msg;
|
||||
int x, count;
|
||||
|
||||
count = 0;
|
||||
/* Start X at -yyn if nec to avoid negative indexes in yycheck. */
|
||||
for (x = (yyn < 0 ? -yyn : 0);
|
||||
x < (sizeof(yytname) / sizeof(char *)); x++)
|
||||
if (yycheck[x + yyn] == x)
|
||||
size += strlen(yytname[x]) + 15, count++;
|
||||
msg = (char *) malloc(size + 15);
|
||||
if (msg != 0)
|
||||
{
|
||||
strcpy(msg, "parse error");
|
||||
|
||||
if (count < 5)
|
||||
{
|
||||
count = 0;
|
||||
for (x = (yyn < 0 ? -yyn : 0);
|
||||
x < (sizeof(yytname) / sizeof(char *)); x++)
|
||||
if (yycheck[x + yyn] == x)
|
||||
{
|
||||
strcat(msg, count == 0 ? ", expecting `" : " or `");
|
||||
strcat(msg, yytname[x]);
|
||||
strcat(msg, "'");
|
||||
count++;
|
||||
}
|
||||
}
|
||||
yyerror(msg);
|
||||
free(msg);
|
||||
}
|
||||
else
|
||||
yyerror ("parse error; also virtual memory exceeded");
|
||||
}
|
||||
else
|
||||
#endif /* YYERROR_VERBOSE */
|
||||
yyerror("parse error");
|
||||
}
|
||||
|
||||
goto yyerrlab1;
|
||||
yyerrlab1: /* here on error raised explicitly by an action */
|
||||
|
||||
if (yyerrstatus == 3)
|
||||
{
|
||||
/* if just tried and failed to reuse lookahead token after an error, discard it. */
|
||||
|
||||
/* return failure if at end of input */
|
||||
if (yychar == YYEOF)
|
||||
YYABORT;
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
|
||||
#endif
|
||||
|
||||
yychar = YYEMPTY;
|
||||
}
|
||||
|
||||
/* Else will try to reuse lookahead token
|
||||
after shifting the error token. */
|
||||
|
||||
yyerrstatus = 3; /* Each real token shifted decrements this */
|
||||
|
||||
goto yyerrhandle;
|
||||
|
||||
yyerrdefault: /* current state does not do anything special for the error token. */
|
||||
|
||||
#if 0
|
||||
/* This is wrong; only states that explicitly want error tokens
|
||||
should shift them. */
|
||||
yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
|
||||
if (yyn) goto yydefault;
|
||||
#endif
|
||||
|
||||
yyerrpop: /* pop the current state because it cannot handle the error token */
|
||||
|
||||
if (yyssp == yyss) YYABORT;
|
||||
yyvsp--;
|
||||
yystate = *--yyssp;
|
||||
#ifdef YYLSP_NEEDED
|
||||
yylsp--;
|
||||
#endif
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
{
|
||||
short *ssp1 = yyss - 1;
|
||||
fprintf (stderr, "Error: state stack now");
|
||||
while (ssp1 != yyssp)
|
||||
fprintf (stderr, " %d", *++ssp1);
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
yyerrhandle:
|
||||
|
||||
yyn = yypact[yystate];
|
||||
if (yyn == YYFLAG)
|
||||
goto yyerrdefault;
|
||||
|
||||
yyn += YYTERROR;
|
||||
if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
|
||||
goto yyerrdefault;
|
||||
|
||||
yyn = yytable[yyn];
|
||||
if (yyn < 0)
|
||||
{
|
||||
if (yyn == YYFLAG)
|
||||
goto yyerrpop;
|
||||
yyn = -yyn;
|
||||
goto yyreduce;
|
||||
}
|
||||
else if (yyn == 0)
|
||||
goto yyerrpop;
|
||||
|
||||
if (yyn == YYFINAL)
|
||||
YYACCEPT;
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
fprintf(stderr, "Shifting error token, ");
|
||||
#endif
|
||||
|
||||
*++yyvsp = yylval;
|
||||
#ifdef YYLSP_NEEDED
|
||||
*++yylsp = yylloc;
|
||||
#endif
|
||||
|
||||
yystate = yyn;
|
||||
goto yynewstate;
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
// NOTE: this makes it more convinient for me to make the help screen fancier...
|
||||
// blah... not that anybody cares...
|
||||
|
||||
printf("\
|
||||
Usage:\n\
|
||||
mIFF {-%c <filename>|--%s=<filename>}\n\
|
||||
[{-%c <filename>|--%s=<filename>} | {-%c|--%s}]\n\
|
||||
[{-%c|--%s}] [{-%c|--%s}] [{-%c|--%s}]\n\n",
|
||||
SNAME_INPUT_FILE, LNAME_INPUT_FILE,
|
||||
SNAME_OUTPUT_FILE, LNAME_OUTPUT_FILE,
|
||||
SNAME_PRAGMA_TARGET, LNAME_PRAGMA_TARGET,
|
||||
SNAME_CCCP, LNAME_CCCP,
|
||||
SNAME_VERBOSE, LNAME_VERBOSE,
|
||||
SNAME_DEBUG, LNAME_DEBUG);
|
||||
printf("\
|
||||
mIFF {-%c|--%s}\n\n", SNAME_HELP, LNAME_HELP);
|
||||
|
||||
printf("\
|
||||
Parameters:\n\
|
||||
-%c <filename>,--%s=<filename>\n\
|
||||
[required] specifies the input path for IFF source file.\n", SNAME_INPUT_FILE, LNAME_INPUT_FILE);
|
||||
printf("\
|
||||
-%c <filename>,--%s=<filename>\n\
|
||||
[optional] specifies the pathname for the generated \n\
|
||||
IFF data file. Note that if neither this nor the following \n\
|
||||
option are specified, a default output filename of the source\n\
|
||||
file's base name with extension \".iff\" will be used.\n", SNAME_OUTPUT_FILE, LNAME_OUTPUT_FILE);
|
||||
printf("\
|
||||
-%c,--%s\n\
|
||||
[optional] specifies the generated output filename should be \n\
|
||||
taken from the #pragma options within the source file. \n\
|
||||
Allowable #pragma options are: \n\
|
||||
#pragma drive \"<drive letter>:\"\n\
|
||||
#pragma directory \"<directory name>\"\n\
|
||||
#pragma filename \"<filename>\"\n\
|
||||
#pragma extension \"<extension>\"\n", SNAME_PRAGMA_TARGET, LNAME_PRAGMA_TARGET);
|
||||
printf("\
|
||||
-%c,--%s\n\
|
||||
[optional] use CCCP rather than CPP.\n", SNAME_CCCP, LNAME_CCCP);
|
||||
printf("\
|
||||
-%c,--%s\n\
|
||||
[optional] display more information during execution.\n", SNAME_VERBOSE, LNAME_VERBOSE);
|
||||
printf("\
|
||||
-%c,--%s\n\
|
||||
[optional] enable debug mode (save intermediate files).\n", SNAME_DEBUG, LNAME_DEBUG);
|
||||
printf("\
|
||||
-%c,--%s\n\
|
||||
[very optional] this help screen.\n", SNAME_HELP, LNAME_HELP);
|
||||
printf("\
|
||||
Examples:\n\
|
||||
mIFF -%c foo.bar\n\
|
||||
this will generate an iff file foo.iff (default if no parm specified)\n\
|
||||
in the current working directory. Even if foo.bar contains #pragma, \n\
|
||||
it will create foo.iff because -%c was not specified.\n", SNAME_INPUT_FILE, SNAME_PRAGMA_TARGET);
|
||||
printf("\
|
||||
mIFF -%c \"C:\\my project\\myData\\foo.iff\" --%s=foo.bar\n\
|
||||
notice that if you have space in your dirname, use \" to encapsulate \n\
|
||||
it.\n", SNAME_OUTPUT_FILE, LNAME_INPUT_FILE);
|
||||
printf("\
|
||||
mIFF -%c foo.bar --%s\n\
|
||||
will generate output file specified by #pragma statements \n\
|
||||
within file foo.bar.\n", SNAME_INPUT_FILE, LNAME_PRAGMA_TARGET);
|
||||
@@ -0,0 +1,958 @@
|
||||
//===========================================================================
|
||||
//
|
||||
// FILENAME: mIFF.cpp [C:\Projects\new\tools\src\miff\src\]
|
||||
// COPYRIGHT: (C) 1999 BY Bootprint Entertainment
|
||||
//
|
||||
// DESCRIPTION: make IFF (Console version)
|
||||
// AUTHOR: Hideki Ikeda
|
||||
// DATE: 1/07/99 12:57:20 PM
|
||||
//
|
||||
// HISTORY: 1/07/99 [HAI] - File created
|
||||
// : 1/07/99 [HAI] - v1.0 introductory version
|
||||
// : 1/12/99 [HAI] - v1.1 switched from DOS to Engine library
|
||||
// : - first attempt was to setup the main entry
|
||||
// : point via ConsoleEntryPoint() via callback
|
||||
// : 1/29/99 [HAI] - changed the parameter in MIFFMessage to allow
|
||||
// : output even in non-verbose mode (for error
|
||||
// : message purpose.
|
||||
// : 05/07/99 [HAI]- added MIFFallocString() and MIFFfreeString()
|
||||
// : to work with memory manager. they are allocated
|
||||
// : in the lexical analyzer for IDENTIFIERS and STR_LIT
|
||||
// : deleted after parser parses the rule.
|
||||
//
|
||||
// FUNCTION: main()
|
||||
// : evaluateArgs()
|
||||
// : help()
|
||||
// : handleError()
|
||||
// : preprocessSource()
|
||||
// : MIFFMessage()
|
||||
// : callbackFunction()
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
//========================================================== include files ==
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
|
||||
#include "sharedCompression/SetupSharedCompression.h"
|
||||
#include "sharedDebug/SetupSharedDebug.h"
|
||||
#include "sharedFile/SetupSharedFile.h"
|
||||
#include "sharedFile/TreeFile.h"
|
||||
#include "sharedFoundation/CommandLine.h"
|
||||
#include "sharedFoundation/Crc.h"
|
||||
#include "sharedFoundation/Os.h"
|
||||
#include "sharedFoundation/SetupSharedFoundation.h"
|
||||
#include "sharedMemoryManager/MemoryManager.h"
|
||||
#include "sharedThread/SetupSharedThread.h"
|
||||
|
||||
#include "InputFileHandler.h"
|
||||
#include "OutputFileHandler.h"
|
||||
|
||||
#include <string.h> // for memset()
|
||||
#include <stdio.h> // FILE stuff
|
||||
#include <unistd.h> // for getcwd()
|
||||
#include <stdlib.h> // for tolower()
|
||||
|
||||
//================================================= static vars assignment ==
|
||||
const int entryPointVersion = 1; // constantly check DataEntryPoint.h to see if this value has changed
|
||||
|
||||
OutputFileHandler *outfileHandler = NULL;
|
||||
const int bufferSize = 16 * 1024 * 1024;
|
||||
const int maxStringSize = 256;
|
||||
const char version[] = "1.3 September 18, 2000";
|
||||
|
||||
// vars set by pragmas or via command line
|
||||
char drive[8]; // should be no more then 2 char "C:"
|
||||
char directory[maxStringSize];
|
||||
char filename[maxStringSize];
|
||||
char extension[8]; // we'll truncate if the extension is more then 8 chars...
|
||||
char inFileName[512];
|
||||
|
||||
// switches to be sent to mIFF Compiler
|
||||
char sourceBuffer[bufferSize];
|
||||
char outFileName[512]; // x2 to combine filename, dir, and ext
|
||||
bool usePragma = false;
|
||||
bool useCCCP = false;
|
||||
bool verboseMode = false; // default to non-verbose mode
|
||||
bool debugMode = false; // set this on and the preprocessed source file (miff.$$$) won't be deleted
|
||||
|
||||
static bool runningUnderNT;
|
||||
|
||||
enum errorType {
|
||||
ERR_FILENOTFOUND = -1,
|
||||
ERR_ARGSTOOFEW = -2,
|
||||
ERR_BUFFERTOOSMALL = -3,
|
||||
ERR_UNKNOWNDIR = -4,
|
||||
ERR_PREPROCESS = -5,
|
||||
ERR_MULTIPLEINFILE = -6,
|
||||
ERR_PARSER = -7,
|
||||
ERR_ENGINE = -8,
|
||||
|
||||
ERR_HELPREQUEST = -9,
|
||||
ERR_OPTIONS = -10,
|
||||
|
||||
ERR_WRITEERROR = -11,
|
||||
|
||||
ERR_NONE = 0
|
||||
};
|
||||
char err_msg[256];
|
||||
errorType errorFlag = ERR_NONE; // assume no error (default)
|
||||
|
||||
|
||||
// long and short name definitions for command line options
|
||||
|
||||
static const char * const LNAME_HELP = "help";
|
||||
static const char * const LNAME_INPUT_FILE = "inputfile";
|
||||
static const char * const LNAME_OUTPUT_FILE = "outputfile";
|
||||
static const char * const LNAME_PRAGMA_TARGET = "pragmatarget";
|
||||
static const char * const LNAME_CCCP = "cccp";
|
||||
static const char * const LNAME_VERBOSE = "verbose";
|
||||
static const char * const LNAME_DEBUG = "debug";
|
||||
|
||||
static const char SNAME_HELP = 'h';
|
||||
static const char SNAME_INPUT_FILE = 'i';
|
||||
static const char SNAME_OUTPUT_FILE = 'o';
|
||||
static const char SNAME_PRAGMA_TARGET = 'p';
|
||||
static const char SNAME_CCCP = 'c';
|
||||
static const char SNAME_VERBOSE = 'v';
|
||||
static const char SNAME_DEBUG = 'd';
|
||||
|
||||
// following is the command line option spec tree needed for command line processing
|
||||
static CommandLine::OptionSpec optionSpecArray[] =
|
||||
{
|
||||
OP_BEGIN_SWITCH(OP_NODE_REQUIRED),
|
||||
|
||||
// help
|
||||
OP_SINGLE_SWITCH_NODE(SNAME_HELP, LNAME_HELP, OP_ARG_NONE, OP_MULTIPLE_DENIED),
|
||||
|
||||
// real options
|
||||
OP_BEGIN_SWITCH_NODE(OP_MULTIPLE_DENIED),
|
||||
OP_BEGIN_LIST(),
|
||||
// input filename required
|
||||
OP_SINGLE_LIST_NODE(SNAME_INPUT_FILE, LNAME_INPUT_FILE, OP_ARG_REQUIRED, OP_MULTIPLE_DENIED, OP_NODE_REQUIRED),
|
||||
|
||||
// optional, mutually exclusive output file specification options
|
||||
// if none specified, generate derive output filename from input filename
|
||||
OP_BEGIN_LIST_NODE(OP_MULTIPLE_DENIED, OP_NODE_OPTIONAL),
|
||||
OP_BEGIN_SWITCH(OP_NODE_OPTIONAL),
|
||||
// specify output filename on command line
|
||||
OP_SINGLE_SWITCH_NODE(SNAME_OUTPUT_FILE, LNAME_OUTPUT_FILE, OP_ARG_REQUIRED, OP_MULTIPLE_DENIED),
|
||||
|
||||
// use pragma target for output filename
|
||||
OP_SINGLE_SWITCH_NODE(SNAME_PRAGMA_TARGET, LNAME_PRAGMA_TARGET, OP_ARG_NONE, OP_MULTIPLE_DENIED),
|
||||
OP_END_SWITCH(),
|
||||
OP_END_LIST_NODE(),
|
||||
|
||||
// if specified, use cccp instead of cpp
|
||||
OP_SINGLE_LIST_NODE(SNAME_CCCP, LNAME_CCCP, OP_ARG_NONE, OP_MULTIPLE_DENIED, OP_NODE_OPTIONAL),
|
||||
|
||||
// if specified, be verbose
|
||||
OP_SINGLE_LIST_NODE(SNAME_VERBOSE, LNAME_VERBOSE, OP_ARG_NONE, OP_MULTIPLE_DENIED, OP_NODE_OPTIONAL),
|
||||
|
||||
// if specified, enter debug info
|
||||
OP_SINGLE_LIST_NODE(SNAME_DEBUG, LNAME_DEBUG, OP_ARG_NONE, OP_MULTIPLE_DENIED, OP_NODE_OPTIONAL),
|
||||
OP_END_LIST(),
|
||||
OP_END_SWITCH_NODE(),
|
||||
|
||||
OP_END_SWITCH()
|
||||
};
|
||||
static const int optionSpecCount = sizeof(optionSpecArray) / sizeof(optionSpecArray[0]);
|
||||
|
||||
//================================================= function prototypes ==
|
||||
int main(int argc, char *argv[]);
|
||||
static errorType evaluateArgs(void);
|
||||
static void help(void);
|
||||
static void handleError(errorType error);
|
||||
static int preprocessSource(char *sourceName);
|
||||
static void callbackFunction(void);
|
||||
static errorType loadInputToBuffer(void *destAddr, int maxBufferSize);
|
||||
|
||||
// functions called by parser.yac and parser.lex
|
||||
extern "C" void MIFFMessage(char *msg, int forceOut);
|
||||
extern "C" void MIFFSetError(void);
|
||||
extern "C" void MIFFSetIFFName(const char *newFileName);
|
||||
extern "C" void MIFFinsertForm(const char *formName);
|
||||
extern "C" void MIFFinsertChunk(const char *chunkName);
|
||||
extern "C" void MIFFinsertChunkData(void * buffer, unsigned bufferSize);
|
||||
extern "C" int MIFFloadRawData(char *fname, void * buffer, unsigned maxBufferSize);
|
||||
extern "C" void MIFFexitChunk(void);
|
||||
extern "C" void MIFFexitForm(void);
|
||||
extern "C" unsigned long MIFFgetLabelHash(char *inputStream);
|
||||
|
||||
// external functions found in parser.lex file
|
||||
extern "C" void MIFFCompile(char *inputStream, char *inputFname);
|
||||
extern "C" void MIFFCompileInit(char *inputStream, char *inputFname);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// main entry point from console call
|
||||
//
|
||||
// Return Value:
|
||||
// errorType - see enumeration; 0 if no errors
|
||||
//
|
||||
// Remarks:
|
||||
//
|
||||
//
|
||||
// See Also:
|
||||
//
|
||||
//
|
||||
// Revisions and History:
|
||||
// 1/07/99 [HAI] - created
|
||||
//
|
||||
int main( int argc, // number of args in commandline
|
||||
char * argv[] // list of pointers to strings
|
||||
)
|
||||
{
|
||||
memset(sourceBuffer, 0, bufferSize);
|
||||
|
||||
SetupSharedThread::install();
|
||||
SetupSharedDebug::install(4096);
|
||||
|
||||
SetupSharedFoundation::Data SetupSharedFoundationData (SetupSharedFoundation::Data::D_console);
|
||||
SetupSharedFoundationData.argc = argc;
|
||||
SetupSharedFoundationData.argv = argv;
|
||||
SetupSharedFoundation::install (SetupSharedFoundationData);
|
||||
|
||||
SetupSharedCompression::install();
|
||||
|
||||
SetupSharedFile::install(false);
|
||||
|
||||
TreeFile::addSearchAbsolute(0);
|
||||
TreeFile::addSearchPath (".", 0);
|
||||
|
||||
SetupSharedFoundation::callbackWithExceptionHandling(callbackFunction);
|
||||
SetupSharedFoundation::remove();
|
||||
|
||||
SetupSharedThread::remove();
|
||||
return static_cast<int> (errorFlag);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// callback function for Engine's console entry point
|
||||
//
|
||||
// Return Value:
|
||||
// none
|
||||
//
|
||||
// Remarks:
|
||||
// this is like a substitute of main()
|
||||
//
|
||||
// See Also:
|
||||
//
|
||||
//
|
||||
// Revisions and History:
|
||||
// 1/12/99 [HAI] - created
|
||||
//
|
||||
static void callbackFunction(void)
|
||||
{
|
||||
outfileHandler = NULL;
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
// check if we're running under NT
|
||||
OSVERSIONINFO osInfo;
|
||||
Zero(osInfo);
|
||||
|
||||
osInfo.dwOSVersionInfoSize = sizeof(osInfo);
|
||||
const BOOL getVersionResult = GetVersionEx(&osInfo);
|
||||
if (getVersionResult)
|
||||
runningUnderNT = (osInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
|
||||
if (runningUnderNT)
|
||||
DEBUG_REPORT_LOG(true, ("MIFF: running under Windows NT platform\n"));
|
||||
else
|
||||
DEBUG_REPORT_LOG(true, ("MIFF: running under non-NT Windows platform\n"));
|
||||
|
||||
#endif
|
||||
|
||||
errorFlag = evaluateArgs();
|
||||
if (ERR_NONE == errorFlag)
|
||||
{
|
||||
outfileHandler = new OutputFileHandler(outFileName);
|
||||
MIFFCompile(sourceBuffer, inFileName);
|
||||
}
|
||||
else
|
||||
handleError(errorFlag);
|
||||
|
||||
if (outfileHandler)
|
||||
{
|
||||
// only write output IF there was no error
|
||||
if (ERR_NONE == errorFlag)
|
||||
{
|
||||
if (!outfileHandler->writeBuffer())
|
||||
{
|
||||
fprintf(stderr, "MIFF: failed to write output file \"%s\"\n", outFileName);
|
||||
errorFlag = ERR_WRITEERROR;
|
||||
}
|
||||
}
|
||||
delete outfileHandler;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Evaluates the command line and sets up the environment variables required for mIFF to function
|
||||
//
|
||||
// Return Value:
|
||||
// errorType
|
||||
//
|
||||
// Remarks:
|
||||
// argc's and argv's are substituted with CommandLine::functions()
|
||||
//
|
||||
// See Also:
|
||||
//
|
||||
//
|
||||
// Revisions and History:
|
||||
// 1/07/99 [HAI] - created
|
||||
//
|
||||
static errorType evaluateArgs(void)
|
||||
{
|
||||
errorType retVal = ERR_NONE;
|
||||
|
||||
// parse the commandline
|
||||
const CommandLine::MatchCode mc = CommandLine::parseOptions(optionSpecArray, optionSpecCount);
|
||||
if (mc != CommandLine::MC_MATCH)
|
||||
{
|
||||
// -TF- add call to retrieve command line error buffer for display (as soon as it is written!)
|
||||
printf("WARNING: usage error detected, printing help.\n");
|
||||
help();
|
||||
return ERR_OPTIONS;
|
||||
}
|
||||
else if (CommandLine::getOccurrenceCount(SNAME_HELP))
|
||||
{
|
||||
// user specified help
|
||||
help();
|
||||
retVal = ERR_HELPREQUEST;
|
||||
return(retVal);
|
||||
}
|
||||
|
||||
// at this point, we can assume a valid combination of options has been specified on the commandline
|
||||
|
||||
|
||||
// setup input filename
|
||||
strcpy(inFileName, CommandLine::getOptionString(SNAME_INPUT_FILE));
|
||||
|
||||
|
||||
// handle output filename spec
|
||||
if (CommandLine::getOccurrenceCount(SNAME_OUTPUT_FILE))
|
||||
{
|
||||
strcpy(outFileName, CommandLine::getOptionString(SNAME_OUTPUT_FILE));
|
||||
}
|
||||
else if (CommandLine::getOccurrenceCount(SNAME_PRAGMA_TARGET))
|
||||
{
|
||||
// use pragma target within iff source for output filename
|
||||
usePragma = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// no output option specified on commandline, derive from input filename
|
||||
char *terminator;
|
||||
|
||||
// start with input file pathname
|
||||
strcpy(outFileName, inFileName);
|
||||
|
||||
// try to terminate at rightmost '.'
|
||||
terminator = strrchr(outFileName, '.');
|
||||
if (terminator)
|
||||
*terminator = 0;
|
||||
|
||||
// append the default iff extension
|
||||
strcat(outFileName, ".iff");
|
||||
}
|
||||
|
||||
|
||||
// handle options (get them out of the way, as we use them later)
|
||||
useCCCP = (CommandLine::getOccurrenceCount(SNAME_CCCP) != 0);
|
||||
verboseMode = (CommandLine::getOccurrenceCount(SNAME_VERBOSE) != 0);
|
||||
debugMode = (CommandLine::getOccurrenceCount(SNAME_DEBUG) != 0);
|
||||
|
||||
|
||||
// preprocess the input file
|
||||
if (0 == preprocessSource(inFileName))
|
||||
{
|
||||
if (verboseMode)
|
||||
{
|
||||
sprintf(err_msg,"Now compiling %s...\n", inFileName);
|
||||
MIFFMessage(err_msg, 0);
|
||||
}
|
||||
if (ERR_NONE == retVal)
|
||||
retVal = loadInputToBuffer(sourceBuffer, bufferSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
// preprocessSource returned an error...
|
||||
retVal = ERR_PREPROCESS;
|
||||
}
|
||||
if (retVal != ERR_NONE)
|
||||
return retVal;
|
||||
|
||||
return retVal;
|
||||
|
||||
#if 0
|
||||
|
||||
errorType retVal = ERR_NONE; // assume no error has been found
|
||||
bool outPathUsed = false; // flag to monitor if -o flag was used, if so, we can ignore -d, -p, -e, -f
|
||||
bool inFileEntered = false;
|
||||
int argc = CommandLine::getPlainCount();
|
||||
|
||||
// get default values from DOS
|
||||
char currentDir[maxStringSize];
|
||||
if (NULL == getcwd(currentDir, maxStringSize)) // get current working directory
|
||||
{
|
||||
retVal = ERR_UNKNOWNDIR;
|
||||
return(retVal);
|
||||
}
|
||||
drive[0] = currentDir[0]; // drive letter
|
||||
drive[1] = 0; // and null terminate it
|
||||
strcpy(extension, "IFF"); // default to uppercase .IFF
|
||||
strcpy(directory, ¤tDir[2]); // get everything after the Drive: including the first backslash
|
||||
filename[0] = 0;
|
||||
|
||||
// see specs.txt for requests
|
||||
// scan for any argv's that has '-' in the argv[n][0]'s character
|
||||
for (int index = 0; index < argc; index++) // note: if using argv[] rather then CommandLine::getPlainString() then start with 1 rather then 0
|
||||
{
|
||||
if ('-' == CommandLine::getPlainString(index)[0])
|
||||
{
|
||||
// we've found a parameter switch
|
||||
switch (tolower(CommandLine::getPlainString(index)[1])) // assume non case sensitive switches
|
||||
{
|
||||
case 'i': // install via #pragma
|
||||
{
|
||||
usePragma = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'c': // use CCCP instead of CPP
|
||||
useCCCP = true;
|
||||
break;
|
||||
|
||||
case 'v': // don't show any debug message
|
||||
verboseMode = true;
|
||||
break;
|
||||
|
||||
case '$':
|
||||
debugMode = true;
|
||||
break;
|
||||
|
||||
case 'o': // target output file name and path (complete path)
|
||||
{
|
||||
index++; // next param
|
||||
outPathUsed = true;
|
||||
strcpy(outFileName, CommandLine::getPlainString(index));
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
case 'd': // target drive letter (-p must be present)
|
||||
{
|
||||
if (!outPathUsed)
|
||||
{
|
||||
index++; // next param
|
||||
strcpy(drive, CommandLine::getPlainString(index));
|
||||
}
|
||||
else
|
||||
index++; // skip the drive letter arg that SHOULD follow the -d option
|
||||
break;
|
||||
}
|
||||
|
||||
case 'p': // target pathname
|
||||
{
|
||||
if (!outPathUsed)
|
||||
{
|
||||
index++; // next param
|
||||
strcpy(directory, CommandLine::getPlainString(index));
|
||||
}
|
||||
else
|
||||
index++; // skip the pathname arg that follows the -p option
|
||||
break;
|
||||
}
|
||||
|
||||
case 'f': // target filename
|
||||
{
|
||||
if (!outPathUsed)
|
||||
{
|
||||
index++; // next param
|
||||
strcpy(filename, CommandLine::getPlainString(index));
|
||||
}
|
||||
else
|
||||
index++; // skip the filename arg that follows the -f
|
||||
break;
|
||||
}
|
||||
|
||||
case 'e': // target extension
|
||||
{
|
||||
if (!outPathUsed)
|
||||
{
|
||||
index++; // next param
|
||||
strcpy(extension, CommandLine::getPlainString(index));
|
||||
}
|
||||
else
|
||||
index++; // skip the extension arg that follows the -e
|
||||
break;
|
||||
}
|
||||
|
||||
case 'h': // help!
|
||||
case '?':
|
||||
{
|
||||
help();
|
||||
index = argc; // force to exit
|
||||
retVal = ERR_HELPREQUEST;
|
||||
return(retVal); // special case, ONLY time I call return() in the middle of the function (because I check for argc < 2 at the end of the code)
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
sprintf(err_msg, "\nUnknown parameter %s, use -h to seek help...\n", CommandLine::getPlainString(index));
|
||||
MIFFMessage(err_msg, 1);
|
||||
index = argc; // force to exit
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// we found an arg that doesn't start with '-' so let's assume it's a filename
|
||||
if (!inFileEntered)
|
||||
{
|
||||
strcpy(inFileName, CommandLine::getPlainString(index));
|
||||
inFileEntered = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
retVal = ERR_MULTIPLEINFILE;
|
||||
index = argc;
|
||||
}
|
||||
|
||||
// now construct the DEFAULT filename for this file by scanning backwards to front and only extracting the filename (no extension, no path)
|
||||
if (ERR_NONE == retVal)
|
||||
{
|
||||
char sourceName[maxStringSize];
|
||||
strcpy(sourceName, inFileName); // make a duplicate for us to play with
|
||||
for (int strIndex = strlen(sourceName); strIndex > 0; strIndex--)
|
||||
{
|
||||
if ('.' == sourceName[strIndex])
|
||||
sourceName[strIndex] = 0; // put a stopper here... we are assuming that '.' indicates extension! I'm going to assume that the person is just testing me if s/he decides to use filename like "foo.bar.psych" which will truncate to "foo"
|
||||
if ('\\' == sourceName[strIndex])
|
||||
break; // get out, for we've reached the path name...
|
||||
}
|
||||
|
||||
// ok, by here, strIndex should point to either beginning of the string, or where the first '\' was found scanning backwards
|
||||
strcpy(filename, &sourceName[strIndex]); // ta-da-!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (inFileEntered)
|
||||
{
|
||||
if (0 == preprocessSource(inFileName))
|
||||
{
|
||||
if (verboseMode)
|
||||
{
|
||||
// using err_msg as my temp buffer...
|
||||
sprintf(err_msg,"Now compiling %s\n", inFileName);
|
||||
MIFFMessage(err_msg, 0);
|
||||
}
|
||||
|
||||
if (ERR_NONE == retVal)
|
||||
retVal = loadInputToBuffer(sourceBuffer, bufferSize);
|
||||
}
|
||||
else // preprocessSource returned an error...
|
||||
{
|
||||
retVal = ERR_PREPROCESS;
|
||||
}
|
||||
}
|
||||
else // inFileEntered == false
|
||||
{
|
||||
MIFFMessage("Missing input filename in command line!", 1);
|
||||
}
|
||||
|
||||
// construct a outFileName[] based on drive[], directory[], filename[], and extension[]
|
||||
if (!outPathUsed && (ERR_NONE == retVal))
|
||||
{
|
||||
if (inFileName[0]) // make sure the user has entered a input filename
|
||||
sprintf(outFileName,"%s:%s\\%s.%s", drive, directory, filename, extension);
|
||||
}
|
||||
|
||||
if (argc < 1)
|
||||
retVal = ERR_ARGSTOOFEW; // we can do this because we know -h was not entered...
|
||||
|
||||
return(retVal);
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// reads the tmeporary files spit out by CCCP and stuffs the plain text into source buffer
|
||||
//
|
||||
// Return Value:
|
||||
// errorType
|
||||
//
|
||||
// Remarks:
|
||||
//
|
||||
//
|
||||
// See Also:
|
||||
//
|
||||
//
|
||||
// Revisions and History:
|
||||
// 1/14/99 [HAI] - created
|
||||
//
|
||||
static errorType loadInputToBuffer(
|
||||
void * dest, // destination address of where you want the date to be read
|
||||
int maxBufferSize // maximum destination data pool size
|
||||
)
|
||||
{
|
||||
errorType retVal = ERR_NONE;
|
||||
InputFileHandler *inFileHandler = new InputFileHandler("miff.$$$");
|
||||
if (inFileHandler)
|
||||
{
|
||||
int sizeRead = inFileHandler->read(dest, maxBufferSize);
|
||||
if (sizeRead >= maxBufferSize)
|
||||
{
|
||||
retVal = ERR_BUFFERTOOSMALL;
|
||||
}
|
||||
else
|
||||
{
|
||||
reinterpret_cast<char *>(dest)[sizeRead] = 0; // so stupid... but if you don't zero-terminate at exact spot, YYInput may chokes because of extra grammer that may exist...
|
||||
}
|
||||
if (!debugMode)
|
||||
inFileHandler->deleteFile("miff.$$$", true); // no need for temp file now...
|
||||
|
||||
// we've successfully read the file, now close it...
|
||||
delete inFileHandler;
|
||||
}
|
||||
else // inFileName is NULL
|
||||
{
|
||||
retVal = ERR_FILENOTFOUND;
|
||||
}
|
||||
|
||||
return(retVal);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// help function called by main upon -h switch
|
||||
//
|
||||
// Return Value:
|
||||
// none
|
||||
//
|
||||
// Remarks:
|
||||
// #include's mIFF.dox
|
||||
// make sure to update the version when modified.
|
||||
// Notice that help() does NOT go thru MIFFMessage() because we want it to
|
||||
// print out whether it's verbose mode or not...
|
||||
//
|
||||
// See Also:
|
||||
// mIFF.dox
|
||||
//
|
||||
// Revisions and History:
|
||||
// 1/07/99 [HAI] - created
|
||||
//
|
||||
static void help(void)
|
||||
{
|
||||
printf("\nmIFF v%s (DOS version) - Bootprint Ent. (c) 1999\n", version);
|
||||
printf("Hideki Ikeda\n");
|
||||
#include "mIFF.dox"
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// upon exit from main(), if error has been found, it calls here to inform the user of the type of errors it has encounted.
|
||||
//
|
||||
// Return Value:
|
||||
// none
|
||||
//
|
||||
// Remarks:
|
||||
// use -q switch to suppress error messages - but in shell, return value can be used to determine the handling
|
||||
//
|
||||
// See Also:
|
||||
//
|
||||
//
|
||||
// Revisions and History:
|
||||
// 1/07/99 [HAI] - created
|
||||
//
|
||||
static void handleError(errorType error)
|
||||
{
|
||||
if (ERR_NONE == error)
|
||||
return;
|
||||
|
||||
switch (error)
|
||||
{
|
||||
case ERR_NONE:
|
||||
break;
|
||||
|
||||
case ERR_FILENOTFOUND:
|
||||
MIFFMessage("ERROR: INPUT File not found!\n", 1);
|
||||
break;
|
||||
|
||||
case ERR_ARGSTOOFEW:
|
||||
MIFFMessage("ERROR: Not enough arguments. Use -h for help.\n", 1);
|
||||
break;
|
||||
|
||||
case ERR_BUFFERTOOSMALL:
|
||||
MIFFMessage("ERROR: Internally allocated buffer for reading\nsource code is too small, increase buffer and re-compile\n", 1);
|
||||
break;
|
||||
|
||||
case ERR_UNKNOWNDIR:
|
||||
MIFFMessage("ERROR: Directory unknown...\n", 1);
|
||||
break;
|
||||
|
||||
case ERR_PREPROCESS:
|
||||
MIFFMessage("ERROR: Possible problems running the GNU C Preprocessor.\n", 1);
|
||||
break;
|
||||
|
||||
case ERR_MULTIPLEINFILE:
|
||||
MIFFMessage("ERROR: There can only be ONE inputfile name.\nPerhaps you've forgotten the -o option flag\n", 1);
|
||||
break;
|
||||
|
||||
case ERR_ENGINE:
|
||||
MIFFMessage("ERROR: Engine returned a non-zero value...\n", 1);
|
||||
break;
|
||||
|
||||
case ERR_PARSER:
|
||||
MIFFMessage("ERROR: Parser error\n", 1);
|
||||
break;
|
||||
|
||||
case ERR_HELPREQUEST:
|
||||
break;
|
||||
|
||||
case ERR_OPTIONS:
|
||||
MIFFMessage("ERROR: Failed to handle command line options\n", 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
MIFFMessage("ERROR: Unknown error, you suck!\n", 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// gotta write all these externs because you can't call C++ class based non-static
|
||||
// functions from C... So we will use here as the bridge between the two
|
||||
// languages
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Message output handler called by ALL external "C" functions
|
||||
//
|
||||
// Return Value:
|
||||
// none
|
||||
//
|
||||
// Remarks:
|
||||
// all the messages that are displayed are channeled thru this function. Note the -q quiet mode suppresses all messages.
|
||||
// this is an extern "C" function
|
||||
//
|
||||
// See Also:
|
||||
// yyerror()
|
||||
//
|
||||
// Revisions and History:
|
||||
// 1/07/99 [] - created
|
||||
//
|
||||
extern "C" void MIFFMessage(char *message, // null terminated string to be displayed
|
||||
int forceOutput) // if non-zero, it will print out even in quiet mode (for ERRORs)
|
||||
{
|
||||
if (forceOutput)
|
||||
fprintf(stdout, "%s\n", message);
|
||||
else if (verboseMode)
|
||||
fprintf(stdout, "%s\n", message);
|
||||
OutputDebugString(message);
|
||||
OutputDebugString("\n");
|
||||
}
|
||||
|
||||
// Only call this via parser!!!
|
||||
extern "C" void MIFFSetError(void)
|
||||
{
|
||||
errorFlag = ERR_PARSER;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// validation of the filename passed are legal.
|
||||
//
|
||||
// Return Value:
|
||||
// bool usePragma - whether #pragma is ignored or not
|
||||
//
|
||||
// Remarks:
|
||||
// if -i switch is used then #pragma's are expected
|
||||
// this is an extern "C" function
|
||||
//
|
||||
// See Also:
|
||||
//
|
||||
//
|
||||
// Revisions and History:
|
||||
// 1/07/99 [ ] - created
|
||||
//
|
||||
extern "C" int validateTargetFilename( char *targetFileName, // pointer to where we can store the string filename
|
||||
unsigned maxTargetBufSize // size of the filename string buffer
|
||||
)
|
||||
{
|
||||
if (strlen(outFileName) > maxTargetBufSize)
|
||||
MIFFMessage("Internal error, increase string buffer size in parser.yac and recompile!", 1);
|
||||
|
||||
strcpy(targetFileName, outFileName);
|
||||
|
||||
return(usePragma);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// function calls CCCP or CPP via shell to preprocess the source code for #include's and #define's via C-Compatible Compiler Preprocessor
|
||||
//
|
||||
// Return Value:
|
||||
// shell return value (4DOS is very generous on returning different values, while DOS just returns 0 all the time)
|
||||
//
|
||||
// Remarks:
|
||||
// use -c switch to use CCCP rather then CPP in your search path
|
||||
//
|
||||
// See Also:
|
||||
//
|
||||
//
|
||||
// Revisions and History:
|
||||
// 1/07/99 [ ] - created
|
||||
//
|
||||
static int preprocessSource(char *sourceName)
|
||||
{
|
||||
char shellCommand[512];
|
||||
int retVal = 0;
|
||||
|
||||
memset(shellCommand, 0, sizeof(shellCommand));
|
||||
|
||||
// if (!runningUnderNT)
|
||||
{
|
||||
|
||||
if (verboseMode)
|
||||
MIFFMessage("Preprocessing... via CCCP", 0);
|
||||
|
||||
// CCCP parameters:
|
||||
// -nostdinc -nostdinc++ - do NOT search for standard include directory; without this, your
|
||||
// puter would be just twiddling its thumb because CCCP can't find it...
|
||||
// -pedantic - issue warnings (use pedantic-errors if you want it as errors)
|
||||
// required by the ANSI C standard in certain cases such as comments that
|
||||
// follow the #else/#endif
|
||||
// -dD - output #defines (for the purpose of error msg I parse)
|
||||
// -H - display the name of the header/included files (verbose mode)
|
||||
// -P - originally, I had this... so it won't show the # line_num "filename" ???
|
||||
if (!useCCCP && verboseMode)
|
||||
{
|
||||
sprintf(shellCommand, "cpp -nostdinc -nostdinc++ -x c++ -pedantic -Wall -dD -H %s 'miff.$$$'", sourceName);
|
||||
}
|
||||
else if (!useCCCP && !verboseMode)
|
||||
{
|
||||
sprintf(shellCommand, "cpp -nostdinc -nostdinc++ -x c++ -pedantic -Wall -dD %s 'miff.$$$'", sourceName);
|
||||
}
|
||||
else if (useCCCP && verboseMode)
|
||||
{
|
||||
sprintf(shellCommand, "cccp -nostdinc -nostdinc++ -x c++ -pedantic -Wall -dD -H %s 'miff.$$$'", sourceName);
|
||||
}
|
||||
else
|
||||
sprintf(shellCommand, "cccp -nostdinc -nostdinc++ -x c++ -pedantic -Wall -dD %s 'miff.$$$'", sourceName);
|
||||
}
|
||||
// else
|
||||
{
|
||||
// running under NT. Use the MSVC cl since it deals with long filenames on fat16/fat32 partitions correctly
|
||||
// and ccp and cccp don't
|
||||
// sprintf(shellCommand, "cl /nologo /W4 /EP %s > miff.$$$", sourceName);
|
||||
}
|
||||
|
||||
retVal = system(shellCommand);
|
||||
if (2 == retVal) // actually, I think 4DOS reports 2 for cannot find file, but DOS returns a 0...
|
||||
{
|
||||
REPORT_LOG(true, ("failed to execute following shell command (%d):\n", retVal));
|
||||
REPORT_LOG(true, (" %s\n", shellCommand));
|
||||
MIFFMessage("\n\nERROR: Cannot find preprocessor (either CCCP.EXE, CPP.EXE or CL.EXE (under NT) in the search path...\n", 1);
|
||||
MIFFMessage("Please make sure the preprocessor is in your search path!\n", 1);
|
||||
}
|
||||
return(retVal);
|
||||
}
|
||||
|
||||
extern "C" void MIFFSetIFFName(const char *newFileName)
|
||||
{
|
||||
if (ERR_NONE != errorFlag)
|
||||
return;
|
||||
|
||||
if (outfileHandler)
|
||||
outfileHandler->setCurrentFilename(newFileName);
|
||||
}
|
||||
|
||||
extern "C" void MIFFinsertForm(const char *formName)
|
||||
{
|
||||
if (ERR_NONE != errorFlag)
|
||||
return;
|
||||
|
||||
if (outfileHandler)
|
||||
outfileHandler->insertForm(formName);
|
||||
}
|
||||
|
||||
extern "C" void MIFFinsertChunk(const char *chunkName)
|
||||
{
|
||||
if (ERR_NONE != errorFlag)
|
||||
return;
|
||||
|
||||
if (outfileHandler)
|
||||
outfileHandler->insertChunk(chunkName);
|
||||
}
|
||||
|
||||
extern "C" void MIFFinsertChunkData(void * buffer, unsigned bufferSize)
|
||||
{
|
||||
if (ERR_NONE != errorFlag)
|
||||
return;
|
||||
|
||||
if (outfileHandler)
|
||||
outfileHandler->insertChunkData(buffer, bufferSize);
|
||||
}
|
||||
|
||||
extern "C" int MIFFloadRawData(char *fname, void * buffer, unsigned maxBufferSize)
|
||||
{
|
||||
int sizeRead = -1;
|
||||
|
||||
if (ERR_NONE != errorFlag)
|
||||
return(sizeRead); // should be -1
|
||||
|
||||
InputFileHandler * inFileName = new InputFileHandler(fname);
|
||||
if (inFileName)
|
||||
{
|
||||
sizeRead = inFileName->read(buffer, maxBufferSize);
|
||||
if (static_cast<unsigned>(sizeRead) >= maxBufferSize)
|
||||
{
|
||||
handleError(ERR_BUFFERTOOSMALL);
|
||||
sizeRead = -1;
|
||||
}
|
||||
delete inFileName;
|
||||
}
|
||||
|
||||
return(sizeRead);
|
||||
}
|
||||
|
||||
extern "C" void MIFFexitChunk(void)
|
||||
{
|
||||
if (ERR_NONE != errorFlag)
|
||||
return;
|
||||
|
||||
if (outfileHandler)
|
||||
outfileHandler->exitChunk();
|
||||
}
|
||||
extern "C" void MIFFexitForm(void)
|
||||
{
|
||||
if (ERR_NONE != errorFlag)
|
||||
return;
|
||||
|
||||
if (outfileHandler)
|
||||
outfileHandler->exitForm();
|
||||
}
|
||||
|
||||
extern "C" char * MIFFallocString(int sizeOfString)
|
||||
{
|
||||
return(new char[sizeOfString]);
|
||||
}
|
||||
|
||||
extern "C" void MIFFfreeString(char * pointer)
|
||||
{
|
||||
delete [] pointer;
|
||||
}
|
||||
|
||||
extern "C" unsigned long MIFFgetLabelHash(char * inputStream)
|
||||
{
|
||||
return (unsigned long)Crc::calculate(inputStream);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//============================================================ End-of-file ==
|
||||
//===========================================================================
|
||||
|
||||
@@ -0,0 +1,517 @@
|
||||
%option full
|
||||
|
||||
%{
|
||||
/*-----------------------------------------------------------------------------**
|
||||
** FILE: parser.lex **
|
||||
** (c) 1998 - Bootprint GTInteractive **
|
||||
** **
|
||||
** DESCRIPTION: lexical analyzer for mIFF **
|
||||
** **
|
||||
** AUTHOR: Hideki Ikeda **
|
||||
** **
|
||||
** HISTORY: **
|
||||
** **
|
||||
** Notes: companion to parser.yac **
|
||||
**-----------------------------------------------------------------------------*/
|
||||
/* Disable compiler warnings (we want warning level 4) for anything that flex spits out */
|
||||
#pragma warning (disable: 4127) /* conditional expression is constant - ie. while(1) */
|
||||
#pragma warning (disable: 4131) /* usage of old-style declarator */
|
||||
#pragma warning (disable: 4098) /* void function returning a vlue - this is because yyterminate() is defined as return() */
|
||||
#pragma warning (disable: 4505) /* unreferenced local function has been removed (to be direct: yyunput()) */
|
||||
|
||||
/* include files */
|
||||
#include "parser.h" /* NOTE: make sure this matches what Bison/yacc spits out */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/*--------------------------------**
|
||||
** exteranl prototype declaration **
|
||||
**--------------------------------*/
|
||||
void MIFFMessage(char *message, int forceOutput);
|
||||
void MIFFSetError(void);
|
||||
char * MIFFallocString(int sizeOfString);
|
||||
void MIFFfreeString(char * pointer);
|
||||
|
||||
int yyparse();
|
||||
|
||||
/* prototype declaration */
|
||||
int MIFFYYInput(char *buf,int max_size);
|
||||
void initParser(void);
|
||||
void count(void);
|
||||
void yyerror(char *err);
|
||||
void open_brace(void);
|
||||
void close_brace(void);
|
||||
int count_brace(void);
|
||||
|
||||
void printString(char *str);
|
||||
|
||||
/* global vars that has to be pre-declared because it's referenced by the lexical analyzer */
|
||||
int initialCompile = 0;
|
||||
int globalErrorFlag = 0;
|
||||
char inFileName[512]; /* keep track of source file name for error message */
|
||||
|
||||
#undef YY_INPUT
|
||||
#define YY_INPUT(buf,result,max_size) (result = MIFFYYInput(buf,max_size))
|
||||
|
||||
#define SPACE_COUNT_FOR_TAB (8)
|
||||
|
||||
%}
|
||||
|
||||
DIGIT [0-9]
|
||||
HEXDIGIT [0-9a-fA-F]
|
||||
LETTER [A-z_]
|
||||
FLOATSYM (f|F|l|L)
|
||||
INTSYM (u|U|l|L)*
|
||||
EXP (e|E)(\+|-)?
|
||||
|
||||
%%
|
||||
"//"[^\n]*\n {
|
||||
/* don't do count(); */
|
||||
}
|
||||
|
||||
"#define"[^\n]*\n {
|
||||
/* don't you love regular expression? [^\n]* everything but \n, and then end with \n */
|
||||
/* don't do count(); just like comments */
|
||||
/* return(DEFINE); <-- note: #define's are ignored in parser for they are handled via preprocessors CCCP */
|
||||
}
|
||||
|
||||
\"([^\"]|(\\\"))*\" {
|
||||
/* start with " then ( [^\"] | (\\\") )* which means either anything but " OR \" of multiple encounter, and then close with " */
|
||||
/* case for "string" literals */
|
||||
char *s; // allocate space for string and pass the string pointer rather then yytext
|
||||
|
||||
count();
|
||||
s = MIFFallocString(strlen(yytext) + 1);
|
||||
strcpy(s, yytext+1); /* strip off the double quotes */
|
||||
s[strlen(yytext+1)-1] = 0; /* strip off the ending double quotes */
|
||||
yylval.stype = s;
|
||||
return(STR_LIT);
|
||||
}
|
||||
|
||||
"form" |
|
||||
"FORM" {
|
||||
count();
|
||||
return(FORM);
|
||||
}
|
||||
|
||||
"chunk" |
|
||||
"CHUNK" {
|
||||
count();
|
||||
return(CHUNK);
|
||||
}
|
||||
|
||||
"int32" {
|
||||
count();
|
||||
return(INT32);
|
||||
}
|
||||
"int16" {
|
||||
count();
|
||||
return(INT16);
|
||||
}
|
||||
"int8" {
|
||||
count();
|
||||
return(INT8);
|
||||
}
|
||||
"uint32" {
|
||||
count();
|
||||
return(UINT32);
|
||||
}
|
||||
"uint16" {
|
||||
count();
|
||||
return(UINT16);
|
||||
}
|
||||
"uint8" {
|
||||
count();
|
||||
return(UINT8);
|
||||
}
|
||||
"float" {
|
||||
count();
|
||||
return(FLOAT);
|
||||
}
|
||||
"double" {
|
||||
count();
|
||||
return(DOUBLE);
|
||||
}
|
||||
"string" |
|
||||
"cstring" |
|
||||
"CString" {
|
||||
count();
|
||||
return(STRING);
|
||||
}
|
||||
"wstring" |
|
||||
"WString" {
|
||||
count();
|
||||
return(WSTRING);
|
||||
}
|
||||
"labelhash" {
|
||||
count();
|
||||
return(LABELHASH);
|
||||
}
|
||||
|
||||
"sin" {
|
||||
count();
|
||||
return(SIN);
|
||||
}
|
||||
"cos" {
|
||||
count();
|
||||
return(COS);
|
||||
}
|
||||
"tan" {
|
||||
count();
|
||||
return(TAN);
|
||||
}
|
||||
"asin" {
|
||||
count();
|
||||
return(ASIN);
|
||||
}
|
||||
"acos" {
|
||||
count();
|
||||
return(ACOS);
|
||||
}
|
||||
"atan" {
|
||||
count();
|
||||
return(ATAN);
|
||||
}
|
||||
|
||||
"enum" {
|
||||
count();
|
||||
return(ENUMSTRUCT);
|
||||
}
|
||||
|
||||
"includeIFF" |
|
||||
"includeiff" {
|
||||
count();
|
||||
return(INCLUDEIFF);
|
||||
}
|
||||
"include" {
|
||||
count();
|
||||
return(INCLUDEBIN);
|
||||
}
|
||||
"#include" {
|
||||
count();
|
||||
return(INCLUDESOURCE);
|
||||
}
|
||||
"#pragma" {
|
||||
count();
|
||||
return(PRAGMA);
|
||||
}
|
||||
"drive" {
|
||||
count();
|
||||
return(PRAGMA_DRIVE);
|
||||
}
|
||||
"directory" {
|
||||
count();
|
||||
return(PRAGMA_DIR);
|
||||
}
|
||||
"filename" {
|
||||
count();
|
||||
return(PRAGMA_FNAME);
|
||||
}
|
||||
"extension" {
|
||||
count();
|
||||
return(PRAGMA_EXT);
|
||||
}
|
||||
|
||||
{LETTER}({LETTER}|{DIGIT})* {
|
||||
/* label identifiers */
|
||||
char *s; // allocate space for string and pass the string pointer rather then yytext
|
||||
|
||||
count();
|
||||
s = MIFFallocString(strlen(yytext) + 1);
|
||||
strcpy(s, yytext);
|
||||
yylval.stype = s;
|
||||
return(IDENTIFIER);
|
||||
}
|
||||
|
||||
{DIGIT}*"."{DIGIT}+{FLOATSYM}? {
|
||||
/* handle numericals (floats) */
|
||||
/*
|
||||
* {DIGIT}*"."{DIGIT}+{FLOATSYM}? means zero or more digits . one or more digit and with/without f at the end
|
||||
*/
|
||||
count();
|
||||
/* make sure to store it to dtype, and use strtod to convert to double */
|
||||
yylval.dtype = strtod((char *) yytext, (char **) 0);
|
||||
return(FLOAT_LIT);
|
||||
}
|
||||
|
||||
0[xX]{HEXDIGIT}+{INTSYM}? |
|
||||
0{DIGIT}+{INTSYM}? |
|
||||
{DIGIT}+{INTSYM}? {
|
||||
/* handle numericals ( hex, ints) */
|
||||
/*
|
||||
* 0[xX]{HEXDIGIT}+{INTSYM}? means start with 0, then X one or more digit and you can put int symbol if you want
|
||||
* 0{DIGIT}+{INTSYM}? means start with 0, one ore more digit and w/or w/o int symbol
|
||||
* {DIGIT}+{INTSYM}? means one or more digit and w/or w/o int symbol
|
||||
*/
|
||||
count();
|
||||
/* make sure to store it to ltype (long), and use strtod to convert to unsigned long */
|
||||
yylval.ltype = strtoul((char *) yytext, (char **) 0, 0);
|
||||
return(LIT);
|
||||
}
|
||||
|
||||
'(\\.|[^\\'])+' {
|
||||
/* handle 'x' - single character */
|
||||
count();
|
||||
yylval.chtype = yytext[1];
|
||||
return(CHAR_LIT);
|
||||
}
|
||||
|
||||
"#" {
|
||||
/* #'s are used for informing the parser which file and line number it is processing (debug purpose) */
|
||||
count();
|
||||
return(POUND);
|
||||
}
|
||||
|
||||
">>" {
|
||||
count();
|
||||
return(SHIFTRIGHT);
|
||||
}
|
||||
"<<" {
|
||||
count();
|
||||
return(SHIFTLEFT);
|
||||
}
|
||||
"^^" {
|
||||
count();
|
||||
return(RAISEDPOWER);
|
||||
}
|
||||
|
||||
"[" |
|
||||
"]" |
|
||||
"^" |
|
||||
";" |
|
||||
"," |
|
||||
":" |
|
||||
"=" |
|
||||
"(" |
|
||||
")" |
|
||||
"." |
|
||||
"&" |
|
||||
"!" |
|
||||
"~" |
|
||||
"-" |
|
||||
"+" |
|
||||
"*" |
|
||||
"/" |
|
||||
"%" |
|
||||
"<" |
|
||||
">" |
|
||||
"|" |
|
||||
"?" {
|
||||
/* valid operators */
|
||||
count();
|
||||
yylval.stype = yytext;
|
||||
return(* yylval.stype);
|
||||
}
|
||||
|
||||
"{" {
|
||||
count();
|
||||
open_brace();
|
||||
yylval.stype = yytext;
|
||||
return(* yylval.stype);
|
||||
}
|
||||
"}" {
|
||||
count();
|
||||
close_brace();
|
||||
yylval.stype = yytext;
|
||||
return(* yylval.stype);
|
||||
}
|
||||
|
||||
[ \t\n\r]+ {
|
||||
/* white spaces and newlines are ignored */
|
||||
count();
|
||||
}
|
||||
|
||||
<<EOF>> {
|
||||
/* do a count on bracket matching... */
|
||||
if (0 == count_brace())
|
||||
{
|
||||
if (!initialCompile && !globalErrorFlag)
|
||||
MIFFMessage("mIFF successfully compiled!\n", 0);
|
||||
}
|
||||
|
||||
yyterminate(); /* tell yyparse() it's time to quit! DO NOT comment or delete this line! */
|
||||
}
|
||||
|
||||
. {
|
||||
/* anything that's not a rule from above goes here */
|
||||
count();
|
||||
yyerror((char *) yytext);
|
||||
}
|
||||
%%
|
||||
|
||||
/*--------------------**
|
||||
** C supporting codes **
|
||||
**--------------------*/
|
||||
|
||||
/*------------------**
|
||||
** static variables **
|
||||
**------------------*/
|
||||
static char *MIFFInputStream;
|
||||
int column = 0;
|
||||
int line_num = 1;
|
||||
int line_num2 = 1;
|
||||
char error_line_buffer[256];
|
||||
long brace_counter = 0;
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------**
|
||||
** Initialize all the static variables before all calls to MIFFCompile **
|
||||
**---------------------------------------------------------------------*/
|
||||
void initParser(void)
|
||||
{
|
||||
line_num = 1;
|
||||
column = 0;
|
||||
|
||||
brace_counter = 0;
|
||||
error_line_buffer[0] = 0;
|
||||
|
||||
globalErrorFlag = 0;
|
||||
|
||||
memset(inFileName, 0, 512); /* make sure to change this size if the char array gets bigger... */
|
||||
}
|
||||
|
||||
/*-------------------------------------------------**
|
||||
** generate a dialog box to MFC to report an error **
|
||||
**-------------------------------------------------*/
|
||||
void yyerror(char *err) /* called by yyparse() */
|
||||
{
|
||||
char myString[256];
|
||||
|
||||
if (!initialCompile)
|
||||
{
|
||||
/* spit it out in MSDev error format */
|
||||
sprintf(myString, "\n%s(%d) : yyERROR : %s\n>>%s<<", inFileName, line_num, err, error_line_buffer);
|
||||
MIFFMessage(myString, 1);
|
||||
globalErrorFlag = 1;
|
||||
MIFFSetError(); /* set global error flag for shell as well */
|
||||
yyterminate();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*-------------------------**
|
||||
** our version of YY_INPUT **
|
||||
**-------------------------*/
|
||||
int MIFFYYInput(char *buf,int max_size)
|
||||
{
|
||||
int len = strlen(MIFFInputStream);
|
||||
int n = max_size < len ? max_size : len;
|
||||
if (n > 0)
|
||||
{
|
||||
memcpy(buf,MIFFInputStream,n);
|
||||
MIFFInputStream += n;
|
||||
}
|
||||
return(n);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------**
|
||||
** line and column counter for error searching during compile **
|
||||
**------------------------------------------------------------*/
|
||||
void count()
|
||||
{
|
||||
int i;
|
||||
static char *elb = error_line_buffer;
|
||||
for (i = 0; yytext[i] != '\0'; i++)
|
||||
{
|
||||
if (yytext[i] == '\n')
|
||||
{
|
||||
column = 0;
|
||||
line_num++;
|
||||
elb = error_line_buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
*elb++ = yytext[i];
|
||||
if (yytext[i] == '\t')
|
||||
column += SPACE_COUNT_FOR_TAB - (column & (SPACE_COUNT_FOR_TAB - 1));
|
||||
else
|
||||
column++;
|
||||
}
|
||||
*elb = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------**
|
||||
** sets up current line number and filename the error came from **
|
||||
**--------------------------------------------------------------*/
|
||||
void setCurrentLineNumber(int lineNum, char * fileName, int mysteryNum)
|
||||
{
|
||||
line_num = lineNum;
|
||||
strcpy(inFileName, fileName);
|
||||
line_num2 = mysteryNum;
|
||||
}
|
||||
|
||||
/*----------------------------------------------**
|
||||
** MIFFCompile called by CMIFFView::OnCompile() **
|
||||
**----------------------------------------------*/
|
||||
void MIFFCompile(char *inputStream, char *inputFileName)
|
||||
{
|
||||
MIFFInputStream = inputStream;
|
||||
yyrestart(0);
|
||||
initParser();
|
||||
initialCompile = 0;
|
||||
strcpy(inFileName, inputFileName);
|
||||
yyparse();
|
||||
}
|
||||
|
||||
void MIFFCompileInit(char *inputStream, char *inputFileName)
|
||||
{
|
||||
MIFFInputStream = inputStream;
|
||||
yyrestart(0);
|
||||
initParser();
|
||||
initialCompile = 1;
|
||||
strcpy(inFileName, inputFileName);
|
||||
yyparse();
|
||||
}
|
||||
|
||||
/*---------------------------------------**
|
||||
** matching of open/close brace checking **
|
||||
**---------------------------------------*/
|
||||
void open_brace(void)
|
||||
{
|
||||
brace_counter++;
|
||||
}
|
||||
|
||||
void close_brace(void)
|
||||
{
|
||||
brace_counter--;
|
||||
}
|
||||
|
||||
/*
|
||||
* what: count_brace():
|
||||
* return: 0 == all braces matched
|
||||
*/
|
||||
int count_brace(void)
|
||||
{
|
||||
if (0 == brace_counter) /* things are fine... */
|
||||
return(0);
|
||||
|
||||
/* if this is called, we should have 0 brace counter if not, we have a mis-match*/
|
||||
if (brace_counter > 0)
|
||||
{
|
||||
/* a mismatch */
|
||||
yyerror("There are more OPEN brackets then closed");
|
||||
}
|
||||
else if (brace_counter < 0)
|
||||
{
|
||||
yyerror("There are more CLOSED brackets then open");
|
||||
}
|
||||
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------**
|
||||
** FLEX.SLK requires this prototype function so I'm forced to do this... **
|
||||
**-----------------------------------------------------------------------*/
|
||||
int yywrap()
|
||||
{
|
||||
return(1);
|
||||
}
|
||||
|
||||
void printString(char *str)
|
||||
{
|
||||
char ts[256];
|
||||
sprintf(ts, "%s - %s", str, yytext);
|
||||
MIFFMessage(ts, 0);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,334 @@
|
||||
|
||||
extern int timeclock;
|
||||
|
||||
|
||||
int yyerror; /* Yyerror and yycost are set by guards. */
|
||||
int yycost; /* If yyerror is set to a nonzero value by a */
|
||||
/* guard, the reduction with which the guard */
|
||||
/* is associated is not performed, and the */
|
||||
/* error recovery mechanism is invoked. */
|
||||
/* Yycost indicates the cost of performing */
|
||||
/* the reduction given the attributes of the */
|
||||
/* symbols. */
|
||||
|
||||
|
||||
/* YYMAXDEPTH indicates the size of the parser's state and value */
|
||||
/* stacks. */
|
||||
|
||||
#ifndef YYMAXDEPTH
|
||||
#define YYMAXDEPTH 500
|
||||
#endif
|
||||
|
||||
/* YYMAXRULES must be at least as large as the number of rules that */
|
||||
/* could be placed in the rule queue. That number could be determined */
|
||||
/* from the grammar and the size of the stack, but, as yet, it is not. */
|
||||
|
||||
#ifndef YYMAXRULES
|
||||
#define YYMAXRULES 100
|
||||
#endif
|
||||
|
||||
#ifndef YYMAXBACKUP
|
||||
#define YYMAXBACKUP 100
|
||||
#endif
|
||||
|
||||
|
||||
short yyss[YYMAXDEPTH]; /* the state stack */
|
||||
YYSTYPE yyvs[YYMAXDEPTH]; /* the semantic value stack */
|
||||
YYLTYPE yyls[YYMAXDEPTH]; /* the location stack */
|
||||
short yyrq[YYMAXRULES]; /* the rule queue */
|
||||
int yychar; /* the lookahead symbol */
|
||||
|
||||
YYSTYPE yylval; /* the semantic value of the */
|
||||
/* lookahead symbol */
|
||||
|
||||
YYSTYPE yytval; /* the semantic value for the state */
|
||||
/* at the top of the state stack. */
|
||||
|
||||
YYSTYPE yyval; /* the variable used to return */
|
||||
/* semantic values from the action */
|
||||
/* routines */
|
||||
|
||||
YYLTYPE yylloc; /* location data for the lookahead */
|
||||
/* symbol */
|
||||
|
||||
YYLTYPE yytloc; /* location data for the state at the */
|
||||
/* top of the state stack */
|
||||
|
||||
|
||||
int yynunlexed;
|
||||
short yyunchar[YYMAXBACKUP];
|
||||
YYSTYPE yyunval[YYMAXBACKUP];
|
||||
YYLTYPE yyunloc[YYMAXBACKUP];
|
||||
|
||||
short *yygssp; /* a pointer to the top of the state */
|
||||
/* stack; only set during error */
|
||||
/* recovery. */
|
||||
|
||||
YYSTYPE *yygvsp; /* a pointer to the top of the value */
|
||||
/* stack; only set during error */
|
||||
/* recovery. */
|
||||
|
||||
YYLTYPE *yyglsp; /* a pointer to the top of the */
|
||||
/* location stack; only set during */
|
||||
/* error recovery. */
|
||||
|
||||
|
||||
/* Yyget is an interface between the parser and the lexical analyzer. */
|
||||
/* It is costly to provide such an interface, but it avoids requiring */
|
||||
/* the lexical analyzer to be able to back up the scan. */
|
||||
|
||||
yyget()
|
||||
{
|
||||
if (yynunlexed > 0)
|
||||
{
|
||||
yynunlexed--;
|
||||
yychar = yyunchar[yynunlexed];
|
||||
yylval = yyunval[yynunlexed];
|
||||
yylloc = yyunloc[yynunlexed];
|
||||
}
|
||||
else if (yychar <= 0)
|
||||
yychar = 0;
|
||||
else
|
||||
{
|
||||
yychar = yylex();
|
||||
if (yychar < 0)
|
||||
yychar = 0;
|
||||
else yychar = YYTRANSLATE(yychar);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
yyunlex(chr, val, loc)
|
||||
int chr;
|
||||
YYSTYPE val;
|
||||
YYLTYPE loc;
|
||||
{
|
||||
yyunchar[yynunlexed] = chr;
|
||||
yyunval[yynunlexed] = val;
|
||||
yyunloc[yynunlexed] = loc;
|
||||
yynunlexed++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
yyrestore(first, last)
|
||||
register short *first;
|
||||
register short *last;
|
||||
{
|
||||
register short *ssp;
|
||||
register short *rp;
|
||||
register int symbol;
|
||||
register int state;
|
||||
register int tvalsaved;
|
||||
|
||||
ssp = yygssp;
|
||||
yyunlex(yychar, yylval, yylloc);
|
||||
|
||||
tvalsaved = 0;
|
||||
while (first != last)
|
||||
{
|
||||
symbol = yystos[*ssp];
|
||||
if (symbol < YYNTBASE)
|
||||
{
|
||||
yyunlex(symbol, yytval, yytloc);
|
||||
tvalsaved = 1;
|
||||
ssp--;
|
||||
}
|
||||
|
||||
ssp--;
|
||||
|
||||
if (first == yyrq)
|
||||
first = yyrq + YYMAXRULES;
|
||||
|
||||
first--;
|
||||
|
||||
for (rp = yyrhs + yyprhs[*first]; symbol = *rp; rp++)
|
||||
{
|
||||
if (symbol < YYNTBASE)
|
||||
state = yytable[yypact[*ssp] + symbol];
|
||||
else
|
||||
{
|
||||
state = yypgoto[symbol - YYNTBASE] + *ssp;
|
||||
|
||||
if (state >= 0 && state <= YYLAST && yycheck[state] == *ssp)
|
||||
state = yytable[state];
|
||||
else
|
||||
state = yydefgoto[symbol - YYNTBASE];
|
||||
}
|
||||
|
||||
*++ssp = state;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! tvalsaved && ssp > yyss)
|
||||
{
|
||||
yyunlex(yystos[*ssp], yytval, yytloc);
|
||||
ssp--;
|
||||
}
|
||||
|
||||
yygssp = ssp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
yyparse()
|
||||
{
|
||||
register int yystate;
|
||||
register int yyn;
|
||||
register short *yyssp;
|
||||
register short *yyrq0;
|
||||
register short *yyptr;
|
||||
register YYSTYPE *yyvsp;
|
||||
|
||||
int yylen;
|
||||
YYLTYPE *yylsp;
|
||||
short *yyrq1;
|
||||
short *yyrq2;
|
||||
|
||||
yystate = 0;
|
||||
yyssp = yyss - 1;
|
||||
yyvsp = yyvs - 1;
|
||||
yylsp = yyls - 1;
|
||||
yyrq0 = yyrq;
|
||||
yyrq1 = yyrq0;
|
||||
yyrq2 = yyrq0;
|
||||
|
||||
yychar = yylex();
|
||||
if (yychar < 0)
|
||||
yychar = 0;
|
||||
else yychar = YYTRANSLATE(yychar);
|
||||
|
||||
yynewstate:
|
||||
|
||||
if (yyssp >= yyss + YYMAXDEPTH - 1)
|
||||
{
|
||||
yyabort("Parser Stack Overflow");
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
*++yyssp = yystate;
|
||||
|
||||
yyresume:
|
||||
|
||||
yyn = yypact[yystate];
|
||||
if (yyn == YYFLAG)
|
||||
goto yydefault;
|
||||
|
||||
yyn += yychar;
|
||||
if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar)
|
||||
goto yydefault;
|
||||
|
||||
yyn = yytable[yyn];
|
||||
if (yyn < 0)
|
||||
{
|
||||
yyn = -yyn;
|
||||
goto yyreduce;
|
||||
}
|
||||
else if (yyn == 0)
|
||||
goto yyerrlab;
|
||||
|
||||
yystate = yyn;
|
||||
|
||||
yyptr = yyrq2;
|
||||
while (yyptr != yyrq1)
|
||||
{
|
||||
yyn = *yyptr++;
|
||||
yylen = yyr2[yyn];
|
||||
yyvsp -= yylen;
|
||||
yylsp -= yylen;
|
||||
|
||||
yyguard(yyn, yyvsp, yylsp);
|
||||
if (yyerror)
|
||||
goto yysemerr;
|
||||
|
||||
yyaction(yyn, yyvsp, yylsp);
|
||||
*++yyvsp = yyval;
|
||||
|
||||
yylsp++;
|
||||
if (yylen == 0)
|
||||
{
|
||||
yylsp->timestamp = timeclock;
|
||||
yylsp->first_line = yytloc.first_line;
|
||||
yylsp->first_column = yytloc.first_column;
|
||||
yylsp->last_line = (yylsp-1)->last_line;
|
||||
yylsp->last_column = (yylsp-1)->last_column;
|
||||
yylsp->text = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
yylsp->last_line = (yylsp+yylen-1)->last_line;
|
||||
yylsp->last_column = (yylsp+yylen-1)->last_column;
|
||||
}
|
||||
|
||||
if (yyptr == yyrq + YYMAXRULES)
|
||||
yyptr = yyrq;
|
||||
}
|
||||
|
||||
if (yystate == YYFINAL)
|
||||
YYACCEPT;
|
||||
|
||||
yyrq2 = yyptr;
|
||||
yyrq1 = yyrq0;
|
||||
|
||||
*++yyvsp = yytval;
|
||||
*++yylsp = yytloc;
|
||||
yytval = yylval;
|
||||
yytloc = yylloc;
|
||||
yyget();
|
||||
|
||||
goto yynewstate;
|
||||
|
||||
yydefault:
|
||||
|
||||
yyn = yydefact[yystate];
|
||||
if (yyn == 0)
|
||||
goto yyerrlab;
|
||||
|
||||
yyreduce:
|
||||
|
||||
*yyrq0++ = yyn;
|
||||
|
||||
if (yyrq0 == yyrq + YYMAXRULES)
|
||||
yyrq0 = yyrq;
|
||||
|
||||
if (yyrq0 == yyrq2)
|
||||
{
|
||||
yyabort("Parser Rule Queue Overflow");
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
yyssp -= yyr2[yyn];
|
||||
yyn = yyr1[yyn];
|
||||
|
||||
yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
|
||||
if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
|
||||
yystate = yytable[yystate];
|
||||
else
|
||||
yystate = yydefgoto[yyn - YYNTBASE];
|
||||
|
||||
goto yynewstate;
|
||||
|
||||
yysemerr:
|
||||
*--yyptr = yyn;
|
||||
yyrq2 = yyptr;
|
||||
yyvsp += yyr2[yyn];
|
||||
|
||||
yyerrlab:
|
||||
|
||||
yygssp = yyssp;
|
||||
yygvsp = yyvsp;
|
||||
yyglsp = yylsp;
|
||||
yyrestore(yyrq0, yyrq2);
|
||||
yyrecover();
|
||||
yystate = *yygssp;
|
||||
yyssp = yygssp;
|
||||
yyvsp = yygvsp;
|
||||
yyrq0 = yyrq;
|
||||
yyrq1 = yyrq0;
|
||||
yyrq2 = yyrq0;
|
||||
goto yyresume;
|
||||
}
|
||||
|
||||
$
|
||||
@@ -0,0 +1,136 @@
|
||||
//===========================================================================
|
||||
//
|
||||
// FILENAME: InputFileHandler.cpp [C:\Projects\new\tools\src\miff\src\]
|
||||
// COPYRIGHT: (C) 1999 BY Bootprint Entertainment
|
||||
//
|
||||
// DESCRIPTION: file handler for input files (standard flat text files)
|
||||
// AUTHOR: Hideki Ikeda
|
||||
// DATE: 1/13/99 4:53:31 PM
|
||||
//
|
||||
// HISTORY: 1/13/99 [HAI] - File created
|
||||
// :
|
||||
//
|
||||
// FUNCTION: InputFileHandler() constructor
|
||||
// : ~InputFileHandler() destructor
|
||||
// :
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
//========================================================== include files ==
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "InputFileHandler.h"
|
||||
|
||||
#include "sharedFile/TreeFile.h"
|
||||
//#include "sharedFile/Iff.h"
|
||||
|
||||
//================================================= static vars assignment ==
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//
|
||||
// Remarks:
|
||||
//
|
||||
//
|
||||
// See Also:
|
||||
//
|
||||
//
|
||||
// Revisions and History:
|
||||
// 1/13/99 [HAI] - created
|
||||
//
|
||||
InputFileHandler::InputFileHandler(const char *infilename)
|
||||
{
|
||||
TreeFile::addSearchAbsolute(0); // search current working directory
|
||||
|
||||
file = TreeFile::open(infilename, AbstractFile::PriorityData, true);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Destructor
|
||||
//
|
||||
// Remarks:
|
||||
//
|
||||
//
|
||||
// See Also:
|
||||
//
|
||||
//
|
||||
// Revisions and History:
|
||||
// 1/13/99 [HAI] - created
|
||||
//
|
||||
InputFileHandler::~InputFileHandler(void)
|
||||
{
|
||||
if(file)
|
||||
delete file;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// reads a file stream into specified buffer of the size passed
|
||||
//
|
||||
// Return Value:
|
||||
// actual size read (signed int)
|
||||
//
|
||||
// Remarks:
|
||||
//
|
||||
//
|
||||
// See Also:
|
||||
// Treefile::read()
|
||||
//
|
||||
// Revisions and History:
|
||||
// 1/13/99 [HAI] - created
|
||||
//
|
||||
const int InputFileHandler::read(
|
||||
void *sourceBuffer, // pointer to the buffer
|
||||
int bufferSize // number of BYTES to be read
|
||||
)
|
||||
{
|
||||
int retVal = -1; // assume fileHandle is NOT valid
|
||||
|
||||
if (file)
|
||||
retVal = file->read(sourceBuffer, bufferSize);
|
||||
|
||||
return(retVal);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Deletes a file
|
||||
//
|
||||
// Return Value:
|
||||
// whatever DeleteFile() returns
|
||||
// if fileHandle != -1, it assumes that the fileHandle passed belonged to
|
||||
// this filename, and therefore, it will attempt to close the file and
|
||||
// set it to 0.
|
||||
//
|
||||
// Remarks:
|
||||
// calls DeleteFile() found in windows.h
|
||||
// InputFileHandler does NOT have any way to validate that the handle
|
||||
// passed belongs to the filename that it wants to be deleted. So use
|
||||
// it with caution
|
||||
//
|
||||
// See Also:
|
||||
// windows.h
|
||||
//
|
||||
// Revisions and History:
|
||||
// 1/13/99 [HAI] - created
|
||||
//
|
||||
int InputFileHandler::deleteFile(
|
||||
const char *filename,
|
||||
bool deleteHandleFlag
|
||||
)
|
||||
{
|
||||
if (deleteHandleFlag && file)
|
||||
{
|
||||
delete file;
|
||||
file = NULL;
|
||||
}
|
||||
return(DeleteFile(filename));
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//============================================================ End-of-file ==
|
||||
//===========================================================================
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
#ifndef __INPUTFILEHANDLER_H__
|
||||
#define __INPUTFILEHANDLER_H__
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// FILENAME: InputFileHandler.h [C:\Projects\new\tools\src\miff\src\]
|
||||
// COPYRIGHT: (C) 1999 BY Bootprint Entertainment
|
||||
//
|
||||
// DESCRIPTION: file handler for input files (flat text files)
|
||||
// AUTHOR: Hideki Ikeda
|
||||
// DATE: 1/13/99 4:55:15 PM
|
||||
//
|
||||
// HISTORY: 1/13/99 [HAI] - File created
|
||||
// :
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
//============================================================== #includes ==
|
||||
|
||||
//========================================================= class typedefs ==
|
||||
|
||||
//====================================================== class definitions ==
|
||||
|
||||
class AbstractFile;
|
||||
|
||||
class InputFileHandler
|
||||
{
|
||||
//------------------------------
|
||||
//--- public var & functions ---
|
||||
//------------------------------
|
||||
public: // functions
|
||||
InputFileHandler(const char *infilename);
|
||||
~InputFileHandler(void);
|
||||
|
||||
const int read(void *sourceBuffer, int bufferSize);
|
||||
int deleteFile(const char * filename, bool deleteHandleFlag = false);
|
||||
|
||||
public: // vars
|
||||
|
||||
|
||||
//-------------------------------
|
||||
//--- member vars declaration ---
|
||||
//-------------------------------
|
||||
protected: // vars
|
||||
AbstractFile *file;
|
||||
|
||||
private: // vars
|
||||
|
||||
//-----------------------------------
|
||||
//--- member function declaration ---
|
||||
//-----------------------------------
|
||||
protected: // functions
|
||||
|
||||
private: // functions
|
||||
void close(void); // close the input file called by destructor
|
||||
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
//========================================================= inline methods ==
|
||||
//===========================================================================
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//============================================================ End-of-file ==
|
||||
//===========================================================================
|
||||
#else
|
||||
#ifdef DEBUG
|
||||
#pragma message("InputFileHandler.h included more then once!")
|
||||
#endif
|
||||
#endif // ifndef __H__
|
||||
@@ -0,0 +1,164 @@
|
||||
//===========================================================================
|
||||
//
|
||||
// FILENAME: OutputFileHandler.cpp
|
||||
// COPYRIGHT: (C) 1999 BY Bootprint Entertainment
|
||||
//
|
||||
// DESCRIPTION: file handler for Output file (IFF file)
|
||||
// AUTHOR: Hideki Ikeda
|
||||
// DATE: 1/13/99 4:52:42 PM
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "OutputFileHandler.h"
|
||||
|
||||
#include "sharedFile/Iff.h"
|
||||
|
||||
//===========================================================================
|
||||
// Constructor
|
||||
|
||||
OutputFileHandler::OutputFileHandler(const char *filename)
|
||||
{
|
||||
outputIFF = new Iff(MAXIFFDATASIZE);
|
||||
outFilename = NULL;
|
||||
|
||||
setCurrentFilename(filename);
|
||||
}
|
||||
|
||||
void OutputFileHandler::setCurrentFilename(const char *filename)
|
||||
{
|
||||
if (outFilename)
|
||||
delete [] outFilename;
|
||||
|
||||
outFilename = new char[strlen(filename)+1];
|
||||
strcpy(outFilename, filename);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Destructor
|
||||
|
||||
OutputFileHandler::~OutputFileHandler(void)
|
||||
{
|
||||
if (outputIFF && outFilename)
|
||||
{
|
||||
delete outputIFF;
|
||||
delete [] outFilename;
|
||||
}
|
||||
|
||||
outputIFF = NULL;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// begins a new FORM in the IFF
|
||||
//
|
||||
// Return Value:
|
||||
// bool - true == success
|
||||
//
|
||||
// See Also:
|
||||
// Iff::insertForm()
|
||||
|
||||
void OutputFileHandler::insertForm(
|
||||
const char *tag
|
||||
)
|
||||
{
|
||||
Tag formTag = convertStrToTag(tag);
|
||||
outputIFF->insertForm(formTag);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// begins a new CHUNK in the IFF
|
||||
//
|
||||
// See Also:
|
||||
// Iff::insertChunk()
|
||||
|
||||
void OutputFileHandler::insertChunk(
|
||||
const char *tag
|
||||
)
|
||||
{
|
||||
Tag chunkTag = convertStrToTag(tag);
|
||||
outputIFF->insertChunk(chunkTag);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// converts string (4 bytes) form into Tag format
|
||||
//
|
||||
// Return Value:
|
||||
// Tag
|
||||
//
|
||||
// Remarks:
|
||||
// currently, this code is machine dependant code (non portable) and it assumes little endian
|
||||
//
|
||||
// See Also:
|
||||
// Tag
|
||||
|
||||
Tag OutputFileHandler::convertStrToTag(
|
||||
const char *str
|
||||
)
|
||||
{
|
||||
// prepare for hack-o-rama. It is byte order dependant, thus not portable ^_^
|
||||
Tag retVal = str[3] + (str[2] * 0x100) + (str[1] * 0x10000) + (str[0] * 0x1000000);
|
||||
|
||||
return(retVal);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// adds new chunk data into the current chunk it is in
|
||||
//
|
||||
// See Also:
|
||||
// Iff::insertChunkData()
|
||||
//
|
||||
|
||||
void OutputFileHandler::insertChunkData(
|
||||
void *data,
|
||||
int length
|
||||
)
|
||||
{
|
||||
outputIFF->insertChunkData(data, length);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// exits current FORM section we are in
|
||||
//
|
||||
// See Also:
|
||||
// Iff::exitForm()
|
||||
|
||||
void OutputFileHandler::exitForm(void)
|
||||
{
|
||||
outputIFF->exitForm();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// exits current CHUNK we are in
|
||||
//
|
||||
// See Also:
|
||||
// Iff::exitChunk()
|
||||
|
||||
void OutputFileHandler::exitChunk(void)
|
||||
{
|
||||
outputIFF->exitChunk();
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Calls Iff:write()
|
||||
//
|
||||
// Return Value:
|
||||
//
|
||||
// True if the Iff was successfully written, otherwise false
|
||||
//
|
||||
// See Also:
|
||||
// Iff::write()
|
||||
|
||||
bool OutputFileHandler::writeBuffer(void)
|
||||
{
|
||||
if (outputIFF && outFilename)
|
||||
return outputIFF->write(outFilename, true);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
#ifndef __OUTPUTFILEHANDLER_H__
|
||||
#define __OUTPUTFILEHANDLER_H__
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// FILENAME: OutputFileHandler.h [C:\Projects\new\tools\src\miff\src\]
|
||||
// COPYRIGHT: (C) 1999 BY Bootprint Entertainment
|
||||
//
|
||||
// DESCRIPTION: file handler for output files (IFF file format)
|
||||
// AUTHOR: Hideki Ikeda
|
||||
// DATE: 1/13/99 4:55:56 PM
|
||||
//
|
||||
// HISTORY: 1/13/99 [HAI] - File created
|
||||
// :
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
//============================================================== #includes ==
|
||||
|
||||
//========================================================= class typedefs ==
|
||||
#include "sharedFile/Iff.h"
|
||||
|
||||
//====================================================== class definitions ==
|
||||
class OutputFileHandler
|
||||
{
|
||||
//------------------------------
|
||||
//--- public var & functions ---
|
||||
//------------------------------
|
||||
public: // functions
|
||||
OutputFileHandler(const char *filename);
|
||||
~OutputFileHandler(void);
|
||||
bool writeBuffer(void);
|
||||
|
||||
void insertForm(const char *tagName);
|
||||
void insertChunk(const char *tagName);
|
||||
void insertChunkData(void *data, int length);
|
||||
void exitForm(void);
|
||||
void exitChunk(void);
|
||||
|
||||
void setCurrentFilename(const char *fname);
|
||||
|
||||
public: // vars
|
||||
|
||||
|
||||
//-------------------------------
|
||||
//--- member vars declaration ---
|
||||
//-------------------------------
|
||||
protected: // vars
|
||||
Iff * outputIFF;
|
||||
char *outFilename;
|
||||
|
||||
enum{
|
||||
MAXIFFDATASIZE = 8192 // allocate 8K of memory for a starter
|
||||
};
|
||||
|
||||
private: // vars
|
||||
|
||||
//-----------------------------------
|
||||
//--- member function declaration ---
|
||||
//-----------------------------------
|
||||
protected: // functions
|
||||
|
||||
private: // functions
|
||||
Tag convertStrToTag(const char *str);
|
||||
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
//========================================================= inline methods ==
|
||||
//===========================================================================
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//============================================================ End-of-file ==
|
||||
//===========================================================================
|
||||
#else
|
||||
#ifdef DEBUG
|
||||
#pragma message("OutputFileHandler.h included more then once!")
|
||||
#endif
|
||||
#endif // ifndef __H__
|
||||
@@ -0,0 +1,62 @@
|
||||
// NOTE: this makes it more convinient for me to make the help screen fancier...
|
||||
// blah... not that anybody cares...
|
||||
|
||||
printf("\
|
||||
Usage:\n\
|
||||
mIFF {-%c <filename>|--%s=<filename>}\n\
|
||||
[{-%c <filename>|--%s=<filename>} | {-%c|--%s}]\n\
|
||||
[{-%c|--%s}] [{-%c|--%s}] [{-%c|--%s}]\n\n",
|
||||
SNAME_INPUT_FILE, LNAME_INPUT_FILE,
|
||||
SNAME_OUTPUT_FILE, LNAME_OUTPUT_FILE,
|
||||
SNAME_PRAGMA_TARGET, LNAME_PRAGMA_TARGET,
|
||||
SNAME_CCCP, LNAME_CCCP,
|
||||
SNAME_VERBOSE, LNAME_VERBOSE,
|
||||
SNAME_DEBUG, LNAME_DEBUG);
|
||||
printf("\
|
||||
mIFF {-%c|--%s}\n\n", SNAME_HELP, LNAME_HELP);
|
||||
|
||||
printf("\
|
||||
Parameters:\n\
|
||||
-%c <filename>,--%s=<filename>\n\
|
||||
[required] specifies the input path for IFF source file.\n", SNAME_INPUT_FILE, LNAME_INPUT_FILE);
|
||||
printf("\
|
||||
-%c <filename>,--%s=<filename>\n\
|
||||
[optional] specifies the pathname for the generated \n\
|
||||
IFF data file. Note that if neither this nor the following \n\
|
||||
option are specified, a default output filename of the source\n\
|
||||
file's base name with extension \".iff\" will be used.\n", SNAME_OUTPUT_FILE, LNAME_OUTPUT_FILE);
|
||||
printf("\
|
||||
-%c,--%s\n\
|
||||
[optional] specifies the generated output filename should be \n\
|
||||
taken from the #pragma options within the source file. \n\
|
||||
Allowable #pragma options are: \n\
|
||||
#pragma drive \"<drive letter>:\"\n\
|
||||
#pragma directory \"<directory name>\"\n\
|
||||
#pragma filename \"<filename>\"\n\
|
||||
#pragma extension \"<extension>\"\n", SNAME_PRAGMA_TARGET, LNAME_PRAGMA_TARGET);
|
||||
printf("\
|
||||
-%c,--%s\n\
|
||||
[optional] use CCCP rather than CPP.\n", SNAME_CCCP, LNAME_CCCP);
|
||||
printf("\
|
||||
-%c,--%s\n\
|
||||
[optional] display more information during execution.\n", SNAME_VERBOSE, LNAME_VERBOSE);
|
||||
printf("\
|
||||
-%c,--%s\n\
|
||||
[optional] enable debug mode (save intermediate files).\n", SNAME_DEBUG, LNAME_DEBUG);
|
||||
printf("\
|
||||
-%c,--%s\n\
|
||||
[very optional] this help screen.\n", SNAME_HELP, LNAME_HELP);
|
||||
printf("\
|
||||
Examples:\n\
|
||||
mIFF -%c foo.bar\n\
|
||||
this will generate an iff file foo.iff (default if no parm specified)\n\
|
||||
in the current working directory. Even if foo.bar contains #pragma, \n\
|
||||
it will create foo.iff because -%c was not specified.\n", SNAME_INPUT_FILE, SNAME_PRAGMA_TARGET);
|
||||
printf("\
|
||||
mIFF -%c \"C:\\my project\\myData\\foo.iff\" --%s=foo.bar\n\
|
||||
notice that if you have space in your dirname, use \" to encapsulate \n\
|
||||
it.\n", SNAME_OUTPUT_FILE, LNAME_INPUT_FILE);
|
||||
printf("\
|
||||
mIFF -%c foo.bar --%s\n\
|
||||
will generate output file specified by #pragma statements \n\
|
||||
within file foo.bar.\n", SNAME_INPUT_FILE, LNAME_PRAGMA_TARGET);
|
||||
@@ -0,0 +1,961 @@
|
||||
//===========================================================================
|
||||
//
|
||||
// FILENAME: mIFF.cpp [C:\Projects\new\tools\src\miff\src\]
|
||||
// COPYRIGHT: (C) 1999 BY Bootprint Entertainment
|
||||
//
|
||||
// DESCRIPTION: make IFF (Console version)
|
||||
// AUTHOR: Hideki Ikeda
|
||||
// DATE: 1/07/99 12:57:20 PM
|
||||
//
|
||||
// HISTORY: 1/07/99 [HAI] - File created
|
||||
// : 1/07/99 [HAI] - v1.0 introductory version
|
||||
// : 1/12/99 [HAI] - v1.1 switched from DOS to Engine library
|
||||
// : - first attempt was to setup the main entry
|
||||
// : point via ConsoleEntryPoint() via callback
|
||||
// : 1/29/99 [HAI] - changed the parameter in MIFFMessage to allow
|
||||
// : output even in non-verbose mode (for error
|
||||
// : message purpose.
|
||||
// : 05/07/99 [HAI]- added MIFFallocString() and MIFFfreeString()
|
||||
// : to work with memory manager. they are allocated
|
||||
// : in the lexical analyzer for IDENTIFIERS and STR_LIT
|
||||
// : deleted after parser parses the rule.
|
||||
//
|
||||
// FUNCTION: main()
|
||||
// : evaluateArgs()
|
||||
// : help()
|
||||
// : handleError()
|
||||
// : preprocessSource()
|
||||
// : MIFFMessage()
|
||||
// : callbackFunction()
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
//========================================================== include files ==
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
|
||||
#include "sharedCompression/SetupSharedCompression.h"
|
||||
#include "sharedDebug/SetupSharedDebug.h"
|
||||
#include "sharedFile/SetupSharedFile.h"
|
||||
#include "sharedFile/TreeFile.h"
|
||||
#include "sharedFoundation/CommandLine.h"
|
||||
#include "sharedFoundation/Crc.h"
|
||||
#include "sharedFoundation/Os.h"
|
||||
#include "sharedFoundation/SetupSharedFoundation.h"
|
||||
#include "sharedMemoryManager/MemoryManager.h"
|
||||
#include "sharedThread/SetupSharedThread.h"
|
||||
|
||||
#include "InputFileHandler.h"
|
||||
#include "OutputFileHandler.h"
|
||||
|
||||
#include <string.h> // for memset()
|
||||
#include <stdio.h> // FILE stuff
|
||||
#include <direct.h> // for getcwd()
|
||||
#include <stdlib.h> // for tolower()
|
||||
#include <process.h> // for system()
|
||||
|
||||
//================================================= static vars assignment ==
|
||||
const int entryPointVersion = 1; // constantly check DataEntryPoint.h to see if this value has changed
|
||||
|
||||
OutputFileHandler *outfileHandler = NULL;
|
||||
const int bufferSize = 16 * 1024 * 1024;
|
||||
const int maxStringSize = 256;
|
||||
const char version[] = "1.3 September 18, 2000";
|
||||
|
||||
// vars set by pragmas or via command line
|
||||
char drive[4]; // should be no more then 2 char "C:"
|
||||
char directory[maxStringSize];
|
||||
char filename[maxStringSize];
|
||||
char extension[8]; // we'll truncate if the extension is more then 8 chars...
|
||||
char inFileName[maxStringSize];
|
||||
|
||||
// switches to be sent to mIFF Compiler
|
||||
char sourceBuffer[bufferSize];
|
||||
char outFileName[(maxStringSize * 2) + 8]; // x2 to combine filename, dir, and ext
|
||||
bool usePragma = false;
|
||||
bool useCCCP = false;
|
||||
bool verboseMode = false; // default to non-verbose mode
|
||||
bool debugMode = false; // set this on and the preprocessed source file (mIFF.$$$) won't be deleted
|
||||
|
||||
static bool runningUnderNT;
|
||||
|
||||
enum errorType {
|
||||
ERR_FILENOTFOUND = -1,
|
||||
ERR_ARGSTOOFEW = -2,
|
||||
ERR_BUFFERTOOSMALL = -3,
|
||||
ERR_UNKNOWNDIR = -4,
|
||||
ERR_PREPROCESS = -5,
|
||||
ERR_MULTIPLEINFILE = -6,
|
||||
ERR_PARSER = -7,
|
||||
ERR_ENGINE = -8,
|
||||
|
||||
ERR_HELPREQUEST = -9,
|
||||
ERR_OPTIONS = -10,
|
||||
|
||||
ERR_WRITEERROR = -11,
|
||||
|
||||
ERR_NONE = 0
|
||||
};
|
||||
char err_msg[512];
|
||||
errorType errorFlag = ERR_NONE; // assume no error (default)
|
||||
|
||||
|
||||
// long and short name definitions for command line options
|
||||
|
||||
static const char * const LNAME_HELP = "help";
|
||||
static const char * const LNAME_INPUT_FILE = "inputfile";
|
||||
static const char * const LNAME_OUTPUT_FILE = "outputfile";
|
||||
static const char * const LNAME_PRAGMA_TARGET = "pragmatarget";
|
||||
static const char * const LNAME_CCCP = "cccp";
|
||||
static const char * const LNAME_VERBOSE = "verbose";
|
||||
static const char * const LNAME_DEBUG = "debug";
|
||||
|
||||
static const char SNAME_HELP = 'h';
|
||||
static const char SNAME_INPUT_FILE = 'i';
|
||||
static const char SNAME_OUTPUT_FILE = 'o';
|
||||
static const char SNAME_PRAGMA_TARGET = 'p';
|
||||
static const char SNAME_CCCP = 'c';
|
||||
static const char SNAME_VERBOSE = 'v';
|
||||
static const char SNAME_DEBUG = 'd';
|
||||
|
||||
// following is the command line option spec tree needed for command line processing
|
||||
static CommandLine::OptionSpec optionSpecArray[] =
|
||||
{
|
||||
OP_BEGIN_SWITCH(OP_NODE_REQUIRED),
|
||||
|
||||
// help
|
||||
OP_SINGLE_SWITCH_NODE(SNAME_HELP, LNAME_HELP, OP_ARG_NONE, OP_MULTIPLE_DENIED),
|
||||
|
||||
// real options
|
||||
OP_BEGIN_SWITCH_NODE(OP_MULTIPLE_DENIED),
|
||||
OP_BEGIN_LIST(),
|
||||
// input filename required
|
||||
OP_SINGLE_LIST_NODE(SNAME_INPUT_FILE, LNAME_INPUT_FILE, OP_ARG_REQUIRED, OP_MULTIPLE_DENIED, OP_NODE_REQUIRED),
|
||||
|
||||
// optional, mutually exclusive output file specification options
|
||||
// if none specified, generate derive output filename from input filename
|
||||
OP_BEGIN_LIST_NODE(OP_MULTIPLE_DENIED, OP_NODE_OPTIONAL),
|
||||
OP_BEGIN_SWITCH(OP_NODE_OPTIONAL),
|
||||
// specify output filename on command line
|
||||
OP_SINGLE_SWITCH_NODE(SNAME_OUTPUT_FILE, LNAME_OUTPUT_FILE, OP_ARG_REQUIRED, OP_MULTIPLE_DENIED),
|
||||
|
||||
// use pragma target for output filename
|
||||
OP_SINGLE_SWITCH_NODE(SNAME_PRAGMA_TARGET, LNAME_PRAGMA_TARGET, OP_ARG_NONE, OP_MULTIPLE_DENIED),
|
||||
OP_END_SWITCH(),
|
||||
OP_END_LIST_NODE(),
|
||||
|
||||
// if specified, use cccp instead of cpp
|
||||
OP_SINGLE_LIST_NODE(SNAME_CCCP, LNAME_CCCP, OP_ARG_NONE, OP_MULTIPLE_DENIED, OP_NODE_OPTIONAL),
|
||||
|
||||
// if specified, be verbose
|
||||
OP_SINGLE_LIST_NODE(SNAME_VERBOSE, LNAME_VERBOSE, OP_ARG_NONE, OP_MULTIPLE_DENIED, OP_NODE_OPTIONAL),
|
||||
|
||||
// if specified, enter debug info
|
||||
OP_SINGLE_LIST_NODE(SNAME_DEBUG, LNAME_DEBUG, OP_ARG_NONE, OP_MULTIPLE_DENIED, OP_NODE_OPTIONAL),
|
||||
OP_END_LIST(),
|
||||
OP_END_SWITCH_NODE(),
|
||||
|
||||
OP_END_SWITCH()
|
||||
};
|
||||
static const int optionSpecCount = sizeof(optionSpecArray) / sizeof(optionSpecArray[0]);
|
||||
|
||||
//================================================= function prototypes ==
|
||||
int main(int argc, char *argv[]);
|
||||
static errorType evaluateArgs(void);
|
||||
static void help(void);
|
||||
static void handleError(errorType error);
|
||||
static int preprocessSource(char *sourceName);
|
||||
static void callbackFunction(void);
|
||||
static errorType loadInputToBuffer(void *destAddr, int maxBufferSize);
|
||||
|
||||
// functions called by parser.yac and parser.lex
|
||||
extern "C" void MIFFMessage(char *msg, int forceOut);
|
||||
extern "C" void MIFFSetError(void);
|
||||
extern "C" void MIFFSetIFFName(const char *newFileName);
|
||||
extern "C" void MIFFinsertForm(const char *formName);
|
||||
extern "C" void MIFFinsertChunk(const char *chunkName);
|
||||
extern "C" void MIFFinsertChunkData(void * buffer, unsigned bufferSize);
|
||||
extern "C" int MIFFloadRawData(char *fname, void * buffer, unsigned maxBufferSize);
|
||||
extern "C" void MIFFexitChunk(void);
|
||||
extern "C" void MIFFexitForm(void);
|
||||
extern "C" unsigned long MIFFgetLabelHash(char *inputStream);
|
||||
|
||||
// external functions found in parser.lex file
|
||||
extern "C" void MIFFCompile(char *inputStream, char *inputFname);
|
||||
extern "C" void MIFFCompileInit(char *inputStream, char *inputFname);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// main entry point from console call
|
||||
//
|
||||
// Return Value:
|
||||
// errorType - see enumeration; 0 if no errors
|
||||
//
|
||||
// Remarks:
|
||||
//
|
||||
//
|
||||
// See Also:
|
||||
//
|
||||
//
|
||||
// Revisions and History:
|
||||
// 1/07/99 [HAI] - created
|
||||
//
|
||||
int main( int argc, // number of args in commandline
|
||||
char * argv[] // list of pointers to strings
|
||||
)
|
||||
{
|
||||
memset(sourceBuffer, 0, bufferSize);
|
||||
|
||||
SetupSharedThread::install();
|
||||
SetupSharedDebug::install(4096);
|
||||
|
||||
SetupSharedFoundation::Data SetupSharedFoundationData (SetupSharedFoundation::Data::D_console);
|
||||
SetupSharedFoundationData.useWindowHandle = false;
|
||||
SetupSharedFoundationData.argc = argc;
|
||||
SetupSharedFoundationData.argv = argv;
|
||||
SetupSharedFoundationData.demoMode = true;
|
||||
SetupSharedFoundation::install (SetupSharedFoundationData);
|
||||
|
||||
SetupSharedCompression::install();
|
||||
|
||||
SetupSharedFile::install(false);
|
||||
|
||||
TreeFile::addSearchAbsolute(0);
|
||||
TreeFile::addSearchPath (".", 0);
|
||||
|
||||
SetupSharedFoundation::callbackWithExceptionHandling(callbackFunction);
|
||||
SetupSharedFoundation::remove();
|
||||
|
||||
SetupSharedThread::remove();
|
||||
return static_cast<int> (errorFlag);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// callback function for Engine's console entry point
|
||||
//
|
||||
// Return Value:
|
||||
// none
|
||||
//
|
||||
// Remarks:
|
||||
// this is like a substitute of main()
|
||||
//
|
||||
// See Also:
|
||||
//
|
||||
//
|
||||
// Revisions and History:
|
||||
// 1/12/99 [HAI] - created
|
||||
//
|
||||
static void callbackFunction(void)
|
||||
{
|
||||
outfileHandler = NULL;
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
// check if we're running under NT
|
||||
OSVERSIONINFO osInfo;
|
||||
Zero(osInfo);
|
||||
|
||||
osInfo.dwOSVersionInfoSize = sizeof(osInfo);
|
||||
const BOOL getVersionResult = GetVersionEx(&osInfo);
|
||||
if (getVersionResult)
|
||||
runningUnderNT = (osInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
|
||||
if (runningUnderNT)
|
||||
DEBUG_REPORT_LOG(true, ("MIFF: running under Windows NT platform\n"));
|
||||
else
|
||||
DEBUG_REPORT_LOG(true, ("MIFF: running under non-NT Windows platform\n"));
|
||||
|
||||
#endif
|
||||
|
||||
errorFlag = evaluateArgs();
|
||||
if (ERR_NONE == errorFlag)
|
||||
{
|
||||
outfileHandler = new OutputFileHandler(outFileName);
|
||||
MIFFCompile(sourceBuffer, inFileName);
|
||||
}
|
||||
else
|
||||
handleError(errorFlag);
|
||||
|
||||
if (outfileHandler)
|
||||
{
|
||||
// only write output IF there was no error
|
||||
if (ERR_NONE == errorFlag)
|
||||
{
|
||||
if (!outfileHandler->writeBuffer())
|
||||
{
|
||||
fprintf(stderr, "MIFF: failed to write output file \"%s\"\n", outFileName);
|
||||
errorFlag = ERR_WRITEERROR;
|
||||
}
|
||||
}
|
||||
delete outfileHandler;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Evaluates the command line and sets up the environment variables required for mIFF to function
|
||||
//
|
||||
// Return Value:
|
||||
// errorType
|
||||
//
|
||||
// Remarks:
|
||||
// argc's and argv's are substituted with CommandLine::functions()
|
||||
//
|
||||
// See Also:
|
||||
//
|
||||
//
|
||||
// Revisions and History:
|
||||
// 1/07/99 [HAI] - created
|
||||
//
|
||||
static errorType evaluateArgs(void)
|
||||
{
|
||||
errorType retVal = ERR_NONE;
|
||||
|
||||
// parse the commandline
|
||||
const CommandLine::MatchCode mc = CommandLine::parseOptions(optionSpecArray, optionSpecCount);
|
||||
if (mc != CommandLine::MC_MATCH)
|
||||
{
|
||||
// -TF- add call to retrieve command line error buffer for display (as soon as it is written!)
|
||||
printf("WARNING: usage error detected, printing help.\n");
|
||||
help();
|
||||
return ERR_OPTIONS;
|
||||
}
|
||||
else if (CommandLine::getOccurrenceCount(SNAME_HELP))
|
||||
{
|
||||
// user specified help
|
||||
help();
|
||||
retVal = ERR_HELPREQUEST;
|
||||
return(retVal);
|
||||
}
|
||||
|
||||
// at this point, we can assume a valid combination of options has been specified on the commandline
|
||||
|
||||
|
||||
// setup input filename
|
||||
strcpy(inFileName, CommandLine::getOptionString(SNAME_INPUT_FILE));
|
||||
|
||||
|
||||
// handle output filename spec
|
||||
if (CommandLine::getOccurrenceCount(SNAME_OUTPUT_FILE))
|
||||
{
|
||||
strcpy(outFileName, CommandLine::getOptionString(SNAME_OUTPUT_FILE));
|
||||
}
|
||||
else if (CommandLine::getOccurrenceCount(SNAME_PRAGMA_TARGET))
|
||||
{
|
||||
// use pragma target within iff source for output filename
|
||||
usePragma = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// no output option specified on commandline, derive from input filename
|
||||
char *terminator;
|
||||
|
||||
// start with input file pathname
|
||||
strcpy(outFileName, inFileName);
|
||||
|
||||
// try to terminate at rightmost '.'
|
||||
terminator = strrchr(outFileName, '.');
|
||||
if (terminator)
|
||||
*terminator = 0;
|
||||
|
||||
// append the default iff extension
|
||||
strcat(outFileName, ".iff");
|
||||
}
|
||||
|
||||
|
||||
// handle options (get them out of the way, as we use them later)
|
||||
useCCCP = (CommandLine::getOccurrenceCount(SNAME_CCCP) != 0);
|
||||
verboseMode = (CommandLine::getOccurrenceCount(SNAME_VERBOSE) != 0);
|
||||
debugMode = (CommandLine::getOccurrenceCount(SNAME_DEBUG) != 0);
|
||||
|
||||
|
||||
// preprocess the input file
|
||||
if (0 == preprocessSource(inFileName))
|
||||
{
|
||||
if (verboseMode)
|
||||
{
|
||||
sprintf(err_msg,"Now compiling %s...\n", inFileName);
|
||||
MIFFMessage(err_msg, 0);
|
||||
}
|
||||
if (ERR_NONE == retVal)
|
||||
retVal = loadInputToBuffer(sourceBuffer, bufferSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
// preprocessSource returned an error...
|
||||
retVal = ERR_PREPROCESS;
|
||||
}
|
||||
if (retVal != ERR_NONE)
|
||||
return retVal;
|
||||
|
||||
return retVal;
|
||||
|
||||
#if 0
|
||||
|
||||
errorType retVal = ERR_NONE; // assume no error has been found
|
||||
bool outPathUsed = false; // flag to monitor if -o flag was used, if so, we can ignore -d, -p, -e, -f
|
||||
bool inFileEntered = false;
|
||||
int argc = CommandLine::getPlainCount();
|
||||
|
||||
// get default values from DOS
|
||||
char currentDir[maxStringSize];
|
||||
if (NULL == getcwd(currentDir, maxStringSize)) // get current working directory
|
||||
{
|
||||
retVal = ERR_UNKNOWNDIR;
|
||||
return(retVal);
|
||||
}
|
||||
drive[0] = currentDir[0]; // drive letter
|
||||
drive[1] = 0; // and null terminate it
|
||||
strcpy(extension, "IFF"); // default to uppercase .IFF
|
||||
strcpy(directory, ¤tDir[2]); // get everything after the Drive: including the first backslash
|
||||
filename[0] = 0;
|
||||
|
||||
// see specs.txt for requests
|
||||
// scan for any argv's that has '-' in the argv[n][0]'s character
|
||||
for (int index = 0; index < argc; index++) // note: if using argv[] rather then CommandLine::getPlainString() then start with 1 rather then 0
|
||||
{
|
||||
if ('-' == CommandLine::getPlainString(index)[0])
|
||||
{
|
||||
// we've found a parameter switch
|
||||
switch (tolower(CommandLine::getPlainString(index)[1])) // assume non case sensitive switches
|
||||
{
|
||||
case 'i': // install via #pragma
|
||||
{
|
||||
usePragma = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'c': // use CCCP instead of CPP
|
||||
useCCCP = true;
|
||||
break;
|
||||
|
||||
case 'v': // don't show any debug message
|
||||
verboseMode = true;
|
||||
break;
|
||||
|
||||
case '$':
|
||||
debugMode = true;
|
||||
break;
|
||||
|
||||
case 'o': // target output file name and path (complete path)
|
||||
{
|
||||
index++; // next param
|
||||
outPathUsed = true;
|
||||
strcpy(outFileName, CommandLine::getPlainString(index));
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
case 'd': // target drive letter (-p must be present)
|
||||
{
|
||||
if (!outPathUsed)
|
||||
{
|
||||
index++; // next param
|
||||
strcpy(drive, CommandLine::getPlainString(index));
|
||||
}
|
||||
else
|
||||
index++; // skip the drive letter arg that SHOULD follow the -d option
|
||||
break;
|
||||
}
|
||||
|
||||
case 'p': // target pathname
|
||||
{
|
||||
if (!outPathUsed)
|
||||
{
|
||||
index++; // next param
|
||||
strcpy(directory, CommandLine::getPlainString(index));
|
||||
}
|
||||
else
|
||||
index++; // skip the pathname arg that follows the -p option
|
||||
break;
|
||||
}
|
||||
|
||||
case 'f': // target filename
|
||||
{
|
||||
if (!outPathUsed)
|
||||
{
|
||||
index++; // next param
|
||||
strcpy(filename, CommandLine::getPlainString(index));
|
||||
}
|
||||
else
|
||||
index++; // skip the filename arg that follows the -f
|
||||
break;
|
||||
}
|
||||
|
||||
case 'e': // target extension
|
||||
{
|
||||
if (!outPathUsed)
|
||||
{
|
||||
index++; // next param
|
||||
strcpy(extension, CommandLine::getPlainString(index));
|
||||
}
|
||||
else
|
||||
index++; // skip the extension arg that follows the -e
|
||||
break;
|
||||
}
|
||||
|
||||
case 'h': // help!
|
||||
case '?':
|
||||
{
|
||||
help();
|
||||
index = argc; // force to exit
|
||||
retVal = ERR_HELPREQUEST;
|
||||
return(retVal); // special case, ONLY time I call return() in the middle of the function (because I check for argc < 2 at the end of the code)
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
sprintf(err_msg, "\nUnknown parameter %s, use -h to seek help...\n", CommandLine::getPlainString(index));
|
||||
MIFFMessage(err_msg, 1);
|
||||
index = argc; // force to exit
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// we found an arg that doesn't start with '-' so let's assume it's a filename
|
||||
if (!inFileEntered)
|
||||
{
|
||||
strcpy(inFileName, CommandLine::getPlainString(index));
|
||||
inFileEntered = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
retVal = ERR_MULTIPLEINFILE;
|
||||
index = argc;
|
||||
}
|
||||
|
||||
// now construct the DEFAULT filename for this file by scanning backwards to front and only extracting the filename (no extension, no path)
|
||||
if (ERR_NONE == retVal)
|
||||
{
|
||||
char sourceName[maxStringSize];
|
||||
strcpy(sourceName, inFileName); // make a duplicate for us to play with
|
||||
for (int strIndex = strlen(sourceName); strIndex > 0; strIndex--)
|
||||
{
|
||||
if ('.' == sourceName[strIndex])
|
||||
sourceName[strIndex] = 0; // put a stopper here... we are assuming that '.' indicates extension! I'm going to assume that the person is just testing me if s/he decides to use filename like "foo.bar.psych" which will truncate to "foo"
|
||||
if ('\\' == sourceName[strIndex])
|
||||
break; // get out, for we've reached the path name...
|
||||
}
|
||||
|
||||
// ok, by here, strIndex should point to either beginning of the string, or where the first '\' was found scanning backwards
|
||||
strcpy(filename, &sourceName[strIndex]); // ta-da-!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (inFileEntered)
|
||||
{
|
||||
if (0 == preprocessSource(inFileName))
|
||||
{
|
||||
if (verboseMode)
|
||||
{
|
||||
// using err_msg as my temp buffer...
|
||||
sprintf(err_msg,"Now compiling %s\n", inFileName);
|
||||
MIFFMessage(err_msg, 0);
|
||||
}
|
||||
|
||||
if (ERR_NONE == retVal)
|
||||
retVal = loadInputToBuffer(sourceBuffer, bufferSize);
|
||||
}
|
||||
else // preprocessSource returned an error...
|
||||
{
|
||||
retVal = ERR_PREPROCESS;
|
||||
}
|
||||
}
|
||||
else // inFileEntered == false
|
||||
{
|
||||
MIFFMessage("Missing input filename in command line!", 1);
|
||||
}
|
||||
|
||||
// construct a outFileName[] based on drive[], directory[], filename[], and extension[]
|
||||
if (!outPathUsed && (ERR_NONE == retVal))
|
||||
{
|
||||
if (inFileName[0]) // make sure the user has entered a input filename
|
||||
sprintf(outFileName,"%s:%s\\%s.%s", drive, directory, filename, extension);
|
||||
}
|
||||
|
||||
if (argc < 1)
|
||||
retVal = ERR_ARGSTOOFEW; // we can do this because we know -h was not entered...
|
||||
|
||||
return(retVal);
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// reads the tmeporary files spit out by CCCP and stuffs the plain text into source buffer
|
||||
//
|
||||
// Return Value:
|
||||
// errorType
|
||||
//
|
||||
// Remarks:
|
||||
//
|
||||
//
|
||||
// See Also:
|
||||
//
|
||||
//
|
||||
// Revisions and History:
|
||||
// 1/14/99 [HAI] - created
|
||||
//
|
||||
static errorType loadInputToBuffer(
|
||||
void * dest, // destination address of where you want the date to be read
|
||||
int maxBufferSize // maximum destination data pool size
|
||||
)
|
||||
{
|
||||
errorType retVal = ERR_NONE;
|
||||
InputFileHandler *inFileHandler = new InputFileHandler("mIFF.$$$");
|
||||
if (inFileHandler)
|
||||
{
|
||||
int sizeRead = inFileHandler->read(dest, maxBufferSize);
|
||||
if (sizeRead >= maxBufferSize)
|
||||
{
|
||||
retVal = ERR_BUFFERTOOSMALL;
|
||||
}
|
||||
else
|
||||
{
|
||||
reinterpret_cast<char *>(dest)[sizeRead] = 0; // so stupid... but if you don't zero-terminate at exact spot, YYInput may chokes because of extra grammer that may exist...
|
||||
}
|
||||
if (!debugMode)
|
||||
inFileHandler->deleteFile("mIFF.$$$", true); // no need for temp file now...
|
||||
|
||||
// we've successfully read the file, now close it...
|
||||
delete inFileHandler;
|
||||
}
|
||||
else // inFileName is NULL
|
||||
{
|
||||
retVal = ERR_FILENOTFOUND;
|
||||
}
|
||||
|
||||
return(retVal);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// help function called by main upon -h switch
|
||||
//
|
||||
// Return Value:
|
||||
// none
|
||||
//
|
||||
// Remarks:
|
||||
// #include's mIFF.dox
|
||||
// make sure to update the version when modified.
|
||||
// Notice that help() does NOT go thru MIFFMessage() because we want it to
|
||||
// print out whether it's verbose mode or not...
|
||||
//
|
||||
// See Also:
|
||||
// mIFF.dox
|
||||
//
|
||||
// Revisions and History:
|
||||
// 1/07/99 [HAI] - created
|
||||
//
|
||||
static void help(void)
|
||||
{
|
||||
printf("\nmIFF v%s (DOS version) - Bootprint Ent. (c) 1999\n", version);
|
||||
printf("Hideki Ikeda\n");
|
||||
#include "mIFF.dox"
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// upon exit from main(), if error has been found, it calls here to inform the user of the type of errors it has encounted.
|
||||
//
|
||||
// Return Value:
|
||||
// none
|
||||
//
|
||||
// Remarks:
|
||||
// use -q switch to suppress error messages - but in shell, return value can be used to determine the handling
|
||||
//
|
||||
// See Also:
|
||||
//
|
||||
//
|
||||
// Revisions and History:
|
||||
// 1/07/99 [HAI] - created
|
||||
//
|
||||
static void handleError(errorType error)
|
||||
{
|
||||
if (ERR_NONE == error)
|
||||
return;
|
||||
|
||||
switch (error)
|
||||
{
|
||||
case ERR_NONE:
|
||||
break;
|
||||
|
||||
case ERR_FILENOTFOUND:
|
||||
MIFFMessage("ERROR: INPUT File not found!\n", 1);
|
||||
break;
|
||||
|
||||
case ERR_ARGSTOOFEW:
|
||||
MIFFMessage("ERROR: Not enough arguments. Use -h for help.\n", 1);
|
||||
break;
|
||||
|
||||
case ERR_BUFFERTOOSMALL:
|
||||
MIFFMessage("ERROR: Internally allocated buffer for reading\nsource code is too small, increase buffer and re-compile\n", 1);
|
||||
break;
|
||||
|
||||
case ERR_UNKNOWNDIR:
|
||||
MIFFMessage("ERROR: Directory unknown...\n", 1);
|
||||
break;
|
||||
|
||||
case ERR_PREPROCESS:
|
||||
MIFFMessage("ERROR: Possible problems running the GNU C Preprocessor.\n", 1);
|
||||
break;
|
||||
|
||||
case ERR_MULTIPLEINFILE:
|
||||
MIFFMessage("ERROR: There can only be ONE inputfile name.\nPerhaps you've forgotten the -o option flag\n", 1);
|
||||
break;
|
||||
|
||||
case ERR_ENGINE:
|
||||
MIFFMessage("ERROR: Engine returned a non-zero value...\n", 1);
|
||||
break;
|
||||
|
||||
case ERR_PARSER:
|
||||
MIFFMessage("ERROR: Parser error\n", 1);
|
||||
break;
|
||||
|
||||
case ERR_HELPREQUEST:
|
||||
break;
|
||||
|
||||
case ERR_OPTIONS:
|
||||
MIFFMessage("ERROR: Failed to handle command line options\n", 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
MIFFMessage("ERROR: Unknown error, you suck!\n", 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// gotta write all these externs because you can't call C++ class based non-static
|
||||
// functions from C... So we will use here as the bridge between the two
|
||||
// languages
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Message output handler called by ALL external "C" functions
|
||||
//
|
||||
// Return Value:
|
||||
// none
|
||||
//
|
||||
// Remarks:
|
||||
// all the messages that are displayed are channeled thru this function. Note the -q quiet mode suppresses all messages.
|
||||
// this is an extern "C" function
|
||||
//
|
||||
// See Also:
|
||||
// yyerror()
|
||||
//
|
||||
// Revisions and History:
|
||||
// 1/07/99 [] - created
|
||||
//
|
||||
extern "C" void MIFFMessage(char *message, // null terminated string to be displayed
|
||||
int forceOutput) // if non-zero, it will print out even in quiet mode (for ERRORs)
|
||||
{
|
||||
if (forceOutput)
|
||||
fprintf(stdout, "%s\n", message);
|
||||
else if (verboseMode)
|
||||
fprintf(stdout, "%s\n", message);
|
||||
OutputDebugString(message);
|
||||
OutputDebugString("\n");
|
||||
}
|
||||
|
||||
// Only call this via parser!!!
|
||||
extern "C" void MIFFSetError(void)
|
||||
{
|
||||
errorFlag = ERR_PARSER;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// validation of the filename passed are legal.
|
||||
//
|
||||
// Return Value:
|
||||
// bool usePragma - whether #pragma is ignored or not
|
||||
//
|
||||
// Remarks:
|
||||
// if -i switch is used then #pragma's are expected
|
||||
// this is an extern "C" function
|
||||
//
|
||||
// See Also:
|
||||
//
|
||||
//
|
||||
// Revisions and History:
|
||||
// 1/07/99 [ ] - created
|
||||
//
|
||||
extern "C" int validateTargetFilename( char *targetFileName, // pointer to where we can store the string filename
|
||||
unsigned maxTargetBufSize // size of the filename string buffer
|
||||
)
|
||||
{
|
||||
if (strlen(outFileName) > maxTargetBufSize)
|
||||
MIFFMessage("Internal error, increase string buffer size in parser.yac and recompile!", 1);
|
||||
|
||||
strcpy(targetFileName, outFileName);
|
||||
|
||||
return(usePragma);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// function calls CCCP or CPP via shell to preprocess the source code for #include's and #define's via C-Compatible Compiler Preprocessor
|
||||
//
|
||||
// Return Value:
|
||||
// shell return value (4DOS is very generous on returning different values, while DOS just returns 0 all the time)
|
||||
//
|
||||
// Remarks:
|
||||
// use -c switch to use CCCP rather then CPP in your search path
|
||||
//
|
||||
// See Also:
|
||||
//
|
||||
//
|
||||
// Revisions and History:
|
||||
// 1/07/99 [ ] - created
|
||||
//
|
||||
static int preprocessSource(char *sourceName)
|
||||
{
|
||||
char shellCommand[512];
|
||||
int retVal = 0;
|
||||
|
||||
memset(shellCommand, 0, sizeof(shellCommand));
|
||||
|
||||
// if (!runningUnderNT)
|
||||
{
|
||||
|
||||
if (verboseMode)
|
||||
MIFFMessage("Preprocessing... via CCCP", 0);
|
||||
|
||||
// CCCP parameters:
|
||||
// -nostdinc -nostdinc++ - do NOT search for standard include directory; without this, your
|
||||
// puter would be just twiddling its thumb because CCCP can't find it...
|
||||
// -pedantic - issue warnings (use pedantic-errors if you want it as errors)
|
||||
// required by the ANSI C standard in certain cases such as comments that
|
||||
// follow the #else/#endif
|
||||
// -dD - output #defines (for the purpose of error msg I parse)
|
||||
// -H - display the name of the header/included files (verbose mode)
|
||||
// -P - originally, I had this... so it won't show the # line_num "filename" ???
|
||||
if (!useCCCP && verboseMode)
|
||||
{
|
||||
sprintf(shellCommand, "cpp.exe -nostdinc -nostdinc++ -pedantic -Wall -dD -H %s mIFF.$$$", sourceName);
|
||||
}
|
||||
else if (!useCCCP && !verboseMode)
|
||||
{
|
||||
sprintf(shellCommand, "cpp.exe -nostdinc -nostdinc++ -pedantic -Wall -dD %s mIFF.$$$", sourceName);
|
||||
}
|
||||
else if (useCCCP && verboseMode)
|
||||
{
|
||||
sprintf(shellCommand, "cccp.exe -nostdinc -nostdinc++ -pedantic -Wall -dD -H %s mIFF.$$$", sourceName);
|
||||
}
|
||||
else
|
||||
sprintf(shellCommand, "cccp.exe -nostdinc -nostdinc++ -pedantic -Wall -dD %s mIFF.$$$", sourceName);
|
||||
}
|
||||
// else
|
||||
{
|
||||
// running under NT. Use the MSVC cl since it deals with long filenames on fat16/fat32 partitions correctly
|
||||
// and ccp and cccp don't
|
||||
// sprintf(shellCommand, "cl /nologo /W4 /EP %s > mIFF.$$$", sourceName);
|
||||
}
|
||||
|
||||
retVal = system(shellCommand);
|
||||
if (2 == retVal) // actually, I think 4DOS reports 2 for cannot find file, but DOS returns a 0...
|
||||
{
|
||||
REPORT_LOG(true, ("failed to execute following shell command (%d):\n", retVal));
|
||||
REPORT_LOG(true, (" %s\n", shellCommand));
|
||||
MIFFMessage("\n\nERROR: Cannot find preprocessor (either CCCP.EXE, CPP.EXE or CL.EXE (under NT) in the search path...\n", 1);
|
||||
MIFFMessage("Please make sure the preprocessor is in your search path!\n", 1);
|
||||
}
|
||||
return(retVal);
|
||||
}
|
||||
|
||||
extern "C" void MIFFSetIFFName(const char *newFileName)
|
||||
{
|
||||
if (ERR_NONE != errorFlag)
|
||||
return;
|
||||
|
||||
if (outfileHandler)
|
||||
outfileHandler->setCurrentFilename(newFileName);
|
||||
}
|
||||
|
||||
extern "C" void MIFFinsertForm(const char *formName)
|
||||
{
|
||||
if (ERR_NONE != errorFlag)
|
||||
return;
|
||||
|
||||
if (outfileHandler)
|
||||
outfileHandler->insertForm(formName);
|
||||
}
|
||||
|
||||
extern "C" void MIFFinsertChunk(const char *chunkName)
|
||||
{
|
||||
if (ERR_NONE != errorFlag)
|
||||
return;
|
||||
|
||||
if (outfileHandler)
|
||||
outfileHandler->insertChunk(chunkName);
|
||||
}
|
||||
|
||||
extern "C" void MIFFinsertChunkData(void * buffer, unsigned bufferSize)
|
||||
{
|
||||
if (ERR_NONE != errorFlag)
|
||||
return;
|
||||
|
||||
if (outfileHandler)
|
||||
outfileHandler->insertChunkData(buffer, bufferSize);
|
||||
}
|
||||
|
||||
extern "C" int MIFFloadRawData(char *fname, void * buffer, unsigned maxBufferSize)
|
||||
{
|
||||
int sizeRead = -1;
|
||||
|
||||
if (ERR_NONE != errorFlag)
|
||||
return(sizeRead); // should be -1
|
||||
|
||||
InputFileHandler * inFileName = new InputFileHandler(fname);
|
||||
if (inFileName)
|
||||
{
|
||||
sizeRead = inFileName->read(buffer, maxBufferSize);
|
||||
if (static_cast<unsigned>(sizeRead) >= maxBufferSize)
|
||||
{
|
||||
handleError(ERR_BUFFERTOOSMALL);
|
||||
sizeRead = -1;
|
||||
}
|
||||
delete inFileName;
|
||||
}
|
||||
|
||||
return(sizeRead);
|
||||
}
|
||||
|
||||
extern "C" void MIFFexitChunk(void)
|
||||
{
|
||||
if (ERR_NONE != errorFlag)
|
||||
return;
|
||||
|
||||
if (outfileHandler)
|
||||
outfileHandler->exitChunk();
|
||||
}
|
||||
extern "C" void MIFFexitForm(void)
|
||||
{
|
||||
if (ERR_NONE != errorFlag)
|
||||
return;
|
||||
|
||||
if (outfileHandler)
|
||||
outfileHandler->exitForm();
|
||||
}
|
||||
|
||||
extern "C" char * MIFFallocString(int sizeOfString)
|
||||
{
|
||||
return(new char[sizeOfString]);
|
||||
}
|
||||
|
||||
extern "C" void MIFFfreeString(char * pointer)
|
||||
{
|
||||
delete [] pointer;
|
||||
}
|
||||
|
||||
extern "C" unsigned long MIFFgetLabelHash(char * inputStream)
|
||||
{
|
||||
return (unsigned long)Crc::calculate(inputStream);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//============================================================ End-of-file ==
|
||||
//===========================================================================
|
||||
|
||||
@@ -0,0 +1,517 @@
|
||||
%option full
|
||||
|
||||
%{
|
||||
/*-----------------------------------------------------------------------------**
|
||||
** FILE: parser.lex **
|
||||
** (c) 1998 - Bootprint GTInteractive **
|
||||
** **
|
||||
** DESCRIPTION: lexical analyzer for mIFF **
|
||||
** **
|
||||
** AUTHOR: Hideki Ikeda **
|
||||
** **
|
||||
** HISTORY: **
|
||||
** **
|
||||
** Notes: companion to parser.yac **
|
||||
**-----------------------------------------------------------------------------*/
|
||||
/* Disable compiler warnings (we want warning level 4) for anything that flex spits out */
|
||||
#pragma warning (disable: 4127) /* conditional expression is constant - ie. while(1) */
|
||||
#pragma warning (disable: 4131) /* usage of old-style declarator */
|
||||
#pragma warning (disable: 4098) /* void function returning a vlue - this is because yyterminate() is defined as return() */
|
||||
#pragma warning (disable: 4505) /* unreferenced local function has been removed (to be direct: yyunput()) */
|
||||
|
||||
/* include files */
|
||||
#include "parser.h" /* NOTE: make sure this matches what Bison/yacc spits out */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/*--------------------------------**
|
||||
** exteranl prototype declaration **
|
||||
**--------------------------------*/
|
||||
void MIFFMessage(char *message, int forceOutput);
|
||||
void MIFFSetError(void);
|
||||
char * MIFFallocString(int sizeOfString);
|
||||
void MIFFfreeString(char * pointer);
|
||||
|
||||
int yyparse();
|
||||
|
||||
/* prototype declaration */
|
||||
int MIFFYYInput(char *buf,int max_size);
|
||||
void initParser(void);
|
||||
void count(void);
|
||||
void yyerror(char *err);
|
||||
void open_brace(void);
|
||||
void close_brace(void);
|
||||
int count_brace(void);
|
||||
|
||||
void printString(char *str);
|
||||
|
||||
/* global vars that has to be pre-declared because it's referenced by the lexical analyzer */
|
||||
int initialCompile = 0;
|
||||
int globalErrorFlag = 0;
|
||||
char inFileName[512]; /* keep track of source file name for error message */
|
||||
|
||||
#undef YY_INPUT
|
||||
#define YY_INPUT(buf,result,max_size) (result = MIFFYYInput(buf,max_size))
|
||||
|
||||
#define SPACE_COUNT_FOR_TAB (8)
|
||||
|
||||
%}
|
||||
|
||||
DIGIT [0-9]
|
||||
HEXDIGIT [0-9a-fA-F]
|
||||
LETTER [A-z_]
|
||||
FLOATSYM (f|F|l|L)
|
||||
INTSYM (u|U|l|L)*
|
||||
EXP (e|E)(\+|-)?
|
||||
|
||||
%%
|
||||
"//"[^\n]*\n {
|
||||
/* don't do count(); */
|
||||
}
|
||||
|
||||
"#define"[^\n]*\n {
|
||||
/* don't you love regular expression? [^\n]* everything but \n, and then end with \n */
|
||||
/* don't do count(); just like comments */
|
||||
/* return(DEFINE); <-- note: #define's are ignored in parser for they are handled via preprocessors CCCP */
|
||||
}
|
||||
|
||||
\"([^\"]|(\\\"))*\" {
|
||||
/* start with " then ( [^\"] | (\\\") )* which means either anything but " OR \" of multiple encounter, and then close with " */
|
||||
/* case for "string" literals */
|
||||
char *s; // allocate space for string and pass the string pointer rather then yytext
|
||||
|
||||
count();
|
||||
s = MIFFallocString(strlen(yytext) + 1);
|
||||
strcpy(s, yytext+1); /* strip off the double quotes */
|
||||
s[strlen(yytext+1)-1] = 0; /* strip off the ending double quotes */
|
||||
yylval.stype = s;
|
||||
return(STR_LIT);
|
||||
}
|
||||
|
||||
"form" |
|
||||
"FORM" {
|
||||
count();
|
||||
return(FORM);
|
||||
}
|
||||
|
||||
"chunk" |
|
||||
"CHUNK" {
|
||||
count();
|
||||
return(CHUNK);
|
||||
}
|
||||
|
||||
"int32" {
|
||||
count();
|
||||
return(INT32);
|
||||
}
|
||||
"int16" {
|
||||
count();
|
||||
return(INT16);
|
||||
}
|
||||
"int8" {
|
||||
count();
|
||||
return(INT8);
|
||||
}
|
||||
"uint32" {
|
||||
count();
|
||||
return(UINT32);
|
||||
}
|
||||
"uint16" {
|
||||
count();
|
||||
return(UINT16);
|
||||
}
|
||||
"uint8" {
|
||||
count();
|
||||
return(UINT8);
|
||||
}
|
||||
"float" {
|
||||
count();
|
||||
return(FLOAT);
|
||||
}
|
||||
"double" {
|
||||
count();
|
||||
return(DOUBLE);
|
||||
}
|
||||
"string" |
|
||||
"cstring" |
|
||||
"CString" {
|
||||
count();
|
||||
return(STRING);
|
||||
}
|
||||
"wstring" |
|
||||
"WString" {
|
||||
count();
|
||||
return(WSTRING);
|
||||
}
|
||||
"labelhash" {
|
||||
count();
|
||||
return(LABELHASH);
|
||||
}
|
||||
|
||||
"sin" {
|
||||
count();
|
||||
return(SIN);
|
||||
}
|
||||
"cos" {
|
||||
count();
|
||||
return(COS);
|
||||
}
|
||||
"tan" {
|
||||
count();
|
||||
return(TAN);
|
||||
}
|
||||
"asin" {
|
||||
count();
|
||||
return(ASIN);
|
||||
}
|
||||
"acos" {
|
||||
count();
|
||||
return(ACOS);
|
||||
}
|
||||
"atan" {
|
||||
count();
|
||||
return(ATAN);
|
||||
}
|
||||
|
||||
"enum" {
|
||||
count();
|
||||
return(ENUMSTRUCT);
|
||||
}
|
||||
|
||||
"includeIFF" |
|
||||
"includeiff" {
|
||||
count();
|
||||
return(INCLUDEIFF);
|
||||
}
|
||||
"include" {
|
||||
count();
|
||||
return(INCLUDEBIN);
|
||||
}
|
||||
"#include" {
|
||||
count();
|
||||
return(INCLUDESOURCE);
|
||||
}
|
||||
"#pragma" {
|
||||
count();
|
||||
return(PRAGMA);
|
||||
}
|
||||
"drive" {
|
||||
count();
|
||||
return(PRAGMA_DRIVE);
|
||||
}
|
||||
"directory" {
|
||||
count();
|
||||
return(PRAGMA_DIR);
|
||||
}
|
||||
"filename" {
|
||||
count();
|
||||
return(PRAGMA_FNAME);
|
||||
}
|
||||
"extension" {
|
||||
count();
|
||||
return(PRAGMA_EXT);
|
||||
}
|
||||
|
||||
{LETTER}({LETTER}|{DIGIT})* {
|
||||
/* label identifiers */
|
||||
char *s; // allocate space for string and pass the string pointer rather then yytext
|
||||
|
||||
count();
|
||||
s = MIFFallocString(strlen(yytext) + 1);
|
||||
strcpy(s, yytext);
|
||||
yylval.stype = s;
|
||||
return(IDENTIFIER);
|
||||
}
|
||||
|
||||
{DIGIT}*"."{DIGIT}+{FLOATSYM}? {
|
||||
/* handle numericals (floats) */
|
||||
/*
|
||||
* {DIGIT}*"."{DIGIT}+{FLOATSYM}? means zero or more digits . one or more digit and with/without f at the end
|
||||
*/
|
||||
count();
|
||||
/* make sure to store it to dtype, and use strtod to convert to double */
|
||||
yylval.dtype = strtod((char *) yytext, (char **) 0);
|
||||
return(FLOAT_LIT);
|
||||
}
|
||||
|
||||
0[xX]{HEXDIGIT}+{INTSYM}? |
|
||||
0{DIGIT}+{INTSYM}? |
|
||||
{DIGIT}+{INTSYM}? {
|
||||
/* handle numericals ( hex, ints) */
|
||||
/*
|
||||
* 0[xX]{HEXDIGIT}+{INTSYM}? means start with 0, then X one or more digit and you can put int symbol if you want
|
||||
* 0{DIGIT}+{INTSYM}? means start with 0, one ore more digit and w/or w/o int symbol
|
||||
* {DIGIT}+{INTSYM}? means one or more digit and w/or w/o int symbol
|
||||
*/
|
||||
count();
|
||||
/* make sure to store it to ltype (long), and use strtod to convert to unsigned long */
|
||||
yylval.ltype = strtoul((char *) yytext, (char **) 0, 0);
|
||||
return(LIT);
|
||||
}
|
||||
|
||||
'(\\.|[^\\'])+' {
|
||||
/* handle 'x' - single character */
|
||||
count();
|
||||
yylval.chtype = yytext[1];
|
||||
return(CHAR_LIT);
|
||||
}
|
||||
|
||||
"#" {
|
||||
/* #'s are used for informing the parser which file and line number it is processing (debug purpose) */
|
||||
count();
|
||||
return(POUND);
|
||||
}
|
||||
|
||||
">>" {
|
||||
count();
|
||||
return(SHIFTRIGHT);
|
||||
}
|
||||
"<<" {
|
||||
count();
|
||||
return(SHIFTLEFT);
|
||||
}
|
||||
"^^" {
|
||||
count();
|
||||
return(RAISEDPOWER);
|
||||
}
|
||||
|
||||
"[" |
|
||||
"]" |
|
||||
"^" |
|
||||
";" |
|
||||
"," |
|
||||
":" |
|
||||
"=" |
|
||||
"(" |
|
||||
")" |
|
||||
"." |
|
||||
"&" |
|
||||
"!" |
|
||||
"~" |
|
||||
"-" |
|
||||
"+" |
|
||||
"*" |
|
||||
"/" |
|
||||
"%" |
|
||||
"<" |
|
||||
">" |
|
||||
"|" |
|
||||
"?" {
|
||||
/* valid operators */
|
||||
count();
|
||||
yylval.stype = yytext;
|
||||
return(* yylval.stype);
|
||||
}
|
||||
|
||||
"{" {
|
||||
count();
|
||||
open_brace();
|
||||
yylval.stype = yytext;
|
||||
return(* yylval.stype);
|
||||
}
|
||||
"}" {
|
||||
count();
|
||||
close_brace();
|
||||
yylval.stype = yytext;
|
||||
return(* yylval.stype);
|
||||
}
|
||||
|
||||
[ \t\n\r]+ {
|
||||
/* white spaces and newlines are ignored */
|
||||
count();
|
||||
}
|
||||
|
||||
<<EOF>> {
|
||||
/* do a count on bracket matching... */
|
||||
if (0 == count_brace())
|
||||
{
|
||||
if (!initialCompile && !globalErrorFlag)
|
||||
MIFFMessage("mIFF successfully compiled!\n", 0);
|
||||
}
|
||||
|
||||
yyterminate(); /* tell yyparse() it's time to quit! DO NOT comment or delete this line! */
|
||||
}
|
||||
|
||||
. {
|
||||
/* anything that's not a rule from above goes here */
|
||||
count();
|
||||
yyerror((char *) yytext);
|
||||
}
|
||||
%%
|
||||
|
||||
/*--------------------**
|
||||
** C supporting codes **
|
||||
**--------------------*/
|
||||
|
||||
/*------------------**
|
||||
** static variables **
|
||||
**------------------*/
|
||||
static char *MIFFInputStream;
|
||||
int column = 0;
|
||||
int line_num = 1;
|
||||
int line_num2 = 1;
|
||||
char error_line_buffer[4096];
|
||||
long brace_counter = 0;
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------**
|
||||
** Initialize all the static variables before all calls to MIFFCompile **
|
||||
**---------------------------------------------------------------------*/
|
||||
void initParser(void)
|
||||
{
|
||||
line_num = 1;
|
||||
column = 0;
|
||||
|
||||
brace_counter = 0;
|
||||
error_line_buffer[0] = 0;
|
||||
|
||||
globalErrorFlag = 0;
|
||||
|
||||
memset(inFileName, 0, 512); /* make sure to change this size if the char array gets bigger... */
|
||||
}
|
||||
|
||||
/*-------------------------------------------------**
|
||||
** generate a dialog box to MFC to report an error **
|
||||
**-------------------------------------------------*/
|
||||
void yyerror(char *err) /* called by yyparse() */
|
||||
{
|
||||
char myString[256];
|
||||
|
||||
if (!initialCompile)
|
||||
{
|
||||
/* spit it out in MSDev error format */
|
||||
sprintf(myString, "\n%s(%d) : yyERROR : %s\n>>%s<<", inFileName, line_num, err, error_line_buffer);
|
||||
MIFFMessage(myString, 1);
|
||||
globalErrorFlag = 1;
|
||||
MIFFSetError(); /* set global error flag for shell as well */
|
||||
yyterminate();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*-------------------------**
|
||||
** our version of YY_INPUT **
|
||||
**-------------------------*/
|
||||
int MIFFYYInput(char *buf,int max_size)
|
||||
{
|
||||
int len = strlen(MIFFInputStream);
|
||||
int n = max_size < len ? max_size : len;
|
||||
if (n > 0)
|
||||
{
|
||||
memcpy(buf,MIFFInputStream,n);
|
||||
MIFFInputStream += n;
|
||||
}
|
||||
return(n);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------**
|
||||
** line and column counter for error searching during compile **
|
||||
**------------------------------------------------------------*/
|
||||
void count()
|
||||
{
|
||||
int i;
|
||||
static char *elb = error_line_buffer;
|
||||
for (i = 0; yytext[i] != '\0'; i++)
|
||||
{
|
||||
if (yytext[i] == '\n')
|
||||
{
|
||||
column = 0;
|
||||
line_num++;
|
||||
elb = error_line_buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
*elb++ = yytext[i];
|
||||
if (yytext[i] == '\t')
|
||||
column += SPACE_COUNT_FOR_TAB - (column & (SPACE_COUNT_FOR_TAB - 1));
|
||||
else
|
||||
column++;
|
||||
}
|
||||
*elb = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------**
|
||||
** sets up current line number and filename the error came from **
|
||||
**--------------------------------------------------------------*/
|
||||
void setCurrentLineNumber(int lineNum, char * fileName, int mysteryNum)
|
||||
{
|
||||
line_num = lineNum;
|
||||
strcpy(inFileName, fileName);
|
||||
line_num2 = mysteryNum;
|
||||
}
|
||||
|
||||
/*----------------------------------------------**
|
||||
** MIFFCompile called by CMIFFView::OnCompile() **
|
||||
**----------------------------------------------*/
|
||||
void MIFFCompile(char *inputStream, char *inputFileName)
|
||||
{
|
||||
MIFFInputStream = inputStream;
|
||||
yyrestart(0);
|
||||
initParser();
|
||||
initialCompile = 0;
|
||||
strcpy(inFileName, inputFileName);
|
||||
yyparse();
|
||||
}
|
||||
|
||||
void MIFFCompileInit(char *inputStream, char *inputFileName)
|
||||
{
|
||||
MIFFInputStream = inputStream;
|
||||
yyrestart(0);
|
||||
initParser();
|
||||
initialCompile = 1;
|
||||
strcpy(inFileName, inputFileName);
|
||||
yyparse();
|
||||
}
|
||||
|
||||
/*---------------------------------------**
|
||||
** matching of open/close brace checking **
|
||||
**---------------------------------------*/
|
||||
void open_brace(void)
|
||||
{
|
||||
brace_counter++;
|
||||
}
|
||||
|
||||
void close_brace(void)
|
||||
{
|
||||
brace_counter--;
|
||||
}
|
||||
|
||||
/*
|
||||
* what: count_brace():
|
||||
* return: 0 == all braces matched
|
||||
*/
|
||||
int count_brace(void)
|
||||
{
|
||||
if (0 == brace_counter) /* things are fine... */
|
||||
return(0);
|
||||
|
||||
/* if this is called, we should have 0 brace counter if not, we have a mis-match*/
|
||||
if (brace_counter > 0)
|
||||
{
|
||||
/* a mismatch */
|
||||
yyerror("There are more OPEN brackets then closed");
|
||||
}
|
||||
else if (brace_counter < 0)
|
||||
{
|
||||
yyerror("There are more CLOSED brackets then open");
|
||||
}
|
||||
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------**
|
||||
** FLEX.SLK requires this prototype function so I'm forced to do this... **
|
||||
**-----------------------------------------------------------------------*/
|
||||
int yywrap()
|
||||
{
|
||||
return(1);
|
||||
}
|
||||
|
||||
void printString(char *str)
|
||||
{
|
||||
char ts[256];
|
||||
sprintf(ts, "%s - %s", str, yytext);
|
||||
MIFFMessage(ts, 0);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -68,5 +68,6 @@ target_link_libraries(sharedFile
|
||||
sharedCompression
|
||||
sharedDebug
|
||||
sharedFoundation
|
||||
sharedMath
|
||||
fileInterface
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user