| 1 | module pref |
| 2 | |
| 3 | import os |
| 4 | |
| 5 | fn test_source_files_from_args_skips_os_option_value() { |
| 6 | files := source_files_from_args(['-b', 'x64', '-os', 'windows', '-o', 'app', 'main.v']) |
| 7 | assert files == ['main.v'] |
| 8 | } |
| 9 | |
| 10 | fn test_source_files_from_args_skips_fhooks_option_value() { |
| 11 | files := source_files_from_args(['-freestanding', '-fhooks', 'output,panic', '-o', 'app', |
| 12 | 'main.v']) |
| 13 | assert files == ['main.v'] |
| 14 | } |
| 15 | |
| 16 | fn test_new_preferences_from_args_defaults_to_host_target() { |
| 17 | prefs := new_preferences_from_args(['main.v']) |
| 18 | assert prefs.target_os == normalize_target_os_name(os.user_os()) |
| 19 | assert prefs.normalized_target_os() == normalize_target_os_name(os.user_os()) |
| 20 | assert !prefs.is_cross_target() |
| 21 | assert !prefs.is_freestanding() |
| 22 | assert 'cross' !in prefs.user_defines |
| 23 | assert 'freestanding' !in prefs.user_defines |
| 24 | assert prefs.explicit_user_defines.len == 0 |
| 25 | } |
| 26 | |
| 27 | fn test_new_preferences_from_args_parses_macos_tiny_opt_out() { |
| 28 | default_prefs := new_preferences_from_args(['-b', 'x64', '-os', 'macos', 'main.v']) |
| 29 | assert default_prefs.macos_tiny |
| 30 | |
| 31 | opt_out_prefs := |
| 32 | new_preferences_from_args(['-b', 'x64', '-no-mos-tiny', '-os', 'macos', 'main.v']) |
| 33 | assert !opt_out_prefs.macos_tiny |
| 34 | } |
| 35 | |
| 36 | fn test_macos_tiny_opt_out_requires_macos_target() { |
| 37 | validate_macos_tiny_flag_contract(['-no-mos-tiny'], 'macos')! |
| 38 | |
| 39 | for target in ['linux', 'windows', 'cross', 'none'] { |
| 40 | mut got_error := false |
| 41 | validate_macos_tiny_flag_contract(['-no-mos-tiny'], target) or { |
| 42 | got_error = true |
| 43 | assert err.msg().contains('-no-mos-tiny requires a macOS target') |
| 44 | } |
| 45 | assert got_error, '-no-mos-tiny was accepted for target ${target}' |
| 46 | } |
| 47 | } |
| 48 | |
| 49 | fn test_macos_tiny_opt_out_rejection_has_cli_error_prefix() { |
| 50 | tmp_dir := os.join_path(os.vtmp_dir(), 'v2_pref_macos_tiny_error_${os.getpid()}') |
| 51 | os.rmdir_all(tmp_dir) or {} |
| 52 | os.mkdir_all(tmp_dir) or { panic(err) } |
| 53 | defer { |
| 54 | os.rmdir_all(tmp_dir) or {} |
| 55 | } |
| 56 | source_path := os.join_path(tmp_dir, 'main.v') |
| 57 | os.write_file(source_path, |
| 58 | "import v2.pref\n\nfn main() {\n\tpref.new_preferences_from_args(['-no-mos-tiny', '-os', 'linux', 'main.v'])\n}\n") or { |
| 59 | panic(err) |
| 60 | } |
| 61 | vlib_path := os.join_path(os.dir(@VEXE), 'vlib') |
| 62 | res := |
| 63 | os.execute('${os.quoted_path(@VEXE)} -path "${vlib_path}|@vlib|@vmodules" run ${os.quoted_path(source_path)}') |
| 64 | assert res.exit_code == 1, res.output |
| 65 | assert res.output.contains('error: -no-mos-tiny requires a macOS target'), res.output |
| 66 | } |
| 67 | |
| 68 | fn test_new_preferences_from_args_parses_target_os() { |
| 69 | linux_prefs := new_preferences_from_args(['-os', 'linux', 'main.v']) |
| 70 | assert linux_prefs.target_os == 'linux' |
| 71 | assert linux_prefs.normalized_target_os() == 'linux' |
| 72 | assert !linux_prefs.is_cross_target() |
| 73 | |
| 74 | windows_prefs := new_preferences_from_args(['-os', 'windows', 'main.v']) |
| 75 | assert windows_prefs.target_os == 'windows' |
| 76 | assert windows_prefs.normalized_target_os() == 'windows' |
| 77 | |
| 78 | termux_prefs := new_preferences_from_args(['-os', 'termux', 'main.v']) |
| 79 | assert termux_prefs.target_os == 'termux' |
| 80 | assert termux_prefs.normalized_target_os() == 'termux' |
| 81 | assert comptime_flag_value(&termux_prefs, 'termux') |
| 82 | } |
| 83 | |
| 84 | fn test_new_preferences_from_args_normalizes_macos_target_aliases() { |
| 85 | macos_prefs := new_preferences_from_args(['-os', 'macos', 'main.v']) |
| 86 | assert macos_prefs.target_os == 'macos' |
| 87 | assert macos_prefs.normalized_target_os() == 'macos' |
| 88 | |
| 89 | darwin_prefs := new_preferences_from_args(['-os', 'darwin', 'main.v']) |
| 90 | assert darwin_prefs.target_os == 'macos' |
| 91 | assert darwin_prefs.normalized_target_os() == 'macos' |
| 92 | |
| 93 | mac_prefs := new_preferences_from_args(['-os', 'mac', 'main.v']) |
| 94 | assert mac_prefs.target_os == 'macos' |
| 95 | assert mac_prefs.normalized_target_os() == 'macos' |
| 96 | } |
| 97 | |
| 98 | fn test_new_preferences_from_args_cross_is_not_concrete_os() { |
| 99 | prefs := new_preferences_from_args(['-os', 'cross', 'main.v']) |
| 100 | assert prefs.target_os == 'cross' |
| 101 | assert prefs.normalized_target_os() == 'cross' |
| 102 | assert prefs.is_cross_target() |
| 103 | assert 'cross' in prefs.user_defines |
| 104 | assert 'cross' !in prefs.explicit_user_defines |
| 105 | assert comptime_flag_value(&prefs, 'cross') |
| 106 | assert !comptime_optional_flag_value(&prefs, 'cross') |
| 107 | assert !comptime_flag_value(&prefs, 'linux') |
| 108 | assert !comptime_flag_value(&prefs, 'macos') |
| 109 | assert !comptime_flag_value(&prefs, 'darwin') |
| 110 | assert !comptime_flag_value(&prefs, 'windows') |
| 111 | } |
| 112 | |
| 113 | fn test_new_preferences_from_args_freestanding_is_distinct_from_cross() { |
| 114 | prefs := new_preferences_from_args(['-freestanding', '-os', 'linux', 'main.v']) |
| 115 | assert prefs.is_freestanding() |
| 116 | assert !prefs.is_cross_target() |
| 117 | assert prefs.normalized_target_os() == 'linux' |
| 118 | assert comptime_flag_value(&prefs, 'freestanding') |
| 119 | assert comptime_flag_value(&prefs, 'linux') |
| 120 | assert !comptime_flag_value(&prefs, 'cross') |
| 121 | assert 'freestanding' in prefs.user_defines |
| 122 | assert 'freestanding' !in prefs.explicit_user_defines |
| 123 | assert !comptime_optional_flag_value(&prefs, 'freestanding') |
| 124 | } |
| 125 | |
| 126 | fn test_new_preferences_from_args_accepts_freestanding_none_target() { |
| 127 | prefs := new_preferences_from_args(['-freestanding', '-os', 'none', 'main.v']) |
| 128 | assert prefs.is_freestanding() |
| 129 | assert !prefs.is_cross_target() |
| 130 | assert prefs.target_os == 'none' |
| 131 | assert prefs.normalized_target_os() == 'none' |
| 132 | assert prefs.source_filter_target_os() == 'none' |
| 133 | assert !prefs.can_compile_cleanc_locally() |
| 134 | assert comptime_flag_value(&prefs, 'freestanding') |
| 135 | assert comptime_flag_value(&prefs, 'none') |
| 136 | assert !comptime_optional_flag_value(&prefs, 'none') |
| 137 | assert !comptime_flag_value(&prefs, 'cross') |
| 138 | assert !comptime_flag_value(&prefs, 'linux') |
| 139 | assert !comptime_flag_value(&prefs, 'macos') |
| 140 | assert !comptime_flag_value(&prefs, 'windows') |
| 141 | } |
| 142 | |
| 143 | fn test_can_compile_cleanc_locally_follows_target_contract() { |
| 144 | host := normalize_target_os_name(os.user_os()) |
| 145 | host_prefs := new_preferences_from_args(['-os', host, 'main.v']) |
| 146 | assert host_prefs.can_compile_cleanc_locally() |
| 147 | |
| 148 | cross_prefs := new_preferences_from_args(['-os', 'cross', 'main.v']) |
| 149 | assert cross_prefs.can_compile_cleanc_locally() |
| 150 | assert cross_prefs.source_filter_target_os() == host |
| 151 | |
| 152 | freestanding_prefs := new_preferences_from_args(['-freestanding', '-os', host, 'main.v']) |
| 153 | assert !freestanding_prefs.can_compile_cleanc_locally() |
| 154 | assert freestanding_prefs.source_filter_target_os() == host |
| 155 | |
| 156 | non_host := if host == 'windows' { 'linux' } else { 'windows' } |
| 157 | non_host_prefs := new_preferences_from_args(['-os', non_host, 'main.v']) |
| 158 | assert !non_host_prefs.can_compile_cleanc_locally() |
| 159 | assert non_host_prefs.source_filter_target_os() == non_host |
| 160 | } |
| 161 | |
| 162 | fn test_can_run_target_binary_locally_follows_effective_target() { |
| 163 | host := normalize_target_os_name(os.user_os()) |
| 164 | host_prefs := new_preferences_from_args(['-os', host, 'main.v']) |
| 165 | assert host_prefs.can_run_target_binary_locally() |
| 166 | |
| 167 | cross_prefs := new_preferences_from_args(['-os', 'cross', 'main.v']) |
| 168 | assert cross_prefs.can_run_target_binary_locally() |
| 169 | |
| 170 | native_cross_prefs := new_preferences_from_args(['-b', 'x64', '-os', 'cross', 'main.v']) |
| 171 | assert native_cross_prefs.backend == .x64 |
| 172 | assert !native_cross_prefs.can_run_target_binary_locally() |
| 173 | |
| 174 | freestanding_prefs := new_preferences_from_args(['-freestanding', '-os', host, 'main.v']) |
| 175 | assert !freestanding_prefs.can_run_target_binary_locally() |
| 176 | |
| 177 | mut native_freestanding_prefs := new_preferences_from_args(['-b', 'x64', '-freestanding', '-os', |
| 178 | host, 'main.v']) |
| 179 | native_freestanding_prefs.backend = .x64 |
| 180 | assert !native_freestanding_prefs.can_run_target_binary_locally() |
| 181 | |
| 182 | non_host := if host == 'windows' { 'linux' } else { 'windows' } |
| 183 | non_host_prefs := new_preferences_from_args(['-os', non_host, 'main.v']) |
| 184 | assert !non_host_prefs.can_run_target_binary_locally() |
| 185 | |
| 186 | mut native_non_host_prefs := new_preferences_from_args(['-b', 'x64', '-os', non_host, 'main.v']) |
| 187 | native_non_host_prefs.backend = .x64 |
| 188 | assert !native_non_host_prefs.can_run_target_binary_locally() |
| 189 | } |
| 190 | |
| 191 | fn test_new_preferences_from_args_parses_freestanding_hooks() { |
| 192 | prefs := new_preferences_from_args(['-freestanding', '-fhooks', 'output,panic', '-os', 'linux', |
| 193 | 'main.v']) |
| 194 | assert prefs.is_freestanding() |
| 195 | assert !prefs.skip_builtin |
| 196 | assert prefs.freestanding_hook_list() == ['output', 'panic'] |
| 197 | assert prefs.has_freestanding_hooks() |
| 198 | assert prefs.has_freestanding_hook('output') |
| 199 | assert prefs.has_freestanding_hook('panic') |
| 200 | assert !prefs.has_freestanding_hook('alloc') |
| 201 | assert 'freestanding_hooks' in prefs.user_defines |
| 202 | assert 'freestanding_output' in prefs.user_defines |
| 203 | assert 'freestanding_hooks_output' in prefs.user_defines |
| 204 | assert 'freestanding_panic' in prefs.user_defines |
| 205 | assert 'freestanding_hooks_panic' in prefs.user_defines |
| 206 | assert 'freestanding_alloc' !in prefs.user_defines |
| 207 | assert 'freestanding_hooks_alloc' !in prefs.user_defines |
| 208 | assert prefs.explicit_user_defines.len == 0 |
| 209 | assert comptime_flag_value(&prefs, 'freestanding_hooks') |
| 210 | assert comptime_flag_value(&prefs, 'freestanding_output') |
| 211 | assert comptime_flag_value(&prefs, 'freestanding_panic') |
| 212 | assert !comptime_flag_value(&prefs, 'freestanding_alloc') |
| 213 | } |
| 214 | |
| 215 | fn test_new_preferences_from_args_uses_implicit_skip_builtin_only_without_freestanding_hooks() { |
| 216 | prefs := new_preferences_from_args(['-freestanding', '-os', 'linux', 'main.v']) |
| 217 | assert prefs.is_freestanding() |
| 218 | assert prefs.skip_builtin |
| 219 | assert !prefs.has_freestanding_hooks() |
| 220 | |
| 221 | hook_prefs := new_preferences_from_args(['-freestanding', '-fhooks', 'output', '-os', 'linux', |
| 222 | 'main.v']) |
| 223 | assert hook_prefs.is_freestanding() |
| 224 | assert hook_prefs.has_freestanding_hook('output') |
| 225 | assert !hook_prefs.skip_builtin |
| 226 | |
| 227 | explicit_hook_prefs := new_preferences_from_args(['-freestanding', '-fhooks', 'output', |
| 228 | '--skip-builtin', '-os', 'linux', 'main.v']) |
| 229 | assert explicit_hook_prefs.has_freestanding_hook('output') |
| 230 | assert explicit_hook_prefs.skip_builtin |
| 231 | } |
| 232 | |
| 233 | fn test_freestanding_hook_defines_do_not_grant_hook_capabilities() { |
| 234 | prefs := new_preferences_from_args(['-freestanding', '-d', 'freestanding_output', '-d', |
| 235 | 'freestanding_panic', '-d', 'freestanding_alloc', 'main.v']) |
| 236 | assert prefs.is_freestanding() |
| 237 | assert !prefs.has_freestanding_hooks() |
| 238 | assert !prefs.has_freestanding_hook('output') |
| 239 | assert !prefs.has_freestanding_hook('panic') |
| 240 | assert !prefs.has_freestanding_hook('alloc') |
| 241 | assert 'freestanding_output' in prefs.user_defines |
| 242 | assert 'freestanding_panic' in prefs.user_defines |
| 243 | assert 'freestanding_alloc' in prefs.user_defines |
| 244 | assert prefs.explicit_user_defines == ['freestanding_output', 'freestanding_panic', |
| 245 | 'freestanding_alloc'] |
| 246 | assert comptime_flag_value(&prefs, 'freestanding_output') |
| 247 | assert comptime_flag_value(&prefs, 'freestanding_panic') |
| 248 | assert comptime_flag_value(&prefs, 'freestanding_alloc') |
| 249 | } |
| 250 | |
| 251 | fn test_new_preferences_from_args_expands_minimal_freestanding_hooks() { |
| 252 | prefs := new_preferences_from_args(['-freestanding', '-fhooks', 'minimal', 'main.v']) |
| 253 | assert prefs.freestanding_hook_list() == ['output', 'panic', 'alloc'] |
| 254 | assert prefs.has_freestanding_hook('output') |
| 255 | assert prefs.has_freestanding_hook('panic') |
| 256 | assert prefs.has_freestanding_hook('alloc') |
| 257 | assert comptime_flag_value(&prefs, 'freestanding_output') |
| 258 | assert comptime_flag_value(&prefs, 'freestanding_panic') |
| 259 | assert comptime_flag_value(&prefs, 'freestanding_alloc') |
| 260 | } |
| 261 | |
| 262 | fn test_new_preferences_using_options_accepts_target_os_and_freestanding() { |
| 263 | prefs := new_preferences_using_options(['--cleanc', '--os-windows', '--freestanding']) |
| 264 | assert prefs.backend == .cleanc |
| 265 | assert prefs.target_os == 'windows' |
| 266 | assert prefs.normalized_target_os() == 'windows' |
| 267 | assert !prefs.is_cross_target() |
| 268 | assert prefs.is_freestanding() |
| 269 | assert comptime_flag_value(&prefs, 'windows') |
| 270 | assert comptime_flag_value(&prefs, 'freestanding') |
| 271 | assert 'freestanding' in prefs.user_defines |
| 272 | assert 'freestanding' !in prefs.explicit_user_defines |
| 273 | |
| 274 | termux_prefs := new_preferences_using_options(['--cleanc', '--os-termux']) |
| 275 | assert termux_prefs.backend == .cleanc |
| 276 | assert termux_prefs.target_os == 'termux' |
| 277 | assert termux_prefs.normalized_target_os() == 'termux' |
| 278 | assert comptime_flag_value(&termux_prefs, 'termux') |
| 279 | assert !comptime_flag_value(&termux_prefs, 'android') |
| 280 | } |
| 281 | |
| 282 | fn test_new_preferences_using_options_accepts_freestanding_hooks() { |
| 283 | prefs := new_preferences_using_options(['--cleanc', '--os-linux', '--freestanding', |
| 284 | '--fhooks-output,alloc']) |
| 285 | assert prefs.is_freestanding() |
| 286 | assert prefs.freestanding_hook_list() == ['output', 'alloc'] |
| 287 | assert prefs.has_freestanding_hook('output') |
| 288 | assert prefs.has_freestanding_hook('alloc') |
| 289 | assert !prefs.has_freestanding_hook('panic') |
| 290 | assert comptime_flag_value(&prefs, 'freestanding_output') |
| 291 | assert comptime_flag_value(&prefs, 'freestanding_alloc') |
| 292 | assert !comptime_flag_value(&prefs, 'freestanding_panic') |
| 293 | } |
| 294 | |
| 295 | fn test_new_preferences_using_options_accepts_freestanding_none_target() { |
| 296 | prefs := new_preferences_using_options(['--cleanc', '--freestanding', '--os-none']) |
| 297 | assert prefs.is_freestanding() |
| 298 | assert !prefs.is_cross_target() |
| 299 | assert prefs.target_os == 'none' |
| 300 | assert prefs.source_filter_target_os() == 'none' |
| 301 | assert !prefs.can_compile_cleanc_locally() |
| 302 | } |
| 303 | |
| 304 | fn test_new_preferences_using_options_accepts_cross_target() { |
| 305 | prefs := new_preferences_using_options(['--cleanc', '--os-cross']) |
| 306 | assert prefs.target_os == 'cross' |
| 307 | assert prefs.is_cross_target() |
| 308 | assert 'cross' in prefs.user_defines |
| 309 | assert 'cross' !in prefs.explicit_user_defines |
| 310 | assert comptime_flag_value(&prefs, 'cross') |
| 311 | assert !comptime_optional_flag_value(&prefs, 'cross') |
| 312 | assert !comptime_flag_value(&prefs, 'linux') |
| 313 | assert !comptime_flag_value(&prefs, 'macos') |
| 314 | assert !comptime_flag_value(&prefs, 'windows') |
| 315 | } |
| 316 | |
| 317 | fn test_new_preferences_from_args_accepted_targets_match_comptime_flags() { |
| 318 | for target in ['linux', 'macos', 'darwin', 'mac', 'windows', 'freebsd', 'openbsd', 'netbsd', |
| 319 | 'dragonfly', 'android', 'termux', 'ios', 'solaris', 'qnx', 'serenity', 'plan9', 'vinix'] { |
| 320 | prefs := new_preferences_from_args(['-os', target, 'main.v']) |
| 321 | flag_name := match target { |
| 322 | 'darwin', 'mac' { 'macos' } |
| 323 | else { prefs.normalized_target_os() } |
| 324 | } |
| 325 | |
| 326 | assert comptime_flag_value(&prefs, flag_name), '${target} should match ${flag_name}' |
| 327 | } |
| 328 | } |
| 329 | |
| 330 | fn test_cross_and_freestanding_still_allow_user_defines() { |
| 331 | mut prefs := new_preferences() |
| 332 | prefs.user_defines = ['cross', 'freestanding'] |
| 333 | prefs.explicit_user_defines = ['cross', 'freestanding'] |
| 334 | assert comptime_flag_value(&prefs, 'cross') |
| 335 | assert comptime_flag_value(&prefs, 'freestanding') |
| 336 | assert comptime_optional_flag_value(&prefs, 'cross') |
| 337 | assert comptime_optional_flag_value(&prefs, 'freestanding') |
| 338 | } |
| 339 | |
| 340 | fn test_explicit_user_defines_are_separate_from_synthesized_defines() { |
| 341 | cross_prefs := new_preferences_from_args(['-os', 'cross', '-d', 'cross', 'main.v']) |
| 342 | assert 'cross' in cross_prefs.user_defines |
| 343 | assert 'cross' in cross_prefs.explicit_user_defines |
| 344 | assert comptime_optional_flag_value(&cross_prefs, 'cross') |
| 345 | |
| 346 | free_prefs := new_preferences_from_args(['-freestanding', '-d', 'freestanding', 'main.v']) |
| 347 | assert 'freestanding' in free_prefs.user_defines |
| 348 | assert 'freestanding' in free_prefs.explicit_user_defines |
| 349 | assert comptime_optional_flag_value(&free_prefs, 'freestanding') |
| 350 | |
| 351 | none_prefs := |
| 352 | new_preferences_from_args(['-freestanding', '-os', 'none', '-d', 'none', 'main.v']) |
| 353 | assert none_prefs.target_os == 'none' |
| 354 | assert 'none' in none_prefs.explicit_user_defines |
| 355 | assert comptime_optional_flag_value(&none_prefs, 'none') |
| 356 | |
| 357 | bare_prefs := new_preferences_from_args(['-d', 'bare', 'main.v']) |
| 358 | assert 'bare' in bare_prefs.explicit_user_defines |
| 359 | assert comptime_optional_flag_value(&bare_prefs, 'bare') |
| 360 | } |
| 361 | |
| 362 | fn test_file_suffix_filter_cross_target_contract() { |
| 363 | assert !file_has_incompatible_os_suffix('common.v', 'cross') |
| 364 | assert file_has_incompatible_os_suffix('platform_linux.v', 'cross') |
| 365 | assert file_has_incompatible_os_suffix('platform_macos.v', 'cross') |
| 366 | assert file_has_incompatible_os_suffix('platform_darwin.v', 'cross') |
| 367 | assert file_has_incompatible_os_suffix('platform_windows.v', 'cross') |
| 368 | assert file_has_incompatible_os_suffix('platform_termux.c.v', 'cross') |
| 369 | assert !file_has_incompatible_os_suffix('platform_nix.v', 'cross') |
| 370 | } |
| 371 | |
| 372 | fn test_file_suffix_filter_termux_is_selected_only_for_termux_target() { |
| 373 | for target in ['linux', 'macos', 'windows', 'android', 'ios', 'freebsd', 'openbsd', 'netbsd', |
| 374 | 'dragonfly', 'solaris', 'qnx', 'serenity', 'plan9', 'vinix'] { |
| 375 | assert file_has_incompatible_os_suffix('platform_termux.c.v', target) |
| 376 | } |
| 377 | assert !file_has_incompatible_os_suffix('platform_termux.c.v', 'termux') |
| 378 | assert !file_has_incompatible_os_suffix('platform_android.c.v', 'termux') |
| 379 | assert !file_has_incompatible_os_suffix('platform_android_outside_termux.c.v', 'android') |
| 380 | assert file_has_incompatible_os_suffix('platform_android_outside_termux.c.v', 'termux') |
| 381 | } |
| 382 | |
| 383 | fn test_file_suffix_filter_none_target_excludes_all_os_variants() { |
| 384 | assert !file_has_incompatible_os_suffix('common.v', 'none') |
| 385 | assert file_has_incompatible_os_suffix('platform_linux.v', 'none') |
| 386 | assert file_has_incompatible_os_suffix('platform_macos.v', 'none') |
| 387 | assert file_has_incompatible_os_suffix('platform_darwin.v', 'none') |
| 388 | assert file_has_incompatible_os_suffix('platform_windows.v', 'none') |
| 389 | assert file_has_incompatible_os_suffix('platform_nix.v', 'none') |
| 390 | assert file_has_incompatible_os_suffix('platform_termux.c.v', 'none') |
| 391 | assert file_has_incompatible_os_suffix('platform_bsd.v', 'none') |
| 392 | } |
| 393 | |