def Run(self, cmd_val): # type: (cmd_value__Argv) -> int _, arg_r = flag_spec.ParseCmdVal('alias', cmd_val) argv = arg_r.Rest() if len(argv) == 0: for name in sorted(self.aliases): alias_exp = self.aliases[name] # This is somewhat like bash, except we use %r for ''. print('alias %s=%r' % (name, alias_exp)) return 0 status = 0 for i, arg in enumerate(argv): name, alias_exp = mylib.split_once(arg, '=') if alias_exp is None: # if we get a plain word without, print alias alias_exp = self.aliases.get(name) if alias_exp is None: self.errfmt.Print_('No alias named %r' % name, span_id=cmd_val.arg_spids[i]) status = 1 else: print('alias %s=%r' % (name, alias_exp)) else: self.aliases[name] = alias_exp #print(argv) #log('AFTER ALIAS %s', aliases) return status
def ShowAppVersion(app_name, loader): # type: (str, _ResourceLoader) -> None """Show version and platform information.""" try: contents = loader.Get('release-date.txt') release_date, _ = mylib.split_once(contents, '\n') except IOError: release_date = '-' # in dev tree try: contents = loader.Get('pyc-version.txt') pyc_version, _ = mylib.split_once(contents, '\n') except IOError: pyc_version = '-' # in dev tree # node is like 'hostname' # release is the kernel version system, unused_node, unused_release, platform_version, machine = posix.uname( ) # The platform.py module has a big regex that parses sys.version, but we # don't want to depend on regular expressions. So we will do our own parsing # here. version_line, py_compiler = sys.version.splitlines() # Pick off the first part of '2.7.12 (default, ...)' py_version = version_line.split()[0] assert py_compiler.startswith('['), py_compiler assert py_compiler.endswith(']'), py_compiler py_compiler = py_compiler[1:-1] # We removed sys.executable from sysmodule.c. py_impl = 'CPython' if hasattr(sys, 'executable') else 'OVM' version_str = GetVersion(loader) # What C functions do these come from? print('%s version %s' % (app_name, version_str)) print('Release Date: %s' % release_date) print('Arch: %s' % machine) print('OS: %s' % system) print('Platform: %s' % platform_version) print('Compiler: %s' % py_compiler) print('Interpreter: %s' % py_impl) print('Interpreter version: %s' % py_version) print('Bytecode: %s' % pyc_version)
def _ReplaceBackslashCodes(self, tokens): # type: (List[Tuple[Id_t, str]]) -> str ret = [] # type: List[str] non_printing = 0 for id_, value in tokens: # BadBacklash means they should have escaped with \\. TODO: Make it an error. # 'echo -e' has a similar issue. if id_ in (Id.PS_Literals, Id.PS_BadBackslash): ret.append(value) elif id_ == Id.PS_Octal3: i = int(value[1:], 8) ret.append(chr(i % 256)) elif id_ == Id.PS_LBrace: non_printing += 1 ret.append('\x01') elif id_ == Id.PS_RBrace: non_printing -= 1 if non_printing < 0: # e.g. \]\[ return PROMPT_ERROR ret.append('\x02') elif id_ == Id.PS_Subst: # \u \h \w etc. ch = value[1:] if ch == '$': # So the user can tell if they're root or not. r = self.cache.Get('$') elif ch == 'u': r = self.cache.Get('user') elif ch == 'h': hostname = self.cache.Get('hostname') # foo.com -> foo r, _ = mylib.split_once(hostname, '.') elif ch == 'H': r = self.cache.Get('hostname') elif ch == 'w': try: pwd = state.GetString(self.mem, 'PWD') home = state.MaybeString( self.mem, 'HOME') # doesn't have to exist # Shorten to ~/mydir r = ui.PrettyDir(pwd, home) except error.Runtime as e: r = '<Error: %s>' % e.UserErrorString() elif ch == 'W': val = self.mem.GetValue('PWD') if val.tag_() == value_e.Str: str_val = cast(value__Str, val) r = os_path.basename(str_val.s) else: r = '<Error: PWD is not a string> ' else: r = consts.LookupCharPrompt(ch) # TODO: Handle more codes # R(r'\\[adehHjlnrstT@AuvVwW!#$\\]', Id.PS_Subst), if r is None: r = r'<Error: \%s not implemented in $PS1> ' % ch # See comment above on bash hack for $. ret.append(r.replace('$', '\\$')) else: raise AssertionError('Invalid token %r' % id_) # mismatched brackets, see https://github.com/oilshell/oil/pull/256 if non_printing != 0: return PROMPT_ERROR return ''.join(ret)
def GetVersion(loader): # type: (_ResourceLoader) -> str contents = loader.Get('oil-version.txt') version_str, _ = mylib.split_once(contents, '\n') return version_str
def _StringToInteger(self, s, span_id=runtime.NO_SPID): # type: (str, int) -> int """Use bash-like rules to coerce a string to an integer. Runtime parsing enables silly stuff like $(( $(echo 1)$(echo 2) + 1 )) => 13 0xAB -- hex constant 042 -- octal constant 42 -- decimal constant 64#z -- arbitary base constant bare word: variable quoted word: string (not done?) """ if s.startswith('0x'): try: integer = int(s, 16) except ValueError: e_strict('Invalid hex constant %r', s, span_id=span_id) return integer if s.startswith('0'): try: integer = int(s, 8) except ValueError: e_strict('Invalid octal constant %r', s, span_id=span_id) return integer if '#' in s: b, digits = mylib.split_once(s, '#') try: base = int(b) except ValueError: e_strict('Invalid base for numeric constant %r', b, span_id=span_id) integer = 0 for ch in digits: if IsLower(ch): digit = ord(ch) - ord('a') + 10 elif IsUpper(ch): digit = ord(ch) - ord('A') + 36 elif ch == '@': # horrible syntax digit = 62 elif ch == '_': digit = 63 elif ch.isdigit(): digit = int(ch) else: e_strict('Invalid digits for numeric constant %r', digits, span_id=span_id) if digit >= base: e_strict('Digits %r out of range for base %d', digits, base, span_id=span_id) integer = integer * base + digit return integer try: # Normal base 10 integer. This includes negative numbers like '-42'. integer = int(s) except ValueError: # doesn't look like an integer # note: 'test' and '[' never evaluate recursively if self.exec_opts.eval_unsafe_arith() and self.parse_ctx: # Special case so we don't get EOF error if len(s.strip()) == 0: return 0 # For compatibility: Try to parse it as an expression and evaluate it. arena = self.parse_ctx.arena a_parser = self.parse_ctx.MakeArithParser(s) with alloc.ctx_Location(arena, source.Variable(span_id)): try: node2 = a_parser.Parse() # may raise error.Parse except error.Parse as e: ui.PrettyPrintError(e, arena) e_die('Parse error in recursive arithmetic', span_id=e.span_id) # Prevent infinite recursion of $(( 1x )) -- it's a word that evaluates # to itself, and you don't want to reparse it as a word. if node2.tag_() == arith_expr_e.Word: e_die("Invalid integer constant %r", s, span_id=span_id) else: integer = self.EvalToInt(node2) else: if len(s.strip()) == 0 or match.IsValidVarName(s): # x42 could evaluate to 0 e_strict("Invalid integer constant %r", s, span_id=span_id) else: # 42x is always fatal! e_die("Invalid integer constant %r", s, span_id=span_id) return integer
def testSplit(self): self.assertEqual(('foo', None), mylib.split_once('foo', '=')) self.assertEqual(('foo', ''), mylib.split_once('foo=', '=')) self.assertEqual(('foo', 'bar'), mylib.split_once('foo=bar', '='))