using std::cerr;
using std::endl;
-/* Target language and output style. */
-
-/* Io globals. */
-extern istream *inStream;
-extern ostream *outStream;
-extern output_filter *outFilter;
-extern const char *outputFileName;
-
-/* Graphviz dot file generation. */
-extern bool graphvizDone;
extern int numSplitPartitions;
extern bool noLineDirectives;
#define _INPUT_DATA
#include "gendata.h"
+#include <iostream>
+#include <sstream>
struct Parser;
+struct ParseData;
+
+struct InputItem
+{
+ enum Type {
+ HostData,
+ Write,
+ };
+
+ Type type;
+ std::ostringstream data;
+ std::string name;
+ ParseData *pd;
+ Vector<char *> writeArgs;
+
+ InputLoc loc;
+
+ InputItem *prev, *next;
+};
+
+struct Parser;
+
+typedef AvlMap<const char*, Parser*, CmpStr> ParserDict;
+typedef AvlMapEl<const char*, Parser*> ParserDictEl;
+typedef DList<Parser> ParserList;
+typedef DList<InputItem> InputItemList;
+typedef Vector<const char *> ArgsVector;
struct InputData
{
- InputData( const char *inputFileName ) :
- inputFileName(inputFileName),
+ InputData() :
+ inputFileName(0),
+ outputFileName(0),
+ inStream(0),
outStream(0),
+ outFilter(0),
dotGenParser(0)
{}
/* The name of the root section, this does not change during an include. */
const char *inputFileName;
- ostream *outStream;
+ const char *outputFileName;
+
+ /* Io globals. */
+ std::istream *inStream;
+ std::ostream *outStream;
+ output_filter *outFilter;
+
Parser *dotGenParser;
+ ParserDict parserDict;
+ ParserList parserList;
+ InputItemList inputItems;
+
+ ArgsVector includePaths;
+
void writeOutput();
void makeOutputStream();
void openOutput();
void csharpDefaultFileName( const char *inputFile );
};
+extern InputData id;
+
#endif
MinimizeLevel minimizeLevel = MinimizePartition2;
MinimizeOpt minimizeOpt = MinimizeMostOps;
+InputData id;
+
/* Graphviz dot file generation. */
const char *machineSpec = 0, *machineName = 0;
bool machineSpecFound = false;
bool noLineDirectives = false;
bool displayPrintables = false;
-bool graphvizDone = false;
/* Target ruby impl */
RubyImplEnum rubyImpl = MRI;
-ArgsVector includePaths;
-
-istream *inStream = 0;
-ostream *outStream = 0;
-output_filter *outFilter = 0;
-const char *outputFileName = 0;
-
-ParserDict parserDict;
-ParserList parserList;
-InputItemList inputItems;
-
/* Print a summary of the options. */
void usage()
{
}
}
-void processArgs( int argc, const char **argv, const char *&inputFileName )
+void processArgs( int argc, const char **argv )
{
ParamCheck pc("xo:dnmleabjkS:M:I:CDJRAvHh?-:sT:F:G:P:LpV", argc, argv);
case 'o':
if ( *pc.paramArg == 0 )
error() << "a zero length output file name was given" << endl;
- else if ( outputFileName != 0 )
+ else if ( id.outputFileName != 0 )
error() << "more than one output file name was given" << endl;
else {
/* Ok, remember the output file name. */
- outputFileName = pc.paramArg;
+ id.outputFileName = pc.paramArg;
}
break;
if ( *pc.paramArg == 0 )
error() << "please specify an argument to -I" << endl;
else {
- includePaths.append( pc.paramArg );
+ id.includePaths.append( pc.paramArg );
}
break;
/* It is interpreted as an input file. */
if ( *pc.curArg == 0 )
error() << "a zero length input file name was given" << endl;
- else if ( inputFileName != 0 )
+ else if ( id.inputFileName != 0 )
error() << "more than one input file name was given" << endl;
else {
/* OK, Remember the filename. */
- inputFileName = pc.curArg;
+ id.inputFileName = pc.curArg;
}
break;
}
}
}
-void process( const char *inputFileName )
+void process()
{
/* Open the input file for reading. */
- assert( inputFileName != 0 );
- ifstream *inFile = new ifstream( inputFileName );
+ assert( id.inputFileName != 0 );
+ ifstream *inFile = new ifstream( id.inputFileName );
if ( ! inFile->is_open() )
- error() << "could not open " << inputFileName << " for reading" << endp;
-
- InputData inputData( inputFileName );
+ error() << "could not open " << id.inputFileName << " for reading" << endp;
/* Used for just a few things. */
std::ostringstream hostData;
firstInputItem->type = InputItem::HostData;
firstInputItem->loc.line = 1;
firstInputItem->loc.col = 1;
- inputItems.append( firstInputItem );
+ id.inputItems.append( firstInputItem );
- Scanner scanner( inputFileName, *inFile, 0, 0, 0, false );
+ Scanner scanner( id.inputFileName, *inFile, 0, 0, 0, false );
scanner.do_scan();
/* Finished, final check for errors.. */
exit(1);
/* Now send EOF to all parsers. */
- inputData.terminateAllParsers();
+ id.terminateAllParsers();
/* Bail on above error. */
if ( gblErrorCount > 0 )
/* Locate the backend program */
/* Compiles machines. */
- inputData.prepareMachineGen();
+ id.prepareMachineGen();
if ( gblErrorCount > 0 )
exit(1);
- inputData.makeOutputStream();
+ id.makeOutputStream();
/* Generates the reduced machine, which we use to write output. */
- inputData.generateReduced();
+ id.generateReduced();
if ( gblErrorCount > 0 )
exit(1);
+
+ /*
+ * From this point on we should not be reporting any errors.
+ */
- inputData.openOutput();
- inputData.writeOutput();
+ id.openOutput();
+ id.writeOutput();
/* Close the input and the intermediate file. */
delete inFile;
/* If writing to a file, delete the ostream, causing it to flush.
* Standard out is flushed automatically. */
- if ( outputFileName != 0 ) {
- delete outStream;
- delete outFilter;
+ if ( id.outputFileName != 0 ) {
+ delete id.outStream;
+ delete id.outFilter;
}
- /* Finished, final check for errors.. */
- if ( gblErrorCount > 0 ) {
- /* If we opened an output file, remove it. */
- if ( outputFileName != 0 )
- unlink( outputFileName );
- exit(1);
- }
+ assert( gblErrorCount == 0 );
}
char *makeIntermedTemplate( const char *baseFileName )
return result;
};
-const char *openIntermed( const char *inputFileName, const char *outputFileName )
-{
- srand(time(0));
- const char *result = 0;
-
- /* Which filename do we use as the base? */
- const char *baseFileName = outputFileName != 0 ? outputFileName : inputFileName;
-
- /* The template for the intermediate file name. */
- const char *intermedFileName = makeIntermedTemplate( baseFileName );
-
- /* Randomize the name and try to open. */
- char fnChars[] = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- char *firstX = strrchr( intermedFileName, 'X' ) - 5;
- for ( int tries = 0; tries < 20; tries++ ) {
- /* Choose a random name. */
- for ( int x = 0; x < 6; x++ )
- firstX[x] = fnChars[rand() % 52];
-
- /* Try to open the file. */
- int fd = ::open( intermedFileName, O_WRONLY|O_EXCL|O_CREAT, S_IRUSR|S_IWUSR );
-
- if ( fd > 0 ) {
- /* Success. Close the file immediately and return the name for use
- * by the child processes. */
- ::close( fd );
- result = intermedFileName;
- break;
- }
-
- if ( errno == EACCES ) {
- error() << "failed to open temp file " << intermedFileName <<
- ", access denied" << endp;
- }
- }
-
- if ( result == 0 )
- error() << "abnormal error: cannot find unique name for temp file" << endp;
-
- return result;
-}
-
-
-
/* Main, process args and call yyparse to start scanning input. */
int main( int argc, const char **argv )
{
- const char *inputFileName = 0;
- processArgs( argc, argv, inputFileName );
+ processArgs( argc, argv );
/* If -M or -S are given and we're not generating a dot file then invoke
* the frontend. These options are not useful with code generators. */
/* Require an input file. If we use standard in then we won't have a file
* name on which to base the output. */
- if ( inputFileName == 0 )
+ if ( id.inputFileName == 0 )
error() << "no input file given" << endl;
/* Bail on argument processing errors. */
exit(1);
/* Make sure we are not writing to the same file as the input file. */
- if ( inputFileName != 0 && outputFileName != 0 &&
- strcmp( inputFileName, outputFileName ) == 0 )
+ if ( id.inputFileName != 0 && id.outputFileName != 0 &&
+ strcmp( id.inputFileName, id.outputFileName ) == 0 )
{
- error() << "output file \"" << outputFileName <<
+ error() << "output file \"" << id.outputFileName <<
"\" is the same as the input file" << endp;
}
- process( inputFileName );
+ process();
/* Clean up the intermediate. */
exit( 0 );
}
}
-void writeLanguage( std::ostream &out )
-{
- out << " lang=\"";
- switch ( hostLang->lang ) {
- case HostLang::C: out << "C"; break;
- case HostLang::D: out << "D"; break;
- case HostLang::Java: out << "Java"; break;
- case HostLang::Ruby: out << "Ruby"; break;
- case HostLang::CSharp: out << "C#"; break;
- }
- out << "\"";
-}
-
void ParseData::generateXML( ostream &out )
{
beginProcessing();
}
}
-void writeMachines( std::ostream &out, std::string hostData, const char *inputFileName )
-{
- if ( machineSpec == 0 && machineName == 0 ) {
- /* No machine spec or machine name given. Generate everything. */
- for ( ParserDict::Iter parser = parserDict; parser.lte(); parser++ ) {
- ParseData *pd = parser->value->pd;
- if ( pd->instanceList.length() > 0 )
- pd->prepareMachineGen( 0 );
- }
-
- if ( gblErrorCount == 0 ) {
- out << "<ragel version=\"" VERSION "\" filename=\"" << inputFileName << "\"";
- writeLanguage( out );
- out << ">\n";
- for ( ParserDict::Iter parser = parserDict; parser.lte(); parser++ ) {
- ParseData *pd = parser->value->pd;
- if ( pd->instanceList.length() > 0 )
- pd->generateXML( out );
- }
- out << hostData;
- out << "</ragel>\n";
- }
- }
- else if ( parserDict.length() > 0 ) {
- /* There is either a machine spec or machine name given. */
- ParseData *parseData = 0;
- GraphDictEl *graphDictEl = 0;
-
- /* Traverse the sections, break out when we find a section/machine
- * that matches the one specified. */
- for ( ParserDict::Iter parser = parserDict; parser.lte(); parser++ ) {
- ParseData *checkPd = parser->value->pd;
- if ( machineSpec == 0 || strcmp( checkPd->sectionName, machineSpec ) == 0 ) {
- GraphDictEl *checkGdEl = 0;
- if ( machineName == 0 || (checkGdEl =
- checkPd->graphDict.find( machineName )) != 0 )
- {
- /* Have a machine spec and/or machine name that matches
- * the -M/-S options. */
- parseData = checkPd;
- graphDictEl = checkGdEl;
- break;
- }
- }
- }
-
- if ( parseData == 0 )
- error() << "could not locate machine specified with -S and/or -M" << endl;
- else {
- /* Section/Machine to emit was found. Prepare and emit it. */
- parseData->prepareMachineGen( graphDictEl );
- if ( gblErrorCount == 0 ) {
- out << "<ragel version=\"" VERSION "\" filename=\"" << inputFileName << "\"";
- writeLanguage( out );
- out << ">\n";
- parseData->generateXML( out );
- out << hostData;
- out << "</ragel>\n";
- }
- }
- }
-}
-
void errorStateLabels( const NameSet &locations );
-struct InputItem
-{
- enum Type {
- HostData,
- Write,
- };
-
- Type type;
- std::ostringstream data;
- std::string name;
- ParseData *pd;
- Vector<char *> writeArgs;
-
- InputLoc loc;
-
- InputItem *prev, *next;
-};
-
-/*
- * Global data.
- */
-
-struct Parser;
-
-typedef AvlMap<const char*, Parser*, CmpStr> ParserDict;
-typedef AvlMapEl<const char*, Parser*> ParserDictEl;
-
-typedef DList<Parser> ParserList;
-
-typedef DList<InputItem> InputItemList;
-
-extern ParserDict parserDict;
-extern ParserList parserList;
-extern InputItemList inputItems;
#endif
void xmlEscapeHost( std::ostream &out, char *data, long len );
-typedef Vector<const char *> ArgsVector;
-extern ArgsVector includePaths;
-
extern CodeStyle codeStyle;
/* IO filenames and stream. */
extern bool displayPrintables;
-extern bool graphvizDone;
extern int gblErrorCount;
-
/* Options. */
extern int numSplitPartitions;
extern bool noLineDirectives;
/* Target language and output style. */
extern CodeStyle codeStyle;
-/* Io globals. */
-extern std::istream *inStream;
-extern std::ostream *outStream;
-extern output_filter *outFilter;
-extern const char *outputFileName;
-
-/* Graphviz dot file generation. */
-extern bool graphvizDone;
-
extern int numSplitPartitions;
extern bool noLineDirectives;
#include "ragel.h"
#include "rlscan.h"
+#include "inputdata.h"
//#define LOG_TOKENS
/* If no errors and we are at the bottom of the include stack (the
* source file listed on the command line) then write out the data. */
if ( includeDepth == 0 && machineSpec == 0 && machineName == 0 )
- inputItems.tail->data.write( ts, te-ts );
+ id.inputItems.tail->data.write( ts, te-ts );
}
/*
if ( !importMachines && inclSectionTarg == 0 ) {
ignoreSection = false;
- ParserDictEl *pdEl = parserDict.find( machine );
+ ParserDictEl *pdEl = id.parserDict.find( machine );
if ( pdEl == 0 ) {
pdEl = new ParserDictEl( machine );
pdEl->value = new Parser( fileName, machine, sectionLoc );
pdEl->value->init();
- parserDict.insert( pdEl );
- parserList.append( pdEl->value );
+ id.parserDict.insert( pdEl );
+ id.parserList.append( pdEl->value );
}
parser = pdEl->value;
inputItem->loc.col = column;
inputItem->name = parser->sectionName;
inputItem->pd = parser->pd;
- inputItems.append( inputItem );
+ id.inputItems.append( inputItem );
}
}
action write_arg
{
if ( active() && machineSpec == 0 && machineName == 0 )
- inputItems.tail->writeArgs.append( strdup(tokdata) );
+ id.inputItems.tail->writeArgs.append( strdup(tokdata) );
}
action write_close
{
if ( active() && machineSpec == 0 && machineName == 0 )
- inputItems.tail->writeArgs.append( 0 );
+ id.inputItems.tail->writeArgs.append( 0 );
}
write_stmt =
inputItem->type = InputItem::HostData;
inputItem->loc.line = line;
inputItem->loc.col = column;
- inputItems.append( inputItem );
+ id.inputItems.append( inputItem );
}
}
}
}
/* Search from the include paths given on the command line. */
- for ( ArgsVector::Iter incp = includePaths; incp.lte(); incp++ ) {
+ for ( ArgsVector::Iter incp = id.includePaths; incp.lte(); incp++ ) {
long pathLen = strlen( *incp );
long checkLen = pathLen + 1 + length;
char *check = new char[checkLen+1];
/* Target language and output style. */
extern CodeStyle codeStyle;
-/* Io globals. */
-extern istream *inStream;
-extern ostream *outStream;
-extern output_filter *outFilter;
-extern const char *outputFileName;
-
-/* Graphviz dot file generation. */
-extern bool graphvizDone;
-
extern int numSplitPartitions;
/*
void RubyCodeGen::finishRagelDef()
{
-
if ( codeStyle == GenGoto || codeStyle == GenFGoto ||
codeStyle == GenIpGoto || codeStyle == GenSplit )
{
#include "gendata.h"
#include "inputdata.h"
#include <string.h>
+#include "rlparse.h"
+#include "version.h"
using namespace std;
close_ragel_def();
}
+void writeLanguage( std::ostream &out )
+{
+ out << " lang=\"";
+ switch ( hostLang->lang ) {
+ case HostLang::C: out << "C"; break;
+ case HostLang::D: out << "D"; break;
+ case HostLang::Java: out << "Java"; break;
+ case HostLang::Ruby: out << "Ruby"; break;
+ case HostLang::CSharp: out << "C#"; break;
+ }
+ out << "\"";
+}
+
+void writeMachines( std::ostream &out, std::string hostData, const char *inputFileName )
+{
+ if ( machineSpec == 0 && machineName == 0 ) {
+ /* No machine spec or machine name given. Generate everything. */
+ for ( ParserDict::Iter parser = id.parserDict; parser.lte(); parser++ ) {
+ ParseData *pd = parser->value->pd;
+ if ( pd->instanceList.length() > 0 )
+ pd->prepareMachineGen( 0 );
+ }
+
+ if ( gblErrorCount == 0 ) {
+ out << "<ragel version=\"" VERSION "\" filename=\"" << inputFileName << "\"";
+ writeLanguage( out );
+ out << ">\n";
+ for ( ParserDict::Iter parser = id.parserDict; parser.lte(); parser++ ) {
+ ParseData *pd = parser->value->pd;
+ if ( pd->instanceList.length() > 0 )
+ pd->generateXML( out );
+ }
+ out << hostData;
+ out << "</ragel>\n";
+ }
+ }
+ else if ( id.parserDict.length() > 0 ) {
+ /* There is either a machine spec or machine name given. */
+ ParseData *parseData = 0;
+ GraphDictEl *graphDictEl = 0;
+
+ /* Traverse the sections, break out when we find a section/machine
+ * that matches the one specified. */
+ for ( ParserDict::Iter parser = id.parserDict; parser.lte(); parser++ ) {
+ ParseData *checkPd = parser->value->pd;
+ if ( machineSpec == 0 || strcmp( checkPd->sectionName, machineSpec ) == 0 ) {
+ GraphDictEl *checkGdEl = 0;
+ if ( machineName == 0 || (checkGdEl =
+ checkPd->graphDict.find( machineName )) != 0 )
+ {
+ /* Have a machine spec and/or machine name that matches
+ * the -M/-S options. */
+ parseData = checkPd;
+ graphDictEl = checkGdEl;
+ break;
+ }
+ }
+ }
+
+ if ( parseData == 0 )
+ error() << "could not locate machine specified with -S and/or -M" << endl;
+ else {
+ /* Section/Machine to emit was found. Prepare and emit it. */
+ parseData->prepareMachineGen( graphDictEl );
+ if ( gblErrorCount == 0 ) {
+ out << "<ragel version=\"" VERSION "\" filename=\"" << inputFileName << "\"";
+ writeLanguage( out );
+ out << ">\n";
+ parseData->generateXML( out );
+ out << hostData;
+ out << "</ragel>\n";
+ }
+ }
+ }
+}
+