diff options
Diffstat (limited to 'i18npool/source/search/levdis.cxx')
-rw-r--r-- | i18npool/source/search/levdis.cxx | 779 |
1 files changed, 779 insertions, 0 deletions
diff --git a/i18npool/source/search/levdis.cxx b/i18npool/source/search/levdis.cxx new file mode 100644 index 000000000000..aa889a6d3581 --- /dev/null +++ b/i18npool/source/search/levdis.cxx @@ -0,0 +1,779 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_i18npool.hxx" +/************************************************************************* + + Weighted Levenshtein Distance + including wildcards + '*' for any number (0 or more) of arbitrary characters + '?' for exactly one arbitrary character + escapeable with backslash, "\*" or "\?" + + Return: + WLD if WLD <= nLimit, else nLimit+1 + + or, if bSplitCount: + WLD if WLD <= nLimit + -WLD if Replace and Insert and Delete <= nLimit + else nLimit+1 + + Recursive definition of WLD: + + WLD( X(i), Y(j) ) = min( WLD( X(i-1), Y(j-1) ) + p(i,j) , + WLD( X(i) , Y(j-1) ) + q , + WLD( X(i-1), Y(j) ) + r ) + + X(i) := the first i characters of the word X + Y(j) := the first j characters of the word Y + p(i,j) := 0 if i-th character of X == j-th character of Y, + p else + + Boundary conditions: + WLD( X(0), Y(j) ) := j*q (Y created by j inserts) + WLD( X(i), Y(0) ) := i*r (Y created by i deletes) + WLD( X(0), Y(0) ) := 0 + + Instead of recursions a dynamic algorithm is used. + + See also: German computer magazine + c't 07/89 pages 192-208 and c't 03/94 pages 230-239 + +*************************************************************************/ + + +#include <string.h> // strlen() + +#if defined( _MSC_VER ) +#pragma warning(once: 4068) +#endif + +#include "levdis.hxx" + + +#ifdef erTEST +#include <stdlib.h> +#include <stdio.h> +#include <iostream.h> +#endif + +#ifdef SOLARIS +#undef min +#endif + +#define LEVDISBIG (nLimit + 1) // Returnwert wenn Distanz > nLimit +#define LEVDISDOUBLEBUF 2048 // dadrueber wird nicht mehr gedoppelt + +// Balance, aus Geschwindigkeitsgruenden ist dieses keine Funktion +// c == cpPattern[jj] == cString[ii] +// erst wird bis Fundstelle gesucht, wenn dort die Balance gleich ist, wird +// auch nach der Fundstelle verglichen +#define LEVDISBALANCE(jj,ii) \ +{ \ + if ( jj != ii ) \ + { \ + register sal_Int32 k; \ + if ( jj > 0 ) \ + for ( k=0; k < jj; k++ ) \ + if ( cpPattern[k] == c ) \ + nBalance++; \ + if ( ii > 0 ) \ + for ( k=0; k < ii; k++ ) \ + if ( cString[k] == c ) \ + nBalance--; \ + if ( !nBalance ) \ + { \ + for ( k=jj+1; k < nPatternLen; k++ ) \ + if ( cpPattern[k] == c ) \ + nBalance++; \ + for ( k=ii+1; k < nStringLen; k++ ) \ + if ( cString[k] == c ) \ + nBalance--; \ + } \ + } \ +} + +static sal_Int32 Impl_WLD_StringLen( const sal_Unicode* pStr ) +{ + const sal_Unicode* pTempStr = pStr; + while( *pTempStr ) + pTempStr++; + return (sal_Int32)(pTempStr-pStr); +} + +#ifdef erTESTMAT +#define erTESTMATMAX 180 +static int npMatrix[erTESTMATMAX][erTESTMATMAX]; // nearly 64K +#endif + +// Distanz von String zu Pattern +int WLevDistance::WLD( const sal_Unicode* cString, sal_Int32 nStringLen ) +{ + int nSPMin = 0; // StrafPunkteMinimum + int nRepS = 0; // fuer SplitCount + +#ifdef erTESTMAT +{ + for ( sal_Int32 r=0; r<=nStringLen && r < erTESTMATMAX; r++ ) + for ( sal_Int32 c=0; c<=nPatternLen && c < erTESTMATMAX; c++ ) + npMatrix[r][c] = 99; // Matrix initialisieren, nur visuell +} +#endif + + // Laengendifferenz von Pattern und String + int nLenDiff = nPatternLen - nStars - nStringLen; + // mehr Einfuegungen oder Loeschungen noetig als Limit? => raus hier + if ( (nLenDiff * nInsQ0 > nLimit) + || ((nStars == 0) && (nLenDiff * nDelR0 < -nLimit)) ) + return(LEVDISBIG); + + // wenn der zu vergleichende String groesser ist als das bisherige Array + // muss dieses angepasst werden + if ( nStringLen >= nArrayLen ) + { + // gib ihm moeglichst mehr, damit nicht gleich naechstesmal + // wieder realloziert werden muss + if ( nStringLen < LEVDISDOUBLEBUF ) + nArrayLen = 2 * nStringLen; + else + nArrayLen = nStringLen + 1; + npDistance = aDisMem.NewMem( nArrayLen ); +#ifdef erTEST + if ( !npDistance ) + { + cerr << "DOOM! (Damned, Out Of Memory)" << endl; + exit(1); + } +#endif + } + + // Anfangswerte der zweiten Spalte (erstes Pattern-Zeichen) berechnen + // die erste Spalte (0-Len Pattern) ist immer 0 .. nStringLen * nInsQ0, + // deren Minimum also 0 + if ( nPatternLen == 0 ) + { + // Anzahl der Loeschungen, um auf Pattern zu kommen + for ( sal_Int32 i=0; i <= nStringLen; i++ ) + npDistance[i] = i * nDelR0; + } + else if ( cpPattern[0] == '*' && bpPatIsWild[0] ) + { + // statt einem '*' ist alles einsetzbar + for ( sal_Int32 i=0; i <= nStringLen; i++ ) + npDistance[i] = 0; + } + else + { + sal_Unicode c; + int nP; + c = cpPattern[0]; + if ( c == '?' && bpPatIsWild[0] ) + nP = 0; // ein '?' kann jedes Zeichen sein + else + // Minimum von Ersetzen und Loeschen+Einfuegen Gewichtung + nP = Min3( nRepP0, nRepP0, nDelR0 + nInsQ0 ); + npDistance[0] = nInsQ0; // mit einfachem Einfuegen geht's los + npDistance[1] = nInsQ0; + npDistance[2] = nInsQ0; + int nReplacePos = -1; // tristate Flag + int nDelCnt = 0; + for ( sal_Int32 i=1; i <= nStringLen; i++, nDelCnt += nDelR0 ) + { + if ( cString[i-1] == c ) + nP = 0; // Replace ab dieser Stelle ist 0 + // Loeschungen um auf Pattern zu kommen + Replace + npDistance[i] = nDelCnt + nP; + if ( bSplitCount ) + { + if ( nReplacePos < 0 && nP ) + { // diese Stelle wird ersetzt + nRepS++; + nReplacePos = i; +#ifdef erTESTMAT + npMatrix[i][1] = -npDistance[i]; +#endif + } + else if ( nReplacePos > 0 && !nP ) + { + int nBalance = 0; // gleiche Anzahl c + LEVDISBALANCE( 0, i-1 ); + if ( !nBalance ) + { // einer wurde ersetzt, der ein Insert war + nRepS--; +#ifdef erTESTMAT + npMatrix[nReplacePos][1] = npDistance[nReplacePos]; +#endif + nReplacePos = 0; + } + } + } + } + nSPMin = Min3( npDistance[0], npDistance[1], npDistance[2] ); + } +#ifdef erTESTMAT +{ + for ( sal_Int32 r=0; r<=nStringLen && r < erTESTMATMAX; r++ ) + { + npMatrix[r][0] = r * nInsQ0; + if ( npMatrix[r][1] >= 0) + npMatrix[r][1] = npDistance[r]; + } +} +#endif + + // Distanzmatrix berechnen + sal_Int32 j = 0; // fuer alle Spalten des Pattern, solange nicht Limit + while ( (j < nPatternLen-1) + && nSPMin <= (bSplitCount ? 2 * nLimit : nLimit) ) + { + sal_Unicode c; + int nP, nQ, nR, nPij, d1, d2; + + j++; + c = cpPattern[j]; + if ( bpPatIsWild[j] ) // '*' oder '?' nicht escaped + nP = 0; // kann ohne Strafpunkte ersetzt werden + else + nP = nRepP0; + if ( c == '*' && bpPatIsWild[j] ) + { + nQ = 0; // Einfuegen und Loeschen ohne Strafpunkte + nR = 0; + } + else + { + nQ = nInsQ0; // normale Gewichtung + nR = nDelR0; + } + d2 = npDistance[0]; + // Anzahl Einfuegungen um von Null-String auf Pattern zu kommen erhoehen + npDistance[0] = npDistance[0] + nQ; + nSPMin = npDistance[0]; + int nReplacePos = -1; // tristate Flag + // fuer jede Patternspalte den String durchgehen + for ( register sal_Int32 i=1; i <= nStringLen; i++ ) + { + d1 = d2; // WLD( X(i-1), Y(j-1) ) + d2 = npDistance[i]; // WLD( X(i) , Y(j-1) ) + if ( cString[i-1] == c ) + { + nPij = 0; // p(i,j) + if ( nReplacePos < 0 ) + { + int nBalance = 0; // gleiche Anzahl c + LEVDISBALANCE( j, i-1 ); + if ( !nBalance ) + nReplacePos = 0; // keine Ersetzung mehr + } + } + else + nPij = nP; + // WLD( X(i), Y(j) ) = min( WLD( X(i-1), Y(j-1) ) + p(i,j) , + // WLD( X(i) , Y(j-1) ) + q , + // WLD( X(i-1), Y(j) ) + r ) + npDistance[i] = Min3( d1 + nPij, d2 + nQ, npDistance[i-1] + nR ); + if ( npDistance[i] < nSPMin ) + nSPMin = npDistance[i]; + if ( bSplitCount ) + { + if ( nReplacePos < 0 && nPij && npDistance[i] == d1 + nPij ) + { // diese Stelle wird ersetzt + nRepS++; + nReplacePos = i; +#ifdef erTESTMAT + npMatrix[i][j+1] = -npDistance[i]; +#endif + } + else if ( nReplacePos > 0 && !nPij ) + { // Zeichen in String und Pattern gleich. + // wenn ab hier die gleiche Anzahl dieses Zeichens + // sowohl in Pattern als auch in String ist, und vor + // dieser Stelle das Zeichen gleich oft vorkommt, war das + // Replace keins. Buchstabendreher werden hier erfasst + // und der ReplaceS zurueckgenommen, wodurch das doppelte + // Limit zum Tragen kommt. + int nBalance = 0; // gleiche Anzahl c + LEVDISBALANCE( j, i-1 ); + if ( !nBalance ) + { // einer wurde ersetzt, der ein Insert war + nRepS--; +#ifdef erTESTMAT + npMatrix[nReplacePos][j+1] = npDistance[nReplacePos]; +#endif + nReplacePos = 0; + } + } + } + } +#ifdef erTESTMAT +{ + for ( sal_Int32 r=0; r<=nStringLen && r < erTESTMATMAX; r++ ) + if ( npMatrix[r][j+1] >= 0) + npMatrix[r][j+1] = npDistance[r]; +} +#endif + } +#ifdef erTESTSPLIT + printf(" nRepS: %d ", nRepS ); +#endif + if ( (nSPMin <= nLimit) && (npDistance[nStringLen] <= nLimit) ) + return(npDistance[nStringLen]); + else + { + if ( bSplitCount ) + { + if ( nRepS && nLenDiff > 0 ) + nRepS -= nLenDiff; // Inserts wurden mitgezaehlt +#ifdef erTESTSPLIT + printf(" nRepSdiff: %d ", nRepS ); +#endif + if ( (nSPMin <= 2 * nLimit) + && (npDistance[nStringLen] <= 2 * nLimit) + && (nRepS * nRepP0 <= nLimit) ) + return( -npDistance[nStringLen] ); + return(LEVDISBIG); + } + return(LEVDISBIG); + } +} + + + +// Berechnung von nLimit, nReplP0, nInsQ0, nDelR0, bSplitCount +// aus Userwerten nOtherX, nShorterY, nLongerZ, bRelaxed +int WLevDistance::CalcLPQR( int nX, int nY, int nZ, bool bRelaxed ) +{ + int nMin, nMid, nMax; + if ( nX < 0 ) nX = 0; // nur positive Werte + if ( nY < 0 ) nY = 0; + if ( nZ < 0 ) nZ = 0; + if ( 0 == (nMin = Min3( nX, nY, nZ )) ) // mindestens einer 0 + { + nMax = Max3( nX, nY, nZ ); // entweder 0 bei drei 0 oder Max + if ( 0 == (nMid = Mid3( nX, nY, nZ )) ) // sogar zwei 0 + nLimit = nMax; // entweder 0 oder einziger >0 + else // einer 0 + nLimit = KGV( nMid, nMax ); + } + else // alle drei nicht 0 + nLimit = KGV( KGV( nX, nY ), nZ ); + nRepP0 = ( nX ? nLimit / nX : nLimit + 1 ); + nInsQ0 = ( nY ? nLimit / nY : nLimit + 1 ); + nDelR0 = ( nZ ? nLimit / nZ : nLimit + 1 ); + bSplitCount = bRelaxed; + return( nLimit ); +} + + + +// Groesster Gemeinsamer Teiler nach Euklid (Kettendivision) +// Sonderfall: 0 und irgendwas geben 1 +int WLevDistance::GGT( int a, int b ) +{ + if ( !a || !b ) + return 1; + if ( a < 0 ) a = -a; + if ( b < 0 ) b = -b; + do + { + if ( a > b ) + a -= int(a / b) * b; + else + b -= int(b / a) * a; + } while ( a && b ); + return( a ? a : b); +} + + + +// Kleinstes Gemeinsames Vielfaches: a * b / GGT(a,b) +int WLevDistance::KGV( int a, int b ) +{ + if ( a > b ) // Ueberlauf unwahrscheinlicher machen + return( (a / GGT(a,b)) * b ); + else + return( (b / GGT(a,b)) * a ); +} + + +// Minimum von drei Werten +inline int WLevDistance::Min3( int x, int y, int z ) +{ + if ( x < y ) + return( x < z ? x : z ); + else + return( y < z ? y : z ); +} + + + +// mittlerer von drei Werten +int WLevDistance::Mid3( int x, int y, int z ) +{ + int min = Min3(x,y,z); + if ( x == min ) + return( y < z ? y : z); + else if ( y == min ) + return( x < z ? x : z); + else // z == min + return( x < y ? x : y); +} + + + +// Maximum von drei Werten +int WLevDistance::Max3( int x, int y, int z ) +{ + if ( x > y ) + return( x > z ? x : z ); + else + return( y > z ? y : z ); +} + + + +// Daten aus CTor initialisieren +void WLevDistance::InitData( const sal_Unicode* cPattern ) +{ + cpPattern = aPatMem.GetcPtr(); + bpPatIsWild = aPatMem.GetbPtr(); + npDistance = aDisMem.GetPtr(); + nStars = 0; + const sal_Unicode* cp1 = cPattern; + sal_Unicode* cp2 = cpPattern; + bool* bp = bpPatIsWild; + // Pattern kopieren, Sternchen zaehlen, escaped Jokers + while ( *cp1 ) + { + if ( *cp1 == '\\' ) // maybe escaped + { + if ( *(cp1+1) == '*' || *(cp1+1) == '?' ) // naechstes Joker? + { + cp1++; // skip '\\' + nPatternLen--; + } + *bp++ = false; + } + else if ( *cp1 == '*' || *cp1 == '?' ) // Joker + { + if ( *cp1 == '*' ) + nStars++; // Sternchenzaehler erhoehen + *bp++ = true; + } + else + *bp++ = false; + *cp2++ = *cp1++; + } + *cp2 = '\0'; +} + + +// CTor + +#ifdef erTEST + +WLevDistance::WLevDistance( const ::rtl::OUString& rPattern ) : + nPatternLen( rPattern.getLength() ), + aPatMem( nPatternLen + 1 ), + nArrayLen( nPatternLen + 1 ), + aDisMem( nArrayLen ), + nLimit( LEVDISDEFAULTLIMIT ), + nRepP0( LEVDISDEFAULT_P0 ), + nInsQ0( LEVDISDEFAULT_Q0 ), + nDelR0( LEVDISDEFAULT_R0 ), + bSplitCount( false ) +{ + InitData( rPattern.getStr() ); +} + +#endif // erTEST + + +WLevDistance::WLevDistance( const sal_Unicode* cPattern, + int nOtherX, int nShorterY, int nLongerZ, + bool bRelaxed ) : + nPatternLen( Impl_WLD_StringLen(cPattern) ), + aPatMem( nPatternLen + 1 ), + nArrayLen( nPatternLen + 1 ), + aDisMem( nArrayLen ) +{ + InitData( cPattern ); + CalcLPQR( nOtherX, nShorterY, nLongerZ, bRelaxed ); +} + + +// CopyCTor +WLevDistance::WLevDistance( const WLevDistance& rWLD ) : + nPatternLen( rWLD.nPatternLen ), + aPatMem( nPatternLen + 1 ), + nArrayLen( nPatternLen + 1 ), + aDisMem( nArrayLen ), + nLimit( rWLD.nLimit ), + nRepP0( rWLD.nRepP0 ), + nInsQ0( rWLD.nInsQ0 ), + nDelR0( rWLD.nDelR0 ), + nStars( rWLD.nStars ), + bSplitCount( rWLD.bSplitCount ) +{ + cpPattern = aPatMem.GetcPtr(); + bpPatIsWild = aPatMem.GetbPtr(); + npDistance = aDisMem.GetPtr(); + sal_Int32 i; + for ( i=0; i<nPatternLen; i++ ) + { + cpPattern[i] = rWLD.cpPattern[i]; + bpPatIsWild[i] = rWLD.bpPatIsWild[i]; + } + cpPattern[i] = '\0'; +} + + +// DTor +WLevDistance::~WLevDistance() +{ +} + +/************************************************************************* + * Test + *************************************************************************/ + +#ifdef erTEST + +#define LINESIZE 1000 +typedef char MAXSTRING [LINESIZE+1]; + +#ifdef erTESTMAT + +void WLevDistance::ShowMatrix( const sal_Unicode* cString ) +{ + sal_Int32 r, c, l = Impl_WLD_StringLen(cString); + printf(" | "); + for ( c=0; c<nPatternLen; c++ ) +#error Error: conversion from sal_Unicode to char needed! + printf( " %c ", cpPattern[c] ); + printf("\n---+---"); + for ( c=0; c<nPatternLen; c++ ) + printf( "---" ); + for ( r=0; r<=l && r < erTESTMATMAX; r++ ) + { +#error Error: conversion from sal_Unicode to char needed! + printf( "\n %c |", ( r==0 ? ' ' : cString[r-1] ) ); + for ( c=0; c<=nPatternLen && c < erTESTMATMAX; c++ ) + printf( "%2d ", npMatrix[r][c] ); + } + printf("\n\n"); +} + +#endif // erTESTMAT + +// Delimiter fuer Token, \t Tab bleibt fuer immer an der ersten Stelle +MAXSTRING cDelim = "\t, ;(){}[]<>&=+-/%!|.\\'\"~"; + +void WLevDistance::ShowTest() +{ + printf(" \n"); +#error Error: conversion from sal_Unicode to char needed! + printf(" a *cpPattern . . . . : %s\n", cpPattern); + printf(" b *bpPatIsWild . . . : "); + for ( sal_Int32 i=0; i<nPatternLen; i++ ) + printf("%d", bpPatIsWild[i]); + printf("\n"); + printf(" c nPatternLen . . . : %d\n", (int)nPatternLen); + printf(" d nStars . . . . . . : %d\n", nStars); + printf(" e nLimit . . . . . . : %d\n", nLimit); + printf(" f nRepP0 (Ersetzen) : %d\n", nRepP0); + printf(" g nInsQ0 (Einfuegen) : %d\n", nInsQ0); + printf(" h nDelR0 (Loeschen) : %d\n", nDelR0); + printf(" i bSplitCount . . . : %d\n", bSplitCount); +#error Error: conversion from sal_Unicode to char needed! + printf(" j cDelim . . . . . . : '%s'\n", cDelim); + printf(" ~\n"); +} + +inline bool IsDelim( char c ) +{ + char* cp = cDelim; + while ( *cp ) + if ( *cp++ == c ) + return( true ); + return( false ); +} + +MAXSTRING cString, cLine, cIgString; + +int main( int argc, char **argv ) +{ + int nLim, nP0, nQ0, nR0, nX, nY, nZ; + int args = 0; + bool IgnoreCase = false, Direct = false, bStrict = false; + WLevDistance* pTest; + if ( argc < 2 ) + { + printf("%s Syntax:\n" + " ... [-i] cPattern [nOtherX, nShorterY, nLongerZ [bStrict [cDelim]]] [<stdin] [>stdout]\n" + " ... -d cPattern [nLimit [nRepP0 nInsQ0 nDelR0 [cDelim]]] [<stdin] [>stdout]\n" + , argv[0]); + exit(1); + } + if ( *argv[1] == '-' ) + { + args++; + argc--; + switch ( *(argv[1]+1) ) + { + case 'i': + { + IgnoreCase = true; + char* cp = argv[args+1]; + while ( (*cp = tolower( *cp )) != 0 ) + cp++; + break; + } + case 'd': + Direct = true; + break; + } + } + if ( Direct ) + { + if ( argc > 2 ) + nLim = atoi(argv[args+2]); + else + nLim = LEVDISDEFAULTLIMIT; + if ( argc > 3 ) + { + nP0 = atoi(argv[args+3]); + nQ0 = atoi(argv[args+4]); + nR0 = atoi(argv[args+5]); + } + else + { + nP0 = LEVDISDEFAULT_P0; + nQ0 = LEVDISDEFAULT_Q0; + nR0 = LEVDISDEFAULT_R0; + } + if ( argc > 6 ) + { + strncpy( cDelim+1, argv[args+6], LINESIZE ); // \t Tab always remains + cDelim[LINESIZE-1] = 0; + } + } + else + { + if ( argc > 2 ) + { + nX = atoi(argv[args+2]); + nY = atoi(argv[args+3]); + nZ = atoi(argv[args+4]); + } + else + { + nX = LEVDISDEFAULT_XOTHER; + nY = LEVDISDEFAULT_YSHORTER; + nZ = LEVDISDEFAULT_ZLONGER; + } + if ( argc > 5 ) + bStrict = atoi(argv[args+5]); + if ( argc > 6 ) + { + strncpy( cDelim+1, argv[args+6], LINESIZE ); // \t Tab always remains + cDelim[LINESIZE-1] = 0; + } + } + if ( Direct ) + { +#error Error: conversion from char to OUString needed! + pTest = new WLevDistance( argv[args+1] ); +#ifdef erTESTDEFAULT + pTest->ShowTest(); +#endif + pTest->SetLimit( nLim ); + pTest->SetReplaceP0( nP0 ); + pTest->SetInsertQ0( nQ0 ); + pTest->SetDeleteR0( nR0 ); + } + else + { +#error Error: conversion from char to sal_Unicode needed! + pTest = new WLevDistance( argv[args+1], nX, nY, nZ, !bStrict ); +#ifdef erTESTCCTOR + WLevDistance aTmp( *pTest ); + aTmp.ShowTest(); +#endif + nLim = pTest->GetLimit(); + } + pTest->ShowTest(); + do + { + char* cp1, *cp2; + static long unsigned int nLine = 0; + cp1 = cLine; + cin.getline( cLine, LINESIZE ) ; + nLine++; + while ( *cp1 ) + { + while ( *cp1 && IsDelim(*cp1) ) + cp1++; + cp2 = cString; + while ( *cp1 && !IsDelim(*cp1) ) + *cp2++ = *cp1++; + *cp2 = '\0'; + while ( *cp1 && IsDelim(*cp1) ) + cp1++; + if ( *cString ) + { + int ret; + if ( IgnoreCase ) + { + char* cpi1 = cString; + char* cpi2 = cIgString; + while ( *cpi1 ) + *cpi2++ = tolower( *cpi1++ ); + *cpi2 = '\0'; +#error Error: conversion from char to OUString / sal_Unicode,length needed! + ret = pTest->WLD( cIgString ); + } + else +#error Error: conversion from char to OUString / sal_Unicode,length needed! + ret = pTest->WLD( cString ); +#ifdef erTESTMAT + printf("\n# %3d : %s\n", ret, cString); +#error Error: conversion from char to sal_Unicode needed! + pTest->ShowMatrix( cString ); +#else + if ( ret <= nLim ) + printf("# %3d : %s\t(line %lu)\t%s\n", ret, cString, nLine, cLine); +#endif + } + } + } while ( !cin.eof() ); + return 0; +} + +#endif // erTEST + |