Example #1
0
def _TestGetCompletionType(buf):
  ev = test_lib.MakeTestEvaluator()
  arena = test_lib.MakeArena('<completion_test.py>')
  parse_ctx = parse_lib.ParseContext(arena, {})
  w_parser, c_parser = parse_ctx.MakeParserForCompletion(buf, arena)
  print('---', buf)
  return completion._GetCompletionType(w_parser, c_parser, ev, debug_f)
Example #2
0
def _MakeParser(code_str):
    # NOTE: We need the extra ]] token
    arena = test_lib.MakeArena('<bool_parse_test.py>')
    parse_ctx = parse_lib.ParseContext(arena, {})
    w_parser, _ = parse_ctx.MakeParserForCompletion(code_str + ' ]]', arena)
    w_parser._Next(lex_mode_e.DBRACKET)  # for tests only
    p = bool_parse.BoolParser(w_parser)
    p._Next()
    return p
Example #3
0
def InitExecutor(arena=None):
  arena = arena or MakeArena('<InitExecutor>')

  mem = state.Mem('', [], {}, arena)
  fd_state = process.FdState()
  funcs = {}
  comp_funcs = {}
  # For the tests, we do not use 'readline'.
  exec_opts = state.ExecOpts(mem, None)
  parse_ctx = parse_lib.ParseContext(arena, {})

  debug_f = util.DebugFile(sys.stderr)
  devtools = dev.DevTools(dev.CrashDumper(''), debug_f, debug_f)

  return cmd_exec.Executor(mem, fd_state, funcs, comp_funcs, exec_opts,
                           parse_ctx, devtools)
Example #4
0
def ParseAndEval(code_str):
    arena = test_lib.MakeArena('<arith_parse_test.py>')
    parse_ctx = parse_lib.ParseContext(arena, {})
    w_parser, _ = parse_ctx.MakeParserForCompletion(code_str, arena)
    w_parser._Next(lex_mode_e.ARITH)  # Calling private method
    anode = w_parser._ReadArithExpr()  # need the right lex state?
    print('node:', anode)

    mem = state.Mem('', [], {}, arena)
    exec_opts = state.ExecOpts(mem, None)
    splitter = legacy.SplitContext(mem)
    ev = word_eval.CompletionWordEvaluator(mem, exec_opts, splitter, arena)

    arith_ev = expr_eval.ArithEvaluator(mem, exec_opts, ev, arena)
    value = arith_ev.Eval(anode)
    return value
Example #5
0
def _Detect(test, word_str, expected):
    # TODO: This function could be moved to test_lib.
    log('-' * 80)
    arena, w = word_parse_test._assertReadWordWithArena(test, word_str)

    actual = word.DetectAssignment(w)
    left_token, close_token, part_offset = actual

    expected_left, expected_close, expected_part_offset = expected

    print(left_token, close_token, part_offset)
    print()

    if expected_left is None:
        test.assertEqual(None, left_token)
    else:
        test.assertEqual(expected_left, left_token.id)

    if expected_close is None:
        test.assertEqual(None, close_token)
    else:
        test.assertEqual(expected_left, left_token.id)

    test.assertEqual(expected_part_offset, part_offset)

    parse_ctx = parse_lib.ParseContext(arena, {})

    if left_token and left_token.id in (Id.Lit_VarLike, Id.Lit_ArrayLhsOpen):
        more_env = []
        preparsed = (left_token, close_token, part_offset, w)
        try:
            cmd_parse._AppendMoreEnv([preparsed], more_env)
        except Exception as e:
            log('Error: %s', e)
        else:
            log('more_env: %s', more_env)

        try:
            assign_pair = cmd_parse._MakeAssignPair(parse_ctx, preparsed)
        except Exception as e:
            log('Error: %s', e)
        else:
            log('assign_pair: %s', assign_pair)
