Skip to content

Commit d663062

Browse files
author
Nicholas Reed
committed
Apply changes based on SCL git 6e9b5a7. Creates GetLiteralStr function to implement and extend functionality common to SDAI_String::STEPread and PushPastString.
1 parent 0ffd0d7 commit d663062

File tree

5 files changed

+83
-124
lines changed

5 files changed

+83
-124
lines changed

src/cldai/sdaiString.cc

Lines changed: 17 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -18,39 +18,11 @@ SDAI_String & SDAI_String::operator= ( const char * s ) {
1818
}
1919

2020
void SDAI_String::STEPwrite( ostream & out ) const {
21-
const char * str = 0;
22-
if( empty() ) {
23-
out << "\'\'";
24-
} else {
25-
out << "\'";
26-
str = c_str();
27-
while( *str ) {
28-
if( *str == STRING_DELIM ) {
29-
out << STRING_DELIM;
30-
}
31-
out << *str;
32-
str++;
33-
}
34-
out << "\'";
35-
}
21+
out << c_str();
3622
}
3723

3824
void SDAI_String::STEPwrite( std::string & s ) const {
39-
const char * str = 0;
40-
if( empty() ) {
41-
s = "\'\'";
42-
} else {
43-
s = "\'";
44-
str = c_str();
45-
while( *str ) {
46-
if( *str == STRING_DELIM ) {
47-
s += STRING_DELIM;
48-
}
49-
s += *str;
50-
str++;
51-
}
52-
s += STRING_DELIM;
53-
}
25+
s += c_str();
5426
}
5527

