mirror of
https://github.com/odin-lang/Odin.git
synced 2026-01-06 04:57:55 +00:00
Merge branch 'master' of https://github.com/odin-lang/Odin
This commit is contained in:
@@ -111,7 +111,7 @@ call build_vendor.bat
|
||||
if %errorlevel% neq 0 goto end_of_build
|
||||
|
||||
rem If the demo doesn't run for you and your CPU is more than a decade old, try -microarch:native
|
||||
if %release_mode% EQU 0 odin run examples/demo
|
||||
if %release_mode% EQU 0 odin run examples/demo -- Hellope World
|
||||
|
||||
del *.obj > NUL 2> NUL
|
||||
|
||||
|
||||
@@ -27,11 +27,13 @@ error() {
|
||||
if [ -z "$LLVM_CONFIG" ]; then
|
||||
# darwin, linux, openbsd
|
||||
if [ -n "$(command -v llvm-config-17)" ]; then LLVM_CONFIG="llvm-config-17"
|
||||
elif [ -n "$(command -v llvm-config-14)" ]; then LLVM_CONFIG="llvm-config-14"
|
||||
elif [ -n "$(command -v llvm-config-13)" ]; then LLVM_CONFIG="llvm-config-13"
|
||||
elif [ -n "$(command -v llvm-config-12)" ]; then LLVM_CONFIG="llvm-config-12"
|
||||
elif [ -n "$(command -v llvm-config-11)" ]; then LLVM_CONFIG="llvm-config-11"
|
||||
# freebsd
|
||||
elif [ -n "$(command -v llvm-config17)" ]; then LLVM_CONFIG="llvm-config-17"
|
||||
elif [ -n "$(command -v llvm-config14)" ]; then LLVM_CONFIG="llvm-config-14"
|
||||
elif [ -n "$(command -v llvm-config13)" ]; then LLVM_CONFIG="llvm-config-13"
|
||||
elif [ -n "$(command -v llvm-config12)" ]; then LLVM_CONFIG="llvm-config-12"
|
||||
elif [ -n "$(command -v llvm-config11)" ]; then LLVM_CONFIG="llvm-config-11"
|
||||
@@ -117,7 +119,7 @@ build_odin() {
|
||||
}
|
||||
|
||||
run_demo() {
|
||||
./odin run examples/demo/demo.odin -file
|
||||
./odin run examples/demo/demo.odin -file -- Hellope World
|
||||
}
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
|
||||
@@ -2856,7 +2856,7 @@ internal_int_random :: proc(dest: ^Int, bits: int, r: ^rnd.Rand = nil, allocator
|
||||
dest.digit[digits - 1] &= ((1 << uint(bits)) - 1)
|
||||
}
|
||||
dest.used = digits
|
||||
return nil
|
||||
return internal_clamp(dest)
|
||||
}
|
||||
internal_random :: proc { internal_int_random, }
|
||||
|
||||
|
||||
@@ -2312,17 +2312,17 @@ F32_NORMALIZE :: 0
|
||||
F32_RADIX :: 2
|
||||
F32_ROUNDS :: 1
|
||||
|
||||
F64_DIG :: 15 // # of decimal digits of precision
|
||||
F64_EPSILON :: 2.2204460492503131e-016 // smallest such that 1.0+F64_EPSILON != 1.0
|
||||
F64_MANT_DIG :: 53 // # of bits in mantissa
|
||||
F64_MAX :: 1.7976931348623158e+308 // max value
|
||||
F64_MAX_10_EXP :: 308 // max decimal exponent
|
||||
F64_MAX_EXP :: 1024 // max binary exponent
|
||||
F64_MIN :: 2.2250738585072014e-308 // min positive value
|
||||
F64_MIN_10_EXP :: -307 // min decimal exponent
|
||||
F64_MIN_EXP :: -1021 // min binary exponent
|
||||
F64_RADIX :: 2 // exponent radix
|
||||
F64_ROUNDS :: 1 // addition rounding: near
|
||||
F64_DIG :: 15 // Number of representable decimal digits.
|
||||
F64_EPSILON :: 2.2204460492503131e-016 // Smallest number such that `1.0 + F64_EPSILON != 1.0`.
|
||||
F64_MANT_DIG :: 53 // Number of bits in the mantissa.
|
||||
F64_MAX :: 1.7976931348623158e+308 // Maximum representable value.
|
||||
F64_MAX_10_EXP :: 308 // Maximum base-10 exponent yielding normalized value.
|
||||
F64_MAX_EXP :: 1024 // One greater than the maximum possible base-2 exponent yielding normalized value.
|
||||
F64_MIN :: 2.2250738585072014e-308 // Minimum positive normalized value.
|
||||
F64_MIN_10_EXP :: -307 // Minimum base-10 exponent yielding normalized value.
|
||||
F64_MIN_EXP :: -1021 // One greater than the minimum possible base-2 exponent yielding normalized value.
|
||||
F64_RADIX :: 2 // Exponent radix.
|
||||
F64_ROUNDS :: 1 // Addition rounding: near.
|
||||
|
||||
|
||||
F16_MASK :: 0x1f
|
||||
|
||||
@@ -51,7 +51,7 @@ arena_init_growing :: proc(arena: ^Arena, reserved: uint = DEFAULT_ARENA_GROWING
|
||||
// Initialization of an `Arena` to be a `.Static` variant.
|
||||
// A static arena contains a single `Memory_Block` allocated with virtual memory.
|
||||
@(require_results)
|
||||
arena_init_static :: proc(arena: ^Arena, reserved: uint, commit_size: uint = DEFAULT_ARENA_STATIC_COMMIT_SIZE) -> (err: Allocator_Error) {
|
||||
arena_init_static :: proc(arena: ^Arena, reserved: uint = DEFAULT_ARENA_STATIC_RESERVE_SIZE, commit_size: uint = DEFAULT_ARENA_STATIC_COMMIT_SIZE) -> (err: Allocator_Error) {
|
||||
arena.kind = .Static
|
||||
arena.curr_block = memory_block_alloc(commit_size, reserved, {}) or_return
|
||||
arena.total_used = 0
|
||||
|
||||
@@ -148,7 +148,29 @@ recv_udp :: proc(socket: UDP_Socket, buf: []byte) -> (bytes_read: int, remote_en
|
||||
return _recv_udp(socket, buf)
|
||||
}
|
||||
|
||||
recv :: proc{recv_tcp, recv_udp}
|
||||
/*
|
||||
Receive data from into a buffer from any socket.
|
||||
|
||||
Note: `remote_endpoint` parameter is non-nil only if the socket type is UDP. On TCP sockets it
|
||||
will always return `nil`.
|
||||
*/
|
||||
recv_any :: proc(socket: Any_Socket, buf: []byte) -> (
|
||||
bytes_read: int,
|
||||
remote_endpoint: Maybe(Endpoint),
|
||||
err: Network_Error,
|
||||
) {
|
||||
switch socktype in socket {
|
||||
case TCP_Socket:
|
||||
bytes_read, err := recv_tcp(socktype, buf)
|
||||
return bytes_read, nil, err
|
||||
case UDP_Socket:
|
||||
bytes_read, endpoint, err := recv_udp(socktype, buf)
|
||||
return bytes_read, endpoint, err
|
||||
case: panic("Not supported")
|
||||
}
|
||||
}
|
||||
|
||||
recv :: proc{recv_tcp, recv_udp, recv_any}
|
||||
|
||||
/*
|
||||
Repeatedly sends data until the entire buffer is sent.
|
||||
@@ -168,7 +190,20 @@ send_udp :: proc(socket: UDP_Socket, buf: []byte, to: Endpoint) -> (bytes_writte
|
||||
return _send_udp(socket, buf, to)
|
||||
}
|
||||
|
||||
send :: proc{send_tcp, send_udp}
|
||||
send_any :: proc(socket: Any_Socket, buf: []byte, to: Maybe(Endpoint) = nil) -> (
|
||||
bytes_written: int,
|
||||
err: Network_Error,
|
||||
) {
|
||||
switch socktype in socket {
|
||||
case TCP_Socket:
|
||||
return send_tcp(socktype, buf)
|
||||
case UDP_Socket:
|
||||
return send_udp(socktype, buf, to.(Endpoint))
|
||||
case: panic("Not supported")
|
||||
}
|
||||
}
|
||||
|
||||
send :: proc{send_tcp, send_udp, send_any}
|
||||
|
||||
shutdown :: proc(socket: Any_Socket, manner: Shutdown_Manner) -> (err: Network_Error) {
|
||||
return _shutdown(socket, manner)
|
||||
@@ -180,4 +215,4 @@ set_option :: proc(socket: Any_Socket, option: Socket_Option, value: any, loc :=
|
||||
|
||||
set_blocking :: proc(socket: Any_Socket, should_block: bool) -> (err: Network_Error) {
|
||||
return _set_blocking(socket, should_block)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ _create_socket :: proc(family: Address_Family, protocol: Socket_Protocol) -> (An
|
||||
}
|
||||
|
||||
@(private)
|
||||
_dial_tcp_from_endpoint :: proc(endpoint: Endpoint, options := default_tcp_options) -> (tcp_sock: TCP_Socket, err: Network_Error) {
|
||||
_dial_tcp_from_endpoint :: proc(endpoint: Endpoint, options := default_tcp_options) -> (TCP_Socket, Network_Error) {
|
||||
errno: linux.Errno
|
||||
if endpoint.port == 0 {
|
||||
return 0, .Port_Required
|
||||
|
||||
@@ -7,7 +7,7 @@ import "core:reflect"
|
||||
import "core:odin/tokenizer"
|
||||
_ :: intrinsics
|
||||
|
||||
new :: proc($T: typeid, pos, end: tokenizer.Pos) -> ^T {
|
||||
new_from_positions :: proc($T: typeid, pos, end: tokenizer.Pos) -> ^T {
|
||||
n, _ := mem.new(T)
|
||||
n.pos = pos
|
||||
n.end = end
|
||||
@@ -23,6 +23,15 @@ new :: proc($T: typeid, pos, end: tokenizer.Pos) -> ^T {
|
||||
return n
|
||||
}
|
||||
|
||||
new_from_pos_and_end_node :: proc($T: typeid, pos: tokenizer.Pos, end: ^Node) -> ^T {
|
||||
return new(T, pos, end != nil ? end.end : pos)
|
||||
}
|
||||
|
||||
new :: proc {
|
||||
new_from_positions,
|
||||
new_from_pos_and_end_node,
|
||||
}
|
||||
|
||||
clone :: proc{
|
||||
clone_node,
|
||||
clone_expr,
|
||||
|
||||
@@ -786,8 +786,11 @@ parse_if_stmt :: proc(p: ^Parser) -> ^ast.If_Stmt {
|
||||
else_stmt = ast.new(ast.Bad_Stmt, p.curr_tok.pos, end_pos(p.curr_tok))
|
||||
}
|
||||
}
|
||||
|
||||
end := body.end
|
||||
|
||||
end: tokenizer.Pos
|
||||
if body != nil {
|
||||
end = body.end
|
||||
}
|
||||
if else_stmt != nil {
|
||||
end = else_stmt.end
|
||||
}
|
||||
@@ -850,7 +853,7 @@ parse_for_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
|
||||
body = parse_body(p)
|
||||
}
|
||||
|
||||
range_stmt := ast.new(ast.Range_Stmt, tok.pos, body.end)
|
||||
range_stmt := ast.new(ast.Range_Stmt, tok.pos, body)
|
||||
range_stmt.for_pos = tok.pos
|
||||
range_stmt.in_pos = in_tok.pos
|
||||
range_stmt.expr = rhs
|
||||
@@ -910,7 +913,7 @@ parse_for_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
|
||||
rhs = assign_stmt.rhs[0]
|
||||
}
|
||||
|
||||
range_stmt := ast.new(ast.Range_Stmt, tok.pos, body.end)
|
||||
range_stmt := ast.new(ast.Range_Stmt, tok.pos, body)
|
||||
range_stmt.for_pos = tok.pos
|
||||
range_stmt.vals = vals
|
||||
range_stmt.in_pos = assign_stmt.op.pos
|
||||
@@ -920,7 +923,7 @@ parse_for_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
|
||||
}
|
||||
|
||||
cond_expr := convert_stmt_to_expr(p, cond, "boolean expression")
|
||||
for_stmt := ast.new(ast.For_Stmt, tok.pos, body.end)
|
||||
for_stmt := ast.new(ast.For_Stmt, tok.pos, body)
|
||||
for_stmt.for_pos = tok.pos
|
||||
for_stmt.init = init
|
||||
for_stmt.cond = cond_expr
|
||||
@@ -976,7 +979,7 @@ parse_switch_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
|
||||
lhs[0] = new_blank_ident(p, tok.pos)
|
||||
rhs[0] = parse_expr(p, true)
|
||||
|
||||
as := ast.new(ast.Assign_Stmt, tok.pos, rhs[0].end)
|
||||
as := ast.new(ast.Assign_Stmt, tok.pos, rhs[0])
|
||||
as.lhs = lhs
|
||||
as.op = in_tok
|
||||
as.rhs = rhs
|
||||
@@ -1010,14 +1013,14 @@ parse_switch_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
|
||||
body.stmts = clauses[:]
|
||||
|
||||
if is_type_switch {
|
||||
ts := ast.new(ast.Type_Switch_Stmt, tok.pos, body.end)
|
||||
ts := ast.new(ast.Type_Switch_Stmt, tok.pos, body)
|
||||
ts.tag = tag
|
||||
ts.body = body
|
||||
ts.switch_pos = tok.pos
|
||||
return ts
|
||||
} else {
|
||||
cond := convert_stmt_to_expr(p, tag, "switch expression")
|
||||
ts := ast.new(ast.Switch_Stmt, tok.pos, body.end)
|
||||
ts := ast.new(ast.Switch_Stmt, tok.pos, body)
|
||||
ts.init = init
|
||||
ts.cond = cond
|
||||
ts.body = body
|
||||
@@ -1044,7 +1047,7 @@ parse_attribute :: proc(p: ^Parser, tok: tokenizer.Token, open_kind, close_kind:
|
||||
if p.curr_tok.kind == .Eq {
|
||||
eq := expect_token(p, .Eq)
|
||||
value := parse_value(p)
|
||||
fv := ast.new(ast.Field_Value, elem.pos, value.end)
|
||||
fv := ast.new(ast.Field_Value, elem.pos, value)
|
||||
fv.field = elem
|
||||
fv.sep = eq.pos
|
||||
fv.value = value
|
||||
@@ -1137,7 +1140,7 @@ parse_foreign_block :: proc(p: ^Parser, tok: tokenizer.Token) -> ^ast.Foreign_Bl
|
||||
body.stmts = decls[:]
|
||||
body.close = close.pos
|
||||
|
||||
decl := ast.new(ast.Foreign_Block_Decl, tok.pos, body.end)
|
||||
decl := ast.new(ast.Foreign_Block_Decl, tok.pos, body)
|
||||
decl.docs = docs
|
||||
decl.tok = tok
|
||||
decl.foreign_library = foreign_library
|
||||
@@ -1248,7 +1251,7 @@ parse_unrolled_for_loop :: proc(p: ^Parser, inline_tok: tokenizer.Token) -> ^ast
|
||||
return ast.new(ast.Bad_Stmt, inline_tok.pos, end_pos(p.prev_tok))
|
||||
}
|
||||
|
||||
range_stmt := ast.new(ast.Inline_Range_Stmt, inline_tok.pos, body.end)
|
||||
range_stmt := ast.new(ast.Inline_Range_Stmt, inline_tok.pos, body)
|
||||
range_stmt.inline_pos = inline_tok.pos
|
||||
range_stmt.for_pos = for_tok.pos
|
||||
range_stmt.val0 = val0
|
||||
@@ -1304,7 +1307,7 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
|
||||
case ^ast.Return_Stmt:
|
||||
error(p, s.pos, "you cannot defer a return statement")
|
||||
}
|
||||
ds := ast.new(ast.Defer_Stmt, tok.pos, stmt.end)
|
||||
ds := ast.new(ast.Defer_Stmt, tok.pos, stmt)
|
||||
ds.stmt = stmt
|
||||
return ds
|
||||
|
||||
@@ -1341,8 +1344,7 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
|
||||
if tok.kind != .Fallthrough && p.curr_tok.kind == .Ident {
|
||||
label = parse_ident(p)
|
||||
}
|
||||
end := label.end if label != nil else end_pos(tok)
|
||||
s := ast.new(ast.Branch_Stmt, tok.pos, end)
|
||||
s := ast.new(ast.Branch_Stmt, tok.pos, label)
|
||||
s.tok = tok
|
||||
s.label = label
|
||||
expect_semicolon(p, s)
|
||||
@@ -1366,7 +1368,7 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
|
||||
if p.curr_tok.kind != .Colon {
|
||||
end := list[len(list)-1]
|
||||
expect_semicolon(p, end)
|
||||
us := ast.new(ast.Using_Stmt, tok.pos, end.end)
|
||||
us := ast.new(ast.Using_Stmt, tok.pos, end)
|
||||
us.list = list
|
||||
return us
|
||||
}
|
||||
@@ -1416,13 +1418,13 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
|
||||
bd.tok = tok
|
||||
bd.name = name
|
||||
ce := parse_call_expr(p, bd)
|
||||
es := ast.new(ast.Expr_Stmt, ce.pos, ce.end)
|
||||
es := ast.new(ast.Expr_Stmt, ce.pos, ce)
|
||||
es.expr = ce
|
||||
return es
|
||||
|
||||
case "force_inline", "force_no_inline":
|
||||
expr := parse_inlining_operand(p, true, tag)
|
||||
es := ast.new(ast.Expr_Stmt, expr.pos, expr.end)
|
||||
es := ast.new(ast.Expr_Stmt, expr.pos, expr)
|
||||
es.expr = expr
|
||||
return es
|
||||
case "unroll":
|
||||
@@ -1444,7 +1446,8 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
|
||||
return ast.new(ast.Bad_Stmt, tok.pos, end_pos(tag))
|
||||
case:
|
||||
stmt := parse_stmt(p)
|
||||
te := ast.new(ast.Tag_Stmt, tok.pos, stmt.pos)
|
||||
end := stmt.pos if stmt != nil else end_pos(tok)
|
||||
te := ast.new(ast.Tag_Stmt, tok.pos, end)
|
||||
te.op = tok
|
||||
te.name = name
|
||||
te.stmt = stmt
|
||||
@@ -1572,7 +1575,7 @@ convert_stmt_to_body :: proc(p: ^Parser, stmt: ^ast.Stmt) -> ^ast.Stmt {
|
||||
error(p, stmt.pos, "expected a non-empty statement")
|
||||
}
|
||||
|
||||
bs := ast.new(ast.Block_Stmt, stmt.pos, stmt.end)
|
||||
bs := ast.new(ast.Block_Stmt, stmt.pos, stmt)
|
||||
bs.open = stmt.pos
|
||||
bs.stmts = make([]^ast.Stmt, 1)
|
||||
bs.stmts[0] = stmt
|
||||
@@ -1741,7 +1744,7 @@ parse_var_type :: proc(p: ^Parser, flags: ast.Field_Flags) -> ^ast.Expr {
|
||||
error(p, tok.pos, "variadic field missing type after '..'")
|
||||
type = ast.new(ast.Bad_Expr, tok.pos, end_pos(tok))
|
||||
}
|
||||
e := ast.new(ast.Ellipsis, type.pos, type.end)
|
||||
e := ast.new(ast.Ellipsis, type.pos, type)
|
||||
e.expr = type
|
||||
return e
|
||||
}
|
||||
@@ -1808,7 +1811,7 @@ parse_ident_list :: proc(p: ^Parser, allow_poly_names: bool) -> []^ast.Expr {
|
||||
if is_blank_ident(ident) {
|
||||
error(p, ident.pos, "invalid polymorphic type definition with a blank identifier")
|
||||
}
|
||||
poly_name := ast.new(ast.Poly_Type, tok.pos, ident.end)
|
||||
poly_name := ast.new(ast.Poly_Type, tok.pos, ident)
|
||||
poly_name.type = ident
|
||||
append(&list, poly_name)
|
||||
} else {
|
||||
@@ -2154,7 +2157,7 @@ parse_inlining_operand :: proc(p: ^Parser, lhs: bool, tok: tokenizer.Token) -> ^
|
||||
e.inlining = pi
|
||||
case:
|
||||
error(p, tok.pos, "'%s' must be followed by a procedure literal or call", tok.text)
|
||||
return ast.new(ast.Bad_Expr, tok.pos, expr.end)
|
||||
return ast.new(ast.Bad_Expr, tok.pos, expr)
|
||||
}
|
||||
return expr
|
||||
}
|
||||
@@ -2204,7 +2207,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
case .Distinct:
|
||||
tok := advance_token(p)
|
||||
type := parse_type(p)
|
||||
dt := ast.new(ast.Distinct_Type, tok.pos, type.end)
|
||||
dt := ast.new(ast.Distinct_Type, tok.pos, type)
|
||||
dt.tok = tok.kind
|
||||
dt.type = type
|
||||
return dt
|
||||
@@ -2215,7 +2218,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
switch name.text {
|
||||
case "type":
|
||||
type := parse_type(p)
|
||||
hp := ast.new(ast.Helper_Type, tok.pos, type.end)
|
||||
hp := ast.new(ast.Helper_Type, tok.pos, type)
|
||||
hp.tok = tok.kind
|
||||
hp.type = type
|
||||
return hp
|
||||
@@ -2319,7 +2322,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
tag_call := parse_call_expr(p, tag)
|
||||
type := parse_type(p)
|
||||
|
||||
rt := ast.new(ast.Relative_Type, tok.pos, type.end)
|
||||
rt := ast.new(ast.Relative_Type, tok.pos, type)
|
||||
rt.tag = tag_call
|
||||
rt.type = type
|
||||
return rt
|
||||
@@ -2328,7 +2331,8 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
return parse_inlining_operand(p, lhs, name)
|
||||
case:
|
||||
expr := parse_expr(p, lhs)
|
||||
te := ast.new(ast.Tag_Expr, tok.pos, expr.pos)
|
||||
end := expr.pos if expr != nil else end_pos(tok)
|
||||
te := ast.new(ast.Tag_Expr, tok.pos, end)
|
||||
te.op = tok
|
||||
te.name = name.text
|
||||
te.expr = expr
|
||||
@@ -2456,7 +2460,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
case .Pointer:
|
||||
tok := expect_token(p, .Pointer)
|
||||
elem := parse_type(p)
|
||||
ptr := ast.new(ast.Pointer_Type, tok.pos, elem.end)
|
||||
ptr := ast.new(ast.Pointer_Type, tok.pos, elem)
|
||||
ptr.pointer = tok.pos
|
||||
ptr.elem = elem
|
||||
return ptr
|
||||
@@ -2470,7 +2474,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
tok := expect_token(p, .Pointer)
|
||||
close := expect_token(p, .Close_Bracket)
|
||||
elem := parse_type(p)
|
||||
t := ast.new(ast.Multi_Pointer_Type, open.pos, elem.end)
|
||||
t := ast.new(ast.Multi_Pointer_Type, open.pos, elem)
|
||||
t.open = open.pos
|
||||
t.pointer = tok.pos
|
||||
t.close = close.pos
|
||||
@@ -2480,7 +2484,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
tok := expect_token(p, .Dynamic)
|
||||
close := expect_token(p, .Close_Bracket)
|
||||
elem := parse_type(p)
|
||||
da := ast.new(ast.Dynamic_Array_Type, open.pos, elem.end)
|
||||
da := ast.new(ast.Dynamic_Array_Type, open.pos, elem)
|
||||
da.open = open.pos
|
||||
da.dynamic_pos = tok.pos
|
||||
da.close = close.pos
|
||||
@@ -2500,7 +2504,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
}
|
||||
close := expect_token(p, .Close_Bracket)
|
||||
elem := parse_type(p)
|
||||
at := ast.new(ast.Array_Type, open.pos, elem.end)
|
||||
at := ast.new(ast.Array_Type, open.pos, elem)
|
||||
at.open = open.pos
|
||||
at.len = count
|
||||
at.close = close.pos
|
||||
@@ -2514,7 +2518,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
expect_token(p, .Close_Bracket)
|
||||
value := parse_type(p)
|
||||
|
||||
mt := ast.new(ast.Map_Type, tok.pos, value.end)
|
||||
mt := ast.new(ast.Map_Type, tok.pos, value)
|
||||
mt.tok_pos = tok.pos
|
||||
mt.key = key
|
||||
mt.value = value
|
||||
@@ -2755,7 +2759,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
expect_token(p, .Close_Bracket)
|
||||
elem := parse_type(p)
|
||||
|
||||
mt := ast.new(ast.Matrix_Type, tok.pos, elem.end)
|
||||
mt := ast.new(ast.Matrix_Type, tok.pos, elem)
|
||||
mt.tok_pos = tok.pos
|
||||
mt.row_count = row_count
|
||||
mt.column_count = column_count
|
||||
@@ -2893,7 +2897,7 @@ parse_elem_list :: proc(p: ^Parser) -> []^ast.Expr {
|
||||
eq := expect_token(p, .Eq)
|
||||
value := parse_value(p)
|
||||
|
||||
fv := ast.new(ast.Field_Value, elem.pos, value.end)
|
||||
fv := ast.new(ast.Field_Value, elem.pos, value)
|
||||
fv.field = elem
|
||||
fv.sep = eq.pos
|
||||
fv.value = value
|
||||
@@ -2962,7 +2966,7 @@ parse_call_expr :: proc(p: ^Parser, operand: ^ast.Expr) -> ^ast.Expr {
|
||||
}
|
||||
|
||||
value := parse_value(p)
|
||||
fv := ast.new(ast.Field_Value, arg.pos, value.end)
|
||||
fv := ast.new(ast.Field_Value, arg.pos, value)
|
||||
fv.field = arg
|
||||
fv.sep = eq.pos
|
||||
fv.value = value
|
||||
@@ -2993,7 +2997,7 @@ parse_call_expr :: proc(p: ^Parser, operand: ^ast.Expr) -> ^ast.Expr {
|
||||
|
||||
o := ast.unparen_expr(operand)
|
||||
if se, ok := o.derived.(^ast.Selector_Expr); ok && se.op.kind == .Arrow_Right {
|
||||
sce := ast.new(ast.Selector_Call_Expr, ce.pos, ce.end)
|
||||
sce := ast.new(ast.Selector_Call_Expr, ce.pos, ce)
|
||||
sce.expr = o
|
||||
sce.call = ce
|
||||
return sce
|
||||
@@ -3101,7 +3105,7 @@ parse_atom_expr :: proc(p: ^Parser, value: ^ast.Expr, lhs: bool) -> (operand: ^a
|
||||
case .Ident:
|
||||
field := parse_ident(p)
|
||||
|
||||
sel := ast.new(ast.Selector_Expr, operand.pos, field.end)
|
||||
sel := ast.new(ast.Selector_Expr, operand.pos, field)
|
||||
sel.expr = operand
|
||||
sel.op = tok
|
||||
sel.field = field
|
||||
@@ -3127,7 +3131,7 @@ parse_atom_expr :: proc(p: ^Parser, value: ^ast.Expr, lhs: bool) -> (operand: ^a
|
||||
type.op = question
|
||||
type.expr = nil
|
||||
|
||||
ta := ast.new(ast.Type_Assertion, operand.pos, type.end)
|
||||
ta := ast.new(ast.Type_Assertion, operand.pos, type)
|
||||
ta.expr = operand
|
||||
ta.type = type
|
||||
|
||||
@@ -3145,7 +3149,7 @@ parse_atom_expr :: proc(p: ^Parser, value: ^ast.Expr, lhs: bool) -> (operand: ^a
|
||||
case .Ident:
|
||||
field := parse_ident(p)
|
||||
|
||||
sel := ast.new(ast.Selector_Expr, operand.pos, field.end)
|
||||
sel := ast.new(ast.Selector_Expr, operand.pos, field)
|
||||
sel.expr = operand
|
||||
sel.op = tok
|
||||
sel.field = field
|
||||
@@ -3225,7 +3229,7 @@ parse_unary_expr :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
close := expect_token(p, .Close_Paren)
|
||||
expr := parse_unary_expr(p, lhs)
|
||||
|
||||
tc := ast.new(ast.Type_Cast, tok.pos, expr.end)
|
||||
tc := ast.new(ast.Type_Cast, tok.pos, expr)
|
||||
tc.tok = tok
|
||||
tc.open = open.pos
|
||||
tc.type = type
|
||||
@@ -3237,7 +3241,7 @@ parse_unary_expr :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
op := advance_token(p)
|
||||
expr := parse_unary_expr(p, lhs)
|
||||
|
||||
ac := ast.new(ast.Auto_Cast, op.pos, expr.end)
|
||||
ac := ast.new(ast.Auto_Cast, op.pos, expr)
|
||||
ac.op = op
|
||||
ac.expr = expr
|
||||
return ac
|
||||
@@ -3247,8 +3251,8 @@ parse_unary_expr :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
.And:
|
||||
op := advance_token(p)
|
||||
expr := parse_unary_expr(p, lhs)
|
||||
|
||||
ue := ast.new(ast.Unary_Expr, op.pos, expr.end)
|
||||
|
||||
ue := ast.new(ast.Unary_Expr, op.pos, expr)
|
||||
ue.op = op
|
||||
ue.expr = expr
|
||||
return ue
|
||||
@@ -3258,7 +3262,7 @@ parse_unary_expr :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
error(p, op.pos, "unary '%s' operator is not supported", op.text)
|
||||
expr := parse_unary_expr(p, lhs)
|
||||
|
||||
ue := ast.new(ast.Unary_Expr, op.pos, expr.end)
|
||||
ue := ast.new(ast.Unary_Expr, op.pos, expr)
|
||||
ue.op = op
|
||||
ue.expr = expr
|
||||
return ue
|
||||
@@ -3266,7 +3270,7 @@ parse_unary_expr :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
case .Period:
|
||||
op := advance_token(p)
|
||||
field := parse_ident(p)
|
||||
ise := ast.new(ast.Implicit_Selector_Expr, op.pos, field.end)
|
||||
ise := ast.new(ast.Implicit_Selector_Expr, op.pos, field)
|
||||
ise.field = field
|
||||
return ise
|
||||
|
||||
@@ -3407,7 +3411,7 @@ parse_simple_stmt :: proc(p: ^Parser, flags: Stmt_Allow_Flags) -> ^ast.Stmt {
|
||||
error(p, p.curr_tok.pos, "no right-hand side in assignment statement")
|
||||
return ast.new(ast.Bad_Stmt, start_tok.pos, end_pos(p.curr_tok))
|
||||
}
|
||||
stmt := ast.new(ast.Assign_Stmt, lhs[0].pos, rhs[len(rhs)-1].end)
|
||||
stmt := ast.new(ast.Assign_Stmt, lhs[0].pos, rhs[len(rhs)-1])
|
||||
stmt.lhs = lhs
|
||||
stmt.op = op
|
||||
stmt.rhs = rhs
|
||||
@@ -3424,7 +3428,7 @@ parse_simple_stmt :: proc(p: ^Parser, flags: Stmt_Allow_Flags) -> ^ast.Stmt {
|
||||
rhs := make([]^ast.Expr, 1)
|
||||
rhs[0] = expr
|
||||
|
||||
stmt := ast.new(ast.Assign_Stmt, lhs[0].pos, rhs[len(rhs)-1].end)
|
||||
stmt := ast.new(ast.Assign_Stmt, lhs[0].pos, rhs[len(rhs)-1])
|
||||
stmt.lhs = lhs
|
||||
stmt.op = op
|
||||
stmt.rhs = rhs
|
||||
@@ -3466,7 +3470,7 @@ parse_simple_stmt :: proc(p: ^Parser, flags: Stmt_Allow_Flags) -> ^ast.Stmt {
|
||||
error(p, op.pos, "postfix '%s' statement is not supported", op.text)
|
||||
}
|
||||
|
||||
es := ast.new(ast.Expr_Stmt, lhs[0].pos, lhs[0].end)
|
||||
es := ast.new(ast.Expr_Stmt, lhs[0].pos, lhs[0])
|
||||
es.expr = lhs[0]
|
||||
return es
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ nil_allocator :: proc() -> Allocator {
|
||||
when ODIN_OS == .Freestanding {
|
||||
default_allocator_proc :: nil_allocator_proc
|
||||
default_allocator :: nil_allocator
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -78,9 +78,7 @@ panic_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
|
||||
|
||||
panic_allocator :: proc() -> Allocator {
|
||||
return Allocator{
|
||||
procedure = nil_allocator_proc,
|
||||
procedure = panic_allocator_proc,
|
||||
data = nil,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ package runtime
|
||||
import "core:intrinsics"
|
||||
|
||||
_os_write :: proc "contextless" (data: []byte) -> (int, _OS_Errno) {
|
||||
ret := intrinsics.syscall(4, 1, uintptr(raw_data(data)), uintptr(len(data)))
|
||||
ret := intrinsics.syscall(0x2000004, 1, uintptr(raw_data(data)), uintptr(len(data)))
|
||||
if ret < 0 {
|
||||
return 0, _OS_Errno(-ret)
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ to_bytes :: proc "contextless" (s: []$T) -> []byte {
|
||||
```
|
||||
```
|
||||
small_items := []byte{1, 0, 0, 0, 0, 0, 0, 0,
|
||||
2, 0, 0, 0}
|
||||
2, 0, 0, 0}
|
||||
large_items := slice.reinterpret([]i64, small_items)
|
||||
assert(len(large_items) == 1) // only enough bytes to make 1 x i64; two would need at least 8 bytes.
|
||||
```
|
||||
@@ -78,7 +78,7 @@ swap_between :: proc(a, b: $T/[]$E) {
|
||||
n := builtin.min(len(a), len(b))
|
||||
if n >= 0 {
|
||||
ptr_swap_overlapping(&a[0], &b[0], size_of(E)*n)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -117,46 +117,93 @@ linear_search_proc :: proc(array: $A/[]$T, f: proc(T) -> bool) -> (index: int, f
|
||||
return -1, false
|
||||
}
|
||||
|
||||
/*
|
||||
Binary search searches the given slice for the given element.
|
||||
If the slice is not sorted, the returned index is unspecified and meaningless.
|
||||
|
||||
If the value is found then the returned int is the index of the matching element.
|
||||
If there are multiple matches, then any one of the matches could be returned.
|
||||
|
||||
If the value is not found then the returned int is the index where a matching
|
||||
element could be inserted while maintaining sorted order.
|
||||
|
||||
# Examples
|
||||
|
||||
Looks up a series of four elements. The first is found, with a
|
||||
uniquely determined position; the second and third are not
|
||||
found; the fourth could match any position in `[1, 4]`.
|
||||
|
||||
```
|
||||
index: int
|
||||
found: bool
|
||||
|
||||
s := []i32{0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55}
|
||||
|
||||
index, found = slice.binary_search(s, 13)
|
||||
assert(index == 9 && found == true)
|
||||
|
||||
index, found = slice.binary_search(s, 4)
|
||||
assert(index == 7 && found == false)
|
||||
|
||||
index, found = slice.binary_search(s, 100)
|
||||
assert(index == 13 && found == false)
|
||||
|
||||
index, found = slice.binary_search(s, 1)
|
||||
assert(index >= 1 && index <= 4 && found == true)
|
||||
```
|
||||
|
||||
For slices of more complex types see: binary_search_by
|
||||
*/
|
||||
@(require_results)
|
||||
binary_search :: proc(array: $A/[]$T, key: T) -> (index: int, found: bool)
|
||||
where intrinsics.type_is_ordered(T) #no_bounds_check {
|
||||
|
||||
n := len(array)
|
||||
switch n {
|
||||
case 0:
|
||||
return -1, false
|
||||
case 1:
|
||||
if array[0] == key {
|
||||
return 0, true
|
||||
}
|
||||
return -1, false
|
||||
}
|
||||
|
||||
lo, hi := 0, n-1
|
||||
|
||||
for array[hi] != array[lo] && key >= array[lo] && key <= array[hi] {
|
||||
when intrinsics.type_is_ordered_numeric(T) {
|
||||
// NOTE(bill): This is technically interpolation search
|
||||
m := lo + int((key - array[lo]) * T(hi - lo) / (array[hi] - array[lo]))
|
||||
} else {
|
||||
m := lo + (hi - lo)/2
|
||||
}
|
||||
where intrinsics.type_is_ordered(T) #no_bounds_check
|
||||
{
|
||||
// I would like to use binary_search_by(array, key, cmp) here, but it doesn't like it:
|
||||
// Cannot assign value 'cmp' of type 'proc($E, $E) -> Ordering' to 'proc(i32, i32) -> Ordering' in argument
|
||||
return binary_search_by(array, key, proc(key: T, element: T) -> Ordering {
|
||||
switch {
|
||||
case array[m] < key:
|
||||
lo = m + 1
|
||||
case key < array[m]:
|
||||
hi = m - 1
|
||||
case:
|
||||
return m, true
|
||||
case element < key: return .Less
|
||||
case element > key: return .Greater
|
||||
case: return .Equal
|
||||
}
|
||||
}
|
||||
|
||||
if key == array[lo] {
|
||||
return lo, true
|
||||
}
|
||||
return -1, false
|
||||
})
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
binary_search_by :: proc(array: $A/[]$T, key: T, f: proc(T, T) -> Ordering) -> (index: int, found: bool) #no_bounds_check {
|
||||
// INVARIANTS:
|
||||
// - 0 <= left <= (left + size = right) <= len(array)
|
||||
// - f returns .Less for everything in array[:left]
|
||||
// - f returns .Greater for everything in array[right:]
|
||||
size := len(array)
|
||||
left := 0
|
||||
right := size
|
||||
|
||||
for left < right {
|
||||
mid := left + size / 2
|
||||
|
||||
// Steps to verify this is in-bounds:
|
||||
// 1. We note that `size` is strictly positive due to the loop condition
|
||||
// 2. Therefore `size/2 < size`
|
||||
// 3. Adding `left` to both sides yields `(left + size/2) < (left + size)`
|
||||
// 4. We know from the invariant that `left + size <= len(array)`
|
||||
// 5. Therefore `left + size/2 < self.len()`
|
||||
cmp := f(key, array[mid])
|
||||
|
||||
left = mid + 1 if cmp == .Less else left
|
||||
right = mid if cmp == .Greater else right
|
||||
|
||||
switch cmp {
|
||||
case .Equal: return mid, true
|
||||
case .Less: left = mid + 1
|
||||
case .Greater: right = mid
|
||||
}
|
||||
|
||||
size = right - left
|
||||
}
|
||||
|
||||
return left, false
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
equal :: proc(a, b: $T/[]$E) -> bool where intrinsics.type_is_comparable(E) {
|
||||
@@ -463,6 +510,40 @@ min_max :: proc(s: $S/[]$T) -> (min, max: T, ok: bool) where intrinsics.type_is_
|
||||
return
|
||||
}
|
||||
|
||||
// Find the index of the (first) minimum element in a slice.
|
||||
@(require_results)
|
||||
min_index :: proc(s: $S/[]$T) -> (min_index: int, ok: bool) where intrinsics.type_is_ordered(T) #optional_ok {
|
||||
if len(s) == 0 {
|
||||
return -1, false
|
||||
}
|
||||
min_index = 0
|
||||
min_value := s[0]
|
||||
for v, i in s[1:] {
|
||||
if v < min_value {
|
||||
min_value = v
|
||||
min_index = i+1
|
||||
}
|
||||
}
|
||||
return min_index, true
|
||||
}
|
||||
|
||||
// Find the index of the (first) maximum element in a slice.
|
||||
@(require_results)
|
||||
max_index :: proc(s: $S/[]$T) -> (max_index: int, ok: bool) where intrinsics.type_is_ordered(T) #optional_ok {
|
||||
if len(s) == 0 {
|
||||
return -1, false
|
||||
}
|
||||
max_index = 0
|
||||
max_value := s[0]
|
||||
for v, i in s[1:] {
|
||||
if v > max_value {
|
||||
max_value = v
|
||||
max_index = i+1
|
||||
}
|
||||
}
|
||||
return max_index, true
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
any_of :: proc(s: $S/[]$T, value: T) -> bool where intrinsics.type_is_comparable(T) {
|
||||
for v in s {
|
||||
|
||||
@@ -885,6 +885,7 @@ Splits a string into parts based on a separator. If n < count of seperators, the
|
||||
Inputs:
|
||||
- s: The string to split.
|
||||
- sep: The separator string used to split the input string.
|
||||
- n: The maximum amount of parts to split the string into.
|
||||
- allocator: (default is context.allocator)
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -718,7 +718,7 @@ Perf_Event_Sample_Type_Bits :: enum {
|
||||
}
|
||||
|
||||
/// Describes field sets to include in mmaped page
|
||||
Perf_Read_Format :: enum {
|
||||
Perf_Read_Format_Bits :: enum {
|
||||
TOTAL_TIME_ENABLED = 0,
|
||||
TOTAL_TIME_RUNNING = 1,
|
||||
ID = 2,
|
||||
|
||||
@@ -283,6 +283,8 @@ Perf_Flags :: bit_set[Perf_Flags_Bits; uint]
|
||||
|
||||
Perf_Event_Flags :: distinct bit_set[Perf_Event_Flags_Bits; u64]
|
||||
|
||||
Perf_Read_Format :: distinct bit_set[Perf_Read_Format_Bits; u64]
|
||||
|
||||
Perf_Cap_Flags :: distinct bit_set[Perf_Cap_Flags_Bits; u64]
|
||||
|
||||
Perf_Event_Sample_Type :: bit_set[Perf_Event_Sample_Type_Bits; u64]
|
||||
|
||||
@@ -10,6 +10,8 @@ foreign gdi32 {
|
||||
DeleteObject :: proc(ho: HGDIOBJ) -> BOOL ---
|
||||
SetBkColor :: proc(hdc: HDC, color: COLORREF) -> COLORREF ---
|
||||
|
||||
CreateCompatibleDC :: proc(hdc: HDC) -> HDC ---
|
||||
|
||||
CreateDIBPatternBrush :: proc(h: HGLOBAL, iUsage: UINT) -> HBRUSH ---
|
||||
|
||||
CreateDIBitmap :: proc(
|
||||
@@ -81,6 +83,11 @@ foreign gdi32 {
|
||||
GetTextMetricsW :: proc(hdc: HDC, lptm: LPTEXTMETRICW) -> BOOL ---
|
||||
|
||||
CreateSolidBrush :: proc(color: COLORREF) -> HBRUSH ---
|
||||
|
||||
GetObjectW :: proc(h: HANDLE, c: c_int, pv: LPVOID) -> int ---
|
||||
CreateCompatibleBitmap :: proc(hdc: HDC, cx, cy: c_int) -> HBITMAP ---
|
||||
BitBlt :: proc(hdc: HDC, x, y, cx, cy: c_int, hdcSrc: HDC, x1, y1: c_int, rop: DWORD) -> BOOL ---
|
||||
GetDIBits :: proc(hdc: HDC, hbm: HBITMAP, start, cLines: UINT, lpvBits: LPVOID, lpbmi: ^BITMAPINFO, usage: UINT) -> int ---
|
||||
}
|
||||
|
||||
RGB :: #force_inline proc "contextless" (r, g, b: u8) -> COLORREF {
|
||||
|
||||
@@ -291,6 +291,14 @@ foreign kernel32 {
|
||||
hTemplateFile: HANDLE,
|
||||
) -> HANDLE ---
|
||||
|
||||
GetFileTime :: proc(
|
||||
hFile: HANDLE,
|
||||
lpCreationTime: LPFILETIME,
|
||||
lpLastAccessTime: LPFILETIME,
|
||||
lpLastWriteTime: LPFILETIME,
|
||||
) -> BOOL ---
|
||||
CompareFileTime :: proc(lpFileTime1: LPFILETIME, lpFileTime2: LPFILETIME) -> LONG ---
|
||||
|
||||
FindFirstFileW :: proc(fileName: LPCWSTR, findFileData: LPWIN32_FIND_DATAW) -> HANDLE ---
|
||||
FindNextFileW :: proc(findFile: HANDLE, findFileData: LPWIN32_FIND_DATAW) -> BOOL ---
|
||||
FindClose :: proc(findFile: HANDLE) -> BOOL ---
|
||||
@@ -354,6 +362,9 @@ foreign kernel32 {
|
||||
LocalReAlloc :: proc(mem: LPVOID, bytes: SIZE_T, flags: UINT) -> LPVOID ---
|
||||
LocalFree :: proc(mem: LPVOID) -> LPVOID ---
|
||||
|
||||
GlobalAlloc :: proc(flags: UINT, bytes: SIZE_T) -> LPVOID ---
|
||||
GlobalReAlloc :: proc(mem: LPVOID, bytes: SIZE_T, flags: UINT) -> LPVOID ---
|
||||
GlobalFree :: proc(mem: LPVOID) -> LPVOID ---
|
||||
|
||||
ReadDirectoryChangesW :: proc(
|
||||
hDirectory: HANDLE,
|
||||
@@ -422,7 +433,7 @@ foreign kernel32 {
|
||||
GetConsoleWindow :: proc() -> HWND ---
|
||||
GetConsoleScreenBufferInfo :: proc(hConsoleOutput: HANDLE, lpConsoleScreenBufferInfo: PCONSOLE_SCREEN_BUFFER_INFO) -> BOOL ---
|
||||
SetConsoleScreenBufferSize :: proc(hConsoleOutput: HANDLE, dwSize: COORD) -> BOOL ---
|
||||
SetConsoleWindowInfo :: proc(hConsoleOutput: HANDLE, bAbsolute : BOOL, lpConsoleWindow: ^SMALL_RECT) -> BOOL ---
|
||||
SetConsoleWindowInfo :: proc(hConsoleOutput: HANDLE, bAbsolute: BOOL, lpConsoleWindow: ^SMALL_RECT) -> BOOL ---
|
||||
GetConsoleCursorInfo :: proc(hConsoleOutput: HANDLE, lpConsoleCursorInfo: PCONSOLE_CURSOR_INFO) -> BOOL ---
|
||||
SetConsoleCursorInfo :: proc(hConsoleOutput: HANDLE, lpConsoleCursorInfo: PCONSOLE_CURSOR_INFO) -> BOOL ---
|
||||
|
||||
|
||||
@@ -1971,6 +1971,16 @@ BITMAPINFO :: struct {
|
||||
bmiColors: [1]RGBQUAD,
|
||||
}
|
||||
|
||||
BITMAP :: struct {
|
||||
bmType: LONG,
|
||||
bmWidth: LONG,
|
||||
bmHeight: LONG,
|
||||
bmWidthBytes: LONG,
|
||||
bmPlanes: WORD,
|
||||
bmBitsPixel: WORD,
|
||||
bmBits: LPVOID,
|
||||
}
|
||||
|
||||
// pixel types
|
||||
PFD_TYPE_RGBA :: 0
|
||||
PFD_TYPE_COLORINDEX :: 1
|
||||
|
||||
@@ -161,6 +161,8 @@ foreign user32 {
|
||||
MonitorFromRect :: proc(lprc: LPRECT, dwFlags: Monitor_From_Flags) -> HMONITOR ---
|
||||
MonitorFromWindow :: proc(hwnd: HWND, dwFlags: Monitor_From_Flags) -> HMONITOR ---
|
||||
EnumDisplayMonitors :: proc(hdc: HDC, lprcClip: LPRECT, lpfnEnum: Monitor_Enum_Proc, dwData: LPARAM) -> BOOL ---
|
||||
|
||||
EnumWindows :: proc(lpEnumFunc: Window_Enum_Proc, lParam: LPARAM) -> BOOL ---
|
||||
|
||||
SetThreadDpiAwarenessContext :: proc(dpiContext: DPI_AWARENESS_CONTEXT) -> DPI_AWARENESS_CONTEXT ---
|
||||
GetThreadDpiAwarenessContext :: proc() -> DPI_AWARENESS_CONTEXT ---
|
||||
@@ -311,6 +313,7 @@ Monitor_From_Flags :: enum DWORD {
|
||||
}
|
||||
|
||||
Monitor_Enum_Proc :: #type proc "stdcall" (HMONITOR, HDC, LPRECT, LPARAM) -> BOOL
|
||||
Window_Enum_Proc :: #type proc "stdcall" (HWND, LPARAM) -> BOOL
|
||||
|
||||
USER_DEFAULT_SCREEN_DPI :: 96
|
||||
DPI_AWARENESS_CONTEXT :: distinct HANDLE
|
||||
|
||||
@@ -116,26 +116,21 @@ run_with_data :: proc(data: rawptr, fn: proc(data: rawptr), init_context: Maybe(
|
||||
}
|
||||
|
||||
run_with_poly_data :: proc(data: $T, fn: proc(data: T), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal)
|
||||
where size_of(T) <= size_of(rawptr) {
|
||||
where size_of(T) <= size_of(rawptr) * MAX_USER_ARGUMENTS {
|
||||
create_and_start_with_poly_data(data, fn, init_context, priority, true)
|
||||
}
|
||||
|
||||
run_with_poly_data2 :: proc(arg1: $T1, arg2: $T2, fn: proc(T1, T2), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal)
|
||||
where size_of(T1) <= size_of(rawptr),
|
||||
size_of(T2) <= size_of(rawptr) {
|
||||
where size_of(T1) + size_of(T2) <= size_of(rawptr) * MAX_USER_ARGUMENTS {
|
||||
create_and_start_with_poly_data2(arg1, arg2, fn, init_context, priority, true)
|
||||
}
|
||||
|
||||
run_with_poly_data3 :: proc(arg1: $T1, arg2: $T2, arg3: $T3, fn: proc(arg1: T1, arg2: T2, arg3: T3), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal)
|
||||
where size_of(T1) <= size_of(rawptr),
|
||||
size_of(T2) <= size_of(rawptr),
|
||||
size_of(T3) <= size_of(rawptr) {
|
||||
where size_of(T1) + size_of(T2) + size_of(T3) <= size_of(rawptr) * MAX_USER_ARGUMENTS {
|
||||
create_and_start_with_poly_data3(arg1, arg2, arg3, fn, init_context, priority, true)
|
||||
}
|
||||
run_with_poly_data4 :: proc(arg1: $T1, arg2: $T2, arg3: $T3, arg4: $T4, fn: proc(arg1: T1, arg2: T2, arg3: T3, arg4: T4), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal)
|
||||
where size_of(T1) <= size_of(rawptr),
|
||||
size_of(T2) <= size_of(rawptr),
|
||||
size_of(T3) <= size_of(rawptr) {
|
||||
where size_of(T1) + size_of(T2) + size_of(T3) + size_of(T4) <= size_of(rawptr) * MAX_USER_ARGUMENTS {
|
||||
create_and_start_with_poly_data4(arg1, arg2, arg3, arg4, fn, init_context, priority, true)
|
||||
}
|
||||
|
||||
@@ -178,7 +173,7 @@ create_and_start_with_data :: proc(data: rawptr, fn: proc(data: rawptr), init_co
|
||||
}
|
||||
|
||||
create_and_start_with_poly_data :: proc(data: $T, fn: proc(data: T), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal, self_cleanup := false) -> ^Thread
|
||||
where size_of(T) <= size_of(rawptr) {
|
||||
where size_of(T) <= size_of(rawptr) * MAX_USER_ARGUMENTS {
|
||||
thread_proc :: proc(t: ^Thread) {
|
||||
fn := cast(proc(T))t.data
|
||||
assert(t.user_index >= 1)
|
||||
@@ -188,96 +183,118 @@ create_and_start_with_poly_data :: proc(data: $T, fn: proc(data: T), init_contex
|
||||
t := create(thread_proc, priority)
|
||||
t.data = rawptr(fn)
|
||||
t.user_index = 1
|
||||
|
||||
data := data
|
||||
mem.copy(&t.user_args[0], &data, size_of(data))
|
||||
|
||||
mem.copy(&t.user_args[0], &data, size_of(T))
|
||||
|
||||
if self_cleanup {
|
||||
t.flags += {.Self_Cleanup}
|
||||
}
|
||||
|
||||
t.init_context = init_context
|
||||
start(t)
|
||||
return t
|
||||
}
|
||||
|
||||
create_and_start_with_poly_data2 :: proc(arg1: $T1, arg2: $T2, fn: proc(T1, T2), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal, self_cleanup := false) -> ^Thread
|
||||
where size_of(T1) <= size_of(rawptr),
|
||||
size_of(T2) <= size_of(rawptr) {
|
||||
where size_of(T1) + size_of(T2) <= size_of(rawptr) * MAX_USER_ARGUMENTS {
|
||||
thread_proc :: proc(t: ^Thread) {
|
||||
fn := cast(proc(T1, T2))t.data
|
||||
assert(t.user_index >= 2)
|
||||
arg1 := (^T1)(&t.user_args[0])^
|
||||
arg2 := (^T2)(&t.user_args[1])^
|
||||
|
||||
user_args := mem.slice_to_bytes(t.user_args[:])
|
||||
arg1 := (^T1)(raw_data(user_args))^
|
||||
arg2 := (^T2)(raw_data(user_args[size_of(T1):]))^
|
||||
|
||||
fn(arg1, arg2)
|
||||
}
|
||||
t := create(thread_proc, priority)
|
||||
t.data = rawptr(fn)
|
||||
t.user_index = 2
|
||||
|
||||
arg1, arg2 := arg1, arg2
|
||||
mem.copy(&t.user_args[0], &arg1, size_of(arg1))
|
||||
mem.copy(&t.user_args[1], &arg2, size_of(arg2))
|
||||
user_args := mem.slice_to_bytes(t.user_args[:])
|
||||
|
||||
n := copy(user_args, mem.ptr_to_bytes(&arg1))
|
||||
_ = copy(user_args[n:], mem.ptr_to_bytes(&arg2))
|
||||
|
||||
if self_cleanup {
|
||||
t.flags += {.Self_Cleanup}
|
||||
}
|
||||
|
||||
t.init_context = init_context
|
||||
start(t)
|
||||
return t
|
||||
}
|
||||
|
||||
create_and_start_with_poly_data3 :: proc(arg1: $T1, arg2: $T2, arg3: $T3, fn: proc(arg1: T1, arg2: T2, arg3: T3), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal, self_cleanup := false) -> ^Thread
|
||||
where size_of(T1) <= size_of(rawptr),
|
||||
size_of(T2) <= size_of(rawptr),
|
||||
size_of(T3) <= size_of(rawptr) {
|
||||
where size_of(T1) + size_of(T2) + size_of(T3) <= size_of(rawptr) * MAX_USER_ARGUMENTS {
|
||||
thread_proc :: proc(t: ^Thread) {
|
||||
fn := cast(proc(T1, T2, T3))t.data
|
||||
assert(t.user_index >= 3)
|
||||
arg1 := (^T1)(&t.user_args[0])^
|
||||
arg2 := (^T2)(&t.user_args[1])^
|
||||
arg3 := (^T3)(&t.user_args[2])^
|
||||
|
||||
user_args := mem.slice_to_bytes(t.user_args[:])
|
||||
arg1 := (^T1)(raw_data(user_args))^
|
||||
arg2 := (^T2)(raw_data(user_args[size_of(T1):]))^
|
||||
arg3 := (^T3)(raw_data(user_args[size_of(T1) + size_of(T2):]))^
|
||||
|
||||
fn(arg1, arg2, arg3)
|
||||
}
|
||||
t := create(thread_proc, priority)
|
||||
t.data = rawptr(fn)
|
||||
t.user_index = 3
|
||||
|
||||
arg1, arg2, arg3 := arg1, arg2, arg3
|
||||
mem.copy(&t.user_args[0], &arg1, size_of(arg1))
|
||||
mem.copy(&t.user_args[1], &arg2, size_of(arg2))
|
||||
mem.copy(&t.user_args[2], &arg3, size_of(arg3))
|
||||
user_args := mem.slice_to_bytes(t.user_args[:])
|
||||
|
||||
n := copy(user_args, mem.ptr_to_bytes(&arg1))
|
||||
n += copy(user_args[n:], mem.ptr_to_bytes(&arg2))
|
||||
_ = copy(user_args[n:], mem.ptr_to_bytes(&arg3))
|
||||
|
||||
if self_cleanup {
|
||||
t.flags += {.Self_Cleanup}
|
||||
}
|
||||
|
||||
t.init_context = init_context
|
||||
start(t)
|
||||
return t
|
||||
}
|
||||
create_and_start_with_poly_data4 :: proc(arg1: $T1, arg2: $T2, arg3: $T3, arg4: $T4, fn: proc(arg1: T1, arg2: T2, arg3: T3, arg4: T4), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal, self_cleanup := false) -> ^Thread
|
||||
where size_of(T1) <= size_of(rawptr),
|
||||
size_of(T2) <= size_of(rawptr),
|
||||
size_of(T3) <= size_of(rawptr) {
|
||||
where size_of(T1) + size_of(T2) + size_of(T3) + size_of(T4) <= size_of(rawptr) * MAX_USER_ARGUMENTS {
|
||||
thread_proc :: proc(t: ^Thread) {
|
||||
fn := cast(proc(T1, T2, T3, T4))t.data
|
||||
assert(t.user_index >= 4)
|
||||
arg1 := (^T1)(&t.user_args[0])^
|
||||
arg2 := (^T2)(&t.user_args[1])^
|
||||
arg3 := (^T3)(&t.user_args[2])^
|
||||
arg4 := (^T4)(&t.user_args[3])^
|
||||
|
||||
user_args := mem.slice_to_bytes(t.user_args[:])
|
||||
arg1 := (^T1)(raw_data(user_args))^
|
||||
arg2 := (^T2)(raw_data(user_args[size_of(T1):]))^
|
||||
arg3 := (^T3)(raw_data(user_args[size_of(T1) + size_of(T2):]))^
|
||||
arg4 := (^T4)(raw_data(user_args[size_of(T1) + size_of(T2) + size_of(T3):]))^
|
||||
|
||||
fn(arg1, arg2, arg3, arg4)
|
||||
}
|
||||
t := create(thread_proc, priority)
|
||||
t.data = rawptr(fn)
|
||||
t.user_index = 4
|
||||
|
||||
arg1, arg2, arg3, arg4 := arg1, arg2, arg3, arg4
|
||||
mem.copy(&t.user_args[0], &arg1, size_of(arg1))
|
||||
mem.copy(&t.user_args[1], &arg2, size_of(arg2))
|
||||
mem.copy(&t.user_args[2], &arg3, size_of(arg3))
|
||||
mem.copy(&t.user_args[3], &arg4, size_of(arg4))
|
||||
user_args := mem.slice_to_bytes(t.user_args[:])
|
||||
|
||||
n := copy(user_args, mem.ptr_to_bytes(&arg1))
|
||||
n += copy(user_args[n:], mem.ptr_to_bytes(&arg2))
|
||||
n += copy(user_args[n:], mem.ptr_to_bytes(&arg3))
|
||||
_ = copy(user_args[n:], mem.ptr_to_bytes(&arg4))
|
||||
|
||||
if self_cleanup {
|
||||
t.flags += {.Self_Cleanup}
|
||||
}
|
||||
|
||||
t.init_context = init_context
|
||||
start(t)
|
||||
return t
|
||||
}
|
||||
|
||||
|
||||
_select_context_for_thread :: proc(init_context: Maybe(runtime.Context)) -> runtime.Context {
|
||||
ctx, ok := init_context.?
|
||||
if !ok {
|
||||
|
||||
@@ -39,6 +39,8 @@ import nvg "vendor:nanovg"
|
||||
import nvg_gl "vendor:nanovg/gl"
|
||||
import fontstash "vendor:fontstash"
|
||||
|
||||
import xlib "vendor:x11/xlib"
|
||||
|
||||
_ :: botan_bindings
|
||||
_ :: botan_blake2b
|
||||
_ :: keccak
|
||||
@@ -76,4 +78,6 @@ _ :: lua_5_4
|
||||
|
||||
_ :: nvg
|
||||
_ :: nvg_gl
|
||||
_ :: fontstash
|
||||
_ :: fontstash
|
||||
|
||||
_ :: xlib
|
||||
@@ -44,7 +44,13 @@ the_basics :: proc() {
|
||||
fmt.println("\n# the basics")
|
||||
|
||||
{ // The Basics
|
||||
fmt.println("Hellope")
|
||||
|
||||
// os.args holds the path to the current executable and any arguments passed to it.
|
||||
if len(os.args) == 1 {
|
||||
fmt.printf("Hellope from %v.\n", os.args[0])
|
||||
} else {
|
||||
fmt.printf("%v, %v! from %v.\n", os.args[1], os.args[2], os.args[0])
|
||||
}
|
||||
|
||||
// Lexical elements and literals
|
||||
// A comment
|
||||
|
||||
@@ -6123,9 +6123,6 @@ gb_internal void check_parsed_files(Checker *c) {
|
||||
TIME_SECTION("calculate global init order");
|
||||
calculate_global_init_order(c);
|
||||
|
||||
TIME_SECTION("check test procedures");
|
||||
check_test_procedures(c);
|
||||
|
||||
TIME_SECTION("add type info for type definitions");
|
||||
add_type_info_for_type_definitions(c);
|
||||
check_merge_queues_into_arrays(c);
|
||||
@@ -6136,6 +6133,11 @@ gb_internal void check_parsed_files(Checker *c) {
|
||||
TIME_SECTION("generate minimum dependency set");
|
||||
generate_minimum_dependency_set(c, c->info.entry_point);
|
||||
|
||||
// NOTE(laytan): has to be ran after generate_minimum_dependency_set,
|
||||
// because that collects the test procedures.
|
||||
TIME_SECTION("check test procedures");
|
||||
check_test_procedures(c);
|
||||
|
||||
TIME_SECTION("check bodies have all been checked");
|
||||
check_unchecked_bodies(c);
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
#include "llvm_backend_stmt.cpp"
|
||||
#include "llvm_backend_proc.cpp"
|
||||
|
||||
char *get_default_microarchitecture() {
|
||||
char * default_march = "generic";
|
||||
String get_default_microarchitecture() {
|
||||
String default_march = str_lit("generic");
|
||||
if (build_context.metrics.arch == TargetArch_amd64) {
|
||||
// NOTE(bill): x86-64-v2 is more than enough for everyone
|
||||
//
|
||||
@@ -32,9 +32,9 @@ char *get_default_microarchitecture() {
|
||||
// x86-64-v4: AVX512F, AVX512BW, AVX512CD, AVX512DQ, AVX512VL
|
||||
if (ODIN_LLVM_MINIMUM_VERSION_12) {
|
||||
if (build_context.metrics.os == TargetOs_freestanding) {
|
||||
default_march = "x86-64";
|
||||
default_march = str_lit("x86-64");
|
||||
} else {
|
||||
default_march = "x86-64-v2";
|
||||
default_march = str_lit("x86-64-v2");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2509,16 +2509,16 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
|
||||
code_mode = LLVMCodeModelKernel;
|
||||
}
|
||||
|
||||
char const *host_cpu_name = LLVMGetHostCPUName();
|
||||
char const *llvm_cpu = get_default_microarchitecture();
|
||||
String host_cpu_name = copy_string(permanent_allocator(), make_string_c(LLVMGetHostCPUName()));
|
||||
String llvm_cpu = get_default_microarchitecture();
|
||||
char const *llvm_features = "";
|
||||
if (build_context.microarch.len != 0) {
|
||||
if (build_context.microarch == "native") {
|
||||
llvm_cpu = host_cpu_name;
|
||||
} else {
|
||||
llvm_cpu = alloc_cstring(permanent_allocator(), build_context.microarch);
|
||||
llvm_cpu = copy_string(permanent_allocator(), build_context.microarch);
|
||||
}
|
||||
if (gb_strcmp(llvm_cpu, host_cpu_name) == 0) {
|
||||
if (llvm_cpu == host_cpu_name) {
|
||||
llvm_features = LLVMGetHostCPUFeatures();
|
||||
}
|
||||
}
|
||||
@@ -2578,7 +2578,7 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
|
||||
|
||||
for (auto const &entry : gen->modules) {
|
||||
LLVMTargetMachineRef target_machine = LLVMCreateTargetMachine(
|
||||
target, target_triple, llvm_cpu,
|
||||
target, target_triple, (const char *)llvm_cpu.text,
|
||||
llvm_features,
|
||||
code_gen_level,
|
||||
reloc_mode,
|
||||
|
||||
274
src/main.cpp
274
src/main.cpp
@@ -199,19 +199,19 @@ gb_internal void print_usage_line(i32 indent, char const *fmt, ...) {
|
||||
}
|
||||
|
||||
gb_internal void usage(String argv0) {
|
||||
print_usage_line(0, "%.*s is a tool for managing Odin source code", LIT(argv0));
|
||||
print_usage_line(0, "%.*s is a tool for managing Odin source code.", LIT(argv0));
|
||||
print_usage_line(0, "Usage:");
|
||||
print_usage_line(1, "%.*s command [arguments]", LIT(argv0));
|
||||
print_usage_line(0, "Commands:");
|
||||
print_usage_line(1, "build compile directory of .odin files, as an executable.");
|
||||
print_usage_line(1, " one must contain the program's entry point, all must be in the same package.");
|
||||
print_usage_line(1, "run same as 'build', but also then runs the newly compiled executable.");
|
||||
print_usage_line(1, "check parse, and type check a directory of .odin files");
|
||||
print_usage_line(1, "strip-semicolon parse, type check, and remove unneeded semicolons from the entire program");
|
||||
print_usage_line(1, "test build and runs procedures with the attribute @(test) in the initial package");
|
||||
print_usage_line(1, "doc generate documentation on a directory of .odin files");
|
||||
print_usage_line(1, "version print version");
|
||||
print_usage_line(1, "report print information useful to reporting a bug");
|
||||
print_usage_line(1, "build Compiles directory of .odin files, as an executable.");
|
||||
print_usage_line(1, " One must contain the program's entry point, all must be in the same package.");
|
||||
print_usage_line(1, "run Same as 'build', but also then runs the newly compiled executable.");
|
||||
print_usage_line(1, "check Parses, and type checks a directory of .odin files.");
|
||||
print_usage_line(1, "strip-semicolon Parses, type checks, and removes unneeded semicolons from the entire program.");
|
||||
print_usage_line(1, "test Builds and runs procedures with the attribute @(test) in the initial package.");
|
||||
print_usage_line(1, "doc Generates documentation on a directory of .odin files.");
|
||||
print_usage_line(1, "version Prints version.");
|
||||
print_usage_line(1, "report Prints information useful to reporting a bug.");
|
||||
print_usage_line(0, "");
|
||||
print_usage_line(0, "For further details on a command, invoke command help:");
|
||||
print_usage_line(1, "e.g. `odin build -help` or `odin help build`");
|
||||
@@ -1580,45 +1580,45 @@ gb_internal void remove_temp_files(lbGenerator *gen) {
|
||||
|
||||
|
||||
gb_internal void print_show_help(String const arg0, String const &command) {
|
||||
print_usage_line(0, "%.*s is a tool for managing Odin source code", LIT(arg0));
|
||||
print_usage_line(0, "%.*s is a tool for managing Odin source code.", LIT(arg0));
|
||||
print_usage_line(0, "Usage:");
|
||||
print_usage_line(1, "%.*s %.*s [arguments]", LIT(arg0), LIT(command));
|
||||
print_usage_line(0, "");
|
||||
|
||||
if (command == "build") {
|
||||
print_usage_line(1, "build Compile directory of .odin files as an executable.");
|
||||
print_usage_line(1, "build Compiles directory of .odin files as an executable.");
|
||||
print_usage_line(2, "One must contain the program's entry point, all must be in the same package.");
|
||||
print_usage_line(2, "Use `-file` to build a single file instead.");
|
||||
print_usage_line(2, "Examples:");
|
||||
print_usage_line(3, "odin build . # Build package in current directory");
|
||||
print_usage_line(3, "odin build <dir> # Build package in <dir>");
|
||||
print_usage_line(3, "odin build filename.odin -file # Build single-file package, must contain entry point.");
|
||||
print_usage_line(3, "odin build . Builds package in current directory.");
|
||||
print_usage_line(3, "odin build <dir> Builds package in <dir>.");
|
||||
print_usage_line(3, "odin build filename.odin -file Builds single-file package, must contain entry point.");
|
||||
} else if (command == "run") {
|
||||
print_usage_line(1, "run Same as 'build', but also then runs the newly compiled executable.");
|
||||
print_usage_line(2, "Append an empty flag and then the args, '-- <args>', to specify args for the output.");
|
||||
print_usage_line(2, "Examples:");
|
||||
print_usage_line(3, "odin run . # Build and run package in current directory");
|
||||
print_usage_line(3, "odin run <dir> # Build and run package in <dir>");
|
||||
print_usage_line(3, "odin run filename.odin -file # Build and run single-file package, must contain entry point.");
|
||||
print_usage_line(3, "odin run . Builds and runs package in current directory.");
|
||||
print_usage_line(3, "odin run <dir> Builds and runs package in <dir>.");
|
||||
print_usage_line(3, "odin run filename.odin -file Builds and runs single-file package, must contain entry point.");
|
||||
} else if (command == "check") {
|
||||
print_usage_line(1, "check Parse and type check directory of .odin files");
|
||||
print_usage_line(1, "check Parses and type checks directory of .odin files.");
|
||||
print_usage_line(2, "Examples:");
|
||||
print_usage_line(3, "odin check . # Type check package in current directory");
|
||||
print_usage_line(3, "odin check <dir> # Type check package in <dir>");
|
||||
print_usage_line(3, "odin check filename.odin -file # Type check single-file package, must contain entry point.");
|
||||
print_usage_line(3, "odin check . Type checks package in current directory.");
|
||||
print_usage_line(3, "odin check <dir> Type checks package in <dir>.");
|
||||
print_usage_line(3, "odin check filename.odin -file Type checks single-file package, must contain entry point.");
|
||||
} else if (command == "test") {
|
||||
print_usage_line(1, "test Build and runs procedures with the attribute @(test) in the initial package");
|
||||
print_usage_line(1, "test Builds and runs procedures with the attribute @(test) in the initial package.");
|
||||
} else if (command == "doc") {
|
||||
print_usage_line(1, "doc generate documentation from a directory of .odin files");
|
||||
print_usage_line(1, "doc Generates documentation from a directory of .odin files.");
|
||||
print_usage_line(2, "Examples:");
|
||||
print_usage_line(3, "odin doc . # Generate documentation on package in current directory");
|
||||
print_usage_line(3, "odin doc <dir> # Generate documentation on package in <dir>");
|
||||
print_usage_line(3, "odin doc filename.odin -file # Generate documentation on single-file package.");
|
||||
print_usage_line(3, "odin doc . Generates documentation on package in current directory.");
|
||||
print_usage_line(3, "odin doc <dir> Generates documentation on package in <dir>.");
|
||||
print_usage_line(3, "odin doc filename.odin -file Generates documentation on single-file package.");
|
||||
} else if (command == "version") {
|
||||
print_usage_line(1, "version print version");
|
||||
print_usage_line(1, "version Prints version.");
|
||||
} else if (command == "strip-semicolon") {
|
||||
print_usage_line(1, "strip-semicolon");
|
||||
print_usage_line(2, "Parse and type check .odin file(s) and then remove unneeded semicolons from the entire project");
|
||||
print_usage_line(2, "Parses and type checks .odin file(s) and then removes unneeded semicolons from the entire project.");
|
||||
}
|
||||
|
||||
bool doc = command == "doc";
|
||||
@@ -1642,237 +1642,240 @@ gb_internal void print_show_help(String const arg0, String const &command) {
|
||||
|
||||
if (doc) {
|
||||
print_usage_line(1, "-short");
|
||||
print_usage_line(2, "Show shortened documentation for the packages");
|
||||
print_usage_line(2, "Shows shortened documentation for the packages.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-all-packages");
|
||||
print_usage_line(2, "Generates documentation for all packages used in the current project");
|
||||
print_usage_line(2, "Generates documentation for all packages used in the current project.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-doc-format");
|
||||
print_usage_line(2, "Generates documentation as the .odin-doc format (useful for external tooling)");
|
||||
print_usage_line(2, "Generates documentation as the .odin-doc format (useful for external tooling).");
|
||||
print_usage_line(0, "");
|
||||
}
|
||||
|
||||
if (run_or_build) {
|
||||
print_usage_line(1, "-out:<filepath>");
|
||||
print_usage_line(2, "Set the file name of the outputted executable");
|
||||
print_usage_line(2, "Sets the file name of the outputted executable.");
|
||||
print_usage_line(2, "Example: -out:foo.exe");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-o:<string>");
|
||||
print_usage_line(2, "Set the optimization mode for compilation");
|
||||
print_usage_line(2, "Sets the optimization mode for compilation.");
|
||||
print_usage_line(2, "Available options:");
|
||||
print_usage_line(3, "-o:none");
|
||||
print_usage_line(3, "-o:minimal");
|
||||
print_usage_line(3, "-o:size");
|
||||
print_usage_line(3, "-o:speed");
|
||||
if (LB_USE_NEW_PASS_SYSTEM) {
|
||||
print_usage_line(2, "Accepted values: none, minimal, size, speed, aggressive");
|
||||
} else {
|
||||
print_usage_line(2, "Accepted values: none, minimal, size, speed");
|
||||
print_usage_line(3, "-o:aggressive");
|
||||
}
|
||||
print_usage_line(2, "Example: -o:speed");
|
||||
print_usage_line(2, "The default is -o:minimal");
|
||||
print_usage_line(2, "The default is -o:minimal.");
|
||||
print_usage_line(0, "");
|
||||
}
|
||||
|
||||
if (check) {
|
||||
print_usage_line(1, "-show-timings");
|
||||
print_usage_line(2, "Shows basic overview of the timings of different stages within the compiler in milliseconds");
|
||||
print_usage_line(2, "Shows basic overview of the timings of different stages within the compiler in milliseconds.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-show-more-timings");
|
||||
print_usage_line(2, "Shows an advanced overview of the timings of different stages within the compiler in milliseconds");
|
||||
print_usage_line(2, "Shows an advanced overview of the timings of different stages within the compiler in milliseconds.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-show-system-calls");
|
||||
print_usage_line(2, "Prints the whole command and arguments for calls to external tools like linker and assembler");
|
||||
print_usage_line(2, "Prints the whole command and arguments for calls to external tools like linker and assembler.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-export-timings:<format>");
|
||||
print_usage_line(2, "Export timings to one of a few formats. Requires `-show-timings` or `-show-more-timings`");
|
||||
print_usage_line(2, "Exports timings to one of a few formats. Requires `-show-timings` or `-show-more-timings`.");
|
||||
print_usage_line(2, "Available options:");
|
||||
print_usage_line(3, "-export-timings:json Export compile time stats to JSON");
|
||||
print_usage_line(3, "-export-timings:csv Export compile time stats to CSV");
|
||||
print_usage_line(3, "-export-timings:json Exports compile time stats to JSON.");
|
||||
print_usage_line(3, "-export-timings:csv Exports compile time stats to CSV.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-export-timings-file:<filename>");
|
||||
print_usage_line(2, "Specify the filename for `-export-timings`");
|
||||
print_usage_line(2, "Specifies the filename for `-export-timings`.");
|
||||
print_usage_line(2, "Example: -export-timings-file:timings.json");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-thread-count:<integer>");
|
||||
print_usage_line(2, "Override the number of threads the compiler will use to compile with");
|
||||
print_usage_line(2, "Overrides the number of threads the compiler will use to compile with.");
|
||||
print_usage_line(2, "Example: -thread-count:2");
|
||||
print_usage_line(0, "");
|
||||
}
|
||||
|
||||
if (check_only) {
|
||||
print_usage_line(1, "-show-unused");
|
||||
print_usage_line(2, "Shows unused package declarations within the current project");
|
||||
print_usage_line(2, "Shows unused package declarations within the current project.");
|
||||
print_usage_line(0, "");
|
||||
print_usage_line(1, "-show-unused-with-location");
|
||||
print_usage_line(2, "Shows unused package declarations within the current project with the declarations source location");
|
||||
print_usage_line(2, "Shows unused package declarations within the current project with the declarations source location.");
|
||||
print_usage_line(0, "");
|
||||
}
|
||||
|
||||
if (run_or_build) {
|
||||
print_usage_line(1, "-keep-temp-files");
|
||||
print_usage_line(2, "Keeps the temporary files generated during compilation");
|
||||
print_usage_line(2, "Keeps the temporary files generated during compilation.");
|
||||
print_usage_line(0, "");
|
||||
} else if (strip_semicolon) {
|
||||
print_usage_line(1, "-keep-temp-files");
|
||||
print_usage_line(2, "Keeps the temporary files generated during stripping the unneeded semicolons from files");
|
||||
print_usage_line(2, "Keeps the temporary files generated during stripping the unneeded semicolons from files.");
|
||||
print_usage_line(0, "");
|
||||
}
|
||||
|
||||
if (check) {
|
||||
print_usage_line(1, "-collection:<name>=<filepath>");
|
||||
print_usage_line(2, "Defines a library collection used for imports");
|
||||
print_usage_line(2, "Defines a library collection used for imports.");
|
||||
print_usage_line(2, "Example: -collection:shared=dir/to/shared");
|
||||
print_usage_line(2, "Usage in Code:");
|
||||
print_usage_line(3, "import \"shared:foo\"");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-define:<name>=<value>");
|
||||
print_usage_line(2, "Defines a scalar boolean, integer or string as global constant");
|
||||
print_usage_line(2, "Defines a scalar boolean, integer or string as global constant.");
|
||||
print_usage_line(2, "Example: -define:SPAM=123");
|
||||
print_usage_line(2, "To use: #config(SPAM, default_value)");
|
||||
print_usage_line(2, "Usage in code:");
|
||||
print_usage_line(3, "#config(SPAM, default_value)");
|
||||
print_usage_line(0, "");
|
||||
}
|
||||
|
||||
if (build) {
|
||||
print_usage_line(1, "-build-mode:<mode>");
|
||||
print_usage_line(2, "Sets the build mode");
|
||||
print_usage_line(2, "Sets the build mode.");
|
||||
print_usage_line(2, "Available options:");
|
||||
print_usage_line(3, "-build-mode:exe Build as an executable");
|
||||
print_usage_line(3, "-build-mode:dll Build as a dynamically linked library");
|
||||
print_usage_line(3, "-build-mode:shared Build as a dynamically linked library");
|
||||
print_usage_line(3, "-build-mode:obj Build as an object file");
|
||||
print_usage_line(3, "-build-mode:object Build as an object file");
|
||||
print_usage_line(3, "-build-mode:assembly Build as an assembly file");
|
||||
print_usage_line(3, "-build-mode:assembler Build as an assembly file");
|
||||
print_usage_line(3, "-build-mode:asm Build as an assembly file");
|
||||
print_usage_line(3, "-build-mode:llvm-ir Build as an LLVM IR file");
|
||||
print_usage_line(3, "-build-mode:llvm Build as an LLVM IR file");
|
||||
print_usage_line(3, "-build-mode:exe Builds as an executable.");
|
||||
print_usage_line(3, "-build-mode:dll Builds as a dynamically linked library.");
|
||||
print_usage_line(3, "-build-mode:shared Builds as a dynamically linked library.");
|
||||
print_usage_line(3, "-build-mode:obj Builds as an object file.");
|
||||
print_usage_line(3, "-build-mode:object Builds as an object file.");
|
||||
print_usage_line(3, "-build-mode:assembly Builds as an assembly file.");
|
||||
print_usage_line(3, "-build-mode:assembler Builds as an assembly file.");
|
||||
print_usage_line(3, "-build-mode:asm Builds as an assembly file.");
|
||||
print_usage_line(3, "-build-mode:llvm-ir Builds as an LLVM IR file.");
|
||||
print_usage_line(3, "-build-mode:llvm Builds as an LLVM IR file.");
|
||||
print_usage_line(0, "");
|
||||
}
|
||||
|
||||
if (check) {
|
||||
print_usage_line(1, "-target:<string>");
|
||||
print_usage_line(2, "Sets the target for the executable to be built in");
|
||||
print_usage_line(2, "Sets the target for the executable to be built in.");
|
||||
print_usage_line(0, "");
|
||||
}
|
||||
|
||||
if (run_or_build) {
|
||||
print_usage_line(1, "-debug");
|
||||
print_usage_line(2, "Enabled debug information, and defines the global constant ODIN_DEBUG to be 'true'");
|
||||
print_usage_line(2, "Enables debug information, and defines the global constant ODIN_DEBUG to be 'true'.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-disable-assert");
|
||||
print_usage_line(2, "Disable the code generation of the built-in run-time 'assert' procedure, and defines the global constant ODIN_DISABLE_ASSERT to be 'true'");
|
||||
print_usage_line(2, "Disables the code generation of the built-in run-time 'assert' procedure, and defines the global constant ODIN_DISABLE_ASSERT to be 'true'.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-no-bounds-check");
|
||||
print_usage_line(2, "Disables bounds checking program wide");
|
||||
print_usage_line(2, "Disables bounds checking program wide.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-no-crt");
|
||||
print_usage_line(2, "Disables automatic linking with the C Run Time");
|
||||
print_usage_line(2, "Disables automatic linking with the C Run Time.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-no-thread-local");
|
||||
print_usage_line(2, "Ignore @thread_local attribute, effectively treating the program as if it is single-threaded");
|
||||
print_usage_line(2, "Ignores @thread_local attribute, effectively treating the program as if it is single-threaded.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-lld");
|
||||
print_usage_line(2, "Use the LLD linker rather than the default");
|
||||
print_usage_line(2, "Uses the LLD linker rather than the default.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-use-separate-modules");
|
||||
print_usage_line(1, "[EXPERIMENTAL]");
|
||||
print_usage_line(2, "The backend generates multiple build units which are then linked together");
|
||||
print_usage_line(2, "Normally, a single build unit is generated for a standard project");
|
||||
print_usage_line(2, "The backend generates multiple build units which are then linked together.");
|
||||
print_usage_line(2, "Normally, a single build unit is generated for a standard project.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
}
|
||||
|
||||
if (check) {
|
||||
print_usage_line(1, "-no-threaded-checker");
|
||||
print_usage_line(2, "Disabled multithreading in the semantic checker stage");
|
||||
print_usage_line(2, "Disables multithreading in the semantic checker stage.");
|
||||
print_usage_line(0, "");
|
||||
}
|
||||
|
||||
if (check) {
|
||||
print_usage_line(1, "-vet");
|
||||
print_usage_line(2, "Do extra checks on the code");
|
||||
print_usage_line(2, "Does extra checks on the code.");
|
||||
print_usage_line(2, "Extra checks include:");
|
||||
print_usage_line(2, "-vet-unused");
|
||||
print_usage_line(2, "-vet-shadowing");
|
||||
print_usage_line(2, "-vet-using-stmt");
|
||||
print_usage_line(3, "-vet-unused");
|
||||
print_usage_line(3, "-vet-shadowing");
|
||||
print_usage_line(3, "-vet-using-stmt");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-vet-unused");
|
||||
print_usage_line(2, "Checks for unused declarations");
|
||||
print_usage_line(2, "Checks for unused declarations.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-vet-shadowing");
|
||||
print_usage_line(2, "Checks for variable shadowing within procedures");
|
||||
print_usage_line(2, "Checks for variable shadowing within procedures.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-vet-using-stmt");
|
||||
print_usage_line(2, "Checks for the use of 'using' as a statement");
|
||||
print_usage_line(2, "'using' is considered bad practice outside of immediate refactoring");
|
||||
print_usage_line(2, "Checks for the use of 'using' as a statement.");
|
||||
print_usage_line(2, "'using' is considered bad practice outside of immediate refactoring.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-vet-using-param");
|
||||
print_usage_line(2, "Checks for the use of 'using' on procedure parameters");
|
||||
print_usage_line(2, "'using' is considered bad practice outside of immediate refactoring");
|
||||
print_usage_line(2, "Checks for the use of 'using' on procedure parameters.");
|
||||
print_usage_line(2, "'using' is considered bad practice outside of immediate refactoring.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-vet-style");
|
||||
print_usage_line(2, "Errs on missing trailing commas followed by a newline");
|
||||
print_usage_line(2, "Errs on deprecated syntax");
|
||||
print_usage_line(2, "Does not err on unneeded tokens (unlike -strict-style)");
|
||||
print_usage_line(2, "Errs on missing trailing commas followed by a newline.");
|
||||
print_usage_line(2, "Errs on deprecated syntax.");
|
||||
print_usage_line(2, "Does not err on unneeded tokens (unlike -strict-style).");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-vet-semicolon");
|
||||
print_usage_line(2, "Errs on unneeded semicolons");
|
||||
print_usage_line(2, "Errs on unneeded semicolons.");
|
||||
print_usage_line(0, "");
|
||||
}
|
||||
|
||||
if (check) {
|
||||
print_usage_line(1, "-ignore-unknown-attributes");
|
||||
print_usage_line(2, "Ignores unknown attributes");
|
||||
print_usage_line(2, "This can be used with metaprogramming tools");
|
||||
print_usage_line(2, "Ignores unknown attributes.");
|
||||
print_usage_line(2, "This can be used with metaprogramming tools.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
if (command != "test") {
|
||||
print_usage_line(1, "-no-entry-point");
|
||||
print_usage_line(2, "Removes default requirement of an entry point (e.g. main procedure)");
|
||||
print_usage_line(2, "Removes default requirement of an entry point (e.g. main procedure).");
|
||||
print_usage_line(0, "");
|
||||
}
|
||||
}
|
||||
|
||||
if (test_only) {
|
||||
print_usage_line(1, "-test-name:<string>");
|
||||
print_usage_line(2, "Run specific test only by name");
|
||||
print_usage_line(2, "Runs specific test only by name.");
|
||||
print_usage_line(0, "");
|
||||
}
|
||||
|
||||
if (run_or_build) {
|
||||
print_usage_line(1, "-minimum-os-version:<string>");
|
||||
print_usage_line(2, "Sets the minimum OS version targeted by the application");
|
||||
print_usage_line(2, "e.g. -minimum-os-version:12.0.0");
|
||||
print_usage_line(2, "(Only used when target is Darwin)");
|
||||
print_usage_line(2, "Sets the minimum OS version targeted by the application.");
|
||||
print_usage_line(2, "Example: -minimum-os-version:12.0.0");
|
||||
print_usage_line(2, "(Only used when target is Darwin.)");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-extra-linker-flags:<string>");
|
||||
print_usage_line(2, "Adds extra linker specific flags in a string");
|
||||
print_usage_line(2, "Adds extra linker specific flags in a string.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-extra-assembler-flags:<string>");
|
||||
print_usage_line(2, "Adds extra assembler specific flags in a string");
|
||||
print_usage_line(2, "Adds extra assembler specific flags in a string.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-microarch:<string>");
|
||||
print_usage_line(2, "Specifies the specific micro-architecture for the build in a string");
|
||||
print_usage_line(2, "Specifies the specific micro-architecture for the build in a string.");
|
||||
print_usage_line(2, "Examples:");
|
||||
print_usage_line(3, "-microarch:sandybridge");
|
||||
print_usage_line(3, "-microarch:native");
|
||||
@@ -1880,74 +1883,77 @@ gb_internal void print_show_help(String const arg0, String const &command) {
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-reloc-mode:<string>");
|
||||
print_usage_line(2, "Specifies the reloc mode");
|
||||
print_usage_line(2, "Options:");
|
||||
print_usage_line(3, "default");
|
||||
print_usage_line(3, "static");
|
||||
print_usage_line(3, "pic");
|
||||
print_usage_line(3, "dynamic-no-pic");
|
||||
print_usage_line(2, "Specifies the reloc mode.");
|
||||
print_usage_line(2, "Available options:");
|
||||
print_usage_line(3, "-reloc-mode:default");
|
||||
print_usage_line(3, "-reloc-mode:static");
|
||||
print_usage_line(3, "-reloc-mode:pic");
|
||||
print_usage_line(3, "-reloc-mode:dynamic-no-pic");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-disable-red-zone");
|
||||
print_usage_line(2, "Disable red zone on a supported freestanding target");
|
||||
print_usage_line(2, "Disables red zone on a supported freestanding target.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-dynamic-map-calls");
|
||||
print_usage_line(2, "Use dynamic map calls to minimize code generation at the cost of runtime execution");
|
||||
print_usage_line(2, "Uses dynamic map calls to minimize code generation at the cost of runtime execution.");
|
||||
print_usage_line(0, "");
|
||||
}
|
||||
|
||||
if (check) {
|
||||
print_usage_line(1, "-disallow-do");
|
||||
print_usage_line(2, "Disallows the 'do' keyword in the project");
|
||||
print_usage_line(2, "Disallows the 'do' keyword in the project.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-default-to-nil-allocator");
|
||||
print_usage_line(2, "Sets the default allocator to be the nil_allocator, an allocator which does nothing");
|
||||
print_usage_line(2, "Sets the default allocator to be the nil_allocator, an allocator which does nothing.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-strict-style");
|
||||
print_usage_line(2, "Errs on unneeded tokens, such as unneeded semicolons");
|
||||
print_usage_line(2, "Errs on missing trailing commas followed by a newline");
|
||||
print_usage_line(2, "Errs on deprecated syntax");
|
||||
print_usage_line(2, "Errs on unneeded tokens, such as unneeded semicolons.");
|
||||
print_usage_line(2, "Errs on missing trailing commas followed by a newline.");
|
||||
print_usage_line(2, "Errs on deprecated syntax.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-ignore-warnings");
|
||||
print_usage_line(2, "Ignores warning messages");
|
||||
print_usage_line(2, "Ignores warning messages.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-warnings-as-errors");
|
||||
print_usage_line(2, "Treats warning messages as error messages");
|
||||
print_usage_line(2, "Treats warning messages as error messages.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-terse-errors");
|
||||
print_usage_line(2, "Prints a terse error message without showing the code on that line and the location in that line");
|
||||
print_usage_line(2, "Prints a terse error message without showing the code on that line and the location in that line.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-error-pos-style:<string>");
|
||||
print_usage_line(2, "Options are 'unix', 'odin' and 'default' (odin)");
|
||||
print_usage_line(2, "'odin' file/path(45:3)");
|
||||
print_usage_line(2, "'unix' file/path:45:3:");
|
||||
print_usage_line(2, "Available options:");
|
||||
print_usage_line(3, "-error-pos-style:unix file/path:45:3:");
|
||||
print_usage_line(3, "-error-pos-style:odin file/path(45:3)");
|
||||
print_usage_line(3, "-error-pos-style:default (Defaults to 'odin'.)");
|
||||
print_usage_line(0, "");
|
||||
|
||||
|
||||
print_usage_line(1, "-max-error-count:<integer>");
|
||||
print_usage_line(2, "Set the maximum number of errors that can be displayed before the compiler terminates");
|
||||
print_usage_line(2, "Must be an integer >0");
|
||||
print_usage_line(2, "If not set, the default max error count is %d", DEFAULT_MAX_ERROR_COLLECTOR_COUNT);
|
||||
print_usage_line(2, "Sets the maximum number of errors that can be displayed before the compiler terminates.");
|
||||
print_usage_line(2, "Must be an integer >0.");
|
||||
print_usage_line(2, "If not set, the default max error count is %d.", DEFAULT_MAX_ERROR_COLLECTOR_COUNT);
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-foreign-error-procedures");
|
||||
print_usage_line(2, "States that the error procedues used in the runtime are defined in a separate translation unit");
|
||||
print_usage_line(2, "States that the error procedures used in the runtime are defined in a separate translation unit.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
}
|
||||
|
||||
if (run_or_build) {
|
||||
print_usage_line(1, "-sanitize:<string>");
|
||||
print_usage_line(1, "Enables sanitization analysis");
|
||||
print_usage_line(1, "Options are 'address', 'memory', and 'thread'");
|
||||
print_usage_line(1, "NOTE: This flag can be used multiple times");
|
||||
print_usage_line(2, "Enables sanitization analysis.");
|
||||
print_usage_line(2, "Available options:");
|
||||
print_usage_line(3, "-sanitize:address");
|
||||
print_usage_line(3, "-sanitize:memory");
|
||||
print_usage_line(3, "-sanitize:thread");
|
||||
print_usage_line(2, "NOTE: This flag can be used multiple times.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
}
|
||||
@@ -1956,27 +1962,27 @@ gb_internal void print_show_help(String const arg0, String const &command) {
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
print_usage_line(1, "-ignore-vs-search");
|
||||
print_usage_line(2, "[Windows only]");
|
||||
print_usage_line(2, "Ignores the Visual Studio search for library paths");
|
||||
print_usage_line(2, "Ignores the Visual Studio search for library paths.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-resource:<filepath>");
|
||||
print_usage_line(2, "[Windows only]");
|
||||
print_usage_line(2, "Defines the resource file for the executable");
|
||||
print_usage_line(2, "Defines the resource file for the executable.");
|
||||
print_usage_line(2, "Example: -resource:path/to/file.rc");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-pdb-name:<filepath>");
|
||||
print_usage_line(2, "[Windows only]");
|
||||
print_usage_line(2, "Defines the generated PDB name when -debug is enabled");
|
||||
print_usage_line(2, "Defines the generated PDB name when -debug is enabled.");
|
||||
print_usage_line(2, "Example: -pdb-name:different.pdb");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-subsystem:<option>");
|
||||
print_usage_line(2, "[Windows only]");
|
||||
print_usage_line(2, "Defines the subsystem for the application");
|
||||
print_usage_line(2, "Defines the subsystem for the application.");
|
||||
print_usage_line(2, "Available options:");
|
||||
print_usage_line(3, "console");
|
||||
print_usage_line(3, "windows");
|
||||
print_usage_line(3, "-subsystem:console");
|
||||
print_usage_line(3, "-subsystem:windows");
|
||||
print_usage_line(0, "");
|
||||
|
||||
#endif
|
||||
@@ -2538,6 +2544,7 @@ int main(int arg_count, char const **arg_ptr) {
|
||||
}
|
||||
}
|
||||
|
||||
String default_march = get_default_microarchitecture();
|
||||
if (print_microarch_list) {
|
||||
if (build_context.microarch != "?") {
|
||||
gb_printf("Unknown microarchitecture '%.*s'.\n", LIT(build_context.microarch));
|
||||
@@ -2548,8 +2555,6 @@ int main(int arg_count, char const **arg_ptr) {
|
||||
String march_list = target_microarch_list[build_context.metrics.arch];
|
||||
String_Iterator it = {march_list, 0};
|
||||
|
||||
String default_march = make_string_c(get_default_microarchitecture());
|
||||
|
||||
for (;;) {
|
||||
String str = string_split_iterator(&it, ',');
|
||||
if (str == "") break;
|
||||
@@ -2568,6 +2573,7 @@ int main(int arg_count, char const **arg_ptr) {
|
||||
}
|
||||
|
||||
if (build_context.show_debug_messages) {
|
||||
debugf("Selected microarch: %.*s\n", LIT(default_march));
|
||||
for_array(i, build_context.build_paths) {
|
||||
String build_path = path_to_string(heap_allocator(), build_context.build_paths[i]);
|
||||
debugf("build_paths[%ld]: %.*s\n", i, LIT(build_path));
|
||||
|
||||
@@ -1,9 +1,26 @@
|
||||
ODIN=../../odin
|
||||
PYTHON=$(shell which python3)
|
||||
|
||||
all: download_test_assets image_test compress_test strings_test hash_test crypto_test noise_test encoding_test \
|
||||
math_test linalg_glsl_math_test filepath_test reflect_test os_exit_test i18n_test match_test c_libc_test net_test \
|
||||
fmt_test
|
||||
all: c_libc_test \
|
||||
compress_test \
|
||||
crypto_test \
|
||||
download_test_assets \
|
||||
encoding_test \
|
||||
filepath_test \
|
||||
fmt_test \
|
||||
hash_test \
|
||||
i18n_test \
|
||||
image_test \
|
||||
linalg_glsl_math_test \
|
||||
match_test \
|
||||
math_test \
|
||||
net_test \
|
||||
noise_test \
|
||||
os_exit_test \
|
||||
reflect_test \
|
||||
slice_test \
|
||||
strings_test \
|
||||
thread_test
|
||||
|
||||
download_test_assets:
|
||||
$(PYTHON) download_assets.py
|
||||
@@ -44,6 +61,9 @@ filepath_test:
|
||||
reflect_test:
|
||||
$(ODIN) run reflect/test_core_reflect.odin -file -collection:tests=.. -out:test_core_reflect
|
||||
|
||||
slice_test:
|
||||
$(ODIN) run slice/test_core_slice.odin -file -out:test_core_slice
|
||||
|
||||
os_exit_test:
|
||||
$(ODIN) run os/test_core_os_exit.odin -file -out:test_core_os_exit && exit 1 || exit 0
|
||||
|
||||
@@ -61,3 +81,6 @@ net_test:
|
||||
|
||||
fmt_test:
|
||||
$(ODIN) run fmt -out:test_core_fmt
|
||||
|
||||
thread_test:
|
||||
$(ODIN) run thread -out:test_core_thread
|
||||
|
||||
@@ -66,6 +66,11 @@ echo Running core:reflect tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run reflect %COMMON% %COLLECTION% -out:test_core_reflect.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:slice tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run slice %COMMON% -out:test_core_slice.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:text/i18n tests
|
||||
echo ---
|
||||
@@ -85,3 +90,8 @@ echo ---
|
||||
echo Running core:container tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run container %COMMON% %COLLECTION% -out:test_core_container.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:thread tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run thread %COMMON% %COLLECTION% -out:test_core_thread.exe || exit /b
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package test_core_slice
|
||||
|
||||
import "core:slice"
|
||||
import "core:strings"
|
||||
import "core:testing"
|
||||
import "core:fmt"
|
||||
import "core:os"
|
||||
@@ -30,6 +31,7 @@ when ODIN_TEST {
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
test_sort_with_indices(&t)
|
||||
test_binary_search(&t)
|
||||
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
@@ -180,3 +182,64 @@ test_sort_by_indices :: proc(t: ^testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_binary_search :: proc(t: ^testing.T) {
|
||||
builder := strings.Builder{}
|
||||
defer strings.builder_destroy(&builder)
|
||||
|
||||
test_search :: proc(t: ^testing.T, b: ^strings.Builder, s: []i32, v: i32) -> (int, bool) {
|
||||
log(t, fmt.sbprintf(b, "Searching for %v in %v", v, s))
|
||||
strings.builder_reset(b)
|
||||
index, found := slice.binary_search(s, v)
|
||||
log(t, fmt.sbprintf(b, "index: %v, found: %v", index, found))
|
||||
strings.builder_reset(b )
|
||||
|
||||
return index, found
|
||||
}
|
||||
|
||||
index: int
|
||||
found: bool
|
||||
|
||||
s := []i32{0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55}
|
||||
|
||||
index, found = test_search(t, &builder, s, 13)
|
||||
expect(t, index == 9, "Expected index to be 9.")
|
||||
expect(t, found == true, "Expected found to be true.")
|
||||
|
||||
index, found = test_search(t, &builder, s, 4)
|
||||
expect(t, index == 7, "Expected index to be 7.")
|
||||
expect(t, found == false, "Expected found to be false.")
|
||||
|
||||
index, found = test_search(t, &builder, s, 100)
|
||||
expect(t, index == 13, "Expected index to be 13.")
|
||||
expect(t, found == false, "Expected found to be false.")
|
||||
|
||||
index, found = test_search(t, &builder, s, 1)
|
||||
expect(t, index >= 1 && index <= 4, "Expected index to be 1, 2, 3, or 4.")
|
||||
expect(t, found == true, "Expected found to be true.")
|
||||
|
||||
index, found = test_search(t, &builder, s, -1)
|
||||
expect(t, index == 0, "Expected index to be 0.")
|
||||
expect(t, found == false, "Expected found to be false.")
|
||||
|
||||
a := []i32{}
|
||||
|
||||
index, found = test_search(t, &builder, a, 13)
|
||||
expect(t, index == 0, "Expected index to be 0.")
|
||||
expect(t, found == false, "Expected found to be false.")
|
||||
|
||||
b := []i32{1}
|
||||
|
||||
index, found = test_search(t, &builder, b, 13)
|
||||
expect(t, index == 1, "Expected index to be 1.")
|
||||
expect(t, found == false, "Expected found to be false.")
|
||||
|
||||
index, found = test_search(t, &builder, b, 1)
|
||||
expect(t, index == 0, "Expected index to be 0.")
|
||||
expect(t, found == true, "Expected found to be true.")
|
||||
|
||||
index, found = test_search(t, &builder, b, 0)
|
||||
expect(t, index == 0, "Expected index to be 0.")
|
||||
expect(t, found == false, "Expected found to be false.")
|
||||
}
|
||||
|
||||
84
tests/core/thread/test_core_thread.odin
Normal file
84
tests/core/thread/test_core_thread.odin
Normal file
@@ -0,0 +1,84 @@
|
||||
package test_core_thread
|
||||
|
||||
import "core:testing"
|
||||
import "core:thread"
|
||||
import "core:fmt"
|
||||
import "core:os"
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
|
||||
t := &testing.T{}
|
||||
|
||||
when ODIN_TEST {
|
||||
expect :: testing.expect
|
||||
log :: testing.log
|
||||
} else {
|
||||
expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
|
||||
TEST_count += 1
|
||||
if !condition {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v] %v\n", loc, message)
|
||||
return
|
||||
}
|
||||
}
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
poly_data_test(t)
|
||||
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
poly_data_test :: proc(_t: ^testing.T) {
|
||||
MAX :: size_of(rawptr) * thread.MAX_USER_ARGUMENTS
|
||||
|
||||
@static poly_data_test_t: ^testing.T
|
||||
poly_data_test_t = _t
|
||||
|
||||
b: [MAX]byte = 8
|
||||
t1 := thread.create_and_start_with_poly_data(b, proc(b: [MAX]byte) {
|
||||
b_expect: [MAX]byte = 8
|
||||
expect(poly_data_test_t, b == b_expect, "thread poly data not correct")
|
||||
})
|
||||
defer free(t1)
|
||||
|
||||
b1: [3]uintptr = 1
|
||||
b2: [MAX / 2]byte = 3
|
||||
t2 := thread.create_and_start_with_poly_data2(b1, b2, proc(b: [3]uintptr, b2: [MAX / 2]byte) {
|
||||
b_expect: [3]uintptr = 1
|
||||
b2_expect: [MAX / 2]byte = 3
|
||||
expect(poly_data_test_t, b == b_expect, "thread poly data not correct")
|
||||
expect(poly_data_test_t, b2 == b2_expect, "thread poly data not correct")
|
||||
})
|
||||
defer free(t2)
|
||||
|
||||
t3 := thread.create_and_start_with_poly_data3(b1, b2, uintptr(333), proc(b: [3]uintptr, b2: [MAX / 2]byte, b3: uintptr) {
|
||||
b_expect: [3]uintptr = 1
|
||||
b2_expect: [MAX / 2]byte = 3
|
||||
|
||||
expect(poly_data_test_t, b == b_expect, "thread poly data not correct")
|
||||
expect(poly_data_test_t, b2 == b2_expect, "thread poly data not correct")
|
||||
expect(poly_data_test_t, b3 == 333, "thread poly data not correct")
|
||||
})
|
||||
defer free(t3)
|
||||
|
||||
t4 := thread.create_and_start_with_poly_data4(uintptr(111), b1, uintptr(333), u8(5), proc(n: uintptr, b: [3]uintptr, n2: uintptr, n4: u8) {
|
||||
b_expect: [3]uintptr = 1
|
||||
|
||||
expect(poly_data_test_t, n == 111, "thread poly data not correct")
|
||||
expect(poly_data_test_t, b == b_expect, "thread poly data not correct")
|
||||
expect(poly_data_test_t, n2 == 333, "thread poly data not correct")
|
||||
expect(poly_data_test_t, n4 == 5, "thread poly data not correct")
|
||||
})
|
||||
defer free(t4)
|
||||
|
||||
thread.join_multiple(t1, t2, t3, t4)
|
||||
}
|
||||
BIN
vendor/raylib/linux/libraygui.a
vendored
Normal file
BIN
vendor/raylib/linux/libraygui.a
vendored
Normal file
Binary file not shown.
BIN
vendor/raylib/linux/libraygui.so.3.6
vendored
Executable file
BIN
vendor/raylib/linux/libraygui.so.3.6
vendored
Executable file
Binary file not shown.
29
vendor/raylib/raygui.odin
vendored
29
vendor/raylib/raygui.odin
vendored
@@ -16,23 +16,9 @@ when ODIN_OS == .Windows {
|
||||
}
|
||||
} else when ODIN_OS == .Linux {
|
||||
when RAYGUI_SHARED {
|
||||
// Note(bumbread): can't panic here, because the users might be expecting to
|
||||
// only use raylib. Let's have them get the error at link-time instead..
|
||||
//#panic("Cannot link libraygui.so: not in the vendor collection")
|
||||
// Note(bumbread): unless we import something the rest of the bindings will
|
||||
// make a compile-time error. This is a bit ugly for now, but in the future
|
||||
// raygui probably needs to be in a separate package.
|
||||
foreign import lib {"_"}
|
||||
foreign import lib "linux/libraygui.so"
|
||||
} else {
|
||||
// #panic("Cannot link libraygui.a: not in the vendor collection")
|
||||
// TODO(bumbread): apparently this one was missing. This might need
|
||||
// to get rebuilt for linux
|
||||
// foreign import lib {
|
||||
// "linux/libraygui.a",
|
||||
// // "system:dl",
|
||||
// // "system:pthread",
|
||||
// }
|
||||
foreign import lib {"_"}
|
||||
foreign import lib "linux/libraygui.a"
|
||||
}
|
||||
} else when ODIN_OS == .Darwin {
|
||||
when ODIN_ARCH == .arm64 {
|
||||
@@ -238,6 +224,7 @@ SCROLLBAR_RIGHT_SIDE :: 1
|
||||
|
||||
@(default_calling_convention="c")
|
||||
foreign lib {
|
||||
@(link_name="raylib_version") version: cstring
|
||||
// Global gui state control functions
|
||||
|
||||
GuiEnable :: proc() --- // Enable gui controls (global state)
|
||||
@@ -293,17 +280,17 @@ foreign lib {
|
||||
// Basic controls set
|
||||
|
||||
GuiLabel :: proc(bounds: Rectangle, text: cstring) -> c.int --- // Label control, shows text
|
||||
GuiButton :: proc(bounds: Rectangle, text: cstring) -> c.int --- // Button control, returns true when clicked
|
||||
GuiLabelButton :: proc(bounds: Rectangle, text: cstring) -> c.int --- // Label button control, show true when clicked
|
||||
GuiButton :: proc(bounds: Rectangle, text: cstring) -> bool --- // Button control, returns true when clicked
|
||||
GuiLabelButton :: proc(bounds: Rectangle, text: cstring) -> bool --- // Label button control, show true when clicked
|
||||
GuiToggle :: proc(bounds: Rectangle, text: cstring, active: ^bool) -> c.int --- // Toggle Button control, returns true when active
|
||||
GuiToggleGroup :: proc(bounds: Rectangle, text: cstring, active: ^c.int) -> c.int --- // Toggle Group control, returns active toggle index
|
||||
GuiCheckBox :: proc(bounds: Rectangle, text: cstring, checked: ^bool) -> c.int --- // Check Box control, returns true when active
|
||||
GuiCheckBox :: proc(bounds: Rectangle, text: cstring, checked: ^bool) -> bool --- // Check Box control, returns true when active
|
||||
GuiComboBox :: proc(bounds: Rectangle, text: cstring, active: ^c.int) -> c.int --- // Combo Box control, returns selected item index
|
||||
|
||||
GuiDropdownBox :: proc(bounds: Rectangle, text: cstring, active: ^c.int, editMode: bool) -> c.int --- // Dropdown Box control, returns selected item
|
||||
GuiDropdownBox :: proc(bounds: Rectangle, text: cstring, active: ^c.int, editMode: bool) -> bool --- // Dropdown Box control, returns selected item
|
||||
GuiSpinner :: proc(bounds: Rectangle, text: cstring, value: ^c.int, minValue, maxValue: c.int, editMode: bool) -> c.int --- // Spinner control, returns selected value
|
||||
GuiValueBox :: proc(bounds: Rectangle, text: cstring, value: ^c.int, minValue, maxValue: c.int, editMode: bool) -> c.int --- // Value Box control, updates input text with numbers
|
||||
GuiTextBox :: proc(bounds: Rectangle, text: cstring, textSize: c.int, editMode: bool) -> c.int --- // Text Box control, updates input text
|
||||
GuiTextBox :: proc(bounds: Rectangle, text: cstring, textSize: c.int, editMode: bool) -> bool --- // Text Box control, updates input text
|
||||
|
||||
GuiSlider :: proc(bounds: Rectangle, textLeft: cstring, textRight: cstring, value: ^f32, minValue: f32, maxValue: f32) -> c.int --- // Slider control, returns selected value
|
||||
GuiSliderBar :: proc(bounds: Rectangle, textLeft: cstring, textRight: cstring, value: ^f32, minValue: f32, maxValue: f32) -> c.int --- // Slider Bar control, returns selected value
|
||||
|
||||
16
vendor/sdl2/sdl_pixels.odin
vendored
16
vendor/sdl2/sdl_pixels.odin
vendored
@@ -163,21 +163,21 @@ PixelFormatEnum :: enum u32 {
|
||||
ABGR32 = ABGR8888 when ODIN_ENDIAN == .Big else RGBA8888,
|
||||
|
||||
YV12 = /**< Planar mode: Y + V + U (3 planes) */
|
||||
'Y'<<24 | 'V'<<16 | '1'<<8 | '2'<<0,
|
||||
'Y'<<0 | 'V'<<8 | '1'<<16 | '2'<<24,
|
||||
IYUV = /**< Planar mode: Y + U + V (3 planes) */
|
||||
'I'<<24 | 'Y'<<16 | 'U'<<8 | 'V'<<0,
|
||||
'I'<<0 | 'Y'<<8 | 'U'<<16 | 'V'<<24,
|
||||
YUY2 = /**< Packed mode: Y0+U0+Y1+V0 (1 plane) */
|
||||
'Y'<<24 | 'U'<<16 | 'Y'<<8 | '2'<<0,
|
||||
'Y'<<0 | 'U'<<8 | 'Y'<<16 | '2'<<24,
|
||||
UYVY = /**< Packed mode: U0+Y0+V0+Y1 (1 plane) */
|
||||
'U'<<24 | 'Y'<<16 | 'V'<<8 | 'Y'<<0,
|
||||
'U'<<0 | 'Y'<<8 | 'V'<<16 | 'Y'<<24,
|
||||
YVYU = /**< Packed mode: Y0+V0+Y1+U0 (1 plane) */
|
||||
'Y'<<24 | 'V'<<16 | 'Y'<<8 | 'U'<<0,
|
||||
'Y'<<0 | 'V'<<8 | 'Y'<<16 | 'U'<<24,
|
||||
NV12 = /**< Planar mode: Y + U/V interleaved (2 planes) */
|
||||
'N'<<24 | 'V'<<16 | '1'<<8 | '2'<<0,
|
||||
'N'<<0 | 'V'<<8 | '1'<<16 | '2'<<24,
|
||||
NV21 = /**< Planar mode: Y + V/U interleaved (2 planes) */
|
||||
'N'<<24 | 'V'<<16 | '2'<<8 | '1'<<0,
|
||||
'N'<<0 | 'V'<<8 | '2'<<16 | '1'<<24,
|
||||
EXTERNAL_OES = /**< Android video texture format */
|
||||
'O'<<24 | 'E'<<16 | 'S'<<8 | ' '<<0,
|
||||
'O'<<0 | 'E'<<8 | 'S'<<16 | ' '<<24,
|
||||
}
|
||||
|
||||
|
||||
|
||||
4
vendor/x11/.gitignore
vendored
Normal file
4
vendor/x11/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
# TODO(flysand): Remove this file.
|
||||
|
||||
*.i
|
||||
651
vendor/x11/xlib/xlib_const.odin
vendored
Normal file
651
vendor/x11/xlib/xlib_const.odin
vendored
Normal file
@@ -0,0 +1,651 @@
|
||||
//+build linux, freebsd, openbsd
|
||||
package xlib
|
||||
|
||||
// Special values for many types. Most of these constants
|
||||
// aren't attached to a specific type.
|
||||
|
||||
None :: 0
|
||||
ParentRelative :: 1
|
||||
CopyFromParent :: 0
|
||||
PointerWindow :: 0
|
||||
InputFocus :: 1
|
||||
PointerRoot :: 1
|
||||
AnyPropertyType :: 0
|
||||
AnyKey :: 0
|
||||
AnyButton :: 0
|
||||
AllTemporary :: 0
|
||||
CurrentTime :: 0
|
||||
NoSymbol :: 0
|
||||
|
||||
XA_WM_CLASS :: Atom(67)
|
||||
XA_WM_CLIENT_MACHINE :: Atom(36)
|
||||
XA_WM_COMMAND :: Atom(34)
|
||||
XA_WM_HINTS :: Atom(35)
|
||||
XA_WM_ICON_NAME :: Atom(37)
|
||||
XA_WM_ICON_SIZE :: Atom(38)
|
||||
XA_WM_NAME :: Atom(39)
|
||||
XA_WM_NORMAL_HINTS :: Atom(40)
|
||||
XA_WM_SIZE_HINTS :: Atom(41)
|
||||
XA_WM_TRANSIENT_FOR :: Atom(68)
|
||||
XA_WM_ZOOM_HINTS :: Atom(42)
|
||||
|
||||
// NOTE(flysand): Some implementations return Status as enum, other return it
|
||||
// as an integer. I will make it a status.
|
||||
Status :: enum i32 {
|
||||
Success = 0,
|
||||
BadRequest = 1,
|
||||
BadValue = 2,
|
||||
BadWindow = 3,
|
||||
BadPixmap = 4,
|
||||
BadAtom = 5,
|
||||
BadCursor = 6,
|
||||
BadFont = 7,
|
||||
BadMatch = 8,
|
||||
BadDrawable = 9,
|
||||
BadAccess = 10,
|
||||
BadAlloc = 11,
|
||||
BadColor = 12,
|
||||
BadGC = 13,
|
||||
BadIDChoice = 14,
|
||||
BadName = 15,
|
||||
BadLength = 16,
|
||||
BadImplementation = 17,
|
||||
FirstExtensionError = 128,
|
||||
LastExtensionError = 255,
|
||||
}
|
||||
|
||||
ByteOrder :: enum i32 {
|
||||
LSBFirst = 0,
|
||||
MSBFirst = 1,
|
||||
}
|
||||
|
||||
Gravity :: enum i32 {
|
||||
ForgetGravity = 0,
|
||||
UnmapGravity = 0,
|
||||
NorthWestGravity = 1,
|
||||
NorthGravity = 2,
|
||||
NorthEastGravity = 3,
|
||||
WestGravity = 4,
|
||||
CenterGravity = 5,
|
||||
EastGravity = 6,
|
||||
SouthWestGravity = 7,
|
||||
SouthGravity = 8,
|
||||
SouthEastGravity = 9,
|
||||
StaticGravity = 10,
|
||||
}
|
||||
|
||||
BackingStore :: enum i32 {
|
||||
NotUseful = 0,
|
||||
WhenMapped = 1,
|
||||
Always = 2,
|
||||
}
|
||||
|
||||
MouseButton :: enum i32 {
|
||||
Button1 = 1,
|
||||
Button2 = 2,
|
||||
Button3 = 3,
|
||||
Button4 = 4,
|
||||
Button5 = 5,
|
||||
}
|
||||
|
||||
EventMask :: bit_set[EventMaskBits; int]
|
||||
EventMaskBits :: enum i32 {
|
||||
KeyPress = 0,
|
||||
KeyRelease = 1,
|
||||
ButtonPress = 2,
|
||||
ButtonRelease = 3,
|
||||
EnterWindow = 4,
|
||||
LeaveWindow = 5,
|
||||
PointerMotion = 6,
|
||||
PointerMotionHint = 7,
|
||||
Button1Motion = 8,
|
||||
Button2Motion = 9,
|
||||
Button3Motion = 10,
|
||||
Button4Motion = 11,
|
||||
Button5Motion = 12,
|
||||
ButtonMotion = 13,
|
||||
KeymapState = 14,
|
||||
Exposure = 15,
|
||||
VisibilityChange = 16,
|
||||
StructureNotify = 17,
|
||||
ResizeRedirect = 18,
|
||||
SubstructureNotify = 19,
|
||||
SubstructureRedirect = 20,
|
||||
FocusChange = 21,
|
||||
PropertyChange = 22,
|
||||
ColormapChange = 23,
|
||||
OwnerGrabButton = 24,
|
||||
}
|
||||
|
||||
EventType :: enum i32 {
|
||||
KeyPress = 2,
|
||||
KeyRelease = 3,
|
||||
ButtonPress = 4,
|
||||
ButtonRelease = 5,
|
||||
MotionNotify = 6,
|
||||
EnterNotify = 7,
|
||||
LeaveNotify = 8,
|
||||
FocusIn = 9,
|
||||
FocusOut = 10,
|
||||
KeymapNotify = 11,
|
||||
Expose = 12,
|
||||
GraphicsExpose = 13,
|
||||
NoExpose = 14,
|
||||
VisibilityNotify = 15,
|
||||
CreateNotify = 16,
|
||||
DestroyNotify = 17,
|
||||
UnmapNotify = 18,
|
||||
MapNotify = 19,
|
||||
MapRequest = 20,
|
||||
ReparentNotify = 21,
|
||||
ConfigureNotify = 22,
|
||||
ConfigureRequest = 23,
|
||||
GravityNotify = 24,
|
||||
ResizeRequest = 25,
|
||||
CirculateNotify = 26,
|
||||
CirculateRequest = 27,
|
||||
PropertyNotify = 28,
|
||||
SelectionClear = 29,
|
||||
SelectionRequest = 30,
|
||||
SelectionNotify = 31,
|
||||
ColormapNotify = 32,
|
||||
ClientMessage = 33,
|
||||
MappingNotify = 34,
|
||||
GenericEvent = 35,
|
||||
}
|
||||
|
||||
InputMask :: bit_set[InputMaskBits; i32]
|
||||
InputMaskBits :: enum {
|
||||
ShiftMask = 0,
|
||||
LockMask = 1,
|
||||
ControlMask = 2,
|
||||
Mod1Mask = 3,
|
||||
Mod2Mask = 4,
|
||||
Mod3Mask = 5,
|
||||
Mod4Mask = 6,
|
||||
Mod5Mask = 7,
|
||||
Button1Mask = 8,
|
||||
Button2Mask = 9,
|
||||
Button3Mask = 10,
|
||||
Button4Mask = 11,
|
||||
Button5Mask = 12,
|
||||
AnyModifier = 15,
|
||||
}
|
||||
|
||||
NotifyMode :: enum i32 {
|
||||
NotifyNormal = 0,
|
||||
NotifyGrab = 1,
|
||||
NotifyUngrab = 2,
|
||||
NotifyWhileGrabbed = 3,
|
||||
}
|
||||
|
||||
NotifyDetail :: enum i32 {
|
||||
NotifyAncestor = 0,
|
||||
NotifyVirtual = 1,
|
||||
NotifyInferior = 2,
|
||||
NotifyNonlinear = 3,
|
||||
NotifyNonlinearVirtual = 4,
|
||||
NotifyPointer = 5,
|
||||
NotifyPointerRoot = 6,
|
||||
NotifyDetailNone = 7,
|
||||
}
|
||||
|
||||
MappingRequest :: enum i32 {
|
||||
MappingModifier = 0,
|
||||
MappingKeyboard = 1,
|
||||
MappingPointer = 2,
|
||||
}
|
||||
|
||||
VisibilityState :: enum i32 {
|
||||
VisibilityUnobscured = 0,
|
||||
VisibilityPartiallyObscured = 1,
|
||||
VisibilityFullyObscured = 2,
|
||||
}
|
||||
|
||||
ColormapState :: enum i32 {
|
||||
ColormapUninstalled = 0,
|
||||
ColormapInstalled = 1,
|
||||
}
|
||||
|
||||
PropertyState :: enum i32 {
|
||||
PropertyNewValue = 0,
|
||||
PropertyDelete = 1,
|
||||
}
|
||||
|
||||
CloseMode :: enum i32 {
|
||||
DestroyAll = 0,
|
||||
RetainPermanent = 1,
|
||||
RetainTemporary = 2,
|
||||
}
|
||||
|
||||
EventQueueMode :: enum i32 {
|
||||
QueuedAlready = 0,
|
||||
QueuedAfterReading = 1,
|
||||
QueuedAfterFlush = 2,
|
||||
}
|
||||
|
||||
WindowAttributeMask :: bit_set[WindowAttributeMaskBits; int]
|
||||
WindowAttributeMaskBits :: enum {
|
||||
CWBackPixmap = 0,
|
||||
CWBackPixel = 1,
|
||||
CWBorderPixmap = 2,
|
||||
CWBorderPixel = 3,
|
||||
CWBitGravity = 4,
|
||||
CWWinGravity = 5,
|
||||
CWBackingStore = 6,
|
||||
CWBackingPlanes = 7,
|
||||
CWBackingPixel = 8,
|
||||
CWOverrideRedirect = 9,
|
||||
CWSaveUnder = 10,
|
||||
CWEventMask = 11,
|
||||
CWDontPropagate = 12,
|
||||
CWColormap = 13,
|
||||
CWCursor = 14,
|
||||
}
|
||||
|
||||
WindowClass :: enum i32 {
|
||||
CopyFromParent = 0,
|
||||
InputOutput = 1,
|
||||
InputOnly = 2,
|
||||
}
|
||||
|
||||
WindowChangesMask :: bit_set[WindowChangesMaskBits; i32]
|
||||
WindowChangesMaskBits :: enum {
|
||||
CWX = 0,
|
||||
CWY = 1,
|
||||
CWWidth = 2,
|
||||
CWHeight = 3,
|
||||
CWBorderWidth = 4,
|
||||
CWSibling = 5,
|
||||
CWStackMode = 6,
|
||||
}
|
||||
|
||||
WindowStacking :: enum i32 {
|
||||
Above = 0,
|
||||
Below = 1,
|
||||
TopIf = 2,
|
||||
BottomIf = 3,
|
||||
Opposite = 4,
|
||||
}
|
||||
|
||||
CirculationDirection :: enum i32 {
|
||||
RaiseLowest = 0,
|
||||
LowerHighest = 1,
|
||||
}
|
||||
|
||||
CirculationRequest :: enum i32 {
|
||||
PlaceOnTop = 0,
|
||||
PlaceOnBottom = 1,
|
||||
}
|
||||
|
||||
WindowMapState :: enum i32 {
|
||||
IsUnmapped = 0,
|
||||
IsUnviewable = 1,
|
||||
IsViewable = 2,
|
||||
}
|
||||
|
||||
KeyMask :: enum u32 {
|
||||
ShiftMask = 0,
|
||||
LockMask = 1,
|
||||
ControlMask = 2,
|
||||
Mod1Mask = 3,
|
||||
Mod2Mask = 4,
|
||||
Mod3Mask = 5,
|
||||
Mod4Mask = 6,
|
||||
Mod5Mask = 7,
|
||||
}
|
||||
|
||||
CursorShape :: enum u32 {
|
||||
XC_X_cursor = 0,
|
||||
XC_arrow = 2,
|
||||
XC_based_arrow_down = 4,
|
||||
XC_based_arrow_up = 6,
|
||||
XC_boat = 8,
|
||||
XC_bogosity = 10,
|
||||
XC_bottom_left_corner = 12,
|
||||
XC_bottom_right_corner = 14,
|
||||
XC_bottom_side = 16,
|
||||
XC_bottom_tee = 18,
|
||||
XC_box_spiral = 20,
|
||||
XC_center_ptr = 22,
|
||||
XC_circle = 24,
|
||||
XC_clock = 26,
|
||||
XC_coffee_mug = 28,
|
||||
XC_cross = 30,
|
||||
XC_cross_reverse = 32,
|
||||
XC_crosshair = 34,
|
||||
XC_diamond_cross = 36,
|
||||
XC_dot = 38,
|
||||
XC_dotbox = 40,
|
||||
XC_double_arrow = 42,
|
||||
XC_draft_large = 44,
|
||||
XC_draft_small = 46,
|
||||
XC_draped_box = 48,
|
||||
XC_exchange = 50,
|
||||
XC_fleur = 52,
|
||||
XC_gobbler = 54,
|
||||
XC_gumby = 56,
|
||||
XC_hand1 = 58,
|
||||
XC_hand2 = 60,
|
||||
XC_heart = 62,
|
||||
XC_icon = 64,
|
||||
XC_iron_cross = 66,
|
||||
XC_left_ptr = 68,
|
||||
XC_left_side = 70,
|
||||
XC_left_tee = 72,
|
||||
XC_leftbutton = 74,
|
||||
XC_ll_angle = 76,
|
||||
XC_lr_angle = 78,
|
||||
XC_man = 80,
|
||||
XC_middlebutton = 82,
|
||||
XC_mouse = 84,
|
||||
XC_pencil = 86,
|
||||
XC_pirate = 88,
|
||||
XC_plus = 90,
|
||||
XC_question_arrow = 92,
|
||||
XC_right_ptr = 94,
|
||||
XC_right_side = 96,
|
||||
XC_right_tee = 98,
|
||||
XC_rightbutton = 100,
|
||||
XC_rtl_logo = 102,
|
||||
XC_sailboat = 104,
|
||||
XC_sb_down_arrow = 106,
|
||||
XC_sb_h_double_arrow = 108,
|
||||
XC_sb_left_arrow = 110,
|
||||
XC_sb_right_arrow = 112,
|
||||
XC_sb_up_arrow = 114,
|
||||
XC_sb_v_double_arrow = 116,
|
||||
XC_shuttle = 118,
|
||||
XC_sizing = 120,
|
||||
XC_spider = 122,
|
||||
XC_spraycan = 124,
|
||||
XC_star = 126,
|
||||
XC_target = 128,
|
||||
XC_tcross = 130,
|
||||
XC_top_left_arrow = 132,
|
||||
XC_top_left_corner = 134,
|
||||
XC_top_right_corner = 136,
|
||||
XC_top_side = 138,
|
||||
XC_top_tee = 140,
|
||||
XC_trek = 142,
|
||||
XC_ul_angle = 144,
|
||||
XC_umbrella = 146,
|
||||
XC_ur_angle = 148,
|
||||
XC_watch = 150,
|
||||
XC_xterm = 152,
|
||||
XC_num_glyphs = 154,
|
||||
}
|
||||
|
||||
ColorFormat :: enum u32 {
|
||||
XcmsUndefinedFormat = 0x00000000,
|
||||
XcmsCIEXYZFormat = 0x00000001,
|
||||
XcmsCIEuvYFormat = 0x00000002,
|
||||
XcmsCIExyYFormat = 0x00000003,
|
||||
XcmsCIELabFormat = 0x00000004,
|
||||
XcmsCIELuvFormat = 0x00000005,
|
||||
XcmsTekHVCFormat = 0x00000006,
|
||||
XcmsRGBFormat = 0x80000000,
|
||||
XcmsRGBiFormat = 0x80000001,
|
||||
}
|
||||
|
||||
ColormapAlloc :: enum i32 {
|
||||
AllocNone = 0,
|
||||
AllocAll = 1,
|
||||
}
|
||||
|
||||
ColorFlags :: bit_set[ColorFlagsBits; i32]
|
||||
ColorFlagsBits :: enum {
|
||||
DoRed = 0,
|
||||
DoGreen = 1,
|
||||
DoBlue = 2,
|
||||
}
|
||||
|
||||
GCAttributeMask :: bit_set[GCAttributeMaskBits; uint]
|
||||
GCAttributeMaskBits :: enum {
|
||||
GCFunction = 0,
|
||||
GCPlaneMask = 1,
|
||||
GCForeground = 2,
|
||||
GCBackground = 3,
|
||||
GCLineWidth = 4,
|
||||
GCLineStyle = 5,
|
||||
GCCapStyle = 6,
|
||||
GCJoinStyle = 7,
|
||||
GCFillStyle = 8,
|
||||
GCFillRule = 9,
|
||||
GCTile = 10,
|
||||
GCStipple = 11,
|
||||
GCTileStipXOrigin = 12,
|
||||
GCTileStipYOrigin = 13,
|
||||
GCFont = 14,
|
||||
GCSubwindowMode = 15,
|
||||
GCGraphicsExposures= 16,
|
||||
GCClipXOrigin = 17,
|
||||
GCClipYOrigin = 18,
|
||||
GCClipMask = 19,
|
||||
GCDashOffset = 20,
|
||||
GCDashList = 21,
|
||||
GCArcMode = 22,
|
||||
}
|
||||
|
||||
GCFunction :: enum i32 {
|
||||
GXclear = 0x0, // 0
|
||||
GXand = 0x1, // src & dst
|
||||
GXandReverse = 0x2, // src & ~dst
|
||||
GXcopy = 0x3, // src
|
||||
GXandInverted = 0x4, // ~src & dst
|
||||
GXnoop = 0x5, // dst
|
||||
GXxor = 0x6, // src ~ dst
|
||||
GXor = 0x7, // src | dst
|
||||
GXnor = 0x8, // ~src & ~dst
|
||||
GXequiv = 0x9, // ~src ~ dst
|
||||
GXinvert = 0xa, // ~dst
|
||||
GXorReverse = 0xb, // src | ~dst
|
||||
GXcopyInverted = 0xc, // ~src
|
||||
GXorInverted = 0xd, // ~src | dst
|
||||
GXnand = 0xe, // ~src | ~dst
|
||||
GXset = 0xf, // 1
|
||||
}
|
||||
|
||||
LineStyle :: enum i32 {
|
||||
LineSolid = 0,
|
||||
LineOnOffDash = 1,
|
||||
LineDoubleDash = 2,
|
||||
}
|
||||
|
||||
CapStyle :: enum i32 {
|
||||
CapNotLast = 0,
|
||||
CapButt = 1,
|
||||
CapRound = 2,
|
||||
CapProjecting = 3,
|
||||
}
|
||||
|
||||
JoinStyle :: enum i32 {
|
||||
JoinMiter = 0,
|
||||
JoinRound = 1,
|
||||
JoinBevel = 2,
|
||||
}
|
||||
|
||||
FillStyle :: enum i32 {
|
||||
FillSolid = 0,
|
||||
FillTiled = 1,
|
||||
FillStippled = 2,
|
||||
FillOpaqueStippled = 3,
|
||||
}
|
||||
|
||||
FillRule :: enum i32 {
|
||||
EvenOddRule = 0,
|
||||
WindingRule = 1,
|
||||
}
|
||||
|
||||
ArcMode :: enum i32 {
|
||||
ArcChord = 0,
|
||||
ArcPieSlice = 1,
|
||||
}
|
||||
|
||||
SubwindowMode :: enum i32 {
|
||||
ClipByChildren = 0,
|
||||
IncludeInferiors = 1,
|
||||
}
|
||||
|
||||
CoordMode :: enum i32 {
|
||||
CoordModeOrigin = 0,
|
||||
CoordModePrevious = 1,
|
||||
}
|
||||
|
||||
Shape :: enum i32 {
|
||||
Complex = 0,
|
||||
Nonconvex = 1,
|
||||
Convex = 2,
|
||||
}
|
||||
|
||||
FontDirection :: enum i32 {
|
||||
FontLeftToRight = 0,
|
||||
FontRightToLeft = 1,
|
||||
}
|
||||
|
||||
ImageFormat :: enum i32 {
|
||||
XYBitmap = 0,
|
||||
XYPixmap = 1,
|
||||
ZPixmap = 2,
|
||||
}
|
||||
|
||||
SaveSetChangeMode :: enum i32 {
|
||||
SetModeInsert = 0,
|
||||
SetModeDelete = 1,
|
||||
}
|
||||
|
||||
|
||||
ScreenSaverBlanking :: enum i32 {
|
||||
DontPreferBlanking = 0,
|
||||
PreferBlanking = 1,
|
||||
DefaultBlanking = 2,
|
||||
}
|
||||
|
||||
ScreenSavingExposures :: enum i32 {
|
||||
DontAllowExposures = 0,
|
||||
AllowExposures = 1,
|
||||
DefaultExposures = 2,
|
||||
}
|
||||
|
||||
ScreenSaverForceMode :: enum i32 {
|
||||
ScreenSaverReset = 0,
|
||||
ScreenSaverActive = 1,
|
||||
}
|
||||
|
||||
AccessControlMode :: enum i32 {
|
||||
DisableAccess = 0,
|
||||
EnableAccess = 1,
|
||||
}
|
||||
|
||||
GrabMode :: enum i32 {
|
||||
GrabModeSync = 0,
|
||||
GrabModeAsync = 1,
|
||||
}
|
||||
|
||||
AllowEventsMode :: enum i32 {
|
||||
AsyncPointer = 0,
|
||||
SyncPointer = 1,
|
||||
ReplayPointer = 2,
|
||||
AsyncKeyboard = 3,
|
||||
SyncKeyboard = 4,
|
||||
ReplayKeyboard = 5,
|
||||
AsyncBoth = 6,
|
||||
SyncBoth = 7,
|
||||
}
|
||||
|
||||
FocusRevert :: enum i32 {
|
||||
RevertToNone = 0,
|
||||
RevertToPointerRoot = 1,
|
||||
RevertToParent = 2,
|
||||
}
|
||||
|
||||
KeyboardControlMask :: bit_set[KeyboardControlMaskBits; int]
|
||||
KeyboardControlMaskBits :: enum {
|
||||
KBKeyClickPercent = 0,
|
||||
KBBellPercent = 1,
|
||||
KBBellPitch = 2,
|
||||
KBBellDuration = 3,
|
||||
KBLed = 4,
|
||||
KBLedMode = 5,
|
||||
KBKey = 6,
|
||||
KBAutoRepeatMode = 7,
|
||||
}
|
||||
|
||||
KeyboardAutoRepeatMode :: enum i32 {
|
||||
AutoRepeatModeOff = 0,
|
||||
AutoRepeatModeOn = 1,
|
||||
AutoRepeatModeDefault = 2,
|
||||
}
|
||||
|
||||
KeyboardLedMode :: enum i32 {
|
||||
LedModeOff = 0,
|
||||
LedModeOn = 1,
|
||||
}
|
||||
|
||||
WMHints :: bit_set[WMHintsBits; uint]
|
||||
WMHintsBits :: enum {
|
||||
InputHint = 0,
|
||||
StateHint = 1,
|
||||
IconPixmapHint = 2,
|
||||
IconWindowHint = 3,
|
||||
IconPositionHint = 4,
|
||||
IconMaskHint = 5,
|
||||
WindowGroupHint = 6,
|
||||
XUrgencyHint = 8,
|
||||
}
|
||||
|
||||
WMHintState :: enum i32 {
|
||||
WithdrawnState = 0,
|
||||
NormalState = 1,
|
||||
IconicState = 3,
|
||||
}
|
||||
|
||||
AllHints :: WMHints{
|
||||
.InputHint,
|
||||
.StateHint,
|
||||
.IconPixmapHint,
|
||||
.IconWindowHint,
|
||||
.IconPositionHint,
|
||||
.IconMaskHint,
|
||||
.WindowGroupHint,
|
||||
}
|
||||
|
||||
SizeHints :: bit_set[SizeHintsBits; uint]
|
||||
SizeHintsBits :: enum {
|
||||
USPosition = 0,
|
||||
USSize = 1,
|
||||
PPosition = 2,
|
||||
PSize = 3,
|
||||
PMinSize = 4,
|
||||
PMaxSize = 5,
|
||||
PResizeInc = 6,
|
||||
PAspect = 7,
|
||||
PBaseSize = 8,
|
||||
PWinGravity = 9,
|
||||
}
|
||||
|
||||
VisualInfoMask :: bit_set[VisualInfoMaskBits; int]
|
||||
VisualInfoMaskBits :: enum {
|
||||
VisualIDMask = 0,
|
||||
VisualScreenMask = 1,
|
||||
VisualDepthMask = 2,
|
||||
VisualClassMask = 3,
|
||||
VisualRedMaskMask = 4,
|
||||
VisualGreenMaskMask = 5,
|
||||
VisualBlueMaskMask = 6,
|
||||
VisualColormapSizeMask = 7,
|
||||
VisualBitsPerRGBMask = 8,
|
||||
}
|
||||
|
||||
VisualNoMask :: VisualInfoMask {}
|
||||
VisualAllMask :: VisualInfoMask {
|
||||
.VisualIDMask,
|
||||
.VisualScreenMask,
|
||||
.VisualDepthMask,
|
||||
.VisualClassMask,
|
||||
.VisualRedMaskMask,
|
||||
.VisualGreenMaskMask,
|
||||
.VisualBlueMaskMask,
|
||||
.VisualColormapSizeMask,
|
||||
.VisualBitsPerRGBMask,
|
||||
}
|
||||
1681
vendor/x11/xlib/xlib_keysym.odin
vendored
Normal file
1681
vendor/x11/xlib/xlib_keysym.odin
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1909
vendor/x11/xlib/xlib_procs.odin
vendored
Normal file
1909
vendor/x11/xlib/xlib_procs.odin
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1307
vendor/x11/xlib/xlib_types.odin
vendored
Normal file
1307
vendor/x11/xlib/xlib_types.odin
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user