def combine_concat_plans(plans, concat_axis):
if len(plans) == <NUM_LIT:1>:<EOL><INDENT>for p in plans[<NUM_LIT:0>]:<EOL><INDENT>yield p[<NUM_LIT:0>], [p[<NUM_LIT:1>]]<EOL><DEDENT><DEDENT>elif concat_axis == <NUM_LIT:0>:<EOL><INDENT>offset = <NUM_LIT:0><EOL>for plan in plans:<EOL><INDENT>last_plc = None<EOL>for plc, unit in plan:<EOL><INDENT>yield plc.add(offset), [unit]<EOL>last_plc = plc<EOL><DEDENT>if last_plc is not None:<EOL><INDENT>offset += last_plc.as_slice.stop<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>num_ended = [<NUM_LIT:0>]<EOL>def _next_or_none(seq):<EOL><INDENT>retval = next(seq, None)<EOL>if retval is None:<EOL><INDENT>num_ended[<NUM_LIT:0>] += <NUM_LIT:1><EOL><DEDENT>return retval<EOL><DEDENT>plans = list(map(iter, plans))<EOL>next_items = list(map(_next_or_none, plans))<EOL>while num_ended[<NUM_LIT:0>] != len(next_items):<EOL><INDENT>if num_ended[<NUM_LIT:0>] > <NUM_LIT:0>:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>placements, units = zip(*next_items)<EOL>lengths = list(map(len, placements))<EOL>min_len, max_len = min(lengths), max(lengths)<EOL>if min_len == max_len:<EOL><INDENT>yield placements[<NUM_LIT:0>], units<EOL>next_items[:] = map(_next_or_none, plans)<EOL><DEDENT>else:<EOL><INDENT>yielded_placement = None<EOL>yielded_units = [None] * len(next_items)<EOL>for i, (plc, unit) in enumerate(next_items):<EOL><INDENT>yielded_units[i] = unit<EOL>if len(plc) > min_len:<EOL><INDENT>next_items[i] = (plc[min_len:],<EOL>trim_join_unit(unit, min_len))<EOL><DEDENT>else:<EOL><INDENT>yielded_placement = plc<EOL>next_items[i] = _next_or_none(plans[i])<EOL><DEDENT><DEDENT>yield yielded_placement, yielded_units<EOL><DEDENT><DEDENT><DEDENT>
Combine multiple concatenation plans into one.

existing_plan is updated in-place.