5628
Severity SDAI_String::StrToVal( const char * s ) {
@@ -67,54 +39,28 @@ Severity SDAI_String::StrToVal( const char * s ) {
6739
* starting with a single quote
6840
*/
6941
Severity SDAI_String::STEPread( istream & in, ErrorDescriptor * err ) {
70-
int foundEndQuote = 0; // need so this string is not ok: 'hi''
7142
clear(); // clear the old string
72-
char c;
73-
in >> ws; // skip white space
74-
in >> c;
75-
7643
// remember the current format state to restore the previous settings
7744
ios_base::fmtflags flags = in.flags();
7845
in.unsetf( ios::skipws );
7946

80-
if( c == STRING_DELIM ) {
81-
while( ( c != '\0' ) && in.good() && in.get( c ) ) {
82-
if( c == STRING_DELIM ) {
83-
in.get( c );
84-
if( ! in.good() ) {
85-
// it is the final quote and no extra char was read
86-
foundEndQuote = 1;
87-
c = '\0';
88-
continue;
89-
} else if( !( c == STRING_DELIM ) ) {
90-
// it is the final quote and extra char was read
91-
in.putback( c ); // put back non-quote extra char
92-
foundEndQuote = 1;
93-
c = '\0';
94-
continue;
95-
}
96-
// else { ; } // do nothing it is an embedded quote
97-
}
98-
operator+= ( c );
99-
}
100-
101-
if( foundEndQuote ) {
102-
return SEVERITY_NULL;
103-
} else {
104-
// non-recoverable error
105-
err->AppendToDetailMsg( "Missing closing quote on string value.\n" );
106-
err->AppendToUserMsg( "Missing closing quote on string value.\n" );
107-
err->GreaterSeverity( SEVERITY_INPUT_ERROR );
108-
return SEVERITY_INPUT_ERROR;
109-
}
110-
}
111-
// otherwise there was not a quote
112-
in.putback( c );
113-
in.flags( flags ); // set the format state back to previous settings
47+
// extract the string from the inputstream
48+
std::string s = GetLiteralStr( in, err );
49+
append( s );
11450

115-
clear();
51+
// retrieve current severity
52+
Severity sev = err -> severity();
11653

117-
return err -> GreaterSeverity( SEVERITY_INCOMPLETE );
54+
if ( s.empty() ) {
55+
// no string was read
56+
in.flags( flags ); // set the format state back to previous settings
57+
err -> GreaterSeverity( SEVERITY_INCOMPLETE );
58+
sev = SEVERITY_INCOMPLETE;
59+
} else if ( sev != SEVERITY_INPUT_ERROR ) {
60+
// read valid string
61+
sev = SEVERITY_NULL;
62+
}
63+
return sev;
11864
}
11965

12066
Severity SDAI_String::STEPread( const char * s, ErrorDescriptor * err ) {

src/clstepcore/read_func.cc

Lines changed: 2 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "sdai.h"
55
#include "read_func.h"
66
#include "STEPattribute.h"
7+
#include "Str.h"
78

89
const int RealNumPrecision = REAL_NUM_PRECISION;
910

@@ -458,41 +459,7 @@ Severity NumberValidLevel( const char * attrValue, ErrorDescriptor * err,
458459

459460
/// assign 's' so that it contains an exchange file format string read from 'in'.
460461
void PushPastString( istream & in, std::string & s, ErrorDescriptor * err ) {
461-
in >> ws; // skip whitespace
462-
463-
if ( in.peek() == STRING_DELIM ) {
464-
int lastAppended = in.get();
465-
s += lastAppended;
466-
467-
int numDelims = 0;
468-
while ( in.good() ) {
469-
if ( in.peek() == STRING_DELIM ) {
470-
numDelims++;
471-
} else if ( numDelims % 2 != 0 ) {
472-
// Found non-delim char following odd number of inner delims.
473-
// Most recently appended delim was unescaped and terminates string,
474-
// so we break rather than append the next non-delim char.
475-
break;
476-
}
477-
lastAppended = in.get();
478-
s += lastAppended;
479-
}
480-
481-
if ( lastAppended != STRING_DELIM ||
482-
( lastAppended == STRING_DELIM && numDelims % 2 == 0 ) )
483-
{
484-
// Last appended was non-delimiter, or was the opening delimiter
485-
// or an escaped delimiter. Add closing delim and log error.
486-
char messageBuf[BUFSIZ];
487-
messageBuf[0] = '\0';
488-
489-
err->GreaterSeverity( SEVERITY_INPUT_ERROR );
490-
sprintf( messageBuf, "Unterminated string value.\n" );
491-
err->AppendToDetailMsg( messageBuf );
492-
493-
s += STRING_DELIM;
494-
}
495-
}
462+
s += GetLiteralStr( in, err );
496463
}
497464

498465
/**

src/clstepcore/sdaiApplication_instance.cc

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -574,23 +574,6 @@ Severity SDAI_Application_instance::STEPread( int id, int idIncr,
574574
_error.AppendToUserMsg(
575575
"Since using pre-technical corrigendum... missing asterisk for redefined attr. " );
576576
}
577-
/*
578-
if( ! ( (c == ',') || (c == ')') ) )
579-
{ // input is not a delimiter - an error
580-
PrependEntityErrMsg();
581-
582-
_error.AppendToDetailMsg(
583-
"Delimiter expected after redefined asterisk attribute encoding (since using pre-technical corregendum.\n");
584-
CheckRemainingInput(in, &_error, "ENTITY", ",)");
585-
if(!in.good())
586-
return _error.severity();
587-
if(_error.severity() <= SEVERITY_INPUT_ERROR)
588-
{
589-
// STEPread_error(c,i,in);
590-
return _error.severity();
591-
}
592-
}
593-
*/
594577
} else { // using technical corrigendum
595578
// should be nothing to do except loop again unless...
596579
// if at end need to have read the closing paren.

src/clutils/Str.cc

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
99
* and is not subject to copyright.
1010
*/
1111

12-
#include <Str.h>
12+
#include "Str.h"
1313
#include <sstream>
14+
#include <string>
1415

1516
/******************************************************************
1617
** Procedure: string functions
@@ -111,6 +112,65 @@ int StrCmpIns( const char * str1, const char * str2 ) {
111112
return c1 - c2;
112113
}
113114

115+
/**
116+
* Test if a string ends with the given suffix.
117+
*/
118+
bool StrEndsWith( const std::string &s, const char * suf ) {
119+
if ( suf == NULL ) {
120+
return false;
121+
}
122+
std::string suffix = suf;
123+
size_t sLen = s.length();
124+
size_t suffixLen = suffix.length();
125+
if ( sLen < suffixLen ) {
126+
return false;
127+
}
128+
if ( s.substr( sLen - suffixLen ).compare( suffix ) == 0 ) {
129+
return true;
130+
}
131+
return false;
132+
}
133+
134+
/**
135+
* Extract the next delimited string from the istream.
136+
*/
137+
std::string GetLiteralStr( istream & in, ErrorDescriptor * err ) {
138+
std::string s;
139+
in >> std::ws; // skip whitespace
140+
141+
if ( in.good() && in.peek() == STRING_DELIM ) {
142+
s += in.get();
143+
bool allDelimsEscaped = true;
144+
while ( in.good() ) {
145+
if ( in.peek() == STRING_DELIM ) {
146+
// A delimiter closes the string unless it's followed by another
147+
// delimiter, in which case it's escaped. \S\ starts an ISO
148+
// 8859 character escape sequence, so we ignore delimiters
149+
// prefixed with \S\.
150+
if ( !StrEndsWith( s, "\\S\\" ) ) {
151+
allDelimsEscaped = !allDelimsEscaped;
152+
}
153+
} else if ( !allDelimsEscaped ) {
154+
// Found normal char after unescaped delim, so last delim
155+
// that was appended terminated the string.
156+
break;
157+
}
158+
if ( !in.eof() ) {
159+
s += in.get();
160+
}
161+
}
162+
if ( allDelimsEscaped ) {
163+
// Any delimiters found after the opening delimiter were escaped,
164+
// so the string is unclosed.
165+
// non-recoverable error
166+
err->AppendToDetailMsg( "Missing closing quote on string value.\n" );
167+
err->AppendToUserMsg( "Missing closing quote on string value.\n" );
168+
err->GreaterSeverity( SEVERITY_INPUT_ERROR );
169+
}
170+
}
171+
return s;
172+
}
173+
114174
/**************************************************************//**
115175
** \fn PrettyTmpName (char * oldname)
116176
** \returns a new capitalized name in a static buffer

src/clutils/Str.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ char * StrToLower( const char *, char * );
3434
const char * StrToLower( const char * word, std::string & s );
3535
const char * StrToUpper( const char * word, std::string & s );
3636
const char * StrToConstant( const char * word, std::string & s );
37+
int StrCmpIns( const char * str1, const char * str2 );
38+
bool StrEndsWith( const std::string &s, const char * suffix );
39+
std::string GetLiteralStr( istream & in, ErrorDescriptor * err );
3740
const char * PrettyTmpName( const char * oldname );
3841
char * PrettyNewName( const char * oldname );
3942
int StrCmpIns( const char *, const char * );

0 commit comments

Comments
 (0)