home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Elysian Archive
/
AmigaElysianArchive.iso
/
wp_dtp
/
xdme1821.lha
/
XDME
/
varstack.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-25
|
6KB
|
258 lines
/******************************************************************************
MODUL
varstack.c
DESCRIPTION
Variable Stack for DME/XDME
NOTES
-/-
BUGS
<none known>
TODO
-/-
EXAMPLES
-/-
SEE ALSO
vars.c
INDEX
HISTORY
<see RCS-File>
******************************************************************************/
/*
** (C)Copyright 1992 by Bernd Noll for null/zero-soft
** All Rights Reserved
**
** RCS Header: $Id: varstack.c,v 1.65 92/12/05 12:47:24 b_noll Exp $
**
**
*!**********************************************************
*!
*! Variable Stacking:
*!
*! Stacking for all structures, which may be read and
*! written via GetTypedVar()
*! (Please notice that stackable are only variables,
*! not macros, menues or mappings (they are stackable, but
*! popping or picking might fail))
*!
*! Users should be aware to pop their entries from the stack
*! when they are needed not any more
*! (We have NOT planned to create a garbage-collector :-))
*!
************************************************************
**
** Implementator's note:
**
** variable stacking is done in a quiet simple way:
** all variables are searched with gettypedvar and their types
** are used as Node.ln_Type - entry
**
** currently (12-92) we use the same structure for storing variables
** on varstack which is used for storage in the main variable
** lists, but I preferred redefining that structure, as this method
** gives us the possibility of changing our definitions locally.
** (This is as we are just implementing AVL-Trees for Varstorage)
*/
/**************************************
Includes
**************************************/
#include "defs.h"
/**************************************
Globale Exports
**************************************/
Prototype void do_pushVAR (void);
Prototype void do_pickVAR (void);
Prototype void do_popVAR (void);
Prototype void do_swapVAR (void);
Prototype void do_purgeVAR (void);
/**************************************
Interne Defines & Strukturen
**************************************/
#define MLIST struct MinList
#define MNODE struct MinNode
static MLIST varstack =
{ (MNODE*)&varstack.mlh_Tail, NULL, (MNODE*)&varstack.mlh_Head };
typedef struct _VARS
{
NODE Node;
char* Str;
} VARS;
/**************************************
Interne Prototypes
**************************************/
/**************************************
Impementation
**************************************/
/*
*! >PUSHVAR varname
*!
*! push the contents of the variable varname onto variable-stack
*!
*/
void do_pushVAR (void)
{
VARS* v;
int type;
if (v = malloc (sizeof (VARS)))
{ /* allocate a node */
setmem(v, sizeof (VARS), 0);
v->Node.ln_Name = strdup (av[1]); /* and space for name and value */
v->Str = GetTypedVar (av[1], &type);
if (v->Node.ln_Name && v->Str)
{ /* if its done, fill in all values and push the node onto the varstack */
v->Node.ln_Type = type;
AddHead((LIST*)&varstack, (NODE*)v);
} else
{
if (v->Node.ln_Name)
{ /* else free all what yu have already allocated */
free(v->Node.ln_Name);
} /* if */
if (v->Str)
{
free(v->Str);
} /* if */
free(v);
error ("%s: failure!\nno memory or unknown variable", av[0]);
} /* if (not) malloced|found */
} else
{
error ("%s: no memory for stack-entry", av[0]);
} /* if (not) malloced */
} /* do_pushVAR */
/*
*! >POPVAR varname
*!
*! get the latest to variable-stack pushed contents of the variable
*! varname back and free the stack-entry
*!
*/
void do_popVAR (void)
{
VARS* v;
if (v = (VARS*)FindName((LIST*)&varstack, av[1]))
{ /* if there is a stack-entry of the right name */
SetTypedVar(av[1], v->Str, v->Node.ln_Type); /* do a setvar to the right variable and the right contents */
Remove((NODE*)v); /* then remove the node from varstack and */
free(v->Str); /* free all its data */
free(v->Node.ln_Name);
free(v);
} else
{
error ("%s: stackentry %s not found", av[0], av[1]);
} /* if (not) found */
} /* do_popVAR */
/*
*! >PICKVAR varname
*!
*! get the latest to variable-stack pushed contents of the variable
*! varname back without freeing the stack-entry
*!
*/
void do_pickVAR (void)
{
VARS* v;
if (v = (VARS*)FindName((LIST*)&varstack, av[1]))
{ /* if there is a stack-entry of the right name */
SetTypedVar(av[1], v->Str, v->Node.ln_Type); /* do a setvar to the right variable and the right contents */
} else
{
error ("%s: stackentry %s not found", av[0], av[1]);
} /* if (not) found */
} /* do_pickVAR */
/*
*! >SWAPVAR varname
*!
*! swap the contents of the variable varname and of its first occurancy in variable-stack
*!
** this is not a very effective way of change, I would say,
** but it is one of the shortest
*/
void do_swapVAR (void)
{
VARS* v;
if (v = (VARS*)FindName((LIST*)&varstack, av[1]))
{ /* if there is a stack-entry of the right name */
Remove((NODE*)v); /* remove it */
do_pushVAR(); /* push the variables current contents onto stack */
AddHead((LIST*)&varstack, (NODE*)v); /* set the elder stack-entry before that new node */
do_popVAR(); /* and then pop it into the variable */
} else
{
error ("%s: stackentry %s not found", av[0], av[1]);
} /* if (not) found */
} /* do_swapVAR */
/*
*! >PURGEVAR varname
*!
*! remove all entries with the name varname from varstack
*!
*/
void do_purgeVAR (void)
{
VARS* v;
for (v = (VARS*)varstack.mlh_Head; v; v = (VARS*)v->Node.ln_Succ)
{ /* with all entries of varstack do */
if (strcmp(v->Node.ln_Name, av[1]) == 0)
{ /* if they match the requested name */
Remove((NODE*)v); /* remove them and free their parts */
free(v->Str);
free(v->Node.ln_Name);
free(v);
} /* if */
} /* for */
} /* do_purgeVAR */
/******************************************************************************
***** ENDE varstack.c
******************************************************************************/