Beispiel #1
0
  def testPushTemp(self):
    mem = _InitMem()

    # x=1
    mem.SetVar(
        lvalue.LhsName('x'), value.Str('1'), (), scope_e.Dynamic)
    self.assertEqual('1', mem.var_stack[-1].vars['x'].val.s)

    mem.PushTemp()

    self.assertEqual(2, len(mem.var_stack))

    # Temporary frame is immutable
    self.assertEqual(False, mem.var_stack[-1].mutable)
    self.assertEqual(True, mem.var_stack[-2].mutable)

    # x=temp E=3 read x <<< 'line'
    mem.SetVar(
        lvalue.LhsName('x'), value.Str('temp'), (), scope_e.TempEnv)
    mem.SetVar(
        lvalue.LhsName('E'), value.Str('3'), (), scope_e.TempEnv)
    mem.SetVar(
        lvalue.LhsName('x'), value.Str('line'), (), scope_e.LocalOnly)

    self.assertEqual('3', mem.var_stack[-1].vars['E'].val.s)
    self.assertEqual('temp', mem.var_stack[-1].vars['x'].val.s)
    self.assertEqual('line', mem.var_stack[-2].vars['x'].val.s)

    mem.PopTemp()
    self.assertEqual(1, len(mem.var_stack))
    self.assertEqual('line', mem.var_stack[-1].vars['x'].val.s)
Beispiel #2
0
  def testPushTemp(self):
    mem = _InitMem()

    # x=1
    mem.SetVar(
        lvalue.LhsName('x'), value.Str('1'), (), scope_e.Dynamic)
    self.assertEqual('1', mem.var_stack[-1]['x'].val.s)

    mem.PushTemp()

    self.assertEqual(2, len(mem.var_stack))

    # x=temp E=3 read x <<< 'line'
    mem.SetVar(
        lvalue.LhsName('x'), value.Str('temp'), (), scope_e.LocalOnly)
    mem.SetVar(
        lvalue.LhsName('E'), value.Str('3'), (), scope_e.LocalOnly)
    mem.SetVar(
        lvalue.LhsName('x'), value.Str('line'), (), scope_e.LocalOnly)

    self.assertEqual('3', mem.var_stack[-1]['E'].val.s)
    self.assertEqual('line', mem.var_stack[-1]['x'].val.s)
    self.assertEqual('1', mem.var_stack[-2]['x'].val.s)

    mem.PopTemp()
    self.assertEqual(1, len(mem.var_stack))
    self.assertEqual('1', mem.var_stack[-1]['x'].val.s)
Beispiel #3
0
    def testExportThenAssign(self):
        """Regression Test"""
        mem = _InitMem()

        # export U
        mem.SetVar(lvalue.LhsName('U'), None, (var_flags_e.Exported, ),
                   scope_e.Dynamic)
        print(mem)

        # U=u
        mem.SetVar(lvalue.LhsName('U'), value.Str('u'), (), scope_e.Dynamic)
        print(mem)
        e = mem.GetExported()
        self.assertEqual('u', e['U'])
Beispiel #4
0
def Export(argv, mem):
    arg, i = EXPORT_SPEC.Parse(argv)
    if arg.n:
        for name in argv[i:]:
            m = match.IsValidVarName(name)
            if not m:
                raise args.UsageError('export: Invalid variable name %r' %
                                      name)

            # NOTE: bash doesn't care if it wasn't found.
            mem.ClearFlag(name, var_flags_e.Exported, scope_e.Dynamic)
    else:
        for arg in argv[i:]:
            parts = arg.split('=', 1)
            if len(parts) == 1:
                name = parts[0]
                val = None  # Creates an empty variable
            else:
                name, s = parts
                val = value.Str(s)

            m = match.IsValidVarName(name)
            if not m:
                raise args.UsageError('export: Invalid variable name %r' %
                                      name)

            #log('%s %s', name, val)
            mem.SetVar(lvalue.LhsName(name), val, (var_flags_e.Exported, ),
                       scope_e.Dynamic)

    return 0
