예제 #1
0
    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
예제 #2
0
파일: builtin_misc.py 프로젝트: ilyash/oil
    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
예제 #3
0
    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