v2 / vlib / v / util / vflags / vflags.v
66 lines · 63 sloc · 1.79 KB · ec1f95ac5024aa944e7887de927492271457bf95
Raw
1// Copyright (c) 2019-2024 Delyan Angelov. All rights reserved.
2// Use of this source code is governed by an MIT license
3// that can be found in the LICENSE file.
4module vflags
5
6import os
7import strings
8
9// join_env_vflags_and_os_args returns all the arguments (the ones from the env variable VFLAGS too), passed on the command line.
10pub fn join_env_vflags_and_os_args() []string {
11 vosargs := os.getenv('VOSARGS')
12 if vosargs != '' {
13 return tokenize_to_args(vosargs)
14 }
15 vflags := os.getenv('VFLAGS')
16 if vflags != '' {
17 mut args := []string{}
18 args << os.args[0]
19 args << tokenize_to_args(vflags)
20 args << os.args#[1..]
21 return args
22 }
23 return os.args
24}
25
26// tokenize_to_args converts the input `s`, into an array of arguments.
27// The arguments are separated by one or more spaces in the input `s`.
28// The separating spaces are ignored.
29// It supports quoted arguments, where "several little words" for example,
30// will become a *single argument* in the output.
31// The quotes can be single or double ones.
32pub fn tokenize_to_args(s string) []string {
33 mut tokens := []string{}
34 mut ctoken := strings.new_builder(20)
35 mut in_quotes := false
36 mut quote_char := ` `
37 for i in 0 .. s.len {
38 c := s[i]
39 if !in_quotes && c in [`"`, `'`] {
40 in_quotes = true
41 quote_char = c
42 } else if in_quotes && c == quote_char {
43 if i > 0 && s[i - 1] == `\\` {
44 // support escaping a quote with a \
45 ctoken.go_back(1)
46 ctoken.write_rune(c)
47 } else {
48 in_quotes = false
49 tokens << ctoken.str()
50 }
51 } else if c.is_space() && !in_quotes {
52 // space outside quotes means end of a token
53 if ctoken.len > 0 {
54 tokens << ctoken.str()
55 }
56 } else {
57 // part of a token
58 ctoken.write_rune(c)
59 }
60 }
61 // add the potential remaining token too
62 if ctoken.len > 0 {
63 tokens << ctoken.str()
64 }
65 return tokens
66}
67