Files
geant4/source/geometry/solids/STEP/src/Str.cc
T
2016-06-09 10:28:22 +02:00

314 lines
9.3 KiB
C++

/*
* NIST Utils Class Library
* clutils/Str.cc
* April 1997
* K. C. Morris
* David Sauder
* Development of this software was funded by the United States Government,
* and is not subject to copyright.
*/
/* $Id: Str.cc,v 1.5 2003/06/06 17:07:35 gcosmo Exp $ */
#include <Str.h>
/******************************************************************
** Procedure: string functions
** Description: These functions take a character or a string and return
** a temporary copy of the string with the function applied to it.
** Parameters:
** Returns: temporary copy of characters
** Side Effects:
** Status: complete
******************************************************************/
char
ToLower (const char c)
{
if (isupper (c)) return (tolower (c));
else return (c);
}
char
ToUpper (const char c)
{
if (islower (c)) return (toupper (c));
else return (c);
}
char *
StrToLower (const char *strOld, char *strNew)
/*
* Place in strNew a lowercase version of strOld.
*/
{
int i = 0;
while ( strOld[i] != '\0' ) {
strNew[i] = ToLower( strOld[i] );
i++;
}
strNew[i] = '\0';
return strNew;
}
const char *
StrToLower (const char * word, SCLstring &s)
{
char newword [BUFSIZ];
int i =0;
// char ToLower (char c);
while (word [i] != '\0') {
newword [i] = ToLower (word [i]);
++i;
}
newword [i] = '\0';
s = newword;
return s.chars();
}
const char *
StrToUpper (const char * word, SCLstring &s)
{
char newword [BUFSIZ];
int i =0;
// char ToUpper (char c);
while (word [i] != '\0') {
newword [i] = ToUpper (word [i]);
++i;
}
newword [i] = '\0';
s = newword;
return s.chars();
}
const char *
StrToConstant (const char * word, SCLstring &s)
{
char newword [BUFSIZ];
int i =0;
// char ToUpper (char c);
while (word [i] != '\0') {
if (word [i] == '/' || word [i] == '.') newword [i] = '_';
else newword [i] = ToUpper (word [i]);
++i;
}
newword [i] = '\0';
s = newword;
return s.chars();
}
/******************************************************************
** Procedure: PrettyName (char * oldname)
** Parameters: oldname
** Returns: a new capitalized name
** Description: creates a new name with first character's in caps
** Side Effects: PrettyNewName allocates memory for the new name
PrettyTmpName returns new name in a static buffer
** Status: OK 7-Oct-1992 kcm
******************************************************************/
const char *
PrettyTmpName (const char * oldname)
{
int i= 0;
static char newname [BUFSIZ];
newname [0] = '\0';
while (( oldname [i] != '\0') && (i < BUFSIZ)) {
newname [i] = ToLower (oldname [i]);
if (oldname [i] == '_') /* character is '_' */
{
++i;
newname [i] = ToUpper (oldname [i]);
}
if (oldname [i] != '\0') ++i;
}
newname [0] = ToUpper (oldname [0]);
newname [i] = '\0';
return newname;
}
char *
PrettyNewName (const char * oldname)
{
char * name = new char [strlen (oldname) +1];
strcpy (name, PrettyTmpName (oldname));
return name;
}
int
StrCmpIns( const char *strA, const char *strB )
/*
* An insensitive string compare function. Used most often to compare
* names of objects where case is not known and not significant.
*
* NOTE - cygnus does not define strcmpi/stricmp. I'm sure there's a nifty
* way to add preprocessor commands to check if it exists, and if so to
* use it, but I didn't bother.
*/
{
char str1[BUFSIZ], str2[BUFSIZ];
strncpy( str1, PrettyTmpName( strA ), BUFSIZ-1 );
strncpy( str2, PrettyTmpName( strB ), BUFSIZ-1 );
return ( strcmp( str1, str2 ) );
}
// This function is used to check an input stream following a read. It writes
// error messages in the 'ErrorDescriptor &err' argument as appropriate.
// 'const char *tokenList' argument contains a string made up of delimiters
// that are used to move the file pointer in the input stream to the end of
// the value you are reading (i.e. the ending marked by the presence of the
// delimiter). The file pointer is moved just prior to the delimiter. If the
// tokenList argument is a null pointer then this function expects to find EOF.
//
// If input is being read from a stream then a tokenList should be provided so
// this function can push the file pointer up to but not past the delimiter
// (i.e. not removing the delimiter from the input stream). If you have a
// string containing a single value and you expect the whole string to contain
// a valid value, you can change the string to an std::istrstream, read the value
// then send the std::istrstream to this function with tokenList set to null
// and this function will set an error for you if any input remains following
// the value.
// If the input stream can be readable again then
// - any error states set for the the stream are cleared.
// - white space skipped in the input stream
// - if EOF is encountered it returns
// otherwise it peeks at the next character
// - if the tokenList argument exists (i.e. is not null)
// then if looks to see if the char peeked at is in the tokenList string
// if it is then no error is set in the ErrorDescriptor
// if the char peeked at is not in the tokenList string that implies
// that there is garbage following the value that was successfully
// or unsuccessfully read. The garbage is read until EOF or a
// delimiter in the tokenList is found.
// - EOF is found you did not recover -> SEVERITY_INPUT_ERROR
// - delimiter found you recovered successfully => SEVERITY_WARNING
// - if tokenList does not exist then it expects to find EOF, if it does
// not then it is an error but the bad chars are not read since you have
// no way to know when to stop.
Severity
CheckRemainingInput(std::istream &in, ErrorDescriptor *err,
const char *typeName, // used in error message
const char *tokenList) // e.g. ",)"
{
SCLstring skipBuf;
char name[64];
name[0] = 0;
// 1. CHECK to see if there is invalid input following what you read.
// good or fail means you can still read from the input stream.
if( in.good() || in.fail() )
// fail means that the input did not match the expected input.
{ // check for bad input following what you read (or tried to read) but
// preceding a delimiter if you are expecting one.
in.clear(); // clear the istreams error
in >> std::ws; // skip whitespace
if(in.eof()) // no input following the desired input (or following the
{ // missing desired input)
return err->severity();
}
char c;
c = in.peek();
if( tokenList ) // are expecting a delim so read till you find it
{
// 3. FIND a delimiter
if( strchr(tokenList, c) )
{ // next char peeked at was delim expected => success
return err->severity();
}
else // next character was not a delim and thus is garbage
{ // read bad input until you find the delim
in.get(c);
while(in && !strchr(tokenList, c) )
{ // this could chew up the remainder of the input unless you
// give it the delim to end an entity value and it knows
// about strings
skipBuf.Append(c);
in.get(c);
}
// ENHANCEMENT may want to add the bad data to the err msg.
if(strchr(tokenList, c))
{ // congratulations you recovered
err->GreaterSeverity(SEVERITY_WARNING);
sprintf(name,
"\tFound invalid %s value...\n",
typeName);
err->AppendToUserMsg(name);
err->AppendToDetailMsg(name);
err->AppendToDetailMsg(
"\tdata lost looking for end of attribute: ");
err->AppendToDetailMsg( skipBuf.chars() );
err->AppendToDetailMsg( "\n" );
in.putback(c);
// invalid input
// (though a valid value may have been assigned)
return err->severity();
}
else
{ // could not recover (of course)
err->GreaterSeverity(SEVERITY_INPUT_ERROR);
sprintf(name,
"Unable to recover from input error while reading %s %s",
typeName, "value.\n");
err->AppendToUserMsg(name);
err->AppendToDetailMsg(name);
// invalid input
// (though a valid value may have been assigned)
return err->severity();
}
}
}
else if(in.good()) // found a char => error
// i.e. skipping whitespace did not cause EOF so must have hit a char
{ // remember we are not expecting more input since no tokenList
// or 3. since not expecting a delimiter and there is input there
// is an error
err->GreaterSeverity(SEVERITY_WARNING);
sprintf(name, "Invalid %s value.\n", typeName);
err->AppendToUserMsg(name);
err->AppendToDetailMsg(name);
// invalid input
// (though a valid value may have been assigned)
return err->severity();
}
}
else if (in.eof())
{
// hit EOF when reading for a value
// don\'t set any error
return err->severity();
}
else
{ // badbit set (in.bad()) means there was a problem when reading std::istream
// this is bad news... it means the input stream is hopelessly messed up
err->GreaterSeverity(SEVERITY_INPUT_ERROR);
sprintf(name, "Invalid %s value.\n", typeName);
err->AppendToUserMsg(name);
err->AppendToDetailMsg(name);
// invalid input
// (though a valid value may have been assigned)
return err->severity();
}
return err->severity();
}