diff options
| author | Daniel Gavin <danielgavin5@hotmail.com> | 2022-03-04 12:17:00 +0100 |
|---|---|---|
| committer | Daniel Gavin <danielgavin5@hotmail.com> | 2022-03-04 12:17:00 +0100 |
| commit | 58287455d64ab16091522bf8a358b079ef05daad (patch) | |
| tree | 7b6655d6d34b5ad6d719523e4938b8002c43d8ab /src/common | |
| parent | 63d0bd412a8817445d6dc18e79d5d54c94caf401 (diff) | |
strip colons and update ast to use unions
Diffstat (limited to 'src/common')
| -rw-r--r-- | src/common/allocator.odin | 104 | ||||
| -rw-r--r-- | src/common/ast.odin | 1116 | ||||
| -rw-r--r-- | src/common/fuzzy.odin | 254 | ||||
| -rw-r--r-- | src/common/position.odin | 166 | ||||
| -rw-r--r-- | src/common/sha1.odin | 334 | ||||
| -rw-r--r-- | src/common/uri.odin | 92 | ||||
| -rw-r--r-- | src/common/util_windows.odin | 62 |
7 files changed, 1059 insertions, 1069 deletions
diff --git a/src/common/allocator.odin b/src/common/allocator.odin index bbb654c..6d2d371 100644 --- a/src/common/allocator.odin +++ b/src/common/allocator.odin @@ -12,119 +12,119 @@ Scratch_Allocator :: struct { }
scratch_allocator_init :: proc (s: ^Scratch_Allocator, size: int, backup_allocator := context.allocator) {
- s.data, _ = mem.make_aligned([]byte, size, 2 * align_of(rawptr), backup_allocator);
- s.curr_offset = 0;
- s.prev_allocation = nil;
- s.backup_allocator = backup_allocator;
- s.leaked_allocations.allocator = backup_allocator;
+ s.data, _ = mem.make_aligned([]byte, size, 2 * align_of(rawptr), backup_allocator)
+ s.curr_offset = 0
+ s.prev_allocation = nil
+ s.backup_allocator = backup_allocator
+ s.leaked_allocations.allocator = backup_allocator
}
scratch_allocator_destroy :: proc (s: ^Scratch_Allocator) {
if s == nil {
- return;
+ return
}
for ptr in s.leaked_allocations {
- mem.free_bytes(ptr, s.backup_allocator);
+ mem.free_bytes(ptr, s.backup_allocator)
}
- delete(s.leaked_allocations);
- delete(s.data, s.backup_allocator);
- s^ = {};
+ delete(s.leaked_allocations)
+ delete(s.data, s.backup_allocator)
+ s^ = {}
}
scratch_allocator_proc :: proc (allocator_data: rawptr, mode: mem.Allocator_Mode, size, alignment: int, old_memory: rawptr, old_size: int, loc := #caller_location) -> ([]byte, mem.Allocator_Error) {
- s := (^Scratch_Allocator)(allocator_data);
+ s := (^Scratch_Allocator)(allocator_data)
if s.data == nil {
- DEFAULT_BACKING_SIZE :: 1 << 22;
+ DEFAULT_BACKING_SIZE :: 1 << 22
if !(context.allocator.procedure != scratch_allocator_proc &&
context.allocator.data != allocator_data) {
- panic("cyclic initialization of the scratch allocator with itself");
+ panic("cyclic initialization of the scratch allocator with itself")
}
- scratch_allocator_init(s, DEFAULT_BACKING_SIZE);
+ scratch_allocator_init(s, DEFAULT_BACKING_SIZE)
}
- size := size;
+ size := size
switch mode {
case .Alloc:
- size = mem.align_forward_int(size, alignment);
+ size = mem.align_forward_int(size, alignment)
switch {
case s.curr_offset + size <= len(s.data):
- start := uintptr(raw_data(s.data));
- ptr := start + uintptr(s.curr_offset);
- ptr = mem.align_forward_uintptr(ptr, uintptr(alignment));
- mem.zero(rawptr(ptr), size);
-
- s.prev_allocation = rawptr(ptr);
- offset := int(ptr - start);
- s.curr_offset = offset + size;
- return mem.byte_slice(rawptr(ptr), size), nil;
+ start := uintptr(raw_data(s.data))
+ ptr := start + uintptr(s.curr_offset)
+ ptr = mem.align_forward_uintptr(ptr, uintptr(alignment))
+ mem.zero(rawptr(ptr), size)
+
+ s.prev_allocation = rawptr(ptr)
+ offset := int(ptr - start)
+ s.curr_offset = offset + size
+ return mem.byte_slice(rawptr(ptr), size), nil
}
- a := s.backup_allocator;
+ a := s.backup_allocator
if a.procedure == nil {
- a = context.allocator;
- s.backup_allocator = a;
+ a = context.allocator
+ s.backup_allocator = a
}
- ptr, err := mem.alloc_bytes(size, alignment, a, loc);
+ ptr, err := mem.alloc_bytes(size, alignment, a, loc)
if err != nil {
- return ptr, err;
+ return ptr, err
}
if s.leaked_allocations == nil {
- s.leaked_allocations = make([dynamic][]byte, a);
+ s.leaked_allocations = make([dynamic][]byte, a)
}
- append(&s.leaked_allocations, ptr);
+ append(&s.leaked_allocations, ptr)
if logger := context.logger; logger.lowest_level <= .Warning {
if logger.procedure != nil {
- logger.procedure(logger.data, .Warning, "mem.Scratch_Allocator resorted to backup_allocator" , logger.options, loc);
+ logger.procedure(logger.data, .Warning, "mem.Scratch_Allocator resorted to backup_allocator" , logger.options, loc)
}
}
- return ptr, err;
+ return ptr, err
case .Free:
case .Free_All:
- s.curr_offset = 0;
- s.prev_allocation = nil;
+ s.curr_offset = 0
+ s.prev_allocation = nil
for ptr in s.leaked_allocations {
- mem.free_bytes(ptr, s.backup_allocator);
+ mem.free_bytes(ptr, s.backup_allocator)
}
- clear(&s.leaked_allocations);
+ clear(&s.leaked_allocations)
case .Resize:
- begin := uintptr(raw_data(s.data));
- end := begin + uintptr(len(s.data));
- old_ptr := uintptr(old_memory);
+ begin := uintptr(raw_data(s.data))
+ end := begin + uintptr(len(s.data))
+ old_ptr := uintptr(old_memory)
- data, err := scratch_allocator_proc(allocator_data, .Alloc, size, alignment, old_memory, old_size, loc);
+ data, err := scratch_allocator_proc(allocator_data, .Alloc, size, alignment, old_memory, old_size, loc)
if err != nil {
- return data, err;
+ return data, err
}
- runtime.copy(data, mem.byte_slice(old_memory, old_size));
- _, err = scratch_allocator_proc(allocator_data, .Free, 0, alignment, old_memory, old_size, loc);
- return data, err;
+ runtime.copy(data, mem.byte_slice(old_memory, old_size))
+ _, err = scratch_allocator_proc(allocator_data, .Free, 0, alignment, old_memory, old_size, loc)
+ return data, err
case .Query_Features:
- set := (^mem.Allocator_Mode_Set)(old_memory);
+ set := (^mem.Allocator_Mode_Set)(old_memory)
if set != nil {
- set^ = {.Alloc, .Free, .Free_All, .Resize, .Query_Features};
+ set^ = {.Alloc, .Free, .Free_All, .Resize, .Query_Features}
}
- return nil, nil;
+ return nil, nil
case .Query_Info:
- return nil, nil;
+ return nil, nil
}
- return nil, nil;
+ return nil, nil
}
scratch_allocator :: proc (allocator: ^Scratch_Allocator) -> mem.Allocator {
return mem.Allocator {
procedure = scratch_allocator_proc,
data = allocator,
- };
+ }
}
diff --git a/src/common/ast.odin b/src/common/ast.odin index 69f35e0..7677634 100644 --- a/src/common/ast.odin +++ b/src/common/ast.odin @@ -62,7 +62,7 @@ keyword_map: map[string]bool = { "quaternion64" = true, "quaternion128" = true, "quaternion256" = true, -}; +} GlobalExpr :: struct { name: string, @@ -77,63 +77,63 @@ GlobalExpr :: struct { unwrap_pointer :: proc(expr: ^ast.Expr) -> (ast.Ident, bool) { - expr := expr; + expr := expr for expr != nil { - if pointer, ok := expr.derived.(ast.Pointer_Type); ok { - expr = pointer.elem; + if pointer, ok := expr.derived.(^ast.Pointer_Type); ok { + expr = pointer.elem } else { - break; + break } } if expr != nil { - ident, ok := expr.derived.(ast.Ident); - return ident, ok; + ident, ok := expr.derived.(^ast.Ident) + return ident^, ok } - return {}, false; + return {}, false } collect_value_decl :: proc(exprs: ^[dynamic]GlobalExpr, file: ast.File, stmt: ^ast.Node, skip_private: bool) { - if value_decl, ok := stmt.derived.(ast.Value_Decl); ok { + if value_decl, ok := stmt.derived.(^ast.Value_Decl); ok { - is_deprecated := false; - is_private_file := false; - is_package_file := false; + is_deprecated := false + is_private_file := false + is_package_file := false for attribute in value_decl.attributes { for elem in attribute.elems { - if value, ok := elem.derived.(ast.Field_Value); ok { - if ident, ok := value.field.derived.(ast.Ident); ok { + if value, ok := elem.derived.(^ast.Field_Value); ok { + if ident, ok := value.field.derived.(^ast.Ident); ok { switch ident.name { case "private": - if val, ok := value.value.derived.(ast.Basic_Lit); ok { + if val, ok := value.value.derived.(^ast.Basic_Lit); ok { switch val.tok.text { case "\"file\"": - is_private_file = true; + is_private_file = true case "package": - is_package_file = true; + is_package_file = true } } case "deprecated": - is_deprecated = true; + is_deprecated = true } } - } else if ident, ok := elem.derived.(ast.Ident); ok { + } else if ident, ok := elem.derived.(^ast.Ident); ok { switch ident.name { case "deprecated": - is_deprecated = true; + is_deprecated = true } } } } if is_private_file && skip_private { - return; + return } for name, i in value_decl.names { - str := get_ast_node_string(name, file.src); + str := get_ast_node_string(name, file.src) if value_decl.type != nil { append(exprs, GlobalExpr { @@ -143,7 +143,7 @@ collect_value_decl :: proc(exprs: ^[dynamic]GlobalExpr, file: ast.File, stmt: ^a docs = value_decl.docs, attributes = value_decl.attributes[:], deprecated = is_deprecated, - }); + }) } else { if len(value_decl.values) > i { append(exprs, GlobalExpr { @@ -153,7 +153,7 @@ collect_value_decl :: proc(exprs: ^[dynamic]GlobalExpr, file: ast.File, stmt: ^a docs = value_decl.docs, attributes = value_decl.attributes[:], deprecated = is_deprecated, - }); + }) } } } @@ -161,98 +161,97 @@ collect_value_decl :: proc(exprs: ^[dynamic]GlobalExpr, file: ast.File, stmt: ^a } collect_globals :: proc(file: ast.File, skip_private := false) -> []GlobalExpr { - exprs := make([dynamic]GlobalExpr, context.temp_allocator); + exprs := make([dynamic]GlobalExpr, context.temp_allocator) for decl in file.decls { - if value_decl, ok := decl.derived.(ast.Value_Decl); ok { - collect_value_decl(&exprs, file, decl, skip_private); - } else if when_decl, ok := decl.derived.(ast.When_Stmt); ok { + if value_decl, ok := decl.derived.(^ast.Value_Decl); ok { + collect_value_decl(&exprs, file, decl, skip_private) + } else if when_decl, ok := decl.derived.(^ast.When_Stmt); ok { if when_decl.cond == nil { - continue; + continue } if when_decl.body == nil { - continue; + continue } - if binary, ok := when_decl.cond.derived.(ast.Binary_Expr); ok { + if binary, ok := when_decl.cond.derived.(^ast.Binary_Expr); ok { if binary.left == nil || binary.right == nil { - continue; + continue } - ident: ^ast.Ident; - basic_lit: ^ast.Basic_Lit; + ident: ^ast.Ident + implicit: ^ast.Implicit - if t, ok := binary.left.derived.(ast.Ident); ok { - ident = cast(^ast.Ident)binary.left; - } else if t, ok := binary.left.derived.(ast.Basic_Lit); ok { - basic_lit = cast(^ast.Basic_Lit)binary.left; + if t, ok := binary.left.derived.(^ast.Ident); ok { + ident = cast(^ast.Ident)binary.left + } else if t, ok := binary.left.derived.(^ast.Basic_Lit); ok { + implicit = cast(^ast.Implicit)binary.left } - if t, ok := binary.right.derived.(ast.Ident); ok { - ident = cast(^ast.Ident)binary.right; - } else if t, ok := binary.right.derived.(ast.Basic_Lit); ok { - basic_lit = cast(^ast.Basic_Lit)binary.right; + if t, ok := binary.right.derived.(^ast.Ident); ok { + ident = cast(^ast.Ident)binary.right + } else if t, ok := binary.right.derived.(^ast.Basic_Lit); ok { + implicit = cast(^ast.Implicit)binary.right } - if ident != nil && basic_lit != nil { - if ident.name == "ODIN_OS" && basic_lit.tok.text[1:len(basic_lit.tok.text)-1] == ODIN_OS { - if block, ok := when_decl.body.derived.(ast.Block_Stmt); ok { + if ident != nil && implicit != nil { + if ident.name == "ODIN_OS" && implicit.tok.text == fmt.tprint(ODIN_OS) { + if block, ok := when_decl.body.derived.(^ast.Block_Stmt); ok { for stmt in block.stmts { - collect_value_decl(&exprs, file, stmt, skip_private); + collect_value_decl(&exprs, file, stmt, skip_private) } } } else if ident.name != "ODIN_OS" { - if block, ok := when_decl.body.derived.(ast.Block_Stmt); ok { + if block, ok := when_decl.body.derived.(^ast.Block_Stmt); ok { for stmt in block.stmts { - collect_value_decl(&exprs, file, stmt, skip_private); + collect_value_decl(&exprs, file, stmt, skip_private) } } } } } else { - if block, ok := when_decl.body.derived.(ast.Block_Stmt); ok { + if block, ok := when_decl.body.derived.(^ast.Block_Stmt); ok { for stmt in block.stmts { - collect_value_decl(&exprs, file, stmt, skip_private); + collect_value_decl(&exprs, file, stmt, skip_private) } } } - } else if foreign_decl, ok := decl.derived.(ast.Foreign_Block_Decl); ok { + } else if foreign_decl, ok := decl.derived.(^ast.Foreign_Block_Decl); ok { if foreign_decl.body == nil { - continue; + continue } - if block, ok := foreign_decl.body.derived.(ast.Block_Stmt); ok { + if block, ok := foreign_decl.body.derived.(^ast.Block_Stmt); ok { for stmt in block.stmts { - collect_value_decl(&exprs, file, stmt, skip_private); + collect_value_decl(&exprs, file, stmt, skip_private) } } } } - return exprs[:]; + return exprs[:] } get_ast_node_string :: proc(node: ^ast.Node, src: string) -> string { - return string(src[node.pos.offset:node.end.offset]); + return string(src[node.pos.offset:node.end.offset]) } get_doc :: proc(comment: ^ast.Comment_Group, allocator: mem.Allocator) -> string { - if comment != nil { - tmp: string; + tmp: string for doc in comment.list { - tmp = strings.concatenate({tmp, "\n", doc.text}, context.temp_allocator); + tmp = strings.concatenate({tmp, "\n", doc.text}, context.temp_allocator) } if tmp != "" { - replaced, allocated := strings.replace_all(tmp, "//", "", context.temp_allocator); - return strings.clone(replaced, allocator); + replaced, allocated := strings.replace_all(tmp, "//", "", context.temp_allocator) + return strings.clone(replaced, allocator) } } - return ""; + return "" } free_ast :: proc{ @@ -260,451 +259,443 @@ free_ast :: proc{ free_ast_array, free_ast_dynamic_array, free_ast_comment, -}; +} free_ast_comment :: proc(a: ^ast.Comment_Group, allocator: mem.Allocator) { if a == nil { - return; + return } if len(a.list) > 0 { - delete(a.list, allocator); + delete(a.list, allocator) } - free(a, allocator); + free(a, allocator) } free_ast_array :: proc(array: $A/[]^$T, allocator: mem.Allocator) { for elem, i in array { - free_ast(elem, allocator); + free_ast(elem, allocator) } - delete(array, allocator); + delete(array, allocator) } free_ast_dynamic_array :: proc(array: $A/[dynamic]^$T, allocator: mem.Allocator) { for elem, i in array { - free_ast(elem, allocator); + free_ast(elem, allocator) } - delete(array); + delete(array) } free_ast_node :: proc(node: ^ast.Node, allocator: mem.Allocator) { - - using ast; + using ast if node == nil { - return; + return } - switch n in node.derived { - case Bad_Expr: - case Ident: - case Implicit: - case Undef: - case Basic_Directive: - case Basic_Lit: - case Ellipsis: - free_ast(n.expr, allocator); - case Proc_Lit: - free_ast(n.type, allocator); - free_ast(n.body, allocator); - free_ast(n.where_clauses, allocator); - case Comp_Lit: - free_ast(n.type, allocator); - free_ast(n.elems, allocator); - case Tag_Expr: - free_ast(n.expr, allocator); - case Unary_Expr: - free_ast(n.expr, allocator); - case Binary_Expr: - free_ast(n.left, allocator); - free_ast(n.right, allocator); - case Paren_Expr: - free_ast(n.expr, allocator); - case Call_Expr: - free_ast(n.expr, allocator); - free_ast(n.args, allocator); - case Selector_Expr: - free_ast(n.expr, allocator); - free_ast(n.field, allocator); - case Implicit_Selector_Expr: - free_ast(n.field, allocator); - case Index_Expr: - free_ast(n.expr, allocator); - free_ast(n.index, allocator); - case Deref_Expr: - free_ast(n.expr, allocator); - case Slice_Expr: - free_ast(n.expr, allocator); - free_ast(n.low, allocator); - free_ast(n.high, allocator); - case Field_Value: - free_ast(n.field, allocator); - free_ast(n.value, allocator); - case Ternary_If_Expr: - free_ast(n.x, allocator); - free_ast(n.cond, allocator); - free_ast(n.y, allocator); - case Ternary_When_Expr: - free_ast(n.x, allocator); - free_ast(n.cond, allocator); - free_ast(n.y, allocator); - case Type_Assertion: - free_ast(n.expr, allocator); - free_ast(n.type, allocator); - case Type_Cast: - free_ast(n.type, allocator); - free_ast(n.expr, allocator); - case Auto_Cast: - free_ast(n.expr, allocator); - case Bad_Stmt: - case Empty_Stmt: - case Expr_Stmt: - free_ast(n.expr, allocator); - case Tag_Stmt: - r := cast(^Expr_Stmt)node; - free_ast(r.expr, allocator); - case Assign_Stmt: - free_ast(n.lhs, allocator); - free_ast(n.rhs, allocator); - case Block_Stmt: - free_ast(n.label, allocator); - free_ast(n.stmts, allocator); - case If_Stmt: - free_ast(n.label, allocator); - free_ast(n.init, allocator); - free_ast(n.cond, allocator); - free_ast(n.body, allocator); - free_ast(n.else_stmt, allocator); - case When_Stmt: - free_ast(n.cond, allocator); - free_ast(n.body, allocator); - free_ast(n.else_stmt, allocator); - case Return_Stmt: - free_ast(n.results, allocator); - case Defer_Stmt: - free_ast(n.stmt, allocator); - case For_Stmt: - free_ast(n.label, allocator); - free_ast(n.init, allocator); - free_ast(n.cond, allocator); - free_ast(n.post, allocator); - free_ast(n.body, allocator); - case Range_Stmt: - free_ast(n.label, allocator); - free_ast(n.vals, allocator); - free_ast(n.expr, allocator); - free_ast(n.body, allocator); - case Case_Clause: - free_ast(n.list, allocator); - free_ast(n.body, allocator); - case Switch_Stmt: - free_ast(n.label, allocator); - free_ast(n.init, allocator); - free_ast(n.cond, allocator); - free_ast(n.body, allocator); - case Type_Switch_Stmt: - free_ast(n.label, allocator); - free_ast(n.tag, allocator); - free_ast(n.expr, allocator); - free_ast(n.body, allocator); - case Branch_Stmt: - free_ast(n.label, allocator); - case Using_Stmt: - free_ast(n.list, allocator); - case Bad_Decl: - case Value_Decl: - free_ast(n.attributes, allocator); - free_ast(n.names, allocator); - free_ast(n.type, allocator); - free_ast(n.values, allocator); - //free_ast(n.docs); - //free_ast(n.comment); - case Package_Decl: - //free_ast(n.docs); - //free_ast(n.comment); - case Import_Decl: - //free_ast(n.docs); - //free_ast(n.comment); - case Foreign_Block_Decl: - free_ast(n.attributes, allocator); - free_ast(n.foreign_library, allocator); - free_ast(n.body, allocator); - case Foreign_Import_Decl: - free_ast(n.name, allocator); - free_ast(n.attributes, allocator); - case Proc_Group: - free_ast(n.args, allocator); - case Attribute: - free_ast(n.elems, allocator); - case Field: - free_ast(n.names, allocator); - free_ast(n.type, allocator); - free_ast(n.default_value, allocator); + if node.derived != nil do #partial switch n in node.derived { + case ^Bad_Expr: + case ^Ident: + case ^Implicit: + case ^Undef: + case ^Basic_Directive: + case ^Basic_Lit: + case ^Ellipsis: + free_ast(n.expr, allocator) + case ^Proc_Lit: + free_ast(n.type, allocator) + free_ast(n.body, allocator) + free_ast(n.where_clauses, allocator) + case ^Comp_Lit: + free_ast(n.type, allocator) + free_ast(n.elems, allocator) + case ^Tag_Expr: + free_ast(n.expr, allocator) + case ^Unary_Expr: + free_ast(n.expr, allocator) + case ^Binary_Expr: + free_ast(n.left, allocator) + free_ast(n.right, allocator) + case ^Paren_Expr: + free_ast(n.expr, allocator) + case ^Call_Expr: + free_ast(n.expr, allocator) + free_ast(n.args, allocator) + case ^Selector_Expr: + free_ast(n.expr, allocator) + free_ast(n.field, allocator) + case ^Implicit_Selector_Expr: + free_ast(n.field, allocator) + case ^Index_Expr: + free_ast(n.expr, allocator) + free_ast(n.index, allocator) + case ^Deref_Expr: + free_ast(n.expr, allocator) + case ^Slice_Expr: + free_ast(n.expr, allocator) + free_ast(n.low, allocator) + free_ast(n.high, allocator) + case ^Field_Value: + free_ast(n.field, allocator) + free_ast(n.value, allocator) + case ^Ternary_If_Expr: + free_ast(n.x, allocator) + free_ast(n.cond, allocator) + free_ast(n.y, allocator) + case ^Ternary_When_Expr: + free_ast(n.x, allocator) + free_ast(n.cond, allocator) + free_ast(n.y, allocator) + case ^Type_Assertion: + free_ast(n.expr, allocator) + free_ast(n.type, allocator) + case ^Type_Cast: + free_ast(n.type, allocator) + free_ast(n.expr, allocator) + case ^Auto_Cast: + free_ast(n.expr, allocator) + case ^Bad_Stmt: + case ^Empty_Stmt: + case ^Expr_Stmt: + free_ast(n.expr, allocator) + case ^Tag_Stmt: + r := cast(^Expr_Stmt)node + free_ast(r.expr, allocator) + case ^Assign_Stmt: + free_ast(n.lhs, allocator) + free_ast(n.rhs, allocator) + case ^Block_Stmt: + free_ast(n.label, allocator) + free_ast(n.stmts, allocator) + case ^If_Stmt: + free_ast(n.label, allocator) + free_ast(n.init, allocator) + free_ast(n.cond, allocator) + free_ast(n.body, allocator) + free_ast(n.else_stmt, allocator) + case ^When_Stmt: + free_ast(n.cond, allocator) + free_ast(n.body, allocator) + free_ast(n.else_stmt, allocator) + case ^Return_Stmt: + free_ast(n.results, allocator) + case ^Defer_Stmt: + free_ast(n.stmt, allocator) + case ^For_Stmt: + free_ast(n.label, allocator) + free_ast(n.init, allocator) + free_ast(n.cond, allocator) + free_ast(n.post, allocator) + free_ast(n.body, allocator) + case ^Range_Stmt: + free_ast(n.label, allocator) + free_ast(n.vals, allocator) + free_ast(n.expr, allocator) + free_ast(n.body, allocator) + case ^Case_Clause: + free_ast(n.list, allocator) + free_ast(n.body, allocator) + case ^Switch_Stmt: + free_ast(n.label, allocator) + free_ast(n.init, allocator) + free_ast(n.cond, allocator) + free_ast(n.body, allocator) + case ^Type_Switch_Stmt: + free_ast(n.label, allocator) + free_ast(n.tag, allocator) + free_ast(n.expr, allocator) + free_ast(n.body, allocator) + case ^Branch_Stmt: + free_ast(n.label, allocator) + case ^Using_Stmt: + free_ast(n.list, allocator) + case ^Bad_Decl: + case ^Value_Decl: + free_ast(n.attributes, allocator) + free_ast(n.names, allocator) + free_ast(n.type, allocator) + free_ast(n.values, allocator) + case ^Package_Decl: + case ^Import_Decl: + case ^Foreign_Block_Decl: + free_ast(n.attributes, allocator) + free_ast(n.foreign_library, allocator) + free_ast(n.body, allocator) + case ^Foreign_Import_Decl: + free_ast(n.name, allocator) + free_ast(n.attributes, allocator) + case ^Proc_Group: + free_ast(n.args, allocator) + case ^Attribute: + free_ast(n.elems, allocator) + case ^Field: + free_ast(n.names, allocator) + free_ast(n.type, allocator) + free_ast(n.default_value, allocator) //free_ast(n.docs); //free_ast(n.comment); - case Field_List: - free_ast(n.list, allocator); - case Typeid_Type: - free_ast(n.specialization, allocator); - case Helper_Type: - free_ast(n.type, allocator); - case Distinct_Type: - free_ast(n.type, allocator); - case Poly_Type: - free_ast(n.type, allocator); - free_ast(n.specialization, allocator); - case Proc_Type: - free_ast(n.params, allocator); - free_ast(n.results, allocator); - case Pointer_Type: - free_ast(n.elem, allocator); - case Array_Type: - free_ast(n.len, allocator); - free_ast(n.elem, allocator); - free_ast(n.tag, allocator); - case Dynamic_Array_Type: - free_ast(n.elem, allocator); - free_ast(n.tag, allocator); - case Struct_Type: - free_ast(n.poly_params, allocator); - free_ast(n.align, allocator); - free_ast(n.fields, allocator); - free_ast(n.where_clauses, allocator); - case Union_Type: - free_ast(n.poly_params, allocator); - free_ast(n.align, allocator); - free_ast(n.variants, allocator); - free_ast(n.where_clauses, allocator); - case Enum_Type: - free_ast(n.base_type, allocator); - free_ast(n.fields, allocator); - case Bit_Set_Type: - free_ast(n.elem, allocator); - free_ast(n.underlying, allocator); - case Map_Type: - free_ast(n.key, allocator); - free_ast(n.value, allocator); - case Multi_Pointer_Type: - free_ast(n.elem, allocator); - case Matrix_Type: - free_ast(n.elem, allocator); + case ^Field_List: + free_ast(n.list, allocator) + case ^Typeid_Type: + free_ast(n.specialization, allocator) + case ^Helper_Type: + free_ast(n.type, allocator) + case ^Distinct_Type: + free_ast(n.type, allocator) + case ^Poly_Type: + free_ast(n.type, allocator) + free_ast(n.specialization, allocator) + case ^Proc_Type: + free_ast(n.params, allocator) + free_ast(n.results, allocator) + case ^Pointer_Type: + free_ast(n.elem, allocator) + case ^Array_Type: + free_ast(n.len, allocator) + free_ast(n.elem, allocator) + free_ast(n.tag, allocator) + case ^Dynamic_Array_Type: + free_ast(n.elem, allocator) + free_ast(n.tag, allocator) + case ^Struct_Type: + free_ast(n.poly_params, allocator) + free_ast(n.align, allocator) + free_ast(n.fields, allocator) + free_ast(n.where_clauses, allocator) + case ^Union_Type: + free_ast(n.poly_params, allocator) + free_ast(n.align, allocator) + free_ast(n.variants, allocator) + free_ast(n.where_clauses, allocator) + case ^Enum_Type: + free_ast(n.base_type, allocator) + free_ast(n.fields, allocator) + case ^Bit_Set_Type: + free_ast(n.elem, allocator) + free_ast(n.underlying, allocator) + case ^Map_Type: + free_ast(n.key, allocator) + free_ast(n.value, allocator) + case ^Multi_Pointer_Type: + free_ast(n.elem, allocator) + case ^Matrix_Type: + free_ast(n.elem, allocator) case: - panic(fmt.aprintf("free Unhandled node kind: %T", n)); + panic(fmt.aprintf("free Unhandled node kind: %T", n)) } - mem.free(node, allocator); + mem.free(node, allocator) } free_ast_file :: proc(file: ast.File, allocator := context.allocator) { for decl in file.decls { - free_ast(decl, allocator); + free_ast(decl, allocator) } - free_ast(file.pkg_decl, allocator); + free_ast(file.pkg_decl, allocator) for comment in file.comments { - free_ast(comment, allocator); + free_ast(comment, allocator) } - delete(file.comments); - delete(file.imports); - delete(file.decls); + delete(file.comments) + delete(file.imports) + delete(file.decls) } node_equal :: proc{ node_equal_node, node_equal_array, node_equal_dynamic_array, -}; +} node_equal_array :: proc(a, b: $A/[]^$T) -> bool { - ret := true; + ret := true if len(a) != len(b) { - return false; + return false } for elem, i in a { - ret &= node_equal(elem, b[i]); + ret &= node_equal(elem, b[i]) } - return ret; + return ret } node_equal_dynamic_array :: proc(a, b: $A/[dynamic]^$T) -> bool { - ret := true; + ret := true if len(a) != len(b) { - return false; + return false } for elem, i in a { - ret &= node_equal(elem, b[i]); + ret &= node_equal(elem, b[i]) } - return ret; + return ret } node_equal_node :: proc(a, b: ^ast.Node) -> bool { - - using ast; + using ast if a == nil || b == nil { - return false; + return false } - switch m in b.derived { - case Bad_Expr: - if n, ok := a.derived.(Bad_Expr); ok { - return true; + #partial switch m in b.derived { + case ^Bad_Expr: + if n, ok := a.derived.(^Bad_Expr); ok { + return true } - case Ident: - if n, ok := a.derived.(Ident); ok { - return true; + case ^Ident: + if n, ok := a.derived.(^Ident); ok { + return true //return n.name == m.name; } - case Implicit: - if n, ok := a.derived.(Implicit); ok { - return true; - } - case Undef: - if n, ok := a.derived.(Undef); ok { - return true; - } - case Basic_Lit: - if n, ok := a.derived.(Basic_Lit); ok { - return true; - } - case Poly_Type: - return true; - case Ellipsis: - if n, ok := a.derived.(Ellipsis); ok { - return node_equal(n.expr, m.expr); - } - case Tag_Expr: - if n, ok := a.derived.(Tag_Expr); ok { - return node_equal(n.expr, m.expr); - } - case Unary_Expr: - if n, ok := a.derived.(Unary_Expr); ok { - return node_equal(n.expr, m.expr); - } - case Binary_Expr: - if n, ok := a.derived.(Binary_Expr); ok { - ret := node_equal(n.left, m.left); - ret &= node_equal(n.right, m.right); - return ret; - } - case Paren_Expr: - if n, ok := a.derived.(Paren_Expr); ok { - return node_equal(n.expr, m.expr); - } - case Selector_Expr: - if n, ok := a.derived.(Selector_Expr); ok { - ret := node_equal(n.expr, m.expr); - ret &= node_equal(n.field, m.field); - return ret; - } - case Slice_Expr: - if n, ok := a.derived.(Slice_Expr); ok { - ret := node_equal(n.expr, m.expr); - ret &= node_equal(n.low, m.low); - ret &= node_equal(n.high, m.high); - return ret; - } - case Distinct_Type: - if n, ok := a.derived.(Distinct_Type); ok { - return node_equal(n.type, m.type); - } - case Proc_Type: - if n, ok := a.derived.(Proc_Type); ok { - ret := node_equal(n.params, m.params); - ret &= node_equal(n.results, m.results); - return ret; - } - case Pointer_Type: - if n, ok := a.derived.(Pointer_Type); ok { - return node_equal(n.elem, m.elem); - } - case Array_Type: - if n, ok := a.derived.(Array_Type); ok { - ret := node_equal(n.elem, m.elem); + case ^Implicit: + if n, ok := a.derived.(^Implicit); ok { + return true + } + case ^Undef: + if n, ok := a.derived.(^Undef); ok { + return true + } + case ^Basic_Lit: + if n, ok := a.derived.(^Basic_Lit); ok { + return true + } + case ^Poly_Type: + return true + case ^Ellipsis: + if n, ok := a.derived.(^Ellipsis); ok { + return node_equal(n.expr, m.expr) + } + case ^Tag_Expr: + if n, ok := a.derived.(^Tag_Expr); ok { + return node_equal(n.expr, m.expr) + } + case ^Unary_Expr: + if n, ok := a.derived.(^Unary_Expr); ok { + return node_equal(n.expr, m.expr) + } + case ^Binary_Expr: + if n, ok := a.derived.(^Binary_Expr); ok { + ret := node_equal(n.left, m.left) + ret &= node_equal(n.right, m.right) + return ret + } + case ^Paren_Expr: + if n, ok := a.derived.(^Paren_Expr); ok { + return node_equal(n.expr, m.expr) + } + case ^Selector_Expr: + if n, ok := a.derived.(^Selector_Expr); ok { + ret := node_equal(n.expr, m.expr) + ret &= node_equal(n.field, m.field) + return ret + } + case ^Slice_Expr: + if n, ok := a.derived.(^Slice_Expr); ok { + ret := node_equal(n.expr, m.expr) + ret &= node_equal(n.low, m.low) + ret &= node_equal(n.high, m.high) + return ret + } + case ^Distinct_Type: + if n, ok := a.derived.(^Distinct_Type); ok { + return node_equal(n.type, m.type) + } + case ^Proc_Type: + if n, ok := a.derived.(^Proc_Type); ok { + ret := node_equal(n.params, m.params) + ret &= node_equal(n.results, m.results) + return ret + } + case ^Pointer_Type: + if n, ok := a.derived.(^Pointer_Type); ok { + return node_equal(n.elem, m.elem) + } + case ^Array_Type: + if n, ok := a.derived.(^Array_Type); ok { + ret := node_equal(n.elem, m.elem) if n.len != nil && m.len != nil { - ret &= node_equal(n.len, m.len); + ret &= node_equal(n.len, m.len) } - return ret; - } - case Dynamic_Array_Type: - if n, ok := a.derived.(Dynamic_Array_Type); ok { - return node_equal(n.elem, m.elem); - } - case Struct_Type: - if n, ok := a.derived.(Struct_Type); ok { - ret := node_equal(n.poly_params, m.poly_params); - ret &= node_equal(n.align, m.align); - ret &= node_equal(n.fields, m.fields); - return ret; - } - case Field: - if n, ok := a.derived.(Field); ok { - ret := node_equal(n.names, m.names); - ret &= node_equal(n.type, m.type); - ret &= node_equal(n.default_value, m.default_value); - return ret; - } - case Field_List: - if n, ok := a.derived.(Field_List); ok { - return node_equal(n.list, m.list); - } - case Field_Value: - if n, ok := a.derived.(Field_Value); ok { - ret := node_equal(n.field, m.field); - ret &= node_equal(n.value, m.value); - return ret; - } - case Union_Type: - if n, ok := a.derived.(Union_Type); ok { - ret := node_equal(n.poly_params, m.poly_params); - ret &= node_equal(n.align, m.align); - ret &= node_equal(n.variants, m.variants); - return ret; - } - case Enum_Type: - if n, ok := a.derived.(Enum_Type); ok { - ret := node_equal(n.base_type, m.base_type); - ret &= node_equal(n.fields, m.fields); - return ret; - } - case Bit_Set_Type: - if n, ok := a.derived.(Bit_Set_Type); ok { - ret := node_equal(n.elem, m.elem); - ret &= node_equal(n.underlying, m.underlying); - return ret; - } - case Map_Type: - if n, ok := a.derived.(Map_Type); ok { - ret := node_equal(n.key, m.key); - ret &= node_equal(n.value, m.value); - return ret; - } - case Call_Expr: - if n, ok := a.derived.(Call_Expr); ok { - ret := node_equal(n.expr, m.expr); - ret &= node_equal(n.args, m.args); - return ret; - } - case Typeid_Type: - return true; + return ret + } + case ^Dynamic_Array_Type: + if n, ok := a.derived.(^Dynamic_Array_Type); ok { + return node_equal(n.elem, m.elem) + } + case ^Struct_Type: + if n, ok := a.derived.(^Struct_Type); ok { + ret := node_equal(n.poly_params, m.poly_params) + ret &= node_equal(n.align, m.align) + ret &= node_equal(n.fields, m.fields) + return ret + } + case ^Field: + if n, ok := a.derived.(^Field); ok { + ret := node_equal(n.names, m.names) + ret &= node_equal(n.type, m.type) + ret &= node_equal(n.default_value, m.default_value) + return ret + } + case ^Field_List: + if n, ok := a.derived.(^Field_List); ok { + return node_equal(n.list, m.list) + } + case ^Field_Value: + if n, ok := a.derived.(^Field_Value); ok { + ret := node_equal(n.field, m.field) + ret &= node_equal(n.value, m.value) + return ret + } + case ^Union_Type: + if n, ok := a.derived.(^Union_Type); ok { + ret := node_equal(n.poly_params, m.poly_params) + ret &= node_equal(n.align, m.align) + ret &= node_equal(n.variants, m.variants) + return ret + } + case ^Enum_Type: + if n, ok := a.derived.(^Enum_Type); ok { + ret := node_equal(n.base_type, m.base_type) + ret &= node_equal(n.fields, m.fields) + return ret + } + case ^Bit_Set_Type: + if n, ok := a.derived.(^Bit_Set_Type); ok { + ret := node_equal(n.elem, m.elem) + ret &= node_equal(n.underlying, m.underlying) + return ret + } + case ^Map_Type: + if n, ok := a.derived.(^Map_Type); ok { + ret := node_equal(n.key, m.key) + ret &= node_equal(n.value, m.value) + return ret + } + case ^Call_Expr: + if n, ok := a.derived.(^Call_Expr); ok { + ret := node_equal(n.expr, m.expr) + ret &= node_equal(n.args, m.args) + return ret + } + case ^Typeid_Type: + return true case: - log.warn("Unhandled poly node kind: %T", m); + log.warn("Unhandled poly node kind: %T", m) } - return false; + return false } /* @@ -712,199 +703,198 @@ node_equal_node :: proc(a, b: ^ast.Node) -> bool { */ node_to_string :: proc(node: ^ast.Node) -> string { - builder := strings.make_builder(context.temp_allocator); + builder := strings.make_builder(context.temp_allocator) - build_string(node, &builder); + build_string(node, &builder) - return strings.to_string(builder); + return strings.to_string(builder) } build_string :: proc{ build_string_ast_array, build_string_dynamic_array, build_string_node, -}; +} build_string_dynamic_array :: proc(array: $A/[]^$T, builder: ^strings.Builder) { for elem, i in array { - build_string(elem, builder); + build_string(elem, builder) } } build_string_ast_array :: proc(array: $A/[dynamic]^$T, builder: ^strings.Builder) { for elem, i in array { - build_string(elem, builder); + build_string(elem, builder) } } build_string_node :: proc(node: ^ast.Node, builder: ^strings.Builder) { - using ast; + using ast if node == nil { - return; + return } - switch n in node.derived { - case Bad_Expr: - case Ident: + #partial switch n in node.derived { + case ^Bad_Expr: + case ^Ident: if strings.contains(n.name, "/") { - strings.write_string(builder, path.base(n.name, false, context.temp_allocator)); + strings.write_string(builder, path.base(n.name, false, context.temp_allocator)) } else { - strings.write_string(builder, n.name); - } - case Implicit: - strings.write_string(builder, n.tok.text); - case Undef: - case Basic_Lit: - strings.write_string(builder, n.tok.text); - case Basic_Directive: - strings.write_string(builder, n.name); - case Implicit_Selector_Expr: - strings.write_string(builder, "."); - build_string(n.field, builder); - case Ellipsis: - strings.write_string(builder, ".."); - build_string(n.expr, builder); - case Proc_Lit: - build_string(n.type, builder); - build_string(n.body, builder); - case Comp_Lit: - build_string(n.type, builder); - strings.write_string(builder, "{"); - build_string(n.elems, builder); - strings.write_string(builder, "}"); - case Tag_Expr: - build_string(n.expr, builder); - case Unary_Expr: - build_string(n.expr, builder); - case Binary_Expr: - build_string(n.left, builder); - build_string(n.right, builder); - case Paren_Expr: - strings.write_string(builder, "("); - build_string(n.expr, builder); - strings.write_string(builder, ")"); - case Call_Expr: - build_string(n.expr, builder); - strings.write_string(builder, "("); + strings.write_string(builder, n.name) + } + case ^Implicit: + strings.write_string(builder, n.tok.text) + case ^Undef: + case ^Basic_Lit: + strings.write_string(builder, n.tok.text) + case ^Basic_Directive: + strings.write_string(builder, n.name) + case ^Implicit_Selector_Expr: + strings.write_string(builder, ".") + build_string(n.field, builder) + case ^Ellipsis: + strings.write_string(builder, "..") + build_string(n.expr, builder) + case ^Proc_Lit: + build_string(n.type, builder) + build_string(n.body, builder) + case ^Comp_Lit: + build_string(n.type, builder) + strings.write_string(builder, "{") + build_string(n.elems, builder) + strings.write_string(builder, "}") + case ^Tag_Expr: + build_string(n.expr, builder) + case ^Unary_Expr: + build_string(n.expr, builder) + case ^Binary_Expr: + build_string(n.left, builder) + build_string(n.right, builder) + case ^Paren_Expr: + strings.write_string(builder, "(") + build_string(n.expr, builder) + strings.write_string(builder, ")") + case ^Call_Expr: + build_string(n.expr, builder) + strings.write_string(builder, "(") for arg, i in n.args { - build_string(arg, builder); + build_string(arg, builder) if len(n.args) - 1 != i { - strings.write_string(builder, ", "); + strings.write_string(builder, ", ") } } - strings.write_string(builder, ")"); - case Selector_Expr: - build_string(n.expr, builder); - strings.write_string(builder, "."); - build_string(n.field, builder); - case Index_Expr: - build_string(n.expr, builder); - strings.write_string(builder, "["); - build_string(n.index, builder); - strings.write_string(builder, "]"); - case Deref_Expr: - build_string(n.expr, builder); - case Slice_Expr: - build_string(n.expr, builder); - build_string(n.low, builder); - build_string(n.high, builder); - case Field_Value: - build_string(n.field, builder); - strings.write_string(builder, ": "); - build_string(n.value, builder); - case Type_Cast: - build_string(n.type, builder); - build_string(n.expr, builder); - case Bad_Stmt: - case Bad_Decl: - case Attribute: - build_string(n.elems, builder); - case Field: - + strings.write_string(builder, ")") + case ^Selector_Expr: + build_string(n.expr, builder) + strings.write_string(builder, ".") + build_string(n.field, builder) + case ^Index_Expr: + build_string(n.expr, builder) + strings.write_string(builder, "[") + build_string(n.index, builder) + strings.write_string(builder, "]") + case ^Deref_Expr: + build_string(n.expr, builder) + case ^Slice_Expr: + build_string(n.expr, builder) + build_string(n.low, builder) + build_string(n.high, builder) + case ^Field_Value: + build_string(n.field, builder) + strings.write_string(builder, ": ") + build_string(n.value, builder) + case ^Type_Cast: + build_string(n.type, builder) + build_string(n.expr, builder) + case ^Bad_Stmt: + case ^Bad_Decl: + case ^Attribute: + build_string(n.elems, builder) + case ^Field: for name, i in n.names { - build_string(name, builder); + build_string(name, builder) if len(n.names) - 1 != i { - strings.write_string(builder, ", "); + strings.write_string(builder, ", ") } } if len(n.names) > 0 && n.type != nil { - strings.write_string(builder, ": "); - build_string(n.type, builder); + strings.write_string(builder, ": ") + build_string(n.type, builder) if n.default_value != nil && n.type != nil { - strings.write_string(builder, " = "); + strings.write_string(builder, " = ") } } else if len(n.names) > 0 && n.default_value != nil { - strings.write_string(builder, " := "); + strings.write_string(builder, " := ") } else { - build_string(n.type, builder); + build_string(n.type, builder) } - build_string(n.default_value, builder); - case Field_List: + build_string(n.default_value, builder) + case ^Field_List: for field, i in n.list { - build_string(field, builder); + build_string(field, builder) if len(n.list) - 1 != i { - strings.write_string(builder, ","); + strings.write_string(builder, ",") } } - case Typeid_Type: - strings.write_string(builder, "$"); - build_string(n.specialization, builder); - case Helper_Type: - build_string(n.type, builder); - case Distinct_Type: - build_string(n.type, builder); - case Poly_Type: - strings.write_string(builder, "$"); + case ^Typeid_Type: + strings.write_string(builder, "$") + build_string(n.specialization, builder) + case ^Helper_Type: + build_string(n.type, builder) + case ^Distinct_Type: + build_string(n.type, builder) + case ^Poly_Type: + strings.write_string(builder, "$") - build_string(n.type, builder); + build_string(n.type, builder) if n.specialization != nil { - strings.write_string(builder, "/"); - build_string(n.specialization, builder); - } - case Proc_Type: - strings.write_string(builder, "proc("); - build_string(n.params, builder); - strings.write_string(builder, ") -> "); - build_string(n.results, builder); - case Pointer_Type: - strings.write_string(builder, "^"); - build_string(n.elem, builder); - case Array_Type: - strings.write_string(builder, "["); - build_string(n.len, builder); - strings.write_string(builder, "]"); - build_string(n.elem, builder); - case Dynamic_Array_Type: - strings.write_string(builder, "[dynamic]"); - build_string(n.elem, builder); - case Struct_Type: - build_string(n.poly_params, builder); - build_string(n.align, builder); - build_string(n.fields, builder); - case Union_Type: - build_string(n.poly_params, builder); - build_string(n.align, builder); - build_string(n.variants, builder); - case Enum_Type: - build_string(n.base_type, builder); - build_string(n.fields, builder); - case Bit_Set_Type: - build_string(n.elem, builder); - build_string(n.underlying, builder); - case Map_Type: - strings.write_string(builder, "map"); - strings.write_string(builder, "["); - build_string(n.key, builder); - strings.write_string(builder, "]"); - build_string(n.value, builder); + strings.write_string(builder, "/") + build_string(n.specialization, builder) + } + case ^Proc_Type: + strings.write_string(builder, "proc(") + build_string(n.params, builder) + strings.write_string(builder, ") -> ") + build_string(n.results, builder) + case ^Pointer_Type: + strings.write_string(builder, "^") + build_string(n.elem, builder) + case ^Array_Type: + strings.write_string(builder, "[") + build_string(n.len, builder) + strings.write_string(builder, "]") + build_string(n.elem, builder) + case ^Dynamic_Array_Type: + strings.write_string(builder, "[dynamic]") + build_string(n.elem, builder) + case ^Struct_Type: + build_string(n.poly_params, builder) + build_string(n.align, builder) + build_string(n.fields, builder) + case ^Union_Type: + build_string(n.poly_params, builder) + build_string(n.align, builder) + build_string(n.variants, builder) + case ^Enum_Type: + build_string(n.base_type, builder) + build_string(n.fields, builder) + case ^Bit_Set_Type: + build_string(n.elem, builder) + build_string(n.underlying, builder) + case ^Map_Type: + strings.write_string(builder, "map") + strings.write_string(builder, "[") + build_string(n.key, builder) + strings.write_string(builder, "]") + build_string(n.value, builder) } } diff --git a/src/common/fuzzy.odin b/src/common/fuzzy.odin index 68223e0..f6c8b11 100644 --- a/src/common/fuzzy.odin +++ b/src/common/fuzzy.odin @@ -7,15 +7,15 @@ import "core:fmt" Ported from https://github.com/llvm/llvm-project/blob/master/clang-tools-extra/clangd/FuzzyMatch.cpp */ -max_pattern :: 63; -max_word :: 127; +max_pattern :: 63 +max_word :: 127 -awful_score: int = -(1 << 13); -perfect_bonus :: 4; -miss :: 0; -match :: 1; +awful_score: int = -(1 << 13) +perfect_bonus :: 4 +miss :: 0 +match :: 1 -FuzzyCharTypeSet :: u8; +FuzzyCharTypeSet :: u8 //do bitfield instead FuzzyScoreInfo :: struct { @@ -60,7 +60,7 @@ char_roles: []u8 = { /*Prev=Upper */0x00,0x55,0x59,0xff, // Ditto, but U(U)U->Tail /*Prev=Separ */0x00,0xaa,0xaa,0xff, // After separator, like at start // clang-format on -}; +} char_types: []u8 = { 0x00,0x00,0x00,0x00, // Control characters @@ -75,266 +75,266 @@ char_types: []u8 = { 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, // (probably UTF-8). 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, -}; +} make_fuzzy_matcher :: proc(pattern: string, allocator := context.temp_allocator) -> ^FuzzyMatcher { - matcher := new(FuzzyMatcher, allocator); + matcher := new(FuzzyMatcher, allocator) - matcher.pattern_count = min(len(pattern), max_pattern); - matcher.score_scale = matcher.pattern_count > 0 ? 1 / cast(f32)(perfect_bonus * matcher.pattern_count) : 0; - matcher.pattern = pattern[0:matcher.pattern_count]; - matcher.lower_pattern = strings.to_lower(matcher.pattern, context.temp_allocator); + matcher.pattern_count = min(len(pattern), max_pattern) + matcher.score_scale = matcher.pattern_count > 0 ? 1 / cast(f32)(perfect_bonus * matcher.pattern_count) : 0 + matcher.pattern = pattern[0:matcher.pattern_count] + matcher.lower_pattern = strings.to_lower(matcher.pattern, context.temp_allocator) - score_info_miss: FuzzyScoreInfo; - score_info_miss.score = 0; - score_info_miss.prev = miss; + score_info_miss: FuzzyScoreInfo + score_info_miss.score = 0 + score_info_miss.prev = miss - matcher.scores[0][0][miss] = score_info_miss; + matcher.scores[0][0][miss] = score_info_miss - score_info_match: FuzzyScoreInfo; - score_info_match.score = awful_score; - score_info_match.prev = match; + score_info_match: FuzzyScoreInfo + score_info_match.score = awful_score + score_info_match.prev = match - matcher.scores[0][0][match] = score_info_match; + matcher.scores[0][0][match] = score_info_match for p := 0; p < matcher.pattern_count; p += 1 { for w := 0; w < p; w += 1 { for a := 0; a < 2; a += 1 { - score_info: FuzzyScoreInfo; - score_info.score = awful_score; - score_info.prev = miss; - matcher.scores[p][w][a] = score_info; - ref := matcher.pattern_role[:matcher.pattern_count]; - matcher.pattern_type_set = fuzzy_calculate_roles(matcher.pattern, &ref); + score_info: FuzzyScoreInfo + score_info.score = awful_score + score_info.prev = miss + matcher.scores[p][w][a] = score_info + ref := matcher.pattern_role[:matcher.pattern_count] + matcher.pattern_type_set = fuzzy_calculate_roles(matcher.pattern, &ref) } } } - return matcher; + return matcher } fuzzy_to_acronym :: proc(word: string) -> (string, bool) { - builder := strings.make_builder(context.temp_allocator); + builder := strings.make_builder(context.temp_allocator) if len(word) <= 1 { - return "", false; + return "", false } - i := 1; - last_char := word[0]; + i := 1 + last_char := word[0] - strings.write_byte(&builder, last_char); + strings.write_byte(&builder, last_char) for i < len(word) { if last_char == '_' { - strings.write_byte(&builder, word[i]); + strings.write_byte(&builder, word[i]) } - last_char = word[i]; + last_char = word[i] - i += 1; + i += 1 } - str := strings.to_string(builder); + str := strings.to_string(builder) if len(str) <= 1 { - return "", false; + return "", false } - return str, true; + return str, true } //changed from bool to int because of a linux bug - 10.05.2021 fuzzy_match :: proc(matcher: ^FuzzyMatcher, word: string) -> (f32, int) { if !fuzzy_init(matcher, word) { - return 0, 0; + return 0, 0 } if matcher.pattern_count <= 0 { - return 1, 1; + return 1, 1 } if acronym, ok := fuzzy_to_acronym(word); ok { if acronym == matcher.pattern { - return 20, 1; + return 20, 1 } } - fuzzy_build_graph(matcher); + fuzzy_build_graph(matcher) best := max(cast(int)matcher.scores[matcher.pattern_count][matcher.word_count][miss].score, - cast(int)matcher.scores[matcher.pattern_count][matcher.word_count][match].score); + cast(int)matcher.scores[matcher.pattern_count][matcher.word_count][match].score) if fuzzy_is_awful(best) { - return 0.0, 0; + return 0.0, 0 } - score := matcher.score_scale * min(perfect_bonus * cast(f32)matcher.pattern_count, cast(f32)max(0, best)); + score := matcher.score_scale * min(perfect_bonus * cast(f32)matcher.pattern_count, cast(f32)max(0, best)) if matcher.word_count == matcher.pattern_count { - score *= 2; + score *= 2 } - return score, 1; + return score, 1 } fuzzy_is_awful :: proc(s: int) -> bool { - return s < awful_score / 2; + return s < awful_score / 2 } fuzzy_calculate_roles :: proc(text: string, roles: ^[]FuzzyCharRole) -> FuzzyCharTypeSet { - assert(len(text) == len(roles)); + assert(len(text) == len(roles)) if len(text) == 0 { - return 0; + return 0 } - type: FuzzyCharType = cast(FuzzyCharType)fuzzy_packed_lookup(char_types, cast(uint)text[0]); + type: FuzzyCharType = cast(FuzzyCharType)fuzzy_packed_lookup(char_types, cast(uint)text[0]) - type_set: FuzzyCharTypeSet = cast(u8)(1 << cast(uint)type); + type_set: FuzzyCharTypeSet = cast(u8)(1 << cast(uint)type) - types := type; + types := type for i := 0; i < len(text) - 1; i += 1 { - type = cast(FuzzyCharType)fuzzy_packed_lookup(char_types, cast(uint)text[i + 1]); - type_set |= 1 << cast(uint)type; + type = cast(FuzzyCharType)fuzzy_packed_lookup(char_types, cast(uint)text[i + 1]) + type_set |= 1 << cast(uint)type - fuzzy_rotate(type, &types); + fuzzy_rotate(type, &types) - roles[i] = cast(FuzzyCharRole)fuzzy_packed_lookup(char_roles, cast(uint)types); + roles[i] = cast(FuzzyCharRole)fuzzy_packed_lookup(char_roles, cast(uint)types) } - fuzzy_rotate(.Empty, &types); + fuzzy_rotate(.Empty, &types) - roles[len(text) - 1] = cast(FuzzyCharRole)fuzzy_packed_lookup(char_roles, cast(uint)types); + roles[len(text) - 1] = cast(FuzzyCharRole)fuzzy_packed_lookup(char_roles, cast(uint)types) - return type_set; + return type_set } fuzzy_rotate :: proc(t: FuzzyCharType, types: ^FuzzyCharType) { - types^ = cast(FuzzyCharType)(((cast(uint)types^ << 2) | cast(uint)t) & 0x3f); + types^ = cast(FuzzyCharType)(((cast(uint)types^ << 2) | cast(uint)t) & 0x3f) } fuzzy_packed_lookup :: proc(data: $A/[]$T, i: uint) -> T { - return (data[i >> 2] >> ((i & 3) * 2)) & 3; + return (data[i >> 2] >> ((i & 3) * 2)) & 3 } fuzzy_init :: proc(matcher: ^FuzzyMatcher, word: string) -> bool { - matcher.word = word; - matcher.word_count = min(max_word, len(matcher.word)); + matcher.word = word + matcher.word_count = min(max_word, len(matcher.word)) if matcher.pattern_count > matcher.word_count { - return false; + return false } if matcher.pattern_count == 0 { - return true; + return true } - matcher.lower_word = strings.to_lower(word, context.temp_allocator); + matcher.lower_word = strings.to_lower(word, context.temp_allocator) - w, p := 0, 0; + w, p := 0, 0 for ; p != matcher.pattern_count; w += 1 { if w == matcher.word_count { - return false; + return false } if matcher.lower_word[w] == matcher.lower_pattern[p] { - p += 1; + p += 1 } } - ref := matcher.word_role[:matcher.word_count]; + ref := matcher.word_role[:matcher.word_count] - matcher.word_type_set = fuzzy_calculate_roles(word, &ref); + matcher.word_type_set = fuzzy_calculate_roles(word, &ref) - return true; + return true } fuzzy_skip_penalty :: proc(matcher: ^FuzzyMatcher, w: int) -> int { if w == 0 { // Skipping the first character. - return 3; + return 3 } if matcher.word_role[w] == .Head { // Skipping a segment. - return 1; + return 1 } - return 0; + return 0 } fuzzy_build_graph :: proc(matcher: ^FuzzyMatcher) { for w := 0; w < matcher.word_count; w += 1 { - s: FuzzyScoreInfo; + s: FuzzyScoreInfo - score := cast(int)matcher.scores[0][w][miss].score; - penalty := fuzzy_skip_penalty(matcher, w); - sum := score - penalty; + score := cast(int)matcher.scores[0][w][miss].score + penalty := fuzzy_skip_penalty(matcher, w) + sum := score - penalty - s.score = sum; - s.prev = miss; + s.score = sum + s.prev = miss - matcher.scores[0][w + 1][miss] = s; + matcher.scores[0][w + 1][miss] = s - s.score = awful_score; - s.prev = miss; + s.score = awful_score + s.prev = miss - matcher.scores[0][w + 1][match] = s; + matcher.scores[0][w + 1][match] = s } for p := 0; p < matcher.pattern_count; p += 1 { for w := p; w < matcher.word_count; w += 1 { - score := &matcher.scores[p + 1][w + 1]; - pre_miss := &matcher.scores[p + 1][w]; + score := &matcher.scores[p + 1][w + 1] + pre_miss := &matcher.scores[p + 1][w] - match_miss_score := pre_miss[match].score; - miss_miss_score := pre_miss[miss].score; + match_miss_score := pre_miss[match].score + miss_miss_score := pre_miss[miss].score if p < matcher.pattern_count - 1 { - match_miss_score -= fuzzy_skip_penalty(matcher, w); - miss_miss_score -= fuzzy_skip_penalty(matcher, w); + match_miss_score -= fuzzy_skip_penalty(matcher, w) + miss_miss_score -= fuzzy_skip_penalty(matcher, w) } if match_miss_score > miss_miss_score { - s: FuzzyScoreInfo; - s.score = match_miss_score; - s.prev = match; - score[miss] = s; + s: FuzzyScoreInfo + s.score = match_miss_score + s.prev = match + score[miss] = s } else { - s: FuzzyScoreInfo; - s.score = miss_miss_score; - s.prev = miss; - score[miss] = s; + s: FuzzyScoreInfo + s.score = miss_miss_score + s.prev = miss + score[miss] = s } - pre_match := &matcher.scores[p][w]; + pre_match := &matcher.scores[p][w] - match_match_score := fuzzy_allow_match(matcher, p, w, match) ? cast(int)pre_match[match].score + fuzzy_match_bonus(matcher, p, w, match) : awful_score; + match_match_score := fuzzy_allow_match(matcher, p, w, match) ? cast(int)pre_match[match].score + fuzzy_match_bonus(matcher, p, w, match) : awful_score - miss_match_score := fuzzy_allow_match(matcher, p, w, miss) ? cast(int)pre_match[miss].score + fuzzy_match_bonus(matcher, p, w, miss) : awful_score; + miss_match_score := fuzzy_allow_match(matcher, p, w, miss) ? cast(int)pre_match[miss].score + fuzzy_match_bonus(matcher, p, w, miss) : awful_score if match_match_score > miss_match_score { - s: FuzzyScoreInfo; - s.score = match_match_score; - s.prev = match; - score[match] = s; + s: FuzzyScoreInfo + s.score = match_match_score + s.prev = match + score[match] = s } else { - s: FuzzyScoreInfo; - s.score = miss_match_score; - s.prev = miss; - score[match] = s; + s: FuzzyScoreInfo + s.score = miss_match_score + s.prev = miss + score[match] = s } } } @@ -342,12 +342,12 @@ fuzzy_build_graph :: proc(matcher: ^FuzzyMatcher) { fuzzy_match_bonus :: proc(matcher: ^FuzzyMatcher, p: int, w: int, last: int) -> int { - assert(matcher.lower_pattern[p] == matcher.lower_word[w]); + assert(matcher.lower_pattern[p] == matcher.lower_word[w]) - s := 1; + s := 1 - is_pattern_single_case := (cast(uint)matcher.pattern_type_set == 1 << cast(uint)FuzzyCharType.Lower); - is_pattern_single_case |= (cast(uint)matcher.pattern_type_set == 1 << cast(uint)FuzzyCharType.Upper); + is_pattern_single_case := (cast(uint)matcher.pattern_type_set == 1 << cast(uint)FuzzyCharType.Lower) + is_pattern_single_case |= (cast(uint)matcher.pattern_type_set == 1 << cast(uint)FuzzyCharType.Upper) // Bonus: case matches, or a Head in the pattern aligns with one in the word. // Single-case patterns lack segmentation signals and we assume any character @@ -355,53 +355,53 @@ fuzzy_match_bonus :: proc(matcher: ^FuzzyMatcher, p: int, w: int, last: int) -> if matcher.pattern[p] == matcher.word[w] || (matcher.word_role[w] == FuzzyCharRole.Head && (is_pattern_single_case || matcher.pattern_role[p] == FuzzyCharRole.Head)) { - s += 1; + s += 1 //fmt.println("match 1"); } // Bonus: a consecutive match. First character match also gets a bonus to // ensure prefix final match score normalizes to 1.0. if w == 0 || last == match { - s += 2; + s += 2 //fmt.println("match 2"); } // Penalty: matching inside a segment (and previous char wasn't matched). if matcher.word_role[w] == FuzzyCharRole.Tail && p > 0 && last == miss { - s -= 3; + s -= 3 //fmt.println("match 3"); } // Penalty: a Head in the pattern matches in the middle of a word segment. if matcher.pattern_role[p] == FuzzyCharRole.Head && matcher.word_role[w] == FuzzyCharRole.Tail { - s -= 1; + s -= 1 //fmt.println("match 4"); } // Penalty: matching the first pattern character in the middle of a segment. if p == 0 && matcher.word_role[w] == FuzzyCharRole.Tail { - s -= 4; + s -= 4 //fmt.println("match 5"); } - assert(s <= perfect_bonus); + assert(s <= perfect_bonus) - return s; + return s } fuzzy_allow_match :: proc(matcher: ^FuzzyMatcher, p: int, w: int, last: int) -> bool { if matcher.lower_pattern[p] != matcher.lower_word[w] { - return false; + return false } if last == miss { if matcher.word_role[w] == FuzzyCharRole.Tail && (matcher.word[w] == matcher.lower_word[w] || 0 >= (cast(uint)matcher.word_type_set & 1 << cast(uint)FuzzyCharType.Lower)) { - return false; + return false } } - return true; + return true } diff --git a/src/common/position.odin b/src/common/position.odin index 4e84568..2ccd0a8 100644 --- a/src/common/position.odin +++ b/src/common/position.odin @@ -31,219 +31,219 @@ AbsoluteRange :: struct { end: int, } -AbsolutePosition :: int; +AbsolutePosition :: int get_absolute_position :: proc(position: Position, document_text: []u8) -> (AbsolutePosition, bool) { - absolute: AbsolutePosition; + absolute: AbsolutePosition if len(document_text) == 0 { - absolute = 0; - return absolute, true; + absolute = 0 + return absolute, true } - line_count := 0; - index := 1; - last := document_text[0]; + line_count := 0 + index := 1 + last := document_text[0] if !get_index_at_line(&index, &line_count, &last, document_text, position.line) { - return absolute, false; + return absolute, false } - absolute = index + get_character_offset_u16_to_u8(position.character, document_text[index:]); + absolute = index + get_character_offset_u16_to_u8(position.character, document_text[index:]) - return absolute, true; + return absolute, true } get_relative_token_position :: proc(offset: int, document_text: []u8, current_start: int) -> Position { - start_index := current_start; + start_index := current_start - data := document_text[start_index:]; + data := document_text[start_index:] - i: int; + i: int - position: Position; + position: Position for i + start_index < offset { - r, w := utf8.decode_rune(data[i:]); + r, w := utf8.decode_rune(data[i:]) if r == '\n' { //\r? - position.character = 0; - position.line += 1; - i += 1; + position.character = 0 + position.line += 1 + i += 1 } else if w == 0 { - return position; + return position } else { if r < 0x10000 { - position.character += 1; + position.character += 1 } else { - position.character += 2; + position.character += 2 } - i += w; + i += w } } - return position; + return position } /* Get the range of a token in utf16 space */ get_token_range :: proc(node: ast.Node, document_text: string) -> Range { - range: Range; + range: Range go_backwards_to_endline :: proc(offset: int, document_text: []u8) -> int { - index := offset; + index := offset for index > 0 && document_text[index] != '\n' && document_text[index] != '\r' { - index -= 1; + index -= 1 } if index == 0 { - return 0; + return 0 } - return index + 1; - }; + return index + 1 + } - pos_offset := min(len(document_text) - 1, node.pos.offset); - end_offset := min(len(document_text) - 1, node.end.offset); + pos_offset := min(len(document_text) - 1, node.pos.offset) + end_offset := min(len(document_text) - 1, node.end.offset) - offset := go_backwards_to_endline(pos_offset, transmute([]u8)document_text); + offset := go_backwards_to_endline(pos_offset, transmute([]u8)document_text) - range.start.line = node.pos.line - 1; - range.start.character = get_character_offset_u8_to_u16(node.pos.column - 1, transmute([]u8)document_text[offset:]); + range.start.line = node.pos.line - 1 + range.start.character = get_character_offset_u8_to_u16(node.pos.column - 1, transmute([]u8)document_text[offset:]) - offset = go_backwards_to_endline(end_offset, transmute([]u8)document_text); + offset = go_backwards_to_endline(end_offset, transmute([]u8)document_text) - range.end.line = node.end.line - 1; - range.end.character = get_character_offset_u8_to_u16(node.end.column - 1, transmute([]u8)document_text[offset:]); + range.end.line = node.end.line - 1 + range.end.character = get_character_offset_u8_to_u16(node.end.column - 1, transmute([]u8)document_text[offset:]) - return range; + return range } get_absolute_range :: proc(range: Range, document_text: []u8) -> (AbsoluteRange, bool) { - absolute: AbsoluteRange; + absolute: AbsoluteRange if len(document_text) == 0 { - absolute.start = 0; - absolute.end = 0; - return absolute, true; + absolute.start = 0 + absolute.end = 0 + return absolute, true } - line_count := 0; - index := 1; - last := document_text[0]; + line_count := 0 + index := 1 + last := document_text[0] if !get_index_at_line(&index, &line_count, &last, document_text, range.start.line) { - return absolute, false; + return absolute, false } - absolute.start = index + get_character_offset_u16_to_u8(range.start.character, document_text[index:]); + absolute.start = index + get_character_offset_u16_to_u8(range.start.character, document_text[index:]) //if the last line was indexed at zero we have to move it back to index 1. //This happens when line = 0 if index == 0 { - index = 1; + index = 1 } if !get_index_at_line(&index, &line_count, &last, document_text, range.end.line) { - return absolute, false; + return absolute, false } - absolute.end = index + get_character_offset_u16_to_u8(range.end.character, document_text[index:]); + absolute.end = index + get_character_offset_u16_to_u8(range.end.character, document_text[index:]) - return absolute, true; + return absolute, true } get_index_at_line :: proc(current_index: ^int, current_line: ^int, last: ^u8, document_text: []u8, end_line: int) -> bool { if end_line == 0 { - current_index^ = 0; - return true; + current_index^ = 0 + return true } if current_line^ == end_line { - return true; + return true } for ; current_index^ < len(document_text); current_index^ += 1 { - current := document_text[current_index^]; + current := document_text[current_index^] if last^ == '\r' { - current_line^ += 1; + current_line^ += 1 if current_line^ == end_line { - last^ = current; - current_index^ += 1; - return true; + last^ = current + current_index^ += 1 + return true } } else if current == '\n' { - current_line^ += 1; + current_line^ += 1 if current_line^ == end_line { - last^ = current; - current_index^ += 1; - return true; + last^ = current + current_index^ += 1 + return true } } - last^ = document_text[current_index^]; + last^ = document_text[current_index^] } - return false; + return false } get_character_offset_u16_to_u8 :: proc(character_offset: int, document_text: []u8) -> int { - utf8_idx := 0; - utf16_idx := 0; + utf8_idx := 0 + utf16_idx := 0 for utf16_idx < character_offset { - r, w := utf8.decode_rune(document_text[utf8_idx:]); + r, w := utf8.decode_rune(document_text[utf8_idx:]) if r == '\n' || r == '\r' { - return utf8_idx; + return utf8_idx } else if w == 0 { - return utf8_idx; + return utf8_idx } else if r < 0x10000 { - utf16_idx += 1; + utf16_idx += 1 } else { - utf16_idx += 2; + utf16_idx += 2 } - utf8_idx += w; + utf8_idx += w } - return utf8_idx; + return utf8_idx } get_character_offset_u8_to_u16 :: proc(character_offset: int, document_text: []u8) -> int { - utf8_idx := 0; - utf16_idx := 0; + utf8_idx := 0 + utf16_idx := 0 for utf8_idx < character_offset { - r, w := utf8.decode_rune(document_text[utf8_idx:]); + r, w := utf8.decode_rune(document_text[utf8_idx:]) if r == '\n' || r == '\r' { - return utf16_idx; + return utf16_idx } else if w == 0 { - return utf16_idx; + return utf16_idx } else if r < 0x10000 { - utf16_idx += 1; + utf16_idx += 1 } else { - utf16_idx += 2; + utf16_idx += 2 } - utf8_idx += w; + utf8_idx += w } - return utf16_idx; + return utf16_idx }
\ No newline at end of file diff --git a/src/common/sha1.odin b/src/common/sha1.odin index 4516467..4f1d62f 100644 --- a/src/common/sha1.odin +++ b/src/common/sha1.odin @@ -5,58 +5,58 @@ import "core:fmt" //ported version of https://llvm.org/doxygen/SHa1_8cpp_source.html rol :: proc (number: u32, bits: u32) -> u32 { - return number << bits | number >> (32 - bits); + return number << bits | number >> (32 - bits) } blk0 :: proc (buf: []u32, i: int) -> u32 { - return buf[i]; + return buf[i] } blk :: proc (buf: []u32, i: int) -> u32 { buf[i & 15] = rol(buf[(i + 13) & 15] ~ buf[(i + 8) & 15] ~ buf[(i + 2) & 15] ~ - buf[i & 15], 1); + buf[i & 15], 1) - return buf[i & 15]; + return buf[i & 15] } r0 :: proc (a: ^u32, b: ^u32, c: ^u32, d: ^u32, e: ^u32, i: int, buf: []u32) { - e^ += ((b^ & (c^ ~ d^)) ~ d^) + blk0(buf, i) + 0x5a827999 + rol(a^, 5); - b^ = rol(b^, 30); + e^ += ((b^ & (c^ ~ d^)) ~ d^) + blk0(buf, i) + 0x5a827999 + rol(a^, 5) + b^ = rol(b^, 30) } r1 :: proc (a: ^u32, b: ^u32, c: ^u32, d: ^u32, e: ^u32, i: int, buf: []u32) { - e^ += ((b^ & (c^ ~ d^)) ~ d^) + blk(buf, i) + 0x5a827999 + rol(a^, 5); - b^ += rol(b^, 30); + e^ += ((b^ & (c^ ~ d^)) ~ d^) + blk(buf, i) + 0x5a827999 + rol(a^, 5) + b^ += rol(b^, 30) } r2 :: proc (a: ^u32, b: ^u32, c: ^u32, d: ^u32, e: ^u32, i: int, buf: []u32) { - e^ += (b^ ~ c^ ~ d^) + blk(buf, i) + 0x6ed9eba1 + rol(a^, 5); - b^ += rol(b^, 30); + e^ += (b^ ~ c^ ~ d^) + blk(buf, i) + 0x6ed9eba1 + rol(a^, 5) + b^ += rol(b^, 30) } r3 :: proc (a: ^u32, b: ^u32, c: ^u32, d: ^u32, e: ^u32, i: int, buf: []u32) { - e^ += (((b^ | c^) & d^) | (b^ & c^)) + blk(buf, i) + 0x8F1bbcdc + rol(a^, 5); - b^ += rol(b^, 30); + e^ += (((b^ | c^) & d^) | (b^ & c^)) + blk(buf, i) + 0x8F1bbcdc + rol(a^, 5) + b^ += rol(b^, 30) } r4 :: proc (a: ^u32, b: ^u32, c: ^u32, d: ^u32, e: ^u32, i: int, buf: []u32) { - e^ += (b^ ~ c^ ~ d^) + blk(buf, i) + 0xca62c1d6 + rol(a^, 5); - b^ += rol(b^, 30); + e^ += (b^ ~ c^ ~ d^) + blk(buf, i) + 0xca62c1d6 + rol(a^, 5) + b^ += rol(b^, 30) } -SHA1_K0 :: 0x5a827999; -SHA1_K20 :: 0x6ed9eba1; -SHA1_K40 :: 0x8f1bbcdc; -SHA1_K60 :: 0xca62c1d6; +SHA1_K0 :: 0x5a827999 +SHA1_K20 :: 0x6ed9eba1 +SHA1_K40 :: 0x8f1bbcdc +SHA1_K60 :: 0xca62c1d6 -SEED_0 :: 0x67452301; -SEED_1 :: 0xefcdab89; -SEED_2 :: 0x98badcfe; -SEED_3 :: 0x10325476; -SEED_4 :: 0xc3d2e1f0; +SEED_0 :: 0x67452301 +SEED_1 :: 0xefcdab89 +SEED_2 :: 0x98badcfe +SEED_3 :: 0x10325476 +SEED_4 :: 0xc3d2e1f0 -BLOCK_LENGTH :: 64; -HASH_LENGTH :: 20; +BLOCK_LENGTH :: 64 +HASH_LENGTH :: 20 Sha1context :: struct { buf: struct #raw_union { @@ -69,222 +69,222 @@ Sha1context :: struct { } sha1_init :: proc (state_context: ^Sha1context) { - state_context.state[0] = SEED_0; - state_context.state[1] = SEED_1; - state_context.state[2] = SEED_2; - state_context.state[3] = SEED_3; - state_context.state[4] = SEED_4; - state_context.byte_count = 0; - state_context.buf_offset = 0; + state_context.state[0] = SEED_0 + state_context.state[1] = SEED_1 + state_context.state[2] = SEED_2 + state_context.state[3] = SEED_3 + state_context.state[4] = SEED_4 + state_context.byte_count = 0 + state_context.buf_offset = 0 } sha1_hash_block :: proc (state_context: ^Sha1context) { - a := state_context.state[0]; - b := state_context.state[1]; - c := state_context.state[2]; - d := state_context.state[3]; - e := state_context.state[4]; + a := state_context.state[0] + b := state_context.state[1] + c := state_context.state[2] + d := state_context.state[3] + e := state_context.state[4] // 4 rounds of 20 operations each. loop unrolled. - r0(&a, &b, &c, &d, &e, 0, state_context.buf.l[:]); - r0(&e, &a, &b, &c, &d, 1, state_context.buf.l[:]); - r0(&d, &e, &a, &b, &c, 2, state_context.buf.l[:]); - r0(&c, &d, &e, &a, &b, 3, state_context.buf.l[:]); - r0(&b, &c, &d, &e, &a, 4, state_context.buf.l[:]); - r0(&a, &b, &c, &d, &e, 5, state_context.buf.l[:]); - r0(&e, &a, &b, &c, &d, 6, state_context.buf.l[:]); - r0(&d, &e, &a, &b, &c, 7, state_context.buf.l[:]); - r0(&c, &d, &e, &a, &b, 8, state_context.buf.l[:]); - r0(&b, &c, &d, &e, &a, 9, state_context.buf.l[:]); - r0(&a, &b, &c, &d, &e, 10, state_context.buf.l[:]); - r0(&e, &a, &b, &c, &d, 11, state_context.buf.l[:]); - r0(&d, &e, &a, &b, &c, 12, state_context.buf.l[:]); - r0(&c, &d, &e, &a, &b, 13, state_context.buf.l[:]); - r0(&b, &c, &d, &e, &a, 14, state_context.buf.l[:]); - r0(&a, &b, &c, &d, &e, 15, state_context.buf.l[:]); - r1(&e, &a, &b, &c, &d, 16, state_context.buf.l[:]); - r1(&d, &e, &a, &b, &c, 17, state_context.buf.l[:]); - r1(&c, &d, &e, &a, &b, 18, state_context.buf.l[:]); - r1(&b, &c, &d, &e, &a, 19, state_context.buf.l[:]); - - r2(&a, &b, &c, &d, &e, 20, state_context.buf.l[:]); - r2(&e, &a, &b, &c, &d, 21, state_context.buf.l[:]); - r2(&d, &e, &a, &b, &c, 22, state_context.buf.l[:]); - r2(&c, &d, &e, &a, &b, 23, state_context.buf.l[:]); - r2(&b, &c, &d, &e, &a, 24, state_context.buf.l[:]); - r2(&a, &b, &c, &d, &e, 25, state_context.buf.l[:]); - r2(&e, &a, &b, &c, &d, 26, state_context.buf.l[:]); - r2(&d, &e, &a, &b, &c, 27, state_context.buf.l[:]); - r2(&c, &d, &e, &a, &b, 28, state_context.buf.l[:]); - r2(&b, &c, &d, &e, &a, 29, state_context.buf.l[:]); - r2(&a, &b, &c, &d, &e, 30, state_context.buf.l[:]); - r2(&e, &a, &b, &c, &d, 31, state_context.buf.l[:]); - r2(&d, &e, &a, &b, &c, 32, state_context.buf.l[:]); - r2(&c, &d, &e, &a, &b, 33, state_context.buf.l[:]); - r2(&b, &c, &d, &e, &a, 34, state_context.buf.l[:]); - r2(&a, &b, &c, &d, &e, 35, state_context.buf.l[:]); - r2(&e, &a, &b, &c, &d, 36, state_context.buf.l[:]); - r2(&d, &e, &a, &b, &c, 37, state_context.buf.l[:]); - r2(&c, &d, &e, &a, &b, 38, state_context.buf.l[:]); - r2(&b, &c, &d, &e, &a, 39, state_context.buf.l[:]); - - r3(&a, &b, &c, &d, &e, 40, state_context.buf.l[:]); - r3(&e, &a, &b, &c, &d, 41, state_context.buf.l[:]); - r3(&d, &e, &a, &b, &c, 42, state_context.buf.l[:]); - r3(&c, &d, &e, &a, &b, 43, state_context.buf.l[:]); - r3(&b, &c, &d, &e, &a, 44, state_context.buf.l[:]); - r3(&a, &b, &c, &d, &e, 45, state_context.buf.l[:]); - r3(&e, &a, &b, &c, &d, 46, state_context.buf.l[:]); - r3(&d, &e, &a, &b, &c, 47, state_context.buf.l[:]); - r3(&c, &d, &e, &a, &b, 48, state_context.buf.l[:]); - r3(&b, &c, &d, &e, &a, 49, state_context.buf.l[:]); - r3(&a, &b, &c, &d, &e, 50, state_context.buf.l[:]); - r3(&e, &a, &b, &c, &d, 51, state_context.buf.l[:]); - r3(&d, &e, &a, &b, &c, 52, state_context.buf.l[:]); - r3(&c, &d, &e, &a, &b, 53, state_context.buf.l[:]); - r3(&b, &c, &d, &e, &a, 54, state_context.buf.l[:]); - r3(&a, &b, &c, &d, &e, 55, state_context.buf.l[:]); - r3(&e, &a, &b, &c, &d, 56, state_context.buf.l[:]); - r3(&d, &e, &a, &b, &c, 57, state_context.buf.l[:]); - r3(&c, &d, &e, &a, &b, 58, state_context.buf.l[:]); - r3(&b, &c, &d, &e, &a, 59, state_context.buf.l[:]); - - r4(&a, &b, &c, &d, &e, 60, state_context.buf.l[:]); - r4(&e, &a, &b, &c, &d, 61, state_context.buf.l[:]); - r4(&d, &e, &a, &b, &c, 62, state_context.buf.l[:]); - r4(&c, &d, &e, &a, &b, 63, state_context.buf.l[:]); - r4(&b, &c, &d, &e, &a, 64, state_context.buf.l[:]); - r4(&a, &b, &c, &d, &e, 65, state_context.buf.l[:]); - r4(&e, &a, &b, &c, &d, 66, state_context.buf.l[:]); - r4(&d, &e, &a, &b, &c, 67, state_context.buf.l[:]); - r4(&c, &d, &e, &a, &b, 68, state_context.buf.l[:]); - r4(&b, &c, &d, &e, &a, 69, state_context.buf.l[:]); - r4(&a, &b, &c, &d, &e, 70, state_context.buf.l[:]); - r4(&e, &a, &b, &c, &d, 71, state_context.buf.l[:]); - r4(&d, &e, &a, &b, &c, 72, state_context.buf.l[:]); - r4(&c, &d, &e, &a, &b, 73, state_context.buf.l[:]); - r4(&b, &c, &d, &e, &a, 74, state_context.buf.l[:]); - r4(&a, &b, &c, &d, &e, 75, state_context.buf.l[:]); - r4(&e, &a, &b, &c, &d, 76, state_context.buf.l[:]); - r4(&d, &e, &a, &b, &c, 77, state_context.buf.l[:]); - r4(&c, &d, &e, &a, &b, 78, state_context.buf.l[:]); - r4(&b, &c, &d, &e, &a, 79, state_context.buf.l[:]); - - state_context.state[0] += a; - state_context.state[1] += b; - state_context.state[2] += c; - state_context.state[3] += d; - state_context.state[4] += e; + r0(&a, &b, &c, &d, &e, 0, state_context.buf.l[:]) + r0(&e, &a, &b, &c, &d, 1, state_context.buf.l[:]) + r0(&d, &e, &a, &b, &c, 2, state_context.buf.l[:]) + r0(&c, &d, &e, &a, &b, 3, state_context.buf.l[:]) + r0(&b, &c, &d, &e, &a, 4, state_context.buf.l[:]) + r0(&a, &b, &c, &d, &e, 5, state_context.buf.l[:]) + r0(&e, &a, &b, &c, &d, 6, state_context.buf.l[:]) + r0(&d, &e, &a, &b, &c, 7, state_context.buf.l[:]) + r0(&c, &d, &e, &a, &b, 8, state_context.buf.l[:]) + r0(&b, &c, &d, &e, &a, 9, state_context.buf.l[:]) + r0(&a, &b, &c, &d, &e, 10, state_context.buf.l[:]) + r0(&e, &a, &b, &c, &d, 11, state_context.buf.l[:]) + r0(&d, &e, &a, &b, &c, 12, state_context.buf.l[:]) + r0(&c, &d, &e, &a, &b, 13, state_context.buf.l[:]) + r0(&b, &c, &d, &e, &a, 14, state_context.buf.l[:]) + r0(&a, &b, &c, &d, &e, 15, state_context.buf.l[:]) + r1(&e, &a, &b, &c, &d, 16, state_context.buf.l[:]) + r1(&d, &e, &a, &b, &c, 17, state_context.buf.l[:]) + r1(&c, &d, &e, &a, &b, 18, state_context.buf.l[:]) + r1(&b, &c, &d, &e, &a, 19, state_context.buf.l[:]) + + r2(&a, &b, &c, &d, &e, 20, state_context.buf.l[:]) + r2(&e, &a, &b, &c, &d, 21, state_context.buf.l[:]) + r2(&d, &e, &a, &b, &c, 22, state_context.buf.l[:]) + r2(&c, &d, &e, &a, &b, 23, state_context.buf.l[:]) + r2(&b, &c, &d, &e, &a, 24, state_context.buf.l[:]) + r2(&a, &b, &c, &d, &e, 25, state_context.buf.l[:]) + r2(&e, &a, &b, &c, &d, 26, state_context.buf.l[:]) + r2(&d, &e, &a, &b, &c, 27, state_context.buf.l[:]) + r2(&c, &d, &e, &a, &b, 28, state_context.buf.l[:]) + r2(&b, &c, &d, &e, &a, 29, state_context.buf.l[:]) + r2(&a, &b, &c, &d, &e, 30, state_context.buf.l[:]) + r2(&e, &a, &b, &c, &d, 31, state_context.buf.l[:]) + r2(&d, &e, &a, &b, &c, 32, state_context.buf.l[:]) + r2(&c, &d, &e, &a, &b, 33, state_context.buf.l[:]) + r2(&b, &c, &d, &e, &a, 34, state_context.buf.l[:]) + r2(&a, &b, &c, &d, &e, 35, state_context.buf.l[:]) + r2(&e, &a, &b, &c, &d, 36, state_context.buf.l[:]) + r2(&d, &e, &a, &b, &c, 37, state_context.buf.l[:]) + r2(&c, &d, &e, &a, &b, 38, state_context.buf.l[:]) + r2(&b, &c, &d, &e, &a, 39, state_context.buf.l[:]) + + r3(&a, &b, &c, &d, &e, 40, state_context.buf.l[:]) + r3(&e, &a, &b, &c, &d, 41, state_context.buf.l[:]) + r3(&d, &e, &a, &b, &c, 42, state_context.buf.l[:]) + r3(&c, &d, &e, &a, &b, 43, state_context.buf.l[:]) + r3(&b, &c, &d, &e, &a, 44, state_context.buf.l[:]) + r3(&a, &b, &c, &d, &e, 45, state_context.buf.l[:]) + r3(&e, &a, &b, &c, &d, 46, state_context.buf.l[:]) + r3(&d, &e, &a, &b, &c, 47, state_context.buf.l[:]) + r3(&c, &d, &e, &a, &b, 48, state_context.buf.l[:]) + r3(&b, &c, &d, &e, &a, 49, state_context.buf.l[:]) + r3(&a, &b, &c, &d, &e, 50, state_context.buf.l[:]) + r3(&e, &a, &b, &c, &d, 51, state_context.buf.l[:]) + r3(&d, &e, &a, &b, &c, 52, state_context.buf.l[:]) + r3(&c, &d, &e, &a, &b, 53, state_context.buf.l[:]) + r3(&b, &c, &d, &e, &a, 54, state_context.buf.l[:]) + r3(&a, &b, &c, &d, &e, 55, state_context.buf.l[:]) + r3(&e, &a, &b, &c, &d, 56, state_context.buf.l[:]) + r3(&d, &e, &a, &b, &c, 57, state_context.buf.l[:]) + r3(&c, &d, &e, &a, &b, 58, state_context.buf.l[:]) + r3(&b, &c, &d, &e, &a, 59, state_context.buf.l[:]) + + r4(&a, &b, &c, &d, &e, 60, state_context.buf.l[:]) + r4(&e, &a, &b, &c, &d, 61, state_context.buf.l[:]) + r4(&d, &e, &a, &b, &c, 62, state_context.buf.l[:]) + r4(&c, &d, &e, &a, &b, 63, state_context.buf.l[:]) + r4(&b, &c, &d, &e, &a, 64, state_context.buf.l[:]) + r4(&a, &b, &c, &d, &e, 65, state_context.buf.l[:]) + r4(&e, &a, &b, &c, &d, 66, state_context.buf.l[:]) + r4(&d, &e, &a, &b, &c, 67, state_context.buf.l[:]) + r4(&c, &d, &e, &a, &b, 68, state_context.buf.l[:]) + r4(&b, &c, &d, &e, &a, 69, state_context.buf.l[:]) + r4(&a, &b, &c, &d, &e, 70, state_context.buf.l[:]) + r4(&e, &a, &b, &c, &d, 71, state_context.buf.l[:]) + r4(&d, &e, &a, &b, &c, 72, state_context.buf.l[:]) + r4(&c, &d, &e, &a, &b, 73, state_context.buf.l[:]) + r4(&b, &c, &d, &e, &a, 74, state_context.buf.l[:]) + r4(&a, &b, &c, &d, &e, 75, state_context.buf.l[:]) + r4(&e, &a, &b, &c, &d, 76, state_context.buf.l[:]) + r4(&d, &e, &a, &b, &c, 77, state_context.buf.l[:]) + r4(&c, &d, &e, &a, &b, 78, state_context.buf.l[:]) + r4(&b, &c, &d, &e, &a, 79, state_context.buf.l[:]) + + state_context.state[0] += a + state_context.state[1] += b + state_context.state[2] += c + state_context.state[3] += d + state_context.state[4] += e } sha1_add_uncounted :: proc (state_context: ^Sha1context, data: byte) { when ODIN_ENDIAN == .Big { - state_context.buf.c[state_context.buf_offset] = data; + state_context.buf.c[state_context.buf_offset] = data } else { - state_context.buf.c[state_context.buf_offset ~ 3] = data; + state_context.buf.c[state_context.buf_offset ~ 3] = data } - state_context.buf_offset += 1; + state_context.buf_offset += 1 if state_context.buf_offset == BLOCK_LENGTH { - sha1_hash_block(state_context); - state_context.buf_offset = 0; + sha1_hash_block(state_context) + state_context.buf_offset = 0 } } sha1_write_byte :: proc (state_context: ^Sha1context, data: byte) { - state_context.byte_count += 1; - sha1_add_uncounted(state_context, data); + state_context.byte_count += 1 + sha1_add_uncounted(state_context, data) } sha1_update :: proc (state_context: ^Sha1context, data: []byte) { - state_context.byte_count += cast(u32)len(data); + state_context.byte_count += cast(u32)len(data) - current_data := data; + current_data := data if state_context.buf_offset > 0 { - remainder := min(len(current_data), BLOCK_LENGTH - cast(int)state_context.buf_offset); + remainder := min(len(current_data), BLOCK_LENGTH - cast(int)state_context.buf_offset) for i := 0; i < remainder; i += 1 { - sha1_add_uncounted(state_context, current_data[i]); + sha1_add_uncounted(state_context, current_data[i]) } - current_data = current_data[remainder - 1:]; + current_data = current_data[remainder - 1:] } for len(current_data) >= BLOCK_LENGTH { - assert(state_context.buf_offset == 0); - assert(BLOCK_LENGTH % 4 == 0); + assert(state_context.buf_offset == 0) + assert(BLOCK_LENGTH % 4 == 0) - BLOCK_LENGTH_32 :: BLOCK_LENGTH / 4; + BLOCK_LENGTH_32 :: BLOCK_LENGTH / 4 for i := 0; i < BLOCK_LENGTH_32; i += 1 { - n := (transmute([]u32)current_data)[i]; + n := (transmute([]u32)current_data)[i] state_context.buf.l[i] = (((n & 0xFF) << 24) | ((n & 0xFF00) << 8) | ((n & 0xFF0000) >> 8) | - ((n & 0xFF000000) >> 24)); + ((n & 0xFF000000) >> 24)) } - sha1_hash_block(state_context); + sha1_hash_block(state_context) - current_data = current_data[BLOCK_LENGTH - 1:]; + current_data = current_data[BLOCK_LENGTH - 1:] } for c in current_data { - sha1_add_uncounted(state_context, c); + sha1_add_uncounted(state_context, c) } } sha1_pad :: proc (state_context: ^Sha1context) { - sha1_add_uncounted(state_context, 0x80); + sha1_add_uncounted(state_context, 0x80) for state_context.buf_offset != 56 { - sha1_add_uncounted(state_context, 0x00); + sha1_add_uncounted(state_context, 0x00) } - sha1_add_uncounted(state_context, 0); // We're only using 32 bit lengths - sha1_add_uncounted(state_context, 0); // But SHA-1 supports 64 bit lengths - sha1_add_uncounted(state_context, 0); // So zero pad the top bits - sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count >> 29)); // Shifting to multiply by 8 - sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count >> 21)); // as SHA-1 supports bitstreams as well as - sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count >> 13)); // byte. - sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count >> 5)); - sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count << 3)); + sha1_add_uncounted(state_context, 0) // We're only using 32 bit lengths + sha1_add_uncounted(state_context, 0) // But SHA-1 supports 64 bit lengths + sha1_add_uncounted(state_context, 0) // So zero pad the top bits + sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count >> 29)) // Shifting to multiply by 8 + sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count >> 21)) // as SHA-1 supports bitstreams as well as + sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count >> 13)) // byte. + sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count >> 5)) + sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count << 3)) } sha1_final :: proc (state_context: ^Sha1context, result: ^[5]u32) { - sha1_pad(state_context); + sha1_pad(state_context) when ODIN_ENDIAN == .Big { for i := 0; i < 5; i += 1 { - result[i] = state_context.state[i]; + result[i] = state_context.state[i] } } else { for i := 0; i < 5; i += 1 { result[i] = (((state_context.state[i]) << 24) & 0xff000000) | (((state_context.state[i]) << 8) & 0x00ff0000) | (((state_context.state[i]) >> 8) & 0x0000ff00) | - (((state_context.state[i]) >> 24) & 0x000000ff); + (((state_context.state[i]) >> 24) & 0x000000ff) } } } sha1_hash :: proc (data: []byte) -> [20]byte { - sha1_context: Sha1context; - sha1_init(&sha1_context); - sha1_update(&sha1_context, data); + sha1_context: Sha1context + sha1_init(&sha1_context) + sha1_update(&sha1_context, data) - result: [20]byte; + result: [20]byte - sha1_final(&sha1_context, cast(^[5]u32)&result); + sha1_final(&sha1_context, cast(^[5]u32)&result) - ret: [20]byte; + ret: [20]byte - copy(ret[:], result[:]); + copy(ret[:], result[:]) - return ret; + return ret } diff --git a/src/common/uri.odin b/src/common/uri.odin index ee25393..d93eab3 100644 --- a/src/common/uri.odin +++ b/src/common/uri.odin @@ -17,116 +17,116 @@ Uri :: struct { parse_uri :: proc(value: string, allocator: mem.Allocator) -> (Uri, bool) { - uri: Uri; + uri: Uri - decoded, ok := decode_percent(value, allocator); + decoded, ok := decode_percent(value, allocator) if !ok { - return uri, false; + return uri, false } - starts := "file:///"; + starts := "file:///" - start_index := len(starts); + start_index := len(starts) if !starts_with(decoded, starts) { - return uri, false; + return uri, false } - when ODIN_OS != "windows" { - start_index -= 1; + when ODIN_OS != .Windows { + start_index -= 1 } - uri.uri = strings.clone(value, allocator); - uri.decode_full = decoded; - uri.path = decoded[start_index:]; + uri.uri = strings.clone(value, allocator) + uri.decode_full = decoded + uri.path = decoded[start_index:] - return uri, true; + return uri, true } //Note(Daniel, Again some really incomplete and scuffed uri writer) create_uri :: proc(path: string, allocator: mem.Allocator) -> Uri { - path_forward, _ := filepath.to_slash(path, context.temp_allocator); + path_forward, _ := filepath.to_slash(path, context.temp_allocator) - builder := strings.make_builder(allocator); + builder := strings.make_builder(allocator) //bad - when ODIN_OS == "windows" { - strings.write_string(&builder, "file:///"); + when ODIN_OS == .Windows { + strings.write_string(&builder, "file:///") } else { - strings.write_string(&builder, "file://"); + strings.write_string(&builder, "file://") } - strings.write_string(&builder, encode_percent(path_forward, context.temp_allocator)); + strings.write_string(&builder, encode_percent(path_forward, context.temp_allocator)) - uri: Uri; + uri: Uri - uri.uri = strings.to_string(builder); - uri.decode_full = strings.clone(path_forward, allocator); - uri.path = uri.decode_full; + uri.uri = strings.to_string(builder) + uri.decode_full = strings.clone(path_forward, allocator) + uri.path = uri.decode_full - return uri; + return uri } delete_uri :: proc(uri: Uri) { if uri.uri != "" { - delete(uri.uri); + delete(uri.uri) } if uri.decode_full != "" { - delete(uri.decode_full); + delete(uri.decode_full) } } encode_percent :: proc(value: string, allocator: mem.Allocator) -> string { - builder := strings.make_builder(allocator); + builder := strings.make_builder(allocator) - data := transmute([]u8)value; - index: int; + data := transmute([]u8)value + index: int for index < len(value) { - r, w := utf8.decode_rune(data[index:]); + r, w := utf8.decode_rune(data[index:]) if r > 127 || r == ':' { for i := 0; i < w; i += 1 { strings.write_string(&builder, strings.concatenate({"%", fmt.tprintf("%X", data[index + i])}, - context.temp_allocator)); + context.temp_allocator)) } } else { - strings.write_byte(&builder, data[index]); + strings.write_byte(&builder, data[index]) } - index += w; + index += w } - return strings.to_string(builder); + return strings.to_string(builder) } @(private) starts_with :: proc(value: string, starts_with: string) -> bool { if len(value) < len(starts_with) { - return false; + return false } for i := 0; i < len(starts_with); i += 1 { if value[i] != starts_with[i] { - return false; + return false } } - return true; + return true } @(private) decode_percent :: proc(value: string, allocator: mem.Allocator) -> (string, bool) { - builder := strings.make_builder(allocator); + builder := strings.make_builder(allocator) for i := 0; i < len(value); i += 1 { @@ -134,24 +134,24 @@ decode_percent :: proc(value: string, allocator: mem.Allocator) -> (string, bool if i + 2 < len(value) { - v, ok := strconv.parse_i64_of_base(value[i + 1:i + 3], 16); + v, ok := strconv.parse_i64_of_base(value[i + 1:i + 3], 16) if !ok { - strings.destroy_builder(&builder); - return "", false; + strings.destroy_builder(&builder) + return "", false } - strings.write_byte(&builder, cast(byte)v); + strings.write_byte(&builder, cast(byte)v) - i += 2; + i += 2 } else { - strings.destroy_builder(&builder); - return "", false; + strings.destroy_builder(&builder) + return "", false } } else { - strings.write_byte(&builder, value[i]); + strings.write_byte(&builder, value[i]) } } - return strings.to_string(builder), true; + return strings.to_string(builder), true } diff --git a/src/common/util_windows.odin b/src/common/util_windows.odin index 835348a..bf89c47 100644 --- a/src/common/util_windows.odin +++ b/src/common/util_windows.odin @@ -11,71 +11,71 @@ foreign import kernel32 "system:kernel32.lib" @(default_calling_convention = "std") foreign kernel32 { - @(link_name = "CreatePipe")create_pipe :: proc (hReadPipe, hWritePipe: ^win32.Handle, lpPipeAttributes: ^win32.Security_Attributes, nSize: i32) -> i32 ---; + @(link_name = "CreatePipe")create_pipe :: proc (hReadPipe, hWritePipe: ^win32.Handle, lpPipeAttributes: ^win32.Security_Attributes, nSize: i32) -> i32 --- } run_executable :: proc(command: string, stdout: ^[]byte) -> (u32, bool, []byte) { - stdout_read: win32.Handle; - stdout_write: win32.Handle; + stdout_read: win32.Handle + stdout_write: win32.Handle - command := strings.clone_to_cstring(command, context.temp_allocator); + command := strings.clone_to_cstring(command, context.temp_allocator) - attributes: win32.Security_Attributes; - attributes.length = size_of(win32.Security_Attributes); - attributes.inherit_handle = true; - attributes.security_descriptor = nil; + attributes: win32.Security_Attributes + attributes.length = size_of(win32.Security_Attributes) + attributes.inherit_handle = true + attributes.security_descriptor = nil if create_pipe(&stdout_read, &stdout_write, &attributes, 0) == 0 { - return 0, false, stdout[0:]; + return 0, false, stdout[0:] } if !win32.set_handle_information(stdout_read, win32.HANDLE_FLAG_INHERIT, 0) { - return 0, false, stdout[0:]; + return 0, false, stdout[0:] } - startup_info: win32.Startup_Info; - process_info: win32.Process_Information; + startup_info: win32.Startup_Info + process_info: win32.Process_Information - startup_info.cb = size_of(win32.Startup_Info); + startup_info.cb = size_of(win32.Startup_Info) - startup_info.stderr = stdout_write; - startup_info.stdout = stdout_write; - startup_info.flags |= win32.STARTF_USESTDHANDLES; + startup_info.stderr = stdout_write + startup_info.stdout = stdout_write + startup_info.flags |= win32.STARTF_USESTDHANDLES if !win32.create_process_a(nil, command, nil, nil, true, 0, nil, nil, &startup_info, &process_info) { - return 0, false, stdout[0:]; + return 0, false, stdout[0:] } - win32.close_handle(stdout_write); + win32.close_handle(stdout_write) - index: int; - read: i32; + index: int + read: i32 - read_buffer: [50]byte; + read_buffer: [50]byte - success: win32.Bool = true; + success: win32.Bool = true for success { - success = win32.read_file(stdout_read, &read_buffer[0], len(read_buffer), &read, nil); + success = win32.read_file(stdout_read, &read_buffer[0], len(read_buffer), &read, nil) if read > 0 && index + cast(int)read <= len(stdout) { - mem.copy(&stdout[index], &read_buffer[0], cast(int)read); + mem.copy(&stdout[index], &read_buffer[0], cast(int)read) } - index += cast(int)read; + index += cast(int)read } - stdout[index + 1] = 0; + stdout[index + 1] = 0 - exit_code: u32; + exit_code: u32 - win32.wait_for_single_object(process_info.process, win32.INFINITE); + win32.wait_for_single_object(process_info.process, win32.INFINITE) - win32.get_exit_code_process(process_info.process, &exit_code); + win32.get_exit_code_process(process_info.process, &exit_code) - win32.close_handle(stdout_read); + win32.close_handle(stdout_read) - return exit_code, true, stdout[0:index]; + return exit_code, true, stdout[0:index] }
\ No newline at end of file |