56
56
ClearExport = 1 << 3
57
57
SetNameref = 1 << 4
58
58
ClearNameref = 1 << 5
59
+ YshDecl = 1 << 6
59
60
60
61
61
62
class ctx_Source (object ):
@@ -1217,8 +1218,8 @@ def _Pop(self):
1217
1218
self .mem .SetNamed (lval , old_val , scope_e .LocalOnly )
1218
1219
1219
1220
1220
- def _FrameLookup (frame , name ):
1221
- # type: (Dict[str, Cell], str) -> Tuple[Optional[Cell], Dict[str, Cell]]
1221
+ def _FrameLookup (frame , name , ysh_decl ):
1222
+ # type: (Dict[str, Cell], str, bool ) -> Tuple[Optional[Cell], Dict[str, Cell]]
1222
1223
"""
1223
1224
Look for a name in the frame, then recursively into the enclosing __E__
1224
1225
frame, if it exists
@@ -1227,13 +1228,14 @@ def _FrameLookup(frame, name):
1227
1228
if cell :
1228
1229
return cell , frame
1229
1230
1230
- rear_cell = frame .get ('__E__' ) # ctx_EnclosedFrame() sets this
1231
- if rear_cell :
1232
- rear_val = rear_cell .val
1233
- assert rear_val , rear_val
1234
- if rear_val .tag () == value_e .Frame :
1235
- to_enclose = cast (value .Frame , rear_val ).frame
1236
- return _FrameLookup (to_enclose , name ) # recursive call
1231
+ if not ysh_decl :
1232
+ rear_cell = frame .get ('__E__' ) # ctx_EnclosedFrame() sets this
1233
+ if rear_cell :
1234
+ rear_val = rear_cell .val
1235
+ assert rear_val , rear_val
1236
+ if rear_val .tag () == value_e .Frame :
1237
+ to_enclose = cast (value .Frame , rear_val ).frame
1238
+ return _FrameLookup (to_enclose , name , ysh_decl ) # recursive call
1237
1239
1238
1240
return None , None
1239
1241
@@ -1719,33 +1721,43 @@ def GetSpecialVar(self, op_id):
1719
1721
# Named Vars
1720
1722
#
1721
1723
1722
- def _ResolveNameOnly (self , name , which_scopes ):
1723
- # type: (str, scope_t) -> Tuple[Optional[Cell], Dict[str, Cell]]
1724
- """Helper for getting and setting variable.
1724
+ def _ResolveNameOnly (self , name , which_scopes , flags ):
1725
+ # type: (str, scope_t, int) -> Tuple[Optional[Cell], Dict[str, Cell]]
1726
+ """Given a variable name, and scope rule, return a Cell and Frame.
1727
+
1728
+ This function does not resolve 'nameref'. It's used to get and set
1729
+ variables.
1725
1730
1726
1731
Returns:
1727
- cell: The cell corresponding to looking up 'name' with the given mode , or
1732
+ cell: The cell corresponding to looking up 'name' with the given scope , or
1728
1733
None if it's not found.
1729
1734
var_frame: The frame it should be set to or deleted from.
1730
1735
"""
1731
1736
if which_scopes == scope_e .Dynamic :
1732
1737
for i in xrange (len (self .var_stack ) - 1 , - 1 , - 1 ):
1733
1738
var_frame = self .var_stack [i ]
1734
- cell , result_frame = _FrameLookup (var_frame , name )
1739
+ cell , result_frame = _FrameLookup (var_frame , name , bool ( flags & YshDecl ) )
1735
1740
if cell :
1736
1741
return cell , result_frame
1737
1742
return None , self .var_stack [0 ] # set in global var_frame
1738
1743
1739
1744
if which_scopes == scope_e .LocalOnly :
1745
+ # Stack:
1746
+ # CommandEvaluator::_DoVarDecl
1747
+ # Mem::SetNamed - do we need a flag for 'var'?
1748
+ # Mem::_ResolveNameOrRef
1749
+ # Mem::_ResolveNameOnly
1750
+ #raise AssertionError()
1751
+
1740
1752
var_frame = self .var_stack [- 1 ]
1741
- cell , result_frame = _FrameLookup (var_frame , name )
1753
+ cell , result_frame = _FrameLookup (var_frame , name , bool ( flags & YshDecl ) )
1742
1754
if cell :
1743
1755
return cell , result_frame
1744
1756
return None , var_frame
1745
1757
1746
1758
if which_scopes == scope_e .GlobalOnly :
1747
1759
var_frame = self .var_stack [0 ]
1748
- cell , result_frame = _FrameLookup (var_frame , name )
1760
+ cell , result_frame = _FrameLookup (var_frame , name , bool ( flags & YshDecl ) )
1749
1761
if cell :
1750
1762
return cell , result_frame
1751
1763
@@ -1754,13 +1766,13 @@ def _ResolveNameOnly(self, name, which_scopes):
1754
1766
if which_scopes == scope_e .LocalOrGlobal :
1755
1767
# Local
1756
1768
var_frame = self .var_stack [- 1 ]
1757
- cell , result_frame = _FrameLookup (var_frame , name )
1769
+ cell , result_frame = _FrameLookup (var_frame , name , bool ( flags & YshDecl ) )
1758
1770
if cell :
1759
1771
return cell , result_frame
1760
1772
1761
1773
# Global
1762
1774
var_frame = self .var_stack [0 ]
1763
- cell , result_frame = _FrameLookup (var_frame , name )
1775
+ cell , result_frame = _FrameLookup (var_frame , name , bool ( flags & YshDecl ) )
1764
1776
if cell :
1765
1777
return cell , result_frame
1766
1778
@@ -1772,14 +1784,15 @@ def _ResolveNameOrRef(
1772
1784
self ,
1773
1785
name , # type: str
1774
1786
which_scopes , # type: scope_t
1787
+ flags , # type: int
1775
1788
ref_trail = None , # type: Optional[List[str]]
1776
1789
):
1777
1790
# type: (...) -> Tuple[Optional[Cell], Dict[str, Cell], str]
1778
- """Look up a cell and namespace , but respect the nameref flag.
1791
+ """Look up a cell and frame , but respect the nameref flag.
1779
1792
1780
1793
Resolving namerefs does RECURSIVE calls.
1781
1794
"""
1782
- cell , var_frame = self ._ResolveNameOnly (name , which_scopes )
1795
+ cell , var_frame = self ._ResolveNameOnly (name , which_scopes , flags )
1783
1796
1784
1797
if cell is None or not cell .nameref :
1785
1798
return cell , var_frame , name # not a nameref
@@ -1827,7 +1840,7 @@ def _ResolveNameOrRef(
1827
1840
1828
1841
# 'declare -n' uses dynamic scope.
1829
1842
cell , var_frame , cell_name = self ._ResolveNameOrRef (
1830
- new_name , scope_e .Dynamic , ref_trail = ref_trail )
1843
+ new_name , scope_e .Dynamic , flags , ref_trail = ref_trail )
1831
1844
return cell , var_frame , cell_name
1832
1845
1833
1846
def IsBashAssoc (self , name ):
@@ -1837,7 +1850,7 @@ def IsBashAssoc(self, name):
1837
1850
We need to know this to evaluate the index expression properly
1838
1851
-- should it be coerced to an integer or not?
1839
1852
"""
1840
- cell , _ , _ = self ._ResolveNameOrRef (name , self .ScopesForReading ())
1853
+ cell , _ , _ = self ._ResolveNameOrRef (name , self .ScopesForReading (), 0 )
1841
1854
# foo=([key]=value)
1842
1855
return cell is not None and cell .val .tag () == value_e .BashAssoc
1843
1856
@@ -1890,6 +1903,8 @@ def SetLocalName(self, lval, val):
1890
1903
1891
1904
# Equivalent to
1892
1905
# self._ResolveNameOnly(lval.name, scope_e.LocalOnly)
1906
+
1907
+ # Note: doesn't use _FrameLookup
1893
1908
var_frame = self .var_stack [- 1 ]
1894
1909
cell = var_frame .get (lval .name )
1895
1910
@@ -1906,7 +1921,7 @@ def SetNamed(self, lval, val, which_scopes, flags=0):
1906
1921
# type: (LeftName, value_t, scope_t, int) -> None
1907
1922
if flags & SetNameref or flags & ClearNameref :
1908
1923
# declare -n ref=x # refers to the ref itself
1909
- cell , var_frame = self ._ResolveNameOnly (lval .name , which_scopes )
1924
+ cell , var_frame = self ._ResolveNameOnly (lval .name , which_scopes , flags )
1910
1925
cell_name = lval .name
1911
1926
else :
1912
1927
# ref=x # mutates THROUGH the reference
@@ -1918,7 +1933,7 @@ def SetNamed(self, lval, val, which_scopes, flags=0):
1918
1933
# 3. Turn BracedVarSub into an sh_lvalue, and call
1919
1934
# self.unsafe_arith.SetValue() wrapper with ref_trail
1920
1935
cell , var_frame , cell_name = self ._ResolveNameOrRef (
1921
- lval .name , which_scopes )
1936
+ lval .name , which_scopes , flags )
1922
1937
1923
1938
if cell :
1924
1939
# Clear before checking readonly bit.
@@ -2021,7 +2036,7 @@ def SetValue(self, lval, val, which_scopes, flags=0):
2021
2036
# Undef, which then turns into an INDEXED array. (Undef means that set
2022
2037
# -o nounset fails.)
2023
2038
cell , var_frame , _ = self ._ResolveNameOrRef (
2024
- lval .name , which_scopes )
2039
+ lval .name , which_scopes , flags )
2025
2040
if not cell :
2026
2041
self ._BindNewArrayWithEntry (var_frame , lval , rval , flags ,
2027
2042
left_loc )
@@ -2083,7 +2098,7 @@ def SetValue(self, lval, val, which_scopes, flags=0):
2083
2098
left_loc = lval .blame_loc
2084
2099
2085
2100
cell , var_frame , _ = self ._ResolveNameOrRef (
2086
- lval .name , which_scopes )
2101
+ lval .name , which_scopes , flags )
2087
2102
if cell .readonly :
2088
2103
e_die ("Can't assign to readonly associative array" ,
2089
2104
left_loc )
@@ -2295,7 +2310,7 @@ def GetValue(self, name, which_scopes=scope_e.Shopt):
2295
2310
# 1. Call self.unsafe_arith.ParseVarRef() -> BracedVarSub
2296
2311
# 2. Call self.unsafe_arith.GetNameref(bvs_part), and get a value_t
2297
2312
# We still need a ref_trail to detect cycles.
2298
- cell , _ , _ = self ._ResolveNameOrRef (name , which_scopes )
2313
+ cell , _ , _ = self ._ResolveNameOrRef (name , which_scopes , 0 )
2299
2314
if cell :
2300
2315
return cell .val
2301
2316
@@ -2321,7 +2336,7 @@ def GetCell(self, name, which_scopes=scope_e.Shopt):
2321
2336
if which_scopes == scope_e .Shopt :
2322
2337
which_scopes = self .ScopesForReading ()
2323
2338
2324
- cell , _ = self ._ResolveNameOnly (name , which_scopes )
2339
+ cell , _ = self ._ResolveNameOnly (name , which_scopes , 0 )
2325
2340
return cell
2326
2341
2327
2342
def GetCellDeref (self , name , which_scopes = scope_e .Shopt ):
@@ -2332,7 +2347,7 @@ def GetCellDeref(self, name, which_scopes=scope_e.Shopt):
2332
2347
if which_scopes == scope_e .Shopt :
2333
2348
which_scopes = self .ScopesForReading ()
2334
2349
2335
- cell , _ , _ = self ._ResolveNameOrRef (name , which_scopes )
2350
+ cell , _ , _ = self ._ResolveNameOrRef (name , which_scopes , 0 )
2336
2351
return cell
2337
2352
2338
2353
def Unset (self , lval , which_scopes ):
@@ -2361,7 +2376,7 @@ def Unset(self, lval, which_scopes):
2361
2376
which_scopes = self .ScopesForWriting ()
2362
2377
2363
2378
cell , var_frame , cell_name = self ._ResolveNameOrRef (
2364
- var_name , which_scopes )
2379
+ var_name , which_scopes , 0 )
2365
2380
if not cell :
2366
2381
return False # 'unset' builtin falls back on functions
2367
2382
if cell .readonly :
@@ -2445,7 +2460,7 @@ def ClearFlag(self, name, flag):
2445
2460
We don't use SetValue() because even if rval is None, it will make an
2446
2461
Undef value in a scope.
2447
2462
"""
2448
- cell , var_frame = self ._ResolveNameOnly (name , self .ScopesForReading ())
2463
+ cell , var_frame = self ._ResolveNameOnly (name , self .ScopesForReading (), 0 )
2449
2464
if cell :
2450
2465
if flag & ClearExport :
2451
2466
cell .exported = False
0 commit comments