Documentation and Visualization

Diomidis Spinellis
Department of Management Science and Technology
Athens University of Economics and Business
Athens, Greece
dds@aueb.gr

Declarative Text Processing

DocBook Details

Best Practices

Documentation from Source Code

Javadoc Example

/**
 * Constructs a newly allocated {@code Integer} object that
 * represents the specified {@code int} value.
 *
 * @param   value   the value to be represented by the
 *                  {@code Integer} object.
 */
public Integer(int value) {
    this.value = value;
}

Automation Example: C++ Code

void
workdb_schema(Sql *db, ostream &of)
{
    cout <<
        // BEGIN AUTOSCHEMA
        "CREATE TABLE STRINGS("         // Strings in the code
        "FID INTEGER,"                  // File key (references FILES)
        "FOFFSET INTEGER,"              // Offset within the file
        "STRING " << db->varchar() << ","   // The string, including its delimiters
        "PRIMARY KEY(FID, FOFFSET)"
        ");\n"

        "CREATE TABLE LINEPOS("         // Line number offsets within each file
        "FID INTEGER,"                  // File key (references FILES)
        "FOFFSET INTEGER,"              // Offset within the file
        "LNUM INTEGER,"                 // Line number (starts at 1)
        "PRIMARY KEY(FID, FOFFSET)"
        ");\n"

        "CREATE TABLE FCALLS("          // Function calls
        "SOURCEID INTEGER, "            // Calling function identifier key (references FUNCTIONS)
        "DESTID INTEGER"                // Called function identifier key (references FUNCTIONS)
        ");\n"
        // ...
        // END AUTOSCHEMA
        "";
}

Automation Example: Processing Script

print 'The following sections describe the
schema of the database created through the SQL backend.';
while (<>) {
    if (/BEGIN AUTOSCHEMA/../END AUTOSCHEMA/) {
        if (/CREATE TABLE (\w+)\(.*\/\/ (.*)/) {
            print qq{
<h2>Table $1</h2>
<p>
$2.
</p>
<table border = "1">
<tr> <th>Field name</th> <th>Field type</th> <th>Value description</th> </tr>
            };
        } elsif (/^\s*\"(\w+).*\/\/ (.*)/) {
            $name = $1;
            $description = $2;
            $type = 'BOOLEAN' if (/booltype/);
            $type = 'CHARACTER VARYING' if (/varchar/);
            print "
<tr><td>$name</td><td>$type</td><td>$description</td></tr>
";
        } elsif (/\"\)\;\\n\"/) {
            print "</table>\n";
        }
    }
}

Automation Example: Documentation Page

The following sections describe the schema of the database created through the SQL backend.

Table STRINGS

Strings in the code.

Field name Field type Value description
FIDINTEGERFile key (references FILES)
FOFFSETINTEGEROffset within the file
STRINGCHARACTER VARYINGThe string, including its delimiters

Table LINEPOS

Line number offsets within each file.

Field name Field type Value description
FIDINTEGERFile key (references FILES)
FOFFSETINTEGEROffset within the file
LNUMINTEGERLine number (starts at 1)

Table PROJECTS

Project details.

Field name Field type Value description
PIDINTEGERUnique project key
NAMECHARACTER VARYINGProject name

Table FCALLS

Function calls.

Field name Field type Value description
SOURCEIDINTEGERCalling function identifier key (references FUNCTIONS)
DESTIDINTEGERCalled function identifier key (references FUNCTIONS)

Graph and Diagram Types

Declarative Drawing Tools

UMLGraph Class Diagram

class Person {
        String Name;
}

class Employee extends Person {}

class Client extends Person {}
A UMLGraph Class Diagram

Detailed Class Diagram

A more complex class diagram
// Author:  Vadim Nasardinov
// Version: $Id: ceg-mv.xml,v 1.1 2005/11/23 22:21:22 dds Exp $

import java.util.List;
import java.util.Map;

/**
 * @assoc "1..1" - "0..n" Adapter
 * @assoc "" - "0..n" ObjectType
 * @assoc "" - "0..n" ObjectMap
 * @assoc "" - "0..n" Table
 * @assoc "" - "0..n" DataOperation
 **/
class Root {
    private Map m_adapters;
    private List m_types;
    private List m_maps;
    private List m_tables;
    private List m_ops;

    public Adapter getAdapter(Class klass) {}
}

class Adapter {
    public Root getRoot();
}

abstract class Element {
    Root getRoot() {}
}

class ObjectType extends Element {}

/**
 * @has "1..1" - "1..1" ObjectType
 **/
class ObjectMap extends Element {
    private ObjectType m_type;
}

class Table extends Element {}

class DataOperation extends Element {}

UMLGraph Sequence Diagram

# Define the objects
object(O,"o:Toolkit");
placeholder_object(P);
step();

# Activation and messages
active(O);
message(O,O,"callbackLoop()");
create_message(O,P,"p:Peer");
message(O,P,"handleExpose()");
active(P);
return_message(P,O,"");
inactive(P);
destroy_message(O,P);
inactive(O);

# Complete the lifeline of O
step();
complete(O);
A sequence diagram

Directory Hierarchies with dot

(Generated with a 50-line Perl script) A directory hierarchy

Plotting Test Coverage: GNU Plot Script

#
# $Id: testcoverage.gpl 1.3 2005/10/13 18:57:00 dds Exp $
#
set ylabel 'Branch test coverage %'
set xlabel 'Test case number'
set ytics 10
set y2tics 10
set mytics
set nomxtics
set terminal png medium enhanced
set output 'testbranch.png'
plot [] [0:100] 'testbranch.dat' using 1:3 title "Executed branches" with lines,\
'testbranch.dat' using 1:5 title "Fully tested branches" with lines

Plotting Test Coverage: Result

Branch test coverage analysis

Memory Fragmentation Example

(Postscript generated by a Perl script and a custom new operator.) Memory fragmentation map

Stack Usage Example

(GNU Plot data generated by a custom function prologue.) Stack usage diagram

Map Example

(Generated by mining data from the CVS repository.) Developer contributions around the world