home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / wp_dtp / xdme1821.lha / XDME / varstack.c < prev    next >
C/C++ Source or Header  |  1993-03-25  |  6KB  |  258 lines

  1. /******************************************************************************
  2.  
  3.     MODUL
  4.     varstack.c
  5.  
  6.     DESCRIPTION
  7.     Variable Stack for DME/XDME
  8.  
  9.     NOTES
  10.     -/-
  11.  
  12.     BUGS
  13.     <none known>
  14.  
  15.     TODO
  16.     -/-
  17.  
  18.     EXAMPLES
  19.     -/-
  20.  
  21.     SEE ALSO
  22.     vars.c
  23.  
  24.     INDEX
  25.  
  26.     HISTORY
  27.     <see RCS-File>
  28.  
  29.  
  30. ******************************************************************************/
  31.  
  32. /*
  33. **  (C)Copyright 1992 by Bernd Noll for null/zero-soft
  34. **  All Rights Reserved
  35. **
  36. **  RCS Header: $Id: varstack.c,v 1.65 92/12/05 12:47:24 b_noll Exp $
  37. **
  38. **
  39. *!**********************************************************
  40. *!
  41. *!  Variable Stacking:
  42. *!
  43. *!  Stacking for all structures, which may be read and
  44. *!  written via GetTypedVar()
  45. *!  (Please notice that stackable are only variables,
  46. *!   not macros, menues or mappings (they are stackable, but
  47. *!   popping or picking might fail))
  48. *!
  49. *!  Users should be aware to pop their entries from the stack
  50. *!  when they are needed not any more
  51. *!  (We have NOT planned to create a garbage-collector :-))
  52. *!
  53. ************************************************************
  54. **
  55. **  Implementator's note:
  56. **
  57. **  variable stacking is done in a quiet simple way:
  58. **  all variables are searched with gettypedvar and their types
  59. **  are used as Node.ln_Type - entry
  60. **
  61. **  currently (12-92) we use the same structure for storing variables
  62. **  on varstack which is used for storage in the main variable
  63. **  lists, but I preferred redefining that structure, as this method
  64. **  gives us the possibility of changing our definitions locally.
  65. **  (This is as we are just implementing AVL-Trees for Varstorage)
  66. */
  67.  
  68. /**************************************
  69.         Includes
  70. **************************************/
  71. #include "defs.h"
  72.  
  73.  
  74. /**************************************
  75.         Globale Exports
  76. **************************************/
  77. Prototype void do_pushVAR  (void);
  78. Prototype void do_pickVAR  (void);
  79. Prototype void do_popVAR   (void);
  80. Prototype void do_swapVAR  (void);
  81. Prototype void do_purgeVAR (void);
  82.  
  83.  
  84. /**************************************
  85.       Interne Defines & Strukturen
  86. **************************************/
  87. #define MLIST struct MinList
  88. #define MNODE struct MinNode
  89.  
  90. static MLIST varstack =
  91. { (MNODE*)&varstack.mlh_Tail, NULL, (MNODE*)&varstack.mlh_Head };
  92.  
  93.  
  94. typedef struct _VARS
  95. {
  96.     NODE    Node;
  97.     char*   Str;
  98. } VARS;
  99.  
  100.  
  101. /**************************************
  102.        Interne Prototypes
  103. **************************************/
  104.  
  105.  
  106. /**************************************
  107.        Impementation
  108. **************************************/
  109.  
  110. /*
  111. *! >PUSHVAR varname
  112. *!
  113. *!    push the contents of the variable varname onto variable-stack
  114. *!
  115. */
  116.  
  117. void do_pushVAR (void)
  118. {
  119.     VARS* v;
  120.     int type;
  121.  
  122.     if (v = malloc (sizeof (VARS)))
  123.     {          /* allocate a node */
  124.     setmem(v, sizeof (VARS), 0);
  125.     v->Node.ln_Name = strdup (av[1]);        /* and space for name and value */
  126.     v->Str = GetTypedVar (av[1], &type);
  127.     if (v->Node.ln_Name && v->Str)
  128.     {     /* if its done, fill in all values and push the node onto the varstack */
  129.         v->Node.ln_Type = type;
  130.         AddHead((LIST*)&varstack, (NODE*)v);
  131.     } else
  132.     {
  133.         if (v->Node.ln_Name)
  134.         {           /* else free all what yu have already allocated */
  135.         free(v->Node.ln_Name);
  136.         } /* if */
  137.         if (v->Str)
  138.         {
  139.         free(v->Str);
  140.         } /* if */
  141.         free(v);
  142.  
  143.         error ("%s: failure!\nno memory or unknown variable", av[0]);
  144.     } /* if (not) malloced|found */
  145.     } else
  146.     {
  147.     error ("%s: no memory for stack-entry", av[0]);
  148.     } /* if (not) malloced */
  149. } /* do_pushVAR */
  150.  
  151.  
  152.  
  153. /*
  154. *! >POPVAR varname
  155. *!
  156. *!    get the latest to variable-stack pushed contents of the variable
  157. *!    varname back and free the stack-entry
  158. *!
  159. */
  160.  
  161. void do_popVAR (void)
  162. {
  163.     VARS* v;
  164.  
  165.     if (v = (VARS*)FindName((LIST*)&varstack, av[1]))
  166.     { /* if there is a stack-entry of the right name */
  167.     SetTypedVar(av[1], v->Str, v->Node.ln_Type); /* do a setvar to the right variable and the right contents */
  168.     Remove((NODE*)v);                       /* then remove the node from varstack and */
  169.     free(v->Str);                           /* free all its data */
  170.     free(v->Node.ln_Name);
  171.     free(v);
  172.     } else
  173.     {
  174.     error ("%s: stackentry %s not found", av[0], av[1]);
  175.     } /* if (not) found */
  176. } /* do_popVAR */
  177.  
  178.  
  179.  
  180. /*
  181. *! >PICKVAR varname
  182. *!
  183. *!    get the latest to variable-stack pushed contents of the variable
  184. *!    varname back without freeing the stack-entry
  185. *!
  186. */
  187.  
  188. void do_pickVAR (void)
  189. {
  190.     VARS* v;
  191.  
  192.     if (v = (VARS*)FindName((LIST*)&varstack, av[1]))
  193.     { /* if there is a stack-entry of the right name */
  194.     SetTypedVar(av[1], v->Str, v->Node.ln_Type); /* do a setvar to the right variable and the right contents */
  195.     } else
  196.     {
  197.     error ("%s: stackentry %s not found", av[0], av[1]);
  198.     } /* if (not) found */
  199. } /* do_pickVAR */
  200.  
  201.  
  202.  
  203. /*
  204. *! >SWAPVAR varname
  205. *!
  206. *!    swap the contents of the variable varname and of its first occurancy in variable-stack
  207. *!
  208. **  this is not a very effective way of change, I would say,
  209. **  but it is one of the shortest
  210. */
  211.  
  212. void do_swapVAR (void)
  213. {
  214.     VARS* v;
  215.  
  216.     if (v = (VARS*)FindName((LIST*)&varstack, av[1]))
  217.     { /* if there is a stack-entry of the right name */
  218.     Remove((NODE*)v);                        /* remove it */
  219.     do_pushVAR();                            /* push the variables current contents onto stack */
  220.     AddHead((LIST*)&varstack, (NODE*)v);     /* set the elder stack-entry before that new node */
  221.     do_popVAR();                             /* and then pop it into the variable */
  222.     } else
  223.     {
  224.     error ("%s: stackentry %s not found", av[0], av[1]);
  225.     } /* if (not) found */
  226. } /* do_swapVAR */
  227.  
  228.  
  229.  
  230. /*
  231. *! >PURGEVAR varname
  232. *!
  233. *!    remove all entries with the name varname from varstack
  234. *!
  235. */
  236.  
  237. void do_purgeVAR (void)
  238. {
  239.     VARS* v;
  240.  
  241.     for (v = (VARS*)varstack.mlh_Head; v; v = (VARS*)v->Node.ln_Succ)
  242.     { /* with all entries of varstack do */
  243.     if (strcmp(v->Node.ln_Name, av[1]) == 0)
  244.     { /* if they match the requested name */
  245.         Remove((NODE*)v);                      /* remove them and free their parts */
  246.         free(v->Str);
  247.         free(v->Node.ln_Name);
  248.         free(v);
  249.     } /* if */
  250.     } /* for */
  251. } /* do_purgeVAR */
  252.  
  253.  
  254. /******************************************************************************
  255. *****  ENDE varstack.c
  256. ******************************************************************************/
  257.  
  258.