summaryrefslogtreecommitdiff
path: root/basic/source
diff options
context:
space:
mode:
authorOliver Bolte <obo@openoffice.org>2005-04-13 08:25:31 +0000
committerOliver Bolte <obo@openoffice.org>2005-04-13 08:25:31 +0000
commite704dfb4fc48bb25c8ef41d69e7328686b380fce (patch)
treefb3a1936fb8e787cb4bbc413d699f59d8c1b6027 /basic/source
parent889517ca3e206a8f0f506b54ab48cb285b88feb2 (diff)
INTEGRATION: CWS visibility03 (1.1.2); FILE ADDED
2005/03/24 18:04:31 mhu 1.1.2.1: #i45006# Moved from svtools/source/sbx/
Diffstat (limited to 'basic/source')
-rw-r--r--basic/source/sbx/sbxres.hxx123
-rw-r--r--basic/source/sbx/sbxscan.cxx787
2 files changed, 910 insertions, 0 deletions
diff --git a/basic/source/sbx/sbxres.hxx b/basic/source/sbx/sbxres.hxx
new file mode 100644
index 000000000000..d4615c87dc2e
--- /dev/null
+++ b/basic/source/sbx/sbxres.hxx
@@ -0,0 +1,123 @@
+/*************************************************************************
+ *
+ * $RCSfile: sbxres.hxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: obo $ $Date: 2005-04-13 09:25:19 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SBXRES_HXX
+#define _SBXRES_HXX
+
+#ifndef _STRING_HXX //autogen
+#include <tools/string.hxx>
+#endif
+
+// Zur Zeit sind Ressources im SVTOOLS-Projekt nicht vorgesehen.
+// Da es sich um unkritische Ressourcen handelt (BASIC-Keywords),
+// koennen wir mit Dummies arbeiten.
+
+#define STRING_TYPES 0
+#define STRING_EMPTY 0
+#define STRING_NULL 1
+#define STRING_INTEGER 2
+#define STRING_LONG 3
+#define STRING_SINGLE 4
+#define STRING_DOUBLE 5
+#define STRING_CURRENCY 6
+#define STRING_DATE 7
+#define STRING_STRING 8
+#define STRING_OBJECT 9
+#define STRING_ERROR 10
+#define STRING_BOOL 11
+#define STRING_VARIANT 12
+#define STRING_ANY 13
+#define STRING_CHAR 16
+#define STRING_BYTE 17
+#define STRING_USHORT 18
+#define STRING_ULONG 19
+#define STRING_INT 22
+#define STRING_UINT 23
+#define STRING_LPSTR 30
+#define STRING_LPWSTR 31
+#define STRING_AS 32
+#define STRING_OPTIONAL 33
+#define STRING_BYREF 34
+
+#define STRING_NAMEPROP 35
+#define STRING_PARENTPROP 36
+#define STRING_APPLPROP 37
+#define STRING_COUNTPROP 38
+#define STRING_ADDMETH 39
+#define STRING_ITEMMETH 40
+#define STRING_REMOVEMETH 41
+
+#define STRING_ERRORMSG 42
+#define STRING_FALSE 43
+#define STRING_TRUE 44
+
+#define SBXRES_MAX 44
+
+class SbxRes : public String
+{
+public:
+ SbxRes( USHORT );
+};
+
+const char* GetSbxRes( USHORT );
+
+
+#endif
diff --git a/basic/source/sbx/sbxscan.cxx b/basic/source/sbx/sbxscan.cxx
new file mode 100644
index 000000000000..e4ba794e8378
--- /dev/null
+++ b/basic/source/sbx/sbxscan.cxx
@@ -0,0 +1,787 @@
+/*************************************************************************
+ *
+ * $RCSfile: sbxscan.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: obo $ $Date: 2005-04-13 09:25:31 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _ERRCODE_HXX //autogen
+#include <tools/errcode.hxx>
+#endif
+#include "sbx.hxx"
+#include "sbxconv.hxx"
+
+#include "svtools/syslocale.hxx"
+
+#pragma hdrstop
+#if defined ( WTC ) || defined ( ICC ) || defined ( MAC ) || defined ( UNX )
+#include <stdlib.h>
+#endif
+
+#ifndef _INTN_HXX //autogen
+#include <tools/intn.hxx>
+#endif
+#ifndef _APP_HXX //autogen
+#include <vcl/svapp.hxx>
+#endif
+#include <math.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "sbxres.hxx"
+#include "sbxbase.hxx"
+#include "sbxform.hxx"
+#include <svtools/svtools.hrc>
+
+#include "basrid.hxx"
+
+void ImpGetIntntlSep( sal_Unicode& rcDecimalSep, sal_Unicode& rcThousandSep )
+{
+ SvtSysLocale aSysLocale;
+ const LocaleDataWrapper& rData = aSysLocale.GetLocaleData();
+ rcDecimalSep = rData.getNumDecimalSep().GetBuffer()[0];
+ rcThousandSep = rData.getNumThousandSep().GetBuffer()[0];
+}
+
+// Scannen eines Strings nach BASIC-Konventionen
+// Dies entspricht den ueblichen Konventionen, nur dass der Exponent
+// auch ein D sein darf, was den Datentyp auf SbxDOUBLE festlegt.
+// Die Routine versucht, den Datentyp so klein wie moeglich zu gestalten.
+// Das ganze gibt auch noch einen Konversionsfehler, wenn der Datentyp
+// Fixed ist und das ganze nicht hineinpasst!
+
+SbxError ImpScan( const XubString& rWSrc, double& nVal, SbxDataType& rType,
+ USHORT* pLen, BOOL bAllowIntntl, BOOL bOnlyIntntl )
+{
+ ByteString aBStr( rWSrc, RTL_TEXTENCODING_ASCII_US );
+
+ // Bei International Komma besorgen
+ char cIntntlComma, cIntntl1000;
+ char cNonIntntlComma = '.';
+
+ sal_Unicode cDecimalSep, cThousandSep;
+ if( bAllowIntntl || bOnlyIntntl )
+ {
+ ImpGetIntntlSep( cDecimalSep, cThousandSep );
+ cIntntlComma = (char)cDecimalSep;
+ cIntntl1000 = (char)cThousandSep;
+ }
+ // Sonst einfach auch auf . setzen
+ else
+ {
+ cIntntlComma = cNonIntntlComma;
+ cIntntl1000 = cNonIntntlComma; // Unschaedlich machen
+ }
+ // Nur International -> IntnlComma uebernehmen
+ if( bOnlyIntntl )
+ {
+ cNonIntntlComma = cIntntlComma;
+ cIntntl1000 = (char)cThousandSep;
+ }
+
+ const char* pStart = aBStr.GetBuffer();
+ const char* p = pStart;
+ char buf[ 80 ], *q = buf;
+ BOOL bRes = TRUE;
+ BOOL bMinus = FALSE;
+ nVal = 0;
+ SbxDataType eScanType = SbxSINGLE;
+ // Whitespace wech
+ while( *p &&( *p == ' ' || *p == '\t' ) ) p++;
+ // Zahl? Dann einlesen und konvertieren.
+ if( *p == '-' )
+ p++, bMinus = TRUE;
+ if( isdigit( *p ) ||( (*p == cNonIntntlComma || *p == cIntntlComma ||
+ *p == cIntntl1000) && isdigit( *(p+1 ) ) ) )
+ {
+ short exp = 0; // >0: Exponentteil
+ short comma = 0; // >0: Nachkomma
+ short ndig = 0; // Anzahl Ziffern
+ short ncdig = 0; // Anzahl Ziffern nach Komma
+ ByteString aSearchStr( "0123456789DEde" );
+ // Kommas ergaenzen
+ aSearchStr += cNonIntntlComma;
+ if( cIntntlComma != cNonIntntlComma )
+ aSearchStr += cIntntlComma;
+ if( bOnlyIntntl )
+ aSearchStr += cIntntl1000;
+ const char* pSearchStr = aSearchStr.GetBuffer();
+ while( strchr( pSearchStr, *p ) && *p )
+ {
+ // 1000er-Trenner ueberlesen
+ if( bOnlyIntntl && *p == cIntntl1000 )
+ {
+ p++;
+ continue;
+ }
+
+ // Komma oder Exponent?
+ if( *p == cNonIntntlComma || *p == cIntntlComma )
+ {
+ // Immer '.' einfuegen, damit atof funktioniert
+ p++;
+ if( ++comma > 1 )
+ continue;
+ else
+ *q++ = '.';
+ }
+ else if( strchr( "DdEe", *p ) )
+ {
+ if( ++exp > 1 )
+ {
+ p++; continue;
+ }
+ if( toupper( *p ) == 'D' )
+ eScanType = SbxDOUBLE;
+ *q++ = 'E'; p++;
+ // Vorzeichen hinter Exponent?
+ if( *p == '+' )
+ p++;
+ else
+ if( *p == '-' )
+ *q++ = *p++;
+ }
+ else
+ {
+ *q++ = *p++;
+ if( comma && !exp ) ncdig++;
+ }
+ if( !exp ) ndig++;
+ }
+ *q = 0;
+ // Komma, Exponent mehrfach vorhanden?
+ if( comma > 1 || exp > 1 )
+ bRes = FALSE;
+ // Kann auf Integer gefaltet werden?
+ if( !comma && !exp )
+ {
+ if( nVal >= SbxMININT && nVal <= SbxMAXINT )
+ eScanType = SbxINTEGER;
+ else if( nVal >= SbxMINLNG && nVal <= SbxMAXLNG )
+ eScanType = SbxLONG;
+ }
+
+ nVal = atof( buf );
+ ndig -= comma;
+ // zu viele Zahlen fuer SINGLE?
+ if( ndig > 15 || ncdig > 6 )
+ eScanType = SbxDOUBLE;
+
+ // Typkennung?
+ if( strchr( "%!&#", *p ) && *p ) p++;
+ }
+ // Hex/Oktalzahl? Einlesen und konvertieren:
+ else if( *p == '&' )
+ {
+ p++;
+ eScanType = SbxLONG;
+ const char *cmp = "0123456789ABCDEF";
+ char base = 16;
+ char ndig = 8;
+ char xch = *p++;
+ switch( toupper( xch ) )
+ {
+ case 'O': cmp = "01234567"; base = 8; ndig = 11; break;
+ case 'H': break;
+ default : bRes = FALSE;
+ }
+ long l = 0;
+ int i;
+ while( isalnum( *p ) )
+ {
+ char ch = toupper( *p );
+ p++;
+ if( strchr( cmp, ch ) ) *q++ = ch;
+ else bRes = FALSE;
+ }
+ *q = 0;
+ for( q = buf; *q; q++ )
+ {
+ i =( *q & 0xFF ) - '0';
+ if( i > 9 ) i -= 7;
+ l =( l * base ) + i;
+ if( !ndig-- )
+ bRes = FALSE;
+ }
+ if( *p == '&' ) p++;
+ nVal = (double) l;
+ if( l >= SbxMININT && l <= SbxMAXINT )
+ eScanType = SbxINTEGER;
+ }
+ if( pLen )
+ *pLen = (USHORT) ( p - pStart );
+ if( !bRes )
+ return SbxERR_CONVERSION;
+ if( bMinus )
+ nVal = -nVal;
+ rType = eScanType;
+ return SbxERR_OK;
+}
+
+// Schnittstelle fuer CDbl im Basic
+SbxError SbxValue::ScanNumIntnl( const String& rSrc, double& nVal, BOOL bSingle )
+{
+ SbxDataType t;
+ USHORT nLen = 0;
+ SbxError nRetError = ImpScan( rSrc, nVal, t, &nLen,
+ /*bAllowIntntl*/FALSE, /*bOnlyIntntl*/TRUE );
+ // Komplett gelesen?
+ if( nRetError == SbxERR_OK && nLen != rSrc.Len() )
+ nRetError = SbxERR_CONVERSION;
+
+ if( bSingle )
+ {
+ SbxValues aValues( nVal );
+ nVal = (double)ImpGetSingle( &aValues ); // Hier Error bei Overflow
+ }
+ return nRetError;
+}
+
+////////////////////////////////////////////////////////////////////////////
+
+static double roundArray[] = {
+ 5.0e+0, 0.5e+0, 0.5e-1, 0.5e-2, 0.5e-3, 0.5e-4, 0.5e-5, 0.5e-6, 0.5e-7,
+ 0.5e-8, 0.5e-9, 0.5e-10,0.5e-11,0.5e-12,0.5e-13,0.5e-14,0.5e-15 };
+
+/***************************************************************************
+|*
+|* void myftoa( double, char *, short, short, BOOL, BOOL )
+|*
+|* Beschreibung: Konversion double --> ASCII
+|* Parameter: double die Zahl.
+|* char * der Zielpuffer
+|* short Anzahl Nachkommastellen
+|* short Weite des Exponenten( 0=kein E )
+|* BOOL TRUE: mit 1000er Punkten
+|* BOOL TRUE: formatfreie Ausgabe
+|*
+***************************************************************************/
+
+static void myftoa( double nNum, char * pBuf, short nPrec, short nExpWidth,
+ BOOL bPt, BOOL bFix, sal_Unicode cForceThousandSep = 0 )
+{
+
+ short nExp = 0; // Exponent
+ short nDig = nPrec + 1; // Anzahl Digits in Zahl
+ short nDec; // Anzahl Vorkommastellen
+ register int i, digit;
+
+ // Komma besorgen
+ sal_Unicode cDecimalSep, cThousandSep;
+ ImpGetIntntlSep( cDecimalSep, cThousandSep );
+ if( cForceThousandSep )
+ cThousandSep = cForceThousandSep;
+
+ // Exponentberechnung:
+ nExp = 0;
+ if( nNum > 0.0 )
+ {
+ while( nNum < 1.0 ) nNum *= 10.0, nExp--;
+ while( nNum >= 10.0 ) nNum /= 10.0, nExp++;
+ }
+ if( !bFix && !nExpWidth )
+ nDig += nExp;
+ else if( bFix && !nPrec )
+ nDig = nExp + 1;
+
+ // Zahl runden:
+ if( (nNum += roundArray [( nDig > 16 ) ? 16 : nDig] ) >= 10.0 )
+ {
+ nNum = 1.0;
+ ++nExp;
+ if( !nExpWidth ) ++nDig;
+ }
+
+ // Bestimmung der Vorkommastellen:
+ if( !nExpWidth )
+ {
+ if( nExp < 0 )
+ {
+ // #41691: Auch bei bFix eine 0 spendieren
+ *pBuf++ = '0';
+ if( nPrec ) *pBuf++ = (char)cDecimalSep;
+ i = -nExp - 1;
+ if( nDig <= 0 ) i = nPrec;
+ while( i-- ) *pBuf++ = '0';
+ nDec = 0;
+ }
+ else
+ nDec = nExp+1;
+ }
+ else
+ nDec = 1;
+
+ // Zahl ausgeben:
+ if( nDig > 0 )
+ {
+ for( i = 0 ; ; ++i )
+ {
+ if( i < 16 )
+ {
+ digit = (int) nNum;
+ *pBuf++ = digit + '0';
+ nNum =( nNum - digit ) * 10.0;
+ } else
+ *pBuf++ = '0';
+ if( --nDig == 0 ) break;
+ if( nDec )
+ {
+ nDec--;
+ if( !nDec )
+ *pBuf++ = (char)cDecimalSep;
+ else if( !(nDec % 3 ) && bPt )
+ *pBuf++ = (char)cThousandSep;
+ }
+ }
+ }
+
+ // Exponent ausgeben:
+ if( nExpWidth )
+ {
+ if( nExpWidth < 3 ) nExpWidth = 3;
+ nExpWidth -= 2;
+ *pBuf++ = 'E';
+ *pBuf++ =( nExp < 0 ) ?( (nExp = -nExp ), '-' ) : '+';
+ while( nExpWidth > 3 ) *pBuf++ = '0', nExpWidth--;
+ if( nExp >= 100 || nExpWidth == 3 )
+ {
+ *pBuf++ = nExp/100 + '0';
+ nExp %= 100;
+ }
+ if( nExp/10 || nExpWidth >= 2 )
+ *pBuf++ = nExp/10 + '0';
+ *pBuf++ = nExp%10 + '0';
+ }
+ *pBuf = 0;
+}
+
+// Die Zahl wird unformatiert mit der angegebenen Anzahl NK-Stellen
+// aufbereitet. Evtl. wird ein Minus vorangestellt.
+// Diese Routine ist public, weil sie auch von den Put-Funktionen
+// der Klasse SbxImpSTRING verwendet wird.
+
+#ifdef _MSC_VER
+#pragma optimize( "", off )
+#endif
+
+void ImpCvtNum( double nNum, short nPrec, XubString& rRes, BOOL bCoreString )
+{
+ char *q;
+ char cBuf[ 40 ], *p = cBuf;
+
+ sal_Unicode cDecimalSep, cThousandSep;
+ ImpGetIntntlSep( cDecimalSep, cThousandSep );
+ if( bCoreString )
+ cDecimalSep = '.';
+
+ if( nNum < 0.0 ) {
+ nNum = -nNum;
+ *p++ = '-';
+ }
+ double dMaxNumWithoutExp = (nPrec == 6) ? 1E6 : 1E14;
+ myftoa( nNum, p, nPrec,( nNum &&( nNum < 1E-1 || nNum > dMaxNumWithoutExp ) ) ? 4:0,
+ FALSE, TRUE, cDecimalSep );
+ // Trailing Zeroes weg:
+ for( p = cBuf; *p &&( *p != 'E' ); p++ ) {}
+ q = p; p--;
+ while( nPrec && *p == '0' ) nPrec--, p--;
+ if( *p == cDecimalSep ) p--;
+ while( *q ) *++p = *q++;
+ *++p = 0;
+ rRes = String::CreateFromAscii( cBuf );
+}
+
+#ifdef _MSC_VER
+#pragma optimize( "", on )
+#endif
+
+BOOL ImpConvStringExt( XubString& rSrc, SbxDataType eTargetType )
+{
+ // Merken, ob ueberhaupt was geaendert wurde
+ BOOL bChanged = FALSE;
+ String aNewString;
+
+ // Nur Spezial-Flle behandeln, als Default tun wir nichts
+ switch( eTargetType )
+ {
+ // Bei Fliesskomma International beruecksichtigen
+ case SbxSINGLE:
+ case SbxDOUBLE:
+ case SbxCURRENCY:
+ {
+ ByteString aBStr( rSrc, RTL_TEXTENCODING_ASCII_US );
+ const char* pChar = aBStr.GetBuffer();
+
+ // Komma besorgen
+ sal_Unicode cDecimalSep, cThousandSep;
+ ImpGetIntntlSep( cDecimalSep, cThousandSep );
+ aNewString = rSrc;
+
+ // Ersetzen, wenn DecimalSep kein '.' (nur den ersten)
+ if( cDecimalSep != (sal_Unicode)'.' )
+ {
+ USHORT nPos = aNewString.Search( cDecimalSep );
+ if( nPos != STRING_NOTFOUND )
+ {
+ aNewString.SetChar( nPos, '.' );
+ bChanged = TRUE;
+ }
+ }
+ break;
+ }
+
+ // Bei BOOL TRUE und FALSE als String pruefen
+ case SbxBOOL:
+ {
+ if( rSrc.EqualsIgnoreCaseAscii( "true" ) )
+ {
+ aNewString = String::CreateFromInt32(SbxTRUE);
+ bChanged = TRUE;
+ }
+ else
+ if( rSrc.EqualsIgnoreCaseAscii( "false" ) )
+ {
+ aNewString = String::CreateFromInt32(SbxFALSE);
+ bChanged = TRUE;
+ }
+ break;
+ }
+ }
+ // String bei Aenderung uebernehmen
+ if( bChanged )
+ rSrc = aNewString;
+ return bChanged;
+}
+
+
+// Formatierte Zahlenausgabe
+// Der Returnwert ist die Anzahl Zeichen, die aus dem
+// Format verwendt wurden.
+
+#ifdef _old_format_code_
+// lasse diesen Code vorl"aufig drin, zum 'abgucken'
+// der bisherigen Implementation
+
+static USHORT printfmtnum( double nNum, XubString& rRes, const XubString& rWFmt )
+{
+ const String& rFmt = rWFmt;
+ char cFill = ' '; // Fuellzeichen
+ char cPre = 0; // Startzeichen( evtl. "$" )
+ short nExpDig= 0; // Anzahl Exponentstellen
+ short nPrec = 0; // Anzahl Nachkommastellen
+ short nWidth = 0; // Zahlenweite gesamnt
+ short nLen; // Laenge konvertierte Zahl
+ BOOL bPoint = FALSE; // TRUE: mit 1000er Kommas
+ BOOL bTrail = FALSE; // TRUE, wenn folgendes Minus
+ BOOL bSign = FALSE; // TRUE: immer mit Vorzeichen
+ BOOL bNeg = FALSE; // TRUE: Zahl ist negativ
+ char cBuf [1024]; // Zahlenpuffer
+ char * p;
+ const char* pFmt = rFmt;
+ rRes.Erase();
+ // $$ und ** abfangen. Einfach wird als Zeichen ausgegeben.
+ if( *pFmt == '$' )
+ if( *++pFmt != '$' ) rRes += '$';
+ if( *pFmt == '*' )
+ if( *++pFmt != '*' ) rRes += '*';
+
+ switch( *pFmt++ )
+ {
+ case 0:
+ break;
+ case '+':
+ bSign = TRUE; nWidth++; break;
+ case '*':
+ nWidth++; cFill = '*';
+ if( *pFmt == '$' ) nWidth++, pFmt++, cPre = '$';
+ break;
+ case '$':
+ nWidth++; cPre = '$'; break;
+ case '#':
+ case '.':
+ case ',':
+ pFmt--; break;
+ }
+ // Vorkomma:
+ for( ;; )
+ {
+ while( *pFmt == '#' ) pFmt++, nWidth++;
+ // 1000er Kommas?
+ if( *pFmt == ',' )
+ {
+ nWidth++; pFmt++; bPoint = TRUE;
+ } else break;
+ }
+ // Nachkomma:
+ if( *pFmt == '.' )
+ {
+ while( *++pFmt == '#' ) nPrec++;
+ nWidth += nPrec + 1;
+ }
+ // Exponent:
+ while( *pFmt == '^' )
+ pFmt++, nExpDig++, nWidth++;
+ // Folgendes Minus:
+ if( !bSign && *pFmt == '-' )
+ pFmt++, bTrail = TRUE;
+
+ // Zahl konvertieren:
+ if( nPrec > 15 ) nPrec = 15;
+ if( nNum < 0.0 ) nNum = -nNum, bNeg = TRUE;
+ p = cBuf;
+ if( bSign ) *p++ = bNeg ? '-' : '+';
+ myftoa( nNum, p, nPrec, nExpDig, bPoint, FALSE );
+ nLen = strlen( cBuf );
+
+ // Ueberlauf?
+ if( cPre ) nLen++;
+ if( nLen > nWidth ) rRes += '%';
+ else {
+ nWidth -= nLen;
+ while( nWidth-- ) rRes += (xub_Unicode)cFill;
+ if( cPre ) rRes += (xub_Unicode)cPre;
+ }
+ rRes += (xub_Unicode*)&(cBuf[0]);
+ if( bTrail )
+ rRes += bNeg ? '-' : ' ';
+
+ return (USHORT) ( pFmt - (const char*) rFmt );
+}
+
+#endif //_old_format_code_
+
+static USHORT printfmtstr( const XubString& rStr, XubString& rRes, const XubString& rFmt )
+{
+ const xub_Unicode* pStr = rStr.GetBuffer();
+ const xub_Unicode* pFmtStart = rFmt.GetBuffer();
+ const xub_Unicode* pFmt = pFmtStart;
+ rRes.Erase();
+ switch( *pFmt )
+ {
+ case '!':
+ rRes += *pStr++; pFmt++; break;
+ case '\\':
+ do
+ {
+ rRes += *pStr ? *pStr++ : static_cast< xub_Unicode >(' ');
+ pFmt++;
+ } while( *pFmt != '\\' );
+ rRes += *pStr ? *pStr++ : static_cast< xub_Unicode >(' ');
+ pFmt++; break;
+ case '&':
+ rRes = rStr;
+ pFmt++; break;
+ default:
+ rRes = rStr;
+ break;
+ }
+ return (USHORT) ( pFmt - pFmtStart );
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+BOOL SbxValue::Scan( const XubString& rSrc, USHORT* pLen )
+{
+ SbxError eRes = SbxERR_OK;
+ if( !CanWrite() )
+ eRes = SbxERR_PROP_READONLY;
+ else
+ {
+ double n;
+ SbxDataType t;
+ eRes = ImpScan( rSrc, n, t, pLen );
+ if( eRes == SbxERR_OK )
+ {
+ if( !IsFixed() )
+ SetType( t );
+ PutDouble( n );
+ }
+ }
+ if( eRes )
+ {
+ SetError( eRes ); return FALSE;
+ }
+ else
+ return TRUE;
+}
+
+void SbxValue::Format( XubString& rRes, const XubString* pFmt ) const
+{
+ short nComma;
+ double d;
+ SbxDataType eType = GetType();
+ switch( eType )
+ {
+ case SbxCHAR:
+ case SbxBYTE:
+ case SbxINTEGER:
+ case SbxUSHORT:
+ case SbxLONG:
+ case SbxULONG:
+ case SbxINT:
+ case SbxUINT:
+ case SbxNULL: // #45929 NULL mit durchschummeln
+ nComma = 0; goto cvt;
+ case SbxSINGLE:
+ nComma = 6; goto cvt;
+ case SbxDOUBLE:
+ nComma = 14;
+
+ cvt:
+ if( eType != SbxNULL )
+ d = GetDouble();
+
+ // #45355 weiterer Einsprungpunkt fuer isnumeric-String
+ cvt2:
+ if( pFmt )
+ {
+ // hole die 'statischen' Daten f"ur Sbx
+ SbxAppData* pData = GetSbxData_Impl();
+
+ LanguageType eLangType = GetpApp()->GetSettings().GetLanguage();
+ if( pData->pBasicFormater )
+ {
+ if( pData->eBasicFormaterLangType != eLangType )
+ {
+ delete pData->pBasicFormater;
+ pData->pBasicFormater = NULL;
+ }
+ }
+ pData->eBasicFormaterLangType = eLangType;
+
+ // falls bisher noch kein BasicFormater-Objekt
+ // existiert, so erzeuge dieses
+ if( !pData->pBasicFormater )
+ {
+ SvtSysLocale aSysLocale;
+ const LocaleDataWrapper& rData = aSysLocale.GetLocaleData();
+ sal_Unicode cComma = rData.getNumDecimalSep().GetBuffer()[0];
+ sal_Unicode c1000 = rData.getNumThousandSep().GetBuffer()[0];
+ String aCurrencyStrg = rData.getCurrSymbol();
+
+ // Initialisierung des Basic-Formater-Hilfsobjekts:
+ // hole die Resourcen f"ur die vordefinierten Ausgaben
+ // des Format()-Befehls, z.B. f"ur "On/Off".
+ String aOnStrg = String( BasicResId(
+ STR_BASICKEY_FORMAT_ON ) );
+ String aOffStrg = String( BasicResId(
+ STR_BASICKEY_FORMAT_OFF) );
+ String aYesStrg = String( BasicResId(
+ STR_BASICKEY_FORMAT_YES) );
+ String aNoStrg = String( BasicResId(
+ STR_BASICKEY_FORMAT_NO) );
+ String aTrueStrg = String( BasicResId(
+ STR_BASICKEY_FORMAT_TRUE) );
+ String aFalseStrg = String( BasicResId(
+ STR_BASICKEY_FORMAT_FALSE) );
+ String aCurrencyFormatStrg = String( BasicResId(
+ STR_BASICKEY_FORMAT_CURRENCY) );
+ // erzeuge das Basic-Formater-Objekt
+ pData->pBasicFormater
+ = new SbxBasicFormater( cComma,c1000,aOnStrg,aOffStrg,
+ aYesStrg,aNoStrg,aTrueStrg,aFalseStrg,
+ aCurrencyStrg,aCurrencyFormatStrg );
+ }
+ // Bem.: Aus Performance-Gr"unden wird nur EIN BasicFormater-
+ // Objekt erzeugt und 'gespeichert', dadurch erspart man
+ // sich das teure Resourcen-Laden (f"ur landesspezifische
+ // vordefinierte Ausgaben, z.B. "On/Off") und die st"andige
+ // String-Erzeugungs Operationen.
+ // ABER: dadurch ist dieser Code NICHT multithreading f"ahig !
+
+ // hier gibt es Probleme mit ;;;Null, da diese Methode nur aufgerufen
+ // wird, wenn der SbxValue eine Zahl ist !!!
+ // dazu koennte: pData->pBasicFormater->BasicFormatNull( *pFmt ); aufgerufen werden !
+ if( eType != SbxNULL )
+ {
+ rRes = pData->pBasicFormater->BasicFormat( d ,*pFmt );
+ }
+ else
+ {
+ rRes = pData->pBasicFormater->BasicFormatNull( *pFmt );
+ }
+
+ // Die alte Implementierung:
+ //old: printfmtnum( GetDouble(), rRes, *pFmt );
+ }
+ else
+ ImpCvtNum( GetDouble(), nComma, rRes );
+ break;
+ case SbxSTRING:
+ if( pFmt )
+ {
+ // #45355 wenn es numerisch ist, muss gewandelt werden
+ if( IsNumericRTL() )
+ {
+ ScanNumIntnl( GetString(), d, /*bSingle*/FALSE );
+ goto cvt2;
+ }
+ else
+ {
+ // Sonst String-Formatierung
+ printfmtstr( GetString(), rRes, *pFmt );
+ }
+ }
+ else
+ rRes = GetString();
+ break;
+ default:
+ rRes = GetString();
+ }
+}
+
+