Skip to content

Commit a54e666

Browse files
author
Andy C
committed
[main] Support mutiple --eval flags
1 parent e587f90 commit a54e666

14 files changed

+244
-97
lines changed

core/shell.py

+3-8
Original file line numberDiff line numberDiff line change
@@ -959,11 +959,10 @@ def Main(
959959
# (It could be used for the headless shell. Although terminals have a bootstrap process.)
960960
# Note that --eval
961961

962-
# TODO: process these in a loop, in order
963-
if flag.eval is not None:
962+
for path, is_pure in attrs.eval_flags:
963+
# TODO: respect is_pure
964964
try:
965-
ok = main_loop.EvalFile(flag.eval, fd_state, parse_ctx, cmd_ev,
966-
lang)
965+
ok = main_loop.EvalFile(path, fd_state, parse_ctx, cmd_ev, lang)
967966
except util.UserExit as e:
968967
# Doesn't seem like we need this, and verbose_errexit isn't the right option
969968
#if exec_opts.verbose_errexit():
@@ -972,10 +971,6 @@ def Main(
972971
if not ok: # parse error or I/O error was already printed
973972
return 1
974973

975-
if flag.eval_pure is not None:
976-
# TODO: Same as above, except we restrict
977-
raise AssertionError('pure')
978-
979974
#
980975
# Is the shell interactive?
981976
#

cpp/frontend_flag_spec.cc

+4-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,10 @@ void _CreateActions(Action_c* in, Dict<BigStr*, args::_Action*>* out) {
123123
}
124124
action = a;
125125
} break;
126-
}
126+
case ActionType_c::AppendEvalFlag:
127+
action = Alloc<args::AppendEvalFlag>(StrFromC(p->name));
128+
break;
129+
} // switch
127130

