2000-09-18 15:18:56 +00:00
|
|
|
|
/*************************************************************************
|
|
|
|
|
*
|
2005-09-29 15:35:53 +00:00
|
|
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
2005-09-29 11:43:39 +00:00
|
|
|
|
*
|
2005-09-29 15:35:53 +00:00
|
|
|
|
* $RCSfile: sbxmod.cxx,v $
|
2005-09-29 11:43:39 +00:00
|
|
|
|
*
|
2006-11-03 14:11:10 +00:00
|
|
|
|
* $Revision: 1.36 $
|
2000-09-18 15:18:56 +00:00
|
|
|
|
*
|
2006-11-03 14:11:10 +00:00
|
|
|
|
* last change: $Author: vg $ $Date: 2006-11-03 15:10:25 $
|
2000-09-18 15:18:56 +00:00
|
|
|
|
*
|
2005-09-29 15:35:53 +00:00
|
|
|
|
* The Contents of this file are made available subject to
|
|
|
|
|
* the terms of GNU Lesser General Public License Version 2.1.
|
2000-09-18 15:18:56 +00:00
|
|
|
|
*
|
|
|
|
|
*
|
2005-09-29 15:35:53 +00:00
|
|
|
|
* GNU Lesser General Public License Version 2.1
|
|
|
|
|
* =============================================
|
|
|
|
|
* Copyright 2005 by Sun Microsystems, Inc.
|
|
|
|
|
* 901 San Antonio Road, Palo Alto, CA 94303, USA
|
2000-09-18 15:18:56 +00:00
|
|
|
|
*
|
2005-09-29 15:35:53 +00:00
|
|
|
|
* 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.
|
2000-09-18 15:18:56 +00:00
|
|
|
|
*
|
2005-09-29 15:35:53 +00:00
|
|
|
|
* 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.
|
2000-09-18 15:18:56 +00:00
|
|
|
|
*
|
2005-09-29 15:35:53 +00:00
|
|
|
|
* 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
|
2000-09-18 15:18:56 +00:00
|
|
|
|
*
|
|
|
|
|
************************************************************************/
|
|
|
|
|
|
2006-09-17 09:00:50 +00:00
|
|
|
|
// MARKER(update_precomp.py): autogen include statement, do not remove
|
|
|
|
|
#include "precompiled_basic.hxx"
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
#include <list>
|
|
|
|
|
|
|
|
|
|
#include <vos/macros.hxx>
|
|
|
|
|
#include <vcl/svapp.hxx>
|
|
|
|
|
|
|
|
|
|
#ifndef _STREAM_HXX //autogen
|
|
|
|
|
#include <tools/stream.hxx>
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef _SFXBRDCST_HXX //autogen
|
|
|
|
|
#include <svtools/brdcst.hxx>
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef _SHL_HXX //autogen
|
|
|
|
|
#include <tools/shl.hxx>
|
|
|
|
|
#endif
|
2005-04-13 08:10:40 +00:00
|
|
|
|
#include <sbx.hxx>
|
2000-09-18 15:18:56 +00:00
|
|
|
|
#include "sb.hxx"
|
|
|
|
|
#include <sbjsmeth.hxx>
|
|
|
|
|
#include "sbjsmod.hxx"
|
|
|
|
|
#include "sbintern.hxx"
|
|
|
|
|
#include "image.hxx"
|
|
|
|
|
#include "opcodes.hxx"
|
|
|
|
|
#include "runtime.hxx"
|
|
|
|
|
#include "token.hxx"
|
|
|
|
|
#include "sbunoobj.hxx"
|
|
|
|
|
#include <hilight.hxx>
|
|
|
|
|
#include <basrdll.hxx>
|
|
|
|
|
|
2004-11-15 12:29:17 +00:00
|
|
|
|
#ifndef _VOS_MUTEX_HXX_
|
|
|
|
|
#include <vos/mutex.hxx>
|
|
|
|
|
#endif
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// for the bsearch
|
|
|
|
|
#ifdef WNT
|
|
|
|
|
#define CDECL _cdecl
|
|
|
|
|
#endif
|
2006-06-19 16:40:39 +00:00
|
|
|
|
#if defined(UNX)
|
2000-09-18 15:18:56 +00:00
|
|
|
|
#define CDECL
|
|
|
|
|
#endif
|
2004-03-17 12:32:25 +00:00
|
|
|
|
#ifdef UNX
|
|
|
|
|
#include <sys/resource.h>
|
|
|
|
|
#endif
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TYPEINIT1(SbModule,SbxObject)
|
|
|
|
|
TYPEINIT1(SbMethod,SbxMethod)
|
|
|
|
|
TYPEINIT1(SbProperty,SbxProperty)
|
2005-03-29 10:48:33 +00:00
|
|
|
|
TYPEINIT1(SbProcedureProperty,SbxProperty)
|
2000-09-18 15:18:56 +00:00
|
|
|
|
TYPEINIT1(SbJScriptModule,SbModule)
|
|
|
|
|
TYPEINIT1(SbJScriptMethod,SbMethod)
|
|
|
|
|
|
|
|
|
|
SV_DECL_VARARR(SbiBreakpoints,USHORT,4,4)
|
|
|
|
|
SV_IMPL_VARARR(SbiBreakpoints,USHORT)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SV_IMPL_VARARR(HighlightPortions, HighlightPortion)
|
|
|
|
|
|
|
|
|
|
// ##########################################################################
|
|
|
|
|
// ACHTUNG!!! Alle Woerter dieser Tabelle m<>ssen KLEIN geschrieben werden!!!
|
|
|
|
|
// ##########################################################################
|
2006-06-19 16:40:39 +00:00
|
|
|
|
static const char* strListBasicKeyWords[] = {
|
2000-09-18 15:18:56 +00:00
|
|
|
|
"access",
|
|
|
|
|
"alias",
|
|
|
|
|
"and",
|
|
|
|
|
"any",
|
|
|
|
|
"append",
|
|
|
|
|
"as",
|
|
|
|
|
"base",
|
|
|
|
|
"binary",
|
|
|
|
|
"boolean",
|
2004-03-17 12:32:25 +00:00
|
|
|
|
"byref",
|
2006-05-05 07:47:08 +00:00
|
|
|
|
"byte",
|
2000-09-18 15:18:56 +00:00
|
|
|
|
"byval",
|
|
|
|
|
"call",
|
|
|
|
|
"case",
|
|
|
|
|
"cdecl",
|
2005-03-29 10:48:33 +00:00
|
|
|
|
"classmodule",
|
2000-09-18 15:18:56 +00:00
|
|
|
|
"close",
|
|
|
|
|
"compare",
|
2005-03-29 10:48:33 +00:00
|
|
|
|
"compatible",
|
2000-09-18 15:18:56 +00:00
|
|
|
|
"const",
|
|
|
|
|
"currency",
|
|
|
|
|
"date",
|
|
|
|
|
"declare",
|
|
|
|
|
"defbool",
|
|
|
|
|
"defcur",
|
|
|
|
|
"defdate",
|
|
|
|
|
"defdbl",
|
|
|
|
|
"deferr",
|
|
|
|
|
"defint",
|
|
|
|
|
"deflng",
|
|
|
|
|
"defobj",
|
|
|
|
|
"defsng",
|
|
|
|
|
"defstr",
|
|
|
|
|
"defvar",
|
|
|
|
|
"dim",
|
|
|
|
|
"do",
|
|
|
|
|
"double",
|
|
|
|
|
"each",
|
|
|
|
|
"else",
|
|
|
|
|
"elseif",
|
|
|
|
|
"end",
|
2004-11-15 15:34:15 +00:00
|
|
|
|
"end enum",
|
2000-09-18 15:18:56 +00:00
|
|
|
|
"end function",
|
|
|
|
|
"end if",
|
|
|
|
|
"end select",
|
|
|
|
|
"end sub",
|
|
|
|
|
"end type",
|
|
|
|
|
"endif",
|
2004-11-15 15:34:15 +00:00
|
|
|
|
"enum",
|
2000-09-18 15:18:56 +00:00
|
|
|
|
"eqv",
|
|
|
|
|
"erase",
|
|
|
|
|
"error",
|
|
|
|
|
"exit",
|
|
|
|
|
"explicit",
|
|
|
|
|
"for",
|
|
|
|
|
"function",
|
2005-03-29 10:48:33 +00:00
|
|
|
|
"get",
|
2000-09-18 15:18:56 +00:00
|
|
|
|
"global",
|
|
|
|
|
"gosub",
|
|
|
|
|
"goto",
|
|
|
|
|
"if",
|
|
|
|
|
"imp",
|
2005-03-29 10:48:33 +00:00
|
|
|
|
"implements",
|
2000-09-18 15:18:56 +00:00
|
|
|
|
"in",
|
|
|
|
|
"input",
|
|
|
|
|
"integer",
|
|
|
|
|
"is",
|
|
|
|
|
"let",
|
|
|
|
|
"lib"
|
|
|
|
|
"line",
|
|
|
|
|
"line input",
|
|
|
|
|
"local",
|
|
|
|
|
"lock",
|
|
|
|
|
"long",
|
|
|
|
|
"loop",
|
|
|
|
|
"lprint",
|
|
|
|
|
"lset",
|
|
|
|
|
"mod",
|
|
|
|
|
"name",
|
|
|
|
|
"new",
|
|
|
|
|
"next",
|
|
|
|
|
"not",
|
|
|
|
|
"object",
|
|
|
|
|
"on",
|
|
|
|
|
"open",
|
|
|
|
|
"option",
|
|
|
|
|
"optional",
|
|
|
|
|
"or",
|
|
|
|
|
"output",
|
|
|
|
|
"preserve",
|
|
|
|
|
"print",
|
|
|
|
|
"private",
|
2005-03-29 10:48:33 +00:00
|
|
|
|
"property",
|
2000-09-18 15:18:56 +00:00
|
|
|
|
"public",
|
|
|
|
|
"random",
|
|
|
|
|
"read",
|
|
|
|
|
"redim",
|
|
|
|
|
"rem",
|
|
|
|
|
"resume",
|
|
|
|
|
"return",
|
|
|
|
|
"rset",
|
|
|
|
|
"select",
|
|
|
|
|
"set",
|
|
|
|
|
"shared",
|
|
|
|
|
"single",
|
|
|
|
|
"static",
|
|
|
|
|
"step",
|
|
|
|
|
"stop",
|
|
|
|
|
"string",
|
|
|
|
|
"sub",
|
|
|
|
|
"system",
|
|
|
|
|
"text",
|
|
|
|
|
"then",
|
|
|
|
|
"to",
|
|
|
|
|
"type",
|
2005-03-29 10:48:33 +00:00
|
|
|
|
"typeof",
|
2000-09-18 15:18:56 +00:00
|
|
|
|
"until",
|
|
|
|
|
"variant",
|
|
|
|
|
"wend",
|
|
|
|
|
"while",
|
|
|
|
|
"with",
|
|
|
|
|
"write",
|
|
|
|
|
"xor"
|
|
|
|
|
};
|
|
|
|
|
|
2006-06-19 16:40:39 +00:00
|
|
|
|
extern "C" int CDECL compare_strings( const void *arg1, const void *arg2 )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
return strcmp( (char *)arg1, *(char **)arg2 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
// Ein BASIC-Modul hat EXTSEARCH gesetzt, damit die im Modul enthaltenen
|
|
|
|
|
// Elemente von anderen Modulen aus gefunden werden koennen.
|
|
|
|
|
|
|
|
|
|
SbModule::SbModule( const String& rName )
|
|
|
|
|
: SbxObject( String( RTL_CONSTASCII_USTRINGPARAM("StarBASICModule") ) ),
|
2005-03-29 10:48:33 +00:00
|
|
|
|
pImage( NULL ), pBreaks( NULL ), pClassData( NULL )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
SetName( rName );
|
|
|
|
|
SetFlag( SBX_EXTSEARCH | SBX_GBLSEARCH );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SbModule::~SbModule()
|
|
|
|
|
{
|
|
|
|
|
if( pImage )
|
|
|
|
|
delete pImage;
|
|
|
|
|
if( pBreaks )
|
|
|
|
|
delete pBreaks;
|
2005-03-29 10:48:33 +00:00
|
|
|
|
if( pClassData )
|
|
|
|
|
delete pClassData;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL SbModule::IsCompiled() const
|
|
|
|
|
{
|
|
|
|
|
return BOOL( pImage != 0 );
|
|
|
|
|
}
|
|
|
|
|
|
2004-03-17 12:32:25 +00:00
|
|
|
|
const SbxObject* SbModule::FindType( String aTypeName ) const
|
|
|
|
|
{
|
|
|
|
|
return pImage ? pImage->FindType( aTypeName ) : NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// Aus dem Codegenerator: Loeschen des Images und Invalidieren der Entries
|
|
|
|
|
|
|
|
|
|
void SbModule::StartDefinitions()
|
|
|
|
|
{
|
|
|
|
|
delete pImage; pImage = NULL;
|
2005-03-29 10:48:33 +00:00
|
|
|
|
if( pClassData )
|
|
|
|
|
pClassData->clear();
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// Methoden und Properties bleiben erhalten, sind jedoch ungueltig
|
|
|
|
|
// schliesslich sind ja u.U. die Infos belegt
|
|
|
|
|
USHORT i;
|
|
|
|
|
for( i = 0; i < pMethods->Count(); i++ )
|
|
|
|
|
{
|
|
|
|
|
SbMethod* p = PTR_CAST(SbMethod,pMethods->Get( i ) );
|
|
|
|
|
if( p )
|
|
|
|
|
p->bInvalid = TRUE;
|
|
|
|
|
}
|
|
|
|
|
for( i = 0; i < pProps->Count(); )
|
|
|
|
|
{
|
|
|
|
|
SbProperty* p = PTR_CAST(SbProperty,pProps->Get( i ) );
|
|
|
|
|
if( p )
|
|
|
|
|
pProps->Remove( i );
|
|
|
|
|
else
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Methode anfordern/anlegen
|
|
|
|
|
|
|
|
|
|
SbMethod* SbModule::GetMethod( const String& rName, SbxDataType t )
|
|
|
|
|
{
|
|
|
|
|
SbxVariable* p = pMethods->Find( rName, SbxCLASS_METHOD );
|
|
|
|
|
SbMethod* pMeth = p ? PTR_CAST(SbMethod,p) : NULL;
|
|
|
|
|
if( p && !pMeth )
|
|
|
|
|
pMethods->Remove( p );
|
|
|
|
|
if( !pMeth )
|
|
|
|
|
{
|
|
|
|
|
pMeth = new SbMethod( rName, t, this );
|
|
|
|
|
pMeth->SetParent( this );
|
|
|
|
|
pMeth->SetFlags( SBX_READ );
|
|
|
|
|
pMethods->Put( pMeth, pMethods->Count() );
|
|
|
|
|
StartListening( pMeth->GetBroadcaster(), TRUE );
|
|
|
|
|
}
|
|
|
|
|
// Per Default ist die Methode GUELTIG, da sie auch vom Compiler
|
|
|
|
|
// (Codegenerator) erzeugt werden kann
|
|
|
|
|
pMeth->bInvalid = FALSE;
|
|
|
|
|
pMeth->ResetFlag( SBX_FIXED );
|
|
|
|
|
pMeth->SetFlag( SBX_WRITE );
|
|
|
|
|
pMeth->SetType( t );
|
|
|
|
|
pMeth->ResetFlag( SBX_WRITE );
|
|
|
|
|
if( t != SbxVARIANT )
|
|
|
|
|
pMeth->SetFlag( SBX_FIXED );
|
|
|
|
|
return pMeth;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Property anfordern/anlegen
|
|
|
|
|
|
|
|
|
|
SbProperty* SbModule::GetProperty( const String& rName, SbxDataType t )
|
|
|
|
|
{
|
|
|
|
|
SbxVariable* p = pProps->Find( rName, SbxCLASS_PROPERTY );
|
|
|
|
|
SbProperty* pProp = p ? PTR_CAST(SbProperty,p) : NULL;
|
|
|
|
|
if( p && !pProp )
|
|
|
|
|
pProps->Remove( p );
|
|
|
|
|
if( !pProp )
|
|
|
|
|
{
|
|
|
|
|
pProp = new SbProperty( rName, t, this );
|
|
|
|
|
pProp->SetFlag( SBX_READWRITE );
|
|
|
|
|
pProp->SetParent( this );
|
|
|
|
|
pProps->Put( pProp, pProps->Count() );
|
|
|
|
|
StartListening( pProp->GetBroadcaster(), TRUE );
|
|
|
|
|
}
|
|
|
|
|
return pProp;
|
|
|
|
|
}
|
|
|
|
|
|
2004-11-02 10:52:32 +00:00
|
|
|
|
SbProcedureProperty* SbModule::GetProcedureProperty
|
|
|
|
|
( const String& rName, SbxDataType t )
|
|
|
|
|
{
|
|
|
|
|
SbxVariable* p = pProps->Find( rName, SbxCLASS_PROPERTY );
|
|
|
|
|
SbProcedureProperty* pProp = p ? PTR_CAST(SbProcedureProperty,p) : NULL;
|
|
|
|
|
if( p && !pProp )
|
|
|
|
|
pProps->Remove( p );
|
|
|
|
|
if( !pProp )
|
|
|
|
|
{
|
|
|
|
|
pProp = new SbProcedureProperty( rName, t );
|
|
|
|
|
pProp->SetFlag( SBX_READWRITE );
|
|
|
|
|
pProp->SetParent( this );
|
|
|
|
|
pProps->Put( pProp, pProps->Count() );
|
|
|
|
|
StartListening( pProp->GetBroadcaster(), TRUE );
|
|
|
|
|
}
|
|
|
|
|
return pProp;
|
|
|
|
|
}
|
|
|
|
|
|
2005-03-29 10:48:33 +00:00
|
|
|
|
SbIfaceMapperMethod* SbModule::GetIfaceMapperMethod
|
|
|
|
|
( const String& rName, SbMethod* pImplMeth )
|
|
|
|
|
{
|
|
|
|
|
SbxVariable* p = pMethods->Find( rName, SbxCLASS_METHOD );
|
|
|
|
|
SbIfaceMapperMethod* pMapperMethod = p ? PTR_CAST(SbIfaceMapperMethod,p) : NULL;
|
|
|
|
|
if( p && !pMapperMethod )
|
|
|
|
|
pMethods->Remove( p );
|
|
|
|
|
if( !pMapperMethod )
|
|
|
|
|
{
|
|
|
|
|
pMapperMethod = new SbIfaceMapperMethod( rName, pImplMeth );
|
|
|
|
|
pMapperMethod->SetParent( this );
|
|
|
|
|
pMapperMethod->SetFlags( SBX_READ );
|
|
|
|
|
pMethods->Put( pMapperMethod, pMethods->Count() );
|
|
|
|
|
}
|
|
|
|
|
pMapperMethod->bInvalid = FALSE;
|
|
|
|
|
return pMapperMethod;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SbIfaceMapperMethod::~SbIfaceMapperMethod()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TYPEINIT1(SbIfaceMapperMethod,SbMethod)
|
|
|
|
|
|
2004-11-02 10:52:32 +00:00
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// Aus dem Codegenerator: Ungueltige Eintraege entfernen
|
|
|
|
|
|
|
|
|
|
void SbModule::EndDefinitions( BOOL bNewState )
|
|
|
|
|
{
|
|
|
|
|
for( USHORT i = 0; i < pMethods->Count(); )
|
|
|
|
|
{
|
|
|
|
|
SbMethod* p = PTR_CAST(SbMethod,pMethods->Get( i ) );
|
|
|
|
|
if( p )
|
|
|
|
|
{
|
|
|
|
|
if( p->bInvalid )
|
|
|
|
|
pMethods->Remove( p );
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
p->bInvalid = bNewState;
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
}
|
2005-03-29 10:48:33 +00:00
|
|
|
|
else
|
|
|
|
|
i++;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
SetModified( TRUE );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SbModule::Clear()
|
|
|
|
|
{
|
|
|
|
|
delete pImage; pImage = NULL;
|
2005-03-29 10:48:33 +00:00
|
|
|
|
if( pClassData )
|
|
|
|
|
pClassData->clear();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
SbxObject::Clear();
|
|
|
|
|
}
|
|
|
|
|
|
2004-11-15 15:34:15 +00:00
|
|
|
|
|
|
|
|
|
SbxVariable* SbModule::Find( const XubString& rName, SbxClassType t )
|
|
|
|
|
{
|
|
|
|
|
SbxVariable* pRes = SbxObject::Find( rName, t );
|
|
|
|
|
if( !pRes && pImage )
|
|
|
|
|
{
|
|
|
|
|
SbiInstance* pInst = pINST;
|
|
|
|
|
if( pInst && pInst->IsCompatibility() )
|
|
|
|
|
{
|
|
|
|
|
// Put enum types as objects into module,
|
|
|
|
|
// allows MyEnum.First notation
|
|
|
|
|
SbxArrayRef xArray = pImage->GetEnums();
|
|
|
|
|
if( xArray.Is() )
|
|
|
|
|
{
|
|
|
|
|
SbxVariable* pEnumVar = xArray->Find( rName, SbxCLASS_DONTCARE );
|
|
|
|
|
SbxObject* pEnumObject = PTR_CAST( SbxObject, pEnumVar );
|
|
|
|
|
if( pEnumObject )
|
|
|
|
|
{
|
|
|
|
|
bool bPrivate = pEnumObject->IsSet( SBX_PRIVATE );
|
|
|
|
|
String aEnumName = pEnumObject->GetName();
|
|
|
|
|
|
|
|
|
|
pRes = new SbxVariable( SbxOBJECT );
|
|
|
|
|
pRes->SetName( aEnumName );
|
|
|
|
|
pRes->SetParent( this );
|
|
|
|
|
pRes->SetFlag( SBX_READ );
|
|
|
|
|
if( bPrivate )
|
|
|
|
|
pRes->SetFlag( SBX_PRIVATE );
|
|
|
|
|
pRes->PutObject( pEnumObject );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return pRes;
|
|
|
|
|
}
|
|
|
|
|
|
2003-04-23 15:56:27 +00:00
|
|
|
|
const ::rtl::OUString& SbModule::GetSource32() const
|
|
|
|
|
{
|
|
|
|
|
return aOUSource;
|
|
|
|
|
}
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
const String& SbModule::GetSource() const
|
|
|
|
|
{
|
2003-04-23 15:56:27 +00:00
|
|
|
|
static String aRetStr;
|
|
|
|
|
aRetStr = aOUSource;
|
|
|
|
|
return aRetStr;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Parent und BASIC sind eins!
|
|
|
|
|
|
|
|
|
|
void SbModule::SetParent( SbxObject* p )
|
|
|
|
|
{
|
2004-11-02 10:52:32 +00:00
|
|
|
|
// #118083: Assertion is not valid any more
|
|
|
|
|
// DBG_ASSERT( !p || p->IsA( TYPE(StarBASIC) ), "SbModules nur in BASIC eintragen" );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
pParent = p;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SbModule::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
|
|
|
|
|
const SfxHint& rHint, const TypeId& rHintType )
|
|
|
|
|
{
|
|
|
|
|
const SbxHint* pHint = PTR_CAST(SbxHint,&rHint);
|
|
|
|
|
if( pHint )
|
|
|
|
|
{
|
|
|
|
|
SbxVariable* pVar = pHint->GetVar();
|
|
|
|
|
SbProperty* pProp = PTR_CAST(SbProperty,pVar);
|
|
|
|
|
SbMethod* pMeth = PTR_CAST(SbMethod,pVar);
|
|
|
|
|
if( pProp )
|
|
|
|
|
{
|
|
|
|
|
if( pProp->GetModule() != this )
|
|
|
|
|
SetError( SbxERR_BAD_ACTION );
|
|
|
|
|
}
|
|
|
|
|
else if( pMeth )
|
|
|
|
|
{
|
|
|
|
|
if( pHint->GetId() == SBX_HINT_DATAWANTED )
|
|
|
|
|
{
|
|
|
|
|
if( pMeth->bInvalid && !Compile() )
|
|
|
|
|
// Auto-Compile hat nicht geklappt!
|
|
|
|
|
StarBASIC::Error( SbERR_BAD_PROP_VALUE );
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Aufruf eines Unterprogramms
|
|
|
|
|
SbModule* pOld = pMOD;
|
|
|
|
|
pMOD = this;
|
|
|
|
|
Run( (SbMethod*) pVar );
|
|
|
|
|
pMOD = pOld;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Das Setzen der Source macht das Image ungueltig
|
|
|
|
|
// und scant die Methoden-Definitionen neu ein
|
|
|
|
|
|
|
|
|
|
void SbModule::SetSource( const String& r )
|
|
|
|
|
{
|
2003-04-23 15:56:27 +00:00
|
|
|
|
SetSource32( r );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SbModule::SetSource32( const ::rtl::OUString& r )
|
|
|
|
|
{
|
|
|
|
|
aOUSource = r;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
StartDefinitions();
|
|
|
|
|
SbiTokenizer aTok( r );
|
|
|
|
|
while( !aTok.IsEof() )
|
|
|
|
|
{
|
|
|
|
|
SbiToken eEndTok = NIL;
|
|
|
|
|
|
|
|
|
|
// Suchen nach SUB oder FUNCTION
|
|
|
|
|
SbiToken eLastTok = NIL;
|
|
|
|
|
while( !aTok.IsEof() )
|
|
|
|
|
{
|
|
|
|
|
// #32385: Nicht bei declare
|
|
|
|
|
SbiToken eCurTok = aTok.Next();
|
|
|
|
|
if( eLastTok != DECLARE )
|
|
|
|
|
{
|
|
|
|
|
if( eCurTok == SUB )
|
|
|
|
|
{
|
|
|
|
|
eEndTok = ENDSUB; break;
|
|
|
|
|
}
|
|
|
|
|
if( eCurTok == FUNCTION )
|
|
|
|
|
{
|
|
|
|
|
eEndTok = ENDFUNC; break;
|
|
|
|
|
}
|
2005-03-29 10:48:33 +00:00
|
|
|
|
if( eCurTok == PROPERTY )
|
|
|
|
|
{
|
|
|
|
|
eEndTok = ENDPROPERTY; break;
|
|
|
|
|
}
|
2004-11-15 15:34:15 +00:00
|
|
|
|
if( eCurTok == OPTION )
|
|
|
|
|
{
|
|
|
|
|
eCurTok = aTok.Next();
|
|
|
|
|
if( eCurTok == COMPATIBLE )
|
|
|
|
|
aTok.SetCompatible( true );
|
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
eLastTok = eCurTok;
|
|
|
|
|
}
|
|
|
|
|
// Definition der Methode
|
2006-10-12 13:26:01 +00:00
|
|
|
|
SbMethod* pMeth = NULL;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
if( eEndTok != NIL )
|
|
|
|
|
{
|
|
|
|
|
USHORT nLine1 = aTok.GetLine();
|
|
|
|
|
if( aTok.Next() == SYMBOL )
|
|
|
|
|
{
|
2006-06-19 16:40:39 +00:00
|
|
|
|
String aName_( aTok.GetSym() );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
SbxDataType t = aTok.GetType();
|
|
|
|
|
if( t == SbxVARIANT && eEndTok == ENDSUB )
|
|
|
|
|
t = SbxVOID;
|
2006-06-19 16:40:39 +00:00
|
|
|
|
pMeth = GetMethod( aName_, t );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
pMeth->nLine1 = pMeth->nLine2 = nLine1;
|
|
|
|
|
// Die Methode ist erst mal GUELTIG
|
|
|
|
|
pMeth->bInvalid = FALSE;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
eEndTok = NIL;
|
|
|
|
|
}
|
|
|
|
|
// Skip bis END SUB/END FUNCTION
|
|
|
|
|
if( eEndTok != NIL )
|
|
|
|
|
{
|
|
|
|
|
while( !aTok.IsEof() )
|
|
|
|
|
{
|
|
|
|
|
if( aTok.Next() == eEndTok )
|
|
|
|
|
{
|
|
|
|
|
pMeth->nLine2 = aTok.GetLine();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if( aTok.IsEof() )
|
|
|
|
|
pMeth->nLine2 = aTok.GetLine();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
EndDefinitions( TRUE );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SbModule::SetComment( const String& r )
|
|
|
|
|
{
|
|
|
|
|
aComment = r;
|
|
|
|
|
SetModified( TRUE );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SbMethod* SbModule::GetFunctionForLine( USHORT nLine )
|
|
|
|
|
{
|
|
|
|
|
for( USHORT i = 0; i < pMethods->Count(); i++ )
|
|
|
|
|
{
|
|
|
|
|
SbMethod* p = (SbMethod*) pMethods->Get( i );
|
|
|
|
|
if( p->GetSbxId() == SBXID_BASICMETHOD )
|
|
|
|
|
{
|
|
|
|
|
if( nLine >= p->nLine1 && nLine <= p->nLine2 )
|
|
|
|
|
return p;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ausstrahlen eines Hints an alle Basics
|
|
|
|
|
|
|
|
|
|
static void _SendHint( SbxObject* pObj, ULONG nId, SbMethod* p )
|
|
|
|
|
{
|
|
|
|
|
// Selbst ein BASIC?
|
|
|
|
|
if( pObj->IsA( TYPE(StarBASIC) ) && pObj->IsBroadcaster() )
|
|
|
|
|
pObj->GetBroadcaster().Broadcast( SbxHint( nId, p ) );
|
|
|
|
|
// Dann die Unterobjekte fragen
|
|
|
|
|
SbxArray* pObjs = pObj->GetObjects();
|
|
|
|
|
for( USHORT i = 0; i < pObjs->Count(); i++ )
|
|
|
|
|
{
|
|
|
|
|
SbxVariable* pVar = pObjs->Get( i );
|
|
|
|
|
if( pVar->IsA( TYPE(SbxObject) ) )
|
|
|
|
|
_SendHint( PTR_CAST(SbxObject,pVar), nId, p );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void SendHint( SbxObject* pObj, ULONG nId, SbMethod* p )
|
|
|
|
|
{
|
|
|
|
|
while( pObj->GetParent() )
|
|
|
|
|
pObj = pObj->GetParent();
|
|
|
|
|
_SendHint( pObj, nId, p );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// #57841 Uno-Objekte, die in RTL-Funktionen gehalten werden,
|
|
|
|
|
// beim Programm-Ende freigeben, damit nichts gehalten wird.
|
|
|
|
|
void ClearUnoObjectsInRTL_Impl_Rek( StarBASIC* pBasic )
|
|
|
|
|
{
|
|
|
|
|
// return-Wert von CreateUnoService loeschen
|
|
|
|
|
static String aName( RTL_CONSTASCII_USTRINGPARAM("CreateUnoService") );
|
|
|
|
|
SbxVariable* pVar = pBasic->GetRtl()->Find( aName, SbxCLASS_METHOD );
|
|
|
|
|
if( pVar )
|
|
|
|
|
pVar->SbxValue::Clear();
|
|
|
|
|
|
2002-01-08 09:57:34 +00:00
|
|
|
|
// return-Wert von CreateUnoDialog loeschen
|
|
|
|
|
static String aName2( RTL_CONSTASCII_USTRINGPARAM("CreateUnoDialog") );
|
|
|
|
|
pVar = pBasic->GetRtl()->Find( aName2, SbxCLASS_METHOD );
|
|
|
|
|
if( pVar )
|
|
|
|
|
pVar->SbxValue::Clear();
|
|
|
|
|
|
2006-08-04 09:54:10 +00:00
|
|
|
|
// return-Wert von CDec loeschen
|
2004-03-17 12:32:25 +00:00
|
|
|
|
static String aName3( RTL_CONSTASCII_USTRINGPARAM("CDec") );
|
|
|
|
|
pVar = pBasic->GetRtl()->Find( aName3, SbxCLASS_METHOD );
|
|
|
|
|
if( pVar )
|
|
|
|
|
pVar->SbxValue::Clear();
|
|
|
|
|
|
2006-08-04 09:54:10 +00:00
|
|
|
|
// return-Wert von CreateObject loeschen
|
|
|
|
|
static String aName4( RTL_CONSTASCII_USTRINGPARAM("CreateObject") );
|
|
|
|
|
pVar = pBasic->GetRtl()->Find( aName4, SbxCLASS_METHOD );
|
|
|
|
|
if( pVar )
|
|
|
|
|
pVar->SbxValue::Clear();
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// Ueber alle Sub-Basics gehen
|
|
|
|
|
SbxArray* pObjs = pBasic->GetObjects();
|
|
|
|
|
USHORT nCount = pObjs->Count();
|
|
|
|
|
for( USHORT i = 0 ; i < nCount ; i++ )
|
|
|
|
|
{
|
|
|
|
|
SbxVariable* pObjVar = pObjs->Get( i );
|
|
|
|
|
StarBASIC* pSubBasic = PTR_CAST( StarBASIC, pObjVar );
|
|
|
|
|
if( pSubBasic )
|
|
|
|
|
ClearUnoObjectsInRTL_Impl_Rek( pSubBasic );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ClearUnoObjectsInRTL_Impl( StarBASIC* pBasic )
|
|
|
|
|
{
|
|
|
|
|
// #67781 Rueckgabewerte der Uno-Methoden loeschen
|
|
|
|
|
clearUnoMethods();
|
|
|
|
|
|
2003-03-18 15:28:40 +00:00
|
|
|
|
ClearUnoObjectsInRTL_Impl_Rek( pBasic );
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// Oberstes Basic suchen
|
|
|
|
|
SbxObject* p = pBasic;
|
|
|
|
|
while( p->GetParent() )
|
|
|
|
|
p = p->GetParent();
|
2003-03-18 15:28:40 +00:00
|
|
|
|
if( ((StarBASIC*)p) != pBasic )
|
|
|
|
|
ClearUnoObjectsInRTL_Impl_Rek( (StarBASIC*)p );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ausfuehren eines BASIC-Unterprogramms
|
|
|
|
|
USHORT SbModule::Run( SbMethod* pMeth )
|
|
|
|
|
{
|
2004-03-17 12:32:25 +00:00
|
|
|
|
static USHORT nMaxCallLevel = 0;
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
USHORT nRes = 0;
|
|
|
|
|
BOOL bDelInst = BOOL( pINST == NULL );
|
|
|
|
|
StarBASICRef xBasic;
|
|
|
|
|
if( bDelInst )
|
|
|
|
|
{
|
|
|
|
|
// #32779: Basic waehrend der Ausfuehrung festhalten
|
|
|
|
|
xBasic = (StarBASIC*) GetParent();
|
|
|
|
|
|
|
|
|
|
pINST = new SbiInstance( (StarBASIC*) GetParent() );
|
|
|
|
|
|
|
|
|
|
// Error-Stack loeschen
|
|
|
|
|
SbErrorStack*& rErrStack = GetSbData()->pErrStack;
|
|
|
|
|
delete rErrStack;
|
|
|
|
|
rErrStack = NULL;
|
2004-03-17 12:32:25 +00:00
|
|
|
|
|
|
|
|
|
if( nMaxCallLevel == 0 )
|
|
|
|
|
{
|
|
|
|
|
#ifdef UNX
|
|
|
|
|
struct rlimit rl;
|
|
|
|
|
getrlimit ( RLIMIT_STACK, &rl );
|
|
|
|
|
// printf( "RLIMIT_STACK = %ld\n", rl.rlim_cur );
|
|
|
|
|
#endif
|
2006-10-12 13:26:01 +00:00
|
|
|
|
#if defined LINUX
|
2004-03-17 12:32:25 +00:00
|
|
|
|
// Empiric value, 900 = needed bytes/Basic call level
|
|
|
|
|
// for Linux including 10% safety margin
|
|
|
|
|
nMaxCallLevel = rl.rlim_cur / 900;
|
2006-10-12 13:26:01 +00:00
|
|
|
|
#elif defined SOLARIS
|
2004-03-17 12:32:25 +00:00
|
|
|
|
// Empiric value, 1650 = needed bytes/Basic call level
|
|
|
|
|
// for Solaris including 10% safety margin
|
|
|
|
|
nMaxCallLevel = rl.rlim_cur / 1650;
|
2006-10-12 13:26:01 +00:00
|
|
|
|
#elif defined WIN32
|
2004-03-17 12:32:25 +00:00
|
|
|
|
nMaxCallLevel = 5800;
|
|
|
|
|
#else
|
|
|
|
|
nMaxCallLevel = MAXRECURSION;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
2004-03-17 12:32:25 +00:00
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// Rekursion zu tief?
|
2004-03-17 12:32:25 +00:00
|
|
|
|
if( ++pINST->nCallLvl <= nMaxCallLevel )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
// Globale Variable in allen Mods definieren
|
|
|
|
|
GlobalRunInit( /* bBasicStart = */ bDelInst );
|
|
|
|
|
|
|
|
|
|
// Trat ein Compiler-Fehler auf? Dann starten wir nicht
|
|
|
|
|
if( GetSbData()->bGlobalInitErr == FALSE )
|
|
|
|
|
{
|
|
|
|
|
if( bDelInst )
|
|
|
|
|
{
|
|
|
|
|
SendHint( GetParent(), SBX_HINT_BASICSTART, pMeth );
|
|
|
|
|
|
|
|
|
|
// 16.10.96: #31460 Neues Konzept fuer StepInto/Over/Out
|
|
|
|
|
// Erklaerung siehe runtime.cxx bei SbiInstance::CalcBreakCallLevel()
|
|
|
|
|
// BreakCallLevel ermitteln
|
|
|
|
|
pINST->CalcBreakCallLevel( pMeth->GetDebugFlags() );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SbModule* pOldMod = pMOD;
|
|
|
|
|
pMOD = this;
|
|
|
|
|
SbiRuntime* pRt = new SbiRuntime( this, pMeth, pMeth->nStart );
|
|
|
|
|
pRt->pNext = pINST->pRun;
|
2005-09-29 17:38:55 +00:00
|
|
|
|
if( pRt->pNext )
|
|
|
|
|
pRt->pNext->block();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
pINST->pRun = pRt;
|
2006-05-05 09:11:23 +00:00
|
|
|
|
if ( SbiRuntime ::isVBAEnabled() )
|
|
|
|
|
pINST->EnableCompatibility( TRUE );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
while( pRt->Step() ) {}
|
2005-09-29 17:38:55 +00:00
|
|
|
|
if( pRt->pNext )
|
|
|
|
|
pRt->pNext->unblock();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// #63710 Durch ein anderes Thread-Handling bei Events kann es passieren,
|
|
|
|
|
// dass show-Aufruf an einem Dialog zurueckkehrt (durch schliessen des
|
|
|
|
|
// Dialogs per UI), BEVOR ein per Event ausgeloester weitergehender Call,
|
|
|
|
|
// der in Basic weiter oben im Stack steht und auf einen Basic-Breakpoint
|
|
|
|
|
// gelaufen ist, zurueckkehrt. Dann wird unten die Instanz zerstoert und
|
|
|
|
|
// wenn das noch im Call stehende Basic weiterlaeuft, gibt es einen GPF.
|
|
|
|
|
// Daher muss hier gewartet werden, bis andere Call zurueckkehrt.
|
|
|
|
|
if( bDelInst )
|
|
|
|
|
{
|
|
|
|
|
// Hier mit 1 statt 0 vergleichen, da vor nCallLvl--
|
|
|
|
|
while( pINST->nCallLvl != 1 )
|
|
|
|
|
GetpApp()->Yield();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nRes = TRUE;
|
|
|
|
|
pINST->pRun = pRt->pNext;
|
|
|
|
|
pINST->nCallLvl--; // Call-Level wieder runter
|
|
|
|
|
|
|
|
|
|
// Gibt es eine uebergeordnete Runtime-Instanz?
|
|
|
|
|
// Dann SbDEBUG_BREAK uebernehmen, wenn gesetzt
|
|
|
|
|
SbiRuntime* pRtNext = pRt->pNext;
|
|
|
|
|
if( pRtNext && (pRt->GetDebugFlags() & SbDEBUG_BREAK) )
|
|
|
|
|
pRtNext->SetDebugFlags( SbDEBUG_BREAK );
|
|
|
|
|
|
|
|
|
|
delete pRt;
|
|
|
|
|
pMOD = pOldMod;
|
|
|
|
|
if( bDelInst )
|
|
|
|
|
{
|
|
|
|
|
// #57841 Uno-Objekte, die in RTL-Funktionen gehalten werden,
|
|
|
|
|
// beim Programm-Ende freigeben, damit nichts gehalten wird.
|
|
|
|
|
ClearUnoObjectsInRTL_Impl( xBasic );
|
|
|
|
|
|
|
|
|
|
DBG_ASSERT(pINST->nCallLvl==0,"BASIC-Call-Level > 0")
|
|
|
|
|
delete pINST, pINST = NULL, bDelInst = FALSE;
|
2004-11-15 12:29:17 +00:00
|
|
|
|
|
|
|
|
|
// #i30690
|
|
|
|
|
vos::OGuard aSolarGuard( Application::GetSolarMutex() );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
SendHint( GetParent(), SBX_HINT_BASICSTOP, pMeth );
|
2001-09-04 09:20:53 +00:00
|
|
|
|
|
|
|
|
|
GlobalRunDeInit();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2002-07-10 09:54:53 +00:00
|
|
|
|
else
|
|
|
|
|
pINST->nCallLvl--; // Call-Level wieder runter
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
2003-04-23 15:56:27 +00:00
|
|
|
|
{
|
|
|
|
|
pINST->nCallLvl--; // Call-Level wieder runter
|
2000-09-18 15:18:56 +00:00
|
|
|
|
StarBASIC::FatalError( SbERR_STACK_OVERFLOW );
|
2003-04-23 15:56:27 +00:00
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
if( bDelInst )
|
|
|
|
|
{
|
|
|
|
|
// #57841 Uno-Objekte, die in RTL-Funktionen gehalten werden,
|
|
|
|
|
// beim Programm-Ende freigeben, damit nichts gehalten wird.
|
|
|
|
|
ClearUnoObjectsInRTL_Impl( xBasic );
|
|
|
|
|
|
|
|
|
|
delete pINST;
|
|
|
|
|
pINST = NULL;
|
|
|
|
|
}
|
|
|
|
|
return nRes;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ausfuehren der Init-Methode eines Moduls nach dem Laden
|
|
|
|
|
// oder der Compilation
|
|
|
|
|
|
|
|
|
|
void SbModule::RunInit()
|
|
|
|
|
{
|
|
|
|
|
if( pImage
|
|
|
|
|
&& !pImage->bInit
|
|
|
|
|
&& pImage->GetFlag( SBIMG_INITCODE ) )
|
|
|
|
|
{
|
|
|
|
|
// Flag setzen, dass RunInit aktiv ist (Testtool)
|
|
|
|
|
GetSbData()->bRunInit = TRUE;
|
|
|
|
|
|
|
|
|
|
// BOOL bDelInst = BOOL( pINST == NULL );
|
|
|
|
|
// if( bDelInst )
|
|
|
|
|
// pINST = new SbiInstance( (StarBASIC*) GetParent() );
|
|
|
|
|
SbModule* pOldMod = pMOD;
|
|
|
|
|
pMOD = this;
|
|
|
|
|
// Der Init-Code beginnt immer hier
|
|
|
|
|
SbiRuntime* pRt = new SbiRuntime( this, NULL, 0 );
|
|
|
|
|
pRt->pNext = pINST->pRun;
|
|
|
|
|
pINST->pRun = pRt;
|
|
|
|
|
while( pRt->Step() ) {}
|
|
|
|
|
pINST->pRun = pRt->pNext;
|
|
|
|
|
delete pRt;
|
|
|
|
|
pMOD = pOldMod;
|
|
|
|
|
// if( bDelInst )
|
|
|
|
|
// delete pINST, pINST = NULL;
|
|
|
|
|
pImage->bInit = TRUE;
|
2001-09-04 09:20:53 +00:00
|
|
|
|
pImage->bFirstInit = FALSE;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// RunInit ist nicht mehr aktiv
|
|
|
|
|
GetSbData()->bRunInit = FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Mit private/dim deklarierte Variablen loeschen
|
|
|
|
|
void SbModule::ClearPrivateVars()
|
|
|
|
|
{
|
2006-10-12 13:26:01 +00:00
|
|
|
|
for( USHORT i = 0 ; i < pProps->Count() ; i++ )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
SbProperty* p = PTR_CAST(SbProperty,pProps->Get( i ) );
|
|
|
|
|
if( p )
|
|
|
|
|
{
|
|
|
|
|
// Arrays nicht loeschen, sondern nur deren Inhalt
|
|
|
|
|
if( p->GetType() & SbxARRAY )
|
|
|
|
|
{
|
|
|
|
|
SbxArray* pArray = PTR_CAST(SbxArray,p->GetObject());
|
|
|
|
|
if( pArray )
|
|
|
|
|
{
|
2006-10-12 13:26:01 +00:00
|
|
|
|
for( USHORT j = 0 ; j < pArray->Count() ; j++ )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
SbxVariable* pj = PTR_CAST(SbxVariable,pArray->Get( j ));
|
|
|
|
|
pj->SbxValue::Clear();
|
|
|
|
|
/*
|
|
|
|
|
USHORT nFlags = pj->GetFlags();
|
|
|
|
|
pj->SetFlags( (nFlags | SBX_WRITE) & (~SBX_FIXED) );
|
|
|
|
|
pj->PutEmpty();
|
|
|
|
|
pj->SetFlags( nFlags );
|
|
|
|
|
*/
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
p->SbxValue::Clear();
|
|
|
|
|
/*
|
|
|
|
|
USHORT nFlags = p->GetFlags();
|
|
|
|
|
p->SetFlags( (nFlags | SBX_WRITE) & (~SBX_FIXED) );
|
|
|
|
|
p->PutEmpty();
|
|
|
|
|
p->SetFlags( nFlags );
|
|
|
|
|
*/
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Zunaechst in dieses Modul, um 358-faehig zu bleiben
|
|
|
|
|
// (Branch in sb.cxx vermeiden)
|
|
|
|
|
void StarBASIC::ClearAllModuleVars( void )
|
|
|
|
|
{
|
|
|
|
|
// Eigene Module initialisieren
|
|
|
|
|
for ( USHORT nMod = 0; nMod < pModules->Count(); nMod++ )
|
|
|
|
|
{
|
|
|
|
|
SbModule* pModule = (SbModule*)pModules->Get( nMod );
|
|
|
|
|
// Nur initialisieren, wenn der Startcode schon ausgefuehrt wurde
|
|
|
|
|
if( pModule->pImage && pModule->pImage->bInit )
|
|
|
|
|
pModule->ClearPrivateVars();
|
|
|
|
|
}
|
2001-07-03 09:46:50 +00:00
|
|
|
|
|
|
|
|
|
/* #88042 This code can delete already used public vars during runtime!
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// Alle Objekte ueberpruefen, ob es sich um ein Basic handelt
|
|
|
|
|
// Wenn ja, auch dort initialisieren
|
|
|
|
|
for ( USHORT nObj = 0; nObj < pObjs->Count(); nObj++ )
|
|
|
|
|
{
|
|
|
|
|
SbxVariable* pVar = pObjs->Get( nObj );
|
|
|
|
|
StarBASIC* pBasic = PTR_CAST(StarBASIC,pVar);
|
|
|
|
|
if( pBasic )
|
|
|
|
|
pBasic->ClearAllModuleVars();
|
|
|
|
|
}
|
2001-07-03 09:46:50 +00:00
|
|
|
|
*/
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ausfuehren des Init-Codes aller Module
|
|
|
|
|
void SbModule::GlobalRunInit( BOOL bBasicStart )
|
|
|
|
|
{
|
|
|
|
|
// Wenn kein Basic-Start, nur initialisieren, wenn Modul uninitialisiert
|
|
|
|
|
if( !bBasicStart )
|
|
|
|
|
if( !(pImage && !pImage->bInit) )
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
// GlobalInitErr-Flag fuer Compiler-Error initialisieren
|
|
|
|
|
// Anhand dieses Flags kann in SbModule::Run() nach dem Aufruf
|
|
|
|
|
// von GlobalRunInit festgestellt werden, ob beim initialisieren
|
|
|
|
|
// der Module ein Fehler auftrat. Dann wird nicht gestartet.
|
|
|
|
|
GetSbData()->bGlobalInitErr = FALSE;
|
|
|
|
|
|
|
|
|
|
// Parent vom Modul ist ein Basic
|
|
|
|
|
StarBASIC *pBasic = PTR_CAST(StarBASIC,GetParent());
|
|
|
|
|
if( pBasic )
|
|
|
|
|
{
|
|
|
|
|
pBasic->InitAllModules();
|
|
|
|
|
|
2006-06-19 16:40:39 +00:00
|
|
|
|
SbxObject* pParent_ = pBasic->GetParent();
|
|
|
|
|
if( pParent_ )
|
2003-05-22 07:52:42 +00:00
|
|
|
|
{
|
2006-06-19 16:40:39 +00:00
|
|
|
|
StarBASIC * pParentBasic = PTR_CAST(StarBASIC,pParent_);
|
2003-05-22 07:52:42 +00:00
|
|
|
|
if( pParentBasic )
|
|
|
|
|
{
|
|
|
|
|
pParentBasic->InitAllModules( pBasic );
|
|
|
|
|
|
|
|
|
|
// #109018 Parent can also have a parent (library in doc)
|
|
|
|
|
SbxObject* pParentParent = pParentBasic->GetParent();
|
|
|
|
|
if( pParentParent )
|
|
|
|
|
{
|
|
|
|
|
StarBASIC * pParentParentBasic = PTR_CAST(StarBASIC,pParentParent);
|
|
|
|
|
if( pParentParentBasic )
|
|
|
|
|
pParentParentBasic->InitAllModules( pParentBasic );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-09-04 09:20:53 +00:00
|
|
|
|
void SbModule::GlobalRunDeInit( void )
|
|
|
|
|
{
|
|
|
|
|
StarBASIC *pBasic = PTR_CAST(StarBASIC,GetParent());
|
|
|
|
|
if( pBasic )
|
|
|
|
|
{
|
|
|
|
|
pBasic->DeInitAllModules();
|
|
|
|
|
|
2006-06-19 16:40:39 +00:00
|
|
|
|
SbxObject* pParent_ = pBasic->GetParent();
|
|
|
|
|
if( pParent_ )
|
|
|
|
|
pBasic = PTR_CAST(StarBASIC,pParent_);
|
2001-09-04 09:20:53 +00:00
|
|
|
|
if( pBasic )
|
|
|
|
|
pBasic->DeInitAllModules();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// Suche nach dem naechsten STMNT-Befehl im Code. Wird vom STMNT-
|
|
|
|
|
// Opcode verwendet, um die Endspalte zu setzen.
|
|
|
|
|
|
|
|
|
|
const BYTE* SbModule::FindNextStmnt( const BYTE* p, USHORT& nLine, USHORT& nCol ) const
|
2002-08-09 09:27:16 +00:00
|
|
|
|
{
|
|
|
|
|
return FindNextStmnt( p, nLine, nCol, FALSE );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const BYTE* SbModule::FindNextStmnt( const BYTE* p, USHORT& nLine, USHORT& nCol,
|
|
|
|
|
BOOL bFollowJumps, const SbiImage* pImg ) const
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2006-11-01 15:13:15 +00:00
|
|
|
|
UINT32 nPC = (UINT32) ( p - (const BYTE*) pImage->GetCode() );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
while( nPC < pImage->GetCodeSize() )
|
|
|
|
|
{
|
|
|
|
|
SbiOpcode eOp = (SbiOpcode ) ( *p++ );
|
|
|
|
|
nPC++;
|
2002-08-09 09:27:16 +00:00
|
|
|
|
if( bFollowJumps && eOp == _JUMP && pImg )
|
|
|
|
|
{
|
|
|
|
|
DBG_ASSERT( pImg, "FindNextStmnt: pImg==NULL with FollowJumps option" );
|
2006-11-01 15:13:15 +00:00
|
|
|
|
UINT32 nOp1 = *p++; nOp1 |= *p++ << 8;
|
|
|
|
|
nOp1 |= *p++ << 16; nOp1 |= *p++ << 24;
|
2002-08-09 09:27:16 +00:00
|
|
|
|
p = (const BYTE*) pImg->GetCode() + nOp1;
|
|
|
|
|
}
|
|
|
|
|
else if( eOp >= SbOP1_START && eOp <= SbOP1_END )
|
2006-11-01 15:13:15 +00:00
|
|
|
|
p += 4, nPC += 4;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
else if( eOp == _STMNT )
|
|
|
|
|
{
|
2006-11-01 15:13:15 +00:00
|
|
|
|
UINT32 nl, nc;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
nl = *p++; nl |= *p++ << 8;
|
2006-11-01 15:13:15 +00:00
|
|
|
|
nl |= *p++ << 16 ; nl |= *p++ << 24;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
nc = *p++; nc |= *p++ << 8;
|
2006-11-01 15:13:15 +00:00
|
|
|
|
nc |= *p++ << 16 ; nc |= *p++ << 24;
|
2006-11-03 14:11:10 +00:00
|
|
|
|
nLine = (USHORT)nl; nCol = (USHORT)nc;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
return p;
|
|
|
|
|
}
|
|
|
|
|
else if( eOp >= SbOP2_START && eOp <= SbOP2_END )
|
2006-11-01 15:13:15 +00:00
|
|
|
|
p += 8, nPC += 8;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
else if( !( eOp >= SbOP0_START && eOp <= SbOP0_END ) )
|
|
|
|
|
{
|
|
|
|
|
StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Testen, ob eine Zeile STMNT-Opcodes enthaelt
|
|
|
|
|
|
|
|
|
|
BOOL SbModule::IsBreakable( USHORT nLine ) const
|
|
|
|
|
{
|
|
|
|
|
if( !pImage )
|
|
|
|
|
return FALSE;
|
|
|
|
|
const BYTE* p = (const BYTE* ) pImage->GetCode();
|
|
|
|
|
USHORT nl, nc;
|
|
|
|
|
while( ( p = FindNextStmnt( p, nl, nc ) ) != NULL )
|
|
|
|
|
if( nl == nLine )
|
|
|
|
|
return TRUE;
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
USHORT SbModule::GetBPCount() const
|
|
|
|
|
{
|
|
|
|
|
return pBreaks ? pBreaks->Count() : 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
USHORT SbModule::GetBP( USHORT n ) const
|
|
|
|
|
{
|
|
|
|
|
if( pBreaks && n < pBreaks->Count() )
|
|
|
|
|
return pBreaks->GetObject( n );
|
|
|
|
|
else
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL SbModule::IsBP( USHORT nLine ) const
|
|
|
|
|
{
|
|
|
|
|
if( pBreaks )
|
|
|
|
|
{
|
|
|
|
|
const USHORT* p = pBreaks->GetData();
|
|
|
|
|
USHORT n = pBreaks->Count();
|
|
|
|
|
for( USHORT i = 0; i < n; i++, p++ )
|
|
|
|
|
{
|
|
|
|
|
USHORT b = *p;
|
|
|
|
|
if( b == nLine )
|
|
|
|
|
return TRUE;
|
|
|
|
|
if( b < nLine )
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL SbModule::SetBP( USHORT nLine )
|
|
|
|
|
{
|
|
|
|
|
if( !IsBreakable( nLine ) )
|
|
|
|
|
return FALSE;
|
|
|
|
|
if( !pBreaks )
|
|
|
|
|
pBreaks = new SbiBreakpoints;
|
|
|
|
|
const USHORT* p = pBreaks->GetData();
|
|
|
|
|
USHORT n = pBreaks->Count();
|
|
|
|
|
USHORT i;
|
|
|
|
|
for( i = 0; i < n; i++, p++ )
|
|
|
|
|
{
|
|
|
|
|
USHORT b = *p;
|
|
|
|
|
if( b == nLine )
|
|
|
|
|
return TRUE;
|
|
|
|
|
if( b < nLine )
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
pBreaks->Insert( &nLine, 1, i );
|
|
|
|
|
|
|
|
|
|
// #38568: Zur Laufzeit auch hier SbDEBUG_BREAK setzen
|
|
|
|
|
if( pINST && pINST->pRun )
|
|
|
|
|
pINST->pRun->SetDebugFlags( SbDEBUG_BREAK );
|
|
|
|
|
|
|
|
|
|
return IsBreakable( nLine );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL SbModule::ClearBP( USHORT nLine )
|
|
|
|
|
{
|
|
|
|
|
BOOL bRes = FALSE;
|
|
|
|
|
if( pBreaks )
|
|
|
|
|
{
|
|
|
|
|
const USHORT* p = pBreaks->GetData();
|
|
|
|
|
USHORT n = pBreaks->Count();
|
|
|
|
|
for( USHORT i = 0; i < n; i++, p++ )
|
|
|
|
|
{
|
|
|
|
|
USHORT b = *p;
|
|
|
|
|
if( b == nLine )
|
|
|
|
|
{
|
|
|
|
|
pBreaks->Remove( i, 1 ); bRes = TRUE; break;
|
|
|
|
|
}
|
|
|
|
|
if( b < nLine )
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if( !pBreaks->Count() )
|
|
|
|
|
delete pBreaks, pBreaks = NULL;
|
|
|
|
|
}
|
|
|
|
|
return bRes;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SbModule::ClearAllBP()
|
|
|
|
|
{
|
|
|
|
|
delete pBreaks; pBreaks = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2006-11-01 15:13:15 +00:00
|
|
|
|
void
|
|
|
|
|
SbModule::fixUpMethodStart( bool bCvtToLegacy, SbiImage* pImg ) const
|
|
|
|
|
{
|
|
|
|
|
if ( !pImg )
|
|
|
|
|
pImg = pImage;
|
|
|
|
|
for( UINT32 i = 0; i < pMethods->Count(); i++ )
|
|
|
|
|
{
|
2006-11-03 14:11:10 +00:00
|
|
|
|
SbMethod* pMeth = PTR_CAST(SbMethod,pMethods->Get( (USHORT)i ) );
|
2006-11-01 15:13:15 +00:00
|
|
|
|
if( pMeth )
|
|
|
|
|
{
|
|
|
|
|
//fixup method start positions
|
|
|
|
|
if ( bCvtToLegacy )
|
|
|
|
|
pMeth->nStart = pImg->CalcLegacyOffset( pMeth->nStart );
|
|
|
|
|
else
|
2006-11-03 14:11:10 +00:00
|
|
|
|
pMeth->nStart = pImg->CalcNewOffset( (USHORT)pMeth->nStart );
|
2006-11-01 15:13:15 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
BOOL SbModule::LoadData( SvStream& rStrm, USHORT nVer )
|
|
|
|
|
{
|
|
|
|
|
Clear();
|
|
|
|
|
if( !SbxObject::LoadData( rStrm, 1 ) )
|
|
|
|
|
return FALSE;
|
|
|
|
|
// Sicherheitshalber...
|
|
|
|
|
SetFlag( SBX_EXTSEARCH | SBX_GBLSEARCH );
|
|
|
|
|
BYTE bImage;
|
|
|
|
|
rStrm >> bImage;
|
|
|
|
|
if( bImage )
|
|
|
|
|
{
|
|
|
|
|
SbiImage* p = new SbiImage;
|
2006-11-01 15:13:15 +00:00
|
|
|
|
UINT32 nImgVer = 0;
|
|
|
|
|
|
|
|
|
|
if( !p->Load( rStrm, nImgVer ) )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
delete p;
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2006-11-01 15:13:15 +00:00
|
|
|
|
// If the image is in old format, we fix up the method start offsets
|
|
|
|
|
if ( nImgVer < B_EXT_IMG_VERSION )
|
|
|
|
|
{
|
|
|
|
|
fixUpMethodStart( false, p );
|
|
|
|
|
p->ReleaseLegacyBuffer();
|
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
aComment = p->aComment;
|
|
|
|
|
SetName( p->aName );
|
|
|
|
|
if( p->GetCodeSize() )
|
|
|
|
|
{
|
2003-04-23 15:56:27 +00:00
|
|
|
|
aOUSource = p->aOUSource;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// Alte Version: Image weg
|
|
|
|
|
if( nVer == 1 )
|
|
|
|
|
{
|
2003-04-23 15:56:27 +00:00
|
|
|
|
SetSource32( p->aOUSource );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
delete p;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
pImage = p;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2003-04-23 15:56:27 +00:00
|
|
|
|
SetSource32( p->aOUSource );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
delete p;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL SbModule::StoreData( SvStream& rStrm ) const
|
|
|
|
|
{
|
2006-11-01 15:13:15 +00:00
|
|
|
|
BOOL bFixup = ( pImage && !pImage->ExceedsLegacyLimits() );
|
|
|
|
|
if ( bFixup )
|
|
|
|
|
fixUpMethodStart( true );
|
|
|
|
|
BOOL bRet = SbxObject::StoreData( rStrm );
|
|
|
|
|
if ( !bRet )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
return FALSE;
|
2006-11-01 15:13:15 +00:00
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
if( pImage )
|
|
|
|
|
{
|
2003-04-23 15:56:27 +00:00
|
|
|
|
pImage->aOUSource = aOUSource;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
pImage->aComment = aComment;
|
|
|
|
|
pImage->aName = GetName();
|
|
|
|
|
rStrm << (BYTE) 1;
|
2006-11-01 15:13:15 +00:00
|
|
|
|
// # PCode is saved only for legacy formats only
|
|
|
|
|
// It should be noted that it probably isn't necessary
|
|
|
|
|
// It would be better not to store the image ( more flexible with
|
|
|
|
|
// formats )
|
|
|
|
|
bool bRes = pImage->Save( rStrm, B_LEGACYVERSION );
|
|
|
|
|
if ( bFixup )
|
|
|
|
|
fixUpMethodStart( false ); // restore method starts
|
|
|
|
|
return bRes;
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SbiImage aImg;
|
2003-04-23 15:56:27 +00:00
|
|
|
|
aImg.aOUSource = aOUSource;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
aImg.aComment = aComment;
|
|
|
|
|
aImg.aName = GetName();
|
|
|
|
|
rStrm << (BYTE) 1;
|
|
|
|
|
return aImg.Save( rStrm );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2006-11-01 15:13:15 +00:00
|
|
|
|
BOOL SbModule::ExceedsLegacyModuleSize()
|
|
|
|
|
{
|
|
|
|
|
if ( !IsCompiled() )
|
|
|
|
|
Compile();
|
|
|
|
|
if ( pImage && pImage->ExceedsLegacyLimits() )
|
|
|
|
|
return true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2001-10-23 11:06:51 +00:00
|
|
|
|
// Store only image, no source
|
|
|
|
|
BOOL SbModule::StoreBinaryData( SvStream& rStrm )
|
2006-11-01 15:13:15 +00:00
|
|
|
|
{
|
|
|
|
|
return StoreBinaryData( rStrm, 0 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL SbModule::StoreBinaryData( SvStream& rStrm, USHORT nVer )
|
2001-10-23 11:06:51 +00:00
|
|
|
|
{
|
2001-11-14 10:11:32 +00:00
|
|
|
|
BOOL bRet = Compile();
|
2001-10-23 11:06:51 +00:00
|
|
|
|
if( bRet )
|
|
|
|
|
{
|
2006-11-01 15:13:15 +00:00
|
|
|
|
BOOL bFixup = ( !nVer && !pImage->ExceedsLegacyLimits() );// save in old image format, fix up method starts
|
|
|
|
|
|
|
|
|
|
if ( bFixup ) // save in old image format, fix up method starts
|
|
|
|
|
fixUpMethodStart( true );
|
2001-11-14 10:11:32 +00:00
|
|
|
|
bRet = SbxObject::StoreData( rStrm );
|
2001-10-23 11:06:51 +00:00
|
|
|
|
if( bRet )
|
|
|
|
|
{
|
2003-04-23 15:56:27 +00:00
|
|
|
|
pImage->aOUSource = OUString();
|
2001-10-23 11:06:51 +00:00
|
|
|
|
pImage->aComment = aComment;
|
|
|
|
|
pImage->aName = GetName();
|
|
|
|
|
|
|
|
|
|
rStrm << (BYTE) 1;
|
2006-11-01 15:13:15 +00:00
|
|
|
|
if ( nVer )
|
|
|
|
|
bRet = pImage->Save( rStrm, B_EXT_IMG_VERSION );
|
|
|
|
|
else
|
|
|
|
|
bRet = pImage->Save( rStrm, B_LEGACYVERSION );
|
|
|
|
|
if ( bFixup )
|
|
|
|
|
fixUpMethodStart( false ); // restore method starts
|
2001-10-23 11:06:51 +00:00
|
|
|
|
|
2003-04-23 15:56:27 +00:00
|
|
|
|
pImage->aOUSource = aOUSource;
|
2001-10-23 11:06:51 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return bRet;
|
|
|
|
|
}
|
|
|
|
|
|
2006-11-01 15:13:15 +00:00
|
|
|
|
// Called for >= OO 1.0 passwd protected libraries only
|
|
|
|
|
//
|
|
|
|
|
|
2001-10-23 11:06:51 +00:00
|
|
|
|
BOOL SbModule::LoadBinaryData( SvStream& rStrm )
|
|
|
|
|
{
|
2003-04-23 15:56:27 +00:00
|
|
|
|
OUString aKeepSource = aOUSource;
|
2001-10-23 11:06:51 +00:00
|
|
|
|
bool bRet = LoadData( rStrm, 2 );
|
2005-07-08 08:58:33 +00:00
|
|
|
|
LoadCompleted();
|
2003-04-23 15:56:27 +00:00
|
|
|
|
aOUSource = aKeepSource;
|
2001-10-23 11:06:51 +00:00
|
|
|
|
return bRet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
BOOL SbModule::LoadCompleted()
|
|
|
|
|
{
|
|
|
|
|
SbxArray* p = GetMethods();
|
|
|
|
|
USHORT i;
|
|
|
|
|
for( i = 0; i < p->Count(); i++ )
|
|
|
|
|
{
|
|
|
|
|
SbMethod* q = PTR_CAST(SbMethod,p->Get( i ) );
|
|
|
|
|
if( q )
|
|
|
|
|
q->pMod = this;
|
|
|
|
|
}
|
|
|
|
|
p = GetProperties();
|
|
|
|
|
for( i = 0; i < p->Count(); i++ )
|
|
|
|
|
{
|
|
|
|
|
SbProperty* q = PTR_CAST(SbProperty,p->Get( i ) );
|
|
|
|
|
if( q )
|
|
|
|
|
q->pMod = this;
|
|
|
|
|
}
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Hilfsklasse zur Untersuchung von JavaScript-Modulen, zunaechst zum
|
|
|
|
|
// Heraussuchen der Funktionen, spaeter auch zum Syntax-Highlighting verwenden
|
|
|
|
|
|
|
|
|
|
// Flags fuer Zeichen-Eigenschaften
|
|
|
|
|
#define CHAR_START_IDENTIFIER 0x0001
|
|
|
|
|
#define CHAR_IN_IDENTIFIER 0x0002
|
|
|
|
|
#define CHAR_START_NUMBER 0x0004
|
|
|
|
|
#define CHAR_IN_NUMBER 0x0008
|
|
|
|
|
#define CHAR_IN_HEX_NUMBER 0x0010
|
|
|
|
|
#define CHAR_IN_OCT_NUMBER 0x0020
|
|
|
|
|
#define CHAR_START_STRING 0x0040
|
|
|
|
|
#define CHAR_OPERATOR 0x0080
|
|
|
|
|
#define CHAR_SPACE 0x0100
|
|
|
|
|
#define CHAR_EOL 0x0200
|
|
|
|
|
|
|
|
|
|
#define CHAR_EOF 0x00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SimpleTokenizer_Impl
|
|
|
|
|
{
|
|
|
|
|
// Zeichen-Info-Tabelle
|
|
|
|
|
USHORT aCharTypeTab[256];
|
|
|
|
|
|
2004-11-15 15:34:15 +00:00
|
|
|
|
const sal_Unicode* mpStringBegin;
|
|
|
|
|
const sal_Unicode* mpActualPos;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// Zeile und Spalte
|
|
|
|
|
UINT32 nLine;
|
|
|
|
|
UINT32 nCol;
|
|
|
|
|
|
2004-11-15 15:34:15 +00:00
|
|
|
|
sal_Unicode peekChar( void ) { return *mpActualPos; }
|
|
|
|
|
sal_Unicode getChar( void ) { nCol++; return *mpActualPos++; }
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// Hilfsfunktion: Zeichen-Flag Testen
|
2004-11-15 15:34:15 +00:00
|
|
|
|
BOOL testCharFlags( sal_Unicode c, USHORT nTestFlags );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// Neues Token holen, Leerstring == nix mehr da
|
|
|
|
|
BOOL getNextToken( /*out*/TokenTypes& reType,
|
2004-11-15 15:34:15 +00:00
|
|
|
|
/*out*/const sal_Unicode*& rpStartPos, /*out*/const sal_Unicode*& rpEndPos );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
2004-11-15 15:34:15 +00:00
|
|
|
|
String getTokStr( /*out*/const sal_Unicode* pStartPos, /*out*/const sal_Unicode* pEndPos );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
2004-11-15 15:34:15 +00:00
|
|
|
|
#ifndef PRODUCT
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// TEST: Token ausgeben
|
|
|
|
|
String getFullTokenStr( /*out*/TokenTypes eType,
|
2004-11-15 15:34:15 +00:00
|
|
|
|
/*out*/const sal_Unicode* pStartPos, /*out*/const sal_Unicode* pEndPos );
|
|
|
|
|
#endif
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
2006-06-19 16:40:39 +00:00
|
|
|
|
const char** ppListKeyWords;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
UINT16 nKeyWordCount;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
SimpleTokenizer_Impl( void );
|
|
|
|
|
~SimpleTokenizer_Impl( void );
|
|
|
|
|
|
|
|
|
|
UINT16 parseLine( UINT32 nLine, const String* aSource );
|
|
|
|
|
void getHighlightPortions( UINT32 nParseLine, const String& rLine,
|
|
|
|
|
/*out*/HighlightPortions& portions );
|
2006-06-19 16:40:39 +00:00
|
|
|
|
void setKeyWords( const char** ppKeyWords, UINT16 nCount );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Hilfsfunktion: Zeichen-Flag Testen
|
2004-11-15 15:34:15 +00:00
|
|
|
|
BOOL SimpleTokenizer_Impl::testCharFlags( sal_Unicode c, USHORT nTestFlags )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2004-11-15 15:34:15 +00:00
|
|
|
|
bool bRet = false;
|
|
|
|
|
if( c != 0 && c <= 255 )
|
|
|
|
|
{
|
|
|
|
|
bRet = ( (aCharTypeTab[c] & nTestFlags) != 0 );
|
|
|
|
|
}
|
|
|
|
|
else if( c > 255 )
|
|
|
|
|
{
|
|
|
|
|
bRet = (( CHAR_START_IDENTIFIER | CHAR_IN_IDENTIFIER ) & nTestFlags) != 0
|
|
|
|
|
? BasicSimpleCharClass::isAlpha( c, true ) : false;
|
|
|
|
|
}
|
|
|
|
|
return bRet;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-06-19 16:40:39 +00:00
|
|
|
|
void SimpleTokenizer_Impl::setKeyWords( const char** ppKeyWords, UINT16 nCount )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
ppListKeyWords = ppKeyWords;
|
|
|
|
|
nKeyWordCount = nCount;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Neues Token holen
|
|
|
|
|
BOOL SimpleTokenizer_Impl::getNextToken( /*out*/TokenTypes& reType,
|
2004-11-15 15:34:15 +00:00
|
|
|
|
/*out*/const sal_Unicode*& rpStartPos, /*out*/const sal_Unicode*& rpEndPos )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
reType = TT_UNKNOWN;
|
|
|
|
|
|
|
|
|
|
// Position merken
|
|
|
|
|
rpStartPos = mpActualPos;
|
|
|
|
|
|
|
|
|
|
// Zeichen untersuchen
|
2004-11-15 15:34:15 +00:00
|
|
|
|
sal_Unicode c = peekChar();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
if( c == CHAR_EOF )
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
// Zeichen lesen
|
|
|
|
|
getChar();
|
|
|
|
|
|
|
|
|
|
//*** Alle Moeglichkeiten durchgehen ***
|
2004-11-15 15:34:15 +00:00
|
|
|
|
// Space?
|
|
|
|
|
if ( (testCharFlags( c, CHAR_SPACE ) == TRUE) )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
while( testCharFlags( peekChar(), CHAR_SPACE ) == TRUE )
|
|
|
|
|
getChar();
|
|
|
|
|
|
|
|
|
|
reType = TT_WHITESPACE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Identifier?
|
2004-11-15 15:34:15 +00:00
|
|
|
|
else if ( (testCharFlags( c, CHAR_START_IDENTIFIER ) == TRUE) )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
BOOL bIdentifierChar;
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
// Naechstes Zeichen holen
|
|
|
|
|
c = peekChar();
|
|
|
|
|
bIdentifierChar = testCharFlags( c, CHAR_IN_IDENTIFIER );
|
|
|
|
|
if( bIdentifierChar )
|
|
|
|
|
getChar();
|
|
|
|
|
}
|
|
|
|
|
while( bIdentifierChar );
|
|
|
|
|
|
|
|
|
|
reType = TT_IDENTIFIER;
|
|
|
|
|
|
|
|
|
|
// Schluesselwort-Tabelle
|
|
|
|
|
if (ppListKeyWords != NULL)
|
|
|
|
|
{
|
2004-11-15 15:34:15 +00:00
|
|
|
|
int nCount = mpActualPos - rpStartPos;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
2004-11-15 15:34:15 +00:00
|
|
|
|
// No keyword if string contains char > 255
|
|
|
|
|
bool bCanBeKeyword = true;
|
|
|
|
|
for( int i = 0 ; i < nCount ; i++ )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2004-11-15 15:34:15 +00:00
|
|
|
|
if( rpStartPos[i] > 255 )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2004-11-15 15:34:15 +00:00
|
|
|
|
bCanBeKeyword = false;
|
|
|
|
|
break;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2004-11-15 15:34:15 +00:00
|
|
|
|
if( bCanBeKeyword )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2006-10-12 13:26:01 +00:00
|
|
|
|
String aKWString(
|
|
|
|
|
rpStartPos, sal::static_int_cast< xub_StrLen >(nCount) );
|
2004-11-15 15:34:15 +00:00
|
|
|
|
ByteString aByteStr( aKWString, RTL_TEXTENCODING_ASCII_US );
|
|
|
|
|
aByteStr.ToLowerAscii();
|
|
|
|
|
if ( bsearch( aByteStr.GetBuffer(), ppListKeyWords, nKeyWordCount, sizeof( char* ),
|
|
|
|
|
compare_strings ) )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2004-11-15 15:34:15 +00:00
|
|
|
|
reType = TT_KEYWORD;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
2004-11-15 15:34:15 +00:00
|
|
|
|
if ( aByteStr.Equals( "rem" ) )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2004-11-15 15:34:15 +00:00
|
|
|
|
// Alle Zeichen bis Zeilen-Ende oder EOF entfernen
|
|
|
|
|
sal_Unicode cPeek = peekChar();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
while( cPeek != CHAR_EOF && testCharFlags( cPeek, CHAR_EOL ) == FALSE )
|
|
|
|
|
{
|
|
|
|
|
c = getChar();
|
|
|
|
|
cPeek = peekChar();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reType = TT_COMMENT;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-11-15 15:34:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Operator?
|
|
|
|
|
else if ( testCharFlags( c, CHAR_OPERATOR ) == TRUE || c == '\'' )
|
|
|
|
|
{
|
|
|
|
|
// Kommentar ?
|
|
|
|
|
if ( c == '\'' )
|
|
|
|
|
{
|
|
|
|
|
c = getChar(); // '/' entfernen
|
|
|
|
|
|
|
|
|
|
// Alle Zeichen bis Zeilen-Ende oder EOF entfernen
|
|
|
|
|
sal_Unicode cPeek = peekChar();
|
|
|
|
|
while( cPeek != CHAR_EOF && testCharFlags( cPeek, CHAR_EOL ) == FALSE )
|
|
|
|
|
{
|
|
|
|
|
getChar();
|
|
|
|
|
cPeek = peekChar();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reType = TT_COMMENT;
|
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// Echter Operator, kann hier einfach behandelt werden,
|
|
|
|
|
// da nicht der wirkliche Operator, wie z.B. += interessiert,
|
|
|
|
|
// sondern nur die Tatsache, dass es sich um einen handelt.
|
|
|
|
|
if( reType != TT_COMMENT )
|
|
|
|
|
{
|
|
|
|
|
reType = TT_OPERATOR;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Objekt-Trenner? Muss vor Number abgehandelt werden
|
|
|
|
|
else if( c == '.' && ( peekChar() < '0' || peekChar() > '9' ) )
|
|
|
|
|
{
|
|
|
|
|
reType = TT_OPERATOR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Zahl?
|
|
|
|
|
else if( testCharFlags( c, CHAR_START_NUMBER ) == TRUE )
|
|
|
|
|
{
|
2006-04-07 13:01:25 +00:00
|
|
|
|
reType = TT_NUMBER;
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// Zahlensystem, 10 = normal, wird bei Oct/Hex geaendert
|
|
|
|
|
int nRadix = 10;
|
|
|
|
|
|
|
|
|
|
// Ist es eine Hex- oder Oct-Zahl?
|
2006-04-07 13:01:25 +00:00
|
|
|
|
if( c == '&' )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
// Octal?
|
2006-04-07 13:01:25 +00:00
|
|
|
|
if( peekChar() == 'o' || peekChar() == 'O' )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2006-04-07 13:01:25 +00:00
|
|
|
|
// o entfernen
|
|
|
|
|
getChar();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
nRadix = 8; // Octal-Basis
|
|
|
|
|
|
|
|
|
|
// Alle Ziffern einlesen
|
|
|
|
|
while( testCharFlags( peekChar(), CHAR_IN_OCT_NUMBER ) )
|
|
|
|
|
c = getChar();
|
|
|
|
|
}
|
2006-04-07 13:01:25 +00:00
|
|
|
|
// Hex?
|
|
|
|
|
else if( peekChar() == 'h' || peekChar() == 'H' )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
// x entfernen
|
|
|
|
|
getChar();
|
|
|
|
|
nRadix = 16; // Hex-Basis
|
|
|
|
|
|
|
|
|
|
// Alle Ziffern einlesen und puffern
|
|
|
|
|
while( testCharFlags( peekChar(), CHAR_IN_HEX_NUMBER ) )
|
|
|
|
|
c = getChar();
|
|
|
|
|
}
|
2006-04-07 13:01:25 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
reType = TT_OPERATOR;
|
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Wenn nicht Oct oder Hex als double ansehen
|
2006-04-07 13:01:25 +00:00
|
|
|
|
if( reType == TT_NUMBER && nRadix == 10 )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
// Flag, ob das letzte Zeichen ein Exponent war
|
|
|
|
|
BOOL bAfterExpChar = FALSE;
|
|
|
|
|
|
|
|
|
|
// Alle Ziffern einlesen
|
|
|
|
|
while( testCharFlags( peekChar(), CHAR_IN_NUMBER ) ||
|
|
|
|
|
(bAfterExpChar && peekChar() == '+' ) ||
|
|
|
|
|
(bAfterExpChar && peekChar() == '-' ) )
|
|
|
|
|
// Nach Exponent auch +/- OK
|
|
|
|
|
{
|
|
|
|
|
c = getChar(); // Zeichen lesen
|
|
|
|
|
bAfterExpChar = ( c == 'e' || c == 'E' );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2006-04-07 13:01:25 +00:00
|
|
|
|
// reType = TT_NUMBER;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// String?
|
|
|
|
|
else if( testCharFlags( c, CHAR_START_STRING ) == TRUE )
|
|
|
|
|
{
|
|
|
|
|
// Merken, welches Zeichen den String eroeffnet hat
|
2004-11-15 15:34:15 +00:00
|
|
|
|
sal_Unicode cEndString = c;
|
2006-04-07 13:01:25 +00:00
|
|
|
|
if( c == '[' )
|
|
|
|
|
cEndString = ']';
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// Alle Ziffern einlesen und puffern
|
|
|
|
|
while( peekChar() != cEndString )
|
|
|
|
|
{
|
|
|
|
|
// #58846 EOF vor getChar() abfangen, damit EOF micht verloren geht
|
|
|
|
|
if( peekChar() == CHAR_EOF )
|
|
|
|
|
{
|
|
|
|
|
// ERROR: unterminated string literal
|
|
|
|
|
reType = TT_ERROR;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
c = getChar();
|
|
|
|
|
if( testCharFlags( c, CHAR_EOL ) == TRUE )
|
|
|
|
|
{
|
|
|
|
|
// ERROR: unterminated string literal
|
|
|
|
|
reType = TT_ERROR;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Zeichen lesen
|
|
|
|
|
if( reType != TT_ERROR )
|
|
|
|
|
{
|
|
|
|
|
getChar();
|
2006-04-07 13:01:25 +00:00
|
|
|
|
if( cEndString == ']' )
|
|
|
|
|
reType = TT_IDENTIFIER;
|
|
|
|
|
else
|
|
|
|
|
reType = TT_STRING;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Zeilenende?
|
|
|
|
|
else if( testCharFlags( c, CHAR_EOL ) == TRUE )
|
|
|
|
|
{
|
|
|
|
|
// Falls ein weiteres anderes EOL-Char folgt, weg damit
|
2004-11-15 15:34:15 +00:00
|
|
|
|
sal_Unicode cNext = peekChar();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
if( cNext != c && testCharFlags( cNext, CHAR_EOL ) == TRUE )
|
|
|
|
|
getChar();
|
|
|
|
|
|
|
|
|
|
// Positions-Daten auf Zeilen-Beginn setzen
|
|
|
|
|
nCol = 0;
|
|
|
|
|
nLine++;
|
|
|
|
|
|
|
|
|
|
reType = TT_EOL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Alles andere bleibt TT_UNKNOWN
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// End-Position eintragen
|
|
|
|
|
rpEndPos = mpActualPos;
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String SimpleTokenizer_Impl::getTokStr
|
2004-11-15 15:34:15 +00:00
|
|
|
|
( /*out*/const sal_Unicode* pStartPos, /*out*/const sal_Unicode* pEndPos )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
return String( pStartPos, (USHORT)( pEndPos - pStartPos ) );
|
|
|
|
|
}
|
|
|
|
|
|
2004-11-15 15:34:15 +00:00
|
|
|
|
#ifndef PRODUCT
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// TEST: Token ausgeben
|
|
|
|
|
String SimpleTokenizer_Impl::getFullTokenStr( /*out*/TokenTypes eType,
|
2004-11-15 15:34:15 +00:00
|
|
|
|
/*out*/const sal_Unicode* pStartPos, /*out*/const sal_Unicode* pEndPos )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
String aOut;
|
|
|
|
|
switch( eType )
|
|
|
|
|
{
|
|
|
|
|
case TT_UNKNOWN: aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_UNKNOWN:") ); break;
|
|
|
|
|
case TT_IDENTIFIER: aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_IDENTIFIER:") ); break;
|
|
|
|
|
case TT_WHITESPACE: aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_WHITESPACE:") ); break;
|
|
|
|
|
case TT_NUMBER: aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_NUMBER:") ); break;
|
|
|
|
|
case TT_STRING: aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_STRING:") ); break;
|
|
|
|
|
case TT_EOL: aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_EOL:") ); break;
|
|
|
|
|
case TT_COMMENT: aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_COMMENT:") ); break;
|
|
|
|
|
case TT_ERROR: aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_ERROR:") ); break;
|
|
|
|
|
case TT_OPERATOR: aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_OPERATOR:") ); break;
|
|
|
|
|
case TT_KEYWORD: aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_KEYWORD:") ); break;
|
|
|
|
|
}
|
|
|
|
|
if( eType != TT_EOL )
|
|
|
|
|
{
|
|
|
|
|
aOut += String( pStartPos, (USHORT)( pEndPos - pStartPos ) );
|
|
|
|
|
}
|
|
|
|
|
aOut += String( RTL_CONSTASCII_USTRINGPARAM("\n") );
|
|
|
|
|
return aOut;
|
|
|
|
|
}
|
2004-11-15 15:34:15 +00:00
|
|
|
|
#endif
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
SimpleTokenizer_Impl::SimpleTokenizer_Impl( void )
|
|
|
|
|
{
|
|
|
|
|
memset( aCharTypeTab, 0, sizeof( aCharTypeTab ) );
|
|
|
|
|
|
|
|
|
|
// Zeichen-Tabelle fuellen
|
|
|
|
|
USHORT i;
|
|
|
|
|
|
|
|
|
|
// Zulaessige Zeichen fuer Identifier
|
|
|
|
|
USHORT nHelpMask = (USHORT)( CHAR_START_IDENTIFIER | CHAR_IN_IDENTIFIER );
|
|
|
|
|
for( i = 'a' ; i <= 'z' ; i++ )
|
|
|
|
|
aCharTypeTab[i] |= nHelpMask;
|
|
|
|
|
for( i = 'A' ; i <= 'Z' ; i++ )
|
|
|
|
|
aCharTypeTab[i] |= nHelpMask;
|
|
|
|
|
// '_' extra eintragen
|
2006-06-19 16:40:39 +00:00
|
|
|
|
aCharTypeTab[(int)'_'] |= nHelpMask;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// AB 23.6.97: '$' ist auch erlaubt
|
2006-06-19 16:40:39 +00:00
|
|
|
|
aCharTypeTab[(int)'$'] |= nHelpMask;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// Ziffern (Identifier und Number ist moeglich)
|
|
|
|
|
nHelpMask = (USHORT)( CHAR_IN_IDENTIFIER | CHAR_START_NUMBER |
|
|
|
|
|
CHAR_IN_NUMBER | CHAR_IN_HEX_NUMBER );
|
|
|
|
|
for( i = '0' ; i <= '9' ; i++ )
|
|
|
|
|
aCharTypeTab[i] |= nHelpMask;
|
|
|
|
|
|
|
|
|
|
// e und E sowie . von Hand ergaenzen
|
2006-06-19 16:40:39 +00:00
|
|
|
|
aCharTypeTab[(int)'e'] |= CHAR_IN_NUMBER;
|
|
|
|
|
aCharTypeTab[(int)'E'] |= CHAR_IN_NUMBER;
|
|
|
|
|
aCharTypeTab[(int)'.'] |= (USHORT)( CHAR_IN_NUMBER | CHAR_START_NUMBER );
|
|
|
|
|
aCharTypeTab[(int)'&'] |= CHAR_START_NUMBER;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// Hex-Ziffern
|
|
|
|
|
for( i = 'a' ; i <= 'f' ; i++ )
|
|
|
|
|
aCharTypeTab[i] |= CHAR_IN_HEX_NUMBER;
|
|
|
|
|
for( i = 'A' ; i <= 'F' ; i++ )
|
|
|
|
|
aCharTypeTab[i] |= CHAR_IN_HEX_NUMBER;
|
|
|
|
|
|
|
|
|
|
// Oct-Ziffern
|
|
|
|
|
for( i = '0' ; i <= '7' ; i++ )
|
|
|
|
|
aCharTypeTab[i] |= CHAR_IN_OCT_NUMBER;
|
|
|
|
|
|
|
|
|
|
// String-Beginn/End-Zeichen
|
2006-06-19 16:40:39 +00:00
|
|
|
|
aCharTypeTab[(int)'\''] |= CHAR_START_STRING;
|
|
|
|
|
aCharTypeTab[(int)'\"'] |= CHAR_START_STRING;
|
|
|
|
|
aCharTypeTab[(int)'['] |= CHAR_START_STRING;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// Operator-Zeichen
|
2006-06-19 16:40:39 +00:00
|
|
|
|
aCharTypeTab[(int)'!'] |= CHAR_OPERATOR;
|
|
|
|
|
aCharTypeTab[(int)'%'] |= CHAR_OPERATOR;
|
|
|
|
|
// aCharTypeTab[(int)'&'] |= CHAR_OPERATOR; Removed because of #i14140
|
|
|
|
|
aCharTypeTab[(int)'('] |= CHAR_OPERATOR;
|
|
|
|
|
aCharTypeTab[(int)')'] |= CHAR_OPERATOR;
|
|
|
|
|
aCharTypeTab[(int)'*'] |= CHAR_OPERATOR;
|
|
|
|
|
aCharTypeTab[(int)'+'] |= CHAR_OPERATOR;
|
|
|
|
|
aCharTypeTab[(int)','] |= CHAR_OPERATOR;
|
|
|
|
|
aCharTypeTab[(int)'-'] |= CHAR_OPERATOR;
|
|
|
|
|
aCharTypeTab[(int)'/'] |= CHAR_OPERATOR;
|
|
|
|
|
aCharTypeTab[(int)':'] |= CHAR_OPERATOR;
|
|
|
|
|
aCharTypeTab[(int)'<'] |= CHAR_OPERATOR;
|
|
|
|
|
aCharTypeTab[(int)'='] |= CHAR_OPERATOR;
|
|
|
|
|
aCharTypeTab[(int)'>'] |= CHAR_OPERATOR;
|
|
|
|
|
aCharTypeTab[(int)'?'] |= CHAR_OPERATOR;
|
|
|
|
|
aCharTypeTab[(int)'^'] |= CHAR_OPERATOR;
|
|
|
|
|
aCharTypeTab[(int)'|'] |= CHAR_OPERATOR;
|
|
|
|
|
aCharTypeTab[(int)'~'] |= CHAR_OPERATOR;
|
|
|
|
|
aCharTypeTab[(int)'{'] |= CHAR_OPERATOR;
|
|
|
|
|
aCharTypeTab[(int)'}'] |= CHAR_OPERATOR;
|
|
|
|
|
// aCharTypeTab[(int)'['] |= CHAR_OPERATOR; Removed because of #i17826
|
|
|
|
|
aCharTypeTab[(int)']'] |= CHAR_OPERATOR;
|
|
|
|
|
aCharTypeTab[(int)';'] |= CHAR_OPERATOR;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// Space
|
2006-06-19 16:40:39 +00:00
|
|
|
|
aCharTypeTab[(int)' ' ] |= CHAR_SPACE;
|
|
|
|
|
aCharTypeTab[(int)'\t'] |= CHAR_SPACE;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// Zeilen-Ende-Zeichen
|
2006-06-19 16:40:39 +00:00
|
|
|
|
aCharTypeTab[(int)'\r'] |= CHAR_EOL;
|
|
|
|
|
aCharTypeTab[(int)'\n'] |= CHAR_EOL;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
ppListKeyWords = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SimpleTokenizer_Impl::~SimpleTokenizer_Impl( void )
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SimpleTokenizer_Impl* getSimpleTokenizer( void )
|
|
|
|
|
{
|
|
|
|
|
static SimpleTokenizer_Impl* pSimpleTokenizer = NULL;
|
|
|
|
|
if( !pSimpleTokenizer )
|
|
|
|
|
pSimpleTokenizer = new SimpleTokenizer_Impl();
|
|
|
|
|
return pSimpleTokenizer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Heraussuchen der jeweils naechsten Funktion aus einem JavaScript-Modul
|
|
|
|
|
UINT16 SimpleTokenizer_Impl::parseLine( UINT32 nParseLine, const String* aSource )
|
|
|
|
|
{
|
|
|
|
|
// Position auf den Anfang des Source-Strings setzen
|
2004-11-15 15:34:15 +00:00
|
|
|
|
mpStringBegin = mpActualPos = aSource->GetBuffer();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// Zeile und Spalte initialisieren
|
|
|
|
|
nLine = nParseLine;
|
|
|
|
|
nCol = 0L;
|
|
|
|
|
|
|
|
|
|
// Variablen fuer die Out-Parameter
|
|
|
|
|
TokenTypes eType;
|
2004-11-15 15:34:15 +00:00
|
|
|
|
const sal_Unicode* pStartPos;
|
|
|
|
|
const sal_Unicode* pEndPos;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// Schleife ueber alle Tokens
|
|
|
|
|
UINT16 nTokenCount = 0;
|
|
|
|
|
while( getNextToken( eType, pStartPos, pEndPos ) )
|
|
|
|
|
nTokenCount++;
|
|
|
|
|
|
|
|
|
|
return nTokenCount;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SimpleTokenizer_Impl::getHighlightPortions( UINT32 nParseLine, const String& rLine,
|
|
|
|
|
/*out*/HighlightPortions& portions )
|
|
|
|
|
{
|
|
|
|
|
// Position auf den Anfang des Source-Strings setzen
|
2004-11-15 15:34:15 +00:00
|
|
|
|
mpStringBegin = mpActualPos = rLine.GetBuffer();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// Zeile und Spalte initialisieren
|
|
|
|
|
nLine = nParseLine;
|
|
|
|
|
nCol = 0L;
|
|
|
|
|
|
|
|
|
|
// Variablen fuer die Out-Parameter
|
|
|
|
|
TokenTypes eType;
|
2004-11-15 15:34:15 +00:00
|
|
|
|
const sal_Unicode* pStartPos;
|
|
|
|
|
const sal_Unicode* pEndPos;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// Schleife ueber alle Tokens
|
|
|
|
|
while( getNextToken( eType, pStartPos, pEndPos ) )
|
|
|
|
|
{
|
|
|
|
|
HighlightPortion portion;
|
|
|
|
|
|
|
|
|
|
portion.nBegin = (UINT16)(pStartPos - mpStringBegin);
|
|
|
|
|
portion.nEnd = (UINT16)(pEndPos - mpStringBegin);
|
|
|
|
|
portion.tokenType = eType;
|
|
|
|
|
|
|
|
|
|
portions.Insert(portion, portions.Count());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Implementierung des SyntaxHighlighter
|
|
|
|
|
|
|
|
|
|
SyntaxHighlighter::SyntaxHighlighter()
|
|
|
|
|
{
|
|
|
|
|
m_pSimpleTokenizer = new SimpleTokenizer_Impl();
|
|
|
|
|
m_pKeyWords = NULL;
|
|
|
|
|
m_nKeyWordCount = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SyntaxHighlighter::~SyntaxHighlighter()
|
|
|
|
|
{
|
|
|
|
|
delete(m_pSimpleTokenizer);
|
|
|
|
|
delete(m_pKeyWords);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SyntaxHighlighter::initialize( HighlighterLanguage eLanguage_ )
|
|
|
|
|
{
|
|
|
|
|
eLanguage = eLanguage_;
|
|
|
|
|
delete(m_pSimpleTokenizer);
|
|
|
|
|
m_pSimpleTokenizer = new SimpleTokenizer_Impl();
|
|
|
|
|
|
|
|
|
|
if (eLanguage == HIGHLIGHT_BASIC)
|
|
|
|
|
{
|
|
|
|
|
m_pSimpleTokenizer->setKeyWords( strListBasicKeyWords,
|
|
|
|
|
sizeof( strListBasicKeyWords ) / sizeof( char* ));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
m_pSimpleTokenizer->setKeyWords( NULL, 0 );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const Range SyntaxHighlighter::notifyChange( UINT32 nLine, INT32 nLineCountDifference,
|
|
|
|
|
const String* pChangedLines, UINT32 nArrayLength)
|
|
|
|
|
{
|
2006-06-19 16:40:39 +00:00
|
|
|
|
(void)nLineCountDifference;
|
|
|
|
|
|
|
|
|
|
for( UINT32 i=0 ; i < nArrayLength ; i++ )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
m_pSimpleTokenizer->parseLine(nLine+i, &pChangedLines[i]);
|
|
|
|
|
|
2006-06-19 16:40:39 +00:00
|
|
|
|
return Range( nLine, nLine + nArrayLength-1 );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SyntaxHighlighter::getHighlightPortions( UINT32 nLine, const String& rLine,
|
|
|
|
|
/*out*/HighlightPortions& portions )
|
|
|
|
|
{
|
|
|
|
|
m_pSimpleTokenizer->getHighlightPortions( nLine, rLine, portions );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Implementation SbJScriptModule (Basic-Modul fuer JavaScript-Sourcen)
|
|
|
|
|
SbJScriptModule::SbJScriptModule( const String& rName )
|
|
|
|
|
:SbModule( rName )
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL SbJScriptModule::LoadData( SvStream& rStrm, USHORT nVer )
|
|
|
|
|
{
|
2006-06-19 16:40:39 +00:00
|
|
|
|
(void)nVer;
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
Clear();
|
|
|
|
|
if( !SbxObject::LoadData( rStrm, 1 ) )
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
// Source-String holen
|
2003-04-23 15:56:27 +00:00
|
|
|
|
String aTmp;
|
|
|
|
|
rStrm.ReadByteString( aTmp, gsl_getSystemTextEncoding() );
|
|
|
|
|
aOUSource = aTmp;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
//rStrm >> aSource;
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL SbJScriptModule::StoreData( SvStream& rStrm ) const
|
|
|
|
|
{
|
|
|
|
|
if( !SbxObject::StoreData( rStrm ) )
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
// Source-String schreiben
|
2003-04-23 15:56:27 +00:00
|
|
|
|
String aTmp = aOUSource;
|
|
|
|
|
rStrm.WriteByteString( aTmp, gsl_getSystemTextEncoding() );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
//rStrm << aSource;
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
SbMethod::SbMethod( const String& r, SbxDataType t, SbModule* p )
|
|
|
|
|
: SbxMethod( r, t ), pMod( p )
|
|
|
|
|
{
|
|
|
|
|
bInvalid = TRUE;
|
|
|
|
|
nStart =
|
|
|
|
|
nDebugFlags =
|
|
|
|
|
nLine1 =
|
|
|
|
|
nLine2 = 0;
|
|
|
|
|
// AB: 2.7.1996: HACK wegen 'Referenz kann nicht gesichert werden'
|
|
|
|
|
SetFlag( SBX_NO_MODIFY );
|
|
|
|
|
}
|
|
|
|
|
|
2003-04-23 15:56:27 +00:00
|
|
|
|
SbMethod::SbMethod( const SbMethod& r )
|
2006-06-19 16:40:39 +00:00
|
|
|
|
: SvRefBase( r ), SbxMethod( r )
|
2003-04-23 15:56:27 +00:00
|
|
|
|
{
|
|
|
|
|
pMod = r.pMod;
|
|
|
|
|
bInvalid = r.bInvalid;
|
|
|
|
|
nStart = r.nStart;
|
|
|
|
|
nDebugFlags = r.nDebugFlags;
|
|
|
|
|
nLine1 = r.nLine1;
|
|
|
|
|
nLine2 = r.nLine2;
|
|
|
|
|
SetFlag( SBX_NO_MODIFY );
|
|
|
|
|
}
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
SbMethod::~SbMethod()
|
2003-04-23 15:56:27 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
SbxArray* SbMethod::GetLocals()
|
|
|
|
|
{
|
|
|
|
|
if( pINST )
|
|
|
|
|
return pINST->GetLocals( this );
|
|
|
|
|
else
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SbxArray* SbMethod::GetStatics()
|
|
|
|
|
{
|
|
|
|
|
DBG_ERROR( "SbMethod::GetStatics() invalid, AB fragen" )
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL SbMethod::LoadData( SvStream& rStrm, USHORT nVer )
|
|
|
|
|
{
|
|
|
|
|
if( !SbxMethod::LoadData( rStrm, 1 ) )
|
|
|
|
|
return FALSE;
|
|
|
|
|
INT16 n;
|
|
|
|
|
rStrm >> n;
|
2006-11-03 14:11:10 +00:00
|
|
|
|
INT16 nTempStart = (INT16)nStart;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// nDebugFlags = n; // AB 16.1.96: Nicht mehr uebernehmen
|
|
|
|
|
if( nVer == 2 )
|
2006-11-01 15:13:15 +00:00
|
|
|
|
rStrm >> nLine1 >> nLine2 >> nTempStart >> bInvalid;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// AB: 2.7.1996: HACK wegen 'Referenz kann nicht gesichert werden'
|
|
|
|
|
SetFlag( SBX_NO_MODIFY );
|
2006-11-01 15:13:15 +00:00
|
|
|
|
nStart = nTempStart;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL SbMethod::StoreData( SvStream& rStrm ) const
|
|
|
|
|
{
|
|
|
|
|
if( !SbxMethod::StoreData( rStrm ) )
|
|
|
|
|
return FALSE;
|
|
|
|
|
rStrm << (INT16) nDebugFlags
|
|
|
|
|
<< (INT16) nLine1
|
|
|
|
|
<< (INT16) nLine2
|
|
|
|
|
<< (INT16) nStart
|
|
|
|
|
<< (BYTE) bInvalid;
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SbMethod::GetLineRange( USHORT& l1, USHORT& l2 )
|
|
|
|
|
{
|
|
|
|
|
l1 = nLine1; l2 = nLine2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Kann spaeter mal weg
|
|
|
|
|
|
|
|
|
|
SbxInfo* SbMethod::GetInfo()
|
|
|
|
|
{
|
|
|
|
|
return pInfo;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Schnittstelle zum Ausfuehren einer Methode aus den Applikationen
|
|
|
|
|
// #34191# Mit speziellem RefCounting, damit das Basic nicht durch CloseDocument()
|
|
|
|
|
// abgeschossen werden kann. Rueckgabewert wird als String geliefert.
|
|
|
|
|
ErrCode SbMethod::Call( SbxValue* pRet )
|
|
|
|
|
{
|
|
|
|
|
// RefCount vom Modul hochzaehlen
|
2006-06-19 16:40:39 +00:00
|
|
|
|
SbModule* pMod_ = (SbModule*)GetParent();
|
|
|
|
|
pMod_->AddRef();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// RefCount vom Basic hochzaehlen
|
2006-06-19 16:40:39 +00:00
|
|
|
|
StarBASIC* pBasic = (StarBASIC*)pMod_->GetParent();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
pBasic->AddRef();
|
|
|
|
|
|
|
|
|
|
// Values anlegen, um Return-Wert zu erhalten
|
|
|
|
|
SbxValues aVals;
|
|
|
|
|
aVals.eType = SbxVARIANT;
|
2002-10-25 09:03:13 +00:00
|
|
|
|
|
|
|
|
|
// #104083: Compile BEFORE get
|
2006-06-19 16:40:39 +00:00
|
|
|
|
if( bInvalid && !pMod_->Compile() )
|
2002-10-25 09:03:13 +00:00
|
|
|
|
StarBASIC::Error( SbERR_BAD_PROP_VALUE );
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
Get( aVals );
|
|
|
|
|
if ( pRet )
|
|
|
|
|
pRet->Put( aVals );
|
|
|
|
|
|
|
|
|
|
// Gab es einen Error
|
|
|
|
|
ErrCode nErr = SbxBase::GetError();
|
|
|
|
|
SbxBase::ResetError();
|
|
|
|
|
|
|
|
|
|
// Objekte freigeben
|
2006-06-19 16:40:39 +00:00
|
|
|
|
pMod_->ReleaseRef();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
pBasic->ReleaseRef();
|
|
|
|
|
|
|
|
|
|
return nErr;
|
|
|
|
|
}
|
|
|
|
|
|
2003-04-23 15:56:27 +00:00
|
|
|
|
|
|
|
|
|
// #100883 Own Broadcast for SbMethod
|
|
|
|
|
void SbMethod::Broadcast( ULONG nHintId )
|
|
|
|
|
{
|
|
|
|
|
if( pCst && !IsSet( SBX_NO_BROADCAST ) && StaticIsEnabledBroadcasting() )
|
|
|
|
|
{
|
|
|
|
|
// Da die Methode von aussen aufrufbar ist, hier noch einmal
|
|
|
|
|
// die Berechtigung testen
|
|
|
|
|
if( nHintId & SBX_HINT_DATAWANTED )
|
|
|
|
|
if( !CanRead() )
|
|
|
|
|
return;
|
|
|
|
|
if( nHintId & SBX_HINT_DATACHANGED )
|
|
|
|
|
if( !CanWrite() )
|
|
|
|
|
return;
|
|
|
|
|
|
2003-07-01 13:52:35 +00:00
|
|
|
|
if( pMod && !pMod->IsCompiled() )
|
2003-04-23 15:56:27 +00:00
|
|
|
|
pMod->Compile();
|
|
|
|
|
|
|
|
|
|
// Block broadcasts while creating new method
|
|
|
|
|
SfxBroadcaster* pSave = pCst;
|
|
|
|
|
pCst = NULL;
|
|
|
|
|
SbMethod* pThisCopy = new SbMethod( *this );
|
|
|
|
|
SbMethodRef xHolder = pThisCopy;
|
2006-06-19 16:40:39 +00:00
|
|
|
|
if( mpPar.Is() )
|
2003-04-23 15:56:27 +00:00
|
|
|
|
{
|
|
|
|
|
// this, als Element 0 eintragen, aber den Parent nicht umsetzen!
|
2006-06-19 16:40:39 +00:00
|
|
|
|
mpPar->PutDirect( pThisCopy, 0 );
|
2003-04-23 15:56:27 +00:00
|
|
|
|
SetParameters( NULL );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pCst = pSave;
|
|
|
|
|
pSave->Broadcast( SbxHint( nHintId, pThisCopy ) );
|
|
|
|
|
|
|
|
|
|
USHORT nSaveFlags = GetFlags();
|
|
|
|
|
SetFlag( SBX_READWRITE );
|
|
|
|
|
pCst = NULL;
|
|
|
|
|
Put( pThisCopy->GetValues_Impl() );
|
|
|
|
|
pCst = pSave;
|
|
|
|
|
SetFlags( nSaveFlags );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
// Implementation SbJScriptMethod (Method-Klasse als Wrapper fuer JavaScript-Funktionen)
|
|
|
|
|
|
|
|
|
|
SbJScriptMethod::SbJScriptMethod( const String& r, SbxDataType t, SbModule* p )
|
|
|
|
|
: SbMethod( r, t, p )
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SbJScriptMethod::~SbJScriptMethod()
|
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
SbProperty::SbProperty( const String& r, SbxDataType t, SbModule* p )
|
|
|
|
|
: SbxProperty( r, t ), pMod( p )
|
|
|
|
|
{
|
|
|
|
|
bInvalid = FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SbProperty::~SbProperty()
|
|
|
|
|
{}
|
|
|
|
|
|
2004-11-02 10:52:32 +00:00
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
SbProcedureProperty::~SbProcedureProperty()
|
|
|
|
|
{}
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|