Example #1
0
    def Run(self, cmd_val):
        # type: (cmd_value__Argv) -> int
        attrs, arg_r = flag_spec.ParseCmdVal('mapfile', cmd_val)
        # TODO: Implement flags to mapfile
        #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
            lines.append(line)

        state.SetArrayDynamic(self.mem, var_name, lines)
        return 0
Example #2
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.SetArrayDynamic(self.mem, var_name, lines)
        return 0
    def Run(self, cmd_val):
        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.GetVar('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 = []
        for a in comp_argv:
            completion.AdjustArg(a, break_chars, adjusted_argv)

        if 'words' in var_names:
            state.SetArrayDynamic(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.SetStringDynamic(self.mem, 'split', split)

        if 'cur' in var_names:
            state.SetStringDynamic(self.mem, 'cur', cur)
        if 'prev' in var_names:
            state.SetStringDynamic(self.mem, 'prev', prev)
        if 'cword' in var_names:
            # Same weird invariant after adjustment
            state.SetStringDynamic(self.mem, 'cword', str(n - 1))

        return 0
Example #4
0
    def Run(self, cmd_val):
        # type: (cmd_value__Argv) -> int
        arg, i = READ_SPEC.ParseCmdVal(cmd_val)

        names = cmd_val.argv[i:]
        if arg.n is not None:  # read a certain number of bytes
            stdin = sys.stdin.fileno()
            try:
                name = names[0]
            except IndexError:
                name = 'REPLY'  # default variable name
            s = ""
            if sys.stdin.isatty():  # set stdin to read in unbuffered mode
                orig_attrs = termios.tcgetattr(stdin)
                attrs = termios.tcgetattr(stdin)
                # disable canonical (buffered) mode
                # see `man termios` for an extended discussion
                attrs[3] &= ~termios.ICANON
                try:
                    termios.tcsetattr(stdin, termios.TCSANOW, attrs)
                    # posix.read always returns a single character in unbuffered mode
                    while arg.n > 0:
                        s += posix.read(stdin, 1)
                        arg.n -= 1
                finally:
                    termios.tcsetattr(stdin, termios.TCSANOW, orig_attrs)
            else:
                s_len = 0
                while arg.n > 0:
                    buf = posix.read(stdin, arg.n)
                    # EOF
                    if buf == '':
                        break
                    arg.n -= len(buf)
                    s += buf

            state.SetLocalString(self.mem, name, s)
            # NOTE: Even if we don't get n bytes back, there is no error?
            return 0

        if not names:
            names.append('REPLY')

        # leftover words assigned to the last name
        if arg.a:
            max_results = 0  # no max
        else:
            max_results = len(names)

        # We have to read more than one line if there is a line continuation (and
        # it's not -r).

        parts = []
        join_next = False
        while True:
            line = ReadLineFromStdin()
            #log('LINE %r', line)
            if not line:  # EOF
                status = 1
                break

            if line.endswith('\n'):  # strip trailing newline
                line = line[:-1]
                status = 0
            else:
                # odd bash behavior: fail even if we can set variables.
                status = 1

            spans = self.splitter.SplitForRead(line, not arg.r)
            done, join_next = _AppendParts(line, spans, max_results, join_next,
                                           parts)

            #log('PARTS %s continued %s', parts, continued)
            if done:
                break

        if arg.a:
            state.SetArrayDynamic(self.mem, arg.a, parts)
        else:
            for i in xrange(max_results):
                try:
                    s = parts[i]
                except IndexError:
                    s = ''  # if there are too many variables
                #log('read: %s = %s', names[i], s)
                state.SetStringDynamic(self.mem, names[i], s)

        return status
Example #5
0
    def Run(self, cmd_val):
        # type: (cmd_value__Argv) -> int
        attrs, arg_r = flag_spec.ParseCmdVal('read', cmd_val)
        arg = arg_types.read(attrs.attrs)
        names = arg_r.Rest()

        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

            status = 0
            stdin_fd = self.stdin.fileno()
            if self.stdin.isatty():  # set stdin to read in unbuffered mode
                s = passwd.ReadBytesFromTerminal(stdin_fd, arg.n)
            else:
                chunks = []  # type: List[str]
                n = arg.n
                while n > 0:
                    chunk = posix.read(stdin_fd, n)  # read at up to N chars
                    if len(chunk) == 0:
                        break
                    chunks.append(chunk)
                    n -= len(chunk)
                s = ''.join(chunks)

            # DIdn't read all the bytes we wanted
            if len(s) != n:
                status = 1

            state.SetStringDynamic(self.mem, name, s)
            # NOTE: Even if we don't get n bytes back, there is no error?
            return status

        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.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 = ReadLineFromStdin(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 arg.r)
            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.SetArrayDynamic(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.SetStringDynamic(self.mem, names[i], s)

        return status
Example #6
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.SetStringDynamic(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.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 = ReadLineFromStdin(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 arg.r)
            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.SetArrayDynamic(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.SetStringDynamic(self.mem, names[i], s)

        return status