示例#1
0
def _assertReadWordFailure(test, word_str):
  print('\n---', word_str)
  w_parser = InitWordParser(word_str)
  w = w_parser.ReadWord(LexMode.OUTER)
  if w:
    ast.PrettyPrint(w)
    test.fail('Expected a parser error, got %r' % w)
  else:
    print(w_parser.Error())
示例#2
0
def InteractiveLoop(opts, ex, c_parser, w_parser, line_reader):
    # Is this correct?  Are there any non-ANSI terminals?  I guess you can pass
    # -i but redirect stdout.
    if opts.ast_output == '-':
        ast_f = fmt.DetectConsoleOutput(sys.stdout)
    elif opts.ast_output == '-':
        f = open(opts.ast_output,
                 'w')  # implicitly closed when the process ends
        ast_f = fmt.DetectConsoleOutput(f)
    else:
        ast_f = None

    while True:
        try:
            w = c_parser.Peek()
        except KeyboardInterrupt:
            print('Ctrl-C')
            break

        if w is None:
            raise RuntimeError('Failed parse: %s' % c_parser.Error())
        c_id = word.CommandId(w)
        if c_id == Id.Op_Newline:
            print('nothing to execute')
        elif c_id == Id.Eof_Real:
            print('EOF')
            break
        else:
            node = c_parser.ParseCommandLine()

            # TODO: Need an error for an empty command, which we ignore?  GetLine
            # could do that in the first position?
            # ParseSimpleCommand fails with '\n' token?
            if not node:
                # TODO: PrintError here
                raise RuntimeError('failed parse: %s' % c_parser.Error())

            if ast_f:
                ast.PrettyPrint(node)

            status = ex.Execute(node)

            if opts.print_status:
                print('STATUS', repr(status))

        # Reset prompt and clear memory.  TODO: If there are any function
        # definitions ANYWHERE in the node, you should not clear the underlying
        # memory.  We still need to execute those strings!
        line_reader.Reset()

        # Reset internal newline state.
        # NOTE: It would actually be correct to reinitialize all objects (except
        # Env) on every iteration.  But we know that the w_parser is the only thing
        # that needs to be reset, for now.
        w_parser.Reset()
        c_parser.Reset()
示例#3
0
def _assertParseCommandListError(test, code_str):
  arena, c_parser = InitCommandParser(code_str)
  node = c_parser.ParseCommandLine()
  if node:
    print('UNEXPECTED:')
    ast.PrettyPrint(node)
    test.fail("Expected %r to fail" % code_str)
    return
  err = c_parser.Error()
  #print(err)
  ui.PrintErrorStack(err, arena, sys.stdout)
示例#4
0
文件: oil.py 项目: xydinesh/oil
def InteractiveLoop(opts, ex, c_parser, w_parser, line_reader):
  if opts.show_ast:
    ast_f = fmt.DetectConsoleOutput(sys.stdout)
  else:
    ast_f = None

  while True:
    try:
      w = c_parser.Peek()
    except KeyboardInterrupt:
      print('Ctrl-C')
      break

    if w is None:
      raise RuntimeError('Failed parse: %s' % c_parser.Error())
    c_id = word.CommandId(w)
    if c_id == Id.Op_Newline:
      print('nothing to execute')
    elif c_id == Id.Eof_Real:
      print('EOF')
      break
    else:
      node = c_parser.ParseCommandLine()

      # TODO: Need an error for an empty command, which we ignore?  GetLine
      # could do that in the first position?
      # ParseSimpleCommand fails with '\n' token?
      if not node:
        # TODO: PrintError here
        raise RuntimeError('failed parse: %s' % c_parser.Error())

      if ast_f:
        ast.PrettyPrint(node)

      status = ex.Execute(node)

      if opts.print_status:
        print('STATUS', repr(status))

    # Reset prompt to PS1.
    line_reader.Reset()

    # Reset internal newline state.
    # NOTE: It would actually be correct to reinitialize all objects (except
    # Env) on every iteration.  But we know that the w_parser is the only thing
    # that needs to be reset, for now.
    w_parser.Reset()
    c_parser.Reset()
