Ejemplo n.º 1
0
    def EvalPrompt(self, val):
        """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
Ejemplo n.º 2
0
Archivo: dev.py Proyecto: rbs-pli/oil
    def _EvalPS4(self):
        """For set -x."""

        val = self.mem.GetVar('PS4')
        assert val.tag == value_e.Str

        s = val.s
        if s:
            first_char, ps4 = s[0], s[1:]
        else:
            first_char, ps4 = '+', ' '  # default

        # 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 util.ParseError as e:
                ps4_word = word.ErrorWord("<ERROR: Can't parse PS4: %s>", e)
            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.exec_opts.xtrace = False
        try:
            prefix = self.word_ev.EvalForPlugin(ps4_word)
        finally:
            self.exec_opts.xtrace = True
        return first_char, prefix.s