Files
harbour-core/harbour/source/rtl/strtran.c
2000-03-21 11:51:27 +00:00

198 lines
6.1 KiB
C

/*
* $Id$
*/
/*
* Harbour Project source code:
* STRTRAN function
*
* Copyright 1999 Antonio Linares <alinares@fivetech.com>
* www - http://www.harbour-project.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version, with one exception:
*
* The exception is that if you link the Harbour Runtime Library (HRL)
* and/or the Harbour Virtual Machine (HVM) with other files to produce
* an executable, this does not by itself cause the resulting executable
* to be covered by the GNU General Public License. Your use of that
* executable is in no way restricted on account of linking the HRL
* and/or HVM code into it.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA (or visit
* their web site at http://www.gnu.org/).
*
*/
#include "hbapi.h"
#include "hbapiitm.h"
#include "hbapierr.h"
/* TOFIX: Check for string overflow, Clipper can crash if the resulting
string is too large. Example:
StrTran( "...", ".", Replicate( "A", 32000 ) ) [vszakats] */
/* replaces lots of characters in a string */
/* TOFIX: Will not work with a search string of > 64 KB on some platforms */
HB_FUNC( STRTRAN )
{
PHB_ITEM pText = hb_param( 1, IT_STRING );
if( pText )
{
PHB_ITEM pSeek = hb_param( 2, IT_STRING );
if( pSeek )
{
char * szText = hb_itemGetCPtr( pText );
ULONG ulText = hb_itemGetCLen( pText );
ULONG ulSeek = hb_itemGetCLen( pSeek );
if( ulSeek && ulSeek <= ulText )
{
char * szSeek = hb_itemGetCPtr( pSeek );
char * szReplace;
ULONG ulStart;
ulStart = ( ISNUM( 4 ) ? hb_parnl( 4 ) : 1 );
if( !ulStart )
{
/* Clipper seems to work this way */
hb_retc( "" );
}
else if( ulStart > 0 )
{
PHB_ITEM pReplace = hb_param( 3, IT_STRING );
ULONG ulReplace;
ULONG ulCount;
BOOL bAll;
if( pReplace )
{
szReplace = hb_itemGetCPtr( pReplace );
ulReplace = hb_itemGetCLen( pReplace );
}
else
{
szReplace = ""; /* shouldn't matter that we don't allocate */
ulReplace = 0;
}
if( ISNUM( 5 ) )
{
ulCount = hb_parnl( 5 );
bAll = FALSE;
}
else
{
ulCount = 0;
bAll = TRUE;
}
if( bAll || ulCount > 0 )
{
ULONG ulFound = 0;
long lReplaced = 0;
ULONG i = 0;
ULONG ulLength = ulText;
while( i < ulText )
{
if( ( bAll || lReplaced < ( long ) ulCount ) && ! memcmp( szText + i, szSeek, ulSeek ) )
{
ulFound++;
if( ulFound >= ulStart )
{
lReplaced++;
ulLength = ulLength - ulSeek + ulReplace;
i += ulSeek;
}
else
i++;
}
else
i++;
}
if( ulFound )
{
char * szResult = ( char * ) hb_xgrab( ulLength + 1 );
char * szPtr = szResult;
ulFound = 0;
i = 0;
while( i < ulText )
{
if( lReplaced && ! memcmp( szText + i, szSeek, ulSeek ) )
{
ulFound++;
if( ulFound >= ulStart )
{
lReplaced--;
memcpy( szPtr, szReplace, ulReplace );
szPtr += ulReplace;
i += ulSeek;
}
else
{
*szPtr = szText[ i ];
szPtr++;
i++;
}
}
else
{
*szPtr = szText[ i ];
szPtr++;
i++;
}
}
hb_retclen( szResult, ulLength );
hb_xfree( szResult );
}
else
hb_retclen( szText, ulText );
}
else
hb_retclen( szText, ulText );
}
else
hb_retclen( szText, ulText );
}
else
hb_retclen( szText, ulText );
}
else
{
PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1126, NULL, "STRTRAN" ); /* NOTE: Undocumented but existing Clipper Run-time error [vszakats] */
if( pResult )
{
hb_itemReturn( pResult );
hb_itemRelease( pResult );
}
}
}
else
{
PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1126, NULL, "STRTRAN" ); /* NOTE: Undocumented but existing Clipper Run-time error [vszakats] */
if( pResult )
{
hb_itemReturn( pResult );
hb_itemRelease( pResult );
}
}
}