From a38d023da11ffb5a5d7aca480d121129315eb64f Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Fri, 6 Sep 2024 23:02:15 -0400 Subject: Update files and add new dependency printer tool --- examples/dependencies.tm | 65 ++++++++++++++++++++++++++++++++++++++++++++++++ examples/file.tm | 6 ++++- 2 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 examples/dependencies.tm (limited to 'examples') diff --git a/examples/dependencies.tm b/examples/dependencies.tm new file mode 100644 index 00000000..e13e3621 --- /dev/null +++ b/examples/dependencies.tm @@ -0,0 +1,65 @@ +# Show dependency graph +use file + +func build_dependency_graph(filename:Text, dependencies:&{Text:@{Text}}): + reader := when LineReader.from_file(filename) is Failure(msg): + return + is Open(reader): reader + + while when reader:next_line() is Success(line): + if line:matches($/{start}use {..}.tm/): + import := line:replace($/{start}use {..}/, "\2") + resolved := relative_path(resolve_path(import, filename)) + if resolved != "": + import = resolved + + if not dependencies:has(filename): + dependencies:set(filename, @{:Text}) + + dependencies:get(filename):add(import) + if not dependencies:has(import): + build_dependency_graph(import, dependencies) + +func get_dependency_graph(file:Text)->{Text:{Text}}: + graph := {:Text:@{Text}} + resolved := relative_path(file) + build_dependency_graph(resolved, &graph) + return {f:deps[] for f,deps in graph} + +func draw_tree(file:Text, dependencies:{Text:{Text}}, already_printed:&{Text}, prefix="", is_last=yes): + color_file := if resolve_path(file): file else: "$\x1b[31;1m$file$\x1b[m" + + + if already_printed:has(file): + say(prefix ++ (if is_last: "└── " else: "├── ") ++ color_file ++ " $\x1b[2m(recursive)$\x1b[m") + return + + say(prefix ++ (if is_last: "└── " else: "├── ") ++ color_file) + already_printed:add(file) + + child_prefix := prefix ++ (if is_last: " " else: "│ ") + + children := dependencies:get(file, {:Text}) + for i,child in children.items: + is_child_last := (i == children.length) + draw_tree(child, dependencies, already_printed, child_prefix, is_child_last) + +func main(files:[Text]): + for f,file in files: + if not file:matches($/{..}.tm/): + say("$\x1b[2mSkipping $file$\x1b[m") + skip + + printed := {:Text} + resolved := relative_path(file) + if resolved != "": + file = resolved + + deps := get_dependency_graph(file) + + say(file) + printed:add(file) + children := deps:get(file, {:Text}) + for i,child in children.items: + is_child_last := (i == children.length) + draw_tree(child, deps, already_printed=&printed, is_last=is_child_last) diff --git a/examples/file.tm b/examples/file.tm index 4f4d8645..7def4187 100644 --- a/examples/file.tm +++ b/examples/file.tm @@ -6,6 +6,8 @@ use use use use +use +use libunistring.so enum FileReadResult(Success(text:Text), Failure(reason:Text)) @@ -45,6 +47,8 @@ func read(path:Text)->FileReadResult: do { just_read = read(fd, buf, chunk_size); if (just_read > 0) { + if (u8_check(buf, just_read) != NULL) + break; contents = Texts(contents, Text$from_strn(buf, just_read)); buf = GC_MALLOC_ATOMIC(chunk_size); } @@ -132,7 +136,7 @@ struct LineReader(_file:@Memory): memcpy(line, buf, len); line[len] = '\0'; if (buf) free(buf); - Text$from_strn(line, len); + u8_check(line, len) ? Text("") : Text$from_strn(line, len); }) ):Text return Success(line) -- cgit v1.2.3