summaryrefslogtreecommitdiffstats
path: root/Auxiliary/vim/extract-upper-case.pl
blob: 11791991d7788e9a25bc8afca3b8a04568f3b64e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
#!/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);

# unwanted upper-cases
my %unwanted = map { $_ => 1 } qw(VS CXX IDE NOTFOUND NO_ DFOO DBAR NEW);
	# 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";

# 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";
}