diff --git a/.gitignore b/.gitignore index 1d309cd7..d02fa4c4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ /obj /files/cfg /.direnv +.cache +compile_commands.json diff --git a/src/l4/tool/bin/gen_ccj b/src/l4/tool/bin/gen_ccj new file mode 100755 index 00000000..cc55364c --- /dev/null +++ b/src/l4/tool/bin/gen_ccj @@ -0,0 +1,71 @@ +#! /usr/bin/env perl + +use strict; +use warnings; +use File::Basename; +use File::Find; + +my $searchdir = shift; +my $outfile = shift; + +if (not defined $outfile) + { + print "Usage: $0 search-dir outfile\n"; + print "\n"; + print "Example: $0 /path/to/obj-dir /path/to/your/l4re/src/dir/compile_commands.json\n"; + exit 1; + } + +open(my $out, ">$outfile") or die "Cannot open '$outfile': $!"; + +my @db; + +sub add_cmd +{ + return unless /\.cmd$/; + + open(my $fh_cmd, $_) or die "Cannot open '$File::Find::name': $!"; + my $cmd; + my $source; + my $obj; + while (<$fh_cmd>) + { + chomp; + $cmd = $1 if /^savedcmd_\S+\s+:=\s+(.+)/; + $source = $1 if /^source_\S+\s+:=\s+(.+)/; + $obj = $1 if /^savedcmd_(\S+)\s+:=\s+.+/; + } + + return unless defined $cmd and defined $source and defined $obj; + + my $obj_dir = dirname($obj); + my $obj_path = $File::Find::dir =~ s|\Q/$obj_dir\E$||r; + + sub json_escape { return shift =~ s/(["\\])/\\$1/gr; } + + push @db, { + "file" => json_escape($source), + "directory" => json_escape($obj_path), + "command" => json_escape($cmd), + "output" => json_escape("$obj_path/$obj"), + } +} + +find(\&add_cmd, $searchdir); + +my @sorted = sort { $b->{file} cmp $a->{file} } @db; + +print $out "[\n"; +my $comma = ""; +for my $entry (@sorted) + { + print $out $comma; + print $out " {\n"; + print $out " \"file\": \"$entry->{file}\",\n"; + print $out " \"directory\": \"$entry->{directory}\",\n"; + print $out " \"command\": \"$entry->{command}\",\n"; + print $out " \"output\": \"$entry->{output}\"\n"; + print $out " }"; + $comma = ",\n"; + } +print $out "\n]\n";