@@ -45,7 +45,7 @@ def note_param_for_removal(vstr, name, var_list):
4545 vstr .params_for_removal += [ copy .deepcopy (vstr .path ) ]
4646
4747
48- def replace_value (vstr , name , var_list ):
48+ def replace_value (vstr , name_in , var_list ):
4949 """ This function actually replaces the variable at the path specified in vstr with the name $name
5050 and saves all the replacements back to vstr.nodes """
5151
@@ -55,32 +55,80 @@ def replace_value(vstr, name, var_list):
5555 most nested variable will have a replacement_width of 1 while the top most will have a
5656 replacement_width of 2. I hope that makes sense """
5757 replacement_width = len (vstr .nodes )
58+
5859 for el in vstr .variable_replacement_order :
5960 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 ]
6295 """ h is used when the number of nodes is larger than the number of values
6396 then you need to loop x times where x=itr_num and x*len(values) = len(vstr.nodes) """
6497 factor = (len (var_list [name ]) * replacement_width )
6598 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+
66108
67109 for h in range (0 , itr_num ):
68110 for i , value in enumerate (var_list [name ]): # By this point the number of nodes will have factor of num of values
69111 for j in range (0 , replacement_width ): # Indexing scheme is:
70112 nodes_index = (h * factor ) + (i * replacement_width ) + j
71113
72114 if type (value ) is str :
73- pattern = r'\$' + re .escape (name ) + r'\b'
74115 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+
79127 elif type (value ) is bashlex .ast .node :
80128 vstr .nodes [nodes_index ] = vstr .swap_node (root = vstr .nodes [nodes_index ], path = copy .copy (vstr .path [:- 1 ]), child = value )
81129 else :
82130 raise ValueError ("Error! Variable replacement value wasn't a str or node. bashparser.variables.replace_variables" )
83-
131+ var_list [ name ] = orig_values
84132
85133 def apply_fn (node , vstr , var_list , replace_blanks = False ):
86134 """ This function only works on parameter nodes in the tree. If there is no parameter
0 commit comments