CMake.pm
Go to the documentation of this file.
1 # ============================================================================
2 # Copyright (c) 2011-2012 University of Pennsylvania
3 # Copyright (c) 2013-2016 Andreas Schuh
4 # All rights reserved.
5 #
6 # See COPYING file for license information or visit
7 # https://cmake-basis.github.io/download.html#license
8 # ============================================================================
9 
10 ##############################################################################
11 # @file DoxyFilter/CMake.pm
12 # @brief Doxygen filter for CMake.
13 #
14 # @ingroup BasisTools
15 ##############################################################################
16 
17 package BASIS::DoxyFilter::CMake;
18 use base BASIS::DoxyFilter;
19 
20 # ============================================================================
21 # public
22 # ============================================================================
23 
24 # ----------------------------------------------------------------------------
25 ## @brief Constructs a CMake Doxygen filter.
26 sub new
27 {
28  shift->SUPER::new([
29  # if() else() endif()
30  ['start', qr/^\s*if\s*\(/, undef, 'start'], # discard if()'s such that
31  # Doxygen comment is
32  # associated with next
33  # block that is supposed
34  # to be in the then branch.
35  # include()
36  ['start', qr/^\s*include\s*\((.+)\)\s*(#.*)?$/, \&_include, 'start'],
37  # option()
38  ['start', qr/^\s*option\s*\(\s*(\w+)\s+(\"([^\"]|\\\")*[^\\]\")\s+(ON|OFF)\s*\)\s*(#.*)?$/, \&_option, 'start'],
39  ['start', qr/^\s*option(.*)[^\)]\s*(#.*)?$/, \&_option_begin, 'option'],
40  ['option', qr/(^|^.*\s+)\"([^\"]|\\\")*$/, \&_option_line, 'option_doc'],
41  ['option_doc', qr/(^|^.*[^\\])\".*\s+\"([^\"]|\\\")*$/, \&_option_line, 'option_doc'],
42  ['option_doc', qr/(^|^.*[^\\])\".*\)\s*(#.*)?$/, \&_option_end, 'start'],
43  ['option_doc', qr/(^|^.*[^\\])\".*$/, \&_option_line, 'option'],
44  ['option_doc', qr/.*/, \&_option_line, 'option_doc'],
45  ['option', qr/^.*\)\s*(#.*)?$/, \&_option_end, 'start'],
46  ['option', qr/.*$/, \&_option_line, 'option'],
47  # set()
48  ['start', qr/^\s*(set|basis_set_if_empty|basis_set_if_not_set|basis_set_script_path)\s*\(\s*(\w+)\s+(.*)\s*\)\s*(#.*)?$/, \&_set_nocache, 'start'],
49  ['start', qr/^\s*(set|basis_set_if_empty|basis_set_if_not_set|basis_set_script_path)\s*\(\s*(\w+)\s+(.*)\s+CACHE\s+(\w+)\s+(.*)\)\s*(#.*)?$/, \&_set_cache, 'start'],
50  ['start', qr/^\s*(set|basis_set_if_empty|basis_set_if_not_set|basis_set_script_path)(.*)[^\)]\s*(#.*)?$/, \&_set_begin, 'set'],
51  ['set', qr/(^|^.*\s+)\"([^\"]|\\\")*$/, \&_set_line, 'set_value'],
52  ['set_value', qr/(^|^.*[^\\])\".*\s+\"([^\"]|\\\")*$/, \&_set_line, 'set_value'],
53  ['set_value', qr/(^|^.*[^\\])\".*\)\s*(#.*)?$/, \&_set_end, 'start'],
54  ['set_value', qr/(^|^.*[^\\])\".*$/, \&_set_line, 'set'],
55  ['set_value', qr/.*/, \&_set_line, 'set_value'],
56  ['set', qr/^.*\)\s*(#.*)?$/, \&_set_end, 'start'],
57  ['set', qr/.*$/, \&_set_line, 'set'],
58  # function()/macro()
59  ['start', qr/^\s*(macro|function)\s*\(\s*(\w+)(\s+[^\)]*)?\)\s*(#.*)?$/, \&_fndef, 'fnbody'],
60  ['start', qr/^\s*(macro|function)\s*\(\s*(\w+)(\s+[^\)]*)?\s*(#.*)?$/, \&_fndef_begin, 'fndef'],
61  ['fndef', qr/^[^\)]*$/, \&_fndef_line, 'fndef'],
62  ['fndef', qr/^.*\)\s*(#.*)?$/, \&_fndef_end, 'fnbody'],
63  ['fnbody', qr/^\s*end(macro|function)\s*\(\s*(\w+)?\s*\)\s*(#.*)?$/, undef, 'start'],
64  ['fnbody', qr/^\s*end(macro|function)\s*.*[^\)]\s*(#.*)?$/, undef, 'fnend'],
65  ['fnend', qr/^.*\)\s*(#.*)?$/, undef, 'start'],
66  ]);
67 }
68 
69 # ============================================================================
70 # actions
71 # ============================================================================
72 
73 # ----------------------------------------------------------------------------
74 # include()
75 # ----------------------------------------------------------------------------
76 
77 # ----------------------------------------------------------------------------
78 sub _include
79 {
80  my ($self, $module) = @_;
81  $module =~ s/^\s*\"?//;
82  $module =~ s/\"?\s*$//;
83  $module =~ s/\${(CMAKE_CURRENT_LIST_DIR|BASIS_MODULE_PATH|\${NS}MODULE_PATH)}|\@BASIS_MODULE_PATH\@//;
84  $module =~ s/ (OPTIONAL|NO_POLICY_SCOPE)//g;
85  $module =~ s/\.cmake$//;
86  $self->_append("#include \"$module.cmake\"");
87 }
88 
89 # ----------------------------------------------------------------------------
90 # option()
91 # ----------------------------------------------------------------------------
92 
93 # ----------------------------------------------------------------------------
94 sub _option
95 {
96  my $self = shift;
97  $self->_option_append($self->{'line'});
98 }
99 
100 # ----------------------------------------------------------------------------
101 sub _option_begin
102 {
103  my $self = shift;
104  my $line = $self->{'line'};
105  $line =~ s/\s*#.*$//;
106  $self->{'buffer'} = "$line";
107 }
108 
109 # ----------------------------------------------------------------------------
110 sub _option_line
111 {
112  my $self = shift;
113  my $line = $self->{'line'};
114  $line =~ s/\s*#.*$//;
115  $self->{'buffer'} .= " $line";
116 }
117 
118 # ----------------------------------------------------------------------------
119 sub _option_end
120 {
121  my $self = shift;
122  my $line = $self->{'line'};
123  $self->{'buffer'} .= " $line";
124  $self->_option_append($self->{'buffer'});
125 }
126 
127 # ----------------------------------------------------------------------------
128 sub _option_append
129 {
130  my ($self, $line) = @_;
131  if ($line =~ /^\s*option\s*\(\s*(\w+)\s+(\"([^\"]|\\\")*[^\\]\")\s+(ON|OFF)\s*\)\s*(#.*)?$/) {
132  my $name = $1;
133  my $default = $4;
134  $self->_append("option $name = $default;");
135  }
136 }
137 
138 # ----------------------------------------------------------------------------
139 # set()
140 # ----------------------------------------------------------------------------
141 
142 # ----------------------------------------------------------------------------
143 sub _set_cache
144 {
145  my ($self, $setfn, $name, $value, $type) = @_;
146  $type = lc $type;
147  $self->_append("$type $name;");
148 }
149 
150 # ----------------------------------------------------------------------------
151 sub _set_nocache
152 {
153  my ($self, $setfn, $name, $value) = @_;
154  $self->_append("cmake $name;");
155 }
156 
157 # ----------------------------------------------------------------------------
158 sub _set_begin
159 {
160  my $self = shift;
161  my $line = $self->{'line'};
162  $line =~ s/\s*#.*$//;
163  $self->{'buffer'} = "$line";
164 }
165 
166 # ----------------------------------------------------------------------------
167 sub _set_line
168 {
169  my $self = shift;
170  my $line = $self->{'line'};
171  $line =~ s/\s*#.*$//;
172  $self->{'buffer'} .= " $line";
173 }
174 
175 # ----------------------------------------------------------------------------
176 sub _set_end
177 {
178  my $self = shift;
179  my $line = $self->{'line'};
180  $self->{'buffer'} .= " $line";
181  if ($self->{'buffer'} =~ /\s*(set|basis_set_if_empty|basis_set_if_not_set)\s*\(\s*(\w+)\s+(\"([^\"]|\\\")*[^\\]\"|[^\s]+)(\s+PARENT_SCOPE|\s+CACHE\s+(\w+)\s+(.*))?\s*\)\s*$/) {
182  my $type = '';
183  my $name = $2;
184  my $value = $3;
185  $type = lc $6 if defined $6;
186  $value =~ s/^\s*\"?//;
187  $value =~ s/\"?\s*$//;
188  $self->_append("$type $name = \"$value\"");
189  }
190 }
191 
192 # ----------------------------------------------------------------------------
193 # function()/macro()
194 # ----------------------------------------------------------------------------
195 
196 # ----------------------------------------------------------------------------
197 sub _fndef
198 {
199  my ($self, $dummy, $name) = @_;
200  if ($name =~ m/^_/) {
201  $self->_noneblank();
202  } else {
203  $self->_fndef_append($self->{'line'});
204  }
205 }
206 
207 # ----------------------------------------------------------------------------
208 sub _fndef_begin
209 {
210  my ($self, $dummy, $name) = @_;
211  if ($name =~ m/^_/) {
212  $self->{'skip'} = 1;
213  } else {
214  $self->{'buffer'} = "$self->{'line'}";
215  }
216 }
217 
218 # ----------------------------------------------------------------------------
219 sub _fndef_line
220 {
221  my $self = shift;
222  $self->{'buffer'} .= " $self->{'line'}" unless $self->{'skip'};
223 }
224 
225 # ----------------------------------------------------------------------------
226 sub _fndef_end
227 {
228  my $self = shift;
229  if ($self->{'skip'}) {
230  $self->_noneblank();
231  $self->{'skip'} = 0;
232  } else {
233  $self->{'buffer'} .= " $self->{'line'}";
234  $self->_fndef_append($self->{'buffer'});
235  }
236 }
237 
238 # ----------------------------------------------------------------------------
239 sub _fndef_append
240 {
241  my ($self, $line) = @_;
242  if ($line =~ /^\s*(macro|function)\s*\(\s*(\w+)(\s+[^\)]*)?\)\s*(#.*)?$/) {
243  my $type = $1;
244  my $name = $2;
245  my $params = $3;
246  my @params = ();
247  if ($params) {
248  chomp $params;
249  $params =~ s/^\s+//;
250  @params = split /\s+/, $params;
251  for (my $i = 0; $i <= $#params; $i++) {
252  my $dir = 'in';
253  foreach my $paramdoc (@{$self->{'params'}}) {
254  if ($paramdoc->{'name'} eq $params[$i]) {
255  $dir = $paramdoc->{'dir'};
256  last;
257  }
258  }
259  $params[$i] = "$dir $params[$i]";
260  }
261  }
262  foreach my $paramdoc (@{$self->{'params'}}) {
263  push @params, $paramdoc->{'dir'} . " " . $paramdoc->{'name'}
264  if $paramdoc->{'name'} =~ /^ARG(N|V[0-9])$/;
265  }
266  $self->_append("/// \@returns Nothing.") if not $self->{'returndoc'};
267  $self->_append("$type $name(" . join(', ', @params) . ");");
268  }
269 }
270 
271 
272 1;