mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 07:38:48 +00:00
ran odinfmt on source
This commit is contained in:
+219
-232
@@ -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
@@ -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);
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user