| 1 | module main |
| 2 | |
| 3 | import os |
| 4 | import term { bright_green, bright_red, bright_yellow, ecolorize } |
| 5 | import os.cmdline |
| 6 | |
| 7 | // Symbol type to search |
| 8 | enum Symbol { |
| 9 | fn |
| 10 | method |
| 11 | struct |
| 12 | interface |
| 13 | enum |
| 14 | const |
| 15 | var |
| 16 | regexp |
| 17 | } |
| 18 | |
| 19 | // Visibility of the symbols to search |
| 20 | enum Visibility { |
| 21 | all |
| 22 | pub |
| 23 | pri |
| 24 | } |
| 25 | |
| 26 | // Mutability of the symbols to search |
| 27 | enum Mutability { |
| 28 | any |
| 29 | yes |
| 30 | not |
| 31 | } |
| 32 | |
| 33 | const _args = os.args |
| 34 | const verbose = '-v' in cmdline.only_options(_args) |
| 35 | const header = '-h' in cmdline.only_options(_args) |
| 36 | const format = '-f' in cmdline.only_options(_args) |
| 37 | const symbols = { |
| 38 | 'fn': Symbol.fn |
| 39 | 'method': .method |
| 40 | 'struct': .struct |
| 41 | 'interface': .interface |
| 42 | 'enum': .enum |
| 43 | 'const': .const |
| 44 | 'var': .var |
| 45 | 'regexp': .regexp |
| 46 | } |
| 47 | const visibilities = { |
| 48 | 'all': Visibility.all |
| 49 | 'pub': .pub |
| 50 | 'pri': .pri |
| 51 | } |
| 52 | const mutabilities = { |
| 53 | 'any': Mutability.any |
| 54 | 'yes': .yes |
| 55 | 'not': .not |
| 56 | } |
| 57 | const vexe = os.real_path(os.getenv_opt('VEXE') or { @VEXE }) |
| 58 | const vlib_dir = os.join_path(os.dir(vexe), 'vlib') |
| 59 | const vmod_dir = os.vmodules_dir() |
| 60 | const vmod_paths = os.vmodules_paths()[1..] |
| 61 | const current_dir = os.abs_path('.') |
| 62 | |
| 63 | fn (mut cfg Symbol) set_from_str(str_in string) { |
| 64 | if str_in !in symbols { |
| 65 | invalid_option(cfg, str_in) |
| 66 | } |
| 67 | cfg = symbols[str_in] |
| 68 | } |
| 69 | |
| 70 | fn (mut cfg Visibility) set_from_str(str_in string) { |
| 71 | if str_in !in visibilities { |
| 72 | invalid_option(cfg, str_in) |
| 73 | } |
| 74 | cfg = visibilities[str_in] |
| 75 | } |
| 76 | |
| 77 | fn (mut cfg Mutability) set_from_str(str_in string) { |
| 78 | if str_in !in mutabilities { |
| 79 | invalid_option(cfg, str_in) |
| 80 | } |
| 81 | cfg = mutabilities[str_in] |
| 82 | } |
| 83 | |
| 84 | type ParamOption = Mutability | Symbol | Visibility |
| 85 | |
| 86 | // General helpers |
| 87 | fn invalid_option(invalid ParamOption, arg string) { |
| 88 | match invalid.type_name() { |
| 89 | 'Symbol' { |
| 90 | msg := 'First arg (symbol type) must be one of the following:' |
| 91 | make_and_print_error(msg, symbols.keys(), arg) |
| 92 | } |
| 93 | 'Visibility' { |
| 94 | msg := '"-vis" (visibility) must be one of the following:' |
| 95 | make_and_print_error(msg, visibilities.keys(), arg) |
| 96 | } |
| 97 | 'Mutability' { |
| 98 | msg := '"-mut" (mutability) must be one of the following:' |
| 99 | make_and_print_error(msg, mutabilities.keys(), arg) |
| 100 | } |
| 101 | else { |
| 102 | exit(1) |
| 103 | } |
| 104 | } |
| 105 | } |
| 106 | |
| 107 | fn make_and_print_error(msg string, opts []string, arg string) { |
| 108 | if verbose || format { |
| 109 | eprintln('\n' + ecolorize(bright_yellow, msg)) |
| 110 | if opts.len > 0 { |
| 111 | eprint(opts.map(ecolorize(bright_green, it)).join(' | ')) |
| 112 | } |
| 113 | eprintln(' ...can not be ${ecolorize(bright_red, arg)}') |
| 114 | } else { |
| 115 | eprint(ecolorize(bright_yellow, msg) + ' ') |
| 116 | if opts.len > 0 { |
| 117 | eprint(opts.map(ecolorize(bright_green, it)).join(' | ')) |
| 118 | } |
| 119 | eprintln(' ...can not be ${ecolorize(bright_red, arg)}') |
| 120 | } |
| 121 | exit(1) |
| 122 | } |
| 123 | |
| 124 | fn collect_v_files(path string, recursive bool) ![]string { |
| 125 | if path == '' || !os.is_dir(path) { |
| 126 | return error('path `${path}` does not exist or is not a directory') |
| 127 | } |
| 128 | mut all_files := []string{} |
| 129 | mut entries := os.ls(path)! |
| 130 | for entry in entries { |
| 131 | if entry == '.git' { |
| 132 | continue |
| 133 | } |
| 134 | if entry == 'tests' { |
| 135 | continue |
| 136 | } |
| 137 | file := os.join_path_single(path, entry) |
| 138 | if os.file_ext(entry) in ['.v', '.vsh'] { |
| 139 | all_files << file |
| 140 | continue |
| 141 | } |
| 142 | if recursive && os.is_dir(file) && !os.is_link(file) { |
| 143 | all_files << collect_v_files(file, recursive)! |
| 144 | } |
| 145 | } |
| 146 | return all_files |
| 147 | } |
| 148 | |
| 149 | fn resolve_module(path string) !string { |
| 150 | return match true { |
| 151 | os.is_dir(path) { path } |
| 152 | os.is_dir(os.join_path(vmod_dir, path)) { os.join_path(vmod_dir, path) } |
| 153 | os.is_dir(os.join_path(vlib_dir, path)) { os.join_path(vlib_dir, path) } |
| 154 | else { error('Path: ${path} not found') } |
| 155 | } |
| 156 | } |
| 157 | |