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
def testInvalidEscapes(self): for invalid_prompt in [ r"\[\[", r"\[\]\[\]\]", r"\]\]", r"almost valid \]", r"\[almost valid", r"\]\[", # goes negative! ]: tokens = match.Ps1Tokens(invalid_prompt) self.assertEqual(prompt.PROMPT_ERROR, self.p._ReplaceBackslashCodes(tokens))
def testPS1Lexer(self): print(list(match.Ps1Tokens(r'foo'))) print(list(match.Ps1Tokens(r'\h \w \$')))