Ejemplo n.º 1
0
def _ReconcileTypes(rval, flag_a, flag_A, span_id):
    # type: (Optional[value_t], bool, bool, int) -> value_t
    """Check that -a and -A flags are consistent with RHS.

  Special case: () is allowed to mean empty indexed array or empty assoc array
  if the context is clear.

  Shared between NewVar and Readonly.
  """
    if flag_a and rval is not None and rval.tag_() != value_e.MaybeStrArray:
        e_usage("Got -a but RHS isn't an array", span_id=span_id)

    if flag_A and rval:
        # Special case: declare -A A=() is OK.  The () is changed to mean an empty
        # associative array.
        if rval.tag_() == value_e.MaybeStrArray:
            array_val = cast(value__MaybeStrArray, rval)
            if len(array_val.strs) == 0:
                return value.AssocArray({})
                #return value.MaybeStrArray([])

        if rval.tag_() != value_e.AssocArray:
            e_usage("Got -A but RHS isn't an associative array",
                    span_id=span_id)

    return rval
Ejemplo n.º 2
0
  def __call__(self, cmd_val):
    arg_r = args.Reader(cmd_val.argv, spids=cmd_val.arg_spids)
    arg_r.Next()
    arg, arg_index = READONLY_SPEC.Parse(arg_r)

    for pair in cmd_val.pairs:
      if pair.rval is None:
        if arg.a:
          rval = value.MaybeStrArray([])
        elif arg.A:
          rval = value.AssocArray({})
        else:
          rval = None
      else:
        rval = pair.rval

      if not _CheckType(rval, arg, self.errfmt, pair.spid):
        return 1

      # NOTE:
      # - when rval is None, only flags are changed
      # - dynamic scope because flags on locals can be changed, etc.
      self.mem.SetVar(pair.lval, rval, (var_flags_e.ReadOnly,), scope_e.Dynamic)

    return 0
Ejemplo n.º 3
0
  def Run(self, cmd_val):
    # type: (cmd_value__Assign) -> int
    arg_r = args.Reader(cmd_val.argv, spids=cmd_val.arg_spids)
    arg_r.Next()
    attrs = flag_spec.Parse('readonly', arg_r)
    arg = arg_types.readonly(attrs.attrs)

    if arg.p or len(cmd_val.pairs) == 0:
      return _PrintVariables(self.mem, cmd_val, attrs, True, builtin=_READONLY)

    for pair in cmd_val.pairs:
      if pair.rval is None:
        if arg.a:
          rval = value.MaybeStrArray([])  # type: value_t
        elif arg.A:
          rval = value.AssocArray({})
        else:
          rval = None
      else:
        rval = pair.rval

      rval = _ReconcileTypes(rval, arg.a, arg.A, pair.spid)

      # NOTE:
      # - when rval is None, only flags are changed
      # - dynamic scope because flags on locals can be changed, etc.
      self.mem.SetVar(lvalue.Named(pair.var_name), rval, scope_e.Dynamic,
                      flags=state.SetReadOnly)

    return 0
Ejemplo n.º 4
0
  def _BindNewAssocArrayWithEntry(self, namespace, lval, val, new_flags):
    """Fill 'namespace' with a new indexed array entry."""
    d = {lval.index: val.s}  # TODO: RHS has to be string?
    new_value = value.AssocArray(d)

    # associative arrays can't be exported; don't need AssocArray flag
    readonly = var_flags_e.ReadOnly in new_flags
    namespace[lval.name] = runtime_asdl.cell(new_value, False, readonly, False)
Ejemplo n.º 5
0
  def __call__(self, cmd_val):
    arg_r = args.Reader(cmd_val.argv, spids=cmd_val.arg_spids)
    arg_r.Next()
    arg, arg_index = NEW_VAR_SPEC.Parse(arg_r)

    status = 0

    # NOTE: in bash, -f shows the function body, while -F shows the name.  In
    # osh, they're identical and behave like -F.
    if arg.f or arg.F:  # Lookup and print functions.
      names = [pair.lval.name for pair in cmd_val.pairs]
      if names:
        for name in names:
          if name in self.funcs:
            print(name)
            # TODO: Could print LST, or render LST.  Bash does this.  'trap' too.
            #print(funcs[name])
          else:
            status = 1
      elif arg.F:
        for func_name in sorted(self.funcs):
          print('declare -f %s' % (func_name))
      else:
        raise args.UsageError('declare/typeset -f without args')
      return status

    if arg.p:  # Lookup and print variables.
      names = [pair.lval.name for pair in cmd_val.pairs]
      if names:
        for name in names:
          val = self.mem.GetVar(name)
          if val.tag != value_e.Undef:
            # TODO: Print flags.

            print(name)
          else:
            status = 1
      else:
        raise args.UsageError('declare/typeset -p without args')
      return status

    #
    # Set variables
    #

    #raise args.UsageError("doesn't understand %s" % cmd_val.argv[1:])
    if cmd_val.builtin_id == builtin_e.LOCAL:
      lookup_mode = scope_e.LocalOnly
    else:  # declare/typeset
      if arg.g:  
        lookup_mode = scope_e.GlobalOnly
      else:
        lookup_mode = scope_e.LocalOnly

    flags_to_set = []
    if arg.x == '-': 
      flags_to_set.append(var_flags_e.Exported)
    if arg.r == '-':
      flags_to_set.append(var_flags_e.ReadOnly)

    flags_to_clear = []
    if arg.x == '+': 
      flags_to_clear.append(var_flags_e.Exported)
    if arg.r == '+':
      flags_to_clear.append(var_flags_e.ReadOnly)

    for pair in cmd_val.pairs:
      if pair.rval is None:
        if arg.a:
          rval = value.MaybeStrArray([])
        elif arg.A:
          rval = value.AssocArray({})
        else:
          rval = None
      else:
        rval = pair.rval

      if not _CheckType(rval, arg, self.errfmt, pair.spid):
        return 1
      self.mem.SetVar(pair.lval, rval, flags_to_set, lookup_mode,
                      flags_to_clear=flags_to_clear)

    return status
