def _SplitPartsIntoFragments(part_vals, ifs): """ part_value[] -> part_value[] Depends on no_glob """ # Every part yields a single fragment array. frag_arrays = [] for p in part_vals: if p.tag == part_value_e.StringPartValue: #log("SPLITTING %s with ifs %r", p, ifs) if p.do_split_elide: frags = _IfsSplit(p.s, ifs) res = [runtime.fragment(f, True, p.do_glob) for f in frags] #log("RES %s", res) else: # Example: 'a b' and "a b" don't need to be split. res = [runtime.fragment(p.s, p.do_split_elide, p.do_glob)] elif p.tag == part_value_e.ArrayPartValue: # "$@" and "${a[@]}" don't need to be split or globbed res = [runtime.fragment(f, False, False) for f in p.strs] else: raise AssertionError(p.tag) frag_arrays.append(res) return frag_arrays
def EvalWordToAny(self, word, glob_escape=False): """ Used for RHS of assignment Also used for default value? e.g. "${a:-"a" "b"}" and so forth. Returns: arg_value Or maybe just string? Whatever would go in ConstArg and GlobArg. But you don't need to distinguish it later. You could also have EvalWord and EvalGlobWord methods or EvalPatternWord """ # Special case for a=(1 2). ArrayLiteralPart won't appear in words that # don't look like assignments. if (len(word.parts) == 1 and word.parts[0].tag == word_part_e.ArrayLiteralPart): array_words = word.parts[0].words words = braces.BraceExpandWords(array_words) strs = self._EvalWordSequence(words) #log('ARRAY LITERAL EVALUATED TO -> %s', strs) return runtime.StrArray(strs) part_vals = self._EvalParts(word) #log('part_vals %s', part_vals) # Instead of splitting, do a trivial transformation to frag array. # Example: # foo="-$@-${a[@]}-" requires fragment, reframe, and simple join frag_arrays = [] for p in part_vals: if p.tag == part_value_e.StringPartValue: frag_arrays.append([runtime.fragment(p.s, False, False)]) elif p.tag == part_value_e.ArrayPartValue: frag_arrays.append( [runtime.fragment(s, False, False) for s in p.strs]) else: raise AssertionError frag_arrays = _Reframe(frag_arrays) #log('frag_arrays %s', frag_arrays) # Simple join args = [] for frag_array in frag_arrays: args.append(''.join(frag.s for frag in frag_array)) # Example: # a=(1 2) # b=$a # one word # c="${a[@]}" # two words if len(args) == 1: val = runtime.Str(args[0]) else: # NOTE: For bash compatibility, could have an option to join them here. # foo="-$@-${a[@]}-" -- join with IFS again, like "$*" ? # Or maybe do that in cmd_exec in assignment. val = runtime.StrArray(args) return val