Example #6
0
  def testRootCompleter(self):
    comp_lookup = completion.CompletionLookup()

    comp_lookup.RegisterName('grep', C1)
    comp_lookup.RegisterName('__first', FIRST)

    ev = test_lib.MakeTestEvaluator()

    pool = alloc.Pool()
    arena = pool.NewArena()
    parse_ctx = parse_lib.ParseContext(arena, {})
    var_comp = V1
    r = completion.RootCompleter(ev, comp_lookup, var_comp, parse_ctx,
                                 progress_f, debug_f)

    comp = completion.CompletionApi(line='grep f')
    m = list(r.Matches(comp))
    self.assertEqual(['foo.py', 'foo'], m)

    comp = completion.CompletionApi(line='grep g')
    m = list(r.Matches(comp))
    self.assertEqual([], m)

    m = list(r.Matches(completion.CompletionApi(line='ls $v')))
    self.assertEqual(['$var1', '$var2'], m)

    m = list(r.Matches(completion.CompletionApi(line='g')))
    self.assertEqual(['grep'], m)

    # Empty completer
    m = list(r.Matches(completion.CompletionApi('')))
    self.assertEqual(['grep', 'sed', 'test'], m)

    # Test compound commands. These PARSE
    m = list(r.Matches(completion.CompletionApi('echo hi || grep f')))
    m = list(r.Matches(completion.CompletionApi('echo hi; grep f')))

    # Brace -- does NOT parse
    m = list(r.Matches(completion.CompletionApi('{ echo hi; grep f')))
    # TODO: Test if/for/while/case/etc.

    m = list(r.Matches(completion.CompletionApi('var=$v')))
    m = list(r.Matches(completion.CompletionApi('local var=$v')))
Example #7
0
def InitCommandParser(code_str):
    arena = test_lib.MakeArena('<cmd_parse_test.py>')
    parse_ctx = parse_lib.ParseContext(arena, {})
    line_reader, lexer = parse_lib.InitLexer(code_str, arena)
    _, c_parser = parse_ctx.MakeParser(line_reader)
    return arena, c_parser  # arena is returned for printing errors
Example #8
0
def InitCommandParser(code_str, arena=None):
  arena = arena or test_lib.MakeArena('<cmd_exec_test.py>')
  parse_ctx = parse_lib.ParseContext(arena, {})
  line_reader, lexer = parse_lib.InitLexer(code_str, arena)
  _, c_parser = parse_ctx.MakeParser(line_reader)
  return c_parser
Example #9
0
def _InitWordParserWithArena(s):
    arena = alloc.SideArena('word_parse_test.py')
    parse_ctx = parse_lib.ParseContext(arena, {})
    line_reader, lexer = parse_lib.InitLexer(s, arena)
    w_parser, _ = parse_ctx.MakeParser(line_reader)
    return arena, w_parser