示例#5
0
def _assertReadWordWithArena(test, word_str):
    print('\n---', word_str)
    arena, w_parser = _InitWordParserWithArena(word_str)
    w = w_parser.ReadWord(LexMode.OUTER)
    if w:
        ast.PrettyPrint(w)
    else:
        err = w_parser.Error()
        test.fail("Couldn't parse %r: %s" % (word_str, err))

    # Next word must be \n
    w2 = w_parser.ReadWord(LexMode.OUTER)
    test.assertTrue(
        TokenWordsEqual(ast.TokenWord(ast.token(Id.Op_Newline, '\n')), w2))

    return arena, w
示例#6
0
  def testReadArith(self):
    CASES = [
        '1 + 2',
        'a + b',
        '$a * $b',
        '${a} * ${b}',
        '$(echo 1) * $(echo 2)',
        '`echo 1` + 2',
        '$((1 + 2)) * $((3 + 4))',
        "'single quoted'",  # Allowed by oil but not bash
        '"${a}" + "${b}"',  # Ditto
        '$# + $$',
        # This doesn't work but does in bash -- should be 15
        #'$(( $(echo 1)$(echo 2) + 3 ))',

        '$(( x[0] < 5 ))',
        '$(( ++i ))',
        '$(( i++ ))',

        '$(( x -= 1))',
        '$(( x |= 1))',

        '$(( x[0] = 1 ))',

        '$(( 1 | 0 ))',

        '$((0x$size))',
    ]

    for expr in CASES:
      print('---')
      print(expr)
      print()

      w_parser = InitWordParser(expr)
      w_parser._Next(LexMode.ARITH)  # Can we remove this requirement?

      while True:
        w = w_parser.ReadWord(LexMode.ARITH)
        if not w:
          err = w_parser.Error()
          print('ERROR', err)
          self.fail(err)
          break
        ast.PrettyPrint(w)
        if word.CommandId(w) in (Id.Eof_Real, Id.Unknown_Tok):
          break
示例#7
0
def _assertParseMethod(test, code_str, method, expect_success=True):
  arena, c_parser = InitCommandParser(code_str)
  m = getattr(c_parser, method)
  node = m()

  if node:
    ast.PrettyPrint(node)
    if not expect_success:
      test.fail('Expected %r to fail ' % code_str)
  else:
    # TODO: Could copy PrettyPrintError from pysh.py
    err = c_parser.Error()
    print(err)
    ui.PrintErrorStack(err, arena, sys.stdout)
    if expect_success:
      test.fail('%r failed' % code_str)
  return node
示例#8
0
def _assertReadWordWithArena(test, word_str):
  print('\n---', word_str)
  arena, w_parser = _InitWordParserWithArena(word_str)
  w = w_parser.ReadWord(lex_mode_e.OUTER)
  if w:
    ast.PrettyPrint(w)
  else:
    err = w_parser.Error()
    test.fail("Couldn't parse %r: %s" % (word_str, err))

  # Next word must be Eof_Real
  w2 = w_parser.ReadWord(lex_mode_e.OUTER)
  test.assertTrue(
      test_lib.TokenWordsEqual(ast.TokenWord(ast.token(Id.Eof_Real, '')), w2),
      w2)

  return arena, w
示例#9
0
  def testRead(self):
    CASES = [
        'ls "foo"',
        '$(( 1 + 2 ))',

        '$(echo $(( 1 )) )',  # OLD BUG: arith sub within command sub

        'echo ${#array[@]} b',  # Had a bug here
        'echo $(( ${#array[@]} ))',  # Bug here

        # Had a bug: unary minus
        #'${mounted_disk_regex:0:-1}',

        'echo ${@%suffix}',  # had a bug here

        '${@}',

        'echo ${var,,}',
        'echo ${var,,?}',

        # Line continuation tests
        '${\\\nfoo}',  # VS_1
        '${foo\\\n}',  # VS_2
        '${foo#\\\nyo}',  # VS_ARG_UNQ
        '"${foo#\\\nyo}"',  # VS_ARG_DQ
    ]
    for expr in CASES:
      print('---')
      print(expr)
      print()

      w_parser = InitWordParser(expr)

      while True:
        w = w_parser.ReadWord(LexMode.OUTER)
        if w is None:
          e = w_parser.Error()
          print('Error in word parser: %s' % e)
          self.fail(e)

        ast.PrettyPrint(w)

        if word.CommandId(w) == Id.Eof_Real:
          break