#
# saveglob();
# restglob();
#
# Author: Dominik Gruntz - gruntz@inf.ethz.ch - May 9, 1992
#

macro( ScopeCounter = `saveglob/ScopeCounter` );
macro( ScopeName = `saveglob/ScopeName` );

saveglob := proc() 
   local name;
   options `Copyright 1992 by Dominik Gruntz, ETH Zuerich`;

   if nargs>0 then name := args[1] else name := `` fi;
   saveglob(ScopeCounter) := 
      map(proc(t) local res; res := NULL;
             if whattype(eval(t)) <> 'exprseq' then res := 't' = eval(t) fi;
             if type(t,table) then assign(t, copy(t)) fi;
             res;
          end, 
          {anames()} 
      ):
   ScopeCounter := ScopeCounter+1;
   ScopeName := name;
   NULL
end:

restglob := proc() 
   local name;
   options `Copyright 1992 by Dominik Gruntz, ETH Zuerich`;

   if ScopeCounter = 0 then ERROR(`nothing saved!`) fi;
   name := ScopeName;
   assign( saveglob(ScopeCounter-1) );
   if name <> `` then
      lprint(`<-- exit `,name,`(now in `,ScopeName,`)`);
   fi;
   NULL
end:

ScopeCounter := 0:
ScopeName    := `top level`:

`help/text/saveglob` := TEXT(
`FUNCTION: saveglob - saves all global variables `,
`   `,
`CALLING SEQUENCE:`,
`   saveglob()`,
`   saveglob(string)`,
`   `,
`   restglob()`,
`   `,
`PARAMETERS:`,
`   string - an arbitrary string or name`,
`   `,
`SYNOPSIS:   `,
`- saveglob saves all global variables of a Maple session and keeps them`,
`  for further use in the same session. After a call to saveglob, all`,
`  globals may be deleted or changed, and after a call  to restglob,`,
`  the old values of the changed globals are restored. New variables, which`,
`  have been generated after the last call to saveglob, will not be`,
`  destroyed.`,
`   `,
`- saveglob may be called recursively.`,
`   `,
`- saveglob is an excellent tool if you want to trace a program step by`,
`  step interactively. Every time the program calls a procedure, call saveglob`,
`  and all globals are saved. You now can execute that procedure interactively`,
`  without loosing any globals. You may pass an arbitrary string as an argument,`,
`  probably the procedure you enter interactively. If you leave that procedure,`,
`  call restglob() and you get a message similar to the one if`,
`  you debug a program with a high value of printlevel.`,
`   `,
`- Exceptions: `,
`   o expression sequences assigned to a global are not stored.`,
`   o if a remember table of a procedure is changed after saveglob, `,
`     restglob will not restore the old values of the remember table.`,
`   `,
`   `,
`EXAMPLES:   `,
`> a := [2,3]: f := n->n^2: t := table([A=a,B=b]): g(1):=1:`,
`> saveglob();`,
`> a := 'a': f := 7: t := 't': g := sin(x): n := 5:`,
`> restglob();`,
`> a, eval(f), t[A], t[B], g(1), n;`,
`                                       2`,
`                         [2, 3], n -> n , [2, 3], b, 1, 5`,
`   `,
`> saveglob( ``saveglob()`` );`,
`> t[B] := c: g(1) := 2: g(2) := 2:`,
`> restglob();`,
`<-- exit    saveglob()   (now in    top level   )`,
`> op(t);   `,
`                                 table([`,
`                                     A = [2, 3]`,
`                                     B = b`,
`                                 ])`,
`> op(4,eval(g));`,
`                                   table([`,
`                                       1 = 2`,
`                                       2 = 2`,
`                                   ])`,
`   `,
`SEE ALSO: save, read, assign, copy`
):

`help/text/restglob` := `help/text/saveglob`:

save `saveglob.m`;
done;
