mirror of
https://github.com/adtools/clib2.git
synced 2025-12-08 14:59:05 +00:00
- Rewrote the GetRexxVar()/SetRexxVar() functions (mostly) in 'C', using available
code as a reference. The 68k stubs currently only work for the 68k version of the library, and a solution for the OS4 build still needs to be found. The code is currently untested, but it should be complete. git-svn-id: file:///Users/olsen/Code/migration-svn-zu-git/logical-line-staging/clib2/trunk@15183 87f5fb63-7c3d-0410-a384-fd976d0f7a62
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: amiga_rexxvars.c,v 1.12 2008-03-11 13:26:18 obarthel Exp $
|
||||
* $Id: amiga_rexxvars.c,v 1.13 2008-04-14 15:07:37 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -53,6 +53,10 @@
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
struct Environment;
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#define __NOLIBBASE__
|
||||
#include <proto/rexxsyslib.h>
|
||||
|
||||
@ -124,7 +128,7 @@ static struct RexxSysIFace * IRexxSys;
|
||||
|
||||
BOOL CheckRexxMsg(struct RexxMsg *message);
|
||||
LONG GetRexxVar(struct RexxMsg *message,STRPTR variable_name,STRPTR *buffer_pointer);
|
||||
LONG SetRexxVar(struct RexxMsg *message,STRPTR variable_name,STRPTR value,ULONG length);
|
||||
LONG SetRexxVar(struct RexxMsg *message,STRPTR variable_name,STRPTR value,LONG length);
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
@ -208,6 +212,10 @@ CheckRexxMsg(struct RexxMsg *message)
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#if 1
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* The following function works in about like the original, except that it's
|
||||
not reentrant, does not fill in a pointer to the variable itself and
|
||||
requires rexxsyslib.library V45. */
|
||||
@ -261,3 +269,437 @@ SetRexxVar(struct RexxMsg *message,STRPTR variable_name,STRPTR value,ULONG lengt
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#else
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#if defined(__GNUC__) && !defined(__amigaos4__)
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* A selection of lovingly hand-crafted 68k stub functions which call
|
||||
into rexxsyslib.library LVOs which still used to be documented back
|
||||
in 1987. */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#if defined(SMALL_DATA)
|
||||
#define A4(x) "a4@(" #x ":W)"
|
||||
#elif defined(SMALL_DATA32)
|
||||
#define A4(x) "a4@(" #x ":L)"
|
||||
#else
|
||||
#define A4(x) #x
|
||||
#endif /* SMALL_DATA */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
asm("
|
||||
|
||||
.text
|
||||
.even
|
||||
|
||||
.globl _RexxSysBase
|
||||
.globl __FreeSpace
|
||||
|
||||
__FreeSpace:
|
||||
|
||||
moveal sp@(4),a0
|
||||
moveal sp@(8),a1
|
||||
movel sp@(12),d0
|
||||
movel a6,sp@-
|
||||
moveal "A4(_RexxSysBase)",a6
|
||||
jsr a6@(-120)
|
||||
moveal sp@+,a6
|
||||
rts
|
||||
|
||||
");
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
asm("
|
||||
|
||||
.text
|
||||
.even
|
||||
|
||||
.globl _RexxSysBase
|
||||
.globl __GetSpace
|
||||
|
||||
__GetSpace:
|
||||
|
||||
moveal sp@(4),a0
|
||||
movel sp@(8),d0
|
||||
movel a6,sp@-
|
||||
moveal "A4(_RexxSysBase)",a6
|
||||
jsr a6@(-114)
|
||||
moveal sp@+,a6
|
||||
rts
|
||||
|
||||
");
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
asm("
|
||||
|
||||
.text
|
||||
.even
|
||||
|
||||
.globl _RexxSysBase
|
||||
.globl __IsSymbol
|
||||
|
||||
__IsSymbol:
|
||||
moveal sp@(4),a0
|
||||
movel a6,sp@-
|
||||
moveal "A4(_RexxSysBase)",a6
|
||||
jsr a6@(-102)
|
||||
moveal sp@+,a6
|
||||
moveal sp@(8),a1
|
||||
movel d1,a1@
|
||||
rts
|
||||
|
||||
");
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
asm("
|
||||
|
||||
.text
|
||||
.even
|
||||
|
||||
.globl _RexxSysBase
|
||||
.globl __CurrentEnv
|
||||
|
||||
__CurrentEnv:
|
||||
moveal sp@(4),a0
|
||||
movel a6,sp@-
|
||||
moveal "A4(_RexxSysBase)",a6
|
||||
jsr a6@(-108)
|
||||
moveal sp@+,a6
|
||||
moveal sp@(8),a1
|
||||
movel a0,a1@
|
||||
rts
|
||||
|
||||
");
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
asm("
|
||||
|
||||
.text
|
||||
.even
|
||||
|
||||
.globl _RexxSysBase
|
||||
.globl __FetchValue
|
||||
|
||||
__FetchValue:
|
||||
moveal sp@(4),a0
|
||||
moveal sp@(8),a1
|
||||
movel sp@(12),d0
|
||||
movel sp@(16),d1
|
||||
movel a6,sp@-
|
||||
moveal "A4(_RexxSysBase)",a6
|
||||
jsr a6@(-72)
|
||||
moveal sp@+,a6
|
||||
moveal sp@(20),a1
|
||||
movel a0,a1@
|
||||
moveal sp@(24),a1
|
||||
movel d1,a1@
|
||||
rts
|
||||
|
||||
");
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
asm("
|
||||
|
||||
.text
|
||||
.even
|
||||
|
||||
.globl _RexxSysBase
|
||||
.globl __EnterSymbol
|
||||
|
||||
__EnterSymbol:
|
||||
moveal sp@(4),a0
|
||||
moveal sp@(8),a1
|
||||
movel sp@(12),d0
|
||||
movel a6,sp@-
|
||||
moveal "A4(_RexxSysBase)",a6
|
||||
jsr a6@(-66)
|
||||
moveal sp@+,a6
|
||||
rts
|
||||
|
||||
");
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
asm("
|
||||
|
||||
.text
|
||||
.even
|
||||
|
||||
.globl _RexxSysBase
|
||||
.globl __FreeSpace
|
||||
|
||||
__SetValue:
|
||||
moveal sp@(4),a0
|
||||
moveal sp@(8),a1
|
||||
movel sp@(12),d0
|
||||
movel a6,sp@-
|
||||
moveal "A4(_RexxSysBase)",a6
|
||||
jsr a6@(-84)
|
||||
moveal sp@+,a6
|
||||
rts
|
||||
|
||||
");
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
asm("
|
||||
|
||||
.text
|
||||
.even
|
||||
|
||||
.globl _RexxSysBase
|
||||
.globl __FreeSpace
|
||||
|
||||
__StrcpyN:
|
||||
moveal sp@(4),a0
|
||||
moveal sp@(8),a1
|
||||
movel sp@(12),d0
|
||||
movel a6,sp@-
|
||||
moveal "A4(_RexxSysBase)",a6
|
||||
jsr a6@(-270)
|
||||
moveal sp@+,a6
|
||||
moveal sp@(16),a1
|
||||
movel d1,a1@
|
||||
rts
|
||||
|
||||
");
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#endif /* __GNUC__ && !__amigaos4__ */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* Function prototypes for the 68k stubs. */
|
||||
extern VOID _FreeSpace(struct Environment * env,APTR mem,LONG size);
|
||||
extern APTR _GetSpace(struct Environment * env,LONG size);
|
||||
extern LONG _IsSymbol(STRPTR name,LONG * symbol_length_ptr);
|
||||
extern VOID _CurrentEnv(struct RexxTask *task,struct Environment ** environment_ptr);
|
||||
extern struct Node * _FetchValue(struct Environment * env,struct NexxStr * stem,struct NexxStr * compound,struct Node *symbol_table_node,LONG * is_literal_ptr,struct NexxStr ** value_ptr);
|
||||
extern struct Node * _EnterSymbol(struct Environment * env,struct NexxStr * stem,struct NexxStr * compound);
|
||||
extern VOID _SetValue(struct Environment * env,struct NexxStr * value,struct Node * symbol_table_node);
|
||||
extern ULONG _StrcpyN(STRPTR destination,STRPTR source,LONG length);
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* Releases a string structure, if it's not owned at the time. */
|
||||
STATIC VOID
|
||||
FreeString(struct Environment * environment,struct NexxStr * ns)
|
||||
{
|
||||
/* Not currently owned? */
|
||||
if(!(ns->ns_Flags & NSF_KEEP))
|
||||
_FreeSpace(environment,ns,sizeof(*ns) + ns->ns_Length + 1); /* struct Environment * a0,APTR block a1,LONG d0 */
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* Allocates and initializes a string structure. */
|
||||
STATIC struct NexxStr *
|
||||
MakeString(struct Environment * environment,STRPTR value,LONG length)
|
||||
{
|
||||
struct NexxStr * result = NULL;
|
||||
struct NexxStr * ns;
|
||||
|
||||
/* Allocate memory for the NexxStr and the NUL-terminated string itself. */
|
||||
ns = _GetSpace(environment,sizeof(*ns) + length + 1); /* struct Environment * a0,LONG d0 : APTR d0 */
|
||||
if(ns == NULL)
|
||||
goto out;
|
||||
|
||||
/* Fill in the NexxStr structure, copy the string and remember the hash value for it. */
|
||||
ns->ns_Length = length;
|
||||
ns->ns_Flags = NSF_STRING;
|
||||
ns->ns_Hash = _StrcpyN((STRPTR)ns->ns_Buff,value,length); /* STRPTR a0,STRPTR a1,LONG d0 : ULONG d0 */
|
||||
|
||||
result = ns;
|
||||
|
||||
out:
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* Classifies a symbol and returns the stem and compound parts. */
|
||||
STATIC LONG
|
||||
TypeString(STRPTR variable_name,struct Environment * environment,struct NexxStr ** compound_ptr,struct NexxStr ** stem_ptr)
|
||||
{
|
||||
struct NexxStr * compound;
|
||||
struct NexxStr * stem = NULL;
|
||||
LONG error = ERR10_003; /* no memory available */
|
||||
LONG stem_length;
|
||||
LONG symbol_length;
|
||||
STRPTR dot;
|
||||
|
||||
(*compound_ptr) = NULL;
|
||||
(*stem_ptr) = NULL;
|
||||
|
||||
/* The 'compound' part is the entire variable name, including all dots and
|
||||
what's in between them. */
|
||||
compound = MakeString(environment,variable_name,strlen(variable_name));
|
||||
if(compound == NULL)
|
||||
goto out;
|
||||
|
||||
/* Find the first dot in the variable name. Everything in front of it
|
||||
constitutes the 'stem' part. If there is no dot in the name, then
|
||||
the 'compound' and 'stem' parts are identical. */
|
||||
dot = memchr(compound->ns_Buff,'.',compound->ns_Length);
|
||||
if(dot != NULL)
|
||||
stem_length = ((char *)dot - (char *)compound->ns_Buff) + 1;
|
||||
else
|
||||
stem_length = compound->ns_Length;
|
||||
|
||||
/* Make a copy of the 'stem' part. */
|
||||
stem = MakeString(environment,variable_name,stem_length);
|
||||
if(stem == NULL)
|
||||
goto out;
|
||||
|
||||
/* Figure out if this is a symbol after all. */
|
||||
_IsSymbol((STRPTR)stem->ns_Buff,&symbol_length); /* STRPTR a0 : LONG d0, LONG d1 */
|
||||
|
||||
/* The entire name must match the stem part. */
|
||||
if(symbol_length != stem->ns_Length)
|
||||
{
|
||||
error = ERR10_040; /* invalid variable name */
|
||||
goto out;
|
||||
}
|
||||
|
||||
(*compound_ptr) = compound;
|
||||
(*stem_ptr) = stem;
|
||||
|
||||
error = 0;
|
||||
|
||||
out:
|
||||
|
||||
if(error != 0)
|
||||
{
|
||||
if(compound != NULL)
|
||||
FreeString(environment,compound);
|
||||
|
||||
if(stem != NULL)
|
||||
FreeString(environment,stem);
|
||||
}
|
||||
|
||||
return(error);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* Retrieves the value of a variable from the current storage environment. */
|
||||
LONG
|
||||
GetRexxVar(struct RexxMsg *context,STRPTR variable_name,STRPTR * return_value)
|
||||
{
|
||||
struct Environment * environment;
|
||||
struct NexxStr * ns;
|
||||
struct NexxStr * compound_string;
|
||||
struct NexxStr * stem_string;
|
||||
LONG is_literal;
|
||||
LONG error;
|
||||
|
||||
(*return_value) = NULL;
|
||||
|
||||
if(!CheckRexxMsg(context))
|
||||
{
|
||||
error = ERR10_010; /* invalid message packet */
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Find the current storage environment. */
|
||||
_CurrentEnv(context->rm_TaskBlock,&environment); /* struct RexxTask * a0 : struct Environment * a0 */
|
||||
|
||||
/* Create the stem and component parts. */
|
||||
error = TypeString(variable_name,environment,&compound_string,&stem_string);
|
||||
if(error != 0)
|
||||
goto out;
|
||||
|
||||
/* Look up the value. NOTE: _FetchValue() will free the two 'struct NexxStr *' provided. */
|
||||
_FetchValue(environment,stem_string,compound_string,NULL,&is_literal,&ns); /* struct Environment * a0,struct NexxStr * a1,struct NexxStr * d0,struct Node * d1 : struct NexxStr * a0, LONG d1 */
|
||||
|
||||
/* If this is not a literal, return a pointer to the string. */
|
||||
if(!is_literal)
|
||||
(*return_value) = (STRPTR)ns->ns_Buff;
|
||||
|
||||
error = 0;
|
||||
|
||||
out:
|
||||
|
||||
return(error);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* Assigns a value to a variable in the current storage environment. */
|
||||
LONG
|
||||
SetRexxVar(struct RexxMsg *context,STRPTR variable_name,STRPTR value,LONG length)
|
||||
{
|
||||
struct Environment * environment;
|
||||
struct NexxStr * compound_string;
|
||||
struct NexxStr * stem_string;
|
||||
struct Node * symbol_table_node;
|
||||
struct NexxStr *value_string;
|
||||
LONG error;
|
||||
|
||||
/* Make sure the value string is not too long */
|
||||
if(length > 65535)
|
||||
{
|
||||
error = ERR10_009; /* symbol or string too long */
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(!CheckRexxMsg(context))
|
||||
{
|
||||
error = ERR10_010; /* invalid message packet */
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Find the current storage environment. */
|
||||
_CurrentEnv(context->rm_TaskBlock,&environment); /* struct RexxTask * a0 : struct Environment * a0 */
|
||||
|
||||
/* Create the stem and compound parts */
|
||||
error = TypeString(variable_name,environment,&compound_string,&stem_string);
|
||||
if(error != 0)
|
||||
goto out;
|
||||
|
||||
/* Locate or create the symbol node. NOTE: _EnterSymbol() will put the two 'struct NexxStr *' into
|
||||
the symbol table. It is not nececessary to free them. */
|
||||
symbol_table_node = _EnterSymbol(environment,stem_string,compound_string); /* struct Environment a0, struct NexxStr *a1, struct NexxStr * d0 : struct Node * d0 */
|
||||
if(symbol_table_node == NULL)
|
||||
{
|
||||
error = ERR10_003; /* no memory available */
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Create the value string. */
|
||||
value_string = MakeString(environment,value,length);
|
||||
if(value_string == NULL)
|
||||
{
|
||||
error = ERR10_003; /* no memory available */
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Install the value string. */
|
||||
_SetValue(environment,value_string,symbol_table_node); /* struct Environment *a0, struct NexxStr *a1, struct Node * d0 */
|
||||
|
||||
error = 0;
|
||||
|
||||
out:
|
||||
|
||||
return(error);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,3 +1,8 @@
|
||||
- Rewrote the GetRexxVar()/SetRexxVar() functions (mostly) in 'C', using available
|
||||
code as a reference. The 68k stubs currently only work for the 68k version of
|
||||
the library, and a solution for the OS4 build still needs to be found. The code
|
||||
is currently untested, but it should be complete.
|
||||
|
||||
- The printf() family now ignores argument specifications, as in "%2$d %1$d",
|
||||
which are used for localization on some platforms. This is a non-standard
|
||||
feature and the way clib2 treats it for now is just intended to avoid
|
||||
|
||||
Reference in New Issue
Block a user