meta,
C++
70 Methoden:
/* private: */ void str_set :: trans_rsh_at
|
/* public: */ BOOL str_set :: forget
/* public: */ BOOL str_set :: rm
/* public: */ char * str_set :: alloc
/* public: */ char * str_set :: take
/* public: */ int str_set :: cardinality
/* public: */ int str_set :: st_clone
/* public: */ int str_set :: st_clone
/* public: */ match_rec * str_set :: to_char
/* public: */ match_rec * str_set :: to_first
/* public: */ match_rec * str_set :: to_next
/* public: */ match_rec * str_set :: element
/* public: */ match_rec * str_set :: ensure
/* public: */ match_rec * str_set :: ensure
/* public: */ match_rec * str_set :: get_pc
/* public: */ match_rec * str_set :: ins_pc
/* public: */ match_rec * str_set :: insert
/* public: */ match_rec * str_set :: insert
/* public: */ match_rec * str_set :: insert
/* public: */ match_rec * str_set :: match
/* public: */ str_set :: ~str_set
/* public: */ uint str_set :: rm_see
/* public: */ void str_set :: check
/* public: */ void str_set :: msHtm_escape
/* public: */ void str_set :: closure
/* public: */ void str_set :: rsh
/* public: */ void str_set :: rsh_at
/* public: */ void str_set :: sort
/* public: */ void * str_set :: newSto
/* public: */ void str_set :: checkSto
/* public: */ void str_set :: forgetALL
/* public: */ void str_set :: init
/* public: */ void str_set :: rsh
/* public: */ void str_set :: rsh
/* public: */ void str_set :: rsh
#define static
#include str_set.h : cpp
#include str_set.c1 : cpp
#undef BB
#undef BBStr
#undef bb
#undef bbStr
#define BB
#define BBStr( x,y,z ) ;
#define bb
#define bbStr( x,y,z ) ;
#ifndef procNestOn
#undef LB_
#undef LE_
#undef LE_ret
#undef ret
#undef ret_
#undef __
#undef ___
#define LB_( x ) {
#define LE_ }
#define ret_ return ;
#define LE_ret( x ) return( x ); }
#define ret( x ) return( x );
#define __
#define ___
#endif
/* public: */ void str_set :: init
// -----------------------------------------------------------------------------
(
char * prefix
)
LB_("str_set.init")
pre = prefix ; if ( ! pre ) fErr
maxlen = 0 ; ich = this ; L_pre = strlen( pre );
aset = 0 ;
nextstr = 0 ;
updates = 0 ;
errors = 0 ;
cksto = 0 ;
for ( int r = 0 ; r < 256 ; ) strings[ r++ ] = 0 ;
new_sto( sto, store );
ste = ( sta = sto->sto ) + L_stopage ; sto->pre = 0 ;
LE_
/* public: */ void str_set :: forgetALL(
// -----------------------------------------------------------------------------
)
LB_("str_set.forgetALL")
for ( int r = 0 ; r < 256 ; ) strings[ r++ ] = 0 ;
nextstr = 0 ;
LE_
/* public: */ str_set :: ~str_set
// -----------------------------------------------------------------------------
(
)
LB_("str_set.~str_set")
if ( this != ich ) fErr2( this, ich ) // object undeclared or destroyed
__
for ( int r = 0 ; r < 256 ; )
{
match_rec * rec = strings[ r++ ] ;
match_rec * rec1 ; ;
__
while ( rec )
{
__ rec1 = rec->next ; rem_sto( rec ) ; rec = rec1 ;
}
}
__
store * pre ;
do {
pre = sto->pre ; rem_sto( sto ); if ( pre ) sto = pre ;
}
while( pre ); // !! nicht sto
if ( aset ) rem_sto( aset );
__
LE_
/* public: */ void * str_set :: newSto
/* -----------------------------------------------------------------------------
Diese Methode gestattet, das str_set als lokalen Heap zu nutzen - mit dem
Vorteil, darauf allokierten Speicher nicht mehr einzeln freigeben zu mssen.
Mittels checkSto() kann man untersuchen, ob der lokale Heap noch intakt ist.
Der Aufrufer sagt:
allocate L bytes, their scope will be the scope of 'this
Die Funktion garantiert: fErr || ok
-----------------------------------------------------------------------------
*/ (
int L // allocate L bytes
)
LB_("str_set.newSto")
if ( this != ich ) fErr // object not yet declared
L += 4 * sizeof( void * );
if ( ste < sta + L )
then {
if ( L_stopage <= L ) fErr
store * pre = sto ; new_sto( sto, store ); sto->pre = pre ;
ste = ( sta = sto->sto ) + L_stopage ;
}
else ;
void * a = sta + 3 * sizeof( void * );
sta += L ;
void * e = sta - sizeof( void * );
void ** A = ( void ** )a ;
A[ -1 ] = a ;
A[ -2 ] = e ;
A[ -3 ] = cksto ; cksto = ( void ** )a ;
*(( void ** )e ) = a ;
checkSto();
LE_ret( a )
/* public: */ void str_set :: checkSto(
/* -----------------------------------------------------------------------------
check all storage allocated so far on the local heap
-----------------------------------------------------------------------------
*/ )
LB_("str_set.checkSto")
void ** a = cksto ; int n = 0 ;
while ( a )
{
n++ ;
if ( a != a[ -1 ] ) fErr
if ( a != *(( void ** )( a[ -2 ] )) ) fErr
a = ( void ** ) a[ -3 ] ;
}
// S_"checkSto: Heap ok, %i items ", n _TR
LE_
/* public: */ match_rec * str_set :: to_char
/* -----------------------------------------------------------------------------
return address of first rec X satisfying X.str[0] == c
-----------------------------------------------------------------------------
*/ (
char c
)
{
return( strings[ c ] );
}
/* public: */ void str_set :: trace
// -----------------------------------------------------------------------------
(
char * name // Objekt
, FILE * f // soll geschrieben werden nach
)
LB_("str_set.trace")
fprintf( f, "\n%s - Instanz der Klasse 'str_set': \n\n", name );
match_rec * rec ;
for ( int r = 0 ; r < 256 ; r++ ) if ( strings[ r ] )
{
rec = strings[ r ] ;
fprintf( f, "at ascii %3i : %p\n", r, rec );
while ( rec )
{
fprintf( f, "x1 = %4i, %s (%s)\n", rec->x1, name, rec->str );
rec = rec->next ;
}
}
fprintf( f, "\n--- end str_set \n" );
LE_
/* public: */ char * str_set :: take
/* -----------------------------------------------------------------------------
clone string str, return pointer to clone
-----------------------------------------------------------------------------
*/ (
char * str
)
LB_("str_set.take")
// if ( ! str || ! *str ) fErr1( str ) // falsch
if ( ! str ) fErr // so gewollt
char * cp ; st_clone( cp, str );
LE_ret( cp )
/* public: */ char * str_set :: alloc
/* -----------------------------------------------------------------------------
allocate storage of length L
-----------------------------------------------------------------------------
*/ (
int L
, char * str
)
LB_("str_set.alloc")
path x ; *x = 0 ;
char * cp ; st_clone( cp, x, L ); strcpy( cp, str );
LE_ret( cp )
/* public: */ int str_set :: st_clone
/* -----------------------------------------------------------------------------
clone string str, return its length
-----------------------------------------------------------------------------
*/ (
char * & dest
, char * str
)
LB_("str_set.st_clone")
if ( this != ich ) fErr2( this, ich ) // object undeclared or destroyed
if ( ! str ) fErr
LE_ret( st_clone( dest, str, strlen( str ) ) )
/* public: */ int str_set :: st_clone
/* -----------------------------------------------------------------------------
clone prefix( str, L ) as if it were a string,
return corrected L
-----------------------------------------------------------------------------
*/ (
char * & dest // out: pointer to clone
, char * str
, int L
)
LB_("str_set.st_clone")
if ( this != ich ) fErr2( this, ich ) // object undeclared or destroyed
if ( L <= 0 ) { dest = "" ; ret( 0 ) }
if ( ste < sta + L )
{
if ( L_stopage <= L )
{
traceStr( "LLL", str, L ); fErr2( L_stopage, L )
}
store * pre = sto ; new_sto( sto, store ); sto->pre = pre ;
ste = ( sta = sto->sto ) + L_stopage ;
}
memcpy( sta, str, L ); sta[ L ] = 0 ;
dest = sta ; sta += ( L + 1 );
LE_ret( L )
/* public: */ void str_set :: msHtm_escape ( uchar u
// -----------------------------------------------------------------------------
)
LB_("str_set.msHtm_escape")
char * ers = "?" ; char10 str ; s_( str, "%u;", u );
*ers = u ; insert( ers, str );
LE_
/* public: */ match_rec * str_set :: ins_pc
/* -----------------------------------------------------------------------------
insert a padded clone of a string representing an int
-----------------------------------------------------------------------------
*/ (
char * & c // pointer to int representation to scan
, char * k // pointer to key representation
)
LB_("str_set.ins_pc")
while space( *c ) c++ ;
int wert ; sscanf( c, "%i", &wert );
path pc ; char * s = pc ; *s++ = ( char )( wert % 255 + 1 );
while ( *k ) *s++ = *k++ ;
while digit( *c ) *s++ = *c++ ; *s = 0 ;
match_rec * mr = insert( pc ); L1_( pc+1 )
mr->w1 = wert ;
mr->w2 = 0 ;
LE_ret( mr )
/* public: */ match_rec * str_set :: get_pc
/* -----------------------------------------------------------------------------
return int value of a padded clone representing an int
-----------------------------------------------------------------------------
*/ (
char * & c
, char * k // pointer to key representation
, char * mess // 0, or "e..." (= fErr), or "a..." (= appErr)
)
LB_("str_set.get_pc")
while not_digit( *c ) c++ ;
int wert ; sscanf( c, "%i", &wert );
if ( ! wert )
{
if ( *c == '0' ) { c++ ; ret( 0 ) } else fErr
}
path pc ; char * s = pc ; *s++ = ( char )( wert % 255 + 1 );
char * kk = k ;
while ( *k ) *s++ = *k++ ;
while digit( *c ) *s++ = *c++ ; *s = 0 ;
match_rec * mr = element( pc );
if ( ! mr && mess )
{
if ( *mess == 'e' )
then {
L1_( *this )
S_ "%s pc( %s.%s )\n", ++mess, kk, pc+1 _fErr
}
else S_ "%s pc( %s.%s )\n", ++mess, kk, pc+1 _appErr
errors++ ;
}
LE_ret( mr )
/* public: */ match_rec * str_set :: to_first (
/* -----------------------------------------------------------------------------
Let nextstr point to the first element of the set
-----------------------------------------------------------------------------
*/ )
LB_("str_set.to_first")
nextstr = 0 ;
for ( int r = 0 ; r < 256 ; r++ )
{
nextstr = strings[ r ] ;
if ( nextstr ) ret( nextstr )
}
LE_ret( nextstr )
/* public: */ match_rec * str_set :: to_next (
/* -----------------------------------------------------------------------------
Let nextstr point to the next element of the set
-----------------------------------------------------------------------------
*/ )
LB_("str_set.to_next")
if ( ! nextstr ) ret( 0 )
if ( nextstr -> next )
{
nextstr = nextstr -> next ; ret( nextstr )
}
int r1 = ( uchar ) *( nextstr -> str );
for ( int r = r1+1 ; r < 256 ; r++ )
{
nextstr = strings[ r ] ;
if ( nextstr ) ret( nextstr )
}
LE_ret( nextstr )
/* public: */ uint str_set :: rm_see
/* -----------------------------------------------------------------------------
forget all elements x with s1 <= x.see <= s2
return number of elements forgotten
-----------------------------------------------------------------------------
*/ (
int s1
, int s2
, BOOL trace
)
LB_("str_set.rm_see")
uint r, anz = 0 ;
match_rec * mx ;
match_rec * m = new match_rec ;
match_rec * m1 = m ;
for ( r = 0 ; r < 256 ; r++ )
{
m = m1 ;
m -> next = strings[ r ] ;
while ( m -> next )
{
if ( s1 <= m -> next -> see && m -> next -> see <= s2 )
then {
anz++ ;
mx = m -> next ;
m -> next = m -> next -> next ;
if ( mx == strings[ r ] ) strings[ r ] = m -> next ;
delete( mx );
}
else m = m -> next ;
}
}
delete( m1 );
if ( trace )
{
printf( "\nrm_see( %i, %i ).anz = %i, elements now:", s1, s2, anz );
for ( r = 0 ; r < 256 ; )
{
m = strings[ r++ ] ;
while ( m )
{
printf( "\nsee %i = %s", m -> see, m -> str );
m = m -> next ;
}
}
}
LE_ret( anz )
/* public: */ void str_set :: check (
// -----------------------------------------------------------------------------
)
LB_("str_set.check")
if ( this != ich ) fErr2( this, ich ) // object undeclared or destroyed
LE_
/* public: */ match_rec * str_set :: insert ( char * str
// -----------------------------------------------------------------------------
)
LB_("str_set.insert")
// if ( ! str || ! *str ) fErr1( str )
if ( this != ich ) fErr2( this, ich ) // object undeclared or destroyed
match_rec * rec ; new_sto( rec, match_rec );
updates++ ;
rec -> x = 0 ;
rec -> see = 0 ;
rec -> w1 = 0 ;
rec -> to = 0 ;
rec -> str2 = "" ;
rec -> L = st_clone( rec->str, str ); uchar at = *( rec->str ) ;
if ( strings[ at ] && sm_( rec->str, strings[ at ]->str ) )
then {
match_rec * x = strings[ at ] ;
while ( rec -> L < x -> L )
{
if ( ! x->next )
then {
x->next = rec ; rec->next = x = 0 ; break ;
}
else x = x->next ;
}
if ( x ){ rec->next = x->next ; x->next = rec ; }
}
else {
rec->next = strings[ at ] ; strings[ at ] = rec ;
}
// rec->str k a n n von str verschieden sein (und ist es, wenn
// str = 'ascii. ... ' ist).
//
// Damit ist nun insbesondere garantiert, dass die Lnge der hinter
// strings[ at ] stehenden strings monoton fllt (ist notwendig, damit
// find() korrekt arbeitet, d.h. auch die Werte findet, die Verlngerung
// eines anderen sind.
if ( maxlen <= rec -> L ) maxlen = rec -> L + 1 ;
LE_ret( rec )
/* public: */ match_rec * str_set :: insert
// -----------------------------------------------------------------------------
(
char * str
, char * str2
)
LB_("str_set.insert")
if ( ! str2 ) str2 = "" ;
match_rec * rec = insert( str ); st_clone( rec -> str2, str2 );
LE_ret( rec )
/* public: */ match_rec * str_set :: insert
// -----------------------------------------------------------------------------
(
char * str
, void * data
, int of_len
)
LB_("str_set.insert")
match_rec * rec = insert( str );
st_clone( rec->str2, ( char * ) data, of_len );
LE_ret( rec )
/* public: */ match_rec * str_set :: ensure( char * str
/* -----------------------------------------------------------------------------
Der Aufrufer sagt:
Wenn ( str ) noch nicht im str_set, dann schreib' es rein als
Paar ( str, "" ).
Die Funktion garantiert: fErr || ok
-----------------------------------------------------------------------------
*/ )
LB_("str_set.ensure(")
match_rec * rec = element( str );
if ( ! rec ) rec = insert( str );
LE_ret( rec )
/* public: */ match_rec * str_set :: ensure
/* -----------------------------------------------------------------------------
Der Aufrufer sagt:
Wenn das Paar ( str, str2 ) noch nicht im str_set, dann schreib' es
rein. Ist von str2 schon ein Clone vorhanden, so verwende den - es
zeigen dann die Pointer str2 mehrerer Paare auf denselben Speicher.
Die Funktion garantiert: fErr || ok
-----------------------------------------------------------------------------
*/ (
char * str
, char * str2
)
LB_("str_set.ensure")
if ( ! str ) fErr
if ( ! str[0] ) fErr
match_rec * rec = element( str ); if ( ! rec ) rec = insert( str );
if ( str2 && not_is_( str2, rec -> str2 ) )
{
if ( ! aset ) new_sto( aset, str_set );
rec -> str2 = ( aset -> insert( str2 ) ) -> str ;
}
LE_ret( rec )
/* public: */ BOOL str_set :: forget ( char * str1
/* -----------------------------------------------------------------------------
post condition: String 'str' is not element of 'strings'
return 'str was in set'
-----------------------------------------------------------------------------
*/ )
LB_("str_set.forget")
updates++ ;
char * str ; int L ;
if is( str1, "ascii", 5 )
then {
L = st_clone( str, str1 ); sta -= ( L + 1 ) ;
}
else {
str = str1 ; L = strlen( str ) ;
}
match_rec * rec = strings[ ( uchar ) *str ] ;
match_rec * rec1 = 0 ;
while ( rec )
{
if ( L == rec -> L )
then {
if is( rec->str, str, L )
then {
if ( rec1 )
then rec1->next = rec->next ;
else strings[ ( uchar ) *str ] = rec->next ;
rem_sto( rec );
// Die Strings in rec kann man so nicht freigeben,
// da clone() sie nicht einzeln allokiert.
ret(1)
}
}
rec1 = rec ; rec = rec->next ;
}
LE_ret(0)
/* public: */ match_rec * str_set :: element
/* -----------------------------------------------------------------------------
return 0 if string 'str' not in the set
-----------------------------------------------------------------------------
*/ (
char * str
)
LB_("str_set.element")
match_rec * rec = strings[ ( uchar ) *str ] ;
int len = strlen( str );
while ( rec )
{
if ( len == rec -> L )
then {
if is( rec->str, str, len ) ret( rec )
}
rec = rec->next ;
}
LE_ret(0)
/* public: */ BOOL str_set :: rm ( char * str
/* -----------------------------------------------------------------------------
return 1 if found and deleted
return 0 if not found
-----------------------------------------------------------------------------
*/ )
LB_("str_set.rm")
match_rec * rec = strings[ ( uchar ) *str ] ;
match_rec * pre = 0 ;
int len = strlen( str );
while ( rec )
{
if ( len == rec -> L && is( rec->str, str, len ) )
{
if ( pre ) then pre -> next = rec -> next ;
else strings[ ( uchar ) *str ] = rec -> next ;
ret(1)
}
pre = rec ;
rec = rec->next ;
}
LE_ret(0)
/* public: */ match_rec * str_set :: match
/* -----------------------------------------------------------------------------
return 0 if no match found
else return pointer to f i r s t match
-----------------------------------------------------------------------------
*/ (
char * such
, int prefix // e.g. strlen( such )
)
LB_("str_set.match")
if ( prefix < 0 ) fErr
match_rec * rec = strings[ ( uchar ) *such ] ;
while ( rec )
{
if ( prefix )
then {
if is( such, rec->str, prefix ) ret( rec )
}
else if is( such, rec->str, rec -> L ) ret( rec )
/*
{
int n = prefix ; if ( n == 0 ) n = rec -> L ;
_ show_ascii( such, rec->str, n );
}
*/
rec = rec->next ;
}
LE_ret( 0 )
/* public: */ void str_set :: rsh
/* -----------------------------------------------------------------------------
insert relationship
-----------------------------------------------------------------------------
*/ (
match_rec * f // at
, int r // use relation
, match_rec * s // to
)
LB_("str_set.rsh")
if ( r % 2 ) rsh( s, r-1, f ); // inverse relation is also updated
#define at_relation (( arrow ** )( f->to ))
if ( max_Relation <= r ) fErr
if ( ! f->to )
{
// f->to = new ( arrow * )[ max_Relation ] ; // geht so nicht !!!
f->to = ( arrow ** )malloc( sizeof( arrow * ) * max_Relation );
int n = 0 ; while ( n < max_Relation )
{ L1_( n ) at_relation[ n++ ] = 0 ; }
}
arrow * a = at_relation[r] ;
if ( a )
then {
arrow * pre ;
while ( a )
{
if ( a->to == s ) ret_ else { pre = a ; a = a->next ; }
}
a = pre -> next = new arrow ;
}
else a = at_relation[r] = new arrow ;
a -> next = 0 ;
a -> to = s ;
#undef at_relation
LE_
/* public: */ void str_set :: rsh
/* -----------------------------------------------------------------------------
insert relationship
-----------------------------------------------------------------------------
*/ (
match_rec * f // at
, int r // use relation
, char * s // to
)
LB_("str_set.rsh")
match_rec * mrs = ensure( s, 0 ); rsh( f, r, mrs );
LE_
/* public: */ void str_set :: rsh
/* -----------------------------------------------------------------------------
insert relationship
-----------------------------------------------------------------------------
*/ (
char * f // at
, int r // use relation
, char * s // to
)
LB_("str_set.rsh")
match_rec * mrf = ensure( f, 0 );
match_rec * mrs = ensure( s, 0 ); rsh( mrf, r, mrs );
LE_
/* public: */ void str_set :: rsh
/* -----------------------------------------------------------------------------
insert relationship
-----------------------------------------------------------------------------
*/ (
char * f // at father
, int r // use relation
, match_rec * s // to son
)
LB_("str_set.rsh")
match_rec * mrf = ensure( f, 0 ); rsh( mrf, r, s );
LE_
/* public: */ void str_set :: closure
/* -----------------------------------------------------------------------------
Der Aufrufer sagt:
Mache Relation 'r transitiv abgeschlossen.
Die Funktion garantiert: fErr || ok
-----------------------------------------------------------------------------
*/ (
int r
)
LB_("str_set.closure")
if ( r%2 ) r++ ;
if ( max_Relation <= r ) fErr
rsh_set Res ; sort(1); // printf( "card = %i\n", card );
for ( int n = 0 ; n < card ; n++ )
{
match_rec * mr = elem[ n ];
trans_rsh_at( Res, mr, r, 0 );
for ( int m = Res.a_trans ; m < Res.e ; ) rsh( mr, r, Res.res[m++] );
}
LE_
/* public: */ void str_set :: rsh_at
/* -----------------------------------------------------------------------------
Der Aufrufer sagt:
Make 'Res the set of arrows ( 'mr, 'relation, * )
Die Funktion garantiert: fErr || ok
-----------------------------------------------------------------------------
*/ (
rsh_set & Res
, match_rec * mr
, int relation
)
LB_("str_set.rsh_at")
for ( int m = 0 ; m < card ; ) elem[ m++ ]->x = 1 ;
Res.e = 0 ;
#define at_relation (( arrow ** )( mr->to ))
if ( at_relation )
{
arrow * a = at_relation[ relation ];
while ( a )
{
if ( L_res <= Res.e )
S_ "error: Konstante str_set.L_res = %i zu klein\n", L_res _fErr
if ( a->to->x ) { a->to->x = 0 ; Res.res[ Res.e++ ] = a->to ; }
/* for ( int j = 0 ; j < Res.e ; j++ )
{
if ( Res.res[j] == a->to ) j = Res.e + 1 ;
}
if ( j == Res.e ) Res.res[ Res.e++ ] = a->to ; */
a = a->next ;
}
}
#undef at_relation
Res.a_trans = Res.e ;
LE_
/* private: */ void str_set :: trans_rsh_at
/* -----------------------------------------------------------------------------
Make 'Res the transitive closure of ( 'us, 'relation, * )
-----------------------------------------------------------------------------
*/ (
rsh_set & Res
, match_rec * us
, int relation
, int depth
)
LB_("str_set.trans_rsh_at")
if ( depth == 0 )
{
for ( int m = 0 ; m < card ; ) elem[ m++ ]->x = 1 ;
Res.a_trans = Res.e = 0 ;
}
if ( us->x ) // not yet in closure
{
if ( L_res <= Res.e )
{
m_errMess "System: error: Konstante str_set.L_res = %i zu klein\n" m_
L_res, ret_error
}
us->x = 0 ; Res.res[ Res.e++ ] = us ;
if ( us->to )
{
// calculate recursive closure:
#define at_relation (( arrow ** )( us->to ))
arrow * a = at_relation[ relation ];
while ( a )
{
if ( a->to->x ) trans_rsh_at( Res, a->to, relation, depth + 1 );
a = a->next ;
}
#undef at_relation
}
}
if ( depth == 0 ) Res.a_trans = Res.e ;
LE_
/* public: */ int str_set :: cardinality(
/* -----------------------------------------------------------------------------
Return cardinality of this str_set
-----------------------------------------------------------------------------
*/ )
LB_("str_set.cardinality")
// if ( ! updates ) ret( card ) else updates = card = 0 ;
updates = card = 0 ;
for ( int r = 0 ; r < 256 ; )
{
match_rec * rec = strings[ r++ ] ;
while ( rec ) { card++ ; rec = rec->next ; }
}
LE_ret( card )
int compare_mr
/* -----------------------------------------------------------------------------
for use in qsort when sorting elements of str_set
-----------------------------------------------------------------------------
*/ (
const void * mr1
, const void * mr2
);
#ifndef NOSORT
#include comp_mr.cpp
#endif
/* public: */ void str_set :: sort
/* -----------------------------------------------------------------------------
Make elem[ 0 .. card [ the ascendingly sorted str_set.
Note: sort( 0 ) defines card and elem[], but does not sort.
-----------------------------------------------------------------------------
*/ (
int a_compare_method
)
LB_("str_set.sort")
if ( this != ich ) fErr // object not yet declared oder zerstrt !!!!
card = cardinality();
int L = ( card + 1 ) * sizeof( match_rec * );
if ( ste < sta + L )
then {
if ( L_stopage <= L ) fErr
store * pre = sto ; new_sto( sto, store ); sto->pre = pre ;
ste = ( sta = sto->sto ) + L_stopage ;
}
else ;
elem = ( match_rec ** )sta ; sta += L ;
int n = 0 ;
for ( int r = 0 ; r < 256 ; )
{
match_rec * rec = strings[ r++ ] ;
while ( rec ) { elem[ n++ ] = rec ; rec = rec->next ; }
}
if ( n != card )
{
trace_on L1_( *this )
S_ "n = %i <> %i = card \n", n, card _fErr
}
#ifndef NOSORT
switch ( a_compare_method )
{
case 1: qsort( elem, card, sizeof( match_rec * ), compare_mr );
Case 2: qsort( elem, card, sizeof( match_rec * ), compare_mr2 );
Case 3: qsort( elem, card, sizeof( match_rec * ), compare_mr3 );
Else : ;
}
#else
fErr
#endif
/*
for ( r = 0 ; r < card; r++ )
{
printf( "%4i %s[%s]\n", r, elem[r]->str, elem[r]->str2 );
}
printf( "%i = elem.card \n", card );
*/
/*
for ( r = 0 ; r < card ; r++ )
{
if ( ! elem[ r ] ) fErr
if ( ! elem[ r ] -> str ) fErr
if ( strlen( elem[r] -> str ) < 4 ) fErr
printf( "\n%4i %s", r, elem[r]->str );
}
//
*/
LE_
#undef static
#endif