Merge branch 'olesenm'

This commit is contained in:
andy 2009-08-11 13:10:47 +01:00
commit ab0b271ebe
3 changed files with 185 additions and 136 deletions

View File

@ -33,6 +33,7 @@ Description
#include "IOstreams.H"
#include "IFstream.H"
#include "IStringStream.H"
#include "cpuTime.H"
using namespace Foam;
@ -44,41 +45,76 @@ int main(int argc, char *argv[])
argList::noParallel();
argList::validArgs.insert("string .. stringN");
argList::validOptions.insert("file", "name");
argList::validOptions.insert("repeat", "count");
argList args(argc, argv, false, true);
forAll(args.additionalArgs(), argI)
{
const string& rawArg = args.additionalArgs()[argI];
Info<< "input string: " << rawArg << nl;
label repeat = 1;
args.optionReadIfPresent<label>("repeat", repeat);
IStringStream is(rawArg);
while (is.good())
cpuTime timer;
for (label count = 0; count < repeat; ++count)
{
forAll(args.additionalArgs(), argI)
{
token tok(is);
Info<< "token: " << tok.info() << endl;
const string& rawArg = args.additionalArgs()[argI];
if (count == 0)
{
Info<< "input string: " << rawArg << nl;
}
IStringStream is(rawArg);
while (is.good())
{
token tok(is);
if (count == 0)
{
Info<< "token: " << tok.info() << endl;
}
}
if (count == 0)
{
Info<< nl;
IOobject::writeDivider(Info);
}
}
Info<< nl;
IOobject::writeDivider(Info);
}
}
Info<< "tokenized args " << repeat << " times in "
<< timer.cpuTimeIncrement() << " s\n\n";
if (args.optionFound("file"))
{
IFstream is(args.option("file"));
Info<< "tokenizing file: " << args.option("file") << nl;
while (is.good())
for (label count = 0; count < repeat; ++count)
{
token tok(is);
Info<< "token: " << tok.info() << endl;
IFstream is(args.option("file"));
if (count == 0)
{
Info<< "tokenizing file: " << args.option("file") << nl;
}
while (is.good())
{
token tok(is);
if (count == 0)
{
Info<< "token: " << tok.info() << endl;
}
}
if (count == 0)
{
Info<< nl;
IOobject::writeDivider(Info);
}
}
Info<< nl;
IOobject::writeDivider(Info);
Info<< "tokenized file " << repeat << " times in "
<< timer.cpuTimeIncrement() << " s\n\n";
}
return 0;

View File