128131
if (action) {
129132
out->set(StrFromC(p->key), action);

cpp/frontend_flag_spec.h

+2
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ enum class ActionType_c {
4747
SetNamedOption_shopt, // no args, valid
4848
SetAction, // name
4949
SetNamedAction, // no args, valid
50+
51+
AppendEvalFlag, // no args, valid
5052
};
5153

5254
// TODO: Figure out the difference between name and key

frontend/args.py

+40-25
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,15 @@
5454
from __future__ import print_function
5555

5656
from _devbuild.gen.syntax_asdl import loc, loc_t, CompoundWord
57-
from _devbuild.gen.value_asdl import (value, value_e, value_t)
57+
from _devbuild.gen.value_asdl import (value, value_t)
5858

5959
from core.error import e_usage
60-
#from frontend import match
6160
from mycpp import mops
62-
from mycpp.mylib import log, tagswitch, iteritems
61+
from mycpp.mylib import log, iteritems
6362

6463
_ = log
6564

66-
from typing import (cast, Tuple, Optional, Dict, List, Any, TYPE_CHECKING)
65+
from typing import (Tuple, Optional, Dict, List, TYPE_CHECKING)
6766
if TYPE_CHECKING:
6867
from frontend import flag_spec
6968
OptChange = Tuple[str, bool]
@@ -87,9 +86,18 @@ def __init__(self, defaults):
8786
# New style
8887
self.attrs = {} # type: Dict[str, value_t]
8988

90-
self.opt_changes = [] # type: List[OptChange] # -o errexit +o nounset
91-
self.shopt_changes = [
92-
] # type: List[OptChange] # -O nullglob +O nullglob
89+
# -o errexit +o nounset
90+
self.opt_changes = [] # type: List[OptChange]
91+
92+
# -O nullglob +O nullglob
93+
self.shopt_changes = [] # type: List[OptChange]
94+
95+
# Special case for --eval and --eval-pure? For bin/osh. It seems OK
96+
# to have one now. The pool tells us if it was pure or not.
97+
# Note: MAIN_SPEC is different than SET_SPEC, so set --eval does
98+
# nothing.
99+
self.eval_flags = [] # type: List[Tuple[str, bool]]
100+
93101
self.show_options = False # 'set -o' without an argument
94102
self.actions = [] # type: List[str] # for compgen -A
95103
self.saw_double_dash = False # for set --
@@ -112,24 +120,6 @@ def Set(self, name, val):
112120

113121
self.attrs[name] = val
114122

115-
if 0:
116-
# Backward compatibility!
117-
with tagswitch(val) as case:
118-
if case(value_e.Undef):
119-
py_val = None # type: Any
120-
elif case(value_e.Bool):
121-
py_val = cast(value.Bool, val).b
122-
elif case(value_e.Int):
123-
py_val = cast(value.Int, val).i
124-
elif case(value_e.Float):
125-
py_val = cast(value.Float, val).f
126-
elif case(value_e.Str):
127-
py_val = cast(value.Str, val).s
128-
else:
129-
raise AssertionError(val)
130-
131-
setattr(self, name, py_val)
132-
133123
def __repr__(self):
134124
# type: () -> str
135125
return '<_Attributes %s>' % self.__dict__
@@ -266,6 +256,31 @@ def OnMatch(self, attached_arg, arg_r, out):
266256
raise NotImplementedError()
267257

268258

259+
class AppendEvalFlag(_Action):
260+
261+
def __init__(self, name):
262+
# type: (str) -> None
263+
_Action.__init__(self)
264+
self.name = name
265+
self.is_pure = (name == 'eval-pure')
266+
267+
def OnMatch(self, attached_arg, arg_r, out):
268+
# type: (Optional[str], Reader, _Attributes) -> bool
269+
"""Called when the flag matches."""
270+
271+
assert attached_arg is None, attached_arg
272+
273+
arg_r.Next()
274+
arg = arg_r.Peek()
275+
if arg is None:
276+
e_usage('expected argument to %r' % ('--' + self.name),
277+
arg_r.Location())
278+
279+
# is_pure is True for --eval-pure
280+
out.eval_flags.append((arg, self.is_pure))
281+
return False
282+
283+
269284
class _ArgAction(_Action):
270285

271286
def __init__(self, name, quit_parsing_flags, valid=None):

frontend/flag_def.py

+3-7
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,9 @@ def _AddShellOptions(spec):
243243

244244
MAIN_SPEC = FlagSpecAndMore('main')
245245

246+
# Special case: Define --eval and --eval-pure
247+
MAIN_SPEC.EvalFlags()
248+
246249
MAIN_SPEC.ShortFlag('-c', args.String,
247250
quit_parsing_flags=True) # command string
248251
MAIN_SPEC.LongFlag('--help')
@@ -265,13 +268,6 @@ def _AddShellOptions(spec):
265268
MAIN_SPEC.LongFlag('--login') # login - currently no-op
266269
MAIN_SPEC.LongFlag('--headless') # accepts ECMD, etc.
267270

268-
# --eval is not processed in interactive mode
269-
# TODO: This should be a list
270-
MAIN_SPEC.LongFlag('--eval', args.String)
271-
272-
# TODO: relative order of --eval and --eval-pure should be preserved
273-
MAIN_SPEC.LongFlag('--eval-pure', args.String)
274-
275271
# TODO: -h too
276272
# the output format when passing -n
277273
MAIN_SPEC.LongFlag('--ast-format',

frontend/flag_gen.py

+4
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ def _WriteActions(f, var_name, actions, counter):
128128
elif isinstance(action, args.SetNamedAction):
129129
action_type = 'SetNamedAction'
130130

131+
elif isinstance(action, args.AppendEvalFlag):
132+
action_type = 'AppendEvalFlag'
133+
name = action.name
134+
131135
else:
132136
raise AssertionError(action)
133137

frontend/flag_spec.py

+5
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,11 @@ def InitShopt(self):
266266
self.actions_short['O'] = args.SetNamedOption(shopt=True) # -O and +O
267267
self.plus_flags.append('O')
268268

269+
def EvalFlags(self):
270+
# type: () -> None
271+
self.actions_long['eval'] = args.AppendEvalFlag('eval')
272+
self.actions_long['eval-pure'] = args.AppendEvalFlag('eval-pure')
273+
269274
def ShortFlag(self,
270275
short_name,
271276
arg_type=None,

prebuilt/asdl/runtime.mycpp.cc

-4
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,12 @@ GLOBAL_STR(S_rpo, "\u001b[37m");
3737
GLOBAL_STR(S_sCc, "\u001b[4m");
3838
GLOBAL_STR(S_woy, "\u001b[7m");
3939
GLOBAL_STR(S_yfw, " ");
40-
GLOBAL_STR(S_ctw, "%s%s%s");
4140
GLOBAL_STR(S_Clt, "&");
4241
GLOBAL_STR(S_usD, "&amp;");
4342
GLOBAL_STR(S_dyr, "&gt;");
4443
GLOBAL_STR(S_Dcl, "&lt;");
4544
GLOBAL_STR(S_ijB, "(");
4645
GLOBAL_STR(S_hxb, ")");
47-
GLOBAL_STR(S_Cpi, "...0x%s");
4846
GLOBAL_STR(S_fyj, ":");
4947
GLOBAL_STR(S_eox, "<");
5048
GLOBAL_STR(S_jye, ">");
@@ -54,9 +52,7 @@ GLOBAL_STR(S_Eax, "[");
5452
GLOBAL_STR(S_xmu, "[]");
5553
GLOBAL_STR(S_pcD, "]");
5654
GLOBAL_STR(S_tci, "_");
57-
GLOBAL_STR(S_bme, "___ DOC COUNT %d");
5855
GLOBAL_STR(S_gfw, "___ GC: after printing");
59-
GLOBAL_STR(S_ray, "___ HNODE COUNT %d");
6056

6157
namespace ansi { // declare
6258

prebuilt/core/error.mycpp.cc

+8-3
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,13 @@ namespace runtime { // forward declare
1212
namespace num { // forward declare
1313
}
1414

15-
GLOBAL_STR(S_BEl, " (line %d, offset %d-%d: %r)");
16-
GLOBAL_STR(S_xFg, "%s, got %s");
1715
GLOBAL_STR(S_ijB, "(");
1816
GLOBAL_STR(S_hxb, ")");
1917
GLOBAL_STR(S_gFh, "F");
2018
GLOBAL_STR(S_cor, "T");
2119
GLOBAL_STR(S_tci, "_");
2220
GLOBAL_STR(S_gFE, "code");
21+
GLOBAL_STR(S_xho, "failglob: ");
2322
GLOBAL_STR(S_pBg, "message");
2423

2524
namespace runtime { // declare
@@ -124,7 +123,13 @@ Usage::Usage(BigStr* msg, syntax_asdl::loc_t* location) : ::error::_ErrorWithLoc
124123
Parse::Parse(BigStr* msg, syntax_asdl::loc_t* location) : ::error::_ErrorWithLocation(msg, location) {
125124
}
126125

127-
FailGlob::FailGlob(BigStr* msg, syntax_asdl::loc_t* location) : ::error::_ErrorWithLocation(msg, location) {
126+
WordFailure::WordFailure(BigStr* msg, syntax_asdl::loc_t* location) : ::error::_ErrorWithLocation(msg, location) {
127+
}
128+
129+
FailGlob::FailGlob(BigStr* msg, syntax_asdl::loc_t* location) : ::error::WordFailure(str_concat(S_xho, msg), location) {
130+
}
131+
132+
VarSubFailure::VarSubFailure(BigStr* msg, syntax_asdl::loc_t* location) : ::error::WordFailure(msg, location) {
128133
}
129134

130135
RedirectEval::RedirectEval(BigStr* msg, syntax_asdl::loc_t* location) : ::error::_ErrorWithLocation(msg, location) {

prebuilt/core/error.mycpp.h

+34-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ namespace error { // forward declare
1818
class _ErrorWithLocation;
1919
class Usage;
2020
class Parse;
21+
class WordFailure;
2122
class FailGlob;
23+
class VarSubFailure;
2224
class RedirectEval;
2325
class FatalRuntime;
2426
class Strict;
@@ -86,21 +88,51 @@ class Parse : public ::error::_ErrorWithLocation {
8688
DISALLOW_COPY_AND_ASSIGN(Parse)
8789
};
8890

89-
class FailGlob : public ::error::_ErrorWithLocation {
91+
class WordFailure : public ::error::_ErrorWithLocation {
9092
public:
91-
FailGlob(BigStr* msg, syntax_asdl::loc_t* location);
93+
WordFailure(BigStr* msg, syntax_asdl::loc_t* location);
9294

9395
static constexpr uint32_t field_mask() {
9496
return ::error::_ErrorWithLocation::field_mask();
9597
}
9698

99+
static constexpr ObjHeader obj_header() {
100+
return ObjHeader::ClassFixed(field_mask(), sizeof(WordFailure));
101+
}
102+
103+
DISALLOW_COPY_AND_ASSIGN(WordFailure)
104+
};
105+
106+
class FailGlob : public ::error::WordFailure {
107+
public:
108+
FailGlob(BigStr* msg, syntax_asdl::loc_t* location);
109+
110+
static constexpr uint32_t field_mask() {
111+
return ::error::WordFailure::field_mask();
112+
}
113+
97114
static constexpr ObjHeader obj_header() {
98115
return ObjHeader::ClassFixed(field_mask(), sizeof(FailGlob));
99116
}
100117

101118
DISALLOW_COPY_AND_ASSIGN(FailGlob)
102119
};
103120

121+
class VarSubFailure : public ::error::WordFailure {
122+
public:
123+
VarSubFailure(BigStr* msg, syntax_asdl::loc_t* location);
124+
125+
static constexpr uint32_t field_mask() {
126+
return ::error::WordFailure::field_mask();
127+
}
128+
129+
static constexpr ObjHeader obj_header() {
130+
return ObjHeader::ClassFixed(field_mask(), sizeof(VarSubFailure));
131+
}
132+
133+
DISALLOW_COPY_AND_ASSIGN(VarSubFailure)
134+
};
135+
104136
class RedirectEval : public ::error::_ErrorWithLocation {
105137
public:
106138
RedirectEval(BigStr* msg, syntax_asdl::loc_t* location);

0 commit comments

Comments
 (0)