BASIS  r3148
CMake.pm
Go to the documentation of this file.
00001 ##############################################################################
00002 # @file  DoxyFilter/CMake.pm
00003 # @brief Doxygen filter for CMake.
00004 #
00005 # Copyright (c) 2012 University of Pennsylvania. All rights reserved.
00006 # See https://www.cbica.upenn.edu/sbia/software/license.html or COPYING file.
00007 #
00008 # Contact: SBIA Group <sbia-software at uphs.upenn.edu>
00009 #
00010 # @ingroup BasisTools
00011 ##############################################################################
00012 
00013 package BASIS::DoxyFilter::CMake;
00014 use base BASIS::DoxyFilter;
00015 
00016 # ============================================================================
00017 # public
00018 # ============================================================================
00019 
00020 # ----------------------------------------------------------------------------
00021 ## @brief Constructs a CMake Doxygen filter.
00022 sub new
00023 {
00024     shift->SUPER::new([
00025         # if() else() endif()
00026         ['start', qr/^\s*if\s*\(/, undef, 'start'], # discard if()'s such that
00027                                                     # Doxygen comment is
00028                                                     # associated with next
00029                                                     # block that is supposed
00030                                                     # to be in the then branch.
00031         # include()
00032         ['start', qr/^\s*include\s*\((.+)\)\s*(#.*)?$/, \&_include, 'start'],
00033         # option()
00034         ['start',         qr/^\s*option\s*\(\s*(\w+)\s+(\"([^\"]|\\\")*[^\\]\")\s+(ON|OFF)\s*\)\s*(#.*)?$/, \&_option,       'start'],
00035         ['start',         qr/^\s*option(.*)[^\)]\s*(#.*)?$/,                                                \&_option_begin, 'option'],
00036         ['option',        qr/(^|^.*\s+)\"([^\"]|\\\")*$/,                                                   \&_option_line,  'option_doc'],
00037         ['option_doc',    qr/(^|^.*[^\\])\".*\s+\"([^\"]|\\\")*$/,                                          \&_option_line,  'option_doc'],
00038         ['option_doc',    qr/(^|^.*[^\\])\".*\)\s*(#.*)?$/,                                                 \&_option_end,   'start'],
00039         ['option_doc',    qr/(^|^.*[^\\])\".*$/,                                                            \&_option_line,  'option'],
00040         ['option_doc',    qr/.*/,                                                                           \&_option_line,  'option_doc'],
00041         ['option',        qr/^.*\)\s*(#.*)?$/,                                                              \&_option_end,   'start'],
00042         ['option',        qr/.*$/,                                                                          \&_option_line,  'option'],
00043         # set()
00044         ['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'],
00045         ['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'],
00046         ['start',         qr/^\s*(set|basis_set_if_empty|basis_set_if_not_set|basis_set_script_path)(.*)[^\)]\s*(#.*)?$/,                                     \&_set_begin,   'set'],
00047         ['set',           qr/(^|^.*\s+)\"([^\"]|\\\")*$/,                                                                               \&_set_line,    'set_value'],
00048         ['set_value',     qr/(^|^.*[^\\])\".*\s+\"([^\"]|\\\")*$/,                                                                      \&_set_line,    'set_value'],
00049         ['set_value',     qr/(^|^.*[^\\])\".*\)\s*(#.*)?$/,                                                                             \&_set_end,     'start'],
00050         ['set_value',     qr/(^|^.*[^\\])\".*$/,                                                                                        \&_set_line,    'set'],
00051         ['set_value',     qr/.*/,                                                                                                       \&_set_line,    'set_value'],
00052         ['set',           qr/^.*\)\s*(#.*)?$/,                                                                                          \&_set_end,     'start'],
00053         ['set',           qr/.*$/,                                                                                                      \&_set_line,    'set'],
00054         # function()/macro()
00055         ['start',  qr/^\s*(macro|function)\s*\(\s*(\w+)(\s+[^\)]*)?\)\s*(#.*)?$/, \&_fndef,       'fnbody'],
00056         ['start',  qr/^\s*(macro|function)\s*\(\s*(\w+)(\s+[^\)]*)?\s*(#.*)?$/,   \&_fndef_begin, 'fndef'],
00057         ['fndef',  qr/^[^\)]*$/,                                                  \&_fndef_line,  'fndef'],
00058         ['fndef',  qr/^.*\)\s*(#.*)?$/,                                           \&_fndef_end,   'fnbody'],
00059         ['fnbody', qr/^\s*end(macro|function)\s*\(\s*(\w+)?\s*\)\s*(#.*)?$/,      undef,          'start'],
00060         ['fnbody', qr/^\s*end(macro|function)\s*.*[^\)]\s*(#.*)?$/,               undef,          'fnend'],
00061         ['fnend',  qr/^.*\)\s*(#.*)?$/,                                           undef,          'start'],
00062     ]);
00063 }
00064 
00065 # ============================================================================
00066 # actions
00067 # ============================================================================
00068 
00069 # ----------------------------------------------------------------------------
00070 # include()
00071 # ----------------------------------------------------------------------------
00072 
00073 # ----------------------------------------------------------------------------
00074 sub _include
00075 {
00076     my ($self, $module) = @_;
00077     $module =~ s/^\s*\"?//;
00078     $module =~ s/\"?\s*$//;
00079     $module =~ s/\${(CMAKE_CURRENT_LIST_DIR|BASIS_MODULE_PATH|\${NS}MODULE_PATH)}|\@BASIS_MODULE_PATH\@//;
00080     $module =~ s/ (OPTIONAL|NO_POLICY_SCOPE)//g;
00081     $module =~ s/\.cmake$//;
00082     $self->_append("#include \"$module.cmake\"");
00083 }
00084 
00085 # ----------------------------------------------------------------------------
00086 # option()
00087 # ----------------------------------------------------------------------------
00088 
00089 # ----------------------------------------------------------------------------
00090 sub _option
00091 {
00092     my $self = shift;
00093     $self->_option_append($self->{'line'});
00094 }
00095 
00096 # ----------------------------------------------------------------------------
00097 sub _option_begin
00098 {
00099     my $self = shift;
00100     my $line = $self->{'line'};
00101     $line =~ s/\s*#.*$//;
00102     $self->{'buffer'} = "$line";
00103 }
00104 
00105 # ----------------------------------------------------------------------------
00106 sub _option_line
00107 {
00108     my $self = shift;
00109     my $line = $self->{'line'};
00110     $line =~ s/\s*#.*$//;
00111     $self->{'buffer'} .= " $line";
00112 }
00113 
00114 # ----------------------------------------------------------------------------
00115 sub _option_end
00116 {
00117     my $self = shift;
00118     my $line = $self->{'line'};
00119     $self->{'buffer'} .= " $line";
00120     $self->_option_append($self->{'buffer'});
00121 }
00122 
00123 # ----------------------------------------------------------------------------
00124 sub _option_append
00125 {
00126     my ($self, $line) = @_;
00127     if ($line =~ /^\s*option\s*\(\s*(\w+)\s+(\"([^\"]|\\\")*[^\\]\")\s+(ON|OFF)\s*\)\s*(#.*)?$/) {
00128         my $name    = $1;
00129         my $default = $4;
00130         $self->_append("option $name = $default;");
00131     }
00132 }
00133 
00134 # ----------------------------------------------------------------------------
00135 # set()
00136 # ----------------------------------------------------------------------------
00137 
00138 # ----------------------------------------------------------------------------
00139 sub _set_cache
00140 {
00141     my ($self, $setfn, $name, $value, $type) = @_;
00142     $type = lc $type;
00143     $self->_append("$type $name;");
00144 }
00145 
00146 # ----------------------------------------------------------------------------
00147 sub _set_nocache
00148 {
00149     my ($self, $setfn, $name, $value) = @_;
00150     $self->_append("cmake $name;");
00151 }
00152 
00153 # ----------------------------------------------------------------------------
00154 sub _set_begin
00155 {
00156     my $self = shift;
00157     my $line = $self->{'line'};
00158     $line =~ s/\s*#.*$//;
00159     $self->{'buffer'} = "$line";
00160 }
00161 
00162 # ----------------------------------------------------------------------------
00163 sub _set_line
00164 {
00165     my $self = shift;
00166     my $line = $self->{'line'};
00167     $line =~ s/\s*#.*$//;
00168     $self->{'buffer'} .= " $line";
00169 }
00170 
00171 # ----------------------------------------------------------------------------
00172 sub _set_end
00173 {
00174     my $self = shift;
00175     my $line = $self->{'line'};
00176     $self->{'buffer'} .= " $line";
00177     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*$/) {
00178         my $type  = '';
00179         my $name  = $2;
00180         my $value = $3;
00181         $type = lc $6 if defined $6;
00182         $value =~ s/^\s*\"?//;
00183         $value =~ s/\"?\s*$//;
00184         $self->_append("$type $name = \"$value\"");
00185     }
00186 }
00187 
00188 # ----------------------------------------------------------------------------
00189 # function()/macro()
00190 # ----------------------------------------------------------------------------
00191 
00192 # ----------------------------------------------------------------------------
00193 sub _fndef
00194 {
00195     my ($self, $dummy, $name) = @_;
00196     $self->_fndef_append($self->{'line'}) unless $name =~ m/^_/;
00197 }
00198 
00199 # ----------------------------------------------------------------------------
00200 sub _fndef_begin
00201 {
00202     my ($self, $dummy, $name) = @_;
00203     if ($name =~ m/^_/) {
00204         $self->{'skip'} = 1;
00205     } else {
00206         $self->{'buffer'} = "$self->{'line'}";
00207     }
00208 }
00209 
00210 # ----------------------------------------------------------------------------
00211 sub _fndef_line
00212 {
00213     my $self = shift;
00214     $self->{'buffer'} .= " $self->{'line'}" unless $self->{'skip'};
00215 }
00216 
00217 # ----------------------------------------------------------------------------
00218 sub _fndef_end
00219 {
00220     my $self = shift;
00221     if (not $self->{'skip'}) {
00222         $self->{'buffer'} .= " $self->{'line'}";
00223         $self->_fndef_append($self->{'buffer'});
00224     } else {
00225         $self->{'skip'} = 0;
00226     }
00227 }
00228 
00229 # ----------------------------------------------------------------------------
00230 sub _fndef_append
00231 {
00232     my ($self, $line) = @_;
00233     if ($line =~ /^\s*(macro|function)\s*\(\s*(\w+)(\s+[^\)]*)?\)\s*(#.*)?$/) {
00234         my $type   = $1;
00235         my $name   = $2;
00236         my $params = $3;
00237         my @params = ();
00238         if ($params) {
00239             chomp $params;
00240             $params =~ s/^\s+//;
00241             @params = split /\s+/, $params;
00242             for (my $i = 0; $i <= $#params; $i++) {
00243                 my $dir = 'in';
00244                 foreach my $paramdoc (@{$self->{'params'}}) {
00245                     if ($paramdoc->{'name'} eq $params[$i]) {
00246                         $dir = $paramdoc->{'dir'};
00247                         last;
00248                     }
00249                 }
00250                 $params[$i] = "$dir $params[$i]";
00251             }
00252         }
00253         foreach my $paramdoc (@{$self->{'params'}}) {
00254             push @params, $paramdoc->{'dir'} . " " . $paramdoc->{'name'}
00255                     if $paramdoc->{'name'} =~ /^ARG(N|V[0-9])$/;
00256         }
00257         $self->_append("/// \@returns Nothing.") if not $self->{'returndoc'};
00258         $self->_append("$type $name(" . join(', ', @params) . ");");
00259     }
00260 }
00261 
00262 
00263 1;