3 /* vim: set binary expandtab tabstop=4 shiftwidth=4 foldmethod=marker:
4 -------------------------------------------------------------------------------
5 Created: jue jul 31 14:01:57 ART 2003
6 Author : Martin Marrese <m_marrese@argentina.com> <mmarre@mecon.gov.ar>
7 -------------------------------------------------------------------------------
9 -----------------------------------------------------------------------------*/
11 // CONVERTS A STRING TO XML ENTITIES {{{
12 function xmlentities($s) {
14 array('&', '"', '<', '>'),
15 array('&', '"', '<', '>'),
22 <?xml version="1.0" encoding="UTF-8"?>
23 <XMI xmlns:UML="org.omg/standards/UML" verified="false" timestamp="" xmi.version="1.2" >
30 <listitem open="1" type="800" id="-1" label="Views" >
31 <listitem open="1" type="801" id="-1" label="Logical View" >
35 <listitem open="1" type="802" id="-1" label="Use Case View" />
36 <listitem open="1" type="821" id="-1" label="Component View" />
37 <listitem open="1" type="827" id="-1" label="Deployment View" />
38 <listitem open="0" type="823" id="-1" label="Diagrams" />
46 $umlclass = '<UML:Class stereotype="##STEREOTYPE##" package="##PACKAGE##" xmi.id="##ID##" abstract="##ABSTRACT##" documentation="##DOCUMENTATION##" name="##NAME##" static="##STATIC##" scope="##SCOPE##" >';
47 $umlclass_c = '</UML:Class>';
49 $umloperation = '<UML:Operation stereotype="##STEREOTYPE##" package="##PACKAGE##" xmi.id="##ID##" type="##TYPE##" abstract="##ABSTRACT##" documentation="##DOCUMENTATION##" name="##NAME##" static="##STATIC##" scope="##SCOPE##">';
50 $umloperation_c = '</UML:Operation>';
52 $umlparameter = '<UML:Parameter stereotype="##STEREOTYPE##" package="##PACKAGE##" xmi.id="##ID##" value="##VALUE##" type="##TYPE##" abstract="##ABSTRACT##" documentation="##DOCUMENTATION##" name="##NAME##" static="##STATIC##" scope="##SCOPE##" />';
54 $umlattribute = '<UML:Attribute stereotype="##STEREOTYPE##" package="##PACKAGE##" xmi.id="##ID##" value="##VALUE##" type="##TYPE##" abstract="##ABSTRACT##" documentation="##DOCUMENTATION##" name="##NAME##" static="##STATIC##" scope="##SCOPE##" />';
56 $umllistitem = '<listitem open="0" type="##TYPE##" id="##ID##" label="##LABEL##" >';
57 $umllistitem_c = '</listitem>';
61 $IDPARAM = 0; //Functions parameter ID
62 $ARRAY = array(); //Array with information obtained from the code file
65 //GETTING DATA FROM FILES {{{
66 for ($j = 1; $j < count($argv); $j++) {
70 while (($f = readdir($dh)) !== false) {
71 if (is_readable("$file/$f") and substr($f, -4) == '.php') {
78 //PARSING INFORMATION {{{
79 elseif (is_readable($file) and substr($file, -4) == '.php') {
84 foreach ($cont as $line) {
86 $tmp = preg_split ('/[^\w_\/\*\@\$\&\.\']+/', $line);
88 if ($tmp['0'] == '/**') { //Starts documentation
90 $doc_param = 0; //If 1 the line belongs to a parameter documentation
92 if ($tmp['0'] == '*/') { //Ends documentation
97 //Parse documentation {{{
99 $tmp2 = ltrim ($line,'* /**'); //Removes * or /** from the beginning of the line
100 $action = substr($tmp2, 0, strpos($tmp2,' ')); //Gets the action (evrerything before the @)
101 $action = ($action === '') ? $tmp2 : $action;
102 $value = trim(strstr($tmp2, ' ')); //Action value
105 case '@access' : switch ($value) {
106 case 'private' : $options['access'] = 201;
108 case 'protected': $options['access'] = 202;
110 default : $options['access'] = 200;
114 case '@package' : $options['package'] = $value;
117 case '@abstract': $options['abstract'] = 1;
120 case '@static' : $options['static'] = 1;
123 case '@var' : $options['type'] = substr($value, 0, strpos($value,' '));
126 case '@return' : $type = substr($value, 0, strpos($value,' '));
127 $rest = (strpos($value,' ')) ? substr($value, strpos($value,' ')) : '';
131 if (strtolower($type) == 'object') {
133 $type = substr($rest, 0, strpos($rest,' '));
134 $rest = (strpos($rest,' ')) ? substr($rest, strpos($rest,' ')) : '';
136 $options['type'] = $type;
137 //If there is more documentation, I add it to the main documentation
139 $options['documentation'].= "Returns: ".xmlentities(trim($rest))."\n";
144 case '@param' : $cont_param++;
145 $type = substr($value, 0, strpos($value,' '));
146 $rest = substr($value, strpos($value,' ') + 1);
147 if (strtolower($type) == 'object') {
149 $type = substr($rest, 0, strpos($rest,' '));
150 $rest = substr($rest, strpos($rest,' ') + 1);
152 $options['param'][$cont_param]['type'] = $type;
153 $options['param'][$cont_param]['documentation'] =
154 xmlentities(trim(substr(trim($rest), strpos(trim($rest), ' '))));
158 $tmp2 = xmlentities($tmp2);
160 $options['param'][$cont_param]['documentation'].= "\n".$tmp2;
163 @$options['documentation'].= $tmp2."\n";
170 if (!$DOCUMENTING && $tmp['0'] == 'class') {
173 $ARRAY[$ID]['id'] = $ID;
174 $ARRAY[$ID]['name'] = $tmp['1'];
175 $ARRAY[$ID]['stereotype'] = (@$options['stereotype']) ? $options['stereotype'] : '';
176 $ARRAY[$ID]['package'] = (@$options['package']) ? $options['package'] : '';
177 $ARRAY[$ID]['abstract'] = (@$options['abstract']) ? $options['abstract'] : 0;
178 $ARRAY[$ID]['documentation'] = (@$options['documentation']) ? $options['documentation'] : '';
179 $ARRAY[$ID]['static'] = (@$options['static']) ? $options['static'] : 0;
180 $ARRAY[$ID]['scope'] = (@$options['access']) ? $options['access'] : 200;
181 $ARRAY[$ID]['operations'] = array();
182 $ARRAY[$ID]['attributes'] = array();
187 if (!$DOCUMENTING && $tmp['0'] == 'function') {
190 if ($tmp['1']{0} == '&') {
191 $tmp['1'] = substr($tmp['1'], 1); //Removes the &
192 $options['type'] = (@$options['type']) ? '&'.$options['type'] : '';
195 if ($tmp['1']{0} == '_') {
196 $tmp['1'] = substr($tmp['1'], 1); //Removes the _
198 $ARRAY[$IDCLASS]['operations'][$ID]['id'] = $ID;
199 $ARRAY[$IDCLASS]['operations'][$ID]['name'] = $tmp['1'];
200 $ARRAY[$IDCLASS]['operations'][$ID]['stereotype'] = (@$options['stereotype']) ? $options['stereotype'] : '';
201 $ARRAY[$IDCLASS]['operations'][$ID]['package'] = (@$options['package']) ? $options['package'] : '';
202 $ARRAY[$IDCLASS]['operations'][$ID]['abstract'] = (@$options['abstract']) ? $options['abstract'] : 0;
203 $ARRAY[$IDCLASS]['operations'][$ID]['documentation'] = (@$options['documentation']) ? $options['documentation'] : '';
204 $ARRAY[$IDCLASS]['operations'][$ID]['static'] = (@$options['static']) ? $options['static'] : 0;
205 $ARRAY[$IDCLASS]['operations'][$ID]['scope'] = (@$options['access']) ? $options['access'] : 200;
206 $ARRAY[$IDCLASS]['operations'][$ID]['type'] = (@$options['type']) ? $options['type'] : '';
207 $ARRAY[$IDCLASS]['operations'][$ID]['param'] = array();
210 $param_line = trim(substr(strstr($line,'('),0),'{ '); //Removes the last {
211 $param = parseParenthesis($param_line);
213 foreach ($param as $par) {
214 if ($par['name']{0} == '$'|| $par['name']{0} == '&') { //If starts with $ or &
215 switch ($par['name']{0}) {
216 case '$': $par['name'] = substr($par['name'], 1); //Removes the $
218 case '&': $par['name'] = substr($par['name'], 2); //Removes the & and the $
219 $options['param'][$i]['type'] =
220 (@$options['param'][$i]['type']) ? '&'.$options['param'][$i]['type'] : '';
223 $ARRAY[$IDCLASS]['operations'][$ID]['param'][$i]['id'] = $i;
224 $ARRAY[$IDCLASS]['operations'][$ID]['param'][$i]['name'] = $par['name'];
225 $ARRAY[$IDCLASS]['operations'][$ID]['param'][$i]['stereotype'] =
226 (@$options['param'][$i]['stereotype']) ? $options['param'][$i]['stereotype'] : '';
228 $ARRAY[$IDCLASS]['operations'][$ID]['param'][$i]['package'] =
229 (@$options['param'][$i]['package']) ? $options['param'][$i]['package'] : '';
231 $ARRAY[$IDCLASS]['operations'][$ID]['param'][$i]['abstract'] =
232 (@$options['param'][$i]['abstract']) ? $options['param'][$i]['abstract'] : 0;
234 $ARRAY[$IDCLASS]['operations'][$ID]['param'][$i]['documentation'] =
235 (@$options['param'][$i]['documentation']) ? $options['param'][$i]['documentation'] : '';
237 $ARRAY[$IDCLASS]['operations'][$ID]['param'][$i]['static'] =
238 (@$options['param'][$i]['static']) ? $options['param'][$i]['static'] : 0;
240 $ARRAY[$IDCLASS]['operations'][$ID]['param'][$i]['scope'] =
241 (@$options['param'][$i]['access']) ? $options['param'][$i]['access'] : '';
243 $ARRAY[$IDCLASS]['operations'][$ID]['param'][$i]['type'] =
244 (@$options['param'][$i]['type']) ? $options['param'][$i]['type'] : '';
246 $ARRAY[$IDCLASS]['operations'][$ID]['param'][$i]['value'] =
247 (@$par['value']) ? $par['value'] : '';
258 if (!$DOCUMENTING && $tmp['0'] == 'var') {
260 $tmp['1'] = substr($tmp['1'], 1); //Removes the $
261 if ($tmp['1']{0} == '_') {
262 $tmp['1'] = substr($tmp['1'],1); //Removes the _
263 if (!(@$options['access'])) {
264 $options['access'] = 201;
267 //Check for default values
268 if (array_key_exists('2',$tmp)) {
269 $options['value'] = $tmp['2'];
272 $ARRAY[$IDCLASS]['attributes'][$ID]['id'] = $ID;
273 $ARRAY[$IDCLASS]['attributes'][$ID]['name'] = $tmp['1'];
274 $ARRAY[$IDCLASS]['attributes'][$ID]['stereotype'] = (@$options['stereotype']) ? $options['stereotype'] : '';
275 $ARRAY[$IDCLASS]['attributes'][$ID]['package'] = (@$options['package']) ? $options['package'] : '';
276 $ARRAY[$IDCLASS]['attributes'][$ID]['abstract'] = (@$options['abstract']) ? $options['abstract'] : 0;
277 $ARRAY[$IDCLASS]['attributes'][$ID]['documentation'] = (@$options['documentation']) ? $options['documentation'] : '';
278 $ARRAY[$IDCLASS]['attributes'][$ID]['static'] = (@$options['static']) ? $options['static'] : 0;
279 $ARRAY[$IDCLASS]['attributes'][$ID]['scope'] = (@$options['access']) ? $options['access'] : 200;
280 $ARRAY[$IDCLASS]['attributes'][$ID]['type'] = (@$options['type']) ? $options['type'] : '';
281 $ARRAY[$IDCLASS]['attributes'][$ID]['value'] = (@$options['value']) ? $options['value'] : '';
291 //WRITES XMI FILE {{{
292 $m =fopen ('./umlOut.xmi', 'w');
293 fwrite($m, $xmi_start);
296 foreach ($ARRAY as $ar) {
299 fwrite($m, preg_replace (array ('/##STEREOTYPE##/','/##PACKAGE##/','/##ID##/','/##ABSTRACT##/','/##DOCUMENTATION##/','/##NAME##/',
300 '/##STATIC##/','/##SCOPE##/'),
301 array ($ar['stereotype'],$ar['package'],$ar['id'],$ar['abstract'],trim($ar['documentation']),$ar['name'],
302 $ar['static'],$ar['scope']),
304 //Prepare class listitem line
305 $tmp2 = $umllistitem;
306 $LISTITEM.= preg_replace (array('/##TYPE##/','/##LABEL##/','/##ID##/'),array(813, $ar['name'], $ar['id']),$tmp2)."\n";
309 foreach ($ar['operations'] as $op) {
310 $tmp2 = $umloperation;
311 fwrite($m, preg_replace (array('/##STEREOTYPE##/','/##PACKAGE##/','/##ID##/','/##TYPE##/','/##ABSTRACT##/','/##DOCUMENTATION##/',
312 '/##NAME##/','/##STATIC##/','/##SCOPE##/'),
313 array($op['stereotype'],$op['package'],$op['id'],$op['type'],$op['abstract'],trim($op['documentation']),
314 $op['name'],$op['static'],$op['scope']) ,
317 //Parameters aren't listed in listview
318 foreach ($op['param'] as $pa) {
319 $tmp2 = $umlparameter;
320 fwrite ($m, preg_replace(array('/##STEREOTYPE##/','/##PACKAGE##/','/##ID##/','/##TYPE##/','/##ABSTRACT##/','/##DOCUMENTATION##/',
321 '/##NAME##/','/##STATIC##/','/##SCOPE##/','/##VALUE##/'),
322 array($pa['stereotype'],$pa['package'],$pa['id'],$pa['type'],$pa['abstract'],trim($pa['documentation']),
323 $pa['name'],$pa['static'],$pa['scope'],$pa['value']),
326 fwrite($m,$umloperation_c."\n");
327 //Pepare function lisitem line
328 $tmp2 = $umllistitem;
329 $LISTITEM.= preg_replace (array('/##TYPE##/','/##LABEL##/','/##ID##/'),array(815, $op['name'], $op['id']),$tmp2)."\n";
330 $LISTITEM.=$umllistitem_c."\n";
333 foreach ($ar['attributes'] as $op) {
334 $tmp2 = $umlattribute;
335 fwrite($m, preg_replace(array('/##STEREOTYPE##/','/##PACKAGE##/','/##ID##/','/##TYPE##/','/##ABSTRACT##/','/##DOCUMENTATION##/',
336 '/##NAME##/','/##STATIC##/','/##SCOPE##/','/##VALUE##/'),
337 array($op['stereotype'],$op['package'],$op['id'],$op['type'],$op['abstract'],trim($op['documentation']),$op['name'],
338 $op['static'],$op['scope'],$op['value']),
340 //Prepare attributes listitem line
341 $tmp2 = $umllistitem;
342 $LISTITEM.= preg_replace (array('/##TYPE##/','/##LABEL##/','/##ID##/'),array(814, $op['name'], $op['id']),$tmp2)."\n";
343 $LISTITEM.=$umllistitem_c."\n";
345 fwrite($m,$umlclass_c);
346 $LISTITEM.=$umllistitem_c."\n";
348 fwrite($m, $xmi_half. $LISTITEM."\n".$xmi_end);
352 //parsePARENTHESIS {{{
353 //This function receives the content between the parenthesis ( with the ( and the ) )
354 //It's a recursive function
355 //Returns an array of arrays
356 function parseParenthesis($value) {
361 $value = substr(substr(trim($value), 1), 0, strrpos(substr(trim($value), 1),')')); //Removes the ( and the )
364 //I look for the following separation ( , or = ) {{{
365 //If its an = then I check if the next character is an >
366 if (!strpos($value, ',') && !strpos($value, '=')) {
369 elseif (!strpos($value, ',') && strpos($value, '=')) {
370 if ($value{strpos($value, '=') + 1} == '>') {
377 elseif (strpos($value, ',') && !strpos($value, '=')) {
380 elseif (strpos($value, ',') && strpos($value, '=') && strpos($value, ',') > strpos($value, '=')) {
381 if ($value{strpos($value, '=') + 1} == '>') {
388 elseif (strpos($value, ',') && strpos($value, '=') && strpos($value, ',') < strpos($value, '=')) {
393 //Get's the option name {{{
394 $result[$pos]['name'] = (strpos($value, $char)) ? substr($value, 0, strpos($value, $char)) : $value;
395 $pos_del = strpos($value, $char);
398 //If $char is an = or an =>, gets the option value {{{
400 $op_value = (strpos($value, $char)) ? trim(substr($value, strpos($value, $char) + 1)) : false;
402 elseif ($char == '=>') {
403 $op_value = (strpos($value, $char)) ? trim(substr($value, strpos($value, $char) + 2)) : false;
407 //Parse the rest of the line {{{
409 if ($op_value{0} == "'" || $op_value{0} == '"') {
410 $pos_del = parseString($op_value);
412 $result[$pos]['value'] = "''";
415 $op_value = substr($op_value, 1);
416 $result[$pos]['value'] = substr($op_value, 0, $pos_del);
419 elseif (trim(strtolower(substr($op_value, 0 ,5))) == 'array') { //Recursive part {{{
420 $op_value = trim(substr($op_value, 5));
421 $op_value = trim(substr($op_value, 1)); //Removes the (
423 if ($op_value{0} == ')') {
424 $result[$pos]['value'] = 'array()';
427 //I look for the colsing ) {{{
432 if (($temp{$subpos} == '"' || $temp{$subpos} == "'") && $temp{$subpos - 1} != '\\') {
433 $pos_del = parseString(substr($temp,$subpos)) + $subpos;
434 $subpos = $pos_del + 2;
436 if (trim($temp{$subpos}) == ')') {
441 if ($subpos > strlen($temp)) {
448 $par = parseParenthesis('('.substr($op_value, 0 , $subpos).')');
449 $result[$pos]['value'] = 'array(';
450 foreach ($par as $p) {
451 $result[$pos]['value'] .= $p['name'];
453 $result[$pos]['value'] .= '=>\''.$p['value'].'\',';
456 $result[$pos]['value'] .= ',';
459 $result[$pos]['value'] = rtrim($result[$pos]['value'],',');
460 $result[$pos]['value'] .= ')';
465 //Look for the next parameter. If its the last one
466 //I assign it as it came.
467 if ($pos_del = strpos($op_value, ',')) {
468 $result[$pos]['value'] = ($pos_del) ? trim(substr($op_value, 0, $pos_del)): $op_value;
475 //Removes from $value the part that's alredy parsed {{{
477 $value = trim(substr(trim($value), $pos_del + 2));
490 //Funtion that parse the content between "" or ''
491 //Returns the position of the final ' or "
492 function parseString($value) {
496 switch ($value{0}) { //{{{
504 $value = substr($value, 1); //Removes the ' or the " from the beginning of the string
505 if ($value{0} == $char) {
509 while ($cont) { //{{{
511 if ($value{$ii} == $char) {
512 if ($value{$ii - 1} != '\\') {