* harbour/bin/hb-func.sh
* harbour/bin/hb-mkslib.sh
* harbour/bin/postinst.sh
* harbour/config/bsd/gcc.cf
* harbour/config/darwin/gcc.cf
* harbour/config/dos/owatcom.cf
* harbour/config/hpux/gcc.cf
* harbour/config/linux/gcc.cf
* harbour/config/linux/owatcom.cf
* harbour/config/os2/gcc.cf
* harbour/config/sunos/gcc.cf
* harbour/config/w32/watcom.cf
* harbour/contrib/rdd_ads/ads1.c
* harbour/contrib/rdd_ads/adsfunc.c
* harbour/include/hbapifs.h
* harbour/include/hbexprc.c
* harbour/include/hbsetup.h
* harbour/source/common/expropt2.c
* harbour/source/common/hbdate.c
* harbour/source/common/hbgete.c
* harbour/source/common/hbstr.c
* harbour/source/common/hbver.c
* harbour/source/common/hbverdsp.c
* harbour/source/compiler/cmdcheck.c
* harbour/source/compiler/fixflex.c
* harbour/source/compiler/gencobj.c
* harbour/source/compiler/genobj32.c
* harbour/source/compiler/harbour.c
* harbour/source/compiler/harbour.l
* harbour/source/compiler/harbour.y
* harbour/source/compiler/harbour.yyc
* harbour/source/compiler/hbfix.c
* harbour/source/compiler/hbfunchk.c
* harbour/source/pp/ppcore.c
* harbour/source/pp/ppgen.c
* harbour/source/pp/pplib.c
* harbour/source/rdd/dbcmd.c
* harbour/source/rdd/workarea.c
* harbour/source/rdd/dbfcdx/dbfcdx1.c
* harbour/source/rdd/dbffpt/dbffpt1.c
* harbour/source/rdd/hsx/hsx.c
* harbour/source/rtl/accept.c
* harbour/source/rtl/ampm.c
* harbour/source/rtl/console.c
* harbour/source/rtl/defpath.c
* harbour/source/rtl/errorint.c
* harbour/source/rtl/filesys.c
* harbour/source/rtl/fkmax.c
* harbour/source/rtl/fstemp.c
* harbour/source/rtl/hbffind.c
* harbour/source/rtl/hbgtcore.c
* harbour/source/rtl/langapi.c
* harbour/source/rtl/seconds.c
* harbour/source/rtl/set.c
* harbour/source/rtl/tobject.prg
* harbour/source/rtl/transfrm.c
* harbour/source/rtl/gtcrs/chrmap.c
* harbour/source/rtl/gtcrs/gtcrs.c
* harbour/source/rtl/gtcrs/gtcrs.h
* harbour/source/rtl/gtpca/gtpca.c
* harbour/source/rtl/gtwvt/gtwvt.c
* harbour/source/rtl/gtxwc/gtxwc.c
* harbour/source/vm/classes.c
* harbour/source/vm/cmdarg.c
* harbour/source/vm/debug.c
* harbour/source/vm/estack.c
* harbour/source/vm/fm.c
* harbour/source/vm/hvm.c
* harbour/source/vm/macro.c
* harbour/source/vm/proc.c
* harbour/source/vm/runner.c
* harbour/utils/hbmake/hbmlang.c
* harbour/utils/hbpp/hbpp.c
* harbour/utils/hbpp/hbppcomp.c
* harbour/utils/hbpp/hbppcore.c
* harbour/utils/hbpp/hbpplib.c
* harbour/utils/hbpp/pragma.c
* harbour/utils/hbver/hbverfix.c
* general code cleanup: all strcpy() and strcat() replaced hb strn*()
and hb_strn*(), sprintf() by snprintf(), etc.
It fixed some possible buffer overflow but it's also possible that
it will exploit some some hidden so far problems but I strongly
prefer to know about them ASAP to fix them before final 1.0 release.
! fixed bug I introduce in codeblock falgs which disabled early macro
evaluation in codeblocks.
! added missing protection against execution by bison destructor for
used CBSTART token on syntax error.
% use PP stringify logik added for FLEX support to remove all redundant
spaces in stringified for early macro evaluation codeblocks and add
spaces between operators if after preprocessing they were removed.
Now we are supporting also some code which cannot be compiled by
Clipper.
% cleaned and improved the speed of printer redirecting in console code.
Chen please check if CG still reports problems and if not ubdate
TODO/TOFIX or inform me about them.
* some cleanups in building process for different *nixes: MacOSX, SunOS,
*BSD, etc.
* removed not longer necessary (I hope) compiler flag to force default
'char' type as signed. Now Harbour should work with signed and unsigned
char without any problems. To other developers: please remember that
when you are using 'char' as 8 bytes signed integer then it's a bug.
Always explicitly use: 'signed char' in such case. On some platforms
it's not possible to set default type for 'char' so if you hardcode
that 'char' is signed or unsigned somewhere then code will not be
portable. Chen if you will find a while to also rebuild Harbour with
BCC and -K switch to make some tests with CG then I'll be thankful.
860 lines
28 KiB
C
860 lines
28 KiB
C
/*
|
|
* $Id$
|
|
*/
|
|
|
|
/*
|
|
* Harbour Project source code:
|
|
* TRANSFORM() function
|
|
*
|
|
* Copyright 1999 Eddie Runia <eddie@runia.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, or (at your option)
|
|
* any later version.
|
|
*
|
|
* 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 software; see the file COPYING. If not, write to
|
|
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
|
* Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/).
|
|
*
|
|
* As a special exception, the Harbour Project gives permission for
|
|
* additional uses of the text contained in its release of Harbour.
|
|
*
|
|
* The exception is that, if you link the Harbour libraries 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 Harbour library code into it.
|
|
*
|
|
* This exception does not however invalidate any other reasons why
|
|
* the executable file might be covered by the GNU General Public License.
|
|
*
|
|
* This exception applies only to the code released by the Harbour
|
|
* Project under the name Harbour. If you copy code from other
|
|
* Harbour Project or Free Software Foundation releases into a copy of
|
|
* Harbour, as the General Public License permits, the exception does
|
|
* not apply to the code that you add in this way. To avoid misleading
|
|
* anyone as to the status of such modified files, you must delete
|
|
* this exception notice from them.
|
|
*
|
|
* If you write modifications of your own for Harbour, it is your choice
|
|
* whether to permit this exception to apply to your modifications.
|
|
* If you do not wish that, delete this exception notice.
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* The following parts are Copyright of the individual authors.
|
|
* www - http://www.harbour-project.org
|
|
*
|
|
* Copyright 1999 Matthew Hamilton <mhamilton@bunge.com.au>
|
|
* String handling
|
|
*
|
|
* See doc/license.txt for licensing terms.
|
|
*
|
|
*/
|
|
|
|
#include <ctype.h>
|
|
|
|
#include "hbapi.h"
|
|
#include "hbapiitm.h"
|
|
#include "hbapierr.h"
|
|
#include "hbdate.h"
|
|
#include "hbset.h"
|
|
#include "hbapicdp.h"
|
|
|
|
/* Picture function flags */
|
|
#define PF_LEFT 0x0001 /* @B */
|
|
#define PF_CREDIT 0x0002 /* @C */
|
|
#define PF_DEBIT 0x0004 /* @X */
|
|
#define PF_PADL 0x0008 /* @L */ /* NOTE: This is a FoxPro/XPP extension [vszakats] */
|
|
#define PF_PARNEG 0x0010 /* @( */
|
|
#define PF_REMAIN 0x0020 /* @R */
|
|
#define PF_UPPER 0x0040 /* @! */
|
|
#define PF_DATE 0x0080 /* @D */
|
|
#define PF_BRITISH 0x0100 /* @E */
|
|
#define PF_EXCHANG 0x0100 /* @E. Also means exchange . and , */
|
|
#define PF_EMPTY 0x0200 /* @Z */
|
|
#define PF_NUMDATE 0x0400 /* Internal flag. Ignore decimal dot */
|
|
#define PF_WIDTH 0x0800 /* @S */
|
|
#define PF_PARNEGWOS 0x1000 /* @) Similar to PF_PARNEG but without leading spaces */
|
|
|
|
extern PHB_CODEPAGE hb_cdp_page;
|
|
#define TOUPPER(c) ((hb_cdp_page->nChars)? (char)hb_cdp_page->s_upper[c&255] : (char)toupper(c))
|
|
|
|
HB_FUNC( TRANSFORM )
|
|
{
|
|
PHB_ITEM pValue = hb_param( 1, HB_IT_ANY ); /* Input parameter */
|
|
PHB_ITEM pPic = hb_param( 2, HB_IT_STRING ); /* Picture string */
|
|
|
|
BOOL bError = FALSE;
|
|
|
|
if( pPic && hb_itemGetCLen( pPic ) > 0 )
|
|
{
|
|
char * szPic = hb_itemGetCPtr( pPic );
|
|
ULONG ulPicLen = hb_itemGetCLen( pPic );
|
|
USHORT uiPicFlags; /* Function flags */
|
|
|
|
ULONG ulParamS = 0; /* To avoid GCC -O2 warning */
|
|
BYTE byParamL = '\0'; /* To avoid GCC -O2 warning */
|
|
|
|
char * szResult;
|
|
ULONG ulResultPos;
|
|
|
|
double dValue = 0;
|
|
|
|
/* ======================================================= */
|
|
/* Analyze picture functions */
|
|
/* ======================================================= */
|
|
|
|
uiPicFlags = 0;
|
|
|
|
/* If an "@" char is at the first pos, we have picture function */
|
|
|
|
if( *szPic == '@' )
|
|
{
|
|
BOOL bDone = FALSE;
|
|
|
|
/* Skip the "@" char */
|
|
|
|
szPic++;
|
|
ulPicLen--;
|
|
|
|
/* Go through all function chars, until the end of the picture string
|
|
or any whitespace found. */
|
|
|
|
while( ulPicLen && ! bDone )
|
|
{
|
|
switch( toupper( *szPic ) )
|
|
{
|
|
case HB_CHAR_HT:
|
|
case '9':
|
|
case ' ':
|
|
bDone = TRUE; /* End of function string */
|
|
break;
|
|
case '!':
|
|
uiPicFlags |= PF_UPPER;
|
|
break;
|
|
case '(':
|
|
uiPicFlags |= PF_PARNEG;
|
|
break;
|
|
case ')':
|
|
uiPicFlags |= PF_PARNEGWOS;
|
|
break;
|
|
case 'L':
|
|
case '0':
|
|
uiPicFlags |= PF_PADL;
|
|
byParamL = '0';
|
|
break;
|
|
case 'B':
|
|
uiPicFlags |= PF_LEFT;
|
|
break;
|
|
case 'C':
|
|
uiPicFlags |= PF_CREDIT;
|
|
break;
|
|
case 'D':
|
|
uiPicFlags |= PF_DATE;
|
|
uiPicFlags |= PF_NUMDATE;
|
|
break;
|
|
case 'E':
|
|
uiPicFlags |= PF_BRITISH;
|
|
break;
|
|
case 'R':
|
|
uiPicFlags |= PF_REMAIN;
|
|
break;
|
|
case 'S':
|
|
uiPicFlags |= PF_WIDTH;
|
|
|
|
ulParamS = 0;
|
|
while( ulPicLen > 1 && *( szPic + 1 ) >= '0' && *( szPic + 1 ) <= '9' )
|
|
{
|
|
szPic++;
|
|
ulPicLen--;
|
|
|
|
ulParamS = ( ulParamS * 10 ) + ( ( ULONG ) ( *szPic - '0' ) );
|
|
}
|
|
|
|
break;
|
|
case 'X':
|
|
uiPicFlags |= PF_DEBIT;
|
|
break;
|
|
case 'Z':
|
|
uiPicFlags |= PF_EMPTY;
|
|
break;
|
|
}
|
|
|
|
szPic++;
|
|
ulPicLen--;
|
|
}
|
|
}
|
|
|
|
/* ======================================================= */
|
|
/* Handle STRING values */
|
|
/* ======================================================= */
|
|
|
|
if( HB_IS_STRING( pValue ) )
|
|
{
|
|
char * szExp = hb_itemGetCPtr( pValue );
|
|
ULONG ulExpLen = hb_itemGetCLen( pValue );
|
|
ULONG ulExpPos = 0;
|
|
|
|
char szPicDate[ 11 ];
|
|
BOOL bAnyPic = FALSE;
|
|
BOOL bFound = FALSE;
|
|
|
|
/* Grab enough */
|
|
|
|
/* Support date function for strings */
|
|
if( ( uiPicFlags & PF_DATE ) ||
|
|
( ( uiPicFlags & PF_BRITISH ) && ( uiPicFlags & PF_REMAIN ) ) )
|
|
{
|
|
hb_dateFormat( "XXXXXXXX", szPicDate, hb_set.HB_SET_DATEFORMAT );
|
|
|
|
szPic = szPicDate;
|
|
ulPicLen = strlen( szPicDate );
|
|
}
|
|
szResult = ( char * ) hb_xgrab( ulExpLen + ulPicLen + 1 );
|
|
ulResultPos = 0;
|
|
|
|
/* Template string */
|
|
if( ulPicLen )
|
|
{
|
|
while( ulPicLen ) /* Analyze picture mask */
|
|
{
|
|
if( ulExpPos < ulExpLen )
|
|
{
|
|
switch( *szPic )
|
|
{
|
|
/* Upper */
|
|
case '!':
|
|
{
|
|
szResult[ ulResultPos++ ] = TOUPPER( szExp[ ulExpPos ] );
|
|
ulExpPos++;
|
|
bAnyPic = TRUE;
|
|
break;
|
|
}
|
|
|
|
/* Out the character */
|
|
case '#':
|
|
case '9':
|
|
case 'a':
|
|
case 'A':
|
|
case 'l':
|
|
case 'L':
|
|
case 'n':
|
|
case 'N':
|
|
case 'x':
|
|
case 'X':
|
|
{
|
|
szResult[ ulResultPos++ ] = ( uiPicFlags & PF_UPPER ) ? TOUPPER( szExp[ ulExpPos ] ) : szExp[ ulExpPos ];
|
|
ulExpPos++;
|
|
bAnyPic = TRUE;
|
|
break;
|
|
}
|
|
|
|
/* Logical */
|
|
case 'y':
|
|
case 'Y':
|
|
{
|
|
szResult[ ulResultPos++ ] = ( szExp[ ulExpPos ] == 't' ||
|
|
szExp[ ulExpPos ] == 'T' ||
|
|
szExp[ ulExpPos ] == 'y' ||
|
|
szExp[ ulExpPos ] == 'Y' ) ? ( char ) 'Y' : ( char ) 'N';
|
|
ulExpPos++;
|
|
bAnyPic = TRUE;
|
|
break;
|
|
}
|
|
|
|
/* Other choices */
|
|
default:
|
|
{
|
|
szResult[ ulResultPos++ ] = *szPic;
|
|
|
|
if( !( uiPicFlags & PF_REMAIN ) )
|
|
ulExpPos++;
|
|
}
|
|
}
|
|
}
|
|
else if( !( uiPicFlags & PF_REMAIN ) )
|
|
break;
|
|
|
|
else
|
|
{
|
|
switch( *szPic )
|
|
{
|
|
case '!':
|
|
case '#':
|
|
case '9':
|
|
case 'a':
|
|
case 'A':
|
|
case 'l':
|
|
case 'L':
|
|
case 'n':
|
|
case 'N':
|
|
case 'x':
|
|
case 'X':
|
|
case 'y':
|
|
case 'Y':
|
|
{
|
|
szResult[ ulResultPos++ ] = ' ';
|
|
break;
|
|
}
|
|
|
|
default:
|
|
szResult[ ulResultPos++ ] = *szPic;
|
|
}
|
|
}
|
|
|
|
szPic++;
|
|
ulPicLen--;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
while( ulExpPos++ < ulExpLen )
|
|
{
|
|
if( uiPicFlags & PF_EXCHANG )
|
|
{
|
|
switch( *szExp )
|
|
{
|
|
case ',':
|
|
{
|
|
szResult[ ulResultPos++ ] = '.';
|
|
break;
|
|
}
|
|
case '.':
|
|
{
|
|
if( !bFound && ulResultPos )
|
|
{
|
|
szResult[ ulResultPos++ ] = ',';
|
|
bFound = TRUE;
|
|
}
|
|
|
|
break;
|
|
}
|
|
default:
|
|
szResult[ ulResultPos++ ] = ( uiPicFlags & PF_UPPER ) ? TOUPPER( *szExp ) : *szExp;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
szResult[ ulResultPos++ ] = ( uiPicFlags & PF_UPPER ) ? TOUPPER( *szExp ) : *szExp;
|
|
}
|
|
szExp++;
|
|
}
|
|
}
|
|
|
|
if( ( uiPicFlags & PF_REMAIN ) && ! bAnyPic )
|
|
{
|
|
while( ulExpPos++ < ulExpLen )
|
|
{
|
|
szResult[ ulResultPos++ ] = ( uiPicFlags & PF_UPPER ) ? TOUPPER( *szExp ) : *szExp;
|
|
szExp++;
|
|
}
|
|
}
|
|
|
|
/* Any chars left ? */
|
|
if( ( uiPicFlags & PF_REMAIN ) && ulPicLen )
|
|
{
|
|
/* Export remainder */
|
|
while( ulPicLen-- )
|
|
szResult[ ulResultPos++ ] = ' ';
|
|
}
|
|
|
|
if( ( ( uiPicFlags & PF_DATE ) && ( uiPicFlags & PF_BRITISH ) ) ||
|
|
( ( uiPicFlags & PF_BRITISH ) && ( uiPicFlags & PF_REMAIN ) ) )
|
|
{
|
|
szPicDate[ 0 ] = szResult[ 3 ];
|
|
szPicDate[ 1 ] = szResult[ 4 ];
|
|
|
|
szResult[ 3 ] = szResult[ 0 ];
|
|
szResult[ 4 ] = szResult[ 1 ];
|
|
|
|
szResult[ 0 ] = szPicDate[ 0 ];
|
|
szResult[ 1 ] = szPicDate[ 1 ];
|
|
}
|
|
}
|
|
|
|
/* ======================================================= */
|
|
/* Handle NUMERIC values */
|
|
/* ======================================================= */
|
|
|
|
else if( HB_IS_NUMERIC( pValue ) )
|
|
{
|
|
double dPush;
|
|
|
|
int iOrigWidth;
|
|
int iOrigDec;
|
|
int iWidth; /* Width of string */
|
|
int iDec; /* Number of decimals */
|
|
ULONG i;
|
|
ULONG ulBufSize;
|
|
int iCount = 0;
|
|
|
|
char * szStr;
|
|
char cPic;
|
|
char szPicDate[ 11 ];
|
|
|
|
PHB_ITEM pNumber;
|
|
PHB_ITEM pWidth;
|
|
PHB_ITEM pDec;
|
|
|
|
BOOL bFound = FALSE;
|
|
BOOL bInit = FALSE;
|
|
BOOL bPDec = FALSE;
|
|
|
|
dValue = hb_itemGetND( pValue );
|
|
hb_itemGetNLen( pValue, &iOrigWidth, &iOrigDec );
|
|
|
|
/* Support date function for numbers */
|
|
if( uiPicFlags & PF_DATE )
|
|
{
|
|
hb_dateFormat( "99999999", szPicDate,
|
|
hb_set.HB_SET_DATEFORMAT );
|
|
|
|
szPic = szPicDate;
|
|
ulPicLen = strlen( szPicDate );
|
|
}
|
|
|
|
/* TODO: maybe replace this 16 with something else */
|
|
ulBufSize = ulPicLen + (ULONG) iOrigWidth + (ULONG) iOrigDec + 16;
|
|
szResult = ( char * ) hb_xgrab( ulBufSize ); /* Grab enough */
|
|
*szResult = '\0';
|
|
|
|
for( i = 0; i < ulPicLen && !bFound; i++ ) /* Count number in front */
|
|
{
|
|
if( szPic[ i ] == '.' )
|
|
/* bFound = !( uiPicFlags & PF_NUMDATE ); / * Exit when numeric */
|
|
bFound = TRUE;
|
|
else if( szPic[ i ] == '9' || szPic[ i ] == '#' ||
|
|
szPic[ i ] == '$' || szPic[ i ] == '*' )
|
|
iCount++;
|
|
}
|
|
iWidth = iCount;
|
|
|
|
if( bFound ) /* Did we find a dot */
|
|
{
|
|
iDec = 0;
|
|
if( i < ulPicLen )
|
|
{ /* if not 9999. */
|
|
iWidth++; /* Also adjust iWidth */
|
|
}
|
|
for( ; i < ulPicLen; i++ )
|
|
{
|
|
if( szPic[ i ] == '9' ||
|
|
szPic[ i ] == '#' ||
|
|
szPic[ i ] == '$' ||
|
|
szPic[ i ] == '*' )
|
|
{
|
|
iWidth++;
|
|
iDec++;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
iDec = 0;
|
|
|
|
if( ( uiPicFlags & ( PF_DEBIT + PF_PARNEG + PF_PARNEGWOS ) ) && dValue < 0 )
|
|
dPush = -dValue; /* Always push absolute val */
|
|
else
|
|
dPush = dValue;
|
|
|
|
/* Don't empty the result if the number is not zero */
|
|
if( dPush != 0 && ( uiPicFlags & PF_EMPTY ) )
|
|
uiPicFlags &= ~PF_EMPTY;
|
|
|
|
if( iWidth == 0 ) /* Width calculated ?? */
|
|
{
|
|
iWidth = iOrigWidth; /* Push original width */
|
|
iDec = iOrigDec; /* Push original decimals */
|
|
}
|
|
|
|
pNumber = hb_itemPutNDLen( NULL, dPush, -1, iDec );
|
|
pWidth = hb_itemPutNI( NULL, iWidth + ( ( ulPicLen || iDec == 0 ) ? 0 : ( iDec + 1 ) ) );
|
|
pDec = hb_itemPutNI( NULL, iDec );
|
|
|
|
szStr = hb_itemStr( pNumber, pWidth, pDec );
|
|
|
|
hb_itemRelease( pNumber );
|
|
hb_itemRelease( pWidth );
|
|
hb_itemRelease( pDec );
|
|
|
|
if( szStr )
|
|
{
|
|
iCount = 0;
|
|
|
|
/* Pad with padding char */
|
|
if( uiPicFlags & PF_PADL )
|
|
{
|
|
for( i = 0; szStr[ i ] == ' ' && i < ( ULONG ) iWidth; i++ )
|
|
szStr[ i ] = byParamL;
|
|
}
|
|
|
|
if( ulPicLen )
|
|
for( i = 0; i < ulPicLen; i++ )
|
|
{
|
|
cPic = szPic[ i ];
|
|
|
|
if( !bInit && ( cPic == '9' || cPic == '#' || cPic == '$' || cPic == '*' ) )
|
|
bInit = TRUE;
|
|
|
|
if( cPic == '9' || cPic == '#' )
|
|
{
|
|
if( iCount < iWidth )
|
|
szResult[ i ] = szStr[ iCount++ ]; /* Just copy */
|
|
else
|
|
szResult[ i ] = ' ';
|
|
}
|
|
else if( cPic == '.' && bInit )
|
|
{
|
|
bPDec = TRUE;
|
|
|
|
if( uiPicFlags & PF_EXCHANG ) /* Exchange . and , */
|
|
{
|
|
szResult[ i ] = ',';
|
|
iCount++;
|
|
}
|
|
else
|
|
{
|
|
if( uiPicFlags & PF_NUMDATE || bPDec ) /* Dot in date */
|
|
{
|
|
szResult[ i ] = cPic;
|
|
iCount++;
|
|
}
|
|
else /* Dot in number */
|
|
{
|
|
szResult[ i ] = szStr[ iCount++ ];
|
|
}
|
|
}
|
|
}
|
|
else if( cPic == '$' || cPic == '*' )
|
|
{
|
|
if( szStr[ iCount ] == ' ' )
|
|
{
|
|
szResult[ i ] = cPic;
|
|
iCount++;
|
|
}
|
|
else
|
|
szResult[ i ] = szStr[ iCount++ ];
|
|
}
|
|
else if( cPic == ',' && bInit ) /* Comma */
|
|
{
|
|
if( iCount && isdigit( ( int ) szStr[ iCount - 1 ] ) )
|
|
{ /* May we place it */
|
|
if( uiPicFlags & PF_EXCHANG )
|
|
szResult[ i ] = '.';
|
|
else
|
|
szResult[ i ] = ',';
|
|
}
|
|
else
|
|
{
|
|
if( i && szResult[ i - 1 ] == '*' )
|
|
szResult[ i ] = '*';
|
|
else
|
|
szResult[ i ] = ' ';
|
|
|
|
if ( i && szResult[ i - 1 ] == '-' )
|
|
{
|
|
szResult[ i -1 ] = ' ';
|
|
szResult[ i ] = '-';
|
|
}
|
|
}
|
|
}
|
|
else
|
|
szResult[ i ] = cPic;
|
|
}
|
|
else
|
|
{
|
|
hb_strncpy( szResult, szStr, ulBufSize - 1 );
|
|
i = strlen( szResult );
|
|
}
|
|
|
|
if( ( uiPicFlags & PF_PARNEG ) && dValue < 0 && !( uiPicFlags & PF_PARNEGWOS ) )
|
|
/* This is a behavior of Clipper,
|
|
if exist PF_PARNEG and PF_PARNEGWOS,
|
|
PR_PARNEGWOS prevails. */
|
|
|
|
{
|
|
for( iCount = 0; ( ULONG ) iCount < i; iCount++ )
|
|
/* Permit to detect overflow when picture init with mask */
|
|
{
|
|
if( isdigit( ( int ) szResult[ iCount ] ) &&
|
|
!( szResult[ iCount ] == '0' ) && /* if not PF_PADL */
|
|
( iCount == 0 ||
|
|
!isdigit( ( int ) szPic[ iCount ] ) ) ) /* if not mask symbol */
|
|
/* Overflow */
|
|
{
|
|
for( iCount++; ( ULONG ) iCount < i; iCount++ )
|
|
{
|
|
if( isdigit( ( int ) szResult[ iCount ] ) )
|
|
szResult[ iCount ] = '*';
|
|
}
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if( !isdigit( ( int ) szResult[ iCount ] ) ||
|
|
( szResult[ iCount ] == '0' && !isdigit( ( int ) szPic[ iCount ] ) ) )
|
|
break;
|
|
}
|
|
}
|
|
*szResult = '(';
|
|
szResult[ i++ ] = ')';
|
|
}
|
|
|
|
if( ( uiPicFlags & PF_PARNEGWOS ) && dValue < 0 )
|
|
{
|
|
for( iCount = 0; ( ULONG ) iCount < i; iCount++ )
|
|
/* Permit to detect overflow when picture init with mask */
|
|
{
|
|
if( isdigit( ( int ) szResult[ iCount ] ) &&
|
|
!( szResult[ iCount ] == '0' ) && /* if not PF_PADL */
|
|
( iCount == 0 ||
|
|
!isdigit( ( int ) szPic[ iCount ] ) ) ) /* if not mask symbol */
|
|
/* Overflow */
|
|
{
|
|
for( iCount++; ( ULONG ) iCount < i; iCount++ )
|
|
{
|
|
if( isdigit( ( int ) szResult[ iCount ] ) )
|
|
szResult[ iCount ] = '*';
|
|
}
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if( !isdigit( ( int ) szResult[ iCount ] ) ||
|
|
( szResult[ iCount ] == '0' && !isdigit( ( int ) szPic[ iCount ] ) ) )
|
|
{
|
|
for( ; ( ULONG ) iCount < i; iCount++ )
|
|
{
|
|
if( szResult[ iCount ] != ' ' )
|
|
{
|
|
if( iCount > 0 )
|
|
szResult[ iCount - 1 ] = '(';
|
|
else
|
|
*szResult = '(';
|
|
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
szResult[ i++ ] = ')';
|
|
}
|
|
|
|
if( ( uiPicFlags & PF_CREDIT ) && dValue >= 0 )
|
|
{
|
|
szResult[ i++ ] = ' ';
|
|
szResult[ i++ ] = 'C';
|
|
szResult[ i++ ] = 'R';
|
|
}
|
|
|
|
if( ( uiPicFlags & PF_DEBIT ) && dValue < 0 )
|
|
{
|
|
szResult[ i++ ] = ' ';
|
|
szResult[ i++ ] = 'D';
|
|
szResult[ i++ ] = 'B';
|
|
}
|
|
|
|
ulResultPos = i;
|
|
szResult[ i ] = '\0';
|
|
|
|
hb_xfree( szStr );
|
|
}
|
|
else
|
|
{
|
|
ulResultPos = 0;
|
|
}
|
|
}
|
|
|
|
/* ======================================================= */
|
|
/* Handle DATE values */
|
|
/* ======================================================= */
|
|
|
|
else if( HB_IS_DATE( pValue ) )
|
|
{
|
|
char szPicDate[ 11 ];
|
|
char szDate[ 9 ];
|
|
|
|
UINT nFor;
|
|
|
|
szResult = ( char * ) hb_xgrab( 13 );
|
|
|
|
hb_dateFormat( hb_itemGetDS( pValue, szDate ), szResult,
|
|
( uiPicFlags & PF_BRITISH ) ?
|
|
( hb_set.hb_set_century ? "DD/MM/YYYY" : "DD/MM/YY" ) :
|
|
hb_set.HB_SET_DATEFORMAT );
|
|
|
|
ulResultPos = strlen( szResult );
|
|
|
|
if( uiPicFlags & PF_REMAIN )
|
|
{
|
|
hb_dateFormat( "99999999", szPicDate,
|
|
( uiPicFlags & PF_BRITISH ) ?
|
|
( hb_set.hb_set_century ? "DD/MM/YYYY" : "DD/MM/YY" ) :
|
|
hb_set.HB_SET_DATEFORMAT );
|
|
|
|
ulPicLen = strlen( szPicDate );
|
|
|
|
for( nFor = 0; nFor < ulPicLen; nFor++ )
|
|
{
|
|
if( szPicDate[ nFor ] != '9' )
|
|
{
|
|
memmove( szResult + nFor + 1, szResult + nFor, 12 - nFor );
|
|
szResult[ nFor ] = szPicDate[ nFor ];
|
|
ulResultPos++;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/* ======================================================= */
|
|
/* Handle LOGICAL values */
|
|
/* ======================================================= */
|
|
|
|
else if( HB_IS_LOGICAL( pValue ) )
|
|
{
|
|
BOOL bDone = FALSE;
|
|
BOOL bExit = FALSE;
|
|
|
|
char cPic;
|
|
|
|
ulResultPos = 0;
|
|
|
|
szResult = ( char * ) hb_xgrab( ulPicLen + 2 );
|
|
|
|
for( ; ( ulPicLen || !bDone ) && !bExit ; ulResultPos++, szPic++, ulPicLen-- )
|
|
{
|
|
|
|
if( ulPicLen )
|
|
cPic = *szPic;
|
|
else
|
|
{
|
|
cPic = 'L';
|
|
bExit = TRUE;
|
|
}
|
|
|
|
switch( cPic )
|
|
{
|
|
case 'y': /* Yes/No */
|
|
case 'Y': /* Yes/No */
|
|
{
|
|
if( !bDone )
|
|
{
|
|
szResult[ ulResultPos ] = hb_itemGetL( pValue ) ? ( char ) 'Y' : ( char ) 'N';
|
|
bDone = TRUE; /* Logical written */
|
|
}
|
|
else
|
|
szResult[ ulResultPos ] = ' ';
|
|
|
|
break;
|
|
}
|
|
|
|
case '#':
|
|
case 'l': /* True/False */
|
|
case 'L': /* True/False */
|
|
{
|
|
if( !bDone )
|
|
{
|
|
szResult[ ulResultPos ] = hb_itemGetL( pValue ) ? ( char ) 'T' : ( char ) 'F';
|
|
bDone = TRUE;
|
|
}
|
|
else
|
|
szResult[ ulResultPos ] = ' ';
|
|
|
|
break;
|
|
}
|
|
|
|
default:
|
|
szResult[ ulResultPos ] = cPic;
|
|
}
|
|
|
|
if( !( uiPicFlags & PF_REMAIN ) )
|
|
bExit = TRUE;
|
|
}
|
|
|
|
}
|
|
|
|
/* ======================================================= */
|
|
|
|
else
|
|
{
|
|
szResult = NULL; /* To avoid GCC -O2 warning */
|
|
ulResultPos = 0; /* To avoid GCC -O2 warning */
|
|
bError = TRUE;
|
|
}
|
|
|
|
if( ! bError )
|
|
{
|
|
/* Trim left and pad with spaces */
|
|
if( uiPicFlags & PF_LEFT )
|
|
{
|
|
|
|
ULONG ulFirstChar = ( ( ( uiPicFlags & PF_PARNEG ) && dValue < 0 && !( uiPicFlags & PF_PARNEGWOS ) ) ? 1: 0 );
|
|
|
|
while( ulFirstChar < ulResultPos && szResult[ ulFirstChar ] == ' ' )
|
|
ulFirstChar++;
|
|
|
|
if( ulFirstChar < ulResultPos )
|
|
{
|
|
memmove( szResult + ( ( ( uiPicFlags & PF_PARNEG ) && dValue < 0 && !( uiPicFlags & PF_PARNEGWOS ) ) ? 1: 0 ), szResult + ulFirstChar, ulResultPos - ulFirstChar );
|
|
memset( szResult + ulResultPos - ulFirstChar + ( ( ( uiPicFlags & PF_PARNEG ) && dValue < 0 && !( uiPicFlags & PF_PARNEGWOS ) ) ? 1: 0 ), ' ', ulFirstChar );
|
|
}
|
|
}
|
|
|
|
if( uiPicFlags & PF_EMPTY )
|
|
memset( szResult, ' ', ulResultPos );
|
|
|
|
hb_retclen_buffer( szResult, ( uiPicFlags & PF_WIDTH && ulResultPos > ulParamS && ulParamS > 0 ) ? ulParamS : ulResultPos );
|
|
}
|
|
}
|
|
else if( pPic || ISNIL( 2 ) ) /* Picture is an empty string or NIL */
|
|
{
|
|
if( HB_IS_STRING( pValue ) )
|
|
{
|
|
hb_itemReturn( pValue );
|
|
}
|
|
else if( HB_IS_NUMERIC( pValue ) )
|
|
{
|
|
ULONG ulLen;
|
|
BOOL bFreeReq;
|
|
char * szStr = hb_itemString( pValue, &ulLen, &bFreeReq );
|
|
|
|
if( bFreeReq )
|
|
hb_retclen_buffer( szStr, ulLen );
|
|
else
|
|
hb_retclen( szStr, ulLen );
|
|
}
|
|
else if( HB_IS_DATE( pValue ) )
|
|
{
|
|
char szDate[ 9 ];
|
|
char szResult[ 11 ];
|
|
|
|
hb_retc( hb_dateFormat( hb_itemGetDS( pValue, szDate ), szResult, hb_set.HB_SET_DATEFORMAT ) );
|
|
}
|
|
else if( HB_IS_LOGICAL( pValue ) )
|
|
{
|
|
hb_retc( hb_itemGetL( pValue ) ? "T" : "F" );
|
|
}
|
|
else
|
|
bError = TRUE;
|
|
}
|
|
else
|
|
bError = TRUE;
|
|
|
|
/* If there was any parameter error, launch a runtime error */
|
|
|
|
if( bError )
|
|
hb_errRT_BASE_SubstR( EG_ARG, 1122, NULL, "TRANSFORM", 2, pValue, hb_paramError( 2 ) );
|
|
}
|