def MaybeCollect(self, cmd_ev, err): # type: (Any, _ErrorWithLocation) -> None # TODO: Any -> CommandEvaluator """ Args: cmd_ev: CommandEvaluator instance error: _ErrorWithLocation (ParseError or FatalRuntimeError) """ if not self.do_collect: # Either we already did it, or there is no file return if mylib.PYTHON: # can't translate yet due to dynamic typing self.var_stack, self.argv_stack, self.debug_stack = cmd_ev.mem.Dump() span_id = word_.SpanIdFromError(err) self.error = { 'msg': err.UserErrorString(), 'span_id': span_id, } if span_id != runtime.NO_SPID: span = cmd_ev.arena.GetLineSpan(span_id) line_id = span.line_id # Could also do msg % args separately, but JavaScript won't be able to # render that. self.error['source'] = cmd_ev.arena.GetLineSourceString(line_id) self.error['line_num'] = cmd_ev.arena.GetLineNumber(line_id) self.error['line'] = cmd_ev.arena.GetLine(line_id) # TODO: Collect functions, aliases, etc. self.do_collect = False self.collected = True
def MaybeCollect(self, ex, err): # type: (Any, _ErrorWithLocation) -> None # TODO: Any -> Executor """ Args: ex: Executor instance error: _ErrorWithLocation (ParseError or FatalRuntimeError) """ if not self.do_collect: # Either we already did it, or there is no file return self.var_stack, self.argv_stack, self.debug_stack = ex.mem.Dump() span_id = word_.SpanIdFromError(err) self.error = { 'msg': err.UserErrorString(), 'span_id': span_id, } if span_id != const.NO_INTEGER: span = ex.arena.GetLineSpan(span_id) line_id = span.line_id # Could also do msg % args separately, but JavaScript won't be able to # render that. self.error['source'] = ex.arena.GetLineSourceString(line_id) self.error['line_num'] = ex.arena.GetLineNumber(line_id) self.error['line'] = ex.arena.GetLine(line_id) # TODO: Collect functions, aliases, etc. self.do_collect = False self.collected = True
def _ValToIntOrError(self, val, blame_word=None, span_id=runtime.NO_SPID): # type: (value_t, word_t, int) -> int if span_id == runtime.NO_SPID and blame_word: span_id = word_.LeftMostSpanForWord(blame_word) #log('_ValToIntOrError span=%s blame=%s', span_id, blame_word) try: if val.tag == value_e.Undef: # 'nounset' already handled before got here # Happens upon a[undefined]=42, which unfortunately turns into a[0]=42. #log('blame_word %s arena %s', blame_word, self.arena) e_die('Undefined value in arithmetic context', span_id=span_id) if val.tag == value_e.Int: return val.i if val.tag == value_e.Str: return _StringToInteger(val.s, span_id=span_id) # calls e_die except error.FatalRuntime as e: if self.exec_opts.strict_arith: raise else: span_id = word_.SpanIdFromError(e) self.errfmt.PrettyPrintError(e, prefix='warning: ') return 0 # Arrays and associative arrays always fail -- not controlled by strict_arith. # In bash, (( a )) is like (( a[0] )), but I don't want that. # And returning '0' gives different results. e_die("Expected a value convertible to integer, got %s", val, span_id=span_id)
def _ValToArithOrError(self, val, blame_word=None, span_id=runtime.NO_SPID): if span_id == runtime.NO_SPID and blame_word: span_id = word_.LeftMostSpanForWord(blame_word) #log('_ValToArithOrError span=%s blame=%s', span_id, blame_word) try: i = self._ValToArith(val, span_id) except util.FatalRuntimeError as e: if self.exec_opts.strict_arith: raise else: i = 0 span_id = word_.SpanIdFromError(e) self.errfmt.PrettyPrintError(e, prefix='warning: ') return i
def PrettyPrintError(err, arena, prefix='', f=sys.stderr): # type: (_ErrorWithLocation, Arena, str, IO[str]) -> None """ Args: prefix: in osh/cmd_exec.py we want to print 'fatal' """ msg = err.UserErrorString() span_id = word_.SpanIdFromError(err) # TODO: Should there be a special span_id of 0 for EOF? runtime.NO_SPID # means there is no location info, but 0 could mean that the location is EOF. # So then you query the arena for the last line in that case? # Eof_Real is the ONLY token with 0 span, because it's invisible! # Well Eol_Tok is a sentinel with a span_id of runtime.NO_SPID. I think # that is OK. # Problem: the column for Eof could be useful. _PrintWithOptionalSpanId(prefix, msg, span_id, arena, f)
def _ValToIntOrError(self, val, span_id=runtime.NO_SPID): # type: (value_t, int) -> int try: UP_val = val with tagswitch(val) as case: if case(value_e.Undef ): # 'nounset' already handled before got here # Happens upon a[undefined]=42, which unfortunately turns into a[0]=42. #log('blame_word %s arena %s', blame_word, self.arena) e_die('Undefined value in arithmetic context', span_id=span_id) elif case(value_e.Int): val = cast(value__Int, UP_val) return val.i elif case(value_e.Str): val = cast(value__Str, UP_val) return _StringToInteger(val.s, span_id=span_id) # calls e_die elif case(value_e.Obj): # Note: this handles var x = 42; echo $(( x > 2 )). if mylib.PYTHON: val = cast(value__Obj, UP_val) if isinstance(val.obj, int): return val.obj raise AssertionError() # not in C++ except error.FatalRuntime as e: if self.exec_opts.strict_arith(): raise else: span_id = word_.SpanIdFromError(e) self.errfmt.PrettyPrintError(e, prefix='warning: ') return 0 # Arrays and associative arrays always fail -- not controlled by strict_arith. # In bash, (( a )) is like (( a[0] )), but I don't want that. # And returning '0' gives different results. e_die("Expected a value convertible to integer, got %s", ui.ValType(val), span_id=span_id)
def _pp(err, arena, prefix): # type: (_ErrorWithLocation, Arena, str) -> None """ Called by free function PrettyPrintError and method PrettyPrintError. This is a HACK for mycpp translation. C++ can't find a free function PrettyPrintError() when called within a METHOD of the same name. """ msg = err.UserErrorString() span_id = word_.SpanIdFromError(err) # TODO: Should there be a special span_id of 0 for EOF? runtime.NO_SPID # means there is no location info, but 0 could mean that the location is EOF. # So then you query the arena for the last line in that case? # Eof_Real is the ONLY token with 0 span, because it's invisible! # Well Eol_Tok is a sentinel with a span_id of runtime.NO_SPID. I think # that is OK. # Problem: the column for Eof could be useful. _PrintWithOptionalSpanId(prefix, msg, span_id, arena)