From f6844e97661d55094833fd8a0e44589aeca62ebf Mon Sep 17 00:00:00 2001 From: yuyi Date: Sun, 16 Oct 2022 14:28:57 +0800 Subject: [PATCH] all: change optional to result of io (#16075) --- cmd/tools/check_os_api_parity.v | 2 +- cmd/tools/fast/fast.v | 34 +- cmd/tools/measure/scanner_speed.v | 10 +- cmd/tools/oldv.v | 2 +- cmd/tools/performance_compare.v | 2 +- cmd/tools/repeat.v | 6 +- cmd/tools/test_if_v_test_system_works.v | 22 +- cmd/tools/translate.v | 8 +- cmd/tools/vast/vast.v | 2 +- cmd/tools/vbin2v.v | 10 +- cmd/tools/vbuild-tools.v | 4 +- cmd/tools/vbump_test.v | 12 +- cmd/tools/vcreate_test.v | 40 +- cmd/tools/vgret.v | 12 +- cmd/tools/vls.v | 82 ++-- cmd/tools/vrepl.v | 2 +- cmd/tools/vscan.v | 4 +- cmd/tools/vself.v | 4 +- cmd/tools/vsetup-freetype.v | 2 +- cmd/tools/vshader.v | 32 +- cmd/tools/vtest-parser.v | 2 +- cmd/tools/vtracev.v | 2 +- cmd/tools/vup.v | 2 +- cmd/tools/vvet/vet_test.v | 2 +- cmd/tools/vwatch.v | 2 +- cmd/tools/vwhere/finder_utils.v | 8 +- doc/docs.md | 4 +- examples/buf_reader.v | 4 +- examples/concurrency/concurrency_http.v | 8 +- examples/dynamic_library_loading/use.v | 4 +- examples/http_server.v | 2 +- examples/mini_calculator.v | 4 +- examples/net_failconnect.v | 4 +- examples/net_peer_ip.v | 4 +- examples/net_raw_http.v | 10 +- examples/net_t.v | 4 +- examples/net_udp_server_and_client.v | 8 +- examples/pendulum-simulation/animation.v | 4 +- examples/pendulum-simulation/full.v | 6 +- .../modules/sim/args/parser.v | 18 +- .../pendulum-simulation/modules/sim/img/ppm.v | 22 +- .../modules/sim/img/writer.v | 4 +- .../pendulum-simulation/modules/sim/runner.v | 6 +- examples/pendulum-simulation/parallel.v | 4 +- .../pendulum-simulation/parallel_with_iw.v | 6 +- examples/pendulum-simulation/sequential.v | 8 +- examples/tcp_echo_server.v | 6 +- examples/tcp_notify_echo_server.v | 10 +- examples/viewer/file_scan.v | 8 +- examples/viewer/zip_container.v | 18 +- examples/vweb/vweb_assets/vweb_assets.v | 2 +- examples/websocket/client-server/client.v | 16 +- examples/websocket/client-server/server.v | 12 +- examples/websocket/ping.v | 26 +- vlib/builtin/string.v | 4 +- vlib/dl/dl.v | 4 +- vlib/flag/flag.v | 22 +- vlib/flag/flag_test.v | 28 +- vlib/io/buffered_reader.v | 8 +- vlib/io/io.v | 2 +- vlib/io/io_cp_test.v | 4 +- vlib/io/io_test.v | 4 +- vlib/io/multi_writer.v | 4 +- vlib/io/multi_writer_test.v | 6 +- vlib/io/reader.v | 8 +- vlib/io/readerwriter.v | 2 +- vlib/io/util/util.v | 4 +- vlib/io/writer.v | 4 +- vlib/net/address.v | 22 +- vlib/net/common.v | 24 +- vlib/net/errors.v | 14 +- vlib/net/ftp/ftp.v | 68 ++-- vlib/net/ftp/ftp_test.v | 8 +- vlib/net/http/backend_nix.c.v | 6 +- vlib/net/http/backend_windows.c.v | 2 +- vlib/net/http/cookie.v | 4 +- vlib/net/http/download.v | 4 +- vlib/net/http/header.v | 40 +- vlib/net/http/http.v | 30 +- vlib/net/http/http_httpbin_test.v | 8 +- vlib/net/http/request.v | 46 +-- vlib/net/http/request_test.v | 2 +- vlib/net/http/response.v | 14 +- vlib/net/http/response_test.v | 2 +- vlib/net/http/server.v | 7 +- vlib/net/http/server_test.v | 12 +- vlib/net/mbedtls/ssl_connection.v | 38 +- vlib/net/openssl/openssl.v | 2 +- vlib/net/openssl/ssl_connection.v | 62 +-- vlib/net/smtp/smtp.v | 78 ++-- vlib/net/socket.v | 2 +- vlib/net/ssl/ssl_d_use_openssl.v | 2 +- vlib/net/ssl/ssl_notd_use_openssl.v | 2 +- vlib/net/tcp.v | 120 +++--- vlib/net/tcp_read_line.v | 6 +- vlib/net/udp.v | 96 ++--- vlib/net/udp_test.v | 4 +- vlib/net/unix/common.v | 28 +- vlib/net/unix/stream_nix.v | 84 ++-- vlib/net/unix/unix_test.v | 10 +- .../unix/use_net_and_net_unix_together_test.v | 14 +- vlib/net/urllib/urllib.v | 56 +-- vlib/net/util.v | 6 +- vlib/net/websocket/events.v | 24 +- vlib/net/websocket/handshake.v | 32 +- vlib/net/websocket/io.v | 32 +- vlib/net/websocket/message.v | 44 +- .../tests/autobahn/autobahn_client.v | 16 +- .../tests/autobahn/autobahn_client_wss.v | 16 +- .../tests/autobahn/autobahn_server.v | 10 +- .../autobahn/local_run/autobahn_client.v | 16 +- .../autobahn/local_run/autobahn_client_wss.v | 16 +- vlib/net/websocket/utils.v | 2 +- vlib/net/websocket/websocket_client.v | 64 +-- vlib/net/websocket/websocket_server.v | 22 +- vlib/net/websocket/websocket_test.v | 26 +- vlib/os/dir_expansions_test.v | 8 +- vlib/os/file.c.v | 82 ++-- vlib/os/file.js.v | 30 +- vlib/os/file_test.v | 192 ++++----- vlib/os/filelock/lib_nix.c.v | 4 +- vlib/os/filelock/lib_windows.c.v | 4 +- vlib/os/find_abs_path_of_executable_test.v | 4 +- vlib/os/glob_test.v | 24 +- vlib/os/notify/backend_default.c.v | 2 +- vlib/os/notify/backend_linux.c.v | 18 +- vlib/os/notify/notify.v | 8 +- vlib/os/notify/notify_test.v | 44 +- vlib/os/open_uri_default.c.v | 2 +- vlib/os/open_uri_windows.c.v | 6 +- vlib/os/os.c.v | 56 +-- vlib/os/os.js.v | 16 +- vlib/os/os.v | 42 +- vlib/os/os_js.js.v | 14 +- vlib/os/os_nix.c.v | 20 +- vlib/os/os_test.v | 88 ++-- vlib/os/os_windows.c.v | 22 +- vlib/os/process_test.v | 4 +- vlib/os/signal.c.v | 2 +- vlib/sokol/sapp/sapp_v.c.v | 22 +- vlib/stbi/stbi.c.v | 14 +- vlib/strconv/atof.c.v | 2 +- vlib/strconv/atof.js.v | 2 +- vlib/strconv/atoi.v | 14 +- vlib/strconv/atoi_test.v | 32 +- vlib/strings/builder.c.v | 2 +- vlib/szip/szip.v | 36 +- vlib/szip/szip_test.v | 114 +++--- vlib/toml/ast/walker/walker.v | 28 +- vlib/toml/checker/checker.v | 54 +-- vlib/toml/decoder/decoder.v | 28 +- vlib/toml/input/input.v | 10 +- vlib/toml/parser/parser.v | 376 +++++++++--------- vlib/toml/scanner/scanner.v | 48 +-- .../tests/alexcrichton.toml-rs-tests_test.v | 22 +- .../toml/tests/array_of_tables_2_level_test.v | 4 +- .../tests/array_of_tables_edge_case_2_test.v | 4 +- vlib/toml/tests/burntsushi.toml-test_test.v | 20 +- vlib/toml/tests/json_encoding_test.v | 4 +- vlib/toml/tests/key_test.v | 10 +- vlib/toml/toml.v | 28 +- vlib/v/builder/msvc_windows.v | 20 +- vlib/v/checker/tests/array_fancy_sort_err.out | 2 +- vlib/v/checker/tests/array_fancy_sort_err.vv | 2 +- .../tests/fn_call_arg_mismatch_err_c.out | 4 +- .../tests/fn_call_arg_mismatch_err_c.vv | 6 +- .../v/checker/tests/for_in_index_optional.out | 2 +- .../checker/tests/optional_type_call_err.out | 2 +- vlib/v/gen/c/cgen.v | 6 +- vlib/v/gen/js/sourcemap/mappings.v | 12 +- vlib/v/gen/js/sourcemap/source_map.v | 4 +- vlib/v/gen/js/sourcemap/vlq/vlq.v | 4 +- vlib/v/gen/js/sourcemap/vlq/vlq_decode_test.v | 2 +- vlib/v/gen/js/sourcemap/vlq/vlq_encode_test.v | 4 +- vlib/v/scanner/scanner.v | 2 +- vlib/v/tests/repl/runner/runner.v | 8 +- vlib/v/tests/repl/void_vlib_fncall.repl | 4 +- ...ket_logger_interface_should_compile_test.v | 18 +- vlib/v/vcache/vcache.v | 24 +- vlib/vweb/parse.v | 4 +- vlib/vweb/sse/sse.v | 6 +- vlib/vweb/vweb.v | 8 +- vlib/x/json2/decoder.v | 42 +- vlib/x/json2/decoder_test.v | 20 +- vlib/x/json2/encoder.v | 86 ++-- vlib/x/json2/encoder_test.v | 8 +- vlib/x/json2/json2.v | 8 +- 187 files changed, 1887 insertions(+), 1876 deletions(-) diff --git a/cmd/tools/check_os_api_parity.v b/cmd/tools/check_os_api_parity.v index adc364a68..78e951a96 100644 --- a/cmd/tools/check_os_api_parity.v +++ b/cmd/tools/check_os_api_parity.v @@ -43,7 +43,7 @@ fn main() { vexe := pref.vexe_path() vroot := os.dir(vexe) util.set_vroot_folder(vroot) - os.chdir(vroot)? + os.chdir(vroot)! cmd := diff.find_working_diff_command() or { '' } mut app := App{ diff_cmd: cmd diff --git a/cmd/tools/fast/fast.v b/cmd/tools/fast/fast.v index 1631d6582..48df2a0b5 100644 --- a/cmd/tools/fast/fast.v +++ b/cmd/tools/fast/fast.v @@ -15,7 +15,7 @@ const vdir = @VEXEROOT fn main() { dump(fast_dir) dump(vdir) - os.chdir(fast_dir)? + os.chdir(fast_dir)! if !os.exists('$vdir/v') && !os.is_dir('$vdir/vlib') { println('fast.html generator needs to be located in `v/cmd/tools/fast`') } @@ -32,11 +32,11 @@ fn main() { // fetch the last commit's hash commit := exec('git rev-parse HEAD')[..8] if !os.exists('table.html') { - os.create('table.html')? + os.create('table.html')! } - mut table := os.read_file('table.html')? + mut table := os.read_file('table.html')! if os.exists('website/index.html') { - uploaded_index := os.read_file('website/index.html')? + uploaded_index := os.read_file('website/index.html')! if uploaded_index.contains('>$commit<') { println('nothing to benchmark') exit(1) @@ -48,7 +48,7 @@ fn main() { // build an optimized V println(' Building vprod...') - os.chdir(vdir)? + os.chdir(vdir)! if os.args.contains('-noprod') { exec('./v -o vprod cmd/v') // for faster debugging } else { @@ -82,8 +82,8 @@ fn main() { commit_date := exec('git log -n1 --pretty="format:%at" $commit') date := time.unix(commit_date.int()) - os.chdir(fast_dir)? - mut out := os.create('table.html')? + os.chdir(fast_dir)! + mut out := os.create('table.html')! // place the new row on top html_message := message.replace_each(['<', '<', '>', '>']) @@ -105,25 +105,25 @@ fn main() { ${int(f64(vlines) / f64(diff1) * 1000.0)} \n' + table.trim_space() - out.writeln(table)? + out.writeln(table)! out.close() // regenerate index.html - header := os.read_file('header.html')? - footer := os.read_file('footer.html')? - mut res := os.create('index.html')? - res.writeln(header)? - res.writeln(table)? - res.writeln(footer)? + header := os.read_file('header.html')! + footer := os.read_file('footer.html')! + mut res := os.create('index.html')! + res.writeln(header)! + res.writeln(table)! + res.writeln(footer)! res.close() // upload the result to github pages if os.args.contains('-upload') { println('uploading...') - os.chdir('website')? + os.chdir('website')! os.execute_or_exit('git checkout gh-pages') - os.cp('../index.html', 'index.html')? - os.rm('../index.html')? + os.cp('../index.html', 'index.html')! + os.rm('../index.html')! os.system('git commit -am "update benchmark"') os.system('git push origin gh-pages') } diff --git a/cmd/tools/measure/scanner_speed.v b/cmd/tools/measure/scanner_speed.v index 5697bd5ab..224f11704 100644 --- a/cmd/tools/measure/scanner_speed.v +++ b/cmd/tools/measure/scanner_speed.v @@ -7,14 +7,14 @@ fn main() { files := os.args#[1..] if files.len > 0 && files[0].starts_with('@') { lst_path := files[0].all_after('@') - listed_files := os.read_file(lst_path)?.split('\n') - process_files(listed_files)? + listed_files := os.read_file(lst_path)!.split('\n') + process_files(listed_files)! return } - process_files(files)? + process_files(files)! } -fn process_files(files []string) ? { +fn process_files(files []string) ! { mut pref := pref.new_preferences() pref.is_fmt = true pref.skip_warnings = true @@ -31,7 +31,7 @@ fn process_files(files []string) ? { continue } sw.restart() - s := scanner.new_scanner_file(f, .skip_comments, pref)? + s := scanner.new_scanner_file(f, .skip_comments, pref)! f_us := sw.elapsed().microseconds() total_us += f_us total_bytes += s.text.len diff --git a/cmd/tools/oldv.v b/cmd/tools/oldv.v index b57681581..5eaef980a 100644 --- a/cmd/tools/oldv.v +++ b/cmd/tools/oldv.v @@ -125,7 +125,7 @@ fn main() { should_sync := fp.bool('cache-sync', `s`, false, 'Update the local cache') context.is_bisect = fp.bool('bisect', `b`, false, 'Bisect mode. Use the current commit in the repo where oldv is.') if !should_sync && !context.is_bisect { - fp.limit_free_args(1, 1)? + fp.limit_free_args(1, 1)! } //// context.cleanup = fp.bool('clean', 0, false, 'Clean before running (slower).') diff --git a/cmd/tools/performance_compare.v b/cmd/tools/performance_compare.v index 5b421be24..183b8a3c2 100644 --- a/cmd/tools/performance_compare.v +++ b/cmd/tools/performance_compare.v @@ -194,7 +194,7 @@ fn main() { fp.description(tool_description) fp.arguments_description('COMMIT_BEFORE [COMMIT_AFTER]') fp.skip_executable() - fp.limit_free_args(1, 2)? + fp.limit_free_args(1, 2)! context.vflags = fp.string('vflags', 0, '', 'Additional options to pass to the v commands, for example "-cc tcc"') context.hyperfineopts = fp.string('hyperfine_options', 0, '', 'Additional options passed to hyperfine. ${flag.space}For example on linux, you may want to pass: diff --git a/cmd/tools/repeat.v b/cmd/tools/repeat.v index 1438ee2fe..6e0571a2d 100644 --- a/cmd/tools/repeat.v +++ b/cmd/tools/repeat.v @@ -143,19 +143,19 @@ const ( fn main() { mut context := Context{} - context.parse_options()? + context.parse_options()! context.run() context.show_diff_summary() } -fn (mut context Context) parse_options() ? { +fn (mut context Context) parse_options() ! { mut fp := flag.new_flag_parser(os.args) fp.application(os.file_name(os.executable())) fp.version('0.0.1') fp.description('Repeat command(s) and collect statistics. Note: you have to quote each command, if it contains spaces.') fp.arguments_description('CMD1 CMD2 ...') fp.skip_executable() - fp.limit_free_args_to_at_least(1)? + fp.limit_free_args_to_at_least(1)! context.count = fp.int('count', `c`, 10, 'Repetition count.') context.series = fp.int('series', `s`, 2, 'Series count. `-s 2 -c 4 a b` => aaaabbbbaaaabbbb, while `-s 3 -c 2 a b` => aabbaabbaabb.') context.warmup = fp.int('warmup', `w`, 2, 'Warmup runs. These are done *only at the start*, and are ignored.') diff --git a/cmd/tools/test_if_v_test_system_works.v b/cmd/tools/test_if_v_test_system_works.v index 9799b6a4b..5af4ca822 100644 --- a/cmd/tools/test_if_v_test_system_works.v +++ b/cmd/tools/test_if_v_test_system_works.v @@ -60,16 +60,16 @@ fn (result MyResult) matches(gpattern string) MyResult { return result } -fn create_test(tname string, tcontent string) ?string { +fn create_test(tname string, tcontent string) !string { tpath := os.join_path(tdir, tname) - os.write_file(tpath, tcontent)? + os.write_file(tpath, tcontent)! eprintln('>>>>>>>> tpath: $tpath | tcontent: $tcontent') return os.quoted_path(tpath) } -fn check_assert_continues_works() ? { - os.chdir(tdir)? - create_test('assert_continues_option_works_test.v', 'fn test_fail1() { assert 2==4\nassert 2==1\nassert 2==0 }\nfn test_ok(){ assert true }\nfn test_fail2() { assert false }')? +fn check_assert_continues_works() ! { + os.chdir(tdir)! + create_test('assert_continues_option_works_test.v', 'fn test_fail1() { assert 2==4\nassert 2==1\nassert 2==0 }\nfn test_ok(){ assert true }\nfn test_fail2() { assert false }')! result := check_fail('$vexe -assert continues assert_continues_option_works_test.v') result.has('assert_continues_option_works_test.v:1: fn test_fail1') result.has('assert_continues_option_works_test.v:2: fn test_fail1') @@ -77,7 +77,7 @@ fn check_assert_continues_works() ? { result.has('assert_continues_option_works_test.v:5: fn test_fail2') result.has('> assert 2 == 4').has('> assert 2 == 1').has('> assert 2 == 0') // Check if a test function, tagged with [assert_continues], has the same behaviour, without needing additional options - create_test('assert_continues_tag_works_test.v', '[assert_continues]fn test_fail1() { assert 2==4\nassert 2==1\nassert 2==0 }\nfn test_ok(){ assert true }\nfn test_fail2() { assert false\n assert false }')? + create_test('assert_continues_tag_works_test.v', '[assert_continues]fn test_fail1() { assert 2==4\nassert 2==1\nassert 2==0 }\nfn test_ok(){ assert true }\nfn test_fail2() { assert false\n assert false }')! tag_res := check_fail('$vexe assert_continues_tag_works_test.v') tag_res.has('assert_continues_tag_works_test.v:1: fn test_fail1') tag_res.has('assert_continues_tag_works_test.v:2: fn test_fail1') @@ -113,23 +113,23 @@ fn main() { os.chdir(os.wd_at_startup) or {} } println('> vroot: $vroot | vexe: $vexe | tdir: $tdir') - ok_fpath := create_test('a_single_ok_test.v', 'fn test_ok(){ assert true }')? + ok_fpath := create_test('a_single_ok_test.v', 'fn test_ok(){ assert true }')! if check_ok('$vexe $ok_fpath') != '' { exit(1) } check_ok('$vexe test $ok_fpath').matches('*OK*a_single_ok_test.v*') check_ok('$vexe test "$tdir"').matches('*OK*a_single_ok_test.v*') // - fail_fpath := create_test('a_single_failing_test.v', 'fn test_fail(){ assert 1 == 2 }')? + fail_fpath := create_test('a_single_failing_test.v', 'fn test_fail(){ assert 1 == 2 }')! check_fail('$vexe $fail_fpath').has('> assert 1 == 2').has('a_single_failing_test.v:1: fn test_fail') check_fail('$vexe test $fail_fpath').has('> assert 1 == 2').has('a_single_failing_test.v:1: fn test_fail') check_fail('$vexe test "$tdir"').has('> assert 1 == 2') rel_dir := os.join_path(tdir, rand.ulid()) - os.mkdir(rel_dir)? - os.chdir(rel_dir)? + os.mkdir(rel_dir)! + os.chdir(rel_dir)! relative_path := '..' + os.path_separator + 'a_single_ok_test.v' check_ok('$vexe test ${os.quoted_path(relative_path)}').has('OK').has('a_single_ok_test.v') // - check_assert_continues_works()? + check_assert_continues_works()! println('> all done') } diff --git a/cmd/tools/translate.v b/cmd/tools/translate.v index 4a368f1b0..ad30f80b6 100644 --- a/cmd/tools/translate.v +++ b/cmd/tools/translate.v @@ -16,9 +16,9 @@ fn main() { } // Git clone c2v if !os.exists(c2v_dir) { - os.mkdir_all(vmodules)? + os.mkdir_all(vmodules)! println('C2V is not installed. Cloning C2V to $c2v_dir ...') - os.chdir(vmodules)? + os.chdir(vmodules)! res := os.execute('git clone https://github.com/vlang/c2v') if res.exit_code != 0 { eprintln('Failed to download C2V.') @@ -27,7 +27,7 @@ fn main() { } // Compile c2v if !os.exists(c2v_bin) { - os.chdir(c2v_dir)? + os.chdir(c2v_dir)! println('Compiling c2v ...') res2 := os.execute('${os.quoted_path(vexe)} -o ${os.quoted_path(c2v_bin)} -keepc -g -experimental .') if res2.exit_code != 0 { @@ -42,7 +42,7 @@ fn main() { } passed_args := util.args_quote_paths(os.args[2..]) // println(passed_args) - os.chdir(os.wd_at_startup)? + os.chdir(os.wd_at_startup)! c2v_cmd := '${os.quoted_path(c2v_bin)} $passed_args' res := os.system(c2v_cmd) if res != 0 { diff --git a/cmd/tools/vast/vast.v b/cmd/tools/vast/vast.v index 0a5e168e5..58e6a739a 100644 --- a/cmd/tools/vast/vast.v +++ b/cmd/tools/vast/vast.v @@ -44,7 +44,7 @@ fn main() { for hf in hfields.split(',') { ctx.hide_names[hf] = true } - fp.limit_free_args_to_at_least(1)? + fp.limit_free_args_to_at_least(1)! rest_of_args := fp.remaining_parameters() for vfile in rest_of_args { file := get_abs_path(vfile) diff --git a/cmd/tools/vbin2v.v b/cmd/tools/vbin2v.v index a67cfc0c1..3c4afbd9e 100644 --- a/cmd/tools/vbin2v.v +++ b/cmd/tools/vbin2v.v @@ -73,7 +73,7 @@ fn (context Context) file2v(bname string, fbytes []u8, bn_max int) string { return sb.str() } -fn (context Context) bname_and_bytes(file string) ?(string, []u8) { +fn (context Context) bname_and_bytes(file string) !(string, []u8) { fname := os.file_name(file) fname_escaped := fname.replace_each(['.', '_', '-', '_']) byte_name := '$context.prefix$fname_escaped'.to_lower() @@ -130,12 +130,12 @@ fn main() { } max_bname := context.max_bname_len(file_byte_map.keys()) if context.write_file.len > 0 { - mut out_file := os.create(context.write_file)? - out_file.write_string(context.header())? + mut out_file := os.create(context.write_file)! + out_file.write_string(context.header())! for bname, fbytes in file_byte_map { - out_file.write_string(context.file2v(bname, fbytes, max_bname))? + out_file.write_string(context.file2v(bname, fbytes, max_bname))! } - out_file.write_string(context.footer())? + out_file.write_string(context.footer())! } else { print(context.header()) for bname, fbytes in file_byte_map { diff --git a/cmd/tools/vbuild-tools.v b/cmd/tools/vbuild-tools.v index 2f4ce4355..b0ee17e10 100644 --- a/cmd/tools/vbuild-tools.v +++ b/cmd/tools/vbuild-tools.v @@ -23,7 +23,7 @@ fn main() { args_string := os.args[1..].join(' ') vexe := os.getenv('VEXE') vroot := os.dir(vexe) - os.chdir(vroot)? + os.chdir(vroot)! folder := os.join_path('cmd', 'tools') tfolder := os.join_path(vroot, 'cmd', 'tools') main_label := 'Building $folder ...' @@ -47,7 +47,7 @@ fn main() { exit(1) } // - mut executables := os.ls(session.vtmp_dir)? + mut executables := os.ls(session.vtmp_dir)! executables.sort() for texe in executables { tname := texe.replace(os.file_ext(texe), '') diff --git a/cmd/tools/vbump_test.v b/cmd/tools/vbump_test.v index 7089f7a39..15b81e61f 100644 --- a/cmd/tools/vbump_test.v +++ b/cmd/tools/vbump_test.v @@ -73,25 +73,25 @@ fn main() { }, ] -fn run_individual_test(case BumpTestCase) ? { +fn run_individual_test(case BumpTestCase) ! { test_file := os.join_path_single(tfolder, case.file_name) os.rm(test_file) or {} - os.write_file(test_file, case.contents)? + os.write_file(test_file, case.contents)! // os.execute_or_exit('${os.quoted_path(vexe)} bump --patch ${os.quoted_path(test_file)}') - patch_lines := os.read_lines(test_file)? + patch_lines := os.read_lines(test_file)! assert patch_lines[case.line] == case.expected_patch os.execute_or_exit('${os.quoted_path(vexe)} bump --minor ${os.quoted_path(test_file)}') - minor_lines := os.read_lines(test_file)? + minor_lines := os.read_lines(test_file)! assert minor_lines[case.line] == case.expected_minor os.execute_or_exit('${os.quoted_path(vexe)} bump --major ${os.quoted_path(test_file)}') - major_lines := os.read_lines(test_file)? + major_lines := os.read_lines(test_file)! assert major_lines[case.line] == case.expected_major // - os.rm(test_file)? + os.rm(test_file)! } fn test_all_bump_cases() { diff --git a/cmd/tools/vcreate_test.v b/cmd/tools/vcreate_test.v index 9448c4f59..3eda2ac4a 100644 --- a/cmd/tools/vcreate_test.v +++ b/cmd/tools/vcreate_test.v @@ -2,10 +2,10 @@ import os const test_path = os.join_path(os.temp_dir(), 'v', 'vcreate_test') -fn init_and_check() ? { +fn init_and_check() ! { os.execute_or_exit('${os.quoted_path(@VEXE)} init') - assert os.read_file('vcreate_test.v')? == [ + assert os.read_file('vcreate_test.v')! == [ 'module main\n', 'fn main() {', " println('Hello World!')", @@ -13,7 +13,7 @@ fn init_and_check() ? { '', ].join_lines() - assert os.read_file('v.mod')? == [ + assert os.read_file('v.mod')! == [ 'Module {', " name: 'vcreate_test'", " description: ''", @@ -24,7 +24,7 @@ fn init_and_check() ? { '', ].join_lines() - assert os.read_file('.gitignore')? == [ + assert os.read_file('.gitignore')! == [ '# Binaries for programs and plugins', 'main', 'vcreate_test', @@ -37,7 +37,7 @@ fn init_and_check() ? { '', ].join_lines() - assert os.read_file('.gitattributes')? == [ + assert os.read_file('.gitattributes')! == [ '*.v linguist-language=V text=auto eol=lf', '*.vv linguist-language=V text=auto eol=lf', '*.vsh linguist-language=V text=auto eol=lf', @@ -45,7 +45,7 @@ fn init_and_check() ? { '', ].join_lines() - assert os.read_file('.editorconfig')? == [ + assert os.read_file('.editorconfig')! == [ '[*]', 'charset = utf-8', 'end_of_line = lf', @@ -59,28 +59,28 @@ fn init_and_check() ? { ].join_lines() } -fn prepare_test_path() ? { +fn prepare_test_path() ! { os.rmdir_all(test_path) or {} os.mkdir_all(test_path) or {} - os.chdir(test_path)? + os.chdir(test_path)! } fn test_v_init() { - prepare_test_path()? - init_and_check()? + prepare_test_path()! + init_and_check()! } fn test_v_init_in_git_dir() { - prepare_test_path()? + prepare_test_path()! os.execute_or_exit('git init .') - init_and_check()? + init_and_check()! } fn test_v_init_no_overwrite_gitignore() { - prepare_test_path()? - os.write_file('.gitignore', 'blah')? + prepare_test_path()! + os.write_file('.gitignore', 'blah')! os.execute_or_exit('${os.quoted_path(@VEXE)} init') - assert os.read_file('.gitignore')? == 'blah' + assert os.read_file('.gitignore')! == 'blah' } fn test_v_init_no_overwrite_gitattributes_and_editorconfig() { @@ -95,13 +95,13 @@ trim_trailing_whitespace = true indent_style = tab indent_size = 4 ' - prepare_test_path()? - os.write_file('.gitattributes', git_attributes_content)? - os.write_file('.editorconfig', editor_config_content)? + prepare_test_path()! + os.write_file('.gitattributes', git_attributes_content)! + os.write_file('.editorconfig', editor_config_content)! os.execute_or_exit('${os.quoted_path(@VEXE)} init') - assert os.read_file('.gitattributes')? == git_attributes_content - assert os.read_file('.editorconfig')? == editor_config_content + assert os.read_file('.gitattributes')! == git_attributes_content + assert os.read_file('.editorconfig')! == editor_config_content } fn testsuite_end() { diff --git a/cmd/tools/vgret.v b/cmd/tools/vgret.v index 194c11977..eb4b32dcb 100644 --- a/cmd/tools/vgret.v +++ b/cmd/tools/vgret.v @@ -166,7 +166,7 @@ fn main() { } toml_conf := fp.string('toml-config', `t`, default_toml, 'Path or string with TOML configuration') - arg_paths := fp.finalize()? + arg_paths := fp.finalize()! if show_help { println(fp.usage()) exit(0) @@ -179,7 +179,7 @@ fn main() { } if !os.exists(tmp_dir) { - os.mkdir_all(tmp_dir)? + os.mkdir_all(tmp_dir)! } opt.config = new_config(opt.root_path, toml_conf) or { panic(err) } @@ -202,7 +202,7 @@ fn main() { eprintln('Compare paths can not be the same directory `$path`/`$target_path`/`$gen_in_path`') exit(1) } - compare_screenshots(opt, gen_in_path, target_path)? + compare_screenshots(opt, gen_in_path, target_path)! } } @@ -254,7 +254,7 @@ fn generate_screenshots(mut opt Options, output_path string) ! { } } -fn compare_screenshots(opt Options, output_path string, target_path string) ? { +fn compare_screenshots(opt Options, output_path string, target_path string) ! { mut fails := map[string]string{} mut warns := map[string]string{} for app_config in opt.config.apps { @@ -306,14 +306,14 @@ fn compare_screenshots(opt Options, output_path string, target_path string) ? { } first := fails.keys()[0] fail_copy := os.join_path(os.temp_dir(), 'fail.' + first.all_after_last('.')) - os.cp(first, fail_copy)? + os.cp(first, fail_copy)! eprintln('First failed file `$first` is copied to `$fail_copy`') diff_file := os.join_path(os.temp_dir(), os.file_name(first).all_before_last('.') + '.diff.tif') diff_copy := os.join_path(os.temp_dir(), 'diff.tif') if os.is_file(diff_file) { - os.cp(diff_file, diff_copy)? + os.cp(diff_file, diff_copy)! eprintln('First failed diff file `$diff_file` is copied to `$diff_copy`') eprintln('Removing alpha channel from $diff_copy ...') final_fail_result_file := os.join_path(os.temp_dir(), 'diff.png') diff --git a/cmd/tools/vls.v b/cmd/tools/vls.v index 82c61a8cc..062859aa3 100644 --- a/cmd/tools/vls.v +++ b/cmd/tools/vls.v @@ -67,16 +67,16 @@ const json_enc = json2.Encoder{ escape_unicode: false } -fn (upd VlsUpdater) check_or_create_vls_folder() ? { +fn (upd VlsUpdater) check_or_create_vls_folder() ! { if !os.exists(vls_folder) { upd.log('Creating .vls folder...') - os.mkdir(vls_folder)? + os.mkdir(vls_folder)! } } -fn (upd VlsUpdater) manifest_config() ?map[string]json2.Any { +fn (upd VlsUpdater) manifest_config() !map[string]json2.Any { manifest_buf := os.read_file(vls_manifest_path) or { '{}' } - manifest_contents := json2.raw_decode(manifest_buf)?.as_map() + manifest_contents := json2.raw_decode(manifest_buf)!.as_map() return manifest_contents } @@ -88,9 +88,9 @@ fn (upd VlsUpdater) exec_asset_file_name() string { return 'vls_${os_name}_${arch + ext}' } -fn (upd VlsUpdater) update_manifest(new_path string, from_source bool, timestamp time.Time) ? { +fn (upd VlsUpdater) update_manifest(new_path string, from_source bool, timestamp time.Time) ! { upd.log('Updating permissions...') - os.chmod(new_path, 755)? + os.chmod(new_path, 755)! upd.log('Updating vls.config.json...') mut manifest := upd.manifest_config() or { @@ -103,7 +103,7 @@ fn (upd VlsUpdater) update_manifest(new_path string, from_source bool, timestamp } } - mut manifest_file := os.open_file(vls_manifest_path, 'w+')? + mut manifest_file := os.open_file(vls_manifest_path, 'w+')! defer { manifest_file.close() } @@ -112,31 +112,31 @@ fn (upd VlsUpdater) update_manifest(new_path string, from_source bool, timestamp manifest['last_updated'] = json2.Any(timestamp.format_ss()) manifest['from_source'] = json2.Any(from_source) - json_enc.encode_value(manifest, mut manifest_file)? + json_enc.encode_value(manifest, mut manifest_file)! } -fn (upd VlsUpdater) init_download_prebuilt() ? { +fn (upd VlsUpdater) init_download_prebuilt() ! { if !os.exists(vls_cache_folder) { - os.mkdir(vls_cache_folder)? + os.mkdir(vls_cache_folder)! } if os.exists(vls_bin_folder) { - os.rmdir_all(vls_bin_folder)? + os.rmdir_all(vls_bin_folder)! } - os.mkdir(vls_bin_folder)? + os.mkdir(vls_bin_folder)! } -fn (upd VlsUpdater) get_last_updated_at() ?time.Time { +fn (upd VlsUpdater) get_last_updated_at() !time.Time { if manifest := upd.manifest_config() { if 'last_updated' in manifest { - return time.parse(manifest['last_updated'] or { '' }.str()) or { return none } + return time.parse(manifest['last_updated'] or { '' }.str()) or { return error('none') } } } - return none + return error('none') } -fn (upd VlsUpdater) download_prebuilt() ? { +fn (upd VlsUpdater) download_prebuilt() ! { mut has_last_updated_at := true last_updated_at := upd.get_last_updated_at() or { has_last_updated_at = false @@ -147,14 +147,15 @@ fn (upd VlsUpdater) download_prebuilt() ? { } upd.log('Finding prebuilt executables from GitHub release..') - resp := http.get('https://api.github.com/repos/vlang/vls/releases')? - releases_json := json2.raw_decode(resp.body)?.arr() + resp := http.get('https://api.github.com/repos/vlang/vls/releases')! + releases_json := json2.raw_decode(resp.body)!.arr() if releases_json.len == 0 { return error('Unable to fetch latest VLS release data: No releases found.') } latest_release := releases_json[0].as_map() - assets := latest_release['assets']?.arr() + latest_assets := latest_release['assets'] or { return } + assets := latest_assets.arr() mut checksum_asset_idx := -1 mut exec_asset_idx := -1 @@ -164,7 +165,8 @@ fn (upd VlsUpdater) download_prebuilt() ? { for asset_idx, raw_asset in assets { asset := raw_asset.as_map() - match asset['name']?.str() { + t_asset := asset['name'] or { return } + match t_asset.str() { exp_asset_name { exec_asset_idx = asset_idx @@ -196,13 +198,15 @@ fn (upd VlsUpdater) download_prebuilt() ? { } upd.log('Executable found for this system. Downloading...') - upd.init_download_prebuilt()? - http.download_file(exec_asset['browser_download_url']?.str(), exec_asset_file_path)? + upd.init_download_prebuilt()! + t_asset := exec_asset['browser_download_url'] or { return } + http.download_file(t_asset.str(), exec_asset_file_path)! checksum_file_path := os.join_path(vls_cache_folder, 'checksums.txt') checksum_file_asset := assets[checksum_asset_idx].as_map() - http.download_file(checksum_file_asset['browser_download_url']?.str(), checksum_file_path)? - checksums := os.read_file(checksum_file_path)?.split_into_lines() + t_checksum_asset := checksum_file_asset['browser_download_url'] or { return } + http.download_file(t_checksum_asset.str(), checksum_file_path)! + checksums := os.read_file(checksum_file_path)!.split_into_lines() upd.log('Verifying checksum...') for checksum_result in checksums { @@ -217,7 +221,7 @@ fn (upd VlsUpdater) download_prebuilt() ? { } new_exec_path := os.join_path(vls_bin_folder, exp_asset_name) - os.cp(exec_asset_file_path, new_exec_path)? + os.cp(exec_asset_file_path, new_exec_path)! upd.update_manifest(new_exec_path, false, asset_last_updated_at) or { upd.log('Unable to update config but the executable was updated successfully.') } @@ -231,12 +235,12 @@ fn (upd VlsUpdater) print_new_vls_version(new_vls_exec_path string) { } } -fn calculate_checksum(file_path string) ?string { - data := os.read_file(file_path)? +fn calculate_checksum(file_path string) !string { + data := os.read_file(file_path)! return sha256.hexhash(data) } -fn (upd VlsUpdater) compile_from_source() ? { +fn (upd VlsUpdater) compile_from_source() ! { git := os.find_abs_path_of_executable('git') or { return error('Git not found.') } if !os.exists(vls_src_folder) { @@ -280,22 +284,22 @@ fn (upd VlsUpdater) compile_from_source() ? { upd.print_new_vls_version(exec_path) } -fn (upd VlsUpdater) find_ls_path() ?string { - manifest := upd.manifest_config()? +fn (upd VlsUpdater) find_ls_path() !string { + manifest := upd.manifest_config()! if 'server_path' in manifest { - server_path := manifest['server_path']? + server_path := manifest['server_path'] or { return error('none') } if server_path is string { if server_path.len == 0 { - return none + return error('none') } return server_path } } - return none + return error('none') } -fn (mut upd VlsUpdater) parse(mut fp flag.FlagParser) ? { +fn (mut upd VlsUpdater) parse(mut fp flag.FlagParser) ! { is_json := fp.bool('json', ` `, false, 'Print the output as JSON.') if is_json { upd.output = .json @@ -364,7 +368,7 @@ fn (mut upd VlsUpdater) parse(mut fp flag.FlagParser) ? { fp.allow_unknown_args() upd.args << fp.finalize() or { fp.remaining_parameters() } } else { - fp.finalize()? + fp.finalize()! } } @@ -436,23 +440,23 @@ fn (upd VlsUpdater) check_installation() { } } -fn (upd VlsUpdater) run(fp flag.FlagParser) ? { +fn (upd VlsUpdater) run(fp flag.FlagParser) ! { if upd.is_check { upd.check_installation() } else if upd.setup_kind != .none_ { - upd.check_or_create_vls_folder()? + upd.check_or_create_vls_folder()! match upd.update_source { .github_releases { upd.download_prebuilt() or { if err.code() == 100 { - upd.compile_from_source()? + upd.compile_from_source()! } return err } } .git_repo { - upd.compile_from_source()? + upd.compile_from_source()! } } } else if upd.pass_to_ls { diff --git a/cmd/tools/vrepl.v b/cmd/tools/vrepl.v index 524713e10..46edf4967 100644 --- a/cmd/tools/vrepl.v +++ b/cmd/tools/vrepl.v @@ -133,7 +133,7 @@ fn (r &Repl) function_call(line string) (bool, FnType) { // TODO(vincenzopalazzo) Remove this fancy check and add a regex fn (r &Repl) is_function_call(line string) bool { return !line.starts_with('[') && line.contains('.') && line.contains('(') - && (line.ends_with(')') || line.ends_with('?')) + && (line.ends_with(')') || line.ends_with('?') || line.ends_with('!')) } // Convert the list of modules that we parsed already, diff --git a/cmd/tools/vscan.v b/cmd/tools/vscan.v index 31d7d155a..4266adc8d 100644 --- a/cmd/tools/vscan.v +++ b/cmd/tools/vscan.v @@ -12,11 +12,11 @@ fn main() { fp.version('0.0.1') fp.description('\nScan .v source files, and print the V tokens contained in them.') fp.arguments_description('PATH [PATH]...') - fp.limit_free_args_to_at_least(1)? + fp.limit_free_args_to_at_least(1)! pref := pref.new_preferences() mut all_paths := fp.remaining_parameters() for path in all_paths { - mut scanner := scanner.new_scanner_file(path, .parse_comments, pref)? + mut scanner := scanner.new_scanner_file(path, .parse_comments, pref)! mut tok := token.Token{} for tok.kind != .eof { tok = scanner.scan() diff --git a/cmd/tools/vself.v b/cmd/tools/vself.v index b13466a59..3346e5ffa 100644 --- a/cmd/tools/vself.v +++ b/cmd/tools/vself.v @@ -15,7 +15,7 @@ fn main() { short_v_name := vexe_name.all_before('.') // recompilation.must_be_enabled(vroot, 'Please install V from source, to use `$vexe_name self` .') - os.chdir(vroot)? + os.chdir(vroot)! os.setenv('VCOLORS', 'always', true) args := os.args[1..].filter(it != 'self') jargs := args.join(' ') @@ -60,7 +60,7 @@ fn list_folder(short_v_name string, bmessage string, message string) { println(message) } -fn backup_old_version_and_rename_newer(short_v_name string) ?bool { +fn backup_old_version_and_rename_newer(short_v_name string) !bool { mut errors := []string{} short_v_file := if os.user_os() == 'windows' { '${short_v_name}.exe' } else { '$short_v_name' } short_v2_file := if os.user_os() == 'windows' { 'v2.exe' } else { 'v2' } diff --git a/cmd/tools/vsetup-freetype.v b/cmd/tools/vsetup-freetype.v index a0409bcb6..5a608bb03 100644 --- a/cmd/tools/vsetup-freetype.v +++ b/cmd/tools/vsetup-freetype.v @@ -11,7 +11,7 @@ fn main() { $if windows { println('Setup freetype...') vroot := os.dir(pref.vexe_path()) - os.chdir(vroot)? + os.chdir(vroot)! if os.is_dir(freetype_folder) { println('Thirdparty "freetype" is already installed.') } else { diff --git a/cmd/tools/vshader.v b/cmd/tools/vshader.v index dfe644f93..71b65ec0d 100644 --- a/cmd/tools/vshader.v +++ b/cmd/tools/vshader.v @@ -122,7 +122,7 @@ fn shader_program_name(shader_file string) string { } // validate_shader_file returns an error if `shader_file` isn't valid. -fn validate_shader_file(shader_file string) ? { +fn validate_shader_file(shader_file string) ! { shader_program := os.read_lines(shader_file) or { return error('shader program at "$shader_file" could not be opened for reading') } @@ -140,7 +140,7 @@ fn validate_shader_file(shader_file string) ? { // compile_shaders compiles all `*.glsl` files found in `input_path` // to their C header file representatives. -fn compile_shaders(opt Options, input_path string) ? { +fn compile_shaders(opt Options, input_path string) ! { mut path := os.real_path(input_path) path = path.trim_right('/') if os.is_file(path) { @@ -172,12 +172,12 @@ fn compile_shaders(opt Options, input_path string) ? { // Currently sokol-shdc allows for multiple --input flags // - but it's only the last entry that's actually compiled/used // Given this fact - we can only compile one '.glsl' file to one C '.h' header - compile_shader(co, shader_file)? + compile_shader(co, shader_file)! } } // compile_shader compiles `shader_file` to a C header file. -fn compile_shader(opt CompileOptions, shader_file string) ? { +fn compile_shader(opt CompileOptions, shader_file string) ! { path := opt.invoke_path // The output convetion, for now, is to use the name of the .glsl file mut out_file := os.file_name(shader_file).all_before_last('.') + '.h' @@ -231,12 +231,12 @@ fn collect(path string, mut list []string) { // ensure_external_tools returns nothing if the external // tools can be setup or is already in place. -fn ensure_external_tools(opt Options) ? { +fn ensure_external_tools(opt Options) ! { if !os.exists(cache_dir) { - os.mkdir_all(cache_dir)? + os.mkdir_all(cache_dir)! } if opt.force_update { - download_shdc(opt)? + download_shdc(opt)! return } @@ -250,7 +250,7 @@ fn ensure_external_tools(opt Options) ? { return } - download_shdc(opt)? + download_shdc(opt)! } // shdc_exe returns an absolute path to the `sokol-shdc` tool. @@ -261,7 +261,7 @@ fn shdc_exe() string { } // download_shdc downloads the `sokol-shdc` tool to an OS specific cache directory. -fn download_shdc(opt Options) ? { +fn download_shdc(opt Options) ! { // We want to use the same, runtime, OS type as this tool is invoked on. download_url := shdc_urls[runtime_os] or { '' } if download_url == '' { @@ -277,26 +277,26 @@ fn download_shdc(opt Options) ? { } } if os.exists(file) { - os.rm(file)? + os.rm(file)! } - mut dtmp_file, dtmp_path := util.temp_file(util.TempFileOptions{ path: os.dir(file) })? + mut dtmp_file, dtmp_path := util.temp_file(util.TempFileOptions{ path: os.dir(file) })! dtmp_file.close() if opt.verbose { eprintln('$tool_name downloading sokol-shdc from $download_url') } http.download_file(download_url, dtmp_path) or { - os.rm(dtmp_path)? + os.rm(dtmp_path)! return error('$tool_name failed to download sokol-shdc needed for shader compiling: $err') } // Make it executable - os.chmod(dtmp_path, 0o775)? + os.chmod(dtmp_path, 0o775)! // Move downloaded file in place - os.mv(dtmp_path, file)? + os.mv(dtmp_path, file)! if runtime_os in ['linux', 'macos'] { // Use the .exe file ending to minimize platform friction. - os.mv(file, shdc)? + os.mv(file, shdc)! } // Update internal version file - os.write_file(shdc_version_file, update_to_shdc_version)? + os.write_file(shdc_version_file, update_to_shdc_version)! } diff --git a/cmd/tools/vtest-parser.v b/cmd/tools/vtest-parser.v index bde3a5fd5..de8d4ca92 100644 --- a/cmd/tools/vtest-parser.v +++ b/cmd/tools/vtest-parser.v @@ -54,7 +54,7 @@ fn main() { context.pref = &pref.Preferences{ output_mode: .silent } - mut source := os.read_file(context.path)? + mut source := os.read_file(context.path)! source = source[..context.cut_index] go fn (ms int) { diff --git a/cmd/tools/vtracev.v b/cmd/tools/vtracev.v index 504886a6c..9010cca51 100644 --- a/cmd/tools/vtracev.v +++ b/cmd/tools/vtracev.v @@ -6,7 +6,7 @@ import v.pref fn main() { vexe := pref.vexe_path() vroot := os.dir(vexe) - os.chdir(vroot)? + os.chdir(vroot)! os.setenv('VCOLORS', 'always', true) self_idx := os.args.index('tracev') args := os.args[1..self_idx] diff --git a/cmd/tools/vup.v b/cmd/tools/vup.v index 51d93940b..6a48be86a 100644 --- a/cmd/tools/vup.v +++ b/cmd/tools/vup.v @@ -26,7 +26,7 @@ fn new_app() App { fn main() { app := new_app() recompilation.must_be_enabled(app.vroot, 'Please install V from source, to use `v up` .') - os.chdir(app.vroot)? + os.chdir(app.vroot)! println('Updating V...') app.update_from_master() v_hash := version.githash(false) diff --git a/cmd/tools/vvet/vet_test.v b/cmd/tools/vvet/vet_test.v index d4ad7dfcb..aab8f94a0 100644 --- a/cmd/tools/vvet/vet_test.v +++ b/cmd/tools/vvet/vet_test.v @@ -14,7 +14,7 @@ fn find_diff_cmd() string { fn test_vet() { vexe := os.getenv('VEXE') vroot := os.dir(vexe) - os.chdir(vroot)? + os.chdir(vroot)! test_dir := 'cmd/tools/vvet/tests' tests := get_tests_in_dir(test_dir) fails := check_path(vexe, test_dir, tests) diff --git a/cmd/tools/vwatch.v b/cmd/tools/vwatch.v index a20f646b7..9fb8d2f28 100644 --- a/cmd/tools/vwatch.v +++ b/cmd/tools/vwatch.v @@ -318,7 +318,7 @@ fn main() { fp.description('Collect all .v files needed for a compilation, then re-run the compilation when any of the source changes.') fp.arguments_description('[--silent] [--clear] [--ignore .db] [--add /path/to/a/file.v] [run] program.v') fp.allow_unknown_args() - fp.limit_free_args_to_at_least(1)? + fp.limit_free_args_to_at_least(1)! context.is_worker = fp.bool('vwatchworker', 0, false, 'Internal flag. Used to distinguish vwatch manager and worker processes.') context.silent = fp.bool('silent', `s`, false, 'Be more silent; do not print the watch timestamp before each re-run.') context.clear_terminal = fp.bool('clear', `c`, false, 'Clears the terminal before each re-run.') diff --git a/cmd/tools/vwhere/finder_utils.v b/cmd/tools/vwhere/finder_utils.v index 7f169358a..65a1ffa29 100755 --- a/cmd/tools/vwhere/finder_utils.v +++ b/cmd/tools/vwhere/finder_utils.v @@ -145,7 +145,7 @@ fn maybe_color(term_color fn (string) string, str string) string { } } -fn collect_v_files(path string, recursive bool) ?[]string { +fn collect_v_files(path string, recursive bool) ![]string { if path.len == 0 { return error('path cannot be empty') } @@ -153,7 +153,7 @@ fn collect_v_files(path string, recursive bool) ?[]string { return error('path does not exist or is not a directory') } mut all_files := []string{} - mut entries := os.ls(path)? + mut entries := os.ls(path)! mut local_path_separator := os.path_separator if path.ends_with(os.path_separator) { local_path_separator = '' @@ -161,7 +161,7 @@ fn collect_v_files(path string, recursive bool) ?[]string { for entry in entries { file := path + local_path_separator + entry if os.is_dir(file) && !os.is_link(file) && recursive { - all_files << collect_v_files(file, recursive)? + all_files << collect_v_files(file, recursive)! } else if os.exists(file) && (file.ends_with('.v') || file.ends_with('.vsh')) { all_files << file } @@ -169,7 +169,7 @@ fn collect_v_files(path string, recursive bool) ?[]string { return all_files } -fn resolve_module(path string) ?string { +fn resolve_module(path string) !string { if os.is_dir(path) { return path } else if os.is_dir(os.join_path(vmod_dir, path)) { diff --git a/doc/docs.md b/doc/docs.md index e58cc5a79..6cec3714d 100644 --- a/doc/docs.md +++ b/doc/docs.md @@ -1901,8 +1901,8 @@ enum State { } // write log file and return number of bytes written -fn write_log(s State) ?int { - mut f := os.create('log.txt')? +fn write_log(s State) !int { + mut f := os.create('log.txt')! defer { f.close() } diff --git a/examples/buf_reader.v b/examples/buf_reader.v index a3f708ef2..380a9fabf 100644 --- a/examples/buf_reader.v +++ b/examples/buf_reader.v @@ -5,9 +5,9 @@ import io fn main() { // Make a new connection - mut conn := net.dial_tcp('google.com:80')? + mut conn := net.dial_tcp('google.com:80')! // Simple http HEAD request for a file - conn.write_string('GET /index.html HTTP/1.0\r\n\r\n')? + conn.write_string('GET /index.html HTTP/1.0\r\n\r\n')! // Wrap in a buffered reader mut r := io.new_buffered_reader(reader: conn) for { diff --git a/examples/concurrency/concurrency_http.v b/examples/concurrency/concurrency_http.v index 10b5060f9..39de5a765 100644 --- a/examples/concurrency/concurrency_http.v +++ b/examples/concurrency/concurrency_http.v @@ -2,9 +2,9 @@ import net.http import sync import time -fn vlang_time(mut wg sync.WaitGroup) ?string { +fn vlang_time(mut wg sync.WaitGroup) !string { start := time.ticks() - data := http.get('https://vlang.io/utc_now')? + data := http.get('https://vlang.io/utc_now')! finish := time.ticks() println('Finish getting time ${finish - start} ms') println(data.body) @@ -12,9 +12,9 @@ fn vlang_time(mut wg sync.WaitGroup) ?string { return data.body } -fn remote_ip(mut wg sync.WaitGroup) ?string { +fn remote_ip(mut wg sync.WaitGroup) !string { start := time.ticks() - data := http.get('https://api.ipify.org')? + data := http.get('https://api.ipify.org')! finish := time.ticks() println('Finish getting ip ${finish - start} ms') println(data.body) diff --git a/examples/dynamic_library_loading/use.v b/examples/dynamic_library_loading/use.v index e41f9f0f1..a6a35c225 100644 --- a/examples/dynamic_library_loading/use.v +++ b/examples/dynamic_library_loading/use.v @@ -10,9 +10,9 @@ type FNAdder = fn (int, int) int fn main() { library_file_path := os.join_path(os.dir(@FILE), dl.get_libname('library')) - handle := dl.open_opt(library_file_path, dl.rtld_lazy)? + handle := dl.open_opt(library_file_path, dl.rtld_lazy)! eprintln('handle: ${ptr_str(handle)}') - f := FNAdder(dl.sym_opt(handle, 'add_1')?) + f := FNAdder(dl.sym_opt(handle, 'add_1')!) eprintln('f: ${ptr_str(f)}') res := f(1, 2) eprintln('res: $res') diff --git a/examples/http_server.v b/examples/http_server.v index 256ccdeb1..630fa20fd 100644 --- a/examples/http_server.v +++ b/examples/http_server.v @@ -34,5 +34,5 @@ fn main() { mut server := Server{ handler: ExampleHandler{} } - server.listen_and_serve()? + server.listen_and_serve() } diff --git a/examples/mini_calculator.v b/examples/mini_calculator.v index 0c22aa380..9aefa4be9 100644 --- a/examples/mini_calculator.v +++ b/examples/mini_calculator.v @@ -5,7 +5,7 @@ import os const numeric_char = [`0`, `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `.`, `e`, `E`] // Convert expression to Reverse Polish Notation. -fn expr_to_rev_pol(expr string) ?[]string { +fn expr_to_rev_pol(expr string) ![]string { if expr == '' { return error('err: empty expression') } @@ -63,7 +63,7 @@ fn expr_to_rev_pol(expr string) ?[]string { } // Evaluate the result of Reverse Polish Notation. -fn eval_rev_pol(rev_pol []string) ?f64 { +fn eval_rev_pol(rev_pol []string) !f64 { mut stack := []f64{} for item in rev_pol { if is_num_string(item) { diff --git a/examples/net_failconnect.v b/examples/net_failconnect.v index 1035a4507..8f971f8e2 100644 --- a/examples/net_failconnect.v +++ b/examples/net_failconnect.v @@ -1,5 +1,5 @@ import net -conn := net.dial_tcp('[::1]:57000')? -peer_addr := conn.peer_addr()? +conn := net.dial_tcp('[::1]:57000')! +peer_addr := conn.peer_addr()! println('$peer_addr') diff --git a/examples/net_peer_ip.v b/examples/net_peer_ip.v index 9c45c08b9..b27f32e6c 100644 --- a/examples/net_peer_ip.v +++ b/examples/net_peer_ip.v @@ -1,5 +1,5 @@ import net -conn := net.dial_tcp('google.com:80')? -peer_addr := conn.peer_addr()? +conn := net.dial_tcp('google.com:80')! +peer_addr := conn.peer_addr()! println('$peer_addr') diff --git a/examples/net_raw_http.v b/examples/net_raw_http.v index 08a2c3f90..84a2a200a 100644 --- a/examples/net_raw_http.v +++ b/examples/net_raw_http.v @@ -3,18 +3,18 @@ import io fn main() { // Make a new connection - mut conn := net.dial_tcp('google.com:80')? + mut conn := net.dial_tcp('google.com:80')! defer { conn.close() or {} } - println(' peer: ${conn.peer_addr()?}') - println('local: ${conn.addr()?}') + println(' peer: ${conn.peer_addr()!}') + println('local: ${conn.addr()!}') // Simple http HEAD request for a file - conn.write_string('HEAD /index.html HTTP/1.0\r\n\r\n')? + conn.write_string('HEAD /index.html HTTP/1.0\r\n\r\n')! // Read all the data that is waiting - result := io.read_all(reader: conn)? + result := io.read_all(reader: conn)! // Cast to string and print result println(result.bytestr()) } diff --git a/examples/net_t.v b/examples/net_t.v index 71fc71acd..c2ff47fb4 100644 --- a/examples/net_t.v +++ b/examples/net_t.v @@ -2,9 +2,9 @@ import net.http import sync import time -fn send_request(mut wg sync.WaitGroup) ?string { +fn send_request(mut wg sync.WaitGroup) !string { start := time.ticks() - data := http.get('https://google.com')? + data := http.get('https://google.com')! finish := time.ticks() println('Finish getting time ${finish - start} ms') wg.done() diff --git a/examples/net_udp_server_and_client.v b/examples/net_udp_server_and_client.v index 7aa0ef669..cb808fa34 100644 --- a/examples/net_udp_server_and_client.v +++ b/examples/net_udp_server_and_client.v @@ -12,7 +12,7 @@ fn main() { mut buf := []u8{len: 100} if is_server { println('UDP echo server, listening for udp packets on port: $port') - mut c := net.listen_udp(':$port')? + mut c := net.listen_udp(':$port')! for { read, addr := c.read(mut buf) or { continue } println('received $read bytes from $addr') @@ -23,7 +23,7 @@ fn main() { } } else { println('UDP client, sending packets to port: ${port}.\nType `exit` to exit.') - mut c := net.dial_udp('localhost:$port')? + mut c := net.dial_udp('localhost:$port')! for { mut line := os.input('client > ') match line { @@ -36,8 +36,8 @@ fn main() { } else {} } - c.write_string(line)? - read, _ := c.read(mut buf)? + c.write_string(line)! + read, _ := c.read(mut buf)! println('server : ' + buf[0..read].bytestr()) } } diff --git a/examples/pendulum-simulation/animation.v b/examples/pendulum-simulation/animation.v index fe48e7ca0..9d41b826b 100644 --- a/examples/pendulum-simulation/animation.v +++ b/examples/pendulum-simulation/animation.v @@ -6,7 +6,7 @@ import sim.anim import sim.args as simargs fn main() { - args := simargs.parse_args(extra_workers: 1)? as simargs.ParallelArgs + args := simargs.parse_args(extra_workers: 1)! as simargs.ParallelArgs mut app := anim.new_app(args) mut workers := []thread{cap: args.workers} @@ -27,7 +27,7 @@ fn main() { workers << go sim.sim_worker(id, app.request_chan, [app.result_chan]) } - handle_request := fn [app] (request &sim.SimRequest) ? { + handle_request := fn [app] (request &sim.SimRequest) ! { app.request_chan <- request } diff --git a/examples/pendulum-simulation/full.v b/examples/pendulum-simulation/full.v index b72140769..796e6cd86 100644 --- a/examples/pendulum-simulation/full.v +++ b/examples/pendulum-simulation/full.v @@ -7,11 +7,11 @@ import sim.args as simargs import sim.img fn main() { - args := simargs.parse_args(extra_workers: 2)? as simargs.ParallelArgs + args := simargs.parse_args(extra_workers: 2)! as simargs.ParallelArgs img_settings := img.image_settings_from_grid(args.grid) - mut writer := img.ppm_writer_for_fname(args.filename, img_settings)? + mut writer := img.ppm_writer_for_fname(args.filename, img_settings)! mut app := anim.new_app(args) mut workers := []thread{cap: args.workers + 1} @@ -41,7 +41,7 @@ fn main() { workers << go sim.sim_worker(id, app.request_chan, [app.result_chan, img_result_chan]) } - handle_request := fn [app] (request &sim.SimRequest) ? { + handle_request := fn [app] (request &sim.SimRequest) ! { app.request_chan <- request } diff --git a/examples/pendulum-simulation/modules/sim/args/parser.v b/examples/pendulum-simulation/modules/sim/args/parser.v index 56ff96e63..f7f8ede12 100644 --- a/examples/pendulum-simulation/modules/sim/args/parser.v +++ b/examples/pendulum-simulation/modules/sim/args/parser.v @@ -31,21 +31,21 @@ pub: pub type SimArgs = ParallelArgs | SequentialArgs -pub fn parse_args(config ParserSettings) ?SimArgs { +pub fn parse_args(config ParserSettings) !SimArgs { if config.sequential { - args := parse_sequential_args()? + args := parse_sequential_args()! return SimArgs(args) } else { - args := parse_parallel_args(config.extra_workers)? + args := parse_parallel_args(config.extra_workers)! return SimArgs(args) } } -fn parse_sequential_args() ?SequentialArgs { +fn parse_sequential_args() !SequentialArgs { mut fp := flag.new_flag_parser(os.args) fp.application('vps') fp.version('v0.1.0') - fp.limit_free_args(0, 0)? + fp.limit_free_args(0, 0)! fp.description('This is a pendulum simulation written in pure V') fp.skip_executable() @@ -64,7 +64,7 @@ fn parse_sequential_args() ?SequentialArgs { fp.finalize() or { println(fp.usage()) - return none + return error('none') } params := sim.sim_params( @@ -92,11 +92,11 @@ fn parse_sequential_args() ?SequentialArgs { return args } -fn parse_parallel_args(extra_workers int) ?ParallelArgs { +fn parse_parallel_args(extra_workers int) !ParallelArgs { mut fp := flag.new_flag_parser(os.args) fp.application('vps') fp.version('v0.1.0') - fp.limit_free_args(0, 0)? + fp.limit_free_args(0, 0)! fp.description('This is a pendulum simulation written in pure V') fp.skip_executable() @@ -117,7 +117,7 @@ fn parse_parallel_args(extra_workers int) ?ParallelArgs { fp.finalize() or { println(fp.usage()) - return none + return error('none') } params := sim.sim_params( diff --git a/examples/pendulum-simulation/modules/sim/img/ppm.v b/examples/pendulum-simulation/modules/sim/img/ppm.v index bb1517f27..2b8b73dde 100644 --- a/examples/pendulum-simulation/modules/sim/img/ppm.v +++ b/examples/pendulum-simulation/modules/sim/img/ppm.v @@ -39,34 +39,34 @@ mut: cache_size int } -pub fn ppm_writer_for_fname(fname string, settings ImageSettings) ?&PPMWriter { +pub fn ppm_writer_for_fname(fname string, settings ImageSettings) !&PPMWriter { mut writer := &PPMWriter{ cache_size: settings.cache_size cache: []u8{cap: settings.cache_size} } - writer.start_for_file(fname, settings)? + writer.start_for_file(fname, settings)! return writer } -pub fn (mut writer PPMWriter) start_for_file(fname string, settings ImageSettings) ? { - writer.file = os.create(fname)? - writer.file.writeln('P6 $settings.width $settings.height 255')? +pub fn (mut writer PPMWriter) start_for_file(fname string, settings ImageSettings) ! { + writer.file = os.create(fname)! + writer.file.writeln('P6 $settings.width $settings.height 255')! } -pub fn (mut writer PPMWriter) handle_pixel(p gx.Color) ? { +pub fn (mut writer PPMWriter) handle_pixel(p gx.Color) ! { if writer.cache.len >= writer.cache_size { - writer.write()? - writer.flush()? + writer.write()! + writer.flush()! } writer.cache << [p.r, p.g, p.b] } -pub fn (mut writer PPMWriter) flush() ? { +pub fn (mut writer PPMWriter) flush() ! { writer.cache.clear() } -pub fn (mut writer PPMWriter) write() ? { - writer.file.write(writer.cache)? +pub fn (mut writer PPMWriter) write() ! { + writer.file.write(writer.cache)! } pub fn (mut writer PPMWriter) close() { diff --git a/examples/pendulum-simulation/modules/sim/img/writer.v b/examples/pendulum-simulation/modules/sim/img/writer.v index 0e2816987..f0a215453 100644 --- a/examples/pendulum-simulation/modules/sim/img/writer.v +++ b/examples/pendulum-simulation/modules/sim/img/writer.v @@ -29,7 +29,7 @@ pub fn new_image_writer(mut writer PPMWriter, settings ImageSettings) &ImageWrit } } -pub fn (mut iw ImageWritter) handle(result sim.SimResult) ?int { +pub fn (mut iw ImageWritter) handle(result sim.SimResult) !int { total_pixels := iw.settings.width * iw.settings.height // find the closest magnet @@ -46,7 +46,7 @@ pub fn (mut iw ImageWritter) handle(result sim.SimResult) ?int { if iw.current_index == total_pixels { iw.writer.write() or { panic('Could not write image') } - return none + return error('none') } return iw.current_index diff --git a/examples/pendulum-simulation/modules/sim/runner.v b/examples/pendulum-simulation/modules/sim/runner.v index bd4e92fa5..54ab9a937 100644 --- a/examples/pendulum-simulation/modules/sim/runner.v +++ b/examples/pendulum-simulation/modules/sim/runner.v @@ -3,11 +3,11 @@ module sim import benchmark import term -pub type SimRequestHandler = fn (request &SimRequest) ? +pub type SimRequestHandler = fn (request &SimRequest) ! -pub type SimStartHandler = fn () ? +pub type SimStartHandler = fn () ! -pub type SimFinishHandler = fn () ? +pub type SimFinishHandler = fn () ! pub const ( default_width = 600 diff --git a/examples/pendulum-simulation/parallel.v b/examples/pendulum-simulation/parallel.v index 841288522..416a69b5c 100644 --- a/examples/pendulum-simulation/parallel.v +++ b/examples/pendulum-simulation/parallel.v @@ -6,7 +6,7 @@ import sim.args as simargs import sim.img fn main() { - args := simargs.parse_args()? as simargs.ParallelArgs + args := simargs.parse_args()! as simargs.ParallelArgs img_settings := img.image_settings_from_grid(args.grid) @@ -17,7 +17,7 @@ fn main() { request_chan := chan &sim.SimRequest{cap: args.workers} result_chan := chan &sim.SimResult{cap: args.workers} - mut writer := img.ppm_writer_for_fname(args.filename, img_settings)? + mut writer := img.ppm_writer_for_fname(args.filename, img_settings)! mut image_writer := img.new_image_writer(mut writer, img_settings) mut workers := []thread{cap: args.workers} diff --git a/examples/pendulum-simulation/parallel_with_iw.v b/examples/pendulum-simulation/parallel_with_iw.v index eeab7b901..96911c3d2 100644 --- a/examples/pendulum-simulation/parallel_with_iw.v +++ b/examples/pendulum-simulation/parallel_with_iw.v @@ -6,14 +6,14 @@ import sim.args as simargs import sim.img fn main() { - args := simargs.parse_args(extra_workers: 1)? as simargs.ParallelArgs + args := simargs.parse_args(extra_workers: 1)! as simargs.ParallelArgs img_settings := img.image_settings_from_grid(args.grid) request_chan := chan &sim.SimRequest{cap: args.workers} result_chan := chan &sim.SimResult{cap: args.workers} - mut writer := img.ppm_writer_for_fname(args.filename, img_settings)? + mut writer := img.ppm_writer_for_fname(args.filename, img_settings)! mut workers := []thread{cap: args.workers + 1} mut bmark := benchmark.start() @@ -39,7 +39,7 @@ fn main() { workers << go img.image_worker(mut writer, result_chan, img_settings) - handle_request := fn [request_chan] (request &sim.SimRequest) ? { + handle_request := fn [request_chan] (request &sim.SimRequest) ! { request_chan <- request } diff --git a/examples/pendulum-simulation/sequential.v b/examples/pendulum-simulation/sequential.v index 9437400a1..d9d29334a 100644 --- a/examples/pendulum-simulation/sequential.v +++ b/examples/pendulum-simulation/sequential.v @@ -6,19 +6,19 @@ import sim.args as simargs import sim.img fn main() { - args := simargs.parse_args(sequential: true)? as simargs.SequentialArgs + args := simargs.parse_args(sequential: true)! as simargs.SequentialArgs mut bmark := benchmark.start() defer { bmark.measure(@FN) } - mut writer := img.ppm_writer_for_fname(args.filename, img.image_settings_from_grid(args.grid))? + mut writer := img.ppm_writer_for_fname(args.filename, img.image_settings_from_grid(args.grid))! defer { writer.close() } - handle_request := fn [mut writer] (request &sim.SimRequest) ? { + handle_request := fn [mut writer] (request &sim.SimRequest) ! { result := sim.compute_result(request) pixel := img.compute_pixel(result) return writer.handle_pixel(pixel) @@ -26,5 +26,5 @@ fn main() { sim.run(args.params, grid: args.grid, on_request: sim.SimRequestHandler(handle_request)) - writer.write()? + writer.write()! } diff --git a/examples/tcp_echo_server.v b/examples/tcp_echo_server.v index 72b2fedd5..7fa0b5887 100644 --- a/examples/tcp_echo_server.v +++ b/examples/tcp_echo_server.v @@ -9,11 +9,11 @@ import net // telnet 127.0.0.1 12345 fn main() { - mut server := net.listen_tcp(.ip6, ':12345')? - laddr := server.addr()? + mut server := net.listen_tcp(.ip6, ':12345')! + laddr := server.addr()! eprintln('Listen on $laddr ...') for { - mut socket := server.accept()? + mut socket := server.accept()! go handle_client(mut socket) } } diff --git a/examples/tcp_notify_echo_server.v b/examples/tcp_notify_echo_server.v index b20cbe000..d97ecb30f 100644 --- a/examples/tcp_notify_echo_server.v +++ b/examples/tcp_notify_echo_server.v @@ -14,21 +14,21 @@ fn main() { } // create TCP listener - mut listener := net.listen_tcp(.ip, 'localhost:9001')? + mut listener := net.listen_tcp(.ip, 'localhost:9001')! defer { listener.close() or {} } - addr := listener.addr()? + addr := listener.addr()! eprintln('Listening on $addr') eprintln('Type `stop` to stop the server') // create file descriptor notifier - mut notifier := notify.new()? + mut notifier := notify.new()! defer { notifier.close() or {} } - notifier.add(os.stdin().fd, .read)? - notifier.add(listener.sock.handle, .read)? + notifier.add(os.stdin().fd, .read)! + notifier.add(listener.sock.handle, .read)! for { for event in notifier.wait(time.infinite) { diff --git a/examples/viewer/file_scan.v b/examples/viewer/file_scan.v index 119c03e7b..a37e57c1e 100644 --- a/examples/viewer/file_scan.v +++ b/examples/viewer/file_scan.v @@ -150,10 +150,10 @@ fn (item_list Item_list) get_file_path() string { * Scan functions * ******************************************************************************/ -fn (mut item_list Item_list) scan_folder(path string, in_index int) ? { +fn (mut item_list Item_list) scan_folder(path string, in_index int) ! { println('Scanning [$path]') mut folder_list := []string{} - lst := os.ls(path)? + lst := os.ls(path)! // manage the single files for c, x in lst { @@ -171,7 +171,7 @@ fn (mut item_list Item_list) scan_folder(path string, in_index int) ? { if ext == .zip { item.i_type = .zip item_list.lst << item - item_list.scan_zip(pt, item_list.lst.len - 1)? + item_list.scan_zip(pt, item_list.lst.len - 1)! continue } if is_image(ext) == true { @@ -194,7 +194,7 @@ fn (mut item_list Item_list) scan_folder(path string, in_index int) ? { i_type: .folder } item_list.lst << item - item_list.scan_folder(pt, item_list.lst.len - 1)? + item_list.scan_folder(pt, item_list.lst.len - 1)! } // println(item_list.lst.len) // println("==================================") diff --git a/examples/viewer/zip_container.v b/examples/viewer/zip_container.v index 0c8bde0b4..73e8ce79b 100644 --- a/examples/viewer/zip_container.v +++ b/examples/viewer/zip_container.v @@ -11,14 +11,14 @@ import sokol.gfx import szip -fn (mut il Item_list) scan_zip(path string, in_index int) ? { +fn (mut il Item_list) scan_zip(path string, in_index int) ! { println('Scanning ZIP [$path]') - mut zp := szip.open(path, szip.CompressionLevel.no_compression, szip.OpenMode.read_only)? - n_entries := zp.total()? + mut zp := szip.open(path, szip.CompressionLevel.no_compression, szip.OpenMode.read_only)! + n_entries := zp.total()! // println(n_entries) for index in 0 .. n_entries { - zp.open_entry_by_index(index)? - is_dir := zp.is_dir()? + zp.open_entry_by_index(index)! + is_dir := zp.is_dir()! name := zp.name() size := zp.size() // println("$index ${name} ${size:10} $is_dir") @@ -47,7 +47,7 @@ fn (mut il Item_list) scan_zip(path string, in_index int) ? { zp.close() } -fn (mut app App) load_texture_from_zip() ?(gfx.Image, int, int) { +fn (mut app App) load_texture_from_zip() !(gfx.Image, int, int) { item := app.item_list.lst[app.item_list.item_index] // println("Load from zip [${item.path}]") @@ -58,15 +58,15 @@ fn (mut app App) load_texture_from_zip() ?(gfx.Image, int, int) { } app.zip_index = item.container_index // println("Opening the zip [${item.path}]") - app.zip = szip.open(item.path, szip.CompressionLevel.no_compression, szip.OpenMode.read_only)? + app.zip = szip.open(item.path, szip.CompressionLevel.no_compression, szip.OpenMode.read_only)! } // println("Now get the image") - app.zip.open_entry_by_index(item.container_item_index)? + app.zip.open_entry_by_index(item.container_item_index)! zip_entry_size := int(item.size) app.resize_buf_if_needed(zip_entry_size) - app.zip.read_entry_buf(app.mem_buf, app.mem_buf_size)? + app.zip.read_entry_buf(app.mem_buf, app.mem_buf_size)! app.zip.close_entry() return app.load_texture_from_buffer(app.mem_buf, zip_entry_size) } diff --git a/examples/vweb/vweb_assets/vweb_assets.v b/examples/vweb/vweb_assets/vweb_assets.v index 97fda32cc..93493d9da 100644 --- a/examples/vweb/vweb_assets/vweb_assets.v +++ b/examples/vweb/vweb_assets/vweb_assets.v @@ -17,7 +17,7 @@ fn main() { mut app := &App{} app.serve_static('/favicon.ico', 'favicon.ico') // Automatically make available known static mime types found in given directory. - os.chdir(os.dir(os.executable()))? + os.chdir(os.dir(os.executable()))! app.handle_static('assets', true) vweb.run(app, port) } diff --git a/examples/websocket/client-server/client.v b/examples/websocket/client-server/client.v index eac41cafb..cb20bdf36 100644 --- a/examples/websocket/client-server/client.v +++ b/examples/websocket/client-server/client.v @@ -8,7 +8,7 @@ import term // it connects to the server who will broadcast your messages // to all other connected clients fn main() { - mut ws := start_client()? + mut ws := start_client()! println(term.green('client $ws.id ready')) println('Write message and enter to send...') for { @@ -16,7 +16,7 @@ fn main() { if line == '' { break } - ws.write_string(line)? + ws.write_string(line)! } ws.close(1000, 'normal') or { println(term.red('panicing $err')) } unsafe { @@ -24,23 +24,23 @@ fn main() { } } -fn start_client() ?&websocket.Client { - mut ws := websocket.new_client('ws://localhost:30000')? +fn start_client() !&websocket.Client { + mut ws := websocket.new_client('ws://localhost:30000')! // mut ws := websocket.new_client('wss://echo.websocket.org:443')? // use on_open_ref if you want to send any reference object - ws.on_open(fn (mut ws websocket.Client) ? { + ws.on_open(fn (mut ws websocket.Client) ! { println(term.green('websocket connected to the server and ready to send messages...')) }) // use on_error_ref if you want to send any reference object - ws.on_error(fn (mut ws websocket.Client, err string) ? { + ws.on_error(fn (mut ws websocket.Client, err string) ! { println(term.red('error: $err')) }) // use on_close_ref if you want to send any reference object - ws.on_close(fn (mut ws websocket.Client, code int, reason string) ? { + ws.on_close(fn (mut ws websocket.Client, code int, reason string) ! { println(term.green('the connection to the server successfully closed')) }) // on new messages from other clients, display them in blue text - ws.on_message(fn (mut ws websocket.Client, msg &websocket.Message) ? { + ws.on_message(fn (mut ws websocket.Client, msg &websocket.Message) ! { if msg.payload.len > 0 { message := msg.payload.bytestr() println(term.blue('$message')) diff --git a/examples/websocket/client-server/server.v b/examples/websocket/client-server/server.v index d60aaa71a..afc9e2337 100644 --- a/examples/websocket/client-server/server.v +++ b/examples/websocket/client-server/server.v @@ -6,24 +6,24 @@ import term // this server accepts client connections and broadcast all messages to other connected clients fn main() { println('press ctrl-c to quit...') - start_server()? + start_server()! } -fn start_server() ? { +fn start_server() ! { mut s := websocket.new_server(.ip6, 30000, '') // Make that in execution test time give time to execute at least one time s.ping_interval = 100 - s.on_connect(fn (mut s websocket.ServerClient) ?bool { + s.on_connect(fn (mut s websocket.ServerClient) !bool { // Here you can look att the client info and accept or not accept // just returning a true/false if s.resource_name != '/' { return false } return true - })? + })! // on_message_ref, broadcast all incoming messages to all clients except the one sent it - s.on_message_ref(fn (mut ws websocket.Client, msg &websocket.Message, mut m websocket.Server) ? { + s.on_message_ref(fn (mut ws websocket.Client, msg &websocket.Message, mut m websocket.Server) ! { // for _, cli in m.clients { for i, _ in m.clients { mut c := m.clients[i] @@ -33,7 +33,7 @@ fn start_server() ? { } }, s) - s.on_close(fn (mut ws websocket.Client, code int, reason string) ? { + s.on_close(fn (mut ws websocket.Client, code int, reason string) ! { println(term.green('client ($ws.id) closed connection')) }) s.listen() or { println(term.red('error on server listen: $err')) } diff --git a/examples/websocket/ping.v b/examples/websocket/ping.v index 82e833861..967841470 100644 --- a/examples/websocket/ping.v +++ b/examples/websocket/ping.v @@ -6,27 +6,27 @@ import net.websocket fn main() { go start_server() time.sleep(100 * time.millisecond) - start_client()? + start_client()! } // start_server starts the websocket server, it receives messages // and send it back to the client that sent it -fn start_server() ? { +fn start_server() ! { mut s := websocket.new_server(.ip6, 30000, '') // Make that in execution test time give time to execute at least one time s.ping_interval = 100 - s.on_connect(fn (mut s websocket.ServerClient) ?bool { + s.on_connect(fn (mut s websocket.ServerClient) !bool { // Here you can look att the client info and accept or not accept // just returning a true/false if s.resource_name != '/' { return false } return true - })? - s.on_message(fn (mut ws websocket.Client, msg &websocket.Message) ? { + })! + s.on_message(fn (mut ws websocket.Client, msg &websocket.Message) ! { ws.write(msg.payload, msg.opcode) or { panic(err) } }) - s.on_close(fn (mut ws websocket.Client, code int, reason string) ? { + s.on_close(fn (mut ws websocket.Client, code int, reason string) ! { // println('client ($ws.id) closed connection') }) s.listen() or { println('error on server listen: $err') } @@ -37,23 +37,23 @@ fn start_server() ? { // start_client starts the websocket client, it writes a message to // the server and prints all the messages received -fn start_client() ? { - mut ws := websocket.new_client('ws://localhost:30000')? +fn start_client() ! { + mut ws := websocket.new_client('ws://localhost:30000')! // mut ws := websocket.new_client('wss://echo.websocket.org:443')? // use on_open_ref if you want to send any reference object - ws.on_open(fn (mut ws websocket.Client) ? { + ws.on_open(fn (mut ws websocket.Client) ! { println('open!') }) // use on_error_ref if you want to send any reference object - ws.on_error(fn (mut ws websocket.Client, err string) ? { + ws.on_error(fn (mut ws websocket.Client, err string) ! { println('error: $err') }) // use on_close_ref if you want to send any reference object - ws.on_close(fn (mut ws websocket.Client, code int, reason string) ? { + ws.on_close(fn (mut ws websocket.Client, code int, reason string) ! { println('closed') }) // use on_message_ref if you want to send any reference object - ws.on_message(fn (mut ws websocket.Client, msg &websocket.Message) ? { + ws.on_message(fn (mut ws websocket.Client, msg &websocket.Message) ! { if msg.payload.len > 0 { message := msg.payload.bytestr() println('client got type: $msg.opcode payload:\n$message') @@ -72,7 +72,7 @@ fn start_client() ? { } } -fn write_echo(mut ws websocket.Client) ? { +fn write_echo(mut ws websocket.Client) ! { message := 'echo this' for i := 0; i <= 10; i++ { // Server will send pings every 30 seconds diff --git a/vlib/builtin/string.v b/vlib/builtin/string.v index da1b25eb2..8aa5c8981 100644 --- a/vlib/builtin/string.v +++ b/vlib/builtin/string.v @@ -624,7 +624,7 @@ pub fn (s string) u64() u64 { // This method directly exposes the `parse_int` function from `strconv` // as a method on `string`. For more advanced features, // consider calling `strconv.common_parse_int` directly. -pub fn (s string) parse_uint(_base int, _bit_size int) ?u64 { +pub fn (s string) parse_uint(_base int, _bit_size int) !u64 { return strconv.parse_uint(s, _base, _bit_size) } @@ -644,7 +644,7 @@ pub fn (s string) parse_uint(_base int, _bit_size int) ?u64 { // This method directly exposes the `parse_uint` function from `strconv` // as a method on `string`. For more advanced features, // consider calling `strconv.common_parse_uint` directly. -pub fn (s string) parse_int(_base int, _bit_size int) ?i64 { +pub fn (s string) parse_int(_base int, _bit_size int) !i64 { return strconv.parse_int(s, _base, _bit_size) } diff --git a/vlib/dl/dl.v b/vlib/dl/dl.v index 2dbdac9fc..3035fe8cd 100644 --- a/vlib/dl/dl.v +++ b/vlib/dl/dl.v @@ -28,7 +28,7 @@ pub fn get_libname(libname string) string { // open_opt - loads the dynamic shared object. // Unlike open, open_opt return an option. -pub fn open_opt(filename string, flags int) ?voidptr { +pub fn open_opt(filename string, flags int) !voidptr { shared_object_handle := open(filename, flags) if shared_object_handle == 0 { e := dlerror() @@ -39,7 +39,7 @@ pub fn open_opt(filename string, flags int) ?voidptr { // sym_opt returns the address of a symbol in a given shared object, if found. // Unlike sym, sym_opt returns an option. -pub fn sym_opt(shared_object_handle voidptr, symbol string) ?voidptr { +pub fn sym_opt(shared_object_handle voidptr, symbol string) !voidptr { sym_handle := sym(shared_object_handle, symbol) if sym_handle == 0 { e := dlerror() diff --git a/vlib/flag/flag.v b/vlib/flag/flag.v index e14dd9071..246841645 100644 --- a/vlib/flag/flag.v +++ b/vlib/flag/flag.v @@ -71,7 +71,7 @@ pub fn (af []Flag) str() string { // That structure is created with `mut parser := flag.new_flag_parser(os.args)`, // The returned instance can be further customised by calling various methods, // for specifying the accepted options and their values. The user should finally -// call `rest := parser.finalize()?` to get the rest of the non optional arguments +// call `rest := parser.finalize()!` to get the rest of the non optional arguments // (if there are any left). pub struct FlagParser { pub: @@ -278,7 +278,7 @@ fn (mut fs FlagParser) parse_value(longhand string, shorthand u8) []string { // special: it is allowed to define bool flags without value // -> '--flag' is parsed as true // -> '--flag' is equal to '--flag=true' -fn (mut fs FlagParser) parse_bool_value(longhand string, shorthand u8) ?string { +fn (mut fs FlagParser) parse_bool_value(longhand string, shorthand u8) !string { { full := '--$longhand' for i, arg in fs.args { @@ -317,7 +317,7 @@ fn (mut fs FlagParser) parse_bool_value(longhand string, shorthand u8) ?string { // bool_opt returns an option with the bool value of the given command line flag, named `name`. // It returns an error, when the flag is not given by the user. // This version supports abbreviations. -pub fn (mut fs FlagParser) bool_opt(name string, abbr u8, usage string) ?bool { +pub fn (mut fs FlagParser) bool_opt(name string, abbr u8, usage string) !bool { mut res := false { fs.add_flag(name, abbr, usage, '') @@ -354,7 +354,7 @@ pub fn (mut fs FlagParser) int_multi(name string, abbr u8, usage string) []int { // int_opt returns an option with the integer value, associated with the flag in `name`. // When the flag is not given by the user, it returns an error. // This version supports abbreviations. -pub fn (mut fs FlagParser) int_opt(name string, abbr u8, usage string) ?int { +pub fn (mut fs FlagParser) int_opt(name string, abbr u8, usage string) !int { mut res := 0 { fs.add_flag(name, abbr, usage, '') @@ -393,7 +393,7 @@ pub fn (mut fs FlagParser) float_multi(name string, abbr u8, usage string) []f64 // float_opt returns an option with the floating point value, associated with the flag in `name`. // When the flag is not given by the user, it returns an error. // This version supports abbreviations. -pub fn (mut fs FlagParser) float_opt(name string, abbr u8, usage string) ?f64 { +pub fn (mut fs FlagParser) float_opt(name string, abbr u8, usage string) !f64 { mut res := 0.0 { fs.add_flag(name, abbr, usage, '') @@ -426,7 +426,7 @@ pub fn (mut fs FlagParser) string_multi(name string, abbr u8, usage string) []st // string_opt returns an option with the string value, associated with the flag in `name`. // When the flag is not given by the user, it returns an error. // This version supports abbreviations. -pub fn (mut fs FlagParser) string_opt(name string, abbr u8, usage string) ?string { +pub fn (mut fs FlagParser) string_opt(name string, abbr u8, usage string) !string { mut res := '' { fs.add_flag(name, abbr, usage, '') @@ -451,7 +451,7 @@ pub fn (mut fs FlagParser) string(name string, abbr u8, sdefault string, usage s // limit_free_args_to_at_least restricts the list of free arguments (non options) to be // at least `n` in length. If the user gives less free arguments to the program, // the parser will return an error. -pub fn (mut fs FlagParser) limit_free_args_to_at_least(n int) ? { +pub fn (mut fs FlagParser) limit_free_args_to_at_least(n int) ! { if n > flag.max_args_number { return error('flag.limit_free_args_to_at_least expect n to be smaller than $flag.max_args_number') } @@ -464,7 +464,7 @@ pub fn (mut fs FlagParser) limit_free_args_to_at_least(n int) ? { // limit_free_args_to_exactly restricts the list of free arguments (non options) to be // at exactly `n` in length. If the user gives more or less free arguments to the program, // the parser will return an error. -pub fn (mut fs FlagParser) limit_free_args_to_exactly(n int) ? { +pub fn (mut fs FlagParser) limit_free_args_to_exactly(n int) ! { if n > flag.max_args_number { return error('flag.limit_free_args_to_exactly expect n to be smaller than $flag.max_args_number') } @@ -478,7 +478,7 @@ pub fn (mut fs FlagParser) limit_free_args_to_exactly(n int) ? { // limit_free_args restricts the list of free arguments (non options) to be between // `min` and `max` in length. If the user gives more or less free arguments to the program, // the parser will return an error. -pub fn (mut fs FlagParser) limit_free_args(min int, max int) ? { +pub fn (mut fs FlagParser) limit_free_args(min int, max int) ! { if min > max { return error('flag.limit_free_args expect min < max, got $min >= $max') } @@ -578,7 +578,7 @@ pub fn (fs FlagParser) usage() string { // find_existing_flag looks up the given flag by name, and returns // it, if it was found in the FlagParser. If it was not, it returns an error. -fn (mut fs FlagParser) find_existing_flag(fname string) ?Flag { +fn (mut fs FlagParser) find_existing_flag(fname string) !Flag { for f in fs.flags { if f.name == fname { return f @@ -614,7 +614,7 @@ fn (mut fs FlagParser) handle_builtin_options() { // The remaining arguments are returned in the same order they are // defined on the command line. If additional flags are found, i.e. // (things starting with '--' or '-'), it returns an error. -pub fn (mut fs FlagParser) finalize() ?[]string { +pub fn (mut fs FlagParser) finalize() ![]string { fs.handle_builtin_options() mut remaining := fs.args.clone() if !fs.allow_unknown_args { diff --git a/vlib/flag/flag_test.v b/vlib/flag/flag_test.v index 1d6497d64..1c3ac7af2 100644 --- a/vlib/flag/flag_test.v +++ b/vlib/flag/flag_test.v @@ -153,9 +153,9 @@ fn test_finalize_returns_error_for_unknown_flags_short() { assert finalized.len < 0 // expect error to be returned } -fn test_allow_to_build_usage_message() ? { +fn test_allow_to_build_usage_message() { mut fp := flag.new_flag_parser([]) - fp.limit_free_args(1, 4)? + fp.limit_free_args(1, 4)! fp.application('flag_tool') fp.version('v0.0.0') fp.description('some short information about this tool') @@ -194,9 +194,9 @@ fn test_if_no_options_given_usage_message_does_not_contain_options() { assert !fp.usage().contains('Options:') } -fn test_free_args_could_be_limited() ? { +fn test_free_args_could_be_limited() { mut fp1 := flag.new_flag_parser(['a', 'b', 'c']) - fp1.limit_free_args(1, 4)? + fp1.limit_free_args(1, 4)! args := fp1.finalize() or { assert false return @@ -206,9 +206,9 @@ fn test_free_args_could_be_limited() ? { assert args[2] == 'c' } -fn test_error_for_to_few_free_args() ? { +fn test_error_for_to_few_free_args() { mut fp1 := flag.new_flag_parser(['a', 'b', 'c']) - fp1.limit_free_args(5, 6)? + fp1.limit_free_args(5, 6)! args := fp1.finalize() or { assert err.msg().starts_with('Expected at least 5 arguments') return @@ -216,9 +216,9 @@ fn test_error_for_to_few_free_args() ? { assert args.len < 0 // expect an error and need to use args } -fn test_error_for_to_much_free_args() ? { +fn test_error_for_to_much_free_args() { mut fp1 := flag.new_flag_parser(['a', 'b', 'c']) - fp1.limit_free_args(1, 2)? + fp1.limit_free_args(1, 2)! args := fp1.finalize() or { assert err.msg().starts_with('Expected at most 2 arguments') return @@ -226,9 +226,9 @@ fn test_error_for_to_much_free_args() ? { assert args.len < 0 // expect an error and need to use args } -fn test_could_expect_no_free_args() ? { +fn test_could_expect_no_free_args() { mut fp1 := flag.new_flag_parser(['a']) - fp1.limit_free_args(0, 0)? + fp1.limit_free_args(0, 0)! args := fp1.finalize() or { assert err.msg().starts_with('Expected no arguments') return @@ -383,7 +383,7 @@ fn test_optional_flags() { assert b == 'some_default_value' } -fn test_dashdash_acts_as_parser_full_stop() ? { +fn test_dashdash_acts_as_parser_full_stop() { mut fp := flag.new_flag_parser(['-b', '5', '--', '-d', '-x', '-b', '4', '-a', '-c', 'hello', 'some', 'other', 'parameters']) a := fp.bool_opt('a-bool-flag', `a`, '') or { false } @@ -392,17 +392,17 @@ fn test_dashdash_acts_as_parser_full_stop() ? { assert a == false assert b == 5 assert c == 'default' - args := fp.finalize()? + args := fp.finalize()! assert args.len > 0 assert args[0] != '--' assert args == ['-d', '-x', '-b', '4', '-a', '-c', 'hello', 'some', 'other', 'parameters'] } -fn test_dashdash_acts_as_parser_full_stop_dashdash_at_end() ? { +fn test_dashdash_acts_as_parser_full_stop_dashdash_at_end() { mut fp := flag.new_flag_parser(['-b', '5', '-b', '4', 'other', 'params', '--']) b := fp.int_multi('an-int-flag', `b`, '') assert b == [5, 4] - args := fp.finalize()? + args := fp.finalize()! assert args.len > 0 } diff --git a/vlib/io/buffered_reader.v b/vlib/io/buffered_reader.v index cf25a4f5f..4f9b1bcf8 100644 --- a/vlib/io/buffered_reader.v +++ b/vlib/io/buffered_reader.v @@ -107,9 +107,9 @@ pub fn (r BufferedReader) end_of_stream() bool { // read_line attempts to read a line from the buffered reader // it will read until it finds a new line character (\n) or // the end of stream -pub fn (mut r BufferedReader) read_line() ?string { +pub fn (mut r BufferedReader) read_line() !string { if r.end_of_stream { - return none + return error('none') } mut line := []u8{} for { @@ -119,7 +119,7 @@ pub fn (mut r BufferedReader) read_line() ?string { // We are at the end of the stream if line.len == 0 { // we had nothing so return nothing - return none + return error('none') } return line.bytestr() } @@ -144,5 +144,5 @@ pub fn (mut r BufferedReader) read_line() ?string { line << r.buf[r.offset..i] r.offset = i } - return none + return error('none') } diff --git a/vlib/io/io.v b/vlib/io/io.v index cb644093a..56ef4d718 100644 --- a/vlib/io/io.v +++ b/vlib/io/io.v @@ -4,7 +4,7 @@ const ( buf_max_len = 1024 ) -pub fn cp(mut src Reader, mut dst Writer) ? { +pub fn cp(mut src Reader, mut dst Writer) ! { mut buf := []u8{len: io.buf_max_len} for { len := src.read(mut buf) or { break } diff --git a/vlib/io/io_cp_test.v b/vlib/io/io_cp_test.v index a53fc91a1..84f756f09 100644 --- a/vlib/io/io_cp_test.v +++ b/vlib/io/io_cp_test.v @@ -1,13 +1,13 @@ import io import os -fn test_cp() ? { +fn test_cp() { mut f := os.open(@FILE) or { panic(err) } defer { f.close() } mut r := io.new_buffered_reader(reader: f) mut stdout := os.stdout() - io.cp(mut r, mut stdout)? + io.cp(mut r, mut stdout)! assert true } diff --git a/vlib/io/io_test.v b/vlib/io/io_test.v index 70c0c6d26..396e35931 100644 --- a/vlib/io/io_test.v +++ b/vlib/io/io_test.v @@ -21,9 +21,9 @@ fn (mut b Buf) read(mut buf []u8) !int { return n } -fn (mut w Writ) write(buf []u8) ?int { +fn (mut w Writ) write(buf []u8) !int { if buf.len <= 0 { - return none + return error('none') } w.bytes << buf return buf.len diff --git a/vlib/io/multi_writer.v b/vlib/io/multi_writer.v index 4007dae65..18e805371 100644 --- a/vlib/io/multi_writer.v +++ b/vlib/io/multi_writer.v @@ -22,9 +22,9 @@ pub mut: // written. If any writer fails to write the full length an error is returned // and writing to other writers stops. If any writer returns an error the error // is returned immediately and writing to other writers stops. -pub fn (mut m MultiWriter) write(buf []u8) ?int { +pub fn (mut m MultiWriter) write(buf []u8) !int { for mut w in m.writers { - n := w.write(buf)? + n := w.write(buf)! if n != buf.len { return error('io: incomplete write to writer of MultiWriter') } diff --git a/vlib/io/multi_writer_test.v b/vlib/io/multi_writer_test.v index e62b81e40..14ccd371f 100644 --- a/vlib/io/multi_writer_test.v +++ b/vlib/io/multi_writer_test.v @@ -43,7 +43,7 @@ pub mut: bytes []u8 } -fn (mut w TestWriter) write(buf []u8) ?int { +fn (mut w TestWriter) write(buf []u8) !int { w.bytes << buf return buf.len } @@ -53,7 +53,7 @@ pub mut: bytes []u8 } -fn (mut w TestIncompleteWriter) write(buf []u8) ?int { +fn (mut w TestIncompleteWriter) write(buf []u8) !int { b := buf[..buf.len - 1] w.bytes << b return b.len @@ -61,6 +61,6 @@ fn (mut w TestIncompleteWriter) write(buf []u8) ?int { struct TestErrorWriter {} -fn (mut w TestErrorWriter) write(buf []u8) ?int { +fn (mut w TestErrorWriter) write(buf []u8) !int { return error('error writer errored') } diff --git a/vlib/io/reader.v b/vlib/io/reader.v index 6bcc77942..570dad83c 100644 --- a/vlib/io/reader.v +++ b/vlib/io/reader.v @@ -44,7 +44,7 @@ mut: // read_all reads all bytes from a reader until either a 0 length read // or if read_to_end_of_stream is true then the end of the stream (`none`) -pub fn read_all(config ReadAllConfig) ?[]u8 { +pub fn read_all(config ReadAllConfig) ![]u8 { mut r := config.reader read_till_eof := config.read_to_end_of_stream @@ -65,11 +65,11 @@ pub fn read_all(config ReadAllConfig) ?[]u8 { // read_any reads any available bytes from a reader // (until the reader returns a read of 0 length) -pub fn read_any(mut r Reader) ?[]u8 { +pub fn read_any(mut r Reader) ![]u8 { mut b := []u8{len: io.read_all_len} mut read := 0 for { - new_read := r.read(mut b[read..]) or { return none } + new_read := r.read(mut b[read..]) or { return error('none') } read += new_read if new_read == 0 { break @@ -83,5 +83,5 @@ pub fn read_any(mut r Reader) ?[]u8 { // RandomReader represents a stream of data that can be read from at a random location pub interface RandomReader { - read_from(pos u64, mut buf []u8) ?int + read_from(pos u64, mut buf []u8) !int } diff --git a/vlib/io/readerwriter.v b/vlib/io/readerwriter.v index b03c891a0..7867781bb 100644 --- a/vlib/io/readerwriter.v +++ b/vlib/io/readerwriter.v @@ -18,7 +18,7 @@ pub fn (mut r ReaderWriterImpl) read(mut buf []u8) !int { return r.r.read(mut buf) } -pub fn (mut r ReaderWriterImpl) write(buf []u8) ?int { +pub fn (mut r ReaderWriterImpl) write(buf []u8) !int { return r.w.write(buf) } diff --git a/vlib/io/util/util.v b/vlib/io/util/util.v index 895a1c06b..9aadca9b0 100644 --- a/vlib/io/util/util.v +++ b/vlib/io/util/util.v @@ -14,7 +14,7 @@ pub struct TempFileOptions { } // temp_file returns an uniquely named, open, writable, `os.File` and it's path -pub fn temp_file(tfo TempFileOptions) ?(os.File, string) { +pub fn temp_file(tfo TempFileOptions) !(os.File, string) { mut d := tfo.path if d == '' { d = os.temp_dir() @@ -47,7 +47,7 @@ pub struct TempDirOptions { } // temp_dir returns an uniquely named, writable, directory path -pub fn temp_dir(tdo TempFileOptions) ?string { +pub fn temp_dir(tdo TempFileOptions) !string { mut d := tdo.path if d == '' { d = os.temp_dir() diff --git a/vlib/io/writer.v b/vlib/io/writer.v index 3cda29cc5..077f5bfda 100644 --- a/vlib/io/writer.v +++ b/vlib/io/writer.v @@ -3,11 +3,11 @@ module io // Writer represents a stream of data that can be wrote to pub interface Writer { mut: - write(buf []u8) ?int + write(buf []u8) !int } // RandomWriter represents a stream of data that can be wrote to // at a random pos pub interface RandomWriter { - write_to(pos u64, buf []u8) ?int + write_to(pos u64, buf []u8) !int } diff --git a/vlib/net/address.v b/vlib/net/address.v index 4e81be2c8..370b97b31 100644 --- a/vlib/net/address.v +++ b/vlib/net/address.v @@ -44,15 +44,15 @@ fn new_ip(port u16, addr [4]u8) Addr { return a } -fn temp_unix() ?Addr { +fn temp_unix() !Addr { // create a temp file to get a filename // close it // remove it // then reuse the filename - mut file, filename := util.temp_file()? + mut file, filename := util.temp_file()! file.close() - os.rm(filename)? - addrs := resolve_addrs(filename, .unix, .udp)? + os.rm(filename)! + addrs := resolve_addrs(filename, .unix, .udp)! return addrs[0] } @@ -114,7 +114,7 @@ fn (a Addr) len() u32 { } } -pub fn resolve_addrs(addr string, family AddrFamily, @type SocketType) ?[]Addr { +pub fn resolve_addrs(addr string, family AddrFamily, @type SocketType) ![]Addr { match family { .ip, .ip6, .unspec { return resolve_ipaddrs(addr, family, @type) @@ -143,9 +143,9 @@ pub fn resolve_addrs(addr string, family AddrFamily, @type SocketType) ?[]Addr { } } -pub fn resolve_addrs_fuzzy(addr string, @type SocketType) ?[]Addr { +pub fn resolve_addrs_fuzzy(addr string, @type SocketType) ![]Addr { if addr.len == 0 { - return none + return error('none') } // Use a small heuristic to figure out what address family this is @@ -160,8 +160,8 @@ pub fn resolve_addrs_fuzzy(addr string, @type SocketType) ?[]Addr { return resolve_addrs(addr, .unix, @type) } -pub fn resolve_ipaddrs(addr string, family AddrFamily, typ SocketType) ?[]Addr { - address, port := split_address(addr)? +pub fn resolve_ipaddrs(addr string, family AddrFamily, typ SocketType) ![]Addr { + address, port := split_address(addr)! if addr[0] == `:` { match family { @@ -191,10 +191,10 @@ pub fn resolve_ipaddrs(addr string, family AddrFamily, typ SocketType) ?[]Addr { // This might look silly but is recommended by MSDN $if windows { - socket_error(0 - C.getaddrinfo(&char(address.str), &char(sport.str), &hints, &results))? + socket_error(0 - C.getaddrinfo(&char(address.str), &char(sport.str), &hints, &results))! } $else { x := C.getaddrinfo(&char(address.str), &char(sport.str), &hints, &results) - wrap_error(x)? + wrap_error(x)! } defer { diff --git a/vlib/net/common.v b/vlib/net/common.v index 4fae84d7c..4ce01d43d 100644 --- a/vlib/net/common.v +++ b/vlib/net/common.v @@ -17,18 +17,18 @@ pub const no_timeout = time.Duration(0) pub const infinite_timeout = time.infinite // Shutdown shutsdown a socket and closes it -fn shutdown(handle int) ? { +fn shutdown(handle int) ! { $if windows { C.shutdown(handle, C.SD_BOTH) - socket_error(C.closesocket(handle))? + socket_error(C.closesocket(handle))! } $else { C.shutdown(handle, C.SHUT_RDWR) - socket_error(C.close(handle))? + socket_error(C.close(handle))! } } // Select waits for an io operation (specified by parameter `test`) to be available -fn @select(handle int, test Select, timeout time.Duration) ?bool { +fn @select(handle int, test Select, timeout time.Duration) !bool { set := C.fd_set{} C.FD_ZERO(&set) @@ -52,13 +52,13 @@ fn @select(handle int, test Select, timeout time.Duration) ?bool { match test { .read { - socket_error(C.@select(handle + 1, &set, C.NULL, C.NULL, timeval_timeout))? + socket_error(C.@select(handle + 1, &set, C.NULL, C.NULL, timeval_timeout))! } .write { - socket_error(C.@select(handle + 1, C.NULL, &set, C.NULL, timeval_timeout))? + socket_error(C.@select(handle + 1, C.NULL, &set, C.NULL, timeval_timeout))! } .except { - socket_error(C.@select(handle + 1, C.NULL, C.NULL, &set, timeval_timeout))? + socket_error(C.@select(handle + 1, C.NULL, C.NULL, &set, timeval_timeout))! } } @@ -66,7 +66,7 @@ fn @select(handle int, test Select, timeout time.Duration) ?bool { } [inline] -fn select_deadline(handle int, test Select, deadline time.Time) ?bool { +fn select_deadline(handle int, test Select, deadline time.Time) !bool { // if we have a 0 deadline here then the timeout that was passed was infinite... infinite := deadline.unix_time() == 0 for infinite || time.now() <= deadline { @@ -89,7 +89,7 @@ fn select_deadline(handle int, test Select, deadline time.Time) ?bool { } // wait_for_common wraps the common wait code -fn wait_for_common(handle int, deadline time.Time, timeout time.Duration, test Select) ? { +fn wait_for_common(handle int, deadline time.Time, timeout time.Duration, test Select) ! { // Convert timeouts to deadlines real_deadline := if timeout == net.infinite_timeout { time.unix(0) @@ -104,7 +104,7 @@ fn wait_for_common(handle int, deadline time.Time, timeout time.Duration, test S time.now().add(timeout) } - ready := select_deadline(handle, test, real_deadline)? + ready := select_deadline(handle, test, real_deadline)! if ready { return @@ -114,11 +114,11 @@ fn wait_for_common(handle int, deadline time.Time, timeout time.Duration, test S } // wait_for_write waits for a write io operation to be available -fn wait_for_write(handle int, deadline time.Time, timeout time.Duration) ? { +fn wait_for_write(handle int, deadline time.Time, timeout time.Duration) ! { return wait_for_common(handle, deadline, timeout, .write) } // wait_for_read waits for a read io operation to be available -fn wait_for_read(handle int, deadline time.Time, timeout time.Duration) ? { +fn wait_for_read(handle int, deadline time.Time, timeout time.Duration) ! { return wait_for_common(handle, deadline, timeout, .read) } diff --git a/vlib/net/errors.v b/vlib/net/errors.v index 6cbc1a445..410aa8372 100644 --- a/vlib/net/errors.v +++ b/vlib/net/errors.v @@ -21,11 +21,11 @@ pub const ( err_connection_refused = error_with_code('net: connection refused', errors_base + 10) ) -pub fn socket_error_message(potential_code int, s string) ?int { +pub fn socket_error_message(potential_code int, s string) !int { return socket_error(potential_code) or { return error('$err.msg(); $s') } } -pub fn socket_error(potential_code int) ?int { +pub fn socket_error(potential_code int) !int { $if windows { if potential_code < 0 { last_error_int := C.WSAGetLastError() @@ -43,7 +43,7 @@ pub fn socket_error(potential_code int) ?int { return potential_code } -pub fn wrap_error(error_code int) ? { +pub fn wrap_error(error_code int) ! { if error_code == 0 { return } @@ -59,17 +59,17 @@ pub fn wrap_error(error_code int) ? { // connection termination and returns none // e.g. res := wrap_read_result(C.recv(c.sock.handle, voidptr(buf_ptr), len, 0))? [inline] -fn wrap_read_result(result int) ?int { +fn wrap_read_result(result int) !int { if result == 0 { - return none + return error('none') } return result } [inline] -fn wrap_write_result(result int) ?int { +fn wrap_write_result(result int) !int { if result == 0 { - return none + return error('none') } return result } diff --git a/vlib/net/ftp/ftp.v b/vlib/net/ftp/ftp.v index f6fc40f5a..219bca250 100644 --- a/vlib/net/ftp/ftp.v +++ b/vlib/net/ftp/ftp.v @@ -42,7 +42,7 @@ mut: port int } -fn (mut dtp DTP) read() ?[]u8 { +fn (mut dtp DTP) read() ![]u8 { mut data := []u8{} mut buf := []u8{len: 1024} for { @@ -75,15 +75,15 @@ pub fn new() FTP { return f } -fn (mut zftp FTP) write(data string) ?int { +fn (mut zftp FTP) write(data string) !int { $if debug { println('FTP.v >>> $data') } return zftp.conn.write('$data\r\n'.bytes()) } -fn (mut zftp FTP) read() ?(int, string) { - mut data := zftp.reader.read_line()? +fn (mut zftp FTP) read() !(int, string) { + mut data := zftp.reader.read_line()! $if debug { println('FTP.v <<< $data') } @@ -93,7 +93,7 @@ fn (mut zftp FTP) read() ?(int, string) { code := data[..3].int() if data[3] == `-` { for { - data = zftp.reader.read_line()? + data = zftp.reader.read_line()! if data[..3].int() == code && data[3] != `-` { break } @@ -103,10 +103,10 @@ fn (mut zftp FTP) read() ?(int, string) { } // connect establishes an FTP connection to the host at `ip` port 21. -pub fn (mut zftp FTP) connect(ip string) ?bool { - zftp.conn = net.dial_tcp('$ip:21')? +pub fn (mut zftp FTP) connect(ip string) !bool { + zftp.conn = net.dial_tcp('$ip:21')! zftp.reader = io.new_buffered_reader(reader: zftp.conn) - code, _ := zftp.read()? + code, _ := zftp.read()! if code == ftp.connected { return true } @@ -114,14 +114,14 @@ pub fn (mut zftp FTP) connect(ip string) ?bool { } // login sends the "USER `user`" and "PASS `passwd`" commands to the remote host. -pub fn (mut zftp FTP) login(user string, passwd string) ?bool { +pub fn (mut zftp FTP) login(user string, passwd string) !bool { zftp.write('USER $user') or { $if debug { println('ERROR sending user') } return false } - mut code, _ := zftp.read()? + mut code, _ := zftp.read()! if code == ftp.logged_in { return true } @@ -134,7 +134,7 @@ pub fn (mut zftp FTP) login(user string, passwd string) ?bool { } return false } - code, _ = zftp.read()? + code, _ = zftp.read()! if code == ftp.logged_in { return true } @@ -142,15 +142,15 @@ pub fn (mut zftp FTP) login(user string, passwd string) ?bool { } // close closes the FTP connection. -pub fn (mut zftp FTP) close() ? { - zftp.write('QUIT')? - zftp.conn.close()? +pub fn (mut zftp FTP) close() ! { + zftp.write('QUIT')! + zftp.conn.close()! } // pwd returns the current working directory on the remote host for the logged in user. -pub fn (mut zftp FTP) pwd() ?string { - zftp.write('PWD')? - _, data := zftp.read()? +pub fn (mut zftp FTP) pwd() !string { + zftp.write('PWD')! + _, data := zftp.read()! spl := data.split('"') // " if spl.len >= 2 { return spl[1] @@ -159,9 +159,9 @@ pub fn (mut zftp FTP) pwd() ?string { } // cd changes the current working directory to the specified remote directory `dir`. -pub fn (mut zftp FTP) cd(dir string) ? { +pub fn (mut zftp FTP) cd(dir string) ! { zftp.write('CWD $dir') or { return } - mut code, mut data := zftp.read()? + mut code, mut data := zftp.read()! match int(code) { ftp.denied { $if debug { @@ -169,7 +169,7 @@ pub fn (mut zftp FTP) cd(dir string) ? { } } ftp.complete { - code, data = zftp.read()? + code, data = zftp.read()! } else {} } @@ -178,7 +178,7 @@ pub fn (mut zftp FTP) cd(dir string) ? { } } -fn new_dtp(msg string) ?&DTP { +fn new_dtp(msg string) !&DTP { if !is_dtp_message_valid(msg) { return error('Bad message') } @@ -194,32 +194,32 @@ fn new_dtp(msg string) ?&DTP { return dtp } -fn (mut zftp FTP) pasv() ?&DTP { - zftp.write('PASV')? - code, data := zftp.read()? +fn (mut zftp FTP) pasv() !&DTP { + zftp.write('PASV')! + code, data := zftp.read()! $if debug { println('pass: $data') } if code != ftp.passive_mode { return error('pasive mode not allowed') } - dtp := new_dtp(data)? + dtp := new_dtp(data)! return dtp } // dir returns a list of the files in the current working directory. -pub fn (mut zftp FTP) dir() ?[]string { +pub fn (mut zftp FTP) dir() ![]string { mut dtp := zftp.pasv() or { return error('Cannot establish data connection') } - zftp.write('LIST')? - code, _ := zftp.read()? + zftp.write('LIST')! + code, _ := zftp.read()! if code == ftp.denied { return error('`LIST` denied') } if code != ftp.open_data_connection { return error('Data channel empty') } - list_dir := dtp.read()? - result, _ := zftp.read()? + list_dir := dtp.read()! + result, _ := zftp.read()! if result != ftp.close_data_connection { println('`LIST` not ok') } @@ -235,17 +235,17 @@ pub fn (mut zftp FTP) dir() ?[]string { } // get retrieves `file` from the remote host. -pub fn (mut zftp FTP) get(file string) ?[]u8 { +pub fn (mut zftp FTP) get(file string) ![]u8 { mut dtp := zftp.pasv() or { return error('Cannot stablish data connection') } - zftp.write('RETR $file')? - code, _ := zftp.read()? + zftp.write('RETR $file')! + code, _ := zftp.read()! if code == ftp.denied { return error('Permission denied') } if code != ftp.open_data_connection { return error('Data connection not ready') } - blob := dtp.read()? + blob := dtp.read()! dtp.close() return blob } diff --git a/vlib/net/ftp/ftp_test.v b/vlib/net/ftp/ftp_test.v index 8e03e0063..8fe899a56 100644 --- a/vlib/net/ftp/ftp_test.v +++ b/vlib/net/ftp/ftp_test.v @@ -11,17 +11,17 @@ fn test_ftp_cleint() { ftp_client_test_inside() or { panic(err) } } -fn ftp_client_test_inside() ? { +fn ftp_client_test_inside() ! { mut zftp := ftp.new() // eprintln(zftp) defer { zftp.close() or { panic(err) } } - connect_result := zftp.connect('ftp.redhat.com')? + connect_result := zftp.connect('ftp.redhat.com')! assert connect_result - login_result := zftp.login('ftp', 'ftp')? + login_result := zftp.login('ftp', 'ftp')! assert login_result - pwd := zftp.pwd()? + pwd := zftp.pwd()! assert pwd.len > 0 zftp.cd('/') or { assert false diff --git a/vlib/net/http/backend_nix.c.v b/vlib/net/http/backend_nix.c.v index e1a7a914c..abf2b0874 100644 --- a/vlib/net/http/backend_nix.c.v +++ b/vlib/net/http/backend_nix.c.v @@ -6,14 +6,14 @@ module http import net.ssl import strings -fn (req &Request) ssl_do(port int, method Method, host_name string, path string) ?Response { +fn (req &Request) ssl_do(port int, method Method, host_name string, path string) !Response { mut ssl_conn := ssl.new_ssl_conn( verify: req.verify cert: req.cert cert_key: req.cert_key validate: req.validate in_memory_verification: req.in_memory_verification - )? + )! ssl_conn.dial(host_name, port) or { return err } req_headers := req.build_request_headers(method, host_name, path) @@ -38,7 +38,7 @@ fn (req &Request) ssl_do(port int, method Method, host_name string, path string) } unsafe { content.write_ptr(bp, len) } } - ssl_conn.shutdown()? + ssl_conn.shutdown()! response_text := content.str() $if trace_http_response ? { eprintln('< $response_text') diff --git a/vlib/net/http/backend_windows.c.v b/vlib/net/http/backend_windows.c.v index 51f6a3558..6371c7faf 100644 --- a/vlib/net/http/backend_windows.c.v +++ b/vlib/net/http/backend_windows.c.v @@ -13,7 +13,7 @@ $if gcboehm ? { fn C.new_tls_context() C.TlsContext -fn (req &Request) ssl_do(port int, method Method, host_name string, path string) ?Response { +fn (req &Request) ssl_do(port int, method Method, host_name string, path string) !Response { mut ctx := C.new_tls_context() C.vschannel_init(&ctx) mut buff := unsafe { malloc_noscan(C.vsc_init_resp_buff_size) } diff --git a/vlib/net/http/cookie.v b/vlib/net/http/cookie.v index 46647ce93..af8e3c1a2 100644 --- a/vlib/net/http/cookie.v +++ b/vlib/net/http/cookie.v @@ -294,7 +294,7 @@ pub fn is_cookie_domain_name(_s string) bool { return ok } -fn parse_cookie_value(_raw string, allow_double_quote bool) ?string { +fn parse_cookie_value(_raw string, allow_double_quote bool) !string { mut raw := _raw // Strip the quotes, if present if allow_double_quote && raw.len > 1 && raw[0] == `"` && raw[raw.len - 1] == `"` { @@ -320,7 +320,7 @@ fn is_cookie_name_valid(name string) bool { return true } -fn parse_cookie(line string) ?Cookie { +fn parse_cookie(line string) !Cookie { mut parts := line.trim_space().split(';') if parts.len == 1 && parts[0] == '' { return error('malformed cookie') diff --git a/vlib/net/http/download.v b/vlib/net/http/download.v index eab6df8d7..d750c7718 100644 --- a/vlib/net/http/download.v +++ b/vlib/net/http/download.v @@ -7,7 +7,7 @@ import os // download_file retrieves a document from the URL `url`, // and saves it in the output file path `out_file_path`. -pub fn download_file(url string, out_file_path string) ? { +pub fn download_file(url string, out_file_path string) ! { $if debug_http ? { println('http.download_file url=$url out_file_path=$out_file_path') } @@ -18,7 +18,7 @@ pub fn download_file(url string, out_file_path string) ? { $if debug_http ? { println('http.download_file saving $s.body.len bytes') } - os.write_file(out_file_path, s.body)? + os.write_file(out_file_path, s.body)! } // TODO: implement download_file_with_progress diff --git a/vlib/net/http/header.v b/vlib/net/http/header.v index 440206554..05ac32327 100644 --- a/vlib/net/http/header.v +++ b/vlib/net/http/header.v @@ -363,9 +363,9 @@ pub fn new_header_from_map(kvs map[CommonHeader]string) Header { } // new_custom_header_from_map creates a Header from string key value pairs -pub fn new_custom_header_from_map(kvs map[string]string) ?Header { +pub fn new_custom_header_from_map(kvs map[string]string) !Header { mut h := new_header() - h.add_custom_map(kvs)? + h.add_custom_map(kvs)! return h } @@ -378,8 +378,8 @@ pub fn (mut h Header) add(key CommonHeader, value string) { // add_custom appends a value to a custom header key. This function will // return an error if the key contains invalid header characters. -pub fn (mut h Header) add_custom(key string, value string) ? { - is_valid(key)? +pub fn (mut h Header) add_custom(key string, value string) ! { + is_valid(key)! h.data[key] << value h.add_key(key) } @@ -392,9 +392,9 @@ pub fn (mut h Header) add_map(kvs map[CommonHeader]string) { } // add_custom_map appends the value for each custom header key. -pub fn (mut h Header) add_custom_map(kvs map[string]string) ? { +pub fn (mut h Header) add_custom_map(kvs map[string]string) ! { for k, v in kvs { - h.add_custom(k, v)? + h.add_custom(k, v)! } } @@ -410,8 +410,8 @@ pub fn (mut h Header) set(key CommonHeader, value string) { // function will clear any other values that exist for the header. This // function will return an error if the key contains invalid header // characters. -pub fn (mut h Header) set_custom(key string, value string) ? { - is_valid(key)? +pub fn (mut h Header) set_custom(key string, value string) ! { + is_valid(key)! h.data[key] = [value] h.add_key(key) } @@ -479,37 +479,37 @@ pub fn (h Header) contains_custom(key string, flags HeaderQueryConfig) bool { // get gets the first value for the CommonHeader, or none if the key // does not exist. -pub fn (h Header) get(key CommonHeader) ?string { +pub fn (h Header) get(key CommonHeader) !string { return h.get_custom(key.str()) } // get_custom gets the first value for the custom header, or none if // the key does not exist. -pub fn (h Header) get_custom(key string, flags HeaderQueryConfig) ?string { +pub fn (h Header) get_custom(key string, flags HeaderQueryConfig) !string { mut data_key := key if !flags.exact { // get the first key from key metadata k := key.to_lower() if h.keys[k].len == 0 { - return none + return error('none') } data_key = h.keys[k][0] } if h.data[data_key].len == 0 { - return none + return error('none') } return h.data[data_key][0] } // starting_with gets the first header starting with key, or none if // the key does not exist. -pub fn (h Header) starting_with(key string) ?string { +pub fn (h Header) starting_with(key string) !string { for k, _ in h.data { if k.starts_with(key) { return k } } - return none + return error('none') } // values gets all values for the CommonHeader. @@ -642,7 +642,7 @@ pub fn (err HeaderKeyError) code() int { } // is_valid checks if the header token contains all valid bytes -fn is_valid(header string) ? { +fn is_valid(header string) ! { for _, c in header { if int(c) >= 128 || !is_token(c) { return IError(HeaderKeyError{ @@ -676,7 +676,7 @@ pub fn (h Header) str() string { } // parse_headers parses a newline delimited string into a Header struct -fn parse_headers(s string) ?Header { +fn parse_headers(s string) !Header { mut h := new_header() mut last_key := '' mut last_value := '' @@ -689,15 +689,15 @@ fn parse_headers(s string) ?Header { last_value += ' ${line.trim(' \t')}' continue } else if last_key != '' { - h.add_custom(last_key, last_value)? + h.add_custom(last_key, last_value)! } - last_key, last_value = parse_header(line)? + last_key, last_value = parse_header(line)! } - h.add_custom(last_key, last_value)? + h.add_custom(last_key, last_value)! return h } -fn parse_header(s string) ?(string, string) { +fn parse_header(s string) !(string, string) { if !s.contains(':') { return error('missing colon in header') } diff --git a/vlib/net/http/http.v b/vlib/net/http/http.v index 1a47709db..6dc2cab58 100644 --- a/vlib/net/http/http.v +++ b/vlib/net/http/http.v @@ -31,7 +31,7 @@ pub mut: allow_redirect bool = true // whether to allow redirect } -pub fn new_request(method Method, url_ string, data string) ?Request { +pub fn new_request(method Method, url_ string, data string) !Request { url := if method == .get && !url_.contains('?') { url_ + '?' + data } else { url_ } // println('new req() method=$method url="$url" dta="$data"') return Request{ @@ -47,12 +47,12 @@ pub fn new_request(method Method, url_ string, data string) ?Request { } // get sends a GET HTTP request to the URL -pub fn get(url string) ?Response { +pub fn get(url string) !Response { return fetch(method: .get, url: url) } // post sends a POST HTTP request to the URL with a string data -pub fn post(url string, data string) ?Response { +pub fn post(url string, data string) !Response { return fetch( method: .post url: url @@ -62,7 +62,7 @@ pub fn post(url string, data string) ?Response { } // post_json sends a POST HTTP request to the URL with a JSON data -pub fn post_json(url string, data string) ?Response { +pub fn post_json(url string, data string) !Response { return fetch( method: .post url: url @@ -72,7 +72,7 @@ pub fn post_json(url string, data string) ?Response { } // post_form sends a POST HTTP request to the URL with X-WWW-FORM-URLENCODED data -pub fn post_form(url string, data map[string]string) ?Response { +pub fn post_form(url string, data map[string]string) !Response { return fetch( method: .post url: url @@ -90,7 +90,7 @@ pub mut: } // post_multipart_form sends a POST HTTP request to the URL with multipart form data -pub fn post_multipart_form(url string, conf PostMultipartFormConfig) ?Response { +pub fn post_multipart_form(url string, conf PostMultipartFormConfig) !Response { body, boundary := multipart_form_body(conf.form, conf.files) mut header := conf.header header.set(.content_type, 'multipart/form-data; boundary="$boundary"') @@ -103,7 +103,7 @@ pub fn post_multipart_form(url string, conf PostMultipartFormConfig) ?Response { } // put sends a PUT HTTP request to the URL with a string data -pub fn put(url string, data string) ?Response { +pub fn put(url string, data string) !Response { return fetch( method: .put url: url @@ -113,7 +113,7 @@ pub fn put(url string, data string) ?Response { } // patch sends a PATCH HTTP request to the URL with a string data -pub fn patch(url string, data string) ?Response { +pub fn patch(url string, data string) !Response { return fetch( method: .patch url: url @@ -123,17 +123,17 @@ pub fn patch(url string, data string) ?Response { } // head sends a HEAD HTTP request to the URL -pub fn head(url string) ?Response { +pub fn head(url string) !Response { return fetch(method: .head, url: url) } // delete sends a DELETE HTTP request to the URL -pub fn delete(url string) ?Response { +pub fn delete(url string) !Response { return fetch(method: .delete, url: url) } // fetch sends an HTTP request to the URL with the given method and configurations -pub fn fetch(config FetchConfig) ?Response { +pub fn fetch(config FetchConfig) !Response { if config.url == '' { return error('http.fetch: empty url') } @@ -154,7 +154,7 @@ pub fn fetch(config FetchConfig) ?Response { in_memory_verification: config.in_memory_verification allow_redirect: config.allow_redirect } - res := req.do()? + res := req.do()! return res } @@ -176,14 +176,14 @@ pub fn url_encode_form_data(data map[string]string) string { } [deprecated: 'use fetch()'] -fn fetch_with_method(method Method, _config FetchConfig) ?Response { +fn fetch_with_method(method Method, _config FetchConfig) !Response { mut config := _config config.method = method return fetch(config) } -fn build_url_from_fetch(config FetchConfig) ?string { - mut url := urllib.parse(config.url)? +fn build_url_from_fetch(config FetchConfig) !string { + mut url := urllib.parse(config.url)! if config.params.len == 0 { return url.str() } diff --git a/vlib/net/http/http_httpbin_test.v b/vlib/net/http/http_httpbin_test.v index 458ad3148..d70479977 100644 --- a/vlib/net/http/http_httpbin_test.v +++ b/vlib/net/http/http_httpbin_test.v @@ -14,7 +14,7 @@ struct HttpbinResponseBody { url string } -fn http_fetch_mock(_methods []string, _config FetchConfig) ?[]Response { +fn http_fetch_mock(_methods []string, _config FetchConfig) ![]Response { url := 'https://httpbin.org/' methods := if _methods.len == 0 { ['GET', 'POST', 'PATCH', 'PUT', 'DELETE'] } else { _methods } mut config := _config @@ -23,7 +23,7 @@ fn http_fetch_mock(_methods []string, _config FetchConfig) ?[]Response { for method in methods { lmethod := method.to_lower() config.method = method_from_str(method) - res := fetch(FetchConfig{ ...config, url: url + lmethod })? + res := fetch(FetchConfig{ ...config, url: url + lmethod })! // TODO // body := json.decode(HttpbinResponseBody,res.body)? result << res @@ -75,12 +75,12 @@ fn test_http_fetch_with_params() { } } -fn test_http_fetch_with_headers() ? { +fn test_http_fetch_with_headers() ! { $if !network ? { return } mut header := new_header() - header.add_custom('Test-Header', 'hello world')? + header.add_custom('Test-Header', 'hello world')! responses := http_fetch_mock([], header: header ) or { panic(err) } diff --git a/vlib/net/http/request.v b/vlib/net/http/request.v index 9ad02de6f..0e6fcf30a 100644 --- a/vlib/net/http/request.v +++ b/vlib/net/http/request.v @@ -48,12 +48,12 @@ pub fn (mut req Request) add_header(key CommonHeader, val string) { // add_custom_header adds the key and value of an HTTP request header // This method may fail if the key contains characters that are not permitted -pub fn (mut req Request) add_custom_header(key string, val string) ? { +pub fn (mut req Request) add_custom_header(key string, val string) ! { return req.header.add_custom(key, val) } // do will send the HTTP request and returns `http.Response` as soon as the response is recevied -pub fn (req &Request) do() ?Response { +pub fn (req &Request) do() !Response { mut url := urllib.parse(req.url) or { return error('http.Request.do: invalid url $req.url') } mut rurl := url mut resp := Response{} @@ -62,7 +62,7 @@ pub fn (req &Request) do() ?Response { if no_redirects == max_redirects { return error('http.request.do: maximum number of redirects reached ($max_redirects)') } - qresp := req.method_and_url_to_response(req.method, rurl)? + qresp := req.method_and_url_to_response(req.method, rurl)! resp = qresp if !req.allow_redirect { break @@ -88,7 +88,7 @@ pub fn (req &Request) do() ?Response { return resp } -fn (req &Request) method_and_url_to_response(method Method, url urllib.URL) ?Response { +fn (req &Request) method_and_url_to_response(method Method, url urllib.URL) !Response { host_name := url.hostname() scheme := url.scheme p := url.escaped_path().trim_left('/') @@ -105,11 +105,11 @@ fn (req &Request) method_and_url_to_response(method Method, url urllib.URL) ?Res // println('fetch $method, $scheme, $host_name, $nport, $path ') if scheme == 'https' { // println('ssl_do( $nport, $method, $host_name, $path )') - res := req.ssl_do(nport, method, host_name, path)? + res := req.ssl_do(nport, method, host_name, path)! return res } else if scheme == 'http' { // println('http_do( $nport, $method, $host_name, $path )') - res := req.http_do('$host_name:$nport', method, path)? + res := req.http_do('$host_name:$nport', method, path)! return res } return error('http.request.method_and_url_to_response: unsupported scheme: "$scheme"') @@ -151,19 +151,19 @@ fn (req &Request) build_request_cookies_header() string { return 'Cookie: ' + cookie.join('; ') + '\r\n' } -fn (req &Request) http_do(host string, method Method, path string) ?Response { - host_name, _ := net.split_address(host)? +fn (req &Request) http_do(host string, method Method, path string) !Response { + host_name, _ := net.split_address(host)! s := req.build_request_headers(method, host_name, path) - mut client := net.dial_tcp(host)? + mut client := net.dial_tcp(host)! client.set_read_timeout(req.read_timeout) client.set_write_timeout(req.write_timeout) // TODO this really needs to be exposed somehow - client.write(s.bytes())? + client.write(s.bytes())! $if trace_http_request ? { eprintln('> $s') } - mut bytes := io.read_all(reader: client)? - client.close()? + mut bytes := io.read_all(reader: client)! + client.close()! response_text := bytes.bytestr() $if trace_http_response ? { eprintln('< $response_text') @@ -178,8 +178,8 @@ pub fn (req &Request) referer() string { // parse_request parses a raw HTTP request into a Request object. // See also: `parse_request_head`, which parses only the headers. -pub fn parse_request(mut reader io.BufferedReader) ?Request { - mut request := parse_request_head(mut reader)? +pub fn parse_request(mut reader io.BufferedReader) !Request { + mut request := parse_request_head(mut reader)! // body mut body := []u8{} @@ -199,18 +199,18 @@ pub fn parse_request(mut reader io.BufferedReader) ?Request { } // parse_request_head parses *only* the header of a raw HTTP request into a Request object -pub fn parse_request_head(mut reader io.BufferedReader) ?Request { +pub fn parse_request_head(mut reader io.BufferedReader) !Request { // request line - mut line := reader.read_line()? - method, target, version := parse_request_line(line)? + mut line := reader.read_line()! + method, target, version := parse_request_line(line)! // headers mut header := new_header() - line = reader.read_line()? + line = reader.read_line()! for line != '' { - key, value := parse_header(line)? - header.add_custom(key, value)? - line = reader.read_line()? + key, value := parse_header(line)! + header.add_custom(key, value)! + line = reader.read_line()! } header.coerce(canonicalize: true) @@ -228,13 +228,13 @@ pub fn parse_request_head(mut reader io.BufferedReader) ?Request { } } -fn parse_request_line(s string) ?(Method, urllib.URL, Version) { +fn parse_request_line(s string) !(Method, urllib.URL, Version) { words := s.split(' ') if words.len != 3 { return error('malformed request line') } method := method_from_str(words[0]) - target := urllib.parse(words[1])? + target := urllib.parse(words[1])! version := version_from_str(words[2]) if version == .unknown { return error('unsupported version') diff --git a/vlib/net/http/request_test.v b/vlib/net/http/request_test.v index bc56bce09..36aa8809f 100644 --- a/vlib/net/http/request_test.v +++ b/vlib/net/http/request_test.v @@ -178,7 +178,7 @@ fn test_parse_large_body() { body := 'A'.repeat(101) // greater than max_bytes req := 'GET / HTTP/1.1\r\nContent-Length: $body.len\r\n\r\n$body' mut reader_ := reader(req) - result := parse_request(mut reader_)? + result := parse_request(mut reader_)! assert result.data.len == body.len assert result.data == body } diff --git a/vlib/net/http/response.v b/vlib/net/http/response.v index 5ebd9e0ec..33682d184 100644 --- a/vlib/net/http/response.v +++ b/vlib/net/http/response.v @@ -35,11 +35,11 @@ pub fn (resp Response) bytestr() string { } // Parse a raw HTTP response into a Response object -pub fn parse_response(resp string) ?Response { - version, status_code, status_msg := parse_status_line(resp.all_before('\n'))? +pub fn parse_response(resp string) !Response { + version, status_code, status_msg := parse_status_line(resp.all_before('\n'))! // Build resp header map and separate the body - start_idx, end_idx := find_headers_range(resp)? - header := parse_headers(resp.substr(start_idx, end_idx))? + start_idx, end_idx := find_headers_range(resp)! + header := parse_headers(resp.substr(start_idx, end_idx))! mut body := resp.substr(end_idx, resp.len) if header.get(.transfer_encoding) or { '' } == 'chunked' { body = chunked.decode(body) @@ -56,7 +56,7 @@ pub fn parse_response(resp string) ?Response { // parse_status_line parses the first HTTP response line into the HTTP // version, status code, and reason phrase -fn parse_status_line(line string) ?(string, int, string) { +fn parse_status_line(line string) !(string, int, string) { if line.len < 5 || line[..5].to_lower() != 'http/' { return error('response does not start with HTTP/') } @@ -73,7 +73,7 @@ fn parse_status_line(line string) ?(string, int, string) { for digit in digits { strconv.atoi(digit) or { return error('HTTP version must contain only integers') } } - return version, strconv.atoi(data[1])?, data[2] + return version, strconv.atoi(data[1])!, data[2] } // cookies parses the Set-Cookie headers into Cookie objects @@ -138,7 +138,7 @@ pub fn new_response(conf ResponseConfig) Response { // index of the headers in the string, including the trailing newlines. This // helper function expects the first line in `data` to be the HTTP status line // (HTTP/1.1 200 OK). -fn find_headers_range(data string) ?(int, int) { +fn find_headers_range(data string) !(int, int) { start_idx := data.index('\n') or { return error('no start index found') } + 1 mut count := 0 for i := start_idx; i < data.len; i++ { diff --git a/vlib/net/http/response_test.v b/vlib/net/http/response_test.v index c10a0bc3b..732e7b9d9 100644 --- a/vlib/net/http/response_test.v +++ b/vlib/net/http/response_test.v @@ -26,7 +26,7 @@ fn test_response_bytestr() { // check_headers is a helper function for asserting all expected headers // are found because rendered header order is not guaranteed. The check // is O(n^2) which is fine for small lists. -fn check_headers(expected []string, found []string) ? { +fn check_headers(expected []string, found []string) ! { assert expected.len == found.len for header in expected { if !found.contains(header) { diff --git a/vlib/net/http/server.v b/vlib/net/http/server.v index 45edc5094..a0beab859 100644 --- a/vlib/net/http/server.v +++ b/vlib/net/http/server.v @@ -34,11 +34,14 @@ pub mut: accept_timeout time.Duration = 30 * time.second } -pub fn (mut s Server) listen_and_serve() ? { +pub fn (mut s Server) listen_and_serve() { if s.handler is DebugHandler { eprintln('Server handler not set, using debug handler') } - s.listener = net.listen_tcp(.ip6, ':$s.port')? + s.listener = net.listen_tcp(.ip6, ':$s.port') or { + eprintln('Listening on :$s.port failed') + return + } s.listener.set_accept_timeout(s.accept_timeout) eprintln('Listening on :$s.port') s.state = .running diff --git a/vlib/net/http/server_test.v b/vlib/net/http/server_test.v index fbf2b54e5..70db4d597 100644 --- a/vlib/net/http/server_test.v +++ b/vlib/net/http/server_test.v @@ -11,7 +11,7 @@ fn test_server_stop() { server.stop() assert server.status() == .stopped assert watch.elapsed() < 100 * time.millisecond - t.wait()? + t.wait() assert watch.elapsed() < 999 * time.millisecond } @@ -26,7 +26,7 @@ fn test_server_close() { server.close() assert server.status() == .closed assert watch.elapsed() < 100 * time.millisecond - t.wait()? + t.wait() assert watch.elapsed() < 999 * time.millisecond } @@ -71,19 +71,19 @@ fn test_server_custom_handler() { for server.status() != .running { time.sleep(10 * time.millisecond) } - x := http.fetch(url: 'http://localhost:$cport/endpoint?abc=xyz', data: 'my data')? + x := http.fetch(url: 'http://localhost:$cport/endpoint?abc=xyz', data: 'my data')! assert x.body == 'my data, /endpoint?abc=xyz' assert x.status_code == 200 assert x.http_version == '1.1' - y := http.fetch(url: 'http://localhost:$cport/another/endpoint', data: 'abcde')? + y := http.fetch(url: 'http://localhost:$cport/another/endpoint', data: 'abcde')! assert y.body == 'abcde, /another/endpoint' assert y.status_code == 200 assert y.status() == .ok assert y.http_version == '1.1' // - http.fetch(url: 'http://localhost:$cport/something/else')? + http.fetch(url: 'http://localhost:$cport/something/else')! server.stop() - t.wait()? + t.wait() assert handler.counter == 3 assert handler.oks == 2 assert handler.not_founds == 1 diff --git a/vlib/net/mbedtls/ssl_connection.v b/vlib/net/mbedtls/ssl_connection.v index 3a3b2255d..41ea28bdd 100644 --- a/vlib/net/mbedtls/ssl_connection.v +++ b/vlib/net/mbedtls/ssl_connection.v @@ -52,7 +52,7 @@ pub struct SSLConnectConfig { } // new_ssl_conn returns a new SSLConn with the given config. -pub fn new_ssl_conn(config SSLConnectConfig) ?&SSLConn { +pub fn new_ssl_conn(config SSLConnectConfig) !&SSLConn { mut conn := &SSLConn{ config: config } @@ -68,7 +68,7 @@ enum Select { } // shutdown terminates the ssl connection and does cleanup -pub fn (mut s SSLConn) shutdown() ? { +pub fn (mut s SSLConn) shutdown() ! { if !s.opened { return error('ssl connection not open') } @@ -82,16 +82,16 @@ pub fn (mut s SSLConn) shutdown() ? { if s.owns_socket { $if windows { C.shutdown(s.handle, C.SD_BOTH) - net.socket_error(C.closesocket(s.handle))? + net.socket_error(C.closesocket(s.handle))! } $else { C.shutdown(s.handle, C.SHUT_RDWR) - net.socket_error(C.close(s.handle))? + net.socket_error(C.close(s.handle))! } } } // connect to server using mbedtls -fn (mut s SSLConn) init() ? { +fn (mut s SSLConn) init() ! { C.mbedtls_net_init(&s.server_fd) C.mbedtls_ssl_init(&s.ssl) C.mbedtls_ssl_config_init(&s.conf) @@ -157,7 +157,7 @@ fn (mut s SSLConn) init() ? { } // connect sets up an ssl connection on an existing TCP connection -pub fn (mut s SSLConn) connect(mut tcp_conn net.TcpConn, hostname string) ? { +pub fn (mut s SSLConn) connect(mut tcp_conn net.TcpConn, hostname string) ! { if s.opened { return error('ssl connection already open') } @@ -183,7 +183,7 @@ pub fn (mut s SSLConn) connect(mut tcp_conn net.TcpConn, hostname string) ? { } // dial opens an ssl connection on hostname:port -pub fn (mut s SSLConn) dial(hostname string, port int) ? { +pub fn (mut s SSLConn) dial(hostname string, port int) ! { s.owns_socket = true if s.opened { return error('ssl connection already open') @@ -216,7 +216,7 @@ pub fn (mut s SSLConn) dial(hostname string, port int) ? { } // socket_read_into_ptr reads `len` bytes into `buf` -pub fn (mut s SSLConn) socket_read_into_ptr(buf_ptr &u8, len int) ?int { +pub fn (mut s SSLConn) socket_read_into_ptr(buf_ptr &u8, len int) !int { mut res := 0 for { res = C.mbedtls_ssl_read(&s.ssl, buf_ptr, len) @@ -227,13 +227,13 @@ pub fn (mut s SSLConn) socket_read_into_ptr(buf_ptr &u8, len int) ?int { } else { match res { C.MBEDTLS_ERR_SSL_WANT_READ { - ready := @select(s.handle, .read, s.duration)? + ready := @select(s.handle, .read, s.duration)! if !ready { return net.err_timed_out } } C.MBEDTLS_ERR_SSL_WANT_WRITE { - ready := @select(s.handle, .write, s.duration)? + ready := @select(s.handle, .write, s.duration)! if !ready { return net.err_timed_out } @@ -257,7 +257,7 @@ pub fn (mut s SSLConn) read(mut buffer []u8) !int { } // write_ptr writes `len` bytes from `bytes` to the ssl connection -pub fn (mut s SSLConn) write_ptr(bytes &u8, len int) ?int { +pub fn (mut s SSLConn) write_ptr(bytes &u8, len int) !int { unsafe { mut ptr_base := bytes mut total_sent := 0 @@ -269,7 +269,7 @@ pub fn (mut s SSLConn) write_ptr(bytes &u8, len int) ?int { match sent { C.MBEDTLS_ERR_SSL_WANT_READ { for { - ready := @select(s.handle, .read, s.duration)? + ready := @select(s.handle, .read, s.duration)! if ready { break } @@ -278,7 +278,7 @@ pub fn (mut s SSLConn) write_ptr(bytes &u8, len int) ?int { } C.MBEDTLS_ERR_SSL_WANT_WRITE { for { - ready := @select(s.handle, .write, s.duration)? + ready := @select(s.handle, .write, s.duration)! if ready { break } @@ -297,12 +297,12 @@ pub fn (mut s SSLConn) write_ptr(bytes &u8, len int) ?int { } // write writes data from `bytes` to the ssl connection -pub fn (mut s SSLConn) write(bytes []u8) ?int { +pub fn (mut s SSLConn) write(bytes []u8) !int { return s.write_ptr(&u8(bytes.data), bytes.len) } // write_string writes a string to the ssl connection -pub fn (mut s SSLConn) write_string(str string) ?int { +pub fn (mut s SSLConn) write_string(str string) !int { return s.write_ptr(str.str, str.len) } @@ -313,7 +313,7 @@ This is basically a copy of Emily socket implementation of select. */ // Select waits for an io operation (specified by parameter `test`) to be available -fn @select(handle int, test Select, timeout time.Duration) ?bool { +fn @select(handle int, test Select, timeout time.Duration) !bool { set := C.fd_set{} C.FD_ZERO(&set) @@ -336,13 +336,13 @@ fn @select(handle int, test Select, timeout time.Duration) ?bool { match test { .read { - net.socket_error(C.@select(handle + 1, &set, C.NULL, C.NULL, timeval_timeout))? + net.socket_error(C.@select(handle + 1, &set, C.NULL, C.NULL, timeval_timeout))! } .write { - net.socket_error(C.@select(handle + 1, C.NULL, &set, C.NULL, timeval_timeout))? + net.socket_error(C.@select(handle + 1, C.NULL, &set, C.NULL, timeval_timeout))! } .except { - net.socket_error(C.@select(handle + 1, C.NULL, C.NULL, &set, timeval_timeout))? + net.socket_error(C.@select(handle + 1, C.NULL, C.NULL, &set, timeval_timeout))! } } diff --git a/vlib/net/openssl/openssl.v b/vlib/net/openssl/openssl.v index 144636cae..6aa96b79f 100644 --- a/vlib/net/openssl/openssl.v +++ b/vlib/net/openssl/openssl.v @@ -1,7 +1,7 @@ module openssl // ssl_error returns non error ssl code or error if unrecoverable and we should panic -fn ssl_error(ret int, ssl voidptr) ?SSLError { +fn ssl_error(ret int, ssl voidptr) !SSLError { res := C.SSL_get_error(ssl, ret) match unsafe { SSLError(res) } { .ssl_error_syscall { diff --git a/vlib/net/openssl/ssl_connection.v b/vlib/net/openssl/ssl_connection.v index d19644d0c..e920249ec 100644 --- a/vlib/net/openssl/ssl_connection.v +++ b/vlib/net/openssl/ssl_connection.v @@ -28,7 +28,7 @@ pub struct SSLConnectConfig { } // new_ssl_conn instance an new SSLCon struct -pub fn new_ssl_conn(config SSLConnectConfig) ?&SSLConn { +pub fn new_ssl_conn(config SSLConnectConfig) !&SSLConn { mut conn := &SSLConn{ config: config sslctx: 0 @@ -47,7 +47,7 @@ enum Select { } // shutdown closes the ssl connection and does cleanup -pub fn (mut s SSLConn) shutdown() ? { +pub fn (mut s SSLConn) shutdown() ! { if s.ssl != 0 { mut res := 0 for { @@ -100,15 +100,15 @@ pub fn (mut s SSLConn) shutdown() ? { if s.owns_socket { $if windows { C.shutdown(s.handle, C.SD_BOTH) - net.socket_error(C.closesocket(s.handle))? + net.socket_error(C.closesocket(s.handle))! } $else { C.shutdown(s.handle, C.SHUT_RDWR) - net.socket_error(C.close(s.handle))? + net.socket_error(C.close(s.handle))! } } } -fn (mut s SSLConn) init() ? { +fn (mut s SSLConn) init() ! { s.sslctx = unsafe { C.SSL_CTX_new(C.SSLv23_client_method()) } if s.sslctx == 0 { return error("Couldn't get ssl context") @@ -136,13 +136,13 @@ fn (mut s SSLConn) init() ? { cert = os.temp_dir() + '/v_cert' + now cert_key = os.temp_dir() + '/v_cert_key' + now if s.config.verify != '' { - os.write_file(verify, s.config.verify)? + os.write_file(verify, s.config.verify)! } if s.config.cert != '' { - os.write_file(cert, s.config.cert)? + os.write_file(cert, s.config.cert)! } if s.config.cert_key != '' { - os.write_file(cert_key, s.config.cert_key)? + os.write_file(cert_key, s.config.cert_key)! } } if s.config.verify != '' { @@ -175,7 +175,7 @@ fn (mut s SSLConn) init() ? { } // connect to server using OpenSSL -pub fn (mut s SSLConn) connect(mut tcp_conn net.TcpConn, hostname string) ? { +pub fn (mut s SSLConn) connect(mut tcp_conn net.TcpConn, hostname string) ! { s.handle = tcp_conn.sock.handle s.duration = tcp_conn.read_timeout() @@ -192,7 +192,7 @@ pub fn (mut s SSLConn) connect(mut tcp_conn net.TcpConn, hostname string) ? { } // dial opens an ssl connection on hostname:port -pub fn (mut s SSLConn) dial(hostname string, port int) ? { +pub fn (mut s SSLConn) dial(hostname string, port int) ! { s.owns_socket = true mut tcp_conn := net.dial_tcp('$hostname:$port') or { return err } $if macos { @@ -201,14 +201,14 @@ pub fn (mut s SSLConn) dial(hostname string, port int) ? { s.connect(mut tcp_conn, hostname) or { return err } } -fn (mut s SSLConn) complete_connect() ? { +fn (mut s SSLConn) complete_connect() ! { for { mut res := C.SSL_connect(voidptr(s.ssl)) if res != 1 { - err_res := ssl_error(res, s.ssl)? + err_res := ssl_error(res, s.ssl)! if err_res == .ssl_error_want_read { for { - ready := @select(s.handle, .read, s.duration)? + ready := @select(s.handle, .read, s.duration)! if ready { break } @@ -216,7 +216,7 @@ fn (mut s SSLConn) complete_connect() ? { continue } else if err_res == .ssl_error_want_write { for { - ready := @select(s.handle, .write, s.duration)? + ready := @select(s.handle, .write, s.duration)! if ready { break } @@ -232,10 +232,10 @@ fn (mut s SSLConn) complete_connect() ? { for { mut res := C.SSL_do_handshake(voidptr(s.ssl)) if res != 1 { - err_res := ssl_error(res, s.ssl)? + err_res := ssl_error(res, s.ssl)! if err_res == .ssl_error_want_read { for { - ready := @select(s.handle, .read, s.duration)? + ready := @select(s.handle, .read, s.duration)! if ready { break } @@ -243,7 +243,7 @@ fn (mut s SSLConn) complete_connect() ? { continue } else if err_res == .ssl_error_want_write { for { - ready := @select(s.handle, .write, s.duration)? + ready := @select(s.handle, .write, s.duration)! if ready { break } @@ -267,7 +267,7 @@ fn (mut s SSLConn) complete_connect() ? { } } -pub fn (mut s SSLConn) socket_read_into_ptr(buf_ptr &u8, len int) ?int { +pub fn (mut s SSLConn) socket_read_into_ptr(buf_ptr &u8, len int) !int { mut res := 0 for { res = C.SSL_read(voidptr(s.ssl), buf_ptr, len) @@ -276,16 +276,16 @@ pub fn (mut s SSLConn) socket_read_into_ptr(buf_ptr &u8, len int) ?int { } else if res == 0 { return IError(io.Eof{}) } else { - err_res := ssl_error(res, s.ssl)? + err_res := ssl_error(res, s.ssl)! match err_res { .ssl_error_want_read { - ready := @select(s.handle, .read, s.duration)? + ready := @select(s.handle, .read, s.duration)! if !ready { return net.err_timed_out } } .ssl_error_want_write { - ready := @select(s.handle, .write, s.duration)? + ready := @select(s.handle, .write, s.duration)! if !ready { return net.err_timed_out } @@ -308,7 +308,7 @@ pub fn (mut s SSLConn) read(mut buffer []u8) !int { } // write_ptr writes `len` bytes from `bytes` to the ssl connection -pub fn (mut s SSLConn) write_ptr(bytes &u8, len int) ?int { +pub fn (mut s SSLConn) write_ptr(bytes &u8, len int) !int { unsafe { mut ptr_base := bytes mut total_sent := 0 @@ -317,17 +317,17 @@ pub fn (mut s SSLConn) write_ptr(bytes &u8, len int) ?int { remaining := len - total_sent mut sent := C.SSL_write(voidptr(s.ssl), ptr, remaining) if sent <= 0 { - err_res := ssl_error(sent, s.ssl)? + err_res := ssl_error(sent, s.ssl)! if err_res == .ssl_error_want_read { for { - ready := @select(s.handle, .read, s.duration)? + ready := @select(s.handle, .read, s.duration)! if ready { break } } } else if err_res == .ssl_error_want_write { for { - ready := @select(s.handle, .write, s.duration)? + ready := @select(s.handle, .write, s.duration)! if ready { break } @@ -345,12 +345,12 @@ pub fn (mut s SSLConn) write_ptr(bytes &u8, len int) ?int { } // write writes data from `bytes` to the ssl connection -pub fn (mut s SSLConn) write(bytes []u8) ?int { +pub fn (mut s SSLConn) write(bytes []u8) !int { return s.write_ptr(&u8(bytes.data), bytes.len) } // write_string writes a string to the ssl connection -pub fn (mut s SSLConn) write_string(str string) ?int { +pub fn (mut s SSLConn) write_string(str string) !int { return s.write_ptr(str.str, str.len) } @@ -364,7 +364,7 @@ This is basically a copy of Emily socket implementation of select. // } // Select waits for an io operation (specified by parameter `test`) to be available -fn @select(handle int, test Select, timeout time.Duration) ?bool { +fn @select(handle int, test Select, timeout time.Duration) !bool { set := C.fd_set{} C.FD_ZERO(&set) @@ -387,13 +387,13 @@ fn @select(handle int, test Select, timeout time.Duration) ?bool { match test { .read { - net.socket_error(C.@select(handle + 1, &set, C.NULL, C.NULL, timeval_timeout))? + net.socket_error(C.@select(handle + 1, &set, C.NULL, C.NULL, timeval_timeout))! } .write { - net.socket_error(C.@select(handle + 1, C.NULL, &set, C.NULL, timeval_timeout))? + net.socket_error(C.@select(handle + 1, C.NULL, &set, C.NULL, timeval_timeout))! } .except { - net.socket_error(C.@select(handle + 1, C.NULL, C.NULL, &set, timeval_timeout))? + net.socket_error(C.@select(handle + 1, C.NULL, C.NULL, &set, timeval_timeout))! } } diff --git a/vlib/net/smtp/smtp.v b/vlib/net/smtp/smtp.v index 6b4cf6a9e..fb1c5a6ad 100644 --- a/vlib/net/smtp/smtp.v +++ b/vlib/net/smtp/smtp.v @@ -59,7 +59,7 @@ pub struct Mail { } // new_client returns a new SMTP client and connects to it -pub fn new_client(config Client) ?&Client { +pub fn new_client(config Client) !&Client { if config.ssl && config.starttls { return error('Can not use both implicit SSL and STARTTLS') } @@ -67,12 +67,12 @@ pub fn new_client(config Client) ?&Client { mut c := &Client{ ...config } - c.reconnect()? + c.reconnect()! return c } // reconnect reconnects to the SMTP server if the connection was closed -pub fn (mut c Client) reconnect() ? { +pub fn (mut c Client) reconnect() ! { if c.is_open { return error('Already connected to server') } @@ -81,7 +81,7 @@ pub fn (mut c Client) reconnect() ? { c.conn = conn if c.ssl { - c.connect_ssl()? + c.connect_ssl()! } else { c.reader = io.new_buffered_reader(reader: c.conn) } @@ -98,7 +98,7 @@ pub fn (mut c Client) reconnect() ? { } // send sends an email -pub fn (mut c Client) send(config Mail) ? { +pub fn (mut c Client) send(config Mail) ! { if !c.is_open { return error('Disconnected from server') } @@ -113,20 +113,20 @@ pub fn (mut c Client) send(config Mail) ? { } // quit closes the connection to the server -pub fn (mut c Client) quit() ? { - c.send_str('QUIT\r\n')? - c.expect_reply(.close)? +pub fn (mut c Client) quit() ! { + c.send_str('QUIT\r\n')! + c.expect_reply(.close)! if c.encrypted { - c.ssl_conn.shutdown()? + c.ssl_conn.shutdown()! } else { - c.conn.close()? + c.conn.close()! } c.is_open = false c.encrypted = false } -fn (mut c Client) connect_ssl() ? { - c.ssl_conn = ssl.new_ssl_conn()? +fn (mut c Client) connect_ssl() ! { + c.ssl_conn = ssl.new_ssl_conn()! c.ssl_conn.connect(mut c.conn, c.server) or { return error('Connecting to server using OpenSSL failed: $err') } @@ -136,10 +136,10 @@ fn (mut c Client) connect_ssl() ? { } // expect_reply checks if the SMTP server replied with the expected reply code -fn (mut c Client) expect_reply(expected ReplyCode) ? { +fn (mut c Client) expect_reply(expected ReplyCode) ! { mut str := '' for { - str = c.reader.read_line()? + str = c.reader.read_line()! if str.len < 4 { return error('Invalid SMTP response: $str') } @@ -167,7 +167,7 @@ fn (mut c Client) expect_reply(expected ReplyCode) ? { } [inline] -fn (mut c Client) send_str(s string) ? { +fn (mut c Client) send_str(s string) ! { $if smtp_debug ? { eprintln('\n\n[SEND START]') eprint(s.trim_space()) @@ -175,27 +175,27 @@ fn (mut c Client) send_str(s string) ? { } if c.encrypted { - c.ssl_conn.write(s.bytes())? + c.ssl_conn.write(s.bytes())! } else { - c.conn.write(s.bytes())? + c.conn.write(s.bytes())! } } [inline] -fn (mut c Client) send_ehlo() ? { - c.send_str('EHLO $c.server\r\n')? - c.expect_reply(.action_ok)? +fn (mut c Client) send_ehlo() ! { + c.send_str('EHLO $c.server\r\n')! + c.expect_reply(.action_ok)! } [inline] -fn (mut c Client) send_starttls() ? { - c.send_str('STARTTLS\r\n')? - c.expect_reply(.ready)? - c.connect_ssl()? +fn (mut c Client) send_starttls() ! { + c.send_str('STARTTLS\r\n')! + c.expect_reply(.ready)! + c.connect_ssl()! } [inline] -fn (mut c Client) send_auth() ? { +fn (mut c Client) send_auth() ! { if c.username.len == 0 { return } @@ -206,28 +206,28 @@ fn (mut c Client) send_auth() ? { sb.write_string(c.password) a := sb.str() auth := 'AUTH PLAIN ${base64.encode_str(a)}\r\n' - c.send_str(auth)? - c.expect_reply(.auth_ok)? + c.send_str(auth)! + c.expect_reply(.auth_ok)! } -fn (mut c Client) send_mailfrom(from string) ? { - c.send_str('MAIL FROM: <$from>\r\n')? - c.expect_reply(.action_ok)? +fn (mut c Client) send_mailfrom(from string) ! { + c.send_str('MAIL FROM: <$from>\r\n')! + c.expect_reply(.action_ok)! } -fn (mut c Client) send_mailto(to string) ? { +fn (mut c Client) send_mailto(to string) ! { for rcpt in to.split(';') { - c.send_str('RCPT TO: <$rcpt>\r\n')? - c.expect_reply(.action_ok)? + c.send_str('RCPT TO: <$rcpt>\r\n')! + c.expect_reply(.action_ok)! } } -fn (mut c Client) send_data() ? { - c.send_str('DATA\r\n')? - c.expect_reply(.mail_start)? +fn (mut c Client) send_data() ! { + c.send_str('DATA\r\n')! + c.expect_reply(.mail_start)! } -fn (mut c Client) send_body(cfg Mail) ? { +fn (mut c Client) send_body(cfg Mail) ! { is_html := cfg.body_type == .html date := cfg.date.custom_format('ddd, D MMM YYYY HH:mm ZZ') nonascii_subject := cfg.subject.bytes().any(it < u8(` `) || it > u8(`~`)) @@ -253,6 +253,6 @@ fn (mut c Client) send_body(cfg Mail) ? { sb.write_string('\r\n\r\n') sb.write_string(base64.encode_str(cfg.body)) sb.write_string('\r\n.\r\n') - c.send_str(sb.str())? - c.expect_reply(.action_ok)? + c.send_str(sb.str())! + c.expect_reply(.action_ok)! } diff --git a/vlib/net/socket.v b/vlib/net/socket.v index 2cb7ef902..f2c72fa0d 100644 --- a/vlib/net/socket.v +++ b/vlib/net/socket.v @@ -6,6 +6,6 @@ pub: } // address gets the address of a socket -pub fn (s &Socket) address() ?Addr { +pub fn (s &Socket) address() !Addr { return addr_from_socket_handle(s.handle) } diff --git a/vlib/net/ssl/ssl_d_use_openssl.v b/vlib/net/ssl/ssl_d_use_openssl.v index 65dd250e9..46aaf53b6 100644 --- a/vlib/net/ssl/ssl_d_use_openssl.v +++ b/vlib/net/ssl/ssl_d_use_openssl.v @@ -12,7 +12,7 @@ pub struct SSLConnectConfig { } // new_ssl_conn returns a new SSLConn with the given config. -pub fn new_ssl_conn(config SSLConnectConfig) ?&SSLConn { +pub fn new_ssl_conn(config SSLConnectConfig) !&SSLConn { c := openssl.new_ssl_conn(config.SSLConnectConfig) or { return err } return &SSLConn{c} } diff --git a/vlib/net/ssl/ssl_notd_use_openssl.v b/vlib/net/ssl/ssl_notd_use_openssl.v index 71fc376ca..a59bd2048 100644 --- a/vlib/net/ssl/ssl_notd_use_openssl.v +++ b/vlib/net/ssl/ssl_notd_use_openssl.v @@ -12,7 +12,7 @@ pub struct SSLConnectConfig { } // new_ssl_conn returns a new SSLConn with the given config. -pub fn new_ssl_conn(config SSLConnectConfig) ?&SSLConn { +pub fn new_ssl_conn(config SSLConnectConfig) !&SSLConn { c := mbedtls.new_ssl_conn(config.SSLConnectConfig) or { return err } return &SSLConn{c} } diff --git a/vlib/net/tcp.v b/vlib/net/tcp.v index 14000ba4c..7d9cdda32 100644 --- a/vlib/net/tcp.v +++ b/vlib/net/tcp.v @@ -21,7 +21,7 @@ mut: is_blocking bool } -pub fn dial_tcp(address string) ?&TcpConn { +pub fn dial_tcp(address string) !&TcpConn { addrs := resolve_addrs_fuzzy(address, .tcp) or { return error('$err.msg(); could not resolve address $address in dial_tcp') } @@ -64,7 +64,7 @@ pub fn dial_tcp(address string) ?&TcpConn { } // bind local address and dial. -pub fn dial_tcp_with_bind(saddr string, laddr string) ?&TcpConn { +pub fn dial_tcp_with_bind(saddr string, laddr string) !&TcpConn { addrs := resolve_addrs_fuzzy(saddr, .tcp) or { return error('$err.msg(); could not resolve address $saddr in dial_tcp_with_bind') } @@ -94,15 +94,15 @@ pub fn dial_tcp_with_bind(saddr string, laddr string) ?&TcpConn { return error('dial_tcp_with_bind failed for address $saddr') } -pub fn (mut c TcpConn) close() ? { +pub fn (mut c TcpConn) close() ! { $if trace_tcp ? { eprintln(' TcpConn.close | c.sock.handle: ${c.sock.handle:6}') } - c.sock.close()? + c.sock.close()! } -pub fn (c TcpConn) read_ptr(buf_ptr &u8, len int) ?int { - mut res := wrap_read_result(C.recv(c.sock.handle, voidptr(buf_ptr), len, 0))? +pub fn (c TcpConn) read_ptr(buf_ptr &u8, len int) !int { + mut res := wrap_read_result(C.recv(c.sock.handle, voidptr(buf_ptr), len, 0))! $if trace_tcp ? { eprintln('<<< TcpConn.read_ptr | c.sock.handle: $c.sock.handle | buf_ptr: ${ptr_str(buf_ptr)} len: $len | res: $res') } @@ -115,8 +115,8 @@ pub fn (c TcpConn) read_ptr(buf_ptr &u8, len int) ?int { } code := error_code() if code == int(error_ewouldblock) { - c.wait_for_read()? - res = wrap_read_result(C.recv(c.sock.handle, voidptr(buf_ptr), len, 0))? + c.wait_for_read()! + res = wrap_read_result(C.recv(c.sock.handle, voidptr(buf_ptr), len, 0))! $if trace_tcp ? { eprintln('<<< TcpConn.read_ptr | c.sock.handle: $c.sock.handle | buf_ptr: ${ptr_str(buf_ptr)} len: $len | res: $res') } @@ -128,9 +128,9 @@ pub fn (c TcpConn) read_ptr(buf_ptr &u8, len int) ?int { } return socket_error(res) } else { - wrap_error(code)? + wrap_error(code)! } - return none + return error('none') } pub fn (c TcpConn) read(mut buf []u8) !int { @@ -142,15 +142,15 @@ pub fn (c TcpConn) read(mut buf []u8) !int { } } -pub fn (mut c TcpConn) read_deadline() ?time.Time { +pub fn (mut c TcpConn) read_deadline() !time.Time { if c.read_deadline.unix == 0 { return c.read_deadline } - return none + return error('none') } // write_ptr blocks and attempts to write all data -pub fn (mut c TcpConn) write_ptr(b &u8, len int) ?int { +pub fn (mut c TcpConn) write_ptr(b &u8, len int) !int { $if trace_tcp ? { eprintln( '>>> TcpConn.write_ptr | c.sock.handle: $c.sock.handle | b: ${ptr_str(b)} len: $len |\n' + @@ -173,10 +173,10 @@ pub fn (mut c TcpConn) write_ptr(b &u8, len int) ?int { if sent < 0 { code := error_code() if code == int(error_ewouldblock) { - c.wait_for_write()? + c.wait_for_write()! continue } else { - wrap_error(code)? + wrap_error(code)! } } total_sent += sent @@ -186,12 +186,12 @@ pub fn (mut c TcpConn) write_ptr(b &u8, len int) ?int { } // write blocks and attempts to write all data -pub fn (mut c TcpConn) write(bytes []u8) ?int { +pub fn (mut c TcpConn) write(bytes []u8) !int { return c.write_ptr(bytes.data, bytes.len) } // write_string blocks and attempts to write all data -pub fn (mut c TcpConn) write_string(s string) ?int { +pub fn (mut c TcpConn) write_string(s string) !int { return c.write_ptr(s.str, s.len) } @@ -199,11 +199,11 @@ pub fn (mut c TcpConn) set_read_deadline(deadline time.Time) { c.read_deadline = deadline } -pub fn (mut c TcpConn) write_deadline() ?time.Time { +pub fn (mut c TcpConn) write_deadline() !time.Time { if c.write_deadline.unix == 0 { return c.write_deadline } - return none + return error('none') } pub fn (mut c TcpConn) set_write_deadline(deadline time.Time) { @@ -227,31 +227,31 @@ pub fn (mut c TcpConn) set_write_timeout(t time.Duration) { } [inline] -pub fn (c TcpConn) wait_for_read() ? { +pub fn (c TcpConn) wait_for_read() ! { return wait_for_read(c.sock.handle, c.read_deadline, c.read_timeout) } [inline] -pub fn (mut c TcpConn) wait_for_write() ? { +pub fn (mut c TcpConn) wait_for_write() ! { return wait_for_write(c.sock.handle, c.write_deadline, c.write_timeout) } -pub fn (c &TcpConn) peer_addr() ?Addr { +pub fn (c &TcpConn) peer_addr() !Addr { mut addr := Addr{ addr: AddrData{ Ip6: Ip6{} } } mut size := sizeof(Addr) - socket_error_message(C.getpeername(c.sock.handle, voidptr(&addr), &size), 'peer_addr failed')? + socket_error_message(C.getpeername(c.sock.handle, voidptr(&addr), &size), 'peer_addr failed')! return addr } -pub fn (c &TcpConn) peer_ip() ?string { - return c.peer_addr()?.str() +pub fn (c &TcpConn) peer_ip() !string { + return c.peer_addr()!.str() } -pub fn (c &TcpConn) addr() ?Addr { +pub fn (c &TcpConn) addr() !Addr { return c.sock.address() } @@ -268,7 +268,7 @@ mut: accept_deadline time.Time } -pub fn listen_tcp(family AddrFamily, saddr string) ?&TcpListener { +pub fn listen_tcp(family AddrFamily, saddr string) !&TcpListener { s := new_tcp_socket(family) or { return error('$err.msg(); could not create new socket') } addrs := resolve_addrs(saddr, family, .tcp) or { @@ -280,8 +280,8 @@ pub fn listen_tcp(family AddrFamily, saddr string) ?&TcpListener { // cast to the correct type alen := addr.len() - socket_error_message(C.bind(s.handle, voidptr(&addr), alen), 'binding to $saddr failed')? - socket_error_message(C.listen(s.handle, 128), 'listening on $saddr failed')? + socket_error_message(C.bind(s.handle, voidptr(&addr), alen), 'binding to $saddr failed')! + socket_error_message(C.listen(s.handle, 128), 'listening on $saddr failed')! return &TcpListener{ sock: s accept_deadline: no_deadline @@ -289,19 +289,19 @@ pub fn listen_tcp(family AddrFamily, saddr string) ?&TcpListener { } } -pub fn (mut l TcpListener) accept() ?&TcpConn { +pub fn (mut l TcpListener) accept() !&TcpConn { $if trace_tcp ? { eprintln(' TcpListener.accept | l.sock.handle: ${l.sock.handle:6}') } mut new_handle := C.accept(l.sock.handle, 0, 0) if new_handle <= 0 { - l.wait_for_accept()? + l.wait_for_accept()! new_handle = C.accept(l.sock.handle, 0, 0) if new_handle == -1 || new_handle == 0 { return error('accept failed') } } - new_sock := tcp_socket_from_handle(new_handle)? + new_sock := tcp_socket_from_handle(new_handle)! $if trace_tcp ? { eprintln(' TcpListener.accept | << new_sock.handle: ${new_sock.handle:6}') } @@ -312,7 +312,7 @@ pub fn (mut l TcpListener) accept() ?&TcpConn { } } -pub fn (c &TcpListener) accept_deadline() ?time.Time { +pub fn (c &TcpListener) accept_deadline() !time.Time { if c.accept_deadline.unix != 0 { return c.accept_deadline } @@ -331,15 +331,15 @@ pub fn (mut c TcpListener) set_accept_timeout(t time.Duration) { c.accept_timeout = t } -pub fn (mut c TcpListener) wait_for_accept() ? { +pub fn (mut c TcpListener) wait_for_accept() ! { return wait_for_read(c.sock.handle, c.accept_deadline, c.accept_timeout) } -pub fn (mut c TcpListener) close() ? { - c.sock.close()? +pub fn (mut c TcpListener) close() ! { + c.sock.close()! } -pub fn (c &TcpListener) addr() ?Addr { +pub fn (c &TcpListener) addr() !Addr { return c.sock.address() } @@ -347,8 +347,8 @@ struct TcpSocket { Socket } -fn new_tcp_socket(family AddrFamily) ?TcpSocket { - handle := socket_error(C.socket(family, SocketType.tcp, 0))? +fn new_tcp_socket(family AddrFamily) !TcpSocket { + handle := socket_error(C.socket(family, SocketType.tcp, 0))! mut s := TcpSocket{ handle: handle } @@ -362,20 +362,20 @@ fn new_tcp_socket(family AddrFamily) ?TcpSocket { // TODO(emily): // Move this to its own function on the socket - s.set_option_int(.reuse_addr, 1)? + s.set_option_int(.reuse_addr, 1)! $if !net_blocking_sockets ? { $if windows { t := u32(1) // true - socket_error(C.ioctlsocket(handle, fionbio, &t))? + socket_error(C.ioctlsocket(handle, fionbio, &t))! } $else { - socket_error(C.fcntl(handle, C.F_SETFL, C.fcntl(handle, C.F_GETFL) | C.O_NONBLOCK))? + socket_error(C.fcntl(handle, C.F_SETFL, C.fcntl(handle, C.F_GETFL) | C.O_NONBLOCK))! } } return s } -fn tcp_socket_from_handle(sockfd int) ?TcpSocket { +fn tcp_socket_from_handle(sockfd int) !TcpSocket { mut s := TcpSocket{ handle: sockfd } @@ -383,22 +383,22 @@ fn tcp_socket_from_handle(sockfd int) ?TcpSocket { eprintln(' tcp_socket_from_handle | s.handle: ${s.handle:6}') } // s.set_option_bool(.reuse_addr, true)? - s.set_option_int(.reuse_addr, 1)? + s.set_option_int(.reuse_addr, 1)! s.set_dualstack(true) or { // Not ipv6, we dont care } $if !net_blocking_sockets ? { $if windows { t := u32(1) // true - socket_error(C.ioctlsocket(sockfd, fionbio, &t))? + socket_error(C.ioctlsocket(sockfd, fionbio, &t))! } $else { - socket_error(C.fcntl(sockfd, C.F_SETFL, C.fcntl(sockfd, C.F_GETFL) | C.O_NONBLOCK))? + socket_error(C.fcntl(sockfd, C.F_SETFL, C.fcntl(sockfd, C.F_GETFL) | C.O_NONBLOCK))! } } return s } -pub fn (mut s TcpSocket) set_option_bool(opt SocketOption, value bool) ? { +pub fn (mut s TcpSocket) set_option_bool(opt SocketOption, value bool) ! { // TODO reenable when this `in` operation works again // if opt !in opts_can_set { // return err_option_not_settable @@ -407,21 +407,21 @@ pub fn (mut s TcpSocket) set_option_bool(opt SocketOption, value bool) ? { // return err_option_wrong_type // } x := int(value) - socket_error(C.setsockopt(s.handle, C.SOL_SOCKET, int(opt), &x, sizeof(int)))? + socket_error(C.setsockopt(s.handle, C.SOL_SOCKET, int(opt), &x, sizeof(int)))! } -pub fn (mut s TcpSocket) set_dualstack(on bool) ? { +pub fn (mut s TcpSocket) set_dualstack(on bool) ! { x := int(!on) socket_error(C.setsockopt(s.handle, C.IPPROTO_IPV6, int(SocketOption.ipv6_only), &x, - sizeof(int)))? + sizeof(int)))! } -pub fn (mut s TcpSocket) set_option_int(opt SocketOption, value int) ? { - socket_error(C.setsockopt(s.handle, C.SOL_SOCKET, int(opt), &value, sizeof(int)))? +pub fn (mut s TcpSocket) set_option_int(opt SocketOption, value int) ! { + socket_error(C.setsockopt(s.handle, C.SOL_SOCKET, int(opt), &value, sizeof(int)))! } // bind a local rddress for TcpSocket -pub fn (mut s TcpSocket) bind(addr string) ? { +pub fn (mut s TcpSocket) bind(addr string) ! { addrs := resolve_addrs(addr, AddrFamily.ip, .tcp) or { return error('$err.msg(); could not resolve address $addr') } @@ -436,11 +436,11 @@ pub fn (mut s TcpSocket) bind(addr string) ? { } } -fn (mut s TcpSocket) close() ? { +fn (mut s TcpSocket) close() ! { return shutdown(s.handle) } -fn (mut s TcpSocket) @select(test Select, timeout time.Duration) ?bool { +fn (mut s TcpSocket) @select(test Select, timeout time.Duration) !bool { return @select(s.handle, test, timeout) } @@ -448,7 +448,7 @@ const ( connect_timeout = 5 * time.second ) -fn (mut s TcpSocket) connect(a Addr) ? { +fn (mut s TcpSocket) connect(a Addr) ! { $if !net_blocking_sockets ? { res := C.connect(s.handle, voidptr(&a), a.len()) if res == 0 { @@ -467,7 +467,7 @@ fn (mut s TcpSocket) connect(a Addr) ? { // determine whether connect() completed successfully (SO_ERROR is zero) or // unsuccessfully (SO_ERROR is one of the usual error codes listed here, // ex‐ plaining the reason for the failure). - write_result := s.@select(.write, net.connect_timeout)? + write_result := s.@select(.write, net.connect_timeout)! err := 0 len := sizeof(err) xyz := C.getsockopt(s.handle, C.SOL_SOCKET, C.SO_ERROR, &err, &len) @@ -476,17 +476,17 @@ fn (mut s TcpSocket) connect(a Addr) ? { } if write_result { if xyz == 0 { - wrap_error(err)? + wrap_error(err)! return } return } return err_timed_out } - wrap_error(ecode)? + wrap_error(ecode)! return } $else { x := C.connect(s.handle, voidptr(&a), a.len()) - socket_error(x)? + socket_error(x)! } } diff --git a/vlib/net/tcp_read_line.v b/vlib/net/tcp_read_line.v index b7a9ed144..3d2672ba7 100644 --- a/vlib/net/tcp_read_line.v +++ b/vlib/net/tcp_read_line.v @@ -22,14 +22,14 @@ pub fn (mut con TcpConn) get_blocking() bool { // when state is true, or non blocking (false). // The default for `net` tcp connections is the non blocking mode. // Calling .read_line will set the connection to blocking mode. -pub fn (mut con TcpConn) set_blocking(state bool) ? { +pub fn (mut con TcpConn) set_blocking(state bool) ! { con.is_blocking = state $if windows { mut t := u32(0) if !con.is_blocking { t = 1 } - socket_error(C.ioctlsocket(con.sock.handle, fionbio, &t))? + socket_error(C.ioctlsocket(con.sock.handle, fionbio, &t))! } $else { mut flags := C.fcntl(con.sock.handle, C.F_GETFL, 0) if state { @@ -37,7 +37,7 @@ pub fn (mut con TcpConn) set_blocking(state bool) ? { } else { flags |= C.O_NONBLOCK } - socket_error(C.fcntl(con.sock.handle, C.F_SETFL, flags))? + socket_error(C.fcntl(con.sock.handle, C.F_SETFL, flags))! } } diff --git a/vlib/net/udp.v b/vlib/net/udp.v index 9c2db6515..0d6abe80e 100644 --- a/vlib/net/udp.v +++ b/vlib/net/udp.v @@ -27,8 +27,8 @@ mut: write_timeout time.Duration } -pub fn dial_udp(raddr string) ?&UdpConn { - addrs := resolve_addrs_fuzzy(raddr, .udp)? +pub fn dial_udp(raddr string) !&UdpConn { + addrs := resolve_addrs_fuzzy(raddr, .udp)! for addr in addrs { // create a local socket for this @@ -43,7 +43,7 @@ pub fn dial_udp(raddr string) ?&UdpConn { } } - return none + return error('none') } // pub fn dial_udp(laddr string, raddr string) ?&UdpConn { @@ -58,46 +58,46 @@ pub fn dial_udp(raddr string) ?&UdpConn { // } // } -pub fn (mut c UdpConn) write_ptr(b &u8, len int) ?int { +pub fn (mut c UdpConn) write_ptr(b &u8, len int) !int { remote := c.sock.remote() or { return err_no_udp_remote } return c.write_to_ptr(remote, b, len) } -pub fn (mut c UdpConn) write(buf []u8) ?int { +pub fn (mut c UdpConn) write(buf []u8) !int { return c.write_ptr(buf.data, buf.len) } -pub fn (mut c UdpConn) write_string(s string) ?int { +pub fn (mut c UdpConn) write_string(s string) !int { return c.write_ptr(s.str, s.len) } -pub fn (mut c UdpConn) write_to_ptr(addr Addr, b &u8, len int) ?int { +pub fn (mut c UdpConn) write_to_ptr(addr Addr, b &u8, len int) !int { res := C.sendto(c.sock.handle, b, len, 0, voidptr(&addr), addr.len()) if res >= 0 { return res } code := error_code() if code == int(error_ewouldblock) { - c.wait_for_write()? - socket_error(C.sendto(c.sock.handle, b, len, 0, voidptr(&addr), addr.len()))? + c.wait_for_write()! + socket_error(C.sendto(c.sock.handle, b, len, 0, voidptr(&addr), addr.len()))! } else { - wrap_error(code)? + wrap_error(code)! } - return none + return error('none') } // write_to blocks and writes the buf to the remote addr specified -pub fn (mut c UdpConn) write_to(addr Addr, buf []u8) ?int { +pub fn (mut c UdpConn) write_to(addr Addr, buf []u8) !int { return c.write_to_ptr(addr, buf.data, buf.len) } // write_to_string blocks and writes the buf to the remote addr specified -pub fn (mut c UdpConn) write_to_string(addr Addr, s string) ?int { +pub fn (mut c UdpConn) write_to_string(addr Addr, s string) !int { return c.write_to_ptr(addr, s.str, s.len) } // read reads from the socket into buf up to buf.len returning the number of bytes read -pub fn (mut c UdpConn) read(mut buf []u8) ?(int, Addr) { +pub fn (mut c UdpConn) read(mut buf []u8) !(int, Addr) { mut addr := Addr{ addr: AddrData{ Ip6: Ip6{} @@ -105,40 +105,40 @@ pub fn (mut c UdpConn) read(mut buf []u8) ?(int, Addr) { } len := sizeof(Addr) mut res := wrap_read_result(C.recvfrom(c.sock.handle, voidptr(buf.data), buf.len, - 0, voidptr(&addr), &len))? + 0, voidptr(&addr), &len))! if res > 0 { return res, addr } code := error_code() if code == int(error_ewouldblock) { - c.wait_for_read()? + c.wait_for_read()! // same setup as in tcp res = wrap_read_result(C.recvfrom(c.sock.handle, voidptr(buf.data), buf.len, 0, - voidptr(&addr), &len))? - res2 := socket_error(res)? + voidptr(&addr), &len))! + res2 := socket_error(res)! return res2, addr } else { - wrap_error(code)? + wrap_error(code)! } - return none + return error('none') } -pub fn (c &UdpConn) read_deadline() ?time.Time { +pub fn (c &UdpConn) read_deadline() !time.Time { if c.read_deadline.unix == 0 { return c.read_deadline } - return none + return error('none') } pub fn (mut c UdpConn) set_read_deadline(deadline time.Time) { c.read_deadline = deadline } -pub fn (c &UdpConn) write_deadline() ?time.Time { +pub fn (c &UdpConn) write_deadline() !time.Time { if c.write_deadline.unix == 0 { return c.write_deadline } - return none + return error('none') } pub fn (mut c UdpConn) set_write_deadline(deadline time.Time) { @@ -162,12 +162,12 @@ pub fn (mut c UdpConn) set_write_timeout(t time.Duration) { } [inline] -pub fn (mut c UdpConn) wait_for_read() ? { +pub fn (mut c UdpConn) wait_for_read() ! { return wait_for_read(c.sock.handle, c.read_deadline, c.read_timeout) } [inline] -pub fn (mut c UdpConn) wait_for_write() ? { +pub fn (mut c UdpConn) wait_for_write() ! { return wait_for_write(c.sock.handle, c.write_deadline, c.write_timeout) } @@ -176,27 +176,27 @@ pub fn (c &UdpConn) str() string { return 'UdpConn' } -pub fn (mut c UdpConn) close() ? { +pub fn (mut c UdpConn) close() ! { return c.sock.close() } -pub fn listen_udp(laddr string) ?&UdpConn { - addrs := resolve_addrs_fuzzy(laddr, .udp)? +pub fn listen_udp(laddr string) !&UdpConn { + addrs := resolve_addrs_fuzzy(laddr, .udp)! // TODO(emily): // here we are binding to the first address // and that is probably not ideal addr := addrs[0] return &UdpConn{ - sock: new_udp_socket(addr)? + sock: new_udp_socket(addr)! read_timeout: net.udp_default_read_timeout write_timeout: net.udp_default_write_timeout } } -fn new_udp_socket(local_addr Addr) ?&UdpSocket { +fn new_udp_socket(local_addr Addr) !&UdpSocket { family := local_addr.family() - sockfd := socket_error(C.socket(family, SocketType.udp, 0))? + sockfd := socket_error(C.socket(family, SocketType.udp, 0))! mut s := &UdpSocket{ handle: sockfd l: local_addr @@ -207,28 +207,28 @@ fn new_udp_socket(local_addr Addr) ?&UdpSocket { } } - s.set_option_bool(.reuse_addr, true)? + s.set_option_bool(.reuse_addr, true)! if family == .ip6 { - s.set_dualstack(true)? + s.set_dualstack(true)! } $if !net_blocking_sockets ? { // NOTE: refer to comments in tcp.v $if windows { t := u32(1) // true - socket_error(C.ioctlsocket(sockfd, fionbio, &t))? + socket_error(C.ioctlsocket(sockfd, fionbio, &t))! } $else { - socket_error(C.fcntl(sockfd, C.F_SETFD, C.O_NONBLOCK))? + socket_error(C.fcntl(sockfd, C.F_SETFD, C.O_NONBLOCK))! } } // cast to the correct type - socket_error(C.bind(s.handle, voidptr(&local_addr), local_addr.len()))? + socket_error(C.bind(s.handle, voidptr(&local_addr), local_addr.len()))! return s } -fn new_udp_socket_for_remote(raddr Addr) ?&UdpSocket { +fn new_udp_socket_for_remote(raddr Addr) !&UdpSocket { // Invent a sutible local address for this remote addr // Appease compiler mut addr := Addr{ @@ -246,20 +246,20 @@ fn new_udp_socket_for_remote(raddr Addr) ?&UdpSocket { addr = new_ip6(0, addr_ip6_any) } .unix { - addr = temp_unix()? + addr = temp_unix()! } else { panic('Invalid family') } } - mut sock := new_udp_socket(addr)? + mut sock := new_udp_socket(addr)! sock.has_r = true sock.r = raddr return sock } -pub fn (mut s UdpSocket) set_option_bool(opt SocketOption, value bool) ? { +pub fn (mut s UdpSocket) set_option_bool(opt SocketOption, value bool) ! { // TODO reenable when this `in` operation works again // if opt !in opts_can_set { // return err_option_not_settable @@ -268,26 +268,26 @@ pub fn (mut s UdpSocket) set_option_bool(opt SocketOption, value bool) ? { // return err_option_wrong_type // } x := int(value) - socket_error(C.setsockopt(s.handle, C.SOL_SOCKET, int(opt), &x, sizeof(int)))? + socket_error(C.setsockopt(s.handle, C.SOL_SOCKET, int(opt), &x, sizeof(int)))! } -pub fn (mut s UdpSocket) set_dualstack(on bool) ? { +pub fn (mut s UdpSocket) set_dualstack(on bool) ! { x := int(!on) socket_error(C.setsockopt(s.handle, C.IPPROTO_IPV6, int(SocketOption.ipv6_only), &x, - sizeof(int)))? + sizeof(int)))! } -fn (mut s UdpSocket) close() ? { +fn (mut s UdpSocket) close() ! { return shutdown(s.handle) } -fn (mut s UdpSocket) @select(test Select, timeout time.Duration) ?bool { +fn (mut s UdpSocket) @select(test Select, timeout time.Duration) !bool { return @select(s.handle, test, timeout) } -fn (s &UdpSocket) remote() ?Addr { +fn (s &UdpSocket) remote() !Addr { if s.has_r { return s.r } - return none + return error('none') } diff --git a/vlib/net/udp_test.v b/vlib/net/udp_test.v index e4d4adf63..5ca749ac6 100644 --- a/vlib/net/udp_test.v +++ b/vlib/net/udp_test.v @@ -24,7 +24,7 @@ fn echo_server(mut c net.UdpConn) { const server_addr = '127.0.0.1:40003' -fn echo() ? { +fn echo() ! { mut c := net.dial_udp(server_addr) or { panic('could not net.dial_udp: $err') } defer { c.close() or {} @@ -48,7 +48,7 @@ fn echo() ? { println('Got "$buf.bytestr()"') - c.close()? + c.close()! } fn test_udp() { diff --git a/vlib/net/unix/common.v b/vlib/net/unix/common.v index 9891e3030..348519285 100644 --- a/vlib/net/unix/common.v +++ b/vlib/net/unix/common.v @@ -12,18 +12,18 @@ fn C.SUN_LEN(ptr &C.sockaddr_un) int fn C.strncpy(&char, &char, int) // Shutdown shutsdown a socket and closes it -fn shutdown(handle int) ? { +fn shutdown(handle int) ! { $if windows { C.shutdown(handle, C.SD_BOTH) - net.socket_error(C.closesocket(handle))? + net.socket_error(C.closesocket(handle))! } $else { C.shutdown(handle, C.SHUT_RDWR) - net.socket_error(C.close(handle))? + net.socket_error(C.close(handle))! } } // Select waits for an io operation (specified by parameter `test`) to be available -fn @select(handle int, test Select, timeout time.Duration) ?bool { +fn @select(handle int, test Select, timeout time.Duration) !bool { set := C.fd_set{} C.FD_ZERO(&set) @@ -47,13 +47,13 @@ fn @select(handle int, test Select, timeout time.Duration) ?bool { match test { .read { - net.socket_error(C.@select(handle + 1, &set, C.NULL, C.NULL, timeval_timeout))? + net.socket_error(C.@select(handle + 1, &set, C.NULL, C.NULL, timeval_timeout))! } .write { - net.socket_error(C.@select(handle + 1, C.NULL, &set, C.NULL, timeval_timeout))? + net.socket_error(C.@select(handle + 1, C.NULL, &set, C.NULL, timeval_timeout))! } .except { - net.socket_error(C.@select(handle + 1, C.NULL, C.NULL, &set, timeval_timeout))? + net.socket_error(C.@select(handle + 1, C.NULL, C.NULL, &set, timeval_timeout))! } } @@ -61,13 +61,13 @@ fn @select(handle int, test Select, timeout time.Duration) ?bool { } // wait_for_common wraps the common wait code -fn wait_for_common(handle int, deadline time.Time, timeout time.Duration, test Select) ? { +fn wait_for_common(handle int, deadline time.Time, timeout time.Duration, test Select) ! { if deadline.unix == 0 { // do not accept negative timeout if timeout < 0 { return net.err_timed_out } - ready := @select(handle, test, timeout)? + ready := @select(handle, test, timeout)! if ready { return } @@ -82,7 +82,7 @@ fn wait_for_common(handle int, deadline time.Time, timeout time.Duration, test S return net.err_timed_out } - ready := @select(handle, test, d_timeout)? + ready := @select(handle, test, d_timeout)! if ready { return } @@ -90,12 +90,12 @@ fn wait_for_common(handle int, deadline time.Time, timeout time.Duration, test S } // wait_for_write waits for a write io operation to be available -fn wait_for_write(handle int, deadline time.Time, timeout time.Duration) ? { +fn wait_for_write(handle int, deadline time.Time, timeout time.Duration) ! { return wait_for_common(handle, deadline, timeout, .write) } // wait_for_read waits for a read io operation to be available -fn wait_for_read(handle int, deadline time.Time, timeout time.Duration) ? { +fn wait_for_read(handle int, deadline time.Time, timeout time.Duration) ! { return wait_for_common(handle, deadline, timeout, .read) } @@ -120,9 +120,9 @@ const ( ) [inline] -fn wrap_read_result(result int) ?int { +fn wrap_read_result(result int) !int { if result != 0 { return result } - return none + return error('none') } diff --git a/vlib/net/unix/stream_nix.v b/vlib/net/unix/stream_nix.v index 918c6841d..d13b0c7bd 100644 --- a/vlib/net/unix/stream_nix.v +++ b/vlib/net/unix/stream_nix.v @@ -40,23 +40,23 @@ fn error_code() int { return C.errno } -fn new_stream_socket() ?StreamSocket { - sockfd := net.socket_error(C.socket(net.AddrFamily.unix, net.SocketType.tcp, 0))? +fn new_stream_socket() !StreamSocket { + sockfd := net.socket_error(C.socket(net.AddrFamily.unix, net.SocketType.tcp, 0))! mut s := StreamSocket{ handle: sockfd } return s } -fn (mut s StreamSocket) close() ? { +fn (mut s StreamSocket) close() ! { return shutdown(s.handle) } -fn (mut s StreamSocket) @select(test Select, timeout time.Duration) ?bool { +fn (mut s StreamSocket) @select(test Select, timeout time.Duration) !bool { return @select(s.handle, test, timeout) } -fn (mut s StreamSocket) connect(a string) ? { +fn (mut s StreamSocket) connect(a string) ! { if a.len >= max_sun_path { return error('Socket path too long! Max length: ${max_sun_path - 1} chars.') } @@ -73,12 +73,12 @@ fn (mut s StreamSocket) connect(a string) ? { return } _ := error_code() - write_result := s.@select(.write, unix.connect_timeout)? + write_result := s.@select(.write, unix.connect_timeout)! if write_result { // succeeded return } - except_result := s.@select(.except, unix.connect_timeout)? + except_result := s.@select(.except, unix.connect_timeout)! if except_result { return net.err_connect_failed } @@ -86,11 +86,11 @@ fn (mut s StreamSocket) connect(a string) ? { return net.err_connect_timed_out } -pub fn listen_stream(sock string) ?&StreamListener { +pub fn listen_stream(sock string) !&StreamListener { if sock.len >= max_sun_path { return error('Socket path too long! Max length: ${max_sun_path - 1} chars.') } - mut s := new_stream_socket()? + mut s := new_stream_socket()! s.path = sock mut addr := C.sockaddr_un{} unsafe { C.memset(&addr, 0, sizeof(C.sockaddr_un)) } @@ -98,19 +98,19 @@ pub fn listen_stream(sock string) ?&StreamListener { unsafe { C.strncpy(&addr.sun_path[0], &char(sock.str), max_sun_path) } size := C.SUN_LEN(&addr) if os.exists(sock) { - os.rm(sock)? + os.rm(sock)! } - net.socket_error(C.bind(s.handle, voidptr(&addr), size))? - os.chmod(sock, 0o777)? - net.socket_error(C.listen(s.handle, 128))? + net.socket_error(C.bind(s.handle, voidptr(&addr), size))! + os.chmod(sock, 0o777)! + net.socket_error(C.listen(s.handle, 128))! return &StreamListener{ sock: s } } -pub fn connect_stream(path string) ?&StreamConn { - mut s := new_stream_socket()? - s.connect(path)? +pub fn connect_stream(path string) !&StreamConn { + mut s := new_stream_socket()! + s.connect(path)! return &StreamConn{ sock: s read_timeout: unix.unix_default_read_timeout @@ -118,10 +118,10 @@ pub fn connect_stream(path string) ?&StreamConn { } } -pub fn (mut l StreamListener) accept() ?&StreamConn { +pub fn (mut l StreamListener) accept() !&StreamConn { mut new_handle := C.accept(l.sock.handle, 0, 0) if new_handle <= 0 { - l.wait_for_accept()? + l.wait_for_accept()! new_handle = C.accept(l.sock.handle, 0, 0) if new_handle == -1 || new_handle == 0 { return error('accept failed') @@ -137,7 +137,7 @@ pub fn (mut l StreamListener) accept() ?&StreamConn { } } -pub fn (c &StreamListener) accept_deadline() ?time.Time { +pub fn (c &StreamListener) accept_deadline() !time.Time { if c.accept_deadline.unix != 0 { return c.accept_deadline } @@ -156,21 +156,21 @@ pub fn (mut c StreamListener) set_accept_timeout(t time.Duration) { c.accept_timeout = t } -pub fn (mut c StreamListener) wait_for_accept() ? { +pub fn (mut c StreamListener) wait_for_accept() ! { return wait_for_read(c.sock.handle, c.accept_deadline, c.accept_timeout) } -pub fn (mut c StreamListener) close() ? { - os.rm(c.sock.path)? - c.sock.close()? +pub fn (mut c StreamListener) close() ! { + os.rm(c.sock.path)! + c.sock.close()! } -pub fn (mut c StreamConn) close() ? { - c.sock.close()? +pub fn (mut c StreamConn) close() ! { + c.sock.close()! } // write_ptr blocks and attempts to write all data -pub fn (mut c StreamConn) write_ptr(b &u8, len int) ?int { +pub fn (mut c StreamConn) write_ptr(b &u8, len int) !int { $if trace_unix ? { eprintln( '>>> StreamConn.write_ptr | c.sock.handle: $c.sock.handle | b: ${ptr_str(b)} len: $len |\n' + @@ -186,10 +186,10 @@ pub fn (mut c StreamConn) write_ptr(b &u8, len int) ?int { if sent < 0 { code := error_code() if code == int(error_ewouldblock) { - c.wait_for_write()? + c.wait_for_write()! continue } else { - net.wrap_error(code)? + net.wrap_error(code)! } } total_sent += sent @@ -199,17 +199,17 @@ pub fn (mut c StreamConn) write_ptr(b &u8, len int) ?int { } // write blocks and attempts to write all data -pub fn (mut c StreamConn) write(bytes []u8) ?int { +pub fn (mut c StreamConn) write(bytes []u8) !int { return c.write_ptr(bytes.data, bytes.len) } // write_string blocks and attempts to write all data -pub fn (mut c StreamConn) write_string(s string) ?int { +pub fn (mut c StreamConn) write_string(s string) !int { return c.write_ptr(s.str, s.len) } -pub fn (mut c StreamConn) read_ptr(buf_ptr &u8, len int) ?int { - mut res := wrap_read_result(C.recv(c.sock.handle, voidptr(buf_ptr), len, 0))? +pub fn (mut c StreamConn) read_ptr(buf_ptr &u8, len int) !int { + mut res := wrap_read_result(C.recv(c.sock.handle, voidptr(buf_ptr), len, 0))! $if trace_unix ? { eprintln('<<< StreamConn.read_ptr | c.sock.handle: $c.sock.handle | buf_ptr: ${ptr_str(buf_ptr)} len: $len | res: $res') } @@ -218,38 +218,38 @@ pub fn (mut c StreamConn) read_ptr(buf_ptr &u8, len int) ?int { } code := error_code() if code == int(error_ewouldblock) { - c.wait_for_read()? - res = wrap_read_result(C.recv(c.sock.handle, voidptr(buf_ptr), len, 0))? + c.wait_for_read()! + res = wrap_read_result(C.recv(c.sock.handle, voidptr(buf_ptr), len, 0))! $if trace_unix ? { eprintln('<<< StreamConn.read_ptr | c.sock.handle: $c.sock.handle | buf_ptr: ${ptr_str(buf_ptr)} len: $len | res: $res') } return net.socket_error(res) } else { - net.wrap_error(code)? + net.wrap_error(code)! } return net.socket_error(code) } -pub fn (mut c StreamConn) read(mut buf []u8) ?int { +pub fn (mut c StreamConn) read(mut buf []u8) !int { return c.read_ptr(buf.data, buf.len) } -pub fn (mut c StreamConn) read_deadline() ?time.Time { +pub fn (mut c StreamConn) read_deadline() !time.Time { if c.read_deadline.unix == 0 { return c.read_deadline } - return none + return error('none') } pub fn (mut c StreamConn) set_read_deadline(deadline time.Time) { c.read_deadline = deadline } -pub fn (mut c StreamConn) write_deadline() ?time.Time { +pub fn (mut c StreamConn) write_deadline() !time.Time { if c.write_deadline.unix == 0 { return c.write_deadline } - return none + return error('none') } pub fn (mut c StreamConn) set_write_deadline(deadline time.Time) { @@ -273,12 +273,12 @@ pub fn (mut c StreamConn) set_write_timeout(t time.Duration) { } [inline] -pub fn (mut c StreamConn) wait_for_read() ? { +pub fn (mut c StreamConn) wait_for_read() ! { return wait_for_read(c.sock.handle, c.read_deadline, c.read_timeout) } [inline] -pub fn (mut c StreamConn) wait_for_write() ? { +pub fn (mut c StreamConn) wait_for_write() ! { return wait_for_write(c.sock.handle, c.write_deadline, c.write_timeout) } diff --git a/vlib/net/unix/unix_test.v b/vlib/net/unix/unix_test.v index d3cea9e6a..0813cb995 100644 --- a/vlib/net/unix/unix_test.v +++ b/vlib/net/unix/unix_test.v @@ -27,22 +27,22 @@ fn handle_conn(mut c unix.StreamConn) { } } -fn echo_server(mut l unix.StreamListener) ? { +fn echo_server(mut l unix.StreamListener) ! { for { mut new_conn := l.accept() or { continue } go handle_conn(mut new_conn) } } -fn echo() ? { - mut c := unix.connect_stream(test_port)? +fn echo() ! { + mut c := unix.connect_stream(test_port)! defer { c.close() or {} } data := 'Hello from vlib/net!' - c.write_string(data)? + c.write_string(data)! mut buf := []u8{len: 4096} - read := c.read(mut buf)? + read := c.read(mut buf)! assert read == data.len for i := 0; i < read; i++ { assert buf[i] == data[i] diff --git a/vlib/net/unix/use_net_and_net_unix_together_test.v b/vlib/net/unix/use_net_and_net_unix_together_test.v index 96774d8a1..85f277d34 100644 --- a/vlib/net/unix/use_net_and_net_unix_together_test.v +++ b/vlib/net/unix/use_net_and_net_unix_together_test.v @@ -17,31 +17,31 @@ fn testsuite_end() { os.rmdir_all(tfolder) or {} } -fn test_that_net_and_net_unix_can_be_imported_together_without_conflicts() ? { +fn test_that_net_and_net_unix_can_be_imported_together_without_conflicts() { mut l := unix.listen_stream(test_port) or { panic(err) } go echo_server(mut l) defer { l.close() or {} } // - mut c := unix.connect_stream(test_port)? + mut c := unix.connect_stream(test_port)! defer { c.close() or {} } // data := 'Hello from vlib/net!' - c.write_string(data)? + c.write_string(data)! mut buf := []u8{len: 100} - assert c.read(mut buf)? == data.len + assert c.read(mut buf)! == data.len eprintln('< client read back buf: |${buf[0..data.len].bytestr()}|') assert buf[0..data.len] == data.bytes() } -fn perror(s string) ? { +fn perror(s string) ! { println(s) } -fn handle_conn(mut c unix.StreamConn) ? { +fn handle_conn(mut c unix.StreamConn) ! { for { mut buf := []u8{len: 100, init: 0} read := c.read(mut buf) or { return perror('Server: connection dropped') } @@ -50,7 +50,7 @@ fn handle_conn(mut c unix.StreamConn) ? { } } -fn echo_server(mut l unix.StreamListener) ? { +fn echo_server(mut l unix.StreamListener) ! { for { mut new_conn := l.accept() or { continue } handle_conn(mut new_conn) or {} diff --git a/vlib/net/urllib/urllib.v b/vlib/net/urllib/urllib.v index 3a617dc86..1b322a24b 100644 --- a/vlib/net/urllib/urllib.v +++ b/vlib/net/urllib/urllib.v @@ -127,7 +127,7 @@ fn should_escape(c u8, mode EncodingMode) bool { // hex-decoded byte 0xAB. // It returns an error if any % is not followed by two hexadecimal // digits. -pub fn query_unescape(s string) ?string { +pub fn query_unescape(s string) !string { return unescape(s, .encode_query_component) } @@ -138,13 +138,13 @@ pub fn query_unescape(s string) ?string { // // path_unescape is identical to query_unescape except that it does not // unescape '+' to ' ' (space). -pub fn path_unescape(s string) ?string { +pub fn path_unescape(s string) !string { return unescape(s, .encode_path_segment) } // unescape unescapes a string; the mode specifies // which section of the URL string is being unescaped. -fn unescape(s_ string, mode EncodingMode) ?string { +fn unescape(s_ string, mode EncodingMode) !string { mut s := s_ // Count %, check that they're well-formed. mut n := 0 @@ -387,7 +387,7 @@ fn (u &Userinfo) str() string { // Maybe rawurl is of the form scheme:path. // (scheme must be [a-zA-Z][a-zA-Z0-9+-.]*) // If so, return [scheme, path]; else return ['', rawurl] -fn split_by_scheme(rawurl string) ?[]string { +fn split_by_scheme(rawurl string) ![]string { for i in 0 .. rawurl.len { c := rawurl[i] if (`a` <= c && c <= `z`) || (`A` <= c && c <= `Z`) { @@ -410,7 +410,7 @@ fn split_by_scheme(rawurl string) ?[]string { return ['', rawurl] } -fn get_scheme(rawurl string) ?string { +fn get_scheme(rawurl string) !string { split := split_by_scheme(rawurl) or { return err.msg() } return split[0] } @@ -435,7 +435,7 @@ fn split(s string, sep u8, cutc bool) (string, string) { // (starting with a scheme). Trying to parse a hostname and path // without a scheme is invalid but may not necessarily return an // error, due to parsing ambiguities. -pub fn parse(rawurl string) ?URL { +pub fn parse(rawurl string) !URL { // Cut off #frag u, frag := split(rawurl, `#`, true) mut url := parse_url(u, false) or { return error(error_msg(urllib.err_msg_parse, u)) } @@ -453,7 +453,7 @@ pub fn parse(rawurl string) ?URL { // only as an absolute URI or an absolute path. // The string rawurl is assumed not to have a #fragment suffix. // (Web browsers strip #fragment before sending the URL to a web server.) -fn parse_request_uri(rawurl string) ?URL { +fn parse_request_uri(rawurl string) !URL { return parse_url(rawurl, true) } @@ -462,7 +462,7 @@ fn parse_request_uri(rawurl string) ?URL { // in which case only absolute URLs or path-absolute relative URLs are allowed. // If via_request is false, all forms of relative URLs are allowed. [manualfree] -fn parse_url(rawurl string, via_request bool) ?URL { +fn parse_url(rawurl string, via_request bool) !URL { if string_contains_ctl_u8(rawurl) { return error(error_msg('parse_url: invalid control character in URL', rawurl)) } @@ -478,7 +478,7 @@ fn parse_url(rawurl string, via_request bool) ?URL { } // Split off possible leading 'http:', 'mailto:', etc. // Cannot contain escaped characters. - p := split_by_scheme(rawurl)? + p := split_by_scheme(rawurl)! url.scheme = p[0] mut rest := p[1] url.scheme = url.scheme.to_lower() @@ -517,7 +517,7 @@ fn parse_url(rawurl string, via_request bool) ?URL { if ((url.scheme != '' || !via_request) && !rest.starts_with('///')) && rest.starts_with('//') { authority, r := split(rest[2..], `/`, false) rest = r - a := parse_authority(authority)? + a := parse_authority(authority)! url.user = a.user url.host = a.host } @@ -525,7 +525,7 @@ fn parse_url(rawurl string, via_request bool) ?URL { // raw_path is a hint of the encoding of path. We don't want to set it if // the default escaping of path is equivalent, to help make sure that people // don't rely on it in general. - url.set_path(rest)? + url.set_path(rest)! return url } @@ -534,15 +534,15 @@ struct ParseAuthorityRes { host string } -fn parse_authority(authority string) ?ParseAuthorityRes { +fn parse_authority(authority string) !ParseAuthorityRes { i := authority.last_index('@') or { -1 } mut host := '' mut zuser := user('') if i < 0 { - h := parse_host(authority)? + h := parse_host(authority)! host = h } else { - h := parse_host(authority[i + 1..])? + h := parse_host(authority[i + 1..])! host = h } if i < 0 { @@ -556,14 +556,14 @@ fn parse_authority(authority string) ?ParseAuthorityRes { return error(error_msg('parse_authority: invalid userinfo', '')) } if !userinfo.contains(':') { - u := unescape(userinfo, .encode_user_password)? + u := unescape(userinfo, .encode_user_password)! userinfo = u zuser = user(userinfo) } else { mut username, mut password := split(userinfo, `:`, true) - u := unescape(username, .encode_user_password)? + u := unescape(username, .encode_user_password)! username = u - p := unescape(password, .encode_user_password)? + p := unescape(password, .encode_user_password)! password = p zuser = user_password(username, password) } @@ -575,7 +575,7 @@ fn parse_authority(authority string) ?ParseAuthorityRes { // parse_host parses host as an authority without user // information. That is, as host[:port]. -fn parse_host(host string) ?string { +fn parse_host(host string) !string { if host.starts_with('[') { // parse an IP-Literal in RFC 3986 and RFC 6874. // E.g., '[fe80::1]', '[fe80::1%25en0]', '[fe80::1]:80'. @@ -620,8 +620,8 @@ fn parse_host(host string) ?string { // - set_path('/foo%2fbar') will set path='/foo/bar' and raw_path='/foo%2fbar' // set_path will return an error only if the provided path contains an invalid // escaping. -pub fn (mut u URL) set_path(p string) ?bool { - u.path = unescape(p, .encode_path)? +pub fn (mut u URL) set_path(p string) !bool { + u.path = unescape(p, .encode_path)! u.raw_path = if p == escape(u.path, .encode_path) { '' } else { p } return true } @@ -781,9 +781,9 @@ pub fn (u URL) str() string { // Query is expected to be a list of key=value settings separated by // ampersands or semicolons. A setting without an equals sign is // interpreted as a key set to an empty value. -pub fn parse_query(query string) ?Values { +pub fn parse_query(query string) !Values { mut m := new_values() - parse_query_values(mut m, query)? + parse_query_values(mut m, query)! return m } @@ -795,7 +795,7 @@ fn parse_query_silent(query string) Values { return m } -fn parse_query_values(mut m Values, query string) ?bool { +fn parse_query_values(mut m Values, query string) !bool { mut had_error := false mut q := query for q != '' { @@ -914,8 +914,8 @@ pub fn (u &URL) is_abs() bool { // parse parses a URL in the context of the receiver. The provided URL // may be relative or absolute. parse returns nil, err on parse // failure, otherwise its return value is the same as resolve_reference. -pub fn (u &URL) parse(ref string) ?URL { - refurl := parse(ref)? +pub fn (u &URL) parse(ref string) !URL { + refurl := parse(ref)! return u.resolve_reference(refurl) } @@ -925,7 +925,7 @@ pub fn (u &URL) parse(ref string) ?URL { // URL instance, even if the returned URL is identical to either the // base or reference. If ref is an absolute URL, then resolve_reference // ignores base and returns a copy of ref. -pub fn (u &URL) resolve_reference(ref &URL) ?URL { +pub fn (u &URL) resolve_reference(ref &URL) !URL { mut url := *ref if ref.scheme == '' { url.scheme = u.scheme @@ -934,7 +934,7 @@ pub fn (u &URL) resolve_reference(ref &URL) ?URL { // The 'absoluteURI' or 'net_path' cases. // We can ignore the error from set_path since we know we provided a // validly-escaped path. - url.set_path(resolve_path(ref.escaped_path(), ''))? + url.set_path(resolve_path(ref.escaped_path(), ''))! return url } if ref.opaque != '' { @@ -952,7 +952,7 @@ pub fn (u &URL) resolve_reference(ref &URL) ?URL { // The 'abs_path' or 'rel_path' cases. url.host = u.host url.user = u.user - url.set_path(resolve_path(u.escaped_path(), ref.escaped_path()))? + url.set_path(resolve_path(u.escaped_path(), ref.escaped_path()))! return url } diff --git a/vlib/net/util.v b/vlib/net/util.v index 8d0ea2a06..d027cf5f8 100644 --- a/vlib/net/util.v +++ b/vlib/net/util.v @@ -6,7 +6,7 @@ const ( // validate_port checks whether a port is valid // and returns the port or an error -pub fn validate_port(port int) ?u16 { +pub fn validate_port(port int) !u16 { if port <= net.socket_max_port { return u16(port) } else { @@ -15,13 +15,13 @@ pub fn validate_port(port int) ?u16 { } // split address splits an address into its host name and its port -pub fn split_address(addr string) ?(string, u16) { +pub fn split_address(addr string) !(string, u16) { port := addr.all_after_last(':').int() address := addr.all_before_last(':') // TODO(emily): Maybe do some more checking here // to validate ipv6 address sanity? - p := validate_port(port)? + p := validate_port(port)! return address, p } diff --git a/vlib/net/websocket/events.v b/vlib/net/websocket/events.v index c703d29ac..6f0480975 100644 --- a/vlib/net/websocket/events.v +++ b/vlib/net/websocket/events.v @@ -32,26 +32,26 @@ struct CloseEventHandler { ref voidptr // referenced object } -pub type AcceptClientFn = fn (mut c ServerClient) ?bool +pub type AcceptClientFn = fn (mut c ServerClient) !bool -pub type SocketMessageFn = fn (mut c Client, msg &Message) ? +pub type SocketMessageFn = fn (mut c Client, msg &Message) ! -pub type SocketMessageFn2 = fn (mut c Client, msg &Message, v voidptr) ? +pub type SocketMessageFn2 = fn (mut c Client, msg &Message, v voidptr) ! -pub type SocketErrorFn = fn (mut c Client, err string) ? +pub type SocketErrorFn = fn (mut c Client, err string) ! -pub type SocketErrorFn2 = fn (mut c Client, err string, v voidptr) ? +pub type SocketErrorFn2 = fn (mut c Client, err string, v voidptr) ! -pub type SocketOpenFn = fn (mut c Client) ? +pub type SocketOpenFn = fn (mut c Client) ! -pub type SocketOpenFn2 = fn (mut c Client, v voidptr) ? +pub type SocketOpenFn2 = fn (mut c Client, v voidptr) ! -pub type SocketCloseFn = fn (mut c Client, code int, reason string) ? +pub type SocketCloseFn = fn (mut c Client, code int, reason string) ! -pub type SocketCloseFn2 = fn (mut c Client, code int, reason string, v voidptr) ? +pub type SocketCloseFn2 = fn (mut c Client, code int, reason string, v voidptr) ! // on_connect registers a callback when client connects to the server -pub fn (mut s Server) on_connect(fun AcceptClientFn) ? { +pub fn (mut s Server) on_connect(fun AcceptClientFn) ! { if s.accept_client_callbacks.len > 0 { return error('only one callback can be registered for accept client') } @@ -156,13 +156,13 @@ pub fn (mut ws Client) on_close_ref(fun SocketCloseFn2, ref voidptr) { } // send_connect_event invokes the on_connect callback -fn (mut s Server) send_connect_event(mut c ServerClient) ?bool { +fn (mut s Server) send_connect_event(mut c ServerClient) !bool { if s.accept_client_callbacks.len == 0 { // If no callback all client will be accepted return true } fun := s.accept_client_callbacks[0] - res := fun(mut c)? + res := fun(mut c)! return res } diff --git a/vlib/net/websocket/handshake.v b/vlib/net/websocket/handshake.v index a7163d904..82d05b731 100644 --- a/vlib/net/websocket/handshake.v +++ b/vlib/net/websocket/handshake.v @@ -5,7 +5,7 @@ import encoding.base64 import strings // handshake manages the websocket handshake process -fn (mut ws Client) handshake() ? { +fn (mut ws Client) handshake() ! { nonce := get_nonce(ws.nonce_size) seckey := base64.encode_str(nonce) mut sb := strings.new_builder(1024) @@ -34,21 +34,21 @@ fn (mut ws Client) handshake() ? { } handshake_bytes := handshake.bytes() ws.debug_log('sending handshake: $handshake') - ws.socket_write(handshake_bytes)? - ws.read_handshake(seckey)? + ws.socket_write(handshake_bytes)! + ws.read_handshake(seckey)! unsafe { handshake_bytes.free() } } // handle_server_handshake manages websocket server handshake process -fn (mut s Server) handle_server_handshake(mut c Client) ?(string, &ServerClient) { - msg := c.read_handshake_str()? - handshake_response, client := s.parse_client_handshake(msg, mut c)? +fn (mut s Server) handle_server_handshake(mut c Client) !(string, &ServerClient) { + msg := c.read_handshake_str()! + handshake_response, client := s.parse_client_handshake(msg, mut c)! unsafe { msg.free() } return handshake_response, client } // parse_client_handshake parses result from handshake process -fn (mut s Server) parse_client_handshake(client_handshake string, mut c Client) ?(string, &ServerClient) { +fn (mut s Server) parse_client_handshake(client_handshake string, mut c Client) !(string, &ServerClient) { s.logger.debug('server-> client handshake:\n$client_handshake') lines := client_handshake.split_into_lines() get_tokens := lines[0].split(' ') @@ -81,7 +81,7 @@ fn (mut s Server) parse_client_handshake(client_handshake string, mut c Client) 'Sec-WebSocket-Key', 'sec-websocket-key' { key = keys[1].trim_space() s.logger.debug('server-> got key: $key') - seckey = create_key_challenge_response(key)? + seckey = create_key_challenge_response(key)! s.logger.debug('server-> challenge: $seckey, response: ${keys[1]}') flags << .has_accept } @@ -112,12 +112,12 @@ fn (mut s Server) parse_client_handshake(client_handshake string, mut c Client) } // read_handshake_str returns the handshake response -fn (mut ws Client) read_handshake_str() ?string { +fn (mut ws Client) read_handshake_str() !string { mut total_bytes_read := 0 mut msg := [1024]u8{} mut buffer := [1]u8{} for total_bytes_read < 1024 { - bytes_read := ws.socket_read_ptr(&buffer[0], 1)? + bytes_read := ws.socket_read_ptr(&buffer[0], 1)! if bytes_read == 0 { return error_with_code('unexpected no response from handshake', 5) } @@ -134,15 +134,15 @@ fn (mut ws Client) read_handshake_str() ?string { } // read_handshake reads the handshake result and check if valid -fn (mut ws Client) read_handshake(seckey string) ? { - mut msg := ws.read_handshake_str()? - ws.check_handshake_response(msg, seckey)? +fn (mut ws Client) read_handshake(seckey string) ! { + mut msg := ws.read_handshake_str()! + ws.check_handshake_response(msg, seckey)! unsafe { msg.free() } } // check_handshake_response checks the response from handshake and returns // the response and secure key provided by the websocket client -fn (mut ws Client) check_handshake_response(handshake_response string, seckey string) ? { +fn (mut ws Client) check_handshake_response(handshake_response string, seckey string) ! { ws.debug_log('handshake response:\n$handshake_response') lines := handshake_response.split_into_lines() header := lines[0] @@ -164,7 +164,7 @@ fn (mut ws Client) check_handshake_response(handshake_response string, seckey st } 'Sec-WebSocket-Accept', 'sec-websocket-accept' { ws.debug_log('seckey: $seckey') - challenge := create_key_challenge_response(seckey)? + challenge := create_key_challenge_response(seckey)! ws.debug_log('challenge: $challenge, response: ${keys[1]}') if keys[1].trim_space() != challenge { return error_with_code('handshake_handler: Sec-WebSocket-Accept header does not match computed sha1/base64 response.', @@ -179,7 +179,7 @@ fn (mut ws Client) check_handshake_response(handshake_response string, seckey st } unsafe { lines.free() } if ws.flags.len < 3 { - ws.close(1002, 'invalid websocket HTTP headers')? + ws.close(1002, 'invalid websocket HTTP headers')! return error_with_code('invalid websocket HTTP headers', 8) } } diff --git a/vlib/net/websocket/io.v b/vlib/net/websocket/io.v index b0cebd0b1..286a771b8 100644 --- a/vlib/net/websocket/io.v +++ b/vlib/net/websocket/io.v @@ -3,41 +3,41 @@ module websocket import net // socket_read reads from socket into the provided buffer -fn (mut ws Client) socket_read(mut buffer []u8) ?int { +fn (mut ws Client) socket_read(mut buffer []u8) !int { lock { if ws.state in [.closed, .closing] || ws.conn.sock.handle <= 1 { return error('socket_read: trying to read a closed socket') } if ws.is_ssl { - r := ws.ssl_conn.read(mut buffer) or { return none } + r := ws.ssl_conn.read(mut buffer) or { return error('none') } return r } else { - r := ws.conn.read(mut buffer) or { return none } + r := ws.conn.read(mut buffer) or { return error('none') } return r } } - return none + return error('none') } // socket_read reads from socket into the provided byte pointer and length -fn (mut ws Client) socket_read_ptr(buf_ptr &u8, len int) ?int { +fn (mut ws Client) socket_read_ptr(buf_ptr &u8, len int) !int { lock { if ws.state in [.closed, .closing] || ws.conn.sock.handle <= 1 { return error('socket_read_ptr: trying to read a closed socket') } if ws.is_ssl { - r := ws.ssl_conn.socket_read_into_ptr(buf_ptr, len)? + r := ws.ssl_conn.socket_read_into_ptr(buf_ptr, len)! return r } else { - r := ws.conn.read_ptr(buf_ptr, len)? + r := ws.conn.read_ptr(buf_ptr, len)! return r } } - return none + return error('none') } // socket_write writes the provided byte array to the socket -fn (mut ws Client) socket_write(bytes []u8) ?int { +fn (mut ws Client) socket_write(bytes []u8) !int { lock { if ws.state == .closed || ws.conn.sock.handle <= 1 { ws.debug_log('socket_write: Socket allready closed') @@ -61,25 +61,25 @@ fn (mut ws Client) socket_write(bytes []u8) ?int { } // shutdown_socket shuts down the socket properly when connection is closed -fn (mut ws Client) shutdown_socket() ? { +fn (mut ws Client) shutdown_socket() ! { ws.debug_log('shutting down socket') if ws.is_ssl { - ws.ssl_conn.shutdown()? + ws.ssl_conn.shutdown()! } else { - ws.conn.close()? + ws.conn.close()! } } // dial_socket connects tcp socket and initializes default configurations -fn (mut ws Client) dial_socket() ?&net.TcpConn { +fn (mut ws Client) dial_socket() !&net.TcpConn { tcp_address := '$ws.uri.hostname:$ws.uri.port' - mut t := net.dial_tcp(tcp_address)? + mut t := net.dial_tcp(tcp_address)! optval := int(1) - t.sock.set_option_int(.keep_alive, optval)? + t.sock.set_option_int(.keep_alive, optval)! t.set_read_timeout(ws.read_timeout) t.set_write_timeout(ws.write_timeout) if ws.is_ssl { - ws.ssl_conn.connect(mut t, ws.uri.hostname)? + ws.ssl_conn.connect(mut t, ws.uri.hostname)! } return t } diff --git a/vlib/net/websocket/message.v b/vlib/net/websocket/message.v index a44f19919..2f90f48be 100644 --- a/vlib/net/websocket/message.v +++ b/vlib/net/websocket/message.v @@ -37,35 +37,35 @@ const ( ) // validate_client validates client frame rules from RFC6455 -pub fn (mut ws Client) validate_frame(frame &Frame) ? { +pub fn (mut ws Client) validate_frame(frame &Frame) ! { if frame.rsv1 || frame.rsv2 || frame.rsv3 { - ws.close(1002, 'rsv cannot be other than 0, not negotiated')? + ws.close(1002, 'rsv cannot be other than 0, not negotiated')! return error('rsv cannot be other than 0, not negotiated') } if (int(frame.opcode) >= 3 && int(frame.opcode) <= 7) || (int(frame.opcode) >= 11 && int(frame.opcode) <= 15) { - ws.close(1002, 'use of reserved opcode')? + ws.close(1002, 'use of reserved opcode')! return error('use of reserved opcode') } if frame.has_mask && !ws.is_server { // server should never send masked frames // to client, close connection - ws.close(1002, 'client got masked frame')? + ws.close(1002, 'client got masked frame')! return error('client sent masked frame') } if is_control_frame(frame.opcode) { if !frame.fin { - ws.close(1002, 'control message must not be fragmented')? + ws.close(1002, 'control message must not be fragmented')! return error('unexpected control frame with no fin') } if frame.payload_len > 125 { - ws.close(1002, 'control frames must not exceed 125 bytes')? + ws.close(1002, 'control frames must not exceed 125 bytes')! return error('unexpected control frame payload length') } } if frame.fin == false && ws.fragments.len == 0 && frame.opcode == .continuation { err_msg := 'unexecpected continuation, there are no frames to continue, $frame' - ws.close(1002, err_msg)? + ws.close(1002, err_msg)! return error(err_msg) } } @@ -81,7 +81,7 @@ fn is_data_frame(opcode OPCode) bool { } // read_payload reads the message payload from the socket -fn (mut ws Client) read_payload(frame &Frame) ?[]u8 { +fn (mut ws Client) read_payload(frame &Frame) ![]u8 { if frame.payload_len == 0 { return []u8{} } @@ -89,7 +89,7 @@ fn (mut ws Client) read_payload(frame &Frame) ?[]u8 { mut read_buf := [1]u8{} mut bytes_read := 0 for bytes_read < frame.payload_len { - len := ws.socket_read_ptr(&read_buf[0], 1)? + len := ws.socket_read_ptr(&read_buf[0], 1)! if len != 1 { return error('expected read all message, got zero') } @@ -109,21 +109,21 @@ fn (mut ws Client) read_payload(frame &Frame) ?[]u8 { // validate_utf_8 validates payload for valid utf8 encoding // - Future implementation needs to support fail fast utf errors for strict autobahn conformance -fn (mut ws Client) validate_utf_8(opcode OPCode, payload []u8) ? { +fn (mut ws Client) validate_utf_8(opcode OPCode, payload []u8) ! { if opcode in [.text_frame, .close] && !utf8.validate(payload.data, payload.len) { ws.logger.error('malformed utf8 payload, payload len: ($payload.len)') ws.send_error_event('Recieved malformed utf8.') - ws.close(1007, 'malformed utf8 payload')? + ws.close(1007, 'malformed utf8 payload')! return error('malformed utf8 payload') } } // read_next_message reads 1 to n frames to compose a message -pub fn (mut ws Client) read_next_message() ?Message { +pub fn (mut ws Client) read_next_message() !Message { for { - frame := ws.parse_frame_header()? - ws.validate_frame(&frame)? - frame_payload := ws.read_payload(&frame)? + frame := ws.parse_frame_header()! + ws.validate_frame(&frame)! + frame_payload := ws.read_payload(&frame)! if is_control_frame(frame.opcode) { // Control frames can interject other frames // and need to be returned immediately @@ -161,12 +161,12 @@ pub fn (mut ws Client) read_next_message() ?Message { ws.fragments = [] } if is_data_frame(frame.opcode) { - ws.close(0, '')? + ws.close(0, '')! return error('Unexpected frame opcode') } - payload := ws.payload_from_fragments(frame_payload)? + payload := ws.payload_from_fragments(frame_payload)! opcode := ws.opcode_from_fragments() - ws.validate_utf_8(opcode, payload)? + ws.validate_utf_8(opcode, payload)! msg := Message{ opcode: opcode payload: payload.clone() @@ -177,11 +177,11 @@ pub fn (mut ws Client) read_next_message() ?Message { } return msg } - return none + return error('none') } // payload_from_fragments returs the whole paylaod from fragmented message -fn (ws Client) payload_from_fragments(fin_payload []u8) ?[]u8 { +fn (ws Client) payload_from_fragments(fin_payload []u8) ![]u8 { mut total_size := 0 for f in ws.fragments { if f.data.len > 0 { @@ -208,14 +208,14 @@ fn (ws Client) opcode_from_fragments() OPCode { } // parse_frame_header parses next message by decoding the incoming frames -pub fn (mut ws Client) parse_frame_header() ?Frame { +pub fn (mut ws Client) parse_frame_header() !Frame { mut buffer := [256]u8{} mut bytes_read := 0 mut frame := Frame{} mut rbuff := [1]u8{} mut mask_end_byte := 0 for ws.state == .open { - read_bytes := ws.socket_read_ptr(&rbuff[0], 1)? + read_bytes := ws.socket_read_ptr(&rbuff[0], 1)! if read_bytes == 0 { // this is probably a timeout or close continue diff --git a/vlib/net/websocket/tests/autobahn/autobahn_client.v b/vlib/net/websocket/tests/autobahn/autobahn_client.v index d449bbebf..739f42b81 100644 --- a/vlib/net/websocket/tests/autobahn/autobahn_client.v +++ b/vlib/net/websocket/tests/autobahn/autobahn_client.v @@ -10,20 +10,20 @@ fn main() { } // update the reports uri := 'ws://autobahn_server:9001/updateReports?agent=v-client' - mut ws := websocket.new_client(uri)? - ws.connect()? - ws.listen()? + mut ws := websocket.new_client(uri)! + ws.connect()! + ws.listen()! } -fn handle_case(case_nr int) ? { +fn handle_case(case_nr int) ! { uri := 'ws://autobahn_server:9001/runCase?case=$case_nr&agent=v-client' - mut ws := websocket.new_client(uri)? + mut ws := websocket.new_client(uri)! ws.on_message(on_message) - ws.connect()? - ws.listen()? + ws.connect()! + ws.listen()! } -fn on_message(mut ws websocket.Client, msg &websocket.Message) ? { +fn on_message(mut ws websocket.Client, msg &websocket.Message) ! { // autobahn tests expects to send same message back if msg.opcode == .pong { // We just wanna pass text and binary message back to autobahn diff --git a/vlib/net/websocket/tests/autobahn/autobahn_client_wss.v b/vlib/net/websocket/tests/autobahn/autobahn_client_wss.v index 1cf17820f..887ea80bd 100644 --- a/vlib/net/websocket/tests/autobahn/autobahn_client_wss.v +++ b/vlib/net/websocket/tests/autobahn/autobahn_client_wss.v @@ -11,21 +11,21 @@ fn main() { // update the reports // uri := 'wss://localhost:9002/updateReports?agent=v-client' uri := 'wss://autobahn_server_wss:9002/updateReports?agent=v-client' - mut ws := websocket.new_client(uri)? - ws.connect()? - ws.listen()? + mut ws := websocket.new_client(uri)! + ws.connect()! + ws.listen()! } -fn handle_case(case_nr int) ? { +fn handle_case(case_nr int) ! { uri := 'wss://autobahn_server_wss:9002/runCase?case=$case_nr&agent=v-client' // uri := 'wss://localhost:9002/runCase?case=$case_nr&agent=v-client' - mut ws := websocket.new_client(uri)? + mut ws := websocket.new_client(uri)! ws.on_message(on_message) - ws.connect()? - ws.listen()? + ws.connect()! + ws.listen()! } -fn on_message(mut ws websocket.Client, msg &websocket.Message) ? { +fn on_message(mut ws websocket.Client, msg &websocket.Message) ! { // autobahn tests expects to send same message back if msg.opcode == .pong { // We just wanna pass text and binary message back to autobahn diff --git a/vlib/net/websocket/tests/autobahn/autobahn_server.v b/vlib/net/websocket/tests/autobahn/autobahn_server.v index 3dfded7d8..96cfc1669 100644 --- a/vlib/net/websocket/tests/autobahn/autobahn_server.v +++ b/vlib/net/websocket/tests/autobahn/autobahn_server.v @@ -9,15 +9,15 @@ fn main() { s.listen() or { panic(err) } } -fn handle_case(case_nr int) ? { +fn handle_case(case_nr int) ! { uri := 'ws://localhost:9002/runCase?case=$case_nr&agent=v-client' - mut ws := websocket.new_client(uri)? + mut ws := websocket.new_client(uri)! ws.on_message(on_message) - ws.connect()? - ws.listen()? + ws.connect()! + ws.listen()! } -fn on_message(mut ws websocket.Client, msg &websocket.Message) ? { +fn on_message(mut ws websocket.Client, msg &websocket.Message) ! { // autobahn tests expects to send same message back if msg.opcode == .pong { // We just wanna pass text and binary message back to autobahn diff --git a/vlib/net/websocket/tests/autobahn/local_run/autobahn_client.v b/vlib/net/websocket/tests/autobahn/local_run/autobahn_client.v index 4f7645d02..5e78aa951 100644 --- a/vlib/net/websocket/tests/autobahn/local_run/autobahn_client.v +++ b/vlib/net/websocket/tests/autobahn/local_run/autobahn_client.v @@ -10,20 +10,20 @@ fn main() { } // update the reports uri := 'ws://localhost:9001/updateReports?agent=v-client' - mut ws := websocket.new_client(uri)? - ws.connect()? - ws.listen()? + mut ws := websocket.new_client(uri)! + ws.connect()! + ws.listen()! } -fn handle_case(case_nr int) ? { +fn handle_case(case_nr int) ! { uri := 'ws://localhost:9001/runCase?case=$case_nr&agent=v-client' - mut ws := websocket.new_client(uri)? + mut ws := websocket.new_client(uri)! ws.on_message(on_message) - ws.connect()? - ws.listen()? + ws.connect()! + ws.listen()! } -fn on_message(mut ws websocket.Client, msg &websocket.Message) ? { +fn on_message(mut ws websocket.Client, msg &websocket.Message) ! { // autobahn tests expects to send same message back if msg.opcode == .pong { // We just wanna pass text and binary message back to autobahn diff --git a/vlib/net/websocket/tests/autobahn/local_run/autobahn_client_wss.v b/vlib/net/websocket/tests/autobahn/local_run/autobahn_client_wss.v index 1cf17820f..887ea80bd 100644 --- a/vlib/net/websocket/tests/autobahn/local_run/autobahn_client_wss.v +++ b/vlib/net/websocket/tests/autobahn/local_run/autobahn_client_wss.v @@ -11,21 +11,21 @@ fn main() { // update the reports // uri := 'wss://localhost:9002/updateReports?agent=v-client' uri := 'wss://autobahn_server_wss:9002/updateReports?agent=v-client' - mut ws := websocket.new_client(uri)? - ws.connect()? - ws.listen()? + mut ws := websocket.new_client(uri)! + ws.connect()! + ws.listen()! } -fn handle_case(case_nr int) ? { +fn handle_case(case_nr int) ! { uri := 'wss://autobahn_server_wss:9002/runCase?case=$case_nr&agent=v-client' // uri := 'wss://localhost:9002/runCase?case=$case_nr&agent=v-client' - mut ws := websocket.new_client(uri)? + mut ws := websocket.new_client(uri)! ws.on_message(on_message) - ws.connect()? - ws.listen()? + ws.connect()! + ws.listen()! } -fn on_message(mut ws websocket.Client, msg &websocket.Message) ? { +fn on_message(mut ws websocket.Client, msg &websocket.Message) ! { // autobahn tests expects to send same message back if msg.opcode == .pong { // We just wanna pass text and binary message back to autobahn diff --git a/vlib/net/websocket/utils.v b/vlib/net/websocket/utils.v index 1149a34b7..ce1b1c0b1 100644 --- a/vlib/net/websocket/utils.v +++ b/vlib/net/websocket/utils.v @@ -27,7 +27,7 @@ fn create_masking_key() []u8 { } // create_key_challenge_response creates a key challange response from security key -fn create_key_challenge_response(seckey string) ?string { +fn create_key_challenge_response(seckey string) !string { if seckey.len == 0 { return error('unexpected seckey lengt zero') } diff --git a/vlib/net/websocket/websocket_client.v b/vlib/net/websocket/websocket_client.v index bd5a9e798..2f2551624 100644 --- a/vlib/net/websocket/websocket_client.v +++ b/vlib/net/websocket/websocket_client.v @@ -88,12 +88,12 @@ pub struct ClientOpt { } // new_client instance a new websocket client -pub fn new_client(address string, opt ClientOpt) ?&Client { - uri := parse_uri(address)? +pub fn new_client(address string, opt ClientOpt) !&Client { + uri := parse_uri(address)! return &Client{ conn: 0 is_server: false - ssl_conn: ssl.new_ssl_conn()? + ssl_conn: ssl.new_ssl_conn()! is_ssl: address.starts_with('wss') logger: opt.logger uri: uri @@ -106,19 +106,19 @@ pub fn new_client(address string, opt ClientOpt) ?&Client { } // connect connects to remote websocket server -pub fn (mut ws Client) connect() ? { - ws.assert_not_connected()? +pub fn (mut ws Client) connect() ! { + ws.assert_not_connected()! ws.set_state(.connecting) ws.logger.info('connecting to host $ws.uri') - ws.conn = ws.dial_socket()? - ws.handshake()? + ws.conn = ws.dial_socket()! + ws.handshake()! ws.set_state(.open) ws.logger.info('successfully connected to host $ws.uri') ws.send_open_event() } // listen listens and processes incoming messages -pub fn (mut ws Client) listen() ? { +pub fn (mut ws Client) listen() ! { mut log := 'Starting client listener, server($ws.is_server)...' ws.logger.info(log) unsafe { log.free() } @@ -185,30 +185,30 @@ pub fn (mut ws Client) listen() ? { } if msg.payload.len > 0 { if msg.payload.len == 1 { - ws.close(1002, 'close payload cannot be 1 byte')? + ws.close(1002, 'close payload cannot be 1 byte')! return error('close payload cannot be 1 byte') } code := u16(msg.payload[0]) << 8 | u16(msg.payload[1]) if code in invalid_close_codes { - ws.close(1002, 'invalid close code: $code')? + ws.close(1002, 'invalid close code: $code')! return error('invalid close code: $code') } reason := if msg.payload.len > 2 { msg.payload[2..] } else { []u8{} } if reason.len > 0 { - ws.validate_utf_8(.close, reason)? + ws.validate_utf_8(.close, reason)! } if ws.state !in [.closing, .closed] { // sending close back according to spec ws.debug_log('close with reason, code: $code, reason: $reason') r := reason.bytestr() - ws.close(code, r)? + ws.close(code, r)! } unsafe { msg.free() } } else { if ws.state !in [.closing, .closed] { ws.debug_log('close with reason, no code') // sending close back according to spec - ws.close(1000, 'normal')? + ws.close(1000, 'normal')! } unsafe { msg.free() } } @@ -217,7 +217,7 @@ pub fn (mut ws Client) listen() ? { .continuation { ws.logger.error('unexpected opcode continuation, nothing to continue') ws.send_error_event('unexpected opcode continuation, nothing to continue') - ws.close(1002, 'nothing to continue')? + ws.close(1002, 'nothing to continue')! return error('unexpected opcode continuation, nothing to continue') } } @@ -230,17 +230,17 @@ fn (mut ws Client) manage_clean_close() { } // ping sends ping message to server -pub fn (mut ws Client) ping() ? { - ws.send_control_frame(.ping, 'PING', [])? +pub fn (mut ws Client) ping() ! { + ws.send_control_frame(.ping, 'PING', [])! } // pong sends pong message to server, -pub fn (mut ws Client) pong() ? { - ws.send_control_frame(.pong, 'PONG', [])? +pub fn (mut ws Client) pong() ! { + ws.send_control_frame(.pong, 'PONG', [])! } // write_ptr writes len bytes provided a byteptr with a websocket messagetype -pub fn (mut ws Client) write_ptr(bytes &u8, payload_len int, code OPCode) ?int { +pub fn (mut ws Client) write_ptr(bytes &u8, payload_len int, code OPCode) !int { // ws.debug_log('write_ptr code: $code') if ws.state != .open || ws.conn.sock.handle < 1 { // todo: send error here later @@ -290,7 +290,7 @@ pub fn (mut ws Client) write_ptr(bytes &u8, payload_len int, code OPCode) ?int { header[12] = masking_key[2] header[13] = masking_key[3] } else { - ws.close(1009, 'frame too large')? + ws.close(1009, 'frame too large')! return error('frame too large') } } @@ -307,7 +307,7 @@ pub fn (mut ws Client) write_ptr(bytes &u8, payload_len int, code OPCode) ?int { frame_buf[header_len + i] ^= masking_key[i % 4] & 0xff } } - written_len := ws.socket_write(frame_buf)? + written_len := ws.socket_write(frame_buf)! unsafe { frame_buf.free() masking_key.free() @@ -317,17 +317,17 @@ pub fn (mut ws Client) write_ptr(bytes &u8, payload_len int, code OPCode) ?int { } // write writes a byte array with a websocket messagetype to socket -pub fn (mut ws Client) write(bytes []u8, code OPCode) ?int { +pub fn (mut ws Client) write(bytes []u8, code OPCode) !int { return ws.write_ptr(&u8(bytes.data), bytes.len, code) } // write_str, writes a string with a websocket texttype to socket -pub fn (mut ws Client) write_string(str string) ?int { +pub fn (mut ws Client) write_string(str string) !int { return ws.write_ptr(str.str, str.len, .text_frame) } // close closes the websocket connection -pub fn (mut ws Client) close(code int, message string) ? { +pub fn (mut ws Client) close(code int, message string) ! { ws.debug_log('sending close, $code, $message') if ws.state in [.closed, .closing] || ws.conn.sock.handle <= 1 { ws.debug_log('close: Websocket allready closed ($ws.state), $message, $code handle($ws.conn.sock.handle)') @@ -350,16 +350,16 @@ pub fn (mut ws Client) close(code int, message string) ? { for i in 0 .. message.len { close_frame[i + 2] = message[i] } - ws.send_control_frame(.close, 'CLOSE', close_frame)? + ws.send_control_frame(.close, 'CLOSE', close_frame)! unsafe { close_frame.free() } } else { - ws.send_control_frame(.close, 'CLOSE', [])? + ws.send_control_frame(.close, 'CLOSE', [])! } ws.fragments = [] } // send_control_frame sends a control frame to the server -fn (mut ws Client) send_control_frame(code OPCode, frame_typ string, payload []u8) ? { +fn (mut ws Client) send_control_frame(code OPCode, frame_typ string, payload []u8) ! { ws.debug_log('send control frame $code, frame_type: $frame_typ') if ws.state !in [.open, .closing] && ws.conn.sock.handle > 1 { return error('socket is not connected') @@ -419,8 +419,8 @@ fn (mut ws Client) send_control_frame(code OPCode, frame_typ string, payload []u } // parse_uri parses the url to a Uri -fn parse_uri(url string) ?&Uri { - u := urllib.parse(url)? +fn parse_uri(url string) !&Uri { + u := urllib.parse(url)! request_uri := u.request_uri() v := request_uri.split('?') mut port := u.port() @@ -452,7 +452,7 @@ fn (mut ws Client) set_state(state State) { } // assert_not_connected returns error if the connection is not connected -fn (ws Client) assert_not_connected() ? { +fn (ws Client) assert_not_connected() ! { match ws.state { .connecting { return error('connect: websocket is connecting') } .open { return error('connect: websocket already open') } @@ -462,10 +462,10 @@ fn (ws Client) assert_not_connected() ? { } // reset_state resets the websocket and initialize default settings -fn (mut ws Client) reset_state() ? { +fn (mut ws Client) reset_state() ! { lock { ws.state = .closed - ws.ssl_conn = ssl.new_ssl_conn()? + ws.ssl_conn = ssl.new_ssl_conn()! ws.flags = [] ws.fragments = [] } diff --git a/vlib/net/websocket/websocket_server.v b/vlib/net/websocket/websocket_server.v index 2a0b43118..93da3bfb3 100644 --- a/vlib/net/websocket/websocket_server.v +++ b/vlib/net/websocket/websocket_server.v @@ -60,9 +60,9 @@ pub fn (mut s Server) set_ping_interval(seconds int) { } // listen start listen and process to incoming connections from websocket clients -pub fn (mut s Server) listen() ? { +pub fn (mut s Server) listen() ! { s.logger.info('websocket server: start listen on port $s.port') - s.ls = net.listen_tcp(s.family, ':$s.port')? + s.ls = net.listen_tcp(s.family, ':$s.port')! s.set_state(.open) go s.handle_ping() for { @@ -110,20 +110,20 @@ fn (mut s Server) handle_ping() { } // serve_client accepts incoming connection and sets up the callbacks -fn (mut s Server) serve_client(mut c Client) ? { +fn (mut s Server) serve_client(mut c Client) ! { c.logger.debug('server-> Start serve client ($c.id)') defer { c.logger.debug('server-> End serve client ($c.id)') } - mut handshake_response, mut server_client := s.handle_server_handshake(mut c)? - accept := s.send_connect_event(mut server_client)? + mut handshake_response, mut server_client := s.handle_server_handshake(mut c)! + accept := s.send_connect_event(mut server_client)! if !accept { s.logger.debug('server-> client not accepted') - c.shutdown_socket()? + c.shutdown_socket()! return } // the client is accepted - c.socket_write(handshake_response.bytes())? + c.socket_write(handshake_response.bytes())! lock { s.clients[server_client.client.id] = server_client } @@ -155,7 +155,7 @@ fn (mut s Server) setup_callbacks(mut sc ServerClient) { } } // set standard close so we can remove client if closed - sc.client.on_close_ref(fn (mut c Client, code int, reason string, mut sc ServerClient) ? { + sc.client.on_close_ref(fn (mut c Client, code int, reason string, mut sc ServerClient) ! { c.logger.debug('server-> Delete client') lock { sc.server.clients.delete(sc.client.id) @@ -164,12 +164,12 @@ fn (mut s Server) setup_callbacks(mut sc ServerClient) { } // accept_new_client creates a new client instance for client that connects to the socket -fn (mut s Server) accept_new_client() ?&Client { - mut new_conn := s.ls.accept()? +fn (mut s Server) accept_new_client() !&Client { + mut new_conn := s.ls.accept()! c := &Client{ is_server: true conn: new_conn - ssl_conn: ssl.new_ssl_conn()? + ssl_conn: ssl.new_ssl_conn()! logger: s.logger state: .open last_pong_ut: time.now().unix diff --git a/vlib/net/websocket/websocket_test.v b/vlib/net/websocket/websocket_test.v index 4874b00e7..2d04990fa 100644 --- a/vlib/net/websocket/websocket_test.v +++ b/vlib/net/websocket/websocket_test.v @@ -50,12 +50,12 @@ fn test_ws_ipv4() { } } -fn start_server(family net.AddrFamily, listen_port int) ? { +fn start_server(family net.AddrFamily, listen_port int) ! { mut s := websocket.new_server(family, listen_port, '') // make that in execution test time give time to execute at least one time s.ping_interval = 1 - s.on_connect(fn (mut s websocket.ServerClient) ?bool { + s.on_connect(fn (mut s websocket.ServerClient) !bool { // here you can look att the client info and accept or not accept // just returning a true/false if s.resource_name != '/' { @@ -63,37 +63,37 @@ fn start_server(family net.AddrFamily, listen_port int) ? { return false } return true - })? - s.on_message(fn (mut ws websocket.Client, msg &websocket.Message) ? { + })! + s.on_message(fn (mut ws websocket.Client, msg &websocket.Message) ! { match msg.opcode { - .pong { ws.write_string('pong')? } - else { ws.write(msg.payload, msg.opcode)? } + .pong { ws.write_string('pong')! } + else { ws.write(msg.payload, msg.opcode)! } } }) - s.on_close(fn (mut ws websocket.Client, code int, reason string) ? { + s.on_close(fn (mut ws websocket.Client, code int, reason string) ! { // not used }) s.listen() or { panic('websocket server could not listen, err: $err') } } // ws_test tests connect to the websocket server from websocket client -fn ws_test(family net.AddrFamily, uri string) ? { +fn ws_test(family net.AddrFamily, uri string) ! { eprintln('connecting to $uri ...') mut test_results := WebsocketTestResults{} - mut ws := websocket.new_client(uri)? - ws.on_open(fn (mut ws websocket.Client) ? { - ws.pong()? + mut ws := websocket.new_client(uri)! + ws.on_open(fn (mut ws websocket.Client) ! { + ws.pong()! assert true }) - ws.on_error(fn (mut ws websocket.Client, err string) ? { + ws.on_error(fn (mut ws websocket.Client, err string) ! { println('error: $err') // this can be thrown by internet connection problems assert false }) - ws.on_message_ref(fn (mut ws websocket.Client, msg &websocket.Message, mut res WebsocketTestResults) ? { + ws.on_message_ref(fn (mut ws websocket.Client, msg &websocket.Message, mut res WebsocketTestResults) ! { println('client got type: $msg.opcode payload:\n$msg.payload') if msg.opcode == .text_frame { smessage := msg.payload.bytestr() diff --git a/vlib/os/dir_expansions_test.v b/vlib/os/dir_expansions_test.v index 692d46727..ba3e1e599 100644 --- a/vlib/os/dir_expansions_test.v +++ b/vlib/os/dir_expansions_test.v @@ -33,11 +33,11 @@ fn test_expand_tilde_to_home() { assert os.expand_tilde_to_home('~') == os.home_dir() } -fn test_config_dir() ? { - cdir := os.config_dir()? +fn test_config_dir() { + cdir := os.config_dir()! assert cdir.len > 0 adir := '$cdir/test-v-config' - os.mkdir_all(adir)? - os.rmdir(adir)? + os.mkdir_all(adir)! + os.rmdir(adir)! assert os.is_dir(cdir) } diff --git a/vlib/os/file.c.v b/vlib/os/file.c.v index b5412e260..4714633ae 100644 --- a/vlib/os/file.c.v +++ b/vlib/os/file.c.v @@ -52,7 +52,7 @@ fn fix_windows_path(path string) string { } // open_file can be used to open or create a file with custom flags and permissions and returns a `File` object. -pub fn open_file(path string, mode string, options ...int) ?File { +pub fn open_file(path string, mode string, options ...int) !File { mut flags := 0 mut seek_to_end := false for m in mode { @@ -126,7 +126,7 @@ pub fn open_file(path string, mode string, options ...int) ?File { } // open tries to open a file for reading and returns back a read-only `File` object. -pub fn open(path string) ?File { +pub fn open(path string) !File { /* $if linux { $if !android { @@ -141,7 +141,7 @@ pub fn open(path string) ?File { } } */ - cfile := vfopen(path, 'rb')? + cfile := vfopen(path, 'rb')! fd := fileno(cfile) return File{ cfile: cfile @@ -151,7 +151,7 @@ pub fn open(path string) ?File { } // create creates or opens a file at a specified location and returns a write-only `File` object. -pub fn create(path string) ?File { +pub fn create(path string) !File { /* // Note: android/termux/bionic is also a kind of linux, // but linux syscalls there sometimes fail, @@ -175,7 +175,7 @@ pub fn create(path string) ?File { } } */ - cfile := vfopen(path, 'wb')? + cfile := vfopen(path, 'wb')! fd := fileno(cfile) return File{ cfile: cfile @@ -218,7 +218,7 @@ pub fn (f &File) eof() bool { } // reopen allows a `File` to be reused. It is mostly useful for reopening standard input and output. -pub fn (mut f File) reopen(path string, mode string) ? { +pub fn (mut f File) reopen(path string, mode string) ! { p := fix_windows_path(path) mut cfile := &C.FILE(0) $if windows { @@ -257,7 +257,7 @@ pub fn (f &File) read(mut buf []u8) !int { // **************************** Write ops *************************** // write implements the Writer interface. // It returns how many bytes were actually written. -pub fn (mut f File) write(buf []u8) ?int { +pub fn (mut f File) write(buf []u8) !int { if !f.is_opened { return error_file_not_opened() } @@ -278,7 +278,7 @@ pub fn (mut f File) write(buf []u8) ?int { // writeln writes the string `s` into the file, and appends a \n character. // It returns how many bytes were written, including the \n character. -pub fn (mut f File) writeln(s string) ?int { +pub fn (mut f File) writeln(s string) !int { if !f.is_opened { return error_file_not_opened() } @@ -305,15 +305,15 @@ pub fn (mut f File) writeln(s string) ?int { // write_string writes the string `s` into the file // It returns how many bytes were actually written. -pub fn (mut f File) write_string(s string) ?int { - unsafe { f.write_full_buffer(s.str, usize(s.len))? } +pub fn (mut f File) write_string(s string) !int { + unsafe { f.write_full_buffer(s.str, usize(s.len))! } return s.len } // write_to implements the RandomWriter interface. // It returns how many bytes were actually written. // It resets the seek position to the end of the file. -pub fn (mut f File) write_to(pos u64, buf []u8) ?int { +pub fn (mut f File) write_to(pos u64, buf []u8) !int { if !f.is_opened { return error_file_not_opened() } @@ -359,7 +359,7 @@ pub fn (mut f File) write_ptr(data voidptr, size int) int { // write_full_buffer writes a whole buffer of data to the file, starting from the // address in `buffer`, no matter how many tries/partial writes it would take. [unsafe] -pub fn (mut f File) write_full_buffer(buffer voidptr, buffer_len usize) ? { +pub fn (mut f File) write_full_buffer(buffer voidptr, buffer_len usize) ! { if buffer_len <= usize(0) { return } @@ -411,7 +411,7 @@ pub fn (mut f File) write_ptr_at(data voidptr, size int, pos u64) int { // **************************** Read ops *************************** // fread wraps C.fread and handles error and end-of-file detection. -fn fread(ptr voidptr, item_size int, items int, stream &C.FILE) ?int { +fn fread(ptr voidptr, item_size int, items int, stream &C.FILE) !int { nbytes := int(C.fread(ptr, item_size, items, stream)) // If no bytes were read, check for errors and end-of-file. if nbytes <= 0 { @@ -421,7 +421,7 @@ fn fread(ptr voidptr, item_size int, items int, stream &C.FILE) ?int { // read. The caller will get none on their next call because there will be // no data available and the end-of-file will be encountered again. if C.feof(stream) != 0 { - return none + return IError(Eof{}) } // If fread encountered an error, return it. Note that fread and ferror do // not tell us what the error was, so we can't return anything more specific @@ -453,7 +453,7 @@ pub fn (f &File) read_bytes_at(size int, pos u64) []u8 { // read_bytes_into_newline reads from the beginning of the file into the provided buffer. // Each consecutive call on the same file continues reading where it previously ended. // A read call is either stopped, if the buffer is full, a newline was read or EOF. -pub fn (f &File) read_bytes_into_newline(mut buf []u8) ?int { +pub fn (f &File) read_bytes_into_newline(mut buf []u8) !int { if buf.len == 0 { return error(@FN + ': `buf.len` == 0') } @@ -492,7 +492,7 @@ pub fn (f &File) read_bytes_into_newline(mut buf []u8) ?int { // read_bytes_into fills `buf` with bytes at the given position in the file. // `buf` *must* have length greater than zero. // Returns the number of read bytes, or an error. -pub fn (f &File) read_bytes_into(pos u64, mut buf []u8) ?int { +pub fn (f &File) read_bytes_into(pos u64, mut buf []u8) !int { if buf.len == 0 { return error(@FN + ': `buf.len` == 0') } @@ -500,14 +500,14 @@ pub fn (f &File) read_bytes_into(pos u64, mut buf []u8) ?int { $if windows { // Note: fseek errors if pos == os.file_size, which we accept C._fseeki64(f.cfile, pos, C.SEEK_SET) - nbytes := fread(buf.data, 1, buf.len, f.cfile)? + nbytes := fread(buf.data, 1, buf.len, f.cfile)! $if debug { C._fseeki64(f.cfile, 0, C.SEEK_SET) } return nbytes } $else { C.fseeko(f.cfile, pos, C.SEEK_SET) - nbytes := fread(buf.data, 1, buf.len, f.cfile)? + nbytes := fread(buf.data, 1, buf.len, f.cfile)! $if debug { C.fseeko(f.cfile, 0, C.SEEK_SET) } @@ -516,7 +516,7 @@ pub fn (f &File) read_bytes_into(pos u64, mut buf []u8) ?int { } $if x32 { C.fseek(f.cfile, pos, C.SEEK_SET) - nbytes := fread(buf.data, 1, buf.len, f.cfile)? + nbytes := fread(buf.data, 1, buf.len, f.cfile)! $if debug { C.fseek(f.cfile, 0, C.SEEK_SET) } @@ -526,7 +526,7 @@ pub fn (f &File) read_bytes_into(pos u64, mut buf []u8) ?int { } // read_from implements the RandomReader interface. -pub fn (f &File) read_from(pos u64, mut buf []u8) ?int { +pub fn (f &File) read_from(pos u64, mut buf []u8) !int { if buf.len == 0 { return 0 } @@ -537,12 +537,12 @@ pub fn (f &File) read_from(pos u64, mut buf []u8) ?int { C.fseeko(f.cfile, pos, C.SEEK_SET) } - nbytes := fread(buf.data, 1, buf.len, f.cfile)? + nbytes := fread(buf.data, 1, buf.len, f.cfile)! return nbytes } $if x32 { C.fseek(f.cfile, pos, C.SEEK_SET) - nbytes := fread(buf.data, 1, buf.len, f.cfile)? + nbytes := fread(buf.data, 1, buf.len, f.cfile)! return nbytes } return error('Could not read file') @@ -550,7 +550,7 @@ pub fn (f &File) read_from(pos u64, mut buf []u8) ?int { // read_into_ptr reads at most max_size bytes from the file and writes it into ptr. // Returns the amount of bytes read or an error. -pub fn (f &File) read_into_ptr(ptr &u8, max_size int) ?int { +pub fn (f &File) read_into_ptr(ptr &u8, max_size int) !int { return fread(ptr, 1, max_size, f.cfile) } @@ -588,7 +588,7 @@ fn error_size_of_type_0() IError { } // read_struct reads a single struct of type `T` -pub fn (mut f File) read_struct(mut t T) ? { +pub fn (mut f File) read_struct(mut t T) ! { if !f.is_opened { return error_file_not_opened() } @@ -596,14 +596,14 @@ pub fn (mut f File) read_struct(mut t T) ? { if tsize == 0 { return error_size_of_type_0() } - nbytes := fread(t, 1, tsize, f.cfile)? + nbytes := fread(t, 1, tsize, f.cfile)! if nbytes != tsize { return error_with_code('incomplete struct read', nbytes) } } // read_struct_at reads a single struct of type `T` at position specified in file -pub fn (mut f File) read_struct_at(mut t T, pos u64) ? { +pub fn (mut f File) read_struct_at(mut t T, pos u64) ! { if !f.is_opened { return error_file_not_opened() } @@ -615,17 +615,17 @@ pub fn (mut f File) read_struct_at(mut t T, pos u64) ? { $if x64 { $if windows { C._fseeki64(f.cfile, pos, C.SEEK_SET) - nbytes = fread(t, 1, tsize, f.cfile)? + nbytes = fread(t, 1, tsize, f.cfile)! C._fseeki64(f.cfile, 0, C.SEEK_END) } $else { C.fseeko(f.cfile, pos, C.SEEK_SET) - nbytes = fread(t, 1, tsize, f.cfile)? + nbytes = fread(t, 1, tsize, f.cfile)! C.fseeko(f.cfile, 0, C.SEEK_END) } } $if x32 { C.fseek(f.cfile, pos, C.SEEK_SET) - nbytes = fread(t, 1, tsize, f.cfile)? + nbytes = fread(t, 1, tsize, f.cfile)! C.fseek(f.cfile, 0, C.SEEK_END) } if nbytes != tsize { @@ -634,7 +634,7 @@ pub fn (mut f File) read_struct_at(mut t T, pos u64) ? { } // read_raw reads and returns a single instance of type `T` -pub fn (mut f File) read_raw() ?T { +pub fn (mut f File) read_raw() !T { if !f.is_opened { return error_file_not_opened() } @@ -643,7 +643,7 @@ pub fn (mut f File) read_raw() ?T { return error_size_of_type_0() } mut t := T{} - nbytes := fread(&t, 1, tsize, f.cfile)? + nbytes := fread(&t, 1, tsize, f.cfile)! if nbytes != tsize { return error_with_code('incomplete struct read', nbytes) } @@ -651,7 +651,7 @@ pub fn (mut f File) read_raw() ?T { } // read_raw_at reads and returns a single instance of type `T` starting at file byte offset `pos` -pub fn (mut f File) read_raw_at(pos u64) ?T { +pub fn (mut f File) read_raw_at(pos u64) !T { if !f.is_opened { return error_file_not_opened() } @@ -666,7 +666,7 @@ pub fn (mut f File) read_raw_at(pos u64) ?T { if C._fseeki64(f.cfile, pos, C.SEEK_SET) != 0 { return error(posix_get_error_msg(C.errno)) } - nbytes = fread(&t, 1, tsize, f.cfile)? + nbytes = fread(&t, 1, tsize, f.cfile)! if C._fseeki64(f.cfile, 0, C.SEEK_END) != 0 { return error(posix_get_error_msg(C.errno)) } @@ -674,7 +674,7 @@ pub fn (mut f File) read_raw_at(pos u64) ?T { if C.fseeko(f.cfile, pos, C.SEEK_SET) != 0 { return error(posix_get_error_msg(C.errno)) } - nbytes = fread(&t, 1, tsize, f.cfile)? + nbytes = fread(&t, 1, tsize, f.cfile)! if C.fseeko(f.cfile, 0, C.SEEK_END) != 0 { return error(posix_get_error_msg(C.errno)) } @@ -684,7 +684,7 @@ pub fn (mut f File) read_raw_at(pos u64) ?T { if C.fseek(f.cfile, pos, C.SEEK_SET) != 0 { return error(posix_get_error_msg(C.errno)) } - nbytes = fread(&t, 1, tsize, f.cfile)? + nbytes = fread(&t, 1, tsize, f.cfile)! if C.fseek(f.cfile, 0, C.SEEK_END) != 0 { return error(posix_get_error_msg(C.errno)) } @@ -697,7 +697,7 @@ pub fn (mut f File) read_raw_at(pos u64) ?T { } // write_struct writes a single struct of type `T` -pub fn (mut f File) write_struct(t &T) ? { +pub fn (mut f File) write_struct(t &T) ! { if !f.is_opened { return error_file_not_opened() } @@ -716,7 +716,7 @@ pub fn (mut f File) write_struct(t &T) ? { } // write_struct_at writes a single struct of type `T` at position specified in file -pub fn (mut f File) write_struct_at(t &T, pos u64) ? { +pub fn (mut f File) write_struct_at(t &T, pos u64) ! { if !f.is_opened { return error_file_not_opened() } @@ -753,7 +753,7 @@ pub fn (mut f File) write_struct_at(t &T, pos u64) ? { // TODO `write_raw[_at]` implementations are copy-pasted from `write_struct[_at]` // write_raw writes a single instance of type `T` -pub fn (mut f File) write_raw(t &T) ? { +pub fn (mut f File) write_raw(t &T) ! { if !f.is_opened { return error_file_not_opened() } @@ -772,7 +772,7 @@ pub fn (mut f File) write_raw(t &T) ? { } // write_raw_at writes a single instance of type `T` starting at file byte offset `pos` -pub fn (mut f File) write_raw_at(t &T, pos u64) ? { +pub fn (mut f File) write_raw_at(t &T, pos u64) ! { if !f.is_opened { return error_file_not_opened() } @@ -841,7 +841,7 @@ pub enum SeekMode { // be returned to the caller. // A successful call to the fseek() function clears the end-of-file // indicator for the file. -pub fn (mut f File) seek(pos i64, mode SeekMode) ? { +pub fn (mut f File) seek(pos i64, mode SeekMode) ! { if !f.is_opened { return error_file_not_opened() } @@ -866,7 +866,7 @@ pub fn (mut f File) seek(pos i64, mode SeekMode) ? { // the start of the file, in bytes. It is complementary to seek, i.e. // you can use the return value as the `pos` parameter to .seek( pos, .start ), // so that your next read will happen from the same place. -pub fn (f &File) tell() ?i64 { +pub fn (f &File) tell() !i64 { if !f.is_opened { return error_file_not_opened() } diff --git a/vlib/os/file.js.v b/vlib/os/file.js.v index 72affb737..cf67f5679 100644 --- a/vlib/os/file.js.v +++ b/vlib/os/file.js.v @@ -27,7 +27,7 @@ fn error_size_of_type_0() IError { return IError(&ErrSizeOfTypeIs0{}) } */ -pub fn open_file(path string, mode string, options ...int) ?File { +pub fn open_file(path string, mode string, options ...int) !File { mut res := File{} $if js_node { #if (!options) { options = new array([]); } @@ -47,13 +47,13 @@ pub fn open_file(path string, mode string, options ...int) ?File { } // open tries to open a file for reading and returns back a read-only `File` object. -pub fn open(path string) ?File { - f := open_file(path, 'r')? +pub fn open(path string) !File { + f := open_file(path, 'r')! return f } -pub fn create(path string) ?File { - f := open_file(path, 'w')? +pub fn create(path string) !File { + f := open_file(path, 'w')! return f } @@ -78,7 +78,7 @@ pub fn stderr() File { } } -pub fn (f &File) read(mut buf []u8) ?int { +pub fn (f &File) read(mut buf []u8) !int { if buf.len == 0 { return 0 } @@ -93,7 +93,7 @@ pub fn (f &File) read(mut buf []u8) ?int { return nbytes } -pub fn (mut f File) write(buf []u8) ?int { +pub fn (mut f File) write(buf []u8) !int { if !f.is_opened { return error('file is not opened') } @@ -107,13 +107,13 @@ pub fn (mut f File) write(buf []u8) ?int { // writeln writes the string `s` into the file, and appends a \n character. // It returns how many bytes were written, including the \n character. -pub fn (mut f File) writeln(s string) ?int { - mut nbytes := f.write(s.bytes())? - nbytes += f.write('\n'.bytes())? +pub fn (mut f File) writeln(s string) !int { + mut nbytes := f.write(s.bytes())! + nbytes += f.write('\n'.bytes())! return nbytes } -pub fn (mut f File) write_to(pos u64, buf []u8) ?int { +pub fn (mut f File) write_to(pos u64, buf []u8) !int { if !f.is_opened { return error('file is not opened') } @@ -127,8 +127,8 @@ pub fn (mut f File) write_to(pos u64, buf []u8) ?int { // write_string writes the string `s` into the file // It returns how many bytes were actually written. -pub fn (mut f File) write_string(s string) ?int { - nbytes := f.write(s.bytes())? +pub fn (mut f File) write_string(s string) !int { + nbytes := f.write(s.bytes())! return nbytes } @@ -136,9 +136,9 @@ pub fn (mut f File) close() { #$fs.closeSync(f.valueOf().fd.valueOf()) } -pub fn (mut f File) write_full_buffer(s voidptr, buffer_len usize) ? {} +pub fn (mut f File) write_full_buffer(s voidptr, buffer_len usize) ! {} -pub fn (mut f File) write_array(buffer array) ?int { +pub fn (mut f File) write_array(buffer array) !int { if !f.is_opened { return error('file is not opened') } diff --git a/vlib/os/file_test.v b/vlib/os/file_test.v index 896aa2ef1..7746a1e82 100644 --- a/vlib/os/file_test.v +++ b/vlib/os/file_test.v @@ -7,8 +7,8 @@ const tfile = os.join_path_single(tfolder, 'test_file') fn testsuite_begin() { os.rmdir_all(tfolder) or {} assert !os.is_dir(tfolder) - os.mkdir_all(tfolder)? - os.chdir(tfolder)? + os.mkdir_all(tfolder)! + os.chdir(tfolder)! assert os.is_dir(tfolder) } @@ -61,23 +61,23 @@ const ( // returning on each newline, even before the buffer is full, and reaching EOF before // the buffer is completely filled. fn test_read_bytes_into_newline_text() { - mut f := os.open_file(tfile, 'w')? - f.write_string('Hello World!\nGood\r morning.')? + mut f := os.open_file(tfile, 'w')! + f.write_string('Hello World!\nGood\r morning.')! f.close() - f = os.open_file(tfile, 'r')? + f = os.open_file(tfile, 'r')! mut buf := []u8{len: 8} - n0 := f.read_bytes_into_newline(mut buf)? + n0 := f.read_bytes_into_newline(mut buf)! assert n0 == 8 - n1 := f.read_bytes_into_newline(mut buf)? + n1 := f.read_bytes_into_newline(mut buf)! assert n1 == 5 - n2 := f.read_bytes_into_newline(mut buf)? + n2 := f.read_bytes_into_newline(mut buf)! assert n2 == 8 - n3 := f.read_bytes_into_newline(mut buf)? + n3 := f.read_bytes_into_newline(mut buf)! assert n3 == 6 f.close() @@ -96,22 +96,22 @@ fn test_read_bytes_into_newline_binary() { n1_bytes := bw[10..13] n2_bytes := bw[13..] - mut f := os.open_file(tfile, 'w')? - f.write(bw)? + mut f := os.open_file(tfile, 'w')! + f.write(bw)! f.close() - f = os.open_file(tfile, 'r')? + f = os.open_file(tfile, 'r')! mut buf := []u8{len: 10} - n0 := f.read_bytes_into_newline(mut buf)? + n0 := f.read_bytes_into_newline(mut buf)! assert n0 == 10 assert buf[..n0] == n0_bytes - n1 := f.read_bytes_into_newline(mut buf)? + n1 := f.read_bytes_into_newline(mut buf)! assert n1 == 3 assert buf[..n1] == n1_bytes - n2 := f.read_bytes_into_newline(mut buf)? + n2 := f.read_bytes_into_newline(mut buf)! assert n2 == 2 assert buf[..n2] == n2_bytes f.close() @@ -122,12 +122,12 @@ fn test_read_bytes_into_newline_binary() { // test simulates file reading where the end-of-file is reached inside an fread // containing data. fn test_read_eof_last_read_partial_buffer_fill() { - mut f := os.open_file(tfile, 'w')? + mut f := os.open_file(tfile, 'w')! bw := []u8{len: 199, init: 5} - f.write(bw)? + f.write(bw)! f.close() - f = os.open_file(tfile, 'r')? + f = os.open_file(tfile, 'r')! mut br := []u8{len: 100} // Read first 100 bytes of 199 byte file, should fill buffer with no error. n0 := f.read(mut br)! @@ -154,12 +154,12 @@ fn test_read_eof_last_read_partial_buffer_fill() { // simulates file reading where the end-of-file is reached at the beinning of an // fread that returns no data. fn test_read_eof_last_read_full_buffer_fill() { - mut f := os.open_file(tfile, 'w')? + mut f := os.open_file(tfile, 'w')! bw := []u8{len: 200, init: 5} - f.write(bw)? + f.write(bw)! f.close() - f = os.open_file(tfile, 'r')? + f = os.open_file(tfile, 'r')! mut br := []u8{len: 100} // Read first 100 bytes of 200 byte file, should fill buffer with no error. n0 := f.read(mut br)! @@ -184,10 +184,10 @@ fn test_read_eof_last_read_full_buffer_fill() { fn test_write_struct() { os.rm(tfile) or {} // FIXME This is a workaround for macos, because the file isn't truncated when open with 'w' size_of_point := int(sizeof(Point)) - mut f := os.open_file(tfile, 'w')? - f.write_struct(another_point)? + mut f := os.open_file(tfile, 'w')! + f.write_struct(another_point)! f.close() - x := os.read_file(tfile)? + x := os.read_file(tfile)! pcopy := unsafe { &u8(memdup(&another_point, size_of_point)) } y := unsafe { pcopy.vstring_with_len(size_of_point) } assert x == y @@ -198,39 +198,39 @@ fn test_write_struct() { } fn test_write_struct_at() { - mut f := os.open_file(tfile, 'w')? - f.write_struct(extended_point)? - f.write_struct_at(another_point, 3)? + mut f := os.open_file(tfile, 'w')! + f.write_struct(extended_point)! + f.write_struct_at(another_point, 3)! f.close() - f = os.open_file(tfile, 'r')? + f = os.open_file(tfile, 'r')! mut p := Point{} - f.read_struct_at(mut p, 3)? + f.read_struct_at(mut p, 3)! f.close() assert p == another_point } fn test_read_struct() { - mut f := os.open_file(tfile, 'w')? - f.write_struct(another_point)? + mut f := os.open_file(tfile, 'w')! + f.write_struct(another_point)! f.close() - f = os.open_file(tfile, 'r')? + f = os.open_file(tfile, 'r')! mut p := Point{} - f.read_struct(mut p)? + f.read_struct(mut p)! f.close() assert p == another_point } fn test_read_struct_at() { - mut f := os.open_file(tfile, 'w')? - f.write([u8(1), 2, 3])? - f.write_struct(another_point)? + mut f := os.open_file(tfile, 'w')! + f.write([u8(1), 2, 3])! + f.write_struct(another_point)! f.close() - f = os.open_file(tfile, 'r')? + f = os.open_file(tfile, 'r')! mut p := Point{} - f.read_struct_at(mut p, 3)? + f.read_struct_at(mut p, 3)! f.close() assert p == another_point @@ -239,10 +239,10 @@ fn test_read_struct_at() { fn test_write_raw() { os.rm(tfile) or {} // FIXME This is a workaround for macos, because the file isn't truncated when open with 'w' size_of_point := int(sizeof(Point)) - mut f := os.open_file(tfile, 'w')? - f.write_raw(another_point)? + mut f := os.open_file(tfile, 'w')! + f.write_raw(another_point)! f.close() - x := os.read_file(tfile)? + x := os.read_file(tfile)! pcopy := unsafe { &u8(memdup(&another_point, size_of_point)) } y := unsafe { pcopy.vstring_with_len(size_of_point) } assert x == y @@ -253,20 +253,20 @@ fn test_write_raw() { } fn test_write_raw_at() { - mut f := os.open_file(tfile, 'w')? - f.write_raw(extended_point)? - f.write_raw_at(another_point, 3)? + mut f := os.open_file(tfile, 'w')! + f.write_raw(extended_point)! + f.write_raw_at(another_point, 3)! f.close() - f = os.open_file(tfile, 'r')? + f = os.open_file(tfile, 'r')! mut p := Point{} - f.read_struct_at(mut p, 3)? + f.read_struct_at(mut p, 3)! f.close() assert p == another_point } fn test_write_raw_at_negative_pos() { - mut f := os.open_file(tfile, 'w')? + mut f := os.open_file(tfile, 'w')! if _ := f.write_raw_at(another_point, -1) { assert false } @@ -275,17 +275,17 @@ fn test_write_raw_at_negative_pos() { } fn test_read_raw() { - mut f := os.open_file(tfile, 'w')? - f.write_raw(another_point)? - f.write_raw(another_byte)? - f.write_raw(another_color)? - f.write_raw(another_permission)? + mut f := os.open_file(tfile, 'w')! + f.write_raw(another_point)! + f.write_raw(another_byte)! + f.write_raw(another_color)! + f.write_raw(another_permission)! f.close() - f = os.open_file(tfile, 'r')? - p := f.read_raw()? - b := f.read_raw()? - c := f.read_raw()? - x := f.read_raw()? + f = os.open_file(tfile, 'r')! + p := f.read_raw()! + b := f.read_raw()! + c := f.read_raw()! + x := f.read_raw()! f.close() assert p == another_point @@ -295,22 +295,22 @@ fn test_read_raw() { } fn test_read_raw_at() { - mut f := os.open_file(tfile, 'w')? - f.write([u8(1), 2, 3])? - f.write_raw(another_point)? - f.write_raw(another_byte)? - f.write_raw(another_color)? - f.write_raw(another_permission)? + mut f := os.open_file(tfile, 'w')! + f.write([u8(1), 2, 3])! + f.write_raw(another_point)! + f.write_raw(another_byte)! + f.write_raw(another_color)! + f.write_raw(another_permission)! f.close() - f = os.open_file(tfile, 'r')? + f = os.open_file(tfile, 'r')! mut at := u64(3) - p := f.read_raw_at(at)? + p := f.read_raw_at(at)! at += sizeof(Point) - b := f.read_raw_at(at)? + b := f.read_raw_at(at)! at += sizeof(u8) - c := f.read_raw_at(at)? + c := f.read_raw_at(at)! at += sizeof(Color) - x := f.read_raw_at(at)? + x := f.read_raw_at(at)! at += sizeof(Permissions) f.close() @@ -321,7 +321,7 @@ fn test_read_raw_at() { } fn test_read_raw_at_negative_pos() { - mut f := os.open_file(tfile, 'r')? + mut f := os.open_file(tfile, 'r')! if _ := f.read_raw_at(-1) { assert false } @@ -330,23 +330,23 @@ fn test_read_raw_at_negative_pos() { } fn test_seek() { - mut f := os.open_file(tfile, 'w')? - f.write_raw(another_point)? - f.write_raw(another_byte)? - f.write_raw(another_color)? - f.write_raw(another_permission)? + mut f := os.open_file(tfile, 'w')! + f.write_raw(another_point)! + f.write_raw(another_byte)! + f.write_raw(another_color)! + f.write_raw(another_permission)! f.close() // println('> ${sizeof(Point)} ${sizeof(byte)} ${sizeof(Color)} ${sizeof(Permissions)}') - f = os.open_file(tfile, 'r')? + f = os.open_file(tfile, 'r')! // - f.seek(i64(sizeof(Point)), .start)? - assert f.tell()? == sizeof(Point) - b := f.read_raw()? + f.seek(i64(sizeof(Point)), .start)! + assert f.tell()! == sizeof(Point) + b := f.read_raw()! assert b == another_byte - f.seek(i64(sizeof(Color)), .current)? - x := f.read_raw()? + f.seek(i64(sizeof(Color)), .current)! + x := f.read_raw()! assert x == another_permission // f.close() @@ -355,13 +355,13 @@ fn test_seek() { fn test_tell() { for size in 10 .. 30 { s := 'x'.repeat(size) - os.write_file(tfile, s)? + os.write_file(tfile, s)! fs := os.file_size(tfile) assert int(fs) == size // - mut f := os.open_file(tfile, 'r')? - f.seek(-5, .end)? - pos := f.tell()? + mut f := os.open_file(tfile, 'r')! + f.seek(-5, .end)! + pos := f.tell()! f.close() // dump(pos) assert pos == size - 5 @@ -371,21 +371,21 @@ fn test_tell() { fn test_reopen() { tfile1 := os.join_path_single(tfolder, 'tfile1') tfile2 := os.join_path_single(tfolder, 'tfile2') - os.write_file(tfile1, 'Hello World!\nGood\r morning.\nBye 1.')? - os.write_file(tfile2, 'Another file\nAnother line.\nBye 2.')? + os.write_file(tfile1, 'Hello World!\nGood\r morning.\nBye 1.')! + os.write_file(tfile2, 'Another file\nAnother line.\nBye 2.')! assert os.file_size(tfile1) > 0 assert os.file_size(tfile2) > 0 mut line_buffer := []u8{len: 1024} - mut f2 := os.open(tfile2)? - x := f2.read_bytes_into_newline(mut line_buffer)? + mut f2 := os.open(tfile2)! + x := f2.read_bytes_into_newline(mut line_buffer)! assert !f2.eof() assert x > 0 assert line_buffer#[..x].bytestr() == 'Another file\n' // Note: after this call, f2 should be using the file `tfile1`: - f2.reopen(tfile1, 'r')? + f2.reopen(tfile1, 'r')! assert !f2.eof() z := f2.read(mut line_buffer) or { panic(err) } @@ -398,9 +398,9 @@ fn test_reopen() { } fn test_eof() { - os.write_file(tfile, 'Hello World!\n')? + os.write_file(tfile, 'Hello World!\n')! - mut f := os.open(tfile)? + mut f := os.open(tfile)! f.read_bytes(10) assert !f.eof() f.read_bytes(100) @@ -409,13 +409,13 @@ fn test_eof() { fn test_open_file_wb_ab() { os.rm(tfile) or {} - mut wfile := os.open_file('text.txt', 'wb', 0o666)? - wfile.write_string('hello')? + mut wfile := os.open_file('text.txt', 'wb', 0o666)! + wfile.write_string('hello')! wfile.close() - assert os.read_file('text.txt')? == 'hello' + assert os.read_file('text.txt')! == 'hello' // - mut afile := os.open_file('text.txt', 'ab', 0o666)? - afile.write_string('hello')? + mut afile := os.open_file('text.txt', 'ab', 0o666)! + afile.write_string('hello')! afile.close() assert os.read_file('text.txt')? == 'hellohello' } diff --git a/vlib/os/filelock/lib_nix.c.v b/vlib/os/filelock/lib_nix.c.v index 1af99165f..2d77edae2 100644 --- a/vlib/os/filelock/lib_nix.c.v +++ b/vlib/os/filelock/lib_nix.c.v @@ -17,7 +17,7 @@ pub fn (mut l FileLock) unlink() { C.unlink(&char(l.name.str)) } -pub fn (mut l FileLock) acquire() ?bool { +pub fn (mut l FileLock) acquire() !bool { if l.fd != -1 { // lock already acquired by this instance return false @@ -44,7 +44,7 @@ pub fn (mut l FileLock) release() bool { return false } -pub fn (mut l FileLock) wait_acquire(s int) ?bool { +pub fn (mut l FileLock) wait_acquire(s int) !bool { fin := time.now().add(s) for time.now() < fin { if l.try_acquire() { diff --git a/vlib/os/filelock/lib_windows.c.v b/vlib/os/filelock/lib_windows.c.v index 56cbacefe..42aa579ee 100644 --- a/vlib/os/filelock/lib_windows.c.v +++ b/vlib/os/filelock/lib_windows.c.v @@ -15,7 +15,7 @@ pub fn (mut l FileLock) unlink() { C.DeleteFileW(t_wide) } -pub fn (mut l FileLock) acquire() ?bool { +pub fn (mut l FileLock) acquire() !bool { if l.fd != -1 { // lock already acquired by this instance return false @@ -39,7 +39,7 @@ pub fn (mut l FileLock) release() bool { return false } -pub fn (mut l FileLock) wait_acquire(s int) ?bool { +pub fn (mut l FileLock) wait_acquire(s int) !bool { fin := time.now().add(s) for time.now() < fin { if l.try_acquire() { diff --git a/vlib/os/find_abs_path_of_executable_test.v b/vlib/os/find_abs_path_of_executable_test.v index 7bacaf07b..495ef51df 100644 --- a/vlib/os/find_abs_path_of_executable_test.v +++ b/vlib/os/find_abs_path_of_executable_test.v @@ -25,7 +25,7 @@ fn test_find_abs_path_of_executable() { // chdir(tfolder)? write_file(myclang_file, 'echo hello')? - chmod(myclang_file, 0o0777)? + chmod(myclang_file, 0o0777)! dump(real_path(myclang_file)) dump(is_executable(myclang_file)) defer { @@ -39,7 +39,7 @@ fn test_find_abs_path_of_executable() { dump(fpath) // setenv('PATH', original_path, true) - chdir(home_dir())? // change to a *completely* different folder, to avoid the original PATH containing `.` + chdir(home_dir())! // change to a *completely* different folder, to avoid the original PATH containing `.` if x := find_abs_path_of_executable('myclang') { eprintln('> find_abs_path_of_executable should have failed, but instead it found: $x') assert false diff --git a/vlib/os/glob_test.v b/vlib/os/glob_test.v index bab0dcc00..828d604ea 100644 --- a/vlib/os/glob_test.v +++ b/vlib/os/glob_test.v @@ -1,7 +1,7 @@ import os -fn deep_glob() ? { - os.chdir(@VMODROOT)? +fn deep_glob() ! { + os.chdir(@VMODROOT)! matches := os.glob('vlib/v/*/*.v') or { panic(err) } assert matches.len > 10 assert 'vlib/v/ast/ast.v' in matches @@ -15,8 +15,8 @@ fn deep_glob() ? { } } -fn redeep_glob() ? { - os.chdir(@VMODROOT)? +fn redeep_glob() ! { + os.chdir(@VMODROOT)! matches := os.glob('vlib/v/**/*.v') or { panic(err) } assert matches.len > 10 assert 'vlib/v/ast/ast.v' in matches @@ -32,15 +32,15 @@ fn redeep_glob() ? { fn test_glob_can_find_v_files_3_levels_deep() { $if !windows { - deep_glob()? - redeep_glob()? + deep_glob()! + redeep_glob()! } assert true } fn test_glob_can_find_files_in_current_folder() { - os.chdir(@VMODROOT)? - matches := os.glob('*')? + os.chdir(@VMODROOT)! + matches := os.glob('*')! assert '.gitignore' in matches assert 'make.bat' in matches assert 'Makefile' in matches @@ -53,8 +53,8 @@ fn test_glob_can_find_files_in_current_folder() { } fn test_glob_can_be_used_with_multiple_patterns() { - os.chdir(@VMODROOT)? - matches := os.glob('*', 'cmd/tools/*')? + os.chdir(@VMODROOT)! + matches := os.glob('*', 'cmd/tools/*')! assert 'README.md' in matches assert 'Makefile' in matches $if !windows { @@ -66,8 +66,8 @@ fn test_glob_can_be_used_with_multiple_patterns() { } fn test_glob_star() { - os.chdir(@VMODROOT)? - matches := os.glob('*ake*')? + os.chdir(@VMODROOT)! + matches := os.glob('*ake*')! assert 'Makefile' in matches assert 'make.bat' in matches } diff --git a/vlib/os/notify/backend_default.c.v b/vlib/os/notify/backend_default.c.v index 1a35c5087..af5a46c1e 100644 --- a/vlib/os/notify/backend_default.c.v +++ b/vlib/os/notify/backend_default.c.v @@ -1,6 +1,6 @@ module notify // Implement the API -pub fn new() ?FdNotifier { +pub fn new() !FdNotifier { panic('unsupported') } diff --git a/vlib/os/notify/backend_linux.c.v b/vlib/os/notify/backend_linux.c.v index f77dcb035..e4875e658 100644 --- a/vlib/os/notify/backend_linux.c.v +++ b/vlib/os/notify/backend_linux.c.v @@ -43,7 +43,7 @@ pub: // new creates a new EpollNotifier // The FdNotifier interface is returned to allow OS specific // implementations without exposing the concrete type -pub fn new() ?FdNotifier { +pub fn new() !FdNotifier { fd := C.epoll_create1(0) // 0 indicates default behavior if fd == -1 { return error(os.posix_get_error_msg(C.errno)) @@ -69,7 +69,7 @@ const ( ) // ctl is a helper method for add, modify, and remove -fn (mut en EpollNotifier) ctl(fd int, op int, mask u32) ? { +fn (mut en EpollNotifier) ctl(fd int, op int, mask u32) ! { event := C.epoll_event{ events: mask data: C.epoll_data_t{ @@ -82,20 +82,20 @@ fn (mut en EpollNotifier) ctl(fd int, op int, mask u32) ? { } // add adds a file descriptor to the watch list -fn (mut en EpollNotifier) add(fd int, events FdEventType, conf ...FdConfigFlags) ? { +fn (mut en EpollNotifier) add(fd int, events FdEventType, conf ...FdConfigFlags) ! { mask := flags_to_mask(events, ...conf) - en.ctl(fd, C.EPOLL_CTL_ADD, mask)? + en.ctl(fd, C.EPOLL_CTL_ADD, mask)! } // modify sets an existing entry in the watch list to the provided events and configuration -fn (mut en EpollNotifier) modify(fd int, events FdEventType, conf ...FdConfigFlags) ? { +fn (mut en EpollNotifier) modify(fd int, events FdEventType, conf ...FdConfigFlags) ! { mask := flags_to_mask(events, ...conf) - en.ctl(fd, C.EPOLL_CTL_MOD, mask)? + en.ctl(fd, C.EPOLL_CTL_MOD, mask)! } // remove removes a file descriptor from the watch list -fn (mut en EpollNotifier) remove(fd int) ? { - en.ctl(fd, C.EPOLL_CTL_DEL, 0)? +fn (mut en EpollNotifier) remove(fd int) ! { + en.ctl(fd, C.EPOLL_CTL_DEL, 0)! } // wait waits to be notified of events on the watch list, @@ -133,7 +133,7 @@ fn (mut en EpollNotifier) wait(timeout time.Duration) []FdEvent { // close closes the EpollNotifier, // any successive calls to add, modify, remove, and wait should fail -fn (mut en EpollNotifier) close() ? { +fn (mut en EpollNotifier) close() ! { if C.close(en.epoll_fd) == -1 { return error(os.posix_get_error_msg(C.errno)) } diff --git a/vlib/os/notify/notify.v b/vlib/os/notify/notify.v index 8bf3536ca..e8bab1f90 100644 --- a/vlib/os/notify/notify.v +++ b/vlib/os/notify/notify.v @@ -5,11 +5,11 @@ import time // Backends should provide a `new()?FdNotifier` function pub interface FdNotifier { mut: - add(fd int, events FdEventType, conf ...FdConfigFlags) ? - modify(fd int, events FdEventType, conf ...FdConfigFlags) ? - remove(fd int) ? + add(fd int, events FdEventType, conf ...FdConfigFlags) ! + modify(fd int, events FdEventType, conf ...FdConfigFlags) ! + remove(fd int) ! wait(timeout time.Duration) []FdEvent - close() ? + close() ! } pub interface FdEvent { diff --git a/vlib/os/notify/notify_test.v b/vlib/os/notify/notify_test.v index c01124cf4..1c945968e 100644 --- a/vlib/os/notify/notify_test.v +++ b/vlib/os/notify/notify_test.v @@ -4,7 +4,7 @@ import os import os.notify // make a pipe and return the (read, write) file descriptors -fn make_pipe() ?(int, int) { +fn make_pipe() !(int, int) { $if linux { pipefd := [2]int{} if C.pipe(&pipefd[0]) != 0 { @@ -18,14 +18,14 @@ fn make_pipe() ?(int, int) { fn test_level_trigger() { // currently only linux is supported $if linux { - mut notifier := notify.new()? - reader, writer := make_pipe()? + mut notifier := notify.new()! + reader, writer := make_pipe()! defer { os.fd_close(reader) os.fd_close(writer) notifier.close() or {} } - notifier.add(reader, .read)? + notifier.add(reader, .read)! os.fd_write(writer, 'foobar') mut n := ¬ifier @@ -39,14 +39,14 @@ fn test_level_trigger() { fn test_edge_trigger() { // currently only linux is supported $if linux { - mut notifier := notify.new()? - reader, writer := make_pipe()? + mut notifier := notify.new()! + reader, writer := make_pipe()! defer { os.fd_close(reader) os.fd_close(writer) notifier.close() or {} } - notifier.add(reader, .read, .edge_trigger)? + notifier.add(reader, .read, .edge_trigger)! mut n := ¬ifier @@ -66,14 +66,14 @@ fn test_edge_trigger() { fn test_one_shot() { $if linux { - mut notifier := notify.new()? - reader, writer := make_pipe()? + mut notifier := notify.new()! + reader, writer := make_pipe()! defer { os.fd_close(reader) os.fd_close(writer) notifier.close() or {} } - notifier.add(reader, .read, .one_shot)? + notifier.add(reader, .read, .one_shot)! mut n := ¬ifier @@ -84,20 +84,20 @@ fn test_one_shot() { assert notifier.wait(0).len == 0 // rearm - notifier.modify(reader, .read)? + notifier.modify(reader, .read)! check_read_event(mut n, reader, 'barbaz') } } fn test_hangup() { $if linux { - mut notifier := notify.new()? - reader, writer := make_pipe()? + mut notifier := notify.new()! + reader, writer := make_pipe()! defer { os.fd_close(reader) notifier.close() or {} } - notifier.add(reader, .hangup)? + notifier.add(reader, .hangup)! assert notifier.wait(0).len == 0 @@ -113,18 +113,18 @@ fn test_hangup() { fn test_write() { $if linux { - mut notifier := notify.new()? - reader, writer := make_pipe()? + mut notifier := notify.new()! + reader, writer := make_pipe()! defer { os.fd_close(reader) os.fd_close(writer) notifier.close() or {} } - notifier.add(reader, .write)? + notifier.add(reader, .write)! assert notifier.wait(0).len == 0 - notifier.add(writer, .write)? + notifier.add(writer, .write)! events := notifier.wait(0) assert events.len == 1 assert events[0].fd == writer @@ -134,8 +134,8 @@ fn test_write() { fn test_remove() { $if linux { - mut notifier := notify.new()? - reader, writer := make_pipe()? + mut notifier := notify.new()! + reader, writer := make_pipe()! defer { os.fd_close(reader) os.fd_close(writer) @@ -144,12 +144,12 @@ fn test_remove() { // level triggered - will keep getting events while // there is data to read - notifier.add(reader, .read)? + notifier.add(reader, .read)! os.fd_write(writer, 'foobar') assert notifier.wait(0).len == 1 assert notifier.wait(0).len == 1 - notifier.remove(reader)? + notifier.remove(reader)! assert notifier.wait(0).len == 0 } } diff --git a/vlib/os/open_uri_default.c.v b/vlib/os/open_uri_default.c.v index abfbad96d..70d25fcd2 100644 --- a/vlib/os/open_uri_default.c.v +++ b/vlib/os/open_uri_default.c.v @@ -1,6 +1,6 @@ module os -pub fn open_uri(uri string) ? { +pub fn open_uri(uri string) ! { mut vopen_uri_cmd := getenv('VOPEN_URI_CMD') if vopen_uri_cmd == '' { $if macos { diff --git a/vlib/os/open_uri_windows.c.v b/vlib/os/open_uri_windows.c.v index ea3e4ebca..2f3796b72 100644 --- a/vlib/os/open_uri_windows.c.v +++ b/vlib/os/open_uri_windows.c.v @@ -4,7 +4,7 @@ import dl type ShellExecuteWin = fn (voidptr, &u16, &u16, &u16, &u16, int) -pub fn open_uri(uri string) ? { +pub fn open_uri(uri string) ! { mut vopen_uri_cmd := getenv('VOPEN_URI_CMD') if vopen_uri_cmd != '' { result := execute('$vopen_uri_cmd "$uri"') @@ -13,9 +13,9 @@ pub fn open_uri(uri string) ? { } return } - handle := dl.open_opt('shell32', dl.rtld_now)? + handle := dl.open_opt('shell32', dl.rtld_now)! // https://docs.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shellexecutew - func := ShellExecuteWin(dl.sym_opt(handle, 'ShellExecuteW')?) + func := ShellExecuteWin(dl.sym_opt(handle, 'ShellExecuteW')!) func(C.NULL, 'open'.to_wide(), uri.to_wide(), C.NULL, C.NULL, C.SW_SHOWNORMAL) dl.close(handle) } diff --git a/vlib/os/os.c.v b/vlib/os/os.c.v index 3b2f19d1e..10eb44ba2 100644 --- a/vlib/os/os.c.v +++ b/vlib/os/os.c.v @@ -39,14 +39,14 @@ fn C._chsize_s(voidptr, u64) int // read_bytes returns all bytes read from file in `path`. [manualfree] -pub fn read_bytes(path string) ?[]u8 { - mut fp := vfopen(path, 'rb')? +pub fn read_bytes(path string) ![]u8 { + mut fp := vfopen(path, 'rb')! defer { C.fclose(fp) } - fsize := find_cfile_size(fp)? + fsize := find_cfile_size(fp)! if fsize == 0 { - mut sb := slurp_file_in_builder(fp)? + mut sb := slurp_file_in_builder(fp)! return unsafe { sb.reuse_as_plain_u8_array() } } mut res := []u8{len: fsize} @@ -58,7 +58,7 @@ pub fn read_bytes(path string) ?[]u8 { return res } -fn find_cfile_size(fp &C.FILE) ?int { +fn find_cfile_size(fp &C.FILE) !int { // NB: Musl's fseek returns -1 for virtual files, while Glibc's fseek returns 0 cseek := C.fseek(fp, 0, C.SEEK_END) raw_fsize := C.ftell(fp) @@ -84,12 +84,12 @@ const buf_size = 4096 // For these, we can not allocate all memory in advance (since we do not know the final size), and so we have no choice // but to read the file in `buf_size` chunks. [manualfree] -fn slurp_file_in_builder(fp &C.FILE) ?strings.Builder { +fn slurp_file_in_builder(fp &C.FILE) !strings.Builder { buf := [os.buf_size]u8{} mut sb := strings.new_builder(os.buf_size) for { mut read_bytes := fread(&buf[0], 1, os.buf_size, fp) or { - if err is none { + if err == IError(Eof{}) { break } unsafe { sb.free() } @@ -102,15 +102,15 @@ fn slurp_file_in_builder(fp &C.FILE) ?strings.Builder { // read_file reads the file in `path` and returns the contents. [manualfree] -pub fn read_file(path string) ?string { +pub fn read_file(path string) !string { mode := 'rb' - mut fp := vfopen(path, mode)? + mut fp := vfopen(path, mode)! defer { C.fclose(fp) } - allocate := find_cfile_size(fp)? + allocate := find_cfile_size(fp)! if allocate == 0 { - mut sb := slurp_file_in_builder(fp)? + mut sb := slurp_file_in_builder(fp)! res := sb.str() unsafe { sb.free() } return res @@ -144,7 +144,7 @@ pub fn read_file(path string) ?string { // // truncate changes the size of the file located in `path` to `len`. // Note that changing symbolic links on Windows only works as admin. -pub fn truncate(path string, len u64) ? { +pub fn truncate(path string, len u64) ! { fp := C.open(&char(path.str), o_wronly | o_trunc, 0) defer { C.close(fp) @@ -212,7 +212,7 @@ pub fn file_size(path string) u64 { } // mv moves files or folders from `src` to `dst`. -pub fn mv(src string, dst string) ? { +pub fn mv(src string, dst string) ! { mut rdst := dst if is_dir(rdst) { rdst = join_path_single(rdst.trim_right(path_separator), file_name(src.trim_right(path_separator))) @@ -233,7 +233,7 @@ pub fn mv(src string, dst string) ? { } // cp copies files or folders from `src` to `dst`. -pub fn cp(src string, dst string) ? { +pub fn cp(src string, dst string) ! { $if windows { w_src := src.replace('/', '\\') w_dst := dst.replace('/', '\\') @@ -284,7 +284,7 @@ pub fn cp(src string, dst string) ? { // vfopen returns an opened C file, given its path and open mode. // Note: os.vfopen is useful for compatibility with C libraries, that expect `FILE *`. // If you write pure V code, os.create or os.open are more convenient. -pub fn vfopen(path string, mode string) ?&C.FILE { +pub fn vfopen(path string, mode string) !&C.FILE { if path.len == 0 { return error('vfopen called with ""') } @@ -479,7 +479,7 @@ pub fn is_readable(path string) bool { } // rm removes file in `path`. -pub fn rm(path string) ? { +pub fn rm(path string) ! { mut rc := 0 $if windows { rc = C._wremove(path.to_wide()) @@ -493,7 +493,7 @@ pub fn rm(path string) ? { } // rmdir removes a specified directory. -pub fn rmdir(path string) ? { +pub fn rmdir(path string) ! { $if windows { rc := C.RemoveDirectory(path.to_wide()) if rc == 0 { @@ -798,7 +798,7 @@ fn kind_of_existing_path(path string) PathKind { } // chdir changes the current working directory to the new directory in `path`. -pub fn chdir(path string) ? { +pub fn chdir(path string) ! { ret := $if windows { C._wchdir(path.to_wide()) } $else { C.chdir(&char(path.str)) } if ret == -1 { return error_with_code(posix_get_error_msg(C.errno), C.errno) @@ -952,14 +952,14 @@ pub fn flush() { // chmod change file access attributes of `path` to `mode`. // Octals like `0o600` can be used. -pub fn chmod(path string, mode int) ? { +pub fn chmod(path string, mode int) ! { if C.chmod(&char(path.str), mode) != 0 { return error_with_code('chmod failed: ' + posix_get_error_msg(C.errno), C.errno) } } // chown changes the owner and group attributes of `path` to `owner` and `group`. -pub fn chown(path string, owner int, group int) ? { +pub fn chown(path string, owner int, group int) ! { $if windows { return error('os.chown() not implemented for Windows') } $else { @@ -970,7 +970,7 @@ pub fn chown(path string, owner int, group int) ? { } // open_append opens `path` file for appending. -pub fn open_append(path string) ?File { +pub fn open_append(path string) !File { mut file := File{} $if windows { wpath := path.replace('/', '\\').to_wide() @@ -996,7 +996,7 @@ pub fn open_append(path string) ?File { // The arguments, that will be passed to it are in `args`. // Note: this function will NOT return when successfull, since // the child process will take control over execution. -pub fn execvp(cmdpath string, cmdargs []string) ? { +pub fn execvp(cmdpath string, cmdargs []string) ! { mut cargs := []&char{} cargs << &char(cmdpath.str) for i in 0 .. cmdargs.len { @@ -1023,7 +1023,7 @@ pub fn execvp(cmdpath string, cmdargs []string) ? { // You can pass environment variables to through `envs`. // Note: this function will NOT return when successfull, since // the child process will take control over execution. -pub fn execve(cmdpath string, cmdargs []string, envs []string) ? { +pub fn execve(cmdpath string, cmdargs []string, envs []string) ! { mut cargv := []&char{} mut cenvs := []&char{} cargv << &char(cmdpath.str) @@ -1061,16 +1061,16 @@ pub fn is_atty(fd int) int { } // write_file_array writes the data in `buffer` to a file in `path`. -pub fn write_file_array(path string, buffer array) ? { - mut f := create(path)? - unsafe { f.write_full_buffer(buffer.data, usize(buffer.len * buffer.element_size))? } +pub fn write_file_array(path string, buffer array) ! { + mut f := create(path)! + unsafe { f.write_full_buffer(buffer.data, usize(buffer.len * buffer.element_size))! } f.close() } -pub fn glob(patterns ...string) ?[]string { +pub fn glob(patterns ...string) ![]string { mut matches := []string{} for pattern in patterns { - native_glob_pattern(pattern, mut matches)? + native_glob_pattern(pattern, mut matches)! } matches.sort() return matches diff --git a/vlib/os/os.js.v b/vlib/os/os.js.v index 95c2394a1..e47ffbd73 100644 --- a/vlib/os/os.js.v +++ b/vlib/os/os.js.v @@ -68,7 +68,7 @@ pub fn getpid() int { // chmod change file access attributes of `path` to `mode`. // Octals like `0o600` can be used. -pub fn chmod(path string, mode int) ? { +pub fn chmod(path string, mode int) ! { $if js_node { #try { #$fs.chmodSync(''+path,mode.valueOf()) @@ -82,7 +82,7 @@ pub fn chmod(path string, mode int) ? { // chown changes the owner and group attributes of `path` to `owner` and `group`. // Octals like `0o600` can be used. -pub fn chown(path string, owner int, group int) ? { +pub fn chown(path string, owner int, group int) ! { $if js_node { #try { #$fs.chownSync(''+path,owner.valueOf(),group.valueOf()) @@ -156,18 +156,18 @@ pub fn is_atty(fd int) int { return res } -pub fn glob(patterns ...string) ?[]string { +pub fn glob(patterns ...string) ![]string { panic('not yet implemented') - return none + return error('not yet implemented') } -pub fn write_file_array(path string, buffer array) ? { - mut f := create(path)? - f.write_array(buffer)? +pub fn write_file_array(path string, buffer array) ! { + mut f := create(path)! + f.write_array(buffer)! f.close() } -pub fn chdir(s string) ? { +pub fn chdir(s string) ! { #try { $process.chdir(s.str); } catch (e) { return error(new string('' + s)) } } diff --git a/vlib/os/os.v b/vlib/os/os.v index 43ece4346..8319bf81c 100644 --- a/vlib/os/os.v +++ b/vlib/os/os.v @@ -42,7 +42,7 @@ pub fn (mut result Result) free() { // cp_all will recursively copy `src` to `dst`, // optionally overwriting files or dirs in `dst`. -pub fn cp_all(src string, dst string, overwrite bool) ? { +pub fn cp_all(src string, dst string, overwrite bool) ! { source_path := real_path(src) dest_path := real_path(dst) if !exists(source_path) { @@ -58,27 +58,27 @@ pub fn cp_all(src string, dst string, overwrite bool) ? { } if exists(adjusted_path) { if overwrite { - rm(adjusted_path)? + rm(adjusted_path)! } else { return error('Destination file path already exist') } } - cp(source_path, adjusted_path)? + cp(source_path, adjusted_path)! return } if !exists(dest_path) { - mkdir(dest_path)? + mkdir(dest_path)! } if !is_dir(dest_path) { return error('Destination path is not a valid directory') } - files := ls(source_path)? + files := ls(source_path)! for file in files { sp := join_path_single(source_path, file) dp := join_path_single(dest_path, file) if is_dir(sp) { if !exists(dp) { - mkdir(dp)? + mkdir(dp)! } } cp_all(sp, dp, overwrite) or { @@ -90,15 +90,15 @@ pub fn cp_all(src string, dst string, overwrite bool) ? { // mv_by_cp first copies the source file, and if it is copied successfully, deletes the source file. // may be used when you are not sure that the source and target are on the same mount/partition. -pub fn mv_by_cp(source string, target string) ? { - cp(source, target)? - rm(source)? +pub fn mv_by_cp(source string, target string) ! { + cp(source, target)! + rm(source)! } // read_lines reads the file in `path` into an array of lines. [manualfree] -pub fn read_lines(path string) ?[]string { - buf := read_file(path)? +pub fn read_lines(path string) ![]string { + buf := read_file(path)! res := buf.split_into_lines() unsafe { buf.free() } return res @@ -144,9 +144,9 @@ pub fn sigint_to_signal_name(si int) string { } // rmdir_all recursively removes the specified directory. -pub fn rmdir_all(path string) ? { +pub fn rmdir_all(path string) ! { mut ret_err := '' - items := ls(path)? + items := ls(path)! for item in items { fullpath := join_path_single(path, item) if is_dir(fullpath) && !is_link(fullpath) { @@ -362,7 +362,7 @@ pub fn user_os() string { } // user_names returns an array of the name of every user on the system. -pub fn user_names() ?[]string { +pub fn user_names() ![]string { $if windows { result := execute('wmic useraccount get name') if result.exit_code != 0 { @@ -373,7 +373,7 @@ pub fn user_names() ?[]string { users.delete(users.len - 1) return users } $else { - lines := read_lines('/etc/passwd')? + lines := read_lines('/etc/passwd')! mut users := []string{cap: lines.len} for line in lines { end_name := line.index(':') or { line.len } @@ -410,9 +410,9 @@ pub fn expand_tilde_to_home(path string) string { // write_file writes `text` data to the file in `path`. // If `path` exists, the contents of `path` will be overwritten with the contents of `text`. -pub fn write_file(path string, text string) ? { - mut f := create(path)? - unsafe { f.write_full_buffer(text.str, usize(text.len))? } +pub fn write_file(path string, text string) ! { + mut f := create(path)! + unsafe { f.write_full_buffer(text.str, usize(text.len))! } f.close() } @@ -460,7 +460,7 @@ fn error_failed_to_find_executable() IError { // find_abs_path_of_executable walks the environment PATH, just like most shell do, it returns // the absolute path of the executable if found -pub fn find_abs_path_of_executable(exepath string) ?string { +pub fn find_abs_path_of_executable(exepath string) !string { if exepath == '' { return error('expected non empty `exepath`') } @@ -653,7 +653,7 @@ pub struct MkdirParams { } // mkdir_all will create a valid full path of all directories given in `path`. -pub fn mkdir_all(opath string, params MkdirParams) ? { +pub fn mkdir_all(opath string, params MkdirParams) ! { path := opath.replace('/', path_separator) mut p := if path.starts_with(path_separator) { path_separator } else { '' } path_parts := path.trim_left(path_separator).split(path_separator) @@ -833,7 +833,7 @@ pub fn quoted_path(path string) string { // On the rest, that is `$XDG_CONFIG_HOME`, or if that is not available, `~/.config`. // If the path cannot be determined, it returns an error. // (for example, when $HOME on linux, or %AppData% on windows is not defined) -pub fn config_dir() ?string { +pub fn config_dir() !string { $if windows { app_data := getenv('AppData') if app_data != '' { diff --git a/vlib/os/os_js.js.v b/vlib/os/os_js.js.v index f4d4500a6..e0a41e884 100644 --- a/vlib/os/os_js.js.v +++ b/vlib/os/os_js.js.v @@ -1,6 +1,6 @@ module os -pub fn mkdir(path string, params MkdirParams) ?bool { +pub fn mkdir(path string, params MkdirParams) !bool { $if js_node { if path == '.' { return true @@ -55,7 +55,7 @@ pub fn exists(path string) bool { return res } -pub fn ls(path string) ?[]string { +pub fn ls(path string) ![]string { if !is_dir(path) { return error('ls(): cannot open dir $dir') } @@ -81,7 +81,7 @@ pub fn is_executable(path string) bool { return false } -pub fn rmdir(path string) ? { +pub fn rmdir(path string) ! { $if js_node { err := '' #try { @@ -95,7 +95,7 @@ pub fn rmdir(path string) ? { } } -pub fn rm(path string) ? { +pub fn rm(path string) ! { $if js_node { err := '' #try { @@ -109,7 +109,7 @@ pub fn rm(path string) ? { } } -pub fn cp(src string, dst string) ? { +pub fn cp(src string, dst string) ! { $if js_node { err := '' #try { @@ -123,7 +123,7 @@ pub fn cp(src string, dst string) ? { } } -pub fn read_file(s string) ?string { +pub fn read_file(s string) !string { mut err := '' err = err res := '' @@ -151,7 +151,7 @@ pub fn getuid() int { return res } -pub fn execvp(cmd string, args []string) ? { +pub fn execvp(cmd string, args []string) ! { panic('os.execvp() is not available on JS backend') } diff --git a/vlib/os/os_nix.c.v b/vlib/os/os_nix.c.v index 05de17dc1..b04f12e3a 100644 --- a/vlib/os/os_nix.c.v +++ b/vlib/os/os_nix.c.v @@ -156,7 +156,7 @@ fn glob_match(dir string, pattern string, next_pattern string, mut matches []str return subdirs } -fn native_glob_pattern(pattern string, mut matches []string) ? { +fn native_glob_pattern(pattern string, mut matches []string) ! { steps := pattern.split(os.path_separator) mut cwd := if pattern.starts_with(os.path_separator) { os.path_separator } else { '.' } mut subdirs := [cwd] @@ -199,7 +199,7 @@ fn native_glob_pattern(pattern string, mut matches []string) ? { } } -pub fn utime(path string, actime int, modtime int) ? { +pub fn utime(path string, actime int, modtime int) ! { mut u := C.utimbuf{actime, modtime} if C.utime(&char(path.str), voidptr(&u)) != 0 { return error_with_code(posix_get_error_msg(C.errno), C.errno) @@ -252,7 +252,7 @@ fn init_os_args(argc int, argv &&u8) []string { return args_ } -pub fn ls(path string) ?[]string { +pub fn ls(path string) ![]string { if path.len == 0 { return error('ls() expects a folder, not an empty string') } @@ -296,7 +296,7 @@ pub fn is_dir(path string) bool { */ // mkdir creates a new directory with the specified path. -pub fn mkdir(path string, params MkdirParams) ?bool { +pub fn mkdir(path string, params MkdirParams) !bool { if path == '.' { return true } @@ -379,7 +379,7 @@ pub fn raw_execute(cmd string) Result { } [manualfree] -pub fn (mut c Command) start() ? { +pub fn (mut c Command) start() ! { pcmd := c.path + ' 2>&1' defer { unsafe { pcmd.free() } @@ -416,14 +416,14 @@ pub fn (mut c Command) read_line() string { return final } -pub fn (mut c Command) close() ? { +pub fn (mut c Command) close() ! { c.exit_code = vpclose(c.f) if c.exit_code == 127 { return error_with_code('error', 127) } } -pub fn symlink(origin string, target string) ?bool { +pub fn symlink(origin string, target string) !bool { res := C.symlink(&char(origin.str), &char(target.str)) if res == 0 { return true @@ -431,7 +431,7 @@ pub fn symlink(origin string, target string) ?bool { return error(posix_get_error_msg(C.errno)) } -pub fn link(origin string, target string) ?bool { +pub fn link(origin string, target string) !bool { res := C.link(&char(origin.str), &char(target.str)) if res == 0 { return true @@ -477,7 +477,7 @@ fn C.mkstemp(stemplate &u8) int // `is_writable_folder` - `folder` exists and is writable to the process [manualfree] -pub fn is_writable_folder(folder string) ?bool { +pub fn is_writable_folder(folder string) !bool { if !exists(folder) { return error('`$folder` does not exist') } @@ -495,7 +495,7 @@ pub fn is_writable_folder(folder string) ?bool { } C.close(x) } - rm(tmp_perm_check)? + rm(tmp_perm_check)! return true } diff --git a/vlib/os/os_test.v b/vlib/os/os_test.v index 1191c26d3..70baf1828 100644 --- a/vlib/os/os_test.v +++ b/vlib/os/os_test.v @@ -49,7 +49,7 @@ fn test_open_file() { fn test_read_file_from_virtual_filesystem() { $if linux { - mounts := os.read_file('/proc/mounts')? + mounts := os.read_file('/proc/mounts')! // it is not empty, contains some mounting such as root filesystem: /dev/x / ext4 rw 0 0 assert mounts.len > 20 @@ -60,7 +60,7 @@ fn test_read_file_from_virtual_filesystem() { fn test_read_binary_from_virtual_filesystem() { $if linux { - mounts_raw := os.read_bytes('/proc/mounts')? + mounts_raw := os.read_bytes('/proc/mounts')! mounts := mounts_raw.bytestr() // it is not empty, contains some mounting such as root filesystem: /dev/x / ext4 rw 0 0 @@ -108,21 +108,21 @@ fn test_open_file_binary() { // assert line2 == 'line 2' // } -fn create_file(fpath string) ? { - mut f := os.create(fpath)? +fn create_file(fpath string) ! { + mut f := os.create(fpath)! f.close() } -fn create_and_write_to_file(fpath string, content string) ? { - mut f := os.create(fpath)? - f.write_string(content)? +fn create_and_write_to_file(fpath string, content string) ! { + mut f := os.create(fpath)! + f.write_string(content)! f.close() } fn test_create_file() { filename := './test1.txt' hello := 'hello world!' - create_and_write_to_file(filename, hello)? + create_and_write_to_file(filename, hello)! assert u64(hello.len) == os.file_size(filename) os.rm(filename) or { panic(err) } } @@ -194,7 +194,7 @@ fn test_write_and_read_bytes() { // check that trying to read data from EOF doesn't error and returns 0 mut a := []u8{len: 5} nread := file_read.read_bytes_into(5, mut a) or { - n := if err is none { + n := if err == IError(os.Eof{}) { int(0) } else { eprintln(err) @@ -221,22 +221,22 @@ fn test_ls() { } } -fn create_tree() ? { - os.mkdir_all('myfolder/f1/f2/f3')? - os.mkdir_all('myfolder/a1/a2/a3', mode: 0o700)? +fn create_tree() ! { + os.mkdir_all('myfolder/f1/f2/f3')! + os.mkdir_all('myfolder/a1/a2/a3', mode: 0o700)! f3 := os.real_path('myfolder/f1/f2/f3') assert os.is_dir(f3) - create_file('myfolder/f1/f2/f3/a.txt')? - create_file('myfolder/f1/f2/f3/b.txt')? - create_file('myfolder/f1/f2/f3/c.txt')? - create_file('myfolder/f1/f2/f3/d.md')? - create_file('myfolder/f1/0.txt')? - create_file('myfolder/another.md')? - create_file('myfolder/a1/a2/a3/x.txt')? - create_file('myfolder/a1/a2/a3/y.txt')? - create_file('myfolder/a1/a2/a3/z.txt')? - create_file('myfolder/a1/1.txt')? - create_file('myfolder/xyz.ini')? + create_file('myfolder/f1/f2/f3/a.txt')! + create_file('myfolder/f1/f2/f3/b.txt')! + create_file('myfolder/f1/f2/f3/c.txt')! + create_file('myfolder/f1/f2/f3/d.md')! + create_file('myfolder/f1/0.txt')! + create_file('myfolder/another.md')! + create_file('myfolder/a1/a2/a3/x.txt')! + create_file('myfolder/a1/a2/a3/y.txt')! + create_file('myfolder/a1/a2/a3/z.txt')! + create_file('myfolder/a1/1.txt')! + create_file('myfolder/xyz.ini')! } fn remove_tree() { @@ -250,7 +250,7 @@ fn normalise_paths(paths []string) []string { } fn test_walk_ext() { - create_tree()? + create_tree()! defer { remove_tree() } @@ -277,8 +277,8 @@ fn test_walk_ext() { assert mds == ['myfolder/another.md', 'myfolder/f1/f2/f3/d.md'] } -fn test_walk_with_context() ? { - create_tree()? +fn test_walk_with_context() { + create_tree()! defer { remove_tree() } @@ -468,8 +468,8 @@ fn test_realpath_does_not_absolutize_non_existing_relative_paths() { fn test_realpath_absolutepath_symlink() { file_name := 'tolink_file.txt' symlink_name := 'symlink.txt' - create_file(file_name)? - assert os.symlink(file_name, symlink_name)? + create_file(file_name)! + assert os.symlink(file_name, symlink_name)! rpath := os.real_path(symlink_name) println(rpath) assert os.is_abs_path(rpath) @@ -510,7 +510,7 @@ fn test_make_symlink_check_is_link_and_remove_symlink_with_file() { symlink := 'tsymlink' os.rm(symlink) or {} os.rm(file) or {} - create_file(file)? + create_file(file)! os.symlink(file, symlink) or { panic(err) } assert os.is_link(symlink) os.rm(symlink) or { panic(err) } @@ -524,7 +524,7 @@ fn test_make_hardlink_check_is_link_and_remove_hardlink_with_file() { symlink := 'tsymlink' os.rm(symlink) or {} os.rm(file) or {} - create_file(file)? + create_file(file)! os.link(file, symlink) or { panic(err) } assert os.exists(symlink) os.rm(symlink) or { panic(err) } @@ -569,7 +569,7 @@ fn test_symlink() { fn test_is_executable_writable_readable() { file_name := 'rwxfile.exe' - create_file(file_name)? + create_file(file_name)! $if !windows { os.chmod(file_name, 0o600) or {} // mark as readable && writable, but NOT executable assert os.is_writable(file_name) @@ -732,7 +732,7 @@ fn test_posix_set_bit() { assert true } $else { fpath := 'permtest' - create_file(fpath)? + create_file(fpath)! os.chmod(fpath, 0o0777) or { panic(err) } c_fpath := &char(fpath.str) mut s := C.stat{} @@ -790,8 +790,8 @@ fn test_exists_in_system_path() { fn test_truncate() { filename := './test_trunc.txt' hello := 'hello world!' - mut f := os.create(filename)? - f.write_string(hello)? + mut f := os.create(filename)! + f.write_string(hello)! f.close() assert u64(hello.len) == os.file_size(filename) newlen := u64(40000) @@ -808,10 +808,10 @@ fn test_glob() { os.mkdir('test_dir') or { panic(err) } for i in 0 .. 4 { if i == 3 { - create_file('test_dir/test0_another')? - create_file('test_dir/test')? + create_file('test_dir/test0_another')! + create_file('test_dir/test')! } else { - create_file('test_dir/test' + i.str())? + create_file('test_dir/test' + i.str())! } } files := os.glob('test_dir/t*') or { panic(err) } @@ -846,7 +846,7 @@ fn test_execute() { // The output of the next command contains a 0 byte in the middle. // Nevertheless, the execute function *should* return a string that // contains it. - os.write_file(print0script, 'C.printf(c"start%cMIDDLE%cfinish\nxx", 0, 0)\n')? + os.write_file(print0script, 'C.printf(c"start%cMIDDLE%cfinish\nxx", 0, 0)\n')! defer { os.rm(print0script) or {} } @@ -904,12 +904,12 @@ fn test_reading_from_proc_cpuinfo() { assert true return } - info := os.read_file('/proc/cpuinfo')? + info := os.read_file('/proc/cpuinfo')! assert info.len > 0 assert info.contains('processor') assert info.ends_with('\n\n') - info_bytes := os.read_bytes('/proc/cpuinfo')? + info_bytes := os.read_bytes('/proc/cpuinfo')! assert info_bytes.len > 0 assert info.len == info_bytes.len } @@ -918,11 +918,11 @@ fn test_reading_from_empty_file() { empty_file := os.join_path_single(tfolder, 'empty_file.txt') os.rm(empty_file) or {} assert !os.exists(empty_file) - os.write_file(empty_file, '')? + os.write_file(empty_file, '')! assert os.exists(empty_file) - content := os.read_file(empty_file)? + content := os.read_file(empty_file)! assert content.len == 0 - content_bytes := os.read_bytes(empty_file)? + content_bytes := os.read_bytes(empty_file)! assert content_bytes.len == 0 - os.rm(empty_file)? + os.rm(empty_file)! } diff --git a/vlib/os/os_windows.c.v b/vlib/os/os_windows.c.v index eccbff99c..e35a67c44 100644 --- a/vlib/os/os_windows.c.v +++ b/vlib/os/os_windows.c.v @@ -104,7 +104,7 @@ fn init_os_args_wide(argc int, argv &&u8) []string { return args_ } -fn native_glob_pattern(pattern string, mut matches []string) ? { +fn native_glob_pattern(pattern string, mut matches []string) ! { $if debug { // FindFirstFile() and FindNextFile() both have a globbing function. // Unfortunately this is not as pronounced as under Unix, but should provide some functionality @@ -147,14 +147,14 @@ fn native_glob_pattern(pattern string, mut matches []string) ? { } } -pub fn utime(path string, actime int, modtime int) ? { +pub fn utime(path string, actime int, modtime int) ! { mut u := C._utimbuf{actime, modtime} if C._utime(&char(path.str), voidptr(&u)) != 0 { return error_with_code(posix_get_error_msg(C.errno), C.errno) } } -pub fn ls(path string) ?[]string { +pub fn ls(path string) ![]string { if path.len == 0 { return error('ls() expects a folder, not an empty string') } @@ -190,7 +190,7 @@ pub fn ls(path string) ?[]string { } // mkdir creates a new directory with the specified path. -pub fn mkdir(path string, params MkdirParams) ?bool { +pub fn mkdir(path string, params MkdirParams) !bool { if path == '.' { return true } @@ -213,7 +213,7 @@ pub fn get_file_handle(path string) HANDLE { // Ref - https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getmodulefilenamea // get_module_filename retrieves the fully qualified path for the file that contains the specified module. // The module must have been loaded by the current process. -pub fn get_module_filename(handle HANDLE) ?string { +pub fn get_module_filename(handle HANDLE) !string { unsafe { mut sz := 4096 // Optimized length mut buf := &u16(malloc_noscan(4096)) @@ -378,7 +378,7 @@ pub fn raw_execute(cmd string) Result { } } -pub fn symlink(origin string, target string) ?bool { +pub fn symlink(origin string, target string) !bool { // this is a temporary fix for TCC32 due to runtime error // TODO: find the cause why TCC32 for Windows does not work without the compiletime option $if x64 || x32 { @@ -402,7 +402,7 @@ pub fn symlink(origin string, target string) ?bool { return false } -pub fn link(origin string, target string) ?bool { +pub fn link(origin string, target string) !bool { res := C.CreateHardLinkW(target.to_wide(), origin.to_wide(), C.NULL) // 1 = success, != 1 failure => https://stackoverflow.com/questions/33010440/createsymboliclink-on-windows-10 if res != 1 { @@ -495,7 +495,7 @@ pub fn loginname() string { } // `is_writable_folder` - `folder` exists and is writable to the process -pub fn is_writable_folder(folder string) ?bool { +pub fn is_writable_folder(folder string) !bool { if !exists(folder) { return error('`$folder` does not exist') } @@ -505,7 +505,7 @@ pub fn is_writable_folder(folder string) ?bool { tmp_folder_name := 'tmp_perm_check_pid_' + getpid().str() tmp_perm_check := join_path_single(folder, tmp_folder_name) write_file(tmp_perm_check, 'test') or { return error('cannot write to folder "$folder": $err') } - rm(tmp_perm_check)? + rm(tmp_perm_check)! return true } @@ -545,7 +545,7 @@ pub fn posix_set_permission_bit(path_s string, mode u32, enable bool) { // -pub fn (mut c Command) start() ? { +pub fn (mut c Command) start() ! { panic('not implemented') } @@ -553,6 +553,6 @@ pub fn (mut c Command) read_line() string { panic('not implemented') } -pub fn (mut c Command) close() ? { +pub fn (mut c Command) close() ! { panic('not implemented') } diff --git a/vlib/os/process_test.v b/vlib/os/process_test.v index 5c340326e..8a44f5d4f 100644 --- a/vlib/os/process_test.v +++ b/vlib/os/process_test.v @@ -13,13 +13,13 @@ const ( fn testsuite_begin() { os.rmdir_all(tfolder) or {} - os.mkdir_all(tfolder)? + os.mkdir_all(tfolder)! if os.getenv('WINE_TEST_OS_PROCESS_EXE') != '' { // Make it easier to run the test under wine emulation, by just // prebuilding the executable with: // v -os windows -o x.exe cmd/tools/test_os_process.v // WINE_TEST_OS_PROCESS_EXE=x.exe ./v -os windows vlib/os/process_test.v - os.cp(os.getenv('WINE_TEST_OS_PROCESS_EXE'), test_os_process)? + os.cp(os.getenv('WINE_TEST_OS_PROCESS_EXE'), test_os_process)! } else { os.system('${os.quoted_path(vexe)} -o ${os.quoted_path(test_os_process)} ${os.quoted_path(test_os_process_source)}') } diff --git a/vlib/os/signal.c.v b/vlib/os/signal.c.v index 089985ef7..4b739a9ca 100644 --- a/vlib/os/signal.c.v +++ b/vlib/os/signal.c.v @@ -5,7 +5,7 @@ module os fn C.signal(signal int, handlercb SignalHandler) voidptr // signal will assign `handler` callback to be called when `signum` signal is received. -pub fn signal_opt(signum Signal, handler SignalHandler) ?SignalHandler { +pub fn signal_opt(signum Signal, handler SignalHandler) !SignalHandler { C.errno = 0 prev_handler := C.signal(int(signum), handler) if prev_handler == C.SIG_ERR { diff --git a/vlib/sokol/sapp/sapp_v.c.v b/vlib/sokol/sapp/sapp_v.c.v index 346fa2335..4de1fa923 100644 --- a/vlib/sokol/sapp/sapp_v.c.v +++ b/vlib/sokol/sapp/sapp_v.c.v @@ -11,7 +11,7 @@ fn C.v_sapp_gl_read_rgba_pixels(x int, y int, width int, height int, pixels char // of the file name in `path`. // // Supported formats are: `.png`, `.ppm`. -pub fn screenshot(path string) ? { +pub fn screenshot(path string) ! { match os.file_ext(path) { '.png' { return screenshot_png(path) @@ -28,31 +28,31 @@ pub fn screenshot(path string) ? { // screenshot_ppm takes a screenshot of the current window and // saves it to `path` as a .ppm file. [manualfree] -pub fn screenshot_ppm(path string) ? { +pub fn screenshot_ppm(path string) ! { ss := screenshot_window() - write_rgba_to_ppm(path, ss.width, ss.height, 4, ss.pixels)? + write_rgba_to_ppm(path, ss.width, ss.height, 4, ss.pixels)! unsafe { ss.destroy() } } // screenshot_png takes a screenshot of the current window and // saves it to `path` as a .png file. [manualfree] -pub fn screenshot_png(path string) ? { +pub fn screenshot_png(path string) ! { ss := screenshot_window() stbi.set_flip_vertically_on_write(true) - stbi.stbi_write_png(path, ss.width, ss.height, 4, ss.pixels, ss.width * 4)? + stbi.stbi_write_png(path, ss.width, ss.height, 4, ss.pixels, ss.width * 4)! unsafe { ss.destroy() } } // write_rgba_to_ppm writes `pixels` data in RGBA format to PPM3 format. -fn write_rgba_to_ppm(path string, w int, h int, components int, pixels &u8) ? { - mut f_out := os.create(path)? +fn write_rgba_to_ppm(path string, w int, h int, components int, pixels &u8) ! { + mut f_out := os.create(path)! defer { f_out.close() } - f_out.writeln('P3')? - f_out.writeln('$w $h')? - f_out.writeln('255')? + f_out.writeln('P3')! + f_out.writeln('$w $h')! + f_out.writeln('255')! for i := h - 1; i >= 0; i-- { for j := 0; j < w; j++ { idx := i * w * components + j * components @@ -60,7 +60,7 @@ fn write_rgba_to_ppm(path string, w int, h int, components int, pixels &u8) ? { r := int(pixels[idx]) g := int(pixels[idx + 1]) b := int(pixels[idx + 2]) - f_out.write_string('$r $g $b ')? + f_out.write_string('$r $g $b ')! } } } diff --git a/vlib/stbi/stbi.c.v b/vlib/stbi/stbi.c.v index 2ca04952c..09766ffb1 100644 --- a/vlib/stbi/stbi.c.v +++ b/vlib/stbi/stbi.c.v @@ -110,7 +110,7 @@ fn C.stbi_load_from_file(f voidptr, x &int, y &int, channels_in_file &int, desir fn C.stbi_load_from_memory(buffer &u8, len int, x &int, y &int, channels_in_file &int, desired_channels int) &u8 // load load an image from a path -pub fn load(path string) ?Image { +pub fn load(path string) !Image { ext := path.all_after_last('.') mut res := Image{ ok: true @@ -132,7 +132,7 @@ pub fn load(path string) ?Image { } // load_from_memory load an image from a memory buffer -pub fn load_from_memory(buf &u8, bufsize int) ?Image { +pub fn load_from_memory(buf &u8, bufsize int) !Image { mut res := Image{ ok: true data: 0 @@ -160,21 +160,21 @@ fn C.stbi_write_jpg(filename &char, w int, h int, comp int, buffer &u8, quality // stbi_write_png write on path a PNG file // row_stride_in_bytes is usually equal to: w * comp -pub fn stbi_write_png(path string, w int, h int, comp int, buf &u8, row_stride_in_bytes int) ? { +pub fn stbi_write_png(path string, w int, h int, comp int, buf &u8, row_stride_in_bytes int) ! { if 0 == C.stbi_write_png(&char(path.str), w, h, comp, buf, row_stride_in_bytes) { return error('stbi_image failed to write png file to "$path"') } } // stbi_write_png write on path a BMP file -pub fn stbi_write_bmp(path string, w int, h int, comp int, buf &u8) ? { +pub fn stbi_write_bmp(path string, w int, h int, comp int, buf &u8) ! { if 0 == C.stbi_write_bmp(&char(path.str), w, h, comp, buf) { return error('stbi_image failed to write bmp file to "$path"') } } // stbi_write_png write on path a TGA file -pub fn stbi_write_tga(path string, w int, h int, comp int, buf &u8) ? { +pub fn stbi_write_tga(path string, w int, h int, comp int, buf &u8) ! { if 0 == C.stbi_write_tga(&char(path.str), w, h, comp, buf) { return error('stbi_image failed to write tga file to "$path"') } @@ -183,14 +183,14 @@ pub fn stbi_write_tga(path string, w int, h int, comp int, buf &u8) ? { // stbi_write_png write on path a JPG file // quality select the compression quality of the JPG // quality is between 1 and 100. Higher quality looks better but results in a bigger image. -pub fn stbi_write_jpg(path string, w int, h int, comp int, buf &u8, quality int) ? { +pub fn stbi_write_jpg(path string, w int, h int, comp int, buf &u8, quality int) ! { if 0 == C.stbi_write_jpg(&char(path.str), w, h, comp, buf, quality) { return error('stbi_image failed to write jpg file to "$path"') } } /* -pub fn stbi_write_hdr(path string, w int, h int, comp int, buf &byte) ? { +pub fn stbi_write_hdr(path string, w int, h int, comp int, buf &byte) ! { if 0 == C.stbi_write_hdr(&char(path.str), w , h , comp , buf){ return error('stbi_image failed to write hdr file to "$path"') } diff --git a/vlib/strconv/atof.c.v b/vlib/strconv/atof.c.v index 14241cdcd..bf7273708 100644 --- a/vlib/strconv/atof.c.v +++ b/vlib/strconv/atof.c.v @@ -393,7 +393,7 @@ fn converter(mut pn PrepNumber) u64 { } // atof64 parses the string `s`, and if possible, converts it into a f64 number -pub fn atof64(s string) ?f64 { +pub fn atof64(s string) !f64 { if s.len == 0 { return error('expected a number found an empty string') } diff --git a/vlib/strconv/atof.js.v b/vlib/strconv/atof.js.v index 217851d23..c1878caf1 100644 --- a/vlib/strconv/atof.js.v +++ b/vlib/strconv/atof.js.v @@ -1,7 +1,7 @@ module strconv // atof64 return a f64 from a string doing a parsing operation -pub fn atof64(s string) ?f64 { +pub fn atof64(s string) !f64 { // TODO: handle parsing invalid numbers as close as possible to the pure V version // that may be slower, but more portable, and will guarantee that higher level code // works the same in the JS version, as well as in the C and Native versions. diff --git a/vlib/strconv/atoi.v b/vlib/strconv/atoi.v index 6418d1989..345ec8723 100644 --- a/vlib/strconv/atoi.v +++ b/vlib/strconv/atoi.v @@ -19,7 +19,7 @@ pub fn byte_to_lower(c u8) u8 { // common_parse_uint is called by parse_uint and allows the parsing // to stop on non or invalid digit characters and return with an error -pub fn common_parse_uint(s string, _base int, _bit_size int, error_on_non_digit bool, error_on_high_digit bool) ?u64 { +pub fn common_parse_uint(s string, _base int, _bit_size int, error_on_non_digit bool, error_on_high_digit bool) !u64 { result, err := common_parse_uint2(s, _base, _bit_size) // TODO: error_on_non_digit and error_on_high_digit have no difference if err != 0 && (error_on_non_digit || error_on_high_digit) { @@ -120,14 +120,14 @@ pub fn common_parse_uint2(s string, _base int, _bit_size int) (u64, int) { } // parse_uint is like parse_int but for unsigned numbers. -pub fn parse_uint(s string, _base int, _bit_size int) ?u64 { +pub fn parse_uint(s string, _base int, _bit_size int) !u64 { return common_parse_uint(s, _base, _bit_size, true, true) } // common_parse_int is called by parse int and allows the parsing // to stop on non or invalid digit characters and return with an error [direct_array_access] -pub fn common_parse_int(_s string, base int, _bit_size int, error_on_non_digit bool, error_on_high_digit bool) ?i64 { +pub fn common_parse_int(_s string, base int, _bit_size int, error_on_non_digit bool, error_on_high_digit bool) !i64 { if _s.len < 1 { // return error('parse_int: syntax error $s') return i64(0) @@ -149,7 +149,7 @@ pub fn common_parse_int(_s string, base int, _bit_size int, error_on_non_digit b // un := parse_uint(s, base, bit_size) or { // return i64(0) // } - un := common_parse_uint(s, base, bit_size, error_on_non_digit, error_on_high_digit)? + un := common_parse_uint(s, base, bit_size, error_on_non_digit, error_on_high_digit)! if un == 0 { return i64(0) } @@ -178,13 +178,13 @@ pub fn common_parse_int(_s string, base int, _bit_size int, error_on_non_digit b // that the result must fit into. Bit sizes 0, 8, 16, 32, and 64 // correspond to int, int8, int16, int32, and int64. // If bitSize is below 0 or above 64, an error is returned. -pub fn parse_int(_s string, base int, _bit_size int) ?i64 { +pub fn parse_int(_s string, base int, _bit_size int) !i64 { return common_parse_int(_s, base, _bit_size, true, true) } // atoi is equivalent to parse_int(s, 10, 0), converted to type int. [direct_array_access] -pub fn atoi(s string) ?int { +pub fn atoi(s string) !int { if s == '' { return error('strconv.atoi: parsing "": invalid syntax') } @@ -211,7 +211,7 @@ pub fn atoi(s string) ?int { return if s[0] == `-` { -n } else { n } } // Slow path for invalid, big, or underscored integers. - int64 := parse_int(s, 10, 0)? + int64 := parse_int(s, 10, 0)! return int(int64) } diff --git a/vlib/strconv/atoi_test.v b/vlib/strconv/atoi_test.v index a4b1405ad..0d8ed8214 100644 --- a/vlib/strconv/atoi_test.v +++ b/vlib/strconv/atoi_test.v @@ -1,9 +1,9 @@ import strconv -fn test_atoi() ? { - assert strconv.atoi('16')? == 16 - assert strconv.atoi('+16')? == 16 - assert strconv.atoi('-16')? == -16 +fn test_atoi() { + assert strconv.atoi('16')! == 16 + assert strconv.atoi('+16')! == 16 + assert strconv.atoi('-16')! == -16 // invalid strings if x := strconv.atoi('str') { @@ -26,20 +26,20 @@ fn test_atoi() ? { } } -fn test_parse_int() ? { +fn test_parse_int() { // Different bases - assert strconv.parse_int('16', 16, 0)? == 0x16 - assert strconv.parse_int('16', 8, 0)? == 0o16 - assert strconv.parse_int('11', 2, 0)? == 3 + assert strconv.parse_int('16', 16, 0)! == 0x16 + assert strconv.parse_int('16', 8, 0)! == 0o16 + assert strconv.parse_int('11', 2, 0)! == 3 // Different bit sizes - assert strconv.parse_int('127', 10, 8)? == 127 - assert strconv.parse_int('128', 10, 8)? == 127 - assert strconv.parse_int('32767', 10, 16)? == 32767 - assert strconv.parse_int('32768', 10, 16)? == 32767 - assert strconv.parse_int('2147483647', 10, 32)? == 2147483647 - assert strconv.parse_int('2147483648', 10, 32)? == 2147483647 - assert strconv.parse_int('9223372036854775807', 10, 64)? == 9223372036854775807 - assert strconv.parse_int('9223372036854775808', 10, 64)? == 9223372036854775807 + assert strconv.parse_int('127', 10, 8)! == 127 + assert strconv.parse_int('128', 10, 8)! == 127 + assert strconv.parse_int('32767', 10, 16)! == 32767 + assert strconv.parse_int('32768', 10, 16)! == 32767 + assert strconv.parse_int('2147483647', 10, 32)! == 2147483647 + assert strconv.parse_int('2147483648', 10, 32)! == 2147483647 + assert strconv.parse_int('9223372036854775807', 10, 64)! == 9223372036854775807 + assert strconv.parse_int('9223372036854775808', 10, 64)! == 9223372036854775807 assert strconv.parse_int('baobab', 36, 64)? == 683058467 // Invalid bit sizes if x := strconv.parse_int('123', 10, -1) { diff --git a/vlib/strings/builder.c.v b/vlib/strings/builder.c.v index 39b16211e..64d27c29f 100644 --- a/vlib/strings/builder.c.v +++ b/vlib/strings/builder.c.v @@ -75,7 +75,7 @@ pub fn (mut b Builder) write_byte(data byte) { } // write implements the Writer interface -pub fn (mut b Builder) write(data []u8) ?int { +pub fn (mut b Builder) write(data []u8) !int { if data.len == 0 { return 0 } diff --git a/vlib/szip/szip.v b/vlib/szip/szip.v index 720820936..a057082b4 100644 --- a/vlib/szip/szip.v +++ b/vlib/szip/szip.v @@ -94,7 +94,7 @@ fn (om OpenMode) to_u8() u8 { // name: the name of the zip file to open. // level: can be any value of the CompressionLevel enum. // mode: can be any value of the OpenMode enum. -pub fn open(name string, level CompressionLevel, mode OpenMode) ?&Zip { +pub fn open(name string, level CompressionLevel, mode OpenMode) !&Zip { if name.len == 0 { return error('szip: name of file empty') } @@ -115,7 +115,7 @@ pub fn (mut z Zip) close() { // For zip archive opened in 'w' or 'a' mode the function will append // a new entry. In readonly mode the function tries to locate the entry // in global dictionary. -pub fn (mut zentry Zip) open_entry(name string) ? { +pub fn (mut zentry Zip) open_entry(name string) ! { res := C.zip_entry_open(zentry, &char(name.str)) if res == -1 { return error('szip: cannot open archive entry') @@ -123,7 +123,7 @@ pub fn (mut zentry Zip) open_entry(name string) ? { } // open_entry_by_index opens an entry by index in the archive. -pub fn (mut z Zip) open_entry_by_index(index int) ? { +pub fn (mut z Zip) open_entry_by_index(index int) ! { res := C.zip_entry_openbyindex(z, index) if res == -1 { return error('szip: cannot open archive entry at index $index') @@ -152,7 +152,7 @@ pub fn (mut zentry Zip) name() string { } // index returns an index of the current zip entry. -pub fn (mut zentry Zip) index() ?int { +pub fn (mut zentry Zip) index() !int { index := int(C.zip_entry_index(zentry)) if index == -1 { return error('szip: cannot get current index of zip entry') @@ -161,7 +161,7 @@ pub fn (mut zentry Zip) index() ?int { } // is_dir determines if the current zip entry is a directory entry. -pub fn (mut zentry Zip) is_dir() ?bool { +pub fn (mut zentry Zip) is_dir() !bool { isdir := C.zip_entry_isdir(zentry) if isdir < 0 { return error('szip: cannot check entry type') @@ -182,7 +182,7 @@ pub fn (mut zentry Zip) crc32() u32 { } // write_entry compresses an input buffer for the current zip entry. -pub fn (mut zentry Zip) write_entry(data []u8) ? { +pub fn (mut zentry Zip) write_entry(data []u8) ! { if int(data[0] & 0xff) == -1 { return error('szip: cannot write entry') } @@ -193,7 +193,7 @@ pub fn (mut zentry Zip) write_entry(data []u8) ? { } // create_entry compresses a file for the current zip entry. -pub fn (mut zentry Zip) create_entry(name string) ? { +pub fn (mut zentry Zip) create_entry(name string) ! { res := C.zip_entry_fwrite(zentry, &char(name.str)) if res != 0 { return error('szip: failed to create entry') @@ -204,7 +204,7 @@ pub fn (mut zentry Zip) create_entry(name string) ? { // The function allocates sufficient memory for an output buffer. // NOTE: remember to release the memory allocated for an output buffer. // for large entries, please take a look at zip_entry_extract function. -pub fn (mut zentry Zip) read_entry() ?voidptr { +pub fn (mut zentry Zip) read_entry() !voidptr { mut buf := &u8(0) mut bsize := usize(0) res := C.zip_entry_read(zentry, unsafe { &voidptr(&buf) }, &bsize) @@ -215,7 +215,7 @@ pub fn (mut zentry Zip) read_entry() ?voidptr { } // read_entry_buf extracts the current zip entry into user specified buffer -pub fn (mut zentry Zip) read_entry_buf(buf voidptr, in_bsize int) ?int { +pub fn (mut zentry Zip) read_entry_buf(buf voidptr, in_bsize int) !int { bsize := usize(in_bsize) res := C.zip_entry_noallocread(zentry, buf, bsize) if res == -1 { @@ -225,7 +225,7 @@ pub fn (mut zentry Zip) read_entry_buf(buf voidptr, in_bsize int) ?int { } // extract_entry extracts the current zip entry into output file. -pub fn (mut zentry Zip) extract_entry(path string) ? { +pub fn (mut zentry Zip) extract_entry(path string) ! { res := C.zip_entry_fread(zentry, &char(path.str)) if res != 0 { return error('szip: failed to extract entry') @@ -233,7 +233,7 @@ pub fn (mut zentry Zip) extract_entry(path string) ? { } // extract zip file to directory -pub fn extract_zip_to_dir(file string, dir string) ?bool { +pub fn extract_zip_to_dir(file string, dir string) !bool { if C.access(&char(dir.str), 0) == -1 { return error('szip: cannot open directory for extracting, directory not exists') } @@ -242,7 +242,7 @@ pub fn extract_zip_to_dir(file string, dir string) ?bool { } // zip files (full path) to zip file -pub fn zip_files(path_to_file []string, path_to_export_zip string) ? { +pub fn zip_files(path_to_file []string, path_to_export_zip string) ! { // open or create new zip mut zip := open(path_to_export_zip, .no_compression, .write) or { panic(err) } @@ -264,7 +264,7 @@ pub fn zip_files(path_to_file []string, path_to_export_zip string) ? { // zip_folder zips all entries in `folder` *recursively* to the zip file at `zip_file`. // Empty folders will be included, unless specified otherwise in `opt`. -pub fn zip_folder(folder string, zip_file string, opt ZipFolderOptions) ? { +pub fn zip_folder(folder string, zip_file string, opt ZipFolderOptions) ! { // get list of files from directory path := folder.trim_right(os.path_separator) mut files := []string{} @@ -273,7 +273,7 @@ pub fn zip_folder(folder string, zip_file string, opt ZipFolderOptions) ? { }) // open or create new zip - mut zip := open(zip_file, .no_compression, .write)? + mut zip := open(zip_file, .no_compression, .write)! // close zip defer { zip.close() @@ -296,17 +296,17 @@ pub fn zip_folder(folder string, zip_file string, opt ZipFolderOptions) ? { zip_file_entry += '/' // Tells the implementation that the entry is a directory } // add file or directory (ends with "/") to zip - zip.open_entry(zip_file_entry)? + zip.open_entry(zip_file_entry)! if !is_dir { - file_as_byte := os.read_bytes(file)? - zip.write_entry(file_as_byte)? + file_as_byte := os.read_bytes(file)! + zip.write_entry(file_as_byte)! } zip.close_entry() } } // total returns the number of all entries (files and directories) in the zip archive. -pub fn (mut zentry Zip) total() ?int { +pub fn (mut zentry Zip) total() !int { tentry := int(C.zip_entries_total(zentry)) if tentry == -1 { return error('szip: cannot count total entries') diff --git a/vlib/szip/szip_test.v b/vlib/szip/szip_test.v index 60333bf6f..0971b596f 100644 --- a/vlib/szip/szip_test.v +++ b/vlib/szip/szip_test.v @@ -41,39 +41,39 @@ fn testsuite_end() { } fn test_szip_create_temp_files() { - os.mkdir(test_path)? - os.mkdir(test_path2)? - os.write_file(fpath1, 'file one')? - os.write_file(fpath2, 'file two')? - os.write_file(fpath3, 'file three')? + os.mkdir(test_path)! + os.mkdir(test_path2)! + os.write_file(fpath1, 'file one')! + os.write_file(fpath2, 'file two')! + os.write_file(fpath3, 'file three')! assert os.exists(fpath1) assert os.exists(fpath2) assert os.exists(fpath3) } fn test_zipping_files() { - mut files := (os.ls(test_path)?).map(os.join_path(test_path, it)) - files << (os.ls(test_path2)?).map(os.join_path(test_path2, it)) - szip.zip_files(files, test_out_zip)? + mut files := (os.ls(test_path)!).map(os.join_path(test_path, it)) + files << (os.ls(test_path2)!).map(os.join_path(test_path2, it)) + szip.zip_files(files, test_out_zip)! assert os.exists(test_out_zip) - os.rm(fpath1)? - os.rm(fpath2)? - os.rm(fpath3)? + os.rm(fpath1)! + os.rm(fpath2)! + os.rm(fpath3)! } fn test_extract_zipped_files() { - szip.extract_zip_to_dir(test_out_zip, test_path)? - szip.extract_zip_to_dir(test_out_zip, test_path2)? + szip.extract_zip_to_dir(test_out_zip, test_path)! + szip.extract_zip_to_dir(test_out_zip, test_path2)! assert os.exists(fpath1) assert os.exists(fpath2) assert os.exists(fpath3) - assert (os.read_file(fpath1)?) == 'file one' - assert (os.read_file(fpath2)?) == 'file two' - assert (os.read_file(fpath3)?) == 'file three' + assert (os.read_file(fpath1)!) == 'file one' + assert (os.read_file(fpath2)!) == 'file two' + assert (os.read_file(fpath3)!) == 'file three' cleanup() } -fn test_reading_zipping_files() ? { +fn test_reading_zipping_files() { n_files := 2 mut file_name_list := []string{} for i in 0 .. n_files { @@ -81,21 +81,21 @@ fn test_reading_zipping_files() ? { } cleanup() - os.mkdir(test_path)? - os.mkdir(test_path2)? - os.write_file(fpath3, 'file three')? + os.mkdir(test_path)! + os.mkdir(test_path2)! + os.write_file(fpath3, 'file three')! for c, f_name in file_name_list { tmp_path := os.join_path(test_path, f_name) - os.write_file(tmp_path, 'file ${c:02}')? + os.write_file(tmp_path, 'file ${c:02}')! assert os.exists(tmp_path) } - files := (os.ls(test_path)?).map(os.join_path(test_path, it)) + files := (os.ls(test_path)!).map(os.join_path(test_path, it)) - szip.zip_files(files, test_out_zip)? + szip.zip_files(files, test_out_zip)! assert os.exists(test_out_zip) - mut zp := szip.open(test_out_zip, szip.CompressionLevel.no_compression, szip.OpenMode.read_only)? - n_entries := zp.total()? + mut zp := szip.open(test_out_zip, szip.CompressionLevel.no_compression, szip.OpenMode.read_only)! + n_entries := zp.total()! assert n_entries == n_files unsafe { @@ -104,11 +104,11 @@ fn test_reading_zipping_files() ? { buf := malloc(data_len * 2) for _ in 0 .. n_files { - zp.open_entry_by_index(0)? + zp.open_entry_by_index(0)! name := zp.name() assert name in file_name_list - zp.read_entry_buf(buf, buf_size)? + zp.read_entry_buf(buf, buf_size)! buf[data_len] = 0 tmp_str := tos(buf, data_len) @@ -125,50 +125,50 @@ fn test_reading_zipping_files() ? { fn test_zip_folder() { cleanup() - os.mkdir_all(test_path3_1)? - os.mkdir_all(test_path3_2)? - os.mkdir_all(test_path3_3)? - os.mkdir_all(test_path3_4)? - os.write_file(fpath4, '4')? - os.write_file(fpath5, '5')? - os.write_file(fpath6, '6')? - - szip.zip_folder(test_path3, test_dir_zip)? + os.mkdir_all(test_path3_1)! + os.mkdir_all(test_path3_2)! + os.mkdir_all(test_path3_3)! + os.mkdir_all(test_path3_4)! + os.write_file(fpath4, '4')! + os.write_file(fpath5, '5')! + os.write_file(fpath6, '6')! + + szip.zip_folder(test_path3, test_dir_zip)! assert os.exists(test_dir_zip) - os.rmdir_all(test_path3)? - os.mkdir_all(test_path3)? - szip.extract_zip_to_dir(test_dir_zip, test_path3)? + os.rmdir_all(test_path3)! + os.mkdir_all(test_path3)! + szip.extract_zip_to_dir(test_dir_zip, test_path3)! assert os.exists(test_path3_1) assert os.exists(test_path3_2) assert os.exists(test_path3_3) // This is the empty dir assert os.exists(test_path3_4) - assert (os.read_file(fpath4)?) == '4' - assert (os.read_file(fpath5)?) == '5' - assert (os.read_file(fpath6)?) == '6' + assert (os.read_file(fpath4)!) == '4' + assert (os.read_file(fpath5)!) == '5' + assert (os.read_file(fpath6)!) == '6' } fn test_zip_folder_omit_empty_directories() { cleanup() - os.mkdir_all(test_path3_1)? - os.mkdir_all(test_path3_2)? - os.mkdir_all(test_path3_3)? - os.mkdir_all(test_path3_4)? - os.write_file(fpath4, '4')? - os.write_file(fpath5, '5')? - os.write_file(fpath6, '6')? - - szip.zip_folder(test_path3, test_dir_zip, omit_empty_folders: true)? + os.mkdir_all(test_path3_1)! + os.mkdir_all(test_path3_2)! + os.mkdir_all(test_path3_3)! + os.mkdir_all(test_path3_4)! + os.write_file(fpath4, '4')! + os.write_file(fpath5, '5')! + os.write_file(fpath6, '6')! + + szip.zip_folder(test_path3, test_dir_zip, omit_empty_folders: true)! assert os.exists(test_dir_zip) - os.rmdir_all(test_path3)? - os.mkdir_all(test_path3)? - szip.extract_zip_to_dir(test_dir_zip, test_path3)? + os.rmdir_all(test_path3)! + os.mkdir_all(test_path3)! + szip.extract_zip_to_dir(test_dir_zip, test_path3)! assert os.exists(test_path3_1) assert os.exists(test_path3_2) assert !os.exists(test_path3_3) // This is the empty dir, should be omitted with `omit_empty_folders` assert os.exists(test_path3_4) - assert (os.read_file(fpath4)?) == '4' - assert (os.read_file(fpath5)?) == '5' - assert (os.read_file(fpath6)?) == '6' + assert (os.read_file(fpath4)!) == '4' + assert (os.read_file(fpath5)!) == '5' + assert (os.read_file(fpath6)!) == '6' } diff --git a/vlib/toml/ast/walker/walker.v b/vlib/toml/ast/walker/walker.v index 3264dacff..c418a2002 100644 --- a/vlib/toml/ast/walker/walker.v +++ b/vlib/toml/ast/walker/walker.v @@ -4,15 +4,15 @@ import toml.ast // Visitor defines a visit method which is invoked by the walker on each Value node it encounters. pub interface Visitor { - visit(value &ast.Value) ? + visit(value &ast.Value) ! } // Modifier defines a modify method which is invoked by the walker on each Value node it encounters. pub interface Modifier { - modify(mut value ast.Value) ? + modify(mut value ast.Value) ! } -pub type InspectorFn = fn (value &ast.Value, data voidptr) ? +pub type InspectorFn = fn (value &ast.Value, data voidptr) ! struct Inspector { inspector_callback InspectorFn @@ -20,48 +20,48 @@ mut: data voidptr } -pub fn (i &Inspector) visit(value &ast.Value) ? { +pub fn (i &Inspector) visit(value &ast.Value) ! { i.inspector_callback(value, i.data) or { return err } } // inspect traverses and checks the AST Value node on a depth-first order and based on the data given -pub fn inspect(value &ast.Value, data voidptr, inspector_callback InspectorFn) ? { - walk(Inspector{inspector_callback, data}, value)? +pub fn inspect(value &ast.Value, data voidptr, inspector_callback InspectorFn) ! { + walk(Inspector{inspector_callback, data}, value)! } // walk traverses the AST using the given visitor -pub fn walk(visitor Visitor, value &ast.Value) ? { +pub fn walk(visitor Visitor, value &ast.Value) ! { if value is map[string]ast.Value { value_map := value as map[string]ast.Value for _, val in value_map { - walk(visitor, &val)? + walk(visitor, &val)! } } if value is []ast.Value { value_array := value as []ast.Value for val in value_array { - walk(visitor, &val)? + walk(visitor, &val)! } } else { - visitor.visit(value)? + visitor.visit(value)! } } // walk_and_modify traverses the AST using the given modifier and lets the visitor // modify the contents. -pub fn walk_and_modify(modifier Modifier, mut value ast.Value) ? { +pub fn walk_and_modify(modifier Modifier, mut value ast.Value) ! { if value is map[string]ast.Value { mut value_map := value as map[string]ast.Value for _, mut val in value_map { - walk_and_modify(modifier, mut &val)? + walk_and_modify(modifier, mut &val)! } } if value is []ast.Value { mut value_array := value as []ast.Value for mut val in value_array { - walk_and_modify(modifier, mut &val)? + walk_and_modify(modifier, mut &val)! } } else { - modifier.modify(mut value)? + modifier.modify(mut value)! } } diff --git a/vlib/toml/checker/checker.v b/vlib/toml/checker/checker.v index 12ad037e7..d5397e730 100644 --- a/vlib/toml/checker/checker.v +++ b/vlib/toml/checker/checker.v @@ -24,29 +24,29 @@ pub struct Checker { // check checks the `ast.Value` and all it's children // for common errors. -pub fn (c Checker) check(n &ast.Value) ? { - walker.walk(c, n)? +pub fn (c Checker) check(n &ast.Value) ! { + walker.walk(c, n)! } -fn (c Checker) visit(value &ast.Value) ? { +fn (c Checker) visit(value &ast.Value) ! { match value { ast.Bool { - c.check_boolean(value)? + c.check_boolean(value)! } ast.Number { - c.check_number(value)? + c.check_number(value)! } ast.Quoted { - c.check_quoted(value)? + c.check_quoted(value)! } ast.DateTime { - c.check_date_time(value)? + c.check_date_time(value)! } ast.Date { - c.check_date(value)? + c.check_date(value)! } ast.Time { - c.check_time(value)? + c.check_time(value)! } else {} } @@ -81,7 +81,7 @@ fn has_repeating(str string, repeats []rune) bool { } // check_number returns an error if `num` is not a valid TOML number. -fn (c Checker) check_number(num ast.Number) ? { +fn (c Checker) check_number(num ast.Number) ! { lit := num.text lit_lower_case := lit.to_lower() if lit in ['0', '0.0', '+0', '-0', '+0.0', '-0.0', '0e0', '+0e0', '-0e0', '0e00'] { @@ -267,7 +267,7 @@ fn (c Checker) is_valid_hex_literal(num string) bool { } // check_boolean returns an error if `b` is not a valid TOML boolean. -fn (c Checker) check_boolean(b ast.Bool) ? { +fn (c Checker) check_boolean(b ast.Bool) ! { lit := b.text if lit in ['true', 'false'] { return @@ -279,7 +279,7 @@ fn (c Checker) check_boolean(b ast.Bool) ? { // check_date_time returns an error if `dt` is not a valid TOML date-time string (RFC 3339). // See also https://ijmacd.github.io/rfc3339-iso8601 for a more // visual representation of the RFC 3339 format. -fn (c Checker) check_date_time(dt ast.DateTime) ? { +fn (c Checker) check_date_time(dt ast.DateTime) ! { lit := dt.text mut split := []string{} // RFC 3339 Date-Times can be split via 4 separators (` `, `_`, `T` and `t`). @@ -307,7 +307,7 @@ fn (c Checker) check_date_time(dt ast.DateTime) ? { pos: dt.pos.pos col: dt.pos.col } - })? + })! c.check_time(ast.Time{ text: split[1] pos: token.Pos{ @@ -316,7 +316,7 @@ fn (c Checker) check_date_time(dt ast.DateTime) ? { pos: dt.pos.pos + split[0].len col: dt.pos.col + split[0].len } - })? + })! // Use V's builtin functionality to validate the string time.parse_rfc3339(lit) or { return error(@MOD + '.' + @STRUCT + '.' + @FN + @@ -329,7 +329,7 @@ fn (c Checker) check_date_time(dt ast.DateTime) ? { } // check_time returns an error if `date` is not a valid TOML date string (RFC 3339). -fn (c Checker) check_date(date ast.Date) ? { +fn (c Checker) check_date(date ast.Date) ! { lit := date.text parts := lit.split('-') if parts.len != 3 { @@ -359,7 +359,7 @@ fn (c Checker) check_date(date ast.Date) ? { } // check_time returns an error if `t` is not a valid TOML time string (RFC 3339). -fn (c Checker) check_time(t ast.Time) ? { +fn (c Checker) check_time(t ast.Time) ! { lit := t.text // Split any offsets from the time mut offset_splitter := if lit.contains('+') { '+' } else { '-' } @@ -387,7 +387,7 @@ fn (c Checker) check_time(t ast.Time) ? { } // check_quoted returns an error if `q` is not a valid quoted TOML string. -pub fn (c Checker) check_quoted(q ast.Quoted) ? { +pub fn (c Checker) check_quoted(q ast.Quoted) ! { lit := q.text quote := q.quote.ascii_str() triple_quote := quote + quote + quote @@ -395,8 +395,8 @@ pub fn (c Checker) check_quoted(q ast.Quoted) ? { return error(@MOD + '.' + @STRUCT + '.' + @FN + ' string values like "$lit" has unbalanced quote literals `q.quote` in ...${c.excerpt(q.pos)}...') } - c.check_quoted_escapes(q)? - c.check_utf8_validity(q)? + c.check_quoted_escapes(q)! + c.check_utf8_validity(q)! } // check_quoted_escapes returns an error for any disallowed escape sequences. @@ -413,9 +413,9 @@ pub fn (c Checker) check_quoted(q ast.Quoted) ? { // \\ - backslash (U+005C) // \uXXXX - Unicode (U+XXXX) // \UXXXXXXXX - Unicode (U+XXXXXXXX) -fn (c Checker) check_quoted_escapes(q ast.Quoted) ? { +fn (c Checker) check_quoted_escapes(q ast.Quoted) ! { // Setup a scanner in stack memory for easier navigation. - mut s := scanner.new_simple_text(q.text)? + mut s := scanner.new_simple_text(q.text)! // See https://toml.io/en/v1.0.0#string for more info on string types. is_basic := q.quote == `\"` @@ -493,7 +493,7 @@ fn (c Checker) check_quoted_escapes(q ast.Quoted) ? { } // check_utf8_string returns an error if `str` is not valid UTF-8. -fn (c Checker) check_utf8_validity(q ast.Quoted) ? { +fn (c Checker) check_utf8_validity(q ast.Quoted) ! { lit := q.text if !utf8.validate_str(lit) { return error(@MOD + '.' + @STRUCT + '.' + @FN + @@ -504,7 +504,7 @@ fn (c Checker) check_utf8_validity(q ast.Quoted) ? { // validate_utf8_codepoint_string returns an error if `str` is not a valid Unicode code point. // `str` is expected to be a `string` containing *only* hex values. // Any preludes or prefixes like `0x` could pontentially yield wrong results. -fn validate_utf8_codepoint_string(str string) ? { +fn validate_utf8_codepoint_string(str string) ! { int_val := strconv.parse_int(str, 16, 64) or { i64(-1) } if int_val > checker.utf8_max || int_val < 0 { return error('Unicode code point `$str` is outside the valid Unicode scalar value ranges.') @@ -523,7 +523,7 @@ fn validate_utf8_codepoint_string(str string) ? { // check_unicode_escape returns an error if `esc_unicode` is not // a valid Unicode escape sequence. `esc_unicode` is expected to be // prefixed with either `u` or `U`. -fn (c Checker) check_unicode_escape(esc_unicode string) ? { +fn (c Checker) check_unicode_escape(esc_unicode string) ! { if esc_unicode.len < 5 || !esc_unicode.to_lower().starts_with('u') { // Makes sure the input to this function is actually valid. return error('`$esc_unicode` is not a valid escaped Unicode sequence.') @@ -539,7 +539,7 @@ fn (c Checker) check_unicode_escape(esc_unicode string) ? { // if !sequence.is_upper() { // return error('Unicode escape sequence `$esc_unicode` is not in all uppercase.') //} - validate_utf8_codepoint_string(sequence.to_upper())? + validate_utf8_codepoint_string(sequence.to_upper())! if is_long_esc_type { // Long escape type checks } else { @@ -549,10 +549,10 @@ fn (c Checker) check_unicode_escape(esc_unicode string) ? { // check_comment returns an error if the contents of `comment` isn't // a valid TOML comment. -pub fn (c Checker) check_comment(comment ast.Comment) ? { +pub fn (c Checker) check_comment(comment ast.Comment) ! { lit := comment.text // Setup a scanner in stack memory for easier navigation. - mut s := scanner.new_simple_text(lit)? + mut s := scanner.new_simple_text(lit)! for { ch := s.next() if ch == scanner.end_of_text { diff --git a/vlib/toml/decoder/decoder.v b/vlib/toml/decoder/decoder.v index 49609dec3..8d375199e 100644 --- a/vlib/toml/decoder/decoder.v +++ b/vlib/toml/decoder/decoder.v @@ -20,23 +20,23 @@ pub struct Decoder { } // decode decodes certain `ast.Value`'s and all it's children. -pub fn (d Decoder) decode(mut n ast.Value) ? { - walker.walk_and_modify(d, mut n)? +pub fn (d Decoder) decode(mut n ast.Value) ! { + walker.walk_and_modify(d, mut n)! } -fn (d Decoder) modify(mut value ast.Value) ? { +fn (d Decoder) modify(mut value ast.Value) ! { match value { ast.Quoted { mut v := &(value as ast.Quoted) - d.decode_quoted(mut v)? + d.decode_quoted(mut v)! } ast.Number { mut v := &(value as ast.Number) - d.decode_number(mut v)? + d.decode_number(mut v)! } ast.DateTime { mut v := &(value as ast.DateTime) - d.decode_date_time(mut v)? + d.decode_date_time(mut v)! } else {} } @@ -48,12 +48,12 @@ fn (d Decoder) excerpt(tp token.Pos) string { } // decode_quoted returns an error if `q` is not a valid quoted TOML string. -fn (d Decoder) decode_quoted(mut q ast.Quoted) ? { - decode_quoted_escapes(mut q)? +fn (d Decoder) decode_quoted(mut q ast.Quoted) ! { + decode_quoted_escapes(mut q)! } // decode_number decodes the `n ast.Number` into valid TOML. -fn (d Decoder) decode_number(mut n ast.Number) ? { +fn (d Decoder) decode_number(mut n ast.Number) ! { if n.text == '-nan' || n.text == '+nan' { n.text = 'nan' } @@ -73,7 +73,7 @@ fn (d Decoder) decode_number(mut n ast.Number) ? { // \\ - backslash (U+005C) // \uXXXX - Unicode (U+XXXX) // \UXXXXXXXX - Unicode (U+XXXXXXXX) -pub fn decode_quoted_escapes(mut q ast.Quoted) ? { +pub fn decode_quoted_escapes(mut q ast.Quoted) ! { // Setup a scanner in stack memory for easier navigation. mut eat_whitespace := false // TODO use string builder @@ -84,7 +84,7 @@ pub fn decode_quoted_escapes(mut q ast.Quoted) ? { return } - mut s := scanner.new_simple_text(q.text)? + mut s := scanner.new_simple_text(q.text)! q.text = q.text.replace('\\"', '"') for { @@ -214,7 +214,7 @@ pub fn decode_quoted_escapes(mut q ast.Quoted) ? { // The sequence is expected to be prefixed with either `u` or `U`. // decode_unicode_escape returns the decoded rune as // a string, it's integer value and it's length. -fn decode_unicode_escape(esc_unicode string) ?(string, int, int) { +fn decode_unicode_escape(esc_unicode string) !(string, int, int) { is_long_esc_type := esc_unicode.starts_with('U') mut sequence := esc_unicode[1..] hex_digits_len := if is_long_esc_type { 8 } else { 4 } @@ -226,13 +226,13 @@ fn decode_unicode_escape(esc_unicode string) ?(string, int, int) { if unicode_point.len < 8 { unicode_point = '0'.repeat(8 - unicode_point.len) + unicode_point } - i64_val := strconv.parse_int(unicode_point, 16, 0)? + i64_val := strconv.parse_int(unicode_point, 16, 0)! rn := rune(i64_val) return '$rn', int(i64_val), sequence_len } // decode_date_time decodes the `dt ast.DateTime`. -fn (d Decoder) decode_date_time(mut dt ast.DateTime) ? { +fn (d Decoder) decode_date_time(mut dt ast.DateTime) ! { // Expand milliseconds that are only 1 char if dt.text.contains('.') { yymmddhhmmss := dt.text.all_before('.') diff --git a/vlib/toml/input/input.v b/vlib/toml/input/input.v index 8f783ca6c..d15f0581a 100644 --- a/vlib/toml/input/input.v +++ b/vlib/toml/input/input.v @@ -19,7 +19,7 @@ pub: // https://discord.com/channels/592103645835821068/592114487759470596/954101934988615721 [deprecated: 'will be removed and not replaced due to flaky heuristics that leads to hard to find bugs'] [deprecated_after: '2022-06-18'] -pub fn auto_config(toml string) ?Config { +pub fn auto_config(toml string) !Config { mut config := Config{} if !toml.contains('\n') && os.is_file(toml) { config = Config{ @@ -30,13 +30,13 @@ pub fn auto_config(toml string) ?Config { text: toml } } - config.validate()? + config.validate()! return config } // validate returns an optional error if more than one of the fields // in `Config` has a non-default value (empty string). -fn (c Config) validate() ? { +fn (c Config) validate() ! { if c.file_path != '' && c.text != '' { error(@MOD + '.' + @FN + ' ${typeof(c).name} should contain only one of the fields `file_path` OR `text` filled out') @@ -48,8 +48,8 @@ fn (c Config) validate() ? { // read_input returns either Config.text or the read file contents of Config.file_path // depending on which one is not empty. -pub fn (c Config) read_input() ?string { - c.validate()? +pub fn (c Config) read_input() !string { + c.validate()! mut text := c.text if text == '' && os.is_file(c.file_path) { text = os.read_file(c.file_path) or { diff --git a/vlib/toml/parser/parser.v b/vlib/toml/parser/parser.v index b685ecfd5..60d74d44e 100644 --- a/vlib/toml/parser/parser.v +++ b/vlib/toml/parser/parser.v @@ -89,58 +89,58 @@ pub fn new_parser(config Config) Parser { } // init initializes the parser. -pub fn (mut p Parser) init() ? { +pub fn (mut p Parser) init() ! { p.root_map = map[string]ast.Value{} - p.tokens << p.scanner.scan()? - p.next()? + p.tokens << p.scanner.scan()! + p.next()! } // run_checker validates the parsed `ast.Value` nodes in the // the generated AST. -fn (mut p Parser) run_checker() ? { +fn (mut p Parser) run_checker() ! { if p.config.run_checks { chckr := checker.Checker{ scanner: p.scanner } - chckr.check(p.root_map)? + chckr.check(p.root_map)! for comment in p.ast_root.comments { - chckr.check_comment(comment)? + chckr.check_comment(comment)! } } } // run_decoder decodes values in the parsed `ast.Value` nodes in the // the generated AST. -fn (mut p Parser) run_decoder() ? { +fn (mut p Parser) run_decoder() ! { if p.config.decode_values { dcoder := decoder.Decoder{ scanner: p.scanner } - dcoder.decode(mut p.root_map)? + dcoder.decode(mut p.root_map)! } } // parse starts parsing the input and returns the root // of the generated AST. -pub fn (mut p Parser) parse() ?&ast.Root { - p.init()? - p.root_table()? - p.run_checker()? - p.run_decoder()? +pub fn (mut p Parser) parse() !&ast.Root { + p.init()! + p.root_table()! + p.run_checker()! + p.run_decoder()! p.ast_root.table = p.root_map return p.ast_root } // next forwards the parser to the next token. -fn (mut p Parser) next() ? { +fn (mut p Parser) next() ! { p.prev_tok = p.tok p.tok = p.peek_tok if p.tokens.len > 0 { p.peek_tok = p.tokens.first() p.tokens.delete(0) - p.peek(1)? + p.peek(1)! } else { - p.peek(1)? + p.peek(1)! p.peek_tok = p.tokens.first() p.tokens.delete(0) } @@ -148,7 +148,7 @@ fn (mut p Parser) next() ? { // peek peeks forward `n` tokens. // peek returns `.unknown` if it can not peek ahead long enough. -fn (mut p Parser) peek(n int) ?token.Token { +fn (mut p Parser) peek(n int) !token.Token { if n < 0 { return error(@MOD + '.' + @STRUCT + '.' + @FN + ' peeking backwards is not supported.') } @@ -163,7 +163,7 @@ fn (mut p Parser) peek(n int) ?token.Token { mut count := n - p.tokens.len util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'buffering $count tokens...') for token.kind != .eof && count != 0 { - token = p.scanner.scan()? + token = p.scanner.scan()! p.tokens << token count-- } @@ -174,9 +174,9 @@ fn (mut p Parser) peek(n int) ?token.Token { // check forwards the parser to the next token if the current // token's `Kind` is equal that of `check_token`. -fn (mut p Parser) check(check_token token.Kind) ? { +fn (mut p Parser) check(check_token token.Kind) ! { if p.tok.kind == check_token { - p.next()? + p.next()! } else { return error(@MOD + '.' + @STRUCT + '.' + @FN + ' expected token "$check_token" but found "$p.tok.kind" in this (excerpt): "...${p.excerpt()}..."') @@ -185,11 +185,11 @@ fn (mut p Parser) check(check_token token.Kind) ? { // peek_for_correct_line_ending_or_fail peeks past any formatting tokens // and return an error if the next token is not one of [.cr, .nl, .hash, .eof]. -fn (mut p Parser) peek_for_correct_line_ending_or_fail() ? { +fn (mut p Parser) peek_for_correct_line_ending_or_fail() ! { // Disallow anything else than [.cr, .nl, .hash, .eof] after any space formatting. - peek_tok, _ := p.peek_over(1, parser.space_formatting)? + peek_tok, _ := p.peek_over(1, parser.space_formatting)! if peek_tok.kind !in [.cr, .nl, .hash, .eof] { - p.next()? // Forward to the peek_tok + p.next()! // Forward to the peek_tok return error(@MOD + '.' + @STRUCT + '.' + @FN + ' unexpected EOL "$p.tok.kind" "$p.tok.lit" expected one of [.cr, .nl, .hash, .eof] at this (excerpt): "...${p.excerpt()}..."') } @@ -197,9 +197,9 @@ fn (mut p Parser) peek_for_correct_line_ending_or_fail() ? { // check_one_of forwards the parser to the next token if the current // token's `Kind` can be found in `tokens`. Otherwise it returns an error. -fn (mut p Parser) check_one_of(tokens []token.Kind) ? { +fn (mut p Parser) check_one_of(tokens []token.Kind) ! { if p.tok.kind in tokens { - p.next()? + p.next()! } else { return error(@MOD + '.' + @STRUCT + '.' + @FN + ' expected one of $tokens but found "$p.tok.kind" in this (excerpt): "...${p.excerpt()}..."') @@ -232,14 +232,14 @@ fn (mut p Parser) ignore_while_peek(tokens []token.Kind) { // peek_over peeks ahead from token starting at `i` skipping over // any `token.Kind`s found in `tokens`. `peek_over` returns the next token *not* // found in `tokens`. -fn (mut p Parser) peek_over(i int, tokens []token.Kind) ?(token.Token, int) { +fn (mut p Parser) peek_over(i int, tokens []token.Kind) !(token.Token, int) { mut peek_tok := p.peek_tok // Peek ahead as far as we can from token at `i` while the peeked // token is found in `tokens`. mut peek_i := i for peek_tok.kind in tokens { - peek_tok = p.peek(peek_i)? + peek_tok = p.peek(peek_i)! peek_i++ } return peek_tok, peek_i @@ -251,7 +251,7 @@ fn (mut p Parser) is_at(expected_token token.Kind) bool { } // expect will error if the token kind is not equal to `expected_token`. -fn (mut p Parser) expect(expected_token token.Kind) ? { +fn (mut p Parser) expect(expected_token token.Kind) ! { if p.tok.kind == expected_token { return } else { @@ -278,7 +278,7 @@ fn todo_msvc_astring2dkey(s []string) DottedKey { } // check_explicitly_declared returns an error if `key` has been explicitly declared. -fn (p Parser) check_explicitly_declared(key DottedKey) ? { +fn (p Parser) check_explicitly_declared(key DottedKey) ! { if p.explicit_declared.len > 0 && p.explicit_declared.has(key) { return error(@MOD + '.' + @STRUCT + '.' + @FN + ' key `$key.str()` is already explicitly declared. Unexpected redeclaration at "$p.tok.kind" "$p.tok.lit" in this (excerpt): "...${p.excerpt()}..."') @@ -287,7 +287,7 @@ fn (p Parser) check_explicitly_declared(key DottedKey) ? { // check_explicitly_declared_array_of_tables returns an error if `key` has been // explicitly declared as an array of tables. -fn (p Parser) check_explicitly_declared_array_of_tables(key DottedKey) ? { +fn (p Parser) check_explicitly_declared_array_of_tables(key DottedKey) ! { if p.explicit_declared_array_of_tables.len > 0 && p.explicit_declared_array_of_tables.has(key) { return error(@MOD + '.' + @STRUCT + '.' + @FN + ' key `$key.str()` is already an explicitly declared array of tables. Unexpected redeclaration at "$p.tok.kind" "$p.tok.lit" in this (excerpt): "...${p.excerpt()}..."') @@ -295,7 +295,7 @@ fn (p Parser) check_explicitly_declared_array_of_tables(key DottedKey) ? { } // check_implicitly_declared returns an error if `key` has been implicitly declared. -fn (p Parser) check_implicitly_declared(key DottedKey) ? { +fn (p Parser) check_implicitly_declared(key DottedKey) ! { if p.implicit_declared.len > 0 && p.implicit_declared.has(key) { return error(@MOD + '.' + @STRUCT + '.' + @FN + ' key `$key.str()` is already implicitly declared. Unexpected redeclaration at "$p.tok.kind" "$p.tok.lit" in this (excerpt): "...${p.excerpt()}..."') @@ -307,7 +307,7 @@ fn (p Parser) check_implicitly_declared(key DottedKey) ? { // allocate a new map for each segment. This behavior is needed because you can // reference maps by multiple keys "dotted" (separated by "." periods) in TOML documents. // See also `find_in_table`. -pub fn (mut p Parser) find_table() ?&map[string]ast.Value { +pub fn (mut p Parser) find_table() !&map[string]ast.Value { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'locating "$p.root_map_key" in map ${ptr_str(p.root_map)}') mut t := unsafe { &p.root_map } if p.root_map_key.len == 0 { @@ -318,13 +318,13 @@ pub fn (mut p Parser) find_table() ?&map[string]ast.Value { } // allocate_table allocates all tables in "dotted" `key` (`a.b.c`) in the *root* table. -pub fn (mut p Parser) allocate_table(key DottedKey) ? { +pub fn (mut p Parser) allocate_table(key DottedKey) ! { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'allocating "$key" in map ${ptr_str(p.root_map)}') mut t := unsafe { &p.root_map } if key.len == 0 { return } - p.allocate_in_table(mut t, key)? + p.allocate_in_table(mut t, key)! } // sub_table_key returns the logic parts of a dotted key (`a.b.c`) for @@ -340,7 +340,7 @@ pub fn (mut p Parser) sub_table_key(key DottedKey) (DottedKey, DottedKey) { // allocate a new map for the segment. This behavior is needed because you can // reference maps by multiple keys "dotted" (separated by "." periods) in TOML documents. // See also `find_in_table`. -pub fn (mut p Parser) find_sub_table(key DottedKey) ?&map[string]ast.Value { +pub fn (mut p Parser) find_sub_table(key DottedKey) !&map[string]ast.Value { mut ky := DottedKey([]string{}) ky << p.root_map_key ky << key @@ -360,7 +360,7 @@ pub fn (mut p Parser) find_sub_table(key DottedKey) ?&map[string]ast.Value { // If some segments of the key does not exist in the input map find_in_table will // allocate a new map for the segment. This behavior is needed because you can // reference maps by multiple keys "dotted" (separated by "." periods) in TOML documents. -pub fn (mut p Parser) find_in_table(mut table map[string]ast.Value, key DottedKey) ?&map[string]ast.Value { +pub fn (mut p Parser) find_in_table(mut table map[string]ast.Value, key DottedKey) !&map[string]ast.Value { // NOTE This code is the result of much trial and error. // I'm still not quite sure *exactly* why it works. All I can leave here is a hope // that this kind of minefield someday will be easier in V :) @@ -391,7 +391,7 @@ pub fn (mut p Parser) find_in_table(mut table map[string]ast.Value, key DottedKe // find_array_of_tables returns an array if found in the root table based on the parser's // last encountered "Array Of Tables" key. // If the state key does not exist find_array_in_table will return an error. -pub fn (mut p Parser) find_array_of_tables() ?[]ast.Value { +pub fn (mut p Parser) find_array_of_tables() ![]ast.Value { mut t := unsafe { &p.root_map } mut key := p.last_aot if key.len > 1 { @@ -411,7 +411,7 @@ pub fn (mut p Parser) find_array_of_tables() ?[]ast.Value { } // allocate_in_table allocates all tables in "dotted" `key` (`a.b.c`) in `table`. -pub fn (mut p Parser) allocate_in_table(mut table map[string]ast.Value, key DottedKey) ? { +pub fn (mut p Parser) allocate_in_table(mut table map[string]ast.Value, key DottedKey) ! { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'allocating "$key" in map ${ptr_str(table)}') mut t := unsafe { &table } unsafe { @@ -436,33 +436,33 @@ pub fn (mut p Parser) allocate_in_table(mut table map[string]ast.Value, key Dott // dotted_key returns a string of the next tokens parsed as // sub/nested/path keys (e.g. `a.b.c`). In TOML, this form of key is referred to as a "dotted" key. -pub fn (mut p Parser) dotted_key() ?DottedKey { +pub fn (mut p Parser) dotted_key() !DottedKey { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing dotted key...') mut dotted_key := DottedKey([]string{}) - key := p.key()? + key := p.key()! p.ignore_while_peek(parser.space_formatting) dotted_key << key.str() for p.peek_tok.kind == .period { - p.next()? // . - p.check(.period)? + p.next()! // . + p.check(.period)! p.ignore_while(parser.space_formatting) - next_key := p.key()? + next_key := p.key()! dotted_key << next_key.text p.ignore_while_peek(parser.space_formatting) } - p.next()? + p.next()! util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsed dotted key `$dotted_key` now at "$p.tok.kind" "$p.tok.lit"') return dotted_key } // root_table parses next tokens into the root map of `ast.Value`s. // The V `map` type is corresponding to a "table" in TOML. -pub fn (mut p Parser) root_table() ? { +pub fn (mut p Parser) root_table() ! { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing root table...') for p.tok.kind != .eof { if !p.skip_next { - p.next()? + p.next()! } else { p.skip_next = false } @@ -480,10 +480,10 @@ pub fn (mut p Parser) root_table() ? { } .bare, .quoted, .number, .minus, .underscore { // Peek forward as far as we can skipping over space formatting tokens. - peek_tok, _ := p.peek_over(1, parser.keys_and_space_formatting)? + peek_tok, _ := p.peek_over(1, parser.keys_and_space_formatting)! if peek_tok.kind == .period { - dotted_key, val := p.dotted_key_value()? + dotted_key, val := p.dotted_key_value()! sub_table, key := p.sub_table_key(dotted_key) @@ -518,16 +518,16 @@ pub fn (mut p Parser) root_table() ? { p.implicit_declared << abs_dotted_key } - t := p.find_sub_table(sub_table)? + t := p.find_sub_table(sub_table)! unsafe { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'setting "$key" = $val in table ${ptr_str(t)}') t[key.str()] = val } } else { p.ignore_while(parser.space_formatting) - key, val := p.key_value()? + key, val := p.key_value()! - t := p.find_table()? + t := p.find_table()! unsafe { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'setting "$key.str()" = $val in table ${ptr_str(t)}') key_str := key.str() @@ -538,15 +538,15 @@ pub fn (mut p Parser) root_table() ? { t[key_str] = val } } - p.peek_for_correct_line_ending_or_fail()? + p.peek_for_correct_line_ending_or_fail()! } .lsbr { - p.check(.lsbr)? // '[' bracket + p.check(.lsbr)! // '[' bracket mut peek_tok := p.peek_tok // Disallow `[ [table]]` if p.tok.kind in parser.space_formatting { - peek_tok, _ = p.peek_over(1, parser.space_formatting)? + peek_tok, _ = p.peek_over(1, parser.space_formatting)! if peek_tok.kind == .lsbr { return error(@MOD + '.' + @STRUCT + '.' + @FN + ' unexpected "$p.tok.kind" "$p.tok.lit" at this (excerpt): "...${p.excerpt()}..."') @@ -557,18 +557,18 @@ pub fn (mut p Parser) root_table() ? { p.ignore_while(parser.space_formatting) // Peek forward as far as we can skipping over space formatting tokens. - peek_tok, _ = p.peek_over(1, parser.keys_and_space_formatting)? + peek_tok, _ = p.peek_over(1, parser.keys_and_space_formatting)! if p.tok.kind == .lsbr { // Parse `[[table]]` unsafe { - p.array_of_tables(mut &p.root_map)? + p.array_of_tables(mut &p.root_map)! } p.skip_next = true // skip calling p.next() in coming iteration util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'leaving double bracket at "$p.tok.kind" "$p.tok.lit". NEXT is "$p.peek_tok.kind "$p.peek_tok.lit"') } else if peek_tok.kind == .period { // Parse `[d.e.f]` - dotted_key := p.dotted_key()? + dotted_key := p.dotted_key()! // So apparently TOML is a *very* key context sensitive language... // [[table]] <- parsed previously @@ -581,14 +581,14 @@ pub fn (mut p Parser) root_table() ? { if p.last_aot.len == 1 && dotted_key.len > 1 && dotted_key[0] == p.last_aot.str() { // Disallow re-declaring the key - p.check_explicitly_declared_array_of_tables(dotted_key)? - p.check(.rsbr)? + p.check_explicitly_declared_array_of_tables(dotted_key)! + p.check(.rsbr)! p.ignore_while(parser.space_formatting) - arr := p.find_array_of_tables()? + arr := p.find_array_of_tables()! if val := arr[p.last_aot_index] { if val is map[string]ast.Value { mut m := map[string]ast.Value{} - p.table_contents(mut m)? + p.table_contents(mut m)! unsafe { mut mut_val := &val if dotted_key.len == 2 { @@ -600,7 +600,7 @@ pub fn (mut p Parser) root_table() ? { dotted_key_copy.delete(0) new_key := todo_msvc_astring2dkey(dotted_key_copy) sub_table, key := p.sub_table_key(new_key) - t := p.find_in_table(mut mut_val, sub_table)? + t := p.find_in_table(mut mut_val, sub_table)! util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'setting "$key" = $val in table ${ptr_str(t)}') t[new_key.last().str()] = m @@ -615,25 +615,25 @@ pub fn (mut p Parser) root_table() ? { } // Disallow re-declaring the key - p.check_explicitly_declared(dotted_key)? + p.check_explicitly_declared(dotted_key)! p.explicit_declared << dotted_key // ... also check implicitly declared keys - p.check_implicitly_declared(dotted_key)? + p.check_implicitly_declared(dotted_key)! p.ignore_while(parser.space_formatting) util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'setting root map key to `$dotted_key` at "$p.tok.kind" "$p.tok.lit"') p.root_map_key = dotted_key - p.allocate_table(p.root_map_key)? - p.expect(.rsbr)? - p.peek_for_correct_line_ending_or_fail()? + p.allocate_table(p.root_map_key)! + p.expect(.rsbr)! + p.peek_for_correct_line_ending_or_fail()! } else { // Parse `[key]` - key := p.key()? + key := p.key()! dotted_key := DottedKey([key.str()]) // Disallow re-declaring the key - p.check_explicitly_declared(dotted_key)? + p.check_explicitly_declared(dotted_key)! p.explicit_declared << dotted_key // Check for footgun redeclaration in this odd way: @@ -649,10 +649,10 @@ pub fn (mut p Parser) root_table() ? { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'setting root map key to `$dotted_key` at "$p.tok.kind" "$p.tok.lit"') p.root_map_key = dotted_key - p.allocate_table(p.root_map_key)? - p.next()? - p.expect(.rsbr)? - p.peek_for_correct_line_ending_or_fail()? + p.allocate_table(p.root_map_key)! + p.next()! + p.expect(.rsbr)! + p.peek_for_correct_line_ending_or_fail()! } } .eof { @@ -673,7 +673,7 @@ fn (p Parser) excerpt() string { // table_contents parses next tokens into a map of `ast.Value`s. // The V `map` type is corresponding to a "table" in TOML. -pub fn (mut p Parser) table_contents(mut tbl map[string]ast.Value) ? { +pub fn (mut p Parser) table_contents(mut tbl map[string]ast.Value) ! { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing table contents...') for p.tok.kind != .eof { @@ -681,7 +681,7 @@ pub fn (mut p Parser) table_contents(mut tbl map[string]ast.Value) ? { return } if !p.skip_next { - p.next()? + p.next()! } else { p.skip_next = false } @@ -699,21 +699,21 @@ pub fn (mut p Parser) table_contents(mut tbl map[string]ast.Value) ? { } .bare, .quoted, .number, .minus, .underscore { // Peek forward as far as we can skipping over space formatting tokens. - peek_tok, _ := p.peek_over(1, parser.keys_and_space_formatting)? + peek_tok, _ := p.peek_over(1, parser.keys_and_space_formatting)! if peek_tok.kind == .period { - dotted_key, val := p.dotted_key_value()? + dotted_key, val := p.dotted_key_value()! sub_table, key := p.sub_table_key(dotted_key) - t := p.find_in_table(mut tbl, sub_table)? + t := p.find_in_table(mut tbl, sub_table)! unsafe { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'setting "$key" = $val in table ${ptr_str(t)}') t[key.str()] = val } } else { p.ignore_while(parser.space_formatting) - key, val := p.key_value()? + key, val := p.key_value()! unsafe { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'setting "$key.str()" = $val in table ${ptr_str(tbl)}') @@ -725,7 +725,7 @@ pub fn (mut p Parser) table_contents(mut tbl map[string]ast.Value) ? { tbl[key_str] = val } } - p.peek_for_correct_line_ending_or_fail()? + p.peek_for_correct_line_ending_or_fail()! } .eof { break @@ -740,18 +740,18 @@ pub fn (mut p Parser) table_contents(mut tbl map[string]ast.Value) ? { // inline_table parses next tokens into a map of `ast.Value`s. // The V map type is corresponding to a "table" in TOML. -pub fn (mut p Parser) inline_table(mut tbl map[string]ast.Value) ? { +pub fn (mut p Parser) inline_table(mut tbl map[string]ast.Value) ! { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing inline table into ${ptr_str(tbl)}...') mut previous_token_was_value := false for p.tok.kind != .eof { - p.next()? + p.next()! util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing token "$p.tok.kind"') if previous_token_was_value { p.ignore_while(parser.space_formatting) if p.tok.kind != .rcbr { - p.expect(.comma)? + p.expect(.comma)! } previous_token_was_value = false } @@ -769,7 +769,7 @@ pub fn (mut p Parser) inline_table(mut tbl map[string]ast.Value) ? { .comma { p.ignore_while_peek(parser.space_formatting) if p.peek_tok.kind in [.comma, .rcbr] { - p.next()? // Forward to the peek_tok + p.next()! // Forward to the peek_tok return error(@MOD + '.' + @STRUCT + '.' + @FN + ' unexpected "$p.tok.kind" "$p.tok.lit" at this (excerpt): "...${p.excerpt()}..."') } @@ -782,21 +782,21 @@ pub fn (mut p Parser) inline_table(mut tbl map[string]ast.Value) ? { } .bare, .quoted, .number, .minus, .underscore { // Peek forward as far as we can skipping over space formatting tokens. - peek_tok, _ := p.peek_over(1, parser.space_formatting)? + peek_tok, _ := p.peek_over(1, parser.space_formatting)! if peek_tok.kind == .period { - dotted_key, val := p.dotted_key_value()? + dotted_key, val := p.dotted_key_value()! sub_table, key := p.sub_table_key(dotted_key) - mut t := p.find_in_table(mut tbl, sub_table)? + mut t := p.find_in_table(mut tbl, sub_table)! unsafe { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'inserting @6 "$key" = $val into ${ptr_str(t)}') t[key.str()] = val } } else { p.ignore_while(parser.space_formatting) - key, val := p.key_value()? + key, val := p.key_value()! key_str := key.str() if _ := tbl[key_str] { return error(@MOD + '.' + @STRUCT + '.' + @FN + @@ -819,31 +819,31 @@ pub fn (mut p Parser) inline_table(mut tbl map[string]ast.Value) ? { } // array_of_tables parses next tokens into an array of `ast.Value`s. -pub fn (mut p Parser) array_of_tables(mut table map[string]ast.Value) ? { +pub fn (mut p Parser) array_of_tables(mut table map[string]ast.Value) ! { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing array of tables "$p.tok.kind" "$p.tok.lit"') // NOTE this is starting to get ugly. TOML isn't simple at this point - p.check(.lsbr)? // '[' bracket + p.check(.lsbr)! // '[' bracket // Allow [[ key]] p.ignore_while(parser.space_formatting) - peek_tok, _ := p.peek_over(1, parser.space_formatting)? + peek_tok, _ := p.peek_over(1, parser.space_formatting)! p.ignore_while(parser.space_formatting) // [[key.key]] horror if peek_tok.kind == .period { - p.double_array_of_tables(mut table)? + p.double_array_of_tables(mut table)! return } - key := p.key()? - p.next()? + key := p.key()! + p.next()! // Allow [[key ]] p.ignore_while(parser.space_formatting) - p.check(.rsbr)? - p.peek_for_correct_line_ending_or_fail()? - p.expect(.rsbr)? + p.check(.rsbr)! + p.peek_for_correct_line_ending_or_fail()! + p.expect(.rsbr)! p.ignore_while(parser.all_formatting) @@ -851,20 +851,20 @@ pub fn (mut p Parser) array_of_tables(mut table map[string]ast.Value) ? { dotted_key_str := dotted_key.str() // Disallow re-declaring the key - p.check_explicitly_declared(dotted_key)? + p.check_explicitly_declared(dotted_key)! unsafe { if val := table[dotted_key_str] { if val is []ast.Value { arr := &(table[dotted_key_str] as []ast.Value) - arr << p.array_of_tables_contents()? + arr << p.array_of_tables_contents()! table[dotted_key_str] = arr } else { return error(@MOD + '.' + @STRUCT + '.' + @FN + ' table[$dotted_key_str] is not an array. (excerpt): "...${p.excerpt()}..."') } } else { - table[dotted_key_str] = p.array_of_tables_contents()? + table[dotted_key_str] = p.array_of_tables_contents()! } } p.last_aot = dotted_key @@ -876,11 +876,11 @@ pub fn (mut p Parser) array_of_tables(mut table map[string]ast.Value) ? { } // array_of_tables_contents parses next tokens into an array of `ast.Value`s. -pub fn (mut p Parser) array_of_tables_contents() ?[]ast.Value { +pub fn (mut p Parser) array_of_tables_contents() ![]ast.Value { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing contents from "$p.tok.kind" "$p.tok.lit"') mut tbl := map[string]ast.Value{} - p.table_contents(mut tbl)? + p.table_contents(mut tbl)! mut arr := []ast.Value{} arr << tbl @@ -889,14 +889,14 @@ pub fn (mut p Parser) array_of_tables_contents() ?[]ast.Value { } // double_array_of_tables parses next tokens into an array of tables of arrays of `ast.Value`s... -pub fn (mut p Parser) double_array_of_tables(mut table map[string]ast.Value) ? { +pub fn (mut p Parser) double_array_of_tables(mut table map[string]ast.Value) ! { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing nested array of tables "$p.tok.kind" "$p.tok.lit"') - dotted_key := p.dotted_key()? + dotted_key := p.dotted_key()! p.ignore_while(parser.space_formatting) - p.check(.rsbr)? - p.expect(.rsbr)? + p.check(.rsbr)! + p.expect(.rsbr)! p.ignore_while(parser.all_formatting) @@ -905,7 +905,7 @@ pub fn (mut p Parser) double_array_of_tables(mut table map[string]ast.Value) ? { ' nested array of tables does not support more than 2 levels. (excerpt): "...${p.excerpt()}..."') } - p.check_explicitly_declared(dotted_key)? + p.check_explicitly_declared(dotted_key)! if !p.explicit_declared_array_of_tables.has(dotted_key) { p.explicit_declared_array_of_tables << dotted_key @@ -941,7 +941,7 @@ pub fn (mut p Parser) double_array_of_tables(mut table map[string]ast.Value) ? { table[first.str()] = ast.Value(nm) t_arr = &(nm[last.str()] as []ast.Value) - t_arr << p.array_of_tables_contents()? + t_arr << p.array_of_tables_contents()! return } else { return error(@MOD + '.' + @STRUCT + '.' + @FN + @@ -960,14 +960,14 @@ pub fn (mut p Parser) double_array_of_tables(mut table map[string]ast.Value) ? { if val := t[last.str()] { if val is []ast.Value { arr := &(val as []ast.Value) - arr << p.double_array_of_tables_contents(dotted_key)? + arr << p.double_array_of_tables_contents(dotted_key)! t[last.str()] = arr } else { return error(@MOD + '.' + @STRUCT + '.' + @FN + ' t[$last.str()] is not an array. (excerpt): "...${p.excerpt()}..."') } } else { - t[last.str()] = p.double_array_of_tables_contents(dotted_key)? + t[last.str()] = p.double_array_of_tables_contents(dotted_key)! } if t_arr.len == 0 { t_arr << t @@ -977,7 +977,7 @@ pub fn (mut p Parser) double_array_of_tables(mut table map[string]ast.Value) ? { } // double_array_of_tables_contents parses next tokens into an array of `ast.Value`s. -pub fn (mut p Parser) double_array_of_tables_contents(target_key DottedKey) ?[]ast.Value { +pub fn (mut p Parser) double_array_of_tables_contents(target_key DottedKey) ![]ast.Value { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing contents from "$p.tok.kind" "$p.tok.lit"') mut tbl := map[string]ast.Value{} @@ -986,15 +986,15 @@ pub fn (mut p Parser) double_array_of_tables_contents(target_key DottedKey) ?[]a mut peek_tok := p.peek_tok for p.tok.kind != .eof { - p.next()? + p.next()! util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing token "$p.tok.kind"') p.ignore_while(parser.all_formatting) // Peek forward as far as we can skipping over space formatting tokens. - peek_tok, peeked_over = p.peek_over(1, parser.space_formatting)? + peek_tok, peeked_over = p.peek_over(1, parser.space_formatting)! // Peek for occurrence of `[[` if peek_tok.kind == .lsbr { - peek_tok, peeked_over = p.peek_over(peeked_over + 1, parser.space_formatting)? + peek_tok, peeked_over = p.peek_over(peeked_over + 1, parser.space_formatting)! if peek_tok.kind == .lsbr { mut arr := []ast.Value{} arr << tbl @@ -1005,27 +1005,27 @@ pub fn (mut p Parser) double_array_of_tables_contents(target_key DottedKey) ?[]a match p.tok.kind { .bare, .quoted, .number, .minus, .underscore { // Peek forward as far as we can skipping over space formatting tokens. - peek_tok, _ = p.peek_over(1, parser.space_formatting)? + peek_tok, _ = p.peek_over(1, parser.space_formatting)! if peek_tok.kind == .period { - mut dotted_key, val := p.dotted_key_value()? + mut dotted_key, val := p.dotted_key_value()! if implicit_allocation_key.len > 0 { dotted_key.insert(0, implicit_allocation_key) } sub_table, key := p.sub_table_key(dotted_key) - mut t := p.find_in_table(mut tbl, sub_table)? + mut t := p.find_in_table(mut tbl, sub_table)! unsafe { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'inserting @6 "$key" = $val into ${ptr_str(t)}') t[key.str()] = val } } else { - key, val := p.key_value()? + key, val := p.key_value()! mut t := unsafe { &tbl } if implicit_allocation_key.len > 0 { - t = p.find_in_table(mut tbl, implicit_allocation_key)? + t = p.find_in_table(mut tbl, implicit_allocation_key)! } unsafe { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'inserting @7 "$key" = $val into ${ptr_str(t)}') @@ -1034,27 +1034,27 @@ pub fn (mut p Parser) double_array_of_tables_contents(target_key DottedKey) ?[]a } } .lsbr { - p.check(.lsbr)? // '[' bracket + p.check(.lsbr)! // '[' bracket peek_tok = p.peek_tok // Allow `[ d.e.f]` p.ignore_while(parser.space_formatting) // Peek forward as far as we can skipping over space formatting tokens. - peek_tok, _ = p.peek_over(1, parser.space_formatting)? + peek_tok, _ = p.peek_over(1, parser.space_formatting)! if peek_tok.kind == .period { // Parse `[d.e.f]` p.ignore_while(parser.space_formatting) - dotted_key := p.dotted_key()? + dotted_key := p.dotted_key()! implicit_allocation_key = dotted_key if dotted_key.len > 2 { implicit_allocation_key = dotted_key[2..] } p.ignore_while(parser.space_formatting) util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'keys are: dotted `$dotted_key`, target `$target_key`, implicit `$implicit_allocation_key` at "$p.tok.kind" "$p.tok.lit"') - p.expect(.rsbr)? - p.peek_for_correct_line_ending_or_fail()? + p.expect(.rsbr)! + p.peek_for_correct_line_ending_or_fail()! p.explicit_declared << dotted_key continue } else { @@ -1074,26 +1074,26 @@ pub fn (mut p Parser) double_array_of_tables_contents(target_key DottedKey) ?[]a } // array parses next tokens into an array of `ast.Value`s. -pub fn (mut p Parser) array() ?[]ast.Value { +pub fn (mut p Parser) array() ![]ast.Value { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing array...') mut arr := []ast.Value{} - p.expect(.lsbr)? // '[' bracket + p.expect(.lsbr)! // '[' bracket mut previous_token_was_value := false for p.tok.kind != .eof { - p.next()? + p.next()! util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing token "$p.tok.kind" "$p.tok.lit"') if previous_token_was_value { p.ignore_while(parser.all_formatting) if p.tok.kind != .rsbr && p.tok.kind != .hash { - p.expect(.comma)? + p.expect(.comma)! } previous_token_was_value = false } match p.tok.kind { .boolean { - arr << ast.Value(p.boolean()?) + arr << ast.Value(p.boolean()!) previous_token_was_value = true } .comma { @@ -1103,7 +1103,7 @@ pub fn (mut p Parser) array() ?[]ast.Value { // Check for known errors: if p.peek_tok.kind in [.comma, .bare] { - p.next()? // Forward to the peek_tok + p.next()! // Forward to the peek_tok return error(@MOD + '.' + @STRUCT + '.' + @FN + ' unexpected "$p.tok.kind" "$p.tok.lit" at this (excerpt): "...${p.excerpt()}..."') } @@ -1122,12 +1122,12 @@ pub fn (mut p Parser) array() ?[]ast.Value { .lcbr { p.ignore_while(parser.space_formatting) mut t := map[string]ast.Value{} - p.inline_table(mut t)? + p.inline_table(mut t)! arr << ast.Value(t) previous_token_was_value = true } .number { - val := p.number_or_date()? + val := p.number_or_date()! arr << val previous_token_was_value = true } @@ -1137,7 +1137,7 @@ pub fn (mut p Parser) array() ?[]ast.Value { } .lsbr { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing array in array "$p.tok.kind" "$p.tok.lit"') - arr << ast.Value(p.array()?) + arr << ast.Value(p.array()!) previous_token_was_value = true } .rsbr { @@ -1149,7 +1149,7 @@ pub fn (mut p Parser) array() ?[]ast.Value { } } } - p.expect(.rsbr)? // ']' bracket + p.expect(.rsbr)! // ']' bracket $if debug { flat := arr.str().replace('\n', r'\n') util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsed array: $flat . Currently @ token "$p.tok.kind"') @@ -1168,7 +1168,7 @@ pub fn (mut p Parser) comment() ast.Comment { // key parse and returns an `ast.Key` type. // Keys are the token(s) appearing before an assignment operator (=). -pub fn (mut p Parser) key() ?ast.Key { +pub fn (mut p Parser) key() !ast.Key { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing key from "$p.tok.lit" ...') mut key := ast.Key(ast.Null{}) @@ -1177,7 +1177,7 @@ pub fn (mut p Parser) key() ?ast.Key { mut lits := p.tok.lit pos := p.tok.pos() for p.peek_tok.kind != .assign && p.peek_tok.kind != .period && p.peek_tok.kind != .rsbr { - p.next()? + p.next()! if p.tok.kind !in parser.space_formatting { lits += p.tok.lit } @@ -1191,10 +1191,10 @@ pub fn (mut p Parser) key() ?ast.Key { } else { key = match p.tok.kind { .bare, .underscore, .minus { - ast.Key(p.bare()?) + ast.Key(p.bare()!) } .boolean { - ast.Key(p.boolean()?) + ast.Key(p.boolean()!) } .quoted { ast.Key(p.quoted()) @@ -1228,11 +1228,11 @@ pub fn (mut p Parser) key() ?ast.Key { chckr := checker.Checker{ scanner: p.scanner } - chckr.check_quoted(quoted)? + chckr.check_quoted(quoted)! } if p.config.decode_values { mut quoted := key as ast.Quoted - decoder.decode_quoted_escapes(mut quoted)? + decoder.decode_quoted_escapes(mut quoted)! key = ast.Key(quoted) } } @@ -1242,14 +1242,14 @@ pub fn (mut p Parser) key() ?ast.Key { // key_value parse and returns a pair `ast.Key` and `ast.Value` type. // see also `key()` and `value()` -pub fn (mut p Parser) key_value() ?(ast.Key, ast.Value) { +pub fn (mut p Parser) key_value() !(ast.Key, ast.Value) { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing key value pair...') - key := p.key()? - p.next()? + key := p.key()! + p.next()! p.ignore_while(parser.space_formatting) - p.check(.assign)? // Assignment operator + p.check(.assign)! // Assignment operator p.ignore_while(parser.space_formatting) - value := p.value()? + value := p.value()! util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsed key value pair. `$key = $value`') p.explicit_declared << p.build_abs_dotted_key(DottedKey([ @@ -1261,14 +1261,14 @@ pub fn (mut p Parser) key_value() ?(ast.Key, ast.Value) { // dotted_key_value parse and returns a pair `DottedKey` and `ast.Value` type. // see also `key()` and `value()` -pub fn (mut p Parser) dotted_key_value() ?(DottedKey, ast.Value) { +pub fn (mut p Parser) dotted_key_value() !(DottedKey, ast.Value) { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing dotted key value pair...') p.ignore_while(parser.space_formatting) - dotted_key := p.dotted_key()? + dotted_key := p.dotted_key()! p.ignore_while(parser.space_formatting) - p.check(.assign)? + p.check(.assign)! p.ignore_while(parser.space_formatting) - value := p.value()? + value := p.value()! util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsed dotted key value pair `$dotted_key = $value`...') p.explicit_declared << p.build_abs_dotted_key(dotted_key) @@ -1278,12 +1278,12 @@ pub fn (mut p Parser) dotted_key_value() ?(DottedKey, ast.Value) { // value parse and returns an `ast.Value` type. // values are the token(s) appearing after an assignment operator (=). -pub fn (mut p Parser) value() ?ast.Value { +pub fn (mut p Parser) value() !ast.Value { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing value from token "$p.tok.kind" "$p.tok.lit"...') mut value := ast.Value(ast.Null{}) if p.tok.kind == .number { - number_or_date := p.number_or_date()? + number_or_date := p.number_or_date()! value = number_or_date } else { value = match p.tok.kind { @@ -1291,15 +1291,15 @@ pub fn (mut p Parser) value() ?ast.Value { ast.Value(p.quoted()) } .boolean { - ast.Value(p.boolean()?) + ast.Value(p.boolean()!) } .lsbr { - ast.Value(p.array()?) + ast.Value(p.array()!) } .lcbr { p.ignore_while(parser.space_formatting) mut t := map[string]ast.Value{} - p.inline_table(mut t)? + p.inline_table(mut t)! ast.Value(t) } else { @@ -1317,10 +1317,10 @@ pub fn (mut p Parser) value() ?ast.Value { // number_or_date parse and returns an `ast.Value` type as // one of [`ast.Date`, `ast.Time`, `ast.DateTime`, `ast.Number`] -pub fn (mut p Parser) number_or_date() ?ast.Value { +pub fn (mut p Parser) number_or_date() !ast.Value { // Handle Date/Time if p.peek_tok.kind == .minus || p.peek_tok.kind == .colon { - date_time_type := p.date_time()? + date_time_type := p.date_time()! match date_time_type { ast.Date { return ast.Value(date_time_type as ast.Date) @@ -1337,12 +1337,12 @@ pub fn (mut p Parser) number_or_date() ?ast.Value { } // bare parse and returns an `ast.Bare` type. -pub fn (mut p Parser) bare() ?ast.Bare { +pub fn (mut p Parser) bare() !ast.Bare { mut lits := p.tok.lit pos := p.tok.pos() for p.peek_tok.kind != .assign && p.peek_tok.kind != .period && p.peek_tok.kind != .rsbr && p.peek_tok.kind !in parser.space_formatting { - p.next()? + p.next()! if p.tok.kind == .bare || p.tok.kind == .minus || p.tok.kind == .underscore { lits += p.tok.lit continue @@ -1382,7 +1382,7 @@ pub fn (mut p Parser) quoted() ast.Quoted { } // boolean parse and returns an `ast.Bool` type. -pub fn (mut p Parser) boolean() ?ast.Bool { +pub fn (mut p Parser) boolean() !ast.Bool { if p.tok.lit !in ['true', 'false'] { return error(@MOD + '.' + @STRUCT + '.' + @FN + ' expected literal to be either `true` or `false` got "$p.tok.kind"') @@ -1403,7 +1403,7 @@ pub fn (mut p Parser) number() ast.Number { // date_time parses dates and time in RFC 3339 format. // https://datatracker.ietf.org/doc/html/rfc3339 -pub fn (mut p Parser) date_time() ?ast.DateTimeType { +pub fn (mut p Parser) date_time() !ast.DateTimeType { // Date and/or Time mut lit := '' pos := p.tok.pos() @@ -1411,19 +1411,19 @@ pub fn (mut p Parser) date_time() ?ast.DateTimeType { mut time := ast.Time{} if p.peek_tok.kind == .minus { - date = p.date()? + date = p.date()! lit += date.text // Look for any THH:MM:SS or HH:MM:SS if (p.peek_tok.kind == .bare && (p.peek_tok.lit.starts_with('T') || p.peek_tok.lit.starts_with('t'))) || p.peek_tok.kind == .whitespace { - p.next()? // Advance to token with Txx or whitespace special case + p.next()! // Advance to token with Txx or whitespace special case if p.tok.lit.starts_with('T') || p.tok.lit.starts_with('t') { lit += p.tok.lit[0].ascii_str() //'T' or 't' } else { lit += p.tok.lit - p.next()? + p.next()! } - time = p.time()? + time = p.time()! lit += time.text util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsed date-time: "$lit"') @@ -1435,7 +1435,7 @@ pub fn (mut p Parser) date_time() ?ast.DateTimeType { } } } else if p.peek_tok.kind == .colon { - time = p.time()? + time = p.time()! return time } @@ -1446,20 +1446,20 @@ pub fn (mut p Parser) date_time() ?ast.DateTimeType { } // date parse and returns an `ast.Date` type. -pub fn (mut p Parser) date() ?ast.Date { +pub fn (mut p Parser) date() !ast.Date { // Date mut lit := p.tok.lit pos := p.tok.pos() - p.check(.number)? + p.check(.number)! lit += p.tok.lit - p.check(.minus)? + p.check(.minus)! lit += p.tok.lit - p.check(.number)? + p.check(.number)! lit += p.tok.lit - p.check(.minus)? + p.check(.minus)! lit += p.tok.lit - p.expect(.number)? + p.expect(.number)! util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsed date: "$lit"') return ast.Date{ @@ -1469,7 +1469,7 @@ pub fn (mut p Parser) date() ?ast.Date { } // time parse and returns an `ast.Time` type. -pub fn (mut p Parser) time() ?ast.Time { +pub fn (mut p Parser) time() !ast.Time { // Time mut lit := p.tok.lit pos := p.tok.pos() @@ -1480,46 +1480,46 @@ pub fn (mut p Parser) time() ?ast.Time { } else if p.tok.lit.starts_with('t') { lit = lit.all_after('t') } - p.next()? + p.next()! } else { - p.check(.number)? + p.check(.number)! } lit += p.tok.lit - p.check(.colon)? + p.check(.colon)! lit += p.tok.lit - p.check(.number)? + p.check(.number)! lit += p.tok.lit // TODO does TOML even have optional seconds? // if p.peek_tok.kind == .colon { - p.check(.colon)? + p.check(.colon)! lit += p.tok.lit - p.expect(.number)? + p.expect(.number)! //} // Optional milliseconds if p.peek_tok.kind == .period { - p.next()? + p.next()! lit += p.tok.lit // lit += '.' - p.check(.period)? + p.check(.period)! lit += p.tok.lit - p.expect(.number)? + p.expect(.number)! } // Parse offset if p.peek_tok.kind == .minus || p.peek_tok.kind == .plus { - p.next()? + p.next()! lit += p.tok.lit // lit += '-' - p.check_one_of([.minus, .plus])? + p.check_one_of([.minus, .plus])! lit += p.tok.lit - p.check(.number)? + p.check(.number)! lit += p.tok.lit - p.check(.colon)? + p.check(.colon)! lit += p.tok.lit - p.expect(.number)? + p.expect(.number)! } else if p.peek_tok.kind == .bare && (p.peek_tok.lit == 'Z' || p.peek_tok.lit == 'z') { - p.next()? + p.next()! lit += p.tok.lit - p.expect(.bare)? + p.expect(.bare)! } util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsed time: "$lit"') diff --git a/vlib/toml/scanner/scanner.v b/vlib/toml/scanner/scanner.v index 91c05884a..56d3d6178 100644 --- a/vlib/toml/scanner/scanner.v +++ b/vlib/toml/scanner/scanner.v @@ -47,25 +47,25 @@ pub: // new_scanner returns a new *heap* allocated `Scanner` instance, based on the file in config.input.file_path, // or based on the text in config.input.text . -pub fn new_scanner(config Config) ?&Scanner { +pub fn new_scanner(config Config) !&Scanner { mut s := &Scanner{ config: config - text: config.input.read_input()? + text: config.input.read_input()! } return s } // new_simple returns a new *stack* allocated `Scanner` instance. -pub fn new_simple(config Config) ?Scanner { +pub fn new_simple(config Config) !Scanner { return Scanner{ config: config - text: config.input.read_input()? + text: config.input.read_input()! } } // new_simple_text returns a new *stack* allocated `Scanner` instance // ready for parsing TOML in `text`. -pub fn new_simple_text(text string) ?Scanner { +pub fn new_simple_text(text string) !Scanner { in_config := input.Config{ text: text } @@ -74,13 +74,13 @@ pub fn new_simple_text(text string) ?Scanner { } return Scanner{ config: config - text: config.input.read_input()? + text: config.input.read_input()! } } // new_simple_file returns a new *stack* allocated `Scanner` instance // ready for parsing TOML in file read from `path`. -pub fn new_simple_file(path string) ?Scanner { +pub fn new_simple_file(path string) !Scanner { in_config := input.Config{ file_path: path } @@ -89,14 +89,14 @@ pub fn new_simple_file(path string) ?Scanner { } return Scanner{ config: config - text: config.input.read_input()? + text: config.input.read_input()! } } // scan returns the next token from the input. [direct_array_access] -pub fn (mut s Scanner) scan() ?token.Token { - s.validate_and_skip_headers()? +pub fn (mut s Scanner) scan() !token.Token { + s.validate_and_skip_headers()! for { c := s.next() @@ -127,7 +127,7 @@ pub fn (mut s Scanner) scan() ?token.Token { is_signed_inf := !is_signed_nan && is_sign && s.at() == `i` && peek_1 == `n` && peek_2 == `f` if !s.is_left_of_assign && (is_nan || is_inf || is_signed_nan || is_signed_inf) { - num := s.extract_nan_or_inf_number()? + num := s.extract_nan_or_inf_number()! util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'identified a special number "$num" ($num.len)') return s.new_token(.number, num, num.len) } @@ -135,7 +135,7 @@ pub fn (mut s Scanner) scan() ?token.Token { is_signed_number := is_sign && u8(s.at()).is_digit() && !u8(s.peek(-1)).is_digit() is_digit := byte_c.is_digit() if is_digit || is_signed_number { - num := s.extract_number()? + num := s.extract_number()! util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'identified a number "$num" ($num.len)') return s.new_token(.number, num, num.len) } @@ -197,12 +197,12 @@ pub fn (mut s Scanner) scan() ?token.Token { return s.new_token(.assign, ascii, ascii.len) } `"`, `'` { // ... some string "/' - ident_string := s.extract_string()? + ident_string := s.extract_string()! util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'identified quoted string `$ident_string`') return s.new_token(.quoted, ident_string, ident_string.len) } `#` { - hash := s.ignore_line()? + hash := s.ignore_line()! util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'identified comment hash "$hash" ($hash.len)') return s.new_token(.hash, hash, hash.len + 1) } @@ -354,7 +354,7 @@ fn (mut s Scanner) new_token(kind token.Kind, lit string, len int) token.Token { // ignore_line forwards the scanner to the end of the current line. [direct_array_access; inline] -fn (mut s Scanner) ignore_line() ?string { +fn (mut s Scanner) ignore_line() !string { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, ' ignoring until EOL...') start := s.pos for c := s.at(); c != scanner.end_of_text && c != `\n`; c = s.at() { @@ -398,7 +398,7 @@ fn (mut s Scanner) extract_key() string { // any bytes recognized as a TOML string. // TOML strings are everything found between two double or single quotation marks (`"`/`'`). [direct_array_access; inline] -fn (mut s Scanner) extract_string() ?string { +fn (mut s Scanner) extract_string() !string { // extract_string is called when the scanner has already reached // a byte that is the start of a string so we rewind it to start at the correct s.pos-- @@ -410,7 +410,7 @@ fn (mut s Scanner) extract_string() ?string { is_multiline := s.text[s.pos + 1] == quote && s.text[s.pos + 2] == quote // Check for escaped multiline quote if is_multiline { - mls := s.extract_multiline_string()? + mls := s.extract_multiline_string()! return mls } @@ -463,7 +463,7 @@ fn (mut s Scanner) extract_string() ?string { // any bytes recognized as a TOML string. // TOML strings are everything found between two double or single quotation marks (`"`/`'`). [direct_array_access; inline] -fn (mut s Scanner) extract_multiline_string() ?string { +fn (mut s Scanner) extract_multiline_string() !string { // extract_multiline_string is called from extract_string so we know the 3 first // characters is the quotes quote := u8(s.at()) @@ -573,7 +573,7 @@ fn (mut s Scanner) handle_escapes(quote u8, is_multiline bool) (string, int) { // any bytes recognized as a TOML number except for "(+/-)nan" and "(+/-)inf". // TOML numbers can include digits 0-9 and `_`. [direct_array_access; inline] -fn (mut s Scanner) extract_number() ?string { +fn (mut s Scanner) extract_number() !string { // extract_number is called when the scanner has already reached // a byte that is a number or +/- - so we rewind it to start at the correct // position to get the complete number. Even if it's only one digit @@ -611,7 +611,7 @@ fn (mut s Scanner) extract_number() ?string { // extract_nan_or_inf_number collects and returns a string containing // any bytes recognized as infinity or not-a-number TOML numbers. [direct_array_access; inline] -fn (mut s Scanner) extract_nan_or_inf_number() ?string { +fn (mut s Scanner) extract_nan_or_inf_number() !string { // extract_nan_or_inf_number is called when the scanner has already identified that // +/- or 'nan'/'inf' bytes is up but we rewind it to start at the correct position s.pos-- @@ -656,9 +656,9 @@ pub fn (s Scanner) state() State { } } -fn (mut s Scanner) validate_and_skip_headers() ? { +fn (mut s Scanner) validate_and_skip_headers() ! { // UTF-16 / UTF-32 headers (BE/LE) - s.check_utf16_or_32_bom()? + s.check_utf16_or_32_bom()! // NICE-TO-HAVE-TODO Check other types of (UTF-?) headers and yield an error. TOML is UTF-8 only. @@ -670,10 +670,10 @@ fn (mut s Scanner) validate_and_skip_headers() ? { } // Check after we've skipped UTF-8 BOM - s.check_utf16_or_32_bom()? + s.check_utf16_or_32_bom()! } -fn (mut s Scanner) check_utf16_or_32_bom() ? { +fn (mut s Scanner) check_utf16_or_32_bom() ! { if (s.at() == 0xFF && s.peek(1) == 0xFE && s.peek(2) == 0x00 && s.peek(3) == 0x00) || (s.at() == 0x00 && s.peek(1) == 0x00 && s.peek(2) == 0xFE && s.peek(3) == 0xFF) { s.header_len = 4 diff --git a/vlib/toml/tests/alexcrichton.toml-rs-tests_test.v b/vlib/toml/tests/alexcrichton.toml-rs-tests_test.v index 13f43fc9c..abd899dc1 100644 --- a/vlib/toml/tests/alexcrichton.toml-rs-tests_test.v +++ b/vlib/toml/tests/alexcrichton.toml-rs-tests_test.v @@ -54,7 +54,7 @@ def normalize: sorted_walk(if type == "array" then sort else . end); normalize' ) -fn run(args []string) ?string { +fn run(args []string) !string { res := os.execute(args.join(' ')) if res.exit_code != 0 { return error('${args[0]} failed with return code ${res.exit_code}.\n$res.output') @@ -87,7 +87,7 @@ fn test_alexcrichton_toml_rs() { if !hide_oks { println('OK [${i + 1}/$valid_test_files.len] "$valid_test_file"...') } - toml_doc := toml.parse_file(valid_test_file)? + toml_doc := toml.parse_file(valid_test_file)! valid++ } println('$valid/$valid_test_files.len TOML files were parsed correctly') @@ -100,12 +100,12 @@ fn test_alexcrichton_toml_rs() { println('Testing value output of $valid_test_files.len valid TOML files using "$jq"...') if os.exists(compare_work_dir_root) { - os.rmdir_all(compare_work_dir_root)? + os.rmdir_all(compare_work_dir_root)! } - os.mkdir_all(compare_work_dir_root)? + os.mkdir_all(compare_work_dir_root)! jq_normalize_path := os.join_path(compare_work_dir_root, 'normalize.jq') - os.write_file(jq_normalize_path, jq_normalize)? + os.write_file(jq_normalize_path, jq_normalize)! valid = 0 e = 0 @@ -147,19 +147,19 @@ fn test_alexcrichton_toml_rs() { array_type = 2 } - os.write_file(v_toml_json_path, to_alexcrichton(toml_doc.ast.table, array_type))? + os.write_file(v_toml_json_path, to_alexcrichton(toml_doc.ast.table, array_type))! - alexcrichton_json := os.read_file(valid_test_file.all_before_last('.') + '.json')? + alexcrichton_json := os.read_file(valid_test_file.all_before_last('.') + '.json')! - os.write_file(alexcrichton_toml_json_path, alexcrichton_json)? + os.write_file(alexcrichton_toml_json_path, alexcrichton_json)! v_normalized_json := run([jq, '-S', '-f "$jq_normalize_path"', v_toml_json_path]) or { - contents := os.read_file(v_toml_json_path)? + contents := os.read_file(v_toml_json_path)! panic(err.msg() + '\n$contents') } alexcrichton_normalized_json := run([jq, '-S', '-f "$jq_normalize_path"', alexcrichton_toml_json_path]) or { - contents := os.read_file(v_toml_json_path)? + contents := os.read_file(v_toml_json_path)! panic(err.msg() + '\n$contents') } @@ -194,7 +194,7 @@ fn test_alexcrichton_toml_rs() { println('OK [${i + 1}/$invalid_test_files.len] "$invalid_test_file"...') } if toml_doc := toml.parse_file(invalid_test_file) { - content_that_should_have_failed := os.read_file(invalid_test_file)? + content_that_should_have_failed := os.read_file(invalid_test_file)! println(' This TOML should have failed:\n${'-'.repeat(40)}\n$content_that_should_have_failed\n${'-'.repeat(40)}') assert false } else { diff --git a/vlib/toml/tests/array_of_tables_2_level_test.v b/vlib/toml/tests/array_of_tables_2_level_test.v index 5c41074ab..b8fa0a7a2 100644 --- a/vlib/toml/tests/array_of_tables_2_level_test.v +++ b/vlib/toml/tests/array_of_tables_2_level_test.v @@ -25,10 +25,10 @@ name = "Born in the USA" const fprefix = os.join_path(os.dir(@FILE), 'testdata', os.file_name(@FILE).all_before_last('.')) fn test_nested_array_of_tables() { - mut toml_doc := toml.parse_text(toml_text)? + mut toml_doc := toml.parse_text(toml_text)! toml_json := to.json(toml_doc) eprintln(toml_json) - assert toml_json == os.read_file(fprefix + '.out')? + assert toml_json == os.read_file(fprefix + '.out')! } diff --git a/vlib/toml/tests/array_of_tables_edge_case_2_test.v b/vlib/toml/tests/array_of_tables_edge_case_2_test.v index 309b7cfc4..d51c5b87c 100644 --- a/vlib/toml/tests/array_of_tables_edge_case_2_test.v +++ b/vlib/toml/tests/array_of_tables_edge_case_2_test.v @@ -5,11 +5,11 @@ import toml.to const fprefix = os.join_path(os.dir(@FILE), 'testdata', os.file_name(@FILE).all_before_last('.')) fn test_array_of_tables_edge_case_file() { - toml_doc := toml.parse_file(os.real_path(fprefix + '.toml'))? + toml_doc := toml.parse_file(os.real_path(fprefix + '.toml'))! toml_json := to.json(toml_doc) - out_file_json := os.read_file(os.real_path(fprefix + '.out'))? + out_file_json := os.read_file(os.real_path(fprefix + '.out'))! println(toml_json) assert toml_json == out_file_json } diff --git a/vlib/toml/tests/burntsushi.toml-test_test.v b/vlib/toml/tests/burntsushi.toml-test_test.v index e0eaefd8d..61a4e651f 100644 --- a/vlib/toml/tests/burntsushi.toml-test_test.v +++ b/vlib/toml/tests/burntsushi.toml-test_test.v @@ -95,12 +95,12 @@ fn test_burnt_sushi_tomltest() { println('Testing value output of $valid_test_files.len valid TOML files using "$jq"...') if os.exists(compare_work_dir_root) { - os.rmdir_all(compare_work_dir_root)? + os.rmdir_all(compare_work_dir_root)! } - os.mkdir_all(compare_work_dir_root)? + os.mkdir_all(compare_work_dir_root)! jq_normalize_path := os.join_path(compare_work_dir_root, 'normalize.jq') - os.write_file(jq_normalize_path, jq_normalize)? + os.write_file(jq_normalize_path, jq_normalize)! valid = 0 e = 0 @@ -126,25 +126,25 @@ fn test_burnt_sushi_tomltest() { if !hide_oks { println('OK [${i + 1}/$valid_test_files.len] "$valid_test_file"...') } - toml_doc := toml.parse_file(valid_test_file)? + toml_doc := toml.parse_file(valid_test_file)! v_toml_json_path := os.join_path(compare_work_dir_root, os.file_name(valid_test_file).all_before_last('.') + '.v.json') bs_toml_json_path := os.join_path(compare_work_dir_root, os.file_name(valid_test_file).all_before_last('.') + '.json') - os.write_file(v_toml_json_path, to_burntsushi(toml_doc.ast.table))? + os.write_file(v_toml_json_path, to_burntsushi(toml_doc.ast.table))! - bs_json := os.read_file(valid_test_file.all_before_last('.') + '.json')? + bs_json := os.read_file(valid_test_file.all_before_last('.') + '.json')! - os.write_file(bs_toml_json_path, bs_json)? + os.write_file(bs_toml_json_path, bs_json)! v_normalized_json := run([jq, '-S', '-f "$jq_normalize_path"', v_toml_json_path]) or { - contents := os.read_file(v_toml_json_path)? + contents := os.read_file(v_toml_json_path)! panic(err.msg() + '\n$contents') } bs_normalized_json := run([jq, '-S', '-f "$jq_normalize_path"', bs_toml_json_path]) or { - contents := os.read_file(v_toml_json_path)? + contents := os.read_file(v_toml_json_path)! panic(err.msg() + '\n$contents') } @@ -177,7 +177,7 @@ fn test_burnt_sushi_tomltest() { println('OK [${i + 1}/$invalid_test_files.len] "$invalid_test_file"...') } if toml_doc := toml.parse_file(invalid_test_file) { - content_that_should_have_failed := os.read_file(invalid_test_file)? + content_that_should_have_failed := os.read_file(invalid_test_file)! println(' This TOML should have failed:\n${'-'.repeat(40)}\n$content_that_should_have_failed\n${'-'.repeat(40)}') assert false } else { diff --git a/vlib/toml/tests/json_encoding_test.v b/vlib/toml/tests/json_encoding_test.v index 20c7cefdf..8729988d3 100644 --- a/vlib/toml/tests/json_encoding_test.v +++ b/vlib/toml/tests/json_encoding_test.v @@ -5,11 +5,11 @@ import toml.to const fprefix = os.join_path(os.dir(@FILE), 'testdata', os.file_name(@FILE).all_before_last('.')) fn test_parse() { - toml_doc := toml.parse_file(os.real_path(fprefix + '.toml'))? + toml_doc := toml.parse_file(os.real_path(fprefix + '.toml'))! toml_json := to.json(toml_doc) println(toml_json) - out_file_json := os.read_file(os.real_path(fprefix + '.out'))? + out_file_json := os.read_file(os.real_path(fprefix + '.out'))! assert toml_json == out_file_json } diff --git a/vlib/toml/tests/key_test.v b/vlib/toml/tests/key_test.v index 4f0f27d84..ab82eb7a5 100644 --- a/vlib/toml/tests/key_test.v +++ b/vlib/toml/tests/key_test.v @@ -7,7 +7,7 @@ fn path_by_extension(ext string) string { } fn test_keys() { - toml_doc := toml.parse_file(path_by_extension('toml'))? + toml_doc := toml.parse_file(path_by_extension('toml'))! mut value := toml_doc.value('34-11') assert value.int() == 23 @@ -19,7 +19,7 @@ fn test_keys() { assert value.int() == 42 toml_json := to.json(toml_doc) - out_file_json := os.read_file(path_by_extension('out'))? + out_file_json := os.read_file(path_by_extension('out'))! println(toml_json) assert toml_json == out_file_json // @@ -36,9 +36,9 @@ fn test_keys() { } fn test_parse_dotted_key() { - assert toml.parse_dotted_key('')? == [] - assert toml.parse_dotted_key('abc')? == ['abc'] - assert toml.parse_dotted_key('tube.test."test.test".h."i.j."."k"')? == ['tube', 'test', + assert toml.parse_dotted_key('')! == [] + assert toml.parse_dotted_key('abc')! == ['abc'] + assert toml.parse_dotted_key('tube.test."test.test".h."i.j."."k"')! == ['tube', 'test', 'test.test', 'h', 'i.j.', 'k'] if x := toml.parse_dotted_key("'some unclosed string") { assert false diff --git a/vlib/toml/toml.v b/vlib/toml/toml.v index 8abce54e7..5db03511b 100644 --- a/vlib/toml/toml.v +++ b/vlib/toml/toml.v @@ -13,8 +13,8 @@ pub struct Null { } // decode decodes a TOML `string` into the target type `T`. -pub fn decode(toml_txt string) ?T { - doc := parse_text(toml_txt)? +pub fn decode(toml_txt string) !T { + doc := parse_text(toml_txt)! mut typ := T{} typ.from_toml(doc.to_any()) return typ @@ -70,7 +70,7 @@ pub: } // parse_file parses the TOML file in `path`. -pub fn parse_file(path string) ?Doc { +pub fn parse_file(path string) !Doc { input_config := input.Config{ file_path: path } @@ -78,17 +78,17 @@ pub fn parse_file(path string) ?Doc { input: input_config } parser_config := parser.Config{ - scanner: scanner.new_scanner(scanner_config)? + scanner: scanner.new_scanner(scanner_config)! } mut p := parser.new_parser(parser_config) - ast := p.parse()? + ast := p.parse()! return Doc{ ast: ast } } // parse_text parses the TOML document provided in `text`. -pub fn parse_text(text string) ?Doc { +pub fn parse_text(text string) !Doc { input_config := input.Config{ text: text } @@ -96,10 +96,10 @@ pub fn parse_text(text string) ?Doc { input: input_config } parser_config := parser.Config{ - scanner: scanner.new_scanner(scanner_config)? + scanner: scanner.new_scanner(scanner_config)! } mut p := parser.new_parser(parser_config) - ast := p.parse()? + ast := p.parse()! return Doc{ ast: ast } @@ -110,16 +110,16 @@ pub fn parse_text(text string) ?Doc { // For explicit parsing of input types see `parse_file` or `parse_text`. [deprecated: 'use parse_file or parse_text instead'] [deprecated_after: '2022-06-18'] -pub fn parse(toml string) ?Doc { - mut input_config := input.auto_config(toml)? +pub fn parse(toml string) !Doc { + mut input_config := input.auto_config(toml)! scanner_config := scanner.Config{ input: input_config } parser_config := parser.Config{ - scanner: scanner.new_scanner(scanner_config)? + scanner: scanner.new_scanner(scanner_config)! } mut p := parser.new_parser(parser_config) - ast := p.parse()? + ast := p.parse()! return Doc{ ast: ast } @@ -127,7 +127,7 @@ pub fn parse(toml string) ?Doc { // parse_dotted_key converts `key` string to an array of strings. // parse_dotted_key preserves strings delimited by both `"` and `'`. -pub fn parse_dotted_key(key string) ?[]string { +pub fn parse_dotted_key(key string) ![]string { mut out := []string{} mut buf := '' mut in_string := false @@ -207,7 +207,7 @@ pub fn (d Doc) value(key string) Any { pub const null = Any(Null{}) -pub fn (d Doc) value_opt(key string) ?Any { +pub fn (d Doc) value_opt(key string) !Any { key_split := parse_dotted_key(key) or { return error('invalid dotted key') } x := d.value_(d.ast.table, key_split) if x is Null { diff --git a/vlib/v/builder/msvc_windows.v b/vlib/v/builder/msvc_windows.v index 0604624a9..175cb8cfc 100644 --- a/vlib/v/builder/msvc_windows.v +++ b/vlib/v/builder/msvc_windows.v @@ -22,7 +22,7 @@ const ( ) // Given a root key look for one of the subkeys in 'versions' and get the path -fn find_windows_kit_internal(key RegKey, versions []string) ?string { +fn find_windows_kit_internal(key RegKey, versions []string) !string { $if windows { unsafe { for version in versions { @@ -66,7 +66,7 @@ struct WindowsKit { } // Try and find the root key for installed windows kits -fn find_windows_kit_root(target_arch string) ?WindowsKit { +fn find_windows_kit_root(target_arch string) !WindowsKit { $if windows { wkroot := find_windows_kit_root_by_reg(target_arch) or { if wkroot := find_windows_kit_root_by_env(target_arch) { @@ -82,7 +82,7 @@ fn find_windows_kit_root(target_arch string) ?WindowsKit { } // Try to find the root key for installed windows kits from registry -fn find_windows_kit_root_by_reg(target_arch string) ?WindowsKit { +fn find_windows_kit_root_by_reg(target_arch string) !WindowsKit { $if windows { root_key := RegKey(0) path := 'SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots' @@ -104,9 +104,9 @@ fn find_windows_kit_root_by_reg(target_arch string) ?WindowsKit { } } -fn new_windows_kit(kit_root string, target_arch string) ?WindowsKit { +fn new_windows_kit(kit_root string, target_arch string) !WindowsKit { kit_lib := kit_root + 'Lib' - files := os.ls(kit_lib)? + files := os.ls(kit_lib)! mut highest_path := '' mut highest_int := 0 for f in files { @@ -128,7 +128,7 @@ fn new_windows_kit(kit_root string, target_arch string) ?WindowsKit { } } -fn find_windows_kit_root_by_env(target_arch string) ?WindowsKit { +fn find_windows_kit_root_by_env(target_arch string) !WindowsKit { kit_root := os.getenv('WindowsSdkDir') if kit_root == '' { return error('empty WindowsSdkDir') @@ -142,7 +142,7 @@ struct VsInstallation { exe_path string } -fn find_vs(vswhere_dir string, host_arch string, target_arch string) ?VsInstallation { +fn find_vs(vswhere_dir string, host_arch string, target_arch string) !VsInstallation { $if windows { vsinst := find_vs_by_reg(vswhere_dir, host_arch, target_arch) or { if vsinst := find_vs_by_env(host_arch, target_arch) { @@ -156,7 +156,7 @@ fn find_vs(vswhere_dir string, host_arch string, target_arch string) ?VsInstalla } } -fn find_vs_by_reg(vswhere_dir string, host_arch string, target_arch string) ?VsInstallation { +fn find_vs_by_reg(vswhere_dir string, host_arch string, target_arch string) !VsInstallation { $if windows { // Emily: // VSWhere is guaranteed to be installed at this location now @@ -192,7 +192,7 @@ fn find_vs_by_reg(vswhere_dir string, host_arch string, target_arch string) ?VsI } } -fn find_vs_by_env(host_arch string, target_arch string) ?VsInstallation { +fn find_vs_by_env(host_arch string, target_arch string) !VsInstallation { vs_dir := os.getenv('VSINSTALLDIR') if vs_dir == '' { return error('empty VSINSTALLDIR') @@ -214,7 +214,7 @@ fn find_vs_by_env(host_arch string, target_arch string) ?VsInstallation { } } -fn find_msvc(m64_target bool) ?MsvcResult { +fn find_msvc(m64_target bool) !MsvcResult { $if windows { processor_architecture := os.getenv('PROCESSOR_ARCHITECTURE') vswhere_dir := if processor_architecture == 'x86' { diff --git a/vlib/v/checker/tests/array_fancy_sort_err.out b/vlib/v/checker/tests/array_fancy_sort_err.out index 14ffa2140..c11bc8053 100644 --- a/vlib/v/checker/tests/array_fancy_sort_err.out +++ b/vlib/v/checker/tests/array_fancy_sort_err.out @@ -1,6 +1,6 @@ vlib/v/checker/tests/array_fancy_sort_err.vv:6:8: error: `.sort()` can only use ident, index or selector as argument, e.g. `arr.sort(a < b)`, `arr.sort(a.id < b.id)`, `arr.sort(a[0] < b[0])` - 4 | text := os.read_file(os.args[0])? + 4 | text := os.read_file(os.args[0])! 5 | mut lines := text.split_into_lines() 6 | lines.sort(a.split('/').last() < b.split('/').last()) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/vlib/v/checker/tests/array_fancy_sort_err.vv b/vlib/v/checker/tests/array_fancy_sort_err.vv index f2a6ede10..d945cbe42 100644 --- a/vlib/v/checker/tests/array_fancy_sort_err.vv +++ b/vlib/v/checker/tests/array_fancy_sort_err.vv @@ -1,7 +1,7 @@ import os fn main() { - text := os.read_file(os.args[0])? + text := os.read_file(os.args[0])! mut lines := text.split_into_lines() lines.sort(a.split('/').last() < b.split('/').last()) println(lines.join('\n')) diff --git a/vlib/v/checker/tests/fn_call_arg_mismatch_err_c.out b/vlib/v/checker/tests/fn_call_arg_mismatch_err_c.out index 58cff628b..2f71f595e 100644 --- a/vlib/v/checker/tests/fn_call_arg_mismatch_err_c.out +++ b/vlib/v/checker/tests/fn_call_arg_mismatch_err_c.out @@ -1,7 +1,7 @@ -vlib/v/checker/tests/fn_call_arg_mismatch_err_c.vv:13:18: error: `os.chdir(files)?` (no value) used as value in argument 1 to `os.ls` +vlib/v/checker/tests/fn_call_arg_mismatch_err_c.vv:13:18: error: `os.chdir(files)!` (no value) used as value in argument 1 to `os.ls` 11 | println(files) 12 | } else { - 13 | println(os.ls(os.chdir(files)?)?) + 13 | println(os.ls(os.chdir(files)!)!) | ~~~~~~~~~~~~~~~~ 14 | } 15 | println(files) diff --git a/vlib/v/checker/tests/fn_call_arg_mismatch_err_c.vv b/vlib/v/checker/tests/fn_call_arg_mismatch_err_c.vv index 89362384b..8a3c3f73d 100644 --- a/vlib/v/checker/tests/fn_call_arg_mismatch_err_c.vv +++ b/vlib/v/checker/tests/fn_call_arg_mismatch_err_c.vv @@ -2,15 +2,15 @@ module main import os -fn list_files() ?[][]string { - mut unchecked_files := os.ls('utilities/modules')? +fn list_files() ![][]string { + mut unchecked_files := os.ls('utilities/modules')! println(unchecked_files) for files in unchecked_files { println(files) if os.is_file(files) == true { println(files) } else { - println(os.ls(os.chdir(files)?)?) + println(os.ls(os.chdir(files)!)!) } println(files) } diff --git a/vlib/v/checker/tests/for_in_index_optional.out b/vlib/v/checker/tests/for_in_index_optional.out index bbab32abb..ad2939c15 100644 --- a/vlib/v/checker/tests/for_in_index_optional.out +++ b/vlib/v/checker/tests/for_in_index_optional.out @@ -1,4 +1,4 @@ -vlib/v/checker/tests/for_in_index_optional.vv:3:18: error: for in: cannot index `?[]string` +vlib/v/checker/tests/for_in_index_optional.vv:3:18: error: for in: cannot index `![]string` 1 | import os 2 | fn main() { 3 | for file in os.ls('.') { diff --git a/vlib/v/checker/tests/optional_type_call_err.out b/vlib/v/checker/tests/optional_type_call_err.out index 655076574..b4002ca53 100644 --- a/vlib/v/checker/tests/optional_type_call_err.out +++ b/vlib/v/checker/tests/optional_type_call_err.out @@ -1,4 +1,4 @@ -vlib/v/checker/tests/optional_type_call_err.vv:4:5: error: optional type cannot be called directly +vlib/v/checker/tests/optional_type_call_err.vv:4:5: error: result type cannot be called directly 2 | 3 | fn main() { 4 | os.ls('.').filter(it.ends_with('.v')) or { return } diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index e4859fbc1..bf0264ac4 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -4405,10 +4405,14 @@ fn (mut g Gen) return_stmt(node ast.Return) { } } g.write('}') - if fn_return_is_optional || fn_return_is_result { + if fn_return_is_optional { g.writeln(' }, ($c.option_name*)(&$tmpvar), sizeof($styp));') g.write_defer_stmts_when_needed() g.write('return $tmpvar') + } else if fn_return_is_result { + g.writeln(' }, ($c.result_name*)(&$tmpvar), sizeof($styp));') + g.write_defer_stmts_when_needed() + g.write('return $tmpvar') } // Make sure to add our unpacks if multi_unpack.len > 0 { diff --git a/vlib/v/gen/js/sourcemap/mappings.v b/vlib/v/gen/js/sourcemap/mappings.v index 46e04a9f5..ef8cd5f47 100644 --- a/vlib/v/gen/js/sourcemap/mappings.v +++ b/vlib/v/gen/js/sourcemap/mappings.v @@ -77,7 +77,7 @@ fn (mut m Mappings) get_sorted_array() []Mapping { return m.values } -fn (mut m Mappings) export_mappings(mut output io.Writer) ? { +fn (mut m Mappings) export_mappings(mut output io.Writer) ! { mut previous_generated_line := u32(1) mut previous_generated_column := u32(0) mut previous_source_index := i64(0) @@ -109,25 +109,25 @@ fn (mut m Mappings) export_mappings(mut output io.Writer) ? { } } - vlq.encode(i64(mapping.gen_column - previous_generated_column), mut &output)? + vlq.encode(i64(mapping.gen_column - previous_generated_column), mut &output)! previous_generated_column = mapping.gen_column match mapping.source_position { Empty {} SourcePosition { - vlq.encode(i64(mapping.sources_ind - previous_source_index), mut &output)? + vlq.encode(i64(mapping.sources_ind - previous_source_index), mut &output)! previous_source_index = mapping.sources_ind // lines are stored 0-based in SourceMap spec version 3 vlq.encode(i64(mapping.source_position.source_line - 1 - previous_source_line), mut - output)? + output)! previous_source_line = mapping.source_position.source_line - 1 vlq.encode(i64(mapping.source_position.source_column - previous_source_column), mut - output)? + output)! previous_source_column = mapping.source_position.source_column match mapping.names_ind { Empty {} IndexNumber { - vlq.encode(i64(mapping.names_ind - previous_name_index), mut &output)? + vlq.encode(i64(mapping.names_ind - previous_name_index), mut &output)! previous_name_index = mapping.names_ind } } diff --git a/vlib/v/gen/js/sourcemap/source_map.v b/vlib/v/gen/js/sourcemap/source_map.v index 123c500b5..c19c1e886 100644 --- a/vlib/v/gen/js/sourcemap/source_map.v +++ b/vlib/v/gen/js/sourcemap/source_map.v @@ -54,7 +54,7 @@ pub fn (mut sm SourceMap) add_mapping(source_name string, source_position Source } // Add multiple mappings from the same source -pub fn (mut sm SourceMap) add_mapping_list(source_name string, mapping_list []MappingInput) ? { +pub fn (mut sm SourceMap) add_mapping_list(source_name string, mapping_list []MappingInput) ! { if source_name.len == 0 { panic('add_mapping_list, source_name should not be ""') } @@ -129,7 +129,7 @@ pub fn (mut sm SourceMap) to_json() SourceMapJson { return source_map_json } -fn (mut w StringWriter) write(buf []u8) ?int { +fn (mut w StringWriter) write(buf []u8) !int { w.bytes << buf return buf.len } diff --git a/vlib/v/gen/js/sourcemap/vlq/vlq.v b/vlib/v/gen/js/sourcemap/vlq/vlq.v index 4e9289cc3..328d6793e 100644 --- a/vlib/v/gen/js/sourcemap/vlq/vlq.v +++ b/vlib/v/gen/js/sourcemap/vlq/vlq.v @@ -50,7 +50,7 @@ fn decode64(input u8) u8 { // // Note that `i64::MIN = -(2^63)` cannot be represented in that form, and this // NOT IMPLEMENTED: function will return `Error::Overflowed` when attempting to decode it. -pub fn decode(mut input io.Reader) ?i64 { +pub fn decode(mut input io.Reader) !i64 { mut buf := []u8{len: 1} mut accum := u64(0) @@ -90,7 +90,7 @@ fn encode64(input u8) u8 { } // Encode a value as Base64 VLQ, sending it to the writer -pub fn encode(value i64, mut output io.Writer) ? { +pub fn encode(value i64, mut output io.Writer) ! { signed := value < 0 mut value_u64 := abs64(value) << 1 if signed { diff --git a/vlib/v/gen/js/sourcemap/vlq/vlq_decode_test.v b/vlib/v/gen/js/sourcemap/vlq/vlq_decode_test.v index 9ca3201a6..981d19ba8 100644 --- a/vlib/v/gen/js/sourcemap/vlq/vlq_decode_test.v +++ b/vlib/v/gen/js/sourcemap/vlq/vlq_decode_test.v @@ -30,7 +30,7 @@ fn test_decode_a() { for _, test_data in decode_values { mut input := make_test_reader(test_data.decode_val) - res := decode(mut &input)? + res := decode(mut &input)! assert res == test_data.expected } } diff --git a/vlib/v/gen/js/sourcemap/vlq/vlq_encode_test.v b/vlib/v/gen/js/sourcemap/vlq/vlq_encode_test.v index 2313c9525..d73efe4ee 100644 --- a/vlib/v/gen/js/sourcemap/vlq/vlq_encode_test.v +++ b/vlib/v/gen/js/sourcemap/vlq/vlq_encode_test.v @@ -23,13 +23,13 @@ fn test_encode_a() { for _, test_data in decode_values { mut output := TestWriter{} - encode(test_data.data_val, mut &output)? + encode(test_data.data_val, mut &output)! // dump(output.bytes) assert output.bytes == test_data.expected.bytes() } } -fn (mut w TestWriter) write(buf []u8) ?int { +fn (mut w TestWriter) write(buf []u8) !int { w.bytes << buf return buf.len } diff --git a/vlib/v/scanner/scanner.v b/vlib/v/scanner/scanner.v index d30daf56b..6ca719bd3 100644 --- a/vlib/v/scanner/scanner.v +++ b/vlib/v/scanner/scanner.v @@ -106,7 +106,7 @@ pub enum CommentsMode { } // new scanner from file. -pub fn new_scanner_file(file_path string, comments_mode CommentsMode, pref &pref.Preferences) ?&Scanner { +pub fn new_scanner_file(file_path string, comments_mode CommentsMode, pref &pref.Preferences) !&Scanner { if !os.is_file(file_path) { return error('$file_path is not a .v file') } diff --git a/vlib/v/tests/repl/runner/runner.v b/vlib/v/tests/repl/runner/runner.v index 6710694ae..4195c6c52 100644 --- a/vlib/v/tests/repl/runner/runner.v +++ b/vlib/v/tests/repl/runner/runner.v @@ -39,7 +39,7 @@ fn diff_files(file_result string, file_expected string) string { return diff.color_compare_files(diffcmd, file_result, file_expected) } -pub fn run_repl_file(wd string, vexec string, file string) ?string { +pub fn run_repl_file(wd string, vexec string, file string) !string { vexec_folder := os.dir(vexec) + os.path_separator fcontent := os.read_file(file) or { return error('Could not read repl file $file') } content := fcontent.replace('\r', '') @@ -52,7 +52,7 @@ pub fn run_repl_file(wd string, vexec string, file string) ?string { rcmd := '${os.quoted_path(vexec)} repl -replfolder ${os.quoted_path(wd)} -replprefix "${fname}." < ${os.quoted_path(input_temporary_filename)}' r := os.execute(rcmd) if r.exit_code != 0 { - os.rm(input_temporary_filename)? + os.rm(input_temporary_filename)! return error('Could not execute: $rcmd') } result := r.output.replace('\r', '').replace('>>> ', '').replace('>>>', '').replace('... ', @@ -63,7 +63,7 @@ pub fn run_repl_file(wd string, vexec string, file string) ?string { dump(r.output) dump(result) } - os.rm(input_temporary_filename)? + os.rm(input_temporary_filename)! if result != output { file_result := '${file}.result.txt' file_expected := '${file}.expected.txt' @@ -83,7 +83,7 @@ $diff } } -pub fn run_prod_file(wd string, vexec string, file string) ?string { +pub fn run_prod_file(wd string, vexec string, file string) !string { file_expected := '${file}.expected.txt' f_expected_content := os.read_file(file_expected) or { return error('Could not read expected prod file $file_expected') diff --git a/vlib/v/tests/repl/void_vlib_fncall.repl b/vlib/v/tests/repl/void_vlib_fncall.repl index 039eadcbf..77288ac5a 100644 --- a/vlib/v/tests/repl/void_vlib_fncall.repl +++ b/vlib/v/tests/repl/void_vlib_fncall.repl @@ -1,3 +1,3 @@ -os.write_file('hi','hi')? -os.rm('hi')? +os.write_file('hi','hi')! +os.rm('hi')! ===output=== diff --git a/vlib/v/tests/websocket_logger_interface_should_compile_test.v b/vlib/v/tests/websocket_logger_interface_should_compile_test.v index fca808540..d7b08c209 100644 --- a/vlib/v/tests/websocket_logger_interface_should_compile_test.v +++ b/vlib/v/tests/websocket_logger_interface_should_compile_test.v @@ -25,30 +25,30 @@ fn (wst WsTransport) wait() { println('wait is called') } -pub fn new_ws_client(transport Transport) ?WsClient { +pub fn new_ws_client(transport Transport) !WsClient { return WsClient{ transport: transport } } -fn server() ? { +fn server() ! { mut s := ws.new_server(.ip6, 8081, '/') - s.on_connect(fn (mut s ws.ServerClient) ?bool { + s.on_connect(fn (mut s ws.ServerClient) !bool { if s.resource_name != '/' { return false } println('Client has connected...') return true - })? + })! - s.on_message(fn (mut ws ws.Client, msg &RawMessage) ? { + s.on_message(fn (mut ws ws.Client, msg &RawMessage) ! { mut transport := WsTransport{} - mut ws_client := new_ws_client(transport)? + mut ws_client := new_ws_client(transport)! _ := ws_client }) - s.on_close(fn (mut ws ws.Client, code int, reason string) ? { + s.on_close(fn (mut ws ws.Client, code int, reason string) ! { println('client ($ws.id) closed connection') }) @@ -59,8 +59,8 @@ fn server() ? { } } -fn abc() ? { - server()? +fn abc() ! { + server()! } fn test_compilation_of_the_example_code_in_issue_15839() { diff --git a/vlib/v/vcache/vcache.v b/vlib/v/vcache/vcache.v index abcbe9671..6b34412b5 100644 --- a/vlib/v/vcache/vcache.v +++ b/vlib/v/vcache/vcache.v @@ -117,7 +117,7 @@ pub fn (mut cm CacheManager) mod_postfix_with_key2cpath(mod string, postfix stri return res } -pub fn (mut cm CacheManager) exists(postfix string, key string) ?string { +pub fn (mut cm CacheManager) exists(postfix string, key string) !string { fpath := cm.postfix_with_key2cpath(postfix, key) dlog(@FN, 'postfix: $postfix | key: $key | fpath: $fpath') if !os.exists(fpath) { @@ -126,7 +126,7 @@ pub fn (mut cm CacheManager) exists(postfix string, key string) ?string { return fpath } -pub fn (mut cm CacheManager) mod_exists(mod string, postfix string, key string) ?string { +pub fn (mut cm CacheManager) mod_exists(mod string, postfix string, key string) !string { fpath := cm.mod_postfix_with_key2cpath(mod, postfix, key) dlog(@FN, 'mod: $mod | postfix: $postfix | key: $key | fpath: $fpath') if !os.exists(fpath) { @@ -137,32 +137,32 @@ pub fn (mut cm CacheManager) mod_exists(mod string, postfix string, key string) // -pub fn (mut cm CacheManager) save(postfix string, key string, content string) ?string { +pub fn (mut cm CacheManager) save(postfix string, key string, content string) !string { fpath := cm.postfix_with_key2cpath(postfix, key) - os.write_file(fpath, content)? + os.write_file(fpath, content)! dlog(@FN, 'postfix: $postfix | key: $key | fpath: $fpath') return fpath } -pub fn (mut cm CacheManager) mod_save(mod string, postfix string, key string, content string) ?string { +pub fn (mut cm CacheManager) mod_save(mod string, postfix string, key string, content string) !string { fpath := cm.mod_postfix_with_key2cpath(mod, postfix, key) - os.write_file(fpath, content)? + os.write_file(fpath, content)! dlog(@FN, 'mod: $mod | postfix: $postfix | key: $key | fpath: $fpath') return fpath } // -pub fn (mut cm CacheManager) load(postfix string, key string) ?string { - fpath := cm.exists(postfix, key)? - content := os.read_file(fpath)? +pub fn (mut cm CacheManager) load(postfix string, key string) !string { + fpath := cm.exists(postfix, key)! + content := os.read_file(fpath)! dlog(@FN, 'postfix: $postfix | key: $key | fpath: $fpath') return content } -pub fn (mut cm CacheManager) mod_load(mod string, postfix string, key string) ?string { - fpath := cm.mod_exists(mod, postfix, key)? - content := os.read_file(fpath)? +pub fn (mut cm CacheManager) mod_load(mod string, postfix string, key string) !string { + fpath := cm.mod_exists(mod, postfix, key)! + content := os.read_file(fpath)! dlog(@FN, 'mod: $mod | postfix: $postfix | key: $key | fpath: $fpath') return content } diff --git a/vlib/vweb/parse.v b/vlib/vweb/parse.v index 84d18d461..aa9662ab1 100644 --- a/vlib/vweb/parse.v +++ b/vlib/vweb/parse.v @@ -4,7 +4,7 @@ import net.urllib import net.http // Parsing function attributes for methods and path. -fn parse_attrs(name string, attrs []string) ?([]http.Method, string) { +fn parse_attrs(name string, attrs []string) !([]http.Method, string) { if attrs.len == 0 { return [http.Method.get], '/$name' } @@ -55,7 +55,7 @@ fn parse_query_from_url(url urllib.URL) map[string]string { return query } -fn parse_form_from_request(request http.Request) ?(map[string]string, map[string][]http.FileData) { +fn parse_form_from_request(request http.Request) !(map[string]string, map[string][]http.FileData) { mut form := map[string]string{} mut files := map[string][]http.FileData{} if request.method in methods_with_form { diff --git a/vlib/vweb/sse/sse.v b/vlib/vweb/sse/sse.v index 18fb8e4e7..9efb1ce19 100644 --- a/vlib/vweb/sse/sse.v +++ b/vlib/vweb/sse/sse.v @@ -42,7 +42,7 @@ pub fn new_connection(conn &net.TcpConn) &SSEConnection { } // sse_start is used to send the start of a Server Side Event response. -pub fn (mut sse SSEConnection) start() ? { +pub fn (mut sse SSEConnection) start() ! { sse.conn.set_write_timeout(sse.write_timeout) mut start_sb := strings.new_builder(512) start_sb.write_string('HTTP/1.1 200') @@ -58,7 +58,7 @@ pub fn (mut sse SSEConnection) start() ? { // send_message sends a single message to the http client that listens for SSE. // It does not close the connection, so you can use it many times in a loop. -pub fn (mut sse SSEConnection) send_message(message SSEMessage) ? { +pub fn (mut sse SSEConnection) send_message(message SSEMessage) ! { mut sb := strings.new_builder(512) if message.id != '' { sb.write_string('id: $message.id\n') @@ -73,5 +73,5 @@ pub fn (mut sse SSEConnection) send_message(message SSEMessage) ? { sb.write_string('retry: $message.retry\n') } sb.write_string('\n') - sse.conn.write(sb)? + sse.conn.write(sb)! } diff --git a/vlib/vweb/vweb.v b/vlib/vweb/vweb.v index 04693d356..16100a89b 100644 --- a/vlib/vweb/vweb.v +++ b/vlib/vweb/vweb.v @@ -331,7 +331,7 @@ pub fn (mut ctx Context) set_cookie_with_expire_date(key string, val string, exp } // Gets a cookie by a key -pub fn (ctx &Context) get_cookie(key string) ?string { // TODO refactor +pub fn (ctx &Context) get_cookie(key string) !string { // TODO refactor mut cookie_header := ctx.get_header('cookie') if cookie_header == '' { cookie_header = ctx.get_header('Cookie') @@ -391,7 +391,7 @@ pub struct RunParams { // run_at - start a new VWeb server, listening only on a specific address `host`, at the specified `port` // Example: vweb.run_at(new_app(), vweb.RunParams{ host: 'localhost' port: 8099 family: .ip }) or { panic(err) } [manualfree] -pub fn run_at(global_app &T, params RunParams) ? { +pub fn run_at(global_app &T, params RunParams) ! { if params.port <= 0 || params.port > 65535 { return error('invalid port number `$params.port`, it should be between 1 and 65535') } @@ -714,11 +714,11 @@ pub fn not_found() Result { return Result{} } -fn send_string(mut conn net.TcpConn, s string) ? { +fn send_string(mut conn net.TcpConn, s string) ! { $if trace_response ? { eprintln('> send_string:\n$s\n') } - conn.write(s.bytes())? + conn.write(s.bytes())! } // Do not delete. diff --git a/vlib/x/json2/decoder.v b/vlib/x/json2/decoder.v index a80faa19b..472cdb917 100644 --- a/vlib/x/json2/decoder.v +++ b/vlib/x/json2/decoder.v @@ -101,7 +101,7 @@ fn (mut p Parser) next() { p.n_tok = p.scanner.scan() } -fn (mut p Parser) next_with_err() ? { +fn (mut p Parser) next_with_err() ! { p.next() if p.tok.kind == .error { return IError(DecodeError{ @@ -140,10 +140,10 @@ fn new_parser(srce string, convert_type bool) Parser { } } -fn (mut p Parser) decode() ?Any { +fn (mut p Parser) decode() !Any { p.next() - p.next_with_err()? - fi := p.decode_value()? + p.next_with_err()! + fi := p.decode_value()! if p.tok.kind != .eof { return IError(InvalidTokenError{ token: p.tok @@ -152,7 +152,7 @@ fn (mut p Parser) decode() ?Any { return fi } -fn (mut p Parser) decode_value() ?Any { +fn (mut p Parser) decode_value() !Any { if p.n_level + 1 == 500 { return IError(DecodeError{ message: 'reached maximum nesting level of 500' @@ -168,7 +168,7 @@ fn (mut p Parser) decode_value() ?Any { .int_, .float { tl := p.tok.lit.bytestr() kind := p.tok.kind - p.next_with_err()? + p.next_with_err()! if p.convert_type { $if !nofloat ? { if kind == .float { @@ -181,14 +181,14 @@ fn (mut p Parser) decode_value() ?Any { } .bool_ { lit := p.tok.lit.bytestr() - p.next_with_err()? + p.next_with_err()! if p.convert_type { return Any(lit.bool()) } return Any(lit) } .null { - p.next_with_err()? + p.next_with_err()! if p.convert_type { return Any(null) } @@ -196,7 +196,7 @@ fn (mut p Parser) decode_value() ?Any { } .str_ { str := p.tok.lit.bytestr() - p.next_with_err()? + p.next_with_err()! return Any(str) } else { @@ -209,15 +209,15 @@ fn (mut p Parser) decode_value() ?Any { } [manualfree] -fn (mut p Parser) decode_array() ?Any { +fn (mut p Parser) decode_array() !Any { mut items := []Any{} - p.next_with_err()? + p.next_with_err()! p.n_level++ for p.tok.kind != .rsbr { - item := p.decode_value()? + item := p.decode_value()! items << item if p.tok.kind == .comma { - p.next_with_err()? + p.next_with_err()! if p.tok.kind == .rsbr { return IError(InvalidTokenError{ token: p.tok @@ -230,14 +230,14 @@ fn (mut p Parser) decode_array() ?Any { }) } } - p.next_with_err()? + p.next_with_err()! p.n_level-- return Any(items) } -fn (mut p Parser) decode_object() ?Any { +fn (mut p Parser) decode_object() !Any { mut fields := map[string]Any{} - p.next_with_err()? + p.next_with_err()! p.n_level++ for p.tok.kind != .rcbr { if p.tok.kind != .str_ { @@ -248,7 +248,7 @@ fn (mut p Parser) decode_object() ?Any { } cur_key := p.tok.lit.bytestr() - p.next_with_err()? + p.next_with_err()! if p.tok.kind != .colon { return IError(InvalidTokenError{ token: p.tok @@ -256,18 +256,18 @@ fn (mut p Parser) decode_object() ?Any { }) } - p.next_with_err()? - fields[cur_key] = p.decode_value()? + p.next_with_err()! + fields[cur_key] = p.decode_value()! if p.tok.kind != .comma && p.tok.kind != .rcbr { return IError(UnknownTokenError{ token: p.tok kind: .object }) } else if p.tok.kind == .comma { - p.next_with_err()? + p.next_with_err()! } } - p.next_with_err()? + p.next_with_err()! p.n_level-- return Any(fields) } diff --git a/vlib/x/json2/decoder_test.v b/vlib/x/json2/decoder_test.v index 6d7e02f29..9c3de2965 100644 --- a/vlib/x/json2/decoder_test.v +++ b/vlib/x/json2/decoder_test.v @@ -1,43 +1,43 @@ module json2 fn test_raw_decode_string() { - str := raw_decode('"Hello!"')? + str := raw_decode('"Hello!"')! assert str.str() == 'Hello!' } fn test_raw_decode_string_escape() { - jstr := raw_decode('"\u001b"')? + jstr := raw_decode('"\u001b"')! str := jstr.str() assert str.len == 1 assert str[0] == 27 } fn test_raw_decode_number() { - num := raw_decode('123')? + num := raw_decode('123')! assert num.int() == 123 } fn test_raw_decode_array() { - raw_arr := raw_decode('["Foo", 1]')? + raw_arr := raw_decode('["Foo", 1]')! arr := raw_arr.arr() assert arr[0] or { 0 }.str() == 'Foo' assert arr[1] or { 0 }.int() == 1 } fn test_raw_decode_bool() { - bol := raw_decode('false')? + bol := raw_decode('false')! assert bol.bool() == false } fn test_raw_decode_map() { - raw_mp := raw_decode('{"name":"Bob","age":20}')? + raw_mp := raw_decode('{"name":"Bob","age":20}')! mp := raw_mp.as_map() assert mp['name'] or { 0 }.str() == 'Bob' assert mp['age'] or { 0 }.int() == 20 } fn test_raw_decode_null() { - nul := raw_decode('null')? + nul := raw_decode('null')! assert nul is Null } @@ -50,12 +50,12 @@ fn test_raw_decode_invalid() { } fn test_raw_decode_string_with_dollarsign() { - str := raw_decode(r'"Hello $world"')? + str := raw_decode(r'"Hello $world"')! assert str.str() == r'Hello $world' } fn test_raw_decode_map_with_whitespaces() { - raw_mp := raw_decode(' \n\t{"name":"Bob","age":20}\n\t')? + raw_mp := raw_decode(' \n\t{"name":"Bob","age":20}\n\t')! mp := raw_mp.as_map() assert mp['name'] or { 0 }.str() == 'Bob' assert mp['age'] or { 0 }.int() == 20 @@ -63,7 +63,7 @@ fn test_raw_decode_map_with_whitespaces() { fn test_nested_array_object() { mut parser := new_parser(r'[[[[[],[],[]]]],{"Test":{}},[[]]]', false) - decoded := parser.decode()? + decoded := parser.decode()! assert parser.n_level == 0 } diff --git a/vlib/x/json2/encoder.v b/vlib/x/json2/encoder.v index 4569e565f..1b902f4eb 100644 --- a/vlib/x/json2/encoder.v +++ b/vlib/x/json2/encoder.v @@ -38,78 +38,78 @@ const escaped_chars = [(r'\b').bytes(), (r'\f').bytes(), (r'\n').bytes(), (r'\r').bytes(), (r'\t').bytes()] // encode_value encodes an `Any` value to the specific writer. -pub fn (e &Encoder) encode_value(f Any, mut wr io.Writer) ? { - e.encode_value_with_level(f, 1, mut wr)? +pub fn (e &Encoder) encode_value(f Any, mut wr io.Writer) ! { + e.encode_value_with_level(f, 1, mut wr)! } -fn (e &Encoder) encode_newline(level int, mut wr io.Writer) ? { +fn (e &Encoder) encode_newline(level int, mut wr io.Writer) ! { if e.newline != 0 { - wr.write([e.newline])? + wr.write([e.newline])! for j := 0; j < level * e.newline_spaces_count; j++ { - wr.write(json2.space_bytes)? + wr.write(json2.space_bytes)! } } } -fn (e &Encoder) encode_value_with_level(f Any, level int, mut wr io.Writer) ? { +fn (e &Encoder) encode_value_with_level(f Any, level int, mut wr io.Writer) ! { match f { string { - e.encode_string(f, mut wr)? + e.encode_string(f, mut wr)! } bool { if f == true { - wr.write(json2.true_in_bytes)? + wr.write(json2.true_in_bytes)! } else { - wr.write(json2.false_in_bytes)? + wr.write(json2.false_in_bytes)! } } int, u64, i64 { - wr.write(f.str().bytes())? + wr.write(f.str().bytes())! } f32, f64 { $if !nofloat ? { str_float := f.str().bytes() - wr.write(str_float)? + wr.write(str_float)! if str_float[str_float.len - 1] == `.` { - wr.write(json2.zero_in_bytes)? + wr.write(json2.zero_in_bytes)! } return } - wr.write(json2.zero_in_bytes)? + wr.write(json2.zero_in_bytes)! } map[string]Any { - wr.write([u8(`{`)])? + wr.write([u8(`{`)])! mut i := 0 for k, v in f { - e.encode_newline(level, mut wr)? - e.encode_string(k, mut wr)? - wr.write(json2.colon_bytes)? + e.encode_newline(level, mut wr)! + e.encode_string(k, mut wr)! + wr.write(json2.colon_bytes)! if e.newline != 0 { - wr.write(json2.space_bytes)? + wr.write(json2.space_bytes)! } - e.encode_value_with_level(v, level + 1, mut wr)? + e.encode_value_with_level(v, level + 1, mut wr)! if i < f.len - 1 { - wr.write(json2.comma_bytes)? + wr.write(json2.comma_bytes)! } i++ } - e.encode_newline(level - 1, mut wr)? - wr.write([u8(`}`)])? + e.encode_newline(level - 1, mut wr)! + wr.write([u8(`}`)])! } []Any { - wr.write([u8(`[`)])? + wr.write([u8(`[`)])! for i, v in f { - e.encode_newline(level, mut wr)? - e.encode_value_with_level(v, level + 1, mut wr)? + e.encode_newline(level, mut wr)! + e.encode_value_with_level(v, level + 1, mut wr)! if i < f.len - 1 { - wr.write(json2.comma_bytes)? + wr.write(json2.comma_bytes)! } } - e.encode_newline(level - 1, mut wr)? - wr.write([u8(`]`)])? + e.encode_newline(level - 1, mut wr)! + wr.write([u8(`]`)])! } Null { - wr.write(json2.null_in_bytes)? + wr.write(json2.null_in_bytes)! } } } @@ -190,47 +190,47 @@ fn (mut iter CharLengthIterator) next() ?int { // encode_string returns the JSON spec-compliant version of the string. [manualfree] -fn (e &Encoder) encode_string(s string, mut wr io.Writer) ? { +fn (e &Encoder) encode_string(s string, mut wr io.Writer) ! { mut char_lens := CharLengthIterator{ text: s } mut i := 0 - wr.write(json2.quote_bytes)? + wr.write(json2.quote_bytes)! for char_len in char_lens { if char_len == 1 { chr := s[i] if chr in important_escapable_chars { for j := 0; j < important_escapable_chars.len; j++ { if chr == important_escapable_chars[j] { - wr.write(json2.escaped_chars[j])? + wr.write(json2.escaped_chars[j])! break } } } else if chr == `"` || chr == `/` || chr == `\\` { - wr.write([u8(`\\`), chr])? + wr.write([u8(`\\`), chr])! } else if int(chr) < 0x20 { hex_code := chr.hex().bytes() - wr.write(json2.unicode_escape_chars)? // \u - wr.write(json2.zero_in_bytes)? // \u0 - wr.write(json2.zero_in_bytes)? // \u00 - wr.write(hex_code)? // \u00xxxx + wr.write(json2.unicode_escape_chars)! // \u + wr.write(json2.zero_in_bytes)! // \u0 + wr.write(json2.zero_in_bytes)! // \u00 + wr.write(hex_code)! // \u00xxxx } else { - wr.write([u8(chr)])? + wr.write([u8(chr)])! } } else { slice := s[i..i + char_len] hex_code := slice.utf32_code().hex().bytes() if !e.escape_unicode || hex_code.len < 4 { // unescaped non-ASCII char - wr.write(slice.bytes())? + wr.write(slice.bytes())! } else if hex_code.len == 4 { // a unicode endpoint - wr.write(json2.unicode_escape_chars)? - wr.write(hex_code)? + wr.write(json2.unicode_escape_chars)! + wr.write(hex_code)! } else { // TODO: still figuring out what // to do with more than 4 chars - wr.write(json2.space_bytes)? + wr.write(json2.space_bytes)! } unsafe { slice.free() @@ -240,5 +240,5 @@ fn (e &Encoder) encode_string(s string, mut wr io.Writer) ? { i += char_len } - wr.write(json2.quote_bytes)? + wr.write(json2.quote_bytes)! } diff --git a/vlib/x/json2/encoder_test.v b/vlib/x/json2/encoder_test.v index 13f225848..d4a419b4f 100644 --- a/vlib/x/json2/encoder_test.v +++ b/vlib/x/json2/encoder_test.v @@ -39,7 +39,7 @@ fn test_json_string_non_ascii() { fn test_utf8_strings_are_not_modified() { original := '{"s":"Schilddrüsenerkrankungen"}' // dump(original) - deresult := json2.raw_decode(original)? + deresult := json2.raw_decode(original)! // dump(deresult) assert deresult.str() == original } @@ -51,13 +51,13 @@ fn test_encoder_unescaped_utf32() { } mut sb := strings.new_builder(20) - enc.encode_value(jap_text, mut sb)? + enc.encode_value(jap_text, mut sb)! assert sb.str() == '"$jap_text"' sb.go_back_to(0) emoji_text := json2.Any('🐈') - enc.encode_value(emoji_text, mut sb)? + enc.encode_value(emoji_text, mut sb)! assert sb.str() == '"$emoji_text"' } @@ -74,7 +74,7 @@ fn test_encoder_prettify() { newline_spaces_count: 2 } mut sb := strings.new_builder(20) - enc.encode_value(obj, mut sb)? + enc.encode_value(obj, mut sb)! assert sb.str() == '{ "hello": "world", "arr": [ diff --git a/vlib/x/json2/json2.v b/vlib/x/json2/json2.v index 08d2d237a..6b6aa0667 100644 --- a/vlib/x/json2/json2.v +++ b/vlib/x/json2/json2.v @@ -13,20 +13,20 @@ pub interface Serializable { } // Decodes a JSON string into an `Any` type. Returns an option. -pub fn raw_decode(src string) ?Any { +pub fn raw_decode(src string) !Any { mut p := new_parser(src, true) return p.decode() } // Same with `raw_decode`, but skips the type conversion for certain types when decoding a certain value. -pub fn fast_raw_decode(src string) ?Any { +pub fn fast_raw_decode(src string) !Any { mut p := new_parser(src, false) return p.decode() } // decode is a generic function that decodes a JSON string into the target type. -pub fn decode(src string) ?T { - res := raw_decode(src)? +pub fn decode(src string) !T { + res := raw_decode(src)! mut typ := T{} typ.from_json(res) return typ -- 2.30.2