1e7e9171eSGeorge Keishing#!/usr/bin/env python3
205cd10e3SMichael Walsh
305cd10e3SMichael Walshr"""
405cd10e3SMichael WalshDefine the var_stack class.
505cd10e3SMichael Walsh"""
605cd10e3SMichael Walsh
705cd10e3SMichael Walshimport collections
8514fad72SMichael Walshimport copy
9*20f38712SPatrick Williamsimport sys
1005cd10e3SMichael Walsh
1105cd10e3SMichael Walshtry:
1205cd10e3SMichael Walsh    from robot.utils import DotDict
1305cd10e3SMichael Walshexcept ImportError:
1405cd10e3SMichael Walsh    pass
1505cd10e3SMichael Walsh
1605cd10e3SMichael Walshimport gen_print as gp
1705cd10e3SMichael Walsh
1805cd10e3SMichael Walsh
1905cd10e3SMichael Walshclass var_stack:
2005cd10e3SMichael Walsh    r"""
2105cd10e3SMichael Walsh    Define the variable stack class.
2205cd10e3SMichael Walsh
23410b1787SMichael Walsh    An object of this class can be used to push variable name/variable value pairs which may be popped off
24410b1787SMichael Walsh    the stack at a later time.  The most obvious use for this is for saving variables that are to be restored
25410b1787SMichael Walsh    later.
2605cd10e3SMichael Walsh
2705cd10e3SMichael Walsh    Example code:
2805cd10e3SMichael Walsh
2905cd10e3SMichael Walsh    save_stack = var_stack('save_stack')
3005cd10e3SMichael Walsh    var1 = "johnson"
3105cd10e3SMichael Walsh    save_stack.push(var1)
3205cd10e3SMichael Walsh    var1 = "smith"
3305cd10e3SMichael Walsh    ...
3405cd10e3SMichael Walsh    var1 = save_stack.pop('var1')
3505cd10e3SMichael Walsh    # var1 has now been restored to the value "johnson".
3605cd10e3SMichael Walsh
3705cd10e3SMichael Walsh
3805cd10e3SMichael Walsh    Example use:
3905cd10e3SMichael Walsh
4005cd10e3SMichael Walsh    var1 = "mike"
4105cd10e3SMichael Walsh    save_stack.push(var1)
4205cd10e3SMichael Walsh    var1 = "james"
4305cd10e3SMichael Walsh    save_stack.push(var1)
4405cd10e3SMichael Walsh    save_stack.print_obj()
4505cd10e3SMichael Walsh
4605cd10e3SMichael Walsh    # The print-out of the object would then look like this:
4705cd10e3SMichael Walsh
4805cd10e3SMichael Walsh    save_stack:
4905cd10e3SMichael Walsh      stack_dict:
5005cd10e3SMichael Walsh        [var1]:
5105cd10e3SMichael Walsh          [var1][0]:  mike
5205cd10e3SMichael Walsh          [var1][1]:  james
5305cd10e3SMichael Walsh
5405cd10e3SMichael Walsh    # Continuing with this code...
5505cd10e3SMichael Walsh
5605cd10e3SMichael Walsh    var1 = save_stack.pop('var1')
5705cd10e3SMichael Walsh    save_stack.print_obj()
5805cd10e3SMichael Walsh
5905cd10e3SMichael Walsh    # The print-out of the object would then look like this:
6005cd10e3SMichael Walsh
6105cd10e3SMichael Walsh    save_stack:
6205cd10e3SMichael Walsh      stack_dict:
6305cd10e3SMichael Walsh        [var1]:
6405cd10e3SMichael Walsh          [var1][0]:  mike
6505cd10e3SMichael Walsh    """
6605cd10e3SMichael Walsh
67*20f38712SPatrick Williams    def __init__(self, obj_name="var_stack"):
6805cd10e3SMichael Walsh        r"""
6905cd10e3SMichael Walsh        Initialize a new object of this class type.
7005cd10e3SMichael Walsh
7105cd10e3SMichael Walsh        Description of argument(s):
72410b1787SMichael Walsh        obj_name                    The name of the object.  This is useful for printing out the object.
7305cd10e3SMichael Walsh        """
7405cd10e3SMichael Walsh
7505cd10e3SMichael Walsh        self.__obj_name = obj_name
7605cd10e3SMichael Walsh        # Create a stack dictionary.
7705cd10e3SMichael Walsh        try:
7805cd10e3SMichael Walsh            self.__stack_dict = collections.OrderedDict()
7905cd10e3SMichael Walsh        except AttributeError:
8005cd10e3SMichael Walsh            self.__stack_dict = DotDict()
8105cd10e3SMichael Walsh
8205cd10e3SMichael Walsh    def sprint_obj(self):
8305cd10e3SMichael Walsh        r"""
84410b1787SMichael Walsh        sprint the fields of this object.  This would normally be for debug purposes.
8505cd10e3SMichael Walsh        """
8605cd10e3SMichael Walsh
8705cd10e3SMichael Walsh        buffer = ""
8805cd10e3SMichael Walsh
8905cd10e3SMichael Walsh        buffer += self.__obj_name + ":\n"
9005cd10e3SMichael Walsh        indent = 2
91*20f38712SPatrick Williams        buffer += gp.sprint_varx("stack_dict", self.__stack_dict, indent)
9205cd10e3SMichael Walsh
9305cd10e3SMichael Walsh        return buffer
9405cd10e3SMichael Walsh
9505cd10e3SMichael Walsh    def print_obj(self):
9605cd10e3SMichael Walsh        r"""
97410b1787SMichael Walsh        print the fields of this object to stdout.  This would normally be for debug purposes.
9805cd10e3SMichael Walsh        """
9905cd10e3SMichael Walsh
10005cd10e3SMichael Walsh        sys.stdout.write(self.sprint_obj())
10105cd10e3SMichael Walsh
102*20f38712SPatrick Williams    def push(self, var_value, var_name=""):
10305cd10e3SMichael Walsh        r"""
10405cd10e3SMichael Walsh        push the var_name/var_value pair onto the stack.
10505cd10e3SMichael Walsh
10605cd10e3SMichael Walsh        Description of argument(s):
10705cd10e3SMichael Walsh        var_value                   The value being pushed.
108410b1787SMichael Walsh        var_name                    The name of the variable containing the value to be pushed.  This
109410b1787SMichael Walsh                                    parameter is normally unnecessary as this function can figure out the
110410b1787SMichael Walsh                                    var_name.  This is provided for Robot callers.  In this scenario, we are
111410b1787SMichael Walsh                                    unable to get the variable name ourselves.
11205cd10e3SMichael Walsh        """
11305cd10e3SMichael Walsh
11405cd10e3SMichael Walsh        if var_name == "":
115410b1787SMichael Walsh            # The caller has not passed a var_name so we will try to figure it out.
11605cd10e3SMichael Walsh            stack_frame_ix = 2
11705cd10e3SMichael Walsh            var_name = gp.get_arg_name(0, 1, stack_frame_ix)
11805cd10e3SMichael Walsh        if var_name in self.__stack_dict:
11905cd10e3SMichael Walsh            self.__stack_dict[var_name].append(var_value)
12005cd10e3SMichael Walsh        else:
121514fad72SMichael Walsh            self.__stack_dict[var_name] = copy.deepcopy([var_value])
12205cd10e3SMichael Walsh
123*20f38712SPatrick Williams    def pop(self, var_name=""):
12405cd10e3SMichael Walsh        r"""
12505cd10e3SMichael Walsh        Pop the value for the given var_name from the stack and return it.
12605cd10e3SMichael Walsh
12705cd10e3SMichael Walsh        Description of argument(s):
128410b1787SMichael Walsh        var_name                    The name of the variable whose value is to be popped.
12905cd10e3SMichael Walsh        """
13005cd10e3SMichael Walsh
13105cd10e3SMichael Walsh        return self.__stack_dict[var_name].pop()
132