Skip to content

Commit 5afbfae

Browse files
author
Peter Clifton
committed
Fix inconsistent sort order compared to ISO-10303-21 standard
This manifested in incorrect complex entity ordering in some cases. For example, a complex containing a BOUNDED_SURFACE and B_SPLINE_SURFACE entity would emit them in the incorrect order. (This was picked up upon loading SCL created files in the IDA-step viewer). Fixes: stepcode#330
1 parent f444958 commit 5afbfae

18 files changed

Lines changed: 244 additions & 22 deletions

src/clstepcore/complexSupport.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,10 @@ class SC_CORE_EXPORT EntNode {
9696
return ( strcmp( name, ent.name ) == 0 );
9797
}
9898
bool operator< ( EntNode & ent ) {
99-
return ( strcmp( name, ent.name ) < 0 );
99+
return ( entity_name_cmp( name, ent.name ) < 0 );
100100
}
101101
bool operator> ( EntNode & ent ) {
102-
return ( strcmp( name, ent.name ) > 0 );
102+
return ( entity_name_cmp( name, ent.name ) > 0 );
103103
}
104104
EntNode & operator= ( EntNode & ent );
105105
void Name( const char * nm ) {
@@ -363,10 +363,10 @@ class SC_CORE_EXPORT ComplexList {
363363
void buildList();
364364
void remove();
365365
int operator< ( ComplexList & c ) {
366-
return ( strcmp( supertype(), c.supertype() ) < 0 );
366+
return ( entity_name_cmp( supertype(), c.supertype() ) < 0 );
367367
}
368368
int operator< ( char * name ) {
369-
return ( strcmp( supertype(), name ) < 0 );
369+
return ( entity_name_cmp( supertype(), name ) < 0 );
370370
}
371371
int operator== ( char * name ) {
372372
return ( strcmp( supertype(), name ) == 0 );

src/clstepcore/complexlist.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ void ComplexList::addChildren( EntList * ent ) {
106106
}
107107
} else {
108108
nm = ( dynamic_cast<SimpleList *>(ent) )->name;
109-
while( prev != NULL && ( comp = strcmp( prev->name, nm ) ) < 0 ) {
109+
while( prev != NULL && ( comp = entity_name_cmp( prev->name, nm ) ) < 0 ) {
110110
prev2 = prev;
111111
prev = prev->next;
112112
}

src/clstepcore/entlist.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ void SimpleList::unmarkAll( EntNode * ents ) {
9393
return;
9494
}
9595

96-
while( eptr != NULL && ( comp = strcmp( eptr->name, name ) ) < 0 ) {
96+
while( eptr != NULL && ( comp = entity_name_cmp( eptr->name, name ) ) < 0 ) {
9797
eptr = eptr->next;
9898
}
9999
// (We assume we have a match now since viable >= MATCHSOME.)
@@ -117,7 +117,7 @@ bool SimpleList::acceptChoice( EntNode * ents ) {
117117
int comp;
118118

119119
while( eptr != NULL ) {
120-
if( ( comp = strcmp( name, eptr->name ) ) == 0 ) {
120+
if( ( comp = entity_name_cmp( name, eptr->name ) ) == 0 ) {
121121
if( ! eptr->marked() ) {
122122
eptr->setmark( ORMARK );
123123
I_marked = ORMARK;

src/clstepcore/entnode.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ EntNode::EntNode( const char ** names ) {
3232

3333
while( names[j] && *names[j] != '*' ) {
3434
nm = names[j];
35-
while( prev != NULL && ( comp = StrCmpIns( prev->name, nm ) ) < 0 ) {
35+
while( prev != NULL && ( comp = entity_name_cmp( prev->name, nm ) ) < 0 ) {
3636
prev2 = prev;
3737
prev = prev->next;
3838
}

src/clstepcore/non-ors.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ MatchType SimpleList::matchNonORs( EntNode * ents ) {
2424
int comp;
2525

2626
while( eptr != NULL ) {
27-
if( ( comp = strcmp( name, eptr->name ) ) == 0 ) {
27+
if( ( comp = entity_name_cmp( name, eptr->name ) ) == 0 ) {
2828
if( ! eptr->marked( MARK ) ) {
2929
// NOTE - this cond also returns true if eptr did have an OR-
3030
// MARK. We don't want to remark now (since we're also trying

src/clstepcore/schRename.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class SC_CORE_EXPORT SchRename {
3232
return newName;
3333
}
3434
int operator< ( SchRename & schrnm ) {
35-
return ( strcmp( schName, schrnm.schName ) < 0 );
35+
return ( entity_name_cmp( schName, schrnm.schName ) < 0 ); /* ??? SHOULD THIS BE entity_name_cmp ??? */
3636
}
3737
bool choice( const char * nm ) const;
3838
// is nm one of our possible choices?

src/clutils/Str.cc

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,98 @@ int StrCmpIns( const char * str1, const char * str2 ) {
112112
return c1 - c2;
113113
}
114114

115+
static int contiguous_block_number( unsigned char c )
116+
{
117+
if (c == 0) /* \0 */
118+
return 0;
119+
if (c == 32) /* SPACE */
120+
return 1;
121+
if (48 <= c && c <= 57) /* 0-9 */
122+
return 2;
123+
if (97 <= c && c <= 122) /* a-z */
124+
return 3;
125+
if (65 <= c && c <= 90) /* A-Z */
126+
return 4;
127+
if (c == 95) /* _ */
128+
return 5;
129+
if (33 <= c && c <= 34) /* !" */
130+
return 6;
131+
if (c == 42) /* * */
132+
return 7;
133+
if (36 <= c && c <= 38) /* $%& */
134+
return 8;
135+
if (c == 46) /* . */
136+
return 9;
137+
if (c == 35) /* # */
138+
return 10;
139+
if (43 <= c && c <= 45) /* +,- */
140+
return 11;
141+
if (40 <= c && c <= 41) /* () */
142+
return 12;
143+
if (c == 63) /* ? */
144+
return 13;
145+
if (c == 47) /* / */
146+
return 14;
147+
if (58 <= c && c <= 62) /* :<=> */
148+
return 15;
149+
if (c == 64) /* @ */
150+
return 16;
151+
if (c == 91) /* [ */
152+
return 17;
153+
if (c == 93) /* ] */
154+
return 18;
155+
if (123 <= c && c <= 125) /* {|} */
156+
return 19;
157+
if (c == 94) /* ^ */
158+
return 20;
159+
if (c == 96) /* ` */
160+
return 21;
161+
if (c == 126) /* ~ */
162+
return 22;
163+
if (c == 92) /* \ */
164+
return 23;
165+
if (c == 39) /* ' */
166+
return 24;
167+
168+
return 25;
169+
}
170+
171+
static int entity_char_cmp( unsigned char c1, unsigned char c2 )
172+
{
173+
int block1 = contiguous_block_number( c1 );
174+
int block2 = contiguous_block_number( c2 );
175+
176+
if (block1 != block2)
177+
return block1 - block2;
178+
179+
return c1 - c2;
180+
}
181+
182+
/**************************************************************//**
183+
** \fn entity_name_cmp (const char * str1, const char * str2)
184+
** \returns Comparison result
185+
** Compares two strings according to P21 entity naming rules
186+
** Returns < 0 when str1 less then str2
187+
** == 0 when str1 equals str2
188+
** > 0 when str1 greater then str2
189+
******************************************************************/
190+
int entity_name_cmp( const char *str1, const char *str2 )
191+
{
192+
const unsigned char *s1 = ( const unsigned char * ) str1;
193+
const unsigned char *s2 = ( const unsigned char * ) str2;
194+
unsigned char c1, c2;
195+
196+
do {
197+
c1 = ( unsigned char ) *s1++;
198+
c2 = ( unsigned char ) *s2++;
199+
if( c1 == '\0' )
200+
return c1 - c2; /* 0 if both c1 and c2 are \0, otherwise returns -ve for c1 terminating first */
201+
} while( c1 == c2 );
202+
203+
return entity_char_cmp( c1, c2 );
204+
}
205+
206+
115207
/**
116208
* Test if a string ends with the given suffix.
117209
*/

src/clutils/Str.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ SC_UTILS_EXPORT const char * StrToLower( const char * word, std::string & s );
3232
SC_UTILS_EXPORT const char * StrToUpper( const char * word, std::string & s );
3333
SC_UTILS_EXPORT const char * StrToConstant( const char * word, std::string & s );
3434
SC_UTILS_EXPORT int StrCmpIns( const char * str1, const char * str2 );
35+
SC_UTILS_EXPORT int entity_name_cmp ( const char * str1, const char * str2 );
3536
SC_UTILS_EXPORT const char * PrettyTmpName( const char * oldname );
3637
SC_UTILS_EXPORT char * PrettyNewName( const char * oldname );
3738
SC_UTILS_EXPORT char * EntityClassName( char * oldname );

src/exp2cxx/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ set(exp2cxx_SOURCES
2727
trynext.cc
2828
write.cc
2929
print.cc
30+
Str.cc
3031
genCxxFilenames.c
3132
)
3233

src/exp2cxx/Str.cc

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*
2+
* NIST Utils Class Library
3+
* clutils/Str.cc
4+
* April 1997
5+
* K. C. Morris
6+
* David Sauder
7+
8+
* Development of this software was funded by the United States Government,
9+
* and is not subject to copyright.
10+
*/
11+
12+
#include "Str.h"
13+
#include <sstream>
14+
#include <string>
15+
16+
static int contiguous_block_number( unsigned char c )
17+
{
18+
if (c == 0) /* \0 */
19+
return 0;
20+
if (c == 32) /* SPACE */
21+
return 1;
22+
if (48 <= c && c <= 57) /* 0-9 */
23+
return 2;
24+
if (97 <= c && c <= 122) /* a-z */
25+
return 3;
26+
if (65 <= c && c <= 90) /* A-Z */
27+
return 4;
28+
if (c == 95) /* _ */
29+
return 5;
30+
if (33 <= c && c <= 34) /* !" */
31+
return 6;
32+
if (c == 42) /* * */
33+
return 7;
34+
if (36 <= c && c <= 38) /* $%& */
35+
return 8;
36+
if (c == 46) /* . */
37+
return 9;
38+
if (c == 35) /* # */
39+
return 10;
40+
if (43 <= c && c <= 45) /* +,- */
41+
return 11;
42+
if (40 <= c && c <= 41) /* () */
43+
return 12;
44+
if (c == 63) /* ? */
45+
return 13;
46+
if (c == 47) /* / */
47+
return 14;
48+
if (58 <= c && c <= 62) /* :<=> */
49+
return 15;
50+
if (c == 64) /* @ */
51+
return 16;
52+
if (c == 91) /* [ */
53+
return 17;
54+
if (c == 93) /* ] */
55+
return 18;
56+
if (123 <= c && c <= 125) /* {|} */
57+
return 19;
58+
if (c == 94) /* ^ */
59+
return 20;
60+
if (c == 96) /* ` */
61+
return 21;
62+
if (c == 126) /* ~ */
63+
return 22;
64+
if (c == 92) /* \ */
65+
return 23;
66+
if (c == 39) /* ' */
67+
return 24;
68+
69+
return 25;
70+
}
71+
72+
static int entity_char_cmp( unsigned char c1, unsigned char c2 )
73+
{
74+
int block1 = contiguous_block_number( c1 );
75+
int block2 = contiguous_block_number( c2 );
76+
77+
if (block1 != block2)
78+
return block1 - block2;
79+
80+
return c1 - c2;
81+
}
82+
83+
/**************************************************************//**
84+
** \fn entity_name_cmp (const char * str1, const char * str2)
85+
** \returns Comparison result
86+
** Compares two strings according to P21 entity naming rules
87+
** Returns < 0 when str1 less then str2
88+
** == 0 when str1 equals str2
89+
** > 0 when str1 greater then str2
90+
******************************************************************/
91+
int entity_name_cmp( const char *str1, const char *str2 )
92+
{
93+
const unsigned char *s1 = ( const unsigned char * ) str1;
94+
const unsigned char *s2 = ( const unsigned char * ) str2;
95+
unsigned char c1, c2;
96+
97+
do {
98+
c1 = ( unsigned char ) *s1++;
99+
c2 = ( unsigned char ) *s2++;
100+
if( c1 == '\0' )
101+
return c1 - c2; /* 0 if both c1 and c2 are \0, otherwise returns -ve for c1 terminating first */
102+
} while( c1 == c2 );
103+
104+
return entity_char_cmp( c1, c2 );
105+
}

0 commit comments

Comments
 (0)