OILS / builtin / method_io.py View on Github | oilshell.org

121 lines, 60 significant
1"""Methods on IO type"""
2from __future__ import print_function
3
4from _devbuild.gen.value_asdl import value, value_t
5
6from core import error
7from core import num
8from core import vm
9from mycpp.mylib import log
10from osh import prompt
11
12from typing import Dict, cast, TYPE_CHECKING
13if TYPE_CHECKING:
14 from frontend import typed_args
15 from osh import cmd_eval
16
17_ = log
18
19
20class Eval(vm._Callable):
21 """
22 These are similar:
23
24 var c = ^(echo hi)
25
26 eval (c)
27 call _io->eval(c)
28
29 The CALLER must handle errors.
30 """
31 def __init__(self, cmd_ev):
32 # type: (cmd_eval.CommandEvaluator) -> None
33 self.cmd_ev = cmd_ev
34
35 def Call(self, rd):
36 # type: (typed_args.Reader) -> value_t
37 io = rd.PosIO()
38 cmd = rd.PosCommand()
39 rd.Done() # no more args
40
41 # errors can arise from false' and 'exit'
42 unused_status = self.cmd_ev.EvalCommand(cmd)
43 return value.Null
44
45
46class CaptureStdout(vm._Callable):
47
48 def __init__(self, shell_ex):
49 # type: (vm._Executor) -> None
50 self.shell_ex = shell_ex
51
52 def Call(self, rd):
53 # type: (typed_args.Reader) -> value_t
54
55 io = rd.PosIO()
56 cmd = rd.PosCommand()
57 rd.Done() # no more args
58
59 status, stdout_str = self.shell_ex.CaptureStdout(cmd)
60 if status != 0:
61 # Note that $() raises error.ErrExit with the status.
62 # But I think that results in a more confusing error message, so we
63 # "wrap" the errors.
64 properties = {
65 'status': num.ToBig(status)
66 } # type: Dict[str, value_t]
67 raise error.Structured(
68 4, 'captureStdout(): command failed with status %d' % status,
69 rd.LeftParenToken(), properties)
70
71 return value.Str(stdout_str)
72
73
74class PromptVal(vm._Callable):
75 """
76 _io->promptVal('$') is like \$
77 It expands to $ or # when root
78 """
79
80 def __init__(self):
81 # type: () -> None
82 pass
83
84 def Call(self, rd):
85 # type: (typed_args.Reader) -> value_t
86
87 # "self" param is guaranteed to succeed
88 io = rd.PosIO()
89 what = rd.PosStr()
90 rd.Done() # no more args
91
92 # Bug fix: protect against crash later in PromptVal()
93 if len(what) != 1:
94 raise error.Expr(
95 'promptVal() expected a single char, got %r' % what,
96 rd.LeftParenToken())
97
98 prompt_ev = cast(prompt.Evaluator, io.prompt_ev)
99 return value.Str(prompt_ev.PromptVal(what))
100
101
102class Time(vm._Callable):
103
104 def __init__(self):
105 # type: () -> None
106 pass
107
108 def Call(self, rd):
109 # type: (typed_args.Reader) -> value_t
110 return value.Null
111
112
113class Strftime(vm._Callable):
114
115 def __init__(self):
116 # type: () -> None
117 pass
118
119 def Call(self, rd):
120 # type: (typed_args.Reader) -> value_t
121 return value.Null