Beispiel #5
0
    def _EvalLhsArith(self, node):
        """lhs_expr -> lvalue.
    
    Very similar to _EvalLhs in core/cmd_exec.
    """
        assert isinstance(node, lhs_expr_t), node

        if node.tag == lhs_expr_e.LhsName:  # (( i = 42 ))
            lval = lvalue.LhsName(node.name)
            # TODO: location info.  Use the = token?
            #lval.spids.append(spid)
            return lval

        if node.tag == lhs_expr_e.LhsIndexedName:  # (( a[42] = 42 ))
            # The index of StrArray needs to be coerced to int, but not the index of
            # an AssocArray.
            int_coerce = not self.mem.IsAssocArray(node.name, scope_e.Dynamic)
            index = self.Eval(node.index, int_coerce=int_coerce)

            lval = lvalue.LhsIndexedName(node.name, index)
            # TODO: location info.  Use the = token?
            #lval.spids.append(node.spids[0])
            return lval

        raise AssertionError(node.tag)
Beispiel #6
0
 def _EvalTempEnv(self, more_env):
   """For FOO=1 cmd."""
   for env_pair in more_env:
     val = self.word_ev.EvalWordToString(env_pair.val)
     # Set each var so the next one can reference it.  Example:
     # FOO=1 BAR=$FOO ls /
     self.mem.SetVar(lvalue.LhsName(env_pair.name), val,
                     (var_flags_e.Exported,), scope_e.TempEnv)
Beispiel #7
0
  def testUnset(self):
    mem = _InitMem()
    # unset a
    mem.Unset(lvalue.LhsName('a'), scope_e.Dynamic)

    return  # not implemented yet

    # unset a[1]
    mem.Unset(lvalue.LhsIndexedName('a', 1), scope_e.Dynamic)
Beispiel #8
0
    def testGetVar(self):
        mem = _InitMem()

        # readonly a=x
        mem.SetVar(lvalue.LhsName('a'), value.Str('x'),
                   (var_flags_e.ReadOnly, ), scope_e.Dynamic)

        val = mem.GetVar('a', scope_e.Dynamic)
        test_lib.AssertAsdlEqual(self, value.Str('x'), val)

        val = mem.GetVar('undef', scope_e.Dynamic)
        test_lib.AssertAsdlEqual(self, value.Undef(), val)
Beispiel #9
0
def Unset(argv, mem, funcs):
    arg, i = UNSET_SPEC.Parse(argv)

    for name in argv[i:]:
        if arg.f:
            if name in funcs:
                del funcs[name]
        elif arg.v:
            ok, _ = mem.Unset(lvalue.LhsName(name), scope_e.Dynamic)
            if not ok:
                util.error("Can't unset readonly variable %r", name)
                return 1
        else:
            # Try to delete var first, then func.
            ok, found = mem.Unset(lvalue.LhsName(name), scope_e.Dynamic)
            if not ok:
                util.error("Can't unset readonly variable %r", name)
                return 1
            #log('%s: %s', name, found)
            if not found:
                if name in funcs:
                    del funcs[name]

    return 0
Beispiel #10
0
  def _EvalLhs(self, node, spid, lookup_mode):
    """lhs_expr -> lvalue."""
    assert isinstance(node, lhs_expr_t), node

    if node.tag == lhs_expr_e.LhsName:  # a=x
      lval = lvalue.LhsName(node.name)
      lval.spids.append(spid)
      return lval

    if node.tag == lhs_expr_e.LhsIndexedName:  # a[1+2]=x
      # The index of StrArray needs to be coerced to int, but not the index of
      # an AssocArray.
      int_coerce = not self.mem.IsAssocArray(node.name, lookup_mode)
      index = self.arith_ev.Eval(node.index, int_coerce=int_coerce)

      lval = lvalue.LhsIndexedName(node.name, index)
      lval.spids.append(node.spids[0])  # copy left-most token over
      return lval

    raise AssertionError(node.tag)
