merge the formfield patch from ooo-build
[ooovba.git] / i18npool / source / search / levdis.cxx
blobf1362bd9e2222bdf45b3fd94e7e375a56daca6bb
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: levdis.cxx,v $
10 * $Revision: 1.6.24.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_i18npool.hxx"
33 /*************************************************************************
35 Weighted Levenshtein Distance
36 including wildcards
37 '*' for any number (0 or more) of arbitrary characters
38 '?' for exactly one arbitrary character
39 escapeable with backslash, "\*" or "\?"
41 Return:
42 WLD if WLD <= nLimit, else nLimit+1
44 or, if bSplitCount:
45 WLD if WLD <= nLimit
46 -WLD if Replace and Insert and Delete <= nLimit
47 else nLimit+1
49 Recursive definition of WLD:
51 WLD( X(i), Y(j) ) = min( WLD( X(i-1), Y(j-1) ) + p(i,j) ,
52 WLD( X(i) , Y(j-1) ) + q ,
53 WLD( X(i-1), Y(j) ) + r )
55 X(i) := the first i characters of the word X
56 Y(j) := the first j characters of the word Y
57 p(i,j) := 0 if i-th character of X == j-th character of Y,
58 p else
60 Boundary conditions:
61 WLD( X(0), Y(j) ) := j*q (Y created by j inserts)
62 WLD( X(i), Y(0) ) := i*r (Y created by i deletes)
63 WLD( X(0), Y(0) ) := 0
65 Instead of recursions a dynamic algorithm is used.
67 See also: German computer magazine
68 c't 07/89 pages 192-208 and c't 03/94 pages 230-239
70 *************************************************************************/
73 #include <string.h> // strlen()
75 #if defined( _MSC_VER )
76 #pragma warning(once: 4068)
77 #endif
79 #include "levdis.hxx"
82 #ifdef erTEST
83 #include <stdlib.h>
84 #include <stdio.h>
85 #include <iostream.h>
86 #endif
88 #ifdef SOLARIS
89 #undef min
90 #endif
92 #define LEVDISBIG (nLimit + 1) // Returnwert wenn Distanz > nLimit
93 #define LEVDISDOUBLEBUF 2048 // dadrueber wird nicht mehr gedoppelt
95 // Balance, aus Geschwindigkeitsgruenden ist dieses keine Funktion
96 // c == cpPattern[jj] == cString[ii]
97 // erst wird bis Fundstelle gesucht, wenn dort die Balance gleich ist, wird
98 // auch nach der Fundstelle verglichen
99 #define LEVDISBALANCE(jj,ii) \
101 if ( jj != ii ) \
103 register sal_Int32 k; \
104 if ( jj > 0 ) \
105 for ( k=0; k < jj; k++ ) \
106 if ( cpPattern[k] == c ) \
107 nBalance++; \
108 if ( ii > 0 ) \
109 for ( k=0; k < ii; k++ ) \
110 if ( cString[k] == c ) \
111 nBalance--; \
112 if ( !nBalance ) \
114 for ( k=jj+1; k < nPatternLen; k++ ) \
115 if ( cpPattern[k] == c ) \
116 nBalance++; \
117 for ( k=ii+1; k < nStringLen; k++ ) \
118 if ( cString[k] == c ) \
119 nBalance--; \
124 static sal_Int32 Impl_WLD_StringLen( const sal_Unicode* pStr )
126 const sal_Unicode* pTempStr = pStr;
127 while( *pTempStr )
128 pTempStr++;
129 return (sal_Int32)(pTempStr-pStr);
132 #ifdef erTESTMAT
133 #define erTESTMATMAX 180
134 static int npMatrix[erTESTMATMAX][erTESTMATMAX]; // nearly 64K
135 #endif
137 // Distanz von String zu Pattern
138 int WLevDistance::WLD( const sal_Unicode* cString, sal_Int32 nStringLen )
140 int nSPMin = 0; // StrafPunkteMinimum
141 int nRepS = 0; // fuer SplitCount
143 #ifdef erTESTMAT
145 for ( sal_Int32 r=0; r<=nStringLen && r < erTESTMATMAX; r++ )
146 for ( sal_Int32 c=0; c<=nPatternLen && c < erTESTMATMAX; c++ )
147 npMatrix[r][c] = 99; // Matrix initialisieren, nur visuell
149 #endif
151 // Laengendifferenz von Pattern und String
152 int nLenDiff = nPatternLen - nStars - nStringLen;
153 // mehr Einfuegungen oder Loeschungen noetig als Limit? => raus hier
154 if ( (nLenDiff * nInsQ0 > nLimit)
155 || ((nStars == 0) && (nLenDiff * nDelR0 < -nLimit)) )
156 return(LEVDISBIG);
158 // wenn der zu vergleichende String groesser ist als das bisherige Array
159 // muss dieses angepasst werden
160 if ( nStringLen >= nArrayLen )
162 // gib ihm moeglichst mehr, damit nicht gleich naechstesmal
163 // wieder realloziert werden muss
164 if ( nStringLen < LEVDISDOUBLEBUF )
165 nArrayLen = 2 * nStringLen;
166 else
167 nArrayLen = nStringLen + 1;
168 npDistance = aDisMem.NewMem( nArrayLen );
169 #ifdef erTEST
170 if ( !npDistance )
172 cerr << "DOOM! (Damned, Out Of Memory)" << endl;
173 exit(1);
175 #endif
178 // Anfangswerte der zweiten Spalte (erstes Pattern-Zeichen) berechnen
179 // die erste Spalte (0-Len Pattern) ist immer 0 .. nStringLen * nInsQ0,
180 // deren Minimum also 0
181 if ( nPatternLen == 0 )
183 // Anzahl der Loeschungen, um auf Pattern zu kommen
184 for ( sal_Int32 i=0; i <= nStringLen; i++ )
185 npDistance[i] = i * nDelR0;
187 else if ( cpPattern[0] == '*' && bpPatIsWild[0] )
189 // statt einem '*' ist alles einsetzbar
190 for ( sal_Int32 i=0; i <= nStringLen; i++ )
191 npDistance[i] = 0;
193 else
195 sal_Unicode c;
196 int nP;
197 c = cpPattern[0];
198 if ( c == '?' && bpPatIsWild[0] )
199 nP = 0; // ein '?' kann jedes Zeichen sein
200 else
201 // Minimum von Ersetzen und Loeschen+Einfuegen Gewichtung
202 nP = Min3( nRepP0, nRepP0, nDelR0 + nInsQ0 );
203 npDistance[0] = nInsQ0; // mit einfachem Einfuegen geht's los
204 npDistance[1] = nInsQ0;
205 npDistance[2] = nInsQ0;
206 int nReplacePos = -1; // tristate Flag
207 int nDelCnt = 0;
208 for ( sal_Int32 i=1; i <= nStringLen; i++, nDelCnt += nDelR0 )
210 if ( cString[i-1] == c )
211 nP = 0; // Replace ab dieser Stelle ist 0
212 // Loeschungen um auf Pattern zu kommen + Replace
213 npDistance[i] = nDelCnt + nP;
214 if ( bSplitCount )
216 if ( nReplacePos < 0 && nP )
217 { // diese Stelle wird ersetzt
218 nRepS++;
219 nReplacePos = i;
220 #ifdef erTESTMAT
221 npMatrix[i][1] = -npDistance[i];
222 #endif
224 else if ( nReplacePos > 0 && !nP )
226 int nBalance = 0; // gleiche Anzahl c
227 LEVDISBALANCE( 0, i-1 );
228 if ( !nBalance )
229 { // einer wurde ersetzt, der ein Insert war
230 nRepS--;
231 #ifdef erTESTMAT
232 npMatrix[nReplacePos][1] = npDistance[nReplacePos];
233 #endif
234 nReplacePos = 0;
239 nSPMin = Min3( npDistance[0], npDistance[1], npDistance[2] );
241 #ifdef erTESTMAT
243 for ( sal_Int32 r=0; r<=nStringLen && r < erTESTMATMAX; r++ )
245 npMatrix[r][0] = r * nInsQ0;
246 if ( npMatrix[r][1] >= 0)
247 npMatrix[r][1] = npDistance[r];
250 #endif
252 // Distanzmatrix berechnen
253 sal_Int32 j = 0; // fuer alle Spalten des Pattern, solange nicht Limit
254 while ( (j < nPatternLen-1)
255 && nSPMin <= (bSplitCount ? 2 * nLimit : nLimit) )
257 sal_Unicode c;
258 int nP, nQ, nR, nPij, d1, d2;
260 j++;
261 c = cpPattern[j];
262 if ( bpPatIsWild[j] ) // '*' oder '?' nicht escaped
263 nP = 0; // kann ohne Strafpunkte ersetzt werden
264 else
265 nP = nRepP0;
266 if ( c == '*' && bpPatIsWild[j] )
268 nQ = 0; // Einfuegen und Loeschen ohne Strafpunkte
269 nR = 0;
271 else
273 nQ = nInsQ0; // normale Gewichtung
274 nR = nDelR0;
276 d2 = npDistance[0];
277 // Anzahl Einfuegungen um von Null-String auf Pattern zu kommen erhoehen
278 npDistance[0] = npDistance[0] + nQ;
279 nSPMin = npDistance[0];
280 int nReplacePos = -1; // tristate Flag
281 // fuer jede Patternspalte den String durchgehen
282 for ( register sal_Int32 i=1; i <= nStringLen; i++ )
284 d1 = d2; // WLD( X(i-1), Y(j-1) )
285 d2 = npDistance[i]; // WLD( X(i) , Y(j-1) )
286 if ( cString[i-1] == c )
288 nPij = 0; // p(i,j)
289 if ( nReplacePos < 0 )
291 int nBalance = 0; // gleiche Anzahl c
292 LEVDISBALANCE( j, i-1 );
293 if ( !nBalance )
294 nReplacePos = 0; // keine Ersetzung mehr
297 else
298 nPij = nP;
299 // WLD( X(i), Y(j) ) = min( WLD( X(i-1), Y(j-1) ) + p(i,j) ,
300 // WLD( X(i) , Y(j-1) ) + q ,
301 // WLD( X(i-1), Y(j) ) + r )
302 npDistance[i] = Min3( d1 + nPij, d2 + nQ, npDistance[i-1] + nR );
303 if ( npDistance[i] < nSPMin )
304 nSPMin = npDistance[i];
305 if ( bSplitCount )
307 if ( nReplacePos < 0 && nPij && npDistance[i] == d1 + nPij )
308 { // diese Stelle wird ersetzt
309 nRepS++;
310 nReplacePos = i;
311 #ifdef erTESTMAT
312 npMatrix[i][j+1] = -npDistance[i];
313 #endif
315 else if ( nReplacePos > 0 && !nPij )
316 { // Zeichen in String und Pattern gleich.
317 // wenn ab hier die gleiche Anzahl dieses Zeichens
318 // sowohl in Pattern als auch in String ist, und vor
319 // dieser Stelle das Zeichen gleich oft vorkommt, war das
320 // Replace keins. Buchstabendreher werden hier erfasst
321 // und der ReplaceS zurueckgenommen, wodurch das doppelte
322 // Limit zum Tragen kommt.
323 int nBalance = 0; // gleiche Anzahl c
324 LEVDISBALANCE( j, i-1 );
325 if ( !nBalance )
326 { // einer wurde ersetzt, der ein Insert war
327 nRepS--;
328 #ifdef erTESTMAT
329 npMatrix[nReplacePos][j+1] = npDistance[nReplacePos];
330 #endif
331 nReplacePos = 0;
336 #ifdef erTESTMAT
338 for ( sal_Int32 r=0; r<=nStringLen && r < erTESTMATMAX; r++ )
339 if ( npMatrix[r][j+1] >= 0)
340 npMatrix[r][j+1] = npDistance[r];
342 #endif
344 #ifdef erTESTSPLIT
345 printf(" nRepS: %d ", nRepS );
346 #endif
347 if ( (nSPMin <= nLimit) && (npDistance[nStringLen] <= nLimit) )
348 return(npDistance[nStringLen]);
349 else
351 if ( bSplitCount )
353 if ( nRepS && nLenDiff > 0 )
354 nRepS -= nLenDiff; // Inserts wurden mitgezaehlt
355 #ifdef erTESTSPLIT
356 printf(" nRepSdiff: %d ", nRepS );
357 #endif
358 if ( (nSPMin <= 2 * nLimit)
359 && (npDistance[nStringLen] <= 2 * nLimit)
360 && (nRepS * nRepP0 <= nLimit) )
361 return( -npDistance[nStringLen] );
362 return(LEVDISBIG);
364 return(LEVDISBIG);
370 // Berechnung von nLimit, nReplP0, nInsQ0, nDelR0, bSplitCount
371 // aus Userwerten nOtherX, nShorterY, nLongerZ, bRelaxed
372 int WLevDistance::CalcLPQR( int nX, int nY, int nZ, bool bRelaxed )
374 int nMin, nMid, nMax;
375 if ( nX < 0 ) nX = 0; // nur positive Werte
376 if ( nY < 0 ) nY = 0;
377 if ( nZ < 0 ) nZ = 0;
378 if ( 0 == (nMin = Min3( nX, nY, nZ )) ) // mindestens einer 0
380 nMax = Max3( nX, nY, nZ ); // entweder 0 bei drei 0 oder Max
381 if ( 0 == (nMid = Mid3( nX, nY, nZ )) ) // sogar zwei 0
382 nLimit = nMax; // entweder 0 oder einziger >0
383 else // einer 0
384 nLimit = KGV( nMid, nMax );
386 else // alle drei nicht 0
387 nLimit = KGV( KGV( nX, nY ), nZ );
388 nRepP0 = ( nX ? nLimit / nX : nLimit + 1 );
389 nInsQ0 = ( nY ? nLimit / nY : nLimit + 1 );
390 nDelR0 = ( nZ ? nLimit / nZ : nLimit + 1 );
391 bSplitCount = bRelaxed;
392 return( nLimit );
397 // Groesster Gemeinsamer Teiler nach Euklid (Kettendivision)
398 // Sonderfall: 0 und irgendwas geben 1
399 int WLevDistance::GGT( int a, int b )
401 if ( !a || !b )
402 return 1;
403 if ( a < 0 ) a = -a;
404 if ( b < 0 ) b = -b;
407 if ( a > b )
408 a -= int(a / b) * b;
409 else
410 b -= int(b / a) * a;
411 } while ( a && b );
412 return( a ? a : b);
417 // Kleinstes Gemeinsames Vielfaches: a * b / GGT(a,b)
418 int WLevDistance::KGV( int a, int b )
420 if ( a > b ) // Ueberlauf unwahrscheinlicher machen
421 return( (a / GGT(a,b)) * b );
422 else
423 return( (b / GGT(a,b)) * a );
427 // Minimum von drei Werten
428 inline int WLevDistance::Min3( int x, int y, int z )
430 if ( x < y )
431 return( x < z ? x : z );
432 else
433 return( y < z ? y : z );
438 // mittlerer von drei Werten
439 int WLevDistance::Mid3( int x, int y, int z )
441 int min = Min3(x,y,z);
442 if ( x == min )
443 return( y < z ? y : z);
444 else if ( y == min )
445 return( x < z ? x : z);
446 else // z == min
447 return( x < y ? x : y);
452 // Maximum von drei Werten
453 int WLevDistance::Max3( int x, int y, int z )
455 if ( x > y )
456 return( x > z ? x : z );
457 else
458 return( y > z ? y : z );
463 // Daten aus CTor initialisieren
464 void WLevDistance::InitData( const sal_Unicode* cPattern )
466 cpPattern = aPatMem.GetcPtr();
467 bpPatIsWild = aPatMem.GetbPtr();
468 npDistance = aDisMem.GetPtr();
469 nStars = 0;
470 const sal_Unicode* cp1 = cPattern;
471 sal_Unicode* cp2 = cpPattern;
472 bool* bp = bpPatIsWild;
473 // Pattern kopieren, Sternchen zaehlen, escaped Jokers
474 while ( *cp1 )
476 if ( *cp1 == '\\' ) // maybe escaped
478 if ( *(cp1+1) == '*' || *(cp1+1) == '?' ) // naechstes Joker?
480 cp1++; // skip '\\'
481 nPatternLen--;
483 *bp++ = false;
485 else if ( *cp1 == '*' || *cp1 == '?' ) // Joker
487 if ( *cp1 == '*' )
488 nStars++; // Sternchenzaehler erhoehen
489 *bp++ = true;
491 else
492 *bp++ = false;
493 *cp2++ = *cp1++;
495 *cp2 = '\0';
499 // CTor
501 #ifdef erTEST
503 WLevDistance::WLevDistance( const ::rtl::OUString& rPattern ) :
504 nPatternLen( rPattern.getLength() ),
505 aPatMem( nPatternLen + 1 ),
506 nArrayLen( nPatternLen + 1 ),
507 aDisMem( nArrayLen ),
508 nLimit( LEVDISDEFAULTLIMIT ),
509 nRepP0( LEVDISDEFAULT_P0 ),
510 nInsQ0( LEVDISDEFAULT_Q0 ),
511 nDelR0( LEVDISDEFAULT_R0 ),
512 bSplitCount( false )
514 InitData( rPattern.getStr() );
517 #endif // erTEST
520 WLevDistance::WLevDistance( const sal_Unicode* cPattern,
521 int nOtherX, int nShorterY, int nLongerZ,
522 bool bRelaxed ) :
523 nPatternLen( Impl_WLD_StringLen(cPattern) ),
524 aPatMem( nPatternLen + 1 ),
525 nArrayLen( nPatternLen + 1 ),
526 aDisMem( nArrayLen )
528 InitData( cPattern );
529 CalcLPQR( nOtherX, nShorterY, nLongerZ, bRelaxed );
533 // CopyCTor
534 WLevDistance::WLevDistance( const WLevDistance& rWLD ) :
535 nPatternLen( rWLD.nPatternLen ),
536 aPatMem( nPatternLen + 1 ),
537 nArrayLen( nPatternLen + 1 ),
538 aDisMem( nArrayLen ),
539 nLimit( rWLD.nLimit ),
540 nRepP0( rWLD.nRepP0 ),
541 nInsQ0( rWLD.nInsQ0 ),
542 nDelR0( rWLD.nDelR0 ),
543 nStars( rWLD.nStars ),
544 bSplitCount( rWLD.bSplitCount )
546 cpPattern = aPatMem.GetcPtr();
547 bpPatIsWild = aPatMem.GetbPtr();
548 npDistance = aDisMem.GetPtr();
549 sal_Int32 i;
550 for ( i=0; i<nPatternLen; i++ )
552 cpPattern[i] = rWLD.cpPattern[i];
553 bpPatIsWild[i] = rWLD.bpPatIsWild[i];
555 cpPattern[i] = '\0';
559 // DTor
560 WLevDistance::~WLevDistance()
564 /*************************************************************************
565 * Test
566 *************************************************************************/
568 #ifdef erTEST
570 #define LINESIZE 1000
571 typedef char MAXSTRING [LINESIZE+1];
573 #ifdef erTESTMAT
575 void WLevDistance::ShowMatrix( const sal_Unicode* cString )
577 sal_Int32 r, c, l = Impl_WLD_StringLen(cString);
578 printf(" | ");
579 for ( c=0; c<nPatternLen; c++ )
580 #error Error: conversion from sal_Unicode to char needed!
581 printf( " %c ", cpPattern[c] );
582 printf("\n---+---");
583 for ( c=0; c<nPatternLen; c++ )
584 printf( "---" );
585 for ( r=0; r<=l && r < erTESTMATMAX; r++ )
587 #error Error: conversion from sal_Unicode to char needed!
588 printf( "\n %c |", ( r==0 ? ' ' : cString[r-1] ) );
589 for ( c=0; c<=nPatternLen && c < erTESTMATMAX; c++ )
590 printf( "%2d ", npMatrix[r][c] );
592 printf("\n\n");
595 #endif // erTESTMAT
597 // Delimiter fuer Token, \t Tab bleibt fuer immer an der ersten Stelle
598 MAXSTRING cDelim = "\t, ;(){}[]<>&=+-/%!|.\\'\"~";
600 void WLevDistance::ShowTest()
602 printf(" \n");
603 #error Error: conversion from sal_Unicode to char needed!
604 printf(" a *cpPattern . . . . : %s\n", cpPattern);
605 printf(" b *bpPatIsWild . . . : ");
606 for ( sal_Int32 i=0; i<nPatternLen; i++ )
607 printf("%d", bpPatIsWild[i]);
608 printf("\n");
609 printf(" c nPatternLen . . . : %d\n", (int)nPatternLen);
610 printf(" d nStars . . . . . . : %d\n", nStars);
611 printf(" e nLimit . . . . . . : %d\n", nLimit);
612 printf(" f nRepP0 (Ersetzen) : %d\n", nRepP0);
613 printf(" g nInsQ0 (Einfuegen) : %d\n", nInsQ0);
614 printf(" h nDelR0 (Loeschen) : %d\n", nDelR0);
615 printf(" i bSplitCount . . . : %d\n", bSplitCount);
616 #error Error: conversion from sal_Unicode to char needed!
617 printf(" j cDelim . . . . . . : '%s'\n", cDelim);
618 printf(" ~\n");
621 inline bool IsDelim( char c )
623 char* cp = cDelim;
624 while ( *cp )
625 if ( *cp++ == c )
626 return( true );
627 return( false );
630 MAXSTRING cString, cLine, cIgString;
632 int main( int argc, char **argv )
634 int nLim, nP0, nQ0, nR0, nX, nY, nZ;
635 int args = 0;
636 bool IgnoreCase = false, Direct = false, bStrict = false;
637 WLevDistance* pTest;
638 if ( argc < 2 )
640 printf("%s Syntax:\n"
641 " ... [-i] cPattern [nOtherX, nShorterY, nLongerZ [bStrict [cDelim]]] [<stdin] [>stdout]\n"
642 " ... -d cPattern [nLimit [nRepP0 nInsQ0 nDelR0 [cDelim]]] [<stdin] [>stdout]\n"
643 , argv[0]);
644 exit(1);
646 if ( *argv[1] == '-' )
648 args++;
649 argc--;
650 switch ( *(argv[1]+1) )
652 case 'i':
654 IgnoreCase = true;
655 char* cp = argv[args+1];
656 while ( (*cp = tolower( *cp )) != 0 )
657 cp++;
658 break;
660 case 'd':
661 Direct = true;
662 break;
665 if ( Direct )
667 if ( argc > 2 )
668 nLim = atoi(argv[args+2]);
669 else
670 nLim = LEVDISDEFAULTLIMIT;
671 if ( argc > 3 )
673 nP0 = atoi(argv[args+3]);
674 nQ0 = atoi(argv[args+4]);
675 nR0 = atoi(argv[args+5]);
677 else
679 nP0 = LEVDISDEFAULT_P0;
680 nQ0 = LEVDISDEFAULT_Q0;
681 nR0 = LEVDISDEFAULT_R0;
683 if ( argc > 6 )
685 strncpy( cDelim+1, argv[args+6], LINESIZE ); // \t Tab always remains
686 cDelim[LINESIZE-1] = 0;
689 else
691 if ( argc > 2 )
693 nX = atoi(argv[args+2]);
694 nY = atoi(argv[args+3]);
695 nZ = atoi(argv[args+4]);
697 else
699 nX = LEVDISDEFAULT_XOTHER;
700 nY = LEVDISDEFAULT_YSHORTER;
701 nZ = LEVDISDEFAULT_ZLONGER;
703 if ( argc > 5 )
704 bStrict = atoi(argv[args+5]);
705 if ( argc > 6 )
707 strncpy( cDelim+1, argv[args+6], LINESIZE ); // \t Tab always remains
708 cDelim[LINESIZE-1] = 0;
711 if ( Direct )
713 #error Error: conversion from char to OUString needed!
714 pTest = new WLevDistance( argv[args+1] );
715 #ifdef erTESTDEFAULT
716 pTest->ShowTest();
717 #endif
718 pTest->SetLimit( nLim );
719 pTest->SetReplaceP0( nP0 );
720 pTest->SetInsertQ0( nQ0 );
721 pTest->SetDeleteR0( nR0 );
723 else
725 #error Error: conversion from char to sal_Unicode needed!
726 pTest = new WLevDistance( argv[args+1], nX, nY, nZ, !bStrict );
727 #ifdef erTESTCCTOR
728 WLevDistance aTmp( *pTest );
729 aTmp.ShowTest();
730 #endif
731 nLim = pTest->GetLimit();
733 pTest->ShowTest();
736 char* cp1, *cp2;
737 static long unsigned int nLine = 0;
738 cp1 = cLine;
739 cin.getline( cLine, LINESIZE ) ;
740 nLine++;
741 while ( *cp1 )
743 while ( *cp1 && IsDelim(*cp1) )
744 cp1++;
745 cp2 = cString;
746 while ( *cp1 && !IsDelim(*cp1) )
747 *cp2++ = *cp1++;
748 *cp2 = '\0';
749 while ( *cp1 && IsDelim(*cp1) )
750 cp1++;
751 if ( *cString )
753 int ret;
754 if ( IgnoreCase )
756 char* cpi1 = cString;
757 char* cpi2 = cIgString;
758 while ( *cpi1 )
759 *cpi2++ = tolower( *cpi1++ );
760 *cpi2 = '\0';
761 #error Error: conversion from char to OUString / sal_Unicode,length needed!
762 ret = pTest->WLD( cIgString );
764 else
765 #error Error: conversion from char to OUString / sal_Unicode,length needed!
766 ret = pTest->WLD( cString );
767 #ifdef erTESTMAT
768 printf("\n# %3d : %s\n", ret, cString);
769 #error Error: conversion from char to sal_Unicode needed!
770 pTest->ShowMatrix( cString );
771 #else
772 if ( ret <= nLim )
773 printf("# %3d : %s\t(line %lu)\t%s\n", ret, cString, nLine, cLine);
774 #endif
777 } while ( !cin.eof() );
778 return 0;
781 #endif // erTEST