"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/inputdata.cc" between
ragel-7.0.0.10.tar.gz and ragel-7.0.0.11.tar.gz

About: Ragel compiles executable finite state machines from regular languages (C, C++, Obj-C, C#, D, Java, Go and Ruby). Development version.

inputdata.cc  (ragel-7.0.0.10):inputdata.cc  (ragel-7.0.0.11)
/* /*
* Copyright 2008-2016 Adrian Thurston <thurston@colm.net> * Copyright 2008-2018 Adrian Thurston <thurston@colm.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to * of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the * deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is * sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in al l * The above copyright notice and this permission notice shall be included in al l
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
skipping to change at line 30 skipping to change at line 30
* SOFTWARE. * SOFTWARE.
*/ */
#include "ragel.h" #include "ragel.h"
#include "common.h" #include "common.h"
#include "inputdata.h" #include "inputdata.h"
#include "parsedata.h" #include "parsedata.h"
#include "load.h" #include "load.h"
#include "rlscan.h" #include "rlscan.h"
#include "reducer.h" #include "reducer.h"
#include "version.h"
#include "pcheck.h"
#include <colm/colm.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <iostream> #include <iostream>
#include <iomanip>
#include <fstream>
#include <unistd.h> #include <unistd.h>
#include <sstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/wait.h>
#ifdef _WIN32
#include <windows.h>
#include <psapi.h>
#include <time.h>
#include <io.h>
#include <process.h>
#if _MSC_VER
#define S_IRUSR _S_IREAD
#define S_IWUSR _S_IWRITE
#endif
#endif
using std::istream; using std::istream;
using std::ifstream; using std::ifstream;
using std::ofstream;
using std::stringstream; using std::stringstream;
using std::ostream; using std::ostream;
using std::endl; using std::endl;
using std::ios; using std::ios;
InputData::~InputData() InputData::~InputData()
{ {
inputItems.empty(); inputItems.empty();
parseDataList.empty(); parseDataList.empty();
sectionList.empty(); sectionList.empty();
skipping to change at line 69 skipping to change at line 97
if ( histogramFn != 0 ) if ( histogramFn != 0 )
::free( (void*)histogramFn ); ::free( (void*)histogramFn );
if ( histogram != 0 ) if ( histogram != 0 )
delete[] histogram; delete[] histogram;
for ( ArgsVector::Iter bl = breadthLabels; bl.lte(); bl++ ) for ( ArgsVector::Iter bl = breadthLabels; bl.lte(); bl++ )
free( (void*) *bl ); free( (void*) *bl );
} }
/* Invoked by the parser when the root element is opened. */
void InputData::cDefaultFileName( const char *inputFile )
{
/* If the output format is code and no output file name is given, then
* make a default. */
if ( outputFileName == 0 ) {
const char *ext = findFileExtension( inputFile );
if ( ext != 0 && strcmp( ext, ".rh" ) == 0 )
outputFileName = fileNameFromStem( inputFile, ".h" );
else {
const char *defExtension = 0;
switch ( hostLang->lang ) {
case HostLang::C: defExtension = ".c"; break;
default: break;
}
outputFileName = fileNameFromStem( inputFile, defExtensio
n );
}
}
}
void InputData::asmDefaultFileName( const char *inputFile )
{
if ( outputFileName == 0 )
outputFileName = fileNameFromStem( inputFile, ".s" );
}
void InputData::makeDefaultFileName() void InputData::makeDefaultFileName()
{ {
switch ( hostLang->lang ) { if ( outputFileName == 0 )
case HostLang::C: outputFileName = (hostLang->defaultOutFn)( inputFileName );
cDefaultFileName( inputFileName );
break;
case HostLang::Asm:
asmDefaultFileName( inputFileName );
break;
}
} }
bool InputData::isBreadthLabel( const string &label ) bool InputData::isBreadthLabel( const string &label )
{ {
for ( ArgsVector::Iter bl = breadthLabels; bl.lte(); bl++ ) { for ( ArgsVector::Iter bl = breadthLabels; bl.lte(); bl++ ) {
if ( label == *bl ) if ( label == *bl )
return true; return true;
} }
return false; return false;
} }
skipping to change at line 232 skipping to change at line 228
void InputData::writeOutput( InputItem *ii ) void InputData::writeOutput( InputItem *ii )
{ {
switch ( ii->type ) { switch ( ii->type ) {
case InputItem::Write: { case InputItem::Write: {
CodeGenData *cgd = ii->pd->cgd; CodeGenData *cgd = ii->pd->cgd;
cgd->writeStatement( ii->loc, ii->writeArgs.size(), cgd->writeStatement( ii->loc, ii->writeArgs.size(),
ii->writeArgs, generateDot, hostLang ); ii->writeArgs, generateDot, hostLang );
break; break;
} }
case InputItem::HostData: { case InputItem::HostData: {
if ( hostLang->lang == HostLang::C ) { switch ( hostLang->backend ) {
if ( ii->loc.fileName != 0 ) { case Direct:
if ( !noLineDirectives ) { if ( hostLang->_lang == HostLang::C ) {
*outStream << "\n#line " << ii->l if ( ii->loc.fileName != 0 ) {
oc.line << if ( !noLineDirectives )
" \"" << ii->loc. {
fileName << "\"\n"; *outStream << "\n
#line " << ii->loc.line <<
"
\"" << ii->loc.fileName << "\"\n";
}
}
} }
}
}
*outStream << ii->data.str(); *outStream << ii->data.str();
break;
case Translated:
openHostBlock( '@', this, *outStream, inp
utFileName, ii->loc.line );
translatedHostData( *outStream, ii->data.
str() );
*outStream << "}@";
break;
}
break; break;
} }
case InputItem::EndSection: { case InputItem::EndSection: {
break; break;
} }
} }
} }
void InputData::writeOutput() void InputData::writeOutput()
{ {
skipping to change at line 396 skipping to change at line 401
while ( lastFlush != 0 ) { while ( lastFlush != 0 ) {
/* Flush out. */ /* Flush out. */
writeOutput( lastFlush ); writeOutput( lastFlush );
lastFlush = lastFlush->next; lastFlush = lastFlush->next;
} }
} }
void InputData::makeTranslateOutputFileName() void InputData::makeTranslateOutputFileName()
{ {
if ( false ) { origOutputFileName = outputFileName;
origOutputFileName = outputFileName; outputFileName = fileNameFromStem( outputFileName, ".ri" );
outputFileName = fileNameFromStem( inputFileName, ".ri" ); genOutputFileName = outputFileName;
genOutputFileName = outputFileName;
}
} }
#ifdef WITH_RAGEL_KELBT #ifdef WITH_RAGEL_KELBT
void InputData::parseKelbt() void InputData::parseKelbt()
{ {
/* /*
* Ragel Parser from ragel 6. * Ragel Parser from ragel 6.
*/ */
ifstream *inFileStream; ifstream *inFileStream;
stringstream *inStringStream;
istream *inStream; istream *inStream;
if ( inLibRagel ) { /* Open the input file for reading. */
/* Open the input file for reading. */ assert( inputFileName != 0 );
assert( inputFileName != 0 ); inFileStream = new ifstream( inputFileName );
inStringStream = new stringstream( string( input ) ); if ( ! inFileStream->is_open() )
inStream = inStringStream; error() << "could not open " << inputFileName << " for reading" <
} < endp;
else { inStream = inFileStream;
/* Open the input file for reading. */
assert( inputFileName != 0 );
inFileStream = new ifstream( inputFileName );
if ( ! inFileStream->is_open() )
error() << "could not open " << inputFileName << " for re
ading" << endp;
inStream = inFileStream;
}
makeFirstInputItem(); makeFirstInputItem();
Scanner scanner( this, inputFileName, *inStream, 0, 0, 0, false ); Scanner scanner( this, inputFileName, *inStream, 0, 0, 0, false );
scanner.sectionPass = true; scanner.sectionPass = true;
scanner.do_scan(); scanner.do_scan();
inStream->clear(); inStream->clear();
inStream->seekg( 0, std::ios::beg ); inStream->seekg( 0, std::ios::beg );
skipping to change at line 451 skipping to change at line 445
scanner.do_scan(); scanner.do_scan();
/* Finished, final check for errors.. */ /* Finished, final check for errors.. */
if ( errorCount > 0 ) if ( errorCount > 0 )
abortCompile( 1 ); abortCompile( 1 );
/* Bail on above error. */ /* Bail on above error. */
if ( errorCount > 0 ) if ( errorCount > 0 )
abortCompile( 1 ); abortCompile( 1 );
if ( inLibRagel ) delete inFileStream;
delete inStringStream;
else
delete inFileStream;
} }
void InputData::processKelbt() void InputData::processKelbt()
{ {
/* With the kelbt version we implement two parse passes. The first is use d /* With the kelbt version we implement two parse passes. The first is use d
* to identify the last time that any given machine is referenced by a * to identify the last time that any given machine is referenced by a
* ragel section. In the second pass we parse, compile, and emit as far * ragel section. In the second pass we parse, compile, and emit as far
* forward as possible when we encounter the last reference to a machine. * forward as possible when we encounter the last reference to a machine.
* */ * */
if ( generateDot ) { if ( generateDot ) {
parseKelbt(); parseKelbt();
terminateAllParsers(); terminateAllParsers();
processDot(); processDot();
} }
else { else {
makeDefaultFileName();
makeTranslateOutputFileName();
createOutputStream(); createOutputStream();
openOutput(); openOutput();
parseKelbt(); parseKelbt();
flushRemaining(); flushRemaining();
closeOutput(); closeOutput();
} }
assert( errorCount == 0 ); assert( errorCount == 0 );
} }
#endif #endif
skipping to change at line 511 skipping to change at line 500
} }
if ( errorCount ) if ( errorCount )
return false; return false;
makeFirstInputItem(); makeFirstInputItem();
curItem = inputItems.head; curItem = inputItems.head;
lastFlush = inputItems.head; lastFlush = inputItems.head;
topLevel->reduceFile( inputFileName, false ); topLevel->reduceFile( "rlparse", inputFileName );
if ( errorCount ) if ( errorCount )
return false; return false;
bool success = topLevel->success; bool success = topLevel->success;
delete topLevel; delete topLevel;
return success; return success;
} }
bool InputData::processReduce() bool InputData::processReduce()
{ {
if ( generateDot ) { if ( generateDot ) {
parseReduce(); parseReduce();
processDot(); processDot();
return true; return true;
} }
else { else {
makeDefaultFileName();
makeTranslateOutputFileName();
createOutputStream(); createOutputStream();
openOutput(); openOutput();
bool success = parseReduce(); bool success = parseReduce();
if ( success ) if ( success )
flushRemaining(); flushRemaining();
closeOutput(); closeOutput();
if ( !success && outputFileName != 0 ) if ( !success && outputFileName != 0 )
unlink( outputFileName ); unlink( outputFileName );
return success; return success;
} }
} }
bool InputData::process() bool InputData::process()
{ {
switch ( frontend ) { switch ( frontend ) {
case KelbtBased: { case KelbtBased: {
#ifdef WITH_RAGEL_KELBT #ifdef WITH_RAGEL_KELBT
processKelbt(); processKelbt();
#endif #endif
return true; return true;
} }
case ReduceBased: { case ReduceBased: {
return processReduce(); return processReduce();
} }
} }
return false; return false;
} }
/* Print a summary of the options. */
void InputData::usage()
{
info() <<
"usage: ragel [options] file\n"
"general:\n"
" -h, -H, -?, --help Print this usage and exit\n"
" -v, --version Print version information and exit\n"
" -o <file> Write output to <file>\n"
" -s Print some statistics and compilation info to stderr\n"
" -d Do not remove duplicates from action lists\n"
" -I <dir> Add <dir> to the list of directories to search\n"
" for included an imported files\n"
" --rlhc Show the rlhc command used to compile\n"
" --save-temps Do not delete intermediate file during compilation\n"
" --no-intermediate Disable call to rlhc, leave behind intermediate\n"
"error reporting format:\n"
" --error-format=gnu file:line:column: message (default)\n"
" --error-format=msvc file(line,column): message\n"
"fsm minimization:\n"
" -n Do not perform minimization\n"
" -m Minimize at the end of the compilation\n"
" -l Minimize after most operations (default)\n"
" -e Minimize after every operation\n"
"visualization:\n"
" -V Generate a dot file for Graphviz\n"
" -p Display printable characters on labels\n"
" -S <spec> FSM specification to output (for graphviz output)\n"
" -M <machine> Machine definition/instantiation to output (for\n"
" graphviz output)\n"
"host language:\n"
" -C C, C++, Obj-C or Obj-C++ (default)\n"
" All code styles supported.\n"
" --asm --gas-x86-64-sys-v\n"
" GNU AS, x86_64, System V ABI.\n"
" Generated in a code style equivalent to -G2\n"
" -D D All code styles supported\n"
" -Z Go All code styles supported\n"
" -A C# -T0 -T1 -F0 -F1 -G0 -G1\n"
" -J Java -T0 -T1 -F0 -F1\n"
" -R Ruby -T0 -T1 -F0 -F1\n"
" -O OCaml -T0 -T1 -F0 -F1\n"
" -U Rust -T0 -T1 -F0 -F1\n"
" -Y Julia -T0 -T1 -F0 -F1\n"
" -K Crack -T0 -T1 -F0 -F1\n"
" -P JavaScript -T0 -T1 -F0 -F1\n"
"line directives:\n"
" -L Inhibit writing of #line directives\n"
"code style:\n"
" -T0 Binary search (default)\n"
" -T1 Binary search with expanded actions \n"
" -F0 Flat table\n"
" -F1 Flat table with expanded actions\n"
" -G0 Switch-driven\n"
" -G1 Switch-driven with expanded actions\n"
" -G2 Goto-driven with expanded actions\n"
"large machines:\n"
" --integral-tables Use integers for table data (default)\n"
" --string-tables Encode table data into strings for faster host lang\n"
" compilation\n"
"analysis:\n"
" --prior-interaction Search for condition-based general repetitions\
n"
" that will not function properly due to state mo
d\n"
" overlap and must be NFA reps. \n"
" --conds-depth=D Search for high-cost conditions inside a prefix
\n"
" of the machine (depth D from start state).\n"
" --state-limit=L Report fail if number of states exceeds this\n"
" during compilation.\n"
" --breadth-check=E1,E2,.. Report breadth cost of named entry points and\n
"
" the start state.\n"
" --input-histogram=FN Input char histogram for breadth check. If\n"
" unspecified a flat histogram is used.\n"
"testing:\n"
" --kelbt-frontend Compile using original ragel + kelbt frontend\n"
" Requires ragel be built with ragel + kelbt support\n
"
" --colm-frontend Compile using a colm-based recursive descent\n"
" frontend\n"
" --reduce-frontend Compile using a colm-based reducer (default)\n"
" --direct-backend Use the direct backend for supported langs (default)
\n"
" --colm-backend Use the translation backed for C\n"
" --var-backend Use the variable-based backend for langs that\n"
" support goto-based\n"
" --goto-backend Use the goto-based backend for supported langs\n"
" (default)\n"
" --supported-host-langs Show supported host languages by command line arg\n"
" --supported-frontends Show supported frontends\n"
" --supported-backends Show supported backends\n"
" --force-libragel Cause mainline to behave like libragel\n"
;
abortCompile( 0 );
}
/* Print version information and exit. */
void InputData::version()
{
info() << "Ragel State Machine Compiler version " VERSION << " " PUBDATE
<< endl <<
"Copyright (c) 2001-2018 by Adrian Thurston" << endl;
abortCompile( 0 );
}
void InputData::showHostLangNames()
{
ostream &out = info();
for ( int i = 0; i < numHostLangs; i++ ) {
if ( i > 0 )
out << " ";
out << hostLangs[i]->name;
}
out << endl;
abortCompile( 0 );
}
void InputData::showHostLangArgs()
{
ostream &out = info();
for ( int i = 0; i < numHostLangs; i++ ) {
if ( i > 0 )
out << " ";
out << hostLangs[i]->arg;
}
out << endl;
abortCompile( 0 );
}
void InputData::showFrontends()
{
ostream &out = info();
out << "--colm-frontend";
out << " --reduce-frontend";
#ifdef WITH_RAGEL_KELBT
out << " --kelbt-frontend";
#endif
out << endl;
abortCompile( 0 );
}
void InputData::showBackends()
{
info() <<
"--direct-backend --colm-backend" << endl;
abortCompile( 0 );
}
InputLoc makeInputLoc( const char *fileName, int line, int col )
{
InputLoc loc( fileName, line, col );
return loc;
}
void escapeLineDirectivePath( std::ostream &out, char *path )
{
for ( char *pc = path; *pc != 0; pc++ ) {
if ( *pc == '\\' )
out << "\\\\";
else
out << *pc;
}
}
void InputData::parseArgs( int argc, const char **argv )
{
ParamCheck pc( "r:o:dnmleabjkS:M:I:CEJZRAOKUYvHh?-:sT:F:G:LpV", argc, arg
v );
/* Decide if we were invoked using a path variable, or with an explicit p
ath. */
const char *lastSlash = strrchr( argv[0], '/' );
if ( lastSlash == 0 ) {
/* Defualt to the the binary install location. */
dirName = BINDIR;
}
else {
/* Compute dirName from argv0. */
dirName = string( argv[0], lastSlash - argv[0] );
}
/* FIXME: Need to check code styles VS langauge. */
while ( pc.check() ) {
switch ( pc.state ) {
case ParamCheck::match:
switch ( pc.parameter ) {
case 'V':
generateDot = true;
break;
/* Output. */
case 'o':
if ( *pc.paramArg == 0 )
error() << "a zero length output file nam
e was given" << endl;
else if ( outputFileName != 0 )
error() << "more than one output file nam
e was given" << endl;
else {
/* Ok, remember the output file name. */
outputFileName = new char[strlen(pc.param
Arg)+1];
strcpy( (char*)outputFileName, pc.paramAr
g );
}
break;
/* Flag for turning off duplicate action removal. */
case 'd':
wantDupsRemoved = false;
break;
/* Minimization, mostly hidden options. */
case 'n':
minimizeOpt = MinimizeNone;
break;
case 'm':
minimizeOpt = MinimizeEnd;
break;
case 'l':
minimizeOpt = MinimizeMostOps;
break;
case 'e':
minimizeOpt = MinimizeEveryOp;
break;
case 'a':
#ifdef TO_UPGRADE_CONDS
minimizeLevel = MinimizeApprox;
#else
error() << "minimize approx (-a) unsupported in t
his version" << endp;
#endif
break;
case 'b':
#ifdef TO_UPGRADE_CONDS
minimizeLevel = MinimizeStable;
#else
error() << "minimize stable (-b) unsupported in t
his version" << endp;
#endif
break;
case 'j':
minimizeLevel = MinimizePartition1;
break;
case 'k':
minimizeLevel = MinimizePartition2;
break;
/* Machine spec. */
case 'S':
if ( *pc.paramArg == 0 )
error() << "please specify an argument to
-S" << endl;
else if ( machineSpec != 0 )
error() << "more than one -S argument was
given" << endl;
else {
/* Ok, remember the path to the machine t
o generate. */
machineSpec = pc.paramArg;
}
break;
/* Machine path. */
case 'M':
if ( *pc.paramArg == 0 )
error() << "please specify an argument to
-M" << endl;
else if ( machineName != 0 )
error() << "more than one -M argument was
given" << endl;
else {
/* Ok, remember the machine name to gener
ate. */
machineName = pc.paramArg;
}
break;
case 'I':
if ( *pc.paramArg == 0 )
error() << "please specify an argument to
-I" << endl;
else {
includePaths.append( pc.paramArg );
}
break;
/* Host language types. */
case 'C':
hostLang = &hostLangC;
break;
// case 'D':
// hostLang = &hostLangD;
// break;
// case 'Z':
// hostLang = &hostLangGo;
// break;
// case 'J':
// hostLang = &hostLangJava;
// break;
// case 'R':
// hostLang = &hostLangRuby;
// break;
// case 'A':
// hostLang = &hostLangCSharp;
// break;
// case 'O':
// hostLang = &hostLangOCaml;
// break;
// case 'K':
// hostLang = &hostLangCrack;
// break;
// case 'U':
// hostLang = &hostLangRust;
// break;
// case 'Y':
// hostLang = &hostLangJulia;
// break;
// case 'P':
// hostLang = &hostLangJS;
// break;
/* Version and help. */
case 'v':
version();
break;
case 'H': case 'h': case '?':
usage();
break;
case 's':
printStatistics = true;
break;
case '-': {
char *arg = strdup( pc.paramArg );
char *eq = strchr( arg, '=' );
if ( eq != 0 )
*eq++ = 0;
if ( strcmp( arg, "help" ) == 0 )
usage();
else if ( strcmp( arg, "version" ) == 0 )
version();
else if ( strcmp( arg, "error-format" ) == 0 ) {
if ( eq == 0 )
error() << "expecting '=value' fo
r error-format" << endl;
else if ( strcmp( eq, "gnu" ) == 0 )
errorFormat = ErrorFormatGNU;
else if ( strcmp( eq, "msvc" ) == 0 )
errorFormat = ErrorFormatMSVC;
else
error() << "invalid value for err
or-format" << endl;
}
else if ( strcmp( arg, "rbx" ) == 0 )
rubyImpl = Rubinius;
else if ( strcmp( arg, "rlhc" ) == 0 )
rlhc = true;
else if ( strcmp( arg, "no-intermediate" ) == 0 )
noIntermediate = true;
#ifdef WITH_RAGEL_KELBT
else if ( strcmp( arg, "kelbt-frontend" ) == 0 )
{
frontend = KelbtBased;
frontendSpecified = true;
}
#else
else if ( strcmp( arg, "kelbt-frontend" ) == 0 )
{
error() << "--kelbt-frontend specified bu
t, "
"ragel not built with rag
el+kelbt support" << endp;
}
#endif
else if ( strcmp( arg, "reduce-frontend" ) == 0 )
{
frontend = ReduceBased;
frontendSpecified = true;
}
else if ( strcmp( arg, "string-tables" ) == 0 )
stringTables = true;
else if ( strcmp( arg, "integral-tables" ) == 0 )
stringTables = false;
else if ( strcmp( arg, "host-lang-names" ) == 0 )
showHostLangNames();
else if ( strcmp( arg, "host-lang-args" ) == 0 ||
strcmp( arg, "supported-host-lang
s" ) == 0 )
showHostLangArgs();
else if ( strcmp( arg, "supported-frontends" ) ==
0 )
showFrontends();
else if ( strcmp( arg, "supported-backends" ) ==
0 )
showBackends();
else if ( strcmp( arg, "save-temps" ) == 0 )
saveTemps = true;
else if ( strcmp( arg, "prior-interaction" ) == 0
)
checkPriorInteraction = true;
else if ( strcmp( arg, "conds-depth" ) == 0 )
condsCheckDepth = strtol( eq, 0, 10 );
else if ( strcmp( arg, "state-limit" ) == 0 )
stateLimit = strtol( eq, 0, 10 );
else if ( strcmp( arg, "breadth-check" ) == 0 ) {
char *ptr = 0;
while ( true ) {
char *label = strtok_r( eq, ",",
&ptr );
eq = NULL;
if ( label == NULL )
break;
breadthLabels.append( strdup( lab
el ) );
}
checkBreadth = true;
}
else if ( strcmp( arg, "input-histogram" ) == 0 )
histogramFn = strdup(eq);
else if ( strcmp( arg, "force-libragel" ) == 0 )
forceLibRagel = true;
else {
error() << "--" << pc.paramArg <<
" is an invalid argument"
<< endl;
}
free( arg );
break;
}
/* Passthrough args. */
case 'T':
if ( pc.paramArg[0] == '0' )
codeStyle = GenBinaryLoop;
else if ( pc.paramArg[0] == '1' )
codeStyle = GenBinaryExp;
else {
error() << "-T" << pc.paramArg[0] <<
" is an invalid argument"
<< endl;
abortCompile( 1 );
}
break;
case 'F':
if ( pc.paramArg[0] == '0' )
codeStyle = GenFlatLoop;
else if ( pc.paramArg[0] == '1' )
codeStyle = GenFlatExp;
else {
error() << "-F" << pc.paramArg[0] <<
" is an invalid argument"
<< endl;
abortCompile( 1 );
}
break;
case 'G':
if ( pc.paramArg[0] == '0' )
codeStyle = GenSwitchLoop;
else if ( pc.paramArg[0] == '1' )
codeStyle = GenSwitchExp;
else if ( pc.paramArg[0] == '2' )
codeStyle = GenIpGoto;
else if ( pc.paramArg[0] == 'T' && pc.paramArg[1]
== '2' ) {
codeStyle = GenIpGoto;
maxTransitions = 32;
} else {
error() << "-G" << pc.paramArg[0] <<
" is an invalid argument"
<< endl;
abortCompile( 1 );
}
break;
case 'p':
displayPrintables = true;
break;
case 'L':
noLineDirectives = true;
break;
}
break;
case ParamCheck::invalid:
error() << "-" << pc.parameter << " is an invalid argumen
t" << endl;
break;
case ParamCheck::noparam:
/* It is interpreted as an input file. */
if ( *pc.curArg == 0 )
error() << "a zero length input file name was giv
en" << endl;
else if ( inputFileName != 0 )
error() << "more than one input file name was giv
en" << endl;
else {
/* OK, Remember the filename. */
inputFileName = pc.curArg;
}
break;
}
}
}
void InputData::loadHistogram()
{
const int alphsize = 256;
/* Init a default. */
histogram = new double[alphsize];
ifstream h( histogramFn );
if ( !h.is_open() )
error() << "histogram read: failed to open file: " << histogramFn
<< endp;
int i = 0;
double value;
while ( true ) {
if ( h >> value ) {
if ( i >= alphsize ) {
/* Too many items. */
error() << "histogram read: too many histogram va
lues,"
" expecting " << alphsize << " (f
or char alphabet)" << endp;
}
histogram[i] = value;
i++;
}
else {
/* Read failure. */
if ( h.eof() ) {
if ( i < alphsize ) {
error() << "histogram read: fell short of
" <<
alphsize << " items" << e
ndp;
}
break;
}
else {
error() << "histogram read: error at item " << i
<< endp;
}
}
}
}
void InputData::defaultHistogram()
{
/* Flat histogram. */
const int alphsize = 256;
histogram = new double[alphsize];
for ( int i = 0; i < alphsize; i++ ) {
histogram[i] = 1.0 / (double)alphsize;
}
}
void InputData::checkArgs()
{
/* 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 )
error() << "no input file given" << endl;
/* Bail on argument processing errors. */
if ( errorCount > 0 )
abortCompile( 1 );
/* Make sure we are not writing to the same file as the input file. */
if ( inputFileName != 0 && outputFileName != 0 &&
strcmp( inputFileName, outputFileName ) == 0 )
{
error() << "output file \"" << outputFileName <<
"\" is the same as the input file" << endp;
}
if ( !frontendSpecified )
frontend = ReduceBased;
if ( checkBreadth ) {
if ( histogramFn != 0 )
loadHistogram();
else
defaultHistogram();
}
}
char *InputData::readInput( const char *inputFileName )
{
struct stat st;
int res = stat( inputFileName, &st );
if ( res != 0 ) {
error() << inputFileName << ": stat failed: " << strerror(errno)
<< endl;
return 0;
}
std::ifstream in( inputFileName );
if ( !in.is_open() ) {
error() << inputFileName << ": could not open in force-libragel m
ode";
return 0;
}
char *input = new char[st.st_size+1];
in.read( input, st.st_size );
if ( in.gcount() != st.st_size ) {
error() << inputFileName << ": could not read in force-libragel m
ode";
delete[] input;
return 0;
}
input[st.st_size] = 0;
return input;
}
int InputData::main( int argc, const char **argv )
{
int code = 0;
try {
parseArgs( argc, argv );
checkArgs();
if ( !generateDot )
makeDefaultFileName();
if ( !process() )
abortCompile( 1 );
}
catch ( const AbortCompile &ac ) {
code = ac.code;
}
return code;
}
int InputData::rlhcRun( int argc, const char **argv )
{
struct colm_program *prg;
int exit_status;
prg = colm_new_program( rlhcSections );
colm_set_debug( prg, 0 );
colm_run_program( prg, argc, argv );
exit_status = colm_delete_program( prg );
return exit_status;
}
int InputData::rlhcMain( int argc, const char **argv )
{
int status = 0;
pid_t pid = 0;
parseArgs( argc, argv );
checkArgs();
makeDefaultFileName();
makeTranslateOutputFileName();
pid = fork();
if ( pid == 0 ) {
/* Child. */
if ( !process() )
abortCompile( 1 );
exit( 0 );
}
waitpid( pid, &status, 0 );
pid = fork();
if ( pid == 0 ) {
/* rlhc <input> <output> */
const char *_argv[] = { "rlhc",
genOutputFileName.c_str(),
origOutputFileName.c_str(), 0 };
rlhcRun( 3, _argv );
}
waitpid( pid, &status, 0 );
return 0;
}
 End of changes. 19 change blocks. 
77 lines changed or deleted 67 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)