Example #10
0
File: oil.py Project: gnprice/oil
def OshCommandMain(argv):
    """Run an 'oshc' tool.

  'osh' is short for "osh compiler" or "osh command".

  TODO:
  - oshc --help

  oshc deps
    --path: the $PATH to use to find executables.  What about libraries?

    NOTE: we're leaving out su -c, find, xargs, etc.?  Those should generally
    run functions using the $0 pattern.
    --chained-command sudo
  """
    try:
        action = argv[0]
    except IndexError:
        raise args.UsageError('oshc: Missing required subcommand.')

    if action not in SUBCOMMANDS:
        raise args.UsageError('oshc: Invalid subcommand %r.' % action)

    try:
        script_name = argv[1]
    except IndexError:
        script_name = '<stdin>'
        f = sys.stdin
    else:
        try:
            f = open(script_name)
        except IOError as e:
            util.error("Couldn't open %r: %s", script_name,
                       posix.strerror(e.errno))
            return 2

    pool = alloc.Pool()
    arena = pool.NewArena()
    arena.PushSource(script_name)

    line_reader = reader.FileLineReader(f, arena)
    aliases = {}  # Dummy value; not respecting aliases!
    parse_ctx = parse_lib.ParseContext(arena, aliases)
    _, c_parser = parse_ctx.MakeParser(line_reader)

    try:
        node = main_loop.ParseWholeFile(c_parser)
    except util.ParseError as e:
        ui.PrettyPrintError(e, arena, sys.stderr)
        return 2
    assert node is not None

    f.close()

    # Columns for list-*
    # path line name
    # where name is the binary path, variable name, or library path.

    # bin-deps and lib-deps can be used to make an app bundle.
    # Maybe I should list them together?  'deps' can show 4 columns?
    #
    # path, line, type, name
    #
    # --pretty can show the LST location.

    # stderr: show how we're following imports?

    if action == 'translate':
        osh2oil.PrintAsOil(arena, node)

    elif action == 'arena':  # for debugging
        osh2oil.PrintArena(arena)

    elif action == 'spans':  # for debugging
        osh2oil.PrintSpans(arena)

    elif action == 'format':
        # TODO: autoformat code
        raise NotImplementedError(action)

    elif action == 'deps':
        deps.Deps(node)

    elif action == 'undefined-vars':  # could be environment variables
        raise NotImplementedError

    else:
        raise AssertionError  # Checked above

    return 0
