From 0ee8bfa74d810b5107ff81e17a63fbebaa8f6f08 Mon Sep 17 00:00:00 2001 From: thurston Date: Sat, 21 Mar 2009 20:15:43 +0000 Subject: [PATCH] Moved some global data into InputData. Not all there yet. git-svn-id: http://svn.complang.org/ragel/trunk@751 052ea7fc-9027-0410-9066-f65837a77df0 --- ragel/cdcodegen.cpp | 10 ---- ragel/inputdata.h | 52 +++++++++++++++++++-- ragel/main.cpp | 127 ++++++++++++++------------------------------------ ragel/parsedata.cpp | 76 ------------------------------ ragel/parsedata.h | 34 -------------- ragel/ragel.h | 14 ------ ragel/rlscan.rl | 19 ++++---- ragel/rubycodegen.cpp | 10 ---- ragel/xmlcodegen.cpp | 78 +++++++++++++++++++++++++++++++ 9 files changed, 171 insertions(+), 249 deletions(-) diff --git a/ragel/cdcodegen.cpp b/ragel/cdcodegen.cpp index ceb0030..01eb50d 100644 --- a/ragel/cdcodegen.cpp +++ b/ragel/cdcodegen.cpp @@ -44,16 +44,6 @@ using std::cout; 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; diff --git a/ragel/inputdata.h b/ragel/inputdata.h index e41b8f0..0420a29 100644 --- a/ragel/inputdata.h +++ b/ragel/inputdata.h @@ -23,22 +23,66 @@ #define _INPUT_DATA #include "gendata.h" +#include +#include struct Parser; +struct ParseData; + +struct InputItem +{ + enum Type { + HostData, + Write, + }; + + Type type; + std::ostringstream data; + std::string name; + ParseData *pd; + Vector writeArgs; + + InputLoc loc; + + InputItem *prev, *next; +}; + +struct Parser; + +typedef AvlMap ParserDict; +typedef AvlMapEl ParserDictEl; +typedef DList ParserList; +typedef DList InputItemList; +typedef Vector 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(); @@ -52,4 +96,6 @@ struct InputData void csharpDefaultFileName( const char *inputFile ); }; +extern InputData id; + #endif diff --git a/ragel/main.cpp b/ragel/main.cpp index 91e279a..4e7f676 100644 --- a/ragel/main.cpp +++ b/ragel/main.cpp @@ -71,6 +71,8 @@ using std::streamsize; MinimizeLevel minimizeLevel = MinimizePartition2; MinimizeOpt minimizeOpt = MinimizeMostOps; +InputData id; + /* Graphviz dot file generation. */ const char *machineSpec = 0, *machineName = 0; bool machineSpecFound = false; @@ -87,22 +89,10 @@ int numSplitPartitions = 0; 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() { @@ -227,7 +217,7 @@ void escapeLineDirectivePath( std::ostream &out, char *path ) } } -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); @@ -249,11 +239,11 @@ void processArgs( int argc, const char **argv, const char *&inputFileName ) 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; @@ -316,7 +306,7 @@ void processArgs( int argc, const char **argv, const char *&inputFileName ) if ( *pc.paramArg == 0 ) error() << "please specify an argument to -I" << endl; else { - includePaths.append( pc.paramArg ); + id.includePaths.append( pc.paramArg ); } break; @@ -435,26 +425,24 @@ void processArgs( int argc, const char **argv, const char *&inputFileName ) /* 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; @@ -464,9 +452,9 @@ void process( const char *inputFileName ) 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.. */ @@ -474,7 +462,7 @@ void process( const char *inputFileName ) exit(1); /* Now send EOF to all parsers. */ - inputData.terminateAllParsers(); + id.terminateAllParsers(); /* Bail on above error. */ if ( gblErrorCount > 0 ) @@ -482,21 +470,25 @@ void process( const char *inputFileName ) /* 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; @@ -507,18 +499,12 @@ void process( const char *inputFileName ) /* 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 ) @@ -539,55 +525,10 @@ 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. */ @@ -598,7 +539,7 @@ int main( int argc, const char **argv ) /* 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. */ @@ -606,14 +547,14 @@ int main( int argc, const char **argv ) 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 ); diff --git a/ragel/parsedata.cpp b/ragel/parsedata.cpp index 73dcc33..5631d48 100644 --- a/ragel/parsedata.cpp +++ b/ragel/parsedata.cpp @@ -1448,19 +1448,6 @@ void ParseData::generateReduced( InputData &inputData ) } } -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(); @@ -1478,66 +1465,3 @@ void ParseData::generateXML( ostream &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 = parserDict; parser.lte(); parser++ ) { - ParseData *pd = parser->value->pd; - if ( pd->instanceList.length() > 0 ) - pd->prepareMachineGen( 0 ); - } - - if ( gblErrorCount == 0 ) { - 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 << "\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 << "\n"; - parseData->generateXML( out ); - out << hostData; - out << "\n"; - } - } - } -} - diff --git a/ragel/parsedata.h b/ragel/parsedata.h index 20ae599..3cad47e 100644 --- a/ragel/parsedata.h +++ b/ragel/parsedata.h @@ -375,39 +375,5 @@ FsmAp *dotStarFsm( ParseData *pd ); void errorStateLabels( const NameSet &locations ); -struct InputItem -{ - enum Type { - HostData, - Write, - }; - - Type type; - std::ostringstream data; - std::string name; - ParseData *pd; - Vector writeArgs; - - InputLoc loc; - - InputItem *prev, *next; -}; - -/* - * Global data. - */ - -struct Parser; - -typedef AvlMap ParserDict; -typedef AvlMapEl ParserDictEl; - -typedef DList ParserList; - -typedef DList InputItemList; - -extern ParserDict parserDict; -extern ParserList parserList; -extern InputItemList inputItems; #endif diff --git a/ragel/ragel.h b/ragel/ragel.h index 1372120..bfcda67 100644 --- a/ragel/ragel.h +++ b/ragel/ragel.h @@ -98,17 +98,12 @@ struct XmlParser; void xmlEscapeHost( std::ostream &out, char *data, long len ); -typedef Vector 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; @@ -118,15 +113,6 @@ std::ostream &error(); /* 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; diff --git a/ragel/rlscan.rl b/ragel/rlscan.rl index 1c5e4bb..6a99cc7 100644 --- a/ragel/rlscan.rl +++ b/ragel/rlscan.rl @@ -25,6 +25,7 @@ #include "ragel.h" #include "rlscan.h" +#include "inputdata.h" //#define LOG_TOKENS @@ -202,7 +203,7 @@ void Scanner::pass() /* 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 ); } /* @@ -278,13 +279,13 @@ void Scanner::handleMachine() 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; @@ -416,20 +417,20 @@ void Scanner::handleImport() 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 = @@ -538,7 +539,7 @@ void Scanner::endSection( ) inputItem->type = InputItem::HostData; inputItem->loc.line = line; inputItem->loc.col = column; - inputItems.append( inputItem ); + id.inputItems.append( inputItem ); } } } @@ -582,7 +583,7 @@ char **Scanner::makeIncludePathChecks( const char *thisFileName, } /* 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]; diff --git a/ragel/rubycodegen.cpp b/ragel/rubycodegen.cpp index 5b50346..78ffce7 100644 --- a/ragel/rubycodegen.cpp +++ b/ragel/rubycodegen.cpp @@ -58,15 +58,6 @@ using std::endl; /* 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; /* @@ -695,7 +686,6 @@ ostream &RubyCodeGen::source_error( const InputLoc &loc ) void RubyCodeGen::finishRagelDef() { - if ( codeStyle == GenGoto || codeStyle == GenFGoto || codeStyle == GenIpGoto || codeStyle == GenSplit ) { diff --git a/ragel/xmlcodegen.cpp b/ragel/xmlcodegen.cpp index 30b757e..bd4c2d0 100644 --- a/ragel/xmlcodegen.cpp +++ b/ragel/xmlcodegen.cpp @@ -28,6 +28,8 @@ #include "gendata.h" #include "inputdata.h" #include +#include "rlparse.h" +#include "version.h" using namespace std; @@ -1396,4 +1398,80 @@ void BackendGen::makeBackend() 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 << "\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 << "\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 << "\n"; + parseData->generateXML( out ); + out << hostData; + out << "\n"; + } + } + } +} + -- 2.7.4