Skip to content

Commit 4df1528

Browse files
committed
Working version of parselog
1 parent 6d446b0 commit 4df1528

File tree

8 files changed

+165
-12
lines changed

8 files changed

+165
-12
lines changed

.github/workflows/CI.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ jobs:
2323
fail-fast: false
2424
matrix:
2525
version:
26-
- '1.10'
27-
- '1.6'
26+
- 'min'
2827
- 'pre'
28+
- 'nightly'
2929
os:
3030
- ubuntu-latest
3131
arch:

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
*.jl.mem
44
/docs/Manifest*.toml
55
/docs/build/
6+
Manifest.toml

Manifest.toml

Lines changed: 0 additions & 7 deletions
This file was deleted.

Project.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,12 @@ uuid = "d61f35a8-f6af-436f-bc10-cee6b101f7bd"
33
authors = ["Tim Holy <[email protected]> and contributors"]
44
version = "1.0.0-DEV"
55

6+
[deps]
7+
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"
8+
69
[compat]
7-
julia = "1.6.7"
10+
Graphs = "1"
11+
julia = "1.12"
812

913
[extras]
1014
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

src/JuliaLibWrapping.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
module JuliaLibWrapping
22

3-
# Write your package code here.
3+
using Graphs
4+
5+
export parselog
6+
7+
include("parselog.jl")
48

59
end

src/parselog.jl

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
struct FieldDesc
2+
name::String
3+
type::String
4+
offset::Int
5+
end
6+
function Base.show(io::IO, field::FieldDesc)
7+
print(io, field.name, "::", field.type, "[", field.offset, "]")
8+
end
9+
10+
struct TypeDesc
11+
name::String
12+
fields::Vector{FieldDesc}
13+
size::Int
14+
end
15+
function Base.show(io::IO, type::TypeDesc)
16+
print(io, type.name, "(", join(type.fields, ", "), ") (", type.size, " bytes)")
17+
end
18+
19+
struct ArgDesc
20+
name::String
21+
type::String
22+
isva::Bool # is this a varargs argument?
23+
end
24+
function Base.show(io::IO, arg::ArgDesc)
25+
print(io, arg.name, "::", arg.type)
26+
if arg.isva
27+
print(io, "...")
28+
end
29+
end
30+
31+
struct MethodDesc
32+
name::String
33+
return_type::String
34+
args::Vector{ArgDesc}
35+
end
36+
37+
function Base.show(io::IO, method::MethodDesc)
38+
print(io, method.name, "(", join(method.args, ", "), ")::", method.return_type)
39+
end
40+
41+
const rexsize = r"^(\d+) bytes$"
42+
const rexfield = r"^ (.+)::(.+)\[(\d+)\]$"
43+
const rexmethod = r"^(.+)\((.*)\)::(.+)$"
44+
const rexarg = r"^(.+)::(.+)(\.\.\.)?$"
45+
46+
"""
47+
entrypoints, typedescs = parselog(filename::String)
48+
49+
Extract the signatures of the entrypoints and nonstandard types from a log file.
50+
"""
51+
function parselog(filename::String)
52+
entrypoints = MethodDesc[]
53+
typedescs = Dict{String, TypeDesc}()
54+
55+
open(filename) do f
56+
handling_types = false
57+
while !eof(f)
58+
line = rstrip(readline(f))
59+
if isempty(line)
60+
handling_types = true
61+
continue
62+
elseif handling_types
63+
current_type = line
64+
fields = FieldDesc[]
65+
line = rstrip(readline(f)) # Read the next line for type details
66+
m = match(rexsize, line)
67+
while m === nothing
68+
m = match(rexfield, line)
69+
field_name = m.captures[1]
70+
field_type = m.captures[2]
71+
field_offset = parse(Int, m.captures[3])
72+
push!(fields, FieldDesc(field_name, field_type, field_offset))
73+
line = rstrip(readline(f))
74+
m = match(rexsize, line)
75+
end
76+
type_size = parse(Int, m.captures[1])
77+
typedescs[current_type] = TypeDesc(current_type, fields, type_size)
78+
else # methods
79+
m = match(rexmethod, line)
80+
method_name = m.captures[1]
81+
args_str = m.captures[2]
82+
return_type = m.captures[3]
83+
84+
args = ArgDesc[]
85+
for arg_str in split(args_str, ",")
86+
arg_str = strip(arg_str)
87+
if isempty(arg_str)
88+
continue
89+
end
90+
m = match(rexarg, arg_str)
91+
arg_name = m.captures[1]
92+
arg_type = m.captures[2]
93+
isva = length(m.captures) > 2 && m.captures[3] !== nothing # Check for varargs
94+
push!(args, ArgDesc(arg_name, arg_type, isva))
95+
end
96+
97+
push!(entrypoints, MethodDesc(method_name, return_type, args))
98+
end
99+
end
100+
end
101+
102+
return entrypoints, typedescs
103+
end
104+
parselog(filename::AbstractString) = parselog(String(filename)::String)

