Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Kitware
GitHub Repository: Kitware/CMake
Path: blob/master/Auxiliary/vim/extract-upper-case.pl
5020 views
1
#!/usr/bin/env perl
2
3
use strict;
4
use warnings;
5
use POSIX qw(strftime);
6
use JSON;
7
use File::Basename;
8
9
#my $cmake = "/home/pboettch/devel/upstream/cmake/build/bin/cmake";
10
my $cmake = "cmake";
11
12
my @variables;
13
my @commands;
14
my @properties;
15
my @modules;
16
my %keywords; # command => keyword-list
17
18
# find cmake/Modules/ | sed -rn 's/.*CMakeDetermine(.+)Compiler.cmake/\1/p' | sort
19
my @languages = qw(ASM ASM_MASM ASM_NASM C CSharp CUDA CXX Fortran Java RC Swift HIP);
20
21
# unwanted upper-cases
22
my %unwanted = map { $_ => 1 } qw(VS CXX IDE NOTFOUND NO_ DFOO DBAR NEW GNU);
23
# cannot remove ALL - exists for add_custom_command
24
25
# control-statements
26
my %conditional = map { $_ => 1 } qw(if else elseif endif);
27
my %loopetc = map { $_ => 1 } qw(block foreach function macro while endblock endfunction endforeach endmacro endwhile);
28
29
# decrecated
30
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);
31
32
# add some (popular) modules
33
push @modules, "ExternalProject", "FetchContent";
34
35
# variables
36
open(CMAKE, "$cmake --help-variable-list|") or die "could not run cmake";
37
while (<CMAKE>) {
38
chomp;
39
40
if (/<(.*?)>/) {
41
if ($1 eq 'LANG') {
42
foreach my $lang (@languages) {
43
(my $V = $_) =~ s/<.*>/$lang/;
44
push @variables, $V;
45
}
46
47
next
48
} else {
49
next; # skip if containing < or >
50
}
51
}
52
53
push @variables, $_;
54
}
55
close(CMAKE);
56
57
# transform all variables in a hash - to be able to use exists later on
58
my %variables = map { $_ => 1 } @variables;
59
60
# commands
61
open(CMAKE, "$cmake --help-command-list|");
62
while (my $cmd = <CMAKE>) {
63
chomp $cmd;
64
push @commands, $cmd;
65
}
66
close(CMAKE);
67
68
# now generate a keyword-list per command
69
foreach my $cmd (@commands) {
70
my @word = extract_upper("$cmake --help-command $cmd|");
71
72
next if scalar @word == 0;
73
74
$keywords{$cmd} = [ sort keys %{ { map { $_ => 1 } @word } } ];
75
}
76
77
# and now for modules
78
foreach my $mod (@modules) {
79
my @word = extract_upper("$cmake --help-module $mod|");
80
81
next if scalar @word == 0;
82
83
$keywords{$mod} = [ sort keys %{ { map { $_ => 1 } @word } } ];
84
}
85
86
# and now for generator-expressions
87
my @generator_expr = extract_upper("$cmake --help-manual cmake-generator-expressions |");
88
89
# properties
90
open(CMAKE, "$cmake --help-property-list|");
91
while (<CMAKE>) {
92
next if /\</; # skip if containing < or >
93
chomp;
94
push @properties, $_;
95
}
96
close(CMAKE);
97
98
# transform all properties in a hash
99
my %properties = map { $_ => 1 } @properties;
100
101
# read in manually written files
102
my $modules_dir = dirname(__FILE__) . "/modules";
103
opendir(DIR, $modules_dir) || die "can't opendir $modules_dir: $!";
104
my @json_files = grep { /\.json$/ && -f "$modules_dir/$_" } readdir(DIR);
105
closedir DIR;
106
107
foreach my $file (@json_files) {
108
local $/; # Enable 'slurp' mode
109
open my $fh, "<", $modules_dir."/".$file;
110
my $json = <$fh>;
111
close $fh;
112
113
my $mod = decode_json($json);
114
foreach my $var (@{$mod->{variables}}) {
115
$variables{$var} = 1;
116
}
117
118
while (my ($cmd, $keywords) = each %{$mod->{commands}}) {
119
$keywords{$cmd} = [ sort @{$keywords} ];
120
}
121
}
122
123
# version
124
open(CMAKE, "$cmake --version|");
125
my $version = 'unknown';
126
while (<CMAKE>) {
127
chomp;
128
$version = $_ if /cmake version/;
129
}
130
close(CMAKE);
131
132
# generate cmake.vim
133
open(IN, "<cmake.vim.in") or die "could not read cmake.vim.in";
134
open(OUT, ">syntax/cmake.vim") or die "could not write to syntax/cmake.vim";
135
136
my @keyword_hi;
137
138
while(<IN>)
139
{
140
if (m/\@([A-Z0-9_]+)\@/) { # match for @SOMETHING@
141
if ($1 eq "COMMAND_LIST") {
142
# do not include "special" commands in this list
143
my @tmp = grep { ! exists $conditional{$_} and
144
! exists $loopetc{$_} and
145
! exists $deprecated{$_} } @commands;
146
print_list(\*OUT, @tmp);
147
} elsif ($1 eq "VARIABLE_LIST") {
148
print_list(\*OUT, keys %variables);
149
} elsif ($1 eq "MODULES") {
150
print_list(\*OUT, @modules);
151
} elsif ($1 eq "GENERATOR_EXPRESSIONS") {
152
print_list(\*OUT, @generator_expr);
153
} elsif ($1 eq "DEPRECATED") {
154
print_list(\*OUT, keys %deprecated);
155
} elsif ($1 eq "PROPERTIES") {
156
print_list(\*OUT, keys %properties);
157
} elsif ($1 eq "KEYWORDS") {
158
foreach my $k (sort keys %keywords) {
159
print OUT "syn keyword cmakeKW$k contained\n";
160
print_list(\*OUT, @{$keywords{$k}});
161
print OUT "\n";
162
push @keyword_hi, "hi def link cmakeKW$k ModeMsg";
163
}
164
} elsif ($1 eq "KEYWORDS_HIGHLIGHT") {
165
print OUT join("\n", @keyword_hi), "\n";
166
} elsif ($1 eq "VERSION") {
167
$_ =~ s/\@VERSION\@/$version/;
168
print OUT $_;
169
} elsif ($1 eq "DATE") {
170
my $date = strftime "%Y %b %d", localtime;
171
$_ =~ s/\@DATE\@/$date/;
172
print OUT $_;
173
} else {
174
print "ERROR do not know how to replace $1\n";
175
}
176
} else {
177
print OUT $_;
178
}
179
}
180
close(IN);
181
close(OUT);
182
183
sub extract_upper
184
{
185
my $input = shift;
186
my @word;
187
188
open(KW, $input);
189
while (<KW>) {
190
foreach my $w (m/\b([A-Z_]{2,})\b/g) {
191
next
192
if exists $variables{$w} or # skip if it is a variable
193
exists $unwanted{$w} or # skip if not wanted
194
grep(/$w/, @word); # skip if already in array
195
196
push @word, $w;
197
}
198
}
199
close(KW);
200
201
return @word;
202
}
203
204
sub print_list
205
{
206
my $O = shift;
207
my $indent = " " x 12 . "\\ ";
208
print $O $indent, join("\n" . $indent, sort @_), "\n";
209
}
210
211