def Run(self, cmd_val): # type: (cmd_value__Argv) -> int attrs, arg_r = flag_spec.ParseCmdVal('mapfile', cmd_val) arg = arg_types.mapfile(attrs.attrs) var_name, _ = arg_r.Peek2() if var_name is None: var_name = 'MAPFILE' lines = [] # type: List[str] while True: line = self.f.readline() if len(line) == 0: break if arg.t and line.endswith('\n'): line = line[:-1] lines.append(line) state.SetRefArray(self.mem, var_name, lines) return 0
def _Read(self, arg, names): # type: (arg_types.read, List[str]) -> int if arg.n >= 0: # read a certain number of bytes (-1 means unset) if len(names): name = names[0] else: name = 'REPLY' # default variable name stdin_fd = self.stdin.fileno() s = self._ReadN(stdin_fd, arg.n) state.SetRefString(self.mem, name, s) # Did we read all the bytes we wanted? return 0 if len(s) == arg.n else 1 if len(names) == 0: names.append('REPLY') # leftover words assigned to the last name if arg.a is not None: max_results = 0 # no max else: max_results = len(names) if arg.Z: # -0 is synonym for -r -d '' raw = True delim_char = '\0' else: raw = arg.r if arg.d is not None: if len(arg.d): delim_char = arg.d[0] else: delim_char = '\0' # -d '' delimits by NUL else: delim_char = '\n' # read a line # We have to read more than one line if there is a line continuation (and # it's not -r). parts = [] # type: List[mylib.BufWriter] join_next = False status = 0 while True: line, eof = _ReadUntilDelim(delim_char) if eof: # status 1 to terminate loop. (This is true even though we set # variables). status = 1 #log('LINE %r', line) if len(line) == 0: break spans = self.splitter.SplitForRead(line, not raw) done, join_next = _AppendParts(line, spans, max_results, join_next, parts) #log('PARTS %s continued %s', parts, continued) if done: break entries = [buf.getvalue() for buf in parts] num_parts = len(entries) if arg.a is not None: state.SetRefArray(self.mem, arg.a, entries) else: for i in xrange(max_results): if i < num_parts: s = entries[i] else: s = '' # if there are too many variables #log('read: %s = %s', names[i], s) state.SetRefString(self.mem, names[i], s) return status
def Run(self, cmd_val): # type: (cmd_value__Argv) -> int argv = cmd_val.argv[1:] arg_r = args.Reader(argv) arg = COMPADJUST_SPEC.Parse(arg_r) var_names = arg_r.Rest() # Output variables to set for name in var_names: # Ironically we could complete these if name not in ['cur', 'prev', 'words', 'cword']: raise error.Usage('Invalid output variable name %r' % name) #print(arg) # TODO: How does the user test a completion function programmatically? Set # COMP_ARGV? val = self.mem.GetValue('COMP_ARGV') if val.tag != value_e.MaybeStrArray: raise error.Usage("COMP_ARGV should be an array") comp_argv = val.strs # These are the ones from COMP_WORDBREAKS that we care about. The rest occur # "outside" of words. break_chars = [':', '='] if arg.s: # implied break_chars.remove('=') # NOTE: The syntax is -n := and not -n : -n =. omit_chars = arg.n or '' for c in omit_chars: if c in break_chars: break_chars.remove(c) # argv adjusted according to 'break_chars'. adjusted_argv = [] # type: List[str] for a in comp_argv: completion.AdjustArg(a, break_chars, adjusted_argv) if 'words' in var_names: state.SetRefArray(self.mem, 'words', adjusted_argv) n = len(adjusted_argv) cur = adjusted_argv[-1] prev = '' if n < 2 else adjusted_argv[-2] if arg.s: if cur.startswith( '--') and '=' in cur: # Split into flag name and value prev, cur = cur.split('=', 1) split = 'true' else: split = 'false' # Do NOT set 'split' without -s. Caller might not have declared it. # Also does not respect var_names, because we don't need it. state.SetRefString(self.mem, 'split', split) if 'cur' in var_names: state.SetRefString(self.mem, 'cur', cur) if 'prev' in var_names: state.SetRefString(self.mem, 'prev', prev) if 'cword' in var_names: # Same weird invariant after adjustment state.SetRefString(self.mem, 'cword', str(n - 1)) return 0