Example #11
0
File: oil.py Project: gnprice/oil
def OshMain(argv0, argv, login_shell):

    arg_r = args.Reader(argv)
    try:
        opts = OSH_SPEC.Parse(arg_r)
    except args.UsageError as e:
        ui.usage('osh usage error: %s', e)
        return 2

    if opts.help:
        loader = util.GetResourceLoader()
        builtin.Help(['osh-usage'], loader)
        return 0
    if opts.version:
        # OSH version is the only binary in Oil right now, so it's all one version.
        _ShowVersion()
        return 0

    # TODO: This should be in interactive mode only?
    builtin.RegisterSigIntHandler()

    if arg_r.AtEnd():
        dollar0 = argv0
        has_main = False
    else:
        dollar0 = arg_r.Peek()  # the script name, or the arg after -c
        has_main = True

    pool = alloc.Pool()
    arena = pool.NewArena()

    # NOTE: has_main is only for ${BASH_SOURCE[@} and family.  Could be a
    # required arg.
    mem = state.Mem(dollar0,
                    argv[arg_r.i + 1:],
                    posix.environ,
                    arena,
                    has_main=has_main)
    funcs = {}

    comp_lookup = completion.CompletionLookup()

    fd_state = process.FdState()
    exec_opts = state.ExecOpts(mem, readline)
    builtin.SetExecOpts(exec_opts, opts.opt_changes)
    aliases = {}  # feedback between runtime and parser

    parse_ctx = parse_lib.ParseContext(arena, aliases)

    if opts.debug_file:
        debug_f = util.DebugFile(fd_state.Open(opts.debug_file, mode='w'))
    else:
        debug_f = util.NullDebugFile()
    debug_f.log('Debug file is %s', opts.debug_file)

    # Controlled by env variable, flag, or hook?
    dumper = dev.CrashDumper(posix.environ.get('OSH_CRASH_DUMP_DIR', ''))
    if opts.xtrace_to_debug_file:
        trace_f = debug_f
    else:
        trace_f = util.DebugFile(sys.stderr)
    devtools = dev.DevTools(dumper, debug_f, trace_f)

    ex = cmd_exec.Executor(mem, fd_state, funcs, comp_lookup, exec_opts,
                           parse_ctx, devtools)

    # NOTE: The rc file can contain both commands and functions... ideally we
    # would only want to save nodes/lines for the functions.
    try:
        rc_path = 'oilrc'
        arena.PushSource(rc_path)
        with open(rc_path) as f:
            rc_line_reader = reader.FileLineReader(f, arena)
            _, rc_c_parser = parse_ctx.MakeParser(rc_line_reader)
            try:
                status = main_loop.Batch(ex, rc_c_parser, arena)
            finally:
                arena.PopSource()
    except IOError as e:
        if e.errno != errno.ENOENT:
            raise

    # Needed in non-interactive shells for @P
    prompt = ui.Prompt(arena, parse_ctx, ex)
    ui.PROMPT = prompt

    if opts.c is not None:
        arena.PushSource('<command string>')
        line_reader = reader.StringLineReader(opts.c, arena)
        if opts.i:  # -c and -i can be combined
            exec_opts.interactive = True
    elif opts.i:  # force interactive
        arena.PushSource('<stdin -i>')
        line_reader = reader.InteractiveLineReader(arena, prompt)
        exec_opts.interactive = True
    else:
        try:
            script_name = arg_r.Peek()
        except IndexError:
            if sys.stdin.isatty():
                arena.PushSource('<interactive>')
                line_reader = reader.InteractiveLineReader(arena, prompt)
                exec_opts.interactive = True
            else:
                arena.PushSource('<stdin>')
                line_reader = reader.FileLineReader(sys.stdin, arena)
        else:
            arena.PushSource(script_name)
            try:
                f = fd_state.Open(script_name)
            except OSError as e:
                util.error("Couldn't open %r: %s", script_name,
                           posix.strerror(e.errno))
                return 1
            line_reader = reader.FileLineReader(f, arena)

    # TODO: assert arena.NumSourcePaths() == 1
    # TODO: .rc file needs its own arena.
    w_parser, c_parser = parse_ctx.MakeParser(line_reader)

    if exec_opts.interactive:
        # NOTE: We're using a different evaluator here.  The completion system can
        # also run functions... it gets the Executor through Executor._Complete.
        if HAVE_READLINE:
            splitter = legacy.SplitContext(mem)  # TODO: share with executor.
            ev = word_eval.CompletionWordEvaluator(mem, exec_opts, splitter,
                                                   arena)
            progress_f = ui.StatusLine()
            var_action = completion.VariablesActionInternal(ex.mem)
            root_comp = completion.RootCompleter(ev, comp_lookup, var_action,
                                                 parse_ctx, progress_f,
                                                 debug_f)
            completion.Init(readline, root_comp, debug_f)
            _InitDefaultCompletions(ex, comp_lookup)

        return main_loop.Interactive(opts, ex, c_parser, arena)

    # TODO: Remove this after removing it from benchmarks/osh-runtime.  It's no
    # longer relevant with main_loop.
    if opts.parser_mem_dump:
        # This might be superstition, but we want to let the value stabilize
        # after parsing.  bash -c 'cat /proc/$$/status' gives different results
        # with a sleep.
        time.sleep(0.001)
        input_path = '/proc/%d/status' % posix.getpid()
        with open(input_path) as f, open(opts.parser_mem_dump, 'w') as f2:
            contents = f.read()
            f2.write(contents)
            log('Wrote %s to %s (--parser-mem-dump)', input_path,
                opts.parser_mem_dump)

    nodes_out = [] if exec_opts.noexec else None

    _tlog('Execute(node)')
    status = main_loop.Batch(ex, c_parser, arena, nodes_out=nodes_out)

    if nodes_out is not None:
        ui.PrintAst(nodes_out, opts)

    # NOTE: 'exit 1' is ControlFlow and gets here, but subshell/commandsub
    # don't because they call sys.exit().
    if opts.runtime_mem_dump:
        # This might be superstition, but we want to let the value stabilize
        # after parsing.  bash -c 'cat /proc/$$/status' gives different results
        # with a sleep.
        time.sleep(0.001)
        input_path = '/proc/%d/status' % posix.getpid()
        with open(input_path) as f, open(opts.runtime_mem_dump, 'w') as f2:
            contents = f.read()
            f2.write(contents)
            log('Wrote %s to %s (--runtime-mem-dump)', input_path,
                opts.runtime_mem_dump)

    # NOTE: We haven't closed the file opened with fd_state.Open
    return status