@ -42,7 +42,7 @@ char Foam::ISstream::nextValid()
while (get(c) && isspace(c))
{}
// Return if stream is bad
// Return if stream is bad - ie, previous get() failed
if (bad() || isspace(c))
{
return 0;
@ -102,7 +102,8 @@ char Foam::ISstream::nextValid()
Foam::Istream& Foam::ISstream::read(token& t)
{
static char charBuffer[128];
static const int maxLen = 128;
static char buf[maxLen];
// Return the put back token if it exists
if (Istream::getBack(t))
@ -114,7 +115,7 @@ Foam::Istream& Foam::ISstream::read(token& t)
// Lines are counted by '\n'
// Get next 'valid character': i.e. proceed through any whitespace
// and/or comments until a semantically valid character is hit upon.
// and/or comments until a semantically valid character is found
char c = nextValid();
@ -131,7 +132,7 @@ Foam::Istream& Foam::ISstream::read(token& t)
// Analyse input starting with this character.
switch (c)
{
// First check for punctuation characters.
// Check for punctuation first
case token::END_STATEMENT :
case token::BEGIN_LIST :
@ -144,7 +145,7 @@ Foam::Istream& Foam::ISstream::read(token& t)
case token::COMMA :
case token::ASSIGN :
case token::ADD :
// case token::SUBTRACT : // Handled later as the possible start of a number
// NB: token::SUBTRACT handled later as the possible start of a Number
case token::MULTIPLY :
case token::DIVIDE :
{
@ -153,26 +154,27 @@ Foam::Istream& Foam::ISstream::read(token& t)
}
// Strings: enclosed by double quotes.
// String: enclosed by double quotes.
case token::BEGIN_STRING :
{
putback(c);
string* sPtr = new string;
if (!read(*sPtr).bad())
{
t = sPtr;
}
else
if (read(*sPtr).bad())
{
delete sPtr;
t.setBad();
}
else
{
t = sPtr;
}
return *this;
}
// Numbers: do not distinguish at this point between Types.
// Number: integer or floating point
//
// ideally match the equivalent of this regular expression
//
@ -185,10 +187,11 @@ Foam::Istream& Foam::ISstream::read(token& t)
{
bool asLabel = (c != '.');
unsigned int nChar = 0;
charBuffer[nChar++] = c;
int nChar = 0;
buf[nChar++] = c;
// get everything that could reasonable look like a number
// get everything that could resemble a number and let
// strtod() determine the validity
while
(
is_.get(c)
@ -202,24 +205,38 @@ Foam::Istream& Foam::ISstream::read(token& t)
)
)
{
asLabel = asLabel && isdigit(c);
if (asLabel)
{
asLabel = isdigit(c);
}
charBuffer[nChar++] = c;
if (nChar >= sizeof(charBuffer))
buf[nChar++] = c;
if (nChar == maxLen)
{
// runaway argument - avoid buffer overflow
buf[maxLen-1] = '\0';
FatalIOErrorIn("ISstream::read(token&)", *this)
<< "number '" << buf << "...'\n"
<< " is too long (max. " << maxLen << " characters)"
<< exit(FatalIOError);
t.setBad();
return *this;
}
}
charBuffer[nChar] = '\0';
buf[nChar] = '\0';
setState(is_.rdstate());
if (!is_.bad())
if (is_.bad())
{
t.setBad();
}
else
{
is_.putback(c);
if (nChar == 1 && charBuffer[0] == '-')
if (nChar == 1 && buf[0] == '-')
{
// a single '-' is punctuation
t = token::punctuationToken(token::SUBTRACT);
@ -230,31 +247,43 @@ Foam::Istream& Foam::ISstream::read(token& t)
if (asLabel)
{
long longval = strtol(charBuffer, &endptr, 10);
t = label(longval);
long longVal(strtol(buf, &endptr, 10));
t = label(longVal);
// return as a scalar if doesn't fit in a label
if (t.labelToken() != longval)
if (t.labelToken() != longVal)
{
t = scalar(strtod(charBuffer, &endptr));
t = scalar(strtod(buf, &endptr));
}
}
else
{
t = scalar(strtod(charBuffer, &endptr));
scalar scalarVal(strtod(buf, &endptr));
t = scalarVal;
// ---------------------------------------
// this would also be possible if desired:
// ---------------------------------------
// // return as a label when possible
// // eg, 1E6 -> 1000000
// if (scalarVal <= labelMax && scalarVal >= labelMin)
// {
// label labelVal(scalarVal);
//
// if (labelVal == scalarVal)
// {
// t = labelVal;
// }
// }
}
// nothing converted (bad format), or trailing junk
if (endptr == charBuffer || *endptr != '\0')
if (endptr == buf || *endptr != '\0')
{
t.setBad();
}
}
}
else
{
t.setBad();
}
return *this;
}
@ -266,23 +295,21 @@ Foam::Istream& Foam::ISstream::read(token& t)
putback(c);
word* wPtr = new word;
if (!read(*wPtr).bad())
{
if (token::compound::isCompound(*wPtr))
{
t = token::compound::New(*wPtr, *this).ptr();
delete wPtr;
}
else
{
t = wPtr;
}
}
else
if (read(*wPtr).bad())
{
delete wPtr;
t.setBad();
}
else if (token::compound::isCompound(*wPtr))
{
t = token::compound::New(*wPtr, *this).ptr();
delete wPtr;
}
else
{
t = wPtr;
}
return *this;
}
}
@ -302,69 +329,64 @@ Foam::Istream& Foam::ISstream::read(word& str)
static const int errLen = 80; // truncate error message for readability
static char buf[maxLen];
register int i = 0;
register int bc = 0;
register int nChar = 0;
register int listDepth = 0;
char c;
while (get(c) && word::valid(c))
{
if (fail())
{
if (i < maxLen-1)
{
buf[i] = '\0';
}
else
{
buf[maxLen-1] = '\0';
}
buf[errLen] = '\0';
FatalIOErrorIn("ISstream::read(word&)", *this)
<< "problem while reading word '" << buf << "'\n"
<< exit(FatalIOError);
return *this;
}
if (i >= maxLen)
{
buf[maxLen-1] = '\0';
buf[errLen] = '\0';
FatalIOErrorIn("ISstream::read(word&)", *this)
<< "word '" << buf << "' ...\n"
<< " is too long (max. " << maxLen << " characters)"
<< exit(FatalIOError);
return *this;
}
if (c == token::BEGIN_LIST)
{
bc++;
listDepth++;
}
else if (c == token::END_LIST)
{
bc--;
if (bc == -1)
if (listDepth)
{
listDepth--;
}
else
{
break;
}
}
buf[i++] = c;
buf[nChar++] = c;
if (nChar == maxLen)
{
buf[errLen] = '\0';
FatalIOErrorIn("ISstream::read(word&)", *this)
<< "word '" << buf << "...'\n"
<< " is too long (max. " << maxLen << " characters)"
<< exit(FatalIOError);
return *this;
}
}
if (i == 0)
// we could probably skip this check
if (bad())
{
buf[errLen] = buf[nChar] = '\0';
FatalIOErrorIn("ISstream::read(word&)", *this)
<< "problem while reading word '" << buf << "...' after "
<< nChar << " characters\n"
<< exit(FatalIOError);
return *this;
}
if (nChar == 0)
{
FatalIOErrorIn("ISstream::read(word&)", *this)
<< "invalid first character found : " << c
<< exit(FatalIOError);
}
buf[i] = '\0'; // Terminator
// done reading
buf[nChar] = '\0';
str = buf;
putback(c);
@ -382,8 +404,6 @@ Foam::Istream& Foam::ISstream::read(string& str)
if (!get(c))
{
buf[0] = '\0';
FatalIOErrorIn("ISstream::read(string&)", *this)
<< "cannot read start of string"
<< exit(FatalIOError);
@ -391,36 +411,32 @@ Foam::Istream& Foam::ISstream::read(string& str)
return *this;
}
char endTok = token::END_STRING;
// Note, we could also handle single-quoted strings here (if desired)
if (c != token::BEGIN_STRING)
{
buf[0] = '\0';
FatalIOErrorIn("ISstream::read(string&)", *this)
<< "Incorrect start of string character"
<< "Incorrect start of string character found : " << c
<< exit(FatalIOError);
return *this;
}
register int i = 0;
register int nChar = 0;
bool escaped = false;
while (get(c))
{
if (c == endTok)
if (c == token::END_STRING)
{
if (escaped)
{
escaped = false;
i--; // overwrite backslash
nChar--; // overwrite backslash
}
else
{
// done reading string
buf[i] = '\0';
// done reading
buf[nChar] = '\0';
str = buf;
return *this;
}
@ -430,12 +446,11 @@ Foam::Istream& Foam::ISstream::read(string& str)
if (escaped)
{
escaped = false;
i--; // overwrite backslash
nChar--; // overwrite backslash
}
else
{
buf[i] = '\0';
buf[errLen] = '\0';
buf[errLen] = buf[nChar] = '\0';
FatalIOErrorIn("ISstream::read(string&)", *this)
<< "found '\\n' while reading string \""
@ -454,10 +469,9 @@ Foam::Istream& Foam::ISstream::read(string& str)
escaped = false;
}
buf[i] = c;
if (i++ == maxLen)
buf[nChar++] = c;
if (nChar == maxLen)
{
buf[maxLen-1] = '\0';
buf[errLen] = '\0';
FatalIOErrorIn("ISstream::read(string&)", *this)
@ -471,8 +485,7 @@ Foam::Istream& Foam::ISstream::read(string& str)
// don't worry about a dangling backslash if string terminated prematurely
buf[i] = '\0';
buf[errLen] = '\0';
buf[errLen] = buf[nChar] = '\0';
FatalIOErrorIn("ISstream::read(string&)", *this)
<< "problem while reading string \"" << buf << "...\""

View File

@ -60,8 +60,8 @@ Foam::argList::initValidTables dummyInitValidTables;
// transform sequences with "(" ... ")" into string lists in the process
bool Foam::argList::regroupArgv(int& argc, char**& argv)
{
int level = 0;
int nArgs = 0;
int listDepth = 0;
string tmpString;
// note: we also re-write directly into args_
@ -70,16 +70,16 @@ bool Foam::argList::regroupArgv(int& argc, char**& argv)
{
if (strcmp(argv[argI], "(") == 0)
{
level++;
listDepth++;
tmpString += "(";
}
else if (strcmp(argv[argI], ")") == 0)
{
if (level >= 1)
if (listDepth)
{
level--;
listDepth--;
tmpString += ")";
if (level == 0)
if (listDepth == 0)
{
args_[nArgs++] = tmpString;
tmpString.clear();
@ -90,7 +90,7 @@ bool Foam::argList::regroupArgv(int& argc, char**& argv)
args_[nArgs++] = argv[argI];
}
}
else if (level)
else if (listDepth)
{
// quote each string element
tmpString += "\"";