1#!/usr/bin/env python
2
3r"""
4Define the var_stack class.
5"""
6
7import sys
8import collections
9
10try:
11    from robot.utils import DotDict
12except ImportError:
13    pass
14
15import gen_print as gp
16
17
18class var_stack:
19
20    r"""
21    Define the variable stack class.
22
23    An object of this class can be used to push variable name/variable value
24    pairs which may be popped off the stack at a later time.  The most obvious
25    use for this is for saving variables that are to be restored later.
26
27    Example code:
28
29    save_stack = var_stack('save_stack')
30    var1 = "johnson"
31    save_stack.push(var1)
32    var1 = "smith"
33    ...
34    var1 = save_stack.pop('var1')
35    # var1 has now been restored to the value "johnson".
36
37
38    Example use:
39
40    var1 = "mike"
41    save_stack.push(var1)
42    var1 = "james"
43    save_stack.push(var1)
44    save_stack.print_obj()
45
46    # The print-out of the object would then look like this:
47
48    save_stack:
49      stack_dict:
50        [var1]:
51          [var1][0]:  mike
52          [var1][1]:  james
53
54    # Continuing with this code...
55
56    var1 = save_stack.pop('var1')
57    save_stack.print_obj()
58
59    # The print-out of the object would then look like this:
60
61    save_stack:
62      stack_dict:
63        [var1]:
64          [var1][0]:  mike
65    """
66
67    def __init__(self,
68                 obj_name='var_stack'):
69
70        r"""
71        Initialize a new object of this class type.
72
73        Description of argument(s):
74        obj_name                    The name of the object.  This is useful
75                                    for printing out the object.
76        """
77
78        self.__obj_name = obj_name
79        # Create a stack dictionary.
80        try:
81            self.__stack_dict = collections.OrderedDict()
82        except AttributeError:
83            self.__stack_dict = DotDict()
84
85    def sprint_obj(self):
86
87        r"""
88        sprint the fields of this object.  This would normally be for debug
89        purposes.
90        """
91
92        buffer = ""
93
94        buffer += self.__obj_name + ":\n"
95        indent = 2
96        buffer += gp.sprint_varx('stack_dict', self.__stack_dict, 1, indent)
97
98        return buffer
99
100    def print_obj(self):
101
102        r"""
103        print the fields of this object to stdout.  This would normally be for
104        debug purposes.
105        """
106
107        sys.stdout.write(self.sprint_obj())
108
109    def push(self,
110             var_value,
111             var_name=""):
112
113        r"""
114        push the var_name/var_value pair onto the stack.
115
116        Description of argument(s):
117        var_value                   The value being pushed.
118        var_name                    The name of the variable containing the
119                                    value to be pushed.  This parameter is
120                                    normally unnecessary as this function can
121                                    figure out the var_name.  This is provided
122                                    for Robot callers.  In this scenario, we
123                                    are unable to get the variable name
124                                    ourselves.
125        """
126
127        if var_name == "":
128            # The caller has not passed a var_name so we will try to figure
129            # it out.
130            stack_frame_ix = 2
131            var_name = gp.get_arg_name(0, 1, stack_frame_ix)
132        if var_name in self.__stack_dict:
133            self.__stack_dict[var_name].append(var_value)
134        else:
135            self.__stack_dict[var_name] = [var_value]
136
137    def pop(self,
138            var_name=""):
139
140        r"""
141        Pop the value for the given var_name from the stack and return it.
142
143        Description of argument(s):
144        var_name                    The name of the variable whose value is to
145                                    be popped.
146        """
147
148        return self.__stack_dict[var_name].pop()
149