ran odinfmt on source

This commit is contained in:
Daniel Gavin
2021-04-22 00:07:07 +02:00
parent ca112c0b6d
commit b18e8898d8
2 changed files with 346 additions and 380 deletions
+219 -232
View File
@@ -1,232 +1,219 @@
package flag package flag
import "core:runtime" import "core:runtime"
import "core:strings" import "core:strings"
import "core:reflect" import "core:reflect"
import "core:fmt" import "core:fmt"
import "core:mem" import "core:mem"
import "core:strconv" import "core:strconv"
Flag_Error :: enum { Flag_Error :: enum {
None, None,
No_Base_Struct, No_Base_Struct,
Arg_Error, Arg_Error,
Arg_Unsupported_Field_Type, Arg_Unsupported_Field_Type,
Arg_Not_Defined, Arg_Not_Defined,
Arg_Non_Optional, Arg_Non_Optional,
Value_Parse_Error, Value_Parse_Error,
Tag_Error, Tag_Error,
} }
Flag :: struct { Flag :: struct {
optional: bool, optional: bool,
type: ^runtime.Type_Info, type: ^runtime.Type_Info,
data: rawptr, data: rawptr,
tag_ptr: rawptr, tag_ptr: rawptr,
parsed: bool, parsed: bool,
} }
Flag_Context :: struct { Flag_Context :: struct {
seen_flags: map [string] Flag, seen_flags: map[string]Flag,
} }
parse_args :: proc(ctx: ^Flag_Context, args: []string) -> Flag_Error { parse_args :: proc(ctx: ^Flag_Context, args: []string) -> Flag_Error {
using runtime; using runtime;
args := args; args := args;
for true { for true {
if len(args) == 0 { if len(args) == 0 {
return .None; return .None;
} }
arg := args[0]; arg := args[0];
if len(arg) < 2 || arg[0] != '-' { if len(arg) < 2 || arg[0] != '-' {
return .Arg_Error; return .Arg_Error;
} }
minus_count := 1; minus_count := 1;
if arg[1] == '-' { if arg[1] == '-' {
minus_count += 1; minus_count += 1;
if len(arg) == 2 { if len(arg) == 2 {
return .Arg_Error; return .Arg_Error;
} }
} }
name := arg[minus_count:]; name := arg[minus_count:];
if len(name) == 0 { if len(name) == 0 {
return .Arg_Error; return .Arg_Error;
} }
args = args[1:]; args = args[1:];
assign_index := strings.index(name, "="); assign_index := strings.index(name, "=");
value := ""; value := "";
if assign_index > 0 { if assign_index > 0 {
value = name[assign_index + 1:]; value = name[assign_index + 1:];
name = name[0:assign_index]; name = name[0:assign_index];
} }
flag := &ctx.seen_flags[name]; flag := &ctx.seen_flags[name];
if flag == nil { if flag == nil {
return .Arg_Not_Defined; return .Arg_Not_Defined;
} }
if reflect.is_boolean(flag.type) { if reflect.is_boolean(flag.type) {
tmp := true; tmp := true;
mem.copy(flag.data, &tmp, flag.type.size); mem.copy(flag.data, &tmp, flag.type.size);
flag.parsed = true; flag.parsed = true;
continue; continue;
} } else
//must be in the next argument //must be in the next argument
else if value == "" { if value == "" {
if len(args) == 0 { if len(args) == 0 {
return .Arg_Error; return .Arg_Error;
} }
value = args[0]; value = args[0];
args = args[1:]; args = args[1:];
} }
#partial switch in flag.type.variant { #partial switch _ in flag.type.variant {
case Type_Info_Integer: case Type_Info_Integer:
if v, ok := strconv.parse_int(value); ok { if v, ok := strconv.parse_int(value); ok {
mem.copy(flag.data, &v, flag.type.size); mem.copy(flag.data, &v, flag.type.size);
} } else {
else { return .Value_Parse_Error;
return .Value_Parse_Error; }
} case Type_Info_String:
case Type_Info_String: raw_string := cast(^mem.Raw_String)flag.data;
raw_string := cast(^mem.Raw_String)flag.data; raw_string.data = strings.ptr_from_string(value);
raw_string.data = strings.ptr_from_string(value); raw_string.len = len(value);
raw_string.len = len(value); case Type_Info_Float:
case Type_Info_Float: switch flag.type.size {
switch flag.type.size { case 32:
case 32: if v, ok := strconv.parse_f32(value); ok {
if v, ok := strconv.parse_f32(value); ok { mem.copy(flag.data, &v, flag.type.size);
mem.copy(flag.data, &v, flag.type.size); } else {
} return .Value_Parse_Error;
else { }
return .Value_Parse_Error; case 64:
} if v, ok := strconv.parse_f64(value); ok {
case 64: mem.copy(flag.data, &v, flag.type.size);
if v, ok := strconv.parse_f64(value); ok { } else {
mem.copy(flag.data, &v, flag.type.size); return .Value_Parse_Error;
} }
else { }
return .Value_Parse_Error; }
}
} flag.parsed = true;
} }
flag.parsed = true; return .None;
} }
reflect_args_structure :: proc(ctx: ^Flag_Context, v: any) -> Flag_Error {
using runtime;
return .None;
} if !reflect.is_struct(type_info_of(v.id)) {
return .No_Base_Struct;
reflect_args_structure :: proc(ctx: ^Flag_Context, v: any) -> Flag_Error { }
using runtime;
names := reflect.struct_field_names(v.id);
if !reflect.is_struct(type_info_of(v.id)) { types := reflect.struct_field_types(v.id);
return .No_Base_Struct; offsets := reflect.struct_field_offsets(v.id);
} tags := reflect.struct_field_tags(v.id);
names := reflect.struct_field_names(v.id); for name, i in names {
types := reflect.struct_field_types(v.id);
offsets := reflect.struct_field_offsets(v.id); flag: Flag;
tags := reflect.struct_field_tags(v.id);
type := types[i];
for name, i in names {
if named_type, ok := type.variant.(Type_Info_Named); ok {
flag: Flag;
if union_type, ok := named_type.base.variant.(Type_Info_Union); ok && union_type.maybe && len(union_type.variants) == 1 {
type := types[i]; flag.optional = true;
flag.tag_ptr = rawptr(uintptr(union_type.tag_offset) + uintptr(v.data) + uintptr(offsets[i]));
if named_type, ok := type.variant.(Type_Info_Named); ok { type = union_type.variants[0];
} else {
if union_type, ok := named_type.base.variant.(Type_Info_Union); ok && union_type.maybe && len(union_type.variants) == 1 { return .Arg_Unsupported_Field_Type;
flag.optional = true; }
flag.tag_ptr = rawptr(uintptr(union_type.tag_offset) + uintptr(v.data) + uintptr(offsets[i])); }
type = union_type.variants[0];
} #partial switch _ in type.variant {
case Type_Info_Integer, Type_Info_String, Type_Info_Boolean, Type_Info_Float:
else { flag.type = type;
return .Arg_Unsupported_Field_Type; flag.data = rawptr(uintptr(v.data) + uintptr(offsets[i]));
} case:
return .Arg_Unsupported_Field_Type;
} }
#partial switch in type.variant { flag_name: string;
case Type_Info_Integer, Type_Info_String, Type_Info_Boolean, Type_Info_Float:
flag.type = type; if value, ok := reflect.struct_tag_lookup(tags[i], "flag"); ok {
flag.data = rawptr(uintptr(v.data) + uintptr(offsets[i])); flag_name = cast(string)value;
case: } else {
return .Arg_Unsupported_Field_Type; return .Tag_Error;
} }
flag_name: string; ctx.seen_flags[flag_name] = flag;
}
if value, ok := reflect.struct_tag_lookup(tags[i], "flag"); ok {
flag_name = cast(string)value; return .None;
} }
else { parse :: proc(v: any, args: []string) -> Flag_Error {
return .Tag_Error;
} if v == nil {
return .None;
ctx.seen_flags[flag_name] = flag; }
}
ctx: Flag_Context;
return .None;
} if res := reflect_args_structure(&ctx, v); res != .None {
return res;
parse :: proc(v: any, args: []string) -> Flag_Error { }
if v == nil { if res := parse_args(&ctx, args); res != .None {
return .None; return res;
} }
ctx: Flag_Context; //validate that the required flags were actually set
for k, v in ctx.seen_flags {
if res := reflect_args_structure(&ctx, v); res != .None {
return res; if v.optional && v.parsed {
} tag_value: i32 = 1;
mem.copy(v.tag_ptr, &tag_value, 4); //4 constant is probably not portable, but it works for me currently
if res := parse_args(&ctx, args); res != .None { } else if !v.parsed && !v.optional {
return res; return .Arg_Non_Optional;
} }
}
//validate that the required flags were actually set
for k, v in ctx.seen_flags { return .None;
}
if v.optional && v.parsed {
tag_value : i32 = 1; usage :: proc(v: any) -> string {
mem.copy(v.tag_ptr, &tag_value, 4); //4 constant is probably not portable, but it works for me currently return "failed";
} }
else if !v.parsed && !v.optional {
return .Arg_Non_Optional;
}
}
return .None;
}
usage :: proc(v: any) -> string {
return "failed";
}
+127 -148
View File
@@ -1,148 +1,127 @@
package odinfmt package odinfmt
import "core:os" import "core:os"
import "core:odin/format" import "core:odin/format"
import "core:fmt" import "core:fmt"
import "core:strings" import "core:strings"
import "core:path/filepath" import "core:path/filepath"
import "core:time" import "core:time"
import "core:mem" import "core:mem"
import "flag" import "flag"
Args :: struct { Args :: struct {
write: Maybe(bool) `flag:"w" usage:"write the new format to file"`, write: Maybe(bool) `flag:"w" usage:"write the new format to file"`,
} }
print_help :: proc() { print_help :: proc() {
}
}
print_arg_error :: proc(error: flag.Flag_Error) {
print_arg_error :: proc(error: flag.Flag_Error) { fmt.println(error);
fmt.println(error); }
}
format_file :: proc(filepath: string) -> ([]u8, bool) {
format_file :: proc(filepath: string) -> ([] u8, bool) {
if data, ok := os.read_entire_file(filepath); ok {
if data, ok := os.read_entire_file(filepath); ok { return format.format(data, format.default_style);
return format.format(data, format.default_style); } else {
} return {}, false;
}
else { }
return {}, false;
} files: [dynamic]string;
} walk_files :: proc(info: os.File_Info, in_err: os.Errno) -> (err: os.Errno, skip_dir: bool) {
files: [dynamic] string; if info.is_dir {
return 0, false;
walk_files :: proc(info: os.File_Info, in_err: os.Errno) -> (err: os.Errno, skip_dir: bool) { }
if info.is_dir { if filepath.ext(info.name) != ".odin" {
return 0, false; return 0, false;
} }
if filepath.ext(info.name) != ".odin" { append(&files, strings.clone(info.fullpath));
return 0, false;
} return 0, false;
}
append(&files, strings.clone(info.fullpath));
main :: proc() {
return 0, false;
} init_global_temporary_allocator(mem.megabytes(100));
main :: proc() { args: Args;
init_global_temporary_allocator(mem.megabytes(100)); if len(os.args) < 2 {
print_help();
args: Args; os.exit(1);
}
if len(os.args) < 2 {
print_help(); if res := flag.parse(args, os.args[1:len(os.args) - 1]); res != .None {
os.exit(1); print_arg_error(res);
} os.exit(1);
}
if res := flag.parse(args, os.args[1:len(os.args)-1]); res != .None {
print_arg_error(res); path := os.args[len(os.args) - 1];
os.exit(1);
} tick_time := time.tick_now();
path := os.args[len(os.args)-1]; if os.is_file(path) {
tick_time := time.tick_now(); if _, ok := args.write.(bool); ok {
if os.is_file(path) { backup_path := strings.concatenate({path, "_bk"}, context.temp_allocator);
if _, ok := args.write.(bool); ok { if data, ok := format_file(path); ok {
backup_path := strings.concatenate({path, "_bk"}, context.temp_allocator); os.rename(path, backup_path);
if data, ok := format_file(path); ok { if os.write_entire_file(path, data) {
os.remove(backup_path);
os.rename(path, backup_path); }
} else {
if os.write_entire_file(path, data) { fmt.eprintf("failed to write %v", path);
os.remove(backup_path); }
} } else {
} if data, ok := format_file(path); ok {
fmt.println(transmute(string)data);
else { }
fmt.eprintf("failed to write %v", path); }
} } else if os.is_dir(path) {
} filepath.walk(path, walk_files);
else { for file in files {
if data, ok := format_file(path); ok { fmt.println(file);
fmt.println(transmute(string)data);
} backup_path := strings.concatenate({file, "_bk"}, context.temp_allocator);
} if data, ok := format_file(file); ok {
} if _, ok := args.write.(bool); ok {
os.rename(file, backup_path);
else if os.is_dir(path) {
if os.write_entire_file(file, data) {
filepath.walk(path, walk_files); os.remove(backup_path);
}
for file in files { } else {
fmt.println(transmute(string)data);
fmt.println(file); }
} else {
backup_path := strings.concatenate({file, "_bk"}, context.temp_allocator); fmt.eprintf("failed to format %v", file);
}
if data, ok := format_file(file); ok {
free_all(context.temp_allocator);
if _, ok := args.write.(bool); ok { }
os.rename(file, backup_path);
fmt.printf("formatted %v files in %vms", len(files), time.duration_milliseconds(time.tick_lap_time(&tick_time)));
if os.write_entire_file(file, data) { } else {
os.remove(backup_path); fmt.eprintf("%v is neither a directory nor a file \n", path);
} os.exit(1);
} }
else { os.exit(0);
fmt.println(transmute(string)data); }
}
} else {
fmt.eprintf("failed to format %v", file);
}
free_all(context.temp_allocator);
}
fmt.printf("formatted %v files in %vms", len(files), time.duration_milliseconds(time.tick_lap_time(&tick_time)));
}
else{
fmt.eprintf("%v is neither a directory nor a file \n", path);
os.exit(1);
}
os.exit(0);
}