Initial import of the CDE 2.1.30 sources from the Open Group.
This commit is contained in:
583
cde/programs/dtinfo/DtMmdb/StyleSheet/PathTable.C
Normal file
583
cde/programs/dtinfo/DtMmdb/StyleSheet/PathTable.C
Normal file
@@ -0,0 +1,583 @@
|
||||
// $XConsortium: PathTable.cc /main/4 1996/06/11 17:07:57 cde-hal $
|
||||
#include "PathTable.h"
|
||||
#include "Debug.h"
|
||||
#include "Feature.h"
|
||||
#include "utility/debug.h"
|
||||
|
||||
extern SymbolTable* gElemSymTab;
|
||||
|
||||
unsigned int letterHash(const LetterType& x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
EncodedPath::~EncodedPath()
|
||||
{
|
||||
delete [] f_array ;
|
||||
f_SVectors.clearAndDestroy();
|
||||
delete f_copyOfS;
|
||||
}
|
||||
|
||||
EncodedPath::EncodedPath(SSPath* p, unsigned int asPattern) :
|
||||
f_size(p -> entries()), f_SVectors(letterHash), f_patternSize(0),
|
||||
f_wildCard(gElemSymTab -> wildCardId()),
|
||||
f_unlimitedWildCard(gElemSymTab -> unlimitedWildCardId()),
|
||||
f_copyOfS(new BitVector(WORD_SIZE, 0))
|
||||
{
|
||||
|
||||
f_array = new LetterType[f_size];
|
||||
|
||||
CC_TPtrDlistIterator<PathTerm> l_pathIter(*p);
|
||||
|
||||
BitVector *l_bv = 0;
|
||||
|
||||
int i = 0;
|
||||
|
||||
while (++l_pathIter) {
|
||||
|
||||
//
|
||||
// Count pattern size, excluding "*".
|
||||
//
|
||||
f_array[i] = (LetterType)((l_pathIter.key() -> symbol()).id());
|
||||
if ( f_array[i] != f_unlimitedWildCard )
|
||||
f_patternSize++;
|
||||
i++;
|
||||
}
|
||||
|
||||
if ( asPattern == true ) {
|
||||
|
||||
//
|
||||
// Compute the S arrays.
|
||||
// Examples pat = a b a c
|
||||
// S(a) = 1 0 1 0
|
||||
// S(b) = 0 0 0 0
|
||||
// S(c) = 0 0 0 1
|
||||
//
|
||||
// pat = a ? a c
|
||||
// S(a) = 1 1 1 0
|
||||
// S(c) = 0 1 0 1
|
||||
// S(?) = 0 1 0 0
|
||||
//
|
||||
// pat = a * a c
|
||||
// S(a) = 1 1 0
|
||||
// S(c) = 0 0 1
|
||||
// S(*) = 1 0 0
|
||||
//
|
||||
l_pathIter.reset();
|
||||
int j = patternLength()-1;
|
||||
|
||||
LetterType l_id;
|
||||
|
||||
// i records each PathTerm position in the list
|
||||
int i=0;
|
||||
|
||||
while (++l_pathIter) {
|
||||
l_id = (LetterType)((l_pathIter.key() -> symbol()).id());
|
||||
|
||||
l_bv = f_SVectors.findValue(&l_id);
|
||||
if ( l_bv == 0 ) {
|
||||
l_bv = new BitVector(patternLength(), 0);
|
||||
f_SVectors.insertKeyAndValue(new LetterType(l_id), l_bv);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
// reverse the order in the bit vector:
|
||||
// MSB position ==> set LSB bit in the bit vector
|
||||
///////////////////////////////////////////////////
|
||||
if ( l_id != f_unlimitedWildCard ) {
|
||||
l_bv -> setBitTo(j, 1);
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// only set position when an expr is attatched
|
||||
// to the term
|
||||
//////////////////////////////////////////////////
|
||||
if ( l_pathIter.key() -> pqexpr() && l_id != f_wildCard ) {
|
||||
/*
|
||||
MESSAGE(cerr, "==========");
|
||||
debug(cerr, (void*)l_bv);
|
||||
debug(cerr, *l_bv);
|
||||
debug(cerr, i);
|
||||
debug(cerr, j);
|
||||
*/
|
||||
l_bv -> recordPositions(i, j);
|
||||
|
||||
}
|
||||
|
||||
j--;
|
||||
|
||||
} else {
|
||||
///////////////////////////////////////////////////
|
||||
// do not set bits for unlimitedWildCards that
|
||||
// begin or end the pattern
|
||||
///////////////////////////////////////////////////
|
||||
if ( j < patternLength() - 1 )
|
||||
l_bv -> setBitTo(j+1, 1);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
// special treatment to the ? symbols:
|
||||
// OR S(?) back to each S's.
|
||||
///////////////////////////////////////////////////
|
||||
BitVector* l_BitVectorWildCard = f_SVectors.findValue(&f_wildCard);
|
||||
hashTableIterator<LetterType, BitVector> l_SVIter(f_SVectors);
|
||||
|
||||
if ( l_BitVectorWildCard ) {
|
||||
while (++l_SVIter) {
|
||||
if ( *l_SVIter.key() != f_wildCard &&
|
||||
*l_SVIter.key() != f_unlimitedWildCard
|
||||
)
|
||||
{
|
||||
(*l_SVIter.value()) |= (*l_BitVectorWildCard);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
#ifdef DEBUG
|
||||
l_SVIter.reset();
|
||||
while (++l_SVIter) {
|
||||
debug(cerr, (*l_SVIter.key()));
|
||||
debug(cerr, (*l_SVIter.value()));
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned int
|
||||
_match(LetterType* pattern, int n,
|
||||
LetterType* text, int m,
|
||||
LetterType wildCard,
|
||||
LetterType unlimitedWildCard
|
||||
)
|
||||
{
|
||||
// A naive (brute force) string matching algorithm that handles
|
||||
// wild card (?) and unlimited wild card (*) symbols.
|
||||
unsigned int findMisMatch = false;
|
||||
|
||||
for ( int i=0; i<n; i++ ) { // over the "text" string
|
||||
|
||||
for ( int j=0; j<m; j++ ) { // over the pattern
|
||||
if ( pattern[j] == wildCard ) {
|
||||
continue;
|
||||
} else
|
||||
if ( pattern[j] == unlimitedWildCard ) {
|
||||
|
||||
for (;;) {
|
||||
|
||||
j++;
|
||||
|
||||
if ( j == m )
|
||||
return true;
|
||||
|
||||
if ( pattern[j] != unlimitedWildCard )
|
||||
break;
|
||||
}
|
||||
|
||||
for ( int x=i+1; x<n; x++ ) {
|
||||
if ( text[x] == pattern[j] )
|
||||
if (
|
||||
_match(
|
||||
&pattern[j], m-j,
|
||||
&text[x], n-x,
|
||||
wildCard, unlimitedWildCard
|
||||
) == true
|
||||
)
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
if ( pattern[j] != text[i] ) {
|
||||
findMisMatch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( findMisMatch == false )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
unsigned int
|
||||
EncodedPath::match(EncodedPath& text, SSPath* patternPath, SSPath* elementPath)
|
||||
{
|
||||
////////////////////////////////////////////////
|
||||
// text: the encoded string for the element path
|
||||
// elementPath: the element path
|
||||
//
|
||||
// this: the encoded string for the pattern string
|
||||
// patternPath: the pattern path
|
||||
////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// the unlimited wildcard vector
|
||||
////////////////////////////////////////////////
|
||||
BitVector* l_U = f_SVectors.findValue(&f_unlimitedWildCard);
|
||||
|
||||
if ( l_U && patternLength() == 0 )
|
||||
return true;
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// the wildcard vector
|
||||
////////////////////////////////////////////////
|
||||
BitVector* l_W = f_SVectors.findValue(&f_wildCard);
|
||||
|
||||
// the S vector of each Letter, including that for '?'
|
||||
BitVector* l_S = 0;
|
||||
|
||||
// the accumulated result vector
|
||||
BitVector l_R(patternLength(), 0);
|
||||
|
||||
// placeholder for '*''s contribution
|
||||
BitVector l_I(patternLength(), 0);
|
||||
|
||||
// hole position record of each path term in the pattern path
|
||||
posRecord l_pr;
|
||||
|
||||
// expr pointer of each path term in the pattern path
|
||||
PQExpr* expr = 0;
|
||||
|
||||
CC_TPtrDlistIterator<PathTerm>* elementPathNextPtr = 0;
|
||||
|
||||
if ( elementPath )
|
||||
elementPathNextPtr = new CC_TPtrDlistIterator<PathTerm>(*elementPath);
|
||||
|
||||
// loop over text string
|
||||
for ( int i=0; i<text.length(); i++) {
|
||||
|
||||
if ( elementPath )
|
||||
++(*elementPathNextPtr);
|
||||
|
||||
//MESSAGE(cerr, "===================");
|
||||
//debug(cerr, text.f_array[i]);
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// get this character's vector, including '?'s
|
||||
////////////////////////////////////////////////
|
||||
l_S = f_SVectors.findValue(&text.f_array[i]);
|
||||
|
||||
if ( l_S ) {
|
||||
//debug(cerr, (void*)l_S);
|
||||
//debug(cerr, *l_S);
|
||||
//MESSAGE(cerr, "checking qualifies");
|
||||
//////////////////////
|
||||
// check qualifies.
|
||||
//////////////////////
|
||||
if ( patternPath && l_S -> positionArray() ) {
|
||||
|
||||
////////////////////
|
||||
// get a copy of S
|
||||
////////////////////
|
||||
f_copyOfS -> setTo(*l_S);
|
||||
|
||||
//debug(cerr, *patternPath);
|
||||
|
||||
positionArrayIteratorT l_positionNext(*(l_S -> positionArray()));
|
||||
while (++ l_positionNext) {
|
||||
|
||||
l_pr = l_positionNext.key();
|
||||
|
||||
//cerr << " calling patternPath -> fastGetAt(): " << (void*)patternPath << "l_pr.pathTermPos= " << l_pr.pathTermPos << endl;
|
||||
|
||||
expr = patternPath -> fastGetAt(l_pr.pathTermPos) -> pqexpr();
|
||||
/*
|
||||
debug(cerr, int(expr));
|
||||
if ( expr ) {
|
||||
MESSAGE(cerr, "qualify checking is needed.");
|
||||
debug(cerr, *(elementPathNext -> key()));
|
||||
}
|
||||
*/
|
||||
|
||||
if ( expr &&
|
||||
expr->evaluate(elementPathNextPtr->key()->element()) == PQFalse )
|
||||
{
|
||||
//MESSAGE(cerr, form("set position %d to 0", l_pr.bitPos));
|
||||
f_copyOfS -> setBitTo(l_pr.bitPos, 0);
|
||||
}
|
||||
}
|
||||
/////////////////////////////////////////
|
||||
// make l_S point at its modified copy
|
||||
/////////////////////////////////////////
|
||||
l_S = f_copyOfS;
|
||||
}
|
||||
} else
|
||||
l_S = l_W;
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// get unlimited wildcard's vector.
|
||||
////////////////////////////////////////////////
|
||||
if ( l_U ) {
|
||||
l_I.setTo(l_R);
|
||||
l_I &= (*l_U);
|
||||
//MESSAGE(cerr, "l_I");
|
||||
//debug(cerr, l_I);
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// shift the partial result vector right once
|
||||
////////////////////////////////////////////////
|
||||
l_R.shiftRightOneBit();
|
||||
//MESSAGE(cerr, "after l_R >> 1");
|
||||
//debug(cerr, l_R);
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// AND in this character's vector
|
||||
////////////////////////////////////////////////
|
||||
if ( l_S ) {
|
||||
l_R &= (*l_S);
|
||||
//debug(cerr, *l_S);
|
||||
//MESSAGE(cerr, "after AND with l_S");
|
||||
//debug(cerr, l_R);
|
||||
} else {
|
||||
///////////////////////////////////////////////
|
||||
// this branch is impossible to reach.
|
||||
///////////////////////////////////////////////
|
||||
//MESSAGE(cerr, "l_R set all bits to 0");
|
||||
l_R.setAllBitsTo(0);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// OR in unlimited wild char's vector.
|
||||
///////////////////////////////////////////////
|
||||
if ( l_U ) {
|
||||
l_R |= l_I;
|
||||
//MESSAGE(cerr, "after OR with l_I");
|
||||
//debug(cerr, l_R);
|
||||
}
|
||||
//debug(cerr, l_R);
|
||||
//MESSAGE(cerr, "===================");
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// Use this test to get the first matched position
|
||||
// if ( l_R.getBit(0) == 1 )
|
||||
// return true;
|
||||
///////////////////////////////////////////////
|
||||
|
||||
}
|
||||
delete elementPathNextPtr;
|
||||
|
||||
///////////////////////////////////////////////
|
||||
//
|
||||
// the last symbol must match
|
||||
//
|
||||
///////////////////////////////////////////////
|
||||
if ( l_R.getBit(0) == 1 )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
basePathFeature::~basePathFeature()
|
||||
{
|
||||
delete f_path;
|
||||
delete f_featureSet;
|
||||
}
|
||||
|
||||
PathFeature::~PathFeature()
|
||||
{
|
||||
delete f_encodedPath ;
|
||||
}
|
||||
|
||||
unsigned int basePathFeature::operator==(const basePathFeature& pf) const
|
||||
{
|
||||
cerr << "Warning: basePathFeature::operator==() called\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int PathFeature::operator==(const PathFeature& pf) const
|
||||
{
|
||||
cerr << "Warning: PathFeature::operator==() called\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
void pathSelector(BitVector& bv)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned int
|
||||
PathFeature::match(SSPath& p)
|
||||
{
|
||||
EncodedPath l_ep(&p);
|
||||
|
||||
if ( f_path -> containSelector() == false )
|
||||
return f_encodedPath -> match(l_ep, 0, 0);
|
||||
else
|
||||
return f_encodedPath -> match(l_ep, f_path, &p);
|
||||
}
|
||||
|
||||
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// class PathTable
|
||||
//
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
unsigned symHashFunc(const Symbol& s)
|
||||
{
|
||||
return s.hash();
|
||||
}
|
||||
|
||||
PathTable::PathTable()
|
||||
: f_lastSymIndex(0),
|
||||
f_lastSymIndexCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
PathTable::~PathTable()
|
||||
{
|
||||
f_pathFeatureList.clearAndDestroy();
|
||||
for (unsigned int i = 0 ; i < f_lastSymIndexCount; i++) {
|
||||
//f_lastSymIndex[i].clearAndDestroy();
|
||||
f_lastSymIndex[i] -> clear();
|
||||
delete f_lastSymIndex[i];
|
||||
}
|
||||
delete f_lastSymIndex;
|
||||
}
|
||||
|
||||
LetterType PathTable::findIndex(SSPath& p)
|
||||
{
|
||||
return (LetterType) ((p.last() -> symbol()).id());
|
||||
}
|
||||
|
||||
void PathTable::initLastSymIndex()
|
||||
{
|
||||
f_lastSymIndexCount = gElemSymTab -> IdsAssigned()+1;
|
||||
f_lastSymIndex = new CC_TPtrDlist_PathFeature_Ptr_T[f_lastSymIndexCount];
|
||||
for (int i=0; i<f_lastSymIndexCount; i++)
|
||||
f_lastSymIndex[i] = new CC_TPtrDlist<PathFeature>;
|
||||
|
||||
|
||||
CC_TPtrDlistIterator<PathFeature> l_pfIter(f_pathFeatureList);
|
||||
PathFeature* l_pathFeature = 0;
|
||||
|
||||
LetterType x;
|
||||
|
||||
while ( ++l_pfIter ) {
|
||||
l_pathFeature = l_pfIter.key();
|
||||
x = findIndex( *(l_pathFeature->path()) );
|
||||
//f_lastSymIndex[x] -> prepend(l_pathFeature); // backward order
|
||||
f_lastSymIndex[x] -> append(l_pathFeature); // select the matching rule
|
||||
// in the same order rules
|
||||
// appear in the
|
||||
// stylesheet
|
||||
}
|
||||
}
|
||||
|
||||
FeatureSet* PathTable::getFeatureSet(SSPath& p)
|
||||
{
|
||||
if ( f_lastSymIndex == 0 ) {
|
||||
initLastSymIndex();
|
||||
}
|
||||
|
||||
int pids[3];
|
||||
FeatureSet* fs[3];
|
||||
|
||||
fs[0] = getFeatureSet(findIndex(p), p, pids[0]);
|
||||
fs[1] = getFeatureSet(gElemSymTab -> wildCardId(), p, pids[1]);
|
||||
fs[2] = getFeatureSet(gElemSymTab -> unlimitedWildCardId(), p, pids[2]);
|
||||
|
||||
int index = 0;
|
||||
int x = pids[0];
|
||||
|
||||
for ( int i=1; i<3; i++ ) {
|
||||
if ( pids[i] > x )
|
||||
index = i;
|
||||
}
|
||||
|
||||
return fs[index];
|
||||
}
|
||||
|
||||
FeatureSet*
|
||||
PathTable::getFeatureSet(int bucketIndex, SSPath& p, int& pathId)
|
||||
{
|
||||
CC_TPtrDlistIterator<PathFeature> l_pathFeatureIter(*f_lastSymIndex[bucketIndex]);
|
||||
|
||||
l_pathFeatureIter.reset();
|
||||
|
||||
PathFeature* l_pathFeature = 0;
|
||||
|
||||
while ( ++l_pathFeatureIter ) {
|
||||
|
||||
l_pathFeature = l_pathFeatureIter.key();
|
||||
|
||||
//debug(cerr, *(l_pathFeature->path()));
|
||||
//debug(cerr, *(l_pathFeature->featureSet()));
|
||||
|
||||
if ( l_pathFeature -> match(p) ) {
|
||||
//MESSAGE(cerr, "match");
|
||||
pathId = l_pathFeature -> id();
|
||||
return l_pathFeature -> featureSet();
|
||||
}
|
||||
}
|
||||
|
||||
pathId = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PathTable::addPathFeatureSet(PathFeature* x)
|
||||
{
|
||||
//MESSAGE(cerr, "addPathFeatureSet():");
|
||||
//debug(cerr, *(x->path()));
|
||||
//debug(cerr, *(x->featureSet()));
|
||||
|
||||
if ( x -> path() -> containSelector() )
|
||||
x -> path() -> fastGetIndex();
|
||||
|
||||
EncodedPath* l_epath = new EncodedPath(x -> path(), true);
|
||||
unsigned int id = f_pathFeatureList.entries()+1;
|
||||
|
||||
x -> setEncodedPath(l_epath);
|
||||
x -> setID(id);
|
||||
|
||||
f_pathFeatureList.insert(x);
|
||||
|
||||
}
|
||||
|
||||
ostream& operator<<(ostream& out, PathTable& pt)
|
||||
{
|
||||
CC_TPtrDlistIterator<PathFeature> l_pfIter(pt.f_pathFeatureList);
|
||||
PathFeature* l_pathFeature = 0;
|
||||
|
||||
while ( ++l_pfIter ) {
|
||||
l_pathFeature = l_pfIter.key();
|
||||
|
||||
out << *(l_pathFeature)->path() << ' ' << *(l_pathFeature->featureSet())
|
||||
<< endl;
|
||||
|
||||
#ifdef DEBUG
|
||||
// this will cause errors if gTopOfStack is not set properly
|
||||
FeatureSet *set = l_pathFeature->featureSet()->evaluate();
|
||||
out << *set << endl;
|
||||
delete set ;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void PathFeatureList::appendList(PathFeatureList& list)
|
||||
{
|
||||
PathFeatureListIterator l_Iter(list);
|
||||
while ( ++ l_Iter ) {
|
||||
append(l_Iter.key());
|
||||
}
|
||||
}
|
||||
|
||||
PathFeatureList::~PathFeatureList()
|
||||
{
|
||||
clearAndDestroy();
|
||||
}
|
||||
Reference in New Issue
Block a user