You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
214 lines
5.3 KiB
214 lines
5.3 KiB
#!/usr/bin/env perl
|
|
|
|
use strict;
|
|
use warnings;
|
|
use POSIX qw(strftime);
|
|
use JSON;
|
|
use File::Basename;
|
|
|
|
#my $cmake = "/home/pboettch/devel/upstream/cmake/build/bin/cmake";
|
|
my $cmake = "cmake";
|
|
|
|
my @variables;
|
|
my @commands;
|
|
my @properties;
|
|
my @modules;
|
|
my %keywords; # command => keyword-list
|
|
|
|
# find cmake/Modules/ | sed -rn 's/.*CMakeDetermine(.+)Compiler.cmake/\1/p' | sort
|
|
my @languages = qw(ASM ASM_MASM ASM_NASM C CSharp CUDA CXX Fortran Java RC Swift HIP);
|
|
|
|
# unwanted upper-cases
|
|
my %unwanted = map { $_ => 1 } qw(VS CXX IDE NOTFOUND NO_ DFOO DBAR NEW GNU);
|
|
# cannot remove ALL - exists for add_custom_command
|
|
|
|
# control-statements
|
|
my %conditional = map { $_ => 1 } qw(if else elseif endif);
|
|
my %loop = map { $_ => 1 } qw(foreach while endforeach endwhile);
|
|
|
|
# decrecated
|
|
my %deprecated = map { $_ => 1 } qw(build_name exec_program export_library_dependencies install_files install_programs install_targets link_libraries make_directory output_required_files remove subdir_depends subdirs use_mangled_mesa utility_source variable_requires write_file);
|
|
|
|
# add some (popular) modules
|
|
push @modules, "ExternalProject", "FetchContent";
|
|
|
|
# variables
|
|
open(CMAKE, "$cmake --help-variable-list|") or die "could not run cmake";
|
|
while (<CMAKE>) {
|
|
chomp;
|
|
|
|
if (/<(.*?)>/) {
|
|
if ($1 eq 'LANG') {
|
|
foreach my $lang (@languages) {
|
|
(my $V = $_) =~ s/<.*>/$lang/;
|
|
push @variables, $V;
|
|
}
|
|
|
|
next
|
|
} else {
|
|
next; # skip if containing < or >
|
|
}
|
|
}
|
|
|
|
push @variables, $_;
|
|
}
|
|
close(CMAKE);
|
|
|
|
# transform all variables in a hash - to be able to use exists later on
|
|
my %variables = map { $_ => 1 } @variables;
|
|
|
|
# commands
|
|
open(CMAKE, "$cmake --help-command-list|");
|
|
while (my $cmd = <CMAKE>) {
|
|
chomp $cmd;
|
|
push @commands, $cmd;
|
|
}
|
|
close(CMAKE);
|
|
|
|
# now generate a keyword-list per command
|
|
foreach my $cmd (@commands) {
|
|
my @word = extract_upper("$cmake --help-command $cmd|");
|
|
|
|
next if scalar @word == 0;
|
|
|
|
$keywords{$cmd} = [ sort keys %{ { map { $_ => 1 } @word } } ];
|
|
}
|
|
|
|
# and now for modules
|
|
foreach my $mod (@modules) {
|
|
my @word = extract_upper("$cmake --help-module $mod|");
|
|
|
|
next if scalar @word == 0;
|
|
|
|
$keywords{$mod} = [ sort keys %{ { map { $_ => 1 } @word } } ];
|
|
}
|
|
|
|
# and now for generator-expressions
|
|
my @generator_expr = extract_upper("$cmake --help-manual cmake-generator-expressions |");
|
|
|
|
# properties
|
|
open(CMAKE, "$cmake --help-property-list|");
|
|
while (<CMAKE>) {
|
|
next if /\</; # skip if containing < or >
|
|
chomp;
|
|
push @properties, $_;
|
|
}
|
|
close(CMAKE);
|
|
|
|
# transform all properties in a hash
|
|
my %properties = map { $_ => 1 } @properties;
|
|
|
|
# read in manually written files
|
|
my $modules_dir = dirname(__FILE__) . "/modules";
|
|
opendir(DIR, $modules_dir) || die "can't opendir $modules_dir: $!";
|
|
my @json_files = grep { /\.json$/ && -f "$modules_dir/$_" } readdir(DIR);
|
|
closedir DIR;
|
|
|
|
foreach my $file (@json_files) {
|
|
local $/; # Enable 'slurp' mode
|
|
open my $fh, "<", $modules_dir."/".$file;
|
|
my $json = <$fh>;
|
|
close $fh;
|
|
|
|
my $mod = decode_json($json);
|
|
foreach my $var (@{$mod->{variables}}) {
|
|
$variables{$var} = 1;
|
|
}
|
|
|
|
while (my ($cmd, $keywords) = each %{$mod->{commands}}) {
|
|
$keywords{$cmd} = [ sort @{$keywords} ];
|
|
}
|
|
}
|
|
|
|
# version
|
|
open(CMAKE, "$cmake --version|");
|
|
my $version = 'unknown';
|
|
while (<CMAKE>) {
|
|
chomp;
|
|
$version = $_ if /cmake version/;
|
|
}
|
|
close(CMAKE);
|
|
|
|
# generate cmake.vim
|
|
open(IN, "<cmake.vim.in") or die "could not read cmake.vim.in";
|
|
open(OUT, ">syntax/cmake.vim") or die "could not write to syntax/cmake.vim";
|
|
|
|
my @keyword_hi;
|
|
|
|
while(<IN>)
|
|
{
|
|
if (m/\@([A-Z0-9_]+)\@/) { # match for @SOMETHING@
|
|
if ($1 eq "COMMAND_LIST") {
|
|
# do not include "special" commands in this list
|
|
my @tmp = grep { ! exists $conditional{$_} and
|
|
! exists $loop{$_} and
|
|
! exists $deprecated{$_} } @commands;
|
|
print_list(\*OUT, @tmp);
|
|
} elsif ($1 eq "VARIABLE_LIST") {
|
|
print_list(\*OUT, keys %variables);
|
|
} elsif ($1 eq "MODULES") {
|
|
print_list(\*OUT, @modules);
|
|
} elsif ($1 eq "GENERATOR_EXPRESSIONS") {
|
|
print_list(\*OUT, @generator_expr);
|
|
} elsif ($1 eq "CONDITIONALS") {
|
|
print_list(\*OUT, keys %conditional);
|
|
} elsif ($1 eq "LOOPS") {
|
|
print_list(\*OUT, keys %loop);
|
|
} elsif ($1 eq "DEPRECATED") {
|
|
print_list(\*OUT, keys %deprecated);
|
|
} elsif ($1 eq "PROPERTIES") {
|
|
print_list(\*OUT, keys %properties);
|
|
} elsif ($1 eq "KEYWORDS") {
|
|
foreach my $k (sort keys %keywords) {
|
|
print OUT "syn keyword cmakeKW$k contained\n";
|
|
print_list(\*OUT, @{$keywords{$k}});
|
|
print OUT "\n";
|
|
push @keyword_hi, "hi def link cmakeKW$k ModeMsg";
|
|
}
|
|
} elsif ($1 eq "KEYWORDS_HIGHLIGHT") {
|
|
print OUT join("\n", @keyword_hi), "\n";
|
|
} elsif ($1 eq "VERSION") {
|
|
$_ =~ s/\@VERSION\@/$version/;
|
|
print OUT $_;
|
|
} elsif ($1 eq "DATE") {
|
|
my $date = strftime "%Y %b %d", localtime;
|
|
$_ =~ s/\@DATE\@/$date/;
|
|
print OUT $_;
|
|
} else {
|
|
print "ERROR do not know how to replace $1\n";
|
|
}
|
|
} else {
|
|
print OUT $_;
|
|
}
|
|
}
|
|
close(IN);
|
|
close(OUT);
|
|
|
|
sub extract_upper
|
|
{
|
|
my $input = shift;
|
|
my @word;
|
|
|
|
open(KW, $input);
|
|
while (<KW>) {
|
|
foreach my $w (m/\b([A-Z_]{2,})\b/g) {
|
|
next
|
|
if exists $variables{$w} or # skip if it is a variable
|
|
exists $unwanted{$w} or # skip if not wanted
|
|
grep(/$w/, @word); # skip if already in array
|
|
|
|
push @word, $w;
|
|
}
|
|
}
|
|
close(KW);
|
|
|
|
return @word;
|
|
}
|
|
|
|
sub print_list
|
|
{
|
|
my $O = shift;
|
|
my $indent = " " x 12 . "\\ ";
|
|
print $O $indent, join("\n" . $indent, sort @_), "\n";
|
|
}
|