Beispiel #11
0
  def testSetVarClearFlag(self):
    mem = _InitMem()
    print(mem)

    mem.PushCall('my-func', 0, ['ONE'])
    self.assertEqual(2, len(mem.var_stack))  # internal details

    # local x=y
    mem.SetVar(
        lvalue.LhsName('x'), value.Str('y'), (), scope_e.LocalOnly)
    self.assertEqual('y', mem.var_stack[-1]['x'].val.s)

    # New frame
    mem.PushCall('my-func', 0, ['TWO'])
    self.assertEqual(3, len(mem.var_stack))  # internal details

    # x=y -- test out dynamic scope
    mem.SetVar(
        lvalue.LhsName('x'), value.Str('YYY'), (), scope_e.Dynamic)
    self.assertEqual('YYY', mem.var_stack[-2]['x'].val.s)
    self.assertEqual(None, mem.var_stack[-1].get('x'))

    # myglobal=g
    mem.SetVar(
        lvalue.LhsName('myglobal'), value.Str('g'), (), scope_e.Dynamic)
    self.assertEqual('g', mem.var_stack[0]['myglobal'].val.s)
    self.assertEqual(False, mem.var_stack[0]['myglobal'].exported)

    # 'export PYTHONPATH=/'
    mem.SetVar(
        lvalue.LhsName('PYTHONPATH'), value.Str('/'),
        (var_flags_e.Exported,), scope_e.Dynamic)
    self.assertEqual('/', mem.var_stack[0]['PYTHONPATH'].val.s)
    self.assertEqual(True, mem.var_stack[0]['PYTHONPATH'].exported)

    ex = mem.GetExported()
    self.assertEqual('/', ex['PYTHONPATH'])

    mem.SetVar(
        lvalue.LhsName('PYTHONPATH'), None, (var_flags_e.Exported,),
        scope_e.Dynamic)
    self.assertEqual(True, mem.var_stack[0]['PYTHONPATH'].exported)

    # 'export myglobal'.  None means don't touch it.  Undef would be confusing
    # because it might mean "unset", but we have a separated API for that.
    mem.SetVar(
        lvalue.LhsName('myglobal'), None, (var_flags_e.Exported,),
        scope_e.Dynamic)
    self.assertEqual(True, mem.var_stack[0]['myglobal'].exported)

    # export g2  -- define and export empty
    mem.SetVar(
        lvalue.LhsName('g2'), None, (var_flags_e.Exported,),
        scope_e.Dynamic)
    self.assertEqual(value_e.Undef, mem.var_stack[0]['g2'].val.tag)
    self.assertEqual(True, mem.var_stack[0]['g2'].exported)

    # readonly myglobal
    self.assertEqual(False, mem.var_stack[0]['myglobal'].readonly)
    mem.SetVar(
        lvalue.LhsName('myglobal'), None, (var_flags_e.ReadOnly,),
        scope_e.Dynamic)
    self.assertEqual(True, mem.var_stack[0]['myglobal'].readonly)

    mem.SetVar(
        lvalue.LhsName('PYTHONPATH'), value.Str('/lib'), (),
        scope_e.Dynamic)
    self.assertEqual('/lib', mem.var_stack[0]['PYTHONPATH'].val.s)
    self.assertEqual(True, mem.var_stack[0]['PYTHONPATH'].exported)

    # COMPREPLY=(1 2 3)
    # invariant to enforce: arrays can't be exported
    mem.SetVar(
        lvalue.LhsName('COMPREPLY'), value.StrArray(['1', '2', '3']),
        (), scope_e.GlobalOnly)
    self.assertEqual(
        ['1', '2', '3'], mem.var_stack[0]['COMPREPLY'].val.strs)

    # export COMPREPLY
    try:
      mem.SetVar(
          lvalue.LhsName('COMPREPLY'), None, (var_flags_e.Exported,),
          scope_e.Dynamic)
    except util.FatalRuntimeError as e:
      pass
    else:
      self.fail("Expected failure")

    # readonly r=1
    mem.SetVar(
        lvalue.LhsName('r'), value.Str('1'), (var_flags_e.ReadOnly,),
        scope_e.Dynamic)
    self.assertEqual('1', mem.var_stack[0]['r'].val.s)
    self.assertEqual(False, mem.var_stack[0]['r'].exported)
    self.assertEqual(True, mem.var_stack[0]['r'].readonly)
    print(mem)

    # r=newvalue
    try:
      mem.SetVar(
          lvalue.LhsName('r'), value.Str('newvalue'), (), scope_e.Dynamic)
    except util.FatalRuntimeError as e:
      pass
    else:
      self.fail("Expected failure")

    # readonly r2  -- define empty readonly
    mem.SetVar(
        lvalue.LhsName('r2'), None, (var_flags_e.ReadOnly,),
        scope_e.Dynamic)
    self.assertEqual(value_e.Undef, mem.var_stack[0]['r2'].val.tag)
    self.assertEqual(True, mem.var_stack[0]['r2'].readonly)

    # export -n PYTHONPATH
    # Remove the exported property.  NOTE: scope is LocalOnly for Oil?
    self.assertEqual(True, mem.var_stack[0]['PYTHONPATH'].exported)
    mem.ClearFlag('PYTHONPATH', var_flags_e.Exported, scope_e.Dynamic)
    self.assertEqual(False, mem.var_stack[0]['PYTHONPATH'].exported)

    lhs = lvalue.LhsIndexedName('a', 1)
    lhs.spids.append(0)
    # a[1]=2
    mem.SetVar(lhs, value.Str('2'), (), scope_e.Dynamic)
    self.assertEqual([None, '2'], mem.var_stack[0]['a'].val.strs)

    # a[1]=3
    mem.SetVar(lhs, value.Str('3'), (), scope_e.Dynamic)
    self.assertEqual([None, '3'], mem.var_stack[0]['a'].val.strs)

    # a[1]=(x y z)  # illegal
    try:
      mem.SetVar(lhs, value.StrArray(['x', 'y', 'z']), (), scope_e.Dynamic)
    except util.FatalRuntimeError as e:
      pass
    else:
      self.fail("Expected failure")

    # readonly a
    mem.SetVar(
        lvalue.LhsName('a'), None, (var_flags_e.ReadOnly,),
        scope_e.Dynamic)
    self.assertEqual(True, mem.var_stack[0]['a'].readonly)

    try:
      # a[1]=3
      mem.SetVar(lhs, value.Str('3'), (), scope_e.Dynamic)
    except util.FatalRuntimeError as e:
      pass
    else:
      self.fail("Expected failure")