test/bindinginfo_simplelib.log

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
copyto_and_sum(fromto::CVectorPair{Float32})::Float32
2+
3+
CVectorPair{Float32}
4+
from::CVector{Float32}[0]
5+
to::CVector{Float32}[16]
6+
32 bytes
7+
CVector{Float32}
8+
length::Int32[0]
9+
data::Ptr{Float32}[8]
10+
16 bytes

test/runtests.jl

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,42 @@ using JuliaLibWrapping
22
using Test
33

44
@testset "JuliaLibWrapping.jl" begin
5-
# Write your tests here.
5+
@testset "parselog" begin
6+
entrypoints, typedescs = parselog("bindinginfo_simplelib.log")
7+
methdesc = only(entrypoints)
8+
@test methdesc.name == "copyto_and_sum"
9+
@test methdesc.return_type == "Float32"
10+
@test length(methdesc.args) == 1
11+
argdesc = only(methdesc.args)
12+
@test argdesc.name == "fromto"
13+
@test argdesc.type == "CVectorPair{Float32}"
14+
@test argdesc.isva == false
15+
@test length(typedescs) == 2
16+
tdesc = typedescs["CVectorPair{Float32}"]
17+
@test tdesc.name == "CVectorPair{Float32}"
18+
@test length(tdesc.fields) == 2
19+
@test tdesc.fields[1].name == "from"
20+
@test tdesc.fields[1].type == "CVector{Float32}"
21+
@test tdesc.fields[1].offset == 0
22+
@test tdesc.fields[2].name == "to"
23+
@test tdesc.fields[2].type == "CVector{Float32}"
24+
@test tdesc.fields[2].offset == 16
25+
@test tdesc.size == 32
26+
tdesc = typedescs["CVector{Float32}"]
27+
@test tdesc.name == "CVector{Float32}"
28+
@test length(tdesc.fields) == 2
29+
@test tdesc.fields[1].name == "length"
30+
@test tdesc.fields[1].type == "Int32"
31+
@test tdesc.fields[1].offset == 0
32+
@test tdesc.fields[2].name == "data"
33+
@test tdesc.fields[2].type == "Ptr{Float32}"
34+
@test tdesc.fields[2].offset == 8
35+
@test tdesc.size == 16
36+
@test haskey(typedescs, "CVectorPair{Float32}")
37+
@test haskey(typedescs, "CVector{Float32}")
38+
@test sprint(show, only(entrypoints)) == "copyto_and_sum(fromto::CVectorPair{Float32})::Float32"
39+
str = sprint(show, typedescs)
40+
@test occursin("CVectorPair{Float32}(from::CVector{Float32}[0], to::CVector{Float32}[16]) (32 bytes)", str)
41+
@test occursin("CVector{Float32}(length::Int32[0], data::Ptr{Float32}[8]) (16 bytes)", str)
42+
end
643
end

0 commit comments

Comments
 (0)