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

121 lines, 59 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, 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
32 def __init__(self, cmd_ev):
33 # type: (cmd_eval.CommandEvaluator) -> None
34 self.cmd_ev = cmd_ev
35
36 def Call(self, rd):
37 # type: (typed_args.Reader) -> value_t
38 unused = rd.PosValue()
39 cmd = rd.PosCommand()
40 rd.Done() # no more args
41
42 # errors can arise from false' and 'exit'
43 unused_status = self.cmd_ev.EvalCommand(cmd)
44 return value.Null
45
46
47class CaptureStdout(vm._Callable):
48
49 def __init__(self, shell_ex):
50 # type: (vm._Executor) -> None
51 self.shell_ex = shell_ex
52
53 def Call(self, rd):
54 # type: (typed_args.Reader) -> value_t
55
56 unused = rd.PosValue()
57 cmd = rd.PosCommand()
58 rd.Done() # no more args
59
60 status, stdout_str = self.shell_ex.CaptureStdout(cmd)
61 if status != 0:
62 # Note that $() raises error.ErrExit with the status.
63 # But I think that results in a more confusing error message, so we
64 # "wrap" the errors.
65 properties = {
66 'status': num.ToBig(status)
67 } # type: Dict[str, value_t]
68 raise error.Structured(
69 4, 'captureStdout(): command failed with status %d' % status,
70 rd.LeftParenToken(), properties)
71
72 return value.Str(stdout_str)
73
74
75class PromptVal(vm._Callable):
76 """
77 _io->promptVal('$') is like \$
78 It expands to $ or # when root
79 """
80
81 def __init__(self, prompt_ev):
82 # type: (prompt.Evaluator) -> None
83 self.prompt_ev = prompt_ev
84
85 def Call(self, rd):
86 # type: (typed_args.Reader) -> value_t
87
88 # "self" param is guaranteed to succeed
89 unused = rd.PosValue()
90 what = rd.PosStr()
91 rd.Done() # no more args
92
93 # Bug fix: protect against crash later in PromptVal()
94 if len(what) != 1:
95 raise error.Expr(
96 'promptVal() expected a single char, got %r' % what,
97 rd.LeftParenToken())
98
99 return value.Str(self.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