Skip to content

Instantly share code, notes, and snippets.

@larpon
Created June 30, 2022 10:45
Show Gist options
  • Save larpon/adefafa3a3d7b634b6d0f2a3f5269df0 to your computer and use it in GitHub Desktop.
Save larpon/adefafa3a3d7b634b6d0f2a3f5269df0 to your computer and use it in GitHub Desktop.
Find and sum all V compile time $if / $else values in a file or dir
#!/usr/bin/env -S v
module main
import os
struct CompInfo {
pub mut:
file string
line string
line_num int
extract string
count int
}
pub fn (a CompInfo) == (b CompInfo) bool {
return a.extract == b.extract
}
fn main() {
if os.args.len <= 1 {
panic('input arg needed')
}
input := os.args[1]
if !(os.is_dir(input) || os.is_file(input)) {
panic('input "$input" should be a valid v file or dir')
}
mut v_files := []string{}
if os.is_dir(input) {
os.walk_with_context(input, &v_files, fn (mut files []string, path string) {
if os.is_file(path) && os.file_ext(path) in ['.v', '.vv'] {
files << path
}
})
} else {
v_files << input
}
mut comp_ds := []CompInfo{}
for v_file in v_files {
scan_v_file(mut comp_ds, v_file) or { panic(err) }
}
mut res := comp_ds.filter(!it.extract.contains(' '))
res = res.filter(!it.extract.contains(')'))
res.sort(a.extract < b.extract)
for cd in res {
// rel_path := cd.file.all_after(input)
println('$cd.extract ($cd.count)') // $cd.file:$cd.line_num
}
println('Unique: $res.len')
}
fn scan_v_file(mut res []CompInfo, file string) ! {
lines := os.read_lines(file) or { return error('failed reading "$file": $err') }
mut line_num := 0
for line in lines {
line_num++
if line.contains(r'$if') || line.contains(r'$else') {
if line.trim_space().starts_with('//') {
continue
}
mut cis := parse_comp_ifelse(line)
for mut ci in cis {
if ci.extract == '' {
// println('Skipping: $file:$line_num ("$line")')
continue
}
if ci !in res {
ci.file = file
ci.line_num = line_num
ci.count++
res << ci
} else {
idx := res.index(ci)
res[idx].count++
}
}
}
}
}
fn parse_comp_ifelse(line string) []CompInfo {
mut cds := []CompInfo{}
mut essentials := line.all_after(r'$').all_after(' ').all_before('{').trim_space()
essentials = essentials.trim_string_left(r'$if')
if essentials.contains('||') || essentials.contains('&&') {
mut split := essentials.split_any('|&').filter(it.trim_space() != '')
for es in split {
e := es.all_before('(').trim_space().trim(r'$()!? ')
cds << CompInfo{
line: line
extract: e
}
}
} else {
e := essentials.all_before('(').trim_space().trim(r'$()!? ')
cds << CompInfo{
line: line
extract: e
}
}
return cds
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment