| 1 | 
  
    ## compare_shells: bash
   | 
  | 2 | 
  
    
   | 
  | 3 | 
  
    
   | 
  | 4 | 
  
    #
   | 
  | 5 | 
  
    # This idiom discussed on
   | 
  | 6 | 
  
    # https://github.com/NixOS/nixpkgs/pull/147629
   | 
  | 7 | 
  
    
   | 
  | 8 | 
  
    show() {
   | 
  | 9 | 
  
      echo show
   | 
  | 10 | 
  
    
   | 
  | 11 | 
  
      # These are actually different
   | 
  | 12 | 
  
      argv.py ${!hooksSlice}
   | 
  | 13 | 
  
    
   | 
  | 14 | 
  
      argv.py ${!hooksSlice+"${!hooksSlice}"}
   | 
  | 15 | 
  
    }
   | 
  | 16 | 
  
    
   | 
  | 17 | 
  
    hooksSlice='preHooks[@]'
   | 
  | 18 | 
  
    
   | 
  | 19 | 
  
    preHooks=()
   | 
  | 20 | 
  
    show
   | 
  | 21 | 
  
    
   | 
  | 22 | 
  
    preHooks=('foo bar' baz)
   | 
  | 23 | 
  
    show
   | 
  | 24 | 
  
    
   | 
  | 25 | 
  
    # WTF this exposes a difference?  But not the test case below?
   | 
  | 26 | 
  
    
   | 
  | 27 | 
  
    # What's happening here?
   | 
  | 28 | 
  
    # Uncomment this and get an error in bash about hookSlice, even though we never
   | 
  | 29 | 
  
    # undefined it.
   | 
  | 30 | 
  
    
   | 
  | 31 | 
  
    #wtf=1
   | 
  | 32 | 
  
    #
   | 
  | 33 | 
  
    # line 6: !hooksSlice: unbound variable
   | 
  | 34 | 
  
    
   | 
  | 35 | 
  
    if test -n "$wtf"; then
   | 
  | 36 | 
  
      # 4.4.0(1)-release
   | 
  | 37 | 
  
      # echo $BASH_VERSION
   | 
  | 38 | 
  
    
   | 
  | 39 | 
  
      set -u
   | 
  | 40 | 
  
      preHooks=()
   | 
  | 41 | 
  
      show
   | 
  | 42 | 
  
    
   | 
  | 43 | 
  
      preHooks=('foo bar' baz)
   | 
  | 44 | 
  
      show
   | 
  | 45 | 
  
    fi
   | 
  | 46 | 
  
    
   | 
  | 47 | 
  
    ## STDOUT:
   | 
  | 48 | 
  
    show
   | 
  | 49 | 
  
    []
   | 
  | 50 | 
  
    []
   | 
  | 51 | 
  
    show
   | 
  | 52 | 
  
    ['foo', 'bar', 'baz']
   | 
  | 53 | 
  
    ['foo bar', 'baz']
   | 
  | 54 | 
  
    ## END
   | 
  | 55 | 
  
    
   | 
  | 56 | 
  
    
   | 
  | 57 | 
  
    show() {
   | 
  | 58 | 
  
      echo show
   | 
  | 59 | 
  
    
   | 
  | 60 | 
  
      # bash gives an error here - !hookSlice unbound, even though preHooks exists
   | 
  | 61 | 
  
      # OSH currently does the "logical" thing
   | 
  | 62 | 
  
    
   | 
  | 63 | 
  
      # NOT testing this -- I think this is WHAT NIX WORKS AROUND WITH
   | 
  | 64 | 
  
      #argv.py ${!hooksSlice}
   | 
  | 65 | 
  
    
   | 
  | 66 | 
  
      argv.py ${!hooksSlice+"${!hooksSlice}"}
   | 
  | 67 | 
  
    }
   | 
  | 68 | 
  
    
   | 
  | 69 | 
  
    hooksSlice='preHooks[@]'
   | 
  | 70 | 
  
    
   | 
  | 71 | 
  
    set -u
   | 
  | 72 | 
  
    preHooks=()
   | 
  | 73 | 
  
    show
   | 
  | 74 | 
  
    
   | 
  | 75 | 
  
    preHooks=('foo bar' baz)
   | 
  | 76 | 
  
    show
   | 
  | 77 | 
  
    
   | 
  | 78 | 
  
    ## STDOUT:
   | 
  | 79 | 
  
    show
   | 
  | 80 | 
  
    []
   | 
  | 81 | 
  
    show
   | 
  | 82 | 
  
    ['foo bar', 'baz']
   | 
  | 83 | 
  
    ## END
   | 
  | 84 | 
  
    
   | 
  | 85 | 
  
    
   | 
  | 86 | 
  
    
   | 
  | 87 | 
  
    set -u
   | 
  | 88 | 
  
    shopt -s eval_unsafe_arith || true 2>/dev/null
   | 
  | 89 | 
  
    
   | 
  | 90 | 
  
    #preHooks=()
   | 
  | 91 | 
  
    hookSlice="preHooks[@]"
   | 
  | 92 | 
  
    
   | 
  | 93 | 
  
    argv.py ${!hookSlice+"${!hookSlice}"}
   | 
  | 94 | 
  
    
   | 
  | 95 | 
  
    for element in ${!hookSlice+"${!hookSlice}"}; do
   | 
  | 96 | 
  
      echo $element
   | 
  | 97 | 
  
    done
   | 
  | 98 | 
  
    
   | 
  | 99 | 
  
    ## STDOUT:
   | 
  | 100 | 
  
    []
   | 
  | 101 | 
  
    ## END
   | 
  | 102 | 
  
    
   | 
  | 103 | 
  
    
   | 
  | 104 | 
  
    hookSlice='preHooks'
   | 
  | 105 | 
  
    
   | 
  | 106 | 
  
    argv.py ${!hookSlice}
   | 
  | 107 | 
  
    
   | 
  | 108 | 
  
    set -u
   | 
  | 109 | 
  
    
   | 
  | 110 | 
  
    argv.py ${!hookSlice}
   | 
  | 111 | 
  
    
   | 
  | 112 | 
  
    echo end
   | 
  | 113 | 
  
    
   | 
  | 114 | 
  
    ## status: 1
   | 
  | 115 | 
  
    ## STDOUT:
   | 
  | 116 | 
  
    []
   | 
  | 117 | 
  
    ## END
   | 
  | 118 | 
  
    
   | 
  | 119 | 
  
    
   | 
  | 120 | 
  
    
   | 
  | 121 | 
  
    orig() {
   | 
  | 122 | 
  
      export NIX_LDFLAGS${role_post}+=" -L$1/lib64"
   | 
  | 123 | 
  
    }
   | 
  | 124 | 
  
    
   | 
  | 125 | 
  
    new() {
   | 
  | 126 | 
  
      local var_name="NIX_LDFLAGS$role_post"
   | 
  | 127 | 
  
      local value=" -L$1/lib64"
   | 
  | 128 | 
  
    
   | 
  | 129 | 
  
      eval "$var_name"+='$value'
   | 
  | 130 | 
  
      export "$var_name"
   | 
  | 131 | 
  
    }
   | 
  | 132 | 
  
    
   | 
  | 133 | 
  
    role_post='_foo'
   | 
  | 134 | 
  
    
   | 
  | 135 | 
  
    # set -u
   | 
  | 136 | 
  
    
   | 
  | 137 | 
  
    if test -n "${BASH_VERSION:-}"; then
   | 
  | 138 | 
  
      orig one
   | 
  | 139 | 
  
    fi
   | 
  | 140 | 
  
    
   | 
  | 141 | 
  
    declare -p NIX_LDFLAGS_foo  # inspect it
   | 
  | 142 | 
  
    unset NIX_LDFLAGS_foo
   | 
  | 143 | 
  
    
   | 
  | 144 | 
  
    new one
   | 
  | 145 | 
  
    
   | 
  | 146 | 
  
    declare -p NIX_LDFLAGS_foo  # inspect it
   | 
  | 147 | 
  
    
   | 
  | 148 | 
  
    ## STDOUT:
   | 
  | 149 | 
  
    declare -x NIX_LDFLAGS_foo=" -Lone/lib64"
   | 
  | 150 | 
  
    declare -x NIX_LDFLAGS_foo=" -Lone/lib64"
   | 
  | 151 | 
  
    ## END
   | 
  | 152 | 
  
    ## OK osh STDOUT:
   | 
  | 153 | 
  
    declare -x NIX_LDFLAGS_foo=' -Lone/lib64'
   | 
  | 154 | 
  
    ## END
   | 
  | 155 | 
  
    
   | 
  | 156 | 
  
    
   | 
  | 157 | 
  
    
   | 
  | 158 | 
  
    for i in 0 1 2; do
   | 
  | 159 | 
  
      echo i=$i
   | 
  | 160 | 
  
    
   | 
  | 161 | 
  
      NIX_ENFORCE_NO_NATIVE=$i
   | 
  | 162 | 
  
    
   | 
  | 163 | 
  
      outputVar=NIX_ENFORCE_NO_NATIVE_x86_64_unknown_linux_gnu
   | 
  | 164 | 
  
      inputVar=NIX_ENFORCE_NO_NATIVE
   | 
  | 165 | 
  
    
   | 
  | 166 | 
  
      # Original Nix idiom
   | 
  | 167 | 
  
    
   | 
  | 168 | 
  
      if test -n "$BASH_VERSION"; then
   | 
  | 169 | 
  
        let "${outputVar} |= ${!inputVar:-0}" "1"
   | 
  | 170 | 
  
      else
   | 
  | 171 | 
  
        # OSH alternative
   | 
  | 172 | 
  
        eval ": \$(( ${outputVar} |= ${!inputVar:-0} ))"
   | 
  | 173 | 
  
      fi
   | 
  | 174 | 
  
    
   | 
  | 175 | 
  
      echo NIX_ENFORCE_NO_NATIVE=$NIX_ENFORCE_NO_NATIVE
   | 
  | 176 | 
  
      echo NIX_ENFORCE_NO_NATIVE_x86_64_unknown_linux_gnu=$NIX_ENFORCE_NO_NATIVE_x86_64_unknown_linux_gnu
   | 
  | 177 | 
  
      echo
   | 
  | 178 | 
  
    
   | 
  | 179 | 
  
    done
   | 
  | 180 | 
  
    
   | 
  | 181 | 
  
    
   | 
  | 182 | 
  
    ## STDOUT:
   | 
  | 183 | 
  
    i=0
   | 
  | 184 | 
  
    NIX_ENFORCE_NO_NATIVE=0
   | 
  | 185 | 
  
    NIX_ENFORCE_NO_NATIVE_x86_64_unknown_linux_gnu=0
   | 
  | 186 | 
  
    
   | 
  | 187 | 
  
    i=1
   | 
  | 188 | 
  
    NIX_ENFORCE_NO_NATIVE=1
   | 
  | 189 | 
  
    NIX_ENFORCE_NO_NATIVE_x86_64_unknown_linux_gnu=1
   | 
  | 190 | 
  
    
   | 
  | 191 | 
  
    i=2
   | 
  | 192 | 
  
    NIX_ENFORCE_NO_NATIVE=2
   | 
  | 193 | 
  
    NIX_ENFORCE_NO_NATIVE_x86_64_unknown_linux_gnu=3
   | 
  | 194 | 
  
    
   | 
  | 195 | 
  
    ## END
   | 
  | 196 | 
  
    
   |