diff --git a/ysh/regex_translate.py b/ysh/regex_translate.py index 9c55a85a70..4a97a5f647 100644 --- a/ysh/regex_translate.py +++ b/ysh/regex_translate.py @@ -14,10 +14,12 @@ re_repeat, re_repeat_e, NameType, + EggexFlag, ) from _devbuild.gen.id_kind_asdl import Id from _devbuild.gen.value_asdl import value from core.error import e_die +from frontend import lexer from mycpp.mylib import log, tagswitch from osh import glob_ # for ExtendedRegexEscape @@ -346,3 +348,25 @@ def AsPosixEre(eggex): eggex.name_types = name_types return eggex.as_ere + + +def _EncodeFlags(flags): + # type: (List[EggexFlag]) -> str + """ + Raises fatal exception on invalid flags. + """ + letters = [] # type: List[str] + for flag in flags: + if flag.negated: + e_die("Flag can't be negated", flag.flag) + flag_name = lexer.TokenVal(flag.flag) + if flag_name in ('i', 'reg_icase'): + letters.append('i') + elif flag_name == 'reg_newline': + letters.append('n') + else: + e_die("Invalid regex flag %r" % flag_name, flag.flag) + + # Normalize for comparison + return ''.join(sorted(letters)) + diff --git a/ysh/regex_translate_test.py b/ysh/regex_translate_test.py new file mode 100755 index 0000000000..c48d501149 --- /dev/null +++ b/ysh/regex_translate_test.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python2 +from __future__ import print_function + +import unittest + +from _devbuild.gen.id_kind_asdl import Id +from _devbuild.gen.syntax_asdl import EggexFlag, Token, source, SourceLine + +from asdl import runtime +from ysh import regex_translate + + +def _Name(s): + # Doesn't work + #return lexer.DummyToken(Id.Expr_Name, s) + src = source.Stdin('') + source_line = SourceLine(1, s, src) + return Token(Id.Expr_Name, 0, len(s), runtime.NO_SPID, source_line, None) + + +class RegexTranslateTest(unittest.TestCase): + + def testEncodeFlags(self): + reg_icase = _Name('reg_icase') + i = _Name('i') # abbreviation + reg_newline = _Name('reg_newline') + bad = _Name('bad') + + flags = [EggexFlag(False, reg_icase)] + self.assertEqual('i', regex_translate._EncodeFlags(flags)) + + flags = [EggexFlag(False, i)] + self.assertEqual('i', regex_translate._EncodeFlags(flags)) + + flags = [EggexFlag(False, bad)] + try: + regex_translate._EncodeFlags(flags) + except Exception as e: + print(e.UserErrorString()) + else: + self.fail('Should have failed') + + order1 = [EggexFlag(False, reg_icase), EggexFlag(False, reg_newline)] + order2 = [EggexFlag(False, reg_newline), EggexFlag(False, reg_icase)] + + self.assertEqual('in', regex_translate._EncodeFlags(order1)) + self.assertEqual('in', regex_translate._EncodeFlags(order2)) + + +if __name__ == '__main__': + unittest.main()