Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
    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)
Ejemplo n.º 4
0
def GetVersion(loader):
  # type: (_ResourceLoader) -> str
  contents = loader.Get('oil-version.txt')
  version_str, _ = mylib.split_once(contents, '\n')
  return version_str
Ejemplo n.º 5
0
  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
Ejemplo n.º 6
0
 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', '='))