Ejemplo n.º 6
0
    def Run(self, cmd_val):
        # type: (cmd_value__Assign) -> int
        arg_r = args.Reader(cmd_val.argv, spids=cmd_val.arg_spids)
        arg_r.Next()
        attrs = flag_spec.Parse('new_var', arg_r)
        arg = arg_types.new_var(attrs.attrs)

        status = 0

        if arg.f:
            names = arg_r.Rest()
            if len(names):
                # NOTE: in bash, -f shows the function body, while -F shows the name.
                # Right now we just show the name.
                status = self._PrintFuncs(names)
            else:
                e_usage('passed -f without args')
            return status

        if arg.F:
            names = arg_r.Rest()
            if len(names):
                status = self._PrintFuncs(names)
            else:  # weird bash quirk: they're printed in a different format!
                for func_name in sorted(self.funcs):
                    print('declare -f %s' % (func_name))
            return status

        if arg.p:  # Lookup and print variables.
            return _PrintVariables(self.mem, cmd_val, attrs, True)
        elif len(cmd_val.pairs) == 0:
            return _PrintVariables(self.mem, cmd_val, attrs, False)

        #
        # Set variables
        #

        #raise error.Usage("doesn't understand %s" % cmd_val.argv[1:])
        if cmd_val.builtin_id == builtin_i.local:
            lookup_mode = scope_e.LocalOnly
        else:  # declare/typeset
            if arg.g:
                lookup_mode = scope_e.GlobalOnly
            else:
                lookup_mode = scope_e.LocalOnly

        flags = 0
        if arg.x == '-':
            flags |= state.SetExport
        if arg.r == '-':
            flags |= state.SetReadOnly
        if arg.n == '-':
            flags |= state.SetNameref

        flags_to_clear = 0
        if arg.x == '+':
            flags |= state.ClearExport
        if arg.r == '+':
            flags |= state.ClearReadOnly
        if arg.n == '+':
            flags |= state.ClearNameref

        for pair in cmd_val.pairs:
            rval = pair.rval
            # declare -a foo=(a b); declare -a foo;  should not reset to empty array
            if rval is None and (arg.a or arg.A):
                old_val = self.mem.GetVar(pair.var_name)
                if arg.a:
                    if old_val.tag_() != value_e.MaybeStrArray:
                        rval = value.MaybeStrArray([])
                elif arg.A:
                    if old_val.tag_() != value_e.AssocArray:
                        rval = value.AssocArray({})

            rval = _ReconcileTypes(rval, arg.a, arg.A, pair.spid)
            self.mem.SetVar(lvalue.Named(pair.var_name),
                            rval,
                            lookup_mode,
                            flags=flags)

        return status
Ejemplo n.º 7
0
  def Run(self, cmd_val):
    # type: (cmd_value__Assign) -> int
    arg_r = args.Reader(cmd_val.argv, spids=cmd_val.arg_spids)
    arg_r.Next()
    attrs = flag_spec.Parse('new_var', arg_r)
    arg = arg_types.new_var(attrs.attrs)

    status = 0

    if arg.f:
      names = arg_r.Rest()
      if len(names):
        # This is only used for a STATUS QUERY now.  We only show the name,
        # not the body.
        status = self._PrintFuncs(names)
      else:
        # Disallow this since it would be incompatible.
        e_usage('with -f expects function names')
      return status

    if arg.F:
      names = arg_r.Rest()
      if len(names):
        status = self._PrintFuncs(names)
      else:
        # bash quirk: with no names, they're printed in a different format!
        for func_name in sorted(self.funcs):
          print('declare -f %s' % (func_name))
      return status

    if arg.p:  # Lookup and print variables.
      return _PrintVariables(self.mem, cmd_val, attrs, True)
    elif len(cmd_val.pairs) == 0:
      return _PrintVariables(self.mem, cmd_val, attrs, False)

    #
    # Set variables
    #

    #raise error.Usage("doesn't understand %s" % cmd_val.argv[1:])
    if cmd_val.builtin_id == builtin_i.local:
      which_scopes = scope_e.LocalOnly
    else:  # declare/typeset
      if arg.g:  
        which_scopes = scope_e.GlobalOnly
      else:
        which_scopes = scope_e.LocalOnly

    flags = 0
    if arg.x == '-': 
      flags |= state.SetExport
    if arg.r == '-':
      flags |= state.SetReadOnly
    if arg.n == '-':
      flags |= state.SetNameref

    flags_to_clear = 0
    if arg.x == '+': 
      flags |= state.ClearExport
    if arg.r == '+':
      flags |= state.ClearReadOnly
    if arg.n == '+':
      flags |= state.ClearNameref

    for pair in cmd_val.pairs:
      rval = pair.rval
      # declare -a foo=(a b); declare -a foo;  should not reset to empty array
      if rval is None and (arg.a or arg.A):
        old_val = self.mem.GetValue(pair.var_name)
        if arg.a:
          if old_val.tag_() != value_e.MaybeStrArray:
            rval = value.MaybeStrArray([])
        elif arg.A:
          if old_val.tag_() != value_e.AssocArray:
            rval = value.AssocArray({})

      rval = _ReconcileTypes(rval, arg.a, arg.A, pair.spid)
      self.mem.SetValue(lvalue.Named(pair.var_name), rval, which_scopes,
                        flags=flags)

    return status