@@ -45,7 +45,7 @@ def note_param_for_removal(vstr, name, var_list):
45
45
vstr .params_for_removal += [ copy .deepcopy (vstr .path ) ]
46
46
47
47
48
- def replace_value (vstr , name , var_list ):
48
+ def replace_value (vstr , name_in , var_list ):
49
49
""" This function actually replaces the variable at the path specified in vstr with the name $name
50
50
and saves all the replacements back to vstr.nodes """
51
51
@@ -55,32 +55,80 @@ def replace_value(vstr, name, var_list):
55
55
most nested variable will have a replacement_width of 1 while the top most will have a
56
56
replacement_width of 2. I hope that makes sense """
57
57
replacement_width = len (vstr .nodes )
58
+
58
59
for el in vstr .variable_replacement_order :
59
60
replacement_width //= len (var_list [el ])
60
- if el == name : break
61
-
61
+ if el == name_in : break
62
+
63
+ # Get all the sub-indexing values
64
+ tmp = name_in .split (':' )
65
+ name = tmp [0 ]
66
+ string_indexing_materials = tmp [1 :]
67
+ tmp = name .split ('[' )
68
+ name = tmp [0 ]
69
+ array_indexing_materials = [ x [:- 1 ] for x in tmp [1 :] ]
70
+
71
+ orig_values = var_list [name ]
72
+ new_values = copy .deepcopy (var_list [name ])
73
+ if len (array_indexing_materials ):
74
+ for arr_index in array_indexing_materials :
75
+ if arr_index != '@' and arr_index .isdigit ():
76
+ if int (arr_index ) < len (new_values ):
77
+ new_values = new_values [int (arr_index )]
78
+ else :
79
+ new_values = [ '' ]
80
+ else : # if there is an @ index then its just asking for the entire array. Sub-arrays generated like strings
81
+ new_values = new_values
82
+
83
+ # Do string indexing
84
+ if len (string_indexing_materials ):
85
+ start = int (string_indexing_materials [0 ])
86
+ length = int (string_indexing_materials [1 ])
87
+ if len (new_values ) > 1 :
88
+ new_values = new_values [start :start + length ]
89
+ else : # its a string
90
+ new_values [0 ] = new_values [0 ][start :start + length ]
91
+
92
+ var_list [name ] = new_values
93
+ if len (array_indexing_materials ) or len (string_indexing_materials ):
94
+ del var_list [name_in ]
62
95
""" h is used when the number of nodes is larger than the number of values
63
96
then you need to loop x times where x=itr_num and x*len(values) = len(vstr.nodes) """
64
97
factor = (len (var_list [name ]) * replacement_width )
65
98
itr_num = len (vstr .nodes ) // factor
99
+
100
+ def replace_pattern (pattern , vstr , nodes_index , name_in , delta , jth_node ):
101
+ param_node = vstr .at_path (vstr .nodes [nodes_index ], copy .copy (vstr .path ))
102
+ orig_word = copy .deepcopy (jth_node .word )
103
+ jth_node .word = re .sub (pattern , value , jth_node .word )
104
+ if jth_node .word != orig_word :
105
+ vstr .nodes [nodes_index ] = bashparser .ast .expand_ast_along_path (vstr .nodes [nodes_index ], copy .copy (vstr .path [:- 1 ]), delta )
106
+ vstr .nodes [nodes_index ] = bashparser .ast .shift_ast_right_of_path (vstr .nodes [nodes_index ], copy .copy (vstr .path [:- 1 ]), delta )
107
+
66
108
67
109
for h in range (0 , itr_num ):
68
110
for i , value in enumerate (var_list [name ]): # By this point the number of nodes will have factor of num of values
69
111
for j in range (0 , replacement_width ): # Indexing scheme is:
70
112
nodes_index = (h * factor ) + (i * replacement_width ) + j
71
113
72
114
if type (value ) is str :
73
- pattern = r'\$' + re .escape (name ) + r'\b'
74
115
jth_node = vstr .at_path (vstr .nodes [nodes_index ], copy .copy (vstr .path [:- 1 ]))
75
- jth_node .word = re .sub (pattern , value , jth_node .word )
76
- delta = len (value ) - (len ('$' ) + len (name )) # Change in text len due to value sub. ie delta = new_len - old_len
77
- vstr .nodes [nodes_index ] = bashparser .ast .expand_ast_along_path (vstr .nodes [nodes_index ], copy .copy (vstr .path [:- 1 ]), delta )
78
- vstr .nodes [nodes_index ] = bashparser .ast .shift_ast_right_of_path (vstr .nodes [nodes_index ], copy .copy (vstr .path [:- 1 ]), delta )
116
+ orig_word = jth_node .word
117
+ delta = len (value ) - (len ('$' ) + len (name_in )) # + ((jth_node.pos[1] - jth_node.pos[0]) - len(jth_node.word)) # Change in text len due to value sub. ie delta = new_len - old_len
118
+ pattern = r'\$' + re .escape (name_in ) + r'\b'
119
+ replace_pattern (pattern , vstr , nodes_index , name_in , delta , jth_node )
120
+ delta -= 2
121
+ # if vstr.at_path(vstr.nodes[nodes_index], copy.copy(vstr.path)).value == '${' + name_in + '}':
122
+ if orig_word == jth_node .word :
123
+ print ('at this point in replace variables bashparser' )
124
+ pattern = re .escape ('${' + name_in + '}' )
125
+ replace_pattern (pattern , vstr , nodes_index , name_in , delta , jth_node )
126
+
79
127
elif type (value ) is bashlex .ast .node :
80
128
vstr .nodes [nodes_index ] = vstr .swap_node (root = vstr .nodes [nodes_index ], path = copy .copy (vstr .path [:- 1 ]), child = value )
81
129
else :
82
130
raise ValueError ("Error! Variable replacement value wasn't a str or node. bashparser.variables.replace_variables" )
83
-
131
+ var_list [ name ] = orig_values
84
132
85
133
def apply_fn (node , vstr , var_list , replace_blanks = False ):
86
134
""" This function only works on parameter nodes in the tree. If there is no parameter
0 commit comments