extract-upper-case.pl 5.3 KB

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