home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
-
- MODUL
- varstack.c
-
- DESCRIPTION
- Variable Stack for DME/XDME
-
- NOTES
- -/-
-
- BUGS
- <none known>
-
- TODO
- -/-
-
- EXAMPLES
- -/-
-
- SEE ALSO
- vars.c
-
- INDEX
-
- HISTORY
- 05-12-92 b_noll created
- 26-08-93 VSTK_drop added
- 24-06-94 renamed VARS to VRST
-
- ******************************************************************************/
-
- /*
- ** (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"
- #ifdef PATCH_NULL
- #include "COM.h"
- #include "libs/AUTO.h"
- #endif
-
- /**************************************
- 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 _VRST
- {
- NODE Node;
- char* Str;
- } VRST;
-
-
- /**************************************
- Interne Prototypes
- **************************************/
-
- void VSTK_drop (VRST *);
-
- /**************************************
- Impementation
- **************************************/
-
-
- /*
- *! >PUSHVAR varname
- *!
- *! push the contents of the variable varname onto variable-stack
- *!
- */
-
- void do_pushVAR (void)
- {
- VRST *v;
- int type;
-
- if ((v = malloc (sizeof (VRST))))
- { /* allocate a node */
- setmem(v, sizeof (VRST), 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
- { /* else free all what You have already allocated */
- if (v->Node.ln_Name)
- {
- error ("%s: failure!\nno memory", av[0]);
- free(v->Node.ln_Name);
- } /* if */
- if (v->Str)
- {
- error ("%s: failure!\nno memory or unknown variable", av[0]);
- free(v->Str);
- } /* if */
- free(v);
-
- } /* 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)
- {
- VRST *v;
-
- if ((v = (VRST *)FindName((LIST*)&varstack, av[1])))
- { /* if there is a matching stack-entry */
- SetTypedVar(av[1], v->Str, v->Node.ln_Type); /* do a setvar to its name with its contents */
- VSTK_drop (v); /* and drop the entry */
- } 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)
- {
- VRST *v;
-
- if ((v = (VRST *)FindName((LIST*)&varstack, av[1])))
- { /* if there is a matching stack-entry */
- SetTypedVar(av[1], v->Str, v->Node.ln_Type); /* do a setvar to its name with its 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)
- {
- VRST *v;
-
- if ((v = (VRST *)FindName((LIST*)&varstack, av[1])))
- { /* if there is a matching stack-entry */
- 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)
- {
- VRST *v;
- VARS *w;
-
- /* ---- we cannot use GetSucc() here, since we would take the successor of a freed node =8-( */
-
- for (v = (VRST *)varstack.mlh_Head; (w = (VRST *)v->Node.ln_Succ) != NULL; v = w) /* for all nodes ... */
- if (strcmp(v->Node.ln_Name, av[1]) == 0) /* if they match ... */
- VSTK_drop (v); /* drop them ... */
- } /* do_purgeVAR */
-
-
- void do_dropVAR (void)
- {
- VRST *v;
- if ((v = (VRST *)FindName((LIST*)&varstack, av[1]))) /* find them first matching node */
- VSTK_drop (v); /* ... and drop it */
- } /* do_dropVAR */
-
-
- void VSTK_drop (VRST *v)
- {
- /* ---- Remove an entry from the stack, and free its contents and itself */
-
- if (v)
- {
- Remove((NODE*)v);
- free(v->Str);
- free(v->Node.ln_Name);
- free(v);
- } /* if */
- } /* VSTK_drop */
-
-
-
-
- #ifdef PATCH_NULL
-
- static const
- struct CommandNode VSTK_Commands[] =
- {
- {ENODE("pickvar"), 1, CF_VWM|CF_COK|CF_ICO, (FPTR)do_pickVAR },
- {ENODE("popvar"), 1, CF_VWM|CF_COK|CF_ICO, (FPTR)do_popVAR },
- {ENODE("pushvar"), 1, CF_VWM|CF_COK|CF_ICO, (FPTR)do_pushVAR },
- {ENODE("purgevar"), 1, CF_VWM|CF_COK|CF_ICO, (FPTR)do_purgeVAR },
- {ENODE("swapvar"), 1, CF_VWM|CF_COK|CF_ICO, (FPTR)do_swapVAR },
- {ENODE("dropvar"), 1, CF_VWM|CF_COK|CF_ICO, (FPTR)do_dropVAR },
- };
-
- MK_AUTOINIT(VSTK_Init)
- {
- int i;
-
- NewList ((struct List*)&varstack);
-
- for (i = sizeof (VSTK_Commands)/sizeof (struct CommandNode) - 1;i >= 0; --i)
- COM_Add (&VSTK_Commands[i]);
- } /* VSTK_Init */
-
-
- MK_AUTOEXIT(VSTK_Exit)
- {
- int i;
- APTR lock;
- VRST*v;
-
- while ((v = GetHead (&varstack)))
- VSTK_drop (v);
-
- for (i = sizeof (VSTK_Commands)/sizeof (struct CommandNode) - 1; (i >= 0); DEC(i))
- if ((lock = COM_Lock (VSTK_Commands[i].Node.ln_Name)))
- COM_Remove (lock);
- } /* VSTK_Exit */
- #endif
-
-
- /******************************************************************************
- ***** ENDE varstack.c
- ******************************************************************************/
-
-