00001 ##############################################################################
00002 # @file doxyfilter-matlab.pl
00003 # @brief Doxygen filter for MATLAB scripts.
00004 #
00005 # This is the Doxygen filter implementation of Fabrice which is available
00006 # on MATLAB Central.
00007 #
00008 # @sa http://www.mathworks.com/matlabcentral/fileexchange/25925-using-doxygen-with-matlab
00009 #
00010 # @ingroup Tools
00011 ##############################################################################
00012
00013 if ($#ARGV != 0)
00014 {
00015 die "Argument must contain filename $#ARGV"
00016 }
00017 else
00018 {
00019 $fname=$ARGV[0];
00020 }
00021
00022 @listeFic = ();
00023
00024 # if we have a .m file inside a (@)-folder with the same name
00025 if ($fname =~ m/^(.*)\@([-_\d\w]*)[\/\\](\2)\.m/)
00026 {
00027 # read each file in class folder
00028 $name = $2;
00029 $nameExt = $name.".m";
00030 $dir = $1."@".$name."/\*.m";
00031 @fic = glob($dir);
00032 $i = 0;
00033 $listeFic[0] = $fname;
00034 foreach $my_test (@fic)
00035 {
00036 if (!($my_test =~ $nameExt))
00037 {
00038 $i++;
00039 $listeFic[$i] = $my_test;
00040 }
00041 }
00042 # otherwise @-folder, but .m with a different name
00043 } elsif ($fname =~ /^(.*)\@([-_\d\w]*)[\/\\](.*)\.m/) {
00044 # ignore it
00045 # otherwise
00046 } else {
00047 $listeFic[0] = $fname;
00048 }
00049
00050 $output = '';
00051 foreach $my_fic (@listeFic)
00052 {
00053
00054 open(my $in, $my_fic);
00055
00056 $declTypeDef="";
00057 $inClass = 0;
00058 $inAbstractMethodBlock = 0;
00059 $listeProperties = 0;
00060 $listeEnumeration = 0;
00061 $listeEvents = 0;
00062
00063 $methodAttribute = "";
00064
00065
00066 while (<$in>)
00067 {
00068 if (/(^\s*)(%%)(.*)/)
00069 {
00070 $output=$output."$1///$3";
00071 }
00072 if (($listeProperties == 1) && (/(^\s*end\s*)/))
00073 {
00074 $listeProperties = 0;
00075 }
00076 if (($inAbstractMethodBlock == 1) && (/(^\s*end\s*)/))
00077 {
00078 $inAbstractMethodBlock = 0;
00079 }
00080 if (($listeProperties == 1) && (/^\s*([\w\d]*)\s*(=\s*[\w\d{}'',\s\[\]\.]*)?.*(%%.*)?/))
00081 {
00082 $propertyName = $1;
00083 $propertyValue = $2;
00084 $propertyComment = $3;
00085 if (!($propertyName =~ /^$/))
00086 {
00087 if ($typeProperties =~ /Constant/)
00088 {
00089 $properties = $propertyName."$propertyValue;$propertyComment";
00090 }
00091 else
00092 {
00093 $properties = $propertyName.";$propertyComment";
00094 }
00095
00096 $properties =~ s/%%/\/\/\
00097 $properties =~ s/%/\/\
00098 $output=$output.$typeProperties."Property ".$properties;
00099 }
00100 }
00101 if (($listeEnumeration == 1) && (/(^\s*end\s*)/))
00102 {
00103 $listeEnumeration = 0;
00104 $output=$output."};";
00105 }
00106 if (($listeEvents == 1) && (/(^\s*end\s*)/))
00107 {
00108 $listeEvents = 0;
00109 $output=$output."};";
00110 }
00111 if (($listeEvents == 1) && (/^\s*([\w\d]*)\s*/))
00112 {
00113 $name_event = $1;
00114 if (!($name_event =~ /^$/))
00115 {
00116 $event = $name_event.",";
00117 $event =~ s/%%/\/\/\
00118 $event =~ s/%/\/\
00119 $output=$output.$event;
00120 }
00121 }
00122 if (($listeEnumeration == 1) && (/^\s*([\w\d]*)\s*(\(.*\))?(%%.*)?/))
00123 {
00124 $name_enum = $1;
00125 $val_enum = $2;
00126 if (!($name_enum =~ /^$/))
00127 {
00128 if (!($val_enum =~ /^$/))
00129 {
00130 $enum = "$name_enum=$val_enum,";
00131 $enum =~ s/%%/\/\/\
00132 $enum =~ s/%/\/\
00133 $output=$output.$enum;
00134 }
00135 else
00136 {
00137 $enum = "$name_enum,";
00138 $enum =~ s/%%/\/\/\
00139 $enum =~ s/%/\/\
00140 $output=$output.$enum;
00141 }
00142 }
00143 }
00144 if (/(^\s*function)\s*([\] \w\d,_\[]+=)?\s*([.\w\d_-]*)\s*\(?([\w\d\s,~]*)\)?(%?.*)/)
00145 {
00146 $functionKeyWord = $1;
00147 $functionName = $3;
00148 $arguments = $4;
00149 if ($inClass == 0)
00150 {
00151 $output = $declTypeDef.$output;
00152 $declTypeDef = "";
00153 }
00154 $arguments =~ s/,/,in /g;
00155 $arguments =~ s/~/ignoredArg/g;
00156 $arguments = "in $arguments";
00157 if ($arguments =~ /^in $/)
00158 {
00159 $arguments = "";
00160 }
00161 $ligne = "$methodAttribute $functionKeyWord $functionName($arguments);";
00162 $output=$output.$ligne;
00163 }
00164 # Signature of functions in abstract methods
00165 elsif ((/^\s*([\] \w\d,_\[]+=)?\s*([.\w\d_-]+)\s*\(?([\w\d\s,~]*)\)?(%?.*)/) & ($inAbstractMethodBlock == 1) )
00166 {
00167 $functionName = $2;
00168 $arguments = $3;
00169 $arguments =~ s/,/,in /g;
00170 $arguments =~ s/~/ignoredArg/g;
00171 $arguments = "in $arguments";
00172 if ($arguments =~ /^in $/)
00173 {
00174 $arguments = "";
00175 }
00176 $ligne = "$methodAttribute $functionKeyWord $functionName($arguments);";
00177 $output=$output.$ligne;
00178 }
00179 # inheritance for classes
00180 if (/(^\s*classdef)\s*(\s*\([\{\}\?\w,=\s]+\s*\))?\s*([\w\d_]+)\s*<?\s*([\s\w\d_&]+)?(.*)/)
00181 {
00182 #$classAttributes = $2;
00183 $className = $3;
00184 $classInheritance = $4;
00185 if (!($classInheritance =~ /^$/))
00186 {
00187 $classInheritance =~ s/&/,public /g;
00188 $classDef = "class ".$className.":public $classInheritance";
00189 }
00190 else
00191 {
00192 $classDef = "class ".$className;
00193 }
00194 $output=$output.$classDef;
00195 $output=$output."{";
00196 $output=$output.$declTypeDef;
00197 $output=$output."public:\n";
00198 $inClass = 1;
00199 }
00200 if (/(^\s*properties)\s*(\s*\([\w,=\s]+\s*\))?(.*)/)
00201 {
00202 $listeProperties = 1;
00203 $propertiesAttributes = $2;
00204 $typeProperties = "public:\n";
00205 if (lc($propertiesAttributes) =~ /(access\s*=\s*private)/)
00206 {
00207 $typeProperties = "private:\n"
00208 }
00209 elsif (lc($propertiesAttributes) =~ /(access\s*=\s*public)/)
00210 {
00211 $typeProperties = "public:\n"
00212 }
00213 elsif (lc($propertiesAttributes) =~ /(access\s*=\s*protected)/)
00214 {
00215 $typeProperties = "protected:\n"
00216 }
00217 if ((lc($propertiesAttributes) =~ /(constant\s*=\s*false)/) || (lc($propertiesAttributes) =~ /(~constant)/))
00218 {
00219 }
00220 elsif (lc($propertiesAttributes) =~ /(constant(\s*=\s*true\s*)?)/)
00221 {
00222 $typeProperties = $typeProperties." Constant ";
00223 }
00224 }
00225 if (/(^\s*enumeration)\s*(.*)/)
00226 {
00227 $listeEnumeration = 1;
00228 $output=$output."public:\nenum ".$className." {";
00229 }
00230 if (/(^\s*events)\s*(.*)/)
00231 {
00232 $listeEvents = 1;
00233 $output=$output."public:\nenum Events {";
00234 }
00235 if (/(^\s*methods)\s*(\s*\([\w,=\s]+\s*\))?(.*)/)
00236 {
00237 $methodAttribute = "public:\n";
00238 $methodsAttributes = $2;
00239 if (lc($methodsAttributes) =~ /(access\s*=\s*private)/)
00240 {
00241 $methodAttribute = "private:\n"
00242 }
00243 elsif (lc($methodsAttributes) =~ /(access\s*=\s*protected)/)
00244 {
00245 $methodAttribute = "protected:\n"
00246 }
00247 elsif (lc($methodsAttributes) =~ /(access\s*=\s*public)/)
00248 {
00249 $methodAttribute = "public:\n"
00250 }
00251 if (lc($methodsAttributes) =~ /(abstract(\s*=\s*true\s*)?)/)
00252 {
00253 $inAbstractMethodBlock = 1;
00254 $methodAttribute = $methodAttribute." virtual ";
00255 }
00256 if ((lc($methodsAttributes) =~ /(static\s*=\s*false)/) || (lc($methodsAttributes) =~ /(~static)/))
00257 {
00258 }
00259 elsif (lc($methodsAttributes) =~ /(static(\s*=\s*true\s*)?)/)
00260 {
00261 $methodAttribute = $methodAttribute." static";
00262 }
00263 }
00264 $output=$output."\n";
00265 }
00266 close $in;
00267 }
00268 $output=$output."};\n";
00269 print $output;