def Run(self, cmd_val): # type: (cmd_value__Argv) -> int attrs, arg_r = flag_spec.ParseCmdVal('shopt', cmd_val) arg = arg_types.shopt(attrs.attrs) opt_names = arg_r.Rest() if arg.p: # print values if arg.o: # use set -o names self.mutable_opts.ShowOptions(opt_names) else: self.mutable_opts.ShowShoptOptions(opt_names) return 0 if arg.q: # query values for name in opt_names: index = match.MatchOption(name) if index == 0: return 2 # bash gives 1 for invalid option; 2 is better if not self.mutable_opts.opt0_array[index]: return 1 # at least one option is not true return 0 # all options are true if arg.s: b = True elif arg.u: b = False else: # If no flags are passed, print the options. bash prints uses a # different format for 'shopt', but we use the same format as 'shopt # -p'. self.mutable_opts.ShowShoptOptions(opt_names) return 0 if cmd_val.block: opt_nums = [] # type: List[int] for name in opt_names: index = match.MatchOption(name) if index == 0: # TODO: compute span_id e_usage('got invalid option %r' % name) opt_nums.append(index) with state.ctx_Option(self.mutable_opts, opt_nums, b): unused = self.cmd_ev.EvalBlock(cmd_val.block) return 0 # cd also returns 0 # Otherwise, set options. for name in opt_names: #if arg.o: # self.mutable_opts.SetOption(name, b) #else: # We allow set -o options here self.mutable_opts.SetShoptOption(name, b) return 0
def Run(self, cmd_val): # type: (cmd_value__Argv) -> int arg, i = SHOPT_SPEC.ParseCmdVal(cmd_val) opt_names = cmd_val.argv[i:] if arg.p: # print values if arg.o: # use set -o names self.exec_opts.ShowOptions(opt_names) else: self.exec_opts.ShowShoptOptions(opt_names) return 0 if arg.q: # query values for name in opt_names: index = match.MatchOption(name) if index == 0: return 2 # bash gives 1 for invalid option; 2 is better if not self.exec_opts.opt_array[index]: return 1 # at least one option is not true return 0 # all options are true b = None if arg.s: b = True elif arg.u: b = False if b is None: # Print options # bash prints uses a different format for 'shopt', but we use the # same format as 'shopt -p'. self.exec_opts.ShowShoptOptions(opt_names) return 0 # Otherwise, set options. for name in opt_names: if arg.o: self.exec_opts.SetOption(name, b) else: self.exec_opts.SetShoptOption(name, b) return 0
def Run(self, cmd_val): # type: (cmd_value__Argv) -> int attrs, arg_r = flag_spec.ParseCmdVal('shopt', cmd_val) arg = arg_types.shopt(attrs.attrs) opt_names = arg_r.Rest() if arg.p: # print values if arg.o: # use set -o names self.exec_opts.ShowOptions(opt_names) else: self.exec_opts.ShowShoptOptions(opt_names) return 0 if arg.q: # query values for name in opt_names: index = match.MatchOption(name) if index == 0: return 2 # bash gives 1 for invalid option; 2 is better if not self.exec_opts.opt_array[index]: return 1 # at least one option is not true return 0 # all options are true if arg.s: b = True elif arg.u: b = False else: # bash prints uses a different format for 'shopt', but we use the # same format as 'shopt -p'. self.exec_opts.ShowShoptOptions(opt_names) return 0 # Otherwise, set options. for name in opt_names: if arg.o: self.exec_opts.SetOption(name, b) else: self.exec_opts.SetShoptOption(name, b) return 0
def Eval(self, node): # type: (bool_expr_t) -> bool UP_node = node with tagswitch(node) as case: if case(bool_expr_e.WordTest): node = cast(bool_expr__WordTest, UP_node) s = self._EvalCompoundWord(node.w) return bool(s) elif case(bool_expr_e.LogicalNot): node = cast(bool_expr__LogicalNot, UP_node) b = self.Eval(node.child) return not b elif case(bool_expr_e.LogicalAnd): node = cast(bool_expr__LogicalAnd, UP_node) # Short-circuit evaluation if self.Eval(node.left): return self.Eval(node.right) else: return False elif case(bool_expr_e.LogicalOr): node = cast(bool_expr__LogicalOr, UP_node) if self.Eval(node.left): return True else: return self.Eval(node.right) elif case(bool_expr_e.Unary): node = cast(bool_expr__Unary, UP_node) op_id = node.op_id s = self._EvalCompoundWord(node.child) # Now dispatch on arg type arg_type = consts.BoolArgType( op_id) # could be static in the LST? if arg_type == bool_arg_type_e.Path: return bool_stat.DoUnaryOp(op_id, s) if arg_type == bool_arg_type_e.Str: if op_id == Id.BoolUnary_z: return not bool(s) if op_id == Id.BoolUnary_n: return bool(s) raise AssertionError(op_id) # should never happen if arg_type == bool_arg_type_e.Other: if op_id == Id.BoolUnary_t: try: fd = int(s) except ValueError: # TODO: Need location information of [ e_die('Invalid file descriptor %r', s, word=node.child) return bool_stat.isatty(fd, s, node.child) # See whether 'set -o' options have been set if op_id == Id.BoolUnary_o: index = match.MatchOption(s) if index == 0: return False else: return self.exec_opts.opt_array[index] e_die("%s isn't implemented", ui.PrettyId(op_id)) # implicit location raise AssertionError(arg_type) # should never happen elif case(bool_expr_e.Binary): node = cast(bool_expr__Binary, UP_node) op_id = node.op_id # Whether to glob escape with switch(op_id) as case2: if case2(Id.BoolBinary_GlobEqual, Id.BoolBinary_GlobDEqual, Id.BoolBinary_GlobNEqual): quote_kind = quote_e.FnMatch elif case2(Id.BoolBinary_EqualTilde): quote_kind = quote_e.ERE else: quote_kind = quote_e.Default s1 = self._EvalCompoundWord(node.left) s2 = self._EvalCompoundWord(node.right, quote_kind=quote_kind) # Now dispatch on arg type arg_type = consts.BoolArgType(op_id) if arg_type == bool_arg_type_e.Path: return bool_stat.DoBinaryOp(op_id, s1, s2) if arg_type == bool_arg_type_e.Int: # NOTE: We assume they are constants like [[ 3 -eq 3 ]]. # Bash also allows [[ 1+2 -eq 3 ]]. i1 = self._StringToIntegerOrError(s1, blame_word=node.left) i2 = self._StringToIntegerOrError(s2, blame_word=node.right) if op_id == Id.BoolBinary_eq: return i1 == i2 if op_id == Id.BoolBinary_ne: return i1 != i2 if op_id == Id.BoolBinary_gt: return i1 > i2 if op_id == Id.BoolBinary_ge: return i1 >= i2 if op_id == Id.BoolBinary_lt: return i1 < i2 if op_id == Id.BoolBinary_le: return i1 <= i2 raise AssertionError(op_id) # should never happen if arg_type == bool_arg_type_e.Str: if op_id in (Id.BoolBinary_GlobEqual, Id.BoolBinary_GlobDEqual): #log('Matching %s against pattern %s', s1, s2) return libc.fnmatch(s2, s1) if op_id == Id.BoolBinary_GlobNEqual: return not libc.fnmatch(s2, s1) if op_id in (Id.BoolBinary_Equal, Id.BoolBinary_DEqual): return s1 == s2 if op_id == Id.BoolBinary_NEqual: return s1 != s2 if op_id == Id.BoolBinary_EqualTilde: # TODO: This should go to --debug-file #log('Matching %r against regex %r', s1, s2) try: matches = libc.regex_match(s2, s1) except RuntimeError: # Status 2 indicates a regex parse error. This is fatal in OSH but # not in bash, which treats [[ like a command with an exit code. e_die("Invalid regex %r", s2, word=node.right, status=2) if matches is None: return False self._SetRegexMatches(matches) return True if op_id == Id.Op_Less: return s1 < s2 if op_id == Id.Op_Great: return s1 > s2 raise AssertionError(op_id) # should never happen raise AssertionError(node.tag_())
def __init__(self, opt0_array, opt_stacks, opt_name): # type: (List[bool], List[List[bool]], str) -> None self.opt0_array = opt0_array self.opt_stacks = opt_stacks self.num = match.MatchOption(opt_name) assert self.num != 0, opt_name