Beispiel #1
0
    def EvalPrompt(self, UP_val):
        # type: (value_t) -> str
        """Perform the two evaluations that bash does.  Used by $PS1 and ${x@P}."""
        if UP_val.tag_() != value_e.Str:
            return self.default_prompt  # no evaluation necessary

        val = cast(value__Str, UP_val)

        # Parse backslash escapes (cached)
        tokens = self.tokens_cache.get(val.s)
        if tokens is None:
            tokens = match.Ps1Tokens(val.s)
            self.tokens_cache[val.s] = tokens

        # Replace values.
        ps1_str = self._ReplaceBackslashCodes(tokens)

        # Parse it like a double-quoted word (cached).  TODO: This could be done on
        # mem.SetValue(), so we get the error earlier.
        # NOTE: This is copied from the PS4 logic in Tracer.
        ps1_word = self.parse_cache.get(ps1_str)
        if ps1_word is None:
            w_parser = self.parse_ctx.MakeWordParserForPlugin(ps1_str)
            try:
                ps1_word = w_parser.ReadForPlugin()
            except error.Parse as e:
                ps1_word = word_.ErrorWord("<ERROR: Can't parse PS1: %s>" %
                                           e.UserErrorString())
            self.parse_cache[ps1_str] = ps1_word

        # Evaluate, e.g. "${debian_chroot}\u" -> '\u'
        val2 = self.word_ev.EvalForPlugin(ps1_word)
        return val2.s
Beispiel #2
0
    def EvalPrompt(self, val):
        # type: (value_t) -> str
        """Perform the two evaluations that bash does.  Used by $PS1 and ${x@P}."""
        if val.tag != value_e.Str:
            return self.default_prompt  # no evaluation necessary

        # Parse backslash escapes (cached)
        try:
            tokens = self.tokens_cache[val.s]
        except KeyError:
            tokens = list(match.PS1_LEXER.Tokens(val.s))
            self.tokens_cache[val.s] = tokens

        # Replace values.
        ps1_str = self._ReplaceBackslashCodes(tokens)

        # Parse it like a double-quoted word (cached).  TODO: This could be done on
        # mem.SetVar(), so we get the error earlier.
        # NOTE: This is copied from the PS4 logic in Tracer.
        try:
            ps1_word = self.parse_cache[ps1_str]
        except KeyError:
            w_parser = self.parse_ctx.MakeWordParserForPlugin(ps1_str)
            try:
                ps1_word = w_parser.ReadForPlugin()
            except util.ParseError as e:
                ps1_word = word_.ErrorWord("<ERROR: Can't parse PS1: %s>", e)
            self.parse_cache[ps1_str] = ps1_word

        # Evaluate, e.g. "${debian_chroot}\u" -> '\u'
        val2 = self.ex.word_ev.EvalForPlugin(ps1_word)
        return val2.s
Beispiel #3
0
    def _EvalPS4(self):
        # type: () -> Tuple[str, str]
        """For set -x."""

        first_char = '+'
        ps4 = ' '  # default
        val = self.mem.GetVar('PS4')
        if val.tag_() == value_e.Str:
            s = cast(value__Str, val).s
            if s:
                first_char = s[0]
                ps4 = s[1:]

        # NOTE: This cache is slightly broken because aliases are mutable!  I think
        # that is more or less harmless though.
        try:
            ps4_word = self.parse_cache[ps4]
        except KeyError:
            # We have to parse this at runtime.  PS4 should usually remain constant.
            w_parser = self.parse_ctx.MakeWordParserForPlugin(ps4)

            try:
                ps4_word = w_parser.ReadForPlugin()
            except error.Parse as e:
                ps4_word = word_.ErrorWord("<ERROR: Can't parse PS4: %s>" %
                                           e.UserErrorString())
            self.parse_cache[ps4] = ps4_word

        #print(ps4_word)

        # TODO: Repeat first character according process stack depth.  Where is
        # that stored?  In the executor itself?  It should be stored along with
        # the PID.  Need some kind of ShellProcessState or something.
        #
        # We should come up with a better mechanism.  Something like $PROC_INDENT
        # and $OIL_XTRACE_PREFIX.

        # Prevent infinite loop when PS4 has command sub!
        assert self.exec_opts.xtrace(
        )  # We shouldn't call this unless it's on!
        self.mutable_opts.set_xtrace(False)
        try:
            prefix = self.word_ev.EvalForPlugin(ps4_word)
        finally:
            self.mutable_opts.set_xtrace(True)
        return first_char, prefix.s
Beispiel #4
0
Datei: dev.py Projekt: ilyash/oil
    def _EvalPS4(self, punct):
        # type: (str) -> str
        """The prefix of each line."""
        val = self.mem.GetValue('PS4')
        if val.tag_() == value_e.Str:
            ps4 = cast(value__Str, val).s
        else:
            ps4 = ''

        # NOTE: This cache is slightly broken because aliases are mutable!  I think
        # that is more or less harmless though.
        ps4_word = self.parse_cache.get(ps4)
        if ps4_word is None:
            # We have to parse this at runtime.  PS4 should usually remain constant.
            w_parser = self.parse_ctx.MakeWordParserForPlugin(ps4)

            try:
                ps4_word = w_parser.ReadForPlugin()
            except error.Parse as e:
                ps4_word = word_.ErrorWord("<ERROR: Can't parse PS4: %s>" %
                                           e.UserErrorString())
            self.parse_cache[ps4] = ps4_word

        # Mutate objects to save allocations
        if self.exec_opts.xtrace_rich():
            self.val_indent.s = self.indents[self.ind]
        else:
            self.val_indent.s = ''
        self.val_punct.s = punct

        # Prevent infinite loop when PS4 has command sub!
        assert self.exec_opts.xtrace()  # We shouldn't call this unless it's on

        # TODO: Remove allocation for [] ?
        with state.ctx_Option(self.mutable_opts, [option_i.xtrace], False):
            with state.ctx_Temp(self.mem):
                self.mem.SetValue(self.lval_indent, self.val_indent,
                                  scope_e.LocalOnly)
                self.mem.SetValue(self.lval_punct, self.val_punct,
                                  scope_e.LocalOnly)
                self.mem.SetValue(self.lval_pid_str, self.val_pid_str,
                                  scope_e.LocalOnly)
                prefix = self.word_ev.EvalForPlugin(ps4_word)
        return prefix.s