mirror of
https://bitbucket.org/theswgsource/client-tools-1.2.git
synced 2026-01-16 23:04:40 -05:00
cleanup some junk we don't need here
This commit is contained in:
@@ -1,3 +0,0 @@
|
||||
PLATFORM =linux
|
||||
#PLATFORM_DEFINES =-DLINUX -DJNI_IBM_JAVA
|
||||
PLATFORM_DEFINES =-DLINUX
|
||||
@@ -1,334 +0,0 @@
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
$
|
||||
@@ -1,136 +0,0 @@
|
||||
//===========================================================================
|
||||
//
|
||||
// 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 ==
|
||||
//===========================================================================
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
#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__
|
||||
@@ -1,164 +0,0 @@
|
||||
//===========================================================================
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
#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__
|
||||
@@ -1,698 +0,0 @@
|
||||
/* -*-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;
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
// 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);
|
||||
@@ -1,958 +0,0 @@
|
||||
//===========================================================================
|
||||
//
|
||||
// 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 ==
|
||||
//===========================================================================
|
||||
|
||||
@@ -1,517 +0,0 @@
|
||||
%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
@@ -1 +0,0 @@
|
||||
#include "FirstTemplateCompiler.h"
|
||||
@@ -1,9 +0,0 @@
|
||||
#include "sharedFoundationTypes/FoundationTypes.h"
|
||||
#include "sharedDebug/FirstSharedDebug.h"
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
#include "FirstTemplateDefinitionCompiler.h"
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
#include "sharedFoundationTypes/FoundationTypes.h"
|
||||
#include "sharedDebug/FirstSharedDebug.h"
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// FirstTerrainViewer.h
|
||||
// copyright 2001, sony online entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_FirstTerrainViewer_H
|
||||
#define INCLUDED_FirstTerrainViewer_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -1,18 +0,0 @@
|
||||
/* SQLC_Defs.h
|
||||
*
|
||||
* This file includes common definitions needed by the other SQLClasses header files.
|
||||
* (Don't include this file directly -- files that require it will include it.)
|
||||
*
|
||||
* Note that this file is specific to each OS, because what header files are
|
||||
* needed varies in each OS. In particular, Unix versions don't want windows.h.
|
||||
*
|
||||
* ODBC versions: includes definitions of ODBC datatypes needed by the various
|
||||
* SQLClasses
|
||||
*/
|
||||
|
||||
#ifndef _SQLC_DEFS_H
|
||||
#define _SQLC_DEFS_H
|
||||
|
||||
#include <sqltypes.h>
|
||||
|
||||
#endif
|
||||
@@ -1,70 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ConfigSharedDebugLinux.cpp
|
||||
// Copyright 2002 Sony Online Entertainment, Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedDebug/FirstSharedDebug.h"
|
||||
#include "sharedDebug/ConfigSharedDebugLinux.h"
|
||||
|
||||
#include "sharedDebug/Profiler.h"
|
||||
#include "sharedFoundation/ConfigFile.h"
|
||||
|
||||
//===================================================================
|
||||
|
||||
namespace ConfigSharedDebugLinuxNamespace
|
||||
{
|
||||
bool s_useTty;
|
||||
const char *s_debugMonitorOutputFilename;
|
||||
bool s_logTtySetup;
|
||||
}
|
||||
|
||||
using namespace ConfigSharedDebugLinuxNamespace;
|
||||
|
||||
//===================================================================
|
||||
|
||||
#define KEY_BOOL(a,b) (s_ ## a = ConfigFile::getKeyBool("SharedDebugLinux", #a, b))
|
||||
#define KEY_STRING(a,b) (s_ ## a = ConfigFile::getKeyString("SharedDebugLinux", #a, b))
|
||||
// #define KEY_INT(a,b) (s_ ## a = ConfigFile::getKeyInt("ClientAnimation", #a, b))
|
||||
// #define KEY_FLOAT(a,b) (s_ ## a = ConfigFile::getKeyFloat("ClientAnimation", #a, b))
|
||||
|
||||
//===================================================================
|
||||
|
||||
void ConfigSharedDebugLinux::install(void)
|
||||
{
|
||||
KEY_BOOL(useTty, false);
|
||||
KEY_STRING(debugMonitorOutputFilename, "ttySpecifier.txt");
|
||||
KEY_BOOL(logTtySetup, false);
|
||||
|
||||
//-- Handle startup profiler handling here.
|
||||
// @todo this should move into ConfigSharedDebug or be loaded
|
||||
// by Profiler. Profiler can't load this config file option
|
||||
// because the Profiler is installed prior to the config file
|
||||
// system.
|
||||
Profiler::enableProfilerOutput(ConfigFile::getKeyBool("SharedDebugLinux", "reportProfiler", false));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedDebugLinux::getUseTty()
|
||||
{
|
||||
return s_useTty;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
char const *ConfigSharedDebugLinux::getDebugMonitorOutputFilename()
|
||||
{
|
||||
return s_debugMonitorOutputFilename;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedDebugLinux::getLogTtySetup()
|
||||
{
|
||||
return s_logTtySetup;
|
||||
}
|
||||
|
||||
//===================================================================
|
||||
@@ -1,29 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ConfigSharedDebugLinux.h
|
||||
// Copyright 2002 Sony Online Entertainment, Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_ConfigSharedDebugLinux_H
|
||||
#define INCLUDED_ConfigSharedDebugLinux_H
|
||||
|
||||
//===================================================================
|
||||
|
||||
class ConfigSharedDebugLinux
|
||||
{
|
||||
public:
|
||||
|
||||
static void install();
|
||||
|
||||
static bool getUseTty();
|
||||
static char const *getDebugMonitorOutputFilename();
|
||||
static bool getLogTtySetup();
|
||||
|
||||
};
|
||||
|
||||
//===================================================================
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,677 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// DebugHelp.cpp
|
||||
// Copyright 2001-2003 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedDebug/FirstSharedDebug.h"
|
||||
#include "sharedDebug/DebugHelp.h"
|
||||
#include "sharedSynchronization/Mutex.h"
|
||||
#include <execinfo.h>
|
||||
#include <elf.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <dlfcn.h>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <stddef.h>
|
||||
// ======================================================================
|
||||
|
||||
class SymbolCache
|
||||
{
|
||||
public:
|
||||
|
||||
struct SymbolInfo
|
||||
{
|
||||
char const *srcLib;
|
||||
char const *srcFile;
|
||||
int srcLine;
|
||||
bool found;
|
||||
};
|
||||
|
||||
static void clear();
|
||||
static SymbolInfo const &lookup(void const *addr);
|
||||
static char const *uniqueString(char const *s);
|
||||
static void *memPoolAllocate(size_t size);
|
||||
static const size_t cms_memPoolMaxBytes = 8*1024*1024;
|
||||
|
||||
private:
|
||||
static size_t ms_memPoolUsed;
|
||||
static char ms_memPool[cms_memPoolMaxBytes];
|
||||
static char *ms_memPoolFreeList;
|
||||
static Mutex ms_memPoolMutex;
|
||||
static SymbolInfo ms_nullSym;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
class SymbolCacheAllocator
|
||||
{
|
||||
public:
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef T * pointer;
|
||||
typedef T const * const_pointer;
|
||||
typedef T & reference;
|
||||
typedef T const & const_reference;
|
||||
typedef T value_type;
|
||||
|
||||
public:
|
||||
SymbolCacheAllocator() {}
|
||||
template <class U> SymbolCacheAllocator(SymbolCacheAllocator<U> const &) {}
|
||||
template <class U> struct rebind { typedef SymbolCacheAllocator<U> other; };
|
||||
|
||||
pointer allocate(size_type n, const_pointer = 0) { return reinterpret_cast<pointer>(SymbolCache::memPoolAllocate(n*sizeof(value_type))); }
|
||||
void deallocate(const_pointer p, size_type n) {}
|
||||
pointer address(reference x) const { return &x; }
|
||||
const_pointer address(const_reference x) const { return &x; }
|
||||
size_type max_size() const { return SymbolCache::cms_memPoolMaxBytes; }
|
||||
void construct(pointer p, value_type const & x) { new(p) value_type(x); }
|
||||
void destroy(pointer p) { p->~value_type(); }
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
size_t SymbolCache::ms_memPoolUsed;
|
||||
char SymbolCache::ms_memPool[SymbolCache::cms_memPoolMaxBytes];
|
||||
char *SymbolCache::ms_memPoolFreeList;
|
||||
Mutex SymbolCache::ms_memPoolMutex;
|
||||
SymbolCache::SymbolInfo SymbolCache::ms_nullSym;
|
||||
typedef std::map<void const *, SymbolCache::SymbolInfo, std::less<void const *>, SymbolCacheAllocator<std::pair<void const *, SymbolCache::SymbolInfo> > > SymbolMap;
|
||||
typedef std::vector<char const *, SymbolCacheAllocator<char const *> > UniqueStringVector;
|
||||
static SymbolMap ms_cacheMap;
|
||||
static UniqueStringVector ms_uniqueStringVector;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
static Elf32_Shdr const *elfGetObjSectionHeader(void const *objBaseAddr, int sectionIndex)
|
||||
{
|
||||
Elf32_Ehdr const *eh = reinterpret_cast<Elf32_Ehdr const *>(objBaseAddr);
|
||||
if (sectionIndex >= 0 && sectionIndex < eh->e_shnum)
|
||||
return reinterpret_cast<Elf32_Shdr const *>(static_cast<char const *>(objBaseAddr)+eh->e_shoff+sectionIndex*eh->e_shentsize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
static char const *elfGetObjSectionData(void const *objBaseAddr, int sectionIndex)
|
||||
{
|
||||
Elf32_Shdr const *sh = elfGetObjSectionHeader(objBaseAddr, sectionIndex);
|
||||
if (sh)
|
||||
return reinterpret_cast<char const *>(objBaseAddr)+sh->sh_offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
static unsigned int elfGetObjSectionSize(void const *objBaseAddr, int sectionIndex)
|
||||
{
|
||||
Elf32_Shdr const *sh = elfGetObjSectionHeader(objBaseAddr, sectionIndex);
|
||||
if (sh)
|
||||
return sh->sh_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
static char const *elfGetObjSectionName(void const *objBaseAddr, int sectionIndex)
|
||||
{
|
||||
Elf32_Ehdr const *eh = reinterpret_cast<Elf32_Ehdr const *>(objBaseAddr);
|
||||
char const *sectionStr = elfGetObjSectionData(objBaseAddr, eh->e_shstrndx);
|
||||
if (sectionStr)
|
||||
{
|
||||
Elf32_Shdr const *sh = elfGetObjSectionHeader(objBaseAddr, sectionIndex);
|
||||
if (sh)
|
||||
return sectionStr+sh->sh_name;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
static int elfGetObjSectionByName(void const *objBaseAddr, char const *sectionName)
|
||||
{
|
||||
int n = reinterpret_cast<Elf32_Ehdr const *>(objBaseAddr)->e_shnum;
|
||||
for (int i = 0; i < n; ++i)
|
||||
if (!strcmp(elfGetObjSectionName(objBaseAddr, i), sectionName))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline unsigned int dwarfGet(char const *src, u_int8_t &dest)
|
||||
{
|
||||
memcpy(&dest, src, sizeof(u_int8_t));
|
||||
return sizeof(u_int8_t);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline unsigned int dwarfGet(char const *src, u_int16_t &dest)
|
||||
{
|
||||
memcpy(&dest, src, sizeof(u_int16_t));
|
||||
return sizeof(u_int16_t);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline unsigned int dwarfGet(char const *src, u_int32_t &dest)
|
||||
{
|
||||
memcpy(&dest, src, sizeof(u_int32_t));
|
||||
return sizeof(u_int32_t);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
class LEB128
|
||||
{
|
||||
public:
|
||||
operator int() const { return value; }
|
||||
int value;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline unsigned int dwarfGet(char const *src, LEB128 &dest)
|
||||
{
|
||||
unsigned int pos = 0;
|
||||
int shift = 7;
|
||||
int byte = ((u_int8_t*)src)[pos++];
|
||||
dest.value = byte;
|
||||
while (byte >= 0x80)
|
||||
{
|
||||
byte = ((u_int8_t *)src)[pos++] ^ 1;
|
||||
dest.value ^= byte << shift;
|
||||
shift += 7;
|
||||
}
|
||||
if (shift < 32 && (byte & 0x40))
|
||||
dest.value |= -(1L<<shift);
|
||||
return pos;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
class LEB128u
|
||||
{
|
||||
public:
|
||||
operator unsigned int() const { return value; }
|
||||
unsigned int value;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline unsigned int dwarfGet(char const *src, LEB128u &dest)
|
||||
{
|
||||
unsigned int pos = 0;
|
||||
int shift = 7;
|
||||
unsigned int byte = ((u_int8_t*)src)[pos++];
|
||||
dest.value = byte;
|
||||
while (byte >= 0x80)
|
||||
{
|
||||
byte = ((u_int8_t *)src)[pos++] ^ 1;
|
||||
dest.value ^= byte << shift;
|
||||
shift += 7;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
static bool dwarfSearch(char const *dwarfLines, unsigned int linesLength, void const *addr, Dl_info const &info, char const *&retSrcFile, int &retSrcLine)
|
||||
{
|
||||
enum
|
||||
{
|
||||
DW_LNE_end_sequence = 1,
|
||||
DW_LNE_set_address = 2,
|
||||
|
||||
DW_LNS_copy = 1,
|
||||
DW_LNS_advance_pc = 2,
|
||||
DW_LNS_advance_line = 3,
|
||||
DW_LNS_set_file = 4,
|
||||
DW_LNS_set_column = 5,
|
||||
DW_LNS_negate_stmt = 6,
|
||||
DW_LNS_set_basic_block = 7,
|
||||
DW_LNS_const_add_pc = 8,
|
||||
DW_LNS_fixed_advance_pc = 9,
|
||||
};
|
||||
////
|
||||
void const *bestOverAddr = reinterpret_cast<void const *>(0xffffffff);
|
||||
void const *bestUnderAddr = 0;
|
||||
char const *bestUnderSrcFileTable = 0;
|
||||
int bestUnderSrcFileNum = 0;
|
||||
int bestUnderSrcLine = 0;
|
||||
|
||||
unsigned int stmtProgMaxLen = linesLength;
|
||||
u_int32_t stmtProgLen = 0;
|
||||
|
||||
for (unsigned int progBeginOffset = 0; progBeginOffset < linesLength; progBeginOffset += stmtProgLen+4, stmtProgMaxLen -= stmtProgLen+4)
|
||||
{
|
||||
char const *stmtProg = dwarfLines+progBeginOffset;
|
||||
// get program length
|
||||
stmtProg += dwarfGet(stmtProg, stmtProgLen);
|
||||
if (stmtProgLen < 12 || stmtProgLen+4 > stmtProgMaxLen)
|
||||
continue;
|
||||
|
||||
char const *stmtProgEnd = stmtProg+stmtProgLen;
|
||||
stmtProg += 2; // skip version
|
||||
// get prologue length
|
||||
u_int32_t stmtProgPrologueLen; stmtProg += dwarfGet(stmtProg, stmtProgPrologueLen);
|
||||
if (stmtProgPrologueLen+10 > stmtProgMaxLen)
|
||||
continue;
|
||||
|
||||
char const *stmtProgStart = stmtProg;
|
||||
u_int8_t stmtProgMinInstructionLen; stmtProg += dwarfGet(stmtProg, stmtProgMinInstructionLen);
|
||||
if (stmtProgMinInstructionLen == 0)
|
||||
continue;
|
||||
++stmtProg; // skip default_is_stmt
|
||||
int8_t stmtProgLineBase; stmtProg += dwarfGet(stmtProg, *(u_int8_t*)&stmtProgLineBase);
|
||||
u_int8_t stmtProgLineRange; stmtProg += dwarfGet(stmtProg, stmtProgLineRange);
|
||||
if (stmtProgLineRange == 0)
|
||||
continue;
|
||||
u_int8_t stmtProgOpcodeBase; stmtProg += dwarfGet(stmtProg, stmtProgOpcodeBase);
|
||||
u_int8_t const *stmtProgOpcodeLengths = reinterpret_cast<u_int8_t const *>(stmtProg);
|
||||
stmtProg += stmtProgOpcodeBase-1;
|
||||
// include dirs here
|
||||
while (*stmtProg)
|
||||
while (*stmtProg++);
|
||||
char const *stmtProgFilenames = stmtProg;
|
||||
stmtProg = stmtProgStart+stmtProgPrologueLen;
|
||||
|
||||
// run program
|
||||
|
||||
while (stmtProg < stmtProgEnd)
|
||||
{
|
||||
int progFile = 0;
|
||||
int progLine = 1;
|
||||
u_int32_t progAddr = 0;
|
||||
bool done = false;
|
||||
bool valid = false;
|
||||
|
||||
while (!done)
|
||||
{
|
||||
u_int8_t opcode = *stmtProg++;
|
||||
if (opcode < stmtProgOpcodeBase)
|
||||
{
|
||||
switch (opcode)
|
||||
{
|
||||
case 0: // extended
|
||||
{
|
||||
u_int8_t size, extendedOpcode;
|
||||
stmtProg += dwarfGet(stmtProg, size);
|
||||
stmtProg += dwarfGet(stmtProg, extendedOpcode);
|
||||
switch (extendedOpcode)
|
||||
{
|
||||
case DW_LNE_end_sequence:
|
||||
valid = true;
|
||||
done = true;
|
||||
break;
|
||||
case DW_LNE_set_address:
|
||||
stmtProg += dwarfGet(stmtProg, progAddr);
|
||||
break;
|
||||
default: // unimplemented extended opcode, skip parms
|
||||
stmtProg += size-1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DW_LNS_advance_pc:
|
||||
{
|
||||
LEB128u incr; stmtProg += dwarfGet(stmtProg, incr);
|
||||
progAddr += incr*stmtProgMinInstructionLen;
|
||||
}
|
||||
break;
|
||||
case DW_LNS_const_add_pc:
|
||||
progAddr += (255-stmtProgOpcodeBase)/stmtProgLineRange*stmtProgMinInstructionLen;
|
||||
break;
|
||||
case DW_LNS_fixed_advance_pc:
|
||||
{
|
||||
u_int16_t incr; stmtProg += dwarfGet(stmtProg, incr);
|
||||
progAddr += incr;
|
||||
}
|
||||
break;
|
||||
case DW_LNS_advance_line:
|
||||
{
|
||||
LEB128 incr; stmtProg += dwarfGet(stmtProg, incr);
|
||||
progLine += incr;
|
||||
}
|
||||
break;
|
||||
case DW_LNS_set_file:
|
||||
{
|
||||
LEB128u fileNum; stmtProg += dwarfGet(stmtProg, fileNum);
|
||||
progFile = fileNum-1;
|
||||
}
|
||||
break;
|
||||
case DW_LNS_copy:
|
||||
valid = true;
|
||||
break;
|
||||
// ignored
|
||||
case DW_LNS_set_column:
|
||||
{
|
||||
LEB128u col; stmtProg += dwarfGet(stmtProg, col);
|
||||
}
|
||||
break;
|
||||
case DW_LNS_negate_stmt:
|
||||
case DW_LNS_set_basic_block:
|
||||
break;
|
||||
default:
|
||||
{
|
||||
// unimplemented standard opcode
|
||||
// look up standard opcode length and skip that many LEB128u's
|
||||
LEB128u temp;
|
||||
for (int i = 0; i < stmtProgOpcodeLengths[opcode-1]; ++i)
|
||||
stmtProg += dwarfGet(stmtProg, temp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // special opcode
|
||||
{
|
||||
progLine += stmtProgLineBase+(opcode-stmtProgOpcodeBase)%stmtProgLineRange;
|
||||
progAddr += (opcode-stmtProgOpcodeBase)/stmtProgLineRange*stmtProgMinInstructionLen;
|
||||
valid = true;
|
||||
}
|
||||
|
||||
if (valid)
|
||||
{
|
||||
unsigned int addrOffset = 0;
|
||||
if (progAddr < reinterpret_cast<unsigned int>(info.dli_fbase))
|
||||
addrOffset = reinterpret_cast<unsigned int>(info.dli_fbase);
|
||||
const void *testAddr = reinterpret_cast<const void *>(progAddr+addrOffset);
|
||||
if (testAddr >= addr)
|
||||
{
|
||||
if (testAddr < bestOverAddr)
|
||||
bestOverAddr = testAddr;
|
||||
}
|
||||
else if (testAddr > bestUnderAddr)
|
||||
{
|
||||
bestUnderAddr = testAddr;
|
||||
bestUnderSrcFileTable = stmtProgFilenames;
|
||||
bestUnderSrcFileNum = progFile;
|
||||
bestUnderSrcLine = progLine;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bestUnderAddr && bestOverAddr != reinterpret_cast<void const *>(0xffffffff))
|
||||
{
|
||||
char const *srcFile = bestUnderSrcFileTable+1;
|
||||
for (int i = 0; i < bestUnderSrcFileNum; ++i)
|
||||
{
|
||||
while (*srcFile++);
|
||||
srcFile += 3;
|
||||
}
|
||||
retSrcFile = SymbolCache::uniqueString(srcFile);
|
||||
retSrcLine = bestUnderSrcLine;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
static bool dwarfFind(void const *addr, Dl_info const &info, char const *& retSrcFile, int &retSrcLine)
|
||||
{
|
||||
bool found = false;
|
||||
int fd = open(info.dli_fname, O_RDONLY);
|
||||
if (fd != -1)
|
||||
{
|
||||
int fileSize = lseek(fd, 0, SEEK_END);
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
void const *mappedAddr = reinterpret_cast<void const *>(mmap(0, fileSize, PROT_READ, MAP_PRIVATE, fd, 0));
|
||||
close(fd);
|
||||
if (mappedAddr != MAP_FAILED)
|
||||
{
|
||||
int dwarfLinesIndex = elfGetObjSectionByName(mappedAddr, ".debug_line");
|
||||
if (dwarfLinesIndex != -1)
|
||||
{
|
||||
try
|
||||
{
|
||||
found = dwarfSearch(
|
||||
elfGetObjSectionData(mappedAddr, dwarfLinesIndex),
|
||||
elfGetObjSectionSize(mappedAddr, dwarfLinesIndex),
|
||||
addr,
|
||||
info,
|
||||
retSrcFile,
|
||||
retSrcLine);
|
||||
}
|
||||
catch (std::bad_alloc &)
|
||||
{
|
||||
munmap(const_cast<void *>(mappedAddr), fileSize);
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
}
|
||||
munmap(const_cast<void *>(mappedAddr), fileSize);
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
struct Stab
|
||||
{
|
||||
unsigned int n_strx; // index into string table
|
||||
unsigned char n_type; // type of stab entry
|
||||
char n_other;
|
||||
unsigned short n_desc; // for N_SLINE entries, line number
|
||||
unsigned int n_value; // value of symbol
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
static bool stabSearch(Stab const *stab, unsigned int stabSize, char const *stabStr, void const *addr, Dl_info const &info, char const *&retSrcFile, int &retSrcLine)
|
||||
{
|
||||
enum
|
||||
{
|
||||
N_UNDF = 0, // undefined
|
||||
N_FUN = 0x24, // function
|
||||
N_SLINE = 0x44, // source line
|
||||
N_SO = 0x64, // source file name
|
||||
N_SOL = 0x84 // local source file name
|
||||
};
|
||||
|
||||
unsigned int stabCount = stabSize/sizeof(Stab);
|
||||
char const *srcFile = "";
|
||||
void const *funcBase = 0;
|
||||
int foundSrcLine = -1;
|
||||
|
||||
for (unsigned int i = 0; i < stabCount; ++i, ++stab)
|
||||
{
|
||||
if (stab->n_type == N_UNDF) // new stabs section, do a recursive search of it
|
||||
{
|
||||
if (stabSearch(stab+1, stab->n_desc*sizeof(Stab), stabStr, addr, info, retSrcFile, retSrcLine))
|
||||
return true;
|
||||
i += stab->n_desc;
|
||||
stab += stab->n_desc;
|
||||
srcFile = "";
|
||||
continue;
|
||||
}
|
||||
else if (stab->n_type == N_SO || stab->n_type == N_SOL) // source or header file specification
|
||||
srcFile = stabStr+stab->n_strx;
|
||||
else if (stab->n_type == N_FUN) // function specification
|
||||
{
|
||||
// This may not be terribly accurate - it's attempting to differentiate between already relocated symbols (main program)
|
||||
// and shared libs, which need to be offset by their file base
|
||||
if (reinterpret_cast<void const *>(stab->n_value) > info.dli_fbase)
|
||||
funcBase = reinterpret_cast<void const *>(stab->n_value);
|
||||
else
|
||||
funcBase = reinterpret_cast<void const *>(reinterpret_cast<unsigned int>(info.dli_fbase)+stab->n_value);
|
||||
foundSrcLine = -1;
|
||||
}
|
||||
else if (stab->n_type == N_SLINE && addr >= funcBase) // source line
|
||||
{
|
||||
if (stab->n_value < reinterpret_cast<unsigned int>(addr)-reinterpret_cast<unsigned int>(funcBase))
|
||||
foundSrcLine = stab->n_desc;
|
||||
else
|
||||
{
|
||||
retSrcLine = foundSrcLine == -1 ? stab->n_desc : foundSrcLine;
|
||||
retSrcFile = SymbolCache::uniqueString(srcFile);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
static bool stabsFind(void const *addr, Dl_info const &info, char const *& retSrcFile, int &retSrcLine)
|
||||
{
|
||||
bool found = false;
|
||||
int fd = open(info.dli_fname, O_RDONLY);
|
||||
if (fd != -1)
|
||||
{
|
||||
int fileSize = lseek(fd, 0, SEEK_END);
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
void const *mappedAddr = reinterpret_cast<void const *>(mmap(0, fileSize, PROT_READ, MAP_PRIVATE, fd, 0));
|
||||
close(fd);
|
||||
if (mappedAddr != MAP_FAILED)
|
||||
{
|
||||
int stabIndex = elfGetObjSectionByName(mappedAddr, ".stab");
|
||||
int stabStrIndex = elfGetObjSectionByName(mappedAddr, ".stabstr");
|
||||
if (stabIndex != -1 && stabStrIndex != -1)
|
||||
{
|
||||
try
|
||||
{
|
||||
found = stabSearch(
|
||||
reinterpret_cast<Stab const *>(elfGetObjSectionData(mappedAddr, stabIndex)),
|
||||
elfGetObjSectionSize(mappedAddr, stabIndex),
|
||||
elfGetObjSectionData(mappedAddr, stabStrIndex),
|
||||
addr,
|
||||
info,
|
||||
retSrcFile,
|
||||
retSrcLine);
|
||||
}
|
||||
catch (std::bad_alloc &)
|
||||
{
|
||||
munmap(const_cast<void *>(mappedAddr), fileSize);
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
}
|
||||
munmap(const_cast<void *>(mappedAddr), fileSize);
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
SymbolCache::SymbolInfo const &SymbolCache::lookup(void const *addr)
|
||||
{
|
||||
SymbolMap::const_iterator i = ms_cacheMap.find(addr);
|
||||
if (i != ms_cacheMap.end())
|
||||
return (*i).second;
|
||||
|
||||
// allow for running out of the fixed memory pool and recover gracefully
|
||||
for (int tries = 0; tries < 2; ++tries)
|
||||
{
|
||||
try
|
||||
{
|
||||
SymbolInfo &symInfo = ms_cacheMap[addr];
|
||||
Dl_info info;
|
||||
if (dladdr(addr, &info))
|
||||
{
|
||||
symInfo.srcLib = uniqueString(info.dli_fname);
|
||||
if ( stabsFind(addr, info, symInfo.srcFile, symInfo.srcLine)
|
||||
|| dwarfFind(addr, info, symInfo.srcFile, symInfo.srcLine))
|
||||
symInfo.found = true;
|
||||
}
|
||||
return symInfo;
|
||||
}
|
||||
catch (std::bad_alloc &)
|
||||
{
|
||||
ms_uniqueStringVector.clear();
|
||||
ms_cacheMap.clear();
|
||||
ms_memPoolUsed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return ms_nullSym;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
char const *SymbolCache::uniqueString(char const *s)
|
||||
{
|
||||
for (UniqueStringVector::const_iterator i = ms_uniqueStringVector.begin(); i != ms_uniqueStringVector.end(); ++i)
|
||||
if (!strcmp(s, *i))
|
||||
return *i;
|
||||
char *newString = static_cast<char *>(memPoolAllocate((strlen(s)+8)&(~7)));
|
||||
strcpy(newString, s);
|
||||
ms_uniqueStringVector.push_back(newString);
|
||||
return newString;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void *SymbolCache::memPoolAllocate(size_t size)
|
||||
{
|
||||
ms_memPoolMutex.enter();
|
||||
if (ms_memPoolUsed+size > cms_memPoolMaxBytes)
|
||||
{
|
||||
ms_memPoolMutex.leave();
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
void *ret = ms_memPool+ms_memPoolUsed;
|
||||
ms_memPoolUsed += size;
|
||||
ms_memPoolMutex.leave();
|
||||
return ret;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool lookupAddressInfo(void const *addr, char *retSrcLib, char *retSrcFile, int &retSrcLine, int stringBufLengths)
|
||||
{
|
||||
SymbolCache::SymbolInfo const &symInfo = SymbolCache::lookup(addr);
|
||||
if (retSrcLib && symInfo.srcLib)
|
||||
{
|
||||
strncpy(retSrcLib, symInfo.srcLib, stringBufLengths);
|
||||
retSrcLib[stringBufLengths-1] = '\0';
|
||||
}
|
||||
if (symInfo.found && retSrcFile)
|
||||
{
|
||||
strncpy(retSrcFile, symInfo.srcFile, stringBufLengths);
|
||||
retSrcFile[stringBufLengths-1] = '\0';
|
||||
}
|
||||
retSrcLine = symInfo.srcLine;
|
||||
return symInfo.found;
|
||||
}
|
||||
|
||||
////
|
||||
// ======================================================================
|
||||
|
||||
void DebugHelp::install()
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void DebugHelp::remove()
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool DebugHelp::lookupAddress(uint32 address, char *libName, char *fileName, int fileNameLength, int &line)
|
||||
{
|
||||
return lookupAddressInfo(reinterpret_cast<void const *>(address), libName, fileName, line, fileNameLength);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void DebugHelp::getCallStack(uint32 *callStack, int sizeOfCallStack)
|
||||
{
|
||||
for (int i = 0; i < sizeOfCallStack; ++i)
|
||||
callStack[i] = 0;
|
||||
IGNORE_RETURN(backtrace(reinterpret_cast<void **>(callStack), sizeOfCallStack));
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// DebugHelp.h
|
||||
// copyright 2000 Verant Interactive
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef DEBUG_HELP_H
|
||||
#define DEBUG_HELP_H
|
||||
|
||||
#include "sharedDebug/FirstSharedDebug.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
typedef unsigned long uint32;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class DebugHelp
|
||||
{
|
||||
public:
|
||||
|
||||
static void install();
|
||||
static void remove();
|
||||
|
||||
static void getCallStack(uint32 *callStack, int sizeOfCallStack);
|
||||
static bool lookupAddress(uint32 address, char *libName, char *fileName, int fileNameLength, int &line);
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,445 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// DebugMonitor.cpp
|
||||
// Copyright 2002, Sony Online Entertainment.h
|
||||
// All rights reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedDebug/FirstSharedDebug.h"
|
||||
#include "sharedDebug/DebugMonitor.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
#include "sharedDebug/ConfigSharedDebugLinux.h"
|
||||
#include "sharedDebug/Profiler.h"
|
||||
#include "sharedFoundation/ConfigSharedFoundation.h"
|
||||
|
||||
#include <curses.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
|
||||
// ======================================================================
|
||||
|
||||
namespace DebugMonitorNamespace
|
||||
{
|
||||
bool s_installed;
|
||||
SCREEN *s_initialScreen;
|
||||
WINDOW *s_initialWindow;
|
||||
|
||||
FILE *s_ttyOutputFile;
|
||||
FILE *s_ttyInputFile;
|
||||
SCREEN *s_outputScreen;
|
||||
WINDOW *s_outputWindow;
|
||||
}
|
||||
|
||||
using namespace DebugMonitorNamespace;
|
||||
|
||||
// ======================================================================
|
||||
// Install the debug monitor subsystem
|
||||
//
|
||||
// Remarks:
|
||||
//
|
||||
// This routine will first attempt to install the selected debug monitor.
|
||||
|
||||
void DebugMonitor::install(void)
|
||||
{
|
||||
DEBUG_FATAL(s_installed, ("DebugMonitor already installed."));
|
||||
|
||||
//-- Check if user wants to use a TTY for the DebugMonitor.
|
||||
if (!ConfigSharedDebugLinux::getUseTty())
|
||||
{
|
||||
// Do not use the DebugMonitor.
|
||||
DEBUG_REPORT_LOG(ConfigSharedDebugLinux::getLogTtySetup(), ("DebugMonitor: skipping install, ConfigSharedDebugLinux/useTty is false.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
//-- Open and retrieve the name of the TTY file for output from the TTY Specification file.
|
||||
char const *const configFilename = ConfigSharedDebugLinux::getDebugMonitorOutputFilename();
|
||||
|
||||
if (!configFilename || (*configFilename == '\0'))
|
||||
{
|
||||
DEBUG_WARNING(true, ("DebugMonitor(): skipping installation, no debugMonitorOutputFilename specified."));
|
||||
return;
|
||||
}
|
||||
|
||||
char ttyFilename[1024];
|
||||
|
||||
if (configFilename[0] != '@')
|
||||
{
|
||||
// filename is the real output filename (usually a device) for DebugMonitor output.
|
||||
strncpy(ttyFilename, configFilename, sizeof(ttyFilename) - 1);
|
||||
ttyFilename[sizeof(ttyFilename)-1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// filename is actually an indirection filename, the contents of this file contains the real filename.
|
||||
FILE *ttySpecifierFile = fopen(configFilename + 1, "r");
|
||||
if (!ttySpecifierFile)
|
||||
{
|
||||
DEBUG_WARNING(true, ("DebugMonitor: failed to open tty specifier file [%s]: [%s].", configFilename + 1, strerror(errno)));
|
||||
return;
|
||||
}
|
||||
|
||||
// Retrieve the TTY file name.
|
||||
fgets(ttyFilename, sizeof(ttyFilename), ttySpecifierFile);
|
||||
fclose(ttySpecifierFile);
|
||||
}
|
||||
|
||||
// Strip trailing newline from TTY filename.
|
||||
const int filenameLength = strlen(ttyFilename);
|
||||
if (filenameLength > 0)
|
||||
{
|
||||
// chop off trailing newline if present.
|
||||
if (ttyFilename[filenameLength - 1] == '\n')
|
||||
ttyFilename[filenameLength - 1] = '\0';
|
||||
}
|
||||
|
||||
//-- Open the TTY file for output.
|
||||
DEBUG_REPORT_LOG(ConfigSharedDebugLinux::getLogTtySetup(), ("DebugMonitor: opening TTY file [%s] for reading and writing.\n", ttyFilename));
|
||||
FILE *s_ttyOutputFile = fopen(ttyFilename, "w");
|
||||
if (!s_ttyOutputFile)
|
||||
{
|
||||
DEBUG_WARNING(true, ("DebugMonitor: failed to open tty file for output [%s]: [%s].", ttyFilename, strerror(errno)));
|
||||
return;
|
||||
}
|
||||
|
||||
//-- Open the TTY file for input.
|
||||
FILE *s_ttyInputFile = fopen(ttyFilename, "r");
|
||||
if (!s_ttyInputFile)
|
||||
{
|
||||
DEBUG_WARNING(true, ("DebugMonitor: failed to open tty file for input [%s]: [%s].", ttyFilename, strerror(errno)));
|
||||
fclose(s_ttyOutputFile);
|
||||
return;
|
||||
}
|
||||
|
||||
#if 1
|
||||
// NOTE: -TRF- I would not expect this chunk of termios setup
|
||||
// code to be necessary. My expectation is that it should
|
||||
// be handled by the curs_inopts (see man page) options I have
|
||||
// selected below. Alas, these are needed.
|
||||
|
||||
//-- Setup profiler window input mode.
|
||||
const int inputFd = STDIN_FILENO;
|
||||
|
||||
// Get terminal attributes.
|
||||
termios terminalAttributes;
|
||||
if (tcgetattr(inputFd, &terminalAttributes) != 0)
|
||||
{
|
||||
DEBUG_WARNING(true, ("DebugMonitor: tcgetattr failed [%s].", strerror(errno)));
|
||||
return;
|
||||
}
|
||||
|
||||
// Turn off line-processing mode. We want a character at a time.
|
||||
terminalAttributes.c_lflag &= ~ICANON;
|
||||
|
||||
// Turn off echo.
|
||||
terminalAttributes.c_lflag &= ~ECHO;
|
||||
|
||||
// Specify that read should return immediately (non-blocking).
|
||||
terminalAttributes.c_cc[VMIN] = 0;
|
||||
terminalAttributes.c_cc[VTIME] = 0;
|
||||
|
||||
// Set terminal attributes.
|
||||
if (tcsetattr(inputFd, TCSAFLUSH, &terminalAttributes) != 0)
|
||||
{
|
||||
DEBUG_WARNING(true, ("DebugMonitor: tcsetattr failed [%s].", strerror(errno)));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
//-- Create a curses screen to represent the DebugMonitor output tty.
|
||||
// NOTE: for now the curses input is hooked up to the application's
|
||||
// standard input. Later we may want to change that to
|
||||
// handle input from the output terminal, particularly to
|
||||
// handle profiler modifications when the output window
|
||||
// is active.
|
||||
s_outputScreen = newterm(NULL, s_ttyOutputFile, stdin);
|
||||
if (!s_outputScreen)
|
||||
{
|
||||
DEBUG_WARNING(true, ("DebugMonitor: newterm() failed [%s].", strerror(errno)));
|
||||
fclose(s_ttyOutputFile);
|
||||
fclose(s_ttyInputFile);
|
||||
return;
|
||||
}
|
||||
|
||||
//-- Initialize the curses library.
|
||||
s_initialWindow = initscr();
|
||||
if (!s_initialWindow)
|
||||
{
|
||||
DEBUG_WARNING(true, ("DebugMonitor: initscr(): failed [%s].", strerror(errno)));
|
||||
fclose(s_ttyOutputFile);
|
||||
fclose(s_ttyInputFile);
|
||||
return;
|
||||
}
|
||||
|
||||
//-- Restore the stdout window to its previous state. We won't use stdout.
|
||||
endwin();
|
||||
|
||||
//-- Set the default terminal to be the output TTY's terminal screen.
|
||||
s_initialScreen = set_term(s_outputScreen);
|
||||
if (!s_initialScreen)
|
||||
{
|
||||
DEBUG_WARNING(true, ("DebugMonitor: set_term(): failed [%s].", strerror(errno)));
|
||||
delscreen(s_outputScreen);
|
||||
fclose(s_ttyOutputFile);
|
||||
fclose(s_ttyInputFile);
|
||||
return;
|
||||
}
|
||||
|
||||
//-- Create the curses WINDOW at the full size of the TTY.
|
||||
s_outputWindow = newwin(0, 0, 0, 0);
|
||||
if (!s_outputWindow)
|
||||
{
|
||||
DEBUG_WARNING(true, ("DebugMonitor: newwin(): failed [%s].", strerror(errno)));
|
||||
delscreen(s_outputScreen);
|
||||
fclose(s_ttyOutputFile);
|
||||
fclose(s_ttyInputFile);
|
||||
return;
|
||||
}
|
||||
|
||||
//-- Destroy curses data structures associated with the stdout TTY
|
||||
delwin(s_initialWindow);
|
||||
delscreen(s_initialScreen);
|
||||
|
||||
//-- Additional profiler input setup.
|
||||
// Allow translation of arrow keys.
|
||||
if (keypad(s_outputWindow, true) == ERR)
|
||||
{
|
||||
DEBUG_WARNING(true, ("DebugMonitor: keypad() failed [%s].", strerror(errno)));
|
||||
return;
|
||||
}
|
||||
|
||||
//-- Add the removal routine to the ExitChain.
|
||||
s_installed = true;
|
||||
|
||||
// NOTE: this can't go on the exit chain because the MemoryManager
|
||||
// will write to it way late in processing.
|
||||
//ExitChain::add(remove, "DebugMonitor");
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void DebugMonitor::remove(void)
|
||||
{
|
||||
if (!s_installed)
|
||||
{
|
||||
// Exit silently rather than FATAL. There's any number of reasons why
|
||||
// we might not be installed, and the ExitChain does not call remove,
|
||||
// so this should be valid.
|
||||
return;
|
||||
}
|
||||
|
||||
s_installed = false;
|
||||
|
||||
//-- Restore the TTY's state.
|
||||
endwin();
|
||||
|
||||
//-- Delete curses data structures associated with the output terminal.
|
||||
delwin(s_outputWindow);
|
||||
s_outputWindow = 0;
|
||||
|
||||
delscreen(s_outputScreen);
|
||||
s_outputScreen = 0;
|
||||
|
||||
//-- Close file handle to output terminal.
|
||||
fclose(s_ttyOutputFile);
|
||||
s_ttyOutputFile = 0;
|
||||
|
||||
fclose(s_ttyInputFile);
|
||||
s_ttyInputFile = 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Set the debug window's z-order.
|
||||
*/
|
||||
|
||||
void DebugMonitor::setBehindWindow(HWND window)
|
||||
{
|
||||
UNREF(window);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Clear the debug monitor and home the cursor.
|
||||
*
|
||||
* If the mono monitor is not installed, this routine does nothing.
|
||||
*
|
||||
* This routine will clear the contents of the debug monitor, reset the screen
|
||||
* offset to 0, and move the cursor to the upper left corner of the screen.
|
||||
*
|
||||
* @see DebugMonitor::home(), DebugMonitor::clearToCursor()
|
||||
*/
|
||||
|
||||
void DebugMonitor::clearScreen(void)
|
||||
{
|
||||
//-- Ignore request if DebugMonitor isn't installed.
|
||||
if (!s_installed)
|
||||
return;
|
||||
|
||||
//-- Tell curses to clear the virtual screen. The actual
|
||||
// clear will not take effect until the next showOutput() call
|
||||
// is made.
|
||||
IGNORE_RETURN(wclear(s_outputWindow));
|
||||
|
||||
//-- Goto upper left corner.
|
||||
gotoXY(0, 0);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Clear the debug monitor to the current cursor position and home the cursor.
|
||||
*
|
||||
* If the debug monitor is not installed, this routine does nothing.
|
||||
*
|
||||
* This routine will clear the contents of the debug monitor only up to the
|
||||
* cursor position. If the cursor is not very far down on the screen,
|
||||
* this routine may be significantly more efficient clearing the screen.
|
||||
*
|
||||
* It will also move the cursor to the upper left corner of the screen.
|
||||
*
|
||||
* @see DebugMonitor::clearScreen(), DebugMonitor::home()
|
||||
*/
|
||||
|
||||
void DebugMonitor::clearToCursor(void)
|
||||
{
|
||||
//-- Ignore request if DebugMonitor isn't installed.
|
||||
if (!s_installed)
|
||||
return;
|
||||
|
||||
//-- I don't see this functionality in curses. Just clear
|
||||
// the entire screen.
|
||||
clearScreen();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Position the cursor on the debug monitor screen.
|
||||
*
|
||||
* If the debug monitor is not installed, this routine does nothing.
|
||||
*
|
||||
* All printing happens at the cursor position.
|
||||
*
|
||||
* @param x New X position for the cursor
|
||||
* @param y New Y position for the cursor
|
||||
*/
|
||||
|
||||
void DebugMonitor::gotoXY(int x, int y)
|
||||
{
|
||||
//-- Ignore request if DebugMonitor isn't installed.
|
||||
if (!s_installed)
|
||||
return;
|
||||
|
||||
//-- Move the cursor position to the specified location.
|
||||
const int result = wmove(s_outputWindow, y, x);
|
||||
DEBUG_REPORT_LOG(result == ERR, ("DebugMonitor: wmove(%d, %d) failed [%s].\n", y, x, strerror(errno)));
|
||||
UNREF(result);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Display a string on the debug monitor.
|
||||
* * If the debug monitor is not installed, this routine does nothing.
|
||||
*
|
||||
* Printing occurs from the cursor position.
|
||||
*
|
||||
* Newline characters '\n' will cause the cursor position to advance to the
|
||||
* beginning of the next line. If the cursor is already on the last line of
|
||||
* the screen, the screen will scroll up one line and the cursor will move to
|
||||
* the beginning of the last line.
|
||||
*
|
||||
* The backspace character '\b' will cause the cursor to move one character
|
||||
* backwards. If at the beginning of the line, the cursor will move to the
|
||||
* end of the previous line. If already on the first line of the screen, the
|
||||
* cursor position and screen contents will be unchanged.
|
||||
*
|
||||
* All other characters are placed directly into the text frame buffer.
|
||||
* After each character, the cursor will be logically advanced one
|
||||
* character forward. If the cursor was on the last column, it will advance
|
||||
* to the next line. If the cursor was already on the last line, the screen
|
||||
* will be scrolled up one line and the cursor will move to the beginning of
|
||||
* the last line.
|
||||
*
|
||||
* @param string String to display on the debug monitor
|
||||
*/
|
||||
|
||||
void DebugMonitor::print(const char *string)
|
||||
{
|
||||
//-- Ignore request if DebugMonitor isn't installed.
|
||||
if (!s_installed)
|
||||
return;
|
||||
|
||||
const int result = wprintw(s_outputWindow, const_cast<char*>(string));
|
||||
DEBUG_REPORT_LOG(result == ERR, ("WARNING: DebugMonitor: wprintw failed [%s].\n", strerror(errno)));
|
||||
UNREF(result);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Ensure all changes to the DebugMonitor have taken effect by the time
|
||||
* this function returns.
|
||||
*
|
||||
* Note: some platforms may do nothing here. The Win32 platform does not
|
||||
* require flushing. The Linux platform does. Call it assuming
|
||||
* that it is needed. It will be a no-op when not required.
|
||||
*/
|
||||
|
||||
void DebugMonitor::flushOutput()
|
||||
{
|
||||
//-- Ignore request if DebugMonitor isn't installed.
|
||||
if (!s_installed)
|
||||
return;
|
||||
|
||||
//-- Tell curses to refresh the output window so that
|
||||
// the virtual curses display is rendered to the real
|
||||
// terminal display.
|
||||
const int result = wrefresh(s_outputWindow);
|
||||
DEBUG_REPORT_LOG(result == ERR, ("WARNING: DebugMonitor: wrefresh failed [%s].\n", strerror(errno)));
|
||||
UNREF(result);
|
||||
|
||||
//-- Handle tty input here. This is somewhat hacky. Unix tty input
|
||||
// and output currently are intimately tied to the profiler. Later
|
||||
// this can be separated out so we can handle multiple TTYs for
|
||||
// multiple purposes, such as for handling a TTY-based popup debug
|
||||
// menu for on-the-fly options changing.
|
||||
const int input = wgetch(s_outputWindow);
|
||||
if (input != ERR)
|
||||
{
|
||||
#if 0
|
||||
DEBUG_REPORT_LOG(true, ("DebugMonitor: received key [index=%d].\n", input));
|
||||
#endif
|
||||
|
||||
//-- Handle input.
|
||||
switch (input)
|
||||
{
|
||||
case '8':
|
||||
case KEY_UP:
|
||||
Profiler::selectionMoveUp();
|
||||
break;
|
||||
|
||||
case '9':
|
||||
case KEY_DOWN:
|
||||
Profiler::selectionMoveDown();
|
||||
break;
|
||||
|
||||
case '0':
|
||||
case 10:
|
||||
case KEY_LEFT:
|
||||
case KEY_RIGHT:
|
||||
Profiler::selectionToggleExpanded();
|
||||
break;
|
||||
|
||||
default:
|
||||
// Nothing to do.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// DebugMonitor.h
|
||||
// Portions Copyright 1998, Bootprint Entertainment, Inc.
|
||||
// Portions Copyright 2002, Sony Online Entertainment, Inc.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_DebugMonitor_H
|
||||
#define INCLUDED_DebugMonitor_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
class DebugMonitor
|
||||
{
|
||||
private:
|
||||
|
||||
public:
|
||||
|
||||
static void install(void);
|
||||
static void remove(void);
|
||||
|
||||
typedef void* HWND;
|
||||
|
||||
static void setBehindWindow(HWND window);
|
||||
|
||||
static void clearScreen(void);
|
||||
static void clearToCursor(void);
|
||||
|
||||
static void home(void);
|
||||
static void gotoXY(int x, int y);
|
||||
static void print(const char *string);
|
||||
|
||||
static void flushOutput();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// ======================================================================
|
||||
// Move the cursor to the upper left hand corner of the mono monitor screen
|
||||
//
|
||||
// Remarks:
|
||||
//
|
||||
// If the debug monitor is not installed, this routine does nothing.
|
||||
//
|
||||
// All printing happens at the cursor position.
|
||||
//
|
||||
// This routine is identical to calling gotoXY(0,0);
|
||||
//
|
||||
// See Also:
|
||||
//
|
||||
// DebugMonitor::gotoXY()
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
inline void DebugMonitor::home(void)
|
||||
{
|
||||
gotoXY(0,0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -1,125 +0,0 @@
|
||||
//=================================================================== //
|
||||
//
|
||||
// PerformanceTimer.cpp
|
||||
// copyright 2000-2004 Sony Online Entertainment
|
||||
// All Rights Reserved
|
||||
//
|
||||
//===================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedDebug/PerformanceTimer.h"
|
||||
|
||||
//===================================================================
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
//===================================================================
|
||||
|
||||
void PerformanceTimer::install()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
PerformanceTimer::PerformanceTimer()
|
||||
{
|
||||
startTime.tv_sec = 0;
|
||||
startTime.tv_usec = 0;
|
||||
stopTime.tv_sec = 0;
|
||||
stopTime.tv_usec = 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
PerformanceTimer::~PerformanceTimer()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
void PerformanceTimer::start()
|
||||
{
|
||||
int const result = gettimeofday(&startTime, NULL);
|
||||
FATAL(result != 0,("PerformanceTimer::start failed"));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
void PerformanceTimer::resume()
|
||||
{
|
||||
long sec = stopTime.tv_sec - startTime.tv_sec;
|
||||
long usec = stopTime.tv_usec - startTime.tv_usec;
|
||||
if(usec < 0)
|
||||
{
|
||||
--sec;
|
||||
usec += 1000000;
|
||||
}
|
||||
|
||||
int const result = gettimeofday(&startTime, NULL);
|
||||
FATAL(result != 0,("PerformanceTimer::resume failed"));
|
||||
|
||||
startTime.tv_sec -= sec;
|
||||
startTime.tv_usec -= usec;
|
||||
if(startTime.tv_usec < 0)
|
||||
{
|
||||
--startTime.tv_sec;
|
||||
startTime.tv_usec += 1000000;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
void PerformanceTimer::stop()
|
||||
{
|
||||
int result = gettimeofday(&stopTime, NULL);
|
||||
FATAL(result != 0,("PerformanceTimer::start failed"));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
float PerformanceTimer::getElapsedTime() const
|
||||
{
|
||||
long sec = stopTime.tv_sec - startTime.tv_sec;
|
||||
long usec = stopTime.tv_usec - startTime.tv_usec;
|
||||
if(usec < 0)
|
||||
{
|
||||
--sec;
|
||||
usec += 1000000;
|
||||
}
|
||||
return static_cast<float>(sec) +(static_cast<float>(usec) / 1000000.0f);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
float PerformanceTimer::getSplitTime() const
|
||||
{
|
||||
timeval currentTime;
|
||||
|
||||
int const result = gettimeofday(¤tTime, NULL);
|
||||
FATAL(result != 0,("PerformanceTimer::getSplitTime failed"));
|
||||
|
||||
long sec = currentTime.tv_sec - startTime.tv_sec;
|
||||
long usec = currentTime.tv_usec - startTime.tv_usec;
|
||||
if(usec < 0)
|
||||
{
|
||||
--sec;
|
||||
usec += 1000000;
|
||||
}
|
||||
|
||||
return static_cast<float>(sec) +(static_cast<float>(usec) / 1000000.0f);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
void PerformanceTimer::logElapsedTime(const char* string) const
|
||||
{
|
||||
UNREF(string);
|
||||
|
||||
#ifdef _DEBUG
|
||||
static char buffer [1000];
|
||||
sprintf(buffer, "%s : %1.5f seconds\n", string ? string : "null", getElapsedTime());
|
||||
DEBUG_REPORT_LOG_PRINT(true, ("%s", buffer));
|
||||
#endif
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
@@ -1,51 +0,0 @@
|
||||
//=================================================================== //
|
||||
//
|
||||
// PerformanceTimer.h
|
||||
// copyright 2000-2004 Sony Online Entertainment
|
||||
// All Rights Reserved
|
||||
//
|
||||
//===================================================================
|
||||
|
||||
#ifndef INCLUDED_PerformaceTimer_H
|
||||
#define INCLUDED_PerformaceTimer_H
|
||||
|
||||
//===================================================================
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
//===================================================================
|
||||
|
||||
class PerformanceTimer
|
||||
{
|
||||
public:
|
||||
|
||||
static void install();
|
||||
|
||||
public:
|
||||
|
||||
PerformanceTimer();
|
||||
~PerformanceTimer();
|
||||
|
||||
void start();
|
||||
void resume();
|
||||
void stop();
|
||||
|
||||
float getElapsedTime() const;
|
||||
float getSplitTime() const;
|
||||
void logElapsedTime(const char* string) const;
|
||||
|
||||
private:
|
||||
|
||||
timeval startTime;
|
||||
timeval stopTime;
|
||||
|
||||
private:
|
||||
|
||||
PerformanceTimer(PerformanceTimer const &);
|
||||
PerformanceTimer & operator=(PerformanceTimer const &);
|
||||
};
|
||||
|
||||
//===================================================================
|
||||
|
||||
#endif
|
||||
@@ -1,39 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ProfilerTimer.cpp
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedDebug/FirstSharedDebug.h"
|
||||
#include "sharedDebug/ProfilerTimer.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
void ProfilerTimer::install()
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void ProfilerTimer::getTime(Type &time)
|
||||
{
|
||||
timeval tv;
|
||||
gettimeofday(&tv, 0);
|
||||
time = static_cast<Type>(tv.tv_sec)*static_cast<Type>(1000000)+static_cast<Type>(tv.tv_usec);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void ProfilerTimer::getCalibratedTime(Type &time, Type &frequency)
|
||||
{
|
||||
getTime(time);
|
||||
frequency = 1000000;
|
||||
}
|
||||
|
||||
void ProfilerTimer::getFrequency(Type &frequency)
|
||||
{
|
||||
frequency = 1000000;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -1,29 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ProfilerTimer.h
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_ProfilerTimer_H
|
||||
#define INCLUDED_ProfilerTimer_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class ProfilerTimer
|
||||
{
|
||||
public:
|
||||
|
||||
typedef uint64 Type;
|
||||
|
||||
public:
|
||||
|
||||
static void install();
|
||||
static void getTime(Type &type);
|
||||
static void getCalibratedTime(Type &time, Type &frequency);
|
||||
static void getFrequency(Type &frequency);
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -1,123 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// OsFile.cpp
|
||||
// Copyright 2002, Sony Online Entertainment Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFile/FirstSharedFile.h"
|
||||
#include "sharedFile/OsFile.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
// ======================================================================
|
||||
|
||||
void OsFile::install()
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool OsFile::exists(const char *fileName)
|
||||
{
|
||||
struct stat statBuffer;
|
||||
if (stat(fileName, &statBuffer) != 0)
|
||||
return false;
|
||||
|
||||
if (S_ISDIR(statBuffer.st_mode))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
int OsFile::getFileSize(const char *fileName)
|
||||
{
|
||||
struct stat statBuffer;
|
||||
int fileSize = 0;
|
||||
|
||||
if (stat(fileName, &statBuffer) == 0)
|
||||
{
|
||||
fileSize = static_cast<int>(statBuffer.st_size);
|
||||
}
|
||||
return fileSize;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
OsFile *OsFile::open(const char *fileName, bool randomAccess)
|
||||
{
|
||||
UNREF(randomAccess);
|
||||
|
||||
if (!exists(fileName))
|
||||
return 0;
|
||||
|
||||
// attempt to open the file
|
||||
const int handle = ::open(fileName, O_RDONLY);
|
||||
FATAL(handle < 0, ("OsFile::open failed to open file %s, errno=%d, which does exist.", fileName, errno));
|
||||
|
||||
return new OsFile(handle, DuplicateString(fileName));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
OsFile::OsFile(int handle, char *fileName)
|
||||
:
|
||||
m_handle(handle),
|
||||
m_length(0),
|
||||
m_offset(0),
|
||||
m_fileName(fileName)
|
||||
{
|
||||
m_length = lseek(m_handle, 0, SEEK_END);
|
||||
lseek(m_handle, 0, SEEK_SET);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
OsFile::~OsFile()
|
||||
{
|
||||
close(m_handle);
|
||||
delete [] m_fileName;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
int OsFile::length() const
|
||||
{
|
||||
return m_length;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void OsFile::seek(int newFilePosition)
|
||||
{
|
||||
if (m_offset != newFilePosition)
|
||||
{
|
||||
const int result = lseek(m_handle, newFilePosition, SEEK_SET);
|
||||
DEBUG_FATAL(result != newFilePosition, ("SetFilePointer failed"));
|
||||
UNREF(result);
|
||||
m_offset = newFilePosition;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
int OsFile::read(void *destinationBuffer, int numberOfBytes)
|
||||
{
|
||||
int result = 0;
|
||||
do
|
||||
{
|
||||
result = ::read(m_handle, destinationBuffer, numberOfBytes);
|
||||
DEBUG_FATAL((result < 0 && errno != EAGAIN), ("Read failed for %s: %d %d %s", m_fileName, result, errno, strerror(errno)));
|
||||
} while (result < 0);
|
||||
|
||||
m_offset += result;
|
||||
return result;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -1,51 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// OsFile.h
|
||||
// Copyright 2002, Sony Online Entertainment Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_OsFile_H
|
||||
#define INCLUDED_OsFile_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class OsFile
|
||||
{
|
||||
public:
|
||||
|
||||
static void install();
|
||||
|
||||
static bool exists(const char *fileName);
|
||||
static int getFileSize(const char *fileName);
|
||||
static OsFile *open(const char *fileName, bool randomAccess=false);
|
||||
|
||||
public:
|
||||
|
||||
~OsFile();
|
||||
|
||||
int length() const;
|
||||
int tell() const;
|
||||
void seek(int newFilePosition);
|
||||
int read(void *destinationBuffer, int numberOfBytes);
|
||||
|
||||
private:
|
||||
|
||||
OsFile(int handle, char *fileName);
|
||||
|
||||
OsFile();
|
||||
OsFile(const OsFile &);
|
||||
OsFile &operator =(const OsFile &);
|
||||
|
||||
private:
|
||||
|
||||
int m_handle;
|
||||
int m_length;
|
||||
int m_offset;
|
||||
char *m_fileName;
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -1,20 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ByteOrder.h
|
||||
// jeff grills
|
||||
//
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef BYTE_ORDER_H
|
||||
#define BYTE_ORDER_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#include "../../../../../../engine/shared/library/sharedFoundation/include/public/sharedFoundation/FirstPlatform.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,289 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ConfigSharedFoundation.cpp
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
// copyright 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/ConfigSharedFoundation.h"
|
||||
|
||||
#include "sharedFoundation/ConfigFile.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
const int c_defaultFatalCallStackDepth = 32;
|
||||
const int c_defaultWarningCallStackDepth = 8;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
namespace ConfigSharedFoundationNamespace
|
||||
{
|
||||
real ms_frameRateLimit;
|
||||
real ms_minFrameRate;
|
||||
bool ms_noExceptionHandling;
|
||||
|
||||
bool ms_fpuExceptionPrecision;
|
||||
bool ms_fpuExceptionUnderflow;
|
||||
bool ms_fpuExceptionOverflow;
|
||||
bool ms_fpuExceptionZeroDivide;
|
||||
bool ms_fpuExceptionDenormal;
|
||||
bool ms_fpuExceptionInvalid;
|
||||
|
||||
bool ms_demoMode;
|
||||
|
||||
bool ms_useRemoteDebug;
|
||||
int ms_defaultRemoteDebugPort;
|
||||
|
||||
bool ms_profilerExpandAllBranches = true;
|
||||
|
||||
bool ms_memoryManagerReportAllocations;
|
||||
bool ms_memoryManagerReportOnOutOfMemory;
|
||||
|
||||
bool ms_useMemoryBlockManager;
|
||||
bool ms_memoryBlockManagerDebugDumpOnRemove;
|
||||
|
||||
int ms_fatalCallStackDepth;
|
||||
int ms_warningCallStackDepth;
|
||||
bool ms_lookUpCallStackNames;
|
||||
|
||||
bool ms_alwaysCanSeeWorldCell;
|
||||
|
||||
bool ms_verboseWarnings;
|
||||
|
||||
float ms_debugReportLongFrameTime;
|
||||
}
|
||||
|
||||
using namespace ConfigSharedFoundationNamespace;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#define KEY_INT(a,b) (ms_ ## a = ConfigFile::getKeyInt("SharedFoundation", #a, b))
|
||||
#define KEY_BOOL(a,b) (ms_ ## a = ConfigFile::getKeyBool("SharedFoundation", #a, b))
|
||||
#define KEY_FLOAT(a,b) (ms_ ## a = ConfigFile::getKeyFloat("SharedFoundation", #a, b))
|
||||
// #define KEY_STRING(a,b) (ms_ ## a = ConfigFile::getKeyString("SharedFoundation", #a, b))
|
||||
|
||||
// ======================================================================
|
||||
// Determine the Platform-specific configuration information
|
||||
//
|
||||
// Remarks:
|
||||
//
|
||||
// This routine inspects the ConfigFile class to set some variables for rapid access
|
||||
// by the rest of the engine.
|
||||
|
||||
void ConfigSharedFoundation::install (const Defaults &defaults)
|
||||
{
|
||||
KEY_BOOL(noExceptionHandling, false);
|
||||
|
||||
KEY_BOOL(fpuExceptionPrecision, false);
|
||||
KEY_BOOL(fpuExceptionUnderflow, false);
|
||||
KEY_BOOL(fpuExceptionOverflow, false);
|
||||
KEY_BOOL(fpuExceptionZeroDivide, false);
|
||||
KEY_BOOL(fpuExceptionDenormal, false);
|
||||
KEY_BOOL(fpuExceptionInvalid, false);
|
||||
|
||||
KEY_BOOL(demoMode, false);
|
||||
|
||||
KEY_FLOAT(frameRateLimit, defaults.frameRateLimit);
|
||||
KEY_FLOAT(minFrameRate, 0.0f);
|
||||
|
||||
KEY_BOOL(useRemoteDebug, false);
|
||||
KEY_INT(defaultRemoteDebugPort, 4445);
|
||||
|
||||
KEY_BOOL(profilerExpandAllBranches, true);
|
||||
KEY_BOOL(memoryManagerReportAllocations, true);
|
||||
KEY_BOOL(memoryManagerReportOnOutOfMemory, true);
|
||||
|
||||
KEY_BOOL(useMemoryBlockManager, true);
|
||||
KEY_BOOL(memoryBlockManagerDebugDumpOnRemove, false);
|
||||
|
||||
KEY_INT(fatalCallStackDepth, c_defaultFatalCallStackDepth);
|
||||
KEY_INT(warningCallStackDepth, c_defaultWarningCallStackDepth);
|
||||
KEY_BOOL(lookUpCallStackNames, true);
|
||||
|
||||
KEY_BOOL(alwaysCanSeeWorldCell, false);
|
||||
|
||||
KEY_BOOL(verboseWarnings, false);
|
||||
|
||||
KEY_FLOAT(debugReportLongFrameTime, 0.25f);
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
/**
|
||||
* Return the frame rate limit value for the game.
|
||||
*
|
||||
* @return The initial frame rate limiter value
|
||||
*/
|
||||
|
||||
real ConfigSharedFoundation::getFrameRateLimit(void)
|
||||
{
|
||||
return ms_frameRateLimit;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Return the minimum frame rate limit value for the game. Frame that take longer
|
||||
* will be set to the minimum and a message will be logged.
|
||||
*
|
||||
* @return The minimum frame rate value
|
||||
*/
|
||||
|
||||
real ConfigSharedFoundation::getMinFrameRate(void)
|
||||
{
|
||||
return ms_minFrameRate;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Return whether to run with exception handling enabled.
|
||||
*
|
||||
* @return True to run without exception handling
|
||||
*/
|
||||
|
||||
bool ConfigSharedFoundation::getNoExceptionHandling(void)
|
||||
{
|
||||
return ms_noExceptionHandling;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedFoundation::getFpuExceptionPrecision(void)
|
||||
{
|
||||
return ms_fpuExceptionPrecision;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedFoundation::getFpuExceptionUnderflow(void)
|
||||
{
|
||||
return ms_fpuExceptionUnderflow;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedFoundation::getFpuExceptionOverflow(void)
|
||||
{
|
||||
return ms_fpuExceptionOverflow;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedFoundation::getFpuExceptionZeroDivide(void)
|
||||
{
|
||||
return ms_fpuExceptionZeroDivide;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedFoundation::getFpuExceptionDenormal(void)
|
||||
{
|
||||
return ms_fpuExceptionDenormal;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedFoundation::getFpuExceptionInvalid(void)
|
||||
{
|
||||
return ms_fpuExceptionInvalid;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
int ConfigSharedFoundation::getFatalCallStackDepth()
|
||||
{
|
||||
return ms_fatalCallStackDepth;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
int ConfigSharedFoundation::getWarningCallStackDepth()
|
||||
{
|
||||
return ms_warningCallStackDepth;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedFoundation::getProfilerExpandAllBranches()
|
||||
{
|
||||
return ms_profilerExpandAllBranches;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedFoundation::getUseRemoteDebug()
|
||||
{
|
||||
return ms_useRemoteDebug;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
int ConfigSharedFoundation::getDefaultRemoteDebugPort()
|
||||
{
|
||||
return ms_defaultRemoteDebugPort;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedFoundation::getDemoMode()
|
||||
{
|
||||
return ms_demoMode;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedFoundation::getAlwaysCanSeeWorldCell()
|
||||
{
|
||||
return ms_alwaysCanSeeWorldCell;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedFoundation::getLookUpCallStackNames()
|
||||
{
|
||||
return ms_lookUpCallStackNames;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedFoundation::getMemoryManagerReportAllocations()
|
||||
{
|
||||
return ms_memoryManagerReportAllocations;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedFoundation::getMemoryManagerReportOnOutOfMemory()
|
||||
{
|
||||
return ms_memoryManagerReportOnOutOfMemory;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedFoundation::getUseMemoryBlockManager()
|
||||
{
|
||||
return ms_useMemoryBlockManager;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedFoundation::getMemoryBlockManagerDebugDumpOnRemove ()
|
||||
{
|
||||
return ms_memoryBlockManagerDebugDumpOnRemove;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedFoundation::getVerboseWarnings()
|
||||
{
|
||||
return ms_verboseWarnings;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
float ConfigSharedFoundation::getDebugReportLongFrameTime()
|
||||
{
|
||||
return ms_debugReportLongFrameTime;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -1,64 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ConfigSharedFoundation.h
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_ConfigSharedFoundation_H
|
||||
#define INCLUDED_ConfigSharedFoundation_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class ConfigSharedFoundation
|
||||
{
|
||||
public:
|
||||
|
||||
struct Defaults
|
||||
{
|
||||
real frameRateLimit;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
static void install (const Defaults &defaults);
|
||||
|
||||
static real getFrameRateLimit();
|
||||
static real getMinFrameRate();
|
||||
static bool getNoExceptionHandling();
|
||||
|
||||
static bool getFpuExceptionPrecision();
|
||||
static bool getFpuExceptionUnderflow();
|
||||
static bool getFpuExceptionOverflow();
|
||||
static bool getFpuExceptionZeroDivide();
|
||||
static bool getFpuExceptionDenormal();
|
||||
static bool getFpuExceptionInvalid();
|
||||
|
||||
static bool getDemoMode();
|
||||
|
||||
static bool getUseRemoteDebug();
|
||||
static int getDefaultRemoteDebugPort();
|
||||
|
||||
static bool getProfilerExpandAllBranches();
|
||||
|
||||
static bool getMemoryManagerReportAllocations();
|
||||
static bool getMemoryManagerReportOnOutOfMemory();
|
||||
|
||||
static bool getUseMemoryBlockManager();
|
||||
static bool getMemoryBlockManagerDebugDumpOnRemove();
|
||||
|
||||
static int getFatalCallStackDepth();
|
||||
static int getWarningCallStackDepth();
|
||||
static bool getLookUpCallStackNames();
|
||||
|
||||
static bool getAlwaysCanSeeWorldCell();
|
||||
|
||||
static bool getVerboseWarnings();
|
||||
|
||||
static float getDebugReportLongFrameTime();
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -1,54 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// FirstPlatform.h
|
||||
// jeff grills
|
||||
//
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef FIRST_PLATFORM_H
|
||||
#define FIRST_PLATFORM_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#define DLLEXPORT
|
||||
|
||||
// ======================================================================
|
||||
|
||||
// C4514 unreferenced inline function has been removed
|
||||
// C4710 inline function not expanded
|
||||
// C4291 no matching operator delete found; memory will not be freed if initialization throws an exception
|
||||
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <ctype.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#include "../../../../../../engine/shared/library/sharedFoundation/include/public/sharedFoundation/PlatformGlue.h"
|
||||
#include "sharedMemoryManager/MemoryManager.h"
|
||||
|
||||
|
||||
// ======================================================================
|
||||
|
||||
template <class T>
|
||||
inline int ComGetReferenceCount(T *t)
|
||||
{
|
||||
t->AddRef();
|
||||
return t->Release();
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#define FATAL_HR(a,b) FATAL(FAILED(b), (a, HRESULT_CODE(b)))
|
||||
#define DEBUG_FATAL_HR(a,b) DEBUG_FATAL(FAILED(b), (a, HRESULT_CODE(b)))
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -1,266 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// FloatingPointUnit.cpp
|
||||
// jeff grills
|
||||
//
|
||||
// copyright 1999 Bootprint Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/FloatingPointUnit.h"
|
||||
|
||||
#include "sharedFoundation/ConfigSharedFoundation.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
int FloatingPointUnit::updateNumber;
|
||||
WORD FloatingPointUnit::status;
|
||||
FloatingPointUnit::Precision FloatingPointUnit::precision;
|
||||
FloatingPointUnit::Rounding FloatingPointUnit::rounding;
|
||||
bool FloatingPointUnit::exceptionEnabled[E_max];
|
||||
|
||||
// ======================================================================
|
||||
|
||||
const WORD PRECISION_MASK = BINARY4(0000,0011,0000,0000);
|
||||
const WORD PRECISION_24 = BINARY4(0000,0000,0000,0000);
|
||||
const WORD PRECISION_53 = BINARY4(0000,0010,0000,0000);
|
||||
const WORD PRECISION_64 = BINARY4(0000,0011,0000,0000);
|
||||
|
||||
const WORD ROUND_MASK = BINARY4(0000,1100,0000,0000);
|
||||
const WORD ROUND_NEAREST = BINARY4(0000,0000,0000,0000);
|
||||
const WORD ROUND_CHOP = BINARY4(0000,1100,0000,0000);
|
||||
const WORD ROUND_DOWN = BINARY4(0000,0100,0000,0000);
|
||||
const WORD ROUND_UP = BINARY4(0000,1000,0000,0000);
|
||||
|
||||
const WORD EXCEPTION_PRECISION = BINARY4(0000,0000,0010,0000);
|
||||
const WORD EXCEPTION_UNDERFLOW = BINARY4(0000,0000,0001,0000);
|
||||
const WORD EXCEPTION_OVERFLOW = BINARY4(0000,0000,0000,1000);
|
||||
const WORD EXCEPTION_ZERO_DIVIDE = BINARY4(0000,0000,0000,0100);
|
||||
const WORD EXCEPTION_DENORMAL = BINARY4(0000,0000,0000,0010);
|
||||
const WORD EXCEPTION_INVALID = BINARY4(0000,0000,0000,0001);
|
||||
const WORD EXCEPTION_ALL = BINARY4(0000,0000,0011,1111);
|
||||
|
||||
// ======================================================================
|
||||
|
||||
void FloatingPointUnit::install(void)
|
||||
{
|
||||
precision = P_24;
|
||||
rounding = R_roundToNearestOrEven;
|
||||
memset(exceptionEnabled, 0, sizeof(exceptionEnabled));
|
||||
|
||||
// preserve all other bits
|
||||
status = getControlWord();
|
||||
status &= ~(PRECISION_MASK | ROUND_MASK | EXCEPTION_ALL);
|
||||
|
||||
// set to single precision, rounding, and all exceptions masked
|
||||
status |= PRECISION_24 | ROUND_NEAREST | EXCEPTION_ALL;
|
||||
|
||||
// check the config platform flags to see if we should enable some exceptions
|
||||
if (ConfigSharedFoundation::getFpuExceptionPrecision())
|
||||
{
|
||||
exceptionEnabled[E_precision] = true;
|
||||
status &= ~EXCEPTION_PRECISION;
|
||||
}
|
||||
|
||||
if (ConfigSharedFoundation::getFpuExceptionUnderflow())
|
||||
{
|
||||
exceptionEnabled[E_underflow] = true;
|
||||
status &= ~EXCEPTION_UNDERFLOW;
|
||||
}
|
||||
|
||||
if (ConfigSharedFoundation::getFpuExceptionOverflow())
|
||||
{
|
||||
exceptionEnabled[E_overflow] = true;
|
||||
status &= ~EXCEPTION_OVERFLOW;
|
||||
}
|
||||
|
||||
if (ConfigSharedFoundation::getFpuExceptionZeroDivide())
|
||||
{
|
||||
exceptionEnabled[E_zeroDivide] = true;
|
||||
status &= ~EXCEPTION_ZERO_DIVIDE;
|
||||
}
|
||||
|
||||
if (ConfigSharedFoundation::getFpuExceptionDenormal())
|
||||
{
|
||||
exceptionEnabled[E_denormal] = true;
|
||||
status &= ~EXCEPTION_DENORMAL;
|
||||
}
|
||||
|
||||
if (ConfigSharedFoundation::getFpuExceptionInvalid())
|
||||
{
|
||||
exceptionEnabled[E_invalid] = true;
|
||||
status &= ~EXCEPTION_INVALID;
|
||||
}
|
||||
|
||||
setControlWord(status);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void FloatingPointUnit::update(void)
|
||||
{
|
||||
WORD currentStatus = getControlWord();
|
||||
|
||||
if (currentStatus != status)
|
||||
{
|
||||
DEBUG_REPORT_LOG_PRINT(true, ("FPU: update=%d, in mode=%04x, should be in mode=%04x", updateNumber, static_cast<int>(currentStatus), static_cast<int>(status)));
|
||||
setControlWord(status);
|
||||
}
|
||||
|
||||
++updateNumber;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
WORD FloatingPointUnit::getControlWord(void)
|
||||
{
|
||||
//TODO wtf is this asm statement?
|
||||
#if 0
|
||||
WORD controlWord = 0;
|
||||
__asm fnstcw controlWord;
|
||||
return controlWord;
|
||||
#else
|
||||
return status;
|
||||
#endif
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void FloatingPointUnit::setControlWord(WORD controlWord)
|
||||
{
|
||||
//TODO see above?
|
||||
|
||||
UNREF(controlWord);
|
||||
#if 0
|
||||
__asm fldcw controlWord;
|
||||
#endif
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void FloatingPointUnit::setPrecision(Precision newPrecision)
|
||||
{
|
||||
WORD bits = 0;
|
||||
|
||||
switch (precision)
|
||||
{
|
||||
case P_24:
|
||||
bits = PRECISION_24;
|
||||
break;
|
||||
|
||||
case P_53:
|
||||
bits = PRECISION_53;
|
||||
break;
|
||||
|
||||
case P_64:
|
||||
bits = PRECISION_64;
|
||||
break;
|
||||
|
||||
case P_max:
|
||||
default:
|
||||
DEBUG_FATAL(true, ("bad case"));
|
||||
}
|
||||
|
||||
// record the current state
|
||||
precision = newPrecision;
|
||||
|
||||
// set the proper bit pattern
|
||||
status &= ~PRECISION_MASK;
|
||||
status |= bits;
|
||||
|
||||
// slam it into the FPU
|
||||
setControlWord(status);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void FloatingPointUnit::setRounding(Rounding newRounding)
|
||||
{
|
||||
WORD bits = 0;
|
||||
|
||||
switch (newRounding)
|
||||
{
|
||||
case R_roundToNearestOrEven:
|
||||
bits = ROUND_NEAREST;
|
||||
break;
|
||||
|
||||
case R_chop:
|
||||
bits = ROUND_CHOP;
|
||||
break;
|
||||
|
||||
case R_roundDown:
|
||||
bits = ROUND_DOWN;
|
||||
break;
|
||||
|
||||
case R_roundUp:
|
||||
bits = ROUND_UP;
|
||||
break;
|
||||
|
||||
case R_max:
|
||||
default:
|
||||
DEBUG_FATAL(true, ("bad case"));
|
||||
}
|
||||
|
||||
// record the current state
|
||||
rounding = newRounding;
|
||||
|
||||
// set the proper bit pattern
|
||||
status &= ~ROUND_MASK;
|
||||
status |= bits;
|
||||
|
||||
// slam it into the FPU
|
||||
setControlWord(status);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void FloatingPointUnit::setExceptionEnabled(Exception exception, bool enabled)
|
||||
{
|
||||
WORD bits = 0;
|
||||
|
||||
switch (exception)
|
||||
{
|
||||
case E_precision:
|
||||
bits = EXCEPTION_PRECISION;
|
||||
break;
|
||||
|
||||
case E_underflow:
|
||||
bits = EXCEPTION_UNDERFLOW;
|
||||
break;
|
||||
|
||||
case E_overflow:
|
||||
bits = EXCEPTION_OVERFLOW;
|
||||
break;
|
||||
|
||||
case E_zeroDivide:
|
||||
bits = EXCEPTION_ZERO_DIVIDE;
|
||||
break;
|
||||
|
||||
case E_denormal:
|
||||
bits = EXCEPTION_DENORMAL;
|
||||
break;
|
||||
|
||||
case E_invalid:
|
||||
bits = EXCEPTION_INVALID;
|
||||
break;
|
||||
|
||||
case E_max:
|
||||
default:
|
||||
DEBUG_FATAL(true, ("bad case"));
|
||||
}
|
||||
|
||||
// record the current state
|
||||
exceptionEnabled[exception] = enabled;
|
||||
|
||||
// twiddle the bit appropriately. these bits masks, so set the bit to disable the exception, clear the bit to enable it.
|
||||
if (enabled)
|
||||
status &= ~bits;
|
||||
else
|
||||
status |= bits;
|
||||
|
||||
// slam it into the FPU
|
||||
setControlWord(status);
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -1,102 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// FloatingPointUnit.h
|
||||
// jeff grills
|
||||
//
|
||||
// copyright 1999 Bootprint Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef FLOATING_POINT_UNIT_H
|
||||
#define FLOATING_POINT_UNIT_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class FloatingPointUnit
|
||||
{
|
||||
public:
|
||||
|
||||
enum Precision
|
||||
{
|
||||
P_24,
|
||||
P_53,
|
||||
P_64,
|
||||
|
||||
P_max
|
||||
};
|
||||
|
||||
enum Rounding
|
||||
{
|
||||
R_roundToNearestOrEven,
|
||||
R_chop,
|
||||
R_roundDown,
|
||||
R_roundUp,
|
||||
|
||||
R_max
|
||||
};
|
||||
|
||||
enum Exception
|
||||
{
|
||||
E_precision,
|
||||
E_underflow,
|
||||
E_overflow,
|
||||
E_zeroDivide,
|
||||
E_denormal,
|
||||
E_invalid,
|
||||
|
||||
E_max
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
static int updateNumber;
|
||||
static WORD status;
|
||||
static Precision precision;
|
||||
static Rounding rounding;
|
||||
static bool exceptionEnabled[E_max];
|
||||
|
||||
public:
|
||||
|
||||
static WORD getControlWord(void);
|
||||
static void setControlWord(WORD controlWord);
|
||||
|
||||
public:
|
||||
|
||||
static void install(void);
|
||||
|
||||
static void update(void);
|
||||
|
||||
static void setPrecision(Precision newPrecision);
|
||||
static void setRounding(Rounding newRounding);
|
||||
static void setExceptionEnabled(Exception exception, bool enabled);
|
||||
|
||||
static Precision getPrecision(void);
|
||||
static Rounding getRounding(void);
|
||||
static bool getExceptionEnabled(Exception exception);
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
inline FloatingPointUnit::Precision FloatingPointUnit::getPrecision(void)
|
||||
{
|
||||
return precision;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline FloatingPointUnit::Rounding FloatingPointUnit::getRounding(void)
|
||||
{
|
||||
return rounding;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline bool FloatingPointUnit::getExceptionEnabled(Exception exception)
|
||||
{
|
||||
DEBUG_FATAL(static_cast<int>(exception) < 0 || static_cast<int>(exception) >= static_cast<int>(E_max), ("exception out of range")); //lint !e568 // non-negative quantity is never less than 0
|
||||
return exceptionEnabled[exception];
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -1,468 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Os.cpp
|
||||
// jeff grills
|
||||
//
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/Os.h"
|
||||
|
||||
#include "sharedFoundation/Clock.h"
|
||||
#include "sharedFoundation/ConfigSharedFoundation.h"
|
||||
#include "sharedDebug/DebugMonitor.h"
|
||||
#include "sharedFoundation/ExitChain.h"
|
||||
#include "sharedFoundation/FloatingPointUnit.h"
|
||||
#include "sharedIoWin/IoWinManager.h"
|
||||
|
||||
#include <stack>
|
||||
#include <string>
|
||||
|
||||
// ======================================================================
|
||||
|
||||
bool Os::installed;
|
||||
bool Os::runInBackground;
|
||||
int Os::numberOfUpdates;
|
||||
int Os::menuValue;
|
||||
bool Os::paused;
|
||||
bool Os::wasPaused;
|
||||
bool Os::gameOver;
|
||||
bool Os::shouldReturnFromAbort;
|
||||
char Os::programName[PROGRAM_NAME_SIZE];
|
||||
char *Os::shortProgramName;
|
||||
pthread_t Os::mainThreadId;
|
||||
bool Os::threadDied;
|
||||
|
||||
bool Os::isMp;
|
||||
int Os::processorCount;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
namespace OsNamespace
|
||||
{
|
||||
class UncatchableException
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Install the Os subsystem for non-games.
|
||||
*
|
||||
* This routine is supported for all platforms, although different platforms may
|
||||
* require different arguments to this routine.
|
||||
*
|
||||
* This routine will add Os::remove to the ExitChain.
|
||||
*
|
||||
* @see Os::remove()
|
||||
*/
|
||||
|
||||
void Os::install(void)
|
||||
{
|
||||
installCommon();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* This routine will remove the Os subsystem.
|
||||
*
|
||||
* This routine should not be called directly. It will be called from the ExitChain.
|
||||
*
|
||||
* @see Os::install()
|
||||
*/
|
||||
|
||||
void Os::remove(void)
|
||||
{
|
||||
DEBUG_FATAL(!installed, ("not installed"));
|
||||
installed = false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void Os::installCommon(void)
|
||||
{
|
||||
DEBUG_FATAL(installed, ("already installed"));
|
||||
|
||||
ExitChain::add(Os::remove, "Os::remove", 0, true);
|
||||
|
||||
#if 0 //TODO For now we won't screw with the priority of the process
|
||||
HANDLE threadHandle = GetCurrentThread();
|
||||
DEBUG_FATAL(!SetThreadPriority(threadHandle, THREAD_PRIORITY_ABOVE_NORMAL), ("Failed to set game thread priority"));
|
||||
#endif
|
||||
|
||||
numberOfUpdates = 0;
|
||||
mainThreadId = pthread_self();
|
||||
|
||||
// get the name of the executable
|
||||
//Can't find UNIX call for this: DWORD result = GetModuleFileName(NULL, programName, sizeof(programName));
|
||||
strcpy(programName, "TempName");
|
||||
DWORD result = 1;
|
||||
|
||||
|
||||
FATAL(result == 0, ("GetModuleFileName failed"));
|
||||
|
||||
// get the file name without the path
|
||||
shortProgramName = strrchr(programName, '\\');
|
||||
if (shortProgramName)
|
||||
++shortProgramName;
|
||||
else
|
||||
shortProgramName = programName;
|
||||
|
||||
// determine the number of processors by parsing /proc/cpuinfo
|
||||
processorCount = 1;
|
||||
FILE * f = fopen("/proc/cpuinfo", "r");
|
||||
if (f)
|
||||
{
|
||||
char buffer[512];
|
||||
while (!feof(f))
|
||||
{
|
||||
fgets(buffer, 512, f);
|
||||
if (strncmp(buffer, "processor\t: ", 12)==0)
|
||||
{
|
||||
processorCount = atoi(buffer+12)+1;
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
isMp = processorCount > 1;
|
||||
|
||||
// switch into single-precision floating point mode
|
||||
FloatingPointUnit::install();
|
||||
|
||||
installed = true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool Os::isMainThread(void)
|
||||
{
|
||||
// if the Os class hasn't been installed, then assume we are the main thread.
|
||||
// otherwise, check to see if our thread id is the main thread id
|
||||
return !installed || (pthread_self() == mainThreadId);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Terminate the application because of an error condition.
|
||||
*
|
||||
* This routine is supported for all platforms.
|
||||
*
|
||||
* This routine should not be called directly. The engine and game should use the
|
||||
* FATAL macro to terminate the application because of an error.
|
||||
*
|
||||
* Calling Os::returnFromAbort() will cause the routine to do nothing but return
|
||||
* immediately.
|
||||
*
|
||||
* @see Os::returnFromAbort(), FATAL()
|
||||
*/
|
||||
#include <signal.h>
|
||||
void Os::abort(void)
|
||||
{
|
||||
if (!isMainThread())
|
||||
{
|
||||
threadDied = true;
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
if (!shouldReturnFromAbort)
|
||||
{
|
||||
// let the C runtime deal with the abnormal termination
|
||||
int * dummy = NULL;
|
||||
int forceCrash = *dummy;
|
||||
UNREF(forceCrash);
|
||||
for (;;)
|
||||
{
|
||||
// One of these should work:
|
||||
pthread_kill(pthread_self(), SIGSEGV);
|
||||
::kill(0,SIGSEGV);
|
||||
::abort();
|
||||
OsNamespace::UncatchableException ex;
|
||||
throw ex;
|
||||
sleep(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
/**
|
||||
* Create the specified directory and all of it's parents.
|
||||
* @param directory the path to a directory
|
||||
* @return always true currently
|
||||
*/
|
||||
|
||||
bool Os::createDirectories (const char *directory)
|
||||
{
|
||||
//-- construct list of subdirectories all the way down to root
|
||||
std::stack<std::string> directoryStack;
|
||||
|
||||
std::string currentDirectory = directory;
|
||||
|
||||
static const char path_seps [] = { '\\', '/', 0 };
|
||||
|
||||
// build the stack
|
||||
while (!currentDirectory.empty())
|
||||
{
|
||||
// remove trailing backslash
|
||||
if (currentDirectory[currentDirectory.size()-1] == '\\' || currentDirectory[currentDirectory.size()-1] == '/')
|
||||
IGNORE_RETURN(currentDirectory.erase(currentDirectory.size()-1));
|
||||
|
||||
if (currentDirectory[currentDirectory.size()-1] == ':')
|
||||
{
|
||||
// we've hit something like c:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!currentDirectory.empty())
|
||||
directoryStack.push(currentDirectory);
|
||||
|
||||
// now strip off current directory
|
||||
size_t previousDirIndex = currentDirectory.find_last_of (path_seps);
|
||||
if (previousDirIndex == currentDirectory.npos)
|
||||
break;
|
||||
else
|
||||
IGNORE_RETURN(currentDirectory.erase(previousDirIndex));
|
||||
}
|
||||
|
||||
//-- build all directories specified by the initial directory
|
||||
while (!directoryStack.empty())
|
||||
{
|
||||
// get the directory
|
||||
currentDirectory = directoryStack.top();
|
||||
directoryStack.pop();
|
||||
|
||||
// try to create it (don't pass any security attributes)
|
||||
IGNORE_RETURN (mkdir (currentDirectory.c_str(), 0));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Write out a file.
|
||||
*
|
||||
* The file name and where the file is written is system-dependent.
|
||||
*
|
||||
* @param fileName Name of the file to write
|
||||
* @param data Data buffer to write to the file
|
||||
*/
|
||||
|
||||
bool Os::writeFile(const char *fileName, const void *data, int length) // Length of the data bufferto write
|
||||
{
|
||||
BOOL result;
|
||||
HANDLE handle;
|
||||
DWORD written;
|
||||
|
||||
// open the file for writing
|
||||
handle = CreateFile(fileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
// check if it was opened
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
|
||||
// attempt to write the data
|
||||
result = WriteFile(handle, data, static_cast<DWORD>(length), &written, NULL);
|
||||
|
||||
// make sure the data was written okay
|
||||
if (!result || written != static_cast<DWORD>(length))
|
||||
{
|
||||
static_cast<void>(CloseHandle(handle));
|
||||
return false;
|
||||
}
|
||||
|
||||
// close the file
|
||||
result = CloseHandle(handle);
|
||||
|
||||
// make sure the close was sucessful
|
||||
if (!result)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Update the Os subsystem.
|
||||
*
|
||||
* This routine is supported for all platforms.
|
||||
*
|
||||
* For the Win* platforms, this routine will process the windows message pump.
|
||||
*/
|
||||
|
||||
bool Os::update(void)
|
||||
{
|
||||
static int ppid = getppid();
|
||||
|
||||
FloatingPointUnit::update();
|
||||
|
||||
++numberOfUpdates;
|
||||
|
||||
#if 0
|
||||
#ifdef _DEBUG
|
||||
|
||||
if (DEBUG_FLAG_PLATFORM(validateHeap))
|
||||
{
|
||||
PROFILER_START("validate heap");
|
||||
MemoryManager::validate();
|
||||
PROFILER_STOP("validate heap");
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Clock::update();
|
||||
|
||||
wasPaused = false;
|
||||
|
||||
// if our parent's pid has changed, we tell our caller it should exit
|
||||
if (getppid() != ppid)
|
||||
{
|
||||
WARNING(true, ("Parent process exited!"));
|
||||
// reset the parent process id, so we don't keep spamming warnings for processes that don't exit because of this
|
||||
ppid = getppid();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Formats a message error using GetLastError() and FormatMessge().
|
||||
*
|
||||
* The buffer returned from this function is dynamically allocated to prevent
|
||||
* issues with this routine being called from multiple threads. The caller
|
||||
* must delete the buffer when it is done.
|
||||
*
|
||||
* @return A dynamically allocated buffer containing the error message
|
||||
*/
|
||||
|
||||
char *Os::getLastError(void)
|
||||
{
|
||||
return DuplicateString(strerror(errno));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool Os::getAbsolutePath(const char *relativePath, char *absolutePath, int absolutePathBufferSize)
|
||||
{
|
||||
// realpath sucks and could cause a buffer overrun. however, it's better than writing it ourselves for now.
|
||||
char *result = realpath(relativePath, absolutePath);
|
||||
if (!result)
|
||||
return false;
|
||||
|
||||
FATAL(istrlen(absolutePath)+1 > absolutePathBufferSize, ("buffer overrun"));
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Get the actual system time, in seconds since the epoch.
|
||||
*
|
||||
* Do not use this for most game systems, since it does not take into account
|
||||
* clock sku, game loop times, etc.
|
||||
*/
|
||||
time_t Os::getRealSystemTime(void)
|
||||
{
|
||||
return time(0);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Convert a time in seconds since the epoch to GMT.
|
||||
*
|
||||
*/
|
||||
|
||||
void Os::convertTimeToGMT(const time_t &time, tm &zulu)
|
||||
{
|
||||
zulu=*gmtime(&time); // gmtime uses a single static tm structure. Yuck!
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Convert a tm structure to the time in seconds since the epoch.
|
||||
*
|
||||
*/
|
||||
|
||||
time_t Os::convertGMTToTime(const tm &zulu)
|
||||
{
|
||||
return mktime(const_cast<tm*>(&zulu));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Get a unique identifier for this thread.
|
||||
*
|
||||
* @return A unique identifier for this thread.
|
||||
*/
|
||||
|
||||
Os::ThreadId Os::getThreadId()
|
||||
{
|
||||
return pthread_self();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Assign the given thread a reasonable name (only works for MSDev 6.0 debugger)
|
||||
* Since this is Linux-specific, make sure this fuction does nothing
|
||||
*
|
||||
*/
|
||||
|
||||
void Os::setThreadName(DWORD threadID, const char* threadName)
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Cause the current thread to sleep for a period of time. If the period is
|
||||
* zero, the current thread yields it's timeslice.
|
||||
*/
|
||||
|
||||
void Os::sleep(int ms)
|
||||
{
|
||||
if (ms == 0)
|
||||
{
|
||||
sched_yield();
|
||||
}
|
||||
else
|
||||
{
|
||||
usleep(ms * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Copy text to the system clipboard.
|
||||
*
|
||||
* This routine can be used if the application wants to make some data easily available for pasting (like crash call stacks).
|
||||
*/
|
||||
|
||||
bool Os::copyTextToClipboard(const char *text)
|
||||
{
|
||||
UNREF(text);
|
||||
return false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
Os::OsPID_t Os::getProcessId()
|
||||
{
|
||||
return getpid();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void Os::setProgramName(const char * name)
|
||||
{
|
||||
strncpy(programName, name, Os::PROGRAM_NAME_SIZE);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool Os::isFocused()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
@@ -1,264 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Os.h
|
||||
// jeff grills
|
||||
//
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef OS_H
|
||||
#define OS_H
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
// ======================================================================
|
||||
|
||||
struct DebugMenuEntry;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class Os
|
||||
{
|
||||
public:
|
||||
|
||||
typedef pthread_t ThreadId;
|
||||
typedef pid_t OsPID_t;
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_PATH_LENGTH = 512
|
||||
};
|
||||
|
||||
typedef void (*QueueCharacterHookFunction)(int keyboard, int character);
|
||||
typedef void (*SetSystemMouseCursorPositionHookFunction)(int x, int y);
|
||||
typedef void (*QueueKeyDownHookFunction)(int keyboard, int character);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
Os(void);
|
||||
Os(const Os &);
|
||||
Os &operator =(const Os &);
|
||||
|
||||
enum
|
||||
{
|
||||
PROGRAM_NAME_SIZE = 512
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
static void remove(void);
|
||||
|
||||
static void installCommon(void);
|
||||
|
||||
private:
|
||||
|
||||
static bool installed;
|
||||
static bool runInBackground;
|
||||
static int numberOfUpdates;
|
||||
static int menuValue;
|
||||
static DebugMenuEntry *debugMenuGame;
|
||||
static bool paused;
|
||||
static bool wasPaused;
|
||||
static bool gameOver;
|
||||
static bool shouldReturnFromAbort;
|
||||
static bool wantPopupDebugMenu;
|
||||
static char programName[PROGRAM_NAME_SIZE];
|
||||
static char *shortProgramName;
|
||||
static pthread_t mainThreadId;
|
||||
static bool threadDied;
|
||||
static bool isMp;
|
||||
static int processorCount;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
static void install(void);
|
||||
|
||||
static bool isGameOver(void);
|
||||
static bool isMainThread(void);
|
||||
static bool wasApplicationPaused(void);
|
||||
|
||||
static bool update(void);
|
||||
|
||||
static void returnFromAbort(void);
|
||||
static void abort(void);
|
||||
|
||||
static void requestPopupDebugMenu();
|
||||
|
||||
static bool createDirectories (const char *dirname);
|
||||
|
||||
static bool writeFile(const char *fileName, const void *data, int length);
|
||||
|
||||
static int getNumberOfUpdates(void);
|
||||
|
||||
static char *getLastError(void);
|
||||
|
||||
static void setThreadName(DWORD threadID, const char* name);
|
||||
static ThreadId getThreadId();
|
||||
|
||||
static const char *getProgramName(void);
|
||||
static const char *getShortProgramName(void);
|
||||
static void setProgramName(const char * name);
|
||||
|
||||
static bool getAbsolutePath(const char *relativePath, char *absolutePath, int absolutePathBufferSize);
|
||||
|
||||
static void sleep(int ms);
|
||||
|
||||
static time_t getRealSystemTime(void);
|
||||
static void convertTimeToGMT(const time_t &time, tm &zulu);
|
||||
static time_t convertGMTToTime(const tm &zulu);
|
||||
|
||||
static bool isMultiprocessor();
|
||||
static int getProcessorCount();
|
||||
|
||||
static bool copyTextToClipboard(const char *text);
|
||||
|
||||
static bool wasFocusLost();
|
||||
static void setQueueCharacterHookFunction(QueueCharacterHookFunction queueCharacterHookFunction);
|
||||
static void setSetSystemMouseCursorPositionHookFunction(SetSystemMouseCursorPositionHookFunction setSystemMouseCursorPositionHookFunction);
|
||||
static OsPID_t getProcessId();
|
||||
static bool isFocused();
|
||||
|
||||
static void setQueueKeyDownHookFunction(QueueKeyDownHookFunction queueKeyDownHookFunction);
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Return the full name of the running executable.
|
||||
*
|
||||
* The program name will include the path as well.
|
||||
*
|
||||
* @return The full name of the running executable
|
||||
* @see Os::getShortProgramName()
|
||||
*/
|
||||
|
||||
inline const char *Os::getProgramName(void)
|
||||
{
|
||||
return programName;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Return the short name of the running executable.
|
||||
*
|
||||
* The program name will not include the path, but will just be the file name.
|
||||
*
|
||||
* @return The short name of the running executable
|
||||
* @see Os::getProgramName()
|
||||
*/
|
||||
|
||||
inline const char *Os::getShortProgramName(void)
|
||||
{
|
||||
return shortProgramName;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Cause Os::abort() to return instead of abort the process.
|
||||
*
|
||||
* This routine should not be called directly by users.
|
||||
*
|
||||
* This routine is provided so that structured exception handling can catch
|
||||
* an exception, call Fatal to run the ExitChain, and rethrow the exception
|
||||
* so that the debugger will catch it.
|
||||
*/
|
||||
|
||||
inline void Os::returnFromAbort(void)
|
||||
{
|
||||
shouldReturnFromAbort = true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Check if the Os knows the game needs to shut down.
|
||||
*
|
||||
* The Os can decide that the game need to end for a number of reasons,
|
||||
* including closing the application or shutting the machine down.
|
||||
*
|
||||
* @return True if the game should quit, otherwise false
|
||||
*/
|
||||
|
||||
inline bool Os::isGameOver(void)
|
||||
{
|
||||
return gameOver;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Return the number of updates that the have occurred.
|
||||
*
|
||||
* @return This value is updated during the Os::update() routine.
|
||||
*/
|
||||
|
||||
inline int Os::getNumberOfUpdates(void)
|
||||
{
|
||||
return numberOfUpdates;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Indicate whether or not the application was paused.
|
||||
*
|
||||
* @return True if the application was in the background (paused), otherwise false
|
||||
*/
|
||||
|
||||
inline bool Os::wasApplicationPaused(void)
|
||||
{
|
||||
return wasPaused;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Return a flag indicating whether we are running a multiprocessor machine or not.
|
||||
*
|
||||
* @return True if the machine has more than one processor, false if not.
|
||||
*/
|
||||
|
||||
inline bool Os::isMultiprocessor(void)
|
||||
{
|
||||
return isMp;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Return the number of processors.
|
||||
*
|
||||
* @return The number of processors in the machine.
|
||||
*/
|
||||
|
||||
inline int Os::getProcessorCount(void)
|
||||
{
|
||||
return processorCount;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline bool Os::wasFocusLost()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline void Os::setQueueCharacterHookFunction(QueueCharacterHookFunction queueCharacterHookFunction)
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline void Os::setSetSystemMouseCursorPositionHookFunction(SetSystemMouseCursorPositionHookFunction setSystemMouseCursorPositionHookFunction)
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline void Os::setQueueKeyDownHookFunction(QueueKeyDownHookFunction)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
#endif
|
||||
@@ -1,161 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// PerThreadData.cpp
|
||||
// jeff grills
|
||||
//
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/PerThreadData.h"
|
||||
|
||||
#include "sharedSynchronization/Gate.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
pthread_key_t PerThreadData::slot;
|
||||
bool PerThreadData::slotCreated=false;
|
||||
|
||||
// ======================================================================
|
||||
// Install the per-thread-data subsystem
|
||||
//
|
||||
// Remarks:
|
||||
//
|
||||
// This routine will install the per-thread-data subsystem that is required for several
|
||||
// other subsystems in the engine. It should be called from the primary thread before
|
||||
// any other threads have been created. It will also call threadInstall() for the
|
||||
// primary thread.
|
||||
//
|
||||
// See Also:
|
||||
//
|
||||
// PerThreadData::remove()
|
||||
|
||||
void PerThreadData::install(void)
|
||||
{
|
||||
if (pthread_key_create(&slot, 0)!=0)
|
||||
{
|
||||
FATAL(true, ("pthread_key_create failed"));
|
||||
}
|
||||
slotCreated=true;
|
||||
|
||||
threadInstall();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Remove the per-thread-subsystem.
|
||||
*
|
||||
* This routine should be called by the primary thread after all other threads have
|
||||
* terminated, and no other uses of per-thread-data will occur.
|
||||
*
|
||||
* @see PerThreadData::install()
|
||||
*/
|
||||
|
||||
void PerThreadData::remove(void)
|
||||
{
|
||||
threadRemove();
|
||||
|
||||
if (pthread_key_delete(slot)!=0)
|
||||
{
|
||||
FATAL(true, ("pthread_key_delete failed"));
|
||||
}
|
||||
|
||||
slotCreated=false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Get access to the per-thread-data.
|
||||
*
|
||||
* This routine will verify the per-thread-data subsystem has been installed and the
|
||||
* threadInstall() function has been called for the current thread.
|
||||
*
|
||||
* @return A pointer to the per-thread-data.
|
||||
*/
|
||||
|
||||
PerThreadData::Data *PerThreadData::getData(bool allowReturnNull)
|
||||
{
|
||||
UNREF(allowReturnNull);
|
||||
|
||||
if (!slotCreated)
|
||||
{
|
||||
DEBUG_FATAL(true && !allowReturnNull, ("not installed"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Data * const data = reinterpret_cast<Data *>(pthread_getspecific(slot));
|
||||
DEBUG_FATAL(!data && !allowReturnNull, ("not installed for this thread"));
|
||||
return data;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Create the per-thread-data for a new thread.
|
||||
*
|
||||
* This routine should be called in a thread before the first usage of per-thread-data.
|
||||
*
|
||||
* If the client is calling this function on a thread that existed before the engine was
|
||||
* installed, the client should set isNewThread to false. Setting isNewThread to false
|
||||
* prevents the function from validating that the thread's TLS is NULL. For threads existing
|
||||
* before the engine is installed, the TLS data for the thread is undefined.
|
||||
*
|
||||
* @param isNewThread [IN] true if the thread was created after the engine was installed, false otherwise
|
||||
* @see PerThreadData::threadRemove()
|
||||
*/
|
||||
|
||||
void PerThreadData::threadInstall(bool isNewThread)
|
||||
{
|
||||
UNREF(isNewThread);
|
||||
|
||||
DEBUG_FATAL(!slotCreated, ("not installed"));
|
||||
|
||||
// only check for already-set data if this is supposed to be a new thread
|
||||
DEBUG_FATAL(isNewThread && pthread_getspecific(slot), ("already installed for this thread"));
|
||||
|
||||
// create the data
|
||||
Data * const data = new Data;
|
||||
|
||||
// initialize the data
|
||||
memset(data, 0, sizeof(*data));
|
||||
|
||||
//create the event for file streaming reads
|
||||
data->readGate = new Gate(false);
|
||||
|
||||
// set the data into the thread slot
|
||||
const BOOL result = pthread_setspecific(slot, data);
|
||||
UNREF(result);
|
||||
DEBUG_FATAL(result, ("pthread_setspecific failed")); //NB: unlike Windows, returns 0 on success.
|
||||
} //lint !e429 // Warning -- Custodial pointer 'data' has not been freed or returned) // stored int thread-local-storage
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Destroythe per-thread-data for a terminating thread.
|
||||
*
|
||||
* This routine should be called in a thread after the last usage of per-thread-data.
|
||||
*
|
||||
* @see PerThreadData::threadInstall()
|
||||
*/
|
||||
|
||||
void PerThreadData::threadRemove(void)
|
||||
{
|
||||
DEBUG_FATAL(!slotCreated, ("not installed"));
|
||||
DEBUG_FATAL(!pthread_getspecific(slot), ("thread not installed"));
|
||||
|
||||
// get the data
|
||||
Data *data = getData();
|
||||
|
||||
//close the event used for file streaming reads
|
||||
delete data->readGate;
|
||||
data->readGate = NULL;
|
||||
|
||||
// wipe the data in the thread slot
|
||||
const BOOL result2 = pthread_setspecific(slot, NULL);
|
||||
UNREF(result2);
|
||||
DEBUG_FATAL(result2, ("TlsSetValue failed")); //NB: unlike Windows, returns 0 on success.
|
||||
|
||||
// free the memory
|
||||
delete data;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -1,232 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// PerThreadData.h
|
||||
// jeff grills
|
||||
//
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef PER_THREAD_DATA_H
|
||||
#define PER_THREAD_DATA_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#include "../../../../../../engine/shared/library/sharedFoundation/include/public/sharedFoundation/ExitChain.h"
|
||||
|
||||
class Gate;
|
||||
|
||||
// ======================================================================
|
||||
/**
|
||||
* Provide thread local storage functionality.
|
||||
*
|
||||
* This class' purpose is to allow each thread to maintain some storage that is local and private to each thread.
|
||||
* The system must be installed before use. Each thread that may use per-thread-data will also need to call the
|
||||
* threadInstall() routine after creation and threadRemove() just before termination of the thread.
|
||||
*/
|
||||
class PerThreadData
|
||||
{
|
||||
private:
|
||||
|
||||
struct Data
|
||||
{
|
||||
bool exitChainRunning;
|
||||
bool exitChainFataling;
|
||||
ExitChain::Entry *exitChainFirstEntry;
|
||||
|
||||
int debugPrintFlags;
|
||||
|
||||
Gate *readGate;
|
||||
};
|
||||
|
||||
static pthread_key_t slot;
|
||||
static bool slotCreated;
|
||||
|
||||
private:
|
||||
|
||||
static Data *getData(bool allowReturnNull=false);
|
||||
|
||||
private:
|
||||
|
||||
PerThreadData(void);
|
||||
PerThreadData(const PerThreadData &);
|
||||
PerThreadData &operator =(const PerThreadData &);
|
||||
|
||||
public:
|
||||
|
||||
static void install(void);
|
||||
static void remove(void);
|
||||
|
||||
static void threadInstall(bool isNewThread = true);
|
||||
static void threadRemove(void);
|
||||
|
||||
static bool isThreadInstalled(void);
|
||||
|
||||
static bool getExitChainRunning(void);
|
||||
static void setExitChainRunning(bool newValue);
|
||||
|
||||
static bool getExitChainFataling(void);
|
||||
static void setExitChainFataling(bool newValue);
|
||||
|
||||
static ExitChain::Entry *getExitChainFirstEntry(void);
|
||||
static void setExitChainFirstEntry(ExitChain::Entry *newValue);
|
||||
|
||||
static int getDebugPrintFlags(void);
|
||||
static void setDebugPrintFlags(int newValue);
|
||||
|
||||
static Gate *getFileStreamerReadGate(void);
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
/**
|
||||
* Determine if the per-thread-data is available for this thread
|
||||
*
|
||||
* Return value:
|
||||
*
|
||||
* True if the per-thread-data is installed correctly, false otherwise
|
||||
*
|
||||
* Remarks:
|
||||
*
|
||||
* This routine is not intended for general use; it should only be used by the ExitChain class.
|
||||
*
|
||||
* -TRF- looks like Win98 does not zero out a new TLS slot for
|
||||
* threads existing at the time of slot creation. Thus, if you build a
|
||||
* plugin that only initializes the engine the first time it is
|
||||
* used, and other threads already exist in the app, those threads
|
||||
* will contain bogus non-null data in the TLS slot. If the plugin really
|
||||
* wants to do lazy initialization of the engine, it will need
|
||||
* to handle calling PerThreadData::threadInstall() for all existing threads
|
||||
* (except the thread that initialized the engine, which already
|
||||
* has its PerThreadData::threadInstall() called).
|
||||
*/
|
||||
|
||||
inline bool PerThreadData::isThreadInstalled(void)
|
||||
{
|
||||
return (getData(true) != NULL);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Get the exit chain running flag value.
|
||||
*
|
||||
* This routine is not intended for general use; it should only be used by the ExitChain class.
|
||||
*
|
||||
* @return True if the exit chain is running, false otherwise.
|
||||
* @see ExitChain::isRunning()
|
||||
*/
|
||||
|
||||
inline bool PerThreadData::getExitChainRunning(void)
|
||||
{
|
||||
return getData()->exitChainRunning;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Set the exit chain running flag value.
|
||||
*
|
||||
* This routine is not intended for general use; it should only be used by the ExitChain class.
|
||||
*
|
||||
* @param newValue New value for the exit chain running flag
|
||||
*/
|
||||
|
||||
inline void PerThreadData::setExitChainRunning(bool newValue)
|
||||
{
|
||||
getData()->exitChainRunning = newValue;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Get the exit chain fataling flag value.
|
||||
*
|
||||
* This routine is not intended for general use; it should only be used by the ExitChain class.
|
||||
*
|
||||
* @return True if the exit chain is fataling, false otherwise.
|
||||
* @see ExitChain::isFataling()
|
||||
*/
|
||||
|
||||
inline bool PerThreadData::getExitChainFataling(void)
|
||||
{
|
||||
return getData()->exitChainFataling;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Set the exit chain fataling flag value.
|
||||
*
|
||||
* This routine is not intended for general use; it should only be used by the ExitChain class.
|
||||
*
|
||||
* @param newValue New value for the exit chain fataling flag
|
||||
*/
|
||||
|
||||
inline void PerThreadData::setExitChainFataling(bool newValue)
|
||||
{
|
||||
getData()->exitChainFataling = newValue;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Get the first entry for the exit chain.
|
||||
*
|
||||
* This routine is not intended for general use; it should only be used by the ExitChain class.
|
||||
* This routine may return NULL.
|
||||
*
|
||||
* @return Pointer to the first entry on the exit chain
|
||||
* @see ExitChain::isFataling()
|
||||
*/
|
||||
|
||||
inline ExitChain::Entry *PerThreadData::getExitChainFirstEntry(void)
|
||||
{
|
||||
return getData()->exitChainFirstEntry;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Set the exit chain fataling flag value.
|
||||
*
|
||||
* This routine is not intended for general use; it should only be used by the ExitChain class.
|
||||
* The parameter to this routine may be NULL.
|
||||
*
|
||||
* @param newValue New value for the exit chain first entry
|
||||
*/
|
||||
|
||||
inline void PerThreadData::setExitChainFirstEntry(ExitChain::Entry *newValue)
|
||||
{
|
||||
getData()->exitChainFirstEntry = newValue;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Get the debug print flags.
|
||||
*
|
||||
* This routine is not intended for general use; it should only be used by the DebugPrint functions.
|
||||
*
|
||||
* @return Current value of the debug print flags
|
||||
*/
|
||||
|
||||
inline int PerThreadData::getDebugPrintFlags(void)
|
||||
{
|
||||
return getData()->debugPrintFlags;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Set the debug print flags value.
|
||||
*
|
||||
* This routine is not intended for general use; it should only be used by the DebugPrint functions.
|
||||
*/
|
||||
|
||||
inline void PerThreadData::setDebugPrintFlags(int newValue)
|
||||
{
|
||||
getData()->debugPrintFlags = newValue;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline Gate *PerThreadData::getFileStreamerReadGate(void)
|
||||
{
|
||||
return getData()->readGate;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -1,273 +0,0 @@
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/PlatformGlue.h"
|
||||
#include <ctime>
|
||||
|
||||
|
||||
real abs(real x)
|
||||
{
|
||||
return fabs(x);
|
||||
}
|
||||
|
||||
int _stricmp(const char* string1, const char* string2)
|
||||
{
|
||||
int first, second;
|
||||
|
||||
do
|
||||
{
|
||||
first = toupper(*string1);
|
||||
second = toupper(*string2);
|
||||
string1++;
|
||||
string2++;
|
||||
} while (first && first==second);
|
||||
|
||||
return (first - second);
|
||||
}
|
||||
|
||||
char* _itoa(int value, char* stringOut, int radix)
|
||||
{
|
||||
DEBUG_FATAL((radix != 10), ("itoa only supprts base 10"));
|
||||
sprintf(stringOut, "%d", value);
|
||||
return stringOut;
|
||||
}
|
||||
|
||||
bool QueryPerformanceCounter(__int64* time)
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
*time = static_cast<LARGE_INTEGER>(tv.tv_sec);
|
||||
*time = (*time * 1000000) + static_cast<LARGE_INTEGER>(tv.tv_usec);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool QueryPerformanceFrequency(__int64 *freq)
|
||||
{
|
||||
*freq = CLOCKS_PER_SEC;
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
void Sleep(DWORD msecs)
|
||||
{
|
||||
//Sleep takes a time to sleep in milliseconds.
|
||||
usleep(msecs*1000); //usleep works with microseconds
|
||||
}
|
||||
|
||||
int GetLastError()
|
||||
{
|
||||
return errno;
|
||||
}
|
||||
|
||||
void OutputDebugString(const char* stringOut)
|
||||
{
|
||||
fprintf(stderr,"%s",stringOut);
|
||||
}
|
||||
|
||||
|
||||
//File Support
|
||||
BOOL WriteFile(FILE* hFile, const void* lpBuffer, DWORD numBytesToWrite, DWORD* numBytesWritten, void* unsup)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if(unsup)
|
||||
return FALSE; //Windows doesn't support this overrlap buffer
|
||||
|
||||
retval = fwrite(lpBuffer, sizeof(char), numBytesToWrite, hFile);
|
||||
*numBytesWritten = retval;
|
||||
return (retval < 0) ? FALSE : TRUE;
|
||||
|
||||
}
|
||||
|
||||
BOOL ReadFile(FILE* hFile, void* lpBuffer, DWORD numBytesToRead, DWORD* numBytesRead, void* unsup)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if(unsup)
|
||||
return FALSE; //Windows doesn't support this overrlap buffer
|
||||
|
||||
retval = fread(lpBuffer, sizeof(char), numBytesToRead, hFile);
|
||||
*numBytesRead = retval;
|
||||
return (retval <= 0) ? FALSE : TRUE;
|
||||
|
||||
}
|
||||
|
||||
DWORD SetFilePointer(FILE* hFile, long lDistanceToMove, long* lpDistanceToMoveHigh, DWORD dwMoveMethod)
|
||||
{
|
||||
//Mimics the Win32 function to set the position of a file pointer. return -1 on failure else current position.
|
||||
|
||||
int retval;
|
||||
retval = fseek(hFile, lDistanceToMove, dwMoveMethod);
|
||||
|
||||
return (retval == 0) ? ftell(hFile) : -1;
|
||||
}
|
||||
|
||||
//TODO Consider using a call to open() instead of fopen() to get a better mapping of parameters to Win32
|
||||
FILE* CreateFile(const char* fileName, DWORD access, DWORD shareMode, void* unsupA, DWORD creationDisposition, DWORD flagsAndAttributes, FILE* unsupB)
|
||||
{
|
||||
FILE* retval = 0;
|
||||
|
||||
DEBUG_FATAL(flagsAndAttributes != FILE_ATTRIBUTE_NORMAL, ("Unsupported File mode call to CreateFile()"));
|
||||
DEBUG_FATAL(unsupB != NULL, ("Unsupported File mode call to CreateFile()"));
|
||||
//DEBUG_FATAL(shareMode != 0, ("Unsupported File mode call to CreateFile()"));
|
||||
DEBUG_FATAL(unsupA != 0, ("Unsupported File mode call to CreateFile()"));
|
||||
|
||||
switch(creationDisposition)
|
||||
{
|
||||
case CREATE_NEW:
|
||||
retval = fopen(fileName, "r");
|
||||
if (retval)
|
||||
{
|
||||
fclose(retval);
|
||||
retval = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
fclose(retval);
|
||||
retval = fopen(fileName, "w");
|
||||
}
|
||||
break;
|
||||
|
||||
case CREATE_ALWAYS:
|
||||
retval = fopen(fileName, "w");
|
||||
break;
|
||||
|
||||
case OPEN_EXISTING:
|
||||
retval = fopen(fileName, "r");
|
||||
if ((access & GENERIC_WRITE) && retval)
|
||||
{
|
||||
fclose(retval);
|
||||
retval = fopen(fileName, "a");
|
||||
rewind(retval);
|
||||
}
|
||||
break;
|
||||
|
||||
case OPEN_ALWAYS:
|
||||
if (access & GENERIC_WRITE)
|
||||
{
|
||||
retval = fopen(fileName, "a");
|
||||
rewind(retval);
|
||||
}
|
||||
else
|
||||
{
|
||||
retval = fopen(fileName, "r");
|
||||
}
|
||||
break;
|
||||
|
||||
case TRUNCATE_EXISTING:
|
||||
DEBUG_FATAL(!(access & GENERIC_WRITE),("Must open truncate file with write access"));
|
||||
retval = fopen(fileName, "w");
|
||||
break;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
BOOL CloseHandle(FILE* hFile)
|
||||
{
|
||||
int retval = fclose(hFile);
|
||||
return (retval == 0) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
//TODO There must be a more elegant UNIX command to get file size...fstat() needs filename
|
||||
DWORD GetFileSize(FILE* hFile, DWORD* lpHighSize)
|
||||
{
|
||||
long int curPos;
|
||||
DWORD endPos;
|
||||
curPos = ftell(hFile);
|
||||
fseek(hFile, 0, SEEK_END);
|
||||
endPos = ftell(hFile);
|
||||
fseek(hFile, curPos, SEEK_SET);
|
||||
return endPos;
|
||||
|
||||
#if 0
|
||||
//This is what I want to do, but I have no file des number
|
||||
struct stat buf;
|
||||
fstat(hFile, &buf);
|
||||
return buf->st_size;
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOL FileExists(const char* filename)
|
||||
{
|
||||
BOOL retval = false;
|
||||
|
||||
struct stat info;
|
||||
if (stat(filename, &info) == 0)
|
||||
{
|
||||
if (S_ISREG(info.st_mode))
|
||||
retval = true;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Memory Functions
|
||||
|
||||
void* VirtualAlloc(void* location, DWORD size, DWORD flAllocationType, DWORD flProtect)
|
||||
{
|
||||
if (location)
|
||||
return location;
|
||||
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
BOOL VirtualFree(void* location, DWORD size, DWORD freeType)
|
||||
{
|
||||
free(location);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL VirtualProtect(void* location, DWORD size, DWORD newProtect, DWORD* oldProect)
|
||||
{
|
||||
//Unused. Function stub for compatibility
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL IsBadReadPtr(const void* location, unsigned int size)
|
||||
{
|
||||
//unused
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void MessageBox (void* unused, const char* message, const char* unused2, int flags)
|
||||
{
|
||||
OutputDebugString(message);
|
||||
}
|
||||
|
||||
char *ConvertCommandLine(int argc, char ** argv)
|
||||
{
|
||||
static char buffer[2048];
|
||||
|
||||
int totalSize=0;
|
||||
for (int i=0; i<argc; ++i)
|
||||
{
|
||||
totalSize+=strlen(argv[i])+1;
|
||||
}
|
||||
|
||||
if(totalSize>1023)
|
||||
{
|
||||
int argIndex = 0;
|
||||
fprintf(stderr, "Exceeded command line args length of %d. Total size is %d\n", sizeof(buffer), totalSize);
|
||||
for(argIndex = 0; argIndex < argc; ++argIndex)
|
||||
{
|
||||
fprintf(stderr, "argv[%d]=\"%s\"\n", argIndex, argv[argIndex]);
|
||||
}
|
||||
FATAL(true,("Command line exceeds maximum length."));
|
||||
}
|
||||
|
||||
buffer[0]='\0';
|
||||
|
||||
for (int i=0; i<argc; ++i)
|
||||
{
|
||||
strcat(buffer,argv[i]);
|
||||
if (i!=argc-1)
|
||||
{
|
||||
strcat(buffer," ");
|
||||
}
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
#ifndef INCLUDED_MISC_H
|
||||
#define INCLUDED_MISC_H
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
|
||||
typedef unsigned short int WORD;
|
||||
typedef unsigned long int DWORD;
|
||||
typedef bool BOOL;
|
||||
typedef long long __int64; //lint !e13 !e19 // Error: 13 (Bad type), Error: 19 (Useless declaration) // -TRF- Lint preprocessor discrepency, @todo look into this.
|
||||
typedef __int64 LARGE_INTEGER;
|
||||
|
||||
const BOOL FALSE = 0;
|
||||
const BOOL TRUE = 1;
|
||||
|
||||
|
||||
float abs(float x);
|
||||
int _stricmp(const char* string1, const char* string2);
|
||||
|
||||
//String to numeric conversions
|
||||
char* _itoa(int value, char* stringOut, int radix);
|
||||
|
||||
//Format specifier for non-portable printf
|
||||
#define UINT64_FORMAT_SPECIFIER "%llu"
|
||||
#define INT64_FORMAT_SPECIFIER "%lli"
|
||||
|
||||
//Constant definition macro for 64 bit values
|
||||
#define UINT64_LITERAL(a) a ## ull
|
||||
#define INT64_LITERAL(a) a ## ll
|
||||
|
||||
bool QueryPerformanceCounter(__int64 *time);
|
||||
bool QueryPerformanceFrequency(__int64 *freq);
|
||||
void Sleep(DWORD msecs);
|
||||
int GetLastError();
|
||||
void OutputDebugString(const char* stringOut);
|
||||
|
||||
//File Support
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
typedef FILE* HANDLE;
|
||||
|
||||
#define INVALID_HANDLE_VALUE NULL //Have to use a #define because this may be a FILE*
|
||||
|
||||
|
||||
const int GENERIC_READ = 1 << 0;
|
||||
const int GENERIC_WRITE = 1 << 1;
|
||||
|
||||
const int CREATE_NEW = 1;
|
||||
const int CREATE_ALWAYS = 2;
|
||||
const int OPEN_EXISTING = 3;
|
||||
const int OPEN_ALWAYS = 4;
|
||||
const int TRUNCATE_EXISTING = 5;
|
||||
|
||||
const DWORD FILE_ATTRIBUTE_NORMAL = 1;
|
||||
|
||||
const int FILE_CURRENT = SEEK_CUR;
|
||||
const int FILE_BEGIN = SEEK_SET;
|
||||
const int FILE_END = SEEK_END;
|
||||
|
||||
const int FILE_SHARE_READ = 1;
|
||||
|
||||
BOOL WriteFile(FILE* hFile, const void* lpBuffer, DWORD numBytesToWrite, DWORD* numBytesWritten, void* unsup=NULL);
|
||||
BOOL ReadFile(FILE* hFile, void* lpBuffer, DWORD numBytesToWrite, DWORD* numBytesRead, void* unsup=NULL);
|
||||
DWORD SetFilePointer(FILE* hFile, long lDistanceToMove, long* lpDistanceToMoveHigh, DWORD dwMoveMethod);
|
||||
FILE* CreateFile(const char* fileName, DWORD access, DWORD shareMode, void* unsupA, DWORD creationDisposition, DWORD flagsAndAttributes, FILE* unsup2);
|
||||
BOOL CloseHandle(FILE* hFile);
|
||||
DWORD GetFileSize(FILE* hFile, DWORD* lpHighSize);
|
||||
BOOL FileExists(const char* fileName);
|
||||
|
||||
|
||||
//Memory Support
|
||||
|
||||
const int MEM_RESERVE = 0;
|
||||
const int MEM_COMMIT = 1;
|
||||
const int PAGE_READWRITE = 0;
|
||||
const int MEM_RELEASE = 0;
|
||||
const int PAGE_NOACCESS = 0;
|
||||
|
||||
void* VirtualAlloc(void* location, DWORD size, DWORD flAllocationType, DWORD flProtect);
|
||||
BOOL VirtualFree(void* location, DWORD size, DWORD freeType);
|
||||
BOOL VirtualProtect(void* location, DWORD size, DWORD newProtect, DWORD* oldProect);
|
||||
BOOL IsBadReadPtr(const void* location, unsigned int size);
|
||||
|
||||
//Misc output stuff
|
||||
|
||||
const int MB_OK = 0;
|
||||
const int MB_ICONEXCLAMATION = 1;
|
||||
void MessageBox (void* unused, const char* message, const char* unused2, int flags);
|
||||
char *ConvertCommandLine(int argc, char ** argv);
|
||||
|
||||
//String functions
|
||||
#define _vsnprintf vsnprintf
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
inline int _strnicmp (const char * a, const char * b, size_t count)
|
||||
{
|
||||
return ::strncasecmp (a, b, count);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
inline int _open(const char *filename, int oflag) { return open(filename, oflag); }
|
||||
inline int _open(const char *filename, int oflag, mode_t pmode) { return open(filename, oflag, pmode); }
|
||||
inline int _creat(const char *filename, mode_t pmode) { return creat(filename, pmode); }
|
||||
inline int _close(int fd) { return close(fd); }
|
||||
inline int _write(int fd, const void *buffer, unsigned int count) { return write(fd, buffer, count); }
|
||||
inline int _dup(int fd) { return dup(fd); }
|
||||
inline int _dup2(int oldfd, int newfd) { return dup2(oldfd, newfd); }
|
||||
inline long _lseek(int fd, long offset, int origin) { return lseek(fd, offset, origin); }
|
||||
inline int _read(int fd, void *buffer, unsigned int count) { return read(fd, buffer, count); }
|
||||
inline long _tell(int fd) { return _lseek(fd,0,SEEK_CUR); }
|
||||
inline int _umask(int pmode) { return umask(pmode); }
|
||||
inline int _unlink(const char *pathname) { return unlink(pathname); }
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
#endif //INCLUDED_MISC_H
|
||||
@@ -1,185 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// SetupSharedFoundation.cpp
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
// copyright 2001 - 2002 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/SetupSharedFoundation.h"
|
||||
|
||||
#include "sharedDebug/ConfigSharedDebugLinux.h"
|
||||
#include "sharedDebug/DebugMonitor.h"
|
||||
#include "sharedDebug/Profiler.h"
|
||||
#include "sharedFoundation/Clock.h"
|
||||
#include "sharedFoundation/CommandLine.h"
|
||||
#include "sharedFoundation/ConfigFile.h"
|
||||
#include "sharedFoundation/ConfigSharedFoundation.h"
|
||||
#include "sharedFoundation/CrcLowerString.h"
|
||||
#include "sharedFoundation/ExitChain.h"
|
||||
#include "sharedFoundation/Os.h"
|
||||
#include "sharedFoundation/PerThreadData.h"
|
||||
#include "sharedFoundation/StaticCallbackEntry.h"
|
||||
|
||||
#include <ctime>
|
||||
#include <math.h>
|
||||
|
||||
// ======================================================================
|
||||
/**
|
||||
* Install the engine.
|
||||
*
|
||||
* The settings in the Data structure will determine which subsystems
|
||||
* get initialized.
|
||||
*/
|
||||
|
||||
void SetupSharedFoundation::install(const Data &data)
|
||||
{
|
||||
// and get the command line stuff in quick so we can make decisions based on the command line settings
|
||||
CommandLine::install();
|
||||
ConfigFile::install();
|
||||
|
||||
if (data.lpCmdLine)
|
||||
CommandLine::absorbString(data.lpCmdLine);
|
||||
if (data.argc)
|
||||
CommandLine::absorbStrings(const_cast<const char**>(data.argv+1), data.argc-1);
|
||||
|
||||
#if 0
|
||||
//currently there's a problem that we cannot override the defaults here.
|
||||
if (data.configFile)
|
||||
IGNORE_RETURN(ConfigFile::loadFile(data.configFile));
|
||||
#endif
|
||||
|
||||
// get the post command-line text for the ConfigFile (key-value pairs)
|
||||
const char *configString = CommandLine::getPostCommandLineString();
|
||||
if (configString)
|
||||
ConfigFile::loadFromCommandLine(configString);
|
||||
|
||||
//@todo there is a lot of stuff in win32 setup not here...like exitchain
|
||||
Profiler::registerDebugFlags();
|
||||
#if _DEBUG
|
||||
MemoryManager::registerDebugFlags();
|
||||
#endif//_DEBUG
|
||||
|
||||
// Setup Linux DebugMonitor support.
|
||||
// @todo fix this dependency: DebugMonitor really should be moved into Foundation the way things currently are. TRF is following the existing win32 setup.
|
||||
#ifdef _DEBUG
|
||||
ConfigSharedDebugLinux::install();
|
||||
DebugMonitor::install();
|
||||
#endif
|
||||
|
||||
// setup the engine configuration
|
||||
ConfigSharedFoundation::Defaults defaults;
|
||||
defaults.frameRateLimit = data.frameRateLimit;
|
||||
ConfigSharedFoundation::install(defaults);
|
||||
SetWarningStrictFatal(ConfigFile::getKeyBool("SharedDebug", "strict", false));
|
||||
Report::install();
|
||||
Clock::install(data.runInBackground, false);
|
||||
|
||||
PersistentCrcString::install();
|
||||
CrcLowerString::install();
|
||||
StaticCallbackEntry::install();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Call a function with appropriate exception handling (not)
|
||||
//
|
||||
// Remarks:
|
||||
//
|
||||
// this is stubbed and exception handling is ignored currently
|
||||
|
||||
void SetupSharedFoundation::callbackWithExceptionHandling(
|
||||
void (*callback)(void) // Routine to call with exception handling
|
||||
)
|
||||
{
|
||||
if (ConfigSharedFoundation::getNoExceptionHandling())
|
||||
{
|
||||
callback();
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
try
|
||||
{
|
||||
callback();
|
||||
}
|
||||
catch (__exception * mathException)
|
||||
{
|
||||
FATAL(true, ("Math Exception: %s\n", mathException->name));
|
||||
}
|
||||
catch (const char* message)
|
||||
{
|
||||
FATAL(true, ("Character Exception: %s\n", message));
|
||||
}
|
||||
catch(std::exception & m)
|
||||
{
|
||||
const char * c = m.what();
|
||||
FATAL(true, ("Std::exception: %s\n", c));
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
FATAL(true, ("Unknown exception\n"));
|
||||
}
|
||||
#else
|
||||
callback();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Uninstall the engine.
|
||||
*
|
||||
* This routine will properly uninstall the engine componenets that were
|
||||
* installed by SetupSharedFoundation::install().
|
||||
*/
|
||||
|
||||
void SetupSharedFoundation::remove(void)
|
||||
{
|
||||
ExitChain::quit();
|
||||
|
||||
if (GetNumberOfWarnings())
|
||||
REPORT(true, Report::RF_print | Report::RF_log | Report::RF_dialog, ("%d warnings logged", GetNumberOfWarnings()));
|
||||
|
||||
// this routine can't be on the exit chain because the exit chain depends upon the PerThreadData class being around
|
||||
//PerThreadData::remove();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
SetupSharedFoundation::Data::Data(Defaults defaults)
|
||||
{
|
||||
Zero(*this);
|
||||
|
||||
switch (defaults)
|
||||
{
|
||||
case D_game:
|
||||
runInBackground = true;
|
||||
|
||||
lpCmdLine = NULL;
|
||||
argc = 0;
|
||||
argv = NULL;
|
||||
|
||||
configFile = NULL;
|
||||
|
||||
frameRateLimit = CONST_REAL(0);
|
||||
break;
|
||||
|
||||
case D_console:
|
||||
runInBackground = true;
|
||||
|
||||
lpCmdLine = NULL;
|
||||
argc = 0;
|
||||
argv = NULL;
|
||||
|
||||
configFile = NULL;
|
||||
|
||||
frameRateLimit = CONST_REAL(0);
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG_FATAL(true, ("unknown case"));
|
||||
}
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -1,58 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// SetupSharedFoundation.h
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
// copyright 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_SetupSharedFoundation_H
|
||||
#define INCLUDED_SetupSharedFoundation_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
struct DebugMenuEntry;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class SetupSharedFoundation
|
||||
{
|
||||
public:
|
||||
|
||||
struct Data
|
||||
{
|
||||
// allow running in background
|
||||
bool runInBackground;
|
||||
|
||||
// pointer to command line
|
||||
char* lpCmdLine;
|
||||
int argc;
|
||||
char **argv;
|
||||
|
||||
const char *configFile;
|
||||
|
||||
real frameRateLimit;
|
||||
|
||||
public:
|
||||
|
||||
enum Defaults
|
||||
{
|
||||
D_game,
|
||||
D_console
|
||||
};
|
||||
|
||||
Data(Defaults defaults);
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
static void install(const Data &data);
|
||||
static void remove(void);
|
||||
|
||||
static void callbackWithExceptionHandling(void (*callback)(void));
|
||||
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -1,35 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// vsnprintf.cpp
|
||||
// jeff grills
|
||||
//
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/vsnprintf.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
// ======================================================================
|
||||
// Format a printf-style string into a text buffer of fixed size
|
||||
//
|
||||
// Return value:
|
||||
//
|
||||
// The number of characters written into the buffer, or -1 if the buffer was too small
|
||||
//
|
||||
// Remarks:
|
||||
//
|
||||
// If the buffer would overflow, the null terminating character is not written and -1
|
||||
// will be returned.
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
int vsnprintf(char *buffer, size_t count, const char *format, va_list va)
|
||||
{
|
||||
return _vsnprintf(buffer, count, format, va);
|
||||
}
|
||||
|
||||
#endif
|
||||
// ======================================================================
|
||||
@@ -1,24 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// vsnprintf.h
|
||||
// jeff grills
|
||||
//
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef VSNPRINTF_H
|
||||
#define VSNPRINTF_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
int vsnprintf(char *buffer, size_t count, const char *format, va_list va);
|
||||
|
||||
#endif
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include "sharedFoundation/Clock.h"
|
||||
#include "sharedFoundation/ConfigFile.h"
|
||||
#include "sharedFoundation/ConfigSharedFoundation.h"
|
||||
#include "sharedFoundation/CrashReportInformation.h"
|
||||
#include "sharedFoundation/ExitChain.h"
|
||||
#include "sharedFoundation/FloatingPointUnit.h"
|
||||
#include "sharedFoundation/Production.h"
|
||||
@@ -80,7 +79,6 @@ namespace OsNamespace
|
||||
Os::IMEHookFunction ms_IMEHookFunction;
|
||||
Os::QueueKeyDownHookFunction ms_queueKeyDownHookFunction;
|
||||
|
||||
int ms_processorCount;
|
||||
int ms_debugKeyIndex;
|
||||
int ms_SystemMouseCursorPositionX;
|
||||
int ms_SystemMouseCursorPositionY;
|
||||
@@ -245,106 +243,6 @@ void Os::installCommon()
|
||||
// switch into single-precision floating point mode
|
||||
FloatingPointUnit::install();
|
||||
|
||||
// get the amount of memory
|
||||
MEMORYSTATUS memoryStatus;
|
||||
GlobalMemoryStatus(&memoryStatus);
|
||||
CrashReportInformation::addStaticText("Ram: %dmb\n", memoryStatus.dwTotalPhys / (1024 * 1024));
|
||||
|
||||
// log the os information
|
||||
{
|
||||
OSVERSIONINFO versionInfo;
|
||||
Zero(versionInfo);
|
||||
versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||||
GetVersionEx(&versionInfo);
|
||||
CrashReportInformation::addStaticText("Os1: %d.%d.%d\n", versionInfo.dwMajorVersion, versionInfo.dwMinorVersion, versionInfo.dwBuildNumber);
|
||||
|
||||
char const * os = "Unknown";
|
||||
|
||||
char CDECL pwine_get_version;
|
||||
HMODULE hntdll = GetModuleHandle("ntdll.dll");
|
||||
|
||||
switch (versionInfo.dwMajorVersion) {
|
||||
case 4:
|
||||
switch (versionInfo.dwMinorVersion){
|
||||
case 10:
|
||||
os = "Windows 98";
|
||||
break;
|
||||
case 90:
|
||||
os = "Windows ME";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
switch (versionInfo.dwMinorVersion) {
|
||||
case 0:
|
||||
os = "Windows 2000";
|
||||
break;
|
||||
case 1:
|
||||
os = "Windows XP";
|
||||
break;
|
||||
case 2:
|
||||
os = "Windows 2003";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
switch (versionInfo.dwMinorVersion){
|
||||
case 0:
|
||||
os = "Windows Vista";
|
||||
break;
|
||||
case 1:
|
||||
os = "Windows 7";
|
||||
break;
|
||||
case 2:
|
||||
os = "Windows 8";
|
||||
break;
|
||||
case 3:
|
||||
os = "Windows 8.1";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
os = "Windows 10";
|
||||
break;
|
||||
}
|
||||
|
||||
//detect WINE
|
||||
if (hntdll)
|
||||
{
|
||||
pwine_get_version = (char)GetProcAddress(hntdll, "wine_get_version");
|
||||
if (pwine_get_version)
|
||||
{
|
||||
os = strcat("Wine ", &pwine_get_version);
|
||||
}
|
||||
}
|
||||
|
||||
CrashReportInformation::addStaticText("Os2: %s %s\n", os, versionInfo.szCSDVersion);
|
||||
}
|
||||
|
||||
// get the number of processors
|
||||
SYSTEM_INFO si;
|
||||
GetSystemInfo(&si);
|
||||
ms_processorCount = static_cast<int>(si.dwNumberOfProcessors);
|
||||
REPORT_LOG (ConfigSharedFoundation::getVerboseHardwareLogging(), ("Processor Count: %i\n", ms_processorCount));
|
||||
CrashReportInformation::addStaticText("NumProc: %d\n", ms_processorCount);
|
||||
|
||||
{
|
||||
HKEY key;
|
||||
LONG result = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0, KEY_EXECUTE, &key);
|
||||
|
||||
if (result == ERROR_SUCCESS)
|
||||
{
|
||||
DWORD data;
|
||||
DWORD type = REG_DWORD;
|
||||
DWORD size = sizeof (data);
|
||||
result = RegQueryValueEx (key, "~MHz", NULL, &type, reinterpret_cast<LPBYTE> (&data), &size);
|
||||
if ((result == ERROR_SUCCESS) && (size > 0))
|
||||
REPORT_LOG (ConfigSharedFoundation::getVerboseHardwareLogging(), ("Processor Speed: %i MHz\n", data));
|
||||
|
||||
RegCloseKey (key);
|
||||
}
|
||||
}
|
||||
|
||||
if (!GetKeyboardLayoutName(ms_keyboardLayout))
|
||||
ms_keyboardLayout[0] = '\0';
|
||||
|
||||
@@ -495,30 +393,6 @@ bool Os::wasFocusLost()
|
||||
return ms_wasFocusLost;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Return a flag indicating whether we are running a multiprocessor machine or not.
|
||||
*
|
||||
* @return True if the machine has more than one processor, false if not.
|
||||
*/
|
||||
|
||||
bool Os::isMultiprocessor()
|
||||
{
|
||||
return ms_processorCount > 1;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Return the number of processors.
|
||||
*
|
||||
* @return The number of processors in the machine.
|
||||
*/
|
||||
|
||||
int Os::getProcessorCount()
|
||||
{
|
||||
return ms_processorCount;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool Os::isMainThread()
|
||||
@@ -1662,10 +1536,7 @@ bool Os::isFocused()
|
||||
bool Os::launchBrowser(std::string const & website)
|
||||
{
|
||||
std::string URL("http://");
|
||||
if (strncmp(URL.c_str(), website.c_str(),7)!=0)
|
||||
URL+=website;
|
||||
else
|
||||
URL=website;
|
||||
URL=website;
|
||||
int result = reinterpret_cast<int>(ShellExecute(NULL, "open", URL.c_str(), NULL, NULL, SW_SHOWNORMAL));
|
||||
return (result > 32);
|
||||
}
|
||||
|
||||
@@ -109,9 +109,6 @@ public:
|
||||
static void convertTimeToGMT(const time_t &time, tm &zulu);
|
||||
static time_t convertGMTToTime(const tm &zulu);
|
||||
|
||||
static bool isMultiprocessor();
|
||||
static int getProcessorCount();
|
||||
|
||||
static void buildRelativePath(const char *baseDirectory, const char *targetPathname, std::string &relativePath);
|
||||
static bool getAbsolutePath(const char *relativePath, char *absolutePath, int absolutePathBufferSize);
|
||||
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
// PRIVATE. Do not export this header file outside the package.
|
||||
|
||||
#ifndef INCLUDED_FoundationTypesLinux_H
|
||||
#define INCLUDED_FoundationTypesLinux_H
|
||||
|
||||
// ======================================================================
|
||||
// specify what platform we're running on.
|
||||
|
||||
#define PLATFORM_UNIX
|
||||
#define PLATFORM_LINUX
|
||||
|
||||
#include <cstdio>
|
||||
// ======================================================================
|
||||
// basic types that we assume to be around
|
||||
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned char uint8;
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned long uint32;
|
||||
typedef signed char int8;
|
||||
typedef signed short int16;
|
||||
typedef signed long int32;
|
||||
typedef signed long long int int64;
|
||||
typedef unsigned long long int uint64;
|
||||
typedef float real;
|
||||
typedef FILE* FILE_HANDLE;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// StderrLogger.cpp
|
||||
//
|
||||
// Copyright 2003 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedLog/FirstSharedLog.h"
|
||||
#include "sharedLog/StderrLogger.h"
|
||||
#include "sharedLog/Log.h"
|
||||
#include <string>
|
||||
#include <fcntl.h>
|
||||
|
||||
// ======================================================================
|
||||
|
||||
namespace StderrLoggerNamespace
|
||||
{
|
||||
bool s_installed;
|
||||
int s_oldStderr;
|
||||
int s_stderrPipe[2];
|
||||
}
|
||||
using namespace StderrLoggerNamespace;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
void StderrLogger::install()
|
||||
{
|
||||
DEBUG_FATAL(s_installed, ("StderrLogger already installed"));
|
||||
s_installed = true;
|
||||
s_oldStderr = dup(2);
|
||||
pipe(s_stderrPipe);
|
||||
dup2(s_stderrPipe[1], 2);
|
||||
fcntl(s_stderrPipe[0], F_SETFL, O_NONBLOCK);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void StderrLogger::remove()
|
||||
{
|
||||
DEBUG_FATAL(!s_installed, ("StderrLogger not installed"));
|
||||
dup2(s_oldStderr, 2);
|
||||
close(s_stderrPipe[0]);
|
||||
close(s_stderrPipe[1]);
|
||||
s_installed = false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void StderrLogger::update()
|
||||
{
|
||||
if (!s_installed)
|
||||
return;
|
||||
|
||||
char buf[8192];
|
||||
int nRead = read(s_stderrPipe[0], buf, sizeof(buf)-1);
|
||||
if (nRead > 0)
|
||||
{
|
||||
int startPos = 0;
|
||||
while (startPos < nRead)
|
||||
{
|
||||
int endPos = startPos;
|
||||
while (buf[endPos] != '\n' && endPos < nRead)
|
||||
++endPos;
|
||||
buf[endPos] = 0;
|
||||
if (endPos > startPos)
|
||||
LOG("stderr", ("%s", buf+startPos));
|
||||
startPos = endPos+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// OsMemory.cpp
|
||||
//
|
||||
// Copyright 2002 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedMemoryManager/FirstSharedMemoryManager.h"
|
||||
#include "sharedMemoryManager/OsMemory.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
void OsMemory::install()
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void OsMemory::remove()
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void *OsMemory::commit(void *, size_t bytes)
|
||||
{
|
||||
return ::malloc(bytes);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool OsMemory::free(void *addr, size_t)
|
||||
{
|
||||
::free(addr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -1,29 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// OsMemory.h
|
||||
//
|
||||
// Copyright 2002 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_OsMemory_H
|
||||
#define INCLUDED_OsMemory_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class OsMemory
|
||||
{
|
||||
public:
|
||||
static void install();
|
||||
static void remove();
|
||||
|
||||
static void * reserve(size_t bytes);
|
||||
static void * commit(void *addr, size_t bytes);
|
||||
static bool free(void *addr, size_t bytes);
|
||||
static bool protect(void *addr, size_t bytes, bool allowAccess);
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif // INCLUDED_OsMemory_H
|
||||
|
||||
@@ -1,134 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// OsNewDel.cpp
|
||||
//
|
||||
// Copyright 2002 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedMemoryManager/FirstSharedMemoryManager.h"
|
||||
#include "sharedMemoryManager/MemoryManager.h"
|
||||
#include "sharedMemoryManager/OsNewDel.h"
|
||||
|
||||
#include <malloc.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
static MemoryManager memoryManager __attribute__ ((init_priority (101)));
|
||||
|
||||
#define USE_LIBC_MALLOC_HOOKS 0
|
||||
|
||||
#if USE_LIBC_MALLOC_HOOKS
|
||||
extern "C"
|
||||
{
|
||||
void memoryManagerFreeHook(__malloc_ptr_t __ptr, __const __malloc_ptr_t)
|
||||
{
|
||||
delete[] (char *)__ptr;
|
||||
}
|
||||
|
||||
__malloc_ptr_t memoryManagerMallocHook(size_t __size, const __malloc_ptr_t)
|
||||
{
|
||||
return new char[__size];
|
||||
}
|
||||
|
||||
__malloc_ptr_t memoryManagerReallocHook(__malloc_ptr_t __ptr, size_t size, __const __malloc_ptr_t)
|
||||
{
|
||||
if(! __ptr)
|
||||
return new char[size];
|
||||
|
||||
return MemoryManager::reallocate(__ptr, size);
|
||||
}
|
||||
|
||||
__malloc_ptr_t memoryManagerMemAlignHook(size_t alignment, size_t size, __const __malloc_ptr_t)
|
||||
{
|
||||
DEBUG_FATAL(true, ("memalign not implemented!"));
|
||||
return new char[size];
|
||||
}
|
||||
|
||||
static void memoryManagerMallocInitializeHook(void)
|
||||
{
|
||||
__free_hook = memoryManagerFreeHook;
|
||||
__malloc_hook = memoryManagerMallocHook;
|
||||
__realloc_hook = memoryManagerReallocHook;
|
||||
__memalign_hook = memoryManagerMemAlignHook;
|
||||
}
|
||||
void (*__malloc_initialize_hook) (void) = memoryManagerMallocInitializeHook;
|
||||
}
|
||||
|
||||
#endif//USE_LIBC_MALLOC_HOOKS
|
||||
|
||||
// ======================================================================
|
||||
|
||||
void *operator new(size_t size, MemoryManagerNotALeak) throw (std::bad_alloc)
|
||||
{
|
||||
return MemoryManager::allocate(size, reinterpret_cast<uint32>(__builtin_return_address(0)), false, false);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void *operator new(size_t size) throw (std::bad_alloc)
|
||||
{
|
||||
return MemoryManager::allocate(size, reinterpret_cast<uint32>(__builtin_return_address(0)), false, true);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void *operator new[](size_t size) throw (std::bad_alloc)
|
||||
{
|
||||
return MemoryManager::allocate(size, reinterpret_cast<uint32>(__builtin_return_address(0)), true, true);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void *operator new(size_t size, const char *file, int line) throw (std::bad_alloc)
|
||||
{
|
||||
return MemoryManager::allocate(size, reinterpret_cast<uint32>(__builtin_return_address(0)), false, true);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void *operator new[](size_t size, const char *file, int line) throw (std::bad_alloc)
|
||||
{
|
||||
return MemoryManager::allocate(size, reinterpret_cast<uint32>(__builtin_return_address(0)), true, true);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void operator delete(void *pointer) throw()
|
||||
{
|
||||
if (pointer)
|
||||
MemoryManager::free(pointer, false);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void operator delete[](void *pointer) throw()
|
||||
{
|
||||
if (pointer)
|
||||
MemoryManager::free(pointer, true);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void operator delete(void *pointer, const char *file, int line) throw()
|
||||
{
|
||||
UNREF(file);
|
||||
UNREF(line);
|
||||
|
||||
if (pointer)
|
||||
MemoryManager::free(pointer, false);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void operator delete[](void *pointer, const char *file, int line) throw()
|
||||
{
|
||||
UNREF(file);
|
||||
UNREF(line);
|
||||
|
||||
if (pointer)
|
||||
MemoryManager::free(pointer, true);
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// OsNewDel.h
|
||||
//
|
||||
// Copyright 2002 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_OsNewDel_H
|
||||
#define INCLUDED_OsNewDel_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
enum MemoryManagerNotALeak
|
||||
{
|
||||
MM_notALeak
|
||||
};
|
||||
|
||||
void *operator new(size_t size, MemoryManagerNotALeak) throw(std::bad_alloc);
|
||||
void *operator new(size_t size) throw(std::bad_alloc);
|
||||
void *operator new[](size_t size) throw(std::bad_alloc);
|
||||
void *operator new(size_t size, char const *file, int line) throw(std::bad_alloc);
|
||||
void *operator new[](size_t size, char const *file, int line) throw(std::bad_alloc);
|
||||
|
||||
void operator delete(void *pointer) throw();
|
||||
void operator delete[](void *pointer) throw();
|
||||
void operator delete(void *pointer, char const *file, int line) throw();
|
||||
void operator delete[](void *pointer, char const *file, int line) throw();
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif // INCLUDED_OsNewDel_H
|
||||
|
||||
@@ -1,372 +0,0 @@
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
#include "FirstSharedNetwork.h"
|
||||
#include "Address.h"
|
||||
#include <cassert>
|
||||
#include <netdb.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <cstdio>
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
Address::Address() :
|
||||
addr4(new struct sockaddr_in),
|
||||
hostAddress("0.0.0.0")
|
||||
{
|
||||
memset(addr4, 0, sizeof(struct sockaddr_in));
|
||||
addr4->sin_family = AF_INET;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
Address::Address(const std::string & newHostAddress, unsigned short newHostPort) :
|
||||
addr4(new struct sockaddr_in),
|
||||
hostAddress(newHostAddress)
|
||||
{
|
||||
struct hostent * h;
|
||||
unsigned long u;
|
||||
|
||||
memset(addr4, 0, sizeof(struct sockaddr_in));
|
||||
addr4->sin_port = htons(newHostPort);
|
||||
addr4->sin_family = AF_INET;
|
||||
// was an address supplied?
|
||||
if(hostAddress.size() > 0)
|
||||
{
|
||||
// Is the first byte a number? (IP names begin with an alpha)
|
||||
if(!isdigit(hostAddress[0]))
|
||||
{
|
||||
// The first byte is a letter, resolve it
|
||||
if( (h = gethostbyname(hostAddress.c_str())) != 0)
|
||||
{
|
||||
memcpy(&addr4->sin_addr, h->h_addr_list[0], sizeof(addr4->sin_addr));
|
||||
}
|
||||
else
|
||||
{
|
||||
// boom! grab the entry from the h_addr member instead!
|
||||
if( (h = gethostbyname(hostAddress.c_str())) != 0)
|
||||
{
|
||||
memcpy(&addr4->sin_addr, h->h_addr, sizeof(addr4->sin_addr));
|
||||
}
|
||||
else
|
||||
{
|
||||
// no resolution, INADDR_ANY
|
||||
memset(&addr4->sin_addr, 0, sizeof(addr4->sin_addr));
|
||||
|
||||
// in debug, fail, something is wrong.
|
||||
// potential problems - an insanely bogus address was
|
||||
// passed or the host system is misconfigured and cannot
|
||||
// resolve the name
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
char addrbuf[17] = {"\0"};
|
||||
unsigned char * a = (unsigned char *)&addr4->sin_addr;
|
||||
snprintf(addrbuf, sizeof(addrbuf), "%u.%u.%u.%u", a[0], a[1], a[2], a[3]);
|
||||
hostAddress = addrbuf;
|
||||
}
|
||||
else
|
||||
{
|
||||
// A dotted decimal ip number string was supplied. Convert for sin_addr
|
||||
u = inet_addr(hostAddress.c_str());
|
||||
memcpy(&addr4->sin_addr, &u, sizeof(addr4->sin_addr));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// nothing was supplied, assign INADDR_ANY
|
||||
addr4->sin_addr.s_addr = INADDR_ANY;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
Address::Address(const Address & source) :
|
||||
addr4(new struct sockaddr_in),
|
||||
hostAddress(source.hostAddress)
|
||||
{
|
||||
*addr4 = *source.addr4;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
Address::Address(const struct sockaddr_in & ipv4addr) :
|
||||
addr4(new struct sockaddr_in),
|
||||
hostAddress("")
|
||||
{
|
||||
convertFromSockAddr(ipv4addr);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
Address::~Address()
|
||||
{
|
||||
delete addr4;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
Address & Address::operator = (const Address & rhs)
|
||||
{
|
||||
if(this != &rhs)
|
||||
{
|
||||
hostAddress = rhs.hostAddress;
|
||||
*addr4 = *rhs.addr4;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
Address & Address::operator = (const struct sockaddr_in & rhs)
|
||||
{
|
||||
convertFromSockAddr(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
void Address::convertFromSockAddr(const struct sockaddr_in & source)
|
||||
{
|
||||
// extract IP bytes from ipv4add4
|
||||
const unsigned char * ip;
|
||||
char name[17] = {"\0"};
|
||||
|
||||
ip = reinterpret_cast<const unsigned char *>(&source.sin_addr);
|
||||
snprintf(name, 17, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]); //lint !e534
|
||||
hostAddress = name;
|
||||
*addr4 = source;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
/**
|
||||
@brief get a human readable host address
|
||||
|
||||
Example:
|
||||
\code
|
||||
void foo(struct sockaddr_in & a)
|
||||
{
|
||||
Address b(a);
|
||||
printf("address = %%s\\n", b.getHostAddress().c_str());
|
||||
}
|
||||
\endcode
|
||||
|
||||
@return A human readable host address string
|
||||
|
||||
@author Justin Randall
|
||||
*/
|
||||
const std::string & Address::getHostAddress() const
|
||||
{
|
||||
return hostAddress;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
/**
|
||||
@brief get the port associated with this address
|
||||
|
||||
Example:
|
||||
\code
|
||||
void foo(struct sockaddr_in & a)
|
||||
{
|
||||
Address b(a);
|
||||
printf("port = %%i\\n", b.getHostPort());
|
||||
}
|
||||
\endcode
|
||||
|
||||
@return A human readable port in host-byte order associated with
|
||||
this address.
|
||||
|
||||
@author Justin Randall
|
||||
*/
|
||||
const unsigned short Address::getHostPort() const
|
||||
{
|
||||
return ntohs(addr4->sin_port);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
/**
|
||||
@brief get the BSD sockaddr describing this address
|
||||
|
||||
Example:
|
||||
\code
|
||||
void foo(SOCKET s, unsigned char * d, int l, const Address & a)
|
||||
{
|
||||
int t = sizeof(struct sockaddr_in);
|
||||
sendto(s, s, l, 0, reinterpret_cast<const struct sockaddr *>(&(a.getSockAddr4())), t);
|
||||
}
|
||||
\endcode
|
||||
|
||||
@return a BSD sockaddr that describes this IPv4 address
|
||||
|
||||
@author Justin Randall
|
||||
*/
|
||||
const struct sockaddr_in & Address::getSockAddr4() const
|
||||
{
|
||||
return *addr4;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
/**
|
||||
@brief equality operator
|
||||
|
||||
The equality operator compares the ip address, ip port,
|
||||
and address family to establish equality.
|
||||
|
||||
Example:
|
||||
\code
|
||||
Address a("127.0.0.1", 55443);
|
||||
Address b;
|
||||
|
||||
b = a;
|
||||
assert(b == a);
|
||||
\endcode
|
||||
|
||||
@return True of the right hand side is equal to this address
|
||||
|
||||
@author Justin Randall
|
||||
*/
|
||||
const bool Address::operator == (const Address & rhs) const
|
||||
{
|
||||
return (addr4->sin_addr.s_addr == rhs.addr4->sin_addr.s_addr &&
|
||||
addr4->sin_family == rhs.addr4->sin_family &&
|
||||
addr4->sin_port == rhs.addr4->sin_port);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
/**
|
||||
@brief less-than comparison operator
|
||||
|
||||
The < comparison operator compares the IP number and port. If
|
||||
the IP numbers are identical, but the left hand side port is
|
||||
less than the right hand side port, the operator will return
|
||||
true.
|
||||
|
||||
@return true if the left hand side's IP number is less than
|
||||
the right hand side IP number. If the numbers are equal, it
|
||||
will return true if the left hand side IP port is less
|
||||
than the right hand side port. Otherwise it returns false.
|
||||
|
||||
@author Justin Randall
|
||||
*/
|
||||
const bool Address::operator < (const Address & rhs) const
|
||||
{
|
||||
return(addr4->sin_addr.s_addr < rhs.addr4->sin_addr.s_addr ||
|
||||
addr4->sin_addr.s_addr == rhs.addr4->sin_addr.s_addr &&
|
||||
addr4->sin_port < rhs.addr4->sin_port);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
/**
|
||||
@brief inequality operator
|
||||
|
||||
Leverages the equality operator, so whenever == returns true,
|
||||
this returns false, and visa versa.
|
||||
|
||||
@return true if the right hand side is not equal to the left
|
||||
hand side. False if they are equal.
|
||||
|
||||
@see Adress::operator==
|
||||
|
||||
@author Justin Randall
|
||||
*/
|
||||
const bool Address::operator != (const Address & rhs) const
|
||||
{
|
||||
return(! (rhs == *this));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
/**
|
||||
@brief greater-than comparison operator
|
||||
|
||||
The > comparison operator compares the IP number and port. If
|
||||
the IP numbers are identical, but the right hand side port is
|
||||
lesser than the left hand side port, the operator will return
|
||||
true.
|
||||
|
||||
@return true if the left hand side's IP number is greater than
|
||||
the right hand side IP number. If the numbers are equal, it
|
||||
will return true if the left hand side IP port is greater
|
||||
than the right hand side port. Otherwise it returns false.
|
||||
|
||||
@author Justin Randall
|
||||
*/
|
||||
const bool Address::operator > (const Address & rhs) const
|
||||
{
|
||||
return(addr4->sin_addr.s_addr > rhs.addr4->sin_addr.s_addr ||
|
||||
addr4->sin_addr.s_addr == rhs.addr4->sin_addr.s_addr &&
|
||||
addr4->sin_port > rhs.addr4->sin_port);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
/**
|
||||
@brief a hash_map support routine
|
||||
|
||||
The STL hash_map (present in most STL implementations) requires
|
||||
a size_t return from a hash function to identify which bucket
|
||||
a particular value should reside in. On 32 bit or better platforms
|
||||
the sockaddr_in.sin_addr.s_addr member is small enough to
|
||||
qualify as a hash-result, provides reasonably unique values
|
||||
and is reproducable given an address input.
|
||||
|
||||
Example:
|
||||
\code
|
||||
typedef std::hash_map<Address, Connection *, Address::HashFunction, Address::EqualFunction> AddressMap;
|
||||
\endcode
|
||||
|
||||
@return the ip number member of a sockaddr_in struct
|
||||
|
||||
@author Justin Randall
|
||||
*/
|
||||
size_t Address::hashFunction() const
|
||||
{
|
||||
return addr4->sin_addr.s_addr;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
/**
|
||||
@brief STL map support routine
|
||||
|
||||
STL maps (including hash_maps) require unique keys, and therefore
|
||||
need to compare a key for equality with an existing target.
|
||||
|
||||
The functor uses Address::operator = for the comparison.
|
||||
|
||||
Example:
|
||||
\code
|
||||
typedef std::hash_map<Address, Connection *, Address::HashFunction, Address::EqualFunction> AddressMap;
|
||||
\endcode
|
||||
|
||||
@return true if the left hand side and right hand side are equal
|
||||
using Address::operator =
|
||||
@see Address::operator=
|
||||
|
||||
*/
|
||||
bool Address::EqualFunction::operator () (const Address & lhs, const Address & rhs) const
|
||||
{
|
||||
return lhs == rhs;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
/**
|
||||
@brief STL hash_map support routine
|
||||
|
||||
The HashFunction::operator() invokes Address::hashFunction to
|
||||
determine an appropriate hash for the address.
|
||||
|
||||
Example:
|
||||
\code
|
||||
typedef std::hash_map<Address, Connection *, Address::HashFunction, Address::EqualFunction> AddressMap;
|
||||
\endcode
|
||||
|
||||
@see Address::hashFunction
|
||||
|
||||
@author Justin Randall
|
||||
*/
|
||||
size_t Address::HashFunction::operator () (const Address & a) const
|
||||
{
|
||||
return a.hashFunction();
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -1,141 +0,0 @@
|
||||
// NetworkGetHostName.cpp
|
||||
// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved.
|
||||
// Author: Justin Randall
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#include "FirstSharedNetwork.h"
|
||||
#include "Address.h"
|
||||
#include "sharedNetwork/NetworkHandler.h"
|
||||
#include <net/if.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
struct HN
|
||||
{
|
||||
HN();
|
||||
std::string hostName;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
HN::HN()
|
||||
{
|
||||
char name[512] = {"\0"};
|
||||
if(gethostname(name, sizeof(name)) == 0)
|
||||
{
|
||||
Address a(name, 0);
|
||||
//hostName = name;
|
||||
hostName = a.getHostAddress();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
const std::string & NetworkHandler::getHostName()
|
||||
{
|
||||
static HN hn;
|
||||
return hn.hostName;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
const std::string & NetworkHandler::getHumanReadableHostName()
|
||||
{
|
||||
char name[512] = {"\0"};
|
||||
static std::string nameString;
|
||||
if(nameString.empty())
|
||||
{
|
||||
if(gethostname(name, sizeof(name)) == 0)
|
||||
{
|
||||
name[sizeof(name) - 1] = 0;
|
||||
//hostName = name;
|
||||
nameString = name;
|
||||
}
|
||||
}
|
||||
return nameString;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
struct HL
|
||||
{
|
||||
HL();
|
||||
std::vector<std::pair<std::string, std::string> > addrList;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
HL::HL() :
|
||||
addrList()
|
||||
{
|
||||
struct ifconf ifc;
|
||||
int sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
// create a socket to perform SIOCGIFCONF on
|
||||
if(sock > -1)
|
||||
{
|
||||
// determine buffer size to receive array of if_req's, initialize it
|
||||
// when length is appropriate
|
||||
int reqSize = 100 * sizeof(struct ifreq);
|
||||
int lastReqSize = reqSize;
|
||||
for(;;)
|
||||
{
|
||||
char * buf = new char[reqSize];
|
||||
ifc.ifc_len = reqSize;
|
||||
ifc.ifc_buf = buf;
|
||||
memset(ifc.ifc_buf, 0, reqSize);
|
||||
if (ioctl(sock, SIOCGIFCONF, &ifc) < 0)
|
||||
{
|
||||
if (errno != EINVAL || lastReqSize != 0)
|
||||
{
|
||||
WARNING(true, ("Error getting interface list: %s", strerror(errno)));
|
||||
delete buf;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(ifc.ifc_len == lastReqSize)
|
||||
break; // we have the reqs
|
||||
lastReqSize = ifc.ifc_len;
|
||||
}
|
||||
|
||||
// need more buffer space for request
|
||||
reqSize += sizeof(struct ifreq);
|
||||
delete [] buf;
|
||||
}
|
||||
|
||||
int reqCount = reqSize / sizeof(struct ifreq);
|
||||
int i;
|
||||
ifreq * reqs = (struct ifreq *)ifc.ifc_buf;
|
||||
for(i = 0; i < reqCount; ++i)
|
||||
{
|
||||
struct sockaddr_in * sa = (struct sockaddr_in *)&reqs[i].ifr_addr;
|
||||
if(sa->sin_family == AF_INET)
|
||||
{
|
||||
char addrbuf[17] = {"\0"};
|
||||
unsigned char * a = (unsigned char *)&sa->sin_addr;
|
||||
snprintf(addrbuf, sizeof(addrbuf), "%u.%u.%u.%u", a[0], a[1], a[2], a[3]);
|
||||
addrList.push_back(std::make_pair(std::string(reqs[i].ifr_name), std::string(addrbuf)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
const std::vector<std::pair<std::string, std::string> > & NetworkHandler::getInterfaceAddresses()
|
||||
{
|
||||
static HL hl;
|
||||
return hl.addrList;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
@@ -1,236 +0,0 @@
|
||||
//---------------------------------------------------------------------
|
||||
#pragma warning(disable : 4127)
|
||||
|
||||
#include "FirstSharedNetwork.h"
|
||||
#include <cassert>
|
||||
#include "Sock.h"
|
||||
#include <netdb.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
const int INVALID_SOCKET = 0xFFFFFFFF;
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
Sock::Sock() :
|
||||
handle(INVALID_SOCKET),
|
||||
lastError(Sock::SOCK_NO_ERROR),
|
||||
bindAddress()
|
||||
{
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
Sock::~Sock()
|
||||
{
|
||||
// ensure we don't block, and that pending
|
||||
// data is sent with a graceful shutdown
|
||||
int err;
|
||||
err = close(handle);
|
||||
assert(err == 0);
|
||||
handle = INVALID_SOCKET;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
/**
|
||||
@brief Bind the socket to the specified local address
|
||||
*/
|
||||
bool Sock::bind(const Address & newBindAddress)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
int enable = 1;
|
||||
setsockopt(handle, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable));
|
||||
|
||||
bindAddress = newBindAddress;
|
||||
assert(handle != INVALID_SOCKET);
|
||||
socklen_t namelen = sizeof(struct sockaddr_in);
|
||||
int err = ::bind(handle, reinterpret_cast<const struct sockaddr *>(&(bindAddress.getSockAddr4())), namelen);
|
||||
if(err == 0)
|
||||
{
|
||||
result = true;
|
||||
struct sockaddr_in a;
|
||||
int r;
|
||||
r = getsockname(handle, reinterpret_cast<struct sockaddr *>(&a), &namelen);
|
||||
assert(r == 0);
|
||||
bindAddress = a;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
|
||||
assert(err == 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
bool Sock::bind()
|
||||
{
|
||||
bool result = false;
|
||||
struct sockaddr_in a;
|
||||
socklen_t namelen = sizeof(struct sockaddr_in);
|
||||
memset(&a, 0, sizeof(struct sockaddr_in));
|
||||
a.sin_family = AF_INET;
|
||||
a.sin_port = 0;
|
||||
a.sin_addr.s_addr = INADDR_ANY;
|
||||
assert(handle != INVALID_SOCKET);
|
||||
int err = ::bind(handle, reinterpret_cast<struct sockaddr *>(&a), namelen);
|
||||
if(err == 0)
|
||||
{
|
||||
result = true;
|
||||
int r;
|
||||
r = getsockname(handle, reinterpret_cast<struct sockaddr *>(&a), &namelen);
|
||||
assert(r == 0);
|
||||
bindAddress = a;
|
||||
}
|
||||
assert(err == 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
bool Sock::canRecv() const
|
||||
{
|
||||
pollfd r;
|
||||
r.fd = handle;
|
||||
r.events = POLLIN | POLLPRI | POLLERR;
|
||||
|
||||
int err = poll(&r, 1, 0);
|
||||
|
||||
if(err < 0)
|
||||
{
|
||||
switch(errno)
|
||||
{
|
||||
case EINTR: // the system has interrupted the call, it's too busy to send right now
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (err > 0);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
bool Sock::canSend() const
|
||||
{
|
||||
pollfd w;
|
||||
w.fd = handle;
|
||||
w.events = POLLOUT | POLLERR;
|
||||
int err = poll(&w, 1, 0);
|
||||
|
||||
if(err < 0)
|
||||
{
|
||||
switch(errno)
|
||||
{
|
||||
case EINTR: // the system has interrupted the call, it's too busy to send right now
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (err > 0);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
const unsigned int Sock::getInputBytesPending() const
|
||||
{
|
||||
unsigned long int bytes = 0;
|
||||
int err;
|
||||
err = ioctl(handle, FIONREAD, &bytes); //lint !e1924 (I don't know WHAT Microsoft is doing here!)
|
||||
assert(err == 0);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
const std::string Sock::getLastError() const
|
||||
{
|
||||
std::string errString;
|
||||
|
||||
switch(errno)
|
||||
{
|
||||
case EBADF:
|
||||
errString = "The argument s is not a valid descriptor.";
|
||||
break;
|
||||
case ENOTSOCK:
|
||||
errString = "The argument s is a file, not a socket.";
|
||||
break;
|
||||
case ENOPROTOOPT:
|
||||
errString = "The option is unknown at the level indicated.";
|
||||
break;
|
||||
case EFAULT:
|
||||
errString = "The address pointed to by optval is not in a valid part of the process address space. For getsockopt, this error may also be returned if optlen is not in a valid part of the process address space.";
|
||||
break;
|
||||
case ENOTTY:
|
||||
errString = "The scoket handle is not associated with a character special device.";
|
||||
break;
|
||||
case EINVAL:
|
||||
errString = "argument is not valid.";
|
||||
break;
|
||||
case EAGAIN:
|
||||
errString = "EAGAIN";
|
||||
break;
|
||||
case EDEADLK:
|
||||
errString = "EDEADLK";
|
||||
break;
|
||||
case ECONNRESET:
|
||||
errString = "The connection was reset by the peer.";
|
||||
lastError = CONNECTION_RESET;
|
||||
break;
|
||||
default:
|
||||
errString = strerror(errno);
|
||||
break;
|
||||
}
|
||||
|
||||
return errString;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
void Sock::getPeerName(struct sockaddr_in & target, int s)
|
||||
{
|
||||
socklen_t namelen = sizeof(struct sockaddr_in);
|
||||
int err;
|
||||
err = getpeername(s, reinterpret_cast<sockaddr *>(&(target)), &namelen);
|
||||
assert(err != -1);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/** @brief determine the maximum message size that may be sent on this socket
|
||||
*/
|
||||
const unsigned int Sock::getMaxMessageSendSize() const
|
||||
{
|
||||
int maxMsgSize = 1500;
|
||||
/** @todo get msg size via IP interface on Linux
|
||||
int optlen = sizeof(int);
|
||||
int result = getsockopt(handle, SOL_SOCKET, SO_MAX_MSG_SIZE, reinterpret_cast<char *>(&maxMsgSize), &optlen);
|
||||
if(result != 0)
|
||||
{
|
||||
perror("Sock::getMaxMessageSendSize() : getsockopt()");
|
||||
}
|
||||
*/
|
||||
return static_cast<unsigned int>(maxMsgSize);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
void Sock::setNonBlocking() const
|
||||
{
|
||||
assert(handle != INVALID_SOCKET);
|
||||
unsigned long int nb = 1;
|
||||
int err;
|
||||
err = ioctl(handle, FIONBIO, &nb); //lint !e569 // loss of precision in the FIONBIO macro, beyond my control
|
||||
assert(err == 0);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
@@ -1,128 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Sock.h
|
||||
//
|
||||
// Copyright 2003 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_Sock_H
|
||||
#define INCLUDED_Sock_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedNetwork/Address.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
const unsigned int SOCK_ERROR = 0xFFFFFFFF;
|
||||
|
||||
/**
|
||||
@brief a BSD socket abstraction
|
||||
|
||||
Sock abstracts BSD sockets for platform independant operation. It
|
||||
also provides common socket operations to simplify socket management.
|
||||
|
||||
@see BroadcastSock
|
||||
@see TcpSock
|
||||
@see UdpSock
|
||||
|
||||
@author Justin Randall
|
||||
*/
|
||||
class Sock
|
||||
{
|
||||
public:
|
||||
/**
|
||||
@brief failure states for a socket
|
||||
*/
|
||||
enum ErrorCodes
|
||||
{
|
||||
SOCK_NO_ERROR,
|
||||
CONNECTION_FAILED,
|
||||
CONNECTION_CLOSED,
|
||||
CONNECTION_RESET
|
||||
};
|
||||
|
||||
Sock();
|
||||
virtual ~Sock() = 0;
|
||||
bool bind(const Address & bindAddress);
|
||||
bool bind();
|
||||
bool canSend() const;
|
||||
bool canRecv() const;
|
||||
const Address & getBindAddress() const;
|
||||
const int getHandle() const;
|
||||
const unsigned int getInputBytesPending() const;
|
||||
const std::string getLastError() const;
|
||||
const enum ErrorCodes getLastErrorCode() const;
|
||||
const unsigned int getMaxMessageSendSize() const;
|
||||
static void getPeerName(struct sockaddr_in & target, int s);
|
||||
|
||||
private:
|
||||
// disabled
|
||||
Sock(const Sock & source);
|
||||
Sock & operator= (const Sock & source);
|
||||
|
||||
protected:
|
||||
void setNonBlocking() const;
|
||||
protected:
|
||||
int handle;
|
||||
|
||||
/**
|
||||
@brief support for setting/getting last error from derived
|
||||
sock classes
|
||||
*/
|
||||
mutable enum ErrorCodes lastError;
|
||||
private:
|
||||
Address bindAddress;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
/**
|
||||
@brief return the local address of the socket
|
||||
|
||||
Until a socket is bound, the bind address may be reported as
|
||||
0.0.0.0:0
|
||||
|
||||
@return a const Address reference describing the local address
|
||||
of the socket.
|
||||
|
||||
@author Justin Randall
|
||||
*/
|
||||
inline const Address & Sock::getBindAddress() const
|
||||
{
|
||||
return bindAddress;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
/**
|
||||
@brief return the platform specific socket handle
|
||||
|
||||
the handle returned is not portable and should only be used locally
|
||||
for Sock specific operations.
|
||||
|
||||
@author Justin Randall
|
||||
*/
|
||||
inline const int Sock::getHandle() const
|
||||
{
|
||||
return handle;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
/**
|
||||
@brief get the last error code on the socket
|
||||
|
||||
@return the last error code on the socket
|
||||
|
||||
@see Sock::ErrorCodes
|
||||
|
||||
@author Justin Randall
|
||||
*/
|
||||
inline const enum Sock::ErrorCodes Sock::getLastErrorCode() const
|
||||
{
|
||||
return lastError;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
#endif // _Sock_H
|
||||
|
||||
@@ -1,610 +0,0 @@
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
#include "sharedNetwork/FirstSharedNetwork.h"
|
||||
#include "TcpClient.h"
|
||||
#include "TcpServer.h"
|
||||
|
||||
#include "Archive/Archive.h"
|
||||
#include "sharedFoundation/Clock.h"
|
||||
#include "sharedFoundation/Os.h"
|
||||
#include "sharedLog/Log.h"
|
||||
#include "sharedLog/NetLogConnection.h"
|
||||
#include "sharedNetwork/Connection.h"
|
||||
#include "sharedNetwork/ConfigSharedNetwork.h"
|
||||
#include <map>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <unistd.h>
|
||||
#include <netdb.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
const unsigned long KEEPALIVE_MS = 1000;
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace TcpClientNamespace
|
||||
{
|
||||
std::set<TcpClient *> s_pendingConnectionSends;
|
||||
std::set<TcpClient *> s_tcpClients;
|
||||
bool s_installed = false;
|
||||
}
|
||||
|
||||
using namespace TcpClientNamespace;
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
TcpClient::TcpClient (int sockHandle, TcpServer * server) :
|
||||
m_socket(sockHandle),
|
||||
m_tcpServer(server),
|
||||
m_pendingSend(),
|
||||
m_connection(0),
|
||||
m_recvBuffer(0),
|
||||
m_recvBufferLength(0),
|
||||
m_remoteAddress(),
|
||||
m_refCount(0),
|
||||
m_connected (true),
|
||||
m_lastSendTime(0),
|
||||
m_bindPort(0),
|
||||
m_rawTCP( false )
|
||||
{
|
||||
s_tcpClients.insert(this);
|
||||
setSockOptions();
|
||||
|
||||
struct sockaddr_in target;
|
||||
socklen_t namelen = sizeof(struct sockaddr_in);
|
||||
if (getpeername(sockHandle, reinterpret_cast<sockaddr *>(&target), &namelen) == 0)
|
||||
m_remoteAddress = target;
|
||||
struct sockaddr_in bindAddr;
|
||||
|
||||
if(getsockname(sockHandle, reinterpret_cast<struct sockaddr *>(&bindAddr), &namelen) == 0)
|
||||
{
|
||||
m_bindPort = ntohs(bindAddr.sin_port);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
TcpClient::TcpClient (const std::string & a, const unsigned short port) :
|
||||
m_socket(-1),
|
||||
m_tcpServer(0),
|
||||
m_connection(0),
|
||||
m_recvBuffer(0),
|
||||
m_recvBufferLength(0),
|
||||
m_remoteAddress(a, port),
|
||||
m_refCount(0),
|
||||
m_connected (false),
|
||||
m_lastSendTime(0),
|
||||
m_bindPort(0),
|
||||
m_rawTCP( false )
|
||||
{
|
||||
FATAL(! s_installed, ("TcpClient is not installed!"));
|
||||
|
||||
s_tcpClients.insert(this);
|
||||
setupSocket();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
TcpClient::~TcpClient()
|
||||
{
|
||||
FATAL(m_refCount > 0, ("Attempting to destroy a TcpClient while references still exist!"));
|
||||
std::set<TcpClient *>::iterator f = s_tcpClients.find(this);
|
||||
if(f != s_tcpClients.end())
|
||||
s_tcpClients.erase(f);
|
||||
f = s_pendingConnectionSends.find(this);
|
||||
if(f != s_pendingConnectionSends.end())
|
||||
s_pendingConnectionSends.erase(f);
|
||||
|
||||
delete[] m_recvBuffer;
|
||||
if(m_socket != -1)
|
||||
close (m_socket);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
void TcpClient::addRef()
|
||||
{
|
||||
m_refCount++;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
std::string const &TcpClient::getRemoteAddress() const
|
||||
{
|
||||
return m_remoteAddress.getHostAddress();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
unsigned short TcpClient::getRemotePort() const
|
||||
{
|
||||
return m_remoteAddress.getHostPort();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
void TcpClient::setSockOptions()
|
||||
{
|
||||
int optval = 1;
|
||||
setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
||||
setsockopt(m_socket, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(optval));
|
||||
ioctl(m_socket, FIONBIO, &optval);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
|
||||
void TcpClient::commit()
|
||||
{
|
||||
int sent = 0;
|
||||
const unsigned char * ptr = m_pendingSend.getBuffer();
|
||||
const unsigned char * const end = ptr + m_pendingSend.getSize();
|
||||
static Archive::ByteStream s_localScratchBuffer;
|
||||
s_localScratchBuffer.clear();
|
||||
int retries = 0;
|
||||
static const int maxRetries = ConfigSharedNetwork::getMaxTCPRetries();
|
||||
bool sentSomething = false;
|
||||
|
||||
do
|
||||
{
|
||||
// attempt to push pending data to socket
|
||||
sent = ::send (m_socket, ptr, end - ptr, MSG_NOSIGNAL);
|
||||
if(sent == -1)
|
||||
{
|
||||
// failed
|
||||
switch(errno)
|
||||
{
|
||||
// because it would block on a non-blocking socket
|
||||
case EAGAIN:
|
||||
case ENOBUFS:
|
||||
case ENOMEM:
|
||||
case EINTR:
|
||||
{
|
||||
retries++;
|
||||
// requeue
|
||||
break;
|
||||
}
|
||||
// an unhandled error (connection reset, for example)
|
||||
default:
|
||||
{
|
||||
m_pendingSend.clear();
|
||||
perror("send: ");
|
||||
if (m_connection)
|
||||
m_connection->setDisconnectReason("TcpClient::commit send returned -1, errno=%d", errno);
|
||||
onConnectionClosed();
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(sent > 0)
|
||||
{
|
||||
sentSomething=true;
|
||||
ptr += sent;
|
||||
if(sent < end - ptr)
|
||||
{
|
||||
// data was passed to the socket, but not all
|
||||
// of it could be committed, keep trying!
|
||||
retries = 0;
|
||||
Os::sleep(1);
|
||||
}
|
||||
}
|
||||
else if(sent == 0)
|
||||
{
|
||||
// tried to send and got nothing through (should have returned an error, but be thorough)
|
||||
retries ++;
|
||||
Os::sleep(1);
|
||||
}
|
||||
|
||||
} while(ptr < end && retries < maxRetries);
|
||||
|
||||
if(ptr == end)
|
||||
{
|
||||
// all data was committed, clear pending buffer
|
||||
m_pendingSend.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
// bailed out before all data was committed, save unsent data for
|
||||
// next pass on commit()
|
||||
if (sentSomething)
|
||||
{
|
||||
s_localScratchBuffer.put(ptr, end - ptr);
|
||||
m_pendingSend.clear();
|
||||
m_pendingSend.put(s_localScratchBuffer.getBuffer(), s_localScratchBuffer.getSize());
|
||||
}
|
||||
s_pendingConnectionSends.insert(this);
|
||||
}
|
||||
|
||||
// clean up local accounting
|
||||
s_localScratchBuffer.clear();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
void TcpClient::flush()
|
||||
{
|
||||
if (m_connected && m_pendingSend.getSize() > 0)
|
||||
{
|
||||
// flush pending buffer
|
||||
commit();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void TcpClient::flushPendingWrites()
|
||||
{
|
||||
std::set<TcpClient *> sends = s_pendingConnectionSends;
|
||||
s_pendingConnectionSends.clear();
|
||||
|
||||
for (std::set<TcpClient *>::const_iterator i = sends.begin(); i != sends.end(); ++i)
|
||||
{
|
||||
TcpClient * const c = *i;
|
||||
|
||||
if (c->m_connected)
|
||||
{
|
||||
c->flush();
|
||||
|
||||
if ( c->m_connection
|
||||
&& c->m_pendingSend.getSize()
|
||||
&& ConfigSharedNetwork::getLogSendingTooMuchData()
|
||||
&& !dynamic_cast<NetLogConnection const *>(c->m_connection))
|
||||
{
|
||||
WARNING(true, ("(%s) Failed to commit %d bytes this frame to %s:%d. This process is sending more data than the remote can receive!", c->m_connection->getConnectionDescription().c_str(), c->m_pendingSend.getSize(), c->getRemoteAddress().c_str(), c->getRemotePort()));
|
||||
LOG("Network", ("(%s) Failed to commit %d bytes this frame to %s:%d. This process is sending more data than the remote can receive!", c->m_connection->getConnectionDescription().c_str(), c->m_pendingSend.getSize(), c->getRemoteAddress().c_str(), c->getRemotePort()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
unsigned short TcpClient::getBindPort() const
|
||||
{
|
||||
return m_bindPort;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
int TcpClient::getSocket() const
|
||||
{
|
||||
return m_socket;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
void TcpClient::install()
|
||||
{
|
||||
FATAL(s_installed, ("TcpClient is already installed!"));
|
||||
s_installed = true;
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
void TcpClient::onConnectionClosed()
|
||||
{
|
||||
if (m_connection)
|
||||
m_connection->setDisconnectReason("TcpClient::onConnectionClosed called");
|
||||
m_connected = false;
|
||||
shutdown(m_socket, SHUT_RDWR);
|
||||
if(m_tcpServer)
|
||||
{
|
||||
m_tcpServer->removeClient(this);
|
||||
}
|
||||
close(m_socket);
|
||||
m_socket = -1;
|
||||
if(m_connection)
|
||||
{
|
||||
NetworkHandler::onTerminate(m_connection);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
void TcpClient::onConnectionOpened()
|
||||
{
|
||||
// Get the local port this socket was bound to. If
|
||||
// a client socket repeatedly attempts to connect to a local
|
||||
// service that should be listening on a port that the operating
|
||||
// system may assign AND the service isn't actually running and
|
||||
// using the port, the client socket may connect to itself.
|
||||
// For example, A client connecting to 127.0.0.1:50005, the operating
|
||||
// system may assign the client socket port 50005 and the connection
|
||||
// succeeds, but it is in fact a connection to itself, meaning the
|
||||
// client isn't actually talking to any valid service.
|
||||
struct sockaddr_in bindAddr;
|
||||
socklen_t addrLen = sizeof(struct sockaddr_in);
|
||||
if(getsockname(m_socket, reinterpret_cast<struct sockaddr *>(&bindAddr), &addrLen) == 0)
|
||||
{
|
||||
m_bindPort = ntohs(bindAddr.sin_port);
|
||||
}
|
||||
|
||||
// this *might* be a valid connection to a remote address, but
|
||||
// to easily catch all cases of loopback connections, attempt a
|
||||
// reconnect if the remote port is identical to the local port
|
||||
if(m_remoteAddress.getHostPort() == m_bindPort && ! m_tcpServer)
|
||||
{
|
||||
shutdown(m_socket, SHUT_RDWR);
|
||||
DEBUG_FATAL(m_tcpServer, ("Detected a loopback client connection on a TCP SERVER!!!"));
|
||||
close(m_socket);
|
||||
m_socket = -1;
|
||||
|
||||
// reconnect the socket
|
||||
// address and port info is initialized in the constructor
|
||||
setupSocket();
|
||||
LOG("Network", ("Detected a loopback, closing socket and reconnecting"));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_connected = true;
|
||||
if(m_connection)
|
||||
{
|
||||
m_connection->onConnectionOpened();
|
||||
}
|
||||
flush();
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
void TcpClient::onReceive (const unsigned char * const recvBuf, const int bytes)
|
||||
{
|
||||
if(m_connection)
|
||||
{
|
||||
m_connection->receive(recvBuf, bytes);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
void TcpClient::queryConnect ()
|
||||
{
|
||||
struct pollfd pfd;
|
||||
pfd.fd = m_socket;
|
||||
pfd.events = POLLOUT;
|
||||
pfd.revents = 0;
|
||||
int pollResult = poll(&pfd, 1, 0);
|
||||
if(pollResult > 0)
|
||||
{
|
||||
if (pfd.revents & POLLERR)
|
||||
{
|
||||
if (m_connection)
|
||||
m_connection->setDisconnectReason("TcpClient::queryConnect POLLERR");
|
||||
onConnectionClosed();
|
||||
}
|
||||
else if (pfd.revents & POLLHUP)
|
||||
{
|
||||
if (m_connection)
|
||||
m_connection->setDisconnectReason("TcpClient::queryConnect POLLHUP");
|
||||
onConnectionClosed();
|
||||
}
|
||||
else
|
||||
{
|
||||
onConnectionOpened();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void TcpClient::release()
|
||||
{
|
||||
m_refCount--;
|
||||
if(m_refCount == 0)
|
||||
{
|
||||
if (m_connected)
|
||||
{
|
||||
if (m_connection)
|
||||
m_connection->setDisconnectReason("TcpClient::release called");
|
||||
onConnectionClosed();
|
||||
}
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void TcpClient::remove()
|
||||
{
|
||||
FATAL(!s_installed, ("TcpClient already removed!"));
|
||||
std::set<TcpClient *>::iterator i;
|
||||
for(i = s_tcpClients.begin(); i != s_tcpClients.end(); ++i)
|
||||
{
|
||||
TcpClient * c = (*i);
|
||||
c->release();
|
||||
}
|
||||
s_installed = false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
void TcpClient::send(const unsigned char * const buffer, const int bufferLen)
|
||||
{
|
||||
if (bufferLen)
|
||||
{
|
||||
m_lastSendTime = Clock::getFrameStartTimeMs();
|
||||
s_pendingConnectionSends.insert(this);
|
||||
if( !m_rawTCP )
|
||||
Archive::put(m_pendingSend, bufferLen);
|
||||
m_pendingSend.put(buffer, bufferLen);
|
||||
|
||||
static int const tcpMinimumFrame = ConfigSharedNetwork::getTcpMinimumFrame();
|
||||
if (static_cast<int>(m_pendingSend.getSize()) >= tcpMinimumFrame)
|
||||
flush();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void TcpClient::setConnection(Connection * c)
|
||||
{
|
||||
m_connection = c;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
void TcpClient::checkKeepalive()
|
||||
{
|
||||
if (m_connected)
|
||||
{
|
||||
unsigned long const timeNow = Clock::getFrameStartTimeMs();
|
||||
if (timeNow-m_lastSendTime > KEEPALIVE_MS)
|
||||
{
|
||||
m_lastSendTime = timeNow;
|
||||
s_pendingConnectionSends.insert(this);
|
||||
Archive::put(m_pendingSend, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
void TcpClient::update()
|
||||
{
|
||||
addRef();
|
||||
if(!m_connected)
|
||||
{
|
||||
queryConnect();
|
||||
}
|
||||
|
||||
if(m_connected)
|
||||
{
|
||||
struct pollfd pfd;
|
||||
pfd.fd = m_socket;
|
||||
pfd.events = POLLIN|POLLHUP;
|
||||
pfd.revents = 0;
|
||||
int pollResult = poll (&pfd, 1, 0);
|
||||
// POLLERR is mutually exclusive with POLLIN and POLLHUP.
|
||||
// POLLIN and POLLHUP are not consistent cross-platform. Additionally,
|
||||
// a POLLHUP doesn't mean that there's not data available. The best,
|
||||
// cross-platform way to check for disconnection is to see if either
|
||||
// POLLHUP or POLLIN are set, and then read from the socket.
|
||||
// In cases where there's data, we'll just end up checking it next
|
||||
// frame anyway. In cases where there's no data, it means we've
|
||||
// disconnected so we can handle cleanup.
|
||||
if (pollResult)
|
||||
{
|
||||
if (m_recvBuffer == NULL)
|
||||
{
|
||||
m_recvBufferLength = 1500;
|
||||
m_recvBuffer = new unsigned char [m_recvBufferLength];
|
||||
}
|
||||
int bytesReceived = recv(m_socket, m_recvBuffer, m_recvBufferLength, 0);
|
||||
if (bytesReceived > 0)
|
||||
{
|
||||
onReceive(m_recvBuffer, bytesReceived);
|
||||
}
|
||||
else if (bytesReceived == -1)
|
||||
{
|
||||
switch (errno)
|
||||
{
|
||||
case EAGAIN:
|
||||
case EINTR:
|
||||
break;
|
||||
default:
|
||||
if (m_connection)
|
||||
m_connection->setDisconnectReason("TcpClient::update recv returned -1, errno=%d", errno);
|
||||
onConnectionClosed();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
else if (bytesReceived == 0)
|
||||
{
|
||||
// peer closed connection
|
||||
|
||||
|
||||
|
||||
if (m_connection)
|
||||
{
|
||||
// Log this, as it's a pretty deep change.
|
||||
LOG("Network", ("(%s) Read zero bytes on a successful poll (POLLIN|POLLHUP). Closing socket since we think it is closed.", m_connection->getConnectionDescription().c_str()));
|
||||
m_connection->setDisconnectReason("TcpClient::update recv returned 0");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG("Network", ("(null connection object) Read zero bytes on a successful poll (POLLIN|POLLHUP). Closing socket since we think it is closed."));
|
||||
}
|
||||
onConnectionClosed();
|
||||
}
|
||||
|
||||
if (bytesReceived == m_recvBufferLength)
|
||||
{
|
||||
// grow the buffer
|
||||
delete [] m_recvBuffer;
|
||||
m_recvBufferLength = m_recvBufferLength * 2;
|
||||
m_recvBuffer = new unsigned char [m_recvBufferLength];
|
||||
}
|
||||
}
|
||||
}
|
||||
release();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void TcpClient::setupSocket()
|
||||
{
|
||||
FATAL(! s_installed, ("TcpClient is not installed!"));
|
||||
|
||||
protoent * p = getprotobyname ("tcp");
|
||||
const int entry = p->p_proto;
|
||||
m_socket = socket (AF_INET, SOCK_STREAM, entry);
|
||||
if (m_socket != -1)
|
||||
{
|
||||
setSockOptions();
|
||||
|
||||
int nameLen = sizeof (struct sockaddr_in);
|
||||
int result;
|
||||
result = connect (m_socket, reinterpret_cast<const struct sockaddr *> (&m_remoteAddress.getSockAddr4 () ), nameLen);
|
||||
if(result == -1)
|
||||
{
|
||||
switch(errno)
|
||||
{
|
||||
case EINPROGRESS:
|
||||
case EALREADY:
|
||||
break;
|
||||
default:
|
||||
perror("connect ");
|
||||
if (m_connection)
|
||||
m_connection->setDisconnectReason("TcpClient::TcpClient connect returned -1, errno=%d", errno);
|
||||
onConnectionClosed();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
struct sockaddr_in bindAddr;
|
||||
socklen_t addrLen = sizeof(struct sockaddr_in);
|
||||
if(getsockname(m_socket, reinterpret_cast<struct sockaddr *>(&bindAddr), &addrLen) == 0)
|
||||
{
|
||||
m_bindPort = ntohs(bindAddr.sin_port);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
void TcpClient::setRawTCP( bool bNewValue )
|
||||
{
|
||||
m_rawTCP = bNewValue;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void TcpClient::clearTcpServer()
|
||||
{
|
||||
m_tcpServer = 0;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
// TcpClient.h
|
||||
// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved.
|
||||
// Author: Justin Randall
|
||||
|
||||
#ifndef _INCLUDED_TcpClient_H
|
||||
#define _INCLUDED_TcpClient_H
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#include "Archive/ByteStream.h"
|
||||
#include "sharedNetwork/Address.h"
|
||||
#include <string>
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
class Connection;
|
||||
class TcpServer;
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
class TcpClient
|
||||
{
|
||||
public:
|
||||
TcpClient(int sock, TcpServer *);
|
||||
TcpClient(const std::string & address, const unsigned short port);
|
||||
|
||||
void addRef();
|
||||
static void install();
|
||||
void release();
|
||||
static void remove();
|
||||
void send(const unsigned char * const buffer, const int length);
|
||||
|
||||
unsigned short getBindPort() const;
|
||||
std::string const &getRemoteAddress() const;
|
||||
unsigned short getRemotePort() const;
|
||||
void setPendingSendAllocatedSizeLimit(unsigned int limit);
|
||||
|
||||
// only used by clients
|
||||
void update();
|
||||
static void flushPendingWrites();
|
||||
|
||||
protected:
|
||||
friend class TcpServer;
|
||||
friend class Connection;
|
||||
|
||||
void setSockOptions();
|
||||
void commit();
|
||||
int getSocket() const;
|
||||
void onConnectionClosed();
|
||||
void onConnectionOpened();
|
||||
void onReceive(const unsigned char * const recvBuf, const int bytes);
|
||||
void queryConnect();
|
||||
void queueReceive();
|
||||
void setConnection(Connection *);
|
||||
void checkKeepalive();
|
||||
void clearTcpServer();
|
||||
void setRawTCP( bool bNewValue );
|
||||
|
||||
private:
|
||||
TcpClient & operator = (const TcpClient & rhs);
|
||||
TcpClient(const TcpClient & source);
|
||||
~TcpClient();
|
||||
void flush ();
|
||||
void setupSocket();
|
||||
int m_socket;
|
||||
TcpServer * m_tcpServer;
|
||||
Archive::ByteStream m_pendingSend;
|
||||
Connection * m_connection;
|
||||
unsigned char * m_recvBuffer;
|
||||
int m_recvBufferLength;
|
||||
Address m_remoteAddress;
|
||||
int m_refCount;
|
||||
bool m_connected;
|
||||
unsigned long m_lastSendTime;
|
||||
unsigned short m_bindPort;
|
||||
bool m_rawTCP;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
inline void TcpClient::setPendingSendAllocatedSizeLimit(const unsigned int limit)
|
||||
{
|
||||
m_pendingSend.setAllocatedSizeLimit(limit);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#endif // _INCLUDED_TcpClient_H
|
||||
|
||||
@@ -1,238 +0,0 @@
|
||||
// TcpServer.cpp
|
||||
// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved.
|
||||
// Author: Justin Randall
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
#include "sharedNetwork/FirstSharedNetwork.h"
|
||||
#include "TcpServer.h"
|
||||
|
||||
#include "sharedNetwork/Connection.h"
|
||||
#include "sharedNetwork/Service.h"
|
||||
#include "TcpClient.h"
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <netdb.h>
|
||||
#include <vector>
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
TcpServer::TcpServer(Service * service, const std::string & a, const unsigned short port) :
|
||||
m_bindAddress(a, port),
|
||||
m_handle(-1),
|
||||
m_service(service),
|
||||
m_connections(),
|
||||
m_connectionSockets(),
|
||||
m_inputBuffer(0),
|
||||
m_inputBufferSize(0)
|
||||
{
|
||||
protoent * p = getprotobyname("tcp");
|
||||
if(p)
|
||||
{
|
||||
int entry = p->p_proto;
|
||||
m_handle = socket(AF_INET, SOCK_STREAM, entry);
|
||||
FATAL(m_handle == -1, ("Failed to create a server socket %s:%d", a.c_str(), port));
|
||||
int optval = 1;
|
||||
if(m_handle != -1)
|
||||
{
|
||||
int optResult = setsockopt(m_handle, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
||||
FATAL(optResult == -1, ("Failed to set socket option SO_REUSEADDR"));
|
||||
unsigned long nb = 1;
|
||||
int ctlResult = ioctl(m_handle, FIONBIO, &nb);
|
||||
FATAL(ctlResult == -1, ("Failed to set socket non-blocking"));
|
||||
socklen_t addrlen = sizeof(struct sockaddr_in);
|
||||
int bindResult = bind(m_handle, (struct sockaddr *)(&m_bindAddress.getSockAddr4()), addrlen);
|
||||
FATAL(bindResult != 0, ("Failed to bind to port %d", port));
|
||||
if(bindResult == 0)
|
||||
{
|
||||
int result = listen(m_handle, 256);
|
||||
if(result == -1)
|
||||
perror("listen ");
|
||||
FATAL(result == -1, ("Failed to start listening on port %d", port));
|
||||
struct sockaddr_in b;
|
||||
getsockname(m_handle, (struct sockaddr *)(&b), &addrlen);
|
||||
m_bindAddress = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
TcpServer::~TcpServer()
|
||||
{
|
||||
close(m_handle);
|
||||
for (std::map<int, TcpClient *>::const_iterator i = m_connections.begin(); i != m_connections.end(); ++i)
|
||||
(*i).second->clearTcpServer();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
const std::string & TcpServer::getBindAddress() const
|
||||
{
|
||||
return m_bindAddress.getHostAddress();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
const unsigned short TcpServer::getBindPort() const
|
||||
{
|
||||
return m_bindAddress.getHostPort();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
void TcpServer::onConnectionClosed(TcpClient * c)
|
||||
{
|
||||
if(c)
|
||||
{
|
||||
std::set<TcpClient *>::iterator f = m_pendingDestroys.find(c);
|
||||
if(f == m_pendingDestroys.end())
|
||||
{
|
||||
m_pendingDestroys.insert(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
void TcpServer::removeClient(TcpClient * c)
|
||||
{
|
||||
std::map<int, TcpClient *>::iterator f = m_connections.find(c->getSocket());
|
||||
if(f != m_connections.end())
|
||||
{
|
||||
// c->release();
|
||||
m_connections.erase(f);
|
||||
}
|
||||
|
||||
std::vector<pollfd>::iterator s;
|
||||
for(s = m_connectionSockets.begin(); s != m_connectionSockets.end(); ++s)
|
||||
{
|
||||
if((*s).fd == c->getSocket())
|
||||
{
|
||||
m_connectionSockets.erase(s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
void TcpServer::update()
|
||||
{
|
||||
struct pollfd pfd;
|
||||
pfd.fd = m_handle;
|
||||
pfd.events = POLLIN;
|
||||
pfd.revents = 0;
|
||||
|
||||
int result = poll(&pfd, 1, 0);
|
||||
if(result > 0)
|
||||
{
|
||||
// connection established
|
||||
struct sockaddr_in addr;
|
||||
socklen_t len = sizeof(struct sockaddr_in);
|
||||
int newSock = accept(m_handle, (struct sockaddr *)(&addr), &len);
|
||||
if(newSock != -1)
|
||||
{
|
||||
TcpClient * ptc = new TcpClient(newSock, this);
|
||||
ptc->addRef();
|
||||
m_connections.insert(std::make_pair(newSock, ptc));
|
||||
struct pollfd readFd;
|
||||
readFd.fd = ptc->getSocket();
|
||||
readFd.events = POLLIN|POLLERR|POLLHUP;
|
||||
readFd.revents = 0;
|
||||
m_connectionSockets.push_back(readFd);
|
||||
ptc->onConnectionOpened();
|
||||
if(m_service)
|
||||
m_service->onConnectionOpened(ptc);
|
||||
ptc->release();
|
||||
}
|
||||
}
|
||||
|
||||
struct pollfd * clients = &m_connectionSockets[0];
|
||||
|
||||
int readResult = poll (clients, m_connectionSockets.size (), 0);
|
||||
if (readResult > 0)
|
||||
{
|
||||
std::vector<struct pollfd>::iterator i;
|
||||
std::vector<struct pollfd> cs = m_connectionSockets;
|
||||
for (i = cs.begin (); i != cs.end (); ++i)
|
||||
{
|
||||
if ((*i).revents & POLLERR)
|
||||
{
|
||||
std::map<int, TcpClient *>::iterator f = m_connections.find ( (*i).fd );
|
||||
if (f != m_connections.end ())
|
||||
{
|
||||
TcpClient * c = (*f).second;
|
||||
if (c->m_connection)
|
||||
c->m_connection->setDisconnectReason("TcpServer::update POLLERR");
|
||||
c->onConnectionClosed();
|
||||
}
|
||||
}
|
||||
// POLLERR is mutually exclusive with POLLIN and POLLHUP.
|
||||
// POLLIN and POLLHUP are not consistent cross-platform. Additionally,
|
||||
// a POLLHUP doesn't mean that there's not data available. The best,
|
||||
// cross-platform way to check for disconnection is to see if either
|
||||
// POLLHUP or POLLIN are set, and then read from the socket.
|
||||
// In cases where there's data, we'll just end up checking it next
|
||||
// frame anyway. In cases where there's no data, it means we've
|
||||
// disconnected so we can handle cleanup.
|
||||
else if( (*i).revents & (POLLIN|POLLHUP) )
|
||||
{
|
||||
|
||||
if (m_inputBuffer == 0)
|
||||
{
|
||||
m_inputBuffer = new unsigned char[1500];
|
||||
m_inputBufferSize = 1500;
|
||||
}
|
||||
int bytesReceived = recv ( (*i).fd, m_inputBuffer, m_inputBufferSize, 0);
|
||||
std::map<int, TcpClient *>::iterator f = m_connections.find ( (*i).fd );
|
||||
if (f != m_connections.end ())
|
||||
{
|
||||
TcpClient * c = (*f).second;
|
||||
std::set<TcpClient *>::iterator pd = m_pendingDestroys.find(c);
|
||||
if(pd == m_pendingDestroys.end())
|
||||
{
|
||||
c->addRef();
|
||||
if(bytesReceived > 0)
|
||||
{
|
||||
c->onReceive(m_inputBuffer, bytesReceived);
|
||||
}
|
||||
else if (bytesReceived == -1)
|
||||
{
|
||||
if (c->m_connection)
|
||||
c->m_connection->setDisconnectReason("TcpServer::update recv returned %d, errno=%d", bytesReceived, errno);
|
||||
c->onConnectionClosed();
|
||||
}
|
||||
else if (bytesReceived == 0)
|
||||
{
|
||||
// 0 bytes received on a read is the guaranteed signal for a
|
||||
// closed connection.
|
||||
if (c->m_connection)
|
||||
c->m_connection->setDisconnectReason("TcpServer::update recv returned no bytes, singaling a closed socket (bytes=%d, errno=%d", bytesReceived, errno);
|
||||
c->onConnectionClosed();
|
||||
}
|
||||
c->release();
|
||||
}
|
||||
}
|
||||
if (bytesReceived == m_inputBufferSize)
|
||||
{
|
||||
delete [] m_inputBuffer;
|
||||
m_inputBufferSize = m_inputBufferSize * 2;
|
||||
m_inputBuffer = new unsigned char [m_inputBufferSize];
|
||||
}
|
||||
}
|
||||
}
|
||||
std::set<TcpClient *>::iterator pdIter;
|
||||
for(pdIter = m_pendingDestroys.begin(); pdIter != m_pendingDestroys.end(); ++pdIter)
|
||||
{
|
||||
removeClient((*pdIter));
|
||||
}
|
||||
m_pendingDestroys.clear();
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
// TcpServer.h
|
||||
// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved.
|
||||
// Author: Justin Randall
|
||||
|
||||
#ifndef _INCLUDED_TcpServer_H
|
||||
#define _INCLUDED_TcpServer_H
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#include "Address.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
class Service;
|
||||
class TcpClient;
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
class TcpServer
|
||||
{
|
||||
public:
|
||||
TcpServer(Service * service, const std::string & bindAddress, const unsigned short bindPort);
|
||||
~TcpServer();
|
||||
|
||||
const std::string & getBindAddress () const;
|
||||
const unsigned short getBindPort () const;
|
||||
void onConnectionClosed (TcpClient *);
|
||||
void removeClient (TcpClient *);
|
||||
void update ();
|
||||
|
||||
private:
|
||||
TcpServer & operator = (const TcpServer & rhs);
|
||||
TcpServer(const TcpServer & source);
|
||||
|
||||
private:
|
||||
Address m_bindAddress;
|
||||
int m_handle;
|
||||
Service * m_service;
|
||||
std::map<int, TcpClient *> m_connections;
|
||||
std::vector<struct pollfd> m_connectionSockets;
|
||||
unsigned char * m_inputBuffer;
|
||||
int m_inputBufferSize;
|
||||
std::set<TcpClient *> m_pendingDestroys;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#endif // _INCLUDED_TcpServer_H
|
||||
@@ -1,63 +0,0 @@
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
#include "FirstSharedNetwork.h"
|
||||
#include <cassert>
|
||||
#include <netdb.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include "sharedNetwork/UdpSock.h"
|
||||
|
||||
const int INVALID_SOCKET = 0xFFFFFFFF;
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
UdpSock::UdpSock() :
|
||||
Sock()
|
||||
{
|
||||
handle = socket(AF_INET, SOCK_DGRAM, 17);
|
||||
assert(handle != INVALID_SOCKET);
|
||||
setNonBlocking();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
UdpSock::~UdpSock()
|
||||
{
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
const unsigned int UdpSock::recvFrom(Address & outAddr, void * targetBuffer, const unsigned int bufferSize) const
|
||||
{
|
||||
socklen_t fromLen = sizeof(struct sockaddr_in);
|
||||
struct sockaddr_in addr;
|
||||
unsigned int result = ::recvfrom(handle, static_cast<char *>(targetBuffer), static_cast<int>(bufferSize), 0, reinterpret_cast<struct sockaddr *>(&addr), &fromLen); //lint !e732 // MS wants an int, should be unsigned IMO
|
||||
outAddr = addr;
|
||||
return result;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
const unsigned int UdpSock::sendTo(const Address & targetAddress, const void * sourceBuffer, const unsigned int length) const
|
||||
{
|
||||
unsigned int bytesSent = 0;
|
||||
if(canSend())
|
||||
{
|
||||
socklen_t toLen = sizeof(struct sockaddr_in);
|
||||
bytesSent = ::sendto(handle, sourceBuffer, static_cast<const int>(length), 0, reinterpret_cast<const struct sockaddr *>(&(targetAddress.getSockAddr4())), toLen); //lint !e732 // MS wants an int, should be unsigned IMO
|
||||
}
|
||||
return bytesSent;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void UdpSock::enableBroadcast()
|
||||
{
|
||||
int optval = 1;
|
||||
socklen_t optlen = sizeof(int);
|
||||
setsockopt(handle, SOL_SOCKET, SO_BROADCAST, &optval, optlen);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// RegexServices.cpp
|
||||
// Copyright 2003 Sony Online Entertainment, Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedRegex/FirstSharedRegex.h"
|
||||
#include "sharedRegex/RegexServices.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
void *RegexServices::allocateMemory(size_t byteCount)
|
||||
{
|
||||
return new char[byteCount];
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void RegexServices::freeMemory(void *pointer)
|
||||
{
|
||||
delete [] reinterpret_cast<char *>(pointer);
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -1,25 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// RegexServices.h
|
||||
// Copyright 2003 Sony Online Entertainment, Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_RegexServices_H
|
||||
#define INCLUDED_RegexServices_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class RegexServices
|
||||
{
|
||||
public:
|
||||
|
||||
static void *allocateMemory(size_t byteCount);
|
||||
static void freeMemory(void *pointer);
|
||||
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -1,38 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ConditionVariable.cpp
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedSynchronization/ConditionVariable.h"
|
||||
|
||||
ConditionVariable::ConditionVariable(Mutex &m)
|
||||
: _mutex(m)
|
||||
{
|
||||
pthread_cond_init(&cond, 0);
|
||||
}
|
||||
|
||||
ConditionVariable::~ConditionVariable()
|
||||
{
|
||||
pthread_cond_destroy(&cond);
|
||||
}
|
||||
|
||||
void ConditionVariable::wait()
|
||||
{
|
||||
pthread_cond_wait(&cond, &_mutex.getInternalMutex());
|
||||
}
|
||||
|
||||
void ConditionVariable::signal()
|
||||
{
|
||||
pthread_cond_signal(&cond);
|
||||
}
|
||||
|
||||
void ConditionVariable::broadcast()
|
||||
{
|
||||
pthread_cond_broadcast(&cond);
|
||||
}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ConditionVariable.h
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_ConditionVariable_h
|
||||
#define INCLUDED_ConditionVariable_h
|
||||
|
||||
#include "sharedSynchronization/Mutex.h"
|
||||
|
||||
class ConditionVariable
|
||||
{
|
||||
public:
|
||||
ConditionVariable(Mutex &m);
|
||||
~ConditionVariable();
|
||||
void wait();
|
||||
// You must own the mutex before calling signal.
|
||||
void signal();
|
||||
void broadcast();
|
||||
Mutex &mutex() { return _mutex; }
|
||||
private:
|
||||
ConditionVariable(const ConditionVariable &o);
|
||||
ConditionVariable &operator =(const ConditionVariable &o);
|
||||
|
||||
Mutex &_mutex;
|
||||
pthread_cond_t cond;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,45 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Gate.cpp
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedSynchronization/Gate.h"
|
||||
|
||||
Gate::Gate(bool open)
|
||||
: cond(lock)
|
||||
{
|
||||
opened = open;
|
||||
}
|
||||
|
||||
Gate::~Gate()
|
||||
{
|
||||
}
|
||||
|
||||
void Gate::wait()
|
||||
{
|
||||
lock.enter();
|
||||
while (!opened)
|
||||
cond.wait();
|
||||
lock.leave();
|
||||
}
|
||||
|
||||
void Gate::close()
|
||||
{
|
||||
lock.enter();
|
||||
opened = false;
|
||||
lock.leave();
|
||||
}
|
||||
|
||||
void Gate::open()
|
||||
{
|
||||
lock.enter();
|
||||
opened = true;
|
||||
cond.broadcast();
|
||||
lock.leave();
|
||||
}
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Gate.h
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_Gate_h
|
||||
#define INCLUDED_Gate_h
|
||||
|
||||
#include "sharedSynchronization/ConditionVariable.h"
|
||||
|
||||
class Gate
|
||||
{
|
||||
public:
|
||||
Gate(bool open);
|
||||
~Gate();
|
||||
|
||||
void wait();
|
||||
|
||||
void close();
|
||||
void open();
|
||||
private:
|
||||
Gate(const Gate &o);
|
||||
Gate &operator =(const Gate &o);
|
||||
|
||||
Mutex lock;
|
||||
bool opened;
|
||||
ConditionVariable cond;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,63 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// InterlockedInteger.h
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_InterlockedInteger_h
|
||||
#define INCLUDED_InterlockedInteger_h
|
||||
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
class InterlockedInteger
|
||||
{
|
||||
public:
|
||||
explicit InterlockedInteger(int initialValue=0);
|
||||
int operator =(int); // returns prior value (exchange)
|
||||
int operator ++(); // returns new value
|
||||
int operator --(); // returns new value
|
||||
operator int() const { return value; }
|
||||
private:
|
||||
InterlockedInteger(const InterlockedInteger &o);
|
||||
InterlockedInteger &operator =(const InterlockedInteger &o);
|
||||
pthread_mutex_t lock;
|
||||
volatile int value;
|
||||
};
|
||||
|
||||
inline InterlockedInteger::InterlockedInteger(int i_value)
|
||||
: value(i_value)
|
||||
{
|
||||
pthread_mutex_init(&lock, 0);
|
||||
}
|
||||
|
||||
inline int InterlockedInteger::operator =(int i_value)
|
||||
{
|
||||
pthread_mutex_lock(&lock);
|
||||
int oldvalue = value;
|
||||
value = i_value;
|
||||
pthread_mutex_unlock(&lock);
|
||||
return oldvalue;
|
||||
}
|
||||
|
||||
inline int InterlockedInteger::operator ++()
|
||||
{
|
||||
pthread_mutex_lock(&lock);
|
||||
int newvalue = value+1;
|
||||
value = newvalue;
|
||||
pthread_mutex_unlock(&lock);
|
||||
return newvalue;
|
||||
}
|
||||
|
||||
inline int InterlockedInteger::operator --()
|
||||
{
|
||||
pthread_mutex_lock(&lock);
|
||||
int newvalue = value-1;
|
||||
value = newvalue;
|
||||
pthread_mutex_unlock(&lock);
|
||||
return newvalue;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,53 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// InterlockedVoidPointer.h
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_InterlockedVoidPointer_h
|
||||
#define INCLUDED_InterlockedVoidPointer_h
|
||||
|
||||
#include "sharedSynchronization/Mutex.h"
|
||||
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
class InterlockedVoidPointer
|
||||
{
|
||||
public:
|
||||
explicit InterlockedVoidPointer(void * initialValue=0);
|
||||
void * compareExchange(void * compare, void * exchange); // compare and exchange if same
|
||||
operator void * () const { return reinterpret_cast<void *>(value); }
|
||||
private:
|
||||
InterlockedVoidPointer(const InterlockedVoidPointer &o);
|
||||
InterlockedVoidPointer &operator =(const InterlockedVoidPointer &o);
|
||||
Mutex lock;
|
||||
void * volatile value;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class InterlockedPointer: public InterlockedVoidPointer
|
||||
{
|
||||
public:
|
||||
explicit InterlockedPointer(T * initialValue): InterlockedVoidPointer(initialValue) {}
|
||||
operator T * () const { return static_cast<const T *>(value); }
|
||||
};
|
||||
|
||||
inline InterlockedVoidPointer::InterlockedVoidPointer(void * initialValue)
|
||||
: value(initialValue)
|
||||
{
|
||||
}
|
||||
|
||||
inline void * InterlockedVoidPointer::compareExchange(void * compare, void * exchange)
|
||||
{
|
||||
lock.enter();
|
||||
void * temp = value;
|
||||
if (temp == compare)
|
||||
value = exchange;
|
||||
lock.leave();
|
||||
return temp;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,32 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Mutex.cpp
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedSynchronization/Mutex.h"
|
||||
|
||||
Mutex::Mutex()
|
||||
{
|
||||
pthread_mutex_init(&mutex, 0);
|
||||
}
|
||||
|
||||
Mutex::~Mutex()
|
||||
{
|
||||
pthread_mutex_destroy(&mutex);
|
||||
}
|
||||
|
||||
void Mutex::enter()
|
||||
{
|
||||
pthread_mutex_lock(&mutex);
|
||||
}
|
||||
|
||||
void Mutex::leave()
|
||||
{
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Mutex.h
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_Mutex_h
|
||||
#define INCLUDED_Mutex_h
|
||||
|
||||
class Mutex
|
||||
{
|
||||
public:
|
||||
Mutex();
|
||||
~Mutex();
|
||||
|
||||
void enter();
|
||||
void leave();
|
||||
|
||||
pthread_mutex_t &getInternalMutex() { return mutex; }
|
||||
private:
|
||||
Mutex(const Mutex &o);
|
||||
Mutex &operator =(const Mutex &o);
|
||||
|
||||
pthread_mutex_t mutex;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,37 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// RecursiveMutex.cpp
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedSynchronization/RecursiveMutex.h"
|
||||
|
||||
RecursiveMutex::RecursiveMutex()
|
||||
{
|
||||
pthread_mutexattr_t attributes;
|
||||
|
||||
pthread_mutexattr_init(&attributes);
|
||||
pthread_mutexattr_settype(&attributes,PTHREAD_MUTEX_RECURSIVE);
|
||||
pthread_mutex_init(&mutex,&attributes);
|
||||
pthread_mutexattr_destroy(&attributes);
|
||||
}
|
||||
|
||||
RecursiveMutex::~RecursiveMutex()
|
||||
{
|
||||
pthread_mutex_destroy(&mutex);
|
||||
}
|
||||
|
||||
void RecursiveMutex::enter()
|
||||
{
|
||||
pthread_mutex_lock(&mutex);
|
||||
}
|
||||
|
||||
void RecursiveMutex::leave()
|
||||
{
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// RecursiveMutex.h
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_RecursiveMutex_h
|
||||
#define INCLUDED_RecursiveMutex_h
|
||||
|
||||
#include "sharedSynchronization/InterlockedInteger.h"
|
||||
|
||||
class RecursiveMutex
|
||||
{
|
||||
public:
|
||||
RecursiveMutex();
|
||||
~RecursiveMutex();
|
||||
|
||||
void enter();
|
||||
void leave();
|
||||
private:
|
||||
RecursiveMutex(const RecursiveMutex &o);
|
||||
RecursiveMutex &operator =(const RecursiveMutex &o);
|
||||
|
||||
pthread_mutex_t mutex;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Semaphore.cpp
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedSynchronization/Semaphore.h"
|
||||
|
||||
Semaphore::Semaphore(int count, int initial)
|
||||
{
|
||||
sem_init(&sem, false, initial);
|
||||
}
|
||||
|
||||
Semaphore::~Semaphore()
|
||||
{
|
||||
sem_destroy(&sem);
|
||||
}
|
||||
|
||||
void Semaphore::wait()
|
||||
{
|
||||
sem_wait(&sem);
|
||||
}
|
||||
|
||||
void Semaphore::wait(unsigned int maxDurationMs)
|
||||
{
|
||||
timespec ts;
|
||||
ts.tv_sec = maxDurationMs/1000000;
|
||||
ts.tv_nsec = maxDurationMs%1000000;
|
||||
sem_timedwait(&sem, &ts);
|
||||
}
|
||||
|
||||
void Semaphore::signal(int count)
|
||||
{
|
||||
sem_post(&sem);
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Semaphore.h
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_Semaphore_h
|
||||
#define INCLUDED_Semaphore_h
|
||||
|
||||
class Semaphore
|
||||
{
|
||||
public:
|
||||
Semaphore(int count=0x7FFFFFFF, int initial=0);
|
||||
~Semaphore();
|
||||
|
||||
void wait();
|
||||
void wait(unsigned int maxDurationMs);
|
||||
void signal(int count=1);
|
||||
private:
|
||||
Semaphore(const Semaphore &o);
|
||||
Semaphore &operator =(const Semaphore &o);
|
||||
|
||||
sem_t sem;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
#include "sharedTemplateDefinition/FirstSharedTemplateDefinition.h"
|
||||
@@ -1,159 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Thread.cpp
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedThread/Thread.h"
|
||||
|
||||
#include "sharedFoundation/ExitChain.h"
|
||||
#include "sharedFoundation/Os.h"
|
||||
#include "sharedFoundation/PerThreadData.h"
|
||||
#include <cstdio>
|
||||
|
||||
class MainThread: public Thread
|
||||
{
|
||||
public:
|
||||
MainThread(const std::string &name): Thread(name) {}
|
||||
protected:
|
||||
void run() {}
|
||||
private:
|
||||
MainThread(const MainThread &o);
|
||||
MainThread &operator =(const MainThread &o);
|
||||
};
|
||||
|
||||
pthread_key_t Thread::implindex;
|
||||
Thread * Thread::mainThread;
|
||||
|
||||
void Thread::install()
|
||||
{
|
||||
DEBUG_FATAL(mainThread, ("Thread::install: already installed"));
|
||||
ExitChain::add(remove, "Thread::remove");
|
||||
|
||||
pthread_key_create(&implindex, 0);
|
||||
mainThread = new MainThread("Main");
|
||||
mainThread->attach();
|
||||
}
|
||||
|
||||
void Thread::remove()
|
||||
{
|
||||
DEBUG_FATAL(!mainThread, ("Thread::remove: not installed"));
|
||||
DEBUG_FATAL(mainThread->refcount > 1, ("Someone still holds the main thread"));
|
||||
delete mainThread;
|
||||
pthread_key_delete(implindex);
|
||||
|
||||
mainThread = 0;
|
||||
}
|
||||
|
||||
Thread::Thread(const std::string &i_name)
|
||||
: refcount(1), name(i_name)
|
||||
{
|
||||
doneFlag = false;
|
||||
}
|
||||
|
||||
void Thread::start()
|
||||
{
|
||||
pthread_create(&thread, 0, threadFunc, this);
|
||||
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
|
||||
}
|
||||
|
||||
void Thread::attach()
|
||||
{
|
||||
thread = pthread_self();
|
||||
pthread_setspecific(implindex, this);
|
||||
}
|
||||
|
||||
Thread::~Thread()
|
||||
{
|
||||
pthread_detach(thread);
|
||||
}
|
||||
|
||||
void * Thread::threadFunc(void * i)
|
||||
{
|
||||
Thread * impl = static_cast<Thread *>(i);
|
||||
pthread_setspecific(implindex, impl);
|
||||
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
|
||||
Os::setThreadName(impl->thread, impl->name.c_str());
|
||||
PerThreadData::threadInstall(true);
|
||||
impl->run();
|
||||
PerThreadData::threadRemove();
|
||||
impl->kill();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Thread::kill()
|
||||
{
|
||||
int t = getCurrentThread()->thread;
|
||||
doneFlag = true;
|
||||
deref();
|
||||
if (this == getCurrentThread())
|
||||
{
|
||||
pthread_exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
pthread_cancel(t);
|
||||
}
|
||||
}
|
||||
|
||||
bool Thread::done()
|
||||
{
|
||||
return doneFlag;
|
||||
}
|
||||
|
||||
void Thread::wait()
|
||||
{
|
||||
if (!doneFlag)
|
||||
{
|
||||
void * junk;
|
||||
pthread_join(thread, &junk);
|
||||
}
|
||||
}
|
||||
|
||||
static inline int interpPriority(float t, int policy)
|
||||
{
|
||||
return (int)(sched_get_priority_max(policy)*t + sched_get_priority_min(policy)*(1-t));
|
||||
}
|
||||
|
||||
void Thread::setPriority(ePriority priority)
|
||||
{
|
||||
static int policies[] =
|
||||
{
|
||||
SCHED_OTHER,
|
||||
SCHED_OTHER,
|
||||
SCHED_OTHER,
|
||||
SCHED_OTHER,
|
||||
SCHED_FIFO
|
||||
};
|
||||
static int priorities[] =
|
||||
{
|
||||
interpPriority(0.0, SCHED_OTHER),
|
||||
interpPriority(0.25, SCHED_OTHER),
|
||||
interpPriority(0.5, SCHED_OTHER),
|
||||
interpPriority(0.75, SCHED_OTHER),
|
||||
interpPriority(0.75, SCHED_FIFO)
|
||||
};
|
||||
sched_param p;
|
||||
p.sched_priority = priorities[priority];
|
||||
pthread_setschedparam(thread, policies[priority], &p);
|
||||
}
|
||||
|
||||
// Make sure the header-only files compile :)
|
||||
|
||||
#if 0
|
||||
|
||||
#include "sharedSynchronization/CountingSemaphore.h"
|
||||
#include "sharedSynchronization/BlockingPointer.h"
|
||||
#include "sharedSynchronization/BlockingQueue.h"
|
||||
#include "sharedSynchronization/WriteOnce.h"
|
||||
|
||||
Mutex t;
|
||||
BlockingQueue<int> bqint(t, 0, 0);
|
||||
BlockingPointer<int> bpint(t, 0, 0);
|
||||
WriteOnce<int> woint;
|
||||
|
||||
#endif
|
||||
@@ -1,100 +0,0 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Thread.h
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_Thread_h
|
||||
#define INCLUDED_Thread_h
|
||||
|
||||
#include "sharedSynchronization/InterlockedInteger.h"
|
||||
#include <string>
|
||||
|
||||
class Thread
|
||||
{
|
||||
template <class T> friend class TypedThreadHandle;
|
||||
public:
|
||||
static void install();
|
||||
static void remove();
|
||||
|
||||
Thread(const std::string &i_name=std::string());
|
||||
|
||||
void kill();
|
||||
bool done();
|
||||
void wait();
|
||||
|
||||
enum ePriority
|
||||
{
|
||||
kIdle = 0,
|
||||
kLow = 1,
|
||||
kNormal = 2,
|
||||
kHigh = 3,
|
||||
kCritical = 4
|
||||
};
|
||||
void setPriority(ePriority priority);
|
||||
|
||||
const std::string &getName() const;
|
||||
void setName(const std::string &i_name);
|
||||
|
||||
static Thread * getCurrentThread();
|
||||
static Thread * getMainThread();
|
||||
protected:
|
||||
virtual ~Thread();
|
||||
virtual void run()=0;
|
||||
|
||||
pthread_t thread;
|
||||
|
||||
InterlockedInteger refcount;
|
||||
private:
|
||||
Thread(const Thread &o);
|
||||
Thread &operator =(const Thread &o);
|
||||
|
||||
void start();
|
||||
void attach(); // pick up the currently running thread
|
||||
|
||||
void ref();
|
||||
void deref();
|
||||
|
||||
bool doneFlag;
|
||||
|
||||
std::string name;
|
||||
|
||||
static pthread_key_t implindex;
|
||||
static Thread * mainThread;
|
||||
static void * threadFunc(void * data);
|
||||
};
|
||||
|
||||
inline void Thread::ref()
|
||||
{
|
||||
++refcount;
|
||||
}
|
||||
|
||||
inline void Thread::deref()
|
||||
{
|
||||
if (--refcount == 0) delete this;
|
||||
}
|
||||
|
||||
inline Thread * Thread::getCurrentThread()
|
||||
{
|
||||
return static_cast<Thread *>(pthread_getspecific(implindex));
|
||||
}
|
||||
|
||||
inline Thread * Thread::getMainThread()
|
||||
{
|
||||
return mainThread;
|
||||
}
|
||||
|
||||
inline const std::string &Thread::getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
inline void Thread::setName(const std::string &i_name)
|
||||
{
|
||||
name = i_name;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* @(#)jawt_md.h 1.4 00/02/02
|
||||
*
|
||||
* Copyright 1999, 2000 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* This software is the proprietary information of Sun Microsystems, Inc.
|
||||
* Use is subject to license terms.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _JAVASOFT_JAWT_MD_H_
|
||||
#define _JAVASOFT_JAWT_MD_H_
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Intrinsic.h>
|
||||
#include "jawt.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* X11-specific declarations for AWT native interface.
|
||||
* See notes in jawt.h for an example of use.
|
||||
*/
|
||||
typedef struct jawt_X11DrawingSurfaceInfo {
|
||||
Drawable drawable;
|
||||
Display* display;
|
||||
VisualID visualID;
|
||||
Colormap colormapID;
|
||||
int depth;
|
||||
} JAWT_X11DrawingSurfaceInfo;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !_JAVASOFT_JAWT_MD_H_ */
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* @(#)jni_md.h 1.12 00/02/02
|
||||
*
|
||||
* Copyright 1996-2000 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* This software is the proprietary information of Sun Microsystems, Inc.
|
||||
* Use is subject to license terms.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _JAVASOFT_JNI_MD_H_
|
||||
#define _JAVASOFT_JNI_MD_H_
|
||||
|
||||
#define JNIEXPORT
|
||||
#define JNIIMPORT
|
||||
#define JNICALL
|
||||
|
||||
#ifdef _LP64 /* 64-bit Solaris */
|
||||
typedef int jint;
|
||||
#else
|
||||
typedef long jint;
|
||||
#endif
|
||||
typedef long long jlong;
|
||||
typedef signed char jbyte;
|
||||
|
||||
#endif /* !_JAVASOFT_JNI_MD_H_ */
|
||||
@@ -1,184 +0,0 @@
|
||||
/*************************************************
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/* Copyright (c) 1997-2003 University of Cambridge */
|
||||
|
||||
#ifndef _PCRE_H
|
||||
#define _PCRE_H
|
||||
|
||||
/* The file pcre.h is build by "configure". Do not edit it; instead
|
||||
make changes to pcre.in. */
|
||||
|
||||
#define PCRE_MAJOR 4
|
||||
#define PCRE_MINOR 1
|
||||
#define PCRE_DATE 12-Mar-2003
|
||||
|
||||
/* Win32 uses DLL by default */
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef PCRE_DEFINITION
|
||||
# ifdef DLL_EXPORT
|
||||
# define PCRE_DATA_SCOPE __declspec(dllexport)
|
||||
# endif
|
||||
# else
|
||||
# ifndef PCRE_STATIC
|
||||
# define PCRE_DATA_SCOPE __declspec(dllimport)
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#ifndef PCRE_DATA_SCOPE
|
||||
# define PCRE_DATA_SCOPE extern
|
||||
#endif
|
||||
|
||||
/* Have to include stdlib.h in order to ensure that size_t is defined;
|
||||
it is needed here for malloc. */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Allow for C++ users */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Options */
|
||||
|
||||
#define PCRE_CASELESS 0x0001
|
||||
#define PCRE_MULTILINE 0x0002
|
||||
#define PCRE_DOTALL 0x0004
|
||||
#define PCRE_EXTENDED 0x0008
|
||||
#define PCRE_ANCHORED 0x0010
|
||||
#define PCRE_DOLLAR_ENDONLY 0x0020
|
||||
#define PCRE_EXTRA 0x0040
|
||||
#define PCRE_NOTBOL 0x0080
|
||||
#define PCRE_NOTEOL 0x0100
|
||||
#define PCRE_UNGREEDY 0x0200
|
||||
#define PCRE_NOTEMPTY 0x0400
|
||||
#define PCRE_UTF8 0x0800
|
||||
#define PCRE_NO_AUTO_CAPTURE 0x1000
|
||||
|
||||
/* Exec-time and get/set-time error codes */
|
||||
|
||||
#define PCRE_ERROR_NOMATCH (-1)
|
||||
#define PCRE_ERROR_NULL (-2)
|
||||
#define PCRE_ERROR_BADOPTION (-3)
|
||||
#define PCRE_ERROR_BADMAGIC (-4)
|
||||
#define PCRE_ERROR_UNKNOWN_NODE (-5)
|
||||
#define PCRE_ERROR_NOMEMORY (-6)
|
||||
#define PCRE_ERROR_NOSUBSTRING (-7)
|
||||
#define PCRE_ERROR_MATCHLIMIT (-8)
|
||||
#define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */
|
||||
|
||||
/* Request types for pcre_fullinfo() */
|
||||
|
||||
#define PCRE_INFO_OPTIONS 0
|
||||
#define PCRE_INFO_SIZE 1
|
||||
#define PCRE_INFO_CAPTURECOUNT 2
|
||||
#define PCRE_INFO_BACKREFMAX 3
|
||||
#define PCRE_INFO_FIRSTBYTE 4
|
||||
#define PCRE_INFO_FIRSTCHAR 4 /* For backwards compatibility */
|
||||
#define PCRE_INFO_FIRSTTABLE 5
|
||||
#define PCRE_INFO_LASTLITERAL 6
|
||||
#define PCRE_INFO_NAMEENTRYSIZE 7
|
||||
#define PCRE_INFO_NAMECOUNT 8
|
||||
#define PCRE_INFO_NAMETABLE 9
|
||||
#define PCRE_INFO_STUDYSIZE 10
|
||||
|
||||
/* Request types for pcre_config() */
|
||||
|
||||
#define PCRE_CONFIG_UTF8 0
|
||||
#define PCRE_CONFIG_NEWLINE 1
|
||||
#define PCRE_CONFIG_LINK_SIZE 2
|
||||
#define PCRE_CONFIG_POSIX_MALLOC_THRESHOLD 3
|
||||
#define PCRE_CONFIG_MATCH_LIMIT 4
|
||||
|
||||
/* Bit flags for the pcre_extra structure */
|
||||
|
||||
#define PCRE_EXTRA_STUDY_DATA 0x0001
|
||||
#define PCRE_EXTRA_MATCH_LIMIT 0x0002
|
||||
#define PCRE_EXTRA_CALLOUT_DATA 0x0004
|
||||
|
||||
/* Types */
|
||||
|
||||
struct real_pcre; /* declaration; the definition is private */
|
||||
typedef struct real_pcre pcre;
|
||||
|
||||
/* The structure for passing additional data to pcre_exec(). This is defined in
|
||||
such as way as to be extensible. */
|
||||
|
||||
typedef struct pcre_extra {
|
||||
unsigned long int flags; /* Bits for which fields are set */
|
||||
void *study_data; /* Opaque data from pcre_study() */
|
||||
unsigned long int match_limit; /* Maximum number of calls to match() */
|
||||
void *callout_data; /* Data passed back in callouts */
|
||||
} pcre_extra;
|
||||
|
||||
/* The structure for passing out data via the pcre_callout_function. We use a
|
||||
structure so that new fields can be added on the end in future versions,
|
||||
without changing the API of the function, thereby allowing old clients to work
|
||||
without modification. */
|
||||
|
||||
typedef struct pcre_callout_block {
|
||||
int version; /* Identifies version of block */
|
||||
/* ------------------------ Version 0 ------------------------------- */
|
||||
int callout_number; /* Number compiled into pattern */
|
||||
int *offset_vector; /* The offset vector */
|
||||
const char *subject; /* The subject being matched */
|
||||
int subject_length; /* The length of the subject */
|
||||
int start_match; /* Offset to start of this match attempt */
|
||||
int current_position; /* Where we currently are */
|
||||
int capture_top; /* Max current capture */
|
||||
int capture_last; /* Most recently closed capture */
|
||||
void *callout_data; /* Data passed in with the call */
|
||||
/* ------------------------------------------------------------------ */
|
||||
} pcre_callout_block;
|
||||
|
||||
/* Indirection for store get and free functions. These can be set to
|
||||
alternative malloc/free functions if required. There is also an optional
|
||||
callout function that is triggered by the (?) regex item. Some magic is
|
||||
required for Win32 DLL; it is null on other OS. For Virtual Pascal, these
|
||||
have to be different again. */
|
||||
|
||||
#ifndef VPCOMPAT
|
||||
PCRE_DATA_SCOPE void *(*pcre_malloc)(size_t);
|
||||
PCRE_DATA_SCOPE void (*pcre_free)(void *);
|
||||
PCRE_DATA_SCOPE int (*pcre_callout)(pcre_callout_block *);
|
||||
#else /* VPCOMPAT */
|
||||
extern void *pcre_malloc(size_t);
|
||||
extern void pcre_free(void *);
|
||||
extern int pcre_callout(pcre_callout_block *);
|
||||
#endif /* VPCOMPAT */
|
||||
|
||||
/* Exported PCRE functions */
|
||||
|
||||
extern pcre *pcre_compile(const char *, int, const char **,
|
||||
int *, const unsigned char *);
|
||||
extern int pcre_config(int, void *);
|
||||
extern int pcre_copy_named_substring(const pcre *, const char *,
|
||||
int *, int, const char *, char *, int);
|
||||
extern int pcre_copy_substring(const char *, int *, int, int,
|
||||
char *, int);
|
||||
extern int pcre_exec(const pcre *, const pcre_extra *,
|
||||
const char *, int, int, int, int *, int);
|
||||
extern void pcre_free_substring(const char *);
|
||||
extern void pcre_free_substring_list(const char **);
|
||||
extern int pcre_fullinfo(const pcre *, const pcre_extra *, int,
|
||||
void *);
|
||||
extern int pcre_get_named_substring(const pcre *, const char *,
|
||||
int *, int, const char *, const char **);
|
||||
extern int pcre_get_stringnumber(const pcre *, const char *);
|
||||
extern int pcre_get_substring(const char *, int *, int, int,
|
||||
const char **);
|
||||
extern int pcre_get_substring_list(const char *, int *, int,
|
||||
const char ***);
|
||||
extern int pcre_info(const pcre *, int *, int *);
|
||||
extern const unsigned char *pcre_maketables(void);
|
||||
extern pcre_extra *pcre_study(const pcre *, int, const char **);
|
||||
extern const char *pcre_version(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* End of pcre.h */
|
||||
@@ -1,88 +0,0 @@
|
||||
/*************************************************
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/* Copyright (c) 1997-2003 University of Cambridge */
|
||||
|
||||
#ifndef _PCREPOSIX_H
|
||||
#define _PCREPOSIX_H
|
||||
|
||||
/* This is the header for the POSIX wrapper interface to the PCRE Perl-
|
||||
Compatible Regular Expression library. It defines the things POSIX says should
|
||||
be there. I hope. */
|
||||
|
||||
/* Have to include stdlib.h in order to ensure that size_t is defined. */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Allow for C++ users */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Options defined by POSIX. */
|
||||
|
||||
#define REG_ICASE 0x01
|
||||
#define REG_NEWLINE 0x02
|
||||
#define REG_NOTBOL 0x04
|
||||
#define REG_NOTEOL 0x08
|
||||
|
||||
/* These are not used by PCRE, but by defining them we make it easier
|
||||
to slot PCRE into existing programs that make POSIX calls. */
|
||||
|
||||
#define REG_EXTENDED 0
|
||||
#define REG_NOSUB 0
|
||||
|
||||
/* Error values. Not all these are relevant or used by the wrapper. */
|
||||
|
||||
enum {
|
||||
REG_ASSERT = 1, /* internal error ? */
|
||||
REG_BADBR, /* invalid repeat counts in {} */
|
||||
REG_BADPAT, /* pattern error */
|
||||
REG_BADRPT, /* ? * + invalid */
|
||||
REG_EBRACE, /* unbalanced {} */
|
||||
REG_EBRACK, /* unbalanced [] */
|
||||
REG_ECOLLATE, /* collation error - not relevant */
|
||||
REG_ECTYPE, /* bad class */
|
||||
REG_EESCAPE, /* bad escape sequence */
|
||||
REG_EMPTY, /* empty expression */
|
||||
REG_EPAREN, /* unbalanced () */
|
||||
REG_ERANGE, /* bad range inside [] */
|
||||
REG_ESIZE, /* expression too big */
|
||||
REG_ESPACE, /* failed to get memory */
|
||||
REG_ESUBREG, /* bad back reference */
|
||||
REG_INVARG, /* bad argument */
|
||||
REG_NOMATCH /* match failed */
|
||||
};
|
||||
|
||||
|
||||
/* The structure representing a compiled regular expression. */
|
||||
|
||||
typedef struct {
|
||||
void *re_pcre;
|
||||
size_t re_nsub;
|
||||
size_t re_erroffset;
|
||||
} regex_t;
|
||||
|
||||
/* The structure in which a captured offset is returned. */
|
||||
|
||||
typedef int regoff_t;
|
||||
|
||||
typedef struct {
|
||||
regoff_t rm_so;
|
||||
regoff_t rm_eo;
|
||||
} regmatch_t;
|
||||
|
||||
/* The functions */
|
||||
|
||||
extern int regcomp(regex_t *, const char *, int);
|
||||
extern int regexec(regex_t *, const char *, size_t, regmatch_t *, int);
|
||||
extern size_t regerror(int, const regex_t *, char *, size_t);
|
||||
extern void regfree(regex_t *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* End of pcreposix.h */
|
||||
Binary file not shown.
@@ -1,32 +0,0 @@
|
||||
# libpcre.la - a libtool library file
|
||||
# Generated by ltmain.sh - GNU libtool 1.4.3 (1.922.2.110 2002/10/23 01:39:54)
|
||||
#
|
||||
# Please DO NOT delete this file!
|
||||
# It is necessary for linking the library.
|
||||
|
||||
# The name that we can dlopen(3).
|
||||
dlname='libpcre.so.0'
|
||||
|
||||
# Names of this library.
|
||||
library_names='libpcre.so.0.0.1 libpcre.so.0 libpcre.so'
|
||||
|
||||
# The name of the static archive.
|
||||
old_library='libpcre.a'
|
||||
|
||||
# Libraries that this one depends upon.
|
||||
dependency_libs=''
|
||||
|
||||
# Version information for libpcre.
|
||||
current=0
|
||||
age=0
|
||||
revision=1
|
||||
|
||||
# Is this an already installed library?
|
||||
installed=yes
|
||||
|
||||
# Files to dlopen/dlpreopen
|
||||
dlopen=''
|
||||
dlpreopen=''
|
||||
|
||||
# Directory that this library needs to be installed in:
|
||||
libdir='/home/tfiala/swg/current/src/external/3rd/library/pcre/4.1/linux/lib'
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,32 +0,0 @@
|
||||
# libpcreposix.la - a libtool library file
|
||||
# Generated by ltmain.sh - GNU libtool 1.4.3 (1.922.2.110 2002/10/23 01:39:54)
|
||||
#
|
||||
# Please DO NOT delete this file!
|
||||
# It is necessary for linking the library.
|
||||
|
||||
# The name that we can dlopen(3).
|
||||
dlname='libpcreposix.so.0'
|
||||
|
||||
# Names of this library.
|
||||
library_names='libpcreposix.so.0.0.0 libpcreposix.so.0 libpcreposix.so'
|
||||
|
||||
# The name of the static archive.
|
||||
old_library='libpcreposix.a'
|
||||
|
||||
# Libraries that this one depends upon.
|
||||
dependency_libs=' -L/home/tfiala/transfer/pcre-4.1 /home/tfiala/swg/current/src/external/3rd/library/pcre/4.1/linux/lib/libpcre.la'
|
||||
|
||||
# Version information for libpcreposix.
|
||||
current=0
|
||||
age=0
|
||||
revision=0
|
||||
|
||||
# Is this an already installed library?
|
||||
installed=yes
|
||||
|
||||
# Files to dlopen/dlpreopen
|
||||
dlopen=''
|
||||
dlpreopen=''
|
||||
|
||||
# Directory that this library needs to be installed in:
|
||||
libdir='/home/tfiala/swg/current/src/external/3rd/library/pcre/4.1/linux/lib'
|
||||
Binary file not shown.
Binary file not shown.
BIN
src/external/3rd/library/perforce/lib/linux/librpc.a
vendored
BIN
src/external/3rd/library/perforce/lib/linux/librpc.a
vendored
Binary file not shown.
Binary file not shown.
@@ -1,44 +0,0 @@
|
||||
#ifndef BASE_LINUX_ARCHIVE_H
|
||||
#define BASE_LINUX_ARCHIVE_H
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
|
||||
#endif
|
||||
|
||||
namespace Base
|
||||
{
|
||||
|
||||
|
||||
#ifdef PACK_BIG_ENDIAN
|
||||
|
||||
inline double byteSwap(double value) { byteReverse(&value); return value; }
|
||||
inline float byteSwap(float value) { byteReverse(&value); return value; }
|
||||
inline uint64 byteSwap(uint64 value) { byteReverse(&value); return value; }
|
||||
inline int64 byteSwap(int64 value) { byteReverse(&value); return value; }
|
||||
inline uint32 byteSwap(uint32 value) { byteReverse(&value); return value; }
|
||||
inline int32 byteSwap(int32 value) { byteReverse(&value); return value; }
|
||||
inline uint16 byteSwap(uint16 value) { byteReverse(&value); return value; }
|
||||
inline int16 byteSwap(int16 value) { byteReverse(&value); return value; }
|
||||
|
||||
#else
|
||||
|
||||
inline double byteSwap(double value) { return value; }
|
||||
inline float byteSwap(float value) { return value; }
|
||||
inline uint64 byteSwap(uint64 value) { return value; }
|
||||
inline int64 byteSwap(int64 value) { return value; }
|
||||
inline uint32 byteSwap(uint32 value) { return value; }
|
||||
inline int32 byteSwap(int32 value) { return value; }
|
||||
inline uint16 byteSwap(uint16 value) { return value; }
|
||||
inline int16 byteSwap(int16 value) { return value; }
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,110 +0,0 @@
|
||||
#include "../BlockAllocator.h"
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
|
||||
#endif
|
||||
namespace Base
|
||||
{
|
||||
BlockAllocator::BlockAllocator()
|
||||
{
|
||||
for(unsigned i = 0; i < 31; i++)
|
||||
{
|
||||
m_blocks[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
BlockAllocator::~BlockAllocator()
|
||||
{
|
||||
// free all allocated memory blocks
|
||||
for(unsigned i = 0; i < 31; i++)
|
||||
{
|
||||
while(m_blocks[i] != NULL)
|
||||
{
|
||||
unsigned *tmp = m_blocks[i];
|
||||
m_blocks[i] = (unsigned *)*m_blocks[i];
|
||||
free(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate a block that is the next power of two greater than the # of bytes passed.
|
||||
// 33 bytes yields a 64 byte block of memory and so forth.
|
||||
|
||||
void *BlockAllocator::getBlock(unsigned bytes)
|
||||
{
|
||||
unsigned accum = 16, bits = 16;
|
||||
unsigned *handle = NULL;
|
||||
|
||||
// Perform a binary search looking for the highest bit.
|
||||
|
||||
while(bits != 0)
|
||||
{
|
||||
// If bytes is less than the bit we're testing for, subtract half
|
||||
// from the bit value and repeat
|
||||
if(bytes < (unsigned)(1 << accum))
|
||||
{
|
||||
bits /= 2;
|
||||
accum -= bits;
|
||||
}
|
||||
// If bytes is greater than the bit we're testing for, add half
|
||||
// from the but value and repeat
|
||||
else if(bytes > (unsigned)(1 << accum))
|
||||
{
|
||||
bits /= 2;
|
||||
accum += bits;
|
||||
}
|
||||
// Got lucky and hit the value dead on
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
// At this point accum contains the most significant bit index, increment
|
||||
accum++;
|
||||
if(accum < 2)
|
||||
{
|
||||
accum = 2;
|
||||
}
|
||||
|
||||
// Note that when memory is actually allocated, 8 extra bytes will be allocated.at the front
|
||||
// The first integer is the address of the next block of memory when the block is in the allocator
|
||||
// The second integer is the bit length of the block
|
||||
// Memory is allocated on 4 byte boundaries to sidestep byte alignment problems
|
||||
|
||||
|
||||
// Check if the allocator already has a block of that size
|
||||
if(m_blocks[accum] == 0)
|
||||
{
|
||||
// remove the pre allocated block from the linked list
|
||||
handle = (unsigned *)calloc(((1 << accum) / 4) + 2, sizeof(unsigned));
|
||||
handle[1] = accum;
|
||||
handle[0] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Allocate a new block
|
||||
handle = m_blocks[accum];
|
||||
m_blocks[accum] = (unsigned *)handle[0];
|
||||
handle[0] = 0;
|
||||
}
|
||||
// return a pointer that skips over the header used for the allocator's purposes
|
||||
return(handle + 2);
|
||||
}
|
||||
|
||||
void BlockAllocator::returnBlock(unsigned *handle)
|
||||
{
|
||||
// C++ allows for safe deletion of a NULL pointer
|
||||
if(handle)
|
||||
{
|
||||
// Update the allocator linked list, insert this entry at the head
|
||||
*(handle - 2) = (unsigned)m_blocks[*(handle - 1)];
|
||||
// Add this entry to the proper linked list node
|
||||
m_blocks[*(handle - 1)] = (handle - 2);
|
||||
}
|
||||
}
|
||||
};
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
@@ -1,103 +0,0 @@
|
||||
////////////////////////////////////////
|
||||
// Event.cpp
|
||||
//
|
||||
// Purpose:
|
||||
// 1. Implementation of the CEvent class.
|
||||
//
|
||||
// Revisions:
|
||||
// 07/10/2001 Created
|
||||
//
|
||||
|
||||
#if defined(_REENTRANT)
|
||||
|
||||
|
||||
#include "Event.h"
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
|
||||
#endif
|
||||
namespace Base
|
||||
{
|
||||
|
||||
CEvent::CEvent() :
|
||||
mMutex(),
|
||||
mCond(),
|
||||
mThreadCount(0)
|
||||
{
|
||||
pthread_mutex_init(&mMutex, NULL);
|
||||
pthread_cond_init(&mCond, NULL);
|
||||
}
|
||||
|
||||
CEvent::~CEvent()
|
||||
{
|
||||
pthread_cond_destroy(&mCond);
|
||||
pthread_mutex_destroy(&mMutex);
|
||||
}
|
||||
|
||||
bool CEvent::Signal()
|
||||
{
|
||||
pthread_mutex_lock(&mMutex);
|
||||
if (mThreadCount == 0)
|
||||
mThreadCount = SIGNALED;
|
||||
pthread_cond_signal(&mCond);
|
||||
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int32 CEvent::Wait(uint32 timeout)
|
||||
{
|
||||
int result;
|
||||
|
||||
pthread_mutex_lock(&mMutex);
|
||||
if (mThreadCount == SIGNALED)
|
||||
{
|
||||
mThreadCount = 0;
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
|
||||
return eWAIT_SIGNAL;
|
||||
}
|
||||
|
||||
if (!timeout)
|
||||
{
|
||||
mThreadCount++;
|
||||
result = pthread_cond_wait(&mCond, &mMutex);
|
||||
mThreadCount--;
|
||||
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct timeval now;
|
||||
struct timespec abs_timeout;
|
||||
|
||||
gettimeofday(&now, NULL);
|
||||
abs_timeout.tv_sec = now.tv_sec + timeout/1000;
|
||||
abs_timeout.tv_nsec = now.tv_usec * 1000 + (timeout%1000)*1000000;
|
||||
abs_timeout.tv_sec += abs_timeout.tv_nsec / 1000000000;
|
||||
abs_timeout.tv_nsec %= 1000000000;
|
||||
|
||||
mThreadCount++;
|
||||
result = pthread_cond_timedwait(&mCond, &mMutex, &abs_timeout);
|
||||
mThreadCount--;
|
||||
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
}
|
||||
|
||||
if (result == 0 || result == EINTR)
|
||||
return eWAIT_SIGNAL;
|
||||
else if (result == ETIMEDOUT)
|
||||
return eWAIT_TIMEOUT;
|
||||
else
|
||||
return eWAIT_ERROR;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
#endif // #if defined(_REENTRANT)
|
||||
@@ -1,74 +0,0 @@
|
||||
////////////////////////////////////////
|
||||
// Event.h
|
||||
//
|
||||
// Purpose:
|
||||
// 1. Declair the CEvent class that encapsulates the functionality of a
|
||||
// single-locking semaphore.
|
||||
//
|
||||
// Revisions:
|
||||
// 07/10/2001 Created
|
||||
//
|
||||
|
||||
#ifndef BASE_LINUX_EVENT_H
|
||||
#define BASE_LINUX_EVENT_H
|
||||
|
||||
#if !defined(_REENTRANT)
|
||||
# pragma message( "Excluding Base::CEvent - requires multi-threaded compile. (_REENTRANT)" )
|
||||
#else
|
||||
|
||||
|
||||
#include <pthread.h>
|
||||
#include "Platform.h"
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
|
||||
#endif
|
||||
namespace Base
|
||||
{
|
||||
|
||||
////////////////////////////////////////
|
||||
// Class:
|
||||
// CEvent
|
||||
//
|
||||
// Purpose:
|
||||
// Encapsulates the functionality of a singal-locking semaphore.
|
||||
// This class is valuable for thread syncronization when a thead's
|
||||
// execution needs to be dependent upon another thread.
|
||||
//
|
||||
// Public Methods:
|
||||
// Signal() : Signals a thread that has called Wait() so that it can
|
||||
// continue execution. This function returns true if the waiting
|
||||
// thread was signalled successfully, otherwise false is returned.
|
||||
// Wait() : Halts the calling thread's execution indefinately until
|
||||
// a Singal() call is made by an external thread. If the thread is
|
||||
// successfully signalled, the function returns eWAIT_SIGNAL. If
|
||||
// timeout period expires without a signal, eWAIT_TIMEOUT is returned.
|
||||
// If the function fails, eWAIT_ERROR is returned.
|
||||
//
|
||||
class CEvent
|
||||
{
|
||||
public:
|
||||
CEvent();
|
||||
virtual ~CEvent();
|
||||
|
||||
bool Signal();
|
||||
int32 Wait(uint32 timeout = 0);
|
||||
|
||||
public:
|
||||
enum { eWAIT_ERROR, eWAIT_SIGNAL, eWAIT_TIMEOUT };
|
||||
enum { SIGNALED = -1 };
|
||||
private:
|
||||
pthread_mutex_t mMutex;
|
||||
pthread_cond_t mCond;
|
||||
int mThreadCount;
|
||||
};
|
||||
|
||||
}
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
#endif // #if defined(_MT)
|
||||
|
||||
#endif // BASE_LINUX_EVENT_H
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user