Beispiel #12
0
def EvalLhsAndLookup(node, arith_ev, mem, exec_opts):
    """Evaluate the operand for i++, a[0]++, i+=2, a[0]+=2 as an R-value.

  Also used by the Executor for s+='x' and a[42]+='x'.

  Args:
    node: syntax_asdl.lhs_expr

  Returns:
    value_t, lvalue_t
  """
    #log('lhs_expr NODE %s', node)
    assert isinstance(node, lhs_expr_t), node

    if node.tag == lhs_expr_e.LhsName:  # a = b
        # Problem: It can't be an array?
        # a=(1 2)
        # (( a++ ))
        lval = lvalue.LhsName(node.name)
        val = _LookupVar(node.name, mem, exec_opts)

    elif node.tag == lhs_expr_e.LhsIndexedName:  # a[1] = b
        # See tdop.IsIndexable for valid values:
        # - ArithVarRef (not LhsName): a[1]
        # - FuncCall: f(x), 1
        # - ArithBinary LBracket: f[1][1] -- no semantics for this?

        index = arith_ev.Eval(node.index)
        lval = lvalue.LhsIndexedName(node.name, index)

        val = mem.GetVar(node.name)
        if val.tag == value_e.Str:
            e_die("Can't assign to characters of string %r", node.name)

        elif val.tag == value_e.Undef:
            # It would make more sense for 'nounset' to control this, but bash
            # doesn't work that way.
            #if self.exec_opts.strict_arith:
            #  e_die('Undefined array %r', node.name)
            val = value.Str('')

        elif val.tag == value_e.StrArray:

            #log('ARRAY %s -> %s, index %d', node.name, array, index)
            array = val.strs
            # NOTE: Similar logic in RHS Arith_LBracket
            try:
                item = array[index]
            except IndexError:
                item = None

            if item is None:
                val = value.Str('')
            else:
                assert isinstance(item, str), item
                val = value.Str(item)

        elif val.tag == value_e.AssocArray:  # declare -A a; a['x']+=1
            # TODO: Also need IsAssocArray() check?
            index = arith_ev.Eval(node.index, int_coerce=False)
            lval = lvalue.LhsIndexedName(node.name, index)
            raise NotImplementedError

        else:
            raise AssertionError(val.tag)

    else:
        raise AssertionError(node.tag)

    return val, lval